feat(z-task-modal): add support for displaying multiple employees in task details with enriched data

This commit is contained in:
Matej Glasnák committed 2025-12-16 17:41:42 +01:00
1 parent 153bd503e6
commit ee2f1eadc7
3 files changed
+106 -22

No files matched your search

@@ -1,5 +1,5 @@
<template> <template>
<v-row no-gutters class="align-center border-bottom"> <v-row no-gutters class="align-center">
<v-col cols="5"> <v-col cols="5">
<v-sheet class="py-3"> <v-sheet class="py-3">
<div class="d-flex align-center"> <div class="d-flex align-center">
@@ -1,32 +1,66 @@
<template> <template>
<A-mastertask-name :id="subtask.master_task_id" :name="subtask._master_task.name" :color="subtask._master_task.color" @close-modal="$emit('close-modal')" /> <A-mastertask-name
:id="subtask.master_task_id"
:name="subtask._master_task.name"
:color="subtask._master_task.color"
@close-modal="$emit('close-modal')"
/>
<A-mastertask-status :is-finished="subtask.is_finished" /> <A-mastertask-status :is-finished="subtask.is_finished" />
<A-task-deadline :subtask="subtask" /> <A-task-deadline :subtask="subtask" />
<A-task-timeblocks :timeblocks="subtask.timeblocks" :subtask="subtask" @update-subtask="$emit('update-subtask', $event)" />
<Z-created-by :employee-id="subtask.created_by" /> <Z-created-by :employee-id="subtask.created_by" />
<A-task-assigned-employee :employee="subtask._employee" />
<A-task-planned-time :hours="subtask.duration" /> <!-- Loop through normalized employees -->
<div
v-for="(employeeData, index) in normalizedEmployees"
:key="`employee-${employeeData.id || index}`"
:class="{
'employee-section': hasMultipleEmployees,
'border-top': hasMultipleEmployees,
'border-bottom':
hasMultipleEmployees && index === normalizedEmployees.length - 1,
}"
>
<A-task-assigned-employee :employee="employeeData._employee" />
<A-task-planned-time :hours="employeeData.duration" />
<A-task-timeblocks
:timeblocks="employeeData.timeblocks"
:subtask="{
...subtask,
employee_id: employeeData.id,
timeblocks: employeeData.timeblocks,
}"
@update-subtask="$emit('update-subtask', $event)"
/>
</div>
<!-- Remaining/spent time only for single employee (not in multi-employee drafts) -->
<template v-if="!hasMultipleEmployees">
<A-task-remaining-time :hours="subtask.duration - subtask.spent_time" /> <A-task-remaining-time :hours="subtask.duration - subtask.spent_time" />
<A-task-spent-time :hours="subtask.spent_time" :subtask="subtask" /> <A-task-spent-time :hours="subtask.spent_time" :subtask="subtask" />
<A-task-description :description="subtask.description" :mastertask-description="subtask.master_task_description" /> </template>
<A-task-description
:description="subtask.description"
:mastertask-description="subtask.master_task_description"
/>
<Z-files :files="subtask.files" /> <Z-files :files="subtask.files" />
</template> </template>
<script> <script>
import AMastertaskName from './_components/a-mastertask-name.vue' import AMastertaskName from './_components/a-mastertask-name.vue';
import AMastertaskStatus from './_components/a-mastertask-status.vue' import AMastertaskStatus from './_components/a-mastertask-status.vue';
import ATaskTimeblocks from './_components/a-task-timeblocks.vue' import ATaskTimeblocks from './_components/a-task-timeblocks.vue';
import ZCreatedBy from '../../_components/read-only/z-created-by.vue' import ZCreatedBy from '../../_components/read-only/z-created-by.vue';
import ATaskAssignedEmployee from './_components/a-task-assigned-employee.vue' import ATaskAssignedEmployee from './_components/a-task-assigned-employee.vue';
import ATaskPlannedTime from './_components/a-task-planned-time.vue' import ATaskPlannedTime from './_components/a-task-planned-time.vue';
import ATaskSpentTime from './_components/a-task-spent-time.vue' import ATaskSpentTime from './_components/a-task-spent-time.vue';
import ATaskRemainingTime from './_components/a-task-remaining-time.vue' import ATaskRemainingTime from './_components/a-task-remaining-time.vue';
import ATaskDeadline from './_components/a-task-deadline.vue' import ATaskDeadline from './_components/a-task-deadline.vue';
import ATaskDescription from './_components/a-task-description.vue' import ATaskDescription from './_components/a-task-description.vue';
import ZFiles from '@/plugins/tm@modal/_components/read-only/z-files.vue' import ZFiles from '@/plugins/tm@modal/_components/read-only/z-files.vue';
import { mapGetters } from 'vuex';
export default { export default {
components: { components: {
ZFiles, ZFiles,
AMastertaskName, AMastertaskName,
@@ -38,15 +72,60 @@ export default {
ATaskSpentTime, ATaskSpentTime,
ATaskRemainingTime, ATaskRemainingTime,
ATaskDescription, ATaskDescription,
ATaskDeadline ATaskDeadline,
}, },
props: { props: {
subtask: { subtask: {
type: Object, type: Object,
required: true required: true,
}
}, },
emits: ['close-modal', 'update-subtask'] },
emits: ['close-modal', 'update-subtask'],
computed: {
...mapGetters('tm', ['enrichedEmployees']),
normalizedEmployees() {
// Draft with multiple employees
if (this.subtask.is_draft && Array.isArray(this.subtask.employees)) {
return this.subtask.employees
.filter((emp) => emp.id) // Filter out empty employee slots
.map((emp) => ({
id: emp.id,
duration: emp.duration || 0,
timeblocks: emp.timeblocks || [],
_employee: this.enrichedEmployees.find((e) => e.id == emp.id) || {},
}));
} }
// Single employee (published subtask)
return [
{
id: this.subtask.employee_id,
duration: this.subtask.duration,
timeblocks: this.subtask.timeblocks || [],
_employee: this.subtask._employee,
},
];
},
hasMultipleEmployees() {
return this.normalizedEmployees.length > 1;
},
},
};
</script> </script>
<style lang="sass" scoped>
.employee-section
margin: 16px 0
.border-top
border-top: 1px solid rgba(0, 0, 0, 0.12)
padding-top: 16px
.border-bottom
border-bottom: 1px solid rgba(0, 0, 0, 0.12)
padding-bottom: 16px
</style>
@@ -579,6 +579,11 @@ export default {
return employee ? `${employee.name} ${employee.surname}` : ''; return employee ? `${employee.name} ${employee.surname}` : '';
}, },
// Helper: Get enriched employee data by ID
getEnrichedEmployee(employeeId) {
return this.enrichedEmployees.find((emp) => emp.id === employeeId) || {};
},
// Helper: Get valid employees (with id and duration) in create mode // Helper: Get valid employees (with id and duration) in create mode
getValidEmployees() { getValidEmployees() {
if (!this.subtask?.employees) return []; if (!this.subtask?.employees) return [];