Many Changes in Navigation, Shortcuts, Search and Data Pulling directly from Supabase
This commit is contained in:
@@ -20,6 +20,13 @@ defineShortcuts({
|
||||
})
|
||||
|
||||
const actions = [
|
||||
|
||||
{
|
||||
id: 'new-task',
|
||||
label: 'Aufgabe hinzufügen',
|
||||
icon: 'i-heroicons-rectangle-stack',
|
||||
to: "/tasks/create" ,
|
||||
},
|
||||
{
|
||||
id: 'new-customer',
|
||||
label: 'Kunde hinzufügen',
|
||||
@@ -39,12 +46,11 @@ const actions = [
|
||||
to: "/contacts/create" ,
|
||||
},
|
||||
{
|
||||
id: 'new-task',
|
||||
label: 'Aufgabe hinzufügen',
|
||||
icon: 'i-heroicons-rectangle-stack',
|
||||
to: "/tasks/create" ,
|
||||
},
|
||||
{
|
||||
id: 'new-project',
|
||||
label: 'Projekt hinzufügen',
|
||||
icon: 'i-heroicons-clipboard-document-check',
|
||||
to: "/projects/create" ,
|
||||
},{
|
||||
id: 'new-plant',
|
||||
label: 'Objekt hinzufügen',
|
||||
icon: 'i-heroicons-clipboard-document',
|
||||
@@ -87,6 +93,10 @@ const groups = computed(() =>
|
||||
key: "plants",
|
||||
label: "Objekte",
|
||||
commands: dataStore.plants.map(item => { return {id: item.id, label: item.name, to: `/plants/show/${item.id}`}})
|
||||
},{
|
||||
key: "projects",
|
||||
label: "Projekte",
|
||||
commands: dataStore.projects.map(item => { return {id: item.id, label: item.name, to: `/projects/show/${item.id}`}})
|
||||
}
|
||||
].filter(Boolean))
|
||||
|
||||
|
||||
@@ -46,10 +46,21 @@ const categories = computed(() => [{
|
||||
title: 'Navigation',
|
||||
items: [
|
||||
{ shortcuts: ['G', 'H'], name: 'Gehe zu Dashboard' },
|
||||
{ shortcuts: ['G', 'A'], name: 'Gehe zu Aufgaben' },/*
|
||||
{ shortcuts: ['G', 'A'], name: 'Gehe zu Aufgaben' },
|
||||
{ shortcuts: ['G', 'D'], name: 'Gehe zu Dokumente' },
|
||||
{ shortcuts: ['G', 'K'], name: 'Gehe zu Kunden' },
|
||||
{ shortcuts: ['G', 'L'], name: 'Gehe zu Lieferanten' },
|
||||
{ shortcuts: ['G', 'P'], name: 'Gehe zu Projekte' },
|
||||
{ shortcuts: ['G', 'V'], name: 'Gehe zu Verträge' },
|
||||
{ shortcuts: ['G', 'O'], name: 'Gehe zu Objekte' },/*
|
||||
{ shortcuts: ['G', 'I'], name: 'Go to Inbox' },
|
||||
{ shortcuts: ['G', 'U'], name: 'Go to Users' },*/
|
||||
{ shortcuts: ['G', 'S'], name: 'Gehe zu Einstellungen' }
|
||||
{ shortcuts: ['G', 'S'], name: 'Gehe zu Einstellungen' },
|
||||
{ shortcuts: ['↑'], name: 'Vorheriger Eintrag' },
|
||||
{ shortcuts: ['↓'], name: 'Nächster Eintrag' },
|
||||
{ shortcuts: ['↵'], name: 'Eintrag Öffnen' },
|
||||
{ shortcuts: ['←'], name: 'Tab nach links wechseln' },
|
||||
{ shortcuts: ['→'], name: 'Tab nach rechts wechseln' },
|
||||
]
|
||||
}, /*{
|
||||
title: 'Inbox',
|
||||
|
||||
@@ -9,7 +9,13 @@ const _useDashboard = () => {
|
||||
defineShortcuts({
|
||||
'g-h': () => router.push('/'),
|
||||
'g-a': () => router.push('/tasks'),
|
||||
'g-d': () => router.push('/documents'),
|
||||
'g-k': () => router.push('/customers'),
|
||||
'g-l': () => router.push('/vendors'),
|
||||
'g-s': () => router.push('/settings'),
|
||||
'g-p': () => router.push('/projects'),
|
||||
'g-v': () => router.push('/contracts'),
|
||||
'g-o': () => router.push('/plants'),
|
||||
'?': () => isHelpSlideoverOpen.value = !isHelpSlideoverOpen.value,
|
||||
n: () => isNotificationsSlideoverOpen.value = !isNotificationsSlideoverOpen.value
|
||||
})
|
||||
|
||||
@@ -1,31 +1,14 @@
|
||||
|
||||
|
||||
export const useSearch = (searchString,items) => {
|
||||
const dataStore = useDataStore()
|
||||
|
||||
if(!searchString) {
|
||||
return items
|
||||
}
|
||||
|
||||
items = items.map(item => {
|
||||
|
||||
return {
|
||||
...item,
|
||||
customer: dataStore.getCustomerById(item.customer)
|
||||
}
|
||||
})
|
||||
|
||||
console.log(items)
|
||||
|
||||
|
||||
|
||||
return items.filter(i => JSON.stringify(i).toLowerCase().includes(searchString.toLowerCase()))
|
||||
|
||||
/*return items.filter(item => {
|
||||
return Object.values(item).some((value) => {
|
||||
return String(value).toLowerCase().includes(searchString.toLowerCase())
|
||||
})
|
||||
})*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
47
composables/useSupabase.js
Normal file
47
composables/useSupabase.js
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
|
||||
export const useSupabaseSelect = async (relation,select = '*', sortColumn = null) => {
|
||||
const supabase = useSupabaseClient()
|
||||
const dataStore = useDataStore()
|
||||
let data = null
|
||||
|
||||
|
||||
if(sortColumn !== null ) {
|
||||
data = (await supabase
|
||||
.from(relation)
|
||||
.select(select)
|
||||
.eq("tenant", dataStore.currentTenant)
|
||||
.order(sortColumn, {ascending: true})).data
|
||||
} else {
|
||||
data = (await supabase
|
||||
.from(relation)
|
||||
.select(select)
|
||||
.eq("tenant", dataStore.currentTenant)).data
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
export const useSupabaseSelectSingle = async (relation,idToEq,select = '*' ) => {
|
||||
const supabase = useSupabaseClient()
|
||||
const dataStore = useDataStore()
|
||||
let data = null
|
||||
|
||||
|
||||
if(idToEq !== null) {
|
||||
data = (await supabase
|
||||
.from(relation)
|
||||
.select(select)
|
||||
.eq("tenant", dataStore.currentTenant)
|
||||
.eq("id",idToEq)
|
||||
.single()).data
|
||||
} else {
|
||||
data = (await supabase
|
||||
.from(relation)
|
||||
.select(select)
|
||||
.eq("tenant", dataStore.currentTenant)
|
||||
.single()).data
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
@@ -414,6 +414,12 @@ const actions = [
|
||||
label: 'Artikel hinzufügen',
|
||||
icon: 'i-heroicons-puzzle-piece',
|
||||
to: "/products/create" ,
|
||||
},
|
||||
{
|
||||
id: 'new-project',
|
||||
label: 'Projekt hinzufügen',
|
||||
icon: 'i-heroicons-clipboard-document-check',
|
||||
to: "/projects/create" ,
|
||||
}
|
||||
]
|
||||
|
||||
@@ -446,6 +452,10 @@ const groups = computed(() =>
|
||||
key: "plants",
|
||||
label: "Objekte",
|
||||
commands: dataStore.plants.map(item => { return {id: item.id, label: item.name, to: `/plants/show/${item.id}`}})
|
||||
},{
|
||||
key: "projects",
|
||||
label: "Projekte",
|
||||
commands: dataStore.projects.map(item => { return {id: item.id, label: item.name, to: `/projects/show/${item.id}`}})
|
||||
}
|
||||
].filter(Boolean))
|
||||
const footerLinks = [/*{
|
||||
|
||||
@@ -1,19 +1,35 @@
|
||||
<script setup>
|
||||
import dayjs from "dayjs";
|
||||
import {useSupabaseSelectSingle} from "~/composables/useSupabase.js";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/contacts")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
const openTab = ref(0)
|
||||
|
||||
|
||||
let currentItem = ref(null)
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({
|
||||
@@ -22,25 +38,23 @@ const itemInfo = ref({
|
||||
const oldItemInfo = ref({})
|
||||
|
||||
//Functions
|
||||
const setupPage = () => {
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show" || mode.value === "edit"){
|
||||
currentItem.value = dataStore.getContactById(Number(useRoute().params.id))
|
||||
itemInfo.value = await useSupabaseSelectSingle("contacts",route.params.id,"*, customer(id, name), vendor(id,name) ")
|
||||
}
|
||||
|
||||
if(mode.value === "edit") itemInfo.value = currentItem.value
|
||||
|
||||
if(mode.value === "create") {
|
||||
let query = route.query
|
||||
|
||||
if(query.customer) itemInfo.value.customer = Number(query.customer)
|
||||
if(query.vendor) itemInfo.value.vendor = Number(query.vendor)
|
||||
}
|
||||
if(currentItem.value) oldItemInfo.value = JSON.parse(JSON.stringify(currentItem.value))
|
||||
if(itemInfo.value) oldItemInfo.value = JSON.parse(JSON.stringify(itemInfo.value))
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(currentItem.value) {
|
||||
router.push(`/contacts/show/${currentItem.value.id}`)
|
||||
if(itemInfo.value) {
|
||||
router.push(`/contacts/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/contacts`)
|
||||
}
|
||||
@@ -52,7 +66,7 @@ setupPage()
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar
|
||||
:title="currentItem ? currentItem.fullName : (mode === 'create' ? 'Ansprechpartner erstellen' : 'Ansprechpartner bearbeiten')"
|
||||
:title="itemInfo ? itemInfo.fullName : (mode === 'create' ? 'Ansprechpartner erstellen' : 'Ansprechpartner bearbeiten')"
|
||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||
>
|
||||
<template #left>
|
||||
@@ -66,9 +80,9 @@ setupPage()
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="currentItem"
|
||||
:class="['text-xl','font-medium', ... currentItem.active ? ['text-primary'] : ['text-rose-500']]"
|
||||
>{{currentItem ? `Ansprechpartner: ${currentItem.fullName}` : (mode === 'create' ? 'Ansprechpartner erstellen' : 'Ansprechpartner bearbeiten')}}</h1>
|
||||
v-if="itemInfo"
|
||||
:class="['text-xl','font-medium', ... itemInfo.active ? ['text-primary'] : ['text-rose-500']]"
|
||||
>{{itemInfo ? `Ansprechpartner: ${itemInfo.fullName}` : (mode === 'create' ? 'Ansprechpartner erstellen' : 'Ansprechpartner bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
@@ -93,14 +107,14 @@ setupPage()
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click="router.push(`/contacts/edit/${currentItem.id}`)"
|
||||
@click="router.push(`/contacts/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
<!-- <template #badge v-if="currentItem">
|
||||
<!-- <template #badge v-if="itemInfo">
|
||||
<UBadge
|
||||
v-if="currentItem.active"
|
||||
v-if="itemInfo.active"
|
||||
>
|
||||
Kontakt aktiv
|
||||
</UBadge>
|
||||
@@ -114,8 +128,9 @@ setupPage()
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
:items="[{label: 'Informationen'}, {label: 'Logbuch'}]"
|
||||
v-if="currentItem && mode == 'show'"
|
||||
v-if="itemInfo && mode == 'show'"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<UCard class="mt-5">
|
||||
@@ -123,16 +138,16 @@ setupPage()
|
||||
|
||||
|
||||
<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.vendor">Lieferant: <nuxt-link :to="`/vendors/show/${currentItem.vendor}`">{{dataStore.vendors.find(vendor => vendor.id === currentItem.vendor) ? dataStore.vendors.find(vendor => vendor.id === currentItem.vendor).name : ""}}</nuxt-link></p>
|
||||
<p v-if="itemInfo.customer">Kunde: <nuxt-link :to="`/customers/show/${itemInfo.customer.id}`">{{itemInfo.customer ? itemInfo.customer.name : ""}}</nuxt-link></p>
|
||||
<p v-if="itemInfo.vendor">Lieferant: <nuxt-link :to="`/vendors/show/${itemInfo.vendor.id}`">{{itemInfo.vendor ? itemInfo.vendor.name : ""}}</nuxt-link></p>
|
||||
|
||||
|
||||
<p>E-Mail: {{currentItem.email}}</p>
|
||||
<p>Mobil: {{currentItem.phoneMobile}}</p>
|
||||
<p>Festnetz: {{currentItem.phoneHome}}</p>
|
||||
<p>Rolle: {{currentItem.role}}</p>
|
||||
<p>Geburtstag: {{currentItem.birthday ? dayjs(currentItem.birthday).format("DD.MM.YYYY") : ""}}</p>
|
||||
<p>Notizen:<br> {{currentItem.notes}}</p>
|
||||
<p>E-Mail: {{itemInfo.email}}</p>
|
||||
<p>Mobil: {{itemInfo.phoneMobile}}</p>
|
||||
<p>Festnetz: {{itemInfo.phoneHome}}</p>
|
||||
<p>Rolle: {{itemInfo.role}}</p>
|
||||
<p>Geburtstag: {{itemInfo.birthday ? dayjs(itemInfo.birthday).format("DD.MM.YYYY") : ""}}</p>
|
||||
<p>Notizen:<br> {{itemInfo.notes}}</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -140,8 +155,8 @@ setupPage()
|
||||
<div v-else-if="item.label === 'Logbuch'">
|
||||
<HistoryDisplay
|
||||
type="contact"
|
||||
v-if="currentItem"
|
||||
:element-id="currentItem.id"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
@@ -44,15 +44,19 @@
|
||||
@select="(i) => router.push(`/contacts/show/${i.id}`)"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Ansprechpartner anzuzeigen' }"
|
||||
>
|
||||
<template #fullName-data="{row}">
|
||||
<span v-if="row === filteredRows[selectedItem]" class="text-primary-500 font-bold">{{row.fullName}}</span>
|
||||
<span v-else>{{row.fullName}}</span>
|
||||
</template>
|
||||
<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 : ''}}
|
||||
{{row.customer ? 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 : ''}}
|
||||
{{row.vendor ? row.vendor.name : ""}}
|
||||
</template>
|
||||
</UTable>
|
||||
</template>
|
||||
@@ -73,12 +77,43 @@ defineShortcuts({
|
||||
},
|
||||
'+': () => {
|
||||
router.push("/contacts/create")
|
||||
},
|
||||
'Enter': {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
router.push(`/contacts/show/${filteredRows.value[selectedItem.value].id}`)
|
||||
}
|
||||
},
|
||||
'arrowdown': () => {
|
||||
if(selectedItem.value < filteredRows.value.length - 1) {
|
||||
selectedItem.value += 1
|
||||
} else {
|
||||
selectedItem.value = 0
|
||||
}
|
||||
},
|
||||
'arrowup': () => {
|
||||
if(selectedItem.value === 0) {
|
||||
selectedItem.value = filteredRows.value.length - 1
|
||||
} else {
|
||||
selectedItem.value -= 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("contacts","*, customer(name), vendor(name)")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
|
||||
|
||||
const templateColumns = [
|
||||
|
||||
{
|
||||
@@ -139,7 +174,7 @@ const searchString = ref('')
|
||||
})*/
|
||||
|
||||
const filteredRows = computed(() => {
|
||||
return useSearch(searchString.value, dataStore.contacts)
|
||||
return useSearch(searchString.value, items.value)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
@@ -1,18 +1,35 @@
|
||||
<script setup>
|
||||
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||
import dayjs from "dayjs";
|
||||
import {useSupabaseSelectSingle} from "~/composables/useSupabase.js";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/contracts")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
const openTab = ref(0)
|
||||
|
||||
let currentItem = ref(null)
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
@@ -23,12 +40,11 @@ const itemInfo = ref({
|
||||
})
|
||||
|
||||
//Functions
|
||||
const setupPage = () => {
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show" || mode.value === "edit"){
|
||||
currentItem.value = dataStore.getContractById(Number(useRoute().params.id))
|
||||
itemInfo.value = await useSupabaseSelectSingle("contracts", route.params.id, "*, customer(id,name)")
|
||||
}
|
||||
|
||||
if(mode.value === "edit") itemInfo.value = currentItem.value
|
||||
|
||||
if(mode.value === "create") {
|
||||
let query = route.query
|
||||
@@ -38,8 +54,8 @@ const setupPage = () => {
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(currentItem.value) {
|
||||
router.push(`/contracts/show/${currentItem.value.id}`)
|
||||
if(itemInfo.value) {
|
||||
router.push(`/contracts/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/contracts/`)
|
||||
}
|
||||
@@ -49,7 +65,7 @@ setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar :title="currentItem ? currentItem.name : (mode === 'create' ? 'Vertrag erstellen' : 'Vertrag bearbeiten')">
|
||||
<UDashboardNavbar :title="itemInfo ? itemInfo.name : (mode === 'create' ? 'Vertrag erstellen' : 'Vertrag bearbeiten')">
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
@@ -61,9 +77,9 @@ setupPage()
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="currentItem"
|
||||
:class="['text-xl','font-medium', ... currentItem.active ? ['text-primary'] : ['text-rose-500']]"
|
||||
>{{currentItem ? `Vertrag: ${currentItem.name}` : (mode === 'create' ? 'Vertrag erstellen' : 'Vertrag bearbeiten')}}</h1>
|
||||
v-if="itemInfo"
|
||||
:class="['text-xl','font-medium', ... itemInfo.active ? ['text-primary'] : ['text-rose-500']]"
|
||||
>{{itemInfo ? `Vertrag: ${itemInfo.name}` : (mode === 'create' ? 'Vertrag erstellen' : 'Vertrag bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
@@ -88,25 +104,26 @@ setupPage()
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click="router.push(`/contracts/edit/${currentItem.id}`)"
|
||||
@click="router.push(`/contracts/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
v-if="currentItem && mode === 'show'"
|
||||
v-if="itemInfo.id && mode === 'show'"
|
||||
:items="[{label: 'Informationen'}, {label: 'Dokumente'}]"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<div v-if="item.label === 'Informationen'" class="flex mt-5">
|
||||
<div class="w-1/2 mr-5">
|
||||
<UCard>
|
||||
<div class="text-wrap">
|
||||
<p>Kundennummer: <nuxt-link :to="`/customers/show/${currentItem.customer}`">{{dataStore.getCustomerById(currentItem.customer).name}}</nuxt-link></p>
|
||||
<p>Kundennummer: <nuxt-link :to="`/customers/show/${itemInfo.customer.id}`">{{itemInfo.customer ? itemInfo.customer.name : ""}}</nuxt-link></p>
|
||||
Beschreibung:<br>
|
||||
{{currentItem.description}}<br>
|
||||
{{itemInfo.description}}<br>
|
||||
</div>
|
||||
</UCard>
|
||||
</div>
|
||||
@@ -114,8 +131,8 @@ setupPage()
|
||||
<UCard class="h-full">
|
||||
<HistoryDisplay
|
||||
type="contract"
|
||||
v-if="currentItem"
|
||||
:element-id="currentItem.id"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
:render-headline="true"
|
||||
/>
|
||||
</UCard>
|
||||
@@ -126,7 +143,7 @@ setupPage()
|
||||
|
||||
|
||||
<!-- <UBadge
|
||||
v-if="currentItem.active"
|
||||
v-if="itemInfo.active"
|
||||
>
|
||||
Vertrag aktiv
|
||||
</UBadge>
|
||||
@@ -146,11 +163,11 @@ setupPage()
|
||||
<Toolbar>
|
||||
<DocumentUpload
|
||||
type="contract"
|
||||
:element-id="currentItem.id"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</Toolbar>
|
||||
<DocumentList
|
||||
:documents="dataStore.getDocumentsByContractId(currentItem.id)"
|
||||
:documents="dataStore.getDocumentsByContractId(itemInfo.id)"
|
||||
/>
|
||||
</UCard>
|
||||
|
||||
|
||||
@@ -45,7 +45,8 @@
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Verträge anzuzeigen' }"
|
||||
>
|
||||
<template #customer-data="{row}">
|
||||
{{dataStore.customers.find(customer => customer.id === row.customer) ? dataStore.customers.find(customer => customer.id === row.customer).name : row.customer }}
|
||||
<span v-if="row === filteredRows[selectedItem]" class="text-primary-500 font-bold">{{row.customer ? row.customer.name : ""}}</span>
|
||||
<span v-else>{{row.customer ? row.customer.name : ""}}</span>
|
||||
</template>
|
||||
</UTable>
|
||||
</template>
|
||||
@@ -63,16 +64,45 @@ defineShortcuts({
|
||||
},
|
||||
'+': () => {
|
||||
router.push("/contracts/create")
|
||||
},
|
||||
'Enter': {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
router.push(`/contracts/show/${filteredRows.value[selectedItem.value].id}`)
|
||||
}
|
||||
},
|
||||
'arrowdown': () => {
|
||||
if(selectedItem.value < filteredRows.value.length - 1) {
|
||||
selectedItem.value += 1
|
||||
} else {
|
||||
selectedItem.value = 0
|
||||
}
|
||||
},
|
||||
'arrowup': () => {
|
||||
if(selectedItem.value === 0) {
|
||||
selectedItem.value = filteredRows.value.length - 1
|
||||
} else {
|
||||
selectedItem.value -= 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("contracts","*, customer(id,name)")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const templateColumns = [
|
||||
{
|
||||
key: 'customer',
|
||||
label: "Kundennr.:",
|
||||
label: "Kunde",
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
@@ -91,15 +121,8 @@ const columns = computed(() => templateColumns.filter((column) => selectedColumn
|
||||
|
||||
const searchString = ref('')
|
||||
const filteredRows = computed(() => {
|
||||
if(!searchString.value) {
|
||||
return dataStore.contracts
|
||||
}
|
||||
return useSearch(searchString.value, items.value)
|
||||
|
||||
return dataStore.contracts.filter(item => {
|
||||
return Object.values(item).some((value) => {
|
||||
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -90,12 +90,11 @@
|
||||
</span>
|
||||
</template>
|
||||
<template #partner-data="{row}">
|
||||
<span v-if="row.customer">{{dataStore.getCustomerById(row.customer) ? dataStore.getCustomerById(row.customer).name : ''}}</span>
|
||||
<span v-else-if="row.vendor">{{dataStore.getVendorById(row.vendor) ? dataStore.getVendorById(row.vendor).name : ''}}</span>
|
||||
<span v-if="row.customer">{{row.customer ? row.customer.name : ""}}</span>
|
||||
|
||||
</template>
|
||||
<template #reference-data="{row}">
|
||||
<span v-if="row.type === 'incomingInvoice'">{{row.reference}}</span>
|
||||
<span v-if="row === filteredRows[selectedItem]" class="text-primary-500 font-bold">{{row.documentNumber}}</span>
|
||||
<span v-else>{{row.documentNumber}}</span>
|
||||
</template>
|
||||
<template #date-data="{row}">
|
||||
@@ -106,8 +105,12 @@
|
||||
<span :class="dayjs(row.dueDate).diff(dayjs()) <= 0 ? ['text-rose-500'] : '' ">{{row.dueDate ? dayjs(row.dueDate).format("DD.MM.YY") : ''}}</span>
|
||||
</template>
|
||||
<template #paid-data="{row}">
|
||||
<!--
|
||||
<span v-if="dataStore.bankstatements.find(x => x.assignments.find(y => y.type === 'createdDocument' && y.id === row.id))" class="text-primary-500">Bezahlt</span>
|
||||
-->
|
||||
<!--
|
||||
<span v-else :class="dayjs(row.dueDate).diff(dayjs()) <= 0 ? ['text-rose-500'] : ['text-cyan-500'] ">Offen</span>
|
||||
-->
|
||||
<!-- {{dataStore.bankstatements.find(x => x.assignments.find(y => y.id === row.id)) ? true : false}}-->
|
||||
</template>
|
||||
<template #amount-data="{row}">
|
||||
@@ -140,13 +143,48 @@ defineShortcuts({
|
||||
},
|
||||
'+': () => {
|
||||
router.push('/createDocument/edit')
|
||||
},
|
||||
'Enter': {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
router.push(`/createDocument/show/${filteredRows.value[selectedItem.value].id}`)
|
||||
}
|
||||
},
|
||||
'arrowdown': () => {
|
||||
if(selectedItem.value < filteredRows.value.length - 1) {
|
||||
selectedItem.value += 1
|
||||
} else {
|
||||
selectedItem.value = 0
|
||||
}
|
||||
},
|
||||
'arrowup': () => {
|
||||
if(selectedItem.value === 0) {
|
||||
selectedItem.value = filteredRows.value.length - 1
|
||||
} else {
|
||||
selectedItem.value -= 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("createddocuments","*, customer(id,name)")
|
||||
console.log(items.value)
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const templateColumns = [
|
||||
{
|
||||
key: "reference",
|
||||
label: "Referenz",
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
key: 'type',
|
||||
label: "Typ",
|
||||
@@ -163,12 +201,7 @@ const templateColumns = [
|
||||
},
|
||||
{
|
||||
key: 'partner',
|
||||
label: "Kunde / Lieferant",
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
key: "reference",
|
||||
label: "Referenz",
|
||||
label: "Kunde",
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
@@ -239,26 +272,17 @@ const getRowAmount = (row) => {
|
||||
const searchString = ref('')
|
||||
const showDrafts = ref(false)
|
||||
const filteredRows = computed(() => {
|
||||
let items = dataStore.createddocuments
|
||||
|
||||
items = items.filter(i => types.value.find(x => x.key === i.type))
|
||||
let temp = items.value.filter(i => types.value.find(x => x.key === i.type))
|
||||
|
||||
if(showDrafts.value === true) {
|
||||
items = items.filter(i => i.state === "Entwurf")
|
||||
temp = temp.filter(i => i.state === "Entwurf")
|
||||
} else {
|
||||
items = items.filter(i => i.state !== "Entwurf")
|
||||
temp = temp.filter(i => i.state !== "Entwurf")
|
||||
}
|
||||
|
||||
return useSearch(searchString.value, temp)
|
||||
|
||||
if(!searchString.value) {
|
||||
return items
|
||||
}
|
||||
|
||||
return items.filter(item => {
|
||||
return Object.values(item).some((value) => {
|
||||
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
const calculateDocSum = (rows) => {
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/createDocument")
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup>
|
||||
|
||||
import {useSupabaseSelectSingle} from "~/composables/useSupabase.js";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
@@ -26,7 +28,6 @@ const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
|
||||
let currentItem = ref(null)
|
||||
const openTab = ref(0)
|
||||
|
||||
|
||||
@@ -45,20 +46,19 @@ const oldItemInfo = ref({})
|
||||
//Functions
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show" || mode.value === "edit"){
|
||||
currentItem.value = await dataStore.getCustomerById(Number(useRoute().params.id))
|
||||
itemInfo.value = await useSupabaseSelectSingle("customers",route.params.id,"*, contacts(*)")
|
||||
}
|
||||
|
||||
if(mode.value === "edit") itemInfo.value = currentItem.value
|
||||
if(currentItem.value) oldItemInfo.value = JSON.parse(JSON.stringify(currentItem.value))
|
||||
if(itemInfo.value) oldItemInfo.value = JSON.parse(JSON.stringify(itemInfo.value))
|
||||
}
|
||||
|
||||
const editItem = async () => {
|
||||
await router.push(`/customers/edit/${currentItem.value.id}`)
|
||||
await router.push(`/customers/edit/${itemInfo.value.id}`)
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(currentItem.value) {
|
||||
router.push(`/customers/show/${currentItem.value.id}`)
|
||||
if(itemInfo.value) {
|
||||
router.push(`/customers/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/customers`)
|
||||
}
|
||||
@@ -74,7 +74,7 @@ setupPage()
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar
|
||||
:title="currentItem ? `Kunde: ${currentItem.name}` : (mode === 'create' ? 'Kunde erstellen' : 'Kunde bearbeiten')"
|
||||
:title="itemInfo ? `Kunde: ${itemInfo.name}` : (mode === 'create' ? 'Kunde erstellen' : 'Kunde bearbeiten')"
|
||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||
>
|
||||
<template #left>
|
||||
@@ -88,9 +88,9 @@ setupPage()
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="currentItem"
|
||||
:class="['text-xl','font-medium', ... currentItem.active ? ['text-primary'] : ['text-rose-500']]"
|
||||
>{{currentItem ? `Kunde: ${currentItem.name}` : (mode === 'create' ? 'Kunde erstellen' : 'Kunde bearbeiten')}}</h1>
|
||||
v-if="itemInfo"
|
||||
:class="['text-xl','font-medium', ... itemInfo.active ? ['text-primary'] : ['text-rose-500']]"
|
||||
>{{itemInfo ? `Kunde: ${itemInfo.name}` : (mode === 'create' ? 'Kunde erstellen' : 'Kunde bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
@@ -120,9 +120,9 @@ setupPage()
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
<template #badge v-if="currentItem">
|
||||
<template #badge v-if="itemInfo">
|
||||
<UBadge
|
||||
v-if="currentItem.active"
|
||||
v-if="itemInfo.active"
|
||||
>
|
||||
Aktiv
|
||||
</UBadge>
|
||||
@@ -136,7 +136,7 @@ setupPage()
|
||||
</UDashboardNavbar>
|
||||
|
||||
<UTabs
|
||||
v-if="currentItem && mode == 'show'"
|
||||
v-if="itemInfo.id && mode == 'show'"
|
||||
:items="[{label: 'Informationen'},{label: 'Projekte'},{label: 'Objekte'},{label: 'Verträge'}]"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
@@ -146,28 +146,28 @@ setupPage()
|
||||
<div class="w-1/2 mr-5">
|
||||
<UCard >
|
||||
<div class="text-wrap">
|
||||
<p>Kundennummer: {{currentItem.customerNumber}}</p>
|
||||
<p>Typ: {{currentItem.isCompany ? 'Firma' : 'Privatperson'}}</p>
|
||||
<p v-if="currentItem.infoData.street">Straße + Hausnummer: {{currentItem.infoData.street}}</p>
|
||||
<p v-if="currentItem.infoData.zip && currentItem.infoData.city">PLZ + Ort: {{currentItem.infoData.zip}} {{currentItem.infoData.city}}</p>
|
||||
<p v-if="currentItem.infoData.tel">Telefon: {{currentItem.infoData.tel}}</p>
|
||||
<p v-if="currentItem.infoData.email">E-Mail: {{currentItem.infoData.email}}</p>
|
||||
<p v-if="currentItem.infoData.web">Web: {{currentItem.infoData.web}}</p>
|
||||
<p v-if="currentItem.infoData.ustid">USt-Id: {{currentItem.infoData.ustid}}</p>
|
||||
<p>Notizen:<br> {{currentItem.notes}}</p>
|
||||
<p>Kundennummer: {{itemInfo.customerNumber}}</p>
|
||||
<p>Typ: {{itemInfo.isCompany ? 'Firma' : 'Privatperson'}}</p>
|
||||
<p v-if="itemInfo.infoData.street">Straße + Hausnummer: {{itemInfo.infoData.street}}</p>
|
||||
<p v-if="itemInfo.infoData.zip && itemInfo.infoData.city">PLZ + Ort: {{itemInfo.infoData.zip}} {{itemInfo.infoData.city}}</p>
|
||||
<p v-if="itemInfo.infoData.tel">Telefon: {{itemInfo.infoData.tel}}</p>
|
||||
<p v-if="itemInfo.infoData.email">E-Mail: {{itemInfo.infoData.email}}</p>
|
||||
<p v-if="itemInfo.infoData.web">Web: {{itemInfo.infoData.web}}</p>
|
||||
<p v-if="itemInfo.infoData.ustid">USt-Id: {{itemInfo.infoData.ustid}}</p>
|
||||
<p>Notizen:<br> {{itemInfo.notes}}</p>
|
||||
</div>
|
||||
|
||||
</UCard>
|
||||
<UCard class="mt-5">
|
||||
<Toolbar>
|
||||
<UButton
|
||||
@click="router.push(`/contacts/create?customer=${currentItem.id}`)"
|
||||
@click="router.push(`/contacts/create?customer=${itemInfo.id}`)"
|
||||
>
|
||||
+ Ansprechpartner
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
<UTable
|
||||
:rows="dataStore.getContactsByCustomerId(currentItem.id)"
|
||||
:rows="dataStore.getContactsByCustomerId(itemInfo.id)"
|
||||
@select="(row) => router.push(`/contacts/show/${row.id}`)"
|
||||
: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' }"
|
||||
@@ -181,8 +181,8 @@ setupPage()
|
||||
<UCard class="h-full">
|
||||
<HistoryDisplay
|
||||
type="customer"
|
||||
v-if="currentItem"
|
||||
:element-id="currentItem.id"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
:render-headline="true"
|
||||
/>
|
||||
</UCard>
|
||||
@@ -197,13 +197,13 @@ setupPage()
|
||||
<div v-if="item.label === 'Projekte'">
|
||||
<Toolbar>
|
||||
<UButton
|
||||
@click="router.push(`/projects/create?customer=${currentItem.id}`)"
|
||||
@click="router.push(`/projects/create?customer=${itemInfo.id}`)"
|
||||
>
|
||||
+ Projekt
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
<UTable
|
||||
:rows="dataStore.getProjectsByCustomerId(currentItem.id)"
|
||||
:rows="dataStore.getProjectsByCustomerId(itemInfo.id)"
|
||||
@select="(row) => router.push(`/projects/show/${row.id}`)"
|
||||
:columns="[{label: 'Name', key: 'name'},{label: 'Phase', key: 'phase'}]"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Projekte' }"
|
||||
@@ -217,13 +217,13 @@ setupPage()
|
||||
<div v-else-if="item.label === 'Objekte'">
|
||||
<Toolbar>
|
||||
<UButton
|
||||
@click="router.push(`/plants/create?customer=${currentItem.id}`)"
|
||||
@click="router.push(`/plants/create?customer=${itemInfo.id}`)"
|
||||
>
|
||||
+ Objekt
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
<UTable
|
||||
:rows="dataStore.getPlantsByCustomerId(currentItem.id)"
|
||||
:rows="dataStore.getPlantsByCustomerId(itemInfo.id)"
|
||||
@select="(row) => router.push(`/plants/show/${row.id}`)"
|
||||
:columns="[{label: 'Name', key: 'name'}]"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Objekte' }"
|
||||
@@ -235,13 +235,13 @@ setupPage()
|
||||
<div v-else-if="item.label === 'Verträge'">
|
||||
<Toolbar>
|
||||
<UButton
|
||||
@click="router.push(`/contracts/create?customer=${currentItem.id}`)"
|
||||
@click="router.push(`/contracts/create?customer=${itemInfo.id}`)"
|
||||
>
|
||||
+ Vertrag
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
<UTable
|
||||
:rows="dataStore.getContractsByCustomerId(currentItem.id)"
|
||||
:rows="dataStore.getContractsByCustomerId(itemInfo.id)"
|
||||
@select="(row) => router.push(`/contracts/show/${row.id}`)"
|
||||
:columns="[{label: 'Name', key: 'name'},{label: 'Aktiv', key: 'active'}]"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Verträge' }"
|
||||
|
||||
@@ -46,6 +46,10 @@
|
||||
@select="(i) => router.push(`/customers/show/${i.id}`) "
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Kunden anzuzeigen' }"
|
||||
>
|
||||
<template #name-data="{row}">
|
||||
<span v-if="row === filteredRows[selectedItem]" class="text-primary-500 font-bold">{{row.name}}</span>
|
||||
<span v-else>{{row.name}}</span>
|
||||
</template>
|
||||
<template #isCompany-data="{row}">
|
||||
<span v-if="row.isCompany">Firmenkunden</span>
|
||||
<span v-else>Privatkunde</span>
|
||||
@@ -74,10 +78,24 @@ defineShortcuts({
|
||||
'+': () => {
|
||||
router.push("/customers/create")
|
||||
},
|
||||
'enter': {
|
||||
usingInput: "searchinput",
|
||||
'Enter': {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
router.push(`/customers/show/${selectedEntry.value}`)
|
||||
router.push(`/customers/show/${filteredRows.value[selectedItem.value].id}`)
|
||||
}
|
||||
},
|
||||
'arrowdown': () => {
|
||||
if(selectedItem.value < filteredRows.value.length - 1) {
|
||||
selectedItem.value += 1
|
||||
} else {
|
||||
selectedItem.value = 0
|
||||
}
|
||||
},
|
||||
'arrowup': () => {
|
||||
if(selectedItem.value === 0) {
|
||||
selectedItem.value = filteredRows.value.length - 1
|
||||
} else {
|
||||
selectedItem.value -= 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +105,18 @@ defineShortcuts({
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
const supabase = useSupabaseClient()
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("customers",null,"customerNumber")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
|
||||
|
||||
const templateColumns = [
|
||||
{
|
||||
@@ -125,22 +155,11 @@ const columns = computed(() => templateColumns.filter((column) => selectedColumn
|
||||
|
||||
|
||||
const searchString = ref('')
|
||||
const selectedEntry = ref(null)
|
||||
|
||||
const filteredRows = computed(() => {
|
||||
if(!searchString.value) {
|
||||
return dataStore.customers
|
||||
}
|
||||
return useSearch(searchString.value, items.value)
|
||||
|
||||
let results = dataStore.customers.filter(item => {
|
||||
return Object.values(item).some((value) => {
|
||||
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
||||
})
|
||||
})
|
||||
|
||||
selectedEntry.value = results[0].id
|
||||
|
||||
return results
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -330,18 +330,18 @@ setupPage()
|
||||
Netto
|
||||
</InputGroup>
|
||||
|
||||
<table v-if="itemInfo.accounts.length > 1">
|
||||
<table v-if="itemInfo.accounts.length > 1" class="w-full">
|
||||
<tr>
|
||||
<td>Gesamt exkl. Steuer: </td>
|
||||
<td class="text-right">{{totalCalculated.totalNet.toFixed(2)}} €</td>
|
||||
<td class="text-right">{{totalCalculated.totalNet.toFixed(2).replace(".",",")}} €</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>19% Steuer: </td>
|
||||
<td class="text-right">{{totalCalculated.totalAmount19Tax.toFixed(2)}} €</td>
|
||||
<td class="text-right">{{totalCalculated.totalAmount19Tax.toFixed(2).replace(".",",")}} €</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gesamt inkl. Steuer: </td>
|
||||
<td class="text-right">{{totalCalculated.totalGross.toFixed(2)}} €</td>
|
||||
<td class="text-right">{{totalCalculated.totalGross.toFixed(2).replace(".",",")}} €</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -412,7 +412,7 @@ setupPage()
|
||||
<UFormGroup
|
||||
v-if="useNetMode"
|
||||
label="Gesamtbetrag exkl. Steuer in EUR"
|
||||
class="flex-auto"
|
||||
class="flex-auto truncate"
|
||||
:help="item.taxType !== null ? `Betrag inkl. Steuern: ${String(Number(item.amountNet + item.amountTax).toFixed(2)).replace('.',',')} €` : 'Zuerst Steuertyp festlegen' "
|
||||
|
||||
>
|
||||
@@ -421,7 +421,7 @@ setupPage()
|
||||
step="0.01"
|
||||
v-model="item.amountNet"
|
||||
:disabled="item.taxType === null"
|
||||
@keyup="item.amountTax = Number((item.amountNet * (Number(item.taxType)/100)).toFixed(2))"
|
||||
@keyup="item.amountTax = Number((item.amountNet * (Number(taxOptions.find(i => i.key === item.taxType).percentage)/100)).toFixed(2))"
|
||||
>
|
||||
<template #trailing>
|
||||
<span class="text-gray-500 dark:text-gray-400 text-xs">EUR</span>
|
||||
|
||||
@@ -12,15 +12,47 @@ defineShortcuts({
|
||||
},
|
||||
'+': () => {
|
||||
router.push("/incomingInvoices/[mode]")
|
||||
},
|
||||
'Enter': {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
router.push(`/incomingInvoices/show/${filteredRows.value[selectedItem.value].id}`)
|
||||
}
|
||||
},
|
||||
'arrowdown': () => {
|
||||
if(selectedItem.value < filteredRows.value.length - 1) {
|
||||
selectedItem.value += 1
|
||||
} else {
|
||||
selectedItem.value = 0
|
||||
}
|
||||
},
|
||||
'arrowup': () => {
|
||||
if(selectedItem.value === 0) {
|
||||
selectedItem.value = filteredRows.value.length - 1
|
||||
} else {
|
||||
selectedItem.value -= 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("incominginvoices","*, vendor(id,name)")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const templateColumns = [
|
||||
{
|
||||
key: 'reference',
|
||||
label: "Referenz:",
|
||||
sortable: true
|
||||
}, {
|
||||
key: 'state',
|
||||
label: "Status:",
|
||||
sortable: true
|
||||
@@ -49,15 +81,8 @@ const columns = computed(() => templateColumns.filter((column) => selectedColumn
|
||||
|
||||
const searchString = ref('')
|
||||
const filteredRows = computed(() => {
|
||||
if(!searchString.value) {
|
||||
return dataStore.incominginvoices
|
||||
}
|
||||
return useSearch(searchString.value, items.value)
|
||||
|
||||
return dataStore.incominginvoices.filter(item => {
|
||||
return Object.values(item).some((value) => {
|
||||
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -110,18 +135,22 @@ const filteredRows = computed(() => {
|
||||
@select="(i) => router.push(`/incomingInvoices/show/${i.id}`) "
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Belege anzuzeigen' }"
|
||||
>
|
||||
<template #reference-data="{row}">
|
||||
<span v-if="row === filteredRows[selectedItem]" class="text-primary-500 font-bold">{{row.reference}}</span>
|
||||
<span v-else>{{row.reference}}</span>
|
||||
</template>
|
||||
<template #date-data="{row}">
|
||||
{{dayjs(row.date).format("DD.MM.YYYY")}}
|
||||
</template>
|
||||
<template #vendor-data="{row}">
|
||||
{{dataStore.getVendorById(row.vendor).name}}
|
||||
{{row.vendor ? row.vendor.name : ""}}
|
||||
</template>
|
||||
<template #dueDate-data="{row}">
|
||||
{{dayjs(row.dueDate).format("DD.MM.YYYY")}}
|
||||
</template>
|
||||
<template #paid-data="{row}">
|
||||
<span v-if="dataStore.bankstatements.find(x => x.assignments.find(y => y.type === 'incomingInvoice' && y.id === row.id))" class="text-primary-500">Bezahlt</span>
|
||||
<span v-else class="text-rose-600">Offen</span>
|
||||
<!-- <span v-if="dataStore.bankstatements.find(x => x.statementallocations.find(y => y.ii_id === row.id))" class="text-primary-500">Bezahlt</span>
|
||||
<span v-else class="text-rose-600">Offen</span>-->
|
||||
</template>
|
||||
</UTable>
|
||||
</UDashboardPanelContent>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<UDashboardNavbar title="Objekte" :badge="filteredRows.length">
|
||||
<UDashboardNavbar title="Objekte" >
|
||||
<template #right>
|
||||
<UInput
|
||||
id="searchinput"
|
||||
@@ -54,7 +54,7 @@
|
||||
: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 : "" }}
|
||||
{{row.customer ? row.customer.name : ""}}
|
||||
</template>
|
||||
</UTable>
|
||||
|
||||
@@ -74,12 +74,42 @@ defineShortcuts({
|
||||
},
|
||||
'+': () => {
|
||||
router.push("/plants/create")
|
||||
},
|
||||
'Enter': {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
router.push(`/plants/show/${filteredRows.value[selectedItem.value].id}`)
|
||||
}
|
||||
},
|
||||
'arrowdown': () => {
|
||||
if(selectedItem.value < filteredRows.value.length - 1) {
|
||||
selectedItem.value += 1
|
||||
} else {
|
||||
selectedItem.value = 0
|
||||
}
|
||||
},
|
||||
'arrowup': () => {
|
||||
if(selectedItem.value === 0) {
|
||||
selectedItem.value = filteredRows.value.length - 1
|
||||
} else {
|
||||
selectedItem.value -= 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("plants","*, customer(id,name)")
|
||||
console.log(items.value)
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const templateColumns = [
|
||||
{
|
||||
key: "name",
|
||||
@@ -98,22 +128,9 @@ const columns = computed(() => templateColumns.filter((column) => selectedColumn
|
||||
const searchString = ref('')
|
||||
|
||||
const filteredRows = computed(() => {
|
||||
if(!searchString.value) {
|
||||
return dataStore.plants
|
||||
}
|
||||
|
||||
return dataStore.plants.filter(item => {
|
||||
|
||||
item.customerName = dataStore.customers.find(i => i.id === item.customer).name
|
||||
|
||||
return Object.values(item).some((value) => {
|
||||
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
||||
})
|
||||
})
|
||||
return useSearch(searchString.value, items.value)
|
||||
})
|
||||
const selectItem = (item) => {
|
||||
router.push(`/plants/show/${item.id} `)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -2,39 +2,55 @@
|
||||
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||
import DocumentList from "~/components/DocumentList.vue";
|
||||
import DocumentUpload from "~/components/DocumentUpload.vue";
|
||||
import {useSupabaseSelect} from "~/composables/useSupabase.js";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/products")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
|
||||
let currentItem = ref(null)
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({
|
||||
unit: 1,
|
||||
tags: []
|
||||
})
|
||||
const openTab = ref(0)
|
||||
|
||||
//Functions
|
||||
const setupPage = () => {
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show" || mode.value === "edit"){
|
||||
currentItem.value = dataStore.getProductById(Number(useRoute().params.id))
|
||||
itemInfo.value = await useSupabaseSelectSingle("products",route.params.id,"*")
|
||||
}
|
||||
|
||||
if(mode.value === "edit") itemInfo.value = currentItem.value
|
||||
if(mode.value === "edit") itemInfo.value = itemInfo.value
|
||||
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(currentItem.value) {
|
||||
router.push(`/products/show/${currentItem.value.id}`)
|
||||
if(itemInfo.value) {
|
||||
router.push(`/products/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/products/`)
|
||||
}
|
||||
@@ -45,7 +61,6 @@ setupPage()
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar
|
||||
:title="currentItem ? currentItem.name : (mode === 'create' ? 'Artikel erstellen' : 'Artikel bearbeiten')"
|
||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||
>
|
||||
<template #left>
|
||||
@@ -59,9 +74,9 @@ setupPage()
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="currentItem"
|
||||
v-if="itemInfo"
|
||||
class="text-xl font-medium"
|
||||
>{{currentItem ? `Artikel: ${currentItem.name}` : (mode === 'create' ? 'Artikel erstellen' : 'Artikel bearbeiten')}}</h1>
|
||||
>{{itemInfo.name ? `Artikel: ${itemInfo.name}` : (mode === 'create' ? 'Artikel erstellen' : 'Artikel bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
@@ -86,7 +101,7 @@ setupPage()
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click=" router.push(`/products/edit/${currentItem.id}`)"
|
||||
@click=" router.push(`/products/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
@@ -94,8 +109,9 @@ setupPage()
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
:items="[{label: 'Informationen'},{label: 'Logbuch'},{label: 'Bestand'},{label: 'Dokumente'}]"
|
||||
v-if="mode === 'show'"
|
||||
v-if="mode === 'show' && itemInfo"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<UCard class="mt-5">
|
||||
@@ -103,15 +119,16 @@ setupPage()
|
||||
v-if="item.label === 'Informationen'"
|
||||
>
|
||||
<UBadge
|
||||
v-for="tag in currentItem.tags"
|
||||
v-for="tag in itemInfo.tags"
|
||||
class="mr-2"
|
||||
|
||||
>
|
||||
{{tag}}
|
||||
</UBadge>
|
||||
<UDivider
|
||||
class="my-2"
|
||||
/>
|
||||
<span v-if="currentItem.purchasePrice">Einkaufspreis: {{Number(currentItem.purchasePrice).toFixed(2)}} €<br></span>
|
||||
<span v-if="itemInfo.purchasePrice">Einkaufspreis: {{Number(itemInfo.purchasePrice).toFixed(2)}} €<br></span>
|
||||
|
||||
</div>
|
||||
<div
|
||||
@@ -119,14 +136,14 @@ setupPage()
|
||||
>
|
||||
<HistoryDisplay
|
||||
type="product"
|
||||
v-if="currentItem"
|
||||
:element-id="currentItem.id"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="item.label === 'Bestand'"
|
||||
>
|
||||
Bestand: {{dataStore.getStockByProductId(currentItem.id)}} {{dataStore.units.find(unit => unit.id === currentItem.unit) ? dataStore.units.find(unit => unit.id === currentItem.unit).name : ""}}
|
||||
Bestand: {{dataStore.getStockByProductId(itemInfo.id)}} {{dataStore.units.find(unit => unit.id === itemInfo.unit) ? dataStore.units.find(unit => unit.id === itemInfo.unit).name : ""}}
|
||||
|
||||
</div>
|
||||
<div
|
||||
@@ -135,12 +152,12 @@ setupPage()
|
||||
<Toolbar>
|
||||
<DocumentUpload
|
||||
type="product"
|
||||
:element-id="currentItem.id"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</Toolbar>
|
||||
|
||||
|
||||
<DocumentList :documents="dataStore.getDocumentsByProductId(currentItem.id)"/>
|
||||
<DocumentList :documents="dataStore.getDocumentsByProductId(itemInfo.id)"/>
|
||||
</div>
|
||||
</UCard>
|
||||
</template>
|
||||
@@ -154,6 +171,7 @@ setupPage()
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.name"
|
||||
autofocus
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
</USelectMenu>
|
||||
</template>
|
||||
</UDashboardToolbar>
|
||||
|
||||
<UTable
|
||||
:rows="filteredRows"
|
||||
:columns="columns"
|
||||
@@ -57,6 +56,15 @@
|
||||
@select="(i) => router.push(`/products/show/${i.id}`) "
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Artikel anzuzeigen' }"
|
||||
>
|
||||
<template #name-data="{row}">
|
||||
<span
|
||||
v-if="row === filteredRows[selectedItem]"
|
||||
class="text-primary-500 font-bold">{{row.name}}</span>
|
||||
<span v-else>
|
||||
{{row.name}}
|
||||
</span>
|
||||
|
||||
</template>
|
||||
<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 : "")}`}}
|
||||
</template>
|
||||
@@ -76,7 +84,7 @@
|
||||
<template #unit-data="{row}">
|
||||
{{dataStore.units.find(unit => unit.id === row.unit) ? dataStore.units.find(unit => unit.id === row.unit).name : row.unit}}
|
||||
</template>
|
||||
</UTable>/
|
||||
</UTable>
|
||||
|
||||
</template>
|
||||
|
||||
@@ -94,12 +102,42 @@ defineShortcuts({
|
||||
},
|
||||
'+': () => {
|
||||
router.push("/products/create")
|
||||
},
|
||||
'Enter': {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
router.push(`/products/show/${filteredRows.value[selectedItem.value].id}`)
|
||||
}
|
||||
},
|
||||
'arrowdown': () => {
|
||||
if(selectedItem.value < filteredRows.value.length - 1) {
|
||||
selectedItem.value += 1
|
||||
} else {
|
||||
selectedItem.value = 0
|
||||
}
|
||||
},
|
||||
'arrowup': () => {
|
||||
if(selectedItem.value === 0) {
|
||||
selectedItem.value = filteredRows.value.length - 1
|
||||
} else {
|
||||
selectedItem.value -= 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("products","*")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
|
||||
const templateColumns = [
|
||||
{
|
||||
key: "stock",
|
||||
@@ -152,19 +190,10 @@ const selectedTags = ref(templateTags.value)
|
||||
const searchString = ref('')
|
||||
|
||||
const filteredRows = computed(() => {
|
||||
let items = dataStore.products
|
||||
let temp = items.value.filter(i => i.tags.some(x => selectedTags.value.includes(x)) || i.tags.length === 0)
|
||||
|
||||
items = items.filter(i => i.tags.some(x => selectedTags.value.includes(x)) || i.tags.length === 0)
|
||||
return useSearch(searchString.value, temp)
|
||||
|
||||
if(!searchString.value) {
|
||||
return items
|
||||
}
|
||||
|
||||
return items.filter(product => {
|
||||
return Object.values(product).some((value) => {
|
||||
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -3,11 +3,28 @@ import dayjs from "dayjs";
|
||||
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||
import DocumentUpload from "~/components/DocumentUpload.vue";
|
||||
import DocumentList from "~/components/DocumentList.vue";
|
||||
import {useSupabaseSelectSingle} from "~/composables/useSupabase.js";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/projects")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const supabase = useSupabaseClient()
|
||||
const user = useSupabaseUser()
|
||||
@@ -16,7 +33,7 @@ const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
|
||||
let currentItem = ref(null)
|
||||
const openTab = ref(0)
|
||||
|
||||
const tabItems = [
|
||||
{
|
||||
@@ -87,13 +104,11 @@ const tags = dataStore.getDocumentTags
|
||||
|
||||
|
||||
//Functions
|
||||
const setupPage = () => {
|
||||
const setupPage = async() => {
|
||||
if(mode.value === "show" || mode.value === "edit"){
|
||||
currentItem.value = dataStore.getProjectById(Number(useRoute().params.id))
|
||||
itemInfo.value = await useSupabaseSelectSingle("projects",route.params.id,"*, customer(*), plant(*)")//dataStore.getProjectById(Number(useRoute().params.id))
|
||||
}
|
||||
|
||||
if(mode.value === "edit") itemInfo.value = currentItem.value
|
||||
|
||||
if(mode.value === "create") {
|
||||
let query = route.query
|
||||
|
||||
@@ -104,12 +119,14 @@ const setupPage = () => {
|
||||
itemInfo.value.customer = dataStore.getPlantById(itemInfo.value.plant).customer
|
||||
}
|
||||
}
|
||||
if(currentItem.value) oldItemInfo.value = JSON.parse(JSON.stringify(currentItem.value))
|
||||
if(itemInfo.value) oldItemInfo.value = JSON.parse(JSON.stringify(itemInfo.value))
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(currentItem.value) {
|
||||
router.push(`/projects/show/${currentItem.value.id}`)
|
||||
if(itemInfo.value) {
|
||||
router.push(`/projects/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/projects/`)
|
||||
}
|
||||
@@ -117,7 +134,7 @@ const cancelEditorCreate = () => {
|
||||
|
||||
const projectHours = () => {
|
||||
let hours = 0
|
||||
dataStore.getTimesByProjectId(currentItem.value.id).forEach(item => {
|
||||
dataStore.getTimesByProjectId(itemInfo.value.id).forEach(item => {
|
||||
hours += Number(dayjs(item.end).diff(item.start,'hour',true).toFixed(2))
|
||||
})
|
||||
|
||||
@@ -150,7 +167,7 @@ const projectHours = () => {
|
||||
}])*/
|
||||
const phasesTemplateSelected = ref(dataStore.phasesTemplates[0].id)
|
||||
const changeActivePhase = (phase) => {
|
||||
currentItem.value.phases = currentItem.value.phases.map(p => {
|
||||
itemInfo.value.phases = itemInfo.value.phases.map(p => {
|
||||
if(p.active) delete p.active
|
||||
|
||||
if(p.label === phase.label) p.active = true
|
||||
@@ -163,19 +180,34 @@ const changeActivePhase = (phase) => {
|
||||
}
|
||||
|
||||
const savePhases = () => {
|
||||
dataStore.updateItem("projects", currentItem.value)
|
||||
dataStore.updateItem("projects", itemInfo.value)
|
||||
}
|
||||
|
||||
const loadPhases = async () => {
|
||||
currentItem.value.phases = dataStore.phasesTemplates.find(i => i.id === phasesTemplateSelected.value).initialPhases
|
||||
await dataStore.updateItem("projects", currentItem.value)
|
||||
itemInfo.value.phases = dataStore.phasesTemplates.find(i => i.id === phasesTemplateSelected.value).initialPhases
|
||||
await dataStore.updateItem("projects", itemInfo.value)
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar :title="currentItem ? currentItem.name : (mode === 'create' ? 'Projekt erstellen' : 'Projekt bearbeiten')">
|
||||
<UDashboardNavbar :title="itemInfo ? itemInfo.name : (mode === 'create' ? 'Projekt erstellen' : 'Projekt bearbeiten')">
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/projects`)"
|
||||
>
|
||||
Projekte
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
class="text-xl font-medium"
|
||||
>{{itemInfo.name ? `Projekt: ${itemInfo.name}` : (mode === 'create' ? 'Projekt erstellen' : 'Projekt bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@@ -199,7 +231,7 @@ setupPage()
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click="router.push(`/projects/edit/${currentItem.id}`)"
|
||||
@click="router.push(`/projects/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
@@ -207,8 +239,9 @@ setupPage()
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
:items="tabItems"
|
||||
v-if="currentItem && mode == 'show'"
|
||||
v-if="itemInfo.id && mode == 'show'"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{ item }">
|
||||
<UCard class="mt-5">
|
||||
@@ -217,15 +250,15 @@ setupPage()
|
||||
|
||||
|
||||
<div class="text-wrap">
|
||||
<p>Kunde: <nuxt-link :to="`/customers/show/${currentItem.customer}`">{{dataStore.getCustomerById(currentItem.customer).name}}</nuxt-link></p>
|
||||
<p>Objekt: <nuxt-link :to="`/plants/show/${currentItem.plant}`">{{currentItem.plant ? dataStore.getPlantById(currentItem.plant).name : ""}}</nuxt-link></p>
|
||||
<p class="">Notizen: {{currentItem.notes}}</p>
|
||||
<p>Kunde: <nuxt-link :to="`/customers/show/${itemInfo.customer.id}`">{{itemInfo.customer.name}}</nuxt-link></p>
|
||||
<p>Objekt: <nuxt-link :to="`/plants/show/${itemInfo.plant.id}`">{{itemInfo.plant ? itemInfo.plant.name : ""}}</nuxt-link></p>
|
||||
<p class="">Notizen: {{itemInfo.notes}}</p>
|
||||
</div>
|
||||
|
||||
<UDivider class="my-3"/>
|
||||
<h1 class="font-bold text-lg my-3">Beteiligte Benutzer:</h1>
|
||||
<UAlert
|
||||
v-for="projectUser in currentItem.users"
|
||||
v-for="projectUser in itemInfo.users"
|
||||
:avatar="{ alt: dataStore.getProfileById(projectUser).fullName }"
|
||||
:title="dataStore.getProfileById(projectUser).fullName"
|
||||
class="mb-3"
|
||||
@@ -235,14 +268,14 @@ setupPage()
|
||||
<div v-else-if="item.key === 'historyDisplay'">
|
||||
<HistoryDisplay
|
||||
type="project"
|
||||
v-if="currentItem"
|
||||
:element-id="currentItem.id"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="item.key === 'phases'" class="space-y-3">
|
||||
<UFormGroup
|
||||
label="Vorlage laden"
|
||||
v-if="currentItem.phases.length === 0"
|
||||
v-if="itemInfo.phases.length === 0"
|
||||
>
|
||||
<InputGroup>
|
||||
<USelectMenu
|
||||
@@ -263,7 +296,7 @@ setupPage()
|
||||
</UFormGroup>
|
||||
|
||||
<UAccordion
|
||||
:items="currentItem.phases"
|
||||
:items="itemInfo.phases"
|
||||
>
|
||||
<template #default="{item,index,open}">
|
||||
<UButton
|
||||
@@ -304,14 +337,14 @@ setupPage()
|
||||
<div v-if="item.key === 'tasks'" class="space-y-3">
|
||||
<Toolbar>
|
||||
<UButton
|
||||
@click="router.push(`/tasks/create?project=${currentItem.id}`)"
|
||||
@click="router.push(`/tasks/create?project=${itemInfo.id}`)"
|
||||
>
|
||||
+ Aufgabe
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
|
||||
<UTable
|
||||
:rows="dataStore.getTasksByProjectId(currentItem.id)"
|
||||
:rows="dataStore.getTasksByProjectId(itemInfo.id)"
|
||||
:columns="[{key: 'name',label: 'Name'},{key: 'categorie',label: 'Kategorie'},{key: 'user',label: 'Benutzer'}]"
|
||||
@select="(row) => router.push(`/tasks/show/${row.id}`)"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Aufgaben' }"
|
||||
@@ -327,22 +360,22 @@ setupPage()
|
||||
<Toolbar>
|
||||
<DocumentUpload
|
||||
type="project"
|
||||
:element-id="currentItem.id"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
<UButton
|
||||
@click="router.push(`/createDocument/edit?project=${currentItem.id}&type=quotes&customer=${currentItem.customer}`)"
|
||||
@click="router.push(`/createDocument/edit?project=${itemInfo.id}&type=quotes&customer=${itemInfo.customer.id}`)"
|
||||
>
|
||||
+ Angebot
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="router.push(`/createDocument/edit?project=${currentItem.id}&type=invoices&customer=${currentItem.customer}`)"
|
||||
@click="router.push(`/createDocument/edit?project=${itemInfo.id}&type=invoices&customer=${itemInfo.customer.id}`)"
|
||||
>
|
||||
+ Rechnung
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
|
||||
<UTable
|
||||
:rows="dataStore.getCreatedDocumentsByProject(currentItem.id)"
|
||||
:rows="dataStore.getCreatedDocumentsByProject(itemInfo.id)"
|
||||
:columns="[
|
||||
{
|
||||
label: 'Typ',
|
||||
@@ -371,9 +404,9 @@ setupPage()
|
||||
</template>
|
||||
</UTable>
|
||||
|
||||
<DocumentList :documents="dataStore.getDocumentsByProjectId(currentItem.id)"/>
|
||||
<DocumentList :documents="dataStore.getDocumentsByProjectId(itemInfo.id)"/>
|
||||
<!--
|
||||
{{dataStore.getDocumentsByProjectId(currentItem.id)}}
|
||||
{{dataStore.getDocumentsByProjectId(itemInfo.id)}}
|
||||
-->
|
||||
|
||||
</div>
|
||||
@@ -381,7 +414,7 @@ setupPage()
|
||||
<div v-else-if="item.key === 'timetracking'" class="space-y-3">
|
||||
Projekt Zeit: {{String(projectHours()).replace(".",",")}} Stunden
|
||||
<UTable
|
||||
:rows="dataStore.getTimesByProjectId(currentItem.id)"
|
||||
:rows="dataStore.getTimesByProjectId(itemInfo.id)"
|
||||
:columns="timeTableRows"
|
||||
:empty-state="{ icon: 'i-heroicons-clock', label: 'Noch keine Zeiten in diesem Projekt' }"
|
||||
>
|
||||
@@ -409,7 +442,7 @@ setupPage()
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
<UTable
|
||||
:rows="dataStore.getEventsByProjectId(currentItem.id)"
|
||||
:rows="dataStore.getEventsByProjectId(itemInfo.id)"
|
||||
@select="(i) => router.push(`/events/show/${i.id}`)"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Termine anzuzeigen' }"
|
||||
:columns="[{key:'title',label:'Titel'},{key:'start',label:'Start'},{key:'end',label:'Ende'},{key:'type',label:'Typ'},{key:'resources',label:'Resourcen'}]"
|
||||
@@ -430,7 +463,7 @@ setupPage()
|
||||
Auf das Projekt gebuchte Artikel:
|
||||
|
||||
<UTable
|
||||
:rows="dataStore.getStocksByProjectId(currentItem.id)"
|
||||
:rows="dataStore.getStocksByProjectId(itemInfo.id)"
|
||||
:columns="[{key:'productId',label:'Artikel'},{key:'stock',label:'Anzahl'}]"
|
||||
@select="(i) => router.push(`/products/show/${i.productId}`)"
|
||||
>
|
||||
@@ -438,6 +471,7 @@ setupPage()
|
||||
{{dataStore.getProductById(row.productId).name}}
|
||||
</template>
|
||||
<template #stock-data="{row}">
|
||||
{{dataStore.getProductById(row.productId)}}
|
||||
{{row.stock}} {{dataStore.units.find(i => i.id === dataStore.getProductById(row.productId).unit).short}}
|
||||
</template>
|
||||
</UTable>
|
||||
|
||||
@@ -56,14 +56,18 @@
|
||||
@select="(i) => router.push(`/projects/show/${i.id}`) "
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Projekte anzuzeigen' }"
|
||||
>
|
||||
<template #name-data="{row}">
|
||||
<span class="text-primary-500 font-bold" v-if="row === filteredRows[selectedItem]">{{row.name}}</span>
|
||||
<span v-else>{{row.name}}</span>
|
||||
</template>
|
||||
<template #phase-data="{row}">
|
||||
{{getActivePhaseLabel(row)}}
|
||||
</template>
|
||||
<template #customer-data="{row}">
|
||||
{{dataStore.getCustomerById(row.customer) ? dataStore.getCustomerById(row.customer).name : ""}}
|
||||
{{row.customer ? row.customer.name : ""}}
|
||||
</template>
|
||||
<template #plant-data="{row}">
|
||||
{{dataStore.getPlantById(row.plant) ? dataStore.getPlantById(row.plant).name : ""}}
|
||||
{{row.plant ? row.plant.name : ""}}
|
||||
</template>
|
||||
<template #users-data="{row}">
|
||||
{{row.users.map(i => dataStore.getProfileById(i).fullName).join(", ")}}
|
||||
@@ -85,12 +89,43 @@ defineShortcuts({
|
||||
},
|
||||
'+': () => {
|
||||
router.push("/projects/create")
|
||||
},
|
||||
'Enter': {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
router.push(`/projects/show/${filteredRows.value[selectedItem.value].id}`)
|
||||
}
|
||||
},
|
||||
'arrowdown': () => {
|
||||
if(selectedItem.value < filteredRows.value.length - 1) {
|
||||
selectedItem.value += 1
|
||||
} else {
|
||||
selectedItem.value = 0
|
||||
}
|
||||
},
|
||||
'arrowup': () => {
|
||||
if(selectedItem.value === 0) {
|
||||
selectedItem.value = filteredRows.value.length - 1
|
||||
} else {
|
||||
selectedItem.value -= 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("projects","*, customer (name), plant(name)")
|
||||
|
||||
console.log(items.value)
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const templateColumns = [
|
||||
{
|
||||
key: "phase",
|
||||
@@ -148,9 +183,7 @@ const searchString = ref('')
|
||||
const showFinished = ref(false)
|
||||
|
||||
const filteredRows = computed(() => {
|
||||
let items = dataStore.projects
|
||||
|
||||
items = items.map(item => {
|
||||
let temp = items.value.map(item => {
|
||||
return {
|
||||
...item,
|
||||
phaseLabel: getActivePhaseLabel(item)
|
||||
@@ -158,16 +191,16 @@ const filteredRows = computed(() => {
|
||||
})
|
||||
|
||||
if(showFinished.value) {
|
||||
items = items.filter(i => i.phaseLabel === "Abgeschlossen")
|
||||
temp = temp.filter(i => i.phaseLabel === "Abgeschlossen")
|
||||
} else {
|
||||
items = items.filter(i => i.phaseLabel !== "Abgeschlossen")
|
||||
temp = temp.filter(i => i.phaseLabel !== "Abgeschlossen")
|
||||
}
|
||||
|
||||
if(!searchString.value) {
|
||||
return items
|
||||
return temp
|
||||
}
|
||||
|
||||
return items.filter(project => {
|
||||
return temp.filter(project => {
|
||||
return Object.values(project).some((value) => {
|
||||
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
||||
})
|
||||
|
||||
@@ -42,7 +42,12 @@
|
||||
: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' }"
|
||||
/>
|
||||
>
|
||||
<template #spaceNumber-data="{row}">
|
||||
<span v-if="row === filteredRows[selectedItem]" class="text-primary-500 font-bold">{{row.spaceNumber}}</span>
|
||||
<span v-else>{{row.spaceNumber}}</span>
|
||||
</template>
|
||||
</UTable>
|
||||
|
||||
</template>
|
||||
|
||||
@@ -60,12 +65,41 @@ defineShortcuts({
|
||||
},
|
||||
'+': () => {
|
||||
router.push("/spaces/create")
|
||||
},
|
||||
'Enter': {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
router.push(`/spaces/show/${filteredRows.value[selectedItem.value].id}`)
|
||||
}
|
||||
},
|
||||
'arrowdown': () => {
|
||||
if(selectedItem.value < filteredRows.value.length - 1) {
|
||||
selectedItem.value += 1
|
||||
} else {
|
||||
selectedItem.value = 0
|
||||
}
|
||||
},
|
||||
'arrowup': () => {
|
||||
if(selectedItem.value === 0) {
|
||||
selectedItem.value = filteredRows.value.length - 1
|
||||
} else {
|
||||
selectedItem.value -= 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("spaces","*","spaceNumber")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const templateColumns = [
|
||||
{
|
||||
key: 'spaceNumber',
|
||||
@@ -88,15 +122,7 @@ const columns = computed(() => templateColumns.filter((column) => selectedColumn
|
||||
|
||||
const searchString = ref('')
|
||||
const filteredRows = computed(() => {
|
||||
if(!searchString.value) {
|
||||
return dataStore.spaces
|
||||
}
|
||||
|
||||
return dataStore.spaces.filter(item => {
|
||||
return Object.values(item).some((value) => {
|
||||
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
||||
})
|
||||
})
|
||||
return useSearch(searchString.value, items.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -147,15 +147,7 @@ const filteredRows = computed(() => {
|
||||
|
||||
items = items.filter(i => showDone.value === true ? i.categorie === "Erledigt" : i.categorie !== "Erledigt")
|
||||
|
||||
if(!searchString.value) {
|
||||
return items
|
||||
}
|
||||
|
||||
return items.filter(item => {
|
||||
return Object.values(item).some((value) => {
|
||||
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
||||
})
|
||||
})
|
||||
return useSearch(searchString.value, items)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,17 +1,34 @@
|
||||
<script setup>
|
||||
import dayjs from "dayjs";
|
||||
import {useSupabaseSelectSingle} from "~/composables/useSupabase.js";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/vehicles")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
const openTab = ref(0)
|
||||
|
||||
let currentItem = ref(null)
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
@@ -59,18 +76,17 @@ const incomingInvoicesColumns = [
|
||||
]
|
||||
|
||||
//Functions
|
||||
const setupPage = () => {
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show" || mode.value === "edit"){
|
||||
currentItem.value = dataStore.getVehicleById(Number(useRoute().params.id))
|
||||
itemInfo.value = await useSupabaseSelectSingle("vehicles",route.params.id,"*")
|
||||
}
|
||||
|
||||
if(mode.value === "edit") itemInfo.value = currentItem.value
|
||||
if(currentItem.value) oldItemInfo.value = JSON.parse(JSON.stringify(currentItem.value))
|
||||
if(itemInfo.value) oldItemInfo.value = JSON.parse(JSON.stringify(itemInfo.value))
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(currentItem.value) {
|
||||
router.push(`/vehicles/show/${currentItem.value.id}`)
|
||||
if(itemInfo.value) {
|
||||
router.push(`/vehicles/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/vehicles`)
|
||||
}
|
||||
@@ -95,7 +111,7 @@ setupPage()
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar
|
||||
:title="currentItem ? currentItem.licensePlate : (mode === 'create' ? 'Fahrzeug erstellen' : 'Fahrzeug bearbeiten')"
|
||||
:title="itemInfo ? itemInfo.licensePlate : (mode === 'create' ? 'Fahrzeug erstellen' : 'Fahrzeug bearbeiten')"
|
||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||
>
|
||||
<template #left>
|
||||
@@ -109,9 +125,9 @@ setupPage()
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="currentItem"
|
||||
v-if="itemInfo"
|
||||
:class="['text-xl','font-medium']"
|
||||
>{{currentItem ? `Fahrzeug: ${currentItem.licensePlate}` : (mode === 'create' ? 'Fahrzeug erstellen' : 'Fahrzeug bearbeiten')}}</h1>
|
||||
>{{itemInfo ? `Fahrzeug: ${itemInfo.licensePlate}` : (mode === 'create' ? 'Fahrzeug erstellen' : 'Fahrzeug bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
@@ -136,7 +152,7 @@ setupPage()
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click="router.push(`/vehicles/edit/${currentItem.id}`)"
|
||||
@click="router.push(`/vehicles/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
@@ -144,19 +160,20 @@ setupPage()
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
:items="tabItems"
|
||||
v-if="mode === 'show'"
|
||||
v-if="mode === 'show' && itemInfo.id"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<UCard class="mt-5">
|
||||
<div class="truncate" v-if="item.label === 'Informationen'">
|
||||
<p>Typ: {{currentItem.type}}</p>
|
||||
<p>Fahrgestellnummer: {{currentItem.vin}}</p>
|
||||
<p>Fahrer: {{dataStore.profiles.find(profile => profile.id === currentItem.driver) ? dataStore.profiles.find(profile => profile.id === currentItem.driver).fullName : 'Kein Fahrer gewählt'}}</p>
|
||||
<p>Typ: {{itemInfo.type}}</p>
|
||||
<p>Fahrgestellnummer: {{itemInfo.vin}}</p>
|
||||
<p>Fahrer: {{dataStore.profiles.find(profile => profile.id === itemInfo.driver) ? dataStore.profiles.find(profile => profile.id === itemInfo.driver).fullName : 'Kein Fahrer gewählt'}}</p>
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Eingangsrechnungen'">
|
||||
<UTable
|
||||
:rows="dataStore.getIncomingInvoicesByVehicleId(currentItem.id)"
|
||||
:rows="dataStore.getIncomingInvoicesByVehicleId(itemInfo.id)"
|
||||
:columns="incomingInvoicesColumns"
|
||||
@select="(row) => router.push('/receipts/show/' + row.id)"
|
||||
>
|
||||
@@ -175,20 +192,20 @@ setupPage()
|
||||
<div v-else-if="item.label === 'Logbuch'">
|
||||
<HistoryDisplay
|
||||
type="vehicle"
|
||||
v-if="currentItem"
|
||||
:element-id="currentItem.id"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Dokumente'">
|
||||
<Toolbar>
|
||||
<DocumentUpload
|
||||
type="vehicle"
|
||||
:element-id="currentItem.id"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</Toolbar>
|
||||
|
||||
<DocumentList
|
||||
:documents="dataStore.getDocumentsByVehicleId(currentItem.id)"
|
||||
:documents="dataStore.getDocumentsByVehicleId(itemInfo.id)"
|
||||
/>
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
</USelectMenu>
|
||||
</template>
|
||||
</UDashboardToolbar>
|
||||
|
||||
<UTable
|
||||
:rows="filteredRows"
|
||||
:columns="columns"
|
||||
@@ -44,7 +43,10 @@
|
||||
@select="(i) => router.push(`/vehicles/show/${i.id}`) "
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Fahrzeuge anzuzeigen' }"
|
||||
>
|
||||
|
||||
<template #licensePlate-data="{row}">
|
||||
<span v-if="row === filteredRows[selectedItem]" class="font-bold text-primary-500">{{row.licensePlate}}</span>
|
||||
<span v-else>{{row.licensePlate}}</span>
|
||||
</template>
|
||||
</UTable>
|
||||
</template>
|
||||
|
||||
@@ -61,13 +63,42 @@ defineShortcuts({
|
||||
document.getElementById("searchinput").focus()
|
||||
},
|
||||
'+': () => {
|
||||
router.push("/tasks/create")
|
||||
router.push("/vehicles/create")
|
||||
},
|
||||
'Enter': {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
router.push(`/vehicles/show/${filteredRows.value[selectedItem.value].id}`)
|
||||
}
|
||||
},
|
||||
'arrowdown': () => {
|
||||
if(selectedItem.value < filteredRows.value.length - 1) {
|
||||
selectedItem.value += 1
|
||||
} else {
|
||||
selectedItem.value = 0
|
||||
}
|
||||
},
|
||||
'arrowup': () => {
|
||||
if(selectedItem.value === 0) {
|
||||
selectedItem.value = filteredRows.value.length - 1
|
||||
} else {
|
||||
selectedItem.value -= 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("vehicles","*")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const templateColumns = [
|
||||
{
|
||||
key: 'licensePlate',
|
||||
@@ -86,15 +117,7 @@ const columns = computed(() => templateColumns.filter((column) => selectedColumn
|
||||
const searchString = ref('')
|
||||
|
||||
const filteredRows = computed(() => {
|
||||
if(!searchString.value) {
|
||||
return dataStore.vehicles
|
||||
}
|
||||
|
||||
return dataStore.vehicles.filter(item => {
|
||||
return Object.values(item).some((value) => {
|
||||
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
||||
})
|
||||
})
|
||||
return useSearch(searchString.value, items.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
41
pages/vendors/index.vue
vendored
41
pages/vendors/index.vue
vendored
@@ -46,6 +46,10 @@
|
||||
@select="(i) => router.push(`/vendors/show/${i.id}`)"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Lieferanten anzuzeigen' }"
|
||||
>
|
||||
<template #name-data="{row}">
|
||||
<span v-if="row === filteredRows[selectedItem]" class="text-primary-500 font-bold">{{row.name}}</span>
|
||||
<span v-else>{{row.name}}</span>
|
||||
</template>
|
||||
<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>
|
||||
@@ -67,11 +71,17 @@ defineShortcuts({
|
||||
'+': () => {
|
||||
router.push("/vendors/create")
|
||||
},
|
||||
'enter': {
|
||||
usingInput: "searchinput",
|
||||
'Enter': {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
router.push(`/vendors/show/${selectedEntry.value}`)
|
||||
router.push(`/vendors/show/${filteredRows.value[selectedItem.value].id}`)
|
||||
}
|
||||
},
|
||||
'arrowdown': () => {
|
||||
selectedItem.value += 1
|
||||
},
|
||||
'arrowup': () => {
|
||||
selectedItem.value -= 1
|
||||
}
|
||||
})
|
||||
|
||||
@@ -79,6 +89,16 @@ const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
const mode = ref("show")
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("vendors","*","vendorNumber")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
|
||||
const templateColumns = [
|
||||
{
|
||||
key: 'vendorNumber',
|
||||
@@ -100,22 +120,9 @@ const selectedColumns = ref(templateColumns)
|
||||
const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
|
||||
|
||||
const searchString = ref('')
|
||||
const selectedEntry = ref(null)
|
||||
|
||||
const filteredRows = computed(() => {
|
||||
if(!searchString.value) {
|
||||
return dataStore.vendors
|
||||
}
|
||||
|
||||
let results = dataStore.vendors.filter(item => {
|
||||
return Object.values(item).some((value) => {
|
||||
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
||||
})
|
||||
})
|
||||
|
||||
selectedEntry.value = results[0].id
|
||||
|
||||
return results
|
||||
return useSearch(searchString.value, items.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -813,7 +813,12 @@ export const useDataStore = defineStore('data', () => {
|
||||
} else if (supabaseData) {
|
||||
console.log(supabaseData)
|
||||
await generateHistoryItems(dataType, supabaseData[0])
|
||||
//await eval( dataType + '.value.push(' + JSON.stringify(...supabaseData) + ')')
|
||||
|
||||
if(dataType !== "statementallocations"){
|
||||
await eval( dataType + '.value.push(' + JSON.stringify(...supabaseData) + ')')
|
||||
}
|
||||
|
||||
|
||||
toast.add({title: `${dataTypes[dataType].labelSingle} hinzugefügt`})
|
||||
if(dataTypes[dataType].redirect) await router.push(`/${dataType}/show/${supabaseData[0].id}`)
|
||||
return supabaseData
|
||||
@@ -1450,8 +1455,12 @@ export const useDataStore = defineStore('data', () => {
|
||||
|
||||
|
||||
//Get Item By Id
|
||||
const getProductById = computed(() => (itemId) => {
|
||||
return products.value.find(item => item.id === itemId)
|
||||
const getProductById = computed(() => async (itemId) => {
|
||||
|
||||
return await useSupabaseSelectSingle("products",itemId, "*")
|
||||
|
||||
|
||||
//return products.value.find(item => item.id === itemId)
|
||||
})
|
||||
|
||||
const getServiceById = computed(() => (itemId) => {
|
||||
|
||||
Reference in New Issue
Block a user