Repository navigation
fix(studio): an item just added to a dashboard list property is held until it is filled in, not autosaved and refused (#27459) - #27784
Merged
Conversation
… of autosaving it "Add item" under a dashboard's Global Filters or header Actions appends an item with every input unset; the draft door refused it with a 422 and every later save of the same body was refused for it too. The Interfaces pillar now holds such an item the way it holds a widget waiting for its binding: judged by the spec's own DashboardSchema, unsent while every issue on the item is an input it leaves unset, with a held line naming it and "Show me" opening the dashboard's properties. Claude-Session: https://claude.ai/code/session_01Utp6CZQGM7KwDbfPanMns3 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Utp6CZQGM7KwDbfPanMns3 Co-authored-by: Claude <noreply@anthropic.com>
…-0gr0r6 Claude-Session: https://claude.ai/code/session_01Utp6CZQGM7KwDbfPanMns3 Co-authored-by: Claude <noreply@anthropic.com>
Contributor
Author
|
domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe 席位核对ACCEPT · head
Generated by Claude Code |
This was referenced Oct 30, 2026
Closed
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.
Requested by Bill · project thread
维护者速读
globalFilters[N] = {},草稿门 422;之后每次保存都带着这个空项继续 422,所以在这之后改的 Label 等都丢了(重载后消失)。DashboardSchema,不另存必填清单;某项只在「所有报错都落在它还没填的输入上」时才拦,填了错值的照常发送并显示红色拒绝条。最坏情况是多拦一次(提示行 + Show me 可解)。回滚即 revert 本 PR。ui/packages/app-shell/src/views/studio-design/metadataError.ts(listItemHeldInput/heldListItem/dashboardHeldEdit)、StudioDesignSurface.tsx(StudioHeldNotice泛型化与界面支柱的 Show me 分支)、InterfacesPillar.heldListItem-27459.test.tsx。pnpm --dir ui exec vitest run packages/app-shell/src/views/studio-design/metadataError.heldListItem-27459.test.ts packages/app-shell/src/views/studio-design/InterfacesPillar.heldListItem-27459.test.tsx,预期 2 个文件 19 条全部通过。Fixes #27459
Clause-②: no
Metadata-protocol: none
What changes
The hold. The Interfaces pillar's leaf autosave already holds a dashboard whose new widget still waits for its dataset or measures (
dashboardHeldEdit, judged by the spec'sDashboardWidgetSchema). It now also holds a dashboard with an item of one of its own list properties that is merely unfinished:listItemHeldInput(body, schema, skip)asks the leaf's spec schema (DashboardSchemahere) of the body the autosave would send. Each issue is placed on the item of the outermost list its path enters. An item is held only when every issue placed on it names an input directly below it that the item leaves unset (absent, or a text cleared to an empty string). An issue on the item itself, or on an input holding a value, makes it finished but wrong: it is sent, and the refusal it draws shows as before. Thewidgetslist is skipped, so the widget rule keeps its own hold and is asked first.#nits row shows. One new clause,engine.studio.held.listItemNeedsInput(en, zh): the existing widget, step, action and field clauses name no list item.StudioHeldgains aTargettype parameter (defaultMetadataSelection, so the other pillars are unchanged) and an optionalinput. A list item's target isnull, the leaf's own properties, which no selection opens. Its "Show me" is always offered and goes through the pillar's existingshowLeafRefusal(clears the selection, opens the properties slot, expands a collapsed inspector, focuses the list by its label).prettifymoves fromSchemaForm.tsxtofield-source-label.tsasprettifyFieldName(no runtime imports there), so the held line can name a row exactly asSchemaFormdoes without importing the form component.SchemaFormimports it under its old local name; nothing else changes there.The Publish refusal and the surface's leave guard read the same reported clause (
useHeldEditReport), unchanged.Tests
metadataError.heldListItem-27459.test.ts(15 cases). Every held case is paired with the spec's verdict on the same dashboard (it refuses exactly the unset inputs): Global Filters' new item (the repeater's all-undefinedrow, and the stored{}the card saw), header Actions' new item (held for Label, then for Action URL), an Action URL cleared to blank, zh-CN naming, and the widget rule asked first. Controls: a Field filled is accepted and not held; a Field cleared to blank is one the spec takes, so not held; a header action refused for the URL it holds is sent; an item with an unset Field and a wrongtypeis sent; a list holding a non-item value is sent; a dashboard the spec accepts holds nothing.InterfacesPillar.heldListItem-27459.test.tsx(4 cases), the realDashboardDefaultInspectorover a recording metadata client: the card's path (Filters → Global Filters → Add item, then a Label edit) sends no PUT past the debounce, shows no red strip, and names the Field; "Show me" focuses a control in the Global Filters row; filling the Field sends one save carrying the item and the Label edit kept meanwhile, whichDashboardSchemaaccepts, and clears the line; control: a Label edit alone saves at once.Readings below are on the final head
7ff9cb5c(this branch merged withorigin/main) unless a line says otherwise.Ablation (ablation-replace, restored blob == HEAD)
metadataError.ts: indashboardHeldEdit,return item ? heldListItem(replaced byreturn item && !"ABLATED_27459" ? heldListItem((no list item is ever held, the behaviour onmain), on pre-merge head62dac23e→ 9 failed / 19 across the two new suites: the 6 held predicate cases and the 3 pillar cases that need a hold; the 9 predicate controls and the pillar's "Label edit alone saves at once" control stay green. Restored: blob after restore == blob at HEAD (e52f543c2055),git diff HEADempty.srcdirectly, so no dist build sits between the mutation and the run.Affected suites (pre-merge head 62dac23): 220 files / 2807 tests passed
Every ui test file naming
metadataError,SchemaForm,field-source-label,StudioHeldNotice,DashboardDefaultInspector,InterfacesPillar,engine.studio.heldormetadata-form-i18n(130 files across app-shell, core, data-objectstack and the console), plus the wholepackages/i18n/directory, under the verification lock:Test Files 220 passed (220) · Tests 2807 passed | 13 skipped (2820), lock VERDICT command-exit 0. The rest of the ui tree is left to CITest UI.After merging origin/main (head 7ff9cb5)
The merge conflicted only beside a sibling card's new held clause (
engine.studio.held.fieldNeedsInputin en / zh) and its new spec imports inmetadataError.ts; both sides kept.Acceptance notes
studio-authoring.dashboard-widget-and-filter-typesacceptance[4]).listItemHeldInputtakes the schema as an argument, so the report's list items need onlyReportSchemaand the report form at the pillar's leaf gate; a chart type set before its axes is not a list item and needs its own rule. Named in the report for the seat to carry as a follow-up card before this one closes.GlobalFilterSchema.fieldis a plain string), so it is sent, not held: the hold is never stricter than the contract.Derived gates (dispatch-gates --commands on this diff, head 7ff9cb5): 34 / 34 exit 0
dispatch-gates --ran: 34 derived families accounted for, 34 run, 0 NOT-MEASURED.node scripts/check-sdui-manifest.mjs(the ui card gate) is among them. CI runs the type-check lanes, the artifact-roster and wide-population families andTest UI.Generated by Claude Code