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 bd53470..87582ee 100644 --- a/app/src/plugins/tm@modal/task/z-task-modal.vue +++ b/app/src/plugins/tm@modal/task/z-task-modal.vue @@ -102,7 +102,7 @@ :timeblocks="getEmployeeTimeblocks(subtask.employee_id)" :all-timeblocks="timeblocks" :deleted-timeblock-ids="deletedTimeblockIds" - :custom-filter="getEmployeeCustomFilter(subtask.employee_id)" + :custom-filter="customFilterWithEmployeeFilter" @update:timeblocks=" updateEmployeeTimeblocks($event, subtask.employee_id) " @@ -122,7 +122,7 @@ :timeblocks="getEmployeeTimeblocks(employee.id)" :all-timeblocks="timeblocks" :deleted-timeblock-ids="deletedTimeblockIds" - :custom-filter="getEmployeeCustomFilter(employee.id)" + :custom-filter="customFilterWithEmployeeFilter" :required="index === 0" @update:timeblocks="updateEmployeeTimeblocks($event, employee.id)" @clear-employee="() => removeEmployeeAtIndex(index)" @@ -521,6 +521,33 @@ export default { }, methods: { + customFilterWithEmployeeFilter(item, input, itemObject) { + const shouldShowItem = this.customFilter(item, input); + + if (!shouldShowItem) return false; + if (!itemObject?.value) return false; + + const employeeId = itemObject.value; + + if (!this.subtask.id) { + // New subtask with multiple employees support or edit of draft with multiple employees + return ( + shouldShowItem && + !this.timeblocks.some((tb) => tb.employee_id === employeeId) + ); + } else if (this.subtask.is_draft) { + // Edit draft subtask with multiple employees support + return ( + shouldShowItem && + !this.subtask.employees.some( + (employee) => Number(employee.id) === employeeId, + ) + ); + } else { + // Saved standard subtask, allow "re-select" for better UX + return shouldShowItem; + } + }, toggleEditMode() { if (this.subtask.type == 'office365') return this.$events.emit('show-unable-to-edit-office-task-modal', { @@ -564,45 +591,6 @@ export default { return this.timeblocks.filter((tb) => tb.employee_id == employeeId); }, - // Custom filter for employee select to prevent selecting the same employee twice - // currentEmployeeId: the ID of the employee currently selected in this dropdown (can be null) - getEmployeeCustomFilter(currentEmployeeId) { - return (itemText, queryText, item) => { - // Get all selected employee IDs except the current one - const selectedEmployeeIds = new Set(); - - if (this.isDraftWithMultipleEmployees && this.subtask?.employees) { - // In multi-employee mode, collect all selected employee IDs except current - this.subtask.employees.forEach((emp) => { - if (emp.id && emp.id !== currentEmployeeId) { - selectedEmployeeIds.add(emp.id); - } - }); - } else if ( - this.subtask?.employee_id && - this.subtask.employee_id !== currentEmployeeId - ) { - // In single employee edit mode - selectedEmployeeIds.add(this.subtask.employee_id); - } - - // Filter out already selected employees (but allow current selection) - if (selectedEmployeeIds.has(item.id)) { - return false; - } - - // Apply default text filtering (from AutocompleteMixin) - if (this.customFilter) { - return this.customFilter(itemText, queryText, item); - } - - // Default case-insensitive text match - const searchText = queryText.toString().toLowerCase(); - const text = itemText.toString().toLowerCase(); - return text.indexOf(searchText) > -1; - }; - }, - updateEmployeeTimeblocks(updatedTimeblocks, employeeId) { // Track deleted timeblocks (saved timeblocks that are no longer in the updated list) const updatedIds = new Set(