mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-03-17 21:32:36 +01:00
Add confluence connector page
This commit is contained in:
parent
49804dcc44
commit
b05bf963bf
@ -6,7 +6,7 @@ const nextConfig = {
|
||||
output: "standalone",
|
||||
redirects: async () => {
|
||||
// In production, something else (nginx in the one box setup) should take
|
||||
// care of this redirect. TODO (chris): better support setups where
|
||||
// care of this redirect. TODO (chris): better support setups where
|
||||
// web_server and api_server are on different machines.
|
||||
if (process.env.NODE_ENV === "production") return [];
|
||||
|
||||
|
9
web/package-lock.json
generated
9
web/package-lock.json
generated
@ -20,6 +20,7 @@
|
||||
"postcss": "^8.4.23",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-icons": "^4.8.0",
|
||||
"swr": "^2.1.5",
|
||||
"tailwindcss": "^3.3.1",
|
||||
"typescript": "5.0.3",
|
||||
@ -3256,6 +3257,14 @@
|
||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz",
|
||||
"integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw=="
|
||||
},
|
||||
"node_modules/react-icons": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.8.0.tgz",
|
||||
"integrity": "sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==",
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
|
@ -21,6 +21,7 @@
|
||||
"postcss": "^8.4.23",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-icons": "^4.8.0",
|
||||
"swr": "^2.1.5",
|
||||
"tailwindcss": "^3.3.1",
|
||||
"typescript": "5.0.3",
|
||||
|
62
web/src/app/admin/connectors/confluence/page.tsx
Normal file
62
web/src/app/admin/connectors/confluence/page.tsx
Normal file
@ -0,0 +1,62 @@
|
||||
"use client";
|
||||
|
||||
import * as Yup from "yup";
|
||||
import { IndexForm } from "@/components/admin/connectors/Form";
|
||||
import { ConfluenceIcon } from "@/components/icons/icons";
|
||||
import { TextFormField } from "@/components/admin/connectors/Field";
|
||||
import { HealthCheckBanner } from "@/components/health/healthcheck";
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div className="mx-auto">
|
||||
<div className="mb-4">
|
||||
<HealthCheckBanner />
|
||||
</div>
|
||||
<div className="border-solid border-gray-600 border-b mb-4 pb-2 flex">
|
||||
<ConfluenceIcon size="32" />
|
||||
<h1 className="text-3xl font-bold pl-2">Confluence</h1>
|
||||
</div>
|
||||
|
||||
{/* TODO: make this periodic */}
|
||||
<h2 className="text-xl font-bold mb-2 mt-6 ml-auto mr-auto">
|
||||
Request Indexing
|
||||
</h2>
|
||||
<p className="text-sm mb-4">
|
||||
To use the Confluence connector, you must first follow the guide
|
||||
described{" "}
|
||||
<a
|
||||
className="text-blue-500"
|
||||
href="https://docs.danswer.dev/connectors/slack#setting-up"
|
||||
>
|
||||
here
|
||||
</a>{" "}
|
||||
to give the Danswer backend read access to your documents. Once that is
|
||||
setup, specify any link to a Confluence page below and click
|
||||
"Index" to Index. Based on the provided link, we will index
|
||||
the ENTIRE SPACE, not just the specified page. For example, entering{" "}
|
||||
<i>https://danswer.atlassian.net/wiki/spaces/SD/overview</i> and
|
||||
clicking the Index button will index the whole <i>SD</i> Confluence
|
||||
space.
|
||||
</p>
|
||||
<div className="border-solid border-gray-600 border rounded-md p-6">
|
||||
<IndexForm
|
||||
source="confluence"
|
||||
formBody={
|
||||
<>
|
||||
<TextFormField name="wiki_page_url" label="Confluence URL:" />
|
||||
</>
|
||||
}
|
||||
validationSchema={Yup.object().shape({
|
||||
wiki_page_url: Yup.string().required(
|
||||
"Please enter any link to your confluence e.g. https://danswer.atlassian.net/wiki/spaces/SD/overview"
|
||||
),
|
||||
})}
|
||||
initialValues={{
|
||||
wiki_page_url: "",
|
||||
}}
|
||||
onSubmit={(isSuccess) => console.log(isSuccess)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -7,6 +7,7 @@ import {
|
||||
GoogleDriveIcon,
|
||||
SlackIcon,
|
||||
KeyIcon,
|
||||
ConfluenceIcon,
|
||||
} from "@/components/icons/icons";
|
||||
import { DISABLE_AUTH } from "@/lib/constants";
|
||||
import { getCurrentUserSS } from "@/lib/userSS";
|
||||
@ -41,7 +42,7 @@ export default async function AdminLayout({
|
||||
{
|
||||
name: (
|
||||
<div className="flex">
|
||||
<NotebookIcon size="16" />
|
||||
<NotebookIcon size="18" />
|
||||
<div className="ml-1">Status</div>
|
||||
</div>
|
||||
),
|
||||
@ -88,6 +89,15 @@ export default async function AdminLayout({
|
||||
),
|
||||
link: "/admin/connectors/google-drive",
|
||||
},
|
||||
{
|
||||
name: (
|
||||
<div className="flex">
|
||||
<ConfluenceIcon size="16" />
|
||||
<div className="ml-1">Confluence</div>
|
||||
</div>
|
||||
),
|
||||
link: "/admin/connectors/confluence",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -96,7 +106,7 @@ export default async function AdminLayout({
|
||||
{
|
||||
name: (
|
||||
<div className="flex">
|
||||
<KeyIcon size="16" />
|
||||
<KeyIcon size="18" />
|
||||
<div className="ml-1">OpenAI</div>
|
||||
</div>
|
||||
),
|
||||
|
@ -3,24 +3,27 @@ import { ErrorMessage, Field } from "formik";
|
||||
interface TextFormFieldProps {
|
||||
name: string;
|
||||
label: string;
|
||||
subtext?: string;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
export const TextFormField = ({
|
||||
name,
|
||||
label,
|
||||
subtext,
|
||||
type = "text",
|
||||
}: TextFormFieldProps) => {
|
||||
return (
|
||||
<div className="mb-4">
|
||||
<label htmlFor={name} className="block mb-1">
|
||||
<label htmlFor={name} className="block">
|
||||
{label}
|
||||
</label>
|
||||
{subtext && <p className="text-xs">{subtext}</p>}
|
||||
<Field
|
||||
type={type}
|
||||
name={name}
|
||||
id={name}
|
||||
className="border bg-slate-700 text-gray-200 border-gray-300 rounded w-full py-2 px-3"
|
||||
className="border bg-slate-700 text-gray-200 border-gray-300 rounded w-full py-2 px-3 mt-1"
|
||||
/>
|
||||
<ErrorMessage
|
||||
name={name}
|
||||
|
@ -18,7 +18,10 @@ export const submitIndexRequest = async (
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ connector_specific_config: values, input_type: inputType }),
|
||||
body: JSON.stringify({
|
||||
connector_specific_config: values,
|
||||
input_type: inputType,
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -1,16 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { ValidSources } from "@/lib/types";
|
||||
import {
|
||||
Globe,
|
||||
SlackLogo,
|
||||
GithubLogo,
|
||||
GoogleDriveLogo,
|
||||
Notebook,
|
||||
Key,
|
||||
Trash,
|
||||
Info,
|
||||
} from "@phosphor-icons/react";
|
||||
import { Notebook, Key, Trash, Info } from "@phosphor-icons/react";
|
||||
import { SiConfluence, SiGithub, SiGoogledrive, SiSlack } from "react-icons/si";
|
||||
import { FaGlobe } from "react-icons/fa";
|
||||
|
||||
interface IconProps {
|
||||
size?: string;
|
||||
@ -44,28 +36,35 @@ export const GlobeIcon = ({
|
||||
size = "16",
|
||||
className = defaultTailwindCSS,
|
||||
}: IconProps) => {
|
||||
return <Globe size={size} className={className} />;
|
||||
return <FaGlobe size={size} className={className} />;
|
||||
};
|
||||
|
||||
export const SlackIcon = ({
|
||||
size = "16",
|
||||
className = defaultTailwindCSS,
|
||||
}: IconProps) => {
|
||||
return <SlackLogo size={size} className={className} />;
|
||||
return <SiSlack size={size} className={className} />;
|
||||
};
|
||||
|
||||
export const GithubIcon = ({
|
||||
size = "16",
|
||||
className = defaultTailwindCSS,
|
||||
}: IconProps) => {
|
||||
return <GithubLogo size={size} className={className} />;
|
||||
return <SiGithub size={size} className={className} />;
|
||||
};
|
||||
|
||||
export const GoogleDriveIcon = ({
|
||||
size = "16",
|
||||
className = defaultTailwindCSS,
|
||||
}: IconProps) => {
|
||||
return <GoogleDriveLogo size={size} className={className} />;
|
||||
return <SiGoogledrive size={size} className={className} />;
|
||||
};
|
||||
|
||||
export const ConfluenceIcon = ({
|
||||
size = "16",
|
||||
className = defaultTailwindCSS,
|
||||
}: IconProps) => {
|
||||
return <SiConfluence size={size} className={className} />;
|
||||
};
|
||||
|
||||
export const InfoIcon = ({
|
||||
|
@ -82,13 +82,13 @@ export const SearchResultsDisplay: React.FC<SearchResultsDisplayProps> = ({
|
||||
{dedupedQuotes.map((quoteInfo) => (
|
||||
<a
|
||||
key={quoteInfo.document_id}
|
||||
className="p-2 ml-1 border border-gray-800 rounded-lg text-sm flex max-w-[230px] hover:bg-gray-800"
|
||||
className="p-2 ml-1 border border-gray-800 rounded-lg text-sm flex max-w-[280px] hover:bg-gray-800"
|
||||
href={quoteInfo.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{getSourceIcon(quoteInfo.source_type, "20")}
|
||||
<p className="truncate break-all ml-0.5">
|
||||
<p className="truncate break-all ml-2">
|
||||
{quoteInfo.semantic_identifier || quoteInfo.document_id}
|
||||
</p>
|
||||
</a>
|
||||
@ -132,7 +132,7 @@ export const SearchResultsDisplay: React.FC<SearchResultsDisplayProps> = ({
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{getSourceIcon(doc.source_type, "20")}
|
||||
<p className="truncate break-all ml-0.5">
|
||||
<p className="truncate break-all ml-2">
|
||||
{doc.semantic_identifier || doc.document_id}
|
||||
</p>
|
||||
</a>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { ValidSources } from "@/lib/types";
|
||||
import {
|
||||
ConfluenceIcon,
|
||||
GithubIcon,
|
||||
GlobeIcon,
|
||||
GoogleDriveIcon,
|
||||
@ -38,6 +39,12 @@ export const getSourceMetadata = (sourceType: ValidSources): SourceMetadata => {
|
||||
displayName: "Github PRs",
|
||||
adminPageLink: "/admin/connectors/github",
|
||||
};
|
||||
case "confluence":
|
||||
return {
|
||||
icon: ConfluenceIcon,
|
||||
displayName: "Confluence",
|
||||
adminPageLink: "/admin/connectors/confluence",
|
||||
};
|
||||
default:
|
||||
throw new Error("Invalid source type");
|
||||
}
|
||||
|
@ -7,5 +7,10 @@ export interface User {
|
||||
role: "basic" | "admin";
|
||||
}
|
||||
|
||||
export type ValidSources = "web" | "github" | "slack" | "google_drive";
|
||||
export type ValidSources =
|
||||
| "web"
|
||||
| "github"
|
||||
| "slack"
|
||||
| "google_drive"
|
||||
| "confluence";
|
||||
export type ValidInputTypes = "load_state" | "poll" | "event";
|
||||
|
Loading…
x
Reference in New Issue
Block a user