mirror of
https://github.com/MODSetter/SurfSense.git
synced 2025-09-02 02:29:08 +00:00
Add UI implementations
This commit is contained in:
parent
2fd97c2e4d
commit
6b2cd9705f
7 changed files with 454 additions and 6 deletions
|
@ -36,6 +36,7 @@ from app.schemas import (
|
||||||
SearchSourceConnectorUpdate,
|
SearchSourceConnectorUpdate,
|
||||||
)
|
)
|
||||||
from app.tasks.connectors_indexing_tasks import (
|
from app.tasks.connectors_indexing_tasks import (
|
||||||
|
index_confluence_pages,
|
||||||
index_discord_messages,
|
index_discord_messages,
|
||||||
index_github_repos,
|
index_github_repos,
|
||||||
index_jira_issues,
|
index_jira_issues,
|
||||||
|
@ -457,6 +458,21 @@ async def index_connector_content(
|
||||||
)
|
)
|
||||||
response_message = "Jira indexing started in the background."
|
response_message = "Jira indexing started in the background."
|
||||||
|
|
||||||
|
elif connector.connector_type == SearchSourceConnectorType.CONFLUENCE_CONNECTOR:
|
||||||
|
# Run indexing in background
|
||||||
|
logger.info(
|
||||||
|
f"Triggering Confluence indexing for connector {connector_id} into search space {search_space_id} from {indexing_from} to {indexing_to}"
|
||||||
|
)
|
||||||
|
background_tasks.add_task(
|
||||||
|
run_confluence_indexing_with_new_session,
|
||||||
|
connector_id,
|
||||||
|
search_space_id,
|
||||||
|
str(user.id),
|
||||||
|
indexing_from,
|
||||||
|
indexing_to,
|
||||||
|
)
|
||||||
|
response_message = "Confluence indexing started in the background."
|
||||||
|
|
||||||
elif connector.connector_type == SearchSourceConnectorType.DISCORD_CONNECTOR:
|
elif connector.connector_type == SearchSourceConnectorType.DISCORD_CONNECTOR:
|
||||||
# Run indexing in background
|
# Run indexing in background
|
||||||
logger.info(
|
logger.info(
|
||||||
|
@ -884,3 +900,61 @@ async def run_jira_indexing(
|
||||||
exc_info=True,
|
exc_info=True,
|
||||||
)
|
)
|
||||||
# Optionally update status in DB to indicate failure
|
# Optionally update status in DB to indicate failure
|
||||||
|
|
||||||
|
|
||||||
|
# Add new helper functions for Confluence indexing
|
||||||
|
async def run_confluence_indexing_with_new_session(
|
||||||
|
connector_id: int,
|
||||||
|
search_space_id: int,
|
||||||
|
user_id: str,
|
||||||
|
start_date: str,
|
||||||
|
end_date: str,
|
||||||
|
):
|
||||||
|
"""Wrapper to run Confluence indexing with its own database session."""
|
||||||
|
logger.info(
|
||||||
|
f"Background task started: Indexing Confluence connector {connector_id} into space {search_space_id} from {start_date} to {end_date}"
|
||||||
|
)
|
||||||
|
async with async_session_maker() as session:
|
||||||
|
await run_confluence_indexing(
|
||||||
|
session, connector_id, search_space_id, user_id, start_date, end_date
|
||||||
|
)
|
||||||
|
logger.info(f"Background task finished: Indexing Confluence connector {connector_id}")
|
||||||
|
|
||||||
|
|
||||||
|
async def run_confluence_indexing(
|
||||||
|
session: AsyncSession,
|
||||||
|
connector_id: int,
|
||||||
|
search_space_id: int,
|
||||||
|
user_id: str,
|
||||||
|
start_date: str,
|
||||||
|
end_date: str,
|
||||||
|
):
|
||||||
|
"""Runs the Confluence indexing task and updates the timestamp."""
|
||||||
|
try:
|
||||||
|
indexed_count, error_message = await index_confluence_pages(
|
||||||
|
session,
|
||||||
|
connector_id,
|
||||||
|
search_space_id,
|
||||||
|
user_id,
|
||||||
|
start_date,
|
||||||
|
end_date,
|
||||||
|
update_last_indexed=False,
|
||||||
|
)
|
||||||
|
if error_message:
|
||||||
|
logger.error(
|
||||||
|
f"Confluence indexing failed for connector {connector_id}: {error_message}"
|
||||||
|
)
|
||||||
|
# Optionally update status in DB to indicate failure
|
||||||
|
else:
|
||||||
|
logger.info(
|
||||||
|
f"Confluence indexing successful for connector {connector_id}. Indexed {indexed_count} documents."
|
||||||
|
)
|
||||||
|
# Update the last indexed timestamp only on success
|
||||||
|
await update_connector_last_indexed(session, connector_id)
|
||||||
|
await session.commit() # Commit timestamp update
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(
|
||||||
|
f"Critical error in run_confluence_indexing for connector {connector_id}: {e}",
|
||||||
|
exc_info=True,
|
||||||
|
)
|
||||||
|
# Optionally update status in DB to indicate failure
|
||||||
|
|
|
@ -208,6 +208,33 @@ export default function EditConnectorPage() {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* == Confluence == */}
|
||||||
|
{connector.connector_type === "CONFLUENCE_CONNECTOR" && (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<EditSimpleTokenForm
|
||||||
|
control={editForm.control}
|
||||||
|
fieldName="CONFLUENCE_BASE_URL"
|
||||||
|
fieldLabel="Confluence Base URL"
|
||||||
|
fieldDescription="Update your Confluence instance URL if needed."
|
||||||
|
placeholder="https://yourcompany.atlassian.net"
|
||||||
|
/>
|
||||||
|
<EditSimpleTokenForm
|
||||||
|
control={editForm.control}
|
||||||
|
fieldName="CONFLUENCE_EMAIL"
|
||||||
|
fieldLabel="Confluence Email"
|
||||||
|
fieldDescription="Update your Atlassian account email if needed."
|
||||||
|
placeholder="your.email@company.com"
|
||||||
|
/>
|
||||||
|
<EditSimpleTokenForm
|
||||||
|
control={editForm.control}
|
||||||
|
fieldName="CONFLUENCE_API_TOKEN"
|
||||||
|
fieldLabel="Confluence API Token"
|
||||||
|
fieldDescription="Update your Confluence API Token if needed."
|
||||||
|
placeholder="Your Confluence API Token"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* == Linkup == */}
|
{/* == Linkup == */}
|
||||||
{connector.connector_type === "LINKUP_API" && (
|
{connector.connector_type === "LINKUP_API" && (
|
||||||
<EditSimpleTokenForm
|
<EditSimpleTokenForm
|
||||||
|
|
|
@ -0,0 +1,324 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useRouter, useParams } from "next/navigation";
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import * as z from "zod";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { ArrowLeft, Check, Info, Loader2 } from "lucide-react";
|
||||||
|
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormDescription,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
|
import {
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardDescription,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
} from "@/components/ui/card";
|
||||||
|
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||||
|
|
||||||
|
import { useSearchSourceConnectors } from "@/hooks/useSearchSourceConnectors";
|
||||||
|
|
||||||
|
// Define the form schema with Zod
|
||||||
|
const confluenceConnectorFormSchema = z.object({
|
||||||
|
name: z.string().min(3, {
|
||||||
|
message: "Connector name must be at least 3 characters.",
|
||||||
|
}),
|
||||||
|
base_url: z
|
||||||
|
.string()
|
||||||
|
.url({
|
||||||
|
message:
|
||||||
|
"Please enter a valid Confluence URL (e.g., https://yourcompany.atlassian.net)",
|
||||||
|
})
|
||||||
|
.refine(
|
||||||
|
(url) => {
|
||||||
|
return url.includes("atlassian.net") || url.includes("confluence");
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message: "Please enter a valid Confluence instance URL",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
email: z.string().email({
|
||||||
|
message: "Please enter a valid email address.",
|
||||||
|
}),
|
||||||
|
api_token: z.string().min(10, {
|
||||||
|
message: "Confluence API Token is required and must be valid.",
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Define the type for the form values
|
||||||
|
type ConfluenceConnectorFormValues = z.infer<typeof confluenceConnectorFormSchema>;
|
||||||
|
|
||||||
|
export default function ConfluenceConnectorPage() {
|
||||||
|
const router = useRouter();
|
||||||
|
const params = useParams();
|
||||||
|
const searchSpaceId = params.search_space_id as string;
|
||||||
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
|
const { createConnector } = useSearchSourceConnectors();
|
||||||
|
|
||||||
|
// Initialize the form
|
||||||
|
const form = useForm<ConfluenceConnectorFormValues>({
|
||||||
|
resolver: zodResolver(confluenceConnectorFormSchema),
|
||||||
|
defaultValues: {
|
||||||
|
name: "Confluence Connector",
|
||||||
|
base_url: "",
|
||||||
|
email: "",
|
||||||
|
api_token: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle form submission
|
||||||
|
const onSubmit = async (values: ConfluenceConnectorFormValues) => {
|
||||||
|
setIsSubmitting(true);
|
||||||
|
try {
|
||||||
|
await createConnector({
|
||||||
|
name: values.name,
|
||||||
|
connector_type: "CONFLUENCE_CONNECTOR",
|
||||||
|
config: {
|
||||||
|
CONFLUENCE_BASE_URL: values.base_url,
|
||||||
|
CONFLUENCE_EMAIL: values.email,
|
||||||
|
CONFLUENCE_API_TOKEN: values.api_token,
|
||||||
|
},
|
||||||
|
is_indexable: true,
|
||||||
|
last_indexed_at: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
toast.success("Confluence connector created successfully!");
|
||||||
|
|
||||||
|
// Navigate back to connectors page
|
||||||
|
router.push(`/dashboard/${searchSpaceId}/connectors`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error creating connector:", error);
|
||||||
|
toast.error(
|
||||||
|
error instanceof Error ? error.message : "Failed to create connector",
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
setIsSubmitting(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container mx-auto py-8 max-w-3xl">
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
className="mb-6"
|
||||||
|
onClick={() =>
|
||||||
|
router.push(`/dashboard/${searchSpaceId}/connectors/add`)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ArrowLeft className="mr-2 h-4 w-4" />
|
||||||
|
Back to Connectors
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
>
|
||||||
|
<Tabs defaultValue="connect" className="w-full">
|
||||||
|
<TabsList className="grid w-full grid-cols-2 mb-6">
|
||||||
|
<TabsTrigger value="connect">Connect</TabsTrigger>
|
||||||
|
<TabsTrigger value="documentation">Documentation</TabsTrigger>
|
||||||
|
</TabsList>
|
||||||
|
|
||||||
|
<TabsContent value="connect">
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>Connect to Confluence</CardTitle>
|
||||||
|
<CardDescription>
|
||||||
|
Connect your Confluence instance to index pages and comments from your spaces.
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="space-y-6">
|
||||||
|
<Alert>
|
||||||
|
<Info className="h-4 w-4" />
|
||||||
|
<AlertDescription>
|
||||||
|
You'll need to create an API token from your{" "}
|
||||||
|
<a
|
||||||
|
href="https://id.atlassian.com/manage-profile/security/api-tokens"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="font-medium underline underline-offset-4"
|
||||||
|
>
|
||||||
|
Atlassian Account Settings
|
||||||
|
</a>
|
||||||
|
</AlertDescription>
|
||||||
|
</Alert>
|
||||||
|
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
className="space-y-6"
|
||||||
|
>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="name"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Connector Name</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input placeholder="My Confluence Connector" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
<FormDescription>
|
||||||
|
A friendly name to identify this connector.
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="base_url"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Confluence Instance URL</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder="https://yourcompany.atlassian.net"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormDescription>
|
||||||
|
Your Confluence instance URL. For Atlassian Cloud, this is
|
||||||
|
typically https://yourcompany.atlassian.net
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="email"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Email Address</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
type="email"
|
||||||
|
placeholder="your.email@company.com"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormDescription>
|
||||||
|
Your Atlassian account email address.
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="api_token"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>API Token</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
type="password"
|
||||||
|
placeholder="Your Confluence API Token"
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormDescription>
|
||||||
|
Your Confluence API Token will be encrypted and stored securely.
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="flex justify-end">
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
className="w-full sm:w-auto"
|
||||||
|
>
|
||||||
|
{isSubmitting ? (
|
||||||
|
<>
|
||||||
|
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||||
|
Connecting...
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Check className="mr-2 h-4 w-4" />
|
||||||
|
Connect Confluence
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</TabsContent>
|
||||||
|
|
||||||
|
<TabsContent value="documentation">
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>Confluence Integration Guide</CardTitle>
|
||||||
|
<CardDescription>
|
||||||
|
Learn how to set up and use the Confluence connector.
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="space-y-6">
|
||||||
|
<div>
|
||||||
|
<h3 className="text-lg font-semibold mb-3">What gets indexed?</h3>
|
||||||
|
<ul className="list-disc list-inside space-y-2 text-sm text-muted-foreground">
|
||||||
|
<li>All pages from accessible spaces</li>
|
||||||
|
<li>Page content and metadata</li>
|
||||||
|
<li>Comments on pages (both footer and inline comments)</li>
|
||||||
|
<li>Page titles and descriptions</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h3 className="text-lg font-semibold mb-3">Setup Instructions</h3>
|
||||||
|
<ol className="list-decimal list-inside space-y-2 text-sm text-muted-foreground">
|
||||||
|
<li>Go to your Atlassian Account Settings</li>
|
||||||
|
<li>Navigate to Security → API tokens</li>
|
||||||
|
<li>Create a new API token with appropriate permissions</li>
|
||||||
|
<li>Copy the token and paste it in the form above</li>
|
||||||
|
<li>Ensure your account has read access to the spaces you want to index</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h3 className="text-lg font-semibold mb-3">Permissions Required</h3>
|
||||||
|
<ul className="list-disc list-inside space-y-2 text-sm text-muted-foreground">
|
||||||
|
<li>Read access to Confluence spaces</li>
|
||||||
|
<li>View pages and comments</li>
|
||||||
|
<li>Access to space metadata</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Alert>
|
||||||
|
<Info className="h-4 w-4" />
|
||||||
|
<AlertDescription>
|
||||||
|
The connector will only index content that your account has permission to view.
|
||||||
|
Make sure your API token has the necessary permissions for the spaces you want to index.
|
||||||
|
</AlertDescription>
|
||||||
|
</Alert>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</TabsContent>
|
||||||
|
</Tabs>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import {
|
||||||
CollapsibleTrigger,
|
CollapsibleTrigger,
|
||||||
} from "@/components/ui/collapsible";
|
} from "@/components/ui/collapsible";
|
||||||
import {
|
import {
|
||||||
|
IconBook,
|
||||||
IconBrandDiscord,
|
IconBrandDiscord,
|
||||||
IconBrandGithub,
|
IconBrandGithub,
|
||||||
IconBrandNotion,
|
IconBrandNotion,
|
||||||
|
@ -141,6 +142,14 @@ const connectorCategories: ConnectorCategory[] = [
|
||||||
icon: <IconBrandGithub className="h-6 w-6" />,
|
icon: <IconBrandGithub className="h-6 w-6" />,
|
||||||
status: "available",
|
status: "available",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "confluence-connector",
|
||||||
|
title: "Confluence",
|
||||||
|
description:
|
||||||
|
"Connect to Confluence to search pages, comments and documentation.",
|
||||||
|
icon: <IconBook className="h-6 w-6" />,
|
||||||
|
status: "available",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,6 +57,7 @@ import {
|
||||||
IconBrandDiscord,
|
IconBrandDiscord,
|
||||||
IconBrandGithub,
|
IconBrandGithub,
|
||||||
IconBrandNotion,
|
IconBrandNotion,
|
||||||
|
IconBrandPagekit,
|
||||||
IconBrandSlack,
|
IconBrandSlack,
|
||||||
IconBrandYoutube,
|
IconBrandYoutube,
|
||||||
IconLayoutKanban,
|
IconLayoutKanban,
|
||||||
|
@ -180,6 +181,7 @@ const documentTypeIcons = {
|
||||||
LINEAR_CONNECTOR: IconLayoutKanban,
|
LINEAR_CONNECTOR: IconLayoutKanban,
|
||||||
JIRA_CONNECTOR: IconTicket,
|
JIRA_CONNECTOR: IconTicket,
|
||||||
DISCORD_CONNECTOR: IconBrandDiscord,
|
DISCORD_CONNECTOR: IconBrandDiscord,
|
||||||
|
CONFLUENCE_CONNECTOR: IconBrandPagekit,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
const columns: ColumnDef<Document>[] = [
|
const columns: ColumnDef<Document>[] = [
|
||||||
|
|
|
@ -32,5 +32,11 @@ export const editConnectorSchema = z.object({
|
||||||
LINEAR_API_KEY: z.string().optional(),
|
LINEAR_API_KEY: z.string().optional(),
|
||||||
LINKUP_API_KEY: z.string().optional(),
|
LINKUP_API_KEY: z.string().optional(),
|
||||||
DISCORD_BOT_TOKEN: z.string().optional(),
|
DISCORD_BOT_TOKEN: z.string().optional(),
|
||||||
|
CONFLUENCE_BASE_URL: z.string().optional(),
|
||||||
|
CONFLUENCE_EMAIL: z.string().optional(),
|
||||||
|
CONFLUENCE_API_TOKEN: z.string().optional(),
|
||||||
|
JIRA_BASE_URL: z.string().optional(),
|
||||||
|
JIRA_EMAIL: z.string().optional(),
|
||||||
|
JIRA_API_TOKEN: z.string().optional(),
|
||||||
});
|
});
|
||||||
export type EditConnectorFormValues = z.infer<typeof editConnectorSchema>;
|
export type EditConnectorFormValues = z.infer<typeof editConnectorSchema>;
|
||||||
|
|
|
@ -43,6 +43,12 @@ export function useConnectorEditPage(connectorId: number, searchSpaceId: string)
|
||||||
TAVILY_API_KEY: "",
|
TAVILY_API_KEY: "",
|
||||||
LINEAR_API_KEY: "",
|
LINEAR_API_KEY: "",
|
||||||
DISCORD_BOT_TOKEN: "",
|
DISCORD_BOT_TOKEN: "",
|
||||||
|
CONFLUENCE_BASE_URL: "",
|
||||||
|
CONFLUENCE_EMAIL: "",
|
||||||
|
CONFLUENCE_API_TOKEN: "",
|
||||||
|
JIRA_BASE_URL: "",
|
||||||
|
JIRA_EMAIL: "",
|
||||||
|
JIRA_API_TOKEN: "",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue