Uh oh!
There was an error while loading. Please reload this page.
fix(types,plugin-charts): DrillDownConfig 只声明有人读的键,ObjectChart 补 target: 'navigate' (#3354) - #3382
Merged
Merged
Conversation
…er reads (#3354) `DrillDownConfig` is shared by five widgets and is the shape the protocol's own `drillDown` declaration is being derived from (objectstack#5022). Three of its promises were not delivered. - `view?: string` ("reserved") and `sort?: Array<{ field; dir? }>` had zero read sites repo-wide. Removed rather than implemented: nothing asked for them, and left in place they were about to become dead keys with protocol authority. A compile-time pin in `@object-ui/types` keeps them from drifting back without a reader. - `target: 'navigate'` was honoured by `DrillDownDrawer` (table / pivot / metric) but ObjectChart draws its own drawer and branched on `'dialog'` only, so `'navigate'` fell through to the default Sheet even with host navigation wired. ObjectChart now routes it through `DrillNavigationContext.openRecordList` with the same merged filter, and keeps the documented fallback to the drawer when no host handler exists. The registry input advertises `'navigate'` so the palette matches. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
…get union
`ChartDrillDownSchema` landed in `@objectstack/spec` declaring the chart drill
target as `'drawer' | 'dialog'`, strictly, and `validate-react-page-props`
parses that schema against the authored `drillDown={{…}}` literal at publish
time. Advertising `'navigate'` in the `object-chart` registry input would
therefore hand an author a value the publish gate then rejects — the exact
failure framework#5022 was opened to stop.
The component still HONOURS `'navigate'`: the asymmetry is the protocol union
being narrower than the renderer, and the fix for that belongs in the spec.
Recorded at the read site, in the registry comment and in the parity test so
the next reader does not "fix" the palette in the wrong direction.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt…jectstack#5435 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 5, 2026 11:53
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#3354
结论先说:三项前提独立复核,全部成立
以
origin/main为准逐项核过,没有一项已经过期:view零消费者 —— 全仓drillDown?.view/config.view类读取点 0 命中。sort零消费者 —— 同样 0 命中。仅有的两处cfg.sort/config.sort是别的类型:packages/app-shell/src/views/InterfaceListPage.tsx:362(页面 list-view 配置)与packages/core/src/data-scope/ViewDataProvider.ts:276(ElementDataSourceConfig),与DrillDownConfig无关。maxRows命中ObjectChart.tsx:781、ObjectPivotTable.tsx:251;columns命中ObjectChart.tsx:782、ObjectDataTable.tsx:439、ObjectPivotTable.tsx:250。所以「0 命中」是真的没人读,不是扫描面写坏了。ObjectChart.tsx自绘抽屉当时确实只有if (target === 'dialog')与默认return Sheet两支,'navigate'落进 Sheet。改了什么
一、
view/sort从DrillDownConfig删除(declared = enforced)两个键自陈 reserved / 承诺排序,却没有任何渲染器读它们 —— 作者写了等于没写,而且没有任何提示。按 PM 裁定删除而非实现:现在没有需求方,而这个接口正是 objectstack#5022 反推 spec 声明形状的依据,留着就会从「渲染器里的死键」升级成「协议承诺的死键」。
同时在接口 JSDoc 上写下这条不变量(哪两个键被删、为什么、不要在没有读取方之前加回来)。
二、
ObjectChart补target: 'navigate'分支共享接口的 JSDoc 承诺
'navigate'跳过就地视图、直接进对象完整列表页,host 未提供 navigation 时回落 drawer。走DrillDownDrawer的三个 widget(table / pivot / metric)都兑现了(navigateOnly),唯独 ObjectChart 自绘抽屉不兑现。现在 ObjectChart 语义对齐
DrillDownDrawer.navigateOnly:target: 'navigate'+ host 提供DrillNavigationContext.openRecordList⇒ 直接跳列表页,不渲染抽屉,过滤条件与抽屉本会用的完全一致(widget filter ∧ 点击上下文);'drawer'/'dialog'行为不变;表头的 "Open in list" escape hatch 仍独立于target。实现上把 drill filter 从抽屉块里提升成一个
useMemo(抽屉块位于本组件的条件式早返回之后,effect 不能放在那里),两条路径因此共用同一个 filter,不会各算一份。⛔
packages/plugin-dashboard/**全程只读:只读它对齐语义,没有改它、没有搬它。三、registry input 描述:维持 spec 声明的
'drawer' | 'dialog',不擅自加'navigate'这一条我先写反了,自查后改了回来,把过程留在这里以免下一个人往错的方向「修」:
我一度把
'navigate'加进了object-chart的drillDowninput 描述,理由是「渲染器兑现了就该声明」。但ChartDrillDownSchema已经在@objectstack/spec落地,把 chart drill 的 target 声明成'drawer' | 'dialog',strict,而且packages/lint/src/validate-react-page-props.ts会真的 parse 它来校验作者写的drillDown={{…}}字面量。所以在面板里列出'navigate',等于把平台权威递给一个发布闸门随后会拒绝的值 —— 正是 objectstack#5022 开单要消灭的失效模式,方向刚好相反。所以:组件兑现
'navigate',面板不广告它。协议的联合先动,面板再跟,顺序不能反。这处不对称在读取点、registry 注释、parity 测试三处都写明了原因,免得被当成疏漏「顺手补上」。四、由此产生的 spec 侧缺口(已另立单,不在本 PR 修)
objectstack#5022 第二轮裁决把 target 定为两个成员,理由是「每键有 ObjectChart 读取点」——一条测量,而本 PR 正好把这条测量改掉了。于是渲染器交付 3 个 target、协议声明 2 个,react 页面上写
'navigate'会被发布闸门拒绝。已按 Prime Directive #10 立 objectstack#5435(未指派),并在 objectstack#5022 留了知会。本 PR 不碰 spec。
测试与反向验证
新增 / 更新
packages/plugin-charts/src/ObjectChart.drillNavigate.test.tsx(新,4 例):navigate 跳转 + 不渲染抽屉、无 host 回退抽屉、默认 drawer 不回归、dialog不回归。Sheet 与 Dialog 在 Radix 下同为role="dialog",用两者各自的定位 class 区分,避免「断言通过是因为什么都没渲染」。packages/types/src/__tests__/drill-down-config-declared-keys.test.ts(新):编译期钉住view/sort不再是DrillDownConfig的键,并保留活键(filter/columns/maxRows/target)与target三元联合作为对照,防止接口被整体改坏时上面两条空过。packages/plugin-charts/src/index.test.ts:parity 测试的断言维持原样(navigate仍在「不得广告」侧),但把理由换成上面第三节的那条 —— 原理由「chart 不读它」已经随本 PR 失效,不换就成了一条钉着正确结论的错误注释。反向验证(方向先判后跑)
view/sort加回接口,pnpm --filter @object-ui/types type-check报drill-down-config-declared-keys.test.ts(62,31)与(63,31)error TS2344: Type 'false' does not satisfy the constraint 'true'。跑出来就是红,方向一致。(这两条是纯编译期钉子 —— vitest 只剥类型不检查类型,靠的是本包tsconfig.test.json被type-check串起来。)navigateOnly强制成false(等价于本 PR 前的行为)后:第 1 例AssertionError: expected "vi.fn()" to be called with arguments: [ 'opportunity', …(1) ],其余 3 例 passed。方向完全一致。正向
pnpm exec vitest run packages/plugin-charts/ packages/plugin-dashboard/ packages/core/ packages/types/(仓根,即 CI 的配置)⇒ 133 files / 2127 tests passed, 0 failed。DrillDownDrawer.escapeHatch/ObjectDataTable.drill/PivotTable.drill与 core 的drill-down工具测试。type-check:@object-ui/types/@object-ui/core/@object-ui/plugin-charts/@object-ui/plugin-dashboard全部 Done。lint:两个改动包 0 errors。check-changeset-no-major/check-changeset-fixed均通过(本 changeset 标minor,按仓库版本政策 —— objectui 自身的破坏性变更也走minor,破坏语义写在正文里)。🤖 Generated with Claude Code
https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt