chore: Project cleanup and Canvas UX improvements (Phase 7-9)
## Cleanup (v0.5.0) - Delete 102+ orphaned MCP session temp files - Remove build artifacts (htmlcov, dist, __pycache__) - Archive superseded plan docs (RALPH_LOOP V2/V3, CANVAS V3, etc.) - Move debug/analysis scripts from tests/ to tools/analysis/ - Archive redundant NX journals to archive/nx_journals/ - Archive monolithic PROTOCOL.md to docs/archive/ - Update .gitignore with missing patterns - Clean old study files (optimization_log_old.txt, run_optimization_old.py) ## Canvas UX (Phases 7-9) - Phase 7: Resizable panels with localStorage persistence - Left sidebar: 200-400px, Right panel: 280-600px - New useResizablePanel hook and ResizeHandle component - Phase 8: Enable all palette items - All 8 node types now draggable - Singleton logic for model/solver/algorithm/surrogate - Phase 9: Solver configuration - Add SolverEngine type (nxnastran, mscnastran, python, etc.) - Add NastranSolutionType (SOL101-SOL200) - Engine/solution dropdowns in config panel - Python script path support ## Documentation - Update CHANGELOG.md with recent versions - Update docs/00_INDEX.md - Create examples/README.md - Add docs/plans/CANVAS_UX_IMPROVEMENTS.md
This commit is contained in:
@@ -11,8 +11,10 @@ import { NodeConfigPanel } from '../components/canvas/panels/NodeConfigPanel';
|
||||
import { NodeConfigPanelV2 } from '../components/canvas/panels/NodeConfigPanelV2';
|
||||
import { ChatPanel } from '../components/canvas/panels/ChatPanel';
|
||||
import { PanelContainer } from '../components/canvas/panels/PanelContainer';
|
||||
import { ResizeHandle } from '../components/canvas/ResizeHandle';
|
||||
import { useCanvasStore } from '../hooks/useCanvasStore';
|
||||
import { useSpecStore, useSpec, useSpecLoading, useSpecIsDirty, useSelectedNodeId } from '../hooks/useSpecStore';
|
||||
import { useResizablePanel } from '../hooks/useResizablePanel';
|
||||
// usePanelStore is now used by child components - PanelContainer handles panels
|
||||
import { useSpecUndoRedo, useUndoRedoKeyboard } from '../hooks/useSpecUndoRedo';
|
||||
import { useStudy } from '../context/StudyContext';
|
||||
@@ -31,6 +33,23 @@ export function CanvasView() {
|
||||
const [paletteCollapsed, setPaletteCollapsed] = useState(false);
|
||||
const [leftSidebarTab, setLeftSidebarTab] = useState<'components' | 'files'>('components');
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Resizable panels
|
||||
const leftPanel = useResizablePanel({
|
||||
storageKey: 'left-sidebar',
|
||||
defaultWidth: 240,
|
||||
minWidth: 200,
|
||||
maxWidth: 400,
|
||||
side: 'left',
|
||||
});
|
||||
|
||||
const rightPanel = useResizablePanel({
|
||||
storageKey: 'right-panel',
|
||||
defaultWidth: 384,
|
||||
minWidth: 280,
|
||||
maxWidth: 600,
|
||||
side: 'right',
|
||||
});
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
// Spec mode is the default (AtomizerSpec v2.0)
|
||||
@@ -423,7 +442,10 @@ export function CanvasView() {
|
||||
<main className="flex-1 overflow-hidden flex">
|
||||
{/* Left Sidebar with tabs (spec mode only - AtomizerCanvas has its own) */}
|
||||
{useSpecMode && (
|
||||
<div className={`${paletteCollapsed ? 'w-14' : 'w-60'} bg-dark-850 border-r border-dark-700 flex flex-col transition-all duration-200`}>
|
||||
<div
|
||||
className="relative bg-dark-850 border-r border-dark-700 flex flex-col"
|
||||
style={{ width: paletteCollapsed ? 56 : leftPanel.width }}
|
||||
>
|
||||
{/* Tab buttons (only show when expanded) */}
|
||||
{!paletteCollapsed && (
|
||||
<div className="flex border-b border-dark-700">
|
||||
@@ -469,6 +491,16 @@ export function CanvasView() {
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Resize handle (only when not collapsed) */}
|
||||
{!paletteCollapsed && (
|
||||
<ResizeHandle
|
||||
onMouseDown={leftPanel.startDrag}
|
||||
onDoubleClick={leftPanel.resetWidth}
|
||||
isDragging={leftPanel.isDragging}
|
||||
position="right"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -494,14 +526,35 @@ export function CanvasView() {
|
||||
{/* Shows INSTEAD of chat when a node is selected */}
|
||||
{selectedNodeId ? (
|
||||
useSpecMode ? (
|
||||
<NodeConfigPanelV2 onClose={() => useSpecStore.getState().clearSelection()} />
|
||||
<div
|
||||
className="relative border-l border-dark-700 bg-dark-850 flex flex-col"
|
||||
style={{ width: rightPanel.width }}
|
||||
>
|
||||
<ResizeHandle
|
||||
onMouseDown={rightPanel.startDrag}
|
||||
onDoubleClick={rightPanel.resetWidth}
|
||||
isDragging={rightPanel.isDragging}
|
||||
position="left"
|
||||
/>
|
||||
<NodeConfigPanelV2 onClose={() => useSpecStore.getState().clearSelection()} />
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-80 border-l border-dark-700 bg-dark-850 overflow-y-auto">
|
||||
<NodeConfigPanel nodeId={selectedNodeId} />
|
||||
</div>
|
||||
)
|
||||
) : showChat ? (
|
||||
<div className="w-96 border-l border-dark-700 bg-dark-850 flex flex-col">
|
||||
<div
|
||||
className="relative border-l border-dark-700 bg-dark-850 flex flex-col"
|
||||
style={{ width: rightPanel.width }}
|
||||
>
|
||||
{/* Resize handle */}
|
||||
<ResizeHandle
|
||||
onMouseDown={rightPanel.startDrag}
|
||||
onDoubleClick={rightPanel.resetWidth}
|
||||
isDragging={rightPanel.isDragging}
|
||||
position="left"
|
||||
/>
|
||||
{/* Chat Header */}
|
||||
<div className="flex items-center justify-between px-4 py-3 border-b border-dark-700">
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
Reference in New Issue
Block a user