Introduced New Projecttypes and Phase Display
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
<script setup>
|
||||
import dayjs from "dayjs";
|
||||
import HistoryDisplay from "~/components/HistoryDisplay.vue";
|
||||
import DocumentUpload from "~/components/DocumentUpload.vue";
|
||||
import DocumentList from "~/components/DocumentList.vue";
|
||||
|
||||
|
||||
definePageMeta({
|
||||
middleware: "auth"
|
||||
@@ -97,17 +95,18 @@ const itemInfo = ref({
|
||||
const oldItemInfo = ref({})
|
||||
const tags = dataStore.getDocumentTags
|
||||
const phasesTemplates = ref([])
|
||||
const phasesTemplateSelected = ref(null)
|
||||
|
||||
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(*)")
|
||||
@@ -127,12 +126,10 @@ const setupPage = async() => {
|
||||
}
|
||||
if(itemInfo.value) oldItemInfo.value = JSON.parse(JSON.stringify(itemInfo.value))
|
||||
|
||||
phasesTemplates.value = await useSupabaseSelect("phasesTemplates","*","created_at")
|
||||
if(phasesTemplates.value.length > 0) {
|
||||
phasesTemplateSelected.value = phasesTemplates.value[0].id
|
||||
if(!oldItemInfo.value.projecttype) {
|
||||
itemInfo.value.projecttype = projecttypes.value[0].id
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
setupPage()
|
||||
@@ -155,53 +152,65 @@ const projectHours = () => {
|
||||
}
|
||||
|
||||
|
||||
/*const phasesTemplate = ref([{
|
||||
label: 'Erstkontakt',
|
||||
icon: 'i-heroicons-clipboard-document',
|
||||
active: true
|
||||
}, {
|
||||
label: 'Überprüfung Vor Ort',
|
||||
icon: 'i-heroicons-magnifying-glass'
|
||||
}, {
|
||||
label: 'Angebotserstellung',
|
||||
icon: 'i-heroicons-document-text'
|
||||
}, {
|
||||
label: 'Auftragsvergabe',
|
||||
icon: 'i-heroicons-document-check'
|
||||
}, {
|
||||
label: 'Umsetzung',
|
||||
icon: 'i-heroicons-wrench-screwdriver'
|
||||
},{
|
||||
label: 'Rechnungsstellung',
|
||||
icon: 'i-heroicons-document-text'
|
||||
}, {
|
||||
label: 'Abgeschlossen',
|
||||
icon: 'i-heroicons-check'
|
||||
}])*/
|
||||
const changeActivePhase = async (phase) => {
|
||||
itemInfo.value = await useSupabaseSelectSingle("projects",route.params.id,'*')
|
||||
|
||||
itemInfo.value.phases = itemInfo.value.phases.map(p => {
|
||||
if(p.active) delete p.active
|
||||
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) => {
|
||||
console.log(key)
|
||||
let item = await useSupabaseSelectSingle("projects",itemInfo.value.id,'*')
|
||||
|
||||
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 = dataStore.activeProfile.id
|
||||
}
|
||||
|
||||
if(p.label === phase.label) p.active = true
|
||||
|
||||
return p
|
||||
})
|
||||
|
||||
await savePhases()
|
||||
console.log(item.phases)
|
||||
|
||||
await dataStore.updateItem("projects", item)
|
||||
setupPage()
|
||||
}
|
||||
|
||||
const savePhases = () => {
|
||||
dataStore.updateItem("projects", itemInfo.value)
|
||||
}
|
||||
|
||||
const loadPhases = async () => {
|
||||
itemInfo.value.phases = dataStore.phasesTemplates.find(i => i.id === phasesTemplateSelected.value).initialPhases
|
||||
await dataStore.updateItem("projects", {...itemInfo.value, customer: itemInfo.value.customer ? itemInfo.value.customer.id : null, plant: itemInfo.value.plant ? itemInfo.value.plant.id : null})
|
||||
}
|
||||
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 []
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
@@ -231,7 +240,7 @@ const loadPhases = async () => {
|
||||
</UButton>
|
||||
<UButton
|
||||
v-else-if="mode === 'create'"
|
||||
@click="dataStore.createNewItem('projects',itemInfo)"
|
||||
@click="createProject"
|
||||
>
|
||||
Erstellen
|
||||
</UButton>
|
||||
@@ -294,37 +303,15 @@ const loadPhases = async () => {
|
||||
</div>
|
||||
<div v-if="item.key === 'phases'" class="space-y-3">
|
||||
<UCard class="mt-5">
|
||||
<UFormGroup
|
||||
label="Vorlage laden"
|
||||
v-if="itemInfo.phases.length === 0"
|
||||
>
|
||||
<InputGroup>
|
||||
<USelectMenu
|
||||
:options="phasesTemplates"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
v-model="phasesTemplateSelected"
|
||||
class="flex-auto"
|
||||
>
|
||||
|
||||
</USelectMenu>
|
||||
<UButton
|
||||
@click="loadPhases"
|
||||
>
|
||||
Vorlage laden
|
||||
</UButton>
|
||||
</InputGroup>
|
||||
|
||||
</UFormGroup>
|
||||
|
||||
<UAccordion
|
||||
:items="itemInfo.phases"
|
||||
: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">
|
||||
@@ -344,15 +331,35 @@ const loadPhases = async () => {
|
||||
|
||||
</UButton>
|
||||
</template>
|
||||
<template #item="{item}">
|
||||
<InputGroup>
|
||||
<UButton
|
||||
v-if="!item.active"
|
||||
@click="changeActivePhase(item)"
|
||||
>
|
||||
Phase aktivieren
|
||||
</UButton>
|
||||
</InputGroup>
|
||||
<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: {{dataStore.getProfileById(item.activated_by).fullName}}</p>
|
||||
<p v-if="item.description" class="text-black">Beschreibung: {{item.description}}</p>
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
|
||||
</template>
|
||||
</UAccordion>
|
||||
</UCard>
|
||||
@@ -490,23 +497,7 @@ const loadPhases = async () => {
|
||||
</UCard>
|
||||
</div>
|
||||
<div v-else-if="item.key === 'material'" class="space-y-3">
|
||||
<UCard class="mt-5">
|
||||
Auf das Projekt gebuchte Artikel:
|
||||
|
||||
<!-- <UTable
|
||||
:rows="dataStore.getStocksByProjectId(itemInfo.id)"
|
||||
:columns="[{key:'productId',label:'Artikel'},{key:'stock',label:'Anzahl'}]"
|
||||
@select="(i) => router.push(`/products/show/${i.productId}`)"
|
||||
>
|
||||
<template #productId-data="{row}">
|
||||
{{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>-->
|
||||
</UCard>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
@@ -532,6 +523,43 @@ const loadPhases = async () => {
|
||||
/>
|
||||
</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:"
|
||||
>
|
||||
@@ -542,6 +570,7 @@ const loadPhases = async () => {
|
||||
value-attribute="id"
|
||||
searchable
|
||||
:search-attributes="['name']"
|
||||
:disabled="disableCustomerSelection"
|
||||
>
|
||||
<template #label>
|
||||
{{dataStore.getCustomerById(itemInfo.customer) ? dataStore.getCustomerById(itemInfo.customer).name : "Kunde auswählen"}}
|
||||
@@ -549,6 +578,21 @@ const loadPhases = async () => {
|
||||
</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:"
|
||||
>
|
||||
@@ -564,38 +608,7 @@ const loadPhases = async () => {
|
||||
</USelectMenu>
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Objekt:"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="itemInfo.plant"
|
||||
:options="plants"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
searchable
|
||||
:search-attributes="['name']"
|
||||
>
|
||||
<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="contracts"
|
||||
option-attribute="name"
|
||||
value-attribute="id"
|
||||
searchable
|
||||
:search-attributes="['name']"
|
||||
>
|
||||
<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="Beteiligte Benutzer:"
|
||||
>
|
||||
@@ -615,13 +628,14 @@ const loadPhases = async () => {
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup
|
||||
label="Notizen:"
|
||||
label="Notizen:"
|
||||
>
|
||||
<UTextarea
|
||||
v-model="itemInfo.notes"
|
||||
v-model="itemInfo.notes"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</UForm>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -26,7 +26,20 @@
|
||||
<UCheckbox
|
||||
label="Abgeschlossene anzeigen"
|
||||
v-model="showFinished"
|
||||
class="mt-1"
|
||||
/>
|
||||
<USelectMenu
|
||||
class="ml-3 w-36"
|
||||
v-model="selectedTypes"
|
||||
:options="projecttypes"
|
||||
value-attribute="id"
|
||||
option-attribute="name"
|
||||
multiple
|
||||
>
|
||||
<template #label>
|
||||
Typen
|
||||
</template>
|
||||
</USelectMenu>
|
||||
</template>
|
||||
|
||||
<template #right>
|
||||
@@ -60,6 +73,9 @@
|
||||
<span class="text-primary-500 font-bold" v-if="row === filteredRows[selectedItem]">{{row.name}}</span>
|
||||
<span v-else>{{row.name}}</span>
|
||||
</template>
|
||||
<template #projecttype-data="{row}">
|
||||
{{row.projecttype.name}}
|
||||
</template>
|
||||
<template #phase-data="{row}">
|
||||
{{getActivePhaseLabel(row)}}
|
||||
</template>
|
||||
@@ -117,9 +133,13 @@ const router = useRouter()
|
||||
|
||||
const items = ref([])
|
||||
const selectedItem = ref(0)
|
||||
const projecttypes = ref([])
|
||||
const selectedTypes = ref([])
|
||||
|
||||
const setupPage = async () => {
|
||||
items.value = await useSupabaseSelect("projects","*, customer (name), plant(name)","projectNumber")
|
||||
items.value = await useSupabaseSelect("projects","*, customer (name), plant(name), projecttype(name, id)","projectNumber")
|
||||
projecttypes.value = await useSupabaseSelect("projecttypes","*")
|
||||
selectedTypes.value = projecttypes.value.map(i => i.id)
|
||||
}
|
||||
|
||||
setupPage()
|
||||
@@ -129,6 +149,10 @@ const templateColumns = [
|
||||
key: "projectNumber",
|
||||
label: "Projektnummer"
|
||||
},
|
||||
{
|
||||
key: "projecttype",
|
||||
label: "Typ"
|
||||
},
|
||||
{
|
||||
key: "phase",
|
||||
label: "Phase"
|
||||
@@ -198,10 +222,11 @@ const filteredRows = computed(() => {
|
||||
temp = temp.filter(i => i.phaseLabel !== "Abgeschlossen")
|
||||
}
|
||||
|
||||
temp = temp.filter(i => selectedTypes.value.includes(i.projecttype.id))
|
||||
|
||||
if(!searchString.value) {
|
||||
return temp
|
||||
}
|
||||
|
||||
return useSearch(searchString.value, temp)
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user