@@ -38,7 +38,8 @@ export default class DaTitle extends LitElement {
3838 previewPrefix : { attribute : false } ,
3939 livePrefix : { attribute : false } ,
4040 hasChanges : { attribute : false } ,
41- _savingDisabled : { state : true } ,
41+ configSaveDisabled : { attribute : false } ,
42+ showConfigStaleDialog : { attribute : false } ,
4243 _actionsVis : { state : true } ,
4344 _status : { state : true } ,
4445 _fixedActions : { state : true } ,
@@ -48,39 +49,48 @@ export default class DaTitle extends LitElement {
4849 connectedCallback ( ) {
4950 super . connectedCallback ( ) ;
5051 this . shadowRoot . adoptedStyleSheets = [ sheet ] ;
51- this . _actionsVis = this . getInitialActions ( ) ;
52- this . hasChanges = false ;
53- this . _savingDisabled = false ;
54- this . _isStaleIgnored = false ;
55- this . _pollSession = 0 ;
5652 inlinesvg ( { parent : this . shadowRoot , paths : ICONS } ) ;
57- this . syncConfigPolling ( ) ;
58-
59- if ( this . details . view === 'sheet' ) {
60- this . collabStatus = window . navigator . onLine
61- ? 'connected'
62- : 'offline' ;
63-
64- window . addEventListener ( 'online' , ( ) => { this . collabStatus = 'connected' ; } ) ;
65- window . addEventListener ( 'offline' , ( ) => { this . collabStatus = 'offline' ; } ) ;
66- }
6753 }
6854
6955 disconnectedCallback ( ) {
70- this . clearConfigPolling ( ) ;
56+ this . removeCollabListeners ( ) ;
7157 super . disconnectedCallback ( ) ;
7258 }
7359
7460 updated ( changedProperties ) {
7561 super . updated ( changedProperties ) ;
76- if ( changedProperties . has ( 'details' ) ) {
77- this . _actionsVis = this . getInitialActions ( ) ;
78- this . _savingDisabled = false ;
79- this . _isStaleIgnored = false ;
80- this . syncConfigPolling ( ) ;
62+ if ( changedProperties . has ( 'details' ) ) this . syncDetailsState ( ) ;
63+ if ( changedProperties . has ( 'showConfigStaleDialog' ) ) {
64+ if ( this . showConfigStaleDialog ) {
65+ this . openConfigStaleDialog ( ) ;
66+ } else {
67+ this . _dialog = undefined ;
68+ }
8169 }
8270 }
8371
72+ async openConfigStaleDialog ( ) {
73+ this . _dialog = undefined ;
74+ await import ( '../../shared/da-dialog/da-dialog.js' ) ;
75+ this . _dialog = {
76+ title : 'Config Updated' ,
77+ content : html `
78+ < p > The config has been updated. Please refresh to get the latest changes, or ignore to keep your existing edits.</ p >
79+ ` ,
80+ action : {
81+ style : 'accent' ,
82+ label : 'Refresh' ,
83+ click : ( ) => this . handleConfigRefreshAction ( ) ,
84+ } ,
85+ ignoreAction : {
86+ style : 'primary outline' ,
87+ label : 'Ignore' ,
88+ click : ( ) => this . handleConfigIgnoreAction ( ) ,
89+ } ,
90+ close : ( ) => this . handleConfigIgnoreAction ( ) ,
91+ } ;
92+ }
93+
8494 firstUpdated ( ) {
8595 const observer = new IntersectionObserver ( ( entries ) => {
8696 this . _fixedActions = ! entries [ 0 ] . isIntersecting ;
@@ -115,6 +125,7 @@ export default class DaTitle extends LitElement {
115125 }
116126
117127 async handleAction ( action ) {
128+ if ( ! this . details ) return ;
118129 this . toggleActions ( ) ;
119130 this . _status = null ;
120131
@@ -138,7 +149,7 @@ export default class DaTitle extends LitElement {
138149 }
139150
140151 if ( this . _isConfigView ) {
141- if ( this . _savingDisabled ) {
152+ if ( this . configSaveDisabled ) {
142153 if ( sendBtn ) {
143154 sendBtn . classList . remove ( 'is-sending' ) ;
144155 }
@@ -155,7 +166,7 @@ export default class DaTitle extends LitElement {
155166 console . log ( 'Saving configuration failed because:' , daConfigResp . status , await daConfigResp . text ( ) ) ;
156167 } else {
157168 this . hasChanges = false ;
158- await this . cacheConfigData ( ) ;
169+ await this . onConfigSaved ?. ( ) ;
159170 }
160171 return ;
161172 }
@@ -241,7 +252,7 @@ export default class DaTitle extends LitElement {
241252 }
242253
243254 // toggle off if already on
244- if ( this . _actionsVis . length > 0 ) {
255+ if ( ( this . _actionsVis || [ ] ) . length > 0 ) {
245256 this . _actionsVis = [ ] ;
246257 return ;
247258 }
@@ -263,18 +274,19 @@ export default class DaTitle extends LitElement {
263274 }
264275
265276 get _isConfigView ( ) {
266- return this . details . view === 'config' ;
277+ return this . details ? .view === 'config' ;
267278 }
268279
269280 get _isSaveOnlyView ( ) {
270- return this . _isConfigView || this . details . view === 'sheet' ;
281+ return this . _isConfigView || this . details ? .view === 'sheet' ;
271282 }
272283
273284 get isDotDADoc ( ) {
274- return this . details . view === 'edit' && this . details . fullpath . includes ( '/.da/' ) ;
285+ return this . details ? .view === 'edit' && this . details ? .fullpath ? .includes ( '/.da/' ) ;
275286 }
276287
277288 getInitialActions ( ) {
289+ if ( ! this . details ) return [ ] ;
278290 if ( this . isDotDADoc ) {
279291 return [ ] ;
280292 }
@@ -284,95 +296,57 @@ export default class DaTitle extends LitElement {
284296 return [ ] ;
285297 }
286298
287- clearConfigPolling ( ) {
288- if ( this . _pollInterval ) {
289- clearInterval ( this . _pollInterval ) ;
290- this . _pollInterval = null ;
299+ get visibleActions ( ) {
300+ if ( this . _isSaveOnlyView ) {
301+ return [ 'save' ] ;
291302 }
303+ return this . _actionsVis || [ ] ;
292304 }
293305
294- syncConfigPolling ( ) {
295- this . _pollSession = ( this . _pollSession || 0 ) + 1 ;
296- this . clearConfigPolling ( ) ;
297- if ( ! this . _isConfigView || this . _isStaleIgnored ) {
298- this . _cachedConfigData = null ;
306+ syncDetailsState ( ) {
307+ this . _actionsVis = [ ] ;
308+ this . syncCollabStatus ( ) ;
309+ }
310+
311+ syncCollabStatus ( ) {
312+ this . removeCollabListeners ( ) ;
313+ if ( this . details ?. view !== 'sheet' ) {
314+ this . collabStatus = undefined ;
299315 return ;
300316 }
301- this . startConfigPolling ( this . _pollSession ) ;
302- }
303317
304- async cacheConfigData ( ) {
305- const resp = await daFetch ( this . details . sourceUrl ) ;
306- if ( ! resp . ok ) return ;
307- this . _cachedConfigData = JSON . stringify ( await resp . json ( ) ) ;
308- }
318+ this . collabStatus = window . navigator . onLine
319+ ? 'connected'
320+ : 'offline' ;
309321
310- async startConfigPolling ( pollSession ) {
311- await this . cacheConfigData ( ) ;
312- if ( pollSession !== this . _pollSession || this . _isStaleIgnored ) return ;
313- this . clearConfigPolling ( ) ;
314- this . _pollInterval = setInterval ( ( ) => this . checkConfigChanges ( ) , 30000 ) ;
322+ this . _handleOnline = ( ) => { this . collabStatus = 'connected' ; } ;
323+ this . _handleOffline = ( ) => { this . collabStatus = 'offline' ; } ;
324+ window . addEventListener ( 'online' , this . _handleOnline ) ;
325+ window . addEventListener ( 'offline' , this . _handleOffline ) ;
315326 }
316327
317- async checkConfigChanges ( ) {
318- if ( this . _isStaleIgnored ) return ;
319- const resp = await daFetch ( this . details . sourceUrl ) ;
320- if ( ! resp . ok ) return ;
321- const latestConfigData = JSON . stringify ( await resp . json ( ) ) ;
322- if ( ! this . _cachedConfigData ) {
323- this . _cachedConfigData = latestConfigData ;
324- return ;
328+ removeCollabListeners ( ) {
329+ if ( this . _handleOnline ) {
330+ window . removeEventListener ( 'online' , this . _handleOnline ) ;
331+ this . _handleOnline = null ;
325332 }
326- if ( latestConfigData !== this . _cachedConfigData ) {
327- this . clearConfigPolling ( ) ;
328- this . showConfigStaleDialog ( ) ;
333+ if ( this . _handleOffline ) {
334+ window . removeEventListener ( 'offline' , this . _handleOffline ) ;
335+ this . _handleOffline = null ;
329336 }
330337 }
331338
332- async showConfigStaleDialog ( ) {
333- await import ( '../../shared/da-dialog/da-dialog.js' ) ;
334- this . _dialog = {
335- title : 'Config Updated' ,
336- content : html `
337- < p > The config has been updated. Please refresh to get the latest changes, or ignore to keep your existing edits.</ p >
338- ` ,
339- action : {
340- style : 'accent' ,
341- label : 'Refresh' ,
342- click : async ( ) => this . handleConfigRefresh ( ) ,
343- } ,
344- ignoreAction : {
345- style : 'primary outline' ,
346- label : 'Ignore' ,
347- click : ( ) => this . handleConfigIgnore ( ) ,
348- } ,
349- close : ( ) => this . handleConfigIgnore ( ) ,
350- } ;
351- }
352-
353- handleConfigIgnore ( ) {
354- this . _dialog = undefined ;
355- this . _savingDisabled = true ;
356- this . _isStaleIgnored = true ;
357- this . clearConfigPolling ( ) ;
339+ async handleConfigIgnoreAction ( ) {
340+ await this . onConfigIgnore ?. ( ) ;
358341 }
359342
360- async handleConfigRefresh ( ) {
361- this . _dialog = undefined ;
362- this . _savingDisabled = false ;
363- this . _isStaleIgnored = false ;
364- this . hasChanges = false ;
365- const daSheet = document . querySelector ( '.da-sheet' ) ;
366- if ( ! daSheet ) return ;
367- const { default : initSheet , getData } = await import ( '../../sheet/utils/index.js' ) ;
368- const freshData = await getData ( this . details . sourceUrl ) ;
369- this . sheet = await initSheet ( daSheet , freshData ) ;
370- this . syncConfigPolling ( ) ;
343+ async handleConfigRefreshAction ( ) {
344+ await this . onConfigRefresh ?. ( ) ;
371345 }
372346
373347 renderActions ( ) {
374- const saveDisabled = this . _isSaveOnlyView && ( ! this . hasChanges || this . _savingDisabled ) ;
375- return html `${ this . _actionsVis . map ( ( action ) => html `
348+ const saveDisabled = this . _isSaveOnlyView && ( ! this . hasChanges || this . configSaveDisabled ) ;
349+ return html `${ this . visibleActions . map ( ( action ) => html `
376350 < button
377351 @click =${ ( ) => this . handleAction ( action ) }
378352 class ="con-button da-title-action ${ saveDisabled ? '' : 'blue' } "
@@ -449,6 +423,8 @@ export default class DaTitle extends LitElement {
449423 }
450424
451425 render ( ) {
426+ if ( ! this . details ) return nothing ;
427+
452428 return html `
453429 < div class ="da-title-inner ${ this . _readOnly ? 'is-read-only' : '' } ">
454430 < div class ="da-title-name ">
@@ -475,7 +451,7 @@ export default class DaTitle extends LitElement {
475451 ` }
476452 </ div >
477453 </ div >
478- ${ this . _isConfigView && this . _savingDisabled
454+ ${ this . _isConfigView && this . configSaveDisabled
479455 ? html `< p class ="da-title-save-disabled-msg "> Saving is disabled until the config has been refreshed. If you have unsaved changes that you want to preserve, you can copy them and merge them after refreshing the config.</ p > `
480456 : nothing }
481457 ${ this . _dialog ? this . renderDialog ( ) : nothing }
0 commit comments