@internetarchive/collection-browser 0.4.0 → 0.4.2
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 +1 -1
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/collection-browser.d.ts +40 -3
- package/dist/src/collection-browser.js +214 -58
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/more-facets-content.d.ts +3 -2
- package/dist/src/collection-facets/more-facets-content.js +6 -2
- package/dist/src/collection-facets/more-facets-content.js.map +1 -1
- package/dist/src/collection-facets.d.ts +3 -2
- package/dist/src/collection-facets.js +6 -2
- package/dist/src/collection-facets.js.map +1 -1
- package/dist/src/models.d.ts +9 -0
- package/dist/src/models.js +8 -0
- package/dist/src/models.js.map +1 -1
- package/dist/src/restoration-state-handler.d.ts +0 -1
- package/dist/src/restoration-state-handler.js +4 -4
- package/dist/src/restoration-state-handler.js.map +1 -1
- package/dist/src/sort-filter-bar/alpha-bar.d.ts +3 -0
- package/dist/src/sort-filter-bar/alpha-bar.js +32 -13
- package/dist/src/sort-filter-bar/alpha-bar.js.map +1 -1
- package/dist/src/sort-filter-bar/sort-filter-bar.d.ts +2 -1
- package/dist/src/sort-filter-bar/sort-filter-bar.js +7 -0
- package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
- package/dist/src/tiles/image-block.js +0 -1
- package/dist/src/tiles/image-block.js.map +1 -1
- package/dist/test/collection-browser.test.js +81 -9
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/collection-facets/more-facets-content.test.js +2 -2
- package/dist/test/collection-facets/more-facets-content.test.js.map +1 -1
- package/dist/test/mocks/mock-search-responses.d.ts +2 -0
- package/dist/test/mocks/mock-search-responses.js +70 -0
- package/dist/test/mocks/mock-search-responses.js.map +1 -1
- package/dist/test/mocks/mock-search-service.js +5 -1
- package/dist/test/mocks/mock-search-service.js.map +1 -1
- package/dist/test/restoration-state-handler.test.js +0 -1
- package/dist/test/restoration-state-handler.test.js.map +1 -1
- package/dist/test/sort-filter-bar/alpha-bar.test.d.ts +1 -0
- package/dist/test/sort-filter-bar/alpha-bar.test.js +44 -0
- package/dist/test/sort-filter-bar/alpha-bar.test.js.map +1 -0
- package/dist/test/sort-filter-bar/sort-filter-bar.test.js +32 -0
- package/dist/test/sort-filter-bar/sort-filter-bar.test.js.map +1 -1
- package/package.json +3 -3
- package/src/app-root.ts +1 -1
- package/src/collection-browser.ts +273 -57
- package/src/collection-facets/more-facets-content.ts +6 -2
- package/src/collection-facets.ts +6 -2
- package/src/models.ts +15 -0
- package/src/restoration-state-handler.ts +7 -5
- package/src/sort-filter-bar/alpha-bar.ts +26 -9
- package/src/sort-filter-bar/sort-filter-bar.ts +9 -0
- package/src/tiles/image-block.ts +0 -1
- package/test/collection-browser.test.ts +90 -10
- package/test/collection-facets/more-facets-content.test.ts +2 -2
- package/test/mocks/mock-search-responses.ts +78 -0
- package/test/mocks/mock-search-service.ts +6 -0
- package/test/restoration-state-handler.test.ts +0 -3
- package/test/sort-filter-bar/alpha-bar.test.ts +52 -0
- package/test/sort-filter-bar/sort-filter-bar.test.ts +44 -0
|
@@ -3,7 +3,7 @@ import { __decorate } from "tslib";
|
|
|
3
3
|
import { html, css, LitElement, nothing, } from 'lit';
|
|
4
4
|
import { customElement, property, query, state } from 'lit/decorators.js';
|
|
5
5
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
6
|
-
import { SearchType, } from '@internetarchive/search-service';
|
|
6
|
+
import { FilterConstraint, FilterMapBuilder, SearchType, } from '@internetarchive/search-service';
|
|
7
7
|
import '@internetarchive/infinite-scroller';
|
|
8
8
|
import './tiles/tile-dispatcher';
|
|
9
9
|
import './tiles/collection-browser-loading-tile';
|
|
@@ -11,7 +11,7 @@ import './sort-filter-bar/sort-filter-bar';
|
|
|
11
11
|
import './collection-facets';
|
|
12
12
|
import './circular-activity-indicator';
|
|
13
13
|
import './sort-filter-bar/sort-filter-bar';
|
|
14
|
-
import { SortField, SortFieldToMetadataField, defaultSelectedFacets, } from './models';
|
|
14
|
+
import { SortField, SortFieldToMetadataField, defaultSelectedFacets, prefixFilterAggregationKeys, } from './models';
|
|
15
15
|
import { RestorationStateHandler, } from './restoration-state-handler';
|
|
16
16
|
import chevronIcon from './assets/img/icons/chevron';
|
|
17
17
|
import { LanguageCodeHandler } from './language-code-handler/language-code-handler';
|
|
@@ -59,6 +59,7 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
59
59
|
this.mobileView = false;
|
|
60
60
|
this.mobileFacetsVisible = false;
|
|
61
61
|
this.placeholderType = null;
|
|
62
|
+
this.prefixFilterCountMap = {};
|
|
62
63
|
this.languageCodeHandler = new LanguageCodeHandler();
|
|
63
64
|
/**
|
|
64
65
|
* When we're animated scrolling to the page, we don't want to fetch
|
|
@@ -183,6 +184,10 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
183
184
|
`;
|
|
184
185
|
}
|
|
185
186
|
get collectionBrowserTemplate() {
|
|
187
|
+
var _a;
|
|
188
|
+
const shouldShowSearching = this.searchResultsLoading || this.totalResults === undefined;
|
|
189
|
+
const resultsCount = (_a = this.totalResults) === null || _a === void 0 ? void 0 : _a.toLocaleString();
|
|
190
|
+
const resultsLabel = this.totalResults === 1 ? 'Result' : 'Results';
|
|
186
191
|
return html `<div
|
|
187
192
|
id="left-column"
|
|
188
193
|
class="column${this.isResizeToMobile ? ' preload' : ''}"
|
|
@@ -191,12 +196,10 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
191
196
|
${this.mobileView ? this.mobileFacetsTemplate : nothing}
|
|
192
197
|
<div id="results-total">
|
|
193
198
|
<span id="big-results-count">
|
|
194
|
-
${
|
|
195
|
-
? this.totalResults.toLocaleString()
|
|
196
|
-
: '-'}
|
|
199
|
+
${shouldShowSearching ? html `Searching…` : resultsCount}
|
|
197
200
|
</span>
|
|
198
201
|
<span id="big-results-label">
|
|
199
|
-
${
|
|
202
|
+
${shouldShowSearching ? nothing : resultsLabel}
|
|
200
203
|
</span>
|
|
201
204
|
</div>
|
|
202
205
|
</div>
|
|
@@ -234,6 +237,7 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
234
237
|
.displayMode=${this.displayMode}
|
|
235
238
|
.selectedTitleFilter=${this.selectedTitleFilter}
|
|
236
239
|
.selectedCreatorFilter=${this.selectedCreatorFilter}
|
|
240
|
+
.prefixFilterCountMap=${this.prefixFilterCountMap}
|
|
237
241
|
.resizeObserver=${this.resizeObserver}
|
|
238
242
|
@sortChanged=${this.userChangedSort}
|
|
239
243
|
@displayModeChanged=${this.displayModeChanged}
|
|
@@ -271,6 +275,8 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
271
275
|
if (!sortField)
|
|
272
276
|
return;
|
|
273
277
|
this.sortParam = { field: sortField, direction: this.sortDirection };
|
|
278
|
+
// Lazy-load the alphabet counts for title/creator sort bar as needed
|
|
279
|
+
this.updatePrefixFiltersForCurrentSort();
|
|
274
280
|
}
|
|
275
281
|
displayModeChanged(e) {
|
|
276
282
|
var _a;
|
|
@@ -375,7 +381,8 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
375
381
|
.collectionNameCache=${this.collectionNameCache}
|
|
376
382
|
.languageCodeHandler=${this.languageCodeHandler}
|
|
377
383
|
.showHistogramDatePicker=${this.showHistogramDatePicker}
|
|
378
|
-
.
|
|
384
|
+
.query=${this.filteredQuery}
|
|
385
|
+
.filterMap=${this.filterMap}
|
|
379
386
|
.modalManager=${this.modalManager}
|
|
380
387
|
?collapsableFacets=${this.mobileView}
|
|
381
388
|
?facetsLoading=${this.facetDataLoading}
|
|
@@ -407,33 +414,21 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
407
414
|
</div>
|
|
408
415
|
`;
|
|
409
416
|
}
|
|
410
|
-
get queryDebuggingTemplate() {
|
|
411
|
-
var _a, _b;
|
|
412
|
-
return html `
|
|
413
|
-
<div>
|
|
414
|
-
<ul>
|
|
415
|
-
<li>Base Query: ${this.baseQuery}</li>
|
|
416
|
-
<li>Facet Query: ${this.facetQuery}</li>
|
|
417
|
-
<li>Sort Filter Query: ${this.sortFilterQueries}</li>
|
|
418
|
-
<li>Date Range Query: ${this.dateRangeQueryClause}</li>
|
|
419
|
-
<li>Sort: ${(_a = this.sortParam) === null || _a === void 0 ? void 0 : _a.field} ${(_b = this.sortParam) === null || _b === void 0 ? void 0 : _b.direction}</li>
|
|
420
|
-
<li>Full Query: ${this.fullQuery}</li>
|
|
421
|
-
</ul>
|
|
422
|
-
</div>
|
|
423
|
-
`;
|
|
424
|
-
}
|
|
425
417
|
histogramDateRangeUpdated(e) {
|
|
426
418
|
var _a;
|
|
427
419
|
const { minDate, maxDate } = e.detail;
|
|
428
420
|
[this.minSelectedDate, this.maxSelectedDate] = [minDate, maxDate];
|
|
429
|
-
this.
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
421
|
+
(_a = this.analyticsHandler) === null || _a === void 0 ? void 0 : _a.sendEvent({
|
|
422
|
+
category: this.searchContext,
|
|
423
|
+
action: analyticsActions.histogramChanged,
|
|
424
|
+
label: this.dateRangeQueryClause,
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
get dateRangeQueryClause() {
|
|
428
|
+
if (!this.minSelectedDate || !this.maxSelectedDate) {
|
|
429
|
+
return undefined;
|
|
436
430
|
}
|
|
431
|
+
return `year:[${this.minSelectedDate} TO ${this.maxSelectedDate}]`;
|
|
437
432
|
}
|
|
438
433
|
firstUpdated() {
|
|
439
434
|
this.setupStateRestorationObserver();
|
|
@@ -459,12 +454,19 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
459
454
|
if (changed.has('baseQuery') ||
|
|
460
455
|
changed.has('titleQuery') ||
|
|
461
456
|
changed.has('creatorQuery') ||
|
|
462
|
-
changed.has('
|
|
457
|
+
changed.has('minSelectedDate') ||
|
|
458
|
+
changed.has('maxSelectedDate') ||
|
|
463
459
|
changed.has('sortParam') ||
|
|
464
460
|
changed.has('selectedFacets') ||
|
|
465
461
|
changed.has('searchService')) {
|
|
466
462
|
this.handleQueryChange();
|
|
467
463
|
}
|
|
464
|
+
if (changed.has('baseQuery') ||
|
|
465
|
+
changed.has('minSelectedDate') ||
|
|
466
|
+
changed.has('maxSelectedDate') ||
|
|
467
|
+
changed.has('selectedFacets')) {
|
|
468
|
+
this.refreshLetterCounts();
|
|
469
|
+
}
|
|
468
470
|
if (changed.has('selectedSort') || changed.has('sortDirection')) {
|
|
469
471
|
const prevSortDirection = changed.get('sortDirection');
|
|
470
472
|
this.sendSortByAnalytics(prevSortDirection);
|
|
@@ -566,6 +568,9 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
566
568
|
return;
|
|
567
569
|
this.previousQueryKey = this.pageFetchQueryKey;
|
|
568
570
|
this.dataSource = {};
|
|
571
|
+
this.totalResults = undefined;
|
|
572
|
+
this.aggregations = undefined;
|
|
573
|
+
this.fullYearsHistogramAggregation = undefined;
|
|
569
574
|
this.pageFetchesInProgress = {};
|
|
570
575
|
this.endOfDataReached = false;
|
|
571
576
|
this.pagesToRender = this.initialPageNumber;
|
|
@@ -614,7 +619,6 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
614
619
|
this.baseQuery = restorationState.baseQuery;
|
|
615
620
|
this.titleQuery = restorationState.titleQuery;
|
|
616
621
|
this.creatorQuery = restorationState.creatorQuery;
|
|
617
|
-
this.dateRangeQueryClause = restorationState.dateRangeQueryClause;
|
|
618
622
|
this.sortParam = (_e = restorationState.sortParam) !== null && _e !== void 0 ? _e : null;
|
|
619
623
|
this.currentPage = (_f = restorationState.currentPage) !== null && _f !== void 0 ? _f : 1;
|
|
620
624
|
this.minSelectedDate = restorationState.minSelectedDate;
|
|
@@ -634,7 +638,6 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
634
638
|
selectedFacets: (_c = this.selectedFacets) !== null && _c !== void 0 ? _c : defaultSelectedFacets,
|
|
635
639
|
baseQuery: this.baseQuery,
|
|
636
640
|
currentPage: this.currentPage,
|
|
637
|
-
dateRangeQueryClause: this.dateRangeQueryClause,
|
|
638
641
|
titleQuery: this.titleQuery,
|
|
639
642
|
creatorQuery: this.creatorQuery,
|
|
640
643
|
minSelectedDate: this.minSelectedDate,
|
|
@@ -649,6 +652,64 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
649
652
|
await this.fetchPage(this.initialPageNumber);
|
|
650
653
|
this.searchResultsLoading = false;
|
|
651
654
|
}
|
|
655
|
+
get filterMap() {
|
|
656
|
+
const builder = new FilterMapBuilder();
|
|
657
|
+
// Add the date range, if applicable
|
|
658
|
+
if (this.minSelectedDate) {
|
|
659
|
+
builder.addFilter('year', this.minSelectedDate, FilterConstraint.GREATER_OR_EQUAL);
|
|
660
|
+
}
|
|
661
|
+
if (this.maxSelectedDate) {
|
|
662
|
+
builder.addFilter('year', this.maxSelectedDate, FilterConstraint.LESS_OR_EQUAL);
|
|
663
|
+
}
|
|
664
|
+
// Add any selected facets
|
|
665
|
+
if (this.selectedFacets) {
|
|
666
|
+
for (const [facetName, facetValues] of Object.entries(this.selectedFacets)) {
|
|
667
|
+
const { name, values } = this.prepareFacetForFetch(facetName, facetValues);
|
|
668
|
+
for (const [value, bucket] of Object.entries(values)) {
|
|
669
|
+
let constraint;
|
|
670
|
+
if (bucket.state === 'selected') {
|
|
671
|
+
constraint = FilterConstraint.INCLUDE;
|
|
672
|
+
}
|
|
673
|
+
else if (bucket.state === 'hidden') {
|
|
674
|
+
constraint = FilterConstraint.EXCLUDE;
|
|
675
|
+
}
|
|
676
|
+
if (constraint) {
|
|
677
|
+
builder.addFilter(name, value, constraint);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
const filterMap = builder.build();
|
|
683
|
+
// TEMP: At present, the backend search engine incorrectly returns 0 results if
|
|
684
|
+
// the _first_ language filter contains a space, so let's try to avoid that if possible.
|
|
685
|
+
if (filterMap.language) {
|
|
686
|
+
for (const [value, constraint] of Object.entries(filterMap.language)) {
|
|
687
|
+
if (value.includes(' ')) {
|
|
688
|
+
// Delete and re-add this filter to make it the last one on the parent object
|
|
689
|
+
// (Technically this isn't in the standard, but most browser impls output
|
|
690
|
+
// object keys in the order they were added.)
|
|
691
|
+
delete filterMap.language[value];
|
|
692
|
+
filterMap.language[value] = constraint;
|
|
693
|
+
}
|
|
694
|
+
else {
|
|
695
|
+
// As soon as we reach one without a space, we're done
|
|
696
|
+
break;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
return filterMap;
|
|
701
|
+
}
|
|
702
|
+
/** The base query joined with any title/creator letter filters */
|
|
703
|
+
get filteredQuery() {
|
|
704
|
+
if (!this.baseQuery)
|
|
705
|
+
return undefined;
|
|
706
|
+
let filteredQuery = this.baseQuery;
|
|
707
|
+
const { sortFilterQueries } = this;
|
|
708
|
+
if (sortFilterQueries) {
|
|
709
|
+
filteredQuery += ` AND ${sortFilterQueries}`;
|
|
710
|
+
}
|
|
711
|
+
return filteredQuery;
|
|
712
|
+
}
|
|
652
713
|
/** The full query, including year facets and date range clauses */
|
|
653
714
|
get fullQuery() {
|
|
654
715
|
if (!this.baseQuery)
|
|
@@ -666,6 +727,20 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
666
727
|
}
|
|
667
728
|
return fullQuery;
|
|
668
729
|
}
|
|
730
|
+
/** The full query without any title/creator letter filters */
|
|
731
|
+
get fullQueryWithoutAlphaFilters() {
|
|
732
|
+
if (!this.baseQuery)
|
|
733
|
+
return undefined;
|
|
734
|
+
let fullQuery = this.baseQuery;
|
|
735
|
+
const { facetQuery, dateRangeQueryClause } = this;
|
|
736
|
+
if (facetQuery) {
|
|
737
|
+
fullQuery += ` AND ${facetQuery}`;
|
|
738
|
+
}
|
|
739
|
+
if (dateRangeQueryClause) {
|
|
740
|
+
fullQuery += ` AND ${dateRangeQueryClause}`;
|
|
741
|
+
}
|
|
742
|
+
return fullQuery;
|
|
743
|
+
}
|
|
669
744
|
/** The full query without any year facets or date range clauses */
|
|
670
745
|
get fullQueryWithoutDates() {
|
|
671
746
|
if (!this.baseQuery)
|
|
@@ -722,26 +797,46 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
722
797
|
* @param facetValues The facet buckets, mapped by their keys
|
|
723
798
|
*/
|
|
724
799
|
buildFacetClause(facetName, facetValues) {
|
|
725
|
-
const
|
|
800
|
+
const { name: facetQueryName, values } = this.prepareFacetForFetch(facetName, facetValues);
|
|
801
|
+
const facetEntries = Object.entries(values);
|
|
726
802
|
if (facetEntries.length === 0)
|
|
727
803
|
return '';
|
|
728
|
-
const facetQueryName = facetName === 'lending' ? 'lending___status' : facetName;
|
|
729
804
|
const facetValuesArray = [];
|
|
730
805
|
for (const [key, facetData] of facetEntries) {
|
|
731
806
|
const plusMinusPrefix = facetData.state === 'hidden' ? '-' : '';
|
|
732
|
-
|
|
733
|
-
const languages = this.languageCodeHandler.getCodeArrayFromCodeString(key);
|
|
734
|
-
for (const language of languages) {
|
|
735
|
-
facetValuesArray.push(`${plusMinusPrefix}"${language}"`);
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
else {
|
|
739
|
-
facetValuesArray.push(`${plusMinusPrefix}"${key}"`);
|
|
740
|
-
}
|
|
807
|
+
facetValuesArray.push(`${plusMinusPrefix}"${key}"`);
|
|
741
808
|
}
|
|
742
809
|
const valueQuery = facetValuesArray.join(` OR `);
|
|
743
810
|
return `${facetQueryName}:(${valueQuery})`;
|
|
744
811
|
}
|
|
812
|
+
/**
|
|
813
|
+
* Handles some special pre-request normalization steps for certain facet types
|
|
814
|
+
* that require them.
|
|
815
|
+
*
|
|
816
|
+
* @param facetName The name of the facet type (e.g., 'language')
|
|
817
|
+
* @param facetValues An array of values for that facet type
|
|
818
|
+
*/
|
|
819
|
+
prepareFacetForFetch(facetName, facetValues) {
|
|
820
|
+
let [normalizedName, normalizedValues] = [facetName, facetValues];
|
|
821
|
+
// The full "search engine" name of the lending field is "lending___status"
|
|
822
|
+
if (facetName === 'lending') {
|
|
823
|
+
normalizedName = 'lending___status';
|
|
824
|
+
}
|
|
825
|
+
// Language codes like "en-US|en-GB|en" need to be broken apart into individual values
|
|
826
|
+
if (facetName === 'language') {
|
|
827
|
+
normalizedValues = {};
|
|
828
|
+
for (const [facetValue, facetData] of Object.entries(facetValues)) {
|
|
829
|
+
const languages = this.languageCodeHandler.getCodeArrayFromCodeString(facetValue);
|
|
830
|
+
for (const lang of languages) {
|
|
831
|
+
normalizedValues[lang] = { ...facetData };
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
return {
|
|
836
|
+
name: normalizedName,
|
|
837
|
+
values: normalizedValues,
|
|
838
|
+
};
|
|
839
|
+
}
|
|
745
840
|
/**
|
|
746
841
|
* Takes an array of facet clauses, and combines them into a
|
|
747
842
|
* full AND-joined facet query string. Empty clauses are ignored.
|
|
@@ -778,11 +873,12 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
778
873
|
}
|
|
779
874
|
async fetchFacets() {
|
|
780
875
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
781
|
-
if (!this.
|
|
876
|
+
if (!this.filteredQuery)
|
|
782
877
|
return;
|
|
783
878
|
const params = {
|
|
784
|
-
query: this.
|
|
879
|
+
query: this.filteredQuery,
|
|
785
880
|
rows: 0,
|
|
881
|
+
filters: this.filterMap,
|
|
786
882
|
// Fetch a few extra buckets beyond the 6 we show, in case some get suppressed
|
|
787
883
|
aggregationsSize: 10,
|
|
788
884
|
// Note: we don't need an aggregations param to fetch the default aggregations from the PPS.
|
|
@@ -869,7 +965,14 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
869
965
|
}, 0);
|
|
870
966
|
}
|
|
871
967
|
/**
|
|
872
|
-
* The query key is a string that uniquely identifies the current
|
|
968
|
+
* The query key is a string that uniquely identifies the current search.
|
|
969
|
+
* It consists of:
|
|
970
|
+
* - The current base query
|
|
971
|
+
* - The current search type
|
|
972
|
+
* - Any currently-applied facets
|
|
973
|
+
* - Any currently-applied date range
|
|
974
|
+
* - Any currently-applied prefix filters
|
|
975
|
+
* - The current sort options
|
|
873
976
|
*
|
|
874
977
|
* This lets us keep track of queries so we don't persist data that's
|
|
875
978
|
* no longer relevant.
|
|
@@ -880,7 +983,7 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
880
983
|
}
|
|
881
984
|
async fetchPage(pageNumber) {
|
|
882
985
|
var _a, _b, _c, _d, _e;
|
|
883
|
-
if (!this.
|
|
986
|
+
if (!this.filteredQuery)
|
|
884
987
|
return;
|
|
885
988
|
// if we already have data, don't fetch again
|
|
886
989
|
if (this.dataSource[pageNumber])
|
|
@@ -896,10 +999,11 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
896
999
|
this.pageFetchesInProgress[pageFetchQueryKey] = pageFetches;
|
|
897
1000
|
const sortParams = this.sortParam ? [this.sortParam] : [];
|
|
898
1001
|
const params = {
|
|
899
|
-
query: this.
|
|
1002
|
+
query: this.filteredQuery,
|
|
900
1003
|
page: pageNumber,
|
|
901
1004
|
rows: this.pageSize,
|
|
902
1005
|
sort: sortParams,
|
|
1006
|
+
filters: this.filterMap,
|
|
903
1007
|
aggregations: { omit: true },
|
|
904
1008
|
};
|
|
905
1009
|
const searchResponse = await ((_b = this.searchService) === null || _b === void 0 ? void 0 : _b.search(params, this.searchType));
|
|
@@ -930,7 +1034,7 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
930
1034
|
}
|
|
931
1035
|
}
|
|
932
1036
|
}
|
|
933
|
-
const queryChangedSinceFetch = searchQuery !== this.
|
|
1037
|
+
const queryChangedSinceFetch = searchQuery !== this.filteredQuery || sortChanged;
|
|
934
1038
|
if (queryChangedSinceFetch)
|
|
935
1039
|
return;
|
|
936
1040
|
const { results } = success.response;
|
|
@@ -938,12 +1042,12 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
938
1042
|
this.preloadCollectionNames(results);
|
|
939
1043
|
this.updateDataSource(pageNumber, results);
|
|
940
1044
|
}
|
|
1045
|
+
// When we reach the end of the data, we can set the infinite scroller's
|
|
1046
|
+
// item count to the real total number of results (rather than the
|
|
1047
|
+
// temporary estimates based on pages rendered so far).
|
|
941
1048
|
if (results.length < this.pageSize) {
|
|
942
1049
|
this.endOfDataReached = true;
|
|
943
|
-
|
|
944
|
-
if (this.infiniteScroller) {
|
|
945
|
-
this.infiniteScroller.itemCount = this.actualTileCount;
|
|
946
|
-
}
|
|
1050
|
+
this.infiniteScroller.itemCount = this.totalResults;
|
|
947
1051
|
}
|
|
948
1052
|
(_e = this.pageFetchesInProgress[pageFetchQueryKey]) === null || _e === void 0 ? void 0 : _e.delete(pageNumber);
|
|
949
1053
|
this.searchResultsLoading = false;
|
|
@@ -1041,6 +1145,56 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
1041
1145
|
this.infiniteScroller.reload();
|
|
1042
1146
|
}
|
|
1043
1147
|
}
|
|
1148
|
+
/** Fetches the aggregation buckets for the given prefix filter type. */
|
|
1149
|
+
async fetchPrefixFilterBuckets(filterType) {
|
|
1150
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1151
|
+
if (!this.fullQueryWithoutAlphaFilters)
|
|
1152
|
+
return [];
|
|
1153
|
+
const filterAggregationKey = prefixFilterAggregationKeys[filterType];
|
|
1154
|
+
const params = {
|
|
1155
|
+
query: this.fullQueryWithoutAlphaFilters,
|
|
1156
|
+
rows: 0,
|
|
1157
|
+
// Only fetch the firstTitle or firstCreator aggregation
|
|
1158
|
+
aggregations: { simpleParams: [filterAggregationKey] },
|
|
1159
|
+
// Fetch all 26 letter buckets
|
|
1160
|
+
aggregationsSize: 26,
|
|
1161
|
+
};
|
|
1162
|
+
const searchResponse = await ((_a = this.searchService) === null || _a === void 0 ? void 0 : _a.search(params, this.searchType));
|
|
1163
|
+
return ((_f = (_e = (_d = (_c = (_b = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.success) === null || _b === void 0 ? void 0 : _b.response) === null || _c === void 0 ? void 0 : _c.aggregations) === null || _d === void 0 ? void 0 : _d[filterAggregationKey]) === null || _e === void 0 ? void 0 : _e.buckets) !== null && _f !== void 0 ? _f : []);
|
|
1164
|
+
}
|
|
1165
|
+
/** Fetches and caches the prefix filter counts for the given filter type. */
|
|
1166
|
+
async updatePrefixFilterCounts(filterType) {
|
|
1167
|
+
const buckets = await this.fetchPrefixFilterBuckets(filterType);
|
|
1168
|
+
// Unpack the aggregation buckets into a simple map like { 'A': 50, 'B': 25, ... }
|
|
1169
|
+
this.prefixFilterCountMap = { ...this.prefixFilterCountMap }; // Clone the object to trigger an update
|
|
1170
|
+
this.prefixFilterCountMap[filterType] = buckets.reduce((acc, bucket) => {
|
|
1171
|
+
acc[bucket.key.toUpperCase()] = bucket.doc_count;
|
|
1172
|
+
return acc;
|
|
1173
|
+
}, {});
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Fetches and caches the prefix filter counts for the current sort type,
|
|
1177
|
+
* provided it is one that permits prefix filtering. (If not, this does nothing).
|
|
1178
|
+
*/
|
|
1179
|
+
async updatePrefixFiltersForCurrentSort() {
|
|
1180
|
+
if (['title', 'creator'].includes(this.selectedSort)) {
|
|
1181
|
+
const filterType = this.selectedSort;
|
|
1182
|
+
if (!this.prefixFilterCountMap[filterType]) {
|
|
1183
|
+
this.updatePrefixFilterCounts(filterType);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
/**
|
|
1188
|
+
* Clears the cached letter counts for both title and creator, and
|
|
1189
|
+
* fetches a new set of counts for whichever of them is the currently
|
|
1190
|
+
* selected sort option (which may be neither).
|
|
1191
|
+
*
|
|
1192
|
+
* Call this whenever the counts are invalidated (e.g., by a query change).
|
|
1193
|
+
*/
|
|
1194
|
+
refreshLetterCounts() {
|
|
1195
|
+
this.prefixFilterCountMap = {};
|
|
1196
|
+
this.updatePrefixFiltersForCurrentSort();
|
|
1197
|
+
}
|
|
1044
1198
|
/*
|
|
1045
1199
|
* Convert etree titles
|
|
1046
1200
|
* "[Creator] Live at [Place] on [Date]" => "[Date]: [Place]"
|
|
@@ -1099,8 +1253,10 @@ let CollectionBrowser = class CollectionBrowser extends LitElement {
|
|
|
1099
1253
|
* increase the number of pages to render and start fetching data for the new page
|
|
1100
1254
|
*/
|
|
1101
1255
|
scrollThresholdReached() {
|
|
1102
|
-
this.
|
|
1103
|
-
|
|
1256
|
+
if (!this.endOfDataReached) {
|
|
1257
|
+
this.pagesToRender += 1;
|
|
1258
|
+
this.fetchPage(this.pagesToRender);
|
|
1259
|
+
}
|
|
1104
1260
|
}
|
|
1105
1261
|
};
|
|
1106
1262
|
CollectionBrowser.styles = css `
|
|
@@ -1342,9 +1498,6 @@ __decorate([
|
|
|
1342
1498
|
__decorate([
|
|
1343
1499
|
property({ type: String })
|
|
1344
1500
|
], CollectionBrowser.prototype, "sortDirection", void 0);
|
|
1345
|
-
__decorate([
|
|
1346
|
-
property({ type: String })
|
|
1347
|
-
], CollectionBrowser.prototype, "dateRangeQueryClause", void 0);
|
|
1348
1501
|
__decorate([
|
|
1349
1502
|
property({ type: Number })
|
|
1350
1503
|
], CollectionBrowser.prototype, "pageSize", void 0);
|
|
@@ -1429,6 +1582,9 @@ __decorate([
|
|
|
1429
1582
|
__decorate([
|
|
1430
1583
|
state()
|
|
1431
1584
|
], CollectionBrowser.prototype, "placeholderType", void 0);
|
|
1585
|
+
__decorate([
|
|
1586
|
+
state()
|
|
1587
|
+
], CollectionBrowser.prototype, "prefixFilterCountMap", void 0);
|
|
1432
1588
|
__decorate([
|
|
1433
1589
|
query('#content-container')
|
|
1434
1590
|
], CollectionBrowser.prototype, "contentContainer", void 0);
|