Repository navigation
feat(workflows): redesign the workflow library, previews and editor nodes - #10222
Open
joshistoast wants to merge 29 commits into
Open
joshistoast wants to merge 29 commits into
joshistoast wants to merge 29 commits into
Conversation
Add last_run_at as a library sort key and regenerate the API contracts. A completed run of a project workflow linked to a non-bundled template now marks that template as run, through a wrapper around the queue history routing that bumps once per completion, owner-scoped and fenced. The mock backend honours the new order key, has_been_opened and the last_run_at touch.
Replace the library tabs with a places rail (In this project, Recent, My library, Templates, Shared with me) and multi-select tag checkboxes with counts. One toolbar on every place: search, a sort menu with direction, a view menu with card size and Fill/Fit, and New workflow on In this project. Sort, direction and card size are account preferences; search and tags reset when the dialog closes. Recent lists opened workflows by last opened; This project filters and sorts client-side. The browse store keys cached views by the whole filter, probes place totals once per opening, refreshes order-touched views only while the dialog is in use, and keeps the selected workflow's list copy enriched when its page is reloaded.
…d quick actions Cards pack at 150px (up to six columns) or 220px in the large size. A workflow without a thumbnail shows a silhouette drawn from its node positions. Each card carries a readiness dot: ready, models to install, or node packs missing. Hovering a card offers Open, Preview and More; keyboard paths are unchanged. The grid dispatches card events from data attributes, memoises cards, renders nothing while scrolling within a row, and pins the scroll area's inherited custom properties so scrolling no longer restyles every card. Focus survives a column-count change.
The library rail leads with the preview, name and Open, then facts (base, nodes, callable), description, tags, requirements with missing node packs named, copies in this project, updated and created. The project rail names the linked template and its revision, flags when the template is newer, and offers Update from template and Update library template. Below 56rem the rails give way to a summary sheet whose details expand over the grid and restore scroll and focus on collapse.
The library dialog no longer ships in the editor startup bundle: the widget chrome loads it lazily on the first opening, preloads it when the library button is hovered or focused, and keeps it mounted afterwards. Two shared module groups absorb the chunks the split exposed. Every editor route loads about 72 KB less script at the same request counts; both performance baselines are re-recorded to keep the saving.
Update the editor reference for places, tags, the sort and view menus, readiness dots, the linked-template actions and the narrow layout.
…y layout The wide-layout rule set the start border and then reset it with the border-width shorthand in the same declaration, so the detail rail met the cards with no divider. Set each side's width explicitly.
Open returns to the pinned footer as the full-width primary action under Preview graph, beside More, in both the library and project rails. A picker's commit action belongs in a fixed, large footer slot rather than a small button competing with the name. The narrow sheet's summary bar keeps its own Open and More, so the footer pair stays wide-only.
List gains onRangeChange, the virtualizer's visible row range reported only when it changes, for server-windowed lists that load pages as they scroll, and pins the scroll area's inherited overflow custom properties on its row container so a scroll no longer restyles every row. ListItem gains id, on the primary button, so an external menu or dialog can name the row as its trigger for focus return, and controls, applied as aria-controls while the button is expanded, so a dialog's focus trap admits a menu the row opened.
The view menu's first group picks Grid or List; the choice is an account preference, and the card size and thumbnail display options apply to the grid only. The list is the platform List at comfortable density: a small thumbnail or silhouette, the name with the Public and Active badges, the base badge, readiness dot and the same fact text as the cards, a date column for the current order, and Open, Preview and More, shown on hover and focus at a constant width. Click selects, double-click opens, right-click, Shift+F10 and More anchor the same menu as the cards. Rows of a windowed place are keyed by position: a placeholder is a busy row labelled for screen readers that becomes the entry when its page arrives, so focus and the tab stop survive End, Home and a layout switch. Range loading, visible demand and the per-filter scroll anchor are shared with the grid through one demand module, and the readiness and fact derivation lives in one helper for both.
In the wide layout the chips row had no grid area and was auto-placed along the dialog's bottom edge, lifting the body whenever a tag was checked. The narrow Tags button already counts the checked tags and the result line names them, so the row goes rather than being hidden per layout.
The hidden quick-action strip still took pointer events while transparent, so a press that began on the card could end on Open and select nothing, and once the pointer had rested on a small card its centre lay under the revealed Open. The strip now ignores the pointer until it is shown and sits over the top of the image, clear of the centre; the in-project marker moves to the image's bottom-left so a long label never covers it.
A returning grid waited for its ResizeObserver's first report to learn its width, and Chromium can hold that report back past the frame, leaving the grid on placeholders with no range requested. The width is now read from the viewport before the first paint; the observer still tracks later changes.
Preview and More sit on an opaque panel fill so they read over any thumbnail, and that fill replaced the outline recipe's hover. They now lay the recipe's tint over the panel on hover, and More while its menu is open.
Right-click, Shift+F10 and the More button on a card or list row open the actions menu for that workflow and leave the selection and the detail rail alone; the rail's and the sheet's More still act on the selection. The action set and its rename and delete dialogs move into one hook used by the rail and by a context-menu host, acting by id and revision with write access captured when a dialog opens. Deleting another workflow keeps the selection; the menu closes when its target leaves the listing; a press on one menu's trigger while another is open swaps them in one press; one pending Duplicate per workflow across both surfaces.
A modal traps focus, so focus leaving it is never a dismissal; under StrictMode a closing child dialog returned focus into itself and closed the dialog that opened it. Escape, close controls and outside presses still dismiss.
A pure preview model built from a workflow document (titles, markers, folded helper inputs, layered layout), and the node view, inputs view and stage parts that draw it. No surface uses them yet.
The invocation state and submission accept a source to lock the route to, and the Invoke button can show that route as fixed, report jumps to a setting, and render at control size. The top bar's own instance is unchanged.
…ew graph The library's Preview replaces its list with a stage (Nodes, Inputs and Graph tabs, find, stepper in the rail) instead of a stacked dialog. View graph and the publication review use the same view, with the top bar's Invoke control bound to the previewed source and run facts in a side rail. The old list, side panel and Open-as menu go; performance baselines drop their sources.
Card, row and rail menus for library and project workflows drop the per-item description and the wider minimum width that made room for it.
… colour The export clone referenced theme variables by names that do not exist for flat dotted tokens, so node borders came out in the text colour.
…l is missing The inputs view used a border token the theme does not define, so the border fell back to the text colour.
…essed control Under a zoomed canvas the text area's bottom edge lands inside a device pixel and the masked fade let a slice of text through. Inside a host marked as a control well the fade is an overlay that reaches the outer edge and redraws the border; elsewhere the mask is unchanged.
Node state is derived in one place: invalid and failed nodes share a red outline and header, the selection ring takes the node's tone, and keyboard focus is a separate ring. The header gets a smaller title and ghost status and info buttons with panels; rows show their actions on hover or focus, mark in-form fields on the label and invalid fields on the control, and controls sit in a recessed well. Collapsed nodes show one merged port per side with counted edges, a selected node's edges are emphasised, the minimap tints invalid and running nodes, and the Current Image node follows the gallery selection and can be dragged. The editor chunk's recorded size and file list in the performance baseline are updated for this.
…ailed load A lazily imported module renders behind an error boundary with one fallback for loading and failure, retries on the next mount, and renders directly once loaded.
Labels are trimmed to the body of their text so a port lines up with the letters, not the line box; ports and edge anchors do not move. Rename inputs use the size of the text they replace, and the node panels load through the shared on-demand helper.
…the workflow menu The workflow name opens a menu of the project's workflows with New workflow and Workflow library beneath it. The widget menu groups its own items under This workflow and Import and export, with an Export submenu that includes Download as PNG; the export flow is shared with the toolbar and loads on first use. The performance baseline lists the two modules that now load with every editor route.
joshistoast
marked this pull request as ready for review
November 10, 2026 12:14
…-redesign # Conflicts: # invokeai/frontend/webv2/scripts/run-project-file-journey.mjs
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Finding a workflow in a growing library meant scrolling a tabbed grid with one fixed sort per tab, no way to filter the project's own workflows, and no sign of whether a workflow would run. Judging one before opening it meant a second dialog that drew the compiled backend graph at an unreadable size. This redesigns the library, replaces that preview, and brings the editor's nodes and header in line with it.
Workflow library
last_run_atis a library order key, with a direction menu on every key. A completed run of a project workflow linked to a template marks that template as run. Sort, direction, layout and card size persist per account; search and tags reset when the dialog closes.Preview in place
Editor
Screenshots are from the mock backend, so names and dates are fixture data.
My library, grid, with the detail rail
Right-click opens the menu for that card; the selection and rail stay put
List layout
View menu: layout, card size, thumbnail display
In this project, list, with the linked-template rail
Narrow window: places menu, Tags button, summary sheet
Short window: the sheet expanded over the cards
Light theme, list
The screenshots above predate the preview, node and header changes: the rail now also shows the author, inputs and notes, and its button reads Preview. Screenshots of the preview, View graph, the refreshed nodes and the switcher are still to be added.
Related Issues / Discussions
Addresses #10168: sort keys and direction, last-run ordering, multi-tag filtering, search and sort on This project, and the persistence rules. Not included, and left for follow-ups: the readiness and callable filters (they need a server-side requirements index to be correct beyond the loaded window), pinned workflows (needs a backend flag) and drag reordering in This project.
QA Instructions
From
invokeai/frontend/webv2under Node 22 / pnpm 10:src/platform/ui/ConfirmDialog.browser.test.tsx > reconciles a confirmation closed while its Activity is hidden, and the accessibility run stops at the hidden-maintenance journey with the same symptom (an alert dialog not hidden while its Activity is hidden), so the journeys after it do not run in sequence. Both reproduce on the base commit in this environment.pytest tests/app/services/workflow_recordspasses; Ruff clean.Review
Findings resolved during review, library: a stored name sort flipping to Z–A on upgrade (a missing direction now takes the key's natural default); place totals being probed on every mount; the last-run touch not refreshing the store; project search ignoring tags; the browse filter not resetting on close; background refreshes while the dialog was closed (now held by an in-use lease); the selected card staying in a loading state after its page was evicted; keyboard focus landing on list placeholders; hover quick actions shifting rows; a stale kept position highlighting the wrong row after a reorder; and a centre click on a small card landing on the hidden quick-action strip.
Preview: preview mode surviving a library close that bypassed its own controls; a node card for a node that left the document crashing the stage; a stale find count; a late step selecting after the preview closed; stage controls painting over the node card; the editor loading the preview dialog at startup through a shared barrel; a starter-models fetch triggered by opening View graph; and the footer's Invoke advertising a shortcut that is suppressed while the dialog is open.
Editor: exported images dropping edges between collapsed nodes and dimming edges when a node was selected; a merged edge being reconnectable or losing its selection on a second click, so only part of it moved or deleted; mass edge selection being quadratic; a failed load of an on-demand panel or of the switcher's list crashing the editor chrome (both now fall back and retry); the switcher's actions shifting as its list arrived, so a quick click could land on another row; the launchpad's Model Manager reaching the editor runtime through the switcher's scrolling list; and split node titles losing the space at their split point.
Remaining limits: the platform Scrollable rewrites four inherited custom properties on every scroll event, which restyles every descendant; the grid and the List pin them locally. Recent in a multi-user install lists globally opened bundled templates. Tag filtering uses the server's substring match. On very tall windows showing more than about 44 list rows, the farthest rows stay placeholders because the browse window holds 60 positions. A preview graph that does not fit a narrow stage opens at its readable zoom with a minimap. The publication review still opens the preview dialog over its own dialog. The Current Image node has no previous/next buttons: nothing outside the Gallery and Preview widgets can step the gallery selection yet. Whether outputs should share rows with inputs, as in the legacy editor, is undecided; rows keep today's order. Ports are centred on a label's lowercase letters, so all-capital labels sit up to two pixels off. The first time the switcher opens in a page session its rows redraw once when the themed scroll container arrives. Light themes and Firefox/Safari were not checked by eye for the node changes.
Compatibility / Rollout
workflowLibrarySortDirection,workflowLibraryCardSizeandworkflowLibraryLayoutare new keys with defaults; unknown or missing values normalise to the defaults, and the previousworkflowLibrarySortvalues remain valid. The preview, node and menu changes add no persisted state; collapsing nodes never rewrites a workflow's edges.WorkflowRecordOrderBygainslast_run_at;openapi.jsonandschema.tsare regenerated. No schema migration: the column already exists and is written only through the existinglast_run_atendpoint.performance/architecture-baseline.jsonandperformance/browser-baseline.jsonare edited by hand for the file-list changes and the one chunk figure above, keeping their recorded timings.Checklist
What's Newcopy (if doing a release after this PR)