Skip to content
Snippets Groups Projects
Unverified Commit 9644f671 authored by Sean Hatfield's avatar Sean Hatfield Committed by GitHub
Browse files

[STYLE] Agent UI mobile styles (#1665)


* implement mobile styles for new agent settings ui

* fix on off label not updating for generate & save files to browser

* update sql connector modal for mobile

* small changes for UI normalization

* breakout layout from forms for mobile/desktop

* add back no-borders

---------

Co-authored-by: default avatarTimothy Carambat <rambat1010@gmail.com>
parent 05870ec8
No related branches found
No related tags found
No related merge requests found
...@@ -8,8 +8,8 @@ export default function ContextualSaveBar({ ...@@ -8,8 +8,8 @@ export default function ContextualSaveBar({
if (!showing) return null; if (!showing) return null;
return ( return (
<div className="fixed top-0 left-0 right-0 h-14 bg-[#18181B] flex items-center justify-end px-4 z-[9999]"> <div className="fixed top-0 left-0 right-0 h-14 bg-[#18181B] flex items-center justify-end px-4 z-[999]">
<div className="absolute left-1/2 transform -translate-x-1/2 flex items-center gap-x-2"> <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" /> <Warning size={18} className="text-white" />
<p className="text-white font-medium text-xs">Unsaved Changes</p> <p className="text-white font-medium text-xs">Unsaved Changes</p>
</div> </div>
......
...@@ -74,7 +74,7 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) { ...@@ -74,7 +74,7 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
// to the parent container form so we don't have nested forms. // to the parent container form so we don't have nested forms.
return createPortal( return createPortal(
<ModalWrapper isOpen={isOpen}> <ModalWrapper isOpen={isOpen}>
<div className="relative w-1/3 max-h-full mt-8"> <div className="relative w-full md:w-1/3 max-w-2xl max-h-full md:mt-8">
<div className="relative bg-main-gradient rounded-xl shadow-[0_4px_14px_rgba(0,0,0,0.25)] max-h-[85vh] overflow-y-scroll no-scroll"> <div className="relative bg-main-gradient rounded-xl shadow-[0_4px_14px_rgba(0,0,0,0.25)] max-h-[85vh] overflow-y-scroll no-scroll">
<div className="flex items-start justify-between p-4 border-b rounded-t border-gray-500/50"> <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"> <h3 className="text-xl font-semibold text-white">
...@@ -114,7 +114,7 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) { ...@@ -114,7 +114,7 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
<label className="text-white text-sm font-semibold block my-4"> <label className="text-white text-sm font-semibold block my-4">
Select your SQL engine Select your SQL engine
</label> </label>
<div className="flex w-full flex-wrap gap-x-4"> <div className="grid md:grid-cols-4 gap-4 grid-cols-2">
<DBEngine <DBEngine
provider="postgresql" provider="postgresql"
active={engine === "postgresql"} active={engine === "postgresql"}
...@@ -148,8 +148,8 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) { ...@@ -148,8 +148,8 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
/> />
</div> </div>
<div className="flex gap-x-2"> <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div className="flex flex-col w-60"> <div className="flex flex-col">
<label className="text-white text-sm font-semibold block mb-4"> <label className="text-white text-sm font-semibold block mb-4">
Database user Database user
</label> </label>
...@@ -163,7 +163,7 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) { ...@@ -163,7 +163,7 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
spellCheck={false} spellCheck={false}
/> />
</div> </div>
<div className="flex flex-col w-60"> <div className="flex flex-col">
<label className="text-white text-sm font-semibold block mb-4"> <label className="text-white text-sm font-semibold block mb-4">
Database user password Database user password
</label> </label>
...@@ -179,8 +179,8 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) { ...@@ -179,8 +179,8 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
</div> </div>
</div> </div>
<div className="flex gap-x-2"> <div className="grid grid-cols-1 gap-4 sm:grid-cols-3">
<div className="flex flex-col w-full"> <div className="sm:col-span-2">
<label className="text-white text-sm font-semibold block mb-4"> <label className="text-white text-sm font-semibold block mb-4">
Server endpoint Server endpoint
</label> </label>
...@@ -194,7 +194,7 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) { ...@@ -194,7 +194,7 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
spellCheck={false} spellCheck={false}
/> />
</div> </div>
<div className="flex flex-col w-30"> <div>
<label className="text-white text-sm font-semibold block mb-4"> <label className="text-white text-sm font-semibold block mb-4">
Port Port
</label> </label>
...@@ -210,7 +210,7 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) { ...@@ -210,7 +210,7 @@ export default function NewSQLConnection({ isOpen, closeModal, onSubmit }) {
</div> </div>
</div> </div>
<div className="flex flex-col w-60"> <div className="flex flex-col">
<label className="text-white text-sm font-semibold block mb-4"> <label className="text-white text-sm font-semibold block mb-4">
Database Database
</label> </label>
...@@ -264,7 +264,7 @@ function DBEngine({ provider, active, onClick }) { ...@@ -264,7 +264,7 @@ function DBEngine({ provider, active, onClick }) {
<img <img
src={DB_LOGOS[provider]} src={DB_LOGOS[provider]}
className="h-[100px] rounded-md" className="h-[100px] rounded-md"
alt="PostgreSQL" alt={provider}
/> />
</button> </button>
); );
......
...@@ -4,7 +4,7 @@ import { isMobile } from "react-device-detect"; ...@@ -4,7 +4,7 @@ import { isMobile } from "react-device-detect";
import Admin from "@/models/admin"; import Admin from "@/models/admin";
import System from "@/models/system"; import System from "@/models/system";
import showToast from "@/utils/toast"; import showToast from "@/utils/toast";
import { CaretRight, Robot } from "@phosphor-icons/react"; import { CaretLeft, CaretRight, Robot } from "@phosphor-icons/react";
import ContextualSaveBar from "@/components/ContextualSaveBar"; import ContextualSaveBar from "@/components/ContextualSaveBar";
import { castToType } from "@/utils/types"; import { castToType } from "@/utils/types";
import { FullScreenLoader } from "@/components/Preloader"; import { FullScreenLoader } from "@/components/Preloader";
...@@ -17,6 +17,7 @@ export default function AdminAgents() { ...@@ -17,6 +17,7 @@ export default function AdminAgents() {
const [selectedSkill, setSelectedSkill] = useState(""); const [selectedSkill, setSelectedSkill] = useState("");
const [agentSkills, setAgentSkills] = useState([]); const [agentSkills, setAgentSkills] = useState([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [showSkillModal, setShowSkillModal] = useState(false);
const formEl = useRef(null); const formEl = useRef(null);
// Alert user if they try to leave the page with unsaved changes // Alert user if they try to leave the page with unsaved changes
...@@ -110,21 +111,19 @@ export default function AdminAgents() { ...@@ -110,21 +111,19 @@ export default function AdminAgents() {
</div> </div>
); );
} }
return (
<div if (isMobile) {
id="workspace-agent-settings-container" return (
className="w-screen h-screen overflow-hidden bg-sidebar flex" <SkillLayout
> hasChanges={hasChanges}
<Sidebar /> handleCancel={() => setHasChanges(false)}
<div handleSubmit={handleSubmit}
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
className="relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] w-full h-full flex"
> >
<form <form
onSubmit={handleSubmit} onSubmit={handleSubmit}
onChange={() => setHasChanges(true)} onChange={() => setHasChanges(true)}
ref={formEl} ref={formEl}
className="flex-1 flex gap-x-6 p-4 mt-10" className="flex flex-col w-full p-4 mt-10"
> >
<input <input
name="system::default_agent_skills" name="system::default_agent_skills"
...@@ -133,56 +132,167 @@ export default function AdminAgents() { ...@@ -133,56 +132,167 @@ export default function AdminAgents() {
/> />
{/* Skill settings nav */} {/* Skill settings nav */}
<div className="flex flex-col gap-y-[18px]"> <div hidden={showSkillModal} className="flex flex-col gap-y-[18px]">
<div className="text-white flex items-center gap-x-2"> <div className="text-white flex items-center gap-x-2">
<Robot size={24} /> <Robot size={24} />
<p className="text-lg font-medium">Agent Skills</p> <p className="text-lg font-medium">Agent Skills</p>
</div> </div>
{/* Default skills */}
{/* Default skills list */}
<SkillList <SkillList
isDefault={true} isDefault={true}
skills={defaultSkills} skills={defaultSkills}
selectedSkill={selectedSkill} selectedSkill={selectedSkill}
handleClick={setSelectedSkill} handleClick={(skill) => {
setSelectedSkill(skill);
setShowSkillModal(true);
}}
/> />
{/* Configurable skills */} {/* Configurable skills */}
<SkillList <SkillList
skills={configurableSkills} skills={configurableSkills}
selectedSkill={selectedSkill} selectedSkill={selectedSkill}
handleClick={setSelectedSkill} handleClick={(skill) => {
setSelectedSkill(skill);
setShowSkillModal(true);
}}
activeSkills={agentSkills} activeSkills={agentSkills}
/> />
</div> </div>
{/* Selected agent skill setting panel */} {/* Selected agent skill modal */}
<div className="flex-[2] flex flex-col gap-y-[18px] mt-10"> {showSkillModal && (
<div className="bg-[#303237] text-white rounded-xl flex-1 p-4"> <div className="fixed top-0 left-0 w-full h-full bg-sidebar z-30">
{SelectedSkillComponent ? ( <div className="flex flex-col h-full">
<SelectedSkillComponent <div className="flex items-center p-4">
skill={configurableSkills[selectedSkill]?.skill} <button
settings={settings} type="button"
toggleSkill={toggleAgentSkill} onClick={() => {
enabled={agentSkills.includes( setShowSkillModal(false);
configurableSkills[selectedSkill]?.skill setSelectedSkill("");
)} }}
setHasChanges={setHasChanges} className="text-white/60 hover:text-white transition-colors duration-200"
{...(configurableSkills[selectedSkill] || >
defaultSkills[selectedSkill])} <div className="flex items-center text-sky-400">
/> <CaretLeft size={24} />
) : ( <div>Back</div>
<div className="flex flex-col items-center justify-center h-full text-white/60"> </div>
<Robot size={40} /> </button>
<p className="font-medium">Select an agent skill</p> </div>
<div className="flex-1 overflow-y-auto p-4">
<div className="bg-[#303237] text-white rounded-xl p-4">
{SelectedSkillComponent ? (
<SelectedSkillComponent
skill={configurableSkills[selectedSkill]?.skill}
settings={settings}
toggleSkill={toggleAgentSkill}
enabled={agentSkills.includes(
configurableSkills[selectedSkill]?.skill
)}
setHasChanges={setHasChanges}
{...(configurableSkills[selectedSkill] ||
defaultSkills[selectedSkill])}
/>
) : (
<div className="flex flex-col items-center justify-center h-full text-white/60">
<Robot size={40} />
<p className="font-medium">Select an agent skill</p>
</div>
)}
</div>
</div> </div>
)} </div>
</div> </div>
</div> )}
</form> </form>
</SkillLayout>
);
}
return (
<SkillLayout
hasChanges={hasChanges}
handleCancel={() => setHasChanges(false)}
handleSubmit={handleSubmit}
>
<form
onSubmit={handleSubmit}
onChange={() => setHasChanges(true)}
ref={formEl}
className="flex-1 flex gap-x-6 p-4 mt-10"
>
<input
name="system::default_agent_skills"
type="hidden"
value={agentSkills.join(",")}
/>
{/* Skill settings nav */}
<div className="flex flex-col gap-y-[18px]">
<div className="text-white flex items-center gap-x-2">
<Robot size={24} />
<p className="text-lg font-medium">Agent Skills</p>
</div>
{/* Default skills list */}
<SkillList
isDefault={true}
skills={defaultSkills}
selectedSkill={selectedSkill}
handleClick={setSelectedSkill}
/>
{/* Configurable skills */}
<SkillList
skills={configurableSkills}
selectedSkill={selectedSkill}
handleClick={setSelectedSkill}
activeSkills={agentSkills}
/>
</div>
{/* Selected agent skill setting panel */}
<div className="flex-[2] flex flex-col gap-y-[18px] mt-10">
<div className="bg-[#303237] text-white rounded-xl flex-1 p-4">
{SelectedSkillComponent ? (
<SelectedSkillComponent
skill={configurableSkills[selectedSkill]?.skill}
settings={settings}
toggleSkill={toggleAgentSkill}
enabled={agentSkills.includes(
configurableSkills[selectedSkill]?.skill
)}
setHasChanges={setHasChanges}
{...(configurableSkills[selectedSkill] ||
defaultSkills[selectedSkill])}
/>
) : (
<div className="flex flex-col items-center justify-center h-full text-white/60">
<Robot size={40} />
<p className="font-medium">Select an agent skill</p>
</div>
)}
</div>
</div>
</form>
</SkillLayout>
);
}
function SkillLayout({ children, hasChanges, handleSubmit, handleCancel }) {
return (
<div
id="workspace-agent-settings-container"
className="w-screen h-screen overflow-hidden bg-sidebar flex md:mt-0 mt-6"
>
<Sidebar />
<div
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
className="relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] w-full h-full flex"
>
{children}
<ContextualSaveBar <ContextualSaveBar
showing={hasChanges} showing={hasChanges}
onSave={handleSubmit} onSave={handleSubmit}
onCancel={() => setHasChanges(false)} onCancel={handleCancel}
/> />
</div> </div>
</div> </div>
...@@ -199,7 +309,11 @@ function SkillList({ ...@@ -199,7 +309,11 @@ function SkillList({
if (skills.length === 0) return null; if (skills.length === 0) return null;
return ( return (
<div className="bg-white/5 text-white min-w-[360px] w-fit rounded-xl"> <div
className={`bg-white/5 text-white rounded-xl ${
isMobile ? "w-full" : "min-w-[360px] w-fit"
}`}
>
{Object.entries(skills).map(([skill, settings], index) => ( {Object.entries(skills).map(([skill, settings], index) => (
<div <div
key={skill} key={skill}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment