Many Changes in Navigation, Shortcuts, Search and Data Pulling directly from Supabase
This commit is contained in:
@@ -3,11 +3,28 @@ import dayjs from "dayjs";
|
||||
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||
import DocumentUpload from "~/components/DocumentUpload.vue";
|
||||
import DocumentList from "~/components/DocumentList.vue";
|
||||
import {useSupabaseSelectSingle} from "~/composables/useSupabase.js";
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
})
|
||||
|
||||
defineShortcuts({
|
||||
'backspace': () => {
|
||||
router.push("/projects")
|
||||
},
|
||||
'arrowleft': () => {
|
||||
if(openTab.value > 0){
|
||||
openTab.value -= 1
|
||||
}
|
||||
},
|
||||
'arrowright': () => {
|
||||
if(openTab.value < 3) {
|
||||
openTab.value += 1
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const supabase = useSupabaseClient()
|
||||
const user = useSupabaseUser()
|
||||
@@ -16,7 +33,7 @@ const router = useRouter()
|
||||
const toast = useToast()
|
||||
const id = ref(route.params.id ? route.params.id : null )
|
||||
|
||||
let currentItem = ref(null)
|
||||
const openTab = ref(0)
|
||||
|
||||
const tabItems = [
|
||||
{
|
||||
@@ -87,13 +104,11 @@ const tags = dataStore.getDocumentTags
|
||||
|
||||
|
||||
//Functions
|
||||
const setupPage = () => {
|
||||
const setupPage = async() => {
|
||||
if(mode.value === "show" || mode.value === "edit"){
|
||||
currentItem.value = dataStore.getProjectById(Number(useRoute().params.id))
|
||||
itemInfo.value = await useSupabaseSelectSingle("projects",route.params.id,"*, customer(*), plant(*)")//dataStore.getProjectById(Number(useRoute().params.id))
|
||||
}
|
||||
|
||||
if(mode.value === "edit") itemInfo.value = currentItem.value
|
||||
|
||||
if(mode.value === "create") {
|
||||
let query = route.query
|
||||
|
||||
@@ -104,12 +119,14 @@ const setupPage = () => {
|
||||
itemInfo.value.customer = dataStore.getPlantById(itemInfo.value.plant).customer
|
||||
}
|
||||
}
|
||||
if(currentItem.value) oldItemInfo.value = JSON.parse(JSON.stringify(currentItem.value))
|
||||
if(itemInfo.value) oldItemInfo.value = JSON.parse(JSON.stringify(itemInfo.value))
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const cancelEditorCreate = () => {
|
||||
if(currentItem.value) {
|
||||
router.push(`/projects/show/${currentItem.value.id}`)
|
||||
if(itemInfo.value) {
|
||||
router.push(`/projects/show/${itemInfo.value.id}`)
|
||||
} else {
|
||||
router.push(`/projects/`)
|
||||
}
|
||||
@@ -117,7 +134,7 @@ const cancelEditorCreate = () => {
|
||||
|
||||
const projectHours = () => {
|
||||
let hours = 0
|
||||
dataStore.getTimesByProjectId(currentItem.value.id).forEach(item => {
|
||||
dataStore.getTimesByProjectId(itemInfo.value.id).forEach(item => {
|
||||
hours += Number(dayjs(item.end).diff(item.start,'hour',true).toFixed(2))
|
||||
})
|
||||
|
||||
@@ -150,7 +167,7 @@ const projectHours = () => {
|
||||
}])*/
|
||||
const phasesTemplateSelected = ref(dataStore.phasesTemplates[0].id)
|
||||
const changeActivePhase = (phase) => {
|
||||
currentItem.value.phases = currentItem.value.phases.map(p => {
|
||||
itemInfo.value.phases = itemInfo.value.phases.map(p => {
|
||||
if(p.active) delete p.active
|
||||
|
||||
if(p.label === phase.label) p.active = true
|
||||
@@ -163,19 +180,34 @@ const changeActivePhase = (phase) => {
|
||||
}
|
||||
|
||||
const savePhases = () => {
|
||||
dataStore.updateItem("projects", currentItem.value)
|
||||
dataStore.updateItem("projects", itemInfo.value)
|
||||
}
|
||||
|
||||
const loadPhases = async () => {
|
||||
currentItem.value.phases = dataStore.phasesTemplates.find(i => i.id === phasesTemplateSelected.value).initialPhases
|
||||
await dataStore.updateItem("projects", currentItem.value)
|
||||
itemInfo.value.phases = dataStore.phasesTemplates.find(i => i.id === phasesTemplateSelected.value).initialPhases
|
||||
await dataStore.updateItem("projects", itemInfo.value)
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UDashboardNavbar :title="currentItem ? currentItem.name : (mode === 'create' ? 'Projekt erstellen' : 'Projekt bearbeiten')">
|
||||
<UDashboardNavbar :title="itemInfo ? itemInfo.name : (mode === 'create' ? 'Projekt erstellen' : 'Projekt bearbeiten')">
|
||||
<template #left>
|
||||
<UButton
|
||||
icon="i-heroicons-chevron-left"
|
||||
variant="outline"
|
||||
@click="router.push(`/projects`)"
|
||||
>
|
||||
Projekte
|
||||
</UButton>
|
||||
</template>
|
||||
<template #center>
|
||||
<h1
|
||||
v-if="itemInfo"
|
||||
class="text-xl font-medium"
|
||||
>{{itemInfo.name ? `Projekt: ${itemInfo.name}` : (mode === 'create' ? 'Projekt erstellen' : 'Projekt bearbeiten')}}</h1>
|
||||
</template>
|
||||
<template #right>
|
||||
<UButton
|
||||
v-if="mode === 'edit'"
|
||||
@@ -199,7 +231,7 @@ setupPage()
|
||||
</UButton>
|
||||
<UButton
|
||||
v-if="mode === 'show'"
|
||||
@click="router.push(`/projects/edit/${currentItem.id}`)"
|
||||
@click="router.push(`/projects/edit/${itemInfo.id}`)"
|
||||
>
|
||||
Bearbeiten
|
||||
</UButton>
|
||||
@@ -207,8 +239,9 @@ setupPage()
|
||||
</UDashboardNavbar>
|
||||
<UTabs
|
||||
:items="tabItems"
|
||||
v-if="currentItem && mode == 'show'"
|
||||
v-if="itemInfo.id && mode == 'show'"
|
||||
class="p-5"
|
||||
v-model="openTab"
|
||||
>
|
||||
<template #item="{ item }">
|
||||
<UCard class="mt-5">
|
||||
@@ -217,15 +250,15 @@ setupPage()
|
||||
|
||||
|
||||
<div class="text-wrap">
|
||||
<p>Kunde: <nuxt-link :to="`/customers/show/${currentItem.customer}`">{{dataStore.getCustomerById(currentItem.customer).name}}</nuxt-link></p>
|
||||
<p>Objekt: <nuxt-link :to="`/plants/show/${currentItem.plant}`">{{currentItem.plant ? dataStore.getPlantById(currentItem.plant).name : ""}}</nuxt-link></p>
|
||||
<p class="">Notizen: {{currentItem.notes}}</p>
|
||||
<p>Kunde: <nuxt-link :to="`/customers/show/${itemInfo.customer.id}`">{{itemInfo.customer.name}}</nuxt-link></p>
|
||||
<p>Objekt: <nuxt-link :to="`/plants/show/${itemInfo.plant.id}`">{{itemInfo.plant ? itemInfo.plant.name : ""}}</nuxt-link></p>
|
||||
<p class="">Notizen: {{itemInfo.notes}}</p>
|
||||
</div>
|
||||
|
||||
<UDivider class="my-3"/>
|
||||
<h1 class="font-bold text-lg my-3">Beteiligte Benutzer:</h1>
|
||||
<UAlert
|
||||
v-for="projectUser in currentItem.users"
|
||||
v-for="projectUser in itemInfo.users"
|
||||
:avatar="{ alt: dataStore.getProfileById(projectUser).fullName }"
|
||||
:title="dataStore.getProfileById(projectUser).fullName"
|
||||
class="mb-3"
|
||||
@@ -235,14 +268,14 @@ setupPage()
|
||||
<div v-else-if="item.key === 'historyDisplay'">
|
||||
<HistoryDisplay
|
||||
type="project"
|
||||
v-if="currentItem"
|
||||
:element-id="currentItem.id"
|
||||
v-if="itemInfo"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="item.key === 'phases'" class="space-y-3">
|
||||
<UFormGroup
|
||||
label="Vorlage laden"
|
||||
v-if="currentItem.phases.length === 0"
|
||||
v-if="itemInfo.phases.length === 0"
|
||||
>
|
||||
<InputGroup>
|
||||
<USelectMenu
|
||||
@@ -263,7 +296,7 @@ setupPage()
|
||||
</UFormGroup>
|
||||
|
||||
<UAccordion
|
||||
:items="currentItem.phases"
|
||||
:items="itemInfo.phases"
|
||||
>
|
||||
<template #default="{item,index,open}">
|
||||
<UButton
|
||||
@@ -304,14 +337,14 @@ setupPage()
|
||||
<div v-if="item.key === 'tasks'" class="space-y-3">
|
||||
<Toolbar>
|
||||
<UButton
|
||||
@click="router.push(`/tasks/create?project=${currentItem.id}`)"
|
||||
@click="router.push(`/tasks/create?project=${itemInfo.id}`)"
|
||||
>
|
||||
+ Aufgabe
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
|
||||
<UTable
|
||||
:rows="dataStore.getTasksByProjectId(currentItem.id)"
|
||||
:rows="dataStore.getTasksByProjectId(itemInfo.id)"
|
||||
:columns="[{key: 'name',label: 'Name'},{key: 'categorie',label: 'Kategorie'},{key: 'user',label: 'Benutzer'}]"
|
||||
@select="(row) => router.push(`/tasks/show/${row.id}`)"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine zugehörigen Aufgaben' }"
|
||||
@@ -327,22 +360,22 @@ setupPage()
|
||||
<Toolbar>
|
||||
<DocumentUpload
|
||||
type="project"
|
||||
:element-id="currentItem.id"
|
||||
:element-id="itemInfo.id"
|
||||
/>
|
||||
<UButton
|
||||
@click="router.push(`/createDocument/edit?project=${currentItem.id}&type=quotes&customer=${currentItem.customer}`)"
|
||||
@click="router.push(`/createDocument/edit?project=${itemInfo.id}&type=quotes&customer=${itemInfo.customer.id}`)"
|
||||
>
|
||||
+ Angebot
|
||||
</UButton>
|
||||
<UButton
|
||||
@click="router.push(`/createDocument/edit?project=${currentItem.id}&type=invoices&customer=${currentItem.customer}`)"
|
||||
@click="router.push(`/createDocument/edit?project=${itemInfo.id}&type=invoices&customer=${itemInfo.customer.id}`)"
|
||||
>
|
||||
+ Rechnung
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
|
||||
<UTable
|
||||
:rows="dataStore.getCreatedDocumentsByProject(currentItem.id)"
|
||||
:rows="dataStore.getCreatedDocumentsByProject(itemInfo.id)"
|
||||
:columns="[
|
||||
{
|
||||
label: 'Typ',
|
||||
@@ -371,9 +404,9 @@ setupPage()
|
||||
</template>
|
||||
</UTable>
|
||||
|
||||
<DocumentList :documents="dataStore.getDocumentsByProjectId(currentItem.id)"/>
|
||||
<DocumentList :documents="dataStore.getDocumentsByProjectId(itemInfo.id)"/>
|
||||
<!--
|
||||
{{dataStore.getDocumentsByProjectId(currentItem.id)}}
|
||||
{{dataStore.getDocumentsByProjectId(itemInfo.id)}}
|
||||
-->
|
||||
|
||||
</div>
|
||||
@@ -381,7 +414,7 @@ setupPage()
|
||||
<div v-else-if="item.key === 'timetracking'" class="space-y-3">
|
||||
Projekt Zeit: {{String(projectHours()).replace(".",",")}} Stunden
|
||||
<UTable
|
||||
:rows="dataStore.getTimesByProjectId(currentItem.id)"
|
||||
:rows="dataStore.getTimesByProjectId(itemInfo.id)"
|
||||
:columns="timeTableRows"
|
||||
:empty-state="{ icon: 'i-heroicons-clock', label: 'Noch keine Zeiten in diesem Projekt' }"
|
||||
>
|
||||
@@ -409,7 +442,7 @@ setupPage()
|
||||
</UButton>
|
||||
</Toolbar>
|
||||
<UTable
|
||||
:rows="dataStore.getEventsByProjectId(currentItem.id)"
|
||||
:rows="dataStore.getEventsByProjectId(itemInfo.id)"
|
||||
@select="(i) => router.push(`/events/show/${i.id}`)"
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Termine anzuzeigen' }"
|
||||
:columns="[{key:'title',label:'Titel'},{key:'start',label:'Start'},{key:'end',label:'Ende'},{key:'type',label:'Typ'},{key:'resources',label:'Resourcen'}]"
|
||||
@@ -430,7 +463,7 @@ setupPage()
|
||||
Auf das Projekt gebuchte Artikel:
|
||||
|
||||
<UTable
|
||||
:rows="dataStore.getStocksByProjectId(currentItem.id)"
|
||||
:rows="dataStore.getStocksByProjectId(itemInfo.id)"
|
||||
:columns="[{key:'productId',label:'Artikel'},{key:'stock',label:'Anzahl'}]"
|
||||
@select="(i) => router.push(`/products/show/${i.productId}`)"
|
||||
>
|
||||
@@ -438,6 +471,7 @@ setupPage()
|
||||
{{dataStore.getProductById(row.productId).name}}
|
||||
</template>
|
||||
<template #stock-data="{row}">
|
||||
{{dataStore.getProductById(row.productId)}}
|
||||
{{row.stock}} {{dataStore.units.find(i => i.id === dataStore.getProductById(row.productId).unit).short}}
|
||||
</template>
|
||||
</UTable>
|
||||
|
||||
@@ -56,14 +56,18 @@
|
||||
@select="(i) => router.push(`/projects/show/${i.id}`) "
|
||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Keine Projekte anzuzeigen' }"
|
||||
>
|
||||
<template #name-data="{row}">
|
||||
<span class="text-primary-500 font-bold" v-if="row === filteredRows[selectedItem]">{{row.name}}</span>
|
||||
<span v-else>{{row.name}}</span>
|
||||
</template>
|
||||
<template #phase-data="{row}">
|
||||
{{getActivePhaseLabel(row)}}
|
||||
</template>
|
||||
<template #customer-data="{row}">
|
||||
{{dataStore.getCustomerById(row.customer) ? dataStore.getCustomerById(row.customer).name : ""}}
|
||||
{{row.customer ? row.customer.name : ""}}
|
||||
</template>
|
||||
<template #plant-data="{row}">
|
||||
{{dataStore.getPlantById(row.plant) ? dataStore.getPlantById(row.plant).name : ""}}
|
||||
{{row.plant ? row.plant.name : ""}}
|
||||
</template>
|
||||
<template #users-data="{row}">
|
||||
{{row.users.map(i => dataStore.getProfileById(i).fullName).join(", ")}}
|
||||
@@ -85,12 +89,43 @@ defineShortcuts({
|
||||
},
|
||||
'+': () => {
|
||||
router.push("/projects/create")
|
||||
},
|
||||
'Enter': {
|
||||
usingInput: true,
|
||||
handler: () => {
|
||||
router.push(`/projects/show/${filteredRows.value[selectedItem.value].id}`)
|
||||
}
|
||||
},
|
||||
'arrowdown': () => {
|
||||
if(selectedItem.value < filteredRows.value.length - 1) {
|
||||
selectedItem.value += 1
|
||||
} else {
|
||||
selectedItem.value = 0
|
||||
}
|
||||
},
|
||||
'arrowup': () => {
|
||||
if(selectedItem.value === 0) {
|
||||
selectedItem.value = filteredRows.value.length - 1
|
||||
} else {
|
||||
selectedItem.value -= 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const dataStore = useDataStore()
|
||||
const router = useRouter()
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("projects","*, customer (name), plant(name)")
|
||||
|
||||
console.log(items.value)
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const templateColumns = [
|
||||
{
|
||||
key: "phase",
|
||||
@@ -148,9 +183,7 @@ const searchString = ref('')
|
||||
const showFinished = ref(false)
|
||||
|
||||
const filteredRows = computed(() => {
|
||||
let items = dataStore.projects
|
||||
|
||||
items = items.map(item => {
|
||||
let temp = items.value.map(item => {
|
||||
return {
|
||||
...item,
|
||||
phaseLabel: getActivePhaseLabel(item)
|
||||
@@ -158,16 +191,16 @@ const filteredRows = computed(() => {
|
||||
})
|
||||
|
||||
if(showFinished.value) {
|
||||
items = items.filter(i => i.phaseLabel === "Abgeschlossen")
|
||||
temp = temp.filter(i => i.phaseLabel === "Abgeschlossen")
|
||||
} else {
|
||||
items = items.filter(i => i.phaseLabel !== "Abgeschlossen")
|
||||
temp = temp.filter(i => i.phaseLabel !== "Abgeschlossen")
|
||||
}
|
||||
|
||||
if(!searchString.value) {
|
||||
return items
|
||||
return temp
|
||||
}
|
||||
|
||||
return items.filter(project => {
|
||||
return temp.filter(project => {
|
||||
return Object.values(project).some((value) => {
|
||||
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user