Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .changeset/object-useractions-view-key-guidance.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
---
"@objectstack/spec": patch
---

docs(spec): wrong-layer guidance for `group` / `hideFields` / `rowColor` on the object `userActions` block (#11459)

`data/object.zod.ts`'s object-level `userActions` block already curated
`sort` / `search` / `filter` / `editInline` with a pointer at the VIEW
`userActions` block they actually belong to. `group` / `hideFields` /
`rowColor` — adopted onto the view's vocabulary at #11195 — shared the same
wrong-layer trap but got only the generic unknown-key rejection with an
edit-distance suggestion, which has nothing useful to offer over the object
block's `create`/`import`/`edit`/`delete`/`exportCsv` shape.

**Nothing changes about what parses.** All three keys were rejected on the
object block before this change and are rejected after it; only the message
gains the same curated pointer the other four wrong-layer keys already carry.
12 changes: 12 additions & 0 deletions packages/spec/src/data/object-strictness-batch20.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -436,6 +436,18 @@ describe('#4001 批 20 — curation is anchored to the sibling contract that mak
}
});

it('`userActions.group` / `.hideFields` / `.rowColor` name the VIEW block, same as `sort` (#11459)', () => {
// The three keys adopted onto the view's vocabulary at #11195 got only
// the generic unknown-key rejection on the object block — no curated
// pointer — until this card added one, mirroring `sort`/`search`/
// `filter`/`editInline` above.
for (const k of ['group', 'hideFields', 'rowColor']) {
const msg = rejectOnObject({ userActions: { [k]: true } });
expect(msg).toContain('VIEW');
expect(msg).toContain(k);
}
});

it('`userActions.clone` points at the `enable` capability block, which really does declare it', () => {
const msg = rejectOnObject({ userActions: { clone: false } });
expect(msg).toContain('enable');
Expand Down
13 changes: 12 additions & 1 deletion packages/spec/src/data/object.zod.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -1736,7 +1736,9 @@ const ObjectSchemaBase = strictObject(
// disjoint vocabulary (sort/search/filter/refresh/rowHeight/group/
// addRecordForm/editInline/hideFields/rowColor/buttons — the last three
// adopted at #11195), so an author who learned that block writes these
// here and gets a shape that has never heard of them.
// here. `group`/`hideFields`/`rowColor` were refused by name but without
// a curated pointer until #11459 gave them one too, mirroring the other
// four.
sort:
'`sort` is a VIEW `userActions` key, not an object one — the two blocks share a ' +
'name and nothing else. The object block governs CRUD affordances ' +
Expand All@@ -1752,6 +1754,15 @@ const ObjectSchemaBase = strictObject(
'`editInline` is a VIEW `userActions` key. The object-level `edit` flag decides ' +
'whether editing is offered AT ALL; how it is offered (inline vs form) is the ' +
"view's call.",
group:
'`group` is a VIEW `userActions` key. This object block governs CRUD affordances ' +
'only — put toolbar controls on the view that renders the records.',
hideFields:
'`hideFields` is a VIEW `userActions` key. This object block governs CRUD ' +
'affordances only — put toolbar controls on the view that renders the records.',
rowColor:
'`rowColor` is a VIEW `userActions` key. This object block governs CRUD ' +
'affordances only — put toolbar controls on the view that renders the records.',
clone:
'`clone` is a CAPABILITY, not a user action — write `enable: { clone: false }`. ' +
'The `enable` block (ObjectCapabilities) is where record deep-cloning is governed.',
Expand Down
Loading