refactor(z-task-modal): implement custom filter for employee selection to prevent reselect of the same employee

This commit is contained in:
Matej Glasnák committed 2025-12-16 07:11:38 +01:00
1 parent 8e9e586276
commit dd3b754fb2
1 file changed
+29 -41
+29 -41
View File
@@ -102,7 +102,7 @@
:timeblocks="getEmployeeTimeblocks(subtask.employee_id)" :timeblocks="getEmployeeTimeblocks(subtask.employee_id)"
:all-timeblocks="timeblocks" :all-timeblocks="timeblocks"
:deleted-timeblock-ids="deletedTimeblockIds" :deleted-timeblock-ids="deletedTimeblockIds"
:custom-filter="getEmployeeCustomFilter(subtask.employee_id)" :custom-filter="customFilterWithEmployeeFilter"
@update:timeblocks=" @update:timeblocks="
updateEmployeeTimeblocks($event, subtask.employee_id) updateEmployeeTimeblocks($event, subtask.employee_id)
" "
@@ -122,7 +122,7 @@
:timeblocks="getEmployeeTimeblocks(employee.id)" :timeblocks="getEmployeeTimeblocks(employee.id)"
:all-timeblocks="timeblocks" :all-timeblocks="timeblocks"
:deleted-timeblock-ids="deletedTimeblockIds" :deleted-timeblock-ids="deletedTimeblockIds"
:custom-filter="getEmployeeCustomFilter(employee.id)" :custom-filter="customFilterWithEmployeeFilter"
:required="index === 0" :required="index === 0"
@update:timeblocks="updateEmployeeTimeblocks($event, employee.id)" @update:timeblocks="updateEmployeeTimeblocks($event, employee.id)"
@clear-employee="() => removeEmployeeAtIndex(index)" @clear-employee="() => removeEmployeeAtIndex(index)"
@@ -521,6 +521,33 @@ export default {
}, },
methods: { 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() { toggleEditMode() {
if (this.subtask.type == 'office365') if (this.subtask.type == 'office365')
return this.$events.emit('show-unable-to-edit-office-task-modal', { 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); 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) { updateEmployeeTimeblocks(updatedTimeblocks, employeeId) {
// Track deleted timeblocks (saved timeblocks that are no longer in the updated list) // Track deleted timeblocks (saved timeblocks that are no longer in the updated list)
const updatedIds = new Set( const updatedIds = new Set(