Deprecated following as non standardEntity checks, inventoryitems, spaces
This commit is contained in:
337
deprecated/checks/[mode]/[[id]].vue
Normal file
337
deprecated/checks/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,337 @@
|
||||
<script setup>
|
||||
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||
import dayjs from "dayjs";
|
||||
import {useSupabaseSelectSingle} from "~/composables/useSupabase.js";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/checks")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
const openTab = ref(0)
|
||||
|
||||
const vehicles = ref([])
|
||||
const profiles = ref([])
|
||||
const inventoryitems = ref([])
|
||||
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({
|
||||
name: "",
|
||||
vehicle: null,
|
||||
inventoryitem: null,
|
||||
profile: null,
|
||||
distance: 1,
|
||||
distanceUnit: "days"
|
||||
})
|
||||
|
||||
//Functions
|
||||
const setupPage = async () => {
|
||||
|
||||
profiles.value = await useSupabaseSelect("profiles")
|
||||
vehicles.value = await useSupabaseSelect("vehicles")
|
||||
inventoryitems.value = await useSupabaseSelect("inventoryitems")
|
||||
|
||||
if(mode.value === "show" ){
|
||||
itemInfo.value = await useSupabaseSelectSingle("checks", route.params.id, "*, checkexecutions(*, executed_by(fullName)), vehicle(*), profile(*), inventoryitem(*)")
|
||||
} else if (mode.value === "edit"){
|
||||
itemInfo.value = await useSupabaseSelectSingle("checks", route.params.id, "*")
|
||||
}
|
||||
|
||||
if(mode.value === "create") {
|
||||
let query = route.query
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(itemInfo.value) {
|
||||
router.push(`/checks/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/checks/`)
|
||||
}
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar>
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/checks`)"
|
||||
>
|
||||
Überprüfungen
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
:class="['text-xl','font-medium']"
|
||||
>{{itemInfo ? `Überprüfung: ${itemInfo.name}` : (mode === 'create' ? 'Überprüfung erstellen' : 'Überprüfung bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@click="dataStore.updateItem('checks',itemInfo)"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else-if="mode === 'create'"
|
||||
@click="dataStore.createNewItem('checks',itemInfo)"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="cancelEditorCreate"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click="router.push(`/checks/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UDashboardPanelContent>
|
||||
<UTabs
|
||||
v-if="itemInfo.id && mode === 'show'"
|
||||
:items="[{label: 'Informationen'}, {label: 'Dokumente'}, {label: 'Ausführungen'}]"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<div v-if="item.label === 'Informationen'" class="flex mt-5">
|
||||
<div class="w-1/2 mr-5">
|
||||
<UCard>
|
||||
<div class="text-wrap">
|
||||
<table class="mb-3 w-full">
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td>{{itemInfo.name}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Rhythmus:</td>
|
||||
<td>
|
||||
{{itemInfo.distance}}
|
||||
<span v-if="itemInfo.distanceUnit === 'dayjs'">Tage</span>
|
||||
<span v-if="itemInfo.distanceUnit === 'years'">Jahre</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="itemInfo.vehicle">
|
||||
<td>Fahrzeug:</td>
|
||||
<td>{{itemInfo.vehicle.licensePlate}}</td>
|
||||
</tr>
|
||||
<tr v-if="itemInfo.profile">
|
||||
<td>Person:</td>
|
||||
<td>{{itemInfo.profile.fullName}}</td>
|
||||
</tr>
|
||||
<tr v-if="itemInfo.inventoryitem">
|
||||
<td>Inventarartikel:</td>
|
||||
<td>{{itemInfo.inventoryitem.name}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Beschreibung:</td>
|
||||
<td>{{itemInfo.description}}</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</UCard>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<UCard class="h-full">
|
||||
<HistoryDisplay
|
||||
type="check"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
:render-headline="true"
|
||||
/>
|
||||
</UCard>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Dokumente'">
|
||||
<UCard class="mt-5">
|
||||
<Toolbar>
|
||||
<DocumentUpload
|
||||
type="check"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</Toolbar>
|
||||
<DocumentList
|
||||
:documents="dataStore.getDocumentsByContractId(itemInfo.id)"
|
||||
/>
|
||||
</UCard>
|
||||
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Ausführungen'">
|
||||
<UCard class="mt-5">
|
||||
<UTable
|
||||
:rows="itemInfo.checkexecutions"
|
||||
:columns="[{key:'created_at',label:'Ersellt am:'},{key:'executed_at',label:'Ausgeführt am:'},{key:'executed_by',label:'Ausgeführt von:'},{key:'description',label:'Beschreibung:'}]"
|
||||
class="w-full"
|
||||
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Ausführungen anzuzeigen' }"
|
||||
>
|
||||
<template #created_at-data="{row}">
|
||||
{{dayjs(row.created_at).format("DD.MM.YYYY HH:mm")}}
|
||||
</template>
|
||||
<template #executed_at-data="{row}">
|
||||
{{dayjs(row.executed_at).format("DD.MM.YYYY HH:mm")}}
|
||||
</template>
|
||||
<template #executed_by-data="{row}">
|
||||
{{row.executed_by.fullName}}
|
||||
</template>
|
||||
</UTable>
|
||||
</UCard>
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
</UTabs>
|
||||
<UForm v-else-if="mode === 'edit' || mode === 'create'" class="p-5" >
|
||||
<div class="mx-auto w-4/5">
|
||||
<div class="flex flex-row justify-around">
|
||||
<div class="w-1/2">
|
||||
<UDivider>Allgemeines</UDivider>
|
||||
<UFormGroup
|
||||
label="Name:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.name"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Typ:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.type"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Rhythmus"
|
||||
class="w-full"
|
||||
>
|
||||
<InputGroup class="w-full">
|
||||
<UInput
|
||||
v-model="itemInfo.distance"
|
||||
type="number"
|
||||
class="flex-auto"
|
||||
></UInput>
|
||||
<USelectMenu
|
||||
:options="[{key: 'days', label: 'Tage'},{key:'years',label:'Jahre'}]"
|
||||
option-attribute="label"
|
||||
value-attribute="key"
|
||||
v-model="itemInfo.distanceUnit"
|
||||
class="w-40"
|
||||
></USelectMenu>
|
||||
</InputGroup>
|
||||
</UFormGroup>
|
||||
|
||||
|
||||
</div>
|
||||
<div class=" ml-5 w-1/2">
|
||||
<UDivider>Verknüpftes Element</UDivider>
|
||||
<UFormGroup
|
||||
label="Fahrzeug:"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="vehicles"
|
||||
option-attribute="licensePlate"
|
||||
value-attribute="id"
|
||||
v-model="itemInfo.vehicle"
|
||||
:disabled="itemInfo.inventoryitem || itemInfo.profile"
|
||||
|
||||
>
|
||||
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Person:"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="profiles"
|
||||
option-attribute="fullName"
|
||||
value-attribute="id"
|
||||
v-model="itemInfo.profile"
|
||||
:disabled="itemInfo.vehicle || itemInfo.inventoryitem"
|
||||
|
||||
>
|
||||
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Inventarartikel:"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="inventoryitems"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
v-model="itemInfo.inventoryitem"
|
||||
:disabled="itemInfo.vehicle || itemInfo.profile"
|
||||
>
|
||||
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<UFormGroup
|
||||
label="Beschreibung:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.description"
|
||||
rows="6"
|
||||
maxrows="12"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</UForm>
|
||||
</UDashboardPanelContent>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
td {
|
||||
border-bottom: 1px solid lightgrey;
|
||||
vertical-align: top;
|
||||
padding-bottom: 0.15em;
|
||||
padding-top: 0.15em;
|
||||
}
|
||||
</style>
|
||||
148
deprecated/checks/index.vue
Normal file
148
deprecated/checks/index.vue
Normal file
@@ -0,0 +1,148 @@
|
||||
<template>
|
||||
<UDashboardNavbar title="Überprüfungen" :badge="filteredRows.length">
|
||||
<template #right>
|
||||
<UInput
|
||||
id="searchinput"
|
||||
v-model="searchString"
|
||||
icon="i-heroicons-funnel"
|
||||
autocomplete="off"
|
||||
placeholder="Suche..."
|
||||
class="hidden lg:block"
|
||||
@keydown.esc="$event.target.blur()"
|
||||
>
|
||||
<template #trailing>
|
||||
<UKbd value="/" />
|
||||
</template>
|
||||
</UInput>
|
||||
|
||||
<UButton @click="router.push(`/checks/create`)">+ Überprüfung</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
|
||||
<UDashboardToolbar>
|
||||
<template #right>
|
||||
<USelectMenu
|
||||
v-model="selectedColumns"
|
||||
icon="i-heroicons-adjustments-horizontal-solid"
|
||||
:options="templateColumns"
|
||||
multiple
|
||||
class="hidden lg:block"
|
||||
by="key"
|
||||
>
|
||||
<template #label>
|
||||
Spalten
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</template>
|
||||
</UDashboardToolbar>
|
||||
|
||||
<UTable
|
||||
:rows="filteredRows"
|
||||
:columns="columns"
|
||||
class="w-full"
|
||||
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
|
||||
@select="(i) => router.push(`/checks/show/${i.id}`) "
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Überprüfungen anzuzeigen' }"
|
||||
>
|
||||
<template #name-data="{row}">
|
||||
<span v-if="row === filteredRows[selectedItem]" class="text-primary-500 font-bold">{{row.name}}</span>
|
||||
<span v-else>{{row.name}}</span>
|
||||
</template>
|
||||
<template #vehicle-data="{row}">
|
||||
<span v-if="row.vehicle">{{row.vehicle.licensePlate}}</span>
|
||||
</template>
|
||||
<template #profile-data="{row}">
|
||||
<span v-if="row.profile">{{row.profile.fullName}}</span>
|
||||
</template>
|
||||
<template #inventoryitem-data="{row}">
|
||||
<span v-if="row.inventoryitem">{{row.inventoryitem.name}}</span>
|
||||
</template>
|
||||
|
||||
</UTable>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'/': () => {
|
||||
//console.log(searchinput)
|
||||
//searchinput.value.focus()
|
||||
document.getElementById("searchinput").focus()
|
||||
},
|
||||
'+': () => {
|
||||
router.push("/checks/create")
|
||||
},
|
||||
'Enter': {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
router.push(`/checks/show/${filteredRows.value[selectedItem.value].id}`)
|
||||
}
|
||||
},
|
||||
'arrowdown': () => {
|
||||
if(selectedItem.value < filteredRows.value.length - 1) {
|
||||
selectedItem.value += 1
|
||||
} else {
|
||||
selectedItem.value = 0
|
||||
}
|
||||
},
|
||||
'arrowup': () => {
|
||||
if(selectedItem.value === 0) {
|
||||
selectedItem.value = filteredRows.value.length - 1
|
||||
} else {
|
||||
selectedItem.value -= 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("checks","*, vehicle(licensePlate), profile(fullName), inventoryitem(name)")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const templateColumns = [
|
||||
{
|
||||
key: "name",
|
||||
label: "Name",
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
key: "vehicle",
|
||||
label: "Fahrzeug"
|
||||
},
|
||||
{
|
||||
key: "profile",
|
||||
label: "Person"
|
||||
},
|
||||
{
|
||||
key: "inventoryitem",
|
||||
label: "Inventarartikel"
|
||||
},
|
||||
{
|
||||
key: "notes",
|
||||
label: "Notizen"
|
||||
}
|
||||
]
|
||||
const selectedColumns = ref(templateColumns)
|
||||
const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
|
||||
|
||||
|
||||
const searchString = ref('')
|
||||
const filteredRows = computed(() => {
|
||||
return useSearch(searchString.value, items.value)
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
580
deprecated/email.vue
Normal file
580
deprecated/email.vue
Normal file
@@ -0,0 +1,580 @@
|
||||
<script setup>
|
||||
import axios from 'axios'
|
||||
import {sub} from 'date-fns'
|
||||
|
||||
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()
|
||||
|
||||
const selectedTab = ref(0)
|
||||
|
||||
const mails = ref([{
|
||||
id: 1,
|
||||
from: {
|
||||
name: 'Alex Smith',
|
||||
email: 'alex.smith@example.com',
|
||||
avatar: {
|
||||
src: 'https://i.pravatar.cc/128?u=1'
|
||||
}
|
||||
},
|
||||
subject: 'Meeting Schedule',
|
||||
body: 'Hi there, just a quick reminder about our meeting scheduled for 10 AM tomorrow. We\'ll be discussing the new marketing strategies and I would really appreciate your input on the matter. Looking forward to a productive session.',
|
||||
date: new Date().toISOString()
|
||||
}, {
|
||||
id: 2,
|
||||
unread: true,
|
||||
from: {
|
||||
name: 'Jordan Brown',
|
||||
email: 'jordan.brown@example.com',
|
||||
avatar: {
|
||||
src: 'https://i.pravatar.cc/128?u=2'
|
||||
}
|
||||
},
|
||||
subject: 'Project Update',
|
||||
body: 'I wanted to provide you with the latest update on the project. We\'ve made significant progress on the development front and I\'ve attached a detailed report for your review. Please let me know your thoughts and any areas for improvement.',
|
||||
date: sub(new Date(), { minutes: 7 }).toISOString()
|
||||
}, {
|
||||
id: 3,
|
||||
unread: true,
|
||||
from: {
|
||||
name: 'Taylor Green',
|
||||
email: 'taylor.green@example.com',
|
||||
avatar: {
|
||||
src: 'https://i.pravatar.cc/128?u=3'
|
||||
}
|
||||
},
|
||||
subject: 'Lunch Plans',
|
||||
body: 'Hey! I was wondering if you would like to grab lunch this Friday. I know a great spot downtown that serves the best Mexican cuisine. It would be a great opportunity for us to catch up and discuss the upcoming team event.',
|
||||
date: sub(new Date(), { hours: 3 }).toISOString()
|
||||
}, {
|
||||
id: 4,
|
||||
from: {
|
||||
name: 'Morgan White',
|
||||
email: 'morgan.white@example.com',
|
||||
avatar: {
|
||||
src: 'https://i.pravatar.cc/128?u=4'
|
||||
}
|
||||
},
|
||||
subject: 'New Proposal',
|
||||
body: 'I\'ve attached the new proposal for our next project. It outlines all the objectives, timelines, and resource allocations. I\'m particularly excited about the innovative approach we\'re taking this time. Please have a look and let me know your thoughts.',
|
||||
date: sub(new Date(), { days: 1 }).toISOString()
|
||||
}, {
|
||||
id: 5,
|
||||
from: {
|
||||
name: 'Casey Gray',
|
||||
email: 'casey.gray@example.com'
|
||||
},
|
||||
subject: 'Travel Itinerary',
|
||||
body: 'Your travel itinerary for the upcoming business trip is ready. I\'ve included all flight details, hotel reservations, and meeting schedules. Please review and let me know if there are any changes you would like to make or any additional arrangements needed.',
|
||||
date: sub(new Date(), { days: 1 }).toISOString()
|
||||
}, {
|
||||
id: 6,
|
||||
from: {
|
||||
name: 'Jamie Johnson',
|
||||
email: 'jamie.johnson@example.com'
|
||||
},
|
||||
subject: 'Budget Report',
|
||||
body: 'I\'ve completed the budget report for this quarter. It includes a detailed analysis of our expenditures and revenue, along with projections for the next quarter. I believe there are some areas where we can optimize our spending. Let\'s discuss this in our next finance meeting.',
|
||||
date: sub(new Date(), { days: 2 }).toISOString()
|
||||
}, {
|
||||
id: 7,
|
||||
from: {
|
||||
name: 'Riley Davis',
|
||||
email: 'riley.davis@example.com',
|
||||
avatar: {
|
||||
src: 'https://i.pravatar.cc/128?u=7'
|
||||
}
|
||||
},
|
||||
subject: 'Training Session',
|
||||
body: 'Just a reminder about the training session scheduled for next week. We\'ll be covering new software tools that are crucial for our workflow. It\'s important that everyone attends as this will greatly enhance our team\'s efficiency. Please confirm your availability.',
|
||||
date: sub(new Date(), { days: 2 }).toISOString()
|
||||
}, {
|
||||
id: 8,
|
||||
unread: true,
|
||||
from: {
|
||||
name: 'Kelly Wilson',
|
||||
email: 'kelly.wilson@example.com',
|
||||
avatar: {
|
||||
src: 'https://i.pravatar.cc/128?u=8'
|
||||
}
|
||||
},
|
||||
subject: 'Happy Birthday!',
|
||||
body: 'Happy Birthday! Wishing you a fantastic day filled with joy and laughter. Your dedication and hard work throughout the year have been invaluable to our team. Enjoy your day to the fullest!',
|
||||
date: sub(new Date(), { days: 2 }).toISOString()
|
||||
}, {
|
||||
id: 9,
|
||||
from: {
|
||||
name: 'Drew Moore',
|
||||
email: 'drew.moore@example.com'
|
||||
},
|
||||
subject: 'Website Feedback',
|
||||
body: 'We are in the process of revamping our company website and I would greatly appreciate your feedback on the new design. Your perspective is always insightful and could help us enhance the user experience significantly. Please let me know a convenient time for you to discuss this.',
|
||||
date: sub(new Date(), { days: 5 }).toISOString()
|
||||
}, {
|
||||
id: 10,
|
||||
from: {
|
||||
name: 'Jordan Taylor',
|
||||
email: 'jordan.taylor@example.com'
|
||||
},
|
||||
subject: 'Gym Membership',
|
||||
body: 'This is a friendly reminder that your gym membership is due for renewal at the end of this month. We\'ve added several new classes and facilities that I think you\'ll really enjoy. Let me know if you would like a tour of the new facilities.',
|
||||
date: sub(new Date(), { days: 5 }).toISOString()
|
||||
}, {
|
||||
id: 11,
|
||||
unread: true,
|
||||
from: {
|
||||
name: 'Morgan Anderson',
|
||||
email: 'morgan.anderson@example.com'
|
||||
},
|
||||
subject: 'Insurance Policy',
|
||||
body: 'I\'m writing to inform you that your insurance policy details have been updated. The new document outlines the changes in coverage and premium rates. It\'s important to review these changes to ensure they meet your needs. Please don\'t hesitate to contact me if you have any questions.',
|
||||
date: sub(new Date(), { days: 12 }).toISOString()
|
||||
}, {
|
||||
id: 12,
|
||||
from: {
|
||||
name: 'Casey Thomas',
|
||||
email: 'casey.thomas@example.com'
|
||||
},
|
||||
subject: 'Book Club Meeting',
|
||||
body: 'I\'m excited to remind you about our next book club meeting scheduled for next Thursday. We\'ll be discussing \'The Great Gatsby,\' and I\'m looking forward to hearing everyone\'s perspectives. Also, we will be choosing our next book, so bring your suggestions!',
|
||||
date: sub(new Date(), { months: 1 }).toISOString()
|
||||
}, {
|
||||
id: 13,
|
||||
from: {
|
||||
name: 'Jamie Jackson',
|
||||
email: 'jamie.jackson@example.com'
|
||||
},
|
||||
subject: 'Recipe Exchange',
|
||||
body: 'Don\'t forget to send in your favorite recipe for our upcoming recipe exchange. It\'s a great opportunity to share and discover new and delicious meals. I\'m particularly excited to try out new dishes and add some variety to my cooking.',
|
||||
date: sub(new Date(), { months: 1 }).toISOString()
|
||||
}, {
|
||||
id: 14,
|
||||
from: {
|
||||
name: 'Riley White',
|
||||
email: 'riley.white@example.com'
|
||||
},
|
||||
subject: 'Yoga Class Schedule',
|
||||
body: 'The new schedule for yoga classes is now available. We\'ve added some new styles and adjusted the timings to accommodate more participants. I believe these classes are a great way to relieve stress and stay healthy. Hope to see you there!',
|
||||
date: sub(new Date(), { months: 1 }).toISOString()
|
||||
}, {
|
||||
id: 15,
|
||||
from: {
|
||||
name: 'Kelly Harris',
|
||||
email: 'kelly.harris@example.com'
|
||||
},
|
||||
subject: 'Book Launch Event',
|
||||
body: 'I\'m thrilled to invite you to my book launch event next month. It\'s been a journey writing this book and I\'m eager to share it with you. The event will include a reading session, Q&A, and a signing opportunity. Your support would mean a lot to me.',
|
||||
date: sub(new Date(), { months: 1 }).toISOString()
|
||||
}, {
|
||||
id: 16,
|
||||
from: {
|
||||
name: 'Drew Martin',
|
||||
email: 'drew.martin@example.com'
|
||||
},
|
||||
subject: 'Tech Conference',
|
||||
body: 'Join us at the upcoming tech conference where we will be discussing the latest trends and innovations in technology. This is a great opportunity to network with industry leaders and learn about cutting-edge developments. Your participation would greatly contribute to our team\'s knowledge and growth.',
|
||||
date: sub(new Date(), { months: 1, days: 4 }).toISOString()
|
||||
}, {
|
||||
id: 17,
|
||||
from: {
|
||||
name: 'Alex Thompson',
|
||||
email: 'alex.thompson@example.com'
|
||||
},
|
||||
subject: 'Art Exhibition',
|
||||
body: 'I wanted to invite you to check out the new art exhibition this weekend. It features some amazing contemporary artists and their latest works. It\'s a great opportunity to immerse yourself in the local art scene and get inspired. Let me know if you\'re interested in going together.',
|
||||
date: sub(new Date(), { months: 1, days: 15 }).toISOString()
|
||||
}, {
|
||||
id: 18,
|
||||
from: {
|
||||
name: 'Jordan Garcia',
|
||||
email: 'jordan.garcia@example.com'
|
||||
},
|
||||
subject: 'Networking Event',
|
||||
body: 'I\'m looking forward to seeing you at the networking event next week. It\'s a great chance to connect with professionals from various industries and expand our professional network. There will also be guest speakers discussing key business trends. Your presence would add great value to the discussions.',
|
||||
date: sub(new Date(), { months: 1, days: 18 }).toISOString()
|
||||
}, {
|
||||
id: 19,
|
||||
from: {
|
||||
name: 'Taylor Rodriguez',
|
||||
email: 'taylor.rodriguez@example.com'
|
||||
},
|
||||
subject: 'Volunteer Opportunity',
|
||||
body: 'We\'re looking for volunteers for the upcoming community event. It\'s a great opportunity to give back and make a positive impact. There are various roles available, so you can choose something that aligns with your interests and skills. Let me know if you\'re interested and I\'ll provide more details.',
|
||||
date: sub(new Date(), { months: 1, days: 25 }).toISOString()
|
||||
}, {
|
||||
id: 20,
|
||||
from: {
|
||||
name: 'Morgan Lopez',
|
||||
email: 'morgan.lopez@example.com'
|
||||
},
|
||||
subject: 'Car Service Reminder',
|
||||
body: 'Just a reminder that your car is due for service next week. Regular maintenance is important to ensure your vehicle\'s longevity and performance. I\'ve included the details of the service center and the recommended services in this email. Feel free to contact them directly to schedule an appointment.',
|
||||
date: sub(new Date(), { months: 2 }).toISOString()
|
||||
}])
|
||||
|
||||
const dropdownItems = [[{
|
||||
label: 'Mark as unread',
|
||||
icon: 'i-heroicons-check-circle'
|
||||
}, {
|
||||
label: 'Mark as important',
|
||||
icon: 'i-heroicons-exclamation-circle'
|
||||
}], [{
|
||||
label: 'Star thread',
|
||||
icon: 'i-heroicons-star'
|
||||
}, {
|
||||
label: 'Mute thread',
|
||||
icon: 'i-heroicons-pause-circle'
|
||||
}]]
|
||||
|
||||
// Filter mails based on the selected tab
|
||||
const filteredMails = computed(() => {
|
||||
if (selectedTab.value === 1) {
|
||||
return mails.value.filter(mail => !!mail.unread)
|
||||
} else {
|
||||
return mails.value
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
|
||||
const selectedMail = ref(null)
|
||||
|
||||
const isMailPanelOpen = computed({
|
||||
get () {
|
||||
return !!selectedMail.value
|
||||
},
|
||||
set (value) {
|
||||
if (!value) {
|
||||
selectedMail.value = null
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
</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>-->
|
||||
|
||||
<UDashboardPanel id="inbox" :width="400" :resizable="{ min: 300, max: 500 }">
|
||||
<UDashboardNavbar title="Inbox" >
|
||||
<template #right>
|
||||
<UTabs v-model="selectedTab" :items="[{label: 'Alle'},{label: 'Ungelesen'}]" :ui="{ wrapper: '', list: { height: 'h-9', tab: { height: 'h-7', size: 'text-[13px]' } } }" />
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
|
||||
<!-- ~/components/inbox/InboxList.vue -->
|
||||
<InboxList v-model="selectedMail" :mails="filteredMails" />
|
||||
</UDashboardPanel>
|
||||
|
||||
<UDashboardPanel v-model="isMailPanelOpen" collapsible grow side="right">
|
||||
<template v-if="selectedMail">
|
||||
<UDashboardNavbar>
|
||||
<template #toggle>
|
||||
<UDashboardNavbarToggle icon="i-heroicons-x-mark" />
|
||||
|
||||
<UDivider orientation="vertical" class="mx-1.5 lg:hidden" />
|
||||
</template>
|
||||
|
||||
<template #left>
|
||||
<UTooltip text="Archive">
|
||||
<UButton icon="i-heroicons-archive-box" color="gray" variant="ghost" />
|
||||
</UTooltip>
|
||||
|
||||
<UTooltip text="Move to junk">
|
||||
<UButton icon="i-heroicons-archive-box-x-mark" color="gray" variant="ghost" />
|
||||
</UTooltip>
|
||||
|
||||
<!-- <UDivider orientation="vertical" class="mx-1.5" />-->
|
||||
|
||||
<!-- <UPopover :popper="{ placement: 'bottom-start' }">
|
||||
<template #default="{ open }">
|
||||
<UTooltip text="Snooze" :prevent="open">
|
||||
<UButton icon="i-heroicons-clock" color="gray" variant="ghost" :class="[open && 'bg-gray-50 dark:bg-gray-800']" />
|
||||
</UTooltip>
|
||||
</template>
|
||||
|
||||
<template #panel="{ close }">
|
||||
<DatePicker @close="close" />
|
||||
</template>
|
||||
</UPopover>-->
|
||||
</template>
|
||||
|
||||
<template #right>
|
||||
<UTooltip text="Reply">
|
||||
<UButton icon="i-heroicons-arrow-uturn-left" color="gray" variant="ghost" />
|
||||
</UTooltip>
|
||||
|
||||
<UTooltip text="Forward">
|
||||
<UButton icon="i-heroicons-arrow-uturn-right" color="gray" variant="ghost" />
|
||||
</UTooltip>
|
||||
|
||||
<UDivider orientation="vertical" class="mx-1.5" />
|
||||
|
||||
<UDropdown :items="dropdownItems">
|
||||
<UButton icon="i-heroicons-ellipsis-vertical" color="gray" variant="ghost" />
|
||||
</UDropdown>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
|
||||
<!-- ~/components/inbox/InboxMail.vue -->
|
||||
<InboxMail :mail="selectedMail" />
|
||||
</template>
|
||||
<div v-else class="flex-1 hidden lg:flex items-center justify-center">
|
||||
<UIcon name="i-heroicons-inbox" class="w-32 h-32 text-gray-400 dark:text-gray-500" />
|
||||
</div>
|
||||
</UDashboardPanel>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
525
deprecated/entitys/contracts/[mode]/[[id]].vue
Normal file
525
deprecated/entitys/contracts/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,525 @@
|
||||
<script setup>
|
||||
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||
import dayjs from "dayjs";
|
||||
import {useSupabaseSelectSingle} from "~/composables/useSupabase.js";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/contracts")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const profileStore = useProfileStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
const openTab = ref(0)
|
||||
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({
|
||||
name: "",
|
||||
customer: null,
|
||||
active: true,
|
||||
ownFields: {}
|
||||
})
|
||||
|
||||
//Functions
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show" ){
|
||||
itemInfo.value = await useSupabaseSelectSingle("contracts", route.params.id, "*, customer(id,name,isCompany, customerNumber), contact(id,fullName)")
|
||||
} else if (mode.value === "edit"){
|
||||
itemInfo.value = await useSupabaseSelectSingle("contracts", route.params.id, "*")
|
||||
}
|
||||
|
||||
|
||||
if(mode.value === "create") {
|
||||
let query = route.query
|
||||
|
||||
if(query.customer) itemInfo.value.customer = Number(query.customer)
|
||||
}
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(itemInfo.value) {
|
||||
router.push(`/contracts/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/contracts/`)
|
||||
}
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar :title="itemInfo ? itemInfo.name : (mode === 'create' ? 'Vertrag erstellen' : 'Vertrag bearbeiten')">
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/contracts`)"
|
||||
>
|
||||
Verträge
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
:class="['text-xl','font-medium', ... itemInfo.active ? ['text-primary'] : ['text-rose-500']]"
|
||||
>{{itemInfo ? `Vertrag: ${itemInfo.name}` : (mode === 'create' ? 'Vertrag erstellen' : 'Vertrag bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@click="dataStore.updateItem('contracts',itemInfo)"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else-if="mode === 'create'"
|
||||
@click="dataStore.createNewItem('contracts',itemInfo)"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="cancelEditorCreate"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click="router.push(`/contracts/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UDashboardPanelContent>
|
||||
<UTabs
|
||||
v-if="itemInfo.id && mode === 'show'"
|
||||
:items="[{label: 'Informationen'}, {label: 'Dokumente'}]"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<div v-if="item.label === 'Informationen'" class="flex mt-5">
|
||||
<div class="w-1/2 mr-5">
|
||||
<UCard>
|
||||
<div class="text-wrap">
|
||||
<table class="mb-3">
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td>{{itemInfo.name}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Aktiv:</td>
|
||||
<td>
|
||||
<span v-if="itemInfo.active" class="text-primary-500">Ja</span>
|
||||
<span v-else class="text-rose-600">Nein</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Kunde:</td>
|
||||
<td>
|
||||
<nuxt-link
|
||||
:to="`/customers/show/${itemInfo.customer.id}`"
|
||||
v-if="itemInfo.customer"
|
||||
>{{itemInfo.customer.customerNumber ? `${itemInfo.customer.customerNumber} - ` : ''}}{{itemInfo.customer ? itemInfo.customer.name : ""}}</nuxt-link>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="itemInfo.customer.isCompany">
|
||||
<td>Ansprechpartner:</td>
|
||||
<td>
|
||||
<nuxt-link
|
||||
v-if="itemInfo.contact"
|
||||
:to="`/contacts/show/${itemInfo.contact.id}`"
|
||||
>{{itemInfo.contact ? itemInfo.contact.fullName : ""}}</nuxt-link>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Wiederkehrend:</td>
|
||||
<td>{{itemInfo.recurring ? "Ja" : "Nein"}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Startdatum:</td>
|
||||
<td>{{dayjs(itemInfo.startDate).format("DD.MM.YYYY")}}</td>
|
||||
</tr>
|
||||
<tr v-if="!itemInfo.active">
|
||||
<td>Enddatum:</td>
|
||||
<td>{{dayjs(itemInfo.endDate).format("DD.MM.YYYY")}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Unterschrieben am:</td>
|
||||
<td>{{dayjs(itemInfo.signDate).format("DD.MM.YYYY")}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Laufzeit:</td>
|
||||
<td>{{itemInfo.duration}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Rechnungsversand:</td>
|
||||
<td>{{itemInfo.invoiceDispatch}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Zahlart:</td>
|
||||
<td>{{itemInfo.paymentType}}</td>
|
||||
</tr>
|
||||
<tr v-if="itemInfo.paymentType === 'Einzug'">
|
||||
<td>SEPA Mandatsreferenz:</td>
|
||||
<td>{{itemInfo.sepaRef}}</td>
|
||||
</tr>
|
||||
<tr v-if="itemInfo.paymentType === 'Einzug'">
|
||||
<td>SEPA Unterschrieben am:</td>
|
||||
<td>{{dayjs(itemInfo.sepaDate).format("DD.MM.YYYY")}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Bank:</td>
|
||||
<td>{{itemInfo.bankingName}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>BIC:</td>
|
||||
<td>{{itemInfo.bankingBIC}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IBAN:</td>
|
||||
<td>{{itemInfo.bankingIban}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Kontoinhaber:</td>
|
||||
<td>{{itemInfo.bankingOwner}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Beschreibung:</td>
|
||||
<td>{{itemInfo.notes}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><span class="font-bold">Eigene Felder:</span></td>
|
||||
</tr>
|
||||
<tr v-for="fieldKey in Object.keys(itemInfo.ownFields)">
|
||||
<td>{{profileStore.ownTenant.ownFields.contracts.find(i => i.key === fieldKey).label}}</td>
|
||||
<td>{{itemInfo.ownFields[fieldKey]}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</UCard>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<UCard class="h-full">
|
||||
<HistoryDisplay
|
||||
type="contract"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
:render-headline="true"
|
||||
/>
|
||||
</UCard>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- <UBadge
|
||||
v-if="itemInfo.active"
|
||||
>
|
||||
Vertrag aktiv
|
||||
</UBadge>
|
||||
<UBadge
|
||||
v-else
|
||||
color="red"
|
||||
>
|
||||
Vertrag gesperrt
|
||||
</UBadge>-->
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Dokumente'">
|
||||
<UCard class="mt-5">
|
||||
<Toolbar>
|
||||
<DocumentUpload
|
||||
type="contract"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</Toolbar>
|
||||
<DocumentList
|
||||
:documents="dataStore.getDocumentsByContractId(itemInfo.id)"
|
||||
/>
|
||||
</UCard>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
</UTabs>
|
||||
<UForm v-else-if="mode == 'edit' || mode == 'create'" class="p-5" >
|
||||
<div class="mx-auto w-4/5">
|
||||
<div class="flex flex-row justify-around">
|
||||
<div class="w-1/2">
|
||||
<UDivider>Vertragsdaten</UDivider>
|
||||
<UFormGroup
|
||||
label="Name:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.name"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Kunde:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.customer"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
:options="dataStore.customers"
|
||||
@change="itemInfo.contact = null"
|
||||
searchable
|
||||
:search-attributes="['name']"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.getCustomerById(itemInfo.customer) ? dataStore.getCustomerById(itemInfo.customer).name : "Kein Kunde ausgewählt" }}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Ansprechpartner:"
|
||||
v-if="itemInfo.customer"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.contact"
|
||||
option-attribute="fullName"
|
||||
value-attribute="id"
|
||||
:options="dataStore.getContactsByCustomerId(itemInfo.customer)"
|
||||
searchable
|
||||
:search-attributes="['name']"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.getContactById(itemInfo.contact) ? dataStore.getContactById(itemInfo.contact).fullName : "Kein Ansprechpartner ausgewählt" }}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
|
||||
<InputGroup>
|
||||
<UFormGroup
|
||||
label="Vertrag aktiv:"
|
||||
>
|
||||
<UCheckbox
|
||||
v-model="itemInfo.active"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Vertrag wiederkehrend:"
|
||||
>
|
||||
<UCheckbox
|
||||
v-model="itemInfo.recurring"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</InputGroup>
|
||||
|
||||
|
||||
<InputGroup>
|
||||
<UFormGroup
|
||||
label="Vertragsstart:"
|
||||
class="mt-2"
|
||||
>
|
||||
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Vertragsende(voraussichtlich):"
|
||||
class="mt-2"
|
||||
>
|
||||
<UPopover :popper="{ placement: 'bottom-start' }">
|
||||
<UButton
|
||||
icon="i-heroicons-calendar-days-20-solid"
|
||||
:label="itemInfo.endDate ? dayjs(itemInfo.endDate).format('DD.MM.YYYY') : 'Datum auswählen'"
|
||||
variant="outline"
|
||||
/>
|
||||
|
||||
<template #panel="{ close }">
|
||||
<LazyDatePicker v-model="itemInfo.endDate" @close="close" />
|
||||
</template>
|
||||
</UPopover>
|
||||
</UFormGroup>
|
||||
</InputGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="mindest Vertragslaufzeit:"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="['12 Monate','24 Monate','36 Monate','48 Monate']"
|
||||
v-model="itemInfo.duration"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Datum der Unterzeichnung:"
|
||||
class="mt-2"
|
||||
>
|
||||
<UPopover :popper="{ placement: 'bottom-start' }">
|
||||
<UButton
|
||||
icon="i-heroicons-calendar-days-20-solid"
|
||||
:label="itemInfo.signDate ? dayjs(itemInfo.signDate).format('DD.MM.YYYY') : 'Datum auswählen'"
|
||||
variant="outline"
|
||||
/>
|
||||
|
||||
<template #panel="{ close }">
|
||||
<LazyDatePicker v-model="itemInfo.signDate" @close="close" />
|
||||
</template>
|
||||
</UPopover>
|
||||
</UFormGroup>
|
||||
</div>
|
||||
<div class=" ml-5 w-1/2">
|
||||
<UDivider>Abrechnung</UDivider>
|
||||
<UFormGroup
|
||||
label="Rechnungsversand:"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="['E-Mail', 'Post']"
|
||||
v-model="itemInfo.invoiceDispatch"
|
||||
>
|
||||
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Zahlungsart:"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="['Einzug', 'Überweisung']"
|
||||
v-model="itemInfo.paymentType"
|
||||
>
|
||||
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Sepa Mandat"
|
||||
>
|
||||
<InputGroup>
|
||||
<UPopover :popper="{ placement: 'bottom-start' }">
|
||||
<UButton
|
||||
icon="i-heroicons-calendar-days-20-solid"
|
||||
:label="itemInfo.sepaDate ? dayjs(itemInfo.sepaDate).format('DD.MM.YYYY') : 'Datum auswählen'"
|
||||
variant="outline"
|
||||
/>
|
||||
|
||||
<template #panel="{ close }">
|
||||
<LazyDatePicker v-model="itemInfo.sepaDate" @close="close" />
|
||||
</template>
|
||||
</UPopover>
|
||||
<UInput
|
||||
placeholder="Mandatsreferenz"
|
||||
class="flex-auto"
|
||||
v-model="itemInfo.sepaRef"
|
||||
/>
|
||||
</InputGroup>
|
||||
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Kontodaten:"
|
||||
>
|
||||
<InputGroup>
|
||||
<UInput
|
||||
v-model="itemInfo.bankingIban"
|
||||
placeholder="IBAN"
|
||||
class="w-1/2"
|
||||
/>
|
||||
<UInput
|
||||
v-model="itemInfo.bankingOwner"
|
||||
class="w-1/2"
|
||||
placeholder="Inhaber"
|
||||
/>
|
||||
</InputGroup>
|
||||
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Bankdaten:"
|
||||
>
|
||||
<InputGroup>
|
||||
<UInput
|
||||
v-model="itemInfo.bankingName"
|
||||
placeholder="Name"
|
||||
class="w-1/2"
|
||||
/>
|
||||
<UInput
|
||||
v-model="itemInfo.bankingBIC"
|
||||
placeholder="BIC"
|
||||
class="w-1/2"
|
||||
/>
|
||||
</InputGroup>
|
||||
|
||||
</UFormGroup>
|
||||
</div>
|
||||
</div>
|
||||
<UFormGroup
|
||||
label="Notizen:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.notes"
|
||||
rows="6"
|
||||
maxrows="12"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<div
|
||||
v-if="profileStore.ownTenant.ownFields"
|
||||
>
|
||||
<UDivider
|
||||
class="mt-3"
|
||||
>Eigene Felder</UDivider>
|
||||
|
||||
<UFormGroup
|
||||
v-for="field in profileStore.ownTenant.ownFields.contracts"
|
||||
:key="field.key"
|
||||
:label="field.label"
|
||||
>
|
||||
<UInput
|
||||
v-if="field.type === 'text'"
|
||||
v-model="itemInfo.ownFields[field.key]"
|
||||
/>
|
||||
<USelectMenu
|
||||
v-else-if="field.type === 'select'"
|
||||
:options="field.options"
|
||||
v-model="itemInfo.ownFields[field.key]"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</UForm>
|
||||
</UDashboardPanelContent>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
td {
|
||||
border-bottom: 1px solid lightgrey;
|
||||
vertical-align: top;
|
||||
padding-bottom: 0.15em;
|
||||
padding-top: 0.15em;
|
||||
}
|
||||
</style>
|
||||
23
deprecated/entitys/contracts/index.vue
Normal file
23
deprecated/entitys/contracts/index.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<EntityList
|
||||
:items="items"
|
||||
type="contracts"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
const items = ref([])
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("contracts","*, customer(id,name)")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
369
deprecated/entitys/customers/[mode]/[[id]].vue
Normal file
369
deprecated/entitys/customers/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,369 @@
|
||||
<script setup>
|
||||
|
||||
import {useSupabaseSelectSingle} from "~/composables/useSupabase.js";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/customers")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const profileStore = useProfileStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const openTab = ref(0)
|
||||
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({
|
||||
name: "",
|
||||
infoData: {
|
||||
country: "Deutschland"
|
||||
},
|
||||
active: true,
|
||||
isCompany: true,
|
||||
profiles: [profileStore.activeProfile.id]
|
||||
})
|
||||
const oldItemInfo = ref({})
|
||||
|
||||
//Functions
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show"){
|
||||
itemInfo.value = await useSupabaseSelectSingle("customers",route.params.id,"*, contacts(*)")
|
||||
} else if(mode.value === "edit") {
|
||||
itemInfo.value = await useSupabaseSelectSingle("customers",route.params.id,"*")
|
||||
}
|
||||
|
||||
if(itemInfo.value) oldItemInfo.value = JSON.parse(JSON.stringify(itemInfo.value))
|
||||
}
|
||||
|
||||
const editItem = async () => {
|
||||
await router.push(`/customers/edit/${itemInfo.value.id}`)
|
||||
}
|
||||
|
||||
const setCityByZip = async () => {
|
||||
itemInfo.value.infoData.city = await useZipCheck(itemInfo.value.infoData.zip)
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar
|
||||
:title="itemInfo ? `Kunde: ${itemInfo.name}` : (mode === 'create' ? 'Kunde erstellen' : 'Kunde bearbeiten')"
|
||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||
>
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/customers`)"
|
||||
>
|
||||
Kunden
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
:class="['text-xl','font-medium', ... itemInfo.active ? ['text-primary'] : ['text-rose-500']]"
|
||||
>{{itemInfo.id ? `Kunde: ${itemInfo.name}` : (mode === 'create' ? 'Kunde erstellen' : 'Kunde bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@click="dataStore.updateItem('customers',itemInfo,oldItemInfo)"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else-if="mode === 'create'"
|
||||
@click="dataStore.createNewItem('customers',itemInfo)"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="itemInfo.id ? router.push(`/customers/show/${itemInfo.id}`) : router.push(`/customers`)"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click="editItem"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
<template #badge v-if="itemInfo">
|
||||
<UBadge
|
||||
v-if="itemInfo.active"
|
||||
>
|
||||
Aktiv
|
||||
</UBadge>
|
||||
<UBadge
|
||||
v-else
|
||||
color="red"
|
||||
>
|
||||
Gesperrt
|
||||
</UBadge>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
|
||||
<UDashboardPanelContent>
|
||||
<UTabs
|
||||
v-if="itemInfo.id && mode == 'show'"
|
||||
:items="[{label: 'Informationen'},{label: 'Projekte'},{label: 'Objekte'},{label: 'Verträge'}]"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<div v-if="item.label === 'Informationen'" class="flex mt-5">
|
||||
<div class="w-1/2 mr-5">
|
||||
<UCard >
|
||||
<div class="text-wrap">
|
||||
<p>Kundennummer: {{itemInfo.customerNumber}}</p>
|
||||
<p>Typ: {{itemInfo.isCompany ? 'Firma' : 'Privatperson'}}</p>
|
||||
<p v-if="itemInfo.infoData.street">Straße + Hausnummer: {{itemInfo.infoData.street}}</p>
|
||||
<p v-if="itemInfo.infoData.zip && itemInfo.infoData.city">PLZ + Ort: {{itemInfo.infoData.zip}} {{itemInfo.infoData.city}}</p>
|
||||
<p v-if="itemInfo.infoData.tel">Telefon: {{itemInfo.infoData.tel}}</p>
|
||||
<p v-if="itemInfo.infoData.email">E-Mail: {{itemInfo.infoData.email}}</p>
|
||||
<p v-if="itemInfo.infoData.web">Web: {{itemInfo.infoData.web}}</p>
|
||||
<p v-if="itemInfo.infoData.ustid">USt-Id: {{itemInfo.infoData.ustid}}</p>
|
||||
<p>Notizen:<br> {{itemInfo.notes}}</p>
|
||||
</div>
|
||||
|
||||
</UCard>
|
||||
<UCard class="mt-5">
|
||||
<Toolbar>
|
||||
<UButton
|
||||
@click="router.push(`/contacts/create?customer=${itemInfo.id}`)"
|
||||
>
|
||||
+ Ansprechpartner
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
<UTable
|
||||
:rows="dataStore.getContactsByCustomerId(itemInfo.id)"
|
||||
@select="(row) => router.push(`/contacts/show/${row.id}`)"
|
||||
:columns="[{label: 'Anrede', key: 'salutation'},{label: 'Name', key: 'fullName'},{label: 'Rolle', key: 'role'}]"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Ansprechpartner' }"
|
||||
|
||||
>
|
||||
|
||||
</UTable>
|
||||
</UCard>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<UCard class="h-full">
|
||||
<HistoryDisplay
|
||||
type="customer"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
:render-headline="true"
|
||||
/>
|
||||
</UCard>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<UCard class="mt-5" v-else>
|
||||
|
||||
<div v-if="item.label === 'Projekte'">
|
||||
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Objekte'">
|
||||
<Toolbar>
|
||||
<UButton
|
||||
@click="router.push(`/plants/create?customer=${itemInfo.id}`)"
|
||||
>
|
||||
+ Objekt
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
<UTable
|
||||
:rows="dataStore.getPlantsByCustomerId(itemInfo.id)"
|
||||
@select="(row) => router.push(`/plants/show/${row.id}`)"
|
||||
:columns="[{label: 'Name', key: 'name'}]"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Objekte' }"
|
||||
|
||||
>
|
||||
|
||||
</UTable>
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Verträge'">
|
||||
<Toolbar>
|
||||
<UButton
|
||||
@click="router.push(`/contracts/create?customer=${itemInfo.id}`)"
|
||||
>
|
||||
+ Vertrag
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
<UTable
|
||||
:rows="dataStore.getContractsByCustomerId(itemInfo.id)"
|
||||
@select="(row) => router.push(`/contracts/show/${row.id}`)"
|
||||
:columns="[{label: 'Name', key: 'name'},{label: 'Aktiv', key: 'active'}]"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Verträge' }"
|
||||
|
||||
>
|
||||
|
||||
</UTable>
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
</template>
|
||||
</UTabs>
|
||||
<UForm v-else-if="mode === 'edit' || mode === 'create'" class="p-5">
|
||||
<UFormGroup
|
||||
label="Name:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.name"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Kundennummer:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.customerNumber"
|
||||
placeholder="Leer lassen für automatisch generierte Nummer"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UTooltip text="Ist ein Kunde nicht aktiv so wird er für neue Aufträge gesperrt">
|
||||
<UFormGroup
|
||||
label="Kunde aktiv:"
|
||||
>
|
||||
<UCheckbox
|
||||
v-model="itemInfo.active"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</UTooltip>
|
||||
<UFormGroup
|
||||
label="Firmenkunde:"
|
||||
>
|
||||
<UCheckbox
|
||||
v-model="itemInfo.isCompany"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Notizen:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.notes"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Straße + Hausnummer"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.infoData.street"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Adresszusatz"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.infoData.special"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Postleitzahl"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.infoData.zip"
|
||||
@focusout="setCityByZip"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Ort"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.infoData.city"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Land"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="['Deutschland','Niederlande','Belgien','Italien', 'Frankreich','Irland','USA','Spanien', 'Schweden']"
|
||||
v-model="itemInfo.infoData.country"
|
||||
/>
|
||||
</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>
|
||||
<UFormGroup
|
||||
label="Berechtigte Benutzer:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.profiles"
|
||||
:options="profileStore.profiles"
|
||||
option-attribute="fullName"
|
||||
value-attribute="id"
|
||||
searchable
|
||||
multiple
|
||||
:search-attributes="['fullName']"
|
||||
>
|
||||
<template #label>
|
||||
{{itemInfo.profiles.length > 0 ? itemInfo.profiles.map(i => profileStore.getProfileById(i).fullName).join(", ") : "Kein Benutzer ausgewählt"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
</UForm>
|
||||
</UDashboardPanelContent>
|
||||
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
26
deprecated/entitys/customers/index.vue
Normal file
26
deprecated/entitys/customers/index.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<EntityList
|
||||
type="customers"
|
||||
:items="items"
|
||||
></EntityList>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import EntityList from "~/components/EntityList.vue";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
const items = ref([])
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("customers",null,"customerNumber")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
252
deprecated/entitys/plants/[mode]/[[id]].vue
Normal file
252
deprecated/entitys/plants/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,252 @@
|
||||
<script setup>
|
||||
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||
import DocumentList from "~/components/DocumentList.vue";
|
||||
import DocumentUpload from "~/components/DocumentUpload.vue";
|
||||
import Toolbar from "~/components/Toolbar.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 )
|
||||
|
||||
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({
|
||||
})
|
||||
|
||||
const tabItems = [
|
||||
{
|
||||
label: "Informationen"
|
||||
},{
|
||||
label: "Projekte"
|
||||
},{
|
||||
label: "Aufgaben"
|
||||
},{
|
||||
label: "Dokumente"
|
||||
}
|
||||
]
|
||||
|
||||
//Functions
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show"){
|
||||
itemInfo.value = (await supabase.from("plants").select("*, customer(*)").eq("id",useRoute().params.id).single()).data
|
||||
} else if(mode.value === "edit") {
|
||||
itemInfo.value = (await supabase.from("plants").select().eq("id",useRoute().params.id).single()).data
|
||||
}
|
||||
|
||||
if(mode.value === "create") {
|
||||
let query = route.query
|
||||
if(query.customer) itemInfo.value.customer = Number(query.customer)
|
||||
}
|
||||
}
|
||||
|
||||
const contentChanged = (content) => {
|
||||
itemInfo.value.description.html = content.html
|
||||
itemInfo.value.description.text = content.text
|
||||
itemInfo.value.description.json = content.json
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar :title="itemInfo ? itemInfo.name : (mode === 'create' ? 'Objekt erstellen' : 'Objekt bearbeiten')">
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/plants`)"
|
||||
>
|
||||
Objekte
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
:class="['text-xl','font-medium']"
|
||||
>{{itemInfo ? `Objekt: ${itemInfo.name}` : (mode === 'create' ? 'Objekt erstellen' : 'Objekt bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<ButtonWithConfirm
|
||||
color="rose"
|
||||
variant="outline"
|
||||
@confirmed="dataStore.updateItem('plants',{...itemInfo, archived: true})"
|
||||
v-if="mode === 'edit'"
|
||||
>
|
||||
<template #button>
|
||||
Archivieren
|
||||
</template>
|
||||
<template #header>
|
||||
<span class="text-md text-black font-bold">Archivieren bestätigen</span>
|
||||
</template>
|
||||
Möchten Sie das Objekt {{itemInfo.name}} wirklich archivieren?
|
||||
</ButtonWithConfirm>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@click="dataStore.updateItem('plants',itemInfo)"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else-if="mode === 'create'"
|
||||
@click="dataStore.createNewItem('plants',itemInfo)"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="router.push(itemInfo.id ? `/plants/show/${itemInfo.id}` : `/plants/`)"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click="router.push(`/plants/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
:items="tabItems"
|
||||
v-if="mode === 'show'"
|
||||
class="p-5"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<div v-if="item.label === 'Informationen'" class="flex flex-row mt-5">
|
||||
<UCard class="w-1/2 mr-5">
|
||||
<UAlert
|
||||
v-if="itemInfo.archived"
|
||||
color="rose"
|
||||
variant="outline"
|
||||
title="Objekt archiviert"
|
||||
icon="i-heroicons-light-bulb"
|
||||
class="mb-5"
|
||||
/>
|
||||
<div class="text-wrap">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Kunde:</td>
|
||||
<td><nuxt-link v-if="itemInfo.customer" :to="`/customers/show/${itemInfo.customer.id}`">{{itemInfo.customer.name}}</nuxt-link></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div v-if="itemInfo.description">
|
||||
<p>Notizen:</p>
|
||||
<span v-html="itemInfo.description.html"></span>
|
||||
</div>
|
||||
</UCard>
|
||||
<UCard class="w-1/2">
|
||||
<HistoryDisplay
|
||||
type="plant"
|
||||
v-if="itemInfo.id"
|
||||
:element-id="itemInfo.id"
|
||||
render-headline
|
||||
/>
|
||||
</UCard>
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Projekte'">
|
||||
<Toolbar>
|
||||
<UButton
|
||||
@click="router.push(`/projects/create?plant=${itemInfo.id}`)"
|
||||
>
|
||||
+ Projekt
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
|
||||
<UTable
|
||||
:rows="dataStore.getProjectsByPlantId(itemInfo.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=${itemInfo.id}`)"
|
||||
>
|
||||
+ Aufgabe
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
<UTable
|
||||
:rows="dataStore.getTasksByPlantId(itemInfo.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="itemInfo.id"
|
||||
/>
|
||||
</Toolbar>
|
||||
|
||||
<DocumentList :documents="dataStore.getDocumentsByPlantId(itemInfo.id)"/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
</UTabs>
|
||||
|
||||
|
||||
<UForm
|
||||
v-else-if="mode === 'edit' || mode === 'create'"
|
||||
class="p-5"
|
||||
>
|
||||
<UFormGroup
|
||||
label="Name:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.name"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Kundennummer:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.customer"
|
||||
:options="dataStore.customers"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
searchable
|
||||
: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="Notizen:"
|
||||
>
|
||||
<Tiptap
|
||||
v-if="itemInfo.description"
|
||||
@updateContent="contentChanged"
|
||||
:preloadedContent="itemInfo.description.html"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
</UForm>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
24
deprecated/entitys/plants/index.vue
Normal file
24
deprecated/entitys/plants/index.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<EntityList
|
||||
:items="items"
|
||||
type="plants"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
const items = ref([])
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("plants","*, customer(id,name)")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
179
deprecated/entitys/productcategories/[mode]/[[id]].vue
Normal file
179
deprecated/entitys/productcategories/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,179 @@
|
||||
<script setup>
|
||||
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||
import DocumentList from "~/components/DocumentList.vue";
|
||||
import DocumentUpload from "~/components/DocumentUpload.vue";
|
||||
import {useSupabaseSelect} from "~/composables/useSupabase.js";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/productcategories")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({})
|
||||
const openTab = ref(0)
|
||||
|
||||
//Functions
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show" || mode.value === "edit"){
|
||||
itemInfo.value = await useSupabaseSelectSingle("productcategories",route.params.id,"*")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(itemInfo.value) {
|
||||
router.push(`/productcategories/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/productcategories/`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar
|
||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||
>
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/productcategories`)"
|
||||
>
|
||||
Artikelkategorien
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
class="text-xl font-medium"
|
||||
>{{itemInfo.name ? `Artikelkategorie: ${itemInfo.name}` : (mode === 'create' ? 'Artikelkategorie erstellen' : 'Artikelkategorie bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@click="dataStore.updateItem('productcategories',itemInfo)"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else-if="mode === 'create'"
|
||||
@click="dataStore.createNewItem('productcategories',itemInfo)"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="cancelEditorCreate"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click=" router.push(`/productcategories/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
:items="[{label: 'Informationen'}]"
|
||||
v-if="mode === 'show' && itemInfo"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<div v-if="item.label === 'Informationen'" class="mr-5 flex flex-row">
|
||||
<div class="w-1/2 mr-5">
|
||||
<UCard>
|
||||
<table class="w-full">
|
||||
<tr>
|
||||
<td>Name: </td>
|
||||
<td>{{itemInfo.name}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Beschreibung:</td>
|
||||
<td>{{itemInfo.description}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</UCard>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<UCard>
|
||||
<HistoryDisplay
|
||||
type="product"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
render-headline
|
||||
/>
|
||||
</UCard>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
</UTabs>
|
||||
<UForm
|
||||
v-else-if="mode == 'edit' || mode == 'create'"
|
||||
class="p-5"
|
||||
>
|
||||
<UFormGroup
|
||||
label="Name:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.name"
|
||||
autofocus
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Beschreibung:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.description"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</UForm>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
td {
|
||||
border-bottom: 1px solid lightgrey;
|
||||
vertical-align: top;
|
||||
padding-bottom: 0.15em;
|
||||
padding-top: 0.15em;
|
||||
}
|
||||
</style>
|
||||
24
deprecated/entitys/productcategories/index.vue
Normal file
24
deprecated/entitys/productcategories/index.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<EntityList
|
||||
:items="items"
|
||||
type="productcategories"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
const items = ref([])
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("productcategories","*")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
354
deprecated/entitys/products/[mode]/[[id]].vue
Normal file
354
deprecated/entitys/products/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,354 @@
|
||||
<script setup>
|
||||
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||
import DocumentList from "~/components/DocumentList.vue";
|
||||
import DocumentUpload from "~/components/DocumentUpload.vue";
|
||||
import {useSupabaseSelect} from "~/composables/useSupabase.js";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/products")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const profileStore = useProfileStore()
|
||||
const supabase = useSupabaseClient()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({
|
||||
unit: 1,
|
||||
tags: [],
|
||||
productcategories: []
|
||||
})
|
||||
const openTab = ref(0)
|
||||
|
||||
const productcategories = ref([])
|
||||
const units = ref([])
|
||||
|
||||
//Functions
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show" || mode.value === "edit"){
|
||||
itemInfo.value = await useSupabaseSelectSingle("products",route.params.id,"*")
|
||||
}
|
||||
|
||||
productcategories.value = await useSupabaseSelect("productcategories","*")
|
||||
units.value = (await supabase.from("units").select()).data
|
||||
console.log(units.value[0])
|
||||
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(itemInfo.value) {
|
||||
router.push(`/products/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/products/`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const printLabel = async (content) => {
|
||||
const label = await useSupabaseSelectSingle("printLabels",1,'*')
|
||||
|
||||
|
||||
usePrintLabel('0dbe30f3-3008-4cde-8a7c-e785b1c22bfc','ZD411',useGenerateZPL(label.handlebarsZPL,{barcode:itemInfo.value.articleNumber }))
|
||||
|
||||
}
|
||||
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar
|
||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||
>
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/products`)"
|
||||
>
|
||||
Artikel
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
class="text-xl font-medium"
|
||||
>{{itemInfo.name ? `Artikel: ${itemInfo.name}` : (mode === 'create' ? 'Artikel erstellen' : 'Artikel bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@click="dataStore.updateItem('products',itemInfo)"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else-if="mode === 'create'"
|
||||
@click="dataStore.createNewItem('products',itemInfo)"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="cancelEditorCreate"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click=" router.push(`/products/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
:items="[{label: 'Informationen'},{label: 'Bestand'},{label: 'Dokumente'}]"
|
||||
v-if="mode === 'show' && itemInfo"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<div v-if="item.label === 'Informationen'" class="mt-5 flex flex-row">
|
||||
<div class="w-1/2 mr-5">
|
||||
<UCard>
|
||||
<UBadge
|
||||
v-for="tag in itemInfo.tags"
|
||||
class="mr-2"
|
||||
|
||||
>
|
||||
{{tag}}
|
||||
</UBadge>
|
||||
<UDivider
|
||||
class="my-2"
|
||||
/>
|
||||
|
||||
<!--
|
||||
<UButton @click="printLabel(itemInfo.ean)">Print Label</UButton>
|
||||
-->
|
||||
|
||||
<table class="w-full">
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td>{{itemInfo.name}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Hersteller:</td>
|
||||
<td>{{itemInfo.manufacturer}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Herstellernummer:</td>
|
||||
<td>{{itemInfo.manufacturerNumber}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Einheit:</td>
|
||||
<td>{{units.find(i => i.id === itemInfo.unit) ? units.find(i => i.id === itemInfo.unit).name : ""}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tags:</td>
|
||||
<td>{{itemInfo.tags.join(", ")}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Artikelkategorien:</td>
|
||||
<td>{{itemInfo.productcategories.map(i => productcategories.find(x => x.id === i).name).join(", ")}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>EAN:</td>
|
||||
<td>{{itemInfo.ean}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Verkaufspreis:</td>
|
||||
<td>{{itemInfo.sellingPrice}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Beschreibung:</td>
|
||||
<td>{{itemInfo.description}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</UCard>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<UCard>
|
||||
<HistoryDisplay
|
||||
type="product"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
render-headline
|
||||
/>
|
||||
</UCard>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="item.label === 'Bestand'"
|
||||
>
|
||||
<UCard class="mt-5">
|
||||
Bestand: {{dataStore.getStockByProductId(itemInfo.id)}} {{dataStore.units.find(unit => unit.id === itemInfo.unit) ? dataStore.units.find(unit => unit.id === itemInfo.unit).name : ""}}
|
||||
</UCard>
|
||||
</div>
|
||||
<div
|
||||
v-if="item.label === 'Dokumente'"
|
||||
>
|
||||
<UCard class="mt-5">
|
||||
<Toolbar>
|
||||
<DocumentUpload
|
||||
type="product"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</Toolbar>
|
||||
|
||||
|
||||
<DocumentList :documents="dataStore.getDocumentsByProductId(itemInfo.id)"/>
|
||||
</UCard>
|
||||
</div>
|
||||
</template>
|
||||
</UTabs>
|
||||
<UForm
|
||||
v-else-if="mode == 'edit' || mode == 'create'"
|
||||
class="p-5"
|
||||
>
|
||||
<UFormGroup
|
||||
label="Name:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.name"
|
||||
autofocus
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Hersteller:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.manufacturer"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Hersteller Nr.:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.manufacturerNumber"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Einheit:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.unit"
|
||||
:options="dataStore.units"
|
||||
option-attribute="name"
|
||||
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
|
||||
v-model="itemInfo.tags"
|
||||
:options="profileStore.ownTenant.tags.products"
|
||||
multiple
|
||||
>
|
||||
<template #label>
|
||||
{{itemInfo.tags.length > 0 ? itemInfo.tags.join(", ") : "Keine Tags ausgewählt"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Artikelkategorien:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.productcategories"
|
||||
:options="productcategories"
|
||||
value-attribute="id"
|
||||
option-attribute="name"
|
||||
multiple
|
||||
>
|
||||
<template #label>
|
||||
{{itemInfo.productcategories.length > 0 ? itemInfo.productcategories.map(i => productcategories.find(x => x.id === i).name).join(", ") : "Keine Kategorien ausgewählt"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
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"
|
||||
>
|
||||
<template #trailing>
|
||||
<span class="text-gray-500 dark:text-gray-400 text-xs">EUR</span>
|
||||
</template>
|
||||
</UInput>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Verkaufspreis:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.sellingPrice"
|
||||
type="number"
|
||||
steps="0.01"
|
||||
>
|
||||
<template #trailing>
|
||||
<span class="text-gray-500 dark:text-gray-400 text-xs">EUR</span>
|
||||
</template>
|
||||
</UInput>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Beschreibung:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.description"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</UForm>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
td {
|
||||
border-bottom: 1px solid lightgrey;
|
||||
vertical-align: top;
|
||||
padding-bottom: 0.15em;
|
||||
padding-top: 0.15em;
|
||||
}
|
||||
</style>
|
||||
27
deprecated/entitys/products/index.vue
Normal file
27
deprecated/entitys/products/index.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<EntityList
|
||||
:items="items"
|
||||
type="products"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
const items = ref([])
|
||||
const productcategories = ref([])
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("products","*, unit(name)")
|
||||
productcategories.value = await useSupabaseSelect("productcategories", "*")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
674
deprecated/entitys/projects/[mode]/[[id]].vue
Normal file
674
deprecated/entitys/projects/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,674 @@
|
||||
<script setup>
|
||||
import dayjs from "dayjs";
|
||||
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/projects")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const profileStore = useProfileStore()
|
||||
const supabase = useSupabaseClient()
|
||||
const user = useSupabaseUser()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
|
||||
const openTab = ref(0)
|
||||
|
||||
const tabItems = [
|
||||
{
|
||||
key: "information",
|
||||
label: "Informationen"
|
||||
},
|
||||
{
|
||||
key: "phases",
|
||||
label: "Phasen"
|
||||
},{
|
||||
key: "tasks",
|
||||
label: "Aufgaben"
|
||||
},/*{
|
||||
key: "forms",
|
||||
label: "Formulare"
|
||||
},*/{
|
||||
key: "documents",
|
||||
label: "Dokumente"
|
||||
},{
|
||||
key: "timetracking",
|
||||
label: "Zeiterfassung"
|
||||
},{
|
||||
key: "events",
|
||||
label: "Termine"
|
||||
},{
|
||||
key: "material",
|
||||
label: "Material"
|
||||
}
|
||||
]
|
||||
|
||||
const timeTableRows = [
|
||||
{
|
||||
key:"user",
|
||||
label: "Benutzer"
|
||||
},{
|
||||
key:"start",
|
||||
label: "Start"
|
||||
},{
|
||||
key:"end",
|
||||
label:"Ende"
|
||||
},{
|
||||
key:"duration",
|
||||
label: "Dauer"
|
||||
},{
|
||||
key: "type",
|
||||
label: "Typ"
|
||||
},{
|
||||
key:"notes",
|
||||
label: "Notizen"
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({
|
||||
name: "",
|
||||
customer: 0,
|
||||
profiles: [profileStore.activeProfile.id]
|
||||
})
|
||||
const oldItemInfo = ref({})
|
||||
|
||||
const plants = ref([])
|
||||
const contracts = ref([])
|
||||
const projecttypes = ref([])
|
||||
const disableCustomerSelection =ref(false)
|
||||
|
||||
|
||||
//Functions
|
||||
const setupPage = async() => {
|
||||
plants.value = await useSupabaseSelect("plants")
|
||||
contracts.value = await useSupabaseSelect("contracts")
|
||||
projecttypes.value = await useSupabaseSelect("projecttypes", "*", "id")
|
||||
|
||||
if(mode.value === "show" ){
|
||||
itemInfo.value = await useSupabaseSelectSingle("projects",route.params.id,"*, customer(*), plant(*), createddocuments(*)")
|
||||
} else if (mode.value === "edit") {
|
||||
itemInfo.value = await useSupabaseSelectSingle("projects",route.params.id,"*")
|
||||
}
|
||||
|
||||
if(mode.value === "create") {
|
||||
let query = route.query
|
||||
|
||||
if(query.customer) itemInfo.value.customer = Number(query.customer)
|
||||
|
||||
if(query.plant) {
|
||||
itemInfo.value.plant = Number(query.plant)
|
||||
itemInfo.value.customer = dataStore.getPlantById(itemInfo.value.plant).customer
|
||||
}
|
||||
}
|
||||
if(itemInfo.value) oldItemInfo.value = JSON.parse(JSON.stringify(itemInfo.value))
|
||||
|
||||
if(!oldItemInfo.value.projecttype) {
|
||||
itemInfo.value.projecttype = projecttypes.value[0].id
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(itemInfo.value) {
|
||||
router.push(`/projects/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/projects/`)
|
||||
}
|
||||
}
|
||||
|
||||
const projectHours = () => {
|
||||
let hours = 0
|
||||
dataStore.getTimesByProjectId(itemInfo.value.id).forEach(item => {
|
||||
hours += Number(dayjs(item.end).diff(item.start,'hour',true).toFixed(2))
|
||||
})
|
||||
|
||||
return hours.toFixed(2)
|
||||
}
|
||||
|
||||
const updateProject = async () => {
|
||||
let initialPhases = projecttypes.value.find(i => i.id === itemInfo.value.projecttype).initialPhases
|
||||
|
||||
if(oldItemInfo.value.phases.length === 0) {
|
||||
itemInfo.value.phases = initialPhases
|
||||
}
|
||||
|
||||
await dataStore.updateItem('projects',itemInfo.value,oldItemInfo.value)
|
||||
|
||||
}
|
||||
|
||||
const createProject = async () => {
|
||||
let initialPhases = projecttypes.value.find(i => i.id === itemInfo.value.projecttype).initialPhases
|
||||
await dataStore.createNewItem('projects',{...itemInfo.value, phases: initialPhases })
|
||||
}
|
||||
|
||||
const changeActivePhase = async (key) => {
|
||||
let item = await useSupabaseSelectSingle("projects",itemInfo.value.id,'*')
|
||||
|
||||
console.log(key)
|
||||
|
||||
let phaseLabel = ""
|
||||
|
||||
item.phases = item.phases.map(p => {
|
||||
if(p.active) p.active = false
|
||||
|
||||
if(p.key === key) {
|
||||
p.active = true
|
||||
p.activated_at = dayjs().format()
|
||||
p.activated_by = profileStore.activeProfile.id
|
||||
phaseLabel = p.label
|
||||
}
|
||||
|
||||
return p
|
||||
})
|
||||
|
||||
console.log(item.phases)
|
||||
|
||||
await supabase.from("projects").update({phases: item.phases}).eq("id",item.id)
|
||||
const {error} = await supabase.from("historyitems").insert({
|
||||
createdBy: profileStore.activeProfile.id,
|
||||
tenant: profileStore.currentTenant,
|
||||
text: `Aktive Phase zu "${phaseLabel}" gewechselt`,
|
||||
project: item.id
|
||||
})
|
||||
console.log(error)
|
||||
|
||||
setupPage()
|
||||
}
|
||||
|
||||
|
||||
const renderedPhases = computed(() => {
|
||||
|
||||
if(itemInfo.value.phases) {
|
||||
return itemInfo.value.phases.map((phase,index,array) => {
|
||||
|
||||
let isAvailable = false
|
||||
|
||||
if(phase.active) {
|
||||
isAvailable = true
|
||||
} else if(index > 0 && array[index-1].active ){
|
||||
isAvailable = true
|
||||
} else if(index > 1 && array[index-1].optional && array[index-2].active){
|
||||
isAvailable = true
|
||||
} else if(array.findIndex(i => i.active) > index) {
|
||||
isAvailable = true
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
...phase,
|
||||
label: phase.optional ? `${phase.label}(optional)`: phase.label,
|
||||
disabled: !isAvailable,
|
||||
defaultOpen: phase.active ? true : false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
})
|
||||
|
||||
const invoiceDeliveryNotes = () => {
|
||||
router.push(`/createDocument/edit?type=invoices&linkedDocuments=[${itemInfo.value.createddocuments.filter(i => i.type === "deliveryNotes").map(i => i.id)}]`)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar :title="itemInfo ? itemInfo.name : (mode === 'create' ? 'Projekt erstellen' : 'Projekt bearbeiten')">
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/projects`)"
|
||||
>
|
||||
Projekte
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
class="text-xl font-medium"
|
||||
>{{itemInfo.name ? `Projekt: ${itemInfo.name}` : (mode === 'create' ? 'Projekt erstellen' : 'Projekt bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@click="updateProject"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else-if="mode === 'create'"
|
||||
@click="createProject"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="cancelEditorCreate"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click="router.push(`/projects/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UDashboardPanelContent>
|
||||
<UTabs
|
||||
:items="tabItems"
|
||||
v-if="itemInfo.id && mode == 'show'"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{ item }">
|
||||
<div v-if="item.key === 'information'" class="flex flex-row">
|
||||
<div class="w-1/2 mr-3">
|
||||
<UCard class="mt-5">
|
||||
<div class="text-wrap">
|
||||
<p>Kunde: <nuxt-link :to="`/customers/show/${itemInfo.customer.id}`">{{itemInfo.customer.name}}</nuxt-link></p>
|
||||
<p>Objekt: <nuxt-link v-if="itemInfo.plant" :to="`/plants/show/${itemInfo.plant.id}`">{{itemInfo.plant ? itemInfo.plant.name : ""}}</nuxt-link><span v-else>-</span></p>
|
||||
<p class="">Notizen: {{itemInfo.notes}}</p>
|
||||
</div>
|
||||
</UCard>
|
||||
<UCard class="mt-3">
|
||||
<h1 class="font-bold text-lg mb-3">Beteiligte Benutzer:</h1>
|
||||
<UAlert
|
||||
v-for="projectUser in itemInfo.profiles"
|
||||
:avatar="{ alt: profileStore.getProfileById(projectUser).fullName }"
|
||||
:title="profileStore.getProfileById(projectUser).fullName"
|
||||
class="mb-3"
|
||||
|
||||
/>
|
||||
</UCard>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<UCard class="mt-5">
|
||||
<HistoryDisplay
|
||||
type="project"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
render-headline
|
||||
/>
|
||||
</UCard>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div v-if="item.key === 'phases'" class="space-y-3">
|
||||
<UCard class="mt-5">
|
||||
<UAccordion
|
||||
:items="renderedPhases"
|
||||
>
|
||||
<template #default="{item,index,open}">
|
||||
<UButton
|
||||
variant="ghost"
|
||||
:color="item.active ? 'primary' : 'white'"
|
||||
class="mb-1"
|
||||
:disabled="true"
|
||||
>
|
||||
<template #leading>
|
||||
<div class="w-6 h-6 flex items-center justify-center -my-1">
|
||||
<UIcon :name="item.icon" class="w-4 h-4 " />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<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, index}">
|
||||
<UCard class="mx-5">
|
||||
<template #header>
|
||||
<span class="text-black">{{item.label}}</span>
|
||||
</template>
|
||||
<InputGroup>
|
||||
<UButton
|
||||
v-if="!item.activated_at && index !== 0 "
|
||||
@click="changeActivePhase(item.key)"
|
||||
>
|
||||
Phase aktivieren
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="item.active"
|
||||
v-for="button in item.quickactions"
|
||||
@click="router.push(`${button.link}&customer=${itemInfo.customer.id}&project=${itemInfo.id}`)"
|
||||
>
|
||||
{{button.label}}
|
||||
</UButton>
|
||||
</InputGroup>
|
||||
|
||||
<div>
|
||||
<p v-if="item.activated_at" class="text-black">Aktiviert am: {{dayjs(item.activated_at).format("DD.MM.YY HH:mm")}} Uhr</p>
|
||||
<p v-if="item.activated_by" class="text-black">Aktiviert durch: {{profileStore.getProfileById(item.activated_by).fullName}}</p>
|
||||
<p v-if="item.description" class="text-black">Beschreibung: {{item.description}}</p>
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
|
||||
</template>
|
||||
</UAccordion>
|
||||
</UCard>
|
||||
</div>
|
||||
<div v-if="item.key === 'tasks'" class="space-y-3">
|
||||
<UCard class="mt-5">
|
||||
<Toolbar>
|
||||
<UButton
|
||||
@click="router.push(`/tasks/create?project=${itemInfo.id}`)"
|
||||
>
|
||||
+ Aufgabe
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
|
||||
<UTable
|
||||
:rows="dataStore.getTasksByProjectId(itemInfo.id)"
|
||||
:columns="[{key: 'name',label: 'Name'},{key: 'categorie',label: 'Kategorie'},{key: 'user',label: 'Benutzer'}]"
|
||||
@select="(row) => router.push(`/tasks/show/${row.id}`)"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Aufgaben' }"
|
||||
|
||||
>
|
||||
<template #user-data="{row}">
|
||||
{{profileStore.profiles.find(i => i.id === row.user) ? profileStore.profiles.find(i => i.id === row.user).fullName : ""}}
|
||||
</template>
|
||||
</UTable>
|
||||
</UCard>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div v-else-if="item.key === 'documents'" class="space-y-3">
|
||||
<UCard class="mt-5">
|
||||
<Toolbar>
|
||||
<DocumentUpload
|
||||
type="project"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
<UButton
|
||||
@click="router.push(`/createDocument/edit?project=${itemInfo.id}&customer=${itemInfo.customer.id}`)"
|
||||
>
|
||||
+ Dokument
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="invoiceDeliveryNotes"
|
||||
>
|
||||
Lieferscheine abrechnen
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
|
||||
|
||||
<UTable
|
||||
:rows="itemInfo.createddocuments"
|
||||
:columns="[
|
||||
{
|
||||
label: 'Typ',
|
||||
key: 'type'
|
||||
}, {
|
||||
label: 'Status',
|
||||
key: 'state'
|
||||
}, {
|
||||
label: 'Dokumentennummer',
|
||||
key: 'documentNumber'
|
||||
}, {
|
||||
label: 'Ansprechpartner',
|
||||
key: 'createdBy'
|
||||
}
|
||||
|
||||
]"
|
||||
@select="(row) => row.state === 'Entwurf' ? router.push(`/createDocument/edit/${row.id}`) : router.push(`/createDocument/show/${row.id}`)"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen erstellten Dokumente' }"
|
||||
|
||||
>
|
||||
<template #type-data="{row}">
|
||||
<span v-if="row.type === 'invoices'">Rechnung</span>
|
||||
<span v-if="row.type === 'quotes'">Angebot</span>
|
||||
<span v-if="row.type === 'deliveryNotes'">Lieferschein</span>
|
||||
</template>
|
||||
<template #createdBy-data="{row}">
|
||||
{{profileStore.getProfileById(row.createdBy).fullName}}
|
||||
</template>
|
||||
</UTable>
|
||||
|
||||
<DocumentList :documents="dataStore.getDocumentsByProjectId(itemInfo.id)"/>
|
||||
</UCard>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div v-else-if="item.key === 'timetracking'" class="space-y-3">
|
||||
<UCard class="mt-5">
|
||||
Projekt Zeit: {{String(projectHours()).replace(".",",")}} Stunden
|
||||
<UTable
|
||||
:rows="dataStore.getTimesByProjectId(itemInfo.id)"
|
||||
:columns="timeTableRows"
|
||||
:empty-state="{ icon: 'i-heroicons-clock', label: 'Noch keine Zeiten in diesem Projekt' }"
|
||||
>
|
||||
<template #user-data="{row}">
|
||||
{{profileStore.profiles.find(profile => profile.id === row.user) ? profileStore.profiles.find(profile => profile.id === row.user).fullName : row.user }}
|
||||
</template>
|
||||
<template #duration-data="{row}">
|
||||
{{(row.start && row.end) ? `${String(dayjs(row.end).diff(row.start,'hour',true).toFixed(2)).replace(".",",")} h` : ""}}
|
||||
</template>
|
||||
<template #start-data="{row}">
|
||||
{{dayjs(row.start).format("DD.MM.YY HH:mm")}}
|
||||
</template>
|
||||
<template #end-data="{row}">
|
||||
{{dayjs(row.end).format("DD.MM.YY HH:mm")}}
|
||||
</template>
|
||||
|
||||
</UTable>
|
||||
</UCard>
|
||||
|
||||
|
||||
</div>
|
||||
<div v-else-if="item.key === 'events'" class="space-y-3">
|
||||
<UCard class="mt-5">
|
||||
<Toolbar>
|
||||
<UButton
|
||||
@click="router.push(`/events/edit`)"
|
||||
>
|
||||
+ Termin
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
<UTable
|
||||
:rows="dataStore.getEventsByProjectId(itemInfo.id)"
|
||||
@select="(i) => router.push(`/events/show/${i.id}`)"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Termine anzuzeigen' }"
|
||||
:columns="[{key:'title',label:'Titel'},{key:'start',label:'Start'},{key:'end',label:'Ende'},{key:'type',label:'Typ'},{key:'resources',label:'Resourcen'}]"
|
||||
>
|
||||
<template #start-data="{row}">
|
||||
{{dayjs(row.start).format("DD.MM.YY HH:mm")}}
|
||||
</template>
|
||||
<template #end-data="{row}">
|
||||
{{dayjs(row.end).format("DD.MM.YY HH:mm")}}
|
||||
</template>
|
||||
<template #resources-data="{row}">
|
||||
{{row.resources.map(i => i.title).join(", ")}}
|
||||
</template>
|
||||
</UTable>
|
||||
</UCard>
|
||||
</div>
|
||||
<div v-else-if="item.key === 'material'" class="space-y-3">
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
</UTabs>
|
||||
|
||||
<UForm v-else-if="mode === 'edit' || mode === 'create'" >
|
||||
<UFormGroup
|
||||
label="Name:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.name"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Projektnummer:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.projectNumber"
|
||||
placeholder="Leer lassen für automatisch generierte Nummer"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Objekt:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.plant"
|
||||
:options="itemInfo.customer ? plants.filter(i => i.customer === itemInfo.customer) : plants"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
searchable
|
||||
:search-attributes="['name']"
|
||||
@change="itemInfo.customer = plants.find(i => i.id === itemInfo.plant).customer,
|
||||
disableCustomerSelection = true"
|
||||
>
|
||||
<template #label>
|
||||
{{plants.find(i => i.id === itemInfo.plant) ? plants.find(i => i.id === itemInfo.plant).name : "Objekt auswählen"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Vertrag:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.contract"
|
||||
:options="itemInfo.customer ? contracts.filter(i => i.customer === itemInfo.customer) : contracts"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
searchable
|
||||
:search-attributes="['name']"
|
||||
@change="itemInfo.customer = contracts.find(i => i.id === itemInfo.contract).customer,
|
||||
disableCustomerSelection = true"
|
||||
>
|
||||
<template #label>
|
||||
{{contracts.find(i => i.id === itemInfo.contract) ? contracts.find(i => i.id === itemInfo.contract).name : "Vertrag auswählen"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Kundennummer:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.customer"
|
||||
:options="dataStore.customers"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
searchable
|
||||
:search-attributes="['name']"
|
||||
:disabled="disableCustomerSelection"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.getCustomerById(itemInfo.customer) ? dataStore.getCustomerById(itemInfo.customer).name : "Kunde auswählen"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Typ:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.projecttype"
|
||||
:options="projecttypes"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
searchable
|
||||
:search-attributes="['label']"
|
||||
:disabled="oldItemInfo.projecttype"
|
||||
>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Gewerk:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.measure"
|
||||
:options="dataStore.getMeasures"
|
||||
option-attribute="name"
|
||||
value-attribute="short"
|
||||
searchable
|
||||
:search-attributes="['name']"
|
||||
>
|
||||
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
|
||||
|
||||
<UFormGroup
|
||||
label="Berechtigte Benutzer:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.profiles"
|
||||
:options="profileStore.profiles"
|
||||
option-attribute="fullName"
|
||||
value-attribute="id"
|
||||
searchable
|
||||
multiple
|
||||
:search-attributes="['fullName']"
|
||||
>
|
||||
<template #label>
|
||||
{{itemInfo.profiles.length > 0 ? itemInfo.profiles.map(i => profileStore.getProfileById(i).fullName).join(", ") : "Kein Benutzer ausgewählt"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Notizen:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.notes"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</UForm>
|
||||
</UDashboardPanelContent>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
45
deprecated/entitys/projects/index.vue
Normal file
45
deprecated/entitys/projects/index.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<EntityList
|
||||
type="projects"
|
||||
:items="items"
|
||||
></EntityList>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import EntityList from "~/components/EntityList.vue";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
const items = ref([])
|
||||
|
||||
const setupPage = async () => {
|
||||
let profiles = (await useSupabaseSelect("profiles"))
|
||||
items.value = (await useSupabaseSelect("projects","*, customer (name), plant(name), projecttype(name, id)","projectNumber")).map(project => {
|
||||
return {
|
||||
...project,
|
||||
//profiles: project.profiles.map(x => profiles.find(z => z.id === x).fullName).join(", "),
|
||||
phase: getActivePhaseLabel(project)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getActivePhaseLabel = (item) => {
|
||||
if(item.phases) {
|
||||
if(item.phases.length > 0) {
|
||||
|
||||
let activePhase = item.phases.find(i => i.active)
|
||||
|
||||
if(activePhase) {
|
||||
return activePhase.label
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
</script>
|
||||
179
deprecated/entitys/servicecategories/[mode]/[[id]].vue
Normal file
179
deprecated/entitys/servicecategories/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,179 @@
|
||||
<script setup>
|
||||
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||
import DocumentList from "~/components/DocumentList.vue";
|
||||
import DocumentUpload from "~/components/DocumentUpload.vue";
|
||||
import {useSupabaseSelect} from "~/composables/useSupabase.js";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/servicecategories")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({})
|
||||
const openTab = ref(0)
|
||||
|
||||
//Functions
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show" || mode.value === "edit"){
|
||||
itemInfo.value = await useSupabaseSelectSingle("servicecategories",route.params.id,"*")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(itemInfo.value) {
|
||||
router.push(`/servicecategories/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/servicecategories/`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar
|
||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||
>
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/servicecategories`)"
|
||||
>
|
||||
Leistungskategorien
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
class="text-xl font-medium"
|
||||
>{{itemInfo.name ? `Leistungskategorie: ${itemInfo.name}` : (mode === 'create' ? 'Leistungskategorie erstellen' : 'Leistungskategorie bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@click="dataStore.updateItem('servicecategories',itemInfo)"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else-if="mode === 'create'"
|
||||
@click="dataStore.createNewItem('servicecategories',itemInfo)"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="cancelEditorCreate"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click=" router.push(`/servicecategories/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
:items="[{label: 'Informationen'}]"
|
||||
v-if="mode === 'show' && itemInfo"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<div v-if="item.label === 'Informationen'" class="mr-5 flex flex-row">
|
||||
<div class="w-1/2 mr-5">
|
||||
<UCard>
|
||||
<table class="w-full">
|
||||
<tr>
|
||||
<td>Name: </td>
|
||||
<td>{{itemInfo.name}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Beschreibung:</td>
|
||||
<td>{{itemInfo.description}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</UCard>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<UCard>
|
||||
<HistoryDisplay
|
||||
type="product"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
render-headline
|
||||
/>
|
||||
</UCard>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
</UTabs>
|
||||
<UForm
|
||||
v-else-if="mode == 'edit' || mode == 'create'"
|
||||
class="p-5"
|
||||
>
|
||||
<UFormGroup
|
||||
label="Name:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.name"
|
||||
autofocus
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Beschreibung:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.description"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</UForm>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
td {
|
||||
border-bottom: 1px solid lightgrey;
|
||||
vertical-align: top;
|
||||
padding-bottom: 0.15em;
|
||||
padding-top: 0.15em;
|
||||
}
|
||||
</style>
|
||||
24
deprecated/entitys/servicecategories/index.vue
Normal file
24
deprecated/entitys/servicecategories/index.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<EntityList
|
||||
:items="items"
|
||||
type="servicecategories"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
const items = ref([])
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("servicecategories","*")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
266
deprecated/entitys/services/[mode]/[[id]].vue
Normal file
266
deprecated/entitys/services/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,266 @@
|
||||
<script setup>
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/services")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const profileStore = useProfileStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const supabase = useSupabaseClient()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({
|
||||
unit: 1,
|
||||
tags: [],
|
||||
servicecategories: []
|
||||
})
|
||||
|
||||
const openTab = ref(0)
|
||||
|
||||
const servicecategories = ref([])
|
||||
const units = ref([])
|
||||
|
||||
//Functions
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show"){
|
||||
itemInfo.value = await useSupabaseSelectSingle("services",useRoute().params.id, "*")
|
||||
} else if(mode.value === "edit") {
|
||||
itemInfo.value = await useSupabaseSelectSingle("services",useRoute().params.id)
|
||||
}
|
||||
|
||||
servicecategories.value = await useSupabaseSelect("servicecategories","*")
|
||||
units.value = (await supabase.from("units").select()).data
|
||||
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar :title="itemInfo ? itemInfo.name : (mode === 'create' ? 'Leistung erstellen' : 'Leistung bearbeiten')">
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/services`)"
|
||||
>
|
||||
Leistungen
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
class="text-xl font-medium"
|
||||
>{{itemInfo.name ? `Leistung: ${itemInfo.name}` : (mode === 'create' ? 'Leistung erstellen' : 'Leistung bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@click="dataStore.updateItem('services',itemInfo)"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else-if="mode === 'create'"
|
||||
@click="dataStore.createNewItem('services',itemInfo)"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="itemInfo.value ? router.push(`/services/show/${itemInfo.value.id}`) : router.push(`/services/`)"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click="router.push(`/services/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
:items="[{label: 'Informationen'},{label: 'Dokumente'}]"
|
||||
v-if="mode === 'show'"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<div v-if="item.label === 'Informationen'" class="mt-5 flex flex-row">
|
||||
<div class="w-1/2 mr-5">
|
||||
<UCard>
|
||||
<table class="w-full">
|
||||
<tr>
|
||||
<td>Name:</td>
|
||||
<td>{{itemInfo.name}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Leistungsnummer:</td>
|
||||
<td>{{itemInfo.serviceNumber}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Verkaufpreis:</td>
|
||||
<td>{{itemInfo.sellingPrice && itemInfo.sellingPrice.toFixed(2).replace(".", ",") + " €"}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Einheit:</td>
|
||||
<td>{{units.find(i => i.id === itemInfo.unit) ? units.find(i => i.id === itemInfo.unit).name : itemInfo.unit}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Tags:</td>
|
||||
<td>{{itemInfo.tags.join(", ")}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Leistungskategorien:</td>
|
||||
<td>{{itemInfo.servicecategories ? itemInfo.servicecategories.map(i => servicecategories.find(x => x.id === i).name).join(", ") : ""}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Beschreibung:</td>
|
||||
<td>{{itemInfo.description}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</UCard>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<UCard>
|
||||
<HistoryDisplay
|
||||
render-headline
|
||||
type="product"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</UCard>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="item.label === 'Dokumente'"
|
||||
class="mt-5"
|
||||
>
|
||||
<UCard>
|
||||
<Toolbar>
|
||||
<DocumentUpload
|
||||
type="product"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</Toolbar>
|
||||
|
||||
|
||||
<DocumentList :documents="dataStore.getDocumentsByProductId(itemInfo.id)"/>
|
||||
</UCard>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
</UTabs>
|
||||
<UForm
|
||||
v-else-if="mode == 'edit' || mode == 'create'"
|
||||
class="p-5"
|
||||
>
|
||||
<UFormGroup
|
||||
label="Name:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.name"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Leistungsnummer:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.serviceNumber"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Einheit:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.unit"
|
||||
:options="dataStore.units"
|
||||
option-attribute="name"
|
||||
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
|
||||
v-model="itemInfo.tags"
|
||||
:options="profileStore.ownTenant.tags.products"
|
||||
multiple
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Leistungskategorie:"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="servicecategories"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
v-model="itemInfo.servicecategories"
|
||||
multiple
|
||||
>
|
||||
<template #label>
|
||||
{{itemInfo.servicecategories && itemInfo.servicecategories.length > 0 ? itemInfo.servicecategories.map(i => servicecategories.find(x => x.id === i).name).join(", ") : "Keine Kategorien ausgewählt"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Verkaufspreis:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.sellingPrice"
|
||||
type="number"
|
||||
steps="0.001"
|
||||
>
|
||||
<template #trailing>
|
||||
<span class="text-gray-500 dark:text-gray-400 text-xs">EUR</span>
|
||||
</template>
|
||||
</UInput>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Beschreibung:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.description"
|
||||
:rows="6"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</UForm>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
td {
|
||||
border-bottom: 1px solid lightgrey;
|
||||
vertical-align: top;
|
||||
padding-bottom: 0.15em;
|
||||
padding-top: 0.15em;
|
||||
}
|
||||
</style>
|
||||
25
deprecated/entitys/services/index.vue
Normal file
25
deprecated/entitys/services/index.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<EntityList
|
||||
:items="items"
|
||||
type="services"
|
||||
/>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
const items = ref([])
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("services","*, unit(name)")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
211
deprecated/entitys/tasks/[mode]/[[id]].vue
Normal file
211
deprecated/entitys/tasks/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,211 @@
|
||||
<script setup>
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const profileStore = useProfileStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({
|
||||
profile: profileStore.activeProfile.id
|
||||
})
|
||||
const oldItemInfo = ref({})
|
||||
const categories = ["Offen", "In Bearbeitung", "Dringed", "Erledigt"]
|
||||
|
||||
//Functions
|
||||
const setupPage = () => {
|
||||
if(mode.value === "show" || mode.value === "edit"){
|
||||
itemInfo.value = dataStore.getTaskById(Number(useRoute().params.id))
|
||||
}
|
||||
|
||||
if(mode.value === "create") {
|
||||
let query = route.query
|
||||
if(query.project) itemInfo.value.project = Number(query.project)
|
||||
if(query.plant) itemInfo.value.plant = Number(query.plant)
|
||||
|
||||
}
|
||||
|
||||
if(itemInfo.value) oldItemInfo.value = JSON.parse(JSON.stringify(itemInfo.value))
|
||||
}
|
||||
|
||||
|
||||
const editItem = async () => {
|
||||
router.push(`/tasks/edit/${itemInfo.value.id}`)
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(itemInfo.value) {
|
||||
router.push(`/tasks/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/tasks/`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar :title="itemInfo ? itemInfo.name : (mode === 'create' ? 'Aufgabe erstellen' : 'Aufgabe bearbeiten')">
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/tasks`)"
|
||||
>
|
||||
Aufgaben
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
:class="['text-xl','font-medium'/*, ... itemInfo.categorie === 'Erledigt' ? ['text-primary'] : ['text-rose-500']*/]"
|
||||
>{{itemInfo ? `Aufgabe: ${itemInfo.name}` : (mode === 'create' ? 'Aufgabe erstellen' : 'Aufgabe bearbeiten')}}</h1>
|
||||
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@click="dataStore.updateItem('tasks',itemInfo,oldItemInfo)"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else-if="mode === 'create'"
|
||||
@click="dataStore.createNewItem('tasks',itemInfo)"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="cancelEditorCreate"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click="editItem"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
:items="[{label: 'Informationen'},{label: 'Logbuch'}]"
|
||||
v-if="itemInfo && mode === 'show'"
|
||||
class="p-5"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<UCard class="mt-5">
|
||||
<div v-if="item.label === 'Informationen'">
|
||||
|
||||
|
||||
<div class="truncate">
|
||||
<p>Kategorie: {{itemInfo.categorie}}</p>
|
||||
<p v-if="itemInfo.project">Projekt: <nuxt-link :to="`/projects/show/${itemInfo.project}`">{{dataStore.getProjectById(itemInfo.project).name}}</nuxt-link></p>
|
||||
<p>Beschreibung: <br><pre v-html="itemInfo.description"></pre></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Logbuch'">
|
||||
<HistoryDisplay
|
||||
type="task"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</div>
|
||||
</UCard>
|
||||
</template>
|
||||
</UTabs>
|
||||
|
||||
<UForm v-else-if="mode === 'edit' || mode === 'create' " class="p-5">
|
||||
<UFormGroup
|
||||
label="Name:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.name"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Kategorie:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.categorie"
|
||||
:options="categories"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Benutzer:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.profile"
|
||||
:options="profileStore.profiles"
|
||||
option-attribute="fullName"
|
||||
value-attribute="id"
|
||||
searchable-placeholder="Suche..."
|
||||
searchable
|
||||
:search-attributes="['fullName']"
|
||||
>
|
||||
<template #label>
|
||||
{{profileStore.getProfileById(itemInfo.profile) ? profileStore.getProfileById(itemInfo.profile).fullName : "Kein Benutzer ausgewählt"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Projekt:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.project"
|
||||
:options="dataStore.projects"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
searchable-placeholder="Suche..."
|
||||
searchable
|
||||
:search-attributes="['name']"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.getProjectById(itemInfo.project) ? dataStore.getProjectById(itemInfo.project).name : "Kein Projekt ausgewählt"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Objekt:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.plant"
|
||||
:options="dataStore.plants"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
searchable-placeholder="Suche..."
|
||||
searchable
|
||||
:search-attributes="['name']"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.getPlantById(itemInfo.plant) ? dataStore.getPlantById(itemInfo.plant).name : "Kein Objekt ausgewählt"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Beschreibung:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.description"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</UForm>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
129
deprecated/entitys/tasks/index.vue
Normal file
129
deprecated/entitys/tasks/index.vue
Normal file
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<UDashboardNavbar title="Aufgaben" :badge="filteredRows.length">
|
||||
<template #right>
|
||||
<UInput
|
||||
id="searchinput"
|
||||
v-model="searchString"
|
||||
icon="i-heroicons-funnel"
|
||||
autocomplete="off"
|
||||
placeholder="Suche..."
|
||||
class="hidden lg:block"
|
||||
@keydown.esc="$event.target.blur()"
|
||||
>
|
||||
<template #trailing>
|
||||
<UKbd value="/" />
|
||||
</template>
|
||||
</UInput>
|
||||
|
||||
<UButton @click="router.push(`/tasks/create`)">+ Aufgabe</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
|
||||
<UDashboardToolbar>
|
||||
<template #left>
|
||||
|
||||
|
||||
<UCheckbox
|
||||
label="Erledigte Anzeigen"
|
||||
v-model="showDone"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #right>
|
||||
<USelectMenu
|
||||
v-model="selectedColumns"
|
||||
icon="i-heroicons-adjustments-horizontal-solid"
|
||||
:options="templateColumns"
|
||||
multiple
|
||||
class="hidden lg:block"
|
||||
by="key"
|
||||
>
|
||||
<template #label>
|
||||
Spalten
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</template>
|
||||
</UDashboardToolbar>
|
||||
|
||||
<UTable
|
||||
:rows="filteredRows"
|
||||
:columns="columns"
|
||||
class="w-full"
|
||||
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
|
||||
@select="(i) => router.push(`/tasks/show/${i.id}`) "
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Aufgaben anzuzeigen' }"
|
||||
>
|
||||
<template #finish-data="{row}">
|
||||
<UButton
|
||||
icon="i-heroicons-check"
|
||||
variant="ghost"
|
||||
@click="markAsFinished(row)"
|
||||
/>
|
||||
</template>
|
||||
<template #created_at-data="{row}">
|
||||
{{row.created_at ? dayjs(row.created_at).format("DD.MM.YY HH:mm") : ''}}
|
||||
</template>
|
||||
<template #user-data="{row}">
|
||||
{{profileStore.profiles.find(i => i.id === row.user) ? profileStore.profiles.find(i => i.id === row.user).fullName : ""}}
|
||||
</template>
|
||||
<template #project-data="{row}">
|
||||
{{dataStore.projects.find(i => i.id === row.project) ? dataStore.projects.find(i => i.id === row.project).name : ""}}
|
||||
</template>
|
||||
<template #customer-data="{row}">
|
||||
{{dataStore.customers.find(customer => customer.id === row.customer) ? dataStore.customers.find(customer => customer.id === row.customer).name : "" }}
|
||||
</template>
|
||||
<template #plant-data="{row}">
|
||||
{{dataStore.getPlantById(row.plant) ? dataStore.getPlantById(row.plant).name : "" }}
|
||||
</template>
|
||||
</UTable>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import dayjs from "dayjs";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const profileStore = useProfileStore()
|
||||
const router = useRouter()
|
||||
|
||||
defineShortcuts({
|
||||
'/': () => {
|
||||
//console.log(searchinput)
|
||||
//searchinput.value.focus()
|
||||
document.getElementById("searchinput").focus()
|
||||
},
|
||||
'+': () => {
|
||||
router.push("/tasks/create")
|
||||
}
|
||||
})
|
||||
|
||||
const templateColumns = [
|
||||
|
||||
/*{
|
||||
key:"finish"
|
||||
},*/
|
||||
]
|
||||
const selectedColumns = ref(templateColumns)
|
||||
const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
|
||||
|
||||
const markAsFinished = (item) => {
|
||||
dataStore.updateItem("tasks", {...item, categorie: "Erledigt"})
|
||||
}
|
||||
|
||||
const searchString = ref('')
|
||||
const showDone = ref(false)
|
||||
const filteredRows = computed(() => {
|
||||
let items = dataStore.tasks
|
||||
|
||||
items = items.filter(i => showDone.value === true ? i.categorie === "Erledigt" : i.categorie !== "Erledigt")
|
||||
|
||||
return useSearch(searchString.value, items)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
236
deprecated/entitys/vehicles/[mode]/[[id]].vue
Normal file
236
deprecated/entitys/vehicles/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,236 @@
|
||||
<script setup>
|
||||
import dayjs from "dayjs";
|
||||
import {useSupabaseSelectSingle} from "~/composables/useSupabase.js";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/vehicles")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const profileStore = useProfileStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
const openTab = ref(0)
|
||||
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({
|
||||
name: "",
|
||||
licensePlate: "",
|
||||
type: "",
|
||||
driver: null,
|
||||
active: true
|
||||
})
|
||||
const oldItemInfo = ref({})
|
||||
|
||||
|
||||
//Functions
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show"){
|
||||
itemInfo.value = await useSupabaseSelectSingle("vehicles",route.params.id,"*, checks(*)")
|
||||
} else if(mode.value === "edit"){
|
||||
itemInfo.value = await useSupabaseSelectSingle("vehicles",route.params.id,"*")
|
||||
}
|
||||
|
||||
if(itemInfo.value) oldItemInfo.value = JSON.parse(JSON.stringify(itemInfo.value))
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(itemInfo.value.id) {
|
||||
router.push(`/vehicles/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/vehicles`)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<EntityEdit
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
type="vehicles"
|
||||
:item="itemInfo"
|
||||
/>
|
||||
|
||||
|
||||
<!-- <UDashboardNavbar
|
||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||
>
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/vehicles`)"
|
||||
>
|
||||
Fahrzeuge
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
:class="['text-xl','font-medium']"
|
||||
>{{itemInfo ? `Fahrzeug: ${itemInfo.licensePlate}` : (mode === 'create' ? 'Fahrzeug erstellen' : 'Fahrzeug bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<ButtonWithConfirm
|
||||
color="rose"
|
||||
variant="outline"
|
||||
@confirmed="dataStore.updateItem('vehicles',{...itemInfo, archived: true})"
|
||||
v-if="mode === 'edit'"
|
||||
>
|
||||
<template #button>
|
||||
Archivieren
|
||||
</template>
|
||||
<template #header>
|
||||
<span class="text-md text-black font-bold">Archivieren bestätigen</span>
|
||||
</template>
|
||||
Möchten Sie das Fahrzeug {{itemInfo.name}} wirklich archivieren?
|
||||
</ButtonWithConfirm>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@click="dataStore.updateItem('vehicles',itemInfo, oldItemInfo)"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else-if="mode === 'create'"
|
||||
@click="dataStore.createNewItem('vehicles',itemInfo)"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="cancelEditorCreate"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>-->
|
||||
|
||||
<!-- <UForm
|
||||
class="p-5"
|
||||
>
|
||||
|
||||
<UFormGroup
|
||||
label="Kennzeichen:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.licensePlate"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
|
||||
|
||||
<UFormGroup
|
||||
label="Fahrzeug aktiv:"
|
||||
>
|
||||
<UCheckbox
|
||||
v-model="itemInfo.active"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Fahrgestellnummer:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.vin"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Typ:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.type"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Fahrer:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.driver"
|
||||
:options="[{id: null, fullName: 'Kein Fahrer'},...profileStore.profiles]"
|
||||
option-attribute="fullName"
|
||||
value-attribute="id"
|
||||
|
||||
>
|
||||
<template #label>
|
||||
{{profileStore.profiles.find(profile => profile.id === itemInfo.driver) ? profileStore.profiles.find(profile => profile.id === itemInfo.driver).fullName : 'Kein Fahrer ausgewählt'}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Tankvolumen:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.tankSize"
|
||||
type="number"
|
||||
>
|
||||
<template #trailing>
|
||||
L
|
||||
</template>
|
||||
</UInput>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Baujahr:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.buildYear"
|
||||
type="number"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Anhängelast:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.towingCapacity"
|
||||
type="number"
|
||||
>
|
||||
<template #trailing>kg</template>
|
||||
</UInput>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Farbe:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.color"
|
||||
type="text"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Leistung:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.powerInKW"
|
||||
type="number"
|
||||
>
|
||||
<template #trailing>kW</template>
|
||||
</UInput>
|
||||
</UFormGroup>
|
||||
</UForm>-->
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
24
deprecated/entitys/vehicles/index.vue
Normal file
24
deprecated/entitys/vehicles/index.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<EntityList
|
||||
:items="items"
|
||||
type="vehicles"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
const items = ref([])
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("vehicles","*")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
33
deprecated/entitys/vehicles/show/[id].vue
Normal file
33
deprecated/entitys/vehicles/show/[id].vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<script setup>
|
||||
import {useSupabaseSelectSingle} from "~/composables/useSupabase.js";
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const itemInfo = ref({})
|
||||
|
||||
const tabItems = [{
|
||||
label: 'Informationen',
|
||||
}, {
|
||||
label: 'Dokumente',
|
||||
}, {
|
||||
label: 'Überprüfungen',
|
||||
}]
|
||||
|
||||
const setupPage = async () => {
|
||||
itemInfo.value = await useSupabaseSelectSingle("vehicles",route.params.id,"*, checks(*), documents(*)")
|
||||
console.log(itemInfo.value)
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<EntityShow
|
||||
type="vehicles"
|
||||
:item="itemInfo"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
291
deprecated/entitys/vendors/[mode]/[[id]].vue
vendored
Normal file
291
deprecated/entitys/vendors/[mode]/[[id]].vue
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
<script setup>
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/vendors")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 1) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const profileStore = useProfileStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const openTab = ref(0)
|
||||
let currentItem = ref(null)
|
||||
|
||||
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({
|
||||
infoData: {},
|
||||
profiles: [profileStore.activeProfile.id]
|
||||
})
|
||||
const oldItemInfo = ref({})
|
||||
|
||||
//Functions
|
||||
const setupPage = () => {
|
||||
if (mode.value === "show" || mode.value === "edit") {
|
||||
currentItem.value = dataStore.getVendorById(Number(useRoute().params.id))
|
||||
}
|
||||
|
||||
if (mode.value === "edit") itemInfo.value = currentItem.value
|
||||
if(currentItem.value) oldItemInfo.value = JSON.parse(JSON.stringify(currentItem.value))
|
||||
|
||||
}
|
||||
|
||||
const setCityByZip = async () => {
|
||||
itemInfo.value.infoData.city = await useZipCheck(itemInfo.value.infoData.zip)
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar
|
||||
:title="currentItem ? `Lieferant: ${currentItem.name}` : (mode === 'create' ? 'Lieferant erstellen' : 'Lieferant bearbeiten')"
|
||||
:ui="{center: 'flex items-stretch gap-1.5 min-w-0'}"
|
||||
>
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/vendors`)"
|
||||
>
|
||||
Lieferanten
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="currentItem"
|
||||
:class="['text-xl','font-medium']"
|
||||
>{{currentItem ? `Lieferant: ${currentItem.name}` : (mode === 'create' ? 'Lieferant erstellen' : 'Lieferant bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@click="dataStore.updateItem('vendors',itemInfo,oldItemInfo)"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else-if="mode === 'create'"
|
||||
@click="dataStore.createNewItem('vendors',itemInfo)"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="router.push(currentItem.id ? `/vendors/show/${currentItem.id}` : '/vendors/show')"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click="router.push(`/vendors/edit/${currentItem.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
:items="[{label: 'Informationen'},{label: 'Dokumente'}]"
|
||||
v-if="currentItem && mode == 'show'"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<div v-if="item.label === 'Informationen'" class="mt-5 flex">
|
||||
<div class="w-1/2 mr-5">
|
||||
<UCard>
|
||||
<div v-if="currentItem.infoData" class="text-wrap">
|
||||
<p>Straße + Hausnummer: {{currentItem.infoData.street ? currentItem.infoData.street : ""}}</p>
|
||||
<p>PLZ + Ort: {{currentItem.infoData.zip}} {{currentItem.infoData.city}}</p>
|
||||
<p>Telefon: {{currentItem.infoData.tel}}</p>
|
||||
<p>E-Mail: {{currentItem.infoData.email}}</p>
|
||||
<p>Web: {{currentItem.infoData.web}}</p>
|
||||
<p>USt-Id: {{currentItem.infoData.ustid}}</p>
|
||||
<p>SEPA Mandat: {{currentItem.hasSEPA ? "Ja" : "Nein"}}</p>
|
||||
<p>Notizen:<br> {{currentItem.notes}}</p>
|
||||
</div>
|
||||
</UCard>
|
||||
<UCard class="mt-5">
|
||||
<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' }"
|
||||
|
||||
>
|
||||
|
||||
</UTable>
|
||||
</UCard>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<UCard class="h-full">
|
||||
<HistoryDisplay
|
||||
type="vendor"
|
||||
v-if="currentItem"
|
||||
:element-id="currentItem.id"
|
||||
:render-headline="true"
|
||||
/>
|
||||
</UCard>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<UCard class="mt-5" v-else>
|
||||
<div v-if="item.label === 'Dokumente'">
|
||||
<InputGroup>
|
||||
<DocumentUpload
|
||||
type="vendor"
|
||||
:element-id="currentItem.id"
|
||||
/>
|
||||
</InputGroup>
|
||||
|
||||
<DocumentList
|
||||
:documents="dataStore.getDocumentsByVendorId(currentItem.id)"
|
||||
/>
|
||||
</div>
|
||||
</UCard>
|
||||
</template>
|
||||
</UTabs>
|
||||
<UForm
|
||||
v-else-if="mode === 'edit' || mode === 'create'"
|
||||
class="p-5"
|
||||
>
|
||||
<UFormGroup
|
||||
label="Name:"
|
||||
>
|
||||
<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"
|
||||
@focusout="setCityByZip"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Ort"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.infoData.city"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Land"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="['Deutschland','Niederlande','Belgien','Italien', 'Frankreich','Irland','USA','Spanien', 'Schweden']"
|
||||
v-model="itemInfo.infoData.country"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Telefon:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.infoData.tel"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Notizen:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.notes"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="E-Mail:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.infoData.email"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Webseite:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.infoData.web"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="SEPA Mandat abgeschlossen:"
|
||||
>
|
||||
<UCheckbox
|
||||
v-model="itemInfo.hasSEPA"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="USt-Id:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.infoData.ustid"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Berechtigte Benutzer:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.profiles"
|
||||
:options="profileStore.profiles"
|
||||
option-attribute="fullName"
|
||||
value-attribute="id"
|
||||
searchable
|
||||
multipledataStore
|
||||
:search-attributes="['fullName']"
|
||||
>
|
||||
<template #label>
|
||||
{{itemInfo.profiles.length > 0 ? itemInfo.profiles.map(i => profileStore.getProfileById(i).fullName).join(", ") : "Kein Benutzer ausgewählt"}}
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
</UForm>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
24
deprecated/entitys/vendors/index.vue
vendored
Normal file
24
deprecated/entitys/vendors/index.vue
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<EntityList
|
||||
:items="items"
|
||||
type="vendors"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
const items = ref([])
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("vendors","*","vendorNumber")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
382
deprecated/inventoryitems/[mode]/[[id]].vue
Normal file
382
deprecated/inventoryitems/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,382 @@
|
||||
<script setup>
|
||||
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||
import dayjs from "dayjs";
|
||||
import {useSupabaseSelectSingle} from "~/composables/useSupabase.js";
|
||||
import DocumentUpload from "~/components/DocumentUpload.vue";
|
||||
import DocumentList from "~/components/DocumentList.vue";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({
|
||||
name: null,
|
||||
description: null,
|
||||
quantity: 0
|
||||
})
|
||||
|
||||
//Functions
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show"){
|
||||
itemInfo.value = await useSupabaseSelectSingle("inventoryitems", route.params.id, "*, vendor(*), checks(*)")
|
||||
} else if(mode.value === "edit") {
|
||||
itemInfo.value = await useSupabaseSelectSingle("inventoryitems", route.params.id, "*")
|
||||
}
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(itemInfo.value) {
|
||||
router.push(`/inventoryitems/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/inventoryitems`)
|
||||
}
|
||||
}
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar :title="itemInfo ? itemInfo.name : (mode === 'create' ? 'Inventartikel erstellen' : 'Inventartikel bearbeiten')">
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/inventoryitems`)"
|
||||
>
|
||||
Inventar
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
:class="['text-xl','font-medium']"
|
||||
>{{itemInfo.id ? `Inventarartikel: ${itemInfo.name}` : (mode === 'create' ? 'Inventarartikel erstellen' : 'Inventarartikel bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<ButtonWithConfirm
|
||||
color="rose"
|
||||
variant="outline"
|
||||
@confirmed="dataStore.updateItem('inventoryitems',{...itemInfo, archived: true})"
|
||||
v-if="mode === 'edit'"
|
||||
>
|
||||
<template #button>
|
||||
Archivieren
|
||||
</template>
|
||||
<template #header>
|
||||
<span class="text-md text-black font-bold">Archivieren bestätigen</span>
|
||||
</template>
|
||||
Möchten Sie den Inventarartikel {{itemInfo.name}} wirklich archivieren?
|
||||
</ButtonWithConfirm>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@click="dataStore.updateItem('inventoryitems',itemInfo)"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'create'"
|
||||
@click="dataStore.createNewItem('inventoryitems',itemInfo)"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'create'"
|
||||
class="ml-2"
|
||||
@click="dataStore.createNewItem('inventoryitems',itemInfo);
|
||||
itemInfo = {
|
||||
name: null,
|
||||
description: null,
|
||||
quantity: 0
|
||||
}"
|
||||
>
|
||||
Erstellen + Neu
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="cancelEditorCreate"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click=" router.push(`/inventoryitems/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
:items="[{label: 'Informationen'},{label: 'Dokumente'},{label: 'Überprüfungen'}]"
|
||||
v-if="itemInfo && mode === 'show'"
|
||||
class="p-5"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<div v-if="item.label === 'Informationen'" class="flex-row flex mt-5">
|
||||
<div class="w-1/2 mr-5">
|
||||
<UCard>
|
||||
<UAlert
|
||||
v-if="itemInfo.archived"
|
||||
color="rose"
|
||||
variant="outline"
|
||||
title="Objekt archiviert"
|
||||
icon="i-heroicons-light-bulb"
|
||||
class="mb-5"
|
||||
/>
|
||||
<table class="w-full">
|
||||
<tr>
|
||||
<td>Name: </td>
|
||||
<td>{{itemInfo.name}}</td>
|
||||
</tr>
|
||||
<tr v-if="itemInfo.currentSpace">
|
||||
<td>Lagerplatz: </td>
|
||||
<td>{{dataStore.getSpaceById(itemInfo.currentSpace).spaceNumber}} - {{dataStore.getSpaceById(itemInfo.currentSpace).description}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Seriennummer:</td>
|
||||
<td>{{itemInfo.serialNumber}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Menge:</td>
|
||||
<td>{{itemInfo.quantity > 0 ? itemInfo.quantity : 'Einzelarktikel'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Artikelnummer:</td>
|
||||
<td>{{itemInfo.articleNumber}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Hersteller:</td>
|
||||
<td>{{itemInfo.manufacturer}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Herstellernummer:</td>
|
||||
<td>{{itemInfo.manufacturerNumber}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Lieferant:</td>
|
||||
<td>{{itemInfo.vendor ? itemInfo.vendor.name : ''}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Kaufdatum:</td>
|
||||
<td>{{itemInfo.purchaseDate ? dayjs(itemInfo.purchaseDate).format("DD.MM.YYYY") : ''}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Wert bei Kauf:</td>
|
||||
<td>{{itemInfo.purchasePrice ? itemInfo.purchasePrice.toFixed(2).replace(".",",") + " €" : ''}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Aktueller Wert:</td>
|
||||
<td>{{itemInfo.currentValue ? itemInfo.currentValue.toFixed(2).replace(".",",") + " €" : ''}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Beschreibung:</td>
|
||||
<td>{{itemInfo.description}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</UCard>
|
||||
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<UCard>
|
||||
<HistoryDisplay
|
||||
type="inventoryitem"
|
||||
v-if="itemInfo"
|
||||
render-headline
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</UCard>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Dokumente'">
|
||||
<UCard>
|
||||
<DocumentUpload
|
||||
type="inventoryitem"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
|
||||
<DocumentList :documents="dataStore.getDocumentsByProfileId(itemInfo.id)"/>
|
||||
</UCard>
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Überprüfungen'">
|
||||
<UCard>
|
||||
<UTable
|
||||
:rows="itemInfo.checks"
|
||||
:columns="[{key:'name',label: 'Name'},{key:'rhythm',label: 'Rhythmus'},{key:'description',label: 'Beschreibung'}]"
|
||||
class="w-full"
|
||||
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
|
||||
@select="(i) => router.push(`/checks/show/${i.id}`) "
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Überprüfungen anzuzeigen' }"
|
||||
>
|
||||
<template #rhythm-data="{row}">
|
||||
{{row.distance}}
|
||||
<span v-if="row.distanceUnit === 'dayjs'">Tage</span>
|
||||
<span v-if="row.distanceUnit === 'years'">Jahre</span>
|
||||
</template>
|
||||
</UTable>
|
||||
</UCard>
|
||||
</div>
|
||||
</template>
|
||||
</UTabs>
|
||||
<UForm
|
||||
v-else-if="mode == 'edit' || mode == 'create'"
|
||||
class="p-5"
|
||||
>
|
||||
<div class="flex flex-row">
|
||||
<div class="w-1/2 mr-5">
|
||||
<UDivider>
|
||||
Allgemeines
|
||||
</UDivider>
|
||||
<UFormGroup
|
||||
label="Name:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.name"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Artikelnummer:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.articleNumber"
|
||||
placeholder="Leer lassen für automatische generierte Nummer"
|
||||
/>
|
||||
</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="Seriennummer:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.serialNumber"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Menge:"
|
||||
:help="itemInfo.serialNumber ? 'Menge deaktiviert durch Eingabe der Seriennummer' : 'Für Einzelartikel Menge gleich 0'"
|
||||
>
|
||||
<UInput
|
||||
type="number"
|
||||
v-model="itemInfo.quantity"
|
||||
:disabled="itemInfo.serialNumber"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<UDivider>
|
||||
Anschaffung
|
||||
</UDivider>
|
||||
<UFormGroup
|
||||
label="Hersteller:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.manufacturer"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Herstellernr.:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.manufacturerNumber"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Lieferant:"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="dataStore.vendors"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
searchable
|
||||
:search-attributes="['name']"
|
||||
v-model="itemInfo.vendor"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Kaufdatum:"
|
||||
>
|
||||
<UPopover :popper="{ placement: 'bottom-start' }">
|
||||
<UButton
|
||||
icon="i-heroicons-calendar-days-20-solid"
|
||||
:label="itemInfo.purchaseDate ? dayjs(itemInfo.purchaseDate).format('DD.MM.YYYY') : 'Datum auswählen'"
|
||||
variant="outline"
|
||||
/>
|
||||
|
||||
<template #panel="{ close }">
|
||||
<LazyDatePicker v-model="itemInfo.purchaseDate" @close="close" />
|
||||
</template>
|
||||
</UPopover>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Wert bei Kauf:"
|
||||
>
|
||||
<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>
|
||||
<UFormGroup
|
||||
label="Aktueller Wert:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.currentValue"
|
||||
type="number"
|
||||
steps="0.01"
|
||||
>
|
||||
<template #trailing>
|
||||
<span class="text-gray-500 dark:text-gray-400 text-xs">EUR</span>
|
||||
</template>
|
||||
</UInput>
|
||||
</UFormGroup>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<UFormGroup
|
||||
label="Beschreibung:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.description"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</UForm>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
td {
|
||||
border-bottom: 1px solid lightgrey;
|
||||
vertical-align: top;
|
||||
padding-bottom: 0.15em;
|
||||
padding-top: 0.15em;
|
||||
}
|
||||
</style>
|
||||
130
deprecated/inventoryitems/index.vue
Normal file
130
deprecated/inventoryitems/index.vue
Normal file
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<UDashboardNavbar title="Inventar" :badge="filteredRows.length">
|
||||
<template #right>
|
||||
<UInput
|
||||
id="searchinput"
|
||||
v-model="searchString"
|
||||
icon="i-heroicons-funnel"
|
||||
autocomplete="off"
|
||||
placeholder="Suche..."
|
||||
class="hidden lg:block"
|
||||
@keydown.esc="$event.target.blur()"
|
||||
>
|
||||
<template #trailing>
|
||||
<UKbd value="/" />
|
||||
</template>
|
||||
</UInput>
|
||||
|
||||
<UButton @click="router.push(`/inventoryitems/create`)">+ Inventarartikel</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
|
||||
<UDashboardToolbar>
|
||||
<template #right>
|
||||
<USelectMenu
|
||||
v-model="selectedColumns"
|
||||
icon="i-heroicons-adjustments-horizontal-solid"
|
||||
:options="templateColumns"
|
||||
multiple
|
||||
class="hidden lg:block"
|
||||
by="key"
|
||||
>
|
||||
<template #label>
|
||||
Spalten
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</template>
|
||||
</UDashboardToolbar>
|
||||
|
||||
<UTable
|
||||
:rows="filteredRows"
|
||||
:columns="columns"
|
||||
class="w-full"
|
||||
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
|
||||
@select="(i) => router.push(`/inventoryitems/show/${i.id}`) "
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Inventarartikel anzuzeigen' }"
|
||||
v-model:sort="sortConfig"
|
||||
sort-mode="manual"
|
||||
@update:sort="setupPage"
|
||||
>
|
||||
|
||||
|
||||
</UTable>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {sort} from "fast-sort"
|
||||
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'/': () => {
|
||||
//console.log(searchinput)
|
||||
//searchinput.value.focus()
|
||||
document.getElementById("searchinput").focus()
|
||||
},
|
||||
'+': () => {
|
||||
router.push("/tasks/create")
|
||||
}
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
const items = ref([])
|
||||
|
||||
const sortConfig = ref({
|
||||
column: "articleNumber",
|
||||
direction: "desc"
|
||||
})
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("inventoryitems","*")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const templateColumns = [
|
||||
{
|
||||
key: "articleNumber",
|
||||
label: "Artikelnummer",
|
||||
sortable: true
|
||||
},{
|
||||
key: "name",
|
||||
label: "Name",
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
key: "description",
|
||||
label: "Beschreibung",
|
||||
sortable: true
|
||||
}
|
||||
]
|
||||
const selectedColumns = ref(templateColumns)
|
||||
const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
|
||||
|
||||
|
||||
|
||||
const searchString = ref('')
|
||||
const filteredRows = computed(() => {
|
||||
|
||||
let sorted = []
|
||||
|
||||
if(sortConfig.value.direction === "asc"){
|
||||
sorted = sort(items.value).asc(i => i[sortConfig.value.column])
|
||||
} else {
|
||||
sorted = sort(items.value).desc(i => i[sortConfig.value.column])
|
||||
}
|
||||
|
||||
return useListFilter(searchString.value, sorted)
|
||||
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
321
deprecated/spaces/[mode]/[[id]].vue
Normal file
321
deprecated/spaces/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,321 @@
|
||||
<script setup>
|
||||
import axios from "axios";
|
||||
import ZebraBrowserPrintWrapper from "zebra-browser-print-wrapper"
|
||||
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({
|
||||
spaceNumber: "",
|
||||
address: {
|
||||
streetNumber: "",
|
||||
city: "",
|
||||
zip:""
|
||||
}
|
||||
})
|
||||
const spaceTypes = ["Standort","Regalplatz", "Kiste", "Palettenplatz", "Sonstiges"]
|
||||
const spaceProducts = ref([])
|
||||
const spaceMovements = ref([])
|
||||
|
||||
const spaces = ref([])
|
||||
|
||||
//Functions
|
||||
const setupPage = async () => {
|
||||
if(mode.value === "show"){
|
||||
itemInfo.value = await useSupabaseSelectSingle("spaces",route.params.id,"*, parentSpace(*), inventoryitems(*)")
|
||||
|
||||
spaceMovements.value = await dataStore.getMovementsBySpace(itemInfo.value.id)
|
||||
spaceProducts.value = []
|
||||
spaceMovements.value.forEach(movement => {
|
||||
if(spaceProducts.value.filter(product => product.id === movement.productId).length === 0) spaceProducts.value.push(dataStore.getProductById(movement.productId))
|
||||
})
|
||||
|
||||
|
||||
} else if(mode.value === "edit") {
|
||||
itemInfo.value = await useSupabaseSelectSingle("spaces",route.params.id,"*")
|
||||
}
|
||||
|
||||
if(mode.value === "edit" || mode.value === "create"){
|
||||
if(itemInfo.value){
|
||||
spaces.value = (await useSupabaseSelect("spaces",'*')).filter(i => i.id !== itemInfo.value.id)
|
||||
} else {
|
||||
spaces.value = (await useSupabaseSelect("spaces",'*'))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(itemInfo.value) {
|
||||
router.push(`/spaces/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/spaces/`)
|
||||
}
|
||||
}
|
||||
|
||||
function getSpaceProductCount(productId) {
|
||||
let productMovements = spaceMovements.value.filter(movement => movement.productId === productId)
|
||||
let count = 0;
|
||||
productMovements.forEach(movement => count += movement.quantity)
|
||||
|
||||
return count
|
||||
}
|
||||
|
||||
/*
|
||||
const printSpaceLabel = async () => {
|
||||
axios
|
||||
.post(`http://${profileStore.ownTenant.value.labelPrinterIp}/pstprnt`, `^XA^FO10,20^BCN,100^FD${itemInfo.value.spaceNumber}^XZ` )
|
||||
.then(console.log)
|
||||
.catch(console.log)
|
||||
}
|
||||
*/
|
||||
|
||||
const cityLoading = ref(false)
|
||||
const setCityByZip = async () => {
|
||||
cityLoading.value = true
|
||||
itemInfo.value.address.city = await useZipCheck(itemInfo.value.address.zip)
|
||||
cityLoading.value = false
|
||||
}
|
||||
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar :title="itemInfo ? itemInfo.name : (mode === 'create' ? 'Lagerplatz erstellen' : 'Lagerplatz bearbeiten')">
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/spaces`)"
|
||||
>
|
||||
Lagerplätze
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
:class="['text-xl','font-medium']"
|
||||
>{{itemInfo ? `Lagerplatz: ${itemInfo.spaceNumber} - ${itemInfo.description}` : (mode === 'create' ? 'Lagerplatz erstellen' : 'Lagerplatz bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@click="dataStore.updateItem('spaces',itemInfo)"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else-if="mode === 'create'"
|
||||
@click="dataStore.createNewItem('spaces',itemInfo)"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="cancelEditorCreate"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
v-if="mode === 'edit' || mode === 'create'"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click=" router.push(`/spaces/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
<UDashboardPanelContent>
|
||||
<UTabs
|
||||
:items="[{label: 'Informationen'},{label: 'Bestand'},{label: 'Inventarartikel'}]"
|
||||
v-if="itemInfo && mode === 'show'"
|
||||
class="p-5"
|
||||
>
|
||||
<template #item="{item}">
|
||||
<div v-if="item.label === 'Informationen'" class="flex mt-5">
|
||||
<div class="w-1/2 mr-5">
|
||||
<UCard>
|
||||
<div class="truncate">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Typ:</td>
|
||||
<td>{{itemInfo.type}}</td>
|
||||
</tr>
|
||||
<tr v-if="itemInfo.type !== 'Standort'">
|
||||
<td>Übergeordneter Lagerplatz:</td>
|
||||
<td><router-link v-if="itemInfo.parentSpace" :to="`/spaces/show/${itemInfo.parentSpace.id}`">{{itemInfo.parentSpace.spaceNumber}} - {{itemInfo.parentSpace.description}}</router-link></td>
|
||||
</tr>
|
||||
<tr v-if="itemInfo.type === 'Standort'">
|
||||
<td>Adresse:</td>
|
||||
<td>{{`${itemInfo.address.streetNumber}, ${itemInfo.address.zip} ${itemInfo.address.city}`}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Beschreibung:</td>
|
||||
<td>{{itemInfo.description}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<UCard>
|
||||
<HistoryDisplay
|
||||
type="space"
|
||||
v-if="itemInfo"
|
||||
render-headline
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</UCard>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Bestand'">
|
||||
<UCard>
|
||||
<div v-if="spaceProducts.length > 0">
|
||||
|
||||
<table class="w-full">
|
||||
<tr>
|
||||
<th class="text-left">Artikel in diesem Lagerplatz</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>
|
||||
</UCard>
|
||||
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Inventarartikel'">
|
||||
<UAlert
|
||||
description="Hier werden alle Inventarartikel in diesem Lagerplatz aufgelistet"
|
||||
color="primary"
|
||||
variant="outline"
|
||||
/>
|
||||
<UTable
|
||||
:rows="itemInfo.inventoryitems"
|
||||
:columns="[{label:'Name',key:'name'}]"
|
||||
@select="(row) => router.push(`/inventoryitems/show/${row.id}`)"
|
||||
>
|
||||
|
||||
</UTable>
|
||||
</div>
|
||||
</template>
|
||||
</UTabs>
|
||||
<UForm
|
||||
v-else-if="mode === 'edit' || mode === 'create'"
|
||||
class="p-5"
|
||||
>
|
||||
<div class="flex flex-row">
|
||||
<div class="w-1/2 mr-5">
|
||||
<UDivider>
|
||||
Allgemeines
|
||||
</UDivider>
|
||||
<UFormGroup
|
||||
label="Typ:"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="spaceTypes"
|
||||
v-model="itemInfo.type"
|
||||
>
|
||||
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Übergeordneter Lagerplatz:"
|
||||
v-if="itemInfo.type !== 'Standort'"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="spaces"
|
||||
option-attribute="spaceNumber"
|
||||
value-attribute="id"
|
||||
v-model="itemInfo.parentSpace"
|
||||
>
|
||||
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
</div>
|
||||
<div class="w-1/2" v-if="itemInfo.type === 'Standort'">
|
||||
<UDivider>
|
||||
Ort
|
||||
</UDivider>
|
||||
<UFormGroup
|
||||
label="Straße + Hausnummer:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.address.streetNumber"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="PLZ + Ort:"
|
||||
>
|
||||
<InputGroup class="w-full">
|
||||
<UInput
|
||||
v-model="itemInfo.address.zip"
|
||||
placeholder="PLZ"
|
||||
@focusout="setCityByZip"
|
||||
/>
|
||||
<UInput
|
||||
v-model="itemInfo.address.city"
|
||||
placeholder="Ort"
|
||||
class="flex-auto"
|
||||
:disabled="cityLoading"
|
||||
|
||||
/>
|
||||
</InputGroup>
|
||||
|
||||
</UFormGroup>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<UFormGroup
|
||||
label="Beschreibung:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.description"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</UForm>
|
||||
</UDashboardPanelContent>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
td,th {
|
||||
padding-right: 2em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
td {
|
||||
border-bottom: 1px solid lightgrey;
|
||||
vertical-align: top;
|
||||
padding-bottom: 0.15em;
|
||||
padding-top: 0.15em;
|
||||
}
|
||||
</style>
|
||||
139
deprecated/spaces/index.vue
Normal file
139
deprecated/spaces/index.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<UDashboardNavbar title="Lagerplätze" :badge="filteredRows.length">
|
||||
<template #right>
|
||||
<UInput
|
||||
id="searchinput"
|
||||
v-model="searchString"
|
||||
icon="i-heroicons-funnel"
|
||||
autocomplete="off"
|
||||
placeholder="Suche..."
|
||||
class="hidden lg:block"
|
||||
@keydown.esc="$event.target.blur()"
|
||||
>
|
||||
<template #trailing>
|
||||
<UKbd value="/" />
|
||||
</template>
|
||||
</UInput>
|
||||
|
||||
<UButton @click="router.push(`/spaces/create`)">+ Lagerplatz</UButton>
|
||||
</template>
|
||||
</UDashboardNavbar>
|
||||
|
||||
<UDashboardToolbar>
|
||||
<template #right>
|
||||
<USelectMenu
|
||||
v-model="selectedColumns"
|
||||
icon="i-heroicons-adjustments-horizontal-solid"
|
||||
:options="templateColumns"
|
||||
multiple
|
||||
class="hidden lg:block"
|
||||
by="key"
|
||||
>
|
||||
<template #label>
|
||||
Spalten
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</template>
|
||||
</UDashboardToolbar>
|
||||
<UTable
|
||||
:rows="filteredRows"
|
||||
:columns="columns"
|
||||
class="w-full"
|
||||
:ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
|
||||
@select="(i) => router.push(`/spaces/show/${i.id}`) "
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Lagerplätze anzuzeigen' }"
|
||||
>
|
||||
<template #spaceNumber-data="{row}">
|
||||
<span v-if="row === filteredRows[selectedItem]" class="text-primary-500 font-bold">{{row.spaceNumber}}</span>
|
||||
<span v-else>{{row.spaceNumber}}</span>
|
||||
</template>
|
||||
<template #address-data="{row}">
|
||||
<span>{{row.address.streetNumber ? `${row.address.streetNumber}, ${row.address.zip}${row.address.city}` : ''}}</span>
|
||||
</template>
|
||||
</UTable>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'/': () => {
|
||||
//console.log(searchinput)
|
||||
//searchinput.value.focus()
|
||||
document.getElementById("searchinput").focus()
|
||||
},
|
||||
'+': () => {
|
||||
router.push("/spaces/create")
|
||||
},
|
||||
'Enter': {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
router.push(`/spaces/show/${filteredRows.value[selectedItem.value].id}`)
|
||||
}
|
||||
},
|
||||
'arrowdown': () => {
|
||||
if(selectedItem.value < filteredRows.value.length - 1) {
|
||||
selectedItem.value += 1
|
||||
} else {
|
||||
selectedItem.value = 0
|
||||
}
|
||||
},
|
||||
'arrowup': () => {
|
||||
if(selectedItem.value === 0) {
|
||||
selectedItem.value = filteredRows.value.length - 1
|
||||
} else {
|
||||
selectedItem.value -= 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("spaces","*","spaceNumber")
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const templateColumns = [
|
||||
{
|
||||
key: 'spaceNumber',
|
||||
label: "Lagerplatznr.",
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
key: "type",
|
||||
label: "Typ",
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
key: "description",
|
||||
label: "Beschreibung",
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
key: "address",
|
||||
label: "Adresse",
|
||||
sortable: true
|
||||
}
|
||||
]
|
||||
const selectedColumns = ref(templateColumns)
|
||||
const columns = computed(() => templateColumns.filter((column) => selectedColumns.value.includes(column)))
|
||||
|
||||
const searchString = ref('')
|
||||
const filteredRows = computed(() => {
|
||||
return useSearch(searchString.value, items.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
453
deprecated/users/[mode]/[[id]].vue
Normal file
453
deprecated/users/[mode]/[[id]].vue
Normal file
@@ -0,0 +1,453 @@
|
||||
<script setup>
|
||||
import dayjs from "dayjs";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
|
||||
//TODO: Build User Page
|
||||
|
||||
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const profileStore = useProfileStore()
|
||||
const supabase = useSupabaseClient()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
|
||||
let currentItem = null
|
||||
|
||||
//Working
|
||||
const mode = ref(route.params.mode || "show")
|
||||
const itemInfo = ref({})
|
||||
|
||||
const tabItems = [
|
||||
{
|
||||
label: "Informationen"
|
||||
},{
|
||||
label: "Zeiterfassung"
|
||||
},{
|
||||
label: "Rechte"
|
||||
},
|
||||
]
|
||||
|
||||
const timeSelection = ref("Heute")
|
||||
const timeColumns = [
|
||||
{
|
||||
key: "state",
|
||||
label: "Status"
|
||||
},{
|
||||
key: "user",
|
||||
label: "Benutzer"
|
||||
},{
|
||||
key: "start",
|
||||
label: "Start"
|
||||
},{
|
||||
key: "end",
|
||||
label: "Ende"
|
||||
},{
|
||||
key: "notes",
|
||||
label: "Notizen"
|
||||
},{
|
||||
key: "projectId",
|
||||
label: "Projekt"
|
||||
},{
|
||||
key: "duration",
|
||||
label: "Dauer"
|
||||
},
|
||||
]
|
||||
|
||||
const filteredTimes = computed(() => {
|
||||
let rows = dataStore.times
|
||||
rows = rows.filter(i => i.user === currentItem.id)
|
||||
|
||||
if(timeSelection.value === 'Heute') {
|
||||
rows = rows.filter(i => dayjs().isSame(i.start,'day'))
|
||||
} else if(timeSelection.value === 'Diese Woche') {
|
||||
rows = rows.filter(i => dayjs().isSame(i.start,'week'))
|
||||
} else if(timeSelection.value === 'Dieser Monat') {
|
||||
rows = rows.filter(i => dayjs().isSame(i.start,'month'))
|
||||
} else if(timeSelection.value === 'Dieses Jahr') {
|
||||
rows = rows.filter(i => dayjs().isSame(i.start,'year'))
|
||||
} else if(timeSelection.value === 'Letztes Jahr') {
|
||||
rows = rows.filter(i => dayjs().subtract(1,'year').isSame(i.start,'year'))
|
||||
}
|
||||
|
||||
return rows
|
||||
})
|
||||
|
||||
//Functions
|
||||
const setupPage = () => {
|
||||
if(mode.value === "show" || mode.value === "edit"){
|
||||
currentItem = profileStore.getProfileById(useRoute().params.id)
|
||||
}
|
||||
|
||||
itemInfo.value = currentItem
|
||||
}
|
||||
|
||||
const editItem = async () => {
|
||||
router.push(`/users/edit/${currentItem.id}`)
|
||||
setupPage()
|
||||
}
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
mode.value = "show"
|
||||
itemInfo.value = {
|
||||
id: 0,
|
||||
infoData: {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const getDuration = (time) => {
|
||||
const dez = dayjs(time.end).diff(time.start,'hour',true).toFixed(2)
|
||||
const hours = Math.floor(dez)
|
||||
const minutes = Math.floor((dez - hours) * 60)
|
||||
return {
|
||||
dezimal: dez,
|
||||
hours: hours,
|
||||
minutes: minutes,
|
||||
composed: `${hours}:${minutes}`
|
||||
}
|
||||
}
|
||||
|
||||
const getSelectionSum = computed(() => {
|
||||
let times = filteredTimes.value
|
||||
let sum = 0
|
||||
let sumEntwurf = 0
|
||||
let sumEingereicht = 0
|
||||
let sumBestaetigt = 0
|
||||
|
||||
times.forEach(time => {
|
||||
let duration = getDuration(time)
|
||||
|
||||
sum += Number(duration.dezimal)
|
||||
|
||||
if(time.state === 'Entwurf') {
|
||||
sumEntwurf += Number(duration.dezimal)
|
||||
} else if(time.state === 'Eingereicht') {
|
||||
sumEingereicht += Number(duration.dezimal)
|
||||
} else if(time.state === 'Bestätigt') {
|
||||
sumBestaetigt += Number(duration.dezimal)
|
||||
}
|
||||
})
|
||||
|
||||
sum = sum.toFixed(2)
|
||||
sumEntwurf = sumEntwurf.toFixed(2)
|
||||
sumEingereicht = sumEingereicht.toFixed(2)
|
||||
sumBestaetigt = sumBestaetigt.toFixed(2)
|
||||
|
||||
return {
|
||||
sum,
|
||||
sumEntwurf,
|
||||
sumEingereicht,
|
||||
sumBestaetigt
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
setupPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<UCard v-if="currentItem && mode == 'show'" >
|
||||
<template #header>
|
||||
{{currentItem.fullName}}
|
||||
</template>
|
||||
|
||||
<UTabs :items="tabItems">
|
||||
<template #item="{item}">
|
||||
<div
|
||||
v-if="item.label === 'Informationen'"
|
||||
class="w-full"
|
||||
>
|
||||
<InputGroup class="w-full">
|
||||
<div class="w-1/2 mr-5">
|
||||
<UFormGroup
|
||||
label="Anrede"
|
||||
>
|
||||
<UInput/>
|
||||
</UFormGroup>
|
||||
|
||||
<InputGroup>
|
||||
<UFormGroup
|
||||
label="Vorname:"
|
||||
class="flex-auto"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.firstName"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Nachnahme:"
|
||||
class="flex-auto"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.lastName"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</InputGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Geburtsdatum"
|
||||
>
|
||||
<UInput/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Benutzername"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.username"
|
||||
disabled
|
||||
/>
|
||||
</UFormGroup>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<UFormGroup
|
||||
label="E-Mail"
|
||||
>
|
||||
<UInput/>
|
||||
</UFormGroup>
|
||||
|
||||
<InputGroup>
|
||||
<UFormGroup
|
||||
label="Telefonnummer:"
|
||||
class="w-1/2"
|
||||
>
|
||||
<UInput/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Mobilfunknummer:"
|
||||
class="w-1/2"
|
||||
>
|
||||
<UInput/>
|
||||
</UFormGroup>
|
||||
</InputGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Straße & Hausnummer"
|
||||
>
|
||||
<UInput
|
||||
class="flex-auto"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<InputGroup>
|
||||
<UFormGroup
|
||||
label="Postleitzahl:"
|
||||
class="w-40"
|
||||
>
|
||||
<UInput/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Ort:"
|
||||
class="flex-auto"
|
||||
>
|
||||
<UInput/>
|
||||
</UFormGroup>
|
||||
</InputGroup>
|
||||
</div>
|
||||
</InputGroup>
|
||||
<UButton
|
||||
class="mt-5"
|
||||
@click="dataStore.updateItem('users',itemInfo)"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
|
||||
</div>
|
||||
<div v-else-if="item.label === 'Zeiterfassung'">
|
||||
<UButtonGroup>
|
||||
<UButton
|
||||
@click="timeSelection = 'Heute'"
|
||||
:variant="timeSelection === 'Heute' ? 'solid' : 'outline'"
|
||||
>
|
||||
Heute
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="timeSelection = 'Diese Woche'"
|
||||
:variant="timeSelection === 'Diese Woche' ? 'solid' : 'outline'"
|
||||
>
|
||||
Diese Woche
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="timeSelection = 'Dieser Monat'"
|
||||
:variant="timeSelection === 'Dieser Monat' ? 'solid' : 'outline'"
|
||||
>
|
||||
Dieser Monat
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="timeSelection = 'Dieses Jahr'"
|
||||
:variant="timeSelection === 'Dieses Jahr' ? 'solid' : 'outline'"
|
||||
>
|
||||
Dieses Jahr
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="timeSelection = 'Letztes Jahr'"
|
||||
:variant="timeSelection === 'Letztes Jahr' ? 'solid' : 'outline'"
|
||||
color="rose"
|
||||
>
|
||||
Letztes Jahr
|
||||
</UButton>
|
||||
</UButtonGroup>
|
||||
<UButton
|
||||
class="ml-3"
|
||||
to="/employees/timetracking"
|
||||
>
|
||||
Zur Zeiterfassung
|
||||
</UButton>
|
||||
|
||||
<InputGroup class="w-full">
|
||||
<div>
|
||||
Summe: {{getSelectionSum.sum}}<br>
|
||||
Summe Entwurf: {{getSelectionSum.sumEntwurf}}<br>
|
||||
Summe Eingereicht: {{getSelectionSum.sumEingereicht}}<br>
|
||||
Summe Bestätigt: {{getSelectionSum.sumBestaetigt}}<br>
|
||||
</div>
|
||||
</InputGroup>
|
||||
|
||||
<UTable
|
||||
:rows="filteredTimes"
|
||||
:columns="timeColumns"
|
||||
>
|
||||
<template #state-data="{row}">
|
||||
<span
|
||||
v-if="row.state === 'Entwurf'"
|
||||
class="text-rose-500"
|
||||
>{{row.state}}</span>
|
||||
<span
|
||||
v-if="row.state === 'Eingereicht'"
|
||||
class="text-cyan-500"
|
||||
>{{row.state}}</span>
|
||||
<span
|
||||
v-if="row.state === 'Bestätigt'"
|
||||
class="text-primary-500"
|
||||
>{{row.state}}</span>
|
||||
</template>
|
||||
<template #start-data="{row}">
|
||||
<div class="text-right">{{dayjs(row.start).format("DD.MM.YY HH:mm")}}</div>
|
||||
</template>
|
||||
<template #end-data="{row}">
|
||||
<div class="text-right">{{dayjs(row.end).format("HH:mm")}}</div>
|
||||
</template>
|
||||
<template #user-data="{row}">
|
||||
{{profileStore.getProfileById(row.user) ? profileStore.getProfileById(row.user).fullName : ""}}
|
||||
</template>
|
||||
<template #duration-data="{row}">
|
||||
<div class="text-right">{{ getDuration(row).composed}} Std</div>
|
||||
</template>
|
||||
<template #projectId-data="{row}">
|
||||
{{dataStore.getProjectById(row.projectId) ? dataStore.getProjectById(row.projectId).name : ""}}
|
||||
</template>
|
||||
</UTable>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
</UTabs>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<template #footer>
|
||||
<UButton
|
||||
v-if="mode == 'show' && currentItem.id"
|
||||
@click="editItem"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
</UCard>
|
||||
<UCard v-else-if="mode == 'edit' || mode == 'create'" >
|
||||
<template #header>
|
||||
{{itemInfo.title}}
|
||||
</template>
|
||||
|
||||
<UFormGroup
|
||||
label="Titel:"
|
||||
>
|
||||
<UInput
|
||||
v-model="itemInfo.title"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Status:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.state"
|
||||
:options="states"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Kundennummer:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.customer"
|
||||
:options="dataStore.customers"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
searchable
|
||||
: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="Beschreibung:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.description"
|
||||
/>
|
||||
</UFormGroup>
|
||||
|
||||
|
||||
<template #footer>
|
||||
<UButton
|
||||
v-if="mode == 'edit'"
|
||||
@click="dataStore.updateItem('users',{...itemInfo, fullName: `${itemInfo.firstName} ${itemInfo.lastName}`})"
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<!-- <UButton
|
||||
v-else-if="mode == 'create'"
|
||||
@click="dataStore.createItem()"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>-->
|
||||
<UButton
|
||||
@click="cancelEditorCreate"
|
||||
color="red"
|
||||
class="ml-2"
|
||||
>
|
||||
Abbrechen
|
||||
</UButton>
|
||||
</template>
|
||||
|
||||
</UCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
43
deprecated/users/index.vue
Normal file
43
deprecated/users/index.vue
Normal file
@@ -0,0 +1,43 @@
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
|
||||
const columns = [
|
||||
{
|
||||
key:"fullName",
|
||||
label: "Name",
|
||||
},/*
|
||||
{
|
||||
key: "username",
|
||||
label: "Benutzername"
|
||||
},*/
|
||||
{
|
||||
key: "role",
|
||||
label: "Rolle"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<UTable
|
||||
:rows="dataStore.profiles"
|
||||
:columns="columns"
|
||||
@select="(item) => router.push(`/users/show/${item.id}`)"
|
||||
>
|
||||
|
||||
</UTable>
|
||||
|
||||
<DevOnly>
|
||||
{{dataStore.profiles}}
|
||||
</DevOnly>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user