Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .changeset/home-tabs-bind-saved-views.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
'hotcrm': patch
---

Sales Home's three tabs now show the work they are named after, and the
Activities documentation describes the task views the app actually ships.

**Sales Home.** *My Leads*, *My Opportunities* and *My Tasks* each held a single
`page:section` with no properties. That is a legal page schema — it validates,
it builds, and it renders `<section></section>`: three tab names over three
blank panels, measured in a browser, with no diagnostic anywhere because there
is no broken reference to catch. The three tabs now embed the objects' own saved
views (**My Leads**, **My Open Deals**, **My Open Tasks**), which render as
sortable, filterable grids on the landing page; `{current_user_id}` resolves on
this path, so "mine" means mine. Two tabs were renamed to match the view behind
them — *My Opportunities* became **My Open Deals** and *My Tasks* became **My
Open Tasks**, because both views exclude closed/completed records and the old
names promised more than they showed.

The tab configuration is **read off** `src/views/*.view.ts` rather than retyped,
so there is still exactly one definition of what "my leads" means; a page
component cannot name a saved view on 17.0.0-rc.2, and retyping the columns and
filters would have created a second definition free to drift from the first.
A new guard (`no page tab renders an empty container`) fails the build for any
future tab that promises content and binds none.

**Activities documentation** (English, zh-Hans, zh-Hant). The page advertised a
*home page activity widget* offering *Today's Tasks* and *Overdue Tasks* — no
such widget exists, and those two names belong to list views whose shipped
labels and behaviour are different again. Its "Standard list views" roster named
six views, of which four do not exist and two were described by the wrong
filter: *Today* was documented as "due today" when **📅 My Priority Tasks**
filters on priority and status and never looks at a date, and *Overdue* was
documented as "past due date, not completed" when **⏰ Open Tasks · Most Overdue
First** is the whole open backlog ordered oldest-due-first, not a past-due
filter. Meanwhile the five views that make tasks the richest object in the app —
All Tasks, Task Board, Task Schedule, Execution Plan and Worklog Timeline — went
unmentioned. All eight views are now documented tab by tab against
`src/views/task.view.ts`, including where each one is reached from.
24 changes: 15 additions & 9 deletions content/docs/sales/activities.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,24 @@ Use cases:

Activities show up in **three** places:

1. **The task list** — global "My Tasks" tab.
2. **The Activity tab on the related record** — open an account, see all related tasks.
3. **The home page activity widget** — *Today's Tasks* and *Overdue Tasks*.
1. **The task list** — **My Work › All Tasks** opens the whole list with the eight view tabs described below; **My Work › My Tasks** drops you straight onto *My Open Tasks*.
2. **The Activity tab on the related record** — open an account, a lead, an opportunity or a case and its Activity tab gathers the tasks and events hanging off it.
3. **The Sales Home page** — its **My Open Tasks** tab embeds that same *My Open Tasks* view, so what you owe is on the page you land on. Sales Home carries no activity *metric*: the four tiles at the top are all pipeline (Revenue (Won), Deals Won, Pipeline Value, Open Leads). Activity volume is reported on the Sales Activity dashboard — see below.

## Standard list views

- **My Open Tasks** — your incomplete tasks.
- **Overdue** — past due date, not completed.
- **Today** — due today.
- **This Week** — due in the next 7 days.
- **Completed This Week** — for activity reporting.
- **By Priority** — sorted by priority descending.
Tasks are the richest object in the app for ways to look at the same records: eight saved views, one per tab across the top of the list, in this order. Three of the tabs are named for the job rather than for the view they open, so both names are given.

| Tab | The view it opens | What it shows |
| --- | --- | --- |
| **All** *(the landing tab)* | **All Tasks** | Every task. Unfinished ones first, then soonest due; the row carries a completion tick, status, priority, due date, progress, owner and an overdue flag, and is tinted by priority — red for urgent, orange for high, green for normal, grey for low. 50 rows a page, tick several to act on them together. **My Work › All Tasks** opens the same list. |
| **Board** | **Task Board** | The kanban board, one column per status, cards showing subject, priority, due date and progress. Completed tasks are left out — this is the work still moving. Opening a card slides the task in from the side rather than taking you off the board. |
| **Schedule** | **Task Schedule** | Tasks placed on a calendar by **due date** and coloured by priority. It filters nothing, so finished tasks stay on the calendar where they happened. |
| **Plan** | **Execution Plan** | The gantt view: each task is a bar from its **reminder date** to its **due date**, filled to its progress percentage. |
| **Worklog** | **Worklog Timeline** | The same reminder-to-due span laid out week by week and grouped by **owner**, coloured by status — who is carrying what, and when. |
| **My Tasks** | **My Open Tasks** | The tasks **you** own that are not finished, soonest due first. The same view sits behind **My Work › My Tasks** and behind the **My Open Tasks** tab on Sales Home. |
| **Priority** | **📅 My Priority Tasks** | Open tasks — *Not Started* or *In Progress* — at **High** or **Urgent** priority, soonest due first with urgent above high on the same day. Read the name carefully: the filter mentions **no date at all**, so this is the priority queue, not a "due today" list. It carries no owner clause either, so it shows every high/urgent open task you have access to, not only your own. |
| **Backlog** | **⏰ Open Tasks · Most Overdue First** | Every unfinished task, oldest due date at the top. The name is the honest one: this is **not** filtered down to tasks that are strictly past due — it is the open backlog sorted so that whatever has been waiting longest surfaces first. The **Overdue** tick on the *All* tab is not a second opinion either: it is stamped when the task is **saved**, so it tells you what was true at the last edit, not what is true today. |

## How the system uses activities

Expand Down
24 changes: 15 additions & 9 deletions content/docs/sales/activities.zh-Hans.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,24 @@ description: 任务——你仍然欠客户的事,挂在任意记录上。每

活动会出现在**三个**地方:

1. **任务列表**——全局的"我的任务"标签页。
2. **相关记录上的活动标签页**——打开一个客户,可以看到所有相关任务。
3. **主页活动小部件**——*今日任务*和*逾期任务*。
1. **任务列表**——**我的工作 › 全部任务**打开完整列表,顶部就是下面这八个视图标签页;**我的工作 › 我的任务**则直接落在*我的待办任务*上。
2. **相关记录上的活动标签页**——打开一个客户、线索、商机或服务案例,它的活动标签页会把挂在这条记录上的任务与活动(Event)汇总在一起。
3. **销售主页**——主页上的 **My Open Tasks** 标签页内嵌的就是同一个*我的待办任务*视图,你欠下的事就摆在落地页上。销售主页上**没有**任何活动类**指标**:顶部四个磁贴全是管道指标(Revenue (Won)、Deals Won、Pipeline Value、Open Leads)。活动量的读数在 Sales Activity 仪表盘上——见下文。

## 标准列表视图

- **我的开放任务**——你未完成的任务。
- **逾期**——已过截止日期,未完成。
- **今天**——今天到期。
- **本周**——未来 7 天内到期。
- **本周已完成**——用于活动报告。
- **按优先级**——按优先级降序排序。
任务是全仓库看法最多的对象:八个已保存视图,列表顶部一个标签页对应一个,顺序如下。其中三个标签页是按"干什么"命名的,与它打开的视图不同名,所以两个名字都给出。另外,标签页名字目前不随语言包翻译(界面上就是英文),视图名则跟随界面语言。

| 标签页 | 打开的视图 | 展示什么 |
| --- | --- | --- |
| **All**(默认打开) | **全部任务** | 所有任务。未完成的在前,同组内按截止日期由近及远;行上有完成勾选框、状态、优先级、截止日期、进度、负责人和逾期标记,并按优先级着色——紧急红色、高橙色、普通绿色、低灰色。每页 50 行,可勾选多行批量处理。**我的工作 › 全部任务**打开的就是它。 |
| **Board** | **任务看板** | 看板视图,一个状态一列,卡面是主题、优先级、截止日期和进度。已完成的任务不在板上——这里只放还在动的活。点开卡片是从侧边滑出的抽屉,不会把你带离看板。 |
| **Schedule** | **任务日程** | 任务按**截止日期**落在日历上,按优先级着色。它不做任何过滤,所以已完成的任务仍留在它发生的那一天。 |
| **Plan** | **执行计划** | 甘特图:每个任务是一根从**提醒日期**到**截止日期**的横条,按进度百分比填充。 |
| **Worklog** | **工时时间线** | 同样是提醒日期到截止日期的跨度,按周铺开并按**负责人**分组,按状态着色——谁手上扛着什么、什么时候。 |
| **My Tasks** | **我的待办任务** | **你**负责且尚未完成的任务,按截止日期由近及远。**我的工作 › 我的任务**和销售主页的 **My Open Tasks** 标签页背后是同一个视图。 |
| **Priority** | **📅 我的优先任务** | 处于*未开始*或*进行中*、优先级为**高**或**紧急**的任务,按截止日期由近及远,同一天内紧急排在高之前。名字要仔细读:它的过滤条件里**完全没有日期**,所以这是优先级队列,不是"今天到期"清单;它同样没有负责人条件,因此展示的是你有权看到的所有高/紧急待办任务,不只是你自己的。 |
| **Backlog** | **⏰ 待办任务 · 按逾期时长排序** | 所有未完成的任务,截止日期最早的排在最上面。这个名字是老实的:它**不是**筛出"确已过期"的那批,而是把待办积压按等得最久的排在前面。*All* 标签页上的**逾期**勾选也不是第二个答案:它是**保存**任务时盖上的,告诉你的是上次编辑那一刻的情况,而不是今天的情况。 |

## 系统如何使用活动

Expand Down
24 changes: 15 additions & 9 deletions content/docs/sales/activities.zh-Hant.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,24 @@ description: 任務——你仍然欠客戶的事,掛在任意記錄上。每

活動會出現在**三個**地方:

1. **任務列表**——全局的「我的任務」標籤頁。
2. **相關記錄上的活動標籤頁**——打開一個客戶,可以看到所有相關任務。
3. **首頁活動小工具**——*今日任務*和*逾期任務*。
1. **任務列表**——**我的工作 › 全部任務**打開完整列表,頂部就是下面這八個視圖標籤頁;**我的工作 › 我的任務**則直接落在*我的待辦任務*上。
2. **相關記錄上的活動標籤頁**——打開一個客戶、線索、商機或服務案例,它的活動標籤頁會把掛在這筆記錄上的任務與活動(Event)彙總在一起。
3. **銷售主頁**——主頁上的 **My Open Tasks** 標籤頁內嵌的就是同一個*我的待辦任務*視圖,你欠下的事就擺在落地頁上。銷售主頁上**沒有**任何活動類**指標**:頂部四個磁貼全是管道指標(Revenue (Won)、Deals Won、Pipeline Value、Open Leads)。活動量的讀數在 Sales Activity 儀表板上——見下文。

## 標準列表視圖

- **我的開放任務**——你未完成的任務。
- **逾期**——已過截止日期,未完成。
- **今天**——今天到期。
- **本週**——未來 7 天內到期。
- **本週已完成**——用於活動報告。
- **按優先級**——按優先級降序排序。
任務是全倉庫看法最多的物件:八個已儲存視圖,列表頂部一個標籤頁對應一個,順序如下。其中三個標籤頁是按「做什麼」命名的,與它打開的視圖不同名,所以兩個名字都給出。另外,標籤頁名字目前不隨語言包翻譯(介面上就是英文),視圖名則跟隨介面語言。

| 標籤頁 | 打開的視圖 | 展示什麼 |
| --- | --- | --- |
| **All**(預設打開) | **全部任務** | 所有任務。未完成的在前,同組內按截止日期由近及遠;列上有完成勾選框、狀態、優先級、截止日期、進度、負責人和逾期標記,並按優先級著色——緊急紅色、高橙色、普通綠色、低灰色。每頁 50 列,可勾選多列批次處理。**我的工作 › 全部任務**打開的就是它。 |
| **Board** | **任務看板** | 看板視圖,一個狀態一欄,卡面是主題、優先級、截止日期和進度。已完成的任務不在板上——這裡只放還在動的活。點開卡片是從側邊滑出的抽屜,不會把你帶離看板。 |
| **Schedule** | **任務日程** | 任務按**截止日期**落在日曆上,按優先級著色。它不做任何過濾,所以已完成的任務仍留在它發生的那一天。 |
| **Plan** | **執行計劃** | 甘特圖:每個任務是一根從**提醒日期**到**截止日期**的橫條,按進度百分比填充。 |
| **Worklog** | **工時時間線** | 同樣是提醒日期到截止日期的跨度,按週鋪開並按**負責人**分組,按狀態著色——誰手上扛著什麼、什麼時候。 |
| **My Tasks** | **我的待辦任務** | **你**負責且尚未完成的任務,按截止日期由近及遠。**我的工作 › 我的任務**和銷售主頁的 **My Open Tasks** 標籤頁背後是同一個視圖。 |
| **Priority** | **📅 我的優先任務** | 處於*未開始*或*進行中*、優先級為**高**或**緊急**的任務,按截止日期由近及遠,同一天內緊急排在高之前。名字要仔細讀:它的過濾條件裡**完全沒有日期**,所以這是優先級佇列,不是「今天到期」清單;它同樣沒有負責人條件,因此展示的是你有權看到的所有高/緊急待辦任務,不只是你自己的。 |
| **Backlog** | **⏰ 待辦任務 · 按逾期時長排序** | 所有未完成的任務,截止日期最早的排在最上面。這個名字是老實的:它**不是**篩出「確已過期」的那批,而是把待辦積壓按等得最久的排在前面。*All* 標籤頁上的**逾期**勾選也不是第二個答案:它是**儲存**任務時蓋上的,告訴你的是上次編輯那一刻的情況,而不是今天的情況。 |

## 系統如何使用活動

Expand Down
81 changes: 58 additions & 23 deletions src/pages/home.page.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,58 @@
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.

import { Page } from '@objectstack/spec/ui';
import { Page, PageComponent, View } from '@objectstack/spec/ui';
import { LeadViews } from '../views/lead.view';
import { OpportunityViews } from '../views/opportunity.view';
import { TaskViews } from '../views/task.view';

/**
* Embed one of an object's OWN saved list views in a page region.
*
* The home tabs used to hold a bare `{ type: 'page:section', properties: {} }`
* each, which renders an empty `<section>` — three tab names promising content
* over three blank panels. Same lesson as the `record:highlights` card below:
* a component with no binding renders nothing, silently.
*
* `list-view` is the block that renders an object list inside a page (it is in
* the platform's public block contract, ADR-0080), and it takes its columns /
* filter / sort inline — there is no way for a page component to name a saved
* view, so those three keys are READ OFF the saved view here rather than
* retyped. That is the same iron rule `account_workbench.page.ts` states for
* interface pages: columns, base filter and sort are inherited, never restated.
* Retyping them would have created a second definition of "my leads" that
* drifts from `src/views/lead.view.ts` the first time either side is edited.
*
* `{current_user_id}` in a saved view's filter resolves on this path (the
* ObjectQL read path runs `resolveFilterTokens()` since 17.0.0-rc.0), so
* "mine" really does mean mine here — measured tab by tab in the browser, see
* the PR. The nav's My Work group reaches the SAME views by name
* (`src/apps/crm.app.ts`); these tabs are the landing-page shortcut to them.
*/
const embeddedListView = (id: string, objectName: string, views: View, viewKey: string): PageComponent => {
const view = views.listViews?.[viewKey];
// Loud, at build time: a renamed or deleted view must not degrade back into
// a blank tab — that is the defect this whole component replaces.
if (!view) throw new Error(`home.page.ts: no saved view "${viewKey}" on ${objectName}`);
return {
type: 'list-view',
id,
label: view.label,
properties: {
objectName,
viewType: 'grid',
columns: view.columns,
filter: view.filter,
sort: view.sort,
},
};
};

/**
* Sales Home Page
*
*
* Demonstrates a home page layout with dashboards and quick access widgets.
* Similar to Salesforce Lightning Home Page.
*
*
* Features:
* - Dashboard-style layout
* - Multiple component regions
Expand Down Expand Up @@ -156,32 +201,22 @@ export const SalesHomePage: Page = {
{
label: 'My Leads',
icon: 'user-plus',
children: [
{
type: 'page:section',
properties: {},
},
],
children: [embeddedListView('home_my_leads', 'crm_lead', LeadViews, 'my_leads')],
},
{
label: 'My Opportunities',
// Was "My Opportunities", which promises every deal I own; the
// view behind it is the open-pipeline one (the nav's My Work >
// My Deals opens the same `my_open_deals`). The tab name now
// says what the panel shows.
label: 'My Open Deals',
icon: 'dollar-sign',
children: [
{
type: 'page:section',
properties: {},
},
],
children: [embeddedListView('home_my_deals', 'crm_opportunity', OpportunityViews, 'my_open_deals')],
},
{
label: 'My Tasks',
// Same correction: `my_open_tasks` excludes completed tasks.
label: 'My Open Tasks',
icon: 'list-checks',
children: [
{
type: 'page:section',
properties: {},
},
],
children: [embeddedListView('home_my_tasks', 'crm_task', TaskViews, 'my_open_tasks')],
},
],
},
Expand Down
Loading
Loading