skill-schedule 0.3.2 → 0.3.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +12 -3
- package/dist/.gen-inputs.json +4 -4
- package/dist/admin/adminDocs.d.ts +57 -0
- package/dist/admin/adminDocs.d.ts.map +1 -0
- package/dist/admin/adminDocs.js +190 -0
- package/dist/admin/adminDocs.js.map +1 -0
- package/dist/admin/adminParts.d.ts +37 -0
- package/dist/admin/adminParts.d.ts.map +1 -0
- package/dist/admin/adminParts.js +83 -0
- package/dist/admin/adminParts.js.map +1 -0
- package/dist/admin/handlers.d.ts.map +1 -1
- package/dist/admin/handlers.js +196 -6
- package/dist/admin/handlers.js.map +1 -1
- package/dist/admin/routes.d.ts +10 -1
- package/dist/admin/routes.d.ts.map +1 -1
- package/dist/admin/routes.js +2 -0
- package/dist/admin/routes.js.map +1 -1
- package/dist/analyze/analyzeDocs.d.ts +51 -0
- package/dist/analyze/analyzeDocs.d.ts.map +1 -0
- package/dist/analyze/analyzeDocs.js +442 -0
- package/dist/analyze/analyzeDocs.js.map +1 -0
- package/dist/analyze/analyzeParts.d.ts +53 -0
- package/dist/analyze/analyzeParts.d.ts.map +1 -0
- package/dist/analyze/analyzeParts.js +229 -0
- package/dist/analyze/analyzeParts.js.map +1 -0
- package/dist/analyze/handlers.d.ts.map +1 -1
- package/dist/analyze/handlers.js +41 -4
- package/dist/analyze/handlers.js.map +1 -1
- package/dist/cli/cmd_read.js +8 -2
- package/dist/cli/cmd_read.js.map +1 -1
- package/dist/fetch/feishu.d.ts +6 -0
- package/dist/fetch/feishu.d.ts.map +1 -1
- package/dist/fetch/feishu.js +18 -7
- package/dist/fetch/feishu.js.map +1 -1
- package/dist/fetch/index.d.ts +1 -1
- package/dist/fetch/index.d.ts.map +1 -1
- package/dist/fetch/index.js +1 -1
- package/dist/fetch/index.js.map +1 -1
- package/dist/fetch/paths.d.ts +17 -4
- package/dist/fetch/paths.d.ts.map +1 -1
- package/dist/fetch/paths.js +25 -7
- package/dist/fetch/paths.js.map +1 -1
- package/dist/health.d.ts.map +1 -1
- package/dist/health.js +12 -8
- package/dist/health.js.map +1 -1
- package/dist/help/index.d.ts +1 -0
- package/dist/help/index.d.ts.map +1 -1
- package/dist/help/index.js +3 -0
- package/dist/help/index.js.map +1 -1
- package/dist/plan/discussDocs.d.ts +8 -0
- package/dist/plan/discussDocs.d.ts.map +1 -0
- package/dist/plan/discussDocs.js +321 -0
- package/dist/plan/discussDocs.js.map +1 -0
- package/dist/plan/feishuDocs.d.ts +19 -0
- package/dist/plan/feishuDocs.d.ts.map +1 -0
- package/dist/plan/feishuDocs.js +257 -0
- package/dist/plan/feishuDocs.js.map +1 -0
- package/dist/plan/handlers.d.ts.map +1 -1
- package/dist/plan/handlers.js +107 -3
- package/dist/plan/handlers.js.map +1 -1
- package/dist/plan/index.d.ts +2 -0
- package/dist/plan/index.d.ts.map +1 -1
- package/dist/plan/index.js +16 -9
- package/dist/plan/index.js.map +1 -1
- package/dist/plan/iso.d.ts +2 -0
- package/dist/plan/iso.d.ts.map +1 -1
- package/dist/plan/iso.js +6 -2
- package/dist/plan/iso.js.map +1 -1
- package/dist/plan/planDocs.d.ts +47 -0
- package/dist/plan/planDocs.d.ts.map +1 -0
- package/dist/plan/planDocs.js +159 -0
- package/dist/plan/planDocs.js.map +1 -0
- package/dist/plan/planParts.d.ts +38 -0
- package/dist/plan/planParts.d.ts.map +1 -0
- package/dist/plan/planParts.js +96 -0
- package/dist/plan/planParts.js.map +1 -0
- package/dist/plan/probe.d.ts +28 -0
- package/dist/plan/probe.d.ts.map +1 -0
- package/dist/plan/probe.js +114 -0
- package/dist/plan/probe.js.map +1 -0
- package/dist/plan/receipt.d.ts +12 -0
- package/dist/plan/receipt.d.ts.map +1 -1
- package/dist/plan/receipt.js +17 -0
- package/dist/plan/receipt.js.map +1 -1
- package/dist/plan/receiptDocs.d.ts +26 -0
- package/dist/plan/receiptDocs.d.ts.map +1 -0
- package/dist/plan/receiptDocs.js +341 -0
- package/dist/plan/receiptDocs.js.map +1 -0
- package/dist/plan/replayDocs.d.ts +165 -0
- package/dist/plan/replayDocs.d.ts.map +1 -0
- package/dist/plan/replayDocs.js +226 -0
- package/dist/plan/replayDocs.js.map +1 -0
- package/dist/plan/replaySections.d.ts +5 -0
- package/dist/plan/replaySections.d.ts.map +1 -0
- package/dist/plan/replaySections.js +471 -0
- package/dist/plan/replaySections.js.map +1 -0
- package/dist/plan/reviewDocs.d.ts +4 -0
- package/dist/plan/reviewDocs.d.ts.map +1 -0
- package/dist/plan/reviewDocs.js +130 -0
- package/dist/plan/reviewDocs.js.map +1 -0
- package/dist/plan/sync.d.ts.map +1 -1
- package/dist/plan/sync.js +5 -0
- package/dist/plan/sync.js.map +1 -1
- package/dist/policy/index.d.ts +1 -1
- package/dist/policy/index.d.ts.map +1 -1
- package/dist/policy/index.js +1 -1
- package/dist/policy/index.js.map +1 -1
- package/dist/policy/plan.d.ts +8 -0
- package/dist/policy/plan.d.ts.map +1 -1
- package/dist/policy/plan.js +20 -0
- package/dist/policy/plan.js.map +1 -1
- package/dist/query/handlers.d.ts +3 -0
- package/dist/query/handlers.d.ts.map +1 -1
- package/dist/query/handlers.js +86 -12
- package/dist/query/handlers.js.map +1 -1
- package/dist/query/queryDocs.d.ts +64 -0
- package/dist/query/queryDocs.d.ts.map +1 -0
- package/dist/query/queryDocs.js +554 -0
- package/dist/query/queryDocs.js.map +1 -0
- package/dist/query/routes.d.ts +11 -1
- package/dist/query/routes.d.ts.map +1 -1
- package/dist/query/routes.js +5 -1
- package/dist/query/routes.js.map +1 -1
- package/dist/render/copyArea.d.ts +61 -0
- package/dist/render/copyArea.d.ts.map +1 -0
- package/dist/render/copyArea.js +80 -0
- package/dist/render/copyArea.js.map +1 -0
- package/dist/render/html.d.ts.map +1 -1
- package/dist/render/html.js +3 -1
- package/dist/render/html.js.map +1 -1
- package/dist/render/index.d.ts +3 -0
- package/dist/render/index.d.ts.map +1 -1
- package/dist/render/index.js +2 -0
- package/dist/render/index.js.map +1 -1
- package/dist/shared/dayPage.d.ts +67 -0
- package/dist/shared/dayPage.d.ts.map +1 -0
- package/dist/shared/dayPage.js +92 -0
- package/dist/shared/dayPage.js.map +1 -0
- package/dist/shared/detailPage.d.ts +55 -0
- package/dist/shared/detailPage.d.ts.map +1 -0
- package/dist/shared/detailPage.js +65 -0
- package/dist/shared/detailPage.js.map +1 -0
- package/dist/shared/docPage.d.ts +22 -0
- package/dist/shared/docPage.d.ts.map +1 -0
- package/dist/shared/docPage.js +52 -0
- package/dist/shared/docPage.js.map +1 -0
- package/dist/shared/overviewPage.d.ts +52 -0
- package/dist/shared/overviewPage.d.ts.map +1 -0
- package/dist/shared/overviewPage.js +65 -0
- package/dist/shared/overviewPage.js.map +1 -0
- package/dist/shared/pageNav.d.ts +24 -0
- package/dist/shared/pageNav.d.ts.map +1 -0
- package/dist/shared/pageNav.js +70 -0
- package/dist/shared/pageNav.js.map +1 -0
- package/dist/shared/pageParts.d.ts +45 -0
- package/dist/shared/pageParts.d.ts.map +1 -0
- package/dist/shared/pageParts.js +154 -0
- package/dist/shared/pageParts.js.map +1 -0
- package/dist/shared/planPage.d.ts +49 -0
- package/dist/shared/planPage.d.ts.map +1 -0
- package/dist/shared/planPage.js +48 -0
- package/dist/shared/planPage.js.map +1 -0
- package/dist/shared/rangePage.d.ts +44 -0
- package/dist/shared/rangePage.d.ts.map +1 -0
- package/dist/shared/rangePage.js +50 -0
- package/dist/shared/rangePage.js.map +1 -0
- package/dist/shared/weekPage.d.ts +36 -0
- package/dist/shared/weekPage.d.ts.map +1 -0
- package/dist/shared/weekPage.js +42 -0
- package/dist/shared/weekPage.js.map +1 -0
- package/dist/triggers/routes.generated.d.ts +23 -1
- package/dist/triggers/routes.generated.d.ts.map +1 -1
- package/dist/triggers/routes.generated.js +4 -1
- package/dist/triggers/routes.generated.js.map +1 -1
- package/dist/write/handlers.d.ts.map +1 -1
- package/dist/write/handlers.js +101 -5
- package/dist/write/handlers.js.map +1 -1
- package/dist/write/writeDocs.d.ts +27 -0
- package/dist/write/writeDocs.d.ts.map +1 -0
- package/dist/write/writeDocs.js +423 -0
- package/dist/write/writeDocs.js.map +1 -0
- package/dist/write/writeParts.d.ts +54 -0
- package/dist/write/writeParts.d.ts.map +1 -0
- package/dist/write/writeParts.js +117 -0
- package/dist/write/writeParts.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** #782 · 整页装配(技能侧最后一公里):页头三件 + 区块正文 → 完整 HTML 文档。
|
|
2
|
+
*
|
|
3
|
+
* 与卡路里同名件同族(`packages/skill-calorie/src/shared/docPage.ts`):**文档壳那一圈不住这里**
|
|
4
|
+
* ——doctype/head 槽位/样式与脚本资产拼接/图表位全在公共层 `base-paint/docShell` 的
|
|
5
|
+
* `renderDocShell`;本件只决定三件事:这一页的页头怎么写、正文摆在哪、补哪些技能侧样式。
|
|
6
|
+
*
|
|
7
|
+
* 技能侧补丁=**页面级移动端配方**(`pageUi`:640 断点/44px 触摸区/安全区/窄屏读数卡两格/
|
|
8
|
+
* 表格卡片化)+**页面级形状件**(`pageShapes`:事实条/时间轴条)+**本票两处页内自造件**
|
|
9
|
+
* (`pageParts`:24 小时色带/7×24 热力矩阵)的样式。三样都只在启用时进产物,其余页面逐字节不变。
|
|
10
|
+
*
|
|
11
|
+
* `charts: true` 恒开:本票三张页都可能带图表块(24h 色带),骨架里留 `<!--CHARTS-HELPERS-->` 位;
|
|
12
|
+
* 图表 CSS 由其运行时注入(与公共层同口径)。
|
|
13
|
+
*/
|
|
14
|
+
import { renderDocShell } from 'base-paint/docShell';
|
|
15
|
+
import { renderPageShell } from 'base-paint/blocks';
|
|
16
|
+
import { pageShapeCss, pageUiCss } from 'base-paint';
|
|
17
|
+
import { pagePartsCss } from './pageParts.js';
|
|
18
|
+
const LF = String.fromCharCode(10);
|
|
19
|
+
/** 本页的**宽度口径**(人裁,2026-09-21 复看时圈定):**桌面端正文一律收在中间那一列**。
|
|
20
|
+
*
|
|
21
|
+
* 公共层 `pageUi` ⑧ 条在 ≥1001px 把「真二维数据」那几块(读数卡/数据表/图表块/详情区/列表行)
|
|
22
|
+
* 放满壳宽(`grid-column: 1 / -1`),文字类留在中列 880px —— 那是卡路里那一族的节奏。
|
|
23
|
+
* 作息这三张页人裁的是**单一内容列**:页头、矩阵、分类总览、每日汇总、复制区同宽,
|
|
24
|
+
* 读数卡与每日汇总**不许左右各凸出一截**(用户复看时把「中列那一带」圈成好显示区域,
|
|
25
|
+
* 卡片左右各凸出约 180/270px 被否掉)。
|
|
26
|
+
*
|
|
27
|
+
* 权重与 `pageUi` ⑧ 条**同权**(同为 `.ilife-page-ui` + 两颗类名),靠本段排在 `pageUiCss` 之后取胜;
|
|
28
|
+
* 断点用仓内既有值 **1001**,不新造。**窄屏不受影响**(人复看留言:手机端现样就很好)。 */
|
|
29
|
+
const BODY_SINGLE_COLUMN_CSS = [
|
|
30
|
+
'@media (min-width: 1001px) {',
|
|
31
|
+
' .ilife-page-ui .ilife-block-page-shell-body > * {',
|
|
32
|
+
' grid-column: 2;',
|
|
33
|
+
' }',
|
|
34
|
+
'}',
|
|
35
|
+
].join(LF);
|
|
36
|
+
/** 区块 HTML + 页头 → 完整文档。一页只调一次。 */
|
|
37
|
+
export function assembleDocPage(input) {
|
|
38
|
+
const patch = input.extraCss !== undefined && input.extraCss !== '' ? LF + input.extraCss : '';
|
|
39
|
+
return renderDocShell({
|
|
40
|
+
docTitle: input.head.docTitle,
|
|
41
|
+
bodyHtml: renderPageShell({
|
|
42
|
+
eyebrow: input.head.eyebrow,
|
|
43
|
+
title: input.head.title,
|
|
44
|
+
subtitle: input.head.subtitle,
|
|
45
|
+
content: input.content,
|
|
46
|
+
}),
|
|
47
|
+
extraCss: pageUiCss() + LF + pageShapeCss() + LF + pagePartsCss() + patch + LF + BODY_SINGLE_COLUMN_CSS,
|
|
48
|
+
charts: true,
|
|
49
|
+
pageUi: true,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=docPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docPage.js","sourceRoot":"","sources":["../../src/shared/docPage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,EAAE,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;AAEnC;;;;;;;;;wDASwD;AACxD,MAAM,sBAAsB,GAAG;IAC7B,8BAA8B;IAC9B,qDAAqD;IACrD,qBAAqB;IACrB,KAAK;IACL,GAAG;CACJ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAuBX,kCAAkC;AAClC,MAAM,UAAU,eAAe,CAAC,KAAmB;IACjD,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/F,OAAO,cAAc,CAAC;QACpB,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ;QAC7B,QAAQ,EAAE,eAAe,CAAC;YACxB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO;YAC3B,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK;YACvB,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ;YAC7B,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC;QACF,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,YAAY,EAAE,GAAG,EAAE,GAAG,YAAY,EAAE,GAAG,KAAK,GAAG,EAAE,GAAG,sBAAsB;QACvG,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,IAAI;KACb,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** #785 · 「24h 概览(多日)」的**页型配方**(形状维度的唯一定义地)。
|
|
2
|
+
*
|
|
3
|
+
* 为什么要新立一张:老侧 f11「查日程(多日 24h 概览)」与 f10「查日程(单日)」共用同一个模板
|
|
4
|
+
* (`schedule_list_events.html`),但**两块内容不一样**:单日页给的是事件卡与筛选位(那是 `planPage.ts`),
|
|
5
|
+
* f11 给的是「一天 24 格长什么样」的聚合视图。交接件写着其余家族出页前先把骨架定下来——这里是本票定的那一份。
|
|
6
|
+
*
|
|
7
|
+
* 形状=件序列:
|
|
8
|
+
*
|
|
9
|
+
* 读数卡 → 结论条 → 口径行 → 多日概览表(一行一天)→ 逐日 24 格(段名 + 行列表)→ 复制区
|
|
10
|
+
*
|
|
11
|
+
* 老侧 f11 的两个必现块:**同小时合并**=逐日 24 格里那一格的内容(上游已把同一小时的多条并成一串)、
|
|
12
|
+
* **多日聚合(不含 notes/completion/飞书状态)**=口径行明说丢了哪几样 + 一行一天的概览表。
|
|
13
|
+
*
|
|
14
|
+
* **本件只认形状,不认口径**:分桶怎么分、哪一格写什么、表里报哪几列,都由 `query` 侧算好再进来。
|
|
15
|
+
* 件序列**不随数据多寡变形**:一天也走这一套(表退化成一行、24 格只有一段)。
|
|
16
|
+
*
|
|
17
|
+
* #891 补的**页内定位**(不动件序列):小节=逐日那几段(`周六 09-05` 这种短名)+ 复制区。
|
|
18
|
+
* 按 `./pageNav.ts` 的长页判据(小节数 ≥ `SECTION_TOC_MIN`):**一天那一档判为短页**(逐日 1 段 + 复制区
|
|
19
|
+
* = 2 小节,页首不出目录);**多天(≥2 天)是长页**,页首出页内目录。
|
|
20
|
+
*/
|
|
21
|
+
import { type DataTableColumn, type DataTableRow, type KpiCardInput, type ListRowInput } from 'base-paint/blocks';
|
|
22
|
+
import { type ScheduleCopyAreaInput } from '../render/copyArea.js';
|
|
23
|
+
import { type PageHead } from './docPage.js';
|
|
24
|
+
/** 逐日那一段(一天一段:段名 + 24 格 + 该日的随附读数)。 */
|
|
25
|
+
export interface OverviewDaySection {
|
|
26
|
+
/** 段名(日期与星期 + 已排格数,调用方拼好);**页内目录的条目与它逐字同源**。 */
|
|
27
|
+
readonly title: string;
|
|
28
|
+
/** 这一天 24 格(时:00 / 内容);空桶也占一行,形状不随数据变。 */
|
|
29
|
+
readonly rows: readonly ListRowInput[];
|
|
30
|
+
/** 该日的随附读数(首建与末改时间);不给=这一段不出脚注。 */
|
|
31
|
+
readonly footnote?: string;
|
|
32
|
+
}
|
|
33
|
+
/** 「24h 概览(多日)」一页要的全部东西(8 个字段)。 */
|
|
34
|
+
export interface OverviewPageData {
|
|
35
|
+
readonly head: PageHead;
|
|
36
|
+
readonly kpis: readonly KpiCardInput[];
|
|
37
|
+
readonly conclusion: string;
|
|
38
|
+
/** 口径行:这一页是聚合视图、丢了哪几样(用行文写,不堆并列分隔符)。 */
|
|
39
|
+
readonly caliber: string;
|
|
40
|
+
/** 多日概览表:一行一天(列与行都由调用方给)。 */
|
|
41
|
+
readonly table: {
|
|
42
|
+
readonly columns: readonly DataTableColumn[];
|
|
43
|
+
readonly rows: readonly DataTableRow[];
|
|
44
|
+
readonly caption?: string;
|
|
45
|
+
};
|
|
46
|
+
/** 逐日 24 格:一天一段,顺序即调用方给的顺序。 */
|
|
47
|
+
readonly days: readonly OverviewDaySection[];
|
|
48
|
+
readonly copy: ScheduleCopyAreaInput;
|
|
49
|
+
}
|
|
50
|
+
/** 出「24h 概览(多日)」整页。 */
|
|
51
|
+
export declare function renderOverviewPage(data: OverviewPageData): string;
|
|
52
|
+
//# sourceMappingURL=overviewPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overviewPage.d.ts","sourceRoot":"","sources":["../../src/shared/overviewPage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAEL,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAC9E,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAoB,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG9D,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,SAAS,YAAY,EAAE,CAAC;IACvC,mCAAmC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,mCAAmC;AACnC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,YAAY,EAAE,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wCAAwC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,6BAA6B;IAC7B,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;QAC7C,QAAQ,CAAC,IAAI,EAAE,SAAS,YAAY,EAAE,CAAC;QACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC7C,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;CACtC;AAED,uBAAuB;AACvB,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAwBjE"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/** #785 · 「24h 概览(多日)」的**页型配方**(形状维度的唯一定义地)。
|
|
2
|
+
*
|
|
3
|
+
* 为什么要新立一张:老侧 f11「查日程(多日 24h 概览)」与 f10「查日程(单日)」共用同一个模板
|
|
4
|
+
* (`schedule_list_events.html`),但**两块内容不一样**:单日页给的是事件卡与筛选位(那是 `planPage.ts`),
|
|
5
|
+
* f11 给的是「一天 24 格长什么样」的聚合视图。交接件写着其余家族出页前先把骨架定下来——这里是本票定的那一份。
|
|
6
|
+
*
|
|
7
|
+
* 形状=件序列:
|
|
8
|
+
*
|
|
9
|
+
* 读数卡 → 结论条 → 口径行 → 多日概览表(一行一天)→ 逐日 24 格(段名 + 行列表)→ 复制区
|
|
10
|
+
*
|
|
11
|
+
* 老侧 f11 的两个必现块:**同小时合并**=逐日 24 格里那一格的内容(上游已把同一小时的多条并成一串)、
|
|
12
|
+
* **多日聚合(不含 notes/completion/飞书状态)**=口径行明说丢了哪几样 + 一行一天的概览表。
|
|
13
|
+
*
|
|
14
|
+
* **本件只认形状,不认口径**:分桶怎么分、哪一格写什么、表里报哪几列,都由 `query` 侧算好再进来。
|
|
15
|
+
* 件序列**不随数据多寡变形**:一天也走这一套(表退化成一行、24 格只有一段)。
|
|
16
|
+
*
|
|
17
|
+
* #891 补的**页内定位**(不动件序列):小节=逐日那几段(`周六 09-05` 这种短名)+ 复制区。
|
|
18
|
+
* 按 `./pageNav.ts` 的长页判据(小节数 ≥ `SECTION_TOC_MIN`):**一天那一档判为短页**(逐日 1 段 + 复制区
|
|
19
|
+
* = 2 小节,页首不出目录);**多天(≥2 天)是长页**,页首出页内目录。
|
|
20
|
+
*/
|
|
21
|
+
import { renderCaliberLine, renderConclusionBar, renderDataTable, renderKpiGrid, renderListRows, } from 'base-paint/blocks';
|
|
22
|
+
import { scheduleCopyArea } from '../render/copyArea.js';
|
|
23
|
+
import { assembleDocPage } from './docPage.js';
|
|
24
|
+
import { pageSections } from './pageNav.js';
|
|
25
|
+
/** 出「24h 概览(多日)」整页。 */
|
|
26
|
+
export function renderOverviewPage(data) {
|
|
27
|
+
const { toc, body } = pageSections([
|
|
28
|
+
{ html: renderKpiGrid(data.kpis) },
|
|
29
|
+
{ html: renderConclusionBar(data.conclusion) },
|
|
30
|
+
{ html: renderCaliberLine(data.caliber) },
|
|
31
|
+
{ html: renderDataTable({
|
|
32
|
+
columns: data.table.columns,
|
|
33
|
+
rows: data.table.rows,
|
|
34
|
+
...(data.table.caption === undefined ? {} : { caption: data.table.caption }),
|
|
35
|
+
}) },
|
|
36
|
+
...data.days.map((day) => ({
|
|
37
|
+
navText: day.title,
|
|
38
|
+
html: '<h2 class="heat-title">' + escText(day.title) + '</h2>'
|
|
39
|
+
+ renderListRows({ items: day.rows, emptyText: '这一天没有安排' })
|
|
40
|
+
+ (day.footnote === undefined || day.footnote === '' ? '' : renderCaliberLine(day.footnote)),
|
|
41
|
+
})),
|
|
42
|
+
{ navText: '复制与留档', html: scheduleCopyArea({
|
|
43
|
+
title: '复制与留档',
|
|
44
|
+
dataActionId: 'ilife-sch-overview-copy-data',
|
|
45
|
+
logActionId: 'ilife-sch-overview-copy-log',
|
|
46
|
+
...data.copy,
|
|
47
|
+
}) },
|
|
48
|
+
]);
|
|
49
|
+
return assembleDocPage({ head: data.head, content: toc + body });
|
|
50
|
+
}
|
|
51
|
+
/** 五字符转义(与公共层同口径;本件只为段名用一次,与 `dayPage.ts` 那一处同法)。 */
|
|
52
|
+
function escText(value) {
|
|
53
|
+
return value.replace(/[&<>"']/g, (ch) => {
|
|
54
|
+
if (ch === '&')
|
|
55
|
+
return '&';
|
|
56
|
+
if (ch === '<')
|
|
57
|
+
return '<';
|
|
58
|
+
if (ch === '>')
|
|
59
|
+
return '>';
|
|
60
|
+
if (ch === '"')
|
|
61
|
+
return '"';
|
|
62
|
+
return ''';
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=overviewPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overviewPage.js","sourceRoot":"","sources":["../../src/shared/overviewPage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EACL,iBAAiB,EAAE,mBAAmB,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,GAEvF,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAA8B,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,eAAe,EAAiB,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AA8B5C,uBAAuB;AACvB,MAAM,UAAU,kBAAkB,CAAC,IAAsB;IACvD,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC;QACjC,EAAE,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QAClC,EAAE,IAAI,EAAE,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;QAC9C,EAAE,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;QACzC,EAAE,IAAI,EAAE,eAAe,CAAC;gBACtB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO;gBAC3B,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;gBACrB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;aAC7E,CAAC,EAAE;QACJ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACzB,OAAO,EAAE,GAAG,CAAC,KAAK;YAClB,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,OAAO;kBAC1D,cAAc,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;kBACzD,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,GAAG,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;SAC/F,CAAC,CAAC;QACH,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,gBAAgB,CAAC;gBACzC,KAAK,EAAE,OAAO;gBACd,YAAY,EAAE,8BAA8B;gBAC5C,WAAW,EAAE,6BAA6B;gBAC1C,GAAG,IAAI,CAAC,IAAI;aACb,CAAC,EAAE;KACL,CAAC,CAAC;IACH,OAAO,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,qDAAqD;AACrD,SAAS,OAAO,CAAC,KAAa;IAC5B,OAAO,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE;QACtC,IAAI,EAAE,KAAK,GAAG;YAAE,OAAO,OAAO,CAAC;QAC/B,IAAI,EAAE,KAAK,GAAG;YAAE,OAAO,MAAM,CAAC;QAC9B,IAAI,EAAE,KAAK,GAAG;YAAE,OAAO,MAAM,CAAC;QAC9B,IAAI,EAAE,KAAK,GAAG;YAAE,OAAO,QAAQ,CAAC;QAChC,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** 长页判据:小节数 ≥ 本值(3)才出页内目录。改这里就是改全部页的长短分账。 */
|
|
2
|
+
export declare const SECTION_TOC_MIN = 3;
|
|
3
|
+
/** 一个页内元素(页型件按件序列摆好的**一段**或**一块**)。 */
|
|
4
|
+
export interface PageSection {
|
|
5
|
+
/** **这一段的段名**(页内目录的条目文本)。不给=这一块不是小节:原样透传、不包锚点、不进目录。 */
|
|
6
|
+
readonly navText?: string;
|
|
7
|
+
/** 这一段已渲染好的区块 HTML(受信:全部来自公共层区块件;段名那颗 `<h2>` 含在里头)。 */
|
|
8
|
+
readonly html: string;
|
|
9
|
+
}
|
|
10
|
+
export interface PageNavigation {
|
|
11
|
+
/** 页内目录块(短页=空串,页首不留空块)。摆在页壳正文的最前。 */
|
|
12
|
+
readonly toc: string;
|
|
13
|
+
/** 正文:有 `navText` 的那几段各包一层 `<section id="sec-N">`,其余原样透传。 */
|
|
14
|
+
readonly body: string;
|
|
15
|
+
}
|
|
16
|
+
/** 逐段拼正文 + 从**同一份清单**派生页内目录(条目与锚点只在本函数里写一次,不会走散)。
|
|
17
|
+
*
|
|
18
|
+
* · 空段(`html === ''`)整段丢掉,与各页原来的 `.filter((seg) => seg !== '')` 同一条口径:
|
|
19
|
+
* 「没内容不留空块」,也不占一个目录条目;
|
|
20
|
+
* · 锚点 id 按**入目录的先后**编号(`sec-1`、`sec-2`…):同一页内唯一、与页型件的件序列同序;
|
|
21
|
+
* · 目录条目数 < `SECTION_TOC_MIN` ⇒ 返回空目录(短页)。
|
|
22
|
+
*/
|
|
23
|
+
export declare function pageSections(sections: readonly PageSection[]): PageNavigation;
|
|
24
|
+
//# sourceMappingURL=pageNav.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pageNav.d.ts","sourceRoot":"","sources":["../../src/shared/pageNav.ts"],"names":[],"mappings":"AAyCA,6CAA6C;AAC7C,eAAO,MAAM,eAAe,IAAI,CAAC;AAEjC,uCAAuC;AACvC,MAAM,WAAW,WAAW;IAC1B,uDAAuD;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,GAAG,cAAc,CAe7E"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/** #891 · **页内定位**(页首页内目录 + 各小节锚点):判据与装配的唯一定义地。
|
|
2
|
+
*
|
|
3
|
+
* 为什么要有这一件(四条出处,逐条对着 `docs/skills/skill-memo-ilife/t849-视觉基准.md` §2):
|
|
4
|
+
* · 「页内定位」那一行:**长页必须有页内目录或锚点**;带标识的区块吃定位避让,锚点跳转不把标题顶到视口外;
|
|
5
|
+
* · 判分引擎(`packages/base-render/scripts/判分.mjs`)的 D5 那条腿:
|
|
6
|
+
* `tocCut = (fact.tocEl > 0 && fact.scrollMargin > 0) ? 0 : D5W.toc`(`D5W.toc = 4`);
|
|
7
|
+
* · 本域 61 件产物改前**一件都没有页内目录**(`tocEl = 0`,见 #891 票面现状表);
|
|
8
|
+
* · 公共层已有现成件:页内目录块走 `renderTocBlock`(`packages/base-render/src/blocks.ts`),
|
|
9
|
+
* 卡路里与备忘录的大型页都在用 —— **本件只接线,不自造控件**。
|
|
10
|
+
*
|
|
11
|
+
* ── 判据(唯一一处,别在每页各写一遍)──────────────────────────────────────────
|
|
12
|
+
* **小节**=页内一颗 `<h2>` 段名所领的那一段(本节 `pageSections` 里给了 `navText` 的每一个元素)。
|
|
13
|
+
* 这条口径与 #891 票面现状表的读数逐字同源(今天总结 3 / 复盘本周 9 / 首次使用向导 7,
|
|
14
|
+
* 三处都是「页内 `<h2>` 数」)。
|
|
15
|
+
* **长页**=小节数 ≥ `SECTION_TOC_MIN`(3)⇒ 页首出页内目录。
|
|
16
|
+
* **短页**=小节数 ≤ 2 ⇒ 可以不出目录(`tocEl` 保持 0、D5 那条腿照旧扣 4)——
|
|
17
|
+
* 哪几页被谁判为短页,写在**页型件自己的件头**(例:`shared/planPage.ts` 的「查日程」恒 2 小节)。
|
|
18
|
+
*
|
|
19
|
+
* ── 目录项文本取什么(一处口径,理由写在这里)────────────────────────────────────
|
|
20
|
+
* **目录项文本=这一节的段名,逐字**。唯一一处例外是「段名本身就是一句带读数的事实句」:
|
|
21
|
+
* 作息详情页每条记录的段名是 `记录号 919:2026-09-15 00:00 至 06:30 睡眠`,它的目录项收成
|
|
22
|
+
* `记录号 919`(读数留在大段名上)。
|
|
23
|
+
* 为什么这一处要收:事实列读数器(`docs/skills/skill-schedule/t792-facts.mjs`)的 `dupFacts` 那条
|
|
24
|
+
* 启发式把「**同一句事实在页里出现 >1 次**」算作「同一段事实印两遍」(当刻口径:≥14 字、含数字、
|
|
25
|
+
* 并含 `:` 或 `。` 的事实句),再由判分引擎按 H3 每处扣 2 分。目录与段名逐字同字时它会把**导航**
|
|
26
|
+
* 算成重复事实:按日那条详情页一页 17 条记录各算一处(#891 实测:这一类共 +19 处,全部出在
|
|
27
|
+
* 三张详情页上;其余 58 页逐字同字一处不增,因为那些段名都不到 14 字或不含句读)。
|
|
28
|
+
* 这不是判据放宽(小节数、长页判据、D5 那条腿一字未动),是「导航文本与长段名分开取」这一条
|
|
29
|
+
* 版面决定 —— 卡路里域同一条口径(`scene01-验收墙/看今日主页` 的目录写「今日速览」,
|
|
30
|
+
* 同一节的 `<h2>` 写「🔥 今日速览」)。
|
|
31
|
+
*
|
|
32
|
+
* ── 锚点 id 落在哪 ──────────────────────────────────────────────────────────
|
|
33
|
+
* 落在这一节的 `<section>` 外壳上,不落在 `<h2>` 上:公共层页面配方的定位避让
|
|
34
|
+
* (`pageUiCss()` ③)只认页壳正文的**直接子件**上的 `id`
|
|
35
|
+
* (`.ilife-page-ui .ilife-block-page-shell-body > *[id] { scroll-margin-top: 20px }`),
|
|
36
|
+
* 而 `<h2>` 有的住在图表块/读数卡/复制区**内部**、不是直接子件,吃不到那一条。
|
|
37
|
+
* 故本节把「带 `navText` 的那一段」包一层 `<section id="sec-N">`——**避让仍走公共层那一份,
|
|
38
|
+
* 本件一行 CSS 都不写**。
|
|
39
|
+
*/
|
|
40
|
+
import { renderTocBlock } from 'base-paint/blocks';
|
|
41
|
+
/** 长页判据:小节数 ≥ 本值(3)才出页内目录。改这里就是改全部页的长短分账。 */
|
|
42
|
+
export const SECTION_TOC_MIN = 3;
|
|
43
|
+
/** 逐段拼正文 + 从**同一份清单**派生页内目录(条目与锚点只在本函数里写一次,不会走散)。
|
|
44
|
+
*
|
|
45
|
+
* · 空段(`html === ''`)整段丢掉,与各页原来的 `.filter((seg) => seg !== '')` 同一条口径:
|
|
46
|
+
* 「没内容不留空块」,也不占一个目录条目;
|
|
47
|
+
* · 锚点 id 按**入目录的先后**编号(`sec-1`、`sec-2`…):同一页内唯一、与页型件的件序列同序;
|
|
48
|
+
* · 目录条目数 < `SECTION_TOC_MIN` ⇒ 返回空目录(短页)。
|
|
49
|
+
*/
|
|
50
|
+
export function pageSections(sections) {
|
|
51
|
+
const items = [];
|
|
52
|
+
const parts = [];
|
|
53
|
+
for (const section of sections) {
|
|
54
|
+
if (section.html === '')
|
|
55
|
+
continue;
|
|
56
|
+
const navText = section.navText;
|
|
57
|
+
if (navText === undefined || navText === '') {
|
|
58
|
+
parts.push(section.html);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const id = 'sec-' + String(items.length + 1);
|
|
62
|
+
items.push({ id, text: navText });
|
|
63
|
+
parts.push('<section id="' + id + '">' + section.html + '</section>');
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
toc: items.length >= SECTION_TOC_MIN ? renderTocBlock({ items }) : '',
|
|
67
|
+
body: parts.join(''),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=pageNav.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pageNav.js","sourceRoot":"","sources":["../../src/shared/pageNav.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,6CAA6C;AAC7C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC;AAiBjC;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgC;IAC3D,MAAM,KAAK,GAAmC,EAAE,CAAC;IACjD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,IAAI,KAAK,EAAE;YAAE,SAAS;QAClC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAChC,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QACpF,MAAM,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,eAAe,GAAG,EAAE,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC,CAAC;IACxE,CAAC;IACD,OAAO;QACL,GAAG,EAAE,KAAK,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;QACrE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;KACrB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** 一格=某小时里「覆盖分钟最多」的那枚键(没有记录的小时=`key: null`)。 */
|
|
2
|
+
export interface HourCell {
|
|
3
|
+
readonly key: string | null;
|
|
4
|
+
readonly minutes: number;
|
|
5
|
+
}
|
|
6
|
+
/** 热力矩阵的一行=一天;`cells` 恒 24 格(无记录的小时也占格,形状不随数据变);
|
|
7
|
+
* `sum` 是**已给人看的样子**的当日合计(口径住调用方,本件不格式化数字)。 */
|
|
8
|
+
export interface HeatRow {
|
|
9
|
+
readonly label: string;
|
|
10
|
+
readonly date: string;
|
|
11
|
+
readonly cells: readonly HourCell[];
|
|
12
|
+
readonly sum: string;
|
|
13
|
+
}
|
|
14
|
+
/** 键 → 色的**唯一算式**(位次定色)。表外的键走 `--fg3`(灰),不落回某个真分类的颜色上。
|
|
15
|
+
* 色带、热力矩阵、分类分布行三处都调它——一处改,三处一起改(#782 首版曾在分布行上漏传色,
|
|
16
|
+
* 七条全蓝,见证据件第七节)。 */
|
|
17
|
+
export declare function categoryColor(key: string | null, order: readonly string[]): string;
|
|
18
|
+
/** 一天里的时间片段 → 24 格:逐格累加覆盖分钟,取该格里最多的一枚键。
|
|
19
|
+
* `start`/`end` 是当天的分钟数(0–1440);跨零点由调用方拆成两段(本件不做跨天)。 */
|
|
20
|
+
export declare function hourCellsOf(spans: readonly {
|
|
21
|
+
readonly start: number;
|
|
22
|
+
readonly end: number;
|
|
23
|
+
readonly key: string;
|
|
24
|
+
}[]): HourCell[];
|
|
25
|
+
/** ① 24 小时色带:24 根柱子=24 小时,柱高=该小时已记录分钟,柱色=该小时主键。
|
|
26
|
+
* 空数组=空串(与「没内容不留空块」同口径)。 */
|
|
27
|
+
export declare function renderHourBand(cells: readonly HourCell[], opts: {
|
|
28
|
+
readonly order: readonly string[];
|
|
29
|
+
readonly title?: string;
|
|
30
|
+
readonly height?: number;
|
|
31
|
+
}): string;
|
|
32
|
+
/** ② 7×24 热力矩阵:一行一天(行首日期、行中 24 格、可选行尾当日合计),尾行是小时刻度。
|
|
33
|
+
* 图例跟着矩阵走(`legend`,缺省开):格色与图例同源,分开摆迟早走散。
|
|
34
|
+
* `title` 是这一段在页上的名字(不给=不出这一行)。 */
|
|
35
|
+
export declare function renderHeatMatrix(rows: readonly HeatRow[], opts: {
|
|
36
|
+
readonly order: readonly string[];
|
|
37
|
+
readonly id?: string;
|
|
38
|
+
readonly title?: string;
|
|
39
|
+
readonly legend?: boolean;
|
|
40
|
+
readonly withTotal?: boolean;
|
|
41
|
+
readonly dayLabel?: (row: HeatRow) => string;
|
|
42
|
+
}): string;
|
|
43
|
+
/** 两处块件的样式唯一产出者(只对用上它们的页面有作用)。 */
|
|
44
|
+
export declare function pagePartsCss(): string;
|
|
45
|
+
//# sourceMappingURL=pageParts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pageParts.d.ts","sourceRoot":"","sources":["../../src/shared/pageParts.ts"],"names":[],"mappings":"AAiBA,gDAAgD;AAChD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;gDACgD;AAChD,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAeD;;qBAEqB;AACrB,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAIlF;AAED;yDACyD;AACzD,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,GACvF,QAAQ,EAAE,CAkBZ;AAED;6BAC6B;AAC7B,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,QAAQ,EAAE,EAC1B,IAAI,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7F,MAAM,CAsBR;AAED;;oCAEoC;AACpC,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,SAAS,OAAO,EAAE,EACxB,IAAI,EAAE;IACJ,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;CAC9C,GACA,MAAM,CA2BR;AAED,kCAAkC;AAClC,wBAAgB,YAAY,IAAI,MAAM,CAyBrC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/** #782 · 页面级块件两处:**24 小时色带**与 **7×24 热力矩阵**(含图例与小时刻度)。
|
|
2
|
+
*
|
|
3
|
+
* 为什么住共用位(写得出哪两个在用):`query` 的「今天总结」与「周视图」、`plan` 的「查日程」
|
|
4
|
+
* 都要这两件;公共层给不出——`charts` 八种里没有热力矩阵,24h 色带在公共层只有「通用柱状图」这一档
|
|
5
|
+
* (本件就是把柱状图按小时格染色的那一层)。
|
|
6
|
+
*
|
|
7
|
+
* **只认形状,不认领域**:格子键 `key` 是一枚不透明字符串,谁在上游把它算成一级分类由调用方定
|
|
8
|
+
* (口径住各能力目录)——所以本件不引 `policy`,也不会把领域名带进共用位。
|
|
9
|
+
* **配色只有一条规则**:第 i 个键取 `CHART_PALETTE[i]`,顺序由调用方给的 `order` 定(那 8 个一级
|
|
10
|
+
* 分类的权威顺序在 `policy`,调用方照抄即可);`order` 里没有的键一律走灰,不新造色值。
|
|
11
|
+
*
|
|
12
|
+
* 样式与产出器同文件(与公共层 `pageShapes.ts` 同法:形状件的样式不另立文件);断点只用仓内
|
|
13
|
+
* 既有值 **820**,不新造。
|
|
14
|
+
*/
|
|
15
|
+
import { CHART_PALETTE } from 'base-paint';
|
|
16
|
+
import { renderChartBlock } from 'base-paint/blocks';
|
|
17
|
+
const LF = String.fromCharCode(10);
|
|
18
|
+
/** 五字符转义表(与公共层 `blocks.ts` 同口径;本件不引区块层内部件)。 */
|
|
19
|
+
function esc(value) {
|
|
20
|
+
return value.replace(/[&<>"']/g, (ch) => {
|
|
21
|
+
if (ch === '&')
|
|
22
|
+
return '&';
|
|
23
|
+
if (ch === '<')
|
|
24
|
+
return '<';
|
|
25
|
+
if (ch === '>')
|
|
26
|
+
return '>';
|
|
27
|
+
if (ch === '"')
|
|
28
|
+
return '"';
|
|
29
|
+
return ''';
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/** 键 → 色的**唯一算式**(位次定色)。表外的键走 `--fg3`(灰),不落回某个真分类的颜色上。
|
|
33
|
+
* 色带、热力矩阵、分类分布行三处都调它——一处改,三处一起改(#782 首版曾在分布行上漏传色,
|
|
34
|
+
* 七条全蓝,见证据件第七节)。 */
|
|
35
|
+
export function categoryColor(key, order) {
|
|
36
|
+
if (key === null)
|
|
37
|
+
return 'var(--soft)';
|
|
38
|
+
const at = order.indexOf(key);
|
|
39
|
+
return at >= 0 ? CHART_PALETTE[at % CHART_PALETTE.length] : 'var(--fg3)';
|
|
40
|
+
}
|
|
41
|
+
/** 一天里的时间片段 → 24 格:逐格累加覆盖分钟,取该格里最多的一枚键。
|
|
42
|
+
* `start`/`end` 是当天的分钟数(0–1440);跨零点由调用方拆成两段(本件不做跨天)。 */
|
|
43
|
+
export function hourCellsOf(spans) {
|
|
44
|
+
const buckets = [];
|
|
45
|
+
for (let h = 0; h < 24; h += 1)
|
|
46
|
+
buckets.push({});
|
|
47
|
+
for (const span of spans) {
|
|
48
|
+
if (!(span.end > span.start))
|
|
49
|
+
continue;
|
|
50
|
+
for (let h = Math.floor(span.start / 60); h <= Math.floor((span.end - 1) / 60); h += 1) {
|
|
51
|
+
if (h < 0 || h > 23)
|
|
52
|
+
continue;
|
|
53
|
+
const covered = Math.min((h + 1) * 60, span.end) - Math.max(h * 60, span.start);
|
|
54
|
+
if (covered > 0)
|
|
55
|
+
buckets[h][span.key] = (buckets[h][span.key] ?? 0) + covered;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return buckets.map((bucket) => {
|
|
59
|
+
const keys = Object.keys(bucket);
|
|
60
|
+
if (keys.length === 0)
|
|
61
|
+
return { key: null, minutes: 0 };
|
|
62
|
+
let winner = keys[0];
|
|
63
|
+
for (const k of keys)
|
|
64
|
+
if (bucket[k] > bucket[winner])
|
|
65
|
+
winner = k;
|
|
66
|
+
return { key: winner, minutes: bucket[winner] };
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/** ① 24 小时色带:24 根柱子=24 小时,柱高=该小时已记录分钟,柱色=该小时主键。
|
|
70
|
+
* 空数组=空串(与「没内容不留空块」同口径)。 */
|
|
71
|
+
export function renderHourBand(cells, opts) {
|
|
72
|
+
if (cells.length === 0)
|
|
73
|
+
return '';
|
|
74
|
+
return renderChartBlock({
|
|
75
|
+
kind: 'bar',
|
|
76
|
+
...(opts.title === undefined ? {} : { title: opts.title }),
|
|
77
|
+
input: {
|
|
78
|
+
items: cells.map((cell, h) => ({
|
|
79
|
+
label: String(h).padStart(2, '0'),
|
|
80
|
+
value: cell.minutes,
|
|
81
|
+
color: categoryColor(cell.key, opts.order),
|
|
82
|
+
})),
|
|
83
|
+
options: {
|
|
84
|
+
height: opts.height ?? 120,
|
|
85
|
+
yMax: 60,
|
|
86
|
+
singleColor: false,
|
|
87
|
+
showValues: false,
|
|
88
|
+
grid: false,
|
|
89
|
+
labels: 'select',
|
|
90
|
+
compact: true,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/** ② 7×24 热力矩阵:一行一天(行首日期、行中 24 格、可选行尾当日合计),尾行是小时刻度。
|
|
96
|
+
* 图例跟着矩阵走(`legend`,缺省开):格色与图例同源,分开摆迟早走散。
|
|
97
|
+
* `title` 是这一段在页上的名字(不给=不出这一行)。 */
|
|
98
|
+
export function renderHeatMatrix(rows, opts) {
|
|
99
|
+
if (rows.length === 0)
|
|
100
|
+
return '';
|
|
101
|
+
const withTotal = opts.withTotal === true;
|
|
102
|
+
const rowClass = 'heat-row' + (withTotal ? ' heat-row-total' : '');
|
|
103
|
+
const head = rows.map((row) => {
|
|
104
|
+
const label = opts.dayLabel === undefined ? row.label + ' ' + row.date.slice(5) : opts.dayLabel(row);
|
|
105
|
+
const cells = row.cells.map((cell, h) => '<span class="heat-cell" style="background:'
|
|
106
|
+
+ categoryColor(cell.key, opts.order) + '" title="' + esc(row.date + ' ' + String(h).padStart(2, '0')
|
|
107
|
+
+ ':00 · ' + (cell.key ?? '无记录') + ' · ' + cell.minutes + ' 分钟') + '"></span>').join('');
|
|
108
|
+
return '<div class="' + rowClass + '">'
|
|
109
|
+
+ '<div class="heat-day">' + esc(label) + '</div>'
|
|
110
|
+
+ '<div class="heat-cells">' + cells + '</div>'
|
|
111
|
+
+ (withTotal ? '<div class="heat-sum">' + esc(row.sum) + '</div>' : '')
|
|
112
|
+
+ '</div>';
|
|
113
|
+
}).join('');
|
|
114
|
+
const ticks = [[1, '00:00', 'left'], [7, '06:00', 'left'], [13, '12:00', 'left'],
|
|
115
|
+
[19, '18:00', 'left'], [21, '24:00', 'right']]
|
|
116
|
+
.map(([col, text, align]) => '<span style="grid-column:' + col + '/span 4;text-align:' + align + '">' + text + '</span>')
|
|
117
|
+
.join('');
|
|
118
|
+
const legend = opts.legend === false ? '' : '<div class="heat-legend">' + opts.order.map((key) => '<span><i style="background:'
|
|
119
|
+
+ categoryColor(key, opts.order) + '"></i>' + esc(key) + '</span>').join('') + '</div>';
|
|
120
|
+
const title = opts.title === undefined ? '' : '<h2 class="heat-title">' + esc(opts.title) + '</h2>';
|
|
121
|
+
return title + '<div class="heat"' + (opts.id === undefined ? '' : ' id="' + esc(opts.id) + '"') + '>'
|
|
122
|
+
+ head
|
|
123
|
+
+ '<div class="' + rowClass + '"><div></div><div class="heat-ticks">' + ticks + '</div>'
|
|
124
|
+
+ (withTotal ? '<div></div>' : '') + '</div>'
|
|
125
|
+
+ '</div>' + legend;
|
|
126
|
+
}
|
|
127
|
+
/** 两处块件的样式唯一产出者(只对用上它们的页面有作用)。 */
|
|
128
|
+
export function pagePartsCss() {
|
|
129
|
+
return [
|
|
130
|
+
'/* #782 页内自造件·7×24 热力矩阵(断点只用仓内既有值 820) */',
|
|
131
|
+
'.heat-title { margin: 0 0 8px; font-size: 15px; font-weight: 600; color: var(--fg); }',
|
|
132
|
+
'.heat { display: flex; flex-direction: column; gap: 5px; margin: 16px 0 8px; }',
|
|
133
|
+
'.heat-row { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: 10px; align-items: center; }',
|
|
134
|
+
'.heat-day { color: var(--fg2); font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }',
|
|
135
|
+
'.heat-cells { display: grid; grid-template-columns: repeat(24, minmax(0, 1fr)); gap: 2px; }',
|
|
136
|
+
'.heat-cell { display: block; height: 18px; border-radius: 4px; background: var(--soft); }',
|
|
137
|
+
// #893 小时刻度 11→12:探针量全部非 SVG 可见文本,刻度进 min,留 11 会继续扣 5 分。
|
|
138
|
+
'.heat-ticks { display: grid; grid-template-columns: repeat(24, minmax(0, 1fr)); gap: 2px; color: var(--fg3); font-size: 12px; font-variant-numeric: tabular-nums; }',
|
|
139
|
+
'.heat-ticks span { white-space: nowrap; overflow: hidden; }',
|
|
140
|
+
'.heat-row-total { grid-template-columns: 64px minmax(0, 1fr) 60px; }',
|
|
141
|
+
'.heat-sum { color: var(--fg2); font-size: 12px; text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }',
|
|
142
|
+
'.heat-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 8px 0 0; color: var(--fg2); font-size: 12px; }',
|
|
143
|
+
'.heat-legend span { display: inline-flex; align-items: center; gap: 6px; }',
|
|
144
|
+
'.heat-legend i { display: inline-block; width: 12px; height: 12px; border-radius: 3px; }',
|
|
145
|
+
'@media (max-width: 820px) {',
|
|
146
|
+
' .heat-row { grid-template-columns: 52px minmax(0, 1fr); gap: 8px; }',
|
|
147
|
+
' .heat-row-total { grid-template-columns: 52px minmax(0, 1fr) 50px; }',
|
|
148
|
+
// #893 正文类下限 12px:窄屏不把 heat-day/heat-sum 压到 11,沿用基线 12(留此行防回退)。
|
|
149
|
+
' .heat-cell { height: 15px; border-radius: 3px; }',
|
|
150
|
+
'}',
|
|
151
|
+
'@media print { .heat-cell { print-color-adjust: exact; -webkit-print-color-adjust: exact; } }',
|
|
152
|
+
].join(LF);
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=pageParts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pageParts.js","sourceRoot":"","sources":["../../src/shared/pageParts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** #782 · 「查日程」的**页型配方**(形状维度的唯一定义地)。
|
|
2
|
+
*
|
|
3
|
+
* 形状=人裁过的 **A · 覆盖条+事件卡**(票面 [#782](https://github.com/FeatherHunter/ilife/issues/782),
|
|
4
|
+
* 裁决原文 `B A A`,见 `docs/skills/skill-schedule/t782-形状-证据.md` 第六节):
|
|
5
|
+
*
|
|
6
|
+
* 读数卡 → 结论条 → 24 小时覆盖条(置顶)→ 事件卡列表 → 折叠「空档」→ 筛选位 → 复制区
|
|
7
|
+
*
|
|
8
|
+
* 老侧 f10「查日程(单日)」的三个必现块:**24h 时间轴**=覆盖条(置顶,有事件的格子才着色)、
|
|
9
|
+
* **事件卡**=列表行(时间/标题/同步状态)、**筛选位**=参数表单。
|
|
10
|
+
*
|
|
11
|
+
* **本件只认形状,不认口径**:空档怎么算、状态取哪两位,都由 `plan` 侧算好再进来。
|
|
12
|
+
*
|
|
13
|
+
* #786 动过两处(都不动件序列):事件卡那一段收公共层行列表的入参(空列表那句话随查法变)、
|
|
14
|
+
* 筛选位那句说明句改成行文(`、` 是 #516 分隔符门点名的并列符号)。
|
|
15
|
+
*
|
|
16
|
+
* #891 补的**页内定位**(不动件序列):本页**小节恒 2 颗**(`24 小时覆盖`/`复制与留档`),
|
|
17
|
+
* 按 `./pageNav.ts` 的长页判据(小节数 ≥ `SECTION_TOC_MIN`)**这一页被判为短页**,页首不出页内目录;
|
|
18
|
+
* 两颗段名照旧各包一层带 `id` 的 `<section>`(锚点仍在,只有目录不出)。
|
|
19
|
+
*/
|
|
20
|
+
import { type KpiCardInput, type ListRowsInput, type ListRowInput, type ParamFieldInput } from 'base-paint/blocks';
|
|
21
|
+
import { type ScheduleCopyAreaInput } from '../render/copyArea.js';
|
|
22
|
+
import { type PageHead } from './docPage.js';
|
|
23
|
+
import { type HourCell } from './pageParts.js';
|
|
24
|
+
/** 「查日程」一页要的全部东西(字段数:`head`/`cells`/`order`/`kpis`/`conclusion`/`events`/
|
|
25
|
+
* `gaps`/`filters`/`copy`)。
|
|
26
|
+
*
|
|
27
|
+
* #786 的一处(只加可选位,不动件序列):`events` 收**公共层行列表的入参**(而不是裸数组)——
|
|
28
|
+
* 空列表那句话随查法变(「这一天没有事件」与「这一天没有标题命中的事件」不是一回事),
|
|
29
|
+
* 那句话是**口径**、住调用方,形状侧只负责把它透传给 `renderListRows`。不给 `emptyText`
|
|
30
|
+
* =#782 那张页的同一句话,产出逐字节同。 */
|
|
31
|
+
export interface PlanPageData {
|
|
32
|
+
readonly head: PageHead;
|
|
33
|
+
/** 24 小时覆盖条的 24 格(没有事件的格子=`key: null`,不着色)。 */
|
|
34
|
+
readonly cells: readonly HourCell[];
|
|
35
|
+
readonly order: readonly string[];
|
|
36
|
+
/** 读数卡(事件数/已排时段/空档/已完成)。 */
|
|
37
|
+
readonly kpis: readonly KpiCardInput[];
|
|
38
|
+
readonly conclusion: string;
|
|
39
|
+
/** 事件卡列表(一行一件)+空列表时那句话(不给=「这一天没有事件」)。 */
|
|
40
|
+
readonly events: ListRowsInput;
|
|
41
|
+
/** 空档列表(收在折叠区里)。 */
|
|
42
|
+
readonly gaps: readonly ListRowInput[];
|
|
43
|
+
/** 筛选位的字段(日期/分类/状态)。 */
|
|
44
|
+
readonly filters: readonly ParamFieldInput[];
|
|
45
|
+
readonly copy: ScheduleCopyAreaInput;
|
|
46
|
+
}
|
|
47
|
+
/** 出「查日程」整页。 */
|
|
48
|
+
export declare function renderPlanPage(data: PlanPageData): string;
|
|
49
|
+
//# sourceMappingURL=planPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planPage.d.ts","sourceRoot":"","sources":["../../src/shared/planPage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAEY,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,eAAe,EAChG,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAoB,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE9D,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/D;;;;;;6BAM6B;AAC7B,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,4BAA4B;IAC5B,QAAQ,CAAC,IAAI,EAAE,SAAS,YAAY,EAAE,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,oBAAoB;IACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,YAAY,EAAE,CAAC;IACvC,wBAAwB;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;CACtC;AAED,gBAAgB;AAChB,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAqBzD"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** #782 · 「查日程」的**页型配方**(形状维度的唯一定义地)。
|
|
2
|
+
*
|
|
3
|
+
* 形状=人裁过的 **A · 覆盖条+事件卡**(票面 [#782](https://github.com/FeatherHunter/ilife/issues/782),
|
|
4
|
+
* 裁决原文 `B A A`,见 `docs/skills/skill-schedule/t782-形状-证据.md` 第六节):
|
|
5
|
+
*
|
|
6
|
+
* 读数卡 → 结论条 → 24 小时覆盖条(置顶)→ 事件卡列表 → 折叠「空档」→ 筛选位 → 复制区
|
|
7
|
+
*
|
|
8
|
+
* 老侧 f10「查日程(单日)」的三个必现块:**24h 时间轴**=覆盖条(置顶,有事件的格子才着色)、
|
|
9
|
+
* **事件卡**=列表行(时间/标题/同步状态)、**筛选位**=参数表单。
|
|
10
|
+
*
|
|
11
|
+
* **本件只认形状,不认口径**:空档怎么算、状态取哪两位,都由 `plan` 侧算好再进来。
|
|
12
|
+
*
|
|
13
|
+
* #786 动过两处(都不动件序列):事件卡那一段收公共层行列表的入参(空列表那句话随查法变)、
|
|
14
|
+
* 筛选位那句说明句改成行文(`、` 是 #516 分隔符门点名的并列符号)。
|
|
15
|
+
*
|
|
16
|
+
* #891 补的**页内定位**(不动件序列):本页**小节恒 2 颗**(`24 小时覆盖`/`复制与留档`),
|
|
17
|
+
* 按 `./pageNav.ts` 的长页判据(小节数 ≥ `SECTION_TOC_MIN`)**这一页被判为短页**,页首不出页内目录;
|
|
18
|
+
* 两颗段名照旧各包一层带 `id` 的 `<section>`(锚点仍在,只有目录不出)。
|
|
19
|
+
*/
|
|
20
|
+
import { renderConclusionBar, renderDisclosure, renderKpiGrid, renderListRows, renderParamForm, } from 'base-paint/blocks';
|
|
21
|
+
import { scheduleCopyArea } from '../render/copyArea.js';
|
|
22
|
+
import { assembleDocPage } from './docPage.js';
|
|
23
|
+
import { pageSections } from './pageNav.js';
|
|
24
|
+
import { renderHourBand } from './pageParts.js';
|
|
25
|
+
/** 出「查日程」整页。 */
|
|
26
|
+
export function renderPlanPage(data) {
|
|
27
|
+
const { toc, body } = pageSections([
|
|
28
|
+
{ html: renderKpiGrid(data.kpis) },
|
|
29
|
+
{ html: renderConclusionBar(data.conclusion) },
|
|
30
|
+
// 段名是「24 小时覆盖」(图表块自己那颗 `<h2>`);目录项逐字用它。
|
|
31
|
+
{ navText: '24 小时覆盖', html: renderHourBand(data.cells, { order: data.order, title: '24 小时覆盖', height: 120 }) },
|
|
32
|
+
{ html: renderListRows(data.events) },
|
|
33
|
+
{ html: renderDisclosure({ title: data.gaps.length > 0 ? '空档' : '空档(无)', contentHtml: renderListRows({ items: data.gaps, emptyText: '整天都被事件占满' }) }) },
|
|
34
|
+
// 说明句不堆并列分隔符(`、` 是 #516 分隔符门点名的并列符号之一):写成一句行文。
|
|
35
|
+
{ html: renderParamForm({ description: '换一个日期,或者按分类与状态再收一收。', fields: data.filters }) },
|
|
36
|
+
{
|
|
37
|
+
navText: '复制与留档',
|
|
38
|
+
html: scheduleCopyArea({
|
|
39
|
+
title: '复制与留档',
|
|
40
|
+
dataActionId: 'ilife-sch-plan-copy-data',
|
|
41
|
+
logActionId: 'ilife-sch-plan-copy-log',
|
|
42
|
+
...data.copy,
|
|
43
|
+
}),
|
|
44
|
+
},
|
|
45
|
+
]);
|
|
46
|
+
return assembleDocPage({ head: data.head, content: toc + body });
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=planPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planPage.js","sourceRoot":"","sources":["../../src/shared/planPage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,mBAAmB,EAAE,gBAAgB,EAAE,aAAa,EAAE,cAAc,EACpE,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAA8B,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,eAAe,EAAiB,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AA0B/D,gBAAgB;AAChB,MAAM,UAAU,cAAc,CAAC,IAAkB;IAC/C,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC;QACjC,EAAE,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QAClC,EAAE,IAAI,EAAE,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;QAC9C,wCAAwC;QACxC,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE;QAC9G,EAAE,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QACrC,EAAE,IAAI,EAAE,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,EAAE;QACtJ,+CAA+C;QAC/C,EAAE,IAAI,EAAE,eAAe,CAAC,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;QACvF;YACE,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,gBAAgB,CAAC;gBACrB,KAAK,EAAE,OAAO;gBACd,YAAY,EAAE,0BAA0B;gBACxC,WAAW,EAAE,yBAAyB;gBACtC,GAAG,IAAI,CAAC,IAAI;aACb,CAAC;SACH;KACF,CAAC,CAAC;IACH,OAAO,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC;AACnE,CAAC"}
|