Add feature flags for use multiple projects and display project page accordingly

Update project new page style
This commit is contained in:
akhisud3195 2025-04-07 16:42:03 +05:30
parent 50ac0ebec7
commit 01f16a11d3
4 changed files with 143 additions and 102 deletions

View file

@ -2,4 +2,10 @@ export const USE_RAG = process.env.USE_RAG === 'true';
export const USE_RAG_UPLOADS = process.env.USE_RAG_UPLOADS === 'true'; export const USE_RAG_UPLOADS = process.env.USE_RAG_UPLOADS === 'true';
export const USE_RAG_SCRAPING = process.env.USE_RAG_SCRAPING === 'true'; export const USE_RAG_SCRAPING = process.env.USE_RAG_SCRAPING === 'true';
export const USE_CHAT_WIDGET = process.env.USE_CHAT_WIDGET === 'true'; export const USE_CHAT_WIDGET = process.env.USE_CHAT_WIDGET === 'true';
export const USE_AUTH = process.env.USE_AUTH === 'true'; export const USE_AUTH = process.env.USE_AUTH === 'true';
// export const USE_MULTIPLE_PROJECTS = true;
export const USE_MULTIPLE_PROJECTS = false;
export const USE_TESTING_FEATURE = false;
export const USE_VOICE_FEATURE = false;

View file

@ -11,6 +11,7 @@ import { TestProfile } from "@/app/lib/types/testing_types";
import { WithStringId } from "@/app/lib/types/types"; import { WithStringId } from "@/app/lib/types/types";
import { ProfileSelector } from "@/app/projects/[projectId]/test/[[...slug]]/components/selectors/profile-selector"; import { ProfileSelector } from "@/app/projects/[projectId]/test/[[...slug]]/components/selectors/profile-selector";
import { CheckIcon, CopyIcon, PlusIcon, UserIcon } from "lucide-react"; import { CheckIcon, CopyIcon, PlusIcon, UserIcon } from "lucide-react";
import { USE_TESTING_FEATURE } from "@/app/lib/feature_flags";
const defaultSystemMessage = ''; const defaultSystemMessage = '';
@ -103,15 +104,17 @@ export function App({
} }
rightActions={ rightActions={
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Button {USE_TESTING_FEATURE && (
variant="secondary" <Button
size="sm" variant="secondary"
onClick={() => setIsProfileSelectorOpen(true)} size="sm"
showHoverContent={true} onClick={() => setIsProfileSelectorOpen(true)}
hoverContent={testProfile?.name || 'Select test profile'} showHoverContent={true}
> hoverContent={testProfile?.name || 'Select test profile'}
<UserIcon className="w-4 h-4" /> >
</Button> <UserIcon className="w-4 h-4" />
</Button>
)}
<Button <Button
variant="secondary" variant="secondary"
size="sm" size="sm"
@ -128,13 +131,15 @@ export function App({
</div> </div>
} }
> >
<ProfileSelector {USE_TESTING_FEATURE && (
projectId={projectId} <ProfileSelector
isOpen={isProfileSelectorOpen} projectId={projectId}
onOpenChange={setIsProfileSelectorOpen} isOpen={isProfileSelectorOpen}
onSelect={handleTestProfileChange} onOpenChange={setIsProfileSelectorOpen}
selectedProfileId={testProfile?._id} onSelect={handleTestProfileChange}
/> selectedProfileId={testProfile?._id}
/>
)}
<div className="h-full overflow-auto px-4 py-4"> <div className="h-full overflow-auto px-4 py-4">
<Chat <Chat
key={`chat-${counter}`} key={`chat-${counter}`}

View file

@ -14,11 +14,18 @@ import { SearchProjects } from "./components/search-projects";
import { CustomPromptCard } from "./components/custom-prompt-card"; import { CustomPromptCard } from "./components/custom-prompt-card";
import { Submit } from "./components/submit-button"; import { Submit } from "./components/submit-button";
import { PageHeading } from "@/components/ui/page-heading"; import { PageHeading } from "@/components/ui/page-heading";
import { USE_MULTIPLE_PROJECTS } from "@/app/lib/feature_flags";
const sectionHeaderStyles = clsx( const sectionHeaderStyles = clsx(
"text-sm font-medium", "text-sm font-medium",
"text-gray-900 dark:text-gray-100" "text-gray-900 dark:text-gray-100"
); );
const largeSectionHeaderStyles = clsx(
"text-lg font-medium",
"text-gray-900 dark:text-gray-100"
);
const textareaStyles = clsx( const textareaStyles = clsx(
"w-full", "w-full",
"rounded-lg p-3", "rounded-lg p-3",
@ -34,12 +41,12 @@ export default function App() {
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [selectedCard, setSelectedCard] = useState<'custom' | any>('custom'); const [selectedCard, setSelectedCard] = useState<'custom' | any>('custom');
const [customPrompt, setCustomPrompt] = useState("Create a customer support assistant with one example agent"); const [customPrompt, setCustomPrompt] = useState("");
const [name, setName] = useState(""); const [name, setName] = useState("");
const [defaultName, setDefaultName] = useState('Assistant 1'); const [defaultName, setDefaultName] = useState('Assistant 1');
const [isExamplesExpanded, setIsExamplesExpanded] = useState(false); const [isExamplesExpanded, setIsExamplesExpanded] = useState(false);
const [selectedTemplate, setSelectedTemplate] = useState<string>('blank'); const [selectedTemplate, setSelectedTemplate] = useState<string>('custom');
const [showCustomPrompt, setShowCustomPrompt] = useState(false); const [showCustomPrompt, setShowCustomPrompt] = useState(true);
const [promptError, setPromptError] = useState<string | null>(null); const [promptError, setPromptError] = useState<string | null>(null);
const [hasEditedPrompt, setHasEditedPrompt] = useState(false); const [hasEditedPrompt, setHasEditedPrompt] = useState(false);
@ -88,7 +95,7 @@ export default function App() {
setSelectedCard(card); setSelectedCard(card);
if (card === 'custom') { if (card === 'custom') {
setCustomPrompt("Create a customer support assistant with one example agent"); setCustomPrompt("");
} else { } else {
setCustomPrompt(card.prompt || card.description); setCustomPrompt(card.prompt || card.description);
} }
@ -178,64 +185,121 @@ export default function App() {
"flex-1 px-12 pt-4 pb-32" "flex-1 px-12 pt-4 pb-32"
)}> )}>
<PageHeading <PageHeading
title="Projects" title={USE_MULTIPLE_PROJECTS ? "Projects" : "Let's get started"}
description="Select an existing project or create a new one" description={USE_MULTIPLE_PROJECTS
? "Select an existing project or create a new one"
: "Create a multi-agent assistant in minutes"
}
/> />
<div className="grid grid-cols-1 lg:grid-cols-[1fr,2fr] gap-8 mt-8"> <div className={clsx(
USE_MULTIPLE_PROJECTS
? "grid grid-cols-1 lg:grid-cols-[1fr,2fr] gap-8 mt-8"
: "mt-8 -mx-12"
)}>
{/* Left side: Project Selection */} {/* Left side: Project Selection */}
<div className="overflow-auto"> {USE_MULTIPLE_PROJECTS && (
<SearchProjects <div className="overflow-auto">
projects={projects} <SearchProjects
isLoading={isLoading} projects={projects}
heading="Select an existing project" isLoading={isLoading}
subheading="Choose from your projects" heading="Select an existing project"
className="h-full" subheading="Choose from your projects"
/> className="h-full"
</div> />
</div>
)}
{/* Right side: Project Creation */} {/* Right side: Project Creation */}
<div className="overflow-auto"> <div className={clsx(
<section className="card h-full"> "overflow-auto",
<div className="px-4 pt-4"> !USE_MULTIPLE_PROJECTS && "max-w-none px-12 py-12"
<SectionHeading subheading="Set up a new AI assistant"> )}>
Create a new project <section className={clsx(
</SectionHeading> "card h-full",
</div> !USE_MULTIPLE_PROJECTS && "px-24",
USE_MULTIPLE_PROJECTS && "px-8"
)}>
{USE_MULTIPLE_PROJECTS && (
<div className="pt-12">
<SectionHeading subheading="Set up a new AI assistant">
Create a new project
</SectionHeading>
</div>
)}
<form <form
id="create-project-form" id="create-project-form"
action={handleSubmit} action={handleSubmit}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
className="px-4 pt-4 pb-8 space-y-8" className="pt-12 pb-16 space-y-12"
> >
{/* Name Section */} {/* Name Section */}
<div className="space-y-4"> {USE_MULTIPLE_PROJECTS && (
<div className="flex flex-col gap-2"> <div className="space-y-4">
<label className={sectionHeaderStyles}> <div className="flex flex-col gap-4">
Name <label className={largeSectionHeaderStyles}>
</label> Name
<Textarea </label>
required <Textarea
name="name" required
value={name} name="name"
onChange={(e) => setName(e.target.value)} value={name}
className={clsx( onChange={(e) => setName(e.target.value)}
textareaStyles, className={clsx(
"min-h-[60px]", textareaStyles,
"text-base", "min-h-[60px]",
"text-gray-900 dark:text-gray-100" "text-base",
)} "text-gray-900 dark:text-gray-100"
placeholder={defaultName} )}
/> placeholder={defaultName}
/>
</div>
</div> </div>
</div> )}
{/* Custom Prompt Section - Only show when needed */}
{showCustomPrompt && (
<div className="space-y-4">
<div className="flex flex-col gap-4">
<label className={largeSectionHeaderStyles}>
{selectedTemplate === 'custom' ? 'What do you want to build?' : 'Customize the description'}
</label>
<div className="space-y-2">
<Textarea
value={customPrompt}
onChange={(e) => {
setCustomPrompt(e.target.value);
setPromptError(null);
}}
placeholder="Example: Create a customer support assistant that can handle product inquiries and returns"
className={clsx(
textareaStyles,
"text-base",
"text-gray-900 dark:text-gray-100",
promptError && "border-red-500 focus:ring-red-500/20"
)}
style={{ minHeight: "120px" }}
autoFocus
autoResize
required
/>
{promptError && (
<p className="text-sm text-red-500">
{promptError}
</p>
)}
</div>
</div>
</div>
)}
{/* Template Selection Section */} {/* Template Selection Section */}
<div className="space-y-4"> <div className="space-y-4">
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-4">
<label className={sectionHeaderStyles}> <label className={largeSectionHeaderStyles}>
Choose how to start How do you want to start?
</label> </label>
<select <select
value={selectedTemplate} value={selectedTemplate}
@ -259,9 +323,9 @@ export default function App() {
"dark:bg-[url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22%23ffffff%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpolyline%20points%3D%226%209%2012%2015%2018%209%22%3E%3C%2Fpolyline%3E%3C%2Fsvg%3E')]" "dark:bg-[url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22%23ffffff%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpolyline%20points%3D%226%209%2012%2015%2018%209%22%3E%3C%2Fpolyline%3E%3C%2Fsvg%3E')]"
)} )}
> >
<option value="blank">Start with a blank template</option> <option value="custom">Tell us what you want to build</option>
<option value="custom">Write your own starting prompt</option> <option value="blank">I'll provide a description later</option>
<optgroup label="Example Prompts"> <optgroup label="Customizable Examples">
{starting_copilot_prompts && {starting_copilot_prompts &&
Object.entries(starting_copilot_prompts) Object.entries(starting_copilot_prompts)
.filter(([name]) => name !== 'Blank Template') .filter(([name]) => name !== 'Blank Template')
@ -276,41 +340,7 @@ export default function App() {
</div> </div>
</div> </div>
{/* Custom Prompt Section - Only show when needed */}
{showCustomPrompt && (
<div className="space-y-4">
<div className="flex flex-col gap-2">
<label className={sectionHeaderStyles}>
{selectedTemplate === 'custom' ? 'Write your prompt' : 'Customize the prompt'}
</label>
<div className="space-y-2">
<Textarea
value={customPrompt}
onChange={(e) => {
setCustomPrompt(e.target.value);
setPromptError(null);
}}
placeholder="Example: Create a customer support assistant that can handle product inquiries and returns"
className={clsx(
textareaStyles,
"min-h-[100px]",
"text-base",
"text-gray-900 dark:text-gray-100",
promptError && "border-red-500 focus:ring-red-500/20"
)}
autoResize
required
/>
{promptError && (
<p className="text-sm text-red-500">
{promptError}
</p>
)}
</div>
</div>
</div>
)}
{/* Submit Button */} {/* Submit Button */}
<div className="pt-6 w-full"> <div className="pt-6 w-full">
<Submit /> <Submit />

View file

@ -27,7 +27,7 @@ export function Submit() {
isLoading={pending} isLoading={pending}
startContent={<PlusIcon size={16} />} startContent={<PlusIcon size={16} />}
> >
Create project Create assistant
</Button> </Button>
</div> </div>
); );