Skip to content

Commit 875b089

Browse files
os-zhuangclaude
andauthored
feat(spec): add userActions.refresh toggle to ListView (objectui#2634) (#3158)
* feat(spec): add userActions.refresh toggle to ListView (objectui#2634) The ListView UserActionsConfig exposed toolbar toggles for sort / search / filter / rowHeight but had no toggle for a manual data-refresh action, so consumers had no spec-canonical way to reload a list without a full page reload (objectui#2634). Add `refresh: boolean` (default true) alongside the existing toggles. objectui's ListView reads `userActions.refresh` to gate its toolbar Refresh button; the liveness note for `userActions` is updated to record the new live sub-key. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C7Z2cbcb14wb99upTD6LNw * docs(spec): regenerate ui reference docs for userActions.refresh `content/docs/references/ui/{view,page}.mdx` are generated from the spec (gen:schema + gen:docs). Adding `userActions.refresh` made them drift; this regenerates them so `check:docs` passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C7Z2cbcb14wb99upTD6LNw --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 493544b commit 875b089

5 files changed

Lines changed: 9 additions & 4 deletions

File tree

content/docs/references/ui/page.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Interface-level page configuration (Airtable parity)
5656
| **sourceView** | `string` | optional | @deprecated Legacy named-view inheritance. Define columns/sort/filterBy on the page instead. |
5757
| **appearance** | `{ showDescription: boolean; allowedVisualizations?: Enum<'grid' \| 'kanban' \| 'gallery' \| 'calendar' \| 'timeline' \| 'gantt' \| 'map' \| 'chart' \| 'tree'>[] }` | optional | Appearance and visualization configuration |
5858
| **userFilters** | `{ element: Enum<'dropdown' \| 'tabs' \| 'toggle'>; fields?: { field: string; label?: string; type?: Enum<'select' \| 'multi-select' \| 'boolean' \| 'date-range' \| 'text'>; options?: { value: string \| number \| boolean; label: string; color?: string }[]; … }[]; tabs?: { name: string; label?: string; icon?: string; view?: string; … }[]; showAllRecords?: boolean }` | optional | End-user quick-filter bar for this page (overrides the source view's userFilters) |
59-
| **userActions** | `{ sort: boolean; search: boolean; filter: boolean; rowHeight: boolean; … }` | optional | User action toggles |
59+
| **userActions** | `{ sort: boolean; search: boolean; filter: boolean; refresh: boolean; … }` | optional | User action toggles |
6060
| **addRecord** | `{ enabled: boolean; position: Enum<'top' \| 'bottom' \| 'both'>; mode: Enum<'inline' \| 'form' \| 'modal'>; formView?: string }` | optional | Add record entry point configuration |
6161
| **buttons** | `string[]` | optional | Toolbar buttons — names of the source object's actions to surface in the page toolbar |
6262
| **recordAction** | `Enum<'drawer' \| 'page' \| 'modal' \| 'none'>` | optional | How clicking a record opens its detail (drawer \| page \| modal \| none). Default: drawer |

content/docs/references/ui/view.mdx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ List chart view configuration
374374
| **conditionalFormatting** | `{ condition: string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }; style: Record<string, string> }[]` | optional | Conditional formatting rules for list rows |
375375
| **inlineEdit** | `boolean` | optional | Allow inline editing of records directly in the list view |
376376
| **exportOptions** | `Enum<'csv' \| 'xlsx' \| 'pdf' \| 'json'>[]` | optional | Available export format options |
377-
| **userActions** | `{ sort?: boolean; search?: boolean; filter?: boolean; rowHeight?: boolean; … }` | optional | User action toggles for the view toolbar |
377+
| **userActions** | `{ sort?: boolean; search?: boolean; filter?: boolean; refresh?: boolean; … }` | optional | User action toggles for the view toolbar |
378378
| **appearance** | `{ showDescription?: boolean; allowedVisualizations?: Enum<'grid' \| 'kanban' \| 'gallery' \| 'calendar' \| 'timeline' \| 'gantt' \| 'map' \| 'chart' \| 'tree'>[] }` | optional | Appearance and visualization configuration |
379379
| **tabs** | `{ name: string; label?: string; icon?: string; view?: string; … }[]` | optional | Tab definitions for multi-tab view interface |
380380
| **addRecord** | `{ enabled?: boolean; position?: Enum<'top' \| 'bottom' \| 'both'>; mode?: Enum<'inline' \| 'form' \| 'modal'>; formView?: string }` | optional | Add record entry point configuration |
@@ -462,7 +462,7 @@ List chart view configuration
462462
| **conditionalFormatting** | `{ condition: string \| { dialect: Enum<'cel' \| 'js' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }; style: Record<string, string> }[]` | optional | Conditional formatting rules for list rows |
463463
| **inlineEdit** | `boolean` | optional | Allow inline editing of records directly in the list view |
464464
| **exportOptions** | `Enum<'csv' \| 'xlsx' \| 'pdf' \| 'json'>[]` | optional | Available export format options |
465-
| **userActions** | `{ sort?: boolean; search?: boolean; filter?: boolean; rowHeight?: boolean; … }` | optional | User action toggles for the view toolbar |
465+
| **userActions** | `{ sort?: boolean; search?: boolean; filter?: boolean; refresh?: boolean; … }` | optional | User action toggles for the view toolbar |
466466
| **appearance** | `{ showDescription?: boolean; allowedVisualizations?: Enum<'grid' \| 'kanban' \| 'gallery' \| 'calendar' \| 'timeline' \| 'gantt' \| 'map' \| 'chart' \| 'tree'>[] }` | optional | Appearance and visualization configuration |
467467
| **tabs** | `{ name: string; label?: string; icon?: string; view?: string; … }[]` | optional | Tab definitions for multi-tab view interface |
468468
| **addRecord** | `{ enabled?: boolean; position?: Enum<'top' \| 'bottom' \| 'both'>; mode?: Enum<'inline' \| 'form' \| 'modal'>; formView?: string }` | optional | Add record entry point configuration |
@@ -584,6 +584,7 @@ User action toggles for the view toolbar
584584
| **sort** | `boolean` || Allow users to sort records |
585585
| **search** | `boolean` || Allow users to search records |
586586
| **filter** | `boolean` || Allow users to filter records |
587+
| **refresh** | `boolean` || Allow users to reload the view data from the backend without a full page reload |
587588
| **rowHeight** | `boolean` || Allow users to toggle row height/density |
588589
| **addRecordForm** | `boolean` || Add records through a form instead of inline |
589590
| **editInline** | `boolean` || Allow users to edit records inline — click a cell to edit it with the field's type-aware widget (the same control the form uses). Off by default: the list is read-only unless the author opts in. |

packages/spec/liveness/view.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"conditionalFormatting": { "status": "live", "note": "objectui: ObjectGrid.tsx (audit L15)." },
4242
"inlineEdit": { "status": "live", "note": "objectui: ObjectGrid.tsx (audit L15)." },
4343
"exportOptions": { "status": "live", "note": "objectui: ObjectGrid.tsx (audit L15)." },
44-
"userActions": { "status": "live", "note": "objectui: ListView.tsx:374 toolbarFlags (search/sort/filters/density/hide-fields/group/color + addRecordForm). Sub-key userActions.buttons has NO reader (audit L20, re-verified objectui@fb35e48) — dead sub-surface, enforce-or-remove worklist." },
44+
"userActions": { "status": "live", "note": "objectui: ListView.tsx:374 toolbarFlags (search/sort/filters/refresh/density/hide-fields/group/color + addRecordForm). Sub-key userActions.refresh drives the manual toolbar Refresh button (objectui#2634). Sub-key userActions.buttons has NO reader (audit L20, re-verified objectui@fb35e48) — dead sub-surface, enforce-or-remove worklist." },
4545
"appearance": { "status": "live", "note": "objectui: allowedVisualizations gates the view-type switcher (audit L15); showDescription gates ListView.tsx:1728." },
4646
"tabs": { "status": "live", "note": "objectui: TabBar.tsx — icon/visible/pinned/filter wired (audit L15). Sub-key tabs[].order is NOT used for sorting (audit L20) — dead sub-surface." },
4747
"addRecord": { "status": "live", "note": "objectui: ListView.tsx:374 (addRecord + userActions.addRecordForm drive the add-record flow). Sub-keys addRecord.mode / addRecord.formView have NO reader (audit L20, re-verified objectui@fb35e48) — dead sub-surface." },

packages/spec/src/ui/view.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2126,6 +2126,7 @@ describe('UserActionsConfigSchema', () => {
21262126
expect(config.sort).toBe(true);
21272127
expect(config.search).toBe(true);
21282128
expect(config.filter).toBe(true);
2129+
expect(config.refresh).toBe(true);
21292130
expect(config.rowHeight).toBe(true);
21302131
expect(config.addRecordForm).toBe(false);
21312132
expect(config.editInline).toBe(false);
@@ -2335,11 +2336,13 @@ describe('ListViewSchema — Airtable Interface parity fields', () => {
23352336
sort: true,
23362337
search: true,
23372338
filter: false,
2339+
refresh: false,
23382340
rowHeight: false,
23392341
},
23402342
});
23412343
expect(listView.userActions?.sort).toBe(true);
23422344
expect(listView.userActions?.filter).toBe(false);
2345+
expect(listView.userActions?.refresh).toBe(false);
23432346
});
23442347

23452348
it('should accept list view with appearance', () => {

packages/spec/src/ui/view.zod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ export const UserActionsConfigSchema = lazySchema(() => z.object({
240240
sort: z.boolean().default(true).describe('Allow users to sort records'),
241241
search: z.boolean().default(true).describe('Allow users to search records'),
242242
filter: z.boolean().default(true).describe('Allow users to filter records'),
243+
refresh: z.boolean().default(true).describe('Allow users to reload the view data from the backend without a full page reload'),
243244
rowHeight: z.boolean().default(true).describe('Allow users to toggle row height/density'),
244245
addRecordForm: z.boolean().default(false).describe('Add records through a form instead of inline'),
245246
editInline: z.boolean().default(false).describe('Allow users to edit records inline — click a cell to edit it with the field\'s type-aware widget (the same control the form uses). Off by default: the list is read-only unless the author opts in.'),

0 commit comments

Comments
 (0)