mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-30 11:26:24 +02:00
Merge pull request #316 from MODSetter/dev
refactor: connector icon handling by centralizing icon retrieval in contracts.
This commit is contained in:
commit
b50001b640
25 changed files with 318 additions and 310 deletions
|
|
@ -6,7 +6,6 @@ import { Calendar as CalendarIcon, Edit, Plus, RefreshCw, Trash2 } from "lucide-
|
||||||
import { useParams, useRouter } from "next/navigation";
|
import { useParams, useRouter } from "next/navigation";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { getConnectorIcon } from "@/components/chat";
|
|
||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
AlertDialogAction,
|
AlertDialogAction,
|
||||||
|
|
@ -41,6 +40,7 @@ import {
|
||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||||
import { EnumConnectorName } from "@/contracts/enums/connector";
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import { ArrowLeft, Check, Loader2 } from "lucide-react";
|
||||||
import { useParams, useRouter } from "next/navigation";
|
import { useParams, useRouter } from "next/navigation";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { getConnectorIcon } from "@/components/chat";
|
|
||||||
import { EditConnectorLoadingSkeleton } from "@/components/editConnector/EditConnectorLoadingSkeleton";
|
import { EditConnectorLoadingSkeleton } from "@/components/editConnector/EditConnectorLoadingSkeleton";
|
||||||
import { EditConnectorNameForm } from "@/components/editConnector/EditConnectorNameForm";
|
import { EditConnectorNameForm } from "@/components/editConnector/EditConnectorNameForm";
|
||||||
import { EditGitHubConnectorConfig } from "@/components/editConnector/EditGitHubConnectorConfig";
|
import { EditGitHubConnectorConfig } from "@/components/editConnector/EditGitHubConnectorConfig";
|
||||||
|
|
@ -20,6 +19,7 @@ import {
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
import { Form } from "@/components/ui/form";
|
import { Form } from "@/components/ui/form";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import { useConnectorEditPage } from "@/hooks/useConnectorEditPage";
|
import { useConnectorEditPage } from "@/hooks/useConnectorEditPage";
|
||||||
// Import Utils, Types, Hook, and Components
|
// Import Utils, Types, Hook, and Components
|
||||||
import { getConnectorTypeDisplay } from "@/lib/connectors/utils";
|
import { getConnectorTypeDisplay } from "@/lib/connectors/utils";
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { IconBrandAirtable } from "@tabler/icons-react";
|
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { ArrowLeft, Check, ExternalLink, Loader2 } from "lucide-react";
|
import { ArrowLeft, Check, ExternalLink, Loader2 } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
@ -17,6 +16,8 @@ import {
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
import { EnumConnectorName } from "@/contracts/enums/connector";
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
// import { IconBrandAirtable } from "@tabler/icons-react";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import {
|
import {
|
||||||
type SearchSourceConnector,
|
type SearchSourceConnector,
|
||||||
useSearchSourceConnectors,
|
useSearchSourceConnectors,
|
||||||
|
|
@ -88,8 +89,8 @@ export default function AirtableConnectorPage() {
|
||||||
Back to connectors
|
Back to connectors
|
||||||
</Link>
|
</Link>
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<div className="flex h-12 w-12 items-center justify-center rounded-lg bg-blue-100 dark:bg-blue-900">
|
<div className="flex h-12 w-12 items-center justify-center rounded-lg">
|
||||||
<IconBrandAirtable className="h-6 w-6 text-blue-600 dark:text-blue-400" />
|
{getConnectorIcon(EnumConnectorName.AIRTABLE_CONNECTOR, "h-6 w-6")}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold tracking-tight">Connect Airtable</h1>
|
<h1 className="text-3xl font-bold tracking-tight">Connect Airtable</h1>
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ import {
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||||
|
|
||||||
// Define the form schema with Zod
|
// Define the form schema with Zod
|
||||||
|
|
@ -59,7 +61,7 @@ export default function ClickUpConnectorPage() {
|
||||||
try {
|
try {
|
||||||
const connectorData = {
|
const connectorData = {
|
||||||
name: values.name,
|
name: values.name,
|
||||||
connector_type: "CLICKUP_CONNECTOR",
|
connector_type: EnumConnectorName.CLICKUP_CONNECTOR,
|
||||||
is_indexable: true,
|
is_indexable: true,
|
||||||
config: {
|
config: {
|
||||||
CLICKUP_API_TOKEN: values.api_token,
|
CLICKUP_API_TOKEN: values.api_token,
|
||||||
|
|
@ -90,6 +92,21 @@ export default function ClickUpConnectorPage() {
|
||||||
Back to Connectors
|
Back to Connectors
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{/* Header */}
|
||||||
|
<div className="mb-8">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="flex h-12 w-12 items-center justify-center rounded-lg">
|
||||||
|
{getConnectorIcon(EnumConnectorName.CLICKUP_CONNECTOR, "h-6 w-6")}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 className="text-3xl font-bold tracking-tight">Connect ClickUp</h1>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
Connect your ClickUp workspace to search tasks and projects.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>ClickUp Configuration</CardTitle>
|
<CardTitle>ClickUp Configuration</CardTitle>
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ import {
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||||
|
|
||||||
// Define the form schema with Zod
|
// Define the form schema with Zod
|
||||||
|
|
@ -78,7 +79,7 @@ export default function ConfluenceConnectorPage() {
|
||||||
try {
|
try {
|
||||||
await createConnector({
|
await createConnector({
|
||||||
name: values.name,
|
name: values.name,
|
||||||
connector_type: "CONFLUENCE_CONNECTOR",
|
connector_type: EnumConnectorName.CONFLUENCE_CONNECTOR,
|
||||||
config: {
|
config: {
|
||||||
CONFLUENCE_BASE_URL: values.base_url,
|
CONFLUENCE_BASE_URL: values.base_url,
|
||||||
CONFLUENCE_EMAIL: values.email,
|
CONFLUENCE_EMAIL: values.email,
|
||||||
|
|
@ -111,6 +112,21 @@ export default function ConfluenceConnectorPage() {
|
||||||
Back to Connectors
|
Back to Connectors
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{/* Header */}
|
||||||
|
<div className="mb-8">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="flex h-12 w-12 items-center justify-center rounded-lg">
|
||||||
|
{getConnectorIcon(EnumConnectorName.CONFLUENCE_CONNECTOR, "h-6 w-6")}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 className="text-3xl font-bold tracking-tight">Connect Confluence</h1>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
Connect your Confluence instance to search pages and spaces.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ import {
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||||
|
|
||||||
// Define the form schema with Zod
|
// Define the form schema with Zod
|
||||||
|
|
@ -73,7 +75,7 @@ export default function DiscordConnectorPage() {
|
||||||
try {
|
try {
|
||||||
await createConnector({
|
await createConnector({
|
||||||
name: values.name,
|
name: values.name,
|
||||||
connector_type: "DISCORD_CONNECTOR",
|
connector_type: EnumConnectorName.DISCORD_CONNECTOR,
|
||||||
config: {
|
config: {
|
||||||
DISCORD_BOT_TOKEN: values.bot_token,
|
DISCORD_BOT_TOKEN: values.bot_token,
|
||||||
},
|
},
|
||||||
|
|
@ -102,6 +104,21 @@ export default function DiscordConnectorPage() {
|
||||||
Back to Connectors
|
Back to Connectors
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{/* Header */}
|
||||||
|
<div className="mb-8">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="flex h-12 w-12 items-center justify-center rounded-lg ">
|
||||||
|
{getConnectorIcon(EnumConnectorName.DISCORD_CONNECTOR, "h-6 w-6")}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 className="text-3xl font-bold tracking-tight">Connect Discord</h1>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
Connect your Discord server to search messages and channels.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ import {
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
// Assuming useSearchSourceConnectors hook exists and works similarly
|
// Assuming useSearchSourceConnectors hook exists and works similarly
|
||||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||||
|
|
||||||
|
|
@ -148,7 +150,7 @@ export default function GithubConnectorPage() {
|
||||||
try {
|
try {
|
||||||
await createConnector({
|
await createConnector({
|
||||||
name: connectorName, // Use the stored name
|
name: connectorName, // Use the stored name
|
||||||
connector_type: "GITHUB_CONNECTOR",
|
connector_type: EnumConnectorName.GITHUB_CONNECTOR,
|
||||||
config: {
|
config: {
|
||||||
GITHUB_PAT: validatedPat, // Use the stored validated PAT
|
GITHUB_PAT: validatedPat, // Use the stored validated PAT
|
||||||
repo_full_names: selectedRepos, // Add the selected repo names
|
repo_full_names: selectedRepos, // Add the selected repo names
|
||||||
|
|
@ -215,7 +217,7 @@ export default function GithubConnectorPage() {
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-2xl font-bold flex items-center gap-2">
|
<CardTitle className="text-2xl font-bold flex items-center gap-2">
|
||||||
{step === "enter_pat" ? (
|
{step === "enter_pat" ? (
|
||||||
<Github className="h-6 w-6" />
|
getConnectorIcon(EnumConnectorName.GITHUB_CONNECTOR, "h-6 w-6")
|
||||||
) : (
|
) : (
|
||||||
<ListChecks className="h-6 w-6" />
|
<ListChecks className="h-6 w-6" />
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { IconCalendar } from "@tabler/icons-react";
|
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { ArrowLeft, Check, ExternalLink, Loader2 } from "lucide-react";
|
import { ArrowLeft, Check, ExternalLink, Loader2 } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
@ -19,6 +18,8 @@ import {
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import {
|
import {
|
||||||
type SearchSourceConnector,
|
type SearchSourceConnector,
|
||||||
useSearchSourceConnectors,
|
useSearchSourceConnectors,
|
||||||
|
|
@ -36,7 +37,8 @@ export default function GoogleCalendarConnectorPage() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchConnectors().then((data) => {
|
fetchConnectors().then((data) => {
|
||||||
const connector = data.find(
|
const connector = data.find(
|
||||||
(c: SearchSourceConnector) => c.connector_type === "GOOGLE_CALENDAR_CONNECTOR"
|
(c: SearchSourceConnector) =>
|
||||||
|
c.connector_type === EnumConnectorName.GOOGLE_CALENDAR_CONNECTOR
|
||||||
);
|
);
|
||||||
if (connector) {
|
if (connector) {
|
||||||
setDoesConnectorExist(true);
|
setDoesConnectorExist(true);
|
||||||
|
|
@ -92,8 +94,8 @@ export default function GoogleCalendarConnectorPage() {
|
||||||
Back to connectors
|
Back to connectors
|
||||||
</Link>
|
</Link>
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<div className="flex h-12 w-12 items-center justify-center rounded-lg bg-blue-100 dark:bg-blue-900">
|
<div className="flex h-12 w-12 items-center justify-center rounded-lg">
|
||||||
<IconCalendar className="h-6 w-6 text-blue-600 dark:text-blue-400" />
|
{getConnectorIcon(EnumConnectorName.GOOGLE_CALENDAR_CONNECTOR, "h-6 w-6")}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold tracking-tight">Connect Google Calendar</h1>
|
<h1 className="text-3xl font-bold tracking-tight">Connect Google Calendar</h1>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { IconMail } from "@tabler/icons-react";
|
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { ArrowLeft, Check, ExternalLink, Loader2 } from "lucide-react";
|
import { ArrowLeft, Check, ExternalLink, Loader2 } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
@ -19,6 +18,8 @@ import {
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import {
|
import {
|
||||||
type SearchSourceConnector,
|
type SearchSourceConnector,
|
||||||
useSearchSourceConnectors,
|
useSearchSourceConnectors,
|
||||||
|
|
@ -36,7 +37,7 @@ export default function GoogleGmailConnectorPage() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchConnectors().then((data) => {
|
fetchConnectors().then((data) => {
|
||||||
const connector = data.find(
|
const connector = data.find(
|
||||||
(c: SearchSourceConnector) => c.connector_type === "GOOGLE_GMAIL_CONNECTOR"
|
(c: SearchSourceConnector) => c.connector_type === EnumConnectorName.GOOGLE_GMAIL_CONNECTOR
|
||||||
);
|
);
|
||||||
if (connector) {
|
if (connector) {
|
||||||
setDoesConnectorExist(true);
|
setDoesConnectorExist(true);
|
||||||
|
|
@ -92,8 +93,8 @@ export default function GoogleGmailConnectorPage() {
|
||||||
Back to connectors
|
Back to connectors
|
||||||
</Link>
|
</Link>
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<div className="flex h-12 w-12 items-center justify-center rounded-lg bg-red-100 dark:bg-red-900">
|
<div className="flex h-12 w-12 items-center justify-center rounded-lg">
|
||||||
<IconMail className="h-6 w-6 text-red-600 dark:text-red-400" />
|
{getConnectorIcon(EnumConnectorName.GOOGLE_GMAIL_CONNECTOR, "h-6 w-6")}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold tracking-tight">Connect Google Gmail</h1>
|
<h1 className="text-3xl font-bold tracking-tight">Connect Google Gmail</h1>
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ import {
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||||
|
|
||||||
// Define the form schema with Zod
|
// Define the form schema with Zod
|
||||||
|
|
@ -90,7 +92,7 @@ export default function JiraConnectorPage() {
|
||||||
try {
|
try {
|
||||||
await createConnector({
|
await createConnector({
|
||||||
name: values.name,
|
name: values.name,
|
||||||
connector_type: "JIRA_CONNECTOR",
|
connector_type: EnumConnectorName.JIRA_CONNECTOR,
|
||||||
config: {
|
config: {
|
||||||
JIRA_BASE_URL: values.base_url,
|
JIRA_BASE_URL: values.base_url,
|
||||||
JIRA_EMAIL: values.email,
|
JIRA_EMAIL: values.email,
|
||||||
|
|
@ -123,6 +125,21 @@ export default function JiraConnectorPage() {
|
||||||
Back to Connectors
|
Back to Connectors
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{/* Header */}
|
||||||
|
<div className="mb-8">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="flex h-12 w-12 items-center justify-center rounded-lg">
|
||||||
|
{getConnectorIcon(EnumConnectorName.JIRA_CONNECTOR, "h-6 w-6")}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 className="text-3xl font-bold tracking-tight">Connect Jira</h1>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
Connect your Jira instance to search issues and tickets.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ import {
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||||
|
|
||||||
// Define the form schema with Zod
|
// Define the form schema with Zod
|
||||||
|
|
@ -77,7 +79,7 @@ export default function LinearConnectorPage() {
|
||||||
try {
|
try {
|
||||||
await createConnector({
|
await createConnector({
|
||||||
name: values.name,
|
name: values.name,
|
||||||
connector_type: "LINEAR_CONNECTOR",
|
connector_type: EnumConnectorName.LINEAR_CONNECTOR,
|
||||||
config: {
|
config: {
|
||||||
LINEAR_API_KEY: values.api_key,
|
LINEAR_API_KEY: values.api_key,
|
||||||
},
|
},
|
||||||
|
|
@ -108,6 +110,21 @@ export default function LinearConnectorPage() {
|
||||||
Back to Connectors
|
Back to Connectors
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{/* Header */}
|
||||||
|
<div className="mb-8">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="flex h-12 w-12 items-center justify-center rounded-lg">
|
||||||
|
{getConnectorIcon(EnumConnectorName.LINEAR_CONNECTOR, "h-6 w-6")}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 className="text-3xl font-bold tracking-tight">Connect Linear</h1>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
Connect your Linear workspace to search issues and projects.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ import {
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||||
|
|
||||||
// Define the form schema with Zod
|
// Define the form schema with Zod
|
||||||
|
|
@ -65,7 +67,7 @@ export default function LinkupApiPage() {
|
||||||
try {
|
try {
|
||||||
await createConnector({
|
await createConnector({
|
||||||
name: values.name,
|
name: values.name,
|
||||||
connector_type: "LINKUP_API",
|
connector_type: EnumConnectorName.LINKUP_API,
|
||||||
config: {
|
config: {
|
||||||
LINKUP_API_KEY: values.api_key,
|
LINKUP_API_KEY: values.api_key,
|
||||||
},
|
},
|
||||||
|
|
@ -96,6 +98,21 @@ export default function LinkupApiPage() {
|
||||||
Back to Connectors
|
Back to Connectors
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{/* Header */}
|
||||||
|
<div className="mb-8">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="flex h-12 w-12 items-center justify-center rounded-lg">
|
||||||
|
{getConnectorIcon(EnumConnectorName.LINKUP_API, "h-6 w-6")}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 className="text-3xl font-bold tracking-tight">Connect Linkup API</h1>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
Connect Linkup API for enhanced search capabilities.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ import {
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||||
|
|
||||||
// Define the form schema with Zod
|
// Define the form schema with Zod
|
||||||
|
|
@ -72,7 +74,7 @@ export default function NotionConnectorPage() {
|
||||||
try {
|
try {
|
||||||
await createConnector({
|
await createConnector({
|
||||||
name: values.name,
|
name: values.name,
|
||||||
connector_type: "NOTION_CONNECTOR",
|
connector_type: EnumConnectorName.NOTION_CONNECTOR,
|
||||||
config: {
|
config: {
|
||||||
NOTION_INTEGRATION_TOKEN: values.integration_token,
|
NOTION_INTEGRATION_TOKEN: values.integration_token,
|
||||||
},
|
},
|
||||||
|
|
@ -103,6 +105,21 @@ export default function NotionConnectorPage() {
|
||||||
Back to Connectors
|
Back to Connectors
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{/* Header */}
|
||||||
|
<div className="mb-8">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="flex h-12 w-12 items-center justify-center rounded-lg">
|
||||||
|
{getConnectorIcon(EnumConnectorName.NOTION_CONNECTOR, "h-6 w-6")}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 className="text-3xl font-bold tracking-tight">Connect Notion</h1>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
Connect your Notion workspace to search pages and databases.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,10 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IconBook,
|
|
||||||
IconBrandDiscord,
|
|
||||||
IconBrandGithub,
|
|
||||||
IconBrandNotion,
|
|
||||||
IconBrandSlack,
|
|
||||||
IconBrandWindows,
|
IconBrandWindows,
|
||||||
IconBrandZoom,
|
IconBrandZoom,
|
||||||
IconCalendar,
|
|
||||||
IconChecklist,
|
|
||||||
IconChevronDown,
|
IconChevronDown,
|
||||||
IconChevronRight,
|
IconChevronRight,
|
||||||
IconLayoutKanban,
|
|
||||||
IconLinkPlus,
|
|
||||||
IconMail,
|
|
||||||
IconTable,
|
|
||||||
IconTicket,
|
|
||||||
IconWorldWww,
|
|
||||||
} from "@tabler/icons-react";
|
} from "@tabler/icons-react";
|
||||||
import { AnimatePresence, motion, type Variants } from "framer-motion";
|
import { AnimatePresence, motion, type Variants } from "framer-motion";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
@ -27,6 +14,8 @@ import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card";
|
import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card";
|
||||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
|
|
||||||
// Define the Connector type
|
// Define the Connector type
|
||||||
interface Connector {
|
interface Connector {
|
||||||
|
|
@ -53,14 +42,14 @@ const connectorCategories: ConnectorCategory[] = [
|
||||||
id: "tavily-api",
|
id: "tavily-api",
|
||||||
title: "Tavily API",
|
title: "Tavily API",
|
||||||
description: "Search the web using the Tavily API",
|
description: "Search the web using the Tavily API",
|
||||||
icon: <IconWorldWww className="h-6 w-6" />,
|
icon: getConnectorIcon(EnumConnectorName.TAVILY_API, "h-6 w-6"),
|
||||||
status: "available",
|
status: "available",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "linkup-api",
|
id: "linkup-api",
|
||||||
title: "Linkup API",
|
title: "Linkup API",
|
||||||
description: "Search the web using the Linkup API",
|
description: "Search the web using the Linkup API",
|
||||||
icon: <IconLinkPlus className="h-6 w-6" />,
|
icon: getConnectorIcon(EnumConnectorName.LINKUP_API, "h-6 w-6"),
|
||||||
status: "available",
|
status: "available",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
@ -73,7 +62,7 @@ const connectorCategories: ConnectorCategory[] = [
|
||||||
id: "slack-connector",
|
id: "slack-connector",
|
||||||
title: "Slack",
|
title: "Slack",
|
||||||
description: "Connect to your Slack workspace to access messages and channels.",
|
description: "Connect to your Slack workspace to access messages and channels.",
|
||||||
icon: <IconBrandSlack className="h-6 w-6" />,
|
icon: getConnectorIcon(EnumConnectorName.SLACK_CONNECTOR, "h-6 w-6"),
|
||||||
status: "available",
|
status: "available",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -87,7 +76,7 @@ const connectorCategories: ConnectorCategory[] = [
|
||||||
id: "discord-connector",
|
id: "discord-connector",
|
||||||
title: "Discord",
|
title: "Discord",
|
||||||
description: "Connect to Discord servers to access messages and channels.",
|
description: "Connect to Discord servers to access messages and channels.",
|
||||||
icon: <IconBrandDiscord className="h-6 w-6" />,
|
icon: getConnectorIcon(EnumConnectorName.DISCORD_CONNECTOR, "h-6 w-6"),
|
||||||
status: "available",
|
status: "available",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
@ -100,21 +89,21 @@ const connectorCategories: ConnectorCategory[] = [
|
||||||
id: "linear-connector",
|
id: "linear-connector",
|
||||||
title: "Linear",
|
title: "Linear",
|
||||||
description: "Connect to Linear to search issues, comments and project data.",
|
description: "Connect to Linear to search issues, comments and project data.",
|
||||||
icon: <IconLayoutKanban className="h-6 w-6" />,
|
icon: getConnectorIcon(EnumConnectorName.LINEAR_CONNECTOR, "h-6 w-6"),
|
||||||
status: "available",
|
status: "available",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "jira-connector",
|
id: "jira-connector",
|
||||||
title: "Jira",
|
title: "Jira",
|
||||||
description: "Connect to Jira to search issues, tickets and project data.",
|
description: "Connect to Jira to search issues, tickets and project data.",
|
||||||
icon: <IconTicket className="h-6 w-6" />,
|
icon: getConnectorIcon(EnumConnectorName.JIRA_CONNECTOR, "h-6 w-6"),
|
||||||
status: "available",
|
status: "available",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "clickup-connector",
|
id: "clickup-connector",
|
||||||
title: "ClickUp",
|
title: "ClickUp",
|
||||||
description: "Connect to ClickUp to search tasks, comments and project data.",
|
description: "Connect to ClickUp to search tasks, comments and project data.",
|
||||||
icon: <IconChecklist className="h-6 w-6" />,
|
icon: getConnectorIcon(EnumConnectorName.CLICKUP_CONNECTOR, "h-6 w-6"),
|
||||||
status: "available",
|
status: "available",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
@ -127,28 +116,28 @@ const connectorCategories: ConnectorCategory[] = [
|
||||||
id: "notion-connector",
|
id: "notion-connector",
|
||||||
title: "Notion",
|
title: "Notion",
|
||||||
description: "Connect to your Notion workspace to access pages and databases.",
|
description: "Connect to your Notion workspace to access pages and databases.",
|
||||||
icon: <IconBrandNotion className="h-6 w-6" />,
|
icon: getConnectorIcon(EnumConnectorName.NOTION_CONNECTOR, "h-6 w-6"),
|
||||||
status: "available",
|
status: "available",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "github-connector",
|
id: "github-connector",
|
||||||
title: "GitHub",
|
title: "GitHub",
|
||||||
description: "Connect a GitHub PAT to index code and docs from accessible repositories.",
|
description: "Connect a GitHub PAT to index code and docs from accessible repositories.",
|
||||||
icon: <IconBrandGithub className="h-6 w-6" />,
|
icon: getConnectorIcon(EnumConnectorName.GITHUB_CONNECTOR, "h-6 w-6"),
|
||||||
status: "available",
|
status: "available",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "confluence-connector",
|
id: "confluence-connector",
|
||||||
title: "Confluence",
|
title: "Confluence",
|
||||||
description: "Connect to Confluence to search pages, comments and documentation.",
|
description: "Connect to Confluence to search pages, comments and documentation.",
|
||||||
icon: <IconBook className="h-6 w-6" />,
|
icon: getConnectorIcon(EnumConnectorName.CONFLUENCE_CONNECTOR, "h-6 w-6"),
|
||||||
status: "available",
|
status: "available",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "airtable-connector",
|
id: "airtable-connector",
|
||||||
title: "Airtable",
|
title: "Airtable",
|
||||||
description: "Connect to Airtable to search records, tables and database content.",
|
description: "Connect to Airtable to search records, tables and database content.",
|
||||||
icon: <IconTable className="h-6 w-6" />,
|
icon: getConnectorIcon(EnumConnectorName.AIRTABLE_CONNECTOR, "h-6 w-6"),
|
||||||
status: "available",
|
status: "available",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
@ -161,14 +150,14 @@ const connectorCategories: ConnectorCategory[] = [
|
||||||
id: "google-calendar-connector",
|
id: "google-calendar-connector",
|
||||||
title: "Google Calendar",
|
title: "Google Calendar",
|
||||||
description: "Connect to Google Calendar to search events, meetings and schedules.",
|
description: "Connect to Google Calendar to search events, meetings and schedules.",
|
||||||
icon: <IconCalendar className="h-6 w-6" />,
|
icon: getConnectorIcon(EnumConnectorName.GOOGLE_CALENDAR_CONNECTOR, "h-6 w-6"),
|
||||||
status: "available",
|
status: "available",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "google-gmail-connector",
|
id: "google-gmail-connector",
|
||||||
title: "Gmail",
|
title: "Gmail",
|
||||||
description: "Connect to your Gmail account to search through your emails.",
|
description: "Connect to your Gmail account to search through your emails.",
|
||||||
icon: <IconMail className="h-6 w-6" />,
|
icon: getConnectorIcon(EnumConnectorName.GOOGLE_GMAIL_CONNECTOR, "h-6 w-6"),
|
||||||
status: "available",
|
status: "available",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ import {
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||||
|
|
||||||
// Define the form schema with Zod
|
// Define the form schema with Zod
|
||||||
|
|
@ -65,7 +67,7 @@ export default function SerperApiPage() {
|
||||||
try {
|
try {
|
||||||
await createConnector({
|
await createConnector({
|
||||||
name: values.name,
|
name: values.name,
|
||||||
connector_type: "SERPER_API",
|
connector_type: EnumConnectorName.SERPER_API,
|
||||||
config: {
|
config: {
|
||||||
SERPER_API_KEY: values.api_key,
|
SERPER_API_KEY: values.api_key,
|
||||||
},
|
},
|
||||||
|
|
@ -96,6 +98,21 @@ export default function SerperApiPage() {
|
||||||
Back to Connectors
|
Back to Connectors
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{/* Header */}
|
||||||
|
<div className="mb-8">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="flex h-12 w-12 items-center justify-center rounded-lg">
|
||||||
|
{getConnectorIcon(EnumConnectorName.SERPER_API, "h-6 w-6")}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 className="text-3xl font-bold tracking-tight">Connect Serper API</h1>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
Connect Serper API for Google search capabilities.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ import {
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||||
|
|
||||||
// Define the form schema with Zod
|
// Define the form schema with Zod
|
||||||
|
|
@ -72,7 +74,7 @@ export default function SlackConnectorPage() {
|
||||||
try {
|
try {
|
||||||
await createConnector({
|
await createConnector({
|
||||||
name: values.name,
|
name: values.name,
|
||||||
connector_type: "SLACK_CONNECTOR",
|
connector_type: EnumConnectorName.SLACK_CONNECTOR,
|
||||||
config: {
|
config: {
|
||||||
SLACK_BOT_TOKEN: values.bot_token,
|
SLACK_BOT_TOKEN: values.bot_token,
|
||||||
},
|
},
|
||||||
|
|
@ -103,6 +105,21 @@ export default function SlackConnectorPage() {
|
||||||
Back to Connectors
|
Back to Connectors
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{/* Header */}
|
||||||
|
<div className="mb-8">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="flex h-12 w-12 items-center justify-center rounded-lg">
|
||||||
|
{getConnectorIcon(EnumConnectorName.SLACK_CONNECTOR, "h-6 w-6")}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 className="text-3xl font-bold tracking-tight">Connect Slack</h1>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
Connect your Slack workspace to search messages and channels.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ import {
|
||||||
FormMessage,
|
FormMessage,
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||||
|
|
||||||
// Define the form schema with Zod
|
// Define the form schema with Zod
|
||||||
|
|
@ -65,7 +67,7 @@ export default function TavilyApiPage() {
|
||||||
try {
|
try {
|
||||||
await createConnector({
|
await createConnector({
|
||||||
name: values.name,
|
name: values.name,
|
||||||
connector_type: "TAVILY_API",
|
connector_type: EnumConnectorName.TAVILY_API,
|
||||||
config: {
|
config: {
|
||||||
TAVILY_API_KEY: values.api_key,
|
TAVILY_API_KEY: values.api_key,
|
||||||
},
|
},
|
||||||
|
|
@ -96,6 +98,21 @@ export default function TavilyApiPage() {
|
||||||
Back to Connectors
|
Back to Connectors
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{/* Header */}
|
||||||
|
<div className="mb-8">
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<div className="flex h-12 w-12 items-center justify-center rounded-lg">
|
||||||
|
{getConnectorIcon(EnumConnectorName.TAVILY_API, "h-6 w-6")}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1 className="text-3xl font-bold tracking-tight">Connect Tavily API</h1>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
Connect Tavily API for AI-powered search capabilities.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,12 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import {
|
|
||||||
IconBook,
|
|
||||||
IconBrandDiscord,
|
|
||||||
IconBrandGithub,
|
|
||||||
IconBrandNotion,
|
|
||||||
IconBrandSlack,
|
|
||||||
IconBrandYoutube,
|
|
||||||
IconCalendar,
|
|
||||||
IconChecklist,
|
|
||||||
IconLayoutKanban,
|
|
||||||
IconMail,
|
|
||||||
IconTable,
|
|
||||||
IconTicket,
|
|
||||||
} from "@tabler/icons-react";
|
|
||||||
import { File, Globe, Webhook } from "lucide-react";
|
|
||||||
import type React from "react";
|
import type React from "react";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
|
|
||||||
type IconComponent = React.ComponentType<{ size?: number; className?: string }>;
|
type IconComponent = React.ComponentType<{ size?: number; className?: string }>;
|
||||||
|
|
||||||
const documentTypeIcons: Record<string, IconComponent> = {
|
export function getDocumentTypeIcon(type: string): React.ReactNode {
|
||||||
EXTENSION: Webhook,
|
return getConnectorIcon(type);
|
||||||
CRAWLED_URL: Globe,
|
|
||||||
SLACK_CONNECTOR: IconBrandSlack,
|
|
||||||
NOTION_CONNECTOR: IconBrandNotion,
|
|
||||||
FILE: File,
|
|
||||||
YOUTUBE_VIDEO: IconBrandYoutube,
|
|
||||||
GITHUB_CONNECTOR: IconBrandGithub,
|
|
||||||
LINEAR_CONNECTOR: IconLayoutKanban,
|
|
||||||
JIRA_CONNECTOR: IconTicket,
|
|
||||||
DISCORD_CONNECTOR: IconBrandDiscord,
|
|
||||||
CONFLUENCE_CONNECTOR: IconBook,
|
|
||||||
CLICKUP_CONNECTOR: IconChecklist,
|
|
||||||
GOOGLE_CALENDAR_CONNECTOR: IconCalendar,
|
|
||||||
GOOGLE_GMAIL_CONNECTOR: IconMail,
|
|
||||||
AIRTABLE_CONNECTOR: IconTable,
|
|
||||||
};
|
|
||||||
|
|
||||||
export function getDocumentTypeIcon(type: string): IconComponent {
|
|
||||||
return documentTypeIcons[type] ?? File;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDocumentTypeLabel(type: string): string {
|
export function getDocumentTypeLabel(type: string): string {
|
||||||
|
|
@ -49,7 +17,7 @@ export function getDocumentTypeLabel(type: string): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DocumentTypeChip({ type, className }: { type: string; className?: string }) {
|
export function DocumentTypeChip({ type, className }: { type: string; className?: string }) {
|
||||||
const Icon = getDocumentTypeIcon(type);
|
const icon = getDocumentTypeIcon(type);
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
className={
|
className={
|
||||||
|
|
@ -57,7 +25,7 @@ export function DocumentTypeChip({ type, className }: { type: string; className?
|
||||||
(className ?? "")
|
(className ?? "")
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Icon size={14} className="text-primary" />
|
<span className="text-primary">{icon}</span>
|
||||||
{getDocumentTypeLabel(type)}
|
{getDocumentTypeLabel(type)}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ export function DocumentsTableShell({
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{sorted.map((doc, index) => {
|
{sorted.map((doc, index) => {
|
||||||
const Icon = getDocumentTypeIcon(doc.document_type);
|
const icon = getDocumentTypeIcon(doc.document_type);
|
||||||
const title = doc.title;
|
const title = doc.title;
|
||||||
const truncatedTitle = title.length > 30 ? `${title.slice(0, 30)}...` : title;
|
const truncatedTitle = title.length > 30 ? `${title.slice(0, 30)}...` : title;
|
||||||
return (
|
return (
|
||||||
|
|
@ -235,7 +235,7 @@ export function DocumentsTableShell({
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<span className="flex items-center gap-2">
|
<span className="flex items-center gap-2">
|
||||||
<Icon size={16} className="text-muted-foreground shrink-0" />
|
<span className="text-muted-foreground shrink-0">{icon}</span>
|
||||||
<span>{truncatedTitle}</span>
|
<span>{truncatedTitle}</span>
|
||||||
</span>
|
</span>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|
@ -293,7 +293,7 @@ export function DocumentsTableShell({
|
||||||
</div>
|
</div>
|
||||||
<div className="md:hidden divide-y">
|
<div className="md:hidden divide-y">
|
||||||
{sorted.map((doc) => {
|
{sorted.map((doc) => {
|
||||||
const Icon = getDocumentTypeIcon(doc.document_type);
|
const icon = getDocumentTypeIcon(doc.document_type);
|
||||||
return (
|
return (
|
||||||
<div key={doc.id} className="p-3">
|
<div key={doc.id} className="p-3">
|
||||||
<div className="flex items-start gap-3">
|
<div className="flex items-start gap-3">
|
||||||
|
|
@ -305,7 +305,7 @@ export function DocumentsTableShell({
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<div className="flex items-center justify-between gap-2">
|
<div className="flex items-center justify-between gap-2">
|
||||||
<div className="flex items-center gap-2 min-w-0">
|
<div className="flex items-center gap-2 min-w-0">
|
||||||
<Icon size={16} className="text-muted-foreground shrink-0" />
|
<span className="text-muted-foreground shrink-0">{icon}</span>
|
||||||
<div className="font-medium truncate">{doc.title}</div>
|
<div className="font-medium truncate">{doc.title}</div>
|
||||||
</div>
|
</div>
|
||||||
<RowActions
|
<RowActions
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import {
|
||||||
SheetTitle,
|
SheetTitle,
|
||||||
SheetTrigger,
|
SheetTrigger,
|
||||||
} from "@/components/ui/sheet";
|
} from "@/components/ui/sheet";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import { useDocumentByChunk } from "@/hooks/use-document-by-chunk";
|
import { useDocumentByChunk } from "@/hooks/use-document-by-chunk";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
|
@ -74,7 +75,7 @@ export const CitationDisplay: React.FC<{ index: number; node: any }> = ({ index,
|
||||||
<SheetContent side="right" className="w-full sm:max-w-5xl lg:max-w-7xl">
|
<SheetContent side="right" className="w-full sm:max-w-5xl lg:max-w-7xl">
|
||||||
<SheetHeader className="px-6 py-4 border-b">
|
<SheetHeader className="px-6 py-4 border-b">
|
||||||
<SheetTitle className="flex items-center gap-3 text-lg">
|
<SheetTitle className="flex items-center gap-3 text-lg">
|
||||||
<FileText className="h-6 w-6" />
|
{getConnectorIcon(sourceType)}
|
||||||
{document?.title || node?.metadata?.title || node?.metadata?.group_name || "Source"}
|
{document?.title || node?.metadata?.title || node?.metadata?.group_name || "Source"}
|
||||||
</SheetTitle>
|
</SheetTitle>
|
||||||
<SheetDescription className="text-base mt-2">
|
<SheetDescription className="text-base mt-2">
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,7 @@ import { Brain, Check, FolderOpen, Zap } from "lucide-react";
|
||||||
import { useParams } from "next/navigation";
|
import { useParams } from "next/navigation";
|
||||||
import React, { Suspense, useCallback, useState } from "react";
|
import React, { Suspense, useCallback, useState } from "react";
|
||||||
import type { ResearchMode } from "@/components/chat";
|
import type { ResearchMode } from "@/components/chat";
|
||||||
import {
|
import { ConnectorButton as ConnectorButtonComponent } from "@/components/chat/ConnectorComponents";
|
||||||
ConnectorButton as ConnectorButtonComponent,
|
|
||||||
getConnectorIcon,
|
|
||||||
} from "@/components/chat/ConnectorComponents";
|
|
||||||
import { DocumentsDataTable } from "@/components/chat/DocumentsDataTable";
|
import { DocumentsDataTable } from "@/components/chat/DocumentsDataTable";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
@ -27,6 +24,7 @@ import {
|
||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import { type Document, useDocuments } from "@/hooks/use-documents";
|
import { type Document, useDocuments } from "@/hooks/use-documents";
|
||||||
import { useLLMConfigs, useLLMPreferences } from "@/hooks/use-llm-configs";
|
import { useLLMConfigs, useLLMPreferences } from "@/hooks/use-llm-configs";
|
||||||
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,14 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { getAnnotationData, type Message } from "@llamaindex/chat-ui";
|
import { getAnnotationData, type Message } from "@llamaindex/chat-ui";
|
||||||
import {
|
import { ExternalLink, FileText } from "lucide-react";
|
||||||
IconBrandDiscord,
|
|
||||||
IconBrandGithub,
|
|
||||||
IconBrandNotion,
|
|
||||||
IconBrandSlack,
|
|
||||||
IconBrandYoutube,
|
|
||||||
} from "@tabler/icons-react";
|
|
||||||
import {
|
|
||||||
BookOpen,
|
|
||||||
Calendar,
|
|
||||||
CheckSquare,
|
|
||||||
Database,
|
|
||||||
ExternalLink,
|
|
||||||
FileText,
|
|
||||||
Globe,
|
|
||||||
Link2,
|
|
||||||
Mail,
|
|
||||||
Puzzle,
|
|
||||||
} from "lucide-react";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet";
|
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet";
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
|
|
||||||
interface Source {
|
interface Source {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
@ -56,86 +39,11 @@ interface SourceNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSourceIcon(type: string) {
|
function getSourceIcon(type: string) {
|
||||||
switch (type) {
|
// Handle USER_SELECTED_ prefix
|
||||||
// GitHub
|
const normalizedType = type.startsWith("USER_SELECTED_")
|
||||||
case "USER_SELECTED_GITHUB_CONNECTOR":
|
? type.replace("USER_SELECTED_", "")
|
||||||
case "GITHUB_CONNECTOR":
|
: type;
|
||||||
return <IconBrandGithub className="h-4 w-4" />;
|
return getConnectorIcon(normalizedType, "h-4 w-4");
|
||||||
|
|
||||||
// Notion
|
|
||||||
case "USER_SELECTED_NOTION_CONNECTOR":
|
|
||||||
case "NOTION_CONNECTOR":
|
|
||||||
return <IconBrandNotion className="h-4 w-4" />;
|
|
||||||
|
|
||||||
// Slack
|
|
||||||
case "USER_SELECTED_SLACK_CONNECTOR":
|
|
||||||
case "SLACK_CONNECTOR":
|
|
||||||
return <IconBrandSlack className="h-4 w-4" />;
|
|
||||||
|
|
||||||
// Discord
|
|
||||||
case "USER_SELECTED_DISCORD_CONNECTOR":
|
|
||||||
case "DISCORD_CONNECTOR":
|
|
||||||
return <IconBrandDiscord className="h-4 w-4" />;
|
|
||||||
|
|
||||||
// Google Calendar
|
|
||||||
case "USER_SELECTED_GOOGLE_CALENDAR_CONNECTOR":
|
|
||||||
case "GOOGLE_CALENDAR_CONNECTOR":
|
|
||||||
return <Calendar className="h-4 w-4" />;
|
|
||||||
|
|
||||||
// Google Gmail
|
|
||||||
case "USER_SELECTED_GOOGLE_GMAIL_CONNECTOR":
|
|
||||||
case "GOOGLE_GMAIL_CONNECTOR":
|
|
||||||
return <Mail className="h-4 w-4" />;
|
|
||||||
|
|
||||||
// Airtable
|
|
||||||
case "USER_SELECTED_AIRTABLE_CONNECTOR":
|
|
||||||
case "AIRTABLE_CONNECTOR":
|
|
||||||
return <Database className="h-4 w-4" />;
|
|
||||||
|
|
||||||
// YouTube
|
|
||||||
case "USER_SELECTED_YOUTUBE_VIDEO":
|
|
||||||
case "YOUTUBE_VIDEO":
|
|
||||||
return <IconBrandYoutube className="h-4 w-4" />;
|
|
||||||
|
|
||||||
// Linear
|
|
||||||
case "USER_SELECTED_LINEAR_CONNECTOR":
|
|
||||||
case "LINEAR_CONNECTOR":
|
|
||||||
return <CheckSquare className="h-4 w-4" />;
|
|
||||||
|
|
||||||
// Jira
|
|
||||||
case "USER_SELECTED_JIRA_CONNECTOR":
|
|
||||||
case "JIRA_CONNECTOR":
|
|
||||||
return <CheckSquare className="h-4 w-4" />;
|
|
||||||
|
|
||||||
// Confluence
|
|
||||||
case "USER_SELECTED_CONFLUENCE_CONNECTOR":
|
|
||||||
case "CONFLUENCE_CONNECTOR":
|
|
||||||
return <BookOpen className="h-4 w-4" />;
|
|
||||||
|
|
||||||
// ClickUp
|
|
||||||
case "USER_SELECTED_CLICKUP_CONNECTOR":
|
|
||||||
case "CLICKUP_CONNECTOR":
|
|
||||||
return <CheckSquare className="h-4 w-4" />;
|
|
||||||
|
|
||||||
// Files
|
|
||||||
case "USER_SELECTED_FILE":
|
|
||||||
case "FILE":
|
|
||||||
return <FileText className="h-4 w-4" />;
|
|
||||||
|
|
||||||
// Extension
|
|
||||||
case "USER_SELECTED_EXTENSION":
|
|
||||||
case "EXTENSION":
|
|
||||||
return <Puzzle className="h-4 w-4" />;
|
|
||||||
|
|
||||||
// Crawled URL
|
|
||||||
case "USER_SELECTED_CRAWLED_URL":
|
|
||||||
case "CRAWLED_URL":
|
|
||||||
return <Link2 className="h-4 w-4" />;
|
|
||||||
|
|
||||||
// Default for any other source type
|
|
||||||
default:
|
|
||||||
return <Globe className="h-4 w-4" />;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function SourceCard({ source }: { source: Source }) {
|
function SourceCard({ source }: { source: Source }) {
|
||||||
|
|
|
||||||
|
|
@ -1,81 +1,9 @@
|
||||||
import {
|
import { ChevronDown, FileText, MessageCircle, Plus } from "lucide-react";
|
||||||
IconBrandDiscord,
|
|
||||||
IconBrandGithub,
|
|
||||||
IconBrandNotion,
|
|
||||||
IconBrandSlack,
|
|
||||||
IconBrandYoutube,
|
|
||||||
IconCalendar,
|
|
||||||
IconLayoutKanban,
|
|
||||||
IconLinkPlus,
|
|
||||||
IconMail,
|
|
||||||
IconTable,
|
|
||||||
IconTicket,
|
|
||||||
} from "@tabler/icons-react";
|
|
||||||
import {
|
|
||||||
ChevronDown,
|
|
||||||
File,
|
|
||||||
FileText,
|
|
||||||
Globe,
|
|
||||||
Link,
|
|
||||||
MessageCircle,
|
|
||||||
Microscope,
|
|
||||||
Plus,
|
|
||||||
Search,
|
|
||||||
Sparkles,
|
|
||||||
Telescope,
|
|
||||||
Webhook,
|
|
||||||
} from "lucide-react";
|
|
||||||
import type React from "react";
|
import type React from "react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import type { Connector, ResearchMode } from "./types";
|
import type { Connector, ResearchMode } from "./types";
|
||||||
|
|
||||||
// Helper function to get connector icon
|
|
||||||
export const getConnectorIcon = (connectorType: string) => {
|
|
||||||
const iconProps = { className: "h-4 w-4" };
|
|
||||||
|
|
||||||
switch (connectorType) {
|
|
||||||
case "LINKUP_API":
|
|
||||||
return <IconLinkPlus {...iconProps} />;
|
|
||||||
case "LINEAR_CONNECTOR":
|
|
||||||
return <IconLayoutKanban {...iconProps} />;
|
|
||||||
case "GITHUB_CONNECTOR":
|
|
||||||
return <IconBrandGithub {...iconProps} />;
|
|
||||||
case "YOUTUBE_VIDEO":
|
|
||||||
return <IconBrandYoutube {...iconProps} />;
|
|
||||||
case "CRAWLED_URL":
|
|
||||||
return <Globe {...iconProps} />;
|
|
||||||
case "FILE":
|
|
||||||
return <File {...iconProps} />;
|
|
||||||
case "EXTENSION":
|
|
||||||
return <Webhook {...iconProps} />;
|
|
||||||
case "SERPER_API":
|
|
||||||
case "TAVILY_API":
|
|
||||||
return <Link {...iconProps} />;
|
|
||||||
case "SLACK_CONNECTOR":
|
|
||||||
return <IconBrandSlack {...iconProps} />;
|
|
||||||
case "NOTION_CONNECTOR":
|
|
||||||
return <IconBrandNotion {...iconProps} />;
|
|
||||||
case "DISCORD_CONNECTOR":
|
|
||||||
return <IconBrandDiscord {...iconProps} />;
|
|
||||||
case "JIRA_CONNECTOR":
|
|
||||||
return <IconTicket {...iconProps} />;
|
|
||||||
case "GOOGLE_CALENDAR_CONNECTOR":
|
|
||||||
return <IconCalendar {...iconProps} />;
|
|
||||||
case "GOOGLE_GMAIL_CONNECTOR":
|
|
||||||
return <IconMail {...iconProps} />;
|
|
||||||
case "AIRTABLE_CONNECTOR":
|
|
||||||
return <IconTable {...iconProps} />;
|
|
||||||
case "DEEP":
|
|
||||||
return <Sparkles {...iconProps} />;
|
|
||||||
case "DEEPER":
|
|
||||||
return <Microscope {...iconProps} />;
|
|
||||||
case "DEEPEST":
|
|
||||||
return <Telescope {...iconProps} />;
|
|
||||||
default:
|
|
||||||
return <Search {...iconProps} />;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const researcherOptions: {
|
export const researcherOptions: {
|
||||||
value: ResearchMode;
|
value: ResearchMode;
|
||||||
label: string;
|
label: string;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import {
|
||||||
} from "@tanstack/react-table";
|
} from "@tanstack/react-table";
|
||||||
import { ArrowUpDown, Calendar, FileText, Search } from "lucide-react";
|
import { ArrowUpDown, Calendar, FileText, Search } from "lucide-react";
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { Badge } from "@/components/ui/badge";
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
|
@ -33,6 +32,8 @@ import {
|
||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
|
import { EnumConnectorName } from "@/contracts/enums/connector";
|
||||||
|
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
|
||||||
import type { Document, DocumentType } from "@/hooks/use-documents";
|
import type { Document, DocumentType } from "@/hooks/use-documents";
|
||||||
|
|
||||||
interface DocumentsDataTableProps {
|
interface DocumentsDataTableProps {
|
||||||
|
|
@ -42,42 +43,16 @@ interface DocumentsDataTableProps {
|
||||||
initialSelectedDocuments?: Document[];
|
initialSelectedDocuments?: Document[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const DOCUMENT_TYPES: (DocumentType | "ALL")[] = [
|
// Combine EnumConnectorName with additional document types
|
||||||
|
const DOCUMENT_TYPES: (string | "ALL")[] = [
|
||||||
"ALL",
|
"ALL",
|
||||||
"FILE",
|
"FILE",
|
||||||
"EXTENSION",
|
"EXTENSION",
|
||||||
"CRAWLED_URL",
|
"CRAWLED_URL",
|
||||||
"YOUTUBE_VIDEO",
|
"YOUTUBE_VIDEO",
|
||||||
"SLACK_CONNECTOR",
|
...Object.values(EnumConnectorName),
|
||||||
"NOTION_CONNECTOR",
|
|
||||||
"GITHUB_CONNECTOR",
|
|
||||||
"LINEAR_CONNECTOR",
|
|
||||||
"DISCORD_CONNECTOR",
|
|
||||||
"JIRA_CONNECTOR",
|
|
||||||
"CONFLUENCE_CONNECTOR",
|
|
||||||
"CLICKUP_CONNECTOR",
|
|
||||||
"GOOGLE_CALENDAR_CONNECTOR",
|
|
||||||
"GOOGLE_GMAIL_CONNECTOR",
|
|
||||||
"AIRTABLE_CONNECTOR",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const getDocumentTypeColor = (type: DocumentType) => {
|
|
||||||
const colors = {
|
|
||||||
FILE: "bg-blue-50 text-blue-700 border-blue-200",
|
|
||||||
EXTENSION: "bg-green-50 text-green-700 border-green-200",
|
|
||||||
CRAWLED_URL: "bg-purple-50 text-purple-700 border-purple-200",
|
|
||||||
YOUTUBE_VIDEO: "bg-red-50 text-red-700 border-red-200",
|
|
||||||
SLACK_CONNECTOR: "bg-yellow-50 text-yellow-700 border-yellow-200",
|
|
||||||
NOTION_CONNECTOR: "bg-indigo-50 text-indigo-700 border-indigo-200",
|
|
||||||
GITHUB_CONNECTOR: "bg-gray-50 text-gray-700 border-gray-200",
|
|
||||||
LINEAR_CONNECTOR: "bg-pink-50 text-pink-700 border-pink-200",
|
|
||||||
DISCORD_CONNECTOR: "bg-violet-50 text-violet-700 border-violet-200",
|
|
||||||
JIRA_CONNECTOR: "bg-orange-50 text-orange-700 border-orange-200",
|
|
||||||
CONFLUENCE_CONNECTOR: "bg-teal-50 text-teal-700 border-teal-200",
|
|
||||||
};
|
|
||||||
return colors[type] || "bg-gray-50 text-gray-700 border-gray-200";
|
|
||||||
};
|
|
||||||
|
|
||||||
const columns: ColumnDef<Document>[] = [
|
const columns: ColumnDef<Document>[] = [
|
||||||
{
|
{
|
||||||
id: "select",
|
id: "select",
|
||||||
|
|
@ -133,13 +108,9 @@ const columns: ColumnDef<Document>[] = [
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const type = row.getValue("document_type") as DocumentType;
|
const type = row.getValue("document_type") as DocumentType;
|
||||||
return (
|
return (
|
||||||
<Badge
|
<div className="flex items-center gap-2" title={type}>
|
||||||
variant="outline"
|
<span className="text-primary">{getConnectorIcon(type)}</span>
|
||||||
className={`${getDocumentTypeColor(type)} text-[10px] sm:text-xs px-1 sm:px-2`}
|
</div>
|
||||||
>
|
|
||||||
<span className="hidden sm:inline">{type.replace(/_/g, " ")}</span>
|
|
||||||
<span className="sm:hidden">{type.split("_")[0]}</span>
|
|
||||||
</Badge>
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
size: 80,
|
size: 80,
|
||||||
|
|
@ -214,7 +185,7 @@ export function DocumentsDataTable({
|
||||||
const [sorting, setSorting] = useState<SortingState>([]);
|
const [sorting, setSorting] = useState<SortingState>([]);
|
||||||
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
|
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
|
||||||
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
|
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
|
||||||
const [documentTypeFilter, setDocumentTypeFilter] = useState<DocumentType | "ALL">("ALL");
|
const [documentTypeFilter, setDocumentTypeFilter] = useState<string | "ALL">("ALL");
|
||||||
|
|
||||||
// Memoize initial row selection to prevent infinite loops
|
// Memoize initial row selection to prevent infinite loops
|
||||||
const initialRowSelection = useMemo(() => {
|
const initialRowSelection = useMemo(() => {
|
||||||
|
|
@ -311,7 +282,7 @@ export function DocumentsDataTable({
|
||||||
</div>
|
</div>
|
||||||
<Select
|
<Select
|
||||||
value={documentTypeFilter}
|
value={documentTypeFilter}
|
||||||
onValueChange={(value) => setDocumentTypeFilter(value as DocumentType | "ALL")}
|
onValueChange={(value) => setDocumentTypeFilter(value as string | "ALL")}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="w-full sm:w-[180px]">
|
<SelectTrigger className="w-full sm:w-[180px]">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
|
|
|
||||||
70
surfsense_web/contracts/enums/connectorIcons.tsx
Normal file
70
surfsense_web/contracts/enums/connectorIcons.tsx
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
import {
|
||||||
|
IconBook,
|
||||||
|
IconBrandDiscord,
|
||||||
|
IconBrandGithub,
|
||||||
|
IconBrandNotion,
|
||||||
|
IconBrandSlack,
|
||||||
|
IconBrandYoutube,
|
||||||
|
IconCalendar,
|
||||||
|
IconChecklist,
|
||||||
|
IconLayoutKanban,
|
||||||
|
IconLinkPlus,
|
||||||
|
IconMail,
|
||||||
|
IconTable,
|
||||||
|
IconTicket,
|
||||||
|
IconWorldWww,
|
||||||
|
} from "@tabler/icons-react";
|
||||||
|
import { File, Globe, Link, Microscope, Search, Sparkles, Telescope, Webhook } from "lucide-react";
|
||||||
|
import { EnumConnectorName } from "./connector";
|
||||||
|
|
||||||
|
export const getConnectorIcon = (connectorType: EnumConnectorName | string, className?: string) => {
|
||||||
|
const iconProps = { className: className || "h-4 w-4" };
|
||||||
|
|
||||||
|
switch (connectorType) {
|
||||||
|
case EnumConnectorName.LINKUP_API:
|
||||||
|
return <IconLinkPlus {...iconProps} />;
|
||||||
|
case EnumConnectorName.LINEAR_CONNECTOR:
|
||||||
|
return <IconLayoutKanban {...iconProps} />;
|
||||||
|
case EnumConnectorName.GITHUB_CONNECTOR:
|
||||||
|
return <IconBrandGithub {...iconProps} />;
|
||||||
|
case EnumConnectorName.SERPER_API:
|
||||||
|
return <Link {...iconProps} />;
|
||||||
|
case EnumConnectorName.TAVILY_API:
|
||||||
|
return <IconWorldWww {...iconProps} />;
|
||||||
|
case EnumConnectorName.SLACK_CONNECTOR:
|
||||||
|
return <IconBrandSlack {...iconProps} />;
|
||||||
|
case EnumConnectorName.NOTION_CONNECTOR:
|
||||||
|
return <IconBrandNotion {...iconProps} />;
|
||||||
|
case EnumConnectorName.DISCORD_CONNECTOR:
|
||||||
|
return <IconBrandDiscord {...iconProps} />;
|
||||||
|
case EnumConnectorName.JIRA_CONNECTOR:
|
||||||
|
return <IconTicket {...iconProps} />;
|
||||||
|
case EnumConnectorName.GOOGLE_CALENDAR_CONNECTOR:
|
||||||
|
return <IconCalendar {...iconProps} />;
|
||||||
|
case EnumConnectorName.GOOGLE_GMAIL_CONNECTOR:
|
||||||
|
return <IconMail {...iconProps} />;
|
||||||
|
case EnumConnectorName.AIRTABLE_CONNECTOR:
|
||||||
|
return <IconTable {...iconProps} />;
|
||||||
|
case EnumConnectorName.CONFLUENCE_CONNECTOR:
|
||||||
|
return <IconBook {...iconProps} />;
|
||||||
|
case EnumConnectorName.CLICKUP_CONNECTOR:
|
||||||
|
return <IconChecklist {...iconProps} />;
|
||||||
|
// Additional cases for non-enum connector types
|
||||||
|
case "YOUTUBE_VIDEO":
|
||||||
|
return <IconBrandYoutube {...iconProps} />;
|
||||||
|
case "CRAWLED_URL":
|
||||||
|
return <Globe {...iconProps} />;
|
||||||
|
case "FILE":
|
||||||
|
return <File {...iconProps} />;
|
||||||
|
case "EXTENSION":
|
||||||
|
return <Webhook {...iconProps} />;
|
||||||
|
case "DEEP":
|
||||||
|
return <Sparkles {...iconProps} />;
|
||||||
|
case "DEEPER":
|
||||||
|
return <Microscope {...iconProps} />;
|
||||||
|
case "DEEPEST":
|
||||||
|
return <Telescope {...iconProps} />;
|
||||||
|
default:
|
||||||
|
return <Search {...iconProps} />;
|
||||||
|
}
|
||||||
|
};
|
||||||
Loading…
Add table
Add a link
Reference in a new issue