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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | 5x 16x 16x 8x 5x 5x 19x 19x 10x 10x 10x 10x 3x 10x 6x 6x 3x 2x 5x 26x 26x 9x 5x 5x | /**
* useCompanyMutations Hooks
*
* React Query mutation hooks for company CRUD operations with optimistic updates
* AC 3 (Create Company), AC 4 (Edit Company), AC 10 (Performance), AC 14 (State Management)
*/
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { companyApiClient } from '@/services/api/companyApi';
import type { components } from '@/types/generated/company-api.types';
type Company = components['schemas']['CompanyResponse'];
type CreateCompanyRequest = components['schemas']['CreateCompanyRequest'];
type UpdateCompanyRequest = components['schemas']['UpdateCompanyRequest'];
/**
* Create new company mutation
*
* Features:
* - Automatic cache invalidation of companies list
* - Support for draft mode (partial validation)
* - Error handling with correlation IDs
*
* @returns Mutation hook for creating companies
*/
export const useCreateCompany = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: CreateCompanyRequest) => companyApiClient.createCompany(data),
onSuccess: () => {
// Invalidate companies list to refetch with new company
queryClient.invalidateQueries({ queryKey: ['companies'] });
},
});
};
/**
* Update existing company mutation with optimistic updates
*
* Features:
* - Optimistic UI updates (immediate feedback)
* - Rollback on error
* - Cache invalidation of both list and detail
* - Partial update support (only changed fields)
*
* Story 1.16.2: Uses company name as identifier instead of UUID
*
* @returns Mutation hook for updating companies
*/
export const useUpdateCompany = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ name, data }: { name: string; data: UpdateCompanyRequest }) =>
companyApiClient.updateCompany(name, data),
// Optimistic update (AC 14 - State Management with immediate UI feedback)
onMutate: async ({ name, data }) => {
// Cancel any outgoing refetches to prevent overwriting optimistic update
await queryClient.cancelQueries({ queryKey: ['company', name] });
// Snapshot the previous value for rollback
const previousCompany = queryClient.getQueryData(['company', name, undefined]);
// Optimistically update to the new value
if (previousCompany) {
queryClient.setQueryData(['company', name, undefined], (old: Company) => ({
...old,
...data,
}));
}
// Return context with snapshot for rollback
return { previousCompany };
},
// On success, invalidate caches to refetch fresh data
onSuccess: (_, { name }) => {
queryClient.invalidateQueries({ queryKey: ['companies'] });
queryClient.invalidateQueries({ queryKey: ['company', name] });
},
// Rollback on error (AC 14 - Error handling with rollback)
onError: (_error, { name }, context) => {
if (context?.previousCompany) {
queryClient.setQueryData(['company', name, undefined], context.previousCompany);
}
},
});
};
/**
* Delete company mutation
*
* Features:
* - Cache invalidation of companies list
* - Removal of deleted company from detail cache
* - Error handling for permission/dependency issues
*
* Story 1.16.2: Uses company name as identifier instead of UUID
*
* @returns Mutation hook for deleting companies
*/
export const useDeleteCompany = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (name: string) => companyApiClient.deleteCompany(name),
onSuccess: (_, name) => {
// Invalidate companies list
queryClient.invalidateQueries({ queryKey: ['companies'] });
// Remove deleted company from cache
queryClient.removeQueries({ queryKey: ['company', name] });
},
});
};
|