mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-20 18:30:15 +01:00
🏷️ fix: Address Statefulness Issues for Bookmarks (#3590)
* refactor: optimize tag methods, remove rebuild * refactor(tags): add lean db operations, fix updateTagsForConversation, remove rebuild button, only send convoId once * refactor: Update BookmarkMenu to use Constants.NEW_CONVO constant for comparison * style: Update BookmarkMenu styles and constants, use theming * refactor: move tags query from package to client workspace * refactor: optimize ConversationTag document creation and update logic * style: Update BookmarkMenuItems to use theming * refactor: JSDocs + try/catch for conversation tags API routes * refactor: Update BookmarkNav theming classes and new data provider location * fix: statefulness of conversation bookmarks - move non-mutation hook to hooks/Conversation - remove use of deprecated global convo - update convo infinite data as well as current convo state upon successful tag add * refactor: Update BookmarkMenu styles and constants, use theming * refactor: Add lean option to ConversationTag deletion query * fix(BookmarkTable): position order rendering esp. when new tag is created * refactor: Update useBookmarkSucess to useBookmarkSuccess for consistency * refactor: Update ConversationTag creation logic to increment count only if addToConversation is true * style: theming
This commit is contained in:
parent
6ea2628b56
commit
016ed866a3
28 changed files with 622 additions and 536 deletions
|
|
@ -10,6 +10,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|||
import { dataService, MutationKeys, QueryKeys, defaultOrderQuery } from 'librechat-data-provider';
|
||||
import type t from 'librechat-data-provider';
|
||||
import type { InfiniteData, UseMutationResult } from '@tanstack/react-query';
|
||||
import useUpdateTagsInConvo from '~/hooks/Conversations/useUpdateTagsInConvo';
|
||||
import { updateConversationTag } from '~/utils/conversationTags';
|
||||
import { normalizeData } from '~/utils/collection';
|
||||
import store from '~/store';
|
||||
|
|
@ -89,89 +90,6 @@ export const useUpdateConversationMutation = (
|
|||
);
|
||||
};
|
||||
|
||||
const useUpdateTagsInConversation = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
// Update the queryClient cache with the new tag when a new tag is added/removed to a conversation
|
||||
const updateTagsInConversation = (conversationId: string, tags: string[]) => {
|
||||
// Update the tags for the current conversation
|
||||
const currentConvo = queryClient.getQueryData<t.TConversation>([
|
||||
QueryKeys.conversation,
|
||||
conversationId,
|
||||
]);
|
||||
if (!currentConvo) {
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedConvo = {
|
||||
...currentConvo,
|
||||
tags,
|
||||
} as t.TConversation;
|
||||
queryClient.setQueryData([QueryKeys.conversation, conversationId], updatedConvo);
|
||||
queryClient.setQueryData<t.ConversationData>([QueryKeys.allConversations], (convoData) => {
|
||||
if (!convoData) {
|
||||
return convoData;
|
||||
}
|
||||
return updateConvoFields(
|
||||
convoData,
|
||||
{
|
||||
conversationId: currentConvo.conversationId,
|
||||
tags: updatedConvo.tags,
|
||||
} as t.TConversation,
|
||||
true,
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
// update the tag to newTag in all conversations when a tag is updated to a newTag
|
||||
// The difference with updateTagsInConversation is that it adds or removes tags for a specific conversation,
|
||||
// whereas this function is for changing the title of a specific tag.
|
||||
const replaceTagsInAllConversations = (tag: string, newTag: string) => {
|
||||
const data = queryClient.getQueryData<InfiniteData<ConversationListResponse>>([
|
||||
QueryKeys.allConversations,
|
||||
]);
|
||||
|
||||
const conversationIdsWithTag = [] as string[];
|
||||
|
||||
// update tag to newTag in all conversations
|
||||
const newData = JSON.parse(JSON.stringify(data)) as InfiniteData<ConversationListResponse>;
|
||||
for (let pageIndex = 0; pageIndex < newData.pages.length; pageIndex++) {
|
||||
const page = newData.pages[pageIndex];
|
||||
page.conversations = page.conversations.map((conversation) => {
|
||||
if (conversation.conversationId && conversation.tags?.includes(tag)) {
|
||||
conversationIdsWithTag.push(conversation.conversationId);
|
||||
conversation.tags = conversation.tags.map((t) => (t === tag ? newTag : t));
|
||||
}
|
||||
return conversation;
|
||||
});
|
||||
}
|
||||
queryClient.setQueryData<InfiniteData<ConversationListResponse>>(
|
||||
[QueryKeys.allConversations],
|
||||
newData,
|
||||
);
|
||||
|
||||
// update the tag to newTag from the cache of each conversation
|
||||
for (let i = 0; i < conversationIdsWithTag.length; i++) {
|
||||
const conversationId = conversationIdsWithTag[i];
|
||||
const conversation = queryClient.getQueryData<t.TConversation>([
|
||||
QueryKeys.conversation,
|
||||
conversationId,
|
||||
]);
|
||||
if (conversation && conversation.tags) {
|
||||
const updatedConvo = {
|
||||
...conversation,
|
||||
tags: conversation.tags.map((t) => (t === tag ? newTag : t)),
|
||||
} as t.TConversation;
|
||||
queryClient.setQueryData<t.TConversation>(
|
||||
[QueryKeys.conversation, conversationId],
|
||||
updatedConvo,
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return { updateTagsInConversation, replaceTagsInAllConversations };
|
||||
};
|
||||
/**
|
||||
* Add or remove tags for a conversation
|
||||
*/
|
||||
|
|
@ -179,7 +97,7 @@ export const useTagConversationMutation = (
|
|||
conversationId: string,
|
||||
): UseMutationResult<t.TTagConversationResponse, unknown, t.TTagConversationRequest, unknown> => {
|
||||
const query = useConversationTagsQuery();
|
||||
const { updateTagsInConversation } = useUpdateTagsInConversation();
|
||||
const { updateTagsInConversation } = useUpdateTagsInConvo();
|
||||
return useMutation(
|
||||
(payload: t.TTagConversationRequest) =>
|
||||
dataService.addTagToConversation(conversationId, payload),
|
||||
|
|
@ -385,21 +303,6 @@ export const useDeleteSharedLinkMutation = (
|
|||
});
|
||||
};
|
||||
|
||||
// If the number of conversations tagged is incorrect, recalculate the tag information.
|
||||
export const useRebuildConversationTagsMutation = (): UseMutationResult<
|
||||
t.TConversationTagsResponse,
|
||||
unknown,
|
||||
unknown,
|
||||
unknown
|
||||
> => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation(() => dataService.rebuildConversationTags(), {
|
||||
onSuccess: (_data) => {
|
||||
queryClient.setQueryData<t.TConversationTag[]>([QueryKeys.conversationTags], _data);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// Add a tag or update tag information (tag, description, position, etc.)
|
||||
export const useConversationTagMutation = (
|
||||
tag?: string,
|
||||
|
|
@ -407,7 +310,7 @@ export const useConversationTagMutation = (
|
|||
): UseMutationResult<t.TConversationTagResponse, unknown, t.TConversationTagRequest, unknown> => {
|
||||
const queryClient = useQueryClient();
|
||||
const { ..._options } = options || {};
|
||||
const { updateTagsInConversation, replaceTagsInAllConversations } = useUpdateTagsInConversation();
|
||||
const { updateTagsInConversation, replaceTagsInAllConversations } = useUpdateTagsInConvo();
|
||||
return useMutation(
|
||||
(payload: t.TConversationTagRequest) =>
|
||||
tag
|
||||
|
|
@ -427,6 +330,9 @@ export const useConversationTagMutation = (
|
|||
},
|
||||
] as t.TConversationTag[];
|
||||
}
|
||||
if (!tag) {
|
||||
return [...data, _data].sort((a, b) => a.position - b.position);
|
||||
}
|
||||
return updateConversationTag(data, vars, _data, tag);
|
||||
});
|
||||
if (vars.addToConversation && vars.conversationId && _data.tag) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue