@goodandready/dsh-cron 0.3.11 → 0.3.13
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 +14 -1
- package/README.ru.md +14 -1
- package/README.zh.md +23 -0
- package/lib/api-helpers.js +9 -9
- package/lib/api-task-webhook.js +4 -4
- package/lib/api.js +133 -19
- package/lib/branching.js +341 -0
- package/lib/client.js +870 -758
- package/lib/dag.js +88 -18
- package/lib/doctor.js +431 -0
- package/lib/http-utils.js +116 -35
- package/lib/index.js +2 -2
- package/lib/routes.js +19 -19
- package/lib/scheduler-execution.js +59 -6
- package/lib/task-create.js +9 -0
- package/lib/task-patch.js +18 -1
- package/lib/task-transfer.js +7 -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,62 @@ 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.silentSkip &&
|
|
3560
|
+
run.silentSkip && h('div', {
|
|
3470
3561
|
className: 'dsh-cron-hint',
|
|
3471
3562
|
style: { display: 'flex', gap: '6px', alignItems: 'center' }
|
|
3472
3563
|
},
|
|
3473
|
-
|
|
3474
|
-
|
|
3564
|
+
h('span', { className: 'dsh-cron-badge-ref' }, T_KEY(t, 'history.silentSkip')),
|
|
3565
|
+
h('span', null, run.silentReason || '')
|
|
3475
3566
|
),
|
|
3476
|
-
run.output &&
|
|
3477
|
-
run.error &&
|
|
3478
|
-
run.sessionId &&
|
|
3567
|
+
run.output && h('div', { className: 'dsh-cron-history-output' }, run.output),
|
|
3568
|
+
run.error && h('div', { className: 'dsh-cron-history-output', style: { color: 'var(--dsh-cron-danger)', borderColor: 'var(--dsh-cron-danger-bg)' } }, run.error),
|
|
3569
|
+
run.sessionId && h('button', {
|
|
3479
3570
|
type: 'button',
|
|
3480
3571
|
className: 'dsh-cron-btn-secondary',
|
|
3481
3572
|
style: { marginTop: '8px', fontSize: '12px', padding: '4px 10px' },
|
|
@@ -3483,23 +3574,23 @@ onClick: () => openSession(ctx, run.sessionId)
|
|
|
3483
3574
|
}, T_KEY(t, 'history.openSession'))
|
|
3484
3575
|
))
|
|
3485
3576
|
),
|
|
3486
|
-
|
|
3487
|
-
|
|
3577
|
+
h('div', { className: 'dsh-cron-modal-foot', style: { marginTop: '18px' } },
|
|
3578
|
+
h('button', {
|
|
3488
3579
|
type: 'button',
|
|
3489
3580
|
className: 'dsh-cron-btn-secondary',
|
|
3490
3581
|
onClick: () => { if (formId) loadTaskHistory(formId); }
|
|
3491
3582
|
}, T_KEY(t, 'history.refresh')),
|
|
3492
|
-
|
|
3583
|
+
h('button', {
|
|
3493
3584
|
type: 'button',
|
|
3494
3585
|
className: 'dsh-cron-btn-primary',
|
|
3495
3586
|
onClick: closeManualModalWithConfirm
|
|
3496
3587
|
}, T_KEY(t, 'modal.close'))
|
|
3497
3588
|
)
|
|
3498
3589
|
) :
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3590
|
+
h('form', { onSubmit: handleSaveManual },
|
|
3591
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3592
|
+
h('label', null, T_KEY(t, 'form.nameLabel')),
|
|
3593
|
+
h('input', {
|
|
3503
3594
|
required: true,
|
|
3504
3595
|
autoFocus: true,
|
|
3505
3596
|
value: formTitle,
|
|
@@ -3507,40 +3598,40 @@ placeholder: T_KEY(t, 'form.namePlaceholder'),
|
|
|
3507
3598
|
onChange: (e) => setFormTitle(e.target.value)
|
|
3508
3599
|
})
|
|
3509
3600
|
),
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3601
|
+
h('div', { className: 'dsh-cron-form-row' },
|
|
3602
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3603
|
+
h('label', null, T_KEY(t, 'form.typeLabel')),
|
|
3604
|
+
h('select', {
|
|
3514
3605
|
value: formType,
|
|
3515
3606
|
onChange: (e) => setFormType(e.target.value)
|
|
3516
3607
|
},
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3608
|
+
h('option', { value: 'llm' }, T_KEY(t, 'form.typeLlm')),
|
|
3609
|
+
h('option', { value: 'script' }, T_KEY(t, 'form.typeScript')),
|
|
3610
|
+
h('option', { value: 'node' }, T_KEY(t, 'form.typeNode')),
|
|
3611
|
+
h('option', { value: 'python' }, T_KEY(t, 'form.typePython')),
|
|
3612
|
+
h('option', { value: 'http' }, T_KEY(t, 'form.typeHttp')),
|
|
3613
|
+
h('option', { value: 'ssh' }, T_KEY(t, 'form.typeSsh')),
|
|
3614
|
+
h('option', { value: 'docker' }, T_KEY(t, 'form.typeDocker')),
|
|
3615
|
+
h('option', { value: 'skill' }, T_KEY(t, 'form.typeSkill')),
|
|
3616
|
+
h('option', { value: 'workflow' }, T_KEY(t, 'form.typeWorkflow'))
|
|
3526
3617
|
)
|
|
3527
3618
|
),
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3619
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3620
|
+
h('label', null, T_KEY(t, 'form.scheduleLabel')),
|
|
3621
|
+
h('input', {
|
|
3531
3622
|
required: true,
|
|
3532
3623
|
value: formSchedule,
|
|
3533
3624
|
placeholder: T_KEY(t, 'form.schedulePlaceholder'),
|
|
3534
3625
|
onChange: (e) => setFormSchedule(e.target.value)
|
|
3535
3626
|
}),
|
|
3536
|
-
|
|
3627
|
+
h('div', { style: { display: 'flex', gap: '5px', flexWrap: 'wrap', marginTop: '5px' } },
|
|
3537
3628
|
[
|
|
3538
3629
|
{ label: '15m', expr: '*/15 * * * *' },
|
|
3539
3630
|
{ label: '1h', expr: '0 * * * *' },
|
|
3540
3631
|
{ label: 'Daily 09:00', expr: '0 9 * * *' },
|
|
3541
3632
|
{ label: 'Weekdays', expr: '0 9 * * 1-5' },
|
|
3542
3633
|
{ label: 'Weekly Mon', expr: '0 9 * * 1' },
|
|
3543
|
-
].map((p) =>
|
|
3634
|
+
].map((p) => h('button', {
|
|
3544
3635
|
key: p.label,
|
|
3545
3636
|
type: 'button',
|
|
3546
3637
|
className: 'dsh-cron-btn-secondary',
|
|
@@ -3548,23 +3639,23 @@ style: { padding: '2px 7px', fontSize: '11px', borderRadius: '4px' },
|
|
|
3548
3639
|
onClick: () => { setFormSchedule(p.expr); handlePreviewSchedule(p.expr); }
|
|
3549
3640
|
}, p.label))
|
|
3550
3641
|
),
|
|
3551
|
-
|
|
3552
|
-
|
|
3642
|
+
h('div', { style: { display: 'flex', gap: '8px', alignItems: 'center', marginTop: '6px' } },
|
|
3643
|
+
h('button', {
|
|
3553
3644
|
type: 'button',
|
|
3554
3645
|
className: 'dsh-cron-btn-secondary',
|
|
3555
3646
|
style: { padding: '3px 8px', fontSize: '11.5px' },
|
|
3556
3647
|
onClick: () => handlePreviewSchedule(formSchedule)
|
|
3557
3648
|
}, T_KEY(t, 'form.previewSchedule')),
|
|
3558
|
-
schedulePreviewRuns && schedulePreviewRuns.length > 0 &&
|
|
3649
|
+
schedulePreviewRuns && schedulePreviewRuns.length > 0 && h('div', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary, #999)' } },
|
|
3559
3650
|
T_KEY(t, 'form.previewScheduleTitle') + ' ' + schedulePreviewRuns.slice(0, 3).map(r => new Date(r).toLocaleTimeString()).join(', ')
|
|
3560
3651
|
)
|
|
3561
3652
|
)
|
|
3562
3653
|
)
|
|
3563
3654
|
),
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3655
|
+
h('div', { className: 'dsh-cron-form-row' },
|
|
3656
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3657
|
+
h('label', null, T_KEY(t, 'form.timeoutLabel')),
|
|
3658
|
+
h('input', {
|
|
3568
3659
|
type: 'number',
|
|
3569
3660
|
min: 1,
|
|
3570
3661
|
value: formTimeoutSeconds,
|
|
@@ -3572,44 +3663,44 @@ placeholder: '1800',
|
|
|
3572
3663
|
onChange: (e) => setFormTimeoutSeconds(e.target.value)
|
|
3573
3664
|
})
|
|
3574
3665
|
),
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3666
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3667
|
+
h('label', null, T_KEY(t, 'form.overlapLabel')),
|
|
3668
|
+
h('select', {
|
|
3578
3669
|
value: formOverlapPolicy,
|
|
3579
3670
|
onChange: (e) => setFormOverlapPolicy(e.target.value)
|
|
3580
3671
|
},
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3672
|
+
h('option', { value: 'skip' }, T_KEY(t, 'form.overlapSkip')),
|
|
3673
|
+
h('option', { value: 'queue' }, T_KEY(t, 'form.overlapQueue')),
|
|
3674
|
+
h('option', { value: 'replace' }, T_KEY(t, 'form.overlapReplace'))
|
|
3584
3675
|
)
|
|
3585
3676
|
)
|
|
3586
3677
|
),
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3678
|
+
h('div', { className: 'dsh-cron-form-row' },
|
|
3679
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3680
|
+
h('label', null, T_KEY(t, 'form.timezoneLabel')),
|
|
3681
|
+
h('input', {
|
|
3591
3682
|
value: formTimezone,
|
|
3592
3683
|
placeholder: T_KEY(t, 'form.timezonePlaceholder'),
|
|
3593
3684
|
onChange: (e) => setFormTimezone(e.target.value)
|
|
3594
3685
|
})
|
|
3595
3686
|
),
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3687
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3688
|
+
h('label', null, T_KEY(t, 'form.misfireLabel')),
|
|
3689
|
+
h('select', {
|
|
3599
3690
|
value: formMisfirePolicy,
|
|
3600
3691
|
onChange: (e) => setFormMisfirePolicy(e.target.value)
|
|
3601
3692
|
},
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3693
|
+
h('option', { value: 'skip' }, T_KEY(t, 'form.misfireSkip')),
|
|
3694
|
+
h('option', { value: 'runOnce' }, T_KEY(t, 'form.misfireRunOnce')),
|
|
3695
|
+
h('option', { value: 'catchUpAll' }, T_KEY(t, 'form.misfireCatchUp'))
|
|
3605
3696
|
)
|
|
3606
3697
|
)
|
|
3607
3698
|
),
|
|
3608
3699
|
AGENT_FORM_TYPES.includes(formType) ? (
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3700
|
+
h('div', { className: 'dsh-cron-form-row' },
|
|
3701
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3702
|
+
h('label', null, T_KEY(t, 'form.retriesLabel')),
|
|
3703
|
+
h('input', {
|
|
3613
3704
|
type: 'number',
|
|
3614
3705
|
min: 0,
|
|
3615
3706
|
value: formMaxRetries,
|
|
@@ -3617,23 +3708,23 @@ placeholder: '0',
|
|
|
3617
3708
|
onChange: (e) => setFormMaxRetries(e.target.value)
|
|
3618
3709
|
})
|
|
3619
3710
|
),
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3711
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3712
|
+
h('label', null, T_KEY(t, 'form.permissionLabel')),
|
|
3713
|
+
h('select', {
|
|
3623
3714
|
value: formPermissionPreset,
|
|
3624
3715
|
onChange: (e) => setFormPermissionPreset(e.target.value)
|
|
3625
3716
|
},
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3717
|
+
h('option', { value: 'default' }, T_KEY(t, 'form.permissionDefault')),
|
|
3718
|
+
h('option', { value: 'read-only' }, T_KEY(t, 'form.permissionReadonly')),
|
|
3719
|
+
h('option', { value: 'workspace-write' }, T_KEY(t, 'form.permissionWrite')),
|
|
3720
|
+
h('option', { value: 'full' }, T_KEY(t, 'form.permissionFull'))
|
|
3630
3721
|
)
|
|
3631
3722
|
)
|
|
3632
3723
|
)
|
|
3633
3724
|
) : (
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3725
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3726
|
+
h('label', null, T_KEY(t, 'form.retriesLabel')),
|
|
3727
|
+
h('input', {
|
|
3637
3728
|
type: 'number',
|
|
3638
3729
|
min: 0,
|
|
3639
3730
|
value: formMaxRetries,
|
|
@@ -3642,114 +3733,114 @@ onChange: (e) => setFormMaxRetries(e.target.value)
|
|
|
3642
3733
|
})
|
|
3643
3734
|
)
|
|
3644
3735
|
),
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3736
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3737
|
+
h('label', null, T_KEY(t, 'form.kanbanLabel')),
|
|
3738
|
+
h('select', {
|
|
3648
3739
|
value: formKanbanMode,
|
|
3649
3740
|
onChange: (e) => setFormKanbanMode(e.target.value)
|
|
3650
3741
|
},
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3742
|
+
h('option', { value: 'none' }, T_KEY(t, 'form.kanbanNone')),
|
|
3743
|
+
h('option', { value: 'on_failure' }, T_KEY(t, 'form.kanbanOnFailure')),
|
|
3744
|
+
h('option', { value: 'always' }, T_KEY(t, 'form.kanbanAlways'))
|
|
3654
3745
|
)
|
|
3655
3746
|
),
|
|
3656
|
-
AGENT_FORM_TYPES.includes(formType) &&
|
|
3657
|
-
|
|
3658
|
-
|
|
3747
|
+
AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-group' },
|
|
3748
|
+
h('label', null, T_KEY(t, 'form.agentPresetLabel')),
|
|
3749
|
+
h('input', {
|
|
3659
3750
|
type: 'text',
|
|
3660
3751
|
value: formAgentPreset,
|
|
3661
3752
|
placeholder: T_KEY(t, 'form.agentPresetPlaceholder'),
|
|
3662
3753
|
onChange: (e) => setFormAgentPreset(e.target.value)
|
|
3663
3754
|
}),
|
|
3664
|
-
|
|
3755
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.agentPresetHint'))
|
|
3665
3756
|
),
|
|
3666
|
-
AGENT_FORM_TYPES.includes(formType) &&
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3757
|
+
AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-row' },
|
|
3758
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3759
|
+
h('label', null, T_KEY(t, 'form.targetSessionIdLabel')),
|
|
3760
|
+
h('input', {
|
|
3670
3761
|
type: 'text',
|
|
3671
3762
|
value: formTargetSessionId,
|
|
3672
3763
|
placeholder: T_KEY(t, 'form.targetSessionIdPlaceholder'),
|
|
3673
3764
|
onChange: (e) => setFormTargetSessionId(e.target.value)
|
|
3674
3765
|
}),
|
|
3675
|
-
|
|
3766
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.targetSessionIdHint'))
|
|
3676
3767
|
),
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3768
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3769
|
+
h('label', null, T_KEY(t, 'form.targetSessionResetLabel')),
|
|
3770
|
+
h('select', {
|
|
3680
3771
|
value: formTargetSessionReset,
|
|
3681
3772
|
onChange: (e) => setFormTargetSessionReset(e.target.value)
|
|
3682
3773
|
},
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3774
|
+
h('option', { value: 'never' }, T_KEY(t, 'form.targetSessionResetNever')),
|
|
3775
|
+
h('option', { value: 'daily' }, T_KEY(t, 'form.targetSessionResetDaily')),
|
|
3776
|
+
h('option', { value: 'weekly' }, T_KEY(t, 'form.targetSessionResetWeekly'))
|
|
3686
3777
|
),
|
|
3687
|
-
|
|
3778
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.targetSessionResetHint'))
|
|
3688
3779
|
)
|
|
3689
3780
|
),
|
|
3690
|
-
AGENT_FORM_TYPES.includes(formType) &&
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3781
|
+
AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-row' },
|
|
3782
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3783
|
+
h('label', null, T_KEY(t, 'form.providerLabel')),
|
|
3784
|
+
h('select', {
|
|
3694
3785
|
value: formProvider,
|
|
3695
3786
|
onChange: handleProviderChange
|
|
3696
3787
|
},
|
|
3697
|
-
|
|
3698
|
-
providers.map((p) =>
|
|
3788
|
+
h('option', { value: '' }, T_KEY(t, 'form.providerDefault')),
|
|
3789
|
+
providers.map((p) => h('option', { key: p.id, value: p.id }, p.name || p.id))
|
|
3699
3790
|
)
|
|
3700
3791
|
),
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3792
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3793
|
+
h('label', null, T_KEY(t, 'form.modelLabel')),
|
|
3794
|
+
h('select', {
|
|
3704
3795
|
value: formModel,
|
|
3705
3796
|
onChange: (e) => setFormModel(e.target.value)
|
|
3706
3797
|
},
|
|
3707
|
-
|
|
3708
|
-
models.map((m) =>
|
|
3798
|
+
h('option', { value: '' }, T_KEY(t, 'form.modelDefault')),
|
|
3799
|
+
models.map((m) => h('option', { key: m.id, value: m.id }, m.name || m.id))
|
|
3709
3800
|
)
|
|
3710
3801
|
),
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3802
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3803
|
+
h('label', null, T_KEY(t, 'form.fallbackModelLabel')),
|
|
3804
|
+
h('input', {
|
|
3714
3805
|
type: 'text',
|
|
3715
3806
|
value: formFallbackModel,
|
|
3716
3807
|
placeholder: T_KEY(t, 'form.fallbackModelPlaceholder'),
|
|
3717
3808
|
onChange: (e) => setFormFallbackModel(e.target.value)
|
|
3718
3809
|
}),
|
|
3719
|
-
|
|
3810
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.fallbackModelHint'))
|
|
3720
3811
|
),
|
|
3721
|
-
|
|
3722
|
-
|
|
3812
|
+
h('label', { className: 'dsh-cron-checkbox-row', style: { marginTop: '4px' } },
|
|
3813
|
+
h('input', {
|
|
3723
3814
|
type: 'checkbox',
|
|
3724
3815
|
checked: formInspectOnFailure,
|
|
3725
3816
|
onChange: (e) => setFormInspectOnFailure(e.target.checked)
|
|
3726
3817
|
}),
|
|
3727
|
-
|
|
3818
|
+
h('span', null, T_KEY(t, 'form.inspectOnFailureLabel'))
|
|
3728
3819
|
),
|
|
3729
|
-
formInspectOnFailure &&
|
|
3730
|
-
|
|
3731
|
-
|
|
3820
|
+
formInspectOnFailure && h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.inspectOnFailureHint')),
|
|
3821
|
+
h('label', { className: 'dsh-cron-checkbox-row', style: { marginTop: '8px' } },
|
|
3822
|
+
h('input', {
|
|
3732
3823
|
type: 'checkbox',
|
|
3733
3824
|
checked: formRequireApproval,
|
|
3734
3825
|
onChange: (e) => setFormRequireApproval(e.target.checked)
|
|
3735
3826
|
}),
|
|
3736
|
-
|
|
3827
|
+
h('span', null, T_KEY(t, 'form.requireApprovalLabel'))
|
|
3737
3828
|
),
|
|
3738
|
-
formRequireApproval &&
|
|
3829
|
+
formRequireApproval && h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.requireApprovalHint'))
|
|
3739
3830
|
),
|
|
3740
|
-
formType === 'http' &&
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3831
|
+
formType === 'http' && h('div', { className: 'dsh-cron-form-row' },
|
|
3832
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3833
|
+
h('label', null, T_KEY(t, 'form.httpMethodLabel')),
|
|
3834
|
+
h('select', {
|
|
3744
3835
|
value: formHttpMethod,
|
|
3745
3836
|
onChange: (e) => setFormHttpMethod(e.target.value)
|
|
3746
3837
|
},
|
|
3747
|
-
['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'].map((m) =>
|
|
3838
|
+
['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'].map((m) => h('option', { key: m, value: m }, m))
|
|
3748
3839
|
)
|
|
3749
3840
|
),
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3841
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3842
|
+
h('label', null, T_KEY(t, 'form.httpUrlLabel')),
|
|
3843
|
+
h('input', {
|
|
3753
3844
|
required: true,
|
|
3754
3845
|
value: formHttpUrl,
|
|
3755
3846
|
placeholder: 'https://example.test/webhook',
|
|
@@ -3757,41 +3848,41 @@ onChange: (e) => setFormHttpUrl(e.target.value)
|
|
|
3757
3848
|
})
|
|
3758
3849
|
)
|
|
3759
3850
|
),
|
|
3760
|
-
formType === 'http' &&
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3851
|
+
formType === 'http' && h('div', { className: 'dsh-cron-form-row' },
|
|
3852
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3853
|
+
h('label', null, T_KEY(t, 'form.httpHeadersLabel')),
|
|
3854
|
+
h('input', {
|
|
3764
3855
|
value: formHttpHeaders,
|
|
3765
3856
|
placeholder: '{"Authorization":"Bearer ..."}',
|
|
3766
3857
|
onChange: (e) => setFormHttpHeaders(e.target.value)
|
|
3767
3858
|
})
|
|
3768
3859
|
),
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3860
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3861
|
+
h('label', null, T_KEY(t, 'form.httpBodyLabel')),
|
|
3862
|
+
h('input', {
|
|
3772
3863
|
value: formHttpBody,
|
|
3773
3864
|
onChange: (e) => setFormHttpBody(e.target.value)
|
|
3774
3865
|
})
|
|
3775
3866
|
)
|
|
3776
3867
|
),
|
|
3777
|
-
formType === 'ssh' &&
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3868
|
+
formType === 'ssh' && h('div', { className: 'dsh-cron-form-row' },
|
|
3869
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3870
|
+
h('label', null, T_KEY(t, 'form.sshProfileLabel')),
|
|
3871
|
+
h('input', {
|
|
3781
3872
|
value: formSshProfileId,
|
|
3782
3873
|
placeholder: 'prod-web',
|
|
3783
3874
|
onChange: (e) => setFormSshProfileId(e.target.value)
|
|
3784
3875
|
}),
|
|
3785
|
-
|
|
3876
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.sshProfileHint'))
|
|
3786
3877
|
),
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3878
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3879
|
+
h('label', null, T_KEY(t, 'form.sshTargetLabel')),
|
|
3880
|
+
h('input', {
|
|
3790
3881
|
value: formSshTarget,
|
|
3791
3882
|
placeholder: 'user@example.com',
|
|
3792
3883
|
onChange: (e) => setFormSshTarget(e.target.value)
|
|
3793
3884
|
}),
|
|
3794
|
-
|
|
3885
|
+
h('input', {
|
|
3795
3886
|
style: { marginTop: '6px' },
|
|
3796
3887
|
value: formSshKeyPath,
|
|
3797
3888
|
placeholder: '~/.ssh/id_ed25519',
|
|
@@ -3799,93 +3890,93 @@ onChange: (e) => setFormSshKeyPath(e.target.value)
|
|
|
3799
3890
|
})
|
|
3800
3891
|
)
|
|
3801
3892
|
),
|
|
3802
|
-
formType === 'docker' &&
|
|
3803
|
-
|
|
3804
|
-
|
|
3893
|
+
formType === 'docker' && h('div', { className: 'dsh-cron-form-group' },
|
|
3894
|
+
h('label', null, T_KEY(t, 'form.dockerImageLabel')),
|
|
3895
|
+
h('input', {
|
|
3805
3896
|
required: true,
|
|
3806
3897
|
value: formDockerImage,
|
|
3807
3898
|
placeholder: 'alpine:3.20',
|
|
3808
3899
|
onChange: (e) => setFormDockerImage(e.target.value)
|
|
3809
3900
|
})
|
|
3810
3901
|
),
|
|
3811
|
-
formType === 'skill' &&
|
|
3812
|
-
|
|
3813
|
-
|
|
3902
|
+
formType === 'skill' && h('div', { className: 'dsh-cron-form-group' },
|
|
3903
|
+
h('label', null, T_KEY(t, 'form.skillNameLabel')),
|
|
3904
|
+
h('input', {
|
|
3814
3905
|
value: formSkillName,
|
|
3815
3906
|
placeholder: 'gitea',
|
|
3816
3907
|
onChange: (e) => setFormSkillName(e.target.value)
|
|
3817
3908
|
})
|
|
3818
3909
|
),
|
|
3819
|
-
formType === 'workflow' &&
|
|
3820
|
-
|
|
3821
|
-
|
|
3910
|
+
formType === 'workflow' && h('div', { className: 'dsh-cron-form-group' },
|
|
3911
|
+
h('label', null, T_KEY(t, 'form.workflowNameLabel')),
|
|
3912
|
+
h('input', {
|
|
3822
3913
|
value: formWorkflowName,
|
|
3823
3914
|
placeholder: 'nightly-release',
|
|
3824
3915
|
onChange: (e) => setFormWorkflowName(e.target.value)
|
|
3825
3916
|
})
|
|
3826
3917
|
),
|
|
3827
|
-
(formType === 'node' || formType === 'python') &&
|
|
3828
|
-
|
|
3829
|
-
|
|
3918
|
+
(formType === 'node' || formType === 'python') && h('div', { className: 'dsh-cron-form-group' },
|
|
3919
|
+
h('label', null, formType === 'node' ? 'Node.js binary (optional)' : 'Python interpreter (optional)'),
|
|
3920
|
+
h('input', {
|
|
3830
3921
|
value: formType === 'node' ? formNodePath : formPythonPath,
|
|
3831
3922
|
placeholder: formType === 'node' ? 'auto' : '.venv/bin/python',
|
|
3832
3923
|
onChange: (e) => (formType === 'node' ? setFormNodePath(e.target.value) : setFormPythonPath(e.target.value))
|
|
3833
3924
|
})
|
|
3834
3925
|
),
|
|
3835
|
-
!AGENT_FORM_TYPES.includes(formType) &&
|
|
3836
|
-
|
|
3837
|
-
|
|
3926
|
+
!AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-group' },
|
|
3927
|
+
h('label', null, T_KEY(t, 'form.envLabel')),
|
|
3928
|
+
h('textarea', {
|
|
3838
3929
|
rows: 3,
|
|
3839
3930
|
style: { fontFamily: 'monospace', fontSize: '12.5px' },
|
|
3840
3931
|
value: formEnv,
|
|
3841
3932
|
placeholder: T_KEY(t, 'form.envPlaceholder'),
|
|
3842
3933
|
onChange: (e) => setFormEnv(e.target.value)
|
|
3843
3934
|
}),
|
|
3844
|
-
|
|
3935
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.envHint'))
|
|
3845
3936
|
),
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3937
|
+
h('div', { className: 'dsh-cron-form-row' },
|
|
3938
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3939
|
+
h('label', null, T_KEY(t, 'form.cwdLabel')),
|
|
3940
|
+
h('input', {
|
|
3850
3941
|
value: formCwd,
|
|
3851
3942
|
placeholder: '/srv/app',
|
|
3852
3943
|
onChange: (e) => setFormCwd(e.target.value)
|
|
3853
3944
|
})
|
|
3854
3945
|
),
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3946
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
3947
|
+
h('label', null, T_KEY(t, 'form.workspaceLabel')),
|
|
3948
|
+
h('input', {
|
|
3858
3949
|
value: formWorkspaceId,
|
|
3859
3950
|
onChange: (e) => setFormWorkspaceId(e.target.value)
|
|
3860
3951
|
})
|
|
3861
3952
|
)
|
|
3862
3953
|
),
|
|
3863
|
-
AGENT_FORM_TYPES.includes(formType) &&
|
|
3864
|
-
|
|
3865
|
-
|
|
3954
|
+
AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-group' },
|
|
3955
|
+
h('label', { className: 'dsh-cron-checkbox-row' },
|
|
3956
|
+
h('input', {
|
|
3866
3957
|
type: 'checkbox',
|
|
3867
3958
|
checked: formWorktree,
|
|
3868
3959
|
onChange: (e) => setFormWorktree(e.target.checked)
|
|
3869
3960
|
}),
|
|
3870
|
-
|
|
3961
|
+
h('span', null, T_KEY(t, 'form.worktreeLabel'))
|
|
3871
3962
|
),
|
|
3872
|
-
formWorktree &&
|
|
3873
|
-
|
|
3963
|
+
formWorktree && h('label', { className: 'dsh-cron-checkbox-row', style: { marginLeft: '24px', marginTop: '6px' } },
|
|
3964
|
+
h('input', {
|
|
3874
3965
|
type: 'checkbox',
|
|
3875
3966
|
checked: formKeepWorktree,
|
|
3876
3967
|
onChange: (e) => setFormKeepWorktree(e.target.checked)
|
|
3877
3968
|
}),
|
|
3878
|
-
|
|
3969
|
+
h('span', null, T_KEY(t, 'form.keepWorktreeLabel'))
|
|
3879
3970
|
)
|
|
3880
3971
|
),
|
|
3881
|
-
formType !== 'http' &&
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
(selectedTaskMeta && selectedTaskMeta.promptHistory && selectedTaskMeta.promptHistory.length > 0) ?
|
|
3885
|
-
|
|
3972
|
+
formType !== 'http' && h('div', { className: 'dsh-cron-form-group' },
|
|
3973
|
+
h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '4px' } },
|
|
3974
|
+
h('label', { style: { margin: 0 } }, AGENT_FORM_TYPES.includes(formType) ? T_KEY(t, 'form.promptLabelLlm') : T_KEY(t, 'form.promptLabelScript')),
|
|
3975
|
+
(selectedTaskMeta && selectedTaskMeta.promptHistory && selectedTaskMeta.promptHistory.length > 0) ? h('div', { style: { display: 'flex', gap: '6px', alignItems: 'center' } },
|
|
3976
|
+
h('span', {
|
|
3886
3977
|
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
3978
|
}, '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
|
-
|
|
3979
|
+
h('select', {
|
|
3889
3980
|
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
3981
|
onChange: (e) => {
|
|
3891
3982
|
const targetV = Number(e.target.value);
|
|
@@ -3895,11 +3986,11 @@ setFormPrompt(entry.prompt);
|
|
|
3895
3986
|
}
|
|
3896
3987
|
}
|
|
3897
3988
|
},
|
|
3898
|
-
selectedTaskMeta.promptHistory.map((h) =>
|
|
3989
|
+
selectedTaskMeta.promptHistory.map((h) => h('option', { key: h.version, value: h.version }, 'v' + h.version + ' (' + Math.round((h.successRate || 1) * 100) + '%)'))
|
|
3899
3990
|
)
|
|
3900
3991
|
) : null
|
|
3901
3992
|
),
|
|
3902
|
-
|
|
3993
|
+
h('textarea', {
|
|
3903
3994
|
required: true,
|
|
3904
3995
|
rows: 9,
|
|
3905
3996
|
style: { fontFamily: 'monospace', fontSize: '12.5px', lineHeight: '1.45' },
|
|
@@ -3918,7 +4009,7 @@ placeholder: AGENT_FORM_TYPES.includes(formType)
|
|
|
3918
4009
|
onChange: (e) => setFormPrompt(e.target.value)
|
|
3919
4010
|
})
|
|
3920
4011
|
),
|
|
3921
|
-
|
|
4012
|
+
h('div', {
|
|
3922
4013
|
style: {
|
|
3923
4014
|
background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary) 2%, transparent))',
|
|
3924
4015
|
border: '1px solid var(--dsw-alias-border-l2)',
|
|
@@ -3927,31 +4018,31 @@ padding: '12px 14px',
|
|
|
3927
4018
|
marginBottom: '16px'
|
|
3928
4019
|
}
|
|
3929
4020
|
},
|
|
3930
|
-
|
|
3931
|
-
|
|
4021
|
+
h('div', { style: { fontWeight: 500, fontSize: '13px', color: 'var(--dsw-alias-label-primary, #eee)', marginBottom: '8px', display: 'flex', alignItems: 'center', gap: '6px' } },
|
|
4022
|
+
h('span', { style: { display: 'flex', alignItems: 'center', color: 'var(--dsh-cron-info)' }, ...iconHtml(ICON_TELEGRAM) }),
|
|
3932
4023
|
T_KEY(t, 'form.notifyTitle')
|
|
3933
4024
|
),
|
|
3934
|
-
|
|
3935
|
-
|
|
4025
|
+
h('label', { className: 'dsh-cron-checkbox-row', style: { marginBottom: formNotifyTelegram ? '8px' : '0' } },
|
|
4026
|
+
h('input', {
|
|
3936
4027
|
type: 'checkbox',
|
|
3937
4028
|
checked: formNotifyTelegram,
|
|
3938
4029
|
onChange: (e) => setFormNotifyTelegram(e.target.checked)
|
|
3939
4030
|
}),
|
|
3940
|
-
|
|
4031
|
+
h('span', null, T_KEY(t, 'form.notifyTelegram'))
|
|
3941
4032
|
),
|
|
3942
|
-
(formNotifyTelegram || formChannels.length > 0) &&
|
|
3943
|
-
|
|
4033
|
+
(formNotifyTelegram || formChannels.length > 0) && h('label', { className: 'dsh-cron-checkbox-row', style: { marginLeft: '24px', marginTop: '6px' } },
|
|
4034
|
+
h('input', {
|
|
3944
4035
|
type: 'checkbox',
|
|
3945
4036
|
checked: formOnlyOnFailure,
|
|
3946
4037
|
onChange: (e) => setFormOnlyOnFailure(e.target.checked)
|
|
3947
4038
|
}),
|
|
3948
|
-
|
|
4039
|
+
h('span', null, T_KEY(t, 'form.notifyOnlyFailure'))
|
|
3949
4040
|
),
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
...DELIVERY_CHANNELS.map((id) =>
|
|
3954
|
-
|
|
4041
|
+
h('div', { style: { marginTop: '12px', paddingTop: '10px', borderTop: '1px solid var(--dsw-alias-border-l2)' } },
|
|
4042
|
+
h('div', { style: { fontWeight: 500, fontSize: '12.5px', color: 'var(--dsw-alias-label-secondary, #aaa)', marginBottom: '8px' } }, T_KEY(t, 'form.channelsTitle')),
|
|
4043
|
+
h('div', { className: 'dsh-cron-channel-grid' },
|
|
4044
|
+
...DELIVERY_CHANNELS.map((id) => h('label', { key: id, className: 'dsh-cron-checkbox-row' },
|
|
4045
|
+
h('input', {
|
|
3955
4046
|
type: 'checkbox',
|
|
3956
4047
|
checked: formChannels.indexOf(id) >= 0,
|
|
3957
4048
|
onChange: (e) => {
|
|
@@ -3962,56 +4053,56 @@ return DELIVERY_CHANNELS.filter((c) => set.has(c));
|
|
|
3962
4053
|
});
|
|
3963
4054
|
}
|
|
3964
4055
|
}),
|
|
3965
|
-
|
|
4056
|
+
h('span', null, T_KEY(t, CHANNEL_LABEL_KEYS[id]))
|
|
3966
4057
|
))
|
|
3967
4058
|
),
|
|
3968
|
-
|
|
4059
|
+
h('div', { className: 'dsh-cron-hint', style: { marginTop: '6px' } }, T_KEY(t, 'form.channelsHint'))
|
|
3969
4060
|
),
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
4061
|
+
h('div', { className: 'dsh-cron-form-group', style: { marginTop: '12px', marginBottom: 0 } },
|
|
4062
|
+
h('label', null, T_KEY(t, 'form.templateLabel')),
|
|
4063
|
+
h('input', {
|
|
3973
4064
|
type: 'text',
|
|
3974
4065
|
value: formTemplate,
|
|
3975
4066
|
placeholder: T_KEY(t, 'form.templatePlaceholder'),
|
|
3976
4067
|
onChange: (e) => setFormTemplate(e.target.value)
|
|
3977
4068
|
}),
|
|
3978
|
-
|
|
4069
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.templateHint'))
|
|
3979
4070
|
),
|
|
3980
|
-
!AGENT_FORM_TYPES.includes(formType) &&
|
|
3981
|
-
|
|
3982
|
-
|
|
4071
|
+
!AGENT_FORM_TYPES.includes(formType) && h('div', { className: 'dsh-cron-form-group', style: { marginTop: '12px', marginBottom: 0 } },
|
|
4072
|
+
h('label', null, T_KEY(t, 'form.silentRuleLabel')),
|
|
4073
|
+
h('input', {
|
|
3983
4074
|
type: 'text',
|
|
3984
4075
|
value: formSilentRule,
|
|
3985
4076
|
placeholder: T_KEY(t, 'form.silentRulePlaceholder'),
|
|
3986
4077
|
onChange: (e) => setFormSilentRule(e.target.value)
|
|
3987
4078
|
}),
|
|
3988
|
-
|
|
4079
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.silentRuleHint'))
|
|
3989
4080
|
)
|
|
3990
4081
|
),
|
|
3991
|
-
|
|
4082
|
+
h('div', {
|
|
3992
4083
|
style: {
|
|
3993
4084
|
marginTop: '16px',
|
|
3994
4085
|
paddingTop: '14px',
|
|
3995
4086
|
borderTop: '1px solid var(--dsw-alias-border-l2)'
|
|
3996
4087
|
}
|
|
3997
4088
|
},
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4089
|
+
h('div', { style: { fontWeight: '600', fontSize: '13px', marginBottom: '10px' } }, T_KEY(t, 'form.reliabilityTitle')),
|
|
4090
|
+
h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
|
|
4091
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4092
|
+
h('label', null, T_KEY(t, 'form.preflightLabel')),
|
|
4093
|
+
h('select', {
|
|
4003
4094
|
value: formPreflightType,
|
|
4004
4095
|
onChange: (e) => setFormPreflightType(e.target.value)
|
|
4005
4096
|
},
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4097
|
+
h('option', { value: 'none' }, T_KEY(t, 'form.preflightNone')),
|
|
4098
|
+
h('option', { value: 'http' }, T_KEY(t, 'form.preflightHttp')),
|
|
4099
|
+
h('option', { value: 'shell' }, T_KEY(t, 'form.preflightShell')),
|
|
4100
|
+
h('option', { value: 'disk' }, T_KEY(t, 'form.preflightDisk'))
|
|
4010
4101
|
)
|
|
4011
4102
|
),
|
|
4012
|
-
formPreflightType !== 'none' &&
|
|
4013
|
-
|
|
4014
|
-
|
|
4103
|
+
formPreflightType !== 'none' && h('div', { className: 'dsh-cron-form-group' },
|
|
4104
|
+
h('label', null, T_KEY(t, 'form.preflightTargetLabel')),
|
|
4105
|
+
h('input', {
|
|
4015
4106
|
type: 'text',
|
|
4016
4107
|
value: formPreflightTarget,
|
|
4017
4108
|
placeholder: T_KEY(t, 'form.preflightTargetPlaceholder'),
|
|
@@ -4019,19 +4110,19 @@ onChange: (e) => setFormPreflightTarget(e.target.value)
|
|
|
4019
4110
|
})
|
|
4020
4111
|
)
|
|
4021
4112
|
),
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4113
|
+
h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
|
|
4114
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4115
|
+
h('label', null, T_KEY(t, 'form.heartbeatIntervalLabel')),
|
|
4116
|
+
h('input', {
|
|
4026
4117
|
type: 'number',
|
|
4027
4118
|
value: formHeartbeatIntervalSeconds,
|
|
4028
4119
|
min: 0,
|
|
4029
4120
|
onChange: (e) => setFormHeartbeatIntervalSeconds(Number(e.target.value))
|
|
4030
4121
|
})
|
|
4031
4122
|
),
|
|
4032
|
-
formHeartbeatIntervalSeconds > 0 &&
|
|
4033
|
-
|
|
4034
|
-
|
|
4123
|
+
formHeartbeatIntervalSeconds > 0 && h('div', { className: 'dsh-cron-form-group' },
|
|
4124
|
+
h('label', null, T_KEY(t, 'form.gracePeriodLabel')),
|
|
4125
|
+
h('input', {
|
|
4035
4126
|
type: 'number',
|
|
4036
4127
|
value: formGracePeriodSeconds,
|
|
4037
4128
|
min: 1,
|
|
@@ -4039,10 +4130,10 @@ onChange: (e) => setFormGracePeriodSeconds(Number(e.target.value))
|
|
|
4039
4130
|
})
|
|
4040
4131
|
)
|
|
4041
4132
|
),
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4133
|
+
h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
|
|
4134
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4135
|
+
h('label', null, T_KEY(t, 'form.priorityLabel')),
|
|
4136
|
+
h('input', {
|
|
4046
4137
|
type: 'number',
|
|
4047
4138
|
value: formPriority,
|
|
4048
4139
|
min: 1,
|
|
@@ -4050,117 +4141,138 @@ max: 10,
|
|
|
4050
4141
|
onChange: (e) => setFormPriority(Number(e.target.value))
|
|
4051
4142
|
})
|
|
4052
4143
|
),
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4144
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4145
|
+
h('label', null, T_KEY(t, 'form.concurrencyGroupLabel')),
|
|
4146
|
+
h('input', {
|
|
4056
4147
|
type: 'text',
|
|
4057
4148
|
value: formConcurrencyGroup,
|
|
4058
4149
|
onChange: (e) => setFormConcurrencyGroup(e.target.value)
|
|
4059
4150
|
})
|
|
4060
4151
|
)
|
|
4061
4152
|
),
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4153
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4154
|
+
h('label', null, T_KEY(t, 'form.selfHealingLabel')),
|
|
4155
|
+
h('input', {
|
|
4065
4156
|
type: 'text',
|
|
4066
4157
|
value: formSelfHealingCommand,
|
|
4067
4158
|
placeholder: T_KEY(t, 'form.selfHealingPlaceholder'),
|
|
4068
4159
|
onChange: (e) => setFormSelfHealingCommand(e.target.value)
|
|
4069
4160
|
})
|
|
4070
4161
|
),
|
|
4071
|
-
|
|
4072
|
-
|
|
4162
|
+
h('div', { style: { display: 'flex', alignItems: 'center', gap: '8px', marginTop: '6px' } },
|
|
4163
|
+
h('input', {
|
|
4073
4164
|
type: 'checkbox',
|
|
4074
4165
|
id: 'formAutoDiagnoseCheckbox',
|
|
4075
4166
|
checked: formAutoDiagnose,
|
|
4076
4167
|
onChange: (e) => setFormAutoDiagnose(e.target.checked)
|
|
4077
4168
|
}),
|
|
4078
|
-
|
|
4169
|
+
h('label', { htmlFor: 'formAutoDiagnoseCheckbox', style: { margin: 0, fontSize: '12.5px', cursor: 'pointer' } }, T_KEY(t, 'form.autoDiagnoseLabel'))
|
|
4079
4170
|
)
|
|
4080
4171
|
),
|
|
4081
|
-
|
|
4172
|
+
h('div', {
|
|
4082
4173
|
style: {
|
|
4083
4174
|
marginTop: '16px',
|
|
4084
4175
|
paddingTop: '14px',
|
|
4085
4176
|
borderTop: '1px solid var(--dsw-alias-border-l2)'
|
|
4086
4177
|
}
|
|
4087
4178
|
},
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4179
|
+
h('div', { style: { fontWeight: '600', fontSize: '13px', marginBottom: '10px' } }, '⛓️ ' + T_KEY(t, 'form.chainingTitle')),
|
|
4180
|
+
h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
|
|
4181
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4182
|
+
h('label', null, T_KEY(t, 'form.onSuccessLabel')),
|
|
4183
|
+
h('input', {
|
|
4093
4184
|
type: 'text',
|
|
4094
4185
|
value: formOnSuccess,
|
|
4095
4186
|
placeholder: 'task-build, task-test',
|
|
4096
4187
|
onChange: (e) => setFormOnSuccess(e.target.value)
|
|
4097
4188
|
}),
|
|
4098
|
-
|
|
4189
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.onSuccessHint'))
|
|
4099
4190
|
),
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4191
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4192
|
+
h('label', null, T_KEY(t, 'form.onFailureLabel')),
|
|
4193
|
+
h('input', {
|
|
4103
4194
|
type: 'text',
|
|
4104
4195
|
value: formOnFailure,
|
|
4105
4196
|
placeholder: 'task-alert',
|
|
4106
4197
|
onChange: (e) => setFormOnFailure(e.target.value)
|
|
4107
4198
|
}),
|
|
4108
|
-
|
|
4199
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.onFailureHint'))
|
|
4109
4200
|
)
|
|
4110
4201
|
),
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4202
|
+
h('div', { style: { display: 'grid', gridTemplateColumns: '2fr 1fr', gap: '10px', marginTop: '8px' } },
|
|
4203
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4204
|
+
h('label', null, T_KEY(t, 'form.dependsOnLabel')),
|
|
4205
|
+
h('input', {
|
|
4115
4206
|
type: 'text',
|
|
4116
4207
|
value: formDependsOn,
|
|
4117
4208
|
placeholder: 'task-build, task-lint',
|
|
4118
4209
|
onChange: (e) => setFormDependsOn(e.target.value)
|
|
4119
4210
|
}),
|
|
4120
|
-
|
|
4211
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.dependsOnHint'))
|
|
4121
4212
|
),
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4213
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4214
|
+
h('label', null, T_KEY(t, 'form.joinPolicyLabel')),
|
|
4215
|
+
h('select', {
|
|
4125
4216
|
value: formJoinPolicy,
|
|
4126
4217
|
onChange: (e) => setFormJoinPolicy(e.target.value)
|
|
4127
4218
|
},
|
|
4128
|
-
|
|
4129
|
-
|
|
4219
|
+
h('option', { value: 'all_success' }, T_KEY(t, 'form.joinPolicyAll')),
|
|
4220
|
+
h('option', { value: 'any_success' }, T_KEY(t, 'form.joinPolicyAny'))
|
|
4130
4221
|
)
|
|
4131
4222
|
)
|
|
4132
4223
|
),
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4224
|
+
h('div', { className: 'dsh-cron-form-group', style: { marginTop: '8px' } },
|
|
4225
|
+
h('label', null, T_KEY(t, 'form.elseTaskLabel')),
|
|
4226
|
+
h('input', {
|
|
4227
|
+
type: 'text',
|
|
4228
|
+
value: formElseTask || '',
|
|
4229
|
+
placeholder: T_KEY(t, 'form.elseTaskPlaceholder'),
|
|
4230
|
+
onChange: (e) => setFormElseTask(e.target.value)
|
|
4231
|
+
}),
|
|
4232
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.elseTaskHint'))
|
|
4233
|
+
),
|
|
4234
|
+
h('div', { className: 'dsh-cron-form-group', style: { marginTop: '8px' } },
|
|
4235
|
+
h('label', { style: { display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' } },
|
|
4236
|
+
h('input', {
|
|
4237
|
+
type: 'checkbox',
|
|
4238
|
+
checked: Boolean(formAutoHeal),
|
|
4239
|
+
onChange: (e) => setFormAutoHeal(e.target.checked)
|
|
4240
|
+
}),
|
|
4241
|
+
h('span', { style: { fontWeight: '600' } }, '🩺 ' + T_KEY(t, 'form.autoHealLabel'))
|
|
4242
|
+
),
|
|
4243
|
+
h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'form.autoHealHint'))
|
|
4244
|
+
),
|
|
4245
|
+
h('div', { style: { marginTop: '12px', padding: '10px', background: 'var(--dsw-alias-bg-layer-2)', borderRadius: '6px' } },
|
|
4246
|
+
h('label', { style: { display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer', fontWeight: '500' } },
|
|
4247
|
+
h('input', {
|
|
4136
4248
|
type: 'checkbox',
|
|
4137
4249
|
checked: formAdaptiveEnabled,
|
|
4138
4250
|
onChange: (e) => setFormAdaptiveEnabled(e.target.checked)
|
|
4139
4251
|
}),
|
|
4140
4252
|
T_KEY(t, 'form.adaptiveEnabled')
|
|
4141
4253
|
),
|
|
4142
|
-
|
|
4143
|
-
formAdaptiveEnabled &&
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4254
|
+
h('div', { className: 'dsh-cron-hint', style: { marginLeft: '24px' } }, T_KEY(t, 'form.adaptiveHint')),
|
|
4255
|
+
formAdaptiveEnabled && h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: '8px', marginTop: '8px', marginLeft: '24px' } },
|
|
4256
|
+
h('div', null,
|
|
4257
|
+
h('label', { style: { fontSize: '11px' } }, 'Min'),
|
|
4258
|
+
h('input', { type: 'text', value: formAdaptiveMinInterval, placeholder: '5m', onChange: (e) => setFormAdaptiveMinInterval(e.target.value) })
|
|
4147
4259
|
),
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4260
|
+
h('div', null,
|
|
4261
|
+
h('label', { style: { fontSize: '11px' } }, 'Max'),
|
|
4262
|
+
h('input', { type: 'text', value: formAdaptiveMaxInterval, placeholder: '2h', onChange: (e) => setFormAdaptiveMaxInterval(e.target.value) })
|
|
4151
4263
|
),
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4264
|
+
h('div', null,
|
|
4265
|
+
h('label', { style: { fontSize: '11px' } }, 'Factor'),
|
|
4266
|
+
h('input', { type: 'number', step: '0.1', value: formAdaptiveBackoffFactor, placeholder: '1.5', onChange: (e) => setFormAdaptiveBackoffFactor(e.target.value) })
|
|
4155
4267
|
),
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4268
|
+
h('div', null,
|
|
4269
|
+
h('label', { style: { fontSize: '11px' } }, 'Idle Runs'),
|
|
4270
|
+
h('input', { type: 'number', value: formAdaptiveIdleThreshold, placeholder: '3', onChange: (e) => setFormAdaptiveIdleThreshold(e.target.value) })
|
|
4159
4271
|
)
|
|
4160
4272
|
)
|
|
4161
4273
|
)
|
|
4162
4274
|
),
|
|
4163
|
-
selectedTaskMeta &&
|
|
4275
|
+
selectedTaskMeta && h('div', {
|
|
4164
4276
|
style: {
|
|
4165
4277
|
background: 'var(--dsw-alias-bg-layer-3, color-mix(in srgb, var(--dsw-alias-label-primary) 3%, transparent))',
|
|
4166
4278
|
border: '1px solid var(--dsw-alias-border-l2)',
|
|
@@ -4174,11 +4286,11 @@ justifyContent: 'space-between',
|
|
|
4174
4286
|
alignItems: 'center'
|
|
4175
4287
|
}
|
|
4176
4288
|
},
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4289
|
+
h('div', null,
|
|
4290
|
+
h('span', null, T_KEY(t, 'form.nextRunLabel')),
|
|
4291
|
+
h('strong', { style: { color: 'var(--dsw-alias-label-primary, #eee)' } }, selectedTaskMeta.nextRunAt ? new Date(selectedTaskMeta.nextRunAt).toLocaleString() : T_KEY(t, 'form.notScheduled'))
|
|
4180
4292
|
),
|
|
4181
|
-
|
|
4293
|
+
h('button', {
|
|
4182
4294
|
type: 'button',
|
|
4183
4295
|
className: 'dsh-cron-btn-secondary',
|
|
4184
4296
|
style: { padding: '4px 10px', fontSize: '12px' },
|
|
@@ -4188,13 +4300,13 @@ if (formId) loadTaskHistory(formId);
|
|
|
4188
4300
|
}
|
|
4189
4301
|
}, T_KEY(t, 'actions.runNow'))
|
|
4190
4302
|
),
|
|
4191
|
-
|
|
4192
|
-
|
|
4303
|
+
h('div', { className: 'dsh-cron-modal-foot' },
|
|
4304
|
+
h('button', {
|
|
4193
4305
|
type: 'button',
|
|
4194
4306
|
className: 'dsh-cron-btn-secondary',
|
|
4195
4307
|
onClick: closeManualModalWithConfirm
|
|
4196
4308
|
}, T_KEY(t, 'modal.cancel')),
|
|
4197
|
-
|
|
4309
|
+
h('button', {
|
|
4198
4310
|
type: 'submit',
|
|
4199
4311
|
className: 'dsh-cron-btn-primary'
|
|
4200
4312
|
}, formId ? T_KEY(t, 'modal.save') : T_KEY(t, 'modal.create'))
|
|
@@ -4202,28 +4314,28 @@ className: 'dsh-cron-btn-primary'
|
|
|
4202
4314
|
)
|
|
4203
4315
|
)
|
|
4204
4316
|
),
|
|
4205
|
-
dryRunResult &&
|
|
4206
|
-
|
|
4317
|
+
dryRunResult && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => setDryRunResult(null) },
|
|
4318
|
+
h('div', {
|
|
4207
4319
|
className: 'dsh-cron-modal',
|
|
4208
4320
|
style: { maxWidth: '580px' },
|
|
4209
4321
|
role: 'dialog',
|
|
4210
4322
|
'aria-modal': 'true',
|
|
4211
4323
|
onClick: (e) => e.stopPropagation()
|
|
4212
4324
|
},
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4325
|
+
h('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
|
|
4326
|
+
h('div', { className: 'dsh-cron-modal-title', style: { margin: 0 } }, T_KEY(t, 'dryRun.title')),
|
|
4327
|
+
h('button', {
|
|
4216
4328
|
type: 'button',
|
|
4217
4329
|
className: 'dsh-cron-icon-btn',
|
|
4218
4330
|
onClick: () => setDryRunResult(null)
|
|
4219
4331
|
}, '✕')
|
|
4220
4332
|
),
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
((dryRunResult.result && dryRunResult.result.preflight) || dryRunResult.preflight) &&
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4333
|
+
h('div', { style: { marginTop: '12px', display: 'flex', flexDirection: 'column', gap: '8px', fontSize: '13px' } },
|
|
4334
|
+
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')),
|
|
4335
|
+
((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) || '') + ')')),
|
|
4336
|
+
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')),
|
|
4337
|
+
h('div', { style: { marginTop: '6px' } }, h('strong', null, T_KEY(t, 'dryRun.output') + ':')),
|
|
4338
|
+
h('pre', {
|
|
4227
4339
|
style: {
|
|
4228
4340
|
background: 'var(--dsw-alias-bg-layer-2)',
|
|
4229
4341
|
border: '1px solid var(--dsw-alias-border-l2)',
|
|
@@ -4238,8 +4350,8 @@ color: 'var(--dsw-alias-label-primary)'
|
|
|
4238
4350
|
}
|
|
4239
4351
|
}, ((dryRunResult.result && dryRunResult.result.output) !== undefined ? dryRunResult.result.output : (dryRunResult.output !== undefined ? dryRunResult.output : ((dryRunResult.result && dryRunResult.result.error) || dryRunResult.error || '(no output)'))))
|
|
4240
4352
|
),
|
|
4241
|
-
|
|
4242
|
-
|
|
4353
|
+
h('div', { className: 'dsh-cron-modal-foot', style: { marginTop: '16px' } },
|
|
4354
|
+
h('button', {
|
|
4243
4355
|
type: 'button',
|
|
4244
4356
|
className: 'dsh-cron-btn-primary',
|
|
4245
4357
|
onClick: () => setDryRunResult(null)
|
|
@@ -4247,29 +4359,29 @@ onClick: () => setDryRunResult(null)
|
|
|
4247
4359
|
)
|
|
4248
4360
|
)
|
|
4249
4361
|
),
|
|
4250
|
-
archiveModalOpen &&
|
|
4251
|
-
|
|
4362
|
+
archiveModalOpen && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => setArchiveModalOpen(false) },
|
|
4363
|
+
h('div', {
|
|
4252
4364
|
className: 'dsh-cron-modal',
|
|
4253
4365
|
style: { maxWidth: '700px' },
|
|
4254
4366
|
role: 'dialog',
|
|
4255
4367
|
'aria-modal': 'true',
|
|
4256
4368
|
onClick: (e) => e.stopPropagation()
|
|
4257
4369
|
},
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4370
|
+
h('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
|
|
4371
|
+
h('div', { className: 'dsh-cron-modal-title', style: { margin: 0 } }, T_KEY(t, 'archive.title') + (archiveTask ? ' - ' + archiveTask.title : '')),
|
|
4372
|
+
h('button', {
|
|
4261
4373
|
type: 'button',
|
|
4262
4374
|
className: 'dsh-cron-icon-btn',
|
|
4263
4375
|
onClick: () => setArchiveModalOpen(false)
|
|
4264
4376
|
}, '✕')
|
|
4265
4377
|
),
|
|
4266
|
-
|
|
4378
|
+
h('div', { style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #999)', margin: '4px 0 12px 0' } },
|
|
4267
4379
|
T_KEY(t, 'archive.totalRuns', { total: archiveTotal })
|
|
4268
4380
|
),
|
|
4269
|
-
archiveLoading ?
|
|
4270
|
-
archiveRuns.length === 0 ?
|
|
4271
|
-
|
|
4272
|
-
archiveRuns.map((r, idx) =>
|
|
4381
|
+
archiveLoading ? h('div', { className: 'dsh-cron-history-empty' }, T_KEY(t, 'history.loading')) :
|
|
4382
|
+
archiveRuns.length === 0 ? h('div', { className: 'dsh-cron-history-empty' }, T_KEY(t, 'archive.empty')) :
|
|
4383
|
+
h('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px', maxHeight: '380px', overflowY: 'auto' } },
|
|
4384
|
+
archiveRuns.map((r, idx) => h('div', {
|
|
4273
4385
|
key: idx,
|
|
4274
4386
|
style: {
|
|
4275
4387
|
background: 'var(--dsw-alias-bg-layer-2)',
|
|
@@ -4279,21 +4391,21 @@ padding: '8px 12px',
|
|
|
4279
4391
|
fontSize: '12px'
|
|
4280
4392
|
}
|
|
4281
4393
|
},
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4394
|
+
h('div', { style: { display: 'flex', justifyContent: 'space-between', marginBottom: '4px' } },
|
|
4395
|
+
h('span', { style: { fontWeight: '600', color: r.status === 'success' ? 'var(--dsh-cron-success)' : 'var(--dsh-cron-danger)' } }, (r.status || 'unknown').toUpperCase()),
|
|
4396
|
+
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
4397
|
),
|
|
4286
|
-
r.durationMs > 0 &&
|
|
4287
|
-
r.chainRunId &&
|
|
4288
|
-
|
|
4398
|
+
r.durationMs > 0 && h('div', { style: { color: 'var(--dsw-alias-label-secondary, #888)', marginBottom: '4px' } }, 'Duration: ' + r.durationMs + 'ms'),
|
|
4399
|
+
r.chainRunId && h('div', { style: { marginBottom: '4px' } },
|
|
4400
|
+
h('button', {
|
|
4289
4401
|
type: 'button',
|
|
4290
4402
|
className: 'dsh-cron-btn-secondary',
|
|
4291
4403
|
style: { padding: '2px 8px', fontSize: '11px', display: 'inline-flex', alignItems: 'center', gap: '4px' },
|
|
4292
4404
|
onClick: () => openChainGraphModal(null, r.chainRunId)
|
|
4293
4405
|
}, '🕸️ ' + T_KEY(t, 'chainGraph.viewGraph'))
|
|
4294
4406
|
),
|
|
4295
|
-
r.error &&
|
|
4296
|
-
r.output &&
|
|
4407
|
+
r.error && h('div', { style: { color: 'var(--dsh-cron-danger)', marginBottom: '4px' } }, 'Error: ' + r.error),
|
|
4408
|
+
r.output && h('div', {
|
|
4297
4409
|
style: {
|
|
4298
4410
|
color: 'var(--dsw-alias-label-primary, #ccc)',
|
|
4299
4411
|
whiteSpace: 'pre-wrap',
|
|
@@ -4304,16 +4416,16 @@ overflowY: 'auto'
|
|
|
4304
4416
|
}, r.output.slice(0, 300) + (r.output.length > 300 ? '...' : ''))
|
|
4305
4417
|
))
|
|
4306
4418
|
),
|
|
4307
|
-
|
|
4308
|
-
archiveRuns.length < archiveTotal ?
|
|
4419
|
+
h('div', { className: 'dsh-cron-modal-foot', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: '16px' } },
|
|
4420
|
+
archiveRuns.length < archiveTotal ? h('button', {
|
|
4309
4421
|
type: 'button',
|
|
4310
4422
|
className: 'dsh-cron-btn-secondary',
|
|
4311
4423
|
onClick: () => {
|
|
4312
4424
|
const nextOffset = archiveRuns.length;
|
|
4313
4425
|
if (archiveTask) openArchiveModal(archiveTask, nextOffset);
|
|
4314
4426
|
}
|
|
4315
|
-
}, T_KEY(t, 'archive.loadMore', { shown: archiveRuns.length, total: archiveTotal })) :
|
|
4316
|
-
|
|
4427
|
+
}, T_KEY(t, 'archive.loadMore', { shown: archiveRuns.length, total: archiveTotal })) : h('div', null),
|
|
4428
|
+
h('button', {
|
|
4317
4429
|
type: 'button',
|
|
4318
4430
|
className: 'dsh-cron-btn-primary',
|
|
4319
4431
|
onClick: () => setArchiveModalOpen(false)
|
|
@@ -4321,54 +4433,54 @@ onClick: () => setArchiveModalOpen(false)
|
|
|
4321
4433
|
)
|
|
4322
4434
|
)
|
|
4323
4435
|
),
|
|
4324
|
-
settingsModalOpen &&
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4436
|
+
settingsModalOpen && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => setSettingsModalOpen(false) },
|
|
4437
|
+
h('div', { className: 'dsh-cron-modal dsh-cron-modal-scroll', role: 'dialog', 'aria-modal': 'true', onClick: (e) => e.stopPropagation() },
|
|
4438
|
+
h('div', { className: 'dsh-cron-modal-head', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '18px' } },
|
|
4439
|
+
h('div', { className: 'dsh-cron-modal-title', style: { margin: 0, display: 'flex', alignItems: 'center', gap: '8px' } },
|
|
4440
|
+
h('span', { style: { display: 'flex', alignItems: 'center', color: 'var(--dsh-cron-info)' }, ...iconHtml(ICON_TELEGRAM) }),
|
|
4329
4441
|
T_KEY(t, 'settings.modalTitle')
|
|
4330
4442
|
),
|
|
4331
|
-
|
|
4443
|
+
h('button', {
|
|
4332
4444
|
type: 'button',
|
|
4333
4445
|
style: { background: 'none', border: 'none', color: 'var(--dsw-alias-label-tertiary, #888)', cursor: 'pointer', fontSize: '18px' },
|
|
4334
4446
|
onClick: () => setSettingsModalOpen(false)
|
|
4335
4447
|
}, '✕')
|
|
4336
4448
|
),
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4449
|
+
h('form', { onSubmit: handleSaveSettings },
|
|
4450
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4451
|
+
h('label', null, T_KEY(t, 'settings.tokenLabel')),
|
|
4452
|
+
h('input', {
|
|
4341
4453
|
type: 'password',
|
|
4342
4454
|
value: settingsBotToken,
|
|
4343
4455
|
placeholder: settingsHasDefault ? T_KEY(t, 'settings.tokenPlaceholderDefault') : T_KEY(t, 'settings.tokenPlaceholder'),
|
|
4344
4456
|
onChange: (e) => setSettingsBotToken(e.target.value)
|
|
4345
4457
|
}),
|
|
4346
|
-
settingsHasDefault &&
|
|
4458
|
+
settingsHasDefault && h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'settings.defaultHint'))
|
|
4347
4459
|
),
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4460
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4461
|
+
h('label', null, T_KEY(t, 'settings.chatIdLabel')),
|
|
4462
|
+
h('input', {
|
|
4351
4463
|
value: settingsChatId,
|
|
4352
4464
|
placeholder: T_KEY(t, 'settings.chatIdPlaceholder'),
|
|
4353
4465
|
onChange: (e) => setSettingsChatId(e.target.value)
|
|
4354
4466
|
})
|
|
4355
4467
|
),
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4468
|
+
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' } },
|
|
4469
|
+
h('label', { className: 'dsh-cron-checkbox-row', style: { marginBottom: '8px' } },
|
|
4470
|
+
h('input', {
|
|
4359
4471
|
type: 'checkbox',
|
|
4360
4472
|
checked: settingsNotifyGlobal,
|
|
4361
4473
|
onChange: (e) => setSettingsNotifyGlobal(e.target.checked)
|
|
4362
4474
|
}),
|
|
4363
|
-
|
|
4475
|
+
h('span', null, T_KEY(t, 'settings.globalNotify'))
|
|
4364
4476
|
),
|
|
4365
|
-
|
|
4366
|
-
|
|
4477
|
+
h('label', { className: 'dsh-cron-checkbox-row' },
|
|
4478
|
+
h('input', {
|
|
4367
4479
|
type: 'checkbox',
|
|
4368
4480
|
checked: settingsOnlyOnFailureGlobal,
|
|
4369
4481
|
onChange: (e) => setSettingsOnlyOnFailureGlobal(e.target.checked)
|
|
4370
4482
|
}),
|
|
4371
|
-
|
|
4483
|
+
h('span', null, T_KEY(t, 'settings.globalOnlyFailure'))
|
|
4372
4484
|
)
|
|
4373
4485
|
),
|
|
4374
4486
|
...renderDeliverySettings({
|
|
@@ -4379,8 +4491,8 @@ onChannelTemplate: updateChannelTemplate,
|
|
|
4379
4491
|
sections: settingsSections,
|
|
4380
4492
|
onToggleSection: toggleDeliverySection,
|
|
4381
4493
|
}),
|
|
4382
|
-
|
|
4383
|
-
|
|
4494
|
+
h('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '14px' } },
|
|
4495
|
+
h('button', {
|
|
4384
4496
|
type: 'button',
|
|
4385
4497
|
className: 'dsh-cron-btn-secondary',
|
|
4386
4498
|
style: { display: 'inline-flex', alignItems: 'center', gap: '6px' },
|
|
@@ -4388,17 +4500,17 @@ disabled: testStatus?.loading,
|
|
|
4388
4500
|
onClick: handleTestTelegram
|
|
4389
4501
|
}, testStatus?.loading ? T_KEY(t, 'settings.sending') : T_KEY(t, 'settings.testTelegram'))
|
|
4390
4502
|
),
|
|
4391
|
-
testStatus && testStatus.message &&
|
|
4503
|
+
testStatus && testStatus.message && h('div', {
|
|
4392
4504
|
className: 'dsh-cron-status-banner',
|
|
4393
4505
|
'data-type': testStatus.success ? 'success' : 'error'
|
|
4394
4506
|
}, testStatus.message),
|
|
4395
|
-
|
|
4396
|
-
|
|
4507
|
+
h('div', { className: 'dsh-cron-modal-foot' },
|
|
4508
|
+
h('button', {
|
|
4397
4509
|
type: 'button',
|
|
4398
4510
|
className: 'dsh-cron-btn-secondary',
|
|
4399
4511
|
onClick: () => setSettingsModalOpen(false)
|
|
4400
4512
|
}, T_KEY(t, 'modal.cancel')),
|
|
4401
|
-
|
|
4513
|
+
h('button', {
|
|
4402
4514
|
type: 'submit',
|
|
4403
4515
|
className: 'dsh-cron-btn-primary'
|
|
4404
4516
|
}, T_KEY(t, 'settings.save'))
|
|
@@ -4406,12 +4518,12 @@ className: 'dsh-cron-btn-primary'
|
|
|
4406
4518
|
)
|
|
4407
4519
|
)
|
|
4408
4520
|
),
|
|
4409
|
-
importDoc &&
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
importSummary &&
|
|
4414
|
-
|
|
4521
|
+
importDoc && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => !transferBusy && setImportDoc(null) },
|
|
4522
|
+
h('div', { className: 'dsh-cron-modal', role: 'dialog', 'aria-modal': 'true', onClick: (e) => e.stopPropagation() },
|
|
4523
|
+
h('div', { className: 'dsh-cron-modal-title' }, T_KEY(t, 'transfer.importTitleModal')),
|
|
4524
|
+
h('div', { className: 'dsh-cron-hint', style: { marginBottom: '10px' } }, T_KEY(t, 'transfer.importHint')),
|
|
4525
|
+
importSummary && h('div', null,
|
|
4526
|
+
h('div', { style: { fontSize: '13px', marginBottom: '12px' } },
|
|
4415
4527
|
T_KEY(t, 'transfer.summary', {
|
|
4416
4528
|
total: (importSummary.add || 0) + (importSummary.replace || 0) + (importSummary.skip || 0),
|
|
4417
4529
|
add: importSummary.add || 0,
|
|
@@ -4419,26 +4531,26 @@ replace: importSummary.replace || 0,
|
|
|
4419
4531
|
skip: importSummary.skip || 0
|
|
4420
4532
|
})
|
|
4421
4533
|
),
|
|
4422
|
-
|
|
4423
|
-
...['add', 'replace', 'skip'].map((mode) =>
|
|
4424
|
-
|
|
4534
|
+
h('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px', marginBottom: '14px' } },
|
|
4535
|
+
...['add', 'replace', 'skip'].map((mode) => h('label', { key: mode, className: 'dsh-cron-checkbox-row' },
|
|
4536
|
+
h('input', {
|
|
4425
4537
|
type: 'radio',
|
|
4426
4538
|
name: 'dsh-cron-import-strategy',
|
|
4427
4539
|
checked: importStrategy === mode,
|
|
4428
4540
|
onChange: () => setImportStrategy(mode)
|
|
4429
4541
|
}),
|
|
4430
|
-
|
|
4542
|
+
h('span', null, T_KEY(t, mode === 'add' ? 'transfer.strategyAdd' : mode === 'replace' ? 'transfer.strategyReplace' : 'transfer.strategySkip'))
|
|
4431
4543
|
))
|
|
4432
4544
|
)
|
|
4433
4545
|
),
|
|
4434
|
-
|
|
4435
|
-
|
|
4546
|
+
h('div', { className: 'dsh-cron-modal-foot' },
|
|
4547
|
+
h('button', {
|
|
4436
4548
|
type: 'button',
|
|
4437
4549
|
className: 'dsh-cron-btn-secondary',
|
|
4438
4550
|
disabled: transferBusy,
|
|
4439
4551
|
onClick: () => setImportDoc(null)
|
|
4440
4552
|
}, T_KEY(t, 'modal.cancel')),
|
|
4441
|
-
|
|
4553
|
+
h('button', {
|
|
4442
4554
|
type: 'button',
|
|
4443
4555
|
className: 'dsh-cron-btn-primary',
|
|
4444
4556
|
disabled: transferBusy || !importSummary,
|
|
@@ -4447,13 +4559,13 @@ onClick: handleImportConfirm
|
|
|
4447
4559
|
)
|
|
4448
4560
|
)
|
|
4449
4561
|
),
|
|
4450
|
-
dshModalOpen &&
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4562
|
+
dshModalOpen && h('div', { className: 'dsh-cron-modal-overlay', onClick: () => !dshLoading && setDshModalOpen(false) },
|
|
4563
|
+
h('div', { className: 'dsh-cron-modal', role: 'dialog', 'aria-modal': 'true', onClick: (e) => e.stopPropagation() },
|
|
4564
|
+
h('div', { className: 'dsh-cron-modal-title' }, T_KEY(t, 'dsh.modalTitle')),
|
|
4565
|
+
h('div', { className: 'dsh-cron-form-group' },
|
|
4566
|
+
h('label', null, T_KEY(t, 'dsh.descLabel')),
|
|
4567
|
+
h('div', { className: 'dsh-cron-chat-box' },
|
|
4568
|
+
h('textarea', {
|
|
4457
4569
|
className: 'dsh-cron-chat-input',
|
|
4458
4570
|
rows: 4,
|
|
4459
4571
|
autoFocus: true,
|
|
@@ -4468,22 +4580,22 @@ handleStartWithDSH();
|
|
|
4468
4580
|
},
|
|
4469
4581
|
onChange: (e) => setDshPrompt(e.target.value)
|
|
4470
4582
|
}),
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4583
|
+
h('div', { className: 'dsh-cron-chat-foot' },
|
|
4584
|
+
h('span', { className: 'dsh-cron-chat-hint' }, T_KEY(t, 'dsh.sendHint')),
|
|
4585
|
+
h('button', {
|
|
4474
4586
|
type: 'button',
|
|
4475
4587
|
className: 'dsh-cron-send-btn',
|
|
4476
4588
|
disabled: dshLoading || !dshPrompt.trim(),
|
|
4477
4589
|
title: T_KEY(t, 'dsh.sendTitle'),
|
|
4478
4590
|
onClick: handleStartWithDSH
|
|
4479
4591
|
},
|
|
4480
|
-
|
|
4592
|
+
h('span', svgProps(ICON_SEND))
|
|
4481
4593
|
)
|
|
4482
4594
|
)
|
|
4483
4595
|
)
|
|
4484
4596
|
),
|
|
4485
|
-
|
|
4486
|
-
|
|
4597
|
+
h('div', { className: 'dsh-cron-modal-foot' },
|
|
4598
|
+
h('button', {
|
|
4487
4599
|
type: 'button',
|
|
4488
4600
|
className: 'dsh-cron-btn-secondary',
|
|
4489
4601
|
disabled: dshLoading,
|
|
@@ -4694,15 +4806,15 @@ setTestInfo({ success: false, message: T_KEY(t, 'settings.kanbanFail', { error:
|
|
|
4694
4806
|
}
|
|
4695
4807
|
};
|
|
4696
4808
|
if (loadState !== 'ready') {
|
|
4697
|
-
return
|
|
4698
|
-
|
|
4699
|
-
|
|
4809
|
+
return h('div', { className: 'dsh-cron-card' },
|
|
4810
|
+
h('div', { className: 'dsh-cron-card-title' }, T_KEY(t, 'settings.cardTitle')),
|
|
4811
|
+
h('div', {
|
|
4700
4812
|
className: 'dsh-cron-status-banner',
|
|
4701
4813
|
'data-type': loadState === 'error' ? 'error' : 'info',
|
|
4702
4814
|
style: { marginTop: '10px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: '10px' }
|
|
4703
4815
|
},
|
|
4704
|
-
|
|
4705
|
-
loadState === 'error' &&
|
|
4816
|
+
h('span', null, loadState === 'error' ? T_KEY(t, 'settings.unavailable') : T_KEY(t, 'settings.loading')),
|
|
4817
|
+
loadState === 'error' && h('button', {
|
|
4706
4818
|
type: 'button',
|
|
4707
4819
|
className: 'dsh-cron-btn-secondary',
|
|
4708
4820
|
onClick: () => setReloadTick(x => x + 1)
|
|
@@ -4711,88 +4823,88 @@ onClick: () => setReloadTick(x => x + 1)
|
|
|
4711
4823
|
);
|
|
4712
4824
|
}
|
|
4713
4825
|
if (props && props.view === 'summary') {
|
|
4714
|
-
return
|
|
4826
|
+
return h('span', { className: 'dsh-cron-card-desc' }, T_KEY(t, 'settings.cardDesc'));
|
|
4715
4827
|
}
|
|
4716
4828
|
const page = !!(props && props.view === 'page');
|
|
4717
|
-
return
|
|
4718
|
-
|
|
4829
|
+
return h('div', { className: page ? 'dsh-cron-page' : 'dsh-cron-card' },
|
|
4830
|
+
h('button', {
|
|
4719
4831
|
type: 'button',
|
|
4720
4832
|
className: 'dsh-cron-card-head-btn',
|
|
4721
4833
|
style: page ? { display: 'none' } : undefined,
|
|
4722
4834
|
'aria-expanded': (page || cardOpen) ? 'true' : 'false',
|
|
4723
4835
|
onClick: () => setCardOpen(!cardOpen)
|
|
4724
4836
|
},
|
|
4725
|
-
|
|
4726
|
-
|
|
4837
|
+
h('span', { className: 'dsh-cron-card-title' }, T_KEY(t, 'settings.cardTitle')),
|
|
4838
|
+
h('span', { className: 'dsh-cron-chev' + (cardOpen ? ' dsh-cron-chev-open' : '') }, chevronNode())
|
|
4727
4839
|
),
|
|
4728
|
-
(page || cardOpen) &&
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4840
|
+
(page || cardOpen) && h('div', { className: 'dsh-cron-card-body' },
|
|
4841
|
+
h('div', { className: 'dsh-cron-card-desc' }, T_KEY(t, 'settings.cardDesc')),
|
|
4842
|
+
h('div', { style: { display: 'flex', justifyContent: 'flex-end', marginBottom: '12px' } },
|
|
4843
|
+
h('button', {
|
|
4732
4844
|
type: 'button',
|
|
4733
4845
|
className: 'dsh-cron-btn-primary',
|
|
4734
4846
|
onClick: () => { if (toggle) toggle.set(true); }
|
|
4735
4847
|
}, T_KEY(t, 'settings.openPanel'))
|
|
4736
4848
|
),
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4849
|
+
h('form', { onSubmit: saveSettings, style: { display: 'flex', flexDirection: 'column', gap: '12px' } },
|
|
4850
|
+
h('div', { className: 'dsh-cron-form-group', style: { marginBottom: 0 } },
|
|
4851
|
+
h('label', null, T_KEY(t, 'settings.tokenLabel')),
|
|
4852
|
+
h('input', {
|
|
4741
4853
|
type: 'password',
|
|
4742
4854
|
value: token,
|
|
4743
4855
|
placeholder: hasDefault ? T_KEY(t, 'settings.tokenPlaceholderDefault') : T_KEY(t, 'settings.tokenPlaceholder'),
|
|
4744
4856
|
onChange: (e) => setToken(e.target.value)
|
|
4745
4857
|
}),
|
|
4746
|
-
hasDefault &&
|
|
4858
|
+
hasDefault && h('div', { className: 'dsh-cron-hint' }, T_KEY(t, 'settings.defaultHint'))
|
|
4747
4859
|
),
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4860
|
+
h('div', { className: 'dsh-cron-form-group', style: { marginBottom: 0 } },
|
|
4861
|
+
h('label', null, T_KEY(t, 'settings.chatIdLabel')),
|
|
4862
|
+
h('input', {
|
|
4751
4863
|
value: chatId,
|
|
4752
4864
|
placeholder: T_KEY(t, 'settings.chatIdPlaceholder'),
|
|
4753
4865
|
onChange: (e) => setChatId(e.target.value)
|
|
4754
4866
|
})
|
|
4755
4867
|
),
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4868
|
+
h('div', { className: 'dsh-cron-form-group', style: { marginBottom: 0 } },
|
|
4869
|
+
h('label', null, T_KEY(t, 'settings.kanbanUrlLabel')),
|
|
4870
|
+
h('input', {
|
|
4759
4871
|
value: kanbanUrl,
|
|
4760
4872
|
placeholder: 'http://127.0.0.1:3000',
|
|
4761
4873
|
onChange: (e) => setKanbanUrl(e.target.value)
|
|
4762
4874
|
})
|
|
4763
4875
|
),
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4876
|
+
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' } },
|
|
4877
|
+
h('label', { className: 'dsh-cron-checkbox-row' },
|
|
4878
|
+
h('input', {
|
|
4767
4879
|
type: 'checkbox',
|
|
4768
4880
|
checked: notify,
|
|
4769
4881
|
onChange: (e) => setNotify(e.target.checked)
|
|
4770
4882
|
}),
|
|
4771
|
-
|
|
4883
|
+
h('span', null, T_KEY(t, 'settings.globalNotify'))
|
|
4772
4884
|
),
|
|
4773
|
-
|
|
4774
|
-
|
|
4885
|
+
h('label', { className: 'dsh-cron-checkbox-row' },
|
|
4886
|
+
h('input', {
|
|
4775
4887
|
type: 'checkbox',
|
|
4776
4888
|
checked: onlyFailure,
|
|
4777
4889
|
onChange: (e) => setOnlyFailure(e.target.checked)
|
|
4778
4890
|
}),
|
|
4779
|
-
|
|
4891
|
+
h('span', null, T_KEY(t, 'settings.globalOnlyFailure'))
|
|
4780
4892
|
),
|
|
4781
|
-
|
|
4782
|
-
|
|
4893
|
+
h('label', { className: 'dsh-cron-checkbox-row' },
|
|
4894
|
+
h('input', {
|
|
4783
4895
|
type: 'checkbox',
|
|
4784
4896
|
checked: llmActionsEnabled,
|
|
4785
4897
|
onChange: (e) => setLlmActionsEnabled(e.target.checked)
|
|
4786
4898
|
}),
|
|
4787
|
-
|
|
4899
|
+
h('span', null, 'Enable Structured LLM Actions (trigger tasks, notify, create issues)')
|
|
4788
4900
|
),
|
|
4789
|
-
|
|
4790
|
-
|
|
4901
|
+
h('label', { className: 'dsh-cron-checkbox-row' },
|
|
4902
|
+
h('input', {
|
|
4791
4903
|
type: 'checkbox',
|
|
4792
4904
|
checked: enableDynamicCredentials,
|
|
4793
4905
|
onChange: (e) => setEnableDynamicCredentials(e.target.checked)
|
|
4794
4906
|
}),
|
|
4795
|
-
|
|
4907
|
+
h('span', null, T_KEY(t, 'settings.dynamicCredentials'))
|
|
4796
4908
|
)
|
|
4797
4909
|
),
|
|
4798
4910
|
...renderDeliverySettings({
|
|
@@ -4813,12 +4925,12 @@ return Object.assign({}, prev, { channelTemplates: templates });
|
|
|
4813
4925
|
sections,
|
|
4814
4926
|
onToggleSection: (key) => setSections((prev) => Object.assign({}, prev, { [key]: !prev[key] })),
|
|
4815
4927
|
}),
|
|
4816
|
-
testInfo && testInfo.message &&
|
|
4928
|
+
testInfo && testInfo.message && h('div', {
|
|
4817
4929
|
className: 'dsh-cron-status-banner',
|
|
4818
4930
|
'data-type': testInfo.success ? 'success' : 'error',
|
|
4819
4931
|
style: { margin: 0, padding: '8px 12px' }
|
|
4820
4932
|
}, testInfo.message),
|
|
4821
|
-
|
|
4933
|
+
h('div', {
|
|
4822
4934
|
className: 'dsh-cron-form-group',
|
|
4823
4935
|
style: {
|
|
4824
4936
|
background: 'var(--dsw-alias-bg-layer-2, color-mix(in srgb, var(--dsw-alias-label-primary) 3%, transparent))',
|
|
@@ -4828,19 +4940,19 @@ padding: '14px',
|
|
|
4828
4940
|
marginBottom: '16px'
|
|
4829
4941
|
}
|
|
4830
4942
|
},
|
|
4831
|
-
|
|
4943
|
+
h('div', {
|
|
4832
4944
|
style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px' }
|
|
4833
4945
|
},
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4946
|
+
h('div', { style: { fontWeight: '600', fontSize: '14px' } }, `🚀 ${T_KEY(t, 'updater.title')}`),
|
|
4947
|
+
h('div', { style: { display: 'flex', gap: '8px' } },
|
|
4948
|
+
h('button', {
|
|
4837
4949
|
type: 'button',
|
|
4838
4950
|
className: 'dsh-cron-btn-secondary',
|
|
4839
4951
|
style: { padding: '4px 10px', fontSize: '12px' },
|
|
4840
4952
|
disabled: updateState.checking || updateState.updating,
|
|
4841
4953
|
onClick: checkUpdates
|
|
4842
4954
|
}, updateState.checking ? T_KEY(t, 'updater.checking') : T_KEY(t, 'updater.btnCheck')),
|
|
4843
|
-
updateState.updateAvailable ?
|
|
4955
|
+
updateState.updateAvailable ? h('button', {
|
|
4844
4956
|
type: 'button',
|
|
4845
4957
|
className: 'dsh-cron-btn-primary',
|
|
4846
4958
|
style: { padding: '4px 10px', fontSize: '12px' },
|
|
@@ -4849,39 +4961,39 @@ onClick: runUpdate
|
|
|
4849
4961
|
}, updateState.updating ? T_KEY(t, 'updater.updating') : T_KEY(t, 'updater.btnUpdate', { version: updateState.latestVersion })) : null
|
|
4850
4962
|
)
|
|
4851
4963
|
),
|
|
4852
|
-
|
|
4964
|
+
h('div', {
|
|
4853
4965
|
style: { fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #999)', marginBottom: '8px' }
|
|
4854
4966
|
}, T_KEY(t, 'updater.desc')),
|
|
4855
|
-
|
|
4967
|
+
h('div', {
|
|
4856
4968
|
style: { display: 'flex', alignItems: 'center', gap: '12px', fontSize: '13px' }
|
|
4857
4969
|
},
|
|
4858
|
-
|
|
4970
|
+
h('span', { style: { color: 'var(--dsw-alias-label-secondary, #aaa)' } },
|
|
4859
4971
|
updateState.currentVersion ? T_KEY(t, 'updater.current', { version: updateState.currentVersion }) : ''
|
|
4860
4972
|
),
|
|
4861
|
-
updateState.checking ?
|
|
4862
|
-
updateState.updateAvailable ?
|
|
4863
|
-
updateState.currentVersion && !updateState.error && !updateState.checking ?
|
|
4973
|
+
updateState.checking ? h('span', { className: 'dsh-cron-badge dsh-cron-badge-info' }, T_KEY(t, 'updater.checking')) :
|
|
4974
|
+
updateState.updateAvailable ? h('span', { className: 'dsh-cron-badge dsh-cron-badge-warn' }, T_KEY(t, 'updater.available', { version: updateState.latestVersion })) :
|
|
4975
|
+
updateState.currentVersion && !updateState.error && !updateState.checking ? h('span', { className: 'dsh-cron-badge dsh-cron-badge-ok' }, `✓ ${T_KEY(t, 'updater.upToDate')}`) : null
|
|
4864
4976
|
),
|
|
4865
|
-
updateState.notice ?
|
|
4977
|
+
updateState.notice ? h('div', {
|
|
4866
4978
|
style: { marginTop: '8px', color: 'var(--dsw-alias-success)', fontSize: '12px' }
|
|
4867
4979
|
}, updateState.notice) : null,
|
|
4868
|
-
updateState.error ?
|
|
4980
|
+
updateState.error ? h('div', {
|
|
4869
4981
|
style: { marginTop: '8px', color: 'var(--dsw-alias-error)', fontSize: '12px' }
|
|
4870
4982
|
}, updateState.error) : null
|
|
4871
4983
|
),
|
|
4872
|
-
|
|
4873
|
-
|
|
4984
|
+
h('div', { style: { display: 'flex', gap: '8px', alignItems: 'center', flexWrap: 'wrap', marginTop: '4px' } },
|
|
4985
|
+
h('button', {
|
|
4874
4986
|
type: 'submit',
|
|
4875
4987
|
className: 'dsh-cron-btn-primary',
|
|
4876
4988
|
style: { minWidth: '140px' }
|
|
4877
4989
|
}, saved ? T_KEY(t, 'settings.saved') : T_KEY(t, 'settings.save')),
|
|
4878
|
-
|
|
4990
|
+
h('button', {
|
|
4879
4991
|
type: 'button',
|
|
4880
4992
|
className: 'dsh-cron-btn-secondary',
|
|
4881
4993
|
onClick: testTelegram,
|
|
4882
4994
|
disabled: testInfo?.loading
|
|
4883
4995
|
}, T_KEY(t, 'settings.testTelegram')),
|
|
4884
|
-
|
|
4996
|
+
h('button', {
|
|
4885
4997
|
type: 'button',
|
|
4886
4998
|
className: 'dsh-cron-btn-secondary',
|
|
4887
4999
|
onClick: testKanban,
|
|
@@ -5106,9 +5218,9 @@ container.setAttribute('data-dsh-plugin', 'dsh-cron');
|
|
|
5106
5218
|
column.appendChild(container);
|
|
5107
5219
|
if (ReactDOM && typeof ReactDOM.createRoot === 'function') {
|
|
5108
5220
|
root = ReactDOM.createRoot(container);
|
|
5109
|
-
root.render(
|
|
5221
|
+
root.render(h(ErrorBoundary, null, h(CronScreen, { ctx, toggle, onClose: () => toggle.set(false), t: translate })));
|
|
5110
5222
|
} else if (ReactDOM && typeof ReactDOM.render === 'function') {
|
|
5111
|
-
ReactDOM.render(
|
|
5223
|
+
ReactDOM.render(h(CronScreen, { ctx, toggle, onClose: () => toggle.set(false), t: translate }), container);
|
|
5112
5224
|
}
|
|
5113
5225
|
};
|
|
5114
5226
|
const applyActive = () => {
|
|
@@ -5176,7 +5288,7 @@ translate = ctx.locale.bind(NS);
|
|
|
5176
5288
|
}
|
|
5177
5289
|
const toggle = createToggle();
|
|
5178
5290
|
function SettingsCardWithBoundary(props) {
|
|
5179
|
-
return
|
|
5291
|
+
return h(ErrorBoundary, null, CronSettingsCard(props));
|
|
5180
5292
|
}
|
|
5181
5293
|
const itemOk = registerIntoMount(ctx, 'plugins.item', {
|
|
5182
5294
|
name: 'plugins.item',
|
|
@@ -5215,7 +5327,7 @@ const cardSlot = cardOk ? 'settings.plugin.item' : undefined;
|
|
|
5215
5327
|
const chipSlot = chipOk ? 'conversation.session.header.utilities' : undefined;
|
|
5216
5328
|
function CronChip(props) {
|
|
5217
5329
|
const chipT = props.t || translate;
|
|
5218
|
-
return
|
|
5330
|
+
return h('button', {
|
|
5219
5331
|
type: 'button',
|
|
5220
5332
|
style: { background: 'none', border: 'none', color: 'var(--dsw-alias-label-secondary, #999)', cursor: 'pointer', padding: '4px', display: 'inline-flex', alignItems: 'center' },
|
|
5221
5333
|
title: T_KEY(chipT, 'chip.title'),
|