08bf160309b16d70dabbaf046e4df398e77dfd74
7
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
fe0835eea3 |
fix(images): concept Load more focus, empty state and review rulings
Review of #249 C2: - Load more and Retry focus the first appended image, as the concept does (app.js loadMoreImages). Focus moves without scrolling so the visible cards keep their place (bounded-DOM anchor), and only while focus is still on the pressed control: a viewer or a field the user moved to keeps it. When a last page adds nothing and the button hides, focus goes to the last image, never to the page; a failed page focuses Retry. - The concept's empty state beside the grid: .empty "No matching images. Try another search or category." - D17: the caption date shows only under Newest first (", YYYY" outside the current year) and is hidden under Oldest first and the name and rating sorts. - en-US number grouping in the embedded count too. - Refine "Folder" defaults to the concept's "All output folders". It is not narrowed by Source: the concept has no Source field, and the list holds every source's folders, so any pair can be chosen in one dialog. - The shared toast moves to toast.mjs; library-editor re-exports it. - The D32 overlay (extreme zoom) wraps the layout segmented control and the continuation row instead of pushing them out of the 390px column. - The legacy gallery checks moved to Overview's "Open existing image gallery" card (D29). Mapping additions: grid with no results -> .empty concept copy beside the grid; Load more press -> focus the first new image (concept). |
||
|
|
12228e286b |
feat(images): concept toolbar, filter row and caption
The Images page now renders the approved mock's heading, shared toolbar, filter row, section caption and infinite continuation (#249, Task C2). - Heading: "Your generations, their prompts, and the next idea." with Import (upload icon) before New prompt (primary). - Toolbar (shared mountToolbar): search over filenames, linked prompt text, titles and tags; category (the Library's categories); sort Recently added / Name A–Z / Highest rated, then Oldest first and Name Z–A (D14). - Filter row: Grid/List/Masonry segmented control, Thumbnail size, the scope chip ("All output folders" or "<source> · <folder>") and "Group by positive prompt →". - Caption: "N of M images · K positive prompts" from positive_count; a plain cursor page keeps the first page's count and an unknown count hides the "· K positive prompts" part. The date span shows "<Today|Yesterday|weekday> · <Month D>" of the newest loaded result under a date sort and is hidden otherwise (D17). - Continuation: "N of M images · more load as you scroll" with Load more, the concept's end copy, Retry for a failed page, and the concept's "K more images loaded. N of M." toast. - The listing sends category, tags and sort=rating (PR B params). Old control -> new control: - "Search filenames" field -> toolbar search "Search workspace" (placeholder "Search prompts, tags, filenames…"), also matching prompt text and tags - Source select -> Filters -> "Refine this view" Source - Folder select -> Refine Folder (all sources' folders and ancestors) - Media select -> Refine Media - (new) Tags -> Refine Tags; Category -> toolbar category select - Sort select (Newest/Oldest/Filename A–Z/Z–A) -> toolbar sort (Recently added/Oldest first/Name A–Z/Name Z–A, plus Highest rated) - Layout buttons -> .segmented Grid/List/Masonry in the filter row - Thumbnail size field -> label.small + select#image-size - "Group by positive prompt" link -> button.chip "Group by positive prompt →" (#/library) - Refresh -> Import -> "Scan an output folder" -> Rescan (D15) - "Current gallery" link -> removed; Overview's tool cards link the legacy gallery (D29) - "All images" h2 + count -> .section-caption #result-count - .image-continuation -> .infinite-continuation (Retry kept) Legacy behavior kept: video items, keyboard grid navigation, scroll and filter restoration, bounded DOM, continuation retry, source-change recovery (now disabling the toolbar, Filters and Import). The Filters and Import dialogs close on route change and browser Back. The shared toolbar (C1) called .some() on select.options, which is an HTMLOptionsCollection in a browser (only the unit tests' fake DOM gave an array); setValue and setCategories now spread it first. The layout segmented control may wrap at extreme zoom (D31) instead of scrolling the 390px page sideways. The retired .image-filters, .image-view-controls, .image-toolbar, .image-layouts, .image-collection, .image-continuation and duplicated .image-workspace grid rules are gone from images.css. |
||
|
|
9d398f9862 |
feat(workspace): concept shell — sidebar, topbar, heading and footer on the approved mock's CSS (#256)
* build(workspace): vendor the approved concept stylesheet with a drift check * refactor(workspace): adopt the concept stylesheet as the workspace base * feat(workspace): concept sidebar with real navigation counts * feat(workspace): concept topbar with Theme and ComfyUI link * refactor(workspace): one concept heading and footer for every route * fix(workspace): keep the canvas link on the proxy mount A resolver failure no longer stops the shell from mounting: the ComfyUI link falls back to the root read from the page's own mount path (never another origin). Tests cover a non-standard /ComfyBackendDirect mount, including that no request escapes it. * test(workspace): concept fixture and shell comparison * test(workspace): concept fixture carries the concept inspector facts * fix(workspace): match the concept brand name and compare shell hover states * test(workspace): shell comparison mutation check and docs Add mutate() to the shared concept inventory and a shell mutation check: a nav-row min-height rule and a removed .breadcrumbs each make the comparison fail with the changed path. Harden the resolver-failure guard test with an injection count, make the overlay lint fail when workspace.css is missing, mark the library.css .row-actions leftovers for PR E, and document the concept CSS base, the overlay lint, the comparison method and the recorded shell deviations in TESTING.md. * fix(workspace): focus the page title on a route change A sidebar or history navigation now focuses #page-title, as the concept does on every hashchange (app.js 1168), so a screen reader announces the page heading instead of the main region. The first render leaves focus alone and the skip link still focuses main. The heading module's comment now describes what the shell does. * fix(workspace): give the Overview nav entry its own home glyph Overview reused the concept's Activity pulse byte for byte, so once the Activity row lands two entries would share one icon. Overview now has an outline home glyph. The shell comparison takes it from the D28 ruling instead of the concept's activity path, and the icon test checks that every approved glyph is distinct. * test(workspace): accept only #249 decision markers and state the lint scope The overlay lint accepted any D-number, so another issue's ruling such as "D5 (#245)" could mark a concept override. A marker now has to be a D-number with no other issue cited; the vocabulary rule that cited #245 reads "#245 decision 5". TESTING.md now states that the lint covers workspace.css only, lists the unmarked overrides still in images.css, and says PRs C and D run the lint over each page sheet they keep. * perf(workspace): re-read only Library and Tags counts after a Library write A confirmed Library or vocabulary write cannot change the Images count, but it re-read all three, including the Images output listing. It now re-reads only the Library and Tags counts. Each count has its own read, so a write never cancels an Images read that is still in flight. |
||
|
|
cbf46a7573 |
feat(vocabulary): native Tags & categories screen (#245)
* feat(vocabulary): add workspace vocabulary state * feat(vocabulary): render the native Tags & categories screen * feat(vocabulary): add guarded vocabulary dialogs * fix(vocabulary): recover unconfirmed deletes and list every category in Manage * refactor(vocabulary): use the shared plural helper * test(vocabulary): compare the native screen with the approved concept * fix(vocabulary): wrap long tag names so row actions stay visible on narrow screens * docs(vocabulary): document the native vocabulary screen and gates Also aligns the shell link focus-ring offset with the concept (3px) and makes the chrome comparison poll the document title. * fix(vocabulary): refresh lists when a write lands after its dialog closes A rename, delete, create or category apply that commits after its dialog was disposed (Chromium force-closing the modal on a repeated Escape, or Back while the write is in flight) returned before onInvalidate, so the lists were never re-read and a cached Library shelf kept showing the old names. Like the recipe editor, a disposed command now still reports any outcome that may have changed storage (receipt, conflict, restore, unconfirmed) without rendering; only a failed write stays silent. * fix(vocabulary): give the Manage categories datalist its own id The proposed-name datalist reused the recipe editor's `categories` id. It was safe only because routes dispose each other's dialogs; it is now `vocabulary-category-options`. * docs(vocabulary): correct vocabulary testing notes Name the Tag column and the Create tag heading action, say that a failed Load more moves focus to Retry, place bulk actions on the admin page, describe late writes after a closed dialog, Browse's exact filter and the full deviation list, and use a test port that is not the live concept server's. * test(vocabulary): raise the vocabulary dialog branch floor coverage:update after the late-write and datalist fixes: workspace/vocabulary-dialog.mjs branches 87 -> 88. No floor is lowered. * fix(vocabulary): keep 390px row actions visible regardless of font metrics The one-column Tags table reserved a fixed 6em for the tag name. With CI's stock DejaVu Sans fallback (about 9% wider than the pinned image's) Tag + Prompts + Images + stacked actions needed 351px of a 336px wrap, so Browse and Rename / merge were pushed out of view on every row. At 700px and below the Tag column now has no fixed minimum and the actions ask for no more than their stacked width, so all remaining space goes to the tag name: short names stay on one line wherever the concept's own table fits, and a wider font wraps the name instead of clipping an action. A new test widens the metrics with letter spacing and fails without this change in every engine. * ci: run browser jobs in the pinned Playwright image Concept comparisons measure geometry, which follows the fonts a browser falls back to. The concept names Inter, which neither environment ships: the pinned image falls back to WenQuanYi Zen Hei, a stock ubuntu-latest runner to DejaVu Sans. Under DejaVu the concept's own Tags table needs more than a 390px viewport (its page scrolls sideways and, under touch emulation, the widened layout viewport resizes its dialogs), so the 390px comparisons failed in CI while passing locally. Both browser jobs now run in mcr.microsoft.com/playwright:v1.64.1-noble, the image local runs use, instead of installing browsers on the runner. A tooling test keeps the tag equal to @playwright/test in the lockfile. * fix(vocabulary): ignore a category preview edited while it is pending Editing the Category or proposed name while a slow Preview was in flight was a no-op in the saving phase, so the late response still became an applicable preview: the form showed the new values while Apply would submit the old source and target. An edit during a pending preview now marks it stale. Its late result returns the dialog to idle (Preview again) instead of showing an impact or offering Apply; a plain failure of a stale preview is not shown either, while a restore or conflict still is, since it describes storage. The inputs stay editable during the request, as in the recipe editor, which disables only its actions while saving. * ci: use the image's Python and Node in containerized browser jobs Inside mcr.microsoft.com/playwright:v1.64.1-noble, actions/setup-python failed before any test ran: `spawn /__t/Python/3.12.15/x64/bin/pip ENOENT`. The toolcache builds come from the runner, and their entry points name host interpreter paths that do not exist in the container. The jobs now use the image's Python 3.12 and Node 24. The image has no ensurepip and the job runs as uid 1001 without root, so a checksum-pinned pip wheel bootstraps a user-space venv for requirements-dev.txt; a step checks that the image Node is 24. The tooling test forbids setup-python and setup-node in these jobs and requires the pinned bootstrap. |
||
|
|
e7cfcc2bfb |
style(workspace): align browsing with the approved concept (#219)
* style(workspace): align approved shell and visual fixtures * test(workflows): preserve evidence across browser projects * style(workspace): match approved image browsing geometry * style(workspace): match natural library card layout * fix(workspace): retain wheel motion during row correction * fix(workspace): contain zoomed controls and image metadata (#215) |
||
|
|
590aa2cd0e |
feat(workspace): add native Images browsing and infinite scroll (#201)
* feat(workspace): add native image browsing and continuous loading * test(workspace): assert empty collections through their status * fix(workspace): rescan refreshed images and expose ancestor folders |
||
|
|
d4bb5c5ba9 |
feat(ui): add the tested opt-in Prompt Manager workspace shell (#198)
* docs(ui): prototype unified prompt management application * docs(ui): add masonry and per-image tagging to application concept * docs(ui): make gallery concept use continuous infinite scrolling * feat(ui): introduce the tested application workspace shell * fix(docs): preserve concept controls across cached navigation * test(ci): emit Python tracebacks for native test crashes * test(ui): cover workspace restoration across cached navigation |