@burdenoff/microfe-vibecontrols 2026.602.9 → 2026.608.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.
@@ -1,159 +1,160 @@
1
1
  import { useListActionsQuery as e } from "../../generated/wspace-operations.js";
2
2
  import { useTr as t } from "../../shared/hooks/useTr.js";
3
- import { useMemo as n, useState as r } from "react";
4
- import { Search as i, X as a, Zap as o } from "lucide-react";
5
- import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
3
+ import { ActionAgentTargetNotice as n } from "../common/ActionAgentTargetNotice.js";
4
+ import { useMemo as r, useState as i } from "react";
5
+ import { Search as a, X as o, Zap as s } from "lucide-react";
6
+ import { Fragment as c, jsx as l, jsxs as u } from "react/jsx-runtime";
6
7
  //#region src/components/vibecalendar/ScheduleTaskModal.tsx
7
- var u = "w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-lg text-sm text-text-primary placeholder-text-placeholder focus:outline-none focus:border-border-primary", d = `${u} font-mono`, f = "block text-sm font-medium text-text-secondary mb-1";
8
- function p({ isOpen: p, onClose: m, onSubmit: h, loading: g, prefillActionId: _ }) {
9
- let v = t(), [y, b] = r(_ ?? ""), [x, S] = r(""), [C, w] = r(""), [T, E] = r(""), [D, O] = r("ONE_TIME"), [k, A] = r(""), [j, M] = r(""), [N, P] = r(60), [F, I] = r("minutes"), [L, R] = r(Intl.DateTimeFormat().resolvedOptions().timeZone), { data: z, loading: B } = e({
8
+ var d = "w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-lg text-sm text-text-primary placeholder-text-placeholder focus:outline-none focus:border-border-primary", f = `${d} font-mono`, p = "block text-sm font-medium text-text-secondary mb-1";
9
+ function m({ isOpen: m, onClose: h, onSubmit: g, loading: _, prefillActionId: v }) {
10
+ let y = t(), [b, x] = i(v ?? ""), [S, C] = i(""), [w, T] = i(""), [E, D] = i(""), [O, k] = i("ONE_TIME"), [A, j] = i(""), [M, N] = i(""), [P, F] = i(60), [I, L] = i("minutes"), [R, z] = i(Intl.DateTimeFormat().resolvedOptions().timeZone), { data: B, loading: V } = e({
10
11
  variables: { pagination: { limit: 100 } },
11
- skip: !p,
12
+ skip: !m,
12
13
  fetchPolicy: "cache-and-network"
13
- }), V = n(() => z?.actions?.items ?? [], [z?.actions?.items]), H = n(() => {
14
- if (!x.trim()) return V;
15
- let e = x.trim().toLowerCase();
16
- return V.filter((t) => t.name?.toLowerCase().includes(e) || t.displayName?.toLowerCase().includes(e) || t.description?.toLowerCase().includes(e));
17
- }, [V, x]), U = n(() => V.find((e) => e.id === y), [V, y]);
18
- if (!p) return null;
19
- let W = !!_, G = !!y && !g;
20
- return /* @__PURE__ */ l("div", {
14
+ }), H = r(() => B?.actions?.items ?? [], [B?.actions?.items]), U = r(() => {
15
+ if (!S.trim()) return H;
16
+ let e = S.trim().toLowerCase();
17
+ return H.filter((t) => t.name?.toLowerCase().includes(e) || t.displayName?.toLowerCase().includes(e) || t.description?.toLowerCase().includes(e));
18
+ }, [H, S]), W = r(() => H.find((e) => e.id === b), [H, b]);
19
+ if (!m) return null;
20
+ let G = !!v, K = !!b && !_;
21
+ return /* @__PURE__ */ u("div", {
21
22
  className: "fixed inset-0 z-50 flex items-center justify-center",
22
- children: [/* @__PURE__ */ c("div", {
23
+ children: [/* @__PURE__ */ l("div", {
23
24
  role: "button",
24
25
  tabIndex: 0,
25
26
  onKeyDown: (e) => {
26
- (e.key === "Enter" || e.key === " ") && (e.preventDefault(), m());
27
+ (e.key === "Enter" || e.key === " ") && (e.preventDefault(), h());
27
28
  },
28
29
  className: "absolute inset-0 bg-bg-overlay",
29
- onClick: m
30
- }), /* @__PURE__ */ l("div", {
30
+ onClick: h
31
+ }), /* @__PURE__ */ u("div", {
31
32
  className: "relative bg-bg-surface border border-border-default rounded-xl shadow-xl w-full max-w-lg max-h-[90vh] overflow-y-auto",
32
- children: [/* @__PURE__ */ l("div", {
33
+ children: [/* @__PURE__ */ u("div", {
33
34
  className: "flex items-center justify-between px-6 py-4 border-b border-border-default",
34
- children: [/* @__PURE__ */ c("h2", {
35
+ children: [/* @__PURE__ */ l("h2", {
35
36
  className: "text-lg font-semibold text-text-primary",
36
- children: W ? v("vibecontrols.calendar.schedule.addActionToCalendar", "Add Action to Calendar") : v("vibecontrols.calendar.schedule.scheduleActionOnCalendar", "Schedule Action on Calendar")
37
- }), /* @__PURE__ */ c("button", {
37
+ children: G ? y("vibecontrols.calendar.schedule.addActionToCalendar", "Add Action to Calendar") : y("vibecontrols.calendar.schedule.scheduleActionOnCalendar", "Schedule Action on Calendar")
38
+ }), /* @__PURE__ */ l("button", {
38
39
  type: "button",
39
- onClick: m,
40
+ onClick: h,
40
41
  className: "p-1 rounded hover:bg-bg-secondary",
41
- children: /* @__PURE__ */ c(a, { size: 18 })
42
+ children: /* @__PURE__ */ l(o, { size: 18 })
42
43
  })]
43
- }), /* @__PURE__ */ l("form", {
44
+ }), /* @__PURE__ */ u("form", {
44
45
  onSubmit: (e) => {
45
- e.preventDefault(), y && h({
46
+ e.preventDefault(), b && g({
46
47
  calendarId: "",
47
- title: C,
48
- description: T || void 0,
49
- scheduleType: D,
50
- scheduledAt: D === "ONE_TIME" ? new Date(k).toISOString() : void 0,
51
- cronExpression: D === "CRON" ? j : void 0,
52
- interval: D === "FIXED_INTERVAL" ? N : void 0,
53
- intervalUnit: D === "FIXED_INTERVAL" ? F : void 0,
54
- timezone: L,
55
- actionId: y
48
+ title: w,
49
+ description: E || void 0,
50
+ scheduleType: O,
51
+ scheduledAt: O === "ONE_TIME" ? new Date(A).toISOString() : void 0,
52
+ cronExpression: O === "CRON" ? M : void 0,
53
+ interval: O === "FIXED_INTERVAL" ? P : void 0,
54
+ intervalUnit: O === "FIXED_INTERVAL" ? I : void 0,
55
+ timezone: R,
56
+ actionId: b
56
57
  });
57
58
  },
58
59
  className: "px-6 py-4 space-y-4",
59
60
  children: [
60
- /* @__PURE__ */ l("div", {
61
+ /* @__PURE__ */ u("div", {
61
62
  className: "space-y-2",
62
63
  children: [
63
- /* @__PURE__ */ l("label", {
64
- className: f,
65
- children: [v("vibecontrols.calendar.schedule.actionToSchedule", "Action to Schedule"), " *"]
64
+ /* @__PURE__ */ u("label", {
65
+ className: p,
66
+ children: [y("vibecontrols.calendar.schedule.actionToSchedule", "Action to Schedule"), " *"]
66
67
  }),
67
- /* @__PURE__ */ c("p", {
68
+ /* @__PURE__ */ l("p", {
68
69
  className: "text-xs text-text-tertiary -mt-1",
69
70
  children: "Calendar entries trigger VibeControls Actions. Agent, command, and webhook details come from the Action definition."
70
71
  }),
71
- W && U && /* @__PURE__ */ l("div", {
72
+ G && W && /* @__PURE__ */ u("div", {
72
73
  className: "flex items-start gap-3 p-3 rounded-lg border border-border-default bg-bg-secondary",
73
- children: [/* @__PURE__ */ c("div", {
74
+ children: [/* @__PURE__ */ l("div", {
74
75
  className: "p-1.5 rounded-md bg-primary/10 text-primary flex-shrink-0",
75
- children: /* @__PURE__ */ c(o, { size: 16 })
76
- }), /* @__PURE__ */ l("div", {
76
+ children: /* @__PURE__ */ l(s, { size: 16 })
77
+ }), /* @__PURE__ */ u("div", {
77
78
  className: "flex-1 min-w-0",
78
79
  children: [
79
- /* @__PURE__ */ c("p", {
80
+ /* @__PURE__ */ l("p", {
80
81
  className: "text-sm font-medium text-text-primary",
81
- children: U.displayName || U.name
82
+ children: W.displayName || W.name
82
83
  }),
83
- /* @__PURE__ */ l("p", {
84
+ /* @__PURE__ */ u("p", {
84
85
  className: "text-xs text-text-secondary mt-0.5",
85
86
  children: [
86
- U.actionType,
87
+ W.actionType,
87
88
  " · ",
88
- U.triggerType
89
+ W.triggerType
89
90
  ]
90
91
  }),
91
- U.description && /* @__PURE__ */ c("p", {
92
+ W.description && /* @__PURE__ */ l("p", {
92
93
  className: "text-xs text-text-tertiary mt-1 line-clamp-2",
93
- children: U.description
94
+ children: W.description
94
95
  })
95
96
  ]
96
97
  })]
97
98
  }),
98
- W && !U && B && /* @__PURE__ */ c("div", {
99
+ G && !W && V && /* @__PURE__ */ l("div", {
99
100
  className: "p-3 rounded-lg border border-border-default bg-bg-secondary text-xs text-text-secondary",
100
101
  children: "Loading action…"
101
102
  }),
102
- W && !U && !B && /* @__PURE__ */ c("div", {
103
+ G && !W && !V && /* @__PURE__ */ l("div", {
103
104
  className: "p-3 rounded-lg border border-status-error-border bg-status-error-bg-subtle text-xs text-status-error-text",
104
105
  children: "Action not found. It may have been deleted."
105
106
  }),
106
- !W && /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ l("div", {
107
+ !G && /* @__PURE__ */ u(c, { children: [/* @__PURE__ */ u("div", {
107
108
  className: "relative",
108
- children: [/* @__PURE__ */ c(i, {
109
+ children: [/* @__PURE__ */ l(a, {
109
110
  size: 16,
110
111
  className: "absolute left-3 top-1/2 -translate-y-1/2 text-text-tertiary"
111
- }), /* @__PURE__ */ c("input", {
112
+ }), /* @__PURE__ */ l("input", {
112
113
  "aria-label": "Search actions by name…",
113
114
  type: "text",
114
- value: x,
115
- onChange: (e) => S(e.target.value),
115
+ value: S,
116
+ onChange: (e) => C(e.target.value),
116
117
  placeholder: "Search actions by name…",
117
- className: `${u} pl-9`
118
+ className: `${d} pl-9`
118
119
  })]
119
- }), /* @__PURE__ */ l("div", {
120
+ }), /* @__PURE__ */ u("div", {
120
121
  className: "max-h-40 overflow-y-auto border border-border-default rounded-lg divide-y divide-border-default",
121
122
  children: [
122
- B && V.length === 0 && /* @__PURE__ */ c("div", {
123
+ V && H.length === 0 && /* @__PURE__ */ l("div", {
123
124
  className: "px-3 py-4 text-xs text-text-secondary text-center",
124
125
  children: "Loading actions…"
125
126
  }),
126
- !B && V.length === 0 && /* @__PURE__ */ c("div", {
127
+ !V && H.length === 0 && /* @__PURE__ */ l("div", {
127
128
  className: "px-3 py-4 text-xs text-text-secondary text-center",
128
129
  children: "No actions yet. Create an Action in VibeControls first, then come back to schedule it."
129
130
  }),
130
- !B && V.length > 0 && H.length === 0 && /* @__PURE__ */ l("div", {
131
+ !V && H.length > 0 && U.length === 0 && /* @__PURE__ */ u("div", {
131
132
  className: "px-3 py-4 text-xs text-text-secondary text-center",
132
133
  children: [
133
134
  "No actions match \"",
134
- x,
135
+ S,
135
136
  "\"."
136
137
  ]
137
138
  }),
138
- H.map((e) => {
139
- let t = e.id === y;
140
- return /* @__PURE__ */ c("button", {
139
+ U.map((e) => {
140
+ let t = e.id === b;
141
+ return /* @__PURE__ */ l("button", {
141
142
  type: "button",
142
- onClick: () => b(e.id),
143
+ onClick: () => x(e.id),
143
144
  className: `w-full text-left px-3 py-2.5 hover:bg-bg-secondary transition-colors ${t ? "bg-primary/5" : ""}`,
144
- children: /* @__PURE__ */ l("div", {
145
+ children: /* @__PURE__ */ u("div", {
145
146
  className: "flex items-start gap-2.5",
146
147
  children: [
147
- /* @__PURE__ */ c("div", {
148
+ /* @__PURE__ */ l("div", {
148
149
  className: `p-1 rounded-md flex-shrink-0 ${t ? "bg-primary/10 text-primary" : "bg-bg-sunken text-text-tertiary"}`,
149
- children: /* @__PURE__ */ c(o, { size: 14 })
150
+ children: /* @__PURE__ */ l(s, { size: 14 })
150
151
  }),
151
- /* @__PURE__ */ l("div", {
152
+ /* @__PURE__ */ u("div", {
152
153
  className: "flex-1 min-w-0",
153
- children: [/* @__PURE__ */ c("p", {
154
+ children: [/* @__PURE__ */ l("p", {
154
155
  className: "text-sm font-medium text-text-primary truncate",
155
156
  children: e.displayName || e.name
156
- }), /* @__PURE__ */ l("p", {
157
+ }), /* @__PURE__ */ u("p", {
157
158
  className: "text-xs text-text-tertiary mt-0.5",
158
159
  children: [
159
160
  e.actionType,
@@ -162,7 +163,7 @@ function p({ isOpen: p, onClose: m, onSubmit: h, loading: g, prefillActionId: _
162
163
  ]
163
164
  })]
164
165
  }),
165
- t && /* @__PURE__ */ c("span", {
166
+ t && /* @__PURE__ */ l("span", {
166
167
  className: "text-xs font-medium text-primary flex-shrink-0",
167
168
  children: "Selected"
168
169
  })
@@ -171,122 +172,123 @@ function p({ isOpen: p, onClose: m, onSubmit: h, loading: g, prefillActionId: _
171
172
  }, e.id);
172
173
  })
173
174
  ]
174
- })] })
175
+ })] }),
176
+ W && /* @__PURE__ */ l(n, { action: W })
175
177
  ]
176
178
  }),
177
- /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
178
- className: f,
179
- children: v("vibecontrols.calendar.schedule.title", "Title")
180
- }), /* @__PURE__ */ c("input", {
179
+ /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
180
+ className: p,
181
+ children: y("vibecontrols.calendar.schedule.title", "Title")
182
+ }), /* @__PURE__ */ l("input", {
181
183
  "aria-label": "e.g. Run test suite",
182
184
  type: "text",
183
- value: C,
184
- onChange: (e) => w(e.target.value),
185
+ value: w,
186
+ onChange: (e) => T(e.target.value),
185
187
  placeholder: "e.g. Run test suite",
186
- className: u,
188
+ className: d,
187
189
  required: !0
188
190
  })] }),
189
- /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
190
- className: f,
191
- children: v("vibecontrols.calendar.schedule.description", "Description")
192
- }), /* @__PURE__ */ c("input", {
191
+ /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
192
+ className: p,
193
+ children: y("vibecontrols.calendar.schedule.description", "Description")
194
+ }), /* @__PURE__ */ l("input", {
193
195
  "aria-label": "Optional description",
194
196
  type: "text",
195
- value: T,
196
- onChange: (e) => E(e.target.value),
197
+ value: E,
198
+ onChange: (e) => D(e.target.value),
197
199
  placeholder: "Optional description",
198
- className: u
200
+ className: d
199
201
  })] }),
200
- /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
201
- className: f,
202
- children: v("vibecontrols.calendar.schedule.schedule", "Schedule")
203
- }), /* @__PURE__ */ l("select", {
204
- value: D,
205
- onChange: (e) => O(e.target.value),
206
- className: u,
202
+ /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
203
+ className: p,
204
+ children: y("vibecontrols.calendar.schedule.schedule", "Schedule")
205
+ }), /* @__PURE__ */ u("select", {
206
+ value: O,
207
+ onChange: (e) => k(e.target.value),
208
+ className: d,
207
209
  children: [
208
- /* @__PURE__ */ c("option", {
210
+ /* @__PURE__ */ l("option", {
209
211
  value: "ONE_TIME",
210
212
  children: "One Time"
211
213
  }),
212
- /* @__PURE__ */ c("option", {
214
+ /* @__PURE__ */ l("option", {
213
215
  value: "CRON",
214
216
  children: "Cron Expression"
215
217
  }),
216
- /* @__PURE__ */ c("option", {
218
+ /* @__PURE__ */ l("option", {
217
219
  value: "FIXED_INTERVAL",
218
220
  children: "Fixed Interval"
219
221
  })
220
222
  ]
221
223
  })] }),
222
- D === "ONE_TIME" && /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
223
- className: f,
224
- children: v("vibecontrols.calendar.schedule.runAt", "Run At")
225
- }), /* @__PURE__ */ c("input", {
224
+ O === "ONE_TIME" && /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
225
+ className: p,
226
+ children: y("vibecontrols.calendar.schedule.runAt", "Run At")
227
+ }), /* @__PURE__ */ l("input", {
226
228
  "aria-label": "control",
227
229
  type: "datetime-local",
228
- value: k,
229
- onChange: (e) => A(e.target.value),
230
- className: u,
230
+ value: A,
231
+ onChange: (e) => j(e.target.value),
232
+ className: d,
231
233
  required: !0
232
234
  })] }),
233
- D === "CRON" && /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
235
+ O === "CRON" && /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
234
236
  htmlFor: "scheduletaskmodal-40",
235
- className: f,
237
+ className: p,
236
238
  children: "Cron Expression"
237
- }), /* @__PURE__ */ c("input", {
239
+ }), /* @__PURE__ */ l("input", {
238
240
  id: "scheduletaskmodal-40",
239
241
  "aria-label": "*/5 * * * * (every 5 minutes)",
240
242
  type: "text",
241
- value: j,
242
- onChange: (e) => M(e.target.value),
243
+ value: M,
244
+ onChange: (e) => N(e.target.value),
243
245
  placeholder: "*/5 * * * * (every 5 minutes)",
244
- className: d,
246
+ className: f,
245
247
  required: !0
246
248
  })] }),
247
- D === "FIXED_INTERVAL" && /* @__PURE__ */ l("div", {
249
+ O === "FIXED_INTERVAL" && /* @__PURE__ */ u("div", {
248
250
  className: "flex gap-2",
249
- children: [/* @__PURE__ */ l("div", {
251
+ children: [/* @__PURE__ */ u("div", {
250
252
  className: "flex-1",
251
- children: [/* @__PURE__ */ c("label", {
253
+ children: [/* @__PURE__ */ l("label", {
252
254
  htmlFor: "scheduletaskmodal-39",
253
- className: f,
255
+ className: p,
254
256
  children: "Every"
255
- }), /* @__PURE__ */ c("input", {
257
+ }), /* @__PURE__ */ l("input", {
256
258
  id: "scheduletaskmodal-39",
257
259
  "aria-label": "control",
258
260
  type: "number",
259
- value: N,
260
- onChange: (e) => P(Number(e.target.value)),
261
+ value: P,
262
+ onChange: (e) => F(Number(e.target.value)),
261
263
  min: 1,
262
- className: u,
264
+ className: d,
263
265
  required: !0
264
266
  })]
265
- }), /* @__PURE__ */ l("div", {
267
+ }), /* @__PURE__ */ u("div", {
266
268
  className: "flex-1",
267
- children: [/* @__PURE__ */ c("label", {
269
+ children: [/* @__PURE__ */ l("label", {
268
270
  htmlFor: "scheduletaskmodal-38",
269
- className: f,
271
+ className: p,
270
272
  children: "Unit"
271
- }), /* @__PURE__ */ l("select", {
273
+ }), /* @__PURE__ */ u("select", {
272
274
  id: "scheduletaskmodal-38",
273
- value: F,
274
- onChange: (e) => I(e.target.value),
275
- className: u,
275
+ value: I,
276
+ onChange: (e) => L(e.target.value),
277
+ className: d,
276
278
  children: [
277
- /* @__PURE__ */ c("option", {
279
+ /* @__PURE__ */ l("option", {
278
280
  value: "seconds",
279
281
  children: "Seconds"
280
282
  }),
281
- /* @__PURE__ */ c("option", {
283
+ /* @__PURE__ */ l("option", {
282
284
  value: "minutes",
283
285
  children: "Minutes"
284
286
  }),
285
- /* @__PURE__ */ c("option", {
287
+ /* @__PURE__ */ l("option", {
286
288
  value: "hours",
287
289
  children: "Hours"
288
290
  }),
289
- /* @__PURE__ */ c("option", {
291
+ /* @__PURE__ */ l("option", {
290
292
  value: "days",
291
293
  children: "Days"
292
294
  })
@@ -294,29 +296,29 @@ function p({ isOpen: p, onClose: m, onSubmit: h, loading: g, prefillActionId: _
294
296
  })]
295
297
  })]
296
298
  }),
297
- /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("label", {
298
- className: f,
299
- children: v("vibecontrols.calendar.schedule.timezone", "Timezone")
300
- }), /* @__PURE__ */ c("input", {
299
+ /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("label", {
300
+ className: p,
301
+ children: y("vibecontrols.calendar.schedule.timezone", "Timezone")
302
+ }), /* @__PURE__ */ l("input", {
301
303
  "aria-label": "control",
302
304
  type: "text",
303
- value: L,
304
- onChange: (e) => R(e.target.value),
305
- className: u
305
+ value: R,
306
+ onChange: (e) => z(e.target.value),
307
+ className: d
306
308
  })] }),
307
- /* @__PURE__ */ l("div", {
309
+ /* @__PURE__ */ u("div", {
308
310
  className: "flex items-center justify-end gap-3 pt-4 border-t border-border-default",
309
- children: [/* @__PURE__ */ c("button", {
311
+ children: [/* @__PURE__ */ l("button", {
310
312
  type: "button",
311
- onClick: m,
313
+ onClick: h,
312
314
  className: "px-4 py-2 text-sm text-text-secondary hover:text-text-primary transition-colors",
313
- children: v("vibecontrols.calendar.schedule.cancel", "Cancel")
314
- }), /* @__PURE__ */ c("button", {
315
+ children: y("vibecontrols.calendar.schedule.cancel", "Cancel")
316
+ }), /* @__PURE__ */ l("button", {
315
317
  type: "submit",
316
- disabled: !G,
318
+ disabled: !K,
317
319
  className: "px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-lg hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-not-allowed",
318
- title: y ? void 0 : v("vibecontrols.calendar.schedule.selectActionFirst", "Select an Action first"),
319
- children: g ? v("vibecontrols.calendar.schedule.creating", "Creating...") : v("vibecontrols.calendar.schedule.scheduleBtn", "Schedule")
320
+ title: b ? void 0 : y("vibecontrols.calendar.schedule.selectActionFirst", "Select an Action first"),
321
+ children: _ ? y("vibecontrols.calendar.schedule.creating", "Creating...") : y("vibecontrols.calendar.schedule.scheduleBtn", "Schedule")
320
322
  })]
321
323
  })
322
324
  ]
@@ -325,6 +327,6 @@ function p({ isOpen: p, onClose: m, onSubmit: h, loading: g, prefillActionId: _
325
327
  });
326
328
  }
327
329
  //#endregion
328
- export { p as ScheduleTaskModal };
330
+ export { m as ScheduleTaskModal };
329
331
 
330
332
  //# sourceMappingURL=ScheduleTaskModal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ScheduleTaskModal.js","names":[],"sources":["../../../src/components/vibecalendar/ScheduleTaskModal.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { X, Zap, Search } from 'lucide-react';\nimport { useListActionsQuery } from '@/generated/wspace-operations';\nimport type { Action } from '@/generated/wspace-types';\nimport { useTr } from '../../shared/hooks/useTr';\n\ntype ActionPickItem = Pick<\n Action,\n 'id' | 'name' | 'displayName' | 'description' | 'actionType' | 'triggerType'\n>;\n\ninterface ScheduleTaskModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSubmit: (input: ScheduleTaskInput) => void;\n // Legacy prop kept for compatibility; unused in Action-only mode.\n agents?: Array<{ id: string; name: string }>;\n loading?: boolean;\n // When provided, the picker is locked to this action (user navigated\n // in from \"Add to calendar\" on the Actions page). Otherwise the user\n // picks from a searchable dropdown of their actions.\n prefillActionId?: string;\n}\n\n/**\n * Calendar entries always delegate execution to a VibeControls Action.\n * Agent, command, script, and webhook fields come from the Action\n * definition at execution time — this modal only collects the calendar\n * metadata and the schedule.\n */\nexport interface ScheduleTaskInput {\n calendarId: string;\n title: string;\n description?: string;\n scheduleType: 'ONE_TIME' | 'CRON' | 'RRULE' | 'FIXED_INTERVAL';\n scheduledAt?: string;\n cronExpression?: string;\n rrule?: string;\n interval?: number;\n intervalUnit?: string;\n timezone: string;\n actionId: string;\n}\n\nconst INPUT_CLASS =\n 'w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-lg text-sm text-text-primary placeholder-text-placeholder focus:outline-none focus:border-border-primary';\nconst MONO_INPUT_CLASS = `${INPUT_CLASS} font-mono`;\nconst LABEL_CLASS = 'block text-sm font-medium text-text-secondary mb-1';\n\nexport function ScheduleTaskModal({\n isOpen,\n onClose,\n onSubmit,\n loading,\n prefillActionId,\n}: ScheduleTaskModalProps) {\n const tr = useTr();\n const [selectedActionId, setSelectedActionId] = useState<string>(prefillActionId ?? '');\n const [actionSearch, setActionSearch] = useState('');\n const [title, setTitle] = useState('');\n const [description, setDescription] = useState('');\n const [scheduleType, setScheduleType] = useState<\n 'ONE_TIME' | 'CRON' | 'RRULE' | 'FIXED_INTERVAL'\n >('ONE_TIME');\n const [scheduledAt, setScheduledAt] = useState('');\n const [cronExpression, setCronExpression] = useState('');\n const [interval, setInterval] = useState(60);\n const [intervalUnit, setIntervalUnit] = useState('minutes');\n const [timezone, setTimezone] = useState(Intl.DateTimeFormat().resolvedOptions().timeZone);\n\n const { data: actionsData, loading: actionsLoading } = useListActionsQuery({\n variables: { pagination: { limit: 100 } },\n skip: !isOpen,\n fetchPolicy: 'cache-and-network',\n });\n\n const allActions = useMemo<ActionPickItem[]>(\n () => (actionsData?.actions?.items ?? []) as ActionPickItem[],\n [actionsData?.actions?.items]\n );\n\n const filteredActions = useMemo(() => {\n if (!actionSearch.trim()) return allActions;\n const q = actionSearch.trim().toLowerCase();\n return allActions.filter(\n (a: ActionPickItem) =>\n a.name?.toLowerCase().includes(q) ||\n a.displayName?.toLowerCase().includes(q) ||\n a.description?.toLowerCase().includes(q)\n );\n }, [allActions, actionSearch]);\n\n const selectedAction = useMemo(\n () => allActions.find((a: ActionPickItem) => a.id === selectedActionId),\n [allActions, selectedActionId]\n );\n\n if (!isOpen) return null;\n\n const isActionLocked = Boolean(prefillActionId);\n const canSubmit = Boolean(selectedActionId) && !loading;\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if (!selectedActionId) return;\n onSubmit({\n calendarId: '',\n title,\n description: description || undefined,\n scheduleType,\n scheduledAt: scheduleType === 'ONE_TIME' ? new Date(scheduledAt).toISOString() : undefined,\n cronExpression: scheduleType === 'CRON' ? cronExpression : undefined,\n interval: scheduleType === 'FIXED_INTERVAL' ? interval : undefined,\n intervalUnit: scheduleType === 'FIXED_INTERVAL' ? intervalUnit : undefined,\n timezone,\n actionId: selectedActionId,\n });\n };\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (onClose as (...a: unknown[]) => unknown)();\n }\n }}\n className=\"absolute inset-0 bg-bg-overlay\"\n onClick={onClose}\n />\n <div className=\"relative bg-bg-surface border border-border-default rounded-xl shadow-xl w-full max-w-lg max-h-[90vh] overflow-y-auto\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-border-default\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {isActionLocked\n ? tr('vibecontrols.calendar.schedule.addActionToCalendar', 'Add Action to Calendar')\n : tr(\n 'vibecontrols.calendar.schedule.scheduleActionOnCalendar',\n 'Schedule Action on Calendar'\n )}\n </h2>\n <button type=\"button\" onClick={onClose} className=\"p-1 rounded hover:bg-bg-secondary\">\n <X size={18} />\n </button>\n </div>\n\n {/* Form */}\n <form onSubmit={handleSubmit} className=\"px-6 py-4 space-y-4\">\n {/* Action Picker — always required */}\n <div className=\"space-y-2\">\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.actionToSchedule', 'Action to Schedule')} *\n </label>\n <p className=\"text-xs text-text-tertiary -mt-1\">\n Calendar entries trigger VibeControls Actions. Agent, command, and webhook details\n come from the Action definition.\n </p>\n\n {isActionLocked && selectedAction && (\n <div className=\"flex items-start gap-3 p-3 rounded-lg border border-border-default bg-bg-secondary\">\n <div className=\"p-1.5 rounded-md bg-primary/10 text-primary flex-shrink-0\">\n <Zap size={16} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-text-primary\">\n {selectedAction.displayName || selectedAction.name}\n </p>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n {selectedAction.actionType} · {selectedAction.triggerType}\n </p>\n {selectedAction.description && (\n <p className=\"text-xs text-text-tertiary mt-1 line-clamp-2\">\n {selectedAction.description}\n </p>\n )}\n </div>\n </div>\n )}\n\n {isActionLocked && !selectedAction && actionsLoading && (\n <div className=\"p-3 rounded-lg border border-border-default bg-bg-secondary text-xs text-text-secondary\">\n Loading action…\n </div>\n )}\n\n {isActionLocked && !selectedAction && !actionsLoading && (\n <div className=\"p-3 rounded-lg border border-status-error-border bg-status-error-bg-subtle text-xs text-status-error-text\">\n Action not found. It may have been deleted.\n </div>\n )}\n\n {!isActionLocked && (\n <>\n <div className=\"relative\">\n <Search\n size={16}\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-text-tertiary\"\n />\n <input\n aria-label=\"Search actions by name…\"\n type=\"text\"\n value={actionSearch}\n onChange={(e) => setActionSearch(e.target.value)}\n placeholder=\"Search actions by name…\"\n className={`${INPUT_CLASS} pl-9`}\n />\n </div>\n\n <div className=\"max-h-40 overflow-y-auto border border-border-default rounded-lg divide-y divide-border-default\">\n {actionsLoading && allActions.length === 0 && (\n <div className=\"px-3 py-4 text-xs text-text-secondary text-center\">\n Loading actions…\n </div>\n )}\n {!actionsLoading && allActions.length === 0 && (\n <div className=\"px-3 py-4 text-xs text-text-secondary text-center\">\n No actions yet. Create an Action in VibeControls first, then come back to\n schedule it.\n </div>\n )}\n {!actionsLoading && allActions.length > 0 && filteredActions.length === 0 && (\n <div className=\"px-3 py-4 text-xs text-text-secondary text-center\">\n No actions match \"{actionSearch}\".\n </div>\n )}\n {filteredActions.map((action: ActionPickItem) => {\n const isSelected = action.id === selectedActionId;\n return (\n <button\n key={action.id}\n type=\"button\"\n onClick={() => setSelectedActionId(action.id)}\n className={`w-full text-left px-3 py-2.5 hover:bg-bg-secondary transition-colors ${\n isSelected ? 'bg-primary/5' : ''\n }`}\n >\n <div className=\"flex items-start gap-2.5\">\n <div\n className={`p-1 rounded-md flex-shrink-0 ${\n isSelected\n ? 'bg-primary/10 text-primary'\n : 'bg-bg-sunken text-text-tertiary'\n }`}\n >\n <Zap size={14} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-text-primary truncate\">\n {action.displayName || action.name}\n </p>\n <p className=\"text-xs text-text-tertiary mt-0.5\">\n {action.actionType} · {action.triggerType}\n </p>\n </div>\n {isSelected && (\n <span className=\"text-xs font-medium text-primary flex-shrink-0\">\n Selected\n </span>\n )}\n </div>\n </button>\n );\n })}\n </div>\n </>\n )}\n </div>\n\n {/* Title */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.title', 'Title')}\n </label>\n <input\n aria-label=\"e.g. Run test suite\"\n type=\"text\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"e.g. Run test suite\"\n className={INPUT_CLASS}\n required\n />\n </div>\n\n {/* Description */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.description', 'Description')}\n </label>\n <input\n aria-label=\"Optional description\"\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional description\"\n className={INPUT_CLASS}\n />\n </div>\n\n {/* Schedule Type */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.schedule', 'Schedule')}\n </label>\n <select\n value={scheduleType}\n onChange={(e) => setScheduleType(e.target.value as typeof scheduleType)}\n className={INPUT_CLASS}\n >\n <option value=\"ONE_TIME\">One Time</option>\n <option value=\"CRON\">Cron Expression</option>\n <option value=\"FIXED_INTERVAL\">Fixed Interval</option>\n </select>\n </div>\n\n {/* Schedule-specific fields */}\n {scheduleType === 'ONE_TIME' && (\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.runAt', 'Run At')}\n </label>\n <input\n aria-label=\"control\"\n type=\"datetime-local\"\n value={scheduledAt}\n onChange={(e) => setScheduledAt(e.target.value)}\n className={INPUT_CLASS}\n required\n />\n </div>\n )}\n\n {scheduleType === 'CRON' && (\n <div>\n <label htmlFor=\"scheduletaskmodal-40\" className={LABEL_CLASS}>\n Cron Expression\n </label>\n <input\n id=\"scheduletaskmodal-40\"\n aria-label=\"*/5 * * * * (every 5 minutes)\"\n type=\"text\"\n value={cronExpression}\n onChange={(e) => setCronExpression(e.target.value)}\n placeholder=\"*/5 * * * * (every 5 minutes)\"\n className={MONO_INPUT_CLASS}\n required\n />\n </div>\n )}\n\n {scheduleType === 'FIXED_INTERVAL' && (\n <div className=\"flex gap-2\">\n <div className=\"flex-1\">\n <label htmlFor=\"scheduletaskmodal-39\" className={LABEL_CLASS}>\n Every\n </label>\n <input\n id=\"scheduletaskmodal-39\"\n aria-label=\"control\"\n type=\"number\"\n value={interval}\n onChange={(e) => setInterval(Number(e.target.value))}\n min={1}\n className={INPUT_CLASS}\n required\n />\n </div>\n <div className=\"flex-1\">\n <label htmlFor=\"scheduletaskmodal-38\" className={LABEL_CLASS}>\n Unit\n </label>\n <select\n id=\"scheduletaskmodal-38\"\n value={intervalUnit}\n onChange={(e) => setIntervalUnit(e.target.value)}\n className={INPUT_CLASS}\n >\n <option value=\"seconds\">Seconds</option>\n <option value=\"minutes\">Minutes</option>\n <option value=\"hours\">Hours</option>\n <option value=\"days\">Days</option>\n </select>\n </div>\n </div>\n )}\n\n {/* Timezone */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.timezone', 'Timezone')}\n </label>\n <input\n aria-label=\"control\"\n type=\"text\"\n value={timezone}\n onChange={(e) => setTimezone(e.target.value)}\n className={INPUT_CLASS}\n />\n </div>\n\n {/* Actions */}\n <div className=\"flex items-center justify-end gap-3 pt-4 border-t border-border-default\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"px-4 py-2 text-sm text-text-secondary hover:text-text-primary transition-colors\"\n >\n {tr('vibecontrols.calendar.schedule.cancel', 'Cancel')}\n </button>\n <button\n type=\"submit\"\n disabled={!canSubmit}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-lg hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-not-allowed\"\n title={\n !selectedActionId\n ? tr('vibecontrols.calendar.schedule.selectActionFirst', 'Select an Action first')\n : undefined\n }\n >\n {loading\n ? tr('vibecontrols.calendar.schedule.creating', 'Creating...')\n : tr('vibecontrols.calendar.schedule.scheduleBtn', 'Schedule')}\n </button>\n </div>\n </form>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ScheduleTaskModal.js","names":[],"sources":["../../../src/components/vibecalendar/ScheduleTaskModal.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { X, Zap, Search } from 'lucide-react';\nimport { useListActionsQuery } from '@/generated/wspace-operations';\nimport type { Action } from '@/generated/wspace-types';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { ActionAgentTargetNotice } from '../common/ActionAgentTargetNotice';\n\ntype ActionPickItem = Pick<\n Action,\n | 'id'\n | 'name'\n | 'displayName'\n | 'description'\n | 'actionType'\n | 'triggerType'\n | 'targetAgentId'\n | 'targetPlatformFilter'\n>;\n\ninterface ScheduleTaskModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSubmit: (input: ScheduleTaskInput) => void;\n // Legacy prop kept for compatibility; unused in Action-only mode.\n agents?: Array<{ id: string; name: string }>;\n loading?: boolean;\n // When provided, the picker is locked to this action (user navigated\n // in from \"Add to calendar\" on the Actions page). Otherwise the user\n // picks from a searchable dropdown of their actions.\n prefillActionId?: string;\n}\n\n/**\n * Calendar entries always delegate execution to a VibeControls Action.\n * Agent, command, script, and webhook fields come from the Action\n * definition at execution time — this modal only collects the calendar\n * metadata and the schedule.\n */\nexport interface ScheduleTaskInput {\n calendarId: string;\n title: string;\n description?: string;\n scheduleType: 'ONE_TIME' | 'CRON' | 'RRULE' | 'FIXED_INTERVAL';\n scheduledAt?: string;\n cronExpression?: string;\n rrule?: string;\n interval?: number;\n intervalUnit?: string;\n timezone: string;\n actionId: string;\n}\n\nconst INPUT_CLASS =\n 'w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-lg text-sm text-text-primary placeholder-text-placeholder focus:outline-none focus:border-border-primary';\nconst MONO_INPUT_CLASS = `${INPUT_CLASS} font-mono`;\nconst LABEL_CLASS = 'block text-sm font-medium text-text-secondary mb-1';\n\nexport function ScheduleTaskModal({\n isOpen,\n onClose,\n onSubmit,\n loading,\n prefillActionId,\n}: ScheduleTaskModalProps) {\n const tr = useTr();\n const [selectedActionId, setSelectedActionId] = useState<string>(prefillActionId ?? '');\n const [actionSearch, setActionSearch] = useState('');\n const [title, setTitle] = useState('');\n const [description, setDescription] = useState('');\n const [scheduleType, setScheduleType] = useState<\n 'ONE_TIME' | 'CRON' | 'RRULE' | 'FIXED_INTERVAL'\n >('ONE_TIME');\n const [scheduledAt, setScheduledAt] = useState('');\n const [cronExpression, setCronExpression] = useState('');\n const [interval, setInterval] = useState(60);\n const [intervalUnit, setIntervalUnit] = useState('minutes');\n const [timezone, setTimezone] = useState(Intl.DateTimeFormat().resolvedOptions().timeZone);\n\n const { data: actionsData, loading: actionsLoading } = useListActionsQuery({\n variables: { pagination: { limit: 100 } },\n skip: !isOpen,\n fetchPolicy: 'cache-and-network',\n });\n\n const allActions = useMemo<ActionPickItem[]>(\n () => (actionsData?.actions?.items ?? []) as ActionPickItem[],\n [actionsData?.actions?.items]\n );\n\n const filteredActions = useMemo(() => {\n if (!actionSearch.trim()) return allActions;\n const q = actionSearch.trim().toLowerCase();\n return allActions.filter(\n (a: ActionPickItem) =>\n a.name?.toLowerCase().includes(q) ||\n a.displayName?.toLowerCase().includes(q) ||\n a.description?.toLowerCase().includes(q)\n );\n }, [allActions, actionSearch]);\n\n const selectedAction = useMemo(\n () => allActions.find((a: ActionPickItem) => a.id === selectedActionId),\n [allActions, selectedActionId]\n );\n\n if (!isOpen) return null;\n\n const isActionLocked = Boolean(prefillActionId);\n const canSubmit = Boolean(selectedActionId) && !loading;\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if (!selectedActionId) return;\n onSubmit({\n calendarId: '',\n title,\n description: description || undefined,\n scheduleType,\n scheduledAt: scheduleType === 'ONE_TIME' ? new Date(scheduledAt).toISOString() : undefined,\n cronExpression: scheduleType === 'CRON' ? cronExpression : undefined,\n interval: scheduleType === 'FIXED_INTERVAL' ? interval : undefined,\n intervalUnit: scheduleType === 'FIXED_INTERVAL' ? intervalUnit : undefined,\n timezone,\n actionId: selectedActionId,\n });\n };\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (onClose as (...a: unknown[]) => unknown)();\n }\n }}\n className=\"absolute inset-0 bg-bg-overlay\"\n onClick={onClose}\n />\n <div className=\"relative bg-bg-surface border border-border-default rounded-xl shadow-xl w-full max-w-lg max-h-[90vh] overflow-y-auto\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-6 py-4 border-b border-border-default\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {isActionLocked\n ? tr('vibecontrols.calendar.schedule.addActionToCalendar', 'Add Action to Calendar')\n : tr(\n 'vibecontrols.calendar.schedule.scheduleActionOnCalendar',\n 'Schedule Action on Calendar'\n )}\n </h2>\n <button type=\"button\" onClick={onClose} className=\"p-1 rounded hover:bg-bg-secondary\">\n <X size={18} />\n </button>\n </div>\n\n {/* Form */}\n <form onSubmit={handleSubmit} className=\"px-6 py-4 space-y-4\">\n {/* Action Picker — always required */}\n <div className=\"space-y-2\">\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.actionToSchedule', 'Action to Schedule')} *\n </label>\n <p className=\"text-xs text-text-tertiary -mt-1\">\n Calendar entries trigger VibeControls Actions. Agent, command, and webhook details\n come from the Action definition.\n </p>\n\n {isActionLocked && selectedAction && (\n <div className=\"flex items-start gap-3 p-3 rounded-lg border border-border-default bg-bg-secondary\">\n <div className=\"p-1.5 rounded-md bg-primary/10 text-primary flex-shrink-0\">\n <Zap size={16} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-text-primary\">\n {selectedAction.displayName || selectedAction.name}\n </p>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n {selectedAction.actionType} · {selectedAction.triggerType}\n </p>\n {selectedAction.description && (\n <p className=\"text-xs text-text-tertiary mt-1 line-clamp-2\">\n {selectedAction.description}\n </p>\n )}\n </div>\n </div>\n )}\n\n {isActionLocked && !selectedAction && actionsLoading && (\n <div className=\"p-3 rounded-lg border border-border-default bg-bg-secondary text-xs text-text-secondary\">\n Loading action…\n </div>\n )}\n\n {isActionLocked && !selectedAction && !actionsLoading && (\n <div className=\"p-3 rounded-lg border border-status-error-border bg-status-error-bg-subtle text-xs text-status-error-text\">\n Action not found. It may have been deleted.\n </div>\n )}\n\n {!isActionLocked && (\n <>\n <div className=\"relative\">\n <Search\n size={16}\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-text-tertiary\"\n />\n <input\n aria-label=\"Search actions by name…\"\n type=\"text\"\n value={actionSearch}\n onChange={(e) => setActionSearch(e.target.value)}\n placeholder=\"Search actions by name…\"\n className={`${INPUT_CLASS} pl-9`}\n />\n </div>\n\n <div className=\"max-h-40 overflow-y-auto border border-border-default rounded-lg divide-y divide-border-default\">\n {actionsLoading && allActions.length === 0 && (\n <div className=\"px-3 py-4 text-xs text-text-secondary text-center\">\n Loading actions…\n </div>\n )}\n {!actionsLoading && allActions.length === 0 && (\n <div className=\"px-3 py-4 text-xs text-text-secondary text-center\">\n No actions yet. Create an Action in VibeControls first, then come back to\n schedule it.\n </div>\n )}\n {!actionsLoading && allActions.length > 0 && filteredActions.length === 0 && (\n <div className=\"px-3 py-4 text-xs text-text-secondary text-center\">\n No actions match \"{actionSearch}\".\n </div>\n )}\n {filteredActions.map((action: ActionPickItem) => {\n const isSelected = action.id === selectedActionId;\n return (\n <button\n key={action.id}\n type=\"button\"\n onClick={() => setSelectedActionId(action.id)}\n className={`w-full text-left px-3 py-2.5 hover:bg-bg-secondary transition-colors ${\n isSelected ? 'bg-primary/5' : ''\n }`}\n >\n <div className=\"flex items-start gap-2.5\">\n <div\n className={`p-1 rounded-md flex-shrink-0 ${\n isSelected\n ? 'bg-primary/10 text-primary'\n : 'bg-bg-sunken text-text-tertiary'\n }`}\n >\n <Zap size={14} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-text-primary truncate\">\n {action.displayName || action.name}\n </p>\n <p className=\"text-xs text-text-tertiary mt-0.5\">\n {action.actionType} · {action.triggerType}\n </p>\n </div>\n {isSelected && (\n <span className=\"text-xs font-medium text-primary flex-shrink-0\">\n Selected\n </span>\n )}\n </div>\n </button>\n );\n })}\n </div>\n </>\n )}\n\n {/* Tell the user which agent this action runs on, and warn if that\n agent is unhealthy or gone — before the schedule is created. */}\n {selectedAction && <ActionAgentTargetNotice action={selectedAction} />}\n </div>\n\n {/* Title */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.title', 'Title')}\n </label>\n <input\n aria-label=\"e.g. Run test suite\"\n type=\"text\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"e.g. Run test suite\"\n className={INPUT_CLASS}\n required\n />\n </div>\n\n {/* Description */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.description', 'Description')}\n </label>\n <input\n aria-label=\"Optional description\"\n type=\"text\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional description\"\n className={INPUT_CLASS}\n />\n </div>\n\n {/* Schedule Type */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.schedule', 'Schedule')}\n </label>\n <select\n value={scheduleType}\n onChange={(e) => setScheduleType(e.target.value as typeof scheduleType)}\n className={INPUT_CLASS}\n >\n <option value=\"ONE_TIME\">One Time</option>\n <option value=\"CRON\">Cron Expression</option>\n <option value=\"FIXED_INTERVAL\">Fixed Interval</option>\n </select>\n </div>\n\n {/* Schedule-specific fields */}\n {scheduleType === 'ONE_TIME' && (\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.runAt', 'Run At')}\n </label>\n <input\n aria-label=\"control\"\n type=\"datetime-local\"\n value={scheduledAt}\n onChange={(e) => setScheduledAt(e.target.value)}\n className={INPUT_CLASS}\n required\n />\n </div>\n )}\n\n {scheduleType === 'CRON' && (\n <div>\n <label htmlFor=\"scheduletaskmodal-40\" className={LABEL_CLASS}>\n Cron Expression\n </label>\n <input\n id=\"scheduletaskmodal-40\"\n aria-label=\"*/5 * * * * (every 5 minutes)\"\n type=\"text\"\n value={cronExpression}\n onChange={(e) => setCronExpression(e.target.value)}\n placeholder=\"*/5 * * * * (every 5 minutes)\"\n className={MONO_INPUT_CLASS}\n required\n />\n </div>\n )}\n\n {scheduleType === 'FIXED_INTERVAL' && (\n <div className=\"flex gap-2\">\n <div className=\"flex-1\">\n <label htmlFor=\"scheduletaskmodal-39\" className={LABEL_CLASS}>\n Every\n </label>\n <input\n id=\"scheduletaskmodal-39\"\n aria-label=\"control\"\n type=\"number\"\n value={interval}\n onChange={(e) => setInterval(Number(e.target.value))}\n min={1}\n className={INPUT_CLASS}\n required\n />\n </div>\n <div className=\"flex-1\">\n <label htmlFor=\"scheduletaskmodal-38\" className={LABEL_CLASS}>\n Unit\n </label>\n <select\n id=\"scheduletaskmodal-38\"\n value={intervalUnit}\n onChange={(e) => setIntervalUnit(e.target.value)}\n className={INPUT_CLASS}\n >\n <option value=\"seconds\">Seconds</option>\n <option value=\"minutes\">Minutes</option>\n <option value=\"hours\">Hours</option>\n <option value=\"days\">Days</option>\n </select>\n </div>\n </div>\n )}\n\n {/* Timezone */}\n <div>\n <label className={LABEL_CLASS}>\n {tr('vibecontrols.calendar.schedule.timezone', 'Timezone')}\n </label>\n <input\n aria-label=\"control\"\n type=\"text\"\n value={timezone}\n onChange={(e) => setTimezone(e.target.value)}\n className={INPUT_CLASS}\n />\n </div>\n\n {/* Actions */}\n <div className=\"flex items-center justify-end gap-3 pt-4 border-t border-border-default\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"px-4 py-2 text-sm text-text-secondary hover:text-text-primary transition-colors\"\n >\n {tr('vibecontrols.calendar.schedule.cancel', 'Cancel')}\n </button>\n <button\n type=\"submit\"\n disabled={!canSubmit}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-lg hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-not-allowed\"\n title={\n !selectedActionId\n ? tr('vibecontrols.calendar.schedule.selectActionFirst', 'Select an Action first')\n : undefined\n }\n >\n {loading\n ? tr('vibecontrols.calendar.schedule.creating', 'Creating...')\n : tr('vibecontrols.calendar.schedule.scheduleBtn', 'Schedule')}\n </button>\n </div>\n </form>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}