| import { useRecoilValue } from 'recoil'; |
| import { useMutation, useQueryClient } from '@tanstack/react-query'; |
| import { dataService, QueryKeys } from 'librechat-data-provider'; |
| import type { UseMutationResult } from '@tanstack/react-query'; |
| import type t from 'librechat-data-provider'; |
| import { |
| |
| addGroupToAll, |
| addPromptGroup, |
| updateGroupInAll, |
| updateGroupFields, |
| deletePromptGroup, |
| removeGroupFromAll, |
| } from '~/utils'; |
| import store from '~/store'; |
|
|
| export const useUpdatePromptGroup = ( |
| options?: t.UpdatePromptGroupOptions, |
| ): UseMutationResult< |
| t.TUpdatePromptGroupResponse, |
| unknown, |
| t.TUpdatePromptGroupVariables, |
| unknown |
| > => { |
| const { onMutate, onError, onSuccess } = options || {}; |
| const queryClient = useQueryClient(); |
| const name = useRecoilValue(store.promptsName); |
| const pageSize = useRecoilValue(store.promptsPageSize); |
| const category = useRecoilValue(store.promptsCategory); |
|
|
| return useMutation({ |
| mutationFn: (variables: t.TUpdatePromptGroupVariables) => |
| dataService.updatePromptGroup(variables), |
| onMutate: (variables: t.TUpdatePromptGroupVariables) => { |
| const groupData = queryClient.getQueryData<t.TPromptGroup>([ |
| QueryKeys.promptGroup, |
| variables.id, |
| ]); |
| const group = groupData ? structuredClone(groupData) : undefined; |
|
|
| const groupListData = queryClient.getQueryData<t.PromptGroupListData>([ |
| QueryKeys.promptGroups, |
| name, |
| category, |
| pageSize, |
| ]); |
| const previousListData = groupListData ? structuredClone(groupListData) : undefined; |
|
|
| let update = variables.payload; |
| if (update.removeProjectIds && group?.projectIds) { |
| update = structuredClone(update); |
| update.projectIds = group.projectIds.filter((id) => !update.removeProjectIds?.includes(id)); |
| delete update.removeProjectIds; |
| } |
|
|
| if (groupListData) { |
| const newData = updateGroupFields( |
| |
| groupListData, |
| |
| { _id: variables.id, ...update }, |
| |
| (group) => queryClient.setQueryData([QueryKeys.promptGroup, variables.id], group), |
| ); |
| queryClient.setQueryData<t.PromptGroupListData>( |
| [QueryKeys.promptGroups, name, category, pageSize], |
| newData, |
| ); |
| } |
|
|
| if (onMutate) { |
| onMutate(variables); |
| } |
|
|
| return { group, previousListData }; |
| }, |
| onError: (err, variables, context) => { |
| if (context?.group) { |
| queryClient.setQueryData([QueryKeys.promptGroups, variables.id], context.group); |
| } |
| if (context?.previousListData) { |
| queryClient.setQueryData<t.PromptGroupListData>( |
| [QueryKeys.promptGroups, name, category, pageSize], |
| context.previousListData, |
| ); |
| } |
| if (onError) { |
| onError(err, variables, context); |
| } |
| }, |
| onSuccess: (response, variables, context) => { |
| updateGroupInAll(queryClient, { _id: variables.id, ...response }); |
| if (onSuccess) { |
| onSuccess(response, variables, context); |
| } |
| }, |
| }); |
| }; |
|
|
| export const useCreatePrompt = ( |
| options?: t.CreatePromptOptions, |
| ): UseMutationResult<t.TCreatePromptResponse, unknown, t.TCreatePrompt, unknown> => { |
| const queryClient = useQueryClient(); |
| const { onSuccess, ...rest } = options || {}; |
| const name = useRecoilValue(store.promptsName); |
| const pageSize = useRecoilValue(store.promptsPageSize); |
| const category = useRecoilValue(store.promptsCategory); |
|
|
| return useMutation({ |
| mutationFn: (payload: t.TCreatePrompt) => dataService.createPrompt(payload), |
| ...rest, |
| onSuccess: (response, variables, context) => { |
| const { prompt, group } = response; |
| queryClient.setQueryData( |
| [QueryKeys.prompts, variables.prompt.groupId], |
| (oldData: t.TPrompt[] | undefined) => { |
| return [prompt, ...(oldData ?? [])]; |
| }, |
| ); |
|
|
| if (group) { |
| queryClient.setQueryData<t.PromptGroupListData>( |
| [QueryKeys.promptGroups, name, category, pageSize], |
| (data) => { |
| if (!data) { |
| return data; |
| } |
| return addPromptGroup(data, group); |
| }, |
| ); |
|
|
| addGroupToAll(queryClient, group); |
| } |
|
|
| if (onSuccess) { |
| onSuccess(response, variables, context); |
| } |
| }, |
| }); |
| }; |
|
|
| export const useAddPromptToGroup = ( |
| options?: t.CreatePromptOptions, |
| ): UseMutationResult< |
| t.TCreatePromptResponse, |
| unknown, |
| t.TCreatePrompt & { groupId: string }, |
| unknown |
| > => { |
| const queryClient = useQueryClient(); |
| const { onSuccess, ...rest } = options || {}; |
|
|
| return useMutation({ |
| mutationFn: ({ groupId, ...payload }: t.TCreatePrompt & { groupId: string }) => |
| dataService.addPromptToGroup(groupId, payload), |
| ...rest, |
| onSuccess: (response, variables, context) => { |
| const { prompt } = response; |
| queryClient.setQueryData( |
| [QueryKeys.prompts, variables.prompt.groupId], |
| (oldData: t.TPrompt[] | undefined) => { |
| return [prompt, ...(oldData ?? [])]; |
| }, |
| ); |
|
|
| if (onSuccess) { |
| onSuccess(response, variables, context); |
| } |
| }, |
| }); |
| }; |
|
|
| export const useDeletePrompt = ( |
| options?: t.DeletePromptOptions, |
| ): UseMutationResult<t.TDeletePromptResponse, unknown, t.TDeletePromptVariables, unknown> => { |
| const queryClient = useQueryClient(); |
| const { onSuccess, ...rest } = options || {}; |
| const name = useRecoilValue(store.promptsName); |
| const pageSize = useRecoilValue(store.promptsPageSize); |
| const category = useRecoilValue(store.promptsCategory); |
|
|
| return useMutation({ |
| mutationFn: (payload: t.TDeletePromptVariables) => dataService.deletePrompt(payload), |
| ...rest, |
| onSuccess: (response, variables, context) => { |
| if (response.promptGroup) { |
| const promptGroupId = response.promptGroup.id; |
| queryClient.setQueryData<t.PromptGroupListData>( |
| [QueryKeys.promptGroups, name, category, pageSize], |
| (data) => { |
| if (!data) { |
| return data; |
| } |
| return deletePromptGroup(data, promptGroupId); |
| }, |
| ); |
|
|
| removeGroupFromAll(queryClient, promptGroupId); |
| } else { |
| queryClient.setQueryData<t.TPrompt[]>( |
| [QueryKeys.prompts, variables.groupId], |
| (oldData?: t.TPrompt[]) => { |
| const prompts = oldData ? oldData.filter((prompt) => prompt._id !== variables._id) : []; |
| queryClient.setQueryData<t.TPromptGroup>( |
| [QueryKeys.promptGroup, variables.groupId], |
| (data) => { |
| if (!data) { |
| return data; |
| } |
| if (data.productionId === variables._id) { |
| data.productionId = prompts[0]._id; |
| data.productionPrompt = prompts[0]; |
| } |
| }, |
| ); |
| return prompts; |
| }, |
| ); |
| } |
| if (onSuccess) { |
| onSuccess(response, variables, context); |
| } |
| }, |
| }); |
| }; |
|
|
| export const useDeletePromptGroup = ( |
| options?: t.DeletePromptGroupOptions, |
| ): UseMutationResult< |
| t.TDeletePromptGroupResponse, |
| unknown, |
| t.TDeletePromptGroupRequest, |
| unknown |
| > => { |
| const queryClient = useQueryClient(); |
| const { onSuccess, ...rest } = options || {}; |
| const name = useRecoilValue(store.promptsName); |
| const pageSize = useRecoilValue(store.promptsPageSize); |
| const category = useRecoilValue(store.promptsCategory); |
|
|
| return useMutation({ |
| mutationFn: (variables: t.TDeletePromptGroupRequest) => |
| dataService.deletePromptGroup(variables.id), |
| ...rest, |
| onSuccess: (response, variables, context) => { |
| queryClient.setQueryData<t.PromptGroupListData>( |
| [QueryKeys.promptGroups, name, category, pageSize], |
| (data) => { |
| if (!data) { |
| return data; |
| } |
|
|
| return deletePromptGroup(data, variables.id); |
| }, |
| ); |
|
|
| removeGroupFromAll(queryClient, variables.id); |
| if (onSuccess) { |
| onSuccess(response, variables, context); |
| } |
| }, |
| }); |
| }; |
|
|
| export const useUpdatePromptLabels = ( |
| options?: t.UpdatePromptLabelOptions, |
| ): UseMutationResult< |
| t.TUpdatePromptLabelsResponse, |
| unknown, |
| t.TUpdatePromptLabelsRequest, |
| unknown |
| > => { |
| const { onSuccess, ...rest } = options || {}; |
| return useMutation({ |
| mutationFn: (variables: t.TUpdatePromptLabelsRequest) => |
| dataService.updatePromptLabels(variables), |
| ...rest, |
| onSuccess: (response, variables, context) => { |
| if (onSuccess) { |
| onSuccess(response, variables, context); |
| } |
| }, |
| }); |
| }; |
|
|
| export const useMakePromptProduction = (options?: t.MakePromptProductionOptions) => { |
| const queryClient = useQueryClient(); |
| const { onSuccess, onError, onMutate } = options || {}; |
| const name = useRecoilValue(store.promptsName); |
| const pageSize = useRecoilValue(store.promptsPageSize); |
| const category = useRecoilValue(store.promptsCategory); |
|
|
| return useMutation({ |
| mutationFn: (variables: t.TMakePromptProductionRequest) => |
| dataService.makePromptProduction(variables.id), |
| onMutate: (variables: t.TMakePromptProductionRequest) => { |
| const group = JSON.parse( |
| JSON.stringify( |
| queryClient.getQueryData<t.TPromptGroup>([QueryKeys.promptGroup, variables.groupId]), |
| ), |
| ) as t.TPromptGroup; |
| const groupData = queryClient.getQueryData<t.PromptGroupListData>([ |
| QueryKeys.promptGroups, |
| name, |
| category, |
| pageSize, |
| ]); |
| const previousListData = JSON.parse(JSON.stringify(groupData)) as t.PromptGroupListData; |
|
|
| if (groupData) { |
| const newData = updateGroupFields( |
| |
| groupData, |
| |
| { |
| _id: variables.groupId, |
| productionId: variables.id, |
| productionPrompt: variables.productionPrompt, |
| }, |
| |
| (group) => queryClient.setQueryData([QueryKeys.promptGroup, variables.groupId], group), |
| ); |
| queryClient.setQueryData<t.PromptGroupListData>( |
| [QueryKeys.promptGroups, name, category, pageSize], |
| newData, |
| ); |
| } |
|
|
| if (onMutate) { |
| onMutate(variables); |
| } |
|
|
| return { group, previousListData }; |
| }, |
| onError: (err, variables, context) => { |
| if (context?.group) { |
| queryClient.setQueryData([QueryKeys.promptGroups, variables.groupId], context.group); |
| } |
| if (context?.previousListData) { |
| queryClient.setQueryData<t.PromptGroupListData>( |
| [QueryKeys.promptGroups, name, category, pageSize], |
| context.previousListData, |
| ); |
| } |
| if (onError) { |
| onError(err, variables, context); |
| } |
| }, |
| onSuccess: (response, variables, context) => { |
| updateGroupInAll(queryClient, { |
| _id: variables.groupId, |
| productionId: variables.id, |
| productionPrompt: variables.productionPrompt, |
| }); |
| if (onSuccess) { |
| onSuccess(response, variables, context); |
| } |
| }, |
| }); |
| }; |
|
|