@@ -42,6 +42,7 @@ import { VersionHistoryPanel } from "./version-history-panel"
4242import { ExportImportDialog } from "./export-import-dialog"
4343import { BuilderCommandPalette } from "./builder-command-palette"
4444import { NodeContextMenu , PaneContextMenu } from "./builder-context-menu"
45+ import { GlassContainer } from "@/components/ui/glass-container"
4546import { getHistoryManager } from "@/lib/history-manager"
4647import { useToast } from "@/hooks/use-toast"
4748import {
@@ -747,127 +748,126 @@ function BuilderCanvasInner() {
747748 />
748749
749750 < div className = "relative flex flex-1 flex-col" >
750- < div
751- className = "border-border/80 bg-card/90 absolute top-4 right-4 left-4 z-50 flex items-center gap-3 rounded-2xl border px-3 py-2 shadow-sm"
752- data-testid = "builder-toolbar"
753- >
754- < div className = "flex min-w-0 items-center gap-3" >
755- < h1 className = "truncate text-sm font-semibold tracking-tight" >
756- { workflow ?. name || "Untitled Workflow" }
757- </ h1 >
758- < span className = "border-border/80 bg-muted/40 text-muted-foreground rounded-full border px-2 py-0.5 text-[10px] font-medium" >
759- v{ workflow ?. version || 1 }
760- </ span >
761- </ div >
762-
763- < div className = "border-border/80 bg-background/70 ml-auto flex max-w-full items-center gap-1.5 overflow-x-auto rounded-full border p-1" >
764- < ExportImportDialog
765- workflowId = { workflowId }
766- onImportSuccess = { ( newWorkflow ) => {
767- mutate ( "/api/workflows" )
768- if ( newWorkflow ?. id ) {
769- setWorkflowId ( newWorkflow . id )
770- mutate ( `/api/workflows/${ newWorkflow . id } ` )
771- } else {
772- mutate ( `/api/workflows/${ workflowId } ` )
773- }
774- } }
775- />
776- < div className = "bg-border/80 mx-1 h-4 w-px" />
777- < Button
778- variant = "ghost"
779- size = "icon"
780- className = "hover:bg-accent h-8 w-8 rounded-full"
781- onClick = { handleUndo }
782- disabled = { ! historyStatus ?. canUndo }
783- aria-label = "Undo"
784- title = "Undo"
785- >
786- < Undo className = "h-4 w-4" />
787- </ Button >
788- < Button
789- variant = "ghost"
790- size = "icon"
791- className = "hover:bg-accent h-8 w-8 rounded-full"
792- onClick = { handleRedo }
793- disabled = { ! historyStatus ?. canRedo }
794- aria-label = "Redo"
795- title = "Redo"
796- >
797- < Redo className = "h-4 w-4" />
798- </ Button >
799- < div className = "bg-border/80 mx-1 h-4 w-px" />
800- < Button
801- variant = "ghost"
802- size = "icon"
803- className = "hover:bg-accent h-8 w-8 rounded-full"
804- onClick = { handleAutoLayout }
805- title = "Auto Layout"
806- aria-label = "Auto Layout"
807- >
808- < ArrowDownUp className = "h-4 w-4" />
809- </ Button >
810- < Button
811- variant = "ghost"
812- size = "icon"
813- className = "hover:bg-accent h-8 w-8 rounded-full"
814- onClick = { handleZoomOut }
815- aria-label = "Zoom out"
816- title = "Zoom out"
817- >
818- < ZoomOut className = "h-4 w-4" />
819- </ Button >
820- < span
821- className = "text-muted-foreground w-10 text-center text-xs font-medium select-none"
822- aria-live = "polite"
823- >
824- { Math . round ( ( viewport ?. zoom ?? 1 ) * 100 ) } %
825- </ span >
826- < Button
827- variant = "ghost"
828- size = "icon"
829- className = "hover:bg-accent h-8 w-8 rounded-full"
830- onClick = { handleZoomIn }
831- aria-label = "Zoom in"
832- title = "Zoom in"
833- >
834- < ZoomIn className = "h-4 w-4" />
835- </ Button >
836- < Button
837- variant = "ghost"
838- size = "icon"
839- className = "hover:bg-accent h-8 w-8 rounded-full"
840- onClick = { handleResetView }
841- aria-label = "Fit view"
842- title = "Fit view"
843- >
844- < Maximize2 className = "h-4 w-4" />
845- </ Button >
846- < div className = "bg-border/80 mx-1 h-4 w-px" />
847- < Button
848- variant = "ghost"
849- size = "icon"
850- className = "hover:bg-accent h-8 w-8 rounded-full"
851- onClick = { ( ) => setShowVersionHistory ( ! showVersionHistory ) }
852- aria-label = "Version history"
853- title = "Version history"
854- >
855- < History className = "h-4 w-4" />
856- </ Button >
857- < Button
858- variant = "outline"
859- size = "sm"
860- className = "ml-1 h-8 gap-2 rounded-full border-indigo-500/20 bg-indigo-500/10 text-indigo-300 hover:bg-indigo-500/20"
861- onClick = { ( ) => setShowExecutionMonitor ( ! showExecutionMonitor ) }
862- >
863- < Play className = "h-3.5 w-3.5" />
864- { showExecutionMonitor ? "Close" : "Run" }
865- </ Button >
866- < Button size = "sm" className = "h-8 gap-2 rounded-full" onClick = { handleSaveVersion } >
867- < Save className = "h-3.5 w-3.5" />
868- Save
869- </ Button >
870- </ div >
751+ < div className = "absolute top-4 right-4 left-4 z-50" data-testid = "builder-toolbar" >
752+ < GlassContainer className = "flex items-center gap-3 px-3 py-2 shadow-sm" >
753+ < div className = "flex min-w-0 items-center gap-3" >
754+ < h1 className = "truncate text-sm font-semibold tracking-tight" >
755+ { workflow ?. name || "Untitled Workflow" }
756+ </ h1 >
757+ < span className = "border-border/80 bg-muted/40 text-muted-foreground rounded-full border px-2 py-0.5 text-[10px] font-medium" >
758+ v{ workflow ?. version || 1 }
759+ </ span >
760+ </ div >
761+
762+ < div className = "border-border/80 bg-background/70 ml-auto flex max-w-full items-center gap-1.5 overflow-x-auto rounded-full border p-1" >
763+ < ExportImportDialog
764+ workflowId = { workflowId }
765+ onImportSuccess = { ( newWorkflow ) => {
766+ mutate ( "/api/workflows" )
767+ if ( newWorkflow ?. id ) {
768+ setWorkflowId ( newWorkflow . id )
769+ mutate ( `/api/workflows/${ newWorkflow . id } ` )
770+ } else {
771+ mutate ( `/api/workflows/${ workflowId } ` )
772+ }
773+ } }
774+ />
775+ < div className = "bg-border/80 mx-1 h-4 w-px" />
776+ < Button
777+ variant = "ghost"
778+ size = "icon"
779+ className = "hover:bg-accent h-8 w-8 rounded-full"
780+ onClick = { handleUndo }
781+ disabled = { ! historyStatus ?. canUndo }
782+ aria-label = "Undo"
783+ title = "Undo"
784+ >
785+ < Undo className = "h-4 w-4" />
786+ </ Button >
787+ < Button
788+ variant = "ghost"
789+ size = "icon"
790+ className = "hover:bg-accent h-8 w-8 rounded-full"
791+ onClick = { handleRedo }
792+ disabled = { ! historyStatus ?. canRedo }
793+ aria-label = "Redo"
794+ title = "Redo"
795+ >
796+ < Redo className = "h-4 w-4" />
797+ </ Button >
798+ < div className = "bg-border/80 mx-1 h-4 w-px" />
799+ < Button
800+ variant = "ghost"
801+ size = "icon"
802+ className = "hover:bg-accent h-8 w-8 rounded-full"
803+ onClick = { handleAutoLayout }
804+ title = "Auto Layout"
805+ aria-label = "Auto Layout"
806+ >
807+ < ArrowDownUp className = "h-4 w-4" />
808+ </ Button >
809+ < Button
810+ variant = "ghost"
811+ size = "icon"
812+ className = "hover:bg-accent h-8 w-8 rounded-full"
813+ onClick = { handleZoomOut }
814+ aria-label = "Zoom out"
815+ title = "Zoom out"
816+ >
817+ < ZoomOut className = "h-4 w-4" />
818+ </ Button >
819+ < span
820+ className = "text-muted-foreground w-10 text-center text-xs font-medium select-none"
821+ aria-live = "polite"
822+ >
823+ { Math . round ( ( viewport ?. zoom ?? 1 ) * 100 ) } %
824+ </ span >
825+ < Button
826+ variant = "ghost"
827+ size = "icon"
828+ className = "hover:bg-accent h-8 w-8 rounded-full"
829+ onClick = { handleZoomIn }
830+ aria-label = "Zoom in"
831+ title = "Zoom in"
832+ >
833+ < ZoomIn className = "h-4 w-4" />
834+ </ Button >
835+ < Button
836+ variant = "ghost"
837+ size = "icon"
838+ className = "hover:bg-accent h-8 w-8 rounded-full"
839+ onClick = { handleResetView }
840+ aria-label = "Fit view"
841+ title = "Fit view"
842+ >
843+ < Maximize2 className = "h-4 w-4" />
844+ </ Button >
845+ < div className = "bg-border/80 mx-1 h-4 w-px" />
846+ < Button
847+ variant = "ghost"
848+ size = "icon"
849+ className = "hover:bg-accent h-8 w-8 rounded-full"
850+ onClick = { ( ) => setShowVersionHistory ( ! showVersionHistory ) }
851+ aria-label = "Version history"
852+ title = "Version history"
853+ >
854+ < History className = "h-4 w-4" />
855+ </ Button >
856+ < Button
857+ variant = "outline"
858+ size = "sm"
859+ className = "ml-1 h-8 gap-2 rounded-full border-indigo-500/20 bg-indigo-500/10 text-indigo-300 hover:bg-indigo-500/20"
860+ onClick = { ( ) => setShowExecutionMonitor ( ! showExecutionMonitor ) }
861+ >
862+ < Play className = "h-3.5 w-3.5" />
863+ { showExecutionMonitor ? "Close" : "Run" }
864+ </ Button >
865+ < Button size = "sm" className = "h-8 gap-2 rounded-full" onClick = { handleSaveVersion } >
866+ < Save className = "h-3.5 w-3.5" />
867+ Save
868+ </ Button >
869+ </ div >
870+ </ GlassContainer >
871871 </ div >
872872
873873 < div
0 commit comments