@antelopejs/dms-automation 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +190 -0
- package/README.md +95 -0
- package/dist/cluster/bus.d.ts +17 -0
- package/dist/cluster/bus.js +82 -0
- package/dist/cluster/bus.js.map +1 -0
- package/dist/cluster/instance.d.ts +1 -0
- package/dist/cluster/instance.js +6 -0
- package/dist/cluster/instance.js.map +1 -0
- package/dist/cluster/leader.d.ts +7 -0
- package/dist/cluster/leader.js +123 -0
- package/dist/cluster/leader.js.map +1 -0
- package/dist/cluster/mode.d.ts +3 -0
- package/dist/cluster/mode.js +25 -0
- package/dist/cluster/mode.js.map +1 -0
- package/dist/data/procedures-table.d.ts +66 -0
- package/dist/data/procedures-table.js +271 -0
- package/dist/data/procedures-table.js.map +1 -0
- package/dist/data/runs-table.d.ts +23 -0
- package/dist/data/runs-table.js +125 -0
- package/dist/data/runs-table.js.map +1 -0
- package/dist/db/index.d.ts +7 -0
- package/dist/db/index.js +24 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/models/automation_template.model.d.ts +58 -0
- package/dist/db/models/automation_template.model.js +134 -0
- package/dist/db/models/automation_template.model.js.map +1 -0
- package/dist/db/models/index.d.ts +3 -0
- package/dist/db/models/index.js +20 -0
- package/dist/db/models/index.js.map +1 -0
- package/dist/db/models/procedure.model.d.ts +25 -0
- package/dist/db/models/procedure.model.js +28 -0
- package/dist/db/models/procedure.model.js.map +1 -0
- package/dist/db/models/procedure_run.model.d.ts +34 -0
- package/dist/db/models/procedure_run.model.js +39 -0
- package/dist/db/models/procedure_run.model.js.map +1 -0
- package/dist/db/models/stats.model.d.ts +73 -0
- package/dist/db/models/stats.model.js +267 -0
- package/dist/db/models/stats.model.js.map +1 -0
- package/dist/db/models/type_config.model.d.ts +47 -0
- package/dist/db/models/type_config.model.js +51 -0
- package/dist/db/models/type_config.model.js.map +1 -0
- package/dist/db/tables/action_type_config.table.d.ts +7 -0
- package/dist/db/tables/action_type_config.table.js +35 -0
- package/dist/db/tables/action_type_config.table.js.map +1 -0
- package/dist/db/tables/automation_template.table.d.ts +11 -0
- package/dist/db/tables/automation_template.table.js +52 -0
- package/dist/db/tables/automation_template.table.js.map +1 -0
- package/dist/db/tables/index.d.ts +5 -0
- package/dist/db/tables/index.js +22 -0
- package/dist/db/tables/index.js.map +1 -0
- package/dist/db/tables/procedure.table.d.ts +10 -0
- package/dist/db/tables/procedure.table.js +48 -0
- package/dist/db/tables/procedure.table.js.map +1 -0
- package/dist/db/tables/procedure_run.table.d.ts +13 -0
- package/dist/db/tables/procedure_run.table.js +57 -0
- package/dist/db/tables/procedure_run.table.js.map +1 -0
- package/dist/db/tables/trigger_type_config.table.d.ts +7 -0
- package/dist/db/tables/trigger_type_config.table.js +35 -0
- package/dist/db/tables/trigger_type_config.table.js.map +1 -0
- package/dist/implementations/dms-automation/index.d.ts +19 -0
- package/dist/implementations/dms-automation/index.js +50 -0
- package/dist/implementations/dms-automation/index.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +121 -0
- package/dist/index.js.map +1 -0
- package/dist/pages/builder.d.ts +10 -0
- package/dist/pages/builder.js +28 -0
- package/dist/pages/builder.js.map +1 -0
- package/dist/pages/category.d.ts +1 -0
- package/dist/pages/category.js +10 -0
- package/dist/pages/category.js.map +1 -0
- package/dist/pages/index.d.ts +6 -0
- package/dist/pages/index.js +9 -0
- package/dist/pages/index.js.map +1 -0
- package/dist/pages/library.d.ts +10 -0
- package/dist/pages/library.js +28 -0
- package/dist/pages/library.js.map +1 -0
- package/dist/pages/overview.d.ts +10 -0
- package/dist/pages/overview.js +28 -0
- package/dist/pages/overview.js.map +1 -0
- package/dist/pages/procedures.d.ts +10 -0
- package/dist/pages/procedures.js +72 -0
- package/dist/pages/procedures.js.map +1 -0
- package/dist/pages/runs.d.ts +11 -0
- package/dist/pages/runs.js +61 -0
- package/dist/pages/runs.js.map +1 -0
- package/dist/routes/action-types.d.ts +23 -0
- package/dist/routes/action-types.js +80 -0
- package/dist/routes/action-types.js.map +1 -0
- package/dist/routes/data-node-types.d.ts +6 -0
- package/dist/routes/data-node-types.js +36 -0
- package/dist/routes/data-node-types.js.map +1 -0
- package/dist/routes/graphSchema.d.ts +92 -0
- package/dist/routes/graphSchema.js +60 -0
- package/dist/routes/graphSchema.js.map +1 -0
- package/dist/routes/index.d.ts +8 -0
- package/dist/routes/index.js +11 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/node-kinds.d.ts +9 -0
- package/dist/routes/node-kinds.js +35 -0
- package/dist/routes/node-kinds.js.map +1 -0
- package/dist/routes/procedures.d.ts +23 -0
- package/dist/routes/procedures.js +181 -0
- package/dist/routes/procedures.js.map +1 -0
- package/dist/routes/runs.d.ts +7 -0
- package/dist/routes/runs.js +81 -0
- package/dist/routes/runs.js.map +1 -0
- package/dist/routes/stats.d.ts +6 -0
- package/dist/routes/stats.js +35 -0
- package/dist/routes/stats.js.map +1 -0
- package/dist/routes/templates.d.ts +20 -0
- package/dist/routes/templates.js +243 -0
- package/dist/routes/templates.js.map +1 -0
- package/dist/routes/trigger-types.d.ts +24 -0
- package/dist/routes/trigger-types.js +80 -0
- package/dist/routes/trigger-types.js.map +1 -0
- package/dist/routes/typeConfigShared.d.ts +22 -0
- package/dist/routes/typeConfigShared.js +37 -0
- package/dist/routes/typeConfigShared.js.map +1 -0
- package/dist/runtime/builtins/actions/http.d.ts +13 -0
- package/dist/runtime/builtins/actions/http.js +47 -0
- package/dist/runtime/builtins/actions/http.js.map +1 -0
- package/dist/runtime/builtins/actions/index.d.ts +2 -0
- package/dist/runtime/builtins/actions/index.js +7 -0
- package/dist/runtime/builtins/actions/index.js.map +1 -0
- package/dist/runtime/builtins/actions/log.d.ts +13 -0
- package/dist/runtime/builtins/actions/log.js +49 -0
- package/dist/runtime/builtins/actions/log.js.map +1 -0
- package/dist/runtime/builtins/data/boolean.d.ts +2 -0
- package/dist/runtime/builtins/data/boolean.js +39 -0
- package/dist/runtime/builtins/data/boolean.js.map +1 -0
- package/dist/runtime/builtins/data/compare.d.ts +2 -0
- package/dist/runtime/builtins/data/compare.js +29 -0
- package/dist/runtime/builtins/data/compare.js.map +1 -0
- package/dist/runtime/builtins/data/constant.d.ts +2 -0
- package/dist/runtime/builtins/data/constant.js +29 -0
- package/dist/runtime/builtins/data/constant.js.map +1 -0
- package/dist/runtime/builtins/data/index.d.ts +2 -0
- package/dist/runtime/builtins/data/index.js +20 -0
- package/dist/runtime/builtins/data/index.js.map +1 -0
- package/dist/runtime/builtins/data/json.d.ts +2 -0
- package/dist/runtime/builtins/data/json.js +46 -0
- package/dist/runtime/builtins/data/json.js.map +1 -0
- package/dist/runtime/builtins/data/math.d.ts +2 -0
- package/dist/runtime/builtins/data/math.js +53 -0
- package/dist/runtime/builtins/data/math.js.map +1 -0
- package/dist/runtime/builtins/data/object.d.ts +2 -0
- package/dist/runtime/builtins/data/object.js +121 -0
- package/dist/runtime/builtins/data/object.js.map +1 -0
- package/dist/runtime/builtins/data/string.d.ts +2 -0
- package/dist/runtime/builtins/data/string.js +143 -0
- package/dist/runtime/builtins/data/string.js.map +1 -0
- package/dist/runtime/builtins/index.d.ts +17 -0
- package/dist/runtime/builtins/index.js +24 -0
- package/dist/runtime/builtins/index.js.map +1 -0
- package/dist/runtime/builtins/nodes/action.d.ts +1 -0
- package/dist/runtime/builtins/nodes/action.js +36 -0
- package/dist/runtime/builtins/nodes/action.js.map +1 -0
- package/dist/runtime/builtins/nodes/data.d.ts +1 -0
- package/dist/runtime/builtins/nodes/data.js +28 -0
- package/dist/runtime/builtins/nodes/data.js.map +1 -0
- package/dist/runtime/builtins/nodes/delay.d.ts +1 -0
- package/dist/runtime/builtins/nodes/delay.js +41 -0
- package/dist/runtime/builtins/nodes/delay.js.map +1 -0
- package/dist/runtime/builtins/nodes/forRange.d.ts +1 -0
- package/dist/runtime/builtins/nodes/forRange.js +52 -0
- package/dist/runtime/builtins/nodes/forRange.js.map +1 -0
- package/dist/runtime/builtins/nodes/foreach.d.ts +1 -0
- package/dist/runtime/builtins/nodes/foreach.js +31 -0
- package/dist/runtime/builtins/nodes/foreach.js.map +1 -0
- package/dist/runtime/builtins/nodes/groupInput.d.ts +1 -0
- package/dist/runtime/builtins/nodes/groupInput.js +11 -0
- package/dist/runtime/builtins/nodes/groupInput.js.map +1 -0
- package/dist/runtime/builtins/nodes/groupOutput.d.ts +1 -0
- package/dist/runtime/builtins/nodes/groupOutput.js +11 -0
- package/dist/runtime/builtins/nodes/groupOutput.js.map +1 -0
- package/dist/runtime/builtins/nodes/if.d.ts +1 -0
- package/dist/runtime/builtins/nodes/if.js +23 -0
- package/dist/runtime/builtins/nodes/if.js.map +1 -0
- package/dist/runtime/builtins/nodes/parallel.d.ts +1 -0
- package/dist/runtime/builtins/nodes/parallel.js +34 -0
- package/dist/runtime/builtins/nodes/parallel.js.map +1 -0
- package/dist/runtime/builtins/nodes/retry.d.ts +1 -0
- package/dist/runtime/builtins/nodes/retry.js +46 -0
- package/dist/runtime/builtins/nodes/retry.js.map +1 -0
- package/dist/runtime/builtins/nodes/setVariable.d.ts +1 -0
- package/dist/runtime/builtins/nodes/setVariable.js +31 -0
- package/dist/runtime/builtins/nodes/setVariable.js.map +1 -0
- package/dist/runtime/builtins/nodes/switch.d.ts +1 -0
- package/dist/runtime/builtins/nodes/switch.js +33 -0
- package/dist/runtime/builtins/nodes/switch.js.map +1 -0
- package/dist/runtime/builtins/nodes/trigger.d.ts +1 -0
- package/dist/runtime/builtins/nodes/trigger.js +25 -0
- package/dist/runtime/builtins/nodes/trigger.js.map +1 -0
- package/dist/runtime/builtins/nodes/tryCatch.d.ts +1 -0
- package/dist/runtime/builtins/nodes/tryCatch.js +35 -0
- package/dist/runtime/builtins/nodes/tryCatch.js.map +1 -0
- package/dist/runtime/builtins/triggers/cron.d.ts +9 -0
- package/dist/runtime/builtins/triggers/cron.js +52 -0
- package/dist/runtime/builtins/triggers/cron.js.map +1 -0
- package/dist/runtime/builtins/triggers/index.d.ts +2 -0
- package/dist/runtime/builtins/triggers/index.js +12 -0
- package/dist/runtime/builtins/triggers/index.js.map +1 -0
- package/dist/runtime/builtins/triggers/manual.d.ts +3 -0
- package/dist/runtime/builtins/triggers/manual.js +20 -0
- package/dist/runtime/builtins/triggers/manual.js.map +1 -0
- package/dist/runtime/builtins/triggers/webhook.d.ts +14 -0
- package/dist/runtime/builtins/triggers/webhook.js +90 -0
- package/dist/runtime/builtins/triggers/webhook.js.map +1 -0
- package/dist/runtime/executionResult.d.ts +6 -0
- package/dist/runtime/executionResult.js +3 -0
- package/dist/runtime/executionResult.js.map +1 -0
- package/dist/runtime/executor.d.ts +9 -0
- package/dist/runtime/executor.js +300 -0
- package/dist/runtime/executor.js.map +1 -0
- package/dist/runtime/flatten.d.ts +3 -0
- package/dist/runtime/flatten.js +188 -0
- package/dist/runtime/flatten.js.map +1 -0
- package/dist/runtime/nodeKinds.d.ts +64 -0
- package/dist/runtime/nodeKinds.js +43 -0
- package/dist/runtime/nodeKinds.js.map +1 -0
- package/dist/runtime/reconcileDiff.d.ts +9 -0
- package/dist/runtime/reconcileDiff.js +26 -0
- package/dist/runtime/reconcileDiff.js.map +1 -0
- package/dist/runtime/registry.d.ts +19 -0
- package/dist/runtime/registry.js +47 -0
- package/dist/runtime/registry.js.map +1 -0
- package/dist/runtime/resolveInputs.d.ts +14 -0
- package/dist/runtime/resolveInputs.js +64 -0
- package/dist/runtime/resolveInputs.js.map +1 -0
- package/dist/runtime/resolveSubgraph.d.ts +7 -0
- package/dist/runtime/resolveSubgraph.js +15 -0
- package/dist/runtime/resolveSubgraph.js.map +1 -0
- package/dist/runtime/subscriptions.d.ts +16 -0
- package/dist/runtime/subscriptions.js +419 -0
- package/dist/runtime/subscriptions.js.map +1 -0
- package/dist/runtime/subwalk.d.ts +17 -0
- package/dist/runtime/subwalk.js +74 -0
- package/dist/runtime/subwalk.js.map +1 -0
- package/dist/runtime/topo.d.ts +3 -0
- package/dist/runtime/topo.js +75 -0
- package/dist/runtime/topo.js.map +1 -0
- package/dist/runtime/typeOrigin.d.ts +7 -0
- package/dist/runtime/typeOrigin.js +24 -0
- package/dist/runtime/typeOrigin.js.map +1 -0
- package/dist/runtime/validate.d.ts +10 -0
- package/dist/runtime/validate.js +185 -0
- package/dist/runtime/validate.js.map +1 -0
- package/dist/runtime/validateTemplate.d.ts +3 -0
- package/dist/runtime/validateTemplate.js +54 -0
- package/dist/runtime/validateTemplate.js.map +1 -0
- package/dist/types/constants.d.ts +6 -0
- package/dist/types/constants.js +10 -0
- package/dist/types/constants.js.map +1 -0
- package/dist/types/graph.d.ts +51 -0
- package/dist/types/graph.js +23 -0
- package/dist/types/graph.js.map +1 -0
- package/dist/types/pagination.d.ts +8 -0
- package/dist/types/pagination.js +3 -0
- package/dist/types/pagination.js.map +1 -0
- package/dist/types/runLog.d.ts +26 -0
- package/dist/types/runLog.js +3 -0
- package/dist/types/runLog.js.map +1 -0
- package/frontend-vue/.prettierignore +4 -0
- package/frontend-vue/app/components/Actions.vue +141 -0
- package/frontend-vue/app/components/Catalog/TypeConfigForm.vue +166 -0
- package/frontend-vue/app/components/Catalog/TypeList.vue +198 -0
- package/frontend-vue/app/components/DataNodes.vue +259 -0
- package/frontend-vue/app/components/Editor/BuilderPalette.vue +234 -0
- package/frontend-vue/app/components/Editor/GraphCanvas.vue +994 -0
- package/frontend-vue/app/components/Editor/GroupPortEditor.vue +289 -0
- package/frontend-vue/app/components/Editor/JsonField.vue +63 -0
- package/frontend-vue/app/components/Editor/NodeInspector.vue +356 -0
- package/frontend-vue/app/components/Editor/ProcedureList.vue +156 -0
- package/frontend-vue/app/components/Editor/RunsDrawer.vue +312 -0
- package/frontend-vue/app/components/Editor/WiredField.vue +42 -0
- package/frontend-vue/app/components/Editor/nodes/GenericNode.vue +161 -0
- package/frontend-vue/app/components/Editor/nodes/GroupInputNode.vue +19 -0
- package/frontend-vue/app/components/Editor/nodes/GroupNode.vue +200 -0
- package/frontend-vue/app/components/Editor/nodes/GroupOutputNode.vue +19 -0
- package/frontend-vue/app/components/Editor/nodes/GroupSentinel.vue +161 -0
- package/frontend-vue/app/components/Editor/nodes/styles.ts +53 -0
- package/frontend-vue/app/components/Editor.vue +2504 -0
- package/frontend-vue/app/components/Library.vue +67 -0
- package/frontend-vue/app/components/Overview.vue +503 -0
- package/frontend-vue/app/components/RunDetailDrawer.vue +165 -0
- package/frontend-vue/app/components/RunFireTree.vue +170 -0
- package/frontend-vue/app/components/RunTraceDrawer.vue +59 -0
- package/frontend-vue/app/components/RunsStats.vue +126 -0
- package/frontend-vue/app/components/RunsTimelineDisplay.vue +287 -0
- package/frontend-vue/app/components/Templates.vue +663 -0
- package/frontend-vue/app/components/Triggers.vue +137 -0
- package/frontend-vue/app/composables/useAutomationNodeKinds.ts +48 -0
- package/frontend-vue/app/composables/useAutomationRuns.ts +75 -0
- package/frontend-vue/app/composables/useGraphConnect.ts +542 -0
- package/frontend-vue/app/plugins/runs-timeline-display.client.ts +16 -0
- package/frontend-vue/app/utils/automation.ts +51 -0
- package/frontend-vue/dms.frontend.ts +26 -0
- package/frontend-vue/eslint.config.mjs +24 -0
- package/frontend-vue/i18n/locales/dms-automation-en-GB.json +369 -0
- package/frontend-vue/i18n/locales/dms-automation-fr-FR.json +369 -0
- package/frontend-vue/package.json +33 -0
- package/frontend-vue/pnpm-lock.yaml +6483 -0
- package/frontend-vue/pnpm-workspace.yaml +2 -0
- package/package.json +81 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, watch } from 'vue'
|
|
3
|
+
|
|
4
|
+
interface ProcedureListItem {
|
|
5
|
+
_id: string
|
|
6
|
+
name: string
|
|
7
|
+
enabled: boolean
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const props = defineProps<{
|
|
11
|
+
procedures: ProcedureListItem[]
|
|
12
|
+
modelValue: string | null
|
|
13
|
+
}>()
|
|
14
|
+
|
|
15
|
+
const emit = defineEmits(['update:modelValue', 'create', 'delete'])
|
|
16
|
+
|
|
17
|
+
const confirmOpen = ref(false)
|
|
18
|
+
const pendingDeleteId = ref<string | null>(null)
|
|
19
|
+
const pendingDeleteName = ref<string>('')
|
|
20
|
+
|
|
21
|
+
function select(id: string) {
|
|
22
|
+
const next = props.modelValue === id ? null : id
|
|
23
|
+
emit('update:modelValue', next)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function askDelete(p: ProcedureListItem) {
|
|
27
|
+
pendingDeleteId.value = p._id
|
|
28
|
+
pendingDeleteName.value = p.name
|
|
29
|
+
confirmOpen.value = true
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function confirmDelete() {
|
|
33
|
+
const id = pendingDeleteId.value
|
|
34
|
+
if (id) {
|
|
35
|
+
emit('delete', id)
|
|
36
|
+
}
|
|
37
|
+
confirmOpen.value = false
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function cancelDelete() {
|
|
41
|
+
confirmOpen.value = false
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Reset pending state whenever the modal closes (via any means).
|
|
45
|
+
watch(confirmOpen, (open) => {
|
|
46
|
+
if (!open) {
|
|
47
|
+
pendingDeleteId.value = null
|
|
48
|
+
pendingDeleteName.value = ''
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
const isSelected = (id: string) => props.modelValue === id
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<template>
|
|
56
|
+
<div class="flex flex-col gap-2">
|
|
57
|
+
<div class="flex flex-wrap items-center justify-between gap-2">
|
|
58
|
+
<div class="text-sm font-semibold text-highlighted">
|
|
59
|
+
{{ $t('dms_automation.editor.procedureList.title') }}
|
|
60
|
+
</div>
|
|
61
|
+
<UButton
|
|
62
|
+
size="xs"
|
|
63
|
+
icon="i-ph-plus"
|
|
64
|
+
color="primary"
|
|
65
|
+
variant="soft"
|
|
66
|
+
class="shrink-0"
|
|
67
|
+
@click="emit('create')"
|
|
68
|
+
>
|
|
69
|
+
{{ $t('dms_automation.editor.procedureList.new') }}
|
|
70
|
+
</UButton>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<div
|
|
74
|
+
v-if="!procedures || procedures.length === 0"
|
|
75
|
+
class="px-2 py-6 text-center text-sm text-dimmed"
|
|
76
|
+
>
|
|
77
|
+
{{ $t('dms_automation.editor.procedureList.empty') }}
|
|
78
|
+
</div>
|
|
79
|
+
<ul v-else class="flex flex-col gap-1">
|
|
80
|
+
<li v-for="p in procedures" :key="p._id">
|
|
81
|
+
<div
|
|
82
|
+
class="flex w-full items-center gap-2 rounded-lg px-2 py-1.5 transition-colors"
|
|
83
|
+
:class="
|
|
84
|
+
isSelected(p._id)
|
|
85
|
+
? 'bg-primary/10 ring-1 ring-primary/20'
|
|
86
|
+
: 'hover:bg-elevated/60'
|
|
87
|
+
"
|
|
88
|
+
>
|
|
89
|
+
<button
|
|
90
|
+
type="button"
|
|
91
|
+
class="flex min-w-0 flex-1 items-center gap-2 text-left"
|
|
92
|
+
@click="select(p._id)"
|
|
93
|
+
>
|
|
94
|
+
<div class="min-w-0 flex-1">
|
|
95
|
+
<div
|
|
96
|
+
class="truncate text-sm font-medium"
|
|
97
|
+
:class="isSelected(p._id) ? 'text-primary' : 'text-highlighted'"
|
|
98
|
+
>
|
|
99
|
+
{{ p.name }}
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
<UBadge
|
|
103
|
+
:color="p.enabled ? 'success' : 'neutral'"
|
|
104
|
+
variant="subtle"
|
|
105
|
+
size="xs"
|
|
106
|
+
>
|
|
107
|
+
{{
|
|
108
|
+
p.enabled
|
|
109
|
+
? $t('dms_automation.editor.procedureList.enabled')
|
|
110
|
+
: $t('dms_automation.editor.procedureList.disabled')
|
|
111
|
+
}}
|
|
112
|
+
</UBadge>
|
|
113
|
+
</button>
|
|
114
|
+
<UButton
|
|
115
|
+
size="xs"
|
|
116
|
+
icon="i-ph-trash"
|
|
117
|
+
color="error"
|
|
118
|
+
variant="ghost"
|
|
119
|
+
:aria-label="$t('dms_automation.editor.procedureList.deleteAria')"
|
|
120
|
+
@click.stop="askDelete(p)"
|
|
121
|
+
/>
|
|
122
|
+
</div>
|
|
123
|
+
</li>
|
|
124
|
+
</ul>
|
|
125
|
+
|
|
126
|
+
<UModal
|
|
127
|
+
v-model:open="confirmOpen"
|
|
128
|
+
:title="$t('dms_automation.editor.procedureList.deleteTitle')"
|
|
129
|
+
>
|
|
130
|
+
<template #body>
|
|
131
|
+
<p class="text-muted">
|
|
132
|
+
{{
|
|
133
|
+
$t('dms_automation.editor.procedureList.deleteConfirm', {
|
|
134
|
+
name: pendingDeleteName,
|
|
135
|
+
})
|
|
136
|
+
}}
|
|
137
|
+
</p>
|
|
138
|
+
</template>
|
|
139
|
+
<template #footer>
|
|
140
|
+
<div class="flex w-full justify-end gap-2">
|
|
141
|
+
<UButton
|
|
142
|
+
:label="$t('dms_automation.editor.procedureList.cancel')"
|
|
143
|
+
variant="outline"
|
|
144
|
+
color="neutral"
|
|
145
|
+
@click="cancelDelete"
|
|
146
|
+
/>
|
|
147
|
+
<UButton
|
|
148
|
+
:label="$t('dms_automation.editor.procedureList.delete')"
|
|
149
|
+
color="error"
|
|
150
|
+
@click="confirmDelete"
|
|
151
|
+
/>
|
|
152
|
+
</div>
|
|
153
|
+
</template>
|
|
154
|
+
</UModal>
|
|
155
|
+
</div>
|
|
156
|
+
</template>
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref, watch } from 'vue'
|
|
3
|
+
import RunDetailDrawer from '../RunDetailDrawer.vue'
|
|
4
|
+
import { useAutomationRuns } from '../../composables/useAutomationRuns'
|
|
5
|
+
import { type ListEnvelope, unwrapList } from '../../utils/automation'
|
|
6
|
+
|
|
7
|
+
interface RunRecord {
|
|
8
|
+
_id: string
|
|
9
|
+
procedureId: string
|
|
10
|
+
startedAt: string | Date
|
|
11
|
+
endedAt?: string | Date | null
|
|
12
|
+
status: string
|
|
13
|
+
errorMessage?: string | null
|
|
14
|
+
triggerNodeId?: string
|
|
15
|
+
triggerPayload?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const props = defineProps<{
|
|
19
|
+
procedureId: string | null
|
|
20
|
+
procedureName?: string
|
|
21
|
+
}>()
|
|
22
|
+
|
|
23
|
+
const { $authFetch } = useAuthFetch()
|
|
24
|
+
// DMS-themed drawer from the dms layer (dms ≥0.0.26, public API replacing the
|
|
25
|
+
// removed useSheets/addSheet). Opens the run-detail view sliding in from the
|
|
26
|
+
// right; `open` marks the body component raw and generates a containerId.
|
|
27
|
+
const { open: openRunDrawer } = useDrawer()
|
|
28
|
+
const { getRun } = useAutomationRuns()
|
|
29
|
+
const { t } = useI18n()
|
|
30
|
+
|
|
31
|
+
const PAGE_SIZE = 10
|
|
32
|
+
|
|
33
|
+
const runs = ref<RunRecord[]>([])
|
|
34
|
+
const loading = ref(false)
|
|
35
|
+
const open = ref(false)
|
|
36
|
+
const error = ref<string | null>(null)
|
|
37
|
+
const loadingDetailId = ref<string | null>(null)
|
|
38
|
+
const detailError = ref<string | null>(null)
|
|
39
|
+
const page = ref(0)
|
|
40
|
+
const hasMore = ref(false)
|
|
41
|
+
|
|
42
|
+
async function load(target = 0) {
|
|
43
|
+
if (!props.procedureId) {
|
|
44
|
+
runs.value = []
|
|
45
|
+
hasMore.value = false
|
|
46
|
+
page.value = 0
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
const p = Math.max(0, target)
|
|
50
|
+
loading.value = true
|
|
51
|
+
error.value = null
|
|
52
|
+
try {
|
|
53
|
+
const data = await $authFetch<RunRecord[] | ListEnvelope<RunRecord>>(
|
|
54
|
+
`/api/automation/procedures/${props.procedureId}/runs?page=${p}&limit=${PAGE_SIZE}`,
|
|
55
|
+
)
|
|
56
|
+
// The API over-fetches one row beyond PAGE_SIZE as a next-page probe;
|
|
57
|
+
// trim it for display and use its presence for `hasMore`, so an
|
|
58
|
+
// exactly-full final page never enables a dead "Next".
|
|
59
|
+
const list = unwrapList<RunRecord>(data)
|
|
60
|
+
runs.value = list.slice(0, PAGE_SIZE)
|
|
61
|
+
page.value = p
|
|
62
|
+
hasMore.value = list.length > PAGE_SIZE
|
|
63
|
+
} catch (e) {
|
|
64
|
+
error.value = (e as Error).message ?? 'Failed to load runs'
|
|
65
|
+
runs.value = []
|
|
66
|
+
hasMore.value = false
|
|
67
|
+
} finally {
|
|
68
|
+
loading.value = false
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
watch(
|
|
73
|
+
() => props.procedureId,
|
|
74
|
+
() => {
|
|
75
|
+
void load(0)
|
|
76
|
+
},
|
|
77
|
+
{ immediate: true },
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
// Reset to the first page when the panel closes so the trigger badge always
|
|
81
|
+
// reflects the most recent runs, not whatever page was left open.
|
|
82
|
+
watch(open, (isOpen) => {
|
|
83
|
+
if (!isOpen && page.value !== 0) void load(0)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
// Let the editor refresh the list (and the trigger badge) after "Run now".
|
|
87
|
+
defineExpose({ reload: () => load(0) })
|
|
88
|
+
|
|
89
|
+
function fmtStarted(v: string | Date | null | undefined): string {
|
|
90
|
+
if (!v) return '—'
|
|
91
|
+
try {
|
|
92
|
+
return new Date(v).toLocaleString()
|
|
93
|
+
} catch {
|
|
94
|
+
return String(v)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function fmtDuration(
|
|
99
|
+
startedAt: string | Date | null | undefined,
|
|
100
|
+
endedAt: string | Date | null | undefined,
|
|
101
|
+
): string {
|
|
102
|
+
if (!endedAt || !startedAt) return '—'
|
|
103
|
+
try {
|
|
104
|
+
const s = new Date(startedAt).getTime()
|
|
105
|
+
const e = new Date(endedAt).getTime()
|
|
106
|
+
if (Number.isNaN(s) || Number.isNaN(e)) return '—'
|
|
107
|
+
return `${e - s} ms`
|
|
108
|
+
} catch {
|
|
109
|
+
return '—'
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function statusIcon(status: string): { name: string; color: string } {
|
|
114
|
+
if (status === 'ok')
|
|
115
|
+
return { name: 'i-ph-check-circle', color: 'text-success' }
|
|
116
|
+
if (status === 'failed')
|
|
117
|
+
return { name: 'i-ph-x-circle', color: 'text-error' }
|
|
118
|
+
return { name: 'i-ph-spinner', color: 'text-warning' }
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function truncate(s: string | null | undefined, n: number): string {
|
|
122
|
+
if (!s) return '—'
|
|
123
|
+
if (s.length <= n) return s
|
|
124
|
+
return `${s.slice(0, n)}…`
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const headerText = computed(() => {
|
|
128
|
+
if (!props.procedureId) return t('dms_automation.editor.runsDrawer.title')
|
|
129
|
+
if (loading.value) return t('dms_automation.editor.runsDrawer.loading')
|
|
130
|
+
return t('dms_automation.editor.runsDrawer.count', { n: runs.value.length })
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
async function onRefresh() {
|
|
134
|
+
await load()
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function openDetail(r: RunRecord) {
|
|
138
|
+
if (loadingDetailId.value === r._id) return
|
|
139
|
+
loadingDetailId.value = r._id
|
|
140
|
+
detailError.value = null
|
|
141
|
+
try {
|
|
142
|
+
// Bubble fetch errors up to the drawer (instead of pretending the
|
|
143
|
+
// summary is the detail — the fire tree would just render empty).
|
|
144
|
+
const full = await getRun(r._id)
|
|
145
|
+
openRunDrawer({
|
|
146
|
+
containerId: `dms-automation-run-${r._id}`,
|
|
147
|
+
title: `${r.status.toUpperCase()} · ${props.procedureName ?? r.procedureId}`,
|
|
148
|
+
description: new Date(r.startedAt).toLocaleString(),
|
|
149
|
+
direction: 'right',
|
|
150
|
+
component: RunDetailDrawer,
|
|
151
|
+
componentOptions: {
|
|
152
|
+
run: full,
|
|
153
|
+
procedureName: props.procedureName,
|
|
154
|
+
},
|
|
155
|
+
})
|
|
156
|
+
// Intentionally keep the runs list open BEHIND the detail. Closing it
|
|
157
|
+
// here (open.value = false) made the just-opened detail vanish ~a tick
|
|
158
|
+
// later — tearing down the runs USlideover cascades into the detail
|
|
159
|
+
// overlay. The detail is a separate dms `useDrawer` (a dismissible:false
|
|
160
|
+
// UDrawer) closed only via its own control, so leaving the list mounted
|
|
161
|
+
// lets you inspect runs back to back. Trade-off: while a detail is open
|
|
162
|
+
// the drawer stacks above the still-mounted list.
|
|
163
|
+
} catch (e) {
|
|
164
|
+
const msg = (e as Error).message ?? 'Failed to load run'
|
|
165
|
+
detailError.value = msg
|
|
166
|
+
console.error('[dms-automation] failed to open run detail', e)
|
|
167
|
+
} finally {
|
|
168
|
+
loadingDetailId.value = null
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
</script>
|
|
172
|
+
|
|
173
|
+
<template>
|
|
174
|
+
<UButton
|
|
175
|
+
icon="i-ph-clock-counter-clockwise"
|
|
176
|
+
variant="outline"
|
|
177
|
+
color="neutral"
|
|
178
|
+
:disabled="!procedureId"
|
|
179
|
+
@click="open = true"
|
|
180
|
+
>
|
|
181
|
+
{{ $t('dms_automation.editor.runsDrawer.title') }}
|
|
182
|
+
<UBadge
|
|
183
|
+
v-if="runs.length"
|
|
184
|
+
:label="hasMore ? `${runs.length}+` : String(runs.length)"
|
|
185
|
+
color="neutral"
|
|
186
|
+
variant="subtle"
|
|
187
|
+
size="sm"
|
|
188
|
+
/>
|
|
189
|
+
</UButton>
|
|
190
|
+
|
|
191
|
+
<USlideover v-model:open="open" side="right" :title="headerText">
|
|
192
|
+
<template #body>
|
|
193
|
+
<div class="flex flex-col gap-2">
|
|
194
|
+
<div class="flex items-center justify-between">
|
|
195
|
+
<div class="text-xs text-dimmed">
|
|
196
|
+
<span v-if="error" class="text-error">{{ error }}</span>
|
|
197
|
+
<span v-else-if="detailError" class="text-error">{{ detailError }}</span>
|
|
198
|
+
<span v-else-if="!procedureId">
|
|
199
|
+
{{ $t('dms_automation.editor.runsDrawer.selectProcedure') }}
|
|
200
|
+
</span>
|
|
201
|
+
<span v-else-if="loading">
|
|
202
|
+
{{ $t('dms_automation.editor.runsDrawer.loadingShort') }}
|
|
203
|
+
</span>
|
|
204
|
+
<span v-else>
|
|
205
|
+
{{ $t('dms_automation.editor.runsDrawer.runCount', { n: runs.length }) }}
|
|
206
|
+
</span>
|
|
207
|
+
</div>
|
|
208
|
+
<UButton
|
|
209
|
+
size="xs"
|
|
210
|
+
variant="ghost"
|
|
211
|
+
color="neutral"
|
|
212
|
+
icon="i-ph-arrows-clockwise"
|
|
213
|
+
:loading="loading"
|
|
214
|
+
:disabled="!procedureId"
|
|
215
|
+
@click="onRefresh"
|
|
216
|
+
>
|
|
217
|
+
{{ $t('dms_automation.editor.runsDrawer.refresh') }}
|
|
218
|
+
</UButton>
|
|
219
|
+
</div>
|
|
220
|
+
|
|
221
|
+
<div
|
|
222
|
+
v-if="runs.length > 0"
|
|
223
|
+
class="overflow-hidden rounded-lg border border-default"
|
|
224
|
+
>
|
|
225
|
+
<table class="w-full text-xs">
|
|
226
|
+
<thead>
|
|
227
|
+
<tr class="border-b border-default bg-muted">
|
|
228
|
+
<th class="w-12 px-3 py-2 text-left font-semibold text-dimmed">
|
|
229
|
+
{{ $t('dms_automation.editor.runsDrawer.cols.status') }}
|
|
230
|
+
</th>
|
|
231
|
+
<th class="px-3 py-2 text-left font-semibold text-dimmed">
|
|
232
|
+
{{ $t('dms_automation.editor.runsDrawer.cols.started') }}
|
|
233
|
+
</th>
|
|
234
|
+
<th class="px-3 py-2 text-left font-semibold text-dimmed">
|
|
235
|
+
{{ $t('dms_automation.editor.runsDrawer.cols.duration') }}
|
|
236
|
+
</th>
|
|
237
|
+
<th class="px-3 py-2 text-left font-semibold text-dimmed">
|
|
238
|
+
{{ $t('dms_automation.editor.runsDrawer.cols.error') }}
|
|
239
|
+
</th>
|
|
240
|
+
</tr>
|
|
241
|
+
</thead>
|
|
242
|
+
<tbody>
|
|
243
|
+
<tr
|
|
244
|
+
v-for="r in runs"
|
|
245
|
+
:key="r._id"
|
|
246
|
+
class="cursor-pointer border-b border-default/60 transition-colors last:border-0 hover:bg-elevated/40"
|
|
247
|
+
:class="{ 'opacity-60': loadingDetailId === r._id }"
|
|
248
|
+
@click="openDetail(r)"
|
|
249
|
+
>
|
|
250
|
+
<td class="px-3 py-2">
|
|
251
|
+
<UIcon
|
|
252
|
+
v-if="loadingDetailId === r._id"
|
|
253
|
+
name="i-ph-spinner"
|
|
254
|
+
class="animate-spin text-dimmed"
|
|
255
|
+
/>
|
|
256
|
+
<UIcon
|
|
257
|
+
v-else
|
|
258
|
+
:name="statusIcon(r.status).name"
|
|
259
|
+
:class="statusIcon(r.status).color"
|
|
260
|
+
/>
|
|
261
|
+
</td>
|
|
262
|
+
<td class="whitespace-nowrap px-3 py-2 tabular-nums text-toned">
|
|
263
|
+
{{ fmtStarted(r.startedAt) }}
|
|
264
|
+
</td>
|
|
265
|
+
<td class="whitespace-nowrap px-3 py-2 tabular-nums text-toned">
|
|
266
|
+
{{ fmtDuration(r.startedAt, r.endedAt) }}
|
|
267
|
+
</td>
|
|
268
|
+
<td class="px-3 py-2 text-error">
|
|
269
|
+
{{ truncate(r.errorMessage, 60) }}
|
|
270
|
+
</td>
|
|
271
|
+
</tr>
|
|
272
|
+
</tbody>
|
|
273
|
+
</table>
|
|
274
|
+
</div>
|
|
275
|
+
|
|
276
|
+
<div
|
|
277
|
+
v-else-if="!loading && procedureId && !error"
|
|
278
|
+
class="p-2 text-xs text-dimmed"
|
|
279
|
+
>
|
|
280
|
+
{{ $t('dms_automation.editor.runsDrawer.empty') }}
|
|
281
|
+
</div>
|
|
282
|
+
|
|
283
|
+
<div
|
|
284
|
+
v-if="runs.length > 0"
|
|
285
|
+
class="flex items-center justify-between gap-3 pt-1"
|
|
286
|
+
>
|
|
287
|
+
<UButton
|
|
288
|
+
size="xs"
|
|
289
|
+
color="neutral"
|
|
290
|
+
variant="ghost"
|
|
291
|
+
icon="i-ph-caret-left"
|
|
292
|
+
:label="$t('dms_automation.common.previous')"
|
|
293
|
+
:disabled="page === 0 || loading"
|
|
294
|
+
@click="load(page - 1)"
|
|
295
|
+
/>
|
|
296
|
+
<span class="text-xs tabular-nums text-dimmed">
|
|
297
|
+
{{ $t('dms_automation.runs.pageLabel', { n: page + 1 }) }}
|
|
298
|
+
</span>
|
|
299
|
+
<UButton
|
|
300
|
+
size="xs"
|
|
301
|
+
color="neutral"
|
|
302
|
+
variant="ghost"
|
|
303
|
+
trailing-icon="i-ph-caret-right"
|
|
304
|
+
:label="$t('dms_automation.common.next')"
|
|
305
|
+
:disabled="!hasMore || loading"
|
|
306
|
+
@click="load(page + 1)"
|
|
307
|
+
/>
|
|
308
|
+
</div>
|
|
309
|
+
</div>
|
|
310
|
+
</template>
|
|
311
|
+
</USlideover>
|
|
312
|
+
</template>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
interface Source {
|
|
3
|
+
node: string
|
|
4
|
+
port: string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
defineProps<{
|
|
8
|
+
field: string
|
|
9
|
+
source: Source
|
|
10
|
+
sourceLabel?: string
|
|
11
|
+
}>()
|
|
12
|
+
|
|
13
|
+
const emit = defineEmits<{
|
|
14
|
+
(e: 'unwire'): void
|
|
15
|
+
}>()
|
|
16
|
+
|
|
17
|
+
function onUnwire() {
|
|
18
|
+
emit('unwire')
|
|
19
|
+
}
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<div
|
|
24
|
+
class="flex items-center gap-2 rounded-lg border border-default bg-elevated px-2 py-1.5"
|
|
25
|
+
>
|
|
26
|
+
<UIcon name="i-ph-plugs-connected" class="size-4 text-success" />
|
|
27
|
+
<span class="min-w-0 flex-1 truncate text-xs text-toned">
|
|
28
|
+
{{ $t('dms_automation.editor.wiredField.wiredFrom') }}
|
|
29
|
+
<span class="font-mono font-medium text-highlighted">{{ sourceLabel ?? source.node }}.{{ source.port }}</span>
|
|
30
|
+
</span>
|
|
31
|
+
<UButton
|
|
32
|
+
size="xs"
|
|
33
|
+
variant="ghost"
|
|
34
|
+
color="error"
|
|
35
|
+
icon="i-ph-x"
|
|
36
|
+
:aria-label="$t('dms_automation.editor.wiredField.unwire')"
|
|
37
|
+
@click="onUnwire"
|
|
38
|
+
>
|
|
39
|
+
{{ $t('dms_automation.editor.wiredField.unwire') }}
|
|
40
|
+
</UButton>
|
|
41
|
+
</div>
|
|
42
|
+
</template>
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { Handle, Position } from '@vue-flow/core'
|
|
4
|
+
|
|
5
|
+
interface PortRef {
|
|
6
|
+
name: string
|
|
7
|
+
type?: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface NodeData {
|
|
11
|
+
label?: string
|
|
12
|
+
icon?: string
|
|
13
|
+
/** Small uppercase badge in the top-right of the header (data nodes). */
|
|
14
|
+
category?: string
|
|
15
|
+
/** Render the trigger-in handle on the header's left. Default true. */
|
|
16
|
+
hasTriggerIn?: boolean
|
|
17
|
+
/** Render the trigger-out `main` handle on the header's right. Default true. */
|
|
18
|
+
hasMainTriggerOut?: boolean
|
|
19
|
+
/**
|
|
20
|
+
* Non-main trigger-out ports. Rendered as body rows top-to-bottom,
|
|
21
|
+
* paired with `dataIns` left-to-right (per the asserted port
|
|
22
|
+
* convention: trigger ports first, no gap from data-ins on same row).
|
|
23
|
+
*/
|
|
24
|
+
triggerOuts?: string[]
|
|
25
|
+
/** Data inputs. Left-aligned. Paired with trigger-outs / data-outs. */
|
|
26
|
+
dataIns?: PortRef[]
|
|
27
|
+
/** Data outputs. Right-aligned. Render below all trigger-outs. */
|
|
28
|
+
dataOuts?: PortRef[]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const props = defineProps<{
|
|
32
|
+
id: string
|
|
33
|
+
data: NodeData
|
|
34
|
+
selected?: boolean
|
|
35
|
+
}>()
|
|
36
|
+
|
|
37
|
+
const hasTriggerIn = computed(() => props.data?.hasTriggerIn !== false)
|
|
38
|
+
const hasMainTriggerOut = computed(() => props.data?.hasMainTriggerOut !== false)
|
|
39
|
+
const triggerOuts = computed<string[]>(() => props.data?.triggerOuts ?? [])
|
|
40
|
+
const dataIns = computed<PortRef[]>(() => props.data?.dataIns ?? [])
|
|
41
|
+
const dataOuts = computed<PortRef[]>(() => props.data?.dataOuts ?? [])
|
|
42
|
+
|
|
43
|
+
import { dataStyle, triggerStyle } from './styles'
|
|
44
|
+
|
|
45
|
+
interface BodyRow {
|
|
46
|
+
leftDataIn?: PortRef
|
|
47
|
+
rightTriggerOut?: string
|
|
48
|
+
rightDataOut?: PortRef
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Body layout (per the convention):
|
|
52
|
+
// Phase 1: each trigger-out, top-to-bottom, paired with the next available
|
|
53
|
+
// data-in on the same row (left-aligned). No gap.
|
|
54
|
+
// Phase 2: data-outs (and any leftover data-ins) row-by-row, action-style
|
|
55
|
+
// (input[i] left, output[i] right), filling remaining space.
|
|
56
|
+
const rows = computed<BodyRow[]>(() => {
|
|
57
|
+
const r: BodyRow[] = []
|
|
58
|
+
const ti = [...triggerOuts.value]
|
|
59
|
+
const di = [...dataIns.value]
|
|
60
|
+
const dout = [...dataOuts.value]
|
|
61
|
+
|
|
62
|
+
// Phase 1
|
|
63
|
+
while (ti.length > 0) {
|
|
64
|
+
r.push({
|
|
65
|
+
leftDataIn: di.shift(),
|
|
66
|
+
rightTriggerOut: ti.shift(),
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Phase 2 — pair any leftover data-ins with data-outs.
|
|
71
|
+
const remaining = Math.max(di.length, dout.length)
|
|
72
|
+
for (let i = 0; i < remaining; i++) {
|
|
73
|
+
r.push({ leftDataIn: di[i], rightDataOut: dout[i] })
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return r
|
|
77
|
+
})
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
<template>
|
|
81
|
+
<div
|
|
82
|
+
class="dms-automation-node generic-node relative min-w-[180px] rounded-lg border bg-default shadow-sm"
|
|
83
|
+
:class="
|
|
84
|
+
selected
|
|
85
|
+
? 'border-primary ring-1 ring-primary'
|
|
86
|
+
: 'border-default'
|
|
87
|
+
"
|
|
88
|
+
>
|
|
89
|
+
<div
|
|
90
|
+
class="relative flex items-center gap-2 rounded-t-lg border-b border-default bg-elevated px-3 py-2"
|
|
91
|
+
>
|
|
92
|
+
<Handle
|
|
93
|
+
v-if="hasTriggerIn"
|
|
94
|
+
id="trigger-in"
|
|
95
|
+
type="target"
|
|
96
|
+
:position="Position.Left"
|
|
97
|
+
:style="triggerStyle"
|
|
98
|
+
/>
|
|
99
|
+
<UIcon
|
|
100
|
+
:name="data.icon || 'i-ph-circle'"
|
|
101
|
+
class="size-4 text-primary"
|
|
102
|
+
/>
|
|
103
|
+
<div class="truncate text-sm font-medium text-highlighted">
|
|
104
|
+
{{ data.label || 'Node' }}
|
|
105
|
+
</div>
|
|
106
|
+
<div
|
|
107
|
+
v-if="data.category"
|
|
108
|
+
class="ml-auto text-[10px] uppercase text-dimmed"
|
|
109
|
+
>
|
|
110
|
+
{{ data.category }}
|
|
111
|
+
</div>
|
|
112
|
+
<Handle
|
|
113
|
+
v-if="hasMainTriggerOut"
|
|
114
|
+
id="trigger-out-main"
|
|
115
|
+
type="source"
|
|
116
|
+
:position="Position.Right"
|
|
117
|
+
:style="triggerStyle"
|
|
118
|
+
/>
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<div v-if="rows.length > 0" class="py-2 text-xs text-dimmed">
|
|
122
|
+
<div
|
|
123
|
+
v-for="(row, i) in rows"
|
|
124
|
+
:key="i"
|
|
125
|
+
class="relative flex items-stretch py-1"
|
|
126
|
+
>
|
|
127
|
+
<div class="flex-1 flex items-center gap-1 pl-3">
|
|
128
|
+
<template v-if="row.leftDataIn">
|
|
129
|
+
<Handle
|
|
130
|
+
:id="`data-in-${row.leftDataIn.name}`"
|
|
131
|
+
type="target"
|
|
132
|
+
:position="Position.Left"
|
|
133
|
+
:style="dataStyle"
|
|
134
|
+
/>
|
|
135
|
+
<span>{{ row.leftDataIn.name }}</span>
|
|
136
|
+
</template>
|
|
137
|
+
</div>
|
|
138
|
+
<div class="flex-1 flex items-center justify-end gap-1 pr-3">
|
|
139
|
+
<template v-if="row.rightTriggerOut">
|
|
140
|
+
<span>{{ row.rightTriggerOut }}</span>
|
|
141
|
+
<Handle
|
|
142
|
+
:id="`trigger-out-${row.rightTriggerOut}`"
|
|
143
|
+
type="source"
|
|
144
|
+
:position="Position.Right"
|
|
145
|
+
:style="triggerStyle"
|
|
146
|
+
/>
|
|
147
|
+
</template>
|
|
148
|
+
<template v-else-if="row.rightDataOut">
|
|
149
|
+
<span>{{ row.rightDataOut.name }}</span>
|
|
150
|
+
<Handle
|
|
151
|
+
:id="`data-out-${row.rightDataOut.name}`"
|
|
152
|
+
type="source"
|
|
153
|
+
:position="Position.Right"
|
|
154
|
+
:style="dataStyle"
|
|
155
|
+
/>
|
|
156
|
+
</template>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
</template>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { GroupPort } from '../../../composables/useGraphConnect'
|
|
3
|
+
import GroupSentinel from './GroupSentinel.vue'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
id: string
|
|
7
|
+
data: { ports?: GroupPort[] }
|
|
8
|
+
selected?: boolean
|
|
9
|
+
}>()
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<GroupSentinel
|
|
14
|
+
:id="props.id"
|
|
15
|
+
side="in"
|
|
16
|
+
:data="props.data"
|
|
17
|
+
:selected="props.selected"
|
|
18
|
+
/>
|
|
19
|
+
</template>
|