|
| 1 | +<script setup lang='ts'> |
| 2 | +import { useDragAndDrop } from '@formkit/drag-and-drop/vue' |
| 3 | +import { FormKitSchema } from '@formkit/vue' |
| 4 | +import { ref } from 'vue' |
| 5 | +import { useInputEditor, useInputEditorSchema } from 'my-library' |
| 6 | +import { blueprint, formkitPreset } from '../../utils/presets' |
| 7 | +
|
| 8 | +const { editorSchema } = useInputEditorSchema() |
| 9 | +const { generateSchemaItemId, schemaToEditorData, editorDataToSchema } = useInputEditor() |
| 10 | +
|
| 11 | +const formSchema = ref(editorSchema) |
| 12 | +const formData = ref(null) |
| 13 | +
|
| 14 | +function enhanceValuesForInputList(values: any[]): any[] { |
| 15 | + const result = [] |
| 16 | + values.forEach((value) => { |
| 17 | + result.push({ ...value, editableItemId: generateSchemaItemId(), selectButton: 'showBasic' }) |
| 18 | + }) |
| 19 | + return result |
| 20 | +} |
| 21 | +
|
| 22 | +const [formInputRef, formInputList] = useDragAndDrop(enhanceValuesForInputList(formkitPreset), { dragHandle: '.p-drag-handle', plugins: [] }) |
| 23 | +
|
| 24 | +function actionDelete(schema: any) { |
| 25 | + formInputList.value = formInputList.value.filter(input => input !== schema) |
| 26 | +} |
| 27 | +
|
| 28 | +function actionEdit(schema: any) { |
| 29 | + formData.value = schemaToEditorData({ ...schema }) |
| 30 | +} |
| 31 | +
|
| 32 | +function actionInsert(schema: any) { |
| 33 | + const index = formInputList.value.indexOf(schema) + 1 |
| 34 | + const schemaToInsert = { ...blueprint, editableItemId: generateSchemaItemId(), selectButton: 'showBasic' } |
| 35 | + formInputList.value.splice(index, 0, schemaToInsert) |
| 36 | +} |
| 37 | +
|
| 38 | +function actionCopy(schema: any) { |
| 39 | + const index = formInputList.value.indexOf(schema) + 1 |
| 40 | + const copyOfSchema = { ...schema, editableItemId: generateSchemaItemId() } |
| 41 | + formInputList.value.splice(index, 0, copyOfSchema) |
| 42 | +} |
| 43 | +
|
| 44 | +function actionUpdateInputs() { |
| 45 | + const schema = formInputList.value.find(input => input.editableItemId === formData.value.editableItemId) |
| 46 | + const index = formInputList.value.indexOf(schema) |
| 47 | + formInputList.value.splice(index, 1, editorDataToSchema(formData.value)) |
| 48 | + formData.value = null |
| 49 | +} |
| 50 | +
|
| 51 | +const schemaResult = computed(() => editorDataToSchema(formData.value)) |
| 52 | +
|
| 53 | +const schemaItems = computed(() => editorDataToSchema(formInputList.value)) |
| 54 | +</script> |
| 55 | + |
| 56 | +<template> |
| 57 | + <div cl> |
| 58 | + <Toolbar class="mt-6 mb-4"> |
| 59 | + <template #start> |
| 60 | + <Button icon="pi pi-plus" class="mr-2" severity="secondary" text /> |
| 61 | + <Button icon="pi pi-print" class="mr-2" severity="secondary" text /> |
| 62 | + <Button icon="pi pi-upload" severity="secondary" text /> |
| 63 | + </template> |
| 64 | + |
| 65 | + <template #center> |
| 66 | + Form Editor |
| 67 | + </template> |
| 68 | + <template #end /> |
| 69 | + </Toolbar> |
| 70 | + <div class="grid grid-cols-2 xl:grid-cols-3 gap-10"> |
| 71 | + <div> |
| 72 | + <ul ref="formInputRef" class="list-none"> |
| 73 | + <li v-for="formInput in formInputList" :key="formInput" class="mb-1"> |
| 74 | + <div class="" style="box-sizing: border-box;"> |
| 75 | + <div class="min-w-100 mr-4 flex gap-2"> |
| 76 | + <span class="block p-drag-handle"><i class="pi pi-bars text-[color:var(--primary-color)]" /></span> |
| 77 | + <i class="pi pi-file-edit text-[color:var(--primary-color)] mb-2" @click="actionEdit(formInput)" /> |
| 78 | + <i class="pi pi-copy text-[color:var(--primary-color)] mb-2" @click="actionCopy(formInput)" /> |
| 79 | + <i class="pi pi-plus text-[color:var(--primary-color)] mb-2" @click="actionInsert(formInput)" /> |
| 80 | + <i class="pi pi-trash text-[color:var(--primary-color)]" @click="actionDelete(formInput)" /> |
| 81 | + <span class="text-gray-700">|</span> |
| 82 | + <i |
| 83 | + v-if="formInput.if && formInput.if.length > 0" v-tooltip="`condition: ${formInput.if}`" |
| 84 | + class="pi pi-question-circle text-yellow-700" |
| 85 | + /> |
| 86 | + <span class="text-xs text-yellow-500">{{ formInput.name }}</span> |
| 87 | + </div> |
| 88 | + <div class="min-w-100"> |
| 89 | + <FormKitSchema :schema="formInput" :data="{}" /> |
| 90 | + </div> |
| 91 | + </div> |
| 92 | + </li> |
| 93 | + </ul> |
| 94 | + <div> |
| 95 | + <pre class="text-xs color-gray-400">{{ formInputList }}</pre> |
| 96 | + </div> |
| 97 | + </div> |
| 98 | + <div v-if="formData" class="mt-4"> |
| 99 | + <FormKit |
| 100 | + |
| 101 | + v-model="formData" |
| 102 | + type="form" |
| 103 | + :submit-attrs="{ |
| 104 | + inputClass: 'p-button p-component', |
| 105 | + }" |
| 106 | + submit-label="Update Generated Input" |
| 107 | + @submit="actionUpdateInputs" |
| 108 | + > |
| 109 | + <FormKitSchema :schema="formSchema()" :data="formData" /> |
| 110 | + </FormKit> |
| 111 | + <div> |
| 112 | + <pre class="text-xs color-gray-400">{{ schemaResult }}</pre> |
| 113 | + </div> |
| 114 | + </div> |
| 115 | + </div> |
| 116 | + </div> |
| 117 | +</template> |
| 118 | + |
| 119 | +<style lang='scss' scoped> |
| 120 | +ul { |
| 121 | + display: block; |
| 122 | + padding-inline-start: 1em; |
| 123 | +} |
| 124 | +</style> |
0 commit comments