Repository navigation
fix(app-shell): the Studio canvas runs a report or widget over a draft dataset before the package publishes - #27758
Conversation
…dget before the package publishes (#27585) `queryDataset` takes an explicit `previewDrafts` option (the caller's answer wins over the page URL), and the Studio's report and dashboard previews hand the renderers a data source whose dataset queries carry it, keyed on the same signal the dataset pickers read. Claude-Session: https://claude.ai/code/session_01Utp6CYWA2yJcJwFWLpBa7Q Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Utp6CYWA2yJcJwFWLpBa7Q Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Utp6CYWA2yJcJwFWLpBa7Q Co-authored-by: Claude <noreply@anthropic.com>
|
domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC Contract reviewServed-tier: Face: the ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
|
domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC 席位核对ACCEPT · head
Generated by Claude Code |
domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC
Requested by Bill · project thread
Fixes #27585
Clause-②: yes (widening)
Metadata-protocol: none
维护者速读
queryDataset新增可选参数previewDrafts。canvasDataSource.ts(画布数据源)、data-objectstack/src/index.ts的queryDataset参数一段、canvasDataSource-27585.test.tsx。pnpm --dir ui exec vitest run packages/app-shell/src/views/metadata-admin/previews/canvasDataSource-27585.test.tsx,预期 5 个测试全过。What changes
The defect. In the Studio, a report or a dashboard widget bound to a dataset that is still a draft said the dataset "is not defined in this environment" until the package published.
queryDatasetdecided the draft world only from the page URL's?preview=draft, and the Studio canvas is a draft window that does not carry that flag, so its query went to the published world, where a draft-only dataset does not exist. The dataset pickers beside the canvas already read the draft-overlaid catalog (#27518).@object-ui/data-objectstack:queryDataset(dataset, selection, options?). A new optional{ previewDrafts?: boolean }.trueputspreviewDrafts: trueon the one dataset-query request, exactly what the URL flag already put there; the server then resolves the dataset from the draft overlay. It is the same explicit optionlistViews(objectName, { previewDrafts })takes. Absent, the page URL decides as before; given, it wins over the URL. A caller that passes nothing sends a byte-identical request.@object-ui/app-shell: the canvas data source.ReportPreviewandDashboardPreviewrender throughuseCanvasDataSource()(new, internal,previews/canvasDataSource.ts). In the Studio, keyed on the signal the dataset pickers read (StudioDatasetAuthoringContext, provided by the Interfaces pillar around the canvas), it hands the runtime renderers the adapter with itsqueryDatasetasking forpreviewDrafts; every other member is the adapter's own, bound to it. Outside the Studio (Setup's editors) it hands back the adapter unchanged. The shape follows the Form tab preview's data source inStudioDesignSurface.tsx(formPreviewSource): the preview hands the runtime renderer a data source rather than threading a flag throughplugin-reportandplugin-dashboard, so every dataset query those renderers make (the report, a dataset widget, a dataset-bound chart, a filter bar's options) carries it with no change in either plugin. One source per adapter is kept in a moduleWeakMap, so its identity is the adapter's and never auseMemoresult (ui/AGENTS.md #10).The ruling. "⛔ The canvas resolves draft datasets the same way the draft preview resolves other draft metadata. It does not add a second lookup." The draft preview resolves draft metadata with one request-level flag the server honours (
?preview=drafton/meta,previewDraftson the dataset query). The canvas now sends that same flag on the same request. The dataset is still named and only the server resolves it: no client-side read of the draft definition, no inline post of it.Measurements (the order's mechanism assumptions)
packages/rest/src/analytics-routes.ts, thePOST /analytics/dataset/queryhandler:previewDraftsisbody.previewDrafts === trueor?preview=draft, admitted only for a callermayReadPendingDraftsadmits; the by-name lookup readsgetMetaItems({ type: 'dataset', previewDrafts }), the draft-overlaid list in which draft-only items surface, then handspreviewDraftson tosvc.queryDataset. It is the one owner of that path in the tree. No server file changes.useStudioDatasetAuthoring()(studio-design/datasetCreate.tsx), the context the Interfaces pillar provides around both the inspector and the canvas.DashboardWidgetInspectorandReportDefaultInspectorread it to askuseDatasetCatalogforpreviewDraftssince Studio cannot report or chart on the package's own objects: the report and dashboard-widget dataset pickers list only pre-existing sys_/showcase_ datasets, and Studio offers no way to create a dataset #27518; the canvas previews now read the same one.DashboardViewandReportViewrender with the plain adapter and pass no option, soqueryDatasetstill follows the page URL only: no flag on a runtime page, the flag inside the app draft preview, as before.Tests
ui/packages/app-shell/src/views/metadata-admin/previews/canvasDataSource-27585.test.tsx(new). Through the realObjectStackAdapter(fetch stubbed) and the realplugin-report/plugin-dashboardrenderers. The stub server answers the dataset by name only when the request carriespreviewDrafts: true, and otherwise answers the door's own404 NOT_FOUND, which is what the door does for a draft-only dataset.{ datasetName: 'draft_sales', previewDrafts: true }on every dataset query and draw the draft's rows.previewDraftsand draw no rows.datasetDraftsSourceis one source per adapter, binds every other member to the adapter, and mergespreviewDraftsinto a caller's own options.ui/packages/data-objectstack/src/queryDataset.test.ts, new block "the draft world (objectstack#27585)": the option with no URL flag sendspreviewDrafts: true; neither sends nothing; the URL flag alone still sends it; an explicitpreviewDrafts: falsewins over the URL flag.Targeted run, ablations and type-check (head 27e684e, before the main merge)
pnpm --dir ui exec vitest run --reporter=verbose packages/data-objectstack/src/queryDataset.test.ts packages/app-shell/src/views/metadata-admin/previews/canvasDataSource-27585.test.tsx packages/app-shell/src/views/metadata-admin/previews/ReportPreview.dataset.test.tsx packages/app-shell/src/views/metadata-admin/previews/DashboardPreview.loneWidget.test.tsx packages/app-shell/src/views/metadata-admin/previews/DashboardPreview.i18nTitle-10847.test.tsx·VERDICT command-exit 0· Test Files 5 passed (5) · Tests 56 passed (56). The three existing preview test files are unchanged and green: outside the Studio the previews callqueryDataset(name, selection)exactly as before.scripts/ablation-replace.mjs:canvasDataSource.tsanchorreturn inStudio && adapterreplaced with a marker that always hands back the adapter (anchor 1 to 0, blob a3c4bd40de49 to 3f04dfb10d35). The two Studio tests went red (Tests 2 failed, 3 passed); restored to blob a3c4bd40de49.index.tsanchorconst previewDrafts = options?.previewDrafts !== undefinedreplaced with a marker that ignores the option (blob a258fe17a1ec to 36c53a39804e). Red: the two option tests inqueryDataset.test.tsand the two Studio tests (Tests 4 failed, 36 passed); restored to blob a258fe17a1ec.pnpm --filter @object-ui/data-objectstack run type-check && pnpm --filter @object-ui/app-shell run type-check(the latter also compiles the tests throughtsconfig.test.json) ·VERDICT command-exit 0.@object-ui/*tosrc, so neither ablation needed a dist build.Acceptance notes
mayReadPendingDrafts); anyone else gets the published dataset, as if the flag were absent. A Studio author is admitted by construction.useDatasetFields, reading objects without the draft overlay) is a metadata read, not a dataset query; this option does not reach it. Left as the card noted it.ui/packages/data-objectstack/src/index.ts(the record-page open request, another region). This diff in that file is thequeryDatasetdocblock and its option only; whichever lands second rebases.Verification
Derived gates (dispatch-gates --commands, on the merged head)
Head
41685152(the main merge). Each line is the command and the exit code captured before any pipe.node scripts/pm/dispatch-gates.mjs --ranreconciliation: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN.After the merge, on the same head: the six dataset/preview test files (the five above plus
queryDataset.forbidden-10899.test.ts) ·VERDICT command-exit 0· Test Files 6 passed (6) · Tests 59 passed (59);eslintover the six touched source and test files: 0 errors (the warnings are pre-existing ones in the edited files; the two new files carry none).CI runs every other family on this PR; its check-runs are the record.
Generated by Claude Code