Spaces:
Sleeping
Sleeping
| import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; | |
| import { systemDetailsApi } from '@/services/systemDetailsApi'; | |
| import { SystemDetails, SystemDetailsCreateRequest, SystemDetailsUpdateRequest } from '@/types/asset-management'; | |
| import { toast } from '@/lib/custom-toast'; | |
| import { assetQueryKeys } from './useAssets'; | |
| // Query keys for system details-related queries | |
| export const systemDetailsQueryKeys = { | |
| all: ['systemDetails'] as const, | |
| lists: () => [...systemDetailsQueryKeys.all, 'list'] as const, | |
| list: (filters?: any) => [...systemDetailsQueryKeys.lists(), { filters }] as const, | |
| details: () => [...systemDetailsQueryKeys.all, 'detail'] as const, | |
| detail: (id: number) => [...systemDetailsQueryKeys.details(), id] as const, | |
| byAsset: (assetId: number) => [...systemDetailsQueryKeys.all, 'byAsset', assetId] as const, | |
| }; | |
| /** | |
| * Hook for fetching all system details | |
| */ | |
| export const useSystemDetails = () => { | |
| return useQuery({ | |
| queryKey: systemDetailsQueryKeys.lists(), | |
| queryFn: () => systemDetailsApi.getAll(), | |
| staleTime: 5 * 60 * 1000, // 5 minutes | |
| gcTime: 10 * 60 * 1000, // 10 minutes | |
| }); | |
| }; | |
| /** | |
| * Hook for fetching a single system details record by ID | |
| */ | |
| export const useSystemDetail = (id: number) => { | |
| return useQuery({ | |
| queryKey: systemDetailsQueryKeys.detail(id), | |
| queryFn: () => systemDetailsApi.getById(id), | |
| staleTime: 5 * 60 * 1000, // 5 minutes | |
| gcTime: 10 * 60 * 1000, // 10 minutes | |
| enabled: !!id && id > 0, // Only run query if ID is valid | |
| }); | |
| }; | |
| /** | |
| * Hook for fetching system details by asset ID | |
| */ | |
| export const useSystemDetailsByAsset = (assetId: number) => { | |
| return useQuery({ | |
| queryKey: systemDetailsQueryKeys.byAsset(assetId), | |
| queryFn: () => systemDetailsApi.getByAssetId(assetId), | |
| staleTime: 5 * 60 * 1000, // 5 minutes | |
| gcTime: 10 * 60 * 1000, // 10 minutes | |
| enabled: !!assetId && assetId > 0, // Only run query if asset ID is valid | |
| }); | |
| }; | |
| /** | |
| * Hook for creating new system details | |
| */ | |
| export const useCreateSystemDetails = () => { | |
| const queryClient = useQueryClient(); | |
| return useMutation({ | |
| mutationFn: (systemDetails: SystemDetailsCreateRequest) => | |
| systemDetailsApi.create(systemDetails), | |
| onSuccess: (newSystemDetails) => { | |
| // Invalidate and refetch system details lists | |
| queryClient.invalidateQueries({ queryKey: systemDetailsQueryKeys.lists() }); | |
| // Invalidate system details for the specific asset | |
| queryClient.invalidateQueries({ | |
| queryKey: systemDetailsQueryKeys.byAsset(newSystemDetails.assetID) | |
| }); | |
| // Optionally add the new system details to the cache | |
| queryClient.setQueryData( | |
| systemDetailsQueryKeys.detail(newSystemDetails.systemDetailsID), | |
| newSystemDetails | |
| ); | |
| // Invalidate the asset details to refresh related data | |
| queryClient.invalidateQueries({ | |
| queryKey: assetQueryKeys.detail(newSystemDetails.assetID) | |
| }); | |
| toast.success('System details created successfully'); | |
| }, | |
| onError: (error) => { | |
| console.error('Create system details error:', error); | |
| toast.error('Failed to create system details'); | |
| }, | |
| }); | |
| }; | |
| /** | |
| * Hook for updating existing system details | |
| */ | |
| export const useUpdateSystemDetails = () => { | |
| const queryClient = useQueryClient(); | |
| return useMutation({ | |
| mutationFn: ({ id, systemDetails }: { id: number; systemDetails: SystemDetailsUpdateRequest }) => | |
| systemDetailsApi.update(id, systemDetails), | |
| onMutate: async ({ id, systemDetails }) => { | |
| // Cancel any outgoing refetches | |
| await queryClient.cancelQueries({ queryKey: systemDetailsQueryKeys.detail(id) }); | |
| // Snapshot the previous value | |
| const previousSystemDetails = queryClient.getQueryData(systemDetailsQueryKeys.detail(id)); | |
| // Optimistically update to the new value | |
| queryClient.setQueryData(systemDetailsQueryKeys.detail(id), systemDetails); | |
| // Return a context object with the snapshotted value | |
| return { previousSystemDetails, id, assetId: systemDetails.assetID }; | |
| }, | |
| onError: (error, variables, context) => { | |
| // If the mutation fails, use the context returned from onMutate to roll back | |
| if (context?.previousSystemDetails) { | |
| queryClient.setQueryData( | |
| systemDetailsQueryKeys.detail(context.id), | |
| context.previousSystemDetails | |
| ); | |
| } | |
| console.error('Update system details error:', error); | |
| toast.error('Failed to update system details'); | |
| }, | |
| onSuccess: (updatedSystemDetails, { id }) => { | |
| // Update the system details in the cache | |
| queryClient.setQueryData(systemDetailsQueryKeys.detail(id), updatedSystemDetails); | |
| // Invalidate system details lists to ensure consistency | |
| queryClient.invalidateQueries({ queryKey: systemDetailsQueryKeys.lists() }); | |
| // Invalidate system details for the specific asset | |
| queryClient.invalidateQueries({ | |
| queryKey: systemDetailsQueryKeys.byAsset(updatedSystemDetails.assetID) | |
| }); | |
| // Invalidate the asset details to refresh related data | |
| queryClient.invalidateQueries({ | |
| queryKey: assetQueryKeys.detail(updatedSystemDetails.assetID) | |
| }); | |
| toast.success('System details updated successfully'); | |
| }, | |
| }); | |
| }; | |
| /** | |
| * Hook for deleting system details | |
| */ | |
| export const useDeleteSystemDetails = () => { | |
| const queryClient = useQueryClient(); | |
| return useMutation({ | |
| mutationFn: (id: number) => systemDetailsApi.delete(id), | |
| onMutate: async (id) => { | |
| // Cancel any outgoing refetches | |
| await queryClient.cancelQueries({ queryKey: systemDetailsQueryKeys.detail(id) }); | |
| await queryClient.cancelQueries({ queryKey: systemDetailsQueryKeys.lists() }); | |
| // Snapshot the previous values | |
| const previousSystemDetails = queryClient.getQueryData(systemDetailsQueryKeys.detail(id)); | |
| const previousSystemDetailsList = queryClient.getQueryData(systemDetailsQueryKeys.lists()); | |
| // Get the asset ID from the system details to invalidate related queries | |
| const systemDetails = previousSystemDetails as SystemDetails; | |
| const assetId = systemDetails?.assetID; | |
| // Optimistically remove the system details from the list | |
| if (previousSystemDetailsList) { | |
| queryClient.setQueryData( | |
| systemDetailsQueryKeys.lists(), | |
| (previousSystemDetailsList as SystemDetails[]).filter( | |
| details => details.systemDetailsID !== id | |
| ) | |
| ); | |
| } | |
| // Optimistically remove from asset-specific list if we have the asset ID | |
| if (assetId) { | |
| const previousAssetSystemDetails = queryClient.getQueryData( | |
| systemDetailsQueryKeys.byAsset(assetId) | |
| ); | |
| if (previousAssetSystemDetails) { | |
| queryClient.setQueryData( | |
| systemDetailsQueryKeys.byAsset(assetId), | |
| (previousAssetSystemDetails as SystemDetails[]).filter( | |
| details => details.systemDetailsID !== id | |
| ) | |
| ); | |
| } | |
| } | |
| // Return a context object with the snapshotted values | |
| return { | |
| previousSystemDetails, | |
| previousSystemDetailsList, | |
| id, | |
| assetId | |
| }; | |
| }, | |
| onError: (error, id, context) => { | |
| // If the mutation fails, use the context to roll back | |
| if (context?.previousSystemDetailsList) { | |
| queryClient.setQueryData(systemDetailsQueryKeys.lists(), context.previousSystemDetailsList); | |
| } | |
| if (context?.previousSystemDetails) { | |
| queryClient.setQueryData(systemDetailsQueryKeys.detail(id), context.previousSystemDetails); | |
| } | |
| if (context?.assetId) { | |
| // Invalidate asset-specific system details to refresh from server | |
| queryClient.invalidateQueries({ | |
| queryKey: systemDetailsQueryKeys.byAsset(context.assetId) | |
| }); | |
| } | |
| console.error('Delete system details error:', error); | |
| toast.error('Failed to delete system details'); | |
| }, | |
| onSuccess: (_, id, context) => { | |
| // Remove the system details from the cache | |
| queryClient.removeQueries({ queryKey: systemDetailsQueryKeys.detail(id) }); | |
| // Invalidate system details lists to ensure consistency | |
| queryClient.invalidateQueries({ queryKey: systemDetailsQueryKeys.lists() }); | |
| // Invalidate system details for the specific asset if we have the asset ID | |
| if (context?.assetId) { | |
| queryClient.invalidateQueries({ | |
| queryKey: systemDetailsQueryKeys.byAsset(context.assetId) | |
| }); | |
| // Invalidate the asset details to refresh related data | |
| queryClient.invalidateQueries({ | |
| queryKey: assetQueryKeys.detail(context.assetId) | |
| }); | |
| } | |
| toast.success('System details deleted successfully'); | |
| }, | |
| }); | |
| }; |