add sub componet in catego ske
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
:lock-type="lockRootType"
|
||||
:locked-type-label="displayedRootTypeLabel"
|
||||
:allow-subcomponents="allowSubcomponents"
|
||||
:max-subcomponent-depth="maxSubcomponentDepth"
|
||||
is-root
|
||||
/>
|
||||
</div>
|
||||
@@ -48,6 +49,10 @@ const props = defineProps({
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
maxSubcomponentDepth: {
|
||||
type: Number,
|
||||
default: Infinity,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
@@ -61,6 +66,9 @@ const { componentTypes, loadComponentTypes } = useComponentTypes()
|
||||
const availablePieceTypes = computed(() => pieceTypes.value ?? [])
|
||||
const availableComponentTypes = computed(() => componentTypes.value ?? [])
|
||||
const allowSubcomponents = computed(() => props.allowSubcomponents !== false)
|
||||
const maxSubcomponentDepth = computed(() =>
|
||||
typeof props.maxSubcomponentDepth === 'number' ? props.maxSubcomponentDepth : Infinity,
|
||||
)
|
||||
|
||||
const fallbackRootTypeLabel = computed(() => {
|
||||
if (!props.rootTypeId) {
|
||||
@@ -72,6 +80,79 @@ const fallbackRootTypeLabel = computed(() => {
|
||||
|
||||
const displayedRootTypeLabel = computed(() => props.rootTypeLabel || fallbackRootTypeLabel.value)
|
||||
|
||||
const formatOptionsText = (field: Record<string, any>) => {
|
||||
if (typeof field?.optionsText === 'string') {
|
||||
return field.optionsText
|
||||
}
|
||||
if (Array.isArray(field?.options)) {
|
||||
return field.options.join('\n')
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
const normalizeLineEndings = (text: string) =>
|
||||
text.replace(/\r\n/g, '\n').replace(/\r/g, '\n')
|
||||
|
||||
const parseOptionsFromText = (text: string) => {
|
||||
return text
|
||||
.split('\n')
|
||||
.map((option) => option.trim())
|
||||
.filter((option) => option.length > 0)
|
||||
}
|
||||
|
||||
const applyCustomFieldOptions = (node: Record<string, any> | null | undefined) => {
|
||||
if (!node || typeof node !== 'object') {
|
||||
return
|
||||
}
|
||||
|
||||
if (Array.isArray(node.customFields)) {
|
||||
node.customFields = node.customFields.map((field: any) => {
|
||||
if (!field || typeof field !== 'object') {
|
||||
return field
|
||||
}
|
||||
|
||||
const next = { ...field }
|
||||
if (next.type === 'select') {
|
||||
const baseText = normalizeLineEndings(formatOptionsText(next))
|
||||
if (next.optionsText !== baseText) {
|
||||
next.optionsText = baseText
|
||||
}
|
||||
const parsedOptions = parseOptionsFromText(next.optionsText || '')
|
||||
if (parsedOptions.length > 0) {
|
||||
next.options = parsedOptions
|
||||
} else {
|
||||
delete next.options
|
||||
}
|
||||
} else {
|
||||
if (next.options !== undefined) {
|
||||
delete next.options
|
||||
}
|
||||
if (next.optionsText !== undefined && next.optionsText !== '') {
|
||||
next.optionsText = ''
|
||||
}
|
||||
}
|
||||
return next
|
||||
})
|
||||
}
|
||||
|
||||
if (Array.isArray(node.subcomponents)) {
|
||||
node.subcomponents = node.subcomponents.map((sub: any) => {
|
||||
if (!sub || typeof sub !== 'object') {
|
||||
return sub
|
||||
}
|
||||
const copy = { ...sub }
|
||||
applyCustomFieldOptions(copy)
|
||||
return copy
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const prepareStructureForEmit = (structure: any) => {
|
||||
const clone = cloneStructure(structure)
|
||||
applyCustomFieldOptions(clone as Record<string, any>)
|
||||
return clone
|
||||
}
|
||||
|
||||
const syncRootType = () => {
|
||||
if (!props.lockRootType) {
|
||||
previousLockedLabel.value = props.rootTypeLabel || ''
|
||||
@@ -97,9 +178,14 @@ const syncRootType = () => {
|
||||
previousLockedLabel.value = newLabel
|
||||
}
|
||||
|
||||
let lastEmitted = JSON.stringify(cloneStructure(props.modelValue))
|
||||
let lastEmitted = JSON.stringify(prepareStructureForEmit(props.modelValue))
|
||||
|
||||
const syncFromProps = (value: any) => {
|
||||
const normalizedIncoming = prepareStructureForEmit(value)
|
||||
const incomingSerialized = JSON.stringify(normalizedIncoming)
|
||||
if (incomingSerialized === lastEmitted) {
|
||||
return
|
||||
}
|
||||
const hydrated = hydrateStructureForEditor(value)
|
||||
localStructure.customFields = hydrated.customFields
|
||||
localStructure.pieces = hydrated.pieces
|
||||
@@ -109,7 +195,7 @@ const syncFromProps = (value: any) => {
|
||||
localStructure.modelId = hydrated.modelId
|
||||
localStructure.familyCode = hydrated.familyCode
|
||||
localStructure.alias = hydrated.alias
|
||||
lastEmitted = JSON.stringify(cloneStructure(value))
|
||||
lastEmitted = incomingSerialized
|
||||
syncRootType()
|
||||
}
|
||||
|
||||
@@ -139,7 +225,7 @@ watch(
|
||||
watch(
|
||||
localStructure,
|
||||
(value) => {
|
||||
const payload = cloneStructure(value)
|
||||
const payload = prepareStructureForEmit(value)
|
||||
const serialized = JSON.stringify(payload)
|
||||
if (serialized !== lastEmitted) {
|
||||
lastEmitted = serialized
|
||||
|
||||
Reference in New Issue
Block a user