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.
- package/LICENSE +21 -0
- package/README.md +389 -0
- package/dist/module.d.mts +193 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +974 -0
- package/dist/runtime/app/components/ConfirmDialog.d.vue.ts +33 -0
- package/dist/runtime/app/components/ConfirmDialog.vue +121 -0
- package/dist/runtime/app/components/ConfirmDialog.vue.d.ts +33 -0
- package/dist/runtime/app/components/FlowDiagram.d.vue.ts +64 -0
- package/dist/runtime/app/components/FlowDiagram.vue +338 -0
- package/dist/runtime/app/components/FlowDiagram.vue.d.ts +64 -0
- package/dist/runtime/app/components/FlowNodeCard.d.vue.ts +29 -0
- package/dist/runtime/app/components/FlowNodeCard.vue +156 -0
- package/dist/runtime/app/components/FlowNodeCard.vue.d.ts +29 -0
- package/dist/runtime/app/components/FlowRunOverview.d.vue.ts +9 -0
- package/dist/runtime/app/components/FlowRunOverview.vue +291 -0
- package/dist/runtime/app/components/FlowRunOverview.vue.d.ts +9 -0
- package/dist/runtime/app/components/FlowRunStatusBadge.d.vue.ts +14 -0
- package/dist/runtime/app/components/FlowRunStatusBadge.vue +60 -0
- package/dist/runtime/app/components/FlowRunStatusBadge.vue.d.ts +14 -0
- package/dist/runtime/app/components/FlowRunTimeline.d.vue.ts +12 -0
- package/dist/runtime/app/components/FlowRunTimeline.vue +127 -0
- package/dist/runtime/app/components/FlowRunTimeline.vue.d.ts +12 -0
- package/dist/runtime/app/components/FlowScheduleDialog.d.vue.ts +16 -0
- package/dist/runtime/app/components/FlowScheduleDialog.vue +226 -0
- package/dist/runtime/app/components/FlowScheduleDialog.vue.d.ts +16 -0
- package/dist/runtime/app/components/FlowSchedulesList.d.vue.ts +12 -0
- package/dist/runtime/app/components/FlowSchedulesList.vue +99 -0
- package/dist/runtime/app/components/FlowSchedulesList.vue.d.ts +12 -0
- package/dist/runtime/app/components/JobScheduling.d.vue.ts +6 -0
- package/dist/runtime/app/components/JobScheduling.vue +203 -0
- package/dist/runtime/app/components/JobScheduling.vue.d.ts +6 -0
- package/dist/runtime/app/components/ListItem.d.vue.ts +23 -0
- package/dist/runtime/app/components/ListItem.vue +70 -0
- package/dist/runtime/app/components/ListItem.vue.d.ts +23 -0
- package/dist/runtime/app/components/QueueConfigDetails.d.vue.ts +45 -0
- package/dist/runtime/app/components/QueueConfigDetails.vue +412 -0
- package/dist/runtime/app/components/QueueConfigDetails.vue.d.ts +45 -0
- package/dist/runtime/app/components/StatCounter.d.vue.ts +9 -0
- package/dist/runtime/app/components/StatCounter.vue +25 -0
- package/dist/runtime/app/components/StatCounter.vue.d.ts +9 -0
- package/dist/runtime/app/components/TimelineList.d.vue.ts +7 -0
- package/dist/runtime/app/components/TimelineList.vue +210 -0
- package/dist/runtime/app/components/TimelineList.vue.d.ts +7 -0
- package/dist/runtime/app/components/nhealth/component-router.d.vue.ts +46 -0
- package/dist/runtime/app/components/nhealth/component-router.vue +26 -0
- package/dist/runtime/app/components/nhealth/component-router.vue.d.ts +46 -0
- package/dist/runtime/app/components/nhealth/component-shell.d.vue.ts +24 -0
- package/dist/runtime/app/components/nhealth/component-shell.vue +89 -0
- package/dist/runtime/app/components/nhealth/component-shell.vue.d.ts +24 -0
- package/dist/runtime/app/composables/useAnalyzedFlows.d.ts +14 -0
- package/dist/runtime/app/composables/useAnalyzedFlows.js +7 -0
- package/dist/runtime/app/composables/useComponentRouter.d.ts +38 -0
- package/dist/runtime/app/composables/useComponentRouter.js +240 -0
- package/dist/runtime/app/composables/useFlowRunTimeline.d.ts +15 -0
- package/dist/runtime/app/composables/useFlowRunTimeline.js +66 -0
- package/dist/runtime/app/composables/useFlowRuns.d.ts +11 -0
- package/dist/runtime/app/composables/useFlowRuns.js +31 -0
- package/dist/runtime/app/composables/useFlowRunsInfinite.d.ts +24 -0
- package/dist/runtime/app/composables/useFlowRunsInfinite.js +123 -0
- package/dist/runtime/app/composables/useFlowRunsPolling.d.ts +8 -0
- package/dist/runtime/app/composables/useFlowRunsPolling.js +26 -0
- package/dist/runtime/app/composables/useFlowState.d.ts +125 -0
- package/dist/runtime/app/composables/useFlowState.js +211 -0
- package/dist/runtime/app/composables/useFlowWebSocket.d.ts +27 -0
- package/dist/runtime/app/composables/useFlowWebSocket.js +205 -0
- package/dist/runtime/app/composables/useFlowsNavigation.d.ts +10 -0
- package/dist/runtime/app/composables/useFlowsNavigation.js +57 -0
- package/dist/runtime/app/composables/useQueueJobs.d.ts +20 -0
- package/dist/runtime/app/composables/useQueueJobs.js +20 -0
- package/dist/runtime/app/composables/useQueueUpdates.d.ts +26 -0
- package/dist/runtime/app/composables/useQueueUpdates.js +122 -0
- package/dist/runtime/app/composables/useQueues.d.ts +43 -0
- package/dist/runtime/app/composables/useQueues.js +26 -0
- package/dist/runtime/app/composables/useQueuesLive.d.ts +19 -0
- package/dist/runtime/app/composables/useQueuesLive.js +143 -0
- package/dist/runtime/app/pages/flows/index.d.vue.ts +3 -0
- package/dist/runtime/app/pages/flows/index.vue +645 -0
- package/dist/runtime/app/pages/flows/index.vue.d.ts +3 -0
- package/dist/runtime/app/pages/index.d.vue.ts +3 -0
- package/dist/runtime/app/pages/index.vue +34 -0
- package/dist/runtime/app/pages/index.vue.d.ts +3 -0
- package/dist/runtime/app/pages/queues/index.d.vue.ts +3 -0
- package/dist/runtime/app/pages/queues/index.vue +229 -0
- package/dist/runtime/app/pages/queues/index.vue.d.ts +3 -0
- package/dist/runtime/app/pages/queues/job.d.vue.ts +3 -0
- package/dist/runtime/app/pages/queues/job.vue +262 -0
- package/dist/runtime/app/pages/queues/job.vue.d.ts +3 -0
- package/dist/runtime/app/pages/queues/jobs.d.vue.ts +3 -0
- package/dist/runtime/app/pages/queues/jobs.vue +291 -0
- package/dist/runtime/app/pages/queues/jobs.vue.d.ts +3 -0
- package/dist/runtime/app/plugins/vueflow.client.d.ts +6 -0
- package/dist/runtime/app/plugins/vueflow.client.js +15 -0
- package/dist/runtime/constants.d.ts +11 -0
- package/dist/runtime/constants.js +11 -0
- package/dist/runtime/python/get_config.py +64 -0
- package/dist/runtime/schema.d.ts +37 -0
- package/dist/runtime/schema.js +20 -0
- package/dist/runtime/server/api/_flows/[name]/clear-history.delete.d.ts +10 -0
- package/dist/runtime/server/api/_flows/[name]/clear-history.delete.js +44 -0
- package/dist/runtime/server/api/_flows/[name]/runs.get.d.ts +7 -0
- package/dist/runtime/server/api/_flows/[name]/runs.get.js +53 -0
- package/dist/runtime/server/api/_flows/[name]/schedule.post.d.ts +2 -0
- package/dist/runtime/server/api/_flows/[name]/schedule.post.js +57 -0
- package/dist/runtime/server/api/_flows/[name]/schedules/[id].delete.d.ts +2 -0
- package/dist/runtime/server/api/_flows/[name]/schedules/[id].delete.js +42 -0
- package/dist/runtime/server/api/_flows/[name]/schedules.get.d.ts +2 -0
- package/dist/runtime/server/api/_flows/[name]/schedules.get.js +48 -0
- package/dist/runtime/server/api/_flows/[name]/start.post.d.ts +2 -0
- package/dist/runtime/server/api/_flows/[name]/start.post.js +9 -0
- package/dist/runtime/server/api/_flows/index.get.d.ts +6 -0
- package/dist/runtime/server/api/_flows/index.get.js +5 -0
- package/dist/runtime/server/api/_flows/ws.d.ts +60 -0
- package/dist/runtime/server/api/_flows/ws.js +183 -0
- package/dist/runtime/server/api/_queues/[name]/job/[id].get.d.ts +2 -0
- package/dist/runtime/server/api/_queues/[name]/job/[id].get.js +9 -0
- package/dist/runtime/server/api/_queues/[name]/job/index.get.d.ts +2 -0
- package/dist/runtime/server/api/_queues/[name]/job/index.get.js +18 -0
- package/dist/runtime/server/api/_queues/index.get.d.ts +2 -0
- package/dist/runtime/server/api/_queues/index.get.js +63 -0
- package/dist/runtime/server/api/_queues/ws.d.ts +48 -0
- package/dist/runtime/server/api/_queues/ws.js +200 -0
- package/dist/runtime/server/events/adapters/fileAdapter.d.ts +2 -0
- package/dist/runtime/server/events/adapters/fileAdapter.js +382 -0
- package/dist/runtime/server/events/adapters/memoryAdapter.d.ts +2 -0
- package/dist/runtime/server/events/adapters/memoryAdapter.js +171 -0
- package/dist/runtime/server/events/adapters/redis/redisAdapter.d.ts +2 -0
- package/dist/runtime/server/events/adapters/redis/redisAdapter.js +348 -0
- package/dist/runtime/server/events/adapters/redis/redisPubSubGateway.d.ts +29 -0
- package/dist/runtime/server/events/adapters/redis/redisPubSubGateway.js +82 -0
- package/dist/runtime/server/events/eventBus.d.ts +20 -0
- package/dist/runtime/server/events/eventBus.js +35 -0
- package/dist/runtime/server/events/eventStoreFactory.d.ts +19 -0
- package/dist/runtime/server/events/eventStoreFactory.js +44 -0
- package/dist/runtime/server/events/streamNames.d.ts +17 -0
- package/dist/runtime/server/events/streamNames.js +17 -0
- package/dist/runtime/server/events/types.d.ts +63 -0
- package/dist/runtime/server/events/types.js +0 -0
- package/dist/runtime/server/events/wiring/flowWiring.d.ts +33 -0
- package/dist/runtime/server/events/wiring/flowWiring.js +406 -0
- package/dist/runtime/server/events/wiring/registry.d.ts +10 -0
- package/dist/runtime/server/events/wiring/registry.js +24 -0
- package/dist/runtime/server/plugins/00.event-store.d.ts +13 -0
- package/dist/runtime/server/plugins/00.event-store.js +16 -0
- package/dist/runtime/server/plugins/00.ws-lifecycle.d.ts +5 -0
- package/dist/runtime/server/plugins/00.ws-lifecycle.js +66 -0
- package/dist/runtime/server/plugins/flow-management.d.ts +13 -0
- package/dist/runtime/server/plugins/flow-management.js +65 -0
- package/dist/runtime/server/plugins/queue-management.d.ts +2 -0
- package/dist/runtime/server/plugins/queue-management.js +27 -0
- package/dist/runtime/server/plugins/state-cleanup.d.ts +11 -0
- package/dist/runtime/server/plugins/state-cleanup.js +93 -0
- package/dist/runtime/server/plugins/worker-management.d.ts +2 -0
- package/dist/runtime/server/plugins/worker-management.js +33 -0
- package/dist/runtime/server/queue/adapters/bullmq.d.ts +17 -0
- package/dist/runtime/server/queue/adapters/bullmq.js +164 -0
- package/dist/runtime/server/queue/queueFactory.d.ts +3 -0
- package/dist/runtime/server/queue/queueFactory.js +10 -0
- package/dist/runtime/server/queue/types.d.ts +47 -0
- package/dist/runtime/server/queue/types.js +0 -0
- package/dist/runtime/server/state/adapters/redis.d.ts +2 -0
- package/dist/runtime/server/state/adapters/redis.js +42 -0
- package/dist/runtime/server/state/stateFactory.d.ts +3 -0
- package/dist/runtime/server/state/stateFactory.js +17 -0
- package/dist/runtime/server/state/types.d.ts +23 -0
- package/dist/runtime/server/state/types.js +0 -0
- package/dist/runtime/server/tsconfig.json +3 -0
- package/dist/runtime/server/utils/defineQueueConfig.d.ts +154 -0
- package/dist/runtime/server/utils/defineQueueConfig.js +2 -0
- package/dist/runtime/server/utils/defineQueueWorker.d.ts +10 -0
- package/dist/runtime/server/utils/defineQueueWorker.js +17 -0
- package/dist/runtime/server/utils/useEventManager.d.ts +15 -0
- package/dist/runtime/server/utils/useEventManager.js +26 -0
- package/dist/runtime/server/utils/useEventStore.d.ts +20 -0
- package/dist/runtime/server/utils/useEventStore.js +119 -0
- package/dist/runtime/server/utils/useFlowEngine.d.ts +9 -0
- package/dist/runtime/server/utils/useFlowEngine.js +44 -0
- package/dist/runtime/server/utils/useLogs.d.ts +41 -0
- package/dist/runtime/server/utils/useLogs.js +74 -0
- package/dist/runtime/server/utils/useQueue.d.ts +31 -0
- package/dist/runtime/server/utils/useQueue.js +24 -0
- package/dist/runtime/server/utils/useServerLogger.d.ts +42 -0
- package/dist/runtime/server/utils/useServerLogger.js +54 -0
- package/dist/runtime/server/utils/wsPeerManager.d.ts +34 -0
- package/dist/runtime/server/utils/wsPeerManager.js +23 -0
- package/dist/runtime/server/worker/adapter.d.ts +4 -0
- package/dist/runtime/server/worker/adapter.js +65 -0
- package/dist/runtime/server/worker/runner/node.d.ts +27 -0
- package/dist/runtime/server/worker/runner/node.js +196 -0
- package/dist/runtime/types.d.ts +132 -0
- package/dist/types.d.mts +3 -0
- 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="{ "key": "value" }"
|
|
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;
|