nvent 0.4.0

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.
Files changed (192) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +389 -0
  3. package/dist/module.d.mts +193 -0
  4. package/dist/module.json +9 -0
  5. package/dist/module.mjs +974 -0
  6. package/dist/runtime/app/components/ConfirmDialog.d.vue.ts +33 -0
  7. package/dist/runtime/app/components/ConfirmDialog.vue +121 -0
  8. package/dist/runtime/app/components/ConfirmDialog.vue.d.ts +33 -0
  9. package/dist/runtime/app/components/FlowDiagram.d.vue.ts +64 -0
  10. package/dist/runtime/app/components/FlowDiagram.vue +338 -0
  11. package/dist/runtime/app/components/FlowDiagram.vue.d.ts +64 -0
  12. package/dist/runtime/app/components/FlowNodeCard.d.vue.ts +29 -0
  13. package/dist/runtime/app/components/FlowNodeCard.vue +156 -0
  14. package/dist/runtime/app/components/FlowNodeCard.vue.d.ts +29 -0
  15. package/dist/runtime/app/components/FlowRunOverview.d.vue.ts +9 -0
  16. package/dist/runtime/app/components/FlowRunOverview.vue +291 -0
  17. package/dist/runtime/app/components/FlowRunOverview.vue.d.ts +9 -0
  18. package/dist/runtime/app/components/FlowRunStatusBadge.d.vue.ts +14 -0
  19. package/dist/runtime/app/components/FlowRunStatusBadge.vue +60 -0
  20. package/dist/runtime/app/components/FlowRunStatusBadge.vue.d.ts +14 -0
  21. package/dist/runtime/app/components/FlowRunTimeline.d.vue.ts +12 -0
  22. package/dist/runtime/app/components/FlowRunTimeline.vue +127 -0
  23. package/dist/runtime/app/components/FlowRunTimeline.vue.d.ts +12 -0
  24. package/dist/runtime/app/components/FlowScheduleDialog.d.vue.ts +16 -0
  25. package/dist/runtime/app/components/FlowScheduleDialog.vue +226 -0
  26. package/dist/runtime/app/components/FlowScheduleDialog.vue.d.ts +16 -0
  27. package/dist/runtime/app/components/FlowSchedulesList.d.vue.ts +12 -0
  28. package/dist/runtime/app/components/FlowSchedulesList.vue +99 -0
  29. package/dist/runtime/app/components/FlowSchedulesList.vue.d.ts +12 -0
  30. package/dist/runtime/app/components/JobScheduling.d.vue.ts +6 -0
  31. package/dist/runtime/app/components/JobScheduling.vue +203 -0
  32. package/dist/runtime/app/components/JobScheduling.vue.d.ts +6 -0
  33. package/dist/runtime/app/components/ListItem.d.vue.ts +23 -0
  34. package/dist/runtime/app/components/ListItem.vue +70 -0
  35. package/dist/runtime/app/components/ListItem.vue.d.ts +23 -0
  36. package/dist/runtime/app/components/QueueConfigDetails.d.vue.ts +45 -0
  37. package/dist/runtime/app/components/QueueConfigDetails.vue +412 -0
  38. package/dist/runtime/app/components/QueueConfigDetails.vue.d.ts +45 -0
  39. package/dist/runtime/app/components/StatCounter.d.vue.ts +9 -0
  40. package/dist/runtime/app/components/StatCounter.vue +25 -0
  41. package/dist/runtime/app/components/StatCounter.vue.d.ts +9 -0
  42. package/dist/runtime/app/components/TimelineList.d.vue.ts +7 -0
  43. package/dist/runtime/app/components/TimelineList.vue +210 -0
  44. package/dist/runtime/app/components/TimelineList.vue.d.ts +7 -0
  45. package/dist/runtime/app/components/nhealth/component-router.d.vue.ts +46 -0
  46. package/dist/runtime/app/components/nhealth/component-router.vue +26 -0
  47. package/dist/runtime/app/components/nhealth/component-router.vue.d.ts +46 -0
  48. package/dist/runtime/app/components/nhealth/component-shell.d.vue.ts +24 -0
  49. package/dist/runtime/app/components/nhealth/component-shell.vue +89 -0
  50. package/dist/runtime/app/components/nhealth/component-shell.vue.d.ts +24 -0
  51. package/dist/runtime/app/composables/useAnalyzedFlows.d.ts +14 -0
  52. package/dist/runtime/app/composables/useAnalyzedFlows.js +7 -0
  53. package/dist/runtime/app/composables/useComponentRouter.d.ts +38 -0
  54. package/dist/runtime/app/composables/useComponentRouter.js +240 -0
  55. package/dist/runtime/app/composables/useFlowRunTimeline.d.ts +15 -0
  56. package/dist/runtime/app/composables/useFlowRunTimeline.js +66 -0
  57. package/dist/runtime/app/composables/useFlowRuns.d.ts +11 -0
  58. package/dist/runtime/app/composables/useFlowRuns.js +31 -0
  59. package/dist/runtime/app/composables/useFlowRunsInfinite.d.ts +24 -0
  60. package/dist/runtime/app/composables/useFlowRunsInfinite.js +123 -0
  61. package/dist/runtime/app/composables/useFlowRunsPolling.d.ts +8 -0
  62. package/dist/runtime/app/composables/useFlowRunsPolling.js +26 -0
  63. package/dist/runtime/app/composables/useFlowState.d.ts +125 -0
  64. package/dist/runtime/app/composables/useFlowState.js +211 -0
  65. package/dist/runtime/app/composables/useFlowWebSocket.d.ts +27 -0
  66. package/dist/runtime/app/composables/useFlowWebSocket.js +205 -0
  67. package/dist/runtime/app/composables/useFlowsNavigation.d.ts +10 -0
  68. package/dist/runtime/app/composables/useFlowsNavigation.js +57 -0
  69. package/dist/runtime/app/composables/useQueueJobs.d.ts +20 -0
  70. package/dist/runtime/app/composables/useQueueJobs.js +20 -0
  71. package/dist/runtime/app/composables/useQueueUpdates.d.ts +26 -0
  72. package/dist/runtime/app/composables/useQueueUpdates.js +122 -0
  73. package/dist/runtime/app/composables/useQueues.d.ts +43 -0
  74. package/dist/runtime/app/composables/useQueues.js +26 -0
  75. package/dist/runtime/app/composables/useQueuesLive.d.ts +19 -0
  76. package/dist/runtime/app/composables/useQueuesLive.js +143 -0
  77. package/dist/runtime/app/pages/flows/index.d.vue.ts +3 -0
  78. package/dist/runtime/app/pages/flows/index.vue +645 -0
  79. package/dist/runtime/app/pages/flows/index.vue.d.ts +3 -0
  80. package/dist/runtime/app/pages/index.d.vue.ts +3 -0
  81. package/dist/runtime/app/pages/index.vue +34 -0
  82. package/dist/runtime/app/pages/index.vue.d.ts +3 -0
  83. package/dist/runtime/app/pages/queues/index.d.vue.ts +3 -0
  84. package/dist/runtime/app/pages/queues/index.vue +229 -0
  85. package/dist/runtime/app/pages/queues/index.vue.d.ts +3 -0
  86. package/dist/runtime/app/pages/queues/job.d.vue.ts +3 -0
  87. package/dist/runtime/app/pages/queues/job.vue +262 -0
  88. package/dist/runtime/app/pages/queues/job.vue.d.ts +3 -0
  89. package/dist/runtime/app/pages/queues/jobs.d.vue.ts +3 -0
  90. package/dist/runtime/app/pages/queues/jobs.vue +291 -0
  91. package/dist/runtime/app/pages/queues/jobs.vue.d.ts +3 -0
  92. package/dist/runtime/app/plugins/vueflow.client.d.ts +6 -0
  93. package/dist/runtime/app/plugins/vueflow.client.js +15 -0
  94. package/dist/runtime/constants.d.ts +11 -0
  95. package/dist/runtime/constants.js +11 -0
  96. package/dist/runtime/python/get_config.py +64 -0
  97. package/dist/runtime/schema.d.ts +37 -0
  98. package/dist/runtime/schema.js +20 -0
  99. package/dist/runtime/server/api/_flows/[name]/clear-history.delete.d.ts +10 -0
  100. package/dist/runtime/server/api/_flows/[name]/clear-history.delete.js +44 -0
  101. package/dist/runtime/server/api/_flows/[name]/runs.get.d.ts +7 -0
  102. package/dist/runtime/server/api/_flows/[name]/runs.get.js +53 -0
  103. package/dist/runtime/server/api/_flows/[name]/schedule.post.d.ts +2 -0
  104. package/dist/runtime/server/api/_flows/[name]/schedule.post.js +57 -0
  105. package/dist/runtime/server/api/_flows/[name]/schedules/[id].delete.d.ts +2 -0
  106. package/dist/runtime/server/api/_flows/[name]/schedules/[id].delete.js +42 -0
  107. package/dist/runtime/server/api/_flows/[name]/schedules.get.d.ts +2 -0
  108. package/dist/runtime/server/api/_flows/[name]/schedules.get.js +48 -0
  109. package/dist/runtime/server/api/_flows/[name]/start.post.d.ts +2 -0
  110. package/dist/runtime/server/api/_flows/[name]/start.post.js +9 -0
  111. package/dist/runtime/server/api/_flows/index.get.d.ts +6 -0
  112. package/dist/runtime/server/api/_flows/index.get.js +5 -0
  113. package/dist/runtime/server/api/_flows/ws.d.ts +60 -0
  114. package/dist/runtime/server/api/_flows/ws.js +183 -0
  115. package/dist/runtime/server/api/_queues/[name]/job/[id].get.d.ts +2 -0
  116. package/dist/runtime/server/api/_queues/[name]/job/[id].get.js +9 -0
  117. package/dist/runtime/server/api/_queues/[name]/job/index.get.d.ts +2 -0
  118. package/dist/runtime/server/api/_queues/[name]/job/index.get.js +18 -0
  119. package/dist/runtime/server/api/_queues/index.get.d.ts +2 -0
  120. package/dist/runtime/server/api/_queues/index.get.js +63 -0
  121. package/dist/runtime/server/api/_queues/ws.d.ts +48 -0
  122. package/dist/runtime/server/api/_queues/ws.js +200 -0
  123. package/dist/runtime/server/events/adapters/fileAdapter.d.ts +2 -0
  124. package/dist/runtime/server/events/adapters/fileAdapter.js +382 -0
  125. package/dist/runtime/server/events/adapters/memoryAdapter.d.ts +2 -0
  126. package/dist/runtime/server/events/adapters/memoryAdapter.js +171 -0
  127. package/dist/runtime/server/events/adapters/redis/redisAdapter.d.ts +2 -0
  128. package/dist/runtime/server/events/adapters/redis/redisAdapter.js +348 -0
  129. package/dist/runtime/server/events/adapters/redis/redisPubSubGateway.d.ts +29 -0
  130. package/dist/runtime/server/events/adapters/redis/redisPubSubGateway.js +82 -0
  131. package/dist/runtime/server/events/eventBus.d.ts +20 -0
  132. package/dist/runtime/server/events/eventBus.js +35 -0
  133. package/dist/runtime/server/events/eventStoreFactory.d.ts +19 -0
  134. package/dist/runtime/server/events/eventStoreFactory.js +44 -0
  135. package/dist/runtime/server/events/streamNames.d.ts +17 -0
  136. package/dist/runtime/server/events/streamNames.js +17 -0
  137. package/dist/runtime/server/events/types.d.ts +63 -0
  138. package/dist/runtime/server/events/types.js +0 -0
  139. package/dist/runtime/server/events/wiring/flowWiring.d.ts +33 -0
  140. package/dist/runtime/server/events/wiring/flowWiring.js +406 -0
  141. package/dist/runtime/server/events/wiring/registry.d.ts +10 -0
  142. package/dist/runtime/server/events/wiring/registry.js +24 -0
  143. package/dist/runtime/server/plugins/00.event-store.d.ts +13 -0
  144. package/dist/runtime/server/plugins/00.event-store.js +16 -0
  145. package/dist/runtime/server/plugins/00.ws-lifecycle.d.ts +5 -0
  146. package/dist/runtime/server/plugins/00.ws-lifecycle.js +66 -0
  147. package/dist/runtime/server/plugins/flow-management.d.ts +13 -0
  148. package/dist/runtime/server/plugins/flow-management.js +65 -0
  149. package/dist/runtime/server/plugins/queue-management.d.ts +2 -0
  150. package/dist/runtime/server/plugins/queue-management.js +27 -0
  151. package/dist/runtime/server/plugins/state-cleanup.d.ts +11 -0
  152. package/dist/runtime/server/plugins/state-cleanup.js +93 -0
  153. package/dist/runtime/server/plugins/worker-management.d.ts +2 -0
  154. package/dist/runtime/server/plugins/worker-management.js +33 -0
  155. package/dist/runtime/server/queue/adapters/bullmq.d.ts +17 -0
  156. package/dist/runtime/server/queue/adapters/bullmq.js +164 -0
  157. package/dist/runtime/server/queue/queueFactory.d.ts +3 -0
  158. package/dist/runtime/server/queue/queueFactory.js +10 -0
  159. package/dist/runtime/server/queue/types.d.ts +47 -0
  160. package/dist/runtime/server/queue/types.js +0 -0
  161. package/dist/runtime/server/state/adapters/redis.d.ts +2 -0
  162. package/dist/runtime/server/state/adapters/redis.js +42 -0
  163. package/dist/runtime/server/state/stateFactory.d.ts +3 -0
  164. package/dist/runtime/server/state/stateFactory.js +17 -0
  165. package/dist/runtime/server/state/types.d.ts +23 -0
  166. package/dist/runtime/server/state/types.js +0 -0
  167. package/dist/runtime/server/tsconfig.json +3 -0
  168. package/dist/runtime/server/utils/defineQueueConfig.d.ts +154 -0
  169. package/dist/runtime/server/utils/defineQueueConfig.js +2 -0
  170. package/dist/runtime/server/utils/defineQueueWorker.d.ts +10 -0
  171. package/dist/runtime/server/utils/defineQueueWorker.js +17 -0
  172. package/dist/runtime/server/utils/useEventManager.d.ts +15 -0
  173. package/dist/runtime/server/utils/useEventManager.js +26 -0
  174. package/dist/runtime/server/utils/useEventStore.d.ts +20 -0
  175. package/dist/runtime/server/utils/useEventStore.js +119 -0
  176. package/dist/runtime/server/utils/useFlowEngine.d.ts +9 -0
  177. package/dist/runtime/server/utils/useFlowEngine.js +44 -0
  178. package/dist/runtime/server/utils/useLogs.d.ts +41 -0
  179. package/dist/runtime/server/utils/useLogs.js +74 -0
  180. package/dist/runtime/server/utils/useQueue.d.ts +31 -0
  181. package/dist/runtime/server/utils/useQueue.js +24 -0
  182. package/dist/runtime/server/utils/useServerLogger.d.ts +42 -0
  183. package/dist/runtime/server/utils/useServerLogger.js +54 -0
  184. package/dist/runtime/server/utils/wsPeerManager.d.ts +34 -0
  185. package/dist/runtime/server/utils/wsPeerManager.js +23 -0
  186. package/dist/runtime/server/worker/adapter.d.ts +4 -0
  187. package/dist/runtime/server/worker/adapter.js +65 -0
  188. package/dist/runtime/server/worker/runner/node.d.ts +27 -0
  189. package/dist/runtime/server/worker/runner/node.js +196 -0
  190. package/dist/runtime/types.d.ts +132 -0
  191. package/dist/types.d.mts +3 -0
  192. package/package.json +75 -0
@@ -0,0 +1,127 @@
1
+ <template>
2
+ <div class="flex flex-col h-full">
3
+ <!-- Filter Bar -->
4
+ <div class="flex items-center gap-3 px-6 py-3 border-b border-gray-200 dark:border-gray-800 bg-gray-50 dark:bg-gray-900/50 shrink-0">
5
+ <div class="flex items-center gap-2">
6
+ <span class="text-xs font-medium text-gray-700 dark:text-gray-300">Show:</span>
7
+ <URadioGroup
8
+ v-model="filter"
9
+ :items="filterOptions"
10
+ orientation="horizontal"
11
+ size="xs"
12
+ variant="table"
13
+ indicator="hidden"
14
+ :ui="{
15
+ base: 'size-2',
16
+ container: 'h-2',
17
+ item: 'p-1'
18
+ }"
19
+ />
20
+ </div>
21
+
22
+ <div class="flex items-center gap-2 ml-auto">
23
+ <UButton
24
+ size="xs"
25
+ color="neutral"
26
+ variant="outline"
27
+ :disabled="filteredItems.length === 0"
28
+ @click="$emit('export')"
29
+ >
30
+ Export JSON
31
+ </UButton>
32
+ <div class="text-xs text-gray-500">
33
+ {{ filteredItems.length }} item{{ filteredItems.length === 1 ? "" : "s" }}
34
+ </div>
35
+ </div>
36
+ </div>
37
+
38
+ <!-- Combined Timeline/Logs Content -->
39
+ <div class="flex-1 overflow-y-auto overflow-x-hidden">
40
+ <div
41
+ v-if="filteredItems.length === 0"
42
+ class="h-full flex flex-col items-center justify-center text-gray-400 dark:text-gray-500"
43
+ >
44
+ <UIcon
45
+ name="i-lucide-inbox"
46
+ class="w-12 h-12 mb-3 opacity-50"
47
+ />
48
+ <span class="text-sm">No {{ filter === "all" ? "items" : filter }} yet.</span>
49
+ </div>
50
+ <TimelineList
51
+ v-else
52
+ :items="filteredItems"
53
+ height-class="min-h-full"
54
+ />
55
+ </div>
56
+ </div>
57
+ </template>
58
+
59
+ <script setup>
60
+ import { ref, computed } from "#imports";
61
+ import TimelineList from "./TimelineList.vue";
62
+ import { UButton, UIcon, URadioGroup } from "#components";
63
+ const props = defineProps({
64
+ events: { type: Array, required: true },
65
+ logs: { type: Array, required: true },
66
+ isLive: { type: Boolean, required: false }
67
+ });
68
+ defineEmits(["export"]);
69
+ const filter = ref("all");
70
+ const filterOptions = [
71
+ { value: "all", label: "All" },
72
+ { value: "events", label: "Events" },
73
+ { value: "logs", label: "Logs" }
74
+ ];
75
+ function getItemHash(item) {
76
+ if (item.type === "log") {
77
+ const message = item.data?.message || item.data?.msg || "";
78
+ const level = item.data?.level || "info";
79
+ const step2 = item.stepName || item.data?.stepName || "";
80
+ const ts2 = item.ts || 0;
81
+ return `log-${ts2}-${step2}-${level}-${message}`.toLowerCase();
82
+ }
83
+ const step = item.stepName || "";
84
+ const ts = item.ts || 0;
85
+ return `${item.type}-${ts}-${step}`.toLowerCase();
86
+ }
87
+ const filteredItems = computed(() => {
88
+ const allItems = [];
89
+ allItems.push(...props.events);
90
+ const logItems = props.logs.map((log) => ({
91
+ id: `log-${log.ts}`,
92
+ ts: log.ts,
93
+ type: "log",
94
+ stepName: log.step || log.stepName,
95
+ data: {
96
+ level: log.level,
97
+ message: log.msg || log.message,
98
+ ...log.data
99
+ }
100
+ }));
101
+ allItems.push(...logItems);
102
+ const seenHashes = /* @__PURE__ */ new Set();
103
+ const uniqueItems = [];
104
+ allItems.forEach((item) => {
105
+ const hash = getItemHash(item);
106
+ if (!seenHashes.has(hash)) {
107
+ seenHashes.add(hash);
108
+ uniqueItems.push(item);
109
+ }
110
+ });
111
+ let deduplicatedItems = uniqueItems;
112
+ if (filter.value === "events") {
113
+ deduplicatedItems = uniqueItems.filter((item) => item.type !== "log");
114
+ } else if (filter.value === "logs") {
115
+ deduplicatedItems = uniqueItems.filter((item) => item.type === "log");
116
+ }
117
+ deduplicatedItems.sort((a, b) => {
118
+ const getTs = (item) => {
119
+ if (typeof item.ts === "number") return item.ts;
120
+ if (typeof item.ts === "string") return new Date(item.ts).getTime();
121
+ return 0;
122
+ };
123
+ return getTs(b) - getTs(a);
124
+ });
125
+ return deduplicatedItems;
126
+ });
127
+ </script>
@@ -0,0 +1,12 @@
1
+ type __VLS_Props = {
2
+ events: any[];
3
+ logs: any[];
4
+ isLive?: boolean;
5
+ };
6
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
+ export: () => any;
8
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
9
+ onExport?: (() => any) | undefined;
10
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
+ declare const _default: typeof __VLS_export;
12
+ export default _default;
@@ -0,0 +1,16 @@
1
+ type __VLS_Props = {
2
+ flowName: string;
3
+ };
4
+ type __VLS_ModelProps = {
5
+ modelValue?: boolean;
6
+ };
7
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ scheduled: () => any;
10
+ "update:modelValue": (value: boolean) => any;
11
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
12
+ onScheduled?: (() => any) | undefined;
13
+ "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
14
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
@@ -0,0 +1,226 @@
1
+ <template>
2
+ <UModal v-model:open="isOpen">
3
+ <template #header>
4
+ <div class="flex items-center justify-between">
5
+ <div>
6
+ <h3 class="text-lg font-semibold">
7
+ Schedule Flow
8
+ </h3>
9
+ <p class="text-sm text-gray-500 mt-1">
10
+ {{ flowName }}
11
+ </p>
12
+ </div>
13
+ </div>
14
+ </template>
15
+ <template #body>
16
+ <div class="space-y-4">
17
+ <!-- Schedule Type -->
18
+ <div>
19
+ <label class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
20
+ Schedule Type
21
+ </label>
22
+ <UTabs
23
+ v-model="scheduleType"
24
+ :items="typeOptions"
25
+ size="sm"
26
+ variant="pill"
27
+ color="neutral"
28
+ />
29
+ </div>
30
+
31
+ <!-- Cron Pattern -->
32
+ <div v-if="scheduleType === 'cron'">
33
+ <label class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
34
+ Pattern
35
+ </label>
36
+ <USelectMenu
37
+ v-model="selectedPreset"
38
+ :items="cronPresets"
39
+ class="w-full"
40
+ placeholder="Select preset or custom"
41
+ />
42
+ <UInput
43
+ v-if="selectedPreset?.value === 'custom'"
44
+ v-model="customCron"
45
+ placeholder="0 2 * * *"
46
+ class="mt-2 w-full"
47
+ />
48
+ </div>
49
+
50
+ <!-- Delay -->
51
+ <div v-else-if="scheduleType === 'delay'">
52
+ <label class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
53
+ Delay
54
+ </label>
55
+ <div class="flex gap-2">
56
+ <UInput
57
+ v-model="delayValue"
58
+ type="number"
59
+ placeholder="5"
60
+ class="flex-1"
61
+ />
62
+ <USelectMenu
63
+ v-model="delayUnit"
64
+ :items="delayUnits"
65
+ class="w-32"
66
+ />
67
+ </div>
68
+ </div>
69
+
70
+ <!-- Input Data -->
71
+ <div>
72
+ <label class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
73
+ Input Data (JSON)
74
+ </label>
75
+ <UTextarea
76
+ v-model="inputJson"
77
+ placeholder="{ &quot;key&quot;: &quot;value&quot; }"
78
+ :rows="4"
79
+ class="font-mono text-sm w-full"
80
+ />
81
+ <p
82
+ v-if="jsonError"
83
+ class="text-xs text-red-500 mt-1"
84
+ >
85
+ {{ jsonError }}
86
+ </p>
87
+ </div>
88
+
89
+ <!-- Description -->
90
+ <div>
91
+ <label class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
92
+ Description (optional)
93
+ </label>
94
+ <UInput
95
+ v-model="description"
96
+ class="w-full"
97
+ placeholder="Daily cleanup job"
98
+ />
99
+ </div>
100
+ </div>
101
+ </template>
102
+ <template #footer>
103
+ <div class="flex justify-end gap-2">
104
+ <UButton
105
+ color="neutral"
106
+ variant="ghost"
107
+ @click="isOpen = false"
108
+ >
109
+ Cancel
110
+ </UButton>
111
+ <UButton
112
+ color="primary"
113
+ :loading="isSubmitting"
114
+ :disabled="!canSubmit"
115
+ @click="handleSubmit"
116
+ >
117
+ Schedule Flow
118
+ </UButton>
119
+ </div>
120
+ </template>
121
+ </UModal>
122
+ </template>
123
+
124
+ <script setup>
125
+ import { ref, computed, watch } from "#imports";
126
+ import { UModal, UButton, UTabs, USelectMenu, UInput, UTextarea } from "#components";
127
+ const props = defineProps({
128
+ flowName: { type: String, required: true }
129
+ });
130
+ const emit = defineEmits(["scheduled"]);
131
+ const isOpen = defineModel({ type: Boolean, ...{ default: false } });
132
+ const scheduleType = ref("cron");
133
+ const typeOptions = [
134
+ { label: "Recurring (Cron)", value: "cron" },
135
+ { label: "One-time (Delay)", value: "delay" }
136
+ ];
137
+ const cronPresets = [
138
+ { label: "Every minute", value: "* * * * *" },
139
+ { label: "Every 5 minutes", value: "*/5 * * * *" },
140
+ { label: "Every hour", value: "0 * * * *" },
141
+ { label: "Daily at 2 AM", value: "0 2 * * *" },
142
+ { label: "Daily at noon", value: "0 12 * * *" },
143
+ { label: "Weekly (Monday 9 AM)", value: "0 9 * * 1" },
144
+ { label: "Monthly (1st at midnight)", value: "0 0 1 * *" },
145
+ { label: "Custom", value: "custom" }
146
+ ];
147
+ const selectedPreset = ref(cronPresets[3]);
148
+ const customCron = ref("");
149
+ const delayValue = ref("5");
150
+ const delayUnit = ref({ label: "Minutes", value: 6e4 });
151
+ const delayUnits = [
152
+ { label: "Seconds", value: 1e3 },
153
+ { label: "Minutes", value: 6e4 },
154
+ { label: "Hours", value: 36e5 },
155
+ { label: "Days", value: 864e5 }
156
+ ];
157
+ const inputJson = ref("");
158
+ const description = ref("");
159
+ const isSubmitting = ref(false);
160
+ const jsonError = computed(() => {
161
+ if (!inputJson.value)
162
+ return null;
163
+ try {
164
+ JSON.parse(inputJson.value);
165
+ return null;
166
+ } catch (e) {
167
+ return `Invalid JSON: ${e.message}`;
168
+ }
169
+ });
170
+ const canSubmit = computed(() => {
171
+ if (jsonError.value)
172
+ return false;
173
+ if (scheduleType.value === "cron") {
174
+ if (selectedPreset.value?.value === "custom") {
175
+ return customCron.value.trim().length > 0;
176
+ }
177
+ return selectedPreset.value?.value != null;
178
+ } else {
179
+ const num = Number.parseInt(delayValue.value);
180
+ return !Number.isNaN(num) && num > 0;
181
+ }
182
+ });
183
+ const handleSubmit = async () => {
184
+ isSubmitting.value = true;
185
+ try {
186
+ let input = {};
187
+ if (inputJson.value) {
188
+ input = JSON.parse(inputJson.value);
189
+ }
190
+ const body = {
191
+ input,
192
+ metadata: {
193
+ description: description.value || void 0
194
+ }
195
+ };
196
+ if (scheduleType.value === "cron") {
197
+ body.cron = selectedPreset.value?.value === "custom" ? customCron.value : selectedPreset.value?.value;
198
+ } else {
199
+ const num = Number.parseInt(delayValue.value);
200
+ body.delay = num * delayUnit.value.value;
201
+ }
202
+ await $fetch(`/api/_flows/${props.flowName}/schedule`, {
203
+ method: "POST",
204
+ body
205
+ });
206
+ emit("scheduled");
207
+ isOpen.value = false;
208
+ inputJson.value = "";
209
+ description.value = "";
210
+ customCron.value = "";
211
+ delayValue.value = "5";
212
+ } finally {
213
+ isSubmitting.value = false;
214
+ }
215
+ };
216
+ watch(isOpen, (newVal) => {
217
+ if (!newVal) {
218
+ scheduleType.value = "cron";
219
+ selectedPreset.value = cronPresets[3];
220
+ inputJson.value = "";
221
+ description.value = "";
222
+ customCron.value = "";
223
+ delayValue.value = "5";
224
+ }
225
+ });
226
+ </script>
@@ -0,0 +1,16 @@
1
+ type __VLS_Props = {
2
+ flowName: string;
3
+ };
4
+ type __VLS_ModelProps = {
5
+ modelValue?: boolean;
6
+ };
7
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ scheduled: () => any;
10
+ "update:modelValue": (value: boolean) => any;
11
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
12
+ onScheduled?: (() => any) | undefined;
13
+ "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
14
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
@@ -0,0 +1,12 @@
1
+ type __VLS_Props = {
2
+ flowName: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
5
+ loadSchedules: () => Promise<void>;
6
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
+ updated: () => any;
8
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
9
+ onUpdated?: (() => any) | undefined;
10
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
+ declare const _default: typeof __VLS_export;
12
+ export default _default;
@@ -0,0 +1,99 @@
1
+ <template>
2
+ <div class="space-y-4">
3
+ <div v-if="!schedules || schedules.length === 0">
4
+ <UAlert
5
+ color="info"
6
+ title="No schedules configured"
7
+ variant="subtle"
8
+ icon="i-lucide-info"
9
+ description="Create a schedule to run this flow automatically"
10
+ />
11
+ </div>
12
+
13
+ <div
14
+ v-for="schedule in schedules"
15
+ :key="schedule.id"
16
+ class="border border-gray-200 dark:border-gray-800 rounded-lg p-4"
17
+ >
18
+ <div class="flex items-start justify-between">
19
+ <div class="flex-1">
20
+ <div class="flex items-center gap-2 mb-2">
21
+ <UIcon
22
+ name="i-lucide-clock"
23
+ class="text-blue-500"
24
+ />
25
+ <span class="font-medium text-sm">
26
+ {{ schedule.schedule.cron || "One-time delay" }}
27
+ </span>
28
+ </div>
29
+ <div class="text-xs text-gray-500 space-y-1">
30
+ <div>
31
+ <span class="font-medium">Next run:</span>
32
+ {{ formatDate(schedule.nextRun) }}
33
+ </div>
34
+ <div v-if="schedule.metadata?.description">
35
+ <span class="font-medium">Description:</span>
36
+ {{ schedule.metadata.description }}
37
+ </div>
38
+ </div>
39
+ </div>
40
+ <UButton
41
+ icon="i-lucide-trash-2"
42
+ color="error"
43
+ variant="ghost"
44
+ size="xs"
45
+ :loading="deletingId === schedule.id"
46
+ @click="handleDelete(schedule.id)"
47
+ />
48
+ </div>
49
+ </div>
50
+ </div>
51
+ </template>
52
+
53
+ <script setup>
54
+ import { ref, onMounted } from "#imports";
55
+ import { UAlert, UButton, UIcon } from "#components";
56
+ const props = defineProps({
57
+ flowName: { type: String, required: true }
58
+ });
59
+ const emit = defineEmits(["updated"]);
60
+ const schedules = ref([]);
61
+ const deletingId = ref(null);
62
+ const loadSchedules = async () => {
63
+ try {
64
+ const data = await $fetch(`/api/_flows/${props.flowName}/schedules`);
65
+ schedules.value = data;
66
+ } catch (error) {
67
+ console.error("Failed to load schedules:", error);
68
+ schedules.value = [];
69
+ }
70
+ };
71
+ const handleDelete = async (id) => {
72
+ deletingId.value = id;
73
+ try {
74
+ await $fetch(`/api/_flows/${props.flowName}/schedules/${id}`, {
75
+ method: "DELETE"
76
+ });
77
+ await loadSchedules();
78
+ emit("updated");
79
+ } catch (error) {
80
+ console.error("Failed to delete schedule:", error);
81
+ } finally {
82
+ deletingId.value = null;
83
+ }
84
+ };
85
+ const formatDate = (date) => {
86
+ if (!date)
87
+ return "N/A";
88
+ return new Date(date).toLocaleString("en-US", {
89
+ dateStyle: "medium",
90
+ timeStyle: "short"
91
+ });
92
+ };
93
+ onMounted(() => {
94
+ loadSchedules();
95
+ });
96
+ defineExpose({
97
+ loadSchedules
98
+ });
99
+ </script>
@@ -0,0 +1,12 @@
1
+ type __VLS_Props = {
2
+ flowName: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
5
+ loadSchedules: () => Promise<void>;
6
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
+ updated: () => any;
8
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
9
+ onUpdated?: (() => any) | undefined;
10
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
+ declare const _default: typeof __VLS_export;
12
+ export default _default;
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ queue: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;