Added Phases to Projects
This commit is contained in:
@@ -12,4 +12,4 @@ ENV NUXT_PORT=3000
|
|||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
ENTRYPOINT ["node", ".output/server/index.mjs"]
|
ENTRYPOINT ["node", ".output/server/index.js"]
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ const viewport = useViewport()
|
|||||||
console.log('Breakpoint updated:', oldBreakpoint, '->', newBreakpoint)
|
console.log('Breakpoint updated:', oldBreakpoint, '->', newBreakpoint)
|
||||||
})*/
|
})*/
|
||||||
|
|
||||||
dataStore.initializeData()
|
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
meta: [
|
meta: [
|
||||||
@@ -52,10 +51,7 @@ useSeoMeta({
|
|||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#contentContainer {
|
|
||||||
width: 95vw;
|
|
||||||
height: 85vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.documentList {
|
.documentList {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -103,4 +99,18 @@ useSeoMeta({
|
|||||||
a:hover {
|
a:hover {
|
||||||
color: #69c350
|
color: #69c350
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.table > div {
|
||||||
|
width: 78vw;
|
||||||
|
height: 90vh;
|
||||||
|
overflow: scroll !important;
|
||||||
|
-ms-overflow-style: none; /*!* IE and Edge *!*/
|
||||||
|
scrollbar-width: none; /*!* Firefox *!*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.table > div::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -99,7 +99,16 @@ const archiveDocument = () => {
|
|||||||
:data="documentData.url"
|
:data="documentData.url"
|
||||||
class="previewEmbed"
|
class="previewEmbed"
|
||||||
type="application/pdf"
|
type="application/pdf"
|
||||||
|
v-if="!documentData.tags.includes('Bild')"
|
||||||
/>
|
/>
|
||||||
|
<img
|
||||||
|
v-else
|
||||||
|
alt=""
|
||||||
|
:src="documentData.url"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<UButton
|
<UButton
|
||||||
@click="openDocument"
|
@click="openDocument"
|
||||||
class="mt-3"
|
class="mt-3"
|
||||||
@@ -141,6 +150,13 @@ const archiveDocument = () => {
|
|||||||
class="h-full w-full"
|
class="h-full w-full"
|
||||||
:data="documentData.url"
|
:data="documentData.url"
|
||||||
type="application/pdf"
|
type="application/pdf"
|
||||||
|
v-if="!documentData.tags.includes('Bild')"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
class="h-full w-full"
|
||||||
|
:src="documentData.url"
|
||||||
|
alt=""
|
||||||
|
v-else
|
||||||
/>
|
/>
|
||||||
</UContainer>
|
</UContainer>
|
||||||
|
|
||||||
@@ -159,7 +175,11 @@ const archiveDocument = () => {
|
|||||||
Eingangsrechnung erstellen
|
Eingangsrechnung erstellen
|
||||||
</UButton>
|
</UButton>
|
||||||
</UButtonGroup>
|
</UButtonGroup>
|
||||||
|
<br>
|
||||||
|
<a
|
||||||
|
:href="documentData.url"
|
||||||
|
target="_blank"
|
||||||
|
>In neuen Tab anzeigen</a>
|
||||||
|
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="Tags ändern:"
|
label="Tags ändern:"
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const uploadFiles = async () => {
|
|||||||
let fileData = fileUploadFormData.value
|
let fileData = fileUploadFormData.value
|
||||||
fileData[type] = elementId
|
fileData[type] = elementId
|
||||||
|
|
||||||
await dataStore.uploadFiles(fileData, document.getElementById("fileUploadInput").files)
|
await dataStore.uploadFiles(fileData, document.getElementById("fileUploadInput").files,true)
|
||||||
|
|
||||||
uploadModalOpen.value = false;
|
uploadModalOpen.value = false;
|
||||||
uploadInProgress.value = false;
|
uploadInProgress.value = false;
|
||||||
@@ -40,7 +40,7 @@ const uploadFiles = async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<UModal
|
<USlideover
|
||||||
v-model="uploadModalOpen"
|
v-model="uploadModalOpen"
|
||||||
>
|
>
|
||||||
<UCard :ui="{ ring: '', divide: 'divide-y divide-gray-100 dark:divide-gray-800' }">
|
<UCard :ui="{ ring: '', divide: 'divide-y divide-gray-100 dark:divide-gray-800' }">
|
||||||
@@ -66,6 +66,7 @@ const uploadFiles = async () => {
|
|||||||
<UInput
|
<UInput
|
||||||
type="file"
|
type="file"
|
||||||
id="fileUploadInput"
|
id="fileUploadInput"
|
||||||
|
multiple
|
||||||
/>
|
/>
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
@@ -78,7 +79,12 @@ const uploadFiles = async () => {
|
|||||||
searchable-placeholder="Suchen..."
|
searchable-placeholder="Suchen..."
|
||||||
:options="tags"
|
:options="tags"
|
||||||
v-model="fileUploadFormData.tags"
|
v-model="fileUploadFormData.tags"
|
||||||
/>
|
>
|
||||||
|
<template #label>
|
||||||
|
<span v-if="fileUploadFormData.tags.length > 0">{{fileUploadFormData.tags.join(", ")}}</span>
|
||||||
|
<span v-else>Keine Tags ausgewählt</span>
|
||||||
|
</template>
|
||||||
|
</USelectMenu>
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -89,10 +95,11 @@ const uploadFiles = async () => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
</UCard>
|
</UCard>
|
||||||
</UModal>
|
</USlideover>
|
||||||
|
|
||||||
<UButton
|
<UButton
|
||||||
@click="openModal"
|
@click="openModal"
|
||||||
|
icon="i-heroicons-arrow-up-tray"
|
||||||
>
|
>
|
||||||
Hochladen
|
Hochladen
|
||||||
</UButton>
|
</UButton>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ const props = defineProps({
|
|||||||
type: String
|
type: String
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const { metaSymbol } = useShortcuts()
|
||||||
const dataStore = useDataStore()
|
const dataStore = useDataStore()
|
||||||
const user = useSupabaseUser()
|
const user = useSupabaseUser()
|
||||||
const supabase = useSupabaseClient()
|
const supabase = useSupabaseClient()
|
||||||
@@ -34,6 +35,14 @@ const historyItems = computed(() => {
|
|||||||
items = dataStore.historyItems.filter(i => i.incomingInvoice === elementId)
|
items = dataStore.historyItems.filter(i => i.incomingInvoice === elementId)
|
||||||
} else if(type === "document") {
|
} else if(type === "document") {
|
||||||
items = dataStore.historyItems.filter(i => i.document === elementId)
|
items = dataStore.historyItems.filter(i => i.document === elementId)
|
||||||
|
} else if(type === "contact") {
|
||||||
|
items = dataStore.historyItems.filter(i => i.contact === elementId)
|
||||||
|
} else if(type === "contract") {
|
||||||
|
items = dataStore.historyItems.filter(i => i.contract === elementId)
|
||||||
|
} else if(type === "inventoryitem") {
|
||||||
|
items = dataStore.historyItems.filter(i => i.inventoryitem === elementId)
|
||||||
|
} else if(type === "product") {
|
||||||
|
items = dataStore.historyItems.filter(i => i.product === elementId)
|
||||||
}
|
}
|
||||||
|
|
||||||
return items
|
return items
|
||||||
@@ -59,6 +68,14 @@ const addHistoryItem = async () => {
|
|||||||
addHistoryItemData.value.incomingInvoice = elementId
|
addHistoryItemData.value.incomingInvoice = elementId
|
||||||
} else if(type === "document") {
|
} else if(type === "document") {
|
||||||
addHistoryItemData.value.document = elementId
|
addHistoryItemData.value.document = elementId
|
||||||
|
} else if(type === "contact") {
|
||||||
|
addHistoryItemData.value.contact = elementId
|
||||||
|
} else if(type === "contract") {
|
||||||
|
addHistoryItemData.value.contract = elementId
|
||||||
|
} else if(type === "inventoryitem") {
|
||||||
|
addHistoryItemData.value.inventoryitem = elementId
|
||||||
|
} else if(type === "product") {
|
||||||
|
addHistoryItemData.value.product = elementId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -102,56 +119,55 @@ const renderText = (text) => {
|
|||||||
>
|
>
|
||||||
<UTextarea
|
<UTextarea
|
||||||
v-model="addHistoryItemData.text"
|
v-model="addHistoryItemData.text"
|
||||||
|
@keyup.meta.enter="addHistoryItem"
|
||||||
/>
|
/>
|
||||||
|
<!-- <template #help>
|
||||||
|
<UKbd>{{metaSymbol}}</UKbd> <UKbd>Enter</UKbd> Speichern
|
||||||
|
</template>-->
|
||||||
|
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<UButton @click="addHistoryItem">Hinzufügen</UButton>
|
<UButton @click="addHistoryItem">Speichern</UButton>
|
||||||
</template>
|
</template>
|
||||||
</UCard>
|
</UCard>
|
||||||
</UModal>
|
</UModal>
|
||||||
<UCard class="mt-5">
|
<Toolbar>
|
||||||
<template #header>
|
<UButton
|
||||||
<InputGroup>
|
@click="showAddHistoryItemModal = true"
|
||||||
<UButton
|
|
||||||
@click="showAddHistoryItemModal = true"
|
|
||||||
>
|
|
||||||
+ Eintrag
|
|
||||||
</UButton>
|
|
||||||
</InputGroup>
|
|
||||||
</template>
|
|
||||||
<div
|
|
||||||
v-if="historyItems.length > 0"
|
|
||||||
v-for="(item,index) in historyItems.slice().reverse()
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<UDivider
|
+ Eintrag
|
||||||
class="my-3"
|
</UButton>
|
||||||
v-if="index !== 0"
|
</Toolbar>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="historyItems.length > 0"
|
||||||
|
v-for="(item,index) in historyItems.slice().reverse()"
|
||||||
|
>
|
||||||
|
<UDivider
|
||||||
|
class="my-3"
|
||||||
|
v-if="index !== 0"
|
||||||
|
/>
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<UAvatar
|
||||||
|
v-if="!item.user"
|
||||||
|
:src="colorMode.value === 'light' ? '/spaces_hell.svg' : '/spaces.svg' "
|
||||||
/>
|
/>
|
||||||
<div class="flex items-center gap-3">
|
<UAvatar
|
||||||
<UAvatar
|
:alt="dataStore.profiles.find(profile => profile.id === item.user).fullName"
|
||||||
v-if="!item.user"
|
v-else
|
||||||
:src="colorMode.value === 'light' ? '/spaces_hell.svg' : '/spaces.svg' "
|
/>
|
||||||
/>
|
<div>
|
||||||
<UAvatar
|
<h3 v-if="item.user">{{dataStore.getProfileById(item.user) ? dataStore.getProfileById(item.user).fullName : ""}}</h3>
|
||||||
:alt="dataStore.profiles.find(profile => profile.id === item.user).fullName"
|
<h3 v-else>Spaces Bot</h3>
|
||||||
v-else
|
<span v-html="renderText(item.text)"/><br>
|
||||||
/>
|
<span class="text-gray-500">{{dayjs(item.created_at).format("DD.MM.YY HH:mm")}}</span>
|
||||||
<div>
|
|
||||||
<h3 v-if="item.user">{{dataStore.getProfileById(item.user) ? dataStore.getProfileById(item.user).fullName : ""}}</h3>
|
|
||||||
<h3 v-else>Spaces Bot</h3>
|
|
||||||
<span v-html="renderText(item.text)"/><br>
|
|
||||||
<span class="text-gray-500">{{dayjs(item.created_at).format("DD.MM.YY HH:mm")}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</UCard>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
14
spaces/components/Toolbar.vue
Normal file
14
spaces/components/Toolbar.vue
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<InputGroup>
|
||||||
|
<slot/>
|
||||||
|
</InputGroup>
|
||||||
|
<UDivider class="my-3"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -6,13 +6,15 @@ const colorMode = useColorMode()
|
|||||||
const userProfile = dataStore.getOwnProfile
|
const userProfile = dataStore.getOwnProfile
|
||||||
const supabase = useSupabaseClient()
|
const supabase = useSupabaseClient()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
dataStore.initializeData((await supabase.auth.getUser()).data.user.id)
|
||||||
|
|
||||||
const isLight = computed({
|
const isLight = computed({
|
||||||
get () {
|
get() {
|
||||||
return colorMode.value !== 'dark'
|
return colorMode.value !== 'dark'
|
||||||
},
|
},
|
||||||
set () {
|
set() {
|
||||||
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
|
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -52,12 +54,12 @@ const navLinks = [
|
|||||||
label: "Belege",
|
label: "Belege",
|
||||||
to: "/receipts",
|
to: "/receipts",
|
||||||
icon: "i-heroicons-document-text"
|
icon: "i-heroicons-document-text"
|
||||||
},/*
|
},
|
||||||
{
|
{
|
||||||
label: "Bank",
|
label: "Bank",
|
||||||
to: "/banking",
|
to: "/banking",
|
||||||
icon: "i-heroicons-currency-euro"
|
icon: "i-heroicons-currency-euro"
|
||||||
},*/
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -105,6 +107,11 @@ const navLinks = [
|
|||||||
to: "/documents",
|
to: "/documents",
|
||||||
icon: "i-heroicons-document"
|
icon: "i-heroicons-document"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "E-Mail",
|
||||||
|
to: "/email",
|
||||||
|
icon: "i-heroicons-envelope"
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},/*
|
},/*
|
||||||
{
|
{
|
||||||
@@ -122,7 +129,7 @@ const navLinks = [
|
|||||||
icon: "i-heroicons-clock"
|
icon: "i-heroicons-clock"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Stechuhr",
|
label: "Anwesenheiten",
|
||||||
to: "/workingtimes",
|
to: "/workingtimes",
|
||||||
icon: "i-heroicons-clock"
|
icon: "i-heroicons-clock"
|
||||||
},
|
},
|
||||||
@@ -156,6 +163,10 @@ const navLinks = [
|
|||||||
label: "Fahrzeuge",
|
label: "Fahrzeuge",
|
||||||
to: "/vehicles",
|
to: "/vehicles",
|
||||||
icon: "i-heroicons-truck"
|
icon: "i-heroicons-truck"
|
||||||
|
}, {
|
||||||
|
label: "Inventar",
|
||||||
|
to: "/inventoryitems",
|
||||||
|
icon: "i-heroicons-puzzle-piece"
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -173,6 +184,11 @@ const userMenuItems = ref([
|
|||||||
icon: "i-heroicons-cog-8-tooth",
|
icon: "i-heroicons-cog-8-tooth",
|
||||||
to: "/settings/numberRanges"
|
to: "/settings/numberRanges"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "Einstellungen",
|
||||||
|
icon: "i-heroicons-cog-8-tooth",
|
||||||
|
to: "/settings"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: 'Benutzer',
|
label: 'Benutzer',
|
||||||
icon: 'i-heroicons-user-group',
|
icon: 'i-heroicons-user-group',
|
||||||
@@ -180,127 +196,255 @@ const userMenuItems = ref([
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const links = [[{
|
||||||
|
label: 'Profil',
|
||||||
|
avatar: {
|
||||||
|
alt: userProfile ? userProfile.fullName : "XY"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
label: "Dashboard",
|
||||||
|
to: "/",
|
||||||
|
icon: "i-heroicons-home"
|
||||||
|
}], [{
|
||||||
|
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: "E-Mail",
|
||||||
|
to: "/email",
|
||||||
|
icon: "i-heroicons-envelope"
|
||||||
|
}],[{
|
||||||
|
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: "Belege",
|
||||||
|
to: "/receipts",
|
||||||
|
icon: "i-heroicons-document-text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Bank",
|
||||||
|
to: "/banking",
|
||||||
|
icon: "i-heroicons-currency-euro"
|
||||||
|
}], [{
|
||||||
|
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: "Zeiterfassung",
|
||||||
|
to: "/employees/timetracking",
|
||||||
|
icon: "i-heroicons-clock"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Anwesenheiten",
|
||||||
|
to: "/workingtimes",
|
||||||
|
icon: "i-heroicons-clock"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Abwesenheiten",
|
||||||
|
to: "/absenceRequests",
|
||||||
|
icon: "i-heroicons-document-text"
|
||||||
|
}],[{
|
||||||
|
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"
|
||||||
|
}, {
|
||||||
|
label: "Inventar",
|
||||||
|
to: "/inventoryitems",
|
||||||
|
icon: "i-heroicons-puzzle-piece"
|
||||||
|
},]
|
||||||
|
]
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="dataStore.loaded">
|
<div v-if="dataStore.loaded" class="flex justify-center flex-row">
|
||||||
<UHeader :links="navLinks" :to="null">
|
<!-- <UHeader :links="navLinks" :to="null">
|
||||||
<template #logo>
|
<template #logo>
|
||||||
<div id="logo">
|
<div id="logo">
|
||||||
<img
|
<img
|
||||||
:src="!isLight ? '/spaces.svg' : '/spaces_hell.svg'"
|
:src="!isLight ? '/spaces.svg' : '/spaces_hell.svg'"
|
||||||
alt="Logo"
|
alt="Logo"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #panel>
|
<template #panel>
|
||||||
<UNavigationTree :links="navLinks"/>
|
<UNavigationTree :links="navLinks"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #right>
|
<template #right>
|
||||||
|
|
||||||
<GlobalSearch/>
|
<GlobalSearch/>
|
||||||
|
|
||||||
<UButton
|
<UButton
|
||||||
@click="showUserMenu = true"
|
@click="showUserMenu = true"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
color="gray"
|
color="gray"
|
||||||
>
|
>
|
||||||
<UAvatar
|
<UAvatar
|
||||||
:alt="userProfile ? userProfile.firstName + ' ' + userProfile.lastName : '' "
|
:alt="userProfile ? userProfile.firstName + ' ' + userProfile.lastName : '' "
|
||||||
icon="i-heroicons-user-20-solid"
|
icon="i-heroicons-user-20-solid"
|
||||||
:chip-color="dataStore.notifications.filter(item => !item.read).length > 0 ? 'primary' : null"
|
:chip-color="dataStore.notifications.filter(item => !item.read).length > 0 ? 'primary' : null"
|
||||||
|
|
||||||
/>
|
/>
|
||||||
</UButton>
|
</UButton>
|
||||||
|
|
||||||
<USlideover
|
<USlideover
|
||||||
v-model="showUserMenu"
|
v-model="showUserMenu"
|
||||||
>
|
>
|
||||||
<UCard
|
<UCard
|
||||||
class="h-full"
|
class="h-full"
|
||||||
>
|
>
|
||||||
|
|
||||||
<UDivider
|
<div v-if="dataStore.getOwnProfile.tenants.length > 1">
|
||||||
class="my-3"
|
<UDivider
|
||||||
label="Tenant"
|
class="my-3"
|
||||||
/>
|
label="Tenant"
|
||||||
|
/>
|
||||||
|
|
||||||
<USelectMenu
|
<USelectMenu
|
||||||
:options="dataStore.getOwnProfile.tenants"
|
:options="dataStore.getOwnProfile.tenants"
|
||||||
option-attribute="name"
|
option-attribute="name"
|
||||||
value-attribute="id"
|
value-attribute="id"
|
||||||
v-model="dataStore.currentTenant"
|
v-model="dataStore.currentTenant"
|
||||||
@change="dataStore.changeTenant()"
|
@change="dataStore.changeTenant()"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
<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()
|
|
||||||
}"
|
|
||||||
/>-->
|
|
||||||
|
|
||||||
|
|
||||||
|
<UDivider
|
||||||
<template #footer>
|
class="my-3"
|
||||||
<InputGroup>
|
label="Menü"
|
||||||
<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')
|
|
||||||
|
|
||||||
}"
|
<UVerticalNavigation
|
||||||
>
|
:links="userMenuItems"
|
||||||
Ausloggen
|
/>
|
||||||
</UButton>
|
|
||||||
</InputGroup>
|
|
||||||
|
|
||||||
</template>
|
<!– <UDivider
|
||||||
|
class="my-3"
|
||||||
|
label="Benachrichtigungen"
|
||||||
|
/>
|
||||||
|
|
||||||
</UCard>
|
<UAlert
|
||||||
</USlideover>
|
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>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</UHeader>
|
||||||
|
<UDivider />-->
|
||||||
|
<div class="ml-2 mt-3" id="menuLeft">
|
||||||
|
|
||||||
|
<UVerticalNavigation
|
||||||
|
:links="links"
|
||||||
|
>
|
||||||
|
<template #avatar="{link}">
|
||||||
|
<UAvatar
|
||||||
|
v-if="link.avatar"
|
||||||
|
v-bind="link.avatar"
|
||||||
|
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</UVerticalNavigation>
|
||||||
|
</div>
|
||||||
|
|
||||||
</template>
|
|
||||||
</UHeader>
|
|
||||||
<UDivider />
|
|
||||||
<div class="m-3" id="contentContainer">
|
<div class="m-3" id="contentContainer">
|
||||||
<slot/>
|
<slot id="content"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -317,5 +461,28 @@ const userMenuItems = ref([
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
#menuLeft {
|
||||||
|
height: 95vh;
|
||||||
|
width: 20vw;
|
||||||
|
overflow-y: scroll;
|
||||||
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
|
scrollbar-width: none; /* Firefox */
|
||||||
|
}
|
||||||
|
|
||||||
|
#menuLeft::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#contentContainer {
|
||||||
|
width: 77vw;
|
||||||
|
height: 95vh;
|
||||||
|
}
|
||||||
|
/* -ms-overflow-style: none; !* IE and Edge *!
|
||||||
|
scrollbar-width: none; !* Firefox *!
|
||||||
|
}
|
||||||
|
|
||||||
|
#contentContainer::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}*/
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
"@vicons/ionicons5": "^0.12.0",
|
"@vicons/ionicons5": "^0.12.0",
|
||||||
"@vuepic/vue-datepicker": "^7.4.0",
|
"@vuepic/vue-datepicker": "^7.4.0",
|
||||||
"@zip.js/zip.js": "^2.7.32",
|
"@zip.js/zip.js": "^2.7.32",
|
||||||
"axios": "^1.6.2",
|
"axios": "^1.6.7",
|
||||||
"base64-arraybuffer": "^1.0.2",
|
"base64-arraybuffer": "^1.0.2",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"client-oauth2": "^4.3.3",
|
"client-oauth2": "^4.3.3",
|
||||||
|
|||||||
@@ -120,14 +120,6 @@ setupPage()
|
|||||||
>
|
>
|
||||||
Bearbeiten
|
Bearbeiten
|
||||||
</UButton>
|
</UButton>
|
||||||
<UButton
|
|
||||||
color="red"
|
|
||||||
class="ml-2"
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
Archivieren
|
|
||||||
</UButton>
|
|
||||||
<!-- TODO: Kunde archivieren -->
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ const calendarOptionsGrid = reactive({
|
|||||||
nowIndicator: true,
|
nowIndicator: true,
|
||||||
height: "80vh",
|
height: "80vh",
|
||||||
selectable: true,
|
selectable: true,
|
||||||
|
weekNumbers: true,
|
||||||
select: function(info) {
|
select: function(info) {
|
||||||
console.log(info)
|
console.log(info)
|
||||||
/*newEventData.value.resourceId = info.resource.id
|
/*newEventData.value.resourceId = info.resource.id
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
middleware: "auth"
|
middleware: "auth"
|
||||||
})
|
})
|
||||||
@@ -12,7 +14,7 @@ const id = ref(route.params.id ? route.params.id : null )
|
|||||||
|
|
||||||
//Store
|
//Store
|
||||||
const dataStore = useDataStore()
|
const dataStore = useDataStore()
|
||||||
let currentContact = null
|
let currentItem = null
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -25,10 +27,10 @@ const itemInfo = ref({
|
|||||||
//Functions
|
//Functions
|
||||||
const setupPage = () => {
|
const setupPage = () => {
|
||||||
if(mode.value === "show" || mode.value === "edit"){
|
if(mode.value === "show" || mode.value === "edit"){
|
||||||
currentContact = dataStore.getContactById(Number(useRoute().params.id))
|
currentItem = dataStore.getContactById(Number(useRoute().params.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mode.value === "edit") itemInfo.value = currentContact
|
if(mode.value === "edit") itemInfo.value = currentItem
|
||||||
|
|
||||||
if(mode.value === "create") {
|
if(mode.value === "create") {
|
||||||
let query = route.query
|
let query = route.query
|
||||||
@@ -41,213 +43,199 @@ const setupPage = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const editCustomer = async () => {
|
const editCustomer = async () => {
|
||||||
router.push(`/contacts/edit/${currentContact.id}`)
|
router.push(`/contacts/edit/${currentItem.id}`)
|
||||||
setupPage()
|
setupPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
const cancelEditorCreate = () => {
|
const cancelEditorCreate = () => {
|
||||||
mode.value = "show"
|
if(currentItem.value) {
|
||||||
itemInfo.value = {
|
router.push(`/contacts/show/${currentItem.value.id}`)
|
||||||
id: 0,
|
} else {
|
||||||
name: "",
|
router.push(`/contacts`)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setupPage()
|
setupPage()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<h1
|
||||||
<UCard v-if="currentContact && mode == 'show'" >
|
class="mb-3 font-bold text-2xl truncate"
|
||||||
<template #header>
|
v-if="currentItem"
|
||||||
<UBadge
|
>Ansprechpartner: {{currentItem.fullName}}</h1>
|
||||||
v-if="currentContact.active"
|
<UTabs
|
||||||
>
|
:items="[{label: 'Informationen'}, {label: 'Logbuch'}]"
|
||||||
Kontakt aktiv
|
v-if="currentItem && mode == 'show'"
|
||||||
</UBadge>
|
>
|
||||||
<UBadge
|
<template #item="{item}">
|
||||||
v-else
|
<UCard class="mt-5">
|
||||||
color="red"
|
<div v-if="item.label === 'Informationen'">
|
||||||
>
|
<Toolbar>
|
||||||
Kontakt inaktiv
|
<UButton
|
||||||
</UBadge>
|
v-if="mode == 'show' && currentItem.id"
|
||||||
{{currentContact.fullName}}
|
@click="editCustomer"
|
||||||
</template>
|
>
|
||||||
|
Bearbeiten
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
<InputGroup class="mb-3">
|
<UBadge
|
||||||
<UButton
|
v-if="currentItem.active"
|
||||||
v-if="currentContact.customer"
|
>
|
||||||
:to="`/customers/show/${currentContact.customer}`"
|
Kontakt aktiv
|
||||||
>
|
</UBadge>
|
||||||
Zum Kunden
|
<UBadge
|
||||||
</UButton>
|
v-else
|
||||||
<UButton
|
color="red"
|
||||||
v-if="currentContact.vendor"
|
>
|
||||||
:to="`/vendors/show/${currentContact.vendor}`"
|
Kontakt inaktiv
|
||||||
>
|
</UBadge>
|
||||||
Zum Lieferanten
|
|
||||||
</UButton>
|
|
||||||
</InputGroup>
|
|
||||||
|
|
||||||
<span v-if="currentContact.customer">Kunde: {{dataStore.customers.find(customer => customer.id === currentContact.customer) ? dataStore.customers.find(customer => customer.id === currentContact.customer).name : "" }}</span><br>
|
<div class="text-wrap mt-3">
|
||||||
<span v-if="currentContact.vendor">Lieferant: {{dataStore.vendors.find(vendor => vendor.id === currentContact.vendor) ? dataStore.vendors.find(vendor => vendor.id === currentContact.vendor).name : ""}}</span><br>
|
<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>
|
||||||
<span>E-Mail: {{currentContact.email}}</span><br>
|
|
||||||
<span>Mobil: {{currentContact.phoneMobile}}</span><br>
|
|
||||||
<span>Festnetz: {{currentContact.phoneHome}}</span><br>
|
|
||||||
<span>Rolle: {{currentContact.role}}</span>
|
|
||||||
|
|
||||||
|
|
||||||
|
<p>E-Mail: {{currentItem.email}}</p>
|
||||||
<DevOnly>
|
<p>Mobil: {{currentItem.phoneMobile}}</p>
|
||||||
<UDivider
|
<p>Festnetz: {{currentItem.phoneHome}}</p>
|
||||||
class="my-3"
|
<p>Rolle: {{currentItem.role}}</p>
|
||||||
/>
|
</div>
|
||||||
{{currentContact}}
|
|
||||||
</DevOnly>
|
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
</div>
|
||||||
<UButton
|
<div v-else-if="item.label === 'Logbuch'">
|
||||||
v-if="mode == 'show' && currentContact.id"
|
<HistoryDisplay
|
||||||
@click="editCustomer"
|
type="contact"
|
||||||
>
|
v-if="currentItem"
|
||||||
Bearbeiten
|
:element-id="currentItem.id"
|
||||||
</UButton>
|
/>
|
||||||
<UButton
|
</div>
|
||||||
color="red"
|
</UCard>
|
||||||
class="ml-2"
|
</template>
|
||||||
disabled
|
</UTabs>
|
||||||
>
|
<UCard v-else-if="mode == 'edit' || mode == 'create'" >
|
||||||
Archivieren
|
<template #header>
|
||||||
</UButton>
|
{{itemInfo.fullName}}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<UFormGroup
|
||||||
|
label="Anrede:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.salutation"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Vorname:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.firstName"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Nachname:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.lastName"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
|
||||||
|
<UFormGroup
|
||||||
</UCard>
|
label="Kunde:"
|
||||||
<UCard v-else-if="mode == 'edit' || mode == 'create'" >
|
>
|
||||||
<template #header>
|
<USelectMenu
|
||||||
{{itemInfo.fullName}}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<UFormGroup
|
|
||||||
label="Anrede:"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="itemInfo.salutation"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup
|
|
||||||
label="Vorname:"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="itemInfo.firstName"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup
|
|
||||||
label="Nachname:"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="itemInfo.lastName"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
|
|
||||||
<UFormGroup
|
|
||||||
label="Kunde:"
|
|
||||||
>
|
|
||||||
<USelectMenu
|
|
||||||
v-model="itemInfo.customer"
|
v-model="itemInfo.customer"
|
||||||
option-attribute="name"
|
option-attribute="name"
|
||||||
value-attribute="id"
|
value-attribute="id"
|
||||||
:options="dataStore.customers"
|
:options="dataStore.customers"
|
||||||
searchable
|
searchable
|
||||||
:search-attributes="['name']"
|
:search-attributes="['name']"
|
||||||
>
|
|
||||||
<template #label>
|
|
||||||
{{dataStore.customers.find(customer => customer.id === itemInfo.customer) ? dataStore.customers.find(customer => customer.id === itemInfo.customer).name : "Kunde auswählen"}}
|
|
||||||
</template>
|
|
||||||
</USelectMenu>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup
|
|
||||||
label="Lieferant:"
|
|
||||||
>
|
>
|
||||||
<USelectMenu
|
<template #label>
|
||||||
|
{{dataStore.customers.find(customer => customer.id === itemInfo.customer) ? dataStore.customers.find(customer => customer.id === itemInfo.customer).name : "Kunde auswählen"}}
|
||||||
|
</template>
|
||||||
|
</USelectMenu>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Lieferant:"
|
||||||
|
>
|
||||||
|
<USelectMenu
|
||||||
v-model="itemInfo.vendor"
|
v-model="itemInfo.vendor"
|
||||||
option-attribute="name"
|
option-attribute="name"
|
||||||
value-attribute="id"
|
value-attribute="id"
|
||||||
:options="dataStore.vendors"
|
:options="dataStore.vendors"
|
||||||
searchable
|
searchable
|
||||||
:search-attributes="['name']"
|
:search-attributes="['name']"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
{{dataStore.vendors.find(vendor => vendor.id === itemInfo.vendor) ? dataStore.vendors.find(vendor => vendor.id === itemInfo.vendor).name : "Lieferant auswählen"}}
|
{{dataStore.vendors.find(vendor => vendor.id === itemInfo.vendor) ? dataStore.vendors.find(vendor => vendor.id === itemInfo.vendor).name : "Lieferant auswählen"}}
|
||||||
</template>
|
</template>
|
||||||
</USelectMenu>
|
</USelectMenu>
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
|
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="Kontakt aktiv:"
|
label="Kontakt aktiv:"
|
||||||
>
|
>
|
||||||
<UCheckbox
|
<UCheckbox
|
||||||
v-model="itemInfo.active"
|
v-model="itemInfo.active"
|
||||||
/>
|
/>
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
|
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="E-Mail:"
|
label="E-Mail:"
|
||||||
>
|
>
|
||||||
<UInput
|
<UInput
|
||||||
v-model="itemInfo.email"
|
v-model="itemInfo.email"
|
||||||
/>
|
/>
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="Mobil:"
|
label="Mobil:"
|
||||||
>
|
>
|
||||||
<UInput
|
<UInput
|
||||||
v-model="itemInfo.phoneMobile"
|
v-model="itemInfo.phoneMobile"
|
||||||
/>
|
/>
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="Festnetz:"
|
label="Festnetz:"
|
||||||
>
|
>
|
||||||
<UInput
|
<UInput
|
||||||
v-model="itemInfo.phoneHome"
|
v-model="itemInfo.phoneHome"
|
||||||
/>
|
/>
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="Rolle:"
|
label="Rolle:"
|
||||||
>
|
>
|
||||||
<UInput
|
<UInput
|
||||||
v-model="itemInfo.role"
|
v-model="itemInfo.role"
|
||||||
/>
|
/>
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<UButton
|
<UButton
|
||||||
v-if="mode == 'edit'"
|
v-if="mode == 'edit'"
|
||||||
@click="dataStore.updateItem('contacts',{...itemInfo, fullName: `${itemInfo.firstName} ${itemInfo.lastName}`})"
|
@click="dataStore.updateItem('contacts',{...itemInfo, fullName: `${itemInfo.firstName} ${itemInfo.lastName}`})"
|
||||||
>
|
>
|
||||||
Speichern
|
Speichern
|
||||||
</UButton>
|
</UButton>
|
||||||
<UButton
|
<UButton
|
||||||
v-else-if="mode == 'create'"
|
v-else-if="mode == 'create'"
|
||||||
@click="dataStore.createNewItem('contacts',{...itemInfo, fullName: `${itemInfo.firstName} ${itemInfo.lastName}`})"
|
@click="dataStore.createNewItem('contacts',{...itemInfo, fullName: `${itemInfo.firstName} ${itemInfo.lastName}`})"
|
||||||
>
|
>
|
||||||
Erstellen
|
Erstellen
|
||||||
</UButton>
|
</UButton>
|
||||||
<UButton
|
<UButton
|
||||||
@click="cancelEditorCreate"
|
@click="cancelEditorCreate"
|
||||||
color="red"
|
color="red"
|
||||||
class="ml-2"
|
class="ml-2"
|
||||||
>
|
>
|
||||||
Abbrechen
|
Abbrechen
|
||||||
</UButton>
|
</UButton>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</UCard>
|
</UCard>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -1,18 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="main">
|
<Toolbar>
|
||||||
<!-- TODO: Kontakte erstellen und dem Kunden zuweisen -->
|
<UButton @click="router.push(`/contacts/create/`)">+ Kontakt</UButton>
|
||||||
|
|
||||||
<InputGroup>
|
|
||||||
<UButton @click="router.push(`/contacts/create/`)">+ Kontakt</UButton>
|
|
||||||
|
|
||||||
<UInput
|
|
||||||
v-model="searchString"
|
|
||||||
placeholder="Suche..."
|
|
||||||
/>
|
|
||||||
</InputGroup>
|
|
||||||
|
|
||||||
|
<UInput
|
||||||
|
v-model="searchString"
|
||||||
|
placeholder="Suche..."
|
||||||
|
/>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="table">
|
||||||
<UTable
|
<UTable
|
||||||
:rows="filteredRows"
|
:rows="filteredRows"
|
||||||
:columns="itemColumns"
|
:columns="itemColumns"
|
||||||
@@ -26,8 +23,8 @@
|
|||||||
{{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>
|
||||||
</UTable>
|
</UTable>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
middleware: "auth"
|
middleware: "auth"
|
||||||
})
|
})
|
||||||
@@ -13,7 +15,7 @@ const id = ref(route.params.id ? route.params.id : null )
|
|||||||
//Store
|
//Store
|
||||||
const {customers, contracts } = storeToRefs(useDataStore())
|
const {customers, contracts } = storeToRefs(useDataStore())
|
||||||
|
|
||||||
let currentContract = null
|
let currentItem = ref(null)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -21,32 +23,37 @@ let currentContract = null
|
|||||||
const mode = ref(route.params.mode || "show")
|
const mode = ref(route.params.mode || "show")
|
||||||
const itemInfo = ref({
|
const itemInfo = ref({
|
||||||
name: "",
|
name: "",
|
||||||
customer: 0,
|
customer: null,
|
||||||
active: true
|
active: true
|
||||||
})
|
})
|
||||||
|
|
||||||
//Functions
|
//Functions
|
||||||
const setupPage = () => {
|
const setupPage = () => {
|
||||||
if(mode.value === "show" || mode.value === "edit"){
|
if(mode.value === "show" || mode.value === "edit"){
|
||||||
currentContract = dataStore.getContractById(Number(useRoute().params.id))
|
currentItem.value = dataStore.getContractById(Number(useRoute().params.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mode.value === "edit") itemInfo.value = currentContract
|
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)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const editCustomer = async () => {
|
const editCustomer = async () => {
|
||||||
router.push(`/contracts/edit/${currentContract.id}`)
|
router.push(`/contracts/edit/${currentItem.value.id}`)
|
||||||
setupPage()
|
setupPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
const cancelEditorCreate = () => {
|
const cancelEditorCreate = () => {
|
||||||
mode.value = "show"
|
if(currentItem.value) {
|
||||||
itemInfo.value = {
|
router.push(`/contracts/show/${currentItem.value.id}`)
|
||||||
id: 0,
|
} else {
|
||||||
name: "",
|
router.push(`/contracts/`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,130 +61,136 @@ setupPage()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<h1
|
||||||
<UCard v-if="currentContract && mode == 'show'" >
|
class="text-center my-3 font-bold text-2xl"
|
||||||
<template #header>
|
v-if="currentItem"
|
||||||
<UBadge
|
>{{currentItem.name}}</h1>
|
||||||
v-if="currentContract.active"
|
<UTabs
|
||||||
>
|
v-if="currentItem && mode == 'show'"
|
||||||
Vertrag aktiv
|
:items="[{label: 'Informationen'}, {label: 'Logbuch'}, {label: 'Dokumente'}]"
|
||||||
</UBadge>
|
>
|
||||||
<UBadge
|
<template #item="{item}">
|
||||||
v-else
|
<UCard class="mt-5">
|
||||||
color="red"
|
<div v-if="item.label === 'Informationen'">
|
||||||
>
|
<Toolbar>
|
||||||
Vertrag gesperrt
|
<UButton
|
||||||
</UBadge>
|
v-if="mode == 'show' && currentItem.id"
|
||||||
{{currentContract.name}}
|
@click="editCustomer"
|
||||||
</template>
|
>
|
||||||
|
Bearbeiten
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
Kundennummer: {{dataStore.customers.find(customer => customer.id === currentContract.customer) ? dataStore.customers.find(customer => customer.id === currentContract.customer).name : ""}} <br>
|
<UBadge
|
||||||
|
v-if="currentItem.active"
|
||||||
|
>
|
||||||
|
Vertrag aktiv
|
||||||
|
</UBadge>
|
||||||
|
<UBadge
|
||||||
|
v-else
|
||||||
|
color="red"
|
||||||
|
>
|
||||||
|
Vertrag gesperrt
|
||||||
|
</UBadge>
|
||||||
|
|
||||||
<UDivider
|
<div class="text-wrap">
|
||||||
class="my-2"
|
<p>Kundennummer: <nuxt-link :to="`/customers/show/${currentItem.customer}`">{{dataStore.getCustomerById(currentItem.customer).name}}</nuxt-link></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<UDivider
|
||||||
|
class="my-2"
|
||||||
|
/>
|
||||||
|
|
||||||
|
Beschreibung:<br>
|
||||||
|
{{currentItem.description}}<br>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Logbuch'">
|
||||||
|
<HistoryDisplay
|
||||||
|
type="contract"
|
||||||
|
v-if="currentItem"
|
||||||
|
:element-id="currentItem.id"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Dokumente'">
|
||||||
|
<Toolbar>
|
||||||
|
<DocumentUpload
|
||||||
|
type="contract"
|
||||||
|
:element-id="currentItem.id"
|
||||||
|
/>
|
||||||
|
</Toolbar>
|
||||||
|
<DocumentList
|
||||||
|
:documents="dataStore.getDocumentsByContractId(currentItem.id)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</UCard>
|
||||||
|
</template>
|
||||||
|
</UTabs>
|
||||||
|
<UCard v-else-if="mode == 'edit' || mode == 'create'" >
|
||||||
|
|
||||||
|
<UFormGroup
|
||||||
|
label="Name:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.name"
|
||||||
/>
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
|
||||||
Beschreibung:<br>
|
<UFormGroup
|
||||||
{{currentContract.description}}<br>
|
label="Kunde:"
|
||||||
|
>
|
||||||
<InputGroup>
|
<USelectMenu
|
||||||
<DocumentUpload
|
|
||||||
type="contract"
|
|
||||||
:element-id="currentContract.id"
|
|
||||||
/>
|
|
||||||
</InputGroup>
|
|
||||||
|
|
||||||
<DocumentList
|
|
||||||
:documents="dataStore.getDocumentsByContractId(currentContract.id)"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<DevOnly>
|
|
||||||
{{currentContract}}
|
|
||||||
</DevOnly>
|
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<UButton
|
|
||||||
v-if="mode == 'show' && currentContract.id"
|
|
||||||
@click="editCustomer"
|
|
||||||
>
|
|
||||||
Bearbeiten
|
|
||||||
</UButton>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</UCard>
|
|
||||||
<UCard v-else-if="mode == 'edit' || mode == 'create'" >
|
|
||||||
<template #header>
|
|
||||||
<UBadge>{{itemInfo.customerNumber}}</UBadge> {{itemInfo.name}}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<UFormGroup
|
|
||||||
label="Name:"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="itemInfo.name"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
|
|
||||||
<UFormGroup
|
|
||||||
label="Kunde:"
|
|
||||||
>
|
|
||||||
<USelectMenu
|
|
||||||
v-model="itemInfo.customer"
|
v-model="itemInfo.customer"
|
||||||
option-attribute="name"
|
option-attribute="name"
|
||||||
value-attribute="id"
|
value-attribute="id"
|
||||||
:options="customers"
|
:options="customers"
|
||||||
searchable
|
searchable
|
||||||
:search-attributes="['name']"
|
:search-attributes="['name']"
|
||||||
>
|
|
||||||
<template #label>
|
|
||||||
{{dataStore.customers.find(customer => customer.id === itemInfo.customer) ? dataStore.customers.find(customer => customer.id === itemInfo.customer).name : itemInfo.customer}}
|
|
||||||
</template>
|
|
||||||
</USelectMenu>
|
|
||||||
</UFormGroup>
|
|
||||||
|
|
||||||
<UFormGroup
|
|
||||||
label="Vertrag aktiv:"
|
|
||||||
>
|
>
|
||||||
<UCheckbox
|
<template #label>
|
||||||
v-model="itemInfo.active"
|
{{dataStore.getCustomerById(itemInfo.customer) ? dataStore.getCustomerById(itemInfo.customer).name : "Kein Kunde ausgewählt" }}
|
||||||
/>
|
</template>
|
||||||
</UFormGroup>
|
</USelectMenu>
|
||||||
<UFormGroup
|
</UFormGroup>
|
||||||
label="Beschreibung:"
|
|
||||||
|
<UFormGroup
|
||||||
|
label="Vertrag aktiv:"
|
||||||
|
>
|
||||||
|
<UCheckbox
|
||||||
|
v-model="itemInfo.active"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Beschreibung:"
|
||||||
|
>
|
||||||
|
<UTextarea
|
||||||
|
v-model="itemInfo.description"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<UButton
|
||||||
|
v-if="mode === 'edit'"
|
||||||
|
@click="dataStore.updateItem('contracts',itemInfo)"
|
||||||
>
|
>
|
||||||
<UTextarea
|
Speichern
|
||||||
v-model="itemInfo.description"
|
</UButton>
|
||||||
/>
|
<UButton
|
||||||
</UFormGroup>
|
v-else-if="mode === 'create'"
|
||||||
|
@click="dataStore.createNewItem('contracts',itemInfo)"
|
||||||
|
>
|
||||||
|
Erstellen
|
||||||
|
</UButton>
|
||||||
|
<UButton
|
||||||
|
@click="cancelEditorCreate"
|
||||||
|
color="red"
|
||||||
|
class="ml-2"
|
||||||
|
>
|
||||||
|
Abbrechen
|
||||||
|
</UButton>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</UCard>
|
||||||
<template #footer>
|
|
||||||
<UButton
|
|
||||||
v-if="mode == 'edit'"
|
|
||||||
@click="dataStore.updateItem('contracts',itemInfo)"
|
|
||||||
>
|
|
||||||
Speichern
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
v-else-if="mode == 'create'"
|
|
||||||
@click="dataStore.createNewItem('contracts',itemInfo)"
|
|
||||||
>
|
|
||||||
Erstellen
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
@click="cancelEditorCreate"
|
|
||||||
color="red"
|
|
||||||
class="ml-2"
|
|
||||||
>
|
|
||||||
Abbrechen
|
|
||||||
</UButton>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
</UCard>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -42,117 +42,151 @@ const editCustomer = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cancelEditorCreate = () => {
|
const cancelEditorCreate = () => {
|
||||||
mode.value = "show"
|
if(currentItem.value) {
|
||||||
itemInfo.value = {
|
router.push(`/customers/show/${currentItem.value.id}`)
|
||||||
id: 0,
|
} else {
|
||||||
name: "",
|
router.push(`/customers`)
|
||||||
infoData: {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setupPage()
|
setupPage()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<UCard v-if="currentItem && mode == 'show'" >
|
<h1
|
||||||
<template #header>
|
class="mb-3 font-bold text-3xl truncate"
|
||||||
<UBadge
|
v-if="currentItem "
|
||||||
v-if="currentItem.active"
|
>Kunde: {{currentItem.name}}</h1>
|
||||||
>
|
<UTabs
|
||||||
Kunde aktiv
|
v-if="currentItem && mode == 'show'"
|
||||||
</UBadge>
|
:items="[{label: 'Informationen'}, {label: 'Logbuch'}, {label: 'Projekte'},{label: 'Objekte'},{label: 'Verträge'}, {label: 'Ansprechpartner'}]"
|
||||||
<UBadge
|
>
|
||||||
v-else
|
<template #item="{item}">
|
||||||
color="red"
|
<UCard class="mt-5">
|
||||||
>
|
<div v-if="item.label === 'Informationen'">
|
||||||
Kunde gesperrt
|
<Toolbar>
|
||||||
</UBadge>
|
<UButton
|
||||||
{{currentItem.name}}
|
v-if="mode == 'show' && currentItem.id"
|
||||||
|
@click="editCustomer"
|
||||||
|
>
|
||||||
|
Bearbeiten
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
|
<UBadge
|
||||||
|
v-if="currentItem.active"
|
||||||
|
>
|
||||||
|
Kunde aktiv
|
||||||
|
</UBadge>
|
||||||
|
<UBadge
|
||||||
|
v-else
|
||||||
|
color="red"
|
||||||
|
>
|
||||||
|
Kunde gesperrt
|
||||||
|
</UBadge>
|
||||||
|
|
||||||
|
<div class="text-wrap">
|
||||||
|
<p>Kundennummer: {{currentItem.customerNumber}}</p>
|
||||||
|
<p v-if="currentItem.infoData.street">Straße + Hausnummer: {{currentItem.infoData.street}}<br></p>
|
||||||
|
<p v-if="currentItem.infoData.zip && currentItem.infoData.city">PLZ + Ort: {{currentItem.infoData.zip}} {{currentItem.infoData.city}}<br></p>
|
||||||
|
<p v-if="currentItem.infoData.tel">Telefon: {{currentItem.infoData.tel}}<br></p>
|
||||||
|
<p v-if="currentItem.infoData.email">E-Mail: {{currentItem.infoData.email}}<br></p>
|
||||||
|
<p v-if="currentItem.infoData.web">Web: {{currentItem.infoData.web}}<br></p>
|
||||||
|
<p v-if="currentItem.infoData.ustid">USt-Id: {{currentItem.infoData.ustid}}<br></p>
|
||||||
|
<p>Notizen: {{currentItem.notes}}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Logbuch'">
|
||||||
|
<HistoryDisplay
|
||||||
|
type="customer"
|
||||||
|
v-if="currentItem"
|
||||||
|
:element-id="currentItem.id"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Projekte'">
|
||||||
|
<Toolbar>
|
||||||
|
<UButton
|
||||||
|
@click="router.push(`/projects/create?customer=${currentItem.id}`)"
|
||||||
|
>
|
||||||
|
+ Projekt
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
<UTable
|
||||||
|
:rows="dataStore.getProjectsByCustomerId(currentItem.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' }"
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
</UTable>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Objekte'">
|
||||||
|
<Toolbar>
|
||||||
|
<UButton
|
||||||
|
@click="router.push(`/plants/create?customer=${currentItem.id}`)"
|
||||||
|
>
|
||||||
|
+ Objekt
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
<UTable
|
||||||
|
:rows="dataStore.getPlantsByCustomerId(currentItem.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' }"
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
</UTable>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Verträge'">
|
||||||
|
<Toolbar>
|
||||||
|
<UButton
|
||||||
|
@click="router.push(`/contracts/create?customer=${currentItem.id}`)"
|
||||||
|
>
|
||||||
|
+ Objekt
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
<UTable
|
||||||
|
:rows="dataStore.getContractsByCustomerId(currentItem.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' }"
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
</UTable>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Ansprechpartner'">
|
||||||
|
<Toolbar>
|
||||||
|
<UButton
|
||||||
|
@click="router.push(`/contacts/create?customer=${currentItem.id}`)"
|
||||||
|
>
|
||||||
|
+ Ansprechpartner
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
<UTable
|
||||||
|
:rows="dataStore.getContactsByCustomerId(currentItem.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' }"
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
</UTable>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</UCard>
|
||||||
</template>
|
</template>
|
||||||
|
</UTabs>
|
||||||
<InputGroup>
|
|
||||||
<UButton
|
|
||||||
@click="router.push(`/projects/create?customer=${currentItem.id}`)"
|
|
||||||
>
|
|
||||||
+ Projekt
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
@click="router.push(`/contacts/create?customer=${currentItem.id}`)"
|
|
||||||
>
|
|
||||||
+ Ansprechpartner
|
|
||||||
</UButton>
|
|
||||||
</InputGroup>
|
|
||||||
|
|
||||||
|
|
||||||
Kundennummer: {{currentItem.customerNumber}} <br>
|
<UCard v-else-if="mode === 'edit' || mode === 'create'" >
|
||||||
|
|
||||||
<UDivider
|
|
||||||
class="my-2"
|
|
||||||
/>
|
|
||||||
|
|
||||||
Informationen:<br>
|
|
||||||
<div v-if="currentItem.infoData">
|
|
||||||
<span v-if="currentItem.infoData.street">Straße + Hausnummer: {{currentItem.infoData.street}}<br></span>
|
|
||||||
<span v-if="currentItem.infoData.zip && currentItem.infoData.city">PLZ + Ort: {{currentItem.infoData.zip}} {{currentItem.infoData.city}}<br></span>
|
|
||||||
<span v-if="currentItem.infoData.tel">Telefon: {{currentItem.infoData.tel}}<br></span>
|
|
||||||
<span v-if="currentItem.infoData.email">E-Mail: {{currentItem.infoData.email}}<br></span>
|
|
||||||
<span v-if="currentItem.infoData.web">Web: {{currentItem.infoData.web}}<br></span>
|
|
||||||
<span v-if="currentItem.infoData.ustid">USt-Id: {{currentItem.infoData.ustid}}<br></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<UDivider
|
|
||||||
class="my-2"
|
|
||||||
/>
|
|
||||||
|
|
||||||
Notizen:<br>
|
|
||||||
{{currentItem.notes}}<br>
|
|
||||||
|
|
||||||
<UDivider
|
|
||||||
class="my-2"
|
|
||||||
/>
|
|
||||||
|
|
||||||
Kontakte: <br>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li
|
|
||||||
v-for="contact in dataStore.getContactsByCustomerId(currentItem.id)"
|
|
||||||
>
|
|
||||||
<router-link :to="'/contacts/show/' + contact.id">{{contact.salutation}} {{contact.fullName}} - {{contact.role}}</router-link>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<UButton
|
|
||||||
v-if="mode == 'show' && currentItem.id"
|
|
||||||
@click="editCustomer"
|
|
||||||
>
|
|
||||||
Bearbeiten
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
color="red"
|
|
||||||
class="ml-2"
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
Archivieren
|
|
||||||
</UButton>
|
|
||||||
<!-- TODO: Kunde archivieren -->
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</UCard>
|
|
||||||
<UCard v-else-if="mode == 'edit' || mode == 'create'" >
|
|
||||||
<template #header v-if="mode === 'edit'">
|
<template #header v-if="mode === 'edit'">
|
||||||
<UBadge>{{itemInfo.customerNumber}}</UBadge>{{itemInfo.name}}
|
<UBadge>{{itemInfo.customerNumber}}</UBadge>{{itemInfo.name}}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="Name:"
|
label="Name:"
|
||||||
>
|
>
|
||||||
@@ -262,11 +296,7 @@ setupPage()
|
|||||||
|
|
||||||
</UCard>
|
</UCard>
|
||||||
|
|
||||||
<HistoryDisplay
|
|
||||||
type="customer"
|
|
||||||
v-if="currentItem"
|
|
||||||
:element-id="currentItem.id"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -1,18 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="main">
|
|
||||||
<!-- TODO: Kontakte erstellen und dem Kunden zuweisen -->
|
|
||||||
|
|
||||||
<div class="flex items-center gap-1">
|
|
||||||
<UButton @click="router.push(`/customers/create/`)">+ Kunde</UButton>
|
|
||||||
|
|
||||||
<UInput
|
|
||||||
v-model="searchString"
|
|
||||||
placeholder="Suche..."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<Toolbar>
|
||||||
|
<UButton @click="router.push(`/customers/create/`)">+ Kunde</UButton>
|
||||||
|
|
||||||
|
<UInput
|
||||||
|
v-model="searchString"
|
||||||
|
placeholder="Suche..."
|
||||||
|
/>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
|
<div class="table">
|
||||||
<UTable
|
<UTable
|
||||||
:rows="filteredRows"
|
:rows="filteredRows"
|
||||||
:columns="customerColumns"
|
:columns="customerColumns"
|
||||||
@@ -20,7 +17,6 @@
|
|||||||
|
|
||||||
: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' }"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -74,8 +74,11 @@ const downloadSelected = async () => {
|
|||||||
// Map the response to an array of objects containing the file name and blob
|
// Map the response to an array of objects containing the file name and blob
|
||||||
const downloadedFiles = response.map((result, index) => {
|
const downloadedFiles = response.map((result, index) => {
|
||||||
if (result.status === "fulfilled") {
|
if (result.status === "fulfilled") {
|
||||||
|
|
||||||
|
console.log(files[index].split("/")[files[index].split("/").length -1])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: files[index],
|
name: files[index].split("/")[files[index].split("/").length -1],
|
||||||
blob: result.value.data,
|
blob: result.value.data,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -109,7 +112,7 @@ const downloadSelected = async () => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<InputGroup>
|
<Toolbar>
|
||||||
<UButton @click="uploadModalOpen = true">Hochladen</UButton>
|
<UButton @click="uploadModalOpen = true">Hochladen</UButton>
|
||||||
<UButton
|
<UButton
|
||||||
@click="downloadSelected"
|
@click="downloadSelected"
|
||||||
@@ -127,8 +130,8 @@ const downloadSelected = async () => {
|
|||||||
</USelectMenu>
|
</USelectMenu>
|
||||||
|
|
||||||
|
|
||||||
</InputGroup>
|
</Toolbar>
|
||||||
<div >
|
<div class="scrollList">
|
||||||
<USlideover
|
<USlideover
|
||||||
v-model="uploadModalOpen"
|
v-model="uploadModalOpen"
|
||||||
>
|
>
|
||||||
|
|||||||
316
spaces/pages/email.vue
Normal file
316
spaces/pages/email.vue
Normal file
@@ -0,0 +1,316 @@
|
|||||||
|
<script setup>
|
||||||
|
import axios from 'axios'
|
||||||
|
const dataStore = useDataStore()
|
||||||
|
const accounts = ref([])
|
||||||
|
|
||||||
|
//accounts.value = dataStore.emailAccounts.map(i => { return { label: i.emailAddress, emailEngingeId: i.emailEngineId }})
|
||||||
|
|
||||||
|
const mailboxes = ref({})
|
||||||
|
const messages = ref([])
|
||||||
|
const selectedMailbox = ref("INBOX")
|
||||||
|
const selectedAccount = ref(null)
|
||||||
|
const selectedMessage = ref(null)
|
||||||
|
const setup = async () => {
|
||||||
|
accounts.value = dataStore.emailAccounts.map((i,index) => {
|
||||||
|
let item = { label: i.emailAddress, emailEngineId: i.emailEngineId }
|
||||||
|
if(index === 0) {
|
||||||
|
item.defaultOpen = true
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
for await (const account of accounts.value) {
|
||||||
|
console.log(account.emailEngineId)
|
||||||
|
const {data,error} = await axios.get(`http://157.90.231.142:3000/v1/account/${account.emailEngineId}/mailboxes`, {headers: { 'Authorization': 'Bearer dadb572465fba648590f31557f68028a750b47b278d87c1773e8fd09670eec59'}})
|
||||||
|
console.log(data)
|
||||||
|
console.log(error)
|
||||||
|
mailboxes.value[account.emailEngineId] = data.mailboxes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const selectMailbox = async (account, mailbox) => {
|
||||||
|
selectedMailbox.value = mailbox
|
||||||
|
const {data,error} = await axios.get(`http://157.90.231.142:3000/v1/account/${account}/messages?path=${ mailbox.path}`, {headers: { 'Authorization': 'Bearer dadb572465fba648590f31557f68028a750b47b278d87c1773e8fd09670eec59'}})
|
||||||
|
console.log(data)
|
||||||
|
console.log(error)
|
||||||
|
messages.value = data.messages
|
||||||
|
selectedAccount.value = account
|
||||||
|
}
|
||||||
|
const messageHTML = ref(null)
|
||||||
|
const messageText = ref(null)
|
||||||
|
const selectMessage = async (account, message) => {
|
||||||
|
console.log(message)
|
||||||
|
selectedMessage.value = message
|
||||||
|
const {data,error} = await axios.get(`http://157.90.231.142:3000/v1/account/${account}/text/${message.text.id}`, {headers: { 'Authorization': 'Bearer dadb572465fba648590f31557f68028a750b47b278d87c1773e8fd09670eec59'}})
|
||||||
|
messageHTML.value = data.html
|
||||||
|
messageText.value = data.plain
|
||||||
|
}
|
||||||
|
|
||||||
|
const addFlags = async (account, message, flags) => {
|
||||||
|
console.log(flags)
|
||||||
|
const {data,error} = await axios({
|
||||||
|
method: "PUT",
|
||||||
|
url: `http://157.90.231.142:3000/v1/account/${account}/message/${message.id}`,
|
||||||
|
headers: { 'Authorization': 'Bearer dadb572465fba648590f31557f68028a750b47b278d87c1773e8fd09670eec59'},
|
||||||
|
data: {
|
||||||
|
flags: {
|
||||||
|
add: flags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(data)
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeFlags = async (account, message, flags) => {
|
||||||
|
console.log(flags)
|
||||||
|
const {data,error} = await axios({
|
||||||
|
method: "PUT",
|
||||||
|
url: `http://157.90.231.142:3000/v1/account/${account}/message/${message.id}`,
|
||||||
|
headers: { 'Authorization': 'Bearer dadb572465fba648590f31557f68028a750b47b278d87c1773e8fd09670eec59'},
|
||||||
|
data: {
|
||||||
|
flags: {
|
||||||
|
delete: flags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(data)
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
const setSeen = async (seen,message) => {
|
||||||
|
if(seen) {
|
||||||
|
await addFlags(selectedAccount.value,message, ["\\Seen"])
|
||||||
|
await selectMailbox(selectedAccount.value, selectedMailbox.value)
|
||||||
|
} else {
|
||||||
|
await removeFlags(selectedAccount.value,message, ["\\Seen"])
|
||||||
|
await selectMailbox(selectedAccount.value, selectedMailbox.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const moveTo = async (destinationPath) => {
|
||||||
|
const {data,error} = await axios({
|
||||||
|
method: "PUT",
|
||||||
|
url: `http://157.90.231.142:3000/v1/account/${selectedAccount.value}/message/${selectedMessage.value.id}/move`,
|
||||||
|
headers: { 'Authorization': 'Bearer dadb572465fba648590f31557f68028a750b47b278d87c1773e8fd09670eec59'},
|
||||||
|
data: {
|
||||||
|
path: destinationPath
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(data)
|
||||||
|
console.log(error)
|
||||||
|
selectedMessage.value = null
|
||||||
|
messageHTML.value = null
|
||||||
|
messageText.value = null
|
||||||
|
selectMailbox(selectedAccount.value, selectedMailbox.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const downloadAttachment = async (attachment) => {
|
||||||
|
const {data,error} = await axios({
|
||||||
|
method: "GET",
|
||||||
|
url: `http://157.90.231.142:3000/v1/account/${selectedAccount.value}/attachment/${attachment.id}`,
|
||||||
|
headers: { 'Authorization': 'Bearer dadb572465fba648590f31557f68028a750b47b278d87c1773e8fd09670eec59'},
|
||||||
|
responseType: "blob"
|
||||||
|
})
|
||||||
|
|
||||||
|
const downloadURL = URL.createObjectURL(new Blob([data]))
|
||||||
|
const link = document.createElement('a')
|
||||||
|
link.href = downloadURL
|
||||||
|
link.setAttribute('download', attachment.filename)
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
link.remove()
|
||||||
|
console.log(data)
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setup()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<div class="flex flex-row">
|
||||||
|
<div id="mailboxlist">
|
||||||
|
<UAccordion
|
||||||
|
:items="accounts"
|
||||||
|
>
|
||||||
|
<template #default="{ item, index, open }">
|
||||||
|
<UButton variant="soft" class="mt-3">
|
||||||
|
|
||||||
|
<span class="truncate">{{ item.label }}</span>
|
||||||
|
|
||||||
|
<template #trailing>
|
||||||
|
<UIcon
|
||||||
|
name="i-heroicons-chevron-right-20-solid"
|
||||||
|
class="w-5 h-5 ms-auto transform transition-transform duration-200"
|
||||||
|
:class="[open && 'rotate-90']"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</UButton>
|
||||||
|
</template>
|
||||||
|
<template #item="{ item }">
|
||||||
|
<div
|
||||||
|
v-for="mailbox in mailboxes[item.emailEngineId]"
|
||||||
|
class="my-3"
|
||||||
|
>
|
||||||
|
<UButton
|
||||||
|
@click="selectMailbox(item.emailEngineId, mailbox)"
|
||||||
|
variant="outline"
|
||||||
|
>
|
||||||
|
<span v-if="mailbox.name === 'Trash'">Papierkorb</span>
|
||||||
|
<span v-else-if="mailbox.name === 'INBOX'">Eingang</span>
|
||||||
|
<span v-else-if="mailbox.name === 'Sent'">Gesendet</span>
|
||||||
|
<span v-else-if="mailbox.name === 'Drafts'">Entwürfe</span>
|
||||||
|
<span v-else-if="mailbox.name === 'spambucket'">Spam</span>
|
||||||
|
<span v-else>{{mailbox.name}}</span>
|
||||||
|
<UBadge v-if="mailbox.messages > 0">{{mailbox.messages}}</UBadge>
|
||||||
|
</UButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</UAccordion>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<UDivider orientation="vertical" class="maiLDivider"/>
|
||||||
|
<div id="maillist">
|
||||||
|
<div
|
||||||
|
v-for="message in messages"
|
||||||
|
v-if="messages.length > 0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:class="message === selectedMessage ? ['message','text-primary-500'] : ['message']"
|
||||||
|
@click="selectMessage(selectedAccount, message),
|
||||||
|
!message.flags.includes('\\Seen') ? setSeen(true,message) : null"
|
||||||
|
>
|
||||||
|
<UChip
|
||||||
|
position="top-left"
|
||||||
|
:show="!message.flags.includes('\\Seen')"
|
||||||
|
>
|
||||||
|
<h1>{{message.from.name ||message.from.address}}</h1>
|
||||||
|
</UChip>
|
||||||
|
|
||||||
|
<h3>{{message.subject}}</h3>
|
||||||
|
</div>
|
||||||
|
<UDivider class="my-3"/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
>
|
||||||
|
Keine E-Mails in diesem Postfach
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<UDivider orientation="vertical" class="maiLDivider"/>
|
||||||
|
|
||||||
|
<div id="mailcontent" v-if="selectedMessage">
|
||||||
|
<Toolbar>
|
||||||
|
<!--<UButton
|
||||||
|
@click="setup"
|
||||||
|
>Setup</UButton>
|
||||||
|
<UButton>+ Neu</UButton>
|
||||||
|
<UButton>Sync</UButton>
|
||||||
|
<UButton>Papierkorb</UButton>
|
||||||
|
<UButton>Weiterleiten</UButton>
|
||||||
|
<UButton>Antworten</UButton>-->
|
||||||
|
<UButton
|
||||||
|
@click="setSeen(false,selectedMessage)"
|
||||||
|
>
|
||||||
|
Als Ungelesen markieren
|
||||||
|
</UButton>
|
||||||
|
<UButton
|
||||||
|
@click="moveTo('INBOX.Trash')"
|
||||||
|
icon="i-heroicons-trash"
|
||||||
|
>
|
||||||
|
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
<UAlert
|
||||||
|
v-if="selectedMessage"
|
||||||
|
:title="attachment.filename"
|
||||||
|
v-for="attachment in selectedMessage.attachments"
|
||||||
|
class="my-3"
|
||||||
|
:actions="[{label: 'Download', click:() => {downloadAttachment(attachment)}}]"
|
||||||
|
>
|
||||||
|
|
||||||
|
</UAlert>
|
||||||
|
<iframe
|
||||||
|
v-if="messageHTML"
|
||||||
|
style="width: 100%; height: 100%"
|
||||||
|
:srcdoc="messageHTML">
|
||||||
|
</iframe>
|
||||||
|
<pre
|
||||||
|
class="text-wrap"
|
||||||
|
v-else-if="messageText">
|
||||||
|
{{messageText}}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.maiLDivider {
|
||||||
|
width: 5vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mailboxlist {
|
||||||
|
width: 15vw;
|
||||||
|
height: 95vh;
|
||||||
|
overflow-y: scroll;
|
||||||
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
|
scrollbar-width: none; /* Firefox */
|
||||||
|
}
|
||||||
|
|
||||||
|
#mailboxlist::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#maillist {
|
||||||
|
width: 25vw;
|
||||||
|
height: 88vh;
|
||||||
|
overflow-y:scroll;
|
||||||
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
|
scrollbar-width: none; /* Firefox */
|
||||||
|
}
|
||||||
|
|
||||||
|
#maillist::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mailcontent {
|
||||||
|
width: 55vw;
|
||||||
|
height: 88vh;
|
||||||
|
overflow-y:scroll;
|
||||||
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
|
scrollbar-width: none; /* Firefox */
|
||||||
|
}
|
||||||
|
|
||||||
|
#mailcontent::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
//border: 1px solid #69c350;
|
||||||
|
margin-right: 1em;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.message:hover {
|
||||||
|
background-color: #69c350;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message h1 {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,6 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="cardHolder">
|
||||||
Offene Aufgaben: {{openTasks}}<br>
|
<div class="card">
|
||||||
|
<h1 class="text-center text-4xl">Aufgaben</h1>
|
||||||
|
<p class="text-center text-6xl mt-5">{{openTasks}}</p>
|
||||||
|
</div><div class="card">
|
||||||
|
|
||||||
|
</div><div class="card">
|
||||||
|
|
||||||
|
</div><div class="card">
|
||||||
|
|
||||||
|
</div><div class="card">
|
||||||
|
|
||||||
|
</div><div class="card">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -20,5 +38,16 @@ const user = useSupabaseUser()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.cardHolder {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card{
|
||||||
|
width: 22vw;
|
||||||
|
height: 40vh;
|
||||||
|
border: 1px solid white
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
155
spaces/pages/inventoryitems/[mode]/[[id]].vue
Normal file
155
spaces/pages/inventoryitems/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
<script setup>
|
||||||
|
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
middleware: "auth"
|
||||||
|
})
|
||||||
|
|
||||||
|
const dataStore = useDataStore()
|
||||||
|
const supabase = useSupabaseClient()
|
||||||
|
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({
|
||||||
|
name: null,
|
||||||
|
description: null
|
||||||
|
})
|
||||||
|
|
||||||
|
//Functions
|
||||||
|
const setupPage = () => {
|
||||||
|
if(mode.value === "show" || mode.value === "edit"){
|
||||||
|
currentItem.value = dataStore.getInventoryItemById(Number(useRoute().params.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mode.value === "edit") itemInfo.value = currentItem.value
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const editItem = async () => {
|
||||||
|
router.push(`/inventoryitems/edit/${currentItem.value.id}`)
|
||||||
|
setupPage()
|
||||||
|
}
|
||||||
|
|
||||||
|
const cancelEditorCreate = () => {
|
||||||
|
if(currentItem.value) {
|
||||||
|
router.push(`/inventoryitems/show/${currentItem.value.id}`)
|
||||||
|
} else {
|
||||||
|
router.push(`/inventoryitems`)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
setupPage()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<h1
|
||||||
|
class="text-center my-3 font-bold text-2xl"
|
||||||
|
v-if="currentItem "
|
||||||
|
>{{currentItem.name}}</h1>
|
||||||
|
<UTabs
|
||||||
|
:items="[{label: 'Informationen'}, {label: 'Logbuch'}]"
|
||||||
|
v-if="currentItem && mode == 'show'"
|
||||||
|
>
|
||||||
|
<template #item="{item}">
|
||||||
|
<UCard class="mt-5">
|
||||||
|
<div v-if="item.label === 'Informationen'">
|
||||||
|
<Toolbar>
|
||||||
|
<UButton
|
||||||
|
v-if="mode === 'show' && currentItem.id"
|
||||||
|
@click="editItem"
|
||||||
|
>
|
||||||
|
Bearbeiten
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
|
<div class="text-wrap">
|
||||||
|
<p v-if="currentItem.currentSpace">Lagerplatz: {{dataStore.getSpaceById(currentItem.currentSpace).spaceNumber}} - {{dataStore.getSpaceById(currentItem.currentSpace).description}}</p>
|
||||||
|
<p>Beschreibung: {{currentItem.description}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Logbuch'">
|
||||||
|
<HistoryDisplay
|
||||||
|
type="inventoryitem"
|
||||||
|
v-if="currentItem"
|
||||||
|
:element-id="currentItem.id"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</UCard>
|
||||||
|
</template>
|
||||||
|
</UTabs>
|
||||||
|
<UCard v-else-if="mode == 'edit' || mode == 'create'" >
|
||||||
|
<template #header v-if="mode === 'edit'">
|
||||||
|
{{itemInfo.name}}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<UFormGroup
|
||||||
|
label="Name:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.name"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Lagerplatz:"
|
||||||
|
>
|
||||||
|
<USelectMenu
|
||||||
|
:options="dataStore.spaces"
|
||||||
|
v-model="itemInfo.currentSpace"
|
||||||
|
value-attribute="id"
|
||||||
|
>
|
||||||
|
<template #option="{option}">
|
||||||
|
<span class="truncate">{{option.spaceNumber}} - {{option.description}}</span>
|
||||||
|
</template>
|
||||||
|
<template #label>
|
||||||
|
<span v-if="itemInfo.currentSpace">{{dataStore.getSpaceById(itemInfo.currentSpace).spaceNumber }} - {{dataStore.getSpaceById(itemInfo.currentSpace).description}}</span>
|
||||||
|
<span v-else>Kein Lagerplatz ausgewählt</span>
|
||||||
|
</template>
|
||||||
|
</USelectMenu>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Beschreibung:"
|
||||||
|
>
|
||||||
|
<UTextarea
|
||||||
|
v-model="itemInfo.description"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<UButton
|
||||||
|
v-if="mode === 'edit'"
|
||||||
|
@click="dataStore.updateItem('inventoryitems',itemInfo)"
|
||||||
|
>
|
||||||
|
Speichern
|
||||||
|
</UButton>
|
||||||
|
<UButton
|
||||||
|
v-else-if="mode === 'create'"
|
||||||
|
@click="dataStore.createNewItem('inventoryitems',itemInfo)"
|
||||||
|
>
|
||||||
|
Erstellen
|
||||||
|
</UButton>
|
||||||
|
<UButton
|
||||||
|
@click="cancelEditorCreate"
|
||||||
|
color="red"
|
||||||
|
class="ml-2"
|
||||||
|
>
|
||||||
|
Abbrechen
|
||||||
|
</UButton>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</UCard>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
75
spaces/pages/inventoryitems/index.vue
Normal file
75
spaces/pages/inventoryitems/index.vue
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<UButton @click="router.push(`/inventoryitems/create/`)">+ Inventarartikel</UButton>
|
||||||
|
|
||||||
|
<UInput
|
||||||
|
v-model="searchString"
|
||||||
|
placeholder="Suche..."
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<UTable
|
||||||
|
:rows="filteredRows"
|
||||||
|
@select="selectItem"
|
||||||
|
:columns="itemColumns"
|
||||||
|
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }"
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
|
</UTable>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
middleware: "auth"
|
||||||
|
})
|
||||||
|
const dataStore = useDataStore()
|
||||||
|
const supabase = useSupabaseClient()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const itemColumns = [
|
||||||
|
{
|
||||||
|
key: "name",
|
||||||
|
label: "Name",
|
||||||
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "description",
|
||||||
|
label: "Beschreibung",
|
||||||
|
sortable: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const selectItem = (item) => {
|
||||||
|
console.log(item)
|
||||||
|
router.push(`/inventoryitems/show/${item.id} `)
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchString = ref('')
|
||||||
|
|
||||||
|
const filteredRows = computed(() => {
|
||||||
|
if(!searchString.value) {
|
||||||
|
return dataStore.inventoryitems
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataStore.inventoryitems.filter(product => {
|
||||||
|
return Object.values(product).some((value) => {
|
||||||
|
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -38,16 +38,15 @@ const fields = [{
|
|||||||
|
|
||||||
const onSubmit = async (data) => {
|
const onSubmit = async (data) => {
|
||||||
|
|
||||||
const { error } = await supabase.auth.signInWithPassword({
|
const {error, data:{ user}} = await supabase.auth.signInWithPassword({
|
||||||
email: data.email,
|
email: data.email,
|
||||||
password: data.password
|
password: data.password
|
||||||
})
|
})
|
||||||
if(error) {
|
if(error) {
|
||||||
console.log(error.toString())
|
console.log(error.toString())
|
||||||
alert(error.toString())
|
|
||||||
} else {
|
} else {
|
||||||
console.log("Login Successful")
|
console.log("Login Successful")
|
||||||
dataStore.changeTenant()
|
dataStore.initializeData(user.id)
|
||||||
router.push("/")
|
router.push("/")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ const calendarOptionsTimeline = reactive({
|
|||||||
},
|
},
|
||||||
initialEvents: events,
|
initialEvents: events,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
|
weekNumbers: true,
|
||||||
select: function (info) {
|
select: function (info) {
|
||||||
//console.log(info)
|
//console.log(info)
|
||||||
newEventData.value.resourceId = info.resource.id
|
newEventData.value.resourceId = info.resource.id
|
||||||
@@ -97,7 +98,7 @@ const calendarOptionsTimeline = reactive({
|
|||||||
slotDuration: {hours: 3},
|
slotDuration: {hours: 3},
|
||||||
slotMinTime: "06:00:00",
|
slotMinTime: "06:00:00",
|
||||||
slotMaxTime: "21:00:00",
|
slotMaxTime: "21:00:00",
|
||||||
/*duration: {days:7},*/
|
duration: {days:7},
|
||||||
buttonText: "Woche",
|
buttonText: "Woche",
|
||||||
visibleRange: function(currentDate) {
|
visibleRange: function(currentDate) {
|
||||||
// Generate a new date for manipulating in the next step
|
// Generate a new date for manipulating in the next step
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||||
import DocumentList from "~/components/DocumentList.vue";
|
import DocumentList from "~/components/DocumentList.vue";
|
||||||
import DocumentUpload from "~/components/DocumentUpload.vue";
|
import DocumentUpload from "~/components/DocumentUpload.vue";
|
||||||
|
import Toolbar from "~/components/Toolbar.vue";
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
middleware: "auth"
|
middleware: "auth"
|
||||||
@@ -15,7 +16,7 @@ const toast = useToast()
|
|||||||
const id = ref(route.params.id ? route.params.id : null )
|
const id = ref(route.params.id ? route.params.id : null )
|
||||||
|
|
||||||
const editor = useEditor({
|
const editor = useEditor({
|
||||||
content: "<p>I'm running Tiptap with Vue.js. 🎉</p>",
|
content: "<p>Hier kann deine Projektdokumentation stehen</p>",
|
||||||
extensions: [TiptapStarterKit],
|
extensions: [TiptapStarterKit],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -28,6 +29,8 @@ const itemInfo = ref({})
|
|||||||
const tabItems = [
|
const tabItems = [
|
||||||
{
|
{
|
||||||
label: "Informationen"
|
label: "Informationen"
|
||||||
|
},{
|
||||||
|
label: "Logbuch"
|
||||||
},{
|
},{
|
||||||
label: "Projekte"
|
label: "Projekte"
|
||||||
},{
|
},{
|
||||||
@@ -47,6 +50,11 @@ const setupPage = () => {
|
|||||||
|
|
||||||
if(mode.value === "edit") itemInfo.value = currentItem.value
|
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)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -59,156 +67,178 @@ const editItem = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cancelEditorCreate = () => {
|
const cancelEditorCreate = () => {
|
||||||
mode.value = "show"
|
if(currentItem.value) {
|
||||||
itemInfo.value = {
|
router.push(`/plants/show/${currentItem.value.id}`)
|
||||||
id: 0,
|
} else {
|
||||||
infoData: {}
|
router.push(`/plants`)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setupPage()
|
setupPage()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<UCard v-if="currentItem && mode == 'show'">
|
<h1
|
||||||
|
class="mb-3 truncate font-bold text-2xl"
|
||||||
|
v-if="currentItem "
|
||||||
|
>Objekt: {{currentItem.name}}</h1>
|
||||||
|
<div v-if="currentItem && mode == 'show'">
|
||||||
|
<UTabs :items="tabItems">
|
||||||
|
<template #item="{item}">
|
||||||
|
<UCard class="mt-5">
|
||||||
|
<div v-if="item.label === 'Informationen'">
|
||||||
|
<Toolbar>
|
||||||
|
<UButton
|
||||||
|
v-if="mode == 'show' && currentItem.id"
|
||||||
|
@click="editItem"
|
||||||
|
>
|
||||||
|
Bearbeiten
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
|
<div class="text-wrap">
|
||||||
|
<p>Kunde: <nuxt-link :to="`/customers/show/${currentItem.customer}`">{{dataStore.getCustomerById(currentItem.customer).name}}</nuxt-link></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Logbuch'">
|
||||||
|
<HistoryDisplay
|
||||||
|
type="plant"
|
||||||
|
v-if="currentItem"
|
||||||
|
:element-id="currentItem.id"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Projekte'">
|
||||||
|
<Toolbar>
|
||||||
|
<UButton
|
||||||
|
@click="router.push(`/projects/create?plant=${currentItem.id}`)"
|
||||||
|
>
|
||||||
|
+ Projekt
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
|
<UTable
|
||||||
|
:rows="dataStore.getProjectsByPlantId(currentItem.id)"
|
||||||
|
:columns="[{key: 'name', label: 'Name'}]"
|
||||||
|
@select="(row) => router.push(`/projects/show/${row.id}`)"
|
||||||
|
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Projekte' }"
|
||||||
|
>
|
||||||
|
|
||||||
|
</UTable>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Aufgaben'">
|
||||||
|
<Toolbar>
|
||||||
|
<UButton
|
||||||
|
@click="router.push(`/tasks/create?plant=${currentItem.id}`)"
|
||||||
|
>
|
||||||
|
+ Aufgabe
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
<UTable
|
||||||
|
:rows="dataStore.getTasksByPlantId(currentItem.id)"
|
||||||
|
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Aufgaben' }"
|
||||||
|
:columns="[{key: 'name', label: 'Name'},{key: 'categore', label: 'Kategorie'}]"
|
||||||
|
@select="(row) => router.push(`/tasks/show/${row.id}`)"
|
||||||
|
>
|
||||||
|
|
||||||
|
</UTable>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Dokumente'" class="space-y-3">
|
||||||
|
<Toolbar>
|
||||||
|
<DocumentUpload
|
||||||
|
type="plant"
|
||||||
|
:element-id="currentItem.id"
|
||||||
|
/>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
|
<!-- <UModal
|
||||||
|
v-model="uploadModalOpen"
|
||||||
|
>
|
||||||
|
<UCard class="p-4">
|
||||||
|
|
||||||
|
<template #header>
|
||||||
|
Datei hochladen
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<UFormGroup
|
||||||
|
label="Datei:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
type="file"
|
||||||
|
id="fileUploadInput"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<!– <UFormGroup
|
||||||
|
label="Name:"
|
||||||
|
class="mt-3"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="fileUploadFormData.name"
|
||||||
|
/>
|
||||||
|
</UFormGroup>–>
|
||||||
|
<UFormGroup
|
||||||
|
label="Tags:"
|
||||||
|
class="mt-3"
|
||||||
|
>
|
||||||
|
<USelectMenu
|
||||||
|
multiple
|
||||||
|
searchable
|
||||||
|
searchable-placeholder="Suchen..."
|
||||||
|
:options="tags"
|
||||||
|
v-model="fileUploadFormData.tags"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<!–<UFormGroup
|
||||||
|
label="Ordner:"
|
||||||
|
class="mt-3"
|
||||||
|
>
|
||||||
|
<USelectMenu
|
||||||
|
:options="folders"
|
||||||
|
v-model="fileUploadFormData.folder"
|
||||||
|
value-attribute="label"
|
||||||
|
|
||||||
|
/>
|
||||||
|
</UFormGroup>–>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<UButton
|
||||||
|
class="mt-3"
|
||||||
|
@click="uploadFiles"
|
||||||
|
>Hochladen</UButton>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
</UCard>
|
||||||
|
|
||||||
|
</UModal>-->
|
||||||
|
|
||||||
|
<DocumentList :documents="dataStore.getDocumentsByPlantId(currentItem.id)"/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div v-if="item.label === 'Dokumentation'">
|
||||||
|
|
||||||
|
<Editor/>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</UCard>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</UTabs>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <UCard v-if="currentItem && mode == 'show'">
|
||||||
<template #header>
|
<template #header>
|
||||||
{{currentItem.name}}
|
{{currentItem.name}}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<UTabs :items="tabItems">
|
|
||||||
<template #item="{item}">
|
|
||||||
<div v-if="item.label === 'Informationen'">
|
|
||||||
{{currentItem}}
|
|
||||||
</div>
|
|
||||||
<div v-else-if="item.label === 'Projekte'">
|
|
||||||
<InputGroup>
|
|
||||||
<UButton
|
|
||||||
@click="router.push(`/projects/create?plant=${currentItem.id}`)"
|
|
||||||
>
|
|
||||||
+ Projekt
|
|
||||||
</UButton>
|
|
||||||
</InputGroup>
|
|
||||||
|
|
||||||
<UTable
|
|
||||||
:rows="dataStore.getProjectsByPlantId(currentItem.id)"
|
|
||||||
>
|
|
||||||
|
|
||||||
</UTable>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div v-else-if="item.label === 'Aufgaben'">
|
|
||||||
|
|
||||||
<UTable
|
|
||||||
:rows="dataStore.getTasksByPlantId(currentItem.id)"
|
|
||||||
>
|
|
||||||
|
|
||||||
</UTable>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="item.label === 'Dokumente'" class="space-y-3">
|
|
||||||
<InputGroup>
|
|
||||||
<DocumentUpload
|
|
||||||
type="plant"
|
|
||||||
:element-id="currentItem.id"
|
|
||||||
/>
|
|
||||||
</InputGroup>
|
|
||||||
|
|
||||||
<!-- <UModal
|
|
||||||
v-model="uploadModalOpen"
|
|
||||||
>
|
|
||||||
<UCard class="p-4">
|
|
||||||
|
|
||||||
<template #header>
|
|
||||||
Datei hochladen
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<UFormGroup
|
|
||||||
label="Datei:"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
type="file"
|
|
||||||
id="fileUploadInput"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
<!– <UFormGroup
|
|
||||||
label="Name:"
|
|
||||||
class="mt-3"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="fileUploadFormData.name"
|
|
||||||
/>
|
|
||||||
</UFormGroup>–>
|
|
||||||
<UFormGroup
|
|
||||||
label="Tags:"
|
|
||||||
class="mt-3"
|
|
||||||
>
|
|
||||||
<USelectMenu
|
|
||||||
multiple
|
|
||||||
searchable
|
|
||||||
searchable-placeholder="Suchen..."
|
|
||||||
:options="tags"
|
|
||||||
v-model="fileUploadFormData.tags"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
<!–<UFormGroup
|
|
||||||
label="Ordner:"
|
|
||||||
class="mt-3"
|
|
||||||
>
|
|
||||||
<USelectMenu
|
|
||||||
:options="folders"
|
|
||||||
v-model="fileUploadFormData.folder"
|
|
||||||
value-attribute="label"
|
|
||||||
|
|
||||||
/>
|
|
||||||
</UFormGroup>–>
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<UButton
|
|
||||||
class="mt-3"
|
|
||||||
@click="uploadFiles"
|
|
||||||
>Hochladen</UButton>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
</UCard>
|
|
||||||
|
|
||||||
</UModal>-->
|
|
||||||
|
|
||||||
<DocumentList :documents="dataStore.getDocumentsByPlantId(currentItem.id)"/>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div v-if="item.label === 'Dokumentation'">
|
|
||||||
|
|
||||||
<Editor/>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</UTabs>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</UCard>-->
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<UButton
|
|
||||||
v-if="mode == 'show' && currentItem.id"
|
|
||||||
@click="editItem"
|
|
||||||
>
|
|
||||||
Bearbeiten
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
color="red"
|
|
||||||
class="ml-2"
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
Archivieren
|
|
||||||
</UButton>
|
|
||||||
<!-- TODO: Kunde archivieren -->
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</UCard>
|
|
||||||
<UCard v-else-if="mode === 'edit' || mode === 'create'">
|
<UCard v-else-if="mode === 'edit' || mode === 'create'">
|
||||||
<template #header v-if="mode === 'edit'">
|
<template #header v-if="mode === 'edit'">
|
||||||
{{itemInfo.name}}
|
{{itemInfo.name}}
|
||||||
@@ -265,11 +295,7 @@ setupPage()
|
|||||||
|
|
||||||
</UCard>
|
</UCard>
|
||||||
|
|
||||||
<HistoryDisplay
|
|
||||||
type="plant"
|
|
||||||
v-if="currentItem"
|
|
||||||
:element-id="currentItem.id"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="main">
|
<Toolbar>
|
||||||
<InputGroup>
|
<UButton @click="router.push(`/plants/create/`)">+ Objekt</UButton>
|
||||||
<UButton @click="router.push(`/plants/create/`)">+ Objekt</UButton>
|
|
||||||
|
|
||||||
<UInput
|
|
||||||
v-model="searchString"
|
|
||||||
placeholder="Suche..."
|
|
||||||
/>
|
|
||||||
</InputGroup>
|
|
||||||
|
|
||||||
|
<UInput
|
||||||
|
v-model="searchString"
|
||||||
|
placeholder="Suche..."
|
||||||
|
/>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
|
<div class="table">
|
||||||
<UTable
|
<UTable
|
||||||
:rows="filteredRows"
|
:rows="filteredRows"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
@@ -20,8 +19,8 @@
|
|||||||
{{dataStore.customers.find(customer => customer.id === row.customer) ? dataStore.customers.find(customer => customer.id === row.customer).name : "" }}
|
{{dataStore.customers.find(customer => customer.id === row.customer) ? dataStore.customers.find(customer => customer.id === row.customer).name : "" }}
|
||||||
</template>
|
</template>
|
||||||
</UTable>
|
</UTable>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||||
|
import DocumentList from "~/components/DocumentList.vue";
|
||||||
|
import DocumentUpload from "~/components/DocumentUpload.vue";
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
middleware: "auth"
|
middleware: "auth"
|
||||||
})
|
})
|
||||||
@@ -10,7 +14,7 @@ const router = useRouter()
|
|||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
const id = ref(route.params.id ? route.params.id : null )
|
const id = ref(route.params.id ? route.params.id : null )
|
||||||
|
|
||||||
let currentProduct = null
|
let currentItem = ref(null)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -24,10 +28,10 @@ const itemInfo = ref({
|
|||||||
//Functions
|
//Functions
|
||||||
const setupPage = () => {
|
const setupPage = () => {
|
||||||
if(mode.value === "show" || mode.value === "edit"){
|
if(mode.value === "show" || mode.value === "edit"){
|
||||||
currentProduct = dataStore.getProductById(Number(useRoute().params.id))
|
currentItem.value = dataStore.getProductById(Number(useRoute().params.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mode.value === "edit") itemInfo.value = currentProduct
|
if(mode.value === "edit") itemInfo.value = currentItem.value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -35,7 +39,7 @@ const setupPage = () => {
|
|||||||
|
|
||||||
|
|
||||||
const editItem = async () => {
|
const editItem = async () => {
|
||||||
router.push(`/products/edit/${currentProduct.id}`)
|
router.push(`/products/edit/${currentItem.value.id}`)
|
||||||
setupPage()
|
setupPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,153 +57,164 @@ setupPage()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<h1
|
||||||
<UCard v-if="currentProduct && mode == 'show'" >
|
class="mb-3 truncate font-bold text-2xl"
|
||||||
<template #header>
|
v-if="currentItem "
|
||||||
{{currentProduct.name}}
|
>Artikel: {{currentItem.name}}</h1>
|
||||||
</template>
|
<UTabs
|
||||||
|
:items="[{label: 'Informationen'},{label: 'Logbuch'},{label: 'Bestand'},{label: 'Dokumente'}]"
|
||||||
|
v-if="mode === 'show'"
|
||||||
|
>
|
||||||
|
<template #item="{item}">
|
||||||
|
<UCard class="mt-5">
|
||||||
|
<div
|
||||||
|
v-if="item.label === 'Informationen'"
|
||||||
|
>
|
||||||
|
<Toolbar>
|
||||||
|
<UButton
|
||||||
|
v-if="mode === 'show' && currentItem.id"
|
||||||
|
@click="editItem"
|
||||||
|
>
|
||||||
|
Bearbeiten
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
<UBadge
|
||||||
|
v-for="tag in currentItem.tags"
|
||||||
|
class="mr-2"
|
||||||
|
>
|
||||||
|
{{tag}}
|
||||||
|
</UBadge>
|
||||||
|
<UDivider
|
||||||
|
class="my-2"
|
||||||
|
/>
|
||||||
|
<span v-if="currentItem.purchasePrice">Einkaufspreis: {{Number(currentItem.purchasePrice).toFixed(2)}} €<br></span>
|
||||||
|
|
||||||
<UBadge
|
</div>
|
||||||
v-for="tag in currentProduct.tags"
|
<div
|
||||||
class="mr-2"
|
v-if="item.label === 'Logbuch'"
|
||||||
>
|
>
|
||||||
{{tag}}
|
<HistoryDisplay
|
||||||
</UBadge>
|
type="product"
|
||||||
|
v-if="currentItem"
|
||||||
|
:element-id="currentItem.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 : ""}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="item.label === 'Dokumente'"
|
||||||
|
>
|
||||||
|
<Toolbar>
|
||||||
|
<DocumentUpload
|
||||||
|
type="product"
|
||||||
|
:element-id="currentItem.id"
|
||||||
|
/>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
|
|
||||||
|
<DocumentList :documents="dataStore.getDocumentsByProductId(currentItem.id)"/>
|
||||||
|
</div>
|
||||||
|
</UCard>
|
||||||
|
</template>
|
||||||
|
</UTabs>
|
||||||
|
<UCard v-else-if="mode == 'edit' || mode == 'create'" >
|
||||||
|
<template #header v-if="mode === 'edit'">
|
||||||
|
{{itemInfo.name}}
|
||||||
|
</template>
|
||||||
|
|
||||||
<UDivider
|
<UFormGroup
|
||||||
class="my-2"
|
label="Name:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.name"
|
||||||
/>
|
/>
|
||||||
<span v-if="currentProduct.purchasePrice">Einkaufspreis: {{Number(currentProduct.purchasePrice).toFixed(2)}} €<br></span>
|
</UFormGroup>
|
||||||
Bestand: {{dataStore.getStockByProductId(currentProduct.id)}} {{dataStore.units.find(unit => unit.id === currentProduct.unit) ? dataStore.units.find(unit => unit.id === currentProduct.unit).name : ""}}
|
<UFormGroup
|
||||||
|
label="Hersteller:"
|
||||||
<DevOnly>
|
>
|
||||||
<UDivider
|
<UInput
|
||||||
class="my-2"
|
v-model="itemInfo.manufacturer"
|
||||||
/>
|
/>
|
||||||
|
</UFormGroup>
|
||||||
{{currentProduct}}
|
<UFormGroup
|
||||||
</DevOnly>
|
label="Einheit:"
|
||||||
|
>
|
||||||
|
<USelectMenu
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<UButton
|
|
||||||
v-if="mode === 'show' && currentProduct.id"
|
|
||||||
@click="editItem"
|
|
||||||
>
|
|
||||||
Bearbeiten
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
color="red"
|
|
||||||
class="ml-2"
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
Archivieren
|
|
||||||
</UButton>
|
|
||||||
<!-- TODO: Produkt archivieren -->
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</UCard>
|
|
||||||
<UCard v-else-if="mode == 'edit' || mode == 'create'" >
|
|
||||||
<template #header v-if="mode === 'edit'">
|
|
||||||
{{itemInfo.name}}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<UFormGroup
|
|
||||||
label="Name:"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="itemInfo.name"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup
|
|
||||||
label="Hersteller:"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="itemInfo.manufacturer"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup
|
|
||||||
label="Einheit:"
|
|
||||||
>
|
|
||||||
<USelectMenu
|
|
||||||
v-model="itemInfo.unit"
|
v-model="itemInfo.unit"
|
||||||
:options="dataStore.units"
|
:options="dataStore.units"
|
||||||
option-attribute="name"
|
option-attribute="name"
|
||||||
value-attribute="id"
|
value-attribute="id"
|
||||||
>
|
|
||||||
<template #label>
|
|
||||||
{{dataStore.units.find(unit => unit.id === itemInfo.unit) ? dataStore.units.find(unit => unit.id === itemInfo.unit).name : itemInfo.unit }}
|
|
||||||
</template>
|
|
||||||
</USelectMenu>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup
|
|
||||||
label="Tags:"
|
|
||||||
>
|
>
|
||||||
<USelectMenu
|
<template #label>
|
||||||
|
{{dataStore.units.find(unit => unit.id === itemInfo.unit) ? dataStore.units.find(unit => unit.id === itemInfo.unit).name : itemInfo.unit }}
|
||||||
|
</template>
|
||||||
|
</USelectMenu>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Tags:"
|
||||||
|
>
|
||||||
|
<USelectMenu
|
||||||
v-model="itemInfo.tags"
|
v-model="itemInfo.tags"
|
||||||
:options="dataStore.ownTenant.tags.products"
|
:options="dataStore.ownTenant.tags.products"
|
||||||
multiple
|
multiple
|
||||||
/>
|
/>
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="EAN:"
|
label="EAN:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.ean"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Barcode:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.barcode"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Einkaufspreis:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.purchasePrice"
|
||||||
|
type="number"
|
||||||
|
steps="0.01"
|
||||||
>
|
>
|
||||||
<UInput
|
<template #trailing>
|
||||||
v-model="itemInfo.ean"
|
<span class="text-gray-500 dark:text-gray-400 text-xs">EUR</span>
|
||||||
/>
|
</template>
|
||||||
</UFormGroup>
|
</UInput>
|
||||||
<UFormGroup
|
</UFormGroup>
|
||||||
label="Barcode:"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="itemInfo.barcode"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup
|
|
||||||
label="Einkaufspreis:"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="itemInfo.purchasePrice"
|
|
||||||
type="number"
|
|
||||||
steps="0.01"
|
|
||||||
>
|
|
||||||
<template #trailing>
|
|
||||||
<span class="text-gray-500 dark:text-gray-400 text-xs">EUR</span>
|
|
||||||
</template>
|
|
||||||
</UInput>
|
|
||||||
</UFormGroup>
|
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<UButton
|
<UButton
|
||||||
v-if="mode == 'edit'"
|
v-if="mode == 'edit'"
|
||||||
@click="dataStore.updateItem('products',itemInfo)"
|
@click="dataStore.updateItem('products',itemInfo)"
|
||||||
>
|
>
|
||||||
Speichern
|
Speichern
|
||||||
</UButton>
|
</UButton>
|
||||||
<UButton
|
<UButton
|
||||||
v-else-if="mode == 'create'"
|
v-else-if="mode == 'create'"
|
||||||
@click="dataStore.createNewItem('products',itemInfo)"
|
@click="dataStore.createNewItem('products',itemInfo)"
|
||||||
>
|
>
|
||||||
Erstellen
|
Erstellen
|
||||||
</UButton>
|
</UButton>
|
||||||
<UButton
|
<UButton
|
||||||
@click="cancelEditorCreate"
|
@click="cancelEditorCreate"
|
||||||
color="red"
|
color="red"
|
||||||
class="ml-2"
|
class="ml-2"
|
||||||
>
|
>
|
||||||
Abbrechen
|
Abbrechen
|
||||||
</UButton>
|
</UButton>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</UCard>
|
</UCard>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<Toolbar>
|
||||||
|
<UButton @click="router.push(`/products/create/`)">+ Artikel</UButton>
|
||||||
<div class="flex items-center gap-1">
|
|
||||||
<UButton @click="router.push(`/products/create/`)">+ Artikel</UButton>
|
|
||||||
|
|
||||||
<UInput
|
|
||||||
v-model="searchString"
|
|
||||||
placeholder="Suche..."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<UInput
|
||||||
|
v-model="searchString"
|
||||||
|
placeholder="Suche..."
|
||||||
|
/>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="table">
|
||||||
<UTable
|
<UTable
|
||||||
:rows="filteredRows"
|
:rows="filteredRows"
|
||||||
:columns="itemColumns"
|
:columns="itemColumns"
|
||||||
@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 #stock-data="{row}">
|
<template #stock-data="{row}">
|
||||||
{{`${dataStore.getStockByProductId(row.id)} ${(dataStore.units.find(unit => unit.id === row.unit) ? dataStore.units.find(unit => unit.id === row.unit).name : "")}`}}
|
{{`${dataStore.getStockByProductId(row.id)} ${(dataStore.units.find(unit => unit.id === row.unit) ? dataStore.units.find(unit => unit.id === row.unit).name : "")}`}}
|
||||||
@@ -27,8 +25,8 @@
|
|||||||
<template #tags-data="{row}">
|
<template #tags-data="{row}">
|
||||||
<UBadge
|
<UBadge
|
||||||
v-if="row.tags.length > 0"
|
v-if="row.tags.length > 0"
|
||||||
v-for="tag in row.tags"
|
v-for="tag in row.tags"
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
>
|
>
|
||||||
{{tag}}
|
{{tag}}
|
||||||
</UBadge>
|
</UBadge>
|
||||||
@@ -38,9 +36,8 @@
|
|||||||
{{dataStore.units.find(unit => unit.id === row.unit) ? dataStore.units.find(unit => unit.id === row.unit).name : row.unit}}
|
{{dataStore.units.find(unit => unit.id === row.unit) ? dataStore.units.find(unit => unit.id === row.unit).name : row.unit}}
|
||||||
</template>
|
</template>
|
||||||
</UTable>
|
</UTable>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ definePageMeta({
|
|||||||
|
|
||||||
const dataStore = useDataStore()
|
const dataStore = useDataStore()
|
||||||
const supabase = useSupabaseClient()
|
const supabase = useSupabaseClient()
|
||||||
|
const user = useSupabaseUser()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
@@ -22,6 +23,10 @@ const tabItems = [
|
|||||||
key: "information",
|
key: "information",
|
||||||
label: "Informationen"
|
label: "Informationen"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: "historyDisplay",
|
||||||
|
label: "Logbuch"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: "phases",
|
key: "phases",
|
||||||
label: "Phasen"
|
label: "Phasen"
|
||||||
@@ -68,22 +73,6 @@ const timeTableRows = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const taskColumns = [
|
|
||||||
{
|
|
||||||
key: "name",
|
|
||||||
label: "Name"
|
|
||||||
},{
|
|
||||||
key: "description",
|
|
||||||
label: "Beschreibung"
|
|
||||||
},{
|
|
||||||
key: "categorie",
|
|
||||||
label: "Kategorie"
|
|
||||||
}, {
|
|
||||||
key: "user",
|
|
||||||
label: "Benutzer"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Working
|
//Working
|
||||||
@@ -91,7 +80,7 @@ const mode = ref(route.params.mode || "show")
|
|||||||
const itemInfo = ref({
|
const itemInfo = ref({
|
||||||
name: "",
|
name: "",
|
||||||
customer: 0,
|
customer: 0,
|
||||||
|
users: [user.value.id]
|
||||||
})
|
})
|
||||||
|
|
||||||
const uploadModalOpen = ref(false)
|
const uploadModalOpen = ref(false)
|
||||||
@@ -223,38 +212,50 @@ setupPage()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<UCard v-if="currentItem && mode == 'show'">
|
<h1
|
||||||
<template #header>
|
class="mb-3 truncate font-bold text-2xl"
|
||||||
{{currentItem.name}}
|
v-if="currentItem "
|
||||||
</template>
|
>Projekt: {{currentItem.name}}</h1>
|
||||||
|
<UTabs :items="tabItems" class="w-full" v-if="currentItem && mode == 'show'">
|
||||||
<UTabs :items="tabItems" class="w-full">
|
<template #item="{ item }">
|
||||||
<template #item="{ item }">
|
<UCard class="mt-5">
|
||||||
<div v-if="item.key === 'information'">
|
<div v-if="item.key === 'information'">
|
||||||
<InputGroup>
|
<Toolbar>
|
||||||
<UButton
|
<UButton
|
||||||
@click="router.push(`/customers/show/${currentItem.customer}`)"
|
@click="editItem"
|
||||||
class="mb-3"
|
|
||||||
>
|
>
|
||||||
Zum Kunden
|
Bearbeiten
|
||||||
</UButton>
|
</UButton>
|
||||||
<UButton
|
</Toolbar>
|
||||||
@click="router.push(`/plants/show/${currentItem.plant}`)"
|
|
||||||
class="mb-3"
|
|
||||||
>
|
|
||||||
Zum Objekt
|
|
||||||
</UButton>
|
|
||||||
</InputGroup>
|
|
||||||
|
|
||||||
Kunde: {{dataStore.getCustomerById(currentItem.customer).name}}<br>
|
|
||||||
Objekt: {{currentItem.plant ? dataStore.getPlantById(currentItem.plant).name : ""}}<br>
|
<div class="text-wrap">
|
||||||
Notizen:<br>
|
<p>Kunde: <nuxt-link :to="`/customers/show/${currentItem.customer}`">{{dataStore.getCustomerById(currentItem.customer).name}}</nuxt-link></p>
|
||||||
{{currentItem.notes}}
|
<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>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<UDivider class="my-3"/>
|
||||||
|
<h1 class="font-bold text-lg my-3">Beteiligte Benutzer:</h1>
|
||||||
|
<UAlert
|
||||||
|
v-for="projectUser in currentItem.users"
|
||||||
|
:avatar="{ alt: dataStore.getProfileById(projectUser).fullName }"
|
||||||
|
:title="dataStore.getProfileById(projectUser).fullName"
|
||||||
|
class="mb-3"
|
||||||
|
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.key === 'historyDisplay'">
|
||||||
|
<HistoryDisplay
|
||||||
|
type="project"
|
||||||
|
v-if="currentItem"
|
||||||
|
:element-id="currentItem.id"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="item.key === 'phases'" class="space-y-3">
|
<div v-if="item.key === 'phases'" class="space-y-3">
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="Vorlage laden"
|
label="Vorlage laden"
|
||||||
v-if="currentItem.phases.length === 0"
|
v-if="currentItem.phases.length === 0"
|
||||||
>
|
>
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<USelectMenu
|
<USelectMenu
|
||||||
@@ -276,38 +277,58 @@ setupPage()
|
|||||||
|
|
||||||
<UAccordion
|
<UAccordion
|
||||||
:items="currentItem.phases"
|
:items="currentItem.phases"
|
||||||
>
|
>
|
||||||
<template #item="{item}">
|
<template #default="{item,index,open}">
|
||||||
<InputGroup>
|
<UButton
|
||||||
<UButton
|
variant="ghost"
|
||||||
v-if="!item.active"
|
:color="item.active ? 'primary' : 'white'"
|
||||||
@click="changeActivePhase(item)"
|
class="mb-1"
|
||||||
>
|
>
|
||||||
Phase aktivieren
|
<template #leading>
|
||||||
</UButton>
|
<div class="w-6 h-6 flex items-center justify-center -my-1">
|
||||||
|
<UIcon :name="item.icon" class="w-4 h-4 " />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- <UButton>
|
<span class="truncate"> {{item.label}}</span>
|
||||||
+ Phase
|
|
||||||
</UButton>-->
|
<template #trailing>
|
||||||
</InputGroup>
|
<UIcon
|
||||||
</template>
|
name="i-heroicons-chevron-right-20-solid"
|
||||||
|
class="w-5 h-5 ms-auto transform transition-transform duration-200"
|
||||||
|
:class="[open && 'rotate-90']"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</UButton>
|
||||||
|
</template>
|
||||||
|
<template #item="{item}">
|
||||||
|
<InputGroup>
|
||||||
|
<UButton
|
||||||
|
v-if="!item.active"
|
||||||
|
@click="changeActivePhase(item)"
|
||||||
|
>
|
||||||
|
Phase aktivieren
|
||||||
|
</UButton>
|
||||||
|
</InputGroup>
|
||||||
|
</template>
|
||||||
</UAccordion>
|
</UAccordion>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="item.key === 'tasks'" class="space-y-3">
|
<div v-if="item.key === 'tasks'" class="space-y-3">
|
||||||
<InputGroup>
|
<Toolbar>
|
||||||
<UButton
|
<UButton
|
||||||
@click="router.push(`/tasks/create?project=${currentItem.id}`)"
|
@click="router.push(`/tasks/create?project=${currentItem.id}`)"
|
||||||
>
|
>
|
||||||
+ Aufgabe
|
+ Aufgabe
|
||||||
</UButton>
|
</UButton>
|
||||||
</InputGroup>
|
</Toolbar>
|
||||||
|
|
||||||
<UTable
|
<UTable
|
||||||
:rows="dataStore.getTasksByProjectId(currentItem.id)"
|
:rows="dataStore.getTasksByProjectId(currentItem.id)"
|
||||||
:columns="taskColumns"
|
:columns="[{key: 'name',label: 'Name'},{key: 'categorie',label: 'Kategorie'},{key: 'user',label: 'Benutzer'}]"
|
||||||
@select="(row) => {
|
@select="(row) => router.push(`/tasks/show/${row.id}`)"
|
||||||
router.push(`/tasks/show/${row.id}`)
|
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Aufgaben' }"
|
||||||
}"
|
|
||||||
>
|
>
|
||||||
<template #user-data="{row}">
|
<template #user-data="{row}">
|
||||||
{{dataStore.profiles.find(i => i.id === row.user) ? dataStore.profiles.find(i => i.id === row.user).fullName : ""}}
|
{{dataStore.profiles.find(i => i.id === row.user) ? dataStore.profiles.find(i => i.id === row.user).fullName : ""}}
|
||||||
@@ -315,63 +336,8 @@ setupPage()
|
|||||||
</UTable>
|
</UTable>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--
|
|
||||||
<div v-else-if="item.key === 'forms'" class="space-y-3">
|
|
||||||
<UButton
|
|
||||||
@click="formModalOpen = true"
|
|
||||||
>
|
|
||||||
+ Formular
|
|
||||||
</UButton>
|
|
||||||
<UModal
|
|
||||||
v-model="formModalOpen"
|
|
||||||
>
|
|
||||||
<UCard>
|
|
||||||
<template #header>
|
|
||||||
Formular hinzufügen
|
|
||||||
</template>
|
|
||||||
<UFormGroup>
|
|
||||||
<USelectMenu
|
|
||||||
:options="forms"
|
|
||||||
option-attribute="name"
|
|
||||||
value-attribute="id"
|
|
||||||
v-model="newFormSubmissionData.formType"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
<template #footer>
|
|
||||||
<UButton
|
|
||||||
@click="addNewFormSubmission"
|
|
||||||
>
|
|
||||||
Hinzufügen
|
|
||||||
</UButton>
|
|
||||||
</template>
|
|
||||||
</UCard>
|
|
||||||
</UModal>
|
|
||||||
|
|
||||||
|
|
||||||
<UAccordion :items="formSubmissionsComposed">
|
|
||||||
<template #item="{item}">
|
|
||||||
|
|
||||||
<p class="my-3">Formular Link: <a :href="'https://app.spaces.software/formSubmissions/' + item.id">{{'https://app.spaces.software/formSubmissions/' + item.id}}</a></p>
|
|
||||||
|
|
||||||
|
|
||||||
<div v-if="Object.keys(item.values).length == 0">
|
|
||||||
<p>Es wurden noch keine Daten über das Formular abgegeben</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<table v-else>
|
|
||||||
<tr v-for="key in Object.keys(item.values)">
|
|
||||||
<td>{{key}}</td>
|
|
||||||
<td>{{ item.values[key] }}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</UAccordion>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
<div v-else-if="item.key === 'documents'" class="space-y-3">
|
<div v-else-if="item.key === 'documents'" class="space-y-3">
|
||||||
<InputGroup>
|
<Toolbar>
|
||||||
<DocumentUpload
|
<DocumentUpload
|
||||||
type="project"
|
type="project"
|
||||||
:element-id="currentItem.id"
|
:element-id="currentItem.id"
|
||||||
@@ -386,68 +352,8 @@ setupPage()
|
|||||||
>
|
>
|
||||||
+ Rechnung
|
+ Rechnung
|
||||||
</UButton>
|
</UButton>
|
||||||
</InputGroup>
|
</Toolbar>
|
||||||
|
|
||||||
<!-- <UModal
|
|
||||||
v-model="uploadModalOpen"
|
|
||||||
>
|
|
||||||
<UCard class="p-4">
|
|
||||||
|
|
||||||
<template #header>
|
|
||||||
Datei hochladen
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<UFormGroup
|
|
||||||
label="Datei:"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
type="file"
|
|
||||||
id="fileUploadInput"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
<!– <UFormGroup
|
|
||||||
label="Name:"
|
|
||||||
class="mt-3"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="fileUploadFormData.name"
|
|
||||||
/>
|
|
||||||
</UFormGroup>–>
|
|
||||||
<UFormGroup
|
|
||||||
label="Tags:"
|
|
||||||
class="mt-3"
|
|
||||||
>
|
|
||||||
<USelectMenu
|
|
||||||
multiple
|
|
||||||
searchable
|
|
||||||
searchable-placeholder="Suchen..."
|
|
||||||
:options="tags"
|
|
||||||
v-model="fileUploadFormData.tags"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
<!–<UFormGroup
|
|
||||||
label="Ordner:"
|
|
||||||
class="mt-3"
|
|
||||||
>
|
|
||||||
<USelectMenu
|
|
||||||
:options="folders"
|
|
||||||
v-model="fileUploadFormData.folder"
|
|
||||||
value-attribute="label"
|
|
||||||
|
|
||||||
/>
|
|
||||||
</UFormGroup>–>
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<UButton
|
|
||||||
class="mt-3"
|
|
||||||
@click="uploadFiles"
|
|
||||||
>Hochladen</UButton>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
</UCard>
|
|
||||||
|
|
||||||
</UModal>-->
|
|
||||||
|
|
||||||
<DocumentList :documents="dataStore.getDocumentsByProjectId(currentItem.id)"/>
|
<DocumentList :documents="dataStore.getDocumentsByProjectId(currentItem.id)"/>
|
||||||
|
|
||||||
@@ -476,32 +382,15 @@ setupPage()
|
|||||||
</UTable>
|
</UTable>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.key === 'events'" class="space-y-3">
|
<div v-else-if="item.key === 'events'" class="space-y-3">
|
||||||
{{dataStore.getEventsByProjectId(currentItem.id)}}
|
{{dataStore.getEventsByProjectId(currentItem.id).length > 0 ? dataStore.getEventsByProjectId(currentItem.id) : "Keine Termine in für dieses Projekt"}}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!--
|
</UCard>
|
||||||
<div v-else-if="item.key === 'material'" class="space-y-3">
|
|
||||||
<p>Hier wird aktuell noch gearbeitet</p>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
</template>
|
|
||||||
</UTabs>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<UButton
|
|
||||||
v-if="mode == 'show' && currentItem.id"
|
|
||||||
@click="editItem"
|
|
||||||
>
|
|
||||||
Bearbeiten
|
|
||||||
</UButton>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
</UTabs>
|
||||||
|
|
||||||
</UCard>
|
|
||||||
<UCard v-else-if="mode === 'edit' || mode === 'create'" >
|
<UCard v-else-if="mode === 'edit' || mode === 'create'" >
|
||||||
<template #header v-if="mode === 'edit'">
|
<template #header v-if="mode === 'edit'">
|
||||||
{{itemInfo.name}}
|
{{itemInfo.name}}
|
||||||
@@ -563,6 +452,23 @@ setupPage()
|
|||||||
</template>
|
</template>
|
||||||
</USelectMenu>
|
</USelectMenu>
|
||||||
</UFormGroup>
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Beteiligte Benutzer:"
|
||||||
|
>
|
||||||
|
<USelectMenu
|
||||||
|
v-model="itemInfo.users"
|
||||||
|
:options="dataStore.profiles"
|
||||||
|
option-attribute="fullName"
|
||||||
|
value-attribute="id"
|
||||||
|
searchable
|
||||||
|
multiple
|
||||||
|
:search-attributes="['fullName']"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
{{itemInfo.users.length > 0 ? itemInfo.users.map(i => dataStore.getProfileById(i).fullName).join(", ") : "Kein Benutzer ausgewählt"}}
|
||||||
|
</template>
|
||||||
|
</USelectMenu>
|
||||||
|
</UFormGroup>
|
||||||
|
|
||||||
<UFormGroup
|
<UFormGroup
|
||||||
label="Notizen:"
|
label="Notizen:"
|
||||||
@@ -596,11 +502,7 @@ setupPage()
|
|||||||
|
|
||||||
</UCard>
|
</UCard>
|
||||||
|
|
||||||
<HistoryDisplay
|
|
||||||
type="project"
|
|
||||||
v-if="currentItem"
|
|
||||||
:element-id="currentItem.id"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -14,23 +14,28 @@
|
|||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="table">
|
||||||
|
<UTable
|
||||||
|
:rows="filteredRows"
|
||||||
|
@select="selectItem"
|
||||||
|
:columns="itemColumns"
|
||||||
|
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }"
|
||||||
|
>
|
||||||
|
<template #phase-data="{row}">
|
||||||
|
{{getActivePhaseLabel(row)}}
|
||||||
|
</template>
|
||||||
|
<template #customer-data="{row}">
|
||||||
|
{{dataStore.getCustomerById(row.customer) ? dataStore.getCustomerById(row.customer).name : ""}}
|
||||||
|
</template>
|
||||||
|
<template #plant-data="{row}">
|
||||||
|
{{dataStore.getPlantById(row.plant) ? dataStore.getPlantById(row.plant).name : ""}}
|
||||||
|
</template>
|
||||||
|
<template #users-data="{row}">
|
||||||
|
{{row.users.map(i => dataStore.getProfileById(i).fullName).join(", ")}}
|
||||||
|
</template>
|
||||||
|
</UTable>
|
||||||
|
</div>
|
||||||
|
|
||||||
<UTable
|
|
||||||
:rows="filteredRows"
|
|
||||||
@select="selectItem"
|
|
||||||
:columns="itemColumns"
|
|
||||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }"
|
|
||||||
>
|
|
||||||
<template #phase-data="{row}">
|
|
||||||
{{getActivePhaseLabel(row)}}
|
|
||||||
</template>
|
|
||||||
<template #customer-data="{row}">
|
|
||||||
{{dataStore.getCustomerById(row.customer) ? dataStore.getCustomerById(row.customer).name : ""}}
|
|
||||||
</template>
|
|
||||||
<template #plant-data="{row}">
|
|
||||||
{{dataStore.getPlantById(row.plant) ? dataStore.getPlantById(row.plant).name : ""}}
|
|
||||||
</template>
|
|
||||||
</UTable>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -58,16 +63,21 @@ const itemColumns = [
|
|||||||
key: "customer",
|
key: "customer",
|
||||||
label: "Kunde",
|
label: "Kunde",
|
||||||
sortable: true
|
sortable: true
|
||||||
},
|
},/*
|
||||||
{
|
{
|
||||||
key: "notes",
|
key: "notes",
|
||||||
label: "Notizen",
|
label: "Notizen",
|
||||||
sortable: true
|
sortable: true
|
||||||
},
|
},*/
|
||||||
{
|
{
|
||||||
key: "plant",
|
key: "plant",
|
||||||
label: "Objekt",
|
label: "Objekt",
|
||||||
sortable: true
|
sortable: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "users",
|
||||||
|
label: "Benutzer",
|
||||||
|
sortable: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -57,8 +57,10 @@
|
|||||||
{{row.state}}
|
{{row.state}}
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #vendor-data="{row}">
|
<template #partner-data="{row}">
|
||||||
{{dataStore.vendors.find(vendor => vendor.id === row.vendor) ? dataStore.vendors.find(vendor => vendor.id === row.vendor).name : ''}}
|
<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>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
<template #reference-data="{row}">
|
<template #reference-data="{row}">
|
||||||
<span v-if="row.type === 'incomingInvoice'">{{row.reference}}</span>
|
<span v-if="row.type === 'incomingInvoice'">{{row.reference}}</span>
|
||||||
@@ -111,8 +113,8 @@ const itemColumns = [
|
|||||||
sortable: true
|
sortable: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'vendor',
|
key: 'partner',
|
||||||
label: "Lieferant",
|
label: "Kunde / Lieferant",
|
||||||
sortable: true
|
sortable: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
51
spaces/pages/settings/index.vue
Normal file
51
spaces/pages/settings/index.vue
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<script setup>
|
||||||
|
|
||||||
|
const dataStore = useDataStore()
|
||||||
|
|
||||||
|
const items = [{
|
||||||
|
label: 'Projekte',
|
||||||
|
content: 'This is the content shown for Tab1'
|
||||||
|
}, {
|
||||||
|
label: 'E-Mail',
|
||||||
|
content: 'And, this is the content for Tab2'
|
||||||
|
}, {
|
||||||
|
label: 'Dokumente'
|
||||||
|
}]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UTabs
|
||||||
|
:items="items"
|
||||||
|
>
|
||||||
|
<template #item="{item}">
|
||||||
|
<UCard class="mt-5 overflow-y-scroll scroll">
|
||||||
|
<div v-if="item.label === 'Projekte'">
|
||||||
|
<UDivider
|
||||||
|
label="Phasenvorlagen"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Dokumente'">
|
||||||
|
<UDivider
|
||||||
|
label="Tags"
|
||||||
|
class="mb-3"
|
||||||
|
/>
|
||||||
|
<InputGroup>
|
||||||
|
<UBadge
|
||||||
|
v-for="tag in dataStore.ownTenant.tags.documents"
|
||||||
|
>
|
||||||
|
{{tag}}
|
||||||
|
</UBadge>
|
||||||
|
</InputGroup>
|
||||||
|
|
||||||
|
|
||||||
|
{{dataStore.ownTenant.tags}}
|
||||||
|
</div>
|
||||||
|
</UCard>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</UTabs>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -94,117 +94,112 @@ setupPage()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<h1
|
||||||
<DevOnly>
|
class="mb-3 truncate font-bold text-2xl"
|
||||||
{{currentItem}}
|
v-if="currentItem "
|
||||||
{{mode}}
|
>Lagerplatz: {{currentItem.spaceNumber}}</h1>
|
||||||
</DevOnly>
|
<UTabs
|
||||||
<UCard v-if="currentItem && mode == 'show'" >
|
:items="[{label: 'Informationen'},{label: 'Logbuch'},{label: 'Bestand'}]"
|
||||||
<template #header>
|
v-if="currentItem && mode == 'show'"
|
||||||
<UBadge>{{currentItem.spaceNumber}}</UBadge> {{currentItem.type}}
|
>
|
||||||
</template>
|
<template #item="{item}">
|
||||||
|
<UCard class="mt-5">
|
||||||
|
<div v-if="item.label === 'Informationen'">
|
||||||
|
<Toolbar>
|
||||||
|
<UButton
|
||||||
|
v-if="mode == 'show' && currentItem.id"
|
||||||
|
@click="editItem"
|
||||||
|
>
|
||||||
|
Bearbeiten
|
||||||
|
</UButton>
|
||||||
|
<UButton
|
||||||
|
v-if="mode == 'show' && currentItem.id"
|
||||||
|
@click="printSpaceLabel"
|
||||||
|
class="ml-2"
|
||||||
|
>
|
||||||
|
Label Drucken
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
{{currentItem.description}}
|
<div class="truncate">
|
||||||
|
<span>Beschreibung: {{currentItem.description}}</span>
|
||||||
<UDivider
|
</div>
|
||||||
class="my-2"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div v-if="spaceProducts.length > 0">
|
|
||||||
<p class="mt-5">Artikel in diesem Lagerplatz</p>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Artikel</th>
|
|
||||||
<th>Anzahl</th>
|
|
||||||
<th>Einheit</th>
|
|
||||||
</tr>
|
|
||||||
<tr v-for="product in spaceProducts">
|
|
||||||
<td>{{product.name}}</td>
|
|
||||||
<td>{{getSpaceProductCount(product.id)}}</td>
|
|
||||||
<td>{{dataStore.units.find(unit => unit.id === product.unit).name}}</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<p v-else>Es befinden sich keine Artikel in diesem Lagerplatz</p>
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Logbuch'">
|
||||||
|
|
||||||
<template #footer>
|
</div>
|
||||||
<UButton
|
<div v-else-if="item.label === 'Bestand'">
|
||||||
v-if="mode == 'show' && currentItem.id"
|
<div v-if="spaceProducts.length > 0">
|
||||||
@click="editItem"
|
<p class="mt-5">Artikel in diesem Lagerplatz</p>
|
||||||
>
|
|
||||||
Bearbeiten
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
v-if="mode == 'show' && currentItem.id"
|
|
||||||
@click="printSpaceLabel"
|
|
||||||
class="ml-2"
|
|
||||||
>
|
|
||||||
Label Drucken
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
color="red"
|
|
||||||
class="ml-2"
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
Archivieren
|
|
||||||
</UButton>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th class="text-left">Artikel</th>
|
||||||
|
<th>Anzahl</th>
|
||||||
|
<th>Einheit</th>
|
||||||
|
</tr>
|
||||||
|
<tr v-for="product in spaceProducts">
|
||||||
|
<td>{{product.name}}</td>
|
||||||
|
<td>{{getSpaceProductCount(product.id)}}</td>
|
||||||
|
<td>{{dataStore.units.find(unit => unit.id === product.unit).name}}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<p v-else>Es befinden sich keine Artikel in diesem Lagerplatz</p>
|
||||||
|
</div>
|
||||||
|
</UCard>
|
||||||
|
</template>
|
||||||
|
</UTabs>
|
||||||
|
<UCard v-else-if="mode === 'edit' || mode === 'create'" >
|
||||||
|
<template #header v-if="mode === 'edit'">
|
||||||
|
<UBadge>{{itemInfo.spaceNumber}}</UBadge>{{itemInfo.type}}
|
||||||
|
</template>
|
||||||
|
|
||||||
</UCard>
|
<UFormGroup
|
||||||
<UCard v-else-if="mode === 'edit' || mode === 'create'" >
|
label="Typ:"
|
||||||
<template #header v-if="mode === 'edit'">
|
>
|
||||||
<UBadge>{{itemInfo.spaceNumber}}</UBadge>{{itemInfo.type}}
|
<USelectMenu
|
||||||
</template>
|
|
||||||
|
|
||||||
<UFormGroup
|
|
||||||
label="Typ:"
|
|
||||||
>
|
|
||||||
<USelectMenu
|
|
||||||
:options="spaceTypes"
|
:options="spaceTypes"
|
||||||
v-model="itemInfo.type"
|
v-model="itemInfo.type"
|
||||||
>
|
|
||||||
|
|
||||||
</USelectMenu>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup
|
|
||||||
label="Beschreibung.:"
|
|
||||||
>
|
>
|
||||||
<UTextarea
|
|
||||||
v-model="itemInfo.description"
|
</USelectMenu>
|
||||||
/>
|
</UFormGroup>
|
||||||
</UFormGroup>
|
<UFormGroup
|
||||||
|
label="Beschreibung.:"
|
||||||
|
>
|
||||||
|
<UTextarea
|
||||||
|
v-model="itemInfo.description"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<UButton
|
<UButton
|
||||||
v-if="mode == 'edit'"
|
v-if="mode == 'edit'"
|
||||||
@click="dataStore.updateItem('spaces',itemInfo)"
|
@click="dataStore.updateItem('spaces',itemInfo)"
|
||||||
>
|
>
|
||||||
Speichern
|
Speichern
|
||||||
</UButton>
|
</UButton>
|
||||||
<UButton
|
<UButton
|
||||||
v-else-if="mode == 'create'"
|
v-else-if="mode == 'create'"
|
||||||
@click="dataStore.createNewItem('spaces',itemInfo)"
|
@click="dataStore.createNewItem('spaces',itemInfo)"
|
||||||
>
|
>
|
||||||
Erstellen
|
Erstellen
|
||||||
</UButton>
|
</UButton>
|
||||||
<UButton
|
<UButton
|
||||||
@click="cancelEditorCreate"
|
@click="cancelEditorCreate"
|
||||||
color="red"
|
color="red"
|
||||||
class="ml-2"
|
class="ml-2"
|
||||||
>
|
>
|
||||||
Abbrechen
|
Abbrechen
|
||||||
</UButton>
|
</UButton>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</UCard>
|
</UCard>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -1,27 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="main">
|
<Toolbar>
|
||||||
|
<UButton @click="router.push(`/inventory/spaces/create/`)">+ Lagerplatz</UButton>
|
||||||
<div class="flex items-center gap-1">
|
|
||||||
<UButton @click="router.push(`/inventory/spaces/create/`)">+ Lagerplatz</UButton>
|
|
||||||
|
|
||||||
<UInput
|
|
||||||
v-model="searchString"
|
|
||||||
placeholder="Suche..."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<UInput
|
||||||
|
v-model="searchString"
|
||||||
|
placeholder="Suche..."
|
||||||
|
/>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="table">
|
||||||
<UTable
|
<UTable
|
||||||
:rows="filteredRows"
|
:rows="filteredRows"
|
||||||
:columns="itemColumns"
|
:columns="itemColumns"
|
||||||
@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' }"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="main">
|
|
||||||
|
|
||||||
<InputGroup>
|
<div>
|
||||||
|
<Toolbar>
|
||||||
<UButton @click="router.push(`/tasks/create`)">+ Aufgabe</UButton>
|
<UButton @click="router.push(`/tasks/create`)">+ Aufgabe</UButton>
|
||||||
|
|
||||||
<UInput
|
<UInput
|
||||||
@@ -13,37 +13,38 @@
|
|||||||
label="Erledigte Anzeigen"
|
label="Erledigte Anzeigen"
|
||||||
v-model="showDone"
|
v-model="showDone"
|
||||||
/>
|
/>
|
||||||
</InputGroup>
|
</Toolbar>
|
||||||
|
<div class="table">
|
||||||
<UTable
|
<UTable
|
||||||
:rows="filteredRows"
|
:rows="filteredRows"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
@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 #finish-data="{row}">
|
<template #finish-data="{row}">
|
||||||
<UButton
|
<UButton
|
||||||
icon="i-heroicons-check"
|
icon="i-heroicons-check"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
@click="markAsFinished(row)"
|
@click="markAsFinished(row)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #created_at-data="{row}">
|
<template #created_at-data="{row}">
|
||||||
{{row.created_at ? dayjs(row.created_at).format("DD.MM.YY HH:mm") : ''}}
|
{{row.created_at ? dayjs(row.created_at).format("DD.MM.YY HH:mm") : ''}}
|
||||||
</template>
|
</template>
|
||||||
<template #user-data="{row}">
|
<template #user-data="{row}">
|
||||||
{{dataStore.profiles.find(i => i.id === row.user) ? dataStore.profiles.find(i => i.id === row.user).fullName : ""}}
|
{{dataStore.profiles.find(i => i.id === row.user) ? dataStore.profiles.find(i => i.id === row.user).fullName : ""}}
|
||||||
</template>
|
</template>
|
||||||
<template #project-data="{row}">
|
<template #project-data="{row}">
|
||||||
{{dataStore.projects.find(i => i.id === row.project) ? dataStore.projects.find(i => i.id === row.project).name : ""}}
|
{{dataStore.projects.find(i => i.id === row.project) ? dataStore.projects.find(i => i.id === row.project).name : ""}}
|
||||||
</template>
|
</template>
|
||||||
<template #customer-data="{row}">
|
<template #customer-data="{row}">
|
||||||
{{dataStore.customers.find(customer => customer.id === row.customer) ? dataStore.customers.find(customer => customer.id === row.customer).name : "" }}
|
{{dataStore.customers.find(customer => customer.id === row.customer) ? dataStore.customers.find(customer => customer.id === row.customer).name : "" }}
|
||||||
</template>
|
</template>
|
||||||
<template #plant-data="{row}">
|
<template #plant-data="{row}">
|
||||||
{{dataStore.getPlantById(row.plant) ? dataStore.getPlantById(row.plant).name : "" }}
|
{{dataStore.getPlantById(row.plant) ? dataStore.getPlantById(row.plant).name : "" }}
|
||||||
</template>
|
</template>
|
||||||
</UTable>
|
</UTable>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -19,10 +19,12 @@ let currentItem = ref(null)
|
|||||||
//Working
|
//Working
|
||||||
const mode = ref(route.params.mode || "show")
|
const mode = ref(route.params.mode || "show")
|
||||||
const itemInfo = ref({
|
const itemInfo = ref({
|
||||||
|
id: null,
|
||||||
name: "",
|
name: "",
|
||||||
licensePlate: "",
|
licensePlate: "",
|
||||||
type: "",
|
type: "",
|
||||||
driver: null
|
driver: null,
|
||||||
|
active: true
|
||||||
})
|
})
|
||||||
|
|
||||||
const tabItems = [{
|
const tabItems = [{
|
||||||
@@ -76,13 +78,12 @@ const editCustomer = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cancelEditorCreate = () => {
|
const cancelEditorCreate = () => {
|
||||||
mode.value = "show"
|
if(currentItem.value) {
|
||||||
itemInfo.value = {
|
router.push(`/vehicles/show/${currentItem.value.id}`)
|
||||||
id: 0,
|
} else {
|
||||||
name: "",
|
router.push(`/vehicles`)
|
||||||
licensePlate: "",
|
|
||||||
type: ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateItem = async () => {
|
const updateItem = async () => {
|
||||||
@@ -135,6 +136,13 @@ setupPage()
|
|||||||
<UTabs :items="tabItems">
|
<UTabs :items="tabItems">
|
||||||
<template #item="{item}">
|
<template #item="{item}">
|
||||||
<div v-if="item.label === 'Informationen'">
|
<div v-if="item.label === 'Informationen'">
|
||||||
|
<InputGroup class="mb-3">
|
||||||
|
<UButton
|
||||||
|
@click="editCustomer"
|
||||||
|
>
|
||||||
|
Bearbeiten
|
||||||
|
</UButton>
|
||||||
|
</InputGroup>
|
||||||
Typ: {{currentItem.type}} <br>
|
Typ: {{currentItem.type}} <br>
|
||||||
Fahrer: {{dataStore.profiles.find(profile => profile.id === currentItem.driver) ? dataStore.profiles.find(profile => profile.id === currentItem.driver).fullName : 'Kein Fahrer gewählt'}} <br>
|
Fahrer: {{dataStore.profiles.find(profile => profile.id === currentItem.driver) ? dataStore.profiles.find(profile => profile.id === currentItem.driver).fullName : 'Kein Fahrer gewählt'}} <br>
|
||||||
</div>
|
</div>
|
||||||
@@ -175,22 +183,7 @@ setupPage()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<UButton
|
|
||||||
v-if="mode == 'show' && currentItem.id"
|
|
||||||
@click="editCustomer"
|
|
||||||
>
|
|
||||||
Bearbeiten
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
color="red"
|
|
||||||
class="ml-2"
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
Archivieren
|
|
||||||
</UButton>
|
|
||||||
<!-- TODO: Fahrzeug archivieren -->
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -229,7 +222,7 @@ setupPage()
|
|||||||
>
|
>
|
||||||
<USelectMenu
|
<USelectMenu
|
||||||
v-model="itemInfo.driver"
|
v-model="itemInfo.driver"
|
||||||
:options="dataStore.profiles"
|
:options="[{id: null, fullName: 'Kein Fahrer'},...dataStore.profiles]"
|
||||||
option-attribute="fullName"
|
option-attribute="fullName"
|
||||||
value-attribute="id"
|
value-attribute="id"
|
||||||
|
|
||||||
|
|||||||
299
spaces/pages/vendors/[mode]/[[id]].vue
vendored
299
spaces/pages/vendors/[mode]/[[id]].vue
vendored
@@ -33,177 +33,178 @@ const setupPage = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const editItem = async () => {
|
const editItem = async () => {
|
||||||
router.push(`/vendors/edit/${currentItem.id}`)
|
router.push(`/vendors/edit/${currentItem.value.id}`)
|
||||||
setupPage()
|
setupPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
const cancelEditorCreate = () => {
|
const cancelEditorCreate = () => {
|
||||||
router.push(`/vendors/`)
|
if(currentItem.value) {
|
||||||
|
router.push(`/vendors/show/${currentItem.value.id}`)
|
||||||
|
} else {
|
||||||
|
router.push(`/vendors`)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setupPage()
|
setupPage()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<h1
|
||||||
<UCard v-if="currentItem && mode == 'show'" >
|
class=" mb-3 font-bold text-2xl truncate"
|
||||||
<template #header>
|
v-if="currentItem "
|
||||||
{{currentItem.name}}
|
>Lieferant: {{currentItem.name}}</h1>
|
||||||
</template>
|
<UTabs
|
||||||
|
:items="[{label: 'Informationen'},{label: 'Logbuch'},{label: 'Ansprechpartner'}]"
|
||||||
|
v-if="currentItem && mode == 'show'"
|
||||||
|
>
|
||||||
|
<template #item="{item}">
|
||||||
|
<UCard class="mt-5">
|
||||||
|
<div v-if="item.label === 'Informationen'">
|
||||||
|
<Toolbar>
|
||||||
|
<UButton
|
||||||
|
v-if="mode == 'show' && currentItem.id"
|
||||||
|
@click="editItem"
|
||||||
|
>
|
||||||
|
Bearbeiten
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
<InputGroup>
|
<div v-if="currentItem.infoData" class="text-wrap">
|
||||||
<UButton
|
<p v-if="currentItem.infoData.street">Straße + Hausnummer: {{currentItem.infoData.street}}</p>
|
||||||
@click="router.push(`/contacts/create?vendor=${currentItem.id}`)"
|
<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>
|
||||||
+ Ansprechpartner
|
<p v-if="currentItem.infoData.email">E-Mail: {{currentItem.infoData.email}}</p>
|
||||||
</UButton>
|
<p v-if="currentItem.infoData.web">Web: {{currentItem.infoData.web}}</p>
|
||||||
</InputGroup>
|
<p v-if="currentItem.infoData.ustid">USt-Id: {{currentItem.infoData.ustid}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Logbuch'">
|
||||||
|
<HistoryDisplay
|
||||||
|
type="vendor"
|
||||||
|
v-if="currentItem"
|
||||||
|
:element-id="currentItem.id"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="item.label === 'Ansprechpartner'">
|
||||||
|
<Toolbar>
|
||||||
|
<UButton
|
||||||
|
@click="router.push(`/contacts/create?vendor=${currentItem.id}`)"
|
||||||
|
>
|
||||||
|
+ Ansprechpartner
|
||||||
|
</UButton>
|
||||||
|
</Toolbar>
|
||||||
|
<UTable
|
||||||
|
:rows="dataStore.getContactsByVendorId(currentItem.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' }"
|
||||||
|
|
||||||
Information: <br>
|
|
||||||
<div v-if="currentItem.infoData">
|
|
||||||
<span v-if="currentItem.infoData.street">Straße + Hausnummer: {{currentItem.infoData.street}}<br></span>
|
|
||||||
<span v-if="currentItem.infoData.zip && currentItem.infoData.city">PLZ + Ort: {{currentItem.infoData.zip}} {{currentItem.infoData.city}}<br></span>
|
|
||||||
<span v-if="currentItem.infoData.tel">Telefon: {{currentItem.infoData.tel}}<br></span>
|
|
||||||
<span v-if="currentItem.infoData.email">E-Mail: {{currentItem.infoData.email}}<br></span>
|
|
||||||
<span v-if="currentItem.infoData.web">Web: {{currentItem.infoData.web}}<br></span>
|
|
||||||
<span v-if="currentItem.infoData.ustid">USt-Id: {{currentItem.infoData.ustid}}<br></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<UDivider class="my-3"/>
|
|
||||||
|
|
||||||
<div v-if="dataStore.getContactsByVendorId(currentItem.id).length > 0">
|
|
||||||
Kontakte: <br>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li
|
|
||||||
v-for="contact in dataStore.getContactsByVendorId(currentItem.id)"
|
|
||||||
>
|
>
|
||||||
<router-link :to="'/contacts/show/' + contact.id">{{contact.salutation}} {{contact.fullName}} - {{contact.role}}</router-link>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<template #footer>
|
</UTable>
|
||||||
<UButton
|
|
||||||
v-if="mode == 'show' && currentItem.id"
|
</div>
|
||||||
@click="editItem"
|
</UCard>
|
||||||
>
|
</template>
|
||||||
Bearbeiten
|
</UTabs>
|
||||||
</UButton>
|
<UCard v-else-if="mode === 'edit' || mode === 'create'" >
|
||||||
<UButton
|
<template #header v-if="mode === 'edit'">
|
||||||
color="red"
|
{{itemInfo.name}}
|
||||||
class="ml-2"
|
</template>
|
||||||
disabled
|
|
||||||
>
|
<UFormGroup
|
||||||
Archivieren
|
label="Name:"
|
||||||
</UButton>
|
>
|
||||||
</template>
|
<UInput
|
||||||
|
v-model="itemInfo.name"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Lieferantennr.:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.vendorNumber"
|
||||||
|
placeholder="Leer lassen für automatisch generierte Nummer"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Straße + Hausnummer"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.infoData.street"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Postleitzahl"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.infoData.zip"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Ort"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.infoData.city"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
|
||||||
|
<UFormGroup
|
||||||
|
label="Telefon:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.infoData.tel"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="E-Mail:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.infoData.email"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="Webseite:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.infoData.web"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
<UFormGroup
|
||||||
|
label="USt-Id:"
|
||||||
|
>
|
||||||
|
<UInput
|
||||||
|
v-model="itemInfo.infoData.ustid"
|
||||||
|
/>
|
||||||
|
</UFormGroup>
|
||||||
|
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
</UCard>
|
<UButton
|
||||||
<UCard v-else-if="mode === 'edit' || mode === 'create'" >
|
v-if="mode == 'edit'"
|
||||||
<template #header v-if="mode === 'edit'">
|
@click="dataStore.updateItem('vendors',itemInfo)"
|
||||||
{{itemInfo.name}}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<UFormGroup
|
|
||||||
label="Name:"
|
|
||||||
>
|
>
|
||||||
<UInput
|
Speichern
|
||||||
v-model="itemInfo.name"
|
</UButton>
|
||||||
/>
|
<UButton
|
||||||
</UFormGroup>
|
v-else-if="mode == 'create'"
|
||||||
<UFormGroup
|
@click="dataStore.createNewItem('vendors',itemInfo)"
|
||||||
label="Lieferantennr.:"
|
|
||||||
>
|
>
|
||||||
<UInput
|
Erstellen
|
||||||
v-model="itemInfo.vendorNumber"
|
</UButton>
|
||||||
placeholder="Leer lassen für automatisch generierte Nummer"
|
<UButton
|
||||||
/>
|
@click="cancelEditorCreate"
|
||||||
</UFormGroup>
|
color="red"
|
||||||
<UFormGroup
|
class="ml-2"
|
||||||
label="Straße + Hausnummer"
|
|
||||||
>
|
>
|
||||||
<UInput
|
Abbrechen
|
||||||
v-model="itemInfo.infoData.street"
|
</UButton>
|
||||||
/>
|
</template>
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup
|
|
||||||
label="Postleitzahl"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="itemInfo.infoData.zip"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup
|
|
||||||
label="Ort"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="itemInfo.infoData.city"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
|
|
||||||
<UFormGroup
|
</UCard>
|
||||||
label="Telefon:"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="itemInfo.infoData.tel"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup
|
|
||||||
label="E-Mail:"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="itemInfo.infoData.email"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup
|
|
||||||
label="Webseite:"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="itemInfo.infoData.web"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
<UFormGroup
|
|
||||||
label="USt-Id:"
|
|
||||||
>
|
|
||||||
<UInput
|
|
||||||
v-model="itemInfo.infoData.ustid"
|
|
||||||
/>
|
|
||||||
</UFormGroup>
|
|
||||||
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<UButton
|
|
||||||
v-if="mode == 'edit'"
|
|
||||||
@click="dataStore.updateItem('vendors',itemInfo)"
|
|
||||||
>
|
|
||||||
Speichern
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
v-else-if="mode == 'create'"
|
|
||||||
@click="dataStore.createNewItem('vendors',itemInfo)"
|
|
||||||
>
|
|
||||||
Erstellen
|
|
||||||
</UButton>
|
|
||||||
<UButton
|
|
||||||
@click="cancelEditorCreate"
|
|
||||||
color="red"
|
|
||||||
class="ml-2"
|
|
||||||
>
|
|
||||||
Abbrechen
|
|
||||||
</UButton>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
</UCard>
|
|
||||||
|
|
||||||
<HistoryDisplay
|
|
||||||
type="vendor"
|
|
||||||
v-if="currentItem"
|
|
||||||
:element-id="currentItem.id"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
21
spaces/pages/vendors/index.vue
vendored
21
spaces/pages/vendors/index.vue
vendored
@@ -1,26 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="main">
|
<Toolbar>
|
||||||
<!-- TODO: Kontakte erstellen und dem Lieferanten zuweisen -->
|
<UButton @click="router.push(`/vendors/create/`)">+ Lieferant</UButton>
|
||||||
|
|
||||||
<div class="flex items-center gap-1">
|
|
||||||
<UButton @click="router.push(`/vendors/create/`)">+ Lieferant</UButton>
|
|
||||||
|
|
||||||
<UInput
|
|
||||||
v-model="searchString"
|
|
||||||
placeholder="Suche..."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<UInput
|
||||||
|
v-model="searchString"
|
||||||
|
placeholder="Suche..."
|
||||||
|
/>
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="table">
|
||||||
<UTable
|
<UTable
|
||||||
:rows="filteredRows"
|
:rows="filteredRows"
|
||||||
:columns="itemColumns"
|
:columns="itemColumns"
|
||||||
@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' }"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|||||||
@@ -87,6 +87,11 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
incomingInvoices: {
|
incomingInvoices: {
|
||||||
label: "Eingangsrechnungen",
|
label: "Eingangsrechnungen",
|
||||||
labelSingle: "Eingangsrechnung"
|
labelSingle: "Eingangsrechnung"
|
||||||
|
},
|
||||||
|
inventoryitems: {
|
||||||
|
label: "Inventarartikel",
|
||||||
|
labelSingle: "Inventarartikel",
|
||||||
|
redirect: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,12 +156,13 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
const accounts = ref([])
|
const accounts = ref([])
|
||||||
const taxTypes = ref([])
|
const taxTypes = ref([])
|
||||||
const plants = ref([])
|
const plants = ref([])
|
||||||
const inventoryItems = ref([])
|
const inventoryitems = ref([])
|
||||||
const chats = ref([])
|
const chats = ref([])
|
||||||
const messages = ref([])
|
const messages = ref([])
|
||||||
const createddocuments = ref([])
|
const createddocuments = ref([])
|
||||||
const workingtimes = ref([])
|
const workingtimes = ref([])
|
||||||
const phasesTemplates = ref([])
|
const phasesTemplates = ref([])
|
||||||
|
const emailAccounts = ref([])
|
||||||
|
|
||||||
|
|
||||||
const rights = ref({
|
const rights = ref({
|
||||||
@@ -217,13 +223,10 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
async function initializeData () {
|
async function initializeData (userId) {
|
||||||
//console.log(user.value.id)
|
let profile = (await supabase.from("profiles").select().eq("id",userId).single()).data
|
||||||
let profile = (await supabase.from("profiles").select().eq("id",user.value.id).single()).data
|
|
||||||
|
|
||||||
//console.log(profile)
|
currentTenant.value = profile.tenant
|
||||||
|
|
||||||
currentTenant.value = profile.tenant//profiles.value.find(i => i.id === user.value.id).tenants[0].id
|
|
||||||
|
|
||||||
await fetchData()
|
await fetchData()
|
||||||
|
|
||||||
@@ -273,6 +276,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
await fetchCreatedDocuments()
|
await fetchCreatedDocuments()
|
||||||
await fetchWorkingTimes()
|
await fetchWorkingTimes()
|
||||||
await fetchPhasesTemplates()
|
await fetchPhasesTemplates()
|
||||||
|
await fetchEmailAccounts()
|
||||||
loaded.value = true
|
loaded.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +284,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
console.log("Clear")
|
console.log("Clear")
|
||||||
loaded.value = false
|
loaded.value = false
|
||||||
ownTenant.value = {}
|
ownTenant.value = {}
|
||||||
profiles.value= []
|
profiles.value = []
|
||||||
events.value= []
|
events.value= []
|
||||||
customers.value= []
|
customers.value= []
|
||||||
tasks.value= []
|
tasks.value= []
|
||||||
@@ -307,12 +311,13 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
accounts.value = []
|
accounts.value = []
|
||||||
taxTypes.value = []
|
taxTypes.value = []
|
||||||
plants.value = []
|
plants.value = []
|
||||||
inventoryItems.value = []
|
inventoryitems.value = []
|
||||||
chats.value = []
|
chats.value = []
|
||||||
messages.value = []
|
messages.value = []
|
||||||
createddocuments.value = []
|
createddocuments.value = []
|
||||||
workingtimes.value = []
|
workingtimes.value = []
|
||||||
phasesTemplates.value = []
|
phasesTemplates.value = []
|
||||||
|
emailAccounts.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasRight (right) {
|
function hasRight (right) {
|
||||||
@@ -338,13 +343,13 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
(payload) => {
|
(payload) => {
|
||||||
//console.log(payload)
|
//console.log(payload)
|
||||||
|
|
||||||
if(payload.eventType === 'INSERT') {
|
/*if(payload.eventType === 'INSERT') {
|
||||||
const c = payload.table + '.value.push(' + JSON.stringify(payload.new) + ')'
|
const c = payload.table + '.value.push(' + JSON.stringify(payload.new) + ')'
|
||||||
eval(c)
|
eval(c)
|
||||||
} else if(payload.eventType === 'UPDATE'){
|
} else if(payload.eventType === 'UPDATE'){
|
||||||
const c = payload.table + '.value[' + payload.table + '.value.findIndex(i => i.id === ' + JSON.stringify(payload.old.id) + ')] = ' + JSON.stringify(payload.new)
|
const c = payload.table + '.value[' + payload.table + '.value.findIndex(i => i.id === ' + JSON.stringify(payload.old.id) + ')] = ' + JSON.stringify(payload.new)
|
||||||
eval(c)
|
eval(c)
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.subscribe()
|
.subscribe()
|
||||||
@@ -371,7 +376,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
if(supabaseError) {
|
if(supabaseError) {
|
||||||
console.log(supabaseError)
|
console.log(supabaseError)
|
||||||
} else if (supabaseData) {
|
} else if (supabaseData) {
|
||||||
//await eval( dataType + '.value.push(' + JSON.stringify(...supabaseData) + ')')
|
await eval( dataType + '.value.push(' + JSON.stringify(...supabaseData) + ')')
|
||||||
toast.add({title: `${dataTypes[dataType].labelSingle} hinzugefügt`})
|
toast.add({title: `${dataTypes[dataType].labelSingle} hinzugefügt`})
|
||||||
if(dataTypes[dataType].redirect) await router.push(`/${dataType}/show/${supabaseData[0].id}`)
|
if(dataTypes[dataType].redirect) await router.push(`/${dataType}/show/${supabaseData[0].id}`)
|
||||||
return supabaseData
|
return supabaseData
|
||||||
@@ -396,7 +401,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uploadFiles = async (formData, files, upsert) => {
|
const uploadFiles = async (formData, files, upsert) => {
|
||||||
|
console.log(files)
|
||||||
let documentsToInsert = []
|
let documentsToInsert = []
|
||||||
|
|
||||||
const uploadSingleFile = async (file) => {
|
const uploadSingleFile = async (file) => {
|
||||||
@@ -436,11 +441,13 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
} else if( files.length > 1) {
|
} else if( files.length > 1) {
|
||||||
|
|
||||||
for(let i = 0; i < files.length; i++){
|
for(let i = 0; i < files.length; i++){
|
||||||
uploadSingleFile(files[i])
|
await uploadSingleFile(files[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(documentsToInsert)
|
||||||
|
|
||||||
const {data, error} = await supabase
|
const {data, error} = await supabase
|
||||||
.from("documents")
|
.from("documents")
|
||||||
.insert(documentsToInsert)
|
.insert(documentsToInsert)
|
||||||
@@ -464,7 +471,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchProfiles () {
|
async function fetchProfiles () {
|
||||||
profiles.value = (await supabase.from("profiles").select('* , tenants (id, name)')).data
|
profiles.value = (await supabase.from("profiles").select('* , tenants (id, name)')/*.eq("tenant", currentTenant.value)*/.order("fullName")).data
|
||||||
}
|
}
|
||||||
async function fetchBankAccounts () {
|
async function fetchBankAccounts () {
|
||||||
bankAccounts.value = (await supabase.from("bankaccounts").select().eq('tenant', currentTenant.value)).data
|
bankAccounts.value = (await supabase.from("bankaccounts").select().eq('tenant', currentTenant.value)).data
|
||||||
@@ -543,7 +550,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
plants.value = (await supabase.from("plants").select().eq('tenant', currentTenant.value)).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().eq('tenant', currentTenant.value)).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
|
||||||
@@ -563,25 +570,35 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
phasesTemplates.value = (await supabase.from("phasesTemplates").select().eq('tenant', currentTenant.value).order('created_at', {ascending:true})).data
|
phasesTemplates.value = (await supabase.from("phasesTemplates").select().eq('tenant', currentTenant.value).order('created_at', {ascending:true})).data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchEmailAccounts() {
|
||||||
|
emailAccounts.value = (await supabase.from("emailAccounts").select().eq('tenant', currentTenant.value)).data
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchDocuments () {
|
async function fetchDocuments () {
|
||||||
let tempDocuments = (await supabase.from("documents").select().eq('tenant', currentTenant.value)).data
|
let tempDocuments = (await supabase.from("documents").select().eq('tenant', currentTenant.value)).data
|
||||||
|
|
||||||
let paths = []
|
if(tempDocuments.length > 0){
|
||||||
tempDocuments.forEach(doc => {
|
let paths = []
|
||||||
paths.push(doc.path)
|
tempDocuments.forEach(doc => {
|
||||||
})
|
paths.push(doc.path)
|
||||||
|
})
|
||||||
|
|
||||||
const {data,error} = await supabase.storage.from('files').createSignedUrls(paths,3600)
|
const {data,error} = await supabase.storage.from('files').createSignedUrls(paths,3600)
|
||||||
|
|
||||||
tempDocuments = tempDocuments.map((doc,index) => {
|
tempDocuments = tempDocuments.map((doc,index) => {
|
||||||
|
|
||||||
|
return {
|
||||||
|
...doc,
|
||||||
|
url: data[index].signedUrl
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
documents.value = tempDocuments
|
||||||
|
} else {
|
||||||
|
documents.value = []
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
|
||||||
...doc,
|
|
||||||
url: data[index].signedUrl
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
documents.value = tempDocuments
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addHistoryItem(text, user, elementId, resourceType) {
|
async function addHistoryItem(text, user, elementId, resourceType) {
|
||||||
@@ -615,7 +632,8 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const getOwnProfile = computed(() => {
|
const getOwnProfile = computed(() => {
|
||||||
return profiles.value.find(profile => profile.id === user.value.id)
|
return profiles.value.find(i => i.id === user.value.id)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const getMovementsBySpace = computed(() => (spaceId) => {
|
const getMovementsBySpace = computed(() => (spaceId) => {
|
||||||
@@ -626,6 +644,18 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
return contacts.value.filter(item => item.customer === customerId)
|
return contacts.value.filter(item => item.customer === customerId)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const getProjectsByCustomerId = computed(() => (customerId) => {
|
||||||
|
return projects.value.filter(item => item.customer === customerId)
|
||||||
|
})
|
||||||
|
|
||||||
|
const getPlantsByCustomerId = computed(() => (customerId) => {
|
||||||
|
return plants.value.filter(item => item.customer === customerId)
|
||||||
|
})
|
||||||
|
|
||||||
|
const getContractsByCustomerId = computed(() => (customerId) => {
|
||||||
|
return contracts.value.filter(item => item.customer === customerId)
|
||||||
|
})
|
||||||
|
|
||||||
const getContactsByVendorId = computed(() => (vendorId) => {
|
const getContactsByVendorId = computed(() => (vendorId) => {
|
||||||
return contacts.value.filter(item => item.vendor === vendorId)
|
return contacts.value.filter(item => item.vendor === vendorId)
|
||||||
})
|
})
|
||||||
@@ -646,6 +676,10 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
return documents.value.filter(item => item.vehicle === itemId && !item.tags.includes("Archiviert"))
|
return documents.value.filter(item => item.vehicle === itemId && !item.tags.includes("Archiviert"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const getDocumentsByProductId = computed(() => (itemId) => {
|
||||||
|
return documents.value.filter(item => item.product === itemId && !item.tags.includes("Archiviert"))
|
||||||
|
})
|
||||||
|
|
||||||
const getEventsByProjectId = computed(() => (projectId) => {
|
const getEventsByProjectId = computed(() => (projectId) => {
|
||||||
return events.value.filter(item => item.project === projectId)
|
return events.value.filter(item => item.project === projectId)
|
||||||
})
|
})
|
||||||
@@ -722,7 +756,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
id: `F-${vehicle.id}`
|
id: `F-${vehicle.id}`
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
...inventoryItems.value.filter(i=> i.usePlanning).map(item => {
|
...inventoryitems.value.filter(i=> i.usePlanning).map(item => {
|
||||||
return {
|
return {
|
||||||
type: 'Inventar',
|
type: 'Inventar',
|
||||||
title: item.name,
|
title: item.name,
|
||||||
@@ -903,6 +937,10 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
return createddocuments.value.find(item => item.id === documentId)
|
return createddocuments.value.find(item => item.id === documentId)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const getInventoryItemById = computed(() => (itemId) => {
|
||||||
|
return inventoryitems.value.find(item => item.id === itemId)
|
||||||
|
})
|
||||||
|
|
||||||
const getProjectById = computed(() => (itemId) => {
|
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)
|
||||||
@@ -961,13 +999,15 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
accounts,
|
accounts,
|
||||||
taxTypes,
|
taxTypes,
|
||||||
plants,
|
plants,
|
||||||
inventoryItems,
|
inventoryitems,
|
||||||
chats,
|
chats,
|
||||||
messages,
|
messages,
|
||||||
createddocuments,
|
createddocuments,
|
||||||
workingtimes,
|
workingtimes,
|
||||||
phasesTemplates,
|
phasesTemplates,
|
||||||
|
emailAccounts,
|
||||||
documentTypesForCreation,
|
documentTypesForCreation,
|
||||||
|
|
||||||
//Functions
|
//Functions
|
||||||
createNewItem,
|
createNewItem,
|
||||||
updateItem,
|
updateItem,
|
||||||
@@ -1008,11 +1048,15 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
getOwnProfile,
|
getOwnProfile,
|
||||||
getMovementsBySpace,
|
getMovementsBySpace,
|
||||||
getContactsByCustomerId,
|
getContactsByCustomerId,
|
||||||
|
getProjectsByCustomerId,
|
||||||
|
getPlantsByCustomerId,
|
||||||
|
getContractsByCustomerId,
|
||||||
getContactsByVendorId,
|
getContactsByVendorId,
|
||||||
getDocumentsByProjectId,
|
getDocumentsByProjectId,
|
||||||
getDocumentsByPlantId,
|
getDocumentsByPlantId,
|
||||||
getDocumentsByContractId,
|
getDocumentsByContractId,
|
||||||
getDocumentsByVehicleId,
|
getDocumentsByVehicleId,
|
||||||
|
getDocumentsByProductId,
|
||||||
getEventsByProjectId,
|
getEventsByProjectId,
|
||||||
getTimesByProjectId,
|
getTimesByProjectId,
|
||||||
getTasksByProjectId,
|
getTasksByProjectId,
|
||||||
@@ -1045,7 +1089,8 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
getProfileById,
|
getProfileById,
|
||||||
getAccountById,
|
getAccountById,
|
||||||
getPlantById,
|
getPlantById,
|
||||||
getCreatedDocumentById
|
getCreatedDocumentById,
|
||||||
|
getInventoryItemById,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user