You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit a7df552
Browse filesBrowse the repository at this point in the historyBrowse files
docs(spec): ObjectNavItemSchema.viewName states the view the console opens when it is omitted (#21981)
Fixes#21973
Clause-②: no
## What changed
`ObjectNavItemSchema.viewName`'s describe said `Defaults to "all"`. The
console does not do that. The describe now states the console's real
rule. One sentence changed, and "Ignored when `recordId` is set." stays:
> Default list view to open. When omitted, the console opens the
object's default list view, else its first declared list view; `all`
names the console's fallback tab, which exists only for an object that
declares no list view. Ignored when `recordId` is set.
- `packages/spec/src/ui/app.zod.ts`: the describe, plus a short docblock
above it naming the objectui code the sentence mirrors.
- `content/docs/references/ui/app.mdx`: regenerated with `pnpm --filter
@objectstack/spec gen:docs` (the five `viewName` rows). Not edited by
hand.
- `packages/lint/src/lint-view-refs.ts`: only the header comment's quote
of the old sentence (about `:46`) moves. This file was declared on
#6023. No lint logic, rule or test changes.
- `.changeset/21973-nav-view-name-default.md`: `@objectstack/spec`
`patch`.
- ⛔ No schema, type, optionality, default, export or accept-set change.
No runtime change, and no objectui file.
## The runtime rule, read at objectui `.objectui-sha` =
`0abd4f9f8769fc4c19ad2f96707684876f74c09f` (read-only)
- `packages/layout/src/NavigationRenderer.tsx` `resolveHref`: precedence
is `recordId`, then `filters`, then `viewName`. With no `viewName`, the
entry links to the bare object route, which has no view segment.
- `packages/app-shell/src/views/ObjectView.tsx:2151`: `activeViewId =
resolvedViewId || defaultViewId || views[0]?.id`. `defaultViewId`
(`:2129`) is the first tab whose `isDefault` is set.
- `buildViewTabs` (`:936`): it sets `isDefault: true` on the primary
`list` and moves that tab to the front. It builds the `fallbackTab`, `{
id: 'all', label: allRecords }`, only when `viewList.length === 0`,
which means no defined view and no primary `list`. Saved overlay rows
are merged after that, and they can carry their own `isDefault` (a
user's set-default). "The object's default list view" covers both cases.
- `resolveViewId` (`@object-ui/core`, `utils/resolve-view-id.ts`)
matches three ways: exact id, short name retried with the object prefix
added, and qualified name retried with the prefix stripped. On a miss it
returns `undefined`. `ObjectView` then logs a `console.warn` and falls
back to `defaultViewId || views[0]`. The describe leaves this out to
stay short. `view-ref-nav-view-missing` in `packages/lint` already
refuses an unresolvable name at build time.
## Census: other live text that restates the old default
Searched docs (excluding `content/docs/releases/`), skills, examples,
`packages/spec` and the rest of the tree for `Defaults to "all"`,
`Defaults to 'all'`, and default-`all`-view phrasings.
- `content/docs/references/ui/app.mdx`: lines 116, 465, 655, 842 and
1084. Regenerated in this PR.
- `packages/lint/src/lint-view-refs.ts:46`: the quote. Moved in this PR.
- `packages/lint/src/lint-view-refs.test.ts:240`: a test comment, "The
schema documents viewName as 'Defaults to "all"'". It is in the lint
lane and asserts nothing about the text, so it is listed here and not
edited.
- No test asserts the describe text. Searched `*.test.ts`, `*.snap` and
`*.json`.
- No hit in `skills/**`, `examples/**`, `content/docs/ui/apps.mdx` or
`docs/**`.
## Tests and gates (all at head `b53d7b5a34`)
- `pnpm --filter @objectstack/spec build`: VERDICT command-exit 0.
- `pnpm --filter @objectstack/spec check:generated`:
- Before the regeneration: `✗ 1 of 15 artifact(s) stale:
content/docs/references/**`.
- After: `✓ All 15 generated artifacts are up to date`.
- `pnpm --filter @objectstack/spec typecheck`: exit 0.
- `pnpm --filter @objectstack/spec exec vitest run --project local
--maxWorkers=2`: `Test Files 619 passed (619)`, `Tests 18485 passed | 1
todo`.
- `pnpm --filter @objectstack/lint typecheck` and `vitest run
--maxWorkers=2`: `Test Files 119 passed (119)`, `Tests 5624 passed | 5
skipped`.
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 104 commands. All 104 ran and exited
0.
- `--ran` reconciliation: `✓ dispatch-gates --ran: 104 derived
famil(ies) accounted for — 104 run, 0 NOT-MEASURED`.
- The first attempt hit four `PREREQUISITE NOT MET` (exit 3):
`check:doc-formula-expressions`, `check:doc-security-posture`,
`check:skill-examples` and `check:dual-build-cjs-loads`. Each was re-run
green after building what it reads.
- NOT MEASURED, because CI owns them:
- The six path-scheduled CI jobs that `dispatch-gates` lists (Test Core,
Temporal Conformance, Dogfood, Dogfood Verify CLI, Build Core, Build
Docs).
- The workflow-valued families.
- The repo-wide `pnpm lint`.
## Changeset, measured
- `@objectstack/spec` ships `dist` and `src/**/*.zod.ts` (`files[]`).
After the build, the new describe text is in
`packages/spec/dist/ui/index.{js,mjs}`. Positive control: the `recordId`
describe is in the same files. The old text has zero hits.
- `@objectstack/lint` ships only `dist`, `README.md` and `CHANGELOG.md`.
The header comment has zero hits in `packages/lint/dist`. Positive
control: `view-ref-nav-view-missing` hits `index.js`, `index.cjs` and
`runtime.js`. So lint publishes nothing new and gets no changeset.
## Acceptance notes
- **Wording vs. the dispatch.** The dispatch said `all` exists "only for
an object that declares no `listViews`". The code's condition is wider
than `listViews`: no defined view AND no primary `list`. An object that
declares only a default `list` gets no `all` tab, and in the spec
`listViews` means a container's *additional* named views. So the
sentence says "declares no list view".
- **The first sentence is kept.** "Default list view to open." is quoted
verbatim in four places:
`packages/spec/src/ai/solution-blueprint.zod.ts:174`,
`packages/platform-objects/src/apps/setup-users-nav-view.test.ts:13`,
`packages/lint/CHANGELOG.md:4743` and
`packages/spec/CHANGELOG.md:17669`. Rewriting it would make those quotes
stale and step outside the declared file surface.
- **`views[0]` and the user's tab order.** `views[0]` follows a per-user
tab order (localStorage) and saved `sortOrder` when they exist;
otherwise it is declared order. The describe states the metadata rule.
- **`lint-view-refs.ts:64`–`:66` is untouched.** It says the schema's
`all` "resolves only when the object actually declares it". That is
outside the declared quote. It stays true for the lint, because the rule
skips objects whose list-view namespace is empty, and those are exactly
the objects that get the runtime fallback tab. Carrier: none.
- **Serial note.** #21976 (#21968) also edits `app.zod.ts`, about 1,200
lines away (near `:1655`). `origin/main` was re-fetched before this PR
opened (`dcf3eb494a`). Nothing that landed touches these four files, so
no merge was needed.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01T9u38rswFp5Rw8DswRUReJ)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
`ObjectNavItemSchema.viewName`'s describe no longer says the default is "all". It now states what the console does when an object nav entry names no view: it opens the object's default list view, else its first declared list view. `all` is only the console's fallback tab, and it exists only for an object that declares no list view.
6
+
7
+
Clause-②: no
8
+
9
+
- The rule is read from objectui at the `.objectui-sha` pin. `ObjectView` opens `defaultViewId || views[0]`, where `defaultViewId` is the view `buildViewTabs` marks `isDefault` (the default `list`). `buildViewTabs` adds the `all` tab only when the object has no list view at all.
10
+
- An author who omitted `viewName` expecting all records got that default or first declared view instead. When the object declares more than one list view, name the one the entry should open in `viewName`.
11
+
- The generated app reference page follows (#21973). The lint header that quoted the old sentence follows too, as a comment only.
12
+
- ⛔ No schema, type, optionality, default, export or accept-set change. The console's behaviour does not change.
Copy file name to clipboardExpand all lines: content/docs/references/ui/app.mdx
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -113,7 +113,7 @@ const result = ActionNavItemSchema.parse(data);
113
113
|**requiresService**|`string`| optional | Hide/disable this entry unless the named kernel service is registered |
114
114
|**type**|`'object'`| ✅ ||
115
115
|**objectName**|`string`| ✅ | Target object name |
116
-
|**viewName**|`string`| optional | Default list view to open. Defaults to "all". Ignored when `recordId` is set. |
116
+
|**viewName**|`string`| optional | Default list view to open. When omitted, the console opens the object's default list view, else its first declared list view; `all` names the console's fallback tab, which exists only for an object that declares no list view. Ignored when `recordId` is set. |
117
117
|**recordId**|`string`| optional | Navigate directly to this record id instead of the list view. Supports template vars: `{current_user_id}`, `{current_org_id}`. |
118
118
|**recordMode**|`Enum<'view' \| 'edit'>`| optional | Open the record in view (default) or edit mode. Only meaningful when `recordId` is set. |
119
119
|**filters**|`Record<string, string>`| optional | URL filter conditions — targets the /:objectName/data bare surface via filter[`<field>`]=`<value>` params instead of a saved view. Values support template vars `{current_user_id}`, `{current_org_id}`. Mutually exclusive with recordId/viewName. |
@@ -462,7 +462,7 @@ Documentation entry on the app menu (ADR-0046). Targets a `book` and/or a `doc`
462
462
|**requiresService**|`string`| optional | Hide/disable this entry unless the named kernel service is registered |
463
463
|**type**|`'object'`| ✅ ||
464
464
|**objectName**|`string`| ✅ | Target object name |
465
-
|**viewName**|`string`| optional | Default list view to open. Defaults to "all". Ignored when `recordId` is set. |
465
+
|**viewName**|`string`| optional | Default list view to open. When omitted, the console opens the object's default list view, else its first declared list view; `all` names the console's fallback tab, which exists only for an object that declares no list view. Ignored when `recordId` is set. |
466
466
|**recordId**|`string`| optional | Navigate directly to this record id instead of the list view. Supports template vars: `{current_user_id}`, `{current_org_id}`. |
467
467
|**recordMode**|`Enum<'view' \| 'edit'>`| optional | Open the record in view (default) or edit mode. Only meaningful when `recordId` is set. |
468
468
|**filters**|`Record<string, string>`| optional | URL filter conditions — targets the /:objectName/data bare surface via filter[`<field>`]=`<value>` params instead of a saved view. Values support template vars `{current_user_id}`, `{current_org_id}`. Mutually exclusive with recordId/viewName. |
@@ -652,7 +652,7 @@ A navigation contribution: a package injecting nav items into an app it does not
652
652
|**requiresService**|`string`| optional | Hide/disable this entry unless the named kernel service is registered |
653
653
|**type**|`'object'`| ✅ ||
654
654
|**objectName**|`string`| ✅ | Target object name |
655
-
|**viewName**|`string`| optional | Default list view to open. Defaults to "all". Ignored when `recordId` is set. |
655
+
|**viewName**|`string`| optional | Default list view to open. When omitted, the console opens the object's default list view, else its first declared list view; `all` names the console's fallback tab, which exists only for an object that declares no list view. Ignored when `recordId` is set. |
656
656
|**recordId**|`string`| optional | Navigate directly to this record id instead of the list view. Supports template vars: `{current_user_id}`, `{current_org_id}`. |
657
657
|**recordMode**|`Enum<'view' \| 'edit'>`| optional | Open the record in view (default) or edit mode. Only meaningful when `recordId` is set. |
658
658
|**filters**|`Record<string, string>`| optional | URL filter conditions — targets the /:objectName/data bare surface via filter[`<field>`]=`<value>` params instead of a saved view. Values support template vars `{current_user_id}`, `{current_org_id}`. Mutually exclusive with recordId/viewName. |
@@ -839,7 +839,7 @@ This schema accepts one of the following structures:
839
839
|**requiresService**|`string`| optional | Hide/disable this entry unless the named kernel service is registered |
840
840
|**type**|`'object'`| ✅ ||
841
841
|**objectName**|`string`| ✅ | Target object name |
842
-
|**viewName**|`string`| optional | Default list view to open. Defaults to "all". Ignored when `recordId` is set. |
842
+
|**viewName**|`string`| optional | Default list view to open. When omitted, the console opens the object's default list view, else its first declared list view; `all` names the console's fallback tab, which exists only for an object that declares no list view. Ignored when `recordId` is set. |
843
843
|**recordId**|`string`| optional | Navigate directly to this record id instead of the list view. Supports template vars: `{current_user_id}`, `{current_org_id}`. |
844
844
|**recordMode**|`Enum<'view' \| 'edit'>`| optional | Open the record in view (default) or edit mode. Only meaningful when `recordId` is set. |
845
845
|**filters**|`Record<string, string>`| optional | URL filter conditions — targets the /:objectName/data bare surface via filter[`<field>`]=`<value>` params instead of a saved view. Values support template vars `{current_user_id}`, `{current_org_id}`. Mutually exclusive with recordId/viewName. |
@@ -1081,7 +1081,7 @@ Documentation entry on the app menu (ADR-0046). Targets a `book` and/or a `doc`
1081
1081
|**requiresService**|`string`| optional | Hide/disable this entry unless the named kernel service is registered |
1082
1082
|**type**|`'object'`| ✅ ||
1083
1083
|**objectName**|`string`| ✅ | Target object name |
1084
-
|**viewName**|`string`| optional | Default list view to open. Defaults to "all". Ignored when `recordId` is set. |
1084
+
|**viewName**|`string`| optional | Default list view to open. When omitted, the console opens the object's default list view, else its first declared list view; `all` names the console's fallback tab, which exists only for an object that declares no list view. Ignored when `recordId` is set. |
1085
1085
|**recordId**|`string`| optional | Navigate directly to this record id instead of the list view. Supports template vars: `{current_user_id}`, `{current_org_id}`. |
1086
1086
|**recordMode**|`Enum<'view' \| 'edit'>`| optional | Open the record in view (default) or edit mode. Only meaningful when `recordId` is set. |
1087
1087
|**filters**|`Record<string, string>`| optional | URL filter conditions — targets the /:objectName/data bare surface via filter[`<field>`]=`<value>` params instead of a saved view. Values support template vars `{current_user_id}`, `{current_org_id}`. Mutually exclusive with recordId/viewName. |
viewName: z.string().optional().describe('Default list view to open. Defaults to "all". Ignored when `recordId` is set.'),
432
+
/**
433
+
* The rule this sentence states is the console's, read at the objectui commit
434
+
* `.objectui-sha` pins: an entry with no `viewName` links to the bare object
435
+
* route, where `ObjectView` opens `defaultViewId || views[0]` — the view
436
+
* `buildViewTabs` marks `isDefault` (the default `list`), else the first
437
+
* declared list view. Its `all` tab is the fallback `buildViewTabs` adds only
438
+
* when the object has no list view at all, so `all` is no default (#21973).
439
+
*/
440
+
viewName: z.string().optional().describe(
441
+
'Default list view to open. When omitted, the console opens the object\'s default list view, else its first declared list view; `all` names the console\'s fallback tab, which exists only for an object that declares no list view. Ignored when `recordId` is set.',
442
+
),
433
443
/**
434
444
* When set, navigate straight to the detail page of this specific
435
445
* record instead of the object's list view. Supports template
0 commit comments