mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-05-25 18:55:19 +02:00
Hide prompts via feature flag and allow auto-resizing of entity lists
This commit is contained in:
parent
96d87b6bdb
commit
5e706f0684
2 changed files with 107 additions and 94 deletions
|
|
@ -14,4 +14,5 @@ export const USE_MULTIPLE_PROJECTS = true;
|
||||||
export const USE_VOICE_FEATURE = false;
|
export const USE_VOICE_FEATURE = false;
|
||||||
export const USE_TRANSFER_CONTROL_OPTIONS = true;
|
export const USE_TRANSFER_CONTROL_OPTIONS = true;
|
||||||
export const USE_PRODUCT_TOUR = true;
|
export const USE_PRODUCT_TOUR = true;
|
||||||
export const SHOW_COPILOT_MARQUEE = false;
|
export const SHOW_COPILOT_MARQUEE = false;
|
||||||
|
export const SHOW_PROMPTS_SECTION = false;
|
||||||
|
|
@ -25,6 +25,7 @@ import { deleteDataSource } from '../../../actions/datasource_actions';
|
||||||
import { ToolkitAuthModal } from '../tools/components/ToolkitAuthModal';
|
import { ToolkitAuthModal } from '../tools/components/ToolkitAuthModal';
|
||||||
import { deleteConnectedAccount } from '@/app/actions/composio_actions';
|
import { deleteConnectedAccount } from '@/app/actions/composio_actions';
|
||||||
import { ProjectWideChangeConfirmationModal } from '@/components/common/project-wide-change-confirmation-modal';
|
import { ProjectWideChangeConfirmationModal } from '@/components/common/project-wide-change-confirmation-modal';
|
||||||
|
import { SHOW_PROMPTS_SECTION } from '../../../lib/feature_flags';
|
||||||
|
|
||||||
// Reduced gap size to match Cursor's UI
|
// Reduced gap size to match Cursor's UI
|
||||||
const GAP_SIZE = 4; // 1 unit * 4px (tailwind's default spacing unit)
|
const GAP_SIZE = 4; // 1 unit * 4px (tailwind's default spacing unit)
|
||||||
|
|
@ -516,6 +517,7 @@ export const EntityList = forwardRef<
|
||||||
|
|
||||||
// Calculate panel sizes based on expanded state
|
// Calculate panel sizes based on expanded state
|
||||||
const getPanelSize = (panelName: 'agents' | 'tools' | 'data' | 'prompts') => {
|
const getPanelSize = (panelName: 'agents' | 'tools' | 'data' | 'prompts') => {
|
||||||
|
// If this panel is collapsed, return minimum size
|
||||||
if (!expandedPanels[panelName]) {
|
if (!expandedPanels[panelName]) {
|
||||||
return 8; // Collapsed height (53px equivalent)
|
return 8; // Collapsed height (53px equivalent)
|
||||||
}
|
}
|
||||||
|
|
@ -523,28 +525,35 @@ export const EntityList = forwardRef<
|
||||||
// Base size when expanded
|
// Base size when expanded
|
||||||
let size = DEFAULT_SIZES[panelName];
|
let size = DEFAULT_SIZES[panelName];
|
||||||
|
|
||||||
// Redistribute space from collapsed panels to the panel above
|
// Calculate total space available from collapsed/hidden panels
|
||||||
if (panelName === 'agents') {
|
let availableSpace = 0;
|
||||||
if (!expandedPanels.tools) {
|
|
||||||
size += DEFAULT_SIZES.tools;
|
// Add space from collapsed panels and hidden prompts
|
||||||
}
|
if (!expandedPanels.tools) {
|
||||||
if (!expandedPanels.data) {
|
availableSpace += DEFAULT_SIZES.tools;
|
||||||
size += DEFAULT_SIZES.data;
|
}
|
||||||
}
|
if (!expandedPanels.data) {
|
||||||
if (!expandedPanels.prompts) {
|
availableSpace += DEFAULT_SIZES.data;
|
||||||
size += DEFAULT_SIZES.prompts;
|
}
|
||||||
}
|
if (!expandedPanels.prompts || !SHOW_PROMPTS_SECTION) {
|
||||||
} else if (panelName === 'tools') {
|
availableSpace += DEFAULT_SIZES.prompts;
|
||||||
if (!expandedPanels.data && expandedPanels.agents) {
|
}
|
||||||
size += DEFAULT_SIZES.data;
|
if (!expandedPanels.agents) {
|
||||||
}
|
availableSpace += DEFAULT_SIZES.agents;
|
||||||
if (!expandedPanels.prompts && expandedPanels.agents) {
|
}
|
||||||
size += DEFAULT_SIZES.prompts;
|
|
||||||
}
|
// Find the topmost expanded panel to give it the extra space
|
||||||
} else if (panelName === 'data') {
|
const panelOrder = ['agents', 'tools', 'data', 'prompts'] as const;
|
||||||
if (!expandedPanels.prompts && (expandedPanels.agents || expandedPanels.tools)) {
|
const expandedVisiblePanels = panelOrder.filter(panel => {
|
||||||
size += DEFAULT_SIZES.prompts;
|
if (panel === 'prompts') {
|
||||||
|
return expandedPanels[panel] && SHOW_PROMPTS_SECTION;
|
||||||
}
|
}
|
||||||
|
return expandedPanels[panel];
|
||||||
|
});
|
||||||
|
|
||||||
|
// If this is the topmost expanded panel, give it all the available space
|
||||||
|
if (expandedVisiblePanels.length > 0 && expandedVisiblePanels[0] === panelName) {
|
||||||
|
size += availableSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
|
|
@ -637,6 +646,7 @@ export const EntityList = forwardRef<
|
||||||
return (
|
return (
|
||||||
<div ref={containerRef} className="flex flex-col h-full min-h-0">
|
<div ref={containerRef} className="flex flex-col h-full min-h-0">
|
||||||
<ResizablePanelGroup
|
<ResizablePanelGroup
|
||||||
|
key={`${expandedPanels.agents}-${expandedPanels.tools}-${expandedPanels.data}-${expandedPanels.prompts}-${SHOW_PROMPTS_SECTION}`}
|
||||||
direction="vertical"
|
direction="vertical"
|
||||||
className="flex-1 min-h-0 flex flex-col"
|
className="flex-1 min-h-0 flex flex-col"
|
||||||
style={{ gap: `${GAP_SIZE}px` }}
|
style={{ gap: `${GAP_SIZE}px` }}
|
||||||
|
|
@ -1084,82 +1094,84 @@ export const EntityList = forwardRef<
|
||||||
</Panel>
|
</Panel>
|
||||||
</ResizablePanel>
|
</ResizablePanel>
|
||||||
|
|
||||||
<ResizableHandle withHandle className="w-[3px] bg-transparent" />
|
{SHOW_PROMPTS_SECTION && <ResizableHandle withHandle className="w-[3px] bg-transparent" />}
|
||||||
|
|
||||||
{/* Prompts Panel */}
|
{/* Prompts Panel */}
|
||||||
<ResizablePanel
|
{SHOW_PROMPTS_SECTION && (
|
||||||
defaultSize={getPanelSize('prompts')}
|
<ResizablePanel
|
||||||
minSize={expandedPanels.prompts ? 20 : 8}
|
defaultSize={getPanelSize('prompts')}
|
||||||
maxSize={100}
|
minSize={expandedPanels.prompts ? 20 : 8}
|
||||||
className="flex flex-col min-h-0 h-full"
|
maxSize={100}
|
||||||
>
|
className="flex flex-col min-h-0 h-full"
|
||||||
<Panel
|
|
||||||
variant="entity-list"
|
|
||||||
tourTarget="entity-prompts"
|
|
||||||
className={clsx(
|
|
||||||
"h-full",
|
|
||||||
!expandedPanels.prompts && "h-[53px]!"
|
|
||||||
)}
|
|
||||||
title={
|
|
||||||
<div className={`${headerClasses} rounded-md transition-colors h-full`}>
|
|
||||||
<div className="flex items-center gap-2 h-full">
|
|
||||||
<button onClick={() => setExpandedPanels(prev => ({ ...prev, prompts: !prev.prompts }))}>
|
|
||||||
{expandedPanels.prompts ? (
|
|
||||||
<ChevronDown className="w-4 h-4" />
|
|
||||||
) : (
|
|
||||||
<ChevronRight className="w-4 h-4" />
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
<PenLine className="w-4 h-4" />
|
|
||||||
<span>Prompts</span>
|
|
||||||
</div>
|
|
||||||
<Button
|
|
||||||
variant="secondary"
|
|
||||||
size="sm"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
setExpandedPanels(prev => ({ ...prev, prompts: true }));
|
|
||||||
onAddPrompt({});
|
|
||||||
}}
|
|
||||||
className={`group ${buttonClasses}`}
|
|
||||||
showHoverContent={true}
|
|
||||||
hoverContent="Add Prompt"
|
|
||||||
>
|
|
||||||
<PlusIcon className="w-4 h-4" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
{expandedPanels.prompts && (
|
<Panel
|
||||||
<div className="h-[calc(100%-53px)] overflow-y-auto">
|
variant="entity-list"
|
||||||
<div className="p-2">
|
tourTarget="entity-prompts"
|
||||||
{prompts.length > 0 ? (
|
className={clsx(
|
||||||
<div className="space-y-1">
|
"h-full",
|
||||||
{prompts.map((prompt, index) => (
|
!expandedPanels.prompts && "h-[53px]!"
|
||||||
<ListItemWithMenu
|
)}
|
||||||
key={`prompt-${index}`}
|
title={
|
||||||
name={prompt.name}
|
<div className={`${headerClasses} rounded-md transition-colors h-full`}>
|
||||||
isSelected={selectedEntity?.type === "prompt" && selectedEntity.name === prompt.name}
|
<div className="flex items-center gap-2 h-full">
|
||||||
onClick={() => onSelectPrompt(prompt.name)}
|
<button onClick={() => setExpandedPanels(prev => ({ ...prev, prompts: !prev.prompts }))}>
|
||||||
selectedRef={selectedEntity?.type === "prompt" && selectedEntity.name === prompt.name ? selectedRef : undefined}
|
{expandedPanels.prompts ? (
|
||||||
icon={<ScrollText className="w-4 h-4 text-blue-600/70 dark:text-blue-500/70" />}
|
<ChevronDown className="w-4 h-4" />
|
||||||
menuContent={
|
) : (
|
||||||
<EntityDropdown
|
<ChevronRight className="w-4 h-4" />
|
||||||
name={prompt.name}
|
)}
|
||||||
onDelete={onDeletePrompt}
|
</button>
|
||||||
/>
|
<PenLine className="w-4 h-4" />
|
||||||
}
|
<span>Prompts</span>
|
||||||
/>
|
</div>
|
||||||
))}
|
<Button
|
||||||
</div>
|
variant="secondary"
|
||||||
) : (
|
size="sm"
|
||||||
<EmptyState entity="prompts" hasFilteredItems={false} />
|
onClick={(e) => {
|
||||||
)}
|
e.stopPropagation();
|
||||||
|
setExpandedPanels(prev => ({ ...prev, prompts: true }));
|
||||||
|
onAddPrompt({});
|
||||||
|
}}
|
||||||
|
className={`group ${buttonClasses}`}
|
||||||
|
showHoverContent={true}
|
||||||
|
hoverContent="Add Prompt"
|
||||||
|
>
|
||||||
|
<PlusIcon className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
)}
|
>
|
||||||
</Panel>
|
{expandedPanels.prompts && (
|
||||||
</ResizablePanel>
|
<div className="h-[calc(100%-53px)] overflow-y-auto">
|
||||||
|
<div className="p-2">
|
||||||
|
{prompts.length > 0 ? (
|
||||||
|
<div className="space-y-1">
|
||||||
|
{prompts.map((prompt, index) => (
|
||||||
|
<ListItemWithMenu
|
||||||
|
key={`prompt-${index}`}
|
||||||
|
name={prompt.name}
|
||||||
|
isSelected={selectedEntity?.type === "prompt" && selectedEntity.name === prompt.name}
|
||||||
|
onClick={() => onSelectPrompt(prompt.name)}
|
||||||
|
selectedRef={selectedEntity?.type === "prompt" && selectedEntity.name === prompt.name ? selectedRef : undefined}
|
||||||
|
icon={<ScrollText className="w-4 h-4 text-blue-600/70 dark:text-blue-500/70" />}
|
||||||
|
menuContent={
|
||||||
|
<EntityDropdown
|
||||||
|
name={prompt.name}
|
||||||
|
onDelete={onDeletePrompt}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<EmptyState entity="prompts" hasFilteredItems={false} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Panel>
|
||||||
|
</ResizablePanel>
|
||||||
|
)}
|
||||||
</ResizablePanelGroup>
|
</ResizablePanelGroup>
|
||||||
|
|
||||||
<AgentTypeModal
|
<AgentTypeModal
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue