@internetarchive/collection-browser 0.4.16-alpha.9 → 0.4.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/app-root.js +12 -0
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/collection-browser.d.ts +53 -14
- package/dist/src/collection-browser.js +279 -113
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/facets-template.d.ts +3 -0
- package/dist/src/collection-facets/facets-template.js +20 -1
- package/dist/src/collection-facets/facets-template.js.map +1 -1
- package/dist/src/collection-facets/more-facets-content.js +7 -4
- package/dist/src/collection-facets/more-facets-content.js.map +1 -1
- package/dist/src/collection-facets.d.ts +0 -2
- package/dist/src/collection-facets.js +1 -4
- package/dist/src/collection-facets.js.map +1 -1
- package/dist/src/empty-placeholder.js +1 -0
- package/dist/src/empty-placeholder.js.map +1 -1
- package/dist/src/models.d.ts +5 -0
- package/dist/src/models.js.map +1 -1
- package/dist/src/tiles/grid/item-tile.js +10 -3
- package/dist/src/tiles/grid/item-tile.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact.d.ts +1 -0
- package/dist/src/tiles/list/tile-list-compact.js +13 -1
- package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
- package/dist/src/tiles/list/tile-list.js +10 -1
- package/dist/src/tiles/list/tile-list.js.map +1 -1
- package/dist/src/utils/format-date.d.ts +1 -1
- package/dist/src/utils/format-date.js +3 -0
- package/dist/src/utils/format-date.js.map +1 -1
- package/dist/src/utils/local-date-from-utc.d.ts +9 -0
- package/dist/src/utils/local-date-from-utc.js +16 -0
- package/dist/src/utils/local-date-from-utc.js.map +1 -0
- package/dist/test/collection-browser.test.js +73 -10
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/collection-facets/facets-template.test.js +80 -0
- package/dist/test/collection-facets/facets-template.test.js.map +1 -1
- package/dist/test/mocks/mock-collection-name-cache.d.ts +2 -0
- package/dist/test/mocks/mock-collection-name-cache.js +4 -0
- package/dist/test/mocks/mock-collection-name-cache.js.map +1 -1
- package/dist/test/mocks/mock-search-responses.d.ts +2 -0
- package/dist/test/mocks/mock-search-responses.js +81 -0
- package/dist/test/mocks/mock-search-responses.js.map +1 -1
- package/dist/test/mocks/mock-search-service.js +3 -1
- package/dist/test/mocks/mock-search-service.js.map +1 -1
- package/dist/test/tiles/grid/item-tile.test.js +124 -3
- package/dist/test/tiles/grid/item-tile.test.js.map +1 -1
- package/dist/test/tiles/list/tile-list-compact.test.js +65 -20
- package/dist/test/tiles/list/tile-list-compact.test.js.map +1 -1
- package/dist/test/tiles/list/tile-list.test.js +106 -4
- package/dist/test/tiles/list/tile-list.test.js.map +1 -1
- package/dist/test/utils/local-date-from-utc.test.d.ts +1 -0
- package/dist/test/utils/local-date-from-utc.test.js +27 -0
- package/dist/test/utils/local-date-from-utc.test.js.map +1 -0
- package/index.html +1 -0
- package/package.json +3 -3
- package/src/app-root.ts +12 -0
- package/src/collection-browser.ts +311 -114
- package/src/collection-facets/facets-template.ts +32 -1
- package/src/collection-facets/more-facets-content.ts +4 -1
- package/src/collection-facets.ts +1 -8
- package/src/empty-placeholder.ts +1 -0
- package/src/models.ts +6 -0
- package/src/tiles/grid/item-tile.ts +11 -4
- package/src/tiles/list/tile-list-compact.ts +16 -2
- package/src/tiles/list/tile-list.ts +12 -5
- package/src/utils/format-date.ts +4 -0
- package/src/utils/local-date-from-utc.ts +15 -0
- package/test/collection-browser.test.ts +101 -12
- package/test/collection-facets/facets-template.test.ts +98 -0
- package/test/mocks/mock-collection-name-cache.ts +8 -0
- package/test/mocks/mock-search-responses.ts +89 -0
- package/test/mocks/mock-search-service.ts +4 -0
- package/test/tiles/grid/item-tile.test.ts +145 -3
- package/test/tiles/list/tile-list-compact.test.ts +70 -19
- package/test/tiles/list/tile-list.test.ts +118 -4
- package/test/utils/local-date-from-utc.test.ts +37 -0
|
@@ -82,6 +82,30 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
82
82
|
* for the previous/next page, we'll fetch the next/previous page to populate it
|
|
83
83
|
*/
|
|
84
84
|
this.dataSource = {};
|
|
85
|
+
/**
|
|
86
|
+
* Updates the height of the left column according to its position on the page.
|
|
87
|
+
* Arrow function ensures proper `this` binding.
|
|
88
|
+
*/
|
|
89
|
+
this.updateLeftColumnHeight = () => {
|
|
90
|
+
var _a, _b, _c, _d, _e;
|
|
91
|
+
if (this.mobileView) {
|
|
92
|
+
(_b = (_a = this.leftColumn) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.removeProperty('height');
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
const clientTop = (_c = this.leftColumn) === null || _c === void 0 ? void 0 : _c.getBoundingClientRect().top;
|
|
96
|
+
(_e = (_d = this.leftColumn) === null || _d === void 0 ? void 0 : _d.style) === null || _e === void 0 ? void 0 : _e.setProperty('height', `${window.innerHeight - (clientTop !== null && clientTop !== void 0 ? clientTop : 0) - 3}px`);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Toggles whether the fade-out is visible at the bottom of the facets.
|
|
101
|
+
* It should only be visible if the facets are not scrolled to the bottom.
|
|
102
|
+
* Arrow function ensures proper `this` binding.
|
|
103
|
+
*/
|
|
104
|
+
this.updateFacetFadeOut = (entries) => {
|
|
105
|
+
var _a, _b;
|
|
106
|
+
const fadeElmt = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.getElementById('facets-bottom-fade');
|
|
107
|
+
fadeElmt === null || fadeElmt === void 0 ? void 0 : fadeElmt.classList.toggle('hidden', (_b = entries === null || entries === void 0 ? void 0 : entries[0]) === null || _b === void 0 ? void 0 : _b.isIntersecting);
|
|
108
|
+
};
|
|
85
109
|
// we only want to scroll on the very first query change
|
|
86
110
|
// so this keeps track of whether we've already set the initial query
|
|
87
111
|
this.initialQueryChangeHappened = false;
|
|
@@ -150,8 +174,6 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
150
174
|
if (letterFilters) {
|
|
151
175
|
this.selectedTitleFilter = null;
|
|
152
176
|
this.selectedCreatorFilter = null;
|
|
153
|
-
this.titleQuery = undefined;
|
|
154
|
-
this.creatorQuery = undefined;
|
|
155
177
|
}
|
|
156
178
|
if (sort) {
|
|
157
179
|
this.sortParam = null;
|
|
@@ -193,8 +215,8 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
193
215
|
if (!((_a = this.baseQuery) === null || _a === void 0 ? void 0 : _a.trim())) {
|
|
194
216
|
this.placeholderType = 'empty-query';
|
|
195
217
|
}
|
|
196
|
-
if (
|
|
197
|
-
!this.searchService) {
|
|
218
|
+
else if (!this.searchResultsLoading &&
|
|
219
|
+
(this.totalResults === 0 || !this.searchService)) {
|
|
198
220
|
this.placeholderType = 'null-result';
|
|
199
221
|
}
|
|
200
222
|
if (this.queryErrorMessage) {
|
|
@@ -218,7 +240,8 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
218
240
|
const shouldShowSearching = this.searchResultsLoading || this.totalResults === undefined;
|
|
219
241
|
const resultsCount = (_a = this.totalResults) === null || _a === void 0 ? void 0 : _a.toLocaleString();
|
|
220
242
|
const resultsLabel = this.totalResults === 1 ? 'Result' : 'Results';
|
|
221
|
-
return html
|
|
243
|
+
return html ` <div id="left-column-scroll-sentinel"></div>
|
|
244
|
+
<div
|
|
222
245
|
id="left-column"
|
|
223
246
|
class="column${this.isResizeToMobile ? ' preload' : ''}"
|
|
224
247
|
>
|
|
@@ -240,7 +263,9 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
240
263
|
: ''}
|
|
241
264
|
>
|
|
242
265
|
${this.facetsTemplate}
|
|
266
|
+
<div id="facets-scroll-sentinel"></div>
|
|
243
267
|
</div>
|
|
268
|
+
${this.mobileView ? nothing : html `<div id="facets-bottom-fade"></div>`}
|
|
244
269
|
</div>
|
|
245
270
|
<div id="right-column" class="column">
|
|
246
271
|
${this.sortFilterBarTemplate}
|
|
@@ -329,9 +354,28 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
329
354
|
});
|
|
330
355
|
}
|
|
331
356
|
}
|
|
332
|
-
/**
|
|
357
|
+
/**
|
|
358
|
+
* Returns a query clause identifying the currently selected title filter,
|
|
359
|
+
* e.g., `firstTitle:X`.
|
|
360
|
+
*/
|
|
361
|
+
get titleQuery() {
|
|
362
|
+
return this.selectedTitleFilter
|
|
363
|
+
? `firstTitle:${this.selectedTitleFilter}`
|
|
364
|
+
: undefined;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Returns a query clause identifying the currently selected creator filter,
|
|
368
|
+
* e.g., `firstCreator:X`.
|
|
369
|
+
*/
|
|
370
|
+
get creatorQuery() {
|
|
371
|
+
return this.selectedCreatorFilter
|
|
372
|
+
? `firstCreator:${this.selectedCreatorFilter}`
|
|
373
|
+
: undefined;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Send Analytics when sorting by title's first letter
|
|
333
377
|
* labels: 'start-<ToLetter>' | 'clear-<FromLetter>' | '<FromLetter>-<ToLetter>'
|
|
334
|
-
|
|
378
|
+
*/
|
|
335
379
|
sendFilterByTitleAnalytics(prevSelectedLetter) {
|
|
336
380
|
var _a;
|
|
337
381
|
if (!prevSelectedLetter && !this.selectedTitleFilter) {
|
|
@@ -346,14 +390,10 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
346
390
|
: `${prevSelectedLetter || 'start'}-${this.selectedTitleFilter}`,
|
|
347
391
|
});
|
|
348
392
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
? `firstTitle:${this.selectedTitleFilter}`
|
|
352
|
-
: undefined;
|
|
353
|
-
}
|
|
354
|
-
/** Send Analytics when filtering by creator's first letter
|
|
393
|
+
/**
|
|
394
|
+
* Send Analytics when filtering by creator's first letter
|
|
355
395
|
* labels: 'start-<ToLetter>' | 'clear-<FromLetter>' | '<FromLetter>-<ToLetter>'
|
|
356
|
-
|
|
396
|
+
*/
|
|
357
397
|
sendFilterByCreatorAnalytics(prevSelectedLetter) {
|
|
358
398
|
var _a;
|
|
359
399
|
if (!prevSelectedLetter && !this.selectedCreatorFilter) {
|
|
@@ -368,20 +408,19 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
368
408
|
: `${prevSelectedLetter || 'start'}-${this.selectedCreatorFilter}`,
|
|
369
409
|
});
|
|
370
410
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
: undefined;
|
|
375
|
-
}
|
|
411
|
+
/**
|
|
412
|
+
* Handler for changes to which letter is selected in the title alphabet bar.
|
|
413
|
+
*/
|
|
376
414
|
titleLetterSelected(e) {
|
|
377
415
|
this.selectedCreatorFilter = null;
|
|
378
416
|
this.selectedTitleFilter = e.detail.selectedLetter;
|
|
379
|
-
this.selectedTitleLetterChanged();
|
|
380
417
|
}
|
|
418
|
+
/**
|
|
419
|
+
* Handler for changes to which letter is selected in the creator alphabet bar.
|
|
420
|
+
*/
|
|
381
421
|
creatorLetterSelected(e) {
|
|
382
422
|
this.selectedTitleFilter = null;
|
|
383
423
|
this.selectedCreatorFilter = e.detail.selectedLetter;
|
|
384
|
-
this.selectedCreatorLetterChanged();
|
|
385
424
|
}
|
|
386
425
|
get mobileFacetsTemplate() {
|
|
387
426
|
return html `
|
|
@@ -422,13 +461,13 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
422
461
|
.selectedFacets=${this.selectedFacets}
|
|
423
462
|
.collectionNameCache=${this.collectionNameCache}
|
|
424
463
|
.showHistogramDatePicker=${this.showHistogramDatePicker}
|
|
425
|
-
.query=${this.
|
|
464
|
+
.query=${this.baseQuery}
|
|
426
465
|
.filterMap=${this.filterMap}
|
|
427
466
|
.modalManager=${this.modalManager}
|
|
428
467
|
?collapsableFacets=${this.mobileView}
|
|
429
468
|
?facetsLoading=${this.facetsLoading}
|
|
430
469
|
?fullYearAggregationLoading=${this.facetsLoading}
|
|
431
|
-
|
|
470
|
+
@facetClick=${this.facetClickHandler}
|
|
432
471
|
.analyticsHandler=${this.analyticsHandler}
|
|
433
472
|
>
|
|
434
473
|
</collection-facets>
|
|
@@ -477,6 +516,15 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
477
516
|
}
|
|
478
517
|
updated(changed) {
|
|
479
518
|
var _a;
|
|
519
|
+
if (changed.has('placeholderType') && this.placeholderType === null) {
|
|
520
|
+
if (!this.leftColIntersectionObserver) {
|
|
521
|
+
this.setupLeftColumnScrollListeners();
|
|
522
|
+
}
|
|
523
|
+
if (!this.facetsIntersectionObserver) {
|
|
524
|
+
this.setupFacetsScrollListeners();
|
|
525
|
+
}
|
|
526
|
+
this.updateLeftColumnHeight();
|
|
527
|
+
}
|
|
480
528
|
if (changed.has('displayMode') ||
|
|
481
529
|
changed.has('baseNavigationUrl') ||
|
|
482
530
|
changed.has('baseImageUrl') ||
|
|
@@ -521,11 +569,9 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
521
569
|
}
|
|
522
570
|
if (changed.has('selectedTitleFilter')) {
|
|
523
571
|
this.sendFilterByTitleAnalytics(changed.get('selectedTitleFilter'));
|
|
524
|
-
this.selectedTitleLetterChanged();
|
|
525
572
|
}
|
|
526
573
|
if (changed.has('selectedCreatorFilter')) {
|
|
527
574
|
this.sendFilterByCreatorAnalytics(changed.get('selectedCreatorFilter'));
|
|
528
|
-
this.selectedCreatorLetterChanged();
|
|
529
575
|
}
|
|
530
576
|
if (changed.has('baseQuery') ||
|
|
531
577
|
changed.has('searchType') ||
|
|
@@ -551,12 +597,16 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
551
597
|
}
|
|
552
598
|
}
|
|
553
599
|
disconnectedCallback() {
|
|
600
|
+
var _a, _b;
|
|
554
601
|
if (this.resizeObserver) {
|
|
555
602
|
this.disconnectResizeObserver(this.resizeObserver);
|
|
556
603
|
}
|
|
557
604
|
if (this.boundNavigationHandler) {
|
|
558
605
|
window.removeEventListener('popstate', this.boundNavigationHandler);
|
|
559
606
|
}
|
|
607
|
+
(_a = this.leftColIntersectionObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
608
|
+
(_b = this.facetsIntersectionObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
609
|
+
window.removeEventListener('resize', this.updateLeftColumnHeight);
|
|
560
610
|
}
|
|
561
611
|
handleResize(entry) {
|
|
562
612
|
const previousView = this.mobileView;
|
|
@@ -567,6 +617,41 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
567
617
|
this.isResizeToMobile = true;
|
|
568
618
|
}
|
|
569
619
|
}
|
|
620
|
+
// Ensure the facet sidebar remains sized correctly
|
|
621
|
+
this.updateLeftColumnHeight();
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Sets up listeners for events that may require updating the left column height.
|
|
625
|
+
*/
|
|
626
|
+
setupLeftColumnScrollListeners() {
|
|
627
|
+
var _a;
|
|
628
|
+
// We observe intersections between the left column's scroll sentinel and
|
|
629
|
+
// the viewport, so that we can ensure the left column is always sized to
|
|
630
|
+
// match the _available_ viewport height. This should generally be more
|
|
631
|
+
// performant than listening to scroll events on the page or column.
|
|
632
|
+
const leftColumnSentinel = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('#left-column-scroll-sentinel');
|
|
633
|
+
if (leftColumnSentinel) {
|
|
634
|
+
this.leftColIntersectionObserver = new IntersectionObserver(this.updateLeftColumnHeight, {
|
|
635
|
+
threshold: [...Array(101).keys()].map(n => n / 100), // Threshold every 1%
|
|
636
|
+
});
|
|
637
|
+
this.leftColIntersectionObserver.observe(leftColumnSentinel);
|
|
638
|
+
}
|
|
639
|
+
// We also listen for window resize events, as they are not always captured
|
|
640
|
+
// by the resize observer and can affect the desired height of the left column.
|
|
641
|
+
window.addEventListener('resize', this.updateLeftColumnHeight);
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Sets up listeners to control whether the facet sidebar shows its bottom fade-out.
|
|
645
|
+
* Note this uses a separate IntersectionObserver from the left column, because we
|
|
646
|
+
* don't need granular intersection thresholds for this.
|
|
647
|
+
*/
|
|
648
|
+
setupFacetsScrollListeners() {
|
|
649
|
+
var _a;
|
|
650
|
+
const facetsSentinel = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('#facets-scroll-sentinel');
|
|
651
|
+
if (facetsSentinel) {
|
|
652
|
+
this.facetsIntersectionObserver = new IntersectionObserver(this.updateFacetFadeOut);
|
|
653
|
+
this.facetsIntersectionObserver.observe(facetsSentinel);
|
|
654
|
+
}
|
|
570
655
|
}
|
|
571
656
|
emitBaseQueryChanged() {
|
|
572
657
|
this.dispatchEvent(new CustomEvent('baseQueryChanged', {
|
|
@@ -703,6 +788,11 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
703
788
|
await this.fetchPage(this.initialPageNumber);
|
|
704
789
|
this.searchResultsLoading = false;
|
|
705
790
|
}
|
|
791
|
+
/**
|
|
792
|
+
* Constructs a search service FilterMap object from the combination of
|
|
793
|
+
* all the currently-applied filters. This includes any facets, letter
|
|
794
|
+
* filters, and date range.
|
|
795
|
+
*/
|
|
706
796
|
get filterMap() {
|
|
707
797
|
const builder = new FilterMapBuilder();
|
|
708
798
|
// Add the date range, if applicable
|
|
@@ -730,20 +820,16 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
730
820
|
}
|
|
731
821
|
}
|
|
732
822
|
}
|
|
823
|
+
// Add any letter filters
|
|
824
|
+
if (this.selectedTitleFilter) {
|
|
825
|
+
builder.addFilter('firstTitle', this.selectedTitleFilter, FilterConstraint.INCLUDE);
|
|
826
|
+
}
|
|
827
|
+
if (this.selectedCreatorFilter) {
|
|
828
|
+
builder.addFilter('firstCreator', this.selectedCreatorFilter, FilterConstraint.INCLUDE);
|
|
829
|
+
}
|
|
733
830
|
const filterMap = builder.build();
|
|
734
831
|
return filterMap;
|
|
735
832
|
}
|
|
736
|
-
/** The base query joined with any title/creator letter filters */
|
|
737
|
-
get filteredQuery() {
|
|
738
|
-
if (!this.baseQuery)
|
|
739
|
-
return undefined;
|
|
740
|
-
let filteredQuery = this.baseQuery.trim();
|
|
741
|
-
const { sortFilterQueries } = this;
|
|
742
|
-
if (sortFilterQueries) {
|
|
743
|
-
filteredQuery += ` AND ${sortFilterQueries}`;
|
|
744
|
-
}
|
|
745
|
-
return filteredQuery.trim();
|
|
746
|
-
}
|
|
747
833
|
/** The full query, including year facets and date range clauses */
|
|
748
834
|
get fullQuery() {
|
|
749
835
|
if (!this.baseQuery)
|
|
@@ -761,20 +847,6 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
761
847
|
}
|
|
762
848
|
return fullQuery.trim();
|
|
763
849
|
}
|
|
764
|
-
/** The full query without any title/creator letter filters */
|
|
765
|
-
get fullQueryWithoutAlphaFilters() {
|
|
766
|
-
if (!this.baseQuery)
|
|
767
|
-
return undefined;
|
|
768
|
-
let fullQuery = this.baseQuery.trim();
|
|
769
|
-
const { facetQuery, dateRangeQueryClause } = this;
|
|
770
|
-
if (facetQuery) {
|
|
771
|
-
fullQuery += ` AND ${facetQuery}`;
|
|
772
|
-
}
|
|
773
|
-
if (dateRangeQueryClause) {
|
|
774
|
-
fullQuery += ` AND ${dateRangeQueryClause}`;
|
|
775
|
-
}
|
|
776
|
-
return fullQuery.trim();
|
|
777
|
-
}
|
|
778
850
|
/**
|
|
779
851
|
* Generates a query string for the given facets
|
|
780
852
|
*
|
|
@@ -846,35 +918,37 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
846
918
|
facetsChanged(e) {
|
|
847
919
|
this.selectedFacets = e.detail;
|
|
848
920
|
}
|
|
849
|
-
facetClickHandler(
|
|
921
|
+
facetClickHandler({ detail: { key, state: facetState, negative }, }) {
|
|
850
922
|
var _a, _b;
|
|
851
923
|
if (negative) {
|
|
852
924
|
(_a = this.analyticsHandler) === null || _a === void 0 ? void 0 : _a.sendEvent({
|
|
853
925
|
category: this.searchContext,
|
|
854
|
-
action:
|
|
926
|
+
action: facetState !== 'none'
|
|
855
927
|
? analyticsActions.facetNegativeSelected
|
|
856
928
|
: analyticsActions.facetNegativeDeselected,
|
|
857
|
-
label:
|
|
929
|
+
label: key,
|
|
858
930
|
});
|
|
859
931
|
}
|
|
860
932
|
else {
|
|
861
933
|
(_b = this.analyticsHandler) === null || _b === void 0 ? void 0 : _b.sendEvent({
|
|
862
934
|
category: this.searchContext,
|
|
863
|
-
action:
|
|
935
|
+
action: facetState !== 'none'
|
|
864
936
|
? analyticsActions.facetSelected
|
|
865
937
|
: analyticsActions.facetDeselected,
|
|
866
|
-
label:
|
|
938
|
+
label: key,
|
|
867
939
|
});
|
|
868
940
|
}
|
|
869
941
|
}
|
|
870
942
|
async fetchFacets() {
|
|
871
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
872
|
-
|
|
943
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
944
|
+
const trimmedQuery = (_a = this.baseQuery) === null || _a === void 0 ? void 0 : _a.trim();
|
|
945
|
+
if (!trimmedQuery)
|
|
873
946
|
return;
|
|
874
947
|
if (!this.searchService)
|
|
875
948
|
return;
|
|
949
|
+
const { facetFetchQueryKey } = this;
|
|
876
950
|
const params = {
|
|
877
|
-
query:
|
|
951
|
+
query: trimmedQuery,
|
|
878
952
|
rows: 0,
|
|
879
953
|
filters: this.filterMap,
|
|
880
954
|
// Fetch a few extra buckets beyond the 6 we show, in case some get suppressed
|
|
@@ -886,26 +960,32 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
886
960
|
this.facetsLoading = true;
|
|
887
961
|
const searchResponse = await this.searchService.search(params, this.searchType);
|
|
888
962
|
const success = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.success;
|
|
889
|
-
|
|
963
|
+
// This is checking to see if the query has changed since the data was fetched.
|
|
964
|
+
// If so, we just want to discard this set of aggregations because they are
|
|
965
|
+
// likely no longer valid for the newer query.
|
|
966
|
+
const queryChangedSinceFetch = facetFetchQueryKey !== this.facetFetchQueryKey;
|
|
967
|
+
if (queryChangedSinceFetch)
|
|
968
|
+
return;
|
|
890
969
|
if (!success) {
|
|
891
|
-
const errorMsg = (
|
|
892
|
-
const detailMsg = (
|
|
970
|
+
const errorMsg = (_b = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.error) === null || _b === void 0 ? void 0 : _b.message;
|
|
971
|
+
const detailMsg = (_d = (_c = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.error) === null || _c === void 0 ? void 0 : _c.details) === null || _d === void 0 ? void 0 : _d.message;
|
|
893
972
|
if (!errorMsg && !detailMsg) {
|
|
894
973
|
// @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'
|
|
895
|
-
(
|
|
974
|
+
(_f = (_e = window === null || window === void 0 ? void 0 : window.Sentry) === null || _e === void 0 ? void 0 : _e.captureMessage) === null || _f === void 0 ? void 0 : _f.call(_e, 'Missing or malformed facet response from backend', 'error');
|
|
896
975
|
}
|
|
897
976
|
return;
|
|
898
977
|
}
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
if (
|
|
905
|
-
return;
|
|
906
|
-
|
|
978
|
+
const { aggregations, collectionTitles } = success.response;
|
|
979
|
+
this.aggregations = aggregations;
|
|
980
|
+
if (collectionTitles) {
|
|
981
|
+
(_g = this.collectionNameCache) === null || _g === void 0 ? void 0 : _g.addKnownTitles(collectionTitles);
|
|
982
|
+
}
|
|
983
|
+
else if ((_h = this.aggregations) === null || _h === void 0 ? void 0 : _h.collection) {
|
|
984
|
+
(_j = this.collectionNameCache) === null || _j === void 0 ? void 0 : _j.preloadIdentifiers(this.aggregations.collection.buckets.map(bucket => { var _a; return (_a = bucket.key) === null || _a === void 0 ? void 0 : _a.toString(); }));
|
|
985
|
+
}
|
|
907
986
|
this.fullYearsHistogramAggregation =
|
|
908
|
-
(
|
|
987
|
+
(_l = (_k = success === null || success === void 0 ? void 0 : success.response) === null || _k === void 0 ? void 0 : _k.aggregations) === null || _l === void 0 ? void 0 : _l.year_histogram;
|
|
988
|
+
this.facetsLoading = false;
|
|
909
989
|
}
|
|
910
990
|
scrollToPage(pageNumber) {
|
|
911
991
|
return new Promise(resolve => {
|
|
@@ -956,8 +1036,9 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
956
1036
|
return `${this.fullQuery}-${this.searchType}`;
|
|
957
1037
|
}
|
|
958
1038
|
async fetchPage(pageNumber) {
|
|
959
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
960
|
-
|
|
1039
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
1040
|
+
const trimmedQuery = (_a = this.baseQuery) === null || _a === void 0 ? void 0 : _a.trim();
|
|
1041
|
+
if (!trimmedQuery)
|
|
961
1042
|
return;
|
|
962
1043
|
if (!this.searchService)
|
|
963
1044
|
return;
|
|
@@ -968,14 +1049,14 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
968
1049
|
return;
|
|
969
1050
|
// if a fetch is already in progress for this query and page, don't fetch again
|
|
970
1051
|
const { pageFetchQueryKey } = this;
|
|
971
|
-
const pageFetches = (
|
|
1052
|
+
const pageFetches = (_b = this.pageFetchesInProgress[pageFetchQueryKey]) !== null && _b !== void 0 ? _b : new Set();
|
|
972
1053
|
if (pageFetches.has(pageNumber))
|
|
973
1054
|
return;
|
|
974
1055
|
pageFetches.add(pageNumber);
|
|
975
1056
|
this.pageFetchesInProgress[pageFetchQueryKey] = pageFetches;
|
|
976
1057
|
const sortParams = this.sortParam ? [this.sortParam] : [];
|
|
977
1058
|
const params = {
|
|
978
|
-
query:
|
|
1059
|
+
query: trimmedQuery,
|
|
979
1060
|
page: pageNumber,
|
|
980
1061
|
rows: this.pageSize,
|
|
981
1062
|
sort: sortParams,
|
|
@@ -985,28 +1066,34 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
985
1066
|
};
|
|
986
1067
|
const searchResponse = await this.searchService.search(params, this.searchType);
|
|
987
1068
|
const success = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.success;
|
|
1069
|
+
// This is checking to see if the query has changed since the data was fetched.
|
|
1070
|
+
// If so, we just want to discard the data since there should be a new query
|
|
1071
|
+
// right behind it.
|
|
1072
|
+
const queryChangedSinceFetch = pageFetchQueryKey !== this.pageFetchQueryKey;
|
|
1073
|
+
if (queryChangedSinceFetch)
|
|
1074
|
+
return;
|
|
988
1075
|
if (!success) {
|
|
989
|
-
const errorMsg = (
|
|
990
|
-
const detailMsg = (
|
|
1076
|
+
const errorMsg = (_c = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.error) === null || _c === void 0 ? void 0 : _c.message;
|
|
1077
|
+
const detailMsg = (_e = (_d = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.error) === null || _d === void 0 ? void 0 : _d.details) === null || _e === void 0 ? void 0 : _e.message;
|
|
991
1078
|
this.queryErrorMessage = `${errorMsg !== null && errorMsg !== void 0 ? errorMsg : ''}${detailMsg ? `; ${detailMsg}` : ''}`;
|
|
992
1079
|
if (!this.queryErrorMessage) {
|
|
993
1080
|
this.queryErrorMessage = 'Missing or malformed response from backend';
|
|
994
1081
|
// @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'
|
|
995
|
-
(
|
|
1082
|
+
(_g = (_f = window === null || window === void 0 ? void 0 : window.Sentry) === null || _f === void 0 ? void 0 : _f.captureMessage) === null || _g === void 0 ? void 0 : _g.call(_f, this.queryErrorMessage, 'error');
|
|
996
1083
|
}
|
|
1084
|
+
(_h = this.pageFetchesInProgress[pageFetchQueryKey]) === null || _h === void 0 ? void 0 : _h.delete(pageNumber);
|
|
1085
|
+
this.searchResultsLoading = false;
|
|
997
1086
|
return;
|
|
998
1087
|
}
|
|
999
|
-
// This is checking to see if the query has changed since the data was fetched.
|
|
1000
|
-
// If so, we just want to discard the data since there should be a new query
|
|
1001
|
-
// right behind it.
|
|
1002
|
-
const returnedUid = success.request.clientParameters.uid;
|
|
1003
|
-
const queryChangedSinceFetch = returnedUid !== this.pageFetchQueryKey;
|
|
1004
|
-
if (queryChangedSinceFetch)
|
|
1005
|
-
return;
|
|
1006
1088
|
this.totalResults = success.response.totalResults;
|
|
1007
|
-
const { results } = success.response;
|
|
1089
|
+
const { results, collectionTitles } = success.response;
|
|
1008
1090
|
if (results && results.length > 0) {
|
|
1009
|
-
|
|
1091
|
+
if (collectionTitles) {
|
|
1092
|
+
(_j = this.collectionNameCache) === null || _j === void 0 ? void 0 : _j.addKnownTitles(collectionTitles);
|
|
1093
|
+
}
|
|
1094
|
+
else {
|
|
1095
|
+
this.preloadCollectionNames(results);
|
|
1096
|
+
}
|
|
1010
1097
|
this.updateDataSource(pageNumber, results);
|
|
1011
1098
|
}
|
|
1012
1099
|
// When we reach the end of the data, we can set the infinite scroller's
|
|
@@ -1018,7 +1105,7 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
1018
1105
|
this.infiniteScroller.itemCount = this.totalResults;
|
|
1019
1106
|
}
|
|
1020
1107
|
}
|
|
1021
|
-
(
|
|
1108
|
+
(_k = this.pageFetchesInProgress[pageFetchQueryKey]) === null || _k === void 0 ? void 0 : _k.delete(pageNumber);
|
|
1022
1109
|
this.searchResultsLoading = false;
|
|
1023
1110
|
}
|
|
1024
1111
|
preloadCollectionNames(results) {
|
|
@@ -1120,24 +1207,32 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
1120
1207
|
}
|
|
1121
1208
|
/** Fetches the aggregation buckets for the given prefix filter type. */
|
|
1122
1209
|
async fetchPrefixFilterBuckets(filterType) {
|
|
1123
|
-
var _a, _b, _c, _d, _e, _f;
|
|
1124
|
-
|
|
1210
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1211
|
+
const trimmedQuery = (_a = this.baseQuery) === null || _a === void 0 ? void 0 : _a.trim();
|
|
1212
|
+
if (!trimmedQuery)
|
|
1125
1213
|
return [];
|
|
1126
1214
|
const filterAggregationKey = prefixFilterAggregationKeys[filterType];
|
|
1127
1215
|
const params = {
|
|
1128
|
-
query:
|
|
1216
|
+
query: trimmedQuery,
|
|
1129
1217
|
rows: 0,
|
|
1218
|
+
filters: this.filterMap,
|
|
1130
1219
|
// Only fetch the firstTitle or firstCreator aggregation
|
|
1131
1220
|
aggregations: { simpleParams: [filterAggregationKey] },
|
|
1132
1221
|
// Fetch all 26 letter buckets
|
|
1133
1222
|
aggregationsSize: 26,
|
|
1134
1223
|
};
|
|
1135
|
-
const searchResponse = await ((
|
|
1136
|
-
return ((_f = (_e = (_d = (_c =
|
|
1224
|
+
const searchResponse = await ((_b = this.searchService) === null || _b === void 0 ? void 0 : _b.search(params, this.searchType));
|
|
1225
|
+
return ((_g = (_f = (_e = (_d = (_c = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.success) === null || _c === void 0 ? void 0 : _c.response) === null || _d === void 0 ? void 0 : _d.aggregations) === null || _e === void 0 ? void 0 : _e[filterAggregationKey]) === null || _f === void 0 ? void 0 : _f.buckets) !== null && _g !== void 0 ? _g : []);
|
|
1137
1226
|
}
|
|
1138
1227
|
/** Fetches and caches the prefix filter counts for the given filter type. */
|
|
1139
1228
|
async updatePrefixFilterCounts(filterType) {
|
|
1229
|
+
const { facetFetchQueryKey } = this;
|
|
1140
1230
|
const buckets = await this.fetchPrefixFilterBuckets(filterType);
|
|
1231
|
+
// Don't update the filter counts for an outdated query (if it has been changed
|
|
1232
|
+
// since we sent the request)
|
|
1233
|
+
const queryChangedSinceFetch = facetFetchQueryKey !== this.facetFetchQueryKey;
|
|
1234
|
+
if (queryChangedSinceFetch)
|
|
1235
|
+
return;
|
|
1141
1236
|
// Unpack the aggregation buckets into a simple map like { 'A': 50, 'B': 25, ... }
|
|
1142
1237
|
this.prefixFilterCountMap = { ...this.prefixFilterCountMap }; // Clone the object to trigger an update
|
|
1143
1238
|
this.prefixFilterCountMap[filterType] = buckets.reduce((acc, bucket) => {
|
|
@@ -1221,6 +1316,9 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
1221
1316
|
CollectionBrowser.styles = css `
|
|
1222
1317
|
:host {
|
|
1223
1318
|
display: block;
|
|
1319
|
+
|
|
1320
|
+
--leftColumnWidth: 18rem;
|
|
1321
|
+
--leftColumnPaddingRight: 2.5rem;
|
|
1224
1322
|
}
|
|
1225
1323
|
|
|
1226
1324
|
/**
|
|
@@ -1281,15 +1379,91 @@ CollectionBrowser.styles = css `
|
|
|
1281
1379
|
}
|
|
1282
1380
|
|
|
1283
1381
|
#left-column {
|
|
1284
|
-
width: 18rem;
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
padding-
|
|
1382
|
+
width: var(--leftColumnWidth, 18rem);
|
|
1383
|
+
/* Prevents Safari from shrinking col at first draw */
|
|
1384
|
+
min-width: var(--leftColumnWidth, 18rem);
|
|
1385
|
+
padding-top: 0;
|
|
1386
|
+
/* Reduced padding by 0.2rem to add the invisible border in the rule below */
|
|
1387
|
+
padding-right: calc(var(--leftColumnPaddingRight, 2.5rem) - 0.2rem);
|
|
1388
|
+
border-right: 0.2rem solid transparent; /* Pads to the right of the scrollbar a bit */
|
|
1288
1389
|
z-index: 1;
|
|
1289
1390
|
}
|
|
1290
1391
|
|
|
1392
|
+
.desktop #left-column {
|
|
1393
|
+
top: 0;
|
|
1394
|
+
position: sticky;
|
|
1395
|
+
height: calc(100vh - 2rem);
|
|
1396
|
+
max-height: calc(100vh - 2rem);
|
|
1397
|
+
overflow-x: hidden;
|
|
1398
|
+
overflow-y: scroll;
|
|
1399
|
+
|
|
1400
|
+
/*
|
|
1401
|
+
* Firefox doesn't support any of the -webkit-scrollbar stuff below, but
|
|
1402
|
+
* does at least give us a tiny bit of control over width & color.
|
|
1403
|
+
*/
|
|
1404
|
+
scrollbar-width: thin;
|
|
1405
|
+
scrollbar-color: transparent transparent;
|
|
1406
|
+
}
|
|
1407
|
+
.desktop #left-column:hover {
|
|
1408
|
+
scrollbar-color: auto;
|
|
1409
|
+
}
|
|
1291
1410
|
.desktop #left-column::-webkit-scrollbar {
|
|
1292
|
-
|
|
1411
|
+
appearance: none;
|
|
1412
|
+
width: 6px;
|
|
1413
|
+
}
|
|
1414
|
+
.desktop #left-column::-webkit-scrollbar-button {
|
|
1415
|
+
height: 3px;
|
|
1416
|
+
background: transparent;
|
|
1417
|
+
}
|
|
1418
|
+
.desktop #left-column::-webkit-scrollbar-corner {
|
|
1419
|
+
background: transparent;
|
|
1420
|
+
}
|
|
1421
|
+
.desktop #left-column::-webkit-scrollbar-thumb {
|
|
1422
|
+
border-radius: 4px;
|
|
1423
|
+
}
|
|
1424
|
+
.desktop #left-column:hover::-webkit-scrollbar-thumb {
|
|
1425
|
+
background: rgba(0, 0, 0, 0.15);
|
|
1426
|
+
}
|
|
1427
|
+
.desktop #left-column:hover::-webkit-scrollbar-thumb:hover {
|
|
1428
|
+
background: rgba(0, 0, 0, 0.2);
|
|
1429
|
+
}
|
|
1430
|
+
.desktop #left-column:hover::-webkit-scrollbar-thumb:active {
|
|
1431
|
+
background: rgba(0, 0, 0, 0.3);
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
#facets-bottom-fade {
|
|
1435
|
+
background: linear-gradient(
|
|
1436
|
+
to bottom,
|
|
1437
|
+
#f5f5f700 0%,
|
|
1438
|
+
#f5f5f7c0 50%,
|
|
1439
|
+
#f5f5f7 80%,
|
|
1440
|
+
#f5f5f7 100%
|
|
1441
|
+
);
|
|
1442
|
+
position: fixed;
|
|
1443
|
+
bottom: 0;
|
|
1444
|
+
height: 50px;
|
|
1445
|
+
/* Wide enough to cover the content, but leave the scrollbar uncovered */
|
|
1446
|
+
width: calc(
|
|
1447
|
+
var(--leftColumnWidth) + var(--leftColumnPaddingRight) - 10px
|
|
1448
|
+
);
|
|
1449
|
+
z-index: 2;
|
|
1450
|
+
pointer-events: none;
|
|
1451
|
+
transition: height 0.1s ease;
|
|
1452
|
+
}
|
|
1453
|
+
#facets-bottom-fade.hidden {
|
|
1454
|
+
height: 0;
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
.desktop #left-column-scroll-sentinel {
|
|
1458
|
+
width: 1px;
|
|
1459
|
+
height: 100vh;
|
|
1460
|
+
background: transparent;
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
.desktop #facets-scroll-sentinel {
|
|
1464
|
+
width: 1px;
|
|
1465
|
+
height: 1px;
|
|
1466
|
+
background: transparent;
|
|
1293
1467
|
}
|
|
1294
1468
|
|
|
1295
1469
|
.mobile #left-column {
|
|
@@ -1297,21 +1471,16 @@ CollectionBrowser.styles = css `
|
|
|
1297
1471
|
padding: 0;
|
|
1298
1472
|
}
|
|
1299
1473
|
|
|
1300
|
-
.desktop #left-column {
|
|
1301
|
-
top: 0;
|
|
1302
|
-
position: sticky;
|
|
1303
|
-
max-height: 100vh;
|
|
1304
|
-
overflow: scroll;
|
|
1305
|
-
-ms-overflow-style: none; /* hide scrollbar IE and Edge */
|
|
1306
|
-
scrollbar-width: none; /* hide scrollbar Firefox */
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1309
1474
|
#mobile-header-container {
|
|
1310
1475
|
display: flex;
|
|
1311
1476
|
justify-content: space-between;
|
|
1312
1477
|
align-items: center;
|
|
1313
1478
|
}
|
|
1314
1479
|
|
|
1480
|
+
.desktop #mobile-header-container {
|
|
1481
|
+
padding-top: 2rem;
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1315
1484
|
#facets-container {
|
|
1316
1485
|
position: relative;
|
|
1317
1486
|
max-height: 0;
|
|
@@ -1485,12 +1654,6 @@ __decorate([
|
|
|
1485
1654
|
__decorate([
|
|
1486
1655
|
property({ type: Object })
|
|
1487
1656
|
], CollectionBrowser.prototype, "resizeObserver", void 0);
|
|
1488
|
-
__decorate([
|
|
1489
|
-
property({ type: String })
|
|
1490
|
-
], CollectionBrowser.prototype, "titleQuery", void 0);
|
|
1491
|
-
__decorate([
|
|
1492
|
-
property({ type: String })
|
|
1493
|
-
], CollectionBrowser.prototype, "creatorQuery", void 0);
|
|
1494
1657
|
__decorate([
|
|
1495
1658
|
property({ type: Number })
|
|
1496
1659
|
], CollectionBrowser.prototype, "currentPage", void 0);
|
|
@@ -1575,6 +1738,9 @@ __decorate([
|
|
|
1575
1738
|
__decorate([
|
|
1576
1739
|
query('#content-container')
|
|
1577
1740
|
], CollectionBrowser.prototype, "contentContainer", void 0);
|
|
1741
|
+
__decorate([
|
|
1742
|
+
query('#left-column')
|
|
1743
|
+
], CollectionBrowser.prototype, "leftColumn", void 0);
|
|
1578
1744
|
__decorate([
|
|
1579
1745
|
property({ type: Object, attribute: false })
|
|
1580
1746
|
], CollectionBrowser.prototype, "analyticsHandler", void 0);
|