diff --git a/web/src/api/buster_rest/users/requests.ts b/web/src/api/buster_rest/users/requests.ts index e70d6ae9c..6b9b55539 100644 --- a/web/src/api/buster_rest/users/requests.ts +++ b/web/src/api/buster_rest/users/requests.ts @@ -55,3 +55,16 @@ export const updateOrganizationUser = async ({ .put(`/users/${userId}`, params) .then((response) => response.data); }; + +export const inviteUser = async ({ + emails, + team_ids +}: { + emails: string[]; + team_ids?: string[]; +}) => { + return mainApi.post(`/users/invite`, { + emails, + team_ids + }); +}; diff --git a/web/src/api/buster_socket/user/userRequests.ts b/web/src/api/buster_socket/user/userRequests.ts index 8e2df15b7..6b0523335 100644 --- a/web/src/api/buster_socket/user/userRequests.ts +++ b/web/src/api/buster_socket/user/userRequests.ts @@ -61,11 +61,6 @@ export type UserRequestUserList = BusterSocketRequestBase< } >; -export type UserInvite = BusterSocketRequestBase< - '/users/invite', - { emails: string[]; team_ids?: null | string[] } ->; - export type UserEmits = | UserColorsList | UserColorsCreate @@ -75,5 +70,4 @@ export type UserEmits = | UsersFavoriteList | UserFavoriteDelete | UserUpdateFavorites - | UserRequestUserList - | UserInvite; + | UserRequestUserList; diff --git a/web/src/api/buster_socket_query/useSocketQueryEmitAndOnce.tsx b/web/src/api/buster_socket_query/useSocketQueryEmitAndOnce.tsx index 1b2a22617..8a4b7f294 100644 --- a/web/src/api/buster_socket_query/useSocketQueryEmitAndOnce.tsx +++ b/web/src/api/buster_socket_query/useSocketQueryEmitAndOnce.tsx @@ -60,20 +60,3 @@ export function useSocketQueryEmitAndOnce< ...options }); } - -// const ExampleComponent = () => { -// const options = queryOptionsConfig['/chats/get:getChat']('123'); - -// const deleteChatInitialData = { -// id: '123' -// } as unknown as BusterChat; - -// const { data } = useSocketQueryEmitAndOnce( -// { route: '/chats/get', payload: { id: '123' } }, -// '/chats/get:getChat', -// options, -// (d, x) => { -// return deleteChatInitialData; -// } -// ); -// }; diff --git a/web/src/api/buster_socket_query/useSocketQueryOn.tsx b/web/src/api/buster_socket_query/useSocketQueryOn.tsx index a85b0c51e..71603dd7a 100644 --- a/web/src/api/buster_socket_query/useSocketQueryOn.tsx +++ b/web/src/api/buster_socket_query/useSocketQueryOn.tsx @@ -79,24 +79,3 @@ const defaultCallback = ( currentData: TData | null, d: InferBusterSocketResponseData ) => d as TData; - -// const _ExampleComponent = () => { -// const options = queryKeys['/chats/get:getChat']('123'); -// const { data } = useSocketQueryOn('/chats/get:getChat', options); - -// const options2 = queryKeys['/chats/list:getChatsList'](); -// const { data: data2 } = useSocketQueryOn('/chats/list:getChatsList', options2); - -// const options3 = queryKeys['/chats/delete:deleteChat']('123'); - -// // Create fresh options for delete chat that match the expected BusterChat type -// const deleteChatInitialData = { -// id: '123' -// } as unknown as BusterChat; - -// const { data: data3 } = useSocketQueryOn('/chats/delete:deleteChat', options3, (d, x) => { -// d?.[0].is_favorited; -// x[0].id; -// return []; -// }); -// }; diff --git a/web/src/api/query_keys/chat.ts b/web/src/api/query_keys/chat.ts index 3818e3b4d..56b98c104 100644 --- a/web/src/api/query_keys/chat.ts +++ b/web/src/api/query_keys/chat.ts @@ -1,11 +1,18 @@ import { queryOptions } from '@tanstack/react-query'; -import type { BusterChat, BusterChatListItem } from '@/api/asset_interfaces'; +import type { BusterChatListItem } from '@/api/asset_interfaces'; import type { GetChatListParams } from '@/api/request_interfaces/chats'; +import { IBusterChat, IBusterChatMessage } from '@/context/Chats'; const chatsGetChat = (chatId: string) => - queryOptions({ + queryOptions({ queryKey: ['chats', 'get', chatId] as const, - staleTime: 10 * 1000 + staleTime: 60 * 1000 // 1 minute + }); + +const chatsMessages = (messageId: string) => + queryOptions({ + queryKey: ['chats', 'messages', messageId] as const, + staleTime: Infinity }); const chatsGetList = (filters?: GetChatListParams) => @@ -15,27 +22,7 @@ const chatsGetList = (filters?: GetChatListParams) => }); export const chatQueryKeys = { - '/chats/get:getChat': chatsGetChat, - '/chats/list:getChatsList': chatsGetList + chatsGetChat, + chatsGetList, + chatsMessages }; - -// const ExampleComponent = () => { -// const queryClient = useQueryClient(); -// const options = chatQueryKeys['/chats/get:getChat']!('123'); -// const queryKey = options.queryKey; - -// const data = queryClient.getQueryData(queryKey); - -// const { data: data2 } = useQuery(options); - -// queryClient.setQueryData(queryKey, (d) => { -// return d; -// }); - -// const options2 = chatQueryKeys['/chats/list:getChatsList']!(); -// const queryKey2 = options2.queryKey; - -// const data3 = queryClient.getQueryData(queryKey2); - -// // -// }; diff --git a/web/src/context/Chats/BusterChatProvider.tsx b/web/src/context/Chats/BusterChatProvider.tsx index 9ae84032e..4f64334c4 100644 --- a/web/src/context/Chats/BusterChatProvider.tsx +++ b/web/src/context/Chats/BusterChatProvider.tsx @@ -1,14 +1,11 @@ import React from 'react'; import { ChatProvider } from './ChatProvider'; import { BusterNewChatProvider } from './NewChatProvider'; -import { BusterChatListProvider } from './ChatListProvider'; export const BusterChatProvider = React.memo(({ children }: { children: React.ReactNode }) => { return ( - - {children} - + {children} ); }); diff --git a/web/src/context/Chats/ChatListProvider/ChatListProvider.tsx b/web/src/context/Chats/ChatListProvider/ChatListProvider.tsx deleted file mode 100644 index ba4a6df1d..000000000 --- a/web/src/context/Chats/ChatListProvider/ChatListProvider.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import React, { PropsWithChildren, useEffect, useRef, useState } from 'react'; -import { - createContext, - ContextSelector, - useContextSelector -} from '@fluentui/react-context-selector'; -import { useBusterWebSocket } from '../../BusterWebSocket'; -import { BusterChatListItem } from '@/api/asset_interfaces'; -import { useMemoizedFn, useThrottleFn } from 'ahooks'; -import { chatsArrayToRecord, createFilterRecord } from './helpers'; -import { useAppLayoutContextSelector } from '@/context/BusterAppLayout'; -import { BusterRoutes } from '@/routes'; - -interface IChatList { - fetching: boolean; - fetched: boolean; - fetchedAt: number; - chatListIds: string[]; -} - -export const useBusterChatList = () => { - const busterSocket = useBusterWebSocket(); - - const [chatList, setChatList] = useState>({}); - const [chatListIds, setChatListIds] = useState>({}); - - //STATE UPDATES - - const onUpdateChatListItem = useMemoizedFn( - (newChat: Partial & { id: string }) => { - setChatList((prevChats) => { - return { - ...prevChats, - [newChat.id]: { - ...prevChats[newChat.id], - ...newChat - } - }; - }); - } - ); - - const removeItemFromChatList = useMemoizedFn(({ chatId }: { chatId: string }) => { - setChatListIds((prevChatListIds) => { - const newChatListIds = { ...prevChatListIds }; - Object.keys(newChatListIds).forEach((key) => { - newChatListIds[key] = { - ...newChatListIds[key], - chatListIds: newChatListIds[key].chatListIds.filter((id) => id !== chatId) - }; - }); - return newChatListIds; - }); - }); - - //LISTENERS - - const _onInitializeListChats = useMemoizedFn( - (chats: BusterChatListItem[], admin_view: boolean) => { - const newChats = chatsArrayToRecord(chats); - const filterKey = createFilterRecord({ admin_view }); - - setChatList((prev) => ({ - ...prev, - ...newChats - })); - - setChatListIds((prev) => ({ - ...prev, - [filterKey]: { - fetching: false, - fetched: true, - fetchedAt: Date.now(), - chatListIds: Object.keys(newChats) - } - })); - } - ); - - const _getChatsList = useMemoizedFn(({ admin_view }: { admin_view: boolean }) => { - const recordKey = createFilterRecord({ admin_view }); - - if (chatListIds[recordKey]?.fetching) { - return; - } - - setChatListIds((prev) => { - const foundRecord = prev[recordKey]; - return { - ...prev, - [recordKey]: { - fetching: true, - chatListIds: foundRecord?.chatListIds || [], - fetched: foundRecord?.fetched || false, - fetchedAt: foundRecord?.fetchedAt || 0 - } - }; - }); - - return busterSocket.emitAndOnce({ - emitEvent: { - route: '/chats/list', - payload: { - page_token: 0, - page_size: 3000, //TODO: make a pagination - admin_view - } - }, - responseEvent: { - route: '/chats/list:getChatsList', - callback: (v) => _onInitializeListChats(v, admin_view) - } - }); - }); - - //ACTIONS - - const { run: getChatsList } = useThrottleFn(_getChatsList, { wait: 350, leading: true }); - - return { - getChatsList, - chatList, - chatListIds, - onUpdateChatListItem, - removeItemFromChatList - }; -}; - -const BusterChatList = createContext>( - {} as ReturnType -); - -export const BusterChatListProvider: React.FC = React.memo(({ children }) => { - const chatListContext = useBusterChatList(); - - return {children}; -}); -BusterChatListProvider.displayName = 'BusterChatListProvider'; - -export const useBusterChatListContextSelector = ( - selector: ContextSelector, T> -) => { - return useContextSelector(BusterChatList, selector); -}; diff --git a/web/src/context/Chats/ChatListProvider/helpers.ts b/web/src/context/Chats/ChatListProvider/helpers.ts deleted file mode 100644 index 142ed5a77..000000000 --- a/web/src/context/Chats/ChatListProvider/helpers.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BusterChatListItem } from '@/api/asset_interfaces'; - -export const createFilterRecord = ({ admin_view }: { admin_view: boolean }): string => { - const adminViewString = admin_view ? 'admin_view' : 'non_admin_view'; - return adminViewString; -}; - -export const chatsArrayToRecord = (chats: BusterChatListItem[]) => { - return chats.reduce>((acc, chat) => { - acc[chat.id] = chat; - return acc; - }, {}); -}; diff --git a/web/src/context/Chats/ChatListProvider/index.ts b/web/src/context/Chats/ChatListProvider/index.ts index 59ace427d..49bde0dc1 100644 --- a/web/src/context/Chats/ChatListProvider/index.ts +++ b/web/src/context/Chats/ChatListProvider/index.ts @@ -1 +1 @@ -export * from './ChatListProvider'; +export * from './useBusterChatListByFilter'; diff --git a/web/src/context/Chats/ChatListProvider/useBusterChatListByFilter.tsx b/web/src/context/Chats/ChatListProvider/useBusterChatListByFilter.tsx new file mode 100644 index 000000000..1361c926c --- /dev/null +++ b/web/src/context/Chats/ChatListProvider/useBusterChatListByFilter.tsx @@ -0,0 +1,18 @@ +import { useSocketQueryEmitOn } from '@/api/buster_socket_query'; +import { queryKeys } from '@/api/query_keys'; +import { GetChatListParams } from '@/api/request_interfaces/chats'; + +export const useBusterChatListByFilter = (filters: GetChatListParams) => { + const { data: chatsList, isFetched: isFetchedChatsList } = useSocketQueryEmitOn( + { route: '/chats/list', payload: { page_token: 0, page_size: 3000, admin_view: false } }, + '/chats/list:getChatsList', + queryKeys['chatsGetList'](filters) + ); + + //ACTIONS + + return { + list: chatsList, + isFetched: isFetchedChatsList + }; +}; diff --git a/web/src/context/Chats/ChatProvider/useChatAssosciations.ts b/web/src/context/Chats/ChatProvider/useChatAssosciations.ts index 700c34276..d4f2b752e 100644 --- a/web/src/context/Chats/ChatProvider/useChatAssosciations.ts +++ b/web/src/context/Chats/ChatProvider/useChatAssosciations.ts @@ -2,7 +2,7 @@ import { useMemoizedFn } from 'ahooks'; import { useSocketQueryMutation } from '@/api/buster_socket_query'; import { queryKeys } from '@/api/query_keys'; -const getChatsListOptions = queryKeys['/chats/list:getChatsList'](); +const getChatsListOptions = queryKeys['chatsGetList'](); export const useChatAssosciations = () => { const { mutate: deleteChat } = useSocketQueryMutation( diff --git a/web/src/context/Chats/index.ts b/web/src/context/Chats/index.ts index 1d24a04f3..a861c654f 100644 --- a/web/src/context/Chats/index.ts +++ b/web/src/context/Chats/index.ts @@ -1,12 +1,8 @@ import { useBusterNewChatContextSelector } from './NewChatProvider'; import { useBusterChatContextSelector } from './ChatProvider'; -import { useBusterChatListContextSelector } from './ChatListProvider'; +import { useBusterChatListByFilter } from './ChatListProvider'; export * from './BusterChatProvider'; -export { - useBusterNewChatContextSelector, - useBusterChatContextSelector, - useBusterChatListContextSelector -}; +export { useBusterNewChatContextSelector, useBusterChatContextSelector, useBusterChatListByFilter }; export * from './interfaces'; diff --git a/web/src/context/Dashboards/DashboardListProvider/index.ts b/web/src/context/Dashboards/DashboardListProvider/index.ts index 480c8efd8..3eaee8b8f 100644 --- a/web/src/context/Dashboards/DashboardListProvider/index.ts +++ b/web/src/context/Dashboards/DashboardListProvider/index.ts @@ -1,2 +1,2 @@ -export * from './DashboardListProvider'; +export * from './useBusterDashboardListByFilter'; export * from './interfaces'; diff --git a/web/src/context/Dashboards/DashboardListProvider/DashboardListProvider.tsx b/web/src/context/Dashboards/DashboardListProvider/useBusterDashboardListByFilter.tsx similarity index 100% rename from web/src/context/Dashboards/DashboardListProvider/DashboardListProvider.tsx rename to web/src/context/Dashboards/DashboardListProvider/useBusterDashboardListByFilter.tsx diff --git a/web/src/context/Users/useInviteUser.ts b/web/src/context/Users/useInviteUser.ts index 1bbb48a60..bf8d4e53f 100644 --- a/web/src/context/Users/useInviteUser.ts +++ b/web/src/context/Users/useInviteUser.ts @@ -1,18 +1,14 @@ import { useMemoizedFn } from 'ahooks'; -import { useBusterWebSocket } from '../BusterWebSocket'; import { timeout } from '@/utils'; import { useBusterNotifications } from '../BusterNotifications'; +import { inviteUser as inviteUserRest } from '@/api/buster_rest'; export const useInviteUser = () => { - const busterSocket = useBusterWebSocket(); const { openSuccessMessage } = useBusterNotifications(); const inviteUsers = useMemoizedFn(async (emails: string[], team_ids?: string[]) => { - busterSocket.emit({ - route: '/users/invite', - payload: { emails, team_ids } - }); - await timeout(350); + await inviteUserRest({ emails, team_ids }); + await timeout(100); openSuccessMessage('Invites sent'); });