From 10aff131b71ad1215418ec23422158927ddea815 Mon Sep 17 00:00:00 2001 From: Abhishekfm Date: Fri, 14 Aug 2026 15:14:33 +0530 Subject: [PATCH] Refactor AI model edit pages to enhance query management and state handling - Updated query keys to include entityType and entitySlug for improved data consistency. - Integrated useQueryClient for better cache invalidation upon mutation success. - Replaced direct refetch calls with centralized query invalidation functions to streamline data fetching. - Enhanced loading states and error handling across various components for a better user experience. --- .../aimodels/edit/[id]/details/page.tsx | 34 +++++++++++--- .../aimodels/edit/[id]/publish/page.tsx | 10 ++++- .../aimodels/edit/[id]/versions/page.tsx | 44 ++++++++++++------- .../[entitySlug]/aimodels/edit/layout.tsx | 26 ++++++++++- 4 files changed, 86 insertions(+), 28 deletions(-) diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/[id]/details/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/[id]/details/page.tsx index 40c5f6aa..e675aedf 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/[id]/details/page.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/[id]/details/page.tsx @@ -214,7 +214,12 @@ export default function AIModelDetailsPage() { refetch: any; error: any; } = useQuery( - [`fetch_AIModelDetails_${params.id}`], + [ + `fetch_AIModelDetails`, + params.id, + params.entityType, + params.entitySlug, + ], () => GraphQL( FetchAIModelDetails, @@ -229,7 +234,7 @@ export default function AIModelDetailsPage() { ), { refetchOnMount: true, - keepPreviousData: false, + refetchOnReconnect: true, } ); @@ -258,7 +263,22 @@ export default function AIModelDetailsPage() { setIsTagsListUpdated(false); } AIModelData.refetch(); - queryClient.invalidateQueries([`fetch_AIModelForPublish_${params.id}`]); + queryClient.invalidateQueries({ + queryKey: [ + `fetch_AIModelForPublish`, + params.id, + params.entityType, + params.entitySlug, + ], + }); + queryClient.invalidateQueries({ + queryKey: [ + `fetch_AIModelData`, + params.id, + params.entityType, + params.entitySlug, + ], + }); }, onError: (error: any) => { const errorMessage = @@ -531,7 +551,7 @@ export default function AIModelDetailsPage() { } key={`sectors-${getSectorsList.data?.sectors?.length || 0}-${formData.sectors.length}`} label="Sectors" - selectedValue={formData.sectors} + selectedValue={formData.sectors || []} onChange={(value) => { handleInputChange('sectors', value); handleSave({ ...formData, sectors: value }); @@ -553,7 +573,7 @@ export default function AIModelDetailsPage() { key={`tags-${getTagsList.data?.tags?.length || 0}-${formData.tags.length}`} label="Tags" creatable - selectedValue={formData.tags} + selectedValue={formData.tags || []} requiredIndicator onChange={(value) => { setIsTagsListUpdated(true); @@ -583,7 +603,7 @@ export default function AIModelDetailsPage() { list={languageOptions} label="Languages" key={`languages-${formData.supportedLanguages.length}`} - selectedValue={formData.supportedLanguages} + selectedValue={formData.supportedLanguages || []} onChange={(value) => { handleInputChange('supportedLanguages', value); handleSave({ ...formData, supportedLanguages: value }); @@ -619,7 +639,7 @@ export default function AIModelDetailsPage() { key={`geographies-${getGeographiesList.data?.geographies?.length || 0}-${formData.geographies.length}`} label="Locations / Geography" requiredIndicator - selectedValue={formData.geographies} + selectedValue={formData.geographies || []} onChange={(value) => { handleInputChange('geographies', value); handleSave({ ...formData, geographies: value }); diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/[id]/publish/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/[id]/publish/page.tsx index 0ccff274..59a4dbbc 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/[id]/publish/page.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/[id]/publish/page.tsx @@ -151,7 +151,12 @@ export default function PublishPage() { const { setStatus } = useEditStatus(); const { data, isLoading, refetch } = useQuery( - [`fetch_AIModelForPublish_${params.id}`], + [ + `fetch_AIModelForPublish`, + params.id, + params.entityType, + params.entitySlug, + ], () => GraphQL( FetchAIModelForPublish, @@ -165,7 +170,8 @@ export default function PublishPage() { } ), { - refetchOnMount: true, + refetchOnMount: 'always', + refetchOnReconnect: 'always', } ); diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/[id]/versions/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/[id]/versions/page.tsx index ca90e82d..caba7c8f 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/[id]/versions/page.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/[id]/versions/page.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useEffect, useState } from 'react'; +import { useState } from 'react'; import { useParams } from 'next/navigation'; import { graphql } from '@/gql'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; @@ -145,11 +145,25 @@ export default function VersionsPage() { id: string; }>(); const queryClient = useQueryClient(); - - // Invalidate cache on mount to force fresh fetch - useEffect(() => { - queryClient.invalidateQueries([`fetch_model_versions_${params.id}`]); - }, [params.id, queryClient]); + const versionsQueryKey = [ + `fetch_model_versions`, + params.id, + params.entityType, + params.entitySlug, + ]; + const invalidateVersionQueries = () => { + queryClient.invalidateQueries({ + queryKey: versionsQueryKey, + }); + queryClient.invalidateQueries({ + queryKey: [ + `fetch_AIModelForPublish`, + params.id, + params.entityType, + params.entitySlug, + ], + }); + }; const [isNewVersionModalOpen, setIsNewVersionModalOpen] = useState(false); const [isProviderModalOpen, setIsProviderModalOpen] = useState(false); @@ -201,15 +215,15 @@ export default function VersionsPage() { const VERSIONS_VALIDATION_TOAST_ID = 'aimodel-versions-validation-toast'; // Fetch model versions - override default refetchOnMount: false const { data, isLoading, refetch } = useQuery( - [`fetch_model_versions_${params.id}`], + versionsQueryKey, () => GraphQL(fetchModelVersions, { [params.entityType]: params.entitySlug }, { filters: { id: parseInt(params.id) }, } as any), { enabled: !!params.id, - staleTime: 0, refetchOnMount: true, + refetchOnReconnect: true, } ); @@ -230,7 +244,7 @@ export default function VersionsPage() { toast('New version created successfully!',{id: VERSIONS_ACTION_TOAST_ID}); setIsNewVersionModalOpen(false); resetVersionForm(); - queryClient.invalidateQueries([`fetch_AIModelForPublish_${params.id}`]); + invalidateVersionQueries(); // Force refetch and update selected version const result = await refetch(); @@ -266,9 +280,7 @@ export default function VersionsPage() { toast('Provider added successfully!',{id: VERSIONS_ACTION_TOAST_ID}); setIsProviderModalOpen(false); resetProviderForm(); - queryClient.invalidateQueries([ - `fetch_AIModelForPublish_${params.id}`, - ]); + invalidateVersionQueries(); // Force refetch and update selected version with new provider const result = await refetch(); @@ -302,9 +314,7 @@ export default function VersionsPage() { setIsProviderModalOpen(false); setEditingProvider(null); resetProviderForm(); - queryClient.invalidateQueries([ - `fetch_AIModelForPublish_${params.id}`, - ]); + invalidateVersionQueries(); // Force refetch and update selected version with updated provider const result = await refetch(); @@ -335,7 +345,7 @@ export default function VersionsPage() { { onSuccess: async () => { toast('Provider deleted successfully!',{id: VERSIONS_ACTION_TOAST_ID}); - queryClient.invalidateQueries([`fetch_AIModelForPublish_${params.id}`]); + invalidateVersionQueries(); // Force refetch and update selected version after provider deletion const result = await refetch(); @@ -617,7 +627,7 @@ export default function VersionsPage() { onSuccess: () => { toast('Version updated successfully!',{id: VERSIONS_ACTION_TOAST_ID}); refetch(); - queryClient.invalidateQueries([`fetch_AIModelForPublish_${params.id}`]); + invalidateVersionQueries(); }, onError: (error: any) => { toast(`Error: ${error.message}`,{id: VERSIONS_ACTION_TOAST_ID}); diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/layout.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/layout.tsx index 69f98d5b..85b613ef 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/layout.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/aimodels/edit/layout.tsx @@ -1,7 +1,7 @@ 'use client'; import { graphql } from '@/gql'; -import { useMutation, useQuery } from '@tanstack/react-query'; +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useParams, usePathname, @@ -47,6 +47,7 @@ const TabsAndChildren = ({ children }: { children: React.ReactNode }) => { entitySlug: string; id: string; }>(); + const queryClient = useQueryClient(); const layoutList = ['details', 'versions', 'publish']; @@ -55,7 +56,12 @@ const TabsAndChildren = ({ children }: { children: React.ReactNode }) => { }); const AIModelData: { data: any; isLoading: boolean; refetch: any } = useQuery( - [`fetch_AIModelData_${params.id}`], + [ + `fetch_AIModelData`, + params.id, + params.entityType, + params.entitySlug, + ], () => GraphQL( FetchAIModelName, @@ -94,6 +100,22 @@ const TabsAndChildren = ({ children }: { children: React.ReactNode }) => { onSuccess: () => { toast('AI Model updated successfully',{id: AIMODEL_TITLE_SUCCESS_TOAST_ID}); AIModelData.refetch(); + queryClient.invalidateQueries({ + queryKey: [ + `fetch_AIModelForPublish`, + params.id, + params.entityType, + params.entitySlug, + ], + }); + queryClient.invalidateQueries({ + queryKey: [ + `fetch_AIModelDetails`, + params.id, + params.entityType, + params.entitySlug, + ], + }); }, onError: (error: any) => { toast(`Error: ${error.message}`,{id: AIMODEL_TITLE_ERROR_TOAST_ID});