@@ -29,6 +29,7 @@ import type { FeatureFeedbackServiceInterface } from '@internetarchive/feature-f
2929import type { RecaptchaManagerInterface } from '@internetarchive/recaptcha-manager' ;
3030import type { AnalyticsManagerInterface } from '@internetarchive/analytics-manager' ;
3131import type { SharedResizeObserverInterface } from '@internetarchive/shared-resize-observer' ;
32+ import type { BinSnappingInterval } from '@internetarchive/histogram-date-range' ;
3233import chevronIcon from './assets/img/icons/chevron' ;
3334import expandIcon from './assets/img/icons/expand' ;
3435import {
@@ -50,10 +51,6 @@ import type {
5051 CollectionTitles ,
5152 PageSpecifierParams ,
5253} from './data-source/models' ;
53- import './collection-facets/more-facets-content' ;
54- import './collection-facets/facets-template' ;
55- import './collection-facets/facet-tombstone-row' ;
56- import './expanded-date-picker' ;
5754import {
5855 analyticsActions ,
5956 analyticsCategories ,
@@ -65,6 +62,12 @@ import {
6562 updateSelectedFacetBucket ,
6663} from './utils/facet-utils' ;
6764
65+ import '@internetarchive/histogram-date-range' ;
66+ import './collection-facets/more-facets-content' ;
67+ import './collection-facets/facets-template' ;
68+ import './collection-facets/facet-tombstone-row' ;
69+ import './expanded-date-picker' ;
70+
6871@customElement ( 'collection-facets' )
6972export class CollectionFacets extends LitElement {
7073 @property ( { type : Object } ) searchService ?: SearchServiceInterface ;
@@ -73,7 +76,7 @@ export class CollectionFacets extends LitElement {
7376
7477 @property ( { type : Object } ) aggregations ?: Record < string , Aggregation > ;
7578
76- @property ( { type : Object } ) fullYearsHistogramAggregation ?: Aggregation ;
79+ @property ( { type : Object } ) histogramAggregation ?: Aggregation ;
7780
7881 @property ( { type : String } ) minSelectedDate ?: string ;
7982
@@ -83,7 +86,7 @@ export class CollectionFacets extends LitElement {
8386
8487 @property ( { type : Boolean } ) facetsLoading = false ;
8588
86- @property ( { type : Boolean } ) fullYearAggregationLoading = false ;
89+ @property ( { type : Boolean } ) histogramAggregationLoading = false ;
8790
8891 @property ( { type : Object } ) selectedFacets ?: SelectedFacets ;
8992
@@ -164,7 +167,7 @@ export class CollectionFacets extends LitElement {
164167 return html `
165168 <div id= "container" class = ${ containerClasses } >
166169 ${ this . showHistogramDatePicker &&
167- ( this . fullYearsHistogramAggregation || this . fullYearAggregationLoading )
170+ ( this . histogramAggregation || this . histogramAggregationLoading )
168171 ? html `
169172 <section
170173 class= "facet-group"
@@ -230,15 +233,63 @@ export class CollectionFacets extends LitElement {
230233 } ) ;
231234 }
232235
236+ /**
237+ * Properties to pass into the date-picker histogram component
238+ */
239+ private get histogramProps ( ) {
240+ const { histogramAggregation : aggregation } = this ;
241+ if ( ! aggregation ) return undefined ;
242+
243+ // Normalize some properties from the raw aggregation
244+ const firstYear =
245+ aggregation . first_bucket_year ?? aggregation . first_bucket_key ;
246+ const lastYear =
247+ aggregation . last_bucket_year ?? aggregation . last_bucket_key ;
248+ if ( firstYear == null || lastYear == null ) return undefined ; // We at least need a start/end year defined
249+
250+ const firstMonth = aggregation . first_bucket_month ?? 1 ;
251+ const lastMonth = aggregation . last_bucket_month ?? 12 ;
252+
253+ const yearInterval = aggregation . interval ?? 1 ;
254+ const monthInterval = aggregation . interval_in_months ?? 12 ;
255+
256+ const zeroPadMonth = ( month : number ) => month . toString ( ) . padStart ( 2 , '0' ) ;
257+
258+ // Format the min/max dates appropriately
259+ const minDate = this . isTvSearch
260+ ? `${ firstYear } -${ zeroPadMonth ( firstMonth ) } `
261+ : `${ firstYear } ` ;
262+
263+ const maxDate = this . isTvSearch
264+ ? `${ lastYear } -${ zeroPadMonth ( lastMonth + monthInterval - 1 ) } `
265+ : `${ lastYear + yearInterval - 1 } ` ;
266+
267+ const hasMonths = this . isTvSearch && monthInterval < 12 ;
268+ return {
269+ buckets : aggregation . buckets as number [ ] ,
270+ dateFormat : this . isTvSearch ? 'YYYY-MM' : 'YYYY' ,
271+ tooltipDateFormat : hasMonths ? 'MMM YYYY' : 'YYYY' ,
272+ binSnapping : ( hasMonths ? 'month' : 'year' ) as BinSnappingInterval ,
273+ minDate,
274+ maxDate,
275+ } ;
276+ }
277+
233278 /**
234279 * Opens a modal dialog containing an enlarged version of the date picker.
235280 */
236281 private showDatePickerModal ( ) : void {
237- const { fullYearsHistogramAggregation } = this ;
238- const minDate = fullYearsHistogramAggregation ?. first_bucket_key ;
239- const maxDate = fullYearsHistogramAggregation ?. last_bucket_key ;
240- const buckets = fullYearsHistogramAggregation ?. buckets as number [ ] ;
241- const dateFormat = this . isTvSearch ? 'YYYY-MM' : 'YYYY' ;
282+ const { histogramProps } = this ;
283+ if ( ! histogramProps ) return ;
284+
285+ const {
286+ buckets,
287+ dateFormat,
288+ tooltipDateFormat,
289+ binSnapping,
290+ minDate,
291+ maxDate,
292+ } = histogramProps ;
242293
243294 // Because the modal manager does not clear its DOM content after being closed,
244295 // it may try to render the exact same date picker template when it is reopened.
@@ -264,6 +315,8 @@ export class CollectionFacets extends LitElement {
264315 .minSelectedDate = ${ this . minSelectedDate }
265316 .maxSelectedDate = ${ this . maxSelectedDate }
266317 .dateFormat = ${ dateFormat }
318+ .tooltipDateFormat = ${ tooltipDateFormat }
319+ .binSnapping = ${ binSnapping }
267320 .buckets = ${ buckets }
268321 .modalManager = ${ this . modalManager }
269322 .analyticsHandler = ${ this . analyticsHandler }
@@ -328,30 +381,42 @@ export class CollectionFacets extends LitElement {
328381 : nothing ;
329382 }
330383
331- private get histogramTemplate ( ) {
332- const { fullYearsHistogramAggregation } = this ;
333- const minDate = fullYearsHistogramAggregation ?. first_bucket_key ;
334- const maxDate = fullYearsHistogramAggregation ?. last_bucket_key ;
335- const dateFormat = this . isTvSearch ? 'YYYY-MM' : 'YYYY' ;
336- return this . fullYearAggregationLoading
337- ? html `<div class= "histogram-loading-indicator" > & hellip;</ div> ` // Ellipsis block
338- : html `
339- <his to gram- date-range
340- class= ${ this . isTvSearch ? 'wide-inputs' : nothing }
341- .minDate = ${ minDate }
342- .maxDate = ${ maxDate }
343- .minSelectedDate = ${ this . minSelectedDate ?? minDate }
344- .maxSelectedDate = ${ this . maxSelectedDate ?? maxDate }
345- .updateDelay = ${ 100 }
346- .dateFormat = ${ dateFormat }
347- mis singDataMessage= "..."
348- .width=${ this . collapsableFacets && this . contentWidth
349- ? this . contentWidth
350- : 180 }
351- .bins=${ fullYearsHistogramAggregation ?. buckets as number [ ] }
352- @histogramDateRangeUpdated=${ this . histogramDateRangeUpdated }
353- ></histogram-date-range>
354- ` ;
384+ private get histogramTemplate ( ) : TemplateResult | typeof nothing {
385+ if ( this . histogramAggregationLoading ) {
386+ return html ` <div class= "histogram-loading-indicator" > & hellip;</ div> ` ;
387+ }
388+
389+ const { histogramProps } = this ;
390+ if ( ! histogramProps ) return nothing ;
391+
392+ const {
393+ buckets,
394+ dateFormat,
395+ tooltipDateFormat,
396+ binSnapping,
397+ minDate,
398+ maxDate,
399+ } = histogramProps ;
400+
401+ return html `
402+ <his to gram- date-range
403+ class= ${ this . isTvSearch ? 'wide-inputs' : nothing }
404+ .minDate = ${ minDate }
405+ .maxDate = ${ maxDate }
406+ .minSelectedDate = ${ this . minSelectedDate ?? minDate }
407+ .maxSelectedDate = ${ this . maxSelectedDate ?? maxDate }
408+ .updateDelay = ${ 100 }
409+ .dateFormat = ${ dateFormat }
410+ .tooltipDateFormat = ${ tooltipDateFormat }
411+ .binSnapping = ${ binSnapping }
412+ .bins = ${ buckets }
413+ mis singDataMessage= "..."
414+ .width=${ this . collapsableFacets && this . contentWidth
415+ ? this . contentWidth
416+ : 180 }
417+ @histogramDateRangeUpdated=${ this . histogramDateRangeUpdated }
418+ ></histogram-date-range>
419+ ` ;
355420 }
356421
357422 /**
@@ -533,8 +598,8 @@ export class CollectionFacets extends LitElement {
533598 private get aggregationFacetGroups ( ) : FacetGroup [ ] {
534599 const facetGroups : FacetGroup [ ] = [ ] ;
535600 Object . entries ( this . aggregations ?? [ ] ) . forEach ( ( [ key , aggregation ] ) => {
536- // the year_histogram data is in a different format so can't be handled here
537- if ( key === 'year_histogram' ) return ;
601+ // the year_histogram and date_histogram data is in a different format so can't be handled here
602+ if ( [ 'year_histogram' , 'date_histogram' ] . includes ( key ) ) return ;
538603
539604 const option = key as FacetOption ;
540605 const title = facetTitles [ option ] ;
0 commit comments