mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2025-04-17 18:18:11 +00:00
Light/dark mode UI overhaul (#2629)
* Refactor workspace sidebar component styles (#2380) rely on css for conditional styles * New sidebar colors (#2381) new sidebar colors * Main container color update (#2382) * Dark mode setup themes (#2411) * setup generic tailwind theme + ability to add new themes * add theme context * use correct colors from design for sidebar + fix padding * Settings sidebar UI updates (#2416) settings sidebar ui updates * fix sidebar resizing/truncate issue on hover * Dark mode chat window (#2443) * Support XLSX files (#2403) * support xlsx files * lint * create seperate docs for each xlsx sheet * lint * use node-xlsx pkg for parsing xslx files * lint * update error handling --------- Co-authored-by: timothycarambat <rambat1010@gmail.com> * wip chat window * ux+ux improvements and update new colors * chat window dark mode * remove comment --------- Co-authored-by: timothycarambat <rambat1010@gmail.com> * Dark mode welcome page (#2444) * dark mode welcome page styles + refactor * remove AI_BACKGROUND_COLOR and USER_BACKGROUND_COLOR constants * Dark mode UI for admin and tools pages + mobile view improvements (#2454) * dark mode ui for admin and tools pages + mobile view improvements * lint * ai provider pages + options darkmode ui * placeholder generic class * appearance settings styles * ai providers mobile margin * dark mode styles for agent skills + experimental features * mobile styles on security settings * fine tune flow ui dark mode * workspace settings page * lint * Dark mode onboarding (#2461) dark mode onboarding * update all modals + normalize styles (#2471) * lint * Dark mode privacy & experimental pages (#2479) * document watch + privacy pages ui + mobile modal darkmode * lint * Dark mode login screens (#2483) * multi-user auth screen ui update * dark mode login screen + recovery key modals * remove unneeded import * Workspace preset commands modals dark mode (#2484) update workspace preset dark mode modal * Document pinning modal ui update (#2490) document pinning modal ui update * Experimental agreement modal dark mode (#2491) experimental agreement modal dark mode * Serp options dark mode (#2492) serp options dark mode * field fixes * attempt light mode wip * setting sidebar * Toasts and threads * main page content and privacy page * force rewrite for light * add border for light mode rightside content * more fixes * wip * wip * wip light mode implementation * wip dark light mode file picker * document picker light mode ui * slight ui tweaks * light mode fine tuning flow * light mode tweaks + qa fixes * fix md rendering of light mode + tooltip fixes * lint * qa bug fixes * Add developer hook for theme move provider to outmost layer * qa light mode bug fixes * Linting and hotfixes for UI * Light mode to dev * accept invite light mode ui fix * Fix onboarding inputs in dark mode * fix close icons last minute items * patch z-index on tooltips * patch light mode citations --------- Co-authored-by: timothycarambat <rambat1010@gmail.com>
This commit is contained in:
parent
e29f054706
commit
727d802779
243 changed files with 3512 additions and 2829 deletions
.github/workflows
frontend/src
App.jsxLogoContext.jsxThemeContext.jsxindex.jsxNewWorkspace.jsxPreloader.jsx
components
ChatBubble
ContextualSaveBar
DefaultChat
EditingChatBubble
EmbeddingSelection
AzureAiOptions
CohereOptions
EmbedderItem
GenericOpenAiOptions
LMStudioOptions
LiteLLMOptions
LocalAiOptions
OllamaOptions
OpenAiOptions
VoyageAiOptions
Footer
LLMSelection
AnthropicAiOptions
ApiPieOptions
AwsBedrockLLMOptions
AzureAiOptions
CohereAiOptions
DeepSeekOptions
FireworksAiOptions
GeminiLLMOptions
GenericOpenAiOptions
GroqAiOptions
HuggingFaceOptions
KoboldCPPOptions
LLMItem
LMStudioOptions
LiteLLMOptions
LocalAiOptions
MistralOptions
NativeLLMOptions
NovitaLLMOptions
OllamaLLMOptions
OpenAiOptions
OpenRouterOptions
PerplexityOptions
TextGenWebUIOptions
TogetherAiOptions
XAiLLMOptions
ModalWrapper
Modals
DisplayRecoveryCodeModal
ManageWorkspace
DataConnectors
Documents
Directory
UploadFile
WorkspaceDirectory
Password
SettingsButton
SettingsSidebar
Sidebar
TextToSpeech
ElevenLabsOptions
OpenAiGenericOptions
OpenAiOptions
PiperTTSOptions
TranscriptionSelection
UserIcon
UserMenu
VectorDBSelection
AstraDBOptions
ChromaDBOptions
MilvusDBOptions
PineconeDBOptions
QDrantDBOptions
VectorDBItem
WeaviateDBOptions
ZillizCloudOptions
WorkspaceChat/ChatContainer/ChatHistory
Citation
HistoricalMessage/Actions
2
.github/workflows/dev-build.yaml
vendored
2
.github/workflows/dev-build.yaml
vendored
|
@ -6,7 +6,7 @@ concurrency:
|
|||
|
||||
on:
|
||||
push:
|
||||
branches: ['2602-page-load-speed'] # put your current branch to create a build. Core team only.
|
||||
branches: ['light-mode-1'] # put your current branch to create a build. Core team only.
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'cloud-deployments/*'
|
||||
|
|
|
@ -16,6 +16,7 @@ import i18n from "./i18n";
|
|||
import { PfpProvider } from "./PfpContext";
|
||||
import { LogoProvider } from "./LogoContext";
|
||||
import { FullScreenLoader } from "./components/Preloader";
|
||||
import { ThemeProvider } from "./ThemeContext";
|
||||
|
||||
const Main = lazy(() => import("@/pages/Main"));
|
||||
const InvitePage = lazy(() => import("@/pages/Invite"));
|
||||
|
@ -70,139 +71,149 @@ const FineTuningWalkthrough = lazy(() => import("@/pages/FineTuning"));
|
|||
|
||||
export default function App() {
|
||||
return (
|
||||
<Suspense fallback={<FullScreenLoader />}>
|
||||
<ContextWrapper>
|
||||
<LogoProvider>
|
||||
<PfpProvider>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<Routes>
|
||||
<Route path="/" element={<PrivateRoute Component={Main} />} />
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route path="/sso/simple" element={<SimpleSSOPassthrough />} />
|
||||
<ThemeProvider>
|
||||
<Suspense fallback={<FullScreenLoader />}>
|
||||
<ContextWrapper>
|
||||
<LogoProvider>
|
||||
<PfpProvider>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<Routes>
|
||||
<Route path="/" element={<PrivateRoute Component={Main} />} />
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route
|
||||
path="/sso/simple"
|
||||
element={<SimpleSSOPassthrough />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/workspace/:slug/settings/:tab"
|
||||
element={<ManagerRoute Component={WorkspaceSettings} />}
|
||||
/>
|
||||
<Route
|
||||
path="/workspace/:slug"
|
||||
element={<PrivateRoute Component={WorkspaceChat} />}
|
||||
/>
|
||||
<Route
|
||||
path="/workspace/:slug/t/:threadSlug"
|
||||
element={<PrivateRoute Component={WorkspaceChat} />}
|
||||
/>
|
||||
<Route path="/accept-invite/:code" element={<InvitePage />} />
|
||||
<Route
|
||||
path="/workspace/:slug/settings/:tab"
|
||||
element={<ManagerRoute Component={WorkspaceSettings} />}
|
||||
/>
|
||||
<Route
|
||||
path="/workspace/:slug"
|
||||
element={<PrivateRoute Component={WorkspaceChat} />}
|
||||
/>
|
||||
<Route
|
||||
path="/workspace/:slug/t/:threadSlug"
|
||||
element={<PrivateRoute Component={WorkspaceChat} />}
|
||||
/>
|
||||
<Route path="/accept-invite/:code" element={<InvitePage />} />
|
||||
|
||||
{/* Admin */}
|
||||
<Route
|
||||
path="/settings/llm-preference"
|
||||
element={<AdminRoute Component={GeneralLLMPreference} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/transcription-preference"
|
||||
element={
|
||||
<AdminRoute Component={GeneralTranscriptionPreference} />
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/audio-preference"
|
||||
element={<AdminRoute Component={GeneralAudioPreference} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/embedding-preference"
|
||||
element={
|
||||
<AdminRoute Component={GeneralEmbeddingPreference} />
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/text-splitter-preference"
|
||||
element={
|
||||
<AdminRoute Component={EmbeddingTextSplitterPreference} />
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/vector-database"
|
||||
element={<AdminRoute Component={GeneralVectorDatabase} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/agents"
|
||||
element={<AdminRoute Component={AdminAgents} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/event-logs"
|
||||
element={<AdminRoute Component={AdminLogs} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/embed-config"
|
||||
element={<AdminRoute Component={EmbedConfigSetup} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/embed-chats"
|
||||
element={<AdminRoute Component={EmbedChats} />}
|
||||
/>
|
||||
{/* Manager */}
|
||||
<Route
|
||||
path="/settings/security"
|
||||
element={<ManagerRoute Component={GeneralSecurity} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/privacy"
|
||||
element={<AdminRoute Component={PrivacyAndData} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/appearance"
|
||||
element={<ManagerRoute Component={GeneralAppearance} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/beta-features"
|
||||
element={<AdminRoute Component={ExperimentalFeatures} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/api-keys"
|
||||
element={<AdminRoute Component={GeneralApiKeys} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/browser-extension"
|
||||
element={<ManagerRoute Component={GeneralBrowserExtension} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/workspace-chats"
|
||||
element={<ManagerRoute Component={GeneralChats} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/invites"
|
||||
element={<ManagerRoute Component={AdminInvites} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/users"
|
||||
element={<ManagerRoute Component={AdminUsers} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/workspaces"
|
||||
element={<ManagerRoute Component={AdminWorkspaces} />}
|
||||
/>
|
||||
{/* Onboarding Flow */}
|
||||
<Route path="/onboarding" element={<OnboardingFlow />} />
|
||||
<Route path="/onboarding/:step" element={<OnboardingFlow />} />
|
||||
{/* Admin */}
|
||||
<Route
|
||||
path="/settings/llm-preference"
|
||||
element={<AdminRoute Component={GeneralLLMPreference} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/transcription-preference"
|
||||
element={
|
||||
<AdminRoute Component={GeneralTranscriptionPreference} />
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/audio-preference"
|
||||
element={<AdminRoute Component={GeneralAudioPreference} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/embedding-preference"
|
||||
element={
|
||||
<AdminRoute Component={GeneralEmbeddingPreference} />
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/text-splitter-preference"
|
||||
element={
|
||||
<AdminRoute Component={EmbeddingTextSplitterPreference} />
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/vector-database"
|
||||
element={<AdminRoute Component={GeneralVectorDatabase} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/agents"
|
||||
element={<AdminRoute Component={AdminAgents} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/event-logs"
|
||||
element={<AdminRoute Component={AdminLogs} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/embed-config"
|
||||
element={<AdminRoute Component={EmbedConfigSetup} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/embed-chats"
|
||||
element={<AdminRoute Component={EmbedChats} />}
|
||||
/>
|
||||
{/* Manager */}
|
||||
<Route
|
||||
path="/settings/security"
|
||||
element={<ManagerRoute Component={GeneralSecurity} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/privacy"
|
||||
element={<AdminRoute Component={PrivacyAndData} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/appearance"
|
||||
element={<ManagerRoute Component={GeneralAppearance} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/beta-features"
|
||||
element={<AdminRoute Component={ExperimentalFeatures} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/api-keys"
|
||||
element={<AdminRoute Component={GeneralApiKeys} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/browser-extension"
|
||||
element={
|
||||
<ManagerRoute Component={GeneralBrowserExtension} />
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/workspace-chats"
|
||||
element={<ManagerRoute Component={GeneralChats} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/invites"
|
||||
element={<ManagerRoute Component={AdminInvites} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/users"
|
||||
element={<ManagerRoute Component={AdminUsers} />}
|
||||
/>
|
||||
<Route
|
||||
path="/settings/workspaces"
|
||||
element={<ManagerRoute Component={AdminWorkspaces} />}
|
||||
/>
|
||||
{/* Onboarding Flow */}
|
||||
<Route path="/onboarding" element={<OnboardingFlow />} />
|
||||
<Route
|
||||
path="/onboarding/:step"
|
||||
element={<OnboardingFlow />}
|
||||
/>
|
||||
|
||||
{/* Experimental feature pages */}
|
||||
{/* Live Document Sync feature */}
|
||||
<Route
|
||||
path="/settings/beta-features/live-document-sync/manage"
|
||||
element={<AdminRoute Component={LiveDocumentSyncManage} />}
|
||||
/>
|
||||
{/* Experimental feature pages */}
|
||||
{/* Live Document Sync feature */}
|
||||
<Route
|
||||
path="/settings/beta-features/live-document-sync/manage"
|
||||
element={<AdminRoute Component={LiveDocumentSyncManage} />}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/fine-tuning"
|
||||
element={<AdminRoute Component={FineTuningWalkthrough} />}
|
||||
/>
|
||||
</Routes>
|
||||
<ToastContainer />
|
||||
</I18nextProvider>
|
||||
</PfpProvider>
|
||||
</LogoProvider>
|
||||
</ContextWrapper>
|
||||
</Suspense>
|
||||
<Route
|
||||
path="/fine-tuning"
|
||||
element={<AdminRoute Component={FineTuningWalkthrough} />}
|
||||
/>
|
||||
</Routes>
|
||||
<ToastContainer />
|
||||
</I18nextProvider>
|
||||
</PfpProvider>
|
||||
</LogoProvider>
|
||||
</ContextWrapper>
|
||||
</Suspense>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { createContext, useEffect, useState } from "react";
|
||||
import AnythingLLM from "./media/logo/anything-llm.png";
|
||||
import DefaultLoginLogo from "./media/illustrations/login-logo.svg";
|
||||
import AnythingLLMDark from "./media/logo/anything-llm-dark.png";
|
||||
import DefaultLoginLogoLight from "./media/illustrations/login-logo.svg";
|
||||
import DefaultLoginLogoDark from "./media/illustrations/login-logo-light.svg";
|
||||
import System from "./models/system";
|
||||
|
||||
export const LogoContext = createContext();
|
||||
|
@ -9,6 +11,10 @@ export function LogoProvider({ children }) {
|
|||
const [logo, setLogo] = useState("");
|
||||
const [loginLogo, setLoginLogo] = useState("");
|
||||
const [isCustomLogo, setIsCustomLogo] = useState(false);
|
||||
const DefaultLoginLogo =
|
||||
localStorage.getItem("theme") !== "default"
|
||||
? DefaultLoginLogoDark
|
||||
: DefaultLoginLogoLight;
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchInstanceLogo() {
|
||||
|
@ -19,12 +25,16 @@ export function LogoProvider({ children }) {
|
|||
setLoginLogo(isCustomLogo ? logoURL : DefaultLoginLogo);
|
||||
setIsCustomLogo(isCustomLogo);
|
||||
} else {
|
||||
setLogo(AnythingLLM);
|
||||
localStorage.getItem("theme") !== "default"
|
||||
? setLogo(AnythingLLMDark)
|
||||
: setLogo(AnythingLLM);
|
||||
setLoginLogo(DefaultLoginLogo);
|
||||
setIsCustomLogo(false);
|
||||
}
|
||||
} catch (err) {
|
||||
setLogo(AnythingLLM);
|
||||
localStorage.getItem("theme") !== "default"
|
||||
? setLogo(AnythingLLMDark)
|
||||
: setLogo(AnythingLLM);
|
||||
setLoginLogo(DefaultLoginLogo);
|
||||
setIsCustomLogo(false);
|
||||
console.error("Failed to fetch logo:", err);
|
||||
|
|
16
frontend/src/ThemeContext.jsx
Normal file
16
frontend/src/ThemeContext.jsx
Normal file
|
@ -0,0 +1,16 @@
|
|||
import React, { createContext, useContext } from "react";
|
||||
import { useTheme } from "./hooks/useTheme";
|
||||
|
||||
const ThemeContext = createContext();
|
||||
|
||||
export function ThemeProvider({ children }) {
|
||||
const themeValue = useTheme();
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={themeValue}>{children}</ThemeContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useThemeContext() {
|
||||
return useContext(ThemeContext);
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
import React from "react";
|
||||
import UserIcon from "../UserIcon";
|
||||
import { userFromStorage } from "@/utils/request";
|
||||
import { AI_BACKGROUND_COLOR, USER_BACKGROUND_COLOR } from "@/utils/constants";
|
||||
|
||||
export default function ChatBubble({ message, type, popMsg }) {
|
||||
const isUser = type === "user";
|
||||
const backgroundColor = isUser ? USER_BACKGROUND_COLOR : AI_BACKGROUND_COLOR;
|
||||
|
||||
return (
|
||||
<div className={`flex justify-center items-end w-full ${backgroundColor}`}>
|
||||
<div
|
||||
className={`flex justify-center items-end w-full bg-theme-bg-secondary`}
|
||||
>
|
||||
<div className={`py-8 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}>
|
||||
<div className="flex gap-x-5">
|
||||
<UserIcon
|
||||
|
|
|
@ -10,18 +10,18 @@ export default function ContextualSaveBar({
|
|||
return (
|
||||
<div className="fixed top-0 left-0 right-0 h-14 bg-dark-input flex items-center justify-end px-4 z-[999]">
|
||||
<div className="absolute ml-4 left-0 md:left-1/2 transform md:-translate-x-1/2 flex items-center gap-x-2">
|
||||
<Warning size={18} className="text-white" />
|
||||
<p className="text-white font-medium text-xs">Unsaved Changes</p>
|
||||
<Warning size={18} className="text-[#FFFFFF]" />
|
||||
<p className="text-[#FFFFFF] font-medium text-xs">Unsaved Changes</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-x-2">
|
||||
<button
|
||||
className="border-none text-white font-medium text-sm px-[10px] py-[6px] rounded-md bg-white/5 hover:bg-white/10"
|
||||
className="border-none text-theme-text-primary font-medium text-sm px-[10px] py-[6px] rounded-md bg-theme-bg-secondary hover:bg-theme-bg-primary"
|
||||
onClick={onCancel}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
className="border-none text-dark-text font-medium text-sm px-[10px] py-[6px] rounded-md bg-primary-button hover:bg-[#3DB5E8]"
|
||||
className="border-none text-theme-text-primary font-medium text-sm px-[10px] py-[6px] rounded-md bg-primary-button hover:bg-primary-button-hover"
|
||||
onClick={onSave}
|
||||
>
|
||||
Save
|
||||
|
|
|
@ -15,7 +15,6 @@ import ChatBubble from "../ChatBubble";
|
|||
import System from "@/models/system";
|
||||
import UserIcon from "../UserIcon";
|
||||
import { userFromStorage } from "@/utils/request";
|
||||
import { AI_BACKGROUND_COLOR, USER_BACKGROUND_COLOR } from "@/utils/constants";
|
||||
import useUser from "@/hooks/useUser";
|
||||
import { useTranslation, Trans } from "react-i18next";
|
||||
import Appearance from "@/models/appearance";
|
||||
|
@ -43,239 +42,136 @@ export default function DefaultChatContainer() {
|
|||
|
||||
const MESSAGES = [
|
||||
<React.Fragment key="msg1">
|
||||
<div
|
||||
className={`flex justify-center items-end w-full ${AI_BACKGROUND_COLOR} md:mt-0 mt-[40px]`}
|
||||
>
|
||||
<div
|
||||
className={`pt-10 pb-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
|
||||
>
|
||||
<div className="flex gap-x-5">
|
||||
<UserIcon user={{ uid: "system" }} role={"assistant"} />
|
||||
|
||||
<span
|
||||
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
|
||||
>
|
||||
{t("welcomeMessage.part1")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<MessageContainer>
|
||||
<MessageContent>
|
||||
<UserIcon user={{ uid: "system" }} role={"assistant"} />
|
||||
<MessageText>{t("welcomeMessage.part1")}</MessageText>
|
||||
</MessageContent>
|
||||
</MessageContainer>
|
||||
</React.Fragment>,
|
||||
|
||||
<React.Fragment key="msg2">
|
||||
<div
|
||||
className={`flex justify-center items-end w-full ${AI_BACKGROUND_COLOR}`}
|
||||
>
|
||||
<div
|
||||
className={`pb-4 pt-2 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
|
||||
>
|
||||
<div className="flex gap-x-5">
|
||||
<UserIcon user={{ uid: "system" }} role={"assistant"} />
|
||||
|
||||
<span
|
||||
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
|
||||
>
|
||||
{t("welcomeMessage.part2")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<MessageContainer>
|
||||
<MessageContent>
|
||||
<UserIcon user={{ uid: "system" }} role={"assistant"} />
|
||||
<MessageText>{t("welcomeMessage.part2")}</MessageText>
|
||||
</MessageContent>
|
||||
</MessageContainer>
|
||||
</React.Fragment>,
|
||||
|
||||
<React.Fragment key="msg3">
|
||||
<div
|
||||
className={`flex justify-center items-end w-full ${AI_BACKGROUND_COLOR}`}
|
||||
>
|
||||
<div
|
||||
className={`pt-2 pb-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
|
||||
>
|
||||
<div className="flex gap-x-5">
|
||||
<UserIcon user={{ uid: "system" }} role={"assistant"} />
|
||||
<div>
|
||||
<span
|
||||
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
|
||||
<MessageContainer>
|
||||
<MessageContent>
|
||||
<UserIcon user={{ uid: "system" }} role={"assistant"} />
|
||||
<div>
|
||||
<MessageText>{t("welcomeMessage.part3")}</MessageText>
|
||||
<a
|
||||
href={paths.github()}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="mt-5 w-fit transition-all duration-300 border border-slate-200 px-4 py-2 rounded-lg text-white light:border-black/50 light:text-theme-text-primary text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800 focus:ring-gray-800"
|
||||
>
|
||||
<GitMerge className="h-4 w-4" />
|
||||
<p>{t("welcomeMessage.githubIssue")}</p>
|
||||
</a>
|
||||
</div>
|
||||
</MessageContent>
|
||||
</MessageContainer>
|
||||
</React.Fragment>,
|
||||
|
||||
<React.Fragment key="msg4">
|
||||
<MessageContainer>
|
||||
<MessageContent>
|
||||
<UserIcon user={{ uid: userFromStorage()?.username }} role={"user"} />
|
||||
<MessageText>{t("welcomeMessage.user1")}</MessageText>
|
||||
</MessageContent>
|
||||
</MessageContainer>
|
||||
</React.Fragment>,
|
||||
|
||||
<React.Fragment key="msg5">
|
||||
<MessageContainer>
|
||||
<MessageContent>
|
||||
<UserIcon user={{ uid: "system" }} role={"assistant"} />
|
||||
<div>
|
||||
<MessageText>{t("welcomeMessage.part4")}</MessageText>
|
||||
|
||||
{(!user || user?.role !== "default") && (
|
||||
<button
|
||||
onClick={showNewWsModal}
|
||||
className="mt-5 w-fit transition-all duration-300 border border-slate-200 px-4 py-2 rounded-lg text-white light:border-black/50 light:text-theme-text-primary text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800 focus:ring-gray-800"
|
||||
>
|
||||
{t("welcomeMessage.part3")}
|
||||
</span>
|
||||
<Plus className="h-4 w-4" />
|
||||
<p>{t("welcomeMessage.createWorkspace")}</p>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</MessageContent>
|
||||
</MessageContainer>
|
||||
</React.Fragment>,
|
||||
|
||||
<React.Fragment key="msg6">
|
||||
<MessageContainer>
|
||||
<MessageContent>
|
||||
<UserIcon user={{ uid: userFromStorage()?.username }} role={"user"} />
|
||||
<MessageText>{t("welcomeMessage.user2")}</MessageText>
|
||||
</MessageContent>
|
||||
</MessageContainer>
|
||||
</React.Fragment>,
|
||||
|
||||
<React.Fragment key="msg7">
|
||||
<MessageContainer>
|
||||
<MessageContent>
|
||||
<UserIcon user={{ uid: "system" }} role={"assistant"} />
|
||||
<MessageText>
|
||||
<Trans
|
||||
i18nKey="welcomeMessage.part5"
|
||||
components={{
|
||||
i: <i />,
|
||||
br: <br />,
|
||||
}}
|
||||
/>
|
||||
</MessageText>
|
||||
</MessageContent>
|
||||
</MessageContainer>
|
||||
</React.Fragment>,
|
||||
|
||||
<React.Fragment key="msg8">
|
||||
<MessageContainer>
|
||||
<MessageContent>
|
||||
<UserIcon user={{ uid: userFromStorage()?.username }} role={"user"} />
|
||||
<MessageText>{t("welcomeMessage.user3")}</MessageText>
|
||||
</MessageContent>
|
||||
</MessageContainer>
|
||||
</React.Fragment>,
|
||||
|
||||
<React.Fragment key="msg9">
|
||||
<MessageContainer>
|
||||
<MessageContent>
|
||||
<UserIcon user={{ uid: "system" }} role={"assistant"} />
|
||||
<div>
|
||||
<MessageText>{t("welcomeMessage.part6")}</MessageText>
|
||||
|
||||
<div className="flex flex-col md:flex-row items-start md:items-center gap-1 md:gap-4">
|
||||
<a
|
||||
href={paths.github()}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="mt-5 w-fit transition-all duration-300 border border-slate-200 px-4 py-2 rounded-lg text-white text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800 focus:ring-gray-800"
|
||||
className="mt-5 w-fit transition-all duration-300 border border-slate-200 px-4 py-2 rounded-lg text-white light:border-black/50 light:text-theme-text-primary text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800 focus:ring-gray-800"
|
||||
>
|
||||
<GitMerge className="h-4 w-4" />
|
||||
<p>{t("welcomeMessage.githubIssue")}</p>
|
||||
<GithubLogo className="h-4 w-4" />
|
||||
<p>{t("welcomeMessage.starOnGithub")}</p>
|
||||
</a>
|
||||
<a
|
||||
href={paths.mailToMintplex()}
|
||||
className="mt-5 w-fit transition-all duration-300 border border-slate-200 px-4 py-2 rounded-lg text-white light:border-black/50 light:text-theme-text-primary text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800 focus:ring-gray-800"
|
||||
>
|
||||
<EnvelopeSimple className="h-4 w-4" />
|
||||
<p>{t("welcomeMessage.contact")}</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>,
|
||||
|
||||
<React.Fragment key="msg4">
|
||||
<div
|
||||
className={`flex justify-center items-end w-full ${USER_BACKGROUND_COLOR}`}
|
||||
>
|
||||
<div
|
||||
className={`py-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
|
||||
>
|
||||
<div className="flex gap-x-5">
|
||||
<UserIcon
|
||||
user={{ uid: userFromStorage()?.username }}
|
||||
role={"user"}
|
||||
/>
|
||||
|
||||
<span
|
||||
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
|
||||
>
|
||||
{t("welcomeMessage.user1")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>,
|
||||
|
||||
<React.Fragment key="msg5">
|
||||
<div
|
||||
className={`flex justify-center items-end w-full ${AI_BACKGROUND_COLOR}`}
|
||||
>
|
||||
<div
|
||||
className={`py-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
|
||||
>
|
||||
<div className="flex gap-x-5">
|
||||
<UserIcon user={{ uid: "system" }} role={"assistant"} />
|
||||
<div>
|
||||
<span
|
||||
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
|
||||
>
|
||||
{t("welcomeMessage.part4")}
|
||||
</span>
|
||||
|
||||
{(!user || user?.role !== "default") && (
|
||||
<button
|
||||
onClick={showNewWsModal}
|
||||
className="mt-5 w-fit transition-all duration-300 border border-slate-200 px-4 py-2 rounded-lg text-white text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800 focus:ring-gray-800"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
<p>{t("welcomeMessage.createWorkspace")}</p>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>,
|
||||
|
||||
<React.Fragment key="msg6">
|
||||
<div
|
||||
className={`flex justify-center items-end w-full ${USER_BACKGROUND_COLOR}`}
|
||||
>
|
||||
<div
|
||||
className={`py-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
|
||||
>
|
||||
<div className="flex gap-x-5">
|
||||
<UserIcon
|
||||
user={{ uid: userFromStorage()?.username }}
|
||||
role={"user"}
|
||||
/>
|
||||
|
||||
<span
|
||||
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
|
||||
>
|
||||
{t("welcomeMessage.user2")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>,
|
||||
|
||||
<React.Fragment key="msg7">
|
||||
<div
|
||||
className={`flex justify-center items-end w-full ${AI_BACKGROUND_COLOR}`}
|
||||
>
|
||||
<div
|
||||
className={`py-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
|
||||
>
|
||||
<div className="flex gap-x-5">
|
||||
<UserIcon user={{ uid: "system" }} role={"assistant"} />
|
||||
|
||||
<span
|
||||
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
|
||||
>
|
||||
<Trans
|
||||
i18nKey="welcomeMessage.part5"
|
||||
components={{
|
||||
i: <i />,
|
||||
br: <br />,
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>,
|
||||
|
||||
<React.Fragment key="msg8">
|
||||
<div
|
||||
className={`flex justify-center items-end w-full ${USER_BACKGROUND_COLOR}`}
|
||||
>
|
||||
<div
|
||||
className={`py-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
|
||||
>
|
||||
<div className="flex gap-x-5">
|
||||
<UserIcon
|
||||
user={{ uid: userFromStorage()?.username }}
|
||||
role={"user"}
|
||||
/>
|
||||
|
||||
<span
|
||||
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
|
||||
>
|
||||
{t("welcomeMessage.user3")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>,
|
||||
|
||||
<React.Fragment key="msg9">
|
||||
<div
|
||||
className={`flex justify-center items-end w-full ${AI_BACKGROUND_COLOR}`}
|
||||
>
|
||||
<div
|
||||
className={`py-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
|
||||
>
|
||||
<div className="flex gap-x-5">
|
||||
<UserIcon user={{ uid: "system" }} role={"assistant"} />
|
||||
<div>
|
||||
<span
|
||||
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
|
||||
>
|
||||
{t("welcomeMessage.part6")}
|
||||
</span>
|
||||
|
||||
<div className="flex flex-col md:flex-row items-start md:items-center gap-1 md:gap-4">
|
||||
<a
|
||||
href={paths.github()}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="mt-5 w-fit transition-all duration-300 border border-slate-200 px-4 py-2 rounded-lg text-white text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800 focus:ring-gray-800"
|
||||
>
|
||||
<GithubLogo className="h-4 w-4" />
|
||||
<p>{t("welcomeMessage.starOnGithub")}</p>
|
||||
</a>
|
||||
<a
|
||||
href={paths.mailToMintplex()}
|
||||
className="mt-5 w-fit transition-all duration-300 border border-slate-200 px-4 py-2 rounded-lg text-white text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800 focus:ring-gray-800"
|
||||
>
|
||||
<EnvelopeSimple className="h-4 w-4" />
|
||||
<p>{t("welcomeMessage.contact")}</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</MessageContent>
|
||||
</MessageContainer>
|
||||
</React.Fragment>,
|
||||
];
|
||||
|
||||
|
@ -307,7 +203,7 @@ export default function DefaultChatContainer() {
|
|||
return (
|
||||
<div
|
||||
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
|
||||
className={`relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-main-gradient w-full border-2 border-outline overflow-y-scroll ${
|
||||
className={`transition-all duration-500 relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-theme-bg-secondary light:border-[1px] light:border-theme-sidebar-border w-full h-full overflow-y-scroll ${
|
||||
showScrollbar ? "show-scrollbar" : "no-scroll"
|
||||
}`}
|
||||
>
|
||||
|
@ -335,3 +231,25 @@ export default function DefaultChatContainer() {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function MessageContainer({ children }) {
|
||||
return (
|
||||
<div className="flex justify-center items-end w-full">
|
||||
<div className="py-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function MessageContent({ children }) {
|
||||
return <div className="flex gap-x-5">{children}</div>;
|
||||
}
|
||||
|
||||
function MessageText({ children }) {
|
||||
return (
|
||||
<span className="text-white/80 light:text-theme-text-primary font-light text-[14px] flex flex-col gap-y-1 mt-2">
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,9 @@ export default function EditingChatBubble({
|
|||
|
||||
return (
|
||||
<div>
|
||||
<p className={`text-xs text-[#D3D4D4] ${isUser ? "text-right" : ""}`}>
|
||||
<p
|
||||
className={`text-xs text-white light:text-black/80 ${isUser ? "text-right" : ""}`}
|
||||
>
|
||||
{isUser ? t("common.user") : t("appearance.message.assistant")}
|
||||
</p>
|
||||
<div
|
||||
|
@ -25,7 +27,7 @@ export default function EditingChatBubble({
|
|||
}`}
|
||||
>
|
||||
<button
|
||||
className={`transition-all duration-300 absolute z-10 text-white rounded-full hover:bg-neutral-700 hover:border-white border-transparent border shadow-lg ${
|
||||
className={`transition-all duration-300 absolute z-10 text-white rounded-full hover:bg-neutral-700 light:hover:invert hover:border-white border-transparent border shadow-lg ${
|
||||
isUser ? "right-0 mr-2" : "ml-2"
|
||||
}`}
|
||||
style={{ top: "6px", [isUser ? "right" : "left"]: "290px" }}
|
||||
|
@ -49,13 +51,13 @@ export default function EditingChatBubble({
|
|||
setIsEditing(false);
|
||||
}}
|
||||
autoFocus
|
||||
className={`w-full ${
|
||||
className={`w-full light:text-white ${
|
||||
isUser ? "bg-[#41444C] text-white" : "bg-[#2E3036] text-white"
|
||||
}`}
|
||||
/>
|
||||
) : (
|
||||
tempMessage && (
|
||||
<p className=" font-[500] md:font-semibold text-sm md:text-base break-words">
|
||||
<p className=" font-[500] md:font-semibold text-sm md:text-base break-words light:invert">
|
||||
{tempMessage}
|
||||
</p>
|
||||
)
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function AzureAiOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="AzureOpenAiEndpoint"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="https://my-azure.openai.azure.com"
|
||||
defaultValue={settings?.AzureOpenAiEndpoint}
|
||||
required={true}
|
||||
|
@ -25,7 +25,7 @@ export default function AzureAiOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="AzureOpenAiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Azure OpenAI API Key"
|
||||
defaultValue={settings?.AzureOpenAiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -41,7 +41,7 @@ export default function AzureAiOptions({ settings }) {
|
|||
<input
|
||||
type="text"
|
||||
name="AzureOpenAiEmbeddingModelPref"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Azure OpenAI embedding model deployment name"
|
||||
defaultValue={settings?.AzureOpenAiEmbeddingModelPref}
|
||||
required={true}
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function CohereEmbeddingOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="CohereApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Cohere API Key"
|
||||
defaultValue={settings?.CohereApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -24,7 +24,7 @@ export default function CohereEmbeddingOptions({ settings }) {
|
|||
<select
|
||||
name="EmbeddingModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<optgroup label="Available embedding models">
|
||||
{[
|
||||
|
|
|
@ -9,8 +9,8 @@ export default function EmbedderItem({
|
|||
return (
|
||||
<div
|
||||
onClick={() => onClick(value)}
|
||||
className={`w-full p-2 rounded-md hover:cursor-pointer hover:bg-white/10 ${
|
||||
checked ? "bg-white/10" : ""
|
||||
className={`w-full p-2 rounded-md hover:cursor-pointer hover:bg-theme-bg-secondary ${
|
||||
checked ? "bg-theme-bg-secondary" : ""
|
||||
}`}
|
||||
>
|
||||
<input
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function GenericOpenAiEmbeddingOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="EmbeddingBasePath"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="https://api.openai.com/v1"
|
||||
defaultValue={settings?.EmbeddingBasePath}
|
||||
required={true}
|
||||
|
@ -24,7 +24,7 @@ export default function GenericOpenAiEmbeddingOptions({ settings }) {
|
|||
<input
|
||||
type="text"
|
||||
name="EmbeddingModelPref"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="text-embedding-ada-002"
|
||||
defaultValue={settings?.EmbeddingModelPref}
|
||||
required={true}
|
||||
|
@ -39,7 +39,7 @@ export default function GenericOpenAiEmbeddingOptions({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="EmbeddingModelMaxChunkLength"
|
||||
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="8192"
|
||||
min={1}
|
||||
onScroll={(e) => e.target.blur()}
|
||||
|
@ -59,7 +59,7 @@ export default function GenericOpenAiEmbeddingOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="GenericOpenAiEmbeddingApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="sk-mysecretkey"
|
||||
defaultValue={
|
||||
settings?.GenericOpenAiEmbeddingApiKey ? "*".repeat(20) : ""
|
||||
|
|
|
@ -38,7 +38,7 @@ export default function LMStudioEmbeddingOptions({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="EmbeddingModelMaxChunkLength"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="8192"
|
||||
min={1}
|
||||
value={maxChunkLength}
|
||||
|
@ -94,7 +94,7 @@ export default function LMStudioEmbeddingOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="EmbeddingBasePath"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://localhost:1234/v1"
|
||||
value={basePathValue.value}
|
||||
required={true}
|
||||
|
@ -150,7 +150,7 @@ function LMStudioModelSelection({ settings, basePath = null }) {
|
|||
<select
|
||||
name="EmbeddingModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
{!!basePath
|
||||
|
@ -174,7 +174,7 @@ function LMStudioModelSelection({ settings, basePath = null }) {
|
|||
<select
|
||||
name="EmbeddingModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{customModels.length > 0 && (
|
||||
<optgroup label="Your loaded models">
|
||||
|
|
|
@ -19,7 +19,7 @@ export default function LiteLLMOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="LiteLLMBasePath"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://127.0.0.1:4000"
|
||||
defaultValue={settings?.LiteLLMBasePath}
|
||||
required={true}
|
||||
|
@ -41,7 +41,7 @@ export default function LiteLLMOptions({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="EmbeddingModelMaxChunkLength"
|
||||
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="8192"
|
||||
min={1}
|
||||
onScroll={(e) => e.target.blur()}
|
||||
|
@ -61,7 +61,7 @@ export default function LiteLLMOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="LiteLLMAPIKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="sk-mysecretkey"
|
||||
defaultValue={settings?.LiteLLMAPIKey ? "*".repeat(20) : ""}
|
||||
autoComplete="off"
|
||||
|
@ -107,7 +107,7 @@ function LiteLLMModelSelection({ settings, basePath = null, apiKey = null }) {
|
|||
<select
|
||||
name="EmbeddingModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
{basePath?.includes("/v1")
|
||||
|
@ -130,7 +130,7 @@ function LiteLLMModelSelection({ settings, basePath = null, apiKey = null }) {
|
|||
<select
|
||||
name="EmbeddingModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{customModels.length > 0 && (
|
||||
<optgroup label="Your loaded models">
|
||||
|
|
|
@ -36,7 +36,7 @@ export default function LocalAiOptions({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="EmbeddingModelMaxChunkLength"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="1000"
|
||||
min={1}
|
||||
onScroll={(e) => e.target.blur()}
|
||||
|
@ -55,7 +55,7 @@ export default function LocalAiOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="LocalAiApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="sk-mysecretkey"
|
||||
defaultValue={settings?.LocalAiApiKey ? "*".repeat(20) : ""}
|
||||
autoComplete="off"
|
||||
|
@ -106,7 +106,7 @@ export default function LocalAiOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="EmbeddingBasePath"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://localhost:8080/v1"
|
||||
value={basePathValue.value}
|
||||
required={true}
|
||||
|
@ -154,7 +154,7 @@ function LocalAIModelSelection({ settings, apiKey = null, basePath = null }) {
|
|||
<select
|
||||
name="EmbeddingModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
{basePath?.includes("/v1")
|
||||
|
@ -174,7 +174,7 @@ function LocalAIModelSelection({ settings, apiKey = null, basePath = null }) {
|
|||
<select
|
||||
name="EmbeddingModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{customModels.length > 0 && (
|
||||
<optgroup label="Your loaded models">
|
||||
|
|
|
@ -41,7 +41,7 @@ export default function OllamaEmbeddingOptions({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="EmbeddingModelMaxChunkLength"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="8192"
|
||||
min={1}
|
||||
value={maxChunkLength}
|
||||
|
@ -97,7 +97,7 @@ export default function OllamaEmbeddingOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="EmbeddingBasePath"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://127.0.0.1:11434"
|
||||
value={basePathValue.value}
|
||||
required={true}
|
||||
|
@ -149,7 +149,7 @@ function OllamaEmbeddingModelSelection({ settings, basePath = null }) {
|
|||
<select
|
||||
name="EmbeddingModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
{!!basePath
|
||||
|
@ -173,7 +173,7 @@ function OllamaEmbeddingModelSelection({ settings, basePath = null }) {
|
|||
<select
|
||||
name="EmbeddingModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{customModels.length > 0 && (
|
||||
<optgroup label="Your loaded models">
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function OpenAiOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="OpenAiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="OpenAI API Key"
|
||||
defaultValue={settings?.OpenAiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -24,7 +24,7 @@ export default function OpenAiOptions({ settings }) {
|
|||
<select
|
||||
name="EmbeddingModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<optgroup label="Available embedding models">
|
||||
{[
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function VoyageAiOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="VoyageAiApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Voyage AI API Key"
|
||||
defaultValue={settings?.VoyageAiApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -25,7 +25,7 @@ export default function VoyageAiOptions({ settings }) {
|
|||
name="EmbeddingModelPref"
|
||||
required={true}
|
||||
defaultValue={settings?.EmbeddingModelPref}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<optgroup label="Available embedding models">
|
||||
{[
|
||||
|
|
|
@ -53,12 +53,16 @@ export default function Footer() {
|
|||
href={paths.github()}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="transition-all duration-300 p-2 rounded-full text-white bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
className="transition-all duration-300 p-2 rounded-full bg-theme-sidebar-footer-icon hover:bg-theme-sidebar-footer-icon-hover"
|
||||
aria-label="Find us on Github"
|
||||
data-tooltip-id="footer-item"
|
||||
data-tooltip-content="View source code on Github"
|
||||
>
|
||||
<GithubLogo weight="fill" className="h-5 w-5 " />
|
||||
<GithubLogo
|
||||
weight="fill"
|
||||
className="h-5 w-5"
|
||||
color="var(--theme-sidebar-footer-icon-fill)"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div className="flex w-fit">
|
||||
|
@ -66,12 +70,16 @@ export default function Footer() {
|
|||
href={paths.docs()}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="w-fit transition-all duration-300 p-2 rounded-full text-white bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
className="transition-all duration-300 p-2 rounded-full bg-theme-sidebar-footer-icon hover:bg-theme-sidebar-footer-icon-hover"
|
||||
aria-label="Docs"
|
||||
data-tooltip-id="footer-item"
|
||||
data-tooltip-content="Open AnythingLLM help docs"
|
||||
>
|
||||
<BookOpen weight="fill" className="h-5 w-5 " />
|
||||
<BookOpen
|
||||
weight="fill"
|
||||
className="h-5 w-5"
|
||||
color="var(--theme-sidebar-footer-icon-fill)"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div className="flex w-fit">
|
||||
|
@ -79,14 +87,15 @@ export default function Footer() {
|
|||
href={paths.discord()}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="transition-all duration-300 p-2 rounded-full text-white bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
className="transition-all duration-300 p-2 rounded-full bg-theme-sidebar-footer-icon hover:bg-theme-sidebar-footer-icon-hover"
|
||||
aria-label="Join our Discord server"
|
||||
data-tooltip-id="footer-item"
|
||||
data-tooltip-content="Join the AnythingLLM Discord"
|
||||
>
|
||||
<DiscordLogo
|
||||
weight="fill"
|
||||
className="h-5 w-5 stroke-slate-200 group-hover:stroke-slate-200"
|
||||
className="h-5 w-5"
|
||||
color="var(--theme-sidebar-footer-icon-fill)"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -111,13 +120,14 @@ export default function Footer() {
|
|||
href={item.url}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="transition-all duration-300 p-2 rounded-full text-white bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
className="transition-all duration-300 p-2 rounded-full bg-theme-sidebar-footer-icon hover:bg-theme-sidebar-footer-icon-hover"
|
||||
>
|
||||
{React.createElement(
|
||||
ICON_COMPONENTS?.[item.icon] ?? ICON_COMPONENTS.Info,
|
||||
{
|
||||
weight: "fill",
|
||||
className: "h-5 w-5",
|
||||
color: "var(--theme-sidebar-footer-icon-fill)",
|
||||
}
|
||||
)}
|
||||
</a>
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function AnthropicAiOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="AnthropicApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Anthropic Claude-2 API Key"
|
||||
defaultValue={settings?.AnthropicApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -27,7 +27,7 @@ export default function AnthropicAiOptions({ settings }) {
|
|||
name="AnthropicModelPref"
|
||||
defaultValue={settings?.AnthropicModelPref || "claude-2"}
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{[
|
||||
"claude-instant-1.2",
|
||||
|
|
|
@ -12,7 +12,7 @@ export default function ApiPieLLMOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="ApipieLLMApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="APIpie API Key"
|
||||
defaultValue={settings?.ApipieLLMApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -60,7 +60,7 @@ function APIPieModelSelection({ settings }) {
|
|||
<select
|
||||
name="ApipieLLMModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
-- loading available models --
|
||||
|
@ -78,7 +78,7 @@ function APIPieModelSelection({ settings }) {
|
|||
<select
|
||||
name="ApipieLLMModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
>
|
||||
{Object.keys(groupedModels)
|
||||
.sort()
|
||||
|
|
|
@ -36,16 +36,20 @@ export default function AwsBedrockLLMOptions({ settings }) {
|
|||
value={useSessionToken ? "sessionToken" : "iam"}
|
||||
/>
|
||||
<div className="flex flex-col w-full">
|
||||
<label className="text-white text-sm font-semibold block mb-3">
|
||||
<label className="text-theme-text-primary text-sm font-semibold block mb-3">
|
||||
Use session token
|
||||
</label>
|
||||
<p className="text-white/50 text-sm">
|
||||
<p className="text-theme-text-secondary text-sm">
|
||||
Select the method to authenticate with AWS Bedrock.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center justify-start gap-x-4 bg-zinc-900 p-2.5 rounded-lg w-fit">
|
||||
<div className="flex items-center justify-start gap-x-4 bg-theme-settings-input-bg p-2.5 rounded-lg w-fit">
|
||||
<span
|
||||
className={`text-sm ${!useSessionToken ? "text-white" : "text-white/50"}`}
|
||||
className={`text-sm ${
|
||||
!useSessionToken
|
||||
? "text-theme-text-primary"
|
||||
: "text-theme-text-secondary"
|
||||
}`}
|
||||
>
|
||||
IAM
|
||||
</span>
|
||||
|
@ -56,10 +60,14 @@ export default function AwsBedrockLLMOptions({ settings }) {
|
|||
checked={useSessionToken}
|
||||
onChange={(e) => setUseSessionToken(e.target.checked)}
|
||||
/>
|
||||
<div className="w-11 h-6 bg-zinc-700 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary-button"></div>
|
||||
<div className="w-11 h-6 bg-[#4b5563] light:bg-[#e5e7eb] peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-[#d1d5db] light:after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary-button"></div>
|
||||
</label>
|
||||
<span
|
||||
className={`text-sm ${useSessionToken ? "text-white" : "text-white/50"}`}
|
||||
className={`text-sm ${
|
||||
useSessionToken
|
||||
? "text-theme-text-primary"
|
||||
: "text-theme-text-secondary"
|
||||
}`}
|
||||
>
|
||||
Session Token
|
||||
</span>
|
||||
|
@ -74,7 +82,7 @@ export default function AwsBedrockLLMOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="AwsBedrockLLMAccessKeyId"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="AWS Bedrock IAM User Access ID"
|
||||
defaultValue={
|
||||
settings?.AwsBedrockLLMAccessKeyId ? "*".repeat(20) : ""
|
||||
|
@ -91,7 +99,7 @@ export default function AwsBedrockLLMOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="AwsBedrockLLMAccessKey"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="AWS Bedrock IAM User Access Key"
|
||||
defaultValue={
|
||||
settings?.AwsBedrockLLMAccessKey ? "*".repeat(20) : ""
|
||||
|
@ -103,13 +111,13 @@ export default function AwsBedrockLLMOptions({ settings }) {
|
|||
</div>
|
||||
{useSessionToken && (
|
||||
<div className="flex flex-col w-60">
|
||||
<label className="text-white text-sm font-semibold block mb-3">
|
||||
<label className="text-theme-text-primary text-sm font-semibold block mb-3">
|
||||
AWS Bedrock Session Token
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="AwsBedrockLLMSessionToken"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="AWS Bedrock Session Token"
|
||||
defaultValue={
|
||||
settings?.AwsBedrockLLMSessionToken ? "*".repeat(20) : ""
|
||||
|
@ -128,7 +136,7 @@ export default function AwsBedrockLLMOptions({ settings }) {
|
|||
name="AwsBedrockLLMRegion"
|
||||
defaultValue={settings?.AwsBedrockLLMRegion || "us-west-2"}
|
||||
required={true}
|
||||
className="border-none bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
>
|
||||
{AWS_REGIONS.map((region) => {
|
||||
return (
|
||||
|
@ -151,7 +159,7 @@ export default function AwsBedrockLLMOptions({ settings }) {
|
|||
<input
|
||||
type="text"
|
||||
name="AwsBedrockLLMModel"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Model id from AWS eg: meta.llama3.1-v0.1"
|
||||
defaultValue={settings?.AwsBedrockLLMModel}
|
||||
required={true}
|
||||
|
@ -166,7 +174,7 @@ export default function AwsBedrockLLMOptions({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="AwsBedrockLLMTokenLimit"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Content window limit (eg: 4096)"
|
||||
min={1}
|
||||
onScroll={(e) => e.target.blur()}
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function AzureAiOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="AzureOpenAiEndpoint"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="https://my-azure.openai.azure.com"
|
||||
defaultValue={settings?.AzureOpenAiEndpoint}
|
||||
required={true}
|
||||
|
@ -25,7 +25,7 @@ export default function AzureAiOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="AzureOpenAiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Azure OpenAI API Key"
|
||||
defaultValue={settings?.AzureOpenAiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -41,7 +41,7 @@ export default function AzureAiOptions({ settings }) {
|
|||
<input
|
||||
type="text"
|
||||
name="AzureOpenAiModelPref"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Azure OpenAI chat model deployment name"
|
||||
defaultValue={settings?.AzureOpenAiModelPref}
|
||||
required={true}
|
||||
|
@ -59,7 +59,7 @@ export default function AzureAiOptions({ settings }) {
|
|||
<select
|
||||
name="AzureOpenAiTokenLimit"
|
||||
defaultValue={settings?.AzureOpenAiTokenLimit || 4096}
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
required={true}
|
||||
>
|
||||
<option value={4096}>4,096 (gpt-3.5-turbo)</option>
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function CohereAiOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="CohereApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Cohere API Key"
|
||||
defaultValue={settings?.CohereApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -25,7 +25,7 @@ export default function CohereAiOptions({ settings }) {
|
|||
name="CohereModelPref"
|
||||
defaultValue={settings?.CohereModelPref || "command-r"}
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{[
|
||||
"command-r",
|
||||
|
|
|
@ -16,7 +16,7 @@ export default function DeepSeekOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="DeepSeekApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="DeepSeek API Key"
|
||||
defaultValue={settings?.DeepSeekApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -65,7 +65,7 @@ function DeepSeekModelSelection({ apiKey, settings }) {
|
|||
<select
|
||||
name="DeepSeekModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
-- loading available models --
|
||||
|
@ -83,7 +83,7 @@ function DeepSeekModelSelection({ apiKey, settings }) {
|
|||
<select
|
||||
name="DeepSeekModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{models.map((model) => (
|
||||
<option
|
||||
|
|
|
@ -11,7 +11,7 @@ export default function FireworksAiOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="FireworksAiLLMApiKey"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Fireworks AI API Key"
|
||||
defaultValue={settings?.FireworksAiLLMApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -58,7 +58,7 @@ function FireworksAiModelSelection({ settings }) {
|
|||
<select
|
||||
name="FireworksAiLLMModelPref"
|
||||
disabled={true}
|
||||
className="border-none bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
-- loading available models --
|
||||
|
@ -76,7 +76,7 @@ function FireworksAiModelSelection({ settings }) {
|
|||
<select
|
||||
name="FireworksAiLLMModelPref"
|
||||
required={true}
|
||||
className="border-none bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{Object.keys(groupedModels)
|
||||
.sort()
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function GeminiLLMOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="GeminiLLMApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Google Gemini API Key"
|
||||
defaultValue={settings?.GeminiLLMApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -28,7 +28,7 @@ export default function GeminiLLMOptions({ settings }) {
|
|||
name="GeminiLLMModelPref"
|
||||
defaultValue={settings?.GeminiLLMModelPref || "gemini-pro"}
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<optgroup label="Stable Models">
|
||||
{[
|
||||
|
@ -70,7 +70,7 @@ export default function GeminiLLMOptions({ settings }) {
|
|||
settings?.GeminiSafetySetting || "BLOCK_MEDIUM_AND_ABOVE"
|
||||
}
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option value="BLOCK_NONE">None</option>
|
||||
<option value="BLOCK_ONLY_HIGH">Block few</option>
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function GenericOpenAiOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="GenericOpenAiBasePath"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="eg: https://proxy.openai.com"
|
||||
defaultValue={settings?.GenericOpenAiBasePath}
|
||||
required={true}
|
||||
|
@ -24,7 +24,7 @@ export default function GenericOpenAiOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="GenericOpenAiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Generic service API Key"
|
||||
defaultValue={settings?.GenericOpenAiKey ? "*".repeat(20) : ""}
|
||||
required={false}
|
||||
|
@ -39,7 +39,7 @@ export default function GenericOpenAiOptions({ settings }) {
|
|||
<input
|
||||
type="text"
|
||||
name="GenericOpenAiModelPref"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Model id used for chat requests"
|
||||
defaultValue={settings?.GenericOpenAiModelPref}
|
||||
required={true}
|
||||
|
@ -55,7 +55,7 @@ export default function GenericOpenAiOptions({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="GenericOpenAiTokenLimit"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Content window limit (eg: 4096)"
|
||||
min={1}
|
||||
onScroll={(e) => e.target.blur()}
|
||||
|
@ -71,7 +71,7 @@ export default function GenericOpenAiOptions({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="GenericOpenAiMaxTokens"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Max tokens per request (eg: 1024)"
|
||||
min={1}
|
||||
defaultValue={settings?.GenericOpenAiMaxTokens || 1024}
|
||||
|
|
|
@ -14,7 +14,7 @@ export default function GroqAiOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="GroqApiKey"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Groq API Key"
|
||||
defaultValue={settings?.GroqApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -67,7 +67,7 @@ function GroqAIModelSelection({ apiKey, settings }) {
|
|||
<select
|
||||
name="GroqModelPref"
|
||||
disabled={true}
|
||||
className="border-none bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
--loading available models--
|
||||
|
@ -88,7 +88,7 @@ function GroqAIModelSelection({ apiKey, settings }) {
|
|||
<select
|
||||
name="GroqModelPref"
|
||||
required={true}
|
||||
className="border-none bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{customModels.length > 0 && (
|
||||
<optgroup label="Available models">
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function HuggingFaceOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="HuggingFaceLLMEndpoint"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="https://example.endpoints.huggingface.cloud"
|
||||
defaultValue={settings?.HuggingFaceLLMEndpoint}
|
||||
required={true}
|
||||
|
@ -24,7 +24,7 @@ export default function HuggingFaceOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="HuggingFaceLLMAccessToken"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="HuggingFace Access Token"
|
||||
defaultValue={
|
||||
settings?.HuggingFaceLLMAccessToken ? "*".repeat(20) : ""
|
||||
|
@ -41,7 +41,7 @@ export default function HuggingFaceOptions({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="HuggingFaceLLMTokenLimit"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="4096"
|
||||
min={1}
|
||||
onScroll={(e) => e.target.blur()}
|
||||
|
|
|
@ -41,7 +41,7 @@ export default function KoboldCPPOptions({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="KoboldCPPTokenLimit"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="4096"
|
||||
min={1}
|
||||
value={tokenLimit}
|
||||
|
@ -97,7 +97,7 @@ export default function KoboldCPPOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="KoboldCPPBasePath"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://127.0.0.1:5000/v1"
|
||||
value={basePathValue.value}
|
||||
required={true}
|
||||
|
@ -153,7 +153,7 @@ function KoboldCPPModelSelection({ settings, basePath = null }) {
|
|||
<select
|
||||
name="KoboldCPPModelPref"
|
||||
disabled={true}
|
||||
className="border-none bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
{basePath?.includes("/v1")
|
||||
|
@ -177,7 +177,7 @@ function KoboldCPPModelSelection({ settings, basePath = null }) {
|
|||
<select
|
||||
name="KoboldCPPModelPref"
|
||||
required={true}
|
||||
className="border-none bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{customModels.map((model) => (
|
||||
<option
|
||||
|
|
|
@ -9,8 +9,8 @@ export default function LLMItem({
|
|||
return (
|
||||
<div
|
||||
onClick={() => onClick(value)}
|
||||
className={`w-full p-2 rounded-md hover:cursor-pointer hover:bg-white/10 ${
|
||||
checked ? "bg-white/10" : ""
|
||||
className={`w-full p-2 rounded-md hover:cursor-pointer hover:bg-theme-bg-secondary ${
|
||||
checked ? "bg-theme-bg-secondary" : ""
|
||||
}`}
|
||||
>
|
||||
<input
|
||||
|
|
|
@ -56,7 +56,7 @@ export default function LMStudioOptions({ settings, showAlert = false }) {
|
|||
<input
|
||||
type="number"
|
||||
name="LMStudioTokenLimit"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="4096"
|
||||
defaultChecked="4096"
|
||||
min={1}
|
||||
|
@ -113,7 +113,7 @@ export default function LMStudioOptions({ settings, showAlert = false }) {
|
|||
<input
|
||||
type="url"
|
||||
name="LMStudioBasePath"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://localhost:1234/v1"
|
||||
value={basePathValue.value}
|
||||
required={true}
|
||||
|
@ -169,7 +169,7 @@ function LMStudioModelSelection({ settings, basePath = null }) {
|
|||
<select
|
||||
name="LMStudioModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
{!!basePath
|
||||
|
@ -193,7 +193,7 @@ function LMStudioModelSelection({ settings, basePath = null }) {
|
|||
<select
|
||||
name="LMStudioModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{customModels.length > 0 && (
|
||||
<optgroup label="Your loaded models">
|
||||
|
|
|
@ -17,7 +17,7 @@ export default function LiteLLMOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="LiteLLMBasePath"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://127.0.0.1:4000"
|
||||
defaultValue={settings?.LiteLLMBasePath}
|
||||
required={true}
|
||||
|
@ -39,7 +39,7 @@ export default function LiteLLMOptions({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="LiteLLMTokenLimit"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="4096"
|
||||
min={1}
|
||||
onScroll={(e) => e.target.blur()}
|
||||
|
@ -59,7 +59,7 @@ export default function LiteLLMOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="LiteLLMAPIKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="sk-mysecretkey"
|
||||
defaultValue={settings?.LiteLLMAPIKey ? "*".repeat(20) : ""}
|
||||
autoComplete="off"
|
||||
|
@ -105,7 +105,7 @@ function LiteLLMModelSelection({ settings, basePath = null, apiKey = null }) {
|
|||
<select
|
||||
name="LiteLLMModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
{basePath?.includes("/v1")
|
||||
|
@ -125,7 +125,7 @@ function LiteLLMModelSelection({ settings, basePath = null, apiKey = null }) {
|
|||
<select
|
||||
name="LiteLLMModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{customModels.length > 0 && (
|
||||
<optgroup label="Your loaded models">
|
||||
|
|
|
@ -56,7 +56,7 @@ export default function LocalAiOptions({ settings, showAlert = false }) {
|
|||
<input
|
||||
type="number"
|
||||
name="LocalAiTokenLimit"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="4096"
|
||||
min={1}
|
||||
onScroll={(e) => e.target.blur()}
|
||||
|
@ -77,7 +77,7 @@ export default function LocalAiOptions({ settings, showAlert = false }) {
|
|||
<input
|
||||
type="password"
|
||||
name="LocalAiApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="sk-mysecretkey"
|
||||
defaultValue={settings?.LocalAiApiKey ? "*".repeat(20) : ""}
|
||||
autoComplete="off"
|
||||
|
@ -128,7 +128,7 @@ export default function LocalAiOptions({ settings, showAlert = false }) {
|
|||
<input
|
||||
type="url"
|
||||
name="LocalAiBasePath"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://localhost:8080/v1"
|
||||
value={basePathValue.value}
|
||||
required={true}
|
||||
|
@ -176,7 +176,7 @@ function LocalAIModelSelection({ settings, basePath = null, apiKey = null }) {
|
|||
<select
|
||||
name="LocalAiModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
{basePath?.includes("/v1")
|
||||
|
@ -196,7 +196,7 @@ function LocalAIModelSelection({ settings, basePath = null, apiKey = null }) {
|
|||
<select
|
||||
name="LocalAiModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{customModels.length > 0 && (
|
||||
<optgroup label="Your loaded models">
|
||||
|
|
|
@ -14,7 +14,7 @@ export default function MistralOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="MistralApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Mistral API Key"
|
||||
defaultValue={settings?.MistralApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -62,7 +62,7 @@ function MistralModelSelection({ apiKey, settings }) {
|
|||
<select
|
||||
name="MistralModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
{!!apiKey
|
||||
|
@ -82,7 +82,7 @@ function MistralModelSelection({ apiKey, settings }) {
|
|||
<select
|
||||
name="MistralModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{customModels.length > 0 && (
|
||||
<optgroup label="Available Mistral Models">
|
||||
|
|
|
@ -43,7 +43,7 @@ function NativeModelSelection({ settings }) {
|
|||
<select
|
||||
name="NativeLLMModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
-- waiting for models --
|
||||
|
@ -62,7 +62,7 @@ function NativeModelSelection({ settings }) {
|
|||
<select
|
||||
name="NativeLLMModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
>
|
||||
{customModels.length > 0 && (
|
||||
<optgroup label="Your loaded models">
|
||||
|
@ -88,7 +88,7 @@ function NativeModelSelection({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="NativeLLMTokenLimit"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="4096"
|
||||
min={1}
|
||||
onScroll={(e) => e.target.blur()}
|
||||
|
|
|
@ -4,16 +4,16 @@ import { useState, useEffect } from "react";
|
|||
|
||||
export default function NovitaLLMOptions({ settings }) {
|
||||
return (
|
||||
<div className="flex flex-col gap-y-4 mt-1.5">
|
||||
<div className="flex gap-[36px]">
|
||||
<div className="w-full flex flex-col gap-y-7">
|
||||
<div className="w-full flex items-start gap-[36px] mt-1.5">
|
||||
<div className="flex flex-col w-60">
|
||||
<label className="text-white text-sm font-semibold block mb-3">
|
||||
<label className="text-theme-text-primary text-sm font-semibold block mb-3">
|
||||
Novita API Key
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="NovitaLLMApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Novita API Key"
|
||||
defaultValue={settings?.NovitaLLMApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -35,27 +35,29 @@ function AdvancedControls({ settings }) {
|
|||
|
||||
return (
|
||||
<div className="flex flex-col gap-y-4">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowAdvancedControls(!showAdvancedControls)}
|
||||
className="text-white hover:text-white/70 flex items-center text-sm"
|
||||
>
|
||||
{showAdvancedControls ? "Hide" : "Show"} advanced controls
|
||||
{showAdvancedControls ? (
|
||||
<CaretUp size={14} className="ml-1" />
|
||||
) : (
|
||||
<CaretDown size={14} className="ml-1" />
|
||||
)}
|
||||
</button>
|
||||
<div className="flex justify-start">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowAdvancedControls(!showAdvancedControls)}
|
||||
className="text-theme-text-primary hover:text-theme-text-secondary flex items-center text-sm"
|
||||
>
|
||||
{showAdvancedControls ? "Hide" : "Show"} advanced settings
|
||||
{showAdvancedControls ? (
|
||||
<CaretUp size={14} className="ml-1" />
|
||||
) : (
|
||||
<CaretDown size={14} className="ml-1" />
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
<div hidden={!showAdvancedControls}>
|
||||
<div className="flex flex-col w-60">
|
||||
<label className="text-white text-sm font-semibold block mb-3">
|
||||
<label className="text-theme-text-primary text-sm font-semibold block mb-3">
|
||||
Stream Timeout (ms)
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
name="NovitaLLMTimeout"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Timeout value between token responses to auto-timeout the stream"
|
||||
defaultValue={settings?.NovitaLLMTimeout ?? 500}
|
||||
autoComplete="off"
|
||||
|
@ -63,6 +65,9 @@ function AdvancedControls({ settings }) {
|
|||
min={500}
|
||||
step={1}
|
||||
/>
|
||||
<p className="text-xs leading-[18px] font-base text-theme-text-primary text-opacity-60 mt-2">
|
||||
Timeout value between token responses to auto-timeout the stream.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -83,10 +88,8 @@ function NovitaModelSelection({ settings }) {
|
|||
acc[model.organization].push(model);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
setGroupedModels(modelsByOrganization);
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
}
|
||||
findCustomModels();
|
||||
|
@ -95,13 +98,13 @@ function NovitaModelSelection({ settings }) {
|
|||
if (loading || Object.keys(groupedModels).length === 0) {
|
||||
return (
|
||||
<div className="flex flex-col w-60">
|
||||
<label className="text-white text-sm font-semibold block mb-3">
|
||||
<label className="text-theme-text-primary text-sm font-semibold block mb-3">
|
||||
Chat Model Selection
|
||||
</label>
|
||||
<select
|
||||
name="NovitaLLMModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-theme-text-primary border-theme-border text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
-- loading available models --
|
||||
|
@ -113,13 +116,13 @@ function NovitaModelSelection({ settings }) {
|
|||
|
||||
return (
|
||||
<div className="flex flex-col w-60">
|
||||
<label className="text-white text-sm font-semibold block mb-3">
|
||||
<label className="text-theme-text-primary text-sm font-semibold block mb-3">
|
||||
Chat Model Selection
|
||||
</label>
|
||||
<select
|
||||
name="NovitaLLMModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-theme-text-primary border-theme-border text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{Object.keys(groupedModels)
|
||||
.sort()
|
||||
|
|
|
@ -40,7 +40,7 @@ export default function OllamaLLMOptions({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="OllamaLLMTokenLimit"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="4096"
|
||||
defaultChecked="4096"
|
||||
min={1}
|
||||
|
@ -97,7 +97,7 @@ export default function OllamaLLMOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="OllamaLLMBasePath"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://127.0.0.1:11434"
|
||||
value={basePathValue.value}
|
||||
required={true}
|
||||
|
@ -118,7 +118,7 @@ export default function OllamaLLMOptions({ settings }) {
|
|||
<select
|
||||
name="OllamaLLMKeepAliveSeconds"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
defaultValue={settings?.OllamaLLMKeepAliveSeconds ?? "300"}
|
||||
>
|
||||
<option value="0">No cache</option>
|
||||
|
@ -153,7 +153,7 @@ export default function OllamaLLMOptions({ settings }) {
|
|||
<select
|
||||
name="OllamaLLMPerformanceMode"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
value={performanceMode}
|
||||
onChange={(e) => setPerformanceMode(e.target.value)}
|
||||
>
|
||||
|
@ -223,7 +223,7 @@ function OllamaLLMModelSelection({ settings, basePath = null }) {
|
|||
<select
|
||||
name="OllamaLLMModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
{!!basePath
|
||||
|
@ -247,7 +247,7 @@ function OllamaLLMModelSelection({ settings, basePath = null }) {
|
|||
<select
|
||||
name="OllamaLLMModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{customModels.length > 0 && (
|
||||
<optgroup label="Your loaded models">
|
||||
|
|
|
@ -14,7 +14,7 @@ export default function OpenAiOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="OpenAiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="OpenAI API Key"
|
||||
defaultValue={settings?.OpenAiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -66,7 +66,7 @@ function OpenAIModelSelection({ apiKey, settings }) {
|
|||
<select
|
||||
name="OpenAiModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
-- loading available models --
|
||||
|
@ -84,7 +84,7 @@ function OpenAIModelSelection({ apiKey, settings }) {
|
|||
<select
|
||||
name="OpenAiModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{Object.keys(groupedModels)
|
||||
.sort()
|
||||
|
|
|
@ -13,7 +13,7 @@ export default function OpenRouterOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="OpenRouterApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="OpenRouter API Key"
|
||||
defaultValue={settings?.OpenRouterApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -55,7 +55,7 @@ function AdvancedControls({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="OpenRouterTimeout"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Timeout value between token responses to auto-timeout the stream"
|
||||
defaultValue={settings?.OpenRouterTimeout ?? 500}
|
||||
autoComplete="off"
|
||||
|
@ -101,7 +101,7 @@ function OpenRouterModelSelection({ settings }) {
|
|||
<select
|
||||
name="OpenRouterModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
-- loading available models --
|
||||
|
@ -119,7 +119,7 @@ function OpenRouterModelSelection({ settings }) {
|
|||
<select
|
||||
name="OpenRouterModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{Object.keys(groupedModels)
|
||||
.sort()
|
||||
|
|
|
@ -11,7 +11,7 @@ export default function PerplexityOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="PerplexityApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Perplexity API Key"
|
||||
defaultValue={settings?.PerplexityApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -49,7 +49,7 @@ function PerplexityModelSelection({ settings }) {
|
|||
<select
|
||||
name="PerplexityModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
-- loading available models --
|
||||
|
@ -67,7 +67,7 @@ function PerplexityModelSelection({ settings }) {
|
|||
<select
|
||||
name="PerplexityModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{customModels.length > 0 && (
|
||||
<optgroup label="Available Perplexity Models">
|
||||
|
|
|
@ -8,7 +8,7 @@ export default function TextGenWebUIOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="TextGenWebUIBasePath"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://127.0.0.1:5000/v1"
|
||||
defaultValue={settings?.TextGenWebUIBasePath}
|
||||
required={true}
|
||||
|
@ -23,7 +23,7 @@ export default function TextGenWebUIOptions({ settings }) {
|
|||
<input
|
||||
type="number"
|
||||
name="TextGenWebUITokenLimit"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Content window limit (eg: 4096)"
|
||||
min={1}
|
||||
onScroll={(e) => e.target.blur()}
|
||||
|
@ -39,7 +39,7 @@ export default function TextGenWebUIOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="TextGenWebUIAPIKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="TextGen Web UI API Key"
|
||||
defaultValue={settings?.TextGenWebUIAPIKey ? "*".repeat(20) : ""}
|
||||
autoComplete="off"
|
||||
|
|
|
@ -11,7 +11,7 @@ export default function TogetherAiOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="TogetherAiApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Together AI API Key"
|
||||
defaultValue={settings?.TogetherAiApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -58,7 +58,7 @@ function TogetherAiModelSelection({ settings }) {
|
|||
<select
|
||||
name="TogetherAiModelPref"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
-- loading available models --
|
||||
|
@ -76,7 +76,7 @@ function TogetherAiModelSelection({ settings }) {
|
|||
<select
|
||||
name="TogetherAiModelPref"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{Object.keys(groupedModels)
|
||||
.sort()
|
||||
|
|
|
@ -14,7 +14,7 @@ export default function XAILLMOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="XAIApiKey"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="xAI API Key"
|
||||
defaultValue={settings?.XAIApiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -61,19 +61,19 @@ function XAIModelSelection({ apiKey, settings }) {
|
|||
if (loading) {
|
||||
return (
|
||||
<div className="flex flex-col w-60">
|
||||
<label className="text-white text-sm font-semibold block mb-3">
|
||||
<label className="text-theme-text-primary text-sm font-semibold block mb-3">
|
||||
Chat Model Selection
|
||||
</label>
|
||||
<select
|
||||
name="XAIModelPref"
|
||||
disabled={true}
|
||||
className="border-none bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-theme-text-primary border-theme-border text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
--loading available models--
|
||||
</option>
|
||||
</select>
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60 mt-2">
|
||||
<p className="text-xs leading-[18px] font-base text-theme-text-primary opacity-60 mt-2">
|
||||
Enter a valid API key to view all available models for your account.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -82,13 +82,13 @@ function XAIModelSelection({ apiKey, settings }) {
|
|||
|
||||
return (
|
||||
<div className="flex flex-col w-60">
|
||||
<label className="text-white text-sm font-semibold block mb-3">
|
||||
<label className="text-theme-text-primary text-sm font-semibold block mb-3">
|
||||
Chat Model Selection
|
||||
</label>
|
||||
<select
|
||||
name="XAIModelPref"
|
||||
required={true}
|
||||
className="border-none bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-theme-text-primary border-theme-border text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{customModels.length > 0 && (
|
||||
<optgroup label="Available models">
|
||||
|
@ -106,7 +106,7 @@ function XAIModelSelection({ apiKey, settings }) {
|
|||
</optgroup>
|
||||
)}
|
||||
</select>
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60 mt-2">
|
||||
<p className="text-xs leading-[18px] font-base text-theme-text-primary opacity-60 mt-2">
|
||||
Select the xAI model you want to use for your conversations.
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { createPortal } from "react-dom";
|
||||
/**
|
||||
* @typedef {Object} ModalWrapperProps
|
||||
* @property {import("react").ReactComponentElement} children - The DOM/JSX to render
|
||||
* @property {import("react").ReactComponentElement} children - The DOM/JSX to render
|
||||
* @property {boolean} isOpen - Option that renders the modal
|
||||
* @property {boolean} noPortal - (default: false) Used for creating sub-DOM modals that need to be rendered as a child element instead of a modal placed at the root
|
||||
* Note: This can impact the bg-overlay presentation due to conflicting DOM positions so if using this property you should
|
||||
|
@ -17,14 +17,14 @@ export default function ModalWrapper({ children, isOpen, noPortal = false }) {
|
|||
|
||||
if (noPortal) {
|
||||
return (
|
||||
<div className="bg-black/60 backdrop-blur-sm fixed top-0 left-0 outline-none w-screen h-screen flex items-center justify-center z-30">
|
||||
<div className="bg-black/60 backdrop-blur-sm fixed top-0 left-0 outline-none w-screen h-screen flex items-center justify-center z-99">
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return createPortal(
|
||||
<div className="bg-black/60 backdrop-blur-sm fixed top-0 left-0 outline-none w-screen h-screen flex items-center justify-center z-30">
|
||||
<div className="bg-black/60 backdrop-blur-sm fixed top-0 left-0 outline-none w-screen h-screen flex items-center justify-center z-99">
|
||||
{children}
|
||||
</div>,
|
||||
document.getElementById("root")
|
||||
|
|
|
@ -2,6 +2,7 @@ import showToast from "@/utils/toast";
|
|||
import { DownloadSimple, Key } from "@phosphor-icons/react";
|
||||
import { saveAs } from "file-saver";
|
||||
import { useState } from "react";
|
||||
import ModalWrapper from "@/components/ModalWrapper";
|
||||
|
||||
export default function RecoveryCodeModal({
|
||||
recoveryCodes,
|
||||
|
@ -32,55 +33,59 @@ export default function RecoveryCodeModal({
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="inline-block bg-secondary rounded-lg text-left overflow-hidden shadow-xl transform transition-all border-2 border-[#BCC9DB]/10 w-[600px] mx-4">
|
||||
<div className="md:py-[35px] md:px-[50px] py-[28px] px-[20px]">
|
||||
<div className="flex gap-x-2">
|
||||
<Key size={24} className="text-white" weight="bold" />
|
||||
<h3
|
||||
className="text-lg leading-6 font-medium text-white"
|
||||
id="modal-headline"
|
||||
>
|
||||
Recovery Codes
|
||||
</h3>
|
||||
<ModalWrapper isOpen={true}>
|
||||
<div className="w-full max-w-2xl bg-theme-bg-secondary rounded-lg shadow border-2 border-theme-modal-border overflow-hidden">
|
||||
<div className="relative p-6 border-b rounded-t border-theme-modal-border">
|
||||
<div className="w-full flex gap-x-2 items-center">
|
||||
<Key size={24} className="text-white" weight="bold" />
|
||||
<h3 className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap">
|
||||
Recovery Codes
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<p className="text-sm text-white flex flex-col">
|
||||
In order to reset your password in the future, you will need these
|
||||
recovery codes. Download or copy your recovery codes to save them.{" "}
|
||||
<br />
|
||||
<b className="mt-4">These recovery codes are only shown once!</b>
|
||||
</p>
|
||||
<div
|
||||
className="bg-dark-highlight text-white hover:text-primary-button
|
||||
flex items-center justify-center rounded-md mt-6 cursor-pointer"
|
||||
onClick={handleCopyToClipboard}
|
||||
>
|
||||
<ul className="space-y-2 md:p-6 p-4">
|
||||
{recoveryCodes.map((code, index) => (
|
||||
<li key={index} className="md:text-sm text-xs">
|
||||
{code}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div
|
||||
className="h-full w-full overflow-y-auto"
|
||||
style={{ maxHeight: "calc(100vh - 200px)" }}
|
||||
>
|
||||
<div className="py-7 px-9 space-y-2 flex-col">
|
||||
<p className="text-sm text-white flex flex-col">
|
||||
In order to reset your password in the future, you will need these
|
||||
recovery codes. Download or copy your recovery codes to save them.{" "}
|
||||
<br />
|
||||
<b className="mt-4">These recovery codes are only shown once!</b>
|
||||
</p>
|
||||
<div
|
||||
className="bg-theme-settings-input-bg text-white hover:text-primary-button
|
||||
flex items-center justify-center rounded-md mt-6 cursor-pointer"
|
||||
onClick={handleCopyToClipboard}
|
||||
>
|
||||
<ul className="space-y-2 md:p-6 p-4">
|
||||
{recoveryCodes.map((code, index) => (
|
||||
<li key={index} className="md:text-sm text-xs">
|
||||
{code}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-full justify-end items-center p-6 space-x-2 border-t border-theme-modal-border rounded-b">
|
||||
<button
|
||||
type="button"
|
||||
className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm flex items-center gap-x-2"
|
||||
onClick={downloadClicked ? handleClose : downloadRecoveryCodes}
|
||||
>
|
||||
{downloadClicked ? (
|
||||
"Close"
|
||||
) : (
|
||||
<>
|
||||
<DownloadSimple weight="bold" size={18} />
|
||||
<p>Download</p>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-full justify-center items-center p-3 space-x-2 rounded-b border-gray-500/50 -mt-4 mb-4">
|
||||
<button
|
||||
type="button"
|
||||
className="transition-all duration-300 text-xs md:w-[500px] md:h-[34px] h-[48px] w-full m-2 font-semibold rounded-lg bg-primary-button hover:bg-secondary border-2 border-transparent hover:border-primary-button hover:text-white whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)] flex justify-center items-center gap-x-2"
|
||||
onClick={downloadClicked ? handleClose : downloadRecoveryCodes}
|
||||
>
|
||||
{downloadClicked ? (
|
||||
"Close"
|
||||
) : (
|
||||
<>
|
||||
<DownloadSimple weight="bold" size={18} />
|
||||
<p>Download</p>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ export default function ConnectorOption({
|
|||
return (
|
||||
<button
|
||||
onClick={() => setSelectedConnector(slug)}
|
||||
className={`flex text-left gap-x-3.5 items-center py-2 px-4 hover:bg-white/10 ${
|
||||
selectedConnector === slug ? "bg-white/10" : ""
|
||||
className={`flex text-left gap-x-3.5 items-center py-2 px-4 hover:bg-theme-file-picker-hover ${
|
||||
selectedConnector === slug ? "bg-theme-file-picker-hover" : ""
|
||||
} rounded-lg cursor-pointer w-full`}
|
||||
>
|
||||
<img src={image} alt={name} className="w-[40px] h-[40px] rounded-md" />
|
||||
|
|
|
@ -58,18 +58,18 @@ export default function ConfluenceOptions() {
|
|||
<div className="flex flex-col pr-10">
|
||||
<div className="flex flex-col gap-y-1 mb-4">
|
||||
<label className="text-white text-sm font-bold flex gap-x-2 items-center">
|
||||
<p className="font-bold text-white">
|
||||
<p className="font-bold text-theme-text-primary">
|
||||
Confluence deployment type
|
||||
</p>
|
||||
</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
Determine if your Confluence instance is hosted on Atlassian
|
||||
cloud or self-hosted.
|
||||
</p>
|
||||
</div>
|
||||
<select
|
||||
name="isCloud"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
spellCheck={false}
|
||||
|
@ -85,14 +85,14 @@ export default function ConfluenceOptions() {
|
|||
<label className="text-white text-sm font-bold flex gap-x-2 items-center">
|
||||
<p className="font-bold text-white">Confluence base URL</p>
|
||||
</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
This is the base URL of your Confluence space.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
type="url"
|
||||
name="baseUrl"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="eg: https://example.atlassian.net, http://localhost:8211, etc..."
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
|
@ -104,7 +104,7 @@ export default function ConfluenceOptions() {
|
|||
<label className="text-white text-sm font-bold">
|
||||
Confluence space key
|
||||
</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
This is the spaces key of your confluence instance that will
|
||||
be used. Usually begins with ~
|
||||
</p>
|
||||
|
@ -112,7 +112,7 @@ export default function ConfluenceOptions() {
|
|||
<input
|
||||
type="text"
|
||||
name="spaceKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="eg: ~7120208c08555d52224113949698b933a3bb56"
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
|
@ -124,14 +124,14 @@ export default function ConfluenceOptions() {
|
|||
<label className="text-white text-sm font-bold">
|
||||
Confluence Username
|
||||
</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
Your Confluence username.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
name="username"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="jdoe@example.com"
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
|
@ -153,7 +153,7 @@ export default function ConfluenceOptions() {
|
|||
<Tooltip
|
||||
delayHide={300}
|
||||
id="access-token-tooltip"
|
||||
className="max-w-xs"
|
||||
className="max-w-xs z-99"
|
||||
clickable={true}
|
||||
>
|
||||
<p className="text-sm">
|
||||
|
@ -172,14 +172,14 @@ export default function ConfluenceOptions() {
|
|||
</p>
|
||||
</Tooltip>
|
||||
</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
Access token for authentication.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
type="password"
|
||||
name="accessToken"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="abcd1234"
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
|
@ -198,7 +198,7 @@ export default function ConfluenceOptions() {
|
|||
{loading ? "Collecting pages..." : "Submit"}
|
||||
</button>
|
||||
{loading && (
|
||||
<p className="text-xs text-white/50">
|
||||
<p className="text-xs text-theme-text-secondary">
|
||||
Once complete, all pages will be available for embedding into
|
||||
workspaces.
|
||||
</p>
|
||||
|
|
|
@ -70,14 +70,14 @@ export default function GithubOptions() {
|
|||
<label className="text-white text-sm font-bold">
|
||||
GitHub Repo URL
|
||||
</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
Url of the GitHub repo you wish to collect.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
type="url"
|
||||
name="repo"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="https://github.com/Mintplex-Labs/anything-llm"
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
|
@ -90,19 +90,21 @@ export default function GithubOptions() {
|
|||
<div className="flex flex-col gap-y-1 mb-4">
|
||||
<label className="text-white font-bold text-sm flex gap-x-2 items-center">
|
||||
<p className="font-bold text-white">Github Access Token</p>{" "}
|
||||
<p className="text-xs text-white/50 font-light flex items-center">
|
||||
optional
|
||||
<p className="text-xs font-light flex items-center">
|
||||
<span className="text-theme-text-secondary">
|
||||
optional
|
||||
</span>
|
||||
<PATTooltip accessToken={accessToken} />
|
||||
</p>
|
||||
</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
Access Token to prevent rate limiting.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
name="accessToken"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="github_pat_1234_abcdefg"
|
||||
required={false}
|
||||
autoComplete="off"
|
||||
|
@ -122,7 +124,7 @@ export default function GithubOptions() {
|
|||
<label className="text-white text-sm flex gap-x-2 items-center">
|
||||
<p className="text-white text-sm font-bold">File Ignores</p>
|
||||
</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
List in .gitignore format to ignore specific files during
|
||||
collection. Press enter after each entry you want to save.
|
||||
</p>
|
||||
|
@ -133,9 +135,9 @@ export default function GithubOptions() {
|
|||
name="ignores"
|
||||
placeholder="!*.js, images/*, .DS_Store, bin/*"
|
||||
classNames={{
|
||||
tag: "bg-blue-300/10 text-zinc-800",
|
||||
tag: "bg-theme-settings-input-bg light:bg-black/10 bg-blue-300/10 text-zinc-800",
|
||||
input:
|
||||
"flex bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none",
|
||||
"flex p-1 !bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
@ -191,14 +193,14 @@ function GitHubBranchSelection({ repo, accessToken }) {
|
|||
<div className="flex flex-col w-60">
|
||||
<div className="flex flex-col gap-y-1 mb-4">
|
||||
<label className="text-white text-sm font-bold">Branch</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
Branch you wish to collect files from.
|
||||
</p>
|
||||
</div>
|
||||
<select
|
||||
name="branch"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
-- loading available branches --
|
||||
|
@ -212,14 +214,14 @@ function GitHubBranchSelection({ repo, accessToken }) {
|
|||
<div className="flex flex-col w-60">
|
||||
<div className="flex flex-col gap-y-1 mb-4">
|
||||
<label className="text-white text-sm font-bold">Branch</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
Branch you wish to collect files from.
|
||||
</p>
|
||||
</div>
|
||||
<select
|
||||
name="branch"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{allBranches.map((branch) => {
|
||||
return (
|
||||
|
@ -276,7 +278,7 @@ function PATTooltip({ accessToken }) {
|
|||
<Tooltip
|
||||
delayHide={300}
|
||||
id="access-token-tooltip"
|
||||
className="max-w-xs"
|
||||
className="max-w-xs z-99"
|
||||
clickable={true}
|
||||
>
|
||||
<p className="text-sm">
|
||||
|
|
|
@ -24,11 +24,10 @@ export default function GitlabOptions() {
|
|||
try {
|
||||
setLoading(true);
|
||||
showToast(
|
||||
`Fetching all files for repo ${repo} - this may take a while.`,
|
||||
"Fetching all files for repo - this may take a while.",
|
||||
"info",
|
||||
{ clear: true, autoClose: false }
|
||||
);
|
||||
|
||||
const { data, error } = await System.dataConnectors.gitlab.collect({
|
||||
repo: form.get("repo"),
|
||||
accessToken: form.get("accessToken"),
|
||||
|
@ -71,40 +70,41 @@ export default function GitlabOptions() {
|
|||
<label className="text-white text-sm font-bold">
|
||||
GitLab Repo URL
|
||||
</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
URL of the GitLab repo you wish to collect.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
type="url"
|
||||
name="repo"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="https://gitlab.com/gitlab-org/gitlab"
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
onChange={(e) => setRepo(e.target.value)}
|
||||
onBlur={() => setSettings({ ...settings, repo })}
|
||||
spellCheck={false}
|
||||
rows={2}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col pr-10">
|
||||
<div className="flex flex-col gap-y-1 mb-4">
|
||||
<label className="text-white font-bold text-sm flex gap-x-2 items-center">
|
||||
<p className="font-bold text-white">GitLab Access Token</p>{" "}
|
||||
<p className="text-xs text-white/50 font-light flex items-center">
|
||||
optional
|
||||
<p className="text-xs font-light flex items-center">
|
||||
<span className="text-theme-text-secondary">
|
||||
optional
|
||||
</span>
|
||||
<PATTooltip accessToken={accessToken} />
|
||||
</p>
|
||||
</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
Access Token to prevent rate limiting.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
name="accessToken"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="glpat-XXXXXXXXXXXXXXXXXXXX"
|
||||
required={false}
|
||||
autoComplete="off"
|
||||
|
@ -148,7 +148,7 @@ export default function GitlabOptions() {
|
|||
<label className="text-white text-sm flex gap-x-2 items-center">
|
||||
<p className="text-white text-sm font-bold">File Ignores</p>
|
||||
</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
List in .gitignore format to ignore specific files during
|
||||
collection. Press enter after each entry you want to save.
|
||||
</p>
|
||||
|
@ -159,9 +159,9 @@ export default function GitlabOptions() {
|
|||
name="ignores"
|
||||
placeholder="!*.js, images/*, .DS_Store, bin/*"
|
||||
classNames={{
|
||||
tag: "bg-blue-300/10 text-zinc-800",
|
||||
tag: "bg-theme-settings-input-bg light:bg-black/10 bg-blue-300/10 text-zinc-800",
|
||||
input:
|
||||
"flex bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:border-white",
|
||||
"flex p-1 !bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
@ -217,14 +217,14 @@ function GitLabBranchSelection({ repo, accessToken }) {
|
|||
<div className="flex flex-col w-60">
|
||||
<div className="flex flex-col gap-y-1 mb-4">
|
||||
<label className="text-white text-sm font-bold">Branch</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
Branch you wish to collect files from.
|
||||
</p>
|
||||
</div>
|
||||
<select
|
||||
name="branch"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
-- loading available branches --
|
||||
|
@ -238,14 +238,14 @@ function GitLabBranchSelection({ repo, accessToken }) {
|
|||
<div className="flex flex-col w-60">
|
||||
<div className="flex flex-col gap-y-1 mb-4">
|
||||
<label className="text-white text-sm font-bold">Branch</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
Branch you wish to collect files from.
|
||||
</p>
|
||||
</div>
|
||||
<select
|
||||
name="branch"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{allBranches.map((branch) => {
|
||||
return (
|
||||
|
@ -302,7 +302,7 @@ function PATTooltip({ accessToken }) {
|
|||
<Tooltip
|
||||
delayHide={300}
|
||||
id="access-token-tooltip"
|
||||
className="max-w-xs"
|
||||
className="max-w-xs z-99"
|
||||
clickable={true}
|
||||
>
|
||||
<p className="text-sm">
|
||||
|
|
|
@ -57,14 +57,14 @@ export default function WebsiteDepthOptions() {
|
|||
<label className="text-white text-sm font-bold">
|
||||
Website URL
|
||||
</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
URL of the website you want to scrape.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
type="url"
|
||||
name="url"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="https://example.com"
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
|
@ -74,7 +74,7 @@ export default function WebsiteDepthOptions() {
|
|||
<div className="flex flex-col pr-10">
|
||||
<div className="flex flex-col gap-y-1 mb-4">
|
||||
<label className="text-white text-sm font-bold">Depth</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
This is the number of child-links that the worker should
|
||||
follow from the origin URL.
|
||||
</p>
|
||||
|
@ -84,7 +84,7 @@ export default function WebsiteDepthOptions() {
|
|||
name="depth"
|
||||
min="1"
|
||||
max="5"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
required={true}
|
||||
defaultValue="1"
|
||||
/>
|
||||
|
@ -94,7 +94,7 @@ export default function WebsiteDepthOptions() {
|
|||
<label className="text-white text-sm font-bold">
|
||||
Max Links
|
||||
</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
Maximum number of links to scrape.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -102,7 +102,7 @@ export default function WebsiteDepthOptions() {
|
|||
type="number"
|
||||
name="maxLinks"
|
||||
min="1"
|
||||
className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
required={true}
|
||||
defaultValue="20"
|
||||
/>
|
||||
|
@ -121,7 +121,7 @@ export default function WebsiteDepthOptions() {
|
|||
{loading ? "Scraping website..." : "Submit"}
|
||||
</button>
|
||||
{loading && (
|
||||
<p className="text-xs text-white/50">
|
||||
<p className="text-xs text-theme-text-secondary">
|
||||
Once complete, all scraped pages will be available for embedding
|
||||
into workspaces in the document picker.
|
||||
</p>
|
||||
|
|
|
@ -52,14 +52,14 @@ export default function YoutubeOptions() {
|
|||
<label className="text-white text-sm font-bold">
|
||||
YouTube Video URL
|
||||
</label>
|
||||
<p className="text-xs font-normal text-white/50">
|
||||
<p className="text-xs font-normal text-theme-text-secondary">
|
||||
URL of the YouTube video you wish to transcribe.
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
type="url"
|
||||
name="url"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="https://youtube.com/watch?v=abc123"
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
|
@ -78,7 +78,7 @@ export default function YoutubeOptions() {
|
|||
{loading ? "Collecting transcript..." : "Collect transcript"}
|
||||
</button>
|
||||
{loading && (
|
||||
<p className="text-xs text-white/50 max-w-sm">
|
||||
<p className="text-xs text-theme-text-secondary max-w-sm">
|
||||
Once complete, the transcription will be available for embedding
|
||||
into workspaces in the document picker.
|
||||
</p>
|
||||
|
|
|
@ -64,7 +64,7 @@ export default function DataConnectors() {
|
|||
<input
|
||||
type="text"
|
||||
placeholder="Search data connectors"
|
||||
className="border-none bg-zinc-600 z-20 pl-10 h-[38px] rounded-full w-full px-4 py-1 text-sm border-2 border-slate-300/40 outline-none focus:outline-primary-button active:outline-primary-button outline-none text-white"
|
||||
className="border-none z-20 pl-10 h-[38px] rounded-full w-full px-4 py-1 text-sm border-2 border-slate-300/40 outline-none focus:outline-primary-button active:outline-primary-button outline-none placeholder:text-theme-settings-input-placeholder text-white bg-theme-settings-input-bg"
|
||||
autoComplete="off"
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
|
|
|
@ -60,17 +60,17 @@ export default function ContextMenu({
|
|||
left: `${contextMenu.x}px`,
|
||||
zIndex: 1000,
|
||||
}}
|
||||
className="bg-zinc-800 border border-zinc-700 rounded-md shadow-lg"
|
||||
className="bg-theme-bg-secondary border border-theme-modal-border rounded-md shadow-lg"
|
||||
>
|
||||
<button
|
||||
onClick={toggleSelectAll}
|
||||
className="block w-full text-left px-4 py-2 text-sm text-white hover:bg-zinc-700"
|
||||
className="block w-full text-left px-4 py-2 text-sm text-theme-text-primary hover:bg-theme-file-picker-hover"
|
||||
>
|
||||
{isAllSelected() ? "Unselect All" : "Select All"}
|
||||
</button>
|
||||
<button
|
||||
onClick={closeContextMenu}
|
||||
className="block w-full text-left px-4 py-2 text-sm text-white hover:bg-zinc-700"
|
||||
className="block w-full text-left px-4 py-2 text-sm text-theme-text-primary hover:bg-theme-file-picker-hover"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
|
|
|
@ -10,8 +10,8 @@ export default function FileRow({ item, selected, toggleSelection }) {
|
|||
return (
|
||||
<tr
|
||||
onClick={() => toggleSelection(item)}
|
||||
className={`text-white/80 text-xs grid grid-cols-12 py-2 pl-3.5 pr-8 hover:bg-sky-500/20 cursor-pointer file-row ${
|
||||
selected ? "selected" : ""
|
||||
className={`text-theme-text-primary text-xs grid grid-cols-12 py-2 pl-3.5 pr-8 hover:bg-theme-file-picker-hover cursor-pointer file-row ${
|
||||
selected ? "selected light:text-white" : ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
|
@ -24,7 +24,9 @@ export default function FileRow({ item, selected, toggleSelection }) {
|
|||
})}
|
||||
>
|
||||
<div
|
||||
className="shrink-0 w-3 h-3 rounded border-[1px] border-white flex justify-center items-center cursor-pointer"
|
||||
className={`shrink-0 w-3 h-3 rounded border-[1px] border-white ${
|
||||
selected ? "text-white" : "text-theme-text-primary light:invert"
|
||||
} flex justify-center items-center cursor-pointer`}
|
||||
role="checkbox"
|
||||
aria-checked={selected}
|
||||
tabIndex={0}
|
||||
|
@ -41,7 +43,7 @@ export default function FileRow({ item, selected, toggleSelection }) {
|
|||
</div>
|
||||
<div className="col-span-2 flex justify-end items-center">
|
||||
{item?.cached && (
|
||||
<div className="bg-white/10 rounded-3xl">
|
||||
<div className="bg-theme-settings-input-active rounded-3xl">
|
||||
<p className="text-xs px-2 py-0.5">Cached</p>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -22,13 +22,19 @@ export default function FolderRow({
|
|||
<>
|
||||
<tr
|
||||
onClick={onRowClick}
|
||||
className={`text-white/80 text-xs grid grid-cols-12 py-2 pl-3.5 pr-8 bg-dark-highlight hover:bg-sky-500/20 cursor-pointer w-full file-row ${
|
||||
selected ? "selected" : ""
|
||||
className={`text-theme-text-primary text-xs grid grid-cols-12 py-2 pl-3.5 pr-8 hover:bg-theme-file-picker-hover cursor-pointer file-row ${
|
||||
selected ? "selected light:text-white !text-white" : ""
|
||||
}`}
|
||||
>
|
||||
<div className="col-span-6 flex gap-x-[4px] items-center">
|
||||
<div
|
||||
className={`col-span-6 flex gap-x-[4px] items-center ${
|
||||
selected ? "!text-white" : "text-theme-text-primary"
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className="shrink-0 w-3 h-3 rounded border-[1px] border-white flex justify-center items-center cursor-pointer"
|
||||
className={`shrink-0 w-3 h-3 rounded border-[1px] border-white ${
|
||||
selected ? "text-white" : "text-theme-text-primary light:invert"
|
||||
} flex justify-center items-center cursor-pointer`}
|
||||
role="checkbox"
|
||||
aria-checked={selected}
|
||||
tabIndex={0}
|
||||
|
|
|
@ -29,24 +29,25 @@ export default function NewFolderModal({ closeModal, files, setFiles }) {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="relative w-full max-w-xl max-h-full">
|
||||
<div className="relative bg-main-gradient rounded-lg shadow">
|
||||
<div className="flex items-start justify-between p-4 border-b rounded-t border-gray-500/50">
|
||||
<h3 className="text-xl font-semibold text-white">
|
||||
Create New Folder
|
||||
</h3>
|
||||
<div className="fixed inset-0 z-50 overflow-auto bg-black bg-opacity-50 flex items-center justify-center">
|
||||
<div className="relative w-full max-w-2xl bg-theme-bg-secondary rounded-lg shadow border-2 border-theme-modal-border">
|
||||
<div className="relative p-6 border-b rounded-t border-theme-modal-border">
|
||||
<div className="w-full flex gap-x-2 items-center">
|
||||
<h3 className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap">
|
||||
Create New Folder
|
||||
</h3>
|
||||
</div>
|
||||
<button
|
||||
onClick={closeModal}
|
||||
type="button"
|
||||
className="transition-all duration-300 text-gray-400 bg-transparent hover:border-white/60 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
data-modal-hide="staticModal"
|
||||
className="absolute top-4 right-4 transition-all duration-300 bg-transparent rounded-lg text-sm p-1 inline-flex items-center hover:bg-theme-modal-border hover:border-theme-modal-border hover:border-opacity-50 border-transparent border"
|
||||
>
|
||||
<X className="text-gray-300 text-lg" />
|
||||
<X size={24} weight="bold" className="text-white" />
|
||||
</button>
|
||||
</div>
|
||||
<form onSubmit={handleCreate}>
|
||||
<div className="p-6 space-y-6 flex h-full w-full">
|
||||
<div className="w-full flex flex-col gap-y-4">
|
||||
<div className="p-6">
|
||||
<form onSubmit={handleCreate}>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<label
|
||||
htmlFor="folderName"
|
||||
|
@ -57,7 +58,7 @@ export default function NewFolderModal({ closeModal, files, setFiles }) {
|
|||
<input
|
||||
name="folderName"
|
||||
type="text"
|
||||
className="bg-zinc-900 placeholder:text-white/20 border-gray-500 text-white text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg w-full text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Enter folder name"
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
|
@ -67,23 +68,23 @@ export default function NewFolderModal({ closeModal, files, setFiles }) {
|
|||
</div>
|
||||
{error && <p className="text-red-400 text-sm">Error: {error}</p>}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-full justify-between items-center p-6 space-x-2 border-t rounded-b border-gray-500/50">
|
||||
<button
|
||||
onClick={closeModal}
|
||||
type="button"
|
||||
className="px-4 py-2 rounded-lg text-white hover:bg-stone-900 transition-all duration-300"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="transition-all duration-300 border border-slate-200 px-4 py-2 rounded-lg text-white text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800 focus:ring-gray-800"
|
||||
>
|
||||
Create Folder
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div className="flex justify-between items-center mt-6 pt-6 border-t border-theme-modal-border">
|
||||
<button
|
||||
onClick={closeModal}
|
||||
type="button"
|
||||
className="transition-all duration-300 text-white hover:bg-zinc-700 px-4 py-2 rounded-lg text-sm"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm"
|
||||
>
|
||||
Create Folder
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -200,7 +200,7 @@ function Directory({
|
|||
type="search"
|
||||
placeholder="Search for document"
|
||||
onChange={handleSearch}
|
||||
className="search-input bg-zinc-900 text-white placeholder-white/40 text-sm rounded-lg pl-9 pr-2.5 py-2 w-[250px] h-[32px]"
|
||||
className="search-input bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-lg pl-9 pr-2.5 py-2 w-[250px] h-[32px] light:border-theme-modal-border light:border"
|
||||
/>
|
||||
<MagnifyingGlass
|
||||
size={14}
|
||||
|
@ -209,18 +209,22 @@ function Directory({
|
|||
/>
|
||||
</div>
|
||||
<button
|
||||
className="flex items-center gap-x-2 cursor-pointer px-[14px] py-[7px] -mr-[14px] rounded-lg hover:bg-[#222628]/60 z-20 relative"
|
||||
className="flex items-center gap-x-2 cursor-pointer px-[14px] py-[7px] -mr-[14px] rounded-lg hover:bg-theme-sidebar-subitem-hover z-20 relative"
|
||||
onClick={openFolderModal}
|
||||
>
|
||||
<Plus size={18} weight="bold" color="#D3D4D4" />
|
||||
<div className="text-[#D3D4D4] text-xs font-bold leading-[18px]">
|
||||
<Plus
|
||||
size={18}
|
||||
weight="bold"
|
||||
className="text-theme-text-primary light:text-[#0ba5ec]"
|
||||
/>
|
||||
<div className="text-theme-text-primary light:text-[#0ba5ec] text-xs font-bold leading-[18px]">
|
||||
New Folder
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="relative w-[560px] h-[310px] bg-zinc-900 rounded-2xl overflow-hidden">
|
||||
<div className="absolute top-0 left-0 right-0 z-10 rounded-t-2xl text-white/80 text-xs grid grid-cols-12 py-2 px-8 border-b border-white/20 shadow-lg bg-zinc-900">
|
||||
<div className="relative w-[560px] h-[310px] bg-theme-settings-input-bg rounded-2xl overflow-hidden border border-theme-modal-border">
|
||||
<div className="absolute top-0 left-0 right-0 z-10 rounded-t-2xl text-theme-text-primary text-xs grid grid-cols-12 py-2 px-8 border-b border-white/20 shadow-md bg-theme-settings-input-bg">
|
||||
<p className="col-span-6">Name</p>
|
||||
</div>
|
||||
|
||||
|
@ -228,7 +232,7 @@ function Directory({
|
|||
{loading ? (
|
||||
<div className="w-full h-full flex items-center justify-center flex-col gap-y-5">
|
||||
<PreLoader />
|
||||
<p className="text-white/80 text-sm font-semibold animate-pulse text-center w-1/3">
|
||||
<p className="text-white text-sm font-semibold animate-pulse text-center w-1/3">
|
||||
{loadingMessage}
|
||||
</p>
|
||||
</div>
|
||||
|
@ -260,13 +264,13 @@ function Directory({
|
|||
</div>
|
||||
{amountSelected !== 0 && (
|
||||
<div className="absolute bottom-[12px] left-0 right-0 flex justify-center pointer-events-none">
|
||||
<div className="mx-auto bg-white/40 rounded-lg py-1 px-2 pointer-events-auto">
|
||||
<div className="mx-auto bg-white/40 light:bg-white rounded-lg py-1 px-2 pointer-events-auto light:shadow-lg">
|
||||
<div className="flex flex-row items-center gap-x-2">
|
||||
<button
|
||||
onClick={moveToWorkspace}
|
||||
onMouseEnter={() => setHighlightWorkspace(true)}
|
||||
onMouseLeave={() => setHighlightWorkspace(false)}
|
||||
className="border-none text-sm font-semibold bg-white h-[30px] px-2.5 rounded-lg hover:text-white hover:bg-neutral-800/80"
|
||||
className="border-none text-sm font-semibold bg-white light:bg-[#E0F2FE] h-[30px] px-2.5 rounded-lg hover:bg-neutral-800/80 hover:text-white light:text-[#026AA2] light:hover:bg-[#026AA2] light:hover:text-white"
|
||||
>
|
||||
Move to Workspace
|
||||
</button>
|
||||
|
@ -275,9 +279,9 @@ function Directory({
|
|||
onClick={() =>
|
||||
setShowFolderSelection(!showFolderSelection)
|
||||
}
|
||||
className="border-none text-sm font-semibold bg-white h-[32px] w-[32px] rounded-lg text-dark-text hover:bg-neutral-800/80 flex justify-center items-center group"
|
||||
className="border-none text-sm font-semibold bg-white light:bg-[#E0F2FE] h-[32px] w-[32px] rounded-lg text-dark-text hover:bg-neutral-800/80 hover:text-white light:text-[#026AA2] light:hover:bg-[#026AA2] light:hover:text-white flex justify-center items-center group"
|
||||
>
|
||||
<MoveToFolderIcon className="text-dark-text group-hover:text-white" />
|
||||
<MoveToFolderIcon className="text-dark-text light:text-[#026AA2] group-hover:text-white" />
|
||||
</button>
|
||||
{showFolderSelection && (
|
||||
<FolderSelectionPopup
|
||||
|
@ -291,7 +295,7 @@ function Directory({
|
|||
</div>
|
||||
<button
|
||||
onClick={deleteFiles}
|
||||
className="border-none text-sm font-semibold bg-white h-[32px] w-[32px] rounded-lg text-dark-text hover:text-white hover:bg-neutral-800/80 flex justify-center items-center"
|
||||
className="border-none text-sm font-semibold bg-white light:bg-[#E0F2FE] h-[32px] w-[32px] rounded-lg text-dark-text hover:bg-neutral-800/80 hover:text-white light:text-[#026AA2] light:hover:bg-[#026AA2] light:hover:text-white flex justify-center items-center"
|
||||
>
|
||||
<Trash size={18} weight="bold" />
|
||||
</button>
|
||||
|
@ -340,13 +344,13 @@ function DirectoryTooltips() {
|
|||
id="directory-item"
|
||||
place="bottom"
|
||||
delayShow={800}
|
||||
className="tooltip invert z-99"
|
||||
className="tooltip invert light:invert-0 z-99 max-w-[200px]"
|
||||
render={({ content }) => {
|
||||
const data = safeJsonParse(content, null);
|
||||
if (!data) return null;
|
||||
return (
|
||||
<div className="text-xs">
|
||||
<p className="text-white">{data.title}</p>
|
||||
<p className="text-white light:invert font-medium">{data.title}</p>
|
||||
<div className="flex mt-1 gap-x-2">
|
||||
<p className="">
|
||||
Date: <b>{data.date}</b>
|
||||
|
|
|
@ -112,7 +112,7 @@ function FileUploadProgressComponent({
|
|||
<div
|
||||
className={`${
|
||||
isFadingOut ? "file-upload-fadeout" : "file-upload"
|
||||
} h-14 px-2 py-2 flex items-center gap-x-4 rounded-lg bg-white/5 border border-white/40`}
|
||||
} h-14 px-2 py-2 flex items-center gap-x-4 rounded-lg bg-white border border-white/40 shadow-md`}
|
||||
>
|
||||
<div className="w-6 h-6 flex-shrink-0">
|
||||
{status !== "complete" ? (
|
||||
|
|
|
@ -78,15 +78,17 @@ export default function UploadFile({
|
|||
return (
|
||||
<div>
|
||||
<div
|
||||
className={`w-[560px] border-2 border-dashed rounded-2xl bg-zinc-900/50 p-3 ${
|
||||
ready ? "cursor-pointer" : "cursor-not-allowed"
|
||||
} hover:bg-zinc-900/90`}
|
||||
className={`w-[560px] border-2 border-dashed light:border-[#686C6F] rounded-2xl bg-theme-bg-primary transition-colors duration-300 p-3 ${
|
||||
ready
|
||||
? " light:bg-[#E0F2FE] cursor-pointer hover:bg-theme-bg-secondary light:hover:bg-transparent"
|
||||
: "cursor-not-allowed"
|
||||
}`}
|
||||
{...getRootProps()}
|
||||
>
|
||||
<input {...getInputProps()} />
|
||||
{ready === false ? (
|
||||
<div className="flex flex-col items-center justify-center h-full">
|
||||
<CloudArrowUp className="w-8 h-8 text-white/80" />
|
||||
<CloudArrowUp className="w-8 h-8 text-white/80 light:invert" />
|
||||
<div className="text-white text-opacity-80 text-sm font-semibold py-1">
|
||||
Document Processor Unavailable
|
||||
</div>
|
||||
|
@ -97,7 +99,7 @@ export default function UploadFile({
|
|||
</div>
|
||||
) : files.length === 0 ? (
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<CloudArrowUp className="w-8 h-8 text-white/80" />
|
||||
<CloudArrowUp className="w-8 h-8 text-white/80 light:invert" />
|
||||
<div className="text-white text-opacity-80 text-sm font-semibold py-1">
|
||||
Click to upload or drag and drop
|
||||
</div>
|
||||
|
@ -133,7 +135,7 @@ export default function UploadFile({
|
|||
disabled={fetchingUrl}
|
||||
name="link"
|
||||
type="url"
|
||||
className="disabled:bg-zinc-600 disabled:text-slate-300 bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-3/4 p-2.5"
|
||||
className="disabled:bg-theme-settings-input-bg disabled:text-theme-settings-input-placeholder bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-3/4 p-2.5"
|
||||
placeholder={"https://example.com"}
|
||||
autoComplete="off"
|
||||
/>
|
||||
|
|
|
@ -56,9 +56,13 @@ export default function WorkspaceFileRow({
|
|||
const isMovedItem = movedItems?.some((movedItem) => movedItem.id === item.id);
|
||||
return (
|
||||
<div
|
||||
className={`items-center h-[34px] text-white/80 text-xs grid grid-cols-12 py-2 pl-3.5 pr-8 ${
|
||||
!disableSelection ? "hover:bg-sky-500/20 cursor-pointer" : ""
|
||||
} ${isMovedItem ? "bg-green-800/40" : "file-row"} ${selected ? "selected" : ""}`}
|
||||
className={`text-theme-text-primary text-xs grid grid-cols-12 py-2 pl-3.5 pr-8 h-[34px] items-center ${
|
||||
!disableSelection
|
||||
? "hover:bg-theme-file-picker-hover cursor-pointer"
|
||||
: ""
|
||||
} ${isMovedItem ? "bg-green-800/40" : "file-row"} ${
|
||||
selected ? "selected light:text-white" : ""
|
||||
}`}
|
||||
onClick={toggleRowSelection}
|
||||
>
|
||||
<div
|
||||
|
@ -73,7 +77,9 @@ export default function WorkspaceFileRow({
|
|||
<div className="shrink-0 w-3 h-3">
|
||||
{!disableSelection ? (
|
||||
<div
|
||||
className="w-full h-full rounded border-[1px] border-white flex justify-center items-center cursor-pointer"
|
||||
className={`shrink-0 w-3 h-3 rounded border-[1px] border-white ${
|
||||
selected ? "text-white" : "text-theme-text-primary light:invert"
|
||||
} flex justify-center items-center cursor-pointer`}
|
||||
role="checkbox"
|
||||
aria-checked={selected}
|
||||
tabIndex={0}
|
||||
|
@ -158,7 +164,7 @@ const PinItemToWorkspace = memo(({ workspace, docPath, item }) => {
|
|||
<div
|
||||
onMouseEnter={() => setHover(true)}
|
||||
onMouseLeave={() => setHover(false)}
|
||||
className="flex gap-x-2 items-center hover:bg-main-gradient p-[2px] rounded ml-2"
|
||||
className="flex gap-x-2 items-center hover:bg-theme-file-picker-hover p-[2px] rounded ml-2"
|
||||
>
|
||||
<PushPin
|
||||
data-tooltip-id="pin-document"
|
||||
|
@ -224,7 +230,7 @@ const WatchForChanges = memo(({ workspace, docPath, item }) => {
|
|||
<div
|
||||
onMouseEnter={() => setHover(true)}
|
||||
onMouseLeave={() => setHover(false)}
|
||||
className="flex gap-x-2 items-center hover:bg-main-gradient p-[2px] rounded ml-2"
|
||||
className="flex gap-x-2 items-center hover:bg-theme-file-picker-hover p-[2px] rounded ml-2"
|
||||
>
|
||||
<Eye
|
||||
data-tooltip-id="watch-changes"
|
||||
|
|
|
@ -3,7 +3,7 @@ import { dollarFormat } from "@/utils/numbers";
|
|||
import WorkspaceFileRow from "./WorkspaceFileRow";
|
||||
import { memo, useEffect, useState } from "react";
|
||||
import ModalWrapper from "@/components/ModalWrapper";
|
||||
import { Eye, PushPin } from "@phosphor-icons/react";
|
||||
import { Eye, PushPin, X } from "@phosphor-icons/react";
|
||||
import { SEEN_DOC_PIN_ALERT, SEEN_WATCH_ALERT } from "@/utils/constants";
|
||||
import paths from "@/utils/paths";
|
||||
import { Link } from "react-router-dom";
|
||||
|
@ -93,8 +93,8 @@ function WorkspaceDirectory({
|
|||
{workspace.name}
|
||||
</h3>
|
||||
</div>
|
||||
<div className="relative w-[560px] h-[445px] bg-zinc-900 rounded-2xl mt-5">
|
||||
<div className="text-white/80 text-xs grid grid-cols-12 py-2 px-3.5 border-b border-white/20 bg-zinc-900 sticky top-0 z-10 rounded-t-2xl">
|
||||
<div className="relative w-[560px] h-[445px] bg-theme-settings-input-bg rounded-2xl mt-5 border border-theme-modal-border">
|
||||
<div className="text-white/80 text-xs grid grid-cols-12 py-2 px-3.5 border-b border-white/20 bg-theme-settings-input-bg sticky top-0 z-10 rounded-t-2xl shadow-lg">
|
||||
<div className="col-span-10 flex items-center gap-x-[4px]">
|
||||
<div className="shrink-0 w-3 h-3" />
|
||||
<p className="ml-[7px]">Name</p>
|
||||
|
@ -103,7 +103,7 @@ function WorkspaceDirectory({
|
|||
</div>
|
||||
<div className="w-full h-[calc(100%-40px)] flex items-center justify-center flex-col gap-y-5">
|
||||
<PreLoader />
|
||||
<p className="text-white/80 text-sm font-semibold animate-pulse text-center w-1/3">
|
||||
<p className="text-white text-sm font-semibold animate-pulse text-center w-1/3">
|
||||
{loadingMessage}
|
||||
</p>
|
||||
</div>
|
||||
|
@ -126,13 +126,13 @@ function WorkspaceDirectory({
|
|||
highlightWorkspace ? "border-4 border-cyan-300/80 z-[999]" : ""
|
||||
}`}
|
||||
/>
|
||||
<div className="relative w-full h-full bg-zinc-900 rounded-2xl overflow-hidden">
|
||||
<div className="text-white/80 text-xs grid grid-cols-12 py-2 px-3.5 border-b border-white/20 bg-zinc-900 sticky top-0 z-10">
|
||||
<div className="relative w-full h-full bg-theme-settings-input-bg rounded-2xl overflow-hidden border border-theme-modal-border">
|
||||
<div className="text-white/80 text-xs grid grid-cols-12 py-2 px-3.5 border-b border-white/20 bg-theme-settings-input-bg sticky top-0 z-10 shadow-md">
|
||||
<div className="col-span-10 flex items-center gap-x-[4px]">
|
||||
{!hasChanges &&
|
||||
files.items.some((folder) => folder.items.length > 0) ? (
|
||||
<div
|
||||
className="shrink-0 w-3 h-3 rounded border-[1px] border-white flex justify-center items-center cursor-pointer"
|
||||
className={`shrink-0 w-3 h-3 rounded border-[1px] border-white text-theme-text-primary light:invert flex justify-center items-center cursor-pointer`}
|
||||
role="checkbox"
|
||||
aria-checked={
|
||||
Object.keys(selectedItems).length ===
|
||||
|
@ -153,7 +153,7 @@ function WorkspaceDirectory({
|
|||
) : (
|
||||
<div className="shrink-0 w-3 h-3" />
|
||||
)}
|
||||
<p className="ml-[7px]">Name</p>
|
||||
<p className="ml-[7px] light:text-theme-text-primary">Name</p>
|
||||
</div>
|
||||
<p className="col-span-2" />
|
||||
</div>
|
||||
|
@ -187,13 +187,14 @@ function WorkspaceDirectory({
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{Object.keys(selectedItems).length > 0 && !hasChanges && (
|
||||
<div className="absolute bottom-[12px] left-0 right-0 flex justify-center pointer-events-none">
|
||||
<div className="mx-auto bg-white/40 rounded-lg py-1 px-2 pointer-events-auto">
|
||||
<div className="mx-auto bg-white/40 light:bg-white rounded-lg py-1 px-2 pointer-events-auto light:shadow-lg">
|
||||
<div className="flex flex-row items-center gap-x-2">
|
||||
<button
|
||||
onClick={toggleSelectAll}
|
||||
className="border-none text-sm font-semibold bg-white h-[30px] px-2.5 rounded-lg hover:text-white hover:bg-neutral-800/80"
|
||||
className="border-none text-sm font-semibold bg-white light:bg-[#E0F2FE] h-[30px] px-2.5 rounded-lg hover:bg-neutral-800/80 hover:text-white light:text-[#026AA2] light:hover:bg-[#026AA2] light:hover:text-white"
|
||||
>
|
||||
{Object.keys(selectedItems).length ===
|
||||
files.items.reduce(
|
||||
|
@ -205,7 +206,7 @@ function WorkspaceDirectory({
|
|||
</button>
|
||||
<button
|
||||
onClick={removeSelectedItems}
|
||||
className="border-none text-sm font-semibold bg-white h-[30px] px-2.5 rounded-lg hover:text-white hover:bg-neutral-800/80"
|
||||
className="border-none text-sm font-semibold bg-white light:bg-[#E0F2FE] h-[30px] px-2.5 rounded-lg hover:bg-neutral-800/80 hover:text-white light:text-[#026AA2] light:hover:bg-[#026AA2] light:hover:text-white"
|
||||
>
|
||||
Remove Selected
|
||||
</button>
|
||||
|
@ -268,17 +269,20 @@ const PinAlert = memo(() => {
|
|||
|
||||
return (
|
||||
<ModalWrapper isOpen={showAlert} noPortal={true}>
|
||||
<div className="relative w-full max-w-2xl max-h-full">
|
||||
<div className="relative bg-main-gradient rounded-lg shadow">
|
||||
<div className="flex items-start justify-between p-4 rounded-t border-gray-500/50">
|
||||
<div className="flex items-center gap-2">
|
||||
<PushPin className="text-red-600 text-lg w-6 h-6" weight="fill" />
|
||||
<h3 className="text-xl font-semibold text-white">
|
||||
What is document pinning?
|
||||
</h3>
|
||||
</div>
|
||||
<div className="w-full max-w-2xl bg-theme-bg-secondary rounded-lg shadow border-2 border-theme-modal-border overflow-hidden">
|
||||
<div className="relative p-6 border-b rounded-t border-theme-modal-border">
|
||||
<div className="flex items-center gap-2">
|
||||
<PushPin
|
||||
className="text-theme-text-primary text-lg w-6 h-6"
|
||||
weight="regular"
|
||||
/>
|
||||
<h3 className="text-xl font-semibold text-white">
|
||||
What is document pinning?
|
||||
</h3>
|
||||
</div>
|
||||
<div className="w-full p-6 text-white text-md flex flex-col gap-y-2">
|
||||
</div>
|
||||
<div className="py-7 px-9 space-y-2 flex-col">
|
||||
<div className="w-full text-white text-md flex flex-col gap-y-2">
|
||||
<p>
|
||||
When you <b>pin</b> a document in AnythingLLM we will inject the
|
||||
entire content of the document into your prompt window for your
|
||||
|
@ -294,16 +298,14 @@ const PinAlert = memo(() => {
|
|||
in a click.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex w-full justify-between items-center p-6 space-x-2 border-t rounded-b border-gray-500/50">
|
||||
<button disabled={true} className="invisible" />
|
||||
<button
|
||||
onClick={dismissAlert}
|
||||
className="border border-slate-200 px-4 py-2 rounded-lg text-white text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800 focus:ring-gray-800"
|
||||
>
|
||||
Okay, got it
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-full justify-end items-center p-6 space-x-2 border-t border-theme-modal-border rounded-b">
|
||||
<button
|
||||
onClick={dismissAlert}
|
||||
className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm"
|
||||
>
|
||||
Okay, got it
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
|
@ -330,20 +332,20 @@ const DocumentWatchAlert = memo(() => {
|
|||
|
||||
return (
|
||||
<ModalWrapper isOpen={showAlert} noPortal={true}>
|
||||
<div className="relative w-full max-w-2xl max-h-full">
|
||||
<div className="relative bg-main-gradient rounded-lg shadow">
|
||||
<div className="flex items-start justify-between p-4 rounded-t border-gray-500/50">
|
||||
<div className="flex items-center gap-2">
|
||||
<Eye
|
||||
className="text-yellow-600 text-lg w-6 h-6"
|
||||
weight="regular"
|
||||
/>
|
||||
<h3 className="text-xl font-semibold text-white">
|
||||
What does watching a document do?
|
||||
</h3>
|
||||
</div>
|
||||
<div className="w-full max-w-2xl bg-theme-bg-secondary rounded-lg shadow border-2 border-theme-modal-border overflow-hidden">
|
||||
<div className="relative p-6 border-b rounded-t border-theme-modal-border">
|
||||
<div className="flex items-center gap-2">
|
||||
<Eye
|
||||
className="text-theme-text-primary text-lg w-6 h-6"
|
||||
weight="regular"
|
||||
/>
|
||||
<h3 className="text-xl font-semibold text-white">
|
||||
What does watching a document do?
|
||||
</h3>
|
||||
</div>
|
||||
<div className="w-full p-6 text-white text-md flex flex-col gap-y-2">
|
||||
</div>
|
||||
<div className="py-7 px-9 space-y-2 flex-col">
|
||||
<div className="w-full text-white text-md flex flex-col gap-y-2">
|
||||
<p>
|
||||
When you <b>watch</b> a document in AnythingLLM we will{" "}
|
||||
<i>automatically</i> sync your document content from it's original
|
||||
|
@ -365,16 +367,14 @@ const DocumentWatchAlert = memo(() => {
|
|||
admin view.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex w-full justify-between items-center p-6 space-x-2 border-t rounded-b border-gray-500/50">
|
||||
<button disabled={true} className="invisible" />
|
||||
<button
|
||||
onClick={dismissAlert}
|
||||
className="border border-slate-200 px-4 py-2 rounded-lg text-white text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800 focus:ring-gray-800"
|
||||
>
|
||||
Okay, got it
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-full justify-end items-center p-6 space-x-2 border-t border-theme-modal-border rounded-b">
|
||||
<button
|
||||
onClick={dismissAlert}
|
||||
className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm"
|
||||
>
|
||||
Okay, got it
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
|
@ -410,13 +410,15 @@ function WorkspaceDocumentTooltips() {
|
|||
id="ws-directory-item"
|
||||
place="bottom"
|
||||
delayShow={800}
|
||||
className="tooltip invert z-99"
|
||||
className="tooltip invert light:invert-0 z-99 max-w-[200px]"
|
||||
render={({ content }) => {
|
||||
const data = safeJsonParse(content, null);
|
||||
if (!data) return null;
|
||||
return (
|
||||
<div className="text-xs">
|
||||
<p className="text-white">{data.title}</p>
|
||||
<p className="text-white light:invert font-medium">
|
||||
{data.title}
|
||||
</p>
|
||||
<div className="flex mt-1 gap-x-2">
|
||||
<p className="">
|
||||
Date: <b>{data.date}</b>
|
||||
|
|
|
@ -7,6 +7,7 @@ import { isMobile } from "react-device-detect";
|
|||
import useUser from "../../../hooks/useUser";
|
||||
import DocumentSettings from "./Documents";
|
||||
import DataConnectors from "./DataConnectors";
|
||||
import ModalWrapper from "@/components/ModalWrapper";
|
||||
|
||||
const noop = () => {};
|
||||
const ManageWorkspace = ({ hideModal = noop, providedSlug = null }) => {
|
||||
|
@ -36,31 +37,44 @@ const ManageWorkspace = ({ hideModal = noop, providedSlug = null }) => {
|
|||
|
||||
if (isMobile) {
|
||||
return (
|
||||
<div className="w-screen h-screen fixed top-0 left-0 flex justify-center items-center z-99">
|
||||
<div className="backdrop h-full w-full absolute top-0 z-10" />
|
||||
<div className={`absolute max-h-full transition duration-300 z-20`}>
|
||||
<div className="relative max-w-lg mx-auto bg-main-gradient rounded-[12px] shadow border-2 border-slate-300/10">
|
||||
<div className="p-6">
|
||||
<h1 className="text-white text-lg font-semibold">
|
||||
<ModalWrapper isOpen={true}>
|
||||
<div className="w-full max-w-2xl bg-theme-bg-secondary rounded-lg shadow border-2 border-theme-modal-border overflow-hidden">
|
||||
<div className="relative p-6 border-b rounded-t border-theme-modal-border">
|
||||
<div className="w-full flex gap-x-2 items-center">
|
||||
<h3 className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap">
|
||||
Editing "{workspace.name}"
|
||||
</h1>
|
||||
<p className="text-white mt-4">
|
||||
</h3>
|
||||
</div>
|
||||
<button
|
||||
onClick={hideModal}
|
||||
type="button"
|
||||
className="absolute top-4 right-4 transition-all duration-300 bg-transparent rounded-lg text-sm p-1 inline-flex items-center hover:bg-theme-modal-border hover:border-theme-modal-border hover:border-opacity-50 border-transparent border"
|
||||
>
|
||||
<X size={24} weight="bold" className="text-white" />
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="h-full w-full overflow-y-auto"
|
||||
style={{ maxHeight: "calc(100vh - 200px)" }}
|
||||
>
|
||||
<div className="py-7 px-9 space-y-2 flex-col">
|
||||
<p className="text-white">
|
||||
Editing these settings are only available on a desktop device.
|
||||
Please access this page on your desktop to continue.
|
||||
</p>
|
||||
<div className="mt-6 flex justify-end">
|
||||
<button
|
||||
onClick={hideModal}
|
||||
type="button"
|
||||
className="transition-all duration-300 border border-slate-200 px-4 py-2 rounded-lg text-white text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800 focus:ring-gray-800"
|
||||
>
|
||||
Dismiss
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-full justify-end items-center p-6 space-x-2 border-t border-theme-modal-border rounded-b">
|
||||
<button
|
||||
onClick={hideModal}
|
||||
type="button"
|
||||
className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm"
|
||||
>
|
||||
Dismiss
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -68,14 +82,14 @@ const ManageWorkspace = ({ hideModal = noop, providedSlug = null }) => {
|
|||
<div className="w-screen h-screen fixed top-0 left-0 flex justify-center items-center z-99">
|
||||
<div className="backdrop h-full w-full absolute top-0 z-10" />
|
||||
<div className="absolute max-h-full w-fit transition duration-300 z-20 md:overflow-y-auto py-10">
|
||||
<div className="relative bg-main-gradient rounded-[12px] shadow border-2 border-slate-300/10">
|
||||
<div className="flex items-start justify-between p-2 rounded-t border-gray-500/50 relative">
|
||||
<div className="relative bg-theme-bg-secondary rounded-[12px] shadow border-2 border-theme-modal-border">
|
||||
<div className="flex items-start justify-between p-2 rounded-t border-theme-modal-border relative">
|
||||
<button
|
||||
onClick={hideModal}
|
||||
type="button"
|
||||
className="z-50 text-gray-400 bg-transparent rounded-lg text-sm p-1.5 ml-auto inline-flex items-center hover:border-white/60 bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
className="z-29 text-white bg-transparent rounded-lg text-sm p-1.5 ml-auto inline-flex items-center bg-sidebar-button hover:bg-theme-modal-border hover:border-theme-modal-border hover:border-opacity-50 border-transparent border"
|
||||
>
|
||||
<X className="text-gray-300 text-lg" />
|
||||
<X size={20} weight="bold" className="text-white" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
@ -102,23 +116,23 @@ export default memo(ManageWorkspace);
|
|||
const ModalTabSwitcher = ({ selectedTab, setSelectedTab }) => {
|
||||
return (
|
||||
<div className="w-full flex justify-center z-10 relative">
|
||||
<div className="gap-x-2 flex justify-center -mt-[68px] mb-10 bg-sidebar-button p-1 rounded-xl shadow border-2 border-slate-300/10 w-fit">
|
||||
<div className="gap-x-2 flex justify-center -mt-[68px] mb-10 bg-theme-bg-secondary p-1 rounded-xl shadow border-2 border-theme-modal-border w-fit">
|
||||
<button
|
||||
onClick={() => setSelectedTab("documents")}
|
||||
className={`px-4 py-2 rounded-[8px] font-semibold text-white hover:bg-switch-selected hover:bg-opacity-60 ${
|
||||
className={`px-4 py-2 rounded-[8px] font-semibold hover:bg-theme-modal-border hover:bg-opacity-60 ${
|
||||
selectedTab === "documents"
|
||||
? "bg-switch-selected shadow-md font-bold"
|
||||
: "bg-sidebar-button text-white/20 font-medium hover:text-white"
|
||||
? "bg-theme-modal-border font-bold text-white light:bg-[#E0F2FE] light:text-[#026AA2]"
|
||||
: "text-white/20 font-medium hover:text-white light:bg-white light:text-[#535862] light:hover:bg-[#E0F2FE]"
|
||||
}`}
|
||||
>
|
||||
Documents
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setSelectedTab("dataConnectors")}
|
||||
className={`px-4 py-2 rounded-[8px] font-semibold text-white hover:bg-switch-selected hover:bg-opacity-60 ${
|
||||
className={`px-4 py-2 rounded-[8px] font-semibold hover:bg-theme-modal-border hover:bg-opacity-60 ${
|
||||
selectedTab === "dataConnectors"
|
||||
? "bg-switch-selected shadow-md font-bold"
|
||||
: "bg-sidebar-button text-white/20 font-medium hover:text-white"
|
||||
? "bg-theme-modal-border font-bold text-white light:bg-[#E0F2FE] light:text-[#026AA2]"
|
||||
: "text-white/20 font-medium hover:text-white light:bg-white light:text-[#535862] light:hover:bg-[#E0F2FE]"
|
||||
}`}
|
||||
>
|
||||
Data Connectors
|
||||
|
|
|
@ -3,6 +3,7 @@ import { X } from "@phosphor-icons/react";
|
|||
import Workspace from "@/models/workspace";
|
||||
import paths from "@/utils/paths";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import ModalWrapper from "@/components/ModalWrapper";
|
||||
|
||||
const noop = () => false;
|
||||
export default function NewWorkspaceModal({ hideModal = noop }) {
|
||||
|
@ -23,27 +24,28 @@ export default function NewWorkspaceModal({ hideModal = noop }) {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="fixed top-0 left-0 right-0 z-50 w-full p-4 overflow-x-hidden overflow-y-auto md:inset-0 h-[calc(100%-1rem)] h-full bg-black bg-opacity-50 flex items-center justify-center">
|
||||
<div
|
||||
className="flex fixed top-0 left-0 right-0 w-full h-full"
|
||||
onClick={hideModal}
|
||||
/>
|
||||
<div className="relative w-[500px] max-h-full">
|
||||
<div className="relative bg-modal-gradient rounded-lg shadow-md border-2 border-accent">
|
||||
<div className="flex items-start justify-between p-4 border-b rounded-t border-white/10">
|
||||
<h3 className="text-xl font-semibold text-white">
|
||||
<ModalWrapper isOpen={true}>
|
||||
<div className="w-full max-w-2xl bg-theme-bg-secondary rounded-lg shadow border-2 border-theme-modal-border overflow-hidden">
|
||||
<div className="relative p-6 border-b rounded-t border-theme-modal-border">
|
||||
<div className="w-full flex gap-x-2 items-center">
|
||||
<h3 className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap">
|
||||
{t("new-workspace.title")}
|
||||
</h3>
|
||||
<button
|
||||
onClick={hideModal}
|
||||
type="button"
|
||||
className="transition-all duration-300 text-gray-400 bg-transparent hover:border-white/60 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
>
|
||||
<X className="text-gray-300 text-lg" />
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
onClick={hideModal}
|
||||
type="button"
|
||||
className="absolute top-4 right-4 transition-all duration-300 bg-transparent rounded-lg text-sm p-1 inline-flex items-center hover:bg-theme-modal-border hover:border-theme-modal-border hover:border-opacity-50 border-transparent border"
|
||||
>
|
||||
<X size={24} weight="bold" className="text-white" />
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="h-full w-full overflow-y-auto"
|
||||
style={{ maxHeight: "calc(100vh - 200px)" }}
|
||||
>
|
||||
<form ref={formEl} onSubmit={handleCreate}>
|
||||
<div className="p-6 space-y-6 flex h-full w-full">
|
||||
<div className="py-7 px-9 space-y-2 flex-col">
|
||||
<div className="w-full flex flex-col gap-y-4">
|
||||
<div>
|
||||
<label
|
||||
|
@ -56,7 +58,7 @@ export default function NewWorkspaceModal({ hideModal = noop }) {
|
|||
name="name"
|
||||
type="text"
|
||||
id="name"
|
||||
className="bg-zinc-900 w-full text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg w-full text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder={t("new-workspace.placeholder")}
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
|
@ -67,10 +69,10 @@ export default function NewWorkspaceModal({ hideModal = noop }) {
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-full justify-end items-center p-6 space-x-2 border-t border-white/10 rounded-b">
|
||||
<div className="flex w-full justify-end items-center p-6 space-x-2 border-t border-theme-modal-border rounded-b">
|
||||
<button
|
||||
type="submit"
|
||||
className="transition-all duration-300 border border-slate-200 px-4 py-2 rounded-lg text-white text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800 focus:ring-gray-800"
|
||||
className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
|
@ -78,7 +80,7 @@ export default function NewWorkspaceModal({ hideModal = noop }) {
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,14 +32,14 @@ const RecoveryForm = ({ onSubmit, setShowRecoveryForm }) => {
|
|||
return (
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
className="flex flex-col justify-center items-center relative rounded-2xl md:bg-login-gradient md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-8 px-0 py-4 w-full md:w-fit mt-10 md:mt-0"
|
||||
className="flex flex-col justify-center items-center relative rounded-2xl border-none bg-theme-bg-secondary md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-8 px-0 py-4 w-full md:w-fit mt-10 md:mt-0"
|
||||
>
|
||||
<div className="flex items-start justify-between pt-11 pb-9 w-screen md:w-full md:px-12 px-6 ">
|
||||
<div className="flex flex-col gap-y-4 w-full">
|
||||
<h3 className="text-4xl md:text-lg font-bold text-white text-center md:text-left">
|
||||
<h3 className="text-4xl md:text-lg font-bold text-theme-text-primary text-center md:text-left">
|
||||
{t("login.password-reset.title")}
|
||||
</h3>
|
||||
<p className="text-sm text-white/90 md:text-left md:max-w-[300px] px-4 md:px-0 text-center">
|
||||
<p className="text-sm text-theme-text-secondary md:text-left md:max-w-[300px] px-4 md:px-0 text-center">
|
||||
{t("login.password-reset.description")}
|
||||
</p>
|
||||
</div>
|
||||
|
@ -56,7 +56,7 @@ const RecoveryForm = ({ onSubmit, setShowRecoveryForm }) => {
|
|||
placeholder={t("login.multi-user.placeholder-username")}
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
|
||||
className="bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
@ -76,7 +76,7 @@ const RecoveryForm = ({ onSubmit, setShowRecoveryForm }) => {
|
|||
onChange={(e) =>
|
||||
handleRecoveryCodeChange(index, e.target.value)
|
||||
}
|
||||
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
|
||||
className="bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
@ -115,7 +115,7 @@ const ResetPasswordForm = ({ onSubmit }) => {
|
|||
return (
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
className="flex flex-col justify-center items-center relative rounded-2xl md:bg-login-gradient md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-12 px-0 py-4 w-full md:w-fit -mt-24 md:-mt-28"
|
||||
className="flex flex-col justify-center items-center relative rounded-2xl bg-theme-bg-secondary md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-8 px-0 py-4 w-full md:w-fit mt-10 md:mt-0"
|
||||
>
|
||||
<div className="flex items-start justify-between pt-11 pb-9 w-screen md:w-full md:px-12 px-6">
|
||||
<div className="flex flex-col gap-y-4 w-full">
|
||||
|
@ -136,7 +136,7 @@ const ResetPasswordForm = ({ onSubmit }) => {
|
|||
placeholder="New Password"
|
||||
value={newPassword}
|
||||
onChange={(e) => setNewPassword(e.target.value)}
|
||||
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
@ -147,7 +147,7 @@ const ResetPasswordForm = ({ onSubmit }) => {
|
|||
placeholder="Confirm Password"
|
||||
value={confirmPassword}
|
||||
onChange={(e) => setConfirmPassword(e.target.value)}
|
||||
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
@ -281,18 +281,18 @@ export default function MultiUserAuth() {
|
|||
return (
|
||||
<>
|
||||
<form onSubmit={handleLogin}>
|
||||
<div className="flex flex-col justify-center items-center relative rounded-2xl md:bg-login-gradient md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-12 py-12 -mt-4 md:mt-0">
|
||||
<div className="flex flex-col justify-center items-center relative rounded-2xl bg-theme-bg-secondary md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-12 py-12 -mt-4 md:mt-0">
|
||||
<div className="flex items-start justify-between pt-11 pb-9 rounded-t">
|
||||
<div className="flex items-center flex-col gap-y-4">
|
||||
<div className="flex gap-x-1">
|
||||
<h3 className="text-md md:text-2xl font-bold text-white text-center white-space-nowrap hidden md:block">
|
||||
{t("login.multi-user.welcome")}
|
||||
</h3>
|
||||
<p className="text-4xl md:text-2xl font-bold bg-gradient-to-r from-[#75D6FF] via-[#FFFFFF] to-[#FFFFFF] bg-clip-text text-transparent">
|
||||
<p className="text-4xl md:text-2xl font-bold bg-gradient-to-r from-[#75D6FF] via-[#FFFFFF] light:via-[#75D6FF] to-[#FFFFFF] light:to-[#75D6FF] bg-clip-text text-transparent">
|
||||
{customAppName || "AnythingLLM"}
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-sm text-white/90 text-center">
|
||||
<p className="text-sm text-theme-text-secondary text-center">
|
||||
{t("login.sign-in.start")} {customAppName || "AnythingLLM"}{" "}
|
||||
{t("login.sign-in.end")}
|
||||
</p>
|
||||
|
@ -305,7 +305,7 @@ export default function MultiUserAuth() {
|
|||
name="username"
|
||||
type="text"
|
||||
placeholder={t("login.multi-user.placeholder-username")}
|
||||
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
|
||||
className="bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
/>
|
||||
|
@ -315,7 +315,7 @@ export default function MultiUserAuth() {
|
|||
name="password"
|
||||
type="password"
|
||||
placeholder={t("login.multi-user.placeholder-password")}
|
||||
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
|
||||
className="bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
/>
|
||||
|
|
|
@ -70,18 +70,18 @@ export default function SingleUserAuth() {
|
|||
return (
|
||||
<>
|
||||
<form onSubmit={handleLogin}>
|
||||
<div className="flex flex-col justify-center items-center relative rounded-2xl md:bg-login-gradient md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-12 py-12 -mt-36 md:-mt-10">
|
||||
<div className="flex flex-col justify-center items-center relative rounded-2xl bg-theme-bg-secondary md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] md:px-12 py-12 -mt-36 md:-mt-10">
|
||||
<div className="flex items-start justify-between pt-11 pb-9 rounded-t">
|
||||
<div className="flex items-center flex-col gap-y-4">
|
||||
<div className="flex gap-x-1">
|
||||
<h3 className="text-md md:text-2xl font-bold text-white text-center white-space-nowrap hidden md:block">
|
||||
{t("login.multi-user.welcome")}
|
||||
</h3>
|
||||
<p className="text-4xl md:text-2xl font-bold bg-gradient-to-r from-[#75D6FF] via-[#FFFFFF] to-[#FFFFFF] bg-clip-text text-transparent">
|
||||
<p className="text-4xl md:text-2xl font-bold bg-gradient-to-r from-[#75D6FF] via-[#FFFFFF] light:via-[#75D6FF] to-[#FFFFFF] light:to-[#75D6FF] bg-clip-text text-transparent">
|
||||
{customAppName || "AnythingLLM"}
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-sm text-white/90 text-center">
|
||||
<p className="text-sm text-theme-text-secondary text-center">
|
||||
{t("login.sign-in.start")} {customAppName || "AnythingLLM"}{" "}
|
||||
{t("login.sign-in.end")}
|
||||
</p>
|
||||
|
@ -94,12 +94,11 @@ export default function SingleUserAuth() {
|
|||
name="password"
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
className="bg-zinc-900 text-white placeholder-white/20 text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
|
||||
className="bg-theme-settings-input-bg text-theme-text-primary placeholder:text-theme-settings-input-placeholder focus:outline-primary-button active:outline-primary-button outline-none text-sm rounded-md p-2.5 w-full h-[48px] md:w-[300px] md:h-[34px]"
|
||||
required={true}
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{error && <p className="text-red-400 text-sm">Error: {error}</p>}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -109,13 +108,15 @@ export default function SingleUserAuth() {
|
|||
type="submit"
|
||||
className="md:text-primary-button md:bg-transparent text-dark-text text-sm font-bold focus:ring-4 focus:outline-none rounded-md border-[1.5px] border-primary-button md:h-[34px] h-[48px] md:hover:text-white md:hover:bg-primary-button bg-primary-button focus:z-10 w-full"
|
||||
>
|
||||
{loading ? "Validating..." : "Login"}
|
||||
{loading
|
||||
? t("login.multi-user.validating")
|
||||
: t("login.multi-user.login")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<ModalWrapper isOpen={isRecoveryCodeModalOpen}>
|
||||
<ModalWrapper isOpen={isRecoveryCodeModalOpen} noPortal={true}>
|
||||
<RecoveryCodeModal
|
||||
recoveryCodes={recoveryCodes}
|
||||
onDownloadComplete={handleDownloadComplete}
|
||||
|
|
|
@ -13,7 +13,7 @@ import illustration from "@/media/illustrations/login-illustration.svg";
|
|||
export default function PasswordModal({ mode = "single" }) {
|
||||
const { loginLogo } = useLogo();
|
||||
return (
|
||||
<div className="fixed top-0 left-0 right-0 z-50 w-full overflow-x-hidden overflow-y-auto md:inset-0 h-[calc(100%-1rem)] h-full bg-[#25272C] flex flex-col md:flex-row items-center justify-center">
|
||||
<div className="fixed top-0 left-0 right-0 z-50 w-full overflow-x-hidden overflow-y-auto md:inset-0 h-[calc(100%-1rem)] h-full bg-theme-bg-primary flex flex-col md:flex-row items-center justify-center">
|
||||
<div
|
||||
style={{
|
||||
background: `
|
||||
|
@ -33,13 +33,13 @@ export default function PasswordModal({ mode = "single" }) {
|
|||
alt="login illustration"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center h-full w-full md:w-1/2 z-50 relative -mt-20">
|
||||
<div className="flex flex-col items-center justify-center h-full w-full md:w-1/2 z-50 relative md:-mt-20 mt-0 !border-none bg-theme-bg-secondary md:bg-transparent">
|
||||
<img
|
||||
src={loginLogo}
|
||||
alt="Logo"
|
||||
className={`hidden relative md:flex rounded-2xl w-fit m-4 z-30 ${
|
||||
mode === "single" ? "md:top-2" : "md:top-12"
|
||||
} absolute max-h-[65px] md:bg-login-gradient md:shadow-[0_4px_14px_rgba(0,0,0,0.25)]`}
|
||||
} absolute max-h-[65px]`}
|
||||
style={{ objectFit: "contain" }}
|
||||
/>
|
||||
{mode === "single" ? <SingleUserAuth /> : <MultiUserAuth />}
|
||||
|
|
|
@ -10,9 +10,9 @@ export function FullScreenLoader() {
|
|||
return (
|
||||
<div
|
||||
id="preloader"
|
||||
className="fixed left-0 top-0 z-999999 flex h-screen w-screen items-center justify-center bg-sidebar"
|
||||
className="fixed left-0 top-0 z-999999 flex h-screen w-screen items-center justify-center bg-theme-bg-primary"
|
||||
>
|
||||
<div className="h-16 w-16 animate-spin rounded-full border-4 border-solid border-primary border-t-transparent"></div>
|
||||
<div className="h-16 w-16 animate-spin rounded-full border-4 border-solid border-[var(--theme-loader)] border-t-transparent"></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,12 +15,16 @@ export default function SettingsButton() {
|
|||
<div className="flex w-fit">
|
||||
<Link
|
||||
to={paths.home()}
|
||||
className="transition-all duration-300 p-2 rounded-full text-white bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
className="transition-all duration-300 p-2 rounded-full bg-theme-sidebar-footer-icon hover:bg-theme-sidebar-footer-icon-hover"
|
||||
aria-label="Home"
|
||||
data-tooltip-id="footer-item"
|
||||
data-tooltip-content="Back to workspaces"
|
||||
>
|
||||
<ArrowUUpLeft className="h-5 w-5" weight="fill" />
|
||||
<ArrowUUpLeft
|
||||
className="h-5 w-5"
|
||||
weight="fill"
|
||||
color="var(--theme-sidebar-footer-icon-fill)"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
|
@ -29,12 +33,17 @@ export default function SettingsButton() {
|
|||
<div className="flex w-fit">
|
||||
<Link
|
||||
to={paths.settings.appearance()}
|
||||
className="transition-all duration-300 p-2 rounded-full text-white bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
className="transition-all duration-300 p-2 rounded-full bg-theme-sidebar-footer-icon hover:bg-theme-sidebar-footer-icon-hover"
|
||||
// className="transition-all duration-300 p-2 rounded-full bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
aria-label="Settings"
|
||||
data-tooltip-id="footer-item"
|
||||
data-tooltip-content="Open settings"
|
||||
>
|
||||
<Wrench className="h-5 w-5" weight="fill" />
|
||||
<Wrench
|
||||
className="h-5 w-5"
|
||||
weight="fill"
|
||||
color="var(--theme-sidebar-footer-icon-fill)"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -66,15 +66,15 @@ export default function MenuOption({
|
|||
rounded-[6px]
|
||||
${
|
||||
isActive
|
||||
? "bg-white/5 font-medium border-outline"
|
||||
: "hover:bg-white/5"
|
||||
? "bg-theme-sidebar-subitem-selected font-medium border-outline"
|
||||
: "hover:bg-theme-sidebar-subitem-hover"
|
||||
}
|
||||
`}
|
||||
>
|
||||
<Link
|
||||
to={href}
|
||||
className={`flex flex-grow items-center px-[12px] h-[32px] font-medium ${
|
||||
isChild ? "text-white/70 hover:text-white" : "text-white"
|
||||
isChild ? "hover:text-white" : "text-white light:text-black"
|
||||
}`}
|
||||
onClick={hasChildren ? handleClick : undefined}
|
||||
>
|
||||
|
@ -83,7 +83,9 @@ export default function MenuOption({
|
|||
className={`${
|
||||
isChild ? "text-xs" : "text-sm"
|
||||
} leading-loose whitespace-nowrap overflow-hidden ml-2 ${
|
||||
isActive ? "text-white" : ""
|
||||
isActive
|
||||
? "text-white font-semibold"
|
||||
: "text-white light:text-black"
|
||||
} ${!icon && "pl-5"}`}
|
||||
>
|
||||
{btnText}
|
||||
|
@ -94,7 +96,8 @@ export default function MenuOption({
|
|||
<CaretRight
|
||||
size={16}
|
||||
weight="bold"
|
||||
className={`transition-transform ${
|
||||
// color={isExpanded ? "#000000" : "var(--theme-sidebar-subitem-icon)"}
|
||||
className={`transition-transform text-white light:text-black ${
|
||||
isExpanded ? "rotate-90" : ""
|
||||
}`}
|
||||
/>
|
||||
|
|
|
@ -13,7 +13,6 @@ import {
|
|||
Toolbox,
|
||||
} from "@phosphor-icons/react";
|
||||
import useUser from "@/hooks/useUser";
|
||||
import { USER_BACKGROUND_COLOR } from "@/utils/constants";
|
||||
import { isMobile } from "react-device-detect";
|
||||
import Footer from "../Footer";
|
||||
import { Link } from "react-router-dom";
|
||||
|
@ -47,10 +46,10 @@ export default function SettingsSidebar() {
|
|||
if (isMobile) {
|
||||
return (
|
||||
<>
|
||||
<div className="fixed top-0 left-0 right-0 z-10 flex justify-between items-center px-4 py-2 bg-sidebar text-slate-200 shadow-lg h-16">
|
||||
<div className="fixed top-0 left-0 right-0 z-10 flex justify-between items-center px-4 py-2 bg-theme-bg-sidebar light:bg-white text-theme-text-secondary shadow-lg h-16">
|
||||
<button
|
||||
onClick={() => setShowSidebar(true)}
|
||||
className="rounded-md p-2 flex items-center justify-center text-slate-200"
|
||||
className="rounded-md p-2 flex items-center justify-center text-theme-text-secondary"
|
||||
>
|
||||
<List className="h-6 w-6" />
|
||||
</button>
|
||||
|
@ -75,12 +74,12 @@ export default function SettingsSidebar() {
|
|||
showBgOverlay
|
||||
? "transition-all opacity-1"
|
||||
: "transition-none opacity-0"
|
||||
} duration-500 fixed top-0 left-0 ${USER_BACKGROUND_COLOR} bg-opacity-75 w-screen h-screen`}
|
||||
} duration-500 fixed top-0 left-0 bg-theme-bg-secondary bg-opacity-75 w-screen h-screen`}
|
||||
onClick={() => setShowSidebar(false)}
|
||||
/>
|
||||
<div
|
||||
ref={sidebarRef}
|
||||
className="h-[100vh] fixed top-0 left-0 rounded-r-[26px] bg-sidebar w-[80%] p-[18px]"
|
||||
className="h-[100vh] fixed top-0 left-0 rounded-r-[26px] bg-theme-bg-sidebar w-[80%] p-[18px]"
|
||||
>
|
||||
<div className="w-full h-full flex flex-col overflow-x-hidden items-between">
|
||||
{/* Header Information */}
|
||||
|
@ -96,7 +95,7 @@ export default function SettingsSidebar() {
|
|||
<div className="flex gap-x-2 items-center text-slate-500 shrink-0">
|
||||
<a
|
||||
href={paths.home()}
|
||||
className="transition-all duration-300 p-2 rounded-full text-white bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
className="transition-all duration-300 p-2 rounded-full text-white bg-theme-action-menu-bg hover:bg-theme-action-menu-item-hover hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
>
|
||||
<House className="h-4 w-4" />
|
||||
</a>
|
||||
|
@ -105,7 +104,7 @@ export default function SettingsSidebar() {
|
|||
|
||||
{/* Primary Body */}
|
||||
<div className="h-full flex flex-col w-full justify-between pt-4 overflow-y-scroll no-scroll">
|
||||
<div className="h-auto md:sidebar-items md:dark:sidebar-items">
|
||||
<div className="h-auto md:sidebar-items">
|
||||
<div className="flex flex-col gap-y-4 pb-[60px] overflow-y-scroll no-scroll">
|
||||
<SidebarOptions user={user} t={t} />
|
||||
<div className="h-[1.5px] bg-[#3D4147] mx-3 mt-[14px]" />
|
||||
|
@ -115,14 +114,14 @@ export default function SettingsSidebar() {
|
|||
user?.hasOwnProperty("role") && user.role !== "admin"
|
||||
}
|
||||
to={paths.settings.privacy()}
|
||||
className="text-darker hover:text-white text-xs leading-[18px] mx-3"
|
||||
className="text-theme-text-secondary hover:text-white text-xs leading-[18px] mx-3"
|
||||
>
|
||||
{t("settings.privacy")}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-2 left-0 right-0 pt-2 bg-sidebar bg-opacity-80 backdrop-filter backdrop-blur-md">
|
||||
<div className="absolute bottom-2 left-0 right-0 pt-2 bg-theme-bg-sidebar bg-opacity-80 backdrop-filter backdrop-blur-md">
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -148,10 +147,10 @@ export default function SettingsSidebar() {
|
|||
</Link>
|
||||
<div
|
||||
ref={sidebarRef}
|
||||
className="transition-all duration-500 relative m-[16px] rounded-[16px] bg-sidebar border-2 border-outline min-w-[250px] p-[10px] h-[calc(100%-76px)]"
|
||||
className="transition-all duration-500 relative m-[16px] rounded-[16px] bg-theme-bg-sidebar border-[2px] border-theme-sidebar-border light:border-none min-w-[250px] p-[10px] h-[calc(100%-76px)]"
|
||||
>
|
||||
<div className="w-full h-full flex flex-col overflow-x-hidden items-between min-w-[235px]">
|
||||
<div className="text-white text-opacity-60 text-sm font-medium uppercase mt-[4px] mb-0 ml-2">
|
||||
<div className="text-theme-text-secondary text-sm font-medium uppercase mt-[4px] mb-0 ml-2">
|
||||
{t("settings.title")}
|
||||
</div>
|
||||
<div className="relative h-[calc(100%-60px)] flex flex-col w-full justify-between pt-[10px] overflow-y-scroll no-scroll">
|
||||
|
@ -165,14 +164,14 @@ export default function SettingsSidebar() {
|
|||
user?.hasOwnProperty("role") && user.role !== "admin"
|
||||
}
|
||||
to={paths.settings.privacy()}
|
||||
className="text-darker hover:text-white text-xs leading-[18px] mx-3"
|
||||
className="text-theme-text-secondary hover:text-white hover:light:text-theme-text-primary text-xs leading-[18px] mx-3"
|
||||
>
|
||||
{t("settings.privacy")}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-0 right-0 pt-4 pb-3 rounded-b-[16px] bg-sidebar bg-opacity-80 backdrop-filter backdrop-blur-md z-10">
|
||||
<div className="absolute bottom-0 left-0 right-0 pt-4 pb-3 rounded-b-[16px] bg-theme-bg-sidebar bg-opacity-80 backdrop-filter backdrop-blur-md z-10">
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -201,7 +200,7 @@ function SupportEmail() {
|
|||
return (
|
||||
<Link
|
||||
to={supportEmail}
|
||||
className="text-darker hover:text-white text-xs leading-[18px] mx-3 mt-1"
|
||||
className="text-theme-text-secondary hover:text-white hover:light:text-theme-text-primary text-xs leading-[18px] mx-3 mt-1"
|
||||
>
|
||||
{t("settings.contact")}
|
||||
</Link>
|
||||
|
|
|
@ -33,7 +33,7 @@ export default function ThreadItem({
|
|||
|
||||
return (
|
||||
<div
|
||||
className="w-full relative flex h-[38px] items-center border-none hover:bg-slate-600/20 rounded-lg"
|
||||
className="w-full relative flex h-[38px] items-center border-none rounded-lg"
|
||||
role="listitem"
|
||||
>
|
||||
{/* Curved line Element and leader if required */}
|
||||
|
@ -41,9 +41,9 @@ export default function ThreadItem({
|
|||
style={{ width: THREAD_CALLOUT_DETAIL_WIDTH / 2 }}
|
||||
className={`${
|
||||
isActive
|
||||
? "border-l-2 border-b-2 border-white"
|
||||
: "border-l border-b border-slate-300"
|
||||
} h-[50%] absolute top-0 z-10 left-2 rounded-bl-lg`}
|
||||
? "border-l-2 border-b-2 border-white light:border-theme-sidebar-border z-30"
|
||||
: "border-l border-b border-[#6F6F71] light:border-theme-sidebar-border z-10"
|
||||
} h-[50%] absolute top-0 left-2 rounded-bl-lg`}
|
||||
></div>
|
||||
{/* Downstroke border for next item */}
|
||||
{hasNext && (
|
||||
|
@ -51,9 +51,9 @@ export default function ThreadItem({
|
|||
style={{ width: THREAD_CALLOUT_DETAIL_WIDTH / 2 }}
|
||||
className={`${
|
||||
idx <= activeIdx && !isActive
|
||||
? "border-l-2 border-white"
|
||||
: "border-l border-slate-300"
|
||||
} h-[100%] absolute top-0 z-1 left-2`}
|
||||
? "border-l-2 border-white light:border-theme-sidebar-border z-20"
|
||||
: "border-l border-[#6F6F71] light:border-theme-sidebar-border z-10"
|
||||
} h-[100%] absolute top-0 left-2`}
|
||||
></div>
|
||||
)}
|
||||
|
||||
|
@ -62,11 +62,15 @@ export default function ThreadItem({
|
|||
style={{ width: THREAD_CALLOUT_DETAIL_WIDTH + 8 }}
|
||||
className="h-full"
|
||||
/>
|
||||
<div className="flex w-full items-center justify-between pr-2 group relative">
|
||||
<div
|
||||
className={`flex w-full items-center justify-between pr-2 group relative ${isActive ? "bg-[var(--theme-sidebar-thread-selected)]" : "hover:bg-theme-sidebar-subitem-hover"} rounded-[4px]`}
|
||||
>
|
||||
{thread.deleted ? (
|
||||
<div className="w-full flex justify-between">
|
||||
<div className="w-full ">
|
||||
<p className={`text-left text-sm text-slate-400/50 italic`}>
|
||||
<div className="w-full pl-2 py-1">
|
||||
<p
|
||||
className={`text-left text-sm text-slate-400/50 light:text-slate-500 italic`}
|
||||
>
|
||||
deleted thread
|
||||
</p>
|
||||
</div>
|
||||
|
@ -77,7 +81,7 @@ export default function ThreadItem({
|
|||
onClick={() => toggleMarkForDeletion(thread.id)}
|
||||
>
|
||||
<ArrowCounterClockwise
|
||||
className="text-zinc-300 hover:text-white"
|
||||
className="text-zinc-300 hover:text-white light:text-theme-text-secondary hover:light:text-theme-text-primary"
|
||||
size={18}
|
||||
/>
|
||||
</button>
|
||||
|
@ -88,12 +92,12 @@ export default function ThreadItem({
|
|||
href={
|
||||
window.location.pathname === linkTo || ctrlPressed ? "#" : linkTo
|
||||
}
|
||||
className="w-full"
|
||||
className="w-full pl-2 py-1"
|
||||
aria-current={isActive ? "page" : ""}
|
||||
>
|
||||
<p
|
||||
className={`text-left text-sm ${
|
||||
isActive ? "font-medium text-white" : "text-slate-400"
|
||||
isActive ? "font-medium text-white" : "text-theme-text-primary"
|
||||
}`}
|
||||
>
|
||||
{truncate(thread.name, 25)}
|
||||
|
@ -101,7 +105,9 @@ export default function ThreadItem({
|
|||
</a>
|
||||
)}
|
||||
{!!thread.slug && !thread.deleted && (
|
||||
<div ref={optionsContainer}>
|
||||
<div ref={optionsContainer} className="flex items-center">
|
||||
{" "}
|
||||
{/* Added flex and items-center */}
|
||||
{ctrlPressed ? (
|
||||
<button
|
||||
type="button"
|
||||
|
@ -109,7 +115,7 @@ export default function ThreadItem({
|
|||
onClick={() => toggleMarkForDeletion(thread.id)}
|
||||
>
|
||||
<X
|
||||
className="text-zinc-300 hover:text-white"
|
||||
className="text-zinc-300 light:text-theme-text-secondary hover:text-white hover:light:text-theme-text-primary"
|
||||
weight="bold"
|
||||
size={18}
|
||||
/>
|
||||
|
@ -122,7 +128,10 @@ export default function ThreadItem({
|
|||
onClick={() => setShowOptions(!showOptions)}
|
||||
aria-label="Thread options"
|
||||
>
|
||||
<DotsThree className="text-slate-300" size={25} />
|
||||
<DotsThree
|
||||
className="text-slate-300 light:text-theme-text-secondary hover:text-white hover:light:text-theme-text-primary"
|
||||
size={25}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
@ -225,12 +234,12 @@ function OptionsMenu({ containerRef, workspace, thread, onRemove, close }) {
|
|||
return (
|
||||
<div
|
||||
ref={menuRef}
|
||||
className="absolute w-fit z-[20] top-[25px] right-[10px] bg-zinc-900 rounded-lg p-1"
|
||||
className="absolute w-fit z-[20] top-[25px] right-[10px] bg-zinc-900 light:bg-theme-bg-sidebar light:border-[1px] light:border-theme-sidebar-border rounded-lg p-1"
|
||||
>
|
||||
<button
|
||||
onClick={renameThread}
|
||||
type="button"
|
||||
className="w-full rounded-md flex items-center p-2 gap-x-2 hover:bg-slate-500/20 text-slate-300"
|
||||
className="w-full rounded-md flex items-center p-2 gap-x-2 hover:bg-slate-500/20 text-slate-300 light:text-theme-text-primary"
|
||||
>
|
||||
<PencilSimple size={18} />
|
||||
<p className="text-sm">Rename</p>
|
||||
|
@ -238,7 +247,7 @@ function OptionsMenu({ containerRef, workspace, thread, onRemove, close }) {
|
|||
<button
|
||||
onClick={handleDelete}
|
||||
type="button"
|
||||
className="w-full rounded-md flex items-center p-2 gap-x-2 hover:bg-red-500/20 text-slate-300 hover:text-red-100"
|
||||
className="w-full rounded-md flex items-center p-2 gap-x-2 hover:bg-red-500/20 text-slate-300 light:text-theme-text-primary hover:text-red-100"
|
||||
>
|
||||
<Trash size={18} />
|
||||
<p className="text-sm">Delete Thread</p>
|
||||
|
|
|
@ -107,9 +107,7 @@ export default function ThreadContainer({ workspace }) {
|
|||
if (loading) {
|
||||
return (
|
||||
<div className="flex flex-col bg-pulse w-full h-10 items-center justify-center">
|
||||
<p className="text-xs text-slate-600 animate-pulse">
|
||||
loading threads....
|
||||
</p>
|
||||
<p className="text-xs text-white animate-pulse">loading threads....</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -171,25 +169,33 @@ function NewThreadButton({ workspace }) {
|
|||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className="w-full relative flex h-[40px] items-center border-none hover:bg-slate-600/20 rounded-lg"
|
||||
className="w-full relative flex h-[40px] items-center border-none hover:bg-[var(--theme-sidebar-thread-selected)] rounded-lg"
|
||||
>
|
||||
<div className="flex w-full gap-x-2 items-center pl-4">
|
||||
<div className="bg-zinc-600 p-2 rounded-lg h-[24px] w-[24px] flex items-center justify-center">
|
||||
<div className="bg-white/20 p-2 rounded-lg h-[24px] w-[24px] flex items-center justify-center">
|
||||
{loading ? (
|
||||
<CircleNotch
|
||||
weight="bold"
|
||||
size={14}
|
||||
className="shrink-0 animate-spin text-slate-100"
|
||||
className="shrink-0 animate-spin text-white light:text-theme-text-primary"
|
||||
/>
|
||||
) : (
|
||||
<Plus weight="bold" size={14} className="shrink-0 text-slate-100" />
|
||||
<Plus
|
||||
weight="bold"
|
||||
size={14}
|
||||
className="shrink-0 text-white light:text-theme-text-primary"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
<p className="text-left text-slate-100 text-sm">Starting Thread...</p>
|
||||
<p className="text-left text-white light:text-theme-text-primary text-sm">
|
||||
Starting Thread...
|
||||
</p>
|
||||
) : (
|
||||
<p className="text-left text-slate-100 text-sm">New Thread</p>
|
||||
<p className="text-left text-white light:text-theme-text-primary text-sm">
|
||||
New Thread
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
|
@ -206,14 +212,14 @@ function DeleteAllThreadButton({ ctrlPressed, threads, onDelete }) {
|
|||
className="w-full relative flex h-[40px] items-center border-none hover:bg-red-400/20 rounded-lg group"
|
||||
>
|
||||
<div className="flex w-full gap-x-2 items-center pl-4">
|
||||
<div className="bg-zinc-600 p-2 rounded-lg h-[24px] w-[24px] flex items-center justify-center">
|
||||
<div className="bg-zinc-600 light:bg-transparent p-2 rounded-lg h-[24px] w-[24px] flex items-center justify-center">
|
||||
<Trash
|
||||
weight="bold"
|
||||
size={14}
|
||||
className="shrink-0 text-slate-100 group-hover:text-red-400"
|
||||
className="shrink-0 text-white light:text-red-500/50 group-hover:text-red-400"
|
||||
/>
|
||||
</div>
|
||||
<p className="text-white text-left text-sm group-hover:text-red-400">
|
||||
<p className="text-white light:text-theme-text-secondary text-left text-sm group-hover:text-red-400">
|
||||
Delete Selected
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import * as Skeleton from "react-loading-skeleton";
|
||||
import "react-loading-skeleton/dist/skeleton.css";
|
||||
import Workspace from "@/models/workspace";
|
||||
|
@ -8,7 +8,6 @@ import ManageWorkspace, {
|
|||
import paths from "@/utils/paths";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { GearSix, SquaresFour, UploadSimple } from "@phosphor-icons/react";
|
||||
import truncate from "truncate";
|
||||
import useUser from "@/hooks/useUser";
|
||||
import ThreadContainer from "./ThreadContainer";
|
||||
import { Link, useMatch } from "react-router-dom";
|
||||
|
@ -18,9 +17,6 @@ export default function ActiveWorkspaces() {
|
|||
const [loading, setLoading] = useState(true);
|
||||
const [workspaces, setWorkspaces] = useState([]);
|
||||
const [selectedWs, setSelectedWs] = useState(null);
|
||||
const [hoverStates, setHoverStates] = useState({});
|
||||
const [gearHover, setGearHover] = useState({});
|
||||
const [uploadHover, setUploadHover] = useState({});
|
||||
const { showing, showModal, hideModal } = useManageWorkspaceModal();
|
||||
const { user } = useUser();
|
||||
const isInWorkspaceSettings = !!useMatch("/workspace/:slug/settings/:tab");
|
||||
|
@ -33,41 +29,18 @@ export default function ActiveWorkspaces() {
|
|||
}
|
||||
getWorkspaces();
|
||||
}, []);
|
||||
const handleMouseEnter = useCallback((workspaceId) => {
|
||||
setHoverStates((prev) => ({ ...prev, [workspaceId]: true }));
|
||||
}, []);
|
||||
|
||||
const handleMouseLeave = useCallback((workspaceId) => {
|
||||
setHoverStates((prev) => ({ ...prev, [workspaceId]: false }));
|
||||
}, []);
|
||||
const handleGearMouseEnter = useCallback((workspaceId) => {
|
||||
setGearHover((prev) => ({ ...prev, [workspaceId]: true }));
|
||||
}, []);
|
||||
|
||||
const handleGearMouseLeave = useCallback((workspaceId) => {
|
||||
setGearHover((prev) => ({ ...prev, [workspaceId]: false }));
|
||||
}, []);
|
||||
|
||||
const handleUploadMouseEnter = useCallback((workspaceId) => {
|
||||
setUploadHover((prev) => ({ ...prev, [workspaceId]: true }));
|
||||
}, []);
|
||||
|
||||
const handleUploadMouseLeave = useCallback((workspaceId) => {
|
||||
setUploadHover((prev) => ({ ...prev, [workspaceId]: false }));
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<>
|
||||
<Skeleton.default
|
||||
height={36}
|
||||
width="100%"
|
||||
count={3}
|
||||
baseColor="#292524"
|
||||
highlightColor="#4c4948"
|
||||
enableAnimation={true}
|
||||
/>
|
||||
</>
|
||||
<Skeleton.default
|
||||
height={40}
|
||||
width="100%"
|
||||
count={5}
|
||||
baseColor="var(--theme-sidebar-item-default)"
|
||||
highlightColor="var(--theme-sidebar-item-hover)"
|
||||
enableAnimation={true}
|
||||
className="my-1"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -75,81 +48,67 @@ export default function ActiveWorkspaces() {
|
|||
<div role="list" aria-label="Workspaces" className="flex flex-col gap-y-2">
|
||||
{workspaces.map((workspace) => {
|
||||
const isActive = workspace.slug === slug;
|
||||
const isHovered = hoverStates[workspace.id];
|
||||
return (
|
||||
<div
|
||||
className="flex flex-col w-full"
|
||||
onMouseEnter={() => handleMouseEnter(workspace.id)}
|
||||
onMouseLeave={() => handleMouseLeave(workspace.id)}
|
||||
className="flex flex-col w-full group"
|
||||
key={workspace.id}
|
||||
role="listitem"
|
||||
>
|
||||
<div
|
||||
key={workspace.id}
|
||||
className="flex gap-x-2 items-center justify-between"
|
||||
>
|
||||
<div className="flex gap-x-2 items-center justify-between">
|
||||
<a
|
||||
href={isActive ? null : paths.workspace.chat(workspace.slug)}
|
||||
aria-current={isActive ? "page" : ""}
|
||||
className={`
|
||||
transition-all duration-[200ms]
|
||||
flex flex-grow w-[75%] gap-x-2 py-[6px] px-[12px] rounded-[4px] text-white justify-start items-center
|
||||
hover:bg-workspace-item-selected-gradient hover:font-bold border-2 border-outline
|
||||
${
|
||||
isActive
|
||||
? "bg-workspace-item-selected-gradient font-bold"
|
||||
: ""
|
||||
}`}
|
||||
transition-all duration-[200ms]
|
||||
flex flex-grow w-[75%] gap-x-2 py-[6px] px-[12px] rounded-[4px] text-white justify-start items-center
|
||||
bg-theme-sidebar-item-default
|
||||
hover:bg-theme-sidebar-subitem-hover hover:font-bold
|
||||
${isActive ? "bg-theme-sidebar-item-selected font-bold border-2 border-transparent light:border-blue-400" : ""}
|
||||
`}
|
||||
>
|
||||
<div className="flex flex-row justify-between w-full">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="flex items-center space-x-2 overflow-hidden">
|
||||
<SquaresFour
|
||||
weight={isActive ? "fill" : "regular"}
|
||||
className="flex-shrink-0"
|
||||
color={
|
||||
isActive
|
||||
? "var(--theme-sidebar-item-workspace-active)"
|
||||
: "var(--theme-sidebar-item-workspace-inactive)"
|
||||
}
|
||||
size={24}
|
||||
/>
|
||||
<p
|
||||
className={`text-[14px] leading-loose whitespace-nowrap overflow-hidden ${
|
||||
isActive ? "text-white " : "text-zinc-200"
|
||||
}`}
|
||||
>
|
||||
{isActive || isHovered
|
||||
? truncate(workspace.name, 15)
|
||||
: truncate(workspace.name, 20)}
|
||||
</p>
|
||||
</div>
|
||||
{(isActive || isHovered || gearHover[workspace.id]) &&
|
||||
user?.role !== "default" ? (
|
||||
<div className="flex items-center gap-x-[2px]">
|
||||
<div
|
||||
className={`flex hover:bg-[#646768] p-[2px] rounded-[4px] text-[#A7A8A9] hover:text-white ${
|
||||
uploadHover[workspace.id] ? "bg-[#646768]" : ""
|
||||
}`}
|
||||
<div className="w-[130px] overflow-hidden">
|
||||
<p
|
||||
className={`
|
||||
text-[14px] leading-loose whitespace-nowrap overflow-hidden text-white
|
||||
${isActive ? "font-bold" : "font-medium"} truncate
|
||||
w-full group-hover:w-[100px] group-hover:font-bold group-hover:duration-200
|
||||
`}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setSelectedWs(workspace);
|
||||
showModal();
|
||||
}}
|
||||
onMouseEnter={() =>
|
||||
handleUploadMouseEnter(workspace.id)
|
||||
}
|
||||
onMouseLeave={() =>
|
||||
handleUploadMouseLeave(workspace.id)
|
||||
}
|
||||
className="rounded-md flex items-center justify-center ml-auto"
|
||||
>
|
||||
<UploadSimple
|
||||
className="h-[20px] w-[20px]"
|
||||
weight="bold"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<Link
|
||||
{workspace.name}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{user?.role !== "default" && (
|
||||
<div
|
||||
className={`flex items-center gap-x-[2px] transition-opacity duration-200 ${isActive ? "opacity-100" : "opacity-0 group-hover:opacity-100"}`}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setSelectedWs(workspace);
|
||||
showModal();
|
||||
}}
|
||||
className="rounded-md flex items-center justify-center ml-auto p-[2px] hover:bg-[#646768] text-[#A7A8A9] hover:text-white"
|
||||
>
|
||||
<UploadSimple
|
||||
className="h-[20px] w-[20px]"
|
||||
weight="bold"
|
||||
/>
|
||||
</button>
|
||||
<Link
|
||||
to={
|
||||
isInWorkspaceSettings
|
||||
? paths.workspace.chat(workspace.slug)
|
||||
|
@ -157,27 +116,21 @@ export default function ActiveWorkspaces() {
|
|||
workspace.slug
|
||||
)
|
||||
}
|
||||
onMouseEnter={() => handleGearMouseEnter(workspace.id)}
|
||||
onMouseLeave={() => handleGearMouseLeave(workspace.id)}
|
||||
className="rounded-md flex items-center justify-center text-[#A7A8A9] hover:text-white ml-auto"
|
||||
className="rounded-md flex items-center justify-center text-[#A7A8A9] hover:text-white ml-auto p-[2px] hover:bg-[#646768]"
|
||||
aria-label="General appearance settings"
|
||||
>
|
||||
<div className="flex hover:bg-[#646768] p-[2px] rounded-[4px]">
|
||||
<GearSix
|
||||
color={
|
||||
isInWorkspaceSettings && workspace.slug === slug
|
||||
? "#46C8FF"
|
||||
: gearHover[workspace.id]
|
||||
? "#FFFFFF"
|
||||
: "#A7A8A9"
|
||||
}
|
||||
weight="bold"
|
||||
className="h-[20px] w-[20px]"
|
||||
/>
|
||||
</div>
|
||||
<GearSix
|
||||
color={
|
||||
isInWorkspaceSettings && workspace.slug === slug
|
||||
? "#46C8FF"
|
||||
: undefined
|
||||
}
|
||||
weight="bold"
|
||||
className="h-[20px] w-[20px]"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
) : null}
|
||||
)}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,6 @@ import NewWorkspaceModal, {
|
|||
useNewWorkspaceModal,
|
||||
} from "../Modals/NewWorkspace";
|
||||
import ActiveWorkspaces from "./ActiveWorkspaces";
|
||||
import { USER_BACKGROUND_COLOR } from "@/utils/constants";
|
||||
import useLogo from "@/hooks/useLogo";
|
||||
import useUser from "@/hooks/useUser";
|
||||
import Footer from "../Footer";
|
||||
|
@ -39,7 +38,7 @@ export default function Sidebar() {
|
|||
</Link>
|
||||
<div
|
||||
ref={sidebarRef}
|
||||
className="relative m-[16px] rounded-[16px] bg-sidebar border-2 border-outline min-w-[250px] p-[10px] h-[calc(100%-76px)]"
|
||||
className="relative m-[16px] rounded-[16px] bg-theme-bg-sidebar border-[2px] border-theme-sidebar-border light:border-none min-w-[250px] p-[10px] h-[calc(100%-76px)]"
|
||||
>
|
||||
<div className="flex flex-col h-full overflow-x-hidden">
|
||||
<div className="flex-grow flex flex-col min-w-[235px]">
|
||||
|
@ -49,7 +48,7 @@ export default function Sidebar() {
|
|||
{(!user || user?.role !== "default") && (
|
||||
<button
|
||||
onClick={showNewWsModal}
|
||||
className="flex flex-grow w-[75%] h-[44px] gap-x-2 py-[5px] px-2.5 mb-2 bg-white rounded-[8px] text-sidebar justify-center items-center hover:bg-opacity-80 transition-all duration-300"
|
||||
className="light:bg-[#C2E7FE] light:hover:bg-[#C2E7FE]/50 flex flex-grow w-[75%] h-[44px] gap-x-2 py-[5px] px-2.5 mb-2 bg-white rounded-[8px] text-sidebar justify-center items-center hover:bg-opacity-80 transition-all duration-300"
|
||||
>
|
||||
<Plus size={18} weight="bold" />
|
||||
<p className="text-sidebar text-sm font-semibold">
|
||||
|
@ -61,7 +60,7 @@ export default function Sidebar() {
|
|||
<ActiveWorkspaces />
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-0 right-0 pt-4 pb-3 rounded-b-[16px] bg-sidebar bg-opacity-80 backdrop-filter backdrop-blur-md z-10">
|
||||
<div className="absolute bottom-0 left-0 right-0 pt-4 pb-3 rounded-b-[16px] bg-theme-bg-sidebar bg-opacity-80 backdrop-filter backdrop-blur-md z-10">
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -104,11 +103,11 @@ export function SidebarMobileHeader() {
|
|||
<>
|
||||
<div
|
||||
aria-label="Show sidebar"
|
||||
className="fixed top-0 left-0 right-0 z-10 flex justify-between items-center px-4 py-2 bg-sidebar text-slate-200 shadow-lg h-16"
|
||||
className="fixed top-0 left-0 right-0 z-10 flex justify-between items-center px-4 py-2 bg-theme-bg-sidebar light:bg-white text-slate-200 shadow-lg h-16"
|
||||
>
|
||||
<button
|
||||
onClick={() => setShowSidebar(true)}
|
||||
className="rounded-md p-2 flex items-center justify-center text-slate-200"
|
||||
className="rounded-md p-2 flex items-center justify-center text-theme-text-secondary"
|
||||
>
|
||||
<List className="h-6 w-6" />
|
||||
</button>
|
||||
|
@ -133,12 +132,12 @@ export function SidebarMobileHeader() {
|
|||
showBgOverlay
|
||||
? "transition-all opacity-1"
|
||||
: "transition-none opacity-0"
|
||||
} duration-500 fixed top-0 left-0 ${USER_BACKGROUND_COLOR} bg-opacity-75 w-screen h-screen`}
|
||||
} duration-500 fixed top-0 left-0 bg-theme-bg-secondary bg-opacity-75 w-screen h-screen`}
|
||||
onClick={() => setShowSidebar(false)}
|
||||
/>
|
||||
<div
|
||||
ref={sidebarRef}
|
||||
className="relative h-[100vh] fixed top-0 left-0 rounded-r-[26px] bg-sidebar w-[80%] p-[18px] "
|
||||
className="relative h-[100vh] fixed top-0 left-0 rounded-r-[26px] bg-theme-bg-sidebar w-[80%] p-[18px] "
|
||||
>
|
||||
<div className="w-full h-full flex flex-col overflow-x-hidden items-between">
|
||||
{/* Header Information */}
|
||||
|
@ -178,7 +177,7 @@ export function SidebarMobileHeader() {
|
|||
<ActiveWorkspaces />
|
||||
</div>
|
||||
</div>
|
||||
<div className="z-99 absolute bottom-0 left-0 right-0 pt-2 pb-6 rounded-br-[26px] bg-sidebar bg-opacity-80 backdrop-filter backdrop-blur-md">
|
||||
<div className="z-99 absolute bottom-0 left-0 right-0 pt-2 pb-6 rounded-br-[26px] bg-theme-bg-sidebar bg-opacity-80 backdrop-filter backdrop-blur-md">
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -16,7 +16,7 @@ export default function ElevenLabsOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="TTSElevenLabsKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="ElevenLabs API Key"
|
||||
defaultValue={settings?.TTSElevenLabsKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -68,7 +68,7 @@ function ElevenLabsModelSelection({ apiKey, settings }) {
|
|||
<select
|
||||
name="TTSElevenLabsVoiceModel"
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
-- loading available models --
|
||||
|
@ -86,7 +86,7 @@ function ElevenLabsModelSelection({ apiKey, settings }) {
|
|||
<select
|
||||
name="TTSElevenLabsVoiceModel"
|
||||
required={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{Object.keys(groupedModels)
|
||||
.sort()
|
||||
|
|
|
@ -11,7 +11,7 @@ export default function OpenAiGenericTextToSpeechOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="TTSOpenAICompatibleEndpoint"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://localhost:7851/v1"
|
||||
defaultValue={settings?.TTSOpenAICompatibleEndpoint}
|
||||
required={false}
|
||||
|
@ -31,7 +31,7 @@ export default function OpenAiGenericTextToSpeechOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="TTSOpenAICompatibleKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="API Key"
|
||||
defaultValue={
|
||||
settings?.TTSOpenAICompatibleKey ? "*".repeat(20) : ""
|
||||
|
@ -51,7 +51,7 @@ export default function OpenAiGenericTextToSpeechOptions({ settings }) {
|
|||
<input
|
||||
type="text"
|
||||
name="TTSOpenAICompatibleVoiceModel"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Your voice model identifier"
|
||||
defaultValue={settings?.TTSOpenAICompatibleVoiceModel}
|
||||
required={true}
|
||||
|
|
|
@ -16,7 +16,7 @@ export default function OpenAiTextToSpeechOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="TTSOpenAIKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="OpenAI API Key"
|
||||
defaultValue={apiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -31,7 +31,7 @@ export default function OpenAiTextToSpeechOptions({ settings }) {
|
|||
<select
|
||||
name="TTSOpenAIVoiceModel"
|
||||
defaultValue={settings?.TTSOpenAIVoiceModel ?? "alloy"}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{["alloy", "echo", "fable", "onyx", "nova", "shimmer"].map(
|
||||
(voice) => {
|
||||
|
|
|
@ -75,7 +75,7 @@ function PiperTTSModelSelection({ settings }) {
|
|||
name="TTSPiperTTSVoiceModel"
|
||||
value=""
|
||||
disabled={true}
|
||||
className="border-none bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option value="" disabled={true}>
|
||||
-- loading available models --
|
||||
|
@ -97,7 +97,7 @@ function PiperTTSModelSelection({ settings }) {
|
|||
required={true}
|
||||
onChange={(e) => setSelectedVoice(e.target.value)}
|
||||
value={selectedVoice}
|
||||
className="border-none flex-shrink-0 bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="border-none flex-shrink-0 bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{voicesByLanguage(voices).map(([lang, voices]) => {
|
||||
return (
|
||||
|
@ -202,8 +202,8 @@ function DemoVoiceSample({ voiceId }) {
|
|||
</>
|
||||
) : (
|
||||
<>
|
||||
<PlayCircle size={20} className="flex-shrink-0" />
|
||||
<p className="text-sm flex-shrink-0">Play sample</p>
|
||||
<PlayCircle size={20} className="flex-shrink-0 text-white" />
|
||||
<p className="text-white text-sm flex-shrink-0">Play sample</p>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
|
|
@ -18,7 +18,7 @@ export default function NativeTranscriptionOptions({ settings }) {
|
|||
name="WhisperModelPref"
|
||||
defaultValue={model}
|
||||
onChange={(e) => setModel(e.target.value)}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
{["Xenova/whisper-small", "Xenova/whisper-large"].map(
|
||||
(value, i) => {
|
||||
|
|
|
@ -13,7 +13,7 @@ export default function OpenAiWhisperOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="OpenAiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="OpenAI API Key"
|
||||
defaultValue={settings?.OpenAiKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -29,7 +29,7 @@ export default function OpenAiWhisperOptions({ settings }) {
|
|||
</label>
|
||||
<select
|
||||
disabled={true}
|
||||
className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5"
|
||||
>
|
||||
<option disabled={true} selected={true}>
|
||||
Whisper Large
|
||||
|
|
|
@ -13,7 +13,7 @@ const UserIcon = memo(({ role }) => {
|
|||
<img
|
||||
src={WorkspaceDefaultPfp}
|
||||
alt="system profile picture"
|
||||
className="flex items-center justify-center rounded-full border border-white/40"
|
||||
className="flex items-center justify-center rounded-full border border-white/40 light:border-theme-sidebar-border light:bg-theme-bg-chat-input"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -4,6 +4,8 @@ import System from "@/models/system";
|
|||
import { AUTH_USER } from "@/utils/constants";
|
||||
import showToast from "@/utils/toast";
|
||||
import { Plus, X } from "@phosphor-icons/react";
|
||||
import ModalWrapper from "@/components/ModalWrapper";
|
||||
import { useTheme } from "@/hooks/useTheme";
|
||||
|
||||
export default function AccountModal({ user, hideModal }) {
|
||||
const { pfp, setPfp } = usePfp();
|
||||
|
@ -61,122 +63,131 @@ export default function AccountModal({ user, hideModal }) {
|
|||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
id="account-modal"
|
||||
className="bg-black/60 backdrop-blur-sm fixed top-0 left-0 outline-none w-screen h-screen flex items-center justify-center"
|
||||
>
|
||||
<div className="relative w-[500px] max-w-2xl max-h-full bg-main-gradient rounded-lg shadow">
|
||||
<div className="flex items-start justify-between p-4 border-b rounded-t border-gray-500/50">
|
||||
<h3 className="text-xl font-semibold text-white">Edit Account</h3>
|
||||
<ModalWrapper isOpen={true}>
|
||||
<div className="w-full max-w-2xl bg-theme-bg-secondary rounded-lg shadow border-2 border-theme-modal-border overflow-hidden">
|
||||
<div className="relative p-6 border-b rounded-t border-theme-modal-border">
|
||||
<div className="w-full flex gap-x-2 items-center">
|
||||
<h3 className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap">
|
||||
Edit Account
|
||||
</h3>
|
||||
</div>
|
||||
<button
|
||||
onClick={hideModal}
|
||||
type="button"
|
||||
className="text-gray-400 bg-transparent hover:border-white/60 rounded-lg p-1.5 ml-auto inline-flex items-center hover:bg-menu-item-selected-gradient hover:border-slate-100 border-transparent"
|
||||
className="absolute top-4 right-4 transition-all duration-300 bg-transparent rounded-lg text-sm p-1 inline-flex items-center hover:bg-theme-modal-border hover:border-theme-modal-border hover:border-opacity-50 border-transparent border"
|
||||
>
|
||||
<X className="text-lg" />
|
||||
<X size={24} weight="bold" className="text-white" />
|
||||
</button>
|
||||
</div>
|
||||
<form onSubmit={handleUpdate} className="space-y-6">
|
||||
<div className="flex flex-col md:flex-row items-center justify-center gap-8">
|
||||
<div className="flex flex-col items-center">
|
||||
<label className="w-48 h-48 flex flex-col items-center justify-center bg-zinc-900/50 transition-all duration-300 rounded-full mt-8 border-2 border-dashed border-white border-opacity-60 cursor-pointer hover:opacity-60">
|
||||
<input
|
||||
id="logo-upload"
|
||||
type="file"
|
||||
accept="image/*"
|
||||
className="hidden"
|
||||
onChange={handleFileUpload}
|
||||
/>
|
||||
{pfp ? (
|
||||
<img
|
||||
src={pfp}
|
||||
alt="User profile picture"
|
||||
className="w-48 h-48 rounded-full object-cover bg-white"
|
||||
<div
|
||||
className="h-full w-full overflow-y-auto"
|
||||
style={{ maxHeight: "calc(100vh - 200px)" }}
|
||||
>
|
||||
<form onSubmit={handleUpdate} className="space-y-6">
|
||||
<div className="flex flex-col md:flex-row items-center justify-center gap-8">
|
||||
<div className="flex flex-col items-center">
|
||||
<label className="group w-48 h-48 flex flex-col items-center justify-center bg-theme-bg-primary hover:bg-theme-bg-secondary transition-colors duration-300 rounded-full mt-8 border-2 border-dashed border-white light:border-[#686C6F] light:bg-[#E0F2FE] light:hover:bg-transparent cursor-pointer hover:opacity-60">
|
||||
<input
|
||||
id="logo-upload"
|
||||
type="file"
|
||||
accept="image/*"
|
||||
className="hidden"
|
||||
onChange={handleFileUpload}
|
||||
/>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center p-3">
|
||||
<Plus className="w-8 h-8 text-white/80 m-2" />
|
||||
<span className="text-white text-opacity-80 text-sm font-semibold">
|
||||
Profile Picture
|
||||
</span>
|
||||
<span className="text-white text-opacity-60 text-xs">
|
||||
800 x 800
|
||||
</span>
|
||||
</div>
|
||||
{pfp ? (
|
||||
<img
|
||||
src={pfp}
|
||||
alt="User profile picture"
|
||||
className="w-48 h-48 rounded-full object-cover bg-white"
|
||||
/>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center p-3">
|
||||
<Plus className="w-8 h-8 text-theme-text-secondary m-2" />
|
||||
<span className="text-theme-text-secondary text-opacity-80 text-sm font-semibold">
|
||||
Profile Picture
|
||||
</span>
|
||||
<span className="text-theme-text-secondary text-opacity-60 text-xs">
|
||||
800 x 800
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</label>
|
||||
{pfp && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleRemovePfp}
|
||||
className="mt-3 text-theme-text-secondary text-opacity-60 text-sm font-medium hover:underline"
|
||||
>
|
||||
Remove Profile Picture
|
||||
</button>
|
||||
)}
|
||||
</label>
|
||||
{pfp && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleRemovePfp}
|
||||
className="mt-3 text-white text-opacity-60 text-sm font-medium hover:underline"
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-y-4 px-6">
|
||||
<div>
|
||||
<label
|
||||
htmlFor="username"
|
||||
className="block mb-2 text-sm font-medium text-theme-text-primary"
|
||||
>
|
||||
Remove Profile Picture
|
||||
</button>
|
||||
)}
|
||||
Username
|
||||
</label>
|
||||
<input
|
||||
name="username"
|
||||
type="text"
|
||||
className="bg-theme-settings-input-bg placeholder:text-theme-settings-input-placeholder border-gray-500 text-white text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="User's username"
|
||||
minLength={2}
|
||||
defaultValue={user.username}
|
||||
required
|
||||
autoComplete="off"
|
||||
/>
|
||||
<p className="mt-2 text-xs text-white/60">
|
||||
Username must be only contain lowercase letters, numbers,
|
||||
underscores, and hyphens with no spaces
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="password"
|
||||
className="block mb-2 text-sm font-medium text-white"
|
||||
>
|
||||
New Password
|
||||
</label>
|
||||
<input
|
||||
name="password"
|
||||
type="text"
|
||||
className="bg-theme-settings-input-bg placeholder:text-theme-settings-input-placeholder border-gray-500 text-white text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder={`${user.username}'s new password`}
|
||||
minLength={8}
|
||||
/>
|
||||
<p className="mt-2 text-xs text-white/60">
|
||||
Password must be at least 8 characters long
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-row gap-x-8">
|
||||
<ThemePreference />
|
||||
<LanguagePreference />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-y-4 px-6">
|
||||
<div>
|
||||
<label
|
||||
htmlFor="username"
|
||||
className="block mb-2 text-sm font-medium text-white"
|
||||
<div className="flex justify-between items-center border-t border-theme-modal-border pt-4 p-6">
|
||||
<button
|
||||
onClick={hideModal}
|
||||
type="button"
|
||||
className="transition-all duration-300 text-white hover:bg-zinc-700 px-4 py-2 rounded-lg text-sm"
|
||||
>
|
||||
Username
|
||||
</label>
|
||||
<input
|
||||
name="username"
|
||||
type="text"
|
||||
className="bg-zinc-900 placeholder:text-white/20 border-gray-500 text-white text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
|
||||
placeholder="User's username"
|
||||
minLength={2}
|
||||
defaultValue={user.username}
|
||||
required
|
||||
autoComplete="off"
|
||||
/>
|
||||
<p className="mt-2 text-xs text-white/60">
|
||||
Username must only contain lowercase letters, numbers,
|
||||
underscores, and hyphens with no spaces
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="password"
|
||||
className="block mb-2 text-sm font-medium text-white"
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm"
|
||||
>
|
||||
New Password
|
||||
</label>
|
||||
<input
|
||||
name="password"
|
||||
type="text"
|
||||
className="bg-zinc-900 placeholder:text-white/20 border-gray-500 text-white text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
|
||||
placeholder={`${user.username}'s new password`}
|
||||
minLength={8}
|
||||
/>
|
||||
<p className="mt-2 text-xs text-white/60">
|
||||
Password must be at least 8 characters long
|
||||
</p>
|
||||
Update Account
|
||||
</button>
|
||||
</div>
|
||||
<LanguagePreference />
|
||||
</div>
|
||||
<div className="flex justify-between items-center border-t border-gray-500/50 pt-4 p-6">
|
||||
<button
|
||||
onClick={hideModal}
|
||||
type="button"
|
||||
className="px-4 py-2 rounded-lg text-white bg-transparent hover:bg-stone-900"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="px-4 py-2 rounded-lg text-white bg-transparent border border-slate-200 hover:bg-slate-200 hover:text-slate-800"
|
||||
>
|
||||
Update Account
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -198,7 +209,7 @@ function LanguagePreference() {
|
|||
</label>
|
||||
<select
|
||||
name="userLang"
|
||||
className="bg-zinc-900 w-fit mt-2 px-4 border-gray-500 text-white text-sm rounded-lg block py-2"
|
||||
className="bg-theme-settings-input-bg w-fit mt-2 px-4 focus:outline-primary-button active:outline-primary-button outline-none text-white text-sm rounded-lg block py-2"
|
||||
defaultValue={currentLanguage || "en"}
|
||||
onChange={(e) => changeLanguage(e.target.value)}
|
||||
>
|
||||
|
@ -213,3 +224,30 @@ function LanguagePreference() {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ThemePreference() {
|
||||
const { theme, setTheme, availableThemes } = useTheme();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<label
|
||||
htmlFor="theme"
|
||||
className="block mb-2 text-sm font-medium text-white"
|
||||
>
|
||||
Theme Preference
|
||||
</label>
|
||||
<select
|
||||
name="theme"
|
||||
value={theme}
|
||||
onChange={(e) => setTheme(e.target.value)}
|
||||
className="bg-theme-settings-input-bg w-fit px-4 focus:outline-primary-button active:outline-primary-button outline-none text-white text-sm rounded-lg block py-2"
|
||||
>
|
||||
{Object.entries(availableThemes).map(([key, value]) => (
|
||||
<option key={key} value={key}>
|
||||
{value}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -54,12 +54,12 @@ export default function UserButton() {
|
|||
|
||||
if (mode === null) return null;
|
||||
return (
|
||||
<div className="absolute top-3 right-4 md:top-9 md:right-10 w-fit h-fit z-99">
|
||||
<div className="absolute top-3 right-4 md:top-9 md:right-10 w-fit h-fit z-40">
|
||||
<button
|
||||
ref={buttonRef}
|
||||
onClick={() => setShowMenu(!showMenu)}
|
||||
type="button"
|
||||
className="uppercase transition-all duration-300 w-[35px] h-[35px] text-base font-semibold rounded-full flex items-center bg-sidebar-button hover:bg-menu-item-selected-gradient justify-center text-white p-2 hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
className="uppercase transition-all duration-300 w-[35px] h-[35px] text-base font-semibold rounded-full flex items-center bg-theme-action-menu-bg hover:bg-theme-action-menu-item-hover justify-center text-white p-2 hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
>
|
||||
{mode === "multi" ? <UserDisplay /> : <Person size={14} />}
|
||||
</button>
|
||||
|
@ -67,20 +67,20 @@ export default function UserButton() {
|
|||
{showMenu && (
|
||||
<div
|
||||
ref={menuRef}
|
||||
className="w-fit rounded-lg absolute top-12 right-0 bg-sidebar p-4 flex items-center-justify-center"
|
||||
className="w-fit rounded-lg absolute top-12 right-0 bg-theme-action-menu-bg p-2 flex items-center-justify-center"
|
||||
>
|
||||
<div className="flex flex-col gap-y-2">
|
||||
{mode === "multi" && !!user && (
|
||||
<button
|
||||
onClick={handleOpenAccountModal}
|
||||
className="text-white hover:bg-slate-200/20 w-full text-left px-4 py-1.5 rounded-md"
|
||||
className="text-white hover:bg-theme-action-menu-item-hover w-full text-left px-4 py-1.5 rounded-md"
|
||||
>
|
||||
Account
|
||||
</button>
|
||||
)}
|
||||
<a
|
||||
href={supportEmail}
|
||||
className="text-white hover:bg-slate-200/20 w-full text-left px-4 py-1.5 rounded-md"
|
||||
className="text-white hover:bg-theme-action-menu-item-hover w-full text-left px-4 py-1.5 rounded-md"
|
||||
>
|
||||
Support
|
||||
</a>
|
||||
|
@ -92,7 +92,7 @@ export default function UserButton() {
|
|||
window.location.replace(paths.home());
|
||||
}}
|
||||
type="button"
|
||||
className="text-white hover:bg-slate-200/20 w-full text-left px-4 py-1.5 rounded-md"
|
||||
className="text-white hover:bg-theme-action-menu-item-hover w-full text-left px-4 py-1.5 rounded-md"
|
||||
>
|
||||
Sign out
|
||||
</button>
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function AstraDBOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="AstraDBEndpoint"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Astra DB API endpoint"
|
||||
defaultValue={settings?.AstraDBEndpoint}
|
||||
required={true}
|
||||
|
@ -25,7 +25,7 @@ export default function AstraDBOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="AstraDBApplicationToken"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="AstraCS:..."
|
||||
defaultValue={
|
||||
settings?.AstraDBApplicationToken ? "*".repeat(20) : ""
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function ChromaDBOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="ChromaEndpoint"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://localhost:8000"
|
||||
defaultValue={settings?.ChromaEndpoint}
|
||||
required={true}
|
||||
|
@ -27,7 +27,7 @@ export default function ChromaDBOptions({ settings }) {
|
|||
autoComplete="off"
|
||||
type="text"
|
||||
defaultValue={settings?.ChromaApiHeader}
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="X-Api-Key"
|
||||
/>
|
||||
</div>
|
||||
|
@ -41,7 +41,7 @@ export default function ChromaDBOptions({ settings }) {
|
|||
autoComplete="off"
|
||||
type="password"
|
||||
defaultValue={settings?.ChromaApiKey ? "*".repeat(20) : ""}
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="sk-myApiKeyToAccessMyChromaInstance"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function MilvusDBOptions({ settings }) {
|
|||
<input
|
||||
type="text"
|
||||
name="MilvusAddress"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://localhost:19530"
|
||||
defaultValue={settings?.MilvusAddress}
|
||||
required={true}
|
||||
|
@ -25,7 +25,7 @@ export default function MilvusDBOptions({ settings }) {
|
|||
<input
|
||||
type="text"
|
||||
name="MilvusUsername"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="username"
|
||||
defaultValue={settings?.MilvusUsername}
|
||||
autoComplete="off"
|
||||
|
@ -39,7 +39,7 @@ export default function MilvusDBOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="MilvusPassword"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="password"
|
||||
defaultValue={settings?.MilvusPassword ? "*".repeat(20) : ""}
|
||||
autoComplete="off"
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function PineconeDBOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="PineConeKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Pinecone API Key"
|
||||
defaultValue={settings?.PineConeKey ? "*".repeat(20) : ""}
|
||||
required={true}
|
||||
|
@ -24,7 +24,7 @@ export default function PineconeDBOptions({ settings }) {
|
|||
<input
|
||||
type="text"
|
||||
name="PineConeIndex"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="my-index"
|
||||
defaultValue={settings?.PineConeIndex}
|
||||
required={true}
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function QDrantDBOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="QdrantEndpoint"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://localhost:6633"
|
||||
defaultValue={settings?.QdrantEndpoint}
|
||||
required={true}
|
||||
|
@ -25,7 +25,7 @@ export default function QDrantDBOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="QdrantApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="wOeqxsYP4....1244sba"
|
||||
defaultValue={settings?.QdrantApiKey}
|
||||
autoComplete="off"
|
||||
|
|
|
@ -9,8 +9,8 @@ export default function VectorDBItem({
|
|||
return (
|
||||
<div
|
||||
onClick={() => onClick(value)}
|
||||
className={`w-full p-2 rounded-md hover:cursor-pointer hover:bg-white/10 ${
|
||||
checked ? "bg-white/10" : ""
|
||||
className={`w-full p-2 rounded-md hover:cursor-pointer hover:bg-theme-bg-secondary ${
|
||||
checked ? "bg-theme-bg-secondary" : ""
|
||||
}`}
|
||||
>
|
||||
<input
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function WeaviateDBOptions({ settings }) {
|
|||
<input
|
||||
type="url"
|
||||
name="WeaviateEndpoint"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="http://localhost:8080"
|
||||
defaultValue={settings?.WeaviateEndpoint}
|
||||
required={true}
|
||||
|
@ -25,7 +25,7 @@ export default function WeaviateDBOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="WeaviateApiKey"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="sk-123Abcweaviate"
|
||||
defaultValue={settings?.WeaviateApiKey}
|
||||
autoComplete="off"
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function ZillizCloudOptions({ settings }) {
|
|||
<input
|
||||
type="text"
|
||||
name="ZillizEndpoint"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="https://sample.api.gcp-us-west1.zillizcloud.com"
|
||||
defaultValue={settings?.ZillizEndpoint}
|
||||
required={true}
|
||||
|
@ -25,7 +25,7 @@ export default function ZillizCloudOptions({ settings }) {
|
|||
<input
|
||||
type="password"
|
||||
name="ZillizApiToken"
|
||||
className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
className="bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="Zilliz cluster API Token"
|
||||
defaultValue={settings?.ZillizApiToken ? "*".repeat(20) : ""}
|
||||
autoComplete="off"
|
||||
|
|
|
@ -44,9 +44,9 @@ export default function Citations({ sources = [] }) {
|
|||
<div className="flex flex-col mt-4 justify-left">
|
||||
<button
|
||||
onClick={() => setOpen(!open)}
|
||||
className={`text-white/50 font-medium italic text-sm text-left ml-14 pt-2 ${
|
||||
className={`text-white/50 light:text-black/50 font-medium italic text-sm text-left ml-14 pt-2 ${
|
||||
open ? "pb-2" : ""
|
||||
} hover:text-white/75 transition-all duration-300`}
|
||||
} hover:text-white/75 hover:light:text-black/75 transition-all duration-300`}
|
||||
>
|
||||
{open ? "Hide Citations" : "Show Citations"}
|
||||
<CaretRight
|
||||
|
@ -96,24 +96,6 @@ const Citation = memo(({ source, onClick }) => {
|
|||
);
|
||||
});
|
||||
|
||||
function SkeletonLine() {
|
||||
const numOfBoxes = Math.floor(Math.random() * 5) + 2;
|
||||
return (
|
||||
<div className="flex space-x-2 mb-2">
|
||||
{Array.from({ length: numOfBoxes }).map((_, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="bg-white/20 rounded"
|
||||
style={{
|
||||
width: `${Math.random() * 150 + 50}px`,
|
||||
height: "20px",
|
||||
}}
|
||||
></div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function omitChunkHeader(text) {
|
||||
if (!text.startsWith("<document_metadata>")) return text;
|
||||
return text.split("</document_metadata>")[1].trim();
|
||||
|
@ -125,8 +107,8 @@ function CitationDetailModal({ source, onClose }) {
|
|||
|
||||
return (
|
||||
<ModalWrapper isOpen={source}>
|
||||
<div className="w-full max-w-2xl bg-main-gradient rounded-lg shadow border border-white/10 overflow-hidden">
|
||||
<div className="relative p-6 border-b rounded-t border-gray-500/50">
|
||||
<div className="w-full max-w-2xl bg-theme-bg-secondary rounded-lg shadow border-2 border-theme-modal-border overflow-hidden">
|
||||
<div className="relative p-6 border-b rounded-t border-theme-modal-border">
|
||||
<div className="w-full flex gap-x-2 items-center">
|
||||
{isUrl ? (
|
||||
<a
|
||||
|
@ -154,43 +136,42 @@ function CitationDetailModal({ source, onClose }) {
|
|||
<button
|
||||
onClick={onClose}
|
||||
type="button"
|
||||
className="absolute top-6 right-6 transition-all duration-300 text-gray-400 bg-transparent hover:border-white/60 rounded-lg text-sm p-1.5 inline-flex items-center bg-sidebar-button hover:bg-menu-item-selected-gradient hover:border-slate-100 hover:border-opacity-50 border-transparent border"
|
||||
className="absolute top-4 right-4 transition-all duration-300 bg-transparent rounded-lg text-sm p-1 inline-flex items-center hover:bg-theme-modal-border hover:border-theme-modal-border hover:border-opacity-50 border-transparent border"
|
||||
>
|
||||
<X className="text-gray-300 text-lg" />
|
||||
<X size={24} weight="bold" className="text-white" />
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="h-full w-full overflow-y-auto"
|
||||
style={{ maxHeight: "calc(100vh - 200px)" }}
|
||||
>
|
||||
<div className="p-6 space-y-2 flex-col">
|
||||
{[...Array(3)].map((_, idx) => (
|
||||
<SkeletonLine key={idx} />
|
||||
))}
|
||||
<div className="py-7 px-9 space-y-2 flex-col">
|
||||
{chunks.map(({ text, score }, idx) => (
|
||||
<div key={idx} className="pt-6 text-white">
|
||||
<div className="flex flex-col w-full justify-start pb-6 gap-y-1">
|
||||
<p className="text-white whitespace-pre-line">
|
||||
{HTMLDecode(omitChunkHeader(text))}
|
||||
</p>
|
||||
<>
|
||||
<div key={idx} className="pt-6 text-white">
|
||||
<div className="flex flex-col w-full justify-start pb-6 gap-y-1">
|
||||
<p className="text-white whitespace-pre-line">
|
||||
{HTMLDecode(omitChunkHeader(text))}
|
||||
</p>
|
||||
|
||||
{!!score && (
|
||||
<div className="w-full flex items-center text-xs text-white/60 gap-x-2 cursor-default">
|
||||
<div
|
||||
data-tooltip-id="similarity-score"
|
||||
data-tooltip-content={`This is the semantic similarity score of this chunk of text compared to your query calculated by the vector database.`}
|
||||
className="flex items-center gap-x-1"
|
||||
>
|
||||
<Info size={14} />
|
||||
<p>{toPercentString(score)} match</p>
|
||||
{!!score && (
|
||||
<div className="w-full flex items-center text-xs text-white/60 gap-x-2 cursor-default">
|
||||
<div
|
||||
data-tooltip-id="similarity-score"
|
||||
data-tooltip-content={`This is the semantic similarity score of this chunk of text compared to your query calculated by the vector database.`}
|
||||
className="flex items-center gap-x-1"
|
||||
>
|
||||
<Info size={14} />
|
||||
<p>{toPercentString(score)} match</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{[...Array(3)].map((_, idx) => (
|
||||
<SkeletonLine key={idx} />
|
||||
))}
|
||||
</div>
|
||||
{idx !== chunks.length - 1 && (
|
||||
<hr className="border-theme-modal-border" />
|
||||
)}
|
||||
</>
|
||||
))}
|
||||
<div className="mb-6"></div>
|
||||
</div>
|
||||
|
|
|
@ -38,7 +38,7 @@ function ActionMenu({ chatId, forkThread, isEditing, role }) {
|
|||
<div className="mt-2 -ml-0.5 relative" ref={menuRef}>
|
||||
<button
|
||||
onClick={toggleMenu}
|
||||
className="border-none text-zinc-300 hover:text-zinc-100 transition-colors duration-200"
|
||||
className="border-none text-[var(--theme-sidebar-footer-icon-fill)] hover:text-[var(--theme-sidebar-footer-icon-fill)] transition-colors duration-200"
|
||||
data-tooltip-id="action-menu"
|
||||
data-tooltip-content="More actions"
|
||||
aria-label="More actions"
|
||||
|
@ -46,17 +46,17 @@ function ActionMenu({ chatId, forkThread, isEditing, role }) {
|
|||
<DotsThreeVertical size={24} weight="bold" />
|
||||
</button>
|
||||
{open && (
|
||||
<div className="absolute -top-1 left-7 mt-1 border-[1.5px] border-white/40 rounded-lg bg-[#41454B] bg-opacity-100 flex flex-col shadow-[0_4px_14px_rgba(0,0,0,0.25)] text-white z-99 md:z-10">
|
||||
<div className="absolute -top-1 left-7 mt-1 border-[1.5px] border-white/40 rounded-lg bg-theme-action-menu-bg flex flex-col shadow-[0_4px_14px_rgba(0,0,0,0.25)] text-white z-99 md:z-10">
|
||||
<button
|
||||
onClick={handleFork}
|
||||
className="border-none flex items-center gap-x-2 hover:bg-white/10 py-1.5 px-2 transition-colors duration-200 w-full text-left"
|
||||
className="border-none flex items-center gap-x-2 hover:bg-theme-action-menu-item-hover py-1.5 px-2 transition-colors duration-200 w-full text-left"
|
||||
>
|
||||
<TreeView size={18} />
|
||||
<span className="text-sm">Fork</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={handleDelete}
|
||||
className="border-none flex items-center gap-x-2 hover:bg-white/10 py-1.5 px-2 transition-colors duration-200 w-full text-left"
|
||||
className="border-none flex items-center gap-x-2 hover:bg-theme-action-menu-item-hover py-1.5 px-2 transition-colors duration-200 w-full text-left"
|
||||
>
|
||||
<Trash size={18} />
|
||||
<span className="text-sm">Delete</span>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { AI_BACKGROUND_COLOR, USER_BACKGROUND_COLOR } from "@/utils/constants";
|
||||
import { Pencil } from "@phosphor-icons/react";
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
|
||||
|
@ -52,7 +51,11 @@ export function EditMessageAction({ chatId = null, role, isEditing }) {
|
|||
className="border-none text-zinc-300"
|
||||
aria-label={`Edit ${role === "user" ? "Prompt" : "Response"}`}
|
||||
>
|
||||
<Pencil size={21} className="mb-1" />
|
||||
<Pencil
|
||||
color="var(--theme-sidebar-footer-icon-fill)"
|
||||
size={21}
|
||||
className="mb-1"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
@ -95,9 +98,7 @@ export function EditMessageForm({
|
|||
<textarea
|
||||
ref={formRef}
|
||||
name="editedMessage"
|
||||
className={`w-full rounded ${
|
||||
role === "user" ? USER_BACKGROUND_COLOR : AI_BACKGROUND_COLOR
|
||||
} border border-white/20 active:outline-none focus:outline-none focus:ring-0 pr-16 pl-1.5 pt-1.5 resize-y`}
|
||||
className="w-full rounded bg-theme-bg-secondary border border-white/20 active:outline-none focus:outline-none focus:ring-0 pr-16 pl-1.5 pt-1.5 resize-y"
|
||||
defaultValue={message}
|
||||
onChange={adjustTextArea}
|
||||
/>
|
||||
|
@ -110,7 +111,7 @@ export function EditMessageForm({
|
|||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="px-2 py-1 bg-historical-msg-system text-white font-medium rounded-md hover:bg-historical-msg-user/90 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2"
|
||||
className="px-2 py-1 bg-historical-msg-system text-white font-medium rounded-md hover:bg-historical-msg-user/90 light:hover:text-white focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2"
|
||||
onClick={cancelEdits}
|
||||
>
|
||||
Cancel
|
||||
|
|
|
@ -60,7 +60,7 @@ export default function AsyncTTSMessage({ slug, chatId }) {
|
|||
data-tooltip-content={
|
||||
speaking ? "Pause TTS speech of message" : "TTS Speak message"
|
||||
}
|
||||
className="border-none text-zinc-300"
|
||||
className="border-none text-[var(--theme-sidebar-footer-icon-fill)]"
|
||||
aria-label={speaking ? "Pause speech" : "Speak message"}
|
||||
>
|
||||
{speaking ? (
|
||||
|
|
|
@ -40,7 +40,7 @@ export default function NativeTTSMessage({ message }) {
|
|||
data-tooltip-content={
|
||||
speaking ? "Pause TTS speech of message" : "TTS Speak message"
|
||||
}
|
||||
className="border-none text-zinc-300"
|
||||
className="border-none text-[var(--theme-sidebar-footer-icon-fill)]"
|
||||
aria-label={speaking ? "Pause speech" : "Speak message"}
|
||||
>
|
||||
{speaking ? (
|
||||
|
|
|
@ -57,7 +57,7 @@ export default function PiperTTS({ voiceId = null, message }) {
|
|||
data-tooltip-content={
|
||||
speaking ? "Pause TTS speech of message" : "TTS Speak message"
|
||||
}
|
||||
className="border-none text-zinc-300"
|
||||
className="border-none text-[var(--theme-sidebar-footer-icon-fill)]"
|
||||
aria-label={speaking ? "Pause speech" : "Speak message"}
|
||||
>
|
||||
{speaking ? (
|
||||
|
|
|
@ -78,6 +78,7 @@ function FeedbackButton({
|
|||
aria-label={tooltipContent}
|
||||
>
|
||||
<IconComponent
|
||||
color="var(--theme-sidebar-footer-icon-fill)"
|
||||
size={20}
|
||||
className="mb-1"
|
||||
weight={isSelected ? "fill" : "regular"}
|
||||
|
@ -101,9 +102,17 @@ function CopyMessage({ message }) {
|
|||
aria-label="Copy"
|
||||
>
|
||||
{copied ? (
|
||||
<Check size={20} className="mb-1" />
|
||||
<Check
|
||||
color="var(--theme-sidebar-footer-icon-fill)"
|
||||
size={20}
|
||||
className="mb-1"
|
||||
/>
|
||||
) : (
|
||||
<Copy size={20} className="mb-1" />
|
||||
<Copy
|
||||
color="var(--theme-sidebar-footer-icon-fill)"
|
||||
size={20}
|
||||
className="mb-1"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -122,7 +131,12 @@ function RegenerateMessage({ regenerateMessage, chatId }) {
|
|||
className="border-none text-zinc-300"
|
||||
aria-label="Regenerate"
|
||||
>
|
||||
<ArrowsClockwise size={20} className="mb-1" weight="fill" />
|
||||
<ArrowsClockwise
|
||||
color="var(--theme-sidebar-footer-icon-fill)"
|
||||
size={20}
|
||||
className="mb-1"
|
||||
weight="fill"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue