From 924d18896ae65f24e062098953b5381414772713 Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Fri, 9 Jan 2026 18:55:50 +0530 Subject: [PATCH 1/9] feat: implement connector status management and warnings, ran frontend linting - Added a new hook `useConnectorStatus` to manage connector status information. - Introduced `ConnectorStatusBadge` and `ConnectorWarningBanner` components for displaying status and warnings. - Updated `ConnectorCard` and `ConnectorAccountsListView` to utilize the new status management features, including conditional rendering based on connector status and warnings. - Created a configuration file for connector statuses to streamline status management across the application. --- surfsense_web/components/Logo.tsx | 8 +- .../components/connector-card.tsx | 56 ++++++++- .../components/connector-status-badge.tsx | 62 ++++++++++ .../components/connector-warning-banner.tsx | 56 +++++++++ .../config/connector-status-config.ts | 114 ++++++++++++++++++ .../hooks/use-connector-status.ts | 63 ++++++++++ .../views/connector-accounts-list-view.tsx | 70 +++++++---- 7 files changed, 400 insertions(+), 29 deletions(-) create mode 100644 surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx create mode 100644 surfsense_web/components/assistant-ui/connector-popup/components/connector-warning-banner.tsx create mode 100644 surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts create mode 100644 surfsense_web/components/assistant-ui/connector-popup/hooks/use-connector-status.ts diff --git a/surfsense_web/components/Logo.tsx b/surfsense_web/components/Logo.tsx index 79799942b..58f8d1c9f 100644 --- a/surfsense_web/components/Logo.tsx +++ b/surfsense_web/components/Logo.tsx @@ -7,7 +7,13 @@ import { cn } from "@/lib/utils"; export const Logo = ({ className }: { className?: string }) => { return ( - logo + logo ); }; diff --git a/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx b/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx index e8fe6da33..43c03e03c 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx @@ -8,6 +8,8 @@ import { Button } from "@/components/ui/button"; import { getConnectorIcon } from "@/contracts/enums/connectorIcons"; import type { LogActiveTask } from "@/contracts/types/log.types"; import { cn } from "@/lib/utils"; +import { useConnectorStatus } from "../hooks/use-connector-status"; +import { ConnectorStatusBadge } from "./connector-status-badge"; interface ConnectorCardProps { id: string; @@ -104,6 +106,21 @@ export const ConnectorCard: FC = ({ onConnect, onManage, }) => { + // Get connector status + const { + getConnectorStatus, + isConnectorEnabled, + getConnectorWarning, + getConnectorStatusMessage, + shouldShowWarnings, + } = useConnectorStatus(); + + const status = getConnectorStatus(connectorType); + const isEnabled = isConnectorEnabled(connectorType); + const warning = getConnectorWarning(connectorType); + const statusMessage = getConnectorStatusMessage(connectorType); + const showWarnings = shouldShowWarnings(); + // Extract count from active task message during indexing const indexingCount = extractIndexedCount(activeTask?.message); @@ -123,6 +140,11 @@ export const ConnectorCard: FC = ({ ); } + // Show status message if available and connector is not connected + if (!isConnected && statusMessage) { + return {statusMessage}; + } + if (isConnected) { // Show last indexed date for connected connectors if (lastIndexedAt) { @@ -136,12 +158,35 @@ export const ConnectorCard: FC = ({ return Never indexed; } + // Show warning message if available and warnings are enabled + if (warning && showWarnings) { + return {warning}; + } + return description; }; return ( -
-
+
+
{connectorType ? ( getConnectorIcon(connectorType, "size-6") ) : id === "youtube-crawler" ? ( @@ -153,6 +198,9 @@ export const ConnectorCard: FC = ({
{title} + {showWarnings && status.status !== "active" && ( + + )}
{getStatusContent()}
{isConnected && documentCount !== undefined && ( @@ -179,10 +227,12 @@ export const ConnectorCard: FC = ({ !isConnected && "shadow-xs" )} onClick={isConnected ? onManage : onConnect} - disabled={isConnecting} + disabled={isConnecting || !isEnabled} > {isConnecting ? ( + ) : !isEnabled ? ( + "Unavailable" ) : isConnected ? ( "Manage" ) : id === "youtube-crawler" ? ( diff --git a/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx b/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx new file mode 100644 index 000000000..0fc48dfb1 --- /dev/null +++ b/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx @@ -0,0 +1,62 @@ +"use client"; + +import { AlertTriangle, Ban, Wrench } from "lucide-react"; +import type { FC } from "react"; +import type { ConnectorStatus } from "../config/connector-status-config"; +import { cn } from "@/lib/utils"; + +interface ConnectorStatusBadgeProps { + status: ConnectorStatus; + className?: string; +} + +export const ConnectorStatusBadge: FC = ({ status, className }) => { + if (status === "active") { + return null; + } + + const getBadgeConfig = () => { + switch (status) { + case "warning": + return { + icon: AlertTriangle, + className: "text-yellow-500 dark:text-yellow-400", + title: "Warning", + }; + case "disabled": + return { + icon: Ban, + className: "text-red-500 dark:text-red-400", + title: "Disabled", + }; + case "maintenance": + return { + icon: Wrench, + className: "text-orange-500 dark:text-orange-400", + title: "Maintenance", + }; + case "deprecated": + return { + icon: AlertTriangle, + className: "text-amber-500 dark:text-amber-400", + title: "Deprecated", + }; + default: + return null; + } + }; + + const config = getBadgeConfig(); + if (!config) return null; + + const Icon = config.icon; + + return ( +
+ +
+ ); +}; diff --git a/surfsense_web/components/assistant-ui/connector-popup/components/connector-warning-banner.tsx b/surfsense_web/components/assistant-ui/connector-popup/components/connector-warning-banner.tsx new file mode 100644 index 000000000..d1de3e37e --- /dev/null +++ b/surfsense_web/components/assistant-ui/connector-popup/components/connector-warning-banner.tsx @@ -0,0 +1,56 @@ +"use client"; + +import { AlertTriangle, X } from "lucide-react"; +import type { FC } from "react"; +import { useState } from "react"; +import { cn } from "@/lib/utils"; + +interface ConnectorWarningBannerProps { + warning: string; + statusMessage?: string | null; + onDismiss?: () => void; + className?: string; +} + +export const ConnectorWarningBanner: FC = ({ + warning, + statusMessage, + onDismiss, + className, +}) => { + const [isDismissed, setIsDismissed] = useState(false); + + if (isDismissed) return null; + + const handleDismiss = () => { + setIsDismissed(true); + onDismiss?.(); + }; + + return ( +
+ +
+

{warning}

+ {statusMessage && ( +

{statusMessage}

+ )} +
+ {onDismiss && ( + + )} +
+ ); +}; diff --git a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts new file mode 100644 index 000000000..5f3f1fee7 --- /dev/null +++ b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts @@ -0,0 +1,114 @@ +/** + * Connector Status Configuration + * + * This configuration allows managing connector statuses in the frontend without backend changes. + * Statuses control warnings, disabling connectors, and displaying status messages. + */ + +import { z } from "zod"; + +// Zod schemas for runtime validation and type safety +export const connectorStatusSchema = z.enum([ + "active", + "warning", + "disabled", + "deprecated", + "maintenance", +]); + +export const connectorStatusConfigSchema = z.object({ + enabled: z.boolean(), + status: connectorStatusSchema, + warning: z.string().nullable().optional(), + statusMessage: z.string().nullable().optional(), + disableReason: z.string().nullable().optional(), +}); + +export const connectorStatusMapSchema = z.record(z.string(), connectorStatusConfigSchema); + +export const connectorStatusConfigFileSchema = z.object({ + connectorStatuses: connectorStatusMapSchema, + globalSettings: z.object({ + showWarnings: z.boolean(), + allowManualOverride: z.boolean(), + }), +}); + +// TypeScript types inferred from Zod schemas +export type ConnectorStatus = z.infer; +export type ConnectorStatusConfig = z.infer; +export type ConnectorStatusMap = z.infer; +export type ConnectorStatusConfigFile = z.infer; + +/** + * Default status configuration for all connectors + * Connectors not listed here default to "active" and enabled + * + * This config is validated at runtime using the Zod schema above + */ +const rawConnectorStatusConfig = { + connectorStatuses: { + // Example: Disabled connector + // "SLACK_CONNECTOR": { + // enabled: false, + // status: "disabled", + // warning: null, + // statusMessage: "Slack connector is currently unavailable due to API changes", + // disableReason: "maintenance", + // }, + // Example: Connector with warning + // "NOTION_CONNECTOR": { + // enabled: true, + // status: "warning", + // warning: "Rate limits may apply", + // statusMessage: "Notion API rate limits are currently active. Some requests may be delayed.", + // disableReason: null, + // }, + // Example: Connector in maintenance + // "TEAMS_CONNECTOR": { + // enabled: false, + // status: "maintenance", + // warning: "Under maintenance", + // statusMessage: "Temporarily unavailable for maintenance", + // disableReason: "maintenance", + // }, + }, + globalSettings: { + showWarnings: true, + allowManualOverride: false, + }, +}; + +// Validate the config at module load time (development only) +// In production, this will throw if config is invalid +export const connectorStatusConfig: ConnectorStatusConfigFile = + connectorStatusConfigFileSchema.parse(rawConnectorStatusConfig); + +/** + * Get default status config for a connector (when not in config file) + * Returns a validated default config + */ +export function getDefaultConnectorStatus(): ConnectorStatusConfig { + return connectorStatusConfigSchema.parse({ + enabled: true, + status: "active", + warning: null, + statusMessage: null, + disableReason: null, + }); +} + +/** + * Validate a connector status config object + * Useful for validating config loaded from external sources + */ +export function validateConnectorStatusConfig(config: unknown): ConnectorStatusConfigFile { + return connectorStatusConfigFileSchema.parse(config); +} + +/** + * Validate a single connector status config + */ +export function validateSingleConnectorStatus(config: unknown): ConnectorStatusConfig { + return connectorStatusConfigSchema.parse(config); +} diff --git a/surfsense_web/components/assistant-ui/connector-popup/hooks/use-connector-status.ts b/surfsense_web/components/assistant-ui/connector-popup/hooks/use-connector-status.ts new file mode 100644 index 000000000..bb781c879 --- /dev/null +++ b/surfsense_web/components/assistant-ui/connector-popup/hooks/use-connector-status.ts @@ -0,0 +1,63 @@ +"use client"; + +import { useMemo } from "react"; +import { + type ConnectorStatusConfig, + connectorStatusConfig, + getDefaultConnectorStatus, +} from "../config/connector-status-config"; + +/** + * Hook to get connector status information + */ +export function useConnectorStatus() { + /** + * Get status configuration for a specific connector type + */ + const getConnectorStatus = (connectorType: string | undefined): ConnectorStatusConfig => { + if (!connectorType) { + return getDefaultConnectorStatus(); + } + + return connectorStatusConfig.connectorStatuses[connectorType] || getDefaultConnectorStatus(); + }; + + /** + * Check if a connector is enabled + */ + const isConnectorEnabled = (connectorType: string | undefined): boolean => { + return getConnectorStatus(connectorType).enabled; + }; + + /** + * Get warning message for a connector (if any) + */ + const getConnectorWarning = (connectorType: string | undefined): string | null => { + return getConnectorStatus(connectorType).warning || null; + }; + + /** + * Get status message for a connector + */ + const getConnectorStatusMessage = (connectorType: string | undefined): string | null => { + return getConnectorStatus(connectorType).statusMessage || null; + }; + + /** + * Check if warnings should be shown globally + */ + const shouldShowWarnings = (): boolean => { + return connectorStatusConfig.globalSettings.showWarnings; + }; + + return useMemo( + () => ({ + getConnectorStatus, + isConnectorEnabled, + getConnectorWarning, + getConnectorStatusMessage, + shouldShowWarnings, + }), + [] + ); +} diff --git a/surfsense_web/components/assistant-ui/connector-popup/views/connector-accounts-list-view.tsx b/surfsense_web/components/assistant-ui/connector-popup/views/connector-accounts-list-view.tsx index e45f24d11..df21c0eb5 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/views/connector-accounts-list-view.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/views/connector-accounts-list-view.tsx @@ -9,6 +9,8 @@ import type { SearchSourceConnector } from "@/contracts/types/connector.types"; import type { LogActiveTask, LogSummary } from "@/contracts/types/log.types"; import { cn } from "@/lib/utils"; import { getConnectorDisplayName } from "../tabs/all-connectors-tab"; +import { useConnectorStatus } from "../hooks/use-connector-status"; +import { ConnectorWarningBanner } from "../components/connector-warning-banner"; interface ConnectorAccountsListViewProps { connectorType: string; @@ -65,43 +67,57 @@ export const ConnectorAccountsListView: FC = ({ onAddAccount, isConnecting = false, }) => { + // Get connector status + const { isConnectorEnabled, getConnectorWarning, getConnectorStatusMessage, shouldShowWarnings } = + useConnectorStatus(); + + const isEnabled = isConnectorEnabled(connectorType); + const warning = getConnectorWarning(connectorType); + const statusMessage = getConnectorStatusMessage(connectorType); + const showWarnings = shouldShowWarnings(); + // Filter connectors to only show those of this type const typeConnectors = connectors.filter((c) => c.connector_type === connectorType); return (
{/* Header */} -
-
-
- -
-
- {getConnectorIcon(connectorType, "size-5")} -
-
-

{connectorTitle} Accounts

-

- {typeConnectors.length} connected account{typeConnectors.length !== 1 ? "s" : ""} -

-
+
+ {/* Back button */} + + + {/* Connector header */} +
+
+
+ {getConnectorIcon(connectorType, "size-7")} +
+
+

+ {connectorTitle} +

+

+ {statusMessage || "Manage your connector settings and sync configuration"} +

{/* Add Account Button with dashed border */}
{/* Content */} -
+
+ {/* Warning Banner */} + {warning && showWarnings && ( + + )} {/* Connected Accounts Grid */}
{typeConnectors.map((connector) => { From 207595bb335682afaf7343cd80b90cb3d4544be7 Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Fri, 9 Jan 2026 23:16:00 +0530 Subject: [PATCH 2/9] refactor: enhance connector card and status badge components - Updated `ConnectorCard` to prioritize displaying status messages over indexed dates and warnings. - Modified `ConnectorStatusBadge` to use a span instead of a div for better inline flexibility. - Adjusted styles in `ConnectorAccountsListView` for improved layout and spacing. - Cleaned up example status messages in the configuration file for clarity. --- .../connector-popup/components/connector-card.tsx | 13 +++++++------ .../components/connector-status-badge.tsx | 6 +++--- .../config/connector-status-config.ts | 7 ++----- .../views/connector-accounts-list-view.tsx | 14 +++++++------- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx b/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx index 43c03e03c..b302da2b5 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx @@ -140,13 +140,14 @@ export const ConnectorCard: FC = ({ ); } - // Show status message if available and connector is not connected - if (!isConnected && statusMessage) { + // Priority 1: Show status message if available (for both connected and disconnected connectors) + // This takes precedence over indexed dates and warnings + if (statusMessage) { return {statusMessage}; } if (isConnected) { - // Show last indexed date for connected connectors + // Show last indexed date for connected connectors (only if no status message) if (lastIndexedAt) { return ( @@ -158,7 +159,7 @@ export const ConnectorCard: FC = ({ return Never indexed; } - // Show warning message if available and warnings are enabled + // Show warning message if available and warnings are enabled (only if no status message) if (warning && showWarnings) { return {warning}; } @@ -196,10 +197,10 @@ export const ConnectorCard: FC = ({ )}
-
+
{title} {showWarnings && status.status !== "active" && ( - + )}
{getStatusContent()}
diff --git a/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx b/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx index 0fc48dfb1..15e9cadb8 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx @@ -52,11 +52,11 @@ export const ConnectorStatusBadge: FC = ({ status, cl const Icon = config.icon; return ( -
-
+ ); }; diff --git a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts index 5f3f1fee7..afad6e1c8 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts +++ b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts @@ -48,23 +48,20 @@ export type ConnectorStatusConfigFile = z.infer = ({ return (
{/* Header */} -
+
{/* Back button */} @@ -136,7 +136,7 @@ export const ConnectorAccountsListView: FC = ({
{/* Content */} -
+
{/* Warning Banner */} {warning && showWarnings && ( From b0043b6446abed533bccc879df283138422604b6 Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Fri, 9 Jan 2026 23:30:33 +0530 Subject: [PATCH 3/9] refactor: streamline connector status handling and remove warnings - Removed the warning message handling from `useConnectorStatus` and related components to simplify status management. - Updated `ConnectorCard` and `ConnectorAccountsListView` to eliminate warning displays, focusing on status messages instead. - Adjusted the connector status configuration to remove warning properties, enhancing clarity and reducing complexity. --- .../components/connector-card.tsx | 7 --- .../config/connector-status-config.ts | 44 +++++++------------ .../hooks/use-connector-status.ts | 8 ---- .../views/connector-accounts-list-view.tsx | 10 +---- 4 files changed, 18 insertions(+), 51 deletions(-) diff --git a/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx b/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx index b302da2b5..a3aee33b0 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx @@ -110,14 +110,12 @@ export const ConnectorCard: FC = ({ const { getConnectorStatus, isConnectorEnabled, - getConnectorWarning, getConnectorStatusMessage, shouldShowWarnings, } = useConnectorStatus(); const status = getConnectorStatus(connectorType); const isEnabled = isConnectorEnabled(connectorType); - const warning = getConnectorWarning(connectorType); const statusMessage = getConnectorStatusMessage(connectorType); const showWarnings = shouldShowWarnings(); @@ -159,11 +157,6 @@ export const ConnectorCard: FC = ({ return Never indexed; } - // Show warning message if available and warnings are enabled (only if no status message) - if (warning && showWarnings) { - return {warning}; - } - return description; }; diff --git a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts index afad6e1c8..e6586e110 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts +++ b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts @@ -1,8 +1,8 @@ /** * Connector Status Configuration * - * This configuration allows managing connector statuses in the frontend without backend changes. - * Statuses control warnings, disabling connectors, and displaying status messages. + * This configuration allows managing connector statuses. + * Statuses control disabling connectors and displaying status messages. */ import { z } from "zod"; @@ -19,9 +19,7 @@ export const connectorStatusSchema = z.enum([ export const connectorStatusConfigSchema = z.object({ enabled: z.boolean(), status: connectorStatusSchema, - warning: z.string().nullable().optional(), statusMessage: z.string().nullable().optional(), - disableReason: z.string().nullable().optional(), }); export const connectorStatusMapSchema = z.record(z.string(), connectorStatusConfigSchema); @@ -48,27 +46,21 @@ export type ConnectorStatusConfigFile = z.infer { - return getConnectorStatus(connectorType).warning || null; - }; - /** * Get status message for a connector */ @@ -54,7 +47,6 @@ export function useConnectorStatus() { () => ({ getConnectorStatus, isConnectorEnabled, - getConnectorWarning, getConnectorStatusMessage, shouldShowWarnings, }), diff --git a/surfsense_web/components/assistant-ui/connector-popup/views/connector-accounts-list-view.tsx b/surfsense_web/components/assistant-ui/connector-popup/views/connector-accounts-list-view.tsx index 34bc97f4e..74dd51929 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/views/connector-accounts-list-view.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/views/connector-accounts-list-view.tsx @@ -10,7 +10,6 @@ import type { LogActiveTask, LogSummary } from "@/contracts/types/log.types"; import { cn } from "@/lib/utils"; import { getConnectorDisplayName } from "../tabs/all-connectors-tab"; import { useConnectorStatus } from "../hooks/use-connector-status"; -import { ConnectorWarningBanner } from "../components/connector-warning-banner"; interface ConnectorAccountsListViewProps { connectorType: string; @@ -68,13 +67,10 @@ export const ConnectorAccountsListView: FC = ({ isConnecting = false, }) => { // Get connector status - const { isConnectorEnabled, getConnectorWarning, getConnectorStatusMessage, shouldShowWarnings } = - useConnectorStatus(); + const { isConnectorEnabled, getConnectorStatusMessage } = useConnectorStatus(); const isEnabled = isConnectorEnabled(connectorType); - const warning = getConnectorWarning(connectorType); const statusMessage = getConnectorStatusMessage(connectorType); - const showWarnings = shouldShowWarnings(); // Filter connectors to only show those of this type const typeConnectors = connectors.filter((c) => c.connector_type === connectorType); @@ -137,10 +133,6 @@ export const ConnectorAccountsListView: FC = ({ {/* Content */}
- {/* Warning Banner */} - {warning && showWarnings && ( - - )} {/* Connected Accounts Grid */}
{typeConnectors.map((connector) => { From 180fff7105eab9421243bbf133f1a8d1953756fe Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Fri, 9 Jan 2026 23:38:38 +0530 Subject: [PATCH 4/9] feat: enhance connector card and status badge with tooltip support - Added tooltip functionality to `ConnectorCard` for displaying status messages on disabled or maintenance connectors. - Updated `ConnectorStatusBadge` to show status messages in tooltips for warning statuses, improving user feedback. - Refactored rendering logic to ensure tooltips are displayed appropriately based on connector status. --- .../components/connector-card.tsx | 38 +++++++++++++----- .../components/connector-status-badge.tsx | 40 ++++++++++++++++--- 2 files changed, 63 insertions(+), 15 deletions(-) diff --git a/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx b/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx index a3aee33b0..b5b76c253 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx @@ -5,6 +5,7 @@ import { differenceInDays, differenceInMinutes, format, isToday, isYesterday } f import { FileText, Loader2 } from "lucide-react"; import type { FC } from "react"; import { Button } from "@/components/ui/button"; +import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { getConnectorIcon } from "@/contracts/enums/connectorIcons"; import type { LogActiveTask } from "@/contracts/types/log.types"; import { cn } from "@/lib/utils"; @@ -138,14 +139,8 @@ export const ConnectorCard: FC = ({ ); } - // Priority 1: Show status message if available (for both connected and disconnected connectors) - // This takes precedence over indexed dates and warnings - if (statusMessage) { - return {statusMessage}; - } - if (isConnected) { - // Show last indexed date for connected connectors (only if no status message) + // Show last indexed date for connected connectors if (lastIndexedAt) { return ( @@ -160,7 +155,12 @@ export const ConnectorCard: FC = ({ return description; }; - return ( + // Determine if we should show tooltip on the whole card (for disabled/maintenance) + const shouldShowCardTooltip = + statusMessage && + (status.status === "disabled" || status.status === "maintenance"); + + const cardContent = (
= ({
{title} {showWarnings && status.status !== "active" && ( - + )}
{getStatusContent()}
@@ -239,4 +243,20 @@ export const ConnectorCard: FC = ({
); + + // Wrap card in tooltip for disabled/maintenance status + if (shouldShowCardTooltip) { + return ( + + + {cardContent} + + + {statusMessage} + + + ); + } + + return cardContent; }; diff --git a/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx b/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx index 15e9cadb8..8549ebc47 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx @@ -2,15 +2,21 @@ import { AlertTriangle, Ban, Wrench } from "lucide-react"; import type { FC } from "react"; +import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import type { ConnectorStatus } from "../config/connector-status-config"; import { cn } from "@/lib/utils"; interface ConnectorStatusBadgeProps { status: ConnectorStatus; + statusMessage?: string | null; className?: string; } -export const ConnectorStatusBadge: FC = ({ status, className }) => { +export const ConnectorStatusBadge: FC = ({ + status, + statusMessage, + className, +}) => { if (status === "active") { return null; } @@ -21,25 +27,25 @@ export const ConnectorStatusBadge: FC = ({ status, cl return { icon: AlertTriangle, className: "text-yellow-500 dark:text-yellow-400", - title: "Warning", + defaultTitle: "Warning", }; case "disabled": return { icon: Ban, className: "text-red-500 dark:text-red-400", - title: "Disabled", + defaultTitle: "Disabled", }; case "maintenance": return { icon: Wrench, className: "text-orange-500 dark:text-orange-400", - title: "Maintenance", + defaultTitle: "Maintenance", }; case "deprecated": return { icon: AlertTriangle, className: "text-amber-500 dark:text-amber-400", - title: "Deprecated", + defaultTitle: "Deprecated", }; default: return null; @@ -50,11 +56,33 @@ export const ConnectorStatusBadge: FC = ({ status, cl if (!config) return null; const Icon = config.icon; + // Only show statusMessage in tooltip for warning status + // For disabled/maintenance, the card tooltip will show the statusMessage + const shouldUseTooltip = status === "warning" && statusMessage; + const tooltipTitle = shouldUseTooltip ? statusMessage : config.defaultTitle; + + // Use Tooltip component for warning status with statusMessage, native title for others + if (shouldUseTooltip) { + return ( + + + + + + + + {statusMessage} + + + ); + } return ( From f52440977fba3605645177748e0bb145e385c362 Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Sun, 11 Jan 2026 16:08:23 +0530 Subject: [PATCH 5/9] fix: disable breadcrumb on mobile view --- surfsense_web/components/layout/ui/header/Header.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/surfsense_web/components/layout/ui/header/Header.tsx b/surfsense_web/components/layout/ui/header/Header.tsx index a03761ef5..0bdb9b423 100644 --- a/surfsense_web/components/layout/ui/header/Header.tsx +++ b/surfsense_web/components/layout/ui/header/Header.tsx @@ -24,7 +24,7 @@ export function Header({ {/* Left side - Mobile menu trigger + Breadcrumb */}
{mobileMenuTrigger} - {breadcrumb} +
{breadcrumb}
{/* Right side - Actions */} From 075bb44731952f9dc400d72b11c45f16e3e86a31 Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Sun, 11 Jan 2026 16:12:28 +0530 Subject: [PATCH 6/9] chore: ran frontend linting --- .../connector-popup/components/connector-card.tsx | 15 ++++----------- .../components/connector-status-badge.tsx | 4 +--- .../config/connector-status-config.ts | 6 +++--- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx b/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx index b5b76c253..a9a33e8b3 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx @@ -108,12 +108,8 @@ export const ConnectorCard: FC = ({ onManage, }) => { // Get connector status - const { - getConnectorStatus, - isConnectorEnabled, - getConnectorStatusMessage, - shouldShowWarnings, - } = useConnectorStatus(); + const { getConnectorStatus, isConnectorEnabled, getConnectorStatusMessage, shouldShowWarnings } = + useConnectorStatus(); const status = getConnectorStatus(connectorType); const isEnabled = isConnectorEnabled(connectorType); @@ -157,8 +153,7 @@ export const ConnectorCard: FC = ({ // Determine if we should show tooltip on the whole card (for disabled/maintenance) const shouldShowCardTooltip = - statusMessage && - (status.status === "disabled" || status.status === "maintenance"); + statusMessage && (status.status === "disabled" || status.status === "maintenance"); const cardContent = (
= ({ if (shouldShowCardTooltip) { return ( - - {cardContent} - + {cardContent} {statusMessage} diff --git a/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx b/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx index 8549ebc47..4b83292bd 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx @@ -66,9 +66,7 @@ export const ConnectorStatusBadge: FC = ({ return ( - + diff --git a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts index e6586e110..42d5c4d76 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts +++ b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts @@ -46,17 +46,17 @@ export type ConnectorStatusConfigFile = z.infer Date: Sun, 11 Jan 2026 16:13:48 +0530 Subject: [PATCH 7/9] refactor: update connector status configuration to use commented example configs --- .../config/connector-status-config.ts | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts index 42d5c4d76..a3745df48 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts +++ b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts @@ -46,21 +46,22 @@ export type ConnectorStatusConfigFile = z.infer Date: Sun, 11 Jan 2026 16:53:54 +0530 Subject: [PATCH 8/9] feat: add json files for status badges --- .../components/connector-card.tsx | 33 +++------------ .../components/connector-status-badge.tsx | 11 ++--- .../connector-status-config.example.json | 29 ++++++++++++++ .../config/connector-status-config.json | 10 +++++ .../config/connector-status-config.ts | 40 +++---------------- 5 files changed, 57 insertions(+), 66 deletions(-) create mode 100644 surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.example.json create mode 100644 surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.json diff --git a/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx b/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx index a9a33e8b3..fa4b8feb6 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/components/connector-card.tsx @@ -5,7 +5,6 @@ import { differenceInDays, differenceInMinutes, format, isToday, isYesterday } f import { FileText, Loader2 } from "lucide-react"; import type { FC } from "react"; import { Button } from "@/components/ui/button"; -import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { getConnectorIcon } from "@/contracts/enums/connectorIcons"; import type { LogActiveTask } from "@/contracts/types/log.types"; import { cn } from "@/lib/utils"; @@ -151,29 +150,21 @@ export const ConnectorCard: FC = ({ return description; }; - // Determine if we should show tooltip on the whole card (for disabled/maintenance) - const shouldShowCardTooltip = - statusMessage && (status.status === "disabled" || status.status === "maintenance"); - const cardContent = (
{connectorType ? ( @@ -239,17 +230,5 @@ export const ConnectorCard: FC = ({
); - // Wrap card in tooltip for disabled/maintenance status - if (shouldShowCardTooltip) { - return ( - - {cardContent} - - {statusMessage} - - - ); - } - return cardContent; }; diff --git a/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx b/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx index 4b83292bd..a5fd0c331 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx @@ -44,7 +44,7 @@ export const ConnectorStatusBadge: FC = ({ case "deprecated": return { icon: AlertTriangle, - className: "text-amber-500 dark:text-amber-400", + className: "ext-slate-500 dark:text-slate-400", defaultTitle: "Deprecated", }; default: @@ -56,12 +56,13 @@ export const ConnectorStatusBadge: FC = ({ if (!config) return null; const Icon = config.icon; - // Only show statusMessage in tooltip for warning status - // For disabled/maintenance, the card tooltip will show the statusMessage - const shouldUseTooltip = status === "warning" && statusMessage; + // Show statusMessage in tooltip for warning, deprecated, disabled, and maintenance statuses + const shouldUseTooltip = + (status === "warning" || status === "deprecated" || status === "disabled" || status === "maintenance") && + statusMessage; const tooltipTitle = shouldUseTooltip ? statusMessage : config.defaultTitle; - // Use Tooltip component for warning status with statusMessage, native title for others + // Use Tooltip component for statuses with statusMessage, native title for others if (shouldUseTooltip) { return ( diff --git a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.example.json b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.example.json new file mode 100644 index 000000000..e239e3e23 --- /dev/null +++ b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.example.json @@ -0,0 +1,29 @@ +{ + "connectorStatuses": { + "SLACK_CONNECTOR": { + "enabled": false, + "status": "disabled", + "statusMessage": "Unavailable due to API changes" + }, + "NOTION_CONNECTOR": { + "enabled": true, + "status": "warning", + "statusMessage": "Rate limits may apply" + }, + "TEAMS_CONNECTOR": { + "enabled": false, + "status": "maintenance", + "statusMessage": "Temporarily unavailable for maintenance" + }, + "JIRA_CONNECTOR": { + "enabled": false, + "status": "deprecated", + "statusMessage": "Deprecated" + } + }, + "globalSettings": { + "showWarnings": true, + "allowManualOverride": false + } +} + diff --git a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.json b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.json new file mode 100644 index 000000000..13b227a16 --- /dev/null +++ b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.json @@ -0,0 +1,10 @@ +{ + "connectorStatuses": { + + }, + "globalSettings": { + "showWarnings": true, + "allowManualOverride": false + } +} + diff --git a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts index a3745df48..06e98d927 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts +++ b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.ts @@ -1,11 +1,13 @@ /** * Connector Status Configuration * - * This configuration allows managing connector statuses. - * Statuses control disabling connectors and displaying status messages. + * Manages connector statuses (disable/enable, status messages). Edit connector-status-config.json to configure. + * Valid status values: "active", "warning", "disabled", "deprecated", "maintenance". + * Unlisted connectors default to "active" and enabled. See connector-status-config.example.json for reference. */ import { z } from "zod"; +import rawConnectorStatusConfigData from "./connector-status-config.json"; // Zod schemas for runtime validation and type safety export const connectorStatusSchema = z.enum([ @@ -39,40 +41,10 @@ export type ConnectorStatusMap = z.infer; export type ConnectorStatusConfigFile = z.infer; /** - * Default status configuration for all connectors - * Connectors not listed here default to "active" and enabled - * - * This config is validated at runtime using the Zod schema above + * Validated at runtime via Zod schema; invalid JSON throws at module load time. */ -const rawConnectorStatusConfig = { - connectorStatuses: { - // Example configs to use - // SLACK_CONNECTOR: { - // enabled: false, - // status: "disabled", - // statusMessage: "Unavailable due to API changes", - // }, - // NOTION_CONNECTOR: { - // enabled: true, - // status: "warning", - // statusMessage: "Rate limits may apply", - // }, - // TEAMS_CONNECTOR: { - // enabled: false, - // status: "maintenance", - // statusMessage: "Temporarily unavailable for maintenance", - // }, - }, - globalSettings: { - showWarnings: true, - allowManualOverride: false, - }, -}; - -// Validate the config at module load time (development only) -// In production, this will throw if config is invalid export const connectorStatusConfig: ConnectorStatusConfigFile = - connectorStatusConfigFileSchema.parse(rawConnectorStatusConfig); + connectorStatusConfigFileSchema.parse(rawConnectorStatusConfigData); /** * Get default status config for a connector (when not in config file) From b53d095ab9a11fd3ad10e7fc17e304dae545078c Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Sun, 11 Jan 2026 16:56:11 +0530 Subject: [PATCH 9/9] chore: ran frontend linting --- .../connector-popup/components/connector-status-badge.tsx | 5 ++++- .../config/connector-status-config.example.json | 1 - .../connector-popup/config/connector-status-config.json | 5 +---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx b/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx index a5fd0c331..ecc3a11cd 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/components/connector-status-badge.tsx @@ -58,7 +58,10 @@ export const ConnectorStatusBadge: FC = ({ const Icon = config.icon; // Show statusMessage in tooltip for warning, deprecated, disabled, and maintenance statuses const shouldUseTooltip = - (status === "warning" || status === "deprecated" || status === "disabled" || status === "maintenance") && + (status === "warning" || + status === "deprecated" || + status === "disabled" || + status === "maintenance") && statusMessage; const tooltipTitle = shouldUseTooltip ? statusMessage : config.defaultTitle; diff --git a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.example.json b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.example.json index e239e3e23..ad2a914f3 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.example.json +++ b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.example.json @@ -26,4 +26,3 @@ "allowManualOverride": false } } - diff --git a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.json b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.json index 13b227a16..470ff22e9 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.json +++ b/surfsense_web/components/assistant-ui/connector-popup/config/connector-status-config.json @@ -1,10 +1,7 @@ { - "connectorStatuses": { - - }, + "connectorStatuses": {}, "globalSettings": { "showWarnings": true, "allowManualOverride": false } } -