Skip to content

fix(home): bind the Sales Home tabs to real views, and document the task views that ship (#771) - #784

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-771-activities-views-home-tabs
Aug 5, 2026
Merged

yinlianghui merged 1 commit into
mainfrom
claude/issue-771-activities-views-home-tabs

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes #771

Description

两件事,顺序有意义:先把 Sales Home 三个空壳标签页绑上真实视图,再按绑定后的事实重写 activities.mdx 三语的两节。

元数据(#771 第 3 点) —— sales_home_page 的 My Leads / My Opportunities / My Tasks 三个标签页,children 都是一个 { type: 'page:section', properties: {} }。这份 schema 合法、能 validate、能 build,渲染出来是一个空的 section 元素:三个承诺内容的标签页名字盖在三块空白上,而且没有任何诊断——因为这里根本没有可以"悬空"的引用,缺陷正是引用的缺席。浏览器实测(见下):三个 tabpanel 的 innerText.length 都是 0。

现在三个标签页各自内嵌对应对象已有的「my」视图,走 list-view —— 平台公开组件契约(ADR-0080 PUBLIC_BLOCKS)里用于在 page 内渲染对象列表的那个块。实测三个标签页分别渲染 21 / 10 / 6 行真实数据,带 Filter / Group / Sort 工具条,主题可点进记录。

为什么是 A 而不是退路 B:PM 的分诊把 B(整体移除标签页)设为"若 rc.2 组件模型里没有可验证的内嵌形态"时的退路。实测结论是有:list-view 在公开契约里、inputs 声明齐全、并且在 type: 'home' 页面的 page:tabs 子节点里确实渲染。所以取 A。

没有重述视图配置。rc.2 里没有任何 page 组件能按名字引用一个已保存视图(PageComponentSchema.dataSource.view 在 spec 里声明了,但 resolveElementDataSource 把 view 丢掉且除测试外零调用方),所以 columns / filter / sort 只能内联。本 PR 的做法是从 src/views/*.view.ts 读出来,不是重打一遍——否则"我的线索"就会有第二份定义,任何一边改动都开始漂移,正是本 issue 要修的缺陷类往下一层。这与 account_workbench.page.ts 写下的铁律一致:columns、base filter、sort 只继承,不重述。embeddedListView() 在视图键找不到时直接抛错,build 立刻红,不会退化回空标签页。

两个标签页改名:my_open_deals 与 my_open_tasks 都排除了已关闭 / 已完成的记录,所以 My Opportunities → My Open Deals、My Tasks → My Open Tasks,标签页名字说的就是面板里的东西(侧边栏「我的工作 › My Deals / My Tasks」进的是同两个视图)。

文档(#771 第 1、2 点) —— 三语重写「活动出现在哪里」与「标准列表视图」两节:

  • 「主页活动小部件 Today's Tasks / Overdue Tasks」不存在,这两个名字其实是两个列表视图,落地 label 又和文档写的都不一样。该条现在描述主页上真正存在的 My Open Tasks 标签页,并点明主页四个磁贴全是管道指标、没有活动指标。
  • 「标准列表视图」原来六项里四项根本不存在(This Week / Completed This Week / By Priority / Today 与 Overdue 的口径),而实际 ship 的 all_tasks / task_board / task_calendar / task_gantt / task_timeline 一个都没提。现在按 src/views/task.view.ts 逐个标签页写清八个视图:tab 名、它打开的视图 label、真实过滤与排序。两处口径按源码如实转述:📅 My Priority Tasks 的过滤里完全没有日期(是优先级队列,不是"今天到期"),也没有 owner 条件;⏰ Open Tasks · Most Overdue First 是未完成任务按最久逾期排序,不是严格已逾期的过滤。另外说明 All 上的 Overdue 勾选是保存时盖的快照,不是今天的判断(task.hook.ts:68)。
  • 第 108 行仪表盘那条是 docs(sales): 把 activities 页的活动量指标指向真正报告它的仪表盘 (#747) #772 刚订正的,原样保留。

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Documentation update

Related Issues

Fixes #771
Related to #758, #747, #772

Changes Made

  • src/pages/home.page.ts —— 三个空 page:section 换成 embeddedListView() 生成的 list-view,配置从 LeadViews / OpportunityViews / TaskViews 读取;两个标签页改名对齐视图。
  • content/docs/sales/activities.mdx + .zh-Hans + .zh-Hant —— 重写「活动出现在哪里」第 3 条与整节「标准列表视图」(八视图表格)。
  • test/metadata-references.test.ts —— 新增 no page tab renders an empty container 守卫与它的拒绝探针;并把 page 组件的 filter 纳入既有的 token 可解析规则(此前只走 interfaceConfig.filterBy)。
  • .changeset/home-tabs-bind-saved-views.md。

Testing

  • Unit tests pass — npx vitest run --maxWorkers=2 → Test Files 63 passed / Tests 1497 passed | 1 skipped
  • Linting passes — pnpm lint → 13 warning(s), 14 suggestion(s),全部是既有告警(line-item / approval 组解析 / campaign_member 字段组),本 PR 未新增
  • Build succeeds — pnpm validate → Validation passed;pnpm typecheck 干净;pnpm hygiene clean
  • Manual testing completed —— 见下「浏览器实测」
  • New tests added

浏览器实测(dev server + Chromium,@objectstack 17.0.0-rc.2)

改前(每个标签页的 tabpanel):

TAB[0] My Leads         => textLen: 0, rows: 0, html: section class="space-y-4" data-obj-type="page:section" (空)
TAB[1] My Opportunities => textLen: 0, rows: 0, 同上
TAB[2] My Tasks         => textLen: 0, rows: 0, 同上

改后:

TAB[0] "My Leads"      => dataRows: 21, tables: 1  (Full Name / Company / Email / Status / Lead Score)
TAB[1] "My Open Deals" => dataRows: 10, tables: 1  (23 条商机里 stage not_in [closed_won, closed_lost] 的 10 条)
TAB[2] "My Open Tasks" => dataRows: 6,  tables: 1  (7 条任务里未完成的 6 条)

{current_user_id} 是否真的解析,用两个临时探针标签页分别排除了"过滤被丢弃"和"按字面量比较"两种可能:

owner_id = {current_org_id}  => 0 行     (过滤确实生效,没有被丢弃)
owner_id = {current_user_id} => 7 行/全部 (字面量匹配不到任何 owner,所以是解析成了当前用户 id)

与 #773 的结论一致:resolveFilterTokens() 自 17.0.0-rc.0 起接在 ObjectQL 读路径上,已保存视图的 filter 同样覆盖。探针标签页已删除,不在提交里。

守卫的反向验证

方向先声明后跑:把删掉的肢体装回去(任一标签页 children 换回 { type: 'page:section', properties: {} }),新守卫应当变红。实测:

× no page tab renders an empty container
  sales_home_page/home_tabs: tab "My Leads" holds only empty containers (page:section) — it renders blank
  Tests  1 failed | 67 passed (68)

红,且报错直接点名是哪个标签页。恢复后 68 passed。守卫另带一个 tabsSeen > 0 断言,防止哪天遍历不到 tabs 之后规则静悄悄地永远通过。

Screenshots

截图在本地实测过程中留存(Sales Home 三个标签页改前空白 / 改后表格),受工具限制未随 PR 上传;上面的 DOM 探针数值是同一次运行的产物。

Checklist

  • I have added a changeset — .changeset/home-tabs-bind-saved-views.md
  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published

Additional Notes

边界:未动 src/views/ 任何文件(任务视图的 label / filter 都是 #770 的未决行为决策),未动 content/docs/releases/,未升降 @objectstack/*(锁 17.0.0-rc.2),平台仓库一行未动。

越界发现(未折入本 PR):

  1. src/views/task.view.ts 的两处注释仍立在 17.0 之前的过期前提上(而且彼此矛盾)—— 与 Two source comments still assert the list-view path resolves no date macro — one of them tells the next author not to generalise #744 / PR docs(comments): 订正四处仍断言「列表路径不解析日期宏」的注释(含 stale_articles) #773 同一缺陷类,是那一轮漏掉的第五个文件。已立 同 #744 缺陷类:src/views/task.view.ts 两处注释仍立在「列表路径不解析日期宏 / 用户令牌」的过期前提上,且彼此矛盾 #782。
  2. src/translations/en.ts 的 crm_task._views 缺 todays_tasks / overdue_tasks 两项,zh-CN / es-ES / ja-JP 都有;任何 gate 都看不见这个缺口(去掉 --skip-i18n 重跑也不报)。已立 i18n: en.ts 的 crm_task._views 缺 todays_tasks / overdue_tasks 两项,另外三个语言包都有,且没有任何 gate 看得见这个缺口 #783。
  3. Sales Home 上另有两张只有标题、没有 body 的 page:card(Recent Items / Today's Schedule)渲染成空卡片 —— 与 [17.0-rc2验收] sales_home_page / app_launcher_page / utility_bar_page 多个组件渲染为「Component Placeholder」,首页欢迎语用户名插值为空 #734 同页同症候族,已在 [17.0-rc2验收] sales_home_page / app_launcher_page / utility_bar_page 多个组件渲染为「Component Placeholder」,首页欢迎语用户名插值为空 #734 追加实测证据,未开新 issue。
  4. 平台侧观察(未 workaround,报给 PM):在 list-view 页面组件上设置 spec 声明的 dataSource: { object, view } 会让该组件运行时直接失败("Couldn't load records"),而同一页面上没有 dataSource 的两个 list-view 正常;ElementDataSourceSchema 的 view 键在 objectui 里被 resolveElementDataSource 丢弃,且该函数除测试外零调用方。

Generated by Claude Code

…ask views that ship

Sales Home's three tabs -- My Leads / My Opportunities / My Tasks -- each held
a single `{ type: 'page:section', properties: {} }`. That validates, builds and
renders `<section></section>`: three tab names over three blank panels, with no
diagnostic anywhere, because there is no dangling reference to catch -- the
defect is the absence of one.

Each tab now embeds the object's own saved view (My Leads, My Open Deals, My
Open Tasks) through `list-view`, the platform's public block for rendering an
object list inside a page. Measured in a browser on 17.0.0-rc.2: 21 / 10 / 6
rows respectively, filters applied and `{current_user_id}` resolved (proved
against `{current_org_id}`, which correctly returns none).

The column / filter / sort config is READ OFF `src/views/*.view.ts` rather than
retyped. A page component cannot name a saved view on rc.2, and retyping would
have created a second definition of "my leads" free to drift from the first --
the same defect class this issue is about, one layer down. Two tabs are renamed
to the view behind them, because `my_open_deals` and `my_open_tasks` both
exclude closed records and the old names promised more than they showed.

Guard: `no page tab renders an empty container` in metadata-references, plus its
own rejection probe. Reverse-verified -- restoring one empty `page:section`
turns it red naming the tab. The page-filter token rule now also walks page
COMPONENT filters, which it never did.

Docs (en / zh-Hans / zh-Hant): the "home page activity widget" offering Today's
Tasks and Overdue Tasks does not exist, and those names belong to views whose
shipped labels and filters are different again. The list-view roster named six
views, four of which do not exist, while omitting All Tasks, Task Board, Task
Schedule, Execution Plan and Worklog Timeline. All eight views are documented
tab by tab against task.view.ts, including that "My Priority Tasks" filters on
priority and never on a date, and that "Open Tasks - Most Overdue First" is the
open backlog ordered oldest-due-first rather than a strictly-past-due filter.

Fixes #771

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHrPAGEgFDoHjphqYG4BMa
@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hotcrm Ignored Ignored Aug 5, 2026 7:28pm

Request Review

@github-actions github-actions Bot added ci/cd CI plumbing and the verification pipeline metadata Declarative metadata — schema, security posture, UI surfaces labels Aug 5, 2026
@yinlianghui
yinlianghui marked this pull request as ready for review August 5, 2026 19:33
@yinlianghui
yinlianghui added this pull request to the merge queue Aug 5, 2026
Merged via the queue into main with commit fb48ab5 Aug 5, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd CI plumbing and the verification pipeline metadata Declarative metadata — schema, security posture, UI surfaces

Projects

None yet

2 participants