adrema/resources/js/views/formtemplate/FormBuilder.vue

207 lines
8.2 KiB
Vue
Raw Normal View History

2023-12-25 19:45:34 +01:00
<template>
2023-12-27 23:38:13 +01:00
<form class="grid gap-3 mt-4 grid-cols-[1fr_max-content] items-start" @submit.prevent="submit">
<div class="grid gap-3">
2023-12-28 00:37:25 +01:00
<slot name="meta"></slot>
2024-06-07 00:48:54 +02:00
<asideform
v-if="singleSection !== null && singleSection.mode === 'edit'"
2024-04-14 11:47:48 +02:00
:heading="`Sektion ${singleSection.index !== null ? 'bearbeiten' : 'erstellen'}`"
2024-06-07 00:48:54 +02:00
@close="singleSection = null"
@submit="storeSection"
>
<f-text :id="`sectionform-name`" v-model="singleSection.model.name" label="Name" :name="`sectionform-name`"></f-text>
<f-textarea :id="`sectionform-intro`" v-model="singleSection.model.intro" label="Einleitung" :name="`sectionform-intro`"></f-textarea>
2023-12-27 23:38:13 +01:00
</asideform>
2024-06-07 00:48:54 +02:00
<asideform v-if="singleSection !== null && singleSection.mode === 'reorder'" heading="Felder ordnen" @close="singleSection = null" @submit="storeSection">
<draggable v-model="singleSection.model.fields" item-key="key" :component-data="{class: 'mt-3 grid gap-3'}">
<template #item="{element}">
<div class="py-2 px-3 border rounded bg-zinc-800 hover:bg-zinc-700 transition justify-between flex items-center">
2024-04-17 21:18:23 +02:00
<span v-text="element.name"></span>
<a href="#">
2024-06-07 00:48:54 +02:00
<ui-sprite v-tooltip="`Umordnen`" class="w-5 h-5" src="menu"></ui-sprite>
2024-04-17 21:18:23 +02:00
</a>
</div>
</template>
</draggable>
</asideform>
2024-06-07 00:48:54 +02:00
<asideform v-if="singleSection === null && singleField === null" heading="Feld erstellen" :closeable="false" :storeable="false" @submit="storeField">
2023-12-28 00:32:41 +01:00
<div class="mt-3 grid gap-3">
2024-06-07 00:48:54 +02:00
<a v-for="(field, index) in props.meta.fields" :key="index" class="py-2 px-3 border rounded bg-zinc-800 hover:bg-zinc-700 transition" href="#" @click.prevent="addField(field)">
2023-12-28 00:32:41 +01:00
<span v-text="field.name"></span>
</a>
</div>
</asideform>
2024-06-07 00:48:54 +02:00
<asideform
v-if="singleSection === null && singleField !== null"
:heading="`Feld ${singleField.index !== null ? 'bearbeiten' : 'erstellen'}`"
@close="singleField = null"
@submit="storeField"
>
2023-12-27 23:38:13 +01:00
<f-text id="fieldname" v-model="singleField.model.name" label="Name" size="sm" name="fieldname"></f-text>
2024-06-07 00:48:54 +02:00
<f-textarea id="intro" v-model="singleField.model.intro" label="Einleitung" size="sm" name="intro"></f-textarea>
2023-12-27 23:38:13 +01:00
<column-selector v-model="singleField.model.columns"></column-selector>
2024-06-07 00:48:54 +02:00
<component :is="fields[singleField.model.type]" v-model="singleField.model" :payload="inner.sections" :meta="props.meta"></component>
<f-select id="nami_type" v-model="singleField.model.nami_type" :options="meta.namiTypes" label="NaMi-Feld" size="sm" name="nami_type"></f-select>
<f-select id="special_type" v-model="singleField.model.special_type" :options="meta.specialTypes" label="Bedeutung" size="sm" name="special_type"></f-select>
2024-04-10 00:00:20 +02:00
<f-textarea id="hint" v-model="singleField.model.hint" label="Hinweis" size="sm" name="hint"></f-textarea>
2024-06-07 00:48:54 +02:00
<f-switch
v-show="singleField.model.nami_type === null"
id="for_members"
v-model="singleField.model.for_members"
label="Für Unter-Mitglieder zusätzlich abfragen"
size="sm"
name="for_members"
></f-switch>
2023-12-27 23:38:13 +01:00
</asideform>
</div>
<ui-box heading="Vorschau" container-class="grid gap-3" class="w-[800px]">
2024-06-07 00:48:54 +02:00
<event-form
editable
2023-12-27 23:38:13 +01:00
style="--primary: hsl(181, 75%, 26%); --secondary: hsl(181, 75%, 35%); --font: hsl(181, 84%, 78%); --circle: hsl(181, 86%, 16%)"
2024-06-07 00:48:54 +02:00
:base-url="meta.base_url"
:value="previewString"
@editSection="editSection($event.detail[0])"
@addSection="addSection"
@editField="editField($event.detail[0], $event.detail[1])"
2023-12-27 23:38:13 +01:00
@deleteField="deleteField($event.detail[0], $event.detail[1])"
2024-06-07 00:48:54 +02:00
@editFields="startReordering($event.detail[0])"
@deleteSection="deleteSection($event.detail[0])"
@active="updateActive($event.detail[0])"
></event-form>
2023-12-27 23:38:13 +01:00
</ui-box>
</form>
2023-12-25 19:45:34 +01:00
</template>
<script setup>
2024-06-07 00:48:54 +02:00
import {watch, computed, ref} from 'vue';
import {snakeCase} from 'change-case';
2024-03-17 16:50:18 +01:00
import '!/adrema-form/dist/main.js';
2023-12-25 22:46:06 +01:00
import Asideform from './Asideform.vue';
2023-12-26 00:44:49 +01:00
import TextareaField from './TextareaField.vue';
2023-12-26 20:20:32 +01:00
import TextField from './TextField.vue';
2023-12-30 01:00:58 +01:00
import DateField from './DateField.vue';
2023-12-26 20:20:32 +01:00
import DropdownField from './RadioField.vue';
2023-12-26 00:44:49 +01:00
import RadioField from './RadioField.vue';
2023-12-31 14:29:50 +01:00
import GroupField from './GroupField.vue';
2024-04-14 11:47:48 +02:00
import NumberField from './NumberField.vue';
2023-12-26 01:05:45 +01:00
import CheckboxField from './CheckboxField.vue';
2023-12-26 20:20:32 +01:00
import CheckboxesField from './CheckboxesField.vue';
2023-12-27 01:20:07 +01:00
import ColumnSelector from './ColumnSelector.vue';
2024-04-17 21:18:23 +02:00
import Draggable from 'vuedraggable';
2023-12-25 19:45:34 +01:00
2023-12-25 22:46:06 +01:00
const singleSection = ref(null);
const singleField = ref(null);
2023-12-28 00:32:41 +01:00
const active = ref(null);
2024-04-17 21:18:23 +02:00
async function onReorder() {
var order = this.inner.map((f) => f.id);
this.loading = true;
2024-06-07 00:48:54 +02:00
This.inner = (await this.axios.patch(`/mediaupload/${this.parentName}/${this.parentId}/${this.collection}`, {order})).data;
2024-04-17 21:18:23 +02:00
this.loading = false;
}
2023-12-28 00:32:41 +01:00
function updateActive(a) {
active.value = a;
if (a === null) {
addSection();
}
}
2023-12-25 19:45:34 +01:00
const props = defineProps({
modelValue: {},
meta: {},
});
2023-12-27 23:38:13 +01:00
const emit = defineEmits(['update:modelValue']);
2023-12-25 22:46:06 +01:00
2023-12-26 00:44:49 +01:00
const fields = {
TextareaField: TextareaField,
2023-12-26 20:20:32 +01:00
TextField: TextField,
2023-12-30 01:00:58 +01:00
DateField: DateField,
2023-12-26 00:44:49 +01:00
DropdownField: DropdownField,
RadioField: RadioField,
2023-12-26 01:05:45 +01:00
CheckboxField: CheckboxField,
CheckboxesField: CheckboxesField,
2023-12-31 14:29:50 +01:00
GroupField: GroupField,
2024-04-14 11:47:48 +02:00
NumberField: NumberField,
2023-12-26 00:44:49 +01:00
};
2023-12-25 22:46:06 +01:00
function editSection(sectionIndex) {
singleSection.value = {
2024-06-07 00:48:54 +02:00
model: {...inner.value.sections[sectionIndex]},
2023-12-25 22:46:06 +01:00
index: sectionIndex,
2024-04-17 21:18:23 +02:00
mode: 'edit',
};
}
function startReordering(index) {
singleSection.value = {
2024-06-07 00:48:54 +02:00
model: {...inner.value.sections[index]},
2024-04-17 21:18:23 +02:00
index: index,
mode: 'reorder',
2023-12-25 22:46:06 +01:00
};
}
2023-12-25 19:45:34 +01:00
2023-12-27 23:38:13 +01:00
function push() {
emit('update:modelValue', inner.value);
}
2023-12-25 19:45:34 +01:00
const inner = ref(JSON.parse(JSON.stringify(props.modelValue)));
2023-12-25 22:46:06 +01:00
const innerMeta = ref(JSON.parse(JSON.stringify(props.meta)));
2023-12-25 19:45:34 +01:00
function addSection() {
2023-12-25 22:46:06 +01:00
singleSection.value = {
model: JSON.parse(JSON.stringify(innerMeta.value.section_default)),
index: null,
2024-04-17 21:18:23 +02:00
mode: 'edit',
2023-12-25 22:46:06 +01:00
};
}
function editField(sindex, findex) {
singleField.value = {
2023-12-27 23:38:13 +01:00
model: JSON.parse(JSON.stringify(inner.value.sections[sindex].fields[findex])),
2023-12-25 22:46:06 +01:00
sectionIndex: sindex,
index: findex,
};
2023-12-25 19:45:34 +01:00
}
2023-12-25 22:46:06 +01:00
function storeSection() {
if (singleSection.value.index !== null) {
2023-12-27 23:38:13 +01:00
inner.value.sections.splice(singleSection.value.index, 1, singleSection.value.model);
2023-12-25 22:46:06 +01:00
} else {
2023-12-27 23:38:13 +01:00
inner.value.sections.push(singleSection.value.model);
2023-12-25 22:46:06 +01:00
}
singleSection.value = null;
2023-12-27 23:38:13 +01:00
push();
2023-12-25 19:45:34 +01:00
}
2023-12-25 22:46:06 +01:00
function storeField() {
2023-12-26 20:06:57 +01:00
singleField.value.model.key = snakeCase(singleField.value.model.name);
2023-12-25 22:46:06 +01:00
if (singleField.value.index !== null) {
2023-12-27 23:38:13 +01:00
inner.value.sections[singleField.value.sectionIndex].fields.splice(singleField.value.index, 1, singleField.value.model);
2023-12-25 22:46:06 +01:00
} else {
2023-12-27 23:38:13 +01:00
inner.value.sections[singleField.value.sectionIndex].fields.push(singleField.value.model);
2023-12-25 19:45:34 +01:00
}
2023-12-25 22:46:06 +01:00
singleField.value = null;
2023-12-27 23:38:13 +01:00
push();
2023-12-25 22:46:06 +01:00
}
function deleteField(sindex, findex) {
2023-12-27 23:38:13 +01:00
inner.value.sections[sindex].fields.splice(findex, 1);
push();
2023-12-25 22:46:06 +01:00
}
2023-12-28 00:32:41 +01:00
function addField(type) {
2023-12-25 22:46:06 +01:00
singleField.value = {
2023-12-28 00:32:41 +01:00
model: JSON.parse(JSON.stringify(type.default)),
sectionIndex: active,
2023-12-25 22:46:06 +01:00
index: null,
};
}
2023-12-27 01:27:47 +01:00
function deleteSection(sindex) {
2023-12-27 23:38:13 +01:00
inner.value.sections.splice(sindex, 1);
push();
2023-12-27 01:27:47 +01:00
}
2023-12-27 23:38:13 +01:00
const previewString = computed(() => (inner.value && inner.value ? JSON.stringify(inner.value) : '{}'));
2023-12-25 19:45:34 +01:00
</script>