Files
FEDEO/frontend/components/EntityShowSubPhases.vue
florianfederspiel cee0e1fa7d
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 15s
Build and Push Docker Images / build-frontend (push) Successful in 59s
Fix Phases
2026-03-25 08:02:24 +01:00

199 lines
4.8 KiB
Vue

<script setup>
import dayjs from "dayjs";
const props = defineProps({
queryStringData: {
type: String
},
item: {
type: Object,
required: true
},
topLevelType: {
type: String,
required: true
},
platform: {
type: String,
required: true
}
})
const emit = defineEmits(["updateNeeded"]);
const router = useRouter()
const profileStore = useProfileStore()
const auth = useAuthStore()
const openPhaseKey = ref(null)
const isPhaseAvailable = (phase, index, phases) => {
if (phase.label === "Abgeschlossen" || phase.active) {
return true
}
const activeIndex = phases.findIndex((item) => item.active)
if (activeIndex > index) {
return true
}
if (activeIndex === -1) {
return index === 0
}
if (index === activeIndex + 1) {
return true
}
if (index <= activeIndex) {
return true
}
return phases.slice(activeIndex + 1, index).every((item) => item.optional)
}
const renderedPhases = computed(() => {
if(props.topLevelType === "projects" && props.item.phases) {
return props.item.phases.map((phase,index,array) => {
return {
...phase,
label: phase.optional ? `${phase.label}(optional)`: phase.label,
disabled: !isPhaseAvailable(phase, index, array),
defaultOpen: phase.active ? true : false
}
})
} else {
return []
}
})
watch(renderedPhases, (phases) => {
if (!phases.length) {
openPhaseKey.value = null
return
}
const activePhase = phases.find((phase) => phase.active)
const currentPhaseStillExists = phases.some((phase) => phase.key === openPhaseKey.value)
if (activePhase) {
openPhaseKey.value = activePhase.key
return
}
if (!currentPhaseStillExists) {
openPhaseKey.value = phases[0].key
}
}, { immediate: true })
const togglePhasePanel = (phase) => {
if (phase.disabled) {
return
}
openPhaseKey.value = openPhaseKey.value === phase.key ? null : phase.key
}
const changeActivePhase = async (key) => {
console.log(props.item)
let item = await useEntities("projects").selectSingle(props.item.id,'*')
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 = auth.user.id
phaseLabel = p.label
}
return p
})
console.log(item)
const res = await useEntities("projects").update(item.id, {phases:item.phases,active_phase: item.phases.find(i => i.active).label})
emit("updateNeeded")
}
</script>
<template>
<UCard class="mt-5 scroll" :style="props.platform !== 'mobile' ? 'height: 80vh' : ''">
<template #header v-if="props.platform === 'mobile'">
<span>Phasen</span>
</template>
<div class="space-y-2">
<div
v-for="(item, index) in renderedPhases"
:key="item.key"
class="space-y-2"
>
<UButton
variant="ghost"
:color="item.active ? 'primary' : 'neutral'"
class="w-full justify-start"
:disabled="item.disabled"
@click="togglePhasePanel(item)"
>
<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="[openPhaseKey === item.key && 'rotate-90']"
/>
</template>
</UButton>
<UCard v-if="openPhaseKey === item.key" class="mx-5">
<template #header>
<span class="dark:text-white 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}&${props.queryStringData}`)"
>
{{button.label}}
</UButton>
</InputGroup>
<div>
<p v-if="item.activated_at" class="dark:text-white text-black">Aktiviert am: {{dayjs(item.activated_at).format("DD.MM.YY HH:mm")}} Uhr</p>
<p v-if="item.activated_by" class="dark:text-white text-black">Aktiviert durch: {{item.activated_by}}</p>
<p v-if="item.description" class="dark:text-white text-black">Beschreibung: {{item.description}}</p>
</div>
</UCard>
</div>
</div>
</UCard>
</template>
<style scoped>
</style>