@burdenoff/microfe-vibecontrols 2026.528.6 → 2026.528.7

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.
@@ -2,37 +2,37 @@ import { useCreateVibeCalendarTaskMutation as e, useTriggerVibeCalendarTaskNowMu
2
2
  import { useVibeControls as n, useVibeNavigate as r } from "../providers/VibeControlsProvider.js";
3
3
  import { LoadingState as i } from "../components/shared/LoadingState.js";
4
4
  import { VIBE_PERMISSIONS as a } from "../constants/permissions.js";
5
- import { VibeCalendarHeader as o } from "../components/vibecalendar/VibeCalendarHeader.js";
6
- import { VibeCalMonthView as s } from "../components/vibecalendar/VibeCalMonthView.js";
7
- import { VibeCalWeekView as ee } from "../components/vibecalendar/VibeCalWeekView.js";
8
- import { VibeCalDayView as te } from "../components/vibecalendar/VibeCalDayView.js";
9
- import { VibeCalAgendaView as ne } from "../components/vibecalendar/VibeCalAgendaView.js";
10
- import { ScheduleTaskModal as c } from "../components/vibecalendar/ScheduleTaskModal.js";
11
- import { LogsDrawer as l } from "../components/vibecalendar/LogsDrawer.js";
5
+ import { VibeCalendarHeader as ee } from "../components/vibecalendar/VibeCalendarHeader.js";
6
+ import { VibeCalMonthView as te } from "../components/vibecalendar/VibeCalMonthView.js";
7
+ import { VibeCalWeekView as o } from "../components/vibecalendar/VibeCalWeekView.js";
8
+ import { VibeCalDayView as ne } from "../components/vibecalendar/VibeCalDayView.js";
9
+ import { VibeCalAgendaView as re } from "../components/vibecalendar/VibeCalAgendaView.js";
10
+ import { ScheduleTaskModal as s } from "../components/vibecalendar/ScheduleTaskModal.js";
11
+ import { LogsDrawer as c } from "../components/vibecalendar/LogsDrawer.js";
12
12
  import "../components/vibecalendar/index.js";
13
- import { expandJobsToOccurrences as u } from "../components/vibecalendar/expandOccurrences.js";
14
- import { useCallback as d, useEffect as f, useMemo as p, useState as m } from "react";
15
- import { useI18n as h } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
16
- import { AlertCircle as g, CalendarClock as re } from "lucide-react";
17
- import { useParams as ie, useSearchParams as ae } from "react-router-dom";
18
- import { graphqlFetch as oe } from "@burdenoff/fe-libs/shared/graphql";
19
- import { usePermissions as se } from "@burdenoff/fe-libs/shared/providers/shell";
20
- import { jsx as _, jsxs as v } from "react/jsx-runtime";
21
- import { MotionPage as y } from "@burdenoff/fe-libs/shared/motion";
22
- import { AccessDenied as ce } from "@burdenoff/fe-libs/shared/components";
13
+ import { expandJobsToOccurrences as l } from "../components/vibecalendar/expandOccurrences.js";
14
+ import { useCallback as u, useEffect as d, useMemo as f, useState as p } from "react";
15
+ import { useI18n as ie } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
16
+ import { AlertCircle as ae, CalendarClock as oe } from "lucide-react";
17
+ import { useParams as se, useSearchParams as m } from "react-router-dom";
18
+ import { graphqlFetch as ce } from "@burdenoff/fe-libs/shared/graphql";
19
+ import { usePermissions as le } from "@burdenoff/fe-libs/shared/providers/shell";
20
+ import { jsx as h, jsxs as g } from "react/jsx-runtime";
21
+ import { MotionPage as _ } from "@burdenoff/fe-libs/shared/motion";
22
+ import { AccessDenied as ue } from "@burdenoff/fe-libs/shared/components";
23
23
  //#region src/pages/VibeCalendarPage.tsx
24
- var b = "\n query GetGlobalScheduledJobsForCalendar {\n scheduledJobs(pagination: { limit: 500 }) {\n jobs {\n id\n name\n description\n status\n scheduleType\n cronExpression\n rrule\n interval\n scheduledAt\n nextExecutionAt\n lastExecutionAt\n actionId\n timezone\n startDate\n endDate\n }\n total\n hasMore\n }\n }\n";
25
- function x() {
26
- let x = r(), { workspaceId: S } = n(), { t: le } = h(), { viewType: C } = ie(), [w, T] = ae(), E = w.get("actionId") ?? void 0, { hasPermission: D, isLoading: ue, permissions: O } = se(), k = D(a.CALENDAR_AGENT_TASK_LIST), A = D(a.CALENDAR_AGENT_TASK_CREATE), j = D(a.CALENDAR_AGENT_TASK_EXECUTE), [M, N] = m(/* @__PURE__ */ new Date()), [P, F] = m(C || "month"), [I, L] = m(!1);
27
- f(() => {
28
- E && L(!0);
29
- }, [E]);
30
- let [R, z] = m(!1), [B, V] = m(null), [H, de] = m(null), U = (e, t) => {
31
- let n = le(e);
24
+ var de = "\n query GetGlobalScheduledJobsForCalendar {\n scheduledJobs(pagination: { limit: 500 }) {\n jobs {\n id\n name\n description\n status\n scheduleType\n cronExpression\n rrule\n interval\n scheduledAt\n nextExecutionAt\n lastExecutionAt\n actionId\n timezone\n startDate\n endDate\n }\n total\n hasMore\n }\n }\n";
25
+ function v() {
26
+ let v = r(), { workspaceId: y } = n(), { t: b } = ie(), { viewType: x } = se(), [S, C] = m(), w = S.get("actionId") ?? void 0, { hasPermission: T, isLoading: fe, permissions: E } = le(), pe = T(a.CALENDAR_AGENT_TASK_LIST), D = T(a.CALENDAR_AGENT_TASK_CREATE), O = T(a.CALENDAR_AGENT_TASK_EXECUTE), [k, A] = p(/* @__PURE__ */ new Date()), [j, M] = p(x || "month"), [N, P] = p(!1);
27
+ d(() => {
28
+ w && P(!0);
29
+ }, [w]);
30
+ let [F, I] = p(!1), [L, R] = p(null), [z, B] = p(null), V = (e, t) => {
31
+ let n = b(e);
32
32
  return n === e ? t : n;
33
- }, W = p(() => {
34
- let e = new Date(M), t = new Date(M);
35
- switch (P) {
33
+ }, H = f(() => {
34
+ let e = new Date(k), t = new Date(k);
35
+ switch (j) {
36
36
  case "month":
37
37
  e.setDate(1), e.setHours(0, 0, 0, 0), t.setMonth(t.getMonth() + 1, 0), t.setHours(23, 59, 59, 999);
38
38
  break;
@@ -50,44 +50,47 @@ function x() {
50
50
  startDate: e.toISOString(),
51
51
  endDate: t.toISOString()
52
52
  };
53
- }, [M, P]), [G, fe] = m([]), [pe, K] = m(void 0), q = d(async () => {
53
+ }, [k, j]), [U, me] = p([]), [W, G] = p(void 0), [he, ge] = p(!1), [_e, K] = p(!1), q = u(async () => {
54
+ K(!0);
54
55
  try {
55
56
  let e = new URLSearchParams(typeof window > "u" ? "" : window.location.search), t = e.get("org") ?? void 0, n = e.get("tenant") ?? void 0, r = {};
56
57
  t && (r["x-org-id"] = t, r["x-organization-id"] = t), n && (r["x-tenant-id"] = n);
57
- let i = await oe({
58
+ let i = await ce({
58
59
  gateway: "global",
59
- query: b,
60
+ query: de,
60
61
  operationName: "GetGlobalScheduledJobsForCalendar",
61
62
  organizationId: t ?? !0,
62
63
  tenantId: n ?? !0,
63
64
  extraHeaders: r
64
65
  });
65
- if (i.errors && i.errors.length) throw Error(i.errors[0]?.message ?? "Failed to load jobs");
66
- fe(i.data?.scheduledJobs?.jobs ?? []), K(void 0);
66
+ if (i.errors && i.errors.length) throw Error(i.errors[0]?.message ?? "Unable to load scheduled tasks");
67
+ me(i.data?.scheduledJobs?.jobs ?? []), G(void 0), ge(!0);
67
68
  } catch (e) {
68
- console.error("[VibeCalendarPage] Failed to load scheduled jobs:", e), K(e instanceof Error ? e : Error(String(e)));
69
+ console.error("[VibeCalendarPage] Failed to load scheduled jobs:", e), G(e instanceof Error ? e : Error(String(e)));
70
+ } finally {
71
+ K(!1);
69
72
  }
70
73
  }, []);
71
- f(() => {
72
- S && q();
73
- }, [S, q]);
74
- let J = p(() => G.length ? u(G, new Date(W.startDate), new Date(W.endDate)) : [], [
75
- G,
76
- W.startDate,
77
- W.endDate
78
- ]), [Y, { loading: me }] = e(), [X] = t(), he = d((e) => {
79
- F(e);
80
- }, []), Z = d(async (e) => {
74
+ d(() => {
75
+ y && q();
76
+ }, [y, q]);
77
+ let J = f(() => U.length ? l(U, new Date(H.startDate), new Date(H.endDate)) : [], [
78
+ U,
79
+ H.startDate,
80
+ H.endDate
81
+ ]), [Y, { loading: ve }] = e(), [X] = t(), ye = u((e) => {
82
+ M(e);
83
+ }, []), Z = u(async (e) => {
81
84
  try {
82
85
  await X({ variables: { id: e } });
83
86
  } catch (e) {
84
87
  console.error("Failed to trigger task:", e);
85
88
  }
86
- }, [X]), Q = d((e) => {
87
- V(e), de(null), z(!0);
88
- }, []), $ = d((e) => {
89
- x(`/calendar/task/${e}`);
90
- }, [x]), ge = d(async (e) => {
89
+ }, [X]), Q = u((e) => {
90
+ R(e), B(null), I(!0);
91
+ }, []), $ = u((e) => {
92
+ v(`/calendar/task/${e}`);
93
+ }, [v]), be = u(async (e) => {
91
94
  try {
92
95
  if (await Y({ variables: { input: {
93
96
  calendarId: e.calendarId || "default",
@@ -100,124 +103,146 @@ function x() {
100
103
  interval: e.interval,
101
104
  intervalUnit: e.intervalUnit,
102
105
  timezone: e.timezone
103
- } } }), L(!1), w.has("actionId")) {
104
- let e = new URLSearchParams(w);
105
- e.delete("actionId"), T(e, { replace: !0 });
106
+ } } }), P(!1), S.has("actionId")) {
107
+ let e = new URLSearchParams(S);
108
+ e.delete("actionId"), C(e, { replace: !0 });
106
109
  }
107
110
  } catch (e) {
108
111
  console.error("Failed to create task:", e);
109
112
  }
110
113
  }, [
111
114
  Y,
112
- w,
113
- T
115
+ S,
116
+ C
114
117
  ]);
115
- return ue ? /* @__PURE__ */ _(y, {
118
+ if (fe) return /* @__PURE__ */ h(_, {
116
119
  className: "flex flex-col h-full p-4 gap-4",
117
- children: /* @__PURE__ */ _(i, { message: U("calendar.loadingPermissions", "Loading permissions...") })
118
- }) : O && O.permissionStrings?.length > 0 && !k ? /* @__PURE__ */ _(y, {
120
+ children: /* @__PURE__ */ h(i, { message: V("calendar.loadingPermissions", "Loading permissions...") })
121
+ });
122
+ if (E && E.permissionStrings?.length > 0 && !pe) return /* @__PURE__ */ h(_, {
119
123
  className: "flex flex-col h-full p-4 gap-4",
120
- children: /* @__PURE__ */ _(ce, {
121
- title: U("common.accessDeniedTitle", "Access Denied"),
122
- description: U("calendar.accessDeniedDescription", "You don't have permission to view the Calendar.")
124
+ children: /* @__PURE__ */ h(ue, {
125
+ title: V("common.accessDeniedTitle", "Access Denied"),
126
+ description: V("calendar.accessDeniedDescription", "You don't have permission to view the Calendar.")
123
127
  })
124
- }) : /* @__PURE__ */ v(y, {
128
+ });
129
+ let xe = he && !W && U.length === 0;
130
+ return /* @__PURE__ */ g(_, {
125
131
  className: "flex flex-col h-full p-4 gap-4",
126
132
  children: [
127
- pe && J.length === 0 && /* @__PURE__ */ v("div", {
133
+ W && U.length === 0 && /* @__PURE__ */ g("div", {
128
134
  className: "flex items-center gap-3 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-2",
129
135
  children: [
130
- /* @__PURE__ */ _(g, {
136
+ /* @__PURE__ */ h(ae, {
131
137
  size: 16,
132
138
  className: "text-status-error-text flex-shrink-0"
133
139
  }),
134
- /* @__PURE__ */ _("p", {
140
+ /* @__PURE__ */ h("p", {
135
141
  className: "flex-1 text-sm text-status-error-text",
136
- children: U("calendar.failedLoad", "Failed to load calendar data")
142
+ children: V("calendar.couldNotLoadEvents", "Could not load events. We'll keep trying — you can retry below.")
137
143
  }),
138
- /* @__PURE__ */ _("button", {
144
+ /* @__PURE__ */ h("button", {
139
145
  type: "button",
140
146
  onClick: () => q(),
141
- className: "rounded px-3 py-1 text-xs text-status-error-text transition-colors hover:bg-status-error-bg/80",
142
- children: U("calendar.retry", "Retry")
147
+ disabled: _e,
148
+ className: "rounded px-3 py-1 text-xs text-status-error-text transition-colors hover:bg-status-error-bg/80 disabled:opacity-50",
149
+ children: V("calendar.retry", "Retry")
143
150
  })
144
151
  ]
145
152
  }),
146
- /* @__PURE__ */ v("div", {
153
+ /* @__PURE__ */ g("div", {
147
154
  className: "flex items-center gap-3 mb-2",
148
- children: [/* @__PURE__ */ _(re, {
155
+ children: [/* @__PURE__ */ h(oe, {
149
156
  size: 24,
150
157
  className: "text-text-primary"
151
- }), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("h1", {
158
+ }), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("h1", {
152
159
  className: "text-xl font-bold text-text-primary",
153
- children: U("nav.vibeCalendar", "Calendar")
154
- }), /* @__PURE__ */ _("p", {
160
+ children: V("nav.vibeCalendar", "Calendar")
161
+ }), /* @__PURE__ */ h("p", {
155
162
  className: "text-sm text-text-secondary",
156
- children: U("calendar.description", "Schedule and manage tasks across your agents")
163
+ children: V("calendar.description", "Schedule and manage tasks across your agents")
157
164
  })] })]
158
165
  }),
159
- /* @__PURE__ */ _(o, {
160
- currentDate: M,
161
- viewMode: P,
162
- onDateChange: N,
163
- onViewModeChange: he,
164
- onCreateTask: A ? () => L(!0) : void 0
166
+ xe && /* @__PURE__ */ g("div", {
167
+ className: "flex flex-col sm:flex-row sm:items-center gap-3 rounded-lg border border-border-default bg-bg-surface px-4 py-3",
168
+ children: [/* @__PURE__ */ g("div", {
169
+ className: "flex-1",
170
+ children: [/* @__PURE__ */ h("p", {
171
+ className: "text-sm font-medium text-text-primary",
172
+ children: V("calendar.empty.title", "No scheduled tasks yet")
173
+ }), /* @__PURE__ */ h("p", {
174
+ className: "text-xs text-text-secondary mt-0.5",
175
+ children: V("calendar.empty.description", "Schedule your first task to start automating actions across your agents.")
176
+ })]
177
+ }), D && /* @__PURE__ */ h("button", {
178
+ type: "button",
179
+ onClick: () => P(!0),
180
+ className: "px-3 py-1.5 text-xs font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors",
181
+ children: V("calendar.empty.cta", "Schedule your first task")
182
+ })]
183
+ }),
184
+ /* @__PURE__ */ h(ee, {
185
+ currentDate: k,
186
+ viewMode: j,
187
+ onDateChange: A,
188
+ onViewModeChange: ye,
189
+ onCreateTask: D ? () => P(!0) : void 0
165
190
  }),
166
- /* @__PURE__ */ v("div", {
191
+ /* @__PURE__ */ g("div", {
167
192
  className: "flex-1 overflow-hidden",
168
193
  children: [
169
- P === "month" && /* @__PURE__ */ _(s, {
170
- currentDate: M,
194
+ j === "month" && /* @__PURE__ */ h(te, {
195
+ currentDate: k,
171
196
  occurrences: J,
172
- onTriggerNow: j ? Z : void 0,
197
+ onTriggerNow: O ? Z : void 0,
173
198
  onViewLogs: Q,
174
199
  onViewDetail: $
175
200
  }),
176
- P === "week" && /* @__PURE__ */ _(ee, {
177
- currentDate: M,
201
+ j === "week" && /* @__PURE__ */ h(o, {
202
+ currentDate: k,
178
203
  occurrences: J,
179
- onTriggerNow: j ? Z : void 0,
204
+ onTriggerNow: O ? Z : void 0,
180
205
  onViewLogs: Q,
181
206
  onViewDetail: $
182
207
  }),
183
- P === "day" && /* @__PURE__ */ _(te, {
184
- currentDate: M,
208
+ j === "day" && /* @__PURE__ */ h(ne, {
209
+ currentDate: k,
185
210
  occurrences: J,
186
- onTriggerNow: j ? Z : void 0,
211
+ onTriggerNow: O ? Z : void 0,
187
212
  onViewLogs: Q,
188
213
  onViewDetail: $
189
214
  }),
190
- P === "agenda" && /* @__PURE__ */ _(ne, {
215
+ j === "agenda" && /* @__PURE__ */ h(re, {
191
216
  occurrences: J,
192
- onTriggerNow: j ? Z : void 0,
217
+ onTriggerNow: O ? Z : void 0,
193
218
  onViewLogs: Q,
194
219
  onViewDetail: $
195
220
  })
196
221
  ]
197
222
  }),
198
- /* @__PURE__ */ _(c, {
199
- isOpen: I,
223
+ /* @__PURE__ */ h(s, {
224
+ isOpen: N,
200
225
  onClose: () => {
201
- if (L(!1), w.has("actionId")) {
202
- let e = new URLSearchParams(w);
203
- e.delete("actionId"), T(e, { replace: !0 });
226
+ if (P(!1), S.has("actionId")) {
227
+ let e = new URLSearchParams(S);
228
+ e.delete("actionId"), C(e, { replace: !0 });
204
229
  }
205
230
  },
206
- onSubmit: ge,
207
- loading: me,
208
- prefillActionId: E
231
+ onSubmit: be,
232
+ loading: ve,
233
+ prefillActionId: w
209
234
  }),
210
- /* @__PURE__ */ _(l, {
211
- isOpen: R,
212
- onClose: () => z(!1),
213
- execution: H,
214
- taskTitle: B?.title || "",
215
- agentId: B?.agentId || ""
235
+ /* @__PURE__ */ h(c, {
236
+ isOpen: F,
237
+ onClose: () => I(!1),
238
+ execution: z,
239
+ taskTitle: L?.title || "",
240
+ agentId: L?.agentId || ""
216
241
  })
217
242
  ]
218
243
  });
219
244
  }
220
245
  //#endregion
221
- export { x as VibeCalendarPage };
246
+ export { v as VibeCalendarPage };
222
247
 
223
248
  //# sourceMappingURL=VibeCalendarPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VibeCalendarPage.js","names":[],"sources":["../../src/pages/VibeCalendarPage.tsx"],"sourcesContent":["import { useState, useMemo, useCallback, useEffect } from 'react';\nimport { useParams, useSearchParams } from 'react-router-dom';\nimport { CalendarClock, AlertCircle } from 'lucide-react';\nimport { MotionPage } from '@burdenoff/fe-libs/shared/motion';\nimport { AccessDenied } from '@burdenoff/fe-libs/shared/components';\nimport { LoadingState } from '@/components/shared/LoadingState';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { VIBE_PERMISSIONS } from '@/constants/permissions';\nimport {\n VibeCalendarHeader,\n VibeCalMonthView,\n VibeCalWeekView,\n VibeCalDayView,\n VibeCalAgendaView,\n ScheduleTaskModal,\n LogsDrawer,\n} from '../components/vibecalendar';\nimport { useVibeNavigate, useVibeControls } from '@/providers/VibeControlsProvider';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport type {\n CalendarViewMode,\n VibeCalendarTask,\n VibeCalendarExecution,\n ScheduleTaskInput,\n} from '../components/vibecalendar';\nimport {\n expandJobsToOccurrences,\n type SchedulerJobLike,\n} from '../components/vibecalendar/expandOccurrences';\nimport {\n useCreateVibeCalendarTaskMutation,\n useTriggerVibeCalendarTaskNowMutation,\n} from '@/generated/wspace-operations';\n\n/**\n * The /scheduler page writes ScheduledJobs on the GLOBAL gateway\n * (organization-scoped). The VibeCalendar needs to render those jobs\n * regardless of where they were created. We use graphqlFetch targeting\n * the global gateway rather than Apollo (which is wspace-only here).\n */\nconst GLOBAL_SCHEDULED_JOBS_QUERY = /* GraphQL */ `\n query GetGlobalScheduledJobsForCalendar {\n scheduledJobs(pagination: { limit: 500 }) {\n jobs {\n id\n name\n description\n status\n scheduleType\n cronExpression\n rrule\n interval\n scheduledAt\n nextExecutionAt\n lastExecutionAt\n actionId\n timezone\n startDate\n endDate\n }\n total\n hasMore\n }\n }\n`;\n\ninterface GlobalScheduledJobsResponse {\n scheduledJobs: {\n jobs: SchedulerJobLike[];\n total: number;\n hasMore: boolean;\n };\n}\n\n/**\n * Calendar Page\n *\n * Main page for scheduling and managing tasks on VibeControls agents.\n * Supports month and agenda views with task creation, on-demand triggering,\n * and log viewing via the LogsDrawer.\n */\nexport function VibeCalendarPage() {\n const navigate = useVibeNavigate();\n const { workspaceId } = useVibeControls();\n const { t } = useI18n();\n const { viewType } = useParams<{ viewType?: string }>();\n const [searchParams, setSearchParams] = useSearchParams();\n // When navigated here from the Actions page via \"Add to calendar\",\n // the URL carries ?actionId=... — open the modal in Action-linked mode.\n const prefillActionId = searchParams.get('actionId') ?? undefined;\n const { hasPermission, isLoading: permissionsLoading, permissions } = usePermissions();\n const canList = hasPermission(VIBE_PERMISSIONS.CALENDAR_AGENT_TASK_LIST);\n const canCreate = hasPermission(VIBE_PERMISSIONS.CALENDAR_AGENT_TASK_CREATE);\n const canExecute = hasPermission(VIBE_PERMISSIONS.CALENDAR_AGENT_TASK_EXECUTE);\n\n const [currentDate, setCurrentDate] = useState(new Date());\n const [viewMode, setViewMode] = useState<CalendarViewMode>(\n (viewType as CalendarViewMode) || 'month'\n );\n const [showCreateModal, setShowCreateModal] = useState(false);\n\n // Auto-open the modal when arriving with an actionId query param.\n useEffect(() => {\n if (prefillActionId) {\n setShowCreateModal(true);\n }\n }, [prefillActionId]);\n const [showLogsDrawer, setShowLogsDrawer] = useState(false);\n const [selectedTask, setSelectedTask] = useState<VibeCalendarTask | null>(null);\n const [selectedExecution, setSelectedExecution] = useState<VibeCalendarExecution | null>(null);\n\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n // Calculate date range for current view\n const dateRange = useMemo(() => {\n const start = new Date(currentDate);\n const end = new Date(currentDate);\n\n switch (viewMode) {\n case 'month':\n start.setDate(1);\n start.setHours(0, 0, 0, 0);\n end.setMonth(end.getMonth() + 1, 0);\n end.setHours(23, 59, 59, 999);\n break;\n case 'week':\n start.setDate(start.getDate() - start.getDay());\n start.setHours(0, 0, 0, 0);\n end.setDate(start.getDate() + 6);\n end.setHours(23, 59, 59, 999);\n break;\n case 'day':\n start.setHours(0, 0, 0, 0);\n end.setHours(23, 59, 59, 999);\n break;\n case 'agenda':\n start.setDate(1);\n start.setHours(0, 0, 0, 0);\n end.setMonth(end.getMonth() + 1, 0);\n end.setHours(23, 59, 59, 999);\n break;\n }\n\n return { startDate: start.toISOString(), endDate: end.toISOString() };\n }, [currentDate, viewMode]);\n\n // Unified calendar view: fetch every ScheduledJob from the global\n // scheduler (where /scheduler writes). The calendar renders jobs\n // regardless of how they were created, so all schedule-to-Action\n // tasks show up here as a single source of truth.\n //\n // `global-scheduler-svc` requires an organization id in the context\n // headers, so we extract it from the URL search params (the shell\n // populates `?org=` on every route) and pass it explicitly — the\n // auto-detect path in graphqlFetch doesn't reliably set `x-org-id`\n // when the profile storage context hasn't been hydrated yet.\n const [jobs, setJobs] = useState<SchedulerJobLike[]>([]);\n const [rangeError, setRangeError] = useState<Error | undefined>(undefined);\n const refetch = useCallback(async () => {\n try {\n const urlParams = new URLSearchParams(\n typeof window === 'undefined' ? '' : window.location.search\n );\n const orgFromUrl = urlParams.get('org') ?? undefined;\n const tenantFromUrl = urlParams.get('tenant') ?? undefined;\n const extraHeaders: Record<string, string> = {};\n if (orgFromUrl) {\n extraHeaders['x-org-id'] = orgFromUrl;\n extraHeaders['x-organization-id'] = orgFromUrl;\n }\n if (tenantFromUrl) {\n extraHeaders['x-tenant-id'] = tenantFromUrl;\n }\n\n const res = await graphqlFetch<GlobalScheduledJobsResponse>({\n gateway: 'global',\n query: GLOBAL_SCHEDULED_JOBS_QUERY,\n operationName: 'GetGlobalScheduledJobsForCalendar',\n organizationId: orgFromUrl ?? true,\n tenantId: tenantFromUrl ?? true,\n extraHeaders,\n });\n\n if (res.errors && res.errors.length) {\n throw new Error(res.errors[0]?.message ?? 'Failed to load jobs');\n }\n setJobs(res.data?.scheduledJobs?.jobs ?? []);\n setRangeError(undefined);\n } catch (err) {\n console.error('[VibeCalendarPage] Failed to load scheduled jobs:', err);\n setRangeError(err instanceof Error ? err : new Error(String(err)));\n }\n }, []);\n\n useEffect(() => {\n if (!workspaceId) return;\n void refetch();\n }, [workspaceId, refetch]);\n\n const occurrences = useMemo(() => {\n if (!jobs.length) return [];\n return expandJobsToOccurrences(\n jobs,\n new Date(dateRange.startDate),\n new Date(dateRange.endDate)\n );\n }, [jobs, dateRange.startDate, dateRange.endDate]);\n\n // Agents are no longer collected in the modal — the scheduler resolves\n // them from the referenced Action at execution time.\n\n // Mutations\n const [createTaskMutation, { loading: createLoading }] = useCreateVibeCalendarTaskMutation();\n const [triggerNowMutation] = useTriggerVibeCalendarTaskNowMutation();\n\n const handleViewModeChange = useCallback((mode: CalendarViewMode) => {\n setViewMode(mode);\n }, []);\n\n const handleTriggerNow = useCallback(\n async (taskId: string) => {\n try {\n await triggerNowMutation({ variables: { id: taskId } });\n } catch (err) {\n console.error('Failed to trigger task:', err);\n }\n },\n [triggerNowMutation]\n );\n\n const handleViewLogs = useCallback((task: VibeCalendarTask) => {\n setSelectedTask(task);\n setSelectedExecution(null);\n setShowLogsDrawer(true);\n }, []);\n\n const handleViewDetail = useCallback(\n (taskId: string) => {\n navigate(`/calendar/task/${taskId}`);\n },\n [navigate]\n );\n\n const handleCreateTask = useCallback(\n async (input: ScheduleTaskInput) => {\n try {\n // Calendar entries always delegate execution to a VibeControls\n // Action. The scheduler resolves agent/command/webhook details\n // from the Action definition at run time — we only send\n // actionId + calendar/schedule config from this modal.\n await createTaskMutation({\n variables: {\n input: {\n calendarId: input.calendarId || 'default',\n title: input.title,\n description: input.description,\n actionId: input.actionId,\n scheduleType: input.scheduleType,\n scheduledAt: input.scheduledAt,\n cronExpression: input.cronExpression,\n interval: input.interval,\n intervalUnit: input.intervalUnit,\n timezone: input.timezone,\n },\n },\n });\n setShowCreateModal(false);\n // Drop the actionId query param after successful creation\n if (searchParams.has('actionId')) {\n const next = new URLSearchParams(searchParams);\n next.delete('actionId');\n setSearchParams(next, { replace: true });\n }\n } catch (err) {\n console.error('Failed to create task:', err);\n }\n },\n [createTaskMutation, searchParams, setSearchParams]\n );\n\n if (permissionsLoading)\n return (\n <MotionPage className=\"flex flex-col h-full p-4 gap-4\">\n <LoadingState message={tr('calendar.loadingPermissions', 'Loading permissions...')} />\n </MotionPage>\n );\n\n if (permissions && permissions.permissionStrings?.length > 0 && !canList) {\n return (\n <MotionPage className=\"flex flex-col h-full p-4 gap-4\">\n <AccessDenied\n title={tr('common.accessDeniedTitle', 'Access Denied')}\n description={tr(\n 'calendar.accessDeniedDescription',\n \"You don't have permission to view the Calendar.\"\n )}\n />\n </MotionPage>\n );\n }\n\n return (\n <MotionPage className=\"flex flex-col h-full p-4 gap-4\">\n {/* Error banner (non-blocking) */}\n {rangeError && occurrences.length === 0 && (\n <div className=\"flex items-center gap-3 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-2\">\n <AlertCircle size={16} className=\"text-status-error-text flex-shrink-0\" />\n <p className=\"flex-1 text-sm text-status-error-text\">\n {tr('calendar.failedLoad', 'Failed to load calendar data')}\n </p>\n <button\n type=\"button\"\n onClick={() => refetch()}\n className=\"rounded px-3 py-1 text-xs text-status-error-text transition-colors hover:bg-status-error-bg/80\"\n >\n {tr('calendar.retry', 'Retry')}\n </button>\n </div>\n )}\n\n {/* Header */}\n <div className=\"flex items-center gap-3 mb-2\">\n <CalendarClock size={24} className=\"text-text-primary\" />\n <div>\n <h1 className=\"text-xl font-bold text-text-primary\">\n {tr('nav.vibeCalendar', 'Calendar')}\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {tr('calendar.description', 'Schedule and manage tasks across your agents')}\n </p>\n </div>\n </div>\n\n {/* Calendar Header with nav + view switcher */}\n <VibeCalendarHeader\n currentDate={currentDate}\n viewMode={viewMode}\n onDateChange={setCurrentDate}\n onViewModeChange={handleViewModeChange}\n onCreateTask={canCreate ? () => setShowCreateModal(true) : undefined}\n />\n\n {/* Calendar Body */}\n <div className=\"flex-1 overflow-hidden\">\n {viewMode === 'month' && (\n <VibeCalMonthView\n currentDate={currentDate}\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n {viewMode === 'week' && (\n <VibeCalWeekView\n currentDate={currentDate}\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n {viewMode === 'day' && (\n <VibeCalDayView\n currentDate={currentDate}\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n {viewMode === 'agenda' && (\n <VibeCalAgendaView\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n </div>\n\n {/* Schedule Task Modal */}\n <ScheduleTaskModal\n isOpen={showCreateModal}\n onClose={() => {\n setShowCreateModal(false);\n // Strip the actionId query param on dismiss so reopening the\n // modal without a fresh navigation doesn't silently resume\n // Action-linked mode.\n if (searchParams.has('actionId')) {\n const next = new URLSearchParams(searchParams);\n next.delete('actionId');\n setSearchParams(next, { replace: true });\n }\n }}\n onSubmit={handleCreateTask}\n loading={createLoading}\n prefillActionId={prefillActionId}\n />\n\n {/* Logs Drawer */}\n <LogsDrawer\n isOpen={showLogsDrawer}\n onClose={() => setShowLogsDrawer(false)}\n execution={selectedExecution}\n taskTitle={selectedTask?.title || ''}\n agentId={selectedTask?.agentId || ''}\n />\n </MotionPage>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"VibeCalendarPage.js","names":[],"sources":["../../src/pages/VibeCalendarPage.tsx"],"sourcesContent":["import { useState, useMemo, useCallback, useEffect } from 'react';\nimport { useParams, useSearchParams } from 'react-router-dom';\nimport { CalendarClock, AlertCircle } from 'lucide-react';\nimport { MotionPage } from '@burdenoff/fe-libs/shared/motion';\nimport { AccessDenied } from '@burdenoff/fe-libs/shared/components';\nimport { LoadingState } from '@/components/shared/LoadingState';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { VIBE_PERMISSIONS } from '@/constants/permissions';\nimport {\n VibeCalendarHeader,\n VibeCalMonthView,\n VibeCalWeekView,\n VibeCalDayView,\n VibeCalAgendaView,\n ScheduleTaskModal,\n LogsDrawer,\n} from '../components/vibecalendar';\nimport { useVibeNavigate, useVibeControls } from '@/providers/VibeControlsProvider';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport type {\n CalendarViewMode,\n VibeCalendarTask,\n VibeCalendarExecution,\n ScheduleTaskInput,\n} from '../components/vibecalendar';\nimport {\n expandJobsToOccurrences,\n type SchedulerJobLike,\n} from '../components/vibecalendar/expandOccurrences';\nimport {\n useCreateVibeCalendarTaskMutation,\n useTriggerVibeCalendarTaskNowMutation,\n} from '@/generated/wspace-operations';\n\n/**\n * The /scheduler page writes ScheduledJobs on the GLOBAL gateway\n * (organization-scoped). The VibeCalendar needs to render those jobs\n * regardless of where they were created. We use graphqlFetch targeting\n * the global gateway rather than Apollo (which is wspace-only here).\n */\nconst GLOBAL_SCHEDULED_JOBS_QUERY = /* GraphQL */ `\n query GetGlobalScheduledJobsForCalendar {\n scheduledJobs(pagination: { limit: 500 }) {\n jobs {\n id\n name\n description\n status\n scheduleType\n cronExpression\n rrule\n interval\n scheduledAt\n nextExecutionAt\n lastExecutionAt\n actionId\n timezone\n startDate\n endDate\n }\n total\n hasMore\n }\n }\n`;\n\ninterface GlobalScheduledJobsResponse {\n scheduledJobs: {\n jobs: SchedulerJobLike[];\n total: number;\n hasMore: boolean;\n };\n}\n\n/**\n * Calendar Page\n *\n * Main page for scheduling and managing tasks on VibeControls agents.\n * Supports month and agenda views with task creation, on-demand triggering,\n * and log viewing via the LogsDrawer.\n */\nexport function VibeCalendarPage() {\n const navigate = useVibeNavigate();\n const { workspaceId } = useVibeControls();\n const { t } = useI18n();\n const { viewType } = useParams<{ viewType?: string }>();\n const [searchParams, setSearchParams] = useSearchParams();\n // When navigated here from the Actions page via \"Add to calendar\",\n // the URL carries ?actionId=... — open the modal in Action-linked mode.\n const prefillActionId = searchParams.get('actionId') ?? undefined;\n const { hasPermission, isLoading: permissionsLoading, permissions } = usePermissions();\n const canList = hasPermission(VIBE_PERMISSIONS.CALENDAR_AGENT_TASK_LIST);\n const canCreate = hasPermission(VIBE_PERMISSIONS.CALENDAR_AGENT_TASK_CREATE);\n const canExecute = hasPermission(VIBE_PERMISSIONS.CALENDAR_AGENT_TASK_EXECUTE);\n\n const [currentDate, setCurrentDate] = useState(new Date());\n const [viewMode, setViewMode] = useState<CalendarViewMode>(\n (viewType as CalendarViewMode) || 'month'\n );\n const [showCreateModal, setShowCreateModal] = useState(false);\n\n // Auto-open the modal when arriving with an actionId query param.\n useEffect(() => {\n if (prefillActionId) {\n setShowCreateModal(true);\n }\n }, [prefillActionId]);\n const [showLogsDrawer, setShowLogsDrawer] = useState(false);\n const [selectedTask, setSelectedTask] = useState<VibeCalendarTask | null>(null);\n const [selectedExecution, setSelectedExecution] = useState<VibeCalendarExecution | null>(null);\n\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n // Calculate date range for current view\n const dateRange = useMemo(() => {\n const start = new Date(currentDate);\n const end = new Date(currentDate);\n\n switch (viewMode) {\n case 'month':\n start.setDate(1);\n start.setHours(0, 0, 0, 0);\n end.setMonth(end.getMonth() + 1, 0);\n end.setHours(23, 59, 59, 999);\n break;\n case 'week':\n start.setDate(start.getDate() - start.getDay());\n start.setHours(0, 0, 0, 0);\n end.setDate(start.getDate() + 6);\n end.setHours(23, 59, 59, 999);\n break;\n case 'day':\n start.setHours(0, 0, 0, 0);\n end.setHours(23, 59, 59, 999);\n break;\n case 'agenda':\n start.setDate(1);\n start.setHours(0, 0, 0, 0);\n end.setMonth(end.getMonth() + 1, 0);\n end.setHours(23, 59, 59, 999);\n break;\n }\n\n return { startDate: start.toISOString(), endDate: end.toISOString() };\n }, [currentDate, viewMode]);\n\n // Unified calendar view: fetch every ScheduledJob from the global\n // scheduler (where /scheduler writes). The calendar renders jobs\n // regardless of how they were created, so all schedule-to-Action\n // tasks show up here as a single source of truth.\n //\n // `global-scheduler-svc` requires an organization id in the context\n // headers, so we extract it from the URL search params (the shell\n // populates `?org=` on every route) and pass it explicitly — the\n // auto-detect path in graphqlFetch doesn't reliably set `x-org-id`\n // when the profile storage context hasn't been hydrated yet.\n const [jobs, setJobs] = useState<SchedulerJobLike[]>([]);\n const [rangeError, setRangeError] = useState<Error | undefined>(undefined);\n const [jobsLoaded, setJobsLoaded] = useState(false);\n const [jobsLoading, setJobsLoading] = useState(false);\n const refetch = useCallback(async () => {\n setJobsLoading(true);\n try {\n const urlParams = new URLSearchParams(\n typeof window === 'undefined' ? '' : window.location.search\n );\n const orgFromUrl = urlParams.get('org') ?? undefined;\n const tenantFromUrl = urlParams.get('tenant') ?? undefined;\n const extraHeaders: Record<string, string> = {};\n if (orgFromUrl) {\n extraHeaders['x-org-id'] = orgFromUrl;\n extraHeaders['x-organization-id'] = orgFromUrl;\n }\n if (tenantFromUrl) {\n extraHeaders['x-tenant-id'] = tenantFromUrl;\n }\n\n const res = await graphqlFetch<GlobalScheduledJobsResponse>({\n gateway: 'global',\n query: GLOBAL_SCHEDULED_JOBS_QUERY,\n operationName: 'GetGlobalScheduledJobsForCalendar',\n organizationId: orgFromUrl ?? true,\n tenantId: tenantFromUrl ?? true,\n extraHeaders,\n });\n\n if (res.errors && res.errors.length) {\n // Wrap GraphQL/network errors in a generic, UI-safe Error so we\n // never leak raw resolver / federation messages into the banner.\n throw new Error(res.errors[0]?.message ?? 'Unable to load scheduled tasks');\n }\n setJobs(res.data?.scheduledJobs?.jobs ?? []);\n setRangeError(undefined);\n setJobsLoaded(true);\n } catch (err) {\n console.error('[VibeCalendarPage] Failed to load scheduled jobs:', err);\n setRangeError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setJobsLoading(false);\n }\n }, []);\n\n useEffect(() => {\n if (!workspaceId) return;\n void refetch();\n }, [workspaceId, refetch]);\n\n const occurrences = useMemo(() => {\n if (!jobs.length) return [];\n return expandJobsToOccurrences(\n jobs,\n new Date(dateRange.startDate),\n new Date(dateRange.endDate)\n );\n }, [jobs, dateRange.startDate, dateRange.endDate]);\n\n // Agents are no longer collected in the modal — the scheduler resolves\n // them from the referenced Action at execution time.\n\n // Mutations\n const [createTaskMutation, { loading: createLoading }] = useCreateVibeCalendarTaskMutation();\n const [triggerNowMutation] = useTriggerVibeCalendarTaskNowMutation();\n\n const handleViewModeChange = useCallback((mode: CalendarViewMode) => {\n setViewMode(mode);\n }, []);\n\n const handleTriggerNow = useCallback(\n async (taskId: string) => {\n try {\n await triggerNowMutation({ variables: { id: taskId } });\n } catch (err) {\n console.error('Failed to trigger task:', err);\n }\n },\n [triggerNowMutation]\n );\n\n const handleViewLogs = useCallback((task: VibeCalendarTask) => {\n setSelectedTask(task);\n setSelectedExecution(null);\n setShowLogsDrawer(true);\n }, []);\n\n const handleViewDetail = useCallback(\n (taskId: string) => {\n navigate(`/calendar/task/${taskId}`);\n },\n [navigate]\n );\n\n const handleCreateTask = useCallback(\n async (input: ScheduleTaskInput) => {\n try {\n // Calendar entries always delegate execution to a VibeControls\n // Action. The scheduler resolves agent/command/webhook details\n // from the Action definition at run time — we only send\n // actionId + calendar/schedule config from this modal.\n await createTaskMutation({\n variables: {\n input: {\n calendarId: input.calendarId || 'default',\n title: input.title,\n description: input.description,\n actionId: input.actionId,\n scheduleType: input.scheduleType,\n scheduledAt: input.scheduledAt,\n cronExpression: input.cronExpression,\n interval: input.interval,\n intervalUnit: input.intervalUnit,\n timezone: input.timezone,\n },\n },\n });\n setShowCreateModal(false);\n // Drop the actionId query param after successful creation\n if (searchParams.has('actionId')) {\n const next = new URLSearchParams(searchParams);\n next.delete('actionId');\n setSearchParams(next, { replace: true });\n }\n } catch (err) {\n console.error('Failed to create task:', err);\n }\n },\n [createTaskMutation, searchParams, setSearchParams]\n );\n\n if (permissionsLoading)\n return (\n <MotionPage className=\"flex flex-col h-full p-4 gap-4\">\n <LoadingState message={tr('calendar.loadingPermissions', 'Loading permissions...')} />\n </MotionPage>\n );\n\n if (permissions && permissions.permissionStrings?.length > 0 && !canList) {\n return (\n <MotionPage className=\"flex flex-col h-full p-4 gap-4\">\n <AccessDenied\n title={tr('common.accessDeniedTitle', 'Access Denied')}\n description={tr(\n 'calendar.accessDeniedDescription',\n \"You don't have permission to view the Calendar.\"\n )}\n />\n </MotionPage>\n );\n }\n\n // Show the empty-state CTA only after the first successful load returned\n // an empty list — never while loading, and never when an error blocks the\n // distinction between \"no data\" and \"couldn't fetch\".\n const showEmptyState = jobsLoaded && !rangeError && jobs.length === 0;\n\n return (\n <MotionPage className=\"flex flex-col h-full p-4 gap-4\">\n {/* Error banner (non-blocking) — friendly message, never raw GraphQL */}\n {rangeError && jobs.length === 0 && (\n <div className=\"flex items-center gap-3 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-2\">\n <AlertCircle size={16} className=\"text-status-error-text flex-shrink-0\" />\n <p className=\"flex-1 text-sm text-status-error-text\">\n {tr(\n 'calendar.couldNotLoadEvents',\n \"Could not load events. We'll keep trying — you can retry below.\"\n )}\n </p>\n <button\n type=\"button\"\n onClick={() => refetch()}\n disabled={jobsLoading}\n className=\"rounded px-3 py-1 text-xs text-status-error-text transition-colors hover:bg-status-error-bg/80 disabled:opacity-50\"\n >\n {tr('calendar.retry', 'Retry')}\n </button>\n </div>\n )}\n\n {/* Header */}\n <div className=\"flex items-center gap-3 mb-2\">\n <CalendarClock size={24} className=\"text-text-primary\" />\n <div>\n <h1 className=\"text-xl font-bold text-text-primary\">\n {tr('nav.vibeCalendar', 'Calendar')}\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {tr('calendar.description', 'Schedule and manage tasks across your agents')}\n </p>\n </div>\n </div>\n\n {/* Empty-state CTA shown when the user has no scheduled tasks yet. */}\n {showEmptyState && (\n <div className=\"flex flex-col sm:flex-row sm:items-center gap-3 rounded-lg border border-border-default bg-bg-surface px-4 py-3\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">\n {tr('calendar.empty.title', 'No scheduled tasks yet')}\n </p>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n {tr(\n 'calendar.empty.description',\n 'Schedule your first task to start automating actions across your agents.'\n )}\n </p>\n </div>\n {canCreate && (\n <button\n type=\"button\"\n onClick={() => setShowCreateModal(true)}\n className=\"px-3 py-1.5 text-xs font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('calendar.empty.cta', 'Schedule your first task')}\n </button>\n )}\n </div>\n )}\n\n {/* Calendar Header with nav + view switcher */}\n <VibeCalendarHeader\n currentDate={currentDate}\n viewMode={viewMode}\n onDateChange={setCurrentDate}\n onViewModeChange={handleViewModeChange}\n onCreateTask={canCreate ? () => setShowCreateModal(true) : undefined}\n />\n\n {/* Calendar Body */}\n <div className=\"flex-1 overflow-hidden\">\n {viewMode === 'month' && (\n <VibeCalMonthView\n currentDate={currentDate}\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n {viewMode === 'week' && (\n <VibeCalWeekView\n currentDate={currentDate}\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n {viewMode === 'day' && (\n <VibeCalDayView\n currentDate={currentDate}\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n {viewMode === 'agenda' && (\n <VibeCalAgendaView\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n </div>\n\n {/* Schedule Task Modal */}\n <ScheduleTaskModal\n isOpen={showCreateModal}\n onClose={() => {\n setShowCreateModal(false);\n // Strip the actionId query param on dismiss so reopening the\n // modal without a fresh navigation doesn't silently resume\n // Action-linked mode.\n if (searchParams.has('actionId')) {\n const next = new URLSearchParams(searchParams);\n next.delete('actionId');\n setSearchParams(next, { replace: true });\n }\n }}\n onSubmit={handleCreateTask}\n loading={createLoading}\n prefillActionId={prefillActionId}\n />\n\n {/* Logs Drawer */}\n <LogsDrawer\n isOpen={showLogsDrawer}\n onClose={() => setShowLogsDrawer(false)}\n execution={selectedExecution}\n taskTitle={selectedTask?.title || ''}\n agentId={selectedTask?.agentId || ''}\n />\n </MotionPage>\n );\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-vibecontrols",
3
- "version": "2026.528.6",
3
+ "version": "2026.528.7",
4
4
  "description": "VibeControls microfrontend for Burdenoff products",
5
5
  "type": "module",
6
6
  "files": [
@@ -55,7 +55,7 @@
55
55
  "license": "PROPRIETARY",
56
56
  "dependencies": {
57
57
  "@apollo/client": "4.1.9",
58
- "@burdenoff/fe-libs": "2026.528.3",
58
+ "@burdenoff/fe-libs": "2026.528.8",
59
59
  "@tanstack/react-query": "^5.90.16",
60
60
  "@xyflow/react": "^12.10.2",
61
61
  "clsx": "^2.1.1",