diff --git a/frontend/src/app/settings/page.tsx b/frontend/src/app/settings/page.tsx index e7250394..a0793d4c 100644 --- a/frontend/src/app/settings/page.tsx +++ b/frontend/src/app/settings/page.tsx @@ -52,11 +52,11 @@ interface Connector { } interface SyncResult { - processed?: number; - added?: number; - errors?: number; - skipped?: number; - total?: number; + processed?: number; + added?: number; + errors?: number; + skipped?: number; + total?: number; } interface Connection { @@ -66,6 +66,34 @@ interface Connection { last_sync?: string; } +// Helper function to get connector icon (moved outside component to avoid re-renders) +const getConnectorIcon = (iconName: string) => { + const iconMap: { [key: string]: React.ReactElement } = { + "google-drive": ( +
+ G +
+ ), + sharepoint: ( +
+ SP +
+ ), + onedrive: ( +
+ OD +
+ ), + }; + return ( + iconMap[iconName] || ( +
+ ? +
+ ) + ); +}; + function KnowledgeSourcesPage() { const { isAuthenticated, isNoAuthMode } = useAuth(); const { addTask, tasks } = useTask(); @@ -89,11 +117,16 @@ function KnowledgeSourcesPage() { const [ingestFlowId, setIngestFlowId] = useState( "5488df7c-b93f-4f87-a446-b67028bc0813", ); + const [nudgesFlowId, setNudgesFlowId] = useState( + "ebc01d31-1976-46ce-a385-b0240327226c", + ); const [langflowEditUrl, setLangflowEditUrl] = useState(""); - const [langflowIngestEditUrl, setLangflowIngestEditUrl] = useState(""); + const [langflowIngestEditUrl, setLangflowIngestEditUrl] = + useState(""); + const [langflowNudgesEditUrl, setLangflowNudgesEditUrl] = + useState(""); const [publicLangflowUrl, setPublicLangflowUrl] = useState(""); - // Fetch settings from backend const fetchSettings = useCallback(async () => { try { @@ -106,12 +139,18 @@ function KnowledgeSourcesPage() { if (settings.ingest_flow_id) { setIngestFlowId(settings.ingest_flow_id); } + if (settings.langflow_nudges_flow_id) { + setNudgesFlowId(settings.langflow_nudges_flow_id); + } if (settings.langflow_edit_url) { setLangflowEditUrl(settings.langflow_edit_url); } if (settings.langflow_ingest_edit_url) { setLangflowIngestEditUrl(settings.langflow_ingest_edit_url); } + if (settings.langflow_nudges_edit_url) { + setLangflowNudgesEditUrl(settings.langflow_nudges_edit_url); + } if (settings.langflow_public_url) { setPublicLangflowUrl(settings.langflow_public_url); } @@ -121,34 +160,6 @@ function KnowledgeSourcesPage() { } }, []); - // Helper function to get connector icon - const getConnectorIcon = (iconName: string) => { - const iconMap: { [key: string]: React.ReactElement } = { - "google-drive": ( -
- G -
- ), - sharepoint: ( -
- SP -
- ), - onedrive: ( -
- OD -
- ), - }; - return ( - iconMap[iconName] || ( -
- ? -
- ) - ); - }; - // Connector functions const checkConnectorStatuses = useCallback(async () => { try { @@ -393,11 +404,25 @@ function KnowledgeSourcesPage() { } }, [tasks, prevTasks]); - const handleEditInLangflow = (flowType: "chat" | "ingest", closeDialog: () => void) => { + const handleEditInLangflow = ( + flowType: "chat" | "ingest" | "nudges", + closeDialog: () => void, + ) => { // Select the appropriate flow ID and edit URL based on flow type - const targetFlowId = flowType === "ingest" ? ingestFlowId : chatFlowId; - const editUrl = flowType === "ingest" ? langflowIngestEditUrl : langflowEditUrl; - + let targetFlowId: string; + let editUrl: string; + + if (flowType === "ingest") { + targetFlowId = ingestFlowId; + editUrl = langflowIngestEditUrl; + } else if (flowType === "nudges") { + targetFlowId = nudgesFlowId; + editUrl = langflowNudgesEditUrl; + } else { + targetFlowId = chatFlowId; + editUrl = langflowEditUrl; + } + const derivedFromWindow = typeof window !== "undefined" ? `${window.location.protocol}//${window.location.hostname}:7860` @@ -408,9 +433,9 @@ function KnowledgeSourcesPage() { "http://localhost:7860" ).replace(/\/$/, ""); const computed = targetFlowId ? `${base}/flow/${targetFlowId}` : base; - + const url = editUrl || computed; - + window.open(url, "_blank"); closeDialog(); // Close immediately after opening Langflow }; @@ -443,6 +468,20 @@ function KnowledgeSourcesPage() { }); }; + const handleRestoreNudgesFlow = (closeDialog: () => void) => { + fetch(`/api/reset-flow/nudges`, { + method: "POST", + }) + .then((response) => response.json()) + .then(() => { + closeDialog(); // Close after successful completion + }) + .catch((error) => { + console.error("Error restoring nudges flow:", error); + closeDialog(); // Close even on error (could show error toast instead) + }); + }; + return (
{/* Knowledge Ingest Section */} @@ -473,7 +512,9 @@ function KnowledgeSourcesPage() { height="22" viewBox="0 0 24 22" className="h-4 w-4 mr-2" + aria-label="Edit in Langflow" > + Edit in Langflow handleEditInLangflow("ingest", closeDialog)} + onConfirm={(closeDialog) => + handleEditInLangflow("ingest", closeDialog) + } />
@@ -569,7 +612,9 @@ function KnowledgeSourcesPage() { height="22" viewBox="0 0 24 22" className="h-4 w-4 mr-2" + aria-label="Edit in Langflow" > + Edit in Langflow handleEditInLangflow("chat", closeDialog)} + onConfirm={(closeDialog) => + handleEditInLangflow("chat", closeDialog) + } + /> + + + + + + {/* Nudges Section */} + + +
+
+ Nudges + + Manage prompt suggestions that appear in the chat interface + +
+
+ Restore flow} + title="Restore default Nudges flow" + description="This restores defaults and discards all custom settings and overrides. This can't be undone." + confirmText="Restore" + variant="destructive" + onConfirm={handleRestoreNudgesFlow} + /> + + + Edit in Langflow + + + + + Edit in Langflow + + } + title="Edit Nudges flow in Langflow" + description="You're entering Langflow. You can edit the Nudges flow and other underlying flows. Manual changes to components, wiring, or I/O can break this experience." + confirmText="Proceed" + onConfirm={(closeDialog) => + handleEditInLangflow("nudges", closeDialog) + } />