style: format web codebase

This commit is contained in:
CREDO23 2026-01-07 15:20:36 +02:00
parent 4de28152d5
commit b664547178
11 changed files with 311 additions and 316 deletions

View file

@ -316,19 +316,19 @@ export const ConnectorIndicator: FC = () => {
/>
</TabsContent>
<ActiveConnectorsTab
searchQuery={searchQuery}
hasSources={hasSources}
totalSourceCount={totalSourceCount}
activeDocumentTypes={activeDocumentTypes}
connectors={connectors as SearchSourceConnector[]}
indexingConnectorIds={indexingConnectorIds}
logsSummary={logsSummary}
searchSpaceId={searchSpaceId}
onTabChange={handleTabChange}
onManage={handleStartEdit}
onViewAccountsList={handleViewAccountsList}
/>
<ActiveConnectorsTab
searchQuery={searchQuery}
hasSources={hasSources}
totalSourceCount={totalSourceCount}
activeDocumentTypes={activeDocumentTypes}
connectors={connectors as SearchSourceConnector[]}
indexingConnectorIds={indexingConnectorIds}
logsSummary={logsSummary}
searchSpaceId={searchSpaceId}
onTabChange={handleTabChange}
onManage={handleStartEdit}
onViewAccountsList={handleViewAccountsList}
/>
</div>
</div>
{/* Bottom fade shadow */}

View file

@ -161,7 +161,9 @@ export const ConnectorCard: FC<ConnectorCardProps> = ({
{accountCount !== undefined && accountCount > 0 && (
<>
<span className="text-muted-foreground/50"></span>
<span>{accountCount} {accountCount === 1 ? "Account" : "Accounts"}</span>
<span>
{accountCount} {accountCount === 1 ? "Account" : "Accounts"}
</span>
</>
)}
</p>

View file

@ -148,7 +148,9 @@ export const ConnectorEditView: FC<ConnectorEditViewProps> = ({
{getConnectorIcon(connector.connector_type, "size-7")}
</div>
<div className="flex-1 min-w-0">
<h2 className="text-xl sm:text-2xl font-semibold tracking-tight text-wrap whitespace-normal wrap-break-word">{connector.name}</h2>
<h2 className="text-xl sm:text-2xl font-semibold tracking-tight text-wrap whitespace-normal wrap-break-word">
{connector.name}
</h2>
<p className="text-xs sm:text-base text-muted-foreground mt-1">
Manage your connector settings and sync configuration
</p>

View file

@ -1,17 +1,17 @@
"use client";
import { ArrowLeft, Check, Info, Loader2 } from "lucide-react";
import { type FC, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useSearchParams } from "next/navigation";
import { type FC, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Button } from "@/components/ui/button";
import type { SearchSourceConnector } from "@/contracts/types/connector.types";
import { getConnectorTypeDisplay } from "@/lib/connectors/utils";
import { cn } from "@/lib/utils";
import { DateRangeSelector } from "../../components/date-range-selector";
import { PeriodicSyncConfig } from "../../components/periodic-sync-config";
import { OAUTH_CONNECTORS, type IndexingConfigState } from "../../constants/connector-constants";
import { getConnectorConfigComponent } from "../index";
import { getConnectorTypeDisplay } from "@/lib/connectors/utils";
import { type IndexingConfigState, OAUTH_CONNECTORS } from "../../constants/connector-constants";
import { getConnectorDisplayName } from "../../tabs/all-connectors-tab";
import { getConnectorConfigComponent } from "../index";
interface IndexingConfigurationViewProps {
config: IndexingConfigState;
@ -121,7 +121,12 @@ export const IndexingConfigurationView: FC<IndexingConfigurationViewProps> = ({
</div>
<div>
<div className="flex flex-col">
<span className="text-xl sm:text-2xl font-semibold tracking-tight text-wrap whitespace-normal wrap-break-word">{getConnectorTypeDisplay(connector?.connector_type || "")} Connected !</span> <span className="text-xl sm:text-xl font-semibold text-muted-foreground tracking-tight text-wrap whitespace-normal wrap-break-word">{getConnectorDisplayName(connector?.name || "")}</span>
<span className="text-xl sm:text-2xl font-semibold tracking-tight text-wrap whitespace-normal wrap-break-word">
{getConnectorTypeDisplay(connector?.connector_type || "")} Connected !
</span>{" "}
<span className="text-xl sm:text-xl font-semibold text-muted-foreground tracking-tight text-wrap whitespace-normal wrap-break-word">
{getConnectorDisplayName(connector?.name || "")}
</span>
</div>
<p className="text-xs sm:text-base text-muted-foreground mt-1">
Configure when to start syncing your data

View file

@ -243,7 +243,14 @@ export const useConnectorDialog = () => {
console.warn("Invalid connector popup query params:", error);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [searchParams, allConnectors, editingConnector, indexingConfig, connectingConnectorType, viewingAccountsType]);
}, [
searchParams,
allConnectors,
editingConnector,
indexingConfig,
connectingConnectorType,
viewingAccountsType,
]);
// Detect OAuth success / Failure and transition to config view
useEffect(() => {
@ -292,9 +299,7 @@ export const useConnectorDialog = () => {
let newConnector: SearchSourceConnector | undefined;
if (params.connectorId) {
const connectorId = parseInt(params.connectorId, 10);
newConnector = result.data.find(
(c: SearchSourceConnector) => c.id === connectorId
);
newConnector = result.data.find((c: SearchSourceConnector) => c.id === connectorId);
} else {
newConnector = result.data.find(
(c: SearchSourceConnector) => c.connector_type === oauthConnector.connectorType
@ -737,7 +742,6 @@ export const useConnectorDialog = () => {
router.replace(url.pathname + url.search, { scroll: false });
}, [router]);
// Handle starting indexing
const handleStartIndexing = useCallback(
async (refreshConnectors: () => void) => {

View file

@ -83,7 +83,9 @@ export const ActiveConnectorsTab: FC<ActiveConnectorsTabProps> = ({
};
// Get most recent last indexed date from a list of connectors
const getMostRecentLastIndexed = (connectorsList: SearchSourceConnector[]): string | undefined => {
const getMostRecentLastIndexed = (
connectorsList: SearchSourceConnector[]
): string | undefined => {
return connectorsList.reduce<string | undefined>((latest, c) => {
if (!c.last_indexed_at) return latest;
if (!latest) return c.last_indexed_at;
@ -131,20 +133,27 @@ export const ActiveConnectorsTab: FC<ActiveConnectorsTabProps> = ({
const getOAuthConnectorTypeInfo = (connectorType: string) => {
const oauthConnector = OAUTH_CONNECTORS.find((c) => c.connectorType === connectorType);
return {
title: oauthConnector?.title || connectorType.replace(/_/g, " ").replace(/connector/gi, "").trim(),
title:
oauthConnector?.title ||
connectorType
.replace(/_/g, " ")
.replace(/connector/gi, "")
.trim(),
};
};
// Filter OAuth connector types based on search query
const filteredOAuthConnectorTypes = Object.entries(oauthConnectorsByType).filter(([connectorType]) => {
if (!searchQuery) return true;
const searchLower = searchQuery.toLowerCase();
const { title } = getOAuthConnectorTypeInfo(connectorType);
return (
title.toLowerCase().includes(searchLower) ||
connectorType.toLowerCase().includes(searchLower)
);
});
const filteredOAuthConnectorTypes = Object.entries(oauthConnectorsByType).filter(
([connectorType]) => {
if (!searchQuery) return true;
const searchLower = searchQuery.toLowerCase();
const { title } = getOAuthConnectorTypeInfo(connectorType);
return (
title.toLowerCase().includes(searchLower) ||
connectorType.toLowerCase().includes(searchLower)
);
}
);
// Filter non-OAuth connectors based on search query
const filteredNonOAuthConnectors = nonOauthConnectors.filter((connector) => {
@ -156,7 +165,8 @@ export const ActiveConnectorsTab: FC<ActiveConnectorsTabProps> = ({
);
});
const hasActiveConnectors = filteredOAuthConnectorTypes.length > 0 || filteredNonOAuthConnectors.length > 0;
const hasActiveConnectors =
filteredOAuthConnectorTypes.length > 0 || filteredNonOAuthConnectors.length > 0;
return (
<TabsContent value="active" className="m-0">
@ -172,8 +182,8 @@ export const ActiveConnectorsTab: FC<ActiveConnectorsTabProps> = ({
{/* OAuth Connectors - Grouped by Type */}
{filteredOAuthConnectorTypes.map(([connectorType, typeConnectors]) => {
const { title } = getOAuthConnectorTypeInfo(connectorType);
const isAnyIndexing = typeConnectors.some(
(c: SearchSourceConnector) => indexingConnectorIds.has(c.id)
const isAnyIndexing = typeConnectors.some((c: SearchSourceConnector) =>
indexingConnectorIds.has(c.id)
);
const documentCount = getDocumentCountForConnector(
connectorType,
@ -211,9 +221,7 @@ export const ActiveConnectorsTab: FC<ActiveConnectorsTabProps> = ({
{getConnectorIcon(connectorType, "size-6")}
</div>
<div className="flex-1 min-w-0">
<p className="text-[14px] font-semibold leading-tight truncate">
{title}
</p>
<p className="text-[14px] font-semibold leading-tight truncate">{title}</p>
{isAnyIndexing ? (
<p className="text-[11px] text-primary mt-1 flex items-center gap-1.5">
<Loader2 className="size-3 animate-spin" />
@ -229,7 +237,9 @@ export const ActiveConnectorsTab: FC<ActiveConnectorsTabProps> = ({
<p className="text-[10px] text-muted-foreground mt-0.5 flex items-center gap-1.5">
<span>{formatDocumentCount(documentCount)}</span>
<span className="text-muted-foreground/50"></span>
<span>{accountCount} {accountCount === 1 ? "Account" : "Accounts"}</span>
<span>
{accountCount} {accountCount === 1 ? "Account" : "Accounts"}
</span>
</p>
</div>
<Button

View file

@ -6,11 +6,7 @@ import { Button } from "@/components/ui/button";
import type { SearchSourceConnector } from "@/contracts/types/connector.types";
import type { LogActiveTask, LogSummary } from "@/contracts/types/log.types";
import { ConnectorCard } from "../components/connector-card";
import {
CRAWLERS,
OAUTH_CONNECTORS,
OTHER_CONNECTORS,
} from "../constants/connector-constants";
import { CRAWLERS, OAUTH_CONNECTORS, OTHER_CONNECTORS } from "../constants/connector-constants";
import { getDocumentCountForConnector } from "../utils/connector-document-mapping";
/**
@ -19,293 +15,271 @@ import { getDocumentCountForConnector } from "../utils/connector-document-mappin
* Returns just the identifier (e.g : john@example.com).
*/
export function getConnectorDisplayName(fullName: string): string {
const separatorIndex = fullName.indexOf(" - ");
if (separatorIndex !== -1) {
return fullName.substring(separatorIndex + 3);
}
return fullName;
const separatorIndex = fullName.indexOf(" - ");
if (separatorIndex !== -1) {
return fullName.substring(separatorIndex + 3);
}
return fullName;
}
interface AllConnectorsTabProps {
searchQuery: string;
searchSpaceId: string;
connectedTypes: Set<string>;
connectingId: string | null;
allConnectors: SearchSourceConnector[] | undefined;
documentTypeCounts?: Record<string, number>;
indexingConnectorIds?: Set<number>;
logsSummary?: LogSummary;
onConnectOAuth: (connector: (typeof OAUTH_CONNECTORS)[number]) => void;
onConnectNonOAuth?: (connectorType: string) => void;
onCreateWebcrawler?: () => void;
onCreateYouTubeCrawler?: () => void;
onManage?: (connector: SearchSourceConnector) => void;
onViewAccountsList?: (connectorType: string, connectorTitle: string) => void;
searchQuery: string;
searchSpaceId: string;
connectedTypes: Set<string>;
connectingId: string | null;
allConnectors: SearchSourceConnector[] | undefined;
documentTypeCounts?: Record<string, number>;
indexingConnectorIds?: Set<number>;
logsSummary?: LogSummary;
onConnectOAuth: (connector: (typeof OAUTH_CONNECTORS)[number]) => void;
onConnectNonOAuth?: (connectorType: string) => void;
onCreateWebcrawler?: () => void;
onCreateYouTubeCrawler?: () => void;
onManage?: (connector: SearchSourceConnector) => void;
onViewAccountsList?: (connectorType: string, connectorTitle: string) => void;
}
export const AllConnectorsTab: FC<AllConnectorsTabProps> = ({
searchQuery,
searchSpaceId,
connectedTypes,
connectingId,
allConnectors,
documentTypeCounts,
indexingConnectorIds,
logsSummary,
onConnectOAuth,
onConnectNonOAuth,
onCreateWebcrawler,
onCreateYouTubeCrawler,
onManage,
onViewAccountsList,
searchQuery,
searchSpaceId,
connectedTypes,
connectingId,
allConnectors,
documentTypeCounts,
indexingConnectorIds,
logsSummary,
onConnectOAuth,
onConnectNonOAuth,
onCreateWebcrawler,
onCreateYouTubeCrawler,
onManage,
onViewAccountsList,
}) => {
// Helper to find active task for a connector
const getActiveTaskForConnector = (
connectorId: number
): LogActiveTask | undefined => {
if (!logsSummary?.active_tasks) return undefined;
return logsSummary.active_tasks.find(
(task: LogActiveTask) => task.connector_id === connectorId
);
};
// Helper to find active task for a connector
const getActiveTaskForConnector = (connectorId: number): LogActiveTask | undefined => {
if (!logsSummary?.active_tasks) return undefined;
return logsSummary.active_tasks.find(
(task: LogActiveTask) => task.connector_id === connectorId
);
};
// Filter connectors based on search
const filteredOAuth = OAUTH_CONNECTORS.filter(
(c) =>
c.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
c.description.toLowerCase().includes(searchQuery.toLowerCase())
);
// Filter connectors based on search
const filteredOAuth = OAUTH_CONNECTORS.filter(
(c) =>
c.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
c.description.toLowerCase().includes(searchQuery.toLowerCase())
);
const filteredCrawlers = CRAWLERS.filter(
(c) =>
c.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
c.description.toLowerCase().includes(searchQuery.toLowerCase())
);
const filteredCrawlers = CRAWLERS.filter(
(c) =>
c.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
c.description.toLowerCase().includes(searchQuery.toLowerCase())
);
const filteredOther = OTHER_CONNECTORS.filter(
(c) =>
c.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
c.description.toLowerCase().includes(searchQuery.toLowerCase())
);
const filteredOther = OTHER_CONNECTORS.filter(
(c) =>
c.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
c.description.toLowerCase().includes(searchQuery.toLowerCase())
);
return (
<div className="space-y-8">
{/* Quick Connect */}
{filteredOAuth.length > 0 && (
<section>
<div className="flex items-center gap-2 mb-4">
<h3 className="text-sm font-semibold text-muted-foreground">
Quick Connect
</h3>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
{filteredOAuth.map((connector) => {
const isConnected = connectedTypes.has(connector.connectorType);
const isConnecting = connectingId === connector.id;
// Find all connectors of this type
const typeConnectors =
isConnected && allConnectors
? allConnectors.filter(
(c: SearchSourceConnector) =>
c.connector_type === connector.connectorType
)
: [];
return (
<div className="space-y-8">
{/* Quick Connect */}
{filteredOAuth.length > 0 && (
<section>
<div className="flex items-center gap-2 mb-4">
<h3 className="text-sm font-semibold text-muted-foreground">Quick Connect</h3>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
{filteredOAuth.map((connector) => {
const isConnected = connectedTypes.has(connector.connectorType);
const isConnecting = connectingId === connector.id;
// Get the most recent last_indexed_at across all accounts
const mostRecentLastIndexed = typeConnectors.reduce<string | undefined>(
(latest, c) => {
if (!c.last_indexed_at) return latest;
if (!latest) return c.last_indexed_at;
return new Date(c.last_indexed_at) > new Date(latest) ? c.last_indexed_at : latest;
},
undefined
);
// Find all connectors of this type
const typeConnectors =
isConnected && allConnectors
? allConnectors.filter(
(c: SearchSourceConnector) => c.connector_type === connector.connectorType
)
: [];
const documentCount = getDocumentCountForConnector(
connector.connectorType,
documentTypeCounts
);
// Check if any account is currently indexing
const isIndexing = typeConnectors.some(
(c) => indexingConnectorIds?.has(c.id)
);
// Get active task from any indexing account
const activeTask = typeConnectors
.map((c) => getActiveTaskForConnector(c.id))
.find((task) => task !== undefined);
// Get the most recent last_indexed_at across all accounts
const mostRecentLastIndexed = typeConnectors.reduce<string | undefined>(
(latest, c) => {
if (!c.last_indexed_at) return latest;
if (!latest) return c.last_indexed_at;
return new Date(c.last_indexed_at) > new Date(latest)
? c.last_indexed_at
: latest;
},
undefined
);
return (
<ConnectorCard
key={connector.id}
id={connector.id}
title={connector.title}
description={connector.description}
connectorType={connector.connectorType}
isConnected={isConnected}
isConnecting={isConnecting}
documentCount={documentCount}
accountCount={typeConnectors.length}
lastIndexedAt={mostRecentLastIndexed}
isIndexing={isIndexing}
activeTask={activeTask}
onConnect={() => onConnectOAuth(connector)}
onManage={
isConnected && onViewAccountsList
? () => onViewAccountsList(connector.connectorType, connector.title)
: undefined
}
/>
);
})}
</div>
</section>
)}
const documentCount = getDocumentCountForConnector(
connector.connectorType,
documentTypeCounts
);
{/* More Integrations */}
{filteredOther.length > 0 && (
<section>
<div className="flex items-center gap-2 mb-4">
<h3 className="text-sm font-semibold text-muted-foreground">
More Integrations
</h3>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
{filteredOther.map((connector) => {
const isConnected = connectedTypes.has(connector.connectorType);
const isConnecting = connectingId === connector.id;
// Check if any account is currently indexing
const isIndexing = typeConnectors.some((c) => indexingConnectorIds?.has(c.id));
// Find the actual connector object if connected
const actualConnector =
isConnected && allConnectors
? allConnectors.find(
(c: SearchSourceConnector) =>
c.connector_type === connector.connectorType
)
: undefined;
// Get active task from any indexing account
const activeTask = typeConnectors
.map((c) => getActiveTaskForConnector(c.id))
.find((task) => task !== undefined);
const documentCount = getDocumentCountForConnector(
connector.connectorType,
documentTypeCounts
);
const isIndexing =
actualConnector &&
indexingConnectorIds?.has(actualConnector.id);
const activeTask = actualConnector
? getActiveTaskForConnector(actualConnector.id)
: undefined;
return (
<ConnectorCard
key={connector.id}
id={connector.id}
title={connector.title}
description={connector.description}
connectorType={connector.connectorType}
isConnected={isConnected}
isConnecting={isConnecting}
documentCount={documentCount}
accountCount={typeConnectors.length}
lastIndexedAt={mostRecentLastIndexed}
isIndexing={isIndexing}
activeTask={activeTask}
onConnect={() => onConnectOAuth(connector)}
onManage={
isConnected && onViewAccountsList
? () => onViewAccountsList(connector.connectorType, connector.title)
: undefined
}
/>
);
})}
</div>
</section>
)}
const handleConnect = onConnectNonOAuth
? () => onConnectNonOAuth(connector.connectorType)
: () => {}; // Fallback - connector popup should handle all connector types
{/* More Integrations */}
{filteredOther.length > 0 && (
<section>
<div className="flex items-center gap-2 mb-4">
<h3 className="text-sm font-semibold text-muted-foreground">More Integrations</h3>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
{filteredOther.map((connector) => {
const isConnected = connectedTypes.has(connector.connectorType);
const isConnecting = connectingId === connector.id;
return (
<ConnectorCard
key={connector.id}
id={connector.id}
title={connector.title}
description={connector.description}
connectorType={connector.connectorType}
isConnected={isConnected}
isConnecting={isConnecting}
documentCount={documentCount}
lastIndexedAt={actualConnector?.last_indexed_at}
isIndexing={isIndexing}
activeTask={activeTask}
onConnect={handleConnect}
onManage={
actualConnector && onManage
? () => onManage(actualConnector)
: undefined
}
/>
);
})}
</div>
</section>
)}
// Find the actual connector object if connected
const actualConnector =
isConnected && allConnectors
? allConnectors.find(
(c: SearchSourceConnector) => c.connector_type === connector.connectorType
)
: undefined;
{/* Content Sources */}
{filteredCrawlers.length > 0 && (
<section>
<div className="flex items-center gap-2 mb-4">
<h3 className="text-sm font-semibold text-muted-foreground">
Content Sources
</h3>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
{filteredCrawlers.map((crawler) => {
const isYouTube = crawler.id === "youtube-crawler";
const isWebcrawler = crawler.id === "webcrawler-connector";
const documentCount = getDocumentCountForConnector(
connector.connectorType,
documentTypeCounts
);
const isIndexing = actualConnector && indexingConnectorIds?.has(actualConnector.id);
const activeTask = actualConnector
? getActiveTaskForConnector(actualConnector.id)
: undefined;
// For crawlers that are actual connectors, check connection status
const isConnected = crawler.connectorType
? connectedTypes.has(crawler.connectorType)
: false;
const isConnecting = connectingId === crawler.id;
const handleConnect = onConnectNonOAuth
? () => onConnectNonOAuth(connector.connectorType)
: () => {}; // Fallback - connector popup should handle all connector types
// Find the actual connector object if connected
const actualConnector =
isConnected && crawler.connectorType && allConnectors
? allConnectors.find(
(c: SearchSourceConnector) =>
c.connector_type === crawler.connectorType
)
: undefined;
return (
<ConnectorCard
key={connector.id}
id={connector.id}
title={connector.title}
description={connector.description}
connectorType={connector.connectorType}
isConnected={isConnected}
isConnecting={isConnecting}
documentCount={documentCount}
lastIndexedAt={actualConnector?.last_indexed_at}
isIndexing={isIndexing}
activeTask={activeTask}
onConnect={handleConnect}
onManage={
actualConnector && onManage ? () => onManage(actualConnector) : undefined
}
/>
);
})}
</div>
</section>
)}
const documentCount = crawler.connectorType
? getDocumentCountForConnector(
crawler.connectorType,
documentTypeCounts
)
: undefined;
const isIndexing =
actualConnector &&
indexingConnectorIds?.has(actualConnector.id);
const activeTask = actualConnector
? getActiveTaskForConnector(actualConnector.id)
: undefined;
{/* Content Sources */}
{filteredCrawlers.length > 0 && (
<section>
<div className="flex items-center gap-2 mb-4">
<h3 className="text-sm font-semibold text-muted-foreground">Content Sources</h3>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
{filteredCrawlers.map((crawler) => {
const isYouTube = crawler.id === "youtube-crawler";
const isWebcrawler = crawler.id === "webcrawler-connector";
const handleConnect =
isYouTube && onCreateYouTubeCrawler
? onCreateYouTubeCrawler
: isWebcrawler && onCreateWebcrawler
? onCreateWebcrawler
: crawler.connectorType && onConnectNonOAuth
? () => {
if (crawler.connectorType) {
onConnectNonOAuth(crawler.connectorType);
}
}
: () => {}; // Fallback for non-connector crawlers
// For crawlers that are actual connectors, check connection status
const isConnected = crawler.connectorType
? connectedTypes.has(crawler.connectorType)
: false;
const isConnecting = connectingId === crawler.id;
return (
<ConnectorCard
key={crawler.id}
id={crawler.id}
title={crawler.title}
description={crawler.description}
connectorType={crawler.connectorType || undefined}
isConnected={isConnected}
isConnecting={isConnecting}
documentCount={documentCount}
lastIndexedAt={actualConnector?.last_indexed_at}
isIndexing={isIndexing}
activeTask={activeTask}
onConnect={handleConnect}
onManage={
actualConnector && onManage
? () => onManage(actualConnector)
: undefined
}
/>
);
})}
</div>
</section>
)}
</div>
);
// Find the actual connector object if connected
const actualConnector =
isConnected && crawler.connectorType && allConnectors
? allConnectors.find(
(c: SearchSourceConnector) => c.connector_type === crawler.connectorType
)
: undefined;
const documentCount = crawler.connectorType
? getDocumentCountForConnector(crawler.connectorType, documentTypeCounts)
: undefined;
const isIndexing = actualConnector && indexingConnectorIds?.has(actualConnector.id);
const activeTask = actualConnector
? getActiveTaskForConnector(actualConnector.id)
: undefined;
const handleConnect =
isYouTube && onCreateYouTubeCrawler
? onCreateYouTubeCrawler
: isWebcrawler && onCreateWebcrawler
? onCreateWebcrawler
: crawler.connectorType && onConnectNonOAuth
? () => {
if (crawler.connectorType) {
onConnectNonOAuth(crawler.connectorType);
}
}
: () => {}; // Fallback for non-connector crawlers
return (
<ConnectorCard
key={crawler.id}
id={crawler.id}
title={crawler.title}
description={crawler.description}
connectorType={crawler.connectorType || undefined}
isConnected={isConnected}
isConnecting={isConnecting}
documentCount={documentCount}
lastIndexedAt={actualConnector?.last_indexed_at}
isIndexing={isIndexing}
activeTask={activeTask}
onConnect={handleConnect}
onManage={
actualConnector && onManage ? () => onManage(actualConnector) : undefined
}
/>
);
})}
</div>
</section>
)}
</div>
);
};

View file

@ -187,4 +187,3 @@ export const ConnectorAccountsListView: FC<ConnectorAccountsListViewProps> = ({
</div>
);
};

View file

@ -1,7 +1,7 @@
"use client";
import { Upload } from "lucide-react";
import { useAtomValue } from "jotai";
import { Upload } from "lucide-react";
import { useRouter } from "next/navigation";
import {
createContext,

View file

@ -1,5 +1,5 @@
import Image from "next/image";
import { type StreamdownProps, Streamdown } from "streamdown";
import { Streamdown, type StreamdownProps } from "streamdown";
import { cn } from "@/lib/utils";
interface MarkdownViewerProps {

View file

@ -20,4 +20,3 @@
],
"defaultOpen": true
}