dsh-task-ledger 0.0.8 → 0.0.10
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 +220 -76
- package/dist/client.js.map +1 -1
- package/dist/host/board.d.ts +38 -17
- package/dist/host/board.js +140 -57
- package/dist/host/routes.js +4 -5
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -536,6 +536,39 @@ body[data-ds-dark-theme]{
|
|
|
536
536
|
/* 过程正文:宽度受限、长行折行 */
|
|
537
537
|
.dtl-worklog{max-width:72ch;font-size:var(--dtl-font-md);line-height:1.6}
|
|
538
538
|
|
|
539
|
+
/* 统计区整体:左 8 块(2 行 × 4 列)+ 右趋势图(参考图同款分栏)。
|
|
540
|
+
⚠️ 列数写死 4 → 2,绝不给 3:3 列会排出 3+1 的非对称(用户 2026-10-17)。 */
|
|
541
|
+
.dtl-stats{display:grid;grid-template-columns:minmax(0,2fr) minmax(0,1fr);gap:var(--dtl-space-3);align-items:stretch;}
|
|
542
|
+
.dtl-stats__cards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));grid-template-rows:repeat(2,auto);
|
|
543
|
+
gap:var(--dtl-space-3);align-content:start;}
|
|
544
|
+
@media (max-width:960px){.dtl-stats{grid-template-columns:minmax(0,1fr);}}
|
|
545
|
+
@media (max-width:640px){.dtl-stats__cards{grid-template-columns:repeat(2,minmax(0,1fr));}}
|
|
546
|
+
|
|
547
|
+
/* 趋势分组柱状图:细柱 + y 轴刻度 + 网格线 + 柱顶数值 + 均值虚线(参考图信息密度) */
|
|
548
|
+
.dtl-gchart{position:relative;height:104px;border-bottom:1px solid var(--dtl-border);}
|
|
549
|
+
.dtl-gchart__grid{position:absolute;left:0;right:0;border-top:1px solid var(--dtl-border-faint);pointer-events:none;}
|
|
550
|
+
.dtl-gchart__ytick{position:absolute;left:0;width:26px;text-align:right;font-size:10px;line-height:12px;
|
|
551
|
+
color:var(--dtl-fg-3);transform:translateY(50%);font-variant-numeric:tabular-nums;}
|
|
552
|
+
.dtl-gchart__avg{position:absolute;left:0;right:0;border-top:1px dashed var(--dtl-border-strong);pointer-events:none;}
|
|
553
|
+
.dtl-gchart__avgtag{position:absolute;right:0;font-size:10px;line-height:12px;color:var(--dtl-fg-3);
|
|
554
|
+
background:var(--dtl-surface-1);padding:0 2px;transform:translateY(-100%);}
|
|
555
|
+
.dtl-gchart__col{position:absolute;top:0;bottom:0;min-width:0;}
|
|
556
|
+
.dtl-gchart__pair{position:absolute;bottom:0;left:50%;transform:translateX(-50%);
|
|
557
|
+
display:flex;align-items:flex-end;gap:2px;}
|
|
558
|
+
.dtl-gchart__bar{width:8px;min-height:0;border-radius:var(--dtl-radius-xs) var(--dtl-radius-xs) 0 0;}
|
|
559
|
+
.dtl-gchart__bar--done{background:var(--dtl-business);}
|
|
560
|
+
.dtl-gchart__bar--created{background:var(--dtl-chip-bg);}
|
|
561
|
+
.dtl-gchart__col:hover .dtl-gchart__bar--done{background:var(--dtl-accent);}
|
|
562
|
+
.dtl-gchart__val{position:absolute;left:50%;transform:translateX(-50%);font-size:10px;line-height:12px;
|
|
563
|
+
color:var(--dtl-fg-2);font-variant-numeric:tabular-nums;white-space:nowrap;}
|
|
564
|
+
.dtl-gchart__label{position:absolute;left:0;right:0;bottom:-16px;text-align:center;
|
|
565
|
+
font-size:10px;line-height:14px;color:var(--dtl-fg-3);white-space:nowrap;}
|
|
566
|
+
.dtl-gchart-legend{display:flex;align-items:center;gap:var(--dtl-space-3);font-size:var(--dtl-font-xs);color:var(--dtl-fg-2);}
|
|
567
|
+
.dtl-gchart-legend i{display:inline-block;width:8px;height:8px;border-radius:2px;margin-right:4px;}
|
|
568
|
+
|
|
569
|
+
/* 过程正文:宽度受限、长行折行 */
|
|
570
|
+
.dtl-worklog{max-width:72ch;font-size:var(--dtl-font-md);line-height:1.6}
|
|
571
|
+
|
|
539
572
|
/* 趋势柱状图:div 柱 + token 色,无新依赖 */
|
|
540
573
|
.dtl-chart{display:flex;align-items:flex-end;gap:var(--dtl-space-2);height:120px;}
|
|
541
574
|
.dtl-chart__col{display:flex;flex-direction:column;justify-content:flex-end;align-items:center;gap:var(--dtl-space-1);flex:1 1 0;height:100%;min-width:0;}
|
|
@@ -619,19 +652,24 @@ body[data-ds-dark-theme]{
|
|
|
619
652
|
}
|
|
620
653
|
});
|
|
621
654
|
}
|
|
622
|
-
/** 统计卡:主数字 + 灰色口径小字;点一下联动下方列表筛选。
|
|
655
|
+
/** 统计卡:主数字 + 灰色口径小字;点一下联动下方列表筛选。
|
|
656
|
+
* `value` 为 0 时显示「—」(用户 2026-10-17 定稿:0 会被读成「没数据 / 出错了」);
|
|
657
|
+
* `hint` 可以是富文本(如把「停滞」两字标红);
|
|
658
|
+
* `interactive: false` = 纯展示卡(统计台:首页没有已结案可筛,不装可点)。 */
|
|
623
659
|
function StatCard(props) {
|
|
624
660
|
ensureUiBase();
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
"
|
|
661
|
+
const interactive = props.interactive !== false && props.onClick !== void 0;
|
|
662
|
+
const shown = props.value === 0 || props.value === "0" ? "—" : String(props.value);
|
|
663
|
+
return (0, react.createElement)(interactive ? "button" : "div", {
|
|
664
|
+
type: interactive ? "button" : void 0,
|
|
665
|
+
className: `dtl-card dtl-stat${interactive ? " dtl-card--clickable" : ""}`,
|
|
666
|
+
"data-active": props.active === true,
|
|
629
667
|
title: props.title,
|
|
630
|
-
onClick: props.onClick
|
|
668
|
+
onClick: interactive ? props.onClick : void 0
|
|
631
669
|
}, (0, react.createElement)("span", { style: {
|
|
632
670
|
fontSize: "var(--dtl-font-sm)",
|
|
633
671
|
color: "var(--dtl-fg-2)"
|
|
634
|
-
} }, props.label), (0, react.createElement)("span", { className: "dtl-stat__value" },
|
|
672
|
+
} }, props.label), (0, react.createElement)("span", { className: "dtl-stat__value" }, shown), props.hint === void 0 || props.hint === null || props.hint === "" ? null : (0, react.createElement)("span", { className: "dtl-stat__hint" }, props.hint));
|
|
635
673
|
}
|
|
636
674
|
/** chip(分类 / 标签 / 工作区名)。 */
|
|
637
675
|
function Chip(props) {
|
|
@@ -658,25 +696,69 @@ body[data-ds-dark-theme]{
|
|
|
658
696
|
color: "var(--dtl-fg-2)"
|
|
659
697
|
} }, props.hint));
|
|
660
698
|
}
|
|
661
|
-
/**
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
699
|
+
/** 千位压缩(1.2k / 12k):y 轴刻度与柱顶数值用,避免 4 位数把刻度挤宽。 */
|
|
700
|
+
function compactCount(value) {
|
|
701
|
+
if (value >= 1e4) return `${Math.round(value / 1e3)}k`;
|
|
702
|
+
if (value >= 1e3) return `${(value / 1e3).toFixed(1)}k`;
|
|
703
|
+
return String(value);
|
|
704
|
+
}
|
|
705
|
+
/** 分组柱状图(div 柱,无新依赖):完成 / 新增各一细柱,y 轴三档刻度 + 网格线 + 柱顶数值 + 均值虚线。
|
|
706
|
+
* 列 / 柱 / 标签全部相对 104px 绘图区绝对定位 ⇒ 与刻度同一基准,不会各算各的高度。 */
|
|
707
|
+
function GroupedBarChart(props) {
|
|
666
708
|
ensureUiBase();
|
|
667
|
-
const
|
|
668
|
-
|
|
669
|
-
|
|
709
|
+
const plotHeight = 104;
|
|
710
|
+
const top = Math.max(1, props.weeks.reduce((peak, week) => Math.max(peak, week.done, week.created), 0));
|
|
711
|
+
const doneTotal = props.weeks.reduce((sum, week) => sum + week.done, 0);
|
|
712
|
+
const avg = props.weeks.length === 0 ? 0 : doneTotal / props.weeks.length;
|
|
713
|
+
const ticks = [
|
|
714
|
+
0,
|
|
715
|
+
top / 2,
|
|
716
|
+
top
|
|
717
|
+
];
|
|
718
|
+
const heightOf = (value) => Math.round(value / top * plotHeight);
|
|
719
|
+
const columnStyle = (index) => ({
|
|
720
|
+
left: `${index / props.weeks.length * 100}%`,
|
|
721
|
+
right: `${(props.weeks.length - index - 1) / props.weeks.length * 100}%`
|
|
722
|
+
});
|
|
723
|
+
return (0, react.createElement)("div", { style: {
|
|
724
|
+
position: "relative",
|
|
725
|
+
paddingLeft: "30px",
|
|
726
|
+
paddingBottom: "18px"
|
|
727
|
+
} }, (0, react.createElement)("div", {
|
|
728
|
+
className: "dtl-gchart",
|
|
670
729
|
role: "img",
|
|
671
730
|
"aria-label": props.ariaLabel
|
|
672
|
-
},
|
|
673
|
-
key:
|
|
674
|
-
className: "dtl-
|
|
675
|
-
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
731
|
+
}, ticks.map((tick) => (0, react.createElement)("div", {
|
|
732
|
+
key: `grid-${String(tick)}`,
|
|
733
|
+
className: "dtl-gchart__grid",
|
|
734
|
+
style: { bottom: `${heightOf(tick)}px` }
|
|
735
|
+
})), ticks.map((tick) => (0, react.createElement)("span", {
|
|
736
|
+
key: `tick-${String(tick)}`,
|
|
737
|
+
className: "dtl-gchart__ytick",
|
|
738
|
+
style: { bottom: `${heightOf(tick)}px` }
|
|
739
|
+
}, compactCount(Math.round(tick)))), avg > 0 ? (0, react.createElement)("div", {
|
|
740
|
+
className: "dtl-gchart__avg",
|
|
741
|
+
style: { bottom: `${heightOf(avg)}px` }
|
|
742
|
+
}, (0, react.createElement)("span", { className: "dtl-gchart__avgtag" }, props.avgLabel)) : null, props.weeks.map((week, index) => (0, react.createElement)("div", {
|
|
743
|
+
key: week.label,
|
|
744
|
+
className: "dtl-gchart__col",
|
|
745
|
+
style: columnStyle(index),
|
|
746
|
+
title: week.title
|
|
747
|
+
}, (0, react.createElement)("div", { className: "dtl-gchart__pair" }, (0, react.createElement)("span", {
|
|
748
|
+
className: "dtl-gchart__bar dtl-gchart__bar--done",
|
|
749
|
+
style: { height: `${heightOf(week.done)}px` }
|
|
750
|
+
}), (0, react.createElement)("span", {
|
|
751
|
+
className: "dtl-gchart__bar dtl-gchart__bar--created",
|
|
752
|
+
style: { height: `${heightOf(week.created)}px` }
|
|
753
|
+
})), week.done === 0 ? null : (0, react.createElement)("span", {
|
|
754
|
+
className: "dtl-gchart__val",
|
|
755
|
+
style: { bottom: `${heightOf(week.done) + 3}px` }
|
|
756
|
+
}, String(week.done)), (0, react.createElement)("span", { className: "dtl-gchart__label" }, week.label)))));
|
|
757
|
+
}
|
|
758
|
+
/** 图例(完成 / 新增 两个色块)。 */
|
|
759
|
+
function ChartLegend(props) {
|
|
760
|
+
ensureUiBase();
|
|
761
|
+
return (0, react.createElement)("div", { className: "dtl-gchart-legend" }, (0, react.createElement)("span", null, (0, react.createElement)("i", { style: { background: "var(--dtl-business)" } }), props.doneLabel), (0, react.createElement)("span", null, (0, react.createElement)("i", { style: { background: "var(--dtl-chip-bg)" } }), props.createdLabel));
|
|
680
762
|
}
|
|
681
763
|
//#endregion
|
|
682
764
|
//#region src/client/task-row.ts
|
|
@@ -875,18 +957,10 @@ body[data-ds-dark-theme]{
|
|
|
875
957
|
fontSize: "var(--dtl-font-xl)",
|
|
876
958
|
fontWeight: 600
|
|
877
959
|
};
|
|
878
|
-
/** 统计区:左 2
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
gap: "var(--dtl-space-3)",
|
|
883
|
-
marginBottom: "var(--dtl-space-4)"
|
|
884
|
-
};
|
|
885
|
-
const cardsGridStyle = {
|
|
886
|
-
display: "grid",
|
|
887
|
-
gridTemplateColumns: "repeat(auto-fit,minmax(148px,1fr))",
|
|
888
|
-
gap: "var(--dtl-space-3)"
|
|
889
|
-
};
|
|
960
|
+
/** 统计区:左 8 块(2 行 × 4 列)+ 右趋势图,参考图同款分栏。
|
|
961
|
+
* 列数写死 4 → 2(媒体查询在 ui.ts 的 .dtl-stats / .dtl-stats__cards 里),
|
|
962
|
+
* 绝不给 3 列——3 列会排出 3+1 的非对称(用户 2026-10-17:必须上下对称)。 */
|
|
963
|
+
const statsRowStyle = { marginBottom: "var(--dtl-space-4)" };
|
|
890
964
|
const chartCardStyle = {
|
|
891
965
|
display: "flex",
|
|
892
966
|
flexDirection: "column",
|
|
@@ -959,14 +1033,34 @@ body[data-ds-dark-theme]{
|
|
|
959
1033
|
setQuery(patch);
|
|
960
1034
|
}
|
|
961
1035
|
});
|
|
962
|
-
|
|
1036
|
+
/** 统计台卡:不可点(首页没有已结案可筛),hover 给具体日期区间。 */
|
|
1037
|
+
const periodCard = (label, period) => (0, react.createElement)(StatCard, {
|
|
1038
|
+
label: t(label),
|
|
1039
|
+
value: period?.done ?? 0,
|
|
1040
|
+
hint: t("statCreatedHint", { n: period?.created ?? 0 }),
|
|
1041
|
+
interactive: false,
|
|
1042
|
+
title: period === void 0 ? void 0 : t("periodRange", {
|
|
1043
|
+
from: period.from,
|
|
1044
|
+
to: period.to
|
|
1045
|
+
})
|
|
1046
|
+
});
|
|
1047
|
+
const [chartScope, setChartScope] = (0, react.useState)("all");
|
|
1048
|
+
const chartWeeks = (0, react.useMemo)(() => (board === null ? [] : board.closed.weekly[chartScope]).map((bucket) => ({
|
|
963
1049
|
label: bucket.week.slice(5),
|
|
964
|
-
|
|
1050
|
+
done: bucket.done,
|
|
1051
|
+
created: bucket.created,
|
|
965
1052
|
title: t("chartBucket", {
|
|
966
1053
|
week: bucket.week,
|
|
967
|
-
|
|
1054
|
+
done: bucket.done,
|
|
1055
|
+
created: bucket.created
|
|
968
1056
|
})
|
|
969
|
-
})), [
|
|
1057
|
+
})), [
|
|
1058
|
+
board,
|
|
1059
|
+
chartScope,
|
|
1060
|
+
t
|
|
1061
|
+
]);
|
|
1062
|
+
const chartDoneTotal = chartWeeks.reduce((sum, week) => sum + week.done, 0);
|
|
1063
|
+
const chartEmpty = chartWeeks.every((week) => week.done === 0 && week.created === 0);
|
|
970
1064
|
return (0, react.createElement)("div", { style: pageStyle }, (0, react.createElement)("div", { style: {
|
|
971
1065
|
display: "flex",
|
|
972
1066
|
justifyContent: "center"
|
|
@@ -1009,42 +1103,76 @@ body[data-ds-dark-theme]{
|
|
|
1009
1103
|
onClick: () => {
|
|
1010
1104
|
refresh();
|
|
1011
1105
|
}
|
|
1012
|
-
}, 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", {
|
|
1106
|
+
}, 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", {
|
|
1107
|
+
className: "dtl-stats",
|
|
1108
|
+
style: statsRowStyle
|
|
1109
|
+
}, (0, react.createElement)("div", { className: "dtl-stats__cards" }, card("statMyActive", stats.myActive, t("statMyActiveHint", { n: stats.myBlocked }), {
|
|
1013
1110
|
scope: "mine",
|
|
1014
1111
|
status: "all",
|
|
1015
1112
|
workspace: ""
|
|
1016
|
-
}), card("statOpen",
|
|
1113
|
+
}), card("statOpen", stats.open, t("statOpenHint", { n: days(stats.oldestOpenDays) }), {
|
|
1017
1114
|
scope: "all",
|
|
1018
1115
|
status: "open",
|
|
1019
1116
|
workspace: ""
|
|
1020
|
-
}), card("statDoing",
|
|
1117
|
+
}), card("statDoing", stats.doing, t("statDoingHint", { n: stats.doing - stats.myActive + stats.myBlocked }), {
|
|
1021
1118
|
scope: "all",
|
|
1022
1119
|
status: "active",
|
|
1023
1120
|
workspace: ""
|
|
1024
|
-
}),
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1121
|
+
}), (0, react.createElement)(StatCard, {
|
|
1122
|
+
label: t("statBlockedStale"),
|
|
1123
|
+
value: stats.blocked,
|
|
1124
|
+
hint: stats.stale === 0 ? void 0 : (0, react.createElement)("span", null, (0, react.createElement)("span", { style: {
|
|
1125
|
+
color: "var(--dtl-danger)",
|
|
1126
|
+
fontWeight: 600
|
|
1127
|
+
} }, t("statStaleWord")), ` ${t("statStaleHint", { n: stats.stale })}`),
|
|
1128
|
+
active: isActive(state.query, {
|
|
1129
|
+
scope: "all",
|
|
1130
|
+
status: "blocked",
|
|
1131
|
+
workspace: ""
|
|
1132
|
+
}),
|
|
1133
|
+
title: t("statStaleHint", { n: stats.staleDays }),
|
|
1134
|
+
onClick: () => {
|
|
1135
|
+
setQuery({
|
|
1136
|
+
scope: "all",
|
|
1137
|
+
status: "blocked",
|
|
1138
|
+
workspace: ""
|
|
1139
|
+
});
|
|
1140
|
+
}
|
|
1141
|
+
}), periodCard("statWeekDone", board?.trend.thisWeek), periodCard("statLastWeekDone", board?.trend.lastWeek), periodCard("statMonthDone", board?.trend.thisMonth), periodCard("statLastMonthDone", board?.trend.lastMonth)), (0, react.createElement)("div", {
|
|
1037
1142
|
className: "dtl-card",
|
|
1038
1143
|
style: chartCardStyle
|
|
1039
1144
|
}, (0, react.createElement)("div", { style: {
|
|
1145
|
+
display: "flex",
|
|
1146
|
+
alignItems: "center",
|
|
1147
|
+
justifyContent: "space-between",
|
|
1148
|
+
gap: "var(--dtl-space-2)"
|
|
1149
|
+
} }, (0, react.createElement)("span", { style: {
|
|
1040
1150
|
fontSize: "var(--dtl-font-md)",
|
|
1041
1151
|
fontWeight: 600
|
|
1042
|
-
} }, t("chartTitle")),
|
|
1152
|
+
} }, t("chartTitle")), (0, react.createElement)(Segmented, {
|
|
1153
|
+
id: "dtl-chart-scope",
|
|
1154
|
+
value: chartScope,
|
|
1155
|
+
label: t("scopeLabel"),
|
|
1156
|
+
size: "sm",
|
|
1157
|
+
variant: "inset",
|
|
1158
|
+
items: [{
|
|
1159
|
+
value: "all",
|
|
1160
|
+
label: t("chartScopeAll")
|
|
1161
|
+
}, {
|
|
1162
|
+
value: "mine",
|
|
1163
|
+
label: t("chartScopeMine")
|
|
1164
|
+
}],
|
|
1165
|
+
onChange: setChartScope
|
|
1166
|
+
})), chartEmpty ? (0, react.createElement)("div", { style: {
|
|
1043
1167
|
...hintStyle,
|
|
1044
1168
|
padding: "var(--dtl-space-4) 0"
|
|
1045
|
-
} }, t("chartEmpty")) : (0, react.createElement)(
|
|
1046
|
-
|
|
1047
|
-
ariaLabel: t("chartTitle")
|
|
1169
|
+
} }, t("chartEmpty")) : (0, react.createElement)(GroupedBarChart, {
|
|
1170
|
+
weeks: chartWeeks,
|
|
1171
|
+
ariaLabel: t("chartTitle"),
|
|
1172
|
+
avgLabel: t("chartAvg", { n: Math.round(chartDoneTotal / Math.max(1, chartWeeks.length) * 10) / 10 })
|
|
1173
|
+
}), (0, react.createElement)(ChartLegend, {
|
|
1174
|
+
doneLabel: t("chartLegendDone"),
|
|
1175
|
+
createdLabel: t("chartLegendCreated")
|
|
1048
1176
|
}), (0, react.createElement)("div", { style: {
|
|
1049
1177
|
fontSize: "var(--dtl-font-xs)",
|
|
1050
1178
|
color: "var(--dtl-fg-3)"
|
|
@@ -1209,18 +1337,26 @@ body[data-ds-dark-theme]{
|
|
|
1209
1337
|
statOpenHint: "最老一条躺了 {n}",
|
|
1210
1338
|
statDoing: "进行中",
|
|
1211
1339
|
statDoingHint: "别人在做 {n}",
|
|
1212
|
-
|
|
1213
|
-
|
|
1340
|
+
statBlockedStale: "阻塞 · 停滞",
|
|
1341
|
+
statStaleWord: "停滞",
|
|
1342
|
+
statStaleHint: "{n} 条",
|
|
1214
1343
|
statWeekDone: "本周完成",
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1344
|
+
statLastWeekDone: "上周完成",
|
|
1345
|
+
statMonthDone: "本月完成",
|
|
1346
|
+
statLastMonthDone: "上月完成",
|
|
1347
|
+
statCreatedHint: "新增 {n} 条",
|
|
1218
1348
|
daysNone: "—",
|
|
1219
1349
|
daysValue: "{n} 天",
|
|
1220
|
-
chartTitle: "近 8
|
|
1221
|
-
chartCaption: "
|
|
1222
|
-
chartBucket: "{week} 那一周:完成 {
|
|
1223
|
-
chartEmpty: "近 8
|
|
1350
|
+
chartTitle: "近 8 周",
|
|
1351
|
+
chartCaption: "完成(按结案时间)/ 新增(按创建时间),周一起桶;我的 = owner 是我",
|
|
1352
|
+
chartBucket: "{week} 那一周:完成 {done} 条,新增 {created} 条",
|
|
1353
|
+
chartEmpty: "近 8 周没有记录",
|
|
1354
|
+
chartScopeAll: "所有",
|
|
1355
|
+
chartScopeMine: "我的",
|
|
1356
|
+
chartLegendDone: "完成",
|
|
1357
|
+
chartLegendCreated: "新增",
|
|
1358
|
+
chartAvg: "周均 {n}",
|
|
1359
|
+
periodRange: "{from} ~ {to}",
|
|
1224
1360
|
scopeLabel: "范围",
|
|
1225
1361
|
scopeMine: "我的",
|
|
1226
1362
|
scopeAll: "全部工作区",
|
|
@@ -1277,18 +1413,26 @@ body[data-ds-dark-theme]{
|
|
|
1277
1413
|
statOpenHint: "oldest waiting {n}",
|
|
1278
1414
|
statDoing: "In progress",
|
|
1279
1415
|
statDoingHint: "{n} by others",
|
|
1280
|
-
|
|
1281
|
-
|
|
1416
|
+
statBlockedStale: "Blocked · Stale",
|
|
1417
|
+
statStaleWord: "Stale",
|
|
1418
|
+
statStaleHint: "{n}",
|
|
1282
1419
|
statWeekDone: "Done this week",
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1420
|
+
statLastWeekDone: "Done last week",
|
|
1421
|
+
statMonthDone: "Done this month",
|
|
1422
|
+
statLastMonthDone: "Done last month",
|
|
1423
|
+
statCreatedHint: "{n} created",
|
|
1286
1424
|
daysNone: "—",
|
|
1287
1425
|
daysValue: "{n}d",
|
|
1288
1426
|
chartTitle: "Last 8 weeks",
|
|
1289
|
-
chartCaption: "by close time, weeks start Monday;
|
|
1290
|
-
chartBucket: "week of {week}: {
|
|
1291
|
-
chartEmpty: "Nothing
|
|
1427
|
+
chartCaption: "done (by close time) / created (by create time), weeks start Monday; mine = owner is me",
|
|
1428
|
+
chartBucket: "week of {week}: {done} done, {created} created",
|
|
1429
|
+
chartEmpty: "Nothing in the last 8 weeks",
|
|
1430
|
+
chartScopeAll: "All",
|
|
1431
|
+
chartScopeMine: "Mine",
|
|
1432
|
+
chartLegendDone: "Done",
|
|
1433
|
+
chartLegendCreated: "Created",
|
|
1434
|
+
chartAvg: "avg {n}/wk",
|
|
1435
|
+
periodRange: "{from} ~ {to}",
|
|
1292
1436
|
scopeLabel: "Scope",
|
|
1293
1437
|
scopeMine: "Mine",
|
|
1294
1438
|
scopeAll: "All workspaces",
|