Skip to content

feat(ui): add shared panel layout, migrate inbox and dashboard - #231

Closed
Clupai8o0 wants to merge 4 commits into
theme/status-and-globalsfrom
ui/panel-layout
Closed

Clupai8o0 wants to merge 4 commits into
theme/status-and-globalsfrom
ui/panel-layout

Conversation

@Clupai8o0

Copy link
Copy Markdown

What this does

Adds a reusable app-panel-layout / app-panel pair (collapsible, resizable, full-screen panels that stack into tabs on a narrow screen) and moves the staff task inbox and the student project dashboard onto it, replacing two separate hand-rolled cdkDrag resize implementations.

Stacked PR

This branch is based on theme/status-and-globals (open as #192). git merge-base theme/status-and-globals ui/panel-layout is 1ec29efb0, the tip of that branch. The diff shown here is only this slice's incremental diff on top of that base, not the whole branch, and it must not be merged before it.

The stack is a DAG with a merge point, not a straight chain. Checked with git merge-base --is-ancestor:

  • ui/panel-layout and ui/a11y-audit are siblings. Neither is an ancestor of the other, and their merge base is cc4a834e6, the first commit in this slice.
  • Both are ancestors of ui/notification-links and of ui/inbox-extension-card. They come back together in 7972ea62a (Merge branch 'ui/panel-layout' into ui/inbox-extension-card) and 3c19fb377 (Merge branch 'ui/a11y-audit' into ui/inbox-extension-card), and both merge commits are ancestors of ui/notification-links.
  • ui/notification-links is an ancestor of ui/inbox-extension-card.

So the order is theme/status-and-globals → cc4a834e6 → ui/panel-layout and ui/a11y-audit in either order → the two merges on ui/inbox-extension-card → ui/notification-links → the ui/inbox-extension-card tip.

What changed and why

A shared panel primitive. PanelLayoutComponent lays out app-panel children side by side in an even 12px frame. Each panel can collapse to a 44px icon rail, resize by dragging its edge or with the arrow keys, or go full screen. At or below the stackBelow width, 899.98px by default, the layout switches to one panel at a time behind a row of tabs instead of shrinking everything, so nothing scrolls sideways on a phone-width screen.

  • PanelComponent talks to its host layout through a PANEL_LAYOUT injection token kept in its own file, so the two components don't need to import each other.
  • Collapsed state is remembered per page and panel (ontrack.panels.<page>.<panel> in localStorage) by PanelStateService, and width is remembered for the panels that can resize, meaning a resizeEdge and no flex. Every read and write is wrapped in try/catch: a private window, blocked site data, or a full quota just means the panel falls back to its default instead of breaking.
  • Resizing is pointer-drag (rAF-throttled, clamped to minWidth/maxWidth) with an arrow-key equivalent (shift for a bigger step) on the same resize handle, which the old CDK-drag implementation did not have. The old handles were aria-hidden divs with no tabindex and no keydown.
  • Full screen positions the panel absolutely inside the layout's own padded frame, not the viewport, so the app header and page chrome stay visible. Escape exits it, unless a dialog or menu already consumed that keypress. The other panels in the same layout get inert while one is full screen, so Tab cannot reach what it covers. That is the same scope the dashboard's old [attr.inert]="commentsFullscreen" bindings had, and it does not cover the page outside the layout.
  • Only the comments panel is fullscreenable on either page, and only while there is a task behind it: the inbox binds [fullscreenable]="!!taskData?.selectedTask" and the dashboard's comments panel only renders inside @if (selectedTaskDefinition). The list and the middle "current item" panel are never fullscreenable. The middle panel is also not collapsible or resizable, it just takes the space the other two leave (flex).

Migrated the task inbox and project dashboard onto it. Both pages had their own cdkDrag resizer, their own width clamping and their own split-pane-resizing body class toggled by hand. The inbox also threw its drag events through a subs$ / auditTime(30) pipeline. The dashboard's subs$ was just of(true) and it clamped on every move event. All of that is now the shared component's job in both places.

The dashboard's floating "show comments" button for a narrow desktop window is gone along with all its CSS. The inbox's copy is gone from the desktop branch only. Its .comments-floating-toggle rules stay in inbox.component.scss because the phone branch still uses that button.

Extension request card restyled in cc4a834e6. It is now a header/reason/footer card with status chips (Granted, Denied, Awaiting decision) instead of the old stacked-text layout, and the Grant/Deny buttons disable while a request is in flight (a new busy flag on the component) so a slow response cannot be double-submitted. Note that cc4a834e6 is the merge base with ui/a11y-audit, so this change is not unique to this branch and will show up again in that sibling's diff from the same base. It only needs reviewing once.

What the migration left alone, and what moved anyway

  • The task inbox's phone branch (the @else on !isMobileView) is unchanged in this diff. Only the desktop branch was migrated.
  • The project dashboard still uses its own mobilePane tab bar (Overview, Tasks, Details, Feedback) rather than the shared layout's tab stacking, and the panes behind it still render the same components. The markup did move though: the tab bar and the pane row now sit inside the @if (isPhoneLayout) branch, the isPhoneLayout && guards came off the project-task-list-panel--phone-hidden conditions, the inline overview skeleton moved into an OverviewSkeleton template, and the old .project-task-resizer element and its --phone-hidden rule are gone. project-dashboard.mobile.spec.ts follows those selectors in this diff.
  • No spec exists for extension-comment.component.ts before or after this change, so the new busy-disables-the-buttons behaviour has no automated coverage in this slice.

Testing

Net across the spec files touched: 9 it(...) cases added, 2 removed. No test run is reported here.

  • New: panel-layout.component.spec.ts, 7 cases, exercising PanelLayoutComponent and PanelComponent together through a 3-panel host template that mirrors real usage (list / flexible work area / fullscreenable comments). Covers: collapse to rail and back, the headerless edge-toggle collapse control, remembering collapsed state and width per page+panel key, falling back to defaults when storage throws, ignoring a stored value of the wrong shape, going full screen (the other panel inert, Esc to exit), and stacking into tabs with collapse ignored while stacked.
  • Updated: project-dashboard.component.spec.ts, 2 cases renamed and simplified for the new fullscreenPanel: string | null field replacing commentsFullscreen/commentsNarrow$. It stays at 12 cases. The toggle-on-and-off assertions those two cases carried are now the layout's behaviour and live in the panel-layout spec instead.
  • project-dashboard.mobile.spec.ts had its selectors and breakpoint mocks updated for the new markup. It stays at 13 cases, none added or removed.
  • Not covered by a dedicated test in this slice: inbox.component.ts's wiring into app-panel-layout (its existing spec overrides the template with an empty string and has one should create case), and the extension-comment restyle noted above.

Review guidance

1101 of the 1521 added lines are the new panel-layout directory, which is 7 new files with nothing removed. It carries all of the new interactive logic and has its own spec. panel.component.ts (drag/keyboard resize, collapse, full screen, inert) and panel-layout.component.ts (breakpoint stacking, Escape handling) are where a bug would actually live. panel.component.html/.scss and panel-layout.component.html/.scss are mostly template and styling for that logic.

The riskier review, behaviourally, is the migration itself: inbox.component.ts/.html and project-dashboard.component.ts/.html, since that is where an existing page's resize, collapse and full-screen behaviour has to keep working, and where widths that used to live in component state now come out of localStorage under a new key. The dashboard's phone branch is worth a second look for the same reason, because its markup moved even though the panes did not change. doubtfire-angular.module.ts (the two new components added to imports) and the extension-comment restyle are mechanical or visual and lower risk.

Merge order

The base branch is theme/status-and-globals, open as #192. Nothing here merges before it.

After #192, this PR and the accessibility-audit PR are independent of each other and can land in either order. Both must land before the notification-links PR, which already contains the merge commits for both.

One overlap to know about: commit cc4a834e6 (the extension request card restyle and the first full-screen comments toggle) is the fork point this branch shares with the accessibility-audit branch, and it is not on theme/status-and-globals. It is 6 files, +247/-68. Whichever of the two PRs merges first carries it, and the second will show it already applied. It only needs reviewing once.

@Clupai8o0

Copy link
Copy Markdown
Author

Closing: this work is now on integration/t2-2026 (web 8fcf4135a), together with #224, the rest of the UI stack and feature/ui-polish. PR intake has closed for the trimester, so the integration branch is the base for the demo and for the upstream PRs to thoth-tech. The full web suite (2235 tests), lint and build pass on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant