mirror of https://github.com/buster-so/buster.git
Fix save to collection dropdown
This commit is contained in:
parent
deb866b67e
commit
efa289fe4d
|
@ -22,6 +22,7 @@ import {
|
|||
updateMetric,
|
||||
updateMetricShare
|
||||
} from './requests';
|
||||
import type { BusterCollection } from '@/api/asset_interfaces/collection';
|
||||
|
||||
/**
|
||||
* This is a mutation that saves a metric to the server.
|
||||
|
@ -157,16 +158,39 @@ export const useSaveMetricToCollections = () => {
|
|||
|
||||
return useMutation({
|
||||
mutationFn: saveMetricToCollection,
|
||||
onSuccess: (_, { collectionIds }) => {
|
||||
onMutate: ({ metricIds, collectionIds }) => {
|
||||
metricIds.forEach((id) => {
|
||||
queryClient.setQueryData(
|
||||
metricsQueryKeys.metricsGetMetric(id, null).queryKey,
|
||||
(oldData) => {
|
||||
if (!oldData) return oldData;
|
||||
const newData: BusterMetric = create(oldData, (draft) => {
|
||||
draft.collections = [
|
||||
...(draft.collections || []),
|
||||
...collectionIds.map((id) => ({ id, name: '' }))
|
||||
];
|
||||
});
|
||||
return newData;
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
onSuccess: (_, { collectionIds, metricIds }) => {
|
||||
const collectionIsInFavorites = userFavorites.some((f) => {
|
||||
return collectionIds.includes(f.id);
|
||||
});
|
||||
if (collectionIsInFavorites) refreshFavoritesList();
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: collectionIds.map(
|
||||
(id) => collectionQueryKeys.collectionsGetCollection(id).queryKey
|
||||
),
|
||||
refetchType: 'all'
|
||||
|
||||
collectionIds.forEach((id) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: collectionQueryKeys.collectionsGetCollection(id).queryKey
|
||||
});
|
||||
});
|
||||
|
||||
metricIds.forEach((id) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: metricsQueryKeys.metricsGetMetric(id, null).queryKey
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -192,17 +216,48 @@ export const useRemoveMetricFromCollection = () => {
|
|||
|
||||
return useMutation({
|
||||
mutationFn: removeMetricFromCollection,
|
||||
onMutate: ({ metricIds, collectionIds }) => {
|
||||
metricIds.forEach((id) => {
|
||||
queryClient.setQueryData(
|
||||
metricsQueryKeys.metricsGetMetric(id, null).queryKey,
|
||||
(oldData) => {
|
||||
if (!oldData) return oldData;
|
||||
const newData: BusterMetric = create(oldData, (draft) => {
|
||||
draft.collections = draft.collections?.filter((c) => !collectionIds.includes(c.id));
|
||||
});
|
||||
return newData;
|
||||
}
|
||||
);
|
||||
});
|
||||
collectionIds.forEach((id) => {
|
||||
queryClient.setQueryData(
|
||||
collectionQueryKeys.collectionsGetCollection(id).queryKey,
|
||||
(oldData) => {
|
||||
if (!oldData) return oldData;
|
||||
const newData: BusterCollection = create(oldData, (draft) => {
|
||||
draft.assets = draft.assets?.filter((a) => !metricIds.includes(a.id)) || [];
|
||||
});
|
||||
return newData;
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
onSuccess: (_, { collectionIds, metricIds }) => {
|
||||
const collectionIsInFavorites = userFavorites.some((f) => {
|
||||
return collectionIds.includes(f.id);
|
||||
});
|
||||
if (collectionIsInFavorites) refreshFavoritesList();
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: collectionIds.map(
|
||||
(id) => collectionQueryKeys.collectionsGetCollection(id).queryKey
|
||||
),
|
||||
refetchType: 'all'
|
||||
collectionIds.forEach((id) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: collectionQueryKeys.collectionsGetCollection(id).queryKey
|
||||
});
|
||||
});
|
||||
|
||||
metricIds.forEach((id) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: metricsQueryKeys.metricsGetMetric(id, null).queryKey
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import uniq from 'lodash/uniq';
|
||||
import type React from 'react';
|
||||
import { useState } from 'react';
|
||||
import {
|
||||
useGetMetric,
|
||||
useRemoveMetricFromCollection,
|
||||
useSaveMetricToCollections
|
||||
} from '@/api/buster_rest/metrics';
|
||||
|
@ -11,38 +10,29 @@ import { SaveToCollectionsDropdown } from '../dropdowns/SaveToCollectionsDropdow
|
|||
import { CollectionButton } from './CollectionsButton';
|
||||
|
||||
export const SaveMetricToCollectionButton: React.FC<{
|
||||
metricIds: string[];
|
||||
selectedCollections: string[];
|
||||
metricId: string;
|
||||
buttonType?: 'ghost' | 'default';
|
||||
useText?: boolean;
|
||||
}> = ({
|
||||
metricIds,
|
||||
selectedCollections: selectedCollectionsProp,
|
||||
buttonType = 'ghost',
|
||||
useText = false
|
||||
}) => {
|
||||
}> = ({ metricId, buttonType = 'ghost', useText = false }) => {
|
||||
const { openInfoMessage } = useBusterNotifications();
|
||||
const { mutateAsync: saveMetricToCollection } = useSaveMetricToCollections();
|
||||
const { mutateAsync: removeMetricFromCollection } = useRemoveMetricFromCollection();
|
||||
|
||||
const [selectedCollections, setSelectedCollections] =
|
||||
useState<Parameters<typeof SaveToCollectionsDropdown>[0]['selectedCollections']>(
|
||||
selectedCollectionsProp
|
||||
);
|
||||
const { data: selectedCollections } = useGetMetric(
|
||||
{ id: metricId },
|
||||
{ select: (x) => x.collections?.map((x) => x.id) }
|
||||
);
|
||||
|
||||
const onSaveToCollection = useMemoizedFn(async (collectionIds: string[]) => {
|
||||
setSelectedCollections((prev) => uniq([...prev, ...collectionIds]));
|
||||
await saveMetricToCollection({
|
||||
metricIds,
|
||||
metricIds: [metricId],
|
||||
collectionIds
|
||||
});
|
||||
openInfoMessage('Metrics saved to collections');
|
||||
});
|
||||
|
||||
const onRemoveFromCollection = useMemoizedFn(async (collectionId: string) => {
|
||||
setSelectedCollections((prev) => prev.filter((x) => x !== collectionId));
|
||||
await removeMetricFromCollection({
|
||||
metricIds,
|
||||
metricIds: [metricId],
|
||||
collectionIds: [collectionId]
|
||||
});
|
||||
openInfoMessage('Metrics removed from collections');
|
||||
|
@ -52,7 +42,7 @@ export const SaveMetricToCollectionButton: React.FC<{
|
|||
<SaveToCollectionsDropdown
|
||||
onSaveToCollection={onSaveToCollection}
|
||||
onRemoveFromCollection={onRemoveFromCollection}
|
||||
selectedCollections={selectedCollections}>
|
||||
selectedCollections={selectedCollections || []}>
|
||||
<CollectionButton buttonType={buttonType} useText={useText} />
|
||||
</SaveToCollectionsDropdown>
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useMemo } from 'react';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import type { BusterCollectionListItem } from '@/api/asset_interfaces/collection';
|
||||
import { useGetCollectionsList } from '@/api/buster_rest/collections';
|
||||
import { Button } from '@/components/ui/buttons';
|
||||
|
@ -56,6 +56,8 @@ export const useSaveToCollectionsDropdownContent = ({
|
|||
> & {
|
||||
ModalComponent: React.ReactNode;
|
||||
} => {
|
||||
const [openCollectionModal, setOpenCollectionModal] = useState(false);
|
||||
|
||||
const { data: collectionsList, isPending: isCreatingCollection } = useGetCollectionsList({});
|
||||
const onChangePage = useAppLayoutContextSelector((s) => s.onChangePage);
|
||||
|
||||
|
@ -75,8 +77,6 @@ export const useSaveToCollectionsDropdownContent = ({
|
|||
return collectionsItems;
|
||||
}, [collectionsList, selectedCollections]);
|
||||
|
||||
const [openCollectionModal, setOpenCollectionModal] = React.useState(false);
|
||||
|
||||
const menuHeader = useMemo(() => {
|
||||
return items.length > 0 ? 'Save to a collection' : undefined;
|
||||
}, [items.length]);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { ShareAssetType } from '@buster/server-shared/share';
|
||||
import {
|
||||
useDeleteChat,
|
||||
useRemoveChatFromCollections,
|
||||
|
|
|
@ -145,16 +145,12 @@ const useVersionHistorySelectMenu = ({ dashboardId }: { dashboardId: string }) =
|
|||
const useCollectionSelectMenu = ({ dashboardId }: { dashboardId: string }) => {
|
||||
const { mutateAsync: saveDashboardToCollection } = useAddDashboardToCollection();
|
||||
const { mutateAsync: removeDashboardFromCollection } = useRemoveDashboardFromCollection();
|
||||
const { data: collections } = useGetDashboard(
|
||||
const { data: selectedCollections } = useGetDashboard(
|
||||
{ id: dashboardId },
|
||||
{ select: (x) => x.collections }
|
||||
{ select: (x) => x.collections?.map((x) => x.id) }
|
||||
);
|
||||
const { openInfoMessage } = useBusterNotifications();
|
||||
|
||||
const selectedCollections = useMemo(() => {
|
||||
return collections?.map((x) => x.id) || [];
|
||||
}, [collections]);
|
||||
|
||||
const onSaveToCollection = useMemoizedFn(async (collectionIds: string[]) => {
|
||||
await saveDashboardToCollection({ dashboardIds: [dashboardId], collectionIds });
|
||||
openInfoMessage('Dashboard saved to collections');
|
||||
|
@ -171,7 +167,7 @@ const useCollectionSelectMenu = ({ dashboardId }: { dashboardId: string }) => {
|
|||
const { ModalComponent, ...dropdownProps } = useSaveToCollectionsDropdownContent({
|
||||
onSaveToCollection,
|
||||
onRemoveFromCollection,
|
||||
selectedCollections
|
||||
selectedCollections: selectedCollections || []
|
||||
});
|
||||
|
||||
const collectionSubMenu = useMemo(() => {
|
||||
|
|
|
@ -126,14 +126,7 @@ const EditChartButton = React.memo(({ metricId }: { metricId: string }) => {
|
|||
EditChartButton.displayName = 'EditChartButton';
|
||||
|
||||
const SaveToCollectionButton = React.memo(({ metricId }: { metricId: string }) => {
|
||||
const { data: collections } = useGetMetric(
|
||||
{ id: metricId },
|
||||
{ select: (x) => x.collections?.map((x) => x.id) }
|
||||
);
|
||||
|
||||
return (
|
||||
<SaveMetricToCollectionButton metricIds={[metricId]} selectedCollections={collections || []} />
|
||||
);
|
||||
return <SaveMetricToCollectionButton metricId={metricId} />;
|
||||
});
|
||||
SaveToCollectionButton.displayName = 'SaveToCollectionButton';
|
||||
|
||||
|
|
|
@ -202,13 +202,12 @@ const useDashboardSelectMenu = ({ metricId }: { metricId: string }) => {
|
|||
const useCollectionSelectMenu = ({ metricId }: { metricId: string }) => {
|
||||
const { mutateAsync: saveMetricToCollection } = useSaveMetricToCollections();
|
||||
const { mutateAsync: removeMetricFromCollection } = useRemoveMetricFromCollection();
|
||||
const { data: collections } = useGetMetric({ id: metricId }, { select: (x) => x.collections });
|
||||
const { data: selectedCollections } = useGetMetric(
|
||||
{ id: metricId },
|
||||
{ select: (x) => x.collections?.map((x) => x.id) }
|
||||
);
|
||||
const { openInfoMessage } = useBusterNotifications();
|
||||
|
||||
const selectedCollections = useMemo(() => {
|
||||
return collections?.map((x) => x.id) || [];
|
||||
}, [collections]);
|
||||
|
||||
const onSaveToCollection = useMemoizedFn(async (collectionIds: string[]) => {
|
||||
await saveMetricToCollection({
|
||||
metricIds: [metricId],
|
||||
|
@ -228,7 +227,7 @@ const useCollectionSelectMenu = ({ metricId }: { metricId: string }) => {
|
|||
const { ModalComponent, ...dropdownProps } = useSaveToCollectionsDropdownContent({
|
||||
onSaveToCollection,
|
||||
onRemoveFromCollection,
|
||||
selectedCollections
|
||||
selectedCollections: selectedCollections || []
|
||||
});
|
||||
|
||||
const CollectionSubMenu = useMemo(() => {
|
||||
|
|
Loading…
Reference in New Issue