Skip to content

Commit bbb49c9

Browse files
docs(plugin-gantt): the object-gantt registration no longer teaches the retired view-level api source (#27421)
<!-- claude-projects-attribution: {"github_login":"os-support-ai"} --> _Requested by **Yibo Wang** · [project thread](https://claude.ai/code/project/chan_01BVUyyPie8gHwoPM18iABwB?thread=cmsg_01BVUyyPie8gHwoPM18iABwBXWXZBxsvNwj3i1LQo3mDae)_ Part of #27130 Clause-②: no Metadata-protocol: none **What stays open on #27130, and whose it is.** After this PR nothing on the card is the spec lane's. The card stays open for the customer reply, which is the triage seat's (ruling 6471507187, step 3). The engine floor for plugin drivers (#27277) and the sharing-model refusal (#27332) are in flight on their own cards; neither edits a file this PR edits (measured: open PRs #27403 and #27391 touch no `plugin-gantt`, `sdui.manifest.json` or `content/docs/ui/components/` path). ## 维护者速读 - 改了什么:只改说明文字。甘特图 `object-gantt` 注册的 `data` 和 `filter` 两个输入说明,不再把已退役的视图级 `api` 数据源写成可用的记录来源;SDUI 清单和组件参考文档随之重新生成。 - 为什么改:客户照着这段官方文字写了 `data: { provider: 'api', read }`,但 spec 早已按名拒收这个 provider,渲染器也没有对应分支,图表是空的、不发任何请求。 - 风险与回滚:零运行时风险,没有输入项、schema、渲染行为或导出变化;回滚即还原文字。 - 先看:`ui/packages/plugin-gantt/src/index.tsx`(`data`、`filter` 两行说明),`ui/packages/plugin-gantt/src/__tests__/apiSourceNotTaught-27130.test.ts`,`sdui.manifest.json`(两行 description)。 - 两分钟验证:`cd ui && pnpm exec vitest run packages/plugin-gantt/src/__tests__/apiSourceNotTaught-27130.test.ts`,应见 3 个测试全绿。 - 需要你做的:无,席位落地。 ## What changes Text only. No registration input, schema, renderer behaviour or export moves: the regenerated `sdui.manifest.json` differs from `origin/main` in exactly the two `description` strings (plus its record file's date and sha256), and `content/docs/ui/components/plugins.mdx` in the same two table rows. **Measured on `origin/main` `cf218eed`.** `resolveDataSource` (`ui/packages/core/src/adapters/resolveDataSource.ts`) has an `object` arm and a `value` arm only; any other provider returns the context adapter. `ObjectGantt` takes rung 1 of `resolveRecordSourceConfig(schema, 'view-data')` verbatim, so an `api` block wins the ladder, then queries `schema.objectName` through the host adapter (`resolveRecordSourceObjectName` reads `data.object` only for the `object` provider). A one-off probe through the real `SchemaRenderer` with the customer's shape, `data: { provider: 'api', read: { url: '/api/gantt/tree' }, write: { url: '/api/gantt/task', method: 'PATCH' } }` and no `objectName`: - `ObjectGanttSchema.safeParse` fails at `data.provider` (`invalid_union`) with the spec's retirement message, "`view.data.provider: 'api'` was removed in @objectstack/spec 18 …"; - the host adapter's `find` is called once with resource `""`; `fetch` is never called, so neither URL is requested; - the chart draws no task. With an `objectName` beside it, `objectName` is queried instead; that row was already pinned ("a retired api block requests nothing and is answered like an unknown provider", `recordSourceInputs-10394.test.tsx`). Before (`data`): > A `{ provider, … }` data-source configuration, read FIRST on the record-source ladder: a gantt carrying one never reaches `staticData` and never queries `objectName`. `{ provider: 'value', items }` charts those rows, `{ provider: 'object', object }` queries that object and `{ provider: 'api', read }` reads through that request. A bare array is not this key’s shape and is not a record source: the gantt falls through to `staticData`, then `objectName`, so inline rows belong under `staticData`. After: > A `{ provider, … }` data-source configuration, read FIRST on the record-source ladder: a gantt carrying one never reaches `staticData`. The gantt reads two providers: `{ provider: 'value', items }` charts those rows and never queries `objectName`, and `{ provider: 'object', object }` queries that object in place of `objectName`. Rows a server computes reach the gantt as an object whose plugin driver computes them, never as a request URL in the view. A bare array is not this key’s shape and is not a record source: the gantt falls through to `staticData`, then `objectName`, so inline rows belong under `staticData`. "never queries `objectName`" moved from every provider to the `value` provider, where it holds: on any provider the gantt does not read, `objectName` is what it queries (above). Before (`filter`): > … narrowing the tasks the gantt charts — from every record source it reads: the object, an `api` request, or inline rows. … After: > … narrowing the tasks the gantt charts — from every record source it reads: the object or inline rows. … **Sweep.** `git grep` over `ui/packages/*/src`, `ui/apps/*/src` and every `ui/packages/*/README.md` for `provider: 'api'` (any quoting), "`api` request" and "reads through that request": the two lines above were the only text teaching the view-level `api` source as a record source. The remaining hits are the live page-element binding `dataSource: { provider: 'api', read, path? }` (`productBlocks.tsx`, `product-blocks.zod.ts`, `useNavMemberGates.ts`, `NavigationRenderer.tsx`, `SchemaRenderer.tsx`, `useElementApiDataSource.ts`, `ConsoleElementApiOpen.tsx`, `i18n/src/locales/en.ts`, `react/README.md`, `preview-gallery.tsx`), left untouched, or text that already says the view-level arm is retired (`resolveDataSource.ts`, `ApiDataSource.ts`, `core/src/adapters/README.md`, `useViewData.ts`, `plugin-gantt/README.md`). No hit under `skills/**` or `docs/adr/**`. **Regenerated, not hand-edited:** `node scripts/gen-sdui-manifest-node.mjs` (in-tree registry: `sdui.manifest.json`, `scripts/sdui-manifest.record.json`), then `node scripts/gen-sdui-reference.mjs` (`content/docs/ui/components/plugins.mdx`). Changeset: `.changeset/27130-gantt-api-source-not-taught.md`, `@object-ui/plugin-gantt` patch. ## Tests - New `ui/packages/plugin-gantt/src/__tests__/apiSourceNotTaught-27130.test.ts` (3 tests): no `object-gantt` input description matches `provider: 'api'` in any quoting or a code-font `api`; positive control that `data` still names `{ provider: 'object', object }` and `{ provider: 'value', items }`; a matcher control on the three replaced strings. - Reverse verification, once: with `index.tsx` restored from `origin/main`, the pin goes red naming `[ 'data', 'filter' ]` (`Tests 1 failed | 2 passed`); restored from `HEAD`, `git diff HEAD` is empty and the HEAD blob and disk hashes match (`4d07512d`). - `@object-ui/plugin-gantt` under the verify lock: `test` (Test Files 103 passed, 1 skipped; Tests 775 passed, 114 skipped) and `type-check`, VERDICT command-exit 0. ## Acceptance notes - `plugin-gantt/README.md` already says the right thing ("The view-level `{ provider: 'api', read, write }` arm is retired in the spec … its `read` / `write` URLs are never requested") and is unchanged. - The `data` description does not cover the `{ provider: 'schema', schemaId }` arm the spec union also accepts; the README states it (the gantt queries `objectName` instead). Not widened here: the order asked for the two providers the gantt reads. ## Verification Derived gates on head `65fcb5de`: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derives 76; all 76 exit 0. `check:skill-examples` first exited 3 (prerequisite not met: no `@objectstack/client-react` dist) and was re-run green after `pnpm --filter @objectstack/client-react build`. `check:sdui-reference` and the ui scripts suite (`pnpm --dir ui exec vitest run scripts/`) are among the 76. `dispatch-gates --ran` reconciles: 76 derived, 76 run, 0 NOT-MEASURED, 0 UNRUN. <details><summary>76 gate commands and exit codes</summary> ```text node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0 node scripts/check-adr-0087-registration.mjs --self-test :: exit 0 node scripts/check-adr-links.mjs --self-test :: exit 0 node scripts/check-adr-links.mjs :: exit 0 node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0 node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 node scripts/check-closing-keyword-parity.mjs :: exit 0 node scripts/check-comment-mask-corpus.mjs :: exit 0 node scripts/check-doc-route-spelling.mjs --advisory :: exit 0 node scripts/check-doc-route-spelling.mjs --self-test :: exit 0 node scripts/check-docs-section-name.mjs --self-test :: exit 0 node scripts/check-docs-section-name.mjs :: exit 0 node scripts/check-empty-changeset.mjs --base origin/main :: exit 0 node scripts/check-empty-changeset.mjs --self-test :: exit 0 node scripts/check-sdui-manifest.mjs --self-test :: exit 0 node scripts/check-sdui-manifest.mjs :: exit 0 node scripts/check-section-landing-index.mjs --self-test :: exit 0 node scripts/check-section-landing-index.mjs :: exit 0 node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0 node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0 node scripts/release-pending-publish.mjs --self-test :: exit 0 pnpm --dir ui exec vitest run scripts/ :: exit 0 pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0 pnpm --filter @objectstack/lint run check:doc-security-posture :: exit 0 pnpm --filter @objectstack/spec run check:docs :: exit 0 pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0 pnpm --filter @objectstack/spec run check:empty-state :: exit 0 pnpm --filter @objectstack/spec run check:liveness :: exit 0 pnpm --filter @objectstack/spec run check:skill-examples :: exit 0 pnpm --filter @objectstack/spec run check:strictness-ledger :: exit 0 pnpm --filter @objectstack/spec run check:variant-docs :: exit 0 pnpm --filter @objectstack/spec run check:yaml-examples :: exit 0 pnpm check:agent-test-spelling :: exit 0 pnpm check:bash32-floor :: exit 0 pnpm check:changeset-gate-self-tests :: exit 0 pnpm check:ci-filter-parity :: exit 0 pnpm check:cli-command-ids :: exit 0 pnpm check:closed-ceremony-text :: exit 0 pnpm check:corpus-claim-drift :: exit 0 pnpm check:cross-package-test-inputs :: exit 0 pnpm check:dispatcher-error-vocabulary :: exit 0 pnpm check:doc-anchors :: exit 0 pnpm check:doc-authoring :: exit 0 pnpm check:doc-frontmatter :: exit 0 pnpm check:docs-audit-scope :: exit 0 pnpm check:docs-redirects :: exit 0 pnpm check:docs-single-h1 :: exit 0 pnpm check:docs-spec-enumerations :: exit 0 pnpm check:docs-transcript-drift :: exit 0 pnpm check:driver-memory-census :: exit 0 pnpm check:engine-double-contract :: exit 0 pnpm check:entry-guard :: exit 0 pnpm check:gitlink-declared :: exit 0 pnpm check:merge-driver :: exit 0 pnpm check:nul-bytes :: exit 0 pnpm check:parse-guard :: exit 0 pnpm check:pm-changeset-deadline-census :: exit 0 pnpm check:pnpm-filter-targets :: exit 0 pnpm check:pnpm-flag-spellings :: exit 0 pnpm check:published-files :: exit 0 pnpm check:published-readme-links :: exit 0 pnpm check:query-options-erasure :: exit 0 pnpm check:react-page-adapter-contract :: exit 0 pnpm check:refd-timer-probe :: exit 0 pnpm check:role-word :: exit 0 pnpm check:scripts-symbol-anchors :: exit 0 pnpm check:sdui-reference :: exit 0 pnpm check:skill-identifier-liveness :: exit 0 pnpm check:test-source-alias :: exit 0 pnpm check:tier-file-adoption :: exit 0 pnpm check:type-check-coverage :: exit 0 pnpm check:type-check-debt :: exit 0 pnpm check:undeclared-dep-imports :: exit 0 pnpm check:vendor-version-stamps :: exit 0 pnpm check:watch-hint-literal :: exit 0 pnpm check:where-matcher :: exit 0 ``` </details> --- _Generated by [Claude Code](https://claude.ai/code/session_01WGufzgPyKYGxK9udhSm8zP)_ 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WGufzgPyKYGxK9udhSm8zP --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 3bfb357 commit bbb49c9

6 files changed

Lines changed: 77 additions & 7 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
'@object-ui/plugin-gantt': patch
3+
---
4+
5+
docs(plugin-gantt): the `object-gantt` registration no longer teaches the retired view-level `api` source
6+
7+
Clause-②: no
8+
Metadata-protocol: none
9+
10+
- **Before.** The `data` input said `{ provider: 'api', read }` "reads through that request", and the `filter` input listed "an `api` request" among the record sources the gantt reads. The spec refuses that provider by name and the gantt has no reader for it: a gantt carrying it requests neither URL.
11+
- **Now.** `data` names the two providers the gantt reads, `{ provider: 'value', items }` and `{ provider: 'object', object }`, and says that rows a server computes reach the gantt as an object whose plugin driver computes them, never as a request URL in the view. `filter` names the object and inline rows.
12+
- **Unchanged.** Text only: no input, schema, renderer behaviour or export moves. The page element's `dataSource: { provider: 'api', read, path? }` binding is a different door and is untouched.

‎content/docs/ui/components/plugins.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ Namespace `plugin-gantt`.
199199
| :--- | :--- | :--- | :--- |
200200
| `objectName` | `string` | | ObjectQL object name. The record source is one of `data`, `staticData` and `objectName`; the `object-gantt` schema refuses a block that declares none of them, unless the node's `dataSource.object` names the object, which then lands on this key. |
201201
| `gantt` | `object` | | Gantt-timeline configuration, the author face — the same block `ListViewSchema.gantt` declares, and the one the renderer validates this node against. Taken WHOLE when present: the flat top-level spelling beside it is ignored. The spec requires `startDateField`, `endDateField` and `titleField`, which name the record fields a task's bar starts at, ends at and is titled by; the other members (`progressField`, `colorField`, `dependenciesField`, `parentField`, `viewMode`, `exportFileName`, …) are optional. |
202-
| `data` | `object` | | A `{ provider, … }` data-source configuration, read FIRST on the record-source ladder: a gantt carrying one never reaches `staticData` and never queries `objectName`. `{ provider: 'value', items }` charts those rows, `{ provider: 'object', object }` queries that object and `{ provider: 'api', read }` reads through that request. A bare array is not this key’s shape and is not a record source: the gantt falls through to `staticData`, then `objectName`, so inline rows belong under `staticData`. |
202+
| `data` | `object` | | A `{ provider, … }` data-source configuration, read FIRST on the record-source ladder: a gantt carrying one never reaches `staticData`. The gantt reads two providers: `{ provider: 'value', items }` charts those rows and never queries `objectName`, and `{ provider: 'object', object }` queries that object in place of `objectName`. Rows a server computes reach the gantt as an object whose plugin driver computes them, never as a request URL in the view. A bare array is not this key’s shape and is not a record source: the gantt falls through to `staticData`, then `objectName`, so inline rows belong under `staticData`. |
203203
| `staticData` | `array` | | Inline records, read SECOND on the record-source ladder: a `data` configuration wins and this key is then never reached, while `objectName` is read AFTER it, so a gantt carrying both charts these rows and never queries that object. `filter` and `sort` narrow and order these rows exactly as they do fetched ones. |
204-
| `filter` | `array` | | Base query filter in the rule-array form `[{ field, operator, value }, ...]`, narrowing the tasks the gantt charts — from every record source it reads: the object, an `api` request, or inline rows. Context tokens such as `{current_user_id}` are resolved first, then the filter is lowered to `$filter` on the query. The MongoDB-style record form is not this key’s shape. |
204+
| `filter` | `array` | | Base query filter in the rule-array form `[{ field, operator, value }, ...]`, narrowing the tasks the gantt charts — from every record source it reads: the object or inline rows. Context tokens such as `{current_user_id}` are resolved first, then the filter is lowered to `$filter` on the query. The MongoDB-style record form is not this key’s shape. |
205205
| `sort` | `array` | | Task order in `[{ field, order }]` form, ordering the rows the gantt charts. Lowered to `$orderby` on the same query. |
206206
| `navigation` | `object` | | What a task click opens — the `{ mode, size, openNewTab, preventNavigation }` block a list view declares. With the key ABSENT a click opens the task's record in a drawer, this renderer's own default. `mode` is `drawer` (the overlay), `new_window`, `page` or `none`, and a block written without `mode` takes the spec's `drawer` default. `drawer` opens the task's record in the drawer; `none` opens nothing. `page` opens the task's record page in the same tab and `new_window` opens it in a new tab. The gantt builds that address itself from the page it is on and does not use a record navigator the host publishes, so a host that publishes one changes nothing: on the object's own list or view route (`…/OBJECT/view/VIEW`) the address is the record page `…/OBJECT/record/ID`, while on any other page, such as a custom page, `/OBJECT/record/ID` is appended to the current address. The object is `data.object` when `data` is the object provider, else `objectName`; on inline rows that name neither there is no record to open, and every mode, the default drawer included, opens nothing. `preventNavigation: true` opens nothing whatever the mode, `openNewTab: true` opens the record page in a new tab and outranks every mode except `none`, and `size` sets the overlay width. |
207207
| `label` | `string` \| `object` | | Gantt label — the second link of the exported PNG/PDF file-name chain, after `gantt.exportFileName` and before the bound object's own label. A string is used as written, and an inline locale map (`{ en, "zh-CN", … }`) gives the entry for the display locale. The chart draws it nowhere else. |

‎scripts/sdui-manifest.record.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"source": "built-tree",
1515
"generator": "scripts/gen-sdui-manifest-node.mjs",
1616
"generatedAt": "2026-10-29",
17-
"sha256": "2ec5933ffaca5ab9cd1767f6d53c0e7eddb3880627c00c3275f71ed03253f3b8",
17+
"sha256": "776bef14f20193239ad50cb76769e3dc366456005e907593041ebb5266c9f444",
1818
"components": 106,
1919
"inTree": {
2020
"modulesRoot": "ui/apps/console",

‎sdui.manifest.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,7 @@
10041004
{
10051005
"name": "data",
10061006
"type": "object",
1007-
"description": "A `{ provider, … }` data-source configuration, read FIRST on the record-source ladder: a gantt carrying one never reaches `staticData` and never queries `objectName`. `{ provider: 'value', items }` charts those rows, `{ provider: 'object', object }` queries that object and `{ provider: 'api', read }` reads through that request. A bare array is not this key’s shape and is not a record source: the gantt falls through to `staticData`, then `objectName`, so inline rows belong under `staticData`."
1007+
"description": "A `{ provider, … }` data-source configuration, read FIRST on the record-source ladder: a gantt carrying one never reaches `staticData`. The gantt reads two providers: `{ provider: 'value', items }` charts those rows and never queries `objectName`, and `{ provider: 'object', object }` queries that object in place of `objectName`. Rows a server computes reach the gantt as an object whose plugin driver computes them, never as a request URL in the view. A bare array is not this key’s shape and is not a record source: the gantt falls through to `staticData`, then `objectName`, so inline rows belong under `staticData`."
10081008
},
10091009
{
10101010
"name": "staticData",
@@ -1014,7 +1014,7 @@
10141014
{
10151015
"name": "filter",
10161016
"type": "array",
1017-
"description": "Base query filter in the rule-array form `[{ field, operator, value }, ...]`, narrowing the tasks the gantt charts — from every record source it reads: the object, an `api` request, or inline rows. Context tokens such as `{current_user_id}` are resolved first, then the filter is lowered to `$filter` on the query. The MongoDB-style record form is not this key’s shape."
1017+
"description": "Base query filter in the rule-array form `[{ field, operator, value }, ...]`, narrowing the tasks the gantt charts — from every record source it reads: the object or inline rows. Context tokens such as `{current_user_id}` are resolved first, then the filter is lowered to `$filter` on the query. The MongoDB-style record form is not this key’s shape."
10181018
},
10191019
{
10201020
"name": "sort",
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* ObjectUI
3+
* Copyright (c) 2024-present ObjectStack Inc.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
/**
10+
* objectstack#27130 — the `object-gantt` registration teaches no view-level
11+
* `api` record source.
12+
*
13+
* The view-level `api` data source is retired in `@objectstack/spec`
14+
* (objectstack#23082): the spec refuses `data: { provider: 'api', … }` by name,
15+
* and `resolveDataSource` has no `api` arm, so a gantt still carrying one never
16+
* requests its `read` / `write` URLs (behaviour pinned by
17+
* `recordSourceInputs-10394.test.tsx`, its "retired api block" row). The
18+
* registration's `data` and `filter` descriptions still named it as a live
19+
* record source, and that published text is what an author copied. Rows a
20+
* server computes reach the gantt as an object behind a plugin driver.
21+
*
22+
* The pin reads the registered inputs, which feed `sdui.manifest.json` and the
23+
* generated component reference, so one row covers all three.
24+
*/
25+
26+
import { describe, it, expect } from 'vitest';
27+
import { ComponentRegistry } from '@object-ui/core';
28+
// Module scope, not a hook: this import IS the registration (AGENTS.md
29+
// test-discipline section).
30+
import '../index';
31+
32+
/** `provider: 'api'` in any quoting, or an `api` request/source named in code font. */
33+
const TEACHES_API_SOURCE = /provider:\s*\\?['"]api\\?['"]|`api`/;
34+
35+
const descriptions = (): Array<[string, string]> =>
36+
(((ComponentRegistry.getConfig('object-gantt', 'plugin-gantt') as any)?.inputs ?? []) as any[]).map(
37+
(input) => [input.name, String(input.description ?? '')],
38+
);
39+
40+
describe('objectstack#27130 — object-gantt teaches no retired api record source', () => {
41+
it('control: the matcher fires on the text it replaced', () => {
42+
expect("`{ provider: \\'api\\', read }` reads through that request").toMatch(TEACHES_API_SOURCE);
43+
expect("`{ provider: 'api', read }` reads through that request").toMatch(TEACHES_API_SOURCE);
44+
expect('the object, an `api` request, or inline rows').toMatch(TEACHES_API_SOURCE);
45+
});
46+
47+
it('no input description names a provider: api record source', () => {
48+
const rows = descriptions();
49+
expect(rows.map(([name]) => name)).toEqual(expect.arrayContaining(['data', 'filter']));
50+
expect(rows.filter(([, text]) => TEACHES_API_SOURCE.test(text)).map(([name]) => name)).toEqual([]);
51+
});
52+
53+
it('positive control: data still names the object and value providers', () => {
54+
const data = new Map(descriptions()).get('data') ?? '';
55+
expect(data).toContain("`{ provider: 'object', object }`");
56+
expect(data).toContain("`{ provider: 'value', items }`");
57+
});
58+
});

‎ui/packages/plugin-gantt/src/index.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,9 @@ ComponentRegistry.register('object-gantt', ObjectGanttRenderer, {
182182
inputs: [
183183
{ name: 'objectName', type: 'string', description: 'ObjectQL object name. The record source is one of `data`, `staticData` and `objectName`; the `object-gantt` schema refuses a block that declares none of them, unless the node\'s `dataSource.object` names the object, which then lands on this key.' },
184184
{ name: 'gantt', type: 'object', description: 'Gantt-timeline configuration, the author face — the same block `ListViewSchema.gantt` declares, and the one the renderer validates this node against. Taken WHOLE when present: the flat top-level spelling beside it is ignored. The spec requires `startDateField`, `endDateField` and `titleField`, which name the record fields a task\'s bar starts at, ends at and is titled by; the other members (`progressField`, `colorField`, `dependenciesField`, `parentField`, `viewMode`, `exportFileName`, …) are optional.' },
185-
{ name: 'data', type: 'object', description: 'A `{ provider, … }` data-source configuration, read FIRST on the record-source ladder: a gantt carrying one never reaches `staticData` and never queries `objectName`. `{ provider: \'value\', items }` charts those rows, `{ provider: \'object\', object }` queries that object and `{ provider: \'api\', read }` reads through that request. A bare array is not this key’s shape and is not a record source: the gantt falls through to `staticData`, then `objectName`, so inline rows belong under `staticData`.' },
185+
{ name: 'data', type: 'object', description: 'A `{ provider, … }` data-source configuration, read FIRST on the record-source ladder: a gantt carrying one never reaches `staticData`. The gantt reads two providers: `{ provider: \'value\', items }` charts those rows and never queries `objectName`, and `{ provider: \'object\', object }` queries that object in place of `objectName`. Rows a server computes reach the gantt as an object whose plugin driver computes them, never as a request URL in the view. A bare array is not this key’s shape and is not a record source: the gantt falls through to `staticData`, then `objectName`, so inline rows belong under `staticData`.' },
186186
{ name: 'staticData', type: 'array', description: 'Inline records, read SECOND on the record-source ladder: a `data` configuration wins and this key is then never reached, while `objectName` is read AFTER it, so a gantt carrying both charts these rows and never queries that object. `filter` and `sort` narrow and order these rows exactly as they do fetched ones.' },
187-
{ name: 'filter', type: 'array', description: 'Base query filter in the rule-array form `[{ field, operator, value }, ...]`, narrowing the tasks the gantt charts — from every record source it reads: the object, an `api` request, or inline rows. Context tokens such as `{current_user_id}` are resolved first, then the filter is lowered to `$filter` on the query. The MongoDB-style record form is not this key’s shape.' },
187+
{ name: 'filter', type: 'array', description: 'Base query filter in the rule-array form `[{ field, operator, value }, ...]`, narrowing the tasks the gantt charts — from every record source it reads: the object or inline rows. Context tokens such as `{current_user_id}` are resolved first, then the filter is lowered to `$filter` on the query. The MongoDB-style record form is not this key’s shape.' },
188188
{ name: 'sort', type: 'array', description: 'Task order in `[{ field, order }]` form, ordering the rows the gantt charts. Lowered to `$orderby` on the same query.' },
189189
{ name: 'navigation', type: 'object', description: OBJECT_GANTT_NAVIGATION_DESCRIPTION },
190190
{ name: 'label', type: ['string', 'object'], description: 'Gantt label — the second link of the exported PNG/PDF file-name chain, after `gantt.exportFileName` and before the bound object\'s own label. A string is used as written, and an inline locale map (`{ en, "zh-CN", … }`) gives the entry for the display locale. The chart draws it nowhere else.' },

0 commit comments

Comments
 (0)