diff --git a/frontend/src/components/Modals/Settings/Keys/index.jsx b/frontend/src/components/Modals/Settings/Keys/index.jsx new file mode 100644 index 00000000..77e1a2f4 --- /dev/null +++ b/frontend/src/components/Modals/Settings/Keys/index.jsx @@ -0,0 +1,280 @@ +import React, { useState, useEffect } from "react"; +import { AlertCircle, Loader, X } from "react-feather"; +import System from "../../../../models/system"; + +const noop = () => false; +export default function SystemKeys({ hideModal = noop }) { + const [loading, setLoading] = useState(true); + const [settings, setSettings] = useState({}); + + function validSettings(settings) { + return ( + settings?.OpenAiKey && + !!settings?.OpenAiModelPref && + !!settings?.VectorDB && + (settings?.VectorDB === "chroma" ? !!settings?.ChromaEndpoint : true) && + (settings?.VectorDB === "pinecone" + ? !!settings?.PineConeKey && + !!settings?.PineConeEnvironment && + !!settings?.PineConeIndex + : true) + ); + } + useEffect(() => { + async function fetchKeys() { + const settings = await System.keys(); + setSettings(settings); + setLoading(false); + } + fetchKeys(); + }, []); + + return ( +
+
+
+

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

+
+
+ {loading ? ( +
+

+ loading system settings +

+
+ ) : ( +
+ {!validSettings(settings) && ( +
+ +

+ Ensure all fields are green before attempting to use + AnythingLLM or it may not function as expected! +

+
+ )} + + +
+ + {settings?.VectorDB === "pinecone" && ( + <> + + + + + )} + {settings?.VectorDB === "chroma" && ( + <> + + + )} +
+ )} +
+
+ +
+
+
+ ); +} + +function ShowKey({ name, env, value, valid, allowDebug = true }) { + const [isValid, setIsValid] = useState(valid); + const [debug, setDebug] = useState(false); + const [saving, setSaving] = useState(false); + const handleSubmit = async (e) => { + e.preventDefault(); + setSaving(true); + const data = {}; + const form = new FormData(e.target); + for (var [key, value] of form.entries()) data[key] = value; + const { newValues, error } = await System.updateSystem(data); + if (!!error) { + alert(error); + setSaving(false); + setIsValid(false); + return; + } + + setSaving(false); + setDebug(false); + setIsValid(true); + }; + + if (!isValid) { + return ( +
+
+ + +
+

+ Need setup in .env file. +

+ {allowDebug && ( + <> + {debug ? ( +
+ {saving ? ( + <> + + + ) : ( + <> + + + + )} +
+ ) : ( + + )} + + )} +
+
+
+ ); + } + + return ( +
+
+ + + {allowDebug && ( +
+ {debug ? ( +
+ {saving ? ( + <> + + + ) : ( + <> + + + + )} +
+ ) : ( + + )} +
+ )} +
+
+ ); +} diff --git a/frontend/src/components/Modals/Settings/index.jsx b/frontend/src/components/Modals/Settings/index.jsx new file mode 100644 index 00000000..d7623c11 --- /dev/null +++ b/frontend/src/components/Modals/Settings/index.jsx @@ -0,0 +1,97 @@ +import React, { useState } from "react"; +import { Key, X } from "react-feather"; +import SystemKeys from "./Keys"; + +const TABS = { + keys: SystemKeys, +}; + +const noop = () => false; +export default function SystemSettingsModal({ hideModal = noop }) { + const [selectedTab, setSelectedTab] = useState("keys"); + const Component = TABS[selectedTab || "keys"]; + + return ( +
+
+
+
+
+
+

+ System Settings +

+ +
+ +
+ +
+
+
+ ); +} + +function SettingTabs({ selectedTab, changeTab }) { + return ( +
+
    + } + onClick={changeTab} + /> +
+
+ ); +} + +function SettingTab({ + active = false, + displayName, + tabName, + icon = "", + onClick, +}) { + const classes = active + ? "text-blue-600 border-blue-600 active dark:text-blue-400 dark:border-blue-400 bg-blue-500 bg-opacity-5" + : "border-transparent hover:text-gray-600 hover:border-gray-300 dark:hover:text-gray-300"; + return ( +
  • + +
  • + ); +} + +export function useSystemSettingsModal() { + const [showing, setShowing] = useState(false); + const showModal = () => { + setShowing(true); + }; + const hideModal = () => { + setShowing(false); + }; + + return { showing, showModal, hideModal }; +} diff --git a/frontend/src/components/Sidebar/index.jsx b/frontend/src/components/Sidebar/index.jsx index fc50fe04..880e54fd 100644 --- a/frontend/src/components/Sidebar/index.jsx +++ b/frontend/src/components/Sidebar/index.jsx @@ -7,10 +7,13 @@ import { Key, Menu, Plus, + Tool, } from "react-feather"; import IndexCount from "./IndexCount"; import LLMStatus from "./LLMStatus"; -import KeysModal, { useKeysModal } from "../Modals/Keys"; +import SystemSettingsModal, { + useSystemSettingsModal, +} from "../Modals/Settings"; import NewWorkspaceModal, { useNewWorkspaceModal, } from "../Modals/NewWorkspace"; @@ -20,10 +23,10 @@ import paths from "../../utils/paths"; export default function Sidebar() { const sidebarRef = useRef(null); const { - showing: showingKeyModal, - showModal: showKeyModal, - hideModal: hideKeyModal, - } = useKeysModal(); + showing: showingSystemSettingsModal, + showModal: showSystemSettingsModal, + hideModal: hideSystemSettingsModal, + } = useSystemSettingsModal(); const { showing: showingNewWsModal, showModal: showNewWsModal, @@ -45,10 +48,10 @@ export default function Sidebar() {

    @@ -126,7 +129,9 @@ export default function Sidebar() {
    - {showingKeyModal && } + {showingSystemSettingsModal && ( + + )} {showingNewWsModal && } ); @@ -137,10 +142,10 @@ export function SidebarMobileHeader() { const [showBgOverlay, setShowBgOverlay] = useState(false); const sidebarRef = useRef(null); const { - showing: showingKeyModal, - showModal: showKeyModal, - hideModal: hideKeyModal, - } = useKeysModal(); + showing: showingSystemSettingsModal, + showModal: showSystemSettingsModal, + hideModal: hideSystemSettingsModal, + } = useSystemSettingsModal(); const { showing: showingNewWsModal, showModal: showNewWsModal, @@ -199,10 +204,10 @@ export function SidebarMobileHeader() {

    @@ -283,7 +288,9 @@ export function SidebarMobileHeader() { - {showingKeyModal && } + {showingSystemSettingsModal && ( + + )} {showingNewWsModal && }