Skip to content

Commit 3739d8d

Browse files
feat(spec,lint): a kanban board chooses which lanes it draws, and in what order (kanban.lanes) (#28196)
domain:spec#2 · os-tesla · session_01L9qibx5r5nhDMwpRs4SL6D <!-- claude-projects-attribution: {"github_login":"os-tesla"} --> _Requested by **Tesla** · [project thread](https://claude.ai/code/project/chan_01AXsQkLFKRdQCqQ3RTr6Jao?thread=cmsg_01AXsQkLFKRdQCqQ3RTr6Jao7KgVSNdGtTtAQ3esq3Sog4)_ Fixes #28018 Clause-②: yes (widening) Metadata-protocol: added Skills-docs: follow-up #28212 (skills/objectstack-ui/rules/list-views.md, to land with the renderer half #28211) ## 维护者速读 - 改了什么:看板视图配置新增可选键 `kanban.lanes`(按顺序列出要画的泳道,取分组字段选项的存储值);`os validate` / `os build` / 运行时发布闸门会拒收不是该字段选项的泳道值和重复泳道。 - 为什么改:HotCRM 任务看板按状态分组、视图又过滤掉已完成任务,于是永远多一列空的「已完成」泳道,作者无法去掉它,也无法调整泳道顺序。 - 风险与回滚:纯新增可选键,不写默认值,已存的看板解析结果不变;新的两条 lint 规则只在写了 `lanes` 时触发。回滚即 revert 本 PR。控制台渲染器还没读这个键,在 ui 跟进卡落地前写了也仍是每个选项一列。 - 先看:`packages/lint/src/validate-list-view-field-refs.ts`(`checkKanbanLanes` / `checkKanbanLaneRepeats` 两段)、`packages/spec/src/ui/view.zod.ts`(`KanbanConfigSchema.lanes`)、`packages/lint/src/validate-list-view-kanban-lanes.test.ts`。 - 两分钟验证:`pnpm --filter @objectstack/lint exec vitest run src/validate-list-view-kanban-lanes.test.ts`,预期 11 个测试全部通过(其中一条把 `inprogress` 判为不是选项,并提示 `Did you mean "in_progress"?`)。 - 需要你做的:无,席位落地。 ## What changes **Spec (`@objectstack/spec`, minor).** `KanbanConfigSchema` (a list view's `kanban` block) gains one optional key, `lanes: string[]`: the lanes the board draws, in this order, as stored option values of `groupByField`. - A choice of lanes, not a record filter: a record whose value is not listed lands in the board's `Uncategorized` lane, as an off-lane record already does. To keep records off the board, filter the view (which is what the HotCRM task board already does). - No spec-side default, so every stored board parses unchanged. - Refused at parse: an empty list (`minItems`), and an entry not shaped like a stored option value (each entry is `SystemIdentifierSchema`, the grammar of `SelectOptionSchema.value`, so a label such as `In Progress` is refused). Both project into the published JSON Schema exactly, so the key adds no row to `dropped-refinements.baseline.json`. - `liveness/view.json`: the `kanban` row notes `lanes` at planned strength (the `viewMode`-on-gantt precedent): at this tree `ui/packages/plugin-kanban/src/ObjectKanban.tsx#effectiveColumns` still draws one lane per option and reads no lane list. **Lint (`@objectstack/lint`, minor).** Spec cannot see the object, so the object-aware half lives where `groupByField` is already judged against the object, `validate-list-view-field-refs.ts` (the reference-integrity suite `os validate`, `os build` and the runtime publish gate run): - `list-view-kanban-lane-unknown` (error): a lane that is not an inline option of the group field, at `kanban.lanes[i]`, with the nearest option as "Did you mean". A misspelled lane draws a lane no card can land in while every card with the option it meant falls into `Uncategorized`. - `list-view-kanban-lane-repeated` (error): a value listed twice, at the second entry. Needs no field map, so it runs before every skip. - Both ids exported from the package barrel and explained in `os explain`. **Alternative not taken: a `hideEmptyLanes: boolean`.** It hides a lane whenever its data happens to be empty, so lanes appear and disappear as records move and an empty lane stops being a drop target; and it cannot order lanes. The ordered list is stable, says which lanes and in what order, and closes the measured case by itself. ## Tests - `packages/spec/src/ui/kanban-config-lanes.test.ts`: member on the bare block and inside a list view (with an unknown-key control), order kept, absence writes nothing, empty list refused (`too_small`), label refused at its own index (`invalid_format`). - `packages/lint/src/validate-list-view-kanban-lanes.test.ts`: the HotCRM board shape is clean; a non-option lane is one error at its path with the nearest option; a label is a non-option; a repeat is one error at the second entry, with and without an object universe; picklist-bound and boolean group fields are not judged; an unknown `groupByField` is reported once at that key and its lanes are not judged; `validate` and `build` fail; the runtime save door (reference-integrity suite) reports both ids; both `os explain` entries exist and every verdict and fix is one line of at most 200 characters. ## Acceptance notes - **Duplicate check lives in lint, not in the schema.** A `superRefine` uniqueness check on `lanes` would add a new dropped site to 16 entries of the shrink-only `dropped-refinements.baseline.json` (measured: the spec build refused it), and growing that ledger is a decision, not a side effect. Keeping the duplicate verdict beside the membership verdict leaves the key fully projectable. - **Not judged by the membership rule:** a group field whose options come from a shared `picklist` (its option set is the list plus every `picklistExtensions` entry, which a stack snapshot need not carry whole), and a group field with no inline options (boolean, lookup: their lanes are values). Both are stated in the module docblock and the `os explain` entry. - **`packages/lint/src/index.ts`** gained the two id exports: `rule-explanations.test.ts` requires every explained id to be a barrel-exported constant. - **UI half:** the console's lane builder reading `lanes` is the follow-up card #28211. No `ui/**` edits here. ## Verification All readings at head `ea4b11b5` (branch merged with `origin/main` `412908cf`), objectstack-ai/objectstack. <details><summary>Builds, package tests and typechecks</summary> - `env -u OS_SKIP_DTS pnpm --filter @objectstack/spec build` then `check:generated`: exit 0, all artifacts current (reference docs regenerated in this PR; authorable surface `ui/KanbanConfig:lanes` added). - Workspace build `turbo run build` over every non-`ui`, non-docs package: 77/77 tasks. - `pnpm --filter @objectstack/lint test`: 179 files, 7650 passed, 5 skipped. - `pnpm --filter @objectstack/spec exec vitest run src/ui src/system/metadata-form-zod-reconciliation.test.ts src/type-alias-convention.pin.test.ts`: 167 files, 5950 passed. - `pnpm --filter @objectstack/lint typecheck` and `pnpm --filter @objectstack/spec typecheck` (tsc plus test-typecheck legs): exit 0. - New files on the final head: lint `validate-list-view-kanban-lanes.test.ts` 11/11, spec `kanban-config-lanes.test.ts` 5/5. </details> <details><summary>Ablation (lint rule, both verdicts)</summary> Through `scripts/ablation-replace.mjs` (anchor hit x1, restored to the HEAD blob `34aa7c35`, `git diff HEAD` empty after each leg): - membership check short-circuited to `return;`: `validate-list-view-kanban-lanes.test.ts` 3 failed / 8 passed. - repeat check made to never fire: 3 failed / 8 passed. </details> <details><summary>Derived gates (dispatch-gates --commands, 104 families)</summary> `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 104 commands for the 12 changed paths; every one ran with stdin closed and exited 0. Reconciliation: `dispatch-gates --ran`: 104 derived, 104 run, 0 NOT-MEASURED, 0 UNRUN. Local-only `check-dev-prereqs.mjs`: exit 1, the `ui/` packages are unbuilt here (excluded from the local build; this diff touches no `ui/**`). The full farm is CI's. </details> --- _Generated by [Claude Code](https://claude.ai/code/session_01L9qibxL3MYcTjfshb8eeK3)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 7811c3f commit 3739d8d

12 files changed

Lines changed: 457 additions & 11 deletions

File tree

‎.changeset/28018-kanban-lanes.md‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
'@objectstack/spec': minor
3+
'@objectstack/lint': minor
4+
---
5+
6+
feat(spec): a kanban board can choose which lanes it draws, and in what order, `kanban.lanes`
7+
8+
Clause-②: yes (widening)
9+
Metadata-protocol: added
10+
11+
A board grouped on a select field drew one lane per option, always, so a lane the view's own filter keeps empty (a task board that filters out completed tasks still drawing its Completed lane) could not be left off, and the lanes could not be put in any order but the options' own. `KanbanConfigSchema` (the list view's `kanban` block) gains one optional key:
12+
13+
- **`lanes: string[]`.** The lanes the board draws, in this order, as stored option values of the `groupByField` field (the option `value`, not its label). For example `lanes: ['not_started', 'in_progress', 'waiting']` on a task board grouped by `status`.
14+
- **A choice of lanes, not a record filter.** A record whose value is not listed lands in the board's `Uncategorized` lane, as a record whose value matches no lane already does. To keep records off the board, filter the view.
15+
- **Absent means one lane per option.** The key has no spec-side default, so a board stored before it existed parses to exactly the block it stored and draws the lanes it always did.
16+
- **Refused at parse:** an empty list (omit the key instead), and an entry that is not shaped like a stored option value (a display label such as `'In Progress'`).
17+
- **Refused against the object** (`@objectstack/lint`, so `os validate`, `os build` and the runtime publish gate): a lane that is not an option of the group field (`list-view-kanban-lane-unknown`, which names the nearest option), and a value listed twice (`list-view-kanban-lane-repeated`, at the second entry). A misspelled lane would otherwise draw a lane no card can land in while every card with the option it meant falls into `Uncategorized`. Judged against the group field's inline `options`; a field whose options come from a shared `picklist`, and a group field with no options (a boolean, a lookup), are not judged. `os explain list-view-kanban-lane-unknown` (and `-repeated`) carries the reasoning.
18+
19+
The Console renderer reads the key in a follow-up change; until then a board that declares it still draws one lane per option.

‎content/docs/references/api/protocol.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,7 +1864,7 @@ The published metadata item body, opaque by ruling (1C). Shape is the item's own
18641864
| **selection** | `{ type?: Enum<'none' \| 'single' \| 'multiple'> }` | optional | Row selection configuration |
18651865
| **navigation** | `{ mode?: Enum<'drawer' \| 'page' \| 'new_window' \| 'none'>; preventNavigation?: boolean; openNewTab?: boolean; size?: Enum<'auto' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'>; … }` | optional | Configuration for item click navigation (drawer by default, page, new_window or none) |
18661866
| **pagination** | `{ pageSize?: integer; pageSizeOptions?: integer[] }` | optional | Pagination configuration |
1867-
| **kanban** | `{ groupByField: string; summarizeField?: string; titleField?: string; columns: string[] }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
1867+
| **kanban** | `{ groupByField: string; lanes?: string[]; summarizeField?: string; titleField?: string; … }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
18681868
| **calendar** | `{ startDateField: string; endDateField?: string; titleField?: string; colorField?: string; … }` | optional | Calendar configuration — applies when the view renders as a calendar layout |
18691869
| **gantt** | `{ startDateField: string; endDateField: string; titleField: string; progressField?: string; … }` | optional | Gantt-timeline configuration — applies when the view renders as a gantt layout |
18701870
| **gallery** | `{ coverField?: string; coverFit?: Enum<'cover' \| 'contain'>; cardSize?: Enum<'small' \| 'medium' \| 'large'>; titleField?: string; … }` | optional | Gallery/card view configuration |
@@ -1943,7 +1943,7 @@ The published metadata item body, opaque by ruling (1C). Shape is the item's own
19431943
| **selection** | `{ type?: Enum<'none' \| 'single' \| 'multiple'> }` | optional | Row selection configuration |
19441944
| **navigation** | `{ mode?: Enum<'drawer' \| 'page' \| 'new_window' \| 'none'>; preventNavigation?: boolean; openNewTab?: boolean; size?: Enum<'auto' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'>; … }` | optional | Configuration for item click navigation (drawer by default, page, new_window or none) |
19451945
| **pagination** | `{ pageSize?: integer; pageSizeOptions?: integer[] }` | optional | Pagination configuration |
1946-
| **kanban** | `{ groupByField: string; summarizeField?: string; titleField?: string; columns: string[] }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
1946+
| **kanban** | `{ groupByField: string; lanes?: string[]; summarizeField?: string; titleField?: string; … }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
19471947
| **calendar** | `{ startDateField: string; endDateField?: string; titleField?: string; colorField?: string; … }` | optional | Calendar configuration — applies when the view renders as a calendar layout |
19481948
| **gantt** | `{ startDateField: string; endDateField: string; titleField: string; progressField?: string; … }` | optional | Gantt-timeline configuration — applies when the view renders as a gantt layout |
19491949
| **gallery** | `{ coverField?: string; coverFit?: Enum<'cover' \| 'contain'>; cardSize?: Enum<'small' \| 'medium' \| 'large'>; titleField?: string; … }` | optional | Gallery/card view configuration |

‎content/docs/references/data/object.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ const result = ApiMethod.parse(data);
382382
| **selection** | `{ type?: Enum<'none' \| 'single' \| 'multiple'> }` | optional | Row selection configuration |
383383
| **navigation** | `{ mode?: Enum<'drawer' \| 'page' \| 'new_window' \| 'none'>; preventNavigation?: boolean; openNewTab?: boolean; size?: Enum<'auto' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'>; … }` | optional | Configuration for item click navigation (drawer by default, page, new_window or none) |
384384
| **pagination** | `{ pageSize?: integer; pageSizeOptions?: integer[] }` | optional | Pagination configuration |
385-
| **kanban** | `{ groupByField: string; summarizeField?: string; titleField?: string; columns: string[] }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
385+
| **kanban** | `{ groupByField: string; lanes?: string[]; summarizeField?: string; titleField?: string; … }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
386386
| **calendar** | `{ startDateField: string; endDateField?: string; titleField?: string; colorField?: string; … }` | optional | Calendar configuration — applies when the view renders as a calendar layout |
387387
| **gantt** | `{ startDateField: string; endDateField: string; titleField: string; progressField?: string; … }` | optional | Gantt-timeline configuration — applies when the view renders as a gantt layout |
388388
| **gallery** | `{ coverField?: string; coverFit?: Enum<'cover' \| 'contain'>; cardSize?: Enum<'small' \| 'medium' \| 'large'>; titleField?: string; … }` | optional | Gallery/card view configuration |

‎content/docs/references/ui/view.mdx‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,7 @@ HTTP methods a view data source may request — the subset of `HttpMethod` witho
676676
| Property | Type | Required | Description |
677677
| :--- | :--- | :--- | :--- |
678678
| **groupByField** | `string` | ✅ | Field to group columns by (usually status/select). NO leading or trailing whitespace: the board reads this name off every card verbatim, so a padded spelling collapses the whole board into one `Uncategorized` lane. |
679+
| **lanes** | `string[]` | optional | The lanes the board draws, in this order: stored option values of the groupByField field (the option `value`, not its label). Omit to draw one lane per option in the options' own order. A record whose value is not listed is not hidden: it lands in the `Uncategorized` lane, as a record whose value matches no lane does. To keep records off the board, filter the view. List each value once. |
679680
| **summarizeField** | `string` | optional | Field to sum at top of column (e.g. amount) |
680681
| **titleField** | `string` | optional | Field displayed as the card title. Omit to fall back to the record display name (ADR-0079 resolver chain) |
681682
| **columns** | `string[]` | ✅ | Fields to show on cards |
@@ -780,7 +781,7 @@ Map view configuration
780781
| **selection** | `{ type?: Enum<'none' \| 'single' \| 'multiple'> }` | optional | Row selection configuration |
781782
| **navigation** | `{ mode?: Enum<'drawer' \| 'page' \| 'new_window' \| 'none'>; preventNavigation?: boolean; openNewTab?: boolean; size?: Enum<'auto' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'>; … }` | optional | Configuration for item click navigation (drawer by default, page, new_window or none) |
782783
| **pagination** | `{ pageSize?: integer; pageSizeOptions?: integer[] }` | optional | Pagination configuration |
783-
| **kanban** | `{ groupByField: string; summarizeField?: string; titleField?: string; columns: string[] }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
784+
| **kanban** | `{ groupByField: string; lanes?: string[]; summarizeField?: string; titleField?: string; … }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
784785
| **calendar** | `{ startDateField: string; endDateField?: string; titleField?: string; colorField?: string; … }` | optional | Calendar configuration — applies when the view renders as a calendar layout |
785786
| **gantt** | `{ startDateField: string; endDateField: string; titleField: string; progressField?: string; … }` | optional | Gantt-timeline configuration — applies when the view renders as a gantt layout |
786787
| **gallery** | `{ coverField?: string; coverFit?: Enum<'cover' \| 'contain'>; cardSize?: Enum<'small' \| 'medium' \| 'large'>; titleField?: string; … }` | optional | Gallery/card view configuration |
@@ -902,6 +903,7 @@ View filter rule
902903
| Property | Type | Required | Description |
903904
| :--- | :--- | :--- | :--- |
904905
| **groupByField** | `string` | ✅ | Field to group columns by (usually status/select). NO leading or trailing whitespace: the board reads this name off every card verbatim, so a padded spelling collapses the whole board into one `Uncategorized` lane. |
906+
| **lanes** | `string[]` | optional | The lanes the board draws, in this order: stored option values of the groupByField field (the option `value`, not its label). Omit to draw one lane per option in the options' own order. A record whose value is not listed is not hidden: it lands in the `Uncategorized` lane, as a record whose value matches no lane does. To keep records off the board, filter the view. List each value once. |
905907
| **summarizeField** | `string` | optional | Field to sum at top of column (e.g. amount) |
906908
| **titleField** | `string` | optional | Field displayed as the card title. Omit to fall back to the record display name (ADR-0079 resolver chain) |
907909
| **columns** | `string[]` | ✅ | Fields to show on cards |
@@ -1158,7 +1160,7 @@ View filter rule
11581160
| **selection** | `{ type?: Enum<'none' \| 'single' \| 'multiple'> }` | optional | Row selection configuration |
11591161
| **navigation** | `{ mode?: Enum<'drawer' \| 'page' \| 'new_window' \| 'none'>; preventNavigation?: boolean; openNewTab?: boolean; size?: Enum<'auto' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'>; … }` | optional | Configuration for item click navigation (drawer by default, page, new_window or none) |
11601162
| **pagination** | `{ pageSize?: integer; pageSizeOptions?: integer[] }` | optional | Pagination configuration |
1161-
| **kanban** | `{ groupByField: string; summarizeField?: string; titleField?: string; columns: string[] }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
1163+
| **kanban** | `{ groupByField: string; lanes?: string[]; summarizeField?: string; titleField?: string; … }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
11621164
| **calendar** | `{ startDateField: string; endDateField?: string; titleField?: string; colorField?: string; … }` | optional | Calendar configuration — applies when the view renders as a calendar layout |
11631165
| **gantt** | `{ startDateField: string; endDateField: string; titleField: string; progressField?: string; … }` | optional | Gantt-timeline configuration — applies when the view renders as a gantt layout |
11641166
| **gallery** | `{ coverField?: string; coverFit?: Enum<'cover' \| 'contain'>; cardSize?: Enum<'small' \| 'medium' \| 'large'>; titleField?: string; … }` | optional | Gallery/card view configuration |
@@ -1271,6 +1273,7 @@ View filter rule
12711273
| Property | Type | Required | Description |
12721274
| :--- | :--- | :--- | :--- |
12731275
| **groupByField** | `string` | ✅ | Field to group columns by (usually status/select). NO leading or trailing whitespace: the board reads this name off every card verbatim, so a padded spelling collapses the whole board into one `Uncategorized` lane. |
1276+
| **lanes** | `string[]` | optional | The lanes the board draws, in this order: stored option values of the groupByField field (the option `value`, not its label). Omit to draw one lane per option in the options' own order. A record whose value is not listed is not hidden: it lands in the `Uncategorized` lane, as a record whose value matches no lane does. To keep records off the board, filter the view. List each value once. |
12741277
| **summarizeField** | `string` | optional | Field to sum at top of column (e.g. amount) |
12751278
| **titleField** | `string` | optional | Field displayed as the card title. Omit to fall back to the record display name (ADR-0079 resolver chain) |
12761279
| **columns** | `string[]` | ✅ | Fields to show on cards |
@@ -1730,7 +1733,7 @@ Tab configuration for multi-tab view interface
17301733
| **selection** | `{ type?: Enum<'none' \| 'single' \| 'multiple'> }` | optional | Row selection configuration |
17311734
| **navigation** | `{ mode?: Enum<'drawer' \| 'page' \| 'new_window' \| 'none'>; preventNavigation?: boolean; openNewTab?: boolean; size?: Enum<'auto' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'>; … }` | optional | Configuration for item click navigation (drawer by default, page, new_window or none) |
17321735
| **pagination** | `{ pageSize?: integer; pageSizeOptions?: integer[] }` | optional | Pagination configuration |
1733-
| **kanban** | `{ groupByField: string; summarizeField?: string; titleField?: string; columns: string[] }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
1736+
| **kanban** | `{ groupByField: string; lanes?: string[]; summarizeField?: string; titleField?: string; … }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
17341737
| **calendar** | `{ startDateField: string; endDateField?: string; titleField?: string; colorField?: string; … }` | optional | Calendar configuration — applies when the view renders as a calendar layout |
17351738
| **gantt** | `{ startDateField: string; endDateField: string; titleField: string; progressField?: string; … }` | optional | Gantt-timeline configuration — applies when the view renders as a gantt layout |
17361739
| **gallery** | `{ coverField?: string; coverFit?: Enum<'cover' \| 'contain'>; cardSize?: Enum<'small' \| 'medium' \| 'large'>; titleField?: string; … }` | optional | Gallery/card view configuration |
@@ -1809,7 +1812,7 @@ Tab configuration for multi-tab view interface
18091812
| **selection** | `{ type?: Enum<'none' \| 'single' \| 'multiple'> }` | optional | Row selection configuration |
18101813
| **navigation** | `{ mode?: Enum<'drawer' \| 'page' \| 'new_window' \| 'none'>; preventNavigation?: boolean; openNewTab?: boolean; size?: Enum<'auto' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'>; … }` | optional | Configuration for item click navigation (drawer by default, page, new_window or none) |
18111814
| **pagination** | `{ pageSize?: integer; pageSizeOptions?: integer[] }` | optional | Pagination configuration |
1812-
| **kanban** | `{ groupByField: string; summarizeField?: string; titleField?: string; columns: string[] }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
1815+
| **kanban** | `{ groupByField: string; lanes?: string[]; summarizeField?: string; titleField?: string; … }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
18131816
| **calendar** | `{ startDateField: string; endDateField?: string; titleField?: string; colorField?: string; … }` | optional | Calendar configuration — applies when the view renders as a calendar layout |
18141817
| **gantt** | `{ startDateField: string; endDateField: string; titleField: string; progressField?: string; … }` | optional | Gantt-timeline configuration — applies when the view renders as a gantt layout |
18151818
| **gallery** | `{ coverField?: string; coverFit?: Enum<'cover' \| 'contain'>; cardSize?: Enum<'small' \| 'medium' \| 'large'>; titleField?: string; … }` | optional | Gallery/card view configuration |
@@ -2012,7 +2015,7 @@ This schema accepts one of the following structures:
20122015
| **selection** | `{ type?: Enum<'none' \| 'single' \| 'multiple'> }` | optional | Row selection configuration |
20132016
| **navigation** | `{ mode?: Enum<'drawer' \| 'page' \| 'new_window' \| 'none'>; preventNavigation?: boolean; openNewTab?: boolean; size?: Enum<'auto' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'>; … }` | optional | Configuration for item click navigation (drawer by default, page, new_window or none) |
20142017
| **pagination** | `{ pageSize?: integer; pageSizeOptions?: integer[] }` | optional | Pagination configuration |
2015-
| **kanban** | `{ groupByField: string; summarizeField?: string; titleField?: string; columns: string[] }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
2018+
| **kanban** | `{ groupByField: string; lanes?: string[]; summarizeField?: string; titleField?: string; … }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
20162019
| **calendar** | `{ startDateField: string; endDateField?: string; titleField?: string; colorField?: string; … }` | optional | Calendar configuration — applies when the view renders as a calendar layout |
20172020
| **gantt** | `{ startDateField: string; endDateField: string; titleField: string; progressField?: string; … }` | optional | Gantt-timeline configuration — applies when the view renders as a gantt layout |
20182021
| **gallery** | `{ coverField?: string; coverFit?: Enum<'cover' \| 'contain'>; cardSize?: Enum<'small' \| 'medium' \| 'large'>; titleField?: string; … }` | optional | Gallery/card view configuration |
@@ -2184,7 +2187,7 @@ This schema accepts one of the following structures:
21842187
| **selection** | `{ type?: Enum<'none' \| 'single' \| 'multiple'> }` | optional | Row selection configuration |
21852188
| **navigation** | `{ mode?: Enum<'drawer' \| 'page' \| 'new_window' \| 'none'>; preventNavigation?: boolean; openNewTab?: boolean; size?: Enum<'auto' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'>; … }` | optional | Configuration for item click navigation (drawer by default, page, new_window or none) |
21862189
| **pagination** | `{ pageSize?: integer; pageSizeOptions?: integer[] }` | optional | Pagination configuration |
2187-
| **kanban** | `{ groupByField: string; summarizeField?: string; titleField?: string; columns: string[] }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
2190+
| **kanban** | `{ groupByField: string; lanes?: string[]; summarizeField?: string; titleField?: string; … }` | optional | Kanban-board configuration — applies when the view renders as a kanban layout |
21882191
| **calendar** | `{ startDateField: string; endDateField?: string; titleField?: string; colorField?: string; … }` | optional | Calendar configuration — applies when the view renders as a calendar layout |
21892192
| **gantt** | `{ startDateField: string; endDateField: string; titleField: string; progressField?: string; … }` | optional | Gantt-timeline configuration — applies when the view renders as a gantt layout |
21902193
| **gallery** | `{ coverField?: string; coverFit?: Enum<'cover' \| 'contain'>; cardSize?: Enum<'small' \| 'medium' \| 'large'>; titleField?: string; … }` | optional | Gallery/card view configuration |

0 commit comments

Comments
 (0)