refactor: simplify connector management and update dashboard layout

- Removed the Connectors management page and integrated its functionality into a popup for better user experience.
- Updated the DashboardLayout to reflect changes in navigation, removing references to the Connectors page.
- Streamlined the breadcrumb component by eliminating unnecessary connector-related sections.
- Enhanced the ConnectorIndicator to facilitate easier access to connector management features.
- Improved overall UI consistency and accessibility across the dashboard components.
This commit is contained in:
Anish Sarkar 2026-01-01 21:41:31 +05:30
parent b909032e32
commit 3ae8fe3a7e
7 changed files with 65 additions and 999 deletions

View file

@ -1,7 +1,6 @@
import { AssistantIf, ComposerPrimitive, useAssistantState } from "@assistant-ui/react";
import { useAtomValue } from "jotai";
import { AlertCircle, ArrowUpIcon, Loader2, Plus, Plug2, SquareIcon } from "lucide-react";
import Link from "next/link";
import type { FC } from "react";
import { useCallback, useMemo, useRef, useState } from "react";
import { getDocumentTypeLabel } from "@/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentTypeIcon";
@ -148,14 +147,15 @@ const ConnectorIndicator: FC = () => {
</>
)}
<div className="pt-1 border-t border-border/50">
<Link
href={`/dashboard/${searchSpaceId}/connectors/add`}
<button
type="button"
className="inline-flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors"
onClick={() => {/* Connector popup should be opened via the connector indicator button */}}
>
<Plus className="size-3" />
Add more sources
<ChevronRightIcon className="size-3" />
</Link>
</button>
</div>
</div>
) : (
@ -164,13 +164,14 @@ const ConnectorIndicator: FC = () => {
<p className="text-xs text-muted-foreground">
Add documents or connect data sources to enhance search results.
</p>
<Link
href={`/dashboard/${searchSpaceId}/connectors/add`}
<button
type="button"
className="inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 transition-colors mt-1"
onClick={() => {/* Connector popup should be opened via the connector indicator button */}}
>
<Plus className="size-3" />
Add Connector
</Link>
</button>
</div>
)}
</PopoverContent>

View file

@ -688,29 +688,7 @@ export const useConnectorDialog = () => {
const handleStartEdit = useCallback((connector: SearchSourceConnector) => {
if (!searchSpaceId) return;
// Check if this is an OAuth connector
const isOAuthConnector = OAUTH_CONNECTORS.some(
(oauthConnector) => oauthConnector.connectorType === connector.connector_type
);
// Check if this is webcrawler, Tavily API, SearxNG, Linkup, Baidu, Linear, Elasticsearch, Slack, Discord, or Notion (can be managed in popup)
const isWebcrawler = connector.connector_type === EnumConnectorName.WEBCRAWLER_CONNECTOR;
const isTavilyApi = connector.connector_type === EnumConnectorName.TAVILY_API;
const isSearxng = connector.connector_type === EnumConnectorName.SEARXNG_API;
const isLinkup = connector.connector_type === EnumConnectorName.LINKUP_API;
const isBaidu = connector.connector_type === EnumConnectorName.BAIDU_SEARCH_API;
const isLinear = connector.connector_type === EnumConnectorName.LINEAR_CONNECTOR;
const isElasticsearch = connector.connector_type === EnumConnectorName.ELASTICSEARCH_CONNECTOR;
const isSlack = connector.connector_type === EnumConnectorName.SLACK_CONNECTOR;
const isDiscord = connector.connector_type === EnumConnectorName.DISCORD_CONNECTOR;
const isNotion = connector.connector_type === EnumConnectorName.NOTION_CONNECTOR;
// If not OAuth, not webcrawler, not Tavily API, not SearxNG, not Linkup, not Baidu, not Linear, not Elasticsearch, not Slack, not Discord, and not Notion, redirect to old connector edit page
if (!isOAuthConnector && !isWebcrawler && !isTavilyApi && !isSearxng && !isLinkup && !isBaidu && !isLinear && !isElasticsearch && !isSlack && !isDiscord && !isNotion) {
router.push(`/dashboard/${searchSpaceId}/connectors/${connector.id}/edit`);
return;
}
// All connector types should be handled in the popup edit view
// Validate connector data
const connectorValidation = searchSourceConnector.safeParse(connector);
if (!connectorValidation.success) {
@ -733,7 +711,7 @@ export const useConnectorDialog = () => {
url.searchParams.set("view", "edit");
url.searchParams.set("connectorId", connector.id.toString());
window.history.pushState({ modal: true }, "", url.toString());
}, [searchSpaceId, router]);
}, [searchSpaceId]);
// Handle saving connector changes
const handleSaveConnector = useCallback(async (refreshConnectors: () => void) => {

View file

@ -1,7 +1,6 @@
"use client";
import { useRouter } from "next/navigation";
import { type FC } from "react";
import type { FC } from "react";
import type { SearchSourceConnector } from "@/contracts/types/connector.types";
import type { LogActiveTask, LogSummary } from "@/contracts/types/log.types";
import { OAUTH_CONNECTORS, CRAWLERS, OTHER_CONNECTORS } from "../constants/connector-constants";
@ -39,8 +38,6 @@ export const AllConnectorsTab: FC<AllConnectorsTabProps> = ({
onCreateYouTubeCrawler,
onManage,
}) => {
const router = useRouter();
// Helper to find active task for a connector
const getActiveTaskForConnector = (connectorId: number): LogActiveTask | undefined => {
if (!logsSummary?.active_tasks) return undefined;
@ -148,9 +145,11 @@ export const AllConnectorsTab: FC<AllConnectorsTabProps> = ({
: isWebcrawler && onCreateWebcrawler
? onCreateWebcrawler
: crawler.connectorType && onConnectNonOAuth
? () => onConnectNonOAuth(crawler.connectorType!)
: crawler.connectorType
? () => router.push(`/dashboard/${searchSpaceId}/connectors/add/${crawler.id}`)
? () => {
if (crawler.connectorType) {
onConnectNonOAuth(crawler.connectorType);
}
}
: () => {}; // Fallback for non-connector crawlers
return (
@ -186,7 +185,6 @@ export const AllConnectorsTab: FC<AllConnectorsTabProps> = ({
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
{filteredOther.map((connector) => {
// Special handling for connectors that can be created in popup
const isWebcrawler = connector.id === "webcrawler-connector";
const isTavily = connector.id === "tavily-api";
const isSearxng = connector.id === "searxng";
const isLinkup = connector.id === "linkup-api";
@ -216,11 +214,9 @@ export const AllConnectorsTab: FC<AllConnectorsTabProps> = ({
const isIndexing = actualConnector && indexingConnectorIds?.has(actualConnector.id);
const activeTask = actualConnector ? getActiveTaskForConnector(actualConnector.id) : undefined;
const handleConnect = isWebcrawler && onCreateWebcrawler
? onCreateWebcrawler
: (isTavily || isSearxng || isLinkup || isBaidu || isLinear || isElasticsearch || isSlack || isDiscord || isNotion || isConfluence || isBookStack || isGithub || isJira || isClickUp || isLuma || isCircleback) && onConnectNonOAuth
const handleConnect = (isTavily || isSearxng || isLinkup || isBaidu || isLinear || isElasticsearch || isSlack || isDiscord || isNotion || isConfluence || isBookStack || isGithub || isJira || isClickUp || isLuma || isCircleback) && onConnectNonOAuth
? () => onConnectNonOAuth(connector.connectorType)
: () => router.push(`/dashboard/${searchSpaceId}/connectors/add/${connector.id}`);
: () => {}; // Fallback - connector popup should handle all connector types
return (
<ConnectorCard