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 && (
+
+ )}
+
+
+
+
+
+
+
+ );
+}
+
+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 = {};