mirror of https://github.com/buster-so/buster.git
query key updates
This commit is contained in:
parent
01382338b1
commit
5d283d49d3
|
@ -2,7 +2,6 @@
|
|||
description: Rules and guidelines for the asset_interfaces directory containing TypeScript interface definitions for all API responses
|
||||
globs: src/api/asset_interfaces/**/*
|
||||
---
|
||||
|
||||
# API Asset Interfaces Directory Rules
|
||||
|
||||
This directory (`src/api/asset_interfaces`) contains TypeScript interface definitions for all API responses. Each subdirectory represents a distinct API namespace.
|
||||
|
@ -13,7 +12,8 @@ src/api/asset_interfaces/
|
|||
├── [namespace]/
|
||||
│ ├── index.ts # Exports all interfaces and types
|
||||
│ ├── interfaces.ts # Contains type definitions
|
||||
│ └── [other].ts # Optional additional type files
|
||||
│ ├── queryKeys.ts # Contains query key definitions for TanStack Query
|
||||
│ └── [other].ts # Optional additional type files
|
||||
```
|
||||
|
||||
## Rules and Guidelines
|
||||
|
@ -21,6 +21,7 @@ src/api/asset_interfaces/
|
|||
1. Each namespace MUST have:
|
||||
- An `index.ts` file that exports all types
|
||||
- An `interfaces.ts` file containing type definitions
|
||||
- A `queryKeys.ts` file that defines query key options for TanStack Query
|
||||
|
||||
2. Interface File (`interfaces.ts`) Requirements:
|
||||
- Must contain TypeScript interfaces, types, and enums for API responses
|
||||
|
@ -32,12 +33,28 @@ src/api/asset_interfaces/
|
|||
- Types: `TPascalCase`
|
||||
- Enums: `EPascalCase`
|
||||
|
||||
3. Index File (`index.ts`) Requirements:
|
||||
3. Query Keys File (`queryKeys.ts`) Requirements:
|
||||
- Defines reusable query keys and query options for TanStack React Query
|
||||
- Uses `queryOptions` to create predefined query configurations
|
||||
- Ensures consistent and structured key usage across API queries
|
||||
- Example:
|
||||
```typescript
|
||||
import { queryOptions } from '@tanstack/react-query';
|
||||
import type { BusterChat } from './chatInterfaces';
|
||||
|
||||
const chatsGetChat = (chatId: string) =>
|
||||
queryOptions<BusterChat>({
|
||||
queryKey: ['chats', 'get', chatId] as const,
|
||||
staleTime: 10 * 1000
|
||||
});
|
||||
```
|
||||
|
||||
4. Index File (`index.ts`) Requirements:
|
||||
- Must re-export all types from `interfaces.ts`
|
||||
- Should not contain any type definitions
|
||||
- May include type utility functions if needed
|
||||
|
||||
4. General Guidelines:
|
||||
5. General Guidelines:
|
||||
- Keep interfaces focused and single-responsibility
|
||||
- Use TypeScript's built-in utility types when appropriate
|
||||
- Document breaking changes in type definitions
|
||||
|
@ -54,10 +71,22 @@ export interface IApiResponse<T> {
|
|||
readonly message?: string;
|
||||
}
|
||||
|
||||
// queryKeys.ts
|
||||
import { queryOptions } from '@tanstack/react-query';
|
||||
import type { IApiResponse } from './interfaces';
|
||||
|
||||
const fetchDataQuery = (id: string) =>
|
||||
queryOptions<IApiResponse<any>>({
|
||||
queryKey: ['data', 'fetch', id] as const,
|
||||
staleTime: 60 * 1000
|
||||
});
|
||||
|
||||
// index.ts
|
||||
export * from './interfaces';
|
||||
export * from './queryKeys';
|
||||
```
|
||||
|
||||
## Purpose
|
||||
|
||||
This directory serves as the single source of truth for API response types across the application. It ensures type safety and provides proper TypeScript intellisense when working with API responses.
|
||||
This directory serves as the single source of truth for API response types and query keys across the application. It ensures type safety, consistency, and provides proper TypeScript intellisense when working with API responses and queries.
|
||||
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
import { queryOptions, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import type { BusterChat, BusterChatListItem } from './chatInterfaces';
|
||||
import type { GetChatListParams } from '@/api/request_interfaces/chats';
|
||||
|
||||
const chatsGetChat = (chatId: string) =>
|
||||
queryOptions<BusterChat>({
|
||||
queryKey: ['chats', 'get', chatId] as const,
|
||||
staleTime: 10 * 1000
|
||||
});
|
||||
|
||||
const chatsGetList = (filters?: GetChatListParams) =>
|
||||
queryOptions<BusterChatListItem[]>({
|
||||
queryKey: ['chats', 'list', filters] as const
|
||||
});
|
||||
|
||||
const deleteChat = () => {
|
||||
const queryKey = ['chats', 'list'] as const;
|
||||
return queryOptions<BusterChatListItem[]>({
|
||||
queryKey
|
||||
});
|
||||
};
|
||||
|
||||
export const chatQueryKeys = {
|
||||
'/chats/get:getChat': chatsGetChat,
|
||||
'/chats/list:getChatsList': chatsGetList,
|
||||
'/chats/delete:deleteChat': deleteChat
|
||||
};
|
||||
|
||||
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/delete:deleteChat']!();
|
||||
const queryKey2 = options2.queryKey;
|
||||
|
||||
const data3 = queryClient.getQueryData(queryKey2);
|
||||
|
||||
//
|
||||
};
|
|
@ -0,0 +1,41 @@
|
|||
import { queryOptions, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import type { BusterChat, BusterChatListItem } from './chatInterfaces';
|
||||
import type { GetChatListParams } from '@/api/request_interfaces/chats';
|
||||
|
||||
const chatsGetChat = (chatId: string) =>
|
||||
queryOptions<BusterChat>({
|
||||
queryKey: ['chats', 'get', chatId] as const,
|
||||
staleTime: 10 * 1000
|
||||
});
|
||||
|
||||
const chatsGetList = (filters?: GetChatListParams) =>
|
||||
queryOptions<BusterChatListItem[]>({
|
||||
queryKey: ['chats', 'list', filters] as const,
|
||||
staleTime: 10 * 1000
|
||||
});
|
||||
|
||||
export const chatQueryKeys = {
|
||||
'/chats/get:getChat': chatsGetChat,
|
||||
'/chats/list:getChatsList': chatsGetList
|
||||
};
|
||||
|
||||
// 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,12 +0,0 @@
|
|||
import { queryOptions } from '@tanstack/react-query';
|
||||
import { BusterCollectionListItem } from './interfaces';
|
||||
import type { GetCollectionListParams } from '../../request_interfaces/collections';
|
||||
|
||||
const collectionsGetList = (filters?: GetCollectionListParams) =>
|
||||
queryOptions<BusterCollectionListItem[]>({
|
||||
queryKey: ['collections', 'list', filters] as const
|
||||
});
|
||||
|
||||
export const collectionQueryKeys = {
|
||||
'/collections/list:getCollectionsList': collectionsGetList
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
import { queryOptions } from '@tanstack/react-query';
|
||||
import { BusterCollectionListItem, BusterCollection } from './interfaces';
|
||||
import type { GetCollectionListParams } from '../../request_interfaces/collections';
|
||||
|
||||
const collectionsGetList = (filters?: GetCollectionListParams) =>
|
||||
queryOptions<BusterCollectionListItem[]>({
|
||||
queryKey: ['collections', 'list', filters] as const
|
||||
});
|
||||
|
||||
const collectionsGetCollection = (collectionId: string) =>
|
||||
queryOptions<BusterCollection>({
|
||||
queryKey: ['collections', 'get', collectionId] as const
|
||||
});
|
||||
|
||||
export const collectionQueryKeys = {
|
||||
'/collections/list:getCollectionsList': collectionsGetList,
|
||||
'/collections/get:collectionState': collectionsGetCollection
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
import { queryOptions } from '@tanstack/react-query';
|
||||
import type { BusterDashboard, BusterDashboardResponse } from './interfaces';
|
||||
|
||||
const dashboardGetList = queryOptions<BusterDashboard[]>({
|
||||
queryKey: ['dashboard', 'list'] as const,
|
||||
staleTime: 10 * 1000
|
||||
});
|
||||
|
||||
const dashboardGetDashboard = (dashboardId: string) =>
|
||||
queryOptions<BusterDashboardResponse>({
|
||||
queryKey: ['dashboard', 'get', dashboardId] as const,
|
||||
staleTime: 10 * 1000
|
||||
});
|
||||
|
||||
export const dashboardQueryKeys = {
|
||||
'/dashboards/get:getDashboardState': dashboardGetDashboard,
|
||||
'/dashboards/list:getDashboardsList': dashboardGetList
|
||||
};
|
|
@ -1,7 +1,11 @@
|
|||
import { chatQueryKeys } from './chat/chatQueryKeys';
|
||||
import { collectionQueryKeys } from './collection/collectionQueryKeys';
|
||||
import { chatQueryKeys } from './chat/queryKeys';
|
||||
import { collectionQueryKeys } from './collection/queryKeys';
|
||||
import { userQueryKeys } from './users/queryKeys';
|
||||
import { dashboardQueryKeys } from './dashboard/queryKeys';
|
||||
|
||||
export const queryKeys = {
|
||||
...chatQueryKeys,
|
||||
...collectionQueryKeys
|
||||
...collectionQueryKeys,
|
||||
...userQueryKeys,
|
||||
...dashboardQueryKeys
|
||||
};
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import { queryOptions } from '@tanstack/react-query';
|
||||
import { BusterUserFavorite } from './interfaces';
|
||||
|
||||
const favoritesGetList = queryOptions<BusterUserFavorite[]>({
|
||||
queryKey: ['users', 'favorites', 'list'] as const
|
||||
});
|
||||
|
||||
export const userQueryKeys = {
|
||||
'/favorites/list:getFavoritesList': favoritesGetList
|
||||
};
|
|
@ -16,9 +16,10 @@ export const useSocketQueryEmitOn = <
|
|||
socketResponse: TRoute,
|
||||
options: UseQueryOptions<TData, TError, TData, TQueryKey>,
|
||||
callback?: (currentData: TData | null, newData: InferBusterSocketResponseData<TRoute>) => TData,
|
||||
enabledTrigger?: boolean | string
|
||||
enabledTriggerProp?: boolean | string
|
||||
) => {
|
||||
const busterSocket = useBusterWebSocket();
|
||||
const enabledTrigger = enabledTriggerProp ?? true;
|
||||
|
||||
const emitQueryFn = useMemoizedFn(async () => {
|
||||
busterSocket.emit(socketRequest);
|
||||
|
@ -30,5 +31,7 @@ export const useSocketQueryEmitOn = <
|
|||
}
|
||||
}, [enabledTrigger]);
|
||||
|
||||
return useSocketQueryOn(socketResponse, options, callback);
|
||||
const queryResult = useSocketQueryOn(socketResponse, options, callback);
|
||||
|
||||
return { ...queryResult, refetch: emitQueryFn };
|
||||
};
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import {
|
||||
type QueryFunction,
|
||||
type QueryKey,
|
||||
type UseQueryOptions,
|
||||
type UseMutationOptions,
|
||||
useMutation,
|
||||
useQueryClient
|
||||
} from '@tanstack/react-query';
|
||||
import { type UseQueryOptions, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import type {
|
||||
BusterSocketRequest,
|
||||
BusterSocketResponse,
|
||||
|
@ -15,7 +8,6 @@ import type {
|
|||
} from '@/api/buster_socket';
|
||||
import { useBusterWebSocket } from '@/context/BusterWebSocket';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { queryKeys } from '../asset_interfaces';
|
||||
import type {
|
||||
BusterSocketRequestConfig,
|
||||
BusterSocketRequestRoute,
|
||||
|
@ -23,7 +15,6 @@ import type {
|
|||
InferBusterSocketRequestPayload,
|
||||
InferBusterSocketResponseData
|
||||
} from './types';
|
||||
import type { BusterChatListItem } from '@/api/asset_interfaces/chat';
|
||||
|
||||
export function useSocketQueryMutation<
|
||||
TRequestRoute extends BusterSocketRequestRoute,
|
||||
|
@ -36,10 +27,13 @@ export function useSocketQueryMutation<
|
|||
socketRequest: BusterSocketRequestConfig<TRequestRoute>,
|
||||
socketResponse: BusterSocketResponseConfig<TRoute>,
|
||||
options?: UseQueryOptions<TQueryData, any, TQueryData, any>,
|
||||
preCallback?: (currentData: TQueryData | null, variables: TPayload) => TQueryData,
|
||||
callback?: (
|
||||
preCallback?: (
|
||||
currentData: TQueryData | null,
|
||||
newData: InferBusterSocketResponseData<TRoute>
|
||||
variables: TPayload
|
||||
) => TQueryData | Promise<TQueryData>,
|
||||
callback?: (
|
||||
newData: InferBusterSocketResponseData<TRoute>,
|
||||
currentData: TQueryData | null
|
||||
) => TQueryData
|
||||
) {
|
||||
const busterSocket = useBusterWebSocket();
|
||||
|
@ -50,7 +44,7 @@ export function useSocketQueryMutation<
|
|||
|
||||
if (queryKey && preCallback) {
|
||||
const currentData = queryClient.getQueryData<TQueryData>(queryKey) ?? null;
|
||||
const transformedData = preCallback(currentData, variables);
|
||||
const transformedData = await preCallback(currentData, variables);
|
||||
queryClient.setQueryData(queryKey, transformedData);
|
||||
}
|
||||
|
||||
|
@ -70,7 +64,7 @@ export function useSocketQueryMutation<
|
|||
if (queryKey && callback) {
|
||||
const socketData = result as InferBusterSocketResponseData<TRoute>;
|
||||
const currentData = queryClient.getQueryData<TQueryData>(queryKey) ?? null;
|
||||
const transformedData = callback(currentData, socketData);
|
||||
const transformedData = callback(socketData, currentData);
|
||||
queryClient.setQueryData(queryKey, transformedData);
|
||||
return result as TData;
|
||||
}
|
||||
|
@ -85,29 +79,3 @@ export function useSocketQueryMutation<
|
|||
mutationFn
|
||||
});
|
||||
}
|
||||
|
||||
// const ExampleComponent = () => {
|
||||
// const queryClient = useQueryClient();
|
||||
// const options = queryKeys['/chats/list:getChatsList']();
|
||||
// const data = queryClient.getQueryData(options.queryKey);
|
||||
// data?.[0].created_by_avatar;
|
||||
|
||||
// const { mutate } = useSocketQueryMutation<
|
||||
// '/chats/delete',
|
||||
// '/chats/delete:deleteChat',
|
||||
// unknown,
|
||||
// { id: string }[],
|
||||
// { id: string }[],
|
||||
// BusterChatListItem[]
|
||||
// >(
|
||||
// { route: '/chats/delete' },
|
||||
// { route: '/chats/delete:deleteChat' },
|
||||
// options,
|
||||
// (currentData, newData) => {
|
||||
// currentData?.[0].created_by_avatar; // This should now be properly typed
|
||||
// return currentData ?? [];
|
||||
// }
|
||||
// );
|
||||
|
||||
// mutate([{ id: '123' }]);
|
||||
// };
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
import { useMemoizedFn } from 'ahooks';
|
||||
import { useBusterWebSocket } from '../../BusterWebSocket';
|
||||
import { useSocketQueryEmitAndOnce, useSocketQueryMutation } from '@/api/buster_socket_query';
|
||||
|
||||
export const useChatAssosciations = () => {
|
||||
const busterSocket = useBusterWebSocket();
|
||||
const x = useSocketQueryMutation('');
|
||||
|
||||
const onDeleteChat = useMemoizedFn(async (chatId: string) => {
|
||||
await busterSocket.emit({
|
||||
route: '/chats/delete',
|
||||
payload: { id: chatId }
|
||||
});
|
||||
//
|
||||
// await busterSocket.emit({
|
||||
// route: '/chats/delete',
|
||||
// payload: { id: chatId }
|
||||
// });
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
import { useSocketQueryEmitOn } from '@/hooks';
|
||||
import { queryKeys } from '@/api/asset_interfaces';
|
||||
import { useSocketQueryEmitOn } from '@/api/buster_socket_query';
|
||||
|
||||
export const useCollectionIndividual = ({ collectionId }: { collectionId: string | undefined }) => {
|
||||
const id = collectionId || '';
|
||||
|
||||
const { data: collection, isFetched: isCollectionFetched } = useSocketQueryEmitOn(
|
||||
{ route: '/collections/get', payload: { id: collectionId || '' } },
|
||||
{ route: '/collections/get:collectionState' },
|
||||
{ enabled: !!collectionId }
|
||||
{ route: '/collections/get', payload: { id } },
|
||||
'/collections/get:collectionState',
|
||||
queryKeys['/collections/get:collectionState'](id),
|
||||
undefined,
|
||||
!!id
|
||||
);
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import React, { useState } from 'react';
|
||||
import { useSocketQueryEmitOn } from '@/hooks';
|
||||
import { useSocketQueryEmitOn } from '@/api/buster_socket_query';
|
||||
import type { CollectionsListEmit } from '@/api/buster_socket/collections';
|
||||
import {
|
||||
ContextSelector,
|
||||
useContextSelector,
|
||||
createContext
|
||||
} from '@fluentui/react-context-selector';
|
||||
import { queryKeys } from '@/api/asset_interfaces';
|
||||
|
||||
type CollectionListFilters = Omit<CollectionsListEmit['payload'], 'page' | 'page_size'>;
|
||||
|
||||
|
@ -18,7 +19,8 @@ export const useCollectionLists = () => {
|
|||
refetch: refetchCollectionList
|
||||
} = useSocketQueryEmitOn(
|
||||
{ route: '/collections/list', payload: { page: 0, page_size: 1000, ...collectionListFilters } },
|
||||
{ route: '/collections/list:listCollections' }
|
||||
'/collections/list:listCollections',
|
||||
queryKeys['/collections/list:getCollectionsList']()
|
||||
);
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { BusterDashboardResponse } from '@/api/asset_interfaces';
|
||||
import { BusterDashboardResponse, queryKeys } from '@/api/asset_interfaces';
|
||||
import { useBusterAssetsContextSelector } from '@/context/Assets/BusterAssetsProvider';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useBusterMetricsIndividualContextSelector } from '@/context/Metrics';
|
||||
import { useSocketQueryEmitOn } from '@/hooks';
|
||||
import { useSocketQueryEmitOn } from '@/api/buster_socket_query';
|
||||
|
||||
export const useBusterDashboardIndividual = ({
|
||||
dashboardId = ''
|
||||
|
@ -18,23 +17,22 @@ export const useBusterDashboardIndividual = ({
|
|||
|
||||
const { data: dashboardResponse, refetch: refreshDashboard } = useSocketQueryEmitOn(
|
||||
{ route: '/dashboards/get', payload: { id: dashboardId, password } },
|
||||
{ route: '/dashboards/get:getDashboardState' },
|
||||
{ enabled: !!dashboardId }
|
||||
'/dashboards/get:getDashboardState',
|
||||
queryKeys['/dashboards/get:getDashboardState'](dashboardId || ''),
|
||||
(currentData, newData) => {
|
||||
initializeDashboardMetrics(newData.metrics);
|
||||
return newData;
|
||||
},
|
||||
!!dashboardId
|
||||
);
|
||||
|
||||
const initializeDashboard = useMemoizedFn((d: BusterDashboardResponse) => {
|
||||
const metrics = d.metrics;
|
||||
|
||||
for (const metric of metrics) {
|
||||
onInitializeMetric(metric);
|
||||
const initializeDashboardMetrics = useMemoizedFn(
|
||||
(metrics: BusterDashboardResponse['metrics']) => {
|
||||
for (const metric of metrics) {
|
||||
onInitializeMetric(metric);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (dashboardResponse) {
|
||||
initializeDashboard(dashboardResponse);
|
||||
}
|
||||
}, [dashboardResponse]);
|
||||
);
|
||||
|
||||
const dashboard = dashboardResponse?.dashboard;
|
||||
const metrics = dashboardResponse?.metrics || [];
|
||||
|
|
|
@ -1,54 +1,37 @@
|
|||
import { useMemoizedFn } from 'ahooks';
|
||||
import { useSocketQueryEmitOn, useSocketQueryMutation } from '@/hooks';
|
||||
import { useSocketQueryEmitOn, useSocketQueryMutation } from '@/api/buster_socket_query';
|
||||
import { queryKeys } from '@/api/asset_interfaces';
|
||||
|
||||
export const useFavoriteProvider = () => {
|
||||
const { data: userFavorites, refetch: refreshFavoritesList } = useSocketQueryEmitOn(
|
||||
{ route: '/users/favorites/list', payload: {} },
|
||||
{ route: '/users/favorites/list:listFavorites' }
|
||||
'/users/favorites/list:listFavorites',
|
||||
queryKeys['/favorites/list:getFavoritesList']
|
||||
);
|
||||
|
||||
const { mutate: addItemToFavorite } = useSocketQueryMutation(
|
||||
{ route: '/users/favorites/post' },
|
||||
{ route: '/users/favorites/post:createFavorite' },
|
||||
{
|
||||
preSetQueryData: [
|
||||
{
|
||||
responseRoute: '/users/favorites/list:listFavorites',
|
||||
callback: (prev, mutationParams) => [mutationParams, ...(prev || [])]
|
||||
}
|
||||
]
|
||||
}
|
||||
queryKeys['/favorites/list:getFavoritesList'],
|
||||
(prev, mutationParams) => [mutationParams, ...(prev || [])]
|
||||
);
|
||||
|
||||
const { mutate: removeItemFromFavorite } = useSocketQueryMutation(
|
||||
{ route: '/users/favorites/delete' },
|
||||
{ route: '/users/favorites/post:createFavorite' },
|
||||
{
|
||||
preSetQueryData: [
|
||||
{
|
||||
responseRoute: '/users/favorites/list:listFavorites',
|
||||
callback: (prev, mutationParams) => prev?.filter((f) => f.id !== mutationParams.id) || []
|
||||
}
|
||||
]
|
||||
}
|
||||
queryKeys['/favorites/list:getFavoritesList'],
|
||||
(prev, mutationParams) => prev?.filter((f) => f.id !== mutationParams.id) || []
|
||||
);
|
||||
|
||||
const { mutate: updateFavorites } = useSocketQueryMutation(
|
||||
{ route: '/users/favorites/update' },
|
||||
{ route: '/users/favorites/update:updateFavorite' },
|
||||
{
|
||||
awaitPrefetchQueryData: true,
|
||||
preSetQueryData: [
|
||||
{
|
||||
responseRoute: '/users/favorites/list:listFavorites',
|
||||
callback: (prev, mutationParams) => {
|
||||
return mutationParams.favorites.map((id, index) => {
|
||||
let favorite = (prev || []).find((f) => f.id === id || f.collection_id === id)!;
|
||||
return { ...favorite, index };
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
||||
queryKeys['/favorites/list:getFavoritesList'],
|
||||
(prev, mutationParams) => {
|
||||
return mutationParams.favorites.map((id, index) => {
|
||||
const favorite = (prev || []).find((f) => f.id === id || f.collection_id === id)!;
|
||||
return { ...favorite, index };
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue