From bb49686be9cea38e4bfb3e0662301a18bf69df7e Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Wed, 2 Apr 2025 10:42:54 -0600 Subject: [PATCH] delete chat --- .../api/buster_rest/chats/queryRequests.ts | 100 +++++++++++++++++- web/src/api/buster_rest/chats/requests.ts | 11 +- .../api/buster_rest/collections/requests.ts | 2 +- .../ChatItemsSelectedPopup.tsx | 58 ++++------ .../ChatHeaderOptions/ChatHeaderDropdown.tsx | 35 ++++-- 5 files changed, 153 insertions(+), 53 deletions(-) diff --git a/web/src/api/buster_rest/chats/queryRequests.ts b/web/src/api/buster_rest/chats/queryRequests.ts index cad5c73bf..2a4e5d00b 100644 --- a/web/src/api/buster_rest/chats/queryRequests.ts +++ b/web/src/api/buster_rest/chats/queryRequests.ts @@ -16,6 +16,13 @@ import { updateChatToIChat } from '@/lib/chat'; import { useMemo } from 'react'; import last from 'lodash/last'; import { prefetchGetMetricDataClient } from '../metrics/queryRequests'; +import { useBusterNotifications } from '@/context/BusterNotifications'; +import { useGetUserFavorites } from '../users/queryRequests'; +import { + useAddAssetToCollection, + useRemoveAssetFromCollection +} from '../collections/queryRequests'; +import { collectionQueryKeys } from '@/api/query_keys/collection'; export const useGetListChats = ( filters?: Omit[0], 'page_token' | 'page_size'> @@ -142,8 +149,30 @@ export const useUpdateChat = () => { export const useDeleteChat = () => { const queryClient = useQueryClient(); + const { openConfirmModal } = useBusterNotifications(); + + const mutationFn = useMemoizedFn( + async ({ + useConfirmModal = true, + data + }: { + data: Parameters[0]; + useConfirmModal?: boolean; + }) => { + const method = () => deleteChat(data); + if (useConfirmModal) { + return await openConfirmModal({ + title: 'Delete Chat', + content: 'Are you sure you want to delete this chat?', + onOk: method + }); + } + return method(); + } + ); + return useMutation({ - mutationFn: deleteChat, + mutationFn, onSuccess(data, variables, context) { queryClient.invalidateQueries({ queryKey: queryKeys.chatsGetList().queryKey @@ -193,3 +222,72 @@ export const useDuplicateChat = () => { mutationFn: duplicateChat }); }; + +export const useSaveChatToCollections = () => { + const queryClient = useQueryClient(); + const { data: userFavorites, refetch: refreshFavoritesList } = useGetUserFavorites(); + const { mutateAsync: addAssetToCollection } = useAddAssetToCollection(); + + const saveChatToCollection = useMemoizedFn( + async ({ chatIds, collectionIds }: { chatIds: string[]; collectionIds: string[] }) => { + await Promise.all( + collectionIds.map((collectionId) => + addAssetToCollection({ + id: collectionId, + assets: chatIds.map((chatId) => ({ id: chatId, type: 'chat' })) + }) + ) + ); + } + ); + + return useMutation({ + mutationFn: saveChatToCollection, + onSuccess: (_, { collectionIds }) => { + const collectionIsInFavorites = userFavorites.some((f) => { + return collectionIds.includes(f.id); + }); + if (collectionIsInFavorites) refreshFavoritesList(); + queryClient.invalidateQueries({ + queryKey: collectionIds.map( + (id) => collectionQueryKeys.collectionsGetCollection(id).queryKey + ) + }); + } + }); +}; + +export const useRemoveChatFromCollections = () => { + const { data: userFavorites, refetch: refreshFavoritesList } = useGetUserFavorites(); + const { mutateAsync: removeAssetFromCollection } = useRemoveAssetFromCollection(); + const queryClient = useQueryClient(); + + const removeChatFromCollection = useMemoizedFn( + async ({ chatIds, collectionIds }: { chatIds: string[]; collectionIds: string[] }) => { + await Promise.all( + collectionIds.map((collectionId) => + removeAssetFromCollection({ + id: collectionId, + assets: chatIds.map((chatId) => ({ id: chatId, type: 'chat' })) + }) + ) + ); + } + ); + + return useMutation({ + mutationFn: removeChatFromCollection, + onSuccess: (_, { collectionIds, chatIds }) => { + const collectionIsInFavorites = userFavorites.some((f) => { + return collectionIds.includes(f.id); + }); + if (collectionIsInFavorites) refreshFavoritesList(); + + queryClient.invalidateQueries({ + queryKey: collectionIds.map( + (id) => collectionQueryKeys.collectionsGetCollection(id).queryKey + ) + }); + } + }); +}; diff --git a/web/src/api/buster_rest/chats/requests.ts b/web/src/api/buster_rest/chats/requests.ts index a19b133c5..9ae0fb7eb 100644 --- a/web/src/api/buster_rest/chats/requests.ts +++ b/web/src/api/buster_rest/chats/requests.ts @@ -61,20 +61,17 @@ export const updateChat = async ({ }; export const deleteChat = async (data: string[]): Promise => { - return mainApi.delete(`${CHATS_BASE}`, { data }).then((res) => res.data); + const stringifiedData = JSON.stringify(data); + return mainApi.delete(`${CHATS_BASE}`, { data: stringifiedData }).then((res) => res.data); }; export const duplicateChat = async ({ id, - message_id, - share_with_same_people + message_id }: { id: string; /** The message ID to start the duplication from */ message_id: string; - share_with_same_people: boolean; }): Promise => { - return mainApi - .post(`${CHATS_BASE}/duplicate`, { id, message_id, share_with_same_people }) - .then((res) => res.data); + return mainApi.post(`${CHATS_BASE}/duplicate`, { id, message_id }).then((res) => res.data); }; diff --git a/web/src/api/buster_rest/collections/requests.ts b/web/src/api/buster_rest/collections/requests.ts index 9b6896a9f..278576bbc 100644 --- a/web/src/api/buster_rest/collections/requests.ts +++ b/web/src/api/buster_rest/collections/requests.ts @@ -104,7 +104,7 @@ export const updateCollectionShare = async ({ export const addAssetToCollection = async (params: { id: string; assets: { - type: 'metric' | 'dashboard'; + type: 'metric' | 'dashboard' | 'chat'; id: string; }[]; }) => { diff --git a/web/src/controllers/ChatsListController/ChatItemsSelectedPopup.tsx b/web/src/controllers/ChatsListController/ChatItemsSelectedPopup.tsx index 737ad57bc..e8224130b 100644 --- a/web/src/controllers/ChatsListController/ChatItemsSelectedPopup.tsx +++ b/web/src/controllers/ChatsListController/ChatItemsSelectedPopup.tsx @@ -10,10 +10,10 @@ import { SaveToCollectionsDropdown } from '@/components/features/dropdowns/SaveT import { useBusterNotifications } from '@/context/BusterNotifications'; import { ASSET_ICONS } from '@/components/features/config/assetIcons'; import { - useDeleteMetric, - useRemoveMetricFromCollection, - useSaveMetricToCollections -} from '@/api/buster_rest/metrics'; + useDeleteChat, + useSaveChatToCollections, + useRemoveChatFromCollections +} from '@/api/buster_rest/chats'; import { useAddUserFavorite, useDeleteUserFavorite, @@ -36,11 +36,6 @@ export const ChatSelectedOptionPopup: React.FC<{ selectedRowKeys={selectedRowKeys} onSelectChange={onSelectChange} />, - , void; }> = ({ selectedRowKeys, onSelectChange }) => { const { openInfoMessage } = useBusterNotifications(); - const { mutateAsync: saveMetricToCollection } = useSaveMetricToCollections(); - const { mutateAsync: removeMetricFromCollection } = useRemoveMetricFromCollection(); + const { mutateAsync: saveChatToCollection } = useSaveChatToCollections(); + const { mutateAsync: removeChatFromCollection } = useRemoveChatFromCollections(); const [selectedCollections, setSelectedCollections] = useState< Parameters[0]['selectedCollections'] @@ -72,20 +67,20 @@ const CollectionsButton: React.FC<{ const onSaveToCollection = useMemoizedFn(async (collectionIds: string[]) => { setSelectedCollections(collectionIds); - await saveMetricToCollection({ - metricIds: selectedRowKeys, + await saveChatToCollection({ + chatIds: selectedRowKeys, collectionIds }); - openInfoMessage('Metrics saved to collections'); + openInfoMessage('Chats saved to collections'); }); const onRemoveFromCollection = useMemoizedFn(async (collectionId: string) => { setSelectedCollections((prev) => prev.filter((id) => id !== collectionId)); - await removeMetricFromCollection({ - metricIds: selectedRowKeys, + await removeChatFromCollection({ + chatIds: selectedRowKeys, collectionIds: [collectionId] }); - openInfoMessage('Metrics removed from collections'); + openInfoMessage('Chats removed from collections'); }); return ( @@ -98,25 +93,14 @@ const CollectionsButton: React.FC<{ ); }; -const DashboardButton: React.FC<{ - selectedRowKeys: string[]; - onSelectChange: (selectedRowKeys: string[]) => void; -}> = ({ selectedRowKeys, onSelectChange }) => { - return ( - - - - ); -}; - const DeleteButton: React.FC<{ selectedRowKeys: string[]; onSelectChange: (selectedRowKeys: string[]) => void; -}> = ({ selectedRowKeys, onSelectChange }) => { - const { mutateAsync: deleteMetric } = useDeleteMetric(); +}> = React.memo(({ selectedRowKeys, onSelectChange }) => { + const { mutateAsync: deleteChat } = useDeleteChat(); const onDeleteClick = async () => { - await deleteMetric({ ids: selectedRowKeys }); + await deleteChat({ data: selectedRowKeys }); onSelectChange([]); }; @@ -125,12 +109,14 @@ const DeleteButton: React.FC<{ Delete ); -}; +}); + +DeleteButton.displayName = 'DeleteButton'; const ThreeDotButton: React.FC<{ selectedRowKeys: string[]; onSelectChange: (selectedRowKeys: string[]) => void; -}> = ({ selectedRowKeys, onSelectChange }) => { +}> = React.memo(({ selectedRowKeys, onSelectChange }) => { const { mutateAsync: removeUserFavorite, isPending: removingFromFavorites } = useDeleteUserFavorite(); const { mutateAsync: addUserFavorite, isPending: addingToFavorites } = useAddUserFavorite(); @@ -148,7 +134,7 @@ const ThreeDotButton: React.FC<{ const name = userFavorites?.find((f) => f.id === id)?.name || ''; return addUserFavorite({ id, - asset_type: ShareAssetType.METRIC, + asset_type: ShareAssetType.CHAT, name }); }) @@ -171,4 +157,6 @@ const ThreeDotButton: React.FC<{