diff --git a/app/src/plugins/tm@modal/task/_components/employees/a-employee-timeblock.vue b/app/src/plugins/tm@modal/task/_components/employees/a-employee-timeblock.vue
index d70f223..b10c50d 100644
--- a/app/src/plugins/tm@modal/task/_components/employees/a-employee-timeblock.vue
+++ b/app/src/plugins/tm@modal/task/_components/employees/a-employee-timeblock.vue
@@ -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 &&
diff --git a/app/src/plugins/tm@modal/task/_components/employees/a-employee.vue b/app/src/plugins/tm@modal/task/_components/employees/a-employee.vue
index 0810002..c2b0f59 100644
--- a/app/src/plugins/tm@modal/task/_components/employees/a-employee.vue
+++ b/app/src/plugins/tm@modal/task/_components/employees/a-employee.vue
@@ -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,
);
});
diff --git a/app/src/plugins/tm@modal/task/z-task-modal.vue b/app/src/plugins/tm@modal/task/z-task-modal.vue
index 1992945..e565d91 100644
--- a/app/src/plugins/tm@modal/task/z-task-modal.vue
+++ b/app/src/plugins/tm@modal/task/z-task-modal.vue
@@ -95,9 +95,9 @@
-
+
-
+
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);