@@ -15,13 +15,20 @@ import { wait } from "../tools/tools";
1515import { openSingleFileDialog } from "../tools/dialog" ;
1616import { ProjectType , projectsKey } from "../tools/project" ;
1717import { checkNodeJSAvailable , nodeJSAvailable } from "../tools/process" ;
18- import { tryAddProjectToLocalStorage , tryGetProjectsFromLocalStorage } from "../tools/local-storage" ;
18+ import {
19+ tryAddProjectToLocalStorage ,
20+ tryGetCloseDashboardOnProjectOpenFromLocalStorage ,
21+ tryGetProjectsFromLocalStorage ,
22+ trySetCloseDashboardOnProjectOpenInLocalStorage ,
23+ } from "../tools/local-storage" ;
1924
2025import { DashboardProjectItem } from "./item" ;
2126import { DashboardCreateProjectDialog } from "./create" ;
2227import { DashboardWindowControls } from "./window-controls" ;
2328
2429import packageJson from "../../package.json" ;
30+ import { Switch } from "../ui/shadcn/ui/switch" ;
31+ import { Tooltip , TooltipContent , TooltipProvider , TooltipTrigger } from "../ui/shadcn/ui/tooltip" ;
2532
2633export function createDashboard ( ) : void {
2734 const theme = localStorage . getItem ( "editor-theme" ) ?? "dark" ;
@@ -48,6 +55,7 @@ export interface IDashboardState {
4855 openedProjects : string [ ] ;
4956
5057 createProject : boolean ;
58+ keepDashboard : boolean ;
5159}
5260
5361export class Dashboard extends Component < IDashboardProps , IDashboardState > {
@@ -59,48 +67,60 @@ export class Dashboard extends Component<IDashboardProps, IDashboardState> {
5967 projects : tryGetProjectsFromLocalStorage ( ) ,
6068
6169 createProject : false ,
70+ keepDashboard : ! tryGetCloseDashboardOnProjectOpenFromLocalStorage ( ) ,
6271 } ;
6372
6473 webFrame . setZoomFactor ( 0.8 ) ;
6574 }
6675
6776 public render ( ) : ReactNode {
68- return (
69- < >
70- < div className = "flex flex-col gap-4 w-screen h-screen p-5 select-none overflow-x-hidden pt-10" >
71- < DashboardWindowControls />
77+ const handleKeepDashboardChanged = ( checked : boolean ) : void => {
78+ this . setState ( {
79+ ...this . state ,
80+ keepDashboard : checked ,
81+ } ) ;
7282
73- < Fade delay = { 0 } >
74- < div className = "flex justify-between items-end w-full mt-1" >
75- < div className = "text-5xl font-semibold" > Dashboard</ div >
83+ trySetCloseDashboardOnProjectOpenInLocalStorage ( ! checked ) ;
84+ } ;
7685
77- < div className = "flex flex-col items-end gap-2" >
78- < img alt = "" src = "assets/babylonjs_icon.png" className = "w-[48px] object-contain" />
79- < div className = "text-xs" > Babylon.js Editor v{ packageJson . version } </ div >
86+ return (
87+ < >
88+ < div className = "flex flex-col gap-4 w-screen h-screen p-5 select-none pt-10" >
89+ < div className = "flex flex-col gap-4 flex-[0_0_auto]" >
90+ < DashboardWindowControls />
91+
92+ < Fade delay = { 0 } >
93+ < div className = "flex justify-between items-end w-full mt-1" >
94+ < div className = "text-5xl font-semibold" > Dashboard</ div >
95+
96+ < div className = "flex flex-col items-end gap-2" >
97+ < img alt = "" src = "assets/babylonjs_icon.png" className = "w-[48px] object-contain" />
98+ < div className = "text-xs" > Babylon.js Editor v{ packageJson . version } </ div >
99+ </ div >
80100 </ div >
81- </ div >
82- </ Fade >
83-
84- < Fade delay = { 250 } >
85- < Separator / >
86- </ Fade >
87-
88- < Fade delay = { 500 } >
89- < div className = "flex justify-between items-center" >
90- < div className = "text-3xl font-semibold" > Projects </ div >
91-
92- < div className = "flex gap-2" >
93- < Button variant = "secondary" className = "font-semibold" onClick = { ( ) => this . _handleImportProject ( ) } >
94- Import project
95- </ Button >
96- < Button className = "font-semibold" onClick = { ( ) => this . setState ( { createProject : true } ) } >
97- Create project
98- </ Button >
101+ </ Fade >
102+
103+ < Fade delay = { 250 } >
104+ < Separator / >
105+ </ Fade >
106+
107+ < Fade delay = { 500 } >
108+ < div className = "flex justify-between items-center" >
109+ < div className = "text-3xl font-semibold" > Projects </ div >
110+
111+ < div className = "flex gap-2" >
112+ < Button variant = "secondary" className = "font-semibold" onClick = { ( ) => this . _handleImportProject ( ) } >
113+ Import project
114+ </ Button >
115+ < Button className = "font-semibold" onClick = { ( ) => this . setState ( { createProject : true } ) } >
116+ Create project
117+ </ Button >
118+ </ div >
99119 </ div >
100- </ div >
101- </ Fade >
120+ </ Fade >
121+ </ div >
102122
103- < Fade delay = { 750 } >
123+ < Fade delay = { 750 } className = "flex-auto overflow-y-auto p-1" >
104124 { ! this . state . projects . length && < div className = "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2" > No project found.</ div > }
105125
106126 { this . state . projects . length && (
@@ -116,6 +136,32 @@ export class Dashboard extends Component<IDashboardProps, IDashboardState> {
116136 </ div >
117137 ) }
118138 </ Fade >
139+
140+ < Fade delay = { 1000 } className = "flex-[0_0_auto]" >
141+ < div >
142+ < Separator />
143+ < div className = "flex justify-end pt-3 pb-1" >
144+ < TooltipProvider >
145+ < Tooltip >
146+ < TooltipTrigger className = "flex gap-2 cursor-auto" >
147+ < Switch checked = { this . state . keepDashboard } onCheckedChange = { handleKeepDashboardChanged } />
148+ < span > Keep dashboard open</ span >
149+ </ TooltipTrigger >
150+ < TooltipContent
151+ align = "end"
152+ side = "top"
153+ collisionPadding = { 8 }
154+ className = "bg-secondary text-muted-foreground text-sm rounded-lg mb-2 p-2 ring-2 ring-muted-foreground overflow-hidden"
155+ >
156+ If enabled, the dashboard will stay open when a project starts.
157+ < br />
158+ If disabled, the dashboard will close when a project starts and reopen after the project is closed.
159+ </ TooltipContent >
160+ </ Tooltip >
161+ </ TooltipProvider >
162+ </ div >
163+ </ div >
164+ </ Fade >
119165 </ div >
120166
121167 < DashboardCreateProjectDialog
0 commit comments