Compare commits

...
Sign in to create a new pull request.

2 commits

Author SHA1 Message Date
Brent O'Neill
8b971ac90b cleanup 2025-10-06 15:48:06 -06:00
Brent O'Neill
6f4d7d0e5a fix connectors on settings page 2025-10-06 15:42:20 -06:00

View file

@ -1,6 +1,6 @@
"use client"; "use client";
import { ArrowUpRight, Loader2, Minus, Plus } from "lucide-react"; import { ArrowUpRight, Loader2, Minus, PlugZap, Plus } from "lucide-react";
import Link from "next/link"; import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation"; import { useRouter, useSearchParams } from "next/navigation";
import { Suspense, useCallback, useEffect, useState } from "react"; import { Suspense, useCallback, useEffect, useState } from "react";
@ -76,12 +76,13 @@ interface OneDriveFile {
} }
interface Connector { interface Connector {
available?: boolean;
id: string; id: string;
name: string; name: string;
description: string; description: string;
icon: React.ReactNode; icon: React.ReactNode;
status: "not_connected" | "connecting" | "connected" | "error"; status?: "not_connected" | "connecting" | "connected" | "error";
type: string; type?: string;
connectionId?: string; connectionId?: string;
access_token?: string; access_token?: string;
selectedFiles?: GoogleDriveFile[] | OneDriveFile[]; selectedFiles?: GoogleDriveFile[] | OneDriveFile[];
@ -102,33 +103,6 @@ interface Connection {
last_sync?: string; last_sync?: string;
} }
const DEFAULT_CONNECTORS: Connector[] = [
{
id: "google_drive",
name: "Google Drive",
description: "Google Drive is not configured.",
icon: <GoogleDriveIcon />,
status: "not_connected",
type: "google_drive",
},
{
id: "one_drive",
name: "OneDrive",
description: "OneDrive is not configured.",
icon: <OneDriveIcon />,
status: "not_connected",
type: "one_drive",
},
{
id: "amazon_s3",
name: "SharePoint",
description: "SharePoint is not configured.",
icon: <SharePointIcon />,
status: "not_connected",
type: "sharepoint",
},
];
function KnowledgeSourcesPage() { function KnowledgeSourcesPage() {
const { isAuthenticated, isNoAuthMode } = useAuth(); const { isAuthenticated, isNoAuthMode } = useAuth();
const { addTask, tasks } = useTask(); const { addTask, tasks } = useTask();
@ -169,7 +143,7 @@ function KnowledgeSourcesPage() {
{ {
enabled: enabled:
(isAuthenticated || isNoAuthMode) && currentProvider === "openai", (isAuthenticated || isNoAuthMode) && currentProvider === "openai",
}, }
); );
const { data: ollamaModelsData } = useGetOllamaModelsQuery( const { data: ollamaModelsData } = useGetOllamaModelsQuery(
@ -177,7 +151,7 @@ function KnowledgeSourcesPage() {
{ {
enabled: enabled:
(isAuthenticated || isNoAuthMode) && currentProvider === "ollama", (isAuthenticated || isNoAuthMode) && currentProvider === "ollama",
}, }
); );
const { data: ibmModelsData } = useGetIBMModelsQuery( const { data: ibmModelsData } = useGetIBMModelsQuery(
@ -185,7 +159,7 @@ function KnowledgeSourcesPage() {
{ {
enabled: enabled:
(isAuthenticated || isNoAuthMode) && currentProvider === "watsonx", (isAuthenticated || isNoAuthMode) && currentProvider === "watsonx",
}, }
); );
// Select the appropriate models data based on provider // Select the appropriate models data based on provider
@ -213,7 +187,7 @@ function KnowledgeSourcesPage() {
(variables: Parameters<typeof updateFlowSettingMutation.mutate>[0]) => { (variables: Parameters<typeof updateFlowSettingMutation.mutate>[0]) => {
updateFlowSettingMutation.mutate(variables); updateFlowSettingMutation.mutate(variables);
}, },
500, 500
); );
// Sync system prompt state with settings data // Sync system prompt state with settings data
@ -306,7 +280,7 @@ function KnowledgeSourcesPage() {
"google-drive": <GoogleDriveIcon />, "google-drive": <GoogleDriveIcon />,
sharepoint: ( sharepoint: (
<div className="w-8 h-8 bg-blue-700 rounded flex items-center justify-center text-white font-bold leading-none shrink-0"> <div className="w-8 h-8 bg-blue-700 rounded flex items-center justify-center text-white font-bold leading-none shrink-0">
SP <SharePointIcon />
</div> </div>
), ),
onedrive: ( onedrive: (
@ -346,6 +320,7 @@ function KnowledgeSourcesPage() {
icon: getConnectorIcon(connectorsResult.connectors[type].icon), icon: getConnectorIcon(connectorsResult.connectors[type].icon),
status: "not_connected" as const, status: "not_connected" as const,
type: type, type: type,
available: connectorsResult.connectors[type].available,
})); }));
setConnectors(initialConnectors); setConnectors(initialConnectors);
@ -358,7 +333,7 @@ function KnowledgeSourcesPage() {
const data = await response.json(); const data = await response.json();
const connections = data.connections || []; const connections = data.connections || [];
const activeConnection = connections.find( const activeConnection = connections.find(
(conn: Connection) => conn.is_active, (conn: Connection) => conn.is_active
); );
const isConnected = activeConnection !== undefined; const isConnected = activeConnection !== undefined;
@ -370,8 +345,8 @@ function KnowledgeSourcesPage() {
status: isConnected ? "connected" : "not_connected", status: isConnected ? "connected" : "not_connected",
connectionId: activeConnection?.connection_id, connectionId: activeConnection?.connection_id,
} }
: c, : c
), )
); );
} }
} }
@ -414,7 +389,7 @@ function KnowledgeSourcesPage() {
`response_type=code&` + `response_type=code&` +
`scope=${result.oauth_config.scopes.join(" ")}&` + `scope=${result.oauth_config.scopes.join(" ")}&` +
`redirect_uri=${encodeURIComponent( `redirect_uri=${encodeURIComponent(
result.oauth_config.redirect_uri, result.oauth_config.redirect_uri
)}&` + )}&` +
`access_type=offline&` + `access_type=offline&` +
`prompt=consent&` + `prompt=consent&` +
@ -547,7 +522,7 @@ function KnowledgeSourcesPage() {
const handleEditInLangflow = ( const handleEditInLangflow = (
flowType: "chat" | "ingest", flowType: "chat" | "ingest",
closeDialog: () => void, closeDialog: () => void
) => { ) => {
// Select the appropriate flow ID and edit URL based on flow type // Select the appropriate flow ID and edit URL based on flow type
const targetFlowId = const targetFlowId =
@ -714,10 +689,7 @@ function KnowledgeSourcesPage() {
{/* Connectors Grid */} {/* Connectors Grid */}
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3"> <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
{DEFAULT_CONNECTORS.map((connector) => { {connectors.map((connector) => {
const actualConnector = connectors.find(
(c) => c.id === connector.id,
);
return ( return (
<Card key={connector.id} className="relative flex flex-col"> <Card key={connector.id} className="relative flex flex-col">
<CardHeader> <CardHeader>
@ -726,7 +698,7 @@ function KnowledgeSourcesPage() {
<div className="mb-1"> <div className="mb-1">
<div <div
className={`w-8 h-8 ${ className={`w-8 h-8 ${
actualConnector ? "bg-white" : "bg-muted grayscale" connector ? "bg-white" : "bg-muted grayscale"
} rounded flex items-center justify-center`} } rounded flex items-center justify-center`}
> >
{connector.icon} {connector.icon}
@ -734,20 +706,21 @@ function KnowledgeSourcesPage() {
</div> </div>
<CardTitle className="flex flex-row items-center gap-2"> <CardTitle className="flex flex-row items-center gap-2">
{connector.name} {connector.name}
{actualConnector && {connector && getStatusBadge(connector.status)}
getStatusBadge(actualConnector.status)}
</CardTitle> </CardTitle>
<CardDescription className="text-[13px]"> <CardDescription className="text-[13px]">
{actualConnector?.description {connector?.description
? `${actualConnector.name} is configured.` ? `${connector.name} is configured.`
: connector.description} : connector.description}
</CardDescription> </CardDescription>
</div> </div>
</div> </div>
</CardHeader> </CardHeader>
<CardContent className="flex-1 flex flex-col justify-end space-y-4"> <CardContent className="flex-1 flex flex-col justify-end space-y-4">
{actualConnector?.status === "connected" ? ( {connector?.available ? (
<div className="space-y-3"> <div className="space-y-3">
{connector?.status === "connected" ? (
<>
<Button <Button
onClick={() => navigateToKnowledgePage(connector)} onClick={() => navigateToKnowledgePage(connector)}
disabled={isSyncing === connector.id} disabled={isSyncing === connector.id}
@ -757,7 +730,6 @@ function KnowledgeSourcesPage() {
<Plus className="h-4 w-4" /> <Plus className="h-4 w-4" />
Add Knowledge Add Knowledge
</Button> </Button>
{syncResults[connector.id] && ( {syncResults[connector.id] && (
<div className="text-xs text-muted-foreground bg-muted/50 p-2 rounded"> <div className="text-xs text-muted-foreground bg-muted/50 p-2 rounded">
<div> <div>
@ -774,6 +746,27 @@ function KnowledgeSourcesPage() {
)} )}
</div> </div>
)} )}
</>
) : (
<Button
onClick={() => handleConnect(connector)}
disabled={isConnecting === connector.id}
className="w-full cursor-pointer"
size="sm"
>
{isConnecting === connector.id ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Connecting...
</>
) : (
<>
<PlugZap className="mr-2 h-4 w-4" />
Connect
</>
)}
</Button>
)}
</div> </div>
) : ( ) : (
<div className="text-[13px] text-muted-foreground"> <div className="text-[13px] text-muted-foreground">
@ -879,7 +872,11 @@ function KnowledgeSourcesPage() {
> >
<ModelSelector <ModelSelector
options={modelsData?.language_models || []} options={modelsData?.language_models || []}
noOptionsPlaceholder={modelsData ? "No language models detected." : "Loading models..."} noOptionsPlaceholder={
modelsData
? "No language models detected."
: "Loading models..."
}
icon={<OpenAILogo className="w-4 h-4" />} icon={<OpenAILogo className="w-4 h-4" />}
value={modelsData ? settings.agent?.llm_model || "" : ""} value={modelsData ? settings.agent?.llm_model || "" : ""}
onValueChange={handleModelChange} onValueChange={handleModelChange}
@ -1121,7 +1118,7 @@ function KnowledgeSourcesPage() {
size="iconSm" size="iconSm"
onClick={() => onClick={() =>
handleChunkOverlapChange( handleChunkOverlapChange(
(chunkOverlap + 1).toString(), (chunkOverlap + 1).toString()
) )
} }
> >
@ -1134,7 +1131,7 @@ function KnowledgeSourcesPage() {
size="iconSm" size="iconSm"
onClick={() => onClick={() =>
handleChunkOverlapChange( handleChunkOverlapChange(
(chunkOverlap - 1).toString(), (chunkOverlap - 1).toString()
) )
} }
> >