Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | 22x 13x 13x 7x 7x 7x 7x 2x 2x 3x 7x 2x 2x 1x 7x 7x | /**
* useUpdateUserRoles Hook
*
* React Query mutation hook for updating user roles with optimistic updates.
* Story 2.5.2: User Management Frontend - AC3
*/
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { updateUserRoles } from '@/services/api/userManagementApi';
import type { User, Role } from '@/types/user.types';
interface UpdateRolesParams {
id: string;
roles: Role[];
}
export const useUpdateUserRoles = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, roles }: UpdateRolesParams) => updateUserRoles(id, roles),
// Optimistic update
onMutate: async ({ id, roles }) => {
// Cancel any outgoing refetches
await queryClient.cancelQueries({ queryKey: ['users', 'list'] });
// Snapshot the previous value
const previousData = queryClient.getQueriesData({ queryKey: ['users', 'list'] });
// Optimistically update all user list queries
queryClient.setQueriesData(
{ queryKey: ['users', 'list'] },
(old: { data: User[] } | undefined) => {
Iif (!old?.data) return old;
return {
...old,
data: old.data.map((user: User) => (user.id === id ? { ...user, roles } : user)),
};
}
);
// Return context with previous data
return { previousData };
},
// On error, rollback to previous state
onError: (_err, _variables, context) => {
Eif (context?.previousData) {
context.previousData.forEach(([queryKey, data]) => {
queryClient.setQueryData(queryKey, data);
});
}
},
// Always refetch after success or error
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['users', 'list'] });
queryClient.invalidateQueries({ queryKey: ['users', 'detail'] });
},
});
};
|