Skip to content

dashboard widget compareTo 收敛为 { kind, dimension? }:遗留内联图表路径跟改 + 删除 DatasetWidget 的字符串丢弃 workaround #3337

Description

@xuyushun441-sys

跨仓 follow-up,来自 framework 侧 objectstack-ai/objectstack#5011(#4876 式知会分片)。未认领,谁接谁 assign。

背景

framework 把 DashboardWidgetSchema.compareTo 从三分支联合

'previousPeriod' | 'previousYear' | { offset: '7d' | '1M' | '1y' }

收敛为执行器已实现的那一份契约的薄投影:

compareTo?: { kind: 'previousPeriod' | 'previousYear'; dimension?: string }

DatasetSelection.compareTo(packages/spec/src/contracts/analytics-service.tsDatasetCompareTo)。dimension 现在可省略,由执行器决议:选择集里带 dateRange 的时间维度恰好一个就用它;零个或多个则响亮报错并列出候选(dataset-executor.tsresolveCompareDimension)。这是生产端决议规则,不是消费端宽容映射(PD#12)。

为什么动:在 ADR-0021 dataset 路径(spec 自称「唯一面向作者的分析形态」)上,三个分支全部无效——两个字符串分支被 DatasetWidget 显式丢弃,{ offset } 被转发进一个根本没有 offset 概念的契约,执行器抛 compareTo requires a timeDimension "undefined"。同一个键两种命运,失败的那条恰是规范路径。

本仓的遗留内联 object-provider 图表路径compareTo 三分支唯一真正能跑的地方,所以它需要跟改到新形状。framework 侧 PR 不含本仓改动。

需要做的映射

  1. packages/core/src/utils/compare-to.tsCompareToConfig 由三分支联合改为 { kind: 'previousPeriod' | 'previousYear'; dimension?: string }
  2. shiftFilterByCompareTo(filter, compareTo) — 按 compareTo.kind 分派;删掉 offset 分支的时长位移。{ offset: '1y' } 语义上等同 kind: 'previousYear'(framework 侧 D2 会确定性改写);'7d'/'1M' 无忠实目标,已登记为 dashboard-widget-compareto-offset 语义迁移,由作者在 widget 自己的 filter 上重述窗口 + kind: 'previousPeriod'
  3. compareToTrendLabelKey(compareTo, filter) — 从 .kind 推 i18n key;vs previous 7d 这类由 offset 派生的标签随分支一起去掉。
  4. packages/plugin-dashboard/src/DatasetWidget.tsx:163-168 — 那段 typeof widget.compareTo === 'object' 守卫不再需要,删掉,widget.compareTo 原样转发进 DatasetSelection.compareTo。注释里写的理由(「forwarding it makes the executor throw」)在新形状下已不成立。
  5. ⚠️ 功能性的那一半:执行器需要一个dateRangetimeDimensions 条目才有窗口可位移。DatasetWidget 目前只把 widget.filter 降成 runtimeFilter,不产出 timeDimensions,所以即使转发了结构化 compareTo,执行器仍会以「本选择集没有带 dateRange 的时间维度」报错。把 widget 已解析的日期窗口(filter 日期宏 / 仪表盘 dateRange)降成 selection.timeDimensions[].dateRange 是这条路径真正跑通的前提,也是本 issue 里唯一不是纯改型的一步。
  6. packages/plugin-charts/src/ObjectChart.tsx(:468-477:624-660)与 packages/plugin-dashboard/src/ObjectMetricWidget.tsx(:261-262:320-337)——读 .kind 而非整值判别。
  7. packages/plugin-dashboard/src/DashboardRenderer.tsx:495 只是把 widget.compareTo 透传进 object-chart schema,值不变,但类型跟着 CompareToConfig 走。
  8. 测试:packages/plugin-dashboard/src/__tests__/DatasetWidget.test.tsx:77-84 现在断言的正是「结构化转发、字符串丢弃」——反转它:新形状全部转发,不再有可丢弃的字符串形态。

设计上的两点(值得留在代码注释里)

  • 无联合。新形状是普通 strict object,不是联合。zod 把失败的联合塌缩成一条裸 Invalid input,arm 里的处方到不了作者(framework#5014),所以这次收敛顺带消除了整类「写了没人读的错误信息」。
  • dimension 的决议在执行器,不在渲染器。任何一侧自己猜维度,都会把「响亮报错」换成「安静的错窗口」——正是本次收敛要终结的失败类。

验收

  • 遗留内联路径(metric + cartesian chart)在新形状下 overlay 正常,i18n 趋势标签正确。
  • dataset 路径:一个带日期宏 filter 的 dataset widget 真的渲染出对比列(即上面第 5 点跑通),而不是静默无对比。
  • 多个带 dateRange 的时间维度时,执行器的歧义报错原样冒到 UI,而不是被吞。
  • framework 侧 pnpm objectui:refresh 后 console 构建绿。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions