Files
malkuthro-ComfyUI-Koolook/web
malkuthroandClaude Opus 4.7 2f370a962c chore(sidebar): finish #47 tidiness — UX touches + magic-string lift + small refactors (#64)
Closes the remaining checkboxes on #47 (Sidebar follow-ups deferred
from PR #45). Bundles seven items in one PR per the new "default to
bundling small slices" policy: two user-visible UX improvements + five
internal hygiene fixes.

User-visible (Changed)
----------------------
- **Save selection toast differentiates "no selection" from "selection
  points at deleted nodes."** `serializeSelection` returns a
  discriminated `{ kind: "empty" | "stale" | "ok", graph? }` instead
  of plain `null` / graph. The "stale" case (selection set non-empty
  but every id refers to a removed node — common after undo/redo)
  now toasts "Selected node(s) no longer exist. Click a node on the
  canvas to re-select." instead of the misleading generic message.
- **Curated-defaults seed failure now toasts.** Previously
  console-only; users without DevTools never saw it. The most common
  cause (localStorage quota / private-mode rejection) is something
  the user can act on.

Internal (no behavior change)
-----------------------------
- Lifted save-modal action sentinels (`new` / `use_existing` /
  `modify_existing`) into `ACTION_*` named constants at the top of
  `showSaveWorkflowModal`, alongside the pre-existing `NEW_TOP` /
  `SAVE_HERE` cascade sentinels.
- Section-id constants (`SECTION_ID_NODES`, `SECTION_ID_WORKFLOWS`,
  `SECTION_ID_TAGS`) lifted to module scope in `tree.js`. `pinExpanded`
  in the save flow now references the constant instead of the literal
  `"workflows"` string, so a future section-id rename only needs the
  constant updated.
- `modalLabel(text)` factory in `modals.js` replaces 7× repetition of
  the four-line `createElement("label")` + `className` + `textContent`
  + `appendChild` pattern.
- `USERDATA_OVERWRITE_QUERY = "?overwrite=true"` named constant in
  `workflows_store.js`. ComfyUI's userdata API requires this flag to
  allow POST over an existing file; pinning the contract as a
  constant makes it visible at a glance.
- `buildFolder` no longer round-trips folder-expansion state through
  `wrapper.dataset.expanded`. State lives in a closure variable;
  `pathStates` remains the canonical cross-render store.
- `subcategoryFor` fallback path now logs `console.warn` with the
  offending category + `categoryRoot`. Reachable only via a logic
  error (stale `REPOS` config); previously silent.
- Save-modal `onSave` callback contract renamed `dir` → `dirPath` to
  match codebase-wide convention (`dirPath` for arrays of segments,
  `dirName` for single segments, `dir` for resolved DirNode objects).
  Caller updates in `tree.js` paired.

Skipped from #47 (with rationale)
---------------------------------
- The broader `el(tag, props, children)` DOM helper from the issue
  body. Adopting it consistently would touch every modal/folder/leaf
  row construction site (~40+ replacements) for marginal readability
  win. The narrower `modalLabel(text)` is the meaningful slice
  because it replaces an exact 4-line repetition. If `el()` becomes
  desirable later, file as a focused refactor PR.

Verification
------------
- `python tools/preflight_release.py --skip manager-meta -v` PASS.
- `node --input-type=module --check` on every modified JS file —
  clean.
- Synced to live ComfyUI install via `scripts/sync_to_dev.py` for
  smoke-test on Mac.

Closes #47.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 09:19:48 +02:00
..