dsh-group-status 0.2.1 → 0.3.0
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/CHANGELOG.md +53 -0
- package/README.en.md +36 -18
- package/README.md +39 -19
- package/lib/client.js +659 -300
- package/lib/client.js.map +1 -1
- package/lib/index.js +22 -9
- package/lib/types/client/WorkspacePicker.d.ts +2 -2
- package/lib/types/client/WorkspacePicker.d.ts.map +1 -1
- package/lib/types/client/badge-labels.d.ts +92 -0
- package/lib/types/client/badge-labels.d.ts.map +1 -0
- package/lib/types/client/badge-labels.js +150 -0
- package/lib/types/client/badge-labels.js.map +1 -0
- package/lib/types/client/badge-settings.d.ts +17 -1
- package/lib/types/client/badge-settings.d.ts.map +1 -1
- package/lib/types/client/badge-settings.js +12 -0
- package/lib/types/client/badge-settings.js.map +1 -1
- package/lib/types/client/facet-store.d.ts +46 -0
- package/lib/types/client/facet-store.d.ts.map +1 -0
- package/lib/types/client/facet-store.js +123 -0
- package/lib/types/client/facet-store.js.map +1 -0
- package/lib/types/client/facet-visibility.d.ts +17 -0
- package/lib/types/client/facet-visibility.d.ts.map +1 -0
- package/lib/types/client/facet-visibility.js +18 -0
- package/lib/types/client/facet-visibility.js.map +1 -0
- package/lib/types/client/facets.d.ts +265 -0
- package/lib/types/client/facets.d.ts.map +1 -0
- package/lib/types/client/facets.js +209 -0
- package/lib/types/client/facets.js.map +1 -0
- package/lib/types/client/group-status.d.ts +43 -47
- package/lib/types/client/group-status.d.ts.map +1 -1
- package/lib/types/client/group-status.js +76 -90
- package/lib/types/client/group-status.js.map +1 -1
- package/lib/types/client/index.d.ts +25 -0
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +28 -0
- package/lib/types/client/index.js.map +1 -1
- package/lib/types/client/legacy/bridge.d.ts +30 -0
- package/lib/types/client/legacy/bridge.d.ts.map +1 -0
- package/lib/types/client/legacy/bridge.js +58 -0
- package/lib/types/client/legacy/bridge.js.map +1 -0
- package/lib/types/client/legacy/register-legacy-facets.d.ts +14 -0
- package/lib/types/client/legacy/register-legacy-facets.d.ts.map +1 -0
- package/lib/types/client/legacy/register-legacy-facets.js +77 -0
- package/lib/types/client/legacy/register-legacy-facets.js.map +1 -0
- package/lib/types/client/legacy/schedule.d.ts +49 -0
- package/lib/types/client/legacy/schedule.d.ts.map +1 -0
- package/lib/types/client/legacy/schedule.js +73 -0
- package/lib/types/client/legacy/schedule.js.map +1 -0
- package/lib/types/client/legacy/store-source.d.ts +78 -0
- package/lib/types/client/legacy/store-source.d.ts.map +1 -0
- package/lib/types/client/legacy/store-source.js +82 -0
- package/lib/types/client/legacy/store-source.js.map +1 -0
- package/lib/types/client/legacy/waiting-review.d.ts +85 -0
- package/lib/types/client/legacy/waiting-review.d.ts.map +1 -0
- package/lib/types/client/legacy/waiting-review.js +179 -0
- package/lib/types/client/legacy/waiting-review.js.map +1 -0
- package/lib/types/client/locales.d.ts +2 -4
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/locales.js +5 -7
- package/lib/types/client/locales.js.map +1 -1
- package/lib/types/client/rows/GroupBadge.d.ts +18 -25
- package/lib/types/client/rows/GroupBadge.d.ts.map +1 -1
- package/lib/types/client/rows/GroupBadge.js +45 -106
- package/lib/types/client/rows/GroupBadge.js.map +1 -1
- package/lib/types/client/rows/Rows.d.ts +8 -4
- package/lib/types/client/rows/Rows.d.ts.map +1 -1
- package/lib/types/client/rows/Rows.js +6 -6
- package/lib/types/client/rows/Rows.js.map +1 -1
- package/lib/types/client/rows/WorkspaceBrowser.d.ts +1 -1
- package/lib/types/client/rows/WorkspaceBrowser.d.ts.map +1 -1
- package/lib/types/client/rows/WorkspaceBrowser.js +30 -23
- package/lib/types/client/rows/WorkspaceBrowser.js.map +1 -1
- package/lib/types/client/session-actions/ArchiveSession.d.ts +3 -3
- package/lib/types/client/session-actions/ArchiveSession.d.ts.map +1 -1
- package/lib/types/client/session-actions/ForkSession.d.ts +1 -1
- package/lib/types/client/session-actions/ForkSession.d.ts.map +1 -1
- package/lib/types/client/session-actions/PinSession.d.ts +2 -2
- package/lib/types/client/session-actions/PinSession.d.ts.map +1 -1
- package/lib/types/client/session-actions/RenameSession.d.ts +2 -2
- package/lib/types/client/session-actions/RenameSession.d.ts.map +1 -1
- package/lib/types/client/session-actions/RowActionToast.d.ts +1 -1
- package/lib/types/client/session-actions/RowActionToast.d.ts.map +1 -1
- package/lib/types/client/tree.d.ts +0 -2
- package/lib/types/client/tree.d.ts.map +1 -1
- package/lib/types/client/tree.js +0 -2
- package/lib/types/client/tree.js.map +1 -1
- package/lib/types/index.d.ts +56 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +1 -1
- package/lib/types/index.js.map +1 -1
- package/package.json +1 -5
- package/lib/tsconfig.tsbuildinfo +0 -1
package/lib/index.js
CHANGED
|
@@ -23,16 +23,29 @@ const name = "dsh-group-status";
|
|
|
23
23
|
* 并把保存结果回灌到条目配置。浏览器半通过 `configForms.get('dsh-group-status')`
|
|
24
24
|
* 读取同一份文档,改完即时生效、无需刷新。
|
|
25
25
|
*
|
|
26
|
-
*
|
|
26
|
+
* 全部可选且带默认值:未配置时即开箱即用(所有来源默认显示)。
|
|
27
27
|
*/
|
|
28
|
-
const Config = Schema.object({
|
|
29
|
-
/**
|
|
30
|
-
* 折叠分组徽标是否显示「已完成」绿点。
|
|
31
|
-
*
|
|
32
|
-
* 关闭后 `done` 既不画绿点,也不计入徽标数字与 hover 明细里的分组聚合行
|
|
33
|
-
* (会话行自身的绿点不受影响——那是行级状态,不是分组提示)。
|
|
34
|
-
*/
|
|
35
|
-
showCompletedInBadge: Schema.boolean().default(true)
|
|
28
|
+
const Config = Schema.object({
|
|
29
|
+
/**
|
|
30
|
+
* 折叠分组徽标是否显示「已完成」绿点。
|
|
31
|
+
*
|
|
32
|
+
* 关闭后 `done` 既不画绿点,也不计入徽标数字与 hover 明细里的分组聚合行
|
|
33
|
+
* (会话行自身的绿点不受影响——那是行级状态,不是分组提示)。
|
|
34
|
+
*/
|
|
35
|
+
showCompletedInBadge: Schema.boolean().default(true),
|
|
36
|
+
/** 折叠分组徽标是否显示「进行中」转圈(含子智能体)。 */
|
|
37
|
+
showRunningInBadge: Schema.boolean().default(true),
|
|
38
|
+
/** 折叠分组徽标是否显示「待审批」黄点(approval / plan-review / question)。 */
|
|
39
|
+
showPendingInBadge: Schema.boolean().default(true),
|
|
40
|
+
/** 折叠分组徽标是否显示「定时任务」时钟图标(数据来自 dsh-later)。 */
|
|
41
|
+
showScheduledInBadge: Schema.boolean().default(true),
|
|
42
|
+
/** 折叠分组徽标是否显示「等待评审」沙漏图标(数据来自 dsh-gitea-dispatch)。 */
|
|
43
|
+
showWaitingReviewInBadge: Schema.boolean().default(true),
|
|
44
|
+
/** 悬停卡里是否显示聚合明细行("1 等待回答 · 1 进行中…")。 */
|
|
45
|
+
showHoverDetails: Schema.boolean().default(true),
|
|
46
|
+
/** 徽标数字显示阈值:数量 >= 此值时才显示数字(默认 2,即 count=1 时省略)。 */
|
|
47
|
+
countThreshold: Schema.number().default(2)
|
|
48
|
+
}).volatile();
|
|
36
49
|
/**
|
|
37
50
|
* Host plugin body. Cordis passes `(ctx, config)`; only the Config matters here
|
|
38
51
|
* and even that is read by the browser half, not here — the body stays empty so
|
|
@@ -48,12 +48,12 @@ export interface WorkspacePickFlowProps {
|
|
|
48
48
|
* @param props - owner-controlled flow props.
|
|
49
49
|
* @returns menu + dialog elements.
|
|
50
50
|
*/
|
|
51
|
-
export declare function WorkspacePickFlow({ t, open, anchorRef, useWorkspaces, createWorkspace, useDirectoryFlow, renderDirectoryFlow, onPick, onClose, addOnly, onBusyChange, side, selectedId, }: WorkspacePickFlowProps):
|
|
51
|
+
export declare function WorkspacePickFlow({ t, open, anchorRef, useWorkspaces, createWorkspace, useDirectoryFlow, renderDirectoryFlow, onPick, onClose, addOnly, onBusyChange, side, selectedId, }: WorkspacePickFlowProps): import("react").JSX.Element;
|
|
52
52
|
/**
|
|
53
53
|
* The conversation empty-state registration: adapts the owner share to the
|
|
54
54
|
* core flow (all state and semantics live in the flow / the owner).
|
|
55
55
|
* @param props - empty-state slot props (owner share + injected creation callback).
|
|
56
56
|
* @returns the flow element.
|
|
57
57
|
*/
|
|
58
|
-
export declare function WorkspacePicker({ open, anchorRef, useWorkspaces, selectedId, onPick, onClose, createWorkspace, useDirectoryFlow, renderSlot, t, }: WorkspacePickerProps):
|
|
58
|
+
export declare function WorkspacePicker({ open, anchorRef, useWorkspaces, selectedId, onPick, onClose, createWorkspace, useDirectoryFlow, renderSlot, t, }: WorkspacePickerProps): import("react").JSX.Element;
|
|
59
59
|
//# sourceMappingURL=WorkspacePicker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspacePicker.d.ts","sourceRoot":"","sources":["../../../src/client/WorkspacePicker.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKjD,OAAO,KAAK,EACV,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAC9C,MAAM,kDAAkD,CAAA;AAEzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAA;AAC5E,OAAO,KAAK,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAKxF,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,kFAAkF;IAClF,CAAC,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAA;IAC5B,oEAAoE;IACpE,IAAI,EAAE,OAAO,CAAA;IACb,kEAAkE;IAClE,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,SAAS,CAAA;IACrD,uEAAuE;IACvE,aAAa,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,CAAC,KAAK,CAAC,CAAA;IAClE,yDAAyD;IACzD,eAAe,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,aAAa,CAAC,CAAA;IACpE,0HAA0H;IAC1H,gBAAgB,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAA;IAC/C,+GAA+G;IAC/G,mBAAmB,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,SAAS,CAAA;IAClE,8CAA8C;IAC9C,MAAM,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAA;IAC1C,8DAA8D;IAC9D,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC,2DAA2D;IAC3D,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qDAAqD;IACrD,IAAI,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAA;IACjC,sEAAsE;IACtE,UAAU,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;CACrC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,CAAC,EACD,IAAI,EACJ,SAAS,EACT,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,MAAM,EACN,OAAO,EACP,OAAe,EACf,YAAY,EACZ,IAAe,EACf,UAAU,GACX,EAAE,sBAAsB
|
|
1
|
+
{"version":3,"file":"WorkspacePicker.d.ts","sourceRoot":"","sources":["../../../src/client/WorkspacePicker.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKjD,OAAO,KAAK,EACV,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAC9C,MAAM,kDAAkD,CAAA;AAEzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAA;AAC5E,OAAO,KAAK,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAKxF,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,kFAAkF;IAClF,CAAC,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAA;IAC5B,oEAAoE;IACpE,IAAI,EAAE,OAAO,CAAA;IACb,kEAAkE;IAClE,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,SAAS,CAAA;IACrD,uEAAuE;IACvE,aAAa,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,CAAC,KAAK,CAAC,CAAA;IAClE,yDAAyD;IACzD,eAAe,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,aAAa,CAAC,CAAA;IACpE,0HAA0H;IAC1H,gBAAgB,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAA;IAC/C,+GAA+G;IAC/G,mBAAmB,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,SAAS,CAAA;IAClE,8CAA8C;IAC9C,MAAM,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAA;IAC1C,8DAA8D;IAC9D,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC,2DAA2D;IAC3D,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qDAAqD;IACrD,IAAI,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAA;IACjC,sEAAsE;IACtE,UAAU,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;CACrC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,CAAC,EACD,IAAI,EACJ,SAAS,EACT,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,MAAM,EACN,OAAO,EACP,OAAe,EACf,YAAY,EACZ,IAAe,EACf,UAAU,GACX,EAAE,sBAAsB,+BAmJxB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,SAAS,EACT,aAAa,EACb,UAAU,EACV,MAAM,EACN,OAAO,EACP,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,CAAC,GACF,EAAE,oBAAoB,+BAetB"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fork-owned: the **wording** of a folded group's aggregated status.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `rows/GroupBadge.tsx` for one concrete reason: that file imports the
|
|
5
|
+
* host icon set, and a published `…/client` bundle's `require` graph only resolves
|
|
6
|
+
* inside the DSH app (see `vitest.config.ts`, exclusion reason (b)). Keeping these
|
|
7
|
+
* functions free of runtime imports is what lets the badge behaviour be tested at all
|
|
8
|
+
* instead of being asserted by a screenshot nobody re-runs.
|
|
9
|
+
*
|
|
10
|
+
* 本模块**不认识任何具体状态源**:外部状态一律经 `./facets.ts` 的协议进来,文案、图标、
|
|
11
|
+
* 脉冲都由该状态的所有者声明,本模块只管排布顺序与分隔符。
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
import type { ReactNode } from 'react';
|
|
16
|
+
import type { WorkspaceBrowserProps } from './contract/slots.ts';
|
|
17
|
+
import type { FacetEntry, GroupLiveStatus } from './group-status.ts';
|
|
18
|
+
import type { ResolvedBadgeSettings } from './badge-settings.ts';
|
|
19
|
+
/** The standard locale seat, prop-passed from the browser root (type-only import). */
|
|
20
|
+
type RowTranslate = WorkspaceBrowserProps['t'];
|
|
21
|
+
/** 一条悬停明细:一个状态点(或来源自己的图标)加它的文案。 */
|
|
22
|
+
export interface HoverStatusLine {
|
|
23
|
+
state: 'warning' | 'ongoing' | 'done';
|
|
24
|
+
text: string;
|
|
25
|
+
/** #24:来源自己交的图标(已含色档)。宿主会话状态没有它,仍用三档 `StateDot`。 */
|
|
26
|
+
glyph?: ReactNode;
|
|
27
|
+
}
|
|
28
|
+
/** 该 facet 贡献进徽标数字的条数。 */
|
|
29
|
+
export declare function facetCountTotal(s: GroupLiveStatus): number;
|
|
30
|
+
/**
|
|
31
|
+
* 每个外部状态来源的那句话,按登记顺序。
|
|
32
|
+
*
|
|
33
|
+
* facet 没实现 `label` 时**不能**退化成 `2 dsh-later.schedule` 这种读法,所以给一句
|
|
34
|
+
* 通用措辞兜底:只说有几个来源在响,具体语义等该来源自己补文案。
|
|
35
|
+
*/
|
|
36
|
+
export declare function facetLines(s: GroupLiveStatus, t: RowTranslate, now: number): string[];
|
|
37
|
+
/**
|
|
38
|
+
* Accessible label for a folded group's aggregated status, reusing the
|
|
39
|
+
* session-row locale keys so both surfaces read identically.
|
|
40
|
+
*
|
|
41
|
+
* 按设置过滤:**关掉的外部来源根本不在折果里**(`WorkspaceBrowser` 折叠前就按
|
|
42
|
+
* `facet.settingKey` 过滤了登记面),所以这里不必再判设置,`aria-label` 与徽标视觉
|
|
43
|
+
* 天然一致;宿主的行级状态仍按设置逐项过滤。
|
|
44
|
+
*/
|
|
45
|
+
export declare function groupLiveLabel(s: GroupLiveStatus, t: RowTranslate, settings: ResolvedBadgeSettings, now?: number): string;
|
|
46
|
+
/**
|
|
47
|
+
* 每个外部状态来源的明细行,**带它自己的图标**(#24)。
|
|
48
|
+
*
|
|
49
|
+
* 徽标侧画的是 provider 交出的、已含色档的元素(`rows/GroupBadge.tsx` 的 `facetGlyph`),
|
|
50
|
+
* 明细侧此前只画一个统一的 `StateDot`,于是同一条状态、同一次悬停里,徽标是红色沙漏、
|
|
51
|
+
* 明细是黄点——同一行的两个视图各说一套。宿主 `StateDot` 只有 warning / ongoing / done
|
|
52
|
+
* 三档、没有 error 档,所以色档**只能**由来源自己的图标表达,这也是本函数存在的理由。
|
|
53
|
+
*
|
|
54
|
+
* provider 没交图标时退回通用点(与徽标侧同一套兜底),陌生来源仍然可见。
|
|
55
|
+
*
|
|
56
|
+
* @returns 明细行;`glyph` 为 `undefined` 表示该行用 `StateDot` 渲染。
|
|
57
|
+
*/
|
|
58
|
+
export declare function facetDetailLines(s: GroupLiveStatus, t: RowTranslate, now: number): HoverStatusLine[];
|
|
59
|
+
/**
|
|
60
|
+
* Build the status detail lines for the workspace hover card.
|
|
61
|
+
*
|
|
62
|
+
* Extracted so `WorkspaceHoverContent` in `Rows.tsx` only needs to map the returned
|
|
63
|
+
* array — the fork-specific status→line logic lives here.
|
|
64
|
+
*
|
|
65
|
+
* 按设置过滤:关掉的来源不出现在明细行里;`showHoverDetails=false` 时整段返回空。
|
|
66
|
+
* 明细行的顺序与徽标**完全一致**(外部来源排在会话状态之后、已完成之前):两处顺序
|
|
67
|
+
* 不一样会让人怀疑它们是两套事实。
|
|
68
|
+
*/
|
|
69
|
+
export declare function hoverStatusLines(status: GroupLiveStatus | undefined, t: RowTranslate, settings: ResolvedBadgeSettings, now?: number): HoverStatusLine[];
|
|
70
|
+
/**
|
|
71
|
+
* 某一条外部来源的元素该带哪只 class(#22)。
|
|
72
|
+
*
|
|
73
|
+
* 脉冲判据仍由各 facet 自己声明(`FacetFold.pulse`),但**作用对象必须下沉到声明它的那个
|
|
74
|
+
* 元素**。此前 `groupBadgeIsUrgent()` 只返回一个整徽标的布尔值、class 加在容器上,于是同组
|
|
75
|
+
* 里任何一家声明 `pulse: true` 都会让别家本该静止的图标跟着呼吸:`pulse: false` 是否生效,
|
|
76
|
+
* 取决于同组里恰好有没有别人开了闪。判断交出去了,作用对象没交出去——这是修过一次的回归
|
|
77
|
+
* (见下)。
|
|
78
|
+
*
|
|
79
|
+
* 保留这条历史的原因写在所有者那边:dsh-gitea-dispatch 把 `overdue` 画成**静止**(其
|
|
80
|
+
* `lib/waiting-glyph.js`:「超时后停动画:静止即不再期待」),且它只代表 CI 窗口到期、
|
|
81
|
+
* 不代表评审失败。同一条等待在行内静止、在父级闪动,就是同一事实的两种说法。
|
|
82
|
+
*/
|
|
83
|
+
export declare function facetPulseClass(entry: FacetEntry, urgentClass: string): string | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* 一个来源的图标。
|
|
86
|
+
*
|
|
87
|
+
* 归 provider 画(`facet.renderIcon`):「这个状态长什么样」是它的知识。没实现时本插件
|
|
88
|
+
* 按色档退回一个通用点(见 `rows/GroupBadge.tsx`),保证陌生来源仍然可见、只是朴素。
|
|
89
|
+
*/
|
|
90
|
+
export declare function facetGlyph(entry: FacetEntry, t: RowTranslate, now: number): ReactNode;
|
|
91
|
+
export {};
|
|
92
|
+
//# sourceMappingURL=badge-labels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"badge-labels.d.ts","sourceRoot":"","sources":["../../../src/client/badge-labels.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACpE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAEhE,sFAAsF;AACtF,KAAK,YAAY,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAA;AAE9C,mCAAmC;AACnC,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAA;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,oDAAoD;IACpD,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAcD,0BAA0B;AAC1B,wBAAgB,eAAe,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CAI1D;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAQrF;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,CAAC,EAAE,eAAe,EAClB,CAAC,EAAE,YAAY,EACf,QAAQ,EAAE,qBAAqB,EAC/B,GAAG,GAAE,MAAmB,GACvB,MAAM,CAgBR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,eAAe,EAAE,CASpG;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,eAAe,GAAG,SAAS,EACnC,CAAC,EAAE,YAAY,EACf,QAAQ,EAAE,qBAAqB,EAC/B,GAAG,GAAE,MAAmB,GACvB,eAAe,EAAE,CAsBnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE1F;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAErF"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 把侧栏行的翻译位交给 facet。
|
|
3
|
+
*
|
|
4
|
+
* 这里有一次**故意的放宽**:协议的 `t` 收任意字符串键,而行位只收本插件 `workspace`
|
|
5
|
+
* 命名空间的键。放宽是安全的——宿主 locale 服务对未注册的键一律**原样回显键名**(不是
|
|
6
|
+
* 抛错),所以外来 facet 传了自己命名空间的键,最坏读出的是那串键名而不是崩渲染。
|
|
7
|
+
* 要正确本地化,provider 应当闭包自己的翻译函数、忽略这里传入的 `t`。
|
|
8
|
+
*/
|
|
9
|
+
function asFacetTranslate(t) {
|
|
10
|
+
return (key, options) => t(key, options);
|
|
11
|
+
}
|
|
12
|
+
/** 该 facet 贡献进徽标数字的条数。 */
|
|
13
|
+
export function facetCountTotal(s) {
|
|
14
|
+
let total = 0;
|
|
15
|
+
for (const entry of s.facets.values())
|
|
16
|
+
total += entry.fold.count;
|
|
17
|
+
return total;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 每个外部状态来源的那句话,按登记顺序。
|
|
21
|
+
*
|
|
22
|
+
* facet 没实现 `label` 时**不能**退化成 `2 dsh-later.schedule` 这种读法,所以给一句
|
|
23
|
+
* 通用措辞兜底:只说有几个来源在响,具体语义等该来源自己补文案。
|
|
24
|
+
*/
|
|
25
|
+
export function facetLines(s, t, now) {
|
|
26
|
+
const translate = asFacetTranslate(t);
|
|
27
|
+
const lines = [];
|
|
28
|
+
for (const entry of s.facets.values()) {
|
|
29
|
+
const text = entry.facet.label?.(entry.fold, { now, t: translate });
|
|
30
|
+
lines.push(text === undefined || text === '' ? `${entry.fold.count} ${t('status.needsAttention')}` : text);
|
|
31
|
+
}
|
|
32
|
+
return lines;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Accessible label for a folded group's aggregated status, reusing the
|
|
36
|
+
* session-row locale keys so both surfaces read identically.
|
|
37
|
+
*
|
|
38
|
+
* 按设置过滤:**关掉的外部来源根本不在折果里**(`WorkspaceBrowser` 折叠前就按
|
|
39
|
+
* `facet.settingKey` 过滤了登记面),所以这里不必再判设置,`aria-label` 与徽标视觉
|
|
40
|
+
* 天然一致;宿主的行级状态仍按设置逐项过滤。
|
|
41
|
+
*/
|
|
42
|
+
export function groupLiveLabel(s, t, settings, now = Date.now()) {
|
|
43
|
+
const parts = [];
|
|
44
|
+
if (settings.showPendingInBadge) {
|
|
45
|
+
if (s.approval > 0)
|
|
46
|
+
parts.push(`${s.approval} ${t('status.waitingApproval')}`);
|
|
47
|
+
if (s.planReview > 0)
|
|
48
|
+
parts.push(`${s.planReview} ${t('status.planReview')}`);
|
|
49
|
+
if (s.question > 0)
|
|
50
|
+
parts.push(`${s.question} ${t('status.waitingAnswer')}`);
|
|
51
|
+
}
|
|
52
|
+
if (settings.showRunningInBadge) {
|
|
53
|
+
if (s.running > 0)
|
|
54
|
+
parts.push(`${s.running} ${t('status.running')}`);
|
|
55
|
+
if (s.subagents > 0) {
|
|
56
|
+
parts.push(t(s.subagents === 1 ? 'status.subagentsRunning.one' : 'status.subagentsRunning.other', { n: s.subagents }));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
parts.push(...facetLines(s, t, now));
|
|
60
|
+
if (settings.showCompletedInBadge && s.done > 0)
|
|
61
|
+
parts.push(`${s.done} ${t('status.completed')}`);
|
|
62
|
+
return parts.join(' · ');
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 每个外部状态来源的明细行,**带它自己的图标**(#24)。
|
|
66
|
+
*
|
|
67
|
+
* 徽标侧画的是 provider 交出的、已含色档的元素(`rows/GroupBadge.tsx` 的 `facetGlyph`),
|
|
68
|
+
* 明细侧此前只画一个统一的 `StateDot`,于是同一条状态、同一次悬停里,徽标是红色沙漏、
|
|
69
|
+
* 明细是黄点——同一行的两个视图各说一套。宿主 `StateDot` 只有 warning / ongoing / done
|
|
70
|
+
* 三档、没有 error 档,所以色档**只能**由来源自己的图标表达,这也是本函数存在的理由。
|
|
71
|
+
*
|
|
72
|
+
* provider 没交图标时退回通用点(与徽标侧同一套兜底),陌生来源仍然可见。
|
|
73
|
+
*
|
|
74
|
+
* @returns 明细行;`glyph` 为 `undefined` 表示该行用 `StateDot` 渲染。
|
|
75
|
+
*/
|
|
76
|
+
export function facetDetailLines(s, t, now) {
|
|
77
|
+
const translate = asFacetTranslate(t);
|
|
78
|
+
const lines = [];
|
|
79
|
+
for (const entry of s.facets.values()) {
|
|
80
|
+
const raw = entry.facet.label?.(entry.fold, { now, t: translate });
|
|
81
|
+
const text = raw === undefined || raw === '' ? `${entry.fold.count} ${t('status.needsAttention')}` : raw;
|
|
82
|
+
lines.push({ state: 'warning', text, glyph: facetGlyph(entry, t, now) });
|
|
83
|
+
}
|
|
84
|
+
return lines;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Build the status detail lines for the workspace hover card.
|
|
88
|
+
*
|
|
89
|
+
* Extracted so `WorkspaceHoverContent` in `Rows.tsx` only needs to map the returned
|
|
90
|
+
* array — the fork-specific status→line logic lives here.
|
|
91
|
+
*
|
|
92
|
+
* 按设置过滤:关掉的来源不出现在明细行里;`showHoverDetails=false` 时整段返回空。
|
|
93
|
+
* 明细行的顺序与徽标**完全一致**(外部来源排在会话状态之后、已完成之前):两处顺序
|
|
94
|
+
* 不一样会让人怀疑它们是两套事实。
|
|
95
|
+
*/
|
|
96
|
+
export function hoverStatusLines(status, t, settings, now = Date.now()) {
|
|
97
|
+
const lines = [];
|
|
98
|
+
if (status === undefined || !settings.showHoverDetails)
|
|
99
|
+
return lines;
|
|
100
|
+
if (settings.showPendingInBadge) {
|
|
101
|
+
if (status.approval > 0)
|
|
102
|
+
lines.push({ state: 'warning', text: `${status.approval} ${t('status.waitingApproval')}` });
|
|
103
|
+
if (status.planReview > 0)
|
|
104
|
+
lines.push({ state: 'warning', text: `${status.planReview} ${t('status.planReview')}` });
|
|
105
|
+
if (status.question > 0)
|
|
106
|
+
lines.push({ state: 'warning', text: `${status.question} ${t('status.waitingAnswer')}` });
|
|
107
|
+
}
|
|
108
|
+
if (settings.showRunningInBadge) {
|
|
109
|
+
if (status.running > 0)
|
|
110
|
+
lines.push({ state: 'ongoing', text: `${status.running} ${t('status.running')}` });
|
|
111
|
+
if (status.subagents > 0) {
|
|
112
|
+
lines.push({
|
|
113
|
+
state: 'ongoing',
|
|
114
|
+
text: t(status.subagents === 1 ? 'status.subagentsRunning.one' : 'status.subagentsRunning.other', { n: status.subagents }),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// #24:外部来源的明细行改用来源自己的图标(已含色档),与徽标同源。宿主的三档点仍用在
|
|
119
|
+
// 宿主会话状态上——那些档位本就是宿主的语义,色档无处可失。
|
|
120
|
+
lines.push(...facetDetailLines(status, t, now));
|
|
121
|
+
if (settings.showCompletedInBadge && status.done > 0)
|
|
122
|
+
lines.push({ state: 'done', text: `${status.done} ${t('status.completed')}` });
|
|
123
|
+
return lines;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* 某一条外部来源的元素该带哪只 class(#22)。
|
|
127
|
+
*
|
|
128
|
+
* 脉冲判据仍由各 facet 自己声明(`FacetFold.pulse`),但**作用对象必须下沉到声明它的那个
|
|
129
|
+
* 元素**。此前 `groupBadgeIsUrgent()` 只返回一个整徽标的布尔值、class 加在容器上,于是同组
|
|
130
|
+
* 里任何一家声明 `pulse: true` 都会让别家本该静止的图标跟着呼吸:`pulse: false` 是否生效,
|
|
131
|
+
* 取决于同组里恰好有没有别人开了闪。判断交出去了,作用对象没交出去——这是修过一次的回归
|
|
132
|
+
* (见下)。
|
|
133
|
+
*
|
|
134
|
+
* 保留这条历史的原因写在所有者那边:dsh-gitea-dispatch 把 `overdue` 画成**静止**(其
|
|
135
|
+
* `lib/waiting-glyph.js`:「超时后停动画:静止即不再期待」),且它只代表 CI 窗口到期、
|
|
136
|
+
* 不代表评审失败。同一条等待在行内静止、在父级闪动,就是同一事实的两种说法。
|
|
137
|
+
*/
|
|
138
|
+
export function facetPulseClass(entry, urgentClass) {
|
|
139
|
+
return entry.fold.pulse ? urgentClass : undefined;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 一个来源的图标。
|
|
143
|
+
*
|
|
144
|
+
* 归 provider 画(`facet.renderIcon`):「这个状态长什么样」是它的知识。没实现时本插件
|
|
145
|
+
* 按色档退回一个通用点(见 `rows/GroupBadge.tsx`),保证陌生来源仍然可见、只是朴素。
|
|
146
|
+
*/
|
|
147
|
+
export function facetGlyph(entry, t, now) {
|
|
148
|
+
return entry.facet.renderIcon?.(entry.fold, { now, t: asFacetTranslate(t) });
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=badge-labels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"badge-labels.js","sourceRoot":"","sources":["../../../src/client/badge-labels.ts"],"names":[],"mappings":"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"}
|
|
@@ -41,13 +41,29 @@ export interface ResolvedBadgeSettings {
|
|
|
41
41
|
showPendingInBadge: boolean;
|
|
42
42
|
/** 折叠徽标是否显示「定时任务」时钟图标(数据来自 dsh-later);缺失/非法一律回落 true。 */
|
|
43
43
|
showScheduledInBadge: boolean;
|
|
44
|
-
/**
|
|
44
|
+
/** 折叠徽标是否显示「等待评审」沙漏图标(数据来自 dsh-gitea-dispatch,自其 #56 起画沙漏;缺失/非法一律回落 true)。 */
|
|
45
45
|
showWaitingReviewInBadge: boolean;
|
|
46
46
|
/** 悬停卡里是否显示聚合明细行;缺失/非法一律回落 true。 */
|
|
47
47
|
showHoverDetails: boolean;
|
|
48
48
|
/** 徽标数字显示阈值:数量 >= 此值时才显示数字;缺失/非法一律回落 2(默认 count=1 时省略)。 */
|
|
49
49
|
countThreshold: number;
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* `ResolvedBadgeSettings` 里的布尔开关键。
|
|
53
|
+
*
|
|
54
|
+
* facet 的 `settingKey` 就是它的字符串形态:状态所有者声明"我受哪个开关管",
|
|
55
|
+
* 而开关的语义与取值仍由本插件判定。
|
|
56
|
+
*/
|
|
57
|
+
export type BooleanSettingKey = {
|
|
58
|
+
[K in keyof ResolvedBadgeSettings]: ResolvedBadgeSettings[K] extends boolean ? K : never;
|
|
59
|
+
}[keyof ResolvedBadgeSettings];
|
|
60
|
+
/**
|
|
61
|
+
* 一个 facet 是否被设置关掉。
|
|
62
|
+
*
|
|
63
|
+
* - 没有 `settingKey` → 始终参与(缺省是"显示",与其余开关的默认值同源)。
|
|
64
|
+
* - 声明了但不是布尔开关键 → 同样按显示处理:拼错的键不该让一个状态整块消失。
|
|
65
|
+
*/
|
|
66
|
+
export declare function facetVisibleBySettings(settings: ResolvedBadgeSettings, settingKey: string | undefined): boolean;
|
|
51
67
|
/** 标准 props 源的结构面(与 `HostObservable<ResolvedBadgeSettings>` 兼容)。 */
|
|
52
68
|
export interface BadgeSettingsSource {
|
|
53
69
|
getSnapshot(): ResolvedBadgeSettings;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"badge-settings.d.ts","sourceRoot":"","sources":["../../../src/client/badge-settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,sDAAsD;AACtD,eAAO,MAAM,QAAQ,qBAAqB,CAAA;AAE1C,gDAAgD;AAChD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACzB;AAED,sCAAsC;AACtC,MAAM,WAAW,iBAAiB;IAChC,WAAW,IAAI,oBAAoB,CAAA;IACnC,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;CAC5C;AAED,sBAAsB;AACtB,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,oBAAoB,EAAE,OAAO,CAAA;IAC7B,6CAA6C;IAC7C,kBAAkB,EAAE,OAAO,CAAA;IAC3B,yEAAyE;IACzE,kBAAkB,EAAE,OAAO,CAAA;IAC3B,yDAAyD;IACzD,oBAAoB,EAAE,OAAO,CAAA;IAC7B,
|
|
1
|
+
{"version":3,"file":"badge-settings.d.ts","sourceRoot":"","sources":["../../../src/client/badge-settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,sDAAsD;AACtD,eAAO,MAAM,QAAQ,qBAAqB,CAAA;AAE1C,gDAAgD;AAChD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACzB;AAED,sCAAsC;AACtC,MAAM,WAAW,iBAAiB;IAChC,WAAW,IAAI,oBAAoB,CAAA;IACnC,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;CAC5C;AAED,sBAAsB;AACtB,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,oBAAoB,EAAE,OAAO,CAAA;IAC7B,6CAA6C;IAC7C,kBAAkB,EAAE,OAAO,CAAA;IAC3B,yEAAyE;IACzE,kBAAkB,EAAE,OAAO,CAAA;IAC3B,yDAAyD;IACzD,oBAAoB,EAAE,OAAO,CAAA;IAC7B,8EAA8E;IAC9E,wBAAwB,EAAE,OAAO,CAAA;IACjC,oCAAoC;IACpC,gBAAgB,EAAE,OAAO,CAAA;IACzB,2DAA2D;IAC3D,cAAc,EAAE,MAAM,CAAA;CACvB;AAED;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG;KAC7B,CAAC,IAAI,MAAM,qBAAqB,GAAG,qBAAqB,CAAC,CAAC,CAAC,SAAS,OAAO,GAAG,CAAC,GAAG,KAAK;CACzF,CAAC,MAAM,qBAAqB,CAAC,CAAA;AAE9B;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAI/G;AAED,oEAAoE;AACpE,MAAM,WAAW,mBAAmB;IAClC,WAAW,IAAI,qBAAqB,CAAA;IACpC,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;CAC5C;AAED,qDAAqD;AACrD,MAAM,WAAW,0BAA2B,SAAQ,mBAAmB;IACrE;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,EAAE,oBAAoB,GAAG,SAAS,GAAG,IAAI,CAAA;CAC1D;AAED,kEAAkE;AAClE,eAAO,MAAM,sBAAsB,EAAE,qBAQnC,CAAA;AAuCF;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,IAAI,0BAA0B,CAuBtE;AAED,qCAAqC;AACrC,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,SAAS,GAAG,qBAAqB,CAEtG"}
|
|
@@ -21,6 +21,18 @@
|
|
|
21
21
|
*/
|
|
22
22
|
/** Loader 条目 id —— 设置页的寻址键,也是宿主 `describe()` 的 ns。 */
|
|
23
23
|
export const ENTRY_ID = 'dsh-group-status';
|
|
24
|
+
/**
|
|
25
|
+
* 一个 facet 是否被设置关掉。
|
|
26
|
+
*
|
|
27
|
+
* - 没有 `settingKey` → 始终参与(缺省是"显示",与其余开关的默认值同源)。
|
|
28
|
+
* - 声明了但不是布尔开关键 → 同样按显示处理:拼错的键不该让一个状态整块消失。
|
|
29
|
+
*/
|
|
30
|
+
export function facetVisibleBySettings(settings, settingKey) {
|
|
31
|
+
if (settingKey === undefined)
|
|
32
|
+
return true;
|
|
33
|
+
const value = settings[settingKey];
|
|
34
|
+
return typeof value === 'boolean' ? value : true;
|
|
35
|
+
}
|
|
24
36
|
/** 默认值:与 `Config` 各字段的 schema 默认同源(全部显示,数字阈值 2 即 count=1 时省略)。 */
|
|
25
37
|
export const DEFAULT_BADGE_SETTINGS = Object.freeze({
|
|
26
38
|
showCompletedInBadge: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"badge-settings.js","sourceRoot":"","sources":["../../../src/client/badge-settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,sDAAsD;AACtD,MAAM,CAAC,MAAM,QAAQ,GAAG,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"badge-settings.js","sourceRoot":"","sources":["../../../src/client/badge-settings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* facet 的**消费侧**:把「登记表面 + 每个 facet 自己的外部存储」压成一份 React 可订阅的
|
|
3
|
+
* 单一存储。
|
|
4
|
+
*
|
|
5
|
+
* ## 为什么必须是一个存储,而不是逐个 hook
|
|
6
|
+
*
|
|
7
|
+
* 见 `./facets.ts` 的文件头:hook 数量在同一个组件里必须逐次渲染恒定,而 facet 是运行
|
|
8
|
+
* 时注册/注销的。所以这里只暴露一个**版本号**(数字,引用天然稳定)给
|
|
9
|
+
* `useSyncExternalStore`,实际的快照读取与折叠都发生在渲染期。
|
|
10
|
+
*
|
|
11
|
+
* ## 快照读取为什么放在渲染期
|
|
12
|
+
*
|
|
13
|
+
* `getSnapshot` 必须返回稳定引用,而「每个 facet 的快照」是一个对象图:为它造一个
|
|
14
|
+
* 缓存就需要判定失效,而判定失效又要读快照本身。改成「版本号变 → 重新渲染 → 现读现折」
|
|
15
|
+
* 之后,缓存问题消失,代价是一次 O(facet × 组内会话) 的纯计算,量级与原有实现相同。
|
|
16
|
+
*
|
|
17
|
+
* @module dsh-group-status/client/facet-store
|
|
18
|
+
*/
|
|
19
|
+
import { type FacetRegistry, type RegisteredFacet } from './facets.ts';
|
|
20
|
+
/** {@link createFacetStore} 的产物。 */
|
|
21
|
+
export interface FacetStore {
|
|
22
|
+
/** 订阅「快照可能变了」或「登记面变了」。 */
|
|
23
|
+
subscribe(listener: () => void): () => void;
|
|
24
|
+
/** 单调递增的版本号;引用天然稳定,可直接作为 `useSyncExternalStore` 的快照。 */
|
|
25
|
+
getVersion(): number;
|
|
26
|
+
/** 服务端渲染快照:与 {@link getVersion} 同型,避免 hydration 不一致。 */
|
|
27
|
+
getServerVersion(): number;
|
|
28
|
+
/** 当前登记项(已排序)。 */
|
|
29
|
+
list(): readonly RegisteredFacet[];
|
|
30
|
+
/** 释放所有对 facet 存储的订阅(宿主卸载本插件时调用)。 */
|
|
31
|
+
dispose(): void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 创建 facet 存储。
|
|
35
|
+
*
|
|
36
|
+
* 对登记面做一次订阅,并在登记变化时**重新接线**各 facet 的 `subscribe`:provider 热替换
|
|
37
|
+
* 实现(同 id 再注册)或运行中启用/停用插件,都只会走到这里一次,不会留下野订阅。
|
|
38
|
+
*
|
|
39
|
+
* @param source - 登记表面;缺省用模块级单例,测试传入自建实例以隔离。
|
|
40
|
+
*/
|
|
41
|
+
export declare function createFacetStore(source?: FacetRegistry): FacetStore;
|
|
42
|
+
/** 取(并首次创建)单例存储。 */
|
|
43
|
+
export declare function facetStore(): FacetStore;
|
|
44
|
+
/** 释放单例存储(插件卸载时调用;下次 {@link facetStore} 会重建)。 */
|
|
45
|
+
export declare function disposeFacetStore(): void;
|
|
46
|
+
//# sourceMappingURL=facet-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facet-store.d.ts","sourceRoot":"","sources":["../../../src/client/facet-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAA2B,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;AAQ/F,oCAAoC;AACpC,MAAM,WAAW,UAAU;IACzB,0BAA0B;IAC1B,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;IAC3C,wDAAwD;IACxD,UAAU,IAAI,MAAM,CAAA;IACpB,wDAAwD;IACxD,gBAAgB,IAAI,MAAM,CAAA;IAC1B,kBAAkB;IAClB,IAAI,IAAI,SAAS,eAAe,EAAE,CAAA;IAClC,qCAAqC;IACrC,OAAO,IAAI,IAAI,CAAA;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,aAAwB,GAAG,UAAU,CAqE7E;AAWD,oBAAoB;AACpB,wBAAgB,UAAU,IAAI,UAAU,CAGvC;AAED,iDAAiD;AACjD,wBAAgB,iBAAiB,IAAI,IAAI,CAIxC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* facet 的**消费侧**:把「登记表面 + 每个 facet 自己的外部存储」压成一份 React 可订阅的
|
|
3
|
+
* 单一存储。
|
|
4
|
+
*
|
|
5
|
+
* ## 为什么必须是一个存储,而不是逐个 hook
|
|
6
|
+
*
|
|
7
|
+
* 见 `./facets.ts` 的文件头:hook 数量在同一个组件里必须逐次渲染恒定,而 facet 是运行
|
|
8
|
+
* 时注册/注销的。所以这里只暴露一个**版本号**(数字,引用天然稳定)给
|
|
9
|
+
* `useSyncExternalStore`,实际的快照读取与折叠都发生在渲染期。
|
|
10
|
+
*
|
|
11
|
+
* ## 快照读取为什么放在渲染期
|
|
12
|
+
*
|
|
13
|
+
* `getSnapshot` 必须返回稳定引用,而「每个 facet 的快照」是一个对象图:为它造一个
|
|
14
|
+
* 缓存就需要判定失效,而判定失效又要读快照本身。改成「版本号变 → 重新渲染 → 现读现折」
|
|
15
|
+
* 之后,缓存问题消失,代价是一次 O(facet × 组内会话) 的纯计算,量级与原有实现相同。
|
|
16
|
+
*
|
|
17
|
+
* @module dsh-group-status/client/facet-store
|
|
18
|
+
*/
|
|
19
|
+
import { registry } from "./facets.js";
|
|
20
|
+
/**
|
|
21
|
+
* 创建 facet 存储。
|
|
22
|
+
*
|
|
23
|
+
* 对登记面做一次订阅,并在登记变化时**重新接线**各 facet 的 `subscribe`:provider 热替换
|
|
24
|
+
* 实现(同 id 再注册)或运行中启用/停用插件,都只会走到这里一次,不会留下野订阅。
|
|
25
|
+
*
|
|
26
|
+
* @param source - 登记表面;缺省用模块级单例,测试传入自建实例以隔离。
|
|
27
|
+
*/
|
|
28
|
+
export function createFacetStore(source = registry) {
|
|
29
|
+
const listeners = new Set();
|
|
30
|
+
const links = new Map();
|
|
31
|
+
let version = 0;
|
|
32
|
+
let disposed = false;
|
|
33
|
+
/** 任一来源变化都要让消费方重新渲染,因此统一 bump。 */
|
|
34
|
+
const bump = () => {
|
|
35
|
+
if (disposed)
|
|
36
|
+
return;
|
|
37
|
+
version += 1;
|
|
38
|
+
for (const listener of [...listeners]) {
|
|
39
|
+
try {
|
|
40
|
+
listener();
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
/* 单个订阅者异常不影响其余订阅者 */
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
/** 把 links 对齐到当前登记项:新增接线、移除退订、替换重接。 */
|
|
48
|
+
const rewire = () => {
|
|
49
|
+
if (disposed)
|
|
50
|
+
return;
|
|
51
|
+
const current = new Map(source.list().map((entry) => [entry.facet.id, entry.facet]));
|
|
52
|
+
for (const [id, link] of [...links]) {
|
|
53
|
+
if (current.get(id) === link.facet)
|
|
54
|
+
continue;
|
|
55
|
+
try {
|
|
56
|
+
link.unsubscribe();
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
/* 退订失败不影响其它 facet 的接线 */
|
|
60
|
+
}
|
|
61
|
+
links.delete(id);
|
|
62
|
+
}
|
|
63
|
+
for (const [id, facet] of current) {
|
|
64
|
+
if (links.has(id))
|
|
65
|
+
continue;
|
|
66
|
+
links.set(id, { facet, unsubscribe: facet.subscribe(bump) });
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const unsubscribeRegistry = source.subscribe(() => {
|
|
70
|
+
rewire();
|
|
71
|
+
bump();
|
|
72
|
+
});
|
|
73
|
+
rewire();
|
|
74
|
+
return {
|
|
75
|
+
subscribe: (listener) => {
|
|
76
|
+
listeners.add(listener);
|
|
77
|
+
return () => {
|
|
78
|
+
listeners.delete(listener);
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
getVersion: () => version,
|
|
82
|
+
getServerVersion: () => 0,
|
|
83
|
+
list: () => source.list(),
|
|
84
|
+
dispose: () => {
|
|
85
|
+
if (disposed)
|
|
86
|
+
return;
|
|
87
|
+
disposed = true;
|
|
88
|
+
for (const link of links.values()) {
|
|
89
|
+
try {
|
|
90
|
+
link.unsubscribe();
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
/* 释放阶段忽略单个退订异常 */
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
links.clear();
|
|
97
|
+
unsubscribeRegistry();
|
|
98
|
+
listeners.clear();
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* 生产用的单例存储:消费侧(`WorkspaceBrowser`)订阅它,
|
|
104
|
+
* `apply` 的 effect 结束时用 {@link disposeFacetStore} 释放全部接线。
|
|
105
|
+
*
|
|
106
|
+
* 单例而非每次渲染新建,是因为它持有**对每个 facet 存储的订阅**;随渲染重建会把
|
|
107
|
+
* provider 的 store 拖进无谓的退订/重订,也让"快照在两个文件夹行之间读数不同"成为可能。
|
|
108
|
+
*/
|
|
109
|
+
let singleton;
|
|
110
|
+
/** 取(并首次创建)单例存储。 */
|
|
111
|
+
export function facetStore() {
|
|
112
|
+
if (singleton === undefined)
|
|
113
|
+
singleton = createFacetStore();
|
|
114
|
+
return singleton;
|
|
115
|
+
}
|
|
116
|
+
/** 释放单例存储(插件卸载时调用;下次 {@link facetStore} 会重建)。 */
|
|
117
|
+
export function disposeFacetStore() {
|
|
118
|
+
if (singleton === undefined)
|
|
119
|
+
return;
|
|
120
|
+
singleton.dispose();
|
|
121
|
+
singleton = undefined;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=facet-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facet-store.js","sourceRoot":"","sources":["../../../src/client/facet-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,QAAQ,EAA2D,MAAM,aAAa,CAAA;AAsB/F;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAwB,QAAQ;IAC/D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAA;IACvC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAA;IAC1C,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,IAAI,QAAQ,GAAG,KAAK,CAAA;IAEpB,kCAAkC;IAClC,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,IAAI,QAAQ;YAAE,OAAM;QACpB,OAAO,IAAI,CAAC,CAAA;QACZ,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC;gBACH,QAAQ,EAAE,CAAA;YACZ,CAAC;YAAC,MAAM,CAAC;gBACP,qBAAqB;YACvB,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IAED,uCAAuC;IACvC,MAAM,MAAM,GAAG,GAAS,EAAE;QACxB,IAAI,QAAQ;YAAE,OAAM;QACpB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACpF,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;YACpC,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,KAAK;gBAAE,SAAQ;YAC5C,IAAI,CAAC;gBACH,IAAI,CAAC,WAAW,EAAE,CAAA;YACpB,CAAC;YAAC,MAAM,CAAC;gBACP,yBAAyB;YAC3B,CAAC;YACD,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAClB,CAAC;QACD,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,SAAQ;YAC3B,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC9D,CAAC;IACH,CAAC,CAAA;IAED,MAAM,mBAAmB,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE;QAChD,MAAM,EAAE,CAAA;QACR,IAAI,EAAE,CAAA;IACR,CAAC,CAAC,CAAA;IACF,MAAM,EAAE,CAAA;IAER,OAAO;QACL,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE;YACtB,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YACvB,OAAO,GAAG,EAAE;gBACV,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;YAC5B,CAAC,CAAA;QACH,CAAC;QACD,UAAU,EAAE,GAAG,EAAE,CAAC,OAAO;QACzB,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;QACzB,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE;QACzB,OAAO,EAAE,GAAG,EAAE;YACZ,IAAI,QAAQ;gBAAE,OAAM;YACpB,QAAQ,GAAG,IAAI,CAAA;YACf,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBAClC,IAAI,CAAC;oBACH,IAAI,CAAC,WAAW,EAAE,CAAA;gBACpB,CAAC;gBAAC,MAAM,CAAC;oBACP,kBAAkB;gBACpB,CAAC;YACH,CAAC;YACD,KAAK,CAAC,KAAK,EAAE,CAAA;YACb,mBAAmB,EAAE,CAAA;YACrB,SAAS,CAAC,KAAK,EAAE,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,IAAI,SAAiC,CAAA;AAErC,oBAAoB;AACpB,MAAM,UAAU,UAAU;IACxB,IAAI,SAAS,KAAK,SAAS;QAAE,SAAS,GAAG,gBAAgB,EAAE,CAAA;IAC3D,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,iBAAiB;IAC/B,IAAI,SAAS,KAAK,SAAS;QAAE,OAAM;IACnC,SAAS,CAAC,OAAO,EAAE,CAAA;IACnB,SAAS,GAAG,SAAS,CAAA;AACvB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 按用户设置筛掉不参与折叠的状态来源。
|
|
3
|
+
*
|
|
4
|
+
* 单独成文是因为它属于**徽标自身**的可见性规则,而不是某个来源的适配:来源只在
|
|
5
|
+
* `facet.settingKey` 上声明"我受哪个开关管",开关的语义与过滤时机归本插件。
|
|
6
|
+
*
|
|
7
|
+
* 过滤发生在**折叠之前**而不是渲染阶段:徽标数字、图标、`aria-label`、悬停明细与
|
|
8
|
+
* "要不要画徽标"因此天然同源。放到渲染阶段会出现"label 里有、计数里没有",而那正是
|
|
9
|
+
* 徽标最容易被怀疑撒谎的地方。
|
|
10
|
+
*
|
|
11
|
+
* @module dsh-group-status/client/facet-visibility
|
|
12
|
+
*/
|
|
13
|
+
import { type ResolvedBadgeSettings } from './badge-settings.ts';
|
|
14
|
+
import type { RegisteredFacet } from './facets.ts';
|
|
15
|
+
/** 筛出设置允许显示的登记项;顺序保持登记面的顺序(已按 `order` 排好)。 */
|
|
16
|
+
export declare function visibleFacets(entries: readonly RegisteredFacet[], settings: ResolvedBadgeSettings): RegisteredFacet[];
|
|
17
|
+
//# sourceMappingURL=facet-visibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facet-visibility.d.ts","sourceRoot":"","sources":["../../../src/client/facet-visibility.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAA0B,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AACxF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,8CAA8C;AAC9C,wBAAgB,aAAa,CAC3B,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,QAAQ,EAAE,qBAAqB,GAC9B,eAAe,EAAE,CAEnB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 按用户设置筛掉不参与折叠的状态来源。
|
|
3
|
+
*
|
|
4
|
+
* 单独成文是因为它属于**徽标自身**的可见性规则,而不是某个来源的适配:来源只在
|
|
5
|
+
* `facet.settingKey` 上声明"我受哪个开关管",开关的语义与过滤时机归本插件。
|
|
6
|
+
*
|
|
7
|
+
* 过滤发生在**折叠之前**而不是渲染阶段:徽标数字、图标、`aria-label`、悬停明细与
|
|
8
|
+
* "要不要画徽标"因此天然同源。放到渲染阶段会出现"label 里有、计数里没有",而那正是
|
|
9
|
+
* 徽标最容易被怀疑撒谎的地方。
|
|
10
|
+
*
|
|
11
|
+
* @module dsh-group-status/client/facet-visibility
|
|
12
|
+
*/
|
|
13
|
+
import { facetVisibleBySettings } from "./badge-settings.js";
|
|
14
|
+
/** 筛出设置允许显示的登记项;顺序保持登记面的顺序(已按 `order` 排好)。 */
|
|
15
|
+
export function visibleFacets(entries, settings) {
|
|
16
|
+
return entries.filter(entry => facetVisibleBySettings(settings, entry.facet.settingKey));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=facet-visibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facet-visibility.js","sourceRoot":"","sources":["../../../src/client/facet-visibility.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,sBAAsB,EAA8B,MAAM,qBAAqB,CAAA;AAGxF,8CAA8C;AAC9C,MAAM,UAAU,aAAa,CAC3B,OAAmC,EACnC,QAA+B;IAE/B,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAA;AAC1F,CAAC"}
|