From 6e8d81c01efbeeb4e373c23a9bb0268d43c3616d Mon Sep 17 00:00:00 2001 From: Timothy Carambat Date: Thu, 3 Aug 2023 15:59:51 -0700 Subject: [PATCH] better vector db selection UI on settings (#175) update logout button --- .../Modals/Settings/VectorDbs/index.jsx | 232 ++++++++++++++++++ .../src/components/Modals/Settings/index.jsx | 39 +-- frontend/src/components/Sidebar/index.jsx | 27 ++ frontend/src/media/vectordbs/chroma.png | Bin 0 -> 2006 bytes frontend/src/media/vectordbs/lancedb.png | Bin 0 -> 1896 bytes frontend/src/media/vectordbs/pinecone.png | Bin 0 -> 2166 bytes server/utils/helpers/updateENV.js | 4 +- 7 files changed, 274 insertions(+), 28 deletions(-) create mode 100644 frontend/src/components/Modals/Settings/VectorDbs/index.jsx create mode 100644 frontend/src/media/vectordbs/chroma.png create mode 100644 frontend/src/media/vectordbs/lancedb.png create mode 100644 frontend/src/media/vectordbs/pinecone.png diff --git a/frontend/src/components/Modals/Settings/VectorDbs/index.jsx b/frontend/src/components/Modals/Settings/VectorDbs/index.jsx new file mode 100644 index 00000000..0c4f5a38 --- /dev/null +++ b/frontend/src/components/Modals/Settings/VectorDbs/index.jsx @@ -0,0 +1,232 @@ +import React, { useState } from "react"; +import System from "../../../../models/system"; +import ChromaLogo from "../../../../media/vectordbs/chroma.png"; +import PineconeLogo from "../../../../media/vectordbs/pinecone.png"; +import LanceDbLogo from "../../../../media/vectordbs/lancedb.png"; + +const noop = () => false; +export default function VectorDBSelection({ + hideModal = noop, + user, + settings = {}, +}) { + const [hasChanges, setHasChanges] = useState(false); + const [vectorDB, setVectorDB] = useState(settings?.VectorDB || "lancedb"); + const [saving, setSaving] = useState(false); + const [error, setError] = useState(null); + const canDebug = settings.MultiUserMode + ? settings?.CanDebug && user?.role === "admin" + : settings?.CanDebug; + + function updateVectorChoice(selection) { + if (!canDebug || selection === vectorDB) return false; + setHasChanges(true); + setVectorDB(selection); + } + + const handleSubmit = async (e) => { + e.preventDefault(); + setSaving(true); + setError(null); + const data = {}; + const form = new FormData(e.target); + for (var [key, value] of form.entries()) data[key] = value; + const { error } = await System.updateSystem(data); + setError(error); + setSaving(false); + setHasChanges(!!error ? true : false); + }; + return ( +
+
+
+

+ These are the credentials and settings for how your AnythingLLM + instance will function. Its important these keys are current and + correct. +

+
+ + {!!error && ( +
+

{error}

+
+ )} + +
setHasChanges(true)}> +
+
+

+ Vector database provider +

+
+ + + + +
+ {vectorDB === "pinecone" && ( + <> +
+ + +
+ +
+ + +
+ +
+ + +
+ + )} + + {vectorDB === "chroma" && ( + <> +
+ + +
+ + )} + {vectorDB === "lancedb" && ( +
+

+ There is no configuration needed for LanceDB. +

+
+ )} +
+
+
+ +
+
+
+ +
+
+
+ ); +} + +const VectorDBOption = ({ + name, + link, + description, + value, + image, + checked = false, + onClick, +}) => { + return ( +
onClick(value)}> + + +
+ ); +}; diff --git a/frontend/src/components/Modals/Settings/index.jsx b/frontend/src/components/Modals/Settings/index.jsx index 9d02d94e..a9ce6de2 100644 --- a/frontend/src/components/Modals/Settings/index.jsx +++ b/frontend/src/components/Modals/Settings/index.jsx @@ -1,26 +1,27 @@ import React, { useEffect, useState } from "react"; -import { Archive, Lock, Key, X, Users, LogOut } from "react-feather"; +import { Archive, Lock, Key, X, Users, Database } from "react-feather"; import SystemKeys from "./Keys"; import ExportOrImportData from "./ExportImport"; import PasswordProtection from "./PasswordProtection"; import System from "../../../models/system"; import MultiUserMode from "./MultiUserMode"; -import { AUTH_TOKEN, AUTH_USER } from "../../../utils/constants"; -import paths from "../../../utils/paths"; import useUser from "../../../hooks/useUser"; +import VectorDBSelection from "./VectorDbs"; const TABS = { keys: SystemKeys, exportimport: ExportOrImportData, password: PasswordProtection, multiuser: MultiUserMode, + vectordb: VectorDBSelection, }; const noop = () => false; export default function SystemSettingsModal({ hideModal = noop }) { const { user } = useUser(); const [loading, setLoading] = useState(true); - const [selectedTab, setSelectedTab] = useState("keys"); + // const [selectedTab, setSelectedTab] = useState("keys"); + const [selectedTab, setSelectedTab] = useState("vectordb"); const [settings, setSettings] = useState(null); const Component = TABS[selectedTab || "keys"]; @@ -93,6 +94,13 @@ function SettingTabs({ selectedTab, changeTab, settings, user }) { icon={} onClick={changeTab} /> + } + onClick={changeTab} + /> } onClick={changeTab} /> - {!settings?.MultiUserMode ? ( + {!settings?.MultiUserMode && ( <> - ) : ( - )} ); @@ -150,25 +156,6 @@ function SettingTab({ ); } -function LogoutTab({ user }) { - if (!user) return null; - - return ( -
  • - -
  • - ); -} - export function useSystemSettingsModal() { const [showing, setShowing] = useState(false); const showModal = () => { diff --git a/frontend/src/components/Sidebar/index.jsx b/frontend/src/components/Sidebar/index.jsx index 3b67abf3..8f453ca7 100644 --- a/frontend/src/components/Sidebar/index.jsx +++ b/frontend/src/components/Sidebar/index.jsx @@ -4,6 +4,7 @@ import { Briefcase, Cpu, GitHub, + LogOut, Menu, Plus, Shield, @@ -21,6 +22,8 @@ import ActiveWorkspaces from "./ActiveWorkspaces"; import paths from "../../utils/paths"; import Discord from "../Icons/Discord"; import useUser from "../../hooks/useUser"; +import { userFromStorage } from "../../utils/request"; +import { AUTH_TOKEN, AUTH_USER } from "../../utils/constants"; export default function Sidebar() { const sidebarRef = useRef(null); @@ -103,6 +106,7 @@ export default function Sidebar() { Enterprise Installation

    + {/* Footer */} @@ -269,6 +273,7 @@ export function SidebarMobileHeader() { Enterprise Installation

    + {/* Footer */} @@ -325,3 +330,25 @@ function AdminHome() { ); } + +function LogoutButton() { + if (!window.localStorage.getItem(AUTH_USER)) return null; + const user = userFromStorage(); + if (!user.username) return null; + + return ( + + ); +} diff --git a/frontend/src/media/vectordbs/chroma.png b/frontend/src/media/vectordbs/chroma.png new file mode 100644 index 0000000000000000000000000000000000000000..fde25384d5592fe9d5eb441be28e0ccda5332d82 GIT binary patch literal 2006 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 literal 0 HcmV?d00001 diff --git a/server/utils/helpers/updateENV.js b/server/utils/helpers/updateENV.js index 54eec1e5..0ff95fa4 100644 --- a/server/utils/helpers/updateENV.js +++ b/server/utils/helpers/updateENV.js @@ -92,8 +92,8 @@ function validChromaURL(input = "") { function updateENV(newENVs = {}) { let error = ""; const validKeys = Object.keys(KEY_MAPPING); - const ENV_KEYS = Object.keys(newENVs).filter((key) => - validKeys.includes(key) + const ENV_KEYS = Object.keys(newENVs).filter( + (key) => validKeys.includes(key) && !newENVs[key].includes("******") // strip out answers where the value is all asterisks ); const newValues = {};