Skip to content

fix(analytics): anchor column resize handles to table headers - #605

Merged
dborup merged 1 commit into
masterfrom
port-2274-resize-handles
Oct 25, 2026
Merged

dborup merged 1 commit into
masterfrom
port-2274-resize-handles

Conversation

@dborup-agent

Copy link
Copy Markdown
Collaborator

Relates to #596

Plan and change

Port of upstream PR 2274 (read only), adapted to this fork rather than cherry-picked.

  • makeColumnsResizable appends an absolutely positioned .col-resize-handle to each header. A static th is not a containing block, so the handle was positioned against the page instead of its header.
  • Fix (public/app.js, 2 lines): before appending a handle, set position: relative on the header only if its computed position is static. Sticky, relative, absolute and fixed headers are left untouched.
  • Fork adaptations: tests live in the repo root here; the makeColumnsResizable measures once and credits colspan rows to column 0 (packets Details column too narrow) #258 sandbox needed a getComputedStyle stub; the E2E uses this fork's theme-refresh event to wait for the final analytics render.

Tests (red before, green after)

  • test-frontend-helpers.js: static headers get relative (measured and saved widths); positioned headers are preserved; last header untouched.
  • test-table-fluid-e2e.js: analytics nodes tab at 1250px and 375px; every handle's offsetParent is its header, its box sits on the header's right edge, and the page does not overflow.
  • Mutants: (1) fix removed, (2) unconditional position = 'relative'. Both fail the unit test (2 failures each); with the fix removed both E2E cases fail.

Performance

One getComputedStyle read per header at setup, once per table. No new requests, listeners or settings.

makeColumnsResizable appends an absolutely positioned .col-resize-handle
to each header, but static headers are not a containing block, so the
handle was positioned against the page. Give static headers
position:relative; already positioned (e.g. sticky) headers are left
alone.

Adds a unit test, a desktop and mobile E2E, and updates the #258 sandbox
with a getComputedStyle stub.

Relates to #596

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@dborup-agent

Copy link
Copy Markdown
Collaborator Author

Rapport — CS-pve-agent3 PR#605 #596 — head be802fb

Status: Ready for review (draft); all CI jobs green, no flaky-test rerun needed.

Requirement: resize handles anchored to their table headers (port of upstream 2274, adapted)

Check Test Red before Green after Mutant
Static headers get position: relative (measured and saved widths), last header untouched test-frontend-helpers.js 2 failures [T] 731 passed, 0 failed [T] Fix removed: 2 failures. Unconditional relative: 2 failures [T]
Already positioned headers (sticky/relative/absolute/fixed) are not overridden test-frontend-helpers.js n/a (passes before; guards the conditional) pass [T] Unconditional relative mutant fails it [T]
Handles sit on the header's right edge, offsetParent is the header, no page overflow, desktop 1250px and mobile 375px test-table-fluid-e2e.js (local server, fixture DB) 2 failed [T] 43 passed, 0 failed [T] Fix removed: both viewport cases fail [T]
Existing column-width behaviour unchanged test-issue-258-column-widths.js, -e2e.js n/a 15/15 and 22/22 pass [T] n/a

Adaptation notes [A]: the fix is two lines in public/app.js; the #258 sandbox gained a getComputedStyle stub; tests live in the repo root as in this fork. The upstream drag/reload-restore and sticky-Nodes E2E cases were not ported; drag and saved-width behaviour is already covered by the existing #258 E2E.

Other gates

  • sh test-all.sh: 273 files passed, 0 failed [T]
  • scripts/check-xss-sinks.sh --diff origin/master: clean, exit 0 [T]
  • No new map[string]interface{}, no Go changes, cmd/server untouched [T]
  • No hardcoded colors; no workflow files changed, so the fork guards are unchanged [T]
  • Go suites were not run locally because no Go code changed; they ran in CI [A]

CI per job (run on head be802fb) [T]

All passed: Go Build & Test, Go Libraries & CLI, Go Ingestor Tests, Go Server Tests (1/3, 2/3, 3/3), JavaScript Unit Tests & Lint, Script & Container Unit Checks, Verify Go Test Assignments, Validate Docker Image, Playwright E2E Tests (1/3, 2/3, 3/3), Verify E2E Shards & Coverage, Build & Publish Docker Image. Skipped by design: Deploy Staging, Release Artifacts, Publish Badges & Summary. Known flaky test #271 did not fail.

Remaining

  • test-table-fluid-e2e.js is not referenced by name in deploy.yml; I did not confirm how CI picks it up, so the new E2E cases may not run there [K]. The Playwright shards passed either way.
  • Browser validation was done headless against a local server only; no screenshot taken [A].

@dborup-agent

Copy link
Copy Markdown
Collaborator Author

Review — CS-pve-agent1 PR#605 — head be802fb

Dom: APPROVE med nits

Independent, read-only review. Head SHA was identical before and after [T]. Verified on the merged tree of the head and origin/master (edfeea99); the merged tree is byte-identical to the head for all files [T].

Findings

# Severity Finding
1 nit The E2E does not kill a mutant that sets position: sticky instead of relative (sticky is also a containing block, so the geometry assertions still hold). The unit test catches it, since it asserts exactly relative. Acceptable, only noting that the E2E checks geometry, not the specific value [T].
2 nit The report says it is unconfirmed whether CI runs test-table-fluid-e2e.js. It does: deploy.yml invokes it by name in the Playwright E2E job [T].
3 nit The unit test fake for getComputedStyle reads `th.style.position
4 info Behaviour change beyond analytics: makeColumnsResizable is shared, so Nodes, Observers, Packets, GPS sanity, node-changes, new-nodes and position-gaps tables get the same anchoring. This is the intended effect of fixing the shared helper, not scope creep. .data-table th is already position: sticky, so those headers are skipped by the conditional [T/A].

No blocking findings.

Answers to the review points

  • Adapted, not blind cherry-pick: two-line change in the shared helper in public/app.js, tests in the fork's repo-root layout, getComputedStyle stub added to the makeColumnsResizable measures once and credits colspan rows to column 0 (packets Details column too narrow) #258 sandbox, E2E waits on this fork's theme-refresh event [T].
  • makeColumnsResizable measures once and credits colspan rows to column 0 (packets Details column too narrow) #258 column widths / existing layouts: test-issue-258-column-widths.js 15/15, test-issue-258-column-widths-e2e.js 22/22, test-table-fluid-e2e.js 43/43 on the merged tree; the sticky-header case is preserved by the conditional [T].
  • CSS variables only: no CSS changed, no colours added. scripts/check-xss-sinks.sh --diff origin/master run in a git worktree of the head: exit 0 [T].
  • Mobile/touch: E2E covers 375px (handles on the header edge, no page overflow). The handle has mouse listeners only for dragging; this is unchanged by the PR and out of scope [T/A]. Real touch drag was not tested.
  • Tests exercise real code, mutant meaningful: the unit test loads the real public/app.js and calls makeColumnsResizable; the E2E uses the real page. Red-before/green-after is documented by the author and reproduced by my mutants below [T].
  • Acceptance criterion: the single criterion of fix(analytics): anchor column resize handles to table headers (port of upstream PR 2274) #596 (handles anchored to headers, desktop and mobile browser test) has a unit test and a desktop+mobile E2E, both red without the fix [T].
  • Invariants: no Go changes, cmd/server untouched, no new map[string]interface{}; fork guards unchanged (9 if: guards plus 1 comment line); no closing keywords (Relates to #596); commit author dborup <kontakt@meshview.dk> [T].

Tests (merged tree)

Mutants (my own)

  1. Fix removed: unit 2 failures; E2E both fix(analytics): anchor column resize handles to table headers (port of upstream PR 2274) #596 cases fail (1250px and 375px) [T]
  2. Unconditional position = 'relative': unit 2 failures [T]
  3. Fix applied only to the first header: unit 2 failures [T]
  4. relative replaced by sticky: unit fails; E2E survives (finding 1) [T]

Not verified

  • Visual check by screenshot and real touch drag on a device.
  • Staging/production behaviour (no access, by rule).
  • Pixel-level comparison against upstream 2274 (upstream read only via the PR description).

@dborup
dborup marked this pull request as ready for review October 25, 2026 16:03
@dborup
dborup merged commit 4218f87 into master Oct 25, 2026
18 checks passed
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.

2 participants