mirror of https://github.com/buster-so/buster.git
start moving chats to react query
This commit is contained in:
parent
912d0e855d
commit
c69030fcc6
|
@ -55,3 +55,16 @@ export const updateOrganizationUser = async ({
|
|||
.put<OrganizationUser>(`/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
|
||||
});
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
// }
|
||||
// );
|
||||
// };
|
||||
|
|
|
@ -79,24 +79,3 @@ const defaultCallback = <TData, TRoute extends BusterSocketResponseRoute>(
|
|||
currentData: TData | null,
|
||||
d: InferBusterSocketResponseData<TRoute>
|
||||
) => 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 [];
|
||||
// });
|
||||
// };
|
||||
|
|
|
@ -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<BusterChat>({
|
||||
queryOptions<IBusterChat>({
|
||||
queryKey: ['chats', 'get', chatId] as const,
|
||||
staleTime: 10 * 1000
|
||||
staleTime: 60 * 1000 // 1 minute
|
||||
});
|
||||
|
||||
const chatsMessages = (messageId: string) =>
|
||||
queryOptions<IBusterChatMessage>({
|
||||
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);
|
||||
|
||||
// //
|
||||
// };
|
||||
|
|
|
@ -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 (
|
||||
<ChatProvider>
|
||||
<BusterChatListProvider>
|
||||
<BusterNewChatProvider>{children}</BusterNewChatProvider>
|
||||
</BusterChatListProvider>
|
||||
<BusterNewChatProvider>{children}</BusterNewChatProvider>
|
||||
</ChatProvider>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -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<Record<string, BusterChatListItem>>({});
|
||||
const [chatListIds, setChatListIds] = useState<Record<string, IChatList>>({});
|
||||
|
||||
//STATE UPDATES
|
||||
|
||||
const onUpdateChatListItem = useMemoizedFn(
|
||||
(newChat: Partial<BusterChatListItem> & { 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<ReturnType<typeof useBusterChatList>>(
|
||||
{} as ReturnType<typeof useBusterChatList>
|
||||
);
|
||||
|
||||
export const BusterChatListProvider: React.FC<PropsWithChildren> = React.memo(({ children }) => {
|
||||
const chatListContext = useBusterChatList();
|
||||
|
||||
return <BusterChatList.Provider value={chatListContext}>{children}</BusterChatList.Provider>;
|
||||
});
|
||||
BusterChatListProvider.displayName = 'BusterChatListProvider';
|
||||
|
||||
export const useBusterChatListContextSelector = <T,>(
|
||||
selector: ContextSelector<ReturnType<typeof useBusterChatList>, T>
|
||||
) => {
|
||||
return useContextSelector(BusterChatList, selector);
|
||||
};
|
|
@ -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<Record<string, BusterChatListItem>>((acc, chat) => {
|
||||
acc[chat.id] = chat;
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
|
@ -1 +1 @@
|
|||
export * from './ChatListProvider';
|
||||
export * from './useBusterChatListByFilter';
|
||||
|
|
|
@ -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
|
||||
};
|
||||
};
|
|
@ -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(
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export * from './DashboardListProvider';
|
||||
export * from './useBusterDashboardListByFilter';
|
||||
export * from './interfaces';
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue