refactor(task-modal): added support for multi-employees edit in z-task-modal to support new draft tasks editing

This commit is contained in:
Matej Glasnák committed 2025-12-15 21:00:39 +01:00
1 parent 604dc4f988
commit 9266991335
3 files changed
+110 -19

No files matched your search

@@ -281,7 +281,7 @@ const otherTimeblocksForSameDate = computed(() => {
// Skip current timeblock - compare by reference or by matching all key properties
if (
tb === currentTimeblock ||
(tb.employee_id === currentTimeblock.employee_id &&
(tb.employee_id == currentTimeblock.employee_id &&
tb.date === currentTimeblock.date &&
tb.starts_at_time === currentTimeblock.starts_at_time &&
tb.ends_at_time === currentTimeblock.ends_at_time &&
@@ -91,14 +91,14 @@ const setTimeblockRef = (el: any, index: number) => {
const selectedEmployee = computed(() => {
if (!props.employeeData.id) return null;
const employees = store.getters['tm/enrichedEmployees'];
return employees.find((emp: any) => emp.id === props.employeeData.id) || null;
return employees.find((emp: any) => emp.id == props.employeeData.id) || null;
});
// Filter allTimeblocks to only include timeblocks for current employee
const allTimeblocksForCurrentEmployee = computed(() => {
if (!props.employeeData.id) return [];
return props.allTimeblocks.filter(
(tb) => tb.employee_id === props.employeeData.id,
(tb) => tb.employee_id == props.employeeData.id,
);
});
+107 -16
View File
@@ -95,9 +95,9 @@
</div>
<!-- Employee Assignment with Timeblocks -->
<!-- Edit Mode: Single Employee -->
<!-- Edit Mode: Single Employee (for published subtasks) -->
<A-employee
v-if="subtask.id"
v-if="subtask.id && !isDraftWithMultipleEmployees"
v-model:employee-data="editModeEmployee"
:timeblocks="getEmployeeTimeblocks(subtask.employee_id)"
:all-timeblocks="timeblocks"
@@ -112,7 +112,7 @@
"
/>
<!-- Create Mode: Multiple Employees -->
<!-- Multi-Employee Mode (for new tasks and drafts with multiple employees) -->
<template v-else>
<A-employee
v-for="(employee, index) in subtask.employees"
@@ -350,6 +350,13 @@ export default {
}
},
},
isDraftWithMultipleEmployees() {
return (
this.subtask?.is_draft &&
Array.isArray(this.subtask?.employees) &&
this.subtask.employees.length > 0
);
},
},
validations() {
@@ -369,7 +376,7 @@ export default {
// In edit mode: reassign timeblocks to new employee
if (this.subtask.id) {
this.timeblocks = this.timeblocks.map((tb) => {
if (tb.employee_id === oldValue) {
if (tb.employee_id == oldValue) {
return { ...tb, employee_id: value };
}
return tb;
@@ -377,7 +384,7 @@ export default {
} else {
// In create mode: remove old employee's timeblocks
this.timeblocks = this.timeblocks.filter(
(tb) => tb.employee_id !== oldValue,
(tb) => tb.employee_id != oldValue,
);
}
@@ -554,7 +561,7 @@ export default {
// Helper: Get timeblocks for specific employee
getEmployeeTimeblocks(employeeId) {
if (!this.timeblocks) return [];
return this.timeblocks.filter((tb) => tb.employee_id === employeeId);
return this.timeblocks.filter((tb) => tb.employee_id == employeeId);
},
updateEmployeeTimeblocks(updatedTimeblocks, employeeId) {
@@ -565,7 +572,7 @@ export default {
const deletedIds = this.timeblocks
.filter(
(tb) =>
tb.employee_id === employeeId && tb.id && !updatedIds.has(tb.id),
tb.employee_id == employeeId && tb.id && !updatedIds.has(tb.id),
)
.map((tb) => tb.id)
.filter((id) => !this.deletedTimeblockIds.includes(id));
@@ -574,7 +581,7 @@ export default {
// Replace timeblocks for this employee
const otherEmployeeTimeblocks = this.timeblocks.filter(
(tb) => tb.employee_id !== employeeId,
(tb) => tb.employee_id != employeeId,
);
const updatedWithEmployeeId = updatedTimeblocks.map((tb) => ({
...tb,
@@ -608,7 +615,7 @@ export default {
// Get timeblocks for this employee
const employeeTimeblocks = this.timeblocks.filter(
(tb) => tb.employee_id === employeeId,
(tb) => tb.employee_id == employeeId,
);
if (afterIndex === -1 || afterIndex >= employeeTimeblocks.length - 1) {
@@ -654,7 +661,7 @@ export default {
if (this.subtask.employee_id) {
// Remove all timeblocks for this employee
this.timeblocks = this.timeblocks.filter(
(tb) => tb.employee_id !== this.subtask.employee_id,
(tb) => tb.employee_id != this.subtask.employee_id,
);
}
@@ -670,7 +677,7 @@ export default {
if (employee?.id) {
// Remove all timeblocks for this employee
this.timeblocks = this.timeblocks.filter(
(tb) => tb.employee_id !== employee.id,
(tb) => tb.employee_id != employee.id,
);
}
@@ -741,8 +748,59 @@ export default {
// Store timeblocks in the component's timeblocks array
this.timeblocks = convertedTimeblocks;
// Ensure at least one timeblock exists for edit mode
if (data.employee_id && this.timeblocks.length === 0) {
// If draft with employees data, parse timeblocks for each employee
if (
data.is_draft &&
data.employees &&
Array.isArray(data.employees)
) {
const draftTimeblocks = [];
data.employees.forEach((employee) => {
if (employee.timeblocks && Array.isArray(employee.timeblocks)) {
employee.timeblocks.forEach((timeblock) => {
// Convert BE format to internal format
if (timeblock.start && timeblock.end) {
const startMoment = moment(
timeblock.start,
'YYYY-MM-DD HH:mm:ss',
);
const endMoment = moment(
timeblock.end,
'YYYY-MM-DD HH:mm:ss',
);
draftTimeblocks.push({
id: timeblock.id || null,
date: startMoment.toDate(),
starts_at_time: startMoment.format('HH:mm'),
ends_at_time: endMoment.format('HH:mm'),
is_finished: timeblock.is_finished || 0,
employee_id: employee.id, // Associate with employee
});
}
});
}
});
// Use draft timeblocks if they exist
if (draftTimeblocks.length > 0) {
this.timeblocks = draftTimeblocks;
}
// Ensure employees array has proper structure for editing
// Check if last employee is not empty, then add empty slot
const lastEmployee = data.employees[data.employees.length - 1];
if (lastEmployee && (lastEmployee.id || lastEmployee.duration)) {
data.employees.push({});
}
}
// Ensure at least one timeblock exists for edit mode (non-draft single employee)
if (
data.employee_id &&
!data.is_draft &&
this.timeblocks.length === 0
) {
this.addTimeblock(data.employee_id);
}
@@ -881,7 +939,7 @@ export default {
timeblock.date &&
timeblock.starts_at_time &&
timeblock.ends_at_time &&
timeblock.employee_id === this.subtask.employee_id,
timeblock.employee_id == this.subtask.employee_id,
) // Only send complete timeblocks for this employee
.map((timeblock) => {
const dateStr = moment(timeblock.date).format('YYYY-MM-DD');
@@ -895,6 +953,36 @@ export default {
const payload = { ...this.subtask, timesheets, timeblocks };
// For drafts with multiple employees, include employees array
if (this.subtask.is_draft && this.isDraftWithMultipleEmployees) {
const validEmployees = this.subtask.employees.filter(
(employee) => employee.id && employee.duration,
);
// Assign timeblocks to each employee
validEmployees.forEach((employee) => {
employee.timeblocks = this.timeblocks
.filter(
(tb) =>
tb.employee_id == employee.id &&
tb.date &&
tb.starts_at_time &&
tb.ends_at_time,
)
.map((tb) => ({
start: `${moment(tb.date).format('YYYY-MM-DD')} ${
tb.starts_at_time
}:00`,
end: `${moment(tb.date).format('YYYY-MM-DD')} ${
tb.ends_at_time
}:00`,
id: tb.id || null,
}));
});
payload.employees = validEmployees;
}
if (concept) {
payload.is_draft = 1;
} else {
@@ -925,7 +1013,7 @@ export default {
timeblock.date &&
timeblock.starts_at_time &&
timeblock.ends_at_time &&
timeblock.employee_id === employee.id,
timeblock.employee_id == employee.id,
)
.map((timeblock) => {
return {
@@ -1002,7 +1090,10 @@ export default {
_mergeDeadlineTimeDate() {
// Override for concept tasks which may not have a deadline time set (check for invalid date)
if (isNaN(new Date(this.subtask.deadline).getTime())) {
if (
isNaN(new Date(this.subtask.deadline).getTime()) ||
!this.subtask._deadline_time
) {
this.subtask.deadline = null;
} else {
const date = new Date(this.subtask.deadline);