@internetarchive/collection-browser 0.4.16-alpha.9 → 0.4.16
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 +264 -110
- 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 +41 -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/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 +1 -1
- package/src/app-root.ts +12 -0
- package/src/collection-browser.ts +294 -112
- 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 +57 -12
- package/test/collection-facets/facets-template.test.ts +98 -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;
|
|
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,25 @@ 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
|
-
// This is checking to see if the query has changed since the data was fetched.
|
|
900
|
-
// If so, we just want to discard this set of aggregations because they are
|
|
901
|
-
// likely no longer valid for the newer query.
|
|
902
|
-
const returnedUid = success.request.clientParameters.uid;
|
|
903
|
-
const queryChangedSinceFetch = returnedUid !== this.facetFetchQueryKey;
|
|
904
|
-
if (queryChangedSinceFetch)
|
|
905
|
-
return;
|
|
906
978
|
this.aggregations = success === null || success === void 0 ? void 0 : success.response.aggregations;
|
|
907
979
|
this.fullYearsHistogramAggregation =
|
|
908
|
-
(
|
|
980
|
+
(_h = (_g = success === null || success === void 0 ? void 0 : success.response) === null || _g === void 0 ? void 0 : _g.aggregations) === null || _h === void 0 ? void 0 : _h.year_histogram;
|
|
981
|
+
this.facetsLoading = false;
|
|
909
982
|
}
|
|
910
983
|
scrollToPage(pageNumber) {
|
|
911
984
|
return new Promise(resolve => {
|
|
@@ -956,8 +1029,9 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
956
1029
|
return `${this.fullQuery}-${this.searchType}`;
|
|
957
1030
|
}
|
|
958
1031
|
async fetchPage(pageNumber) {
|
|
959
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
960
|
-
|
|
1032
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
1033
|
+
const trimmedQuery = (_a = this.baseQuery) === null || _a === void 0 ? void 0 : _a.trim();
|
|
1034
|
+
if (!trimmedQuery)
|
|
961
1035
|
return;
|
|
962
1036
|
if (!this.searchService)
|
|
963
1037
|
return;
|
|
@@ -968,14 +1042,14 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
968
1042
|
return;
|
|
969
1043
|
// if a fetch is already in progress for this query and page, don't fetch again
|
|
970
1044
|
const { pageFetchQueryKey } = this;
|
|
971
|
-
const pageFetches = (
|
|
1045
|
+
const pageFetches = (_b = this.pageFetchesInProgress[pageFetchQueryKey]) !== null && _b !== void 0 ? _b : new Set();
|
|
972
1046
|
if (pageFetches.has(pageNumber))
|
|
973
1047
|
return;
|
|
974
1048
|
pageFetches.add(pageNumber);
|
|
975
1049
|
this.pageFetchesInProgress[pageFetchQueryKey] = pageFetches;
|
|
976
1050
|
const sortParams = this.sortParam ? [this.sortParam] : [];
|
|
977
1051
|
const params = {
|
|
978
|
-
query:
|
|
1052
|
+
query: trimmedQuery,
|
|
979
1053
|
page: pageNumber,
|
|
980
1054
|
rows: this.pageSize,
|
|
981
1055
|
sort: sortParams,
|
|
@@ -985,24 +1059,25 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
985
1059
|
};
|
|
986
1060
|
const searchResponse = await this.searchService.search(params, this.searchType);
|
|
987
1061
|
const success = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.success;
|
|
1062
|
+
// This is checking to see if the query has changed since the data was fetched.
|
|
1063
|
+
// If so, we just want to discard the data since there should be a new query
|
|
1064
|
+
// right behind it.
|
|
1065
|
+
const queryChangedSinceFetch = pageFetchQueryKey !== this.pageFetchQueryKey;
|
|
1066
|
+
if (queryChangedSinceFetch)
|
|
1067
|
+
return;
|
|
988
1068
|
if (!success) {
|
|
989
|
-
const errorMsg = (
|
|
990
|
-
const detailMsg = (
|
|
1069
|
+
const errorMsg = (_c = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.error) === null || _c === void 0 ? void 0 : _c.message;
|
|
1070
|
+
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
1071
|
this.queryErrorMessage = `${errorMsg !== null && errorMsg !== void 0 ? errorMsg : ''}${detailMsg ? `; ${detailMsg}` : ''}`;
|
|
992
1072
|
if (!this.queryErrorMessage) {
|
|
993
1073
|
this.queryErrorMessage = 'Missing or malformed response from backend';
|
|
994
1074
|
// @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'
|
|
995
|
-
(
|
|
1075
|
+
(_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
1076
|
}
|
|
1077
|
+
(_h = this.pageFetchesInProgress[pageFetchQueryKey]) === null || _h === void 0 ? void 0 : _h.delete(pageNumber);
|
|
1078
|
+
this.searchResultsLoading = false;
|
|
997
1079
|
return;
|
|
998
1080
|
}
|
|
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
1081
|
this.totalResults = success.response.totalResults;
|
|
1007
1082
|
const { results } = success.response;
|
|
1008
1083
|
if (results && results.length > 0) {
|
|
@@ -1018,7 +1093,7 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
1018
1093
|
this.infiniteScroller.itemCount = this.totalResults;
|
|
1019
1094
|
}
|
|
1020
1095
|
}
|
|
1021
|
-
(
|
|
1096
|
+
(_j = this.pageFetchesInProgress[pageFetchQueryKey]) === null || _j === void 0 ? void 0 : _j.delete(pageNumber);
|
|
1022
1097
|
this.searchResultsLoading = false;
|
|
1023
1098
|
}
|
|
1024
1099
|
preloadCollectionNames(results) {
|
|
@@ -1120,24 +1195,32 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
1120
1195
|
}
|
|
1121
1196
|
/** Fetches the aggregation buckets for the given prefix filter type. */
|
|
1122
1197
|
async fetchPrefixFilterBuckets(filterType) {
|
|
1123
|
-
var _a, _b, _c, _d, _e, _f;
|
|
1124
|
-
|
|
1198
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1199
|
+
const trimmedQuery = (_a = this.baseQuery) === null || _a === void 0 ? void 0 : _a.trim();
|
|
1200
|
+
if (!trimmedQuery)
|
|
1125
1201
|
return [];
|
|
1126
1202
|
const filterAggregationKey = prefixFilterAggregationKeys[filterType];
|
|
1127
1203
|
const params = {
|
|
1128
|
-
query:
|
|
1204
|
+
query: trimmedQuery,
|
|
1129
1205
|
rows: 0,
|
|
1206
|
+
filters: this.filterMap,
|
|
1130
1207
|
// Only fetch the firstTitle or firstCreator aggregation
|
|
1131
1208
|
aggregations: { simpleParams: [filterAggregationKey] },
|
|
1132
1209
|
// Fetch all 26 letter buckets
|
|
1133
1210
|
aggregationsSize: 26,
|
|
1134
1211
|
};
|
|
1135
|
-
const searchResponse = await ((
|
|
1136
|
-
return ((_f = (_e = (_d = (_c =
|
|
1212
|
+
const searchResponse = await ((_b = this.searchService) === null || _b === void 0 ? void 0 : _b.search(params, this.searchType));
|
|
1213
|
+
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
1214
|
}
|
|
1138
1215
|
/** Fetches and caches the prefix filter counts for the given filter type. */
|
|
1139
1216
|
async updatePrefixFilterCounts(filterType) {
|
|
1217
|
+
const { facetFetchQueryKey } = this;
|
|
1140
1218
|
const buckets = await this.fetchPrefixFilterBuckets(filterType);
|
|
1219
|
+
// Don't update the filter counts for an outdated query (if it has been changed
|
|
1220
|
+
// since we sent the request)
|
|
1221
|
+
const queryChangedSinceFetch = facetFetchQueryKey !== this.facetFetchQueryKey;
|
|
1222
|
+
if (queryChangedSinceFetch)
|
|
1223
|
+
return;
|
|
1141
1224
|
// Unpack the aggregation buckets into a simple map like { 'A': 50, 'B': 25, ... }
|
|
1142
1225
|
this.prefixFilterCountMap = { ...this.prefixFilterCountMap }; // Clone the object to trigger an update
|
|
1143
1226
|
this.prefixFilterCountMap[filterType] = buckets.reduce((acc, bucket) => {
|
|
@@ -1221,6 +1304,9 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
1221
1304
|
CollectionBrowser.styles = css `
|
|
1222
1305
|
:host {
|
|
1223
1306
|
display: block;
|
|
1307
|
+
|
|
1308
|
+
--leftColumnWidth: 18rem;
|
|
1309
|
+
--leftColumnPaddingRight: 2.5rem;
|
|
1224
1310
|
}
|
|
1225
1311
|
|
|
1226
1312
|
/**
|
|
@@ -1281,15 +1367,91 @@ CollectionBrowser.styles = css `
|
|
|
1281
1367
|
}
|
|
1282
1368
|
|
|
1283
1369
|
#left-column {
|
|
1284
|
-
width: 18rem;
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
padding-
|
|
1370
|
+
width: var(--leftColumnWidth, 18rem);
|
|
1371
|
+
/* Prevents Safari from shrinking col at first draw */
|
|
1372
|
+
min-width: var(--leftColumnWidth, 18rem);
|
|
1373
|
+
padding-top: 0;
|
|
1374
|
+
/* Reduced padding by 0.2rem to add the invisible border in the rule below */
|
|
1375
|
+
padding-right: calc(var(--leftColumnPaddingRight, 2.5rem) - 0.2rem);
|
|
1376
|
+
border-right: 0.2rem solid transparent; /* Pads to the right of the scrollbar a bit */
|
|
1288
1377
|
z-index: 1;
|
|
1289
1378
|
}
|
|
1290
1379
|
|
|
1380
|
+
.desktop #left-column {
|
|
1381
|
+
top: 0;
|
|
1382
|
+
position: sticky;
|
|
1383
|
+
height: calc(100vh - 2rem);
|
|
1384
|
+
max-height: calc(100vh - 2rem);
|
|
1385
|
+
overflow-x: hidden;
|
|
1386
|
+
overflow-y: scroll;
|
|
1387
|
+
|
|
1388
|
+
/*
|
|
1389
|
+
* Firefox doesn't support any of the -webkit-scrollbar stuff below, but
|
|
1390
|
+
* does at least give us a tiny bit of control over width & color.
|
|
1391
|
+
*/
|
|
1392
|
+
scrollbar-width: thin;
|
|
1393
|
+
scrollbar-color: transparent transparent;
|
|
1394
|
+
}
|
|
1395
|
+
.desktop #left-column:hover {
|
|
1396
|
+
scrollbar-color: auto;
|
|
1397
|
+
}
|
|
1291
1398
|
.desktop #left-column::-webkit-scrollbar {
|
|
1292
|
-
|
|
1399
|
+
appearance: none;
|
|
1400
|
+
width: 6px;
|
|
1401
|
+
}
|
|
1402
|
+
.desktop #left-column::-webkit-scrollbar-button {
|
|
1403
|
+
height: 3px;
|
|
1404
|
+
background: transparent;
|
|
1405
|
+
}
|
|
1406
|
+
.desktop #left-column::-webkit-scrollbar-corner {
|
|
1407
|
+
background: transparent;
|
|
1408
|
+
}
|
|
1409
|
+
.desktop #left-column::-webkit-scrollbar-thumb {
|
|
1410
|
+
border-radius: 4px;
|
|
1411
|
+
}
|
|
1412
|
+
.desktop #left-column:hover::-webkit-scrollbar-thumb {
|
|
1413
|
+
background: rgba(0, 0, 0, 0.15);
|
|
1414
|
+
}
|
|
1415
|
+
.desktop #left-column:hover::-webkit-scrollbar-thumb:hover {
|
|
1416
|
+
background: rgba(0, 0, 0, 0.2);
|
|
1417
|
+
}
|
|
1418
|
+
.desktop #left-column:hover::-webkit-scrollbar-thumb:active {
|
|
1419
|
+
background: rgba(0, 0, 0, 0.3);
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
#facets-bottom-fade {
|
|
1423
|
+
background: linear-gradient(
|
|
1424
|
+
to bottom,
|
|
1425
|
+
#f5f5f700 0%,
|
|
1426
|
+
#f5f5f7c0 50%,
|
|
1427
|
+
#f5f5f7 80%,
|
|
1428
|
+
#f5f5f7 100%
|
|
1429
|
+
);
|
|
1430
|
+
position: fixed;
|
|
1431
|
+
bottom: 0;
|
|
1432
|
+
height: 50px;
|
|
1433
|
+
/* Wide enough to cover the content, but leave the scrollbar uncovered */
|
|
1434
|
+
width: calc(
|
|
1435
|
+
var(--leftColumnWidth) + var(--leftColumnPaddingRight) - 10px
|
|
1436
|
+
);
|
|
1437
|
+
z-index: 2;
|
|
1438
|
+
pointer-events: none;
|
|
1439
|
+
transition: height 0.1s ease;
|
|
1440
|
+
}
|
|
1441
|
+
#facets-bottom-fade.hidden {
|
|
1442
|
+
height: 0;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
.desktop #left-column-scroll-sentinel {
|
|
1446
|
+
width: 1px;
|
|
1447
|
+
height: 100vh;
|
|
1448
|
+
background: transparent;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
.desktop #facets-scroll-sentinel {
|
|
1452
|
+
width: 1px;
|
|
1453
|
+
height: 1px;
|
|
1454
|
+
background: transparent;
|
|
1293
1455
|
}
|
|
1294
1456
|
|
|
1295
1457
|
.mobile #left-column {
|
|
@@ -1297,21 +1459,16 @@ CollectionBrowser.styles = css `
|
|
|
1297
1459
|
padding: 0;
|
|
1298
1460
|
}
|
|
1299
1461
|
|
|
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
1462
|
#mobile-header-container {
|
|
1310
1463
|
display: flex;
|
|
1311
1464
|
justify-content: space-between;
|
|
1312
1465
|
align-items: center;
|
|
1313
1466
|
}
|
|
1314
1467
|
|
|
1468
|
+
.desktop #mobile-header-container {
|
|
1469
|
+
padding-top: 2rem;
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1315
1472
|
#facets-container {
|
|
1316
1473
|
position: relative;
|
|
1317
1474
|
max-height: 0;
|
|
@@ -1485,12 +1642,6 @@ __decorate([
|
|
|
1485
1642
|
__decorate([
|
|
1486
1643
|
property({ type: Object })
|
|
1487
1644
|
], 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
1645
|
__decorate([
|
|
1495
1646
|
property({ type: Number })
|
|
1496
1647
|
], CollectionBrowser.prototype, "currentPage", void 0);
|
|
@@ -1575,6 +1726,9 @@ __decorate([
|
|
|
1575
1726
|
__decorate([
|
|
1576
1727
|
query('#content-container')
|
|
1577
1728
|
], CollectionBrowser.prototype, "contentContainer", void 0);
|
|
1729
|
+
__decorate([
|
|
1730
|
+
query('#left-column')
|
|
1731
|
+
], CollectionBrowser.prototype, "leftColumn", void 0);
|
|
1578
1732
|
__decorate([
|
|
1579
1733
|
property({ type: Object, attribute: false })
|
|
1580
1734
|
], CollectionBrowser.prototype, "analyticsHandler", void 0);
|