[Debt] Define and implement a DataGrid column sizing contract with min width, preferred percentage/fraction width, max width, and initial layout that respects min/max without de... #39

Closed
opened 2026-07-06 11:32:36 +02:00 by zemion · 7 comments
Owner

Imported from the consolidated GovOPlaN product backlog.

  • Source: /mnt/DATA/Nextcloud/ADD ideas UG/Products/govoplan/backlog.md
  • Line: 257
  • Section: Deferred Cleanup Notes

Imported backlog item:

- [ ] Define and implement a DataGrid column sizing contract with min width, preferred percentage/fraction width, max width, and initial layout that respects min/max without destabilizing fill-column behavior.
<!-- codex-backlog-fingerprint:61057213efef2de9b180a1f4 --> Imported from the consolidated GovOPlaN product backlog. - Source: `/mnt/DATA/Nextcloud/ADD ideas UG/Products/govoplan/backlog.md` - Line: `257` - Section: `Deferred Cleanup Notes` Imported backlog item: ```markdown - [ ] Define and implement a DataGrid column sizing contract with min width, preferred percentage/fraction width, max width, and initial layout that respects min/max without destabilizing fill-column behavior. ```
zemion added this to the Deferred Cleanup milestone 2026-07-06 12:54:06 +02:00
Author
Owner

Codex State: reviewed

Reviewed against published Core 68328f3. This remains open: DataGrid exposes sizing controls, but there is still no completed min/preferred fraction-or-percentage/max sizing contract with initial-layout tests that prove stable fill-column behavior.

## Codex State: reviewed Reviewed against published Core `68328f3`. This remains open: DataGrid exposes sizing controls, but there is still no completed min/preferred fraction-or-percentage/max sizing contract with initial-layout tests that prove stable fill-column behavior.
Author
Owner

2026-07-29 contract review: DataGrid already exposes width/minWidth/maxWidth/resizable, initialFit, resizeBehavior (free/cover/constrained), a synthetic buffer, and persisted pixel widths. A conservative implementation can proceed without one global UX choice by retaining the per-grid resize modes. Proposed invariant: always respect minima; overflow horizontally when the sum of minima exceeds the viewport; allocate preferred pixel/fraction widths within maxima; send residual width to the synthetic buffer when maxima are exhausted; persist only user-overridden pixel widths under a layout signature. The missing work is a focused sizing matrix and deterministic constrained distribution.

2026-07-29 contract review: DataGrid already exposes width/minWidth/maxWidth/resizable, initialFit, resizeBehavior (free/cover/constrained), a synthetic buffer, and persisted pixel widths. A conservative implementation can proceed without one global UX choice by retaining the per-grid resize modes. Proposed invariant: always respect minima; overflow horizontally when the sum of minima exceeds the viewport; allocate preferred pixel/fraction widths within maxima; send residual width to the synthetic buffer when maxima are exhausted; persist only user-overridden pixel widths under a layout signature. The missing work is a focused sizing matrix and deterministic constrained distribution.
Author
Owner

Codex State: ready

Summary

  • #38 is folded into this issue as the focused sizing-regression slice. Preserve the existing per-grid free, cover, and constrained modes; no universal resize behavior is required.

Next / Blocked

  • Add a deterministic matrix for pixel/fraction/percentage preferred widths with min/max bounds.
  • Prove horizontal overflow when the sum of minima exceeds the viewport, residual space flowing to the synthetic buffer when maxima are exhausted, and stable fill-column behavior in free/cover/constrained modes.
  • Persist only user-overridden pixel widths under a matching layout signature, and verify stale signatures reset to the declared layout.

Suggested status label: status/ready

## Codex State: ready ### Summary - #38 is folded into this issue as the focused sizing-regression slice. Preserve the existing per-grid free, cover, and constrained modes; no universal resize behavior is required. ### Next / Blocked - Add a deterministic matrix for pixel/fraction/percentage preferred widths with min/max bounds. - Prove horizontal overflow when the sum of minima exceeds the viewport, residual space flowing to the synthetic buffer when maxima are exhausted, and stable fill-column behavior in free/cover/constrained modes. - Persist only user-overridden pixel widths under a matching layout signature, and verify stale signatures reset to the declared layout. Suggested status label: `status/ready`
zemion added
status
ready
codex/ready
and removed
status
triage
codex/needs-human
labels 2026-07-30 01:05:32 +02:00
Author
Owner

Codex State: progress

Summary

  • Implemented a deterministic DataGrid sizing contract for pixel, percentage, fraction, minmax, and legacy fill tracks.
  • Hard minima now produce horizontal overflow instead of squashed columns; hard maxima send residual space to the neutral buffer track.
  • Only explicit user resize overrides persist under the layout signature; stale and legacy width snapshots reset to declarations.
  • Container reconciliation is paused during an active drag so ResizeObserver cannot fight the pointer resize.

Changed Files

  • webui/src/components/table/DataGrid.tsx
  • webui/src/components/table/dataGridSizing.ts
  • webui/tests/data-grid-sizing.test.ts
  • webui/tsconfig.component-tests.json
  • webui/package.json

Verification

  • npm run test:data-grid-actions: passed
  • npx tsc --noEmit: passed

Next / Blocked

  • Push the local Core changes, perform a browser interaction pass on representative free/cover/constrained grids, then close #39.

Suggested status label: status/in-progress

## Codex State: progress ### Summary - Implemented a deterministic DataGrid sizing contract for pixel, percentage, fraction, minmax, and legacy fill tracks. - Hard minima now produce horizontal overflow instead of squashed columns; hard maxima send residual space to the neutral buffer track. - Only explicit user resize overrides persist under the layout signature; stale and legacy width snapshots reset to declarations. - Container reconciliation is paused during an active drag so ResizeObserver cannot fight the pointer resize. ### Changed Files - `webui/src/components/table/DataGrid.tsx` - `webui/src/components/table/dataGridSizing.ts` - `webui/tests/data-grid-sizing.test.ts` - `webui/tsconfig.component-tests.json` - `webui/package.json` ### Verification - `npm run test:data-grid-actions: passed` - `npx tsc --noEmit: passed` ### Next / Blocked - Push the local Core changes, perform a browser interaction pass on representative free/cover/constrained grids, then close #39. Suggested status label: `status/in-progress`
zemion added
status
in-progress
and removed
status
ready
labels 2026-07-31 02:27:23 +02:00
Author
Owner

Implemented, browser-verified, and published in GovOPlaN/govoplan-core@7b8072d, with the Campaign list declaration corrected in GovOPlaN/govoplan-campaign@fa4eb39.

The final sizing contract follows the subsequently agreed cover behavior: cover grids use real columns to fill the available width without a synthetic overflow/filler column; horizontal overflow appears only when hard minima cannot fit. Free and constrained modes remain explicit. Pixel, percentage, fraction, minmax, omitted/fill, min/max, persistence signatures, stale resets, and first/middle/last resize compensation are covered by a deterministic regression matrix in docs/DATAGRID_SIZING_CONTRACT.md and component tests.

Browser pass at 1920px on the tenant-users grid:

  • initial widths: 230,227,460,139,139,195,190, container/scroll 1579/1579;
  • first-column drag retained 310,201,433,139,139,168,190 after mouse-up;
  • last-resizable-column drag retained 310,210,442,139,139,150,190 after mouse-up;
  • sticky Actions remained at the viewport edge.

At 1440px, the Campaign list covers 1097/1097 and renders Actions at 120px.

Verification: DataGrid component tests, TypeScript build, 33 module permutations, full bundle-budget build, and consolidated focused check all passed.

<!-- codex-closeout-2026-07-31:core-39 --> Implemented, browser-verified, and published in GovOPlaN/govoplan-core@7b8072d, with the Campaign list declaration corrected in GovOPlaN/govoplan-campaign@fa4eb39. The final sizing contract follows the subsequently agreed cover behavior: cover grids use real columns to fill the available width without a synthetic overflow/filler column; horizontal overflow appears only when hard minima cannot fit. Free and constrained modes remain explicit. Pixel, percentage, fraction, `minmax`, omitted/fill, min/max, persistence signatures, stale resets, and first/middle/last resize compensation are covered by a deterministic regression matrix in `docs/DATAGRID_SIZING_CONTRACT.md` and component tests. Browser pass at 1920px on the tenant-users grid: - initial widths: `230,227,460,139,139,195,190`, container/scroll `1579/1579`; - first-column drag retained `310,201,433,139,139,168,190` after mouse-up; - last-resizable-column drag retained `310,210,442,139,139,150,190` after mouse-up; - sticky Actions remained at the viewport edge. At 1440px, the Campaign list covers `1097/1097` and renders Actions at `120px`. Verification: DataGrid component tests, TypeScript build, 33 module permutations, full bundle-budget build, and consolidated focused check all passed.
Author
Owner

Follow-up correction implemented and verified in commit 5211e07.

  • cover now means real columns may overflow horizontally but may never underflow.
  • Growth changes only the active column and may create overflow.
  • Shrink consumes existing overflow first, then transfers width only to eligible resizable columns on the right.
  • The last resizable column stops exactly at the cover boundary instead of creating a filler or compensating against columns on its left.
  • Pointer movement remains anchored to the drag start: overshooting the stop and reversing stays clamped until the pointer crosses the same boundary.
  • Persisted intentional overflow survives reconciliation, removing the mouse-up snap.

Validation: focused DataGrid sizing tests, production WebUI build, live Playwright drag measurements at exact cover and with 80 px overflow, and the workspace focused suite with all 33 WebUI module permutations.

Follow-up correction implemented and verified in commit [5211e07](https://git.add-ideas.de/GovOPlaN/govoplan-core/commit/5211e07). - `cover` now means real columns may overflow horizontally but may never underflow. - Growth changes only the active column and may create overflow. - Shrink consumes existing overflow first, then transfers width only to eligible resizable columns on the right. - The last resizable column stops exactly at the cover boundary instead of creating a filler or compensating against columns on its left. - Pointer movement remains anchored to the drag start: overshooting the stop and reversing stays clamped until the pointer crosses the same boundary. - Persisted intentional overflow survives reconciliation, removing the mouse-up snap. Validation: focused DataGrid sizing tests, production WebUI build, live Playwright drag measurements at exact cover and with 80 px overflow, and the workspace focused suite with all 33 WebUI module permutations.
Author
Owner

Codex State: done

Summary

  • Fixed the follow-up regression where persisted cover layouts retained their original pixel width after the surrounding container contracted.
  • Persisted layouts now remember their selection container, contract toward hard minima, and preserve only deliberate horizontal overflow; legacy hard-width snapshots are invalidated once.

Changed Files

  • docs/DATAGRID_SIZING_CONTRACT.md
  • webui/src/components/table/DataGrid.tsx
  • webui/src/components/table/dataGridSizing.ts
  • webui/src/styles/tables.css
  • webui/tests/data-grid-sizing.test.ts

Verification

  • npm run test:data-grid-actions (passed)
  • npm run build (passed)
  • npm run test:module-permutations: 50 permutations passed
  • tools/checks/check-focused.sh (passed)

Next / Blocked

  • Published in commit 7ea0cb8 on main.
## Codex State: done ### Summary - Fixed the follow-up regression where persisted cover layouts retained their original pixel width after the surrounding container contracted. - Persisted layouts now remember their selection container, contract toward hard minima, and preserve only deliberate horizontal overflow; legacy hard-width snapshots are invalidated once. ### Changed Files - `docs/DATAGRID_SIZING_CONTRACT.md` - `webui/src/components/table/DataGrid.tsx` - `webui/src/components/table/dataGridSizing.ts` - `webui/src/styles/tables.css` - `webui/tests/data-grid-sizing.test.ts` ### Verification - `npm run test:data-grid-actions (passed)` - `npm run build (passed)` - `npm run test:module-permutations: 50 permutations passed` - `tools/checks/check-focused.sh (passed)` ### Next / Blocked - Published in commit 7ea0cb8 on main.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: GovOPlaN/govoplan-core#39