Added Modals for Adding, Editing, Showing
This commit is contained in:
@@ -7,12 +7,20 @@ const props = defineProps({
|
||||
required: true,
|
||||
type: String
|
||||
},
|
||||
createQuery: {
|
||||
type: Object
|
||||
},
|
||||
item: {
|
||||
required: true,
|
||||
type: Object
|
||||
},
|
||||
inModal: {
|
||||
type: Boolean,
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(["returnData"])
|
||||
|
||||
|
||||
const {type} = props
|
||||
|
||||
@@ -38,6 +46,7 @@ const route = useRoute()
|
||||
const dataStore = useDataStore()
|
||||
const profileStore = useProfileStore()
|
||||
const supabase = useSupabaseClient()
|
||||
const modal = useModal()
|
||||
|
||||
const dataType = dataStore.dataTypes[type]
|
||||
const openTab = ref(0)
|
||||
@@ -73,17 +82,20 @@ const setupCreate = () => {
|
||||
setupCreate()
|
||||
|
||||
const setupQuery = () => {
|
||||
if(route.query) {
|
||||
Object.keys(route.query).forEach(key => {
|
||||
if(props.mode === "create" && (route.query || props.createQuery)) {
|
||||
|
||||
let data = !props.inModal ? route.query : props.createQuery
|
||||
|
||||
Object.keys(data).forEach(key => {
|
||||
if(dataType.templateColumns.find(i => i.key === key)) {
|
||||
if (["customer", "contract", "plant", "contact", "project"].includes(key)) {
|
||||
item.value[key] = Number(route.query[key])
|
||||
item.value[key] = Number(data[key])
|
||||
} else {
|
||||
item.value[key] = route.query[key]
|
||||
item.value[key] = data[key]
|
||||
}
|
||||
} else if(key === "resources") {
|
||||
/*item.value[key] = route.query[key]*/
|
||||
JSON.parse(route.query[key]).forEach(async (i) => {
|
||||
/*item.value[key] = data[key]*/
|
||||
JSON.parse(data[key]).forEach(async (i) => {
|
||||
console.log(i)
|
||||
let type = i.substring(0,1)
|
||||
let id = i.substring(2,i.length)
|
||||
@@ -180,10 +192,37 @@ const calcSaveAllowed = (item) => {
|
||||
watch(item.value, async (newItem, oldItem) => {
|
||||
calcSaveAllowed(newItem)
|
||||
})
|
||||
|
||||
const createItem = async () => {
|
||||
let ret = null
|
||||
|
||||
if(props.inModal) {
|
||||
ret = await dataStore.createNewItem(type,item.value,true)
|
||||
} else {
|
||||
ret = dataStore.createNewItem(type,item.value)
|
||||
}
|
||||
|
||||
emit('returnData', ret)
|
||||
}
|
||||
|
||||
const updateItem = async () => {
|
||||
let ret = null
|
||||
|
||||
if(props.inModal) {
|
||||
ret = await dataStore.updateItem(type,item.value, oldItem.value,true)
|
||||
} else {
|
||||
ret = await dataStore.updateItem(type,item.value, oldItem.value)
|
||||
}
|
||||
|
||||
emit('returnData', ret)
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar
|
||||
v-if="!props.inModal"
|
||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||
>
|
||||
<template #left>
|
||||
@@ -217,14 +256,14 @@ watch(item.value, async (newItem, oldItem) => {
|
||||
</ButtonWithConfirm>
|
||||
<UButton
|
||||
v-if="item.id"
|
||||
@click="dataStore.updateItem(type,item, oldItem)"
|
||||
@click="updateItem"
|
||||
:disabled="!saveAllowed"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else
|
||||
@click="dataStore.createNewItem(type,item)"
|
||||
@click="createItem"
|
||||
:disabled="!saveAllowed"
|
||||
>
|
||||
Erstellen
|
||||
@@ -238,6 +277,40 @@ watch(item.value, async (newItem, oldItem) => {
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UDashboardNavbar
|
||||
v-else
|
||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||
>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="item"
|
||||
:class="['text-xl','font-medium']"
|
||||
>{{item.id ? `${dataType.labelSingle} bearbeiten` : `${dataType.labelSingle} erstellen` }}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
v-if="item.id"
|
||||
@click="updateItem"
|
||||
:disabled="!saveAllowed"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else
|
||||
@click="createItem"
|
||||
:disabled="!saveAllowed"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="modal.close()"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
icon="i-heroicons-x-mark"
|
||||
variant="outline"
|
||||
/>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UDashboardPanelContent>
|
||||
<UForm
|
||||
class="p-5"
|
||||
|
||||
82
components/EntityModalButtons.vue
Normal file
82
components/EntityModalButtons.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<script setup>
|
||||
import StandardEntityModal from "~/components/StandardEntityModal.vue";
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
},
|
||||
createQuery: {
|
||||
type: Object,
|
||||
},
|
||||
buttonShow: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
buttonEdit: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
buttonCreate: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(["returnData"])
|
||||
|
||||
|
||||
const modal = useModal()
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UButton
|
||||
variant="outline"
|
||||
class="w-25 ml-2"
|
||||
v-if="props.id && props.buttonShow"
|
||||
icon="i-heroicons-eye"
|
||||
@click="modal.open(StandardEntityModal, {
|
||||
id: props.id,
|
||||
type: props.type,
|
||||
mode: 'show',
|
||||
})"
|
||||
/>
|
||||
<UButton
|
||||
variant="outline"
|
||||
class="w-25 ml-2"
|
||||
v-if="props.id && props.buttonEdit"
|
||||
icon="i-heroicons-pencil-solid"
|
||||
@click="modal.open(StandardEntityModal, {
|
||||
id: props.id,
|
||||
type: props.type,
|
||||
mode: 'edit',
|
||||
onReturnData(data) {
|
||||
emit('returnData', data)
|
||||
}
|
||||
})"
|
||||
/>
|
||||
<UButton
|
||||
variant="outline"
|
||||
class="w-25 ml-2"
|
||||
v-if="!props.id && props.buttonCreate"
|
||||
icon="i-heroicons-plus"
|
||||
@click="modal.open(StandardEntityModal, {
|
||||
type: props.type,
|
||||
mode: 'create',
|
||||
createQuery: props.createQuery,
|
||||
onReturnData(data) {
|
||||
emit('returnData', data)
|
||||
}
|
||||
})"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -9,6 +9,9 @@ const props = defineProps({
|
||||
item: {
|
||||
required: true,
|
||||
type: Object
|
||||
},
|
||||
inModal: {
|
||||
type: Boolean,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -37,6 +40,7 @@ const dataStore = useDataStore()
|
||||
const profileStore = useProfileStore()
|
||||
const supabase = useSupabaseClient()
|
||||
const files = useFiles()
|
||||
const modal = useModal()
|
||||
|
||||
const dataType = dataStore.dataTypes[type]
|
||||
|
||||
@@ -168,6 +172,7 @@ const getAvailableQueryStringData = (keys) => {
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar
|
||||
v-if="!props.inModal"
|
||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||
>
|
||||
<template #left>
|
||||
@@ -200,6 +205,26 @@ const getAvailableQueryStringData = (keys) => {
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UDashboardNavbar
|
||||
v-else
|
||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||
>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="item"
|
||||
:class="['text-xl','font-medium']"
|
||||
>{{item ? `${dataType.labelSingle}${props.item[dataType.templateColumns.find(i => i.title).key] ? ': ' + props.item[dataType.templateColumns.find(i => i.title).key] : ''}`: '' }}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
@click="modal.close()"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
icon="i-heroicons-x-mark"
|
||||
variant="outline"
|
||||
/>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
:items="dataType.showTabs"
|
||||
v-if="props.item.id"
|
||||
|
||||
97
components/StandardEntityModal.vue
Normal file
97
components/StandardEntityModal.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<script setup>
|
||||
|
||||
const toast = useToast()
|
||||
const dataStore = useDataStore()
|
||||
const supabase = useSupabaseClient()
|
||||
const modal = useModal()
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "show"
|
||||
},
|
||||
createQuery: {
|
||||
type: Object
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
|
||||
const emit = defineEmits(["updateNeeded","returnData"])
|
||||
|
||||
const dataType = dataStore.dataTypes[props.type]
|
||||
|
||||
const loaded = ref(false)
|
||||
const items = ref([])
|
||||
const item = ref({})
|
||||
|
||||
const setupPage = async () => {
|
||||
if(props.mode === "show") {
|
||||
//Load Data for Show
|
||||
item.value = await useSupabaseSelectSingle(props.type, props.id, dataType.supabaseSelectWithInformation || "*")
|
||||
} else if(props.mode === "edit") {
|
||||
//Load Data for Edit
|
||||
const data = JSON.stringify((await supabase.from(props.type).select().eq("id", props.id).single()).data)
|
||||
//await useSupabaseSelectSingle(type, route.params.id)
|
||||
item.value = data
|
||||
|
||||
} else if(props.mode === "create") {
|
||||
//Load Data for Create
|
||||
item.value = JSON.stringify({})
|
||||
|
||||
} else if(props.mode === "list") {
|
||||
//Load Data for List
|
||||
items.value = await useSupabaseSelect(props.type, dataType.supabaseSelectWithInformation || "*", dataType.supabaseSortColumn,dataType.supabaseSortAscending || false)
|
||||
}
|
||||
|
||||
loaded.value = true
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UModal :fullscreen="props.mode === 'show'">
|
||||
<EntityShow
|
||||
v-if="loaded && props.mode === 'show'"
|
||||
:type="props.type"
|
||||
:item="item"
|
||||
@updateNeeded="setupPage"
|
||||
:key="item"
|
||||
:in-modal="true"
|
||||
/>
|
||||
<EntityEdit
|
||||
v-else-if="loaded && (props.mode === 'edit' || props.mode === 'create')"
|
||||
:type="props.type"
|
||||
:item="item"
|
||||
:inModal="true"
|
||||
@return-data="(data) => emit('return-data',data)"
|
||||
:createQuery="props.createQuery"
|
||||
/>
|
||||
<!-- <EntityList
|
||||
v-else-if="loaded && props.mode === 'list'"
|
||||
:type="props.type"
|
||||
:items="items"
|
||||
/>-->
|
||||
<UProgress
|
||||
v-else
|
||||
animation="carousel"
|
||||
class="p-5 mt-10"
|
||||
/>
|
||||
</UModal>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user