Changed to new Layout System

This commit is contained in:
2024-02-23 19:30:43 +01:00
parent 96d4ee7356
commit 0d86e4c4f9
32 changed files with 1690 additions and 2214 deletions

View File

@@ -520,7 +520,14 @@ const footerLinks = [/*{
</template> </template>
</UDashboardSidebar> </UDashboardSidebar>
</UDashboardPanel> </UDashboardPanel>
<slot />
<UDashboardPage>
<UDashboardPanel grow>
<slot />
</UDashboardPanel>
</UDashboardPage>
<!-- ~/components/HelpSlideover.vue --> <!-- ~/components/HelpSlideover.vue -->
<HelpSlideover /> <HelpSlideover />

View File

@@ -7,6 +7,12 @@ export default defineNuxtConfig({
extends: [ extends: [
'@nuxt/ui-pro' '@nuxt/ui-pro'
], ],
components: [{
path: '~/components'
}, {
path: '~/components/common',
pathPrefix: false
}],
build: { build: {
transpile: ['@vuepic/vue-datepicker'] transpile: ['@vuepic/vue-datepicker']
}, },

View File

@@ -6,13 +6,12 @@ definePageMeta({
}) })
const dataStore = useDataStore() const dataStore = useDataStore()
const supabase = useSupabaseClient()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const toast = useToast() const toast = useToast()
const id = ref(route.params.id ? route.params.id : null ) const id = ref(route.params.id ? route.params.id : null )
let currentItem = null let currentItem = ref(null)
//Working //Working
const mode = ref(route.params.mode || "show") const mode = ref(route.params.mode || "show")
@@ -37,13 +36,10 @@ const absenceReasons = [
//Functions //Functions
const setupPage = () => { const setupPage = () => {
if(mode.value === "show" || mode.value === "edit"){ if(mode.value === "show" || mode.value === "edit"){
currentItem = dataStore.getAbsenceRequestById(Number(useRoute().params.id)) currentItem.value = dataStore.getAbsenceRequestById(Number(useRoute().params.id))
} }
if(mode.value === "edit") itemInfo.value = currentItem if(mode.value === "edit") itemInfo.value = currentItem.value
} }
const editItem = async () => { const editItem = async () => {
@@ -52,175 +48,147 @@ const editItem = async () => {
} }
const cancelEditorCreate = () => { const cancelEditorCreate = () => {
mode.value = "show" if(currentItem.value) {
itemInfo.value = { router.push(`/tasks/show/${currentItem.value.id}`)
id: 0, } else {
infoData: {} router.push(`/tasks/`)
} }
} }
const updateItem = async () => {
const {error} = await supabase
.from("absenceRequests")
.update(itemInfo.value)
.eq('id',itemInfo.value.id)
if(error) {
console.log(error)
}
router.push(`/employees/absenceRequests/show/${currentItem.id}`)
toast.add({title: "Abwesenheit erfolgreich gespeichert"})
dataStore.fetchAbsenceRequests()
}
setupPage() setupPage()
</script> </script>
<template> <template>
<div> <UDashboardNavbar :title="currentItem ? currentItem.name : (mode === 'create' ? 'Abwesenheit erstellen' : 'Abwesenheit bearbeiten')">
<UCard v-if="currentItem && mode == 'show'" > <template #right>
<template #header> <UButton
<UBadge v-if="mode === 'edit'"
v-if="currentItem.approved === 'Offen'" @click="dataStore.updateItem('tasks',itemInfo)"
color="blue"
>{{currentItem.approved}}</UBadge>
<UBadge
v-else-if="currentItem.approved === 'Genehmigt'"
color="primary"
>{{currentItem.approved}}</UBadge>
<UBadge
v-else-if="currentItem.approved === 'Abgelehnt'"
color="rose"
>{{currentItem.approved}}</UBadge>
{{currentItem.reason}}
</template>
<span>Mitarbeiter: {{dataStore.profiles.find(item => item.id === currentItem.user) ? dataStore.profiles.find(item => item.id === currentItem.user).fullName : ""}}<br></span>
<span>Start: {{dayjs(currentItem.start).format("DD.MM.YYYY")}}<br></span>
<span>Ende: {{dayjs(currentItem.end).format("DD.MM.YYYY")}}<br></span>
Notizen:<br>
{{currentItem.note}}<br>
<template #footer>
<UButton
v-if="mode == 'show' && currentItem.id"
@click="editItem"
>
Bearbeiten
</UButton>
</template>
</UCard>
<UCard v-else-if="mode == 'edit' || mode == 'create'" >
<template #header v-if="mode === 'edit'">
{{itemInfo.reason}}
</template>
<UFormGroup
label="Status:"
> >
<USelectMenu Speichern
v-model="itemInfo.approved" </UButton>
:options="states" <UButton
option-attribute="label" v-else-if="mode === 'create'"
value-attribute="value" @click="dataStore.createNewItem('tasks',itemInfo)"
/>
</UFormGroup>
<UFormGroup
label="Grund:"
> >
<USelectMenu Erstellen
v-model="itemInfo.reason" </UButton>
:options="absenceReasons" <UButton
/> @click="cancelEditorCreate"
</UFormGroup> color="red"
class="ml-2"
<UFormGroup v-if="mode === 'edit' || mode === 'create'"
label="Mitarbeiter:"
> >
<USelectMenu Abbrechen
v-model="itemInfo.user" </UButton>
:options="dataStore.profiles" <UButton
option-attribute="fullName" v-if="mode === 'show'"
value-attribute="id" @click="editItem"
searchable
:search-attributes="['fullName']"
>
<template #label>
{{dataStore.profiles.find(item => item.id === itemInfo.user) ? dataStore.profiles.find(item => item.id === itemInfo.user).fullName : "Mitarbeiter auswählen"}}
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup label="Start:">
<UPopover :popper="{ placement: 'bottom-start' }">
<UButton icon="i-heroicons-calendar-days-20-solid" :label="itemInfo.start ? dayjs(itemInfo.start).format('DD.MM.YYYY') : 'Datum auswählen'" />
<template #panel="{ close }">
<LazyDatePicker v-model="itemInfo.start" @close="close" />
</template>
</UPopover>
</UFormGroup>
<UFormGroup label="Ende:">
<UPopover :popper="{ placement: 'bottom-start' }">
<UButton icon="i-heroicons-calendar-days-20-solid" :label="itemInfo.end ? dayjs(itemInfo.end).format('DD.MM.YYYY') : 'Datum auswählen'" />
<template #panel="{ close }">
<LazyDatePicker v-model="itemInfo.end" @close="close" />
</template>
</UPopover>
</UFormGroup>
<UFormGroup
label="Notizen:"
> >
<UTextarea Bearbeiten
v-model="itemInfo.note" </UButton>
/> </template>
</UFormGroup> <template #badge v-if="currentItem">
<UBadge
v-if="currentItem.approved === 'Offen'"
color="blue"
>{{currentItem.approved}}</UBadge>
<UBadge
v-else-if="currentItem.approved === 'Genehmigt'"
color="primary"
>{{currentItem.approved}}</UBadge>
<UBadge
v-else-if="currentItem.approved === 'Abgelehnt'"
color="rose"
>{{currentItem.approved}}</UBadge>
</template>
</UDashboardNavbar>
<UTabs
:items="[{label: 'Informationen'}]"
v-if="currentItem && mode == 'show'"
class="p-5"
>
<template #item="{item}">
<UCard class="mt-5">
<div v-if="item.label === 'Informationen'">
<div class="truncate">
<p>Mitarbeiter: {{dataStore.profiles.find(item => item.id === currentItem.user) ? dataStore.profiles.find(item => item.id === currentItem.user).fullName : ""}}</p>
<p>Start: {{dayjs(currentItem.start).format("DD.MM.YYYY")}}</p>
<p>Ende: {{dayjs(currentItem.end).format("DD.MM.YYYY")}}</p>
<p>Grund: {{currentItem.reason}}</p>
<p>Notizen: {{currentItem.notes}}</p>
</div>
</div>
</UCard>
</template>
</UTabs>
<UForm v-else-if="mode == 'edit' || mode == 'create'" class="p-5" >
<UFormGroup
label="Status:"
>
<USelectMenu
v-model="itemInfo.approved"
:options="states"
option-attribute="label"
value-attribute="value"
/>
</UFormGroup>
<UFormGroup
label="Grund:"
>
<USelectMenu
v-model="itemInfo.reason"
:options="absenceReasons"
/>
</UFormGroup>
<UFormGroup
label="Mitarbeiter:"
>
<USelectMenu
v-model="itemInfo.user"
:options="dataStore.profiles"
option-attribute="fullName"
value-attribute="id"
searchable
:search-attributes="['fullName']"
>
<template #label>
{{dataStore.profiles.find(item => item.id === itemInfo.user) ? dataStore.profiles.find(item => item.id === itemInfo.user).fullName : "Mitarbeiter auswählen"}}
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup label="Start:">
<UPopover :popper="{ placement: 'bottom-start' }">
<UButton icon="i-heroicons-calendar-days-20-solid" :label="itemInfo.start ? dayjs(itemInfo.start).format('DD.MM.YYYY') : 'Datum auswählen'" />
<template #panel="{ close }">
<LazyDatePicker v-model="itemInfo.start" @close="close" />
</template>
</UPopover>
</UFormGroup>
<UFormGroup label="Ende:">
<UPopover :popper="{ placement: 'bottom-start' }">
<UButton icon="i-heroicons-calendar-days-20-solid" :label="itemInfo.end ? dayjs(itemInfo.end).format('DD.MM.YYYY') : 'Datum auswählen'" />
<template #panel="{ close }">
<LazyDatePicker v-model="itemInfo.end" @close="close" />
</template>
</UPopover>
</UFormGroup>
<template #footer> <UFormGroup
<UButton label="Notizen:"
v-if="mode == 'edit'" >
@click="updateItem" <UTextarea
> v-model="itemInfo.note"
Speichern />
</UButton> </UFormGroup>
<UButton
v-else-if="mode == 'create'"
@click="dataStore.createNewItem('absenceRequests', itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
>
Abbrechen
</UButton>
</template>
</UCard> </UForm>
</div>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,37 +1,69 @@
<template> <template>
<div id="main"> <UDashboardNavbar title="Abwesenheiten" :badge="filteredRows.length">
<template #right>
<UInput
id="searchinput"
v-model="searchString"
icon="i-heroicons-funnel"
autocomplete="off"
placeholder="Suche..."
class="hidden lg:block"
@keydown.esc="$event.target.blur()"
>
<template #trailing>
<UKbd value="/" />
</template>
</UInput>
<UButton @click="router.push(`/employees/absenceRequests/create/`)">+ Abwesenheit</UButton> <UButton @click="router.push(`/absenceRequests/create`)">+ Abwesenheit</UButton>
</template>
</UDashboardNavbar>
<UTable <UDashboardToolbar>
:rows="dataStore.absenceRequests" <template #right>
:columns="columns" <USelectMenu
@select="selectItem" v-model="selectedColumns"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }" icon="i-heroicons-adjustments-horizontal-solid"
> :options="templateColumns"
<template #approved-data="{row}"> multiple
class="hidden lg:block"
by="key"
>
<template #label>
Spalten
</template>
</USelectMenu>
</template>
</UDashboardToolbar>
<UTable
:rows="filteredRows"
:columns="columns"
class="w-full"
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
@select="(i) => router.push(`/absenceRequests/show/${i.id}`) "
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Abwesenheiten anzuzeigen' }"
>
<template #approved-data="{row}">
<span v-if="!row.approved"> <span v-if="!row.approved">
Genehmigung offen Genehmigung offen
</span> </span>
<span <span
v-else-if="row.approved" v-else-if="row.approved"
class="text-primary" class="text-primary"
> >
Genemigt Genemigt
</span> </span>
<span <span
v-else v-else
class="text-rose" class="text-rose"
> >
Abgelehnt Abgelehnt
</span> </span>
</template> </template>
<template #user-data="{row}"> <template #user-data="{row}">
{{dataStore.profiles.find(profile => profile.id === row.user) ? dataStore.profiles.find(profile => profile.id === row.user).fullName : ""}} {{dataStore.profiles.find(profile => profile.id === row.user) ? dataStore.profiles.find(profile => profile.id === row.user).fullName : ""}}
</template> </template>
</UTable> </UTable>
</div>
</template> </template>
<script setup> <script setup>
@@ -40,11 +72,21 @@ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
defineShortcuts({
'/': () => {
//console.log(searchinput)
//searchinput.value.focus()
document.getElementById("searchinput").focus()
},
'+': () => {
router.push("/absenceRequests/create")
}
})
const dataStore = useDataStore() const dataStore = useDataStore()
const router = useRouter() const router = useRouter()
const mode = ref("show")
const columns = [ const templateColumns = [
{ {
key: "approved", key: "approved",
label: "Genehmigt", label: "Genehmigt",
@@ -73,10 +115,24 @@ const columns = [
} }
] ]
const selectedColumns = ref(templateColumns)
const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
const searchString = ref('')
const filteredRows = computed(() => {
let items = dataStore.absenceRequests
if(!searchString.value) {
return items
}
return items.filter(item => {
return Object.values(item).some((value) => {
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
})
})
})
const selectItem = (item) => {
router.push(`/employees/absenceRequests/show/${item.id} `)
}
</script> </script>
<style scoped> <style scoped>

View File

@@ -287,28 +287,23 @@ const calendarOptionsTimeline = reactive({
</UModal> </UModal>
<UDashboardPage> <UDashboardNavbar :title="currentItem ? currentItem.name : ''">
<UDashboardPanel grow> <template #right>
<UDashboardNavbar :title="currentItem ? currentItem.name : ''">
<template #right>
</template> </template>
</UDashboardNavbar> </UDashboardNavbar>
<div v-if="mode === 'grid'" class="p-5"> <div v-if="mode === 'grid'" class="p-5">
<FullCalendar <FullCalendar
:options="calendarOptionsGrid" :options="calendarOptionsGrid"
/> />
</div> </div>
<div v-else-if="mode === 'timeline'" class="p-5"> <div v-else-if="mode === 'timeline'" class="p-5">
<FullCalendar <FullCalendar
:options="calendarOptionsTimeline" :options="calendarOptionsTimeline"
/> />
</div> </div>
</UDashboardPanel>
</UDashboardPage>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,22 +1,16 @@
<script setup> <script setup>
import HistoryDisplay from "~/components/HistoryDisplay.vue";
definePageMeta({ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
// const dataStore = useDataStore()
const supabase = useSupabaseClient()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const toast = useToast() const toast = useToast()
const id = ref(route.params.id ? route.params.id : null ) const id = ref(route.params.id ? route.params.id : null )
//Store
const dataStore = useDataStore()
let currentItem = null
let currentItem = ref(null)
//Working //Working
const mode = ref(route.params.mode || "show") const mode = ref(route.params.mode || "show")
@@ -37,14 +31,7 @@ const setupPage = () => {
if(query.customer) itemInfo.value.customer = Number(query.customer) if(query.customer) itemInfo.value.customer = Number(query.customer)
if(query.vendor) itemInfo.value.vendor = Number(query.vendor) if(query.vendor) itemInfo.value.vendor = Number(query.vendor)
} }
}
const editCustomer = async () => {
router.push(`/contacts/edit/${currentItem.id}`)
setupPage()
} }
const cancelEditorCreate = () => { const cancelEditorCreate = () => {
@@ -60,37 +47,58 @@ setupPage()
</script> </script>
<template> <template>
<h1 <UDashboardNavbar :title="currentItem ? currentItem.fullName : (mode === 'create' ? 'Ansprechpartner erstellen' : 'Ansprechpartner bearbeiten')">
class="mb-3 font-bold text-2xl truncate" <template #right>
v-if="currentItem" <UButton
>Ansprechpartner: {{currentItem.fullName}}</h1> v-if="mode === 'edit'"
@click="dataStore.updateItem('contacts',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode === 'create'"
@click="dataStore.createNewItem('contacts',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
v-if="mode === 'edit' || mode === 'create'"
>
Abbrechen
</UButton>
<UButton
v-if="mode === 'show'"
@click="router.push(`/contacts/edit/${currentItem.id}`)"
>
Bearbeiten
</UButton>
</template>
<template #badge v-if="currentItem">
<UBadge
v-if="currentItem.active"
>
Kontakt aktiv
</UBadge>
<UBadge
v-else
color="red"
>
Kontakt inaktiv
</UBadge>
</template>
</UDashboardNavbar>
<UTabs <UTabs
:items="[{label: 'Informationen'}, {label: 'Logbuch'}]" :items="[{label: 'Informationen'}, {label: 'Logbuch'}]"
v-if="currentItem && mode == 'show'" v-if="currentItem && mode == 'show'"
class="p-5"
> >
<template #item="{item}"> <template #item="{item}">
<UCard class="mt-5"> <UCard class="mt-5">
<div v-if="item.label === 'Informationen'"> <div v-if="item.label === 'Informationen'">
<Toolbar>
<UButton
v-if="mode == 'show' && currentItem.id"
@click="editCustomer"
>
Bearbeiten
</UButton>
</Toolbar>
<UBadge
v-if="currentItem.active"
>
Kontakt aktiv
</UBadge>
<UBadge
v-else
color="red"
>
Kontakt inaktiv
</UBadge>
<div class="text-wrap mt-3"> <div class="text-wrap mt-3">
<p v-if="currentItem.customer">Kunde: <nuxt-link :to="`/customers/show/${currentItem.customer}`">{{dataStore.customers.find(customer => customer.id === currentItem.customer) ? dataStore.customers.find(customer => customer.id === currentItem.customer).name : "" }}</nuxt-link></p> <p v-if="currentItem.customer">Kunde: <nuxt-link :to="`/customers/show/${currentItem.customer}`">{{dataStore.customers.find(customer => customer.id === currentItem.customer) ? dataStore.customers.find(customer => customer.id === currentItem.customer).name : "" }}</nuxt-link></p>
@@ -115,11 +123,10 @@ setupPage()
</UCard> </UCard>
</template> </template>
</UTabs> </UTabs>
<UCard v-else-if="mode == 'edit' || mode == 'create'" > <UForm
<template #header> v-else-if="mode == 'edit' || mode == 'create'"
{{itemInfo.fullName}} class="p-5"
</template> >
<UFormGroup <UFormGroup
label="Anrede:" label="Anrede:"
> >
@@ -211,31 +218,7 @@ setupPage()
v-model="itemInfo.role" v-model="itemInfo.role"
/> />
</UFormGroup> </UFormGroup>
</UForm>
<template #footer>
<UButton
v-if="mode == 'edit'"
@click="dataStore.updateItem('contacts',{...itemInfo, fullName: `${itemInfo.firstName} ${itemInfo.lastName}`})"
>
Speichern
</UButton>
<UButton
v-else-if="mode == 'create'"
@click="dataStore.createNewItem('contacts',{...itemInfo, fullName: `${itemInfo.firstName} ${itemInfo.lastName}`})"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
>
Abbrechen
</UButton>
</template>
</UCard>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,54 +1,60 @@
<template> <template>
<Toolbar> <UDashboardNavbar title="Ansprechpartner" :badge="filteredRows.length">
<UButton @click="router.push(`/contacts/create/`)">+ Kontakt</UButton> <template #right>
<UInput
id="searchinput"
v-model="searchString"
icon="i-heroicons-funnel"
autocomplete="off"
placeholder="Suche..."
class="hidden lg:block"
@keydown.esc="$event.target.blur()"
>
<template #trailing>
<UKbd value="/" />
</template>
</UInput>
<UInput <UButton @click="router.push(`/contacts/create`)">+ Kontakt</UButton>
v-model="searchString" </template>
placeholder="Suche..." </UDashboardNavbar>
/>
<USelectMenu <UDashboardToolbar>
v-model="selectedColumns" <template #right>
multiple <USelectMenu
:options="columnTemplate" v-model="selectedColumns"
:uiMenu="{width:'w-40'}" icon="i-heroicons-adjustments-horizontal-solid"
:popper="{placement: 'bottom-start'}" :options="templateColumns"
by="key" multiple
> class="hidden lg:block"
<UButton by="key"
color="gray" >
variant="ghost" <template #label>
class="flex-1 justify-between" Spalten
icon="i-heroicons-view-columns" </template>
/> </USelectMenu>
</template>
<template #option="{ option }"> </UDashboardToolbar>
{{option.label}}
</template>
</USelectMenu>
</Toolbar>
<div class="table">
<UTable
:rows="filteredRows"
:columns="selectedColumns"
@select="selectItem"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }"
>
<template #active-data="{row}">
<span v-if="row.active" class="text-primary-500">Aktiv</span>
<span v-else class="text-rose">Gesperrt</span>
</template>
<template #customer-data="{row}">
{{dataStore.customers.find(customer => customer.id === row.customer) ? dataStore.customers.find(customer => customer.id === row.customer).name : ''}}
</template>
<template #vendor-data="{row}">
{{dataStore.vendors.find(vendor => vendor.id === row.vendor) ? dataStore.vendors.find(vendor => vendor.id === row.vendor).name : ''}}
</template>
</UTable>
</div>
<UTable
:rows="filteredRows"
:columns="columns"
class="w-full"
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
@select="(i) => router.push(`/contacts/show/${i.id}`)"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Ansprechpartner anzuzeigen' }"
>
<template #active-data="{row}">
<span v-if="row.active" class="text-primary-500">Aktiv</span>
<span v-else class="text-rose">Gesperrt</span>
</template>
<template #customer-data="{row}">
{{dataStore.customers.find(customer => customer.id === row.customer) ? dataStore.customers.find(customer => customer.id === row.customer).name : ''}}
</template>
<template #vendor-data="{row}">
{{dataStore.vendors.find(vendor => vendor.id === row.vendor) ? dataStore.vendors.find(vendor => vendor.id === row.vendor).name : ''}}
</template>
</UTable>
</template> </template>
<script setup> <script setup>
@@ -57,11 +63,21 @@ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
defineShortcuts({
'/': () => {
//console.log(searchinput)
//searchinput.value.focus()
document.getElementById("searchinput").focus()
},
'+': () => {
router.push("/contacts/create")
}
})
const dataStore = useDataStore() const dataStore = useDataStore()
const router = useRouter() const router = useRouter()
const mode = ref("show")
const columnTemplate = ref([ const templateColumns = [
{ {
key: "fullName", key: "fullName",
@@ -102,30 +118,9 @@ const columnTemplate = ref([
key: "birtday", key: "birtday",
label: "Geburtstag", label: "Geburtstag",
} }
]) ]
const selectedColumns = ref([ const selectedColumns = ref(templateColumns)
{ const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
key: "fullName",
label: "Name",
sortable: true
},
{
key: "customer",
label: "Kunde",
sortable: true
},
{
key: "vendor",
label: "Lieferant",
sortable: true
},
])
const selectItem = (item) => {
router.push(`/contacts/show/${item.id} `)
}
const searchString = ref('') const searchString = ref('')

View File

@@ -6,19 +6,13 @@ definePageMeta({
}) })
const dataStore = useDataStore() const dataStore = useDataStore()
const supabase = useSupabaseClient()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const toast = useToast() const toast = useToast()
const id = ref(route.params.id ? route.params.id : null ) const id = ref(route.params.id ? route.params.id : null )
//Store
const {customers, contracts } = storeToRefs(useDataStore())
let currentItem = ref(null) let currentItem = ref(null)
//Working //Working
const mode = ref(route.params.mode || "show") const mode = ref(route.params.mode || "show")
const itemInfo = ref({ const itemInfo = ref({
@@ -39,14 +33,7 @@ const setupPage = () => {
let query = route.query let query = route.query
if(query.customer) itemInfo.value.customer = Number(query.customer) if(query.customer) itemInfo.value.customer = Number(query.customer)
} }
}
const editCustomer = async () => {
router.push(`/contracts/edit/${currentItem.value.id}`)
setupPage()
} }
const cancelEditorCreate = () => { const cancelEditorCreate = () => {
@@ -61,13 +48,40 @@ setupPage()
</script> </script>
<template> <template>
<h1 <UDashboardNavbar :title="currentItem ? currentItem.name : (mode === 'create' ? 'Vertrag erstellen' : 'Vertrag bearbeiten')">
class="mb-3 truncate font-bold text-2xl" <template #right>
v-if="currentItem" <UButton
>Vertrag: {{currentItem.name}}</h1> v-if="mode === 'edit'"
@click="dataStore.updateItem('contracts',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode === 'create'"
@click="dataStore.createNewItem('contracts',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
v-if="mode === 'edit' || mode === 'create'"
>
Abbrechen
</UButton>
<UButton
v-if="mode === 'show'"
@click="router.push(`/contracts/edit/${currentItem.id}`)"
>
Bearbeiten
</UButton>
</template>
</UDashboardNavbar>
<UTabs <UTabs
v-if="currentItem && mode === 'show'" v-if="currentItem && mode === 'show'"
:items="[{label: 'Informationen'}, {label: 'Logbuch'}, {label: 'Dokumente'}]" :items="[{label: 'Informationen'}, {label: 'Logbuch'}, {label: 'Dokumente'}]"
class="p-5"
> >
<template #item="{item}"> <template #item="{item}">
<UCard class="mt-5"> <UCard class="mt-5">
@@ -125,7 +139,7 @@ setupPage()
</UCard> </UCard>
</template> </template>
</UTabs> </UTabs>
<UCard v-else-if="mode == 'edit' || mode == 'create'" > <UForm v-else-if="mode == 'edit' || mode == 'create'" class="p-5" >
<UFormGroup <UFormGroup
label="Name:" label="Name:"
@@ -142,7 +156,7 @@ setupPage()
v-model="itemInfo.customer" v-model="itemInfo.customer"
option-attribute="name" option-attribute="name"
value-attribute="id" value-attribute="id"
:options="customers" :options="dataStore.customers"
searchable searchable
:search-attributes="['name']" :search-attributes="['name']"
> >
@@ -166,31 +180,7 @@ setupPage()
v-model="itemInfo.description" v-model="itemInfo.description"
/> />
</UFormGroup> </UFormGroup>
</UForm>
<template #footer>
<UButton
v-if="mode === 'edit'"
@click="dataStore.updateItem('contracts',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode === 'create'"
@click="dataStore.createNewItem('contracts',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
>
Abbrechen
</UButton>
</template>
</UCard>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,43 +1,75 @@
<template> <template>
<div id="main"> <UDashboardNavbar title="Verträge" :badge="filteredRows.length">
<!-- TODO: Kontakte erstellen und dem Kunden zuweisen --> <template #right>
<div class="flex items-center gap-1">
<UButton @click="router.push(`/contracts/create/`)">+ Vertrag</UButton>
<UInput <UInput
id="searchinput"
v-model="searchString" v-model="searchString"
icon="i-heroicons-funnel"
autocomplete="off"
placeholder="Suche..." placeholder="Suche..."
/> class="hidden lg:block"
</div> @keydown.esc="$event.target.blur()"
>
<template #trailing>
<UKbd value="/" />
</template>
</UInput>
<UButton @click="router.push(`/contracts/create`)">+ Vertrag</UButton>
</template>
</UDashboardNavbar>
<UDashboardToolbar>
<template #right>
<USelectMenu
v-model="selectedColumns"
icon="i-heroicons-adjustments-horizontal-solid"
:options="templateColumns"
multiple
class="hidden lg:block"
by="key"
>
<template #label>
Spalten
</template>
</USelectMenu>
</template>
</UDashboardToolbar>
<UTable <UTable
:rows="filteredRows" :rows="filteredRows"
:columns="itemColumns" :columns="columns"
@select="selectItem" class="w-full"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }" :ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
> @select="(i) => router.push(`/contracts/show/${i.id}`) "
<template #customer-data="{row}"> :empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Verträge anzuzeigen' }"
{{dataStore.customers.find(customer => customer.id === row.customer) ? dataStore.customers.find(customer => customer.id === row.customer).name : row.customer }} >
</template> <template #customer-data="{row}">
</UTable> {{dataStore.customers.find(customer => customer.id === row.customer) ? dataStore.customers.find(customer => customer.id === row.customer).name : row.customer }}
</template>
</div> </UTable>
</template> </template>
<script setup> <script setup>
definePageMeta({ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
defineShortcuts({
'/': () => {
//console.log(searchinput)
//searchinput.value.focus()
document.getElementById("searchinput").focus()
},
'+': () => {
router.push("/contracts/create")
}
})
const dataStore = useDataStore() const dataStore = useDataStore()
const router = useRouter() const router = useRouter()
const mode = ref("show")
const itemColumns = [ const templateColumns = [
{ {
key: 'customer', key: 'customer',
label: "Kundennr.:", label: "Kundennr.:",
@@ -53,15 +85,11 @@ const itemColumns = [
label: "Beschreibung" label: "Beschreibung"
} }
] ]
const selectedColumns = ref(templateColumns)
const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
const selectItem = (item) => {
router.push(`/contracts/show/${item.id} `)
}
const searchString = ref('') const searchString = ref('')
const filteredRows = computed(() => { const filteredRows = computed(() => {
if(!searchString.value) { if(!searchString.value) {
return dataStore.contracts return dataStore.contracts

View File

@@ -1,17 +1,13 @@
<script setup> <script setup>
import HistoryDisplay from "~/components/HistoryDisplay.vue";
definePageMeta({ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
const supabase = useSupabaseClient() const dataStore = useDataStore()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const toast = useToast() const toast = useToast()
const id = ref(route.params.id ? route.params.id : null ) const id = ref(route.params.id ? route.params.id : null )
const numberRange = useNumberRange("customers")
const dataStore = useDataStore()
let currentItem = ref(null) let currentItem = ref(null)
@@ -34,13 +30,10 @@ const setupPage = async () => {
} }
if(mode.value === "edit") itemInfo.value = currentItem.value if(mode.value === "edit") itemInfo.value = currentItem.value
} }
const editCustomer = async () => { const editItem = async () => {
router.push(`/customers/edit/${currentItem.value.id}`) await router.push(`/customers/edit/${currentItem.value.id}`)
setupPage()
} }
const cancelEditorCreate = () => { const cancelEditorCreate = () => {
@@ -56,37 +49,59 @@ setupPage()
</script> </script>
<template> <template>
<h1 <UDashboardNavbar :title="currentItem ? currentItem.name : (mode === 'create' ? 'Kunde erstellen' : 'Kunde bearbeiten')">
class="mb-3 font-bold text-3xl truncate" <template #right>
v-if="currentItem " <UButton
>Kunde: {{currentItem.name}}</h1> v-if="mode === 'edit'"
@click="dataStore.updateItem('customers',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode === 'create'"
@click="dataStore.createNewItem('customers',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
v-if="mode === 'edit' || mode === 'create'"
>
Abbrechen
</UButton>
<UButton
v-if="mode === 'show'"
@click="editItem"
>
Bearbeiten
</UButton>
</template>
<template #badge v-if="currentItem">
<UBadge
v-if="currentItem.active"
>
Kunde aktiv
</UBadge>
<UBadge
v-else
color="red"
>
Kunde gesperrt
</UBadge>
</template>
</UDashboardNavbar>
<UTabs <UTabs
v-if="currentItem && mode == 'show'" v-if="currentItem && mode == 'show'"
:items="[{label: 'Informationen'}, {label: 'Logbuch'}, {label: 'Projekte'},{label: 'Objekte'},{label: 'Verträge'}, {label: 'Ansprechpartner'}]" :items="[{label: 'Informationen'}, {label: 'Logbuch'}, {label: 'Projekte'},{label: 'Objekte'},{label: 'Verträge'}, {label: 'Ansprechpartner'}]"
class="p-5"
> >
<template #item="{item}"> <template #item="{item}">
<UCard class="mt-5"> <UCard class="mt-5">
<div v-if="item.label === 'Informationen'"> <div v-if="item.label === 'Informationen'">
<Toolbar>
<UButton
v-if="mode == 'show' && currentItem.id"
@click="editCustomer"
>
Bearbeiten
</UButton>
</Toolbar>
<UBadge
v-if="currentItem.active"
>
Kunde aktiv
</UBadge>
<UBadge
v-else
color="red"
>
Kunde gesperrt
</UBadge>
<div class="text-wrap"> <div class="text-wrap">
<p>Kundennummer: {{currentItem.customerNumber}}</p> <p>Kundennummer: {{currentItem.customerNumber}}</p>
@@ -164,16 +179,16 @@ setupPage()
<div v-else-if="item.label === 'Ansprechpartner'"> <div v-else-if="item.label === 'Ansprechpartner'">
<Toolbar> <Toolbar>
<UButton <UButton
@click="router.push(`/contacts/create?customer=${currentItem.id}`)" @click="router.push(`/contacts/create?customer=${currentItem.id}`)"
> >
+ Ansprechpartner + Ansprechpartner
</UButton> </UButton>
</Toolbar> </Toolbar>
<UTable <UTable
:rows="dataStore.getContactsByCustomerId(currentItem.id)" :rows="dataStore.getContactsByCustomerId(currentItem.id)"
@select="(row) => router.push(`/contacts/show/${row.id}`)" @select="(row) => router.push(`/contacts/show/${row.id}`)"
:columns="[{label: 'Anrede', key: 'salutation'},{label: 'Name', key: 'fullName'},{label: 'Rolle', key: 'role'}]" :columns="[{label: 'Anrede', key: 'salutation'},{label: 'Name', key: 'fullName'},{label: 'Rolle', key: 'role'}]"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Ansprechpartner' }" :empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Ansprechpartner' }"
> >
@@ -183,12 +198,7 @@ setupPage()
</UCard> </UCard>
</template> </template>
</UTabs> </UTabs>
<UForm v-else-if="mode === 'edit' || mode === 'create'" class="p-5">
<UCard v-else-if="mode === 'edit' || mode === 'create'" >
<template #header v-if="mode === 'edit'">
<UBadge>{{itemInfo.customerNumber}}</UBadge>{{itemInfo.name}}
</template>
<UFormGroup <UFormGroup
label="Name:" label="Name:"
> >
@@ -288,36 +298,11 @@ setupPage()
v-model="itemInfo.infoData.ustid" v-model="itemInfo.infoData.ustid"
/> />
</UFormGroup> </UFormGroup>
</UForm>
<template #footer>
<UButton
v-if="mode == 'edit'"
@click="dataStore.updateItem('customers', itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode == 'create'"
@click="dataStore.createNewItem('customers',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
>
Abbrechen
</UButton>
</template>
</UCard>
</template> </template>
<style scoped> <style scoped>
td {
padding: 0.2em;
}
</style> </style>

View File

@@ -1,64 +1,80 @@
<template> <template>
<UDashboardNavbar title="Kunden" :badge="filteredRows.length">
<template #right>
<UInput
ref="searchinput"
v-model="searchString"
icon="i-heroicons-funnel"
autocomplete="off"
placeholder="Suche..."
class="hidden lg:block"
@keydown.esc="$event.target.blur()"
>
<template #trailing>
<UKbd value="/" />
</template>
</UInput>
<Toolbar> <UButton @click="router.push(`/customers/create/`)">+ Kunde</UButton>
<UButton @click="router.push(`/customers/create/`)">+ Kunde</UButton>
<UInput </template>
v-model="searchString" </UDashboardNavbar>
placeholder="Suche..."
/>
<USelectMenu <UDashboardToolbar>
v-model="selectedColumns" <template #right>
multiple <USelectMenu
:options="columnTemplate" v-model="selectedColumns"
:uiMenu="{width:'w-40'}" icon="i-heroicons-adjustments-horizontal-solid"
:popper="{placement: 'bottom-start'}" :options="templateColumns"
by="key" multiple
> class="hidden lg:block"
<UButton by="key"
color="gray" >
variant="ghost" <template #label>
class="flex-1 justify-between" Spalten
icon="i-heroicons-view-columns" </template>
/> </USelectMenu>
</template>
</UDashboardToolbar>
<template #option="{ option }"> <UTable
{{option.label}} :rows="filteredRows"
</template> :columns="columns"
</USelectMenu> class="w-full"
</Toolbar> :ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
@select="(i) => router.push(`/customers/show/${i.id}`) "
<div class="table"> :empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Kunden anzuzeigen' }"
<UTable >
:rows="filteredRows" <template #active-data="{row}">
:columns="selectedColumns" <span v-if="row.active" class="text-primary-500">Aktiv</span>
@select="selectItem" <span v-else class="text-rose-500">Gesperrt</span>
</template>
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }" <template #address-data="{row}">
> {{row.infoData.street ? `${row.infoData.street}, ` : ''}}{{row.infoData.special ? `${row.infoData.special},` : ''}} {{(row.infoData.zip || row.infoData.city) ? `${row.infoData.zip} ${row.infoData.city}, ` : ''}} {{row.infoData.country}}
<template #active-data="{row}"> </template>
<span v-if="row.active" class="text-primary-500">Aktiv</span> </UTable>
<span v-else class="text-rose">Gesperrt</span>
</template>
<template #address-data="{row}">
{{row.infoData.street}}, {{row.infoData.special ? `${row.infoData.special},` : ''}} {{row.infoData.zip}} {{row.infoData.city}}, {{row.infoData.country}}
</template>
</UTable>
</div>
</template> </template>
<script setup> <script setup>
definePageMeta({ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
defineShortcuts({
'/': () => {
//console.log(searchinput)
//searchinput.value.focus()
document.getElementById("searchinput").focus()
},
'+': () => {
router.push("/customers/create")
}
})
const dataStore = useDataStore() const dataStore = useDataStore()
const router = useRouter() const router = useRouter()
const mode = ref("show")
const columnTemplate = ref([ const templateColumns = [
{ {
key: 'customerNumber', key: 'customerNumber',
label: "Kundennr.", label: "Kundennr.",
@@ -84,26 +100,9 @@ const columnTemplate = ref([
label: "Adresse", label: "Adresse",
sortable: true sortable: true
} }
]) ]
const selectedColumns = ref([ const selectedColumns = ref(templateColumns)
{ const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
key: 'customerNumber',
label: "Kundennr.",
sortable: true
},
{
key: "name",
label: "Name",
sortable: true
},
])
const selectItem = (customer) => {
console.log(customer)
router.push(`/customers/show/${customer.id} `)
}
const searchString = ref('') const searchString = ref('')

View File

@@ -110,14 +110,20 @@ const downloadSelected = async () => {
</script> </script>
<template> <template>
<div> <UDashboardNavbar
<Toolbar> title="Dokumente"
>
</UDashboardNavbar>
<UDashboardToolbar>
<template #left>
<UButton @click="uploadModalOpen = true">Hochladen</UButton> <UButton @click="uploadModalOpen = true">Hochladen</UButton>
<UButton <UButton
@click="downloadSelected" @click="downloadSelected"
:disabled="dataStore.documents.filter(doc => doc.selected).length === 0" :disabled="dataStore.documents.filter(doc => doc.selected).length === 0"
>Herunterladen</UButton> >Herunterladen</UButton>
</template>
<template #right>
<USelectMenu <USelectMenu
:options="tags" :options="tags"
v-model="selectedTags" v-model="selectedTags"
@@ -127,63 +133,63 @@ const downloadSelected = async () => {
{{selectedTags}} {{selectedTags}}
</template> </template>
</USelectMenu> </USelectMenu>
</template>
</UDashboardToolbar>
</Toolbar> <div class="scrollList">
<div class="scrollList">
<USlideover
v-model="uploadModalOpen"
>
<UCard class="flex flex-col flex-1" :ui="{ body: { base: 'flex-1' }, ring: '', divide: 'divide-y divide-gray-100 dark:divide-gray-800' }"> <DocumentList
<template #header> :documents="filteredDocuments"
Datei Hochladen />
</template> </div>
<USlideover
v-model="uploadModalOpen"
>
<div class="h-full"> <UCard class="flex flex-col flex-1" :ui="{ body: { base: 'flex-1' }, ring: '', divide: 'divide-y divide-gray-100 dark:divide-gray-800' }">
<UFormGroup <template #header>
label="Datei:" Datei Hochladen
> </template>
<UInput
type="file"
id="fileUploadInput"
multiple
/>
</UFormGroup>
<UFormGroup <div class="h-full">
label="Tags:" <UFormGroup
class="mt-3" label="Datei:"
> >
<USelectMenu <UInput
multiple type="file"
searchable id="fileUploadInput"
searchable-placeholder="Suchen..." multiple
:options="tags" />
v-model="fileUploadFormData.tags" </UFormGroup>
/>
</UFormGroup>
</div>
<template #footer> <UFormGroup
<UButton label="Tags:"
v-if="!uploadInProgress" class="mt-3"
class="mt-3" >
@click="uploadFiles" <USelectMenu
>Hochladen</UButton> multiple
<UProgress searchable
searchable-placeholder="Suchen..."
:options="tags"
v-model="fileUploadFormData.tags"
/>
</UFormGroup>
</div>
<template #footer>
<UButton
v-if="!uploadInProgress"
class="mt-3"
@click="uploadFiles"
>Hochladen</UButton>
<UProgress
v-else v-else
animation="carousel" animation="carousel"
/> />
</template> </template>
</UCard> </UCard>
</USlideover> </USlideover>
<DocumentList
:documents="filteredDocuments"
/>
</div>
</div>
</template> </template>

View File

@@ -6,7 +6,6 @@ definePageMeta({
}) })
const dataStore = useDataStore() const dataStore = useDataStore()
const supabase = useSupabaseClient()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const toast = useToast() const toast = useToast()
@@ -28,13 +27,6 @@ const setupPage = () => {
} }
if(mode.value === "edit") itemInfo.value = currentItem.value if(mode.value === "edit") itemInfo.value = currentItem.value
}
const editItem = async () => {
router.push(`/inventoryitems/edit/${currentItem.value.id}`)
setupPage()
} }
const cancelEditorCreate = () => { const cancelEditorCreate = () => {
@@ -43,34 +35,50 @@ const cancelEditorCreate = () => {
} else { } else {
router.push(`/inventoryitems`) router.push(`/inventoryitems`)
} }
} }
setupPage() setupPage()
</script> </script>
<template> <template>
<h1 <UDashboardNavbar :title="currentItem ? currentItem.name : (mode === 'create' ? 'Inventartikel erstellen' : 'Inventartikel bearbeiten')">
class="text-center my-3 font-bold text-2xl" <template #right>
v-if="currentItem " <UButton
>{{currentItem.name}}</h1> v-if="mode === 'edit'"
@click="dataStore.updateItem('inventoryitems',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode === 'create'"
@click="dataStore.createNewItem('inventoryitems',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
v-if="mode === 'edit' || mode === 'create'"
>
Abbrechen
</UButton>
<UButton
v-if="mode === 'show'"
@click=" router.push(`/inventoryitems/edit/${currentItem.id}`)"
>
Bearbeiten
</UButton>
</template>
</UDashboardNavbar>
<UTabs <UTabs
:items="[{label: 'Informationen'}, {label: 'Logbuch'}]" :items="[{label: 'Informationen'}, {label: 'Logbuch'}]"
v-if="currentItem && mode == 'show'" v-if="currentItem && mode == 'show'"
class="p-5"
> >
<template #item="{item}"> <template #item="{item}">
<UCard class="mt-5"> <UCard class="mt-5">
<div v-if="item.label === 'Informationen'"> <div v-if="item.label === 'Informationen'">
<Toolbar>
<UButton
v-if="mode === 'show' && currentItem.id"
@click="editItem"
>
Bearbeiten
</UButton>
</Toolbar>
<div class="text-wrap"> <div class="text-wrap">
<p v-if="currentItem.currentSpace">Lagerplatz: {{dataStore.getSpaceById(currentItem.currentSpace).spaceNumber}} - {{dataStore.getSpaceById(currentItem.currentSpace).description}}</p> <p v-if="currentItem.currentSpace">Lagerplatz: {{dataStore.getSpaceById(currentItem.currentSpace).spaceNumber}} - {{dataStore.getSpaceById(currentItem.currentSpace).description}}</p>
@@ -87,11 +95,10 @@ setupPage()
</UCard> </UCard>
</template> </template>
</UTabs> </UTabs>
<UCard v-else-if="mode == 'edit' || mode == 'create'" > <UForm
<template #header v-if="mode === 'edit'"> v-else-if="mode == 'edit' || mode == 'create'"
{{itemInfo.name}} class="p-5"
</template> >
<UFormGroup <UFormGroup
label="Name:" label="Name:"
> >
@@ -123,31 +130,7 @@ setupPage()
v-model="itemInfo.description" v-model="itemInfo.description"
/> />
</UFormGroup> </UFormGroup>
</UForm>
<template #footer>
<UButton
v-if="mode === 'edit'"
@click="dataStore.updateItem('inventoryitems',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode === 'create'"
@click="dataStore.createNewItem('inventoryitems',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
>
Abbrechen
</UButton>
</template>
</UCard>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,29 +1,52 @@
<template> <template>
<div> <UDashboardNavbar title="Inventar" :badge="filteredRows.length">
<template #right>
<div class="flex items-center gap-1">
<UButton @click="router.push(`/inventoryitems/create/`)">+ Inventarartikel</UButton>
<UInput <UInput
id="searchinput"
v-model="searchString" v-model="searchString"
icon="i-heroicons-funnel"
autocomplete="off"
placeholder="Suche..." placeholder="Suche..."
/> class="hidden lg:block"
</div> @keydown.esc="$event.target.blur()"
>
<template #trailing>
<UKbd value="/" />
</template>
</UInput>
<UButton @click="router.push(`/inventoryitems/create`)">+ Inventarartikel</UButton>
</template>
</UDashboardNavbar>
<UDashboardToolbar>
<template #right>
<USelectMenu
v-model="selectedColumns"
icon="i-heroicons-adjustments-horizontal-solid"
:options="templateColumns"
multiple
class="hidden lg:block"
by="key"
>
<template #label>
Spalten
</template>
</USelectMenu>
</template>
</UDashboardToolbar>
<UTable <UTable
:rows="filteredRows" :rows="filteredRows"
@select="selectItem" :columns="columns"
:columns="itemColumns" class="w-full"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }" :ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
> @select="(i) => router.push(`/inventoryitems/show/${i.id}`) "
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Inventarartikel anzuzeigen' }"
>
</UTable> </UTable>
</div>
</template> </template>
<script setup> <script setup>
@@ -31,11 +54,22 @@
definePageMeta({ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
defineShortcuts({
'/': () => {
//console.log(searchinput)
//searchinput.value.focus()
document.getElementById("searchinput").focus()
},
'+': () => {
router.push("/tasks/create")
}
})
const dataStore = useDataStore() const dataStore = useDataStore()
const supabase = useSupabaseClient()
const router = useRouter() const router = useRouter()
const itemColumns = [ const templateColumns = [
{ {
key: "name", key: "name",
label: "Name", label: "Name",
@@ -47,14 +81,11 @@ const itemColumns = [
sortable: true sortable: true
} }
] ]
const selectedColumns = ref(templateColumns)
const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
const selectItem = (item) => {
console.log(item)
router.push(`/inventoryitems/show/${item.id} `)
}
const searchString = ref('') const searchString = ref('')
const filteredRows = computed(() => { const filteredRows = computed(() => {
if(!searchString.value) { if(!searchString.value) {
return dataStore.inventoryitems return dataStore.inventoryitems

View File

@@ -1,262 +0,0 @@
<script setup>
import FullCalendar from "@fullcalendar/vue3"
import resourceTimelinePlugin from '@fullcalendar/resource-timeline'
import deLocale from '@fullcalendar/core/locales/de'
import interactionPlugin from '@fullcalendar/interaction'
import listPlugin from '@fullcalendar/list';
import dayjs from "dayjs";
definePageMeta({
middleware: "auth"
})
const viewport = useViewport()
watch(viewport.breakpoint, (newBreakpoint, oldBreakpoint) => {
console.log('Breakpoint updated:', oldBreakpoint, '->', newBreakpoint)
})
const supabase = useSupabaseClient()
const dataStore = useDataStore()
const resources = dataStore.getResources
const eventTypes = dataStore.getEventTypes
const events = dataStore.getEvents
const openNewEventModal = ref(false)
const showEventModal = ref(false)
const newEventData = ref({
resourceId: "",
resourceType: "",
title: "",
type: "Umsetzung",
start: "",
end: null
})
const selectedEvent = ref({})
const createEvent = async () => {
const {data,error} = await supabase
.from("events")
.insert([newEventData.value])
.select()
if(error) {
console.log(error)
}
console.log("OK")
openNewEventModal.value = false
newEventData.value = {}
dataStore.fetchEvents()
}
const calendarOptionsList = reactive({
locale: deLocale,
plugins: [listPlugin],
initialView: "listWeek",
initialEvents: events,
nowIndicator: true,
height: "80vh"
})
const calendarOptionsTimeline = reactive({
schedulerLicenseKey: "CC-Attribution-NonCommercial-NoDerivatives",
locale: deLocale,
plugins: [resourceTimelinePlugin, interactionPlugin],
initialView: "resourceTimeline3Hours",
headerToolbar: {
left: 'prev,next',
center: 'title',
right: 'resourceTimelineDay,resourceTimeline3Hours,resourceTimelineMonth'
},
initialEvents: events,
selectable: true,
weekNumbers: true,
select: function (info) {
//console.log(info)
newEventData.value.resourceId = info.resource.id
if(info.resource.extendedProps){
newEventData.value.resourceType = info.resource.extendedProps.type
}
newEventData.value.start = info.startStr
newEventData.value.end = info.endStr
openNewEventModal.value = true
},
eventClick: function (info){
selectedEvent.value = info.event
showEventModal.value = true
console.log(info)
},
resourceGroupField: "type",
resources: resources,
nowIndicator:true,
views: {
resourceTimeline3Hours: {
type: 'resourceTimeline',
slotDuration: {hours: 3},
slotMinTime: "06:00:00",
slotMaxTime: "21:00:00",
duration: {days:7},
buttonText: "Woche",
visibleRange: function(currentDate) {
// Generate a new date for manipulating in the next step
var startDate = new Date(currentDate);
var endDate = new Date(currentDate);
// Adjust the start & end dates, respectively
startDate.setDate(startDate.getDate() - startDate.getDay() +1); // One day in the past
endDate.setDate(startDate.getDate() + 5); // Two days into the future
return { start: startDate, end: endDate };
}
}
},
})
</script>
<template>
<UDashboardPage>
<UDashboardPanel grow>
<UDashboardNavbar :title="currentItem ? currentItem.name : ''">
<template #right>
</template>
</UDashboardNavbar>
<div v-if="viewport.isLessThan('tablet')">
<FullCalendar
:options="calendarOptionsList"
/>
</div>
<div v-else>
<FullCalendar
:options="calendarOptionsTimeline"
/>
</div>
</UDashboardPanel>
</UDashboardPage>
<div>
<UModal
v-model="openNewEventModal"
>
<UCard>
<template #header>
Neuen Termin erstellen
</template>
<UFormGroup
label="Resource:"
>
<USelectMenu
v-model="newEventData.resourceId"
:options="resources"
value-attribute="id"
option-attribute="title"
>
<template #label>
<span>{{ resources.find(resource => resource.id === newEventData.resourceId).title }}</span>
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup
label="Titel:"
>
<UInput
v-model="newEventData.title"
/>
</UFormGroup>
<UFormGroup
label="Projekt:"
>
<USelectMenu
v-model="newEventData.project"
:options="dataStore.projects"
option-attribute="name"
value-attribute="id"
searchable
searchable-placeholder="Suche..."
:search-attributes="['name']"
>
<template #label>
{{dataStore.getProjectById(newEventData.project) ? dataStore.getProjectById(newEventData.project).name : "Kein Projekt ausgewählt"}}
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup
label="Typ:"
>
<USelectMenu
v-model="newEventData.type"
:options="eventTypes"
option-attribute="label"
value-attribute="label"
>
</USelectMenu>
</UFormGroup>
<UFormGroup
label="Start:"
>
<UInput
v-model="newEventData.start"
/>
</UFormGroup>
<UFormGroup
label="Ende:"
>
<UInput
v-model="newEventData.end"
/>
</UFormGroup>
<template #footer>
<UButton
@click="createEvent"
>
Erstellen
</UButton>
</template>
</UCard>
</UModal>
<UModal
v-model="showEventModal"
>
<UCard>
<template #header>
{{selectedEvent.title}}
</template>
Start: {{dayjs(selectedEvent.startStr).format("DD.MM.YYYY HH:mm")}}<br>
Ende: {{dayjs(selectedEvent.endStr).format("DD.MM.YYYY HH:mm")}}
<DevOnly>
<UDivider class="my-3"/>
{{selectedEvent}}
</DevOnly>
</UCard>
</UModal>
</div>
</template>
<style scoped>
</style>

View File

@@ -9,7 +9,6 @@ definePageMeta({
}) })
const dataStore = useDataStore() const dataStore = useDataStore()
const supabase = useSupabaseClient()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const toast = useToast() const toast = useToast()
@@ -53,17 +52,7 @@ const setupPage = () => {
if(mode.value === "create") { if(mode.value === "create") {
let query = route.query let query = route.query
if(query.customer) itemInfo.value.customer = Number(query.customer) if(query.customer) itemInfo.value.customer = Number(query.customer)
} }
}
const editItem = async () => {
await router.push(`/plants/edit/${currentItem.value.id}`)
setupPage()
} }
const cancelEditorCreate = () => { const cancelEditorCreate = () => {
@@ -79,171 +68,122 @@ setupPage()
</script> </script>
<template> <template>
<h1 <UDashboardNavbar :title="currentItem ? currentItem.name : (mode === 'create' ? 'Objekt erstellen' : 'Objekt bearbeiten')">
class="mb-3 truncate font-bold text-2xl" <template #right>
v-if="currentItem " <UButton
>Objekt: {{currentItem.name}}</h1> v-if="mode === 'edit'"
<div v-if="currentItem && mode == 'show'"> @click="dataStore.updateItem('plants',itemInfo)"
<UTabs :items="tabItems"> >
<template #item="{item}"> Speichern
<UCard class="mt-5"> </UButton>
<div v-if="item.label === 'Informationen'"> <UButton
<Toolbar> v-else-if="mode === 'create'"
<UButton @click="dataStore.createNewItem('plants',itemInfo)"
v-if="mode == 'show' && currentItem.id" >
@click="editItem" Erstellen
> </UButton>
Bearbeiten <UButton
</UButton> @click="cancelEditorCreate"
</Toolbar> color="red"
class="ml-2"
<div class="text-wrap"> v-if="mode === 'edit' || mode === 'create'"
<p>Kunde: <nuxt-link :to="`/customers/show/${currentItem.customer}`">{{dataStore.getCustomerById(currentItem.customer).name}}</nuxt-link></p> >
</div> Abbrechen
</UButton>
<UButton
v-if="mode === 'show'"
@click="router.push(`/plants/edit/${currentItem.id}`)"
>
Bearbeiten
</UButton>
</template>
</UDashboardNavbar>
<UTabs
:items="tabItems"
v-if="mode === 'show'"
class="p-5"
>
<template #item="{item}">
<UCard class="mt-5">
<div v-if="item.label === 'Informationen'">
<div class="text-wrap">
<p>Kunde: <nuxt-link :to="`/customers/show/${currentItem.customer}`">{{dataStore.getCustomerById(currentItem.customer).name}}</nuxt-link></p>
</div> </div>
<div v-else-if="item.label === 'Logbuch'">
<HistoryDisplay </div>
<div v-else-if="item.label === 'Logbuch'">
<HistoryDisplay
type="plant"
v-if="currentItem"
:element-id="currentItem.id"
/>
</div>
<div v-else-if="item.label === 'Projekte'">
<Toolbar>
<UButton
@click="router.push(`/projects/create?plant=${currentItem.id}`)"
>
+ Projekt
</UButton>
</Toolbar>
<UTable
:rows="dataStore.getProjectsByPlantId(currentItem.id)"
:columns="[{key: 'name', label: 'Name'}]"
@select="(row) => router.push(`/projects/show/${row.id}`)"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Projekte' }"
>
</UTable>
</div>
<div v-else-if="item.label === 'Aufgaben'">
<Toolbar>
<UButton
@click="router.push(`/tasks/create?plant=${currentItem.id}`)"
>
+ Aufgabe
</UButton>
</Toolbar>
<UTable
:rows="dataStore.getTasksByPlantId(currentItem.id)"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Aufgaben' }"
:columns="[{key: 'name', label: 'Name'},{key: 'categore', label: 'Kategorie'}]"
@select="(row) => router.push(`/tasks/show/${row.id}`)"
>
</UTable>
</div>
<div v-else-if="item.label === 'Dokumente'" class="space-y-3">
<Toolbar>
<DocumentUpload
type="plant" type="plant"
v-if="currentItem"
:element-id="currentItem.id" :element-id="currentItem.id"
/> />
</div> </Toolbar>
<div v-else-if="item.label === 'Projekte'">
<Toolbar>
<UButton
@click="router.push(`/projects/create?plant=${currentItem.id}`)"
>
+ Projekt
</UButton>
</Toolbar>
<UTable <DocumentList :documents="dataStore.getDocumentsByPlantId(currentItem.id)"/>
:rows="dataStore.getProjectsByPlantId(currentItem.id)"
:columns="[{key: 'name', label: 'Name'}]"
@select="(row) => router.push(`/projects/show/${row.id}`)"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Projekte' }"
>
</UTable> </div>
<div v-if="item.label === 'Dokumentation'">
</div> <Editor/>
<div v-else-if="item.label === 'Aufgaben'">
<Toolbar>
<UButton
@click="router.push(`/tasks/create?plant=${currentItem.id}`)"
>
+ Aufgabe
</UButton>
</Toolbar>
<UTable
:rows="dataStore.getTasksByPlantId(currentItem.id)"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Aufgaben' }"
:columns="[{key: 'name', label: 'Name'},{key: 'categore', label: 'Kategorie'}]"
@select="(row) => router.push(`/tasks/show/${row.id}`)"
>
</UTable> </div>
</div> </UCard>
<div v-else-if="item.label === 'Dokumente'" class="space-y-3">
<Toolbar>
<DocumentUpload
type="plant"
:element-id="currentItem.id"
/>
</Toolbar>
<!-- <UModal </template>
v-model="uploadModalOpen" </UTabs>
>
<UCard class="p-4">
<template #header> <div v-if="currentItem && mode == 'show'">
Datei hochladen
</template>
<UFormGroup
label="Datei:"
>
<UInput
type="file"
id="fileUploadInput"
/>
</UFormGroup>
&lt;!&ndash; <UFormGroup
label="Name:"
class="mt-3"
>
<UInput
v-model="fileUploadFormData.name"
/>
</UFormGroup>&ndash;&gt;
<UFormGroup
label="Tags:"
class="mt-3"
>
<USelectMenu
multiple
searchable
searchable-placeholder="Suchen..."
:options="tags"
v-model="fileUploadFormData.tags"
/>
</UFormGroup>
&lt;!&ndash;<UFormGroup
label="Ordner:"
class="mt-3"
>
<USelectMenu
:options="folders"
v-model="fileUploadFormData.folder"
value-attribute="label"
/>
</UFormGroup>&ndash;&gt;
<template #footer>
<UButton
class="mt-3"
@click="uploadFiles"
>Hochladen</UButton>
</template>
</UCard>
</UModal>-->
<DocumentList :documents="dataStore.getDocumentsByPlantId(currentItem.id)"/>
</div>
<div v-if="item.label === 'Dokumentation'">
<Editor/>
</div>
</UCard>
</template>
</UTabs>
</div> </div>
<UForm
<!-- <UCard v-if="currentItem && mode == 'show'"> v-else-if="mode === 'edit' || mode === 'create'"
<template #header> class="p-5"
{{currentItem.name}} >
</template>
</UCard>-->
<UCard v-else-if="mode === 'edit' || mode === 'create'">
<template #header v-if="mode === 'edit'">
{{itemInfo.name}}
</template>
<UFormGroup <UFormGroup
label="Name:" label="Name:"
> >
@@ -268,34 +208,7 @@ setupPage()
</template> </template>
</USelectMenu> </USelectMenu>
</UFormGroup> </UFormGroup>
</UForm>
<template #footer>
<UButton
v-if="mode == 'edit'"
@click="dataStore.updateItem('plants',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode == 'create'"
@click="dataStore.createNewItem('plants', itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
>
Abbrechen
</UButton>
</template>
</UCard>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,25 +1,62 @@
<template> <template>
<Toolbar> <UDashboardNavbar title="Objekte" :badge="filteredRows.length">
<UButton @click="router.push(`/plants/create/`)">+ Objekt</UButton> <template #right>
<UInput
id="searchinput"
v-model="searchString"
icon="i-heroicons-funnel"
autocomplete="off"
placeholder="Suche..."
class="hidden lg:block"
@keydown.esc="$event.target.blur()"
>
<template #trailing>
<UKbd value="/" />
</template>
</UInput>
<UInput <UButton @click="router.push(`/plants/create`)">+ Objekt</UButton>
v-model="searchString" </template>
placeholder="Suche..." </UDashboardNavbar>
/>
</Toolbar>
<div class="table"> <UDashboardToolbar>
<UTable <template #left>
:rows="filteredRows"
:columns="columns"
@select="selectItem" <UCheckbox
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }" label="Erledigte Anzeigen"
> v-model="showDone"
<template #customer-data="{row}"> />
{{dataStore.customers.find(customer => customer.id === row.customer) ? dataStore.customers.find(customer => customer.id === row.customer).name : "" }} </template>
</template>
</UTable> <template #right>
</div> <USelectMenu
v-model="selectedColumns"
icon="i-heroicons-adjustments-horizontal-solid"
:options="templateColumns"
multiple
class="hidden lg:block"
by="key"
>
<template #label>
Spalten
</template>
</USelectMenu>
</template>
</UDashboardToolbar>
<UTable
:rows="filteredRows"
:columns="columns"
class="w-full"
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
@select="(i) => router.push(`/plants/show/${i.id}`) "
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Objekte anzuzeigen' }"
>
<template #customer-data="{row}">
{{dataStore.customers.find(customer => customer.id === row.customer) ? dataStore.customers.find(customer => customer.id === row.customer).name : "" }}
</template>
</UTable>
</template> </template>
@@ -29,11 +66,21 @@ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
defineShortcuts({
'/': () => {
//console.log(searchinput)
//searchinput.value.focus()
document.getElementById("searchinput").focus()
},
'+': () => {
router.push("/plants/create")
}
})
const dataStore = useDataStore() const dataStore = useDataStore()
const router = useRouter() const router = useRouter()
const mode = ref("show")
const columns = [ const templateColumns = [
{ {
key: "name", key: "name",
label: "Name", label: "Name",
@@ -44,6 +91,9 @@ const columns = [
sortable: true sortable: true
} }
] ]
const selectedColumns = ref(templateColumns)
const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
const searchString = ref('') const searchString = ref('')

View File

@@ -8,7 +8,6 @@ definePageMeta({
}) })
const dataStore = useDataStore() const dataStore = useDataStore()
const supabase = useSupabaseClient()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const toast = useToast() const toast = useToast()
@@ -16,8 +15,6 @@ const id = ref(route.params.id ? route.params.id : null )
let currentItem = ref(null) let currentItem = ref(null)
//Working //Working
const mode = ref(route.params.mode || "show") const mode = ref(route.params.mode || "show")
const itemInfo = ref({ const itemInfo = ref({
@@ -33,51 +30,60 @@ const setupPage = () => {
if(mode.value === "edit") itemInfo.value = currentItem.value if(mode.value === "edit") itemInfo.value = currentItem.value
}
const editItem = async () => {
router.push(`/products/edit/${currentItem.value.id}`)
setupPage()
} }
const cancelEditorCreate = () => { const cancelEditorCreate = () => {
mode.value = "show" if(currentItem.value) {
itemInfo.value = { router.push(`/products/show/${currentItem.value.id}`)
id: 0, } else {
router.push(`/products/`)
} }
} }
setupPage() setupPage()
</script> </script>
<template> <template>
<h1 <UDashboardNavbar :title="currentItem ? currentItem.name : (mode === 'create' ? 'Artikel erstellen' : 'Artikel bearbeiten')">
class="mb-3 truncate font-bold text-2xl" <template #right>
v-if="currentItem " <UButton
>Artikel: {{currentItem.name}}</h1> v-if="mode === 'edit'"
@click="dataStore.updateItem('products',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode === 'create'"
@click="dataStore.createNewItem('products',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
v-if="mode === 'edit' || mode === 'create'"
>
Abbrechen
</UButton>
<UButton
v-if="mode === 'show'"
@click=" router.push(`/products/edit/${currentItem.id}`)"
>
Bearbeiten
</UButton>
</template>
</UDashboardNavbar>
<UTabs <UTabs
:items="[{label: 'Informationen'},{label: 'Logbuch'},{label: 'Bestand'},{label: 'Dokumente'}]" :items="[{label: 'Informationen'},{label: 'Logbuch'},{label: 'Bestand'},{label: 'Dokumente'}]"
v-if="mode === 'show'" v-if="mode === 'show'"
class="p-5"
> >
<template #item="{item}"> <template #item="{item}">
<UCard class="mt-5"> <UCard class="mt-5">
<div <div
v-if="item.label === 'Informationen'" v-if="item.label === 'Informationen'"
> >
<Toolbar>
<UButton
v-if="mode === 'show' && currentItem.id"
@click="editItem"
>
Bearbeiten
</UButton>
</Toolbar>
<UBadge <UBadge
v-for="tag in currentItem.tags" v-for="tag in currentItem.tags"
class="mr-2" class="mr-2"
@@ -121,11 +127,10 @@ setupPage()
</UCard> </UCard>
</template> </template>
</UTabs> </UTabs>
<UCard v-else-if="mode == 'edit' || mode == 'create'" > <UForm
<template #header v-if="mode === 'edit'"> v-else-if="mode == 'edit' || mode == 'create'"
{{itemInfo.name}} class="p-5"
</template> >
<UFormGroup <UFormGroup
label="Name:" label="Name:"
> >
@@ -161,7 +166,11 @@ setupPage()
v-model="itemInfo.tags" v-model="itemInfo.tags"
:options="dataStore.ownTenant.tags.products" :options="dataStore.ownTenant.tags.products"
multiple multiple
/> >
<template #label>
{{itemInfo.tags.join(", ")}}
</template>
</USelectMenu>
</UFormGroup> </UFormGroup>
<UFormGroup <UFormGroup
label="EAN:" label="EAN:"
@@ -190,31 +199,7 @@ setupPage()
</template> </template>
</UInput> </UInput>
</UFormGroup> </UFormGroup>
</UForm>
<template #footer>
<UButton
v-if="mode == 'edit'"
@click="dataStore.updateItem('products',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode == 'create'"
@click="dataStore.createNewItem('products',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
>
Abbrechen
</UButton>
</template>
</UCard>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,20 +1,50 @@
<template> <template>
<Toolbar> <UDashboardNavbar title="Artikel" :badge="filteredRows.length">
<UButton @click="router.push(`/products/create/`)">+ Artikel</UButton> <template #right>
<UInput
id="searchinput"
v-model="searchString"
icon="i-heroicons-funnel"
autocomplete="off"
placeholder="Suche..."
class="hidden lg:block"
@keydown.esc="$event.target.blur()"
>
<template #trailing>
<UKbd value="/" />
</template>
</UInput>
<UInput <UButton @click="router.push(`/products/create`)">+ Artikel</UButton>
v-model="searchString" </template>
placeholder="Suche..." </UDashboardNavbar>
/>
</Toolbar> <UDashboardToolbar>
<template #right>
<USelectMenu
v-model="selectedColumns"
icon="i-heroicons-adjustments-horizontal-solid"
:options="templateColumns"
multiple
class="hidden lg:block"
by="key"
>
<template #label>
Spalten
</template>
</USelectMenu>
</template>
</UDashboardToolbar>
<div class="table"> <div class="table">
<UTable <UTable
:rows="filteredRows" :rows="filteredRows"
:columns="itemColumns" :columns="columns"
@select="selectItem" class="w-full"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }" :ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
@select="(i) => router.push(`/products/show/${i.id}`) "
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Artikel anzuzeigen' }"
> >
<template #stock-data="{row}"> <template #stock-data="{row}">
{{`${dataStore.getStockByProductId(row.id)} ${(dataStore.units.find(unit => unit.id === row.unit) ? dataStore.units.find(unit => unit.id === row.unit).name : "")}`}} {{`${dataStore.getStockByProductId(row.id)} ${(dataStore.units.find(unit => unit.id === row.unit) ? dataStore.units.find(unit => unit.id === row.unit).name : "")}`}}
@@ -45,11 +75,22 @@
definePageMeta({ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
defineShortcuts({
'/': () => {
//console.log(searchinput)
//searchinput.value.focus()
document.getElementById("searchinput").focus()
},
'+': () => {
router.push("/products/create")
}
})
const dataStore = useDataStore() const dataStore = useDataStore()
const supabase = useSupabaseClient()
const router = useRouter() const router = useRouter()
const itemColumns = [ const templateColumns = [
{ {
key: "stock", key: "stock",
label: "Bestand" label: "Bestand"
@@ -80,11 +121,8 @@ const itemColumns = [
sortable: true sortable: true
} }
] ]
const selectedColumns = ref(templateColumns)
const selectItem = (item) => { const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
console.log(item)
router.push(`/products/show/${item.id} `)
}
const searchString = ref('') const searchString = ref('')

View File

@@ -82,12 +82,6 @@ const itemInfo = ref({
customer: 0, customer: 0,
users: [user.value.id] users: [user.value.id]
}) })
const uploadModalOpen = ref(false)
const fileUploadFormData = ref({
tags: ["Dokument"],
project: null
})
const tags = dataStore.getDocumentTags const tags = dataStore.getDocumentTags
@@ -109,13 +103,6 @@ const setupPage = () => {
itemInfo.value.customer = dataStore.getPlantById(itemInfo.value.plant).customer itemInfo.value.customer = dataStore.getPlantById(itemInfo.value.plant).customer
} }
} }
}
const editItem = async () => {
router.push(`/projects/edit/${currentItem.value.id}`)
setupPage()
} }
const cancelEditorCreate = () => { const cancelEditorCreate = () => {
@@ -126,32 +113,6 @@ const cancelEditorCreate = () => {
} }
} }
const updateItem = async () => {
const {error} = await supabase
.from("projects")
.update(itemInfo.value)
.eq('id',itemInfo.value.id)
if(error) {
console.log(error)
}
router.push(`/projects/show/${currentItem.value.id}`)
toast.add({title: "Projekt erfolgreich gespeichert"})
dataStore.fetchProjects()
}
const uploadFiles = async () => {
//uploadInProgress.value = true;
await dataStore.uploadFiles({...fileUploadFormData.value, project: currentItem.value.id}, document.getElementById("fileUploadInput").files)
uploadModalOpen.value = false;
//uploadInProgress.value = false;
}
const projectHours = () => { const projectHours = () => {
let hours = 0 let hours = 0
dataStore.getTimesByProjectId(currentItem.value.id).forEach(item => { dataStore.getTimesByProjectId(currentItem.value.id).forEach(item => {
@@ -212,21 +173,45 @@ setupPage()
</script> </script>
<template> <template>
<h1 <UDashboardNavbar :title="currentItem ? currentItem.name : (mode === 'create' ? 'Projekt erstellen' : 'Projekt bearbeiten')">
class="mb-3 truncate font-bold text-2xl" <template #right>
v-if="currentItem " <UButton
>Projekt: {{currentItem.name}}</h1> v-if="mode === 'edit'"
<UTabs :items="tabItems" class="w-full" v-if="currentItem && mode == 'show'"> @click="dataStore.updateItem('projects',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode === 'create'"
@click="dataStore.createNewItem('projects',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
v-if="mode === 'edit' || mode === 'create'"
>
Abbrechen
</UButton>
<UButton
v-if="mode === 'show'"
@click="router.push(`/projects/edit/${currentItem.id}`)"
>
Bearbeiten
</UButton>
</template>
</UDashboardNavbar>
<UTabs
:items="tabItems"
v-if="currentItem && mode == 'show'"
class="p-5"
>
<template #item="{ item }"> <template #item="{ item }">
<UCard class="mt-5"> <UCard class="mt-5">
<div v-if="item.key === 'information'"> <div v-if="item.key === 'information'">
<Toolbar>
<UButton
@click="editItem"
>
Bearbeiten
</UButton>
</Toolbar>
<div class="text-wrap"> <div class="text-wrap">
@@ -391,11 +376,7 @@ setupPage()
</UTabs> </UTabs>
<UCard v-else-if="mode === 'edit' || mode === 'create'" > <UForm v-else-if="mode === 'edit' || mode === 'create'" class="p-5" >
<template #header v-if="mode === 'edit'">
{{itemInfo.name}}
</template>
<UFormGroup <UFormGroup
label="Name:" label="Name:"
> >
@@ -477,32 +458,7 @@ setupPage()
v-model="itemInfo.notes" v-model="itemInfo.notes"
/> />
</UFormGroup> </UFormGroup>
</UForm>
<template #footer>
<UButton
v-if="mode == 'edit'"
@click="dataStore.updateItem('projects',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode == 'create'"
@click="dataStore.createNewItem('projects',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
>
Abbrechen
</UButton>
</template>
</UCard>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,53 +1,97 @@
<template> <template>
<InputGroup > <UDashboardNavbar title="Projekte" :badge="filteredRows.length">
<UButton @click="router.push(`/projects/create/`)">+ Projekt</UButton> <template #right>
<UInput
id="searchinput"
v-model="searchString"
icon="i-heroicons-funnel"
autocomplete="off"
placeholder="Suche..."
class="hidden lg:block"
@keydown.esc="$event.target.blur()"
>
<template #trailing>
<UKbd value="/" />
</template>
</UInput>
<UInput <UButton @click="router.push(`/projects/create`)">+ Projekt</UButton>
v-model="searchString" </template>
placeholder="Suche..." </UDashboardNavbar>
/>
<UCheckbox <UDashboardToolbar>
label="Abgeschlossene anzeigen" <template #left>
v-model="showFinished"
/>
</InputGroup>
<div class="table"> <UCheckbox
<UTable label="Abgeschlossene anzeigen"
:rows="filteredRows" v-model="showFinished"
@select="selectItem" />
:columns="itemColumns" </template>
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }"
> <template #right>
<template #phase-data="{row}"> <USelectMenu
{{getActivePhaseLabel(row)}} v-model="selectedColumns"
</template> icon="i-heroicons-adjustments-horizontal-solid"
<template #customer-data="{row}"> :options="templateColumns"
{{dataStore.getCustomerById(row.customer) ? dataStore.getCustomerById(row.customer).name : ""}} multiple
</template> class="hidden lg:block"
<template #plant-data="{row}"> by="key"
{{dataStore.getPlantById(row.plant) ? dataStore.getPlantById(row.plant).name : ""}} >
</template> <template #label>
<template #users-data="{row}"> Spalten
{{row.users.map(i => dataStore.getProfileById(i).fullName).join(", ")}} </template>
</template> </USelectMenu>
</UTable> </template>
</div> </UDashboardToolbar>
<UTable
:rows="filteredRows"
:columns="columns"
class="w-full"
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
@select="(i) => router.push(`/projects/show/${i.id}`) "
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Projekte anzuzeigen' }"
>
<template #phase-data="{row}">
{{getActivePhaseLabel(row)}}
</template>
<template #customer-data="{row}">
{{dataStore.getCustomerById(row.customer) ? dataStore.getCustomerById(row.customer).name : ""}}
</template>
<template #plant-data="{row}">
{{dataStore.getPlantById(row.plant) ? dataStore.getPlantById(row.plant).name : ""}}
</template>
<template #users-data="{row}">
{{row.users.map(i => dataStore.getProfileById(i).fullName).join(", ")}}
</template>
</UTable>
</template> </template>
<script setup> <script setup>
definePageMeta({ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
defineShortcuts({
'/': () => {
//console.log(searchinput)
//searchinput.value.focus()
document.getElementById("searchinput").focus()
},
'+': () => {
router.push("/projects/create")
}
})
const dataStore = useDataStore() const dataStore = useDataStore()
const supabase = useSupabaseClient()
const router = useRouter() const router = useRouter()
const itemColumns = [ const templateColumns = [
{ {
key: "phase", key: "phase",
label: "Phase" label: "Phase"
@@ -80,11 +124,9 @@ const itemColumns = [
sortable: true sortable: true
} }
] ]
const selectedColumns = ref(templateColumns)
const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
const selectItem = (item) => {
console.log(item)
router.push(`/projects/show/${item.id} `)
}
const getActivePhaseLabel = (item) => { const getActivePhaseLabel = (item) => {
if(item.phases) { if(item.phases) {
@@ -125,18 +167,10 @@ const filteredRows = computed(() => {
return items return items
} }
return items.filter(project => { return items.filter(project => {
return Object.values(project).some((value) => { return Object.values(project).some((value) => {
return String(value).toLowerCase().includes(searchString.value.toLowerCase()) return String(value).toLowerCase().includes(searchString.value.toLowerCase())
}) })
}) })
}) })
</script>
</script>
<style scoped>
</style>

View File

@@ -1,14 +1,9 @@
<script setup> <script setup>
import HistoryDisplay from "~/components/HistoryDisplay.vue";
import DocumentList from "~/components/DocumentList.vue";
import DocumentUpload from "~/components/DocumentUpload.vue";
definePageMeta({ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
const dataStore = useDataStore() const dataStore = useDataStore()
const supabase = useSupabaseClient()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const toast = useToast() const toast = useToast()
@@ -16,8 +11,6 @@ const id = ref(route.params.id ? route.params.id : null )
let currentItem = ref(null) let currentItem = ref(null)
//Working //Working
const mode = ref(route.params.mode || "show") const mode = ref(route.params.mode || "show")
const itemInfo = ref({ const itemInfo = ref({
@@ -32,21 +25,13 @@ const setupPage = () => {
} }
if(mode.value === "edit") itemInfo.value = currentItem.value if(mode.value === "edit") itemInfo.value = currentItem.value
}
const editItem = async () => {
router.push(`/services/edit/${currentItem.value.id}`)
setupPage()
} }
const cancelEditorCreate = () => { const cancelEditorCreate = () => {
mode.value = "show" if(currentItem.value) {
itemInfo.value = { router.push(`/services/show/${currentItem.value.id}`)
id: 0, } else {
router.push(`/services/`)
} }
} }
@@ -56,13 +41,40 @@ setupPage()
</script> </script>
<template> <template>
<h1 <UDashboardNavbar :title="currentItem ? currentItem.name : (mode === 'create' ? 'Leistung erstellen' : 'Leistung bearbeiten')">
class="mb-3 truncate font-bold text-2xl" <template #right>
v-if="currentItem " <UButton
>Leistung: {{currentItem.name}}</h1> v-if="mode === 'edit'"
@click="dataStore.updateItem('services',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode === 'create'"
@click="dataStore.createNewItem('services',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
v-if="mode === 'edit' || mode === 'create'"
>
Abbrechen
</UButton>
<UButton
v-if="mode === 'show'"
@click="router.push(`/services/edit/${currentItem.id}`)"
>
Bearbeiten
</UButton>
</template>
</UDashboardNavbar>
<UTabs <UTabs
:items="[{label: 'Informationen'},{label: 'Logbuch'},{label: 'Dokumente'}]" :items="[{label: 'Informationen'},{label: 'Logbuch'},{label: 'Dokumente'}]"
v-if="mode === 'show'" v-if="mode === 'show'"
class="p-5"
> >
<template #item="{item}"> <template #item="{item}">
<UCard class="mt-5"> <UCard class="mt-5">
@@ -86,7 +98,7 @@ setupPage()
<UDivider <UDivider
class="my-2" class="my-2"
/>--> />-->
<span v-if="currentItem.sellingPrice">Verkaufspreis: {{Number(currentItem.sellingPrice).toFixed(2)}} <br></span> <span v-if="currentItem.sellingPrice">Verkaufspreis: {{String(Number(currentItem.sellingPrice).toFixed(2)).replace(".",",")}} <br></span>
</div> </div>
<div <div
@@ -120,11 +132,10 @@ setupPage()
</UCard> </UCard>
</template> </template>
</UTabs> </UTabs>
<UCard v-else-if="mode == 'edit' || mode == 'create'" > <UForm
<template #header v-if="mode === 'edit'"> v-else-if="mode == 'edit' || mode == 'create'"
{{itemInfo.name}} class="p-5"
</template> >
<UFormGroup <UFormGroup
label="Name:" label="Name:"
> >
@@ -179,31 +190,7 @@ setupPage()
</template> </template>
</UInput> </UInput>
</UFormGroup> </UFormGroup>
</UForm>
<template #footer>
<UButton
v-if="mode == 'edit'"
@click="dataStore.updateItem('products',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode == 'create'"
@click="dataStore.createNewItem('products',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
>
Abbrechen
</UButton>
</template>
</UCard>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,34 +1,54 @@
<template> <template>
<Toolbar> <UDashboardNavbar title="Leistungen" :badge="filteredRows.length">
<UButton @click="router.push(`/services/create/`)">+ Leistung</UButton> <template #right>
<UInput
id="searchinput"
v-model="searchString"
icon="i-heroicons-funnel"
autocomplete="off"
placeholder="Suche..."
class="hidden lg:block"
@keydown.esc="$event.target.blur()"
>
<template #trailing>
<UKbd value="/" />
</template>
</UInput>
<UInput <UButton @click="router.push(`/services/create`)">+ Leistung</UButton>
v-model="searchString" </template>
placeholder="Suche..." </UDashboardNavbar>
/>
</Toolbar> <UDashboardToolbar>
<template #right>
<USelectMenu
v-model="selectedColumns"
icon="i-heroicons-adjustments-horizontal-solid"
:options="templateColumns"
multiple
class="hidden lg:block"
by="key"
>
<template #label>
Spalten
</template>
</USelectMenu>
</template>
</UDashboardToolbar>
<div class="table"> <div class="table">
<UTable <UTable
:rows="filteredRows" :rows="filteredRows"
:columns="itemColumns" :columns="columns"
@select="selectItem" class="w-full"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }" :ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
@select="(i) => router.push(`/services/show/${i.id}`) "
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Leistungen anzuzeigen' }"
> >
<template #sellingPrice-data="{row}"> <template #sellingPrice-data="{row}">
{{row.sellingPrice ? Number(row.sellingPrice).toFixed(2) + " €" : ""}} {{row.sellingPrice ? Number(row.sellingPrice).toFixed(2) + " €" : ""}}
</template> </template>
<!-- <template #tags-data="{row}">
<UBadge
v-if="row.tags.length > 0"
v-for="tag in row.tags"
class="mr-2"
>
{{tag}}
</UBadge>
<span v-else>-</span>
</template>-->
<template #unit-data="{row}"> <template #unit-data="{row}">
{{dataStore.units.find(unit => unit.id === row.unit) ? dataStore.units.find(unit => unit.id === row.unit).name : row.unit}} {{dataStore.units.find(unit => unit.id === row.unit) ? dataStore.units.find(unit => unit.id === row.unit).name : row.unit}}
</template> </template>
@@ -38,15 +58,26 @@
</template> </template>
<script setup> <script setup>
definePageMeta({ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
defineShortcuts({
'/': () => {
//console.log(searchinput)
//searchinput.value.focus()
document.getElementById("searchinput").focus()
},
'+': () => {
router.push("/services/create")
}
})
const dataStore = useDataStore() const dataStore = useDataStore()
const supabase = useSupabaseClient() const supabase = useSupabaseClient()
const router = useRouter() const router = useRouter()
const itemColumns = [ const templateColumns = [
{ {
key: "name", key: "name",
label: "Name", label: "Name",
@@ -68,11 +99,8 @@ const itemColumns = [
sortable: true sortable: true
}*/ }*/
] ]
const selectedColumns = ref(templateColumns)
const selectItem = (item) => { const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
console.log(item)
router.push(`/services/show/${item.id} `)
}
const searchString = ref('') const searchString = ref('')
@@ -87,8 +115,6 @@ const filteredRows = computed(() => {
}) })
}) })
}) })
</script> </script>
<style scoped> <style scoped>

View File

@@ -6,17 +6,12 @@ definePageMeta({
}) })
const dataStore = useDataStore() const dataStore = useDataStore()
const supabase = useSupabaseClient()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const toast = useToast() const toast = useToast()
const id = ref(route.params.id ? route.params.id : null ) const id = ref(route.params.id ? route.params.id : null )
const numberRange = useNumberRange("spaces")
let currentItem = ref(null) let currentItem = ref(null)
let currentNumberRange = null
//Working //Working
const mode = ref(route.params.mode || "show") const mode = ref(route.params.mode || "show")
@@ -38,35 +33,16 @@ const setupPage = async () => {
spaceMovements.value.forEach(movement => { spaceMovements.value.forEach(movement => {
if(spaceProducts.value.filter(product => product.id === movement.productId).length === 0) spaceProducts.value.push(dataStore.getProductById(movement.productId)) if(spaceProducts.value.filter(product => product.id === movement.productId).length === 0) spaceProducts.value.push(dataStore.getProductById(movement.productId))
}) })
} }
if(mode.value === "edit") itemInfo.value = currentItem.value if(mode.value === "edit") itemInfo.value = currentItem.value
}
const editItem = async () => {
router.push(`/inventory/spaces/edit/${currentItem.value.id}`)
setupPage()
} }
const cancelEditorCreate = () => { const cancelEditorCreate = () => {
router.push(`/inventory/spaces/`) if(currentItem.value) {
} router.push(`/spaces/show/${currentItem.value.id}`)
const updateItem = async () => {
const {error} = await supabase
.from("spaces")
.update(itemInfo.value)
.eq('id',itemInfo.value.id)
if(error) {
console.log(error)
} else { } else {
mode.value = "show" router.push(`/spaces/`)
itemInfo.value = {}
toast.add({title: "Lagerplatz erfolgreich gespeichert"})
dataStore.fetchSpaces()
} }
} }
@@ -76,13 +52,9 @@ function getSpaceProductCount(productId) {
productMovements.forEach(movement => count += movement.quantity) productMovements.forEach(movement => count += movement.quantity)
return count return count
} }
const printSpaceLabel = async () => { const printSpaceLabel = async () => {
axios axios
.post(`http://${dataStore.ownTenant.value.labelPrinterIp}/pstprnt`, `^XA^FO10,20^BCN,100^FD${currentItem.value.spaceNumber}^XZ` ) .post(`http://${dataStore.ownTenant.value.labelPrinterIp}/pstprnt`, `^XA^FO10,20^BCN,100^FD${currentItem.value.spaceNumber}^XZ` )
.then(console.log) .then(console.log)
@@ -94,33 +66,44 @@ setupPage()
</script> </script>
<template> <template>
<h1 <UDashboardNavbar :title="currentItem ? currentItem.name : (mode === 'create' ? 'Lagerplatz erstellen' : 'Lagerplatz bearbeiten')">
class="mb-3 truncate font-bold text-2xl" <template #right>
v-if="currentItem " <UButton
>Lagerplatz: {{currentItem.spaceNumber}}</h1> v-if="mode === 'edit'"
@click="dataStore.updateItem('spaces',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode === 'create'"
@click="dataStore.createNewItem('spaces',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
v-if="mode === 'edit' || mode === 'create'"
>
Abbrechen
</UButton>
<UButton
v-if="mode === 'show'"
@click=" router.push(`/inventory/spaces/edit/${currentItem.id}`)"
>
Bearbeiten
</UButton>
</template>
</UDashboardNavbar>
<UTabs <UTabs
:items="[{label: 'Informationen'},{label: 'Logbuch'},{label: 'Bestand'}]" :items="[{label: 'Informationen'},{label: 'Logbuch'},{label: 'Bestand'}]"
v-if="currentItem && mode == 'show'" v-if="currentItem && mode == 'show'"
class="p-5"
> >
<template #item="{item}"> <template #item="{item}">
<UCard class="mt-5"> <UCard class="mt-5">
<div v-if="item.label === 'Informationen'"> <div v-if="item.label === 'Informationen'">
<Toolbar>
<UButton
v-if="mode == 'show' && currentItem.id"
@click="editItem"
>
Bearbeiten
</UButton>
<UButton
v-if="mode == 'show' && currentItem.id"
@click="printSpaceLabel"
class="ml-2"
>
Label Drucken
</UButton>
</Toolbar>
<div class="truncate"> <div class="truncate">
<span>Beschreibung: {{currentItem.description}}</span> <span>Beschreibung: {{currentItem.description}}</span>
</div> </div>
@@ -153,11 +136,10 @@ setupPage()
</UCard> </UCard>
</template> </template>
</UTabs> </UTabs>
<UCard v-else-if="mode === 'edit' || mode === 'create'" > <UForm
<template #header v-if="mode === 'edit'"> v-else-if="mode === 'edit' || mode === 'create'"
<UBadge>{{itemInfo.spaceNumber}}</UBadge>{{itemInfo.type}} class="p-5"
</template> >
<UFormGroup <UFormGroup
label="Typ:" label="Typ:"
> >
@@ -175,31 +157,7 @@ setupPage()
v-model="itemInfo.description" v-model="itemInfo.description"
/> />
</UFormGroup> </UFormGroup>
</UForm>
<template #footer>
<UButton
v-if="mode == 'edit'"
@click="dataStore.updateItem('spaces',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode == 'create'"
@click="dataStore.createNewItem('spaces',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
>
Abbrechen
</UButton>
</template>
</UCard>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,20 +1,50 @@
<template> <template>
<Toolbar> <UDashboardNavbar title="Lagerplätze" :badge="filteredRows.length">
<UButton @click="router.push(`/inventory/spaces/create/`)">+ Lagerplatz</UButton> <template #right>
<UInput
id="searchinput"
v-model="searchString"
icon="i-heroicons-funnel"
autocomplete="off"
placeholder="Suche..."
class="hidden lg:block"
@keydown.esc="$event.target.blur()"
>
<template #trailing>
<UKbd value="/" />
</template>
</UInput>
<UInput <UButton @click="router.push(`/spaces/create`)">+ Lagerplatz</UButton>
v-model="searchString" </template>
placeholder="Suche..." </UDashboardNavbar>
/>
</Toolbar> <UDashboardToolbar>
<template #right>
<USelectMenu
v-model="selectedColumns"
icon="i-heroicons-adjustments-horizontal-solid"
:options="templateColumns"
multiple
class="hidden lg:block"
by="key"
>
<template #label>
Spalten
</template>
</USelectMenu>
</template>
</UDashboardToolbar>
<div class="table"> <div class="table">
<UTable <UTable
:rows="filteredRows" :rows="filteredRows"
:columns="itemColumns" :columns="columns"
@select="selectItem" class="w-full"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }" :ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
@select="(i) => router.push(`/spaces/show/${i.id}`) "
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Lagerplätze anzuzeigen' }"
/> />
</div> </div>
@@ -26,11 +56,21 @@ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
defineShortcuts({
'/': () => {
//console.log(searchinput)
//searchinput.value.focus()
document.getElementById("searchinput").focus()
},
'+': () => {
router.push("/spaces/create")
}
})
const dataStore = useDataStore() const dataStore = useDataStore()
const router = useRouter() const router = useRouter()
const mode = ref("show")
const itemColumns = [ const templateColumns = [
{ {
key: 'spaceNumber', key: 'spaceNumber',
label: "Lagerplatznr.", label: "Lagerplatznr.",
@@ -47,16 +87,10 @@ const itemColumns = [
sortable: true sortable: true
} }
] ]
const selectedColumns = ref(templateColumns)
const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
const selectItem = (item) => {
console.log(item)
router.push(`/spaces/show/${item.id} `)
}
const searchString = ref('') const searchString = ref('')
const filteredRows = computed(() => { const filteredRows = computed(() => {
if(!searchString.value) { if(!searchString.value) {
return dataStore.spaces return dataStore.spaces

View File

@@ -1,12 +1,9 @@
<script setup> <script setup>
import dayjs from "dayjs";
definePageMeta({ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
const dataStore = useDataStore() const dataStore = useDataStore()
const supabase = useSupabaseClient()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const toast = useToast() const toast = useToast()
@@ -14,12 +11,6 @@ const id = ref(route.params.id ? route.params.id : null )
let currentItem = ref(null) let currentItem = ref(null)
/*watch(dataStore.tasks, (oldVal,newVal) => {
console.log("OK")
console.log(dataStore.tasks)
currentItem.value = dataStore.getTaskById(Number(useRoute().params.id))
})*/
//Working //Working
const mode = ref(route.params.mode || "show") const mode = ref(route.params.mode || "show")
const itemInfo = ref({}) const itemInfo = ref({})
@@ -44,7 +35,6 @@ const setupPage = () => {
const editItem = async () => { const editItem = async () => {
router.push(`/tasks/edit/${currentItem.value.id}`) router.push(`/tasks/edit/${currentItem.value.id}`)
setupPage()
} }
const cancelEditorCreate = () => { const cancelEditorCreate = () => {
@@ -55,223 +45,50 @@ const cancelEditorCreate = () => {
} }
} }
const updateItem = async () => {
const {error} = await supabase
.from("tasks")
.update(itemInfo.value)
.eq('id',itemInfo.value.id)
if(error) {
console.log(error)
}
router.push(`/tasks/show/${currentItem.value.id}`)
toast.add({title: "Aufgabe erfolgreich gespeichert"})
dataStore.fetchTasks()
}
setupPage() setupPage()
</script> </script>
<template> <template>
<UDashboardPage> <UDashboardNavbar :title="currentItem ? currentItem.name : (mode === 'create' ? 'Aufgabe erstellen' : 'Aufgabe bearbeiten')">
<UDashboardPanel grow> <template #right>
<UDashboardNavbar :title="currentItem ? currentItem.name : ''"> <UButton
<template #right> v-if="mode === 'edit'"
<UButton @click="dataStore.updateItem('tasks',itemInfo)"
v-if="mode === 'edit'"
@click="dataStore.updateItem('tasks',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode === 'create'"
@click="dataStore.createNewItem('tasks',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
v-if="mode === 'edit' || mode === 'create'"
>
Abbrechen
</UButton>
<UButton
v-if="mode === 'show' && currentItem.id"
@click="editItem"
>
Bearbeiten
</UButton>
</template>
</UDashboardNavbar>
<!-- <UDashboardToolbar>
<template #left>
&lt;!&ndash; <UButton @click="router.push(`/tasks/create`)">+ Aufgabe</UButton>
<UInput
v-model="searchString"
placeholder="Suche..."
/>&ndash;&gt;
<UCheckbox
label="Erledigte Anzeigen"
v-model="showDone"
/>
</template>
<template #right>
<USelectMenu
v-model="selectedColumns"
icon="i-heroicons-adjustments-horizontal-solid"
:options="templateColumns"
multiple
class="hidden lg:block"
>
<template #label>
Spalten
</template>
</USelectMenu>
</template>
</UDashboardToolbar>-->
<UTabs
:items="[{label: 'Informationen'},{label: 'Logbuch'}]"
v-if="currentItem && mode === 'show'"
class="p-5"
> >
<template #item="{item}"> Speichern
<UCard class="mt-5"> </UButton>
<div v-if="item.label === 'Informationen'"> <UButton
v-else-if="mode === 'create'"
@click="dataStore.createNewItem('tasks',itemInfo)"
<div class="truncate"> >
<p>Kategorie: {{currentItem.categorie}}</p> Erstellen
<p v-if="currentItem.project">Projekt: <nuxt-link :to="`/projects/show/${currentItem.project}`">{{dataStore.getProjectById(currentItem.project).name}}</nuxt-link></p> </UButton>
<p>Beschreibung: {{currentItem.description}}</p> <UButton
</div> @click="cancelEditorCreate"
color="red"
</div> class="ml-2"
<!-- TODO: Logbuch Tasks --> v-if="mode === 'edit' || mode === 'create'"
</UCard> >
</template> Abbrechen
</UTabs> </UButton>
<UButton
<UForm v-else-if="mode === 'edit' || mode === 'create' " class="p-5"> v-if="mode === 'show'"
<UFormGroup @click="editItem"
label="Name:" >
> Bearbeiten
<UInput </UButton>
v-model="itemInfo.name" </template>
/> </UDashboardNavbar>
</UFormGroup>
<UFormGroup
label="Kategorie:"
>
<USelectMenu
v-model="itemInfo.categorie"
:options="categories"
/>
</UFormGroup>
<UFormGroup
label="Benutzer:"
>
<USelectMenu
v-model="itemInfo.user"
:options="dataStore.profiles"
option-attribute="fullName"
value-attribute="id"
searchable-placeholder="Suche..."
searchable
:search-attributes="['fullName']"
>
<template #label>
{{dataStore.getProfileById(itemInfo.user) ? dataStore.getProfileById(itemInfo.user).fullName : "Kein Benutzer ausgewählt"}}
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup
label="Projekt:"
>
<USelectMenu
v-model="itemInfo.project"
:options="dataStore.projects"
option-attribute="name"
value-attribute="id"
searchable-placeholder="Suche..."
searchable
:search-attributes="['name']"
>
<template #label>
{{dataStore.getProjectById(itemInfo.project) ? dataStore.getProjectById(itemInfo.project).name : "Kein Projekt ausgewählt"}}
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup
label="Objekt:"
>
<USelectMenu
v-model="itemInfo.plant"
:options="dataStore.plants"
option-attribute="name"
value-attribute="id"
searchable-placeholder="Suche..."
searchable
:search-attributes="['name']"
>
<template #label>
{{dataStore.getPlantById(itemInfo.plant) ? dataStore.getPlantById(itemInfo.plant).name : "Kein Objekt ausgewählt"}}
</template>
</USelectMenu>
</UFormGroup>
<UFormGroup
label="Beschreibung:"
>
<UTextarea
v-model="itemInfo.description"
/>
</UFormGroup>
</UForm>
</UDashboardPanel>
</UDashboardPage>
<!-- <h1
class="mb-3 truncate font-bold text-2xl"
v-if="currentItem"
>Aufgabe: {{currentItem.name}}</h1>
<UTabs <UTabs
:items="[{label: 'Informationen'},{label: 'Logbuch'}]" :items="[{label: 'Informationen'},{label: 'Logbuch'}]"
v-if="currentItem && mode === 'show'" v-if="currentItem && mode === 'show'"
class="p-5"
> >
<template #item="{item}"> <template #item="{item}">
<UCard class="mt-5"> <UCard class="mt-5">
<div v-if="item.label === 'Informationen'"> <div v-if="item.label === 'Informationen'">
<Toolbar>
<UButton
v-if="mode === 'show' && currentItem.id"
@click="editItem"
>
Bearbeiten
</UButton>
<UButton
v-if="currentItem.project"
@click="router.push(`/projects/show/${currentItem.project}`)"
>
Zum Projekt
</UButton>
</Toolbar>
<div class="truncate"> <div class="truncate">
<p>Kategorie: {{currentItem.categorie}}</p> <p>Kategorie: {{currentItem.categorie}}</p>
@@ -280,15 +97,12 @@ setupPage()
</div> </div>
</div> </div>
&lt;!&ndash; TODO: Logbuch Tasks &ndash;&gt; <!-- TODO: Logbuch Tasks -->
</UCard> </UCard>
</template> </template>
</UTabs> </UTabs>
<UCard v-else-if="mode === 'edit' || mode === 'create'" >
<template #header v-if="mode === 'edit'">
{{itemInfo.name}}
</template>
<UForm v-else-if="mode === 'edit' || mode === 'create' " class="p-5">
<UFormGroup <UFormGroup
label="Name:" label="Name:"
> >
@@ -358,9 +172,6 @@ setupPage()
</USelectMenu> </USelectMenu>
</UFormGroup> </UFormGroup>
<UFormGroup <UFormGroup
label="Beschreibung:" label="Beschreibung:"
> >
@@ -368,31 +179,7 @@ setupPage()
v-model="itemInfo.description" v-model="itemInfo.description"
/> />
</UFormGroup> </UFormGroup>
</UForm>
<template #footer>
<UButton
v-if="mode === 'edit'"
@click="dataStore.updateItem('tasks',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode === 'create'"
@click="dataStore.createNewItem('tasks',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
>
Abbrechen
</UButton>
</template>
</UCard>-->
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,108 +1,98 @@
<template> <template>
<UDashboardPage> <UDashboardNavbar title="Aufgaben" :badge="filteredRows.length">
<UDashboardPanel grow> <template #right>
<UDashboardNavbar title="Aufgaben" :badge="filteredRows.length"> <UInput
<template #right> id="searchinput"
<UInput v-model="searchString"
ref="input" icon="i-heroicons-funnel"
v-model="searchString" autocomplete="off"
icon="i-heroicons-funnel" placeholder="Suche..."
autocomplete="off" class="hidden lg:block"
placeholder="Suche..." @keydown.esc="$event.target.blur()"
class="hidden lg:block"
@keydown.esc="$event.target.blur()"
>
<template #trailing>
<UKbd value="/" />
</template>
</UInput>
<UButton @click="router.push(`/tasks/create`)">+ Aufgabe</UButton>
</template>
</UDashboardNavbar>
<UDashboardToolbar>
<template #left>
<!-- <UButton @click="router.push(`/tasks/create`)">+ Aufgabe</UButton>
<UInput
v-model="searchString"
placeholder="Suche..."
/>-->
<UCheckbox
label="Erledigte Anzeigen"
v-model="showDone"
/>
</template>
<template #right>
<USelectMenu
v-model="selectedColumns"
icon="i-heroicons-adjustments-horizontal-solid"
:options="templateColumns"
multiple
class="hidden lg:block"
>
<template #label>
Spalten
</template>
</USelectMenu>
</template>
</UDashboardToolbar>
<UTable
v-model:sort="sort"
:rows="filteredRows"
:columns="columns"
sort-mode="manual"
class="w-full"
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
@select="(i) => router.push(`/tasks/show/${i.id}`) "
> >
<template #finish-data="{row}"> <template #trailing>
<UButton <UKbd value="/" />
icon="i-heroicons-check"
variant="ghost"
@click="markAsFinished(row)"
/>
</template> </template>
<template #created_at-data="{row}"> </UInput>
{{row.created_at ? dayjs(row.created_at).format("DD.MM.YY HH:mm") : ''}}
<UButton @click="router.push(`/tasks/create`)">+ Aufgabe</UButton>
</template>
</UDashboardNavbar>
<UDashboardToolbar>
<template #left>
<UCheckbox
label="Erledigte Anzeigen"
v-model="showDone"
/>
</template>
<template #right>
<USelectMenu
v-model="selectedColumns"
icon="i-heroicons-adjustments-horizontal-solid"
:options="templateColumns"
multiple
class="hidden lg:block"
by="key"
>
<template #label>
Spalten
</template> </template>
<template #user-data="{row}"> </USelectMenu>
{{dataStore.profiles.find(i => i.id === row.user) ? dataStore.profiles.find(i => i.id === row.user).fullName : ""}} </template>
</template> </UDashboardToolbar>
<template #project-data="{row}">
{{dataStore.projects.find(i => i.id === row.project) ? dataStore.projects.find(i => i.id === row.project).name : ""}} <UTable
</template> :rows="filteredRows"
<template #customer-data="{row}"> :columns="columns"
{{dataStore.customers.find(customer => customer.id === row.customer) ? dataStore.customers.find(customer => customer.id === row.customer).name : "" }} class="w-full"
</template> :ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
<template #plant-data="{row}"> @select="(i) => router.push(`/tasks/show/${i.id}`) "
{{dataStore.getPlantById(row.plant) ? dataStore.getPlantById(row.plant).name : "" }} :empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Aufgaben anzuzeigen' }"
</template> >
</UTable> <template #finish-data="{row}">
</UDashboardPanel> <UButton
</UDashboardPage> icon="i-heroicons-check"
variant="ghost"
@click="markAsFinished(row)"
/>
</template>
<template #created_at-data="{row}">
{{row.created_at ? dayjs(row.created_at).format("DD.MM.YY HH:mm") : ''}}
</template>
<template #user-data="{row}">
{{dataStore.profiles.find(i => i.id === row.user) ? dataStore.profiles.find(i => i.id === row.user).fullName : ""}}
</template>
<template #project-data="{row}">
{{dataStore.projects.find(i => i.id === row.project) ? dataStore.projects.find(i => i.id === row.project).name : ""}}
</template>
<template #customer-data="{row}">
{{dataStore.customers.find(customer => customer.id === row.customer) ? dataStore.customers.find(customer => customer.id === row.customer).name : "" }}
</template>
<template #plant-data="{row}">
{{dataStore.getPlantById(row.plant) ? dataStore.getPlantById(row.plant).name : "" }}
</template>
</UTable>
</template> </template>
<script lang="ts" setup> <script setup>
import dayjs from "dayjs"; import dayjs from "dayjs";
definePageMeta({ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
const input = ref<{ input: HTMLInputElement }>()
const dataStore = useDataStore() const dataStore = useDataStore()
const router = useRouter() const router = useRouter()
const mode = ref("show")
defineShortcuts({ defineShortcuts({
'/': () => { '/': () => {
input.value?.input?.focus() //console.log(searchinput)
//searchinput.value.focus()
document.getElementById("searchinput").focus()
}, },
'+': () => { '+': () => {
router.push("/tasks/create") router.push("/tasks/create")
@@ -143,40 +133,30 @@ const templateColumns = [
sortable: true sortable: true
} }
] ]
const selectedColumns = ref(templateColumns) const selectedColumns = ref(templateColumns)
const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column))) const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
const markAsFinished = (item) => {
dataStore.updateItem("tasks", {...item, categorie: "Erledigt"})
}
const searchString = ref('') const searchString = ref('')
const showDone = ref(false) const showDone = ref(false)
const filteredRows = computed(() => { const filteredRows = computed(() => {
let tasks = dataStore.tasks let items = dataStore.tasks
if(!showDone.value) { items = items.filter(i => showDone.value === true ? i.categorie === "Erledigt" : i.categorie !== "Erledigt")
tasks = tasks.filter(i => i.categorie !== "Erledigt")
}
if(!searchString.value) { if(!searchString.value) {
return tasks return items
} }
return tasks.filter(item => { return items.filter(item => {
return Object.values(item).some((value) => { return Object.values(item).some((value) => {
return String(value).toLowerCase().includes(searchString.value.toLowerCase()) return String(value).toLowerCase().includes(searchString.value.toLowerCase())
}) })
}) })
}) })
const selectItem = (item) => {
router.push(`/tasks/show/${item.id} `)
}
const markAsFinished = (item) => {
dataStore.updateItem("tasks", {...item, categorie: "Erledigt"})
}
</script> </script>
<style scoped> <style scoped>

View File

@@ -1,11 +0,0 @@
<script setup lang="ts">
</script>
<template>
test
</template>
<style scoped>
</style>

View File

@@ -6,7 +6,6 @@ definePageMeta({
}) })
const dataStore = useDataStore() const dataStore = useDataStore()
const supabase = useSupabaseClient()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const toast = useToast() const toast = useToast()
@@ -14,8 +13,6 @@ const id = ref(route.params.id ? route.params.id : null )
let currentItem = ref(null) let currentItem = ref(null)
//Working //Working
const mode = ref(route.params.mode || "show") const mode = ref(route.params.mode || "show")
const itemInfo = ref({ const itemInfo = ref({
@@ -65,15 +62,6 @@ const setupPage = () => {
} }
if(mode.value === "edit") itemInfo.value = currentItem.value if(mode.value === "edit") itemInfo.value = currentItem.value
}
const editCustomer = async () => {
router.push(`/vehicles/edit/${currentItem.value.id}`)
setupPage()
} }
const cancelEditorCreate = () => { const cancelEditorCreate = () => {
@@ -85,20 +73,7 @@ const cancelEditorCreate = () => {
} }
const updateItem = async () => {
const {error} = await supabase
.from("vehicles")
.update(itemInfo.value)
.eq('id',itemInfo.value.id)
if(error) {
console.log(error)
} else {
router.push(`/vehicles/show/${currentItem.value.id}`)
toast.add({title: "Fahrzeug erfolgreich gespeichert"})
dataStore.fetchVehicles()
}
}
const getRowAmount = (row) => { const getRowAmount = (row) => {
let amount = 0 let amount = 0
@@ -115,148 +90,123 @@ setupPage()
</script> </script>
<template> <template>
<div> <UDashboardNavbar :title="currentItem ? currentItem.licensePlate : (mode === 'create' ? 'Fahrzeug erstellen' : 'Fahrzeug bearbeiten')">
<UCard v-if="currentItem && mode == 'show'" > <template #right>
<template #header> <UButton
<UBadge v-if="mode === 'edit'"
v-if="currentItem.active" @click="dataStore.updateItem('vehicles',itemInfo)"
> >
Fahrzeug aktiv Speichern
</UBadge> </UButton>
<UBadge <UButton
v-else v-else-if="mode === 'create'"
@click="dataStore.createNewItem('vehicles',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red" color="red"
class="ml-2"
v-if="mode === 'edit' || mode === 'create'"
>
Abbrechen
</UButton>
<UButton
v-if="mode === 'show'"
@click="router.push(`/vehicles/edit/${currentItem.id}`)"
>
Bearbeiten
</UButton>
</template>
</UDashboardNavbar>
<UTabs
:items="tabItems"
v-if="mode === 'show'"
class="p-5"
>
<template #item="{item}">
<div v-if="item.label === 'Informationen'">
Typ: {{currentItem.type}} <br>
Fahrer: {{dataStore.profiles.find(profile => profile.id === currentItem.driver) ? dataStore.profiles.find(profile => profile.id === currentItem.driver).fullName : 'Kein Fahrer gewählt'}} <br>
</div>
<div v-else-if="item.label === 'Eingangsrechnungen'">
<UTable
:rows="dataStore.getIncomingInvoicesByVehicleId(currentItem.id)"
:columns="incomingInvoicesColumns"
@select="(row) => router.push('/receipts/show/' + row.id)"
> >
Fahrzeug gesperrt <template #vendor-data="{row}">
</UBadge> {{dataStore.getVendorById(row.vendor) ? dataStore.getVendorById(row.vendor).name : ""}}
{{currentItem.licensePlate}}
</template>
<UTabs :items="tabItems">
<template #item="{item}">
<div v-if="item.label === 'Informationen'">
<InputGroup class="mb-3">
<UButton
@click="editCustomer"
>
Bearbeiten
</UButton>
</InputGroup>
Typ: {{currentItem.type}} <br>
Fahrer: {{dataStore.profiles.find(profile => profile.id === currentItem.driver) ? dataStore.profiles.find(profile => profile.id === currentItem.driver).fullName : 'Kein Fahrer gewählt'}} <br>
</div>
<div v-else-if="item.label === 'Eingangsrechnungen'">
<UTable
:rows="dataStore.getIncomingInvoicesByVehicleId(currentItem.id)"
:columns="incomingInvoicesColumns"
@select="(row) => router.push('/receipts/show/' + row.id)"
>
<template #vendor-data="{row}">
{{dataStore.getVendorById(row.vendor) ? dataStore.getVendorById(row.vendor).name : ""}}
</template>
<template #date-data="{row}">
{{dayjs(row.date).format("DD.MM.YYYY")}}
</template>
<template #accounts-data="{row}">
{{getRowAmount(row) ? String(getRowAmount(row).toFixed(2)).replace('.',',') + " €" : ""}}
</template>
</UTable>
</div>
<div v-else-if="item.label === 'Dokumente'">
<InputGroup>
<DocumentUpload
type="vehicle"
:element-id="currentItem.id"
/>
</InputGroup>
<DocumentList
:documents="dataStore.getDocumentsByVehicleId(currentItem.id)"
/>
</div>
</template> </template>
</UTabs> <template #date-data="{row}">
{{dayjs(row.date).format("DD.MM.YYYY")}}
</UCard>
<UCard v-else-if="mode == 'edit' || mode == 'create'" >
<template #header v-if="mode === 'edit'">
{{itemInfo.licensePlate}}
</template>
<UFormGroup
label="Kennzeichen:"
>
<UInput
v-model="itemInfo.licensePlate"
/>
</UFormGroup>
<UFormGroup
label="Fahrzeug aktiv:"
>
<UCheckbox
v-model="itemInfo.active"
/>
</UFormGroup>
<UFormGroup
label="Typ:"
>
<UTextarea
v-model="itemInfo.type"
/>
</UFormGroup>
<UFormGroup
label="Fahrer:"
>
<USelectMenu
v-model="itemInfo.driver"
:options="[{id: null, fullName: 'Kein Fahrer'},...dataStore.profiles]"
option-attribute="fullName"
value-attribute="id"
>
<template #label>
{{dataStore.profiles.find(profile => profile.id === itemInfo.driver) ? dataStore.profiles.find(profile => profile.id === itemInfo.driver).fullName : 'Kein Fahrer ausgewählt'}}
</template> </template>
</USelectMenu> <template #accounts-data="{row}">
</UFormGroup> {{getRowAmount(row) ? String(getRowAmount(row).toFixed(2)).replace('.',',') + " €" : ""}}
</template>
</UTable>
</div>
<div v-else-if="item.label === 'Dokumente'">
<Toolbar>
<DocumentUpload
type="vehicle"
:element-id="currentItem.id"
/>
</Toolbar>
<DocumentList
:documents="dataStore.getDocumentsByVehicleId(currentItem.id)"
/>
</div>
</template>
</UTabs>
<UForm
v-else-if="mode == 'edit' || mode == 'create'"
class="p-5"
>
<UFormGroup
label="Kennzeichen:"
>
<UInput
v-model="itemInfo.licensePlate"
/>
</UFormGroup>
<template #footer>
<UButton
v-if="mode == 'edit'"
@click="dataStore.updateItem('vehicles',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode == 'create'"
@click="dataStore.createNewItem('vehicles',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
>
Abbrechen
</UButton>
</template>
</UCard> <UFormGroup
</div> label="Fahrzeug aktiv:"
>
<UCheckbox
v-model="itemInfo.active"
/>
</UFormGroup>
<UFormGroup
label="Typ:"
>
<UTextarea
v-model="itemInfo.type"
/>
</UFormGroup>
<UFormGroup
label="Fahrer:"
>
<USelectMenu
v-model="itemInfo.driver"
:options="[{id: null, fullName: 'Kein Fahrer'},...dataStore.profiles]"
option-attribute="fullName"
value-attribute="id"
>
<template #label>
{{dataStore.profiles.find(profile => profile.id === itemInfo.driver) ? dataStore.profiles.find(profile => profile.id === itemInfo.driver).fullName : 'Kein Fahrer ausgewählt'}}
</template>
</USelectMenu>
</UFormGroup>
</UForm>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,27 +1,51 @@
<template> <template>
<div id="main"> <UDashboardNavbar title="Fahrzeuge" :badge="filteredRows.length">
<template #right>
<div class="flex items-center gap-1">
<UButton @click="router.push(`/vehicles/create/`)">+ Fahrzeug</UButton>
<UInput <UInput
id="searchinput"
v-model="searchString" v-model="searchString"
icon="i-heroicons-funnel"
autocomplete="off"
placeholder="Suche..." placeholder="Suche..."
/> class="hidden lg:block"
</div> @keydown.esc="$event.target.blur()"
>
<template #trailing>
<UKbd value="/" />
</template>
</UInput>
<UButton @click="router.push(`/vehicles/create`)">+ Fahrzeug</UButton>
</template>
</UDashboardNavbar>
<UDashboardToolbar>
<template #right>
<USelectMenu
v-model="selectedColumns"
icon="i-heroicons-adjustments-horizontal-solid"
:options="templateColumns"
multiple
class="hidden lg:block"
by="key"
>
<template #label>
Spalten
</template>
</USelectMenu>
</template>
</UDashboardToolbar>
<UTable <UTable
:rows="filteredRows" :rows="filteredRows"
:columns="itemColumns" :columns="columns"
@select="selectItem" class="w-full"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }" :ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
> @select="(i) => router.push(`/vehicles/show/${i.id}`) "
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Fahrzeuge anzuzeigen' }"
>
</UTable> </UTable>
</div>
</template> </template>
<script setup> <script setup>
@@ -30,12 +54,21 @@ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
defineShortcuts({
'/': () => {
//console.log(searchinput)
//searchinput.value.focus()
document.getElementById("searchinput").focus()
},
'+': () => {
router.push("/tasks/create")
}
})
const dataStore = useDataStore() const dataStore = useDataStore()
const router = useRouter() const router = useRouter()
const {vehicles } = storeToRefs(useDataStore())
const mode = ref("show")
const itemColumns = [ const templateColumns = [
{ {
key: 'licensePlate', key: 'licensePlate',
label: "Kennzeichen:", label: "Kennzeichen:",
@@ -47,12 +80,8 @@ const itemColumns = [
sortable: true sortable: true
} }
] ]
const selectedColumns = ref(templateColumns)
const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
const selectItem = (item) => {
router.push(`/vehicles/show/${item.id} `)
}
const searchString = ref('') const searchString = ref('')

View File

@@ -6,12 +6,10 @@ definePageMeta({
}) })
const dataStore = useDataStore() const dataStore = useDataStore()
const supabase = useSupabaseClient()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const toast = useToast() const toast = useToast()
const id = ref(route.params.id ? route.params.id : null ) const id = ref(route.params.id ? route.params.id : null )
const numberRange = useNumberRange("vendors")
let currentItem = ref(null) let currentItem = ref(null)
@@ -34,7 +32,6 @@ const setupPage = () => {
const editItem = async () => { const editItem = async () => {
router.push(`/vendors/edit/${currentItem.value.id}`) router.push(`/vendors/edit/${currentItem.value.id}`)
setupPage()
} }
const cancelEditorCreate = () => { const cancelEditorCreate = () => {
@@ -43,32 +40,51 @@ const cancelEditorCreate = () => {
} else { } else {
router.push(`/vendors`) router.push(`/vendors`)
} }
} }
setupPage() setupPage()
</script> </script>
<template> <template>
<h1 <UDashboardNavbar :title="currentItem ? currentItem.name : (mode === 'create' ? 'Lieferant erstellen' : 'Lieferant bearbeiten')">
class=" mb-3 font-bold text-2xl truncate" <template #right>
v-if="currentItem " <UButton
>Lieferant: {{currentItem.name}}</h1> v-if="mode === 'edit'"
@click="dataStore.updateItem('vendors',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode === 'create'"
@click="dataStore.createNewItem('vendors',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
v-if="mode === 'edit' || mode === 'create'"
>
Abbrechen
</UButton>
<UButton
v-if="mode === 'show'"
@click="editItem"
>
Bearbeiten
</UButton>
</template>
</UDashboardNavbar>
<UTabs <UTabs
:items="[{label: 'Informationen'},{label: 'Logbuch'},{label: 'Ansprechpartner'},{label: 'Dokumente'}]" :items="[{label: 'Informationen'},{label: 'Logbuch'},{label: 'Ansprechpartner'},{label: 'Dokumente'}]"
v-if="currentItem && mode == 'show'" v-if="currentItem && mode == 'show'"
class="p-5"
> >
<template #item="{item}"> <template #item="{item}">
<UCard class="mt-5"> <UCard class="mt-5">
<div v-if="item.label === 'Informationen'"> <div v-if="item.label === 'Informationen'">
<Toolbar>
<UButton
v-if="mode == 'show' && currentItem.id"
@click="editItem"
>
Bearbeiten
</UButton>
</Toolbar>
<div v-if="currentItem.infoData" class="text-wrap"> <div v-if="currentItem.infoData" class="text-wrap">
<p v-if="currentItem.infoData.street">Straße + Hausnummer: {{currentItem.infoData.street}}</p> <p v-if="currentItem.infoData.street">Straße + Hausnummer: {{currentItem.infoData.street}}</p>
@@ -120,11 +136,10 @@ setupPage()
</UCard> </UCard>
</template> </template>
</UTabs> </UTabs>
<UCard v-else-if="mode === 'edit' || mode === 'create'" > <UForm
<template #header v-if="mode === 'edit'"> v-else-if="mode === 'edit' || mode === 'create'"
{{itemInfo.name}} class="p-5"
</template> >
<UFormGroup <UFormGroup
label="Name:" label="Name:"
> >
@@ -198,33 +213,7 @@ setupPage()
v-model="itemInfo.infoData.ustid" v-model="itemInfo.infoData.ustid"
/> />
</UFormGroup> </UFormGroup>
</UForm>
<template #footer>
<UButton
v-if="mode == 'edit'"
@click="dataStore.updateItem('vendors',itemInfo)"
>
Speichern
</UButton>
<UButton
v-else-if="mode == 'create'"
@click="dataStore.createNewItem('vendors',itemInfo)"
>
Erstellen
</UButton>
<UButton
@click="cancelEditorCreate"
color="red"
class="ml-2"
>
Abbrechen
</UButton>
</template>
</UCard>
</template> </template>
<style scoped> <style scoped>

View File

@@ -1,60 +1,78 @@
<template> <template>
<Toolbar> <UDashboardNavbar title="Lieferanten" :badge="filteredRows.length">
<UButton @click="router.push(`/vendors/create/`)">+ Lieferant</UButton> <template #right>
<UInput
ref="searchinput"
v-model="searchString"
icon="i-heroicons-funnel"
autocomplete="off"
placeholder="Suche..."
class="hidden lg:block"
@keydown.esc="$event.target.blur()"
>
<template #trailing>
<UKbd value="/" />
</template>
</UInput>
<UInput <UButton @click="router.push(`/vendors/create/`)">+ Lieferant</UButton>
v-model="searchString"
placeholder="Suche..."
/>
<USelectMenu </template>
v-model="selectedColumns" </UDashboardNavbar>
multiple
:options="columnTemplate"
:uiMenu="{width:'w-40'}"
:popper="{placement: 'bottom-start'}"
by="key"
>
<UButton
color="gray"
variant="ghost"
class="flex-1 justify-between"
icon="i-heroicons-view-columns"
/>
<template #option="{ option }"> <UDashboardToolbar>
{{option.label}} <template #right>
</template> <USelectMenu
</USelectMenu> v-model="selectedColumns"
</Toolbar> icon="i-heroicons-adjustments-horizontal-solid"
:options="templateColumns"
multiple
class="hidden lg:block"
by="key"
>
<template #label>
Spalten
</template>
</USelectMenu>
</template>
</UDashboardToolbar>
<UTable
<div class="table"> :rows="filteredRows"
<UTable :columns="columns"
:rows="filteredRows" :ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
:columns="selectedColumns" class="w-full"
@select="selectItem" @select="(i) => router.push(`/vendors/show/${i.id}`)"
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }" :empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Lieferanten anzuzeigen' }"
> >
<template #address-data="{row}"> <template #address-data="{row}">
{{row.infoData.street ? `${row.infoData.street}, ` : ''}}{{row.infoData.special ? `${row.infoData.special},` : ''}} {{(row.infoData.zip || row.infoData.city) ? `${row.infoData.zip} ${row.infoData.city}, ` : ''}} {{row.infoData.country}} {{row.infoData.street ? `${row.infoData.street}, ` : ''}}{{row.infoData.special ? `${row.infoData.special},` : ''}} {{(row.infoData.zip || row.infoData.city) ? `${row.infoData.zip} ${row.infoData.city}, ` : ''}} {{row.infoData.country}}
</template> </template>
</UTable> </UTable>
</div>
</template> </template>
<script setup> <script setup>
definePageMeta({ definePageMeta({
middleware: "auth" middleware: "auth"
}) })
defineShortcuts({
'/': () => {
//console.log(searchinput)
//searchinput.value.focus()
document.getElementById("searchinput").focus()
},
'+': () => {
router.push("/vendors/create")
}
})
const dataStore = useDataStore() const dataStore = useDataStore()
const router = useRouter() const router = useRouter()
const mode = ref("show") const mode = ref("show")
const columnTemplate = ref([ const templateColumns = [
{ {
key: 'vendorNumber', key: 'vendorNumber',
label: "Lieferantennr.", label: "Lieferantennr.",
@@ -70,26 +88,9 @@ const columnTemplate = ref([
label: "Adresse", label: "Adresse",
sortable: true sortable: true
} }
]) ]
const selectedColumns = ref([ const selectedColumns = ref(templateColumns)
{ const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
key: 'vendorNumber',
label: "Lieferantennr.",
sortable: true
},
{
key: "name",
label: "Name",
sortable: true
}
])
const selectItem = (item) => {
console.log(item)
router.push(`/vendors/show/${item.id} `)
}
const searchString = ref('') const searchString = ref('')