Teren-app/resources/js/Components/BasicTable.vue
2025-03-25 21:38:24 +01:00

192 lines
5.6 KiB
Vue

<script setup>
import { FwbButton, FwbModal, FwbTable, FwbTableBody, FwbTableCell, FwbTableHead, FwbTableHeadCell, FwbTableRow } from 'flowbite-vue';
import Drawer from './Drawer.vue';
import { useForm } from '@inertiajs/vue3';
import { ref } from 'vue';
import TextInput from './TextInput.vue';
import InputLabel from './InputLabel.vue';
import ActionMessage from './ActionMessage.vue';
import PrimaryButton from './PrimaryButton.vue';
import Modal from './Modal.vue';
import SecondaryButton from './SecondaryButton.vue';
const props = defineProps({
title: String,
description: String,
header: Array,
body: Array,
editor: {
type: Boolean,
default: false
},
options: {
type: Object,
default: {}
}
});
const drawerUpdateForm = ref(false);
const modalRemove = ref(false);
const formUpdate = (props.editor) ? useForm(props.options.editor_data.form.values) : false;
const formRemove = (props.editor) ? useForm({type: 'soft', key: null}) : false;
const openEditor = (ref, data) => {
formUpdate[ref.key] = ref.val;
for(const [key, value] of Object.entries(data)) {
formUpdate[key] = value;
}
drawerUpdateForm.value = true;
}
const closeEditor = () => {
drawerUpdateForm.value = false;
}
const setUpdateRoute = (name, params = false, index) => {
if(!params){
return route(name, index)
}
return route(name, [params, index]);
}
const update = () => {
const putRoute = setUpdateRoute(
props.options.editor_data.form.route.name,
props.options.editor_data.form.route.params,
formUpdate[props.options.editor_data.form.key]
)
formUpdate.put(putRoute, {
onSuccess: () => {
closeEditor();
formUpdate.reset();
console.log('ssss')
},
preserveScroll: true
});
}
const modalRemoveTitle = ref('');
const closeModal = () => {
modalRemove.value = false;
}
const showModal = (key, title) => {
modalRemoveTitle.value = title;
formRemove.key = key;
modalRemove.value = true;
}
const remove = () => {
const removeRoute = setUpdateRoute(
props.options.editor_data.form.route_remove.name,
props.options.editor_data.form.route_remove.params,
formRemove.key
)
formRemove.delete(removeRoute, {
onSuccess: () => {
closeModal();
formRemove.reset();
},
preserveScroll: true
});
}
</script>
<template>
<div class="relative overflow-x-auto">
<FwbTable hoverable>
<FwbTableHead>
<FwbTableHeadCell v-for="h in header">{{ h.data }}</FwbTableHeadCell>
<FwbTableHeadCell v-if="editor"></FwbTableHeadCell>
<FwbTableHeadCell v-else />
</FwbTableHead>
<FwbTableBody>
<FwbTableRow v-for="(row, key, parent_index) in body" :class="row.options.class" >
<FwbTableCell v-for="col in row.cols">
<a v-if="col.link !== undefined" :class="col.link.css" :href="route(col.link.route, col.link.options)">{{ col.data }}</a>
<span v-else>{{ col.data }}</span>
</FwbTableCell>
<FwbTableCell v-if="editor">
<fwb-button class="mr-1" size="sm" color="default" @click="openEditor(row.options.ref, row.options.editable)" outline>Edit</fwb-button>
<fwb-button size="sm" color="red" @click="showModal(row.options.ref.val, row.options.title)" outline>Remove</fwb-button>
</FwbTableCell>
<FwbTableCell v-else />
</FwbTableRow>
</FwbTableBody>
</FwbTable>
</div>
<Drawer
v-if="editor"
:show="drawerUpdateForm"
@close="drawerUpdateForm = false"
>
<template #title>Update {{ options.editor_data.title }}</template>
<template #content>
<form @submit.prevent="update">
<div v-for="e in options.editor_data.form.el" class="col-span-6 sm:col-span-4 mb-4">
<InputLabel :for="e.id" :value="e.label"/>
<TextInput
v-if="e.type === 'text'"
:id="e.id"
:ref="e.ref"
type="text"
:autocomplete="e.autocomplete"
class="mt-1 block w-full"
v-model="formUpdate[e.bind]"
/>
<select
v-else-if="e.type === 'select'"
class="block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm"
:id="e.id"
:ref="e.ref"
v-model="formUpdate[e.bind]"
>
<option v-for="op in e.selectOptions" :value="op.val">{{ op.desc }}</option>
</select>
</div>
<div class="flex justify-end mt-4">
<ActionMessage :on="formUpdate.recentlySuccessful" class="me-3">
Saved.
</ActionMessage>
<PrimaryButton :class="{ 'opacity-25': formUpdate.processing }" :disabled="formUpdate.processing">
Save
</PrimaryButton>
</div>
</form>
</template>
</Drawer>
<Modal
v-if="editor"
:show="modalRemove"
@close="closeModal"
maxWidth="sm"
>
<form @submit.prevent="remove">
<div class="p-3">
<div class="text-lg text-center py-2 mb-4">
Remove {{ options.editor_data.title }} <b>{{ modalRemoveTitle }}</b>?
</div>
<div class="flex justify-between">
<SecondaryButton type="button" @click="closeModal">
Cancel
</SecondaryButton>
<ActionMessage :on="formRemove.recentlySuccessful" class="me-3">
Deleted.
</ActionMessage>
<PrimaryButton class="bg-red-700" :class="{ 'opacity-25': formRemove.processing }" :disabled="formRemove.processing">
Delete
</PrimaryButton>
</div>
</div>
</form>
</Modal>
</template>