dsh-task-ledger 0.0.66 → 0.0.68

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 CHANGED
@@ -202,7 +202,7 @@ window.__ModuleLoader__.load({
202
202
  finish: false,
203
203
  release: false
204
204
  };
205
- /** 状态档命中(积压 / 超期 / 停滞由 host 标记,前端不判阈值)——只作用于第二区。 */
205
+ /** 状态档命中(积压 / 逾期 / 停滞由 host 标记,前端不判阈值)——只作用于第二区。 */
206
206
  function statusHit(task, status) {
207
207
  if (status === "all") return true;
208
208
  if (status === "active") return task.status === "doing" || task.status === "blocked";
@@ -378,7 +378,7 @@ body{
378
378
  /* ⚠️ 宿主是 state-warn(不是 state-warning,后者无此定义) */
379
379
  --dtl-warning:var(--dsw-alias-state-warn-primary,#f59e0b);
380
380
  --dtl-danger:var(--dsw-alias-state-error-primary,#ec1313);
381
- /* 超期橙:在「积压黄」与「停滞红」之间再取一档(语义阶梯 灰→黄→橙→红),
381
+ /* 逾期橙:在「积压黄」与「停滞红」之间再取一档(语义阶梯 灰→黄→橙→红),
382
382
  宿主没有现成的橙 token ⇒ 用 warn + error 两色现算,主题一换自动跟随 */
383
383
  --dtl-overdue:color-mix(in srgb,var(--dtl-warning) 55%,var(--dtl-danger));
384
384
  --dtl-link:var(--dsw-alias-link,#3b5bdb);
@@ -667,7 +667,7 @@ body[data-ds-dark-theme]{
667
667
  /* 「查看」钮在表格行里也要常驻布局(display:none 会不算宽度 ⇒ hover 一出就又把行撑开) */
668
668
  .dtl-orow .dtl-viewbtn{display:inline-flex;visibility:hidden;}
669
669
  .dtl-orow:hover .dtl-viewbtn{visibility:visible;}
670
- /* 行首状态圆点:灰=待认领 / 浅蓝=进行中(比「我的」蓝灰一档)/ 黄=积压 / 橙=超期 / 红=停滞;
670
+ /* 行首状态圆点:灰=待认领 / 浅蓝=进行中(比「我的」蓝灰一档)/ 黄=积压 / 橙=逾期 / 红=停滞;
671
671
  6px(用户 2026-10-18:8px 太大) */
672
672
  .dtl-dot{display:inline-block;width:6px;height:6px;flex:none;border-radius:50%;}
673
673
  .dtl-dot--doing{background:var(--dtl-business-dim);}
@@ -724,7 +724,7 @@ body[data-ds-dark-theme]{
724
724
  background:var(--dtl-chip-bg);color:var(--dtl-fg-3);font-size:10px;line-height:16px;
725
725
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;vertical-align:middle;}
726
726
  /* 状态四色 = **实心色块**(用户 2026-10-18:彩色字看不清 ⇒ 改色块 + 反色字):
727
- 待认领灰 / 进行中蓝 / 积压黄 / 超期橙 / 停滞红(与行首圆点同色系)。
727
+ 待认领灰 / 进行中蓝 / 积压黄 / 逾期橙 / 停滞红(与行首圆点同色系)。
728
728
  红黄蓝都是中调 ⇒ 白字两个主题都可读;灰块用「字色底 + 面色字」⇒ 明暗自动反过来 */
729
729
  .dtl-tag--open{background:var(--dtl-fg-3);color:var(--dtl-surface-1);font-weight:600;}
730
730
  .dtl-tag--doing{background:var(--dtl-business);color:var(--dtl-on-signal);font-weight:600;}
@@ -769,7 +769,7 @@ body[data-ds-dark-theme]{
769
769
  两栏**完全等高**:cards 两行 minmax(0,1fr) 均分 + 卡 height:100% ⇒ 图表卡与左边一样高。 */
770
770
  /* 左 8 块略收窄、右图表略放宽(用户 2026-10-17:左再短一丢丢、右长一丢丢) */
771
771
  .dtl-stats{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(0,1fr);gap:var(--dtl-space-3);align-items:stretch;}
772
- .dtl-stats__cards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));grid-template-rows:repeat(2,minmax(0,1fr));
772
+ .dtl-stats__cards{display:grid;grid-auto-flow:column;grid-template-columns:repeat(4,minmax(0,1fr));grid-template-rows:repeat(2,minmax(0,1fr));
773
773
  gap:var(--dtl-space-3);}
774
774
  .dtl-stats__cards > .dtl-stat{height:100%;box-sizing:border-box;}
775
775
  @media (max-width:960px){.dtl-stats{grid-template-columns:minmax(0,1fr);}}
@@ -1088,7 +1088,7 @@ body[data-ds-dark-theme]{
1088
1088
  * + **执行人列**(原状态位,有执行人才摆 `@名字` 标签)+ 最右「@创建人 创建于 年-月-日 时:分:秒」
1089
1089
  * (悬停掉时分秒并让位给操作钮)+ 查看。
1090
1090
  * 状态一律**标签型、五色**(用户 2026-10-18:原来是一排素字 / pill,现在与人员**位置互换**):
1091
- * 灰=待认领 / 蓝=进行中 / 黄=积压 / 橙=超期 / 红=停滞;三个异常标签悬停给**配置出来的**
1091
+ * 灰=待认领 / 蓝=进行中 / 黄=积压 / 橙=逾期 / 红=停滞;三个异常标签悬停给**配置出来的**
1092
1092
  * 阈值解释(staleDays / overdueDays / backlogDays 由 host 下发)。圆点颜色同色系。
1093
1093
  *
1094
1094
  * 按钮(含查看)**不各判各的**:权限一律问 `resolveActions()`(rows.ts),本文件只按返回值画。
@@ -1101,7 +1101,8 @@ body[data-ds-dark-theme]{
1101
1101
  const title = row.record.workpackage ?? row.record.summary;
1102
1102
  return title !== void 0 && title !== "" ? title : row.record.src ?? "—";
1103
1103
  }
1104
- /** 状态语义(异常优先:停滞 > 超期 > 积压;三者都是 host 按时间算出来的,不是状态)。 */
1104
+ /** 状态语义(异常优先:停滞 > 逾期 > 积压;三者都是 host 按时间算出来的,不是状态)。
1105
+ * 只决定圆点 / 左缘色条这类**单色位**——标签可以多枚,见 MARKS。 */
1105
1106
  function toneOf(row) {
1106
1107
  if (row.kind !== "task") return "closed";
1107
1108
  if (row.task.stale === true) return "stale";
@@ -1110,6 +1111,13 @@ body[data-ds-dark-theme]{
1110
1111
  if (row.task.status === "open") return "open";
1111
1112
  return "doing";
1112
1113
  }
1114
+ /** 三个异常标记**可叠加**(用户 2026-10-19):一条任务能同时逾期 + 停滞,两枚标签都要摆。
1115
+ * 积压与逾期 / 停滞不会共存(前者是待认领,后两者是进行中),故最多 2 枚。 */
1116
+ const MARKS = [
1117
+ "backlog",
1118
+ "overdue",
1119
+ "stale"
1120
+ ];
1113
1121
  /** 状态文案(已结案没有在办状态 ⇒ 不给标签)。 */
1114
1122
  function statusLabel(tone, t) {
1115
1123
  if (tone === "stale") return t("statusStale");
@@ -1195,12 +1203,13 @@ body[data-ds-dark-theme]{
1195
1203
  tip: tip ?? detailTip(which)
1196
1204
  });
1197
1205
  };
1198
- const statusTag = tone === "closed" ? null : tagOf(tone);
1199
- const alarmTag = tone === "backlog" || tone === "overdue" || tone === "stale" ? tagOf(tone) : null;
1206
+ const markTones = isTask ? MARKS.filter((which) => row.task[which] === true) : [];
1207
+ const statusTags = tone === "closed" ? [] : (markTones.length > 0 ? markTones : [tone]).map((which) => tagOf(which));
1208
+ const alarmTags = markTones.map((which) => tagOf(which));
1200
1209
  const titleLine = (0, react.createElement)("div", { className: "dtl-taskrow__l1" }, (0, react.createElement)("span", {
1201
1210
  className: "dtl-taskrow__title dtl-ellipsis",
1202
1211
  title: titleOf(row)
1203
- }, titleOf(row)), createdDay === null ? null : (0, react.createElement)("span", { className: "dtl-taskrow__stamp" }, `[${t("fieldCreatedStamp", { day: createdDay })}]`), alarmTag);
1212
+ }, titleOf(row)), createdDay === null ? null : (0, react.createElement)("span", { className: "dtl-taskrow__stamp" }, `[${t("fieldCreatedStamp", { day: createdDay })}]`), ...alarmTags);
1204
1213
  const orowTitleLine = (0, react.createElement)("div", { className: "dtl-orow__title" }, (0, react.createElement)("span", {
1205
1214
  className: "dtl-orow__name dtl-ellipsis",
1206
1215
  title: titleOf(row)
@@ -1216,7 +1225,7 @@ body[data-ds-dark-theme]{
1216
1225
  who: String(owner),
1217
1226
  when: startedOk ? formatDateTime(String(row.task.started)) : t("timeUnknown")
1218
1227
  });
1219
- const tagLine = (0, react.createElement)("div", { className: "dtl-orow__tags" }, statusTag, tags.map((tag) => (0, react.createElement)(Tag, {
1228
+ const tagLine = (0, react.createElement)("div", { className: "dtl-orow__tags" }, ...statusTags, tags.map((tag) => (0, react.createElement)(Tag, {
1220
1229
  key: tag,
1221
1230
  text: `#${tag}`
1222
1231
  })));
@@ -1249,7 +1258,7 @@ body[data-ds-dark-theme]{
1249
1258
  //#endregion
1250
1259
  //#region src/client/board-home.ts
1251
1260
  /**
1252
- * 看板首页(`main` 槽整页内容):6 统计卡 + 近 8 周趋势图 + 两区任务列表。
1261
+ * 看板首页(`main` 槽整页内容):8 统计卡 + 近 8 周趋势图 + 两区任务列表。
1253
1262
  * 定稿见 docs/design/features/board-home.md §二(2026-10-17 专家组改版);
1254
1263
  * 按钮矩阵归「任务按钮与会话交接」任务(写入路径 A/B 未拍板),本页**不画**任务动作按钮。
1255
1264
  *
@@ -1332,12 +1341,12 @@ body[data-ds-dark-theme]{
1332
1341
  value: id,
1333
1342
  label: title
1334
1343
  }))], [board, t]);
1335
- const days = (value) => value === null || value === void 0 ? t("daysNone") : t("daysValue", { n: value });
1336
1344
  /** 统计卡:纯展示(用户 2026-10-17:先全去掉点击,界面定稿后再议滚动 / 筛选联动)。 */
1337
- const card = (label, value, hint) => (0, react.createElement)(StatCard, {
1345
+ const card = (label, value, hint, title) => (0, react.createElement)(StatCard, {
1338
1346
  label: t(label),
1339
1347
  value,
1340
1348
  hint,
1349
+ title,
1341
1350
  interactive: false
1342
1351
  });
1343
1352
  /** 统计台卡:不可点(首页没有已结案可筛),hover 给具体日期区间。
@@ -1413,21 +1422,7 @@ body[data-ds-dark-theme]{
1413
1422
  }, state.refreshing ? t("refreshing") : t("refresh")))), tab === "stats" ? (0, react.createElement)("div", { style: hintStyle }, t("statsPlaceholder")) : (0, react.createElement)("div", null, stats === void 0 ? null : (0, react.createElement)("div", {
1414
1423
  className: "dtl-stats",
1415
1424
  style: statsRowStyle
1416
- }, (0, react.createElement)("div", { className: "dtl-stats__cards" }, card("statMyActive", stats.myActive, t("statMyActiveHint", { n: stats.myOverdue })), card("statOpen", stats.open, t("statOpenHint", { n: days(stats.oldestOpenDays) })), card("statDoing", stats.doing, t("statDoingHint", { n: stats.doing - stats.myActive })), (0, react.createElement)(StatCard, {
1417
- label: t("statAlarm"),
1418
- value: stats.backlog + stats.overdue + stats.stale,
1419
- hint: t("statAlarmSplit", {
1420
- backlog: stats.backlog,
1421
- overdue: stats.overdue,
1422
- stale: stats.stale
1423
- }),
1424
- title: [
1425
- t("statBacklogTitle", { n: stats.backlogDays }),
1426
- t("statOverdueTitle", { n: stats.overdueDays }),
1427
- t("statStaleTitle", { n: stats.staleDays })
1428
- ].join(";"),
1429
- interactive: false
1430
- }), periodCard("statWeekDone", periods?.thisWeek), periodCard("statLastWeekDone", periods?.lastWeek), periodCard("statMonthDone", periods?.thisMonth), periodCard("statLastMonthDone", periods?.lastMonth)), (0, react.createElement)("div", {
1425
+ }, (0, react.createElement)("div", { className: "dtl-stats__cards" }, card("statMyActive", stats.myActive, [stats.myOverdue > 0 ? t("statMyOverdueHint", { n: stats.myOverdue }) : null, stats.myStale > 0 ? t("statMyStaleHint", { n: stats.myStale }) : null].filter((part) => part !== null).join(" | ")), card("statDoing", stats.doing, stats.doing - stats.myActive > 0 ? t("statDoingHint", { n: stats.doing - stats.myActive }) : t("statDoingAllMine")), card("statOpen", stats.open, stats.oldestOpenDays === null ? "" : t("statOpenHint", { n: stats.oldestOpenDays })), card("statBacklog", stats.backlog, stats.backlog > 0 && stats.open > 0 ? t("statBacklogHint", { n: Math.round(stats.backlog / stats.open * 100) }) : "", t("statBacklogTitle", { n: stats.backlogDays })), card("statOverdue", stats.overdue, stats.maxOverdueAge === null ? "" : t("statOverdueHint", { n: stats.maxOverdueAge }), t("statOverdueTitle", { n: stats.overdueDays })), card("statStale", stats.stale, stats.maxStaleIdle === null ? "" : t("statStaleHint", { n: stats.maxStaleIdle }), t("statStaleTitle", { n: stats.staleDays })), periodCard("statWeekDone", periods?.thisWeek), periodCard("statLastWeekDone", periods?.lastWeek)), (0, react.createElement)("div", {
1431
1426
  className: "dtl-card",
1432
1427
  style: chartCardStyle
1433
1428
  }, (0, react.createElement)("div", { style: {
@@ -1611,7 +1606,7 @@ body[data-ds-dark-theme]{
1611
1606
  }
1612
1607
  /** 一个工作区分组(全部待办表格段):段头(点+名+统计)→ 列头行 → 任务行。
1613
1608
  * 统计口径(用户 2026-10-18):共 N|待办 N|进行中 N 常显(0 也显);
1614
- * 积压 / 超期 / 停滞**只在 >0 时出现**。 */
1609
+ * 积压 / 逾期 / 停滞**只在 >0 时出现**。 */
1615
1610
  function WorkspaceGroupView(props) {
1616
1611
  const { t, group, board } = props;
1617
1612
  const [open, setOpen] = (0, react.useState)(group.rows.length <= GROUP_COLLAPSE_OVER);
@@ -1660,23 +1655,25 @@ body[data-ds-dark-theme]{
1660
1655
  degradedItem: "{title}:{message}",
1661
1656
  statsPlaceholder: "统计报表尚未开建(另立任务):这里以后放分类分布、按人完成数、时间线。",
1662
1657
  statMyActive: "我的待办",
1663
- statMyActiveHint: "超期 {n} 条",
1658
+ statMyOverdueHint: "逾期 {n}",
1659
+ statMyStaleHint: "停滞 {n}",
1664
1660
  statOpen: "待认领",
1665
- statOpenHint: "最长未认领 {n}",
1661
+ statOpenHint: "最长等待 {n} 天",
1666
1662
  statDoing: "进行中",
1667
- statDoingHint: "其他成员负责 {n} 条",
1668
- statAlarm: "积压 · 超期 · 停滞",
1669
- statStaleWord: "停滞",
1670
- statStaleHint: "{n} 条",
1671
- statAlarmSplit: "积压 {backlog} | 超期 {overdue} | 停滞 {stale}",
1663
+ statDoingHint: "他人在办 {n}",
1664
+ statDoingAllMine: "均为我负责",
1665
+ statBacklog: "积压",
1666
+ statOverdue: "逾期",
1667
+ statStale: "停滞",
1668
+ statBacklogHint: "占待认领 {n}%",
1669
+ statOverdueHint: "最长 {n} 天未结",
1670
+ statStaleHint: "最长 {n} 天未更新",
1672
1671
  statStaleTitle: "停滞 = 进行中满 {n} 天没更新",
1673
- statOverdueTitle: "超期 = 认领后满 {n} 天还没结案",
1672
+ statOverdueTitle: "逾期 = 认领后满 {n} 天还没结案",
1674
1673
  statBacklogTitle: "积压 = 待认领满 {n} 天没人接",
1675
1674
  statWeekDone: "本周完成",
1676
1675
  statLastWeekDone: "上周完成",
1677
- statMonthDone: "本月完成",
1678
- statLastMonthDone: "上月完成",
1679
- statCreatedHint: "新增 {n} 条",
1676
+ statCreatedHint: "新增 {n}",
1680
1677
  daysNone: "—",
1681
1678
  daysValue: "{n} 天",
1682
1679
  chartTitle: "近 8 周",
@@ -1701,12 +1698,12 @@ body[data-ds-dark-theme]{
1701
1698
  statusActive: "进行中",
1702
1699
  statusOpen: "待认领",
1703
1700
  statusBacklog: "积压",
1704
- statusOverdue: "超期",
1701
+ statusOverdue: "逾期",
1705
1702
  statusStale: "停滞",
1706
1703
  tipOpen: "任务创建于 {created}\n尚未有人认领",
1707
1704
  tipBacklog: "任务创建于 {created}\n无人认领已满 {d}",
1708
1705
  tipDoing: "{who}\n开始执行:{started}\n最后更新:{updated}",
1709
- tipOverdue: "{who}\n开始执行:{started}\n最后更新:{updated}\n任务已开始 {d}",
1706
+ tipOverdue: "{who}\n开始执行:{started}\n最后更新:{updated}\n已逾期 {d}",
1710
1707
  tipStale: "{who}\n开始执行:{started}\n最后更新:{updated}\n已停滞 {d}",
1711
1708
  workspaceLabel: "工作区",
1712
1709
  workspaceAll: "全部工作区",
@@ -1718,7 +1715,7 @@ body[data-ds-dark-theme]{
1718
1715
  groupOpen: "待办 {n} 条",
1719
1716
  groupDoing: "进行中 {n} 条",
1720
1717
  groupBacklog: "积压 {n} 条",
1721
- groupOverdue: "超期 {n} 条",
1718
+ groupOverdue: "逾期 {n} 条",
1722
1719
  groupStale: "停滞 {n} 条",
1723
1720
  colTask: "任务",
1724
1721
  colCreator: "创建人",
@@ -1783,22 +1780,24 @@ body[data-ds-dark-theme]{
1783
1780
  degradedItem: "{title}: {message}",
1784
1781
  statsPlaceholder: "Stats reports are not built yet (separate task): category breakdown, completions by person, timeline.",
1785
1782
  statMyActive: "My todos",
1786
- statMyActiveHint: "overdue {n}",
1783
+ statMyOverdueHint: "overdue {n}",
1784
+ statMyStaleHint: "stale {n}",
1787
1785
  statOpen: "Unclaimed",
1788
- statOpenHint: "longest unclaimed {n}",
1786
+ statOpenHint: "longest waiting {n} days",
1789
1787
  statDoing: "In progress",
1790
- statDoingHint: "owned by other members: {n}",
1791
- statAlarm: "Backlog · Overdue · Stale",
1792
- statStaleWord: "Stale",
1793
- statStaleHint: "{n}",
1794
- statAlarmSplit: "{backlog} backlog | {overdue} overdue | {stale} stale",
1788
+ statDoingHint: "others: {n}",
1789
+ statDoingAllMine: "all mine",
1790
+ statBacklog: "Backlog",
1791
+ statOverdue: "Overdue",
1792
+ statStale: "Stale",
1793
+ statBacklogHint: "{n}% of unclaimed",
1794
+ statOverdueHint: "longest {n} days open",
1795
+ statStaleHint: "longest {n} days idle",
1795
1796
  statStaleTitle: "stale = active with no update for {n}+ days",
1796
1797
  statOverdueTitle: "overdue = claimed {n}+ days ago and still open",
1797
1798
  statBacklogTitle: "backlog = unclaimed for {n}+ days",
1798
1799
  statWeekDone: "Done this week",
1799
1800
  statLastWeekDone: "Done last week",
1800
- statMonthDone: "Done this month",
1801
- statLastMonthDone: "Done last month",
1802
1801
  statCreatedHint: "{n} created",
1803
1802
  daysNone: "—",
1804
1803
  daysValue: "{n}d",
@@ -1829,7 +1828,7 @@ body[data-ds-dark-theme]{
1829
1828
  tipOpen: "Created on {created}\nNot claimed yet",
1830
1829
  tipBacklog: "Created on {created}\nUnclaimed for {d}",
1831
1830
  tipDoing: "{who}\nStarted: {started}\nLast updated: {updated}",
1832
- tipOverdue: "{who}\nStarted: {started}\nLast updated: {updated}\nActive for {d}",
1831
+ tipOverdue: "{who}\nStarted: {started}\nLast updated: {updated}\nOverdue by {d}",
1833
1832
  tipStale: "{who}\nStarted: {started}\nLast updated: {updated}\nStalled for {d}",
1834
1833
  workspaceLabel: "Workspace",
1835
1834
  workspaceAll: "All workspaces",