Skip to content

Commit 9e85a02

Browse files
committed
Bugfix: on the setup page, clicking "Complete Configuration" does not check for any unsaved agent changes
1 parent 92ad268 commit 9e85a02

File tree

2 files changed

+72
-5
lines changed

2 files changed

+72
-5
lines changed

frontend/app/[locale]/agents/AgentsContent.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import React, {useState, useEffect, useRef} from "react";
3+
import React, {useState, useEffect, useRef, forwardRef, useImperativeHandle} from "react";
44
import {motion} from "framer-motion";
55

66
import {useSetupFlow} from "@/hooks/useSetupFlow";
@@ -30,14 +30,14 @@ interface AgentsContentProps {
3030
* AgentsContent - Main component for agent configuration
3131
* Can be used in setup flow or as standalone page
3232
*/
33-
export default function AgentsContent({
33+
export default forwardRef<AgentConfigHandle, AgentsContentProps>(function AgentsContent({
3434
isSaving: externalIsSaving,
3535
connectionStatus: externalConnectionStatus,
3636
isCheckingConnection: externalIsCheckingConnection,
3737
onCheckConnection: externalOnCheckConnection,
3838
onConnectionStatusChange,
3939
onSavingStateChange,
40-
}: AgentsContentProps) {
40+
}: AgentsContentProps, ref) {
4141
const agentConfigRef = useRef<AgentConfigHandle | null>(null);
4242
const [showSaveConfirm, setShowSaveConfirm] = useState(false);
4343
const pendingNavRef = useRef<null | (() => void)>(null);
@@ -59,6 +59,21 @@ export default function AgentsContent({
5959
const [internalIsSaving, setInternalIsSaving] = useState(false);
6060
const isSaving = externalIsSaving ?? internalIsSaving;
6161

62+
// Expose AgentConfigHandle methods to parent
63+
useImperativeHandle(ref, () => ({
64+
hasUnsavedChanges: () => agentConfigRef.current?.hasUnsavedChanges?.() ?? false,
65+
saveAllChanges: async () => {
66+
if (agentConfigRef.current?.saveAllChanges) {
67+
await agentConfigRef.current.saveAllChanges();
68+
}
69+
},
70+
reloadCurrentAgentData: async () => {
71+
if (agentConfigRef.current?.reloadCurrentAgentData) {
72+
await agentConfigRef.current.reloadCurrentAgentData();
73+
}
74+
},
75+
}), []);
76+
6277
// Update external saving state
6378
useEffect(() => {
6479
onSavingStateChange?.(isSaving);
@@ -108,5 +123,5 @@ export default function AgentsContent({
108123
/>
109124
</>
110125
);
111-
}
126+
});
112127

frontend/app/[locale]/page.tsx

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import { useState, useEffect } from "react";
3+
import { useState, useEffect, useRef } from "react";
44
import { useTranslation } from "react-i18next";
55
import { NavigationLayout } from "@/components/navigation/NavigationLayout";
66
import { HomepageContent } from "@/components/homepage/HomepageContent";
@@ -18,6 +18,7 @@ import MemoryContent from "./memory/MemoryContent";
1818
import ModelsContent from "./models/ModelsContent";
1919
import AgentsContent from "./agents/AgentsContent";
2020
import KnowledgesContent from "./knowledges/KnowledgesContent";
21+
import SaveConfirmModal from "./agents/components/SaveConfirmModal";
2122
import { SpaceContent } from "./space/components/SpaceContent";
2223
import { fetchAgentList } from "@/services/agentConfigService";
2324
import { useAgentImport, ImportAgentData } from "@/hooks/useAgentImport";
@@ -103,6 +104,11 @@ export default function Home() {
103104
// Setup-specific states
104105
const [currentSetupStep, setCurrentSetupStep] = useState<SetupStep>("models");
105106
const [isSaving, setIsSaving] = useState(false);
107+
108+
// Agent save confirmation states
109+
const [showAgentSaveConfirm, setShowAgentSaveConfirm] = useState(false);
110+
const [pendingCompleteAction, setPendingCompleteAction] = useState<(() => void) | null>(null);
111+
const agentConfigRef = useRef<any>(null);
106112

107113
// Handle operations that require login
108114
const handleAuthRequired = () => {
@@ -284,6 +290,20 @@ export default function Home() {
284290
};
285291

286292
const handleSetupComplete = () => {
293+
// Check if we're on the agents step and if there are unsaved changes
294+
if (currentSetupStep === "agents" && isAdmin && agentConfigRef.current) {
295+
if (agentConfigRef.current.hasUnsavedChanges?.()) {
296+
// Show save confirmation modal
297+
setShowAgentSaveConfirm(true);
298+
setPendingCompleteAction(() => () => {
299+
setCurrentView("chat");
300+
saveView("chat");
301+
});
302+
return;
303+
}
304+
}
305+
306+
// No unsaved changes, proceed directly
287307
setCurrentView("chat");
288308
saveView("chat");
289309
};
@@ -518,6 +538,7 @@ export default function Home() {
518538

519539
{currentSetupStep === "agents" && isAdmin && (
520540
<AgentsContent
541+
ref={agentConfigRef}
521542
isSaving={isSaving}
522543
connectionStatus={connectionStatus}
523544
isCheckingConnection={isCheckingConnection}
@@ -621,6 +642,37 @@ export default function Home() {
621642
<RegisterModal />
622643
</>
623644
)}
645+
646+
{/* Agent save confirmation modal for setup completion */}
647+
<SaveConfirmModal
648+
open={showAgentSaveConfirm}
649+
onCancel={async () => {
650+
// Reload data from backend to discard changes
651+
await agentConfigRef.current?.reloadCurrentAgentData?.();
652+
setShowAgentSaveConfirm(false);
653+
const action = pendingCompleteAction;
654+
setPendingCompleteAction(null);
655+
if (action) action();
656+
}}
657+
onSave={async () => {
658+
try {
659+
setIsSaving(true);
660+
await agentConfigRef.current?.saveAllChanges?.();
661+
setShowAgentSaveConfirm(false);
662+
const action = pendingCompleteAction;
663+
setPendingCompleteAction(null);
664+
if (action) action();
665+
} catch (e) {
666+
// errors are surfaced by underlying save
667+
} finally {
668+
setIsSaving(false);
669+
}
670+
}}
671+
onClose={() => {
672+
setShowAgentSaveConfirm(false);
673+
setPendingCompleteAction(null);
674+
}}
675+
/>
624676
</NavigationLayout>
625677
);
626678
}

0 commit comments

Comments
 (0)