@zzusp/dingtalk-dsh-observer 0.5.8 → 0.5.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/package.json +1 -1
- package/web-client.js +8 -3
package/package.json
CHANGED
package/web-client.js
CHANGED
|
@@ -95,10 +95,10 @@ window.__ModuleLoader__.load({
|
|
|
95
95
|
return value
|
|
96
96
|
}
|
|
97
97
|
async function load() {
|
|
98
|
-
const [health, groups, tasks, alerts, authorizations] = await Promise.all([
|
|
99
|
-
get('/health'), get('/state/groups'), get('/state/tasks'), get('/state/supervisor/alerts'), get('/state/authorizations')
|
|
98
|
+
const [health, groups, tasks, taskTimings, alerts, authorizations] = await Promise.all([
|
|
99
|
+
get('/health'), get('/state/groups'), get('/state/tasks'), get('/state/task-timings'), get('/state/supervisor/alerts'), get('/state/authorizations')
|
|
100
100
|
])
|
|
101
|
-
return { health, groups, tasks, alerts, authorizations }
|
|
101
|
+
return { health, groups, tasks, taskTimings, alerts, authorizations }
|
|
102
102
|
}
|
|
103
103
|
function SidebarAction({ wide }) {
|
|
104
104
|
const isOpen = useOpen()
|
|
@@ -168,6 +168,7 @@ window.__ModuleLoader__.load({
|
|
|
168
168
|
return () => document.removeEventListener('click', closeForSession, true)
|
|
169
169
|
}, [])
|
|
170
170
|
const groupsById = new Map((data?.groups || []).map((group) => [group.groupId, group]))
|
|
171
|
+
const timingsByTaskId = new Map((data?.taskTimings || []).map((timing) => [timing.taskId, timing]))
|
|
171
172
|
const navigate = async (sessionId, parentSessionId) => {
|
|
172
173
|
try { setNavigationError(undefined); setNavigatingSessionId(sessionId); await openSession(sessionId, parentSessionId); setOpen(false) }
|
|
173
174
|
catch (cause) { setNavigationError(cause instanceof Error ? cause.message : String(cause)) }
|
|
@@ -204,6 +205,8 @@ window.__ModuleLoader__.load({
|
|
|
204
205
|
const delivery = {
|
|
205
206
|
delivered: { label: '已投递', state: 'done' },
|
|
206
207
|
failed: { label: '投递失败', state: 'error' },
|
|
208
|
+
'decision-failed': { label: '判断失败', state: 'error' },
|
|
209
|
+
steered: { label: '已插话·判断中', state: 'ongoing' },
|
|
207
210
|
pending: { label: '投递中', state: 'ongoing' },
|
|
208
211
|
skipped: { label: '历史补拉·未投递', state: 'warning' },
|
|
209
212
|
unknown: { label: '历史状态未知', state: 'warning' },
|
|
@@ -240,6 +243,7 @@ window.__ModuleLoader__.load({
|
|
|
240
243
|
})
|
|
241
244
|
const renderTaskCard = (task) => {
|
|
242
245
|
const group = groupsById.get(task.groupId)
|
|
246
|
+
const timing = timingsByTaskId.get(task.taskId)
|
|
243
247
|
const queued = task.state === 'queued'
|
|
244
248
|
const checkpointEvents = task.checkpoints || []
|
|
245
249
|
const planCheckpointIndex = checkpointEvents.findLastIndex((checkpoint) => checkpoint.kind === 'plan-confirmed')
|
|
@@ -270,6 +274,7 @@ window.__ModuleLoader__.load({
|
|
|
270
274
|
React.createElement('div', { role: 'button', tabIndex: 0, 'aria-expanded': checkpointsExpanded, 'aria-label': checkpointsExpanded ? '收起检查点' : `展开全部 ${checkpoints.length} 个检查点`, 'data-task-card-action': 'toggle-checkpoints', onClick: (event) => { event.stopPropagation(); setExpandedCheckpointTaskId(checkpointsExpanded ? '' : task.taskId) }, onKeyDown: (event) => { if (event.key !== 'Enter' && event.key !== ' ') return; event.preventDefault(); event.stopPropagation(); setExpandedCheckpointTaskId(checkpointsExpanded ? '' : task.taskId) }, style: { minHeight: 24, boxSizing: 'border-box', display: 'flex', alignItems: 'center', gap: 8, fontSize: 10.5, cursor: 'pointer' } }, React.createElement('span', { style: { flex: '0 0 auto', display: 'inline-flex', alignItems: 'center', gap: 4, color: colors.muted } }, React.createElement(IconChecklistOutline14, { size: 12, 'aria-label': '任务' }), '任务'), React.createElement('div', { role: 'progressbar', 'aria-label': '检查点进度', 'aria-valuemin': 0, 'aria-valuemax': 100, 'aria-valuenow': progress, style: { flex: '1 1 auto', minWidth: 24, height: 4, borderRadius: 999, overflow: 'hidden', background: `color-mix(in srgb, ${colors.muted} 22%, transparent)` } }, React.createElement('div', { style: { width: `${progress}%`, height: '100%', borderRadius: 'inherit', background: completedCheckpointCount === checkpoints.length ? statusTone.done : colors.accent, transition: 'width 180ms ease' } })), React.createElement('span', { style: { flex: '0 0 auto', color: completedCheckpointCount === checkpoints.length ? statusTone.done : colors.muted } }, `${completedCheckpointCount} / ${checkpoints.length}`), React.createElement(checkpointsExpanded ? IconChevronUpOutline14 : IconChevronDownOutline14, { size: 14, 'aria-hidden': true, style: { flex: '0 0 auto', color: colors.muted } })),
|
|
271
275
|
checkpointsExpanded ? React.createElement('div', { style: { display: 'grid', gap: 4, padding: '2px 9px 9px' } }, ...checkpoints.map((checkpoint, index) => { const completed = completedCheckpointNames.has(checkpoint); const current = !completed && currentCheckpoint === checkpoint; const tone = completed ? statusTone.done : current ? colors.accent : colors.muted; const duration = checkpointDuration(checkpoint, currentCheckpointEvents, Date.now()); return React.createElement('div', { key: `${index}:${checkpoint}`, title: checkpoint, style: { minWidth: 0, display: 'grid', gridTemplateColumns: '12px minmax(0,1fr) 64px', gap: 5, alignItems: 'start', fontSize: 10.5, lineHeight: 1.4 } }, React.createElement('span', { 'aria-hidden': true, style: { width: 12, height: 14, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', color: tone } }, completed ? React.createElement(CheckpointDoneIcon, { size: 12 }) : current ? React.createElement(StateDot, { state: 'ongoing', size: 10 }) : '○'), React.createElement('span', { style: { color: 'inherit', display: '-webkit-box', WebkitLineClamp: 'unset', WebkitBoxOrient: 'vertical', overflow: 'hidden', overflowWrap: 'anywhere' } }, checkpoint), React.createElement('span', { title: `执行时长 ${duration}`, style: { width: 64, color: colors.muted, textAlign: 'right', whiteSpace: 'nowrap', fontVariantNumeric: 'tabular-nums' } }, duration)) })) : null) : null,
|
|
272
276
|
task.waitingReason ? React.createElement('div', { title: task.waitingReason, style: { fontSize: 10.5, lineHeight: 1.45, color: colors.warning } }, `等待:${task.waitingReason}`) : null),
|
|
277
|
+
timing ? React.createElement('div', { title: timing.complete ? '当前执行轮次精确统计' : `当前执行轮次统计不完整:${(timing.missing || []).join('、') || '历史数据不足'}`, style: { fontSize: 10.5, lineHeight: 1.45, color: timing.complete ? colors.muted : colors.warning } }, `${timing.complete ? '' : '约 '}总计 ${fmtDuration(timing.wallMs)} · 排队 ${fmtDuration(timing.queuedMs)} · 运行 ${fmtDuration(timing.runningMs)} · 等待 ${fmtDuration(timing.waitingMs)} · 工具 ${fmtDuration(timing.toolMs)} · 其他运行 ${fmtDuration(timing.unclassifiedRunningMs)}`) : null,
|
|
273
278
|
React.createElement('div', { style: { minWidth: 0, marginTop: 0, paddingTop: 6, borderTop: `1px solid ${colors.border}`, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 } },
|
|
274
279
|
React.createElement('span', { title: `最后活动 ${fmt(task.updatedAt)}`, style: { minWidth: 0, display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: 10.5, color: colors.muted, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, React.createElement('svg', { width: 12, height: 12, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round', strokeLinejoin: 'round', 'aria-label': '最后活动时间' }, React.createElement('circle', { cx: 12, cy: 12, r: 9 }), React.createElement('path', { d: 'M12 7v5l3 2' })), fmt(task.updatedAt)),
|
|
275
280
|
task.state === 'completed' && !task.archivedAt ? React.createElement('button', { type: 'button', onClick: async (event) => { event.stopPropagation(); try { await post(`/tasks/${encodeURIComponent(task.taskId)}/archive`); await refresh() } catch (cause) { setNavigationError(cause instanceof Error ? cause.message : String(cause)) } }, style: { flex: '0 0 auto', border: `1px solid ${colors.border}`, borderRadius: 7, background: colors.surface2, color: colors.muted, padding: '3px 7px', cursor: 'pointer', fontFamily: 'inherit', fontSize: 10.5 } }, '归档') : null),
|