Skip to content

Commit b7852fe

Browse files
committed
fix(frontend): resolve session rename bugs and prevent message loss
1 parent b7e834b commit b7852fe

7 files changed

Lines changed: 85 additions & 15 deletions

File tree

src/frontend/src/components/core/playgroundComponent/chat-view/chat-header/components/chat-header.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export function ChatHeader({
119119
onMessageLogs={onMessageLogs}
120120
onClearChat={handleClearChat}
121121
onDelete={handleDeleteSessionInternal}
122+
showRename={!isDefaultSession}
122123
showClearChat={isDefaultSession}
123124
showDelete={!isDefaultSession}
124125
side="bottom"

src/frontend/src/components/core/playgroundComponent/chat-view/chat-header/components/session-more-menu.tsx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface SessionMoreMenuProps {
1515
onDelete: () => void;
1616
onClearChat?: () => void;
1717
showMessageLogs?: boolean;
18+
showRename?: boolean;
1819
showDelete?: boolean;
1920
showClearChat?: boolean;
2021
// Positioning props
@@ -36,6 +37,7 @@ export function SessionMoreMenu({
3637
onDelete,
3738
onClearChat,
3839
showMessageLogs = true,
40+
showRename = true,
3941
showDelete = true,
4042
showClearChat = false,
4143
side = "bottom",
@@ -102,15 +104,17 @@ export function SessionMoreMenu({
102104
sideOffset={sideOffset}
103105
className={cn("p-0", contentClassName)}
104106
>
105-
<SelectItem value="rename" className="session-more-menu-item">
106-
<div className="flex items-center">
107-
<ForwardedIconComponent
108-
name="SquarePen"
109-
className="mr-2 h-4 w-4"
110-
/>
111-
Rename
112-
</div>
113-
</SelectItem>
107+
{showRename && (
108+
<SelectItem value="rename" className="session-more-menu-item">
109+
<div className="flex items-center">
110+
<ForwardedIconComponent
111+
name="SquarePen"
112+
className="mr-2 h-4 w-4"
113+
/>
114+
Rename
115+
</div>
116+
</SelectItem>
117+
)}
114118
{showMessageLogs && (
115119
<SelectItem value="messageLogs" className="session-more-menu-item">
116120
<div className="flex items-center">

src/frontend/src/components/core/playgroundComponent/chat-view/chat-header/components/session-selector.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ export function SessionSelector({
111111
onRename={handleEditClick}
112112
onMessageLogs={() => inspectSession?.(session)}
113113
onDelete={() => deleteSession(session)}
114+
showRename={session !== currentFlowId}
114115
showDelete={session !== currentFlowId}
115116
side="bottom"
116117
align="end"

src/frontend/src/components/core/playgroundComponent/chat-view/chat-header/hooks/use-edit-session-info.ts

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { useGetSessionsFromFlowQuery } from "@/controllers/API/queries/messages/
33
import { useUpdateSessionName } from "@/controllers/API/queries/messages/use-rename-session";
44
import { usePlaygroundStore } from "@/stores/playgroundStore";
55

6+
const LOCAL_SESSIONS_STORAGE_KEY = (flowId: string) =>
7+
`langflow_local_sessions_${flowId}`;
8+
69
export const useEditSessionInfo = ({
710
flowId,
811
dbSessions: providedDbSessions,
@@ -41,12 +44,35 @@ export const useEditSessionInfo = ({
4144
};
4245

4346
const handleRename = async (sessionId: string, newSessionId: string) => {
44-
if (dbSessions.includes(sessionId)) {
45-
await updateSessionName({
46-
old_session_id: sessionId,
47-
new_session_id: newSessionId,
48-
});
47+
// Update session name via API or sessionStorage
48+
await updateSessionName({
49+
old_session_id: sessionId,
50+
new_session_id: newSessionId,
51+
});
52+
53+
// Update local sessions list if this is a local session
54+
if (flowId && isPlayground) {
55+
try {
56+
const stored = window.sessionStorage.getItem(
57+
LOCAL_SESSIONS_STORAGE_KEY(flowId),
58+
);
59+
if (stored) {
60+
const localSessions = JSON.parse(stored) as string[];
61+
const index = localSessions.indexOf(sessionId);
62+
if (index !== -1) {
63+
localSessions[index] = newSessionId;
64+
window.sessionStorage.setItem(
65+
LOCAL_SESSIONS_STORAGE_KEY(flowId),
66+
JSON.stringify(localSessions),
67+
);
68+
}
69+
}
70+
} catch (error) {
71+
console.error("Error updating local sessions:", error);
72+
}
4973
}
74+
75+
// Update selected session if the renamed session is currently selected
5076
if (flowId && sessionId === selectedSession) {
5177
setSelectedSession(newSessionId);
5278
}

src/frontend/src/controllers/API/queries/messages/use-rename-session.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { UseMutationResult } from "@tanstack/react-query";
22
import { useGetFlowId } from "@/modals/IOModal/hooks/useGetFlowId";
33
import useFlowStore from "@/stores/flowStore";
4+
import { useMessagesStore } from "@/stores/messagesStore";
45
import type { useMutationFunctionType } from "@/types/api";
56
import type { Message } from "@/types/messages";
67
import { api } from "../../api";
@@ -24,14 +25,40 @@ export const useUpdateSessionName: useMutationFunctionType<
2425
const isPlayground = useFlowStore.getState().playgroundPage;
2526
// if we are in playground we will edit the local storage instead of the API
2627
if (isPlayground && flowId) {
27-
const messages = JSON.parse(sessionStorage.getItem(flowId) || "");
28+
const messages = JSON.parse(sessionStorage.getItem(flowId) || "[]");
2829
const messagesWithNewSessionId = messages.map((message: Message) => {
2930
if (message.session_id === data.old_session_id) {
3031
message.session_id = data.new_session_id;
3132
}
3233
return message;
3334
});
3435
sessionStorage.setItem(flowId, JSON.stringify(messagesWithNewSessionId));
36+
37+
// Update the messages store to reflect the new session_id
38+
useMessagesStore.getState().renameSession(data.old_session_id, data.new_session_id);
39+
40+
// Update React Query cache - move messages from old session key to new session key
41+
const oldCacheKey = [
42+
"useGetMessagesQuery",
43+
{ id: flowId, session_id: data.old_session_id },
44+
];
45+
const newCacheKey = [
46+
"useGetMessagesQuery",
47+
{ id: flowId, session_id: data.new_session_id },
48+
];
49+
50+
const oldMessages = queryClient.getQueryData<Message[]>(oldCacheKey);
51+
if (oldMessages) {
52+
// Update session_id in cached messages and move to new cache key
53+
const updatedMessages = oldMessages.map((msg) => ({
54+
...msg,
55+
session_id: data.new_session_id,
56+
}));
57+
queryClient.setQueryData(newCacheKey, updatedMessages);
58+
// Remove old cache entry
59+
queryClient.removeQueries({ queryKey: oldCacheKey });
60+
}
61+
3562
return {
3663
data: messagesWithNewSessionId,
3764
};

src/frontend/src/stores/messagesStore.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ export const useMessagesStore = create<MessagesStoreType>((set, get) => ({
1111
return { messages: updatedMessages };
1212
});
1313
},
14+
renameSession: (oldSessionId, newSessionId) => {
15+
set((state) => {
16+
const updatedMessages = state.messages.map((msg) =>
17+
msg.session_id === oldSessionId
18+
? { ...msg, session_id: newSessionId }
19+
: msg,
20+
);
21+
return { messages: updatedMessages };
22+
});
23+
},
1424
messages: [],
1525
setMessages: (messages) => {
1626
set(() => ({ messages: messages }));

src/frontend/src/types/zustand/messages/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ export type MessagesStoreType = {
1111
clearMessages: () => void;
1212
removeMessages: (ids: string[]) => void;
1313
deleteSession: (id: string) => void;
14+
renameSession: (oldSessionId: string, newSessionId: string) => void;
1415
displayLoadingMessage: boolean;
1516
};

0 commit comments

Comments
 (0)