From 16c8969028a13d88ee55f489a954d7abe7d7b605 Mon Sep 17 00:00:00 2001 From: Weves Date: Tue, 5 Dec 2023 18:17:53 -0800 Subject: [PATCH] Chat UI --- .../danswer/server/features/prompt/models.py | 6 +- .../server/query_and_chat/chat_backend.py | 1 + .../danswer/server/query_and_chat/models.py | 1 + web/next.config.js | 35 +- web/public/Github.png | Bin 4837 -> 6393 bytes web/public/GithubDarkMode.png | Bin 0 -> 4837 bytes web/src/app/admin/add-connector/page.tsx | 22 +- .../admin/bot/SlackBotConfigCreationForm.tsx | 38 +- web/src/app/admin/bot/SlackBotTokensForm.tsx | 14 +- web/src/app/admin/bot/[id]/page.tsx | 2 +- web/src/app/admin/bot/new/page.tsx | 2 +- web/src/app/admin/bot/page.tsx | 10 +- .../connector/[ccPairId]/ConfigDisplay.tsx | 2 +- .../connector/[ccPairId]/DeletionButton.tsx | 1 - .../[ccPairId]/ModifyStatusButtonCluster.tsx | 4 +- .../connector/[ccPairId]/ReIndexButton.tsx | 2 +- .../app/admin/connector/[ccPairId]/page.tsx | 8 +- .../app/admin/connectors/bookstack/page.tsx | 49 +- .../app/admin/connectors/confluence/page.tsx | 35 +- .../app/admin/connectors/document360/page.tsx | 52 +- web/src/app/admin/connectors/file/page.tsx | 312 +++++----- web/src/app/admin/connectors/github/page.tsx | 44 +- web/src/app/admin/connectors/gong/page.tsx | 42 +- .../google-drive/ConnectorEditPopup.tsx | 39 +- .../connectors/google-drive/Credential.tsx | 7 +- .../GoogleDriveConnectorsTable.tsx | 103 ++- .../admin/connectors/google-drive/page.tsx | 36 +- .../admin/connectors/google-sites/page.tsx | 270 ++++---- web/src/app/admin/connectors/guru/page.tsx | 51 +- web/src/app/admin/connectors/hubspot/page.tsx | 49 +- web/src/app/admin/connectors/jira/page.tsx | 46 +- web/src/app/admin/connectors/linear/page.tsx | 46 +- web/src/app/admin/connectors/notion/page.tsx | 38 +- .../admin/connectors/productboard/page.tsx | 55 +- .../page.tsx | 61 +- web/src/app/admin/connectors/slab/page.tsx | 52 +- web/src/app/admin/connectors/slack/page.tsx | 48 +- web/src/app/admin/connectors/web/page.tsx | 22 +- web/src/app/admin/connectors/zendesk/page.tsx | 41 +- web/src/app/admin/connectors/zulip/page.tsx | 49 +- web/src/app/admin/documents/ScoreEditor.tsx | 17 +- .../app/admin/documents/explorer/Explorer.tsx | 20 +- .../feedback/DocumentFeedbackTable.tsx | 139 +++-- web/src/app/admin/documents/feedback/page.tsx | 7 +- .../sets/DocumentSetCreationForm.tsx | 25 +- web/src/app/admin/documents/sets/page.tsx | 256 ++++---- .../status/CCPairIndexingStatusTable.tsx | 6 +- web/src/app/admin/indexing/status/page.tsx | 4 +- web/src/app/admin/keys/openai/page.tsx | 17 +- web/src/app/admin/personas/PersonaEditor.tsx | 87 +-- web/src/app/admin/personas/PersonaTable.tsx | 23 +- .../[personaId]/DeletePersonaButton.tsx | 1 - .../app/admin/personas/[personaId]/page.tsx | 2 +- web/src/app/admin/personas/interfaces.ts | 20 +- web/src/app/admin/personas/lib.ts | 150 ++++- web/src/app/admin/personas/new/page.tsx | 2 +- web/src/app/admin/personas/page.tsx | 8 +- web/src/app/admin/users/page.tsx | 149 ++--- web/src/app/auth/login/SignInButton.tsx | 2 +- web/src/app/auth/login/page.tsx | 2 +- web/src/app/chat/Chat.tsx | 584 ++++++++++++++++++ web/src/app/chat/ChatPage.tsx | 204 ++++++ web/src/app/chat/ChatPersonaSelector.tsx | 108 ++++ web/src/app/chat/[chatId]/page.tsx | 14 + .../documentSidebar/ChatDocumentDisplay.tsx | 217 +++++++ .../chat/documentSidebar/DocumentSelector.tsx | 23 + .../chat/documentSidebar/DocumentSidebar.tsx | 170 +++++ .../SelectedDocumentDisplay.tsx | 24 + web/src/app/chat/interfaces.ts | 54 ++ web/src/app/chat/lib.tsx | 268 ++++++++ web/src/app/chat/message/Messages.tsx | 235 +++++++ web/src/app/chat/message/SearchSummary.tsx | 92 +++ web/src/app/chat/modal/DeleteChatModal.tsx | 43 ++ web/src/app/chat/modal/FeedbackModal.tsx | 84 +++ web/src/app/chat/modal/ModalWrapper.tsx | 35 ++ web/src/app/chat/modifiers/ChatFilters.tsx | 345 +++++++++++ .../app/chat/modifiers/SearchTypeSelector.tsx | 71 +++ .../app/chat/modifiers/SelectedDocuments.tsx | 25 + web/src/app/chat/page.tsx | 12 + .../app/chat/sessionSidebar/ChatSidebar.tsx | 196 ++++++ .../chat/sessionSidebar/SessionDisplay.tsx | 119 ++++ web/src/app/chat/types.ts | 1 + web/src/app/globals.css | 20 + web/src/app/layout.tsx | 4 +- web/src/app/{ => search}/page.tsx | 4 +- web/src/components/BackButton.tsx | 2 +- web/src/components/BasicClickable.tsx | 89 +++ web/src/components/Bubble.tsx | 29 + web/src/components/CustomCheckbox.tsx | 6 +- web/src/components/DeleteButton.tsx | 28 + web/src/components/Dropdown.tsx | 114 ++-- web/src/components/EditButton.tsx | 8 +- web/src/components/Header.tsx | 92 ++- web/src/components/HoverPopup.tsx | 12 +- web/src/components/Modal.tsx | 4 +- web/src/components/PageSelector.tsx | 7 +- web/src/components/Status.tsx | 6 +- web/src/components/WelcomeModal.tsx | 8 +- web/src/components/admin/Layout.tsx | 18 +- web/src/components/admin/Title.tsx | 4 +- .../{Sidebar.tsx => AdminSidebar.tsx} | 16 +- .../admin/connectors/ConnectorForm.tsx | 25 +- .../admin/connectors/ConnectorTitle.tsx | 2 +- .../admin/connectors/CredentialForm.tsx | 13 +- web/src/components/admin/connectors/Field.tsx | 28 +- .../admin/connectors/FileUpload.tsx | 6 +- .../connectors/table/ConnectorsTable.tsx | 178 +++--- .../admin/connectors/table/DeleteColumn.tsx | 20 +- .../table/SingleUseConnectorsTable.tsx | 241 ++++---- web/src/components/icons/icons.tsx | 7 +- web/src/components/openai/ApiKeyForm.tsx | 11 +- web/src/components/openai/ApiKeyModal.tsx | 62 +- .../components/search/DateRangeSelector.tsx | 82 ++- web/src/components/search/DocumentDisplay.tsx | 14 +- .../search/DocumentUpdatedAtBadge.tsx | 3 +- web/src/components/search/PersonaSelector.tsx | 85 +-- web/src/components/search/SearchBar.tsx | 6 +- .../search/SearchResultsDisplay.tsx | 32 +- web/src/components/search/SearchSection.tsx | 37 +- .../search/filtering/FilterDropdown.tsx | 22 +- .../components/search/filtering/Filters.tsx | 80 +-- .../search/results/AnswerSection.tsx | 10 +- .../search/results/QuotesSection.tsx | 33 +- web/src/lib/documentUtils.ts | 13 + web/src/lib/search/interfaces.ts | 5 +- web/src/lib/search/qa.ts | 76 --- web/src/lib/search/streamingQa.ts | 18 +- .../lib/search/streamingQuestionValidation.ts | 15 +- web/src/lib/search/streamingUtils.ts | 30 + web/tailwind.config.js | 35 +- 130 files changed, 5328 insertions(+), 1888 deletions(-) create mode 100644 web/public/GithubDarkMode.png rename web/src/app/admin/connectors/{requesttracker => request-tracker}/page.tsx (86%) create mode 100644 web/src/app/chat/Chat.tsx create mode 100644 web/src/app/chat/ChatPage.tsx create mode 100644 web/src/app/chat/ChatPersonaSelector.tsx create mode 100644 web/src/app/chat/[chatId]/page.tsx create mode 100644 web/src/app/chat/documentSidebar/ChatDocumentDisplay.tsx create mode 100644 web/src/app/chat/documentSidebar/DocumentSelector.tsx create mode 100644 web/src/app/chat/documentSidebar/DocumentSidebar.tsx create mode 100644 web/src/app/chat/documentSidebar/SelectedDocumentDisplay.tsx create mode 100644 web/src/app/chat/interfaces.ts create mode 100644 web/src/app/chat/lib.tsx create mode 100644 web/src/app/chat/message/Messages.tsx create mode 100644 web/src/app/chat/message/SearchSummary.tsx create mode 100644 web/src/app/chat/modal/DeleteChatModal.tsx create mode 100644 web/src/app/chat/modal/FeedbackModal.tsx create mode 100644 web/src/app/chat/modal/ModalWrapper.tsx create mode 100644 web/src/app/chat/modifiers/ChatFilters.tsx create mode 100644 web/src/app/chat/modifiers/SearchTypeSelector.tsx create mode 100644 web/src/app/chat/modifiers/SelectedDocuments.tsx create mode 100644 web/src/app/chat/page.tsx create mode 100644 web/src/app/chat/sessionSidebar/ChatSidebar.tsx create mode 100644 web/src/app/chat/sessionSidebar/SessionDisplay.tsx create mode 100644 web/src/app/chat/types.ts rename web/src/app/{ => search}/page.tsx (97%) create mode 100644 web/src/components/BasicClickable.tsx create mode 100644 web/src/components/Bubble.tsx create mode 100644 web/src/components/DeleteButton.tsx rename web/src/components/admin/connectors/{Sidebar.tsx => AdminSidebar.tsx} (58%) create mode 100644 web/src/lib/documentUtils.ts delete mode 100644 web/src/lib/search/qa.ts diff --git a/backend/danswer/server/features/prompt/models.py b/backend/danswer/server/features/prompt/models.py index d3062f0ddb..0ae70c58d0 100644 --- a/backend/danswer/server/features/prompt/models.py +++ b/backend/danswer/server/features/prompt/models.py @@ -9,9 +9,9 @@ class CreatePromptRequest(BaseModel): shared: bool system_prompt: str task_prompt: str - include_citations: bool - datetime_aware: bool - persona_ids: list[int] + include_citations: bool = False + datetime_aware: bool = False + persona_ids: list[int] | None = None class PromptSnapshot(BaseModel): diff --git a/backend/danswer/server/query_and_chat/chat_backend.py b/backend/danswer/server/query_and_chat/chat_backend.py index 78607276bf..a2b2c4996d 100644 --- a/backend/danswer/server/query_and_chat/chat_backend.py +++ b/backend/danswer/server/query_and_chat/chat_backend.py @@ -59,6 +59,7 @@ def get_user_chat_sessions( ChatSessionDetails( id=chat.id, name=chat.description, + persona_id=chat.persona_id, time_created=chat.time_created.isoformat(), ) for chat in chat_sessions diff --git a/backend/danswer/server/query_and_chat/models.py b/backend/danswer/server/query_and_chat/models.py index ab1c1dc802..745834c5ba 100644 --- a/backend/danswer/server/query_and_chat/models.py +++ b/backend/danswer/server/query_and_chat/models.py @@ -96,6 +96,7 @@ class RenameChatSessionResponse(BaseModel): class ChatSessionDetails(BaseModel): id: int name: str + persona_id: int time_created: str diff --git a/web/next.config.js b/web/next.config.js index 1730d1ef5d..6f7de34ae4 100644 --- a/web/next.config.js +++ b/web/next.config.js @@ -24,20 +24,35 @@ const nextConfig = { // In production, something else (nginx in the one box setup) should take // 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 []; - - return [ + const defaultRedirects = [ { - source: "/api/stream-direct-qa:params*", - destination: "http://127.0.0.1:8080/stream-direct-qa:params*", // Proxy to Backend - permanent: true, - }, - { - source: "/api/stream-query-validation:params*", - destination: "http://127.0.0.1:8080/stream-query-validation:params*", // Proxy to Backend + source: "/", + destination: "/search", permanent: true, }, ]; + + if (process.env.NODE_ENV === "production") return defaultRedirects; + + return defaultRedirects.concat([ + { + source: "/api/chat/send-message:params*", + destination: "http://127.0.0.1:8080/chat/send-message:params*", // Proxy to Backend + permanent: true, + }, + { + source: "/api/query/stream-answer-with-quote:params*", + destination: + "http://127.0.0.1:8080/query/stream-answer-with-quote:params*", // Proxy to Backend + permanent: true, + }, + { + source: "/api/query/stream-query-validation:params*", + destination: + "http://127.0.0.1:8080/query/stream-query-validation:params*", // Proxy to Backend + permanent: true, + }, + ]); }, publicRuntimeConfig: { version, diff --git a/web/public/Github.png b/web/public/Github.png index 50b81752278d084ba9d449fff25f4051df162b0f..6cb3b705d018006a2bd4200ea94c9d5fb98b6f76 100644 GIT binary patch literal 6393 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 Hu0mjfZ$b4` delta 4831 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 FV1mZogX#bP diff --git a/web/public/GithubDarkMode.png b/web/public/GithubDarkMode.png new file mode 100644 index 0000000000000000000000000000000000000000..50b81752278d084ba9d449fff25f4051df162b0f GIT binary patch literal 4837 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 literal 0 HcmV?d00001 diff --git a/web/src/app/admin/add-connector/page.tsx b/web/src/app/admin/add-connector/page.tsx index 1302fe6716..d6ad8324ef 100644 --- a/web/src/app/admin/add-connector/page.tsx +++ b/web/src/app/admin/add-connector/page.tsx @@ -13,20 +13,20 @@ function SourceTile({ sourceMetadata }: { sourceMetadata: SourceMetadata }) { flex-col items-center justify-center - bg-dark-tremor-background-muted p-4 rounded-lg w-40 cursor-pointer + bg-hover-light shadow-md - hover:bg-gray-800 + hover:bg-hover `} href={sourceMetadata.adminUrl} > - + {sourceMetadata.displayName} - + ); } @@ -42,26 +42,26 @@ export default function Page() { ); return ( -
+
} title="Add Connector" /> -
+ Connect Danswer to your organization's knowledge sources. We'll automatically sync your data into Danswer, so you can find exactly what you're looking for in one place. -
+
Import Knowledge
-
+ Connect to pieces of knowledge that live outside your apps. Upload files, scrape websites, or connect to your organization's Google Site. -
+
{importedKnowledgeSources.map((source) => { return ( @@ -73,11 +73,11 @@ export default function Page() {
Setup Auto-Syncing from Apps
-
+ Setup auto-syncing from your organization's most used apps and services. Unless otherwise specified during the connector setup, we will pull in the latest updates from the source every 10 minutes. -
+
{appConnectionSources.map((source) => { return ( diff --git a/web/src/app/admin/bot/SlackBotConfigCreationForm.tsx b/web/src/app/admin/bot/SlackBotConfigCreationForm.tsx index fa4f383bff..099452445d 100644 --- a/web/src/app/admin/bot/SlackBotConfigCreationForm.tsx +++ b/web/src/app/admin/bot/SlackBotConfigCreationForm.tsx @@ -17,6 +17,7 @@ import { updateSlackBotConfig, } from "./lib"; import { + Button, Card, Divider, Tab, @@ -52,7 +53,7 @@ export const SlackBotCreationForm = ({ ); return ( -
+
{popup} or Document Sets to control how DanswerBot answers. -
+
  • You should use a Persona if you also want to customize @@ -204,7 +205,7 @@ export const SlackBotCreationForm = ({ which documents DanswerBot uses as references.
-
+ NOTE: whichever tab you are when you submit the form will be the one that is used. For example, if you are on the @@ -245,17 +246,17 @@ export const SlackBotCreationForm = ({ key={documentSet.id} className={ ` - px-3 - py-1 - rounded-lg - border - border-gray-700 - w-fit - flex - cursor-pointer ` + + px-3 + py-1 + rounded-lg + border + border-border + w-fit + flex + cursor-pointer ` + (isSelected - ? " bg-gray-600" - : " bg-gray-900 hover:bg-gray-700") + ? " bg-hover" + : " bg-background hover:bg-hover-light") } onClick={() => { if (isSelected) { @@ -289,7 +290,6 @@ export const SlackBotCreationForm = ({ value: persona.id, }; })} - includeDefault={true} /> @@ -298,17 +298,13 @@ export const SlackBotCreationForm = ({
- +
diff --git a/web/src/app/admin/bot/SlackBotTokensForm.tsx b/web/src/app/admin/bot/SlackBotTokensForm.tsx index 118f2de8c8..37bba48775 100644 --- a/web/src/app/admin/bot/SlackBotTokensForm.tsx +++ b/web/src/app/admin/bot/SlackBotTokensForm.tsx @@ -11,7 +11,7 @@ import { setSlackBotTokens, updateSlackBotConfig, } from "./lib"; -import { Card } from "@tremor/react"; +import { Button, Card } from "@tremor/react"; interface SlackBotTokensFormProps { onClose: () => void; @@ -64,17 +64,9 @@ export const SlackBotTokensForm = ({ type="password" />
- +
)} diff --git a/web/src/app/admin/bot/[id]/page.tsx b/web/src/app/admin/bot/[id]/page.tsx index fd6c3aab84..1fc544e5da 100644 --- a/web/src/app/admin/bot/[id]/page.tsx +++ b/web/src/app/admin/bot/[id]/page.tsx @@ -62,7 +62,7 @@ async function Page({ params }: { params: { id: string } }) { const personas = (await personasResponse.json()) as Persona[]; return ( -
+
diff --git a/web/src/app/admin/bot/new/page.tsx b/web/src/app/admin/bot/new/page.tsx index dd6781a19c..93c9c7f469 100644 --- a/web/src/app/admin/bot/new/page.tsx +++ b/web/src/app/admin/bot/new/page.tsx @@ -33,7 +33,7 @@ async function Page() { const personas = (await personasResponse.json()) as Persona[]; return ( -
+
} diff --git a/web/src/app/admin/bot/page.tsx b/web/src/app/admin/bot/page.tsx index fc27e0187f..257153735a 100644 --- a/web/src/app/admin/bot/page.tsx +++ b/web/src/app/admin/bot/page.tsx @@ -173,7 +173,7 @@ const Main = () => { } return ( -
+
{popup} @@ -181,7 +181,7 @@ const Main = () => { to ask questions to Danswer directly from Slack. Additionally, you can: -
+
  • Setup DanswerBot to automatically answer questions in certain @@ -196,7 +196,7 @@ const Main = () => { UI.
-
+ Follow the{" "} @@ -226,7 +226,7 @@ const Main = () => { setSlackBotTokensModalIsOpen(!slackBotTokensModalIsOpen); console.log(slackBotTokensModalIsOpen); }} - variant="secondary" + color="blue" size="xs" className="mt-2" icon={slackBotTokensModalIsOpen ? FiChevronUp : FiChevronDown} @@ -259,7 +259,7 @@ const Main = () => {
- diff --git a/web/src/app/admin/connector/[ccPairId]/ConfigDisplay.tsx b/web/src/app/admin/connector/[ccPairId]/ConfigDisplay.tsx index 5dfe6b25a9..42da01e184 100644 --- a/web/src/app/admin/connector/[ccPairId]/ConfigDisplay.tsx +++ b/web/src/app/admin/connector/[ccPairId]/ConfigDisplay.tsx @@ -1,6 +1,6 @@ import { getNameFromPath } from "@/lib/fileUtils"; import { ValidSources } from "@/lib/types"; -import { List, ListItem, Card, Title, Divider } from "@tremor/react"; +import { List, ListItem, Card, Title } from "@tremor/react"; function convertObjectToString(obj: any): string | any { // Check if obj is an object and not an array or null diff --git a/web/src/app/admin/connector/[ccPairId]/DeletionButton.tsx b/web/src/app/admin/connector/[ccPairId]/DeletionButton.tsx index cd6edcf474..c8ffd6d953 100644 --- a/web/src/app/admin/connector/[ccPairId]/DeletionButton.tsx +++ b/web/src/app/admin/connector/[ccPairId]/DeletionButton.tsx @@ -30,7 +30,6 @@ export function DeletionButton({ ccPair }: { ccPair: CCPairFullInfo }) {
{popup} ) : (
+ )} -
+

Add a New Space

nameBuilder={(values) => @@ -284,14 +288,14 @@ const Main = () => { refreshFreq={10 * 60} // 10 minutes credentialId={confluenceCredential.id} /> -
+ ) : ( -

+ Please provide your access token in Step 1 first! Once done with that, you can then specify which Confluence spaces you want to make searchable. -

+
)} ); @@ -303,10 +307,9 @@ export default function Page() {
-
- -

Confluence

-
+ + } title="Confluence" /> +
); diff --git a/web/src/app/admin/connectors/document360/page.tsx b/web/src/app/admin/connectors/document360/page.tsx index 357151eb97..8d7c03190e 100644 --- a/web/src/app/admin/connectors/document360/page.tsx +++ b/web/src/app/admin/connectors/document360/page.tsx @@ -21,6 +21,8 @@ import { import { ConnectorsTable } from "@/components/admin/connectors/table/ConnectorsTable"; import { ConnectorForm } from "@/components/admin/connectors/ConnectorForm"; import { usePublicCredentials } from "@/lib/hooks"; +import { Title, Text, Card, Divider } from "@tremor/react"; +import { AdminPageTitle } from "@/components/admin/Title"; const MainSection = () => { const { mutate } = useSWRConfig(); @@ -71,18 +73,18 @@ const MainSection = () => { return ( <> -

+ Step 1: Provide Credentials - </h2> + {document360Credential ? ( <>
-

Existing Document360 API Token:

-

+ Existing Document360 API Token: + {document360Credential.credential_json.document360_api_token} -

+
); diff --git a/web/src/app/admin/connectors/file/page.tsx b/web/src/app/admin/connectors/file/page.tsx index 8f8206f7b1..b963b2d94d 100644 --- a/web/src/app/admin/connectors/file/page.tsx +++ b/web/src/app/admin/connectors/file/page.tsx @@ -18,6 +18,8 @@ import { Form, Formik } from "formik"; import { TextFormField } from "@/components/admin/connectors/Field"; import { FileUpload } from "@/components/admin/connectors/FileUpload"; import { getNameFromPath } from "@/lib/fileUtils"; +import { Button, Card, Divider, Text } from "@tremor/react"; +import { AdminPageTitle } from "@/components/admin/Title"; const Main = () => { const [selectedFiles, setSelectedFiles] = useState([]); @@ -48,13 +50,13 @@ const Main = () => {
{popup} {filesAreUploading && } -

+ Specify files below, click the Upload button, and the contents of these files will be searchable via Danswer! Currently only .txt,{" "} .pdf and .zip files (containing only .txt files) are supported. -

-
+ + NOTE: if the original document is accessible via a link, you can add a line at the very beginning of the file that looks like:
@@ -67,163 +69,172 @@ const Main = () => { search result. More details on this can be found in the{" "} documentation. -
+
-
- { - const uploadCreateAndTriggerConnector = async () => { - const formData = new FormData(); +
+ + { + const uploadCreateAndTriggerConnector = async () => { + const formData = new FormData(); - selectedFiles.forEach((file) => { - formData.append("files", file); - }); - - const response = await fetch( - "/api/manage/admin/connector/file/upload", - { method: "POST", body: formData } - ); - const responseJson = await response.json(); - if (!response.ok) { - setPopup({ - message: `Unable to upload files - ${responseJson.detail}`, - type: "error", + selectedFiles.forEach((file) => { + formData.append("files", file); }); - return; - } - const filePaths = responseJson.file_paths as string[]; - const [connectorErrorMsg, connector] = - await createConnector({ - name: "FileConnector-" + Date.now(), - source: "file", - input_type: "load_state", - connector_specific_config: { - file_locations: filePaths, - }, - refresh_freq: null, - disabled: false, - }); - if (connectorErrorMsg || !connector) { - setPopup({ - message: `Unable to create connector - ${connectorErrorMsg}`, - type: "error", - }); - return; - } - - // Since there is no "real" credential associated with a file connector - // we create a dummy one here so that we can associate the CC Pair with a - // user. This is needed since the user for a CC Pair is found via the credential - // associated with it. - const createCredentialResponse = await createCredential({ - credential_json: {}, - admin_public: true, - }); - if (!createCredentialResponse.ok) { - const errorMsg = await createCredentialResponse.text(); - setPopup({ - message: `Error creating credential for CC Pair - ${errorMsg}`, - type: "error", - }); - formikHelpers.setSubmitting(false); - return; - } - const credentialId = (await createCredentialResponse.json()).id; - - const credentialResponse = await linkCredential( - connector.id, - credentialId, - values.name - ); - if (!credentialResponse.ok) { - const credentialResponseJson = - await credentialResponse.json(); - setPopup({ - message: `Unable to link connector to credential - ${credentialResponseJson.detail}`, - type: "error", - }); - return; - } - - const runConnectorErrorMsg = await runConnector(connector.id, [ - 0, - ]); - if (runConnectorErrorMsg) { - setPopup({ - message: `Unable to run connector - ${runConnectorErrorMsg}`, - type: "error", - }); - return; - } - - mutate("/api/manage/admin/connector/indexing-status"); - setSelectedFiles([]); - formikHelpers.resetForm(); - setPopup({ - type: "success", - message: "Successfully uploaded files!", - }); - }; - - setFilesAreUploading(true); - try { - await uploadCreateAndTriggerConnector(); - } catch (e) { - console.log("Failed to index filels: ", e); - } - setFilesAreUploading(false); - }} - > - {({ values, isSubmitting }) => ( -
-

Upload Files

- - -

Files:

- - - - )} -
+ + // Since there is no "real" credential associated with a file connector + // we create a dummy one here so that we can associate the CC Pair with a + // user. This is needed since the user for a CC Pair is found via the credential + // associated with it. + const createCredentialResponse = await createCredential({ + credential_json: {}, + admin_public: true, + }); + if (!createCredentialResponse.ok) { + const errorMsg = await createCredentialResponse.text(); + setPopup({ + message: `Error creating credential for CC Pair - ${errorMsg}`, + type: "error", + }); + formikHelpers.setSubmitting(false); + return; + } + const credentialId = (await createCredentialResponse.json()) + .id; + + const credentialResponse = await linkCredential( + connector.id, + credentialId, + values.name + ); + if (!credentialResponse.ok) { + const credentialResponseJson = + await credentialResponse.json(); + setPopup({ + message: `Unable to link connector to credential - ${credentialResponseJson.detail}`, + type: "error", + }); + return; + } + + const runConnectorErrorMsg = await runConnector( + connector.id, + [0] + ); + if (runConnectorErrorMsg) { + setPopup({ + message: `Unable to run connector - ${runConnectorErrorMsg}`, + type: "error", + }); + return; + } + + mutate("/api/manage/admin/connector/indexing-status"); + setSelectedFiles([]); + formikHelpers.resetForm(); + setPopup({ + type: "success", + message: "Successfully uploaded files!", + }); + }; + + setFilesAreUploading(true); + try { + await uploadCreateAndTriggerConnector(); + } catch (e) { + console.log("Failed to index filels: ", e); + } + setFilesAreUploading(false); + }} + > + {({ values, isSubmitting }) => ( +
+

+ Upload Files +

+ + +

Files:

+ +
+ +
+ + )} + +
{fileIndexingStatuses.length > 0 && ( -
+
+

Indexed Files

connectorIndexingStatuses={fileIndexingStatuses} @@ -253,10 +264,9 @@ export default function File() {
-
- -

File

-
+ + } title="File" /> +
); diff --git a/web/src/app/admin/connectors/github/page.tsx b/web/src/app/admin/connectors/github/page.tsx index 1e3bd941c9..c5346c73a6 100644 --- a/web/src/app/admin/connectors/github/page.tsx +++ b/web/src/app/admin/connectors/github/page.tsx @@ -18,6 +18,8 @@ import { CredentialForm } from "@/components/admin/connectors/CredentialForm"; import { adminDeleteCredential, linkCredential } from "@/lib/credential"; import { ConnectorsTable } from "@/components/admin/connectors/table/ConnectorsTable"; import { usePublicCredentials } from "@/lib/hooks"; +import { Card, Divider, Text, Title } from "@tremor/react"; +import { AdminPageTitle } from "@/components/admin/Title"; const Main = () => { const { mutate } = useSWRConfig(); @@ -66,9 +68,9 @@ const Main = () => { return ( <> -

+ Step 1: Provide your access token - </h2> + {githubCredential ? ( <> {" "} @@ -78,7 +80,7 @@ const Main = () => { {githubCredential.credential_json.github_access_token}

{" "}

); diff --git a/web/src/app/admin/connectors/gong/page.tsx b/web/src/app/admin/connectors/gong/page.tsx index cb5f0547cd..d00beb0e73 100644 --- a/web/src/app/admin/connectors/gong/page.tsx +++ b/web/src/app/admin/connectors/gong/page.tsx @@ -22,6 +22,8 @@ import { ConnectorForm } from "@/components/admin/connectors/ConnectorForm"; import { ConnectorsTable } from "@/components/admin/connectors/table/ConnectorsTable"; import { usePopup } from "@/components/admin/connectors/Popup"; import { usePublicCredentials } from "@/lib/hooks"; +import { Card, Divider, Text, Title } from "@tremor/react"; +import { AdminPageTitle } from "@/components/admin/Title"; const Main = () => { const { popup, setPopup } = usePopup(); @@ -75,21 +77,21 @@ const Main = () => { return ( <> {popup} -

+ This connector allows you to sync all your Gong Transcripts into Danswer. More details on how to setup the Gong connector can be found in{" "} this guide. -

+ -

+ Step 1: Provide your API Access info - </h2> + {gongCredential ? ( <> @@ -99,7 +101,7 @@ const Main = () => { {gongCredential.credential_json?.gong_access_key_secret}

); diff --git a/web/src/app/admin/connectors/google-drive/ConnectorEditPopup.tsx b/web/src/app/admin/connectors/google-drive/ConnectorEditPopup.tsx index b4a84b726f..ee8e14a677 100644 --- a/web/src/app/admin/connectors/google-drive/ConnectorEditPopup.tsx +++ b/web/src/app/admin/connectors/google-drive/ConnectorEditPopup.tsx @@ -7,6 +7,8 @@ import { XIcon } from "@/components/icons/icons"; import { Connector, GoogleDriveConfig } from "@/lib/types"; import * as Yup from "yup"; import { googleDriveConnectorNameBuilder } from "./utils"; +import { Modal } from "@/components/Modal"; +import { Divider, Text } from "@tremor/react"; interface Props { existingConnector: Connector; @@ -15,25 +17,28 @@ interface Props { export const ConnectorEditPopup = ({ existingConnector, onSubmit }: Props) => { return ( -
-
event.stopPropagation()} - > -
-

- Update Google Drive Connector -

-
+ +
+

+ Update Google Drive Connector +
-

+

+ + + Modify the selected Google Drive connector by adjusting the values + below! + + + + nameBuilder={googleDriveConnectorNameBuilder} existingConnector={existingConnector} @@ -67,6 +72,6 @@ export const ConnectorEditPopup = ({ existingConnector, onSubmit }: Props) => { onSubmit={onSubmit} />
-
+ ); }; diff --git a/web/src/app/admin/connectors/google-drive/Credential.tsx b/web/src/app/admin/connectors/google-drive/Credential.tsx index d4c5ec005b..206601adf5 100644 --- a/web/src/app/admin/connectors/google-drive/Credential.tsx +++ b/web/src/app/admin/connectors/google-drive/Credential.tsx @@ -15,6 +15,7 @@ import { GOOGLE_DRIVE_AUTH_IS_ADMIN_COOKIE_NAME } from "@/lib/constants"; import Cookies from "js-cookie"; import { TextFormField } from "@/components/admin/connectors/Field"; import { Form, Formik } from "formik"; +import { Card } from "@tremor/react"; type GoogleDriveCredentialJsonTypes = "authorized_user" | "service_account"; @@ -246,7 +247,7 @@ export const DriveJsonUploadSection = ({

Follow the guide{" "} @@ -322,7 +323,7 @@ export const DriveOAuthSection = ({ the documents you want to index with the service account.

-
+ )} -
+
); } diff --git a/web/src/app/admin/connectors/google-drive/GoogleDriveConnectorsTable.tsx b/web/src/app/admin/connectors/google-drive/GoogleDriveConnectorsTable.tsx index 803d9fc70e..5c22158191 100644 --- a/web/src/app/admin/connectors/google-drive/GoogleDriveConnectorsTable.tsx +++ b/web/src/app/admin/connectors/google-drive/GoogleDriveConnectorsTable.tsx @@ -13,6 +13,14 @@ import { useSWRConfig } from "swr"; import { useState } from "react"; import { ConnectorEditPopup } from "./ConnectorEditPopup"; import { DeleteColumn } from "@/components/admin/connectors/table/DeleteColumn"; +import { + Table, + TableHead, + TableRow, + TableHeaderCell, + TableBody, + TableCell, +} from "@tremor/react"; interface EditableColumnProps { connectorIndexingStatus: ConnectorIndexingStatus< @@ -44,7 +52,7 @@ const EditableColumn = ({ connectorIndexingStatus }: EditableColumnProps) => { className="cursor-pointer" >
- +
@@ -74,6 +82,99 @@ export const GoogleDriveConnectorsTable = ({ (a, b) => a.connector.id - b.connector.id ); + return ( +
+ + + + Edit + Folder Paths + Include Shared + Follow Shortcuts + Status + Delete + + + + {sortedGoogleDriveConnectorIndexingStatuses.map( + (connectorIndexingStatus) => { + return ( + + + + + + {( + connectorIndexingStatus.connector + .connector_specific_config.folder_paths || [] + ).length > 0 ? ( +
+ {( + connectorIndexingStatus.connector + .connector_specific_config.folder_paths || [] + ).map((path) => ( +
+ - {path} +
+ ))} +
+ ) : ( + All Folders + )} +
+ +
+ {connectorIndexingStatus.connector + .connector_specific_config.include_shared ? ( + Yes + ) : ( + No + )} +
+
+ +
+ {connectorIndexingStatus.connector + .connector_specific_config.follow_shortcuts ? ( + Yes + ) : ( + No + )} +
+
+ + { + mutate("/api/manage/admin/connector/indexing-status"); + }} + /> + + + + mutate("/api/manage/admin/connector/indexing-status") + } + /> + +
+ ); + } + )} +
+
+
+ ); + return ( ; @@ -54,10 +56,10 @@ const GoogleDriveConnectorManagement = ({ googleDrivePublicCredential || googleDriveServiceAccountCredential; if (!liveCredential) { return ( -

+ Please authenticate with Google Drive as described in Step 2! Once done with that, you can then move on to enable this connector. -

+ ); } @@ -151,7 +153,7 @@ const GoogleDriveConnectorManagement = ({ return (
-
+
{googleDriveConnectorIndexingStatuses.length > 0 ? ( <> @@ -169,7 +171,7 @@ const GoogleDriveConnectorManagement = ({

)}
-
+ {googleDriveConnectorIndexingStatuses.length > 0 && ( <>
Existing Connectors:
@@ -179,13 +181,14 @@ const GoogleDriveConnectorManagement = ({ } setPopup={setPopup} /> + )} {googleDriveConnectorIndexingStatuses.length > 0 && (

Add New Connector:

)} -
+ nameBuilder={googleDriveConnectorNameBuilder} source="google_drive" @@ -239,7 +242,7 @@ const GoogleDriveConnectorManagement = ({ refreshFreq={10 * 60} // 10 minutes credentialId={liveCredential.id} /> -
+
); }; @@ -353,18 +356,18 @@ const Main = () => { return ( <> {popup} -

+ Step 1: Provide your Credentials - </h2> + -

+ Step 2: Authenticate with Danswer - </h2> + { serviceAccountKeyData={serviceAccountKeyData} /> -

+ Step 3: Start Indexing! - </h2> +

-
- -

Google Drive

-
+ + } + title="Google Drive" + />
diff --git a/web/src/app/admin/connectors/google-sites/page.tsx b/web/src/app/admin/connectors/google-sites/page.tsx index 5a9aba9fbd..1bca39c0cd 100644 --- a/web/src/app/admin/connectors/google-sites/page.tsx +++ b/web/src/app/admin/connectors/google-sites/page.tsx @@ -17,6 +17,8 @@ import { linkCredential } from "@/lib/credential"; import { FileUpload } from "@/components/admin/connectors/FileUpload"; import { SingleUseConnectorsTable } from "@/components/admin/connectors/table/SingleUseConnectorsTable"; import { Spinner } from "@/components/Spinner"; +import { AdminPageTitle } from "@/components/admin/Title"; +import { Button, Card, Text, Title } from "@tremor/react"; export default function GoogleSites() { const { mutate } = useSWRConfig(); @@ -50,11 +52,13 @@ export default function GoogleSites() {
-
- -

Google Sites

-
-

+ + } + title="Google Sites" + /> + + For an in-depth guide on how to setup this connector, check out{" "} . -

+
-

Upload Files

-
- { - const uploadCreateAndTriggerConnector = async () => { - const formData = new FormData(); + Upload Files + +
+ { + const uploadCreateAndTriggerConnector = async () => { + const formData = new FormData(); - selectedFiles.forEach((file) => { - formData.append("files", file); - }); - - const response = await fetch( - "/api/manage/admin/connector/file/upload", - { method: "POST", body: formData } - ); - const responseJson = await response.json(); - if (!response.ok) { - setPopup({ - message: `Unable to upload files - ${responseJson.detail}`, - type: "error", + selectedFiles.forEach((file) => { + formData.append("files", file); }); - return; - } - const filePaths = responseJson.file_paths as string[]; - const [connectorErrorMsg, connector] = - await createConnector({ - name: `GoogleSitesConnector-${values.base_url}`, - source: "google_sites", - input_type: "load_state", - connector_specific_config: { - base_url: values.base_url, - zip_path: filePaths[0], - }, - refresh_freq: null, - disabled: false, - }); - if (connectorErrorMsg || !connector) { - setPopup({ - message: `Unable to create connector - ${connectorErrorMsg}`, - type: "error", - }); - return; - } - - const credentialResponse = await linkCredential( - connector.id, - 0, - values.base_url - ); - if (!credentialResponse.ok) { - const credentialResponseJson = - await credentialResponse.json(); - setPopup({ - message: `Unable to link connector to credential - ${credentialResponseJson.detail}`, - type: "error", - }); - return; - } - - const runConnectorErrorMsg = await runConnector( - connector.id, - [0] - ); - if (runConnectorErrorMsg) { - setPopup({ - message: `Unable to run connector - ${runConnectorErrorMsg}`, - type: "error", - }); - return; - } - - mutate("/api/manage/admin/connector/indexing-status"); - setSelectedFiles([]); - formikHelpers.resetForm(); - setPopup({ - type: "success", - message: "Successfully uploaded files!", - }); - }; - - setFilesAreUploading(true); - try { - await uploadCreateAndTriggerConnector(); - } catch (e) { - console.log("Failed to index filels: ", e); - } - setFilesAreUploading(false); - }} - > - {({ values, isSubmitting }) => ( -
- - -

Files:

- - - - )} -
-
+ + const credentialResponse = await linkCredential( + connector.id, + 0, + values.base_url + ); + if (!credentialResponse.ok) { + const credentialResponseJson = + await credentialResponse.json(); + setPopup({ + message: `Unable to link connector to credential - ${credentialResponseJson.detail}`, + type: "error", + }); + return; + } + + const runConnectorErrorMsg = await runConnector( + connector.id, + [0] + ); + if (runConnectorErrorMsg) { + setPopup({ + message: `Unable to run connector - ${runConnectorErrorMsg}`, + type: "error", + }); + return; + } + + mutate("/api/manage/admin/connector/indexing-status"); + setSelectedFiles([]); + formikHelpers.resetForm(); + setPopup({ + type: "success", + message: "Successfully uploaded files!", + }); + }; + + setFilesAreUploading(true); + try { + await uploadCreateAndTriggerConnector(); + } catch (e) { + console.log("Failed to index filels: ", e); + } + setFilesAreUploading(false); + }} + > + {({ values, isSubmitting }) => ( +
+ + +

Files:

+ +
+ +
+ + )} +
+
+

diff --git a/web/src/app/admin/connectors/guru/page.tsx b/web/src/app/admin/connectors/guru/page.tsx index 70d9c0ecea..e302f53891 100644 --- a/web/src/app/admin/connectors/guru/page.tsx +++ b/web/src/app/admin/connectors/guru/page.tsx @@ -19,6 +19,8 @@ import { ConnectorForm } from "@/components/admin/connectors/ConnectorForm"; import { ConnectorsTable } from "@/components/admin/connectors/table/ConnectorsTable"; import { usePopup } from "@/components/admin/connectors/Popup"; import { usePublicCredentials } from "@/lib/hooks"; +import { AdminPageTitle } from "@/components/admin/Title"; +import { Card, Text, Title } from "@tremor/react"; const Main = () => { const { popup, setPopup } = usePopup(); @@ -70,23 +72,23 @@ const Main = () => { return ( <> {popup} -

+ This connector allows you to sync all your Guru Cards into Danswer. -

+ -

+ Step 1: Provide your Credentials - </h2> + {guruCredential ? ( <>
-

Existing Access Token:

-

+ Existing Access Token: + {guruCredential.credential_json?.guru_user_token} -

+
); diff --git a/web/src/app/admin/connectors/linear/page.tsx b/web/src/app/admin/connectors/linear/page.tsx index eb463e1117..76c4a13a8d 100644 --- a/web/src/app/admin/connectors/linear/page.tsx +++ b/web/src/app/admin/connectors/linear/page.tsx @@ -18,6 +18,8 @@ import { ConnectorForm } from "@/components/admin/connectors/ConnectorForm"; import { ConnectorsTable } from "@/components/admin/connectors/table/ConnectorsTable"; import { usePopup } from "@/components/admin/connectors/Popup"; import { usePublicCredentials } from "@/lib/hooks"; +import { Card, Text, Title } from "@tremor/react"; +import { AdminPageTitle } from "@/components/admin/Title"; const Main = () => { const { popup, setPopup } = usePopup(); @@ -70,19 +72,19 @@ const Main = () => { return ( <> {popup} -

+ Step 1: Provide your Credentials - </h2> + {linearCredential ? ( <>
-

Existing API Key:

-

+ Existing API Key: + {linearCredential.credential_json?.linear_api_key} -

+
); diff --git a/web/src/app/admin/connectors/notion/page.tsx b/web/src/app/admin/connectors/notion/page.tsx index be8401633f..4ffdde68a9 100644 --- a/web/src/app/admin/connectors/notion/page.tsx +++ b/web/src/app/admin/connectors/notion/page.tsx @@ -19,6 +19,8 @@ import { ConnectorForm } from "@/components/admin/connectors/ConnectorForm"; import { ConnectorsTable } from "@/components/admin/connectors/table/ConnectorsTable"; import { usePopup } from "@/components/admin/connectors/Popup"; import { usePublicCredentials } from "@/lib/hooks"; +import { AdminPageTitle } from "@/components/admin/Title"; +import { Card, Divider, Text, Title } from "@tremor/react"; const Main = () => { const { popup, setPopup } = usePopup(); @@ -69,9 +71,9 @@ const Main = () => { return ( <> {popup} -

+ Step 1: Provide your authorization details - </h2> + {notionCredential ? ( <> @@ -101,7 +103,7 @@ const Main = () => { ) : ( <> -

+ To get started you'll need to create an internal integration in Notion for Danswer. Follow the instructions in the  { token and paste it below. Follow the remaining instructions on the Notion docs to allow Danswer to read Notion Databases and Pages using the new integration. -

-
+ + formBody={ { } }} /> -
+ )} -

+ Step 2: Manage Connectors - </h2> + {notionConnectorIndexingStatuses.length > 0 && ( <> -

+ The latest page updates are fetched from Notion every 10 minutes. -

+
connectorIndexingStatuses={notionConnectorIndexingStatuses} @@ -183,12 +185,13 @@ const Main = () => { } />
+ )} {notionCredential && ( <> -
+

Create New Connection

Press connect below to start the connection to Notion. @@ -226,17 +229,17 @@ const Main = () => { refreshFreq={10 * 60} // 10 minutes credentialId={notionCredential.id} /> -

+ )} {!notionCredential && ( <> -

+ Please provide your integration details in Step 1 first! Once done with that, you'll be able to start the connection then see indexing status. -

+ )} @@ -249,10 +252,9 @@ export default function Page() {
-
- -

Notion

-
+ + } title="Notion" /> +

); diff --git a/web/src/app/admin/connectors/productboard/page.tsx b/web/src/app/admin/connectors/productboard/page.tsx index f6fdd3cc51..7b38ee42aa 100644 --- a/web/src/app/admin/connectors/productboard/page.tsx +++ b/web/src/app/admin/connectors/productboard/page.tsx @@ -19,6 +19,8 @@ import { ConnectorForm } from "@/components/admin/connectors/ConnectorForm"; import { ConnectorsTable } from "@/components/admin/connectors/table/ConnectorsTable"; import { usePopup } from "@/components/admin/connectors/Popup"; import { usePublicCredentials } from "@/lib/hooks"; +import { Card, Text, Title } from "@tremor/react"; +import { AdminPageTitle } from "@/components/admin/Title"; const Main = () => { const { popup, setPopup } = usePopup(); @@ -72,29 +74,29 @@ const Main = () => { return ( <> {popup} -

+ This connector allows you to sync all your Features,{" "} Components, Products, and Objectives from Productboard into Danswer. At this time, the Productboard APIs does not support pulling in Releases or Notes. -

+ -

+ Step 1: Provide your Credentials - </h2> + {productboardCredential ? ( <>
-

Existing Access Token:

-

+ Existing Access Token: + { productboardCredential.credential_json ?.productboard_access_token } -

+
); diff --git a/web/src/app/admin/connectors/slack/page.tsx b/web/src/app/admin/connectors/slack/page.tsx index 13a45169b7..ae90a57bde 100644 --- a/web/src/app/admin/connectors/slack/page.tsx +++ b/web/src/app/admin/connectors/slack/page.tsx @@ -21,6 +21,8 @@ import { import { ConnectorsTable } from "@/components/admin/connectors/table/ConnectorsTable"; import { ConnectorForm } from "@/components/admin/connectors/ConnectorForm"; import { usePublicCredentials } from "@/lib/hooks"; +import { Button, Card, Divider, Text, Title } from "@tremor/react"; +import { AdminPageTitle } from "@/components/admin/Title"; const MainSection = () => { const { mutate } = useSWRConfig(); @@ -69,25 +71,27 @@ const MainSection = () => { return ( <> -

+ Step 1: Provide Credentials - </h2> + {slackCredential ? ( <>
-

Existing Slack Bot Token:

-

+ Existing Slack Bot Token: + {slackCredential.credential_json.slack_bot_token} -

{" "} - +
) : ( @@ -104,7 +108,7 @@ const MainSection = () => { .

-
+ formBody={ <> @@ -129,20 +133,20 @@ const MainSection = () => { } }} /> -
+ )} -

+ Step 2: Which channels do you want to make searchable? - </h2> + {slackConnectorIndexingStatuses.length > 0 && ( <> -

+ We pull the latest messages from each workspace listed below every{" "} 10 minutes. -

+
connectorIndexingStatuses={slackConnectorIndexingStatuses} @@ -181,11 +185,12 @@ const MainSection = () => { }} />
+ )} {slackCredential ? ( -
+

Connect to a New Workspace

nameBuilder={(values) => @@ -226,13 +231,13 @@ const MainSection = () => { refreshFreq={10 * 60} // 10 minutes credentialId={slackCredential.id} /> -
+ ) : ( -

+ Please provide your slack bot token in Step 1 first! Once done with that, you can then specify which Slack channels you want to make searchable. -

+ )} ); @@ -244,10 +249,9 @@ export default function Page() {
-
- -

Slack

-
+ + } title="Slack" /> +

); diff --git a/web/src/app/admin/connectors/web/page.tsx b/web/src/app/admin/connectors/web/page.tsx index 11d8f9d119..60b90dda64 100644 --- a/web/src/app/admin/connectors/web/page.tsx +++ b/web/src/app/admin/connectors/web/page.tsx @@ -18,7 +18,8 @@ import { HealthCheckBanner } from "@/components/health/healthcheck"; import { ConnectorIndexingStatus, WebConfig } from "@/lib/types"; import { ConnectorsTable } from "@/components/admin/connectors/table/ConnectorsTable"; import { ConnectorForm } from "@/components/admin/connectors/ConnectorForm"; -import { createCredential, linkCredential } from "@/lib/credential"; +import { AdminPageTitle } from "@/components/admin/Title"; +import { Card, Title } from "@tremor/react"; const SCRAPE_TYPE_TO_PRETTY_NAME = { recursive: "Recursive", @@ -49,17 +50,16 @@ export default function Web() {
-
- -

Web

-
-

+ + } title="Web" /> + + Step 1: Specify which websites to index - </h2> +

We re-fetch the latest state of the website once a day.

-
+ nameBuilder={(values) => `WebConnector-${values.base_url}`} ccPairNameBuilder={(values) => values.base_url} @@ -118,11 +118,11 @@ export default function Web() { }} refreshFreq={60 * 60 * 24} // 1 day /> -
+ -

+ Already Indexed Websites - </h2> + {isConnectorIndexingStatusesLoading ? ( ) : isConnectorIndexingStatusesError || !connectorIndexingStatuses ? ( diff --git a/web/src/app/admin/connectors/zendesk/page.tsx b/web/src/app/admin/connectors/zendesk/page.tsx index c8692e251d..ec03e4e70f 100644 --- a/web/src/app/admin/connectors/zendesk/page.tsx +++ b/web/src/app/admin/connectors/zendesk/page.tsx @@ -19,6 +19,8 @@ import { ConnectorForm } from "@/components/admin/connectors/ConnectorForm"; import { ConnectorsTable } from "@/components/admin/connectors/table/ConnectorsTable"; import { usePopup } from "@/components/admin/connectors/Popup"; import { usePublicCredentials } from "@/lib/hooks"; +import { AdminPageTitle } from "@/components/admin/Title"; +import { Card, Divider, Text, Title } from "@tremor/react"; const Main = () => { const { popup, setPopup } = usePopup(); @@ -69,9 +71,9 @@ const Main = () => { return ( <> {popup} -

- Step 1: Provide your API details -

+ + Provide your API details + {zendeskCredential ? ( <> @@ -81,7 +83,7 @@ const Main = () => { {zendeskCredential.credential_json?.zendesk_email}

); diff --git a/web/src/app/admin/documents/ScoreEditor.tsx b/web/src/app/admin/documents/ScoreEditor.tsx index c95df3a714..58b16662f5 100644 --- a/web/src/app/admin/documents/ScoreEditor.tsx +++ b/web/src/app/admin/documents/ScoreEditor.tsx @@ -2,6 +2,7 @@ import { PopupSpec } from "@/components/admin/connectors/Popup"; import { useState } from "react"; import { updateBoost } from "./lib"; import { CheckmarkIcon, EditIcon } from "@/components/icons/icons"; +import { FiEdit } from "react-icons/fi"; export const ScoreSection = ({ documentId, @@ -62,7 +63,7 @@ export const ScoreSection = ({ setScore(initialScore.toString()); } }} - className="border bg-slate-700 text-gray-200 border-gray-300 rounded py-1 px-3 w-16 h-5 my-auto" + className="border bg-background-strong border-gray-300 rounded py-1 px-1 w-12 h-4 my-auto" />
@@ -73,15 +74,15 @@ export const ScoreSection = ({ return (
-
-
+
setIsOpen(true)} + > +
{initialScore}
-
setIsOpen(true)} - > - +
+
diff --git a/web/src/app/admin/documents/explorer/Explorer.tsx b/web/src/app/admin/documents/explorer/Explorer.tsx index d289b9a0ab..b0e2433a53 100644 --- a/web/src/app/admin/documents/explorer/Explorer.tsx +++ b/web/src/app/admin/documents/explorer/Explorer.tsx @@ -30,7 +30,7 @@ const DocumentDisplay = ({ return (
-
+

Boost:

{document.hidden ? ( -
Hidden
+
Hidden
) : ( "Visible" )} @@ -95,7 +95,7 @@ const DocumentDisplay = ({
)} -

+

{buildDocumentSummaryDisplay(document.match_highlights, document.blurb)}

@@ -159,11 +159,11 @@ export function Explorer({
{popup}
-
- +
+