@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,200 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { Handle, Position } from '@vue-flow/core'
|
|
4
|
+
import type { GroupPort } from '../../../composables/useGraphConnect'
|
|
5
|
+
|
|
6
|
+
interface NodeData {
|
|
7
|
+
label?: string
|
|
8
|
+
icon?: string
|
|
9
|
+
typeId?: string
|
|
10
|
+
templateId?: string
|
|
11
|
+
templateName?: string
|
|
12
|
+
ports?: GroupPort[]
|
|
13
|
+
config?: { name?: string; [k: string]: unknown }
|
|
14
|
+
subgraph?: unknown
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const props = defineProps<{
|
|
18
|
+
id: string
|
|
19
|
+
data: NodeData
|
|
20
|
+
selected?: boolean
|
|
21
|
+
}>()
|
|
22
|
+
|
|
23
|
+
const ports = computed<GroupPort[]>(() =>
|
|
24
|
+
Array.isArray(props.data?.ports) ? props.data.ports : [],
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
const triggerInPorts = computed(() =>
|
|
28
|
+
ports.value.filter((p) => p.kind === 'trigger' && p.direction === 'in'),
|
|
29
|
+
)
|
|
30
|
+
const triggerOutPorts = computed(() =>
|
|
31
|
+
ports.value.filter((p) => p.kind === 'trigger' && p.direction === 'out'),
|
|
32
|
+
)
|
|
33
|
+
const dataInPorts = computed(() =>
|
|
34
|
+
ports.value.filter((p) => p.kind === 'data' && p.direction === 'in'),
|
|
35
|
+
)
|
|
36
|
+
const dataOutPorts = computed(() =>
|
|
37
|
+
ports.value.filter((p) => p.kind === 'data' && p.direction === 'out'),
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
const isTemplateInstance = computed(() => Boolean(props.data?.templateId))
|
|
41
|
+
|
|
42
|
+
const title = computed(
|
|
43
|
+
() => props.data?.config?.name ?? props.data?.label ?? 'Group',
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
const headerIcon = computed(() =>
|
|
47
|
+
isTemplateInstance.value ? 'i-ph-link' : 'i-ph-package',
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
import { dataHandleStyle, triggerStyle } from './styles'
|
|
51
|
+
|
|
52
|
+
// Mirror the convention used by GenericNode: the trigger port named "main"
|
|
53
|
+
// lives on the title bar (left for trigger-in, right for trigger-out). Any
|
|
54
|
+
// other trigger ports spill into the body rows below, interleaved with the
|
|
55
|
+
// data port rows. If no port is named "main", the title bar has no trigger
|
|
56
|
+
// handle on that side — the user picks which port is the "main" one by
|
|
57
|
+
// naming it.
|
|
58
|
+
const mainTriggerIn = computed(
|
|
59
|
+
() => triggerInPorts.value.find((p) => p.name === 'main') ?? null,
|
|
60
|
+
)
|
|
61
|
+
const mainTriggerOut = computed(
|
|
62
|
+
() => triggerOutPorts.value.find((p) => p.name === 'main') ?? null,
|
|
63
|
+
)
|
|
64
|
+
const extraTriggerIn = computed(() =>
|
|
65
|
+
triggerInPorts.value.filter((p) => p.name !== 'main'),
|
|
66
|
+
)
|
|
67
|
+
const extraTriggerOut = computed(() =>
|
|
68
|
+
triggerOutPorts.value.filter((p) => p.name !== 'main'),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
// Body rows: left column shows trigger-in extras followed by data-in ports;
|
|
72
|
+
// right column shows trigger-out extras followed by data-out ports. Each row
|
|
73
|
+
// gets one entry per side (may be null if that side has fewer entries).
|
|
74
|
+
interface LeftRow {
|
|
75
|
+
kind: 'trigger' | 'data'
|
|
76
|
+
port: GroupPort
|
|
77
|
+
}
|
|
78
|
+
interface RightRow {
|
|
79
|
+
kind: 'trigger' | 'data'
|
|
80
|
+
port: GroupPort
|
|
81
|
+
}
|
|
82
|
+
const leftRows = computed<LeftRow[]>(() => [
|
|
83
|
+
...extraTriggerIn.value.map((p) => ({ kind: 'trigger' as const, port: p })),
|
|
84
|
+
...dataInPorts.value.map((p) => ({ kind: 'data' as const, port: p })),
|
|
85
|
+
])
|
|
86
|
+
const rightRows = computed<RightRow[]>(() => [
|
|
87
|
+
...extraTriggerOut.value.map((p) => ({ kind: 'trigger' as const, port: p })),
|
|
88
|
+
...dataOutPorts.value.map((p) => ({ kind: 'data' as const, port: p })),
|
|
89
|
+
])
|
|
90
|
+
const bodyRowCount = computed(() =>
|
|
91
|
+
Math.max(leftRows.value.length, rightRows.value.length),
|
|
92
|
+
)
|
|
93
|
+
const hasAnyPorts = computed(
|
|
94
|
+
() =>
|
|
95
|
+
mainTriggerIn.value !== null ||
|
|
96
|
+
mainTriggerOut.value !== null ||
|
|
97
|
+
bodyRowCount.value > 0,
|
|
98
|
+
)
|
|
99
|
+
</script>
|
|
100
|
+
|
|
101
|
+
<template>
|
|
102
|
+
<div
|
|
103
|
+
class="dms-automation-node group-node relative min-w-[220px] rounded-lg border bg-default shadow-sm"
|
|
104
|
+
:class="
|
|
105
|
+
selected
|
|
106
|
+
? 'border-primary ring-1 ring-primary'
|
|
107
|
+
: 'border-default'
|
|
108
|
+
"
|
|
109
|
+
>
|
|
110
|
+
<!-- Header — main trigger-in (left) / main trigger-out (right), mirroring
|
|
111
|
+
the GenericNode convention. -->
|
|
112
|
+
<div
|
|
113
|
+
class="relative flex items-center gap-2 rounded-t-lg border-b border-default bg-elevated px-3 py-2"
|
|
114
|
+
>
|
|
115
|
+
<Handle
|
|
116
|
+
v-if="mainTriggerIn"
|
|
117
|
+
:id="`group-trigger-in-${mainTriggerIn.name}`"
|
|
118
|
+
type="target"
|
|
119
|
+
:position="Position.Left"
|
|
120
|
+
:style="triggerStyle"
|
|
121
|
+
/>
|
|
122
|
+
<div class="relative">
|
|
123
|
+
<UIcon :name="headerIcon" class="size-4 text-primary" />
|
|
124
|
+
</div>
|
|
125
|
+
<div class="truncate text-sm font-medium text-highlighted">
|
|
126
|
+
{{ title }}
|
|
127
|
+
</div>
|
|
128
|
+
<span
|
|
129
|
+
v-if="isTemplateInstance"
|
|
130
|
+
class="ml-auto inline-flex items-center gap-1 rounded-sm bg-primary/10 px-1.5 py-0.5 text-[10px] uppercase tracking-wide text-primary"
|
|
131
|
+
:title="`Linked to template ${data.templateId}`"
|
|
132
|
+
>
|
|
133
|
+
<UIcon name="i-ph-link" class="w-3 h-3" />
|
|
134
|
+
linked
|
|
135
|
+
</span>
|
|
136
|
+
<Handle
|
|
137
|
+
v-if="mainTriggerOut"
|
|
138
|
+
:id="`group-trigger-out-${mainTriggerOut.name}`"
|
|
139
|
+
type="source"
|
|
140
|
+
:position="Position.Right"
|
|
141
|
+
:style="triggerStyle"
|
|
142
|
+
/>
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
<!-- Body rows: trigger-in extras + data-in on the left, trigger-out
|
|
146
|
+
extras + data-out on the right. -->
|
|
147
|
+
<div v-if="bodyRowCount > 0" class="py-2 text-xs text-dimmed">
|
|
148
|
+
<div
|
|
149
|
+
v-for="i in bodyRowCount"
|
|
150
|
+
:key="`row-${i - 1}`"
|
|
151
|
+
class="relative flex items-stretch py-1"
|
|
152
|
+
>
|
|
153
|
+
<div class="flex-1 flex items-center gap-1 pl-3">
|
|
154
|
+
<template v-if="leftRows[i - 1]">
|
|
155
|
+
<Handle
|
|
156
|
+
v-if="leftRows[i - 1]!.kind === 'trigger'"
|
|
157
|
+
:id="`group-trigger-in-${leftRows[i - 1]!.port.name}`"
|
|
158
|
+
type="target"
|
|
159
|
+
:position="Position.Left"
|
|
160
|
+
:style="triggerStyle"
|
|
161
|
+
/>
|
|
162
|
+
<Handle
|
|
163
|
+
v-else
|
|
164
|
+
:id="`group-data-in-${leftRows[i - 1]!.port.name}`"
|
|
165
|
+
type="target"
|
|
166
|
+
:position="Position.Left"
|
|
167
|
+
:style="dataHandleStyle(leftRows[i - 1]!.port)"
|
|
168
|
+
/>
|
|
169
|
+
<span>{{ leftRows[i - 1]!.port.name }}</span>
|
|
170
|
+
</template>
|
|
171
|
+
</div>
|
|
172
|
+
<div class="flex-1 flex items-center justify-end gap-1 pr-3">
|
|
173
|
+
<template v-if="rightRows[i - 1]">
|
|
174
|
+
<span>{{ rightRows[i - 1]!.port.name }}</span>
|
|
175
|
+
<Handle
|
|
176
|
+
v-if="rightRows[i - 1]!.kind === 'trigger'"
|
|
177
|
+
:id="`group-trigger-out-${rightRows[i - 1]!.port.name}`"
|
|
178
|
+
type="source"
|
|
179
|
+
:position="Position.Right"
|
|
180
|
+
:style="triggerStyle"
|
|
181
|
+
/>
|
|
182
|
+
<Handle
|
|
183
|
+
v-else
|
|
184
|
+
:id="`group-data-out-${rightRows[i - 1]!.port.name}`"
|
|
185
|
+
type="source"
|
|
186
|
+
:position="Position.Right"
|
|
187
|
+
:style="dataHandleStyle(rightRows[i - 1]!.port)"
|
|
188
|
+
/>
|
|
189
|
+
</template>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
<div
|
|
194
|
+
v-else-if="!hasAnyPorts"
|
|
195
|
+
class="py-2 px-3 text-xs text-dimmed italic"
|
|
196
|
+
>
|
|
197
|
+
no ports
|
|
198
|
+
</div>
|
|
199
|
+
</div>
|
|
200
|
+
</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="out"
|
|
16
|
+
:data="props.data"
|
|
17
|
+
:selected="props.selected"
|
|
18
|
+
/>
|
|
19
|
+
</template>
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { Handle, Position } from '@vue-flow/core'
|
|
4
|
+
import type { GroupPort } from '../../../composables/useGraphConnect'
|
|
5
|
+
import { dataHandleStyle, triggerStyle } from './styles'
|
|
6
|
+
|
|
7
|
+
// Shared body for both group sentinels (groupInput / groupOutput). The two
|
|
8
|
+
// are mirror images: `groupInput` exposes the parent group's IN ports as
|
|
9
|
+
// SOURCE handles on the right edge; `groupOutput` exposes its OUT ports as
|
|
10
|
+
// TARGET handles on the left edge. Naming, icon, label, alignment, and
|
|
11
|
+
// empty-state copy all flip on `side`.
|
|
12
|
+
//
|
|
13
|
+
// Sentinel naming:
|
|
14
|
+
// groupInput-trigger-out-<port> / groupInput-data-out-<port>
|
|
15
|
+
// groupOutput-trigger-in-<port> / groupOutput-data-in-<port>
|
|
16
|
+
//
|
|
17
|
+
// Sentinels are not user-deletable — enforcement lives in GraphCanvas.vue's
|
|
18
|
+
// onNodesChange handler.
|
|
19
|
+
|
|
20
|
+
interface NodeData {
|
|
21
|
+
ports?: GroupPort[]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const props = defineProps<{
|
|
25
|
+
id: string
|
|
26
|
+
data: NodeData
|
|
27
|
+
selected?: boolean
|
|
28
|
+
side: 'in' | 'out'
|
|
29
|
+
}>()
|
|
30
|
+
|
|
31
|
+
const isInput = computed(() => props.side === 'in')
|
|
32
|
+
const handleDirection = computed(() => (isInput.value ? 'source' : 'target'))
|
|
33
|
+
const handlePosition = computed(() =>
|
|
34
|
+
isInput.value ? Position.Right : Position.Left,
|
|
35
|
+
)
|
|
36
|
+
const handlePrefix = computed(() => (isInput.value ? 'groupInput' : 'groupOutput'))
|
|
37
|
+
const handleVerb = computed(() => (isInput.value ? 'out' : 'in'))
|
|
38
|
+
const headerIcon = computed(() => (isInput.value ? 'i-ph-sign-in' : 'i-ph-sign-out'))
|
|
39
|
+
const headerLabel = computed(() =>
|
|
40
|
+
isInput.value ? 'Group Input' : 'Group Output',
|
|
41
|
+
)
|
|
42
|
+
const emptyText = computed(() =>
|
|
43
|
+
isInput.value ? 'no input ports' : 'no output ports',
|
|
44
|
+
)
|
|
45
|
+
const rowKeyPrefix = computed(() => (isInput.value ? 'gi-row' : 'go-row'))
|
|
46
|
+
|
|
47
|
+
const ports = computed<GroupPort[]>(() =>
|
|
48
|
+
Array.isArray(props.data?.ports) ? props.data.ports : [],
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
// `groupInput` surfaces the parent's IN ports (they look like sources to
|
|
52
|
+
// the inner subgraph); `groupOutput` surfaces the parent's OUT ports
|
|
53
|
+
// (sinks to the inner subgraph).
|
|
54
|
+
const dataPorts = computed(() =>
|
|
55
|
+
ports.value.filter((p) => p.kind === 'data' && p.direction === props.side),
|
|
56
|
+
)
|
|
57
|
+
const triggerPorts = computed(() =>
|
|
58
|
+
ports.value.filter((p) => p.kind === 'trigger' && p.direction === props.side),
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
const mainTrigger = computed(
|
|
62
|
+
() => triggerPorts.value.find((p) => p.name === 'main') ?? null,
|
|
63
|
+
)
|
|
64
|
+
const extraTrigger = computed(() =>
|
|
65
|
+
triggerPorts.value.filter((p) => p.name !== 'main'),
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
interface BodyRow {
|
|
69
|
+
kind: 'trigger' | 'data'
|
|
70
|
+
port: GroupPort
|
|
71
|
+
}
|
|
72
|
+
const bodyRows = computed<BodyRow[]>(() => [
|
|
73
|
+
...extraTrigger.value.map((p) => ({ kind: 'trigger' as const, port: p })),
|
|
74
|
+
...dataPorts.value.map((p) => ({ kind: 'data' as const, port: p })),
|
|
75
|
+
])
|
|
76
|
+
|
|
77
|
+
function handleId(row: BodyRow): string {
|
|
78
|
+
const subject = row.kind === 'trigger' ? 'trigger' : 'data'
|
|
79
|
+
return `${handlePrefix.value}-${subject}-${handleVerb.value}-${row.port.name}`
|
|
80
|
+
}
|
|
81
|
+
</script>
|
|
82
|
+
|
|
83
|
+
<template>
|
|
84
|
+
<div
|
|
85
|
+
class="dms-automation-node group-sentinel relative min-w-[180px] rounded-lg border border-dashed bg-elevated/40 opacity-90"
|
|
86
|
+
:class="[
|
|
87
|
+
isInput ? 'group-input-sentinel' : 'group-output-sentinel',
|
|
88
|
+
selected
|
|
89
|
+
? 'border-primary ring-1 ring-primary'
|
|
90
|
+
: 'border-default',
|
|
91
|
+
]"
|
|
92
|
+
>
|
|
93
|
+
<!-- Header: main trigger handle on the appropriate edge mirrors
|
|
94
|
+
GroupNode title-bar layout. -->
|
|
95
|
+
<div
|
|
96
|
+
class="relative flex items-center gap-2 px-3 py-1.5 border-b border-dashed border-default rounded-t-md"
|
|
97
|
+
>
|
|
98
|
+
<Handle
|
|
99
|
+
v-if="!isInput && mainTrigger"
|
|
100
|
+
:id="`${handlePrefix}-trigger-${handleVerb}-${mainTrigger.name}`"
|
|
101
|
+
:type="handleDirection"
|
|
102
|
+
:position="handlePosition"
|
|
103
|
+
:style="triggerStyle"
|
|
104
|
+
/>
|
|
105
|
+
<UIcon :name="headerIcon" class="text-dimmed" />
|
|
106
|
+
<div class="text-dimmed text-xs font-medium uppercase tracking-wide">
|
|
107
|
+
{{ headerLabel }}
|
|
108
|
+
</div>
|
|
109
|
+
<Handle
|
|
110
|
+
v-if="isInput && mainTrigger"
|
|
111
|
+
:id="`${handlePrefix}-trigger-${handleVerb}-${mainTrigger.name}`"
|
|
112
|
+
:type="handleDirection"
|
|
113
|
+
:position="handlePosition"
|
|
114
|
+
:style="triggerStyle"
|
|
115
|
+
/>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<!-- Body: trigger extras + data ports, one per row. Layout mirrors
|
|
119
|
+
GroupNode.vue: row is `relative` so each Handle (absolute)
|
|
120
|
+
anchors to its row's vertical center; an inner flex-1 column
|
|
121
|
+
reserves a track for the label so the absolute handle doesn't
|
|
122
|
+
crowd it on narrow nodes. -->
|
|
123
|
+
<div v-if="bodyRows.length > 0" class="py-2 text-xs text-dimmed">
|
|
124
|
+
<div
|
|
125
|
+
v-for="(row, idx) in bodyRows"
|
|
126
|
+
:key="`${rowKeyPrefix}-${row.kind}-${idx}`"
|
|
127
|
+
class="relative flex items-stretch py-1"
|
|
128
|
+
>
|
|
129
|
+
<div
|
|
130
|
+
class="flex-1 flex items-center gap-1"
|
|
131
|
+
:class="isInput ? 'justify-end pr-3' : 'pl-3'"
|
|
132
|
+
>
|
|
133
|
+
<template v-if="isInput">
|
|
134
|
+
<span>{{ row.port.name }}</span>
|
|
135
|
+
<Handle
|
|
136
|
+
:id="handleId(row)"
|
|
137
|
+
:type="handleDirection"
|
|
138
|
+
:position="handlePosition"
|
|
139
|
+
:style="row.kind === 'trigger' ? triggerStyle : dataHandleStyle(row.port)"
|
|
140
|
+
/>
|
|
141
|
+
</template>
|
|
142
|
+
<template v-else>
|
|
143
|
+
<Handle
|
|
144
|
+
:id="handleId(row)"
|
|
145
|
+
:type="handleDirection"
|
|
146
|
+
:position="handlePosition"
|
|
147
|
+
:style="row.kind === 'trigger' ? triggerStyle : dataHandleStyle(row.port)"
|
|
148
|
+
/>
|
|
149
|
+
<span>{{ row.port.name }}</span>
|
|
150
|
+
</template>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
<div
|
|
155
|
+
v-else-if="!mainTrigger"
|
|
156
|
+
class="py-2 px-3 text-xs text-dimmed italic"
|
|
157
|
+
>
|
|
158
|
+
{{ emptyText }}
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
</template>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared handle styling for the editor's node Vue components. Trigger and
|
|
3
|
+
* data handles use a fixed color and size; data handles can additionally
|
|
4
|
+
* pick a per-JSON-schema-type color via `dataHandleStyle(port)` (keyed off
|
|
5
|
+
* `port.schema`) for the group/sentinel node variants.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
GroupPort,
|
|
10
|
+
JsonSchema,
|
|
11
|
+
} from "../../../composables/useGraphConnect";
|
|
12
|
+
|
|
13
|
+
// Trigger (control-flow) handles use the DMS accent cyan so the procedure's
|
|
14
|
+
// main flow reads as the brand colour; data handles stay emerald (success).
|
|
15
|
+
export const triggerStyle = {
|
|
16
|
+
background: "#2dc1cf",
|
|
17
|
+
width: "10px",
|
|
18
|
+
height: "10px",
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const dataStyle = {
|
|
22
|
+
background: "#10b981",
|
|
23
|
+
width: "8px",
|
|
24
|
+
height: "8px",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Per-JSON-schema-type color for data handles. Falls back to the
|
|
28
|
+
// emerald baseline (the data-port default) for unknown / missing types.
|
|
29
|
+
const TYPE_COLORS: Record<string, string> = {
|
|
30
|
+
string: "#10b981", // emerald — matches DataNode default
|
|
31
|
+
number: "#f59e0b", // amber
|
|
32
|
+
integer: "#f59e0b", // amber
|
|
33
|
+
boolean: "#ef4444", // red
|
|
34
|
+
object: "#8b5cf6", // violet
|
|
35
|
+
array: "#06b6d4", // cyan
|
|
36
|
+
null: "#6b7280", // gray
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
function schemaType(schema: JsonSchema | undefined): string {
|
|
40
|
+
if (!schema) return "";
|
|
41
|
+
const t = schema.type;
|
|
42
|
+
if (Array.isArray(t)) return typeof t[0] === "string" ? (t[0] as string) : "";
|
|
43
|
+
return typeof t === "string" ? t : "";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function dataHandleStyle(port: Pick<GroupPort, "schema">): {
|
|
47
|
+
background: string;
|
|
48
|
+
width: string;
|
|
49
|
+
height: string;
|
|
50
|
+
} {
|
|
51
|
+
const color = TYPE_COLORS[schemaType(port.schema)] ?? "#10b981";
|
|
52
|
+
return { background: color, width: "8px", height: "8px" };
|
|
53
|
+
}
|