@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,166 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref, watch } from 'vue'
|
|
3
|
+
import type { JsonSchema } from '../../composables/useGraphConnect'
|
|
4
|
+
|
|
5
|
+
interface CatalogType {
|
|
6
|
+
id: string
|
|
7
|
+
name: string
|
|
8
|
+
description?: string
|
|
9
|
+
icon?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// `schema` is the JSON schema of the selected type's configuration, read from
|
|
13
|
+
// whichever field the catalog exposes it under (trigger types: `configSchema`,
|
|
14
|
+
// action types: `inputSchema`). Rendered read-only next to the config editor.
|
|
15
|
+
const props = defineProps<{
|
|
16
|
+
type: CatalogType | null
|
|
17
|
+
schema?: JsonSchema
|
|
18
|
+
savedConfig: string | null
|
|
19
|
+
savedEnabled: boolean
|
|
20
|
+
}>()
|
|
21
|
+
|
|
22
|
+
const emit = defineEmits<{
|
|
23
|
+
(e: 'save', payload: { enabled: boolean; config: string }): void
|
|
24
|
+
}>()
|
|
25
|
+
|
|
26
|
+
const enabled = ref<boolean>(props.savedEnabled)
|
|
27
|
+
const configText = ref<string>(props.savedConfig ?? '{}')
|
|
28
|
+
const parseError = ref<string | null>(null)
|
|
29
|
+
|
|
30
|
+
watch(
|
|
31
|
+
() => props.type?.id,
|
|
32
|
+
() => {
|
|
33
|
+
enabled.value = props.savedEnabled
|
|
34
|
+
configText.value = props.savedConfig ?? '{}'
|
|
35
|
+
parseError.value = null
|
|
36
|
+
},
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
watch(
|
|
40
|
+
() => props.savedConfig,
|
|
41
|
+
(v) => {
|
|
42
|
+
if (v !== null && v !== undefined) {
|
|
43
|
+
configText.value = v
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
watch(
|
|
49
|
+
() => props.savedEnabled,
|
|
50
|
+
(v) => {
|
|
51
|
+
enabled.value = v
|
|
52
|
+
},
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
function validate() {
|
|
56
|
+
try {
|
|
57
|
+
JSON.parse(configText.value || '{}')
|
|
58
|
+
parseError.value = null
|
|
59
|
+
return true
|
|
60
|
+
} catch (e) {
|
|
61
|
+
parseError.value = (e as Error).message
|
|
62
|
+
return false
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const schemaPretty = computed(() =>
|
|
67
|
+
props.schema ? JSON.stringify(props.schema, null, 2) : '',
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
function onSave() {
|
|
71
|
+
if (!validate()) return
|
|
72
|
+
emit('save', {
|
|
73
|
+
enabled: enabled.value,
|
|
74
|
+
config: configText.value || '{}',
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
</script>
|
|
78
|
+
|
|
79
|
+
<template>
|
|
80
|
+
<DmsCard
|
|
81
|
+
v-if="!type"
|
|
82
|
+
class="flex min-h-[16rem] items-center justify-center text-center"
|
|
83
|
+
>
|
|
84
|
+
<div class="flex flex-col items-center gap-3 text-dimmed">
|
|
85
|
+
<UIcon name="i-ph-faders" class="size-8" />
|
|
86
|
+
<p class="max-w-xs text-sm">
|
|
87
|
+
{{ $t('dms_automation.catalog.selectPrompt') }}
|
|
88
|
+
</p>
|
|
89
|
+
</div>
|
|
90
|
+
</DmsCard>
|
|
91
|
+
|
|
92
|
+
<DmsCard v-else :padded="false" class="flex flex-col">
|
|
93
|
+
<div class="flex items-start gap-3 border-b border-default px-5 py-4 sm:px-6">
|
|
94
|
+
<div
|
|
95
|
+
class="grid size-10 shrink-0 place-items-center rounded-lg bg-primary/10 text-primary ring ring-primary/20"
|
|
96
|
+
>
|
|
97
|
+
<UIcon :name="type.icon || 'i-ph-puzzle-piece'" class="size-5" />
|
|
98
|
+
</div>
|
|
99
|
+
<div class="min-w-0 flex-1">
|
|
100
|
+
<h2 class="truncate text-lg font-semibold text-highlighted">
|
|
101
|
+
{{ type.name }}
|
|
102
|
+
</h2>
|
|
103
|
+
<p v-if="type.description" class="text-sm text-muted">
|
|
104
|
+
{{ type.description }}
|
|
105
|
+
</p>
|
|
106
|
+
<p class="mt-1 font-mono text-xs text-dimmed">{{ type.id }}</p>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<div class="flex flex-col gap-5 px-5 py-4 sm:px-6">
|
|
111
|
+
<div class="flex items-center justify-between gap-4">
|
|
112
|
+
<div>
|
|
113
|
+
<div class="text-sm font-medium text-highlighted">
|
|
114
|
+
{{ $t('dms_automation.catalog.enabled') }}
|
|
115
|
+
</div>
|
|
116
|
+
<div class="text-xs text-muted">
|
|
117
|
+
{{ $t('dms_automation.catalog.enabledHelp') }}
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
<USwitch v-model="enabled" />
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<div v-if="schemaPretty" class="flex flex-col gap-1.5">
|
|
124
|
+
<div class="text-sm font-medium text-highlighted">
|
|
125
|
+
{{ $t('dms_automation.catalog.configSchema') }}
|
|
126
|
+
</div>
|
|
127
|
+
<pre
|
|
128
|
+
class="max-h-48 overflow-auto rounded-lg border border-default bg-muted p-3 font-mono text-xs text-toned"
|
|
129
|
+
>{{ schemaPretty }}</pre>
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
<div class="flex flex-col gap-1.5">
|
|
133
|
+
<div class="text-sm font-medium text-highlighted">
|
|
134
|
+
{{ $t('dms_automation.catalog.globalConfig') }}
|
|
135
|
+
</div>
|
|
136
|
+
<UTextarea
|
|
137
|
+
v-model="configText"
|
|
138
|
+
:rows="10"
|
|
139
|
+
class="w-full font-mono"
|
|
140
|
+
autoresize
|
|
141
|
+
@blur="validate"
|
|
142
|
+
/>
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
<UAlert
|
|
146
|
+
v-if="parseError"
|
|
147
|
+
color="error"
|
|
148
|
+
variant="subtle"
|
|
149
|
+
icon="i-ph-warning"
|
|
150
|
+
:title="$t('dms_automation.catalog.invalidJson')"
|
|
151
|
+
:description="parseError"
|
|
152
|
+
/>
|
|
153
|
+
|
|
154
|
+
<div class="flex justify-end">
|
|
155
|
+
<UButton
|
|
156
|
+
color="primary"
|
|
157
|
+
icon="i-ph-floppy-disk"
|
|
158
|
+
:disabled="!!parseError"
|
|
159
|
+
@click="onSave"
|
|
160
|
+
>
|
|
161
|
+
{{ $t('dms_automation.catalog.save') }}
|
|
162
|
+
</UButton>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
</DmsCard>
|
|
166
|
+
</template>
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// The `generic` attribute is compiled into the component's module scope, where
|
|
3
|
+
// a type declared inside `<script setup>` does not exist yet. Catalog entries
|
|
4
|
+
// therefore describe themselves here.
|
|
5
|
+
export interface CatalogType {
|
|
6
|
+
id: string
|
|
7
|
+
name: string
|
|
8
|
+
description?: string
|
|
9
|
+
icon?: string
|
|
10
|
+
}
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<script setup lang="ts" generic="T extends CatalogType">
|
|
14
|
+
import { computed, ref } from 'vue'
|
|
15
|
+
|
|
16
|
+
const props = withDefaults(
|
|
17
|
+
defineProps<{
|
|
18
|
+
types: T[]
|
|
19
|
+
modelValue: string | null
|
|
20
|
+
groupBy?: (t: T) => string
|
|
21
|
+
title?: string
|
|
22
|
+
/** Show the inline search box (on by default). */
|
|
23
|
+
searchable?: boolean
|
|
24
|
+
/** Placeholder for the search box; falls back to a generic label. */
|
|
25
|
+
searchPlaceholder?: string
|
|
26
|
+
}>(),
|
|
27
|
+
// A bare `boolean` prop defaults to `false` when omitted, which would
|
|
28
|
+
// silently hide search on every catalog; pin the intended on-by-default.
|
|
29
|
+
{ searchable: true },
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
const emit = defineEmits<{
|
|
33
|
+
(e: 'update:modelValue', value: string): void
|
|
34
|
+
}>()
|
|
35
|
+
|
|
36
|
+
function select(id: string) {
|
|
37
|
+
emit('update:modelValue', id)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const isSelected = (id: string) => props.modelValue === id
|
|
41
|
+
|
|
42
|
+
// Search defaults to on; pass `:searchable="false"` to opt out.
|
|
43
|
+
const searchEnabled = computed(() => props.searchable !== false)
|
|
44
|
+
const query = ref('')
|
|
45
|
+
|
|
46
|
+
// Case-insensitive substring filter over name / description / id. Catalogs hold
|
|
47
|
+
// at most a few hundred registered types, so a per-keystroke scan is cheap and
|
|
48
|
+
// avoids pulling in a fuzzy-match dependency.
|
|
49
|
+
const visibleTypes = computed<T[]>(() => {
|
|
50
|
+
const q = query.value.trim().toLowerCase()
|
|
51
|
+
if (!searchEnabled.value || !q) return props.types
|
|
52
|
+
return props.types.filter(
|
|
53
|
+
(t) =>
|
|
54
|
+
t.name?.toLowerCase().includes(q) ||
|
|
55
|
+
t.description?.toLowerCase().includes(q) ||
|
|
56
|
+
t.id?.toLowerCase().includes(q),
|
|
57
|
+
)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
// Group the types by the optional groupBy callback. Preserve insertion order:
|
|
61
|
+
// groups appear in the order of their first-seen member.
|
|
62
|
+
const grouped = computed<Array<{ key: string; items: T[] }> | null>(() => {
|
|
63
|
+
if (!props.groupBy) return null
|
|
64
|
+
const order: string[] = []
|
|
65
|
+
const byKey = new Map<string, T[]>()
|
|
66
|
+
for (const t of visibleTypes.value) {
|
|
67
|
+
const key = props.groupBy(t)
|
|
68
|
+
const bucket = byKey.get(key)
|
|
69
|
+
if (bucket) {
|
|
70
|
+
bucket.push(t)
|
|
71
|
+
} else {
|
|
72
|
+
byKey.set(key, [t])
|
|
73
|
+
order.push(key)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return order.map((key) => ({ key, items: byKey.get(key) as T[] }))
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const itemClass = (id: string) =>
|
|
80
|
+
isSelected(id)
|
|
81
|
+
? 'bg-primary/10 text-primary ring-1 ring-primary/20'
|
|
82
|
+
: 'text-toned hover:bg-elevated/60'
|
|
83
|
+
</script>
|
|
84
|
+
|
|
85
|
+
<template>
|
|
86
|
+
<DmsCard :padded="false" class="flex flex-col overflow-hidden">
|
|
87
|
+
<div
|
|
88
|
+
v-if="title"
|
|
89
|
+
class="flex items-center justify-between gap-2 border-b border-default px-4 py-3"
|
|
90
|
+
>
|
|
91
|
+
<h2 class="text-sm font-semibold text-highlighted">{{ title }}</h2>
|
|
92
|
+
<UBadge color="neutral" variant="subtle" size="sm" class="tabular-nums">
|
|
93
|
+
{{ visibleTypes.length }}
|
|
94
|
+
</UBadge>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<div
|
|
98
|
+
v-if="searchEnabled && types.length"
|
|
99
|
+
class="border-b border-default px-3 py-2"
|
|
100
|
+
>
|
|
101
|
+
<UInput
|
|
102
|
+
v-model="query"
|
|
103
|
+
:placeholder="searchPlaceholder || $t('dms_automation.catalog.search')"
|
|
104
|
+
icon="i-ph-magnifying-glass"
|
|
105
|
+
size="sm"
|
|
106
|
+
autocomplete="off"
|
|
107
|
+
class="w-full"
|
|
108
|
+
/>
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
<div class="flex-1 overflow-y-auto p-2">
|
|
112
|
+
<div
|
|
113
|
+
v-if="!types || types.length === 0"
|
|
114
|
+
class="px-3 py-6 text-center text-sm text-dimmed"
|
|
115
|
+
>
|
|
116
|
+
{{ $t('dms_automation.catalog.empty') }}
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
<div
|
|
120
|
+
v-else-if="visibleTypes.length === 0"
|
|
121
|
+
class="px-3 py-6 text-center text-sm text-dimmed"
|
|
122
|
+
>
|
|
123
|
+
{{ $t('dms_automation.catalog.noResults') }}
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<template v-else-if="grouped">
|
|
127
|
+
<div
|
|
128
|
+
v-for="group in grouped"
|
|
129
|
+
:key="group.key"
|
|
130
|
+
class="mb-2 flex flex-col gap-1 last:mb-0"
|
|
131
|
+
>
|
|
132
|
+
<div
|
|
133
|
+
class="px-3 pb-1 pt-2 text-xs font-semibold uppercase tracking-wide text-dimmed"
|
|
134
|
+
>
|
|
135
|
+
{{ group.key }}
|
|
136
|
+
</div>
|
|
137
|
+
<ul class="flex flex-col gap-1">
|
|
138
|
+
<li v-for="t in group.items" :key="t.id">
|
|
139
|
+
<button
|
|
140
|
+
type="button"
|
|
141
|
+
class="flex w-full items-start gap-3 rounded-lg px-3 py-2 text-left transition-colors"
|
|
142
|
+
:class="itemClass(t.id)"
|
|
143
|
+
@click="select(t.id)"
|
|
144
|
+
>
|
|
145
|
+
<UIcon
|
|
146
|
+
v-if="t.icon"
|
|
147
|
+
:name="t.icon"
|
|
148
|
+
class="mt-0.5 size-4 shrink-0"
|
|
149
|
+
:class="isSelected(t.id) ? 'text-primary' : 'text-dimmed'"
|
|
150
|
+
/>
|
|
151
|
+
<div class="min-w-0 flex-1">
|
|
152
|
+
<div
|
|
153
|
+
class="truncate text-sm font-medium"
|
|
154
|
+
:class="isSelected(t.id) ? 'text-primary' : 'text-highlighted'"
|
|
155
|
+
>
|
|
156
|
+
{{ t.name }}
|
|
157
|
+
</div>
|
|
158
|
+
<div v-if="t.description" class="truncate text-xs text-muted">
|
|
159
|
+
{{ t.description }}
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
</button>
|
|
163
|
+
</li>
|
|
164
|
+
</ul>
|
|
165
|
+
</div>
|
|
166
|
+
</template>
|
|
167
|
+
|
|
168
|
+
<ul v-else class="flex flex-col gap-1">
|
|
169
|
+
<li v-for="t in visibleTypes" :key="t.id">
|
|
170
|
+
<button
|
|
171
|
+
type="button"
|
|
172
|
+
class="flex w-full items-start gap-3 rounded-lg px-3 py-2 text-left transition-colors"
|
|
173
|
+
:class="itemClass(t.id)"
|
|
174
|
+
@click="select(t.id)"
|
|
175
|
+
>
|
|
176
|
+
<UIcon
|
|
177
|
+
v-if="t.icon"
|
|
178
|
+
:name="t.icon"
|
|
179
|
+
class="mt-0.5 size-4 shrink-0"
|
|
180
|
+
:class="isSelected(t.id) ? 'text-primary' : 'text-dimmed'"
|
|
181
|
+
/>
|
|
182
|
+
<div class="min-w-0 flex-1">
|
|
183
|
+
<div
|
|
184
|
+
class="truncate text-sm font-medium"
|
|
185
|
+
:class="isSelected(t.id) ? 'text-primary' : 'text-highlighted'"
|
|
186
|
+
>
|
|
187
|
+
{{ t.name }}
|
|
188
|
+
</div>
|
|
189
|
+
<div v-if="t.description" class="truncate text-xs text-muted">
|
|
190
|
+
{{ t.description }}
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
</button>
|
|
194
|
+
</li>
|
|
195
|
+
</ul>
|
|
196
|
+
</div>
|
|
197
|
+
</DmsCard>
|
|
198
|
+
</template>
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref } from 'vue'
|
|
3
|
+
import { type ListEnvelope, unwrapList } from '../utils/automation'
|
|
4
|
+
import type {
|
|
5
|
+
DataNodeType,
|
|
6
|
+
JsonSchema,
|
|
7
|
+
JsonSchemaProperty,
|
|
8
|
+
} from '../composables/useGraphConnect'
|
|
9
|
+
|
|
10
|
+
// Catalog-side shape: backend returns DataNodeType minus `evaluate`.
|
|
11
|
+
type DataNodeTypeItem = Omit<DataNodeType, 'inputSchema' | 'outputSchema'> & {
|
|
12
|
+
inputSchema?: JsonSchema
|
|
13
|
+
outputSchema?: JsonSchema
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type JsonSchemaProp = JsonSchemaProperty
|
|
17
|
+
|
|
18
|
+
interface PortRow {
|
|
19
|
+
name: string
|
|
20
|
+
type: string | string[]
|
|
21
|
+
description?: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// `embedded` drops the page-head when this catalog is rendered inside a Library tab.
|
|
25
|
+
defineProps<{ embedded?: boolean }>()
|
|
26
|
+
|
|
27
|
+
const { $authFetch } = useAuthFetch()
|
|
28
|
+
|
|
29
|
+
const items = ref<DataNodeTypeItem[]>([])
|
|
30
|
+
const loading = ref(false)
|
|
31
|
+
const loadError = ref<string | null>(null)
|
|
32
|
+
const selectedId = ref<string | null>(null)
|
|
33
|
+
|
|
34
|
+
async function loadList() {
|
|
35
|
+
loading.value = true
|
|
36
|
+
loadError.value = null
|
|
37
|
+
try {
|
|
38
|
+
const data = await $authFetch<DataNodeTypeItem[] | ListEnvelope<DataNodeTypeItem>>(
|
|
39
|
+
'/api/automation/data-node-types',
|
|
40
|
+
)
|
|
41
|
+
items.value = unwrapList(data)
|
|
42
|
+
if (!selectedId.value && items.value[0]) {
|
|
43
|
+
selectedId.value = items.value[0].id
|
|
44
|
+
}
|
|
45
|
+
} catch (e) {
|
|
46
|
+
loadError.value = (e as Error).message ?? 'Failed to load data node types'
|
|
47
|
+
} finally {
|
|
48
|
+
loading.value = false
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
await loadList()
|
|
53
|
+
|
|
54
|
+
const selectedType = computed<DataNodeTypeItem | null>(
|
|
55
|
+
() => items.value.find((t) => t.id === selectedId.value) ?? null,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
function propsOf(schema: JsonSchema | undefined): PortRow[] {
|
|
59
|
+
const props = schema?.properties ?? {}
|
|
60
|
+
return Object.entries(props).map(([name, p]) => ({
|
|
61
|
+
name,
|
|
62
|
+
type: (p as JsonSchemaProp)?.type ?? 'any',
|
|
63
|
+
description: (p as JsonSchemaProp)?.description,
|
|
64
|
+
}))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const inputs = computed<PortRow[]>(() => propsOf(selectedType.value?.inputSchema))
|
|
68
|
+
const outputs = computed<PortRow[]>(() => propsOf(selectedType.value?.outputSchema))
|
|
69
|
+
|
|
70
|
+
function categoryOf(t: DataNodeTypeItem): string {
|
|
71
|
+
return t.category ?? 'other'
|
|
72
|
+
}
|
|
73
|
+
</script>
|
|
74
|
+
|
|
75
|
+
<template>
|
|
76
|
+
<div :class="embedded ? 'flex flex-col gap-5' : 'flex flex-col gap-6 p-4 sm:p-6'">
|
|
77
|
+
<section v-if="!embedded" class="flex flex-wrap items-center gap-4">
|
|
78
|
+
<div
|
|
79
|
+
class="grid size-11 shrink-0 place-items-center rounded-xl bg-primary/10 text-primary ring ring-primary/20"
|
|
80
|
+
>
|
|
81
|
+
<UIcon name="i-ph-cube" class="size-6" />
|
|
82
|
+
</div>
|
|
83
|
+
<div class="min-w-0 flex-1">
|
|
84
|
+
<h1 class="text-2xl font-semibold tracking-tight text-highlighted">
|
|
85
|
+
{{ $t('dms_automation.data_nodes.title') }}
|
|
86
|
+
</h1>
|
|
87
|
+
<p class="text-sm text-muted">
|
|
88
|
+
{{ $t('dms_automation.data_nodes.description') }}
|
|
89
|
+
</p>
|
|
90
|
+
</div>
|
|
91
|
+
<UButton
|
|
92
|
+
class="ml-auto"
|
|
93
|
+
color="neutral"
|
|
94
|
+
variant="outline"
|
|
95
|
+
icon="i-ph-arrows-clockwise"
|
|
96
|
+
:loading="loading"
|
|
97
|
+
@click="loadList"
|
|
98
|
+
>
|
|
99
|
+
{{ $t('dms_automation.data_nodes.refresh') }}
|
|
100
|
+
</UButton>
|
|
101
|
+
</section>
|
|
102
|
+
|
|
103
|
+
<UAlert
|
|
104
|
+
v-if="loadError"
|
|
105
|
+
color="error"
|
|
106
|
+
variant="subtle"
|
|
107
|
+
icon="i-ph-warning"
|
|
108
|
+
:title="$t('dms_automation.data_nodes.loadError')"
|
|
109
|
+
:description="loadError"
|
|
110
|
+
/>
|
|
111
|
+
|
|
112
|
+
<div
|
|
113
|
+
class="grid grid-cols-1 gap-5 lg:grid-cols-[minmax(280px,340px)_1fr] lg:items-start"
|
|
114
|
+
>
|
|
115
|
+
<DmsAutomationTypeList
|
|
116
|
+
:types="items"
|
|
117
|
+
:model-value="selectedId"
|
|
118
|
+
:group-by="categoryOf"
|
|
119
|
+
:title="$t('dms_automation.data_nodes.listLabel')"
|
|
120
|
+
class="lg:max-h-[calc(100vh-12rem)]"
|
|
121
|
+
@update:model-value="selectedId = $event"
|
|
122
|
+
/>
|
|
123
|
+
|
|
124
|
+
<DmsCard v-if="selectedType" :padded="false" class="flex flex-col">
|
|
125
|
+
<div class="flex items-start gap-3 border-b border-default px-5 py-4 sm:px-6">
|
|
126
|
+
<div
|
|
127
|
+
class="grid size-10 shrink-0 place-items-center rounded-lg bg-primary/10 text-primary ring ring-primary/20"
|
|
128
|
+
>
|
|
129
|
+
<UIcon :name="selectedType.icon || 'i-ph-cube'" class="size-5" />
|
|
130
|
+
</div>
|
|
131
|
+
<div class="min-w-0 flex-1">
|
|
132
|
+
<h2 class="truncate text-lg font-semibold text-highlighted">
|
|
133
|
+
{{ selectedType.name }}
|
|
134
|
+
</h2>
|
|
135
|
+
<p class="mt-1 font-mono text-xs text-dimmed">{{ selectedType.id }}</p>
|
|
136
|
+
</div>
|
|
137
|
+
<UBadge
|
|
138
|
+
v-if="selectedType.category"
|
|
139
|
+
color="neutral"
|
|
140
|
+
variant="subtle"
|
|
141
|
+
class="shrink-0"
|
|
142
|
+
>
|
|
143
|
+
{{ selectedType.category }}
|
|
144
|
+
</UBadge>
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
<div class="flex flex-col gap-6 px-5 py-4 sm:px-6">
|
|
148
|
+
<p v-if="selectedType.description" class="text-sm text-toned">
|
|
149
|
+
{{ selectedType.description }}
|
|
150
|
+
</p>
|
|
151
|
+
|
|
152
|
+
<div class="flex flex-col gap-2">
|
|
153
|
+
<div class="text-sm font-semibold text-highlighted">
|
|
154
|
+
{{ $t('dms_automation.data_nodes.inputs') }}
|
|
155
|
+
</div>
|
|
156
|
+
<div v-if="inputs.length === 0" class="text-sm text-dimmed">
|
|
157
|
+
{{ $t('dms_automation.data_nodes.noPorts') }}
|
|
158
|
+
</div>
|
|
159
|
+
<div
|
|
160
|
+
v-else
|
|
161
|
+
class="overflow-hidden rounded-lg border border-default"
|
|
162
|
+
>
|
|
163
|
+
<table class="w-full text-sm">
|
|
164
|
+
<thead>
|
|
165
|
+
<tr class="border-b border-default bg-muted">
|
|
166
|
+
<th class="px-4 py-2.5 text-left text-xs font-semibold text-dimmed">
|
|
167
|
+
{{ $t('dms_automation.data_nodes.col.name') }}
|
|
168
|
+
</th>
|
|
169
|
+
<th class="px-4 py-2.5 text-left text-xs font-semibold text-dimmed">
|
|
170
|
+
{{ $t('dms_automation.data_nodes.col.type') }}
|
|
171
|
+
</th>
|
|
172
|
+
<th class="px-4 py-2.5 text-left text-xs font-semibold text-dimmed">
|
|
173
|
+
{{ $t('dms_automation.data_nodes.col.description') }}
|
|
174
|
+
</th>
|
|
175
|
+
</tr>
|
|
176
|
+
</thead>
|
|
177
|
+
<tbody>
|
|
178
|
+
<tr
|
|
179
|
+
v-for="row in inputs"
|
|
180
|
+
:key="`in-${row.name}`"
|
|
181
|
+
class="border-b border-default/60 last:border-0"
|
|
182
|
+
>
|
|
183
|
+
<td class="px-4 py-2.5 font-mono text-highlighted">
|
|
184
|
+
{{ row.name }}
|
|
185
|
+
</td>
|
|
186
|
+
<td class="whitespace-nowrap px-4 py-2.5 font-mono text-primary">
|
|
187
|
+
{{ row.type }}
|
|
188
|
+
</td>
|
|
189
|
+
<td class="px-4 py-2.5 text-muted">
|
|
190
|
+
{{ row.description ?? '' }}
|
|
191
|
+
</td>
|
|
192
|
+
</tr>
|
|
193
|
+
</tbody>
|
|
194
|
+
</table>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
|
|
198
|
+
<div class="flex flex-col gap-2">
|
|
199
|
+
<div class="text-sm font-semibold text-highlighted">
|
|
200
|
+
{{ $t('dms_automation.data_nodes.outputs') }}
|
|
201
|
+
</div>
|
|
202
|
+
<div v-if="outputs.length === 0" class="text-sm text-dimmed">
|
|
203
|
+
{{ $t('dms_automation.data_nodes.noPorts') }}
|
|
204
|
+
</div>
|
|
205
|
+
<div
|
|
206
|
+
v-else
|
|
207
|
+
class="overflow-hidden rounded-lg border border-default"
|
|
208
|
+
>
|
|
209
|
+
<table class="w-full text-sm">
|
|
210
|
+
<thead>
|
|
211
|
+
<tr class="border-b border-default bg-muted">
|
|
212
|
+
<th class="px-4 py-2.5 text-left text-xs font-semibold text-dimmed">
|
|
213
|
+
{{ $t('dms_automation.data_nodes.col.name') }}
|
|
214
|
+
</th>
|
|
215
|
+
<th class="px-4 py-2.5 text-left text-xs font-semibold text-dimmed">
|
|
216
|
+
{{ $t('dms_automation.data_nodes.col.type') }}
|
|
217
|
+
</th>
|
|
218
|
+
<th class="px-4 py-2.5 text-left text-xs font-semibold text-dimmed">
|
|
219
|
+
{{ $t('dms_automation.data_nodes.col.description') }}
|
|
220
|
+
</th>
|
|
221
|
+
</tr>
|
|
222
|
+
</thead>
|
|
223
|
+
<tbody>
|
|
224
|
+
<tr
|
|
225
|
+
v-for="row in outputs"
|
|
226
|
+
:key="`out-${row.name}`"
|
|
227
|
+
class="border-b border-default/60 last:border-0"
|
|
228
|
+
>
|
|
229
|
+
<td class="px-4 py-2.5 font-mono text-highlighted">
|
|
230
|
+
{{ row.name }}
|
|
231
|
+
</td>
|
|
232
|
+
<td class="whitespace-nowrap px-4 py-2.5 font-mono text-primary">
|
|
233
|
+
{{ row.type }}
|
|
234
|
+
</td>
|
|
235
|
+
<td class="px-4 py-2.5 text-muted">
|
|
236
|
+
{{ row.description ?? '' }}
|
|
237
|
+
</td>
|
|
238
|
+
</tr>
|
|
239
|
+
</tbody>
|
|
240
|
+
</table>
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
244
|
+
</DmsCard>
|
|
245
|
+
|
|
246
|
+
<DmsCard
|
|
247
|
+
v-else
|
|
248
|
+
class="flex min-h-[16rem] items-center justify-center text-center"
|
|
249
|
+
>
|
|
250
|
+
<div class="flex flex-col items-center gap-3 text-dimmed">
|
|
251
|
+
<UIcon name="i-ph-cube" class="size-8" />
|
|
252
|
+
<p class="max-w-xs text-sm">
|
|
253
|
+
{{ $t('dms_automation.data_nodes.empty') }}
|
|
254
|
+
</p>
|
|
255
|
+
</div>
|
|
256
|
+
</DmsCard>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
</template>
|