@decido/shell 1.0.0 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/package.json +17 -14
- package/.turbo/turbo-build.log +0 -13
- package/src/AgentPlayer.tsx +0 -105
- package/src/DecidoPlayer.tsx +0 -117
- package/src/bridge/BridgeAgent.ts +0 -443
- package/src/components/DecidoIcon.tsx +0 -56
- package/src/components/JsonTreeEditor.tsx +0 -117
- package/src/components/PanelSplitter.tsx +0 -71
- package/src/components/PluginErrorBoundary.tsx +0 -69
- package/src/components/SafeLiquidUI.tsx +0 -114
- package/src/components/TransientLayer.tsx +0 -92
- package/src/components/agent/AgentChat.tsx +0 -134
- package/src/components/chat-extensions/IntentCatalogPanel.tsx +0 -81
- package/src/components/chat-extensions/chatSlashCommands.ts +0 -101
- package/src/components/controls/CreatorInputBar.tsx +0 -144
- package/src/components/controls/OSToolbar.tsx +0 -90
- package/src/components/controls/TimelineTape.tsx +0 -43
- package/src/components/debug/ActionTimelineTab.tsx +0 -111
- package/src/components/debug/CSSInspectorTab.tsx +0 -436
- package/src/components/debug/ExportTab.tsx +0 -192
- package/src/components/debug/FlowHealthTab.tsx +0 -86
- package/src/components/debug/LogsTab.tsx +0 -110
- package/src/components/debug/MorphStackTab.tsx +0 -241
- package/src/components/debug/NetworkTab.tsx +0 -173
- package/src/components/debug/PerformanceTab.tsx +0 -171
- package/src/components/debug/ProfilesTab.tsx +0 -238
- package/src/components/debug/ReplayTab.tsx +0 -70
- package/src/components/debug/StoresTab.tsx +0 -255
- package/src/components/debug/TopologyTab.tsx +0 -59
- package/src/components/debug/debugConfig.tsx +0 -66
- package/src/components/playground/DebugPanel.tsx +0 -112
- package/src/components/playground/HeaderCenterControls.tsx +0 -92
- package/src/components/playground/KeyframeListItem.tsx +0 -70
- package/src/components/playground/PlaygroundAppSidebar.tsx +0 -171
- package/src/components/playground/PlaygroundBottomControls.tsx +0 -132
- package/src/components/playground/PlaygroundCanvas.tsx +0 -87
- package/src/components/playground/PlaygroundChat.tsx +0 -236
- package/src/components/playground/PlaygroundErrorBoundary.tsx +0 -63
- package/src/components/playground/PlaygroundFloatingInput.tsx +0 -352
- package/src/components/playground/PlaygroundHeader.tsx +0 -222
- package/src/components/playground/PlaygroundSidebar.tsx +0 -136
- package/src/components/playground/PlaygroundTerminal.tsx +0 -44
- package/src/components/playground/SuggestionCards.tsx +0 -29
- package/src/components/playground/demos/ClinicaAINode.tsx +0 -221
- package/src/components/playground/demos/FinanceAINode.tsx +0 -226
- package/src/components/playground/demos/KiaAcademyNode.tsx +0 -250
- package/src/components/playground/demos/KiaBotNode.tsx +0 -207
- package/src/components/playground/demos/KiaCampaignNode.tsx +0 -191
- package/src/components/playground/demos/KiaComplianceNode.tsx +0 -140
- package/src/components/playground/demos/KiaCustomerJourneyNode.tsx +0 -220
- package/src/components/playground/demos/KiaCyberNode.tsx +0 -203
- package/src/components/playground/demos/KiaDashboardNode.tsx +0 -399
- package/src/components/playground/demos/KiaEmbudoOverviewNode.tsx +0 -168
- package/src/components/playground/demos/KiaExecutiveNode.tsx +0 -169
- package/src/components/playground/demos/KiaGamificationNode.tsx +0 -229
- package/src/components/playground/demos/KiaIntelligenceHubNode.tsx +0 -165
- package/src/components/playground/demos/KiaInventoryNode.tsx +0 -183
- package/src/components/playground/demos/KiaLeadScoringNode.tsx +0 -226
- package/src/components/playground/demos/KiaLiveSimulationNode.tsx +0 -177
- package/src/components/playground/demos/KiaMultiDealerNode.tsx +0 -223
- package/src/components/playground/demos/KiaNPSVoiceNode.tsx +0 -214
- package/src/components/playground/demos/KiaOmnichannelNode.tsx +0 -162
- package/src/components/playground/demos/KiaPBIBudgetNode.tsx +0 -152
- package/src/components/playground/demos/KiaPBIConversionNode.tsx +0 -206
- package/src/components/playground/demos/KiaPBIFunnelNode.tsx +0 -184
- package/src/components/playground/demos/KiaPBIOwnershipNode.tsx +0 -113
- package/src/components/playground/demos/KiaPBIPartnerNode.tsx +0 -143
- package/src/components/playground/demos/KiaPBIPreciosNode.tsx +0 -120
- package/src/components/playground/demos/KiaPBIRuntNode.tsx +0 -205
- package/src/components/playground/demos/KiaPartnerScoreNode.tsx +0 -206
- package/src/components/playground/demos/KiaPredictiveNode.tsx +0 -226
- package/src/components/playground/demos/KiaShowroomNode.tsx +0 -194
- package/src/components/playground/demos/KiaStoreNode.tsx +0 -215
- package/src/components/playground/demos/KiaSustainabilityNode.tsx +0 -173
- package/src/components/playground/demos/KiaUsedVehiclesNode.tsx +0 -163
- package/src/components/playground/demos/KiaWorkshopNode.tsx +0 -221
- package/src/components/playground/demos/SmartCityNode.tsx +0 -205
- package/src/components/playground/demos/kia_campaign_manifest.json +0 -112
- package/src/components/playground/input-parts/AIModelSelector.tsx +0 -156
- package/src/components/playground/input-parts/InputActions.tsx +0 -80
- package/src/components/playground/input-parts/InputToolbar.tsx +0 -245
- package/src/components/playground/input-parts/ResourceLibraryPanel.tsx +0 -287
- package/src/components/playground/sidebarDsdIO.ts +0 -82
- package/src/components/settings/SettingsPanel.tsx +0 -267
- package/src/components/shell/AppHeader.tsx +0 -9
- package/src/components/shell/AppShell.tsx +0 -139
- package/src/components/shell/ArtifactBar.tsx +0 -97
- package/src/components/shell/BootScreen.tsx +0 -19
- package/src/components/shell/CenterComposite.tsx +0 -87
- package/src/components/shell/CodeEditorPanel.tsx +0 -88
- package/src/components/shell/GlobalOverlays.tsx +0 -228
- package/src/components/shell/LayoutConfigurator.tsx +0 -209
- package/src/components/shell/LayoutGrid.tsx +0 -178
- package/src/components/shell/MorphShell.tsx +0 -368
- package/src/components/shell/PluginViewer.tsx +0 -147
- package/src/components/shell/ShellNexusPreview.tsx +0 -458
- package/src/components/shell/SlotRenderer.tsx +0 -115
- package/src/components/shell/TabBar.tsx +0 -94
- package/src/components/shell/TemplateLibrary.tsx +0 -195
- package/src/components/shell/layoutConstants.ts +0 -35
- package/src/components/shell/morphStageMeta.ts +0 -15
- package/src/components/shell/shells/BuiltInShells.tsx +0 -443
- package/src/components/shell/shells/DatawayChatShell.tsx +0 -42
- package/src/components/shell/shells/TokenPreview.tsx +0 -339
- package/src/components/shell/shells/bootShells.ts +0 -31
- package/src/components/shells/CreatorShell.tsx +0 -37
- package/src/components/shells/DecidoShell.tsx +0 -447
- package/src/components/shells/ExperimentalChatShell.tsx +0 -245
- package/src/components/shells/UserCanvas.tsx +0 -44
- package/src/components/studio/BlueprintManagerPanel.tsx +0 -137
- package/src/components/studio/DependencyTreePanel.tsx +0 -192
- package/src/components/studio/NodePalette.tsx +0 -92
- package/src/components/studio/NodePropertiesPanel.tsx +0 -81
- package/src/components/studio/ReactFlowEditor.tsx +0 -242
- package/src/components/studio/TimelineEditor.tsx +0 -122
- package/src/components/studio/TimelineKeyframeCard.tsx +0 -99
- package/src/components/studio/VariablePanel.tsx +0 -181
- package/src/components/studio/blueprint/BlueprintCard.tsx +0 -82
- package/src/components/studio/editor/CanvasContextMenu.tsx +0 -107
- package/src/components/studio/editor/EditorToolbar.tsx +0 -80
- package/src/components/studio/editor/StageContentRenderer.tsx +0 -134
- package/src/components/studio/editor/TrackPropertyEditors.tsx +0 -133
- package/src/components/studio/editor/TreeNodeItem.tsx +0 -91
- package/src/components/studio/editor/edgeStyles.ts +0 -43
- package/src/components/studio/editor/editorKeyHandler.ts +0 -95
- package/src/components/studio/editor/nodeTypeRegistry.ts +0 -137
- package/src/components/studio/editor/paletteCatalog.tsx +0 -84
- package/src/components/studio/nodes/shell/InteractionNodes.tsx +0 -82
- package/src/components/studio/nodes/shell/LayoutControlNodes.tsx +0 -69
- package/src/components/studio/nodes/shell/RegisterActionNode.tsx +0 -20
- package/src/components/studio/nodes/shell/RegisterButtonNode.tsx +0 -22
- package/src/components/studio/nodes/shell/RegisterPanelNode.tsx +0 -19
- package/src/components/studio/nodes/shell/RegisterSidebarNode.tsx +0 -19
- package/src/components/studio/nodes/shell/RegisterStatusBarNode.tsx +0 -22
- package/src/components/studio/nodes/shell/RegisterTabNode.tsx +0 -21
- package/src/components/studio/nodes/shell/RegisterTopBarNode.tsx +0 -22
- package/src/components/studio/nodes/shell/ShellConfigNode.tsx +0 -51
- package/src/components/studio/nodes/shell/ShellNodeBase.tsx +0 -100
- package/src/components/studio/nodes/shell/ThemeNodes.tsx +0 -51
- package/src/components/studio/nodes/shell/index.ts +0 -12
- package/src/components/widgets/BroadcastWidget.tsx +0 -93
- package/src/components/widgets/MarketplaceWidget.tsx +0 -298
- package/src/components/widgets/McpToolsWidget.tsx +0 -231
- package/src/components/widgets/OpsDashboard.tsx +0 -59
- package/src/components/widgets/QuickActionsWidget.tsx +0 -60
- package/src/components/widgets/UsageWidget.tsx +0 -112
- package/src/components/widgets/WidgetRenderer.tsx +0 -892
- package/src/components/widgets/WidgetSlotPanel.tsx +0 -213
- package/src/config/IconRegistry.ts +0 -126
- package/src/contexts/NetworkProvider.tsx +0 -162
- package/src/core/AIDirector.ts +0 -71
- package/src/core/EventBus.ts +0 -37
- package/src/core/PluginContext.tsx +0 -141
- package/src/hooks/listeners/useUIStateListener.ts +0 -59
- package/src/hooks/listeners/useWhatsAppListener.ts +0 -110
- package/src/hooks/morphBridge.ts +0 -82
- package/src/hooks/useAIModelSelector.ts +0 -144
- package/src/hooks/useAgentStream.ts +0 -220
- package/src/hooks/useAutoUpdater.ts +0 -89
- package/src/hooks/useBootSequence.ts +0 -20
- package/src/hooks/useExportDSD.ts +0 -53
- package/src/hooks/useFullscreen.ts +0 -35
- package/src/hooks/useGeminiStream.ts +0 -282
- package/src/hooks/useIntentLens.ts +0 -224
- package/src/hooks/useKeyboardShortcuts.ts +0 -69
- package/src/hooks/useLoggerBridge.ts +0 -32
- package/src/hooks/useMcpClient.ts +0 -112
- package/src/hooks/useNexusaiDeploy.ts +0 -118
- package/src/hooks/usePlaybackEngine.ts +0 -21
- package/src/hooks/usePlaygroundCommander.ts +0 -475
- package/src/hooks/usePluginEngine.ts +0 -165
- package/src/hooks/useScreenRecorder.ts +0 -73
- package/src/hooks/useShellKeyboard.ts +0 -40
- package/src/hooks/useShellShortcuts.ts +0 -118
- package/src/hooks/useSoundEffects.ts +0 -35
- package/src/hooks/useStudioConfig.ts +0 -72
- package/src/hooks/useSystemBoot.ts +0 -84
- package/src/hooks/useSystemTelemetry.ts +0 -62
- package/src/lib/debugLogger.ts +0 -80
- package/src/lib/networkInterceptor.ts +0 -100
- package/src/mocks/decido.tsx +0 -41
- package/src/plugins/pluginAPI.ts +0 -190
- package/src/store/McpStore.ts +0 -69
- package/src/store/UpdaterStore.ts +0 -60
- package/src/store/engine.ts +0 -392
- package/src/store/index.ts +0 -4
- package/src/store/layoutPresets.ts +0 -66
- package/src/store/playgroundTypes.ts +0 -98
- package/src/store/useActionTimelineStore.ts +0 -48
- package/src/store/useDebugPanelStore.ts +0 -98
- package/src/store/useDebugProfileStore.ts +0 -130
- package/src/store/useLayoutStore.ts +0 -205
- package/src/store/useMorphInstanceStore.ts +0 -289
- package/src/store/useMorphologyStore.ts +0 -103
- package/src/store/usePlaygroundStore.ts +0 -236
- package/src/store/useShellRegistry.ts +0 -123
- package/src/store/useSuggestionsStore.ts +0 -57
- package/src/store/useThemeStore.ts +0 -399
- package/src/store/useUIComponentStore.ts +0 -179
- package/src/types/DecidoStoryDefinition.ts +0 -43
- package/src/utils/ai/ai-architect.ts +0 -92
- package/src/utils/ai/ai-code.ts +0 -187
- package/src/utils/ai/ai-core.ts +0 -50
- package/src/utils/ai/ai-media.ts +0 -292
- package/src/utils/layoutGraph.ts +0 -67
- package/tsconfig.json +0 -17
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import React, { useState, useCallback } from 'react';
|
|
2
|
-
import { motion, AnimatePresence } from 'motion/react';
|
|
3
|
-
import { Settings, Grid3X3, Save, RotateCcw, Trash2, ChevronDown, SlidersHorizontal } from 'lucide-react';
|
|
4
|
-
import { useLayoutStore, type RegionId, type SlotComponentId, BUILT_IN_PRESETS } from '../../store/useLayoutStore';
|
|
5
|
-
import { getAvailableSlotComponents } from './SlotRenderer';
|
|
6
|
-
import { REGION_LABELS, SLOT_OPTIONS } from './layoutConstants';
|
|
7
|
-
|
|
8
|
-
export function LayoutConfigurator() {
|
|
9
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
10
|
-
const [regionsOpen, setRegionsOpen] = useState(false);
|
|
11
|
-
const [presetName, setPresetName] = useState('');
|
|
12
|
-
|
|
13
|
-
const slots = useLayoutStore((s) => s.slots);
|
|
14
|
-
const setSlot = useLayoutStore((s) => s.setSlot);
|
|
15
|
-
const resetLayout = useLayoutStore((s) => s.resetLayout);
|
|
16
|
-
const savedPresets = useLayoutStore((s) => s.savedPresets);
|
|
17
|
-
const savePreset = useLayoutStore((s) => s.savePreset);
|
|
18
|
-
const loadPreset = useLayoutStore((s) => s.loadPreset);
|
|
19
|
-
const deletePreset = useLayoutStore((s) => s.deletePreset);
|
|
20
|
-
|
|
21
|
-
const handleSave = useCallback(() => {
|
|
22
|
-
if (presetName.trim()) {
|
|
23
|
-
savePreset(presetName.trim());
|
|
24
|
-
setPresetName('');
|
|
25
|
-
}
|
|
26
|
-
}, [presetName, savePreset]);
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<div className="relative">
|
|
30
|
-
{/* Trigger Button */}
|
|
31
|
-
<button
|
|
32
|
-
onClick={() => setIsOpen(!isOpen)}
|
|
33
|
-
className={`p-2 rounded-lg transition-all ${
|
|
34
|
-
isOpen
|
|
35
|
-
? 'bg-cyan-500/20 text-cyan-400 shadow-[0_0_10px_rgba(6,182,212,0.2)]'
|
|
36
|
-
: 'text-text-muted hover:text-text-primary hover:bg-surface-glass'
|
|
37
|
-
}`}
|
|
38
|
-
title="Layout Configurator"
|
|
39
|
-
>
|
|
40
|
-
<Grid3X3 size={16} />
|
|
41
|
-
</button>
|
|
42
|
-
|
|
43
|
-
{/* Dropdown Panel */}
|
|
44
|
-
<AnimatePresence>
|
|
45
|
-
{isOpen && (
|
|
46
|
-
<>
|
|
47
|
-
{/* Backdrop */}
|
|
48
|
-
<div
|
|
49
|
-
className="fixed inset-0 z-800"
|
|
50
|
-
style={{ position: 'fixed', inset: 0, zIndex: 800 }}
|
|
51
|
-
onClick={() => setIsOpen(false)}
|
|
52
|
-
/>
|
|
53
|
-
|
|
54
|
-
<motion.div
|
|
55
|
-
initial={{ opacity: 0, y: -8, scale: 0.95 }}
|
|
56
|
-
animate={{ opacity: 1, y: 0, scale: 1 }}
|
|
57
|
-
exit={{ opacity: 0, y: -8, scale: 0.95 }}
|
|
58
|
-
transition={{ type: 'spring', damping: 25, stiffness: 300 }}
|
|
59
|
-
className="absolute top-full right-0 mt-2 w-[calc(100vw-2rem)] sm:w-[380px] z-801
|
|
60
|
-
bg-surface-tertiary border border-border-default rounded-xl sm:rounded-2xl shadow-2xl overflow-hidden"
|
|
61
|
-
>
|
|
62
|
-
{/* Header */}
|
|
63
|
-
<div className="px-4 py-3 border-b border-border-subtle flex items-center justify-between">
|
|
64
|
-
<div className="flex items-center gap-2">
|
|
65
|
-
<Settings size={14} className="text-cyan-400" />
|
|
66
|
-
<h3 className="text-sm font-bold text-text-primary">Layout Configurator</h3>
|
|
67
|
-
</div>
|
|
68
|
-
<div className="flex items-center gap-1">
|
|
69
|
-
{Object.keys(BUILT_IN_PRESETS).map((preset) => (
|
|
70
|
-
<button
|
|
71
|
-
key={preset}
|
|
72
|
-
onClick={() => resetLayout(preset)}
|
|
73
|
-
className="px-2.5 py-1 text-[10px] font-bold uppercase tracking-wider
|
|
74
|
-
rounded-full bg-surface-glass text-text-muted hover:text-text-primary hover:bg-surface-glass
|
|
75
|
-
transition-colors border border-border-subtle"
|
|
76
|
-
>
|
|
77
|
-
{preset}
|
|
78
|
-
</button>
|
|
79
|
-
))}
|
|
80
|
-
</div>
|
|
81
|
-
</div>
|
|
82
|
-
|
|
83
|
-
{/* Region Grid (Collapsible) */}
|
|
84
|
-
<div>
|
|
85
|
-
<button
|
|
86
|
-
onClick={() => setRegionsOpen(!regionsOpen)}
|
|
87
|
-
className="w-full px-4 py-2.5 flex items-center justify-between hover:bg-surface-glass transition-colors group"
|
|
88
|
-
>
|
|
89
|
-
<div className="flex items-center gap-2 text-xs font-medium text-text-secondary group-hover:text-text-primary">
|
|
90
|
-
<SlidersHorizontal size={14} className="text-cyan-500/50" />
|
|
91
|
-
<span>Configuración de Slots</span>
|
|
92
|
-
<span className="text-[9px] px-1.5 rounded-full bg-cyan-500/10 text-cyan-400">6 REGIONES</span>
|
|
93
|
-
</div>
|
|
94
|
-
<motion.div animate={{ rotate: regionsOpen ? 180 : 0 }}>
|
|
95
|
-
<ChevronDown size={14} className="text-text-muted" />
|
|
96
|
-
</motion.div>
|
|
97
|
-
</button>
|
|
98
|
-
|
|
99
|
-
<AnimatePresence initial={false}>
|
|
100
|
-
{regionsOpen && (
|
|
101
|
-
<motion.div
|
|
102
|
-
initial={{ height: 0, opacity: 0 }}
|
|
103
|
-
animate={{ height: "auto", opacity: 1 }}
|
|
104
|
-
exit={{ height: 0, opacity: 0 }}
|
|
105
|
-
transition={{ duration: 0.2, ease: "easeInOut" }}
|
|
106
|
-
className="overflow-hidden"
|
|
107
|
-
>
|
|
108
|
-
<div className="px-4 pb-4 pt-1 space-y-2 bg-black/10">
|
|
109
|
-
{(Object.keys(REGION_LABELS) as RegionId[]).map((regionId) => (
|
|
110
|
-
<div key={regionId} className="flex items-center gap-3">
|
|
111
|
-
<div className="w-20 flex items-center gap-1.5">
|
|
112
|
-
<span className="w-5 h-5 rounded bg-surface-glass flex items-center justify-center
|
|
113
|
-
text-[9px] font-bold font-mono text-cyan-400/60 shadow-inner">
|
|
114
|
-
{regionId}
|
|
115
|
-
</span>
|
|
116
|
-
<span className="text-[10px] text-text-muted truncate">
|
|
117
|
-
{REGION_LABELS[regionId]}
|
|
118
|
-
</span>
|
|
119
|
-
</div>
|
|
120
|
-
<div className="flex-1 relative">
|
|
121
|
-
<select
|
|
122
|
-
value={slots[regionId] || ''}
|
|
123
|
-
onChange={(e) => setSlot(regionId, (e.target.value || null) as SlotComponentId)}
|
|
124
|
-
className="w-full bg-surface-secondary border border-border-default rounded-lg px-3 py-1.5
|
|
125
|
-
text-xs text-text-primary appearance-none cursor-pointer
|
|
126
|
-
hover:border-border-strong transition-colors
|
|
127
|
-
focus:outline-hidden focus:border-cyan-500/40"
|
|
128
|
-
>
|
|
129
|
-
{SLOT_OPTIONS.map((opt) => (
|
|
130
|
-
<option key={opt.id || 'null'} value={opt.id || ''}>
|
|
131
|
-
{opt.label}
|
|
132
|
-
</option>
|
|
133
|
-
))}
|
|
134
|
-
</select>
|
|
135
|
-
<ChevronDown size={12} className="absolute right-2.5 top-1/2 -translate-y-1/2 text-text-muted pointer-events-none" />
|
|
136
|
-
</div>
|
|
137
|
-
</div>
|
|
138
|
-
))}
|
|
139
|
-
</div>
|
|
140
|
-
</motion.div>
|
|
141
|
-
)}
|
|
142
|
-
</AnimatePresence>
|
|
143
|
-
</div>
|
|
144
|
-
|
|
145
|
-
{/* Custom Presets Section */}
|
|
146
|
-
<div className="px-4 pb-3 border-t border-border-subtle pt-3">
|
|
147
|
-
<div className="flex items-center gap-2 mb-2">
|
|
148
|
-
<input
|
|
149
|
-
value={presetName}
|
|
150
|
-
onChange={(e) => setPresetName(e.target.value)}
|
|
151
|
-
onKeyDown={(e) => e.key === 'Enter' && handleSave()}
|
|
152
|
-
placeholder="Nombre del preset..."
|
|
153
|
-
className="flex-1 bg-surface-glass border border-border-default rounded-lg px-3 py-1.5
|
|
154
|
-
text-xs text-text-primary placeholder:text-text-muted outline-hidden
|
|
155
|
-
focus:border-cyan-500/40"
|
|
156
|
-
/>
|
|
157
|
-
<button
|
|
158
|
-
onClick={handleSave}
|
|
159
|
-
disabled={!presetName.trim()}
|
|
160
|
-
className="p-1.5 rounded-lg bg-cyan-500/10 text-cyan-400 hover:bg-cyan-500/20
|
|
161
|
-
disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
|
|
162
|
-
title="Guardar Preset"
|
|
163
|
-
>
|
|
164
|
-
<Save size={14} />
|
|
165
|
-
</button>
|
|
166
|
-
</div>
|
|
167
|
-
|
|
168
|
-
{savedPresets.length > 0 && (
|
|
169
|
-
<div className="space-y-1 max-h-[120px] overflow-y-auto">
|
|
170
|
-
{savedPresets.map((preset) => (
|
|
171
|
-
<div key={preset.id} className="flex items-center gap-2 group">
|
|
172
|
-
<button
|
|
173
|
-
onClick={() => loadPreset(preset.id)}
|
|
174
|
-
className="flex-1 text-left px-2 py-1 text-[11px] text-text-secondary
|
|
175
|
-
hover:text-text-primary hover:bg-surface-glass rounded-lg transition-colors"
|
|
176
|
-
>
|
|
177
|
-
{preset.name}
|
|
178
|
-
</button>
|
|
179
|
-
<button
|
|
180
|
-
onClick={() => deletePreset(preset.id)}
|
|
181
|
-
className="p-1 rounded text-text-muted hover:text-red-400
|
|
182
|
-
opacity-0 group-hover:opacity-100 transition-all"
|
|
183
|
-
>
|
|
184
|
-
<Trash2 size={12} />
|
|
185
|
-
</button>
|
|
186
|
-
</div>
|
|
187
|
-
))}
|
|
188
|
-
</div>
|
|
189
|
-
)}
|
|
190
|
-
</div>
|
|
191
|
-
|
|
192
|
-
{/* Footer */}
|
|
193
|
-
<div className="px-4 py-2 border-t border-border-subtle flex items-center justify-between text-[10px] text-text-muted">
|
|
194
|
-
<span>⌘K → buscar slots</span>
|
|
195
|
-
<button
|
|
196
|
-
onClick={() => resetLayout('player')}
|
|
197
|
-
className="flex items-center gap-1 hover:text-text-secondary transition-colors"
|
|
198
|
-
>
|
|
199
|
-
<RotateCcw size={10} />
|
|
200
|
-
Reset
|
|
201
|
-
</button>
|
|
202
|
-
</div>
|
|
203
|
-
</motion.div>
|
|
204
|
-
</>
|
|
205
|
-
)}
|
|
206
|
-
</AnimatePresence>
|
|
207
|
-
</div>
|
|
208
|
-
);
|
|
209
|
-
}
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Panel, Group as PanelGroup, Separator as PanelResizeHandle } from 'react-resizable-panels';
|
|
3
|
-
import { useLayoutStore } from '../../store/useLayoutStore';
|
|
4
|
-
import { SlotRenderer } from './SlotRenderer';
|
|
5
|
-
import { TabBar } from './TabBar';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* LayoutGrid — Configurable grid layout for the Decido OS workspace.
|
|
9
|
-
*
|
|
10
|
-
* Architecture (from the user's boceto):
|
|
11
|
-
* ┌─── AppHeader (rendered by parent) ──────────────────┐
|
|
12
|
-
* ├── T1 ─┤──── T2 (TabBar + Commands) ────┤── T3 ─────┤
|
|
13
|
-
* ├───┐ ┌─────────────────────────┐ ┌──────────┤ │
|
|
14
|
-
* │R1 │ │ Main Content │ │ R3 │ │
|
|
15
|
-
* │ │ │ (children) │ │ │ │
|
|
16
|
-
* ├───┤ │ │ ├──────────┤ │
|
|
17
|
-
* │R2 │ │ │ │ R4 │ │
|
|
18
|
-
* └───┘ └─────────────────────────┘ └──────────┘ │
|
|
19
|
-
* ┌────── R6 (StatusBar) ──────────────────┐ │
|
|
20
|
-
* └────────────────────────────────────────┘ │
|
|
21
|
-
*
|
|
22
|
-
* The grid reads slot assignments from useLayoutStore.
|
|
23
|
-
* PanelResizeHandle between all regions for user-resizable panels.
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
/** Resize handle classes and inner elements */
|
|
27
|
-
const V_HANDLE_CLASSES = "w-1.5 hover:bg-cyan-500/20 active:bg-cyan-500/30 transition-colors cursor-col-resize z-40 relative group flex items-center justify-center";
|
|
28
|
-
const V_HANDLE_INNER = <div className="w-[2px] h-10 bg-white/5 rounded-full group-hover:bg-cyan-500/60 transition-colors" />;
|
|
29
|
-
|
|
30
|
-
const H_HANDLE_CLASSES = "h-1.5 hover:bg-cyan-500/20 active:bg-cyan-500/30 transition-colors cursor-row-resize z-40 relative group flex items-center justify-center";
|
|
31
|
-
const H_HANDLE_INNER = <div className="h-[2px] w-10 bg-white/5 rounded-full group-hover:bg-cyan-500/60 transition-colors" />;
|
|
32
|
-
|
|
33
|
-
/** Shared inset shadow for depth perception on side panels */
|
|
34
|
-
const LEFT_PANEL_CLASSES = "h-full overflow-hidden flex flex-col min-w-0 min-h-0 bg-surface-secondary border-r border-border-subtle shadow-[inset_-6px_0_20px_rgba(0,0,0,0.15)]";
|
|
35
|
-
const RIGHT_PANEL_CLASSES = "h-full overflow-hidden flex flex-col min-w-0 min-h-0 bg-surface-secondary border-l border-border-subtle shadow-[inset_6px_0_20px_rgba(0,0,0,0.15)]";
|
|
36
|
-
|
|
37
|
-
interface LayoutGridProps {
|
|
38
|
-
/** Main content to render in the center (chat area in player mode, or custom) */
|
|
39
|
-
children: React.ReactNode;
|
|
40
|
-
/** Additional props to pass through to slot components */
|
|
41
|
-
slotProps?: Record<string, any>;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function LayoutGrid({ children, slotProps = {} }: LayoutGridProps) {
|
|
45
|
-
const slots = useLayoutStore((s) => s.slots);
|
|
46
|
-
const tabs = useLayoutStore((s) => s.tabs);
|
|
47
|
-
const showCanvas = useLayoutStore((s) => s.showCanvas);
|
|
48
|
-
const showChat = useLayoutStore((s) => s.showChat);
|
|
49
|
-
|
|
50
|
-
const activeR1 = showChat ? slots.R1 : null;
|
|
51
|
-
const hasLeft = !!(activeR1 || slots.R2);
|
|
52
|
-
const hasRight = !!(slots.R3 || slots.R4);
|
|
53
|
-
const hasBottom = !!slots.R6;
|
|
54
|
-
const hasTabs = tabs.length > 0;
|
|
55
|
-
|
|
56
|
-
// ── Dynamic key forces PanelGroup re-mount when composition changes ──
|
|
57
|
-
// This resets react-resizable-panels internal flex ratios to fresh defaults
|
|
58
|
-
const layoutKey = `${hasLeft ? 'L' : ''}${showCanvas ? 'C' : ''}${hasRight ? 'R' : ''}`;
|
|
59
|
-
|
|
60
|
-
// ── Compute panel sizes based on current layout configuration ──
|
|
61
|
-
const leftDefault = showCanvas ? (hasRight ? 20 : 25) : (hasRight ? 50 : 100);
|
|
62
|
-
const leftMax = showCanvas ? 35 : (hasRight ? 70 : 100);
|
|
63
|
-
const rightDefault = showCanvas ? (hasLeft ? 25 : 40) : (hasLeft ? 50 : 100);
|
|
64
|
-
const rightMax = showCanvas ? 60 : (hasLeft ? 70 : 100);
|
|
65
|
-
const centerDefault = hasLeft && hasRight ? 40 : (hasLeft ? 60 : (hasRight ? 50 : 100));
|
|
66
|
-
|
|
67
|
-
return (
|
|
68
|
-
<div className="flex-1 flex flex-col h-full overflow-hidden min-w-0 min-h-0">
|
|
69
|
-
{/* ── R5: Top Edge (extension slot) ── */}
|
|
70
|
-
{slots.R5 && (
|
|
71
|
-
<div className="flex-none">
|
|
72
|
-
<SlotRenderer componentId={slots.R5} slotProps={slotProps} />
|
|
73
|
-
</div>
|
|
74
|
-
)}
|
|
75
|
-
|
|
76
|
-
{/* ── T2: TabBar (only when tabs exist) ── */}
|
|
77
|
-
{hasTabs && <TabBar />}
|
|
78
|
-
|
|
79
|
-
{/* ── Main horizontal layout: R1/R2 | Center | R3/R4 ── */}
|
|
80
|
-
<PanelGroup
|
|
81
|
-
key={layoutKey}
|
|
82
|
-
orientation="horizontal"
|
|
83
|
-
className="flex-1 min-w-0 min-h-0"
|
|
84
|
-
>
|
|
85
|
-
{/* ── LEFT COLUMN: R1 (top) + R2 (bottom) ── */}
|
|
86
|
-
{hasLeft && (
|
|
87
|
-
<Panel
|
|
88
|
-
id="left-column"
|
|
89
|
-
defaultSize={leftDefault}
|
|
90
|
-
minSize={15}
|
|
91
|
-
className="h-full overflow-hidden flex flex-col min-w-0 min-h-0"
|
|
92
|
-
>
|
|
93
|
-
{activeR1 && slots.R2 ? (
|
|
94
|
-
<PanelGroup orientation="vertical" className="h-full min-w-0 min-h-0">
|
|
95
|
-
<Panel id="R1" defaultSize={65} minSize={20} className="flex flex-col min-w-0 min-h-0">
|
|
96
|
-
<div className={LEFT_PANEL_CLASSES}>
|
|
97
|
-
<SlotRenderer componentId={activeR1} slotProps={slotProps} />
|
|
98
|
-
</div>
|
|
99
|
-
</Panel>
|
|
100
|
-
<PanelResizeHandle className={H_HANDLE_CLASSES}>{H_HANDLE_INNER}</PanelResizeHandle>
|
|
101
|
-
<Panel id="R2" defaultSize={35} minSize={15} className="flex flex-col min-w-0 min-h-0">
|
|
102
|
-
<div className={LEFT_PANEL_CLASSES}>
|
|
103
|
-
<SlotRenderer componentId={slots.R2} slotProps={slotProps} />
|
|
104
|
-
</div>
|
|
105
|
-
</Panel>
|
|
106
|
-
</PanelGroup>
|
|
107
|
-
) : (
|
|
108
|
-
<div className={LEFT_PANEL_CLASSES}>
|
|
109
|
-
<SlotRenderer componentId={activeR1 || slots.R2} slotProps={slotProps} />
|
|
110
|
-
</div>
|
|
111
|
-
)}
|
|
112
|
-
</Panel>
|
|
113
|
-
)}
|
|
114
|
-
|
|
115
|
-
{/* ── SEPARATOR: Left ↔ Center ── */}
|
|
116
|
-
{hasLeft && showCanvas && (
|
|
117
|
-
<PanelResizeHandle id="h-left" className={V_HANDLE_CLASSES}>{V_HANDLE_INNER}</PanelResizeHandle>
|
|
118
|
-
)}
|
|
119
|
-
|
|
120
|
-
{/* ── CENTER: Main Content (only when canvas visible) ── */}
|
|
121
|
-
{showCanvas && (
|
|
122
|
-
<Panel
|
|
123
|
-
id="center"
|
|
124
|
-
defaultSize={centerDefault}
|
|
125
|
-
minSize={20}
|
|
126
|
-
className="h-full overflow-hidden flex flex-col min-w-0 min-h-0"
|
|
127
|
-
>
|
|
128
|
-
<div className="h-full flex flex-col overflow-hidden bg-surface-secondary min-w-0 min-h-0">
|
|
129
|
-
{children}
|
|
130
|
-
</div>
|
|
131
|
-
</Panel>
|
|
132
|
-
)}
|
|
133
|
-
|
|
134
|
-
{/* ── SEPARATOR: Center ↔ Right (or Left ↔ Right when canvas hidden) ── */}
|
|
135
|
-
{hasRight && (showCanvas || hasLeft) && (
|
|
136
|
-
<PanelResizeHandle id="h-right" className={V_HANDLE_CLASSES}>{V_HANDLE_INNER}</PanelResizeHandle>
|
|
137
|
-
)}
|
|
138
|
-
|
|
139
|
-
{/* ── RIGHT COLUMN: R3 (top) + R4 (bottom) ── */}
|
|
140
|
-
{hasRight && (
|
|
141
|
-
<Panel
|
|
142
|
-
id="right-column"
|
|
143
|
-
defaultSize={rightDefault}
|
|
144
|
-
minSize={15}
|
|
145
|
-
className="h-full overflow-hidden flex flex-col min-w-0 min-h-0"
|
|
146
|
-
>
|
|
147
|
-
{slots.R3 && slots.R4 ? (
|
|
148
|
-
<PanelGroup orientation="vertical" className="h-full min-w-0 min-h-0">
|
|
149
|
-
<Panel id="R3" defaultSize={65} minSize={20} className="flex flex-col min-w-0 min-h-0">
|
|
150
|
-
<div className={RIGHT_PANEL_CLASSES}>
|
|
151
|
-
<SlotRenderer componentId={slots.R3} slotProps={slotProps} />
|
|
152
|
-
</div>
|
|
153
|
-
</Panel>
|
|
154
|
-
<PanelResizeHandle className={H_HANDLE_CLASSES}>{H_HANDLE_INNER}</PanelResizeHandle>
|
|
155
|
-
<Panel id="R4" defaultSize={35} minSize={15} className="flex flex-col min-w-0 min-h-0">
|
|
156
|
-
<div className={RIGHT_PANEL_CLASSES}>
|
|
157
|
-
<SlotRenderer componentId={slots.R4} slotProps={slotProps} />
|
|
158
|
-
</div>
|
|
159
|
-
</Panel>
|
|
160
|
-
</PanelGroup>
|
|
161
|
-
) : (
|
|
162
|
-
<div className={RIGHT_PANEL_CLASSES}>
|
|
163
|
-
<SlotRenderer componentId={slots.R3 || slots.R4} slotProps={slotProps} />
|
|
164
|
-
</div>
|
|
165
|
-
)}
|
|
166
|
-
</Panel>
|
|
167
|
-
)}
|
|
168
|
-
</PanelGroup>
|
|
169
|
-
|
|
170
|
-
{/* ── R6: Bottom Edge (StatusBar / extension slot) ── */}
|
|
171
|
-
{hasBottom && (
|
|
172
|
-
<div className="flex-none border-t border-border-subtle">
|
|
173
|
-
<SlotRenderer componentId={slots.R6} slotProps={slotProps} />
|
|
174
|
-
</div>
|
|
175
|
-
)}
|
|
176
|
-
</div>
|
|
177
|
-
);
|
|
178
|
-
}
|