diff --git a/surfsense_web/components/assistant-ui/connector-popup/connect-forms/components/circleback-connect-form.tsx b/surfsense_web/components/assistant-ui/connector-popup/connect-forms/components/circleback-connect-form.tsx new file mode 100644 index 000000000..35373fc49 --- /dev/null +++ b/surfsense_web/components/assistant-ui/connector-popup/connect-forms/components/circleback-connect-form.tsx @@ -0,0 +1,121 @@ +"use client"; + +import { zodResolver } from "@hookform/resolvers/zod"; +import { Info, Webhook } from "lucide-react"; +import type { FC } from "react"; +import { useRef } from "react"; +import { useForm } from "react-hook-form"; +import * as z from "zod"; +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { EnumConnectorName } from "@/contracts/enums/connector"; +import type { ConnectFormProps } from "../index"; +import { getConnectorBenefits } from "../connector-benefits"; + +const circlebackFormSchema = z.object({ + name: z.string().min(3, { + message: "Connector name must be at least 3 characters.", + }), +}); + +type CirclebackFormValues = z.infer; + +export const CirclebackConnectForm: FC = ({ + onSubmit, + isSubmitting, +}) => { + const isSubmittingRef = useRef(false); + const form = useForm({ + resolver: zodResolver(circlebackFormSchema), + defaultValues: { + name: "Circleback Connector", + }, + }); + + const handleSubmit = async (values: CirclebackFormValues) => { + // Prevent multiple submissions + if (isSubmittingRef.current || isSubmitting) { + return; + } + + isSubmittingRef.current = true; + try { + await onSubmit({ + name: values.name, + connector_type: EnumConnectorName.CIRCLEBACK_CONNECTOR, + config: {}, + is_indexable: false, + last_indexed_at: null, + periodic_indexing_enabled: false, + indexing_frequency_minutes: null, + next_scheduled_at: null, + }); + } finally { + isSubmittingRef.current = false; + } + }; + + return ( +
+ + +
+ Webhook-Based Integration + + Circleback uses webhooks to automatically send meeting data. After connecting, you'll receive a webhook URL to configure in your Circleback settings. + +
+
+ +
+
+ + ( + + Connector Name + + + + + A friendly name to identify this connector. + + + + )} + /> + + +
+ + {/* What you get section */} + {getConnectorBenefits(EnumConnectorName.CIRCLEBACK_CONNECTOR) && ( +
+

What you get with Circleback:

+
    + {getConnectorBenefits(EnumConnectorName.CIRCLEBACK_CONNECTOR)?.map((benefit) => ( +
  • {benefit}
  • + ))} +
+
+ )} +
+ ); +}; + diff --git a/surfsense_web/components/assistant-ui/connector-popup/connect-forms/connector-benefits.ts b/surfsense_web/components/assistant-ui/connector-popup/connect-forms/connector-benefits.ts index 664fe78b8..194257cd0 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/connect-forms/connector-benefits.ts +++ b/surfsense_web/components/assistant-ui/connector-popup/connect-forms/connector-benefits.ts @@ -101,6 +101,13 @@ export function getConnectorBenefits(connectorType: string): string[] | null { "Keep your search results up-to-date with latest Luma content", "Index your Luma events for enhanced search capabilities", ], + CIRCLEBACK_CONNECTOR: [ + "Automatically receive meeting notes, transcripts, and action items", + "Access meeting details, attendees, and insights", + "Search through all your Circleback meeting records", + "Real-time updates via webhook integration", + "No manual indexing required - meetings are added automatically", + ], }; return benefits[connectorType] || null; diff --git a/surfsense_web/components/assistant-ui/connector-popup/connect-forms/index.tsx b/surfsense_web/components/assistant-ui/connector-popup/connect-forms/index.tsx index 46ed58272..0be9ec563 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/connect-forms/index.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/connect-forms/index.tsx @@ -1,6 +1,7 @@ import type { FC } from "react"; import { BaiduSearchApiConnectForm } from "./components/baidu-search-api-connect-form"; import { BookStackConnectForm } from "./components/bookstack-connect-form"; +import { CirclebackConnectForm } from "./components/circleback-connect-form"; import { ClickUpConnectForm } from "./components/clickup-connect-form"; import { ConfluenceConnectForm } from "./components/confluence-connect-form"; import { DiscordConnectForm } from "./components/discord-connect-form"; @@ -74,6 +75,8 @@ export function getConnectFormComponent( return ClickUpConnectForm; case "LUMA_CONNECTOR": return LumaConnectForm; + case "CIRCLEBACK_CONNECTOR": + return CirclebackConnectForm; // Add other connector types here as needed default: return null; diff --git a/surfsense_web/components/assistant-ui/connector-popup/connector-configs/components/circleback-config.tsx b/surfsense_web/components/assistant-ui/connector-popup/connector-configs/components/circleback-config.tsx new file mode 100644 index 000000000..48e4b43e5 --- /dev/null +++ b/surfsense_web/components/assistant-ui/connector-popup/connector-configs/components/circleback-config.tsx @@ -0,0 +1,156 @@ +"use client"; + +import { Copy, Webhook, Check } from "lucide-react"; +import { useState, useEffect } from "react"; +import type { FC } from "react"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Button } from "@/components/ui/button"; +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import type { ConnectorConfigProps } from "../index"; +import { authenticatedFetch } from "@/lib/auth-utils"; + +export interface CirclebackConfigProps extends ConnectorConfigProps { + onNameChange?: (name: string) => void; +} + +export const CirclebackConfig: FC = ({ + connector, + onNameChange, +}) => { + const [name, setName] = useState(connector.name || ""); + const [webhookUrl, setWebhookUrl] = useState(""); + const [webhookInfo, setWebhookInfo] = useState<{ webhook_url: string; search_space_id: number; method: string; content_type: string; description: string; note: string } | null>(null); + const [isLoading, setIsLoading] = useState(true); + const [copied, setCopied] = useState(false); + + // Update name when connector changes + useEffect(() => { + setName(connector.name || ""); + }, [connector.name]); + + // Fetch webhook info + useEffect(() => { + const fetchWebhookInfo = async () => { + if (!connector.search_space_id) return; + + setIsLoading(true); + try { + const response = await authenticatedFetch( + `${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/webhooks/circleback/${connector.search_space_id}/info` + ); + if (response.ok) { + const data = await response.json(); + setWebhookInfo(data); + setWebhookUrl(data.webhook_url || ""); + } + } catch (error) { + console.error("Failed to fetch webhook info:", error); + } finally { + setIsLoading(false); + } + }; + + fetchWebhookInfo(); + }, [connector.search_space_id]); + + const handleNameChange = (value: string) => { + setName(value); + if (onNameChange) { + onNameChange(value); + } + }; + + const handleCopyWebhookUrl = async () => { + if (webhookUrl) { + await navigator.clipboard.writeText(webhookUrl); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } + }; + + return ( +
+ {/* Connector Name */} +
+
+ + handleNameChange(e.target.value)} + placeholder="My Circleback Connector" + className="border-slate-400/20 focus-visible:border-slate-400/40" + /> +

+ A friendly name to identify this connector. +

+
+
+ + {/* Webhook Configuration */} +
+
+

+ + Webhook Configuration +

+
+ + {isLoading ? ( +

+ Loading webhook information... +

+ ) : webhookUrl ? ( +
+ +
+ + +
+

+ Use this URL in your Circleback automation settings to send meeting data to SurfSense. +

+
+ ) : ( +

+ Unable to load webhook URL. Please try refreshing the page. +

+ )} + + {webhookInfo && ( + + + Configuration Instructions + + Configure this URL in Circleback Settings → Automations → Create automation → Send webhook request. + The webhook will automatically send meeting notes, transcripts, and action items to this search space. + + + )} +
+
+ ); +}; + diff --git a/surfsense_web/components/assistant-ui/connector-popup/connector-configs/index.tsx b/surfsense_web/components/assistant-ui/connector-popup/connector-configs/index.tsx index 59919d0cd..ca296e482 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/connector-configs/index.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/connector-configs/index.tsx @@ -4,6 +4,7 @@ import type { FC } from "react"; import type { SearchSourceConnector } from "@/contracts/types/connector.types"; import { BaiduSearchApiConfig } from "./components/baidu-search-api-config"; import { BookStackConfig } from "./components/bookstack-config"; +import { CirclebackConfig } from "./components/circleback-config"; import { ClickUpConfig } from "./components/clickup-config"; import { ConfluenceConfig } from "./components/confluence-config"; import { DiscordConfig } from "./components/discord-config"; @@ -69,6 +70,8 @@ export function getConnectorConfigComponent( return ClickUpConfig; case "LUMA_CONNECTOR": return LumaConfig; + case "CIRCLEBACK_CONNECTOR": + return CirclebackConfig; // OAuth connectors (Gmail, Calendar, Airtable) and others don't need special config UI default: return null; diff --git a/surfsense_web/components/assistant-ui/connector-popup/connector-configs/views/connector-connect-view.tsx b/surfsense_web/components/assistant-ui/connector-popup/connector-configs/views/connector-connect-view.tsx index 6827c6362..21e84a67b 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/connector-configs/views/connector-connect-view.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/connector-configs/views/connector-connect-view.tsx @@ -62,6 +62,7 @@ export const ConnectorConnectView: FC = ({ JIRA_CONNECTOR: "jira-connect-form", CLICKUP_CONNECTOR: "clickup-connect-form", LUMA_CONNECTOR: "luma-connect-form", + CIRCLEBACK_CONNECTOR: "circleback-connect-form", }; const formId = formIdMap[connectorType]; if (formId) { diff --git a/surfsense_web/components/assistant-ui/connector-popup/constants/connector-constants.ts b/surfsense_web/components/assistant-ui/connector-popup/constants/connector-constants.ts index 60126e135..46f6cb130 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/constants/connector-constants.ts +++ b/surfsense_web/components/assistant-ui/connector-popup/constants/connector-constants.ts @@ -38,7 +38,7 @@ export const CRAWLERS = [ id: "youtube-crawler", title: "YouTube", description: "Crawl YouTube channels and playlists", - connectorType: null, // Not a connector, handled separately + connectorType: EnumConnectorName.YOUTUBE_CONNECTOR, }, { id: "webcrawler-connector", @@ -140,6 +140,12 @@ export const OTHER_CONNECTORS = [ description: "Search with Baidu", connectorType: EnumConnectorName.BAIDU_SEARCH_API, }, + { + id: "circleback-connector", + title: "Circleback", + description: "Receive meeting notes via webhook", + connectorType: EnumConnectorName.CIRCLEBACK_CONNECTOR, + }, ] as const; // Re-export IndexingConfigState from schemas for backward compatibility diff --git a/surfsense_web/components/assistant-ui/connector-popup/tabs/all-connectors-tab.tsx b/surfsense_web/components/assistant-ui/connector-popup/tabs/all-connectors-tab.tsx index 030e5dc3d..7ea9035c4 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/tabs/all-connectors-tab.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/tabs/all-connectors-tab.tsx @@ -183,23 +183,24 @@ export const AllConnectorsTab: FC = ({
{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"; - const isBaidu = connector.id === "baidu-search-api"; - const isLinear = connector.id === "linear-connector"; - const isElasticsearch = connector.id === "elasticsearch-connector"; - const isSlack = connector.id === "slack-connector"; - const isDiscord = connector.id === "discord-connector"; - const isNotion = connector.id === "notion-connector"; - const isConfluence = connector.id === "confluence-connector"; - const isBookStack = connector.id === "bookstack-connector"; - const isGithub = connector.id === "github-connector"; - const isJira = connector.id === "jira-connector"; - const isClickUp = connector.id === "clickup-connector"; - const isLuma = connector.id === "luma-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"; + const isBaidu = connector.id === "baidu-search-api"; + const isLinear = connector.id === "linear-connector"; + const isElasticsearch = connector.id === "elasticsearch-connector"; + const isSlack = connector.id === "slack-connector"; + const isDiscord = connector.id === "discord-connector"; + const isNotion = connector.id === "notion-connector"; + const isConfluence = connector.id === "confluence-connector"; + const isBookStack = connector.id === "bookstack-connector"; + const isGithub = connector.id === "github-connector"; + const isJira = connector.id === "jira-connector"; + const isClickUp = connector.id === "clickup-connector"; + const isLuma = connector.id === "luma-connector"; + const isCircleback = connector.id === "circleback-connector"; const isConnected = connectedTypes.has(connector.connectorType); const isConnecting = connectingId === connector.id; @@ -215,7 +216,7 @@ export const AllConnectorsTab: FC = ({ const handleConnect = isWebcrawler && onCreateWebcrawler ? onCreateWebcrawler - : (isTavily || isSearxng || isLinkup || isBaidu || isLinear || isElasticsearch || isSlack || isDiscord || isNotion || isConfluence || isBookStack || isGithub || isJira || isClickUp || isLuma) && onConnectNonOAuth + : (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}`); diff --git a/surfsense_web/components/assistant-ui/connector-popup/utils/connector-document-mapping.ts b/surfsense_web/components/assistant-ui/connector-popup/utils/connector-document-mapping.ts index a0afa7431..607b6608f 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/utils/connector-document-mapping.ts +++ b/surfsense_web/components/assistant-ui/connector-popup/utils/connector-document-mapping.ts @@ -24,6 +24,7 @@ export const CONNECTOR_TO_DOCUMENT_TYPE: Record = { LUMA_CONNECTOR: "LUMA_CONNECTOR", ELASTICSEARCH_CONNECTOR: "ELASTICSEARCH_CONNECTOR", BOOKSTACK_CONNECTOR: "BOOKSTACK_CONNECTOR", + CIRCLEBACK_CONNECTOR: "CIRCLEBACK", // Special mappings (connector type differs from document type) GOOGLE_DRIVE_CONNECTOR: "GOOGLE_DRIVE_FILE", diff --git a/surfsense_web/components/assistant-ui/connector-popup/views/youtube-crawler-view.tsx b/surfsense_web/components/assistant-ui/connector-popup/views/youtube-crawler-view.tsx index ed5098e37..7f5ad5d2b 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/views/youtube-crawler-view.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/views/youtube-crawler-view.tsx @@ -1,6 +1,5 @@ "use client"; -import { IconBrandYoutube } from "@tabler/icons-react"; import { ArrowLeft } from "lucide-react"; import { TagInput, type Tag as TagType } from "emblor"; import { useAtom } from "jotai"; @@ -12,6 +11,8 @@ import { toast } from "sonner"; import { createDocumentMutationAtom } from "@/atoms/documents/document-mutation.atoms"; import { Button } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; +import { EnumConnectorName } from "@/contracts/enums/connector"; +import { getConnectorIcon } from "@/contracts/enums/connectorIcons"; const youtubeRegex = /^(https:\/\/)?(www\.)?(youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9_-]{11})$/; @@ -129,7 +130,7 @@ export const YouTubeCrawlerView: FC = ({
- + {getConnectorIcon(EnumConnectorName.YOUTUBE_CONNECTOR, "h-7 w-7")}

@@ -236,10 +237,7 @@ export const YouTubeCrawlerView: FC = ({ {t("processing")} ) : ( - <> - - {t("submit")} - + t("submit") )}

diff --git a/surfsense_web/components/sources/connector-data.tsx b/surfsense_web/components/sources/connector-data.tsx deleted file mode 100644 index a1c6084d2..000000000 --- a/surfsense_web/components/sources/connector-data.tsx +++ /dev/null @@ -1,215 +0,0 @@ -import { EnumConnectorName } from "@/contracts/enums/connector"; -import { getConnectorIcon } from "@/contracts/enums/connectorIcons"; -import type { ConnectorCategory } from "./types"; - -export const connectorCategories: ConnectorCategory[] = [ - { - id: "web-crawling", - title: "web_crawling", - connectors: [ - { - id: "webcrawler-connector", - title: "Web Pages", - description: "webcrawler_desc", - icon: getConnectorIcon(EnumConnectorName.WEBCRAWLER_CONNECTOR, "h-6 w-6"), - status: "available", - }, - ], - }, - { - id: "web-search", - title: "web_search", - connectors: [ - { - id: "tavily-api", - title: "Tavily API", - description: "tavily_desc", - icon: getConnectorIcon(EnumConnectorName.TAVILY_API, "h-6 w-6"), - status: "available", - }, - { - id: "searxng", - title: "SearxNG", - description: "searxng_desc", - icon: getConnectorIcon(EnumConnectorName.SEARXNG_API, "h-6 w-6"), - status: "available", - }, - { - id: "linkup-api", - title: "Linkup API", - description: "linkup_desc", - icon: getConnectorIcon(EnumConnectorName.LINKUP_API, "h-6 w-6"), - status: "available", - }, - { - id: "baidu-search-api", - title: "Baidu Search", - description: "baidu_desc", - icon: getConnectorIcon(EnumConnectorName.BAIDU_SEARCH_API, "h-6 w-6"), - status: "available", - }, - ], - }, - { - id: "messaging", - title: "messaging", - connectors: [ - { - id: "slack-connector", - title: "Slack", - description: "slack_desc", - icon: getConnectorIcon(EnumConnectorName.SLACK_CONNECTOR, "h-6 w-6"), - status: "available", - }, - { - id: "discord-connector", - title: "Discord", - description: "discord_desc", - icon: getConnectorIcon(EnumConnectorName.DISCORD_CONNECTOR, "h-6 w-6"), - status: "available", - }, - { - id: "ms-teams", - title: "Microsoft Teams", - description: "teams_desc", - icon: getConnectorIcon("ms-teams", "h-6 w-6"), - status: "coming-soon", - }, - ], - }, - { - id: "project-management", - title: "project_management", - connectors: [ - { - id: "linear-connector", - title: "Linear", - description: "linear_desc", - icon: getConnectorIcon(EnumConnectorName.LINEAR_CONNECTOR, "h-6 w-6"), - status: "available", - }, - { - id: "jira-connector", - title: "Jira", - description: "jira_desc", - icon: getConnectorIcon(EnumConnectorName.JIRA_CONNECTOR, "h-6 w-6"), - status: "available", - }, - { - id: "clickup-connector", - title: "ClickUp", - description: "clickup_desc", - icon: getConnectorIcon(EnumConnectorName.CLICKUP_CONNECTOR, "h-6 w-6"), - status: "available", - }, - ], - }, - { - id: "documentation", - title: "documentation", - connectors: [ - { - id: "notion-connector", - title: "Notion", - description: "notion_desc", - icon: getConnectorIcon(EnumConnectorName.NOTION_CONNECTOR, "h-6 w-6"), - status: "available", - }, - { - id: "confluence-connector", - title: "Confluence", - description: "confluence_desc", - icon: getConnectorIcon(EnumConnectorName.CONFLUENCE_CONNECTOR, "h-6 w-6"), - status: "available", - }, - { - id: "bookstack-connector", - title: "BookStack", - description: "bookstack_desc", - icon: getConnectorIcon(EnumConnectorName.BOOKSTACK_CONNECTOR, "h-6 w-6"), - status: "available", - }, - ], - }, - { - id: "development", - title: "development", - connectors: [ - { - id: "github-connector", - title: "GitHub", - description: "github_desc", - icon: getConnectorIcon(EnumConnectorName.GITHUB_CONNECTOR, "h-6 w-6"), - status: "available", - }, - ], - }, - { - id: "databases", - title: "databases", - connectors: [ - { - id: "elasticsearch-connector", - title: "Elasticsearch", - description: "elasticsearch_desc", - icon: getConnectorIcon(EnumConnectorName.ELASTICSEARCH_CONNECTOR, "h-6 w-6"), - status: "available", - }, - { - id: "airtable-connector", - title: "Airtable", - description: "airtable_desc", - icon: getConnectorIcon(EnumConnectorName.AIRTABLE_CONNECTOR, "h-6 w-6"), - status: "available", - }, - ], - }, - { - id: "productivity", - title: "productivity", - connectors: [ - { - id: "google-calendar-connector", - title: "Google Calendar", - description: "calendar_desc", - icon: getConnectorIcon(EnumConnectorName.GOOGLE_CALENDAR_CONNECTOR, "h-6 w-6"), - status: "available", - }, - { - id: "google-gmail-connector", - title: "Gmail", - description: "gmail_desc", - icon: getConnectorIcon(EnumConnectorName.GOOGLE_GMAIL_CONNECTOR, "h-6 w-6"), - status: "available", - }, - { - id: "google-drive-connector", - title: "Google Drive", - description: "google_drive_desc", - icon: getConnectorIcon(EnumConnectorName.GOOGLE_DRIVE_CONNECTOR, "h-6 w-6"), - status: "available", - }, - { - id: "luma-connector", - title: "Luma", - description: "luma_desc", - icon: getConnectorIcon(EnumConnectorName.LUMA_CONNECTOR, "h-6 w-6"), - status: "available", - }, - { - id: "circleback-connector", - title: "Circleback", - description: "circleback_desc", - icon: getConnectorIcon(EnumConnectorName.CIRCLEBACK_CONNECTOR, "h-6 w-6"), - status: "available", - }, - { - id: "zoom", - title: "Zoom", - description: "zoom_desc", - icon: getConnectorIcon("zoom", "h-6 w-6"), - status: "coming-soon", - }, - ], -}, -]; diff --git a/surfsense_web/contracts/enums/connector.ts b/surfsense_web/contracts/enums/connector.ts index 22f6530da..ae80cf871 100644 --- a/surfsense_web/contracts/enums/connector.ts +++ b/surfsense_web/contracts/enums/connector.ts @@ -19,5 +19,6 @@ export enum EnumConnectorName { LUMA_CONNECTOR = "LUMA_CONNECTOR", ELASTICSEARCH_CONNECTOR = "ELASTICSEARCH_CONNECTOR", WEBCRAWLER_CONNECTOR = "WEBCRAWLER_CONNECTOR", + YOUTUBE_CONNECTOR = "YOUTUBE_CONNECTOR", CIRCLEBACK_CONNECTOR = "CIRCLEBACK_CONNECTOR", } diff --git a/surfsense_web/contracts/enums/connectorIcons.tsx b/surfsense_web/contracts/enums/connectorIcons.tsx index e8c2b4ed0..d836701be 100644 --- a/surfsense_web/contracts/enums/connectorIcons.tsx +++ b/surfsense_web/contracts/enums/connectorIcons.tsx @@ -2,7 +2,6 @@ import { IconLinkPlus, IconSparkles, IconUsersGroup, - IconWorldWww, } from "@tabler/icons-react"; import { File, @@ -20,16 +19,30 @@ import { EnumConnectorName } from "./connector"; export const getConnectorIcon = (connectorType: EnumConnectorName | string, className?: string) => { const iconProps = { className: className || "h-4 w-4" }; const imgProps = { className: className || "h-5 w-5", width: 20, height: 20 }; + // Larger props for specific services (Google services, GitHub, Linear) - scale up from size-6 to size-8 + const getLargeClassName = () => { + if (!className) return "h-8 w-8"; + // Replace size-6 with size-8, or h-6/w-6 with h-8/w-8 + return className + .replace(/size-6/g, "size-8") + .replace(/\bh-6\b/g, "h-8") + .replace(/\bw-6\b/g, "w-8"); + }; + const largeImgProps = { + className: getLargeClassName(), + width: 32, + height: 32 + }; switch (connectorType) { case EnumConnectorName.LINKUP_API: return ; case EnumConnectorName.LINEAR_CONNECTOR: - return Linear; + return Linear; case EnumConnectorName.GITHUB_CONNECTOR: - return GitHub; + return GitHub; case EnumConnectorName.TAVILY_API: - return ; + return Tavily; case EnumConnectorName.SEARXNG_API: return ; case EnumConnectorName.BAIDU_SEARCH_API: @@ -43,11 +56,11 @@ export const getConnectorIcon = (connectorType: EnumConnectorName | string, clas case EnumConnectorName.JIRA_CONNECTOR: return Jira; case EnumConnectorName.GOOGLE_CALENDAR_CONNECTOR: - return Google Calendar; + return Google Calendar; case EnumConnectorName.GOOGLE_GMAIL_CONNECTOR: - return Gmail; + return Gmail; case EnumConnectorName.GOOGLE_DRIVE_CONNECTOR: - return Google Drive; + return Google Drive; case EnumConnectorName.AIRTABLE_CONNECTOR: return Airtable; case EnumConnectorName.CONFLUENCE_CONNECTOR: @@ -62,9 +75,13 @@ export const getConnectorIcon = (connectorType: EnumConnectorName | string, clas return Elasticsearch; case EnumConnectorName.WEBCRAWLER_CONNECTOR: return ; + case EnumConnectorName.YOUTUBE_CONNECTOR: + return YouTube; case EnumConnectorName.CIRCLEBACK_CONNECTOR: return ; // Additional cases for non-enum connector types + case "YOUTUBE_CONNECTOR": + return YouTube; case "CIRCLEBACK": return ; case "CRAWLED_URL": diff --git a/surfsense_web/lib/connectors/utils.ts b/surfsense_web/lib/connectors/utils.ts index de791be7f..75e81e2cc 100644 --- a/surfsense_web/lib/connectors/utils.ts +++ b/surfsense_web/lib/connectors/utils.ts @@ -19,6 +19,7 @@ export const getConnectorTypeDisplay = (type: string): string => { LUMA_CONNECTOR: "Luma", ELASTICSEARCH_CONNECTOR: "Elasticsearch", WEBCRAWLER_CONNECTOR: "Web Pages", + CIRCLEBACK_CONNECTOR: "Circleback", }; return typeMap[type] || type; }; diff --git a/surfsense_web/public/connectors/baidu-search.svg b/surfsense_web/public/connectors/baidu-search.svg index 5bf435123..045239cba 100644 --- a/surfsense_web/public/connectors/baidu-search.svg +++ b/surfsense_web/public/connectors/baidu-search.svg @@ -1,6 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/surfsense_web/public/connectors/clickup.svg b/surfsense_web/public/connectors/clickup.svg index 4bf99cfd8..64f68a7fc 100644 --- a/surfsense_web/public/connectors/clickup.svg +++ b/surfsense_web/public/connectors/clickup.svg @@ -1 +1,14 @@ -ClickUp \ No newline at end of file + + + + + + + + + + + + + + diff --git a/surfsense_web/public/connectors/confluence.svg b/surfsense_web/public/connectors/confluence.svg index f8c539608..cf9e395ee 100644 --- a/surfsense_web/public/connectors/confluence.svg +++ b/surfsense_web/public/connectors/confluence.svg @@ -1,15 +1 @@ - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/surfsense_web/public/connectors/jira.svg b/surfsense_web/public/connectors/jira.svg index 69c69f628..892c240c8 100644 --- a/surfsense_web/public/connectors/jira.svg +++ b/surfsense_web/public/connectors/jira.svg @@ -1,16 +1 @@ - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/surfsense_web/public/connectors/luma.svg b/surfsense_web/public/connectors/luma.svg new file mode 100644 index 000000000..366f59ea8 --- /dev/null +++ b/surfsense_web/public/connectors/luma.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/surfsense_web/public/connectors/notion.svg b/surfsense_web/public/connectors/notion.svg index 38984c87b..92c6b1573 100644 --- a/surfsense_web/public/connectors/notion.svg +++ b/surfsense_web/public/connectors/notion.svg @@ -1,4 +1 @@ - - - - + \ No newline at end of file diff --git a/surfsense_web/public/connectors/slack.svg b/surfsense_web/public/connectors/slack.svg index 1832b4653..259a9745d 100644 --- a/surfsense_web/public/connectors/slack.svg +++ b/surfsense_web/public/connectors/slack.svg @@ -1,6 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/surfsense_web/public/connectors/tavily.svg b/surfsense_web/public/connectors/tavily.svg new file mode 100644 index 000000000..cd3b556d8 --- /dev/null +++ b/surfsense_web/public/connectors/tavily.svg @@ -0,0 +1 @@ +Tavily \ No newline at end of file diff --git a/surfsense_web/public/connectors/youtube.svg b/surfsense_web/public/connectors/youtube.svg index ba2395b5d..7a705392a 100644 --- a/surfsense_web/public/connectors/youtube.svg +++ b/surfsense_web/public/connectors/youtube.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file