clay-server 2.27.1 → 2.28.0-beta.1
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/lib/project-loop.js +116 -34
- package/lib/project-user-message.js +5 -3
- package/lib/public/css/scheduler-modal.css +156 -1
- package/lib/public/css/scheduler.css +81 -0
- package/lib/public/index.html +83 -59
- package/lib/public/modules/app-loop-ui.js +85 -2
- package/lib/public/modules/app-messages.js +1 -0
- package/lib/public/modules/scheduler-config.js +241 -162
- package/lib/public/modules/scheduler-history.js +57 -5
- package/lib/public/modules/scheduler.js +80 -36
- package/lib/sdk-bridge.js +40 -14
- package/lib/server-mates.js +7 -2
- package/package.json +1 -1
|
@@ -114,82 +114,103 @@ export function setupCreateModal() {
|
|
|
114
114
|
}
|
|
115
115
|
});
|
|
116
116
|
|
|
117
|
-
//
|
|
118
|
-
document.getElementById("sched-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
dd.classList.toggle("hidden");
|
|
127
|
-
if (wasHidden && btn) {
|
|
128
|
-
var bRect = btn.getBoundingClientRect();
|
|
129
|
-
var ddW = 280;
|
|
130
|
-
var ddLeft = bRect.left;
|
|
131
|
-
if (ddLeft + ddW > window.innerWidth - 10) ddLeft = window.innerWidth - ddW - 10;
|
|
132
|
-
if (ddLeft < 10) ddLeft = 10;
|
|
133
|
-
dd.style.left = ddLeft + "px";
|
|
134
|
-
dd.style.top = (bRect.bottom + 4) + "px";
|
|
117
|
+
// Review checkbox toggle
|
|
118
|
+
var reviewCheck = document.getElementById("sched-review-check");
|
|
119
|
+
if (reviewCheck) {
|
|
120
|
+
reviewCheck.addEventListener("change", function () {
|
|
121
|
+
var countEl = document.getElementById("sched-review-count");
|
|
122
|
+
if (countEl) countEl.classList.toggle("hidden", !this.checked);
|
|
123
|
+
if (!this.checked) {
|
|
124
|
+
var iterInput = document.getElementById("sched-create-iterations");
|
|
125
|
+
if (iterInput) iterInput.value = "1";
|
|
135
126
|
}
|
|
136
|
-
|
|
127
|
+
updateTaskSubtitle();
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Iterations input change updates subtitle
|
|
132
|
+
var iterInputForSub = document.getElementById("sched-create-iterations");
|
|
133
|
+
if (iterInputForSub) {
|
|
134
|
+
iterInputForSub.addEventListener("change", function () { updateTaskSubtitle(); });
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// updateTaskSubtitle is defined at module level (below)
|
|
138
|
+
|
|
139
|
+
// --- Repeat accordion toggle ---
|
|
140
|
+
document.getElementById("sched-accordion-repeat-header").addEventListener("click", function (e) {
|
|
141
|
+
e.stopPropagation();
|
|
142
|
+
var acc = document.getElementById("sched-accordion-repeat");
|
|
143
|
+
var body = document.getElementById("sched-accordion-repeat-body");
|
|
144
|
+
var isOpen = acc.classList.contains("open");
|
|
145
|
+
// Close interval accordion
|
|
146
|
+
document.getElementById("sched-accordion-interval").classList.remove("open");
|
|
147
|
+
document.getElementById("sched-accordion-interval-body").classList.add("hidden");
|
|
148
|
+
acc.classList.toggle("open", !isOpen);
|
|
149
|
+
body.classList.toggle("hidden", isOpen);
|
|
150
|
+
try { lucide.createIcons({ node: acc }); } catch (ex) {}
|
|
137
151
|
});
|
|
138
152
|
|
|
139
|
-
// --- Interval
|
|
140
|
-
|
|
141
|
-
document.getElementById("sched-create-interval-btn").addEventListener("click", function (e) {
|
|
153
|
+
// --- Interval accordion toggle ---
|
|
154
|
+
document.getElementById("sched-accordion-interval-header").addEventListener("click", function (e) {
|
|
142
155
|
e.stopPropagation();
|
|
143
|
-
var
|
|
144
|
-
var
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
intervalSnapshot = {
|
|
153
|
-
interval: createInterval,
|
|
154
|
-
custom: createIntervalCustom ? { value: createIntervalCustom.value, unit: createIntervalCustom.unit } : null,
|
|
155
|
-
end: createIntervalEnd,
|
|
156
|
-
endAfter: createIntervalEndAfter,
|
|
157
|
-
endTime: createIntervalEndTime
|
|
158
|
-
};
|
|
159
|
-
var bRect = btn.getBoundingClientRect();
|
|
160
|
-
var ddW = 220;
|
|
161
|
-
var ddLeft = bRect.left;
|
|
162
|
-
if (ddLeft + ddW > window.innerWidth - 10) ddLeft = window.innerWidth - ddW - 10;
|
|
163
|
-
if (ddLeft < 10) ddLeft = 10;
|
|
164
|
-
dd.style.left = ddLeft + "px";
|
|
165
|
-
dd.style.top = (bRect.bottom + 4) + "px";
|
|
166
|
-
// Auto-apply custom interval when opening
|
|
167
|
-
if (createInterval === "none") {
|
|
168
|
-
applyInlineInterval();
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
156
|
+
var acc = document.getElementById("sched-accordion-interval");
|
|
157
|
+
var body = document.getElementById("sched-accordion-interval-body");
|
|
158
|
+
var isOpen = acc.classList.contains("open");
|
|
159
|
+
// Close repeat accordion
|
|
160
|
+
document.getElementById("sched-accordion-repeat").classList.remove("open");
|
|
161
|
+
document.getElementById("sched-accordion-repeat-body").classList.add("hidden");
|
|
162
|
+
acc.classList.toggle("open", !isOpen);
|
|
163
|
+
body.classList.toggle("hidden", isOpen);
|
|
164
|
+
try { lucide.createIcons({ node: acc }); } catch (ex) {}
|
|
172
165
|
});
|
|
173
166
|
|
|
174
|
-
//
|
|
175
|
-
document.getElementById("sched-
|
|
167
|
+
// --- Clear buttons ---
|
|
168
|
+
document.getElementById("sched-accordion-repeat-clear").addEventListener("click", function (e) {
|
|
176
169
|
e.stopPropagation();
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
170
|
+
createRecurrence = "none";
|
|
171
|
+
createCustomConfirmed = false;
|
|
172
|
+
// Reset controls
|
|
173
|
+
document.getElementById("sched-custom-interval").value = "1";
|
|
174
|
+
document.getElementById("sched-custom-unit").value = "week";
|
|
175
|
+
var dowSection = document.getElementById("sched-custom-dow-section");
|
|
176
|
+
if (dowSection) dowSection.style.display = "";
|
|
177
|
+
var dowBtns = document.querySelectorAll("#sched-custom-dow-row .sched-dow-btn");
|
|
178
|
+
for (var d = 0; d < dowBtns.length; d++) dowBtns[d].classList.remove("active");
|
|
179
|
+
document.getElementById("sched-custom-end").value = "never";
|
|
180
|
+
document.getElementById("sched-custom-end-label").textContent = "Never";
|
|
181
|
+
var dateBtn3 = document.getElementById("sched-custom-end-date-btn");
|
|
182
|
+
if (dateBtn3) dateBtn3.classList.add("hidden");
|
|
183
|
+
var afterWrap3 = document.getElementById("sched-custom-end-after-wrap");
|
|
184
|
+
if (afterWrap3) afterWrap3.classList.add("hidden");
|
|
185
|
+
var calPanel3 = document.getElementById("sched-custom-end-calendar");
|
|
186
|
+
if (calPanel3) calPanel3.classList.add("hidden");
|
|
187
|
+
// Collapse and update
|
|
188
|
+
document.getElementById("sched-accordion-repeat").classList.remove("open");
|
|
189
|
+
document.getElementById("sched-accordion-repeat-body").classList.add("hidden");
|
|
190
|
+
updateRecurrenceBtn();
|
|
186
191
|
});
|
|
187
192
|
|
|
188
|
-
|
|
189
|
-
document.getElementById("sched-interval-ok").addEventListener("click", function (e) {
|
|
193
|
+
document.getElementById("sched-accordion-interval-clear").addEventListener("click", function (e) {
|
|
190
194
|
e.stopPropagation();
|
|
191
|
-
|
|
192
|
-
|
|
195
|
+
createInterval = "none";
|
|
196
|
+
createIntervalCustom = null;
|
|
197
|
+
createIntervalEnd = "allday";
|
|
198
|
+
createIntervalEndAfter = 5;
|
|
199
|
+
createIntervalEndTime = "";
|
|
200
|
+
// Reset controls
|
|
201
|
+
document.getElementById("sched-interval-custom-value").value = "10";
|
|
202
|
+
var segs = document.querySelectorAll(".sched-interval-seg");
|
|
203
|
+
for (var s = 0; s < segs.length; s++) segs[s].classList.toggle("active", segs[s].dataset.unit === "minute");
|
|
204
|
+
var iendOpts2 = document.querySelectorAll(".sched-interval-end-opt");
|
|
205
|
+
for (var ie2 = 0; ie2 < iendOpts2.length; ie2++) iendOpts2[ie2].classList.toggle("active", iendOpts2[ie2].dataset.iend === "allday");
|
|
206
|
+
var iAfterRow = document.getElementById("sched-interval-end-after-row");
|
|
207
|
+
if (iAfterRow) iAfterRow.classList.add("hidden");
|
|
208
|
+
var iUntilRow = document.getElementById("sched-interval-end-until-row");
|
|
209
|
+
if (iUntilRow) iUntilRow.classList.add("hidden");
|
|
210
|
+
// Collapse and update
|
|
211
|
+
document.getElementById("sched-accordion-interval").classList.remove("open");
|
|
212
|
+
document.getElementById("sched-accordion-interval-body").classList.add("hidden");
|
|
213
|
+
updateIntervalBtn();
|
|
193
214
|
});
|
|
194
215
|
|
|
195
216
|
// Interval custom input
|
|
@@ -255,23 +276,33 @@ export function setupCreateModal() {
|
|
|
255
276
|
});
|
|
256
277
|
}
|
|
257
278
|
|
|
258
|
-
// Custom repeat:
|
|
259
|
-
document.getElementById("sched-custom-cancel").addEventListener("click", function (e) {
|
|
260
|
-
e.stopPropagation();
|
|
261
|
-
document.getElementById("sched-create-recurrence-dropdown").classList.add("hidden");
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
// Custom repeat: unit change
|
|
279
|
+
// Custom repeat: unit change (applies immediately)
|
|
265
280
|
document.getElementById("sched-custom-unit").addEventListener("change", function () {
|
|
266
281
|
var dowSection = document.getElementById("sched-custom-dow-section");
|
|
267
282
|
if (dowSection) dowSection.style.display = this.value === "week" ? "" : "none";
|
|
283
|
+
createRecurrence = "custom";
|
|
284
|
+
createCustomConfirmed = true;
|
|
285
|
+
updateRecurrenceBtn();
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// Custom repeat: interval input (applies immediately)
|
|
289
|
+
document.getElementById("sched-custom-interval").addEventListener("change", function () {
|
|
290
|
+
createRecurrence = "custom";
|
|
291
|
+
createCustomConfirmed = true;
|
|
292
|
+
updateRecurrenceBtn();
|
|
268
293
|
});
|
|
269
294
|
|
|
270
295
|
// Custom repeat: DOW toggle
|
|
271
296
|
var customDowBtns = document.querySelectorAll("#sched-custom-dow-row .sched-dow-btn");
|
|
272
297
|
for (var i = 0; i < customDowBtns.length; i++) {
|
|
273
298
|
(function (btn) {
|
|
274
|
-
btn.addEventListener("click", function (e) {
|
|
299
|
+
btn.addEventListener("click", function (e) {
|
|
300
|
+
e.stopPropagation();
|
|
301
|
+
btn.classList.toggle("active");
|
|
302
|
+
createRecurrence = "custom";
|
|
303
|
+
createCustomConfirmed = true;
|
|
304
|
+
updateRecurrenceBtn();
|
|
305
|
+
});
|
|
275
306
|
})(customDowBtns[i]);
|
|
276
307
|
}
|
|
277
308
|
|
|
@@ -377,29 +408,6 @@ export function setupCreateModal() {
|
|
|
377
408
|
if (createEndAfter < 1) { createEndAfter = 1; this.value = 1; }
|
|
378
409
|
});
|
|
379
410
|
|
|
380
|
-
// Custom repeat: OK
|
|
381
|
-
document.getElementById("sched-custom-ok").addEventListener("click", function (e) {
|
|
382
|
-
e.stopPropagation();
|
|
383
|
-
createRecurrence = "custom";
|
|
384
|
-
createCustomConfirmed = true;
|
|
385
|
-
document.getElementById("sched-create-recurrence-dropdown").classList.add("hidden");
|
|
386
|
-
updateRecurrenceBtn();
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
// Run mode toggle (single vs multi-round)
|
|
390
|
-
var runModeContainer = createPopover.querySelector(".sched-create-run-mode");
|
|
391
|
-
if (runModeContainer) {
|
|
392
|
-
runModeContainer.addEventListener("click", function (e) {
|
|
393
|
-
var btn = e.target.closest(".sched-run-mode-btn");
|
|
394
|
-
if (!btn) return;
|
|
395
|
-
var mode = btn.dataset.mode;
|
|
396
|
-
var btns = runModeContainer.querySelectorAll(".sched-run-mode-btn");
|
|
397
|
-
for (var i = 0; i < btns.length; i++) btns[i].classList.toggle("active", btns[i] === btn);
|
|
398
|
-
var iterGroup = document.getElementById("sched-create-iter-group");
|
|
399
|
-
if (iterGroup) iterGroup.classList.toggle("hidden", mode !== "multi");
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
|
|
403
411
|
// Submit
|
|
404
412
|
document.getElementById("sched-create-submit").addEventListener("click", function () { submitCreateSchedule(); });
|
|
405
413
|
|
|
@@ -492,10 +500,12 @@ export function setupCreateModal() {
|
|
|
492
500
|
document.addEventListener("keydown", function (e) {
|
|
493
501
|
var cp = configCtx.getCreatePopover();
|
|
494
502
|
if (e.key === "Escape" && cp && !cp.classList.contains("hidden")) {
|
|
495
|
-
// Close
|
|
496
|
-
var
|
|
497
|
-
if (
|
|
498
|
-
|
|
503
|
+
// Close open accordions first
|
|
504
|
+
var openAcc = cp.querySelector(".sched-accordion.open");
|
|
505
|
+
if (openAcc) {
|
|
506
|
+
openAcc.classList.remove("open");
|
|
507
|
+
var openBody = openAcc.querySelector(".sched-accordion-body");
|
|
508
|
+
if (openBody) openBody.classList.add("hidden");
|
|
499
509
|
return;
|
|
500
510
|
}
|
|
501
511
|
closeCreateModal();
|
|
@@ -503,11 +513,50 @@ export function setupCreateModal() {
|
|
|
503
513
|
});
|
|
504
514
|
}
|
|
505
515
|
|
|
516
|
+
function updateTaskSubtitle() {
|
|
517
|
+
var sub = document.getElementById("sched-accordion-task-subtitle");
|
|
518
|
+
if (!sub) return;
|
|
519
|
+
var taskLabel = document.getElementById("sched-create-task-label");
|
|
520
|
+
var taskName = (taskLabel && taskLabel.textContent !== "Select a task") ? taskLabel.textContent : null;
|
|
521
|
+
var check = document.getElementById("sched-review-check");
|
|
522
|
+
var iterInput = document.getElementById("sched-create-iterations");
|
|
523
|
+
var iters = iterInput ? (parseInt(iterInput.value, 10) || 1) : 1;
|
|
524
|
+
if (!taskName) {
|
|
525
|
+
sub.textContent = "What to run";
|
|
526
|
+
} else if (check && check.checked && iters > 1) {
|
|
527
|
+
sub.textContent = taskName + " - review " + iters + "x";
|
|
528
|
+
} else {
|
|
529
|
+
sub.textContent = taskName + " - run once";
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
506
533
|
function updateRecurrenceBtn() {
|
|
507
|
-
var
|
|
508
|
-
|
|
509
|
-
|
|
534
|
+
var acc = document.getElementById("sched-accordion-repeat");
|
|
535
|
+
var hasVal = createRecurrence !== "none";
|
|
536
|
+
if (acc) {
|
|
537
|
+
acc.classList.toggle("has-value", hasVal);
|
|
538
|
+
}
|
|
539
|
+
var clearBtn = document.getElementById("sched-accordion-repeat-clear");
|
|
540
|
+
if (clearBtn) clearBtn.classList.toggle("hidden", !hasVal);
|
|
541
|
+
// Update subtitle with summary or default description
|
|
542
|
+
var sub = document.getElementById("sched-accordion-repeat-subtitle");
|
|
543
|
+
if (!sub) return;
|
|
544
|
+
if (createRecurrence === "none" || !createCustomConfirmed) {
|
|
545
|
+
sub.textContent = "Which days to run";
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
var interval = document.getElementById("sched-custom-interval").value || "1";
|
|
549
|
+
var unit = document.getElementById("sched-custom-unit").value || "week";
|
|
550
|
+
var summary = "Every " + interval + " " + unit;
|
|
551
|
+
if (unit === "week") {
|
|
552
|
+
var activeDow = document.querySelectorAll("#sched-custom-dow-row .sched-dow-btn.active");
|
|
553
|
+
if (activeDow.length > 0) {
|
|
554
|
+
var days = [];
|
|
555
|
+
for (var di = 0; di < activeDow.length; di++) days.push(activeDow[di].textContent);
|
|
556
|
+
summary += " on " + days.join(", ");
|
|
557
|
+
}
|
|
510
558
|
}
|
|
559
|
+
sub.textContent = summary;
|
|
511
560
|
}
|
|
512
561
|
|
|
513
562
|
/**
|
|
@@ -542,17 +591,29 @@ function enforceMinTime() {
|
|
|
542
591
|
}
|
|
543
592
|
|
|
544
593
|
function updateIntervalBtn() {
|
|
545
|
-
var
|
|
546
|
-
|
|
547
|
-
|
|
594
|
+
var acc = document.getElementById("sched-accordion-interval");
|
|
595
|
+
var hasVal = createInterval !== "none";
|
|
596
|
+
if (acc) {
|
|
597
|
+
acc.classList.toggle("has-value", hasVal);
|
|
548
598
|
}
|
|
599
|
+
var clearBtn = document.getElementById("sched-accordion-interval-clear");
|
|
600
|
+
if (clearBtn) clearBtn.classList.toggle("hidden", !hasVal);
|
|
549
601
|
// Show/hide interval end conditions section
|
|
550
602
|
var endSection = document.getElementById("sched-interval-end-section");
|
|
551
603
|
if (endSection) {
|
|
552
604
|
endSection.classList.toggle("hidden", createInterval === "none");
|
|
553
605
|
}
|
|
554
|
-
//
|
|
555
|
-
|
|
606
|
+
// Update subtitle
|
|
607
|
+
var sub = document.getElementById("sched-accordion-interval-subtitle");
|
|
608
|
+
if (sub) {
|
|
609
|
+
if (createInterval === "none" || !createIntervalCustom) {
|
|
610
|
+
sub.textContent = "How often within each day";
|
|
611
|
+
} else {
|
|
612
|
+
var v = createIntervalCustom.value || 10;
|
|
613
|
+
var u = createIntervalCustom.unit === "hour" ? "hrs" : "min";
|
|
614
|
+
sub.textContent = "Every " + v + " " + u;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
556
617
|
updateRecurrenceBtn();
|
|
557
618
|
}
|
|
558
619
|
|
|
@@ -633,6 +694,7 @@ export function applyDraggedTask() {
|
|
|
633
694
|
if (taskHidden) taskHidden.value = dragState.draggedTaskId;
|
|
634
695
|
if (taskLabel) taskLabel.textContent = dragState.draggedTaskName || dragState.draggedTaskId;
|
|
635
696
|
if (taskBtn) { taskBtn.classList.add("has-value"); taskBtn.classList.remove("invalid"); }
|
|
697
|
+
updateTaskSubtitle();
|
|
636
698
|
// Mark the matching item as selected in the dropdown list
|
|
637
699
|
var taskListEl = document.getElementById("sched-create-task-list");
|
|
638
700
|
if (taskListEl) {
|
|
@@ -689,8 +751,16 @@ export function openCreateModalWithRecord(rec, anchorEl) {
|
|
|
689
751
|
var titleInput = document.getElementById("sched-create-title");
|
|
690
752
|
if (titleInput) titleInput.value = rec.name || "";
|
|
691
753
|
|
|
754
|
+
// Show description row only if the record already has one
|
|
755
|
+
var descRow = document.getElementById("sched-create-desc-row");
|
|
692
756
|
var descInput = document.getElementById("sched-create-desc");
|
|
693
|
-
if (
|
|
757
|
+
if (rec.description) {
|
|
758
|
+
if (descInput) descInput.value = rec.description;
|
|
759
|
+
if (descRow) descRow.classList.remove("hidden");
|
|
760
|
+
} else {
|
|
761
|
+
if (descInput) descInput.value = "";
|
|
762
|
+
if (descRow) descRow.classList.add("hidden");
|
|
763
|
+
}
|
|
694
764
|
|
|
695
765
|
// Set color
|
|
696
766
|
if (rec.color) {
|
|
@@ -707,18 +777,14 @@ export function openCreateModalWithRecord(rec, anchorEl) {
|
|
|
707
777
|
var skipRunningEl = document.getElementById("sched-skip-running");
|
|
708
778
|
if (skipRunningEl) skipRunningEl.checked = rec.skipIfRunning !== false;
|
|
709
779
|
|
|
710
|
-
// Set
|
|
711
|
-
var
|
|
712
|
-
var
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
var
|
|
717
|
-
if (
|
|
718
|
-
if (rec.maxIterations && rec.maxIterations > 1) {
|
|
719
|
-
var iterInput = document.getElementById("sched-create-iterations");
|
|
720
|
-
if (iterInput) iterInput.value = rec.maxIterations;
|
|
721
|
-
}
|
|
780
|
+
// Set iterations + review checkbox
|
|
781
|
+
var hasReview = rec.maxIterations && rec.maxIterations > 1;
|
|
782
|
+
var iterInput = document.getElementById("sched-create-iterations");
|
|
783
|
+
if (iterInput) iterInput.value = hasReview ? rec.maxIterations : 3;
|
|
784
|
+
var reviewCheckEdit = document.getElementById("sched-review-check");
|
|
785
|
+
if (reviewCheckEdit) reviewCheckEdit.checked = hasReview;
|
|
786
|
+
var reviewCountEdit = document.getElementById("sched-review-count");
|
|
787
|
+
if (reviewCountEdit) reviewCountEdit.classList.toggle("hidden", !hasReview);
|
|
722
788
|
|
|
723
789
|
// Set linked task
|
|
724
790
|
if (rec.linkedTaskId) {
|
|
@@ -735,12 +801,14 @@ export function openCreateModalWithRecord(rec, anchorEl) {
|
|
|
735
801
|
}
|
|
736
802
|
if (taskLabel2) taskLabel2.textContent = taskName;
|
|
737
803
|
if (taskBtn) { taskBtn.classList.add("has-value"); taskBtn.classList.remove("invalid"); }
|
|
804
|
+
// (no accordion to update)
|
|
738
805
|
if (taskListEl) {
|
|
739
806
|
var items = taskListEl.querySelectorAll(".sched-create-task-item");
|
|
740
807
|
for (var k = 0; k < items.length; k++) {
|
|
741
808
|
items[k].classList.toggle("selected", items[k].dataset.taskId === rec.linkedTaskId);
|
|
742
809
|
}
|
|
743
810
|
}
|
|
811
|
+
updateTaskSubtitle();
|
|
744
812
|
}
|
|
745
813
|
|
|
746
814
|
// Restore interval from cron
|
|
@@ -872,15 +940,15 @@ export function openCreateModal(date, hour, anchorEl) {
|
|
|
872
940
|
// Reset form
|
|
873
941
|
document.getElementById("sched-create-title").value = "";
|
|
874
942
|
document.getElementById("sched-create-desc").value = "";
|
|
943
|
+
var descRowReset = document.getElementById("sched-create-desc-row");
|
|
944
|
+
if (descRowReset) descRowReset.classList.add("hidden");
|
|
875
945
|
var iterReset = document.getElementById("sched-create-iterations");
|
|
876
946
|
if (iterReset) iterReset.value = "3";
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
var iterGroup = document.getElementById("sched-create-iter-group");
|
|
883
|
-
if (iterGroup) iterGroup.classList.add("hidden");
|
|
947
|
+
var reviewCheck = document.getElementById("sched-review-check");
|
|
948
|
+
if (reviewCheck) reviewCheck.checked = false;
|
|
949
|
+
var reviewCount = document.getElementById("sched-review-count");
|
|
950
|
+
if (reviewCount) reviewCount.classList.add("hidden");
|
|
951
|
+
// (task is always visible, no accordion reset needed)
|
|
884
952
|
|
|
885
953
|
// Reset color
|
|
886
954
|
var colorDot = document.getElementById("sched-create-color-dot");
|
|
@@ -904,34 +972,36 @@ export function openCreateModal(date, hour, anchorEl) {
|
|
|
904
972
|
if (taskListEl) {
|
|
905
973
|
taskListEl.classList.add("hidden");
|
|
906
974
|
var tasks = records.filter(function (r) { return r.source !== "ralph" && r.source !== "schedule"; });
|
|
975
|
+
var html = "";
|
|
907
976
|
if (tasks.length === 0) {
|
|
908
|
-
|
|
977
|
+
html = '<div class="sched-create-task-empty">No tasks available</div>';
|
|
909
978
|
} else {
|
|
910
|
-
var html = "";
|
|
911
979
|
for (var i = 0; i < tasks.length; i++) {
|
|
912
980
|
html += '<div class="sched-create-task-item" data-task-id="' + configCtx.esc(tasks[i].id) + '">' + configCtx.esc(tasks[i].name || tasks[i].id) + '</div>';
|
|
913
981
|
}
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
|
|
982
|
+
}
|
|
983
|
+
taskListEl.innerHTML = html;
|
|
984
|
+
// Bind click handlers
|
|
985
|
+
var items = taskListEl.querySelectorAll(".sched-create-task-item");
|
|
986
|
+
for (var j = 0; j < items.length; j++) {
|
|
987
|
+
(function (item) {
|
|
988
|
+
item.addEventListener("click", function (e) {
|
|
989
|
+
e.stopPropagation();
|
|
990
|
+
var id = item.dataset.taskId;
|
|
991
|
+
var name = item.textContent;
|
|
992
|
+
if (taskHidden) taskHidden.value = id;
|
|
993
|
+
if (taskLabel) taskLabel.textContent = name;
|
|
994
|
+
if (taskBtn) { taskBtn.classList.add("has-value"); taskBtn.classList.remove("invalid"); }
|
|
995
|
+
// (no accordion to update)
|
|
996
|
+
// Update selected state
|
|
997
|
+
var all = taskListEl.querySelectorAll(".sched-create-task-item");
|
|
998
|
+
for (var k = 0; k < all.length; k++) {
|
|
999
|
+
all[k].classList.toggle("selected", all[k] === item);
|
|
1000
|
+
}
|
|
1001
|
+
taskListEl.classList.add("hidden");
|
|
1002
|
+
updateTaskSubtitle();
|
|
1003
|
+
});
|
|
1004
|
+
})(items[j]);
|
|
935
1005
|
}
|
|
936
1006
|
}
|
|
937
1007
|
|
|
@@ -972,8 +1042,9 @@ export function openCreateModal(date, hour, anchorEl) {
|
|
|
972
1042
|
createCustomConfirmed = false;
|
|
973
1043
|
updateRecurrenceBtn();
|
|
974
1044
|
|
|
975
|
-
// Reset interval
|
|
976
|
-
document.getElementById("sched-
|
|
1045
|
+
// Reset interval accordion
|
|
1046
|
+
document.getElementById("sched-accordion-interval").classList.remove("open");
|
|
1047
|
+
document.getElementById("sched-accordion-interval-body").classList.add("hidden");
|
|
977
1048
|
var timeInput = document.getElementById("sched-create-time");
|
|
978
1049
|
if (timeInput) timeInput.style.display = "";
|
|
979
1050
|
|
|
@@ -993,8 +1064,9 @@ export function openCreateModal(date, hour, anchorEl) {
|
|
|
993
1064
|
|
|
994
1065
|
updateIntervalBtn();
|
|
995
1066
|
|
|
996
|
-
// Reset
|
|
997
|
-
document.getElementById("sched-
|
|
1067
|
+
// Reset repeat accordion
|
|
1068
|
+
document.getElementById("sched-accordion-repeat").classList.remove("open");
|
|
1069
|
+
document.getElementById("sched-accordion-repeat-body").classList.add("hidden");
|
|
998
1070
|
document.getElementById("sched-custom-interval").value = "1";
|
|
999
1071
|
document.getElementById("sched-custom-unit").value = "week";
|
|
1000
1072
|
document.getElementById("sched-custom-dow-section").style.display = "";
|
|
@@ -1105,8 +1177,15 @@ function updateRecurrenceLabels(date) {
|
|
|
1105
1177
|
export function closeCreateModal() {
|
|
1106
1178
|
var createPopover = configCtx.getCreatePopover();
|
|
1107
1179
|
if (createPopover) createPopover.classList.add("hidden");
|
|
1108
|
-
|
|
1109
|
-
|
|
1180
|
+
// Collapse accordions
|
|
1181
|
+
var accRepeat = document.getElementById("sched-accordion-repeat");
|
|
1182
|
+
if (accRepeat) { accRepeat.classList.remove("open"); }
|
|
1183
|
+
var accRepeatBody = document.getElementById("sched-accordion-repeat-body");
|
|
1184
|
+
if (accRepeatBody) accRepeatBody.classList.add("hidden");
|
|
1185
|
+
var accInterval = document.getElementById("sched-accordion-interval");
|
|
1186
|
+
if (accInterval) { accInterval.classList.remove("open"); }
|
|
1187
|
+
var accIntervalBody = document.getElementById("sched-accordion-interval-body");
|
|
1188
|
+
if (accIntervalBody) accIntervalBody.classList.add("hidden");
|
|
1110
1189
|
var pal = document.getElementById("sched-create-color-palette");
|
|
1111
1190
|
if (pal) pal.classList.add("hidden");
|
|
1112
1191
|
var tl = document.getElementById("sched-create-task-list");
|
|
@@ -1385,7 +1464,8 @@ function submitCreateSchedule() {
|
|
|
1385
1464
|
var ctx = configCtx.ctx;
|
|
1386
1465
|
ctx.requireClayRalph(function () {
|
|
1387
1466
|
var createPopover = configCtx.getCreatePopover();
|
|
1388
|
-
var
|
|
1467
|
+
var descInput = document.getElementById("sched-create-desc");
|
|
1468
|
+
var description = descInput ? descInput.value.trim() : "";
|
|
1389
1469
|
var datePicker = document.getElementById("sched-create-date-picker");
|
|
1390
1470
|
var dateVal = datePicker ? datePicker.value : document.getElementById("sched-create-date").value;
|
|
1391
1471
|
var timeVal = document.getElementById("sched-create-time").value || "09:00";
|
|
@@ -1439,10 +1519,9 @@ function submitCreateSchedule() {
|
|
|
1439
1519
|
var skipRunningEl = document.getElementById("sched-skip-running");
|
|
1440
1520
|
var skipIfRunning = skipRunningEl ? skipRunningEl.checked : true;
|
|
1441
1521
|
|
|
1442
|
-
var
|
|
1443
|
-
var runMode = activeRunMode ? activeRunMode.dataset.mode : "single";
|
|
1522
|
+
var reviewCheckSubmit = document.getElementById("sched-review-check");
|
|
1444
1523
|
var maxIterations = 1;
|
|
1445
|
-
if (
|
|
1524
|
+
if (reviewCheckSubmit && reviewCheckSubmit.checked) {
|
|
1446
1525
|
var iterInput = document.getElementById("sched-create-iterations");
|
|
1447
1526
|
maxIterations = iterInput ? (parseInt(iterInput.value, 10) || 3) : 3;
|
|
1448
1527
|
if (maxIterations < 2) maxIterations = 2;
|
|
@@ -43,19 +43,21 @@ export function handleLoopRegistryUpdated(msg) {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
// Cache last-received file content for edit mode
|
|
47
|
+
export var _lastFiles = { id: null, prompt: "", judge: "", settings: null };
|
|
48
|
+
|
|
46
49
|
export function handleLoopRegistryFiles(msg) {
|
|
47
50
|
if (!histCtx.isPanelOpen() || histCtx.getCurrentMode() !== "detail") return;
|
|
48
51
|
if (msg.id !== histCtx.getSelectedTaskId()) return;
|
|
52
|
+
_lastFiles = { id: msg.id, prompt: msg.prompt || "", judge: msg.judge || "", settings: msg.settings || null };
|
|
49
53
|
var bodyEl = document.getElementById("scheduler-detail-body");
|
|
50
54
|
if (!bodyEl) return;
|
|
51
55
|
var contentDetailEl = histCtx.getContentDetailEl();
|
|
52
56
|
var activeTab = contentDetailEl ? contentDetailEl.querySelector(".scheduler-detail-tab.active") : null;
|
|
53
57
|
var tab = activeTab ? activeTab.dataset.tab : "prompt";
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
bodyEl.innerHTML = msg.judge ? '<div class="md-content">' + renderMarkdown(msg.judge) + '</div>' : '<div class="scheduler-empty">No JUDGE.md found</div>';
|
|
58
|
-
}
|
|
58
|
+
var content = tab === "prompt" ? _lastFiles.prompt : _lastFiles.judge;
|
|
59
|
+
var fileLabel = tab === "prompt" ? "PROMPT.md" : "JUDGE.md";
|
|
60
|
+
renderFileView(bodyEl, tab, content, fileLabel, msg.id);
|
|
59
61
|
// Disable "Run now" if PROMPT.md is missing
|
|
60
62
|
var runBtn = contentDetailEl ? contentDetailEl.querySelector('[data-action="run"]') : null;
|
|
61
63
|
if (runBtn) {
|
|
@@ -65,6 +67,56 @@ export function handleLoopRegistryFiles(msg) {
|
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
69
|
|
|
70
|
+
function renderFileView(bodyEl, tab, content, fileLabel, recId) {
|
|
71
|
+
if (content) {
|
|
72
|
+
bodyEl.innerHTML = '<div class="scheduler-file-toolbar"><button class="scheduler-file-edit-btn" title="Edit"><i data-lucide="pencil"></i> Edit</button></div>' +
|
|
73
|
+
'<div class="md-content">' + renderMarkdown(content) + '</div>';
|
|
74
|
+
} else {
|
|
75
|
+
bodyEl.innerHTML = '<div class="scheduler-file-toolbar"><button class="scheduler-file-edit-btn" title="Edit"><i data-lucide="pencil"></i> Edit</button></div>' +
|
|
76
|
+
'<div class="scheduler-empty">No ' + fileLabel + ' found</div>';
|
|
77
|
+
}
|
|
78
|
+
if (typeof lucide !== "undefined") lucide.createIcons({ attrs: { class: "lucide" } });
|
|
79
|
+
var editBtn = bodyEl.querySelector(".scheduler-file-edit-btn");
|
|
80
|
+
if (editBtn) {
|
|
81
|
+
editBtn.addEventListener("click", function () {
|
|
82
|
+
renderFileEdit(bodyEl, tab, content, recId);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function renderFileEdit(bodyEl, tab, content, recId) {
|
|
88
|
+
bodyEl.innerHTML = '<div class="scheduler-file-toolbar">' +
|
|
89
|
+
'<button class="scheduler-file-save-btn" title="Save"><i data-lucide="check"></i> Save</button>' +
|
|
90
|
+
'<button class="scheduler-file-cancel-btn" title="Cancel"><i data-lucide="x"></i> Cancel</button>' +
|
|
91
|
+
'</div>' +
|
|
92
|
+
'<textarea class="scheduler-file-editor">' + escapeHtml(content) + '</textarea>';
|
|
93
|
+
if (typeof lucide !== "undefined") lucide.createIcons({ attrs: { class: "lucide" } });
|
|
94
|
+
var ta = bodyEl.querySelector(".scheduler-file-editor");
|
|
95
|
+
if (ta) ta.focus();
|
|
96
|
+
var saveBtn = bodyEl.querySelector(".scheduler-file-save-btn");
|
|
97
|
+
if (saveBtn) {
|
|
98
|
+
saveBtn.addEventListener("click", function () {
|
|
99
|
+
var newContent = ta.value;
|
|
100
|
+
var data = { type: "loop_registry_save_files", id: recId };
|
|
101
|
+
if (tab === "prompt") data.prompt = newContent;
|
|
102
|
+
else data.judge = newContent;
|
|
103
|
+
histCtx.send(data);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
var cancelBtn = bodyEl.querySelector(".scheduler-file-cancel-btn");
|
|
107
|
+
if (cancelBtn) {
|
|
108
|
+
cancelBtn.addEventListener("click", function () {
|
|
109
|
+
var fileLabel = tab === "prompt" ? "PROMPT.md" : "JUDGE.md";
|
|
110
|
+
renderFileView(bodyEl, tab, _lastFiles[tab], fileLabel, recId);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function escapeHtml(str) {
|
|
116
|
+
if (!str) return "";
|
|
117
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
118
|
+
}
|
|
119
|
+
|
|
68
120
|
export function handleScheduleRunStarted(msg) {
|
|
69
121
|
if (histCtx.isPanelOpen()) histCtx.render();
|
|
70
122
|
}
|