mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-03-26 17:51:54 +01:00
Remove personal connectors page(#779)
This commit is contained in:
parent
187b94a7d8
commit
c83a450ec4
@ -1,9 +1,6 @@
|
||||
import { SearchSection } from "@/components/search/SearchSection";
|
||||
import { Header } from "@/components/Header";
|
||||
import {
|
||||
getAuthDisabledSS,
|
||||
getCurrentUserSS,
|
||||
} from "@/lib/userSS";
|
||||
import { getAuthDisabledSS, getCurrentUserSS } from "@/lib/userSS";
|
||||
import { redirect } from "next/navigation";
|
||||
import { HealthCheckBanner } from "@/components/health/healthcheck";
|
||||
import { ApiKeyModal } from "@/components/openai/ApiKeyModal";
|
||||
|
@ -1,147 +0,0 @@
|
||||
import { Button } from "@/components/Button";
|
||||
import { GoogleDriveIcon } from "@/components/icons/icons";
|
||||
import { deleteCredential, linkCredential } from "@/lib/credential";
|
||||
import { setupGoogleDriveOAuth } from "@/lib/googleDrive";
|
||||
import { GoogleDriveCredentialJson, Credential } from "@/lib/types";
|
||||
import { GOOGLE_DRIVE_AUTH_IS_ADMIN_COOKIE_NAME } from "@/lib/constants";
|
||||
import Cookies from "js-cookie";
|
||||
import { CardProps } from "./interface";
|
||||
import { CheckCircle, MinusCircle } from "@phosphor-icons/react";
|
||||
|
||||
export const GoogleDriveCard = ({
|
||||
connector,
|
||||
userCredentials,
|
||||
setPopup,
|
||||
router,
|
||||
mutate,
|
||||
}: CardProps) => {
|
||||
if (!connector) return null;
|
||||
|
||||
const existingCredential: Credential<GoogleDriveCredentialJson> | undefined =
|
||||
userCredentials?.find(
|
||||
(credential) =>
|
||||
// user_id is set => credential is not a public credential
|
||||
credential.credential_json?.google_drive_tokens !== undefined &&
|
||||
credential.user_id !== null
|
||||
);
|
||||
|
||||
const credentialIsLinked =
|
||||
existingCredential !== undefined &&
|
||||
connector.credential_ids.includes(existingCredential.id);
|
||||
|
||||
return (
|
||||
<div className="border rounded border-gray-700 p-3 w-80">
|
||||
<div className="flex items-center">
|
||||
<GoogleDriveIcon size={20} />{" "}
|
||||
<b className="ml-2 text-xl">Google Drive</b>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{existingCredential && credentialIsLinked ? (
|
||||
<div className="text-green-600 flex text-sm mt-1">
|
||||
<CheckCircle className="my-auto mr-1" size="16" />
|
||||
Enabled
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-gray-400 flex text-sm mt-1">
|
||||
<MinusCircle className="my-auto mr-1" size="16" />
|
||||
Not Setup
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="text-sm mt-2">
|
||||
{existingCredential ? (
|
||||
credentialIsLinked ? (
|
||||
<>
|
||||
<p>
|
||||
Danswer has access to your Google Drive documents! Don't
|
||||
worry, only <b>you</b> will be able to see your private
|
||||
documents. You can revoke this access by clicking the button
|
||||
below.
|
||||
</p>
|
||||
<div className="mt-2 flex">
|
||||
<Button
|
||||
onClick={async () => {
|
||||
await deleteCredential(existingCredential.id);
|
||||
setPopup({
|
||||
message: "Successfully revoked access to Google Drive!",
|
||||
type: "success",
|
||||
});
|
||||
mutate("/api/manage/connector");
|
||||
mutate("/api/manage/credential");
|
||||
}}
|
||||
fullWidth
|
||||
>
|
||||
Revoke Access
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<p>
|
||||
We've received your credentials from Google! Click the
|
||||
button below to activate the connector - we will pull the latest
|
||||
state of your documents every <b>10</b> minutes.
|
||||
</p>
|
||||
<div className="mt-2 flex">
|
||||
<Button
|
||||
onClick={async () => {
|
||||
await linkCredential(connector.id, existingCredential.id);
|
||||
setPopup({
|
||||
message: "Activated!",
|
||||
type: "success",
|
||||
});
|
||||
mutate("/api/manage/connector");
|
||||
}}
|
||||
fullWidth
|
||||
>
|
||||
Activate
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
) : (
|
||||
<>
|
||||
<p>
|
||||
If you want to make all your Google Drive documents searchable
|
||||
through Danswer, click the button below! Don't worry, only{" "}
|
||||
<b>you</b> will be able to see your private documents. Currently,
|
||||
you'll only be able to search through documents shared with
|
||||
the whole company.
|
||||
</p>
|
||||
<div className="mt-2 flex">
|
||||
<Button
|
||||
onClick={async () => {
|
||||
const [authUrl, errorMsg] = await setupGoogleDriveOAuth({
|
||||
isAdmin: false,
|
||||
});
|
||||
if (authUrl) {
|
||||
// cookie used by callback to determine where to finally redirect to
|
||||
Cookies.set(
|
||||
GOOGLE_DRIVE_AUTH_IS_ADMIN_COOKIE_NAME,
|
||||
"false",
|
||||
{
|
||||
path: "/",
|
||||
}
|
||||
);
|
||||
router.push(authUrl);
|
||||
return;
|
||||
}
|
||||
|
||||
setPopup({
|
||||
message: errorMsg,
|
||||
type: "error",
|
||||
});
|
||||
}}
|
||||
fullWidth
|
||||
>
|
||||
Authenticate with Google Drive
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,12 +0,0 @@
|
||||
import { PopupSpec } from "@/components/admin/connectors/Popup";
|
||||
import { Connector, Credential } from "@/lib/types";
|
||||
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
|
||||
import { ScopedMutator } from "swr/_internal";
|
||||
|
||||
export interface CardProps {
|
||||
connector: Connector<{}> | null | undefined;
|
||||
userCredentials: Credential<any>[] | null | undefined;
|
||||
setPopup: (popup: PopupSpec | null) => void;
|
||||
router: AppRouterInstance;
|
||||
mutate: ScopedMutator;
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { PlugIcon } from "@/components/icons/icons";
|
||||
import useSWR, { useSWRConfig } from "swr";
|
||||
import { fetcher } from "@/lib/fetcher";
|
||||
import { LoadingAnimation } from "@/components/Loading";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Popup, PopupSpec } from "@/components/admin/connectors/Popup";
|
||||
import { useState } from "react";
|
||||
import { HealthCheckBanner } from "@/components/health/healthcheck";
|
||||
import { Connector, Credential, ValidSources } from "@/lib/types";
|
||||
import { GoogleDriveCard } from "./GoogleDriveCard";
|
||||
import { CardProps } from "./interface";
|
||||
|
||||
const connectorSourceToConnectorCard = (
|
||||
source: ValidSources
|
||||
): React.FC<CardProps> | null => {
|
||||
switch (source) {
|
||||
case "google_drive":
|
||||
return GoogleDriveCard;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const Main = () => {
|
||||
const router = useRouter();
|
||||
const { mutate } = useSWRConfig();
|
||||
|
||||
const {
|
||||
data: appCredentialData,
|
||||
isLoading: isAppCredentialLoading,
|
||||
error: isAppCredentialError,
|
||||
} = useSWR<{ client_id: string }>(
|
||||
"/api/manage/admin/connector/google-drive/app-credential",
|
||||
fetcher
|
||||
);
|
||||
const {
|
||||
data: connectorsData,
|
||||
isLoading: isConnectorDataLoading,
|
||||
error: isConnectorDataError,
|
||||
} = useSWR<Connector<any>[]>("/api/manage/connector", fetcher);
|
||||
const {
|
||||
data: credentialsData,
|
||||
isLoading: isCredentialsLoading,
|
||||
error: isCredentialsError,
|
||||
} = useSWR<Credential<any>[]>("/api/manage/credential", fetcher);
|
||||
|
||||
const [popup, setPopup] = useState<{
|
||||
message: string;
|
||||
type: "success" | "error";
|
||||
} | null>(null);
|
||||
const setPopupWithExpiration = (popupSpec: PopupSpec | null) => {
|
||||
setPopup(popupSpec);
|
||||
setTimeout(() => {
|
||||
setPopup(null);
|
||||
}, 4000);
|
||||
};
|
||||
|
||||
if (
|
||||
isCredentialsLoading ||
|
||||
isAppCredentialLoading ||
|
||||
isConnectorDataLoading
|
||||
) {
|
||||
return (
|
||||
<div className="mx-auto">
|
||||
<LoadingAnimation text="" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (isCredentialsError || !credentialsData) {
|
||||
return (
|
||||
<div className="mx-auto">
|
||||
<div className="text-red-500">Failed to load credentials.</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (isConnectorDataError || !connectorsData) {
|
||||
return (
|
||||
<div className="mx-auto">
|
||||
<div className="text-red-500">Failed to load connectors.</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (isAppCredentialError || !appCredentialData) {
|
||||
return (
|
||||
<div className="mx-auto">
|
||||
<div className="text-red-500">
|
||||
Error loading Google Drive app credentials. Contact an administrator.
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{popup && <Popup message={popup.message} type={popup.type} />}
|
||||
|
||||
{connectorsData.map((connector) => {
|
||||
const connectorCard = connectorSourceToConnectorCard(connector.source);
|
||||
if (connectorCard) {
|
||||
return (
|
||||
<div key={connector.id}>
|
||||
{connectorCard({
|
||||
connector,
|
||||
userCredentials: credentialsData,
|
||||
setPopup: setPopupWithExpiration,
|
||||
router,
|
||||
mutate,
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div className="mx-auto container">
|
||||
<div className="mb-4">
|
||||
<HealthCheckBanner />
|
||||
</div>
|
||||
<div className="border-solid border-gray-600 border-b mb-4 pb-2 flex">
|
||||
<PlugIcon size={32} />
|
||||
<h1 className="text-3xl font-bold pl-2">Personal Connectors</h1>
|
||||
</div>
|
||||
|
||||
<Main />
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
import { Header } from "@/components/Header";
|
||||
import { getAuthDisabledSS, getCurrentUserSS } from "@/lib/userSS";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
export default async function AdminLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const [authDisabled, user] = await Promise.all([
|
||||
getAuthDisabledSS(),
|
||||
getCurrentUserSS(),
|
||||
]);
|
||||
|
||||
if (!authDisabled) {
|
||||
if (!user) {
|
||||
return redirect("/auth/login");
|
||||
}
|
||||
if (user.role !== "admin") {
|
||||
return redirect("/");
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Header user={user} />
|
||||
<div className="bg-gray-900 pt-8 flex">
|
||||
<div className="px-12 min-h-screen bg-gray-900 text-gray-100 w-full">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -75,11 +75,6 @@ export const Header: React.FC<HeaderProps> = ({ user }) => {
|
||||
"w-48 overflow-hidden shadow-xl z-10 text-sm text-gray-300"
|
||||
}
|
||||
>
|
||||
<Link href="/user/connectors">
|
||||
<div className="flex py-2 px-3 cursor-pointer hover:bg-gray-500 border-b border-gray-500">
|
||||
Personal Connectors
|
||||
</div>
|
||||
</Link>
|
||||
{/* Show connector option if (1) auth is disabled or (2) user is an admin */}
|
||||
{(!user || user.role === "admin") && (
|
||||
<Link href="/admin/indexing/status">
|
||||
|
Loading…
x
Reference in New Issue
Block a user