@@ -73,8 +73,26 @@ export class LayoutService {
7373 map ( ( e : any ) => ( e . matches ? themeDark : themeLight ) )
7474 )
7575 // Modal section
76- private modalIDS : ( number | string ) [ ] = [ ]
77- private readonly dialogConfig : ModalOptions = { animated : true , keyboard : true , backdrop : true , ignoreBackdropClick : true }
76+ private modalIDS = new Set < number | string > ( )
77+ private readonly dialogConfig : ModalOptions = {
78+ animated : true ,
79+ keyboard : false ,
80+ backdrop : true ,
81+ focus : true ,
82+ ignoreBackdropClick : true ,
83+ closeInterceptor : ( ) => {
84+ if ( this . bsModal [ 'lastDismissReason' ] !== 'browser-back-navigation-clicked' ) {
85+ // allow to close for other cases
86+ return Promise . resolve ( )
87+ }
88+ // avoid browser navigation when a modal is open
89+ if ( this . atLeastOneModalOpen ( ) ) {
90+ // back to initial route
91+ history . forward ( )
92+ }
93+ return Promise . reject ( 'blocked-by-interceptor' )
94+ }
95+ }
7896
7997 constructor ( ) {
8098 setTheme ( 'bs5' )
@@ -129,19 +147,14 @@ export class LayoutService {
129147 return this . restoreDialog ( componentStates . id )
130148 }
131149 const modalRef = this . bsModal . show ( dialog , Object . assign ( componentStates , { ...this . dialogConfig , ...override } , { class : dialogClass } ) )
132- if ( modalRef . id && this . modalIDS . indexOf ( modalRef . id ) === - 1 ) {
133- this . modalIDS . push ( modalRef . id )
134- }
150+ this . modalIDS . add ( modalRef . id )
135151 return modalRef
136152 }
137153
138154 minimizeDialog ( modalID : any , element : { name : string ; mimeUrl : string } ) : BsModalRef < unknown > {
139155 const modal = this . getModal ( modalID )
140156 if ( modal ) {
141- this . bsModal [ '_renderer' ] . setAttribute ( modal [ 'instance' ] . _element . nativeElement , 'aria-hidden' , 'true' )
142- this . bsModal [ '_renderer' ] . removeClass ( modal [ 'instance' ] . _element . nativeElement , 'show' )
143- setTimeout ( ( ) => this . bsModal [ '_renderer' ] . setStyle ( modal [ 'instance' ] . _element . nativeElement , 'display' , 'none' ) , 100 )
144-
157+ this . closeModalWithEffect ( modal )
145158 if ( ! this . minimizedWindows . getValue ( ) . find ( ( m : AppWindow ) => m . id === modalID ) ) {
146159 this . minimizedWindows . next ( [ ...this . minimizedWindows . getValue ( ) , { id : modalID , element } ] )
147160 }
@@ -152,36 +165,40 @@ export class LayoutService {
152165 restoreDialog ( modalID : any ) : BsModalRef < unknown > {
153166 const modal : BsModalRef < unknown > = this . getModal ( modalID )
154167 if ( modal ) {
155- this . bsModal [ '_renderer' ] . setAttribute ( modal [ 'instance' ] . _element . nativeElement , 'aria-hidden' , 'false' )
156- this . bsModal [ '_renderer' ] . setStyle ( modal [ 'instance' ] . _element . nativeElement , 'display' , 'block' )
157- setTimeout ( ( ) => {
158- this . bsModal [ '_renderer' ] . addClass ( modal [ 'instance' ] . _element . nativeElement , 'show' )
159- } , 100 )
168+ this . openModalWithEffect ( modal )
169+ this . minimizedWindows . next ( this . minimizedWindows . getValue ( ) . filter ( ( m : AppWindow ) => m . id !== modalID ) )
160170 }
161171 return modal
162172 }
163173
164- closeDialog ( delay : number | null = null , id : any = null , all = false ) {
174+ closeDialog ( delay : number | null = null , id : number | string = null , all = false ) {
165175 if ( all ) {
166176 this . bsModal . hide ( )
167- this . modalIDS = [ ]
168- } else {
169- if ( id ) {
170- this . modalIDS = this . modalIDS . filter ( ( mid ) => mid !== id )
171- } else {
172- id = this . modalIDS . pop ( )
177+ this . modalIDS . clear ( )
178+ this . minimizedWindows . next ( [ ] )
179+ return
180+ }
181+ if ( ! id ) {
182+ let last : string | number
183+ for ( const value of this . modalIDS ) {
184+ last = value
173185 }
174- if ( delay ) {
175- setTimeout ( ( ) => this . bsModal . hide ( id ) , delay )
186+ if ( last !== undefined ) {
187+ id = last
176188 } else {
177- this . bsModal . hide ( id )
189+ console . warn ( 'Last modal id not found' )
190+ return
178191 }
179- this . minimizedWindows . next ( this . minimizedWindows . getValue ( ) . filter ( ( m ) => m . id !== id ) )
180192 }
181- }
182-
183- getModal ( modalID : any ) : BsModalRef {
184- return this . bsModal [ 'loaders' ] . find ( ( loader : any ) => loader . instance ?. config . id === modalID )
193+ this . modalIDS . delete ( id )
194+ const modal : BsModalRef < unknown > = this . getModal ( id )
195+ if ( ! modal ) return
196+ if ( delay ) {
197+ setTimeout ( ( ) => this . closeModalWithEffect ( modal , true ) , delay )
198+ } else {
199+ this . closeModalWithEffect ( modal , true )
200+ }
201+ this . minimizedWindows . next ( this . minimizedWindows . getValue ( ) . filter ( ( m ) => m . id !== id ) )
185202 }
186203
187204 openContextMenu ( event : any , component : ContextMenuComponent < any > ) {
@@ -269,6 +286,37 @@ export class LayoutService {
269286 this . closeDialog ( null , null , true )
270287 }
271288
289+ private openModalWithEffect ( modal : BsModalRef < unknown > ) {
290+ this . bsModal [ '_renderer' ] . setAttribute ( modal [ 'instance' ] . _element . nativeElement , 'aria-hidden' , 'false' )
291+ this . bsModal [ '_renderer' ] . setStyle ( modal [ 'instance' ] . _element . nativeElement , 'display' , 'block' )
292+ setTimeout ( ( ) => {
293+ this . bsModal [ '_renderer' ] . addClass ( modal [ 'instance' ] . _element . nativeElement , 'show' )
294+ } , 100 )
295+ }
296+
297+ private closeModalWithEffect ( modal : BsModalRef < unknown > , hide = false ) {
298+ this . bsModal [ '_renderer' ] . setAttribute ( modal [ 'instance' ] . _element . nativeElement , 'aria-hidden' , 'true' )
299+ this . bsModal [ '_renderer' ] . removeClass ( modal [ 'instance' ] . _element . nativeElement , 'show' )
300+ setTimeout ( ( ) => this . bsModal [ '_renderer' ] . setStyle ( modal [ 'instance' ] . _element . nativeElement , 'display' , 'none' ) , 500 )
301+ if ( hide ) {
302+ this . bsModal . hide ( modal . id )
303+ }
304+ }
305+
306+ private getModal ( modalID : any ) : BsModalRef {
307+ const modal = this . bsModal [ 'loaders' ] . find ( ( loader : any ) => loader . instance ?. config . id === modalID )
308+ if ( modal ) {
309+ modal . id = modalID
310+ return modal
311+ }
312+ console . warn ( `Modal ${ modalID } not found` )
313+ return null
314+ }
315+
316+ private atLeastOneModalOpen ( ) : boolean {
317+ return this . modalIDS . size - this . minimizedWindows . getValue ( ) . length > 0
318+ }
319+
272320 private setTheme ( theme : string ) {
273321 this . electron . send ( EVENT . MISC . SWITCH_THEME , theme )
274322 this . ngZone . run ( ( ) => this . switchTheme . next ( theme ) )
0 commit comments