@@ -47,6 +47,7 @@ import {
4747 Link ,
4848 ColumnSelectionValidator ,
4949 getDashboardConnection ,
50+ NotebookPanel ,
5051} from '@deephaven/dashboard-core-plugins' ;
5152import {
5253 vsGear ,
@@ -77,7 +78,7 @@ import {
7778 ServerConfigValues ,
7879 DeephavenPluginModuleMap ,
7980} from '@deephaven/redux' ;
80- import { PromiseUtils } from '@deephaven/utils' ;
81+ import { bindAllMethods , PromiseUtils } from '@deephaven/utils' ;
8182import GoldenLayout from '@deephaven/golden-layout' ;
8283import type { ItemConfigType } from '@deephaven/golden-layout' ;
8384import {
@@ -139,7 +140,9 @@ interface AppMainContainerState {
139140 isAuthFailed : boolean ;
140141 isDisconnected : boolean ;
141142 isPanelsMenuShown : boolean ;
143+ isResetLayoutPromptShown : boolean ;
142144 isSettingsMenuShown : boolean ;
145+ unsavedNotebookCount : number ;
143146 widgets : VariableDefinition [ ] ;
144147}
145148
@@ -176,29 +179,8 @@ export class AppMainContainer extends Component<
176179
177180 constructor ( props : AppMainContainerProps & RouteComponentProps ) {
178181 super ( props ) ;
179- this . handleSettingsMenuHide = this . handleSettingsMenuHide . bind ( this ) ;
180- this . handleSettingsMenuShow = this . handleSettingsMenuShow . bind ( this ) ;
181- this . handleError = this . handleError . bind ( this ) ;
182- this . handleControlSelect = this . handleControlSelect . bind ( this ) ;
183- this . handleToolSelect = this . handleToolSelect . bind ( this ) ;
184- this . handleClearFilter = this . handleClearFilter . bind ( this ) ;
185- this . handleDataChange = this . handleDataChange . bind ( this ) ;
186- this . handleAutoFillClick = this . handleAutoFillClick . bind ( this ) ;
187- this . handleGoldenLayoutChange = this . handleGoldenLayoutChange . bind ( this ) ;
188- this . handleLayoutConfigChange = this . handleLayoutConfigChange . bind ( this ) ;
189- this . handleExportLayoutClick = this . handleExportLayoutClick . bind ( this ) ;
190- this . handleImportLayoutClick = this . handleImportLayoutClick . bind ( this ) ;
191- this . handleImportLayoutFiles = this . handleImportLayoutFiles . bind ( this ) ;
192- this . handleResetLayoutClick = this . handleResetLayoutClick . bind ( this ) ;
193- this . handleWidgetMenuClick = this . handleWidgetMenuClick . bind ( this ) ;
194- this . handleWidgetsMenuClose = this . handleWidgetsMenuClose . bind ( this ) ;
195- this . handleWidgetSelect = this . handleWidgetSelect . bind ( this ) ;
196- this . handlePaste = this . handlePaste . bind ( this ) ;
197- this . hydrateDefault = this . hydrateDefault . bind ( this ) ;
198- this . openNotebookFromURL = this . openNotebookFromURL . bind ( this ) ;
199- this . handleDisconnect = this . handleDisconnect . bind ( this ) ;
200- this . handleReconnect = this . handleReconnect . bind ( this ) ;
201- this . handleReconnectAuthFailed = this . handleReconnectAuthFailed . bind ( this ) ;
182+
183+ bindAllMethods ( this ) ;
202184
203185 this . importElement = React . createRef ( ) ;
204186
@@ -231,7 +213,9 @@ export class AppMainContainer extends Component<
231213 isAuthFailed : false ,
232214 isDisconnected : false ,
233215 isPanelsMenuShown : false ,
216+ isResetLayoutPromptShown : false ,
234217 isSettingsMenuShown : false ,
218+ unsavedNotebookCount : 0 ,
235219 widgets : [ ] ,
236220 } ;
237221 }
@@ -347,6 +331,20 @@ export class AppMainContainer extends Component<
347331 this . goldenLayout ?. eventHub . emit ( event , ...args ) ;
348332 }
349333
334+ handleCancelResetLayoutPrompt ( ) : void {
335+ this . setState ( {
336+ isResetLayoutPromptShown : false ,
337+ } ) ;
338+ }
339+
340+ handleConfirmResetLayoutPrompt ( ) : void {
341+ this . setState ( {
342+ isResetLayoutPromptShown : false ,
343+ } ) ;
344+
345+ this . resetLayout ( ) ;
346+ }
347+
350348 // eslint-disable-next-line class-methods-use-this
351349 handleError ( error : unknown ) : void {
352350 if ( PromiseUtils . isCanceled ( error ) ) {
@@ -517,9 +515,11 @@ export class AppMainContainer extends Component<
517515 handleResetLayoutClick ( ) : void {
518516 log . info ( 'handleResetLayoutClick' ) ;
519517
520- this . setState ( { isPanelsMenuShown : false } ) ;
521-
522- this . resetLayout ( ) ;
518+ this . setState ( {
519+ isPanelsMenuShown : false ,
520+ isResetLayoutPromptShown : true ,
521+ unsavedNotebookCount : NotebookPanel . unsavedNotebookCount ( ) ,
522+ } ) ;
523523 }
524524
525525 handleImportLayoutFiles ( event : ChangeEvent < HTMLInputElement > ) : void {
@@ -718,7 +718,9 @@ export class AppMainContainer extends Component<
718718 isAuthFailed,
719719 isDisconnected,
720720 isPanelsMenuShown,
721+ isResetLayoutPromptShown,
721722 isSettingsMenuShown,
723+ unsavedNotebookCount,
722724 widgets,
723725 } = this . state ;
724726 const dashboardPlugins = this . getDashboardPlugins ( plugins ) ;
@@ -884,6 +886,23 @@ export class AppMainContainer extends Component<
884886 subtitle = "Please check your network connection."
885887 />
886888 </ DebouncedModal >
889+ < BasicModal
890+ confirmButtonText = "Reset"
891+ onConfirm = { this . handleConfirmResetLayoutPrompt }
892+ onCancel = { this . handleCancelResetLayoutPrompt }
893+ isConfirmDanger
894+ isOpen = { isResetLayoutPromptShown }
895+ headerText = {
896+ unsavedNotebookCount === 0
897+ ? 'Reset Layout'
898+ : 'Reset layout and discard unsaved changes'
899+ }
900+ bodyText = {
901+ unsavedNotebookCount === 0
902+ ? 'Do you want to reset your layout? Your existing layout will be lost.'
903+ : 'Do you want to reset your layout? Any unsaved notebooks will be lost.'
904+ }
905+ />
887906 < BasicModal
888907 confirmButtonText = "Refresh"
889908 onConfirm = { AppMainContainer . handleRefresh }
0 commit comments