diff --git a/.changeset/11601-ref-dataset-widget.md b/.changeset/11601-ref-dataset-widget.md new file mode 100644 index 0000000000..94ad2ff040 --- /dev/null +++ b/.changeset/11601-ref-dataset-widget.md @@ -0,0 +1,25 @@ +--- +'@object-ui/app-shell': minor +--- + +A Studio form field that declares the `ref:dataset` widget now renders a dataset picker instead of the JSON editor fallback (objectui#11601). + +The metadata forms had no renderer for `ref:dataset`, so a field declaring it fell back to a raw +JSON box with a "falling back to JSON" note. The new widget offers the analytics dataset catalog, +showing each dataset's label beside its name and its description after it, and writes the dataset +name. It works for a field in a form section and for a column of a repeater row, in both the grid +and the card layouts. A stored dataset the catalog does not list stays visible and is marked +"(not found)". While the catalog is loading the field shows the stored name, and if the catalog +fails to load the field shows the load-failure notice beside a text box that stays editable. A +form whose host does not supply a catalog shows a plain text input for the dataset name. + +The report inspector now supplies its dataset catalog to the report's form. A joined report's +block row picks up the dataset picker once the spec's "Joined blocks" row declares `ref:dataset` +(objectstack#21714). Until objectui is built against a spec that carries that declaration, a +block's `dataset` is still entered as free text. + +The dataset option list that the report and dashboard-widget inspectors already show is unchanged. + +`SchemaForm`'s `widgetContext` prop gains one optional member, `datasets`, the catalog the new widget +reads. It is additive: a host that passes no `datasets` renders exactly as before, except that a +`ref:dataset` field now shows the text input instead of the JSON fallback. diff --git a/packages/app-shell/src/views/metadata-admin/SchemaForm.controlWidgetGridNaming-9889.test.tsx b/packages/app-shell/src/views/metadata-admin/SchemaForm.controlWidgetGridNaming-9889.test.tsx index d7fae5ff7f..99d2a98670 100644 --- a/packages/app-shell/src/views/metadata-admin/SchemaForm.controlWidgetGridNaming-9889.test.tsx +++ b/packages/app-shell/src/views/metadata-admin/SchemaForm.controlWidgetGridNaming-9889.test.tsx @@ -66,6 +66,7 @@ const ctx: WidgetContext = { objectNames: loaded(['account', 'contact']), objectFields: loaded([{ name: 'status', label: 'Status' }]), objectViews: loaded([{ name: 'account.all', label: 'All' }]), + datasets: loaded([{ name: 'sales_metrics', label: 'Sales metrics', dimensions: [], measures: [] }]), }; /** @@ -90,10 +91,11 @@ interface WidgetCase { faceName: string; } -/** The eleven `labelling: 'control'` widgets. Checked against the registry below. */ +/** The `labelling: 'control'` widgets. Checked against the registry below. */ const CONTROL_CASES: WidgetCase[] = [ { widget: 'ref:object', control: (c) => c.querySelector('[role="combobox"]'), faceName: 'the object picker' }, { widget: 'ref:component', control: (c) => c.querySelector('input'), faceName: 'the free-text component id box' }, + { widget: 'ref:dataset', control: (c) => c.querySelector('[role="combobox"]'), faceName: 'the dataset picker' }, { widget: 'object-selector', control: (c) => c.querySelector('[role="combobox"]'), faceName: 'the object picker' }, { widget: 'field-selector', control: (c) => c.querySelector('input'), faceName: 'the "select an object first" box' }, { widget: 'field-ref', control: (c) => c.querySelector('[role="combobox"]'), faceName: 'the object-field picker' }, diff --git a/packages/app-shell/src/views/metadata-admin/SchemaForm.refDatasetWidget-11601.test.tsx b/packages/app-shell/src/views/metadata-admin/SchemaForm.refDatasetWidget-11601.test.tsx new file mode 100644 index 0000000000..8d00abae01 --- /dev/null +++ b/packages/app-shell/src/views/metadata-admin/SchemaForm.refDatasetWidget-11601.test.tsx @@ -0,0 +1,205 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * objectui#11601 — a spec-form field that declares `widget: 'ref:dataset'` + * renders the dataset picker, and writes the dataset NAME. + * + * ## The defect + * + * `ref:dataset` is a declared hint — the spec's `reportForm` puts it on the + * report's top-level `dataset` — but `WIDGETS` had no entry for it, so + * `resolveFieldFace` sent it down the announced raw-JSON face: a JSON + * `