diff --git a/web/src/api/buster_rest/users/queryRequests.ts b/web/src/api/buster_rest/users/queryRequests.ts index 630e0cd72..575ee1e64 100644 --- a/web/src/api/buster_rest/users/queryRequests.ts +++ b/web/src/api/buster_rest/users/queryRequests.ts @@ -4,11 +4,24 @@ import { getUser_server, updateOrganizationUser, getMyUserInfo, - getMyUserInfo_server + getMyUserInfo_server, + getUserFavorites, + getUserFavorites_server, + createUserFavorite, + deleteUserFavorite, + updateUserFavorites, + getUserList, + getUserList_server } from './requests'; import { useMemoizedFn } from '@/hooks'; import { QueryClient, useQueryClient } from '@tanstack/react-query'; import { queryKeys } from '@/api/query_keys'; +import type { + UsersFavoritePostPayload, + UserFavoriteDeletePayload, + UserUpdateFavoritesPayload, + UserRequestUserListPayload +} from '@/api/request_interfaces/user/interfaces'; export const useGetMyUserInfo = () => { const queryFn = useMemoizedFn(async () => { @@ -71,3 +84,88 @@ export const prefetchGetUser = async (userId: string, queryClientProp?: QueryCli }); return queryClient; }; + +export const useGetUserFavorites = () => { + const queryFn = useMemoizedFn(async () => getUserFavorites()); + return useQuery({ + ...queryKeys.favoritesGetList, + queryFn + }); +}; + +export const prefetchGetUserFavorites = async (queryClientProp?: QueryClient) => { + const queryClient = queryClientProp || new QueryClient(); + await queryClient.prefetchQuery({ + ...queryKeys.favoritesGetList, + queryFn: () => getUserFavorites_server() + }); + return queryClient; +}; + +export const useAddUserFavorite = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: createUserFavorite, + onMutate: (params) => { + queryClient.setQueryData(queryKeys.favoritesGetList.queryKey, (prev) => { + return [params, ...(prev || [])]; + }); + }, + onSettled: () => { + queryClient.invalidateQueries(queryKeys.favoritesGetList); + } + }); +}; + +export const useDeleteUserFavorite = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: deleteUserFavorite, + onMutate: (params) => { + queryClient.setQueryData(queryKeys.favoritesGetList.queryKey, (prev) => { + return prev?.filter((fav) => fav.id !== params.id); + }); + }, + onSettled: () => { + queryClient.invalidateQueries(queryKeys.favoritesGetList); + } + }); +}; + +export const useUpdateUserFavorites = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: updateUserFavorites, + onMutate: (params) => { + queryClient.setQueryData(queryKeys.favoritesGetList.queryKey, (prev) => { + return prev?.filter((fav, index) => { + const id = fav.id || fav.collection_id; + const favorite = (prev || []).find((f) => f.id === id || f.collection_id === id)!; + return { ...favorite, index }; + }); + }); + } + }); +}; + +export const useGetUserList = (params: UserRequestUserListPayload) => { + const queryFn = useMemoizedFn(() => getUserList(params)); + + return useQuery({ + ...queryKeys.userGetUserList(params), + queryFn + }); +}; + +export const prefetchGetUserList = async ( + params: UserRequestUserListPayload, + queryClientProp?: QueryClient +) => { + const queryClient = queryClientProp || new QueryClient(); + await queryClient.prefetchQuery({ + ...queryKeys.userGetUserList(params), + queryFn: () => getUserList_server(params) + }); + return queryClient; +}; diff --git a/web/src/api/buster_rest/users/requests.ts b/web/src/api/buster_rest/users/requests.ts index 9654c51c0..6083f1ffa 100644 --- a/web/src/api/buster_rest/users/requests.ts +++ b/web/src/api/buster_rest/users/requests.ts @@ -1,5 +1,16 @@ import { BASE_URL } from '@/api/buster_rest/config'; -import type { OrganizationUser, BusterUserResponse } from '@/api/asset_interfaces/users'; +import type { + OrganizationUser, + BusterUserResponse, + BusterUserFavorite, + BusterUserListItem +} from '@/api/asset_interfaces/users'; +import type { + UsersFavoritePostPayload, + UserFavoriteDeletePayload, + UserUpdateFavoritesPayload, + UserRequestUserListPayload +} from '@/api/request_interfaces/user/interfaces'; import { mainApi } from '../instances'; import { serverFetch } from '../../createServerInstance'; @@ -76,3 +87,60 @@ export const inviteUser = async ({ team_ids }); }; + +export const getUserFavorites = async () => { + return mainApi.get(`/users/favorites`).then((response) => response.data); +}; + +export const getUserFavorites_server = async () => { + return serverFetch(`/users/favorites`); +}; + +export const createUserFavorite = async (payload: UsersFavoritePostPayload) => { + return mainApi + .post(`/users/favorites`, payload) + .then((response) => response.data); +}; + +export const createUserFavorite_server = async (payload: UsersFavoritePostPayload) => { + return serverFetch(`/users/favorites`, { + method: 'POST', + body: JSON.stringify(payload) + }); +}; + +export const deleteUserFavorite = async (payload: UserFavoriteDeletePayload) => { + return mainApi + .delete(`/users/favorites`, { data: payload }) + .then((response) => response.data); +}; + +export const deleteUserFavorite_server = async (payload: UserFavoriteDeletePayload) => { + return serverFetch(`/users/favorites`, { + method: 'DELETE', + body: JSON.stringify(payload) + }); +}; + +export const updateUserFavorites = async (payload: UserUpdateFavoritesPayload) => { + return mainApi + .put(`/users/favorites`, payload) + .then((response) => response.data); +}; + +export const updateUserFavorites_server = async (payload: UserUpdateFavoritesPayload) => { + return serverFetch(`/users/favorites`, { + method: 'PUT', + body: JSON.stringify(payload) + }); +}; + +export const getUserList = async (payload: UserRequestUserListPayload) => { + return mainApi + .get(`/users/list`, { params: payload }) + .then((response) => response.data); +}; + +export const getUserList_server = async (payload: UserRequestUserListPayload) => { + return serverFetch(`/users/list`, { params: payload }); +}; diff --git a/web/src/api/buster_socket/index.ts b/web/src/api/buster_socket/index.ts index 0b39fb8fd..fe2fad433 100644 --- a/web/src/api/buster_socket/index.ts +++ b/web/src/api/buster_socket/index.ts @@ -1,8 +1,7 @@ -import type { UserEmits, UserResponses, UserResponsesTypes } from './user'; import type { ChatEmits, ChatResponseTypes, ChatsResponses } from './chats'; -export type BusterSocketRequest = UserEmits | ChatEmits; +export type BusterSocketRequest = ChatEmits; -export type BusterSocketResponse = UserResponsesTypes | ChatResponseTypes; +export type BusterSocketResponse = ChatResponseTypes; -export type BusterSocketResponseRoute = keyof typeof UserResponses | keyof typeof ChatsResponses; +export type BusterSocketResponseRoute = keyof typeof ChatsResponses; diff --git a/web/src/api/buster_socket/user/index.ts b/web/src/api/buster_socket/user/index.ts deleted file mode 100644 index 7f85fe9c3..000000000 --- a/web/src/api/buster_socket/user/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './userRequests'; -export * from './userResponses'; diff --git a/web/src/api/buster_socket/user/userRequests.ts b/web/src/api/buster_socket/user/userRequests.ts deleted file mode 100644 index 0c8964612..000000000 --- a/web/src/api/buster_socket/user/userRequests.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { BusterSocketRequestBase } from '../base_interfaces'; -import type { - UsersFavoritePostPayload, - UserFavoriteDeletePayload, - UserUpdateFavoritesPayload, - UserRequestUserListPayload -} from '@/api/request_interfaces/user/interfaces'; - -export type UsersFavoritePost = BusterSocketRequestBase< - '/users/favorites/post', - UsersFavoritePostPayload ->; - -export type UsersFavoriteList = BusterSocketRequestBase<'/users/favorites/list', {}>; - -export type UserFavoriteDelete = BusterSocketRequestBase< - '/users/favorites/delete', - UserFavoriteDeletePayload ->; - -export type UserUpdateFavorites = BusterSocketRequestBase< - '/users/favorites/update', - UserUpdateFavoritesPayload ->; - -export type UserRequestUserList = BusterSocketRequestBase< - '/users/list', - UserRequestUserListPayload ->; - -export type UserEmits = - | UsersFavoritePost - | UsersFavoriteList - | UserFavoriteDelete - | UserUpdateFavorites - | UserRequestUserList; diff --git a/web/src/api/buster_socket/user/userResponses.ts b/web/src/api/buster_socket/user/userResponses.ts deleted file mode 100644 index 8b67a1686..000000000 --- a/web/src/api/buster_socket/user/userResponses.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { - BusterUserFavorite, - BusterUserListItem, - BusterUserPalette, - BusterUserResponse -} from '@/api/asset_interfaces/users'; - -export enum UserResponses { - '/users/favorites/list:listFavorites' = '/users/favorites/list:listFavorites', - '/users/favorites/post:createFavorite' = '/users/favorites/post:createFavorite', - '/users/get:getUser' = '/users/get:getUser', - '/users/favorites/update:updateFavorite' = '/users/favorites/update:updateFavorite', - '/users/list:listUsersTeams' = '/users/list:listUsersTeams', - '/users/list:listUsers' = '/users/list:listUsers' -} - -export type UserColorsPost_createUserColorPalette = { - route: '/users/colors/post:createUserColorPalette'; - callback: (d: BusterUserPalette[]) => void; - onError?: (d: unknown) => void; -}; - -export type UserFavoriteList_listFavorites = { - route: '/users/favorites/list:listFavorites'; - callback: (d: BusterUserFavorite[]) => void; - onError?: (d: unknown) => void; -}; - -export type UserFavoritesPost_createFavorite = { - route: '/users/favorites/post:createFavorite'; - callback: (d: BusterUserFavorite[]) => void; - onError?: (d: unknown) => void; -}; - -export type UserFavoritesUpdate_updateFavorite = { - route: '/users/favorites/update:updateFavorite'; - callback: (d: BusterUserFavorite[]) => void; - onError?: (d: unknown) => void; -}; - -export type UserGet_getUser = { - route: '/users/get:getUser'; - callback: (d: BusterUserResponse) => void; - onError?: (d: unknown) => void; -}; - -export type UserList_getUserList = { - route: '/users/list:listUsers'; - callback: (d: BusterUserListItem[]) => void; - onError?: (d: unknown) => void; -}; - -export type UserResponsesTypes = - | UserColorsPost_createUserColorPalette - | UserFavoriteList_listFavorites - | UserFavoritesPost_createFavorite - | UserGet_getUser - | UserFavoritesUpdate_updateFavorite - | UserList_getUserList; diff --git a/web/src/api/query_keys/users.ts b/web/src/api/query_keys/users.ts index 66de89107..fd53abd14 100644 --- a/web/src/api/query_keys/users.ts +++ b/web/src/api/query_keys/users.ts @@ -7,11 +7,14 @@ import type { BusterUserPermissionGroup, BusterUserResponse, BusterUserTeamListItem, - OrganizationUser + OrganizationUser, + BusterUserListItem } from '@/api/asset_interfaces/users'; +import type { UserRequestUserListPayload } from '@/api/request_interfaces/user/interfaces'; const favoritesGetList = queryOptions({ - queryKey: ['users', 'favorites', 'list'] as const + queryKey: ['users', 'favorites', 'list'] as const, + staleTime: 1000 * 60 * 60 // 1 hour }); const userGetUserMyself = queryOptions({ @@ -48,6 +51,11 @@ const userGetUserDatasetGroups = (userId: string) => queryKey: ['users', userId, 'datasetGroups'] as const }); +const userGetUserList = (params: UserRequestUserListPayload) => + queryOptions({ + queryKey: ['users', 'list', params] as const + }); + export const userQueryKeys = { favoritesGetList, userGetUserMyself, @@ -56,5 +64,6 @@ export const userQueryKeys = { userGetUserTeams, userGetUserAttributes, userGetUserDatasets, - userGetUserDatasetGroups + userGetUserDatasetGroups, + userGetUserList }; diff --git a/web/src/context/Users/useFavoriteProvider.tsx b/web/src/context/Users/useFavoriteProvider.tsx index 378bbe2de..19c4507b1 100644 --- a/web/src/context/Users/useFavoriteProvider.tsx +++ b/web/src/context/Users/useFavoriteProvider.tsx @@ -1,46 +1,24 @@ import { useMemoizedFn } from '@/hooks'; -import { useSocketQueryEmitOn, useSocketQueryMutation } from '@/api/buster_socket_query'; -import { queryKeys } from '@/api/query_keys'; import type { BusterUserFavorite } from '@/api/asset_interfaces/users'; import isEmpty from 'lodash/isEmpty'; +import { + useAddUserFavorite, + useDeleteUserFavorite, + useGetUserFavorites +} from '@/api/buster_rest/users'; const DEFAULT_FAVORITES: BusterUserFavorite[] = []; export const useFavoriteProvider = () => { - const { data: userFavorites, refetch: refreshFavoritesList } = useSocketQueryEmitOn({ - emitEvent: { route: '/users/favorites/list', payload: {} }, - responseEvent: '/users/favorites/list:listFavorites', - options: queryKeys.favoritesGetList - }); + const { data: userFavorites, refetch: refreshFavoritesList } = useGetUserFavorites(); - const { mutate: addItemToFavorite } = useSocketQueryMutation({ - emitEvent: '/users/favorites/post', - responseEvent: '/users/favorites/post:createFavorite', - options: queryKeys.favoritesGetList, - preCallback: (prev, mutationParams) => [mutationParams, ...(prev || [])] - }); + const { mutate: addItemToFavorite } = useAddUserFavorite(); - const { mutate: removeItemFromFavorite } = useSocketQueryMutation({ - emitEvent: '/users/favorites/delete', - responseEvent: '/users/favorites/post:createFavorite', - options: queryKeys.favoritesGetList, - preCallback: (prev, mutationParams) => prev?.filter((f) => f.id !== mutationParams.id) || [] - }); - - const { mutate: updateFavorites } = useSocketQueryMutation({ - emitEvent: '/users/favorites/update', - responseEvent: '/users/favorites/update:updateFavorite', - options: queryKeys.favoritesGetList, - preCallback: (prev, mutationParams) => { - return mutationParams.favorites.map((id, index) => { - const favorite = (prev || []).find((f) => f.id === id || f.collection_id === id)!; - return { ...favorite, index }; - }); - } - }); + const { mutate: removeItemFromFavorite } = useDeleteUserFavorite(); const bulkEditFavorites = useMemoizedFn(async (favorites: string[]) => { - return updateFavorites({ favorites }); + // return updateFavorites({ favorites }); + alert('TODO - feature not implemented yet'); }); return { diff --git a/web/src/hooks/useWebSocket/helpers.ts b/web/src/hooks/useWebSocket/helpers.ts index 7062e16d5..5c2270aa6 100644 --- a/web/src/hooks/useWebSocket/helpers.ts +++ b/web/src/hooks/useWebSocket/helpers.ts @@ -1,5 +1,4 @@ import { isDev } from '@/config'; -import { UserResponses } from '@/api/buster_socket/user'; import type { BusterSocketResponseBase, BusterSocketResponseMessage @@ -26,7 +25,6 @@ export const createBusterResponse = ( const isKnownMessageRoute = (parsedMessage: BusterSocketResponseMessage) => { const allResponses = { - ...UserResponses, ...ChatsResponses }; const event = parsedMessage?.event;