8000 feat(ui): add draggable resize divider to resource dashboard by janzak-dev · Pull Request #1562 · google/xmc · GitHub
[go: up one dir, main page]

Skip to content

feat(ui): add draggable resize divider to resource dashboard - #1562

Merged
janzak-dev merged 8 commits into
mainfrom
feat/rod-resize-divider
Nov 3, 2026
Merged

janzak-dev merged 8 commits into
mainfrom
feat/rod-resize-divider

Conversation

@janzak-dev
@janzak-dev janzak-dev commented Nov 3, 2026 •
Copy link
Copy Markdown
Collaborator

Summary

Adds a draggable, keyboard-accessible vertical resize divider (xmc-rod-resize-divider) between the queues list and the queue jobs pane on the /resources (Resource Observability Dashboard) page.

Note

This is the base PR of a two-PR stack. The "View in full width" toggle is implemented on top of it in #1544.

Motivation & Context

On the /resources split layout, the right-hand queue jobs table previously had a fixed 50% width, making wide multi-column job rows cramped on narrower viewports. A draggable splitter lets users tailor the horizontal space between the queues list and the jobs table, with a quick double-click (or keyboard) reset back to the default 50/50 split.

Screencast

Drag to resize

scrolltoresize.webm

Key Changes

  • Resize Divider Component (cmd/ui/app/resource_dashboard/components/resize_divider/):
    • Added standalone ResizeDividerComponent (xmc-rod-resize-divider) with separate TypeScript (resize_divider.ts), template (resize_divider.ng.html), and stylesheet (resize_divider.scss) files.
    • WAI-ARIA role="separator" with aria-valuemin / aria-valuemax / aria-valuenow (rounded to whole percentages), accessible name "Resize queue list and jobs panes", aria-valuetext ("Queue list N%"), aria-controls pointing at the queue list pane, and tooltip "Drag to resize sections (double-click to reset)".
    • Pointer-event dragging (pointerdown on the divider plus scoped window pointermove / pointerup / pointercancel listeners, touch-action: none) so mouse, touch, and pen all work. Only the primary button starts a drag, events from other pointers are ignored, and listeners are detached on pointerup / pointercancel, when a pointermove arrives with the primary button released, and on ngOnDestroy, so a lost release (e.g. a context menu) cannot leave the divider stuck in drag mode.
    • Container bounding rect read once per drag on pointerdown (zero-width containers never enter drag mode), [20%, 80%] clamping, dblclick reset to 50% / 50%, focus on pointerdown, and keyboard support (ArrowLeft / ArrowRight in 5% steps, Enter / Space reset).
    • Required containerElement and controls inputs and two-way splitRatio model (dragging state stays internal); subtle #dadce0 idle line that highlights as a 2px #1a73e8 line on hover, focus, and while dragging.
    • Added ResizeDividerHarness (startDrag, moveDragTo, endDrag, cancelDrag, isFocused, …) and 1-to-1 unit tests (resize_divider_test.ts) covering button filtering, lost-release recovery, pointercancel, other-pointer filtering, clamping, keyboard bounds, focus, aria-valuenow updates, and destroy cleanup.
  • Resource Dashboard (cmd/ui/app/resource_dashboard/):
    • Placed <xmc-rod-resize-divider> between .rod-main-content and .jobs-side-pane, binding the pane flex-basis percentages to splitRatio; both panes use box-sizing: border-box so the divider tracks the cursor at every ratio.
    • Extended ResourceDashboardHarness (getResizeDivider(), getSplitContainerDimensions(), pane style accessors) and resource_dashboard_test.ts with a wiring test that drags against real layout geometry and double-click resets.
    • Made wide content reachable at narrow splits: the queue jobs table container (cmd/ui/app/side_panel/contents/queue_jobs_table/queue_jobs_table.scss) scrolls horizontally and the queue list header (queue_list.scss) wraps.
    • Regenerated Playwright visual baseline snapshots (cmd/ui/screenshot_tests/resource_dashboard/resource_dashboard.screenshot.spec.ts-snapshots/).

Assumptions

  • Keyboard resize step of 5% (ArrowLeft / ArrowRight) and Enter / Space reset on the focused role="separator" element — WAI-ARIA separator widgets with tabindex="0" require keyboard operability alongside pointer dragging — if a finer or coarser step is preferred, KEYBOARD_RESIZE_STEP_PERCENT in resize_divider.ts can be adjusted without API impact.
  • The split ratio is kept in component state only (not persisted across page reloads) — keeps the change minimal — persistence (e.g. localStorage) can be added later if requested.
  • The container geometry is snapshotted at drag start — the container's box does not change while dragging (only the panes' flex-basis does) — a window resize or horizontal scroll in the middle of a drag is reflected from the next drag onwards.
  • Pointer users without precise dragging can use double-click to reset and the keyboard (Tab to the divider, then arrows / Enter); the stacked full-width toggle (feat(ui): add full-width jobs view toggle to resource dashboard #1544) offers a single-click way to give the jobs table more space — a dedicated non-drag pointer control (WCAG 2.5.7) can be added if required.
  • Queue cards are not individually scrollable — at the 20% minimum split very dense cards may overflow their pane on narrow viewports — a pixel-based minimum pane width can be added if this proves to be a problem in practice.

Verification & Testing

  • Commands Executed: cd cmd/ui && npm run lint && npm run format:check && npm test -- --watch=false --browsers=ChromeHeadlessNoSandbox && npm run build && npm run test:screenshot
  • Coverage & Test Status: 706/706 Angular UI unit tests passed (including the new ResizeDividerComponent and dashboard integration tests), ESLint/Prettier checks passed, 10/10 Playwright visual screenshot tests passed, and verified live on a GKE development environment.

Related Issues / Bugs

N/A

TAG=agy
CONV=3c6eb5b1-7773-4304-b217-5535f5de61bb

Add a standalone ResizeDividerComponent (`xmc-rod-resize-divider`) between
the queues list and the queue jobs pane on the Resource Observability
Dashboard. The divider supports pointer dragging clamped to [20%, 80%],
double-click and Enter/Space reset to 50/50, ArrowLeft/ArrowRight keyboard
resizing, and WAI-ARIA separator semantics.

TAG=agy
CONV=3c6eb5b1-7773-4304-b217-5535f5de61bb
@gemini-code-assist gemini-code-assist Bot left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a draggable and keyboard-accessible vertical split-pane divider (ResizeDividerComponent) to allow users to dynamically resize the left and right panes of the Resource Dashboard. It includes comprehensive unit tests and a test harness for the new component. Feedback on the implementation highlights a performance issue in the drag-resize logic: calling container.getBoundingClientRect() inside the mousemove handler causes layout thrashing. It is recommended to cache the container's bounding rectangle on mousedown to ensure smooth resizing.

Address review feedback: read the container bounding rect on mousedown instead of on every mousemove, and skip starting a drag when the container has zero width. Add tests for the zero-width guard and the single rect read per drag.

TAG=agy
CONV=3c6eb5b1-7773-4304-b217-5535f5de61bb
@janzak-dev janzak-dev left a comment
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed review feedback in commit 85231e9.

Make containerElement a required input and replace the never-bound minRatio, maxRatio, and ariaLabel inputs with constants. Drop the null-container guard, the redundant clamp on reset, and default-valued CSS declarations.

TAG=agy
CONV=3c6eb5b1-7773-4304-b217-5535f5de61bb
Address self-review feedback:
- Ignore non-primary mouse buttons and end the drag when the primary button is no longer held, so a lost mouseup cannot leave the divider stuck in drag mode.
- Focus the divider on mousedown so keyboard resizing works after a click.
- Keep the dragging state internal to the divider instead of exposing a two-way model.
- Use border-box sizing on both panes so the divider tracks the cursor at every split ratio.
- Give the separator a descriptive accessible name while keeping the drag tooltip.
- Replace the TestBed-specific harness accessor with ElementDimensions, add drag harness helpers, and cover button filtering, keyboard bounds, focus, and aria-valuenow updates.

TAG=agy
CONV=3c6eb5b1-7773-4304-b217-5535f5de61bb
Address self-review feedback:
- Drive dragging with pointer events and touch-action: none so the divider can be dragged with touch and pen input; pointercancel also ends a drag.
- Round aria-valuenow to whole percentages.
- Let each pane scroll horizontally instead of overflowing under the divider when squeezed to the minimum split.
- Assert listener removal directly in the destroy test.

TAG=agy
CONV=3c6eb5b1-7773-4304-b217-5535f5de61bb
Address self-review feedback:
- Ignore pointermove/pointerup/pointercancel events from pointers other than the one that started the drag.
- Clip squeezed pane content with overflow-x: clip and an 8px clip margin instead of overflow-x: auto, which clipped card shadows at every split ratio.
- Drop the unused clientX argument from the startDrag harness helper and add tests for pointercancel and multi-pointer input.

TAG=agy
CONV=3c6eb5b1-7773-4304-b217-5535f5de61bb
Address self-review feedback:
- Remove pane-level overflow clipping; the jobs table container now scrolls horizontally and the queue list header wraps, so content stays reachable at narrow splits.
- Add aria-controls and aria-valuetext to the resize divider (window splitter pattern).

TAG=agy
CONV=3c6eb5b1-7773-4304-b217-5535f5de61bb
Address self-review feedback: assert that the exact drag listeners attached are removed on destroy, and cover a second pointerdown replacing an active drag.

TAG=agy
CONV=3c6eb5b1-7773-4304-b217-5535f5de61bb
@janzak-dev
janzak-dev marked this pull request as ready for review November 3, 2026 13:16
@github-actions
github-actions Bot requested a review from AntonTyb November 3, 2026 13:16
@janzak-dev janzak-dev added the priority::2-high top of mind. should not wait. label Nov 3, 2026
@janzak-dev
janzak-dev added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit 8b1bbda Nov 3, 2026
16 checks passed
@janzak-dev
janzak-dev deleted the feat/rod-resize-divider branch November 3, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority::2-high top of mind. should not wait.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0