[eric] canvas: empty-state hero yields to open windows, Marketplace/Settings chrome titles dropped

This commit is contained in:
ciregenz
2026-08-06 20:50:13 -07:00
parent 92f00636df
commit 6cbc1979d0
4 changed files with 8 additions and 16 deletions
@@ -52,7 +52,6 @@ interface DashboardCanvasProps {
canvas: Canvas;
selection: Selection;
sessions: Record<string, AgentSession>;
sessionList: AgentSession[];
cards: Record<string, CardPosition>;
viewCards: Record<string, ViewCardPosition>;
browserCards: Record<string, BrowserCardPosition>;
@@ -114,7 +113,6 @@ const DashboardCanvas: React.FC<DashboardCanvasProps> = ({
canvas,
selection,
sessions,
sessionList,
cards,
viewCards,
browserCards,
@@ -515,7 +513,7 @@ const DashboardCanvas: React.FC<DashboardCanvasProps> = ({
/>
</div>
)}
{sessionList.length === 0 && Object.keys(viewCards).length === 0 && Object.keys(browserCards).length === 0 && Object.keys(workflowCards).length === 0 && !workflowsHub && !fullscreenCardId && (
{canvasEmpty && !fullscreenCardId && (
<DashboardEmptyState c={c} onLaunch={onToolbarSend} onStarter={onStarter} />
)}
</Box>
@@ -90,12 +90,16 @@ export function useDashboardController(dashboardId: string, isActive: boolean) {
// Nudge the chat button while the canvas is empty; the first click dismisses it for this visit.
const bounceDismissedRef = useRef(false);
// Truly-empty canvas: matches the empty-state hero's own render condition (fullscreen is handled
const settingsWindowOpen = useAppSelector((s) => !!s.dashboardLayout.settingsCard);
const marketplaceWindowOpen = useAppSelector((s) => !!s.dashboardLayout.marketplaceCard);
// Truly-empty canvas: IS the empty-state hero's render condition (fullscreen is handled
// separately, it display:none's the whole overlay layer), so "pill hidden" always coincides with
// "hero shown" and a workflow-card-only canvas never ends up with no composer at all.
// "hero shown". The singleton windows (Settings, Marketplace, Run Monitor) count as content,
// otherwise the hero floats on top of an open window.
const canvasEmpty = layoutInitialized && sessionList.length === 0
&& Object.keys(viewCards).length === 0 && Object.keys(browserCards).length === 0
&& Object.keys(workflowCards).length === 0 && !workflowsHub;
&& Object.keys(workflowCards).length === 0 && !workflowsHub
&& !settingsWindowOpen && !marketplaceWindowOpen && !workflowsMonitorCard;
useEffect(() => {
setNewAgentBounce(canvasEmpty && !bounceDismissedRef.current);
}, [canvasEmpty, setNewAgentBounce]);
@@ -1,5 +1,4 @@
import React, { useCallback } from 'react';
import StorefrontIcon from '@mui/icons-material/Storefront';
import { useAppDispatch, useAppSelector } from '@/shared/hooks';
import {
closeMarketplaceCard,
@@ -107,10 +106,6 @@ const MarketplaceAppCard: React.FC<Props> = ({
>
<WindowControls onClose={close} onMinimize={minimize} onTile={onTileZone} tiled={!!tileZone} />
</span>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<StorefrontIcon sx={{ fontSize: 18, color: c.text.secondary, display: 'block' }} />
<span style={{ fontSize: 14, fontWeight: 600, color: c.text.primary, lineHeight: 1 }}>Marketplace</span>
</div>
</div>
<MarketplaceBody />
</>
@@ -1,5 +1,4 @@
import React, { useCallback } from 'react';
import SettingsIcon from '@mui/icons-material/Settings';
import { useAppDispatch, useAppSelector } from '@/shared/hooks';
import {
closeSettingsCard,
@@ -109,10 +108,6 @@ const SettingsAppCard: React.FC<Props> = ({
>
<WindowControls onClose={close} onMinimize={minimize} onTile={onTileZone} tiled={!!tileZone} />
</span>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<SettingsIcon sx={{ fontSize: 18, color: c.text.secondary, display: 'block' }} />
<span style={{ fontSize: 14, fontWeight: 600, color: c.text.primary, lineHeight: 1 }}>Settings</span>
</div>
</div>
<SettingsBody active onRequestClose={close} />
</>