generated from lucas/rust-webserver-template
Column resize and fit-to-content #41
Labels
No labels
Agent
Ignore
Agent
In Progress
Agent
Planned
Agent
Planning
Agent
Ready
Agent
Triage
Compat/Breaking
Kind
Bug
Kind
Documentation
Kind
Enhancement
Kind
Feature
Kind
Security
Kind
Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
Tag/Good First Issue
Tag/Help Wanted
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
lucas/logview#41
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Part of the dynamic-columns work. Depends on #39 (grid layout, cell model, header) and #40 (column state in the query).
Why
With column widths expressed as a single track list and persisted in the query, resizing becomes the one interaction worth real client-side code. Hide and reorder are plain links; wrap is a class toggle. Resize is the remaining gesture, and
fitis its natural companion.Scope
Drag. Handles on the column header cell edges. Dragging writes
--log-colson the list, so the header and every row move together in one frame with no per-element JavaScript — this is the direct payoff of the variable-driven layout. On release, convert the pixel delta tochandhistory.replaceStatethe newcolsvalue. No navigation and no round trip: widths are pure CSS.Resize model. Metadata columns carry explicit widths; the message absorbs the remainder (
minmax(<floor>, 1fr)wrapped,max-contentunwrapped). Dragging a metadata edge therefore takes from or gives back to the message.Floor and clamping. The message floor is a hard safety net — a track that resolves to zero width wraps
pre-wraptext one character per line and makes rows hundreds of lines tall. The floor is reachable three ways: a drag, a largefit, and simply narrowing the window. The drag is clamped so a user cannot scroll themselves into it; the floor still has to exist for the other two. When the tracks genuinely do not fit, the list scrolls horizontally even in wrap mode — incoherent but legible, and far better than the alternative.Fit. Computed server-side. The server has every cell's text at render time and the log is monospace, so a width-aware character count maps exactly to
ch— no DOM measurement, no font metrics, no approximation. Use a display-width measure (unicode-widthconvention) rather thanchars().count(): CJK occupies roughly two columns and combining marks none, and a user-supplied field is exactly where that shows up.fitexists in two forms:app:fit), re-resolved on every render, so a column can be declared fit-by-default per view.data-fit), so the gesture applies instantly andreplaceStates, with no round trip.The split falls out naturally: the gesture that is inherently numeric (drag) writes a number, the gesture that means "you decide" (double-click) writes the keyword.
Bounding
fit. Each column declares a maximum.fitismax(width)over the column, so one pathological value — a 2KB label from a misconfigured shipper — would otherwise set the width for every row, and in wrap mode would eat the space the message needs. Beyond the cap the cell ellipsises as today. This matters most for fit-by-default columns, where it happens without the user asking.Under tail, the running max lives in the stream handler for the life of the connection. That is request-scoped state, not the "in-memory user state" invariant 4 forbids — but modelling what is currently in the client's DOM would be, so do not. Consequences to accept: the max only ratchets upward, it still counts rows the client's DOM cap may have evicted, and a reconnect resets it.
fitunder tail is approximate by nature.Acceptance
?cols=app:fitsizes the column to its widest value, capped by the column's declared maximum.Out of scope
An entry/scroll anchor in the URL (deferred until time ranges exist). Per-row height hints for
content-visibility— deferred with the scale work.Verification note
The
fitcomputation and width parsing are pure functions and belong in unit tests. The drag behaviour, the clamp and the overflow case are not observable to the current harness and there is no browser in CI; prefer making the hazards unreachable over relying on review.