@@ -8,7 +8,7 @@ import { log } from '../../../../../system/decorators/log';
88import { debounce } from '../../../../../system/function/debounce' ;
99import { defer } from '../../../../../system/promise' ;
1010import { pluralize , truncateMiddle } from '../../../../../system/string' ;
11- import type { Commit , State , TimelineSliceBy } from '../../../../plus/timeline/protocol' ;
11+ import type { State , TimelineDatum , TimelineSliceBy } from '../../../../plus/timeline/protocol' ;
1212import { renderCommitSha } from '../../../shared/components/commit-sha' ;
1313import { GlElement } from '../../../shared/components/element' ;
1414import { createFromDateDelta , formatDate , fromNow } from '../../../shared/date' ;
@@ -17,6 +17,7 @@ import type { SliderChangeEventDetail } from './slider';
1717import { GlChartSlider } from './slider' ;
1818import '@shoelace-style/shoelace/dist/components/resize-observer/resize-observer.js' ;
1919import './scroller' ;
20+ import '../../../shared/components/indicators/watermark-loader' ;
2021
2122export const tagName = 'gl-timeline-chart' ;
2223
@@ -51,8 +52,9 @@ export class GlTimelineChart extends GlElement {
5152 }
5253 > ( ) ;
5354 private readonly _slicesByIndex = new Map < number , string > ( ) ;
54- private readonly _commitsByTimestamp = new Map < number , Commit > ( ) ;
55+ private readonly _commitsByTimestamp = new Map < number , TimelineDatum > ( ) ;
5556
57+ @state ( )
5658 private _loading ?: ReturnType < typeof defer < void > > ;
5759
5860 private get compact ( ) : boolean {
@@ -166,24 +168,29 @@ export class GlTimelineChart extends GlElement {
166168 }
167169
168170 protected override render ( ) : unknown {
169- // Don't render anything if the data is still loading
170- if ( this . data === null ) return nothing ;
171- if ( ! this . data ?. length ) {
172- return html `< div class ="empty "> < p > No commits found for the specified time period.</ p > </ div > ` ;
173- }
174-
175- return html `< gl-chart-scroller
176- .range =${ this . _rangeScrollable }
177- .visibleRange =${ this . _zoomedRangeScrollable }
178- @gl-scroll=${ this . onScroll }
179- @gl-scroll-start=${ this . onScrollStart }
180- @gl-scroll-end=${ this . onScrollEnd }
181- >
182- < sl-resize-observer @sl-resize =${ this . onResize } >
183- < div id ="chart " tabindex ="-1 "> </ div >
184- </ sl-resize-observer >
185- ${ this . renderFooter ( ) }
186- </ gl-chart-scroller > ` ;
171+ return html `${ this . _loading ?. pending
172+ ? html `< div class ="notice notice--blur ">
173+ < gl-watermark-loader pulse > < p > Loading...</ p > </ gl-watermark-loader >
174+ </ div > `
175+ : ! this . data ?. length
176+ ? html `< div class ="notice ">
177+ < gl-watermark-loader
178+ > < p > No commits found for the specified time period</ p > </ gl-watermark-loader
179+ >
180+ </ div > `
181+ : nothing }
182+ < gl-chart-scroller
183+ .range =${ this . _rangeScrollable }
184+ .visibleRange =${ this . _zoomedRangeScrollable }
185+ @gl-scroll=${ this . onScroll }
186+ @gl-scroll-start=${ this . onScrollStart }
187+ @gl-scroll-end=${ this . onScrollEnd }
188+ >
189+ < sl-resize-observer @sl-resize =${ this . onResize } >
190+ < div id ="chart " tabindex ="-1 "> </ div >
191+ </ sl-resize-observer >
192+ ${ this . data ?. length ? this . renderFooter ( ) : nothing }
193+ </ gl-chart-scroller > ` ;
187194 }
188195
189196 private renderFooter ( ) {
@@ -442,7 +449,7 @@ export class GlTimelineChart extends GlElement {
442449 return result ;
443450 }
444451
445- private calculateChangeMetrics ( dataset : Commit [ ] ) : { q1 : number ; q3 : number ; maxChanges : number } {
452+ private calculateChangeMetrics ( dataset : TimelineDatum [ ] ) : { q1 : number ; q3 : number ; maxChanges : number } {
446453 const sortedChanges = dataset . map ( c => ( c . additions ?? 0 ) + ( c . deletions ?? 0 ) ) . sort ( ( a , b ) => a - b ) ;
447454 return {
448455 maxChanges : sortedChanges [ sortedChanges . length - 1 ] ,
@@ -511,7 +518,7 @@ export class GlTimelineChart extends GlElement {
511518
512519 @log < GlTimelineChart [ 'prepareChartData' ] > ( { args : { 0 : d => d ?. length } } )
513520 private prepareChartData (
514- dataset : Commit [ ] ,
521+ dataset : TimelineDatum [ ] ,
515522 metrics : { minRadius : number ; maxRadius : number ; q1 : number ; q3 : number ; maxChanges : number } ,
516523 ) : PreparedChartData {
517524 const commits = dataset . length + 1 ;
@@ -601,24 +608,18 @@ export class GlTimelineChart extends GlElement {
601608 const abortController = this . _abortController ;
602609
603610 const loading = defer < void > ( ) ;
611+ void loading . promise . finally ( ( ) => ( this . _loading = undefined ) ) ;
612+
604613 this . _loading = loading ;
605614 this . emit ( 'gl-loading' , loading . promise ) ;
606615
607- const data = await dataPromise ;
616+ const data = ( await dataPromise ) ?? [ ] ;
608617
609618 if ( abortController ?. signal . aborted ) {
610619 loading ?. cancel ( ) ;
611620 return ;
612621 }
613622
614- if ( ! data ?. length ) {
615- this . _chart ?. destroy ( ) ;
616- this . _chart = undefined ;
617-
618- loading ?. fulfill ( ) ;
619- return ;
620- }
621-
622623 // Clear previous state
623624 this . _slices . clear ( ) ;
624625 this . _slicesByIndex . clear ( ) ;
@@ -639,7 +640,9 @@ export class GlTimelineChart extends GlElement {
639640 return ;
640641 }
641642
642- this . range = [ new Date ( data [ data . length - 1 ] . date ) , new Date ( data [ 0 ] . date ) ] ;
643+ this . range = data . length
644+ ? [ new Date ( data [ data . length - 1 ] . date ) , new Date ( data [ 0 ] . date ) ]
645+ : [ new Date ( ) , new Date ( ) ] ;
643646
644647 // Initialize plugins
645648 bar ( ) ;
@@ -657,7 +660,7 @@ export class GlTimelineChart extends GlElement {
657660
658661 onafterinit : ( ) => {
659662 this . updateChartSize ( ) ;
660- setTimeout ( ( ) => loading ?. fulfill ( ) , 250 ) ;
663+ setTimeout ( ( ) => loading ?. fulfill ( ) , 0 ) ;
661664 } ,
662665 onrendered : this . getOnRenderedCallback ( this ) ,
663666 // Restore the zoomed domain when the chart is resized, because it gets lost
@@ -830,9 +833,11 @@ export class GlTimelineChart extends GlElement {
830833
831834 const commit = data [ 0 ] ;
832835 this . _shaHovered = undefined ;
833- this . _shaSelected = commit . sha ;
836+ this . _shaSelected = commit ? .sha ;
834837
835- this . selectDataPoint ( new Date ( commit . date ) , { select : true } ) ;
838+ if ( commit != null ) {
839+ this . selectDataPoint ( new Date ( commit . date ) , { select : true } ) ;
840+ }
836841 } else {
837842 this . _chart . config ( 'axis.y.tick.values' , yTickValues , false ) ;
838843 this . _chart . config ( 'axis.y.min' , minY , false ) ;
@@ -849,11 +854,14 @@ export class GlTimelineChart extends GlElement {
849854 if ( commit == null ) {
850855 commit = data [ 0 ] ;
851856 this . _shaHovered = undefined ;
852- this . _shaSelected = commit . sha ;
857+ this . _shaSelected = commit ?. sha ;
858+ }
859+
860+ if ( commit != null ) {
861+ this . selectDataPoint ( new Date ( commit . date ) , { select : true } ) ;
853862 }
854- this . selectDataPoint ( new Date ( commit . date ) , { select : true } ) ;
855863
856- setTimeout ( ( ) => loading ?. fulfill ( ) , 250 ) ;
864+ setTimeout ( ( ) => loading ?. fulfill ( ) , 0 ) ;
857865 } ,
858866 } ) ;
859867 }
0 commit comments