harryagasi
fix: resizable report sidebar, stable chat layout, guided empty state
15d8afd
|
Raw
History Blame Contribute Delete
2.97 kB
# Phase 1 Data Model: Analysis Chat UI Fixes
This feature is UI-only; no backend/API schema changes. The entities below are **client-side UI state** shapes introduced or modified in React components β€” not persisted server-side.
## Analysis (existing, unchanged)
Source of truth: `src/services/orchestrationApi.ts` `Analysis` type. No fields added or removed. Relevant existing fields used by this feature:
| Field | Type | Used by |
|---|---|---|
| `analysis_title` | `string` | AnalysisHeader (US5) |
| `objective` | `string` | AnalysisHeader (US5, no longer always-visible) |
| `business_questions` | `string[]` | BusinessQuestionsEditor (US4), MessageList empty-state buttons (US3) |
| `data_bind` | `DataBindItem[]` | AnalysisHeader "N sources" pill (US5) |
## ReportPanelState (new, client-only, in `AnalysisShell.tsx`)
Session-scoped (in-memory `useState`, no persistence), replacing/extending the existing `reportCollapsed: boolean`.
| Field | Type | Default | Notes |
|---|---|---|---|
| `collapsed` | `boolean` | `false` | Existing behavior, unchanged |
| `fullscreen` | `boolean` | `false` | New β€” when true, report panel occupies 100% width, chat panel is hidden |
| `widthPercent` | `number` | `23` (~current `23rem` equivalent as % of viewport) | New β€” last-used split-view width, clamped to `[25, 75]` per FR-001; reset to default on page reload (session-only per clarification) |
Transitions:
- `collapsed β†’ false` when user clicks "Restore report sidebar" (existing).
- `fullscreen: false β†’ true` when user activates fullscreen toggle; `widthPercent` is preserved (not overwritten) so exiting fullscreen restores the prior split.
- `fullscreen: true β†’ false` restores `widthPercent` split view.
- `widthPercent` updates continuously (throttled by the resizable library) while dragging the handle, clamped to 25–75.
## BusinessQuestionDraft (existing shape, new constraint)
`NewAnalysisDialog.tsx` `questions: string[]` state β€” no shape change, only a cardinality constraint:
| Rule | Enforcement point |
|---|---|
| `2 <= questions.length <= 5` | `BusinessQuestionsEditor.tsx` Add/Remove button disabling; `NewAnalysisDialog.tsx` `canSubmit` |
| Empty/whitespace entries excluded from the count check | Reuses existing `compactQuestions()` util |
This constraint applies **only** at analysis-creation time (per clarification) β€” it is not retroactively enforced on `Analysis.business_questions` read elsewhere (e.g., MessageList starter buttons filter empty entries but do not cap at 5, per the legacy-analysis edge case in spec.md).
## No new entities
No new persisted domain entities, no new API request/response shapes. `ConversationEmptyStateProps` (or equivalent inline block in `MessageList.tsx`) is a presentational prop shape, not a domain entity:
```ts
interface ConversationEmptyStateProps {
businessQuestions: string[]; // pre-filtered, non-empty, trimmed
onSelectQuestion: (question: string) => void;
}
```