diff --git a/app/src/plugins/tm@modal/_utils/modal-resize.utils.ts b/app/src/plugins/tm@modal/_utils/modal-resize.utils.ts index 45419f6..26d9168 100644 --- a/app/src/plugins/tm@modal/_utils/modal-resize.utils.ts +++ b/app/src/plugins/tm@modal/_utils/modal-resize.utils.ts @@ -15,12 +15,12 @@ const MOBILE_BREAKPOINT = 768; const SIZE_PRESETS = { small: { width: 600, - height: 'fit-content', + height: 'auto', maxWidth: 600, }, medium: { width: 900, - height: 'fit-content', + height: 'auto', maxWidth: 900, }, large: { 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 706a9be..1397440 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 @@ -28,11 +28,7 @@ /> -
+
{ + const { starts_at_time } = payload; + let { ends_at_time } = payload; + + // Fix accidental same start/end time by adding 1 hour to end + if (starts_at_time === ends_at_time) { + const [hours, minutes] = starts_at_time.split(':').map(Number); + const newEndHour = (hours + 1) % 24; // Wrap around at midnight + ends_at_time = `${String(newEndHour).padStart(2, '0')}:${String( + minutes, + ).padStart(2, '0')}`; + } + emit('update:modelValue', { ...props.modelValue, - starts_at_time: payload.starts_at_time, - ends_at_time: payload.ends_at_time, + starts_at_time, + ends_at_time, }); // Trigger validation after timeline update diff --git a/app/src/plugins/tm@modal/task/_components/z-task-readonly-info.vue b/app/src/plugins/tm@modal/task/_components/z-task-readonly-info.vue index da6e8c6..2a0e98a 100644 --- a/app/src/plugins/tm@modal/task/_components/z-task-readonly-info.vue +++ b/app/src/plugins/tm@modal/task/_components/z-task-readonly-info.vue @@ -88,7 +88,7 @@ export default { normalizedEmployees() { // Drafts always have employees array - if (this.subtask.is_draft) { + 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) => ({ 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 89dda3b..e70464b 100644 --- a/app/src/plugins/tm@modal/task/z-task-modal.vue +++ b/app/src/plugins/tm@modal/task/z-task-modal.vue @@ -563,16 +563,20 @@ export default { // New subtask with multiple employees support // Hide employees that are already selected in any slot // The v-autocomplete will still display the currently selected employee - const isAlreadySelected = this.subtask.employees.some( - (emp) => emp.id && Number(emp.id) === employeeId, - ); + const isAlreadySelected = + Array.isArray(this.subtask.employees) && + this.subtask.employees.some( + (emp) => emp.id && Number(emp.id) === employeeId, + ); return shouldShowItem && !isAlreadySelected; } else if (this.subtask.is_draft) { // Edit draft subtask with multiple employees support // Hide employees that are already selected in any slot - const isAlreadySelected = this.subtask.employees.some( - (emp) => emp.id && Number(emp.id) === employeeId, - ); + const isAlreadySelected = + Array.isArray(this.subtask.employees) && + this.subtask.employees.some( + (emp) => emp.id && Number(emp.id) === employeeId, + ); return shouldShowItem && !isAlreadySelected; } else { // Saved standard subtask, allow "re-select" for better UX @@ -734,7 +738,10 @@ export default { this.pendingRemoveEmployeeId = undefined; } // Handle create mode (multiple employees removal) - else if (this.pendingRemoveEmployeeIndex !== undefined) { + else if ( + this.pendingRemoveEmployeeIndex !== undefined && + Array.isArray(this.subtask.employees) + ) { const employee = this.subtask.employees[this.pendingRemoveEmployeeIndex]; if (employee?.id) { @@ -1184,6 +1191,8 @@ export default { // Filter employees based on whether it's a concept/draft or published task // For concepts: only require id (duration can be null/0) // For published tasks: require both id and duration + if (!Array.isArray(employees)) return []; + return employees.filter((employee) => { if (isConcept) { return employee.id; // Only require ID for concepts/drafts