diff --git a/resources/js/common/reassignMixin.js b/resources/js/common/reassignMixin.js index fa1a5c81b5..1b6af9b5f9 100644 --- a/resources/js/common/reassignMixin.js +++ b/resources/js/common/reassignMixin.js @@ -1,3 +1,5 @@ +import { getReassignUsers as getReassignUsersApi } from "../tasks/api"; + export default { data() { return { @@ -21,32 +23,28 @@ export default { this.allowReassignment = response.data[this.task.id]; }); }, - getReassignUsers(filter = null) { - const params = { }; - if (filter) { - params.filter = filter; - } - if (this.task?.id) { - params.assignable_for_task_id = this.task.id; - // The variables are needed to calculate the rule expression. - if (this?.formData) { - params.form_data = this.formData; - delete params.form_data._user; - delete params.form_data._request; - delete params.form_data._process; - } - } + async getReassignUsers(filter = null) { + try { + const response = await getReassignUsersApi( + filter, + this.task?.id, + this?.formData, + this.currentTaskUserId + ); - ProcessMaker.apiClient.post('users_task_count', params ).then(response => { this.reassignUsers = []; - response.data.data.forEach((user) => { - this.reassignUsers.push({ - text: user.fullname, - value: user.id, - active_tasks_count: user.active_tasks_count + if (response?.data) { + response.data.forEach((user) => { + this.reassignUsers.push({ + text: user.fullname, + value: user.id, + active_tasks_count: user.active_tasks_count + }); }); - }); - }); + } + } catch (error) { + console.error('Error loading reassign users:', error); + } }, onReassignInput: _.debounce(function (filter) { this.getReassignUsers(filter); diff --git a/resources/js/tasks/api/index.js b/resources/js/tasks/api/index.js index 0b55e7e35f..c89c360bca 100644 --- a/resources/js/tasks/api/index.js +++ b/resources/js/tasks/api/index.js @@ -1,12 +1,49 @@ import { getApi } from "../variables/index"; -export const getReassignUsers = async (filter = null, taskId = null, currentTaskUserId = null) => { +/** + * Get reassign users using POST with form_data (for rule expression evaluation) + * This replaces the obsolete GET method with the advanced POST logic from reassignMixin + * + * @param {string|null} filter - Filter string to search users + * @param {number|null} taskId - Task ID to get assignable users for + * @param {Object|null} formData - Form data needed to calculate rule expressions + * @param {number|null} currentTaskUserId - User ID to exclude from results (matches: task?.user_id ?? task?.user?.id) + * @returns {Promise} Response data with users array + */ +export const getReassignUsers = async ( + filter = null, + taskId = null, + formData = null, + currentTaskUserId = null +) => { const api = getApi(); - const response = await api.get("users_task_count", { params: { filter, assignable_for_task_id: taskId, include_current_user: true } }); + const params = {}; + + if (filter) { + params.filter = filter; + } + + if (taskId) { + params.assignable_for_task_id = taskId; + + // The variables are needed to calculate the rule expression. + if (formData) { + params.form_data = { ...formData }; + // Remove internal variables + delete params.form_data._user; + delete params.form_data._request; + delete params.form_data._process; + } + } + + const response = await api.post("users_task_count", params); const data = response.data; + + // Filter out current user to prevent self-reassignment (matches mixin logic) if (currentTaskUserId && Array.isArray(data?.data)) { data.data = data.data.filter((user) => user.id !== currentTaskUserId); } + return data; }; diff --git a/resources/js/tasks/components/TasksPreview.vue b/resources/js/tasks/components/TasksPreview.vue index e9b27459df..8f3ec7c85f 100644 --- a/resources/js/tasks/components/TasksPreview.vue +++ b/resources/js/tasks/components/TasksPreview.vue @@ -201,6 +201,8 @@ @@ -413,7 +415,6 @@ export default { }, openReassignment() { this.showReassignment = !this.showReassignment; - this.getReassignUsers(); }, getTaskDefinitionForReassignmentPermission() { ProcessMaker.apiClient diff --git a/resources/js/tasks/components/taskPreview/TaskPreviewAssignment.vue b/resources/js/tasks/components/taskPreview/TaskPreviewAssignment.vue index 52f066c087..dab085918e 100644 --- a/resources/js/tasks/components/taskPreview/TaskPreviewAssignment.vue +++ b/resources/js/tasks/components/taskPreview/TaskPreviewAssignment.vue @@ -67,6 +67,14 @@ const props = defineProps({ type: Object, required: true, }, + formData: { + type: Object, + default: null, + }, + currentTaskUserId: { + type: Number, + default: null, + }, }); const emit = defineEmits(["on-reassign-user"]); @@ -80,18 +88,29 @@ const disabledAssign = ref(false); // Computed properties const disabled = computed(() => !selectedUser.value || !comments.value?.trim()); -// Load the reassign users +// Load the reassign users using the centralized function with form_data const loadReassignUsers = async (filter) => { - const response = await getReassignUsers(filter, props.task.id, props.task.user_id); - - reassignUsers.value = []; - response.data.forEach((user) => { - reassignUsers.value.push({ - text: user.fullname, - value: user.id, - active_tasks_count: user.active_tasks_count, - }); - }); + try { + const response = await getReassignUsers( + filter, + props.task?.id, + props.formData, + props.currentTaskUserId + ); + + reassignUsers.value = []; + if (response?.data) { + response.data.forEach((user) => { + reassignUsers.value.push({ + text: user.fullname, + value: user.id, + active_tasks_count: user.active_tasks_count, + }); + }); + } + } catch (error) { + console.error('Error loading reassign users:', error); + } }; /** diff --git a/routes/api.php b/routes/api.php index 2b3ffc38bb..8955a4deeb 100644 --- a/routes/api.php +++ b/routes/api.php @@ -60,10 +60,8 @@ Route::delete('users/{user}', [UserController::class, 'destroy'])->name('users.destroy')->middleware('can:delete-users'); Route::put('password/change', [ChangePasswordController::class, 'update'])->name('password.update'); Route::put('users/update_language', [UserController::class, 'updateLanguage'])->name('users.updateLanguage'); - Route::get('users_task_count', [UserController::class, 'getUsersTaskCount'])->name('users.users_task_count') - ->middleware('can:view-users'); - Route::post('users_task_count', [UserController::class, 'getUsersTaskCount'])->name('users.users_task_count_post') - ->middleware('can:view-users'); + Route::get('users_task_count', [UserController::class, 'getUsersTaskCount'])->name('users.users_task_count'); + Route::post('users_task_count', [UserController::class, 'getUsersTaskCount'])->name('users.users_task_count_post'); // User Groups Route::put('users/{user}/groups', [UserController::class, 'updateGroups'])->name('users.groups.update')->middleware('can:edit-users');