mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2024-11-13 02:00:10 +01:00
[FEAT] Normalize UI for CTA buttons/UX improvements (#1021)
* members workspace settings menu and admin users UI updates * implement CTAButton in all general/admin settings + ui tweaks * move CTAButton to components/lib * fix UI for security page to match rest of all settings pages * UX improvements * add CTAButton component * prevent components folder from being ignored * patch some UI fixes --------- Co-authored-by: timothycarambat <rambat1010@gmail.com>
This commit is contained in:
parent
a2923e35e8
commit
657be7ecfc
1
frontend/.gitignore
vendored
1
frontend/.gitignore
vendored
@ -12,6 +12,7 @@ dist
|
||||
lib
|
||||
dist-ssr
|
||||
*.local
|
||||
!frontend/components/lib
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
|
16
frontend/src/components/lib/CTAButton/index.jsx
Normal file
16
frontend/src/components/lib/CTAButton/index.jsx
Normal file
@ -0,0 +1,16 @@
|
||||
export default function CTAButton({
|
||||
children,
|
||||
disabled = false,
|
||||
onClick,
|
||||
className = "",
|
||||
}) {
|
||||
return (
|
||||
<button
|
||||
disabled={disabled}
|
||||
onClick={() => onClick?.()}
|
||||
className={`text-xs px-4 py-1 font-semibold rounded-lg bg-[#46C8FF] hover:bg-[#2C2F36] hover:text-white h-[34px] -mr-8 whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)] w-fit ${className}`}
|
||||
>
|
||||
<div className="flex items-center justify-center gap-2">{children}</div>
|
||||
</button>
|
||||
);
|
||||
}
|
@ -10,6 +10,7 @@ import InviteRow from "./InviteRow";
|
||||
import NewInviteModal from "./NewInviteModal";
|
||||
import { useModal } from "@/hooks/useModal";
|
||||
import ModalWrapper from "@/components/ModalWrapper";
|
||||
import CTAButton from "@/components/lib/CTAButton";
|
||||
|
||||
export default function AdminInvites() {
|
||||
const { isOpen, openModal, closeModal } = useModal();
|
||||
@ -21,25 +22,24 @@ export default function AdminInvites() {
|
||||
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 h-full overflow-y-scroll"
|
||||
>
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[86px] md:py-6 py-16">
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="items-center flex gap-x-4">
|
||||
<p className="text-lg leading-6 font-bold text-white">
|
||||
Invitations
|
||||
</p>
|
||||
<button
|
||||
onClick={openModal}
|
||||
className="flex items-center gap-x-2 px-4 py-2 rounded-lg bg-[#2C2F36] text-white text-sm hover:bg-[#3D4147] shadow-md border border-[#3D4147]"
|
||||
>
|
||||
<EnvelopeSimple className="h-4 w-4" />
|
||||
Create Invite Link
|
||||
</button>
|
||||
</div>
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
|
||||
Create invitation links for people in your organization to accept
|
||||
and sign up with. Invitations can only be used by a single user.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full justify-end flex">
|
||||
<CTAButton onClick={openModal} className="mt-3 mr-0 -mb-12 z-10">
|
||||
<EnvelopeSimple className="h-4 w-4" weight="bold" /> Create Invite
|
||||
Link
|
||||
</CTAButton>
|
||||
</div>
|
||||
<InvitationsContainer />
|
||||
</div>
|
||||
<ModalWrapper isOpen={isOpen}>
|
||||
|
@ -6,6 +6,7 @@ import { isMobile } from "react-device-detect";
|
||||
import * as Skeleton from "react-loading-skeleton";
|
||||
import LogRow from "./LogRow";
|
||||
import showToast from "@/utils/toast";
|
||||
import CTAButton from "@/components/lib/CTAButton";
|
||||
|
||||
export default function AdminLogs() {
|
||||
const handleResetLogs = async () => {
|
||||
@ -32,24 +33,26 @@ export default function AdminLogs() {
|
||||
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 h-full overflow-y-scroll"
|
||||
>
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[86px] md:py-6 py-16">
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="flex gap-x-4 items-center">
|
||||
<p className="text-lg leading-6 font-bold text-white">
|
||||
Event Logs
|
||||
</p>
|
||||
<button
|
||||
onClick={handleResetLogs}
|
||||
className="flex items-center gap-x-2 px-4 py-2 rounded-lg bg-[#2C2F36] text-white text-sm hover:bg-[#3D4147] shadow-md border border-[#3D4147]"
|
||||
>
|
||||
Clear event logs
|
||||
</button>
|
||||
</div>
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
|
||||
View all actions and events happening on this instance for
|
||||
monitoring.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full justify-end flex">
|
||||
<CTAButton
|
||||
onClick={handleResetLogs}
|
||||
className="mt-3 mr-0 -mb-14 z-10"
|
||||
>
|
||||
Clear Event Logs
|
||||
</CTAButton>
|
||||
</div>
|
||||
<LogsContainer />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,6 +3,7 @@ import Sidebar from "@/components/SettingsSidebar";
|
||||
import { isMobile } from "react-device-detect";
|
||||
import Admin from "@/models/admin";
|
||||
import showToast from "@/utils/toast";
|
||||
import CTAButton from "@/components/lib/CTAButton";
|
||||
|
||||
export default function AdminSystem() {
|
||||
const [saving, setSaving] = useState(false);
|
||||
@ -49,7 +50,7 @@ export default function AdminSystem() {
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
onChange={() => setHasChanges(true)}
|
||||
className="flex flex-col w-full px-1 md:pl-6 md:pr-[86px] md:py-6 py-16"
|
||||
className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16"
|
||||
>
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="items-center">
|
||||
@ -62,8 +63,14 @@ export default function AdminSystem() {
|
||||
instance.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 mb-8">
|
||||
{hasChanges && (
|
||||
<div className="flex justify-end">
|
||||
<CTAButton onClick={handleSubmit} className="mt-3 mr-0">
|
||||
{saving ? "Saving..." : "Save changes"}
|
||||
</CTAButton>
|
||||
</div>
|
||||
)}
|
||||
<div className="mt-4 mb-8">
|
||||
<div className="flex flex-col gap-y-1">
|
||||
<h2 className="text-base leading-6 font-bold text-white">
|
||||
Users can delete workspaces
|
||||
@ -141,18 +148,6 @@ export default function AdminSystem() {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{hasChanges && (
|
||||
<div className="flex justify-start">
|
||||
<button
|
||||
type="submit"
|
||||
disabled={saving}
|
||||
className="flex items-center gap-x-2 px-4 py-2 rounded-lg bg-[#2C2F36] text-white text-sm hover:bg-[#3D4147] shadow-md border border-[#3D4147]"
|
||||
>
|
||||
{saving ? "Saving..." : "Save changes"}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -10,6 +10,7 @@ import useUser from "@/hooks/useUser";
|
||||
import NewUserModal from "./NewUserModal";
|
||||
import { useModal } from "@/hooks/useModal";
|
||||
import ModalWrapper from "@/components/ModalWrapper";
|
||||
import CTAButton from "@/components/lib/CTAButton";
|
||||
|
||||
export default function AdminUsers() {
|
||||
const { isOpen, openModal, closeModal } = useModal();
|
||||
@ -21,16 +22,10 @@ export default function AdminUsers() {
|
||||
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 h-full overflow-y-scroll"
|
||||
>
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[86px] md:py-6 py-16">
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="items-center flex gap-x-4">
|
||||
<p className="text-lg leading-6 font-bold text-white">Users</p>
|
||||
<button
|
||||
onClick={openModal}
|
||||
className="flex items-center gap-x-2 px-4 py-2 rounded-lg bg-[#2C2F36] text-white text-sm hover:bg-[#3D4147] shadow-md border border-[#3D4147]"
|
||||
>
|
||||
<UserPlus className="h-4 w-4" /> Add user
|
||||
</button>
|
||||
</div>
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
|
||||
These are all the accounts which have an account on this instance.
|
||||
@ -38,6 +33,11 @@ export default function AdminUsers() {
|
||||
instance.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full justify-end flex">
|
||||
<CTAButton onClick={openModal} className="mt-3 mr-0 -mb-6 z-10">
|
||||
<UserPlus className="h-4 w-4" weight="bold" /> Add user
|
||||
</CTAButton>
|
||||
</div>
|
||||
<UsersContainer />
|
||||
</div>
|
||||
<ModalWrapper isOpen={isOpen}>
|
||||
|
@ -9,6 +9,7 @@ import WorkspaceRow from "./WorkspaceRow";
|
||||
import NewWorkspaceModal from "./NewWorkspaceModal";
|
||||
import { useModal } from "@/hooks/useModal";
|
||||
import ModalWrapper from "@/components/ModalWrapper";
|
||||
import CTAButton from "@/components/lib/CTAButton";
|
||||
|
||||
export default function AdminWorkspaces() {
|
||||
const { isOpen, openModal, closeModal } = useModal();
|
||||
@ -20,24 +21,23 @@ export default function AdminWorkspaces() {
|
||||
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 h-full overflow-y-scroll"
|
||||
>
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[86px] md:py-6 py-16">
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="items-center flex gap-x-4">
|
||||
<p className="text-lg leading-6 font-bold text-white">
|
||||
Instance Workspaces
|
||||
</p>
|
||||
<button
|
||||
onClick={openModal}
|
||||
className="flex items-center gap-x-2 px-4 py-2 rounded-lg bg-[#2C2F36] text-white text-sm hover:bg-[#3D4147] shadow-md border border-[#3D4147]"
|
||||
>
|
||||
<BookOpen className="h-4 w-4" /> New Workspace
|
||||
</button>
|
||||
</div>
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
|
||||
These are all the workspaces that exist on this instance. Removing
|
||||
a workspace will delete all of it's associated chats and settings.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full justify-end flex">
|
||||
<CTAButton onClick={openModal} className="mt-3 mr-0 -mb-14 z-10">
|
||||
<BookOpen className="h-4 w-4" weight="bold" /> New Workspace
|
||||
</CTAButton>
|
||||
</div>
|
||||
<WorkspacesContainer />
|
||||
</div>
|
||||
<ModalWrapper isOpen={isOpen}>
|
||||
|
@ -12,6 +12,7 @@ import { userFromStorage } from "@/utils/request";
|
||||
import System from "@/models/system";
|
||||
import ModalWrapper from "@/components/ModalWrapper";
|
||||
import { useModal } from "@/hooks/useModal";
|
||||
import CTAButton from "@/components/lib/CTAButton";
|
||||
|
||||
export default function AdminApiKeys() {
|
||||
const { isOpen, openModal, closeModal } = useModal();
|
||||
@ -23,16 +24,10 @@ export default function AdminApiKeys() {
|
||||
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 h-full overflow-y-scroll"
|
||||
>
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[86px] md:py-6 py-16">
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="items-center flex gap-x-4">
|
||||
<p className="text-lg leading-6 font-bold text-white">API Keys</p>
|
||||
<button
|
||||
onClick={openModal}
|
||||
className="flex items-center gap-x-2 px-4 py-2 rounded-lg bg-[#2C2F36] text-white text-sm hover:bg-[#3D4147] shadow-md border border-[#3D4147]"
|
||||
>
|
||||
<PlusCircle className="h-4 w-4" /> Generate New API Key
|
||||
</button>
|
||||
</div>
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
|
||||
API keys allow the holder to programmatically access and manage
|
||||
@ -47,6 +42,12 @@ export default function AdminApiKeys() {
|
||||
Read the API documentation →
|
||||
</a>
|
||||
</div>
|
||||
<div className="w-full justify-end flex">
|
||||
<CTAButton onClick={openModal} className="mt-3 mr-0 -mb-14 z-10">
|
||||
<PlusCircle className="h-4 w-4" weight="bold" /> Generate New API
|
||||
Key
|
||||
</CTAButton>
|
||||
</div>
|
||||
<ApiKeysContainer />
|
||||
</div>
|
||||
<ModalWrapper isOpen={isOpen}>
|
||||
|
@ -90,7 +90,7 @@ export default function WorkspaceChats() {
|
||||
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 h-full overflow-y-scroll"
|
||||
>
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[86px] md:py-6 py-16">
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="flex gap-x-4 items-center">
|
||||
<p className="text-lg leading-6 font-bold text-white">
|
||||
|
@ -9,6 +9,7 @@ import NewEmbedModal from "./NewEmbedModal";
|
||||
import { useModal } from "@/hooks/useModal";
|
||||
import ModalWrapper from "@/components/ModalWrapper";
|
||||
import Embed from "@/models/embed";
|
||||
import CTAButton from "@/components/lib/CTAButton";
|
||||
|
||||
export default function EmbedConfigs() {
|
||||
const { isOpen, openModal, closeModal } = useModal();
|
||||
@ -20,18 +21,12 @@ export default function EmbedConfigs() {
|
||||
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 h-full overflow-y-scroll"
|
||||
>
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[86px] md:py-6 py-16">
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="items-center flex gap-x-4">
|
||||
<p className="text-lg leading-6 font-bold text-white">
|
||||
Embeddable Chat Widgets
|
||||
</p>
|
||||
<button
|
||||
onClick={openModal}
|
||||
className="flex items-center gap-x-2 px-4 py-2 rounded-lg bg-[#2C2F36] text-white text-sm hover:bg-[#3D4147] shadow-md border border-[#3D4147]"
|
||||
>
|
||||
<CodeBlock className="h-4 w-4" /> Create embed
|
||||
</button>
|
||||
</div>
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
|
||||
Embeddable chat widgets are public facing chat interfaces that are
|
||||
@ -39,6 +34,11 @@ export default function EmbedConfigs() {
|
||||
that then you can publish to the world.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full justify-end flex">
|
||||
<CTAButton onClick={openModal} className="mt-3 mr-0 -mb-14 z-10">
|
||||
<CodeBlock className="h-4 w-4" weight="bold" /> Create embed
|
||||
</CTAButton>
|
||||
</div>
|
||||
<EmbedContainer />
|
||||
</div>
|
||||
<ModalWrapper isOpen={isOpen}>
|
||||
|
@ -19,6 +19,7 @@ import EmbedderItem from "@/components/EmbeddingSelection/EmbedderItem";
|
||||
import { CaretUpDown, MagnifyingGlass, X } from "@phosphor-icons/react";
|
||||
import { useModal } from "@/hooks/useModal";
|
||||
import ModalWrapper from "@/components/ModalWrapper";
|
||||
import CTAButton from "@/components/lib/CTAButton";
|
||||
|
||||
export default function GeneralEmbeddingPreference() {
|
||||
const [saving, setSaving] = useState(false);
|
||||
@ -165,21 +166,12 @@ export default function GeneralEmbeddingPreference() {
|
||||
onSubmit={handleSubmit}
|
||||
className="flex w-full"
|
||||
>
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[86px] md:py-6 py-16">
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="flex gap-x-4 items-center">
|
||||
<p className="text-lg leading-6 font-bold text-white">
|
||||
Embedding Preference
|
||||
</p>
|
||||
{hasChanges && (
|
||||
<button
|
||||
type="submit"
|
||||
disabled={saving}
|
||||
className="flex items-center gap-x-2 px-4 py-2 rounded-lg bg-[#2C2F36] text-white text-sm hover:bg-[#3D4147] shadow-md border border-[#3D4147]"
|
||||
>
|
||||
{saving ? "Saving..." : "Save changes"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
|
||||
When using an LLM that does not natively support an embedding
|
||||
@ -191,6 +183,16 @@ export default function GeneralEmbeddingPreference() {
|
||||
format which AnythingLLM can use to process.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full justify-end flex">
|
||||
{hasChanges && (
|
||||
<CTAButton
|
||||
onClick={() => handleSubmit()}
|
||||
className="mt-3 mr-0 -mb-14 z-10"
|
||||
>
|
||||
{saving ? "Saving..." : "Save changes"}
|
||||
</CTAButton>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-base font-bold text-white mt-6 mb-4">
|
||||
Embedding Provider
|
||||
</div>
|
||||
|
@ -35,6 +35,7 @@ import GroqAiOptions from "@/components/LLMSelection/GroqAiOptions";
|
||||
|
||||
import LLMItem from "@/components/LLMSelection/LLMItem";
|
||||
import { CaretUpDown, MagnifyingGlass, X } from "@phosphor-icons/react";
|
||||
import CTAButton from "@/components/lib/CTAButton";
|
||||
|
||||
export const AVAILABLE_LLM_PROVIDERS = [
|
||||
{
|
||||
@ -245,21 +246,12 @@ export default function GeneralLLMPreference() {
|
||||
className="relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-main-gradient w-full h-full overflow-y-scroll"
|
||||
>
|
||||
<form onSubmit={handleSubmit} className="flex w-full">
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[86px] md:py-6 py-16">
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="flex gap-x-4 items-center">
|
||||
<p className="text-lg leading-6 font-bold text-white">
|
||||
LLM Preference
|
||||
</p>
|
||||
{hasChanges && (
|
||||
<button
|
||||
type="submit"
|
||||
disabled={saving}
|
||||
className="flex items-center gap-x-2 px-4 py-2 rounded-lg bg-[#2C2F36] text-white text-sm hover:bg-[#3D4147] shadow-md border border-[#3D4147]"
|
||||
>
|
||||
{saving ? "Saving..." : "Save changes"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
|
||||
These are the credentials and settings for your preferred LLM
|
||||
@ -268,6 +260,16 @@ export default function GeneralLLMPreference() {
|
||||
properly.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full justify-end flex">
|
||||
{hasChanges && (
|
||||
<CTAButton
|
||||
onClick={() => handleSubmit()}
|
||||
className="mt-3 mr-0 -mb-14 z-10"
|
||||
>
|
||||
{saving ? "Saving..." : "Save changes"}
|
||||
</CTAButton>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-base font-bold text-white mt-6 mb-4">
|
||||
LLM Provider
|
||||
</div>
|
||||
|
@ -29,16 +29,16 @@ export default function PrivacyAndDataHandling() {
|
||||
<Sidebar />
|
||||
<div
|
||||
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
|
||||
className="transition-all duration-500 relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-main-gradient w-full h-full overflow-y-scroll border-2 border-outline"
|
||||
className="relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-main-gradient w-full h-full overflow-y-scroll"
|
||||
>
|
||||
<div className="flex flex-col w-full px-1 md:px-20 md:py-12 py-16">
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="items-center flex gap-x-4">
|
||||
<p className="text-2xl font-semibold text-white">
|
||||
<p className="text-lg leading-6 font-bold text-white">
|
||||
Privacy & Data-Handling
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-sm font-base text-white text-opacity-60">
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
|
||||
This is your configuration for how connected third party providers
|
||||
and AnythingLLM handle your data.
|
||||
</p>
|
||||
|
@ -6,6 +6,7 @@ import System from "@/models/system";
|
||||
import paths from "@/utils/paths";
|
||||
import { AUTH_TIMESTAMP, AUTH_TOKEN, AUTH_USER } from "@/utils/constants";
|
||||
import PreLoader from "@/components/Preloader";
|
||||
import CTAButton from "@/components/lib/CTAButton";
|
||||
|
||||
export default function GeneralSecurity() {
|
||||
return (
|
||||
@ -13,7 +14,7 @@ export default function GeneralSecurity() {
|
||||
<Sidebar />
|
||||
<div
|
||||
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
|
||||
className="transition-all duration-500 relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-main-gradient w-full h-full overflow-y-scroll border-2 border-outline"
|
||||
className="relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-main-gradient w-full h-full overflow-y-scroll"
|
||||
>
|
||||
<MultiUserMode />
|
||||
<PasswordProtection />
|
||||
@ -32,7 +33,7 @@ function MultiUserMode() {
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
setSaving(true);
|
||||
|
||||
setHasChanges(false);
|
||||
if (useMultiUserMode) {
|
||||
const form = new FormData(e.target);
|
||||
const data = {
|
||||
@ -83,27 +84,30 @@ function MultiUserMode() {
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
onChange={() => setHasChanges(true)}
|
||||
className="flex w-full"
|
||||
className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16"
|
||||
>
|
||||
<div className="flex flex-col w-full px-1 md:px-20 md:py-12 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="w-full flex flex-col gap-y-1">
|
||||
<div className="items-center flex gap-x-4">
|
||||
<p className="text-2xl font-semibold text-white">Multi-User Mode</p>
|
||||
{hasChanges && (
|
||||
<button
|
||||
type="submit"
|
||||
disabled={saving}
|
||||
className="border border-slate-200 px-4 py-1 rounded-lg text-slate-200 text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800"
|
||||
>
|
||||
{saving ? "Saving..." : "Save changes"}
|
||||
</button>
|
||||
)}
|
||||
<p className="text-lg leading-6 font-bold text-white">
|
||||
Multi-User Mode
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-sm font-base text-white text-opacity-60">
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
|
||||
Set up your instance to support your team by activating Multi-User
|
||||
Mode.
|
||||
</p>
|
||||
</div>
|
||||
{hasChanges && (
|
||||
<div className="flex justify-end">
|
||||
<CTAButton
|
||||
onClick={() => handleSubmit()}
|
||||
className="mt-3 mr-0 -mb-20 z-10"
|
||||
>
|
||||
{saving ? "Saving..." : "Save changes"}
|
||||
</CTAButton>
|
||||
</div>
|
||||
)}
|
||||
<div className="relative w-full max-h-full">
|
||||
<div className="relative rounded-lg">
|
||||
<div className="flex items-start justify-between px-6 py-4"></div>
|
||||
@ -198,6 +202,7 @@ function PasswordProtection() {
|
||||
if (multiUserModeEnabled) return false;
|
||||
|
||||
setSaving(true);
|
||||
setHasChanges(false);
|
||||
const form = new FormData(e.target);
|
||||
const data = {
|
||||
usePassword,
|
||||
@ -248,29 +253,30 @@ function PasswordProtection() {
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
onChange={() => setHasChanges(true)}
|
||||
className="flex w-full"
|
||||
className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16"
|
||||
>
|
||||
<div className="flex flex-col w-full px-1 md:px-20 md:py-12 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="w-full flex flex-col gap-y-1">
|
||||
<div className="items-center flex gap-x-4">
|
||||
<p className="text-2xl font-semibold text-white">
|
||||
<p className="text-lg leading-6 font-bold text-white">
|
||||
Password Protection
|
||||
</p>
|
||||
{hasChanges && (
|
||||
<button
|
||||
type="submit"
|
||||
disabled={saving}
|
||||
className="border border-slate-200 px-4 py-1 rounded-lg text-slate-200 text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800"
|
||||
>
|
||||
{saving ? "Saving..." : "Save changes"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-sm font-base text-white text-opacity-60">
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
|
||||
Protect your AnythingLLM instance with a password. If you forget
|
||||
this there is no recovery method so ensure you save this password.
|
||||
</p>
|
||||
</div>
|
||||
{hasChanges && (
|
||||
<div className="flex justify-end">
|
||||
<CTAButton
|
||||
onClick={() => handleSubmit()}
|
||||
className="mt-3 mr-0 -mb-20 z-10"
|
||||
>
|
||||
{saving ? "Saving..." : "Save changes"}
|
||||
</CTAButton>
|
||||
</div>
|
||||
)}
|
||||
<div className="relative w-full max-h-full">
|
||||
<div className="relative rounded-lg">
|
||||
<div className="flex items-start justify-between px-6 py-4"></div>
|
||||
|
@ -10,6 +10,7 @@ import OpenAiWhisperOptions from "@/components/TranscriptionSelection/OpenAiOpti
|
||||
import NativeTranscriptionOptions from "@/components/TranscriptionSelection/NativeTranscriptionOptions";
|
||||
import LLMItem from "@/components/LLMSelection/LLMItem";
|
||||
import { CaretUpDown, MagnifyingGlass, X } from "@phosphor-icons/react";
|
||||
import CTAButton from "@/components/lib/CTAButton";
|
||||
|
||||
export default function TranscriptionModelPreference() {
|
||||
const [saving, setSaving] = useState(false);
|
||||
@ -114,21 +115,12 @@ export default function TranscriptionModelPreference() {
|
||||
className="relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-main-gradient w-full h-full overflow-y-scroll"
|
||||
>
|
||||
<form onSubmit={handleSubmit} className="flex w-full">
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[86px] md:py-6 py-16">
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="flex gap-x-4 items-center">
|
||||
<p className="text-lg leading-6 font-bold text-white">
|
||||
Transcription Model Preference
|
||||
</p>
|
||||
{hasChanges && (
|
||||
<button
|
||||
type="submit"
|
||||
disabled={saving}
|
||||
className="flex items-center gap-x-2 px-4 py-2 rounded-lg bg-[#2C2F36] text-white text-sm hover:bg-[#3D4147] shadow-md border border-[#3D4147]"
|
||||
>
|
||||
{saving ? "Saving..." : "Save changes"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
|
||||
These are the credentials and settings for your preferred
|
||||
@ -137,6 +129,16 @@ export default function TranscriptionModelPreference() {
|
||||
transcribe.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full justify-end flex">
|
||||
{hasChanges && (
|
||||
<CTAButton
|
||||
onClick={() => handleSubmit()}
|
||||
className="mt-3 mr-0 -mb-14 z-10"
|
||||
>
|
||||
{saving ? "Saving..." : "Save changes"}
|
||||
</CTAButton>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-base font-bold text-white mt-6 mb-4">
|
||||
Transcription Provider
|
||||
</div>
|
||||
|
@ -25,6 +25,7 @@ import ZillizCloudOptions from "@/components/VectorDBSelection/ZillizCloudOption
|
||||
import { useModal } from "@/hooks/useModal";
|
||||
import ModalWrapper from "@/components/ModalWrapper";
|
||||
import AstraDBOptions from "@/components/VectorDBSelection/AstraDBOptions";
|
||||
import CTAButton from "@/components/lib/CTAButton";
|
||||
|
||||
export default function GeneralVectorDatabase() {
|
||||
const [saving, setSaving] = useState(false);
|
||||
@ -189,21 +190,12 @@ export default function GeneralVectorDatabase() {
|
||||
onSubmit={handleSubmit}
|
||||
className="flex w-full"
|
||||
>
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[86px] md:py-6 py-16">
|
||||
<div className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16">
|
||||
<div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
|
||||
<div className="flex gap-x-4 items-center">
|
||||
<p className="text-lg leading-6 font-bold text-white">
|
||||
Vector Database
|
||||
</p>
|
||||
{hasChanges && (
|
||||
<button
|
||||
type="submit"
|
||||
disabled={saving}
|
||||
className="flex items-center gap-x-2 px-4 py-2 rounded-lg bg-[#2C2F36] text-white text-sm hover:bg-[#3D4147] shadow-md border border-[#3D4147]"
|
||||
>
|
||||
{saving ? "Saving..." : "Save changes"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-xs leading-[18px] font-base text-white text-opacity-60">
|
||||
These are the credentials and settings for how your
|
||||
@ -211,6 +203,16 @@ export default function GeneralVectorDatabase() {
|
||||
are current and correct.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full justify-end flex">
|
||||
{hasChanges && (
|
||||
<CTAButton
|
||||
onClick={() => handleSubmit()}
|
||||
className="mt-3 mr-0 -mb-14 z-10"
|
||||
>
|
||||
{saving ? "Saving..." : "Save changes"}
|
||||
</CTAButton>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-base font-bold text-white mt-6 mb-4">
|
||||
Vector Database Provider
|
||||
</div>
|
||||
|
@ -138,15 +138,17 @@ export default function AddMemberModal({ closeModal, workspace, users }) {
|
||||
</div>
|
||||
<p className="text-white text-sm font-medium">Select All</p>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleUnselect}
|
||||
className="flex items-center gap-x-2 ml-2"
|
||||
>
|
||||
<p className="text-white/60 text-sm font-medium hover:text-white">
|
||||
Unselect
|
||||
</p>
|
||||
</button>
|
||||
{selectedUsers.length > 0 && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleUnselect}
|
||||
className="flex items-center gap-x-2 ml-2"
|
||||
>
|
||||
<p className="text-white/60 text-sm font-medium hover:text-white">
|
||||
Unselect
|
||||
</p>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
|
@ -5,6 +5,7 @@ import { useEffect, useState } from "react";
|
||||
import * as Skeleton from "react-loading-skeleton";
|
||||
import AddMemberModal from "./AddMemberModal";
|
||||
import WorkspaceMemberRow from "./WorkspaceMemberRow";
|
||||
import CTAButton from "@/components/lib/CTAButton";
|
||||
|
||||
export default function Members({ workspace }) {
|
||||
const [loading, setLoading] = useState(true);
|
||||
@ -77,14 +78,7 @@ export default function Members({ workspace }) {
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<button
|
||||
onClick={openModal}
|
||||
className="text-xs px-2 py-1 font-semibold rounded-lg bg-[#46C8FF] hover:bg-[#2C2F36] hover:text-white h-[34px] w-[100px] -mr-8 whitespace-nowrap shadow-[0_4px_14px_rgba(0,0,0,0.25)]"
|
||||
>
|
||||
Manage Users
|
||||
</button>
|
||||
|
||||
<CTAButton onClick={openModal}>Manage Users</CTAButton>
|
||||
<ModalWrapper isOpen={isOpen}>
|
||||
<AddMemberModal
|
||||
closeModal={closeModal}
|
||||
|
Loading…
Reference in New Issue
Block a user