Added Phases to Projects
This commit is contained in:
@@ -123,7 +123,8 @@ const renderText = (text) => {
|
|||||||
</template>
|
</template>
|
||||||
<div
|
<div
|
||||||
v-if="historyItems.length > 0"
|
v-if="historyItems.length > 0"
|
||||||
v-for="(item,index) in historyItems"
|
v-for="(item,index) in historyItems.slice().reverse()
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<UDivider
|
<UDivider
|
||||||
class="my-3"
|
class="my-3"
|
||||||
|
|||||||
@@ -18,12 +18,13 @@ const id = ref(route.params.id ? route.params.id : null )
|
|||||||
let currentItem = ref(null)
|
let currentItem = ref(null)
|
||||||
|
|
||||||
const tabItems = [
|
const tabItems = [
|
||||||
/*{
|
{
|
||||||
key: "phases",
|
|
||||||
label: "Phasen"
|
|
||||||
},*/{
|
|
||||||
key: "information",
|
key: "information",
|
||||||
label: "Informationen"
|
label: "Informationen"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "phases",
|
||||||
|
label: "Phasen"
|
||||||
},{
|
},{
|
||||||
key: "tasks",
|
key: "tasks",
|
||||||
label: "Aufgaben"
|
label: "Aufgaben"
|
||||||
@@ -172,6 +173,52 @@ 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 phasesTemplateSelected = ref(dataStore.phasesTemplates[0].id)
|
||||||
|
const changeActivePhase = (phase) => {
|
||||||
|
currentItem.value.phases = currentItem.value.phases.map(p => {
|
||||||
|
if(p.active) delete p.active
|
||||||
|
|
||||||
|
if(p.label === phase.label) p.active = true
|
||||||
|
|
||||||
|
return p
|
||||||
|
})
|
||||||
|
|
||||||
|
savePhases()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const savePhases = () => {
|
||||||
|
dataStore.updateItem("projects", currentItem.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadPhases = async () => {
|
||||||
|
currentItem.value.phases = dataStore.phasesTemplates.find(i => i.id === phasesTemplateSelected.value).initialPhases
|
||||||
|
await dataStore.updateItem("projects", currentItem.value)
|
||||||
|
}
|
||||||
|
|
||||||
setupPage()
|
setupPage()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -183,29 +230,69 @@ setupPage()
|
|||||||
|
|
||||||
<UTabs :items="tabItems" class="w-full">
|
<UTabs :items="tabItems" class="w-full">
|
||||||
<template #item="{ item }">
|
<template #item="{ item }">
|
||||||
<!--
|
<div v-if="item.key === 'information'">
|
||||||
<div v-if="item.key === 'phases'" class="space-y-3">
|
<InputGroup>
|
||||||
<p>Hier wird aktuell noch gearbeitet</p>
|
<UButton
|
||||||
<!– <div id="phaseList">
|
@click="router.push(`/customers/show/${currentItem.customer}`)"
|
||||||
<a
|
class="mb-3"
|
||||||
v-for="phase in []"
|
>
|
||||||
@click="selectedPhase = phase"
|
Zum Kunden
|
||||||
>
|
</UButton>
|
||||||
<div
|
<UButton
|
||||||
class="phaseContainer"
|
@click="router.push(`/plants/show/${currentItem.plant}`)"
|
||||||
>
|
class="mb-3"
|
||||||
<span>{{phase.name}} - {{phase.position}}</span>
|
>
|
||||||
</div>
|
Zum Objekt
|
||||||
|
</UButton>
|
||||||
|
</InputGroup>
|
||||||
|
|
||||||
<a class="plusIcon" @click="addPhase(phase)">
|
Kunde: {{dataStore.getCustomerById(currentItem.customer).name}}<br>
|
||||||
|
Objekt: {{currentItem.plant ? dataStore.getPlantById(currentItem.plant).name : ""}}<br>
|
||||||
|
Notizen:<br>
|
||||||
|
{{currentItem.notes}}
|
||||||
|
</div>
|
||||||
|
<div v-if="item.key === 'phases'" class="space-y-3">
|
||||||
|
<UFormGroup
|
||||||
|
label="Vorlage laden"
|
||||||
|
v-if="currentItem.phases.length === 0"
|
||||||
|
>
|
||||||
|
<InputGroup>
|
||||||
|
<USelectMenu
|
||||||
|
:options="dataStore.phasesTemplates"
|
||||||
|
option-attribute="name"
|
||||||
|
value-attribute="id"
|
||||||
|
v-model="phasesTemplateSelected"
|
||||||
|
class="flex-auto"
|
||||||
|
>
|
||||||
|
|
||||||
<UDivider icon="i-heroicons-plus-circle"/>
|
</USelectMenu>
|
||||||
</a>
|
<UButton
|
||||||
</a>
|
@click="loadPhases"
|
||||||
</div>–>
|
>
|
||||||
|
Vorlage laden
|
||||||
|
</UButton>
|
||||||
|
</InputGroup>
|
||||||
|
</UFormGroup>
|
||||||
|
|
||||||
</div>
|
<UAccordion
|
||||||
-->
|
:items="currentItem.phases"
|
||||||
|
>
|
||||||
|
<template #item="{item}">
|
||||||
|
<InputGroup>
|
||||||
|
<UButton
|
||||||
|
v-if="!item.active"
|
||||||
|
@click="changeActivePhase(item)"
|
||||||
|
>
|
||||||
|
Phase aktivieren
|
||||||
|
</UButton>
|
||||||
|
|
||||||
|
<!-- <UButton>
|
||||||
|
+ Phase
|
||||||
|
</UButton>-->
|
||||||
|
</InputGroup>
|
||||||
|
</template>
|
||||||
|
</UAccordion>
|
||||||
|
</div>
|
||||||
<div v-if="item.key === 'tasks'" class="space-y-3">
|
<div v-if="item.key === 'tasks'" class="space-y-3">
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<UButton
|
<UButton
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<InputGroup>
|
<InputGroup >
|
||||||
<UButton @click="router.push(`/projects/create/`)">+ Projekt</UButton>
|
<UButton @click="router.push(`/projects/create/`)">+ Projekt</UButton>
|
||||||
|
|
||||||
<UInput
|
<UInput
|
||||||
v-model="searchString"
|
v-model="searchString"
|
||||||
placeholder="Suche..."
|
placeholder="Suche..."
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<UCheckbox
|
||||||
|
label="Abgeschlossene anzeigen"
|
||||||
|
v-model="showFinished"
|
||||||
|
/>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
|
||||||
|
|
||||||
@@ -16,6 +21,9 @@
|
|||||||
:columns="itemColumns"
|
:columns="itemColumns"
|
||||||
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }"
|
:empty-state="{ icon: 'i-heroicons-circle-stack-20-solid', label: 'Noch keine Einträge' }"
|
||||||
>
|
>
|
||||||
|
<template #phase-data="{row}">
|
||||||
|
{{getActivePhaseLabel(row)}}
|
||||||
|
</template>
|
||||||
<template #customer-data="{row}">
|
<template #customer-data="{row}">
|
||||||
{{dataStore.getCustomerById(row.customer) ? dataStore.getCustomerById(row.customer).name : ""}}
|
{{dataStore.getCustomerById(row.customer) ? dataStore.getCustomerById(row.customer).name : ""}}
|
||||||
</template>
|
</template>
|
||||||
@@ -35,6 +43,10 @@ const supabase = useSupabaseClient()
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const itemColumns = [
|
const itemColumns = [
|
||||||
|
{
|
||||||
|
key: "phase",
|
||||||
|
label: "Phase"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: "measure",
|
key: "measure",
|
||||||
label: "Gewerk"
|
label: "Gewerk"
|
||||||
@@ -43,13 +55,13 @@ const itemColumns = [
|
|||||||
label: "Name"
|
label: "Name"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "notes",
|
key: "customer",
|
||||||
label: "Notizen",
|
label: "Kunde",
|
||||||
sortable: true
|
sortable: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "customer",
|
key: "notes",
|
||||||
label: "Kunde",
|
label: "Notizen",
|
||||||
sortable: true
|
sortable: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -64,15 +76,49 @@ const selectItem = (item) => {
|
|||||||
router.push(`/projects/show/${item.id} `)
|
router.push(`/projects/show/${item.id} `)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const searchString = ref('')
|
const searchString = ref('')
|
||||||
|
const showFinished = ref(false)
|
||||||
|
|
||||||
const filteredRows = computed(() => {
|
const filteredRows = computed(() => {
|
||||||
if(!searchString.value) {
|
let items = dataStore.projects
|
||||||
return dataStore.projects
|
|
||||||
|
items = items.map(item => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
phaseLabel: getActivePhaseLabel(item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if(showFinished.value) {
|
||||||
|
items = items.filter(i => i.phaseLabel === "Abgeschlossen")
|
||||||
|
} else {
|
||||||
|
items = items.filter(i => i.phaseLabel !== "Abgeschlossen")
|
||||||
}
|
}
|
||||||
|
|
||||||
return dataStore.projects.filter(product => {
|
if(!searchString.value) {
|
||||||
return Object.values(product).some((value) => {
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return items.filter(project => {
|
||||||
|
return Object.values(project).some((value) => {
|
||||||
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
return String(value).toLowerCase().includes(searchString.value.toLowerCase())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -85,10 +85,20 @@ setupPage()
|
|||||||
{{currentItem.name}}
|
{{currentItem.name}}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<InputGroup>
|
||||||
|
<UButton
|
||||||
|
v-if="currentItem.project"
|
||||||
|
@click="router.push(`/projects/show/${currentItem.project}`)"
|
||||||
|
class="mb-3"
|
||||||
|
>
|
||||||
|
Zum Projekt
|
||||||
|
</UButton>
|
||||||
|
</InputGroup>
|
||||||
|
|
||||||
|
|
||||||
Beschreibung:<br>
|
Beschreibung:<br>
|
||||||
{{currentItem.description}}<br>
|
{{currentItem.description}}<br>
|
||||||
|
Projekt: {{currentItem.project ? dataStore.getProjectById(currentItem.project).name : "Kein Projekt zugeordnet"}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
const messages = ref([])
|
const messages = ref([])
|
||||||
const createddocuments = ref([])
|
const createddocuments = ref([])
|
||||||
const workingtimes = ref([])
|
const workingtimes = ref([])
|
||||||
|
const phasesTemplates = ref([])
|
||||||
|
|
||||||
|
|
||||||
const rights = ref({
|
const rights = ref({
|
||||||
@@ -271,6 +272,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
await fetchMessages()
|
await fetchMessages()
|
||||||
await fetchCreatedDocuments()
|
await fetchCreatedDocuments()
|
||||||
await fetchWorkingTimes()
|
await fetchWorkingTimes()
|
||||||
|
await fetchPhasesTemplates()
|
||||||
loaded.value = true
|
loaded.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,6 +312,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
messages.value = []
|
messages.value = []
|
||||||
createddocuments.value = []
|
createddocuments.value = []
|
||||||
workingtimes.value = []
|
workingtimes.value = []
|
||||||
|
phasesTemplates.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasRight (right) {
|
function hasRight (right) {
|
||||||
@@ -333,7 +336,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
schema: 'public',
|
schema: 'public',
|
||||||
},
|
},
|
||||||
(payload) => {
|
(payload) => {
|
||||||
console.log(payload)
|
//console.log(payload)
|
||||||
|
|
||||||
if(payload.eventType === 'INSERT') {
|
if(payload.eventType === 'INSERT') {
|
||||||
const c = payload.table + '.value.push(' + JSON.stringify(payload.new) + ')'
|
const c = payload.table + '.value.push(' + JSON.stringify(payload.new) + ')'
|
||||||
@@ -347,7 +350,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
.subscribe()
|
.subscribe()
|
||||||
|
|
||||||
async function createNewItem (dataType,data){
|
async function createNewItem (dataType,data){
|
||||||
console.log(dataType)
|
//console.log(dataType)
|
||||||
if(dataTypes[dataType].numberRangeHolder) {
|
if(dataTypes[dataType].numberRangeHolder) {
|
||||||
|
|
||||||
const numberRange = useNumberRange(dataType)
|
const numberRange = useNumberRange(dataType)
|
||||||
@@ -368,7 +371,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
if(supabaseError) {
|
if(supabaseError) {
|
||||||
console.log(supabaseError)
|
console.log(supabaseError)
|
||||||
} else if (supabaseData) {
|
} else if (supabaseData) {
|
||||||
await eval( dataType + '.value.push(' + JSON.stringify(...supabaseData) + ')')
|
//await eval( dataType + '.value.push(' + JSON.stringify(...supabaseData) + ')')
|
||||||
toast.add({title: `${dataTypes[dataType].labelSingle} hinzugefügt`})
|
toast.add({title: `${dataTypes[dataType].labelSingle} hinzugefügt`})
|
||||||
if(dataTypes[dataType].redirect) await router.push(`/${dataType}/show/${supabaseData[0].id}`)
|
if(dataTypes[dataType].redirect) await router.push(`/${dataType}/show/${supabaseData[0].id}`)
|
||||||
return supabaseData
|
return supabaseData
|
||||||
@@ -556,6 +559,10 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
workingtimes.value = (await supabase.from("workingtimes").select().eq('tenant', currentTenant.value).order('created_at', {ascending:true})).data
|
workingtimes.value = (await supabase.from("workingtimes").select().eq('tenant', currentTenant.value).order('created_at', {ascending:true})).data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchPhasesTemplates() {
|
||||||
|
phasesTemplates.value = (await supabase.from("phasesTemplates").select().eq('tenant', currentTenant.value).order('created_at', {ascending:true})).data
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchDocuments () {
|
async function fetchDocuments () {
|
||||||
let tempDocuments = (await supabase.from("documents").select().eq('tenant', currentTenant.value)).data
|
let tempDocuments = (await supabase.from("documents").select().eq('tenant', currentTenant.value)).data
|
||||||
|
|
||||||
@@ -959,6 +966,7 @@ export const useDataStore = defineStore('data', () => {
|
|||||||
messages,
|
messages,
|
||||||
createddocuments,
|
createddocuments,
|
||||||
workingtimes,
|
workingtimes,
|
||||||
|
phasesTemplates,
|
||||||
documentTypesForCreation,
|
documentTypesForCreation,
|
||||||
//Functions
|
//Functions
|
||||||
createNewItem,
|
createNewItem,
|
||||||
|
|||||||
Reference in New Issue
Block a user