[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:
Sean Hatfield 2024-04-05 13:54:12 -07:00 committed by GitHub
parent a2923e35e8
commit 657be7ecfc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 176 additions and 150 deletions

1
frontend/.gitignore vendored
View File

@ -12,6 +12,7 @@ dist
lib
dist-ssr
*.local
!frontend/components/lib
# Editor directories and files
.vscode/*

View 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>
);
}

View File

@ -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}>

View File

@ -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>

View File

@ -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>

View File

@ -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}>

View File

@ -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}>

View File

@ -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 &rarr;
</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}>

View File

@ -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">

View File

@ -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}>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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"

View File

@ -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}