@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.
- package/dist/VibeControlsRoot.js +89 -81
- package/dist/VibeControlsRoot.js.map +1 -1
- package/dist/VibeControlsRoutes.js +144 -140
- package/dist/VibeControlsRoutes.js.map +1 -1
- package/dist/components/templates/TemplateWizard.js +2 -2
- package/dist/components/templates/TemplateWizard.js.map +1 -1
- package/dist/constants/pluginCatalog.js +1 -1
- package/dist/pages/PluginsCatalogPage.js +287 -0
- package/dist/pages/PluginsCatalogPage.js.map +1 -0
- package/dist/pages/VibeCalendarPage.js +132 -107
- package/dist/pages/VibeCalendarPage.js.map +1 -1
- package/package.json +2 -2
|
@@ -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
|
|
6
|
-
import { VibeCalMonthView as
|
|
7
|
-
import { VibeCalWeekView as
|
|
8
|
-
import { VibeCalDayView as
|
|
9
|
-
import { VibeCalAgendaView as
|
|
10
|
-
import { ScheduleTaskModal as
|
|
11
|
-
import { LogsDrawer as
|
|
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
|
|
14
|
-
import { useCallback as
|
|
15
|
-
import { useI18n as
|
|
16
|
-
import { AlertCircle as
|
|
17
|
-
import { useParams as
|
|
18
|
-
import { graphqlFetch as
|
|
19
|
-
import { usePermissions as
|
|
20
|
-
import { jsx as
|
|
21
|
-
import { MotionPage as
|
|
22
|
-
import { AccessDenied as
|
|
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
|
|
25
|
-
function
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}, [
|
|
30
|
-
let [
|
|
31
|
-
let n =
|
|
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
|
-
},
|
|
34
|
-
let e = new Date(
|
|
35
|
-
switch (
|
|
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
|
-
}, [
|
|
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
|
|
58
|
+
let i = await ce({
|
|
58
59
|
gateway: "global",
|
|
59
|
-
query:
|
|
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 ?? "
|
|
66
|
-
|
|
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),
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
}, [
|
|
74
|
-
let J =
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
]), [Y, { loading:
|
|
79
|
-
|
|
80
|
-
}, []), Z =
|
|
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 =
|
|
87
|
-
|
|
88
|
-
}, []), $ =
|
|
89
|
-
|
|
90
|
-
}, [
|
|
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
|
-
} } }),
|
|
104
|
-
let e = new URLSearchParams(
|
|
105
|
-
e.delete("actionId"),
|
|
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
|
-
|
|
113
|
-
|
|
115
|
+
S,
|
|
116
|
+
C
|
|
114
117
|
]);
|
|
115
|
-
|
|
118
|
+
if (fe) return /* @__PURE__ */ h(_, {
|
|
116
119
|
className: "flex flex-col h-full p-4 gap-4",
|
|
117
|
-
children: /* @__PURE__ */
|
|
118
|
-
})
|
|
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__ */
|
|
121
|
-
title:
|
|
122
|
-
description:
|
|
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
|
-
})
|
|
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
|
-
|
|
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__ */
|
|
136
|
+
/* @__PURE__ */ h(ae, {
|
|
131
137
|
size: 16,
|
|
132
138
|
className: "text-status-error-text flex-shrink-0"
|
|
133
139
|
}),
|
|
134
|
-
/* @__PURE__ */
|
|
140
|
+
/* @__PURE__ */ h("p", {
|
|
135
141
|
className: "flex-1 text-sm text-status-error-text",
|
|
136
|
-
children:
|
|
142
|
+
children: V("calendar.couldNotLoadEvents", "Could not load events. We'll keep trying — you can retry below.")
|
|
137
143
|
}),
|
|
138
|
-
/* @__PURE__ */
|
|
144
|
+
/* @__PURE__ */ h("button", {
|
|
139
145
|
type: "button",
|
|
140
146
|
onClick: () => q(),
|
|
141
|
-
|
|
142
|
-
|
|
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__ */
|
|
153
|
+
/* @__PURE__ */ g("div", {
|
|
147
154
|
className: "flex items-center gap-3 mb-2",
|
|
148
|
-
children: [/* @__PURE__ */
|
|
155
|
+
children: [/* @__PURE__ */ h(oe, {
|
|
149
156
|
size: 24,
|
|
150
157
|
className: "text-text-primary"
|
|
151
|
-
}), /* @__PURE__ */
|
|
158
|
+
}), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("h1", {
|
|
152
159
|
className: "text-xl font-bold text-text-primary",
|
|
153
|
-
children:
|
|
154
|
-
}), /* @__PURE__ */
|
|
160
|
+
children: V("nav.vibeCalendar", "Calendar")
|
|
161
|
+
}), /* @__PURE__ */ h("p", {
|
|
155
162
|
className: "text-sm text-text-secondary",
|
|
156
|
-
children:
|
|
163
|
+
children: V("calendar.description", "Schedule and manage tasks across your agents")
|
|
157
164
|
})] })]
|
|
158
165
|
}),
|
|
159
|
-
/* @__PURE__ */
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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__ */
|
|
191
|
+
/* @__PURE__ */ g("div", {
|
|
167
192
|
className: "flex-1 overflow-hidden",
|
|
168
193
|
children: [
|
|
169
|
-
|
|
170
|
-
currentDate:
|
|
194
|
+
j === "month" && /* @__PURE__ */ h(te, {
|
|
195
|
+
currentDate: k,
|
|
171
196
|
occurrences: J,
|
|
172
|
-
onTriggerNow:
|
|
197
|
+
onTriggerNow: O ? Z : void 0,
|
|
173
198
|
onViewLogs: Q,
|
|
174
199
|
onViewDetail: $
|
|
175
200
|
}),
|
|
176
|
-
|
|
177
|
-
currentDate:
|
|
201
|
+
j === "week" && /* @__PURE__ */ h(o, {
|
|
202
|
+
currentDate: k,
|
|
178
203
|
occurrences: J,
|
|
179
|
-
onTriggerNow:
|
|
204
|
+
onTriggerNow: O ? Z : void 0,
|
|
180
205
|
onViewLogs: Q,
|
|
181
206
|
onViewDetail: $
|
|
182
207
|
}),
|
|
183
|
-
|
|
184
|
-
currentDate:
|
|
208
|
+
j === "day" && /* @__PURE__ */ h(ne, {
|
|
209
|
+
currentDate: k,
|
|
185
210
|
occurrences: J,
|
|
186
|
-
onTriggerNow:
|
|
211
|
+
onTriggerNow: O ? Z : void 0,
|
|
187
212
|
onViewLogs: Q,
|
|
188
213
|
onViewDetail: $
|
|
189
214
|
}),
|
|
190
|
-
|
|
215
|
+
j === "agenda" && /* @__PURE__ */ h(re, {
|
|
191
216
|
occurrences: J,
|
|
192
|
-
onTriggerNow:
|
|
217
|
+
onTriggerNow: O ? Z : void 0,
|
|
193
218
|
onViewLogs: Q,
|
|
194
219
|
onViewDetail: $
|
|
195
220
|
})
|
|
196
221
|
]
|
|
197
222
|
}),
|
|
198
|
-
/* @__PURE__ */
|
|
199
|
-
isOpen:
|
|
223
|
+
/* @__PURE__ */ h(s, {
|
|
224
|
+
isOpen: N,
|
|
200
225
|
onClose: () => {
|
|
201
|
-
if (
|
|
202
|
-
let e = new URLSearchParams(
|
|
203
|
-
e.delete("actionId"),
|
|
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:
|
|
207
|
-
loading:
|
|
208
|
-
prefillActionId:
|
|
231
|
+
onSubmit: be,
|
|
232
|
+
loading: ve,
|
|
233
|
+
prefillActionId: w
|
|
209
234
|
}),
|
|
210
|
-
/* @__PURE__ */
|
|
211
|
-
isOpen:
|
|
212
|
-
onClose: () =>
|
|
213
|
-
execution:
|
|
214
|
-
taskTitle:
|
|
215
|
-
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 {
|
|
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.
|
|
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.
|
|
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",
|