|
|
@@ -0,0 +1,194 @@
|
|
|
+<script setup lang="ts">
|
|
|
+import { computed, watch } from 'vue'
|
|
|
+import NodeRuntimeConfig from '@/nodes/_base/NodeRuntimeConfig.vue'
|
|
|
+import { useSetterModel } from '@/nodes/src/_shared/useSetterModel'
|
|
|
+import SecretInput from '@/features/secretInput/SecretInput.vue'
|
|
|
+import { nodeMap } from '../src'
|
|
|
+
|
|
|
+interface CustomNodeOption {
|
|
|
+ label?: string
|
|
|
+ value?: string | number | boolean
|
|
|
+}
|
|
|
+
|
|
|
+interface CustomNodeParameter {
|
|
|
+ name?: string
|
|
|
+ label?: string
|
|
|
+ description?: string
|
|
|
+ type?: string
|
|
|
+ required?: boolean
|
|
|
+ defaultValue?: unknown
|
|
|
+ placeholder?: string
|
|
|
+ min?: number
|
|
|
+ max?: number
|
|
|
+ options?: CustomNodeOption[]
|
|
|
+}
|
|
|
+
|
|
|
+const props = defineProps<{
|
|
|
+ data: Record<string, any>
|
|
|
+}>()
|
|
|
+
|
|
|
+const emit = defineEmits<{
|
|
|
+ update: [data: Record<string, any>]
|
|
|
+}>()
|
|
|
+
|
|
|
+const formData = useSetterModel<Record<string, any>>(props, emit)
|
|
|
+console.log(111, formData, nodeMap)
|
|
|
+const parameters = computed<CustomNodeParameter[]>(
|
|
|
+ () => nodeMap?.[formData.value?.nodeType]?.parameters || []
|
|
|
+)
|
|
|
+
|
|
|
+const normalizeType = (type?: string) => {
|
|
|
+ const raw = `${type || ''}`.toLowerCase()
|
|
|
+ if (['text-input', 'text', 'string', 'input'].includes(raw)) return 'text-input'
|
|
|
+ if (['secret-input', 'password'].includes(raw)) return 'secret-input'
|
|
|
+ if (['text-area', 'textarea'].includes(raw)) return 'text-area'
|
|
|
+ if (['number', 'int', 'integer', 'float', 'double'].includes(raw)) return 'number'
|
|
|
+ if (['select', 'enum'].includes(raw)) return 'select'
|
|
|
+ if (['checkbox', 'switch', 'boolean', 'bool'].includes(raw)) return 'checkbox'
|
|
|
+ if (raw === 'edg-link') return 'edg-link'
|
|
|
+ return 'text-input'
|
|
|
+}
|
|
|
+
|
|
|
+const normalizeDefaultValue = (parameter: CustomNodeParameter) => {
|
|
|
+ const type = normalizeType(parameter.type)
|
|
|
+ if (parameter.defaultValue !== undefined) {
|
|
|
+ return parameter.defaultValue
|
|
|
+ }
|
|
|
+ if (type === 'checkbox') return false
|
|
|
+ if (type === 'number') return undefined
|
|
|
+ return ''
|
|
|
+}
|
|
|
+
|
|
|
+watch(
|
|
|
+ parameters,
|
|
|
+ (newParameters) => {
|
|
|
+ for (const parameter of newParameters) {
|
|
|
+ const key = parameter.name
|
|
|
+ if (!key) continue
|
|
|
+ if (normalizeType(parameter.type) === 'edg-link') continue
|
|
|
+
|
|
|
+ formData.value[key] = normalizeDefaultValue(parameter)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ { immediate: true, deep: true }
|
|
|
+)
|
|
|
+
|
|
|
+const getSelectOptions = (parameter: CustomNodeParameter): CustomNodeOption[] => {
|
|
|
+ if (!Array.isArray(parameter.options)) return []
|
|
|
+ return parameter.options
|
|
|
+ .map((item) => ({
|
|
|
+ label: item?.label ?? `${item?.value ?? ''}`,
|
|
|
+ value: item?.value ?? item?.label ?? ''
|
|
|
+ }))
|
|
|
+ .filter((item) => item.label !== undefined)
|
|
|
+}
|
|
|
+
|
|
|
+const getLabel = (parameter: CustomNodeParameter) => parameter.label || parameter.name || 'param'
|
|
|
+
|
|
|
+const getParameterValue = (parameter: CustomNodeParameter) => {
|
|
|
+ const key = parameter.name
|
|
|
+ if (!key) return undefined
|
|
|
+ return formData.value?.[key]
|
|
|
+}
|
|
|
+
|
|
|
+const setParameterValue = (parameter: CustomNodeParameter, value: unknown) => {
|
|
|
+ const key = parameter.name
|
|
|
+ if (!key) return
|
|
|
+
|
|
|
+ formData.value[key] = value
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <el-scrollbar class="w-full box-border">
|
|
|
+ <el-form label-position="top" label-width="120px" class="p-12px">
|
|
|
+ <el-form-item
|
|
|
+ v-for="parameter in parameters"
|
|
|
+ :key="parameter.name || parameter.label"
|
|
|
+ :required="!!parameter.required"
|
|
|
+ >
|
|
|
+ <template #label>
|
|
|
+ <div class="w-full flex items-center justify-between beautify">
|
|
|
+ <label class="text-14px font-bold text-gray-700">{{ getLabel(parameter) }}</label>
|
|
|
+ </div>
|
|
|
+ <div v-if="parameter.description" class="text-12px text-gray-500">
|
|
|
+ {{ parameter.description }}
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <!-- <el-alert
|
|
|
+ v-if="isEdgeLink(parameter)"
|
|
|
+ type="info"
|
|
|
+ show-icon
|
|
|
+ :closable="false"
|
|
|
+ :title="parameter.description || 'Edge-link output, no value input needed'"
|
|
|
+ /> -->
|
|
|
+
|
|
|
+ <el-input
|
|
|
+ v-if="normalizeType(parameter.type) === 'text-input'"
|
|
|
+ :model-value="getParameterValue(parameter)"
|
|
|
+ :placeholder="parameter.placeholder || ''"
|
|
|
+ @update:model-value="setParameterValue(parameter, $event)"
|
|
|
+ />
|
|
|
+
|
|
|
+ <SecretInput
|
|
|
+ v-else-if="normalizeType(parameter.type) === 'secret-input'"
|
|
|
+ :model-value="getParameterValue(parameter) as any"
|
|
|
+ :placeholder="parameter.placeholder || ''"
|
|
|
+ @update:model-value="setParameterValue(parameter, $event)"
|
|
|
+ />
|
|
|
+
|
|
|
+ <el-input
|
|
|
+ v-else-if="normalizeType(parameter.type) === 'text-area'"
|
|
|
+ :model-value="getParameterValue(parameter)"
|
|
|
+ :placeholder="parameter.placeholder || ''"
|
|
|
+ type="textarea"
|
|
|
+ :autosize="{ minRows: 3, maxRows: 8 }"
|
|
|
+ @update:model-value="setParameterValue(parameter, $event)"
|
|
|
+ />
|
|
|
+
|
|
|
+ <el-input-number
|
|
|
+ v-else-if="normalizeType(parameter.type) === 'number'"
|
|
|
+ :model-value="getParameterValue(parameter)"
|
|
|
+ :min="parameter.min"
|
|
|
+ :max="parameter.max"
|
|
|
+ controls-position="right"
|
|
|
+ style="width: 100%"
|
|
|
+ @update:model-value="setParameterValue(parameter, $event)"
|
|
|
+ />
|
|
|
+
|
|
|
+ <el-select
|
|
|
+ v-else-if="normalizeType(parameter.type) === 'select'"
|
|
|
+ :model-value="getParameterValue(parameter)"
|
|
|
+ style="width: 100%"
|
|
|
+ @update:model-value="setParameterValue(parameter, $event)"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="option in getSelectOptions(parameter)"
|
|
|
+ :key="`${parameter.name}-${option.value}`"
|
|
|
+ :label="option.label"
|
|
|
+ :value="option.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+
|
|
|
+ <el-switch
|
|
|
+ v-else-if="normalizeType(parameter.type) === 'checkbox'"
|
|
|
+ :model-value="Boolean(getParameterValue(parameter))"
|
|
|
+ @update:model-value="setParameterValue(parameter, $event)"
|
|
|
+ />
|
|
|
+
|
|
|
+ <el-input
|
|
|
+ v-else
|
|
|
+ :model-value="getParameterValue(parameter)"
|
|
|
+ :placeholder="parameter.placeholder || ''"
|
|
|
+ @update:model-value="setParameterValue(parameter, $event)"
|
|
|
+ />
|
|
|
+
|
|
|
+ <div v-if="parameter.description" class="text-12px text-gray-500 mt-6px">
|
|
|
+ {{ parameter.description }}
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <NodeRuntimeConfig v-model="formData" />
|
|
|
+ </el-scrollbar>
|
|
|
+</template>
|