@goodandready/dsh-cron 0.3.12 → 0.3.14
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/README.md +24 -0
- package/README.ru.md +24 -0
- package/README.zh.md +24 -0
- package/lib/api.js +180 -5
- package/lib/branching.js +341 -0
- package/lib/client.js +949 -758
- package/lib/dag.js +88 -18
- package/lib/doctor.js +431 -0
- package/lib/git-diff.js +226 -0
- package/lib/scheduler-execution.js +98 -6
- package/lib/store.js +4 -0
- package/lib/swarm.js +303 -0
- package/lib/task-create.js +11 -0
- package/lib/task-patch.js +19 -1
- package/lib/task-transfer.js +9 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -4,6 +4,7 @@ factory: (require) => {
|
|
|
4
4
|
var module = { exports: {} }
|
|
5
5
|
var exports = module.exports
|
|
6
6
|
const React = window.React || require('react');
|
|
7
|
+
const h = (...args) => (React && React.createElement ? React.createElement(...args) : null);
|
|
7
8
|
const ReactDOM = window.ReactDOM || require('react-dom/client');
|
|
8
9
|
const PLUGIN_ID = '@goodandready/dsh-cron';
|
|
9
10
|
const NS = 'dsh-cron';
|
|
@@ -42,7 +43,7 @@ CoreChevron = primitives && primitives.IconChevronDownOutline14;
|
|
|
42
43
|
} catch (e) {
|
|
43
44
|
/* Optional core chevron primitive not available; SVG fallback used */
|
|
44
45
|
}
|
|
45
|
-
const chevronNode = () => (CoreChevron ?
|
|
46
|
+
const chevronNode = () => (CoreChevron ? h(CoreChevron) : h('span', { style: { display: 'flex', alignItems: 'center' }, dangerouslySetInnerHTML: { __html: ICON_CHEVRON_DOWN } }));
|
|
46
47
|
const STRINGS = {
|
|
47
48
|
en: {
|
|
48
49
|
'sidebar.label': 'Scheduled tasks', 'sidebar.jobsTitle': 'Active jobs',
|
|
@@ -280,7 +281,7 @@ en: {
|
|
|
280
281
|
'approval.approved': 'Approved', 'approval.rejected': 'Rejected',
|
|
281
282
|
'chainGraph.modalTitle': 'Visual Chain & Checkpoint Graph', 'chainGraph.viewGraph': 'Chain Graph',
|
|
282
283
|
'chainGraph.noNodes': 'No chained steps found for this task or run.', 'chainGraph.retryStep': 'Retry Step',
|
|
283
|
-
'chainGraph.stepSuccess': 'Success', 'chainGraph.stepFailed': 'Failed', 'chainGraph.stepPending': 'Pending', 'chainGraph.close': 'Close',
|
|
284
|
+
'chainGraph.stepSuccess': 'Success', 'chainGraph.stepFailed': 'Failed', 'chainGraph.stepPending': 'Pending', 'chainGraph.close': 'Close', 'chainGraph.decisionNode': 'Decision Node', 'chainGraph.stepSkipped': 'Skipped', 'history.doctorDiagnosis': 'Doctor Diagnosis & Suggested Fix', 'history.doctorApply': '1-Click Apply Fix', 'history.doctorRevert': 'Revert to Previous Code', 'history.autoHealed': 'Auto-Healed by Doctor', 'form.autoHealLabel': 'Autonomous Self-Healing Doctor', 'form.autoHealHint': 'Automatically diagnose and apply safe fixes upon failure (max 1 auto-patch/day)', 'form.elseTaskLabel': 'Default Fallback Task (elseTask)', 'form.elseTaskHint': 'Target task to trigger if no conditional branch rules matched', 'form.elseTaskPlaceholder': 'e.g. task-fallback',
|
|
284
285
|
'adaptive.badge': 'Adaptive', 'adaptive.idle': 'idle', 'adaptive.backoff': 'backoff',
|
|
285
286
|
'form.adaptiveEnabled': 'Adaptive Polling', 'form.adaptiveHint': 'Exponential backoff when no changes are detected',
|
|
286
287
|
'liveLog.modalTitle': 'Real-Time Streaming Execution Logs', 'liveLog.viewLog': 'Live Stream',
|
|
@@ -462,7 +463,7 @@ zh: {
|
|
|
462
463
|
'approval.approved': '已批准', 'approval.rejected': '已拒绝',
|
|
463
464
|
'chainGraph.modalTitle': '任务链与检查点依赖图', 'chainGraph.viewGraph': '任务链图',
|
|
464
465
|
'chainGraph.noNodes': '未找到该任务或运行的关联步骤。', 'chainGraph.retryStep': '重试此步骤',
|
|
465
|
-
'chainGraph.stepSuccess': '成功', 'chainGraph.stepFailed': '失败', 'chainGraph.stepPending': '等待中', 'chainGraph.close': '关闭',
|
|
466
|
+
'chainGraph.stepSuccess': '成功', 'chainGraph.stepFailed': '失败', 'chainGraph.stepPending': '等待中', 'chainGraph.close': '关闭', 'chainGraph.decisionNode': '条件决策节点', 'chainGraph.stepSkipped': '已跳过', 'history.doctorDiagnosis': 'Doctor 诊断与建议修复', 'history.doctorApply': '一键应用修复', 'history.doctorRevert': '恢复上一版本代码', 'history.autoHealed': '已由 Doctor 自动修复', 'form.autoHealLabel': '自主 Self-Healing Doctor 自动修复', 'form.autoHealHint': '当任务失败时自动诊断并安全修复(每天上限 1 次)', 'form.elseTaskLabel': '默认后备任务 (elseTask)', 'form.elseTaskHint': '当没有分支条件匹配时触发的目标任务', 'form.elseTaskPlaceholder': '如 task-fallback',
|
|
466
467
|
'adaptive.badge': '自适应', 'adaptive.idle': '空闲', 'adaptive.backoff': '避让中',
|
|
467
468
|
'form.adaptiveEnabled': '自适应轮询 (Adaptive Polling)', 'form.adaptiveHint': '数据无变化时指数级延长执行间隔',
|
|
468
469
|
'liveLog.modalTitle': '实时任务执行日志流', 'liveLog.viewLog': '实时日志',
|
|
@@ -781,10 +782,10 @@ console.error('[dsh-cron] React error:', error, errorInfo);
|
|
|
781
782
|
}
|
|
782
783
|
render() {
|
|
783
784
|
if (this.state.hasError) {
|
|
784
|
-
return
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
785
|
+
return h('div', { className: 'dsh-cron-status-banner', 'data-type': 'error', style: { margin: '12px 0' } },
|
|
786
|
+
h('div', { style: { fontWeight: 600, marginBottom: '6px' } }, '⚠️ Cron UI error:'),
|
|
787
|
+
h('div', { style: { fontSize: '12px', wordBreak: 'break-all' } }, String((this.state.error && this.state.error.message) || this.state.error)),
|
|
788
|
+
h('button', {
|
|
788
789
|
type: 'button',
|
|
789
790
|
className: 'dsh-cron-btn-secondary',
|
|
790
791
|
style: { marginTop: '10px', fontSize: '12px', padding: '4px 10px' },
|
|
@@ -979,9 +980,9 @@ return out;
|
|
|
979
980
|
}
|
|
980
981
|
function renderDeliverySettings({ T, values, onChange, onChannelTemplate, sections, onToggleSection }) {
|
|
981
982
|
const val = (key) => (values[key] === undefined || values[key] === null ? '' : String(values[key]));
|
|
982
|
-
const field = (f) =>
|
|
983
|
-
|
|
984
|
-
|
|
983
|
+
const field = (f) => h('div', { className: 'dsh-cron-form-group', key: f.key, style: { marginBottom: '10px' } },
|
|
984
|
+
h('label', null, T(f.labelKey)),
|
|
985
|
+
h('input', f.numeric ? {
|
|
985
986
|
type: 'number',
|
|
986
987
|
min: f.min !== undefined ? f.min : 1000,
|
|
987
988
|
step: 1000,
|
|
@@ -999,49 +1000,49 @@ onChange: (e) => onChange(f.key, e.target.value)
|
|
|
999
1000
|
);
|
|
1000
1001
|
const section = (key, titleKey, children) => {
|
|
1001
1002
|
const open = Boolean(sections[key]);
|
|
1002
|
-
return
|
|
1003
|
-
|
|
1003
|
+
return h('div', { className: 'dsh-cron-section', key },
|
|
1004
|
+
h('button', {
|
|
1004
1005
|
type: 'button',
|
|
1005
1006
|
className: 'dsh-cron-section-head',
|
|
1006
1007
|
'aria-expanded': open ? 'true' : 'false',
|
|
1007
1008
|
onClick: () => onToggleSection(key)
|
|
1008
1009
|
},
|
|
1009
|
-
|
|
1010
|
-
|
|
1010
|
+
h('span', null, T(titleKey)),
|
|
1011
|
+
h('span', { className: 'dsh-cron-section-chevron', 'data-open': open ? 'true' : 'false' }, '▾')
|
|
1011
1012
|
),
|
|
1012
|
-
open &&
|
|
1013
|
+
open && h('div', { className: 'dsh-cron-section-body' }, children)
|
|
1013
1014
|
);
|
|
1014
1015
|
};
|
|
1015
1016
|
return [
|
|
1016
1017
|
section('secrets', 'settings.secretsSection', [
|
|
1017
|
-
|
|
1018
|
+
h('div', { className: 'dsh-cron-hint', key: 'hint', style: { marginBottom: '10px' } }, T('settings.secretsHint')),
|
|
1018
1019
|
...DELIVERY_SETTING_FIELDS.filter((f) => f.group === 'secrets').map(field),
|
|
1019
1020
|
]),
|
|
1020
1021
|
section('channels', 'settings.deliverySection', [
|
|
1021
|
-
|
|
1022
|
+
h('div', { className: 'dsh-cron-form-row', key: 'row' },
|
|
1022
1023
|
...DELIVERY_SETTING_FIELDS.filter((f) => f.group === 'channels').map(field)
|
|
1023
1024
|
),
|
|
1024
1025
|
]),
|
|
1025
1026
|
section('automation', 'settings.automationSection', [
|
|
1026
|
-
|
|
1027
|
-
|
|
1027
|
+
h('div', { className: 'dsh-cron-hint', key: 'hint', style: { marginBottom: '10px' } }, T('settings.automationHint')),
|
|
1028
|
+
h('div', { className: 'dsh-cron-form-row', key: 'row' },
|
|
1028
1029
|
...DELIVERY_SETTING_FIELDS.filter((f) => f.group === 'automation').map(field)
|
|
1029
1030
|
),
|
|
1030
1031
|
]),
|
|
1031
1032
|
section('templates', 'settings.templatesSection', [
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1033
|
+
h('div', { className: 'dsh-cron-form-group', key: 'global', style: { marginBottom: '10px' } },
|
|
1034
|
+
h('label', null, T('settings.templateLabel')),
|
|
1035
|
+
h('input', {
|
|
1035
1036
|
type: 'text',
|
|
1036
1037
|
value: val('template'),
|
|
1037
1038
|
onChange: (e) => onChange('template', e.target.value)
|
|
1038
1039
|
}),
|
|
1039
|
-
|
|
1040
|
+
h('div', { className: 'dsh-cron-hint' }, T('settings.templateHint'))
|
|
1040
1041
|
),
|
|
1041
|
-
|
|
1042
|
-
...DELIVERY_CHANNELS.map((id) =>
|
|
1043
|
-
|
|
1044
|
-
|
|
1042
|
+
h('div', { className: 'dsh-cron-form-row', key: 'perchannel' },
|
|
1043
|
+
...DELIVERY_CHANNELS.map((id) => h('div', { className: 'dsh-cron-form-group', key: id, style: { marginBottom: '10px' } },
|
|
1044
|
+
h('label', null, T('settings.channelTemplateLabel', { channel: T(CHANNEL_LABEL_KEYS[id]) })),
|
|
1045
|
+
h('input', {
|
|
1045
1046
|
type: 'text',
|
|
1046
1047
|
value: (values.channelTemplates && values.channelTemplates[id]) || '',
|
|
1047
1048
|
onChange: (e) => onChannelTemplate(id, e.target.value)
|
|
@@ -1079,9 +1080,49 @@ if (nodeStatus === 'failed') hasFailure = true;
|
|
|
1079
1080
|
nodeStatus = 'running';
|
|
1080
1081
|
}
|
|
1081
1082
|
const deps = sanitizeDependsOn(task.dependsOn);
|
|
1082
|
-
|
|
1083
|
+
const hasBranches = Array.isArray(task.branchRules) && task.branchRules.length > 0;
|
|
1084
|
+
nodes.push({
|
|
1085
|
+
id,
|
|
1086
|
+
title: task.title || id,
|
|
1087
|
+
type: task.type || 'prompt',
|
|
1088
|
+
status: nodeStatus,
|
|
1089
|
+
durationMs,
|
|
1090
|
+
retryCount,
|
|
1091
|
+
outputSnippet,
|
|
1092
|
+
isFocus: Boolean(focusTaskId && id === focusTaskId),
|
|
1093
|
+
isRetryable: nodeStatus === 'failed',
|
|
1094
|
+
isDecisionNode: hasBranches,
|
|
1095
|
+
branchRulesCount: hasBranches ? task.branchRules.length : 0,
|
|
1096
|
+
elseTask: task.elseTask || null,
|
|
1097
|
+
dependsOn: deps,
|
|
1098
|
+
joinPolicy: sanitizeJoinPolicy(task.joinPolicy)
|
|
1099
|
+
});
|
|
1083
1100
|
for (const d of deps) edges.push({ from: d, to: id, type: 'dependsOn', label: task.joinPolicy === 'any_success' ? 'join:any' : 'join:all' });
|
|
1101
|
+
if (hasBranches) {
|
|
1102
|
+
for (const rule of task.branchRules) {
|
|
1103
|
+
if (rule && rule.targetTask) {
|
|
1104
|
+
edges.push({
|
|
1105
|
+
from: id,
|
|
1106
|
+
to: String(rule.targetTask).trim(),
|
|
1107
|
+
type: 'branch',
|
|
1108
|
+
label: rule.label || ('[if: ' + rule.field + ' ' + rule.operator + ' ' + (rule.value != null ? rule.value : '') + ']').trim(),
|
|
1109
|
+
condition: { field: rule.field, operator: rule.operator, value: rule.value }
|
|
1110
|
+
});
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
if (task.elseTask) {
|
|
1115
|
+
edges.push({
|
|
1116
|
+
from: id,
|
|
1117
|
+
to: String(task.elseTask).trim(),
|
|
1118
|
+
type: 'branch_else',
|
|
1119
|
+
label: '[else]',
|
|
1120
|
+
isElse: true
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
if (!hasBranches) {
|
|
1084
1124
|
for (const t of parseChainTargets(task.onSuccess)) edges.push({ from: id, to: t, type: 'onSuccess', label: 'onSuccess' });
|
|
1125
|
+
}
|
|
1085
1126
|
for (const f of parseChainTargets(task.onFailure)) edges.push({ from: id, to: f, type: 'onFailure', label: 'onFailure' });
|
|
1086
1127
|
}
|
|
1087
1128
|
return { nodes, edges, hasFailure };
|
|
@@ -1091,68 +1132,68 @@ if (!isOpen) return null;
|
|
|
1091
1132
|
const graph = data?.graph || { nodes: [], edges: [], hasFailure: false };
|
|
1092
1133
|
const chainRunId = data?.chainRunId || '';
|
|
1093
1134
|
const nodes = graph.nodes || [];
|
|
1094
|
-
return
|
|
1135
|
+
return h('div', {
|
|
1095
1136
|
className: 'dsh-cron-modal-overlay',
|
|
1096
1137
|
onClick: onClose
|
|
1097
1138
|
},
|
|
1098
|
-
|
|
1139
|
+
h('div', {
|
|
1099
1140
|
className: 'dsh-cron-modal',
|
|
1100
1141
|
style: { maxWidth: '820px', width: '92vw', maxHeight: '88vh', display: 'flex', flexDirection: 'column' },
|
|
1101
1142
|
role: 'dialog',
|
|
1102
1143
|
'aria-modal': 'true',
|
|
1103
1144
|
onClick: (e) => e.stopPropagation()
|
|
1104
1145
|
},
|
|
1105
|
-
|
|
1146
|
+
h('div', {
|
|
1106
1147
|
className: 'dsh-cron-modal-head',
|
|
1107
1148
|
style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: '1px solid var(--dsw-alias-border-l2)', paddingBottom: '12px' }
|
|
1108
1149
|
},
|
|
1109
|
-
|
|
1110
|
-
|
|
1150
|
+
h('div', null,
|
|
1151
|
+
h('div', {
|
|
1111
1152
|
className: 'dsh-cron-modal-title',
|
|
1112
1153
|
style: { margin: 0, display: 'flex', alignItems: 'center', gap: '8px' }
|
|
1113
1154
|
},
|
|
1114
|
-
|
|
1155
|
+
h('span', { style: { fontSize: '18px' } }, '🕸️'),
|
|
1115
1156
|
T_KEY(t, 'chainGraph.modalTitle')
|
|
1116
1157
|
),
|
|
1117
|
-
chainRunId &&
|
|
1158
|
+
chainRunId && h('div', {
|
|
1118
1159
|
style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #888)', marginTop: '4px', fontFamily: 'monospace' }
|
|
1119
1160
|
}, 'Run ID: ' + chainRunId)
|
|
1120
1161
|
),
|
|
1121
|
-
|
|
1162
|
+
h('button', {
|
|
1122
1163
|
type: 'button',
|
|
1123
1164
|
className: 'dsh-cron-icon-btn',
|
|
1124
1165
|
onClick: onClose
|
|
1125
1166
|
}, '✕')
|
|
1126
1167
|
),
|
|
1127
|
-
|
|
1168
|
+
h('div', {
|
|
1128
1169
|
style: { flex: 1, overflowY: 'auto', padding: '16px 0', minHeight: '260px' }
|
|
1129
1170
|
},
|
|
1130
|
-
loading &&
|
|
1171
|
+
loading && h('div', {
|
|
1131
1172
|
className: 'dsh-cron-history-empty'
|
|
1132
1173
|
}, T_KEY(t, 'history.loading')),
|
|
1133
|
-
!loading && nodes.length === 0 &&
|
|
1174
|
+
!loading && nodes.length === 0 && h('div', {
|
|
1134
1175
|
className: 'dsh-cron-history-empty'
|
|
1135
1176
|
}, T_KEY(t, 'chainGraph.noNodes')),
|
|
1136
|
-
!loading && nodes.length > 0 &&
|
|
1177
|
+
!loading && nodes.length > 0 && h('div', {
|
|
1137
1178
|
style: { display: 'flex', flexDirection: 'column', gap: '16px' }
|
|
1138
1179
|
},
|
|
1139
|
-
|
|
1180
|
+
h('div', {
|
|
1140
1181
|
style: { display: 'flex', gap: '12px', fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #888)', padding: '0 4px' }
|
|
1141
1182
|
},
|
|
1142
|
-
|
|
1143
|
-
|
|
1183
|
+
h('span', { style: { display: 'inline-flex', alignItems: 'center', gap: '4px' } },
|
|
1184
|
+
h('span', { style: { width: '8px', height: '8px', borderRadius: '50%', background: 'var(--dsh-cron-success)' } }),
|
|
1144
1185
|
T_KEY(t, 'chainGraph.stepSuccess')
|
|
1145
1186
|
),
|
|
1146
|
-
|
|
1147
|
-
|
|
1187
|
+
h('span', { style: { display: 'inline-flex', alignItems: 'center', gap: '4px' } },
|
|
1188
|
+
h('span', { style: { width: '8px', height: '8px', borderRadius: '50%', background: 'var(--dsh-cron-danger)' } }),
|
|
1148
1189
|
T_KEY(t, 'chainGraph.stepFailed')
|
|
1149
1190
|
),
|
|
1150
|
-
|
|
1151
|
-
|
|
1191
|
+
h('span', { style: { display: 'inline-flex', alignItems: 'center', gap: '4px' } },
|
|
1192
|
+
h('span', { style: { width: '8px', height: '8px', borderRadius: '50%', background: 'var(--dsw-alias-label-tertiary, #888)' } }),
|
|
1152
1193
|
T_KEY(t, 'chainGraph.stepPending')
|
|
1153
1194
|
)
|
|
1154
1195
|
),
|
|
1155
|
-
|
|
1196
|
+
h('div', {
|
|
1156
1197
|
style: {
|
|
1157
1198
|
display: 'flex',
|
|
1158
1199
|
flexWrap: 'wrap',
|
|
@@ -1172,7 +1213,7 @@ const borderColor = isOk
|
|
|
1172
1213
|
: isFailed
|
|
1173
1214
|
? 'var(--dsh-cron-danger)'
|
|
1174
1215
|
: 'var(--dsw-alias-border-l2)';
|
|
1175
|
-
return
|
|
1216
|
+
return h('div', {
|
|
1176
1217
|
key: n.id || idx,
|
|
1177
1218
|
style: {
|
|
1178
1219
|
flex: '1 1 220px',
|
|
@@ -1187,13 +1228,13 @@ gap: '8px',
|
|
|
1187
1228
|
boxShadow: isFailed ? '0 0 0 1px var(--dsh-cron-danger)' : 'none'
|
|
1188
1229
|
}
|
|
1189
1230
|
},
|
|
1190
|
-
|
|
1231
|
+
h('div', {
|
|
1191
1232
|
style: { display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: '6px' }
|
|
1192
1233
|
},
|
|
1193
|
-
|
|
1234
|
+
h('div', {
|
|
1194
1235
|
style: { fontWeight: '600', fontSize: '13px', color: 'var(--dsw-alias-label-primary)' }
|
|
1195
1236
|
}, n.title || n.id),
|
|
1196
|
-
|
|
1237
|
+
h('span', {
|
|
1197
1238
|
style: {
|
|
1198
1239
|
fontSize: '10px',
|
|
1199
1240
|
padding: '2px 6px',
|
|
@@ -1204,19 +1245,22 @@ color: isOk ? 'var(--dsh-cron-success)' : isFailed ? 'var(--dsh-cron-danger)' :
|
|
|
1204
1245
|
}
|
|
1205
1246
|
}, isOk ? '✓ ' + T_KEY(t, 'chainGraph.stepSuccess') : isFailed ? '✗ ' + T_KEY(t, 'chainGraph.stepFailed') : '⏳ ' + T_KEY(t, 'chainGraph.stepPending'))
|
|
1206
1247
|
),
|
|
1207
|
-
|
|
1248
|
+
h('div', {
|
|
1208
1249
|
style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary)', display: 'flex', gap: '8px', flexWrap: 'wrap' }
|
|
1209
1250
|
},
|
|
1210
|
-
n.durationMs > 0 &&
|
|
1211
|
-
n.retryCount > 0 &&
|
|
1212
|
-
n.joinPolicy && n.dependsOn?.length > 0 &&
|
|
1251
|
+
n.durationMs > 0 && h('span', null, n.durationMs + 'ms'),
|
|
1252
|
+
n.retryCount > 0 && h('span', { style: { color: 'var(--dsh-cron-warning)' } }, '↻ ' + n.retryCount),
|
|
1253
|
+
n.joinPolicy && n.dependsOn?.length > 0 && h('span', {
|
|
1213
1254
|
style: { background: 'var(--dsw-alias-bg-layer-3)', padding: '1px 4px', borderRadius: '4px' }
|
|
1214
1255
|
}, n.joinPolicy === 'any_success' ? 'join:any' : 'join:all')
|
|
1215
1256
|
),
|
|
1216
|
-
n.
|
|
1257
|
+
n.isDecisionNode && h('div', {
|
|
1258
|
+
style: { fontSize: '11px', color: 'var(--dsh-cron-warning)', fontWeight: '600', display: 'flex', alignItems: 'center', gap: '4px' }
|
|
1259
|
+
}, '🔀 ' + T_KEY(t, 'chainGraph.decisionNode') + ' (' + n.branchRulesCount + ')'),
|
|
1260
|
+
n.dependsOn?.length > 0 && h('div', {
|
|
1217
1261
|
style: { fontSize: '11px', color: 'var(--dsw-alias-label-tertiary)' }
|
|
1218
1262
|
}, '← ' + n.dependsOn.join(', ')),
|
|
1219
|
-
n.outputSnippet &&
|
|
1263
|
+
n.outputSnippet && h('div', {
|
|
1220
1264
|
style: {
|
|
1221
1265
|
background: 'var(--dsw-alias-bg-layer-2)',
|
|
1222
1266
|
border: '1px solid var(--dsw-alias-border-l2)',
|
|
@@ -1231,7 +1275,7 @@ maxHeight: '60px',
|
|
|
1231
1275
|
overflowY: 'auto'
|
|
1232
1276
|
}
|
|
1233
1277
|
}, n.outputSnippet),
|
|
1234
|
-
isFailed && chainRunId &&
|
|
1278
|
+
isFailed && chainRunId && h('button', {
|
|
1235
1279
|
type: 'button',
|
|
1236
1280
|
className: 'dsh-cron-btn-secondary',
|
|
1237
1281
|
style: {
|
|
@@ -1252,11 +1296,11 @@ onClick: () => onRetry && onRetry(n.id)
|
|
|
1252
1296
|
)
|
|
1253
1297
|
)
|
|
1254
1298
|
),
|
|
1255
|
-
|
|
1299
|
+
h('div', {
|
|
1256
1300
|
className: 'dsh-cron-modal-foot',
|
|
1257
1301
|
style: { borderTop: '1px solid var(--dsw-alias-border-l2)', paddingTop: '12px', marginTop: 'auto' }
|
|
1258
1302
|
},
|
|
1259
|
-
|
|
1303
|
+
h('button', {
|
|
1260
1304
|
type: 'button',
|
|
1261
1305
|
className: 'dsh-cron-btn-primary',
|
|
1262
1306
|
onClick: onClose
|
|
@@ -1274,26 +1318,26 @@ el.scrollTop = el.scrollHeight;
|
|
|
1274
1318
|
};
|
|
1275
1319
|
const isLive = status === 'running' || status === 'connecting';
|
|
1276
1320
|
const statusColor = isLive ? 'var(--dsh-cron-success, #2a2)' : (status === 'completed' ? 'var(--dsw-alias-label-secondary, #888)' : 'var(--dsh-cron-danger, #e33)');
|
|
1277
|
-
return
|
|
1321
|
+
return h('div', {
|
|
1278
1322
|
className: 'dsh-cron-modal-overlay',
|
|
1279
1323
|
onClick: onClose
|
|
1280
1324
|
},
|
|
1281
|
-
|
|
1325
|
+
h('div', {
|
|
1282
1326
|
className: 'dsh-cron-modal',
|
|
1283
1327
|
style: { maxWidth: '860px', width: '92vw', height: '80vh', display: 'flex', flexDirection: 'column', background: 'var(--dsw-alias-bg-base, #111)', color: 'var(--dsw-alias-label-primary, #ddd)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '8px' },
|
|
1284
1328
|
role: 'dialog',
|
|
1285
1329
|
'aria-modal': 'true',
|
|
1286
1330
|
onClick: (e) => e.stopPropagation()
|
|
1287
1331
|
},
|
|
1288
|
-
|
|
1332
|
+
h('div', {
|
|
1289
1333
|
style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '12px 16px', borderBottom: '1px solid var(--dsw-alias-border-l2, #333)', background: 'var(--dsw-alias-bg-layer-2, #111)' }
|
|
1290
1334
|
},
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1335
|
+
h('div', { style: { display: 'flex', alignItems: 'center', gap: '10px' } },
|
|
1336
|
+
h('span', { style: { fontSize: '18px' } }, '📺'),
|
|
1337
|
+
h('div', null,
|
|
1338
|
+
h('div', { style: { fontWeight: '600', fontSize: '14px', color: 'var(--dsw-alias-label-primary, #fff)', display: 'flex', alignItems: 'center', gap: '8px' } },
|
|
1295
1339
|
T_KEY(t, 'liveLog.modalTitle'),
|
|
1296
|
-
|
|
1340
|
+
h('span', {
|
|
1297
1341
|
style: {
|
|
1298
1342
|
display: 'inline-block',
|
|
1299
1343
|
width: '8px',
|
|
@@ -1304,14 +1348,14 @@ boxShadow: isLive ? '0 0 8px ' + statusColor : 'none'
|
|
|
1304
1348
|
}
|
|
1305
1349
|
})
|
|
1306
1350
|
),
|
|
1307
|
-
|
|
1351
|
+
h('div', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #888)', marginTop: '2px', fontFamily: 'monospace' } },
|
|
1308
1352
|
(taskTitle || taskId) + ' · ' + (isLive ? T_KEY(t, 'liveLog.connecting') : (completed ? T_KEY(t, 'liveLog.completed') : status))
|
|
1309
1353
|
)
|
|
1310
1354
|
)
|
|
1311
1355
|
),
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1356
|
+
h('div', { style: { display: 'flex', alignItems: 'center', gap: '12px' } },
|
|
1357
|
+
h('label', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)', display: 'flex', alignItems: 'center', gap: '4px', cursor: 'pointer' } },
|
|
1358
|
+
h('input', {
|
|
1315
1359
|
type: 'checkbox',
|
|
1316
1360
|
checked: Boolean(autoScroll),
|
|
1317
1361
|
onChange: onToggleAutoScroll,
|
|
@@ -1319,7 +1363,7 @@ style: { cursor: 'pointer' }
|
|
|
1319
1363
|
}),
|
|
1320
1364
|
T_KEY(t, 'liveLog.autoScroll')
|
|
1321
1365
|
),
|
|
1322
|
-
|
|
1366
|
+
h('button', {
|
|
1323
1367
|
type: 'button',
|
|
1324
1368
|
className: 'dsh-cron-icon-btn',
|
|
1325
1369
|
style: { color: 'var(--dsw-alias-label-secondary, #888)', background: 'transparent', border: 'none', cursor: 'pointer', fontSize: '16px' },
|
|
@@ -1327,29 +1371,29 @@ onClick: onClose
|
|
|
1327
1371
|
}, '✕')
|
|
1328
1372
|
)
|
|
1329
1373
|
),
|
|
1330
|
-
|
|
1374
|
+
h('div', {
|
|
1331
1375
|
ref: terminalRef,
|
|
1332
1376
|
style: { flex: 1, overflowY: 'auto', padding: '14px 16px', fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace', fontSize: '12px', lineHeight: '1.5', background: 'var(--dsw-alias-bg-base, #000)' }
|
|
1333
1377
|
},
|
|
1334
|
-
(!logs || logs.length === 0) &&
|
|
1378
|
+
(!logs || logs.length === 0) && h('div', {
|
|
1335
1379
|
style: { color: 'var(--dsw-alias-label-secondary, #888)', fontStyle: 'italic', padding: '20px 0', textAlign: 'center' }
|
|
1336
1380
|
}, isLive ? T_KEY(t, 'liveLog.waiting') : 'No output captured for this run.'),
|
|
1337
1381
|
logs && logs.length > 0 && logs.map((item, idx) => {
|
|
1338
1382
|
const isErr = item.stream === 'stderr';
|
|
1339
1383
|
const timeStr = item.ts ? new Date(item.ts).toLocaleTimeString() : '';
|
|
1340
|
-
return
|
|
1384
|
+
return h('div', {
|
|
1341
1385
|
key: idx,
|
|
1342
1386
|
style: { display: 'flex', gap: '8px', color: isErr ? 'var(--dsh-cron-danger, #f55)' : 'var(--dsh-cron-success, #5f5)', wordBreak: 'break-all', whiteSpace: 'pre-wrap' }
|
|
1343
1387
|
},
|
|
1344
|
-
timeStr &&
|
|
1345
|
-
|
|
1388
|
+
timeStr && h('span', { style: { color: 'var(--dsw-alias-label-secondary, #555)', userSelect: 'none', flexShrink: 0 } }, '[' + timeStr + ']'),
|
|
1389
|
+
h('span', { style: { flex: 1 } }, item.chunk || item.text || String(item))
|
|
1346
1390
|
);
|
|
1347
1391
|
})
|
|
1348
1392
|
),
|
|
1349
|
-
|
|
1393
|
+
h('div', {
|
|
1350
1394
|
style: { display: 'flex', justifyContent: 'flex-end', padding: '10px 16px', borderTop: '1px solid var(--dsw-alias-border-l2, #333)', background: 'var(--dsw-alias-bg-layer-2, #111)' }
|
|
1351
1395
|
},
|
|
1352
|
-
|
|
1396
|
+
h('button', {
|
|
1353
1397
|
type: 'button',
|
|
1354
1398
|
className: 'dsh-cron-btn dsh-cron-btn-secondary',
|
|
1355
1399
|
style: { padding: '6px 14px', fontSize: '12px' },
|
|
@@ -1385,117 +1429,117 @@ const text = [
|
|
|
1385
1429
|
].join(String.fromCharCode(10));
|
|
1386
1430
|
navigator.clipboard.writeText(text).catch(() => {});
|
|
1387
1431
|
};
|
|
1388
|
-
return
|
|
1432
|
+
return h('div', {
|
|
1389
1433
|
className: 'dsh-cron-modal-overlay',
|
|
1390
1434
|
onClick: onClose
|
|
1391
1435
|
},
|
|
1392
|
-
|
|
1436
|
+
h('div', {
|
|
1393
1437
|
className: 'dsh-cron-modal',
|
|
1394
1438
|
style: { maxWidth: '780px', width: '92vw', maxHeight: '86vh', display: 'flex', flexDirection: 'column', background: 'var(--dsw-alias-bg-base, #111)', color: 'var(--dsw-alias-label-primary, #ddd)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '8px' },
|
|
1395
1439
|
role: 'dialog',
|
|
1396
1440
|
'aria-modal': 'true',
|
|
1397
1441
|
onClick: (e) => e.stopPropagation()
|
|
1398
1442
|
},
|
|
1399
|
-
|
|
1443
|
+
h('div', {
|
|
1400
1444
|
style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '14px 18px', borderBottom: '1px solid var(--dsw-alias-border-l2, #333)', background: 'var(--dsw-alias-bg-layer-2, #111)' }
|
|
1401
1445
|
},
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1446
|
+
h('div', { style: { display: 'flex', alignItems: 'center', gap: '10px' } },
|
|
1447
|
+
h('span', { style: { fontSize: '20px' } }, '📊'),
|
|
1448
|
+
h('div', null,
|
|
1449
|
+
h('div', { style: { fontWeight: '600', fontSize: '15px', color: 'var(--dsw-alias-label-primary, #fff)' } },
|
|
1406
1450
|
T_KEY(t, 'digest.modalTitle')
|
|
1407
1451
|
),
|
|
1408
|
-
|
|
1452
|
+
h('div', { style: { fontSize: '11.5px', color: 'var(--dsw-alias-label-secondary, #888)', marginTop: '2px' } },
|
|
1409
1453
|
(T_KEY(t, 'digest.buttonTitle')) + ' · ' + (periodDays || 7) + 'd'
|
|
1410
1454
|
)
|
|
1411
1455
|
)
|
|
1412
1456
|
),
|
|
1413
|
-
|
|
1414
|
-
|
|
1457
|
+
h('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
|
|
1458
|
+
h('button', {
|
|
1415
1459
|
type: 'button',
|
|
1416
1460
|
className: 'dsh-cron-btn-secondary',
|
|
1417
1461
|
style: { padding: '4px 10px', fontSize: '12px', fontWeight: periodDays === 7 ? '600' : '400', background: periodDays === 7 ? 'var(--dsw-alias-bg-layer-3, #222)' : 'transparent' },
|
|
1418
1462
|
onClick: () => onSelectPeriod && onSelectPeriod(7)
|
|
1419
1463
|
}, T_KEY(t, 'digest.period7')),
|
|
1420
|
-
|
|
1464
|
+
h('button', {
|
|
1421
1465
|
type: 'button',
|
|
1422
1466
|
className: 'dsh-cron-btn-secondary',
|
|
1423
1467
|
style: { padding: '4px 10px', fontSize: '12px', fontWeight: periodDays === 30 ? '600' : '400', background: periodDays === 30 ? 'var(--dsw-alias-bg-layer-3, #222)' : 'transparent' },
|
|
1424
1468
|
onClick: () => onSelectPeriod && onSelectPeriod(30)
|
|
1425
1469
|
}, T_KEY(t, 'digest.period30')),
|
|
1426
|
-
|
|
1470
|
+
h('button', {
|
|
1427
1471
|
type: 'button',
|
|
1428
1472
|
className: 'dsh-cron-icon-btn',
|
|
1429
1473
|
onClick: onClose,
|
|
1430
1474
|
style: { marginLeft: '8px' }
|
|
1431
|
-
},
|
|
1475
|
+
}, h('span', null, '✕'))
|
|
1432
1476
|
)
|
|
1433
1477
|
),
|
|
1434
|
-
|
|
1478
|
+
h('div', {
|
|
1435
1479
|
style: { padding: '16px 18px', overflowY: 'auto', flex: 1, display: 'flex', flexDirection: 'column', gap: '16px' }
|
|
1436
1480
|
},
|
|
1437
|
-
isLoading ?
|
|
1481
|
+
isLoading ? h('div', { style: { padding: '30px', textAlign: 'center', color: 'var(--dsw-alias-label-secondary, #888)' } }, 'Loading digest metrics...') : h(React.Fragment, null,
|
|
1438
1482
|
(() => {
|
|
1439
|
-
const renderKpi = (label, val, sub, subCol) =>
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1483
|
+
const renderKpi = (label, val, sub, subCol) => h('div', { style: { background: 'var(--dsw-alias-bg-layer-2, #111)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '6px', padding: '10px 12px' } },
|
|
1484
|
+
h('div', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #888)' } }, label),
|
|
1485
|
+
h('div', { style: { fontSize: '18px', fontWeight: '700', color: 'var(--dsw-alias-label-primary, #fff)', marginTop: '4px' } }, val),
|
|
1486
|
+
h('div', { style: { fontSize: '11px', color: subCol || 'var(--dsw-alias-label-secondary, #888)', marginTop: '2px' } }, sub)
|
|
1443
1487
|
);
|
|
1444
|
-
return
|
|
1488
|
+
return h('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '10px' } },
|
|
1445
1489
|
renderKpi(T_KEY(t, 'digest.executions'), digest.totalRuns, digest.successRate + '% SR', digest.successRate >= 90 ? 'var(--dsh-cron-success, #2a2)' : 'var(--dsh-cron-warning, #fa0)'),
|
|
1446
1490
|
renderKpi(T_KEY(t, 'digest.tokens'), Number(digest.totalTokens || 0).toLocaleString(), 'LLM prompt+out'),
|
|
1447
1491
|
renderKpi(T_KEY(t, 'digest.cost'), '$' + Number(digest.totalCostUsd || 0).toFixed(4), 'USD estimated'),
|
|
1448
1492
|
renderKpi(T_KEY(t, 'digest.fleet'), digest.activeTasksCount, digest.pausedTasksCount + ' paused')
|
|
1449
1493
|
);
|
|
1450
1494
|
})(),
|
|
1451
|
-
|
|
1452
|
-
|
|
1495
|
+
h('div', { style: { background: 'var(--dsw-alias-bg-layer-2, #111)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '6px', padding: '12px' } },
|
|
1496
|
+
h('div', { style: { fontWeight: '600', fontSize: '13px', color: 'var(--dsh-cron-warning, #fa0)', marginBottom: '8px' } },
|
|
1453
1497
|
'⚠️ ' + (T_KEY(t, 'digest.unstableTitle'))
|
|
1454
1498
|
),
|
|
1455
|
-
(digest.topUnstableTasks && digest.topUnstableTasks.length > 0) ?
|
|
1456
|
-
digest.topUnstableTasks.map((tItem, idx) =>
|
|
1499
|
+
(digest.topUnstableTasks && digest.topUnstableTasks.length > 0) ? h('div', { style: { display: 'flex', flexDirection: 'column', gap: '6px' } },
|
|
1500
|
+
digest.topUnstableTasks.map((tItem, idx) => h('div', {
|
|
1457
1501
|
key: tItem.id || idx,
|
|
1458
1502
|
style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: '12px', padding: '6px 8px', background: 'var(--dsw-alias-bg-base, #111)', borderRadius: '4px', border: '1px solid var(--dsw-alias-border-l2, #222)' }
|
|
1459
1503
|
},
|
|
1460
|
-
|
|
1461
|
-
|
|
1504
|
+
h('span', { style: { fontFamily: 'monospace' } }, (idx + 1) + '. ' + (tItem.name || tItem.id)),
|
|
1505
|
+
h('span', { style: { color: 'var(--dsh-cron-danger, #e33)', fontWeight: '600' } },
|
|
1462
1506
|
tItem.failures + ' fail (' + tItem.successRate + '% SR)'
|
|
1463
1507
|
)
|
|
1464
1508
|
))
|
|
1465
|
-
) :
|
|
1509
|
+
) : h('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)' } }, '✓ All tasks healthy — 0 failures in window!')
|
|
1466
1510
|
),
|
|
1467
|
-
|
|
1468
|
-
|
|
1511
|
+
h('div', { style: { background: 'var(--dsw-alias-bg-layer-2, #111)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '6px', padding: '12px' } },
|
|
1512
|
+
h('div', { style: { fontWeight: '600', fontSize: '13px', color: 'var(--dsh-cron-info, #4af)', marginBottom: '8px' } },
|
|
1469
1513
|
'💰 ' + (T_KEY(t, 'digest.expensiveTitle'))
|
|
1470
1514
|
),
|
|
1471
|
-
(digest.topExpensiveTasks && digest.topExpensiveTasks.length > 0) ?
|
|
1472
|
-
digest.topExpensiveTasks.map((tItem, idx) =>
|
|
1515
|
+
(digest.topExpensiveTasks && digest.topExpensiveTasks.length > 0) ? h('div', { style: { display: 'flex', flexDirection: 'column', gap: '6px' } },
|
|
1516
|
+
digest.topExpensiveTasks.map((tItem, idx) => h('div', {
|
|
1473
1517
|
key: tItem.id || idx,
|
|
1474
1518
|
style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: '12px', padding: '6px 8px', background: 'var(--dsw-alias-bg-base, #111)', borderRadius: '4px', border: '1px solid var(--dsw-alias-border-l2, #222)' }
|
|
1475
1519
|
},
|
|
1476
|
-
|
|
1477
|
-
|
|
1520
|
+
h('span', { style: { fontFamily: 'monospace' } }, (idx + 1) + '. ' + (tItem.name || tItem.id)),
|
|
1521
|
+
h('span', { style: { color: 'var(--dsw-alias-label-primary, #ddd)' } },
|
|
1478
1522
|
Number(tItem.tokens || 0).toLocaleString() + ' tok ($' + Number(tItem.costUsd || 0).toFixed(4) + ')'
|
|
1479
1523
|
)
|
|
1480
1524
|
))
|
|
1481
|
-
) :
|
|
1525
|
+
) : h('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)' } }, 'No significant token consumption recorded.')
|
|
1482
1526
|
)
|
|
1483
1527
|
)
|
|
1484
1528
|
),
|
|
1485
|
-
|
|
1529
|
+
h('div', {
|
|
1486
1530
|
style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '12px 18px', borderTop: '1px solid var(--dsw-alias-border-l2, #333)', background: 'var(--dsw-alias-bg-layer-2, #111)' }
|
|
1487
1531
|
},
|
|
1488
|
-
|
|
1532
|
+
h('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)' } },
|
|
1489
1533
|
sendStatus || ''
|
|
1490
1534
|
),
|
|
1491
|
-
|
|
1492
|
-
|
|
1535
|
+
h('div', { style: { display: 'flex', gap: '8px' } },
|
|
1536
|
+
h('button', {
|
|
1493
1537
|
type: 'button',
|
|
1494
1538
|
className: 'dsh-cron-btn-secondary',
|
|
1495
1539
|
onClick: copyMarkdown,
|
|
1496
1540
|
style: { padding: '6px 14px', fontSize: '12px' }
|
|
1497
1541
|
}, T_KEY(t, 'digest.copyMarkdown')),
|
|
1498
|
-
|
|
1542
|
+
h('button', {
|
|
1499
1543
|
type: 'button',
|
|
1500
1544
|
className: 'dsh-cron-btn-primary',
|
|
1501
1545
|
onClick: onSendTelegram,
|
|
@@ -1520,70 +1564,70 @@ if (!isOpen) return null;
|
|
|
1520
1564
|
const tab = activeTab || 'timeline';
|
|
1521
1565
|
const timeline = timelineData || { buckets: [], totalRuns: 0, peakHoursCount: 0, maxConcurrent: 3 };
|
|
1522
1566
|
const heatmap = heatmapData || { matrix: [], dayLabels: [], hourLabels: [], totalCostUsd: 0, totalTokens: 0, maxCostHour: 0 };
|
|
1523
|
-
return
|
|
1567
|
+
return h('div', {
|
|
1524
1568
|
className: 'dsh-cron-modal-overlay',
|
|
1525
1569
|
onClick: onClose
|
|
1526
1570
|
},
|
|
1527
|
-
|
|
1571
|
+
h('div', {
|
|
1528
1572
|
className: 'dsh-cron-modal',
|
|
1529
1573
|
style: { maxWidth: '960px', width: '94vw', maxHeight: '88vh', display: 'flex', flexDirection: 'column', background: 'var(--dsw-alias-bg-base, #111)', color: 'var(--dsw-alias-label-primary, #ddd)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '8px' },
|
|
1530
1574
|
role: 'dialog',
|
|
1531
1575
|
'aria-modal': 'true',
|
|
1532
1576
|
onClick: (e) => e.stopPropagation()
|
|
1533
1577
|
},
|
|
1534
|
-
|
|
1578
|
+
h('div', {
|
|
1535
1579
|
style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '14px 18px', borderBottom: '1px solid var(--dsw-alias-border-l2, #333)', background: 'var(--dsw-alias-bg-layer-2, #111)' }
|
|
1536
1580
|
},
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1581
|
+
h('div', { style: { display: 'flex', alignItems: 'center', gap: '10px' } },
|
|
1582
|
+
h('span', { style: { fontSize: '20px' } }, tab === 'timeline' ? '⏱' : '🔥'),
|
|
1583
|
+
h('div', null,
|
|
1584
|
+
h('div', { style: { fontWeight: '600', fontSize: '15px', color: 'var(--dsw-alias-label-primary, #fff)' } },
|
|
1541
1585
|
tab === 'timeline' ? (T_KEY(t, 'timeline.modalTitle')) : (T_KEY(t, 'heatmap.modalTitle'))
|
|
1542
1586
|
),
|
|
1543
|
-
|
|
1587
|
+
h('div', { style: { fontSize: '11.5px', color: 'var(--dsw-alias-label-secondary, #888)', marginTop: '2px' } },
|
|
1544
1588
|
tab === 'timeline'
|
|
1545
1589
|
? (timeline.totalRuns + ' runs projected · ' + (timeline.peakHoursCount ? '⚠️ ' + timeline.peakHoursCount + ' peak hours' : '✓ balanced concurrency'))
|
|
1546
1590
|
: ('$' + Number(heatmap.totalCostUsd || 0).toFixed(4) + ' USD · ' + Number(heatmap.totalTokens || 0).toLocaleString() + ' tokens')
|
|
1547
1591
|
)
|
|
1548
1592
|
)
|
|
1549
1593
|
),
|
|
1550
|
-
|
|
1551
|
-
|
|
1594
|
+
h('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
|
|
1595
|
+
h('button', {
|
|
1552
1596
|
type: 'button',
|
|
1553
1597
|
className: 'dsh-cron-btn-secondary',
|
|
1554
1598
|
style: { padding: '4px 12px', fontSize: '12px', fontWeight: tab === 'timeline' ? '600' : '400', background: tab === 'timeline' ? 'var(--dsw-alias-bg-layer-3, #222)' : 'transparent' },
|
|
1555
1599
|
onClick: () => onSelectTab && onSelectTab('timeline')
|
|
1556
1600
|
}, '⏱ ' + (T_KEY(t, 'timeline.tabTimeline'))),
|
|
1557
|
-
|
|
1601
|
+
h('button', {
|
|
1558
1602
|
type: 'button',
|
|
1559
1603
|
className: 'dsh-cron-btn-secondary',
|
|
1560
1604
|
style: { padding: '4px 12px', fontSize: '12px', fontWeight: tab === 'heatmap' ? '600' : '400', background: tab === 'heatmap' ? 'var(--dsw-alias-bg-layer-3, #222)' : 'transparent' },
|
|
1561
1605
|
onClick: () => onSelectTab && onSelectTab('heatmap')
|
|
1562
1606
|
}, '🔥 ' + (T_KEY(t, 'heatmap.tabHeatmap'))),
|
|
1563
|
-
|
|
1607
|
+
h('button', {
|
|
1564
1608
|
type: 'button',
|
|
1565
1609
|
className: 'dsh-cron-icon-btn',
|
|
1566
1610
|
onClick: onClose,
|
|
1567
1611
|
style: { marginLeft: '8px' }
|
|
1568
|
-
},
|
|
1612
|
+
}, h('span', null, '✕'))
|
|
1569
1613
|
)
|
|
1570
1614
|
),
|
|
1571
|
-
|
|
1615
|
+
h('div', {
|
|
1572
1616
|
style: { padding: '16px 18px', overflowY: 'auto', flex: 1, display: 'flex', flexDirection: 'column', gap: '14px' }
|
|
1573
1617
|
},
|
|
1574
|
-
isLoading ?
|
|
1618
|
+
isLoading ? h('div', { style: { padding: '40px', textAlign: 'center', color: 'var(--dsw-alias-label-secondary, #888)' } }, 'Loading visualization data...') : (
|
|
1575
1619
|
tab === 'timeline' ? (
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1620
|
+
h('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px' } },
|
|
1621
|
+
h('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)', display: 'flex', justifyContent: 'space-between' } },
|
|
1622
|
+
h('span', null, T_KEY(t, 'timeline.legendDesc')),
|
|
1623
|
+
h('span', { style: { color: 'var(--dsh-cron-warning, #fa0)' } }, '⚠️ ' + (T_KEY(t, 'timeline.peakWarning')) + ' (' + timeline.maxConcurrent + ')')
|
|
1580
1624
|
),
|
|
1581
|
-
|
|
1625
|
+
h('div', {
|
|
1582
1626
|
style: { display: 'grid', gridTemplateColumns: 'repeat(12, 1fr)', gap: '8px', marginTop: '6px' }
|
|
1583
1627
|
},
|
|
1584
1628
|
(timeline.buckets || []).map((b) => {
|
|
1585
1629
|
const isPeak = b.isPeak, hasRuns = b.count > 0;
|
|
1586
|
-
return
|
|
1630
|
+
return h('div', {
|
|
1587
1631
|
key: b.index,
|
|
1588
1632
|
style: {
|
|
1589
1633
|
background: isPeak ? 'color-mix(in srgb, var(--dsh-cron-danger, #e33) 12%, var(--dsw-alias-bg-layer-2, #111))' : (hasRuns ? 'var(--dsw-alias-bg-layer-2, #111)' : 'var(--dsw-alias-bg-base, #111)'),
|
|
@@ -1591,12 +1635,12 @@ border: isPeak ? '1px solid var(--dsh-cron-danger, #e33)' : (hasRuns ? '1px soli
|
|
|
1591
1635
|
borderRadius: '6px', padding: '8px', minHeight: '75px', display: 'flex', flexDirection: 'column', justifyContent: 'space-between'
|
|
1592
1636
|
}
|
|
1593
1637
|
},
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
hasRuns ?
|
|
1638
|
+
h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: '11px' } },
|
|
1639
|
+
h('span', { style: { fontWeight: '600', color: isPeak ? 'var(--dsh-cron-danger, #e33)' : 'var(--dsw-alias-label-primary, #fff)' } }, b.label),
|
|
1640
|
+
hasRuns ? h('span', { style: { fontSize: '10px', padding: '1px 5px', borderRadius: '8px', background: isPeak ? 'var(--dsh-cron-danger, #e33)' : 'var(--dsw-alias-bg-layer-3, #222)', color: '#fff' } }, b.count) : null
|
|
1597
1641
|
),
|
|
1598
|
-
|
|
1599
|
-
(b.runs || []).slice(0, 3).map((r, rIdx) =>
|
|
1642
|
+
h('div', { style: { display: 'flex', flexWrap: 'wrap', gap: '3px', marginTop: '4px' } },
|
|
1643
|
+
(b.runs || []).slice(0, 3).map((r, rIdx) => h('span', {
|
|
1600
1644
|
key: rIdx, title: (r.title || r.taskId) + ' (' + r.time + ')',
|
|
1601
1645
|
style: { fontSize: '9.5px', fontFamily: 'monospace', padding: '1px 4px', borderRadius: '3px', background: 'var(--dsw-alias-bg-base, #111)', border: '1px solid var(--dsw-alias-border-l2, #333)', maxWidth: '100%', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }
|
|
1602
1646
|
}, r.title || r.taskId))
|
|
@@ -1606,36 +1650,36 @@ style: { fontSize: '9.5px', fontFamily: 'monospace', padding: '1px 4px', borderR
|
|
|
1606
1650
|
)
|
|
1607
1651
|
)
|
|
1608
1652
|
) : (
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1653
|
+
h('div', { style: { display: 'flex', flexDirection: 'column', gap: '10px' } },
|
|
1654
|
+
h('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)', display: 'flex', justifyContent: 'space-between' } },
|
|
1655
|
+
h('span', null, T_KEY(t, 'heatmap.matrixDesc')),
|
|
1656
|
+
h('span', null, 'Max hour spend: $' + Number(heatmap.maxCostHour || 0).toFixed(4))
|
|
1613
1657
|
),
|
|
1614
|
-
|
|
1658
|
+
h('div', {
|
|
1615
1659
|
style: { overflowX: 'auto', paddingBottom: '8px' }
|
|
1616
1660
|
},
|
|
1617
|
-
|
|
1661
|
+
h('table', {
|
|
1618
1662
|
style: { borderCollapse: 'collapse', width: '100%', minWidth: '700px', fontSize: '10.5px' }
|
|
1619
1663
|
},
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
Array.from({ length: 24 }, (_, h) =>
|
|
1664
|
+
h('thead', null,
|
|
1665
|
+
h('tr', null,
|
|
1666
|
+
h('th', { style: { padding: '4px 6px', textAlign: 'left', color: 'var(--dsw-alias-label-secondary, #888)' } }, 'Day'),
|
|
1667
|
+
Array.from({ length: 24 }, (_, h) => h('th', {
|
|
1624
1668
|
key: h,
|
|
1625
1669
|
style: { padding: '4px 2px', textAlign: 'center', color: 'var(--dsw-alias-label-secondary, #888)', fontWeight: '400' }
|
|
1626
1670
|
}, String(h).padStart(2, '0')))
|
|
1627
1671
|
)
|
|
1628
1672
|
),
|
|
1629
|
-
|
|
1630
|
-
(heatmap.matrix || []).map((row, dIdx) =>
|
|
1631
|
-
|
|
1673
|
+
h('tbody', null,
|
|
1674
|
+
(heatmap.matrix || []).map((row, dIdx) => h('tr', { key: dIdx },
|
|
1675
|
+
h('td', { style: { padding: '4px 6px', fontWeight: '600', color: 'var(--dsw-alias-label-primary, #ddd)' } }, (heatmap.dayLabels && heatmap.dayLabels[dIdx]) || 'Day'),
|
|
1632
1676
|
row.map((cell, hIdx) => {
|
|
1633
1677
|
const intensity = cell.costIntensity || 0;
|
|
1634
1678
|
const hasSpend = cell.costUsd > 0;
|
|
1635
1679
|
const bg = hasSpend
|
|
1636
1680
|
? 'color-mix(in srgb, var(--dsh-cron-primary, #4af) ' + Math.max(15, Math.round(intensity * 100)) + '%, transparent)'
|
|
1637
1681
|
: 'transparent';
|
|
1638
|
-
return
|
|
1682
|
+
return h('td', {
|
|
1639
1683
|
key: hIdx,
|
|
1640
1684
|
title: cell.dayLabel + ' ' + cell.hourLabel + ': $' + cell.costUsd + ' (' + cell.tokens.toLocaleString() + ' tokens, ' + cell.runs + ' runs)',
|
|
1641
1685
|
style: {
|
|
@@ -1645,7 +1689,7 @@ background: bg,
|
|
|
1645
1689
|
border: '1px solid var(--dsw-alias-border-l2, #222)',
|
|
1646
1690
|
cursor: hasSpend ? 'pointer' : 'default'
|
|
1647
1691
|
}
|
|
1648
|
-
}, hasSpend ?
|
|
1692
|
+
}, hasSpend ? h('span', { style: { fontSize: '9px', color: intensity > 0.5 ? '#fff' : 'var(--dsw-alias-label-primary, #ddd)' } }, '$' + (cell.costUsd >= 0.01 ? cell.costUsd.toFixed(2) : cell.costUsd.toFixed(3).slice(1))) : '·');
|
|
1649
1693
|
})
|
|
1650
1694
|
))
|
|
1651
1695
|
)
|
|
@@ -1655,10 +1699,10 @@ cursor: hasSpend ? 'pointer' : 'default'
|
|
|
1655
1699
|
)
|
|
1656
1700
|
)
|
|
1657
1701
|
),
|
|
1658
|
-
|
|
1702
|
+
h('div', {
|
|
1659
1703
|
style: { display: 'flex', justifyContent: 'flex-end', padding: '12px 18px', borderTop: '1px solid var(--dsw-alias-border-l2, #333)', background: 'var(--dsw-alias-bg-layer-2, #111)' }
|
|
1660
1704
|
},
|
|
1661
|
-
|
|
1705
|
+
h('button', {
|
|
1662
1706
|
type: 'button',
|
|
1663
1707
|
className: 'dsh-cron-btn-secondary',
|
|
1664
1708
|
onClick: onClose,
|
|
@@ -1716,6 +1760,8 @@ const [formOnSuccess, setFormOnSuccess] = React.useState('');
|
|
|
1716
1760
|
const [formOnFailure, setFormOnFailure] = React.useState('');
|
|
1717
1761
|
const [formDependsOn, setFormDependsOn] = React.useState('');
|
|
1718
1762
|
const [formJoinPolicy, setFormJoinPolicy] = React.useState('all_success');
|
|
1763
|
+
const [formElseTask, setFormElseTask] = React.useState('');
|
|
1764
|
+
const [formAutoHeal, setFormAutoHeal] = React.useState(false);
|
|
1719
1765
|
const [formAdaptiveEnabled, setFormAdaptiveEnabled] = React.useState(false);
|
|
1720
1766
|
const [formAdaptiveMinInterval, setFormAdaptiveMinInterval] = React.useState('5m');
|
|
1721
1767
|
const [formAdaptiveMaxInterval, setFormAdaptiveMaxInterval] = React.useState('2h');
|
|
@@ -2580,6 +2626,24 @@ alert(e.message || 'Error retrying delivery');
|
|
|
2580
2626
|
setRetryingDeliveryId(null);
|
|
2581
2627
|
}
|
|
2582
2628
|
};
|
|
2629
|
+
const handleApplyDoctorFix = async (taskId, fix) => {
|
|
2630
|
+
try {
|
|
2631
|
+
const { res, data } = await fetchJsonWithTimeout('/dsh-cron/tasks/' + encodeURIComponent(taskId) + '/doctor/apply', {
|
|
2632
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ fix }),
|
|
2633
|
+
});
|
|
2634
|
+
if (data && data.ok) { alert('Doctor fix applied successfully! Task code updated.'); await loadTaskHistory(taskId); await fetchTasks(); }
|
|
2635
|
+
else { alert(data?.error || 'Failed to apply doctor fix'); }
|
|
2636
|
+
} catch (e) { alert(e.message || 'Error applying doctor fix'); }
|
|
2637
|
+
};
|
|
2638
|
+
const handleRevertDoctorFix = async (taskId) => {
|
|
2639
|
+
try {
|
|
2640
|
+
const { res, data } = await fetchJsonWithTimeout('/dsh-cron/tasks/' + encodeURIComponent(taskId) + '/doctor/revert', {
|
|
2641
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}),
|
|
2642
|
+
});
|
|
2643
|
+
if (data && data.ok) { alert('Reverted to previous version successfully!'); await loadTaskHistory(taskId); await fetchTasks(); }
|
|
2644
|
+
else { alert(data?.error || 'Failed to revert doctor fix'); }
|
|
2645
|
+
} catch (e) { alert(e.message || 'Error reverting doctor fix'); }
|
|
2646
|
+
};
|
|
2583
2647
|
const handleResolveUncertain = async (taskId, runId, resolution) => {
|
|
2584
2648
|
try {
|
|
2585
2649
|
const { res, data } = await fetchJsonWithTimeout('/dsh-cron/tasks/' + encodeURIComponent(taskId) + '/resolve-uncertain', {
|
|
@@ -2947,82 +3011,82 @@ setTimelineLoading(false);
|
|
|
2947
3011
|
const onSelectTimelineTab = (tab) => {
|
|
2948
3012
|
setTimelineTab(tab);
|
|
2949
3013
|
};
|
|
2950
|
-
return
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
3014
|
+
return h('div', { className: 'dsh-cron-overlay' },
|
|
3015
|
+
h('div', { className: 'dsh-cron-container' },
|
|
3016
|
+
h('div', { className: 'dsh-cron-top-bar' },
|
|
3017
|
+
h('button', {
|
|
2954
3018
|
type: 'button',
|
|
2955
3019
|
className: 'dsh-cron-back-btn',
|
|
2956
3020
|
title: T_KEY(t, 'panel.back'),
|
|
2957
3021
|
onClick: () => { if (onClose) onClose(); else toggle.set(false); }
|
|
2958
3022
|
},
|
|
2959
|
-
|
|
2960
|
-
|
|
3023
|
+
h('span', svgProps(BACK_ICON)),
|
|
3024
|
+
h('span', null, T_KEY(t, 'panel.back'))
|
|
2961
3025
|
)
|
|
2962
3026
|
),
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
3027
|
+
h('div', { className: 'dsh-cron-header' },
|
|
3028
|
+
h('div', null,
|
|
3029
|
+
h('div', { className: 'dsh-cron-title' }, T_KEY(t, 'panel.title')),
|
|
3030
|
+
h('div', { className: 'dsh-cron-subtitle' }, T_KEY(t, 'panel.subtitle'))
|
|
2967
3031
|
),
|
|
2968
|
-
|
|
2969
|
-
|
|
3032
|
+
h('div', { style: { display: 'flex', alignItems: 'center', gap: '10px' } },
|
|
3033
|
+
h('button', {
|
|
2970
3034
|
type: 'button',
|
|
2971
3035
|
className: 'dsh-cron-btn-secondary',
|
|
2972
3036
|
style: { display: 'flex', alignItems: 'center', gap: '6px', height: '36px', padding: '0 12px' },
|
|
2973
3037
|
title: T_KEY(t, 'timeline.buttonTitle'),
|
|
2974
3038
|
onClick: () => openTimelineModal('timeline')
|
|
2975
3039
|
},
|
|
2976
|
-
|
|
3040
|
+
h('span', { style: { fontSize: '14px' } }, '⏱'),
|
|
2977
3041
|
T_KEY(t, 'timeline.buttonLabel')
|
|
2978
3042
|
),
|
|
2979
|
-
|
|
3043
|
+
h('button', {
|
|
2980
3044
|
type: 'button',
|
|
2981
3045
|
className: 'dsh-cron-btn-secondary',
|
|
2982
3046
|
style: { display: 'flex', alignItems: 'center', gap: '6px', height: '36px', padding: '0 12px' },
|
|
2983
3047
|
title: T_KEY(t, 'digest.buttonTitle'),
|
|
2984
3048
|
onClick: openAnalyticsDigest
|
|
2985
3049
|
},
|
|
2986
|
-
|
|
3050
|
+
h('span', { style: { fontSize: '14px' } }, '📊'),
|
|
2987
3051
|
T_KEY(t, 'digest.buttonLabel')
|
|
2988
3052
|
),
|
|
2989
|
-
|
|
3053
|
+
h('button', {
|
|
2990
3054
|
type: 'button',
|
|
2991
3055
|
className: 'dsh-cron-btn-secondary',
|
|
2992
3056
|
style: { display: 'flex', alignItems: 'center', gap: '6px', height: '36px', padding: '0 14px' },
|
|
2993
3057
|
title: T_KEY(t, 'actions.settings'),
|
|
2994
3058
|
onClick: openSettingsModal
|
|
2995
3059
|
},
|
|
2996
|
-
|
|
3060
|
+
h('span', { style: { display: 'flex', alignItems: 'center', color: 'var(--dsh-cron-info)' }, ...iconHtml(ICON_TELEGRAM) }),
|
|
2997
3061
|
T_KEY(t, 'actions.settings')
|
|
2998
3062
|
),
|
|
2999
|
-
|
|
3000
|
-
|
|
3063
|
+
h('div', { style: { position: 'relative' } },
|
|
3064
|
+
h('button', { className: 'dsh-cron-create-btn', onClick: () => setDropdownOpen(!dropdownOpen) },
|
|
3001
3065
|
T_KEY(t, 'actions.create'),
|
|
3002
|
-
|
|
3066
|
+
h('span', iconHtml(ICON_CHEVRON_DOWN))
|
|
3003
3067
|
),
|
|
3004
|
-
dropdownOpen &&
|
|
3005
|
-
|
|
3006
|
-
|
|
3068
|
+
dropdownOpen && h('div', { className: 'dsh-cron-dropdown' },
|
|
3069
|
+
h('button', { className: 'dsh-cron-dropdown-item', onClick: openDshModal }, T_KEY(t, 'actions.createWithDsh')),
|
|
3070
|
+
h('button', { className: 'dsh-cron-dropdown-item', onClick: () => openManualModal(null) }, T_KEY(t, 'actions.setupManually'))
|
|
3007
3071
|
)
|
|
3008
3072
|
),
|
|
3009
|
-
|
|
3073
|
+
h('button', {
|
|
3010
3074
|
type: 'button',
|
|
3011
3075
|
className: 'dsh-cron-icon-btn',
|
|
3012
3076
|
title: T_KEY(t, 'transfer.exportTitle'),
|
|
3013
3077
|
'aria-label': T_KEY(t, 'transfer.exportTitle'),
|
|
3014
3078
|
disabled: transferBusy,
|
|
3015
3079
|
onClick: handleExport
|
|
3016
|
-
},
|
|
3017
|
-
|
|
3080
|
+
}, h('span', svgProps(ICON_DOWNLOAD))),
|
|
3081
|
+
h('button', {
|
|
3018
3082
|
type: 'button',
|
|
3019
3083
|
className: 'dsh-cron-icon-btn',
|
|
3020
3084
|
title: T_KEY(t, 'transfer.importTitle'),
|
|
3021
3085
|
'aria-label': T_KEY(t, 'transfer.importTitle'),
|
|
3022
3086
|
disabled: transferBusy,
|
|
3023
3087
|
onClick: () => { if (importFileRef.current) importFileRef.current.click(); }
|
|
3024
|
-
},
|
|
3025
|
-
|
|
3088
|
+
}, h('span', svgProps(ICON_UPLOAD))),
|
|
3089
|
+
h('input', {
|
|
3026
3090
|
type: 'file',
|
|
3027
3091
|
accept: '.json,application/json',
|
|
3028
3092
|
ref: importFileRef,
|
|
@@ -3031,9 +3095,9 @@ onChange: handleImportFile
|
|
|
3031
3095
|
})
|
|
3032
3096
|
)
|
|
3033
3097
|
),
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3098
|
+
h('div', { className: 'dsh-cron-search-bar' },
|
|
3099
|
+
h('span', { className: 'dsh-cron-search-icon', ...iconHtml(ICON_SEARCH) }),
|
|
3100
|
+
h('input', {
|
|
3037
3101
|
className: 'dsh-cron-search-input',
|
|
3038
3102
|
type: 'search',
|
|
3039
3103
|
'aria-label': T_KEY(t, 'search.placeholder'),
|
|
@@ -3042,27 +3106,27 @@ value: query,
|
|
|
3042
3106
|
onChange: (e) => setQuery(e.target.value)
|
|
3043
3107
|
})
|
|
3044
3108
|
),
|
|
3045
|
-
stats &&
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3109
|
+
stats && h('div', { className: 'dsh-cron-stats-bar' },
|
|
3110
|
+
h('div', { className: 'dsh-cron-stat-card' },
|
|
3111
|
+
h('div', { className: 'dsh-cron-stat-val' }, stats.activeTasks || 0),
|
|
3112
|
+
h('div', { className: 'dsh-cron-stat-lbl' }, T_KEY(t, 'stats.activeTasks'))
|
|
3049
3113
|
),
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3114
|
+
h('div', { className: 'dsh-cron-stat-card' },
|
|
3115
|
+
h('div', { className: 'dsh-cron-stat-val' }, stats.totalRuns || 0),
|
|
3116
|
+
h('div', { className: 'dsh-cron-stat-lbl' }, T_KEY(t, 'stats.totalRuns'))
|
|
3053
3117
|
),
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3118
|
+
h('div', { className: 'dsh-cron-stat-card' },
|
|
3119
|
+
h('div', { className: 'dsh-cron-stat-val' }, (stats.totalTokens || 0).toLocaleString()),
|
|
3120
|
+
h('div', { className: 'dsh-cron-stat-lbl' }, T_KEY(t, 'stats.totalTokens'))
|
|
3057
3121
|
),
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3122
|
+
h('div', { className: 'dsh-cron-stat-card' },
|
|
3123
|
+
h('div', { className: 'dsh-cron-stat-val', style: { color: 'var(--dsh-cron-success)' } }, '$' + (stats.totalCostUsd || 0).toFixed(4)),
|
|
3124
|
+
h('div', { className: 'dsh-cron-stat-lbl' }, T_KEY(t, 'stats.totalCost'))
|
|
3061
3125
|
)
|
|
3062
3126
|
),
|
|
3063
|
-
|
|
3127
|
+
h('div', { className: 'dsh-cron-tabs' },
|
|
3064
3128
|
['all', 'active', 'paused', 'completed'].map((tabName) =>
|
|
3065
|
-
|
|
3129
|
+
h('button', {
|
|
3066
3130
|
key: tabName,
|
|
3067
3131
|
className: 'dsh-cron-tab',
|
|
3068
3132
|
'data-active': tab === tabName ? 'true' : undefined,
|
|
@@ -3074,8 +3138,8 @@ tabName === 'all' ? T_KEY(t, 'tabs.all')
|
|
|
3074
3138
|
: T_KEY(t, 'tabs.completed'))
|
|
3075
3139
|
)
|
|
3076
3140
|
),
|
|
3077
|
-
|
|
3078
|
-
|
|
3141
|
+
h('div', { className: 'dsh-cron-filters' },
|
|
3142
|
+
h('button', {
|
|
3079
3143
|
type: 'button',
|
|
3080
3144
|
className: 'dsh-cron-filter-toggle',
|
|
3081
3145
|
'aria-expanded': filtersOpen ? 'true' : 'false',
|
|
@@ -3084,73 +3148,73 @@ onClick: () => setFiltersOpen(!filtersOpen)
|
|
|
3084
3148
|
T_KEY(t, 'filters.title'),
|
|
3085
3149
|
(filterType || filterModel || filterChannel) ? ' •' : ''
|
|
3086
3150
|
),
|
|
3087
|
-
filtersOpen &&
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3151
|
+
filtersOpen && h('div', { className: 'dsh-cron-filter-panel' },
|
|
3152
|
+
h('label', { className: 'dsh-cron-filter-field' },
|
|
3153
|
+
h('span', null, T_KEY(t, 'filters.type')),
|
|
3154
|
+
h('select', {
|
|
3091
3155
|
value: filterType,
|
|
3092
3156
|
onChange: (e) => setFilterType(e.target.value)
|
|
3093
3157
|
},
|
|
3094
|
-
|
|
3095
|
-
...filterTypeOptions.map((value) =>
|
|
3158
|
+
h('option', { value: '' }, T_KEY(t, 'filters.any')),
|
|
3159
|
+
...filterTypeOptions.map((value) => h('option', { key: value, value }, value))
|
|
3096
3160
|
)
|
|
3097
3161
|
),
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3162
|
+
h('label', { className: 'dsh-cron-filter-field' },
|
|
3163
|
+
h('span', null, T_KEY(t, 'filters.model')),
|
|
3164
|
+
h('select', {
|
|
3101
3165
|
value: filterModel,
|
|
3102
3166
|
onChange: (e) => setFilterModel(e.target.value)
|
|
3103
3167
|
},
|
|
3104
|
-
|
|
3105
|
-
...filterModelOptions.map((value) =>
|
|
3168
|
+
h('option', { value: '' }, T_KEY(t, 'filters.any')),
|
|
3169
|
+
...filterModelOptions.map((value) => h('option', { key: value, value }, value))
|
|
3106
3170
|
)
|
|
3107
3171
|
),
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3172
|
+
h('label', { className: 'dsh-cron-filter-field' },
|
|
3173
|
+
h('span', null, T_KEY(t, 'filters.channel')),
|
|
3174
|
+
h('select', {
|
|
3111
3175
|
value: filterChannel,
|
|
3112
3176
|
onChange: (e) => setFilterChannel(e.target.value)
|
|
3113
3177
|
},
|
|
3114
|
-
|
|
3115
|
-
...DELIVERY_CHANNELS.map((id) =>
|
|
3178
|
+
h('option', { value: '' }, T_KEY(t, 'filters.any')),
|
|
3179
|
+
...DELIVERY_CHANNELS.map((id) => h('option', { key: id, value: id }, T_KEY(t, CHANNEL_LABEL_KEYS[id])))
|
|
3116
3180
|
)
|
|
3117
3181
|
)
|
|
3118
3182
|
)
|
|
3119
3183
|
),
|
|
3120
|
-
fetchError ?
|
|
3184
|
+
fetchError ? h('div', {
|
|
3121
3185
|
className: 'dsh-cron-status-banner',
|
|
3122
3186
|
'data-type': 'error',
|
|
3123
3187
|
style: { margin: '8px 0', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }
|
|
3124
3188
|
},
|
|
3125
|
-
|
|
3126
|
-
|
|
3189
|
+
h('span', null, T_KEY(t, 'banner.loadError', { error: fetchError })),
|
|
3190
|
+
h('button', {
|
|
3127
3191
|
type: 'button',
|
|
3128
3192
|
className: 'dsh-cron-btn-secondary',
|
|
3129
3193
|
style: { marginLeft: '8px', padding: '2px 8px', fontSize: '12px' },
|
|
3130
3194
|
onClick: () => fetchTasks()
|
|
3131
3195
|
}, T_KEY(t, 'banner.retry'))
|
|
3132
3196
|
) : null,
|
|
3133
|
-
(filterType || filterModel || filterChannel) ?
|
|
3197
|
+
(filterType || filterModel || filterChannel) ? h('div', {
|
|
3134
3198
|
className: 'dsh-cron-filter-summary',
|
|
3135
3199
|
style: { fontSize: '12px', color: 'var(--dsw-alias-label-tertiary, #888)', marginBottom: '8px', display: 'flex', gap: '8px', alignItems: 'center' }
|
|
3136
3200
|
},
|
|
3137
|
-
|
|
3138
|
-
|
|
3201
|
+
h('span', null, T_KEY(t, 'filters.showing', { shown: visibleTasks.length, total: tasks.length })),
|
|
3202
|
+
h('button', {
|
|
3139
3203
|
type: 'button',
|
|
3140
3204
|
className: 'dsh-cron-btn-secondary',
|
|
3141
3205
|
style: { padding: '2px 8px', fontSize: '11px' },
|
|
3142
3206
|
onClick: resetFilters
|
|
3143
3207
|
}, T_KEY(t, 'filters.reset'))
|
|
3144
3208
|
) : null,
|
|
3145
|
-
|
|
3209
|
+
h('div', { className: 'dsh-cron-task-list' },
|
|
3146
3210
|
loading && tasks.length === 0
|
|
3147
|
-
?
|
|
3211
|
+
? h('div', { style: { color: 'var(--dsw-alias-label-tertiary, #888)', padding: '16px 0', fontSize: '14px' } }, T_KEY(t, 'list.loading'))
|
|
3148
3212
|
: tasks.length === 0
|
|
3149
|
-
?
|
|
3213
|
+
? h('div', { style: { color: 'var(--dsw-alias-label-tertiary, #777)', padding: '16px 0', fontSize: '14px' } }, T_KEY(t, 'list.empty'))
|
|
3150
3214
|
: visibleTasks.length === 0
|
|
3151
|
-
?
|
|
3152
|
-
|
|
3153
|
-
|
|
3215
|
+
? h('div', { style: { color: 'var(--dsw-alias-label-tertiary, #777)', padding: '16px 0', fontSize: '14px', display: 'flex', gap: '10px', alignItems: 'center' } },
|
|
3216
|
+
h('span', null, T_KEY(t, 'filters.empty')),
|
|
3217
|
+
h('button', {
|
|
3154
3218
|
type: 'button',
|
|
3155
3219
|
className: 'dsh-cron-btn-secondary',
|
|
3156
3220
|
style: { padding: '2px 8px', fontSize: '12px' },
|
|
@@ -3158,7 +3222,7 @@ onClick: resetFilters
|
|
|
3158
3222
|
}, T_KEY(t, 'filters.reset'))
|
|
3159
3223
|
)
|
|
3160
3224
|
: visibleTasks.map((task) =>
|
|
3161
|
-
|
|
3225
|
+
h('div', {
|
|
3162
3226
|
key: task.id,
|
|
3163
3227
|
className: 'dsh-cron-task-item',
|
|
3164
3228
|
'data-task-id': task.id,
|
|
@@ -3174,127 +3238,127 @@ openEditModal(task);
|
|
|
3174
3238
|
}
|
|
3175
3239
|
}
|
|
3176
3240
|
},
|
|
3177
|
-
isConfigManaged(task) ? null :
|
|
3241
|
+
isConfigManaged(task) ? null : h('button', {
|
|
3178
3242
|
type: 'button',
|
|
3179
3243
|
className: 'dsh-cron-task-status-btn' + (task.running ? ' dsh-cron-pulse' : ''),
|
|
3180
3244
|
'data-active': task.status === 'active' ? 'true' : undefined,
|
|
3181
3245
|
title: task.status === 'active' ? T_KEY(t, 'actions.pause') : T_KEY(t, 'actions.resume'),
|
|
3182
3246
|
'aria-label': task.status === 'active' ? T_KEY(t, 'actions.pause') : T_KEY(t, 'actions.resume'),
|
|
3183
3247
|
onClick: (e) => { e.stopPropagation(); handleToggleTask(task.id); }
|
|
3184
|
-
},
|
|
3185
|
-
|
|
3186
|
-
|
|
3248
|
+
}, h('span', svgProps(task.status === 'active' ? ICON_PAUSE : ICON_PLAY))),
|
|
3249
|
+
h('div', { className: 'dsh-cron-task-info' },
|
|
3250
|
+
h('div', { className: 'dsh-cron-task-title' },
|
|
3187
3251
|
task.title,
|
|
3188
|
-
|
|
3252
|
+
h('span', {
|
|
3189
3253
|
className: 'dsh-cron-type-tag',
|
|
3190
3254
|
style: task.type === 'script'
|
|
3191
3255
|
? { background: 'var(--dsh-cron-info-bg)', color: 'var(--dsh-cron-info)' }
|
|
3192
3256
|
: { background: 'var(--dsh-cron-success-bg)', color: 'var(--dsh-cron-success)' }
|
|
3193
3257
|
}, task.type === 'script' ? T_KEY(t, 'list.typeShell') : T_KEY(t, 'list.typeLlm')),
|
|
3194
|
-
task.model ?
|
|
3195
|
-
task.oneShot ?
|
|
3196
|
-
isConfigManaged(task) ?
|
|
3258
|
+
task.model ? h('span', { className: 'dsh-cron-task-model-tag' }, task.model.split('/').pop()) : null,
|
|
3259
|
+
task.oneShot ? h('span', { className: 'dsh-cron-oneshot-tag' }, T_KEY(t, 'list.oneShot')) : null,
|
|
3260
|
+
isConfigManaged(task) ? h('span', {
|
|
3197
3261
|
className: 'dsh-cron-config-tag',
|
|
3198
3262
|
title: T_KEY(t, 'list.configManagedHint')
|
|
3199
3263
|
}, T_KEY(t, 'list.configManaged')) : null,
|
|
3200
|
-
task.lastDurationMs > 0 ?
|
|
3201
|
-
task.onSuccess ?
|
|
3202
|
-
task.onFailure ?
|
|
3203
|
-
(task.dependsOn && (Array.isArray(task.dependsOn) ? task.dependsOn.length > 0 : Boolean(task.dependsOn))) ?
|
|
3204
|
-
task.adaptive?.enabled ?
|
|
3264
|
+
task.lastDurationMs > 0 ? h('span', { className: 'dsh-cron-cost-tag', title: 'Last execution duration' }, task.lastDurationMs + 'ms') : null,
|
|
3265
|
+
task.onSuccess ? h('span', { className: 'dsh-cron-type-tag dsh-cron-tag-success', title: 'On success: triggers ' + task.onSuccess }, '➜ ' + task.onSuccess) : null,
|
|
3266
|
+
task.onFailure ? h('span', { className: 'dsh-cron-type-tag dsh-cron-tag-failure', title: 'On failure: triggers ' + task.onFailure }, '↳ ' + task.onFailure) : null,
|
|
3267
|
+
(task.dependsOn && (Array.isArray(task.dependsOn) ? task.dependsOn.length > 0 : Boolean(task.dependsOn))) ? h('span', { className: 'dsh-cron-type-tag dsh-cron-tag-heartbeat', title: 'Depends on: ' + (Array.isArray(task.dependsOn) ? task.dependsOn.join(', ') : task.dependsOn) }, '⛓️ ' + (Array.isArray(task.dependsOn) ? task.dependsOn.join(', ') : task.dependsOn)) : null,
|
|
3268
|
+
task.adaptive?.enabled ? h('span', {
|
|
3205
3269
|
className: 'dsh-cron-type-tag' + (task.adaptiveState?.backedOff ? ' dsh-cron-tag-failure' : ' dsh-cron-tag-success'),
|
|
3206
3270
|
title: 'Adaptive: ' + (task.adaptiveState?.effectiveIntervalStr || task.adaptive.minInterval || '5m') + ' (idle: ' + (task.adaptiveState?.idleCount || 0) + ')'
|
|
3207
3271
|
}, (task.adaptiveState?.backedOff ? '⏳ ' : '⚡ ') + (task.adaptiveState?.effectiveIntervalStr || task.adaptive.minInterval || '5m')) : null,
|
|
3208
|
-
task.heartbeatIntervalSeconds > 0 ?
|
|
3209
|
-
task.targetSessionId ?
|
|
3210
|
-
task.preflightType && task.preflightType !== 'none' ?
|
|
3211
|
-
task.totalCostUsd > 0 ?
|
|
3212
|
-
task.totalTokens > 0 ?
|
|
3213
|
-
task.status === 'paused' && task.pausedReason ?
|
|
3214
|
-
),
|
|
3215
|
-
|
|
3272
|
+
task.heartbeatIntervalSeconds > 0 ? h('span', { className: 'dsh-cron-type-tag dsh-cron-tag-heartbeat', title: 'Heartbeat: every ' + task.heartbeatIntervalSeconds + 's' }, '💓 ' + task.heartbeatIntervalSeconds + 's') : null,
|
|
3273
|
+
task.targetSessionId ? h('span', { className: 'dsh-cron-type-tag dsh-cron-tag-session', title: 'Target session: ' + task.targetSessionId + (task.targetSessionReset && task.targetSessionReset !== 'never' ? ' (' + task.targetSessionReset + ')' : '') }, '🧵 ' + task.targetSessionId) : null,
|
|
3274
|
+
task.preflightType && task.preflightType !== 'none' ? h('span', { className: 'dsh-cron-type-tag dsh-cron-tag-preflight', title: 'Preflight: ' + task.preflightType }, '🛡️ ' + task.preflightType) : null,
|
|
3275
|
+
task.totalCostUsd > 0 ? h('span', { className: 'dsh-cron-cost-tag' }, '$' + task.totalCostUsd.toFixed(4)) : null,
|
|
3276
|
+
task.totalTokens > 0 ? h('span', { className: 'dsh-cron-tokens-tag' }, (task.totalTokens > 1000 ? Math.round(task.totalTokens / 1000) + 'k' : task.totalTokens) + ' tok') : null,
|
|
3277
|
+
task.status === 'paused' && task.pausedReason ? h('span', { className: 'dsh-cron-type-tag dsh-cron-tag-failure', title: task.pausedReason }, '🛑 ' + task.pausedReason) : null
|
|
3278
|
+
),
|
|
3279
|
+
h('div', { className: 'dsh-cron-task-sched' },
|
|
3216
3280
|
task.scheduleText || task.schedule,
|
|
3217
3281
|
task.nextRunAt ? T_KEY(t, 'list.next', { time: new Date(task.nextRunAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) }) : '',
|
|
3218
3282
|
task.running && task.runningSince
|
|
3219
3283
|
? ' · ' + T_KEY(t, 'list.runningNow') + ' ' + Math.max(0, Math.round((Date.now() - task.runningSince) / 1000)) + 's'
|
|
3220
3284
|
: ''
|
|
3221
3285
|
),
|
|
3222
|
-
task.prompt ?
|
|
3286
|
+
task.prompt ? h('div', {
|
|
3223
3287
|
className: 'dsh-cron-task-prompt-preview',
|
|
3224
3288
|
title: task.prompt
|
|
3225
3289
|
}, task.prompt.slice(0, 140) + (task.prompt.length > 140 ? '…' : '')) : null
|
|
3226
3290
|
),
|
|
3227
|
-
|
|
3291
|
+
h('div', {
|
|
3228
3292
|
className: 'dsh-cron-task-actions',
|
|
3229
3293
|
onClick: (e) => e.stopPropagation()
|
|
3230
3294
|
},
|
|
3231
|
-
|
|
3295
|
+
h('button', {
|
|
3232
3296
|
type: 'button',
|
|
3233
3297
|
className: 'dsh-cron-icon-btn',
|
|
3234
3298
|
title: T_KEY(t, 'actions.dryRunTitle'),
|
|
3235
3299
|
onClick: () => handleDryRun(task.id)
|
|
3236
3300
|
}, '🧪'),
|
|
3237
|
-
|
|
3301
|
+
h('button', {
|
|
3238
3302
|
type: 'button',
|
|
3239
3303
|
className: 'dsh-cron-icon-btn' + (task.running ? ' dsh-cron-pulse' : ''),
|
|
3240
3304
|
title: T_KEY(t, 'liveLog.viewLog'),
|
|
3241
3305
|
onClick: () => handleOpenLiveLogs(task)
|
|
3242
3306
|
}, '📺'),
|
|
3243
|
-
|
|
3307
|
+
h('button', {
|
|
3244
3308
|
type: 'button',
|
|
3245
3309
|
className: 'dsh-cron-icon-btn',
|
|
3246
3310
|
title: T_KEY(t, 'actions.archiveTitle'),
|
|
3247
3311
|
onClick: () => openArchiveModal(task, 0)
|
|
3248
3312
|
}, '📜'),
|
|
3249
|
-
(task.onSuccess || task.onFailure || (task.dependsOn && (Array.isArray(task.dependsOn) ? task.dependsOn.length > 0 : Boolean(task.dependsOn)))) ?
|
|
3313
|
+
(task.onSuccess || task.onFailure || (task.dependsOn && (Array.isArray(task.dependsOn) ? task.dependsOn.length > 0 : Boolean(task.dependsOn)))) ? h('button', {
|
|
3250
3314
|
type: 'button',
|
|
3251
3315
|
className: 'dsh-cron-icon-btn',
|
|
3252
3316
|
title: T_KEY(t, 'chainGraph.viewGraph'),
|
|
3253
3317
|
onClick: () => openChainGraphModal(task)
|
|
3254
3318
|
}, '🕸️') : null,
|
|
3255
|
-
|
|
3319
|
+
h('button', {
|
|
3256
3320
|
type: 'button',
|
|
3257
3321
|
className: 'dsh-cron-icon-btn',
|
|
3258
3322
|
title: T_KEY(t, 'actions.runNow'),
|
|
3259
3323
|
onClick: () => handleRunNow(task.id)
|
|
3260
3324
|
}, T_KEY(t, 'actions.runNowShort')),
|
|
3261
|
-
isConfigManaged(task) ? null :
|
|
3325
|
+
isConfigManaged(task) ? null : h('button', {
|
|
3262
3326
|
type: 'button',
|
|
3263
3327
|
className: 'dsh-cron-icon-btn',
|
|
3264
3328
|
title: T_KEY(t, 'actions.edit'),
|
|
3265
3329
|
'aria-label': T_KEY(t, 'actions.edit'),
|
|
3266
3330
|
onClick: () => openEditModal(task)
|
|
3267
|
-
},
|
|
3268
|
-
isConfigManaged(task) ? null :
|
|
3331
|
+
}, h('span', svgProps(ICON_EDIT))),
|
|
3332
|
+
isConfigManaged(task) ? null : h('button', {
|
|
3269
3333
|
type: 'button',
|
|
3270
3334
|
className: 'dsh-cron-icon-btn',
|
|
3271
3335
|
title: T_KEY(t, 'actions.tuneWithDsh'),
|
|
3272
3336
|
'aria-label': T_KEY(t, 'actions.tuneWithDsh'),
|
|
3273
3337
|
onClick: () => handleTuneWithDsh(task)
|
|
3274
|
-
},
|
|
3275
|
-
isConfigManaged(task) ? null :
|
|
3338
|
+
}, h('span', svgProps(ICON_TUNE))),
|
|
3339
|
+
isConfigManaged(task) ? null : h('button', {
|
|
3276
3340
|
type: 'button',
|
|
3277
3341
|
className: 'dsh-cron-icon-btn',
|
|
3278
3342
|
title: T_KEY(t, 'actions.duplicate'),
|
|
3279
3343
|
'aria-label': T_KEY(t, 'actions.duplicate'),
|
|
3280
3344
|
onClick: () => handleDuplicate(task)
|
|
3281
|
-
},
|
|
3282
|
-
isConfigManaged(task) ? null :
|
|
3345
|
+
}, h('span', svgProps(ICON_COPY))),
|
|
3346
|
+
isConfigManaged(task) ? null : h('button', {
|
|
3283
3347
|
type: 'button',
|
|
3284
3348
|
className: 'dsh-cron-icon-btn dsh-cron-danger',
|
|
3285
3349
|
title: T_KEY(t, 'actions.delete'),
|
|
3286
3350
|
'aria-label': T_KEY(t, 'actions.delete'),
|
|
3287
3351
|
onClick: () => handleDelete(task.id)
|
|
3288
|
-
},
|
|
3352
|
+
}, h('span', svgProps(ICON_TRASH)))
|
|
3289
3353
|
)
|
|
3290
3354
|
)
|
|
3291
3355
|
)
|
|
3292
3356
|
),
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3357
|
+
h('div', { className: 'dsh-cron-recs-title' }, T_KEY(t, 'recs.title')),
|
|
3358
|
+
h('div', { className: 'dsh-cron-hint', style: { marginBottom: '8px' } }, T_KEY(t, 'recs.hint')),
|
|
3359
|
+
h('div', { className: 'dsh-cron-recs-list' },
|
|
3296
3360
|
recs.map((rec) =>
|
|
3297
|
-
|
|
3361
|
+
h('div', {
|
|
3298
3362
|
key: rec.id,
|
|
3299
3363
|
className: 'dsh-cron-rec-card',
|
|
3300
3364
|
role: 'button',
|
|
@@ -3307,36 +3371,36 @@ openManualModal(rec);
|
|
|
3307
3371
|
}
|
|
3308
3372
|
}
|
|
3309
3373
|
},
|
|
3310
|
-
|
|
3311
|
-
|
|
3374
|
+
h('div', { className: 'dsh-cron-rec-icon' },
|
|
3375
|
+
h('span', iconHtml(rec.icon === 'bell' ? ICON_BELL : rec.icon === 'clipboard' ? ICON_CLIPBOARD : ICON_ACTIVITY))
|
|
3312
3376
|
),
|
|
3313
|
-
|
|
3314
|
-
|
|
3377
|
+
h('div', { className: 'dsh-cron-rec-content' },
|
|
3378
|
+
h('div', { className: 'dsh-cron-rec-title' },
|
|
3315
3379
|
rec.title,
|
|
3316
|
-
|
|
3380
|
+
h('span', { className: 'dsh-cron-rec-time' }, rec.scheduleText)
|
|
3317
3381
|
),
|
|
3318
|
-
|
|
3382
|
+
h('div', { className: 'dsh-cron-rec-desc' }, rec.description)
|
|
3319
3383
|
)
|
|
3320
3384
|
)
|
|
3321
3385
|
)
|
|
3322
3386
|
)
|
|
3323
3387
|
),
|
|
3324
|
-
manualModalOpen &&
|
|
3388
|
+
manualModalOpen && h('div', {
|
|
3325
3389
|
className: 'dsh-cron-modal-overlay',
|
|
3326
3390
|
onClick: (e) => {
|
|
3327
3391
|
if (e.target === e.currentTarget) closeManualModalWithConfirm();
|
|
3328
3392
|
}
|
|
3329
3393
|
},
|
|
3330
|
-
|
|
3394
|
+
h('div', {
|
|
3331
3395
|
className: 'dsh-cron-modal dsh-cron-modal-scroll',
|
|
3332
3396
|
style: { maxWidth: '640px' },
|
|
3333
3397
|
role: 'dialog',
|
|
3334
3398
|
'aria-modal': 'true',
|
|
3335
3399
|
onClick: (e) => e.stopPropagation()
|
|
3336
3400
|
},
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
selectedTaskMeta &&
|
|
3401
|
+
h('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: formId ? '12px' : '18px' } },
|
|
3402
|
+
h('div', { className: 'dsh-cron-modal-title', style: { margin: 0 } }, formId ? T_KEY(t, 'modal.editTitle') : T_KEY(t, 'modal.newTitle')),
|
|
3403
|
+
selectedTaskMeta && h('span', {
|
|
3340
3404
|
style: {
|
|
3341
3405
|
fontSize: '12px',
|
|
3342
3406
|
padding: '3px 8px',
|
|
@@ -3346,65 +3410,65 @@ color: selectedTaskMeta.status === 'active' ? 'var(--dsh-cron-success)' : 'var(-
|
|
|
3346
3410
|
}
|
|
3347
3411
|
}, selectedTaskMeta.status === 'active' ? T_KEY(t, 'modal.statusActive') : T_KEY(t, 'modal.statusPaused'))
|
|
3348
3412
|
),
|
|
3349
|
-
formId &&
|
|
3350
|
-
|
|
3413
|
+
formId && h('div', { className: 'dsh-cron-modal-nav' },
|
|
3414
|
+
h('button', {
|
|
3351
3415
|
type: 'button',
|
|
3352
3416
|
className: 'dsh-cron-modal-tab',
|
|
3353
3417
|
'data-active': modalTab === 'params' ? 'true' : undefined,
|
|
3354
3418
|
onClick: () => setModalTab('params')
|
|
3355
3419
|
}, T_KEY(t, 'modal.params')),
|
|
3356
|
-
|
|
3420
|
+
h('button', {
|
|
3357
3421
|
type: 'button',
|
|
3358
3422
|
className: 'dsh-cron-modal-tab',
|
|
3359
3423
|
'data-active': modalTab === 'history' ? 'true' : undefined,
|
|
3360
3424
|
onClick: () => { setModalTab('history'); if (formId) loadTaskHistory(formId); }
|
|
3361
3425
|
}, T_KEY(t, 'modal.history', { count: taskHistory.length || 0 }))
|
|
3362
3426
|
),
|
|
3363
|
-
modalTab === 'history' && formId ?
|
|
3364
|
-
historyLoading ?
|
|
3365
|
-
taskHistory.length === 0 ?
|
|
3366
|
-
|
|
3367
|
-
taskHistory.map((run) =>
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3427
|
+
modalTab === 'history' && formId ? h('div', null,
|
|
3428
|
+
historyLoading ? h('div', { className: 'dsh-cron-history-empty' }, T_KEY(t, 'history.loading')) :
|
|
3429
|
+
taskHistory.length === 0 ? h('div', { className: 'dsh-cron-history-empty' }, T_KEY(t, 'history.empty')) :
|
|
3430
|
+
h('div', { className: 'dsh-cron-history-list' },
|
|
3431
|
+
taskHistory.map((run) => h('div', { key: run.id, className: 'dsh-cron-history-item' },
|
|
3432
|
+
h('div', { className: 'dsh-cron-history-head' },
|
|
3433
|
+
h('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
|
|
3434
|
+
h('span', {
|
|
3371
3435
|
className: 'dsh-cron-history-status',
|
|
3372
3436
|
'data-status': run.status
|
|
3373
3437
|
}, statusLabel(t, run.status)),
|
|
3374
|
-
|
|
3438
|
+
h('span', { className: 'dsh-cron-history-time' }, run.at ? new Date(run.at).toLocaleString() : '')
|
|
3375
3439
|
),
|
|
3376
|
-
|
|
3377
|
-
run.costUsd > 0 &&
|
|
3378
|
-
run.usage && (run.usage.inputTokens > 0 || run.usage.outputTokens > 0) &&
|
|
3379
|
-
|
|
3440
|
+
h('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
|
|
3441
|
+
run.costUsd > 0 && h('span', { className: 'dsh-cron-cost-tag' }, '$' + run.costUsd.toFixed(5)),
|
|
3442
|
+
run.usage && (run.usage.inputTokens > 0 || run.usage.outputTokens > 0) && h('span', { className: 'dsh-cron-tokens-tag' }, (run.usage.inputTokens + run.usage.outputTokens) + ' tok'),
|
|
3443
|
+
h('span', { style: { color: 'var(--dsw-alias-label-tertiary, #888)', fontSize: '11.5px' } }, (run.durationMs || 0) + ' ms')
|
|
3380
3444
|
)
|
|
3381
3445
|
),
|
|
3382
|
-
run.stoppedReason &&
|
|
3446
|
+
run.stoppedReason && h('div', {
|
|
3383
3447
|
className: 'dsh-cron-hint',
|
|
3384
3448
|
style: { display: 'flex', gap: '6px', alignItems: 'center', marginTop: '6px' }
|
|
3385
3449
|
},
|
|
3386
|
-
|
|
3387
|
-
|
|
3450
|
+
h('span', { className: 'dsh-cron-badge-ref' }, T_KEY(t, 'history.stoppedReasonTitle')),
|
|
3451
|
+
h('span', null, run.stoppedReason)
|
|
3388
3452
|
),
|
|
3389
|
-
Array.isArray(run.stages) && run.stages.length > 0 &&
|
|
3453
|
+
Array.isArray(run.stages) && run.stages.length > 0 && h('div', {
|
|
3390
3454
|
className: 'dsh-cron-stages-flow',
|
|
3391
3455
|
style: { display: 'flex', gap: '6px', flexWrap: 'wrap', marginTop: '6px' }
|
|
3392
3456
|
},
|
|
3393
|
-
run.stages.map((st) =>
|
|
3457
|
+
run.stages.map((st) => h('span', {
|
|
3394
3458
|
key: st.name,
|
|
3395
3459
|
className: 'dsh-cron-stage-pill',
|
|
3396
3460
|
'data-status': st.status || 'unknown',
|
|
3397
3461
|
title: st.error ? (st.name + ': ' + st.error) : (st.name + (st.durationMs !== undefined ? ' (' + st.durationMs + 'ms)' : ''))
|
|
3398
3462
|
}, (T_KEY(t, 'history.stage_' + st.name) || st.name) + (st.durationMs !== undefined ? ' ' + st.durationMs + 'ms' : '')))
|
|
3399
3463
|
),
|
|
3400
|
-
run.delivery &&
|
|
3464
|
+
run.delivery && h('div', {
|
|
3401
3465
|
style: { display: 'flex', alignItems: 'center', gap: '8px', marginTop: '6px' }
|
|
3402
3466
|
},
|
|
3403
|
-
|
|
3467
|
+
h('span', {
|
|
3404
3468
|
className: 'dsh-cron-badge-ref',
|
|
3405
3469
|
'data-status': run.delivery.status
|
|
3406
3470
|
}, 'Delivery: ' + run.delivery.status),
|
|
3407
|
-
(run.delivery.status === 'failed' || run.delivery.status === 'partial') &&
|
|
3471
|
+
(run.delivery.status === 'failed' || run.delivery.status === 'partial') && h('button', {
|
|
3408
3472
|
type: 'button',
|
|
3409
3473
|
className: 'dsh-cron-btn-secondary',
|
|
3410
3474
|
style: { padding: '2px 8px', fontSize: '11px' },
|
|
@@ -3412,11 +3476,11 @@ disabled: retryingDeliveryId === run.id,
|
|
|
3412
3476
|
onClick: () => handleRetryDelivery(formId, run.id)
|
|
3413
3477
|
}, retryingDeliveryId === run.id ? T_KEY(t, 'history.retryingDelivery') : T_KEY(t, 'history.retryDelivery'))
|
|
3414
3478
|
),
|
|
3415
|
-
run.artifacts && run.artifacts.length > 0 &&
|
|
3479
|
+
run.artifacts && run.artifacts.length > 0 && h('div', {
|
|
3416
3480
|
style: { display: 'flex', flexWrap: 'wrap', gap: '6px', marginTop: '6px', alignItems: 'center' }
|
|
3417
3481
|
},
|
|
3418
|
-
|
|
3419
|
-
run.artifacts.map((art) =>
|
|
3482
|
+
h('span', { className: 'dsh-cron-hint', style: { fontSize: '11px' } }, '📦 ' + T_KEY(t, 'history.artifacts') + ':'),
|
|
3483
|
+
run.artifacts.map((art) => h('a', {
|
|
3420
3484
|
key: art.name || art.id,
|
|
3421
3485
|
href: '/dsh-cron/runs/' + encodeURIComponent(run.id) + '/artifacts/' + encodeURIComponent(art.name) + '/preview',
|
|
3422
3486
|
target: '_blank',
|
|
@@ -3426,20 +3490,20 @@ style: { padding: '2px 8px', fontSize: '11px', textDecoration: 'none' },
|
|
|
3426
3490
|
title: art.name + ' (' + Math.round((art.size || 0) / 1024 * 10) / 10 + ' KB)'
|
|
3427
3491
|
}, art.name))
|
|
3428
3492
|
),
|
|
3429
|
-
run.status === 'uncertain' &&
|
|
3493
|
+
run.status === 'uncertain' && h('div', {
|
|
3430
3494
|
className: 'dsh-cron-status-banner',
|
|
3431
3495
|
'data-type': 'warning',
|
|
3432
3496
|
style: { marginTop: '8px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '8px' }
|
|
3433
3497
|
},
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3498
|
+
h('span', null, '⚠️ ' + T_KEY(t, 'history.statusUncertainHint')),
|
|
3499
|
+
h('div', { style: { display: 'flex', gap: '6px' } },
|
|
3500
|
+
h('button', {
|
|
3437
3501
|
type: 'button',
|
|
3438
3502
|
className: 'dsh-cron-btn-secondary',
|
|
3439
3503
|
style: { padding: '2px 8px', fontSize: '11px' },
|
|
3440
3504
|
onClick: () => handleResolveUncertain(formId, run.id, 'completed')
|
|
3441
3505
|
}, '✓ ' + T_KEY(t, 'history.resolveCompleted')),
|
|
3442
|
-
|
|
3506
|
+
h('button', {
|
|
3443
3507
|
type: 'button',
|
|
3444
3508
|
className: 'dsh-cron-btn-secondary',
|
|
3445
3509
|
style: { padding: '2px 8px', fontSize: '11px' },
|
|
@@ -3447,35 +3511,141 @@ onClick: () => handleResolveUncertain(formId, run.id, 'failed')
|
|
|
3447
3511
|
}, '✕ ' + T_KEY(t, 'history.resolveFailed'))
|
|
3448
3512
|
)
|
|
3449
3513
|
),
|
|
3450
|
-
run.diagnosis &&
|
|
3514
|
+
(run.diagnosis || run.doctorReport) && h('div', {
|
|
3451
3515
|
className: 'dsh-cron-status-banner',
|
|
3452
3516
|
'data-type': 'info',
|
|
3453
3517
|
style: { marginTop: '8px', display: 'flex', flexDirection: 'column', gap: '6px' }
|
|
3454
3518
|
},
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3519
|
+
h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
|
|
3520
|
+
h('strong', null, '🩺 ' + T_KEY(t, run.doctorReport ? 'history.doctorDiagnosis' : 'history.diagnosis')),
|
|
3521
|
+
h('div', { style: { display: 'flex', gap: '6px', alignItems: 'center' } },
|
|
3522
|
+
(run.autoHealed || run.doctorReport?.autoHealed) && h('span', {
|
|
3523
|
+
style: { fontSize: '10px', background: 'var(--dsh-cron-success-bg)', color: 'var(--dsh-cron-success)', padding: '1px 6px', borderRadius: '8px', fontWeight: '600' }
|
|
3524
|
+
}, '✨ ' + T_KEY(t, 'history.autoHealed')),
|
|
3525
|
+
(run.doctorReport?.category || run.category) && h('span', {
|
|
3526
|
+
style: { fontSize: '10px', background: 'var(--dsw-alias-bg-layer-3)', padding: '1px 6px', borderRadius: '4px' }
|
|
3527
|
+
}, run.doctorReport?.category || run.category),
|
|
3528
|
+
run.confidence ? h('span', { style: { fontSize: '10px', color: 'var(--dsw-alias-label-secondary)' } }, '(' + run.confidence + ')') : null
|
|
3529
|
+
)
|
|
3458
3530
|
),
|
|
3459
|
-
|
|
3460
|
-
run.
|
|
3461
|
-
|
|
3531
|
+
h('div', null, run.doctorReport?.cause || run.diagnosis),
|
|
3532
|
+
run.doctorReport?.diff && h('div', {
|
|
3533
|
+
style: {
|
|
3534
|
+
background: 'var(--dsw-alias-bg-layer-2)',
|
|
3535
|
+
border: '1px solid var(--dsw-alias-border-l2)',
|
|
3536
|
+
borderRadius: '4px',
|
|
3537
|
+
padding: '6px',
|
|
3538
|
+
fontFamily: 'monospace',
|
|
3539
|
+
fontSize: '11px',
|
|
3540
|
+
maxHeight: '120px',
|
|
3541
|
+
overflowY: 'auto',
|
|
3542
|
+
whiteSpace: 'pre'
|
|
3543
|
+
}
|
|
3544
|
+
}, run.doctorReport.diff),
|
|
3545
|
+
(run.doctorReport?.suggestedFix || run.suggestion) && h('div', { style: { display: 'flex', gap: '8px', marginTop: '4px' } },
|
|
3546
|
+
typeof handleApplyDoctorFix === 'function' && h('button', {
|
|
3547
|
+
type: 'button',
|
|
3548
|
+
className: 'dsh-cron-btn-primary',
|
|
3549
|
+
style: { padding: '3px 10px', fontSize: '12px' },
|
|
3550
|
+
onClick: () => handleApplyDoctorFix(formId, run.doctorReport || { suggestedFix: run.suggestion })
|
|
3551
|
+
}, '⚡ ' + T_KEY(t, 'history.doctorApply')),
|
|
3552
|
+
h('button', {
|
|
3462
3553
|
type: 'button',
|
|
3463
3554
|
className: 'dsh-cron-btn-secondary',
|
|
3464
|
-
style: { padding: '
|
|
3555
|
+
style: { padding: '3px 10px', fontSize: '12px' },
|
|
3465
3556
|
onClick: () => openEditModal(selectedTaskMeta, { prompt: run.suggestion })
|
|
3466
3557
|
}, T_KEY(t, 'history.applySuggestion'))
|
|
3467
3558
|
)
|
|
3468
3559
|
),
|
|
3469
|
-
run.
|
|
3560
|
+
run.subtaskRuns && Array.isArray(run.subtaskRuns) && run.subtaskRuns.length > 0 && h('div', {
|
|
3561
|
+
style: { marginTop: '8px', padding: '8px', background: 'var(--dsw-alias-bg-layer-2)', borderRadius: '6px', fontSize: '12px' }
|
|
3562
|
+
},
|
|
3563
|
+
h('div', { style: { fontWeight: '600', marginBottom: '4px' } }, '🐝 ' + T_KEY(t, 'history.swarmBadge') + ' (' + run.subtaskRuns.filter(r => r.status === 'success').length + '/' + run.subtaskRuns.length + ')'),
|
|
3564
|
+
h('div', { style: { display: 'flex', flexDirection: 'column', gap: '4px' } },
|
|
3565
|
+
run.subtaskRuns.map((st, sidx) => h('div', {
|
|
3566
|
+
key: sidx,
|
|
3567
|
+
style: { display: 'flex', justifyContent: 'space-between', padding: '2px 6px', background: 'var(--dsw-alias-bg-layer-3)', borderRadius: '4px' }
|
|
3568
|
+
},
|
|
3569
|
+
h('span', null, (st.status === 'success' ? '✅ ' : '❌ ') + st.title),
|
|
3570
|
+
h('span', { style: { color: 'var(--dsw-alias-label-tertiary)', fontSize: '11px' } }, (st.durationMs || 0) + 'ms')
|
|
3571
|
+
))
|
|
3572
|
+
)
|
|
3573
|
+
),
|
|
3574
|
+
run.gitDiff && run.gitDiff.hasChanges && h('div', {
|
|
3575
|
+
className: 'dsh-cron-status-banner',
|
|
3576
|
+
style: { marginTop: '8px', display: 'flex', flexDirection: 'column', gap: '6px' }
|
|
3577
|
+
},
|
|
3578
|
+
h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
|
|
3579
|
+
h('strong', null, '📝 ' + T_KEY(t, 'history.gitDiff')),
|
|
3580
|
+
h('span', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary)' } }, run.gitDiff.stat || '')
|
|
3581
|
+
),
|
|
3582
|
+
run.gitDiff.diff && h('div', {
|
|
3583
|
+
style: {
|
|
3584
|
+
background: 'var(--dsw-alias-bg-layer-2)',
|
|
3585
|
+
border: '1px solid var(--dsw-alias-border-l2)',
|
|
3586
|
+
borderRadius: '4px',
|
|
3587
|
+
padding: '6px',
|
|
3588
|
+
fontFamily: 'monospace',
|
|
3589
|
+
fontSize: '11px',
|
|
3590
|
+
maxHeight: '140px',
|
|
3591
|
+
overflowY: 'auto',
|
|
3592
|
+
whiteSpace: 'pre'
|
|
3593
|
+
}
|
|
3594
|
+
}, run.gitDiff.diff),
|
|
3595
|
+
h('div', { style: { display: 'flex', gap: '8px', marginTop: '4px' } },
|
|
3596
|
+
h('button', {
|
|
3597
|
+
type: 'button',
|
|
3598
|
+
className: 'dsh-cron-btn-secondary',
|
|
3599
|
+
style: { padding: '2px 8px', fontSize: '12px' },
|
|
3600
|
+
onClick: async () => {
|
|
3601
|
+
if (!confirm('Discard all uncommitted changes in task directory?')) return;
|
|
3602
|
+
const c = typeof AbortController !== 'undefined' ? new AbortController() : null;
|
|
3603
|
+
const tId = c ? setTimeout(() => c.abort(), 15000) : null;
|
|
3604
|
+
try {
|
|
3605
|
+
const res = await fetch('/dsh-cron/tasks/' + encodeURIComponent(formId) + '/git-diff/discard', {
|
|
3606
|
+
method: 'POST',
|
|
3607
|
+
signal: c ? c.signal : undefined
|
|
3608
|
+
});
|
|
3609
|
+
const d = await res.json();
|
|
3610
|
+
if (d.ok) { alert('Working directory reset successfully.'); if (formId) loadTaskHistory(formId); }
|
|
3611
|
+
else alert(d.error || 'Failed to discard changes');
|
|
3612
|
+
} catch (e) { alert(e.message); }
|
|
3613
|
+
finally { if (tId) clearTimeout(tId); }
|
|
3614
|
+
}
|
|
3615
|
+
}, '🗑️ ' + T_KEY(t, 'history.discardDiff')),
|
|
3616
|
+
h('button', {
|
|
3617
|
+
type: 'button',
|
|
3618
|
+
className: 'dsh-cron-btn-primary',
|
|
3619
|
+
style: { padding: '2px 8px', fontSize: '12px' },
|
|
3620
|
+
onClick: async () => {
|
|
3621
|
+
const c = typeof AbortController !== 'undefined' ? new AbortController() : null;
|
|
3622
|
+
const tId = c ? setTimeout(() => c.abort(), 15000) : null;
|
|
3623
|
+
try {
|
|
3624
|
+
const res = await fetch('/dsh-cron/tasks/' + encodeURIComponent(formId) + '/git-diff/apply', {
|
|
3625
|
+
method: 'POST',
|
|
3626
|
+
headers: { 'Content-Type': 'application/json' },
|
|
3627
|
+
signal: c ? c.signal : undefined,
|
|
3628
|
+
body: JSON.stringify({ diff: run.gitDiff.diff })
|
|
3629
|
+
});
|
|
3630
|
+
const d = await res.json();
|
|
3631
|
+
if (d.ok) { alert('Patch applied successfully.'); if (formId) loadTaskHistory(formId); }
|
|
3632
|
+
else alert(d.error || 'Failed to apply patch');
|
|
3633
|
+
} catch (e) { alert(e.message); }
|
|
3634
|
+
finally { if (tId) clearTimeout(tId); }
|
|
3635
|
+
}
|
|
3636
|
+
}, '✅ ' + T_KEY(t, 'history.applyDiff'))
|
|
3637
|
+
)
|
|
3638
|
+
),
|
|
3639
|
+
run.silentSkip && h('div', {
|
|
3470
3640
|
className: 'dsh-cron-hint',
|
|
3471
3641
|
style: { display: 'flex', gap: '6px', alignItems: 'center' }
|
|
3472
3642
|
},
|
|
3473
|
-
|
|
3474
|
-
|
|
3643
|
+
h('span', { className: 'dsh-cron-badge-ref' }, T_KEY(t, 'history.silentSkip')),
|
|
3644
|
+
h('span', null, run.silentReason || '')
|
|
3475
3645
|
),
|
|
3476
|
-
run.output &&
|
|
3477
|
-
run.error &&
|
|
3478
|
-
run.sessionId &&
|
|
3646
|
+
run.output && h('div', { className: 'dsh-cron-history-output' }, run.output),
|
|
3647
|
+
run.error && h('div', { className: 'dsh-cron-history-output', style: { color: 'var(--dsh-cron-danger)', borderColor: 'var(--dsh-cron-danger-bg)' } }, run.error),
|
|
3648
|
+
run.sessionId && h('button', {
|
|
3479
3649
|
type: 'button',
|
|
3480
3650
|
className: 'dsh-cron-btn-secondary',
|
|
3481
3651
|
style: { marginTop: '8px', fontSize: '12px', padding: '4px 10px' },
|
|
@@ -3483,23 +3653,23 @@ onClick: () => openSession(ctx, run.sessionId)
|
|
|
3483
3653
|
}, T_KEY(t, 'history.openSession'))
|
|
3484
3654
|
))
|
|
3485
3655
|
),
|
|
3486
|
-
|
|
3487
|
-
|
|
3656
|
+
h('div', { className: 'dsh-cron-modal-foot', style: { marginTop: '18px' } },
|
|
3657
|
+
h('button', {
|
|
3488
3658
|
type: 'button',
|
|
3489
3659
|
className: 'dsh-cron-btn-secondary',
|
|
3490
3660
|
onClick: () => { if (formId) loadTaskHistory(formId); }
|
|
3491
3661
|
}, T_KEY(t, 'history.refresh')),
|
|
3492
|
-
|
|
3662
|
+
h('button', {
|
|
3493
3663
|
type: 'button',
|
|
3494
3664
|
className: 'dsh-cron-btn-primary',
|
|
3495
3665
|
onClick: closeManualModalWithConfirm
|
|
3496
3666
|
}, T_KEY(t, 'modal.close'))
|
|
3497
3667
|
)
|
|
3498
3668
|
) :
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3669
|
+
h('form', { onSubmit: handleSaveManual },
|
|
3670
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3671
|
+
h('label', null, T_KEY(t, 'form.nameLabel')),
|
|
3672
|
+
h('input', {
|
|
3503
3673
|
required: true,
|
|
3504
3674
|
autoFocus: true,
|
|
3505
3675
|
value: formTitle,
|
|
@@ -3507,40 +3677,40 @@ placeholder: T_KEY(t, 'form.namePlaceholder'),
|
|
|
3507
3677
|
onChange: (e) => setFormTitle(e.target.value)
|
|
3508
3678
|
})
|
|
3509
3679
|
),
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3680
|
+
h('div', { className: 'dsh-cron-form-row' },
|
|
3681
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3682
|
+
h('label', null, T_KEY(t, 'form.typeLabel')),
|
|
3683
|
+
h('select', {
|
|
3514
3684
|
value: formType,
|
|
3515
3685
|
onChange: (e) => setFormType(e.target.value)
|
|
3516
3686
|
},
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3687
|
+
h('option', { value: 'llm' }, T_KEY(t, 'form.typeLlm')),
|
|
3688
|
+
h('option', { value: 'script' }, T_KEY(t, 'form.typeScript')),
|
|
3689
|
+
h('option', { value: 'node' }, T_KEY(t, 'form.typeNode')),
|
|
3690
|
+
h('option', { value: 'python' }, T_KEY(t, 'form.typePython')),
|
|
3691
|
+
h('option', { value: 'http' }, T_KEY(t, 'form.typeHttp')),
|
|
3692
|
+
h('option', { value: 'ssh' }, T_KEY(t, 'form.typeSsh')),
|
|
3693
|
+
h('option', { value: 'docker' }, T_KEY(t, 'form.typeDocker')),
|
|
3694
|
+
h('option', { value: 'skill' }, T_KEY(t, 'form.typeSkill')),
|
|
3695
|
+
h('option', { value: 'workflow' }, T_KEY(t, 'form.typeWorkflow'))
|
|
3526
3696
|
)
|
|
3527
3697
|
),
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3698
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3699
|
+
h('label', null, T_KEY(t, 'form.scheduleLabel')),
|
|
3700
|
+
h('input', {
|
|
3531
3701
|
required: true,
|
|
3532
3702
|
value: formSchedule,
|
|
3533
3703
|
placeholder: T_KEY(t, 'form.schedulePlaceholder'),
|
|
3534
3704
|
onChange: (e) => setFormSchedule(e.target.value)
|
|
3535
3705
|
}),
|
|
3536
|
-
|
|
3706
|
+
h('div', { style: { display: 'flex', gap: '5px', flexWrap: 'wrap', marginTop: '5px' } },
|
|
3537
3707
|
[
|
|
3538
3708
|
{ label: '15m', expr: '*/15 * * * *' },
|
|
3539
3709
|
{ label: '1h', expr: '0 * * * *' },
|
|
3540
3710
|
{ label: 'Daily 09:00', expr: '0 9 * * *' },
|
|
3541
3711
|
{ label: 'Weekdays', expr: '0 9 * * 1-5' },
|
|
3542
3712
|
{ label: 'Weekly Mon', expr: '0 9 * * 1' },
|
|
3543
|
-
].map((p) =>
|
|
3713
|
+
].map((p) => h('button', {
|
|
3544
3714
|
key: p.label,
|
|
3545
3715
|
type: 'button',
|
|
3546
3716
|
className: 'dsh-cron-btn-secondary',
|
|
@@ -3548,23 +3718,23 @@ style: { padding: '2px 7px', fontSize: '11px', borderRadius: '4px' },
|
|
|
3548
3718
|
onClick: () => { setFormSchedule(p.expr); handlePreviewSchedule(p.expr); }
|
|
3549
3719
|
}, p.label))
|
|
3550
3720
|
),
|
|
3551
|
-
|
|
3552
|
-
|
|
3721
|
+
h('div', { style: { display: 'flex', gap: '8px', alignItems: 'center', marginTop: '6px' } },
|
|
3722
|
+
h('button', {
|
|
3553
3723
|
type: 'button',
|
|
3554
3724
|
className: 'dsh-cron-btn-secondary',
|
|
3555
3725
|
style: { padding: '3px 8px', fontSize: '11.5px' },
|
|
3556
3726
|
onClick: () => handlePreviewSchedule(formSchedule)
|
|
3557
3727
|
}, T_KEY(t, 'form.previewSchedule')),
|
|
3558
|
-
schedulePreviewRuns && schedulePreviewRuns.length > 0 &&
|
|
3728
|
+
schedulePreviewRuns && schedulePreviewRuns.length > 0 && h('div', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #999)' } },
|
|
3559
3729
|
T_KEY(t, 'form.previewScheduleTitle') + ' ' + schedulePreviewRuns.slice(0, 3).map(r => new Date(r).toLocaleTimeString()).join(', ')
|
|
3560
3730
|
)
|
|
3561
3731
|
)
|
|
3562
3732
|
)
|
|
3563
3733
|
),
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3734
|
+
h('div', { className: 'dsh-cron-form-row' },
|
|
3735
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3736
|
+
h('label', null, T_KEY(t, 'form.timeoutLabel')),
|
|
3737
|
+
h('input', {
|
|
3568
3738
|
type: 'number',
|
|
3569
3739
|
min: 1,
|
|
3570
3740
|
value: formTimeoutSeconds,
|
|
@@ -3572,44 +3742,44 @@ placeholder: '1800',
|
|
|
3572
3742
|
onChange: (e) => setFormTimeoutSeconds(e.target.value)
|
|
3573
3743
|
})
|
|
3574
3744
|
),
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3745
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3746
|
+
h('label', null, T_KEY(t, 'form.overlapLabel')),
|
|
3747
|
+
h('select', {
|
|
3578
3748
|
value: formOverlapPolicy,
|
|
3579
3749
|
onChange: (e) => setFormOverlapPolicy(e.target.value)
|
|
3580
3750
|
},
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3751
|
+
h('option', { value: 'skip' }, T_KEY(t, 'form.overlapSkip')),
|
|
3752
|
+
h('option', { value: 'queue' }, T_KEY(t, 'form.overlapQueue')),
|
|
3753
|
+
h('option', { value: 'replace' }, T_KEY(t, 'form.overlapReplace'))
|
|
3584
3754
|
)
|
|
3585
3755
|
)
|
|
3586
3756
|
),
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3757
|
+
h('div', { className: 'dsh-cron-form-row' },
|
|
3758
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3759
|
+
h('label', null, T_KEY(t, 'form.timezoneLabel')),
|
|
3760
|
+
h('input', {
|
|
3591
3761
|
value: formTimezone,
|
|
3592
3762
|
placeholder: T_KEY(t, 'form.timezonePlaceholder'),
|
|
3593
3763
|
onChange: (e) => setFormTimezone(e.target.value)
|
|
3594
3764
|
})
|
|
3595
3765
|
),
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3766
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3767
|
+
h('label', null, T_KEY(t, 'form.misfireLabel')),
|
|
3768
|
+
h('select', {
|
|
3599
3769
|
value: formMisfirePolicy,
|
|
3600
3770
|
onChange: (e) => setFormMisfirePolicy(e.target.value)
|
|
3601
3771
|
},
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3772
|
+
h('option', { value: 'skip' }, T_KEY(t, 'form.misfireSkip')),
|
|
3773
|
+
h('option', { value: 'runOnce' }, T_KEY(t, 'form.misfireRunOnce')),
|
|
3774
|
+
h('option', { value: 'catchUpAll' }, T_KEY(t, 'form.misfireCatchUp'))
|
|
3605
3775
|
)
|
|
3606
3776
|
)
|
|
3607
3777
|
),
|
|
3608
3778
|
AGENT_FORM_TYPES.includes(formType) ? (
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3779
|
+
h('div', { className: 'dsh-cron-form-row' },
|
|
3780
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3781
|
+
h('label', null, T_KEY(t, 'form.retriesLabel')),
|
|
3782
|
+
h('input', {
|
|
3613
3783
|
type: 'number',
|
|
3614
3784
|
min: 0,
|
|
3615
3785
|
value: formMaxRetries,
|
|
@@ -3617,23 +3787,23 @@ placeholder: '0',
|
|
|
3617
3787
|
onChange: (e) => setFormMaxRetries(e.target.value)
|
|
3618
3788
|
})
|
|
3619
3789
|
),
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3790
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3791
|
+
h('label', null, T_KEY(t, 'form.permissionLabel')),
|
|
3792
|
+
h('select', {
|
|
3623
3793
|
value: formPermissionPreset,
|
|
3624
3794
|
onChange: (e) => setFormPermissionPreset(e.target.value)
|
|
3625
3795
|
},
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3796
|
+
h('option', { value: 'default' }, T_KEY(t, 'form.permissionDefault')),
|
|
3797
|
+
h('option', { value: 'read-only' }, T_KEY(t, 'form.permissionReadonly')),
|
|
3798
|
+
h('option', { value: 'workspace-write' }, T_KEY(t, 'form.permissionWrite')),
|
|
3799
|
+
h('option', { value: 'full' }, T_KEY(t, 'form.permissionFull'))
|
|
3630
3800
|
)
|
|
3631
3801
|
)
|
|
3632
3802
|
)
|
|
3633
3803
|
) : (
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3804
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3805
|
+
h('label', null, T_KEY(t, 'form.retriesLabel')),
|
|
3806
|
+
h('input', {
|
|
3637
3807
|
type: 'number',
|
|
3638
3808
|
min: 0,
|
|
3639
3809
|
value: formMaxRetries,
|
|
@@ -3642,114 +3812,114 @@ onChange: (e) => setFormMaxRetries(e.target.value)
|
|
|
3642
3812
|
})
|
|
3643
3813
|
)
|
|
3644
3814
|
),
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3815
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3816
|
+
h('label', null, T_KEY(t, 'form.kanbanLabel')),
|
|
3817
|
+
h('select', {
|
|
3648
3818
|
value: formKanbanMode,
|
|
3649
3819
|
onChange: (e) => setFormKanbanMode(e.target.value)
|
|
3650
3820
|
},
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3821
|
+
h('option', { value: 'none' }, T_KEY(t, 'form.kanbanNone')),
|
|
3822
|
+
h('option', { value: 'on_failure' }, T_KEY(t, 'form.kanbanOnFailure')),
|
|
3823
|
+
h('option', { value: 'always' }, T_KEY(t, 'form.kanbanAlways'))
|
|
3654
3824
|
)
|
|
3655
3825
|
),
|
|
3656
|
-
AGENT_FORM_TYPES.includes(formType) &&
|
|
3657
|
-
|
|
3658
|
-
|
|
3826
|
+
AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-group' },
|
|
3827
|
+
h('label', null, T_KEY(t, 'form.agentPresetLabel')),
|
|
3828
|
+
h('input', {
|
|
3659
3829
|
type: 'text',
|
|
3660
3830
|
value: formAgentPreset,
|
|
3661
3831
|
placeholder: T_KEY(t, 'form.agentPresetPlaceholder'),
|
|
3662
3832
|
onChange: (e) => setFormAgentPreset(e.target.value)
|
|
3663
3833
|
}),
|
|
3664
|
-
|
|
3834
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.agentPresetHint'))
|
|
3665
3835
|
),
|
|
3666
|
-
AGENT_FORM_TYPES.includes(formType) &&
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3836
|
+
AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-row' },
|
|
3837
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3838
|
+
h('label', null, T_KEY(t, 'form.targetSessionIdLabel')),
|
|
3839
|
+
h('input', {
|
|
3670
3840
|
type: 'text',
|
|
3671
3841
|
value: formTargetSessionId,
|
|
3672
3842
|
placeholder: T_KEY(t, 'form.targetSessionIdPlaceholder'),
|
|
3673
3843
|
onChange: (e) => setFormTargetSessionId(e.target.value)
|
|
3674
3844
|
}),
|
|
3675
|
-
|
|
3845
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.targetSessionIdHint'))
|
|
3676
3846
|
),
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3847
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3848
|
+
h('label', null, T_KEY(t, 'form.targetSessionResetLabel')),
|
|
3849
|
+
h('select', {
|
|
3680
3850
|
value: formTargetSessionReset,
|
|
3681
3851
|
onChange: (e) => setFormTargetSessionReset(e.target.value)
|
|
3682
3852
|
},
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3853
|
+
h('option', { value: 'never' }, T_KEY(t, 'form.targetSessionResetNever')),
|
|
3854
|
+
h('option', { value: 'daily' }, T_KEY(t, 'form.targetSessionResetDaily')),
|
|
3855
|
+
h('option', { value: 'weekly' }, T_KEY(t, 'form.targetSessionResetWeekly'))
|
|
3686
3856
|
),
|
|
3687
|
-
|
|
3857
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.targetSessionResetHint'))
|
|
3688
3858
|
)
|
|
3689
3859
|
),
|
|
3690
|
-
AGENT_FORM_TYPES.includes(formType) &&
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3860
|
+
AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-row' },
|
|
3861
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3862
|
+
h('label', null, T_KEY(t, 'form.providerLabel')),
|
|
3863
|
+
h('select', {
|
|
3694
3864
|
value: formProvider,
|
|
3695
3865
|
onChange: handleProviderChange
|
|
3696
3866
|
},
|
|
3697
|
-
|
|
3698
|
-
providers.map((p) =>
|
|
3867
|
+
h('option', { value: '' }, T_KEY(t, 'form.providerDefault')),
|
|
3868
|
+
providers.map((p) => h('option', { key: p.id, value: p.id }, p.name || p.id))
|
|
3699
3869
|
)
|
|
3700
3870
|
),
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3871
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3872
|
+
h('label', null, T_KEY(t, 'form.modelLabel')),
|
|
3873
|
+
h('select', {
|
|
3704
3874
|
value: formModel,
|
|
3705
3875
|
onChange: (e) => setFormModel(e.target.value)
|
|
3706
3876
|
},
|
|
3707
|
-
|
|
3708
|
-
models.map((m) =>
|
|
3877
|
+
h('option', { value: '' }, T_KEY(t, 'form.modelDefault')),
|
|
3878
|
+
models.map((m) => h('option', { key: m.id, value: m.id }, m.name || m.id))
|
|
3709
3879
|
)
|
|
3710
3880
|
),
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3881
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3882
|
+
h('label', null, T_KEY(t, 'form.fallbackModelLabel')),
|
|
3883
|
+
h('input', {
|
|
3714
3884
|
type: 'text',
|
|
3715
3885
|
value: formFallbackModel,
|
|
3716
3886
|
placeholder: T_KEY(t, 'form.fallbackModelPlaceholder'),
|
|
3717
3887
|
onChange: (e) => setFormFallbackModel(e.target.value)
|
|
3718
3888
|
}),
|
|
3719
|
-
|
|
3889
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.fallbackModelHint'))
|
|
3720
3890
|
),
|
|
3721
|
-
|
|
3722
|
-
|
|
3891
|
+
h('label', { className: 'dsh-cron-checkbox-row', style: { marginTop: '4px' } },
|
|
3892
|
+
h('input', {
|
|
3723
3893
|
type: 'checkbox',
|
|
3724
3894
|
checked: formInspectOnFailure,
|
|
3725
3895
|
onChange: (e) => setFormInspectOnFailure(e.target.checked)
|
|
3726
3896
|
}),
|
|
3727
|
-
|
|
3897
|
+
h('span', null, T_KEY(t, 'form.inspectOnFailureLabel'))
|
|
3728
3898
|
),
|
|
3729
|
-
formInspectOnFailure &&
|
|
3730
|
-
|
|
3731
|
-
|
|
3899
|
+
formInspectOnFailure && h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.inspectOnFailureHint')),
|
|
3900
|
+
h('label', { className: 'dsh-cron-checkbox-row', style: { marginTop: '8px' } },
|
|
3901
|
+
h('input', {
|
|
3732
3902
|
type: 'checkbox',
|
|
3733
3903
|
checked: formRequireApproval,
|
|
3734
3904
|
onChange: (e) => setFormRequireApproval(e.target.checked)
|
|
3735
3905
|
}),
|
|
3736
|
-
|
|
3906
|
+
h('span', null, T_KEY(t, 'form.requireApprovalLabel'))
|
|
3737
3907
|
),
|
|
3738
|
-
formRequireApproval &&
|
|
3908
|
+
formRequireApproval && h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.requireApprovalHint'))
|
|
3739
3909
|
),
|
|
3740
|
-
formType === 'http' &&
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3910
|
+
formType === 'http' && h('div', { className: 'dsh-cron-form-row' },
|
|
3911
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3912
|
+
h('label', null, T_KEY(t, 'form.httpMethodLabel')),
|
|
3913
|
+
h('select', {
|
|
3744
3914
|
value: formHttpMethod,
|
|
3745
3915
|
onChange: (e) => setFormHttpMethod(e.target.value)
|
|
3746
3916
|
},
|
|
3747
|
-
['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'].map((m) =>
|
|
3917
|
+
['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'].map((m) => h('option', { key: m, value: m }, m))
|
|
3748
3918
|
)
|
|
3749
3919
|
),
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3920
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3921
|
+
h('label', null, T_KEY(t, 'form.httpUrlLabel')),
|
|
3922
|
+
h('input', {
|
|
3753
3923
|
required: true,
|
|
3754
3924
|
value: formHttpUrl,
|
|
3755
3925
|
placeholder: 'https://example.test/webhook',
|
|
@@ -3757,41 +3927,41 @@ onChange: (e) => setFormHttpUrl(e.target.value)
|
|
|
3757
3927
|
})
|
|
3758
3928
|
)
|
|
3759
3929
|
),
|
|
3760
|
-
formType === 'http' &&
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3930
|
+
formType === 'http' && h('div', { className: 'dsh-cron-form-row' },
|
|
3931
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3932
|
+
h('label', null, T_KEY(t, 'form.httpHeadersLabel')),
|
|
3933
|
+
h('input', {
|
|
3764
3934
|
value: formHttpHeaders,
|
|
3765
3935
|
placeholder: '{"Authorization":"Bearer ..."}',
|
|
3766
3936
|
onChange: (e) => setFormHttpHeaders(e.target.value)
|
|
3767
3937
|
})
|
|
3768
3938
|
),
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3939
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3940
|
+
h('label', null, T_KEY(t, 'form.httpBodyLabel')),
|
|
3941
|
+
h('input', {
|
|
3772
3942
|
value: formHttpBody,
|
|
3773
3943
|
onChange: (e) => setFormHttpBody(e.target.value)
|
|
3774
3944
|
})
|
|
3775
3945
|
)
|
|
3776
3946
|
),
|
|
3777
|
-
formType === 'ssh' &&
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3947
|
+
formType === 'ssh' && h('div', { className: 'dsh-cron-form-row' },
|
|
3948
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3949
|
+
h('label', null, T_KEY(t, 'form.sshProfileLabel')),
|
|
3950
|
+
h('input', {
|
|
3781
3951
|
value: formSshProfileId,
|
|
3782
3952
|
placeholder: 'prod-web',
|
|
3783
3953
|
onChange: (e) => setFormSshProfileId(e.target.value)
|
|
3784
3954
|
}),
|
|
3785
|
-
|
|
3955
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.sshProfileHint'))
|
|
3786
3956
|
),
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3957
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3958
|
+
h('label', null, T_KEY(t, 'form.sshTargetLabel')),
|
|
3959
|
+
h('input', {
|
|
3790
3960
|
value: formSshTarget,
|
|
3791
3961
|
placeholder: 'user@example.com',
|
|
3792
3962
|
onChange: (e) => setFormSshTarget(e.target.value)
|
|
3793
3963
|
}),
|
|
3794
|
-
|
|
3964
|
+
h('input', {
|
|
3795
3965
|
style: { marginTop: '6px' },
|
|
3796
3966
|
value: formSshKeyPath,
|
|
3797
3967
|
placeholder: '~/.ssh/id_ed25519',
|
|
@@ -3799,93 +3969,93 @@ onChange: (e) => setFormSshKeyPath(e.target.value)
|
|
|
3799
3969
|
})
|
|
3800
3970
|
)
|
|
3801
3971
|
),
|
|
3802
|
-
formType === 'docker' &&
|
|
3803
|
-
|
|
3804
|
-
|
|
3972
|
+
formType === 'docker' && h('div', { className: 'dsh-cron-form-group' },
|
|
3973
|
+
h('label', null, T_KEY(t, 'form.dockerImageLabel')),
|
|
3974
|
+
h('input', {
|
|
3805
3975
|
required: true,
|
|
3806
3976
|
value: formDockerImage,
|
|
3807
3977
|
placeholder: 'alpine:3.20',
|
|
3808
3978
|
onChange: (e) => setFormDockerImage(e.target.value)
|
|
3809
3979
|
})
|
|
3810
3980
|
),
|
|
3811
|
-
formType === 'skill' &&
|
|
3812
|
-
|
|
3813
|
-
|
|
3981
|
+
formType === 'skill' && h('div', { className: 'dsh-cron-form-group' },
|
|
3982
|
+
h('label', null, T_KEY(t, 'form.skillNameLabel')),
|
|
3983
|
+
h('input', {
|
|
3814
3984
|
value: formSkillName,
|
|
3815
3985
|
placeholder: 'gitea',
|
|
3816
3986
|
onChange: (e) => setFormSkillName(e.target.value)
|
|
3817
3987
|
})
|
|
3818
3988
|
),
|
|
3819
|
-
formType === 'workflow' &&
|
|
3820
|
-
|
|
3821
|
-
|
|
3989
|
+
formType === 'workflow' && h('div', { className: 'dsh-cron-form-group' },
|
|
3990
|
+
h('label', null, T_KEY(t, 'form.workflowNameLabel')),
|
|
3991
|
+
h('input', {
|
|
3822
3992
|
value: formWorkflowName,
|
|
3823
3993
|
placeholder: 'nightly-release',
|
|
3824
3994
|
onChange: (e) => setFormWorkflowName(e.target.value)
|
|
3825
3995
|
})
|
|
3826
3996
|
),
|
|
3827
|
-
(formType === 'node' || formType === 'python') &&
|
|
3828
|
-
|
|
3829
|
-
|
|
3997
|
+
(formType === 'node' || formType === 'python') && h('div', { className: 'dsh-cron-form-group' },
|
|
3998
|
+
h('label', null, formType === 'node' ? 'Node.js binary (optional)' : 'Python interpreter (optional)'),
|
|
3999
|
+
h('input', {
|
|
3830
4000
|
value: formType === 'node' ? formNodePath : formPythonPath,
|
|
3831
4001
|
placeholder: formType === 'node' ? 'auto' : '.venv/bin/python',
|
|
3832
4002
|
onChange: (e) => (formType === 'node' ? setFormNodePath(e.target.value) : setFormPythonPath(e.target.value))
|
|
3833
4003
|
})
|
|
3834
4004
|
),
|
|
3835
|
-
!AGENT_FORM_TYPES.includes(formType) &&
|
|
3836
|
-
|
|
3837
|
-
|
|
4005
|
+
!AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-group' },
|
|
4006
|
+
h('label', null, T_KEY(t, 'form.envLabel')),
|
|
4007
|
+
h('textarea', {
|
|
3838
4008
|
rows: 3,
|
|
3839
4009
|
style: { fontFamily: 'monospace', fontSize: '12.5px' },
|
|
3840
4010
|
value: formEnv,
|
|
3841
4011
|
placeholder: T_KEY(t, 'form.envPlaceholder'),
|
|
3842
4012
|
onChange: (e) => setFormEnv(e.target.value)
|
|
3843
4013
|
}),
|
|
3844
|
-
|
|
4014
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.envHint'))
|
|
3845
4015
|
),
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
4016
|
+
h('div', { className: 'dsh-cron-form-row' },
|
|
4017
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4018
|
+
h('label', null, T_KEY(t, 'form.cwdLabel')),
|
|
4019
|
+
h('input', {
|
|
3850
4020
|
value: formCwd,
|
|
3851
4021
|
placeholder: '/srv/app',
|
|
3852
4022
|
onChange: (e) => setFormCwd(e.target.value)
|
|
3853
4023
|
})
|
|
3854
4024
|
),
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
4025
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4026
|
+
h('label', null, T_KEY(t, 'form.workspaceLabel')),
|
|
4027
|
+
h('input', {
|
|
3858
4028
|
value: formWorkspaceId,
|
|
3859
4029
|
onChange: (e) => setFormWorkspaceId(e.target.value)
|
|
3860
4030
|
})
|
|
3861
4031
|
)
|
|
3862
4032
|
),
|
|
3863
|
-
AGENT_FORM_TYPES.includes(formType) &&
|
|
3864
|
-
|
|
3865
|
-
|
|
4033
|
+
AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-group' },
|
|
4034
|
+
h('label', { className: 'dsh-cron-checkbox-row' },
|
|
4035
|
+
h('input', {
|
|
3866
4036
|
type: 'checkbox',
|
|
3867
4037
|
checked: formWorktree,
|
|
3868
4038
|
onChange: (e) => setFormWorktree(e.target.checked)
|
|
3869
4039
|
}),
|
|
3870
|
-
|
|
4040
|
+
h('span', null, T_KEY(t, 'form.worktreeLabel'))
|
|
3871
4041
|
),
|
|
3872
|
-
formWorktree &&
|
|
3873
|
-
|
|
4042
|
+
formWorktree && h('label', { className: 'dsh-cron-checkbox-row', style: { marginLeft: '24px', marginTop: '6px' } },
|
|
4043
|
+
h('input', {
|
|
3874
4044
|
type: 'checkbox',
|
|
3875
4045
|
checked: formKeepWorktree,
|
|
3876
4046
|
onChange: (e) => setFormKeepWorktree(e.target.checked)
|
|
3877
4047
|
}),
|
|
3878
|
-
|
|
4048
|
+
h('span', null, T_KEY(t, 'form.keepWorktreeLabel'))
|
|
3879
4049
|
)
|
|
3880
4050
|
),
|
|
3881
|
-
formType !== 'http' &&
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
(selectedTaskMeta && selectedTaskMeta.promptHistory && selectedTaskMeta.promptHistory.length > 0) ?
|
|
3885
|
-
|
|
4051
|
+
formType !== 'http' && h('div', { className: 'dsh-cron-form-group' },
|
|
4052
|
+
h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '4px' } },
|
|
4053
|
+
h('label', { style: { margin: 0 } }, AGENT_FORM_TYPES.includes(formType) ? T_KEY(t, 'form.promptLabelLlm') : T_KEY(t, 'form.promptLabelScript')),
|
|
4054
|
+
(selectedTaskMeta && selectedTaskMeta.promptHistory && selectedTaskMeta.promptHistory.length > 0) ? h('div', { style: { display: 'flex', gap: '6px', alignItems: 'center' } },
|
|
4055
|
+
h('span', {
|
|
3886
4056
|
style: { fontSize: '11px', padding: '1px 6px', borderRadius: '4px', background: 'var(--dsw-alias-bg-layer-3, #222)', color: 'var(--dsh-cron-info, #4af)', border: '1px solid var(--dsw-alias-border-l2, #333)' }
|
|
3887
4057
|
}, 'v' + (selectedTaskMeta.promptVersion || 1) + ' (' + (selectedTaskMeta.promptHistory[selectedTaskMeta.promptHistory.length - 1]?.successRate !== undefined ? Math.round(selectedTaskMeta.promptHistory[selectedTaskMeta.promptHistory.length - 1].successRate * 100) : 100) + '% SR)'),
|
|
3888
|
-
|
|
4058
|
+
h('select', {
|
|
3889
4059
|
style: { fontSize: '11px', padding: '1px 4px', background: 'var(--dsw-alias-bg-base, #111)', color: 'var(--dsw-alias-label-primary, #ddd)', border: '1px solid var(--dsw-alias-border-l2, #333)', borderRadius: '4px' },
|
|
3890
4060
|
onChange: (e) => {
|
|
3891
4061
|
const targetV = Number(e.target.value);
|
|
@@ -3895,11 +4065,11 @@ setFormPrompt(entry.prompt);
|
|
|
3895
4065
|
}
|
|
3896
4066
|
}
|
|
3897
4067
|
},
|
|
3898
|
-
selectedTaskMeta.promptHistory.map((h) =>
|
|
4068
|
+
selectedTaskMeta.promptHistory.map((h) => h('option', { key: h.version, value: h.version }, 'v' + h.version + ' (' + Math.round((h.successRate || 1) * 100) + '%)'))
|
|
3899
4069
|
)
|
|
3900
4070
|
) : null
|
|
3901
4071
|
),
|
|
3902
|
-
|
|
4072
|
+
h('textarea', {
|
|
3903
4073
|
required: true,
|
|
3904
4074
|
rows: 9,
|
|
3905
4075
|
style: { fontFamily: 'monospace', fontSize: '12.5px', lineHeight: '1.45' },
|
|
@@ -3918,7 +4088,7 @@ placeholder: AGENT_FORM_TYPES.includes(formType)
|
|
|
3918
4088
|
onChange: (e) => setFormPrompt(e.target.value)
|
|
3919
4089
|
})
|
|
3920
4090
|
),
|
|
3921
|
-
|
|
4091
|
+
h('div', {
|
|
3922
4092
|
style: {
|
|
3923
4093
|
background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary) 2%, transparent))',
|
|
3924
4094
|
border: '1px solid var(--dsw-alias-border-l2)',
|
|
@@ -3927,31 +4097,31 @@ padding: '12px 14px',
|
|
|
3927
4097
|
marginBottom: '16px'
|
|
3928
4098
|
}
|
|
3929
4099
|
},
|
|
3930
|
-
|
|
3931
|
-
|
|
4100
|
+
h('div', { style: { fontWeight: 500, fontSize: '13px', color: 'var(--dsw-alias-label-primary, #eee)', marginBottom: '8px', display: 'flex', alignItems: 'center', gap: '6px' } },
|
|
4101
|
+
h('span', { style: { display: 'flex', alignItems: 'center', color: 'var(--dsh-cron-info)' }, ...iconHtml(ICON_TELEGRAM) }),
|
|
3932
4102
|
T_KEY(t, 'form.notifyTitle')
|
|
3933
4103
|
),
|
|
3934
|
-
|
|
3935
|
-
|
|
4104
|
+
h('label', { className: 'dsh-cron-checkbox-row', style: { marginBottom: formNotifyTelegram ? '8px' : '0' } },
|
|
4105
|
+
h('input', {
|
|
3936
4106
|
type: 'checkbox',
|
|
3937
4107
|
checked: formNotifyTelegram,
|
|
3938
4108
|
onChange: (e) => setFormNotifyTelegram(e.target.checked)
|
|
3939
4109
|
}),
|
|
3940
|
-
|
|
4110
|
+
h('span', null, T_KEY(t, 'form.notifyTelegram'))
|
|
3941
4111
|
),
|
|
3942
|
-
(formNotifyTelegram || formChannels.length > 0) &&
|
|
3943
|
-
|
|
4112
|
+
(formNotifyTelegram || formChannels.length > 0) && h('label', { className: 'dsh-cron-checkbox-row', style: { marginLeft: '24px', marginTop: '6px' } },
|
|
4113
|
+
h('input', {
|
|
3944
4114
|
type: 'checkbox',
|
|
3945
4115
|
checked: formOnlyOnFailure,
|
|
3946
4116
|
onChange: (e) => setFormOnlyOnFailure(e.target.checked)
|
|
3947
4117
|
}),
|
|
3948
|
-
|
|
4118
|
+
h('span', null, T_KEY(t, 'form.notifyOnlyFailure'))
|
|
3949
4119
|
),
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
...DELIVERY_CHANNELS.map((id) =>
|
|
3954
|
-
|
|
4120
|
+
h('div', { style: { marginTop: '12px', paddingTop: '10px', borderTop: '1px solid var(--dsw-alias-border-l2)' } },
|
|
4121
|
+
h('div', { style: { fontWeight: 500, fontSize: '12.5px', color: 'var(--dsw-alias-label-secondary, #aaa)', marginBottom: '8px' } }, T_KEY(t, 'form.channelsTitle')),
|
|
4122
|
+
h('div', { className: 'dsh-cron-channel-grid' },
|
|
4123
|
+
...DELIVERY_CHANNELS.map((id) => h('label', { key: id, className: 'dsh-cron-checkbox-row' },
|
|
4124
|
+
h('input', {
|
|
3955
4125
|
type: 'checkbox',
|
|
3956
4126
|
checked: formChannels.indexOf(id) >= 0,
|
|
3957
4127
|
onChange: (e) => {
|
|
@@ -3962,56 +4132,56 @@ return DELIVERY_CHANNELS.filter((c) => set.has(c));
|
|
|
3962
4132
|
});
|
|
3963
4133
|
}
|
|
3964
4134
|
}),
|
|
3965
|
-
|
|
4135
|
+
h('span', null, T_KEY(t, CHANNEL_LABEL_KEYS[id]))
|
|
3966
4136
|
))
|
|
3967
4137
|
),
|
|
3968
|
-
|
|
4138
|
+
h('div', { className: 'dsh-cron-hint', style: { marginTop: '6px' } }, T_KEY(t, 'form.channelsHint'))
|
|
3969
4139
|
),
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
4140
|
+
h('div', { className: 'dsh-cron-form-group', style: { marginTop: '12px', marginBottom: 0 } },
|
|
4141
|
+
h('label', null, T_KEY(t, 'form.templateLabel')),
|
|
4142
|
+
h('input', {
|
|
3973
4143
|
type: 'text',
|
|
3974
4144
|
value: formTemplate,
|
|
3975
4145
|
placeholder: T_KEY(t, 'form.templatePlaceholder'),
|
|
3976
4146
|
onChange: (e) => setFormTemplate(e.target.value)
|
|
3977
4147
|
}),
|
|
3978
|
-
|
|
4148
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.templateHint'))
|
|
3979
4149
|
),
|
|
3980
|
-
!AGENT_FORM_TYPES.includes(formType) &&
|
|
3981
|
-
|
|
3982
|
-
|
|
4150
|
+
!AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-group', style: { marginTop: '12px', marginBottom: 0 } },
|
|
4151
|
+
h('label', null, T_KEY(t, 'form.silentRuleLabel')),
|
|
4152
|
+
h('input', {
|
|
3983
4153
|
type: 'text',
|
|
3984
4154
|
value: formSilentRule,
|
|
3985
4155
|
placeholder: T_KEY(t, 'form.silentRulePlaceholder'),
|
|
3986
4156
|
onChange: (e) => setFormSilentRule(e.target.value)
|
|
3987
4157
|
}),
|
|
3988
|
-
|
|
4158
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.silentRuleHint'))
|
|
3989
4159
|
)
|
|
3990
4160
|
),
|
|
3991
|
-
|
|
4161
|
+
h('div', {
|
|
3992
4162
|
style: {
|
|
3993
4163
|
marginTop: '16px',
|
|
3994
4164
|
paddingTop: '14px',
|
|
3995
4165
|
borderTop: '1px solid var(--dsw-alias-border-l2)'
|
|
3996
4166
|
}
|
|
3997
4167
|
},
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4168
|
+
h('div', { style: { fontWeight: '600', fontSize: '13px', marginBottom: '10px' } }, T_KEY(t, 'form.reliabilityTitle')),
|
|
4169
|
+
h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
|
|
4170
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4171
|
+
h('label', null, T_KEY(t, 'form.preflightLabel')),
|
|
4172
|
+
h('select', {
|
|
4003
4173
|
value: formPreflightType,
|
|
4004
4174
|
onChange: (e) => setFormPreflightType(e.target.value)
|
|
4005
4175
|
},
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4176
|
+
h('option', { value: 'none' }, T_KEY(t, 'form.preflightNone')),
|
|
4177
|
+
h('option', { value: 'http' }, T_KEY(t, 'form.preflightHttp')),
|
|
4178
|
+
h('option', { value: 'shell' }, T_KEY(t, 'form.preflightShell')),
|
|
4179
|
+
h('option', { value: 'disk' }, T_KEY(t, 'form.preflightDisk'))
|
|
4010
4180
|
)
|
|
4011
4181
|
),
|
|
4012
|
-
formPreflightType !== 'none' &&
|
|
4013
|
-
|
|
4014
|
-
|
|
4182
|
+
formPreflightType !== 'none' && h('div', { className: 'dsh-cron-form-group' },
|
|
4183
|
+
h('label', null, T_KEY(t, 'form.preflightTargetLabel')),
|
|
4184
|
+
h('input', {
|
|
4015
4185
|
type: 'text',
|
|
4016
4186
|
value: formPreflightTarget,
|
|
4017
4187
|
placeholder: T_KEY(t, 'form.preflightTargetPlaceholder'),
|
|
@@ -4019,19 +4189,19 @@ onChange: (e) => setFormPreflightTarget(e.target.value)
|
|
|
4019
4189
|
})
|
|
4020
4190
|
)
|
|
4021
4191
|
),
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4192
|
+
h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
|
|
4193
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4194
|
+
h('label', null, T_KEY(t, 'form.heartbeatIntervalLabel')),
|
|
4195
|
+
h('input', {
|
|
4026
4196
|
type: 'number',
|
|
4027
4197
|
value: formHeartbeatIntervalSeconds,
|
|
4028
4198
|
min: 0,
|
|
4029
4199
|
onChange: (e) => setFormHeartbeatIntervalSeconds(Number(e.target.value))
|
|
4030
4200
|
})
|
|
4031
4201
|
),
|
|
4032
|
-
formHeartbeatIntervalSeconds > 0 &&
|
|
4033
|
-
|
|
4034
|
-
|
|
4202
|
+
formHeartbeatIntervalSeconds > 0 && h('div', { className: 'dsh-cron-form-group' },
|
|
4203
|
+
h('label', null, T_KEY(t, 'form.gracePeriodLabel')),
|
|
4204
|
+
h('input', {
|
|
4035
4205
|
type: 'number',
|
|
4036
4206
|
value: formGracePeriodSeconds,
|
|
4037
4207
|
min: 1,
|
|
@@ -4039,10 +4209,10 @@ onChange: (e) => setFormGracePeriodSeconds(Number(e.target.value))
|
|
|
4039
4209
|
})
|
|
4040
4210
|
)
|
|
4041
4211
|
),
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4212
|
+
h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
|
|
4213
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4214
|
+
h('label', null, T_KEY(t, 'form.priorityLabel')),
|
|
4215
|
+
h('input', {
|
|
4046
4216
|
type: 'number',
|
|
4047
4217
|
value: formPriority,
|
|
4048
4218
|
min: 1,
|
|
@@ -4050,117 +4220,138 @@ max: 10,
|
|
|
4050
4220
|
onChange: (e) => setFormPriority(Number(e.target.value))
|
|
4051
4221
|
})
|
|
4052
4222
|
),
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4223
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4224
|
+
h('label', null, T_KEY(t, 'form.concurrencyGroupLabel')),
|
|
4225
|
+
h('input', {
|
|
4056
4226
|
type: 'text',
|
|
4057
4227
|
value: formConcurrencyGroup,
|
|
4058
4228
|
onChange: (e) => setFormConcurrencyGroup(e.target.value)
|
|
4059
4229
|
})
|
|
4060
4230
|
)
|
|
4061
4231
|
),
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4232
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4233
|
+
h('label', null, T_KEY(t, 'form.selfHealingLabel')),
|
|
4234
|
+
h('input', {
|
|
4065
4235
|
type: 'text',
|
|
4066
4236
|
value: formSelfHealingCommand,
|
|
4067
4237
|
placeholder: T_KEY(t, 'form.selfHealingPlaceholder'),
|
|
4068
4238
|
onChange: (e) => setFormSelfHealingCommand(e.target.value)
|
|
4069
4239
|
})
|
|
4070
4240
|
),
|
|
4071
|
-
|
|
4072
|
-
|
|
4241
|
+
h('div', { style: { display: 'flex', alignItems: 'center', gap: '8px', marginTop: '6px' } },
|
|
4242
|
+
h('input', {
|
|
4073
4243
|
type: 'checkbox',
|
|
4074
4244
|
id: 'formAutoDiagnoseCheckbox',
|
|
4075
4245
|
checked: formAutoDiagnose,
|
|
4076
4246
|
onChange: (e) => setFormAutoDiagnose(e.target.checked)
|
|
4077
4247
|
}),
|
|
4078
|
-
|
|
4248
|
+
h('label', { htmlFor: 'formAutoDiagnoseCheckbox', style: { margin: 0, fontSize: '12.5px', cursor: 'pointer' } }, T_KEY(t, 'form.autoDiagnoseLabel'))
|
|
4079
4249
|
)
|
|
4080
4250
|
),
|
|
4081
|
-
|
|
4251
|
+
h('div', {
|
|
4082
4252
|
style: {
|
|
4083
4253
|
marginTop: '16px',
|
|
4084
4254
|
paddingTop: '14px',
|
|
4085
4255
|
borderTop: '1px solid var(--dsw-alias-border-l2)'
|
|
4086
4256
|
}
|
|
4087
4257
|
},
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4258
|
+
h('div', { style: { fontWeight: '600', fontSize: '13px', marginBottom: '10px' } }, '⛓️ ' + T_KEY(t, 'form.chainingTitle')),
|
|
4259
|
+
h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
|
|
4260
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4261
|
+
h('label', null, T_KEY(t, 'form.onSuccessLabel')),
|
|
4262
|
+
h('input', {
|
|
4093
4263
|
type: 'text',
|
|
4094
4264
|
value: formOnSuccess,
|
|
4095
4265
|
placeholder: 'task-build, task-test',
|
|
4096
4266
|
onChange: (e) => setFormOnSuccess(e.target.value)
|
|
4097
4267
|
}),
|
|
4098
|
-
|
|
4268
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.onSuccessHint'))
|
|
4099
4269
|
),
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4270
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4271
|
+
h('label', null, T_KEY(t, 'form.onFailureLabel')),
|
|
4272
|
+
h('input', {
|
|
4103
4273
|
type: 'text',
|
|
4104
4274
|
value: formOnFailure,
|
|
4105
4275
|
placeholder: 'task-alert',
|
|
4106
4276
|
onChange: (e) => setFormOnFailure(e.target.value)
|
|
4107
4277
|
}),
|
|
4108
|
-
|
|
4278
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.onFailureHint'))
|
|
4109
4279
|
)
|
|
4110
4280
|
),
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4281
|
+
h('div', { style: { display: 'grid', gridTemplateColumns: '2fr 1fr', gap: '10px', marginTop: '8px' } },
|
|
4282
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4283
|
+
h('label', null, T_KEY(t, 'form.dependsOnLabel')),
|
|
4284
|
+
h('input', {
|
|
4115
4285
|
type: 'text',
|
|
4116
4286
|
value: formDependsOn,
|
|
4117
4287
|
placeholder: 'task-build, task-lint',
|
|
4118
4288
|
onChange: (e) => setFormDependsOn(e.target.value)
|
|
4119
4289
|
}),
|
|
4120
|
-
|
|
4290
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.dependsOnHint'))
|
|
4121
4291
|
),
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4292
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4293
|
+
h('label', null, T_KEY(t, 'form.joinPolicyLabel')),
|
|
4294
|
+
h('select', {
|
|
4125
4295
|
value: formJoinPolicy,
|
|
4126
4296
|
onChange: (e) => setFormJoinPolicy(e.target.value)
|
|
4127
4297
|
},
|
|
4128
|
-
|
|
4129
|
-
|
|
4298
|
+
h('option', { value: 'all_success' }, T_KEY(t, 'form.joinPolicyAll')),
|
|
4299
|
+
h('option', { value: 'any_success' }, T_KEY(t, 'form.joinPolicyAny'))
|
|
4130
4300
|
)
|
|
4131
4301
|
)
|
|
4132
4302
|
),
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4303
|
+
h('div', { className: 'dsh-cron-form-group', style: { marginTop: '8px' } },
|
|
4304
|
+
h('label', null, T_KEY(t, 'form.elseTaskLabel')),
|
|
4305
|
+
h('input', {
|
|
4306
|
+
type: 'text',
|
|
4307
|
+
value: formElseTask || '',
|
|
4308
|
+
placeholder: T_KEY(t, 'form.elseTaskPlaceholder'),
|
|
4309
|
+
onChange: (e) => setFormElseTask(e.target.value)
|
|
4310
|
+
}),
|
|
4311
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.elseTaskHint'))
|
|
4312
|
+
),
|
|
4313
|
+
h('div', { className: 'dsh-cron-form-group', style: { marginTop: '8px' } },
|
|
4314
|
+
h('label', { style: { display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' } },
|
|
4315
|
+
h('input', {
|
|
4316
|
+
type: 'checkbox',
|
|
4317
|
+
checked: Boolean(formAutoHeal),
|
|
4318
|
+
onChange: (e) => setFormAutoHeal(e.target.checked)
|
|
4319
|
+
}),
|
|
4320
|
+
h('span', { style: { fontWeight: '600' } }, '🩺 ' + T_KEY(t, 'form.autoHealLabel'))
|
|
4321
|
+
),
|
|
4322
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.autoHealHint'))
|
|
4323
|
+
),
|
|
4324
|
+
h('div', { style: { marginTop: '12px', padding: '10px', background: 'var(--dsw-alias-bg-layer-2)', borderRadius: '6px' } },
|
|
4325
|
+
h('label', { style: { display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer', fontWeight: '500' } },
|
|
4326
|
+
h('input', {
|
|
4136
4327
|
type: 'checkbox',
|
|
4137
4328
|
checked: formAdaptiveEnabled,
|
|
4138
4329
|
onChange: (e) => setFormAdaptiveEnabled(e.target.checked)
|
|
4139
4330
|
}),
|
|
4140
4331
|
T_KEY(t, 'form.adaptiveEnabled')
|
|
4141
4332
|
),
|
|
4142
|
-
|
|
4143
|
-
formAdaptiveEnabled &&
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4333
|
+
h('div', { className: 'dsh-cron-hint', style: { marginLeft: '24px' } }, T_KEY(t, 'form.adaptiveHint')),
|
|
4334
|
+
formAdaptiveEnabled && h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: '8px', marginTop: '8px', marginLeft: '24px' } },
|
|
4335
|
+
h('div', null,
|
|
4336
|
+
h('label', { style: { fontSize: '11px' } }, 'Min'),
|
|
4337
|
+
h('input', { type: 'text', value: formAdaptiveMinInterval, placeholder: '5m', onChange: (e) => setFormAdaptiveMinInterval(e.target.value) })
|
|
4147
4338
|
),
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4339
|
+
h('div', null,
|
|
4340
|
+
h('label', { style: { fontSize: '11px' } }, 'Max'),
|
|
4341
|
+
h('input', { type: 'text', value: formAdaptiveMaxInterval, placeholder: '2h', onChange: (e) => setFormAdaptiveMaxInterval(e.target.value) })
|
|
4151
4342
|
),
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4343
|
+
h('div', null,
|
|
4344
|
+
h('label', { style: { fontSize: '11px' } }, 'Factor'),
|
|
4345
|
+
h('input', { type: 'number', step: '0.1', value: formAdaptiveBackoffFactor, placeholder: '1.5', onChange: (e) => setFormAdaptiveBackoffFactor(e.target.value) })
|
|
4155
4346
|
),
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4347
|
+
h('div', null,
|
|
4348
|
+
h('label', { style: { fontSize: '11px' } }, 'Idle Runs'),
|
|
4349
|
+
h('input', { type: 'number', value: formAdaptiveIdleThreshold, placeholder: '3', onChange: (e) => setFormAdaptiveIdleThreshold(e.target.value) })
|
|
4159
4350
|
)
|
|
4160
4351
|
)
|
|
4161
4352
|
)
|
|
4162
4353
|
),
|
|
4163
|
-
selectedTaskMeta &&
|
|
4354
|
+
selectedTaskMeta && h('div', {
|
|
4164
4355
|
style: {
|
|
4165
4356
|
background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary) 3%, transparent))',
|
|
4166
4357
|
border: '1px solid var(--dsw-alias-border-l2)',
|
|
@@ -4174,11 +4365,11 @@ justifyContent: 'space-between',
|
|
|
4174
4365
|
alignItems: 'center'
|
|
4175
4366
|
}
|
|
4176
4367
|
},
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4368
|
+
h('div', null,
|
|
4369
|
+
h('span', null, T_KEY(t, 'form.nextRunLabel')),
|
|
4370
|
+
h('strong', { style: { color: 'var(--dsw-alias-label-primary, #eee)' } }, selectedTaskMeta.nextRunAt ? new Date(selectedTaskMeta.nextRunAt).toLocaleString() : T_KEY(t, 'form.notScheduled'))
|
|
4180
4371
|
),
|
|
4181
|
-
|
|
4372
|
+
h('button', {
|
|
4182
4373
|
type: 'button',
|
|
4183
4374
|
className: 'dsh-cron-btn-secondary',
|
|
4184
4375
|
style: { padding: '4px 10px', fontSize: '12px' },
|
|
@@ -4188,13 +4379,13 @@ if (formId) loadTaskHistory(formId);
|
|
|
4188
4379
|
}
|
|
4189
4380
|
}, T_KEY(t, 'actions.runNow'))
|
|
4190
4381
|
),
|
|
4191
|
-
|
|
4192
|
-
|
|
4382
|
+
h('div', { className: 'dsh-cron-modal-foot' },
|
|
4383
|
+
h('button', {
|
|
4193
4384
|
type: 'button',
|
|
4194
4385
|
className: 'dsh-cron-btn-secondary',
|
|
4195
4386
|
onClick: closeManualModalWithConfirm
|
|
4196
4387
|
}, T_KEY(t, 'modal.cancel')),
|
|
4197
|
-
|
|
4388
|
+
h('button', {
|
|
4198
4389
|
type: 'submit',
|
|
4199
4390
|
className: 'dsh-cron-btn-primary'
|
|
4200
4391
|
}, formId ? T_KEY(t, 'modal.save') : T_KEY(t, 'modal.create'))
|
|
@@ -4202,28 +4393,28 @@ className: 'dsh-cron-btn-primary'
|
|
|
4202
4393
|
)
|
|
4203
4394
|
)
|
|
4204
4395
|
),
|
|
4205
|
-
dryRunResult &&
|
|
4206
|
-
|
|
4396
|
+
dryRunResult && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => setDryRunResult(null) },
|
|
4397
|
+
h('div', {
|
|
4207
4398
|
className: 'dsh-cron-modal',
|
|
4208
4399
|
style: { maxWidth: '580px' },
|
|
4209
4400
|
role: 'dialog',
|
|
4210
4401
|
'aria-modal': 'true',
|
|
4211
4402
|
onClick: (e) => e.stopPropagation()
|
|
4212
4403
|
},
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4404
|
+
h('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
|
|
4405
|
+
h('div', { className: 'dsh-cron-modal-title', style: { margin: 0 } }, T_KEY(t, 'dryRun.title')),
|
|
4406
|
+
h('button', {
|
|
4216
4407
|
type: 'button',
|
|
4217
4408
|
className: 'dsh-cron-icon-btn',
|
|
4218
4409
|
onClick: () => setDryRunResult(null)
|
|
4219
4410
|
}, '✕')
|
|
4220
4411
|
),
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
((dryRunResult.result && dryRunResult.result.preflight) || dryRunResult.preflight) &&
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4412
|
+
h('div', { style: { marginTop: '12px', display: 'flex', flexDirection: 'column', gap: '8px', fontSize: '13px' } },
|
|
4413
|
+
h('div', null, h('strong', null, T_KEY(t, 'dryRun.status') + ': '), h('span', { style: { color: dryRunResult.ok ? 'var(--dsh-cron-success)' : 'var(--dsh-cron-danger)' } }, dryRunResult.ok ? ((dryRunResult.result && dryRunResult.result.status) || dryRunResult.status || 'success') : 'failed')),
|
|
4414
|
+
((dryRunResult.result && dryRunResult.result.preflight) || dryRunResult.preflight) && h('div', null, h('strong', null, T_KEY(t, 'dryRun.preflight') + ': '), h('span', null, (((dryRunResult.result && dryRunResult.result.preflight) || dryRunResult.preflight).passed) ? '✓ Passed' : '✗ Failed (' + ((((dryRunResult.result && dryRunResult.result.preflight) || dryRunResult.preflight).reason) || '') + ')')),
|
|
4415
|
+
h('div', null, h('strong', null, T_KEY(t, 'dryRun.duration') + ': '), h('span', null, (((dryRunResult.result && dryRunResult.result.durationMs) !== undefined ? dryRunResult.result.durationMs : dryRunResult.durationMs) || 0) + 'ms')),
|
|
4416
|
+
h('div', { style: { marginTop: '6px' } }, h('strong', null, T_KEY(t, 'dryRun.output') + ':')),
|
|
4417
|
+
h('pre', {
|
|
4227
4418
|
style: {
|
|
4228
4419
|
background: 'var(--dsw-alias-bg-layer-2)',
|
|
4229
4420
|
border: '1px solid var(--dsw-alias-border-l2)',
|
|
@@ -4238,8 +4429,8 @@ color: 'var(--dsw-alias-label-primary)'
|
|
|
4238
4429
|
}
|
|
4239
4430
|
}, ((dryRunResult.result && dryRunResult.result.output) !== undefined ? dryRunResult.result.output : (dryRunResult.output !== undefined ? dryRunResult.output : ((dryRunResult.result && dryRunResult.result.error) || dryRunResult.error || '(no output)'))))
|
|
4240
4431
|
),
|
|
4241
|
-
|
|
4242
|
-
|
|
4432
|
+
h('div', { className: 'dsh-cron-modal-foot', style: { marginTop: '16px' } },
|
|
4433
|
+
h('button', {
|
|
4243
4434
|
type: 'button',
|
|
4244
4435
|
className: 'dsh-cron-btn-primary',
|
|
4245
4436
|
onClick: () => setDryRunResult(null)
|
|
@@ -4247,29 +4438,29 @@ onClick: () => setDryRunResult(null)
|
|
|
4247
4438
|
)
|
|
4248
4439
|
)
|
|
4249
4440
|
),
|
|
4250
|
-
archiveModalOpen &&
|
|
4251
|
-
|
|
4441
|
+
archiveModalOpen && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => setArchiveModalOpen(false) },
|
|
4442
|
+
h('div', {
|
|
4252
4443
|
className: 'dsh-cron-modal',
|
|
4253
4444
|
style: { maxWidth: '700px' },
|
|
4254
4445
|
role: 'dialog',
|
|
4255
4446
|
'aria-modal': 'true',
|
|
4256
4447
|
onClick: (e) => e.stopPropagation()
|
|
4257
4448
|
},
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4449
|
+
h('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
|
|
4450
|
+
h('div', { className: 'dsh-cron-modal-title', style: { margin: 0 } }, T_KEY(t, 'archive.title') + (archiveTask ? ' - ' + archiveTask.title : '')),
|
|
4451
|
+
h('button', {
|
|
4261
4452
|
type: 'button',
|
|
4262
4453
|
className: 'dsh-cron-icon-btn',
|
|
4263
4454
|
onClick: () => setArchiveModalOpen(false)
|
|
4264
4455
|
}, '✕')
|
|
4265
4456
|
),
|
|
4266
|
-
|
|
4457
|
+
h('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #999)', margin: '4px 0 12px 0' } },
|
|
4267
4458
|
T_KEY(t, 'archive.totalRuns', { total: archiveTotal })
|
|
4268
4459
|
),
|
|
4269
|
-
archiveLoading ?
|
|
4270
|
-
archiveRuns.length === 0 ?
|
|
4271
|
-
|
|
4272
|
-
archiveRuns.map((r, idx) =>
|
|
4460
|
+
archiveLoading ? h('div', { className: 'dsh-cron-history-empty' }, T_KEY(t, 'history.loading')) :
|
|
4461
|
+
archiveRuns.length === 0 ? h('div', { className: 'dsh-cron-history-empty' }, T_KEY(t, 'archive.empty')) :
|
|
4462
|
+
h('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px', maxHeight: '380px', overflowY: 'auto' } },
|
|
4463
|
+
archiveRuns.map((r, idx) => h('div', {
|
|
4273
4464
|
key: idx,
|
|
4274
4465
|
style: {
|
|
4275
4466
|
background: 'var(--dsw-alias-bg-layer-2)',
|
|
@@ -4279,21 +4470,21 @@ padding: '8px 12px',
|
|
|
4279
4470
|
fontSize: '12px'
|
|
4280
4471
|
}
|
|
4281
4472
|
},
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4473
|
+
h('div', { style: { display: 'flex', justifyContent: 'space-between', marginBottom: '4px' } },
|
|
4474
|
+
h('span', { style: { fontWeight: '600', color: r.status === 'success' ? 'var(--dsh-cron-success)' : 'var(--dsh-cron-danger)' } }, (r.status || 'unknown').toUpperCase()),
|
|
4475
|
+
h('span', { style: { color: 'var(--dsw-alias-label-secondary, #888)' } }, (r.at || r.timestamp || r.startedAt) ? new Date(r.at || r.timestamp || r.startedAt).toLocaleString() : "")
|
|
4285
4476
|
),
|
|
4286
|
-
r.durationMs > 0 &&
|
|
4287
|
-
r.chainRunId &&
|
|
4288
|
-
|
|
4477
|
+
r.durationMs > 0 && h('div', { style: { color: 'var(--dsw-alias-label-secondary, #888)', marginBottom: '4px' } }, 'Duration: ' + r.durationMs + 'ms'),
|
|
4478
|
+
r.chainRunId && h('div', { style: { marginBottom: '4px' } },
|
|
4479
|
+
h('button', {
|
|
4289
4480
|
type: 'button',
|
|
4290
4481
|
className: 'dsh-cron-btn-secondary',
|
|
4291
4482
|
style: { padding: '2px 8px', fontSize: '11px', display: 'inline-flex', alignItems: 'center', gap: '4px' },
|
|
4292
4483
|
onClick: () => openChainGraphModal(null, r.chainRunId)
|
|
4293
4484
|
}, '🕸️ ' + T_KEY(t, 'chainGraph.viewGraph'))
|
|
4294
4485
|
),
|
|
4295
|
-
r.error &&
|
|
4296
|
-
r.output &&
|
|
4486
|
+
r.error && h('div', { style: { color: 'var(--dsh-cron-danger)', marginBottom: '4px' } }, 'Error: ' + r.error),
|
|
4487
|
+
r.output && h('div', {
|
|
4297
4488
|
style: {
|
|
4298
4489
|
color: 'var(--dsw-alias-label-primary, #ccc)',
|
|
4299
4490
|
whiteSpace: 'pre-wrap',
|
|
@@ -4304,16 +4495,16 @@ overflowY: 'auto'
|
|
|
4304
4495
|
}, r.output.slice(0, 300) + (r.output.length > 300 ? '...' : ''))
|
|
4305
4496
|
))
|
|
4306
4497
|
),
|
|
4307
|
-
|
|
4308
|
-
archiveRuns.length < archiveTotal ?
|
|
4498
|
+
h('div', { className: 'dsh-cron-modal-foot', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: '16px' } },
|
|
4499
|
+
archiveRuns.length < archiveTotal ? h('button', {
|
|
4309
4500
|
type: 'button',
|
|
4310
4501
|
className: 'dsh-cron-btn-secondary',
|
|
4311
4502
|
onClick: () => {
|
|
4312
4503
|
const nextOffset = archiveRuns.length;
|
|
4313
4504
|
if (archiveTask) openArchiveModal(archiveTask, nextOffset);
|
|
4314
4505
|
}
|
|
4315
|
-
}, T_KEY(t, 'archive.loadMore', { shown: archiveRuns.length, total: archiveTotal })) :
|
|
4316
|
-
|
|
4506
|
+
}, T_KEY(t, 'archive.loadMore', { shown: archiveRuns.length, total: archiveTotal })) : h('div', null),
|
|
4507
|
+
h('button', {
|
|
4317
4508
|
type: 'button',
|
|
4318
4509
|
className: 'dsh-cron-btn-primary',
|
|
4319
4510
|
onClick: () => setArchiveModalOpen(false)
|
|
@@ -4321,54 +4512,54 @@ onClick: () => setArchiveModalOpen(false)
|
|
|
4321
4512
|
)
|
|
4322
4513
|
)
|
|
4323
4514
|
),
|
|
4324
|
-
settingsModalOpen &&
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4515
|
+
settingsModalOpen && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => setSettingsModalOpen(false) },
|
|
4516
|
+
h('div', { className: 'dsh-cron-modal dsh-cron-modal-scroll', role: 'dialog', 'aria-modal': 'true', onClick: (e) => e.stopPropagation() },
|
|
4517
|
+
h('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '18px' } },
|
|
4518
|
+
h('div', { className: 'dsh-cron-modal-title', style: { margin: 0, display: 'flex', alignItems: 'center', gap: '8px' } },
|
|
4519
|
+
h('span', { style: { display: 'flex', alignItems: 'center', color: 'var(--dsh-cron-info)' }, ...iconHtml(ICON_TELEGRAM) }),
|
|
4329
4520
|
T_KEY(t, 'settings.modalTitle')
|
|
4330
4521
|
),
|
|
4331
|
-
|
|
4522
|
+
h('button', {
|
|
4332
4523
|
type: 'button',
|
|
4333
4524
|
style: { background: 'none', border: 'none', color: 'var(--dsw-alias-label-tertiary, #888)', cursor: 'pointer', fontSize: '18px' },
|
|
4334
4525
|
onClick: () => setSettingsModalOpen(false)
|
|
4335
4526
|
}, '✕')
|
|
4336
4527
|
),
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4528
|
+
h('form', { onSubmit: handleSaveSettings },
|
|
4529
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4530
|
+
h('label', null, T_KEY(t, 'settings.tokenLabel')),
|
|
4531
|
+
h('input', {
|
|
4341
4532
|
type: 'password',
|
|
4342
4533
|
value: settingsBotToken,
|
|
4343
4534
|
placeholder: settingsHasDefault ? T_KEY(t, 'settings.tokenPlaceholderDefault') : T_KEY(t, 'settings.tokenPlaceholder'),
|
|
4344
4535
|
onChange: (e) => setSettingsBotToken(e.target.value)
|
|
4345
4536
|
}),
|
|
4346
|
-
settingsHasDefault &&
|
|
4537
|
+
settingsHasDefault && h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'settings.defaultHint'))
|
|
4347
4538
|
),
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4539
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4540
|
+
h('label', null, T_KEY(t, 'settings.chatIdLabel')),
|
|
4541
|
+
h('input', {
|
|
4351
4542
|
value: settingsChatId,
|
|
4352
4543
|
placeholder: T_KEY(t, 'settings.chatIdPlaceholder'),
|
|
4353
4544
|
onChange: (e) => setSettingsChatId(e.target.value)
|
|
4354
4545
|
})
|
|
4355
4546
|
),
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4547
|
+
h('div', { style: { background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary) 2%, transparent))', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: '8px', padding: '12px 14px', marginBottom: '16px' } },
|
|
4548
|
+
h('label', { className: 'dsh-cron-checkbox-row', style: { marginBottom: '8px' } },
|
|
4549
|
+
h('input', {
|
|
4359
4550
|
type: 'checkbox',
|
|
4360
4551
|
checked: settingsNotifyGlobal,
|
|
4361
4552
|
onChange: (e) => setSettingsNotifyGlobal(e.target.checked)
|
|
4362
4553
|
}),
|
|
4363
|
-
|
|
4554
|
+
h('span', null, T_KEY(t, 'settings.globalNotify'))
|
|
4364
4555
|
),
|
|
4365
|
-
|
|
4366
|
-
|
|
4556
|
+
h('label', { className: 'dsh-cron-checkbox-row' },
|
|
4557
|
+
h('input', {
|
|
4367
4558
|
type: 'checkbox',
|
|
4368
4559
|
checked: settingsOnlyOnFailureGlobal,
|
|
4369
4560
|
onChange: (e) => setSettingsOnlyOnFailureGlobal(e.target.checked)
|
|
4370
4561
|
}),
|
|
4371
|
-
|
|
4562
|
+
h('span', null, T_KEY(t, 'settings.globalOnlyFailure'))
|
|
4372
4563
|
)
|
|
4373
4564
|
),
|
|
4374
4565
|
...renderDeliverySettings({
|
|
@@ -4379,8 +4570,8 @@ onChannelTemplate: updateChannelTemplate,
|
|
|
4379
4570
|
sections: settingsSections,
|
|
4380
4571
|
onToggleSection: toggleDeliverySection,
|
|
4381
4572
|
}),
|
|
4382
|
-
|
|
4383
|
-
|
|
4573
|
+
h('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '14px' } },
|
|
4574
|
+
h('button', {
|
|
4384
4575
|
type: 'button',
|
|
4385
4576
|
className: 'dsh-cron-btn-secondary',
|
|
4386
4577
|
style: { display: 'inline-flex', alignItems: 'center', gap: '6px' },
|
|
@@ -4388,17 +4579,17 @@ disabled: testStatus?.loading,
|
|
|
4388
4579
|
onClick: handleTestTelegram
|
|
4389
4580
|
}, testStatus?.loading ? T_KEY(t, 'settings.sending') : T_KEY(t, 'settings.testTelegram'))
|
|
4390
4581
|
),
|
|
4391
|
-
testStatus && testStatus.message &&
|
|
4582
|
+
testStatus && testStatus.message && h('div', {
|
|
4392
4583
|
className: 'dsh-cron-status-banner',
|
|
4393
4584
|
'data-type': testStatus.success ? 'success' : 'error'
|
|
4394
4585
|
}, testStatus.message),
|
|
4395
|
-
|
|
4396
|
-
|
|
4586
|
+
h('div', { className: 'dsh-cron-modal-foot' },
|
|
4587
|
+
h('button', {
|
|
4397
4588
|
type: 'button',
|
|
4398
4589
|
className: 'dsh-cron-btn-secondary',
|
|
4399
4590
|
onClick: () => setSettingsModalOpen(false)
|
|
4400
4591
|
}, T_KEY(t, 'modal.cancel')),
|
|
4401
|
-
|
|
4592
|
+
h('button', {
|
|
4402
4593
|
type: 'submit',
|
|
4403
4594
|
className: 'dsh-cron-btn-primary'
|
|
4404
4595
|
}, T_KEY(t, 'settings.save'))
|
|
@@ -4406,12 +4597,12 @@ className: 'dsh-cron-btn-primary'
|
|
|
4406
4597
|
)
|
|
4407
4598
|
)
|
|
4408
4599
|
),
|
|
4409
|
-
importDoc &&
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
importSummary &&
|
|
4414
|
-
|
|
4600
|
+
importDoc && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => !transferBusy && setImportDoc(null) },
|
|
4601
|
+
h('div', { className: 'dsh-cron-modal', role: 'dialog', 'aria-modal': 'true', onClick: (e) => e.stopPropagation() },
|
|
4602
|
+
h('div', { className: 'dsh-cron-modal-title' }, T_KEY(t, 'transfer.importTitleModal')),
|
|
4603
|
+
h('div', { className: 'dsh-cron-hint', style: { marginBottom: '10px' } }, T_KEY(t, 'transfer.importHint')),
|
|
4604
|
+
importSummary && h('div', null,
|
|
4605
|
+
h('div', { style: { fontSize: '13px', marginBottom: '12px' } },
|
|
4415
4606
|
T_KEY(t, 'transfer.summary', {
|
|
4416
4607
|
total: (importSummary.add || 0) + (importSummary.replace || 0) + (importSummary.skip || 0),
|
|
4417
4608
|
add: importSummary.add || 0,
|
|
@@ -4419,26 +4610,26 @@ replace: importSummary.replace || 0,
|
|
|
4419
4610
|
skip: importSummary.skip || 0
|
|
4420
4611
|
})
|
|
4421
4612
|
),
|
|
4422
|
-
|
|
4423
|
-
...['add', 'replace', 'skip'].map((mode) =>
|
|
4424
|
-
|
|
4613
|
+
h('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px', marginBottom: '14px' } },
|
|
4614
|
+
...['add', 'replace', 'skip'].map((mode) => h('label', { key: mode, className: 'dsh-cron-checkbox-row' },
|
|
4615
|
+
h('input', {
|
|
4425
4616
|
type: 'radio',
|
|
4426
4617
|
name: 'dsh-cron-import-strategy',
|
|
4427
4618
|
checked: importStrategy === mode,
|
|
4428
4619
|
onChange: () => setImportStrategy(mode)
|
|
4429
4620
|
}),
|
|
4430
|
-
|
|
4621
|
+
h('span', null, T_KEY(t, mode === 'add' ? 'transfer.strategyAdd' : mode === 'replace' ? 'transfer.strategyReplace' : 'transfer.strategySkip'))
|
|
4431
4622
|
))
|
|
4432
4623
|
)
|
|
4433
4624
|
),
|
|
4434
|
-
|
|
4435
|
-
|
|
4625
|
+
h('div', { className: 'dsh-cron-modal-foot' },
|
|
4626
|
+
h('button', {
|
|
4436
4627
|
type: 'button',
|
|
4437
4628
|
className: 'dsh-cron-btn-secondary',
|
|
4438
4629
|
disabled: transferBusy,
|
|
4439
4630
|
onClick: () => setImportDoc(null)
|
|
4440
4631
|
}, T_KEY(t, 'modal.cancel')),
|
|
4441
|
-
|
|
4632
|
+
h('button', {
|
|
4442
4633
|
type: 'button',
|
|
4443
4634
|
className: 'dsh-cron-btn-primary',
|
|
4444
4635
|
disabled: transferBusy || !importSummary,
|
|
@@ -4447,13 +4638,13 @@ onClick: handleImportConfirm
|
|
|
4447
4638
|
)
|
|
4448
4639
|
)
|
|
4449
4640
|
),
|
|
4450
|
-
dshModalOpen &&
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4641
|
+
dshModalOpen && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => !dshLoading && setDshModalOpen(false) },
|
|
4642
|
+
h('div', { className: 'dsh-cron-modal', role: 'dialog', 'aria-modal': 'true', onClick: (e) => e.stopPropagation() },
|
|
4643
|
+
h('div', { className: 'dsh-cron-modal-title' }, T_KEY(t, 'dsh.modalTitle')),
|
|
4644
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4645
|
+
h('label', null, T_KEY(t, 'dsh.descLabel')),
|
|
4646
|
+
h('div', { className: 'dsh-cron-chat-box' },
|
|
4647
|
+
h('textarea', {
|
|
4457
4648
|
className: 'dsh-cron-chat-input',
|
|
4458
4649
|
rows: 4,
|
|
4459
4650
|
autoFocus: true,
|
|
@@ -4468,22 +4659,22 @@ handleStartWithDSH();
|
|
|
4468
4659
|
},
|
|
4469
4660
|
onChange: (e) => setDshPrompt(e.target.value)
|
|
4470
4661
|
}),
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4662
|
+
h('div', { className: 'dsh-cron-chat-foot' },
|
|
4663
|
+
h('span', { className: 'dsh-cron-chat-hint' }, T_KEY(t, 'dsh.sendHint')),
|
|
4664
|
+
h('button', {
|
|
4474
4665
|
type: 'button',
|
|
4475
4666
|
className: 'dsh-cron-send-btn',
|
|
4476
4667
|
disabled: dshLoading || !dshPrompt.trim(),
|
|
4477
4668
|
title: T_KEY(t, 'dsh.sendTitle'),
|
|
4478
4669
|
onClick: handleStartWithDSH
|
|
4479
4670
|
},
|
|
4480
|
-
|
|
4671
|
+
h('span', svgProps(ICON_SEND))
|
|
4481
4672
|
)
|
|
4482
4673
|
)
|
|
4483
4674
|
)
|
|
4484
4675
|
),
|
|
4485
|
-
|
|
4486
|
-
|
|
4676
|
+
h('div', { className: 'dsh-cron-modal-foot' },
|
|
4677
|
+
h('button', {
|
|
4487
4678
|
type: 'button',
|
|
4488
4679
|
className: 'dsh-cron-btn-secondary',
|
|
4489
4680
|
disabled: dshLoading,
|
|
@@ -4694,15 +4885,15 @@ setTestInfo({ success: false, message: T_KEY(t, 'settings.kanbanFail', { error:
|
|
|
4694
4885
|
}
|
|
4695
4886
|
};
|
|
4696
4887
|
if (loadState !== 'ready') {
|
|
4697
|
-
return
|
|
4698
|
-
|
|
4699
|
-
|
|
4888
|
+
return h('div', { className: 'dsh-cron-card' },
|
|
4889
|
+
h('div', { className: 'dsh-cron-card-title' }, T_KEY(t, 'settings.cardTitle')),
|
|
4890
|
+
h('div', {
|
|
4700
4891
|
className: 'dsh-cron-status-banner',
|
|
4701
4892
|
'data-type': loadState === 'error' ? 'error' : 'info',
|
|
4702
4893
|
style: { marginTop: '10px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: '10px' }
|
|
4703
4894
|
},
|
|
4704
|
-
|
|
4705
|
-
loadState === 'error' &&
|
|
4895
|
+
h('span', null, loadState === 'error' ? T_KEY(t, 'settings.unavailable') : T_KEY(t, 'settings.loading')),
|
|
4896
|
+
loadState === 'error' && h('button', {
|
|
4706
4897
|
type: 'button',
|
|
4707
4898
|
className: 'dsh-cron-btn-secondary',
|
|
4708
4899
|
onClick: () => setReloadTick(x => x + 1)
|
|
@@ -4711,88 +4902,88 @@ onClick: () => setReloadTick(x => x + 1)
|
|
|
4711
4902
|
);
|
|
4712
4903
|
}
|
|
4713
4904
|
if (props && props.view === 'summary') {
|
|
4714
|
-
return
|
|
4905
|
+
return h('span', { className: 'dsh-cron-card-desc' }, T_KEY(t, 'settings.cardDesc'));
|
|
4715
4906
|
}
|
|
4716
4907
|
const page = !!(props && props.view === 'page');
|
|
4717
|
-
return
|
|
4718
|
-
|
|
4908
|
+
return h('div', { className: page ? 'dsh-cron-page' : 'dsh-cron-card' },
|
|
4909
|
+
h('button', {
|
|
4719
4910
|
type: 'button',
|
|
4720
4911
|
className: 'dsh-cron-card-head-btn',
|
|
4721
4912
|
style: page ? { display: 'none' } : undefined,
|
|
4722
4913
|
'aria-expanded': (page || cardOpen) ? 'true' : 'false',
|
|
4723
4914
|
onClick: () => setCardOpen(!cardOpen)
|
|
4724
4915
|
},
|
|
4725
|
-
|
|
4726
|
-
|
|
4916
|
+
h('span', { className: 'dsh-cron-card-title' }, T_KEY(t, 'settings.cardTitle')),
|
|
4917
|
+
h('span', { className: 'dsh-cron-chev' + (cardOpen ? ' dsh-cron-chev-open' : '') }, chevronNode())
|
|
4727
4918
|
),
|
|
4728
|
-
(page || cardOpen) &&
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4919
|
+
(page || cardOpen) && h('div', { className: 'dsh-cron-card-body' },
|
|
4920
|
+
h('div', { className: 'dsh-cron-card-desc' }, T_KEY(t, 'settings.cardDesc')),
|
|
4921
|
+
h('div', { style: { display: 'flex', justifyContent: 'flex-end', marginBottom: '12px' } },
|
|
4922
|
+
h('button', {
|
|
4732
4923
|
type: 'button',
|
|
4733
4924
|
className: 'dsh-cron-btn-primary',
|
|
4734
4925
|
onClick: () => { if (toggle) toggle.set(true); }
|
|
4735
4926
|
}, T_KEY(t, 'settings.openPanel'))
|
|
4736
4927
|
),
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4928
|
+
h('form', { onSubmit: saveSettings, style: { display: 'flex', flexDirection: 'column', gap: '12px' } },
|
|
4929
|
+
h('div', { className: 'dsh-cron-form-group', style: { marginBottom: 0 } },
|
|
4930
|
+
h('label', null, T_KEY(t, 'settings.tokenLabel')),
|
|
4931
|
+
h('input', {
|
|
4741
4932
|
type: 'password',
|
|
4742
4933
|
value: token,
|
|
4743
4934
|
placeholder: hasDefault ? T_KEY(t, 'settings.tokenPlaceholderDefault') : T_KEY(t, 'settings.tokenPlaceholder'),
|
|
4744
4935
|
onChange: (e) => setToken(e.target.value)
|
|
4745
4936
|
}),
|
|
4746
|
-
hasDefault &&
|
|
4937
|
+
hasDefault && h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'settings.defaultHint'))
|
|
4747
4938
|
),
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4939
|
+
h('div', { className: 'dsh-cron-form-group', style: { marginBottom: 0 } },
|
|
4940
|
+
h('label', null, T_KEY(t, 'settings.chatIdLabel')),
|
|
4941
|
+
h('input', {
|
|
4751
4942
|
value: chatId,
|
|
4752
4943
|
placeholder: T_KEY(t, 'settings.chatIdPlaceholder'),
|
|
4753
4944
|
onChange: (e) => setChatId(e.target.value)
|
|
4754
4945
|
})
|
|
4755
4946
|
),
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4947
|
+
h('div', { className: 'dsh-cron-form-group', style: { marginBottom: 0 } },
|
|
4948
|
+
h('label', null, T_KEY(t, 'settings.kanbanUrlLabel')),
|
|
4949
|
+
h('input', {
|
|
4759
4950
|
value: kanbanUrl,
|
|
4760
4951
|
placeholder: 'http://127.0.0.1:3000',
|
|
4761
4952
|
onChange: (e) => setKanbanUrl(e.target.value)
|
|
4762
4953
|
})
|
|
4763
4954
|
),
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4955
|
+
h('div', { style: { background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary) 2%, transparent))', border: '1px solid var(--dsw-alias-border-l2)', borderRadius: '6px', padding: '10px 12px', display: 'flex', flexDirection: 'column', gap: '8px' } },
|
|
4956
|
+
h('label', { className: 'dsh-cron-checkbox-row' },
|
|
4957
|
+
h('input', {
|
|
4767
4958
|
type: 'checkbox',
|
|
4768
4959
|
checked: notify,
|
|
4769
4960
|
onChange: (e) => setNotify(e.target.checked)
|
|
4770
4961
|
}),
|
|
4771
|
-
|
|
4962
|
+
h('span', null, T_KEY(t, 'settings.globalNotify'))
|
|
4772
4963
|
),
|
|
4773
|
-
|
|
4774
|
-
|
|
4964
|
+
h('label', { className: 'dsh-cron-checkbox-row' },
|
|
4965
|
+
h('input', {
|
|
4775
4966
|
type: 'checkbox',
|
|
4776
4967
|
checked: onlyFailure,
|
|
4777
4968
|
onChange: (e) => setOnlyFailure(e.target.checked)
|
|
4778
4969
|
}),
|
|
4779
|
-
|
|
4970
|
+
h('span', null, T_KEY(t, 'settings.globalOnlyFailure'))
|
|
4780
4971
|
),
|
|
4781
|
-
|
|
4782
|
-
|
|
4972
|
+
h('label', { className: 'dsh-cron-checkbox-row' },
|
|
4973
|
+
h('input', {
|
|
4783
4974
|
type: 'checkbox',
|
|
4784
4975
|
checked: llmActionsEnabled,
|
|
4785
4976
|
onChange: (e) => setLlmActionsEnabled(e.target.checked)
|
|
4786
4977
|
}),
|
|
4787
|
-
|
|
4978
|
+
h('span', null, 'Enable Structured LLM Actions (trigger tasks, notify, create issues)')
|
|
4788
4979
|
),
|
|
4789
|
-
|
|
4790
|
-
|
|
4980
|
+
h('label', { className: 'dsh-cron-checkbox-row' },
|
|
4981
|
+
h('input', {
|
|
4791
4982
|
type: 'checkbox',
|
|
4792
4983
|
checked: enableDynamicCredentials,
|
|
4793
4984
|
onChange: (e) => setEnableDynamicCredentials(e.target.checked)
|
|
4794
4985
|
}),
|
|
4795
|
-
|
|
4986
|
+
h('span', null, T_KEY(t, 'settings.dynamicCredentials'))
|
|
4796
4987
|
)
|
|
4797
4988
|
),
|
|
4798
4989
|
...renderDeliverySettings({
|
|
@@ -4813,12 +5004,12 @@ return Object.assign({}, prev, { channelTemplates: templates });
|
|
|
4813
5004
|
sections,
|
|
4814
5005
|
onToggleSection: (key) => setSections((prev) => Object.assign({}, prev, { [key]: !prev[key] })),
|
|
4815
5006
|
}),
|
|
4816
|
-
testInfo && testInfo.message &&
|
|
5007
|
+
testInfo && testInfo.message && h('div', {
|
|
4817
5008
|
className: 'dsh-cron-status-banner',
|
|
4818
5009
|
'data-type': testInfo.success ? 'success' : 'error',
|
|
4819
5010
|
style: { margin: 0, padding: '8px 12px' }
|
|
4820
5011
|
}, testInfo.message),
|
|
4821
|
-
|
|
5012
|
+
h('div', {
|
|
4822
5013
|
className: 'dsh-cron-form-group',
|
|
4823
5014
|
style: {
|
|
4824
5015
|
background: 'var(--dsw-alias-bg-layer-2, color-mix(in srgb, var(--dsw-alias-label-primary) 3%, transparent))',
|
|
@@ -4828,19 +5019,19 @@ padding: '14px',
|
|
|
4828
5019
|
marginBottom: '16px'
|
|
4829
5020
|
}
|
|
4830
5021
|
},
|
|
4831
|
-
|
|
5022
|
+
h('div', {
|
|
4832
5023
|
style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px' }
|
|
4833
5024
|
},
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
5025
|
+
h('div', { style: { fontWeight: '600', fontSize: '14px' } }, `🚀 ${T_KEY(t, 'updater.title')}`),
|
|
5026
|
+
h('div', { style: { display: 'flex', gap: '8px' } },
|
|
5027
|
+
h('button', {
|
|
4837
5028
|
type: 'button',
|
|
4838
5029
|
className: 'dsh-cron-btn-secondary',
|
|
4839
5030
|
style: { padding: '4px 10px', fontSize: '12px' },
|
|
4840
5031
|
disabled: updateState.checking || updateState.updating,
|
|
4841
5032
|
onClick: checkUpdates
|
|
4842
5033
|
}, updateState.checking ? T_KEY(t, 'updater.checking') : T_KEY(t, 'updater.btnCheck')),
|
|
4843
|
-
updateState.updateAvailable ?
|
|
5034
|
+
updateState.updateAvailable ? h('button', {
|
|
4844
5035
|
type: 'button',
|
|
4845
5036
|
className: 'dsh-cron-btn-primary',
|
|
4846
5037
|
style: { padding: '4px 10px', fontSize: '12px' },
|
|
@@ -4849,39 +5040,39 @@ onClick: runUpdate
|
|
|
4849
5040
|
}, updateState.updating ? T_KEY(t, 'updater.updating') : T_KEY(t, 'updater.btnUpdate', { version: updateState.latestVersion })) : null
|
|
4850
5041
|
)
|
|
4851
5042
|
),
|
|
4852
|
-
|
|
5043
|
+
h('div', {
|
|
4853
5044
|
style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #999)', marginBottom: '8px' }
|
|
4854
5045
|
}, T_KEY(t, 'updater.desc')),
|
|
4855
|
-
|
|
5046
|
+
h('div', {
|
|
4856
5047
|
style: { display: 'flex', alignItems: 'center', gap: '12px', fontSize: '13px' }
|
|
4857
5048
|
},
|
|
4858
|
-
|
|
5049
|
+
h('span', { style: { color: 'var(--dsw-alias-label-secondary, #aaa)' } },
|
|
4859
5050
|
updateState.currentVersion ? T_KEY(t, 'updater.current', { version: updateState.currentVersion }) : ''
|
|
4860
5051
|
),
|
|
4861
|
-
updateState.checking ?
|
|
4862
|
-
updateState.updateAvailable ?
|
|
4863
|
-
updateState.currentVersion && !updateState.error && !updateState.checking ?
|
|
5052
|
+
updateState.checking ? h('span', { className: 'dsh-cron-badge dsh-cron-badge-info' }, T_KEY(t, 'updater.checking')) :
|
|
5053
|
+
updateState.updateAvailable ? h('span', { className: 'dsh-cron-badge dsh-cron-badge-warn' }, T_KEY(t, 'updater.available', { version: updateState.latestVersion })) :
|
|
5054
|
+
updateState.currentVersion && !updateState.error && !updateState.checking ? h('span', { className: 'dsh-cron-badge dsh-cron-badge-ok' }, `✓ ${T_KEY(t, 'updater.upToDate')}`) : null
|
|
4864
5055
|
),
|
|
4865
|
-
updateState.notice ?
|
|
5056
|
+
updateState.notice ? h('div', {
|
|
4866
5057
|
style: { marginTop: '8px', color: 'var(--dsw-alias-success)', fontSize: '12px' }
|
|
4867
5058
|
}, updateState.notice) : null,
|
|
4868
|
-
updateState.error ?
|
|
5059
|
+
updateState.error ? h('div', {
|
|
4869
5060
|
style: { marginTop: '8px', color: 'var(--dsw-alias-error)', fontSize: '12px' }
|
|
4870
5061
|
}, updateState.error) : null
|
|
4871
5062
|
),
|
|
4872
|
-
|
|
4873
|
-
|
|
5063
|
+
h('div', { style: { display: 'flex', gap: '8px', alignItems: 'center', flexWrap: 'wrap', marginTop: '4px' } },
|
|
5064
|
+
h('button', {
|
|
4874
5065
|
type: 'submit',
|
|
4875
5066
|
className: 'dsh-cron-btn-primary',
|
|
4876
5067
|
style: { minWidth: '140px' }
|
|
4877
5068
|
}, saved ? T_KEY(t, 'settings.saved') : T_KEY(t, 'settings.save')),
|
|
4878
|
-
|
|
5069
|
+
h('button', {
|
|
4879
5070
|
type: 'button',
|
|
4880
5071
|
className: 'dsh-cron-btn-secondary',
|
|
4881
5072
|
onClick: testTelegram,
|
|
4882
5073
|
disabled: testInfo?.loading
|
|
4883
5074
|
}, T_KEY(t, 'settings.testTelegram')),
|
|
4884
|
-
|
|
5075
|
+
h('button', {
|
|
4885
5076
|
type: 'button',
|
|
4886
5077
|
className: 'dsh-cron-btn-secondary',
|
|
4887
5078
|
onClick: testKanban,
|
|
@@ -5106,9 +5297,9 @@ container.setAttribute('data-dsh-plugin', 'dsh-cron');
|
|
|
5106
5297
|
column.appendChild(container);
|
|
5107
5298
|
if (ReactDOM && typeof ReactDOM.createRoot === 'function') {
|
|
5108
5299
|
root = ReactDOM.createRoot(container);
|
|
5109
|
-
root.render(
|
|
5300
|
+
root.render(h(ErrorBoundary, null, h(CronScreen, { ctx, toggle, onClose: () => toggle.set(false), t: translate })));
|
|
5110
5301
|
} else if (ReactDOM && typeof ReactDOM.render === 'function') {
|
|
5111
|
-
ReactDOM.render(
|
|
5302
|
+
ReactDOM.render(h(CronScreen, { ctx, toggle, onClose: () => toggle.set(false), t: translate }), container);
|
|
5112
5303
|
}
|
|
5113
5304
|
};
|
|
5114
5305
|
const applyActive = () => {
|
|
@@ -5176,7 +5367,7 @@ translate = ctx.locale.bind(NS);
|
|
|
5176
5367
|
}
|
|
5177
5368
|
const toggle = createToggle();
|
|
5178
5369
|
function SettingsCardWithBoundary(props) {
|
|
5179
|
-
return
|
|
5370
|
+
return h(ErrorBoundary, null, CronSettingsCard(props));
|
|
5180
5371
|
}
|
|
5181
5372
|
const itemOk = registerIntoMount(ctx, 'plugins.item', {
|
|
5182
5373
|
name: 'plugins.item',
|
|
@@ -5215,7 +5406,7 @@ const cardSlot = cardOk ? 'settings.plugin.item' : undefined;
|
|
|
5215
5406
|
const chipSlot = chipOk ? 'conversation.session.header.utilities' : undefined;
|
|
5216
5407
|
function CronChip(props) {
|
|
5217
5408
|
const chipT = props.t || translate;
|
|
5218
|
-
return
|
|
5409
|
+
return h('button', {
|
|
5219
5410
|
type: 'button',
|
|
5220
5411
|
style: { background: 'none', border: 'none', color: 'var(--dsw-alias-label-secondary, #999)', cursor: 'pointer', padding: '4px', display: 'inline-flex', alignItems: 'center' },
|
|
5221
5412
|
title: T_KEY(chipT, 'chip.title'),
|