From 56e4bba8ef91a1bf8ca0c9abbe64aa84c0f40ca5 Mon Sep 17 00:00:00 2001 From: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Date: Sun, 14 Jun 2026 11:03:38 +0500 Subject: [PATCH] fix(spec): sourceView view picker + hide template on list pages (ADR-0047) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit interfaceConfig.sourceView gets widget:'view-ref' + dependsOn:'source' so the page editor offers a dropdown of the source object's views instead of a free-text name the author can mistype (objectui ships the view-ref widget; degrades to text until then). The template field is hidden for type=='list' since interface pages render via InterfaceListPage and ignore the region template — same rationale as the already-hidden Data Context / Layout sections. Co-Authored-By: Claude Opus 4.8 (1M context) --- .changeset/interface-form-sourceview-picker.md | 8 ++++++++ packages/spec/src/ui/page.form.ts | 8 ++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 .changeset/interface-form-sourceview-picker.md diff --git a/.changeset/interface-form-sourceview-picker.md b/.changeset/interface-form-sourceview-picker.md new file mode 100644 index 0000000000..e1be296972 --- /dev/null +++ b/.changeset/interface-form-sourceview-picker.md @@ -0,0 +1,8 @@ +--- +"@objectstack/spec": patch +--- + +ui(page.form): sourceView is a view picker; hide template on list pages + +- `interfaceConfig.sourceView` now declares `widget: 'view-ref'` + `dependsOn: 'source'` so the page editor renders a dropdown of the source object's views instead of a free-text input (where an author could type a non-existent view name). The objectui `view-ref` widget reads the source object's views; until it ships, the field degrades to the existing text input. +- The `template` field is now hidden for `type == 'list'` (`visibleOn: "data.type != 'list'"`). A list/interface page renders via InterfaceListPage and ignores the region template, so showing the field only added noise — same rationale as the already-hidden Data Context / Layout sections. diff --git a/packages/spec/src/ui/page.form.ts b/packages/spec/src/ui/page.form.ts index d34f66ab93..5e2a3a901e 100644 --- a/packages/spec/src/ui/page.form.ts +++ b/packages/spec/src/ui/page.form.ts @@ -37,7 +37,9 @@ export const pageForm = defineForm({ ], helpText: 'Page kind. "List / Interface" binds a source view into a curated surface — how it looks (grid / kanban / calendar / …) is a visualization set under Interface, not a page type.', }, - { field: 'template', colSpan: 2, helpText: 'Layout template (e.g., "header-sidebar-main")' }, + // A list/interface page renders via InterfaceListPage and ignores the + // region template, so hide it there (same rationale as Data Context / Layout). + { field: 'template', colSpan: 2, visibleOn: "data.type != 'list'", helpText: 'Layout template (e.g., "header-sidebar-main")' }, { field: 'description', widget: 'textarea', colSpan: 2, helpText: 'Page description for navigation' }, ], }, @@ -86,7 +88,9 @@ export const pageForm = defineForm({ // Keep this list in sync with InterfacePageConfigSchema. fields: [ { field: 'source', widget: 'ref:object', helpText: 'Object this list reads from' }, - { field: 'sourceView', helpText: 'Named list view to inherit columns/filter/sort from (blank = object default)' }, + // Pick from the source object's views instead of typing a name. + // `dependsOn: 'source'` tells the picker which object's views to list. + { field: 'sourceView', widget: 'view-ref', dependsOn: 'source', helpText: 'Named list view to inherit columns/filter/sort from (blank = object default)' }, { field: 'appearance', type: 'composite', helpText: 'Allowed visualizations (Grid / Kanban / Calendar / …) and description visibility' }, { field: 'userFilters',