diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/contributors/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/contributors/page.tsx
index f9bcf5a8..6b067421 100644
--- a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/contributors/page.tsx
+++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/contributors/page.tsx
@@ -1,14 +1,14 @@
'use client';
-import { useMutation, useQuery } from '@tanstack/react-query';
+import { useEffect, useState } from 'react';
import Image from 'next/image';
import { useParams } from 'next/navigation';
+import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { Button, Icon, Text, toast } from 'opub-ui';
-import { useEffect, useState } from 'react';
+import { GraphQL } from '@/lib/api';
import { Icons } from '@/components/icons';
import { Loading } from '@/components/loading';
-import { GraphQL } from '@/lib/api';
import { useEditStatus } from '../../context';
import CustomCombobox from './CustomCombobox';
import EntitySection from './EntitySelection';
@@ -25,10 +25,15 @@ import {
} from './query';
const Details = () => {
- const params = useParams<{ entityType: string; entitySlug: string; id: string }>();
+ const params = useParams<{
+ entityType: string;
+ entitySlug: string;
+ id: string;
+ }>();
const CONTRIBUTORS_ADD_SUCCESS_TOAST_ID = 'usecase-contributor-add-success';
const CONTRIBUTORS_ADD_ERROR_TOAST_ID = 'usecase-contributor-add-error';
- const CONTRIBUTORS_REMOVE_SUCCESS_TOAST_ID = 'usecase-contributor-remove-success';
+ const CONTRIBUTORS_REMOVE_SUCCESS_TOAST_ID =
+ 'usecase-contributor-remove-success';
const CONTRIBUTORS_REMOVE_ERROR_TOAST_ID = 'usecase-contributor-remove-error';
const SUPPORTER_ADD_SUCCESS_TOAST_ID = 'usecase-supporter-add-success';
const SUPPORTER_ADD_ERROR_TOAST_ID = 'usecase-supporter-add-error';
@@ -69,13 +74,18 @@ const Details = () => {
);
const Organizations: { data: any; isLoading: boolean; refetch: any } =
- useQuery([`fetch_orgs`], () => GraphQL(OrgList, {
- [params.entityType]: params.entitySlug,
- }, []));
-
+ useQuery([`fetch_orgs`], () =>
+ GraphQL(
+ OrgList,
+ {
+ [params.entityType]: params.entitySlug,
+ },
+ []
+ )
+ );
const UseCaseData: { data: any; isLoading: boolean; refetch: any } = useQuery(
- [`fetch_usecase_${params.id}`],
+ [`fetch_usecase`, params.id, params.entityType, params.entitySlug],
() =>
GraphQL(
FetchUsecaseInfo,
@@ -119,18 +129,31 @@ const Details = () => {
}));
}, [UseCaseData?.data]);
+ const queryClient = useQueryClient();
+
const { mutate: addContributor, isLoading: addContributorLoading } =
useMutation(
(input: { useCaseId: string; userId: string }) =>
- GraphQL(AddContributors, {
- [params.entityType]: params.entitySlug,
- }, input),
+ GraphQL(
+ AddContributors,
+ {
+ [params.entityType]: params.entitySlug,
+ },
+ input
+ ),
{
onSuccess: () => {
toast('Contributor added successfully', {
id: CONTRIBUTORS_ADD_SUCCESS_TOAST_ID,
});
- UseCaseData.refetch();
+ queryClient.invalidateQueries({
+ queryKey: [
+ `fetch_usecase`,
+ params.id,
+ params.entityType,
+ params.entitySlug,
+ ],
+ });
},
onError: (error: any) => {
toast(
@@ -144,14 +167,26 @@ const Details = () => {
const { mutate: removeContributor, isLoading: removeContributorLoading } =
useMutation(
(input: { useCaseId: string; userId: string }) =>
- GraphQL(RemoveContributor, {
- [params.entityType]: params.entitySlug,
- }, input),
+ GraphQL(
+ RemoveContributor,
+ {
+ [params.entityType]: params.entitySlug,
+ },
+ input
+ ),
{
onSuccess: () => {
toast('Contributor removed successfully', {
id: CONTRIBUTORS_REMOVE_SUCCESS_TOAST_ID,
});
+ queryClient.invalidateQueries({
+ queryKey: [
+ `fetch_usecase`,
+ params.id,
+ params.entityType,
+ params.entitySlug,
+ ],
+ });
},
onError: (error: any) => {
toast(
@@ -164,15 +199,26 @@ const Details = () => {
const { mutate: addSupporter, isLoading: addSupporterLoading } = useMutation(
(input: { useCaseId: string; organizationId: string }) =>
- GraphQL(AddSupporters, {
- [params.entityType]: params.entitySlug,
- }, input),
+ GraphQL(
+ AddSupporters,
+ {
+ [params.entityType]: params.entitySlug,
+ },
+ input
+ ),
{
onSuccess: () => {
toast('Supporter added successfully', {
id: SUPPORTER_ADD_SUCCESS_TOAST_ID,
});
- UseCaseData.refetch();
+ queryClient.invalidateQueries({
+ queryKey: [
+ `fetch_usecase`,
+ params.id,
+ params.entityType,
+ params.entitySlug,
+ ],
+ });
},
onError: (error: any) => {
toast(
@@ -186,14 +232,26 @@ const Details = () => {
const { mutate: removeSupporter, isLoading: removeSupporterLoading } =
useMutation(
(input: { useCaseId: string; organizationId: string }) =>
- GraphQL(RemoveSupporters, {
- [params.entityType]: params.entitySlug,
- }, input),
+ GraphQL(
+ RemoveSupporters,
+ {
+ [params.entityType]: params.entitySlug,
+ },
+ input
+ ),
{
onSuccess: () => {
toast('Supporter removed successfully', {
id: SUPPORTER_REMOVE_SUCCESS_TOAST_ID,
});
+ queryClient.invalidateQueries({
+ queryKey: [
+ `fetch_usecase`,
+ params.id,
+ params.entityType,
+ params.entitySlug,
+ ],
+ });
},
onError: (error: any) => {
toast(
@@ -206,13 +264,26 @@ const Details = () => {
const { mutate: addPartner, isLoading: addPartnerLoading } = useMutation(
(input: { useCaseId: string; organizationId: string }) =>
- GraphQL(AddPartners, {
- [params.entityType]: params.entitySlug,
- }, input),
+ GraphQL(
+ AddPartners,
+ {
+ [params.entityType]: params.entitySlug,
+ },
+ input
+ ),
{
onSuccess: () => {
- toast('Partner added successfully', { id: PARTNER_ADD_SUCCESS_TOAST_ID });
- UseCaseData.refetch();
+ toast('Partner added successfully', {
+ id: PARTNER_ADD_SUCCESS_TOAST_ID,
+ });
+ queryClient.invalidateQueries({
+ queryKey: [
+ `fetch_usecase`,
+ params.id,
+ params.entityType,
+ params.entitySlug,
+ ],
+ });
},
onError: (error: any) => {
toast(
@@ -226,14 +297,26 @@ const Details = () => {
const { mutate: removePartner, isLoading: removePartnerLoading } =
useMutation(
(input: { useCaseId: string; organizationId: string }) =>
- GraphQL(RemovePartners, {
- [params.entityType]: params.entitySlug,
- }, input),
+ GraphQL(
+ RemovePartners,
+ {
+ [params.entityType]: params.entitySlug,
+ },
+ input
+ ),
{
onSuccess: () => {
toast('Partner removed successfully', {
id: PARTNER_REMOVE_SUCCESS_TOAST_ID,
});
+ queryClient.invalidateQueries({
+ queryKey: [
+ `fetch_usecase`,
+ params.id,
+ params.entityType,
+ params.entitySlug,
+ ],
+ });
},
onError: (error: any) => {
toast(
@@ -353,7 +436,7 @@ const Details = () => {
}}
kind="tertiary"
>
-
+
{item.label}
diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/dashboards/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/dashboards/page.tsx
index d733559c..26c89c03 100644
--- a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/dashboards/page.tsx
+++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/dashboards/page.tsx
@@ -4,8 +4,8 @@ import { useEffect, useState } from 'react';
import Link from 'next/link';
import { useParams } from 'next/navigation';
import { graphql } from '@/gql';
-import { useMutation, useQuery } from '@tanstack/react-query';
-import { Button, Icon, Text, TextField, toast } from 'opub-ui';
+import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
+import { Button, Icon, Spinner, Text, TextField, toast } from 'opub-ui';
import { GraphQL } from '@/lib/api';
import { Icons } from '@/components/icons';
@@ -75,7 +75,11 @@ const deleteDashboard: any = graphql(`
`);
const Dashboard = () => {
- const params = useParams<{ entityType?: string; entitySlug?: string; id?: string }>();
+ const params = useParams<{
+ entityType?: string;
+ entitySlug?: string;
+ id?: string;
+ }>();
const DASHBOARD_ADD_SUCCESS_TOAST_ID = 'usecase-dashboard-add-success';
const DASHBOARD_SAVE_SUCCESS_TOAST_ID = 'usecase-dashboard-save-success';
const DASHBOARD_DELETE_SUCCESS_TOAST_ID = 'usecase-dashboard-delete-success';
@@ -94,9 +98,8 @@ const Dashboard = () => {
typeof entitySlug === 'string' &&
typeof idParam === 'string';
- const usecaseId = isValidParams && idParam
- ? Number.parseInt(idParam, 10)
- : NaN;
+ const usecaseId =
+ isValidParams && idParam ? Number.parseInt(idParam, 10) : NaN;
const isValidId = !Number.isNaN(usecaseId) && isValidParams;
@@ -109,37 +112,46 @@ const Dashboard = () => {
>([]);
const [previousState, setPreviousState] = useState
({});
- useQuery(
- ['fetch_dashboardData', usecaseId],
+ const queryKey = [
+ 'fetch_dashboardData',
+ params.entityType,
+ params.entitySlug,
+ usecaseId,
+ ];
+
+ const { data: dashboardData, isLoading }: { data: any; isLoading: boolean } =
+ useQuery(
+ queryKey,
() => GraphQL(dashboardList, ownerArgs || {}, { usecaseId }),
{
refetchOnMount: true,
refetchOnReconnect: true,
enabled: isValidId,
- onSuccess: (res: any) => {
- setDashboards(res.usecaseDashboards || []);
- setPreviousState(
- Object.fromEntries(
- res.usecaseDashboards.map((item: any) => [item.id, { ...item }])
- )
- );
- },
}
);
+ useEffect(() => {
+ if (dashboardData?.usecaseDashboards) {
+ setDashboards(dashboardData.usecaseDashboards);
+ setPreviousState(
+ Object.fromEntries(
+ dashboardData.usecaseDashboards.map((item: any) => [item.id, { ...item }])
+ )
+ );
+ }
+ }, [dashboardData]);
+
+ const queryClient = useQueryClient();
+
const { mutate: addDashboard, isLoading: addLoading } = useMutation(
({ usecaseId }: { usecaseId: number }) =>
GraphQL(AddDashboard, ownerArgs || {}, { usecaseId }),
{
- onSuccess: (res: any) => {
- const newDashboard = res.addUsecaseDashboard.data;
-
- setDashboards((prev: any) => [...prev, newDashboard]);
- setPreviousState((prev: any) => ({
- ...prev,
- [newDashboard.id]: { ...newDashboard },
- }));
- toast.success('Dashboard added', { id: DASHBOARD_ADD_SUCCESS_TOAST_ID });
+ onSuccess: () => {
+ queryClient.invalidateQueries({ queryKey });
+ toast.success('Dashboard added', {
+ id: DASHBOARD_ADD_SUCCESS_TOAST_ID,
+ });
},
}
);
@@ -148,6 +160,7 @@ const Dashboard = () => {
GraphQL(updateDashboard, ownerArgs || {}, { id, name, link }),
{
onSuccess: ({ updateUsecaseDashboard }: any) => {
+ queryClient.invalidateQueries({ queryKey });
toast.success('Changes saved', { id: DASHBOARD_SAVE_SUCCESS_TOAST_ID });
setPreviousState((prev: any) => ({
...prev,
@@ -166,9 +179,11 @@ const Dashboard = () => {
const { mutate: removeDashboard, isLoading: deleteLoading } = useMutation(
(id: number) => GraphQL(deleteDashboard, ownerArgs || {}, { id }),
{
- onSuccess: (_, id) => {
- setDashboards((prev) => prev.filter((d) => d.id !== id.toString()));
- toast.success('Dashboard deleted', { id: DASHBOARD_DELETE_SUCCESS_TOAST_ID });
+ onSuccess: () => {
+ toast.success('Dashboard deleted', {
+ id: DASHBOARD_DELETE_SUCCESS_TOAST_ID,
+ });
+ queryClient.invalidateQueries({ queryKey });
},
onError: (error: any) => {
toast(
@@ -236,42 +251,50 @@ const Dashboard = () => {
.
- {dashboards?.map((item) => (
-
-
- handleChange(item.id, 'name', e)}
- onBlur={() => handleSave(item)}
- />
-
-
- handleChange(item.id, 'link', e)}
- onBlur={() => handleSave(item)}
- />
-
-
+ {isLoading ? (
+
+
- ))}
-
+ ) : (
+ <>
+ {dashboards?.map((item) => (
+
+
+ handleChange(item.id, 'name', e)}
+ onBlur={() => handleSave(item)}
+ />
+
+
+ handleChange(item.id, 'link', e)}
+ onBlur={() => handleSave(item)}
+ />
+
+
+
+ ))}
+
+ >
+ )}
);
};
diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/details/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/details/page.tsx
index 09b6ae83..04bbe418 100644
--- a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/details/page.tsx
+++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/details/page.tsx
@@ -4,7 +4,7 @@ import React, { useCallback, useEffect, useState } from 'react';
import { useParams } from 'next/navigation';
import { graphql } from '@/gql';
import { UseCaseInputPartial } from '@/gql/generated/graphql';
-import { useMutation, useQuery } from '@tanstack/react-query';
+import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { DropZone, Select, TextField, toast } from 'opub-ui';
// Assuming you are using these components
@@ -76,7 +76,12 @@ const Details = () => {
: fallback;
const UseCaseData: { data: any; isLoading: boolean; refetch: any } = useQuery(
- [`fetch_UseCaseData_details`],
+ [
+ `fetch_UseCaseData_details`,
+ params.id,
+ params.entityType,
+ params.entitySlug,
+ ],
() =>
GraphQL(
FetchUseCase,
@@ -156,6 +161,8 @@ const Details = () => {
}
}, [params.id, UsecasesData]);
+ const queryClient = useQueryClient();
+
const { mutate, isLoading: editMutationLoading } = useMutation(
(data: { data: UseCaseInputPartial }) =>
GraphQL(
@@ -178,6 +185,14 @@ const Details = () => {
...prev,
...res.updateUseCase,
}));
+ queryClient.invalidateQueries({
+ queryKey: [
+ `fetch_UseCaseData_details`,
+ params.id,
+ params.entityType,
+ params.entitySlug,
+ ],
+ });
},
onError: (error: any) => {
toast(
diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/metadata/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/metadata/page.tsx
index 231a7eb4..b199af93 100644
--- a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/metadata/page.tsx
+++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/metadata/page.tsx
@@ -1,5 +1,7 @@
'use client';
+import { useEffect, useState } from 'react';
+import { useParams } from 'next/navigation';
import { graphql } from '@/gql';
import {
MetadataModels,
@@ -8,10 +10,8 @@ import {
TypeTag,
UpdateUseCaseMetadataInput,
} from '@/gql/generated/graphql';
-import { useMutation, useQuery } from '@tanstack/react-query';
-import { useParams } from 'next/navigation';
+import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { Combobox, Spinner, toast } from 'opub-ui';
-import { useEffect, useState } from 'react';
import { GraphQL } from '@/lib/api';
import { useEditStatus } from '../../context';
@@ -169,7 +169,12 @@ const Metadata = () => {
const { setStatus } = useEditStatus();
const useCaseData: { data: any; isLoading: boolean } = useQuery(
- [`fetch_UseCaseData_Metadata`],
+ [
+ `fetch_UseCaseData_Metadata`,
+ params.id,
+ params.entityType,
+ params.entitySlug,
+ ],
() =>
GraphQL(
FetchUseCasedetails,
@@ -247,7 +252,7 @@ const Metadata = () => {
defaultVal['sdgs'] =
data?.sdgs?.map((sdg: any) => {
- const num = sdg.number
+ const num = sdg.number
? String(sdg.number).padStart(2, '0')
: sdg.code.replace('SDG', '').padStart(2, '0');
return {
@@ -272,14 +277,6 @@ const Metadata = () => {
);
const [previousFormData, setPreviousFormData] = useState(formData);
- useEffect(() => {
- if (useCaseData.data?.useCases[0]) {
- const updatedData = defaultValuesPrepFn(useCaseData.data.useCases[0]);
- setFormData(updatedData);
- setPreviousFormData(updatedData);
- }
- }, [useCaseData.data]);
-
const getSectorsList: { data: any; isLoading: boolean; error: any } =
useQuery([`sectors_list_query`], () =>
GraphQL(
@@ -302,8 +299,9 @@ const Metadata = () => {
)
);
- const getSDGsList: { data: any; isLoading: boolean; error: any } =
- useQuery([`sdgs_list_query`], () =>
+ const getSDGsList: { data: any; isLoading: boolean; error: any } = useQuery(
+ [`sdgs_list_query`],
+ () =>
GraphQL(
sdgsListQueryDoc,
{
@@ -311,7 +309,7 @@ const Metadata = () => {
},
[]
)
- );
+ );
const getTagsList: {
data: any;
@@ -329,12 +327,18 @@ const Metadata = () => {
);
const [isTagsListUpdated, setIsTagsListUpdated] = useState(false);
+ const queryClient = useQueryClient();
+
// Update mutation
const updateUseCase = useMutation(
(data: { updateMetadataInput: UpdateUseCaseMetadataInput }) =>
- GraphQL(UpdateUseCaseMetadataMutation, {
- [params.entityType]: params.entitySlug,
- }, data),
+ GraphQL(
+ UpdateUseCaseMetadataMutation,
+ {
+ [params.entityType]: params.entitySlug,
+ },
+ data
+ ),
{
onSuccess: (res: any) => {
toast('Use case updated successfully', {
@@ -347,6 +351,14 @@ const Metadata = () => {
}
setFormData(updatedData);
setPreviousFormData(updatedData);
+ queryClient.invalidateQueries({
+ queryKey: [
+ `fetch_UseCaseData_Metadata`,
+ params.id,
+ params.entityType,
+ params.entitySlug,
+ ],
+ });
},
onError: (error: any) => {
toast(
@@ -361,6 +373,14 @@ const Metadata = () => {
setStatus(updateUseCase.isLoading ? 'loading' : 'success'); // update based on mutation state
}, [updateUseCase.isLoading]);
+ useEffect(() => {
+ if (useCaseData.data?.useCases?.[0]) {
+ const updatedData = defaultValuesPrepFn(useCaseData.data.useCases[0]);
+ setFormData(updatedData);
+ setPreviousFormData(updatedData);
+ }
+ }, [useCaseData.data]);
+
const handleChange = (field: string, value: any) => {
setFormData((prevData) => ({
...prevData,
@@ -392,8 +412,9 @@ const Metadata = () => {
...Object.keys(transformedValues)
.filter(
(valueItem) =>
- !['sectors', 'tags', 'geographies', 'sdgs'].includes(valueItem) &&
- transformedValues[valueItem] !== ''
+ !['sectors', 'tags', 'geographies', 'sdgs'].includes(
+ valueItem
+ ) && transformedValues[valueItem] !== ''
)
.map((key) => {
return {
@@ -441,7 +462,7 @@ const Metadata = () => {
value: option,
}))}
label={metadataFormItem.label}
- selectedValue={formData[metadataFormItem.id]}
+ selectedValue={formData[metadataFormItem.id] || ''}
displaySelected
onChange={(value) => {
handleChange(metadataFormItem.id, value);
@@ -464,7 +485,7 @@ const Metadata = () => {
})) || []),
]}
label={metadataFormItem.label + ' *'}
- selectedValue={formData[metadataFormItem.id]}
+ selectedValue={formData[metadataFormItem.id] || []}
displaySelected
onChange={(value) => {
handleChange(metadataFormItem.id, value);
@@ -489,7 +510,7 @@ const Metadata = () => {
requiredIndicator={true}
list={
getSDGsList?.data?.sdgs?.map((item: any) => {
- const num = item.number
+ const num = item.number
? String(item.number).padStart(2, '0')
: item.code.replace('SDG', '').padStart(2, '0');
return {
@@ -498,7 +519,7 @@ const Metadata = () => {
};
}) || []
}
- selectedValue={formData.sdgs}
+ selectedValue={formData.sdgs || []}
onChange={(value) => {
handleChange('sdgs', value);
handleSave({ ...formData, sdgs: value });
@@ -518,7 +539,7 @@ const Metadata = () => {
})) || []
}
key={`tags-${getTagsList.data?.tags?.length}`} // forces remount on change
- selectedValue={formData.tags}
+ selectedValue={formData.tags || []}
onChange={(value) => {
setIsTagsListUpdated(true);
handleChange('tags', value);
@@ -539,7 +560,7 @@ const Metadata = () => {
value: item.id,
})) || []
}
- selectedValue={formData.sectors}
+ selectedValue={formData.sectors || []}
onChange={(value) => {
handleChange('sectors', value);
handleSave({ ...formData, sectors: value });
@@ -556,7 +577,7 @@ const Metadata = () => {
value: item.id,
})) || []
}
- selectedValue={formData.geographies}
+ selectedValue={formData.geographies || []}
onChange={(value) => {
handleChange('geographies', value);
handleSave({ ...formData, geographies: value });