dsh-task-ledger 0.0.124 → 0.0.126
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/dist/client.js +1441 -533
- package/dist/client.js.map +1 -1
- package/dist/host/errors.d.ts +2 -2
- package/dist/host/repositories/cache.d.ts +2 -2
- package/dist/host/repositories/trend.repository.d.ts +13 -3
- package/dist/host/repositories/trend.repository.js +24 -5
- package/dist/host/routes.js +14 -0
- package/dist/host/services/history.service.d.ts +2 -0
- package/dist/host/services/history.service.js +130 -0
- package/dist/host/services/trend.service.js +2 -2
- package/dist/host/types.d.ts +55 -1
- package/package.json +2 -2
- package/skill/package.json +1 -1
- package/skill/scripts/bin/ledger-darwin-arm64 +0 -0
- package/skill/scripts/bin/ledger-linux-amd64 +0 -0
- package/skill/scripts/bin/ledger-windows-amd64.exe +0 -0
package/dist/client.js
CHANGED
|
@@ -46,10 +46,10 @@ window.__ModuleLoader__.load({
|
|
|
46
46
|
let react_dom_client = require("react-dom/client");
|
|
47
47
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
48
48
|
_deepseek_ai_dsh_client_ui_primitives = __toESM(_deepseek_ai_dsh_client_ui_primitives, 1);
|
|
49
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
49
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/design/tokens-css.generated.js
|
|
50
50
|
const TOKENS_CSS_TEMPLATE = "\n/* ── 文字(宿主 label 四档 + 反色面用字)────────────────────────────── */\nbody{\n --dshpc-fg:var(--dsw-alias-label-primary,#1f2328);\n --dshpc-fg-2:var(--dsw-alias-label-secondary,#5c6370);\n --dshpc-fg-3:var(--dsw-alias-label-tertiary,#767d87);\n --dshpc-fg-4:var(--dsw-alias-label-caption,#9aa1ab);\n --dshpc-fg-dim:var(--dsw-alias-label-dimmed,#b9bfc7);\n /* 反色面上的字(实心钮 / 角标):暗色下是 bluish-1000,故用 -foreground 而非 -inverted */\n --dshpc-fg-inverse:var(--dsw-alias-label-primary-foreground,#fff);\n\n /* ── 面(宿主 bg-layer 三档 + 下沉轨道底)──────────────────────────── */\n --dshpc-surface-1:var(--dsw-alias-bg-layer-1,#fff);\n --dshpc-surface-2:var(--dsw-alias-bg-layer-2,#fff);\n --dshpc-surface-3:var(--dsw-alias-bg-layer-3,#fff);\n /* 「选中亮片」的底盘色(配 --dshpc-shadow-raised 用) */\n --dshpc-surface-raised:var(--dsw-alias-bg-layer-1,#fff);\n /* 轨道 / 下沉底(官方分段控件轨道用的就是这条) */\n --dshpc-surface-sunken:var(--dsw-alias-interactive-bg-hover,rgba(38,49,72,.06));\n /* 整页 / 编辑器底(bg-base) */\n --dshpc-surface-base:var(--dsw-alias-bg-base,#fff);\n /* 自绘浮层 / 菜单卡的不透明底(= base;不要用半透明的 specific-menu) */\n --dshpc-surface-menu:var(--dshpc-surface-base);\n /* markdown 代码块面 / 字体(会话镜像里用到) */\n --dshpc-code-surface:var(--dsw-alias-markdown-code-block,rgba(128,128,128,.10));\n --dshpc-code-font:var(--dsw-font-markdown-code-block-small,12px/18px var(--ds-font-family-code,monospace));\n /* 警告文字色(宿主 state-warn-label) */\n --dshpc-warning-label:var(--dsw-alias-state-warn-label,#f5a623);\n /* 固定中性实面(自绘浮层、深色主题下必须自己变的那几个)——只有它需要暗色覆盖 */\n --dshpc-solid:var(--dsw-static-neutral-00,#fff);\n --dshpc-on-solid:var(--dsw-alias-label-primary,#1f2328);\n /* 交付文件卡那种「浅底盘 + hover 加深」两拍 */\n --dshpc-plate:var(--dsw-static-neutral-50,#fafafa);\n --dshpc-plate-hover:var(--dsw-static-neutral-100,#f5f5f5);\n /* ⚠️ 这些**固定中性面一律用 rgba 字面量**(2026-10-19 真机教训):不要写成\n 「rgba 回退行 + 嵌 --dsw-static-* 的 color-mix 行」两条同名声明——自定义属性**后者恒胜**,\n 哪怕它的值在宿主里算不出来(static 变量 invalid)⇒ 整条 token 作废、rgba 兜底一起被废,\n 0.2.6 里 Segmented 轨道全透明就是这么来的。要跟宿主主题联动的面用 alias token(那些实测有效)。 */\n --dshpc-icon-plate:rgba(255,255,255,.5);\n /* 表头底:浅色主题**偏深**,且必须**比斑马纹(--dshpc-plate)再深一档**——\n 两者不能撞色(用户 2026-10-02:表头跟斑马纹一模一样)。 */\n --dshpc-head-bg:var(--dsw-static-neutral-100,#f5f5f5);\n /* 图标小底板(产出物):浅色下要**看得见**(原先取 plate ⇒ 在白底上等于没有);hover 加倍。 */\n --dshpc-chip-bg:rgba(15,15,15,.07);\n --dshpc-chip-bg-hover:rgba(15,15,15,.14);\n /* 展开行:**带透明度的蓝**——不是灰、也不是纯色,透出卡片底色,一眼看出「这是展开的」\n (用户 2026-10-02:灰色跟斑马纹分不出来)。内容区再淡一档,形成「行深 / 内容浅」的区隔。 */\n --dshpc-open-bg:rgba(37,99,235,.10);\n --dshpc-open-bg-soft:rgba(37,99,235,.05);\n --dshpc-card-hover:rgba(37,99,235,.07);\n\n /* ── 描边四档(宿主真值:l1 4% / l2 10% / l3 12% / l4 16%)────────── */\n --dshpc-border-faint:var(--dsw-alias-border-l1,#0000000a);\n --dshpc-border:var(--dsw-alias-border-l2,#0000001a);\n --dshpc-border-strong:var(--dsw-alias-border-l3,#0000001f);\n --dshpc-border-heavy:var(--dsw-alias-border-l4,#00000029);\n\n /* ── 品牌 / 语义色 ────────────────────────────────────────────────── */\n /* 品牌「面」色:明色近黑、暗色近白(官方 Switch 选中态即此),**不是蓝色** */\n --dshpc-accent:var(--dsw-alias-brand-primary,#0f1115);\n /* 蓝色:强调 / 选中 / 焦点,一律走这条 */\n --dshpc-business:var(--dsw-alias-state-business-primary,#3b5bdb);\n --dshpc-success:var(--dsw-alias-state-success-primary,#22c55e);\n /* ⚠️ 是 state-warn(不是 state-warning,后者宿主无此定义) */\n --dshpc-warning:var(--dsw-alias-state-warn-primary,#f59e0b);\n --dshpc-danger:var(--dsw-alias-state-error-primary,#ec1313);\n --dshpc-link:var(--dsw-alias-link,#3b5bdb);\n /* 语义色**实面**上的字(角标 / 实心提示):宿主红绿黄三色都是中调 ⇒ 白字两个主题都可读,\n 故这是一条与主题无关的常量;不要拿 --dshpc-fg-inverse 顶——它在暗色下是近黑,压在红底上看不清。 */\n --dshpc-on-signal:#fff;\n /* 黄底上的字:黄色是中高明度,白字看不清 ⇒ 固定深色(与主题无关)。 */\n --dshpc-on-warning:#1f2328;\n\n /* ── 实心按钮的 hover / active 派生态(2026-10-19 用户点名)─────────────────\n 原实现是 :hover 直接压 opacity .9:黑底压 10% 几乎看不出来,用户原话「完全感觉不到颜色变了」。\n ⇒ 改成对底色做**明确的混色**(压 22% / 34%),不用 opacity:\n · 亮色主题:黑底(--dshpc-accent)掺白提亮;红 / 绿 / 黄 / 蓝底掺黑压深;\n · 暗色主题:反过来(暗底掺白、亮底掺黑)。\n 混色对象是**固定中性色字面量**(#fff / #000),不依赖宿主 static-neutral 是否存在;\n 旧内核不认 color-mix 时整条声明作废 ⇒ 回落各档原色(可接受:仍可点,只是没有 hover 反馈)。 */\n --dshpc-accent-hover:color-mix(in srgb,var(--dshpc-accent) 78%,#ffffff);\n --dshpc-accent-active:color-mix(in srgb,var(--dshpc-accent) 64%,#ffffff);\n --dshpc-danger-hover:color-mix(in srgb,var(--dshpc-danger) 78%,#000000);\n --dshpc-danger-active:color-mix(in srgb,var(--dshpc-danger) 64%,#000000);\n --dshpc-success-hover:color-mix(in srgb,var(--dshpc-success) 78%,#000000);\n --dshpc-success-active:color-mix(in srgb,var(--dshpc-success) 64%,#000000);\n --dshpc-warning-hover:color-mix(in srgb,var(--dshpc-warning) 78%,#000000);\n --dshpc-warning-active:color-mix(in srgb,var(--dshpc-warning) 64%,#000000);\n --dshpc-business-hover:color-mix(in srgb,var(--dshpc-business) 78%,#000000);\n --dshpc-business-active:color-mix(in srgb,var(--dshpc-business) 64%,#000000);\n /* 语义色**浅底**:状态色系的「一块底色」——执行记录页每条流水账的块底就是它\n (用户 2026-10-04:正常态给同色系很浅的透明底、失败用红底透出来)。\n 用 「color-mix」 现算而不写死 rgba:状态色本身跟随宿主 alias,主题一换自动成立。\n ⚠️ **深色下要更淡**:用户 2026-10-04「深色风格的绿色和红色好像都有点深」⇒ dark 段\n 把这四条压到 5%(更贴近面板底、存在感更弱);浅色段维持 8%。两端各自给值,不共用一条曲线。\n 命名收在 tokens.ts 单点(本仓硬规矩:业务文件不许自造 --dshpc-*)。 */\n --dshpc-success-soft:color-mix(in srgb,var(--dshpc-success) 8%,transparent);\n --dshpc-warning-soft:color-mix(in srgb,var(--dshpc-warning) 8%,transparent);\n --dshpc-danger-soft:color-mix(in srgb,var(--dshpc-danger) 8%,transparent);\n --dshpc-business-soft:color-mix(in srgb,var(--dshpc-business) 8%,transparent);\n\n /* ── 扩展语义色(2026-10-29 用户拍板:分类 / 图表常用色八支)──────────────\n 宿主无对应 alias ⇒ 写死 hex(不跟随宿主换肤);实心面字色统一走 --dshpc-on-signal(白),\n 因八支明度都低于黄 / 青柠,白字两主题均 ≥4.5:1 可读。每条自带 hover/active/soft 派生;\n 暗色段只覆盖派生(base 写死、两主题同值)。 */\n --dshpc-purple:#9333ea;\n --dshpc-purple-hover:color-mix(in srgb,var(--dshpc-purple) 78%,#000000);\n --dshpc-purple-active:color-mix(in srgb,var(--dshpc-purple) 64%,#000000);\n --dshpc-purple-soft:color-mix(in srgb,var(--dshpc-purple) 8%,transparent);\n --dshpc-pink:#db2777;\n --dshpc-pink-hover:color-mix(in srgb,var(--dshpc-pink) 78%,#000000);\n --dshpc-pink-active:color-mix(in srgb,var(--dshpc-pink) 64%,#000000);\n --dshpc-pink-soft:color-mix(in srgb,var(--dshpc-pink) 8%,transparent);\n --dshpc-cyan:#0e7490;\n --dshpc-cyan-hover:color-mix(in srgb,var(--dshpc-cyan) 78%,#000000);\n --dshpc-cyan-active:color-mix(in srgb,var(--dshpc-cyan) 64%,#000000);\n --dshpc-cyan-soft:color-mix(in srgb,var(--dshpc-cyan) 8%,transparent);\n --dshpc-teal:#0f766e;\n --dshpc-teal-hover:color-mix(in srgb,var(--dshpc-teal) 78%,#000000);\n --dshpc-teal-active:color-mix(in srgb,var(--dshpc-teal) 64%,#000000);\n --dshpc-teal-soft:color-mix(in srgb,var(--dshpc-teal) 8%,transparent);\n --dshpc-orange:#c2410c;\n --dshpc-orange-hover:color-mix(in srgb,var(--dshpc-orange) 78%,#000000);\n --dshpc-orange-active:color-mix(in srgb,var(--dshpc-orange) 64%,#000000);\n --dshpc-orange-soft:color-mix(in srgb,var(--dshpc-orange) 8%,transparent);\n --dshpc-indigo:#4f46e5;\n --dshpc-indigo-hover:color-mix(in srgb,var(--dshpc-indigo) 78%,#000000);\n --dshpc-indigo-active:color-mix(in srgb,var(--dshpc-indigo) 64%,#000000);\n --dshpc-indigo-soft:color-mix(in srgb,var(--dshpc-indigo) 8%,transparent);\n --dshpc-rose:#e11d48;\n --dshpc-rose-hover:color-mix(in srgb,var(--dshpc-rose) 78%,#000000);\n --dshpc-rose-active:color-mix(in srgb,var(--dshpc-rose) 64%,#000000);\n --dshpc-rose-soft:color-mix(in srgb,var(--dshpc-rose) 8%,transparent);\n --dshpc-slate:#475569;\n --dshpc-slate-hover:color-mix(in srgb,var(--dshpc-slate) 78%,#000000);\n --dshpc-slate-active:color-mix(in srgb,var(--dshpc-slate) 64%,#000000);\n --dshpc-slate-soft:color-mix(in srgb,var(--dshpc-slate) 8%,transparent);\n\n /* ⚠️ 2026-10-18 用户拍板:宿主 alias 的 hover(暗色白 8% / 亮色 6%)**太弱**,\n 「移上去要仔细看才看得出来」⇒ 不再委托宿主 hover 别名,改为自掺中性色并加重:\n 亮色掺黑 10%、暗色掺白 14%(active 再加一档)。按钮 / 分段轨道 / 各类 hover 底同时受益。\n ⚠️ 必须保留 rgba 兜底行在前(本文件惯例,见 icon-plate 注释):掺的是**固定中性色**\n (neutral-900=#0f0f0f / neutral-00=#fff),预计算无损;旧内核不认 color-mix 时走兜底,\n 否则整条 background:var(--seg-track) 作废 ⇒ 分段轨道透明(真踩过:预览站轨道消失)。 */\n --dshpc-hover:rgba(15,15,15,.10);\n --dshpc-active:rgba(15,15,15,.18);\n /* 分段控件轨道底:专用 token(rgba 字面量、不借 --dshpc-hover 中转)——\n 2026-10-19 教训:变量链中间任何一环 invalid ⇒ background 整条作废、轨道全透明。\n 亮色:黑 7%(比 hover 的 10% 淡一档,选中白片才跳得出)。 */\n --dshpc-seg-track:rgba(15,15,15,.07);\n --dshpc-mask:var(--dsw-alias-bg-mask-1,#0000003d);\n /* 「选中面」(2026-10-06,任务日程页首创)= 当前底色**朝更深掺 12% 文字色**:\n 浅色主题下文字色是黑 ⇒ 选中面比常态底色**深一档**。深色分支见 body[data-ds-dark-theme](朝背景色掺)。\n 语义:标记「正在看的东西」,比常态明显、又不许盖住内容(不许用半透明叠状态色)。 */\n --dshpc-selected-bg:color-mix(in srgb,var(--dshpc-surface-1) 88%,var(--dshpc-fg));\n /* 任务日程页本月格默认底(2026-10-06 → 续2):浅色下给**淡蓝**(business 8% 透白底)——\n 参照用户参考稿里未选中日程块 / Tuesday 列的那种蓝、再浅一点点;\n 相邻月补位格仍走 --dshpc-surface-2(更灰),不受影响。\n 深色段维持 #23262e(用户:深色 UI 已差不多,不动)。 */\n --dshpc-cal-cell-bg:color-mix(in srgb,var(--dshpc-business) 8%,var(--dshpc-surface-1));\n /* 任务日程页「点开某天」展开的面板底(2026-10-06 续):浅色下**无限接近白、只带一丁点灰**\n (neutral-50 = #fafafa)——面板里装半透明执行记录列表,底再深整片就发糊发灰;\n 深色段沿用原 selected-bg 暗值,保持不动。 */\n --dshpc-cal-panel-bg:var(--dsw-static-neutral-50,#fafafa);\n /* 任务日程页本月格 hover 底(浅色段,2026-10-06 续3):不再走灰色通用交互底——\n 鼠标移上去应是「更亮一点点的蓝」(与深色段同语义:hover = 提亮的蓝,不是灰下去)。\n 浓度**介于**表头蓝(14%)与未选中格蓝(8%)之间、略偏表头一侧:business 12% 透白底\n (比表头浅一点、比未选中格深一点)。 */\n --dshpc-cal-cell-hover:color-mix(in srgb,var(--dshpc-business) 12%,var(--dshpc-surface-1));\n\n /* ── 投影 / 焦点 ──────────────────────────────────────────────────── */\n --dshpc-shadow-1:var(--dsw-elevation-soft,0 4px 16px 0 #00000008);\n /* 亮片自带的浮起感(选中态用;与 --dshpc-surface-raised 配对) */\n --dshpc-shadow-raised:var(--dsw-elevation-soft,0 4px 16px 0 #00000008);\n --dshpc-shadow-2:var(--dsw-shadow-lv3,0 12px 32px 0 #00000014);\n /* 键盘焦点环。⚠️ 不用宿主 --dsw-focus-ring-color:它默认值是 transparent(兜底不生效、会隐身) */\n --dshpc-focus:var(--dsw-alias-state-business-primary,#3b5bdb);\n\n /* ── 圆角(宿主真值 4 / 8 / 12 / 16 / 20 / 28)─────────────────────── */\n --dshpc-radius-xs:var(--dsw-radius-xs,4px);\n --dshpc-radius-sm:var(--dsw-radius-sm,8px);\n --dshpc-radius-md:var(--dsw-radius-md,12px);\n --dshpc-radius-lg:var(--dsw-radius-lg,16px);\n --dshpc-radius-xl:var(--dsw-radius-xl,20px);\n --dshpc-radius-panel:var(--dsw-radius-panel,28px);\n /* 全圆(胶囊标签):宿主的 radius 档最大只有 28px,撑不满 24px 高的 chip */\n --dshpc-radius-pill:999px;\n\n /* ── 间距四拍(只许用这四档,不许出现 5 / 7 / 9px)────────────────── */\n --dshpc-space-1:4px;\n --dshpc-space-2:8px;\n --dshpc-space-3:12px;\n --dshpc-space-4:16px;\n\n /* ── 控件高度:离散三档(控件用 size=\"sm|md|lg\" 选;调用点不许自定义高度,\n 真不够用才允许在调用点本地覆盖 --dshpc-control-h-*,属例外而非常态)── */\n --dshpc-control-h-sm:24px;\n --dshpc-control-h-md:28px;\n --dshpc-control-h-lg:32px;\n\n /* ── 字号 / 行高:直绑宿主字号族(宿主真值 11 / 12 / 13 / 14 / 16)───── */\n --dshpc-font-xs:var(--dsw-font-xxxs-11-font-size,11px);\n --dshpc-font-sm:var(--dsw-font-xxs-12-font-size,12px);\n --dshpc-font-md:var(--dsw-font-xs-13-font-size,13px);\n --dshpc-font-lg:var(--dsw-font-s-14-font-size,14px);\n --dshpc-font-xl:var(--dsw-font-base-16-font-size,16px);\n --dshpc-line-xs:var(--dsw-font-xxxs-11-line-height,14px);\n --dshpc-line-sm:var(--dsw-font-xxs-12-line-height,18px);\n --dshpc-line-md:var(--dsw-font-xs-13-line-height,20px);\n --dshpc-line-lg:var(--dsw-font-s-14-line-height,22px);\n --dshpc-line-xl:var(--dsw-font-base-16-line-height,24px);\n --dshpc-font-mono:var(--ds-font-family-code,monospace);\n\n /* ── 层级阶梯(业务文件不许再写裸 z-index)───────────────────────── */\n /* 页面级预览分栏 → 抽屉(新建/编辑)→ 弹窗/确认框 → 浮层菜单 → 浮层提示 */\n /* 内容层吸顶(天标签 / 表头这类「跟着滚但压住同层内容」的元素):只压同层兄弟,\n 必须低于下面所有浮层档 —— 所以它不是「开新浮层档」,而是内容层内部的排序位。 */\n --dshpc-z-sticky:10;\n --dshpc-z-dock:1030;\n --dshpc-z-drawer:1040;\n --dshpc-z-modal:1070;\n --dshpc-z-menu:1100;\n --dshpc-z-tip:1200;\n\n /* ── 动效 ─────────────────────────────────────────────────────────── */\n --dshpc-dur:var(--ds-transition-duration,.2s);\n --dshpc-dur-fast:var(--ds-transition-duration-fast,.12s);\n --dshpc-ease:var(--ds-ease-in-out,cubic-bezier(.4,0,.2,1));\n /* 运行中状态的脉动时长(2026-10-06 统一前后两端:任务配置里的绿呼吸 → 蓝、放慢;\n 执行记录里的蓝闪 → 放慢一点。两者用同一个值,动画形状本就一致)。 */\n --dshpc-dur-run:500ms;\n}\n\n/* ── 明暗差异的**唯一**落点 ──────────────────────────────────────────────\n 判据 = body[data-ds-dark-theme](宿主 0.2.0-rc.2 源码核实:启动脚本 toggleAttribute 写入,\n 唯一明暗判据;插件禁止用 prefers-color-scheme —— 它跟的是系统、不是用户在宿主里的选择)。\n 下面只放 alias 表达不了的「固定中性面」;颜色若能靠 alias 自动跟随,一律不要写在这里。 */\nbody[data-ds-dark-theme]{\n /* 深色段的蓝**刻意不跟随宿主 alias**(唯一例外):宿主暗色 alias 给的是 #60a5fa 一档的高亮蓝,\n 实心面(Chip / Button info / 日期选中格)压白字会发糊 —— 用户 2026-10-29 实测反馈。\n ⇒ 深色下改定向浅色状态的蓝(#3b5bdb)靠,只在明度上抬一点点,保证它在暗底上仍看得见:\n #4c6bd8 对白字 ≈4.8:1(原亮蓝只有 ~2.3:1),对日历格底 ≈3.2:1 仍过 UI 件的 3:1 线。\n 代价:宿主换品牌色时深色不再自动跟着变,需要这里手动同步。 */\n --dshpc-business:#4c6bd8;\n --dshpc-solid:var(--dsw-static-neutral-900,#0f0f0f);\n --dshpc-on-solid:var(--dsw-static-neutral-00,#fff);\n /* 实心按钮 hover / active(暗色版):黑底(浅色主题的近黑 → 暗色下的近白)掺黑压深;\n 红 / 绿 / 黄 / 蓝掺白提亮。与亮色段方向相反,保证两种主题下「一眼看出变了」。 */\n --dshpc-accent-hover:color-mix(in srgb,var(--dshpc-accent) 80%,#000000);\n --dshpc-accent-active:color-mix(in srgb,var(--dshpc-accent) 66%,#000000);\n --dshpc-danger-hover:color-mix(in srgb,var(--dshpc-danger) 78%,#ffffff);\n --dshpc-danger-active:color-mix(in srgb,var(--dshpc-danger) 64%,#ffffff);\n --dshpc-success-hover:color-mix(in srgb,var(--dshpc-success) 78%,#ffffff);\n --dshpc-success-active:color-mix(in srgb,var(--dshpc-success) 64%,#ffffff);\n --dshpc-warning-hover:color-mix(in srgb,var(--dshpc-warning) 78%,#ffffff);\n --dshpc-warning-active:color-mix(in srgb,var(--dshpc-warning) 64%,#ffffff);\n /* 同上:掺白比例从 22% / 36% 收到 12% / 22% —— 底色已变深,照旧比例提亮会在 hover 瞬间\n 把白字对比打回 ~3:1(正是用户嫌糊的那一档);收窄后 hover 仍可感知、字仍清晰。 */\n --dshpc-business-hover:color-mix(in srgb,var(--dshpc-business) 88%,#ffffff);\n --dshpc-business-active:color-mix(in srgb,var(--dshpc-business) 78%,#ffffff);\n /* 暗色 hover 掺白 14% / active 24%(对齐上面 2026-10-18 的加重拍板)。rgba 兜底行同上。 */\n --dshpc-hover:rgba(255,255,255,.14);\n --dshpc-active:rgba(255,255,255,.24);\n /* 分段轨道(暗色版):白 10%——比 hover 淡一档,选中亮片才跳得出。 */\n --dshpc-seg-track:rgba(255,255,255,.10);\n --dshpc-plate:var(--dsw-static-neutral-850,#212123);\n --dshpc-plate-hover:var(--dsw-static-neutral-800,#292929);\n --dshpc-icon-plate:rgba(255,255,255,.05);\n /* 暗色主题**反过来**:表头要比卡片面**亮**、比斑马纹再**浅一档**(用户:纯黑背景没法看)。 */\n --dshpc-head-bg:var(--dshpc-surface-2);\n /* 暗色底板**微亮**;hover **更亮**(原先 hover 取 plate-hover 反而更淡 ⇒ 鼠标移上去就没了)。 */\n --dshpc-chip-bg:rgba(255,255,255,.08);\n --dshpc-chip-bg-hover:rgba(255,255,255,.16);\n /* 暗色下蓝色要更亮、透明度略高才压得住深底。 */\n --dshpc-open-bg:rgba(96,165,250,.18);\n --dshpc-open-bg-soft:rgba(96,165,250,.08);\n --dshpc-card-hover:rgba(96,165,250,.13);\n /* 语义色**浅底**(深色版):用户嫌深色的绿 / 红「有点深」⇒ 压到 **5%**(浅色段是 8%),\n 更贴近面板底色、存在感更弱;块底与状态色竖条仍同源(竖条是实色,不受这条影响)。 */\n --dshpc-success-soft:color-mix(in srgb,var(--dshpc-success) 5%,transparent);\n --dshpc-warning-soft:color-mix(in srgb,var(--dshpc-warning) 5%,transparent);\n --dshpc-danger-soft:color-mix(in srgb,var(--dshpc-danger) 5%,transparent);\n --dshpc-business-soft:color-mix(in srgb,var(--dshpc-business) 5%,transparent);\n /* 扩展色深色派生:底色写死、hover 掺白 12%/22%(同 business,防白字发糊),soft 5%。 */\n --dshpc-purple-hover:color-mix(in srgb,var(--dshpc-purple) 88%,#ffffff);\n --dshpc-purple-active:color-mix(in srgb,var(--dshpc-purple) 78%,#ffffff);\n --dshpc-purple-soft:color-mix(in srgb,var(--dshpc-purple) 5%,transparent);\n --dshpc-pink-hover:color-mix(in srgb,var(--dshpc-pink) 88%,#ffffff);\n --dshpc-pink-active:color-mix(in srgb,var(--dshpc-pink) 78%,#ffffff);\n --dshpc-pink-soft:color-mix(in srgb,var(--dshpc-pink) 5%,transparent);\n --dshpc-cyan-hover:color-mix(in srgb,var(--dshpc-cyan) 88%,#ffffff);\n --dshpc-cyan-active:color-mix(in srgb,var(--dshpc-cyan) 78%,#ffffff);\n --dshpc-cyan-soft:color-mix(in srgb,var(--dshpc-cyan) 5%,transparent);\n --dshpc-teal-hover:color-mix(in srgb,var(--dshpc-teal) 88%,#ffffff);\n --dshpc-teal-active:color-mix(in srgb,var(--dshpc-teal) 78%,#ffffff);\n --dshpc-teal-soft:color-mix(in srgb,var(--dshpc-teal) 5%,transparent);\n --dshpc-orange-hover:color-mix(in srgb,var(--dshpc-orange) 88%,#ffffff);\n --dshpc-orange-active:color-mix(in srgb,var(--dshpc-orange) 78%,#ffffff);\n --dshpc-orange-soft:color-mix(in srgb,var(--dshpc-orange) 5%,transparent);\n --dshpc-indigo-hover:color-mix(in srgb,var(--dshpc-indigo) 88%,#ffffff);\n --dshpc-indigo-active:color-mix(in srgb,var(--dshpc-indigo) 78%,#ffffff);\n --dshpc-indigo-soft:color-mix(in srgb,var(--dshpc-indigo) 5%,transparent);\n --dshpc-rose-hover:color-mix(in srgb,var(--dshpc-rose) 88%,#ffffff);\n --dshpc-rose-active:color-mix(in srgb,var(--dshpc-rose) 78%,#ffffff);\n --dshpc-rose-soft:color-mix(in srgb,var(--dshpc-rose) 5%,transparent);\n --dshpc-slate-hover:color-mix(in srgb,var(--dshpc-slate) 88%,#ffffff);\n --dshpc-slate-active:color-mix(in srgb,var(--dshpc-slate) 78%,#ffffff);\n --dshpc-slate-soft:color-mix(in srgb,var(--dshpc-slate) 5%,transparent);\n /* 「选中面」(深色版,2026-10-06):掺 **~40% 背景色**(--dshpc-surface-base)⇒ 无限接近页面背景的黑、\n 只比背景略深一点点(用户:深色下展开区压着任务透明绿会发灰,底色要尽量贴近背景才不显灰)。\n ⚠️ 深色下不能掺文字色 —— 那是白,会变亮,选中反而比本月日期浅。 */\n --dshpc-selected-bg:color-mix(in srgb,var(--dshpc-surface-1) 60%,var(--dshpc-surface-base));\n /* 任务日程页本月格的默认底(深色版,2026-10-06):深的、带点灰蓝的暗色(用户给的参考图 ≈ #23262e),\n 比原来的卡片面更沉、更偏蓝灰;选中格仍走 --dshpc-selected-bg(更暗一档),层级不变。 */\n --dshpc-cal-cell-bg:#23262e;\n /* 任务日程页本月格 hover 底(深色段,2026-10-06):原先走 --dshpc-hover(宿主浅色叠加)在深底上显得\n 「灰发亮」,不好看 ⇒ 换成更贴底的蓝调微亮(与 open-bg-soft 同族),hover 时不刺眼、又有反馈。 */\n --dshpc-cal-cell-hover:rgba(96,165,250,.12);\n /* 任务日程页展开面板底(深色段,2026-10-06 续):与原 selected-bg 暗值一致,深色 UI 不动 */\n --dshpc-cal-panel-bg:color-mix(in srgb,var(--dshpc-surface-1) 60%,var(--dshpc-surface-base));\n}\n";
|
|
51
51
|
//#endregion
|
|
52
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
52
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/design/style-kit.js
|
|
53
53
|
/** 全生态统一的 CSS 变量前缀。 */
|
|
54
54
|
const CSS_PREFIX = "dshpc";
|
|
55
55
|
/** token 域固定名:变量定义必须先于消费它的规则出现。 */
|
|
@@ -120,82 +120,7 @@ window.__ModuleLoader__.load({
|
|
|
120
120
|
};
|
|
121
121
|
}
|
|
122
122
|
//#endregion
|
|
123
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
124
|
-
const SEGMENTED_CSS = "\n/* ── 分段控件 P2 ─────────────────────────────────────────────────────\n 结构照兄弟项目 dsh-task-dispatch-table 的 Segmented 皮肤(item 无边框、hover 只提亮文字),\n 前缀 / 变量名换成本仓口径。用户额外要的两处(兄弟没有):weekday 方块间隔(现为 2px);段内中性计数 __count。\n ⚠️ 2026-10-19 两次误判均已澄清:① 「宿主只认单行 CSS」——假,多行一直正常;\n ② 「宿主吃掉 token 块之后第一条规则」——也假,真因是 tokens 模板字符串结尾多了一个反斜杠,\n 注入文本里留下字面反引号,把紧随其后的那条规则的选择器污染掉了(见 dsh-host.md §9)。\n 样式照常多行书写,不必压行;也不需要任何「牺牲规则」。 */\n/* 外观只有一套(2026-10-26):原 variant 的 default / inset 两档在 CSS 里只差 1px 内距,\n 且 default 比文档承诺矮 2px,却让下游以为「有得选」而反复对图 ⇒ 整轴删除。\n padding 3px 是尺寸契约的一部分:item 高度 = 控制高 − 6px,加起来正好 24 / 28 / 32。 */\n/* 选中片配色收在两条局部变量里(--seg-thumb 底 / --seg-on 字):默认走主题亮片,\n tone 档与自定义 {bg, fg} 都只改这两条(后者由组件内联写根节点,内联恒胜)。 */\n.dshpc-seg{display:inline-flex;align-items:center;gap:2px;padding:3px;border-radius:var(--dshpc-radius-md);--seg-thumb:var(--dshpc-surface-raised);--seg-on:var(--dshpc-fg);background:var(--dshpc-seg-track);}\n.dshpc-seg__item{appearance:none;display:inline-flex;align-items:center;gap:4px;box-sizing:border-box;height:calc(var(--dshpc-control-h-sm) - 6px);padding:0 12px;border:0;border-radius:var(--dshpc-radius-sm);background:transparent;color:var(--dshpc-fg-2);font-family:inherit;font-size:var(--dshpc-font-xs);font-weight:500;white-space:nowrap;cursor:pointer;flex:none;transition:color var(--dshpc-dur-fast) var(--dshpc-ease),background-color var(--dshpc-dur-fast) var(--dshpc-ease),box-shadow var(--dshpc-dur-fast) var(--dshpc-ease);}\n.dshpc-seg--md .dshpc-seg__item{height:calc(var(--dshpc-control-h-md) - 6px);}\n.dshpc-seg--lg .dshpc-seg__item{height:calc(var(--dshpc-control-h-lg) - 6px);}\n.dshpc-seg__item:hover:not([aria-pressed='true']):not(:disabled){color:var(--dshpc-fg);}\n.dshpc-seg__item[aria-pressed='true']{background:var(--seg-thumb);box-shadow:var(--dshpc-shadow-raised);color:var(--seg-on);font-weight:600;}\n.dshpc-seg__item:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:-2px;}\n.dshpc-seg__item:disabled{cursor:default;opacity:.4;}\n/* 段内角标(如「异常」的数量):语义色实面 + 反白字,0 由组件侧不渲染。必须是正圆(用户 2026-10-03)。 */\n.dshpc-seg__badge{display:inline-flex;align-items:center;justify-content:center;flex:none;width:16px;height:16px;padding:0;overflow:hidden;border-radius:50%;background:var(--dshpc-danger);color:var(--dshpc-on-signal);font-size:10px;line-height:16px;font-weight:500;font-variant-numeric:tabular-nums;}\n/* 段内中性计数(如筛选条「全部 11」):纯文字、无底无边(对齐 task-ledger .dtl-seg__num 拍板口径);0 由组件侧不渲染。 */\n.dshpc-seg__count{display:inline;flex:none;margin-left:3px;padding:0;border:0;border-radius:0;background:none;color:var(--dshpc-fg-3);font-size:10px;line-height:1;font-weight:400;font-variant-numeric:tabular-nums;}\n/* block:撑满父宽(表单行用),各段等分 */\n.dshpc-seg--block{display:flex;width:100%;}\n.dshpc-seg--block .dshpc-seg__item{flex:1 1 auto;justify-content:center;}\n/* weekday:星期多选方块。基础插件的特殊化定制(用户 2026-10-01:原 WeekdayPicker 即「蓝底 + 近似方形」):\n 每格正方形(宽 = 段高)、选中品牌蓝反白字、**无外描边**(2026-10-18 重申)、\n 方块之间间距 gap:2px(2026-10-20 用户定稿:方块改小后 6px 显得太宽。10-18 曾从 2px 放宽到 6px,\n 两次都是用户拍板 —— 别自作主张改回去)。 */\n.dshpc-seg--weekday{--seg-track:var(--dshpc-seg-track);gap:2px;border:0;padding:3px;background:var(--seg-track);}\n.dshpc-seg--weekday .dshpc-seg__item{width:calc(var(--dshpc-control-h-lg) - 8px);padding:0;justify-content:center;}\n/* 蓝底反白:字色必须是常量白(--dshpc-on-signal)。2026-10-29 用户实测:暗色主题下这里曾用\n --dshpc-fg-inverse,而它跟随宿主 label-primary-foreground,暗色下是近黑 ⇒ 蓝底黑字看不清。 */\n.dshpc-seg--weekday{--seg-thumb:var(--dshpc-business);--seg-on:var(--dshpc-on-signal);}\n\n/* ── tone(2026-10-29 用户):选中片传内置基础色名,底 / 字由核心给,深浅两主题各自成立。\n 放在 weekday 之后:同名变量后写者胜,tone 与 className=\"dshpc-seg--weekday\" 同给时以 tone 为准。\n 黄底按 Chip / Button 同源口径用 on-warning(中高明度,白字看不清)。 */\n.dshpc-seg--tone-business{--seg-thumb:var(--dshpc-business);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-success{--seg-thumb:var(--dshpc-success);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-warning{--seg-thumb:var(--dshpc-warning);--seg-on:var(--dshpc-on-warning);}\n.dshpc-seg--tone-danger{--seg-thumb:var(--dshpc-danger);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-purple{--seg-thumb:var(--dshpc-purple);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-pink{--seg-thumb:var(--dshpc-pink);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-cyan{--seg-thumb:var(--dshpc-cyan);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-teal{--seg-thumb:var(--dshpc-teal);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-orange{--seg-thumb:var(--dshpc-orange);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-indigo{--seg-thumb:var(--dshpc-indigo);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-rose{--seg-thumb:var(--dshpc-rose);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-slate{--seg-thumb:var(--dshpc-slate);--seg-on:var(--dshpc-on-signal);}\n\n/* ── 单选滑动块(2026-10-26 用户:点选后选中底应「滑过去」,不是旧段消失、新段直接亮)。\n 结构 = 一块绝对定位的共用底 + 各段透明;位置/尺寸由组件量出后内联,这里只管外观与过渡。\n --slide 只在单选挂上:多选(如星期)每段各自着色,没有唯一滑块可滑,保持原样。 */\n.dshpc-seg--slide{position:relative;}\n.dshpc-seg--slide .dshpc-seg__item{position:relative;z-index:1;}\n.dshpc-seg--slide .dshpc-seg__item[aria-pressed='true']{background:transparent;box-shadow:none;}\n.dshpc-seg__thumb{position:absolute;z-index:0;border-radius:var(--dshpc-radius-sm);background:var(--seg-thumb);box-shadow:var(--dshpc-shadow-raised);pointer-events:none;transition:left var(--dshpc-dur) var(--dshpc-ease),top var(--dshpc-dur) var(--dshpc-ease),width var(--dshpc-dur) var(--dshpc-ease),height var(--dshpc-dur) var(--dshpc-ease);}\n\n/* ── bordered 外框(2026-10-20 用户要的第二种模式):**只在最外面套一圈 1px 描边**,\n 里面一概不动 —— 选中片的填充色 / 阴影 / 文字色全部保持原样(weekday 的蓝面照旧),\n 这里不写任何针对 __item 的规则。\n 总高必须与无框版逐像素一致:border 1px×2 由 padding 各让 1px 抵消(3 → 2);\n weekday 自己声明的 3px 在文件更后面,靠双类选择器压回 2px。 */\n.dshpc-seg--bordered{border:1px solid var(--dshpc-border);padding:2px;}\n.dshpc-seg--bordered.dshpc-seg--weekday{padding:2px;}\n\n@media (prefers-reduced-motion: reduce){.dshpc-seg__item{transition:none;}.dshpc-seg__thumb{transition:none;}}\n";
|
|
125
|
-
//#endregion
|
|
126
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/controls/button-css.generated.js
|
|
127
|
-
const BUTTON_CSS = "\n/* ── 按钮 / 图标钮 P2 ───────────────────────────────────────────────────\n 与 Segmented 同一条高度纪律:--dshpc-control-h-sm(24) / -md(28) / -lg(32),\n 有边框的 variant 用 1px 真边框 + 内部 padding 补回,**有边 / 无边同高**。\n\n 三条受控轴(2026-10-19 重写,对齐主流 UI 框架的分类口径):\n · variant —— 外观档 = 形态 + 语义色,共 10 档:\n primary / secondary / outline / ghost / danger / success / warning / info /\n danger-outline(红字描边)/ link(行内链接)\n · size —— sm / md / lg\n · block —— 撑满父宽\n 每一档**只填 5 个局部变量**(--btn-bg / -fg / -border / -bg-hover / -bg-active),\n 结构与交互只有上面这一份;任何档位都不许再写一遍 display/height/padding。\n 自定义颜色(Button 的 color 参数)同样只覆盖这 5 个变量(token 覆盖,不是新皮肤)。\n\n ⚠️ hover 不再用 opacity 压一层(用户 2026-10-19:「黑色和红色的按钮移上去变化太小,\n 完全感觉不到颜色变了」)⇒ 走 --dshpc-*-hover / -active 的明确混色,见 tokens-css.ts。 */\n.dshpc-btn{--btn-bg:transparent;--btn-fg:var(--dshpc-fg);--btn-border:transparent;--btn-pad:12px;\n --btn-bg-hover:var(--dshpc-hover);--btn-bg-active:var(--dshpc-active);--btn-fg-hover:var(--btn-fg);\n appearance:none;display:inline-flex;align-items:center;justify-content:center;gap:6px;\n box-sizing:border-box;border:1px solid var(--btn-border);border-radius:var(--dshpc-radius-md);\n background-color:var(--btn-bg);color:var(--btn-fg);font-family:inherit;font-weight:500;white-space:nowrap;cursor:pointer;\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),border-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease),box-shadow var(--dshpc-dur-fast) var(--dshpc-ease),transform var(--dshpc-dur-fast) var(--dshpc-ease);}\n.dshpc-btn--sm{--btn-pad:10px;height:var(--dshpc-control-h-sm);padding:0 var(--btn-pad);font-size:var(--dshpc-font-sm);line-height:1;}\n.dshpc-btn--md{--btn-pad:12px;height:var(--dshpc-control-h-md);padding:0 var(--btn-pad);font-size:var(--dshpc-font-md);line-height:1;}\n.dshpc-btn--lg{--btn-pad:14px;height:var(--dshpc-control-h-lg);padding:0 var(--btn-pad);font-size:var(--dshpc-font-md);line-height:1;}\n/* block:撑满父宽(表单底栏 / 抽屉底部的主操作) */\n.dshpc-btn--block{display:flex;width:100%;}\n/* block + 前置图标 ⇒ 文字视觉居中(2026-10-19 用户点名):\n 内容组 [图标 + 间距 + 文字] 整体在盒内居中时,**文字**的中心会被图标推右半格。\n 把右内边距补上「图标宽 + 间距」,可用盒随之左移同量 ⇒ 文字落回视觉中心,图标贴左侧。\n 图标宽按 1.2em 估(官方图标 14/16px vs 字号 12/13px),em 随字号档自动缩放。 */\n.dshpc-btn--block.dshpc-btn--icon-start{padding-right:calc(var(--btn-pad) + 1.2em + 6px);}\n.dshpc-btn__icon,.dshpc-btn__icon-end{display:inline-flex;align-items:center;justify-content:center;flex:none;line-height:0;}\n.dshpc-btn__icon svg,.dshpc-btn__icon-end svg{display:block;margin:0;}\n/* maxWidth 包 MarqueeText 时:标签作为 flex 子项必须能收缩到内容以下,否则省略号 / 跑马灯测不准 */\n.dshpc-btn .dshpc-btn__label{min-width:0;}\n/* loading:不换 DOM 结构,只在文案前插一个同色小圈。\n ⚠️ 2026-10-20 改画法:原来是 border:1.5px 加 border-radius:999px 画的环 —— 真机实测 computed\n radius 就是 999px、宽高都是 12px(没被任何样式覆盖),看着却\"像圆角方\",原因是**次像素边框\n (1.5px)在 12px 这么小的圆上被抗锯齿插值拉毛**。改用 SVG 矢量弧:任意 DPR 下都是真圆。 */\n.dshpc-btn__spinner{display:block;flex:none;width:12px;height:12px;\n animation:dshpc-btn-spin .7s linear infinite;}\n/* shortcut: 12px 是固定值,不随按钮字号缩放;要更大就改这一处。 */\n@keyframes dshpc-btn-spin{to{transform:rotate(360deg)}}\n\n/* 交互态:颜色变化写在变量上 ⇒ 所有档位一次生效,且变化幅度由 token 决定(够明显) */\n.dshpc-btn:hover:not(:disabled){background-color:var(--btn-bg-hover);color:var(--btn-fg-hover);}\n.dshpc-btn:active:not(:disabled){background-color:var(--btn-bg-active);transform:translateY(1px);}\n.dshpc-btn:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:2px;}\n.dshpc-btn:disabled{cursor:default;opacity:.5;}\n\n.dshpc-btn--primary{--btn-bg:var(--dshpc-accent);--btn-fg:var(--dshpc-fg-inverse);\n --btn-bg-hover:var(--dshpc-accent-hover);--btn-bg-active:var(--dshpc-accent-active);}\n/* secondary:中性实心(灰面),用于「取消 / 次要」这类与主操作并排的按钮 */\n.dshpc-btn--secondary{--btn-bg:var(--dshpc-hover);--btn-fg:var(--dshpc-fg);\n --btn-bg-hover:var(--dshpc-active);--btn-bg-active:var(--dshpc-active);}\n.dshpc-btn--outline{--btn-bg:var(--dshpc-surface-1);--btn-border:var(--dshpc-border-strong);\n --btn-bg-hover:var(--dshpc-hover);--btn-bg-active:var(--dshpc-active);}\n.dshpc-btn--ghost{--btn-fg:var(--dshpc-fg-2);--btn-fg-hover:var(--dshpc-fg);\n --btn-bg-hover:var(--dshpc-hover);--btn-bg-active:var(--dshpc-active);}\n.dshpc-btn--danger{--btn-bg:var(--dshpc-danger);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-danger-hover);--btn-bg-active:var(--dshpc-danger-active);}\n.dshpc-btn--success{--btn-bg:var(--dshpc-success);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-success-hover);--btn-bg-active:var(--dshpc-success-active);}\n.dshpc-btn--warning{--btn-bg:var(--dshpc-warning);--btn-fg:var(--dshpc-on-warning);\n --btn-bg-hover:var(--dshpc-warning-hover);--btn-bg-active:var(--dshpc-warning-active);}\n.dshpc-btn--info{--btn-bg:var(--dshpc-business);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-business-hover);--btn-bg-active:var(--dshpc-business-active);}\n/* 扩展八色实心(2026-10-29):白字两主题均 ≥4.5:1;hover/active 走各自 token 派生。 */\n.dshpc-btn--purple{--btn-bg:var(--dshpc-purple);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-purple-hover);--btn-bg-active:var(--dshpc-purple-active);}\n.dshpc-btn--pink{--btn-bg:var(--dshpc-pink);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-pink-hover);--btn-bg-active:var(--dshpc-pink-active);}\n.dshpc-btn--cyan{--btn-bg:var(--dshpc-cyan);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-cyan-hover);--btn-bg-active:var(--dshpc-cyan-active);}\n.dshpc-btn--teal{--btn-bg:var(--dshpc-teal);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-teal-hover);--btn-bg-active:var(--dshpc-teal-active);}\n.dshpc-btn--orange{--btn-bg:var(--dshpc-orange);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-orange-hover);--btn-bg-active:var(--dshpc-orange-active);}\n.dshpc-btn--indigo{--btn-bg:var(--dshpc-indigo);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-indigo-hover);--btn-bg-active:var(--dshpc-indigo-active);}\n.dshpc-btn--rose{--btn-bg:var(--dshpc-rose);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-rose-hover);--btn-bg-active:var(--dshpc-rose-active);}\n.dshpc-btn--slate{--btn-bg:var(--dshpc-slate);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-slate-hover);--btn-bg-active:var(--dshpc-slate-active);}\n/* danger-outline:红字描边(破坏性次要操作,如卡片上的「删除」)。\n ⚠️ 旧修饰类 danger-ink 保留为别名(消费方可能还在挂),两者同一套皮肤。 */\n.dshpc-btn--danger-outline,.dshpc-btn--danger-ink{--btn-border:var(--dshpc-danger);--btn-fg:var(--dshpc-danger);\n --btn-fg-hover:var(--dshpc-danger);--btn-bg-hover:var(--dshpc-danger-soft);--btn-bg-active:var(--dshpc-danger-soft);}\n/* link:行内文字链接型(会话 / 产出文件名),无底无边、品牌蓝、hover 下划线 */\n.dshpc-btn--link{--btn-fg:var(--dshpc-link);--btn-fg-hover:var(--dshpc-link);\n --btn-bg-hover:transparent;--btn-bg-active:transparent;\n height:auto;padding:0;border:0;background:none;font-weight:400;text-align:left;}\n.dshpc-btn--link:hover:not(:disabled){text-decoration:underline;}\n\n/* 图标钮:纯图标,方形;尺寸档的宽高与同档文字按钮等高、圆角统一吃 md(与 .dshpc-btn 同款,2026-10-28 拍板) */\n.dshpc-iconbtn{appearance:none;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;\n border:1px solid transparent;border-radius:var(--dshpc-radius-md);background:transparent;color:var(--dshpc-fg-2);\n font-family:inherit;cursor:pointer;flex:none;\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),border-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease),opacity var(--dshpc-dur-fast) var(--dshpc-ease);}\n.dshpc-iconbtn--sm{width:var(--dshpc-control-h-sm);height:var(--dshpc-control-h-sm);font-size:var(--dshpc-font-sm);}\n.dshpc-iconbtn--md{width:var(--dshpc-control-h-md);height:var(--dshpc-control-h-md);font-size:var(--dshpc-font-md);}\n.dshpc-iconbtn--lg{width:var(--dshpc-control-h-lg);height:var(--dshpc-control-h-lg);font-size:var(--dshpc-font-md);}\n.dshpc-iconbtn--plain{color:var(--dshpc-fg-2);}\n.dshpc-iconbtn--outline{background:var(--dshpc-surface-1);border-color:var(--dshpc-border);color:var(--dshpc-fg-2);}\n.dshpc-iconbtn--danger{color:var(--dshpc-danger);}\n.dshpc-iconbtn:hover:not(:disabled){background:var(--dshpc-hover);color:var(--dshpc-fg);}\n.dshpc-iconbtn--danger:hover:not(:disabled){background:var(--dshpc-danger-soft);color:var(--dshpc-danger);}\n.dshpc-iconbtn:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:2px;}\n.dshpc-iconbtn:disabled{cursor:default;opacity:.4;}\n\n/* ── 行式文件按钮(图标 + 文件名)P2:**全站唯一实现**(2026-10-04 收编)──────────\n 用途:「产出物 / 附件」那种**一行一个文件**的清单项(基础信息右栏产出物清单、附件区、\n 执行记录页的展开区)。平时透明、**鼠标移上去才出浅底**(沿用用户 2026-10-03 定的观感)。\n 两个形态修饰类:\n --block 撑满父宽(清单里一项一行)\n --inline 内容宽(跟在文字后头,如附件行)\n 收编原因:这份皮肤此前只写在 task-list.tsx 的 TASK_LIST_CSS 里(旧名 .dshpc-info-out),\n 执行记录页展开区要用同一种观感 ⇒ 上提基础层,避免再出现「各写一份外观」(同名不同皮的坑刚踩过)。 */\n.dshpc-filechip{appearance:none;-webkit-appearance:none;border:0;border-radius:var(--dshpc-radius-xs);\n background:transparent;color:var(--dshpc-fg);font:inherit;text-align:left;cursor:pointer;min-width:0;\n transition:background-color var(--dshpc-dur) var(--dshpc-ease);}\n.dshpc-filechip:hover:not(:disabled){background:var(--dshpc-chip-bg);}\n.dshpc-filechip:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px;}\n.dshpc-filechip:disabled{cursor:default;background:transparent;color:var(--dshpc-fg-3);}\n.dshpc-filechip--block{display:flex;align-items:center;gap:6px;width:100%;box-sizing:border-box;\n padding:4px 6px;font-size:var(--dshpc-font-xs);}\n.dshpc-filechip--inline{display:inline-flex;align-items:center;gap:4px;padding:2px 6px;font-size:var(--dshpc-font-sm);}\n\n@media (prefers-reduced-motion: reduce){.dshpc-btn,.dshpc-iconbtn,.dshpc-filechip{transition:none;}}\n";
|
|
128
|
-
//#endregion
|
|
129
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/controls/field-css.generated.js
|
|
130
|
-
const FIELD_CSS = "\n/* ── 字段 + 问号提示(hint 参数内置) ──────────────────────────────────── */\n/* 控件 + FieldHint 同一行;hint 版由组件自己包,调用方只传 hint 字符串。\n 铺满型控件(input/textarea)进包后改吃 flex 弹性,让位给问号。 */\n.dshpc-fieldwrap{display:flex;align-items:center;gap:6px;min-width:0;max-width:100%;}\n.dshpc-fieldwrap--inline{display:inline-flex;}\n.dshpc-fieldwrap > .dshpc-input,.dshpc-fieldwrap > .dshpc-textarea,.dshpc-fieldwrap > .dshpc-iwrap{flex:1 1 auto;width:auto;min-width:0;}\n/* 多行输入:问号钉在**右下角**(2026-10-20 用户:不要垂直居中),文本区底部留出它的位置。\n ⚠️ 这一档必须把 textarea 的宽度还回去(上面那条 flex 让位规则会把它缩窄)。 */\n.dshpc-fieldwrap--block{position:relative;display:block;}\n.dshpc-fieldwrap--block > .dshpc-textarea{width:100%;padding-bottom:24px;}\n.dshpc-fieldwrap--block > .dshpc-hint{position:absolute;right:8px;bottom:6px;}\n\n/* ── 输入类 P3 ────────────────────────────────────────────────────────── */\n/* 默认铺满容器(width:100%,与 .dshpc-textarea 同口径):input 原生按 size 属性取内在宽,\n 不铺满 ⇒ 调用方套定宽壳时会「右边空一截、看着没贴右」(2026-10-20 用户抓的 bug)。\n 要定宽由调用方在外面套壳控制(如 192px 搜索槽)。 */\n.dshpc-input{display:block;width:100%;box-sizing:border-box;border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);\n background:var(--dshpc-surface-1);color:var(--dshpc-fg);font-family:inherit;outline:none;\n transition:border-color var(--dshpc-dur-fast) var(--dshpc-ease),box-shadow var(--dshpc-dur-fast) var(--dshpc-ease);}\n.dshpc-input--sm{height:var(--dshpc-control-h-sm);padding:0 8px;font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);}\n.dshpc-input--md{height:var(--dshpc-control-h-md);padding:0 10px;font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}\n.dshpc-input--lg{height:var(--dshpc-control-h-lg);padding:0 12px;font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}\n.dshpc-input::placeholder{color:var(--dshpc-fg-dim);}\n/* type=\"search\":原生清除钮(::-webkit-search-cancel-button)整个隐掉,换组件自己挂的 plain IconButton\n —— 原生那个各子系统长相不一、还不吃 token(2026-10-28 用户:不好看,要数字框加减号那种)。 */\n.dshpc-iwrap .dshpc-input::-webkit-search-cancel-button{display:none;}\n.dshpc-input:focus{border-color:var(--dshpc-focus);box-shadow:0 0 0 1px var(--dshpc-focus);}\n.dshpc-input--error{border-color:var(--dshpc-danger);}\n.dshpc-input:disabled{cursor:default;opacity:.5;}\n\n/* 左侧图标槽(Input 的 icon 参数):图标绝对定位压在输入框的左内边距上,\n 输入框自己的边框 / 焦点圈 / 描红一律不动。图标不吃点击(pointer-events:none)⇒ 点在图标上照样聚焦。\n 左内边距 = 左偏 8 + 图标宽(sm 14 / md·lg 16,见 fieldMetricsOf)+ 间距 4。 */\n.dshpc-iwrap{position:relative;display:block;width:100%;min-width:0;}\n.dshpc-iwrap__icon{position:absolute;left:8px;top:50%;transform:translateY(-50%);display:inline-flex;pointer-events:none;color:var(--dshpc-fg-2);}\n.dshpc-iwrap--sm > .dshpc-input{padding-left:26px;}\n.dshpc-iwrap--md > .dshpc-input,.dshpc-iwrap--lg > .dshpc-input{padding-left:28px;}\n/* 禁用时图标跟输入框一起变淡(输入框自己已有 opacity:.5,图标不在它里面,得单独跟一下)。 */\n.dshpc-iwrap:has(> .dshpc-input:disabled) > .dshpc-iwrap__icon{opacity:.5;}\n\n/* 搜索框的清空钮(Field.ts 在「有焦点 + 有内容」时才挂出来):**并进框里**,与数字框的 − / +\n 同形态 —— 整段同高、左直右圆、hover 底色铺满这一格(2026-10-28 用户:不要一颗悬在右边的小按钮)。\n 向内让 1px,免得底色压住输入框自己的边框。 */\n.dshpc-iwrap__clear.dshpc-iconbtn{position:absolute;right:1px;top:1px;bottom:1px;height:auto;width:auto;aspect-ratio:1;\n border-radius:0 var(--dshpc-radius-md) var(--dshpc-radius-md) 0;font-size:var(--dshpc-font-md);}\n/* height:auto 必须:iconbtn--md/lg 的固定 height 会让 absolute 的 bottom 被忽略\n (top:1 + 固定高 ⇒ 整钮错位 1px,× 显得没居中,2026-10-28 用户截图抓的)。 */\n/* 文字让开这一段(宽度 = 控件高 - 2,故按档位补)。 */\n.dshpc-iwrap--clear > .dshpc-input{padding-right:calc(var(--dshpc-control-h-md) + 3px);}\n.dshpc-iwrap--clear.dshpc-iwrap--sm > .dshpc-input{padding-right:calc(var(--dshpc-control-h-sm) + 3px);}\n.dshpc-iwrap--clear.dshpc-iwrap--lg > .dshpc-input{padding-right:calc(var(--dshpc-control-h-lg) + 3px);}\n\n.dshpc-pfx{display:inline-flex;align-items:center;box-sizing:border-box;overflow:hidden;\n border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);background:var(--dshpc-surface-1);color:var(--dshpc-fg);}\n.dshpc-pfx--sm{height:var(--dshpc-control-h-sm);}\n.dshpc-pfx--md{height:var(--dshpc-control-h-md);}\n.dshpc-pfx--lg{height:var(--dshpc-control-h-lg);}\n/* md / lg 档字号跟档走(与同档下拉同字号):此前写死 sm(12px),同排下拉是 13px ⇒ 显得「input 字小」。 */\n.dshpc-pfx--md .dshpc-pfx__label,.dshpc-pfx--lg .dshpc-pfx__label{font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}\n.dshpc-pfx--md .dshpc-pfx__input,.dshpc-pfx--lg .dshpc-pfx__input{font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}\n.dshpc-pfx--error{border-color:var(--dshpc-danger);}\n.dshpc-pfx:focus-within{border-color:var(--dshpc-focus);box-shadow:0 0 0 1px var(--dshpc-focus);}\n.dshpc-pfx__label{padding:0 8px;color:var(--dshpc-fg-2);font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);white-space:nowrap;border-right:1px solid var(--dshpc-border);}\n.dshpc-pfx__input{flex:1 1 auto;min-width:0;height:100%;padding:0 8px;border:0;background:transparent;color:var(--dshpc-fg);\n font-family:inherit;font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);outline:none;}\n.dshpc-pfx__input::placeholder{color:var(--dshpc-fg-dim);}\n\n.dshpc-num{display:inline-flex;align-items:center;justify-content:space-between;box-sizing:border-box;overflow:hidden;\n border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);background:var(--dshpc-surface-1);color:var(--dshpc-fg);}\n/* 中段:数字 + 后缀成组居中;容器被消费端拉宽时吃掉全部余量,两端 − / + 因此钉死在左右边缘。 */\n.dshpc-num__mid{display:flex;align-items:center;justify-content:center;flex:1 1 auto;min-width:0;}\n.dshpc-num--sm{height:var(--dshpc-control-h-sm);}\n.dshpc-num--md{height:var(--dshpc-control-h-md);}\n.dshpc-num--lg{height:var(--dshpc-control-h-lg);}\n.dshpc-num--md .dshpc-num__input,.dshpc-num--lg .dshpc-num__input{font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}\n.dshpc-num--md .dshpc-num__suffix,.dshpc-num--lg .dshpc-num__suffix{font-size:var(--dshpc-font-md);}\n.dshpc-num--disabled{opacity:.5;}\n/* 焦点态与 Input 同款(2026-10-20 用户:数字框里点进去没有蓝框):内层 input 无边框,\n 焦点状态画在整个步进控件外框上。 */\n.dshpc-num:focus-within{border-color:var(--dshpc-focus);box-shadow:0 0 0 1px var(--dshpc-focus);}\n.dshpc-num__input{width:36px;height:100%;padding:0 2px;border:0;background:transparent;color:var(--dshpc-fg);\n font-family:inherit;font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);text-align:center;outline:none;}\n.dshpc-num__suffix{padding:0 6px;color:var(--dshpc-fg-2);font-size:var(--dshpc-font-sm);white-space:nowrap;}\n.dshpc-num .dshpc-iconbtn{border-radius:0;color:var(--dshpc-fg-2);flex:none;}\n\n/* 官方 Switch 包装统一:选中 = success 绿。\n (合并原先 task-editor-css / task-list 两处就地覆盖;选择器带包装类 + role,特异性高于官方。) */\n.dshpc-switch button[role='switch'][aria-checked='true']{background:var(--dshpc-success);}\n\n/* 多行文本输入(提示词等,P3):**边框 / 圆角 / 底 / 焦点态与 Input 同一套口径**(用户 2026-10-20:\n 「多行输入应该和 input 的边儿是一个道理,包括圆角在内,都是一个东西」)。\n ⚠️ 旧意图「卡内无边框、视觉重心在整张卡上」已作废 —— 现在它就是一只带框的多行输入框。\n (从 task-editor-css 的 .dshpc-ed-prompt 上提而来;业务文件不再自写 textarea 皮肤。) */\n.dshpc-textarea{display:block;width:100%;box-sizing:border-box;min-height:132px;padding:8px 12px;\n border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);outline:none;\n background:var(--dshpc-surface-1);color:var(--dshpc-fg);font-family:inherit;font-size:var(--dshpc-font-lg);line-height:1.6;resize:vertical;\n transition:border-color var(--dshpc-dur-fast) var(--dshpc-ease),box-shadow var(--dshpc-dur-fast) var(--dshpc-ease);}\n.dshpc-textarea::placeholder{color:var(--dshpc-fg-dim);}\n.dshpc-textarea:focus{border-color:var(--dshpc-focus);box-shadow:0 0 0 1px var(--dshpc-focus);}\n/* 校验不通过:与 Input 一致,走边框描红(旧版是 box-shadow 描红盒,与 Input 不同口径) */\n.dshpc-textarea--error{border-color:var(--dshpc-danger);}\n.dshpc-textarea:disabled{cursor:default;opacity:.5;}\n@media (prefers-reduced-motion: reduce){.dshpc-textarea{transition:none;}}\n\n/* 拖拽分隔条(编辑分栏 / 预览 dock 共用,U20 #3):6px 命中区,col-resize,不画线,hover/按下浮出浅带。\n 具体 z-index 由 .dshpc-ed-resizer / .dshpc-sv-resizer 各自补。 */\n.dshpc-resizer{position:absolute;top:0;bottom:0;left:0;width:6px;cursor:col-resize;background:0 0;touch-action:none;user-select:none;}\n.dshpc-resizer:hover,.dshpc-resizer:active{background:var(--dshpc-hover,rgba(38,49,72,.06));}\n\n@media (prefers-reduced-motion: reduce){.dshpc-input,.dshpc-pfx{transition:none;}}\n";
|
|
131
|
-
//#endregion
|
|
132
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/controls/loading-css.generated.js
|
|
133
|
-
const LOADING_CSS = "\n/* 运行中 / loading 的活动指示:三个小方块依次脉动。 */\n@keyframes dshpc-run-block { 0%, 80%, 100% { opacity: 0.25; transform: scale(0.8) } 40% { opacity: 1; transform: scale(1) } }\n.dshpc-run-blocks { display: inline-flex; align-items: center; gap: 3px; }\n.dshpc-run-blocks > i { width: 5px; height: 5px; border-radius: 1px; background: currentColor; animation: dshpc-run-block 1.2s ease-in-out infinite; }\n.dshpc-run-blocks > i:nth-child(2) { animation-delay: 0.15s; }\n.dshpc-run-blocks > i:nth-child(3) { animation-delay: 0.3s; }\n@media (prefers-reduced-motion: reduce) { .dshpc-run-blocks > i { animation: none; opacity: 1; } }\n\n/* ── 加载提示(LoadingToast / LoadingBlock / showLoading)───────────────────\n 两种样式共用一个灰色面(与 notify 的 info 卡同色),暗色走 body[data-ds-dark-theme]。 */\n.dshpc-loading-spin { display: block; flex: none; animation: dshpc-loading-rotate .8s linear infinite; }\n@keyframes dshpc-loading-rotate { to { transform: rotate(360deg) } }\n\n/* 样式一:横排 toast 卡(图标在左、文字在右),与 notify 的 info 卡同尺寸同色。 */\n.dshpc-loading-toast {\n display: inline-flex; align-items: center; gap: 10px;\n /* 不学 notify 固定 320 宽:这张卡也常被塞进表格 / 窄栏里,宽度随内容走。\n shortcut: 下限 250px,要更宽 / 更窄就改这一处。 */\n min-width: 250px; min-height: 48px; padding: 12px 16px; box-sizing: border-box;\n border-radius: 10px; box-shadow: 0 6px 16px rgba(0, 0, 0, .18);\n background: #f4f4f5; color: #18181b;\n font-size: var(--dshpc-font-lg); line-height: var(--dshpc-line-lg);\n}\n\n/* 样式二:方块卡(转圈在上、文字在下),内距更大。 */\n.dshpc-loading-block {\n display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;\n min-width: 132px; min-height: 132px; padding: 24px; box-sizing: border-box;\n border-radius: var(--dshpc-radius-md); box-shadow: 0 6px 16px rgba(0, 0, 0, .18);\n background: #f4f4f5; color: #18181b;\n font-size: var(--dshpc-font-md); line-height: var(--dshpc-line-md);\n}\nbody[data-ds-dark-theme] .dshpc-loading-toast,\nbody[data-ds-dark-theme] .dshpc-loading-block { background: #3f3f46; color: #fafafa; }\n\n/* 全局浮层:居中、不挡点击(遮罩层单独一个 div 才挡)。\n 与 Modal 遮罩同一套让位口径:右边界读 --dshpc-page-inset-right。 */\n.dshpc-loading-overlay {\n position: fixed; inset: 0 var(--dshpc-page-inset-right, 0px) 0 0; z-index: var(--dshpc-z-modal);\n display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;\n padding: 24px; box-sizing: border-box; pointer-events: none;\n}\n/* 七向定位(与 Toast 的六向同名 + 正中):默认 bottom-center,与 Sonner 提示同屏位。 */\n.dshpc-loading-overlay--top-left { align-items: flex-start; justify-content: flex-start; }\n.dshpc-loading-overlay--top-center { justify-content: flex-start; }\n.dshpc-loading-overlay--top-right { align-items: flex-end; justify-content: flex-start; }\n.dshpc-loading-overlay--bottom-left { align-items: flex-start; justify-content: flex-end; }\n.dshpc-loading-overlay--bottom-center { justify-content: flex-end; }\n.dshpc-loading-overlay--bottom-right { align-items: flex-end; justify-content: flex-end; }\n.dshpc-loading-overlay__mask { position: absolute; inset: 0; pointer-events: auto; }\n\n@media (prefers-reduced-motion: reduce) { .dshpc-loading-spin { animation: none; } }\n";
|
|
134
|
-
//#endregion
|
|
135
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/controls/back-to-top-css.generated.js
|
|
136
|
-
const BACK_TO_TOP_CSS = "\n/* 回到顶部悬浮钮:圆钮、实面、投影;默认隐身,滚过阈值加 .is-visible 才显形。\n 横向 left 由组件按主内容列右缘实时算出(贴在其右侧外侧),不写死。 */\n.dshpc-backtotop{\n position:fixed;\n bottom:var(--dshpc-space-4);\n z-index:var(--dshpc-z-dock);\n width:44px;height:44px;\n display:inline-flex;align-items:center;justify-content:center;\n padding:0;margin:0;\n box-sizing:border-box;\n border:1px solid var(--dshpc-border);\n border-radius:50%;\n background:var(--dshpc-solid);\n color:var(--dshpc-on-solid);\n box-shadow:var(--dshpc-shadow-2);\n cursor:pointer;\n opacity:0;\n transform:translateY(8px) scale(.92);\n transition:opacity var(--dshpc-dur) var(--dshpc-ease),\n transform var(--dshpc-dur) var(--dshpc-ease),\n background-color var(--dshpc-dur-fast) var(--dshpc-ease);\n pointer-events:none;\n}\n.dshpc-backtotop.is-visible{opacity:1;transform:translateY(0) scale(1);pointer-events:auto;}\n.dshpc-backtotop:hover{background:var(--dshpc-hover);}\n.dshpc-backtotop:active{background:var(--dshpc-active);}\n.dshpc-backtotop:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:2px;}\n@media (prefers-reduced-motion: reduce){\n .dshpc-backtotop{transition:opacity var(--dshpc-dur-fast) linear;transform:none;}\n}\n";
|
|
137
|
-
//#endregion
|
|
138
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/controls/hint-css.generated.js
|
|
139
|
-
const HINT_CSS = "\n/* ── 问号提示 P4(用户 2026-10-18:对齐真实插件 HelpButton——**带圈的问号图标**)──\n 本体 14px 细圈 + 圈内 ?,颜色 fg-3、hover 只提亮不加底(与 dshpc-ed-help 同规矩)。\n 气泡不在本文件:2026-10-19 用户拍板「问号必须用官方 Tooltip 那一个」⇒ 气泡由注入的\n 官方组件渲染(src/ui/tooltip.ts),这里只管问号图标本身。 */\n.dshpc-hint{display:inline-flex;align-items:center;justify-content:center;flex:none;\n box-sizing:border-box;width:14px;height:14px;padding:0;border:1px solid currentColor;border-radius:50%;background:transparent;\n color:var(--dshpc-fg-3);font-family:inherit;font-size:8px;font-weight:600;line-height:12px;cursor:help;vertical-align:middle;\n transition:color var(--dshpc-dur-fast) var(--dshpc-ease);}\n.dshpc-hint:hover,.dshpc-hint:focus-visible{color:var(--dshpc-fg);background:0 0;}\n.dshpc-hint:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px;}\n";
|
|
140
|
-
//#endregion
|
|
141
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/controls/datetime-css.generated.js
|
|
142
|
-
const DATETIME_CSS = "/* 日期时间选择器(DateTimePicker)。类名 dshpc-dt-*;配色只吃 token,明暗随 token 切换。\n 结构:触发器(range = 一个整条:两个日期区 + 样式画的灰隔条;single = 单日期)→ 浮层\n (两个独立端框 + 两块独立日历 + 底部动作)。\n 浮层行为与 Picker 一致:portal 到 body、贴边翻转、点外关闭、无遮罩。 */\n.dshpc-dt{position:relative;display:inline-block;font-size:13px;line-height:20px}\n.dshpc-dt__trigger{\n display:inline-flex;align-items:center;justify-content:space-between;gap:6px;\n max-width:100%;height:var(--dshpc-control-h-md);padding:0 8px;\n color:var(--dshpc-fg);background:var(--dshpc-surface-1);\n border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);cursor:pointer;\n}\n.dshpc-dt__trigger--sm{height:var(--dshpc-control-h-sm);font-size:12px}\n.dshpc-dt__trigger--lg{height:var(--dshpc-control-h-lg)}\n.dshpc-dt__trigger:disabled{color:var(--dshpc-fg-dim);cursor:not-allowed;opacity:.7}\n/* 焦点与基础 Input 完全同款(点击即蓝描边 + 1px 光环)。 */\n.dshpc-dt__trigger:focus{border-color:var(--dshpc-focus);box-shadow:0 0 0 1px var(--dshpc-focus)}\n.dshpc-dt__trigger-label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;font-variant-numeric:tabular-nums}\n.dshpc-dt__trigger-label--empty{color:var(--dshpc-fg-dim)}\n.dshpc-dt__cal{flex:none;color:var(--dshpc-fg-3)}\n/* range 触发器:一个整条里两个日期区 + 样式画出来的灰隔条(左右两条竖边),点整条都展开。 */\n/* 组撑满触发器内容高度,隔条才能上下顶到 border。 */\n.dshpc-dt__pair-group{flex:1 1 auto;min-width:0;align-self:stretch;display:flex;align-items:center;gap:8px}\n/* 两个日期区平分(flex:1 1 0):开始 / 结束永远一样宽,不随内容偏袒。 */\n.dshpc-dt__pair-date{flex:1 1 0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums}\n.dshpc-dt__pair-date--empty{color:var(--dshpc-fg-dim)}\n/* 隔条:上下顶到触发器 border(与边框连起来),中间隔出一块;块里放「到」的符号(-,用户 2026-10-24 拍板)。 */\n.dshpc-dt__pair-sep{\n flex:none;align-self:stretch;width:22px;margin:0;\n display:inline-flex;align-items:center;justify-content:center;\n background:var(--dshpc-surface-sunken);\n border-left:1px solid var(--dshpc-border);border-right:1px solid var(--dshpc-border);\n color:var(--dshpc-fg-3);font-size:12px;line-height:1;\n}\n/* 默认宽:**固定**(选中前后不变),数值对照参考图实测(2x 屏,换算 CSS px)后\n 统一 -6px(用户 2026-10-24:实测值留得偏多):\n 单值 day 128 / 时·分 153.2 / 秒 174.8;区间 day 269 / 分 341.4 / 秒 377.6。\n ch = 字体里 \"0\" 的宽(日期 tabular-nums 等宽)⇒ 写成 Nch + 常数;常数同时兜住\n 默认占位「请选择日期时间」(7 汉字)不省略。调用方要另给宽:className 传 width。 */\n.dshpc-dt__trigger--w-day{width:calc(10ch + 56px)}\n.dshpc-dt__trigger--w-minute{width:calc(16ch + 38px)}\n.dshpc-dt__trigger--w-second{width:calc(19ch + 38px)}\n.dshpc-dt__trigger--wr-day{width:calc(20ch + 125px)}\n.dshpc-dt__trigger--wr-minute{width:calc(32ch + 111px)}\n.dshpc-dt__trigger--wr-second{width:calc(38ch + 104px)}\n\n.dshpc-dt__pop{\n z-index:60;padding:10px;user-select:none;\n font-size:13px;line-height:20px;\n background:var(--dshpc-surface-menu);border:1px solid var(--dshpc-border);\n border-radius:var(--dshpc-radius-md);box-shadow:0 8px 24px rgba(15,23,42,.12);\n}\n/* 两个独立端框(range):点哪个哪个成为当前编辑端,互不联动、只是排在一起。 */\n.dshpc-dt__ends{display:flex;gap:6px;margin-bottom:8px}\n.dshpc-dt__end{\n flex:1 1 0;min-width:0;display:flex;align-items:center;gap:6px;padding:4px 8px;\n text-align:left;background:var(--dshpc-surface-1);\n border:1px solid var(--dshpc-border-faint);border-radius:var(--dshpc-radius-sm);cursor:pointer;\n}\n.dshpc-dt__end--active{border-color:var(--dshpc-business);background:var(--dshpc-open-bg)}\n.dshpc-dt__end:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n.dshpc-dt__end-label{flex:none;font-size:11px;line-height:16px;color:var(--dshpc-fg-3);white-space:nowrap}\n.dshpc-dt__end-value{font-size:12px;line-height:18px;color:var(--dshpc-fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums}\n.dshpc-dt__end-value--empty{color:var(--dshpc-fg-dim)}\n\n.dshpc-dt__nav{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}\n.dshpc-dt__nav-group{display:flex;gap:2px}\n.dshpc-dt__nav-btn{\n display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;\n color:var(--dshpc-fg-2);background:none;border:0;border-radius:var(--dshpc-radius-sm);cursor:pointer;\n}\n.dshpc-dt__nav-btn:hover{background:var(--dshpc-surface-sunken);color:var(--dshpc-fg)}\n.dshpc-dt__nav-btn:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:-1px}\n.dshpc-dt__caption{font-size:13px;font-weight:600;color:var(--dshpc-fg);white-space:nowrap}\n\n.dshpc-dt__grid{display:grid;grid-template-columns:repeat(7,30px);gap:2px}\n.dshpc-dt__wd{height:20px;font-size:11px;line-height:20px;color:var(--dshpc-fg-3);text-align:center}\n.dshpc-dt__cell{\n height:26px;padding:0;font-size:12px;font-variant-numeric:tabular-nums;\n color:var(--dshpc-fg);background:none;border:0;border-radius:var(--dshpc-radius-sm);cursor:pointer;\n}\n.dshpc-dt__cell:hover{background:var(--dshpc-surface-sunken)}\n.dshpc-dt__cell:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:-1px}\n.dshpc-dt__cell--out{color:var(--dshpc-fg-dim)}\n.dshpc-dt__cell--today{color:var(--dshpc-business);font-weight:600}\n/* 起 / 止端:品牌蓝实面反白(与 Segmented weekday 选中同口径)。\n ⚠️ 字色用常量白 --dshpc-on-signal,不用 --dshpc-fg-inverse:后者跟宿主 label-primary-foreground,\n 暗色主题下是近黑 ⇒ 蓝底黑字(与 Segmented 2026-10-29 同一事故)。 */\n.dshpc-dt__cell--sel{background:var(--dshpc-business);color:var(--dshpc-on-signal);font-weight:600}\n.dshpc-dt__cell--sel:hover{background:var(--dshpc-business-hover)}\n\n/* 两块日历面板(range:左开始、右结束,各选各的)。 */\n.dshpc-dt__panels{display:flex;gap:14px;align-items:flex-start}\n.dshpc-dt__panel{display:flex;flex-direction:column;gap:6px}\n\n.dshpc-dt__time{display:flex;align-items:flex-end;justify-content:center;gap:4px;margin-top:2px;padding-top:8px;border-top:1px solid var(--dshpc-border-faint)}\n.dshpc-dt__unit{display:flex;flex-direction:column;align-items:center;gap:2px}\n.dshpc-dt__unit-label{font-size:10px;line-height:14px;color:var(--dshpc-fg-3)}\n.dshpc-dt__step-btn{\n display:inline-flex;align-items:center;justify-content:center;width:34px;height:14px;padding:0;\n color:var(--dshpc-fg-2);background:none;border:0;border-radius:var(--dshpc-radius-sm);cursor:pointer;\n}\n.dshpc-dt__step-btn:hover{background:var(--dshpc-surface-sunken);color:var(--dshpc-fg)}\n.dshpc-dt__step-btn:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:-1px}\n.dshpc-dt__step-val{\n width:34px;height:24px;padding:0;box-sizing:border-box;text-align:center;\n font-size:13px;font-variant-numeric:tabular-nums;color:var(--dshpc-fg);\n background:var(--dshpc-surface-sunken);border:1px solid var(--dshpc-border-faint);\n border-radius:var(--dshpc-radius-sm);outline:none;\n}\n.dshpc-dt__step-val:focus{border-color:var(--dshpc-focus);box-shadow:0 0 0 1px var(--dshpc-focus)}\n.dshpc-dt__step-val:disabled{color:var(--dshpc-fg-dim);cursor:not-allowed}\n.dshpc-dt__sep{padding-bottom:5px;color:var(--dshpc-fg-3);font-size:12px}\n\n.dshpc-dt__foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:8px;padding-top:8px;border-top:1px solid var(--dshpc-border-faint)}\n.dshpc-dt__foot-side{display:flex;align-items:center;gap:6px}\n.dshpc-dt__warn{font-size:11px;color:var(--dshpc-warning-label);white-space:nowrap}\n";
|
|
143
|
-
//#endregion
|
|
144
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/controls/split-group-css.generated.js
|
|
145
|
-
const SPLIT_GROUP_CSS = "\n/* ── 拼接外壳 SplitGroup ──────────────────────────────────────────────\n 职责只有一条:把两个控件在外观上焊成一体(外框 / 圆角 / 中间 1px 分隔 / 整体聚焦圈)。\n 它**不持状态、不出联动回调** —— 选中与联动全走内件自己的 value / onChange\n (用户 2026-10-28 拍板:外壳不必知道右边那个下拉管什么)。\n\n ⚠️ 与内件类名有意耦合:内件是 Picker / Segmented 时由下面几条规则把它们自己的\n 边框 / 底色 / 圆角交出来,由外壳统一画。内件改名或改结构要同步改这里,\n 否则会出现双边框、双底色。\n\n 高度不写死:内件自己按 size 档(sm 24 / md 28 / lg 32)撑开,外壳跟着长。\n 两格要等高,就给内件传**同一个 size**。万一两格 size 不一致,外壳内件用 align-items:center\n 居中(不会顶对齐露白,用户 2026-10-28 截图反馈「本月偏上」后的处理);**别用 height:100%**,\n 它会覆盖三档高度(与 --lg/--sm 同特异性且注入更晚)。\n\n 左格统一灰底(用户 2026-10-28 拍板):滑块保留自己的灰轨,左格下拉把底色换成\n surface-sunken;右格保持原样。层次感 = 左格是「档位/范围」,右格是「值」。 */\n .dshpc-split{display:inline-flex;align-items:stretch;max-width:100%;overflow:hidden;border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);background:var(--dshpc-surface-1);}\n /* 两格宽度都由内容给;容器再窄也让内件自己省略,不让外壳被撑破 */\n .dshpc-split > *{min-width:0;max-width:100%;}\n /* 分隔:相邻兄弟的左描边,不额外插 DOM,hover / focus 时也不会断 */\n .dshpc-split > * + *{box-sizing:border-box;border-left:1px solid var(--dshpc-border);}\n /* 整体聚焦:内件自己的外圈交出来,由外壳画一整圈(内件各自画会变成格内半圈) */\n .dshpc-split:focus-within{border-color:var(--dshpc-focus);box-shadow:0 0 0 1px var(--dshpc-focus);}\n /* Picker:去掉自身外框与底色;display 改成 flex,消掉 inline-block 行盒带来的基线间隙。\n 注意**不能用 height:100%**:它会和 .dshpc-picker__trigger--lg / --sm 同特异性(都是两个类),\n 且 split-group.css 在 picker.css 之后注入,会把三档高度全吃掉(md/lg 看起来一样大)。\n 改用 align-items:center —— 同 size 时两格自然等高的同时文字垂直居中;万一两格 size 不一致,\n 较矮的格也只是居中、不会顶对齐露白。 */\n .dshpc-split .dshpc-picker{display:flex;align-items:center;}\n .dshpc-split .dshpc-picker__trigger{border:0;border-radius:0;background:transparent;}\n .dshpc-split .dshpc-picker__trigger:focus-visible{outline:0;}\n /* 左格下拉:灰底(滑块的灰轨是它自己的 --dshpc-seg-track,不在这里覆盖) */\n .dshpc-split > :first-child .dshpc-picker__trigger{background:var(--dshpc-surface-sunken);}\n /* Segmented:只去外圆角与描边,灰轨保留;padding 保持 3px 不动 —— 它是高度契约的一部分\n (3 + item + 3 = control-h)。bordered 那档去掉描边、把让给描边的 1px 还回 padding,\n 否则会比右边矮 2px。 */\n .dshpc-split .dshpc-seg{border-radius:0;border:0;}\n .dshpc-split .dshpc-seg--bordered{padding:3px;}\n";
|
|
146
|
-
//#endregion
|
|
147
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/marquee-css.generated.js
|
|
148
|
-
const MARQUEE_CSS = "/* 跑马灯(MarqueeText):双层——外层只裁剪,内层才 transform 滚动;非 hover 内层自带省略号。\n 2026-10-20:本文件原是杂烩「select.css」(下拉 / 日历 / 时分的皮肤都装过),随着那些控件\n 一个个删完,最后只剩跑马灯,故按本包「一个 css 服务一个对象」的格局改名归档。\n 同批清掉的还有零引用的省略号类 .dshpc-ellipsis —— 本包三个用到截断的地方都没采纳它。 */\n.dshpc-mq{display:block;overflow:hidden;white-space:nowrap;}\n.dshpc-mq .dshpc-mq-in{display:inline-block;white-space:nowrap;max-width:100%;overflow:hidden;text-overflow:ellipsis;vertical-align:top;}\n/* ⚠️ 跑法(用户 2026-10-03 拍板):**跑一遍、停在尾字**(播放 1 次 + forwards),不来回弹、不无限跑。\n 滚距 = 精确溢出量 ⇒ 停下时最后一个字正好贴右缘,**不会跑进黑块**(黑块是旧手写版把\n 内层盒子裁了、按「半截文本」平移导致的)。鼠标移开 ⇒ :hover 失效 ⇒ 自动复位回省略号态。 */\n.dshpc-mq-run:hover .dshpc-mq-in{max-width:none;overflow:visible;animation:dshpc-mq-scroll var(--dshpc-mq-dur,6s) linear .4s 1 forwards;}\n@keyframes dshpc-mq-scroll{from{transform:translateX(0)}to{transform:translateX(var(--dshpc-mq-dist,-40px))}}\n/* 溢出渐影(用户 2026-10-24 拍板「左右稍微有点渐影」;官方口径 = dsh-client-ui-primitives@0.2.1-rc.2\n PathLabel.module.css:13-15:mask-image 线性渐隐 + 28px 随官方)。⚠️ 只在 **hover 滚动态** 加:\n 静态态(三个点)不要渐影(用户 2026-10-24 二次拍板),hover 滚动时两端渐影——左缘柔化被裁的文字头。 */\n.dshpc-mq-run:hover{mask-image:linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent);}\n";
|
|
149
|
-
//#endregion
|
|
150
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/picker-css.generated.js
|
|
151
|
-
const PICKER_CSS = "\n.dshpc-picker{position:relative;display:inline-block;max-width:100%;font-size:13px;line-height:20px}\n.dshpc-picker__trigger{\n display:inline-flex;align-items:center;justify-content:space-between;gap:6px;\n min-width:120px;max-width:100%;height:28px;padding:0 8px;\n color:var(--dshpc-fg);background:var(--dshpc-surface-1);\n border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);cursor:pointer;\n}\n.dshpc-picker__trigger:disabled{color:var(--dshpc-fg-dim);cursor:not-allowed;opacity:.7}\n/* 聚焦(键盘或点击选中)时与全站一致的蓝色描边;菜单打开后焦点会进去,触发器自然失去焦点。 */\n.dshpc-picker__trigger:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n/* 文字默认靠左(吃掉剩余宽度),不给 space-between 把短文案推到中间的机会;\n 确实要居中就显式传 align=\"center\"。 */\n.dshpc-picker__label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}\n.dshpc-picker__trigger--center .dshpc-picker__label{text-align:center}\n.dshpc-picker__caret{flex:none;color:var(--dshpc-fg-3)}\n.dshpc-picker__icon{display:inline-flex;flex:none;color:var(--dshpc-fg-2)}\n.dshpc-picker__option-icon{display:inline-flex;flex:none;color:var(--dshpc-fg-2)}\n.dshpc-picker__menu{\n z-index:60;max-height:280px;overflow:auto;padding:4px;\n /* 菜单经 FloatingPortal 挂到 body,脱离 .dshpc-picker,须显式字号,否则继承 body 的大字号 */\n font-size:13px;line-height:20px;\n background:var(--dshpc-surface-menu);border:1px solid var(--dshpc-border);\n border-radius:var(--dshpc-radius-md);box-shadow:0 8px 24px rgba(15,23,42,.12);\n}\n/* 尺寸档(与 Field 的 sm/md/lg 对应)。 */\n.dshpc-picker__trigger--sm{height:24px;font-size:12px}\n.dshpc-picker__trigger--lg{height:32px}\n/* 键盘游标所在项(无 hover 也要看得见)。 */\n.dshpc-picker__option[data-active='true']{background:var(--dshpc-surface-sunken);outline:1px solid var(--dshpc-border)}\n.dshpc-picker__option--clear{color:var(--dshpc-fg-3)}\n.dshpc-picker__search{\n width:100%;height:28px;margin-bottom:4px;padding:0 8px;box-sizing:border-box;\n color:var(--dshpc-fg);background:var(--dshpc-surface-sunken);\n border:1px solid var(--dshpc-border-faint);border-radius:var(--dshpc-radius-md);outline:none;\n}\n.dshpc-picker__group-label{\n padding:6px 8px 2px;color:var(--dshpc-fg-3);font-size:11px;\n}\n.dshpc-picker__option{\n display:flex;align-items:center;gap:6px;padding:6px 8px;border-radius:var(--dshpc-radius-sm);cursor:pointer;\n color:var(--dshpc-fg);white-space:nowrap;\n}\n.dshpc-picker__option:hover{background:var(--dshpc-surface-sunken)}\n.dshpc-picker__option--active{background:var(--dshpc-open-bg);color:var(--dshpc-business)}\n.dshpc-picker__option--disabled{color:var(--dshpc-fg-dim);cursor:not-allowed}\n/* 选项文字吃掉剩余宽度:超长省略号(配合 MarqueeText hover 跑马灯),不撑宽菜单。 */\n.dshpc-picker__option-label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dshpc-picker__tick{width:12px;color:var(--dshpc-business)}\n.dshpc-picker__empty{padding:8px;color:var(--dshpc-fg-3);text-align:center}\n.dshpc-picker__degraded{\n padding:6px 8px;margin-bottom:4px;border-radius:var(--dshpc-radius-sm);\n color:var(--dshpc-warning-label);background:color-mix(in srgb,var(--dshpc-warning) 12%,transparent);\n font-size:11px;\n}\n.dshpc-picker__row{display:flex;align-items:center;gap:8px}\n";
|
|
152
|
-
//#endregion
|
|
153
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/feedback-css.generated.js
|
|
154
|
-
const FEEDBACK_CSS = "\n/* 遮罩 = 宿主遮罩变量 --dsw-alias-bg-mask-1(与官方 Modal / 兄弟项目 --tdt-mask 同一条真值,用户 2026-10-20)。 */\n/* 右边界让位页面级分栏(PanelDock 发布的 --dshpc-page-inset-right,用户 2026-10-22):\n 分栏不被压暗、照常可点;弹窗在这块**剩下**的区域里居中,就像整页被推出去一样。 */\n.dshpc-modal-mask{\n position:fixed;inset:0 var(--dshpc-page-inset-right,0px) 0 0;z-index:1070;\n display:flex;align-items:center;justify-content:center;\n background:var(--dshpc-mask);\n}\n/* 大弹窗家族(md/lg):抄兄弟项目 archive-session-css 的 .dsh-tdt-sv-panel(surface-base + border-l2 + radius 12 + shadow-2)。 */\n.dshpc-modal{\n display:flex;flex-direction:column;box-sizing:border-box;\n background:var(--dshpc-surface-base);color:var(--dshpc-fg);\n border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);\n box-shadow:var(--dshpc-shadow-2);overflow:hidden;\n}\n.dshpc-modal__head{\n display:flex;align-items:center;gap:8px;padding:18px 31px 12px;\n border-bottom:1px solid var(--dshpc-border);flex-wrap:wrap;\n}\n/* 标题组:第一行 = 标题 + 右侧小块(徽标紧跟标题),第二行 = 副标题。 */\n.dshpc-modal__titlegroup{display:flex;flex-direction:column;gap:2px;min-width:0;flex:0 1 auto}\n.dshpc-modal__titlerow{display:flex;align-items:center;gap:8px;min-width:0}\n.dshpc-modal__title{font-size:var(--dshpc-font-lg);font-weight:600;line-height:1.4;min-width:0}\n/* 标题下副标题行(兄弟项目 .dsh-tdt-sv-sid:等宽字体、caption 色、可换行)。 */\n.dshpc-modal__sid{font-family:var(--ds-font-family-code,monospace);font-size:var(--dshpc-font-xs);color:var(--dshpc-fg-3);word-break:break-all}\n/* 关闭按钮:24×24 方角图标位,不借用 Picker 的触发器皮肤(那份带 min-width:120px)。 */\n.dshpc-modal__close{\n display:inline-flex;align-items:center;justify-content:center;flex:none;\n width:20px;height:20px;padding:0;border:none;border-radius:var(--dshpc-radius-sm);\n background:transparent;color:var(--dshpc-fg-3);font-family:inherit;font-size:13px;line-height:1;cursor:pointer;\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-modal__close:hover{background:var(--dshpc-hover);color:var(--dshpc-fg)}\n.dshpc-modal__close:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n/* body = 唯一滚动容器:内距与滚动都归它(滚动条贴面板右缘,不被内距挤进来);\n 内容按流排,不设 height:100%、不自己开滚动条。 */\n.dshpc-modal__body{flex:1 1 auto;min-height:0;overflow:auto;padding:17px 31px}\n.dshpc-modal__foot{display:flex;justify-content:flex-end;gap:8px;padding:12px 31px 18px}\n.dshpc-toast-host{\n position:fixed;z-index:1090;left:50%;bottom:32px;transform:translateX(-50%);\n display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none;\n}\n.dshpc-toast{\n padding:8px 14px;border-radius:8px;font-size:13px;color:var(--dshpc-fg);\n background:var(--dshpc-surface-menu);border:1px solid var(--dshpc-border);\n box-shadow:0 8px 24px rgba(15,23,42,.16);\n}\n.dshpc-toast--success{color:var(--dshpc-success);border-color:color-mix(in srgb,var(--dshpc-success) 40%,transparent)}\n.dshpc-toast--error{color:var(--dshpc-danger);border-color:color-mix(in srgb,var(--dshpc-danger) 40%,transparent)}\n.dshpc-error__retry{\n margin-top:8px;color:var(--dshpc-link);cursor:pointer;background:none;border:none;padding:0;\n}\n/* 原生弹窗演示:经宿主 Modal 的 contentClassName 注入,证明宿主内容区尺寸可经类名自定义。 */\n.dshpc-native-demo-content{max-width:520px}\n/* Modal 头部四槽:左图标 / 标题组 / 弹性间隔 / 右侧动作区 + 关闭钮。 */\n.dshpc-modal__heading{display:flex;align-items:center;gap:8px;min-width:0;flex:0 1 auto}\n.dshpc-modal__lead{flex:none;display:inline-flex;align-items:center;justify-content:center;font-size:16px;line-height:1}\n.dshpc-modal__extra{flex:none;display:inline-flex;align-items:center}\n.dshpc-modal__spacer{flex:1 1 auto;min-width:8px}\n.dshpc-modal__actions{flex:none;display:flex;align-items:center;gap:8px}\n/* 头部信号图标(AlertModal 按 severity 注入):自含配色,不依赖宿主 token。 */\n.dshpc-alert-sev{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;font-size:12px;color:#fff;flex:none}\n.dshpc-alert-sev--info{background:#2563eb}\n.dshpc-alert-sev--success{background:#16a34a}\n.dshpc-alert-sev--warning{background:#d97706}\n.dshpc-alert-sev--error{background:#dc2626}\n/* 小确认框家族(sm):严格抄兄弟项目 renderConfirm 的 dialogStyle(task-list.tsx:456)——\n 360px 宽 / 18px 内距 / 头部无分隔线 / 说明文字 fg-2 / 底部按钮右对齐。 */\n.dshpc-modal--sm{padding:18px}\n.dshpc-modal--sm .dshpc-modal__head{padding:0 0 8px;border-bottom:none}\n.dshpc-modal--sm .dshpc-modal__body{padding:0 0 14px;overflow:visible;font-size:var(--dshpc-font-sm);color:var(--dshpc-fg-2);line-height:var(--dshpc-line-sm)}\n.dshpc-modal--sm .dshpc-modal__foot{padding:0}\n";
|
|
155
|
-
//#endregion
|
|
156
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/card-css.generated.js
|
|
157
|
-
const CARD_CSS = "\n.dshpc-card{\n position:relative;box-sizing:border-box;color:var(--dshpc-fg);font:inherit;text-align:left;\n --card-accent:var(--dshpc-business);\n --card-accent-soft:var(--dshpc-business-soft);\n}\n/* 档位 → token(照 records-timeline 的 tone 模式:一个变量切档,不写 5 套规则;浅底与色条同源)。 */\n.dshpc-card--success{--card-accent:var(--dshpc-success);--card-accent-soft:var(--dshpc-success-soft)}\n.dshpc-card--warning{--card-accent:var(--dshpc-warning);--card-accent-soft:var(--dshpc-warning-soft)}\n.dshpc-card--danger{--card-accent:var(--dshpc-danger);--card-accent-soft:var(--dshpc-danger-soft)}\n/* neutral 浅底借 chip 底(兄弟项目 mute 档同款:明暗都成立)。 */\n.dshpc-card--neutral{--card-accent:var(--dshpc-fg-4);--card-accent-soft:var(--dshpc-chip-bg)}\n/* 扩展八色(2026-10-29):色条 + 浅底同源,软底走各自 -soft。 */\n.dshpc-card--purple{--card-accent:var(--dshpc-purple);--card-accent-soft:var(--dshpc-purple-soft)}\n.dshpc-card--pink{--card-accent:var(--dshpc-pink);--card-accent-soft:var(--dshpc-pink-soft)}\n.dshpc-card--cyan{--card-accent:var(--dshpc-cyan);--card-accent-soft:var(--dshpc-cyan-soft)}\n.dshpc-card--teal{--card-accent:var(--dshpc-teal);--card-accent-soft:var(--dshpc-teal-soft)}\n.dshpc-card--orange{--card-accent:var(--dshpc-orange);--card-accent-soft:var(--dshpc-orange-soft)}\n.dshpc-card--indigo{--card-accent:var(--dshpc-indigo);--card-accent-soft:var(--dshpc-indigo-soft)}\n.dshpc-card--rose{--card-accent:var(--dshpc-rose);--card-accent-soft:var(--dshpc-rose-soft)}\n.dshpc-card--slate{--card-accent:var(--dshpc-slate);--card-accent-soft:var(--dshpc-slate-soft)}\n\n/* 头部一行 = 色条 + 主内容 + 右侧槽,**整体垂直居中**:调用方在 action 里裸放一个元素\n (按钮 / 文字 / 图标)不用自己套容器居中;一行两行、右边怎么放由调用方在框内自定。 */\n.dshpc-card__head{display:flex;align-items:center;gap:8px;min-width:0}\n.dshpc-card__main{flex:1;min-width:0}\n.dshpc-card__side{display:flex;align-items:center;gap:6px;flex:none}\n\n/* ── 外观一 · StripCard:同色系浅底 + 1px 不可见占位边框 + 方角 + 4px 通高方角色条贴左缘 ── */\n.dshpc-card--strip{\n padding:12px 12px 12px 20px;border:1px solid transparent;\n background:var(--card-accent-soft,transparent);\n}\n/* 左内边距 20px = 16 留白 + 4 条宽 ⇒ 内容从色条右缘起算;色条绝对定位通高,跟着内容高度自适应。 */\n.dshpc-card--strip .dshpc-card__bar{position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--card-accent)}\n\n/* ── 外观二 · Card:surface 底 + 1px 实色边框 + 圆角 + 行内圆角短条 ── */\n.dshpc-card--bordered{\n /* 左内边距 12(比上/右/下 14 少 2):竖条贴近边框;头部内缩 2px ⇒ 主内容跟着左移 2px,\n 竖条↔内容的 12px 间距不变——比「条子 left:-2 而内容不动」更正规(不靠相对定位硬补)。 */\n padding:14px 14px 14px 12px;border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-sm);\n background:var(--dshpc-surface-1);\n}\n.dshpc-card--bordered .dshpc-card__head{gap:12px}\n/* 短条:行内 flex 项,**高度跟着内容走**(stretch),最小一行文字(--dshpc-line-md)——\n 一行文字时条子与文字齐高,不会把卡撑高;竖条距左 12(= 左内边距),距上/右/下 14。 */\n.dshpc-card--bordered .dshpc-card__bar{width:6px;flex:none;align-self:stretch;min-height:var(--dshpc-line-md);border-radius:var(--dshpc-radius-xs);background:var(--card-accent)}\n.dshpc-card__toggle{\n display:inline-flex;align-items:center;justify-content:center;\n width:24px;height:24px;padding:0;background:none;border:none;border-radius:6px;\n color:var(--dshpc-fg-3);cursor:pointer;\n}\n.dshpc-card__toggle:hover{background:var(--dshpc-surface-sunken);color:var(--dshpc-fg)}\n/* 箭头是 svg(Chevron),不是字形 ⇒ 不要 font-size;inline-flex 免掉 svg 的基线留白。 */\n.dshpc-card__caret{display:inline-flex;transition:transform .15s ease}\n.dshpc-card__caret.is-open{transform:rotate(180deg)}\n.dshpc-card__panel{margin-top:8px;padding-top:8px;border-top:1px solid var(--dshpc-border-faint)}\n";
|
|
158
|
-
//#endregion
|
|
159
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/chip-css.generated.js
|
|
160
|
-
const CHIP_CSS = "\n/* 三条局部变量承载配色:neutral 走旧灰面;语义档换底字配对(2026-10-20 用户要多色多尺寸标签)。 */\n.dshpc-chip{--chip-bg:var(--dshpc-chip-bg);--chip-fg:var(--dshpc-fg);--chip-bg-hover:var(--dshpc-chip-bg-hover);\n display:inline-flex;align-items:center;justify-content:center;gap:4px;padding:1px 8px;\n box-sizing:border-box;border-radius:var(--dshpc-radius-pill,999px);border:none;\n background:var(--chip-bg);color:var(--chip-fg);\n font-family:inherit;font-size:11px;line-height:18px;margin:0;\n /* 2026-10-18:chip 是 flex 行里的常用项,禁止被压缩换行(预览站出现过文字竖排、互相叠压的挤压)。 */\n white-space:nowrap;flex:none;\n appearance:none;-webkit-appearance:none;\n}\n/* md 档:卡片元信息行等稍大场景;sm 即旧版默认,逐像素不动。 */\n.dshpc-chip--md{padding:2px 10px;font-size:12px;line-height:20px;}\n/* xs 档:标题后缀等极紧凑场景(2026-10-20 用户要更小标签);16px 高、font 10。 */\n.dshpc-chip--xs{padding:0 6px;font-size:10px;line-height:16px;}\n/* 语义色实心档:底 / 字 / hover 配对与 Button 同源(黄底中高明度 ⇒ 字用 --dshpc-on-warning)。 */\n.dshpc-chip--business{--chip-bg:var(--dshpc-business);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-business-hover);}\n.dshpc-chip--success{--chip-bg:var(--dshpc-success);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-success-hover);}\n.dshpc-chip--warning{--chip-bg:var(--dshpc-warning);--chip-fg:var(--dshpc-on-warning);--chip-bg-hover:var(--dshpc-warning-hover);}\n.dshpc-chip--danger{--chip-bg:var(--dshpc-danger);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-danger-hover);}\n/* 扩展八色(2026-10-29):实心面字色统一白(on-signal),明度均低于黄 / 青柠,白字两主题可读。 */\n.dshpc-chip--purple{--chip-bg:var(--dshpc-purple);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-purple-hover);}\n.dshpc-chip--pink{--chip-bg:var(--dshpc-pink);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-pink-hover);}\n.dshpc-chip--cyan{--chip-bg:var(--dshpc-cyan);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-cyan-hover);}\n.dshpc-chip--teal{--chip-bg:var(--dshpc-teal);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-teal-hover);}\n.dshpc-chip--orange{--chip-bg:var(--dshpc-orange);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-orange-hover);}\n.dshpc-chip--indigo{--chip-bg:var(--dshpc-indigo);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-indigo-hover);}\n.dshpc-chip--rose{--chip-bg:var(--dshpc-rose);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-rose-hover);}\n.dshpc-chip--slate{--chip-bg:var(--dshpc-slate);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-slate-hover);}\n/* 可点态:button 渲染(见 Chip.ts),光标 + hover 加深。 */\n.dshpc-chip--clickable{cursor:pointer;transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease);}\n.dshpc-chip--clickable:hover:not(:disabled){background:var(--chip-bg-hover)}\n.dshpc-chip:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n.dshpc-chip:disabled{cursor:default;color:var(--dshpc-fg-3)}\n/* maxWidth 包 MarqueeText 时:标签作为 flex 子项必须能收缩到内容以下,否则省略号 / 跑马灯测不准 */\n.dshpc-chip .dshpc-chip__label{min-width:0;}\n@media (prefers-reduced-motion: reduce){.dshpc-chip{transition:none}}\n";
|
|
161
|
-
//#endregion
|
|
162
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/code-viewer-css.generated.js
|
|
163
|
-
const CODE_VIEWER_CSS = "/* CodeViewer(只读 CodeMirror 查看器)样式。类名固定 dshpc-cv*;颜色吃 --dshpc-* token,\n 深色由 design 的 token 深色段自动生效(不写死颜色值)。 */\n.dshpc-cv{position:relative;display:flex;flex-direction:column;height:100%;min-height:0;}\n/* 复制钮复用核心 IconButton(variant=outline / size=md):盒型、描边、圆角(已统一 md)、底色、hover 全由核心提供;\n 这里只管「绝对定位 + 默认隐藏、hover/聚焦才显」(overlay 浮在编辑器右上角)。 */\n.dshpc-cv__copy{position:absolute;top:6px;right:6px;z-index:5;opacity:0;}\n.dshpc-cv:hover .dshpc-cv__copy,.dshpc-cv__copy:focus-visible{opacity:1;}\n.dshpc-cv__copy svg{width:16px;height:16px;}\n.dshpc-cv__editor{flex:1 1 auto;min-height:0;overflow:hidden;}\n.dshpc-cv__editor .cm-editor{height:100%;}\n.dshpc-cv__editor .cm-scroller{overflow:auto;}\n";
|
|
164
|
-
//#endregion
|
|
165
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/panel-dock-css.generated.js
|
|
166
|
-
const PANEL_DOCK_CSS = "\n/* 停靠栏 = **布局成员**,不是浮层:它占宽度、把主区真正挤窄(兄弟项目 2026-09-28:\n 「分栏压过来,不是盖上去」)。所以调用方必须把它放进自己的 flex 根里。 */\n.dshpc-dock{display:flex;flex:0 0 auto;align-self:stretch;min-width:0}\n/* 开着时给主区滚动条让出一条缝:滚动条贴死分隔线很难看(用户 2026-10-28,对齐\n dsh-better-sidebar 的留白)。全关时整条 dock 退出,缝隙一起消失、不留白边。\n 缝宽可由调用方盖 --dshpc-dock-gap;TS 侧的让位量(DOCK_GAP)要与它一致。 */\n.dshpc-dock--open{margin-left:var(--dshpc-dock-gap,1px)}\n\n/* 自动加的宿主行(openFilePreview 加 / 关闭即摘):消费方那行不必自己写 flex。\n 只让「第一个非预览子项」当主区伸展,其余直接子项不动(页脚条、工具条不误伤);\n display 不在这里写死 —— 本来就是 grid 等布局的元素保持原样,由 TS 侧按计算值补 flex。 */\n.dshpc-dock-host{min-width:0;min-height:0}\n.dshpc-dock-host>:not([data-dshpc-file-preview]){min-width:0}\n.dshpc-dock-host>:first-child:not([data-dshpc-file-preview]){flex:1 1 auto}\n\n/* 单栏:sticky + 100vh 让它在页面滚动时保持可见,同时仍然占宽度。\n ⚠️ **本条刻意不设 z-index**:布局成员一旦带正 z-index,就会无条件压过宿主 portal 到 body 的\n 弹窗(兄弟项目 2026-10-05 真机事故「侧边栏盖住宿主设置弹窗」)。层序交给 DOM 顺序裁决。 */\n.dshpc-dock__panel{\n box-sizing:border-box;position:sticky;top:0;align-self:stretch;\n display:flex;flex-direction:column;flex:0 0 auto;\n /* 高度默认视口高(整页场景);嵌在定高容器里时由调用方给 --dshpc-dock-h(如 420px / 100%)。 */\n height:var(--dshpc-dock-h,100vh);max-height:var(--dshpc-dock-h,100vh);min-width:0;\n background:var(--dshpc-surface-base);color:var(--dshpc-fg);\n border-left:1px solid var(--dshpc-border);\n transition:border-color var(--dshpc-dur-fast) var(--dshpc-ease);\n box-shadow:var(--dshpc-shadow-2);\n /* 入场:从 0 宽滑出来(keyframes 只写 from,终点取内联 width),打开 / 耳朵展开都走这条。 */\n animation:dshpc-dock-in .22s var(--dshpc-ease);\n}\n/* overflow:hidden 只在动画前段(离散属性在 50% 翻转)——平时不能裁,否则挂在左缘外的\n 收起钮会被切掉一半。 */\n@keyframes dshpc-dock-in{from{width:0;opacity:0;overflow:hidden}}\n/* 收起的出场:宽度收到 0、透明淡出;落定后组件才真正摘掉这一栏(JS 延时 220ms 配合)。 */\n.dshpc-dock__panel--closing{\n width:0!important;min-width:0!important;opacity:0;border-left-width:0;\n transition:width .2s var(--dshpc-ease),opacity .2s var(--dshpc-ease),border-left-width .2s var(--dshpc-ease);\n}\n\n.dshpc-dock__head{\n flex:none;display:flex;align-items:center;gap:8px;\n /* 右侧 34px = 8(边距) + 20(关钮) + 6(呼吸):给绝对定位的关钮留位,标题/extra 不从它底下钻 */\n padding:10px 34px 10px 14px;\n border-bottom:1px solid var(--dshpc-border-faint);\n}\n/* 图标位 / 标题右侧的内容位:消费方传 ReactNode,可塞多个;库只负责排布,不抢宽度。 */\n.dshpc-dock__lead{display:inline-flex;align-items:center;gap:6px;flex:none;color:var(--dshpc-fg-2)}\n.dshpc-dock__extra{display:inline-flex;align-items:center;gap:6px;flex:none;margin-left:auto}\n/* 自定义头部:整行归调用方 —— 不加内边距/边框/背景,也不给关钮留内联空间(关钮是绝对定位的)。 */\n.dshpc-dock__head--custom{display:block;padding:0;border-bottom:none}\n.dshpc-dock__title{\n flex:1 1 auto;min-width:0;\n overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\n font-size:var(--dshpc-font-md);font-weight:600;\n}\n/* 关闭钮:20×20 方角图标位(与 Modal 的关闭钮同规格,不借 Picker 触发器皮肤)。 */\n.dshpc-dock__close{\n display:inline-flex;align-items:center;justify-content:center;flex:none;\n width:20px;height:20px;padding:0;border:none;border-radius:var(--dshpc-radius-sm);\n background:transparent;color:var(--dshpc-fg-3);\n font-family:inherit;font-size:13px;line-height:1;cursor:pointer;\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-dock__close:hover{background:var(--dshpc-hover);color:var(--dshpc-fg)}\n.dshpc-dock__close:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n/* 头部关钮:绝对定位,位置与内置头完全一致(top 10 / right 8);自定义头也用这一个位置。\n 锚点是面板本身(position:sticky 即定位上下文),不在滚动内容里,所以正文滚动它不跟滚。 */\n.dshpc-dock__close--abs{position:absolute;top:10px;right:8px;z-index:8}\n/* 浮动关钮:无头部面板用,略收一点边距。 */\n.dshpc-dock__close--floating{\n position:absolute;top:6px;right:6px;z-index:8;\n background:var(--dshpc-surface-menu);border:1px solid var(--dshpc-border-faint);\n}\n\n/* 内容区自己滚:面板高度锁 100vh,内容不设内部滚动就会把整页撑高。 */\n.dshpc-dock__body{flex:1 1 auto;min-height:0;overflow:auto}\n\n/* 拖拽条:左缘 6px 命中区,**自己不画任何线**。\n hover / 拖动时把面板自己的 border-left 染成蓝(用户 2026-10-28 四轮:蓝线只准改原线,\n 不准在原线旁边加一条 —— 之前在 padding box 左缘画渐变,正好叠出双线)。\n 命中区在 padding box 上、border 在它左外侧,所以只能改面板的 border 色。\n z-index 7 必须高于面板内容里的浮层(复制钮一类),否则命中区会被内容盖住。 */\n.dshpc-dock__resizer{\n position:absolute;left:0;top:0;bottom:0;width:6px;\n z-index:7;cursor:col-resize;background:transparent;\n}\n.dshpc-dock__panel:has(> .dshpc-dock__resizer:hover),\n.dshpc-dock__panel--resizing{\n /* 原线保留「上下渐隐」工作区指示条质感:把面板自己的 border-left 换成同款渐变\n (不是另加一条线)。面板只有这一条边框、无圆角,所以只作用在线上。 */\n border-image:linear-gradient(180deg,transparent,var(--dshpc-business) 30% 70%,transparent) 1;\n}\n\n/* 拖动期:① <iframe>(PDF / HTML 预览)是独立文档,会吞掉父文档的 pointermove,\n 向右拖进 iframe 就卡死 —— 整片让出指针事件;② contain 把重排隔离在栏内,\n 否则每帧改宽度都会牵动整页重排(兄弟项目 2026-10-04 真机「挪很久才动一下」)。 */\n.dshpc-dock.dshpc-dock--resizing iframe{pointer-events:none}\n.dshpc-dock.dshpc-dock--resizing .dshpc-dock__panel{contain:layout paint;will-change:width}\n\n/* 收起钮:**待在面板自己的框里**(用户 2026-10-28 三轮:占面板内部空间,不伸到外面去)。\n left:0 从内侧贴着分隔线 —— 贴线的一边不描边(线是面板自己的 border-left),页签与线不重合。\n 20×44(用户 2026-10-28 四轮定尺寸);实色底(--dshpc-plate,明暗各有实值),hover 亮一档。\n padding-right:2px 是**视觉居中**:右侧是圆角,箭头往直线那边挪 1px(用户 2026-10-28 四轮)。 */\n.dshpc-dock__collapse{\n position:absolute;left:0;top:50%;transform:translateY(-50%);\n z-index:8;display:inline-flex;align-items:center;justify-content:center;\n width:20px;height:44px;padding:0 2px 0 0;\n border-top:1px solid var(--dshpc-border);\n border-bottom:1px solid var(--dshpc-border);\n border-right:1px solid var(--dshpc-border);\n border-left:none;\n border-radius:0 var(--dshpc-radius-sm) var(--dshpc-radius-sm) 0;\n background:var(--dshpc-plate);color:var(--dshpc-fg-3);\n font-family:inherit;font-size:16px;line-height:1;cursor:pointer;\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-dock__collapse:hover{background:var(--dshpc-plate-hover);color:var(--dshpc-fg)}\n.dshpc-dock__collapse:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n\n/* 收起后的浮动耳朵:**fixed 贴右缘、垂直居中、独立于分栏**(用户 2026-10-28 定稿:\n 小页签挂中间、里面放面板图标、不显示文字,箭头与收起钮反向)。多个按收起顺序纵向堆叠。\n z 走 dock 档(低于宿主弹窗),避免盖住宿主 portal 层。 */\n.dshpc-dock__ears{\n position:fixed;top:50%;right:0;transform:translateY(-50%);\n z-index:var(--dshpc-z-dock,1030);\n display:flex;flex-direction:column;gap:8px;align-items:flex-end;\n pointer-events:none;\n}\n.dshpc-dock__ear{\n pointer-events:auto;display:inline-flex;align-items:center;justify-content:center;\n /* 与收起钮**同尺寸**(20×44,用户 2026-10-28 四轮):上/下/左描边,贴右缘的一侧不描。\n 实色底(--dshpc-plate),不用透明色 —— 透明底下透出东西很难看。\n padding-left:2px 是**视觉居中**:左侧是圆角,箭头往直线(右缘)那边挪 1px。 */\n width:20px;height:44px;box-sizing:border-box;padding:0 0 0 2px;\n border-top:1px solid var(--dshpc-border);\n border-bottom:1px solid var(--dshpc-border);\n border-left:1px solid var(--dshpc-border);\n border-right:none;\n border-radius:var(--dshpc-radius-sm) 0 0 var(--dshpc-radius-sm);\n background:var(--dshpc-plate);color:var(--dshpc-fg-2);\n cursor:pointer;font-family:inherit;line-height:1;\n animation:dshpc-ear-in .2s var(--dshpc-ease);\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n/* 入场:从右缘外滑进来,别「突然出现」(用户 2026-10-28)。 */\n@keyframes dshpc-ear-in{from{opacity:0;transform:translateX(14px)}}\n.dshpc-dock__ear:hover{background:var(--dshpc-plate-hover);color:var(--dshpc-fg)}\n.dshpc-dock__ear:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n/* 与收起钮的箭头同一字号(16px):收进去前后箭头一模一样大(用户 2026-10-28)。 */\n.dshpc-dock__ear-arrow{font-size:16px;color:var(--dshpc-fg-3)}\n.dshpc-dock__ear:hover .dshpc-dock__ear-arrow{color:var(--dshpc-fg)}\n/* 动效礼貌:系统声明减少动效时全部关掉(与 Segmented 同一约定),收起退化为瞬时、功能不受影响。 */\n@media (prefers-reduced-motion:reduce){\n .dshpc-dock__panel{animation:none}\n .dshpc-dock__panel--closing{transition:none}\n .dshpc-dock__ear{animation:none}\n}\n";
|
|
167
|
-
//#endregion
|
|
168
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/explorer/explorer-css.generated.js
|
|
169
|
-
const EXPLORER_CSS = "/* 工作区文件浏览器(dshpc-fb-*)。\n *\n * 度量真源 = 兄弟项目 dsh-task-dispatch-table 的 src/client/archive-session-css.ts\n * (.dsh-tdt-sv-* 全族)。**逐条照抄,不许自己估**:padding / gap / 圆角 / 字号 / 行高 /\n * 边框色 / 悬停色 / 透明度动画 / 溢出策略,一一对应,改这里之前先去那边对原文。\n * 前缀与变量名换成本仓口径(--tdt-* → --dshpc-*),数值不换。\n *\n * 控件:能核心就核心(面包屑 = Button ghost、行尾 = Button outline、展开 / 图标 = IconButton、\n * 分段 = Segmented、文字 = MarqueeText)。核心控件自带的 padding / 高度 / 皮肤在本文件里\n * **按兄弟数值覆盖**(选择器带 .dshpc-fb 前缀提高特异性,确保盖得住控件默认值)。\n */\n.dshpc-fb{\n position:relative;display:flex;flex-direction:column;height:100%;min-height:0;\n background:var(--dshpc-surface-base);color:var(--dshpc-fg);\n}\n\n/* 第一排:▾ 选层 + 面包屑 + 动作(兄弟 .dsh-tdt-sv-crumbbar)\n ⚠️ 不能 overflow:hidden —— 下拉浮层挂在它下面,裁了就看不见。 */\n.dshpc-fb__bar{\n position:relative;flex:none;display:flex;align-items:center;gap:2px;\n padding:4px 10px;border-bottom:1px solid var(--dshpc-border);white-space:nowrap;\n}\n.dshpc-fb__menu-wrap{position:relative;flex:none;display:inline-flex}\n.dshpc-fb__crumbs{position:relative;flex:1;min-width:0;display:flex;align-items:center;gap:2px;overflow:hidden}\n.dshpc-fb__crumbs-measure{\n position:absolute;top:0;left:0;display:inline-flex;align-items:center;gap:2px;\n visibility:hidden;pointer-events:none;white-space:nowrap;\n}\n\n/* 面包屑:核心 ghost 钮,但皮肤与尺寸取兄弟 .dsh-tdt-sv-crumb(高由内容决定,不锁控制高)。 */\n.dshpc-fb .dshpc-fb__crumb{\n appearance:none;background:0 0;border:none;height:auto;\n padding:2px 4px;border-radius:var(--dshpc-radius-sm);\n font:inherit;font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);\n color:var(--dshpc-fg-2);cursor:pointer;\n display:inline-flex;align-items:center;min-width:0;overflow:hidden;text-overflow:ellipsis;\n}\n.dshpc-fb .dshpc-fb__crumb:hover{background:var(--dshpc-hover);color:var(--dshpc-fg)}\n.dshpc-fb .dshpc-fb__crumb:disabled{color:var(--dshpc-fg-2);cursor:default}\n.dshpc-fb .dshpc-fb__crumb--current{cursor:default;color:var(--dshpc-fg);font-weight:600;min-width:0}\n.dshpc-fb .dshpc-fb__crumb--current:hover{background:0 0}\n.dshpc-fb__crumb-mq{flex:1 1 auto;min-width:0}\n.dshpc-fb__crumb-sep{flex:none;color:var(--dshpc-fg-3)}\n\n/* 越界(outside-workspace)第一排:只读完整路径(兄弟 .dsh-tdt-sv-crumbbar-plain-inner)。 */\n.dshpc-fb__bar-plain{\n font-family:var(--dshpc-font-mono,ui-monospace,SFMono-Regular,Menlo,Consolas,monospace);\n font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);color:var(--dshpc-fg-2);\n white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:default;user-select:none;\n}\n.dshpc-fb__actions{flex:none;display:flex;align-items:center;gap:4px}\n\n/* ▾ 选层浮层(兄弟 .dsh-tdt-sv-crumbs-*)。\n 层序:兄弟是 30/31;本仓 picker 面板是 1100,遮罩必须高于它,否则菜单开着点面板不算「点外部」。 */\n.dshpc-fb__crumbs-backdrop{position:fixed;inset:0;z-index:1200;background:transparent}\n.dshpc-fb__crumbs-menu{\n position:absolute;top:calc(100% + 4px);left:0;z-index:1201;min-width:160px;max-height:240px;overflow:auto;\n background:var(--dshpc-surface-menu);border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-sm);\n box-shadow:0 4px 16px rgba(0,0,0,.18);padding:4px;display:flex;flex-direction:column;\n}\n.dshpc-fb__menu-item{\n appearance:none;background:0 0;border:none;text-align:left;font:inherit;\n font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-md);\n padding:4px 8px;border-radius:var(--dshpc-radius-sm);color:var(--dshpc-fg);cursor:pointer;\n max-width:280px;display:flex;align-items:center;gap:2px;\n overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\n}\n.dshpc-fb__menu-item:hover{background:var(--dshpc-hover)}\n.dshpc-fb__menu-empty{\n font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-md);padding:4px 8px;color:var(--dshpc-fg-3);\n}\n.dshpc-fb__menu-icon{flex:none;display:inline-flex}\n.dshpc-fb__menu-chev{flex:none;color:var(--dshpc-fg-3);margin-right:1px}\n.dshpc-fb__menu-chev-slot{flex:none;width:11px;height:11px;margin-right:1px}\n.dshpc-fb__menu-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n\n/* 第二排(仅预览态):文件名 + 工具(兄弟 .dsh-tdt-sv-titlebar / -preview-title-inner)。 */\n.dshpc-fb__title{\n flex:none;display:flex;align-items:center;gap:8px;\n padding:8px 14px;border-bottom:1px solid var(--dshpc-border);\n}\n.dshpc-fb__title-inner{\n font-family:var(--dshpc-font-mono,ui-monospace,SFMono-Regular,Menlo,Consolas,monospace);\n font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);color:var(--dshpc-fg);\n white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:default;\n}\n\n/* 主体(兄弟 .dsh-tdt-sv-preview-body / -hint / -preview-err) */\n.dshpc-fb__body{flex:1;min-height:0;overflow-x:hidden;overflow-y:auto;padding:12px 14px}\n.dshpc-fb__note{font-size:var(--dshpc-font-sm);color:var(--dshpc-fg-2);text-align:center;padding:12px 0}\n.dshpc-fb__err{\n display:flex;flex-direction:column;align-items:flex-start;gap:10px;\n font-size:var(--dshpc-font-sm);line-height:1.6;color:var(--dshpc-fg-2);padding:8px 0;\n}\n\n/* 目录树(兄弟 .dsh-tdt-sv-tree*) */\n.dshpc-fb__tree{flex:1;min-height:0;overflow:auto;padding:6px 8px}\n.dshpc-fb__row{\n display:flex;align-items:center;gap:8px;padding:6px 8px;\n border-radius:var(--dshpc-radius-sm);cursor:pointer;user-select:none;\n}\n.dshpc-fb__row:hover{background:var(--dshpc-hover)}\n.dshpc-fb__row:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:-2px}\n.dshpc-fb__row-icon{flex:none;display:inline-flex;color:var(--dshpc-fg-2)}\n.dshpc-fb__row-name{\n flex:1;min-width:0;font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);color:var(--dshpc-fg);\n overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\n}\n\n/* 展开开关:核心 IconButton,命中位 20×20 + 展开时转 90°(兄弟 .dsh-tdt-sv-tree-toggle{,-open})。 */\n.dshpc-fb .dshpc-fb__row-toggle{\n appearance:none;background:0 0;border:none;flex:none;\n width:20px;height:20px;padding:0;margin:0;border-radius:var(--dshpc-radius-sm);\n color:var(--dshpc-fg-2);cursor:pointer;\n display:inline-flex;align-items:center;justify-content:center;\n transition:transform var(--dshpc-dur-fast) var(--dshpc-ease),background var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-fb .dshpc-fb__row-toggle--open{transform:rotate(90deg)}\n\n/* 行尾「进入 / 选择」:核心 outline 钮,皮肤取兄弟 .dsh-tdt-sv-tree-act(高由内容决定)。\n 平时隐身但占位(opacity 而非 display)⇒ 出现时不顶动行内布局。 */\n.dshpc-fb .dshpc-fb__row-act{\n flex:none;margin-left:auto;appearance:none;background:0 0;\n border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-sm);\n height:auto;padding:2px 8px;font-size:var(--dshpc-font-sm);line-height:1.4;\n color:var(--dshpc-fg-2);cursor:pointer;\n opacity:0;pointer-events:none;\n transition:opacity var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-fb__row:hover .dshpc-fb__row-act,.dshpc-fb .dshpc-fb__row-act:focus-visible{opacity:1;pointer-events:auto}\n.dshpc-fb .dshpc-fb__row-act:hover{background:var(--dshpc-hover);color:var(--dshpc-fg)}\n\n.dshpc-fb__row-children{\n margin-left:9px;padding-left:7px;border-left:1px solid var(--dshpc-border);\n display:flex;flex-direction:column;\n}\n.dshpc-fb__row-note{flex:none;padding:8px 10px;font-size:var(--dshpc-font-sm);color:var(--dshpc-fg-3)}\n.dshpc-fb__row-err{padding:4px 8px 4px 36px;font-size:var(--dshpc-font-sm);color:var(--dshpc-danger)}\n\n/* 预览体内部容器(仅本仓预览组件用;兄弟对应 preview-fill / preview-body-code 一类)。\n 必须 border-box:渲染态 inline 加了 padding:12px 14px,content-box 下 width:100%+padding\n 会溢出父层 28px(父 .dshpc-fb 无 overflow 裁切)→ 恒多一条横滚条;border-box 把 padding\n 算进 100%,从根消除该溢出。 */\n.dshpc-fb__text{flex:1;min-height:0;overflow:auto;width:100%;box-sizing:border-box}\n.dshpc-fb__banner{padding:6px 10px;background:var(--dshpc-open-bg);color:var(--dshpc-fg-2);font-size:var(--dshpc-font-sm)}\n.dshpc-fb__more{display:flex;justify-content:center;padding:10px}\n.dshpc-fb__image{max-width:100%;border-radius:var(--dshpc-radius-sm);border:1px solid var(--dshpc-border)}\n/* iframe 的外壳(兄弟 .dsh-tdt-sv-preview-fill):iframe 必须包在这一层里才拿得到高度——\n 裸挂 iframe 时替换元素的自动最小尺寸会让高度算不出来(表现为预览区整片空白、像没反应)。 */\n.dshpc-fb__fill{flex:1;min-height:0;display:flex;overflow:hidden;padding:0}\n.dshpc-fb__frame{flex:1;min-height:0;width:100%;height:100%;border:none;background:var(--dshpc-surface-1)}\n";
|
|
170
|
-
//#endregion
|
|
171
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/session/session-css.generated.js
|
|
172
|
-
const SESSION_CSS = "/* 会话预览(SessionViewModal)自绘样式:只装本包自己的组件(暂存输入区 / fork / 探针等)\n + 两个稳定钩子类(dshpc-sv-frame / dshpc-sv-scroll)。\n 已删:ChangedFiles 卡与 FileDiff 的全部自绘规则(2026-10-24)——官方 ChangedFiles /\n FileDiff 模块类由 officialClass() 运行时发现并挂在元素上,本包不再有一行兜底。\n ⚠️ 2026-10-23 起不再有官方类兜底:镜像官方组件的元素一律挂官方 CSS-module 类名\n (officialClass() 运行时发现,取不到 = 空类、裸结构不白屏)——本包只跑 DSH 宿主、官方样式必在场,\n 自绘一一对应是死代码。要改官方观感走 token 覆盖 / 双类名钩子(见 ChatView.ts 头注),别在这加兜底。\n 类名固定 dshpc-sv-*;颜色一律走 --dshpc-* token(明暗自适应)。\n 外壳(遮罩 / 面板 / 头部 / 关闭钮)= 核心 Modal(size lg)。 */\n/* 会话区 = 普通纵向流:不设高度、不自己滚(滚动与内距归核心 Modal body,用户 2026-10-22 口径)。 */\n.dshpc-sv{display:flex;flex-direction:column;min-width:0;gap:10px}\n\n/* 官方样式未命中时的可见探针(挂在头部副标题行,不占正文)。 */\n.dshpc-sv-probe{font-size:var(--dshpc-font-xs);color:var(--dshpc-warning,#b7791f)}\n\n/* 头部归档标识(官方归档图标 + 「已归档」)。 */\n.dshpc-sv-archived{display:inline-flex;align-items:center;gap:4px;font-size:var(--dshpc-font-xs);font-weight:400;color:var(--dshpc-fg-3)}\n\n/* 内距与滚动全部让给核心 Modal body ⇒ 这里把官方 ChatView.frame / scroll 的内距、\n overflow、高度一律归零(双类名 0,2,0 压过 CSS module,不靠注入顺序)。\n ⚠️ 必须同时把 flex 收掉:官方 scroll 是 flex:1(basis=0),在**自动高**的容器里会把\n 会话区压成 0 高 —— 这正是「内容自管高度」的老毛病,别再放回来。 */\n.dshpc-sv-frame.dshpc-sv-frame{padding-top:0;padding-bottom:0;}\n\n.dshpc-sv-scroll.dshpc-sv-scroll{padding:0;overflow:visible;height:auto;max-height:none;flex:none;}\n\n/* 会话区保底:高度由内容决定(撑开由 Modal body 滚)。 */\n.dshpc-sv-chat{flex:none;min-height:0;}\n\n\n.dshpc-sv-assistant{align-self:stretch;font-size:var(--dshpc-font-lg);line-height:1.7;word-break:break-word;}\n\n.dshpc-sv-image{align-self:flex-start;font-size:var(--dshpc-font-sm);color:var(--dshpc-fg-3,rgba(128,128,128,.8));border:1px dashed var(--dshpc-border,rgba(128,128,128,.35));border-radius:var(--dshpc-radius-sm);padding:4px 10px;}\n\n/* 工具卡根(SessionViewModal legacy 兜底渲染直接用;正常 keyed 路径一律挂官方 ToolRow 类)。 */\n.dshpc-sv-tool{flex-direction:column;display:flex;}\n\n.dshpc-sv-notice{align-self:center;font-size:var(--dshpc-font-sm);color:var(--dshpc-fg-3,rgba(128,128,128,.8));padding:2px 8px;}\n\n\n.dshpc-sv-forkerr{margin:0;font-size:var(--dshpc-font-lg);line-height:var(--dshpc-line-lg);color:var(--dshpc-danger,#e5484d);word-break:break-word;}\n\n.dshpc-sv-forktext{margin:0;font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);color:var(--dshpc-fg-2);}\n\n/* ── 暂存输入区(期4:打字 → 确定 → fork 带话跳官方视图)── */\n.dshpc-sv-composer{flex:1;display:flex;align-items:flex-end;gap:8px;flex-wrap:wrap;}\n\n.dshpc-sv-composer textarea{flex:1;min-width:0;resize:none;font:inherit;font-size:var(--dshpc-font-lg);line-height:var(--dshpc-line-lg);color:var(--dshpc-fg,#1f2328);background:var(--dshpc-surface-2,rgba(128,128,128,.10));border:1px solid var(--dshpc-border,rgba(128,128,128,.28));border-radius:var(--dshpc-radius-md);padding:8px 12px;min-height:40px;max-height:120px;}\n\n.dshpc-sv-composer textarea:focus-visible{outline:2px solid var(--dshpc-focus,#3b5bdb);outline-offset:-1px;}\n\n.dshpc-sv-composer-hint{flex:none;font-size:var(--dshpc-font-xs);color:var(--dshpc-fg-3,rgba(128,128,128,.8));padding-bottom:10px;white-space:nowrap;}";
|
|
173
|
-
//#endregion
|
|
174
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/css.js
|
|
175
|
-
const CONTROLS_DOMAIN = "controls";
|
|
176
|
-
/**
|
|
177
|
-
* 全部控件样式(数组顺序不可调换:同特异性规则后注入者胜出)。
|
|
178
|
-
* 导出仅供 `test/css-contract.test.mjs` 做文本自检,不作为对外 API。
|
|
179
|
-
*/
|
|
180
|
-
const CONTROLS_CSS = [
|
|
181
|
-
SEGMENTED_CSS,
|
|
182
|
-
BUTTON_CSS,
|
|
183
|
-
FIELD_CSS,
|
|
184
|
-
LOADING_CSS,
|
|
185
|
-
BACK_TO_TOP_CSS,
|
|
186
|
-
HINT_CSS,
|
|
187
|
-
PICKER_CSS,
|
|
188
|
-
DATETIME_CSS,
|
|
189
|
-
FEEDBACK_CSS,
|
|
190
|
-
EXPLORER_CSS,
|
|
191
|
-
SESSION_CSS,
|
|
192
|
-
CARD_CSS,
|
|
193
|
-
CHIP_CSS,
|
|
194
|
-
MARQUEE_CSS,
|
|
195
|
-
PANEL_DOCK_CSS,
|
|
196
|
-
CODE_VIEWER_CSS,
|
|
197
|
-
SPLIT_GROUP_CSS
|
|
198
|
-
].join("\n");
|
|
123
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/css.js
|
|
199
124
|
/**
|
|
200
125
|
* 当前插件的样式设施。
|
|
201
126
|
*
|
|
@@ -210,13 +135,33 @@ window.__ModuleLoader__.load({
|
|
|
210
135
|
function getStyleKit() {
|
|
211
136
|
return current$1;
|
|
212
137
|
}
|
|
213
|
-
/**
|
|
138
|
+
/**
|
|
139
|
+
* 只登记 token 变量(幂等;不挂载 `<style>`)。
|
|
140
|
+
*
|
|
141
|
+
* 插件启动时调一次做预热是安全的,但**不是必需的** —— 任何控件首次渲染时
|
|
142
|
+
* 也会自行登记 token(见 {@link ensureComponentStyles})。token 域始终排在所有控件域之前
|
|
143
|
+
* (`style-kit.ts` 的 composeCss 强制),所以颜色 / 变量引用链不受拆分影响。
|
|
144
|
+
*/
|
|
214
145
|
function ensureControls(kit = current$1) {
|
|
215
146
|
kit.registerStyle("tokens", kit.tokensCss);
|
|
216
|
-
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* 确保某个控件自己的样式已登记、且 `<style>` 已挂载(幂等,可直接在 render 里调)。
|
|
150
|
+
*
|
|
151
|
+
* 每个控件**只传自己那份 CSS**:把它依赖的那 1~2 份传进来即可,绝不能顺手把别人的拼上去
|
|
152
|
+
* (一拼就又退化成全量,包体省不下来)。同理,若是某份 CSS 里带上下文限定的修饰
|
|
153
|
+
* (如 `.dshpc-split .dshpc-seg`),那份由提供上下文的控件自己负责,消费者不用管。
|
|
154
|
+
*
|
|
155
|
+
* @param domain 本控件的样式域,repo 内唯一。
|
|
156
|
+
* @param css 该控件自己的 CSS 文本。
|
|
157
|
+
* @param kit 样式设施(默认取当前插件的 kit)。
|
|
158
|
+
*/
|
|
159
|
+
function ensureComponentStyles(domain, css, kit = current$1) {
|
|
160
|
+
kit.registerStyle("tokens", kit.tokensCss);
|
|
161
|
+
kit.applyStyle(domain, css);
|
|
217
162
|
}
|
|
218
163
|
//#endregion
|
|
219
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
164
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/picker-logic.js
|
|
220
165
|
/** 两种输入归一成 groups:给了 `options` 就当成一个无标题的组。 */
|
|
221
166
|
function toGroups(groups, options) {
|
|
222
167
|
if (groups !== void 0 && groups.length > 0) return groups;
|
|
@@ -2450,7 +2395,7 @@ window.__ModuleLoader__.load({
|
|
|
2450
2395
|
]);
|
|
2451
2396
|
}
|
|
2452
2397
|
//#endregion
|
|
2453
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
2398
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/chevron.js
|
|
2454
2399
|
/**
|
|
2455
2400
|
* 全站唯一的箭头:**自绘 chevron**(就是下拉框右侧那颗)。
|
|
2456
2401
|
*
|
|
@@ -2488,7 +2433,7 @@ window.__ModuleLoader__.load({
|
|
|
2488
2433
|
}));
|
|
2489
2434
|
}
|
|
2490
2435
|
//#endregion
|
|
2491
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
2436
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/utils/i18n.js
|
|
2492
2437
|
/**
|
|
2493
2438
|
* utils 自带的最小多语言。
|
|
2494
2439
|
*
|
|
@@ -3025,7 +2970,22 @@ window.__ModuleLoader__.load({
|
|
|
3025
2970
|
});
|
|
3026
2971
|
}
|
|
3027
2972
|
//#endregion
|
|
3028
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
2973
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/controls/segmented-css.generated.js
|
|
2974
|
+
const SEGMENTED_CSS = "\n/* ── 分段控件 P2 ─────────────────────────────────────────────────────\n 结构照兄弟项目 dsh-task-dispatch-table 的 Segmented 皮肤(item 无边框、hover 只提亮文字),\n 前缀 / 变量名换成本仓口径。用户额外要的两处(兄弟没有):weekday 方块间隔(现为 2px);段内中性计数 __count。\n ⚠️ 2026-10-19 两次误判均已澄清:① 「宿主只认单行 CSS」——假,多行一直正常;\n ② 「宿主吃掉 token 块之后第一条规则」——也假,真因是 tokens 模板字符串结尾多了一个反斜杠,\n 注入文本里留下字面反引号,把紧随其后的那条规则的选择器污染掉了(见 dsh-host.md §9)。\n 样式照常多行书写,不必压行;也不需要任何「牺牲规则」。 */\n/* 外观只有一套(2026-10-26):原 variant 的 default / inset 两档在 CSS 里只差 1px 内距,\n 且 default 比文档承诺矮 2px,却让下游以为「有得选」而反复对图 ⇒ 整轴删除。\n padding 3px 是尺寸契约的一部分:item 高度 = 控制高 − 6px,加起来正好 24 / 28 / 32。 */\n/* 选中片配色收在两条局部变量里(--seg-thumb 底 / --seg-on 字):默认走主题亮片,\n tone 档与自定义 {bg, fg} 都只改这两条(后者由组件内联写根节点,内联恒胜)。 */\n.dshpc-seg{display:inline-flex;align-items:center;gap:2px;padding:3px;border-radius:var(--dshpc-radius-md);--seg-thumb:var(--dshpc-surface-raised);--seg-on:var(--dshpc-fg);background:var(--dshpc-seg-track);}\n.dshpc-seg__item{appearance:none;display:inline-flex;align-items:center;gap:4px;box-sizing:border-box;height:calc(var(--dshpc-control-h-sm) - 6px);padding:0 12px;border:0;border-radius:var(--dshpc-radius-sm);background:transparent;color:var(--dshpc-fg-2);font-family:inherit;font-size:var(--dshpc-font-xs);font-weight:500;white-space:nowrap;cursor:pointer;flex:none;transition:color var(--dshpc-dur-fast) var(--dshpc-ease),background-color var(--dshpc-dur-fast) var(--dshpc-ease),box-shadow var(--dshpc-dur-fast) var(--dshpc-ease);}\n.dshpc-seg--md .dshpc-seg__item{height:calc(var(--dshpc-control-h-md) - 6px);}\n.dshpc-seg--lg .dshpc-seg__item{height:calc(var(--dshpc-control-h-lg) - 6px);}\n.dshpc-seg__item:hover:not([aria-pressed='true']):not(:disabled){color:var(--dshpc-fg);}\n.dshpc-seg__item[aria-pressed='true']{background:var(--seg-thumb);box-shadow:var(--dshpc-shadow-raised);color:var(--seg-on);font-weight:600;}\n.dshpc-seg__item:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:-2px;}\n.dshpc-seg__item:disabled{cursor:default;opacity:.4;}\n/* 段内角标(如「异常」的数量):语义色实面 + 反白字,0 由组件侧不渲染。必须是正圆(用户 2026-10-03)。 */\n.dshpc-seg__badge{display:inline-flex;align-items:center;justify-content:center;flex:none;width:16px;height:16px;padding:0;overflow:hidden;border-radius:50%;background:var(--dshpc-danger);color:var(--dshpc-on-signal);font-size:10px;line-height:16px;font-weight:500;font-variant-numeric:tabular-nums;}\n/* 段内中性计数(如筛选条「全部 11」):纯文字、无底无边(对齐 task-ledger .dtl-seg__num 拍板口径);0 由组件侧不渲染。 */\n.dshpc-seg__count{display:inline;flex:none;margin-left:3px;padding:0;border:0;border-radius:0;background:none;color:var(--dshpc-fg-3);font-size:10px;line-height:1;font-weight:400;font-variant-numeric:tabular-nums;}\n/* 选中段(彩色实面)里的计数:必须跟着 --seg-on 走再压暗一档(72% 白 ≈ 「比正文稍灰」)。\n 不许用 --dshpc-fg-3:它跟主题走,暗色下是深灰 ⇒ 蓝底上几乎看不见(2026-10-29 用户截图「My todos 4」)。 */\n.dshpc-seg__item[aria-pressed='true'] .dshpc-seg__count{color:color-mix(in srgb,var(--seg-on) 72%,transparent);}\n/* block:撑满父宽(表单行用),各段等分 */\n.dshpc-seg--block{display:flex;width:100%;}\n.dshpc-seg--block .dshpc-seg__item{flex:1 1 auto;justify-content:center;}\n/* weekday:星期多选方块。基础插件的特殊化定制(用户 2026-10-01:原 WeekdayPicker 即「蓝底 + 近似方形」):\n 每格正方形(宽 = 段高)、选中品牌蓝反白字、**无外描边**(2026-10-18 重申)、\n 方块之间间距 gap:2px(2026-10-20 用户定稿:方块改小后 6px 显得太宽。10-18 曾从 2px 放宽到 6px,\n 两次都是用户拍板 —— 别自作主张改回去)。 */\n.dshpc-seg--weekday{--seg-track:var(--dshpc-seg-track);gap:2px;border:0;padding:3px;background:var(--seg-track);}\n.dshpc-seg--weekday .dshpc-seg__item{width:calc(var(--dshpc-control-h-lg) - 8px);padding:0;justify-content:center;}\n/* 蓝底反白:字色必须是常量白(--dshpc-on-signal)。2026-10-29 用户实测:暗色主题下这里曾用\n --dshpc-fg-inverse,而它跟随宿主 label-primary-foreground,暗色下是近黑 ⇒ 蓝底黑字看不清。 */\n.dshpc-seg--weekday{--seg-thumb:var(--dshpc-business);--seg-on:var(--dshpc-on-signal);}\n\n/* ── tone(2026-10-29 用户):选中片传内置基础色名,底 / 字由核心给,深浅两主题各自成立。\n 放在 weekday 之后:同名变量后写者胜,tone 与 className=\"dshpc-seg--weekday\" 同给时以 tone 为准。\n 黄底按 Chip / Button 同源口径用 on-warning(中高明度,白字看不清)。 */\n.dshpc-seg--tone-business{--seg-thumb:var(--dshpc-business);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-success{--seg-thumb:var(--dshpc-success);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-warning{--seg-thumb:var(--dshpc-warning);--seg-on:var(--dshpc-on-warning);}\n.dshpc-seg--tone-danger{--seg-thumb:var(--dshpc-danger);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-purple{--seg-thumb:var(--dshpc-purple);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-pink{--seg-thumb:var(--dshpc-pink);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-cyan{--seg-thumb:var(--dshpc-cyan);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-teal{--seg-thumb:var(--dshpc-teal);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-orange{--seg-thumb:var(--dshpc-orange);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-indigo{--seg-thumb:var(--dshpc-indigo);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-rose{--seg-thumb:var(--dshpc-rose);--seg-on:var(--dshpc-on-signal);}\n.dshpc-seg--tone-slate{--seg-thumb:var(--dshpc-slate);--seg-on:var(--dshpc-on-signal);}\n\n/* ── 单选滑动块(2026-10-26 用户:点选后选中底应「滑过去」,不是旧段消失、新段直接亮)。\n 结构 = 一块绝对定位的共用底 + 各段透明;位置/尺寸由组件量出后内联,这里只管外观与过渡。\n --slide 只在单选挂上:多选(如星期)每段各自着色,没有唯一滑块可滑,保持原样。 */\n.dshpc-seg--slide{position:relative;}\n.dshpc-seg--slide .dshpc-seg__item{position:relative;z-index:1;}\n.dshpc-seg--slide .dshpc-seg__item[aria-pressed='true']{background:transparent;box-shadow:none;}\n.dshpc-seg__thumb{position:absolute;z-index:0;border-radius:var(--dshpc-radius-sm);background:var(--seg-thumb);box-shadow:var(--dshpc-shadow-raised);pointer-events:none;transition:left var(--dshpc-dur) var(--dshpc-ease),top var(--dshpc-dur) var(--dshpc-ease),width var(--dshpc-dur) var(--dshpc-ease),height var(--dshpc-dur) var(--dshpc-ease);}\n\n/* ── bordered 外框(2026-10-20 用户要的第二种模式):**只在最外面套一圈 1px 描边**,\n 里面一概不动 —— 选中片的填充色 / 阴影 / 文字色全部保持原样(weekday 的蓝面照旧),\n 这里不写任何针对 __item 的规则。\n 总高必须与无框版逐像素一致:border 1px×2 由 padding 各让 1px 抵消(3 → 2);\n weekday 自己声明的 3px 在文件更后面,靠双类选择器压回 2px。 */\n.dshpc-seg--bordered{border:1px solid var(--dshpc-border);padding:2px;}\n.dshpc-seg--bordered.dshpc-seg--weekday{padding:2px;}\n\n@media (prefers-reduced-motion: reduce){.dshpc-seg__item{transition:none;}.dshpc-seg__thumb{transition:none;}}\n";
|
|
2975
|
+
//#endregion
|
|
2976
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/controls/button-css.generated.js
|
|
2977
|
+
const BUTTON_CSS = "\n/* ── 按钮 / 图标钮 P2 ───────────────────────────────────────────────────\n 与 Segmented 同一条高度纪律:--dshpc-control-h-sm(24) / -md(28) / -lg(32),\n 有边框的 variant 用 1px 真边框 + 内部 padding 补回,**有边 / 无边同高**。\n\n 三条受控轴(2026-10-19 重写,对齐主流 UI 框架的分类口径):\n · variant —— 外观档 = 形态 + 语义色,共 10 档:\n primary / secondary / outline / ghost / danger / success / warning / info /\n danger-outline(红字描边)/ link(行内链接)\n · size —— sm / md / lg\n · block —— 撑满父宽\n 每一档**只填 5 个局部变量**(--btn-bg / -fg / -border / -bg-hover / -bg-active),\n 结构与交互只有上面这一份;任何档位都不许再写一遍 display/height/padding。\n 自定义颜色(Button 的 color 参数)同样只覆盖这 5 个变量(token 覆盖,不是新皮肤)。\n\n ⚠️ hover 不再用 opacity 压一层(用户 2026-10-19:「黑色和红色的按钮移上去变化太小,\n 完全感觉不到颜色变了」)⇒ 走 --dshpc-*-hover / -active 的明确混色,见 tokens-css.ts。 */\n.dshpc-btn{--btn-bg:transparent;--btn-fg:var(--dshpc-fg);--btn-border:transparent;--btn-pad:12px;\n --btn-bg-hover:var(--dshpc-hover);--btn-bg-active:var(--dshpc-active);--btn-fg-hover:var(--btn-fg);\n appearance:none;display:inline-flex;align-items:center;justify-content:center;gap:6px;\n box-sizing:border-box;border:1px solid var(--btn-border);border-radius:var(--dshpc-radius-md);\n background-color:var(--btn-bg);color:var(--btn-fg);font-family:inherit;font-weight:500;white-space:nowrap;cursor:pointer;\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),border-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease),box-shadow var(--dshpc-dur-fast) var(--dshpc-ease),transform var(--dshpc-dur-fast) var(--dshpc-ease);}\n.dshpc-btn--sm{--btn-pad:10px;height:var(--dshpc-control-h-sm);padding:0 var(--btn-pad);font-size:var(--dshpc-font-sm);line-height:1;}\n.dshpc-btn--md{--btn-pad:12px;height:var(--dshpc-control-h-md);padding:0 var(--btn-pad);font-size:var(--dshpc-font-md);line-height:1;}\n.dshpc-btn--lg{--btn-pad:14px;height:var(--dshpc-control-h-lg);padding:0 var(--btn-pad);font-size:var(--dshpc-font-md);line-height:1;}\n/* block:撑满父宽(表单底栏 / 抽屉底部的主操作) */\n.dshpc-btn--block{display:flex;width:100%;}\n/* block + 前置图标 ⇒ 文字视觉居中(2026-10-19 用户点名):\n 内容组 [图标 + 间距 + 文字] 整体在盒内居中时,**文字**的中心会被图标推右半格。\n 把右内边距补上「图标宽 + 间距」,可用盒随之左移同量 ⇒ 文字落回视觉中心,图标贴左侧。\n 图标宽按 1.2em 估(官方图标 14/16px vs 字号 12/13px),em 随字号档自动缩放。 */\n.dshpc-btn--block.dshpc-btn--icon-start{padding-right:calc(var(--btn-pad) + 1.2em + 6px);}\n.dshpc-btn__icon,.dshpc-btn__icon-end{display:inline-flex;align-items:center;justify-content:center;flex:none;line-height:0;}\n.dshpc-btn__icon svg,.dshpc-btn__icon-end svg{display:block;margin:0;}\n/* maxWidth 包 MarqueeText 时:标签作为 flex 子项必须能收缩到内容以下,否则省略号 / 跑马灯测不准 */\n.dshpc-btn .dshpc-btn__label{min-width:0;}\n/* loading:不换 DOM 结构,只在文案前插一枚 Loader(size=xs,12px)。\n 环的画法与动画统一在 controls/loader.css(本文件不再维护第二份 SVG 弧 / keyframes)。 */\n\n/* 交互态:颜色变化写在变量上 ⇒ 所有档位一次生效,且变化幅度由 token 决定(够明显) */\n.dshpc-btn:hover:not(:disabled){background-color:var(--btn-bg-hover);color:var(--btn-fg-hover);}\n.dshpc-btn:active:not(:disabled){background-color:var(--btn-bg-active);transform:translateY(1px);}\n.dshpc-btn:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:2px;}\n.dshpc-btn:disabled{cursor:default;opacity:.5;}\n\n.dshpc-btn--primary{--btn-bg:var(--dshpc-accent);--btn-fg:var(--dshpc-fg-inverse);\n --btn-bg-hover:var(--dshpc-accent-hover);--btn-bg-active:var(--dshpc-accent-active);}\n/* secondary:中性实心(灰面),用于「取消 / 次要」这类与主操作并排的按钮 */\n.dshpc-btn--secondary{--btn-bg:var(--dshpc-hover);--btn-fg:var(--dshpc-fg);\n --btn-bg-hover:var(--dshpc-active);--btn-bg-active:var(--dshpc-active);}\n.dshpc-btn--outline{--btn-bg:var(--dshpc-surface-1);--btn-border:var(--dshpc-border-strong);\n --btn-bg-hover:var(--dshpc-hover);--btn-bg-active:var(--dshpc-active);}\n.dshpc-btn--ghost{--btn-fg:var(--dshpc-fg-2);--btn-fg-hover:var(--dshpc-fg);\n --btn-bg-hover:var(--dshpc-hover);--btn-bg-active:var(--dshpc-active);}\n.dshpc-btn--danger{--btn-bg:var(--dshpc-danger);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-danger-hover);--btn-bg-active:var(--dshpc-danger-active);}\n.dshpc-btn--success{--btn-bg:var(--dshpc-success);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-success-hover);--btn-bg-active:var(--dshpc-success-active);}\n.dshpc-btn--warning{--btn-bg:var(--dshpc-warning);--btn-fg:var(--dshpc-on-warning);\n --btn-bg-hover:var(--dshpc-warning-hover);--btn-bg-active:var(--dshpc-warning-active);}\n.dshpc-btn--info{--btn-bg:var(--dshpc-business);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-business-hover);--btn-bg-active:var(--dshpc-business-active);}\n/* 扩展八色实心(2026-10-29):白字两主题均 ≥4.5:1;hover/active 走各自 token 派生。 */\n.dshpc-btn--purple{--btn-bg:var(--dshpc-purple);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-purple-hover);--btn-bg-active:var(--dshpc-purple-active);}\n.dshpc-btn--pink{--btn-bg:var(--dshpc-pink);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-pink-hover);--btn-bg-active:var(--dshpc-pink-active);}\n.dshpc-btn--cyan{--btn-bg:var(--dshpc-cyan);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-cyan-hover);--btn-bg-active:var(--dshpc-cyan-active);}\n.dshpc-btn--teal{--btn-bg:var(--dshpc-teal);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-teal-hover);--btn-bg-active:var(--dshpc-teal-active);}\n.dshpc-btn--orange{--btn-bg:var(--dshpc-orange);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-orange-hover);--btn-bg-active:var(--dshpc-orange-active);}\n.dshpc-btn--indigo{--btn-bg:var(--dshpc-indigo);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-indigo-hover);--btn-bg-active:var(--dshpc-indigo-active);}\n.dshpc-btn--rose{--btn-bg:var(--dshpc-rose);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-rose-hover);--btn-bg-active:var(--dshpc-rose-active);}\n.dshpc-btn--slate{--btn-bg:var(--dshpc-slate);--btn-fg:var(--dshpc-on-signal);\n --btn-bg-hover:var(--dshpc-slate-hover);--btn-bg-active:var(--dshpc-slate-active);}\n/* danger-outline:红字描边(破坏性次要操作,如卡片上的「删除」)。\n ⚠️ 旧修饰类 danger-ink 保留为别名(消费方可能还在挂),两者同一套皮肤。 */\n.dshpc-btn--danger-outline,.dshpc-btn--danger-ink{--btn-border:var(--dshpc-danger);--btn-fg:var(--dshpc-danger);\n --btn-fg-hover:var(--dshpc-danger);--btn-bg-hover:var(--dshpc-danger-soft);--btn-bg-active:var(--dshpc-danger-soft);}\n/* link:行内文字链接型(会话 / 产出文件名),无底无边、品牌蓝、hover 下划线 */\n.dshpc-btn--link{--btn-fg:var(--dshpc-link);--btn-fg-hover:var(--dshpc-link);\n --btn-bg-hover:transparent;--btn-bg-active:transparent;\n height:auto;padding:0;border:0;background:none;font-weight:400;text-align:left;}\n.dshpc-btn--link:hover:not(:disabled){text-decoration:underline;}\n\n/* 图标钮:纯图标,方形;尺寸档的宽高与同档文字按钮等高、圆角统一吃 md(与 .dshpc-btn 同款,2026-10-28 拍板) */\n.dshpc-iconbtn{appearance:none;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;\n border:1px solid transparent;border-radius:var(--dshpc-radius-md);background:transparent;color:var(--dshpc-fg-2);\n font-family:inherit;cursor:pointer;flex:none;\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),border-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease),opacity var(--dshpc-dur-fast) var(--dshpc-ease);}\n.dshpc-iconbtn--sm{width:var(--dshpc-control-h-sm);height:var(--dshpc-control-h-sm);font-size:var(--dshpc-font-sm);}\n.dshpc-iconbtn--md{width:var(--dshpc-control-h-md);height:var(--dshpc-control-h-md);font-size:var(--dshpc-font-md);}\n.dshpc-iconbtn--lg{width:var(--dshpc-control-h-lg);height:var(--dshpc-control-h-lg);font-size:var(--dshpc-font-md);}\n.dshpc-iconbtn--plain{color:var(--dshpc-fg-2);}\n.dshpc-iconbtn--outline{background:var(--dshpc-surface-1);border-color:var(--dshpc-border);color:var(--dshpc-fg-2);}\n.dshpc-iconbtn--danger{color:var(--dshpc-danger);}\n.dshpc-iconbtn:hover:not(:disabled){background:var(--dshpc-hover);color:var(--dshpc-fg);}\n.dshpc-iconbtn--danger:hover:not(:disabled){background:var(--dshpc-danger-soft);color:var(--dshpc-danger);}\n.dshpc-iconbtn:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:2px;}\n.dshpc-iconbtn:disabled{cursor:default;opacity:.4;}\n\n/* ── 行式文件按钮(图标 + 文件名)P2:**全站唯一实现**(2026-10-04 收编)──────────\n 用途:「产出物 / 附件」那种**一行一个文件**的清单项(基础信息右栏产出物清单、附件区、\n 执行记录页的展开区)。平时透明、**鼠标移上去才出浅底**(沿用用户 2026-10-03 定的观感)。\n 两个形态修饰类:\n --block 撑满父宽(清单里一项一行)\n --inline 内容宽(跟在文字后头,如附件行)\n 收编原因:这份皮肤此前只写在 task-list.tsx 的 TASK_LIST_CSS 里(旧名 .dshpc-info-out),\n 执行记录页展开区要用同一种观感 ⇒ 上提基础层,避免再出现「各写一份外观」(同名不同皮的坑刚踩过)。 */\n.dshpc-filechip{appearance:none;-webkit-appearance:none;border:0;border-radius:var(--dshpc-radius-xs);\n background:transparent;color:var(--dshpc-fg);font:inherit;text-align:left;cursor:pointer;min-width:0;\n transition:background-color var(--dshpc-dur) var(--dshpc-ease);}\n.dshpc-filechip:hover:not(:disabled){background:var(--dshpc-chip-bg);}\n.dshpc-filechip:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px;}\n.dshpc-filechip:disabled{cursor:default;background:transparent;color:var(--dshpc-fg-3);}\n.dshpc-filechip--block{display:flex;align-items:center;gap:6px;width:100%;box-sizing:border-box;\n padding:4px 6px;font-size:var(--dshpc-font-xs);}\n.dshpc-filechip--inline{display:inline-flex;align-items:center;gap:4px;padding:2px 6px;font-size:var(--dshpc-font-sm);}\n\n@media (prefers-reduced-motion: reduce){.dshpc-btn,.dshpc-iconbtn,.dshpc-filechip{transition:none;}}\n";
|
|
2978
|
+
//#endregion
|
|
2979
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/controls/field-css.generated.js
|
|
2980
|
+
const FIELD_CSS = "\n/* ── 字段 + 问号提示(hint 参数内置) ──────────────────────────────────── */\n/* 控件 + FieldHint 同一行;hint 版由组件自己包,调用方只传 hint 字符串。\n 铺满型控件(input/textarea)进包后改吃 flex 弹性,让位给问号。 */\n.dshpc-fieldwrap{display:flex;align-items:center;gap:6px;min-width:0;max-width:100%;}\n.dshpc-fieldwrap--inline{display:inline-flex;}\n.dshpc-fieldwrap > .dshpc-input,.dshpc-fieldwrap > .dshpc-textarea,.dshpc-fieldwrap > .dshpc-iwrap{flex:1 1 auto;width:auto;min-width:0;}\n/* 多行输入:问号钉在**右下角**(2026-10-20 用户:不要垂直居中),文本区底部留出它的位置。\n ⚠️ 这一档必须把 textarea 的宽度还回去(上面那条 flex 让位规则会把它缩窄)。 */\n.dshpc-fieldwrap--block{position:relative;display:block;}\n.dshpc-fieldwrap--block > .dshpc-textarea{width:100%;padding-bottom:24px;}\n.dshpc-fieldwrap--block > .dshpc-hint{position:absolute;right:8px;bottom:6px;}\n\n/* ── 输入类 P3 ────────────────────────────────────────────────────────── */\n/* 默认铺满容器(width:100%,与 .dshpc-textarea 同口径):input 原生按 size 属性取内在宽,\n 不铺满 ⇒ 调用方套定宽壳时会「右边空一截、看着没贴右」(2026-10-20 用户抓的 bug)。\n 要定宽由调用方在外面套壳控制(如 192px 搜索槽)。 */\n.dshpc-input{display:block;width:100%;box-sizing:border-box;border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);\n background:var(--dshpc-surface-1);color:var(--dshpc-fg);font-family:inherit;outline:none;\n transition:border-color var(--dshpc-dur-fast) var(--dshpc-ease),box-shadow var(--dshpc-dur-fast) var(--dshpc-ease);}\n.dshpc-input--sm{height:var(--dshpc-control-h-sm);padding:0 8px;font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);}\n.dshpc-input--md{height:var(--dshpc-control-h-md);padding:0 10px;font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}\n.dshpc-input--lg{height:var(--dshpc-control-h-lg);padding:0 12px;font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}\n.dshpc-input::placeholder{color:var(--dshpc-fg-dim);}\n/* type=\"search\":原生清除钮(::-webkit-search-cancel-button)整个隐掉,换组件自己挂的 plain IconButton\n —— 原生那个各子系统长相不一、还不吃 token(2026-10-28 用户:不好看,要数字框加减号那种)。 */\n.dshpc-iwrap .dshpc-input::-webkit-search-cancel-button{display:none;}\n.dshpc-input:focus{border-color:var(--dshpc-focus);box-shadow:0 0 0 1px var(--dshpc-focus);}\n.dshpc-input--error{border-color:var(--dshpc-danger);}\n.dshpc-input:disabled{cursor:default;opacity:.5;}\n\n/* 左侧图标槽(Input 的 icon 参数):图标绝对定位压在输入框的左内边距上,\n 输入框自己的边框 / 焦点圈 / 描红一律不动。图标不吃点击(pointer-events:none)⇒ 点在图标上照样聚焦。\n 左内边距 = 左偏 8 + 图标宽(sm 14 / md·lg 16,见 fieldMetricsOf)+ 间距 4。 */\n.dshpc-iwrap{position:relative;display:block;width:100%;min-width:0;}\n.dshpc-iwrap__icon{position:absolute;left:8px;top:50%;transform:translateY(-50%);display:inline-flex;pointer-events:none;color:var(--dshpc-fg-2);}\n.dshpc-iwrap--sm > .dshpc-input{padding-left:26px;}\n.dshpc-iwrap--md > .dshpc-input,.dshpc-iwrap--lg > .dshpc-input{padding-left:28px;}\n/* 禁用时图标跟输入框一起变淡(输入框自己已有 opacity:.5,图标不在它里面,得单独跟一下)。 */\n.dshpc-iwrap:has(> .dshpc-input:disabled) > .dshpc-iwrap__icon{opacity:.5;}\n\n/* 搜索框的清空钮(Field.ts 在「有焦点 + 有内容」时才挂出来):**并进框里**,与数字框的 − / +\n 同形态 —— 整段同高、左直右圆、hover 底色铺满这一格(2026-10-28 用户:不要一颗悬在右边的小按钮)。\n 向内让 1px,免得底色压住输入框自己的边框。 */\n.dshpc-iwrap__clear.dshpc-iconbtn{position:absolute;right:1px;top:1px;bottom:1px;height:auto;width:auto;aspect-ratio:1;\n border-radius:0 var(--dshpc-radius-md) var(--dshpc-radius-md) 0;font-size:var(--dshpc-font-md);}\n/* height:auto 必须:iconbtn--md/lg 的固定 height 会让 absolute 的 bottom 被忽略\n (top:1 + 固定高 ⇒ 整钮错位 1px,× 显得没居中,2026-10-28 用户截图抓的)。 */\n/* 文字让开这一段(宽度 = 控件高 - 2,故按档位补)。 */\n.dshpc-iwrap--clear > .dshpc-input{padding-right:calc(var(--dshpc-control-h-md) + 3px);}\n.dshpc-iwrap--clear.dshpc-iwrap--sm > .dshpc-input{padding-right:calc(var(--dshpc-control-h-sm) + 3px);}\n.dshpc-iwrap--clear.dshpc-iwrap--lg > .dshpc-input{padding-right:calc(var(--dshpc-control-h-lg) + 3px);}\n\n.dshpc-pfx{display:inline-flex;align-items:center;box-sizing:border-box;overflow:hidden;\n border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);background:var(--dshpc-surface-1);color:var(--dshpc-fg);}\n.dshpc-pfx--sm{height:var(--dshpc-control-h-sm);}\n.dshpc-pfx--md{height:var(--dshpc-control-h-md);}\n.dshpc-pfx--lg{height:var(--dshpc-control-h-lg);}\n/* md / lg 档字号跟档走(与同档下拉同字号):此前写死 sm(12px),同排下拉是 13px ⇒ 显得「input 字小」。 */\n.dshpc-pfx--md .dshpc-pfx__label,.dshpc-pfx--lg .dshpc-pfx__label{font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}\n.dshpc-pfx--md .dshpc-pfx__input,.dshpc-pfx--lg .dshpc-pfx__input{font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}\n.dshpc-pfx--error{border-color:var(--dshpc-danger);}\n.dshpc-pfx:focus-within{border-color:var(--dshpc-focus);box-shadow:0 0 0 1px var(--dshpc-focus);}\n.dshpc-pfx__label{padding:0 8px;color:var(--dshpc-fg-2);font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);white-space:nowrap;border-right:1px solid var(--dshpc-border);}\n.dshpc-pfx__input{flex:1 1 auto;min-width:0;height:100%;padding:0 8px;border:0;background:transparent;color:var(--dshpc-fg);\n font-family:inherit;font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);outline:none;}\n.dshpc-pfx__input::placeholder{color:var(--dshpc-fg-dim);}\n\n.dshpc-num{display:inline-flex;align-items:center;justify-content:space-between;box-sizing:border-box;overflow:hidden;\n border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);background:var(--dshpc-surface-1);color:var(--dshpc-fg);}\n/* 中段:数字 + 后缀成组居中;容器被消费端拉宽时吃掉全部余量,两端 − / + 因此钉死在左右边缘。 */\n.dshpc-num__mid{display:flex;align-items:center;justify-content:center;flex:1 1 auto;min-width:0;}\n.dshpc-num--sm{height:var(--dshpc-control-h-sm);}\n.dshpc-num--md{height:var(--dshpc-control-h-md);}\n.dshpc-num--lg{height:var(--dshpc-control-h-lg);}\n.dshpc-num--md .dshpc-num__input,.dshpc-num--lg .dshpc-num__input{font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);}\n.dshpc-num--md .dshpc-num__suffix,.dshpc-num--lg .dshpc-num__suffix{font-size:var(--dshpc-font-md);}\n.dshpc-num--disabled{opacity:.5;}\n/* 焦点态与 Input 同款(2026-10-20 用户:数字框里点进去没有蓝框):内层 input 无边框,\n 焦点状态画在整个步进控件外框上。 */\n.dshpc-num:focus-within{border-color:var(--dshpc-focus);box-shadow:0 0 0 1px var(--dshpc-focus);}\n.dshpc-num__input{width:36px;height:100%;padding:0 2px;border:0;background:transparent;color:var(--dshpc-fg);\n font-family:inherit;font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);text-align:center;outline:none;}\n.dshpc-num__suffix{padding:0 6px;color:var(--dshpc-fg-2);font-size:var(--dshpc-font-sm);white-space:nowrap;}\n.dshpc-num .dshpc-iconbtn{border-radius:0;color:var(--dshpc-fg-2);flex:none;}\n\n/* 官方 Switch 包装统一:选中 = success 绿。\n (合并原先 task-editor-css / task-list 两处就地覆盖;选择器带包装类 + role,特异性高于官方。) */\n.dshpc-switch button[role='switch'][aria-checked='true']{background:var(--dshpc-success);}\n\n/* 多行文本输入(提示词等,P3):**边框 / 圆角 / 底 / 焦点态与 Input 同一套口径**(用户 2026-10-20:\n 「多行输入应该和 input 的边儿是一个道理,包括圆角在内,都是一个东西」)。\n ⚠️ 旧意图「卡内无边框、视觉重心在整张卡上」已作废 —— 现在它就是一只带框的多行输入框。\n (从 task-editor-css 的 .dshpc-ed-prompt 上提而来;业务文件不再自写 textarea 皮肤。) */\n.dshpc-textarea{display:block;width:100%;box-sizing:border-box;min-height:132px;padding:8px 12px;\n border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);outline:none;\n background:var(--dshpc-surface-1);color:var(--dshpc-fg);font-family:inherit;font-size:var(--dshpc-font-lg);line-height:1.6;resize:vertical;\n transition:border-color var(--dshpc-dur-fast) var(--dshpc-ease),box-shadow var(--dshpc-dur-fast) var(--dshpc-ease);}\n.dshpc-textarea::placeholder{color:var(--dshpc-fg-dim);}\n.dshpc-textarea:focus{border-color:var(--dshpc-focus);box-shadow:0 0 0 1px var(--dshpc-focus);}\n/* 校验不通过:与 Input 一致,走边框描红(旧版是 box-shadow 描红盒,与 Input 不同口径) */\n.dshpc-textarea--error{border-color:var(--dshpc-danger);}\n.dshpc-textarea:disabled{cursor:default;opacity:.5;}\n@media (prefers-reduced-motion: reduce){.dshpc-textarea{transition:none;}}\n\n/* 拖拽分隔条(编辑分栏 / 预览 dock 共用,U20 #3):6px 命中区,col-resize,不画线,hover/按下浮出浅带。\n 具体 z-index 由 .dshpc-ed-resizer / .dshpc-sv-resizer 各自补。 */\n.dshpc-resizer{position:absolute;top:0;bottom:0;left:0;width:6px;cursor:col-resize;background:0 0;touch-action:none;user-select:none;}\n.dshpc-resizer:hover,.dshpc-resizer:active{background:var(--dshpc-hover,rgba(38,49,72,.06));}\n\n@media (prefers-reduced-motion: reduce){.dshpc-input,.dshpc-pfx{transition:none;}}\n";
|
|
2981
|
+
//#endregion
|
|
2982
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/controls/loader-css.generated.js
|
|
2983
|
+
const LOADER_CSS = "/* ── Loader:统一的加载动画图标(无背景 / 无定位 / 颜色跟随 currentColor)────────\n 形态 × 尺寸两轴正交:形态管几何与动画;尺寸档只改 width / height,几何按\n viewBox=\"0 0 24 24\" 等比缩放 —— 一套几何吃五档,12px 时描边即 1.5px、48px 时 6px,\n 视觉重量一致,不用逐个尺寸换算 calc。\n\n 边界:本控件**只管图标本身**。背景 / 圆角 / 内距 / 阴影 / 定位(fixed、居中、漂浮)\n 一律归调用方 —— 套 Chip、套 Card,或自己包一个 div。 */\n\n.dshpc-loader { display: inline-block; flex: none; vertical-align: middle; line-height: 0; color: inherit; }\n\n.dshpc-loader--xs { width: 12px; height: 12px; }\n.dshpc-loader--sm { width: 16px; height: 16px; }\n.dshpc-loader--md { width: 24px; height: 24px; }\n.dshpc-loader--lg { width: 32px; height: 32px; }\n.dshpc-loader--xl { width: 48px; height: 48px; }\n\n/* 形态一 ring:开口弧整体旋转。必须走 SVG 矢量弧 —— 次像素边框画圆在 12px 下会被\n 抗锯齿拉毛、看着像圆角方(2026-10-20 真机实测,曾被误判成 border-radius 被覆盖)。 */\n.dshpc-loader--ring { animation: dshpc-loader-rotate .8s linear infinite; }\n@keyframes dshpc-loader-rotate { to { transform: rotate(360deg) } }\n\n/* 形态二 blocks:三个方块依次脉动放大。\n transform-box: fill-box 是 SVG 子元素做 CSS transform 的必要条件 —— 否则 origin\n 落在 viewBox 原点,节点会绕着左上角飞出去。 */\n.dshpc-loader__node { transform-box: fill-box; transform-origin: center; }\n.dshpc-loader--blocks .dshpc-loader__node { animation: dshpc-loader-blink 1.2s ease-in-out infinite; }\n.dshpc-loader__node:nth-child(2) { animation-delay: .15s; }\n.dshpc-loader__node:nth-child(3) { animation-delay: .3s; }\n@keyframes dshpc-loader-blink {\n 0%, 80%, 100% { opacity: .25; transform: scale(.8) }\n 40% { opacity: 1; transform: scale(1) }\n}\n\n/* 降低动效:停在「全部可见、实体大小」,而不是停在动画中途的半透明小点。 */\n@media (prefers-reduced-motion: reduce) {\n .dshpc-loader--ring { animation: none; }\n .dshpc-loader__node { animation: none; opacity: 1; transform: none; }\n}\n";
|
|
2984
|
+
//#endregion
|
|
2985
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/controls/hint-css.generated.js
|
|
2986
|
+
const HINT_CSS = "\n/* ── 问号提示 P4(用户 2026-10-18:对齐真实插件 HelpButton——**带圈的问号图标**)──\n 本体 14px 细圈 + 圈内 ?,颜色 fg-3、hover 只提亮不加底(与 dshpc-ed-help 同规矩)。\n 气泡不在本文件:2026-10-19 用户拍板「问号必须用官方 Tooltip 那一个」⇒ 气泡由注入的\n 官方组件渲染(src/ui/tooltip.ts),这里只管问号图标本身。 */\n.dshpc-hint{display:inline-flex;align-items:center;justify-content:center;flex:none;\n box-sizing:border-box;width:14px;height:14px;padding:0;border:1px solid currentColor;border-radius:50%;background:transparent;\n color:var(--dshpc-fg-3);font-family:inherit;font-size:8px;font-weight:600;line-height:12px;cursor:help;vertical-align:middle;\n transition:color var(--dshpc-dur-fast) var(--dshpc-ease);}\n.dshpc-hint:hover,.dshpc-hint:focus-visible{color:var(--dshpc-fg);background:0 0;}\n.dshpc-hint:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px;}\n";
|
|
2987
|
+
//#endregion
|
|
2988
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/FieldHint.js
|
|
3029
2989
|
/**
|
|
3030
2990
|
* 问号提示 —— **全站唯一实现、独立组件**(L2,P4)
|
|
3031
2991
|
*
|
|
@@ -3039,7 +2999,7 @@ window.__ModuleLoader__.load({
|
|
|
3039
2999
|
*/
|
|
3040
3000
|
/** 问号提示图标:hover / focus 浮出说明气泡(官方 Tooltip 渲染)。 */
|
|
3041
3001
|
function FieldHint(props) {
|
|
3042
|
-
|
|
3002
|
+
ensureComponentStyles("hint", HINT_CSS);
|
|
3043
3003
|
const { text, side, align, maxWidth, className, style } = props;
|
|
3044
3004
|
return (0, react$1.createElement)("span", {
|
|
3045
3005
|
className: `dshpc-hint${className !== void 0 && className !== "" ? ` ${className}` : ""}`,
|
|
@@ -3050,7 +3010,10 @@ window.__ModuleLoader__.load({
|
|
|
3050
3010
|
}, "?");
|
|
3051
3011
|
}
|
|
3052
3012
|
//#endregion
|
|
3053
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
3013
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/marquee-css.generated.js
|
|
3014
|
+
const MARQUEE_CSS = "/* 跑马灯(MarqueeText):双层——外层只裁剪,内层才 transform 滚动;非 hover 内层自带省略号。\n 2026-10-20:本文件原是杂烩「select.css」(下拉 / 日历 / 时分的皮肤都装过),随着那些控件\n 一个个删完,最后只剩跑马灯,故按本包「一个 css 服务一个对象」的格局改名归档。\n 同批清掉的还有零引用的省略号类 .dshpc-ellipsis —— 本包三个用到截断的地方都没采纳它。 */\n.dshpc-mq{display:block;overflow:hidden;white-space:nowrap;}\n.dshpc-mq .dshpc-mq-in{display:inline-block;white-space:nowrap;max-width:100%;overflow:hidden;text-overflow:ellipsis;vertical-align:top;}\n/* ⚠️ 跑法(用户 2026-10-03 拍板):**跑一遍、停在尾字**(播放 1 次 + forwards),不来回弹、不无限跑。\n 滚距 = 精确溢出量 ⇒ 停下时最后一个字正好贴右缘,**不会跑进黑块**(黑块是旧手写版把\n 内层盒子裁了、按「半截文本」平移导致的)。鼠标移开 ⇒ :hover 失效 ⇒ 自动复位回省略号态。 */\n.dshpc-mq-run:hover .dshpc-mq-in{max-width:none;overflow:visible;animation:dshpc-mq-scroll var(--dshpc-mq-dur,6s) linear .4s 1 forwards;}\n@keyframes dshpc-mq-scroll{from{transform:translateX(0)}to{transform:translateX(var(--dshpc-mq-dist,-40px))}}\n/* 溢出渐影(用户 2026-10-24 拍板「左右稍微有点渐影」;官方口径 = dsh-client-ui-primitives@0.2.1-rc.2\n PathLabel.module.css:13-15:mask-image 线性渐隐 + 28px 随官方)。⚠️ 只在 **hover 滚动态** 加:\n 静态态(三个点)不要渐影(用户 2026-10-24 二次拍板),hover 滚动时两端渐影——左缘柔化被裁的文字头。 */\n.dshpc-mq-run:hover{mask-image:linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent);}\n";
|
|
3015
|
+
//#endregion
|
|
3016
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/MarqueeText.js
|
|
3054
3017
|
/**
|
|
3055
3018
|
* 跑马灯文本 —— **全站唯一实现**(L2,P6 从 editor-fields 迁入 ui)
|
|
3056
3019
|
*
|
|
@@ -3062,6 +3025,7 @@ window.__ModuleLoader__.load({
|
|
|
3062
3025
|
*/
|
|
3063
3026
|
/** 跑马灯文本。 */
|
|
3064
3027
|
function MarqueeText(props) {
|
|
3028
|
+
ensureComponentStyles("marquee", MARQUEE_CSS);
|
|
3065
3029
|
const outerRef = (0, react$1.useRef)(null);
|
|
3066
3030
|
const innerRef = (0, react$1.useRef)(null);
|
|
3067
3031
|
const [dist, setDist] = (0, react$1.useState)(0);
|
|
@@ -3102,7 +3066,10 @@ window.__ModuleLoader__.load({
|
|
|
3102
3066
|
}, props.text));
|
|
3103
3067
|
}
|
|
3104
3068
|
//#endregion
|
|
3105
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
3069
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/picker-css.generated.js
|
|
3070
|
+
const PICKER_CSS = "\n.dshpc-picker{position:relative;display:inline-block;max-width:100%;font-size:13px;line-height:20px}\n.dshpc-picker__trigger{\n display:inline-flex;align-items:center;justify-content:space-between;gap:6px;\n min-width:120px;max-width:100%;height:28px;padding:0 8px;\n color:var(--dshpc-fg);background:var(--dshpc-surface-1);\n border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);cursor:pointer;\n}\n.dshpc-picker__trigger:disabled{color:var(--dshpc-fg-dim);cursor:not-allowed;opacity:.7}\n/* 聚焦(键盘或点击选中)时与全站一致的蓝色描边;菜单打开后焦点会进去,触发器自然失去焦点。 */\n.dshpc-picker__trigger:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n/* 文字默认靠左(吃掉剩余宽度),不给 space-between 把短文案推到中间的机会;\n 确实要居中就显式传 align=\"center\"。 */\n.dshpc-picker__label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}\n.dshpc-picker__trigger--center .dshpc-picker__label{text-align:center}\n.dshpc-picker__caret{flex:none;color:var(--dshpc-fg-3)}\n.dshpc-picker__icon{display:inline-flex;flex:none;color:var(--dshpc-fg-2)}\n.dshpc-picker__option-icon{display:inline-flex;flex:none;color:var(--dshpc-fg-2)}\n.dshpc-picker__menu{\n z-index:60;max-height:280px;overflow:auto;padding:4px;\n /* 菜单经 FloatingPortal 挂到 body,脱离 .dshpc-picker,须显式字号,否则继承 body 的大字号 */\n font-size:13px;line-height:20px;\n background:var(--dshpc-surface-menu);border:1px solid var(--dshpc-border);\n border-radius:var(--dshpc-radius-md);box-shadow:0 8px 24px rgba(15,23,42,.12);\n}\n/* 尺寸档(与 Field 的 sm/md/lg 对应)。 */\n.dshpc-picker__trigger--sm{height:24px;font-size:12px}\n.dshpc-picker__trigger--lg{height:32px}\n/* 键盘游标所在项(无 hover 也要看得见)。 */\n.dshpc-picker__option[data-active='true']{background:var(--dshpc-surface-sunken);outline:1px solid var(--dshpc-border)}\n.dshpc-picker__option--clear{color:var(--dshpc-fg-3)}\n.dshpc-picker__search{\n width:100%;height:28px;margin-bottom:4px;padding:0 8px;box-sizing:border-box;\n color:var(--dshpc-fg);background:var(--dshpc-surface-sunken);\n border:1px solid var(--dshpc-border-faint);border-radius:var(--dshpc-radius-md);outline:none;\n}\n.dshpc-picker__group-label{\n padding:6px 8px 2px;color:var(--dshpc-fg-3);font-size:11px;\n}\n.dshpc-picker__option{\n display:flex;align-items:center;gap:6px;padding:6px 8px;border-radius:var(--dshpc-radius-sm);cursor:pointer;\n color:var(--dshpc-fg);white-space:nowrap;\n}\n.dshpc-picker__option:hover{background:var(--dshpc-surface-sunken)}\n.dshpc-picker__option--active{background:var(--dshpc-open-bg);color:var(--dshpc-business)}\n.dshpc-picker__option--disabled{color:var(--dshpc-fg-dim);cursor:not-allowed}\n/* 选项文字吃掉剩余宽度:超长省略号(配合 MarqueeText hover 跑马灯),不撑宽菜单。 */\n.dshpc-picker__option-label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dshpc-picker__tick{width:12px;color:var(--dshpc-business)}\n.dshpc-picker__empty{padding:8px;color:var(--dshpc-fg-3);text-align:center}\n.dshpc-picker__degraded{\n padding:6px 8px;margin-bottom:4px;border-radius:var(--dshpc-radius-sm);\n color:var(--dshpc-warning-label);background:color-mix(in srgb,var(--dshpc-warning) 12%,transparent);\n font-size:11px;\n}\n.dshpc-picker__row{display:flex;align-items:center;gap:8px}\n";
|
|
3071
|
+
//#endregion
|
|
3072
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/Picker.js
|
|
3106
3073
|
/**
|
|
3107
3074
|
* 通用选择器:单选 / 多选 / 上限 / 搜索 / 分组 / 空态 / 降级。
|
|
3108
3075
|
*
|
|
@@ -3110,7 +3077,8 @@ window.__ModuleLoader__.load({
|
|
|
3110
3077
|
* 边界,通道是插件私有的,组件取不到,见需求文档 §6)。
|
|
3111
3078
|
*/
|
|
3112
3079
|
function Picker(props) {
|
|
3113
|
-
|
|
3080
|
+
ensureComponentStyles("picker", PICKER_CSS);
|
|
3081
|
+
ensureComponentStyles("field", FIELD_CSS);
|
|
3114
3082
|
const tt = props.translate ?? t$2;
|
|
3115
3083
|
const mode = props.mode ?? "single";
|
|
3116
3084
|
const size$3 = props.size ?? "md";
|
|
@@ -3270,7 +3238,86 @@ window.__ModuleLoader__.load({
|
|
|
3270
3238
|
return Array.isArray(v) ? [...v] : [v];
|
|
3271
3239
|
}
|
|
3272
3240
|
//#endregion
|
|
3273
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
3241
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/Loader.js
|
|
3242
|
+
/**
|
|
3243
|
+
* Loader —— 统一的加载动画图标(UI 基础层 · 反馈族)。
|
|
3244
|
+
*
|
|
3245
|
+
* 一句话边界:**只画图标本身**。没有背景、没有内距、没有圆角、没有定位。
|
|
3246
|
+
* 要圆角底就外面套 `Chip` / `Card`,要浮在屏幕上就自己包一层 fixed 容器 ——
|
|
3247
|
+
* 背景与位置属于调用方,不属于这个控件。
|
|
3248
|
+
*
|
|
3249
|
+
* 两轴正交(不是两个组件,也不是 N×M 份样式):
|
|
3250
|
+
* - `variant`:`ring` 开口弧旋转(默认)/ `blocks` 三块脉动
|
|
3251
|
+
* - `size`:`xs` 12 / `sm` 16 / `md` 24(默认)/ `lg` 32 / `xl` 48
|
|
3252
|
+
*
|
|
3253
|
+
* 几何统一画在 `viewBox="0 0 24 24"` 里,尺寸档只改 `width` / `height` ⇒ 等比缩放,
|
|
3254
|
+
* 描边与方块的视觉重量在各档一致(12px 下描边 1.5px,48px 下 6px)。
|
|
3255
|
+
*
|
|
3256
|
+
* 颜色:全程 `currentColor`,自动跟随所在按钮 / 标签的文字色,不给 color 轴
|
|
3257
|
+
* (要换色在调用点给 `style={{ color }}` 即可,不必新增参数)。
|
|
3258
|
+
*
|
|
3259
|
+
* 无障碍:默认 `aria-hidden`(图标本身是装饰,语义由所在按钮的文字 / 卡片的
|
|
3260
|
+
* `role="status"` 承担);要让它自己承担语义时传 `label`,此时输出 `role="status"`。
|
|
3261
|
+
*
|
|
3262
|
+
* 扩展新形态:在 `LoaderVariant` 加一个值 + 本文件加一支几何 + `loader.css` 加一段规则,
|
|
3263
|
+
* 不新增导出(形态由数据决定时直接传字符串即可,见 docs/help/ui.md)。
|
|
3264
|
+
*/
|
|
3265
|
+
/** 形态一:约 265° 的开口弧(周长 59.7,画 44 的空缺留 15.7)。 */
|
|
3266
|
+
function ringNode() {
|
|
3267
|
+
return (0, react$1.createElement)("circle", {
|
|
3268
|
+
cx: 12,
|
|
3269
|
+
cy: 12,
|
|
3270
|
+
r: 9.5,
|
|
3271
|
+
fill: "none",
|
|
3272
|
+
stroke: "currentColor",
|
|
3273
|
+
strokeWidth: 3,
|
|
3274
|
+
strokeLinecap: "round",
|
|
3275
|
+
strokeDasharray: "44 15.7"
|
|
3276
|
+
});
|
|
3277
|
+
}
|
|
3278
|
+
/** 形态二:三个圆角方块,横向三等分(6.4 + 1.1 间隔,左右各留 1.3)。 */
|
|
3279
|
+
function blockNodes() {
|
|
3280
|
+
return [
|
|
3281
|
+
0,
|
|
3282
|
+
1,
|
|
3283
|
+
2
|
|
3284
|
+
].map((i) => (0, react$1.createElement)("rect", {
|
|
3285
|
+
key: i,
|
|
3286
|
+
className: "dshpc-loader__node",
|
|
3287
|
+
x: 1.3 + i * 7.5,
|
|
3288
|
+
y: 8.8,
|
|
3289
|
+
width: 6.4,
|
|
3290
|
+
height: 6.4,
|
|
3291
|
+
rx: 1.4,
|
|
3292
|
+
fill: "currentColor"
|
|
3293
|
+
}));
|
|
3294
|
+
}
|
|
3295
|
+
/**
|
|
3296
|
+
* 渲染一个加载动画图标。
|
|
3297
|
+
*
|
|
3298
|
+
* @param props 见 {@link LoaderProps}。
|
|
3299
|
+
* @returns `<svg>` 元素(inline,不占额外行高)。
|
|
3300
|
+
*/
|
|
3301
|
+
function Loader$2(props) {
|
|
3302
|
+
ensureComponentStyles("loader", LOADER_CSS);
|
|
3303
|
+
const { variant = "ring", size = "md", label, className } = props;
|
|
3304
|
+
const classes = [
|
|
3305
|
+
"dshpc-loader",
|
|
3306
|
+
`dshpc-loader--${variant}`,
|
|
3307
|
+
`dshpc-loader--${size}`
|
|
3308
|
+
];
|
|
3309
|
+
if (className !== void 0 && className !== "") classes.push(className);
|
|
3310
|
+
return (0, react$1.createElement)("svg", {
|
|
3311
|
+
className: classes.join(" "),
|
|
3312
|
+
viewBox: "0 0 24 24",
|
|
3313
|
+
role: label === void 0 ? void 0 : "status",
|
|
3314
|
+
"aria-label": label,
|
|
3315
|
+
"aria-hidden": label === void 0 ? true : void 0,
|
|
3316
|
+
focusable: "false"
|
|
3317
|
+
}, variant === "ring" ? ringNode() : blockNodes());
|
|
3318
|
+
}
|
|
3319
|
+
//#endregion
|
|
3320
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/Button.js
|
|
3274
3321
|
/**
|
|
3275
3322
|
* 按钮 / 图标钮 —— **全站唯一实现**(L2 组件皮肤,P2)
|
|
3276
3323
|
*
|
|
@@ -3337,7 +3384,7 @@ window.__ModuleLoader__.load({
|
|
|
3337
3384
|
* @returns 按钮元素。
|
|
3338
3385
|
*/
|
|
3339
3386
|
function Button$1(props) {
|
|
3340
|
-
|
|
3387
|
+
ensureComponentStyles("button", BUTTON_CSS);
|
|
3341
3388
|
const { variant = "outline", size = "lg", icon, iconRight, color, loading = false, block = false, width, minWidth, maxWidth, className, style, children, ...rest } = props;
|
|
3342
3389
|
const widthStyle = {};
|
|
3343
3390
|
if (width !== void 0) widthStyle.width = width;
|
|
@@ -3357,22 +3404,7 @@ window.__ModuleLoader__.load({
|
|
|
3357
3404
|
...style
|
|
3358
3405
|
}
|
|
3359
3406
|
};
|
|
3360
|
-
return (0, react$1.createElement)("button", attrs, loading ? (0, react$1.createElement)("
|
|
3361
|
-
className: "dshpc-btn__spinner",
|
|
3362
|
-
viewBox: "0 0 12 12",
|
|
3363
|
-
width: 12,
|
|
3364
|
-
height: 12,
|
|
3365
|
-
"aria-hidden": true
|
|
3366
|
-
}, (0, react$1.createElement)("circle", {
|
|
3367
|
-
cx: 6,
|
|
3368
|
-
cy: 6,
|
|
3369
|
-
r: 4.75,
|
|
3370
|
-
fill: "none",
|
|
3371
|
-
stroke: "currentColor",
|
|
3372
|
-
strokeWidth: 1.5,
|
|
3373
|
-
strokeLinecap: "round",
|
|
3374
|
-
strokeDasharray: "22 30"
|
|
3375
|
-
})) : icon !== void 0 && icon !== null ? (0, react$1.createElement)("span", { className: "dshpc-btn__icon" }, icon) : null, marqueeLabel ? (0, react$1.createElement)(MarqueeText, {
|
|
3407
|
+
return (0, react$1.createElement)("button", attrs, loading ? (0, react$1.createElement)(Loader$2, { size: "xs" }) : icon !== void 0 && icon !== null ? (0, react$1.createElement)("span", { className: "dshpc-btn__icon" }, icon) : null, marqueeLabel ? (0, react$1.createElement)(MarqueeText, {
|
|
3376
3408
|
text: children,
|
|
3377
3409
|
className: "dshpc-btn__label"
|
|
3378
3410
|
}) : children, iconRight !== void 0 && iconRight !== null ? (0, react$1.createElement)("span", { className: "dshpc-btn__icon-end" }, iconRight) : null);
|
|
@@ -3384,7 +3416,7 @@ window.__ModuleLoader__.load({
|
|
|
3384
3416
|
* @returns 图标按钮元素。
|
|
3385
3417
|
*/
|
|
3386
3418
|
function IconButton$1(props) {
|
|
3387
|
-
|
|
3419
|
+
ensureComponentStyles("button", BUTTON_CSS);
|
|
3388
3420
|
const { variant = "plain", size = "lg", icon, label, className, style, ...rest } = props;
|
|
3389
3421
|
const attrs = {
|
|
3390
3422
|
...rest,
|
|
@@ -3397,7 +3429,7 @@ window.__ModuleLoader__.load({
|
|
|
3397
3429
|
return (0, react$1.createElement)("button", attrs, icon);
|
|
3398
3430
|
}
|
|
3399
3431
|
//#endregion
|
|
3400
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
3432
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/host-data.js
|
|
3401
3433
|
/** 模型目录的 observable store(useSyncExternalStore 直接消费)。 */
|
|
3402
3434
|
var ModelCatalogStore = class {
|
|
3403
3435
|
constructor() {
|
|
@@ -3503,10 +3535,16 @@ window.__ModuleLoader__.load({
|
|
|
3503
3535
|
});
|
|
3504
3536
|
}
|
|
3505
3537
|
//#endregion
|
|
3506
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
3538
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/feedback-css.generated.js
|
|
3539
|
+
const FEEDBACK_CSS = "\n/* 遮罩 = 宿主遮罩变量 --dsw-alias-bg-mask-1(与官方 Modal / 兄弟项目 --tdt-mask 同一条真值,用户 2026-10-20)。 */\n/* 右边界让位页面级分栏(PanelDock 发布的 --dshpc-page-inset-right,用户 2026-10-22):\n 分栏不被压暗、照常可点;弹窗在这块**剩下**的区域里居中,就像整页被推出去一样。 */\n.dshpc-modal-mask{\n position:fixed;inset:0 var(--dshpc-page-inset-right,0px) 0 0;z-index:1070;\n display:flex;align-items:center;justify-content:center;\n background:var(--dshpc-mask);\n}\n/* 大弹窗家族(md/lg):抄兄弟项目 archive-session-css 的 .dsh-tdt-sv-panel(surface-base + border-l2 + radius 12 + shadow-2)。 */\n.dshpc-modal{\n display:flex;flex-direction:column;box-sizing:border-box;\n background:var(--dshpc-surface-base);color:var(--dshpc-fg);\n border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-md);\n box-shadow:var(--dshpc-shadow-2);overflow:hidden;\n}\n.dshpc-modal__head{\n display:flex;align-items:center;gap:8px;padding:18px 31px 12px;\n border-bottom:1px solid var(--dshpc-border);flex-wrap:wrap;\n}\n/* 标题组:第一行 = 标题 + 右侧小块(徽标紧跟标题),第二行 = 副标题。 */\n.dshpc-modal__titlegroup{display:flex;flex-direction:column;gap:2px;min-width:0;flex:0 1 auto}\n.dshpc-modal__titlerow{display:flex;align-items:center;gap:8px;min-width:0}\n.dshpc-modal__title{font-size:var(--dshpc-font-lg);font-weight:600;line-height:1.4;min-width:0}\n/* 标题下副标题行(兄弟项目 .dsh-tdt-sv-sid:等宽字体、caption 色、可换行)。 */\n.dshpc-modal__sid{font-family:var(--ds-font-family-code,monospace);font-size:var(--dshpc-font-xs);color:var(--dshpc-fg-3);word-break:break-all}\n/* 关闭按钮:24×24 方角图标位,不借用 Picker 的触发器皮肤(那份带 min-width:120px)。 */\n.dshpc-modal__close{\n display:inline-flex;align-items:center;justify-content:center;flex:none;\n width:20px;height:20px;padding:0;border:none;border-radius:var(--dshpc-radius-sm);\n background:transparent;color:var(--dshpc-fg-3);font-family:inherit;font-size:13px;line-height:1;cursor:pointer;\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-modal__close:hover{background:var(--dshpc-hover);color:var(--dshpc-fg)}\n.dshpc-modal__close:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n/* body = 唯一滚动容器:内距与滚动都归它(滚动条贴面板右缘,不被内距挤进来);\n 内容按流排,不设 height:100%、不自己开滚动条。 */\n.dshpc-modal__body{flex:1 1 auto;min-height:0;overflow:auto;padding:17px 31px}\n.dshpc-modal__foot{display:flex;justify-content:flex-end;gap:8px;padding:12px 31px 18px}\n.dshpc-toast-host{\n position:fixed;z-index:1090;left:50%;bottom:32px;transform:translateX(-50%);\n display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none;\n}\n.dshpc-toast{\n padding:8px 14px;border-radius:8px;font-size:13px;color:var(--dshpc-fg);\n background:var(--dshpc-surface-menu);border:1px solid var(--dshpc-border);\n box-shadow:0 8px 24px rgba(15,23,42,.16);\n}\n.dshpc-toast--success{color:var(--dshpc-success);border-color:color-mix(in srgb,var(--dshpc-success) 40%,transparent)}\n.dshpc-toast--error{color:var(--dshpc-danger);border-color:color-mix(in srgb,var(--dshpc-danger) 40%,transparent)}\n.dshpc-error__retry{\n margin-top:8px;color:var(--dshpc-link);cursor:pointer;background:none;border:none;padding:0;\n}\n/* 原生弹窗演示:经宿主 Modal 的 contentClassName 注入,证明宿主内容区尺寸可经类名自定义。 */\n.dshpc-native-demo-content{max-width:520px}\n/* Modal 头部四槽:左图标 / 标题组 / 弹性间隔 / 右侧动作区 + 关闭钮。 */\n.dshpc-modal__heading{display:flex;align-items:center;gap:8px;min-width:0;flex:0 1 auto}\n.dshpc-modal__lead{flex:none;display:inline-flex;align-items:center;justify-content:center;font-size:16px;line-height:1}\n.dshpc-modal__extra{flex:none;display:inline-flex;align-items:center}\n.dshpc-modal__spacer{flex:1 1 auto;min-width:8px}\n.dshpc-modal__actions{flex:none;display:flex;align-items:center;gap:8px}\n/* 头部信号图标(AlertModal 按 severity 注入):自含配色,不依赖宿主 token。 */\n.dshpc-alert-sev{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;font-size:12px;color:#fff;flex:none}\n.dshpc-alert-sev--info{background:#2563eb}\n.dshpc-alert-sev--success{background:#16a34a}\n.dshpc-alert-sev--warning{background:#d97706}\n.dshpc-alert-sev--error{background:#dc2626}\n/* 小确认框家族(sm):严格抄兄弟项目 renderConfirm 的 dialogStyle(task-list.tsx:456)——\n 360px 宽 / 18px 内距 / 头部无分隔线 / 说明文字 fg-2 / 底部按钮右对齐。 */\n.dshpc-modal--sm{padding:18px}\n.dshpc-modal--sm .dshpc-modal__head{padding:0 0 8px;border-bottom:none}\n.dshpc-modal--sm .dshpc-modal__body{padding:0 0 14px;overflow:visible;font-size:var(--dshpc-font-sm);color:var(--dshpc-fg-2);line-height:var(--dshpc-line-sm)}\n.dshpc-modal--sm .dshpc-modal__foot{padding:0}\n";
|
|
3540
|
+
//#endregion
|
|
3541
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/chip-css.generated.js
|
|
3542
|
+
const CHIP_CSS = "\n/* 三条局部变量承载配色:neutral 走旧灰面;语义档换底字配对(2026-10-20 用户要多色多尺寸标签)。 */\n.dshpc-chip{--chip-bg:var(--dshpc-chip-bg);--chip-fg:var(--dshpc-fg);--chip-bg-hover:var(--dshpc-chip-bg-hover);\n display:inline-flex;align-items:center;justify-content:center;gap:4px;padding:1px 8px;\n box-sizing:border-box;border-radius:var(--dshpc-radius-pill,999px);border:none;\n background:var(--chip-bg);color:var(--chip-fg);\n font-family:inherit;font-size:11px;line-height:18px;margin:0;\n /* 2026-10-18:chip 是 flex 行里的常用项,禁止被压缩换行(预览站出现过文字竖排、互相叠压的挤压)。 */\n white-space:nowrap;flex:none;\n appearance:none;-webkit-appearance:none;\n}\n/* md 档:卡片元信息行等稍大场景;sm 即旧版默认,逐像素不动。 */\n.dshpc-chip--md{padding:2px 10px;font-size:12px;line-height:20px;}\n/* xs 档:标题后缀等极紧凑场景(2026-10-20 用户要更小标签);16px 高、font 10。 */\n.dshpc-chip--xs{padding:0 6px;font-size:10px;line-height:16px;}\n/* 语义色实心档:底 / 字 / hover 配对与 Button 同源(黄底中高明度 ⇒ 字用 --dshpc-on-warning)。 */\n.dshpc-chip--business{--chip-bg:var(--dshpc-business);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-business-hover);}\n.dshpc-chip--success{--chip-bg:var(--dshpc-success);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-success-hover);}\n.dshpc-chip--warning{--chip-bg:var(--dshpc-warning);--chip-fg:var(--dshpc-on-warning);--chip-bg-hover:var(--dshpc-warning-hover);}\n.dshpc-chip--danger{--chip-bg:var(--dshpc-danger);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-danger-hover);}\n/* 扩展八色(2026-10-29):实心面字色统一白(on-signal),明度均低于黄 / 青柠,白字两主题可读。 */\n.dshpc-chip--purple{--chip-bg:var(--dshpc-purple);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-purple-hover);}\n.dshpc-chip--pink{--chip-bg:var(--dshpc-pink);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-pink-hover);}\n.dshpc-chip--cyan{--chip-bg:var(--dshpc-cyan);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-cyan-hover);}\n.dshpc-chip--teal{--chip-bg:var(--dshpc-teal);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-teal-hover);}\n.dshpc-chip--orange{--chip-bg:var(--dshpc-orange);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-orange-hover);}\n.dshpc-chip--indigo{--chip-bg:var(--dshpc-indigo);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-indigo-hover);}\n.dshpc-chip--rose{--chip-bg:var(--dshpc-rose);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-rose-hover);}\n.dshpc-chip--slate{--chip-bg:var(--dshpc-slate);--chip-fg:var(--dshpc-on-signal);--chip-bg-hover:var(--dshpc-slate-hover);}\n/* 可点态:button 渲染(见 Chip.ts),光标 + hover 加深。 */\n.dshpc-chip--clickable{cursor:pointer;transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease);}\n.dshpc-chip--clickable:hover:not(:disabled){background:var(--chip-bg-hover)}\n.dshpc-chip:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n/* 禁用态字色从 --chip-fg 派生(45% ≈ 旧 fg-3 的弱化观感),不许直接用 --dshpc-fg-3:\n 它跟主题走,暗色下是深灰 ⇒ 语义色实心标签(蓝 / 红底)上几乎看不见(与 Segmented 计数 2026-10-29 同类)。 */\n.dshpc-chip:disabled{cursor:default;color:color-mix(in srgb,var(--chip-fg) 45%,transparent)}\n/* maxWidth 包 MarqueeText 时:标签作为 flex 子项必须能收缩到内容以下,否则省略号 / 跑马灯测不准 */\n.dshpc-chip .dshpc-chip__label{min-width:0;}\n@media (prefers-reduced-motion: reduce){.dshpc-chip{transition:none}}\n";
|
|
3543
|
+
//#endregion
|
|
3544
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/Chip.js
|
|
3507
3545
|
/** 小标签(neutral 用现成的 `--dshpc-chip-bg`;传 `onClick` 才是可点的)。 */
|
|
3508
3546
|
function Chip(props) {
|
|
3509
|
-
|
|
3547
|
+
ensureComponentStyles("chip", CHIP_CSS);
|
|
3510
3548
|
const { children, tone = "neutral", size = "sm", width, minWidth, maxWidth, onClick, className } = props;
|
|
3511
3549
|
const clickable = onClick !== void 0;
|
|
3512
3550
|
const widthStyle = {};
|
|
@@ -3546,7 +3584,7 @@ window.__ModuleLoader__.load({
|
|
|
3546
3584
|
}
|
|
3547
3585
|
};
|
|
3548
3586
|
const bars = Array(12).fill(0);
|
|
3549
|
-
const Loader = ({ visible, className }) => {
|
|
3587
|
+
const Loader$1 = ({ visible, className }) => {
|
|
3550
3588
|
return /*#__PURE__*/ react$1.default.createElement("div", {
|
|
3551
3589
|
className: ["sonner-loading-wrapper", className].filter(Boolean).join(" "),
|
|
3552
3590
|
"data-visible": visible
|
|
@@ -4078,7 +4116,7 @@ window.__ModuleLoader__.load({
|
|
|
4078
4116
|
"data-visible": toastType === "loading"
|
|
4079
4117
|
}, icons.loading);
|
|
4080
4118
|
}
|
|
4081
|
-
return /*#__PURE__*/ react$1.default.createElement(Loader, {
|
|
4119
|
+
return /*#__PURE__*/ react$1.default.createElement(Loader$1, {
|
|
4082
4120
|
className: cn(classNames == null ? void 0 : classNames.loader, toast == null ? void 0 : (_toast_classNames = toast.classNames) == null ? void 0 : _toast_classNames.loader),
|
|
4083
4121
|
visible: toastType === "loading"
|
|
4084
4122
|
});
|
|
@@ -4477,7 +4515,7 @@ window.__ModuleLoader__.load({
|
|
|
4477
4515
|
}));
|
|
4478
4516
|
});
|
|
4479
4517
|
//#endregion
|
|
4480
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
4518
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/toast-host.js
|
|
4481
4519
|
/** 全局注册表键:Symbol.for 跨 bundle 副本天然共享同一个符号。 */
|
|
4482
4520
|
const TOAST_HOST_KEY = Symbol.for("dsh-plugin-core/toast-host");
|
|
4483
4521
|
/** 全局单例:已注册则直接返回(不触发 create),否则建一个并注册。 */
|
|
@@ -4490,7 +4528,7 @@ window.__ModuleLoader__.load({
|
|
|
4490
4528
|
return created;
|
|
4491
4529
|
}
|
|
4492
4530
|
//#endregion
|
|
4493
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
4531
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/Toast.js
|
|
4494
4532
|
const DEFAULT_MS = 2600;
|
|
4495
4533
|
const ROOT_ID = "dshpc-toast-root";
|
|
4496
4534
|
function currentTheme() {
|
|
@@ -4690,31 +4728,7 @@ window.__ModuleLoader__.load({
|
|
|
4690
4728
|
});
|
|
4691
4729
|
}
|
|
4692
4730
|
//#endregion
|
|
4693
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
4694
|
-
/**
|
|
4695
|
-
* 分段控件(滑动块)—— **全站唯一实现**(L2 组件皮肤,P1)
|
|
4696
|
-
*
|
|
4697
|
-
* 它是「同一份结构 + 两个受控轴」的样板:
|
|
4698
|
-
* - `size`:`sm`(24) / `md`(28) / `lg`(32) —— **离散三档**,调用点**不许**自己写高度
|
|
4699
|
-
* (真不够用才允许在调用点本地覆盖 `--dshpc-control-h-*`,属例外而非常态);
|
|
4700
|
-
* - `bordered`(默认 false):最外再包一圈 1px 描边;总高与无框版逐像素一致
|
|
4701
|
-
* (border 由 padding 抵消),两种模式整行混排不跳高。
|
|
4702
|
-
*
|
|
4703
|
-
* 外观只有一套(灰底轨道 + 白色选中片,阴影来自宿主 elevation token)。
|
|
4704
|
-
* 唯一的配色入口是 `tone`(2026-10-29):传内置色名则由核心定底 / 字(两主题各自成立),
|
|
4705
|
-
* 传 `{ bg, fg }` 则两个主题都用调用方这一对颜色。
|
|
4706
|
-
* 2026-10-26 删掉 `variant` 轴(原 default / inset 两档在 CSS 里只差 1px 内距,
|
|
4707
|
-
* 且 default 比 `size` 承诺矮 2px,下游照 demo 对图时反复查不出原因 —— 见 docs/design/style.md)。
|
|
4708
|
-
*
|
|
4709
|
-
* 用法:
|
|
4710
|
-
* // 单选
|
|
4711
|
-
* h(Segmented<'a' | 'b'>, { value: v, size: 'md', items: [{ value: 'a', label: '甲' }], onChange: setV })
|
|
4712
|
-
* // 多选(如星期)
|
|
4713
|
-
* h(Segmented<'1' | '2'>, { multiple: true, value: vs, items: [...], onChange: setVs })
|
|
4714
|
-
*
|
|
4715
|
-
* ⚠️ 不许在任何使用点就地写分段样式;要多一档高度 / 多一个外观 ⇒ 走
|
|
4716
|
-
* docs/design/ui-style-guide.md §五 的流程(改基础层,一处改全站生效)。
|
|
4717
|
-
*/
|
|
4731
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/Segmented.js
|
|
4718
4732
|
/**
|
|
4719
4733
|
* 角标 / 计数要不要显示,返回要显示的文本。
|
|
4720
4734
|
* 数字 ≤0 是「没东西可数」的老口径;字符串(`'1K'` / `'99+'`)由调用方决定,原样显示,空串不显示。
|
|
@@ -4731,8 +4745,8 @@ window.__ModuleLoader__.load({
|
|
|
4731
4745
|
* @returns 分段控件元素。
|
|
4732
4746
|
*/
|
|
4733
4747
|
function Segmented$1(props) {
|
|
4734
|
-
|
|
4735
|
-
|
|
4748
|
+
ensureComponentStyles("segmented", SEGMENTED_CSS);
|
|
4749
|
+
ensureComponentStyles("segmented", SEGMENTED_CSS);
|
|
4736
4750
|
const size = props.size ?? "lg";
|
|
4737
4751
|
const multiple = props.multiple === true;
|
|
4738
4752
|
const value = props.value;
|
|
@@ -4826,173 +4840,45 @@ window.__ModuleLoader__.load({
|
|
|
4826
4840
|
})]);
|
|
4827
4841
|
}
|
|
4828
4842
|
//#endregion
|
|
4829
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
4830
|
-
/** 全局注册表键:Symbol.for 跨 bundle 副本天然共享同一个符号。 */
|
|
4831
|
-
const LOADING_HOST_KEY = Symbol.for("dsh-plugin-core/loading-host");
|
|
4832
|
-
/** 全局单例:已注册则直接返回(不触发 create),否则建一个并注册。 */
|
|
4833
|
-
function claimLoadingHost(create) {
|
|
4834
|
-
const g = globalThis;
|
|
4835
|
-
const existing = g[LOADING_HOST_KEY];
|
|
4836
|
-
if (existing !== void 0) return existing;
|
|
4837
|
-
const created = create();
|
|
4838
|
-
g[LOADING_HOST_KEY] = created;
|
|
4839
|
-
return created;
|
|
4840
|
-
}
|
|
4841
|
-
/** 浮层定位类名(`center` 走基础规则,不需要修饰类)。 */
|
|
4842
|
-
function loadingOverlayClass(position) {
|
|
4843
|
-
return `dshpc-loading-overlay dshpc-loading-overlay--${position}`;
|
|
4844
|
-
}
|
|
4845
|
-
/**
|
|
4846
|
-
* 全局**只有一个槽位**:任何一次 `show` 都顶掉上一条,屏幕上永远最多一张加载卡
|
|
4847
|
-
* (N 种样式、N 个插件、连点多少次都一样)。被顶掉那次的句柄再 `close()` 是空操作,
|
|
4848
|
-
* 不会误关后一张。
|
|
4849
|
-
*/
|
|
4850
|
-
function createLoadingSlot() {
|
|
4851
|
-
let seq = 0;
|
|
4852
|
-
let current = null;
|
|
4853
|
-
return {
|
|
4854
|
-
current: () => current,
|
|
4855
|
-
show(request) {
|
|
4856
|
-
const id = ++seq;
|
|
4857
|
-
current = {
|
|
4858
|
-
id,
|
|
4859
|
-
request
|
|
4860
|
-
};
|
|
4861
|
-
let closed = false;
|
|
4862
|
-
return { close() {
|
|
4863
|
-
if (closed || current?.id !== id) return;
|
|
4864
|
-
closed = true;
|
|
4865
|
-
current = null;
|
|
4866
|
-
} };
|
|
4867
|
-
}
|
|
4868
|
-
};
|
|
4869
|
-
}
|
|
4870
|
-
//#endregion
|
|
4871
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.10.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_0ca6af7912de6ef2e83feddb390167ee/node_modules/dsh-plugin-core/dist/ui/Loading.js
|
|
4843
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/SectionHead.js
|
|
4872
4844
|
/**
|
|
4873
|
-
*
|
|
4874
|
-
*
|
|
4875
|
-
* 用法:
|
|
4876
|
-
* <Loading />
|
|
4845
|
+
* 模块标题行(UI 基础层):**icon + 标题 + 右侧控件** 三段式。
|
|
4877
4846
|
*
|
|
4878
|
-
*
|
|
4879
|
-
*
|
|
4880
|
-
* - 右侧贴齐主内容容器右边缘(`anchorId` 默认 `dshpc-main`),底部留 16px;
|
|
4881
|
-
* - **三个小方块依次脉动,无任何文案**(基础抽象统一外观,禁止加字;用户 2026-10-06);
|
|
4882
|
-
* - 监听窗口 resize / scroll / 内容盒 resize,自动跟住内容宽度。
|
|
4847
|
+
* 2026-10-08 设置页重构时定型:每块 = 标题行 + 一块内容,标题行左侧 icon、右侧留给该块的控件
|
|
4848
|
+
* (日志块的自动刷新 / 刷新钮,表查询块的表切换)。此前三个块各写一个 `h3`,形态不统一。
|
|
4883
4849
|
*
|
|
4884
|
-
*
|
|
4885
|
-
*
|
|
4886
|
-
*
|
|
4887
|
-
* 文档登记:docs/design/ui-foundation.md §二「唯一实现表」。
|
|
4850
|
+
* 排版规则:字号 / 行高 / 字色走 `--dshpc-*` token;`right` 用 `flex:1` + `justifyContent:flex-end`
|
|
4851
|
+
* 靠右(比 `marginLeft:auto` 稳:内容再宽也始终贴右,不会塌成靠左);标题 `flex:none` 不被压缩。
|
|
4888
4852
|
*/
|
|
4889
|
-
function
|
|
4890
|
-
return (0, react$1.createElement)("
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
role: "status",
|
|
4916
|
-
"aria-live": "polite"
|
|
4917
|
-
}, spin(16), (0, react$1.createElement)("span", null, textOf(props)));
|
|
4918
|
-
}
|
|
4919
|
-
/** 样式二:方块卡(转圈在上、文字在下,内距更大)。就地渲染,位置随调用方。 */
|
|
4920
|
-
function LoadingBlock(props) {
|
|
4921
|
-
ensureControls();
|
|
4922
|
-
return (0, react$1.createElement)("div", {
|
|
4923
|
-
className: "dshpc-loading-block",
|
|
4924
|
-
role: "status",
|
|
4925
|
-
"aria-live": "polite"
|
|
4926
|
-
}, spin(22), (0, react$1.createElement)("span", null, textOf(props)));
|
|
4927
|
-
}
|
|
4928
|
-
function createLoadingHost() {
|
|
4929
|
-
const slot = createLoadingSlot();
|
|
4930
|
-
let root = null;
|
|
4931
|
-
let container = null;
|
|
4932
|
-
function flush() {
|
|
4933
|
-
const state = slot.current();
|
|
4934
|
-
if (state === null) {
|
|
4935
|
-
root?.unmount();
|
|
4936
|
-
container?.remove();
|
|
4937
|
-
root = null;
|
|
4938
|
-
container = null;
|
|
4939
|
-
return;
|
|
4940
|
-
}
|
|
4941
|
-
if (root === null) {
|
|
4942
|
-
container = document.createElement("div");
|
|
4943
|
-
container.setAttribute("data-dshpc-loading-host", "");
|
|
4944
|
-
document.body.appendChild(container);
|
|
4945
|
-
root = (0, react_dom_client.createRoot)(container);
|
|
4946
|
-
}
|
|
4947
|
-
ensureControls(getStyleKit());
|
|
4948
|
-
const { request } = state;
|
|
4949
|
-
const opacity = Math.min(1, Math.max(0, request.maskOpacity));
|
|
4950
|
-
root.render((0, react$1.createElement)("div", { className: loadingOverlayClass(request.position) }, request.mask ? (0, react$1.createElement)("div", {
|
|
4951
|
-
className: "dshpc-loading-overlay__mask",
|
|
4952
|
-
style: { background: `rgba(0, 0, 0, ${opacity})` }
|
|
4953
|
-
}) : null, request.variant === "block" ? (0, react$1.createElement)(LoadingBlock, {
|
|
4954
|
-
text: request.text,
|
|
4955
|
-
translate: request.translate
|
|
4956
|
-
}) : (0, react$1.createElement)(LoadingToast, {
|
|
4957
|
-
text: request.text,
|
|
4958
|
-
translate: request.translate
|
|
4959
|
-
})));
|
|
4960
|
-
}
|
|
4961
|
-
return { show(request) {
|
|
4962
|
-
const handle = slot.show(request);
|
|
4963
|
-
flush();
|
|
4964
|
-
return { close() {
|
|
4965
|
-
handle.close();
|
|
4966
|
-
flush();
|
|
4967
|
-
} };
|
|
4968
|
-
} };
|
|
4969
|
-
}
|
|
4970
|
-
/**
|
|
4971
|
-
* 命令式加载提示(全局唯一浮层,**不自动消失**)。所有插件、所有位置调用都落在**同一处**
|
|
4972
|
-
* (默认屏幕下方居中,与 Toast 同屏位),且屏幕上永远只有一张卡 —— 后一次调用直接顶掉
|
|
4973
|
-
* 前一次,被顶掉那次的句柄再 `close()` 是空操作。收起只能靠自己调 `close()`。
|
|
4974
|
-
*
|
|
4975
|
-
* ```ts
|
|
4976
|
-
* const loading = showLoading({ text: '正在保存…', mask: true, maskOpacity: 0.3 })
|
|
4977
|
-
* await save()
|
|
4978
|
-
* loading.close()
|
|
4979
|
-
* ```
|
|
4980
|
-
*
|
|
4981
|
-
* 无 `document` 时静默返回空句柄(Node 单测 / SSR 不炸)。
|
|
4982
|
-
*/
|
|
4983
|
-
function showLoading$1(opts) {
|
|
4984
|
-
if (typeof document === "undefined") return { close: () => {} };
|
|
4985
|
-
return claimLoadingHost(createLoadingHost).show({
|
|
4986
|
-
text: opts?.text,
|
|
4987
|
-
variant: opts?.variant ?? "toast",
|
|
4988
|
-
position: opts?.position ?? "bottom-center",
|
|
4989
|
-
mask: opts?.mask === true,
|
|
4990
|
-
maskOpacity: opts?.maskOpacity ?? 0,
|
|
4991
|
-
translate: opts?.translate
|
|
4992
|
-
});
|
|
4853
|
+
function SectionHead(props) {
|
|
4854
|
+
return (0, react$1.createElement)("div", { style: {
|
|
4855
|
+
display: "flex",
|
|
4856
|
+
alignItems: "center",
|
|
4857
|
+
gap: "var(--dshpc-space-2)",
|
|
4858
|
+
marginBottom: "var(--dshpc-space-3)"
|
|
4859
|
+
} }, (0, react$1.createElement)("span", { style: {
|
|
4860
|
+
display: "inline-flex",
|
|
4861
|
+
alignItems: "center",
|
|
4862
|
+
flex: "none",
|
|
4863
|
+
lineHeight: "var(--dshpc-line-lg)",
|
|
4864
|
+
color: "var(--dshpc-fg-3)"
|
|
4865
|
+
} }, props.icon), (0, react$1.createElement)("span", { style: {
|
|
4866
|
+
fontSize: "var(--dshpc-font-lg)",
|
|
4867
|
+
lineHeight: "var(--dshpc-line-lg)",
|
|
4868
|
+
fontWeight: 600,
|
|
4869
|
+
color: "var(--dshpc-fg)",
|
|
4870
|
+
flex: "none"
|
|
4871
|
+
} }, props.title), props.right === void 0 ? null : (0, react$1.createElement)("div", { style: {
|
|
4872
|
+
flex: 1,
|
|
4873
|
+
display: "flex",
|
|
4874
|
+
alignItems: "center",
|
|
4875
|
+
justifyContent: "flex-end",
|
|
4876
|
+
gap: "var(--dshpc-space-2)",
|
|
4877
|
+
minWidth: 0
|
|
4878
|
+
} }, props.right));
|
|
4993
4879
|
}
|
|
4994
4880
|
//#endregion
|
|
4995
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
4881
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/resizer.js
|
|
4996
4882
|
/** 开始一次拖拽调宽(监听 window 的 pointermove / pointerup,松手自动清理)。 */
|
|
4997
4883
|
function startResizeLayoutWidth(opts) {
|
|
4998
4884
|
opts.startEvent.preventDefault?.();
|
|
@@ -5031,7 +4917,7 @@ window.__ModuleLoader__.load({
|
|
|
5031
4917
|
window.addEventListener("pointerup", onUp);
|
|
5032
4918
|
}
|
|
5033
4919
|
//#endregion
|
|
5034
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
4920
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/panel-dock-logic.js
|
|
5035
4921
|
/**
|
|
5036
4922
|
* 停靠面板的状态逻辑(纯函数,零 React / 零 DOM)。
|
|
5037
4923
|
*
|
|
@@ -5162,7 +5048,10 @@ window.__ModuleLoader__.load({
|
|
|
5162
5048
|
}, 0);
|
|
5163
5049
|
}
|
|
5164
5050
|
//#endregion
|
|
5165
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
5051
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/panel-dock-css.generated.js
|
|
5052
|
+
const PANEL_DOCK_CSS = "\n/* 停靠栏 = **布局成员**,不是浮层:它占宽度、把主区真正挤窄(兄弟项目 2026-09-28:\n 「分栏压过来,不是盖上去」)。所以调用方必须把它放进自己的 flex 根里。 */\n.dshpc-dock{display:flex;flex:0 0 auto;align-self:stretch;min-width:0}\n/* 开着时给主区滚动条让出一条缝:滚动条贴死分隔线很难看(用户 2026-10-28,对齐\n dsh-better-sidebar 的留白)。全关时整条 dock 退出,缝隙一起消失、不留白边。\n 缝宽可由调用方盖 --dshpc-dock-gap;TS 侧的让位量(DOCK_GAP)要与它一致。 */\n.dshpc-dock--open{margin-left:var(--dshpc-dock-gap,1px)}\n\n/* 自动加的宿主行(openFilePreview 加 / 关闭即摘):消费方那行不必自己写 flex。\n 只让「第一个非预览子项」当主区伸展,其余直接子项不动(页脚条、工具条不误伤);\n display 不在这里写死 —— 本来就是 grid 等布局的元素保持原样,由 TS 侧按计算值补 flex。 */\n.dshpc-dock-host{min-width:0;min-height:0}\n.dshpc-dock-host>:not([data-dshpc-file-preview]){min-width:0}\n.dshpc-dock-host>:first-child:not([data-dshpc-file-preview]){flex:1 1 auto}\n\n/* 单栏:sticky + 100vh 让它在页面滚动时保持可见,同时仍然占宽度。\n ⚠️ **本条刻意不设 z-index**:布局成员一旦带正 z-index,就会无条件压过宿主 portal 到 body 的\n 弹窗(兄弟项目 2026-10-05 真机事故「侧边栏盖住宿主设置弹窗」)。层序交给 DOM 顺序裁决。 */\n.dshpc-dock__panel{\n box-sizing:border-box;position:sticky;top:0;align-self:stretch;\n display:flex;flex-direction:column;flex:0 0 auto;\n /* 高度默认视口高(整页场景);嵌在定高容器里时由调用方给 --dshpc-dock-h(如 420px / 100%)。 */\n height:var(--dshpc-dock-h,100vh);max-height:var(--dshpc-dock-h,100vh);min-width:0;\n background:var(--dshpc-surface-base);color:var(--dshpc-fg);\n border-left:1px solid var(--dshpc-border);\n transition:border-color var(--dshpc-dur-fast) var(--dshpc-ease);\n box-shadow:var(--dshpc-shadow-2);\n /* 入场:从 0 宽滑出来(keyframes 只写 from,终点取内联 width),打开 / 耳朵展开都走这条。 */\n animation:dshpc-dock-in .22s var(--dshpc-ease);\n}\n/* overflow:hidden 只在动画前段(离散属性在 50% 翻转)——平时不能裁,否则挂在左缘外的\n 收起钮会被切掉一半。 */\n@keyframes dshpc-dock-in{from{width:0;opacity:0;overflow:hidden}}\n/* 收起的出场:宽度收到 0、透明淡出;落定后组件才真正摘掉这一栏(JS 延时 220ms 配合)。 */\n.dshpc-dock__panel--closing{\n width:0!important;min-width:0!important;opacity:0;border-left-width:0;\n transition:width .2s var(--dshpc-ease),opacity .2s var(--dshpc-ease),border-left-width .2s var(--dshpc-ease);\n}\n\n.dshpc-dock__head{\n flex:none;display:flex;align-items:center;gap:8px;\n /* 右侧 34px = 8(边距) + 20(关钮) + 6(呼吸):给绝对定位的关钮留位,标题/extra 不从它底下钻 */\n padding:10px 34px 10px 14px;\n border-bottom:1px solid var(--dshpc-border-faint);\n}\n/* 图标位 / 标题右侧的内容位:消费方传 ReactNode,可塞多个;库只负责排布,不抢宽度。 */\n.dshpc-dock__lead{display:inline-flex;align-items:center;gap:6px;flex:none;color:var(--dshpc-fg-2)}\n.dshpc-dock__extra{display:inline-flex;align-items:center;gap:6px;flex:none;margin-left:auto}\n/* 自定义头部:整行归调用方 —— 不加内边距/边框/背景,也不给关钮留内联空间(关钮是绝对定位的)。 */\n.dshpc-dock__head--custom{display:block;padding:0;border-bottom:none}\n.dshpc-dock__title{\n flex:1 1 auto;min-width:0;\n overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\n font-size:var(--dshpc-font-md);font-weight:600;\n}\n/* 关闭钮:20×20 方角图标位(与 Modal 的关闭钮同规格,不借 Picker 触发器皮肤)。 */\n.dshpc-dock__close{\n display:inline-flex;align-items:center;justify-content:center;flex:none;\n width:20px;height:20px;padding:0;border:none;border-radius:var(--dshpc-radius-sm);\n background:transparent;color:var(--dshpc-fg-3);\n font-family:inherit;font-size:13px;line-height:1;cursor:pointer;\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-dock__close:hover{background:var(--dshpc-hover);color:var(--dshpc-fg)}\n.dshpc-dock__close:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n/* 头部关钮:绝对定位,位置与内置头完全一致(top 10 / right 8);自定义头也用这一个位置。\n 锚点是面板本身(position:sticky 即定位上下文),不在滚动内容里,所以正文滚动它不跟滚。 */\n.dshpc-dock__close--abs{position:absolute;top:10px;right:8px;z-index:8}\n/* 浮动关钮:无头部面板用,略收一点边距。 */\n.dshpc-dock__close--floating{\n position:absolute;top:6px;right:6px;z-index:8;\n background:var(--dshpc-surface-menu);border:1px solid var(--dshpc-border-faint);\n}\n\n/* 内容区自己滚:面板高度锁 100vh,内容不设内部滚动就会把整页撑高。 */\n.dshpc-dock__body{flex:1 1 auto;min-height:0;overflow:auto}\n\n/* 拖拽条:左缘 6px 命中区,**自己不画任何线**。\n hover / 拖动时把面板自己的 border-left 染成蓝(用户 2026-10-28 四轮:蓝线只准改原线,\n 不准在原线旁边加一条 —— 之前在 padding box 左缘画渐变,正好叠出双线)。\n 命中区在 padding box 上、border 在它左外侧,所以只能改面板的 border 色。\n z-index 7 必须高于面板内容里的浮层(复制钮一类),否则命中区会被内容盖住。 */\n.dshpc-dock__resizer{\n position:absolute;left:0;top:0;bottom:0;width:6px;\n z-index:7;cursor:col-resize;background:transparent;\n}\n.dshpc-dock__panel:has(> .dshpc-dock__resizer:hover),\n.dshpc-dock__panel--resizing{\n /* 原线保留「上下渐隐」工作区指示条质感:把面板自己的 border-left 换成同款渐变\n (不是另加一条线)。面板只有这一条边框、无圆角,所以只作用在线上。 */\n border-image:linear-gradient(180deg,transparent,var(--dshpc-business) 30% 70%,transparent) 1;\n}\n\n/* 拖动期:① <iframe>(PDF / HTML 预览)是独立文档,会吞掉父文档的 pointermove,\n 向右拖进 iframe 就卡死 —— 整片让出指针事件;② contain 把重排隔离在栏内,\n 否则每帧改宽度都会牵动整页重排(兄弟项目 2026-10-04 真机「挪很久才动一下」)。 */\n.dshpc-dock.dshpc-dock--resizing iframe{pointer-events:none}\n.dshpc-dock.dshpc-dock--resizing .dshpc-dock__panel{contain:layout paint;will-change:width}\n\n/* 收起钮:**待在面板自己的框里**(用户 2026-10-28 三轮:占面板内部空间,不伸到外面去)。\n left:0 从内侧贴着分隔线 —— 贴线的一边不描边(线是面板自己的 border-left),页签与线不重合。\n 20×44(用户 2026-10-28 四轮定尺寸);实色底(--dshpc-plate,明暗各有实值),hover 亮一档。\n padding-right:2px 是**视觉居中**:右侧是圆角,箭头往直线那边挪 1px(用户 2026-10-28 四轮)。 */\n.dshpc-dock__collapse{\n position:absolute;left:0;top:50%;transform:translateY(-50%);\n z-index:8;display:inline-flex;align-items:center;justify-content:center;\n width:20px;height:44px;padding:0 2px 0 0;\n border-top:1px solid var(--dshpc-border);\n border-bottom:1px solid var(--dshpc-border);\n border-right:1px solid var(--dshpc-border);\n border-left:none;\n border-radius:0 var(--dshpc-radius-sm) var(--dshpc-radius-sm) 0;\n background:var(--dshpc-plate);color:var(--dshpc-fg-3);\n font-family:inherit;font-size:16px;line-height:1;cursor:pointer;\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-dock__collapse:hover{background:var(--dshpc-plate-hover);color:var(--dshpc-fg)}\n.dshpc-dock__collapse:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n\n/* 收起后的浮动耳朵:**fixed 贴右缘、垂直居中、独立于分栏**(用户 2026-10-28 定稿:\n 小页签挂中间、里面放面板图标、不显示文字,箭头与收起钮反向)。多个按收起顺序纵向堆叠。\n z 走 dock 档(低于宿主弹窗),避免盖住宿主 portal 层。 */\n.dshpc-dock__ears{\n position:fixed;top:50%;right:0;transform:translateY(-50%);\n z-index:var(--dshpc-z-dock,1030);\n display:flex;flex-direction:column;gap:8px;align-items:flex-end;\n pointer-events:none;\n}\n.dshpc-dock__ear{\n pointer-events:auto;display:inline-flex;align-items:center;justify-content:center;\n /* 与收起钮**同尺寸**(20×44,用户 2026-10-28 四轮):上/下/左描边,贴右缘的一侧不描。\n 实色底(--dshpc-plate),不用透明色 —— 透明底下透出东西很难看。\n padding-left:2px 是**视觉居中**:左侧是圆角,箭头往直线(右缘)那边挪 1px。 */\n width:20px;height:44px;box-sizing:border-box;padding:0 0 0 2px;\n border-top:1px solid var(--dshpc-border);\n border-bottom:1px solid var(--dshpc-border);\n border-left:1px solid var(--dshpc-border);\n border-right:none;\n border-radius:var(--dshpc-radius-sm) 0 0 var(--dshpc-radius-sm);\n background:var(--dshpc-plate);color:var(--dshpc-fg-2);\n cursor:pointer;font-family:inherit;line-height:1;\n animation:dshpc-ear-in .2s var(--dshpc-ease);\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n/* 入场:从右缘外滑进来,别「突然出现」(用户 2026-10-28)。 */\n@keyframes dshpc-ear-in{from{opacity:0;transform:translateX(14px)}}\n.dshpc-dock__ear:hover{background:var(--dshpc-plate-hover);color:var(--dshpc-fg)}\n.dshpc-dock__ear:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n/* 与收起钮的箭头同一字号(16px):收进去前后箭头一模一样大(用户 2026-10-28)。 */\n.dshpc-dock__ear-arrow{font-size:16px;color:var(--dshpc-fg-3)}\n.dshpc-dock__ear:hover .dshpc-dock__ear-arrow{color:var(--dshpc-fg)}\n/* 动效礼貌:系统声明减少动效时全部关掉(与 Segmented 同一约定),收起退化为瞬时、功能不受影响。 */\n@media (prefers-reduced-motion:reduce){\n .dshpc-dock__panel{animation:none}\n .dshpc-dock__panel--closing{transition:none}\n .dshpc-dock__ear{animation:none}\n}\n";
|
|
5053
|
+
//#endregion
|
|
5054
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/PanelDock.js
|
|
5166
5055
|
/**
|
|
5167
5056
|
* 停靠面板(PanelDock)—— 可停靠的右侧分栏容器。
|
|
5168
5057
|
*
|
|
@@ -5334,7 +5223,8 @@ window.__ModuleLoader__.load({
|
|
|
5334
5223
|
}
|
|
5335
5224
|
/** 停靠栏本体:只渲染「开着的」面板,结构取自对应的 `<DockPanel>`。 */
|
|
5336
5225
|
function PanelDock(props) {
|
|
5337
|
-
|
|
5226
|
+
ensureComponentStyles("panel-dock", PANEL_DOCK_CSS);
|
|
5227
|
+
ensureComponentStyles("feedback", FEEDBACK_CSS);
|
|
5338
5228
|
const tt = props.translate ?? t$2;
|
|
5339
5229
|
const state = (0, react$1.useSyncExternalStore)(props.dock.subscribe, props.dock.getSnapshot, props.dock.getSnapshot);
|
|
5340
5230
|
const rootRef = (0, react$1.useRef)(null);
|
|
@@ -5471,7 +5361,7 @@ window.__ModuleLoader__.load({
|
|
|
5471
5361
|
})));
|
|
5472
5362
|
}
|
|
5473
5363
|
//#endregion
|
|
5474
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
5364
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/Field.js
|
|
5475
5365
|
/**
|
|
5476
5366
|
* 输入类控件 —— **全站唯一实现**(L2 组件皮肤,P3)
|
|
5477
5367
|
*
|
|
@@ -5495,7 +5385,7 @@ window.__ModuleLoader__.load({
|
|
|
5495
5385
|
}
|
|
5496
5386
|
/** 文本输入。默认铺满容器(width:100%,与 Textarea 同口径);要定宽由调用方在外面包壳(如 192px 搜索槽)。 */
|
|
5497
5387
|
function Input(props) {
|
|
5498
|
-
|
|
5388
|
+
ensureComponentStyles("field", FIELD_CSS);
|
|
5499
5389
|
const { value, onChange, placeholder, size = "lg", error, disabled, type, icon, className, style } = props;
|
|
5500
5390
|
const [focused, setFocused] = (0, react$1.useState)(false);
|
|
5501
5391
|
const search = type === "search";
|
|
@@ -5543,6 +5433,22 @@ window.__ModuleLoader__.load({
|
|
|
5543
5433
|
function pad2(value) {
|
|
5544
5434
|
return String(value).padStart(2, "0");
|
|
5545
5435
|
}
|
|
5436
|
+
/** `Date` → 本机时区的 `YYYY-MM-DD`(图表按天 / 周切桶用)。 */
|
|
5437
|
+
function ymdOf(date) {
|
|
5438
|
+
return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`;
|
|
5439
|
+
}
|
|
5440
|
+
/** `YYYY-MM-DD` 前后挪几天(本机时区)。 */
|
|
5441
|
+
function addDays(value, delta) {
|
|
5442
|
+
const date = /* @__PURE__ */ new Date(`${value}T00:00:00`);
|
|
5443
|
+
date.setDate(date.getDate() + delta);
|
|
5444
|
+
return ymdOf(date);
|
|
5445
|
+
}
|
|
5446
|
+
/** 本周一(周一为一周之始,与 skill 同口径)。 */
|
|
5447
|
+
function mondayOf(value) {
|
|
5448
|
+
const date = /* @__PURE__ */ new Date(`${value}T00:00:00`);
|
|
5449
|
+
date.setDate(date.getDate() - (date.getDay() + 6) % 7);
|
|
5450
|
+
return ymdOf(date);
|
|
5451
|
+
}
|
|
5546
5452
|
/**
|
|
5547
5453
|
* 相对时间(GitHub 口径,用户 2026-10-28):<1 分钟「刚刚」、<1 小时「N 分钟前」、
|
|
5548
5454
|
* <24 小时「N 小时前」、<30 天「N 天前」、<12 个月「N 个月前」,再往上「N 年前」;
|
|
@@ -5585,7 +5491,7 @@ window.__ModuleLoader__.load({
|
|
|
5585
5491
|
return String(n);
|
|
5586
5492
|
}
|
|
5587
5493
|
//#endregion
|
|
5588
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
5494
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/official.js
|
|
5589
5495
|
/**
|
|
5590
5496
|
* L1 adapter —— 全仓**唯一** import 官方 primitives 平台模块的文件。
|
|
5591
5497
|
*
|
|
@@ -5630,7 +5536,7 @@ window.__ModuleLoader__.load({
|
|
|
5630
5536
|
return value;
|
|
5631
5537
|
}
|
|
5632
5538
|
//#endregion
|
|
5633
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
5539
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/utils/path.js
|
|
5634
5540
|
/**
|
|
5635
5541
|
* 纯路径方法 —— 只做字符串切分 / 拼接,不碰宿主、不依赖 React / DOM。
|
|
5636
5542
|
*
|
|
@@ -5669,7 +5575,7 @@ window.__ModuleLoader__.load({
|
|
|
5669
5575
|
return dir === "" ? name : `${dir}/${name}`;
|
|
5670
5576
|
}
|
|
5671
5577
|
//#endregion
|
|
5672
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
5578
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/explorer/types.js
|
|
5673
5579
|
/** HTML 静态预览的扩展名(与官方 htmlBodyDefinition 同款)。 */
|
|
5674
5580
|
const HTML_KINDS = ["html", "htm"];
|
|
5675
5581
|
/**
|
|
@@ -6051,9 +5957,12 @@ window.__ModuleLoader__.load({
|
|
|
6051
5957
|
};
|
|
6052
5958
|
}
|
|
6053
5959
|
//#endregion
|
|
6054
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
5960
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/explorer/explorer-css.generated.js
|
|
5961
|
+
const EXPLORER_CSS = "/* 工作区文件浏览器(dshpc-fb-*)。\n *\n * 度量真源 = 兄弟项目 dsh-task-dispatch-table 的 src/client/archive-session-css.ts\n * (.dsh-tdt-sv-* 全族)。**逐条照抄,不许自己估**:padding / gap / 圆角 / 字号 / 行高 /\n * 边框色 / 悬停色 / 透明度动画 / 溢出策略,一一对应,改这里之前先去那边对原文。\n * 前缀与变量名换成本仓口径(--tdt-* → --dshpc-*),数值不换。\n *\n * 控件:能核心就核心(面包屑 = Button ghost、行尾 = Button outline、展开 / 图标 = IconButton、\n * 分段 = Segmented、文字 = MarqueeText)。核心控件自带的 padding / 高度 / 皮肤在本文件里\n * **按兄弟数值覆盖**(选择器带 .dshpc-fb 前缀提高特异性,确保盖得住控件默认值)。\n */\n.dshpc-fb{\n position:relative;display:flex;flex-direction:column;height:100%;min-height:0;\n background:var(--dshpc-surface-base);color:var(--dshpc-fg);\n}\n\n/* 第一排:▾ 选层 + 面包屑 + 动作(兄弟 .dsh-tdt-sv-crumbbar)\n ⚠️ 不能 overflow:hidden —— 下拉浮层挂在它下面,裁了就看不见。 */\n.dshpc-fb__bar{\n position:relative;flex:none;display:flex;align-items:center;gap:2px;\n padding:4px 10px;border-bottom:1px solid var(--dshpc-border);white-space:nowrap;\n}\n.dshpc-fb__menu-wrap{position:relative;flex:none;display:inline-flex}\n.dshpc-fb__crumbs{position:relative;flex:1;min-width:0;display:flex;align-items:center;gap:2px;overflow:hidden}\n.dshpc-fb__crumbs-measure{\n position:absolute;top:0;left:0;display:inline-flex;align-items:center;gap:2px;\n visibility:hidden;pointer-events:none;white-space:nowrap;\n}\n\n/* 面包屑:核心 ghost 钮,但皮肤与尺寸取兄弟 .dsh-tdt-sv-crumb(高由内容决定,不锁控制高)。 */\n.dshpc-fb .dshpc-fb__crumb{\n appearance:none;background:0 0;border:none;height:auto;\n padding:2px 4px;border-radius:var(--dshpc-radius-sm);\n font:inherit;font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);\n color:var(--dshpc-fg-2);cursor:pointer;\n display:inline-flex;align-items:center;min-width:0;overflow:hidden;text-overflow:ellipsis;\n}\n.dshpc-fb .dshpc-fb__crumb:hover{background:var(--dshpc-hover);color:var(--dshpc-fg)}\n.dshpc-fb .dshpc-fb__crumb:disabled{color:var(--dshpc-fg-2);cursor:default}\n.dshpc-fb .dshpc-fb__crumb--current{cursor:default;color:var(--dshpc-fg);font-weight:600;min-width:0}\n.dshpc-fb .dshpc-fb__crumb--current:hover{background:0 0}\n.dshpc-fb__crumb-mq{flex:1 1 auto;min-width:0}\n.dshpc-fb__crumb-sep{flex:none;color:var(--dshpc-fg-3)}\n\n/* 越界(outside-workspace)第一排:只读完整路径(兄弟 .dsh-tdt-sv-crumbbar-plain-inner)。 */\n.dshpc-fb__bar-plain{\n font-family:var(--dshpc-font-mono,ui-monospace,SFMono-Regular,Menlo,Consolas,monospace);\n font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);color:var(--dshpc-fg-2);\n white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:default;user-select:none;\n}\n.dshpc-fb__actions{flex:none;display:flex;align-items:center;gap:4px}\n\n/* ▾ 选层浮层(兄弟 .dsh-tdt-sv-crumbs-*)。\n 层序:兄弟是 30/31;本仓 picker 面板是 1100,遮罩必须高于它,否则菜单开着点面板不算「点外部」。 */\n.dshpc-fb__crumbs-backdrop{position:fixed;inset:0;z-index:1200;background:transparent}\n.dshpc-fb__crumbs-menu{\n position:absolute;top:calc(100% + 4px);left:0;z-index:1201;min-width:160px;max-height:240px;overflow:auto;\n background:var(--dshpc-surface-menu);border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-sm);\n box-shadow:0 4px 16px rgba(0,0,0,.18);padding:4px;display:flex;flex-direction:column;\n}\n.dshpc-fb__menu-item{\n appearance:none;background:0 0;border:none;text-align:left;font:inherit;\n font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-md);\n padding:4px 8px;border-radius:var(--dshpc-radius-sm);color:var(--dshpc-fg);cursor:pointer;\n max-width:280px;display:flex;align-items:center;gap:2px;\n overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\n}\n.dshpc-fb__menu-item:hover{background:var(--dshpc-hover)}\n.dshpc-fb__menu-empty{\n font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-md);padding:4px 8px;color:var(--dshpc-fg-3);\n}\n.dshpc-fb__menu-icon{flex:none;display:inline-flex}\n.dshpc-fb__menu-chev{flex:none;color:var(--dshpc-fg-3);margin-right:1px}\n.dshpc-fb__menu-chev-slot{flex:none;width:11px;height:11px;margin-right:1px}\n.dshpc-fb__menu-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n\n/* 第二排(仅预览态):文件名 + 工具(兄弟 .dsh-tdt-sv-titlebar / -preview-title-inner)。 */\n.dshpc-fb__title{\n flex:none;display:flex;align-items:center;gap:8px;\n padding:8px 14px;border-bottom:1px solid var(--dshpc-border);\n}\n.dshpc-fb__title-inner{\n font-family:var(--dshpc-font-mono,ui-monospace,SFMono-Regular,Menlo,Consolas,monospace);\n font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);color:var(--dshpc-fg);\n white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:default;\n}\n\n/* 主体(兄弟 .dsh-tdt-sv-preview-body / -hint / -preview-err) */\n.dshpc-fb__body{flex:1;min-height:0;overflow-x:hidden;overflow-y:auto;padding:12px 14px}\n.dshpc-fb__note{font-size:var(--dshpc-font-sm);color:var(--dshpc-fg-2);text-align:center;padding:12px 0}\n.dshpc-fb__err{\n display:flex;flex-direction:column;align-items:flex-start;gap:10px;\n font-size:var(--dshpc-font-sm);line-height:1.6;color:var(--dshpc-fg-2);padding:8px 0;\n}\n\n/* 目录树(兄弟 .dsh-tdt-sv-tree*) */\n.dshpc-fb__tree{flex:1;min-height:0;overflow:auto;padding:6px 8px}\n.dshpc-fb__row{\n display:flex;align-items:center;gap:8px;padding:6px 8px;\n border-radius:var(--dshpc-radius-sm);cursor:pointer;user-select:none;\n}\n.dshpc-fb__row:hover{background:var(--dshpc-hover)}\n.dshpc-fb__row:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:-2px}\n.dshpc-fb__row-icon{flex:none;display:inline-flex;color:var(--dshpc-fg-2)}\n.dshpc-fb__row-name{\n flex:1;min-width:0;font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);color:var(--dshpc-fg);\n overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\n}\n\n/* 展开开关:核心 IconButton,命中位 20×20 + 展开时转 90°(兄弟 .dsh-tdt-sv-tree-toggle{,-open})。 */\n.dshpc-fb .dshpc-fb__row-toggle{\n appearance:none;background:0 0;border:none;flex:none;\n width:20px;height:20px;padding:0;margin:0;border-radius:var(--dshpc-radius-sm);\n color:var(--dshpc-fg-2);cursor:pointer;\n display:inline-flex;align-items:center;justify-content:center;\n transition:transform var(--dshpc-dur-fast) var(--dshpc-ease),background var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-fb .dshpc-fb__row-toggle--open{transform:rotate(90deg)}\n\n/* 行尾「进入 / 选择」:核心 outline 钮,皮肤取兄弟 .dsh-tdt-sv-tree-act(高由内容决定)。\n 平时隐身但占位(opacity 而非 display)⇒ 出现时不顶动行内布局。 */\n.dshpc-fb .dshpc-fb__row-act{\n flex:none;margin-left:auto;appearance:none;background:0 0;\n border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-sm);\n height:auto;padding:2px 8px;font-size:var(--dshpc-font-sm);line-height:1.4;\n color:var(--dshpc-fg-2);cursor:pointer;\n opacity:0;pointer-events:none;\n transition:opacity var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-fb__row:hover .dshpc-fb__row-act,.dshpc-fb .dshpc-fb__row-act:focus-visible{opacity:1;pointer-events:auto}\n.dshpc-fb .dshpc-fb__row-act:hover{background:var(--dshpc-hover);color:var(--dshpc-fg)}\n\n.dshpc-fb__row-children{\n margin-left:9px;padding-left:7px;border-left:1px solid var(--dshpc-border);\n display:flex;flex-direction:column;\n}\n.dshpc-fb__row-note{flex:none;padding:8px 10px;font-size:var(--dshpc-font-sm);color:var(--dshpc-fg-3)}\n.dshpc-fb__row-err{padding:4px 8px 4px 36px;font-size:var(--dshpc-font-sm);color:var(--dshpc-danger)}\n\n/* 预览体内部容器(仅本仓预览组件用;兄弟对应 preview-fill / preview-body-code 一类)。\n 必须 border-box:渲染态 inline 加了 padding:12px 14px,content-box 下 width:100%+padding\n 会溢出父层 28px(父 .dshpc-fb 无 overflow 裁切)→ 恒多一条横滚条;border-box 把 padding\n 算进 100%,从根消除该溢出。 */\n.dshpc-fb__text{flex:1;min-height:0;overflow:auto;width:100%;box-sizing:border-box}\n.dshpc-fb__banner{padding:6px 10px;background:var(--dshpc-open-bg);color:var(--dshpc-fg-2);font-size:var(--dshpc-font-sm)}\n.dshpc-fb__more{display:flex;justify-content:center;padding:10px}\n.dshpc-fb__image{max-width:100%;border-radius:var(--dshpc-radius-sm);border:1px solid var(--dshpc-border)}\n/* iframe 的外壳(兄弟 .dsh-tdt-sv-preview-fill):iframe 必须包在这一层里才拿得到高度——\n 裸挂 iframe 时替换元素的自动最小尺寸会让高度算不出来(表现为预览区整片空白、像没反应)。 */\n.dshpc-fb__fill{flex:1;min-height:0;display:flex;overflow:hidden;padding:0}\n.dshpc-fb__frame{flex:1;min-height:0;width:100%;height:100%;border:none;background:var(--dshpc-surface-1)}\n";
|
|
5962
|
+
//#endregion
|
|
5963
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/explorer/preview/BytesPreview.js
|
|
6055
5964
|
function BytesPreview(props) {
|
|
6056
|
-
|
|
5965
|
+
ensureComponentStyles("explorer", EXPLORER_CSS);
|
|
6057
5966
|
const tt = props.translate ?? t$2;
|
|
6058
5967
|
const [url, setUrl] = (0, react$1.useState)(null);
|
|
6059
5968
|
const [failed, setFailed] = (0, react$1.useState)(null);
|
|
@@ -51489,7 +51398,7 @@ window.__ModuleLoader__.load({
|
|
|
51489
51398
|
const stex = mkStex(false);
|
|
51490
51399
|
mkStex(true);
|
|
51491
51400
|
//#endregion
|
|
51492
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
51401
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/code-viewer-lang.js
|
|
51493
51402
|
/**
|
|
51494
51403
|
* 源码态语法高亮:扩展名 → CodeMirror 语言映射。
|
|
51495
51404
|
*
|
|
@@ -51642,7 +51551,7 @@ window.__ModuleLoader__.load({
|
|
|
51642
51551
|
}
|
|
51643
51552
|
}
|
|
51644
51553
|
//#endregion
|
|
51645
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
51554
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/code-viewer-theme.js
|
|
51646
51555
|
/**
|
|
51647
51556
|
* CodeMirror 6 主题(DSH 共享底座版)。
|
|
51648
51557
|
*
|
|
@@ -52046,7 +51955,10 @@ window.__ModuleLoader__.load({
|
|
|
52046
51955
|
];
|
|
52047
51956
|
}
|
|
52048
51957
|
//#endregion
|
|
52049
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
51958
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/code-viewer-css.generated.js
|
|
51959
|
+
const CODE_VIEWER_CSS = "/* CodeViewer(只读 CodeMirror 查看器)样式。类名固定 dshpc-cv*;颜色吃 --dshpc-* token,\n 深色由 design 的 token 深色段自动生效(不写死颜色值)。 */\n.dshpc-cv{position:relative;display:flex;flex-direction:column;height:100%;min-height:0;}\n/* 复制钮复用核心 IconButton(variant=outline / size=md):盒型、描边、圆角(已统一 md)、底色、hover 全由核心提供;\n 这里只管「绝对定位 + 默认隐藏、hover/聚焦才显」(overlay 浮在编辑器右上角)。 */\n.dshpc-cv__copy{position:absolute;top:6px;right:6px;z-index:5;opacity:0;}\n.dshpc-cv:hover .dshpc-cv__copy,.dshpc-cv__copy:focus-visible{opacity:1;}\n.dshpc-cv__copy svg{width:16px;height:16px;}\n.dshpc-cv__editor{flex:1 1 auto;min-height:0;overflow:hidden;}\n.dshpc-cv__editor .cm-editor{height:100%;}\n.dshpc-cv__editor .cm-scroller{overflow:auto;}\n";
|
|
51960
|
+
//#endregion
|
|
51961
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/ui/CodeViewer.js
|
|
52050
51962
|
/**
|
|
52051
51963
|
* CodeViewer —— 只读源码查看器(替代官方 Shiki CodeBlock),DSH 共享底座版。
|
|
52052
51964
|
*
|
|
@@ -52071,6 +51983,7 @@ window.__ModuleLoader__.load({
|
|
|
52071
51983
|
return body === null ? false : body.hasAttribute(DARK_ATTR);
|
|
52072
51984
|
}
|
|
52073
51985
|
function CodeViewer(props) {
|
|
51986
|
+
ensureComponentStyles("code-viewer", CODE_VIEWER_CSS);
|
|
52074
51987
|
const { text, path, t, className, style, height = "100%", lineNumbers = true } = props;
|
|
52075
51988
|
const [copied, setCopied] = (0, react$1.useState)(false);
|
|
52076
51989
|
const [dark, setDark] = (0, react$1.useState)(hostDark);
|
|
@@ -52138,7 +52051,7 @@ window.__ModuleLoader__.load({
|
|
|
52138
52051
|
}));
|
|
52139
52052
|
}
|
|
52140
52053
|
//#endregion
|
|
52141
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
52054
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/utils/number.js
|
|
52142
52055
|
/**
|
|
52143
52056
|
* 字节数 → 人话(`12 KB` / `3.4 MB`)。
|
|
52144
52057
|
* 0 与负数 ⇒ `—`(不显示「0 B」这种假精确)。
|
|
@@ -52161,7 +52074,7 @@ window.__ModuleLoader__.load({
|
|
|
52161
52074
|
return `${value >= 10 ? String(Math.round(value)) : value.toFixed(1)} ${units[unit]}`;
|
|
52162
52075
|
}
|
|
52163
52076
|
//#endregion
|
|
52164
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
52077
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/explorer/preview/md-labels.js
|
|
52165
52078
|
function markdownLabels() {
|
|
52166
52079
|
return {
|
|
52167
52080
|
code: {
|
|
@@ -52177,9 +52090,9 @@ window.__ModuleLoader__.load({
|
|
|
52177
52090
|
};
|
|
52178
52091
|
}
|
|
52179
52092
|
//#endregion
|
|
52180
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
52093
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/explorer/preview/TextPreview.js
|
|
52181
52094
|
function TextPreview(props) {
|
|
52182
|
-
|
|
52095
|
+
ensureComponentStyles("explorer", EXPLORER_CSS);
|
|
52183
52096
|
const tt = props.translate ?? t$2;
|
|
52184
52097
|
const [text, setText] = (0, react$1.useState)("");
|
|
52185
52098
|
const [truncated, setTruncated] = (0, react$1.useState)(false);
|
|
@@ -52261,7 +52174,7 @@ window.__ModuleLoader__.load({
|
|
|
52261
52174
|
}, tt("previewLoadMore"))) : null);
|
|
52262
52175
|
}
|
|
52263
52176
|
//#endregion
|
|
52264
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
52177
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/explorer/preview/HtmlPreview.js
|
|
52265
52178
|
/** 官方 CSP 原文(documentpreview lib/client.js 同款,不多开不少关)。 */
|
|
52266
52179
|
const HTML_CSP = "default-src 'none'; script-src 'none'; style-src 'unsafe-inline'; img-src data:; font-src data:; media-src data:";
|
|
52267
52180
|
/** 禁用标签(官方清单)。 */
|
|
@@ -52309,7 +52222,7 @@ window.__ModuleLoader__.load({
|
|
|
52309
52222
|
return `<!DOCTYPE html>\n${doc.documentElement.outerHTML}`;
|
|
52310
52223
|
}
|
|
52311
52224
|
function HtmlPreview(props) {
|
|
52312
|
-
|
|
52225
|
+
ensureComponentStyles("explorer", EXPLORER_CSS);
|
|
52313
52226
|
const tt = props.translate ?? t$2;
|
|
52314
52227
|
const [doc, setDoc] = (0, react$1.useState)(null);
|
|
52315
52228
|
const [failed, setFailed] = (0, react$1.useState)(null);
|
|
@@ -52367,9 +52280,9 @@ window.__ModuleLoader__.load({
|
|
|
52367
52280
|
}));
|
|
52368
52281
|
}
|
|
52369
52282
|
//#endregion
|
|
52370
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
52283
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/explorer/preview/OfficePreview.js
|
|
52371
52284
|
function OfficePreview(props) {
|
|
52372
|
-
|
|
52285
|
+
ensureComponentStyles("explorer", EXPLORER_CSS);
|
|
52373
52286
|
const tt = props.translate ?? t$2;
|
|
52374
52287
|
const [url, setUrl] = (0, react$1.useState)(null);
|
|
52375
52288
|
const [failed, setFailed] = (0, react$1.useState)(null);
|
|
@@ -52412,7 +52325,7 @@ window.__ModuleLoader__.load({
|
|
|
52412
52325
|
});
|
|
52413
52326
|
}
|
|
52414
52327
|
//#endregion
|
|
52415
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
52328
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/explorer/preview/index.js
|
|
52416
52329
|
function FilePreview(props) {
|
|
52417
52330
|
ensureControls();
|
|
52418
52331
|
const tt = props.translate ?? t$2;
|
|
@@ -52454,7 +52367,7 @@ window.__ModuleLoader__.load({
|
|
|
52454
52367
|
return null;
|
|
52455
52368
|
}
|
|
52456
52369
|
//#endregion
|
|
52457
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
52370
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/explorer/FileBrowser.js
|
|
52458
52371
|
/**
|
|
52459
52372
|
* ▾ 下拉条目构造(**picker 与 dock 共用同一段代码**,差别只在入参——源实现用户 2026-09-29
|
|
52460
52373
|
* 点名提炼,严禁两处各写一份):
|
|
@@ -52532,7 +52445,7 @@ window.__ModuleLoader__.load({
|
|
|
52532
52445
|
}
|
|
52533
52446
|
/** 目录浏览器面板。详见 {@link FileBrowserProps}。 */
|
|
52534
52447
|
function FileBrowser(props) {
|
|
52535
|
-
|
|
52448
|
+
ensureComponentStyles("explorer", EXPLORER_CSS);
|
|
52536
52449
|
const tt = props.translate ?? t$2;
|
|
52537
52450
|
const picker = props.picker === true;
|
|
52538
52451
|
const cacheRef = (0, react$1.useRef)(null);
|
|
@@ -53032,7 +52945,7 @@ window.__ModuleLoader__.load({
|
|
|
53032
52945
|
}, outside ? crumbBarPlain : crumbBar, titleBar, body);
|
|
53033
52946
|
}
|
|
53034
52947
|
//#endregion
|
|
53035
|
-
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.
|
|
52948
|
+
//#region ../../node_modules/.pnpm/dsh-plugin-core@0.12.0_@babel+runtime@8.0.8_@codemirror+autocomplete@6.20.4_@codemirror_098a2ccd8a53f295ad0979106693a6a3/node_modules/dsh-plugin-core/dist/explorer/open.js
|
|
53036
52949
|
/**
|
|
53037
52950
|
* 预览体:`openFilePreview` 的 FileBrowser 包裹层。职责只有一个——**切工作区**:
|
|
53038
52951
|
* ▾ 下拉点工作区 ⇒ 换该工作区的锚点会话、key 重挂载、path 回根。
|
|
@@ -53172,7 +53085,8 @@ window.__ModuleLoader__.load({
|
|
|
53172
53085
|
if (event.key === "Escape") close();
|
|
53173
53086
|
};
|
|
53174
53087
|
window.addEventListener("keydown", onKeyDown);
|
|
53175
|
-
|
|
53088
|
+
ensureComponentStyles("panel-dock", PANEL_DOCK_CSS, getStyleKit());
|
|
53089
|
+
ensureComponentStyles("feedback", FEEDBACK_CSS, getStyleKit());
|
|
53176
53090
|
let pinnedWidth = null;
|
|
53177
53091
|
const keepWidth = () => {
|
|
53178
53092
|
const panel = container.querySelector(".dshpc-dock__panel");
|
|
@@ -53261,7 +53175,8 @@ window.__ModuleLoader__.load({
|
|
|
53261
53175
|
claim: !mine && task.status === "open",
|
|
53262
53176
|
resume: mine,
|
|
53263
53177
|
finish: mine,
|
|
53264
|
-
release: mine
|
|
53178
|
+
release: mine,
|
|
53179
|
+
cancel: mine || task.status === "open"
|
|
53265
53180
|
};
|
|
53266
53181
|
}
|
|
53267
53182
|
/** 六档菜单命中。标记(`stale` / `overdue` / `backlog`)都由 skill 判定,前端只读布尔。 */
|
|
@@ -53293,7 +53208,51 @@ window.__ModuleLoader__.load({
|
|
|
53293
53208
|
...task.tags ?? []
|
|
53294
53209
|
].filter((s) => s !== null && s !== void 0 && s !== "").map((s) => s.toLowerCase()).some((s) => s.includes(kw));
|
|
53295
53210
|
}
|
|
53296
|
-
/**
|
|
53211
|
+
/**
|
|
53212
|
+
* 组内优先级(用户 2026-10-30):我在做 → 别人在做 → 积压待认领 → 其余待认领。
|
|
53213
|
+
* 越靠前越需要本人动手;同档再按时间倒序(沿用「我的待办」的老口径)。
|
|
53214
|
+
*/
|
|
53215
|
+
function rankOf(task) {
|
|
53216
|
+
if (task.status === "doing" || task.status === "blocked") return task.mine === true ? 0 : 1;
|
|
53217
|
+
return task.backlog === true ? 2 : 3;
|
|
53218
|
+
}
|
|
53219
|
+
/** 组头要数的那几档(不含「全部」和「我的待办」):与左侧菜单同一套判据。 */
|
|
53220
|
+
const GROUP_TABS = [
|
|
53221
|
+
"open",
|
|
53222
|
+
"doing",
|
|
53223
|
+
"backlog",
|
|
53224
|
+
"overdue",
|
|
53225
|
+
"stale"
|
|
53226
|
+
];
|
|
53227
|
+
/** 按工作区切段:**顺序不在这里定** —— `selectView` 已按「工作区注册序 + 组内优先级」排好,
|
|
53228
|
+
* 这里只把连续同区的行切开,顺带数该组各档(纯函数,冒烟可直测)。
|
|
53229
|
+
* 计数口径 = 组内**当前显示的行**,与左侧六档菜单同一个 `tabHit` ⇒ 组头数字和列出来的行对得上。 */
|
|
53230
|
+
function groupRows(rows) {
|
|
53231
|
+
const groups = [];
|
|
53232
|
+
for (const row of rows) {
|
|
53233
|
+
const last = groups[groups.length - 1];
|
|
53234
|
+
if (last !== void 0 && last.workspace.id === row.task.workspace.id) last.rows.push(row);
|
|
53235
|
+
else groups.push({
|
|
53236
|
+
workspace: row.task.workspace,
|
|
53237
|
+
rows: [row]
|
|
53238
|
+
});
|
|
53239
|
+
}
|
|
53240
|
+
return groups.map((group) => {
|
|
53241
|
+
const counts = {
|
|
53242
|
+
open: 0,
|
|
53243
|
+
doing: 0,
|
|
53244
|
+
backlog: 0,
|
|
53245
|
+
overdue: 0,
|
|
53246
|
+
stale: 0
|
|
53247
|
+
};
|
|
53248
|
+
for (const row of group.rows) for (const tab of GROUP_TABS) if (tabHit(row.task, tab)) counts[tab] += 1;
|
|
53249
|
+
return {
|
|
53250
|
+
...group,
|
|
53251
|
+
counts
|
|
53252
|
+
};
|
|
53253
|
+
});
|
|
53254
|
+
}
|
|
53255
|
+
/** 当前筛选下的平铺列表,已按「工作区分组 + 组内优先级 + 时间倒序」排好。 */
|
|
53297
53256
|
function selectView(current) {
|
|
53298
53257
|
const board = current.board;
|
|
53299
53258
|
const empty = {
|
|
@@ -53311,22 +53270,33 @@ window.__ModuleLoader__.load({
|
|
|
53311
53270
|
if (board === null) return empty;
|
|
53312
53271
|
const { tasks } = board;
|
|
53313
53272
|
const { tab, workspace, owner, keyword } = current.query;
|
|
53273
|
+
const scope = tasks.filter((task) => workspace === "" || task.workspace.id === workspace).filter((task) => ownerHit(task, owner)).filter((task) => keywordHit(task, keyword));
|
|
53274
|
+
const counts = {
|
|
53275
|
+
all: scope.length,
|
|
53276
|
+
mine: 0,
|
|
53277
|
+
open: 0,
|
|
53278
|
+
doing: 0,
|
|
53279
|
+
backlog: 0,
|
|
53280
|
+
overdue: 0,
|
|
53281
|
+
stale: 0
|
|
53282
|
+
};
|
|
53283
|
+
for (const task of scope) {
|
|
53284
|
+
if (task.mine === true) counts.mine += 1;
|
|
53285
|
+
if (task.status === "open") counts.open += 1;
|
|
53286
|
+
if (task.status === "doing" || task.status === "blocked") counts.doing += 1;
|
|
53287
|
+
if (task.backlog === true) counts.backlog += 1;
|
|
53288
|
+
if (task.overdue === true) counts.overdue += 1;
|
|
53289
|
+
if (task.stale === true) counts.stale += 1;
|
|
53290
|
+
}
|
|
53291
|
+
const wsOrder = new Map(board.workspaces.map((ws, index) => [ws.id, index]));
|
|
53314
53292
|
return {
|
|
53315
|
-
rows:
|
|
53293
|
+
rows: scope.filter((task) => tabHit(task, tab)).sort((a, b) => (wsOrder.get(a.workspace.id) ?? Number.MAX_SAFE_INTEGER) - (wsOrder.get(b.workspace.id) ?? Number.MAX_SAFE_INTEGER) || rankOf(a) - rankOf(b) || String(b.created ?? b.started ?? "").localeCompare(String(a.created ?? a.started ?? ""))).map((task) => ({
|
|
53316
53294
|
kind: "task",
|
|
53317
53295
|
key: `${task.workspace.id}:${task.id}`,
|
|
53318
53296
|
task,
|
|
53319
53297
|
mine: task.mine === true
|
|
53320
53298
|
})),
|
|
53321
|
-
counts
|
|
53322
|
-
all: tasks.length,
|
|
53323
|
-
mine: tasks.filter((task) => task.mine === true).length,
|
|
53324
|
-
open: tasks.filter((task) => task.status === "open").length,
|
|
53325
|
-
doing: tasks.filter((task) => task.status === "doing" || task.status === "blocked").length,
|
|
53326
|
-
backlog: tasks.filter((task) => task.backlog === true).length,
|
|
53327
|
-
overdue: tasks.filter((task) => task.overdue === true).length,
|
|
53328
|
-
stale: tasks.filter((task) => task.stale === true).length
|
|
53329
|
-
}
|
|
53299
|
+
counts
|
|
53330
53300
|
};
|
|
53331
53301
|
}
|
|
53332
53302
|
/**
|
|
@@ -53442,6 +53412,10 @@ window.__ModuleLoader__.load({
|
|
|
53442
53412
|
function fetchBoardSnapshot(opts = {}) {
|
|
53443
53413
|
return fetchJson(`/board/snapshot${opts.fresh === true ? "?fresh=1" : ""}`);
|
|
53444
53414
|
}
|
|
53415
|
+
/** 历史页顶部趋势(gran = 柱图粒度;切粒度 = 重新请求,host 有读缓存)。 */
|
|
53416
|
+
function fetchHistoryTrend(gran = "day") {
|
|
53417
|
+
return fetchJson(`/history/trend?gran=${gran}`);
|
|
53418
|
+
}
|
|
53445
53419
|
//#endregion
|
|
53446
53420
|
//#region src/client/store.ts
|
|
53447
53421
|
/**
|
|
@@ -53608,14 +53582,35 @@ body{
|
|
|
53608
53582
|
--dtl-business-soft:color-mix(in srgb,var(--dtl-business) 14%,transparent);
|
|
53609
53583
|
--dtl-danger-soft:color-mix(in srgb,var(--dtl-danger) 8%,transparent);
|
|
53610
53584
|
|
|
53611
|
-
/* ──
|
|
53612
|
-
|
|
53585
|
+
/* ── 图表色(2026-10-30 用户改版)───────────────────────────────
|
|
53586
|
+
首页趋势图:完成 = **蓝**(business,用户 2026-10-30「绿色那个柱子不好看,用 business 蓝」)、
|
|
53587
|
+
取消 = 红;未结那根拆两段(用户 2026-10-30)—— 进行中 = 绿、待认领 = 琥珀;
|
|
53588
|
+
新增曲线另走一档**中性灰**——柱子已经占了蓝,曲线也用蓝就分不清了。
|
|
53589
|
+
色值仍直接取核心 alias(state-business / state-success / state-warn / state-error),不手写。
|
|
53590
|
+
历史页柱色仍是「完成绿 / 取消红」,曲线沿用 --dtl-chart-added(蓝)。 */
|
|
53591
|
+
--dtl-chart-done:var(--dtl-business);
|
|
53592
|
+
--dtl-chart-doing:var(--dtl-success);
|
|
53613
53593
|
--dtl-chart-open:var(--dtl-warning);
|
|
53614
|
-
--dtl-chart-added:var(--dtl-
|
|
53594
|
+
--dtl-chart-added:var(--dtl-business);
|
|
53595
|
+
--dtl-chart-line:var(--dtl-fg-3);
|
|
53596
|
+
/* 柱面斜纹用的半透明条:取卡底色 ⇒ 明暗主题自动跟着走,看着像柱子上开了几道细缝
|
|
53597
|
+
(2026-10-30 三改:32% → 18% → 8%,要很淡) */
|
|
53598
|
+
--dtl-chart-stripe:color-mix(in srgb,var(--dtl-surface-1) 8%,transparent);
|
|
53615
53599
|
|
|
53616
53600
|
/* ── 交互底 ──────────────────────────────────────────────────── */
|
|
53617
53601
|
/* 卡 / 行 hover 高亮:淡蓝(灰高亮在卡底上几乎看不出来) */
|
|
53618
53602
|
--dtl-card-hover:rgba(37,99,235,.07);
|
|
53603
|
+
/* 「有底无边」控件底(图表右上角翻页箭头,用户 2026-10-30):
|
|
53604
|
+
在卡片底色上掺一档前景色 ⇒ 不透明(压得住下面的刻度线)又比卡面略深,
|
|
53605
|
+
明暗两主题都跟着 fg / surface 自动走 */
|
|
53606
|
+
--dtl-btn-soft:color-mix(in srgb,var(--dtl-fg) 8%,var(--dtl-surface-1));
|
|
53607
|
+
/* 图表浮卡:**明暗两主题用同一支深灰底 + 浅字**(用户 2026-10-30 定稿)——
|
|
53608
|
+
掺色的浅灰在浅色主题下仍然像白底、跟页面糊在一起;干脆做成固定深色小片,
|
|
53609
|
+
两套主题都不用再猜对比度。色值写死在这里,别处不许再手写。 */
|
|
53610
|
+
--dtl-tip-bg:#23262c;
|
|
53611
|
+
--dtl-tip-border:rgba(255,255,255,.14);
|
|
53612
|
+
--dtl-tip-fg:#f2f4f7;
|
|
53613
|
+
--dtl-tip-fg-dim:#a8b0ba;
|
|
53619
53614
|
|
|
53620
53615
|
/* ── 圆角(宿主真值 4/8/12)───────────────────────────────────── */
|
|
53621
53616
|
--dtl-radius-xs:var(--dsw-radius-xs,4px);
|
|
@@ -53640,6 +53635,12 @@ body{
|
|
|
53640
53635
|
/* 统计卡主数字:宿主字号族最大 16px,看板主数字要更大 ⇒ 单开一档(别处不许直接写 px) */
|
|
53641
53636
|
--dtl-font-stat:26px;
|
|
53642
53637
|
|
|
53638
|
+
/* ── 统计卡固定高度(用户 2026-10-29 定)────────────────────────
|
|
53639
|
+
卡高**只由这一条决定**,不跟内容走:小字缺行 / 小字凑巧换行都不改卡高。
|
|
53640
|
+
算式 = 三行正文(标签 18 + 数字 26×1.15 + 小字 14)+ 上下 padding 24 + 两处 gap 8,
|
|
53641
|
+
也就是三行都满时的自然高度 ⇒ 视觉与旧版一致,但不再被文字挤动。 */
|
|
53642
|
+
--dtl-stat-h:calc(var(--dtl-space-3) * 2 + var(--dtl-line-sm) + var(--dtl-line-xs) + 1.15 * var(--dtl-font-stat) + var(--dtl-space-1) * 2);
|
|
53643
|
+
|
|
53643
53644
|
/* ── 动效 ────────────────────────────────────────────────────── */
|
|
53644
53645
|
--dtl-dur-fast:var(--ds-transition-duration-fast,.12s);
|
|
53645
53646
|
--dtl-ease:var(--ds-ease-in-out,cubic-bezier(.4,0,.2,1));
|
|
@@ -53650,6 +53651,8 @@ body{
|
|
|
53650
53651
|
body[data-ds-dark-theme]{
|
|
53651
53652
|
/* 暗色下蓝要更亮、透明度更高才压得住深底 */
|
|
53652
53653
|
--dtl-card-hover:rgba(96,165,250,.13);
|
|
53654
|
+
/* 暗底上掺白 8% 太浅 ⇒ 提到 12%,仍与卡面同族(不是另一套皮肤) */
|
|
53655
|
+
--dtl-btn-soft:color-mix(in srgb,var(--dtl-fg) 12%,var(--dtl-surface-1));
|
|
53653
53656
|
/* 语义色浅底在深色下压到 12% / 5%(8% 在深底上偏重) */
|
|
53654
53657
|
--dtl-business-soft:color-mix(in srgb,var(--dtl-business) 12%,transparent);
|
|
53655
53658
|
--dtl-danger-soft:color-mix(in srgb,var(--dtl-danger) 5%,transparent);
|
|
@@ -53688,79 +53691,241 @@ body[data-ds-dark-theme]{
|
|
|
53688
53691
|
*/
|
|
53689
53692
|
/** 基础层样式(tokens + 业务容器类;幂等注入)。 */
|
|
53690
53693
|
const UI_BASE_CSS = `
|
|
53691
|
-
/* 统计卡:8 块(2×4)+ 右图表卡位
|
|
53692
|
-
|
|
53694
|
+
/* 统计卡:8 块(2×4)+ 右图表卡位
|
|
53695
|
+
⚠️ 卡高 = --dtl-stat-h 定死,**不跟内容走**(用户 2026-10-29):小字缺行、小字换行
|
|
53696
|
+
都不许改卡高,否则两个页面的卡一错位就被一眼看出来。文字一律贴顶(不用居中:
|
|
53697
|
+
缺小字时居中的卡会显得空)。 */
|
|
53698
|
+
.dtl-stat{display:flex;flex-direction:column;justify-content:flex-start;gap:var(--dtl-space-1);
|
|
53699
|
+
height:var(--dtl-stat-h);box-sizing:border-box;overflow:hidden;
|
|
53693
53700
|
padding:var(--dtl-space-3) var(--dtl-space-4);text-align:left;}
|
|
53701
|
+
/* 三行文字各自的行高必须显式写死,--dtl-stat-h 的算式才对得上(别让行高继承宿主) */
|
|
53702
|
+
.dtl-stat__label{font-size:var(--dtl-font-sm);line-height:var(--dtl-line-sm);color:var(--dtl-fg-2);}
|
|
53694
53703
|
.dtl-stat__value{font-size:var(--dtl-font-stat);font-weight:600;line-height:1.15;font-variant-numeric:tabular-nums;}
|
|
53695
|
-
|
|
53704
|
+
/* 大数字后面紧跟的小字(历史页「28 完成 27 · 取消 1」那行):基线对齐、不参与大字号 */
|
|
53705
|
+
.dtl-stat__main{display:flex;align-items:baseline;gap:var(--dtl-space-2);min-width:0;}
|
|
53706
|
+
.dtl-stat__sub{font-size:var(--dtl-font-xs);font-weight:400;line-height:var(--dtl-line-xs);
|
|
53707
|
+
color:var(--dtl-fg-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
|
|
53708
|
+
/* 小字锁单行:卡高定死,换行会被 overflow 裁掉 ⇒ 宁可省略号 */
|
|
53709
|
+
.dtl-stat__hint{font-size:var(--dtl-font-xs);line-height:var(--dtl-line-xs);color:var(--dtl-fg-3);
|
|
53710
|
+
white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
|
|
53711
|
+
|
|
53712
|
+
/* 局部加载:核心 Loader(三块脉动)居中,只占没数据的那一块,不盖整页 */
|
|
53713
|
+
.dtl-loading{display:flex;align-items:center;justify-content:center;padding:var(--dtl-space-4) 0;}
|
|
53696
53714
|
|
|
53697
53715
|
/* 统计区整体:左 8 块(2 行 × 4 列)+ 右图表卡,参考图同款分栏。
|
|
53698
53716
|
⚠️ 列数写死 4 → 2,绝不给 3:3 列会排出 3+1 的非对称(用户 2026-10-17)。
|
|
53699
|
-
|
|
53717
|
+
行高也定死成 --dtl-stat-h(不是 1fr)⇒ 行不随内容涨,卡与卡之间永远等高。
|
|
53718
|
+
两侧等高仍由 .dtl-stats 的 stretch + 图卡 height:100% 保证。 */
|
|
53700
53719
|
.dtl-stats{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(0,1fr);gap:var(--dtl-space-3);align-items:stretch;}
|
|
53701
|
-
.dtl-stats__cards{display:grid;grid-auto-flow:column;grid-template-columns:repeat(4,minmax(0,1fr));grid-template-rows:repeat(2,
|
|
53720
|
+
.dtl-stats__cards{display:grid;grid-auto-flow:column;grid-template-columns:repeat(4,minmax(0,1fr));grid-template-rows:repeat(2,var(--dtl-stat-h));
|
|
53702
53721
|
gap:var(--dtl-space-3);}
|
|
53703
|
-
.dtl-stats__cards > .dtl-stat{height:100%;box-sizing:border-box;}
|
|
53704
53722
|
@media (max-width:960px){.dtl-stats{grid-template-columns:minmax(0,1fr);}}
|
|
53705
|
-
@media (max-width:640px){.dtl-stats__cards{grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:repeat(4,
|
|
53723
|
+
@media (max-width:640px){.dtl-stats__cards{grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:repeat(4,var(--dtl-stat-h));}}
|
|
53724
|
+
|
|
53725
|
+
/* ── 历史页顶部:图表卡在左、4 块数显在右(今天 / 本周 / 本月 / 本季度)──────
|
|
53726
|
+
2 列 × 2 行,块高 = --dtl-stat-h(与待办页统计卡同高,总高不变);
|
|
53727
|
+
块宽 = 高 × 1.92(用户 2026-10-30 两次加宽),样式直接吃待办页那套 .dtl-stat,不另写皮肤。 */
|
|
53728
|
+
.dtl-stats--history{grid-template-columns:minmax(0,1fr) auto;}
|
|
53729
|
+
.dtl-stats--history .dtl-stats__cards{grid-auto-flow:row;
|
|
53730
|
+
grid-template-columns:repeat(2,calc(var(--dtl-stat-h) * 1.92));
|
|
53731
|
+
grid-template-rows:repeat(2,var(--dtl-stat-h));}
|
|
53732
|
+
@media (max-width:960px){.dtl-stats--history{grid-template-columns:minmax(0,1fr);}}
|
|
53733
|
+
|
|
53734
|
+
/* 历史日柱:柱间距 2px、悬停虚线框 + 浮卡。
|
|
53735
|
+
翻页按钮**飘**在图区右上角(绝对定位,不单独占一行)——压在柱子上也无妨(用户 2026-10-29)。 */
|
|
53736
|
+
/* z-index:1 同趋势图:浮卡要被下方那排 input / select 压着还是压过去,全靠这层 */
|
|
53737
|
+
.dtl-hist{position:relative;z-index:1;height:100%;box-sizing:border-box;display:flex;flex-direction:column;gap:var(--dtl-space-2);
|
|
53738
|
+
/* 单列(≤960)时 height:100% 解析成 auto,光靠 flex 撑不出高度 ⇒ 用右侧两行卡的总高兜底,
|
|
53739
|
+
两栏并排时这个值恰好等于 stretch 给的高度,等于没改 */
|
|
53740
|
+
min-height:calc(var(--dtl-stat-h) * 2 + var(--dtl-space-3));
|
|
53741
|
+
/* 上边共多留 25px(用户 2026-10-30:10 + 10 + 5):border-box + 卡高不变 ⇒
|
|
53742
|
+
压的是图区,外框高度一点没变 */
|
|
53743
|
+
padding:calc(var(--dtl-space-3) + 25px) var(--dtl-space-4) var(--dtl-space-3);}
|
|
53744
|
+
.dtl-hist__nav{position:absolute;top:var(--dtl-space-2);right:var(--dtl-space-3);z-index:2;
|
|
53745
|
+
display:flex;gap:var(--dtl-space-2);}
|
|
53746
|
+
/* 翻页箭头 = 「有底、无边框」款(用户 2026-10-30):核心 IconButton 没有「实心无描边」这一档
|
|
53747
|
+
(plain 无底 / outline 有底带边)⇒ 这里给它换底、把描边抹平。底取 --dtl-btn-soft(不透明,
|
|
53748
|
+
压得住下面的刻度线)。hover 仍走核心那档灰底;disabled 的弱化改用 fg-dim 字色表达。 */
|
|
53749
|
+
.dtl-hist__nav .dshpc-iconbtn{background:var(--dtl-btn-soft);border-color:transparent;}
|
|
53750
|
+
.dtl-hist__nav .dshpc-iconbtn:disabled{opacity:1;color:var(--dtl-fg-dim);}
|
|
53751
|
+
.dtl-hist__plot{position:relative;flex:1 1 auto;min-height:0;}
|
|
53752
|
+
/* 刻度线四档:顶/底实线,中间两条虚线(用户 2026-10-29:中间要有两根刻度线) */
|
|
53753
|
+
.dtl-hist__grid{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:space-between;pointer-events:none;}
|
|
53754
|
+
.dtl-hist__gridline{border-top:1px solid var(--dtl-border);}
|
|
53755
|
+
.dtl-hist__gridline--dashed{border-top-style:dashed;}
|
|
53756
|
+
.dtl-hist__gridline--base{border-top-color:var(--dtl-border-strong);}
|
|
53757
|
+
/* 顶部那条不画(它正好从右上角那排控件后面穿过)⇒ 留一个等距占位,让下面的线仍落在
|
|
53758
|
+
¾ / ½ / ¼ / 0 四档刻度上,与 y 轴五个数字一一对应 */
|
|
53759
|
+
.dtl-hist__gridline--none{border-top:none;}
|
|
53760
|
+
.dtl-hist__cols{position:absolute;inset:0;display:flex;justify-content:flex-start;gap:2px;}
|
|
53761
|
+
.dtl-hist__col{position:relative;flex:none;display:flex;flex-direction:column;justify-content:flex-end;
|
|
53762
|
+
transition:filter var(--dtl-dur-fast) var(--dtl-ease);}
|
|
53763
|
+
.dtl-hist__col:hover{filter:brightness(1.1);}
|
|
53764
|
+
.dtl-hist__col:hover::after{content:"";position:absolute;inset:0;border:1px dashed var(--dtl-fg-3);
|
|
53765
|
+
border-radius:var(--dtl-radius-xs);pointer-events:none;}
|
|
53766
|
+
/* 柱体:顶端两角 2px 圆角(底端贴基线保持直角);overflow 把内部分段的方角裁成圆角
|
|
53767
|
+
(与首页趋势图的柱子**同一套**:父级圆角 + overflow 裁切 + ::after 斜纹,见 .dtl-chart-stripe) */
|
|
53768
|
+
.dtl-hist__bar{position:relative;width:100%;display:flex;flex-direction:column-reverse;
|
|
53769
|
+
border-radius:2px 2px 0 0;overflow:hidden;
|
|
53770
|
+
/* 入场:柱子从基线逐列升起来(只动 transform,不碰高度 ⇒ 不动布局、不影响 hover 命中)。
|
|
53771
|
+
延迟取列上内联的 --lc-d:**整屏错峰总时长固定 120ms**,由 JS 按「第几列 / 共几列」算好
|
|
53772
|
+
(原来按列序号 ×24ms 累加、还封了 20,宽屏上就变成「前 20 根慢慢来、后面一批同时冒」,
|
|
53773
|
+
看着像分批出现 —— 用户 2026-10-30 抓到的问题)。
|
|
53774
|
+
backwards 必须:延迟期间先停在起始帧,否则会先满怀高度再闪回 0。 */
|
|
53775
|
+
transform-origin:bottom;
|
|
53776
|
+
animation:dtl-bar-in .3s var(--dtl-ease) backwards;
|
|
53777
|
+
animation-delay:var(--lc-d,0ms);}
|
|
53778
|
+
@keyframes dtl-bar-in{from{transform:scaleY(0);}to{transform:scaleY(1);}}
|
|
53779
|
+
@media (prefers-reduced-motion: reduce){.dtl-hist__bar{animation:none;}}
|
|
53780
|
+
/* 浮卡:日期 → 新建任务 → 结案任务(总计)→ 虚线 → 明细(一工作区一行),0 值不列。
|
|
53781
|
+
恒在柱子**下方**:上方会被图表顶边挤出屏幕、hover 判定又带来闪跳(用户 2026-10-29 都放下面);
|
|
53782
|
+
top 让出 6px 间隙 + 12px 的 x 轴日期行,不压刻度。
|
|
53783
|
+
底色取 --dtl-tip-bg(掺一档前景色的浅灰):纯卡底色在浅色主题下跟白底糊住、边界看不清
|
|
53784
|
+
(用户 2026-10-30 试过官方 Tooltip 又退回自绘,就是为了这个底色)。 */
|
|
53785
|
+
.dtl-hist__tip{position:absolute;left:50%;top:calc(100% + 18px);z-index:3;transform:translateX(-50%);
|
|
53786
|
+
padding:var(--dtl-space-2);border:1px solid var(--dtl-tip-border);border-radius:var(--dtl-radius-sm);
|
|
53787
|
+
background:var(--dtl-tip-bg);white-space:nowrap;font-size:var(--dtl-font-xs);line-height:1.5;
|
|
53788
|
+
color:var(--dtl-tip-fg);opacity:0;pointer-events:none;transition:opacity var(--dtl-dur-fast) var(--dtl-ease);}
|
|
53789
|
+
.dtl-hist__col:hover .dtl-hist__tip{opacity:1;}
|
|
53790
|
+
.dtl-hist__tip-date{color:var(--dtl-tip-fg-dim);font-variant-numeric:tabular-nums;}
|
|
53791
|
+
.dtl-hist__tip-row{display:flex;align-items:center;gap:var(--dtl-space-1);
|
|
53792
|
+
font-variant-numeric:tabular-nums;}
|
|
53793
|
+
/* 总计行(结案任务):加粗,它是明细之和,不属于任何一个工作区颜色 */
|
|
53794
|
+
.dtl-hist__tip-total{display:flex;align-items:center;gap:var(--dtl-space-1);
|
|
53795
|
+
font-weight:600;font-variant-numeric:tabular-nums;}
|
|
53796
|
+
/* 总计与明细之间的分隔虚线(用户 2026-10-30) */
|
|
53797
|
+
.dtl-hist__tip-sep{border-top:1px dashed var(--dtl-tip-border);margin:var(--dtl-space-1) 0;
|
|
53798
|
+
height:0;}
|
|
53799
|
+
.dtl-hist__tip-dot{display:inline-block;width:8px;height:8px;flex:none;}
|
|
53800
|
+
/* 总计行的图例块:8×8 方块里几条**横向**色带上下等分(与柱子的分段同向) */
|
|
53801
|
+
.dtl-hist__tip-dot--split{display:inline-flex;flex-direction:column;overflow:hidden;}
|
|
53802
|
+
.dtl-hist__tip-dot--split > span{flex:1 1 0;min-height:0;}
|
|
53803
|
+
.dtl-hist__tip-count{margin-left:auto;padding-left:var(--dtl-space-3);color:var(--dtl-tip-fg);}
|
|
53804
|
+
/* x 轴日期行:高度定死 10px(文字绝对定位,不吃行高),首末钳制靠内联 left / right */
|
|
53805
|
+
.dtl-hist__labels{display:flex;gap:2px;margin-top:2px;flex:none;height:10px;}
|
|
53806
|
+
/* 新增量曲线:铺满 plot 的 SVG,0-100 百分比坐标(preserveAspectRatio:none 拉伸),
|
|
53807
|
+
non-scaling-stroke 保证线宽不随拉伸变形;只描边不填充,色与趋势图「新增」同源 */
|
|
53808
|
+
.dtl-hist__line{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;}
|
|
53809
|
+
.dtl-hist__line polyline{fill:none;stroke:var(--dtl-chart-added);stroke-width:1.5;
|
|
53810
|
+
vector-effect:non-scaling-stroke;stroke-linejoin:round;stroke-linecap:round;}
|
|
53811
|
+
.dtl-hist__label{position:relative;flex:none;font-size:10px;line-height:1;color:var(--dtl-fg-3);
|
|
53812
|
+
font-variant-numeric:tabular-nums;}
|
|
53813
|
+
/* 日期文字以列中心为锚点向两侧展开(用户 2026-10-30:不从卡片最左 / 最右起排);
|
|
53814
|
+
首列 / 末列由内联 left / right 钳回边界内 */
|
|
53815
|
+
.dtl-hist__label > span{position:absolute;top:0;left:50%;transform:translateX(-50%);white-space:nowrap;}
|
|
53706
53816
|
|
|
53707
|
-
/* ──
|
|
53817
|
+
/* ── 趋势图(首页右上卡:每周两根柱 + 新增曲线;2026-10-30 改版,画法对齐历史页)──────
|
|
53708
53818
|
柱高是百分比 ⇒ 祖先链必须有**确定高度**(卡 height:100% → body flex:1 → plot 绝对铺满);
|
|
53709
53819
|
2026-10-17 真机教训:百分比高度没有确定父高时整列柱消失,只剩数字。 */
|
|
53710
|
-
|
|
53711
|
-
|
|
53820
|
+
/* position:relative 是给右上角那对「飘」着的翻页箭头当定位上下文(浮卡已改官方 Tooltip 的
|
|
53821
|
+
传送门,不再需要 z-index)。
|
|
53822
|
+
上下留白不对称(用户 2026-10-30:图例离顶太远、离图太近)⇒ 顶 10 / 图例与图之间 12。 */
|
|
53823
|
+
/* position:relative 既给右上角那对「飘」着的翻页箭头当定位上下文,也配合 z-index:1 —— 浮卡是
|
|
53824
|
+
卡里的绝对定位子元素,不把整张卡抬成一层压过页面下方那排 input / select,就会被它们挡住
|
|
53825
|
+
(用户 2026-10-30 连报两次,别删这个 z-index)。 */
|
|
53826
|
+
.dtl-trend{position:relative;z-index:1;height:100%;box-sizing:border-box;display:flex;
|
|
53827
|
+
flex-direction:column;gap:var(--dtl-space-3);
|
|
53828
|
+
padding:10px var(--dtl-space-4) var(--dtl-space-4);}
|
|
53712
53829
|
.dtl-trend__legend{display:flex;align-items:center;flex-wrap:wrap;gap:var(--dtl-space-3);
|
|
53713
53830
|
font-size:var(--dtl-font-xs);color:var(--dtl-fg-3);}
|
|
53714
|
-
|
|
53831
|
+
/* 图例色块:直角方块,与柱子同一造型(用户 2026-10-29:不要圆角) */
|
|
53832
|
+
.dtl-trend__dot{display:inline-block;width:8px;height:8px;margin-right:4px;border-radius:0;
|
|
53715
53833
|
vertical-align:middle;}
|
|
53716
|
-
|
|
53717
|
-
|
|
53718
|
-
.dtl-trend__dot--
|
|
53719
|
-
|
|
53720
|
-
|
|
53834
|
+
/* 上下两半的色块(用户 2026-10-30):上半 = 柱子里叠在上面那一段 ——
|
|
53835
|
+
已结案(取消红在上 / 完成蓝在下)、未结(进行中绿在上 / 待认领琥珀在下)。 */
|
|
53836
|
+
.dtl-trend__dot--split{display:inline-flex;flex-direction:column;overflow:hidden;}
|
|
53837
|
+
.dtl-trend__dot--split > span{flex:1 1 0;min-height:0;}
|
|
53838
|
+
/* 「只看我的」:跟在图例后面(右侧那角留给翻页箭头,用户 2026-10-30) */
|
|
53839
|
+
.dtl-trend__mine{display:inline-flex;align-items:center;gap:4px;cursor:pointer;
|
|
53721
53840
|
font-size:var(--dtl-font-xs);color:var(--dtl-fg-3);}
|
|
53722
53841
|
.dtl-trend__mine input{margin:0;accent-color:var(--dtl-business);}
|
|
53842
|
+
/* 翻页箭头:**飘**在卡片右上角(绝对定位,不跟图例挤一排 —— 放一排会把整排文字行撑高,
|
|
53843
|
+
用户 2026-10-30);底取 --dtl-btn-soft(不透明,压得住下面的刻度线),与历史页同款 */
|
|
53844
|
+
.dtl-trend__nav{position:absolute;top:var(--dtl-space-2);right:var(--dtl-space-3);z-index:2;
|
|
53845
|
+
display:flex;gap:var(--dtl-space-1);}
|
|
53846
|
+
.dtl-trend__nav .dshpc-iconbtn{background:var(--dtl-btn-soft);border-color:transparent;}
|
|
53723
53847
|
.dtl-trend__body{flex:1 1 auto;min-height:0;display:flex;gap:var(--dtl-space-2);}
|
|
53724
53848
|
.dtl-trend__axis{display:flex;flex-direction:column;justify-content:space-between;flex:none;
|
|
53725
|
-
padding-bottom:
|
|
53849
|
+
padding-bottom:12px;font-size:10px;line-height:1;text-align:right;font-variant-numeric:tabular-nums;
|
|
53726
53850
|
color:var(--dtl-fg-3);}
|
|
53727
53851
|
.dtl-trend__plot{position:relative;flex:1 1 auto;min-width:0;}
|
|
53728
|
-
/*
|
|
53729
|
-
|
|
53730
|
-
|
|
53852
|
+
/* 刻度线五档:顶部不画(正好从右上角控件后面穿过)、中间三档(¾ / ½ / ¼)**全虚线**、
|
|
53853
|
+
底部基线实线(用户 2026-10-30:中间的线都用虚线,不要实线) */
|
|
53854
|
+
.dtl-trend__grid{position:absolute;inset:0;display:flex;flex-direction:column;
|
|
53855
|
+
justify-content:space-between;pointer-events:none;}
|
|
53731
53856
|
.dtl-trend__gridline{border-top:1px solid var(--dtl-border);}
|
|
53857
|
+
.dtl-trend__gridline--dashed{border-top-style:dashed;}
|
|
53858
|
+
.dtl-trend__gridline--none{border-top:none;}
|
|
53732
53859
|
.dtl-trend__gridline--base{border-top-color:var(--dtl-border-strong);}
|
|
53733
|
-
.
|
|
53734
|
-
|
|
53735
|
-
.dtl-trend__col{position:relative;flex:
|
|
53736
|
-
justify-content:flex-end;padding-bottom:14px;}
|
|
53737
|
-
.dtl-trend__bars{display:flex;align-items:flex-end;justify-content:center;gap:1px;flex:1 1 auto;min-height:0;}
|
|
53738
|
-
/* 柱宽 5px、无圆角(用户 2026-10-17:「太粗、不要圆弧」);非零柱给 2px 下限 */
|
|
53739
|
-
.dtl-trend__bar{position:relative;width:5px;flex:none;min-height:2px;
|
|
53860
|
+
/* 柱序居左、组宽固定(组宽 / 组间距由 trend-chart.ts 内联给,这里只管排布) */
|
|
53861
|
+
.dtl-trend__cols{position:absolute;inset:0;display:flex;justify-content:flex-start;}
|
|
53862
|
+
.dtl-trend__col{position:relative;flex:none;display:flex;flex-direction:column;justify-content:flex-end;
|
|
53740
53863
|
transition:filter var(--dtl-dur-fast) var(--dtl-ease);}
|
|
53741
|
-
|
|
53742
|
-
|
|
53743
|
-
.dtl-
|
|
53744
|
-
|
|
53745
|
-
|
|
53746
|
-
.
|
|
53747
|
-
|
|
53748
|
-
|
|
53749
|
-
|
|
53750
|
-
|
|
53751
|
-
|
|
53752
|
-
|
|
53753
|
-
|
|
53754
|
-
|
|
53755
|
-
|
|
53756
|
-
|
|
53864
|
+
.dtl-trend__col:hover{filter:brightness(1.1);}
|
|
53865
|
+
/* hover:整组(两根柱)一个虚线框,不是一根一个(用户 2026-10-30) */
|
|
53866
|
+
.dtl-trend__col:hover::after{content:"";position:absolute;inset:0;border:1px dashed var(--dtl-fg-3);
|
|
53867
|
+
border-radius:var(--dtl-radius-xs);pointer-events:none;}
|
|
53868
|
+
.dtl-trend__bars{display:flex;align-items:flex-end;justify-content:flex-start;flex:1 1 auto;min-height:0;}
|
|
53869
|
+
/* 柱宽**固定** 11.25px(= trend-chart.ts 的 BAR_W,组宽 / 一屏几周都按它算,改一处两边一起改):
|
|
53870
|
+
某周没有未结时只剩一根柱,**不许被拉宽**(用户 2026-10-30)。柱顶 2px 圆角、非零柱 2px 下限。
|
|
53871
|
+
入场动画沿用历史页那套 transform(只动 transform,不碰高度 ⇒ 不动布局) */
|
|
53872
|
+
.dtl-trend__bar{position:relative;flex:none;width:11.25px;min-height:2px;
|
|
53873
|
+
border-radius:2px 2px 0 0;overflow:hidden;
|
|
53874
|
+
transform-origin:bottom;animation:dtl-bar-in .3s var(--dtl-ease) backwards;
|
|
53875
|
+
animation-delay:var(--lc-d,0ms);}
|
|
53876
|
+
@media (prefers-reduced-motion: reduce){.dtl-trend__bar{animation:none;}}
|
|
53877
|
+
/* 结案柱 = 完成 business 蓝(用户 2026-10-30:绿的不好看);未结柱底 = 待认领琥珀 */
|
|
53878
|
+
.dtl-trend__bar--closed{background-color:var(--dtl-chart-done);}
|
|
53879
|
+
.dtl-trend__bar--open{background-color:var(--dtl-chart-open);}
|
|
53880
|
+
/* 叠在柱顶端的那一段(用户 2026-10-30):结案柱顶 = 取消红、未结柱顶 = 进行中绿;圆角交给父级裁 */
|
|
53881
|
+
.dtl-trend__seg{position:absolute;left:0;right:0;top:0;}
|
|
53882
|
+
.dtl-trend__seg--cancelled{background-color:var(--dtl-danger);}
|
|
53883
|
+
.dtl-trend__seg--doing{background-color:var(--dtl-chart-doing);}
|
|
53884
|
+
/* 柱面斜纹:**两个图表共用这一条**(历史页 .dtl-hist__bar / 首页 .dtl-trend__bar)——
|
|
53885
|
+
一根柱铺一层 45° 覆盖层(伪元素画在最上面),不碰任何分段的底色,也不依赖谁先谁后;
|
|
53886
|
+
父级圆角 + overflow 裁切把覆盖层一起裁成圆角(用户 2026-10-30:同一个东西只留一种实现)。
|
|
53887
|
+
斜条 2px、条间(柱色本体)4px、透明度见 --dtl-chart-stripe */
|
|
53888
|
+
.dtl-hist__bar::after,.dtl-trend__bar::after{content:"";position:absolute;inset:0;
|
|
53889
|
+
pointer-events:none;background-image:repeating-linear-gradient(45deg,
|
|
53890
|
+
var(--dtl-chart-stripe) 0 2px,transparent 2px 6px);}
|
|
53891
|
+
/* x 轴日期行:高度定死 10px(文字绝对定位,不吃行高),首末钳制靠内联 left / right */
|
|
53892
|
+
.dtl-trend__labels{display:flex;margin-top:2px;flex:none;height:10px;}
|
|
53893
|
+
.dtl-trend__label{position:relative;flex:none;font-size:10px;line-height:1;color:var(--dtl-fg-3);
|
|
53894
|
+
font-variant-numeric:tabular-nums;}
|
|
53895
|
+
.dtl-trend__label > span{position:absolute;top:0;left:50%;transform:translateX(-50%);white-space:nowrap;}
|
|
53896
|
+
/* 新增量曲线:铺满 plot 的 SVG,0-100 百分比坐标(preserveAspectRatio:none 拉伸),
|
|
53897
|
+
non-scaling-stroke 保证线宽不随拉伸变形。
|
|
53898
|
+
z-index 2 ⇒ **压在柱子上面**(用户 2026-10-30),浮卡再高一层;线色走中性灰
|
|
53899
|
+
(柱子已经是蓝的,曲线再用蓝就分不清了) */
|
|
53900
|
+
.dtl-trend__line{position:absolute;inset:0;z-index:2;width:100%;height:100%;pointer-events:none;}
|
|
53901
|
+
.dtl-trend__line polyline{fill:none;stroke:var(--dtl-chart-line);stroke-width:1.5;
|
|
53902
|
+
vector-effect:non-scaling-stroke;stroke-linejoin:round;stroke-linecap:round;}
|
|
53903
|
+
/* hover 浮卡:恒在柱子**下方**(上方会被卡片顶边挤出屏幕);深灰底 + 浅字同历史页 */
|
|
53904
|
+
.dtl-trend__tip{position:absolute;left:50%;top:calc(100% + 18px);z-index:3;transform:translateX(-50%);
|
|
53905
|
+
padding:var(--dtl-space-2);border:1px solid var(--dtl-tip-border);border-radius:var(--dtl-radius-sm);
|
|
53906
|
+
background:var(--dtl-tip-bg);white-space:nowrap;
|
|
53907
|
+
font-size:var(--dtl-font-xs);line-height:1.5;color:var(--dtl-tip-fg);
|
|
53757
53908
|
opacity:0;pointer-events:none;transition:opacity var(--dtl-dur-fast) var(--dtl-ease);}
|
|
53758
53909
|
.dtl-trend__col:hover .dtl-trend__tip{opacity:1;}
|
|
53759
53910
|
.dtl-trend__tip-row{font-variant-numeric:tabular-nums;}
|
|
53760
53911
|
/* 未结的拆分行:缩进 + 淡一档,读起来是「未结」的注脚 */
|
|
53761
|
-
.dtl-trend__tip-row--sub{padding-left:10px;color:var(--dtl-fg-
|
|
53912
|
+
.dtl-trend__tip-row--sub{padding-left:10px;color:var(--dtl-tip-fg-dim);}
|
|
53762
53913
|
.dtl-trend__foot{font-size:var(--dtl-font-xs);color:var(--dtl-fg-3);}
|
|
53763
53914
|
|
|
53915
|
+
/* 页面滚动到底的留白:实体块跟着内容走(滚到最底时最后一条卡不贴浏览器底边) */
|
|
53916
|
+
.dtl-page-foot{height:24px;flex:none;}
|
|
53917
|
+
|
|
53918
|
+
/* 按工作区分组(用户 2026-10-30):组头是核心 SectionHead(自带 12px 下边距),
|
|
53919
|
+
这里只补组与组之间的留白 —— 首个组不再多一层 */
|
|
53920
|
+
.dtl-group + .dtl-group{margin-top:var(--dtl-space-4);}
|
|
53921
|
+
/* 组头左侧的细竖线(替代图标)+ 组名后的分档条数(0 的档由 JS 直接不渲染,不占位) */
|
|
53922
|
+
.dtl-group__rule{width:3px;height:14px;flex:none;background:var(--dtl-fg-3);
|
|
53923
|
+
border-radius:var(--dtl-radius-xs);}
|
|
53924
|
+
.dtl-group__count{margin-left:var(--dtl-space-2);font-size:var(--dtl-font-xs);font-weight:400;
|
|
53925
|
+
color:var(--dtl-fg-3);white-space:nowrap;}
|
|
53926
|
+
/* 组头整体右移 4px(与任务卡左缘留一点视觉差,用户 2026-10-30) */
|
|
53927
|
+
.dtl-group__head{padding-left:var(--dtl-space-1);}
|
|
53928
|
+
|
|
53764
53929
|
/* 任务行 = 一张卡(样式照抄 dispatch-table TaskCard:surface-1 底 + 1px 边框 + 左缘状态条;
|
|
53765
53930
|
hover 只亮主行;右侧 时间⇄按钮排 互换) */
|
|
53766
53931
|
.dtl-taskrow{background:var(--dtl-surface-1);border:1px solid var(--dtl-border);
|
|
@@ -53782,12 +53947,12 @@ body[data-ds-dark-theme]{
|
|
|
53782
53947
|
.dtl-taskrow__title{font-size:var(--dtl-font-lg);font-weight:600;line-height:var(--dtl-line-md);min-width:0;flex:0 1 auto;}
|
|
53783
53948
|
.dtl-taskrow__stamp{flex:none;font-size:var(--dtl-font-xs);color:var(--dtl-fg-3);white-space:nowrap;
|
|
53784
53949
|
font-variant-numeric:tabular-nums;}
|
|
53785
|
-
/*
|
|
53950
|
+
/* 第二行小字:状态标签 · 异常标签 · #标签(行距拉开,用户 2026-10-17:第一二行别贴着) */
|
|
53786
53951
|
.dtl-taskrow__l2{display:flex;align-items:center;gap:var(--dtl-space-2);margin-top:6px;
|
|
53787
53952
|
font-size:var(--dtl-font-sm);color:var(--dtl-fg-2);min-width:0;}
|
|
53788
|
-
/* 右侧(用户 2026-10-28
|
|
53789
|
-
hover
|
|
53790
|
-
|
|
53953
|
+
/* 右侧(用户 2026-10-28):执行人名(常驻)/ 时间(hover 让位)/ 动作钮。
|
|
53954
|
+
hover 只收时间那一截,人名不动 —— 按钮出现时两者保持同一个 gap。
|
|
53955
|
+
人名走核心 Button 的 link 档(品牌蓝),这里不再有它的样式。 */
|
|
53791
53956
|
.dtl-taskrow__meta{flex:none;overflow:hidden;text-overflow:ellipsis;
|
|
53792
53957
|
font-size:var(--dtl-font-xs);color:var(--dtl-fg-3);white-space:nowrap;
|
|
53793
53958
|
font-variant-numeric:tabular-nums;}
|
|
@@ -53841,13 +54006,14 @@ body[data-ds-dark-theme]{
|
|
|
53841
54006
|
value: props.value,
|
|
53842
54007
|
onChange: props.onChange,
|
|
53843
54008
|
size: props.size,
|
|
54009
|
+
bordered: props.bordered === true,
|
|
53844
54010
|
tone: props.tone,
|
|
53845
54011
|
label: props.label,
|
|
53846
54012
|
id: props.id,
|
|
53847
54013
|
style: props.style
|
|
53848
54014
|
});
|
|
53849
54015
|
}
|
|
53850
|
-
/** 按钮:改由核心 `Button` 承担(
|
|
54016
|
+
/** 按钮:改由核心 `Button` 承担(18 档 variant 里本地用 primary/secondary/outline/ghost/link)。
|
|
53851
54017
|
* `loading` = 核心自带的前置小圈 + 自动禁用(转圈动画只此一份,不自绘)。
|
|
53852
54018
|
* 宽度三件(width/minWidth/maxWidth)核心已支持:给 maxWidth + 纯文字 ⇒ 核心自动省略号 +
|
|
53853
54019
|
* hover 跑马灯,本层原样透传,别再自己写截断。 */
|
|
@@ -53895,16 +54061,8 @@ body[data-ds-dark-theme]{
|
|
|
53895
54061
|
children: (0, react$1.createElement)("span", { className: "dtl-tip" }, props.children)
|
|
53896
54062
|
});
|
|
53897
54063
|
}
|
|
53898
|
-
/**
|
|
53899
|
-
|
|
53900
|
-
* (用户 2026-10-28:就地摆进面板内容区不好看,就用全局那个默认位置)。
|
|
53901
|
-
*
|
|
53902
|
-
* ⚠️ 它**不会自动消失**:谁开的谁 `close()`(句柄可重复关,第二次是空操作);
|
|
53903
|
-
* 同屏只有一张卡,后一次调用顶掉前一次 ⇒ 打开面板 / 首读这种场合直接开、数据到了就关。
|
|
53904
|
-
*/
|
|
53905
|
-
function showLoading(text) {
|
|
53906
|
-
return showLoading$1({ text });
|
|
53907
|
-
}
|
|
54064
|
+
/** 加载图标:核心 `Loader` 原样透出(无背景、无定位;形态 `ring` / `blocks`、尺寸 xs~xl 都走核心档位)。 */
|
|
54065
|
+
const Loader = Loader$2;
|
|
53908
54066
|
/** 下拉:改由核心 `Picker`(单选、受控、portal 菜单)承担。
|
|
53909
54067
|
* 宽度由核心 `Picker` 原生支持(`width`/`minWidth`/`maxWidth` 落到位触发器内联样式,
|
|
53910
54068
|
* 超长省略号 + hover 跑马灯);给了 `width` 即锁定定宽,否则在 min/max 间自适应。 */
|
|
@@ -53948,23 +54106,22 @@ body[data-ds-dark-theme]{
|
|
|
53948
54106
|
function StatCard(props) {
|
|
53949
54107
|
ensureUiBase();
|
|
53950
54108
|
const interactive = props.interactive !== false && props.onClick !== void 0;
|
|
53951
|
-
const shown = props.value === 0 || props.value === "0" ? "—" :
|
|
54109
|
+
const shown = (props.value === 0 || props.value === "0") && props.showZero !== true ? "—" : props.value;
|
|
53952
54110
|
return (0, react$1.createElement)(interactive ? "button" : "div", {
|
|
53953
54111
|
type: interactive ? "button" : void 0,
|
|
53954
54112
|
className: `dtl-card dtl-stat${interactive ? " dtl-card--clickable" : ""}`,
|
|
53955
54113
|
"data-active": props.active === true,
|
|
53956
54114
|
title: props.title,
|
|
53957
54115
|
onClick: interactive ? props.onClick : void 0
|
|
53958
|
-
}, (0, react$1.createElement)("span", {
|
|
53959
|
-
fontSize: "var(--dtl-font-sm)",
|
|
53960
|
-
color: "var(--dtl-fg-2)"
|
|
53961
|
-
} }, props.label), (0, react$1.createElement)("span", { className: "dtl-stat__value" }, shown), props.hint === void 0 || props.hint === null || props.hint === "" ? null : (0, react$1.createElement)("span", { className: "dtl-stat__hint" }, props.hint));
|
|
54116
|
+
}, (0, react$1.createElement)("span", { className: "dtl-stat__label" }, props.label), (0, react$1.createElement)("span", { className: "dtl-stat__value" }, shown), props.hint === void 0 || props.hint === null || props.hint === "" ? null : (0, react$1.createElement)("span", { className: "dtl-stat__hint" }, props.hint));
|
|
53962
54117
|
}
|
|
53963
|
-
/** 本地 7 档语义色 → 核心 `Chip`
|
|
53964
|
-
* overdue 与 stale 都落到 danger、doing 与 person 落到 business(需 core 补 tone 才能精确)。
|
|
54118
|
+
/** 本地 7 档语义色 → 核心 `Chip` 档。core 缺 doing / backlog / overdue / stale / person 的独立色:
|
|
54119
|
+
* overdue 与 stale 都落到 danger、doing 与 person 落到 business(需 core 补 tone 才能精确)。
|
|
54120
|
+
* 待认领用 `slate`(实心灰)而不是 `neutral`:neutral 那层浅灰跟 #标签 长得一模一样,
|
|
54121
|
+
* 状态标签要跟任务行左缘那条灰竖线一个色(用户 2026-10-30)。 */
|
|
53965
54122
|
const CHIP_TONE = {
|
|
53966
54123
|
neutral: "neutral",
|
|
53967
|
-
open: "
|
|
54124
|
+
open: "slate",
|
|
53968
54125
|
backlog: "warning",
|
|
53969
54126
|
doing: "success",
|
|
53970
54127
|
overdue: "danger",
|
|
@@ -54029,16 +54186,399 @@ body[data-ds-dark-theme]{
|
|
|
54029
54186
|
}));
|
|
54030
54187
|
}
|
|
54031
54188
|
//#endregion
|
|
54189
|
+
//#region src/client/history-chart.ts
|
|
54190
|
+
/**
|
|
54191
|
+
* 历史页顶部:**图表卡在左、4 数显在右**,沿用主页 8 块的分栏与单块尺寸;不显示图例。
|
|
54192
|
+
*
|
|
54193
|
+
* 柱:一根 = 一个周期(日 / 周 / 月,右上角切换,默认日),高度 = 该周期的结案数。
|
|
54194
|
+
* 数字真源是 skill `stats --trend <gran>`(切粒度 = 重新请求,host 有读缓存),
|
|
54195
|
+
* 本文件**只做展示**:切片、配色、画图 —— 聚合与求和都在 host / skill(用户 2026-10-30 定)。
|
|
54196
|
+
* 柱色:≥2 工作区 = 叠加分段、每区一色;仅 1 个工作区 = 完成(绿) / 取消(红) 两段。
|
|
54197
|
+
* 曲线:**新增任务量**(一条线、不分工作区),每个周期一个点,跟柱对齐。
|
|
54198
|
+
* 布局:柱序居左、柱宽固定、柱间 2px;按容器宽算能放几个周期(屏幕越窄越少),右边留白。
|
|
54199
|
+
* 翻页:步长随粒度(用户 2026-10-29 定)——日 10 天 / 周 4 周 / 月 3 月。
|
|
54200
|
+
*/
|
|
54201
|
+
/** 工作区配色:色相环按黄金角 137.5° 取 24 档,相邻色差最大、互相不重复
|
|
54202
|
+
* (用户 2026-10-30:内置二三十个够用,按工作区顺序依次分配;中亮度中饱和,明暗底都成立)。 */
|
|
54203
|
+
const colorAt = (index) => `hsl(${String(Math.round(index * 137.5 % 360))}deg 62% 52%)`;
|
|
54204
|
+
/** 单周期槽宽:柱宽 = 槽宽。2026-10-29 用户要求加粗到 1.5 倍(10 → 15)。 */
|
|
54205
|
+
const SLOT_W = 15;
|
|
54206
|
+
/** 入场动画的**整屏**错峰总时长:延迟按「第几列 / 共几列」摊到这段时间里,
|
|
54207
|
+
* 不跟列数累加 ⇒ 宽屏上也不会出现「前几根先出来、后一批等半天才凑一起」。 */
|
|
54208
|
+
const STAGGER_MS$1 = 120;
|
|
54209
|
+
/** x 轴标签的最小间距(小于这个就跳着显示,免得挤成一团)。月是 `2026-10` 七位,
|
|
54210
|
+
* 比 `10-30` 宽一截 ⇒ 单独放宽,跨度落到 4 个槽标一次(用户 2026-10-30 嫌月标签太密)。 */
|
|
54211
|
+
const LABEL_MIN_PITCH$1 = {
|
|
54212
|
+
day: 40,
|
|
54213
|
+
week: 40,
|
|
54214
|
+
month: 62
|
|
54215
|
+
};
|
|
54216
|
+
/** 翻页步长:按一次左右箭头走几个周期(用户 2026-10-29 定)。 */
|
|
54217
|
+
const GRAN_STEP = {
|
|
54218
|
+
day: 10,
|
|
54219
|
+
week: 4,
|
|
54220
|
+
month: 3
|
|
54221
|
+
};
|
|
54222
|
+
/** 各粒度的单位名(用于翻页提示「前 4 周」里的单位)。 */
|
|
54223
|
+
const GRAN_UNIT = {
|
|
54224
|
+
day: "historyGranDay",
|
|
54225
|
+
week: "historyGranWeek",
|
|
54226
|
+
month: "historyGranMonth"
|
|
54227
|
+
};
|
|
54228
|
+
const GRAN_VALUES = [
|
|
54229
|
+
"day",
|
|
54230
|
+
"week",
|
|
54231
|
+
"month"
|
|
54232
|
+
];
|
|
54233
|
+
/** y 轴刻度紧凑格式:≥1000 走 1.3K / 13K(用户 2026-10-30:左侧只留 3~4 位数字的宽度)。 */
|
|
54234
|
+
function compactTick(value) {
|
|
54235
|
+
return value < 1e3 ? String(value) : `${String(Math.round(value / 100) / 10)}K`;
|
|
54236
|
+
}
|
|
54237
|
+
function monthStart(value) {
|
|
54238
|
+
return `${value.slice(0, 7)}-01`;
|
|
54239
|
+
}
|
|
54240
|
+
function addMonths(value, delta) {
|
|
54241
|
+
const date = /* @__PURE__ */ new Date(`${monthStart(value)}T00:00:00`);
|
|
54242
|
+
date.setMonth(date.getMonth() + delta);
|
|
54243
|
+
return ymdOf(date);
|
|
54244
|
+
}
|
|
54245
|
+
/** 某天属于哪个周期(桶 key = 周期起始日,与 skill 口径一致)。 */
|
|
54246
|
+
function keyOf(gran, date) {
|
|
54247
|
+
return gran === "day" ? date : gran === "week" ? mondayOf(date) : monthStart(date);
|
|
54248
|
+
}
|
|
54249
|
+
/** 周期 key 前后挪几个周期。 */
|
|
54250
|
+
function shiftKey(gran, key, delta) {
|
|
54251
|
+
return gran === "day" ? addDays(key, delta) : gran === "week" ? addDays(key, delta * 7) : addMonths(key, delta);
|
|
54252
|
+
}
|
|
54253
|
+
/** 周期最后一天(浮卡的区间标题用)。 */
|
|
54254
|
+
function endOf(gran, key) {
|
|
54255
|
+
return gran === "day" ? key : gran === "week" ? addDays(key, 6) : addDays(addMonths(key, 1), -1);
|
|
54256
|
+
}
|
|
54257
|
+
/** 右侧 4 块(2 列 × 2 行):今日 / 本周 / 本月 / 本季度结案数,样式吃待办页统计卡。
|
|
54258
|
+
* 每块三行(用户 2026-10-30 定稿):
|
|
54259
|
+
* 今日结案
|
|
54260
|
+
* 28 取消 1 ← 大数字 = 本期总数;小字只补「取消 N」,没取消就不显示
|
|
54261
|
+
* 昨日丨完成 6 · 取消 1 ← 上一期,竖线分隔后写完整拆分(没取消就只写「完成 6」)
|
|
54262
|
+
* ⚠️ `showZero`:这几格是**计数**,0 必须照实显示(待办页那套默认把 0 显示成「—」)。 */
|
|
54263
|
+
function HistoryStats(props) {
|
|
54264
|
+
const { data, t } = props;
|
|
54265
|
+
const totals = data?.totals;
|
|
54266
|
+
const dash = "—";
|
|
54267
|
+
const totalOf = (period) => period === void 0 ? dash : compactTick(period.done + period.cancelled);
|
|
54268
|
+
/** 本期小字:只补取消数(总数已是大数字,不再重复写「完成」)。 */
|
|
54269
|
+
const cancelOf = (period) => period.cancelled > 0 ? `取消 ${compactTick(period.cancelled)}` : null;
|
|
54270
|
+
/** 上一期写法:`完成 X · 取消 Y`;没取消就只留 `完成 X`。 */
|
|
54271
|
+
const splitOf = (period) => period.cancelled > 0 ? `完成 ${compactTick(period.done)} · 取消 ${compactTick(period.cancelled)}` : `完成 ${compactTick(period.done)}`;
|
|
54272
|
+
const cell = (label, period, prevLabel, prev) => {
|
|
54273
|
+
const sub = period === void 0 ? null : cancelOf(period);
|
|
54274
|
+
return (0, react$1.createElement)(StatCard, {
|
|
54275
|
+
label: `${label}${t("chartDone")}`,
|
|
54276
|
+
value: (0, react$1.createElement)("span", { className: "dtl-stat__main" }, (0, react$1.createElement)("span", null, totalOf(period)), sub === null ? null : (0, react$1.createElement)("span", { className: "dtl-stat__sub" }, sub)),
|
|
54277
|
+
hint: prev === void 0 ? `${prevLabel}丨${dash}` : `${prevLabel}丨${splitOf(prev)}`,
|
|
54278
|
+
showZero: true
|
|
54279
|
+
});
|
|
54280
|
+
};
|
|
54281
|
+
return (0, react$1.createElement)("div", { className: "dtl-stats__cards" }, cell(t("historyToday"), totals?.today, t("historyYesterday"), totals?.yesterday), cell(t("historyWeek"), totals?.week, t("historyLastWeek"), totals?.lastWeek), cell(t("historyMonth"), totals?.month, t("historyLastMonth"), totals?.lastMonth), cell(t("historyQuarter"), totals?.quarter, t("historyLastQuarter"), totals?.lastQuarter));
|
|
54282
|
+
}
|
|
54283
|
+
/** 左侧图表卡:周期堆叠柱 + 新增量曲线 + y 轴 + 粒度切换 / 翻页(无图例)。
|
|
54284
|
+
* `data = null`(首读未到)⇒ 骨架卡:卡壳高度与有数据时一致,中间核心加载卡 ⇒ 页面不跳。 */
|
|
54285
|
+
function HistoryChart(props) {
|
|
54286
|
+
const { data, t, gran, onGranChange } = props;
|
|
54287
|
+
const [plotEl, setPlotEl] = (0, react$1.useState)(null);
|
|
54288
|
+
const [width, setWidth] = (0, react$1.useState)(0);
|
|
54289
|
+
/** 从最新周期往回翻了几次(每次走 GRAN_STEP 个周期)。 */
|
|
54290
|
+
const [shift, setShift] = (0, react$1.useState)(0);
|
|
54291
|
+
(0, react$1.useEffect)(() => {
|
|
54292
|
+
if (plotEl === null) return;
|
|
54293
|
+
const observer = new ResizeObserver((entries) => {
|
|
54294
|
+
const rect = entries[0];
|
|
54295
|
+
if (rect !== void 0) setWidth(rect.contentRect.width);
|
|
54296
|
+
});
|
|
54297
|
+
observer.observe(plotEl);
|
|
54298
|
+
setWidth(plotEl.clientWidth);
|
|
54299
|
+
return () => observer.disconnect();
|
|
54300
|
+
}, [plotEl]);
|
|
54301
|
+
const step = GRAN_STEP[gran];
|
|
54302
|
+
const unit = t(GRAN_UNIT[gran]);
|
|
54303
|
+
/** 翻页钮:**只画箭头** —— 核心 `IconButton` 出皮、`Icon*` 官方图标出图形,本文件不再手写
|
|
54304
|
+
* 按钮样式与箭头字形(用户 2026-10-29)。悬停提示走官方 Tooltip(本仓库 `Tip` 唯一入口);
|
|
54305
|
+
* 文案只当无障碍名 + 气泡,且用 `title: ""` 压掉原生 title(照 `task-row.ts` 的惯例)。 */
|
|
54306
|
+
const navButton = (dir, label, onClick) => (0, react$1.createElement)(Tip, {
|
|
54307
|
+
label,
|
|
54308
|
+
side: "bottom",
|
|
54309
|
+
children: (0, react$1.createElement)(IconButton, {
|
|
54310
|
+
icon: (0, react$1.createElement)(dir === "left" ? _deepseek_ai_dsh_client_ui_primitives.IconChevronLeftOutlineRegular : _deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, { size: 14 }),
|
|
54311
|
+
label,
|
|
54312
|
+
title: "",
|
|
54313
|
+
variant: "outline",
|
|
54314
|
+
size: "sm",
|
|
54315
|
+
onClick
|
|
54316
|
+
})
|
|
54317
|
+
});
|
|
54318
|
+
/** 右上角控件:翻页箭头在左、粒度滑动框居右(用户 2026-10-30)。
|
|
54319
|
+
* 加载 / 空态也一并渲染 —— 否则切粒度时这排控件会闪掉再回来。 */
|
|
54320
|
+
const nav = (0, react$1.createElement)("div", { className: "dtl-hist__nav" }, navButton("left", t("historyPrev", {
|
|
54321
|
+
n: step,
|
|
54322
|
+
unit
|
|
54323
|
+
}), () => {
|
|
54324
|
+
setShift((value) => value + 1);
|
|
54325
|
+
}), navButton("right", t("historyNext", {
|
|
54326
|
+
n: step,
|
|
54327
|
+
unit
|
|
54328
|
+
}), () => {
|
|
54329
|
+
setShift((value) => Math.max(0, value - 1));
|
|
54330
|
+
}), (0, react$1.createElement)(Segmented, {
|
|
54331
|
+
id: "dtl-hist-gran",
|
|
54332
|
+
value: gran,
|
|
54333
|
+
size: "sm",
|
|
54334
|
+
tone: "business",
|
|
54335
|
+
label: t("historyGranLabel"),
|
|
54336
|
+
items: GRAN_VALUES.map((value) => ({
|
|
54337
|
+
value,
|
|
54338
|
+
label: t(GRAN_UNIT[value])
|
|
54339
|
+
})),
|
|
54340
|
+
onChange: (next) => {
|
|
54341
|
+
setShift(0);
|
|
54342
|
+
onGranChange(next);
|
|
54343
|
+
}
|
|
54344
|
+
}));
|
|
54345
|
+
if (data === null) return (0, react$1.createElement)("div", { className: "dtl-card dtl-hist" }, nav, (0, react$1.createElement)("div", { style: {
|
|
54346
|
+
flex: "1 1 auto",
|
|
54347
|
+
minHeight: 0,
|
|
54348
|
+
display: "flex",
|
|
54349
|
+
alignItems: "center",
|
|
54350
|
+
justifyContent: "center"
|
|
54351
|
+
} }, (0, react$1.createElement)(Loader, {
|
|
54352
|
+
variant: "blocks",
|
|
54353
|
+
size: "xl"
|
|
54354
|
+
})));
|
|
54355
|
+
if (data.buckets.length === 0) return (0, react$1.createElement)("div", { className: "dtl-card dtl-hist" }, nav, (0, react$1.createElement)(EmptyState, { title: t("historyEmpty") }));
|
|
54356
|
+
const perScreen = width > 0 ? Math.max(1, Math.floor(width / 17)) : 30;
|
|
54357
|
+
const byKey = new Map(data.buckets.map((bucket) => [bucket.key, bucket]));
|
|
54358
|
+
const lastKey = keyOf(gran, ymdOf(/* @__PURE__ */ new Date()));
|
|
54359
|
+
const offset = shift * step;
|
|
54360
|
+
const buckets = [];
|
|
54361
|
+
for (let back = perScreen - 1; back >= 0; back -= 1) {
|
|
54362
|
+
const key = shiftKey(gran, lastKey, -(offset + back));
|
|
54363
|
+
buckets.push(byKey.get(key) ?? {
|
|
54364
|
+
key,
|
|
54365
|
+
to: endOf(gran, key),
|
|
54366
|
+
done: 0,
|
|
54367
|
+
cancelled: 0,
|
|
54368
|
+
added: 0,
|
|
54369
|
+
byWorkspace: {}
|
|
54370
|
+
});
|
|
54371
|
+
}
|
|
54372
|
+
const peak = buckets.reduce((max, bucket) => Math.max(max, bucket.done + bucket.cancelled), 0);
|
|
54373
|
+
const multi = data.workspaces.length >= 2;
|
|
54374
|
+
const colorById = /* @__PURE__ */ new Map();
|
|
54375
|
+
data.workspaces.forEach((workspace, index) => {
|
|
54376
|
+
colorById.set(workspace.id, colorAt(index));
|
|
54377
|
+
});
|
|
54378
|
+
const segmentsOf = (bucket) => {
|
|
54379
|
+
if (!multi) {
|
|
54380
|
+
const out = [];
|
|
54381
|
+
if (bucket.done > 0) out.push({
|
|
54382
|
+
count: bucket.done,
|
|
54383
|
+
color: "var(--dtl-success)"
|
|
54384
|
+
});
|
|
54385
|
+
if (bucket.cancelled > 0) out.push({
|
|
54386
|
+
count: bucket.cancelled,
|
|
54387
|
+
color: "var(--dtl-danger)"
|
|
54388
|
+
});
|
|
54389
|
+
return out;
|
|
54390
|
+
}
|
|
54391
|
+
const out = [];
|
|
54392
|
+
for (const workspace of data.workspaces) {
|
|
54393
|
+
const cell = bucket.byWorkspace[workspace.id];
|
|
54394
|
+
const count = cell === void 0 ? 0 : cell.done + cell.cancelled;
|
|
54395
|
+
if (count > 0) out.push({
|
|
54396
|
+
count,
|
|
54397
|
+
color: colorById.get(workspace.id) ?? colorAt(0)
|
|
54398
|
+
});
|
|
54399
|
+
}
|
|
54400
|
+
return out;
|
|
54401
|
+
};
|
|
54402
|
+
/** 浮卡:首行周期,下面**一工作区一行**(色块 + 名称 + 结案数),有几个列几个、0 值不列。
|
|
54403
|
+
* 多工作区按 host 给的 workspaces 顺序(与配色分配同序);单工作区时柱色本来就是
|
|
54404
|
+
* 完成绿 / 取消红,所以拆成那两行,不硬塞一个工作区色(用户 2026-10-29)。 */
|
|
54405
|
+
const rowsOf = (bucket) => {
|
|
54406
|
+
const rows = [];
|
|
54407
|
+
if (multi) for (const workspace of data.workspaces) {
|
|
54408
|
+
const cell = bucket.byWorkspace[workspace.id];
|
|
54409
|
+
const count = cell === void 0 ? 0 : cell.done + cell.cancelled;
|
|
54410
|
+
if (count <= 0) continue;
|
|
54411
|
+
rows.push({
|
|
54412
|
+
key: workspace.id,
|
|
54413
|
+
name: workspace.title,
|
|
54414
|
+
count,
|
|
54415
|
+
color: colorById.get(workspace.id) ?? colorAt(0)
|
|
54416
|
+
});
|
|
54417
|
+
}
|
|
54418
|
+
else {
|
|
54419
|
+
if (bucket.done > 0) rows.push({
|
|
54420
|
+
key: "done",
|
|
54421
|
+
name: t("chartFinished"),
|
|
54422
|
+
count: bucket.done,
|
|
54423
|
+
color: "var(--dtl-success)"
|
|
54424
|
+
});
|
|
54425
|
+
if (bucket.cancelled > 0) rows.push({
|
|
54426
|
+
key: "cancelled",
|
|
54427
|
+
name: t("chartCancelled"),
|
|
54428
|
+
count: bucket.cancelled,
|
|
54429
|
+
color: "var(--dtl-danger)"
|
|
54430
|
+
});
|
|
54431
|
+
}
|
|
54432
|
+
return rows;
|
|
54433
|
+
};
|
|
54434
|
+
/** 浮卡标题:日 = 当天、周 = 起止区间、月 = 年月(桶边界是 skill 口径)。 */
|
|
54435
|
+
const titleOf = (bucket) => gran === "day" ? bucket.key : gran === "week" ? t("periodRange", {
|
|
54436
|
+
from: bucket.key,
|
|
54437
|
+
to: bucket.to
|
|
54438
|
+
}) : bucket.key.slice(0, 7);
|
|
54439
|
+
/** 总计行的图例块(用户 2026-10-30):**固定两/三段等分**,不按本列实际有几段去算 ——
|
|
54440
|
+
* 只借色板前 3 色当示例,横着一条条叠(与柱子的分段同向,柱里的段也是横着叠的)。
|
|
54441
|
+
* 单工作区时柱子本来就是「完成绿 / 取消红」两段,图例跟着给两段,别硬凑三色。 */
|
|
54442
|
+
const legendColors = multi ? [
|
|
54443
|
+
colorAt(0),
|
|
54444
|
+
colorAt(1),
|
|
54445
|
+
colorAt(2)
|
|
54446
|
+
] : ["var(--dtl-success)", "var(--dtl-danger)"];
|
|
54447
|
+
const legend = (0, react$1.createElement)("span", { className: "dtl-hist__tip-dot dtl-hist__tip-dot--split" }, ...legendColors.map((color, index) => (0, react$1.createElement)("span", {
|
|
54448
|
+
key: index,
|
|
54449
|
+
style: { background: color }
|
|
54450
|
+
})));
|
|
54451
|
+
const tipOf = (bucket) => {
|
|
54452
|
+
const rows = rowsOf(bucket);
|
|
54453
|
+
const closed = bucket.done + bucket.cancelled;
|
|
54454
|
+
return (0, react$1.createElement)("div", { className: "dtl-hist__tip" }, (0, react$1.createElement)("div", { className: "dtl-hist__tip-date" }, titleOf(bucket)), bucket.added > 0 ? (0, react$1.createElement)("div", {
|
|
54455
|
+
key: "added",
|
|
54456
|
+
className: "dtl-hist__tip-row"
|
|
54457
|
+
}, (0, react$1.createElement)("span", {
|
|
54458
|
+
className: "dtl-hist__tip-dot",
|
|
54459
|
+
style: { background: "var(--dtl-chart-added)" }
|
|
54460
|
+
}), (0, react$1.createElement)("span", null, t("chartCreatedTasks")), (0, react$1.createElement)("span", { className: "dtl-hist__tip-count" }, String(bucket.added))) : null, closed > 0 ? (0, react$1.createElement)("div", {
|
|
54461
|
+
key: "closed",
|
|
54462
|
+
className: "dtl-hist__tip-total"
|
|
54463
|
+
}, legend, (0, react$1.createElement)("span", null, t("chartClosedTasks")), (0, react$1.createElement)("span", { className: "dtl-hist__tip-count" }, String(closed))) : null, rows.length > 0 ? (0, react$1.createElement)("div", {
|
|
54464
|
+
key: "sep",
|
|
54465
|
+
className: "dtl-hist__tip-sep"
|
|
54466
|
+
}) : null, ...rows.map((row) => (0, react$1.createElement)("div", {
|
|
54467
|
+
key: row.key,
|
|
54468
|
+
className: "dtl-hist__tip-row"
|
|
54469
|
+
}, (0, react$1.createElement)("span", {
|
|
54470
|
+
className: "dtl-hist__tip-dot",
|
|
54471
|
+
style: { background: row.color }
|
|
54472
|
+
}), (0, react$1.createElement)("span", null, row.name), (0, react$1.createElement)("span", { className: "dtl-hist__tip-count" }, String(row.count)))));
|
|
54473
|
+
};
|
|
54474
|
+
const colStyle = { width: `${String(SLOT_W)}px` };
|
|
54475
|
+
const colOf = (bucket, index) => {
|
|
54476
|
+
const total = bucket.done + bucket.cancelled;
|
|
54477
|
+
const style = {
|
|
54478
|
+
...colStyle,
|
|
54479
|
+
"--lc-d": `${String(Math.round(index / Math.max(1, buckets.length - 1) * STAGGER_MS$1))}ms`
|
|
54480
|
+
};
|
|
54481
|
+
const colKey = `${gran}:${String(shift)}:${bucket.key}`;
|
|
54482
|
+
if (total <= 0) return (0, react$1.createElement)("div", {
|
|
54483
|
+
key: colKey,
|
|
54484
|
+
className: "dtl-hist__col",
|
|
54485
|
+
style
|
|
54486
|
+
}, tipOf(bucket));
|
|
54487
|
+
const segments = segmentsOf(bucket);
|
|
54488
|
+
const height = peak === 0 ? 0 : Math.max(total / peak * 100, 2);
|
|
54489
|
+
return (0, react$1.createElement)("div", {
|
|
54490
|
+
key: colKey,
|
|
54491
|
+
className: "dtl-hist__col",
|
|
54492
|
+
style
|
|
54493
|
+
}, (0, react$1.createElement)("div", {
|
|
54494
|
+
className: "dtl-hist__bar",
|
|
54495
|
+
style: { height: `${String(height)}%` }
|
|
54496
|
+
}, segments.map((segment, index) => (0, react$1.createElement)("div", {
|
|
54497
|
+
key: index,
|
|
54498
|
+
style: {
|
|
54499
|
+
height: `${String(segment.count / total * 100)}%`,
|
|
54500
|
+
background: segment.color
|
|
54501
|
+
}
|
|
54502
|
+
}))), tipOf(bucket));
|
|
54503
|
+
};
|
|
54504
|
+
const labelStep = Math.max(1, Math.ceil(LABEL_MIN_PITCH$1[gran] / 17));
|
|
54505
|
+
/** 最后一个真正画出文字的槽:它得右对齐,否则末位数字会顶出卡片。 */
|
|
54506
|
+
const lastLabelIndex = buckets.length - 1 - (buckets.length - 1) % labelStep;
|
|
54507
|
+
const labelOf = (bucket, index) => {
|
|
54508
|
+
const text = index % labelStep === 0 ? gran === "month" ? bucket.key.slice(0, 7) : bucket.key.slice(5) : "";
|
|
54509
|
+
const anchor = text === "" ? null : index === 0 ? {
|
|
54510
|
+
left: "0",
|
|
54511
|
+
transform: "none"
|
|
54512
|
+
} : index === lastLabelIndex ? {
|
|
54513
|
+
left: "auto",
|
|
54514
|
+
right: "0",
|
|
54515
|
+
transform: "none"
|
|
54516
|
+
} : null;
|
|
54517
|
+
return (0, react$1.createElement)("div", {
|
|
54518
|
+
key: bucket.key,
|
|
54519
|
+
className: "dtl-hist__label",
|
|
54520
|
+
style: colStyle
|
|
54521
|
+
}, text === "" ? null : (0, react$1.createElement)("span", { style: anchor ?? void 0 }, text));
|
|
54522
|
+
};
|
|
54523
|
+
/** 新增量曲线:一周期一个点落在柱中心,**一条线、不分工作区**(用户 2026-10-29)。
|
|
54524
|
+
* x 用「列中心 / plot 实宽」的真实占比 —— 周 / 月模式柱子只占左边一小条,
|
|
54525
|
+
* 曲线必须跟着柱走,不许铺满图宽(用户 2026-10-30)。
|
|
54526
|
+
* 归一化只看曲线自己的峰值(与柱子的结案峰值各管各的),全 0 就不画。 */
|
|
54527
|
+
const curve = () => {
|
|
54528
|
+
if (width <= 0) return null;
|
|
54529
|
+
const values = buckets.map((bucket) => bucket.added);
|
|
54530
|
+
const max = values.reduce((m, v) => v > m ? v : m, 0);
|
|
54531
|
+
if (max <= 0) return null;
|
|
54532
|
+
const points = values.map((value, index) => `${((index + .5) * 17 / width * 100).toFixed(3)},${(100 - value / max * 96).toFixed(2)}`).join(" ");
|
|
54533
|
+
return (0, react$1.createElement)("svg", {
|
|
54534
|
+
className: "dtl-hist__line",
|
|
54535
|
+
viewBox: "0 0 100 100",
|
|
54536
|
+
preserveAspectRatio: "none",
|
|
54537
|
+
"aria-hidden": true
|
|
54538
|
+
}, (0, react$1.createElement)("polyline", { points }));
|
|
54539
|
+
};
|
|
54540
|
+
return (0, react$1.createElement)("div", { className: "dtl-card dtl-hist" }, nav, (0, react$1.createElement)("div", { style: {
|
|
54541
|
+
flex: "1 1 auto",
|
|
54542
|
+
minHeight: 0,
|
|
54543
|
+
display: "flex",
|
|
54544
|
+
gap: "var(--dtl-space-2)"
|
|
54545
|
+
} }, (0, react$1.createElement)("div", { style: {
|
|
54546
|
+
display: "flex",
|
|
54547
|
+
flexDirection: "column",
|
|
54548
|
+
justifyContent: "space-between",
|
|
54549
|
+
flex: "none",
|
|
54550
|
+
minWidth: "20px",
|
|
54551
|
+
paddingBottom: "12px",
|
|
54552
|
+
textAlign: "right",
|
|
54553
|
+
fontSize: "10px",
|
|
54554
|
+
lineHeight: "1",
|
|
54555
|
+
color: "var(--dtl-fg-3)",
|
|
54556
|
+
fontVariantNumeric: "tabular-nums"
|
|
54557
|
+
} }, (0, react$1.createElement)("span", null, compactTick(peak)), (0, react$1.createElement)("span", null, compactTick(Math.round(peak * 3 / 4))), (0, react$1.createElement)("span", null, compactTick(Math.round(peak / 2))), (0, react$1.createElement)("span", null, compactTick(Math.round(peak / 4))), (0, react$1.createElement)("span", null, "0")), (0, react$1.createElement)("div", { style: {
|
|
54558
|
+
flex: "1 1 auto",
|
|
54559
|
+
minWidth: 0,
|
|
54560
|
+
display: "flex",
|
|
54561
|
+
flexDirection: "column",
|
|
54562
|
+
minHeight: 0
|
|
54563
|
+
} }, (0, react$1.createElement)("div", {
|
|
54564
|
+
className: "dtl-hist__plot",
|
|
54565
|
+
ref: setPlotEl
|
|
54566
|
+
}, (0, react$1.createElement)("div", { className: "dtl-hist__grid" }, (0, react$1.createElement)("div", { className: "dtl-hist__gridline dtl-hist__gridline--none" }), (0, react$1.createElement)("div", { className: "dtl-hist__gridline dtl-hist__gridline--dashed" }), (0, react$1.createElement)("div", { className: "dtl-hist__gridline dtl-hist__gridline--dashed" }), (0, react$1.createElement)("div", { className: "dtl-hist__gridline dtl-hist__gridline--dashed" }), (0, react$1.createElement)("div", { className: "dtl-hist__gridline dtl-hist__gridline--base" })), (0, react$1.createElement)("div", { className: "dtl-hist__cols" }, ...buckets.map(colOf)), curve()), (0, react$1.createElement)("div", { className: "dtl-hist__labels" }, ...buckets.map((bucket, index) => labelOf(bucket, index))))));
|
|
54567
|
+
}
|
|
54568
|
+
//#endregion
|
|
54032
54569
|
//#region src/client/task-row.ts
|
|
54033
54570
|
/**
|
|
54034
54571
|
* 任务行(宿主**无表格件** ⇒ 自绘):整行一张卡,样式照抄 dispatch-table 任务配置卡:
|
|
54035
|
-
* 左缘 6×36 状态条 + 标题行 +
|
|
54572
|
+
* 左缘 6×36 状态条 + 标题行 + 第二行标签;右侧执行人名 + 灰字时长;悬停出「继续 / 完成 / 释放 / 取消」;
|
|
54036
54573
|
* 最右常驻「查看」放大镜钮。
|
|
54037
54574
|
*
|
|
54038
|
-
*
|
|
54575
|
+
* 标签排最前的一定是**状态本身**(待认领 / 进行中),异常标记跟在后面(用户 2026-10-30)。
|
|
54039
54576
|
* 状态一律**标签型、五色**(用户 2026-10-18):灰=待认领 / 蓝=进行中 / 黄=积压 / 橙=逾期 /
|
|
54040
54577
|
* 红=停滞;三个异常标签悬停给 skill 算好的天数解释(ageDays / idleDays / waitingDays 随 list 下发)。
|
|
54041
54578
|
*
|
|
54579
|
+
* 行内**不再显示工作区**(列表已按工作区分组,组头写着,用户 2026-10-30)——原来那个位置换成了
|
|
54580
|
+
* 执行人名(蓝字,不是标签)。
|
|
54581
|
+
*
|
|
54042
54582
|
* 按钮(含查看)**不各判各的**:权限一律问 `resolveActions()`(rows.ts),本文件只按返回值画。
|
|
54043
54583
|
*
|
|
54044
54584
|
* 按钮点击行为(含查看)归「任务按钮与会话交接」任务,本文件只做样子与提示。
|
|
@@ -54130,7 +54670,7 @@ body[data-ds-dark-theme]{
|
|
|
54130
54670
|
const tipBtn = (icon, actionKey, tipKey) => (0, react$1.createElement)(Tip, {
|
|
54131
54671
|
label: t(tipKey),
|
|
54132
54672
|
children: (0, react$1.createElement)(Button, {
|
|
54133
|
-
variant: "
|
|
54673
|
+
variant: "secondary",
|
|
54134
54674
|
size: "md",
|
|
54135
54675
|
icon: icon ?? void 0
|
|
54136
54676
|
}, t(actionKey))
|
|
@@ -54138,7 +54678,18 @@ body[data-ds-dark-theme]{
|
|
|
54138
54678
|
const claimButton = tipBtn(null, "actionClaim", "tipClaim");
|
|
54139
54679
|
const resumeButton = tipBtn((0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, { size: 14 }), "actionResume", "tipResume");
|
|
54140
54680
|
const finishButton = tipBtn((0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutlineRegular, { size: 14 }), "actionFinish", "tipFinish");
|
|
54141
|
-
const releaseButton = tipBtn(
|
|
54681
|
+
const releaseButton = tipBtn((0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconChevronLeftOutlineRegular, { size: 14 }), "actionRelease", "tipRelease");
|
|
54682
|
+
const cancelButton = (0, react$1.createElement)(Tip, {
|
|
54683
|
+
label: t("tipCancel"),
|
|
54684
|
+
children: (0, react$1.createElement)(IconButton, {
|
|
54685
|
+
variant: "plain",
|
|
54686
|
+
size: "md",
|
|
54687
|
+
label: t("actionCancel"),
|
|
54688
|
+
title: "",
|
|
54689
|
+
className: "dtl-iconbtn--muted",
|
|
54690
|
+
icon: (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutlineRegular, { size: 14 })
|
|
54691
|
+
})
|
|
54692
|
+
});
|
|
54142
54693
|
const tagOf = (which, tip) => {
|
|
54143
54694
|
const text = statusLabel(which, t);
|
|
54144
54695
|
return (0, react$1.createElement)(Tag, {
|
|
@@ -54148,7 +54699,8 @@ body[data-ds-dark-theme]{
|
|
|
54148
54699
|
tip: tip ?? detailTip(which)
|
|
54149
54700
|
});
|
|
54150
54701
|
};
|
|
54151
|
-
const
|
|
54702
|
+
const markTones = MARKS.filter((which) => row.task[which] === true);
|
|
54703
|
+
const statusTags = [tagOf(row.task.status === "open" ? "open" : "doing"), ...markTones.map((which) => tagOf(which))];
|
|
54152
54704
|
const copyButton = (0, react$1.createElement)(Tip, {
|
|
54153
54705
|
label: `${t("copyTaskId")}\n${row.task.id}`,
|
|
54154
54706
|
maxWidth: 320,
|
|
@@ -54172,7 +54724,7 @@ body[data-ds-dark-theme]{
|
|
|
54172
54724
|
const titleLine = (0, react$1.createElement)("div", { className: "dtl-taskrow__l1" }, (0, react$1.createElement)("span", {
|
|
54173
54725
|
className: "dtl-taskrow__title dtl-ellipsis",
|
|
54174
54726
|
title: titleOf(row)
|
|
54175
|
-
}, titleOf(row)), creatorAge === null || creatorName === "" ? null : (0, react$1.createElement)("span", { className: "dtl-taskrow__stamp" }, solo ? `[${t("fieldCreatorStamp", { age: creatorAge })}]` : `[@${creatorName} ${t("fieldCreatorStamp", { age: creatorAge })}]`)
|
|
54727
|
+
}, titleOf(row)), creatorAge === null || creatorName === "" ? null : (0, react$1.createElement)("span", { className: "dtl-taskrow__stamp" }, solo ? `[${t("fieldCreatorStamp", { age: creatorAge })}]` : `[@${creatorName} ${t("fieldCreatorStamp", { age: creatorAge })}]`));
|
|
54176
54728
|
const whenRaw = row.task.updated ?? row.task.started ?? row.task.created;
|
|
54177
54729
|
const metaText = `${t("whenSubmitted", { time: whenRaw === null || whenRaw === void 0 || Number.isNaN(Date.parse(whenRaw)) ? t("timeUnknown") : formatDateTime(whenRaw).slice(5) })} 丨 ${whenRaw === null || whenRaw === void 0 ? t("timeUnknown") : formatRelative(whenRaw, t)}`;
|
|
54178
54730
|
const ownerName = displayName(row.task.owner_name, row.task.owner);
|
|
@@ -54181,7 +54733,6 @@ body[data-ds-dark-theme]{
|
|
|
54181
54733
|
variant: "link",
|
|
54182
54734
|
size: "sm",
|
|
54183
54735
|
maxWidth: 180,
|
|
54184
|
-
title: t("filterByOwner", { name: ownerName }),
|
|
54185
54736
|
onClick: () => focusOwner(ownerUuid, ownerName)
|
|
54186
54737
|
}, `@${ownerName}`);
|
|
54187
54738
|
const handleRowClick = (event) => {
|
|
@@ -54195,113 +54746,324 @@ body[data-ds-dark-theme]{
|
|
|
54195
54746
|
}, (0, react$1.createElement)("span", { className: `dtl-rail dtl-rail--${tone}` }), (0, react$1.createElement)("div", { style: {
|
|
54196
54747
|
flex: "1 1 auto",
|
|
54197
54748
|
minWidth: 0
|
|
54198
|
-
} }, titleLine, (0, react$1.createElement)("div", { className: "dtl-taskrow__l2" },
|
|
54749
|
+
} }, titleLine, (0, react$1.createElement)("div", { className: "dtl-taskrow__l2" }, ...statusTags, tags.map((tag) => (0, react$1.createElement)(Tag, {
|
|
54199
54750
|
key: tag,
|
|
54200
54751
|
text: `#${tag}`,
|
|
54201
54752
|
maxWidth: 160,
|
|
54202
54753
|
onClick: () => setQuery({ keyword: tag })
|
|
54203
|
-
})))), (0, react$1.createElement)(
|
|
54204
|
-
text: row.task.workspace.title,
|
|
54205
|
-
tone: "person",
|
|
54206
|
-
maxWidth: 200,
|
|
54207
|
-
tip: t("filterByWorkspace", { name: row.task.workspace.title }),
|
|
54208
|
-
onClick: () => setQuery({ workspace: row.task.workspace.id })
|
|
54209
|
-
}), (0, react$1.createElement)("span", { className: "dtl-taskrow__meta" }, metaText), (0, react$1.createElement)("span", { className: "dtl-taskrow__actions" }, actions.claim ? claimButton : null, actions.resume ? resumeButton : null, actions.finish ? finishButton : null, actions.release ? releaseButton : null, copyButton, actions.view ? viewButton : null)));
|
|
54754
|
+
})))), whoNode, (0, react$1.createElement)("span", { className: "dtl-taskrow__meta" }, metaText), (0, react$1.createElement)("span", { className: "dtl-taskrow__actions" }, actions.claim ? claimButton : null, actions.resume ? resumeButton : null, actions.finish ? finishButton : null, actions.release ? releaseButton : null, actions.cancel ? cancelButton : null, copyButton, actions.view ? viewButton : null)));
|
|
54210
54755
|
}
|
|
54211
54756
|
//#endregion
|
|
54212
54757
|
//#region src/client/trend-chart.ts
|
|
54213
54758
|
/**
|
|
54214
|
-
*
|
|
54759
|
+
* 首页趋势图(右上卡):**每周两根柱 + 一条新增曲线**(2026-10-30 用户改版)。
|
|
54760
|
+
*
|
|
54761
|
+
* 术语(2026-10-29 用户拍板):**结案 = 完成 + 取消**(上位词)。结案柱一根里上下两段 ——
|
|
54762
|
+
* 底蓝 = 完成、顶红 = 取消(用户 2026-10-30:有取消才多一段,取消在上;完成色从绿改 business 蓝);
|
|
54763
|
+
* 第二根柱 = 未结。「新增」不再占柱,改成历史页那种曲线(各自归一化,不跟柱共用量程),
|
|
54764
|
+
* 线色取中性灰 —— 柱子已经是蓝的。
|
|
54215
54765
|
*
|
|
54216
|
-
* 数据口径**全由 skill 算好**(`stats --trend week --last
|
|
54217
|
-
*
|
|
54766
|
+
* 数据口径**全由 skill 算好**(`stats --trend week --last 26w --by-owner`,host 已跨工作区求和):
|
|
54767
|
+
* 结案按结案时间、新增按**创建人**、未结是「该周结束时仍未结案」(待认领 + 进行中合成一个数)。
|
|
54218
54768
|
*
|
|
54219
54769
|
* 「只看我的」(2026-10-29 用户定稿):勾上 = 我的,不勾 = 所有;两套数随快照一起回来 ⇒ 勾选零请求。
|
|
54220
|
-
* 按人口径 = skill 的 per-owner:`added` 按 creator(我提的)、`done` / `open` 按 owner(我负责的)。
|
|
54221
54770
|
*
|
|
54222
|
-
*
|
|
54223
|
-
*
|
|
54224
|
-
*
|
|
54225
|
-
*
|
|
54226
|
-
|
|
54227
|
-
*/
|
|
54228
|
-
const
|
|
54229
|
-
|
|
54230
|
-
|
|
54231
|
-
|
|
54232
|
-
|
|
54233
|
-
|
|
54234
|
-
|
|
54235
|
-
|
|
54236
|
-
|
|
54237
|
-
|
|
54238
|
-
|
|
54239
|
-
/**
|
|
54240
|
-
const
|
|
54771
|
+
* 画法对齐历史页(用户 2026-10-30):柱宽 11.25px(固定,缺未结那根也不许拉宽)、组内 1px /
|
|
54772
|
+
* 组间 10px、柱顶 2px 圆角、柱面带 45° 斜纹、悬停整组(两根柱)一个虚线框;
|
|
54773
|
+
* y 轴五档(中间三档全虚线,底基线实线);
|
|
54774
|
+
* 一屏几周按容器实宽算(宽屏也不会铺出空柱),右上角**绝对定位**的左右箭头一次翻 4 周。
|
|
54775
|
+
*/
|
|
54776
|
+
/** 同组两根柱的间距(用户 2026-10-30:跟原来一样 1px)。 */
|
|
54777
|
+
const BAR_GAP = 1;
|
|
54778
|
+
/** 两组之间的间距(用户 2026-10-30:3px → 6px → 10px,一直嫌挤)。 */
|
|
54779
|
+
const GROUP_GAP = 10;
|
|
54780
|
+
/** 一组 = 两根柱 + 组内间距。 */
|
|
54781
|
+
const COL_W = 23.5;
|
|
54782
|
+
/** 一组的横向占宽(含组间距)。 */
|
|
54783
|
+
const PITCH = 33.5;
|
|
54784
|
+
/** 翻页步长:一次 4 周(用户 2026-10-30)。 */
|
|
54785
|
+
const WEEK_STEP = 4;
|
|
54786
|
+
/** x 轴标签的最小间距(小于这个就隔一个标一个,免得挤成一团)。 */
|
|
54787
|
+
const LABEL_MIN_PITCH = 40;
|
|
54788
|
+
/** 数据还没到 / 宽度没量到时按几周排(≈ 卡片默认宽度能放的列数)。 */
|
|
54789
|
+
const FALLBACK_WEEKS = 13;
|
|
54790
|
+
/** 入场动画的**整屏**错峰总时长(跟历史页同款:延迟按列摊,不按序号累加)。 */
|
|
54791
|
+
const STAGGER_MS = 120;
|
|
54792
|
+
/** 柱子 / 图例 / 浮卡共用的五种颜色(真值在 tokens.ts,改色只改那里)。 */
|
|
54793
|
+
const C_DONE = "var(--dtl-chart-done)";
|
|
54794
|
+
const C_CANCELLED = "var(--dtl-danger)";
|
|
54795
|
+
const C_DOING = "var(--dtl-chart-doing)";
|
|
54796
|
+
const C_OPEN = "var(--dtl-chart-open)";
|
|
54797
|
+
const C_LINE = "var(--dtl-chart-line)";
|
|
54798
|
+
/**
|
|
54799
|
+
* 四数归一:老版本 host 返回的桶可能没有 `cancelled`(甚至没有 `owners`),
|
|
54800
|
+
* 缺字段按 0 —— 这是「那一类记录本来就没有」,不是拿 0 充真值。
|
|
54801
|
+
* 不做这层兜底,`done + undefined` 会变成 NaN,把峰、刻度、柱高整张图一起毁掉。
|
|
54802
|
+
*/
|
|
54803
|
+
const norm = (cell) => ({
|
|
54804
|
+
added: cell?.added ?? 0,
|
|
54805
|
+
done: cell?.done ?? 0,
|
|
54806
|
+
cancelled: cell?.cancelled ?? 0,
|
|
54807
|
+
open: cell?.open ?? 0
|
|
54808
|
+
});
|
|
54241
54809
|
function TrendChart(props) {
|
|
54242
54810
|
const { trend, me, t } = props;
|
|
54243
54811
|
const [mineOnly, setMineOnly] = (0, react$1.useState)(false);
|
|
54244
|
-
|
|
54812
|
+
/** 从最新一周往回翻了几次(每次 WEEK_STEP 周)。 */
|
|
54813
|
+
const [shift, setShift] = (0, react$1.useState)(0);
|
|
54814
|
+
const [plotEl, setPlotEl] = (0, react$1.useState)(null);
|
|
54815
|
+
const [width, setWidth] = (0, react$1.useState)(0);
|
|
54245
54816
|
const mine = mineOnly && me !== null;
|
|
54817
|
+
(0, react$1.useEffect)(() => {
|
|
54818
|
+
if (plotEl === null) return;
|
|
54819
|
+
const observer = new ResizeObserver((entries) => {
|
|
54820
|
+
const rect = entries[0];
|
|
54821
|
+
if (rect !== void 0) setWidth(rect.contentRect.width);
|
|
54822
|
+
});
|
|
54823
|
+
observer.observe(plotEl);
|
|
54824
|
+
setWidth(plotEl.clientWidth);
|
|
54825
|
+
return () => observer.disconnect();
|
|
54826
|
+
}, [plotEl]);
|
|
54827
|
+
if (trend === null) return (0, react$1.createElement)("div", { className: "dtl-card dtl-trend" }, (0, react$1.createElement)("div", { style: {
|
|
54828
|
+
flex: "1 1 auto",
|
|
54829
|
+
minHeight: 0,
|
|
54830
|
+
display: "flex",
|
|
54831
|
+
alignItems: "center",
|
|
54832
|
+
justifyContent: "center"
|
|
54833
|
+
} }, (0, react$1.createElement)(Loader, {
|
|
54834
|
+
variant: "blocks",
|
|
54835
|
+
size: "xl"
|
|
54836
|
+
})));
|
|
54837
|
+
const buckets = trend.buckets;
|
|
54246
54838
|
if (buckets.length === 0) return (0, react$1.createElement)("div", { className: "dtl-card dtl-trend" }, (0, react$1.createElement)("div", { className: "dtl-trend__foot" }, t("chartEmpty")));
|
|
54247
|
-
/**
|
|
54248
|
-
const counts = (bucket) => mine ? bucket.owners[me]
|
|
54839
|
+
/** 当前口径下这一桶的数:全量,或「我的」那条(没数据就是 0)。 */
|
|
54840
|
+
const counts = (bucket) => mine ? norm(bucket.owners[me]) : norm(bucket);
|
|
54249
54841
|
/** 未结拆两段:进行中 = 各人未结之和;待认领 = 未结 − 进行中。
|
|
54250
|
-
*
|
|
54842
|
+
* 「只看我的」时全是进行中(我的任务必然有人接),整根都是那一段。 */
|
|
54251
54843
|
const breakdown = (bucket) => {
|
|
54844
|
+
if (mine) return {
|
|
54845
|
+
doing: counts(bucket).open,
|
|
54846
|
+
waiting: 0
|
|
54847
|
+
};
|
|
54252
54848
|
const doing = Object.values(bucket.owners).reduce((sum, cell) => sum + cell.open, 0);
|
|
54253
54849
|
return {
|
|
54254
54850
|
doing,
|
|
54255
54851
|
waiting: Math.max(0, bucket.open - doing)
|
|
54256
54852
|
};
|
|
54257
54853
|
};
|
|
54258
|
-
|
|
54259
|
-
|
|
54260
|
-
|
|
54854
|
+
/** 结案 = 完成 + 取消(用户 2026-10-29 定的上位词);结案柱整根高就是它。 */
|
|
54855
|
+
const closed = (cell) => cell.done + cell.cancelled;
|
|
54856
|
+
const fit = width > 0 ? Math.max(1, Math.floor((width + GROUP_GAP) / PITCH)) : FALLBACK_WEEKS;
|
|
54857
|
+
const perScreen = Math.min(fit, buckets.length);
|
|
54858
|
+
const byKey = new Map(buckets.map((bucket) => [bucket.from, bucket]));
|
|
54859
|
+
const lastKey = mondayOf(ymdOf(/* @__PURE__ */ new Date()));
|
|
54860
|
+
const slots = [];
|
|
54861
|
+
for (let back = perScreen - 1; back >= 0; back -= 1) {
|
|
54862
|
+
const key = addDays(lastKey, -(shift * WEEK_STEP + back) * 7);
|
|
54863
|
+
slots.push(byKey.get(key) ?? {
|
|
54864
|
+
from: key,
|
|
54865
|
+
to: addDays(key, 6),
|
|
54866
|
+
added: 0,
|
|
54867
|
+
done: 0,
|
|
54868
|
+
cancelled: 0,
|
|
54869
|
+
open: 0,
|
|
54870
|
+
owners: {}
|
|
54871
|
+
});
|
|
54872
|
+
}
|
|
54873
|
+
const peak = slots.reduce((max, slot) => {
|
|
54874
|
+
const cell = counts(slot);
|
|
54875
|
+
return Math.max(max, closed(cell), cell.open);
|
|
54261
54876
|
}, 0);
|
|
54262
54877
|
const top = peak === 0 ? 1 : peak;
|
|
54263
|
-
|
|
54264
|
-
|
|
54265
|
-
|
|
54266
|
-
"
|
|
54878
|
+
/** 翻页钮:**只画箭头**(核心 `IconButton` 出皮、官方图标出图形);悬停提示走官方 Tooltip。 */
|
|
54879
|
+
const navButton = (dir, label, onClick) => (0, react$1.createElement)(Tip, {
|
|
54880
|
+
label,
|
|
54881
|
+
side: "bottom",
|
|
54882
|
+
children: (0, react$1.createElement)(IconButton, {
|
|
54883
|
+
icon: (0, react$1.createElement)(dir === "left" ? _deepseek_ai_dsh_client_ui_primitives.IconChevronLeftOutlineRegular : _deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, { size: 14 }),
|
|
54884
|
+
label,
|
|
54885
|
+
title: "",
|
|
54886
|
+
variant: "outline",
|
|
54887
|
+
size: "sm",
|
|
54888
|
+
onClick
|
|
54889
|
+
})
|
|
54890
|
+
});
|
|
54891
|
+
const weekUnit = t("historyGranWeek");
|
|
54892
|
+
/** 色块:一色 = 直接用父级那块 8×8 上色;两色 = 上下两半的方块(上段与柱子里叠在上面的
|
|
54893
|
+
* 那一段同色,用户 2026-10-30:「进行中」在上、「待认领」在下,图例和柱子一个朝向)。
|
|
54894
|
+
* 一色时**不能**走子 span —— 子 span 没有尺寸,方块会是空的(2026-10-30 该 bug)。 */
|
|
54895
|
+
const dot = (colors) => colors.length > 1 ? (0, react$1.createElement)("span", { className: "dtl-trend__dot dtl-trend__dot--split" }, ...colors.map((color, index) => (0, react$1.createElement)("span", {
|
|
54896
|
+
key: index,
|
|
54897
|
+
style: { background: color }
|
|
54898
|
+
}))) : (0, react$1.createElement)("span", {
|
|
54899
|
+
className: "dtl-trend__dot",
|
|
54900
|
+
style: { background: colors[0] ?? "transparent" }
|
|
54901
|
+
});
|
|
54902
|
+
/** 图例:两枚上下两段的方块(已结案 = 取消在上 / 完成在下、未结 = 进行中在上 / 待认领在下)
|
|
54903
|
+
* + 新增曲线。只看我的时未结整根都是进行中,那枚不拆(用户 2026-10-30)。 */
|
|
54904
|
+
const legend = [
|
|
54905
|
+
{
|
|
54906
|
+
key: "closed",
|
|
54907
|
+
label: t("chartClosed"),
|
|
54908
|
+
colors: [C_CANCELLED, C_DONE]
|
|
54909
|
+
},
|
|
54910
|
+
{
|
|
54911
|
+
key: "open",
|
|
54912
|
+
label: t(mine ? "chartDoing" : "chartOpen"),
|
|
54913
|
+
colors: mine ? [C_DOING] : [C_DOING, C_OPEN]
|
|
54914
|
+
},
|
|
54915
|
+
{
|
|
54916
|
+
key: "added",
|
|
54917
|
+
label: t("chartAdded"),
|
|
54918
|
+
colors: [C_LINE]
|
|
54919
|
+
}
|
|
54267
54920
|
];
|
|
54268
|
-
const
|
|
54269
|
-
|
|
54921
|
+
const row = (key, label, count, color) => count > 0 ? (0, react$1.createElement)("div", {
|
|
54922
|
+
key,
|
|
54923
|
+
className: "dtl-trend__tip-row"
|
|
54924
|
+
}, (0, react$1.createElement)("span", {
|
|
54925
|
+
className: "dtl-trend__dot",
|
|
54926
|
+
style: { background: color }
|
|
54927
|
+
}), `${label} ${formatCount(count)}`) : null;
|
|
54928
|
+
/** 浮卡的一行总数(带色块)+ 缩进的拆分注脚(用户 2026-10-30:总数一行、下跟「X N · Y M」)。 */
|
|
54929
|
+
const totalRow = (key, label, count, colors, sub) => count > 0 ? [(0, react$1.createElement)("div", {
|
|
54930
|
+
key,
|
|
54931
|
+
className: "dtl-trend__tip-row"
|
|
54932
|
+
}, dot(colors), `${label} ${formatCount(count)}`), sub === "" ? null : (0, react$1.createElement)("div", {
|
|
54933
|
+
key: `${key}-sub`,
|
|
54934
|
+
className: "dtl-trend__tip-row dtl-trend__tip-row--sub"
|
|
54935
|
+
}, sub)] : [];
|
|
54936
|
+
/** 浮卡:周期 → 新建 → 已结案(下跟完成 / 取消)→ 未结(下跟进行中 / 待认领);0 值不列。 */
|
|
54937
|
+
const tipOf = (bucket) => {
|
|
54938
|
+
const cell = counts(bucket);
|
|
54939
|
+
const split = breakdown(bucket);
|
|
54940
|
+
const total = closed(cell);
|
|
54941
|
+
return (0, react$1.createElement)("div", { className: "dtl-trend__tip" }, (0, react$1.createElement)("div", { className: "dtl-trend__tip-row" }, t("periodRange", {
|
|
54942
|
+
from: bucket.from,
|
|
54943
|
+
to: bucket.to
|
|
54944
|
+
})), row("added", t("chartCreatedTasks"), cell.added, "var(--dtl-tip-fg-dim)"), ...totalRow("closed", t("chartClosed"), total, [C_CANCELLED, C_DONE], `${t("chartFinished")} ${formatCount(cell.done)} · ${t("chartCancelled")} ${formatCount(cell.cancelled)}`), ...totalRow("open", t(mine ? "chartDoing" : "chartOpen"), cell.open, mine ? [C_DOING] : [C_DOING, C_OPEN], mine ? "" : `${t("chartDoing")} ${formatCount(split.doing)} · ${t("chartWaiting")} ${formatCount(split.waiting)}`));
|
|
54945
|
+
};
|
|
54946
|
+
const colStyle = { width: `${String(COL_W)}px` };
|
|
54947
|
+
/** 一根柱 = 一个周:左结案(底蓝完成 / 顶红取消)、右未结(底琥珀待认领 / 顶绿进行中)。 */
|
|
54948
|
+
const colOf = (bucket, index) => {
|
|
54949
|
+
const cell = counts(bucket);
|
|
54950
|
+
const total = closed(cell);
|
|
54951
|
+
const split = breakdown(bucket);
|
|
54952
|
+
const height = (value) => `${String(value / top * 100)}%`;
|
|
54953
|
+
const style = {
|
|
54954
|
+
...colStyle,
|
|
54955
|
+
"--lc-d": `${String(Math.round(index / Math.max(1, slots.length - 1) * STAGGER_MS))}ms`
|
|
54956
|
+
};
|
|
54270
54957
|
return (0, react$1.createElement)("div", {
|
|
54271
|
-
|
|
54272
|
-
|
|
54273
|
-
|
|
54274
|
-
|
|
54275
|
-
|
|
54276
|
-
|
|
54958
|
+
key: `${String(shift)}:${bucket.from}`,
|
|
54959
|
+
className: "dtl-trend__col",
|
|
54960
|
+
style
|
|
54961
|
+
}, (0, react$1.createElement)("div", {
|
|
54962
|
+
className: "dtl-trend__bars",
|
|
54963
|
+
style: { gap: `${String(BAR_GAP)}px` }
|
|
54964
|
+
}, total > 0 ? (0, react$1.createElement)("div", {
|
|
54965
|
+
className: "dtl-trend__bar dtl-trend__bar--closed",
|
|
54966
|
+
style: { height: height(total) }
|
|
54967
|
+
}, cell.cancelled > 0 ? (0, react$1.createElement)("span", {
|
|
54968
|
+
className: "dtl-trend__seg dtl-trend__seg--cancelled",
|
|
54969
|
+
style: { height: `${String(cell.cancelled / total * 100)}%` }
|
|
54970
|
+
}) : null) : null, cell.open > 0 ? (0, react$1.createElement)("div", {
|
|
54971
|
+
className: "dtl-trend__bar dtl-trend__bar--open",
|
|
54972
|
+
style: { height: height(cell.open) }
|
|
54973
|
+
}, split.doing > 0 ? (0, react$1.createElement)("span", {
|
|
54974
|
+
className: "dtl-trend__seg dtl-trend__seg--doing",
|
|
54975
|
+
style: { height: `${String(split.doing / cell.open * 100)}%` }
|
|
54976
|
+
}) : null) : null), tipOf(bucket));
|
|
54977
|
+
};
|
|
54978
|
+
const labelStep = Math.max(1, Math.ceil(LABEL_MIN_PITCH / PITCH));
|
|
54979
|
+
/** 最后一个真正画出文字的位置:它得右对齐,否则末位数字会顶出卡片。 */
|
|
54980
|
+
const lastLabelIndex = slots.length - 1 - (slots.length - 1) % labelStep;
|
|
54981
|
+
/** x 轴标**周末日期**(数据按截止日判),当前周就是今天。 */
|
|
54982
|
+
const labelOf = (bucket, index) => {
|
|
54983
|
+
const text = index % labelStep === 0 ? bucket.to.slice(5) : "";
|
|
54984
|
+
const anchor = text === "" ? null : index === 0 ? {
|
|
54985
|
+
left: "0",
|
|
54986
|
+
transform: "none"
|
|
54987
|
+
} : index === lastLabelIndex ? {
|
|
54988
|
+
left: "auto",
|
|
54989
|
+
right: "0",
|
|
54990
|
+
transform: "none"
|
|
54991
|
+
} : null;
|
|
54992
|
+
return (0, react$1.createElement)("div", {
|
|
54993
|
+
key: bucket.from,
|
|
54994
|
+
className: "dtl-trend__label",
|
|
54995
|
+
style: colStyle
|
|
54996
|
+
}, text === "" ? null : (0, react$1.createElement)("span", { style: anchor ?? void 0 }, text));
|
|
54997
|
+
};
|
|
54998
|
+
/** 新增量曲线:一周一个点落在柱组中心,**只看自己的峰值**(不跟柱共用量程),全 0 就不画。 */
|
|
54999
|
+
const curve = () => {
|
|
55000
|
+
if (width <= 0) return null;
|
|
55001
|
+
const values = slots.map((slot) => counts(slot).added);
|
|
55002
|
+
const max = values.reduce((m, v) => v > m ? v : m, 0);
|
|
55003
|
+
if (max <= 0) return null;
|
|
55004
|
+
const points = values.map((value, index) => `${((index + .5) * PITCH / width * 100).toFixed(3)},${(100 - value / max * 96).toFixed(2)}`).join(" ");
|
|
55005
|
+
return (0, react$1.createElement)("svg", {
|
|
55006
|
+
className: "dtl-trend__line",
|
|
55007
|
+
viewBox: "0 0 100 100",
|
|
55008
|
+
preserveAspectRatio: "none",
|
|
55009
|
+
"aria-hidden": true
|
|
55010
|
+
}, (0, react$1.createElement)("polyline", { points }));
|
|
54277
55011
|
};
|
|
54278
|
-
const
|
|
54279
|
-
|
|
54280
|
-
|
|
54281
|
-
})), ...BAR_KINDS.map((kind) => (0, react$1.createElement)("div", { className: "dtl-trend__tip-row" }, (0, react$1.createElement)("span", { className: `dtl-trend__dot dtl-trend__dot--${kind}` }), kind === "open" && !mine ? `${t("chartOpen")} ${formatCount(counts(bucket).open)}(${t("chartDoing")} ${formatCount(breakdown(bucket).doing)} · ${t("chartWaiting")} ${formatCount(breakdown(bucket).waiting)})` : `${t(labelKey(kind, mine))} ${formatCount(counts(bucket)[kind])}`))), (0, react$1.createElement)("div", { className: "dtl-trend__bars" }, ...BAR_KINDS.map((kind) => bar(bucket, kind))), (0, react$1.createElement)("div", { className: "dtl-trend__x" }, bucket.to.slice(5)));
|
|
54282
|
-
const first = buckets[0];
|
|
54283
|
-
const partial = trend.coverageFrom !== "" && trend.coverageFrom > first.from ? (0, react$1.createElement)("div", { className: "dtl-trend__foot" }, t("chartPartial", { from: trend.coverageFrom })) : null;
|
|
54284
|
-
return (0, react$1.createElement)("div", { className: "dtl-card dtl-trend" }, (0, react$1.createElement)("div", { className: "dtl-trend__legend" }, ...BAR_KINDS.map((kind) => (0, react$1.createElement)("span", null, (0, react$1.createElement)("span", { className: `dtl-trend__dot dtl-trend__dot--${kind}` }), t(labelKey(kind, mine)))), me === null ? null : (0, react$1.createElement)("label", { className: "dtl-trend__mine" }, (0, react$1.createElement)("input", {
|
|
55012
|
+
const first = slots[0];
|
|
55013
|
+
const partial = trend.coverageFrom !== "" && first !== void 0 && trend.coverageFrom > first.from ? (0, react$1.createElement)("div", { className: "dtl-trend__foot" }, t("chartPartial", { from: trend.coverageFrom })) : null;
|
|
55014
|
+
return (0, react$1.createElement)("div", { className: "dtl-card dtl-trend" }, (0, react$1.createElement)("div", { className: "dtl-trend__legend" }, ...legend.map((item) => (0, react$1.createElement)("span", { key: item.key }, dot(item.colors), item.label)), me === null ? null : (0, react$1.createElement)("label", { className: "dtl-trend__mine" }, (0, react$1.createElement)("input", {
|
|
54285
55015
|
type: "checkbox",
|
|
54286
55016
|
checked: mineOnly,
|
|
54287
55017
|
onChange: (event) => {
|
|
54288
55018
|
setMineOnly(event.target.checked);
|
|
54289
55019
|
}
|
|
54290
|
-
}), t("chartMine"))), (0, react$1.createElement)("div", { className: "dtl-
|
|
55020
|
+
}), t("chartMine"))), (0, react$1.createElement)("div", { className: "dtl-trend__nav" }, navButton("left", t("historyPrev", {
|
|
55021
|
+
n: WEEK_STEP,
|
|
55022
|
+
unit: weekUnit
|
|
55023
|
+
}), () => {
|
|
55024
|
+
setShift((value) => value + 1);
|
|
55025
|
+
}), navButton("right", t("historyNext", {
|
|
55026
|
+
n: WEEK_STEP,
|
|
55027
|
+
unit: weekUnit
|
|
55028
|
+
}), () => {
|
|
55029
|
+
setShift((value) => Math.max(0, value - 1));
|
|
55030
|
+
})), (0, react$1.createElement)("div", { className: "dtl-trend__body" }, (0, react$1.createElement)("div", { className: "dtl-trend__axis" }, (0, react$1.createElement)("span", null, formatCount(peak)), (0, react$1.createElement)("span", null, formatCount(Math.round(peak * 3 / 4))), (0, react$1.createElement)("span", null, formatCount(Math.round(peak / 2))), (0, react$1.createElement)("span", null, formatCount(Math.round(peak / 4))), (0, react$1.createElement)("span", null, "0")), (0, react$1.createElement)("div", { style: {
|
|
55031
|
+
flex: "1 1 auto",
|
|
55032
|
+
minWidth: 0,
|
|
55033
|
+
display: "flex",
|
|
55034
|
+
flexDirection: "column",
|
|
55035
|
+
minHeight: 0
|
|
55036
|
+
} }, (0, react$1.createElement)("div", {
|
|
55037
|
+
className: "dtl-trend__plot",
|
|
55038
|
+
ref: setPlotEl
|
|
55039
|
+
}, (0, react$1.createElement)("div", { className: "dtl-trend__grid" }, (0, react$1.createElement)("div", { className: "dtl-trend__gridline dtl-trend__gridline--none" }), (0, react$1.createElement)("div", { className: "dtl-trend__gridline dtl-trend__gridline--dashed" }), (0, react$1.createElement)("div", { className: "dtl-trend__gridline dtl-trend__gridline--dashed" }), (0, react$1.createElement)("div", { className: "dtl-trend__gridline dtl-trend__gridline--dashed" }), (0, react$1.createElement)("div", { className: "dtl-trend__gridline dtl-trend__gridline--base" })), (0, react$1.createElement)("div", {
|
|
55040
|
+
className: "dtl-trend__cols",
|
|
55041
|
+
style: { gap: `${String(GROUP_GAP)}px` }
|
|
55042
|
+
}, ...slots.map(colOf)), curve()), (0, react$1.createElement)("div", {
|
|
55043
|
+
className: "dtl-trend__labels",
|
|
55044
|
+
style: { gap: `${String(GROUP_GAP)}px` }
|
|
55045
|
+
}, ...slots.map(labelOf)))), partial);
|
|
54291
55046
|
}
|
|
54292
55047
|
//#endregion
|
|
54293
55048
|
//#region src/client/board-home.ts
|
|
54294
55049
|
/**
|
|
54295
|
-
* 看板首页(`main` 槽整页内容):上 = 8 统计卡 +
|
|
55050
|
+
* 看板首页(`main` 槽整页内容):上 = 8 统计卡 + 趋势图;下 = 单区任务列表。
|
|
54296
55051
|
*
|
|
54297
55052
|
* 2026-10-28:列表沿用原「我的待办」卡片样式,改成**左侧六档菜单 + 右侧三个过滤**的平铺列表。
|
|
54298
55053
|
* - 菜单六档**全部真筛**(积压 / 逾期 / 停滞 用 skill 下发的布尔);
|
|
54299
55054
|
* - 工作区 / 执行人 / 搜索 **全部本地筛**(快照已含全部在办,不发请求)。
|
|
54300
55055
|
*
|
|
55056
|
+
* 2026-10-30 首屏加载改版(用户:不要整页 loading,也别铺骨架):跟历史页一个口径 ——
|
|
55057
|
+
* 8 块卡只画标题 + 「—」、图表卡里一个三点 Loader、列表位一个三点 Loader(最大号);
|
|
55058
|
+
* 快照一到就地替换。原来那层屏幕下方的全局 `showLoading` 已删。
|
|
55059
|
+
*
|
|
54301
55060
|
* 数据纪律:行上的 `mine` / `stale` / `overdue` / `backlog` 与阈值都来自 skill,
|
|
54302
55061
|
* 前端只做布尔判断与渲染。刷新 = 挂载首读 + 手动刷新按钮,**不轮询**。
|
|
54303
55062
|
*/
|
|
54304
|
-
/** 主内容:占满、自己滚动;padding 只在内层,dock 才不会继承内边距。
|
|
55063
|
+
/** 主内容:占满、自己滚动;padding 只在内层,dock 才不会继承内边距。
|
|
55064
|
+
* ⚠️ 底部不留 padding:滚到底的留白改由内容末尾的 `.dtl-page-foot` 实体块承担
|
|
55065
|
+
* (用户 2026-10-30:最后一条贴着浏览器底边 —— 滚动容器未必是这一层,
|
|
55066
|
+
* 挂在这一层的 padding-bottom 就落空了,实体块跟着内容走才不会丢)。 */
|
|
54305
55067
|
const pageStyle = {
|
|
54306
55068
|
height: "100%",
|
|
54307
55069
|
width: "100%",
|
|
@@ -54309,7 +55071,7 @@ body[data-ds-dark-theme]{
|
|
|
54309
55071
|
minWidth: 0,
|
|
54310
55072
|
boxSizing: "border-box",
|
|
54311
55073
|
overflow: "auto",
|
|
54312
|
-
padding: "24px 22px",
|
|
55074
|
+
padding: "24px 22px 0",
|
|
54313
55075
|
color: "var(--dtl-fg)"
|
|
54314
55076
|
};
|
|
54315
55077
|
/** dock 的挂载行:**不带 padding**,dock 作为直接子项才能贴右/上/下边。 */
|
|
@@ -54360,18 +55122,42 @@ body[data-ds-dark-theme]{
|
|
|
54360
55122
|
const SELECT_MAX_WIDTH = 240;
|
|
54361
55123
|
/** 搜索框宽度(用户 2026-10-17:两区同款,96×2 = 192)。 */
|
|
54362
55124
|
const SEARCH_WIDTH = 192;
|
|
54363
|
-
/**
|
|
54364
|
-
|
|
54365
|
-
|
|
55125
|
+
/** **单个工作区**最多渲染条数(用户 2026-10-30:原来是整体 100 条,改成每区各自 100 条,
|
|
55126
|
+
* 超了在该区列表末尾给一条提示;不再有全局截断 —— 「我的待办」与「全部」同一条规则)。 */
|
|
55127
|
+
const WS_LIMIT = 100;
|
|
55128
|
+
/** 组头计数:按「待认领 → 进行中 → 积压 → 逾期 → 停滞」排,` · ` 分隔;
|
|
55129
|
+
* **0 的档整段不出现**(用户 2026-10-30:不显示 0,也不显示杠),「我的待办」不列。 */
|
|
55130
|
+
const GROUP_STATS = [
|
|
55131
|
+
{
|
|
55132
|
+
value: "open",
|
|
55133
|
+
label: "statOpen"
|
|
55134
|
+
},
|
|
55135
|
+
{
|
|
55136
|
+
value: "doing",
|
|
55137
|
+
label: "statDoing"
|
|
55138
|
+
},
|
|
55139
|
+
{
|
|
55140
|
+
value: "backlog",
|
|
55141
|
+
label: "statBacklog"
|
|
55142
|
+
},
|
|
55143
|
+
{
|
|
55144
|
+
value: "overdue",
|
|
55145
|
+
label: "statOverdue"
|
|
55146
|
+
},
|
|
55147
|
+
{
|
|
55148
|
+
value: "stale",
|
|
55149
|
+
label: "statStale"
|
|
55150
|
+
}
|
|
55151
|
+
];
|
|
55152
|
+
/** 组内「已截断」提示样式(核心暂无对应件;灰小字、贴在该组最后一张卡下方,观感定型后再收口)。 */
|
|
54366
55153
|
const limitHintStyle = {
|
|
54367
|
-
marginTop: "var(--dtl-space-
|
|
54368
|
-
padding: "
|
|
54369
|
-
textAlign: "center",
|
|
55154
|
+
marginTop: "var(--dtl-space-2)",
|
|
55155
|
+
padding: "0 var(--dtl-space-2)",
|
|
54370
55156
|
fontSize: "var(--dtl-font-sm)",
|
|
54371
55157
|
lineHeight: "var(--dtl-line-sm)",
|
|
54372
55158
|
color: "var(--dtl-fg-3)"
|
|
54373
55159
|
};
|
|
54374
|
-
/** 左侧菜单(「我的待办」置顶、「全部」次之,其后六档本地真筛;角标 =
|
|
55160
|
+
/** 左侧菜单(「我的待办」置顶、「全部」次之,其后六档本地真筛;角标 = 当前工作区 / 执行人 / 搜索范围内各档计数)。 */
|
|
54375
55161
|
const TABS = [
|
|
54376
55162
|
{
|
|
54377
55163
|
value: "mine",
|
|
@@ -54402,6 +55188,18 @@ body[data-ds-dark-theme]{
|
|
|
54402
55188
|
label: "statStale"
|
|
54403
55189
|
}
|
|
54404
55190
|
];
|
|
55191
|
+
/** 8 块统计卡的标题(DOM 列序,与 `statsGrid` 里的排布一致):
|
|
55192
|
+
* 首屏没数据时只画标题 + 「—」,跟历史页那 4 块一个口径(用户 2026-10-30)。 */
|
|
55193
|
+
const STAT_LABELS = [
|
|
55194
|
+
"statMyActive",
|
|
55195
|
+
"statDoing",
|
|
55196
|
+
"statOpen",
|
|
55197
|
+
"statBacklog",
|
|
55198
|
+
"statOverdue",
|
|
55199
|
+
"statStale",
|
|
55200
|
+
"statWeekDone",
|
|
55201
|
+
"statLastWeekDone"
|
|
55202
|
+
];
|
|
54405
55203
|
/** 错误原文只留第一行并截断:脚本报错常把整段用法提示塞在一行里,toast 装不下。 */
|
|
54406
55204
|
function firstLine(message) {
|
|
54407
55205
|
const line = (message.split("\n")[0] ?? "").trim();
|
|
@@ -54413,6 +55211,18 @@ body[data-ds-dark-theme]{
|
|
|
54413
55211
|
const state = (0, react$1.useSyncExternalStore)(boardSubscribe, boardSnapshot);
|
|
54414
55212
|
const mountRef = (0, react$1.useRef)(null);
|
|
54415
55213
|
const [viewMode, setViewMode] = (0, react$1.useState)("active");
|
|
55214
|
+
const [gran, setGran] = (0, react$1.useState)("day");
|
|
55215
|
+
const [historyByGran, setHistoryByGran] = (0, react$1.useState)({});
|
|
55216
|
+
const historyTrend = historyByGran[gran] ?? null;
|
|
55217
|
+
const [historyError, setHistoryError] = (0, react$1.useState)(null);
|
|
55218
|
+
const lastTrendRef = (0, react$1.useRef)(null);
|
|
55219
|
+
(0, react$1.useEffect)(() => {
|
|
55220
|
+
if (historyTrend !== null) lastTrendRef.current = {
|
|
55221
|
+
gran,
|
|
55222
|
+
payload: historyTrend
|
|
55223
|
+
};
|
|
55224
|
+
});
|
|
55225
|
+
const shownTrend = historyTrend ?? (lastTrendRef.current !== null && lastTrendRef.current.gran === gran ? lastTrendRef.current.payload : null);
|
|
54416
55226
|
/** 查看:右侧 dock 预览过程文档;没有就打开台账文件夹(目录树)。
|
|
54417
55227
|
* 文件服务 / 会话 / flex 全由核心(connectHost 接线)接管,这里只给容器 + 路径。 */
|
|
54418
55228
|
const handleView = (row) => {
|
|
@@ -54428,13 +55238,6 @@ body[data-ds-dark-theme]{
|
|
|
54428
55238
|
(0, react$1.useEffect)(() => {
|
|
54429
55239
|
refresh();
|
|
54430
55240
|
}, []);
|
|
54431
|
-
(0, react$1.useEffect)(() => {
|
|
54432
|
-
if (state.board !== null || state.status === "error") return;
|
|
54433
|
-
const loading = showLoading(t("loading"));
|
|
54434
|
-
return () => {
|
|
54435
|
-
loading.close();
|
|
54436
|
-
};
|
|
54437
|
-
}, [state.board, state.status]);
|
|
54438
55241
|
const board = state.board;
|
|
54439
55242
|
const view = (0, react$1.useMemo)(() => selectView(state), [state]);
|
|
54440
55243
|
const degraded = board?.degraded ?? [];
|
|
@@ -54458,6 +55261,26 @@ body[data-ds-dark-theme]{
|
|
|
54458
55261
|
degraded,
|
|
54459
55262
|
t
|
|
54460
55263
|
]);
|
|
55264
|
+
(0, react$1.useEffect)(() => {
|
|
55265
|
+
if (viewMode !== "history" || historyTrend !== null || historyError !== null) return;
|
|
55266
|
+
let alive = true;
|
|
55267
|
+
fetchHistoryTrend(gran).then((payload) => {
|
|
55268
|
+
if (alive) setHistoryByGran((prev) => ({
|
|
55269
|
+
...prev,
|
|
55270
|
+
[gran]: payload
|
|
55271
|
+
}));
|
|
55272
|
+
}).catch((error) => {
|
|
55273
|
+
if (alive) setHistoryError(error instanceof Error ? error.message : String(error));
|
|
55274
|
+
});
|
|
55275
|
+
return () => {
|
|
55276
|
+
alive = false;
|
|
55277
|
+
};
|
|
55278
|
+
}, [
|
|
55279
|
+
viewMode,
|
|
55280
|
+
gran,
|
|
55281
|
+
historyTrend,
|
|
55282
|
+
historyError
|
|
55283
|
+
]);
|
|
54461
55284
|
/** 工作区下拉候选:宿主里所有含台账的工作区(不是从任务里反推,空工作区也要能选)。 */
|
|
54462
55285
|
const workspaceOptions = (0, react$1.useMemo)(() => [{
|
|
54463
55286
|
value: "",
|
|
@@ -54501,7 +55324,8 @@ body[data-ds-dark-theme]{
|
|
|
54501
55324
|
});
|
|
54502
55325
|
/** 子集卡占比小字:分母为 0 或自己没有 ⇒ 不显示(不拿 0% 充数)。 */
|
|
54503
55326
|
const share = (part, whole, key) => part > 0 && whole > 0 ? t(key, { n: Math.round(part / whole * 100) }) : "";
|
|
54504
|
-
/** 统计台卡:数字 =
|
|
55327
|
+
/** 统计台卡:数字 = **结案**(完成 + 取消);有取消时小字拆「完成 X · 取消 Y」
|
|
55328
|
+
* (术语 2026-10-29 用户拍板:结案是上位词,完成只指正常结案)。
|
|
54505
55329
|
* 不可点,hover 给具体日期区间;数字 null(历史读不到)留 '—',不拿 0 充数。 */
|
|
54506
55330
|
const weekCard = (label, total, cancelled, from, to) => (0, react$1.createElement)(StatCard, {
|
|
54507
55331
|
label: t(label),
|
|
@@ -54516,8 +55340,22 @@ body[data-ds-dark-theme]{
|
|
|
54516
55340
|
to
|
|
54517
55341
|
})
|
|
54518
55342
|
});
|
|
54519
|
-
/** 左 8 块(2×4)+ 右趋势图。
|
|
55343
|
+
/** 左 8 块(2×4)+ 右趋势图。
|
|
55344
|
+
* 首读没到(`payload = null`)⇒ 8 块只画标题 + 「—」、图表卡里一个三点加载(跟历史页同一套,
|
|
55345
|
+
* 用户 2026-10-30:不铺骨架,加载完才出东西)。 */
|
|
54520
55346
|
const statsGrid = (payload) => {
|
|
55347
|
+
if (payload === null) return (0, react$1.createElement)("div", {
|
|
55348
|
+
className: "dtl-stats",
|
|
55349
|
+
style: statsRowStyle
|
|
55350
|
+
}, (0, react$1.createElement)("div", { className: "dtl-stats__cards" }, ...STAT_LABELS.map((label) => (0, react$1.createElement)(StatCard, {
|
|
55351
|
+
key: label,
|
|
55352
|
+
label: t(label),
|
|
55353
|
+
value: "—"
|
|
55354
|
+
}))), (0, react$1.createElement)(TrendChart, {
|
|
55355
|
+
trend: null,
|
|
55356
|
+
me: null,
|
|
55357
|
+
t
|
|
55358
|
+
}));
|
|
54521
55359
|
const view = payload.stats;
|
|
54522
55360
|
return (0, react$1.createElement)("div", {
|
|
54523
55361
|
className: "dtl-stats",
|
|
@@ -54606,8 +55444,8 @@ body[data-ds-dark-theme]{
|
|
|
54606
55444
|
onClick: onBack
|
|
54607
55445
|
}, `← ${t("backToConversation")}`), (0, react$1.createElement)("div", { style: titleStyle }, t("panelTitle"), (0, react$1.createElement)("span", {
|
|
54608
55446
|
style: buildTagStyle,
|
|
54609
|
-
title: `v0.0.
|
|
54610
|
-
}, `v0.0.
|
|
55447
|
+
title: `v0.0.126 · 261031-010833-024`
|
|
55448
|
+
}, `v0.0.126 261031-010833-024`))), (0, react$1.createElement)("div", { style: {
|
|
54611
55449
|
display: "flex",
|
|
54612
55450
|
alignItems: "center",
|
|
54613
55451
|
gap: "var(--dtl-space-3)"
|
|
@@ -54633,8 +55471,26 @@ body[data-ds-dark-theme]{
|
|
|
54633
55471
|
title: t("refresh"),
|
|
54634
55472
|
onClick: () => {
|
|
54635
55473
|
refresh();
|
|
55474
|
+
setHistoryByGran({});
|
|
55475
|
+
lastTrendRef.current = null;
|
|
55476
|
+
setHistoryError(null);
|
|
54636
55477
|
}
|
|
54637
|
-
}, state.refreshing ? t("refreshing") : t("refresh")))), viewMode === "history" ?
|
|
55478
|
+
}, state.refreshing ? t("refreshing") : t("refresh")))), viewMode === "history" ? historyError !== null ? (0, react$1.createElement)("div", { style: {
|
|
55479
|
+
color: "var(--dtl-danger)",
|
|
55480
|
+
fontSize: "var(--dtl-font-md)",
|
|
55481
|
+
paddingTop: "var(--dtl-space-3)"
|
|
55482
|
+
} }, `${t("loadFailed")}:${historyError}`) : (0, react$1.createElement)("div", {
|
|
55483
|
+
className: "dtl-stats dtl-stats--history",
|
|
55484
|
+
style: statsRowStyle
|
|
55485
|
+
}, (0, react$1.createElement)(HistoryChart, {
|
|
55486
|
+
data: shownTrend,
|
|
55487
|
+
t,
|
|
55488
|
+
gran,
|
|
55489
|
+
onGranChange: setGran
|
|
55490
|
+
}), (0, react$1.createElement)(HistoryStats, {
|
|
55491
|
+
data: shownTrend,
|
|
55492
|
+
t
|
|
55493
|
+
})) : state.status === "error" && board === null ? (0, react$1.createElement)("div", { style: {
|
|
54638
55494
|
display: "flex",
|
|
54639
55495
|
alignItems: "center",
|
|
54640
55496
|
gap: "var(--dtl-space-2)"
|
|
@@ -54647,16 +55503,30 @@ body[data-ds-dark-theme]{
|
|
|
54647
55503
|
onClick: () => {
|
|
54648
55504
|
refresh();
|
|
54649
55505
|
}
|
|
54650
|
-
}, t("retry"))) : null, viewMode === "history" ? null :
|
|
55506
|
+
}, t("retry"))) : null, viewMode === "history" ? null : statsGrid(board), viewMode === "history" ? null : regionHead, viewMode === "history" ? null : board === null ? state.status === "error" ? null : (0, react$1.createElement)("div", { className: "dtl-loading" }, (0, react$1.createElement)(Loader, {
|
|
55507
|
+
variant: "blocks",
|
|
55508
|
+
size: "xl"
|
|
55509
|
+
})) : view.rows.length === 0 ? (0, react$1.createElement)(EmptyState, {
|
|
54651
55510
|
title: t("listEmpty"),
|
|
54652
55511
|
hint: t("listEmptyHint")
|
|
54653
|
-
}) : (0, react$1.createElement)("div", null, view.rows
|
|
54654
|
-
|
|
54655
|
-
|
|
54656
|
-
|
|
54657
|
-
|
|
54658
|
-
|
|
54659
|
-
|
|
55512
|
+
}) : (0, react$1.createElement)("div", null, ...groupRows(view.rows).map((group) => {
|
|
55513
|
+
const counts = GROUP_STATS.filter((item) => group.counts[item.value] > 0).map((item) => `${t(item.label)} ${group.counts[item.value]}`).join(" · ");
|
|
55514
|
+
const shown = group.rows.slice(0, WS_LIMIT);
|
|
55515
|
+
const truncated = group.rows.length > WS_LIMIT;
|
|
55516
|
+
return (0, react$1.createElement)("div", {
|
|
55517
|
+
key: group.workspace.id,
|
|
55518
|
+
className: "dtl-group"
|
|
55519
|
+
}, (0, react$1.createElement)("div", { className: "dtl-group__head" }, (0, react$1.createElement)(SectionHead, {
|
|
55520
|
+
icon: (0, react$1.createElement)("span", { className: "dtl-group__rule" }),
|
|
55521
|
+
title: (0, react$1.createElement)("span", null, group.workspace.title, counts === "" ? null : (0, react$1.createElement)("span", { className: "dtl-group__count" }, counts))
|
|
55522
|
+
})), ...shown.map((row) => (0, react$1.createElement)(TaskRowView, {
|
|
55523
|
+
key: row.key,
|
|
55524
|
+
t,
|
|
55525
|
+
row,
|
|
55526
|
+
solo,
|
|
55527
|
+
onView: handleView
|
|
55528
|
+
})), truncated ? (0, react$1.createElement)("div", { style: limitHintStyle }, t("wsLimitHint", { n: WS_LIMIT })) : null);
|
|
55529
|
+
})), (0, react$1.createElement)("div", { className: "dtl-page-foot" }))));
|
|
54660
55530
|
}
|
|
54661
55531
|
//#endregion
|
|
54662
55532
|
//#region src/client/locales.ts
|
|
@@ -54688,14 +55558,19 @@ body[data-ds-dark-theme]{
|
|
|
54688
55558
|
statStaleTitle: "停滞 = 进行中满 {n} 天没更新",
|
|
54689
55559
|
statOverdueTitle: "逾期 = 认领后满 {n} 天还没结案",
|
|
54690
55560
|
statBacklogTitle: "积压 = 待认领满 {n} 天没人接",
|
|
54691
|
-
statWeekDone: "
|
|
54692
|
-
statLastWeekDone: "
|
|
54693
|
-
statWeekSplit: "
|
|
55561
|
+
statWeekDone: "本周结案",
|
|
55562
|
+
statLastWeekDone: "上周结案",
|
|
55563
|
+
statWeekSplit: "完成 {done} · 取消 {cancelled}",
|
|
54694
55564
|
daysNone: "—",
|
|
54695
55565
|
daysValue: "{n} 天",
|
|
54696
|
-
chartDone: "
|
|
55566
|
+
chartDone: "结案",
|
|
55567
|
+
chartClosed: "已结案",
|
|
55568
|
+
chartFinished: "完成",
|
|
55569
|
+
chartCancelled: "取消",
|
|
54697
55570
|
chartOpen: "未结",
|
|
54698
55571
|
chartAdded: "新增",
|
|
55572
|
+
chartCreatedTasks: "新建任务",
|
|
55573
|
+
chartClosedTasks: "结案任务",
|
|
54699
55574
|
chartEmpty: "还没有可统计的记录",
|
|
54700
55575
|
chartPartial: "{from} 起才有台账数据",
|
|
54701
55576
|
chartMine: "只看我的",
|
|
@@ -54722,7 +55597,7 @@ body[data-ds-dark-theme]{
|
|
|
54722
55597
|
ownerAll: "全部执行人",
|
|
54723
55598
|
listEmpty: "未找到匹配的任务记录",
|
|
54724
55599
|
listEmptyHint: "可切换状态或工作区,查看其他记录。",
|
|
54725
|
-
|
|
55600
|
+
wsLimitHint: "本工作区记录较多,此处仅列出前 {n} 条;其余记录未予显示,如需查阅请缩小筛选范围。",
|
|
54726
55601
|
ownerUnclaimed: "待认领",
|
|
54727
55602
|
timeUnknown: "时间未知",
|
|
54728
55603
|
relJustNow: "刚刚",
|
|
@@ -54732,25 +55607,39 @@ body[data-ds-dark-theme]{
|
|
|
54732
55607
|
relMonths: "{n} 个月前",
|
|
54733
55608
|
relYears: "{n} 年前",
|
|
54734
55609
|
whenSubmitted: "更新于 {time}",
|
|
54735
|
-
filterByOwner: "只看 @{name} 的任务",
|
|
54736
|
-
filterByWorkspace: "只看工作区 {name}",
|
|
54737
|
-
filterByTag: "搜索标签 #{tag}",
|
|
54738
55610
|
copyTaskId: "点击复制任务 ID",
|
|
54739
55611
|
copiedTaskId: "已复制任务 ID",
|
|
54740
55612
|
copyFailed: "复制失败",
|
|
54741
55613
|
actionClaim: "认领",
|
|
54742
55614
|
actionResume: "继续",
|
|
54743
|
-
actionFinish: "
|
|
55615
|
+
actionFinish: "完成",
|
|
54744
55616
|
actionRelease: "释放",
|
|
54745
|
-
|
|
54746
|
-
|
|
54747
|
-
|
|
54748
|
-
|
|
55617
|
+
actionCancel: "取消",
|
|
55618
|
+
tipClaim: "将该任务归入本人名下,状态置为进行中",
|
|
55619
|
+
tipResume: "恢复对该任务的推进",
|
|
55620
|
+
tipFinish: "将该任务标记为完成,并归档入历史",
|
|
55621
|
+
tipRelease: "解除本人认领,任务退回公共池",
|
|
55622
|
+
tipCancel: "将该任务标记为取消并归档,不计入完成",
|
|
54749
55623
|
viewDetail: "查看详情",
|
|
54750
55624
|
fieldCreatorStamp: "创建于 {age}",
|
|
54751
55625
|
viewModeLabel: "视图",
|
|
54752
55626
|
viewActive: "在办",
|
|
54753
|
-
viewHistory: "历史"
|
|
55627
|
+
viewHistory: "历史",
|
|
55628
|
+
historyToday: "今日",
|
|
55629
|
+
historyYesterday: "昨日",
|
|
55630
|
+
historyWeek: "本周",
|
|
55631
|
+
historyLastWeek: "上周",
|
|
55632
|
+
historyMonth: "本月",
|
|
55633
|
+
historyLastMonth: "上月",
|
|
55634
|
+
historyQuarter: "本季度",
|
|
55635
|
+
historyLastQuarter: "上季度",
|
|
55636
|
+
historyEmpty: "所选区间内没有结案记录",
|
|
55637
|
+
historyGranLabel: "粒度",
|
|
55638
|
+
historyGranDay: "日",
|
|
55639
|
+
historyGranWeek: "周",
|
|
55640
|
+
historyGranMonth: "月",
|
|
55641
|
+
historyPrev: "前 {n} {unit}",
|
|
55642
|
+
historyNext: "后 {n} {unit}"
|
|
54754
55643
|
};
|
|
54755
55644
|
/** English(与 zh 键完全对齐)。 */
|
|
54756
55645
|
const en = {
|
|
@@ -54780,14 +55669,19 @@ body[data-ds-dark-theme]{
|
|
|
54780
55669
|
statStaleTitle: "stale = active with no update for {n}+ days",
|
|
54781
55670
|
statOverdueTitle: "overdue = claimed {n}+ days ago and still open",
|
|
54782
55671
|
statBacklogTitle: "backlog = unclaimed for {n}+ days",
|
|
54783
|
-
statWeekDone: "
|
|
54784
|
-
statLastWeekDone: "
|
|
54785
|
-
statWeekSplit: "
|
|
55672
|
+
statWeekDone: "Closed this week",
|
|
55673
|
+
statLastWeekDone: "Closed last week",
|
|
55674
|
+
statWeekSplit: "Done {done} · Cancelled {cancelled}",
|
|
54786
55675
|
daysNone: "—",
|
|
54787
55676
|
daysValue: "{n}d",
|
|
54788
|
-
chartDone: "
|
|
55677
|
+
chartDone: "Closed",
|
|
55678
|
+
chartClosed: "Closed",
|
|
55679
|
+
chartFinished: "Done",
|
|
55680
|
+
chartCancelled: "Cancelled",
|
|
54789
55681
|
chartOpen: "Open",
|
|
54790
55682
|
chartAdded: "Added",
|
|
55683
|
+
chartCreatedTasks: "Created",
|
|
55684
|
+
chartClosedTasks: "Closed",
|
|
54791
55685
|
chartEmpty: "No records to chart yet",
|
|
54792
55686
|
chartPartial: "Ledger data starts {from}",
|
|
54793
55687
|
chartMine: "Only mine",
|
|
@@ -54814,7 +55708,7 @@ body[data-ds-dark-theme]{
|
|
|
54814
55708
|
ownerAll: "Anyone",
|
|
54815
55709
|
listEmpty: "No matching task records",
|
|
54816
55710
|
listEmptyHint: "Switch status or workspace to see other records.",
|
|
54817
|
-
|
|
55711
|
+
wsLimitHint: "This workspace has more records than shown; only the first {n} are listed. Narrow the filters to see the rest.",
|
|
54818
55712
|
ownerUnclaimed: "unclaimed",
|
|
54819
55713
|
timeUnknown: "unknown time",
|
|
54820
55714
|
relJustNow: "just now",
|
|
@@ -54824,25 +55718,39 @@ body[data-ds-dark-theme]{
|
|
|
54824
55718
|
relMonths: "{n} mo ago",
|
|
54825
55719
|
relYears: "{n} y ago",
|
|
54826
55720
|
whenSubmitted: "updated {time}",
|
|
54827
|
-
filterByOwner: "Only tasks owned by @{name}",
|
|
54828
|
-
filterByWorkspace: "Only workspace {name}",
|
|
54829
|
-
filterByTag: "Search tag #{tag}",
|
|
54830
55721
|
copyTaskId: "Click to copy task ID",
|
|
54831
55722
|
copiedTaskId: "Task ID copied",
|
|
54832
55723
|
copyFailed: "Copy failed",
|
|
54833
55724
|
actionClaim: "Claim",
|
|
54834
55725
|
actionResume: "Resume",
|
|
54835
|
-
actionFinish: "
|
|
55726
|
+
actionFinish: "Finish",
|
|
54836
55727
|
actionRelease: "Release",
|
|
54837
|
-
|
|
54838
|
-
|
|
54839
|
-
|
|
54840
|
-
|
|
55728
|
+
actionCancel: "Cancel",
|
|
55729
|
+
tipClaim: "assign this task to me and set it to in progress",
|
|
55730
|
+
tipResume: "resume work on this task",
|
|
55731
|
+
tipFinish: "mark this task as done and archive it",
|
|
55732
|
+
tipRelease: "drop my claim and return the task to the public pool",
|
|
55733
|
+
tipCancel: "mark this task as cancelled and archive it; not counted as done",
|
|
54841
55734
|
viewDetail: "View details",
|
|
54842
55735
|
fieldCreatorStamp: "created {age}",
|
|
54843
55736
|
viewModeLabel: "View",
|
|
54844
55737
|
viewActive: "Active",
|
|
54845
|
-
viewHistory: "History"
|
|
55738
|
+
viewHistory: "History",
|
|
55739
|
+
historyToday: "Today",
|
|
55740
|
+
historyYesterday: "Yesterday",
|
|
55741
|
+
historyWeek: "This week",
|
|
55742
|
+
historyLastWeek: "Last week",
|
|
55743
|
+
historyMonth: "This month",
|
|
55744
|
+
historyLastMonth: "Last month",
|
|
55745
|
+
historyQuarter: "This quarter",
|
|
55746
|
+
historyLastQuarter: "Last quarter",
|
|
55747
|
+
historyEmpty: "No closed tasks in the selected range",
|
|
55748
|
+
historyGranLabel: "Granularity",
|
|
55749
|
+
historyGranDay: "Day",
|
|
55750
|
+
historyGranWeek: "Week",
|
|
55751
|
+
historyGranMonth: "Month",
|
|
55752
|
+
historyPrev: "Previous {n} {unit}s",
|
|
55753
|
+
historyNext: "Next {n} {unit}s"
|
|
54846
55754
|
};
|
|
54847
55755
|
/** 把宿主给的无参 t 包成带占位符替换的 t(模板一律 `{name}`,不依赖宿主是否支持 params)。 */
|
|
54848
55756
|
function interpolateTranslate(base) {
|