merlyn/frontend/src/pages/WorkspaceSettings/index.jsx
Timothy Carambat a5bb77f97a
Agent support for @agent default agent inside workspace chat (#1093)
V1 of agent support via built-in `@agent` that can be invoked alongside normal workspace RAG chat.
2024-04-16 10:50:10 -07:00

140 lines
4.4 KiB
JavaScript

import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import Sidebar from "@/components/Sidebar";
import Workspace from "@/models/workspace";
import PasswordModal, { usePasswordModal } from "@/components/Modals/Password";
import { isMobile } from "react-device-detect";
import { FullScreenLoader } from "@/components/Preloader";
import {
ArrowUUpLeft,
ChatText,
Database,
Robot,
User,
Wrench,
} from "@phosphor-icons/react";
import paths from "@/utils/paths";
import { Link } from "react-router-dom";
import { NavLink } from "react-router-dom";
import GeneralAppearance from "./GeneralAppearance";
import ChatSettings from "./ChatSettings";
import VectorDatabase from "./VectorDatabase";
import Members from "./Members";
import WorkspaceAgentConfiguration from "./AgentConfig";
import useUser from "@/hooks/useUser";
const TABS = {
"general-appearance": GeneralAppearance,
"chat-settings": ChatSettings,
"vector-database": VectorDatabase,
members: Members,
"agent-config": WorkspaceAgentConfiguration,
};
export default function WorkspaceSettings() {
const { loading, requiresAuth, mode } = usePasswordModal();
if (loading) return <FullScreenLoader />;
if (requiresAuth !== false) {
return <>{requiresAuth !== null && <PasswordModal mode={mode} />}</>;
}
return <ShowWorkspaceChat />;
}
function ShowWorkspaceChat() {
const { slug, tab } = useParams();
const { user } = useUser();
const [workspace, setWorkspace] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function getWorkspace() {
if (!slug) return;
const _workspace = await Workspace.bySlug(slug);
if (!_workspace) {
setLoading(false);
return;
}
const suggestedMessages = await Workspace.getSuggestedMessages(slug);
setWorkspace({
..._workspace,
suggestedMessages,
});
setLoading(false);
}
getWorkspace();
}, [slug]);
if (loading) return <FullScreenLoader />;
const TabContent = TABS[tab];
return (
<div className="w-screen h-screen overflow-hidden bg-sidebar flex">
{!isMobile && <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"
>
<div className="flex gap-x-10 pt-6 pb-4 ml-16 mr-8 border-b-2 border-white border-opacity-10">
<Link
to={paths.workspace.chat(slug)}
className="absolute top-2 left-2 md:top-4 md:left-4 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 z-10"
>
<ArrowUUpLeft className="h-5 w-5" weight="fill" />
</Link>
<TabItem
title="General Settings"
icon={<Wrench className="h-6 w-6" />}
to={paths.workspace.settings.generalAppearance(slug)}
/>
<TabItem
title="Chat Settings"
icon={<ChatText className="h-6 w-6" />}
to={paths.workspace.settings.chatSettings(slug)}
/>
<TabItem
title="Vector Database"
icon={<Database className="h-6 w-6" />}
to={paths.workspace.settings.vectorDatabase(slug)}
/>
<TabItem
title="Members"
icon={<User className="h-6 w-6" />}
to={paths.workspace.settings.members(slug)}
visible={["admin", "manager"].includes(user?.role)}
/>
<TabItem
title="Agent Configuration"
icon={<Robot className="h-6 w-6" />}
to={paths.workspace.settings.agentConfig(slug)}
/>
</div>
<div className="px-16 py-6">
<TabContent slug={slug} workspace={workspace} />
</div>
</div>
</div>
);
}
function TabItem({ title, icon, to, visible = true }) {
if (!visible) return null;
return (
<NavLink
to={to}
className={({ isActive }) =>
`${
isActive
? "text-sky-400 pb-4 border-b-[4px] -mb-[19px] border-sky-400"
: "text-white/60 hover:text-sky-400"
} ` + " flex gap-x-2 items-center font-medium"
}
>
{icon}
<div>{title}</div>
</NavLink>
);
}