diff --git a/frontend/packages/dashboard/src/tabs.js b/frontend/packages/dashboard/src/tabs.js index dae04d2f..8dcaed8b 100644 --- a/frontend/packages/dashboard/src/tabs.js +++ b/frontend/packages/dashboard/src/tabs.js @@ -2104,6 +2104,60 @@ window.marked = marked; return { wrapper, getSeconds, fillFromSeconds, setParts, updatePreview }; } + // Parse the d/h/m/s sub-fields of a `buildIntervalComposer` instance + // out of submitted FormData. Returns total seconds, or NaN if any + // field carries a non-integer / negative value — the caller alerts + // and bails. Total `0` means "one-shot" at the call site (wire is + // `interval_seconds: null`). `namePrefix` matches the prefix passed + // to `buildIntervalComposer` (e.g. `interval_` or `edit_interval_`). + function intervalSecondsFromFormData(fd, namePrefix) { + const part = (suffix, mult) => { + const raw = String(fd.get(namePrefix + suffix) || '').trim(); + if (!raw) return 0; + const n = parseInt(raw, 10); + if (!Number.isFinite(n) || n < 0) return NaN; + return n * mult; + }; + return part('d', 86400) + part('h', 3600) + part('m', 60) + part('s', 1); + } + + // Targets multi-select chip box — shared between the new-schedule + // form and the edit-schedule form. Same DOM shape, same candidate + // list (containers + operator + manager); only the chip element id + // prefix and checkbox field name vary. Used to be inlined twice in + // near-identical 18-line blocks; consolidated here so a future + // change (new chip kind, candidate-list source swap, etc.) lives in + // one place. Returns the wrapping `