Changes in RLS and Tenants
Many Changes in Invoice Editor Page Loading Rebuilt Started Rights Management
This commit is contained in:
368
spaces/app.vue
368
spaces/app.vue
@@ -3,47 +3,20 @@
|
|||||||
|
|
||||||
|
|
||||||
import GlobalSearch from "~/components/GlobalSearch.vue";
|
import GlobalSearch from "~/components/GlobalSearch.vue";
|
||||||
|
const supabase = useSupabaseClient()
|
||||||
const user = useSupabaseUser()
|
const user = useSupabaseUser()
|
||||||
//console.log(user.value)
|
//console.log(user.value)
|
||||||
const router = useRouter()
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const colorMode = useColorMode()
|
|
||||||
const supabase = useSupabaseClient()
|
|
||||||
const tenants = (await supabase.from("tenants").select()).data
|
const tenants = (await supabase.from("tenants").select()).data
|
||||||
|
|
||||||
|
|
||||||
const dataStore = useDataStore()
|
const dataStore = useDataStore()
|
||||||
|
|
||||||
const isLight = computed({
|
|
||||||
get () {
|
|
||||||
return colorMode.value !== 'dark'
|
|
||||||
},
|
|
||||||
set () {
|
|
||||||
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const userProfile = (user.value ? dataStore.getProfileById(user.value.id) : {})
|
|
||||||
//console.log(userProfile)
|
//console.log(userProfile)
|
||||||
|
|
||||||
const showUserMenu = ref(false)
|
|
||||||
const userMenuItems = ref([
|
|
||||||
{
|
|
||||||
label: "Profil",
|
|
||||||
badge: dataStore.notifications.filter(item => item.read).length,
|
|
||||||
icon: "i-heroicons-user-20-solid"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Nummernkreise",
|
|
||||||
icon: "i-heroicons-cog-8-tooth",
|
|
||||||
to: "/settings/numberRanges"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Benutzer',
|
|
||||||
icon: 'i-heroicons-user-group',
|
|
||||||
to: "/users"
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -56,151 +29,9 @@ watch(viewport.breakpoint, (newBreakpoint, oldBreakpoint) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
dataStore.fetchData()
|
dataStore.initializeData()
|
||||||
|
|
||||||
|
|
||||||
const navLinks = [
|
|
||||||
{
|
|
||||||
label: "Home",
|
|
||||||
to: "/",
|
|
||||||
icon: 'i-heroicons-home'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Kontakte",
|
|
||||||
icon: 'i-heroicons-user-group',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
label: "Kunden",
|
|
||||||
to: "/customers",
|
|
||||||
icon: "i-heroicons-user-group"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Lieferanten",
|
|
||||||
to: "/vendors",
|
|
||||||
icon: "i-heroicons-truck"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Ansprechpartner",
|
|
||||||
to: "/contacts",
|
|
||||||
icon: "i-heroicons-user-group"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Buchhaltung",
|
|
||||||
icon: 'i-heroicons-document-chart-bar',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
label: "Eingangsrechnungen",
|
|
||||||
to: "/incominginvoices",
|
|
||||||
icon: "i-heroicons-document-text"
|
|
||||||
},
|
|
||||||
/*{
|
|
||||||
label: "Ausgangsrechnungen",
|
|
||||||
to: "/customerinvoices",
|
|
||||||
icon: "i-heroicons-document-text"
|
|
||||||
},*/
|
|
||||||
{
|
|
||||||
label: "Bank",
|
|
||||||
to: "/banking",
|
|
||||||
icon: "i-heroicons-currency-euro"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Aufträge",
|
|
||||||
icon: "i-heroicons-square-3-stack-3d",
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
label: "Projekte",
|
|
||||||
to: "/projects",
|
|
||||||
icon: "i-heroicons-clipboard-document-check"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Verträge",
|
|
||||||
to: "/contracts",
|
|
||||||
icon: "i-heroicons-clipboard-document"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Objekte",
|
|
||||||
to: "/plants",
|
|
||||||
icon: "i-heroicons-clipboard-document"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Verwaltung",
|
|
||||||
icon: "i-heroicons-square-3-stack-3d",
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
label: "Aufgaben",
|
|
||||||
to: "/tasks",
|
|
||||||
icon: "i-heroicons-rectangle-stack"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Plantafel",
|
|
||||||
to: "/calendar/timeline",
|
|
||||||
icon: "i-heroicons-calendar-days"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Kalender",
|
|
||||||
to: "/calendar/grid",
|
|
||||||
icon: "i-heroicons-calendar-days"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Dokumente",
|
|
||||||
to: "/documents",
|
|
||||||
icon: "i-heroicons-document"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Chat",
|
|
||||||
to: "/chat",
|
|
||||||
icon:'i-heroicons-chat-bubble-left-right'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Mitarbeiter",
|
|
||||||
icon: 'i-heroicons-user',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
label: "Zeiterfassung",
|
|
||||||
to: "/employees/timetracking",
|
|
||||||
icon: "i-heroicons-clock"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Abwesenheiten",
|
|
||||||
to: "/absenceRequests",
|
|
||||||
icon: "i-heroicons-document-text"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Lager",
|
|
||||||
icon: 'i-heroicons-home',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
label: "Steuerung",
|
|
||||||
to: "/inventory",
|
|
||||||
icon: "i-heroicons-square-3-stack-3d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Artikelstamm",
|
|
||||||
to: "/products",
|
|
||||||
icon: "i-heroicons-puzzle-piece"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Lagerplätze",
|
|
||||||
to: "/spaces",
|
|
||||||
icon: "i-heroicons-square-3-stack-3d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Fahrzeuge",
|
|
||||||
to: "/vehicles",
|
|
||||||
icon: "i-heroicons-truck"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
const linksForBreadcrumbs = ref([])
|
const linksForBreadcrumbs = ref([])
|
||||||
|
|
||||||
@@ -209,8 +40,8 @@ const linksForBreadcrumbs = ref([])
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const userTenant = ref({})
|
//const userTenant = ref({})
|
||||||
if(user) userTenant.value = tenants.find(tenant => tenant.id === user.value.app_metadata.tenant)
|
//if(user) userTenant.value = tenants.find(tenant => tenant.id === user.value.app_metadata.tenant)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -275,189 +106,10 @@ const items = [
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<UHeader :links="navLinks" :to="null">
|
|
||||||
<template #logo>
|
|
||||||
<div id="logo">
|
|
||||||
<img
|
|
||||||
:src="!isLight ? '/spaces.svg' : '/spaces_hell.svg'"
|
|
||||||
alt="Logo"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #panel>
|
|
||||||
<UNavigationTree :links="navLinks"/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #right>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- <ClientOnly>
|
|
||||||
<UButton
|
|
||||||
:icon="!isLight ? 'i-heroicons-moon-20-solid' : 'i-heroicons-sun-20-solid'"
|
|
||||||
color="gray"
|
|
||||||
variant="ghost"
|
|
||||||
aria-label="Theme"
|
|
||||||
@click="isLight = !isLight"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<template #fallback>
|
|
||||||
<div class="w-8 h-8" />
|
|
||||||
</template>
|
|
||||||
</ClientOnly>-->
|
|
||||||
<GlobalSearch/>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- <UPopover :popper="{placement: 'bottom-start'}">
|
|
||||||
<ClientOnly>
|
|
||||||
<UChip
|
|
||||||
:show="dataStore.notifications.filter(notification => !notification.read).length > 0"
|
|
||||||
inset
|
|
||||||
>
|
|
||||||
<UButton
|
|
||||||
icon="i-heroicons-envelope-20-solid"
|
|
||||||
variant="ghost"
|
|
||||||
color="gray"
|
|
||||||
class="mx-2"
|
|
||||||
/>
|
|
||||||
</UChip>
|
|
||||||
|
|
||||||
<template #fallback>
|
|
||||||
<div class="w-8 h-8" />
|
|
||||||
</template>
|
|
||||||
</ClientOnly>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<template #panel>
|
|
||||||
<div class="w-60 p-3">
|
|
||||||
|
|
||||||
<UAlert
|
|
||||||
class="mb-3"
|
|
||||||
v-for="(notification,index) in dataStore.notifications"
|
|
||||||
:color="!notification.read ? 'primary' : 'grey'"
|
|
||||||
variant="outline"
|
|
||||||
:description="notification.text"
|
|
||||||
:title="notification.title"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</UPopover>-->
|
|
||||||
<UButton
|
|
||||||
@click="showUserMenu = true"
|
|
||||||
variant="ghost"
|
|
||||||
color="gray"
|
|
||||||
>
|
|
||||||
<UAvatar
|
|
||||||
:alt="userProfile ? userProfile.firstName + ' ' + userProfile.lastName : '' "
|
|
||||||
icon="i-heroicons-user-20-solid"
|
|
||||||
:chip-color="dataStore.notifications.filter(item => !item.read).length > 0 ? 'primary' : null"
|
|
||||||
|
|
||||||
/>
|
|
||||||
</UButton>
|
|
||||||
|
|
||||||
<USlideover
|
|
||||||
v-model="showUserMenu"
|
|
||||||
>
|
|
||||||
<UCard
|
|
||||||
class="h-full"
|
|
||||||
>
|
|
||||||
|
|
||||||
<UDivider
|
|
||||||
class="my-3"
|
|
||||||
label="Menü"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<UVerticalNavigation
|
|
||||||
:links="userMenuItems"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<UDivider
|
|
||||||
class="my-3"
|
|
||||||
label="Benachrichtigungen"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<UAlert
|
|
||||||
class="mb-3"
|
|
||||||
v-for="(notification) in dataStore.notifications"
|
|
||||||
:color="!notification.read ? 'primary' : 'white'"
|
|
||||||
:variant="!notification.read ? 'outline' : 'soft'"
|
|
||||||
:description="notification.text"
|
|
||||||
:title="notification.title"
|
|
||||||
:close-button="!notification.read ? { icon: 'i-heroicons-x-mark-20-solid', color: 'gray', variant: 'link', padded: false } : null"
|
|
||||||
@close="async () => {
|
|
||||||
const {error} = await supabase.from('notifications').update({read:true}).eq('id', notification.id)
|
|
||||||
if(error) console.log(error)
|
|
||||||
dataStore.fetchNotifications()
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<InputGroup>
|
|
||||||
<UButton
|
|
||||||
:icon="!isLight ? 'i-heroicons-moon-20-solid' : 'i-heroicons-sun-20-solid'"
|
|
||||||
color="white"
|
|
||||||
variant="outline"
|
|
||||||
aria-label="Theme"
|
|
||||||
@click="isLight = !isLight"
|
|
||||||
/>
|
|
||||||
<UButton
|
|
||||||
color="rose"
|
|
||||||
variant="outline"
|
|
||||||
@click="async () => {
|
|
||||||
showUserMenu = false
|
|
||||||
await supabase.auth.signOut()
|
|
||||||
await dataStore.clearStore()
|
|
||||||
await router.push('/login')
|
|
||||||
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
Ausloggen
|
|
||||||
</UButton>
|
|
||||||
</InputGroup>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
</UCard>
|
|
||||||
</USlideover>
|
|
||||||
<!-- <UDropdown :items="items" :ui="{ item: { disabled: 'cursor-text select-text' } }" :popper="{ placement: 'bottom-start' }">
|
|
||||||
<UAvatar
|
|
||||||
:alt="userProfile ? userProfile.firstName + ' ' + userProfile.lastName : '' "
|
|
||||||
icon="i-heroicons-user-20-solid"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<template #account="{ item }">
|
|
||||||
<div class="text-left">
|
|
||||||
<p>
|
|
||||||
Eingeloggt als
|
|
||||||
</p>
|
|
||||||
<p class="truncate font-medium text-gray-900 dark:text-white">
|
|
||||||
{{ item.label }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #item="{ item }">
|
|
||||||
<span class="truncate">{{ item.label }}</span>
|
|
||||||
|
|
||||||
<UIcon :name="item.icon" class="flex-shrink-0 h-4 w-4 text-gray-400 dark:text-gray-500 ms-auto" />
|
|
||||||
</template>
|
|
||||||
</UDropdown>-->
|
|
||||||
</template>
|
|
||||||
</UHeader>
|
|
||||||
<UDivider />
|
|
||||||
<div class="m-3" id="contentContainer">
|
|
||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
<NuxtPage/>
|
<NuxtPage/>
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<!-- <UFooter>
|
<!-- <UFooter>
|
||||||
<template #left>
|
<template #left>
|
||||||
<p class="text-gray-500 dark:text-gray-400 text-sm">
|
<p class="text-gray-500 dark:text-gray-400 text-sm">
|
||||||
@@ -472,11 +124,9 @@ const items = [
|
|||||||
</template>
|
</template>
|
||||||
</UFooter>-->
|
</UFooter>-->
|
||||||
|
|
||||||
|
|
||||||
<UNotifications/>
|
<UNotifications/>
|
||||||
<VitePwaManifest/>
|
<VitePwaManifest/>
|
||||||
|
|
||||||
|
|
||||||
<!-- <UCard id="page">
|
<!-- <UCard id="page">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div id="menu">
|
<div id="menu">
|
||||||
@@ -490,7 +140,7 @@ const items = [
|
|||||||
<!–<router-link to="/customers" class="mr-2"><UButton>Kunden</UButton></router-link>
|
<!–<router-link to="/customers" class="mr-2"><UButton>Kunden</UButton></router-link>
|
||||||
<router-link to="/projects" class="mr-2"><UButton>Projekte</UButton></router-link>
|
<router-link to="/projects" class="mr-2"><UButton>Projekte</UButton></router-link>
|
||||||
-
|
-
|
||||||
<router-link to="/incominginvoices" class="mr-2"><UButton>Eingangsrechnungen</UButton></router-link>
|
<router-link to="/receipts" class="mr-2"><UButton>Eingangsrechnungen</UButton></router-link>
|
||||||
|
|
||||||
<router-link to="/timetracking" class="mr-2"><UButton>Zeiterfassung</UButton></router-link>
|
<router-link to="/timetracking" class="mr-2"><UButton>Zeiterfassung</UButton></router-link>
|
||||||
<router-link to="/products" class="mr-2"><UButton>Artikel</UButton></router-link>
|
<router-link to="/products" class="mr-2"><UButton>Artikel</UButton></router-link>
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ const createVendorInvoice = async () => {
|
|||||||
|
|
||||||
|
|
||||||
dataStore.fetchIncomingInvoices()
|
dataStore.fetchIncomingInvoices()
|
||||||
await router.push("/incominginvoices")
|
await router.push("/receipts")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,388 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
|
||||||
const dataStore = useDataStore()
|
const dataStore = useDataStore()
|
||||||
|
const colorMode = useColorMode()
|
||||||
|
|
||||||
|
const userProfile = dataStore.getOwnProfile
|
||||||
|
const supabase = useSupabaseClient()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
|
||||||
|
const isLight = computed({
|
||||||
|
get () {
|
||||||
|
return colorMode.value !== 'dark'
|
||||||
|
},
|
||||||
|
set () {
|
||||||
|
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const navLinks = [
|
||||||
|
{
|
||||||
|
label: "Home",
|
||||||
|
to: "/",
|
||||||
|
icon: 'i-heroicons-home'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Kontakte",
|
||||||
|
icon: 'i-heroicons-user-group',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: "Kunden",
|
||||||
|
to: "/customers",
|
||||||
|
icon: "i-heroicons-user-group"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Lieferanten",
|
||||||
|
to: "/vendors",
|
||||||
|
icon: "i-heroicons-truck"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Ansprechpartner",
|
||||||
|
to: "/contacts",
|
||||||
|
icon: "i-heroicons-user-group"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Buchhaltung",
|
||||||
|
icon: 'i-heroicons-document-chart-bar',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: "Belege",
|
||||||
|
to: "/receipts",
|
||||||
|
icon: "i-heroicons-document-text"
|
||||||
|
},
|
||||||
|
/*{
|
||||||
|
label: "Ausgangsrechnungen",
|
||||||
|
to: "/customerinvoices",
|
||||||
|
icon: "i-heroicons-document-text"
|
||||||
|
},*/
|
||||||
|
{
|
||||||
|
label: "Bank",
|
||||||
|
to: "/banking",
|
||||||
|
icon: "i-heroicons-currency-euro"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Aufträge",
|
||||||
|
icon: "i-heroicons-square-3-stack-3d",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: "Projekte",
|
||||||
|
to: "/projects",
|
||||||
|
icon: "i-heroicons-clipboard-document-check"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Verträge",
|
||||||
|
to: "/contracts",
|
||||||
|
icon: "i-heroicons-clipboard-document"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Objekte",
|
||||||
|
to: "/plants",
|
||||||
|
icon: "i-heroicons-clipboard-document"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Verwaltung",
|
||||||
|
icon: "i-heroicons-square-3-stack-3d",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: "Aufgaben",
|
||||||
|
to: "/tasks",
|
||||||
|
icon: "i-heroicons-rectangle-stack"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Plantafel",
|
||||||
|
to: "/calendar/timeline",
|
||||||
|
icon: "i-heroicons-calendar-days"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Kalender",
|
||||||
|
to: "/calendar/grid",
|
||||||
|
icon: "i-heroicons-calendar-days"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Dokumente",
|
||||||
|
to: "/documents",
|
||||||
|
icon: "i-heroicons-document"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Chat",
|
||||||
|
to: "/chat",
|
||||||
|
icon:'i-heroicons-chat-bubble-left-right'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Mitarbeiter",
|
||||||
|
icon: 'i-heroicons-user',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: "Zeiterfassung",
|
||||||
|
to: "/employees/timetracking",
|
||||||
|
icon: "i-heroicons-clock"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Abwesenheiten",
|
||||||
|
to: "/absenceRequests",
|
||||||
|
icon: "i-heroicons-document-text"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Lager",
|
||||||
|
icon: 'i-heroicons-home',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: "Steuerung",
|
||||||
|
to: "/inventory",
|
||||||
|
icon: "i-heroicons-square-3-stack-3d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Artikelstamm",
|
||||||
|
to: "/products",
|
||||||
|
icon: "i-heroicons-puzzle-piece"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Lagerplätze",
|
||||||
|
to: "/spaces",
|
||||||
|
icon: "i-heroicons-square-3-stack-3d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Fahrzeuge",
|
||||||
|
to: "/vehicles",
|
||||||
|
icon: "i-heroicons-truck"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const showUserMenu = ref(false)
|
||||||
|
const userMenuItems = ref([
|
||||||
|
{
|
||||||
|
label: "Profil",
|
||||||
|
badge: dataStore.notifications.filter(item => item.read).length,
|
||||||
|
icon: "i-heroicons-user-20-solid"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Nummernkreise",
|
||||||
|
icon: "i-heroicons-cog-8-tooth",
|
||||||
|
to: "/settings/numberRanges"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Benutzer',
|
||||||
|
icon: 'i-heroicons-user-group',
|
||||||
|
to: "/users"
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<div v-if="dataStore.loaded">
|
||||||
|
<UHeader :links="navLinks" :to="null">
|
||||||
|
<template #logo>
|
||||||
|
<div id="logo">
|
||||||
|
<img
|
||||||
|
:src="!isLight ? '/spaces.svg' : '/spaces_hell.svg'"
|
||||||
|
alt="Logo"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #panel>
|
||||||
|
<UNavigationTree :links="navLinks"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #right>
|
||||||
|
|
||||||
|
|
||||||
<slot v-if="dataStore.loaded"/>
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <ClientOnly>
|
||||||
|
<UButton
|
||||||
|
:icon="!isLight ? 'i-heroicons-moon-20-solid' : 'i-heroicons-sun-20-solid'"
|
||||||
|
color="gray"
|
||||||
|
variant="ghost"
|
||||||
|
aria-label="Theme"
|
||||||
|
@click="isLight = !isLight"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<template #fallback>
|
||||||
|
<div class="w-8 h-8" />
|
||||||
|
</template>
|
||||||
|
</ClientOnly>-->
|
||||||
|
<GlobalSearch/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <UPopover :popper="{placement: 'bottom-start'}">
|
||||||
|
<ClientOnly>
|
||||||
|
<UChip
|
||||||
|
:show="dataStore.notifications.filter(notification => !notification.read).length > 0"
|
||||||
|
inset
|
||||||
|
>
|
||||||
|
<UButton
|
||||||
|
icon="i-heroicons-envelope-20-solid"
|
||||||
|
variant="ghost"
|
||||||
|
color="gray"
|
||||||
|
class="mx-2"
|
||||||
|
/>
|
||||||
|
</UChip>
|
||||||
|
|
||||||
|
<template #fallback>
|
||||||
|
<div class="w-8 h-8" />
|
||||||
|
</template>
|
||||||
|
</ClientOnly>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<template #panel>
|
||||||
|
<div class="w-60 p-3">
|
||||||
|
|
||||||
|
<UAlert
|
||||||
|
class="mb-3"
|
||||||
|
v-for="(notification,index) in dataStore.notifications"
|
||||||
|
:color="!notification.read ? 'primary' : 'grey'"
|
||||||
|
variant="outline"
|
||||||
|
:description="notification.text"
|
||||||
|
:title="notification.title"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</UPopover>-->
|
||||||
|
<UButton
|
||||||
|
@click="showUserMenu = true"
|
||||||
|
variant="ghost"
|
||||||
|
color="gray"
|
||||||
|
>
|
||||||
|
<UAvatar
|
||||||
|
:alt="userProfile ? userProfile.firstName + ' ' + userProfile.lastName : '' "
|
||||||
|
icon="i-heroicons-user-20-solid"
|
||||||
|
:chip-color="dataStore.notifications.filter(item => !item.read).length > 0 ? 'primary' : null"
|
||||||
|
|
||||||
|
/>
|
||||||
|
</UButton>
|
||||||
|
|
||||||
|
<USlideover
|
||||||
|
v-model="showUserMenu"
|
||||||
|
>
|
||||||
|
<UCard
|
||||||
|
class="h-full"
|
||||||
|
>
|
||||||
|
|
||||||
|
<UDivider
|
||||||
|
class="my-3"
|
||||||
|
label="Tenant"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<USelectMenu
|
||||||
|
:options="dataStore.getOwnProfile.tenants"
|
||||||
|
option-attribute="name"
|
||||||
|
value-attribute="id"
|
||||||
|
v-model="dataStore.currentTenant"
|
||||||
|
@change="dataStore.changeTenant()"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<UDivider
|
||||||
|
class="my-3"
|
||||||
|
label="Menü"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<UVerticalNavigation
|
||||||
|
:links="userMenuItems"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<UDivider
|
||||||
|
class="my-3"
|
||||||
|
label="Benachrichtigungen"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<UAlert
|
||||||
|
class="mb-3"
|
||||||
|
v-for="(notification) in dataStore.notifications"
|
||||||
|
:color="!notification.read ? 'primary' : 'white'"
|
||||||
|
:variant="!notification.read ? 'outline' : 'soft'"
|
||||||
|
:description="notification.text"
|
||||||
|
:title="notification.title"
|
||||||
|
:close-button="!notification.read ? { icon: 'i-heroicons-x-mark-20-solid', color: 'gray', variant: 'link', padded: false } : null"
|
||||||
|
@close="async () => {
|
||||||
|
const {error} = await supabase.from('notifications').update({read:true}).eq('id', notification.id)
|
||||||
|
if(error) console.log(error)
|
||||||
|
dataStore.fetchNotifications()
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<InputGroup>
|
||||||
|
<UButton
|
||||||
|
:icon="!isLight ? 'i-heroicons-moon-20-solid' : 'i-heroicons-sun-20-solid'"
|
||||||
|
color="white"
|
||||||
|
variant="outline"
|
||||||
|
aria-label="Theme"
|
||||||
|
@click="isLight = !isLight"
|
||||||
|
/>
|
||||||
|
<UButton
|
||||||
|
color="rose"
|
||||||
|
variant="outline"
|
||||||
|
@click="async () => {
|
||||||
|
showUserMenu = false
|
||||||
|
await supabase.auth.signOut()
|
||||||
|
await dataStore.clearStore()
|
||||||
|
await router.push('/login')
|
||||||
|
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
Ausloggen
|
||||||
|
</UButton>
|
||||||
|
</InputGroup>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</UCard>
|
||||||
|
</USlideover>
|
||||||
|
<!-- <UDropdown :items="items" :ui="{ item: { disabled: 'cursor-text select-text' } }" :popper="{ placement: 'bottom-start' }">
|
||||||
|
<UAvatar
|
||||||
|
:alt="userProfile ? userProfile.firstName + ' ' + userProfile.lastName : '' "
|
||||||
|
icon="i-heroicons-user-20-solid"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<template #account="{ item }">
|
||||||
|
<div class="text-left">
|
||||||
|
<p>
|
||||||
|
Eingeloggt als
|
||||||
|
</p>
|
||||||
|
<p class="truncate font-medium text-gray-900 dark:text-white">
|
||||||
|
{{ item.label }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #item="{ item }">
|
||||||
|
<span class="truncate">{{ item.label }}</span>
|
||||||
|
|
||||||
|
<UIcon :name="item.icon" class="flex-shrink-0 h-4 w-4 text-gray-400 dark:text-gray-500 ms-auto" />
|
||||||
|
</template>
|
||||||
|
</UDropdown>-->
|
||||||
|
</template>
|
||||||
|
</UHeader>
|
||||||
|
<UDivider />
|
||||||
|
<div class="m-3" id="contentContainer">
|
||||||
|
<slot/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
|
class="flex-col mx-auto my-auto mt-10 w-3/4"
|
||||||
>
|
>
|
||||||
<UProgress animation="carousel" />
|
<img src="/spaces.svg" class="w-1/3 mx-auto"/>
|
||||||
|
<UProgress animation="carousel" class=" " />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,11 @@
|
|||||||
import dayjs from "dayjs"
|
import dayjs from "dayjs"
|
||||||
const dataStore = useDataStore()
|
const dataStore = useDataStore()
|
||||||
const user = useSupabaseUser()
|
const user = useSupabaseUser()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const tabItems = [
|
const tabItems = [
|
||||||
{
|
{
|
||||||
@@ -13,52 +18,46 @@ const tabItems = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const itemInfo = ref({
|
const itemInfo = ref({
|
||||||
customer: 13,
|
type: "invoices",
|
||||||
contact: 8,
|
customer: null,
|
||||||
|
contact: null,
|
||||||
address: {
|
address: {
|
||||||
street: null,
|
street: null,
|
||||||
special: null,
|
special: null,
|
||||||
zip: null,
|
zip: null,
|
||||||
city: null,
|
city: null,
|
||||||
},
|
},
|
||||||
project: 6,
|
project: null,
|
||||||
documentNumber: "RE23-1409",
|
documentNumber: null,
|
||||||
documentDate: "10.01.2024",
|
documentDate: null,
|
||||||
deliveryDate: "10.01.2024",
|
deliveryDate: null,
|
||||||
dateOfPerformance: null,
|
dateOfPerformance: null,
|
||||||
createdBy: user.value.id,
|
createdBy: user.value.id,
|
||||||
title: "TITEL",
|
title: null,
|
||||||
description: "BESCHREIBUNG",
|
description: null,
|
||||||
startText: "Sehr geehrte Frau Sindern,\n" +
|
startText: "Sehr geehrte Frau Sindern,\n" +
|
||||||
"wir bedanken uns für Ihr entgegengebrachtes Vertrauen und Ihren Auftrag und stellen Ihnen\n" +
|
"wir bedanken uns für Ihr entgegengebrachtes Vertrauen und Ihren Auftrag und stellen Ihnen\n" +
|
||||||
"folgende Positionen in Rechnung: ",
|
"folgende Positionen in Rechnung: ",
|
||||||
endText: "Bitte überweisen Sie den Rechnungsbetrag unter Angabe der Rechnungsnummer im Verwendungszweck innerhalb von 10 Tagen auf das unten angegebene Konto. Wir bedanken uns für das entgegengebrachte Vertrauen und freuen uns auf eine weitere gute Zusammenarbeit.",
|
endText: "Bitte überweisen Sie den Rechnungsbetrag unter Angabe der Rechnungsnummer im Verwendungszweck innerhalb von 10 Tagen auf das unten angegebene Konto. Wir bedanken uns für das entgegengebrachte Vertrauen und freuen uns auf eine weitere gute Zusammenarbeit.",
|
||||||
rows: [
|
rows: [
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
pos: 1,
|
|
||||||
mode: "free",
|
|
||||||
text: "FahrtkostenFahrtkostenFahrtkostenFahrtkosten",
|
|
||||||
quantity: 204,
|
|
||||||
unit: 3,
|
|
||||||
price: 0.80,
|
|
||||||
taxPercent: 19,
|
|
||||||
discountPercent: 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
pos: 2,
|
|
||||||
mode: "free",
|
|
||||||
text: "Test",
|
|
||||||
quantity: 1,
|
|
||||||
unit: 1,
|
|
||||||
price: 10,
|
|
||||||
taxPercent: 19,
|
|
||||||
discountPercent: 0
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const setupPage = () => {
|
||||||
|
if(route.params) {
|
||||||
|
if(route.params.id) itemInfo.value = dataStore.getCreatedDocumentById(Number(route.params.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
if(route.query) {
|
||||||
|
if(route.query.type) itemInfo.value.type = route.query.type
|
||||||
|
if(route.query.project) itemInfo.value.project = Number(route.query.project)
|
||||||
|
if(route.query.customer) itemInfo.value.customer = Number(route.query.customer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const getRowAmount = (row) => {
|
const getRowAmount = (row) => {
|
||||||
return String(Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) /100) ).toFixed(2)).replace('.',',')
|
return String(Number(Number(row.quantity) * Number(row.price) * (1 - Number(row.discountPercent) /100) ).toFixed(2)).replace('.',',')
|
||||||
}
|
}
|
||||||
@@ -218,7 +217,6 @@ const generateDocument = async () => {
|
|||||||
uri.value = await useCreatePdf(getDocumentData())
|
uri.value = await useCreatePdf(getDocumentData())
|
||||||
//alert(uri.value)
|
//alert(uri.value)
|
||||||
showDocument.value = true
|
showDocument.value = true
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const onChangeTab = (index) => {
|
const onChangeTab = (index) => {
|
||||||
@@ -238,20 +236,80 @@ const setPosNumbers = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const saveDocument = async () => {
|
||||||
|
let createData = {
|
||||||
|
type: itemInfo.value.type,
|
||||||
|
customer: itemInfo.value.customer,
|
||||||
|
contact: itemInfo.value.contact,
|
||||||
|
address: itemInfo.value.address,
|
||||||
|
project: itemInfo.value.project,
|
||||||
|
documentNumber: itemInfo.value.documentNumber,
|
||||||
|
documentDate: itemInfo.value.documentDate,
|
||||||
|
state: "Entwurf",
|
||||||
|
info: {
|
||||||
|
|
||||||
|
},
|
||||||
|
createdBy: itemInfo.value.createdBy,
|
||||||
|
title: itemInfo.value.title,
|
||||||
|
description: itemInfo.value.description,
|
||||||
|
startText: itemInfo.value.startText,
|
||||||
|
endText: itemInfo.value.endText,
|
||||||
|
rows: itemInfo.value.rows
|
||||||
|
}
|
||||||
|
|
||||||
|
if(route.params.id) {
|
||||||
|
await dataStore.updateItem("createdDocuments", {...createData, id: itemInfo.value.id})
|
||||||
|
} else {
|
||||||
|
await dataStore.createNewItem("createdDocuments", createData)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeDocument = () => {
|
||||||
|
generateDocument()
|
||||||
|
console.log(uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setupPage()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- <UButton
|
|
||||||
@click="createPdf"
|
|
||||||
>TEST</UButton>-->
|
|
||||||
<UCard class="h-fit">
|
<UCard class="h-fit">
|
||||||
|
<InputGroup class="mb-3">
|
||||||
|
<UButton
|
||||||
|
icon="i-mdi-content-save"
|
||||||
|
@click="saveDocument"
|
||||||
|
>
|
||||||
|
Entwurf
|
||||||
|
</UButton>
|
||||||
|
<UButton
|
||||||
|
@click="closeDocument"
|
||||||
|
>
|
||||||
|
Fertigstellen
|
||||||
|
</UButton>
|
||||||
|
</InputGroup>
|
||||||
<UTabs :items="tabItems" @change="onChangeTab">
|
<UTabs :items="tabItems" @change="onChangeTab">
|
||||||
<template #item="{item}">
|
<template #item="{item}">
|
||||||
<div v-if="item.label === 'Editor'">
|
<div v-if="item.label === 'Editor'">
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<div class="flex-auto mr-5">
|
<div class="flex-auto mr-5">
|
||||||
|
<UFormGroup
|
||||||
|
label="Dokumenttyp:"
|
||||||
|
>
|
||||||
|
<USelectMenu
|
||||||
|
:options="Object.keys(dataStore.documentTypesForCreation).map(i => {return {label: dataStore.documentTypesForCreation[i].labelSingle, type: i }})"
|
||||||
|
v-model="itemInfo.type"
|
||||||
|
value-attribute="type"
|
||||||
|
option-attribute="label"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
{{dataStore.documentTypesForCreation[itemInfo.type].labelSingle}}
|
||||||
|
</template>
|
||||||
|
</USelectMenu>
|
||||||
|
</UFormGroup>
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="Kunde:"
|
label="Kunde:"
|
||||||
>
|
>
|
||||||
@@ -324,6 +382,7 @@ const setPosNumbers = () => {
|
|||||||
>
|
>
|
||||||
<UInput
|
<UInput
|
||||||
v-model="itemInfo.documentNumber"
|
v-model="itemInfo.documentNumber"
|
||||||
|
placeholder="Leer lassen für automatisch generierte Nummer"
|
||||||
/>
|
/>
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
@@ -735,27 +794,6 @@ const setPosNumbers = () => {
|
|||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td class="font-bold">Netto:</td>
|
|
||||||
<td>{{documentTotal.totalNet}}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="font-bold">zzgl. 19 % USt:</td>
|
|
||||||
<td>{{documentTotal.total19}}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="font-bold">Brutto:</td>
|
|
||||||
<td>{{documentTotal.totalGross}}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<UButton
|
<UButton
|
||||||
@click="addPosition('normal')"
|
@click="addPosition('normal')"
|
||||||
@@ -777,6 +815,21 @@ const setPosNumbers = () => {
|
|||||||
</UButton>
|
</UButton>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td class="font-bold">Netto:</td>
|
||||||
|
<td>{{documentTotal.totalNet}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="font-bold">zzgl. 19 % USt:</td>
|
||||||
|
<td>{{documentTotal.total19}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="font-bold">Brutto:</td>
|
||||||
|
<td>{{documentTotal.totalGross}}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<UDivider
|
<UDivider
|
||||||
@@ -797,7 +850,6 @@ const setPosNumbers = () => {
|
|||||||
>
|
>
|
||||||
Show
|
Show
|
||||||
</UButton>-->
|
</UButton>-->
|
||||||
|
|
||||||
<object
|
<object
|
||||||
:data="uri"
|
:data="uri"
|
||||||
v-if="showDocument"
|
v-if="showDocument"
|
||||||
25
spaces/pages/createDocument/show/[id].vue
Normal file
25
spaces/pages/createDocument/show/[id].vue
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<script setup>
|
||||||
|
|
||||||
|
const dataStore = useDataStore()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
const itemInfo = ref({})
|
||||||
|
|
||||||
|
const setupPage = () => {
|
||||||
|
if(route.params) {
|
||||||
|
if(route.params.id) itemInfo.value = dataStore.getCreatedDocumentById(Number(route.params.id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setupPage()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
|
||||||
|
{{itemInfo}}
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -12,11 +12,24 @@ const {fetchData} = useDataStore()
|
|||||||
const email = ref("")
|
const email = ref("")
|
||||||
const password = ref("")
|
const password = ref("")
|
||||||
|
|
||||||
|
const fields = [{
|
||||||
|
name: 'email',
|
||||||
|
type: 'text',
|
||||||
|
label: 'Email',
|
||||||
|
placeholder: 'E-Mail Adresse'
|
||||||
|
}, {
|
||||||
|
name: 'password',
|
||||||
|
label: 'Password',
|
||||||
|
type: 'password',
|
||||||
|
placeholder: 'Passwort'
|
||||||
|
}]
|
||||||
|
|
||||||
|
|
||||||
|
const onSubmit = async (data) => {
|
||||||
|
|
||||||
const onSubmit = async () => {
|
|
||||||
const { error } = await supabase.auth.signInWithPassword({
|
const { error } = await supabase.auth.signInWithPassword({
|
||||||
email: email.value,
|
email: data.email,
|
||||||
password: password.value
|
password: data.password
|
||||||
})
|
})
|
||||||
if(error) {
|
if(error) {
|
||||||
console.log(error.toString())
|
console.log(error.toString())
|
||||||
@@ -33,7 +46,7 @@ const onSubmit = async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div id="loginSite">
|
<!-- <div id="loginSite">
|
||||||
<div id="loginForm">
|
<div id="loginForm">
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="E-Mail:"
|
label="E-Mail:"
|
||||||
@@ -59,7 +72,23 @@ const onSubmit = async () => {
|
|||||||
</UButton>
|
</UButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>-->
|
||||||
|
<UCard class="max-w-sm w-full mx-auto mt-5">
|
||||||
|
<UAuthForm
|
||||||
|
title="Login"
|
||||||
|
description="Geben Sie Ihre Anmeldedaten ein um Zugriff auf Ihren Account zu bekommen"
|
||||||
|
align="bottom"
|
||||||
|
icon="i-heroicons-user-circle"
|
||||||
|
:fields="fields"
|
||||||
|
:loading="false"
|
||||||
|
@submit="onSubmit"
|
||||||
|
>
|
||||||
|
|
||||||
|
</UAuthForm>
|
||||||
|
</UCard>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -309,11 +309,24 @@ setupPage()
|
|||||||
</UAccordion>
|
</UAccordion>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.key === 'documents'" class="space-y-3">
|
<div v-else-if="item.key === 'documents'" class="space-y-3">
|
||||||
|
<InputGroup>
|
||||||
<UButton
|
<UButton
|
||||||
@click="uploadModalOpen = true"
|
@click="uploadModalOpen = true"
|
||||||
>
|
>
|
||||||
Hochladen
|
Hochladen
|
||||||
</UButton>
|
</UButton>
|
||||||
|
<UButton
|
||||||
|
@click="router.push(`/createDocument/edit?project=${currentItem.id}&type=quotes&customer=${currentItem.customer}`)"
|
||||||
|
>
|
||||||
|
+ Angebot
|
||||||
|
</UButton>
|
||||||
|
<UButton
|
||||||
|
@click="router.push(`/createDocument/edit?project=${currentItem.id}&type=invoices&customer=${currentItem.customer}`)"
|
||||||
|
>
|
||||||
|
+ Rechnung
|
||||||
|
</UButton>
|
||||||
|
</InputGroup>
|
||||||
|
|
||||||
<UModal
|
<UModal
|
||||||
v-model="uploadModalOpen"
|
v-model="uploadModalOpen"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ const setState = async (newState) => {
|
|||||||
} else if(mode.value === 'edit') {
|
} else if(mode.value === 'edit') {
|
||||||
await dataStore.updateItem('incomingInvoices',{...itemInfo.value, state: newState})
|
await dataStore.updateItem('incomingInvoices',{...itemInfo.value, state: newState})
|
||||||
}
|
}
|
||||||
await router.push("/incominginvoices")
|
await router.push("/receipts")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -133,11 +133,11 @@ setupPage()
|
|||||||
Status zu Entwurf
|
Status zu Entwurf
|
||||||
</UButton>
|
</UButton>
|
||||||
<UButton
|
<UButton
|
||||||
@click="setState('Offen')"
|
@click="setState('Gebucht')"
|
||||||
v-if="currentVendorInvoice.state !== 'Offen'"
|
v-if="currentVendorInvoice.state !== 'Gebucht'"
|
||||||
color="rose"
|
color="rose"
|
||||||
>
|
>
|
||||||
Status zu Offen
|
Status auf Gebucht
|
||||||
</UButton>
|
</UButton>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
|
||||||
@@ -372,14 +372,14 @@ setupPage()
|
|||||||
>
|
>
|
||||||
Position entfernen
|
Position entfernen
|
||||||
</UButton>
|
</UButton>
|
||||||
|
|
||||||
|
</div>
|
||||||
<HistoryDisplay
|
<HistoryDisplay
|
||||||
type="incomingInvoice"
|
type="incomingInvoice"
|
||||||
v-if="currentVendorInvoice"
|
v-if="currentVendorInvoice"
|
||||||
:element-id="currentVendorInvoice.id"
|
:element-id="currentVendorInvoice.id"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -8,6 +8,11 @@
|
|||||||
v-model="searchString"
|
v-model="searchString"
|
||||||
placeholder="Suche..."
|
placeholder="Suche..."
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<UCheckbox
|
||||||
|
v-model="showDrafts"
|
||||||
|
label="Entwürfe Anzeigen"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@@ -18,16 +23,20 @@
|
|||||||
@select="selectItem"
|
@select="selectItem"
|
||||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }"
|
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }"
|
||||||
>
|
>
|
||||||
|
<template #type-data="{row}">
|
||||||
|
<span v-if="row.type === 'incomingInvoice'">Eingangsrechnung</span>
|
||||||
|
<span v-else>{{dataStore.documentTypesForCreation[row.type].labelSingle}}</span>
|
||||||
|
</template>
|
||||||
<template #state-data="{row}">
|
<template #state-data="{row}">
|
||||||
<span
|
<span
|
||||||
v-if="row.state === 'Entwurf'"
|
v-if="row.state === 'Entwurf'"
|
||||||
class="text-cyan-500"
|
class="text-rose-500"
|
||||||
>
|
>
|
||||||
{{row.state}}
|
{{row.state}}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
v-if="row.state === 'Offen'"
|
v-if="row.state === 'Gebucht'"
|
||||||
class="text-rose-500"
|
class="text-cyan-500"
|
||||||
>
|
>
|
||||||
{{row.state}}
|
{{row.state}}
|
||||||
</span>
|
</span>
|
||||||
@@ -41,6 +50,10 @@
|
|||||||
<template #vendor-data="{row}">
|
<template #vendor-data="{row}">
|
||||||
{{dataStore.vendors.find(vendor => vendor.id === row.vendor) ? dataStore.vendors.find(vendor => vendor.id === row.vendor).name : ''}}
|
{{dataStore.vendors.find(vendor => vendor.id === row.vendor) ? dataStore.vendors.find(vendor => vendor.id === row.vendor).name : ''}}
|
||||||
</template>
|
</template>
|
||||||
|
<template #reference-data="{row}">
|
||||||
|
<span v-if="row.type === 'incomingInvoice'">{{row.reference}}</span>
|
||||||
|
<span v-else>{{row.documentNumber}}</span>
|
||||||
|
</template>
|
||||||
<template #date-data="{row}">
|
<template #date-data="{row}">
|
||||||
<span v-if="row.date">{{row.date ? dayjs(row.date).format("DD.MM.YY") : ''}}</span>
|
<span v-if="row.date">{{row.date ? dayjs(row.date).format("DD.MM.YY") : ''}}</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -52,7 +65,12 @@
|
|||||||
<span v-if="!row.paid" :class="dayjs(row.dueDate).diff(dayjs()) <= 0 ? ['text-rose-500'] : ['text-cyan-500'] ">Offen</span>
|
<span v-if="!row.paid" :class="dayjs(row.dueDate).diff(dayjs()) <= 0 ? ['text-rose-500'] : ['text-cyan-500'] ">Offen</span>
|
||||||
</template>
|
</template>
|
||||||
<template #amount-data="{row}">
|
<template #amount-data="{row}">
|
||||||
<div class="text-right font-bold">{{getRowAmount(row) === 0 ? '' : `${String(getRowAmount(row).toFixed(2)).replace('.',',')} €`}}</div>
|
<div
|
||||||
|
class="text-right font-bold"
|
||||||
|
v-if="row.type === 'incomingInvoice'"
|
||||||
|
>
|
||||||
|
{{getRowAmount(row) === 0 ? '' : `${String(getRowAmount(row).toFixed(2)).replace('.',',')} €`}}
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</UTable>
|
</UTable>
|
||||||
|
|
||||||
@@ -74,6 +92,10 @@ const mode = ref("show")
|
|||||||
|
|
||||||
const itemColumns = [
|
const itemColumns = [
|
||||||
{
|
{
|
||||||
|
key: 'type',
|
||||||
|
label: "Typ",
|
||||||
|
sortable: true
|
||||||
|
},{
|
||||||
key: 'state',
|
key: 'state',
|
||||||
label: "Status.",
|
label: "Status.",
|
||||||
sortable: true
|
sortable: true
|
||||||
@@ -113,12 +135,24 @@ const itemColumns = [
|
|||||||
|
|
||||||
const selectItem = (item) => {
|
const selectItem = (item) => {
|
||||||
console.log(item)
|
console.log(item)
|
||||||
|
|
||||||
|
if(item.type === "incomingInvoice"){
|
||||||
if(item.state === "Entwurf") {
|
if(item.state === "Entwurf") {
|
||||||
console.log("ENTWURF")
|
router.push(`/receipts/incominginvoices/edit/${item.id} `)
|
||||||
router.push(`/incominginvoices/edit/${item.id} `)
|
} else if(item.state === "Gebucht") {
|
||||||
} else if(item.state === "Offen") {
|
router.push(`/receipts/incominginvoices/show/${item.id}`)
|
||||||
router.push(`/incominginvoices/show/${item.id}`)
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if(item.state === "Entwurf"){
|
||||||
|
router.push(`/createDocument/edit/${item.id}`)
|
||||||
|
} else if(item.state !== "Entwurf") {
|
||||||
|
router.push(`/createDocument/show/${item.id}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,13 +169,25 @@ const getRowAmount = (row) => {
|
|||||||
|
|
||||||
|
|
||||||
const searchString = ref('')
|
const searchString = ref('')
|
||||||
|
const showDrafts = ref(false)
|
||||||
|
|
||||||
const filteredRows = computed(() => {
|
const filteredRows = computed(() => {
|
||||||
if(!searchString.value) {
|
let items = [...dataStore.incomingInvoices.map(i => {return {...i, type: "incomingInvoice"}}),...dataStore.createdDocuments]
|
||||||
return dataStore.incomingInvoices
|
|
||||||
|
console.log(dataStore.createdDocuments)
|
||||||
|
|
||||||
|
if(showDrafts.value === true) {
|
||||||
|
items = items.filter(i => i.state === "Entwurf")
|
||||||
|
} else {
|
||||||
|
items = items.filter(i => i.state !== "Entwurf")
|
||||||
}
|
}
|
||||||
|
|
||||||
return dataStore.incomingInvoices.filter(item => {
|
|
||||||
|
if(!searchString.value) {
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
|
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())
|
||||||
})
|
})
|
||||||
@@ -36,11 +36,13 @@ const resources = {
|
|||||||
},
|
},
|
||||||
spaces: {
|
spaces: {
|
||||||
label: "Lagerplätze"
|
label: "Lagerplätze"
|
||||||
|
},
|
||||||
|
invoices: {
|
||||||
|
label: "Rechnungen"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateNumberRange = async (range) => {
|
const updateNumberRange = async (range) => {
|
||||||
console.log(range)
|
|
||||||
|
|
||||||
const {data,error} = await supabase
|
const {data,error} = await supabase
|
||||||
.from("numberRanges")
|
.from("numberRanges")
|
||||||
|
|||||||
78
spaces/pages/settings/rights.vue
Normal file
78
spaces/pages/settings/rights.vue
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<script setup>
|
||||||
|
|
||||||
|
const supabase = useSupabaseClient()
|
||||||
|
|
||||||
|
const data = await supabase.from("profiles").select('* , tenants (id, name)')
|
||||||
|
console.log(data)
|
||||||
|
|
||||||
|
let rights = {
|
||||||
|
createUser: {label: "Benutzer erstellen"},
|
||||||
|
modifyUser: {label: "Benutzer bearbeiten"},
|
||||||
|
deactivateUser: {label: "Benutzer sperren"},
|
||||||
|
createProject: {label: "Projekt erstellen"},
|
||||||
|
viewOwnProjects: {label: "Eigene Projekte sehen"},
|
||||||
|
viewAllProjects: {label: "Alle Projekte sehen"},
|
||||||
|
createTask: {label: "Aufgabe erstellen"},
|
||||||
|
viewOwnTasks: {label:"Eigene Aufgaben sehen"},
|
||||||
|
viewAllTasks: {label: "Alle Aufgaben sehen"},
|
||||||
|
trackOwnTime: {label:""},
|
||||||
|
createOwnTime: {label:""},
|
||||||
|
createTime: {label:""},
|
||||||
|
viewOwnTimes: {label:""},
|
||||||
|
viewAllTimesTimes: {label:""},
|
||||||
|
}
|
||||||
|
|
||||||
|
let roles = [
|
||||||
|
{
|
||||||
|
key: "tenantAdmin",
|
||||||
|
label: "Firmenadministrator",
|
||||||
|
rights: [
|
||||||
|
...Object.keys(rights)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key:"worker",
|
||||||
|
label: "Monteur",
|
||||||
|
rights: [
|
||||||
|
"viewOwnProjects",
|
||||||
|
"createTasks",
|
||||||
|
"viewOwnTasks"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key:"manager",
|
||||||
|
label: "Vorarbeiter",
|
||||||
|
rights: [
|
||||||
|
"createProjects",
|
||||||
|
"viewOwnProjects",
|
||||||
|
"createTasks",
|
||||||
|
"viewOwnTasks",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key:"booker",
|
||||||
|
label: "Buchhalter",
|
||||||
|
rights: [
|
||||||
|
"createTasks",
|
||||||
|
"viewOwnTasks",
|
||||||
|
"createTime",
|
||||||
|
"viewAllTimes"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -141,7 +141,7 @@ setupPage()
|
|||||||
<UTable
|
<UTable
|
||||||
:rows="dataStore.getIncomingInvoicesByVehicleId(currentItem.id)"
|
:rows="dataStore.getIncomingInvoicesByVehicleId(currentItem.id)"
|
||||||
:columns="incomingInvoicesColumns"
|
:columns="incomingInvoicesColumns"
|
||||||
@select="(row) => router.push('/incominginvoices/show/' + row.id)"
|
@select="(row) => router.push('/receipts/show/' + row.id)"
|
||||||
>
|
>
|
||||||
<template #vendor-data="{row}">
|
<template #vendor-data="{row}">
|
||||||
{{dataStore.getVendorById(row.vendor) ? dataStore.getVendorById(row.vendor).name : ""}}
|
{{dataStore.getVendorById(row.vendor) ? dataStore.getVendorById(row.vendor).name : ""}}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {defineStore} from 'pinia'
|
import {defineStore} from 'pinia'
|
||||||
import dayjs from "dayjs"
|
import dayjs from "dayjs"
|
||||||
import {typeOf} from "uri-js/dist/esnext/util";
|
import {typeOf} from "uri-js/dist/esnext/util";
|
||||||
|
import {useNumberRange} from "~/composables/useNumberRange.js";
|
||||||
|
|
||||||
//const supabase = createClient('https://uwppvcxflrcsibuzsbil.supabase.co','eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InV3cHB2Y3hmbHJjc2lidXpzYmlsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDA5MzgxOTQsImV4cCI6MjAxNjUxNDE5NH0.CkxYSQH0uLfwx9GVUlO6AYMU2FMLAxGMrwEKvyPv7Oo')
|
//const supabase = createClient('https://uwppvcxflrcsibuzsbil.supabase.co','eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InV3cHB2Y3hmbHJjc2lidXpzYmlsIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDA5MzgxOTQsImV4cCI6MjAxNjUxNDE5NH0.CkxYSQH0uLfwx9GVUlO6AYMU2FMLAxGMrwEKvyPv7Oo')
|
||||||
|
|
||||||
@@ -21,7 +22,8 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
customers: {
|
customers: {
|
||||||
label: "Kunden",
|
label: "Kunden",
|
||||||
labelSingle: "Kunde",
|
labelSingle: "Kunde",
|
||||||
redirect:true
|
redirect:true,
|
||||||
|
numberRangeHolder: "customerNumber"
|
||||||
},
|
},
|
||||||
contacts: {
|
contacts: {
|
||||||
label: "Kontakte",
|
label: "Kontakte",
|
||||||
@@ -61,7 +63,8 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
vendors: {
|
vendors: {
|
||||||
label: "Lieferanten",
|
label: "Lieferanten",
|
||||||
labelSingle: "Lieferant",
|
labelSingle: "Lieferant",
|
||||||
redirect:true
|
redirect:true,
|
||||||
|
numberRangeHolder: "vendorNumber"
|
||||||
},
|
},
|
||||||
messages: {
|
messages: {
|
||||||
label: "Nachrichten",
|
label: "Nachrichten",
|
||||||
@@ -70,29 +73,58 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
spaces: {
|
spaces: {
|
||||||
label: "Lagerplätze",
|
label: "Lagerplätze",
|
||||||
labelSingle: "Lagerplatz",
|
labelSingle: "Lagerplatz",
|
||||||
redirect: true
|
redirect: true,
|
||||||
|
numberRangeHolder: "spaceNumber"
|
||||||
},
|
},
|
||||||
users: {
|
users: {
|
||||||
label: "Benutzer",
|
label: "Benutzer",
|
||||||
labelSingle: "Benutzer"
|
labelSingle: "Benutzer"
|
||||||
|
},
|
||||||
|
createdDocuments: {
|
||||||
|
label: "Dokumente",
|
||||||
|
labelSingle: "Dokument"
|
||||||
|
},
|
||||||
|
incomingInvoices: {
|
||||||
|
label: "Eingangsrechnungen",
|
||||||
|
labelSingle: "Eingangsrechnung"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const documentTypesForCreation = ref({
|
||||||
|
invoices: {
|
||||||
|
label: "Rechnungen",
|
||||||
|
labelSingle: "Rechnung",
|
||||||
|
|
||||||
|
},
|
||||||
|
quotes: {
|
||||||
|
label: "Angebote",
|
||||||
|
labelSingle: "Angebot"
|
||||||
|
},
|
||||||
|
deliveryNotes: {
|
||||||
|
label: "Lieferscheine",
|
||||||
|
labelSingle: "Lieferschein"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
const loaded = ref(false)
|
const loaded = ref(false)
|
||||||
const ownTenant = ref({
|
const ownTenant = ref({
|
||||||
calendarConfig: {
|
calendarConfig: {
|
||||||
eventTypes: [] as any[]
|
eventTypes: []
|
||||||
},
|
},
|
||||||
timeConfig: {
|
timeConfig: {
|
||||||
timeTypes: [] as any[]
|
timeTypes: []
|
||||||
},
|
},
|
||||||
tags: {
|
tags: {
|
||||||
documents: [] as any[],
|
documents: [] ,
|
||||||
products: [] as any[]
|
products: []
|
||||||
},
|
},
|
||||||
measures: [] as {name:String, short:String}[]
|
measures: []
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const profiles = ref([])
|
const profiles = ref([])
|
||||||
|
const currentTenant = ref(null)
|
||||||
const events = ref([])
|
const events = ref([])
|
||||||
const customers = ref([])
|
const customers = ref([])
|
||||||
const tasks = ref([])
|
const tasks = ref([])
|
||||||
@@ -122,11 +154,30 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
const inventoryItems = ref([])
|
const inventoryItems = ref([])
|
||||||
const chats = ref([])
|
const chats = ref([])
|
||||||
const messages = ref([])
|
const messages = ref([])
|
||||||
|
const createdDocuments = ref([])
|
||||||
|
|
||||||
|
async function initializeData () {
|
||||||
|
await fetchProfiles()
|
||||||
|
currentTenant.value = profiles.value.find(i => i.id === user.value.id).tenants[0].id
|
||||||
|
|
||||||
|
await fetchData()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async function changeTenant() {
|
||||||
|
loaded.value = false
|
||||||
|
await clearStore()
|
||||||
|
await fetchData()
|
||||||
|
router.push("/")
|
||||||
|
loaded.value = true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchData () {
|
async function fetchData () {
|
||||||
|
await fetchProfiles()
|
||||||
|
|
||||||
fetchDocuments()
|
fetchDocuments()
|
||||||
await fetchOwnTenant()
|
await fetchOwnTenant()
|
||||||
await fetchProfiles()
|
|
||||||
await fetchEvents()
|
await fetchEvents()
|
||||||
await fetchTasks()
|
await fetchTasks()
|
||||||
await fetchProjects()
|
await fetchProjects()
|
||||||
@@ -156,6 +207,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
await fetchInventoryItems()
|
await fetchInventoryItems()
|
||||||
await fetchChats()
|
await fetchChats()
|
||||||
await fetchMessages()
|
await fetchMessages()
|
||||||
|
await fetchCreatedDocuments()
|
||||||
loaded.value = true
|
loaded.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,6 +245,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
inventoryItems.value = []
|
inventoryItems.value = []
|
||||||
chats.value = []
|
chats.value = []
|
||||||
messages.value = []
|
messages.value = []
|
||||||
|
createdDocuments.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
//Realtime Update
|
//Realtime Update
|
||||||
@@ -218,7 +271,20 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
)
|
)
|
||||||
.subscribe()
|
.subscribe()
|
||||||
|
|
||||||
async function createNewItem (dataType:string,data:Array){
|
async function createNewItem (dataType,data){
|
||||||
|
console.log(dataType)
|
||||||
|
if(dataTypes[dataType].numberRangeHolder) {
|
||||||
|
|
||||||
|
const numberRange = useNumberRange(dataType)
|
||||||
|
data[dataTypes[dataType].numberRangeHolder] = await numberRange.useNextNumber()
|
||||||
|
|
||||||
|
} else if(dataType === "createdDocuments") {
|
||||||
|
console.log(data.type)
|
||||||
|
const numberRange = useNumberRange(data.type)
|
||||||
|
data.documentNumber = await numberRange.useNextNumber()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const {data:supabaseData,error:supabaseError} = await supabase
|
const {data:supabaseData,error:supabaseError} = await supabase
|
||||||
.from(dataType)
|
.from(dataType)
|
||||||
.insert(typeOf(data) === 'Object' ? [data] : data)
|
.insert(typeOf(data) === 'Object' ? [data] : data)
|
||||||
@@ -233,7 +299,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateItem (dataType:string, data:Object) {
|
async function updateItem (dataType, data) {
|
||||||
const {data:supabaseData,error: supabaseError} = await supabase
|
const {data:supabaseData,error: supabaseError} = await supabase
|
||||||
.from(dataType)
|
.from(dataType)
|
||||||
.update(data)
|
.update(data)
|
||||||
@@ -251,108 +317,116 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchOwnTenant () {
|
async function fetchOwnTenant () {
|
||||||
ownTenant.value = (await supabase.from("tenants").select().eq('id', user.value?.app_metadata.tenant)).data[0]
|
ownTenant.value = (await supabase.from("tenants").select().eq('id', currentTenant.value)).data[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchProfiles () {
|
async function fetchProfiles () {
|
||||||
profiles.value = (await supabase.from("profiles").select()).data
|
profiles.value = (await supabase.from("profiles").select('* , tenants (id, name)')).data
|
||||||
}
|
}
|
||||||
async function fetchBankAccounts () {
|
async function fetchBankAccounts () {
|
||||||
bankAccounts.value = (await supabase.from("bankAccounts").select()).data
|
bankAccounts.value = (await supabase.from("bankaccounts").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchBankStatements () {
|
async function fetchBankStatements () {
|
||||||
bankStatements.value = (await supabase.from("bankStatements").select().order("date", {ascending:false})).data
|
bankStatements.value = (await supabase.from("bankstatements").select().eq('tenant', currentTenant.value).order("date", {ascending:false})).data
|
||||||
}
|
}
|
||||||
async function fetchEvents () {
|
async function fetchEvents () {
|
||||||
events.value = (await supabase.from("events").select()).data
|
events.value = (await supabase.from("events").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchContracts () {
|
async function fetchContracts () {
|
||||||
contracts.value = (await supabase.from("contracts").select()).data
|
contracts.value = (await supabase.from("contracts").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchContacts () {
|
async function fetchContacts () {
|
||||||
contacts.value = (await supabase.from("contacts").select()).data
|
contacts.value = (await supabase.from("contacts").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchCustomers () {
|
async function fetchCustomers () {
|
||||||
customers.value = (await supabase.from("customers").select().order("customerNumber", {ascending:true})).data
|
customers.value = (await supabase.from("customers").select().eq('tenant', currentTenant.value).order("customerNumber", {ascending:true})).data
|
||||||
}
|
}
|
||||||
async function fetchTasks () {
|
async function fetchTasks () {
|
||||||
tasks.value = (await supabase.from("tasks").select()).data
|
tasks.value = (await supabase.from("tasks").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchForms () {
|
async function fetchForms () {
|
||||||
forms.value = (await supabase.from("forms").select()).data
|
forms.value = (await supabase.from("forms").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchFormSubmits () {
|
async function fetchFormSubmits () {
|
||||||
formSubmits.value = (await supabase.from("formSubmits").select()).data
|
formSubmits.value = (await supabase.from("formSubmits").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchProducts () {
|
async function fetchProducts () {
|
||||||
products.value = (await supabase.from("products").select()).data
|
products.value = (await supabase.from("products").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchUnits () {
|
async function fetchUnits () {
|
||||||
units.value = (await supabase.from("units").select()).data
|
units.value = (await supabase.from("units").select()).data
|
||||||
}
|
}
|
||||||
async function fetchProjects () {
|
async function fetchProjects () {
|
||||||
projects.value = (await supabase.from("projects").select()).data
|
projects.value = (await supabase.from("projects").select().eq("tenant",currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchSpaces () {
|
async function fetchSpaces () {
|
||||||
spaces.value = (await supabase.from("spaces").select().order("spaceNumber", {ascending:true})).data
|
spaces.value = (await supabase.from("spaces").select().eq('tenant', currentTenant.value).order("spaceNumber", {ascending:true})).data
|
||||||
}
|
}
|
||||||
async function fetchMovements () {
|
async function fetchMovements () {
|
||||||
movements.value = (await supabase.from("movements").select()).data
|
movements.value = (await supabase.from("movements").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchVehicles () {
|
async function fetchVehicles () {
|
||||||
vehicles.value = (await supabase.from("vehicles").select()).data
|
vehicles.value = (await supabase.from("vehicles").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchTimes () {
|
async function fetchTimes () {
|
||||||
times.value = (await supabase.from("times").select().order("start", {ascending:false})).data
|
times.value = (await supabase.from("times").select().eq('tenant', currentTenant.value).order("start", {ascending:false})).data
|
||||||
}
|
}
|
||||||
async function fetchHistoryItems () {
|
async function fetchHistoryItems () {
|
||||||
|
|
||||||
historyItems.value = (await supabase.from("historyItems").select()).data
|
historyItems.value = (await supabase.from("historyitems").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchVendors () {
|
async function fetchVendors () {
|
||||||
vendors.value = (await supabase.from("vendors").select().order("vendorNumber", {ascending:true})).data
|
vendors.value = (await supabase.from("vendors").select().eq('tenant', currentTenant.value).order("vendorNumber", {ascending:true})).data
|
||||||
}
|
}
|
||||||
async function fetchIncomingInvoices () {
|
async function fetchIncomingInvoices () {
|
||||||
incomingInvoices.value = (await supabase.from("incomingInvoices").select()).data
|
incomingInvoices.value = (await supabase.from("incominginvoices").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchNumberRanges () {
|
async function fetchNumberRanges () {
|
||||||
numberRanges.value = (await supabase.from("numberRanges").select()).data
|
numberRanges.value = (await supabase.from("numberranges").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchNotifications () {
|
async function fetchNotifications () {
|
||||||
notifications.value = (await supabase.from("notifications").select().order("created_at", {ascending: false})).data
|
notifications.value = (await supabase.from("notifications").select().eq('tenant', currentTenant.value).order("created_at", {ascending: false})).data
|
||||||
}
|
}
|
||||||
async function fetchAbsenceRequests () {
|
async function fetchAbsenceRequests () {
|
||||||
absenceRequests.value = (await supabase.from("absenceRequests").select()).data
|
absenceRequests.value = (await supabase.from("absencerequests").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchAccounts () {
|
async function fetchAccounts () {
|
||||||
accounts.value = (await supabase.from("accounts").select()).data
|
accounts.value = (await supabase.from("accounts").select()).data
|
||||||
}
|
}
|
||||||
async function fetchTaxTypes () {
|
async function fetchTaxTypes () {
|
||||||
taxTypes.value = (await supabase.from("taxTypes").select()).data
|
taxTypes.value = (await supabase.from("taxtypes").select()).data
|
||||||
}
|
}
|
||||||
async function fetchPlants () {
|
async function fetchPlants () {
|
||||||
plants.value = (await supabase.from("plants").select()).data
|
plants.value = (await supabase.from("plants").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchInventoryItems () {
|
async function fetchInventoryItems () {
|
||||||
inventoryItems.value = (await supabase.from("inventoryItems").select()).data
|
inventoryItems.value = (await supabase.from("inventoryitems").select().eq('tenant', currentTenant.value)).data
|
||||||
}
|
}
|
||||||
async function fetchChats() {
|
async function fetchChats() {
|
||||||
chats.value = (await supabase.from("chats").select()).data
|
chats.value = (await supabase.from("chats").select()).data
|
||||||
}
|
}
|
||||||
async function fetchMessages() {
|
async function fetchMessages() {
|
||||||
messages.value = (await supabase.from("messages").select().order('created_at', {ascending:true})).data
|
messages.value = (await supabase.from("messages").select().eq('tenant', currentTenant.value).order('created_at', {ascending:true})).data
|
||||||
|
}
|
||||||
|
async function fetchCreatedDocuments() {
|
||||||
|
createdDocuments.value = (await supabase.from("createddocuments").select().eq('tenant', currentTenant.value).order('created_at', {ascending:true})).data
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchDocuments () {
|
async function fetchDocuments () {
|
||||||
documents.value = (await supabase.from("documents").select()).data
|
let tempDocuments = (await supabase.from("documents").select().eq('tenant', currentTenant.value)).data
|
||||||
|
|
||||||
for(const [index,doc] of documents.value.entries()){
|
if(tempDocuments.length > 0) {
|
||||||
|
for(const [index,doc] of tempDocuments.entries()){
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
documents.value[index].url = (await supabase.storage.from('files').createSignedUrl(doc.path, 60 * 60)).data.signedUrl
|
tempDocuments[index].url = (await supabase.storage.from('files').createSignedUrl(doc.path, 60 * 60)).data.signedUrl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addHistoryItem(text: String, user: String, elementId: String, resourceType: String) {
|
documents.value = tempDocuments
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addHistoryItem(text, user, elementId, resourceType) {
|
||||||
let data = {
|
let data = {
|
||||||
user: user,
|
user: user,
|
||||||
text: text
|
text: text
|
||||||
@@ -382,55 +456,59 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
return tasks.value.filter(task => task.categorie != "Erledigt").length
|
return tasks.value.filter(task => task.categorie != "Erledigt").length
|
||||||
})
|
})
|
||||||
|
|
||||||
const getMovementsBySpace = computed(() => (spaceId:string) => {
|
const getOwnProfile = computed(() => {
|
||||||
|
return profiles.value.find(profile => profile.id === user.value.id)
|
||||||
|
})
|
||||||
|
|
||||||
|
const getMovementsBySpace = computed(() => (spaceId) => {
|
||||||
return movements.value.filter(movement => movement.spaceId === spaceId)
|
return movements.value.filter(movement => movement.spaceId === spaceId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getContactsByCustomerId = computed(() => (customerId:string) => {
|
const getContactsByCustomerId = computed(() => (customerId) => {
|
||||||
return contacts.value.filter(item => item.customer === customerId)
|
return contacts.value.filter(item => item.customer === customerId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getContactsByVendorId = computed(() => (vendorId:string) => {
|
const getContactsByVendorId = computed(() => (vendorId) => {
|
||||||
return contacts.value.filter(item => item.vendor === vendorId)
|
return contacts.value.filter(item => item.vendor === vendorId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getDocumentsByProjectId = computed(() => (projectId:string) => {
|
const getDocumentsByProjectId = computed(() => (projectId) => {
|
||||||
return documents.value.filter(item => item.project === projectId)
|
return documents.value.filter(item => item.project === projectId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getEventsByProjectId = computed(() => (projectId:string) => {
|
const getEventsByProjectId = computed(() => (projectId) => {
|
||||||
return events.value.filter(item => item.project === projectId)
|
return events.value.filter(item => item.project === projectId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getTimesByProjectId = computed(() => (projectId:string) => {
|
const getTimesByProjectId = computed(() => (projectId) => {
|
||||||
return times.value.filter(time => time.projectId === projectId)
|
return times.value.filter(time => time.projectId === projectId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getTasksByProjectId = computed(() => (projectId:string) => {
|
const getTasksByProjectId = computed(() => (projectId) => {
|
||||||
return tasks.value.filter(item => item.project === projectId)
|
return tasks.value.filter(item => item.project === projectId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getTasksByPlantId = computed(() => (plantId:string) => {
|
const getTasksByPlantId = computed(() => (plantId) => {
|
||||||
return tasks.value.filter(item => item.plant === plantId)
|
return tasks.value.filter(item => item.plant === plantId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getProjectsByPlantId = computed(() => (plantId:string) => {
|
const getProjectsByPlantId = computed(() => (plantId) => {
|
||||||
return projects.value.filter(item => item.plant === plantId)
|
return projects.value.filter(item => item.plant === plantId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getIncomingInvoicesByVehicleId = computed(() => (vehicleId:string) => {
|
const getIncomingInvoicesByVehicleId = computed(() => (vehicleId) => {
|
||||||
return incomingInvoices.value.filter(i => i.accounts.find(a => a.costCentre === vehicleId))
|
return incomingInvoices.value.filter(i => i.accounts.find(a => a.costCentre === vehicleId))
|
||||||
})
|
})
|
||||||
|
|
||||||
const getMovementsBySpaceId = computed(() => (spaceId:string) => {
|
const getMovementsBySpaceId = computed(() => (spaceId) => {
|
||||||
return movements.value.filter(movement => movement.spaceId === spaceId)
|
return movements.value.filter(movement => movement.spaceId === spaceId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getMessagesByChatId = computed(() => (chatId:string) => {
|
const getMessagesByChatId = computed(() => (chatId) => {
|
||||||
return messages.value.filter(i => i.destination === chatId)
|
return messages.value.filter(i => i.destination === chatId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getStockByProductId = computed(() => (productId:string) => {
|
const getStockByProductId = computed(() => (productId) => {
|
||||||
let productMovements = movements.value.filter(movement => movement.productId === productId)
|
let productMovements = movements.value.filter(movement => movement.productId === productId)
|
||||||
|
|
||||||
let count = 0
|
let count = 0
|
||||||
@@ -595,63 +673,67 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
|
|
||||||
|
|
||||||
//Get Item By Id
|
//Get Item By Id
|
||||||
const getProductById = computed(() => (itemId:string) => {
|
const getProductById = computed(() => (itemId) => {
|
||||||
return products.value.find(item => item.id === itemId)
|
return products.value.find(item => item.id === itemId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getVendorById = computed(() => (itemId:string) => {
|
const getVendorById = computed(() => (itemId) => {
|
||||||
return vendors.value.find(item => item.id === itemId)
|
return vendors.value.find(item => item.id === itemId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getIncomingInvoiceById = computed(() => (itemId:string) => {
|
const getIncomingInvoiceById = computed(() => (itemId) => {
|
||||||
return incomingInvoices.value.find(item => item.id === itemId)
|
return incomingInvoices.value.find(item => item.id === itemId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getContractById = computed(() => (itemId:string) => {
|
const getContractById = computed(() => (itemId) => {
|
||||||
return contracts.value.find(item => item.id === itemId)
|
return contracts.value.find(item => item.id === itemId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getContactById = computed(() => (itemId:string) => {
|
const getContactById = computed(() => (itemId) => {
|
||||||
return contacts.value.find(item => item.id === itemId)
|
return contacts.value.find(item => item.id === itemId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getVehicleById = computed(() => (itemId:string) => {
|
const getVehicleById = computed(() => (itemId) => {
|
||||||
return vehicles.value.find(item => item.id === itemId)
|
return vehicles.value.find(item => item.id === itemId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getDocumentById = computed(() => (itemId:string) => {
|
const getDocumentById = computed(() => (itemId) => {
|
||||||
return documents.value.find(item => item.id === itemId)
|
return documents.value.find(item => item.id === itemId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getSpaceById = computed(() => (itemId:string) => {
|
const getSpaceById = computed(() => (itemId) => {
|
||||||
return spaces.value.find(item => item.id === itemId)
|
return spaces.value.find(item => item.id === itemId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getCustomerById = computed(() => (itemId:number) => {
|
const getCustomerById = computed(() => (itemId) => {
|
||||||
return customers.value.find(item => item.id === itemId)
|
return customers.value.find(item => item.id === itemId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getTaskById = computed(() => (itemId:string) => {
|
const getTaskById = computed(() => (itemId) => {
|
||||||
return tasks.value.find(item => item.id === itemId)
|
return tasks.value.find(item => item.id === itemId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getAbsenceRequestById = computed(() => (itemId:string) => {
|
const getAbsenceRequestById = computed(() => (itemId) => {
|
||||||
return absenceRequests.value.find(item => item.id === itemId)
|
return absenceRequests.value.find(item => item.id === itemId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getProfileById = computed(() => (itemId:string) => {
|
const getProfileById = computed(() => (itemId) => {
|
||||||
return profiles.value.find(item => item.id === itemId)
|
return profiles.value.find(item => item.id === itemId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getAccountById = computed(() => (accountId:string) => {
|
const getAccountById = computed(() => (accountId) => {
|
||||||
return accounts.value.find(item => item.id === accountId)
|
return accounts.value.find(item => item.id === accountId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getPlantById = computed(() => (plantId:string) => {
|
const getPlantById = computed(() => (plantId) => {
|
||||||
return plants.value.find(item => item.id === plantId)
|
return plants.value.find(item => item.id === plantId)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getProjectById = computed(() => (itemId:string) => {
|
const getCreatedDocumentById = computed(() => (documentId) => {
|
||||||
|
return createdDocuments.value.find(item => item.id === documentId)
|
||||||
|
})
|
||||||
|
|
||||||
|
const getProjectById = computed(() => (itemId) => {
|
||||||
if(projects.value.find(i => i.id === itemId)) {
|
if(projects.value.find(i => i.id === itemId)) {
|
||||||
let project = projects.value.find(project => project.id === itemId)
|
let project = projects.value.find(project => project.id === itemId)
|
||||||
|
|
||||||
@@ -672,8 +754,14 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
//General
|
||||||
|
currentTenant,
|
||||||
loaded,
|
loaded,
|
||||||
ownTenant,
|
ownTenant,
|
||||||
|
initializeData,
|
||||||
|
changeTenant,
|
||||||
|
|
||||||
|
//Data
|
||||||
profiles,
|
profiles,
|
||||||
events,
|
events,
|
||||||
customers,
|
customers,
|
||||||
@@ -704,6 +792,8 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
inventoryItems,
|
inventoryItems,
|
||||||
chats,
|
chats,
|
||||||
messages,
|
messages,
|
||||||
|
createdDocuments,
|
||||||
|
documentTypesForCreation,
|
||||||
//Functions
|
//Functions
|
||||||
createNewItem,
|
createNewItem,
|
||||||
updateItem,
|
updateItem,
|
||||||
@@ -741,6 +831,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
addHistoryItem,
|
addHistoryItem,
|
||||||
//Getters
|
//Getters
|
||||||
getOpenTasksCount,
|
getOpenTasksCount,
|
||||||
|
getOwnProfile,
|
||||||
getMovementsBySpace,
|
getMovementsBySpace,
|
||||||
getContactsByCustomerId,
|
getContactsByCustomerId,
|
||||||
getContactsByVendorId,
|
getContactsByVendorId,
|
||||||
@@ -776,7 +867,8 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
getProjectById,
|
getProjectById,
|
||||||
getProfileById,
|
getProfileById,
|
||||||
getAccountById,
|
getAccountById,
|
||||||
getPlantById
|
getPlantById,
|
||||||
|
getCreatedDocumentById
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user