From 2971f9192ccb231fba61aa0e4e14563202fa2f3b Mon Sep 17 00:00:00 2001 From: asus Date: Mon, 5 Oct 2026 11:01:26 +0700 Subject: [PATCH] style: stack per-class override rows instead of a wide table (REQ-181 layout) The width:100% table plus the new MaxBox column let the Class column absorb the slack, stranding the Container checkbox away from its class. One block per class now: name + Container checkbox on the first line, Conf/IoU/MinBox/ MaxBox inputs in a wrapping grid below. Behavior identical - KEYS, buildClassParams, compose() copy line, toggleContainer revert, aria labels. --- docs/design.md | 6 +- docs/tasks.md | 16 ++++ docs/ui-spec.md | 16 ++-- frontend/src/components/ClassParamsTable.jsx | 98 +++++++++----------- 4 files changed, 75 insertions(+), 61 deletions(-) diff --git a/docs/design.md b/docs/design.md index cb0826b..2124ecc 100644 --- a/docs/design.md +++ b/docs/design.md @@ -359,9 +359,11 @@ that class to its full-set detections (blank if no full-set run covered it); cle examples is then a plain full-set view again. Run Preview always refreshes the full-set for every selected class first (with empty exemplars), then re-runs the exemplared classes sequentially; drawing an example never triggers a full-set re-run. The -per-class overrides table also carries a **Container** checkbox (REQ-184) that toggles +per-class overrides block (REQ-181) stacks one row per class — name plus **Container** +checkbox on the first line, the four override inputs in a wrapping grid below — and that +checkbox toggles `project_classes.container` through `PATCH /api/projects/{id} { containers: … }`. The same -table carries a **Copy** button (REQ-186): one click puts every selected class's effective +block carries a **Copy** button (REQ-186): one click puts every selected class's effective settings (per-class override where set, else the global slider; container = the checkbox state) on the clipboard as short lines `class conf … iou … minbox … maxbox … container true|false`, through `clipboard.js`'s `copyText` (Clipboard API with an `execCommand` diff --git a/docs/tasks.md b/docs/tasks.md index b33b91f..264d158 100644 --- a/docs/tasks.md +++ b/docs/tasks.md @@ -1389,6 +1389,22 @@ read it. with expected drops; node eval proves `buildClassParams` emits `max_box_frac`; `git diff --stat` = 5 backend + 5 frontend files + docs. +## Task — stacked per-class override rows (REQ-181 layout) `[DONE]` + +1. The overrides surface drops the wide table for one block per class: name line with the + **Container** checkbox (REQ-184) at the right, then a wrapping + `repeat(auto-fit, minmax(118px, 1fr))` grid of `Conf`/`IoU`/`MinBox`/`MaxBox` inputs, each + labelled in its own colour. Cause of the old cramping: `width: 100%` + the new MaxBox + column let the Class column swallow the slack, stranding the checkbox far right. + Behavior untouched — `KEYS`, `buildClassParams`, `compose()` copy line, `toggleContainer` + revert path, `title`/`aria-label` all identical → verify: **[DONE]** reviewer diff-proved + the functional hunk is render-only (SPEC ✅, 4 Minor all fixed: two stale ui-spec + "table/columns" lines, `label` margin-bottom, dead class hook; plus long-name ellipsis + + `flexShrink: 0` guard); `npm run build` green; grid math checked at 375/768/920/1040 px; + contrast ≥6.6:1 on all label colors; focus ring left to the global `input:focus` + (accent border + glow) — no CSS added; **browser eyeball still owed by the user** + (375 px 2-col wrap, long class names). + ## Known open points - *Not closed by any task, by choice:* **any rebuild kills the running job.** Task 14's resume diff --git a/docs/ui-spec.md b/docs/ui-spec.md index 1567465..61ca4b2 100644 --- a/docs/ui-spec.md +++ b/docs/ui-spec.md @@ -449,9 +449,13 @@ Two columns inside one dialog (920 px wide, max 96 vw / 90 vh, scrollable). - Confidence threshold — 0.05…0.95 step 0.05, default 0.35. - NMS IoU threshold — 0…0.9 step 0.05, default 0.0. - Min box size (fraction of frame) — 0…0.5 step 0.005, default 0, shown as a percentage. -- **Per-class overrides** (REQ-181) — a compact table below the sliders, one row per currently - selected class: `Conf` / `IoU` / `MinBox` / `MaxBox` number inputs and a **Container** checkbox - (REQ-184). Each input's placeholder shows the current global value and an empty input +- **Per-class overrides** (REQ-181) — one **stacked block** per currently selected class + below the sliders: the class name on the first line with its **Container** checkbox + (REQ-184) at the right, then a wrapping grid of `Conf` / `IoU` / `MinBox` / `MaxBox` + number inputs, each labelled in its own colour. No column headers, no wide table — a + narrow modal wraps the grid instead of squeezing the numbers, and the checkbox never + drifts away from its class. Each input's placeholder shows the current global value and + an empty input inherits it; only filled cells are sent, as `class_params` on **both** the preview and the job request, so preview and run cannot disagree. Classes without an override behave exactly as before. The checkbox marks the @@ -462,7 +466,7 @@ Two columns inside one dialog (920 px wide, max 96 vw / 90 vh, scrollable). unmarked classes are governed by IoU alone. Toggling is optimistic `PATCH /projects/{id} { containers: { [classId]: bool } }` into `project_classes.container` with revert on rejection — preview and batch job read the same stored flag. -- **Copy (REQ-186)** — small right-aligned ghost button above the overrides table; label +- **Copy (REQ-186)** — small right-aligned ghost button above the overrides block; label `Copy`, flips to `Copied` for 1.5 s inside an `aria-live` span, and on failure silently stays `Copy`. One line per selected class, e.g. `class sack conf 0.4 iou 0.6 minbox 0.005 maxbox 1 container false` — an empty input copies the @@ -537,8 +541,8 @@ Same anatomy, wider (1040 px), with three differences: must not abort the rest; the backend GPU lock serialises the real work anyway. Progress is reported as `done/total (failed)` and the result message is `Queued N auto-annotation job(s)`. -The per-class overrides table (REQ-181) appears here too, below the sliders — same columns -including the **Container** checkbox (REQ-184) — and its +The per-class overrides block (REQ-181) appears here too, below the sliders — the same +stacked rows, **Container** checkbox (REQ-184) included — and its `class_params` ride along on every preview and start request — one set of overrides applies to all selected batches. diff --git a/frontend/src/components/ClassParamsTable.jsx b/frontend/src/components/ClassParamsTable.jsx index 43fb30f..934bc37 100644 --- a/frontend/src/components/ClassParamsTable.jsx +++ b/frontend/src/components/ClassParamsTable.jsx @@ -92,64 +92,56 @@ export default function ClassParamsTable({ classNames, globals, value, onChange, {copied ? 'Copied' : 'Copy'} - - - - - {KEYS.map(k => ( - - ))} - {project && ( - - )} - - - + {/* Stacked rows (REQ-181): the name line carries the container flag, the + grid below it the four overrides, so a wide class list never squeezes + the numbers or strands the checkbox away from its class. */} +
{classNames.map(name => { const cls = project?.classes.find(c => c.name === name) return ( -
- - {KEYS.map(({ key, label, step, color }) => ( - - ))} - {project && ( - - )} - +
+
+ {name} + {project && cls && ( + + )} +
+
+ {KEYS.map(({ key, label, step, color }) => ( + + ))} +
+
) })} - -
Class{k.label}Container
{name} - set(name, key, e.target.value)} - style={{ - width: 64, fontSize: '0.76rem', background: '#09090b', color, - border: '1px solid #3f3f46', borderRadius: 4, padding: '2px 4px', - cursor: 'text', - }} - /> - - {cls && ( - - )} -
+ ) }