feat: copy/paste per-class auto-annotate overrides as YAML (REQ-186, REQ-190)

Copy now emits YAML instead of the one-line "class <name> conf ..." text: one
block per selected class, fields named after the row labels, globals resolved
into the block, a name quoted only when YAML would misread it.

Paste reads the clipboard back and fills the overrides for the classes selected
in that modal, naming any it ignored — an override for a deselected class would
otherwise ride along in class_params unseen. container diffs go out as one
PATCH /projects/{id} and revert together if the save is rejected.

Parsing is parseClassYaml, a strict subset reader for exactly what Copy emits,
so no YAML dependency: any malformed line throws with its line number and
applies nothing. Values must look like numbers, not merely start like them —
parseFloat would have taken "0.5abc" as 0.5.

Both are real buttons with Lucide icons plus a status line reporting the
outcome, and both live in the shared table so the mass modal carries them too.
This commit is contained in:
asus committed 2026-10-05 14:17:17 +07:00
1 parent 4f15335092
commit 4575c46f4c
8 files changed
+344 -49

No files matched your search

+12 -6
View File
@@ -363,12 +363,18 @@ per-class overrides block (REQ-181) stacks one row per class — name plus **Con
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
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 <name> conf … iou … minbox … maxbox … container
true|false`, through `clipboard.js`'s `copyText` (Clipboard API with an `execCommand`
fallback for insecure contexts) — read-only, no network, no setting changed. Because
`ClassParamsTable` is shared, the mass modal carries the button too.
block carries a **Copy** and a **Paste** button (REQ-186, REQ-190): 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 **YAML** — one block per class, fields
named after the row labels (`conf`, `iou`, `minbox`, `maxbox`, `container`), through
`clipboard.js`'s `copyText` (Clipboard API with an `execCommand` fallback for insecure
contexts) — read-only, no network, no setting changed. **Paste** reads the clipboard back
(`readClipboardText`, no legacy fallback, so a blocked read is reported) and fills the
overrides for the classes selected in this modal; `container` diffs go out as one
`PATCH /api/projects/{id} { containers: { classId: bool } }` and revert together on
rejection. Parsing is `parseClassYaml` in the same file — a strict subset reader for exactly
what Copy emits, no YAML dependency, all-or-nothing with a `line N: …` error. Because
`ClassParamsTable` is shared, the mass modal carries both buttons too.
**Review sidebar class rows (REQ-180, REQ-183, REQ-185).** Each class row's frame-clear `×`
(REQ-180) gains an eye toggle in front of it: session-only `Set` state in `ReviewPage`, so it