Merge branch 'dev' into fix/env-config-connector-forms

This commit is contained in:
Varun Shukla 2026-05-20 03:26:12 +05:30 committed by GitHub
commit 81ce9e4071
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
291 changed files with 8271 additions and 7022 deletions

View file

@ -166,10 +166,10 @@ export const CirclebackConfig: FC<CirclebackConfigProps> = ({ connector, onNameC
)}
{webhookInfo && (
<Alert className="bg-slate-400/5 dark:bg-white/5 border-slate-400/20">
<Info className="h-3 w-3 sm:h-4 sm:w-4" />
<AlertTitle className="text-xs sm:text-sm">Configuration Instructions</AlertTitle>
<AlertDescription className="text-[10px] sm:text-xs mt-1">
<Alert>
<Info />
<AlertTitle>Configuration Instructions</AlertTitle>
<AlertDescription>
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.

View file

@ -3,6 +3,7 @@
import { Info, KeyRound } from "lucide-react";
import type { FC } from "react";
import { useState } from "react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import type { ConnectorConfigProps } from "../index";
@ -47,21 +48,17 @@ export const ClickUpConfig: FC<ClickUpConfigProps> = ({
return (
<div className="space-y-6">
{/* OAuth Info */}
<div className="rounded-xl border border-border bg-primary/5 p-4 flex items-start gap-3">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 shrink-0 mt-0.5">
<Info className="size-4" />
</div>
<div className="text-xs sm:text-sm">
<p className="font-medium text-xs sm:text-sm">Connected via OAuth</p>
<p className="text-muted-foreground mt-1 text-[10px] sm:text-sm">
<Alert>
<Info />
<AlertTitle>Connected via OAuth</AlertTitle>
<AlertDescription>
<p>
Workspace:{" "}
<code className="bg-muted px-1 py-0.5 rounded text-inherit">{workspaceName}</code>
</p>
<p className="text-muted-foreground mt-1 text-[10px] sm:text-sm">
To update your connection, reconnect this connector.
</p>
</div>
</div>
<p>To update your connection, reconnect this connector.</p>
</AlertDescription>
</Alert>
</div>
);
}

View file

@ -14,6 +14,7 @@ import {
import type { FC } from "react";
import { useCallback, useState } from "react";
import { DriveFolderTree, type SelectedFolder } from "@/components/connectors/drive-folder-tree";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import {
Select,
@ -196,14 +197,16 @@ export const ComposioDriveConfig: FC<ConnectorConfigProps> = ({ connector, onCon
>
<FolderClosed className="size-3.5 shrink-0 text-muted-foreground" />
<span className="flex-1 truncate">{folder.name}</span>
<button
<Button
type="button"
variant="ghost"
size="icon"
onClick={() => handleRemoveFolder(folder.id)}
className="shrink-0 p-0.5 hover:bg-muted-foreground/20 rounded transition-colors"
className="size-5 shrink-0 rounded p-0 hover:bg-accent hover:text-accent-foreground"
aria-label={`Remove ${folder.name}`}
>
<X className="size-3.5" />
</button>
</Button>
</div>
))}
{selectedFiles.map((file) => (
@ -214,14 +217,16 @@ export const ComposioDriveConfig: FC<ConnectorConfigProps> = ({ connector, onCon
>
{getFileIconFromName(file.name)}
<span className="flex-1 truncate">{file.name}</span>
<button
<Button
type="button"
variant="ghost"
size="icon"
onClick={() => handleRemoveFile(file.id)}
className="shrink-0 p-0.5 hover:bg-muted-foreground/20 rounded transition-colors"
className="size-5 shrink-0 rounded p-0 hover:bg-accent hover:text-accent-foreground"
aria-label={`Remove ${file.name}`}
>
<X className="size-3.5" />
</button>
</Button>
</div>
))}
</div>
@ -237,10 +242,11 @@ export const ComposioDriveConfig: FC<ConnectorConfigProps> = ({ connector, onCon
{isEditMode ? (
<div className="space-y-2">
<button
<Button
type="button"
variant="ghost"
onClick={() => setIsFolderTreeOpen((prev) => !prev)}
className="flex items-center gap-2 text-xs sm:text-sm text-muted-foreground hover:text-foreground transition-colors w-fit"
className="h-auto w-fit gap-2 px-0 py-0 text-xs font-normal text-muted-foreground hover:bg-transparent hover:text-accent-foreground sm:text-sm"
>
Change Selection
{isFolderTreeOpen ? (
@ -248,7 +254,7 @@ export const ComposioDriveConfig: FC<ConnectorConfigProps> = ({ connector, onCon
) : (
<ChevronRight className="size-4" />
)}
</button>
</Button>
{isFolderTreeOpen && (
<DriveFolderTree
fetchItems={fetchItems}

View file

@ -3,6 +3,7 @@
import { Info, KeyRound } from "lucide-react";
import type { FC } from "react";
import { useState } from "react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import type { ConnectorConfigProps } from "../index";
@ -72,23 +73,17 @@ export const ConfluenceConfig: FC<ConfluenceConfigProps> = ({
return (
<div className="space-y-6">
{/* OAuth Info */}
<div className="rounded-xl border border-border bg-primary/5 p-4 flex items-start gap-3">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 shrink-0 mt-0.5">
<Info className="size-4" />
</div>
<div className="text-xs sm:text-sm">
<p className="font-medium text-xs sm:text-sm">Connected via OAuth</p>
<p className="text-muted-foreground mt-1 text-[10px] sm:text-sm">
This connector is authenticated using OAuth 2.0. Your Confluence instance is:
</p>
<p className="text-muted-foreground mt-1 text-[10px] sm:text-sm">
<Alert>
<Info />
<AlertTitle>Connected via OAuth</AlertTitle>
<AlertDescription>
<p>This connector is authenticated using OAuth 2.0. Your Confluence instance is:</p>
<p>
<code className="bg-muted px-1 py-0.5 rounded text-inherit">{siteUrl}</code>
</p>
<p className="text-muted-foreground mt-1 text-[10px] sm:text-sm">
To update your connection, reconnect this connector.
</p>
</div>
</div>
<p>To update your connection, reconnect this connector.</p>
</AlertDescription>
</Alert>
</div>
);
}

View file

@ -2,6 +2,7 @@
import { AlertCircle, CheckCircle2, Hash, Info, Megaphone, RefreshCw } from "lucide-react";
import { type FC, useCallback, useEffect, useState } from "react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
import { connectorsApiService, type DiscordChannel } from "@/lib/apis/connectors-api.service";
@ -73,17 +74,14 @@ export const DiscordConfig: FC<DiscordConfigProps> = ({ connector }) => {
return (
<div className="space-y-6">
{/* Info box */}
<div className="rounded-xl border border-border bg-primary/5 p-4 flex items-start gap-3">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 shrink-0 mt-0.5">
<Info className="size-4" />
</div>
<div className="text-xs sm:text-sm">
<p className="text-muted-foreground mt-1 text-[10px] sm:text-sm">
The bot needs &quot;Read Message History&quot; permission to access channels. Ask a
server admin to grant this permission for channels shown below.
</p>
</div>
</div>
<Alert>
<Info />
<AlertTitle>Grant Channel Permissions</AlertTitle>
<AlertDescription>
The bot needs &quot;Read Message History&quot; permission to access channels. Ask a server
admin to grant this permission for channels shown below.
</AlertDescription>
</Alert>
{/* Channels Section */}
<div className="space-y-3">
@ -100,7 +98,7 @@ export const DiscordConfig: FC<DiscordConfigProps> = ({ connector }) => {
size="sm"
onClick={fetchChannels}
disabled={isLoading}
className="h-7 px-2.5 text-[11px] bg-slate-400/10 dark:bg-white/10 hover:bg-slate-400/20 dark:hover:bg-white/20 border-slate-400/20 dark:border-white/20"
className="h-7 px-2.5 text-[11px] bg-slate-400/10 dark:bg-white/10 hover:bg-accent hover:text-accent-foreground border-slate-400/20 dark:border-white/20"
>
<RefreshCw className={cn("mr-1.5 size-3", isLoading && "animate-spin")} />
Refresh
@ -175,7 +173,7 @@ interface ChannelPillProps {
const ChannelPill: FC<ChannelPillProps> = ({ channel }) => {
return (
<div className="inline-flex items-center gap-1 px-2 py-1 rounded-md text-[11px] font-medium bg-slate-400/10 dark:bg-white/10 hover:bg-slate-400/20 dark:hover:bg-white/20 transition-colors">
<div className="inline-flex items-center gap-1 px-2 py-1 rounded-md text-[11px] font-medium bg-slate-400/10 dark:bg-white/10 hover:bg-accent hover:text-accent-foreground transition-colors">
{channel.type === "announcement" ? (
<Megaphone className="size-2.5 text-muted-foreground" />
) : (

View file

@ -14,6 +14,7 @@ import {
import type { FC } from "react";
import { useCallback, useEffect, useState } from "react";
import { DriveFolderTree, type SelectedFolder } from "@/components/connectors/drive-folder-tree";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import {
Select,
@ -177,14 +178,16 @@ export const DropboxConfig: FC<ConnectorConfigProps> = ({ connector, onConfigCha
>
<FolderClosed className="size-3.5 shrink-0 text-muted-foreground" />
<span className="flex-1 truncate">{folder.name}</span>
<button
<Button
type="button"
variant="ghost"
size="icon"
onClick={() => handleRemoveFolder(folder.id)}
className="shrink-0 p-0.5 hover:bg-muted-foreground/20 rounded transition-colors"
className="size-5 shrink-0 rounded p-0 hover:bg-accent hover:text-accent-foreground"
aria-label={`Remove ${folder.name}`}
>
<X className="size-3.5" />
</button>
</Button>
</div>
))}
{selectedFiles.map((file) => (
@ -195,14 +198,16 @@ export const DropboxConfig: FC<ConnectorConfigProps> = ({ connector, onConfigCha
>
{getFileIconFromName(file.name)}
<span className="flex-1 truncate">{file.name}</span>
<button
<Button
type="button"
variant="ghost"
size="icon"
onClick={() => handleRemoveFile(file.id)}
className="shrink-0 p-0.5 hover:bg-muted-foreground/20 rounded transition-colors"
className="size-5 shrink-0 rounded p-0 hover:bg-accent hover:text-accent-foreground"
aria-label={`Remove ${file.name}`}
>
<X className="size-3.5" />
</button>
</Button>
</div>
))}
</div>
@ -217,10 +222,11 @@ export const DropboxConfig: FC<ConnectorConfigProps> = ({ connector, onConfigCha
{isEditMode ? (
<div className="space-y-2">
<button
<Button
type="button"
variant="ghost"
onClick={() => setIsFolderTreeOpen(!isFolderTreeOpen)}
className="flex items-center gap-2 text-xs sm:text-sm text-muted-foreground hover:text-foreground transition-colors w-fit"
className="h-auto w-fit gap-2 px-0 py-0 text-xs font-normal text-muted-foreground hover:bg-transparent hover:text-accent-foreground sm:text-sm"
>
Change Selection
{isFolderTreeOpen ? (
@ -228,7 +234,7 @@ export const DropboxConfig: FC<ConnectorConfigProps> = ({ connector, onConfigCha
) : (
<ChevronRight className="size-4" />
)}
</button>
</Button>
{isFolderTreeOpen && (
<DriveFolderTree
fetchItems={fetchItems}

View file

@ -92,20 +92,19 @@ export const GoogleDriveConfig: FC<ConnectorConfigProps> = ({ connector, onConfi
const [selectedFiles, setSelectedFiles] = useState<SelectedItem[]>(existingFiles);
const [indexingOptions, setIndexingOptions] = useState<IndexingOptions>(existingIndexingOptions);
const updateConfig = (
folders: SelectedItem[],
files: SelectedItem[],
options: IndexingOptions
) => {
if (onConfigChange) {
onConfigChange({
...connector.config,
selected_folders: folders,
selected_files: files,
indexing_options: options,
});
}
};
const updateConfig = useCallback(
(folders: SelectedItem[], files: SelectedItem[], options: IndexingOptions) => {
if (onConfigChange) {
onConfigChange({
...connector.config,
selected_folders: folders,
selected_files: files,
indexing_options: options,
});
}
},
[connector.config, onConfigChange]
);
const handlePicked = useCallback(
(result: PickerResult) => {
@ -115,8 +114,7 @@ export const GoogleDriveConfig: FC<ConnectorConfigProps> = ({ connector, onConfi
setSelectedFiles(files);
updateConfig(folders, files, indexingOptions);
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[indexingOptions, connector.config]
[indexingOptions, updateConfig]
);
const {
@ -188,14 +186,16 @@ export const GoogleDriveConfig: FC<ConnectorConfigProps> = ({ connector, onConfi
>
<FolderClosed className="size-3.5 shrink-0 text-muted-foreground" />
<span className="flex-1 truncate">{folder.name}</span>
<button
<Button
type="button"
variant="ghost"
size="icon"
onClick={() => handleRemoveFolder(folder.id)}
className="shrink-0 p-0.5 hover:bg-muted-foreground/20 rounded transition-colors"
className="size-5 shrink-0 rounded p-0 hover:bg-accent hover:text-accent-foreground"
aria-label={`Remove ${folder.name}`}
>
<X className="size-3.5" />
</button>
</Button>
</div>
))}
{selectedFiles.map((file) => (
@ -206,14 +206,16 @@ export const GoogleDriveConfig: FC<ConnectorConfigProps> = ({ connector, onConfi
>
{getFileIconFromName(file.name)}
<span className="flex-1 truncate">{file.name}</span>
<button
<Button
type="button"
variant="ghost"
size="icon"
onClick={() => handleRemoveFile(file.id)}
className="shrink-0 p-0.5 hover:bg-muted-foreground/20 rounded transition-colors"
className="size-5 shrink-0 rounded p-0 hover:bg-accent hover:text-accent-foreground"
aria-label={`Remove ${file.name}`}
>
<X className="size-3.5" />
</button>
</Button>
</div>
))}
</div>
@ -225,7 +227,7 @@ export const GoogleDriveConfig: FC<ConnectorConfigProps> = ({ connector, onConfi
variant="outline"
onClick={openPicker}
disabled={pickerLoading || isAuthExpired}
className="bg-slate-400/5 dark:bg-white/5 border-slate-400/20 hover:bg-slate-400/10 dark:hover:bg-white/10 text-xs sm:text-sm h-8 sm:h-9"
className="bg-slate-400/5 dark:bg-white/5 border-slate-400/20 hover:bg-accent hover:text-accent-foreground text-xs sm:text-sm h-8 sm:h-9"
>
{pickerLoading && <Spinner size="xs" className="mr-1.5" />}
{totalSelected > 0 ? "Change Selection" : "Select from Google Drive"}

View file

@ -3,6 +3,7 @@
import { Info, KeyRound } from "lucide-react";
import type { FC } from "react";
import { useState } from "react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import type { ConnectorConfigProps } from "../index";
@ -65,23 +66,17 @@ export const JiraConfig: FC<JiraConfigProps> = ({ connector, onConfigChange, onN
return (
<div className="space-y-6">
{/* OAuth Info */}
<div className="rounded-xl border border-border bg-primary/5 p-4 flex items-start gap-3">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 shrink-0 mt-0.5">
<Info className="size-4" />
</div>
<div className="text-xs sm:text-sm">
<p className="font-medium text-xs sm:text-sm">Connected via OAuth</p>
<p className="text-muted-foreground mt-1 text-[10px] sm:text-sm">
This connector is authenticated using OAuth 2.0. Your Jira instance is:
</p>
<p className="text-muted-foreground mt-1 text-[10px] sm:text-sm">
<Alert>
<Info />
<AlertTitle>Connected via OAuth</AlertTitle>
<AlertDescription>
<p>This connector is authenticated using OAuth 2.0. Your Jira instance is:</p>
<p>
<code className="bg-muted px-1 py-0.5 rounded text-inherit">{baseUrl}</code>
</p>
<p className="text-muted-foreground mt-1 text-[10px] sm:text-sm">
To update your connection, reconnect this connector.
</p>
</div>
</div>
<p>To update your connection, reconnect this connector.</p>
</AlertDescription>
</Alert>
</div>
);
}

View file

@ -215,7 +215,7 @@ export const MCPConfig: FC<MCPConfigProps> = ({ connector, onConfigChange, onNam
onClick={handleTestConnection}
disabled={isTesting}
variant="secondary"
className="w-full h-8 text-[13px] px-3 rounded-lg font-medium bg-white text-slate-700 hover:bg-slate-50 border-0 shadow-xs dark:bg-secondary dark:text-secondary-foreground dark:hover:bg-secondary/80"
className="w-full h-8 text-[13px] px-3 font-medium bg-white text-slate-700 hover:bg-accent hover:text-accent-foreground border-0 shadow-xs dark:bg-secondary dark:text-secondary-foreground"
>
{isTesting ? (
<>

View file

@ -47,12 +47,10 @@ export const ObsidianConfig: FC<ConnectorConfigProps> = ({ connector }) => {
const LegacyBanner: FC = () => {
return (
<div className="space-y-6">
<Alert className="border-amber-500/40 bg-amber-500/10">
<AlertTriangle className="size-4 shrink-0 text-amber-500" />
<AlertTitle className="text-xs sm:text-sm">
Sync stopped, install the plugin to migrate
</AlertTitle>
<AlertDescription className="text-[11px] sm:text-xs leading-relaxed">
<Alert variant="warning">
<AlertTriangle />
<AlertTitle>Sync stopped, install the plugin to migrate</AlertTitle>
<AlertDescription>
This Obsidian connector used the legacy server-path scanner, which has been removed. The
notes already indexed remain searchable, but they no longer reflect changes made in your
vault.
@ -124,10 +122,10 @@ const PluginStats: FC<{ config: Record<string, unknown> }> = ({ config }) => {
return (
<div className="space-y-4">
<Alert className="border-emerald-500/30 bg-emerald-500/10">
<Info className="size-4 shrink-0 text-emerald-500" />
<AlertTitle className="text-xs sm:text-sm">Plugin connected</AlertTitle>
<AlertDescription className="text-[11px] sm:text-xs">
<Alert>
<Info />
<AlertTitle>Plugin connected</AlertTitle>
<AlertDescription>
Your notes stay synced automatically. To stop syncing, disable or uninstall the plugin in
Obsidian, or delete this connector.
</AlertDescription>
@ -152,11 +150,11 @@ const PluginStats: FC<{ config: Record<string, unknown> }> = ({ config }) => {
const UnknownConnectorState: FC = () => (
<Alert>
<Info className="size-4 shrink-0" />
<AlertTitle className="text-xs sm:text-sm">Unrecognized config</AlertTitle>
<AlertDescription className="text-[11px] sm:text-xs">
This connector has neither plugin metadata nor a legacy marker. It may predate migration you
can safely delete it and re-install the SurfSense Obsidian plugin to resume syncing.
<Info />
<AlertTitle>Unrecognized config</AlertTitle>
<AlertDescription>
This connector is missing plugin metadata and may predate the Obsidian plugin migration. You
can safely delete it and reinstall the SurfSense Obsidian plugin to resume syncing.
</AlertDescription>
</Alert>
);

View file

@ -14,6 +14,7 @@ import {
import type { FC } from "react";
import { useCallback, useEffect, useState } from "react";
import { DriveFolderTree, type SelectedFolder } from "@/components/connectors/drive-folder-tree";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import {
Select,
@ -178,14 +179,16 @@ export const OneDriveConfig: FC<ConnectorConfigProps> = ({ connector, onConfigCh
>
<FolderClosed className="size-3.5 shrink-0 text-muted-foreground" />
<span className="flex-1 truncate">{folder.name}</span>
<button
<Button
type="button"
variant="ghost"
size="icon"
onClick={() => handleRemoveFolder(folder.id)}
className="shrink-0 p-0.5 hover:bg-muted-foreground/20 rounded transition-colors"
className="size-5 shrink-0 rounded p-0 hover:bg-accent hover:text-accent-foreground"
aria-label={`Remove ${folder.name}`}
>
<X className="size-3.5" />
</button>
</Button>
</div>
))}
{selectedFiles.map((file) => (
@ -196,14 +199,16 @@ export const OneDriveConfig: FC<ConnectorConfigProps> = ({ connector, onConfigCh
>
{getFileIconFromName(file.name)}
<span className="flex-1 truncate">{file.name}</span>
<button
<Button
type="button"
variant="ghost"
size="icon"
onClick={() => handleRemoveFile(file.id)}
className="shrink-0 p-0.5 hover:bg-muted-foreground/20 rounded transition-colors"
className="size-5 shrink-0 rounded p-0 hover:bg-accent hover:text-accent-foreground"
aria-label={`Remove ${file.name}`}
>
<X className="size-3.5" />
</button>
</Button>
</div>
))}
</div>
@ -218,10 +223,11 @@ export const OneDriveConfig: FC<ConnectorConfigProps> = ({ connector, onConfigCh
{isEditMode ? (
<div className="space-y-2">
<button
<Button
type="button"
variant="ghost"
onClick={() => setIsFolderTreeOpen((prev) => !prev)}
className="flex items-center gap-2 text-xs sm:text-sm text-muted-foreground hover:text-foreground transition-colors w-fit"
className="h-auto w-fit gap-2 px-0 py-0 text-xs font-normal text-muted-foreground hover:bg-transparent hover:text-accent-foreground sm:text-sm"
>
Change Selection
{isFolderTreeOpen ? (
@ -229,7 +235,7 @@ export const OneDriveConfig: FC<ConnectorConfigProps> = ({ connector, onConfigCh
) : (
<ChevronRight className="size-4" />
)}
</button>
</Button>
{isFolderTreeOpen && (
<DriveFolderTree
fetchItems={fetchItems}

View file

@ -2,6 +2,7 @@
import { AlertCircle, CheckCircle2, Hash, Info, Lock, RefreshCw } from "lucide-react";
import { type FC, useCallback, useEffect, useState } from "react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
import { connectorsApiService, type SlackChannel } from "@/lib/apis/connectors-api.service";
@ -74,20 +75,20 @@ export const SlackConfig: FC<SlackConfigProps> = ({ connector }) => {
return (
<div className="space-y-6">
{/* Info box */}
<div className="rounded-xl border border-border bg-primary/5 p-4 flex items-start gap-3">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 shrink-0 mt-0.5">
<Info className="size-4" />
</div>
<div className="text-xs sm:text-sm">
<p className="font-medium text-xs sm:text-sm">Add Bot to Channels</p>
<p className="text-muted-foreground mt-1 text-[10px] sm:text-sm">
<Alert>
<Info />
<AlertTitle>Add Bot to Channels</AlertTitle>
<AlertDescription>
<p>
Before indexing, add the SurfSense bot to each channel you want to index. The bot can
only access messages from channels it's been added to. Type{" "}
<code className="bg-muted px-1 py-0.5 rounded text-[9px]">/invite @SurfSense</code> in
any channel to add it.
<code className="rounded bg-popover px-1 py-0.5 text-[9px] text-popover-foreground">
/invite @SurfSense
</code>{" "}
in any channel to add it.
</p>
</div>
</div>
</AlertDescription>
</Alert>
{/* Channels Section */}
<div className="space-y-3">
@ -104,7 +105,7 @@ export const SlackConfig: FC<SlackConfigProps> = ({ connector }) => {
size="sm"
onClick={fetchChannels}
disabled={isLoading}
className="h-7 px-2.5 text-[11px] bg-slate-400/10 dark:bg-white/10 hover:bg-slate-400/20 dark:hover:bg-white/20 border-slate-400/20 dark:border-white/20"
className="h-7 px-2.5 text-[11px] bg-slate-400/10 dark:bg-white/10 hover:bg-accent hover:text-accent-foreground border-slate-400/20 dark:border-white/20"
>
<RefreshCw className={cn("mr-1.5 size-3", isLoading && "animate-spin")} />
Refresh
@ -178,7 +179,7 @@ interface ChannelPillProps {
const ChannelPill: FC<ChannelPillProps> = ({ channel }) => {
return (
<div className="inline-flex items-center gap-1 px-2 py-1 rounded-md text-[11px] font-medium bg-slate-400/10 dark:bg-white/10 hover:bg-slate-400/20 dark:hover:bg-white/20 transition-colors">
<div className="inline-flex items-center gap-1 px-2 py-1 rounded-md text-[11px] font-medium bg-slate-400/10 dark:bg-white/10 hover:bg-accent hover:text-accent-foreground transition-colors">
{channel.is_private ? (
<Lock className="size-2.5 text-muted-foreground" />
) : (

View file

@ -2,6 +2,7 @@
import { Info } from "lucide-react";
import type { FC } from "react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import type { ConnectorConfigProps } from "../index";
export interface TeamsConfigProps extends ConnectorConfigProps {
@ -11,19 +12,17 @@ export interface TeamsConfigProps extends ConnectorConfigProps {
export const TeamsConfig: FC<TeamsConfigProps> = () => {
return (
<div className="space-y-6">
<div className="rounded-xl border border-border bg-primary/5 p-4 flex items-start gap-3">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 shrink-0 mt-0.5">
<Info className="size-4" />
</div>
<div className="text-xs sm:text-sm">
<p className="font-medium text-xs sm:text-sm">Microsoft Teams Access</p>
<p className="text-muted-foreground mt-1 text-[10px] sm:text-sm">
<Alert>
<Info />
<AlertTitle>Microsoft Teams Access</AlertTitle>
<AlertDescription>
<p>
Your agent can search and read messages from Teams channels you have access to, and send
messages on your behalf. Make sure you&#39;re a member of the teams you want to interact
with.
</p>
</div>
</div>
</AlertDescription>
</Alert>
</div>
);
};

View file

@ -52,13 +52,13 @@ export const WebcrawlerConfig: FC<ConnectorConfigProps> = ({ connector, onConfig
</div>
{/* Chat tip */}
<div className="flex items-start gap-3 rounded-lg border border-blue-200/50 bg-blue-50/50 dark:border-blue-500/20 dark:bg-blue-950/20 p-3 text-xs sm:text-sm">
<Info className="size-4 mt-0.5 shrink-0 text-blue-600 dark:text-blue-400" />
<p className="text-muted-foreground">
<Alert>
<Info />
<AlertDescription>
Want a quick answer from a webpage without indexing it? Just paste the URL directly into
the chat instead.
</p>
</div>
</AlertDescription>
</Alert>
{/* API Key Field */}
<div className="space-y-2">
@ -79,7 +79,7 @@ export const WebcrawlerConfig: FC<ConnectorConfigProps> = ({ connector, onConfig
variant="ghost"
size="sm"
onClick={() => setShowApiKey((prev) => !prev)}
className="absolute right-1 top-1/2 -translate-y-1/2 h-7 px-2 text-xs text-muted-foreground hover:text-foreground"
className="absolute right-1 top-1/2 -translate-y-1/2 h-7 px-2 text-xs text-muted-foreground hover:text-accent-foreground"
>
{showApiKey ? "Hide" : "Show"}
</Button>
@ -116,9 +116,9 @@ export const WebcrawlerConfig: FC<ConnectorConfigProps> = ({ connector, onConfig
</div>
{/* Info Alert */}
<Alert className="bg-slate-400/5 dark:bg-white/5 border-slate-400/20 p-2 sm:p-3">
<Info className="size-4 shrink-0" />
<AlertDescription className="text-[10px] sm:text-xs">
<Alert>
<Info />
<AlertDescription>
Configuration is saved when you start indexing. You can update these settings anytime from
the connector management page.
</AlertDescription>

View file

@ -90,14 +90,15 @@ export const ConnectorConnectView: FC<ConnectorConnectViewProps> = ({
<div className="flex-1 flex flex-col min-h-0 overflow-hidden">
{/* Header */}
<div className="flex-shrink-0 px-6 sm:px-12 pt-8 sm:pt-10">
<button
<Button
variant="ghost"
type="button"
onClick={onBack}
className="flex items-center gap-2 text-xs sm:text-sm text-muted-foreground hover:text-foreground mb-6 w-fit"
className="mb-6 h-auto w-fit justify-start gap-2 px-0 py-0 text-xs text-muted-foreground hover:bg-transparent hover:text-accent-foreground sm:text-sm"
>
<ArrowLeft className="size-4" />
<ArrowLeft data-icon="inline-start" />
Back to connectors
</button>
</Button>
<div className="flex items-center gap-4 mb-6">
<div className="flex h-14 w-14 items-center justify-center rounded-xl border border-slate-400/30">
@ -133,7 +134,7 @@ export const ConnectorConnectView: FC<ConnectorConnectViewProps> = ({
</div>
{/* Fixed Footer - Action buttons */}
<div className="flex-shrink-0 flex items-center justify-between px-6 sm:px-12 py-6 bg-muted border-t border-border">
<div className="flex-shrink-0 flex items-center justify-between px-6 sm:px-12 py-6 bg-popover">
<Button
variant="ghost"
onClick={onBack}

View file

@ -5,6 +5,7 @@ import { ArrowLeft, Info, RefreshCw } from "lucide-react";
import { type FC, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { toast } from "sonner";
import { activeSearchSpaceIdAtom } from "@/atoms/search-spaces/search-space-query.atoms";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
import { EnumConnectorName } from "@/contracts/enums/connector";
@ -206,14 +207,15 @@ export const ConnectorEditView: FC<ConnectorEditViewProps> = ({
)}
>
{/* Back button */}
<button
<Button
variant="ghost"
type="button"
onClick={onBack}
className="flex items-center gap-2 text-xs sm:text-sm text-muted-foreground hover:text-foreground mb-6 w-fit"
className="mb-6 h-auto w-fit justify-start gap-2 px-0 py-0 text-xs text-muted-foreground hover:bg-transparent hover:text-accent-foreground sm:text-sm"
>
<ArrowLeft className="size-4" />
<ArrowLeft data-icon="inline-start" />
Back to connectors
</button>
</Button>
{/* Connector header */}
<div className="flex flex-col sm:flex-row items-start sm:items-center gap-4 mb-6">
@ -239,7 +241,7 @@ export const ConnectorEditView: FC<ConnectorEditViewProps> = ({
size="sm"
onClick={handleQuickIndex}
disabled={isQuickIndexing || isIndexing || isSaving || isDisconnecting}
className="text-xs sm:text-sm bg-slate-400/10 dark:bg-white/10 hover:bg-slate-400/20 dark:hover:bg-white/20 border-slate-400/20 dark:border-white/20 w-full sm:w-auto"
className="text-xs sm:text-sm bg-slate-400/10 dark:bg-white/10 hover:bg-accent hover:text-accent-foreground border-slate-400/20 dark:border-white/20 w-full sm:w-auto"
>
{isQuickIndexing || isIndexing ? (
<>
@ -349,41 +351,33 @@ export const ConnectorEditView: FC<ConnectorEditViewProps> = ({
{/* Info box - hidden for live connectors */}
{connector.is_indexable && !isLive && (
<div className="rounded-xl border border-border bg-primary/5 p-4 flex items-start gap-3">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 shrink-0 mt-0.5">
<Info className="size-4" />
</div>
<div className="text-xs sm:text-sm">
<p className="font-medium text-xs sm:text-sm">
Re-indexing runs in the background
</p>
<p className="text-muted-foreground mt-1 text-[10px] sm:text-sm">
You can continue using SurfSense while we sync your data. Check inbox for
updates.
</p>
</div>
</div>
<Alert>
<Info />
<AlertDescription>
You can continue using SurfSense while we sync your data. Check inbox for updates.
</AlertDescription>
</Alert>
)}
</div>
</div>
{/* Top fade shadow - appears when scrolled */}
{isScrolled && (
<div className="absolute top-0 left-0 right-0 h-6 bg-gradient-to-b from-muted/50 to-transparent pointer-events-none z-10" />
<div className="absolute top-0 left-0 right-0 h-6 bg-gradient-to-b from-popover to-transparent pointer-events-none z-10" />
)}
{/* Bottom fade shadow - appears when there's more content */}
{hasMoreContent && (
<div className="absolute bottom-0 left-0 right-0 h-3 bg-gradient-to-t from-muted/50 to-transparent pointer-events-none z-10" />
<div className="absolute bottom-0 left-0 right-0 h-3 bg-gradient-to-t from-popover to-transparent pointer-events-none z-10" />
)}
</div>
{/* Fixed Footer - Action buttons */}
<div className="flex-shrink-0 flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-3 sm:gap-0 px-6 sm:px-12 py-6 sm:py-6 bg-muted border-t border-border">
<div className="flex-shrink-0 flex flex-col sm:flex-row items-stretch sm:items-center justify-between gap-3 sm:gap-0 px-6 sm:px-12 py-6 sm:py-6 bg-popover">
{showDisconnectConfirm ? (
<div className="flex flex-col sm:flex-row items-stretch sm:items-center gap-3 flex-1 sm:flex-initial">
<span className="text-xs sm:text-sm text-muted-foreground sm:whitespace-nowrap">
{isLive
? "Your agent will lose access to this service."
: "This will remove all indexed data."}
? "Your agent will lose access to this service"
: "This will remove all indexed data"}
</span>
<div className="flex items-center gap-2 sm:gap-3">
<Button

View file

@ -2,6 +2,7 @@
import { ArrowLeft, Check, Info } from "lucide-react";
import { type FC, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
import { EnumConnectorName } from "@/contracts/enums/connector";
@ -128,14 +129,15 @@ export const IndexingConfigurationView: FC<IndexingConfigurationViewProps> = ({
>
{/* Back button - only show if not from OAuth */}
{!isFromOAuth && (
<button
<Button
variant="ghost"
type="button"
onClick={onSkip}
className="flex items-center gap-2 text-xs sm:text-sm text-muted-foreground hover:text-foreground mb-6 w-fit"
className="mb-6 h-auto w-fit justify-start gap-2 px-0 py-0 text-xs text-muted-foreground hover:bg-transparent hover:text-accent-foreground sm:text-sm"
>
<ArrowLeft className="size-4" />
<ArrowLeft data-icon="inline-start" />
Back to connectors
</button>
</Button>
)}
{/* Success header */}
@ -229,33 +231,27 @@ export const IndexingConfigurationView: FC<IndexingConfigurationViewProps> = ({
{/* Info box - hidden for live connectors */}
{connector?.is_indexable && !isLive && (
<div className="rounded-xl border border-border bg-primary/5 p-4 flex items-start gap-3">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary/10 shrink-0 mt-0.5">
<Info className="size-4" />
</div>
<div className="text-xs sm:text-sm">
<p className="font-medium text-xs sm:text-sm">Indexing runs in the background</p>
<p className="text-muted-foreground mt-1 text-[10px] sm:text-sm">
You can continue using SurfSense while we sync your data. Check inbox for
updates.
</p>
</div>
</div>
<Alert>
<Info />
<AlertDescription>
You can continue using SurfSense while we sync your data. Check inbox for updates.
</AlertDescription>
</Alert>
)}
</div>
</div>
{/* Top fade shadow - appears when scrolled */}
{isScrolled && (
<div className="absolute top-0 left-0 right-0 h-6 bg-gradient-to-b from-muted/50 to-transparent pointer-events-none z-10" />
<div className="absolute top-0 left-0 right-0 h-6 bg-gradient-to-b from-popover to-transparent pointer-events-none z-10" />
)}
{/* Bottom fade shadow - appears when there's more content */}
{hasMoreContent && (
<div className="absolute bottom-0 left-0 right-0 h-3 bg-gradient-to-t from-muted/50 to-transparent pointer-events-none z-10" />
<div className="absolute bottom-0 left-0 right-0 h-3 bg-gradient-to-t from-popover to-transparent pointer-events-none z-10" />
)}
</div>
{/* Fixed Footer - Action buttons */}
<div className="flex-shrink-0 flex items-center justify-end px-6 sm:px-12 py-6 bg-muted">
<div className="flex-shrink-0 flex items-center justify-end px-6 sm:px-12 py-6 bg-popover">
{isLive ? (
<Button onClick={onSkip} className="text-xs sm:text-sm">
Done