@internetarchive/collection-browser 1.14.17-alpha.34 → 1.14.17-alpha.36
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/collection-browser.d.ts +0 -1
- package/dist/src/collection-browser.js +4 -8
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/data-source/collection-browser-data-source-interface.d.ts +4 -0
- package/dist/src/data-source/collection-browser-data-source-interface.js.map +1 -1
- package/dist/src/data-source/collection-browser-data-source.d.ts +29 -0
- package/dist/src/data-source/collection-browser-data-source.js +83 -36
- package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
- package/dist/src/data-source/collection-browser-query-state.d.ts +0 -1
- package/dist/src/data-source/collection-browser-query-state.js.map +1 -1
- package/dist/test/collection-browser.test.js +1 -1
- package/dist/test/collection-browser.test.js.map +1 -1
- package/package.json +1 -1
- package/src/collection-browser.ts +4 -7
- package/src/data-source/collection-browser-data-source-interface.ts +5 -0
- package/src/data-source/collection-browser-data-source.ts +93 -38
- package/src/data-source/collection-browser-query-state.ts +0 -1
- package/test/collection-browser.test.ts +1 -1
|
@@ -171,8 +171,6 @@ export class CollectionBrowser
|
|
|
171
171
|
|
|
172
172
|
@property({ type: Boolean }) isLoansTab = false;
|
|
173
173
|
|
|
174
|
-
@property({ type: String }) queryErrorMessage?: string;
|
|
175
|
-
|
|
176
174
|
/**
|
|
177
175
|
* The results per page so we can paginate.
|
|
178
176
|
*
|
|
@@ -450,7 +448,7 @@ export class CollectionBrowser
|
|
|
450
448
|
!hasQuery && isCollection ? 'empty-collection' : 'no-results';
|
|
451
449
|
}
|
|
452
450
|
|
|
453
|
-
if (this.queryErrorMessage) {
|
|
451
|
+
if (this.dataSource.queryErrorMessage) {
|
|
454
452
|
this.placeholderType =
|
|
455
453
|
!hasQuery && isCollection ? 'collection-error' : 'query-error';
|
|
456
454
|
}
|
|
@@ -462,7 +460,7 @@ export class CollectionBrowser
|
|
|
462
460
|
.placeholderType=${this.placeholderType}
|
|
463
461
|
?isMobileView=${this.mobileView}
|
|
464
462
|
?isCollection=${!!this.withinCollection}
|
|
465
|
-
.detailMessage=${this.queryErrorMessage ?? ''}
|
|
463
|
+
.detailMessage=${this.dataSource.queryErrorMessage ?? ''}
|
|
466
464
|
.baseNavigationUrl=${this.baseNavigationUrl}
|
|
467
465
|
></empty-placeholder>
|
|
468
466
|
${this.infiniteScrollerTemplate}
|
|
@@ -1027,7 +1025,7 @@ export class CollectionBrowser
|
|
|
1027
1025
|
|
|
1028
1026
|
updated(changed: PropertyValues) {
|
|
1029
1027
|
console.log(
|
|
1030
|
-
'* CB UPDATED',
|
|
1028
|
+
'* CB UPDATED\n',
|
|
1031
1029
|
[...changed.entries()]
|
|
1032
1030
|
.map(([k, v]) => `${String(k)}: ${v} => ${this[k as keyof this]}`)
|
|
1033
1031
|
.join('\n')
|
|
@@ -1410,7 +1408,7 @@ export class CollectionBrowser
|
|
|
1410
1408
|
JSON.stringify(this.selectedFacets)
|
|
1411
1409
|
);
|
|
1412
1410
|
this.previousQueryKey = this.dataSource.pageFetchQueryKey;
|
|
1413
|
-
this.emitQueryStateChanged();
|
|
1411
|
+
// this.emitQueryStateChanged();
|
|
1414
1412
|
|
|
1415
1413
|
this.tileModelOffset = 0;
|
|
1416
1414
|
this.totalResults = undefined;
|
|
@@ -1418,7 +1416,6 @@ export class CollectionBrowser
|
|
|
1418
1416
|
this.initialPageNumber === 1
|
|
1419
1417
|
? 2 // First two pages are batched into one request when starting from page 1
|
|
1420
1418
|
: this.initialPageNumber;
|
|
1421
|
-
this.queryErrorMessage = undefined;
|
|
1422
1419
|
|
|
1423
1420
|
// Reset the infinite scroller's item count, so that it
|
|
1424
1421
|
// shows tile placeholders until the new query's results load in
|
|
@@ -120,6 +120,11 @@ export interface CollectionBrowserDataSourceInterface
|
|
|
120
120
|
Record<PrefixFilterType, PrefixFilterCounts>
|
|
121
121
|
>;
|
|
122
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Any error message from the most recent search results response.
|
|
125
|
+
*/
|
|
126
|
+
readonly queryErrorMessage?: string;
|
|
127
|
+
|
|
123
128
|
/**
|
|
124
129
|
* An array of all the tile models whose management checkboxes are checked
|
|
125
130
|
*/
|
|
@@ -45,6 +45,10 @@ export class CollectionBrowserDataSource
|
|
|
45
45
|
*/
|
|
46
46
|
private previousQueryKey: string = '';
|
|
47
47
|
|
|
48
|
+
private searchResultsLoading = false;
|
|
49
|
+
|
|
50
|
+
private facetsLoading = false;
|
|
51
|
+
|
|
48
52
|
// TEMP for ease of debugging
|
|
49
53
|
private id = Math.random();
|
|
50
54
|
|
|
@@ -104,6 +108,11 @@ export class CollectionBrowserDataSource
|
|
|
104
108
|
prefixFilterCountMap: Partial<Record<PrefixFilterType, PrefixFilterCounts>> =
|
|
105
109
|
{};
|
|
106
110
|
|
|
111
|
+
/**
|
|
112
|
+
* @inheritdoc
|
|
113
|
+
*/
|
|
114
|
+
queryErrorMessage?: string;
|
|
115
|
+
|
|
107
116
|
/**
|
|
108
117
|
* Internal property to store the `resolve` function for the most recent
|
|
109
118
|
* `initialSearchComplete` promise, allowing us to resolve it at the appropriate time.
|
|
@@ -124,7 +133,6 @@ export class CollectionBrowserDataSource
|
|
|
124
133
|
return this._initialSearchCompletePromise;
|
|
125
134
|
}
|
|
126
135
|
|
|
127
|
-
// eslint-disable-next-line no-useless-constructor
|
|
128
136
|
constructor(
|
|
129
137
|
/** The host element to which this controller should attach listeners */
|
|
130
138
|
private readonly host: ReactiveControllerHost &
|
|
@@ -132,7 +140,7 @@ export class CollectionBrowserDataSource
|
|
|
132
140
|
/** Default size of result pages */
|
|
133
141
|
private pageSize: number
|
|
134
142
|
) {
|
|
135
|
-
|
|
143
|
+
this.host.addController(this);
|
|
136
144
|
}
|
|
137
145
|
|
|
138
146
|
hostUpdate(): void {
|
|
@@ -146,7 +154,11 @@ export class CollectionBrowserDataSource
|
|
|
146
154
|
// We check whether the host's state has changed in a way which should trigger a reset & new results fetch.
|
|
147
155
|
|
|
148
156
|
// Only the currently-installed data source should react to the update
|
|
149
|
-
if (this.
|
|
157
|
+
if (!this.activeOnHost) return;
|
|
158
|
+
|
|
159
|
+
// Copy loading states onto the host
|
|
160
|
+
this.setSearchResultsLoading(this.searchResultsLoading);
|
|
161
|
+
this.setFacetsLoading(this.facetsLoading);
|
|
150
162
|
|
|
151
163
|
// Can't perform searches without a search service
|
|
152
164
|
if (!this.host.searchService) return;
|
|
@@ -163,10 +175,17 @@ export class CollectionBrowserDataSource
|
|
|
163
175
|
this.host.clearResultsOnEmptyQuery && this.host.baseQuery === '';
|
|
164
176
|
if (!(this.canPerformSearch || shouldShowEmptyQueryResults)) return;
|
|
165
177
|
|
|
166
|
-
this.host.emitQueryStateChanged();
|
|
178
|
+
if (this.activeOnHost) this.host.emitQueryStateChanged();
|
|
167
179
|
this.handleQueryChange();
|
|
168
180
|
}
|
|
169
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Returns whether this data source is the one currently installed on the host component.
|
|
184
|
+
*/
|
|
185
|
+
private get activeOnHost(): boolean {
|
|
186
|
+
return this.host.dataSource === this;
|
|
187
|
+
}
|
|
188
|
+
|
|
170
189
|
/**
|
|
171
190
|
* @inheritdoc
|
|
172
191
|
*/
|
|
@@ -185,6 +204,7 @@ export class CollectionBrowserDataSource
|
|
|
185
204
|
this.pageElements = undefined;
|
|
186
205
|
this.parentCollections = [];
|
|
187
206
|
this.prefixFilterCountMap = {};
|
|
207
|
+
this.queryErrorMessage = undefined;
|
|
188
208
|
|
|
189
209
|
this.offset = 0;
|
|
190
210
|
this.numTileModels = 0;
|
|
@@ -192,9 +212,8 @@ export class CollectionBrowserDataSource
|
|
|
192
212
|
this.endOfDataReached = false;
|
|
193
213
|
this.queryInitialized = false;
|
|
194
214
|
|
|
195
|
-
this.host.setTotalResultCount(0);
|
|
196
|
-
|
|
197
|
-
this.host.requestUpdate();
|
|
215
|
+
if (this.activeOnHost) this.host.setTotalResultCount(0);
|
|
216
|
+
this.requestHostUpdate();
|
|
198
217
|
}
|
|
199
218
|
|
|
200
219
|
/**
|
|
@@ -203,7 +222,7 @@ export class CollectionBrowserDataSource
|
|
|
203
222
|
addPage(pageNum: number, pageTiles: TileModel[]): void {
|
|
204
223
|
this.pages[pageNum] = pageTiles;
|
|
205
224
|
this.numTileModels += pageTiles.length;
|
|
206
|
-
this.
|
|
225
|
+
this.requestHostUpdate();
|
|
207
226
|
}
|
|
208
227
|
|
|
209
228
|
/**
|
|
@@ -287,8 +306,8 @@ export class CollectionBrowserDataSource
|
|
|
287
306
|
),
|
|
288
307
|
])
|
|
289
308
|
);
|
|
290
|
-
this.
|
|
291
|
-
this.
|
|
309
|
+
this.requestHostUpdate();
|
|
310
|
+
this.refreshVisibleResults();
|
|
292
311
|
}
|
|
293
312
|
|
|
294
313
|
/**
|
|
@@ -353,8 +372,8 @@ export class CollectionBrowserDataSource
|
|
|
353
372
|
// Swap in the new pages
|
|
354
373
|
this.pages = newPages;
|
|
355
374
|
this.numTileModels -= numChecked;
|
|
356
|
-
this.
|
|
357
|
-
this.
|
|
375
|
+
this.requestHostUpdate();
|
|
376
|
+
this.refreshVisibleResults();
|
|
358
377
|
};
|
|
359
378
|
|
|
360
379
|
/**
|
|
@@ -388,8 +407,6 @@ export class CollectionBrowserDataSource
|
|
|
388
407
|
);
|
|
389
408
|
}
|
|
390
409
|
|
|
391
|
-
// DATA FETCHES
|
|
392
|
-
|
|
393
410
|
/**
|
|
394
411
|
* @inheritdoc
|
|
395
412
|
*/
|
|
@@ -412,6 +429,47 @@ export class CollectionBrowserDataSource
|
|
|
412
429
|
);
|
|
413
430
|
}
|
|
414
431
|
|
|
432
|
+
/**
|
|
433
|
+
* Sets the state for whether the initial set of search results for the
|
|
434
|
+
* current query is loading
|
|
435
|
+
*/
|
|
436
|
+
private setSearchResultsLoading(loading: boolean): void {
|
|
437
|
+
this.searchResultsLoading = loading;
|
|
438
|
+
if (this.activeOnHost) {
|
|
439
|
+
this.host.setSearchResultsLoading(loading);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Sets the state for whether the facets for a query is loading
|
|
445
|
+
*/
|
|
446
|
+
private setFacetsLoading(loading: boolean): void {
|
|
447
|
+
this.facetsLoading = loading;
|
|
448
|
+
if (this.activeOnHost) {
|
|
449
|
+
this.host.setFacetsLoading(loading);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Requests that the host perform an update, provided this data
|
|
455
|
+
* source is actively installed on it.
|
|
456
|
+
*/
|
|
457
|
+
private requestHostUpdate(): void {
|
|
458
|
+
if (this.activeOnHost) {
|
|
459
|
+
this.host.requestUpdate();
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Requests that the host refresh its visible tiles, provided this
|
|
465
|
+
* data source is actively installed on it.
|
|
466
|
+
*/
|
|
467
|
+
private refreshVisibleResults(): void {
|
|
468
|
+
if (this.activeOnHost) {
|
|
469
|
+
this.host.refreshVisibleResults();
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
415
473
|
/**
|
|
416
474
|
* The query key is a string that uniquely identifies the current search.
|
|
417
475
|
* It consists of:
|
|
@@ -730,7 +788,7 @@ export class CollectionBrowserDataSource
|
|
|
730
788
|
'aggregations'
|
|
731
789
|
);
|
|
732
790
|
|
|
733
|
-
this.
|
|
791
|
+
this.setFacetsLoading(true);
|
|
734
792
|
const searchResponse = await this.host.searchService?.search(
|
|
735
793
|
params,
|
|
736
794
|
this.host.searchType
|
|
@@ -763,7 +821,7 @@ export class CollectionBrowserDataSource
|
|
|
763
821
|
);
|
|
764
822
|
}
|
|
765
823
|
|
|
766
|
-
this.
|
|
824
|
+
this.setFacetsLoading(false);
|
|
767
825
|
return;
|
|
768
826
|
}
|
|
769
827
|
|
|
@@ -779,18 +837,18 @@ export class CollectionBrowserDataSource
|
|
|
779
837
|
this.yearHistogramAggregation =
|
|
780
838
|
success?.response?.aggregations?.year_histogram;
|
|
781
839
|
|
|
782
|
-
this.
|
|
783
|
-
this.
|
|
840
|
+
this.setFacetsLoading(false);
|
|
841
|
+
this.requestHostUpdate();
|
|
784
842
|
}
|
|
785
843
|
|
|
786
844
|
/**
|
|
787
845
|
* Performs the initial page fetch(es) for the current search state.
|
|
788
846
|
*/
|
|
789
847
|
private async doInitialPageFetch(): Promise<void> {
|
|
790
|
-
this.
|
|
848
|
+
this.setSearchResultsLoading(true);
|
|
791
849
|
// Try to batch 2 initial page requests when possible
|
|
792
850
|
await this.fetchPage(this.host.initialPageNumber, 2);
|
|
793
|
-
this.
|
|
851
|
+
this.setSearchResultsLoading(false);
|
|
794
852
|
}
|
|
795
853
|
|
|
796
854
|
/**
|
|
@@ -867,13 +925,12 @@ export class CollectionBrowserDataSource
|
|
|
867
925
|
const errorMsg = searchResponse?.error?.message;
|
|
868
926
|
const detailMsg = searchResponse?.error?.details?.message;
|
|
869
927
|
|
|
870
|
-
this.
|
|
928
|
+
this.queryErrorMessage = `${errorMsg ?? ''}${
|
|
871
929
|
detailMsg ? `; ${detailMsg}` : ''
|
|
872
930
|
}`;
|
|
873
931
|
|
|
874
|
-
if (!this.
|
|
875
|
-
this.
|
|
876
|
-
'Missing or malformed response from backend';
|
|
932
|
+
if (!this.queryErrorMessage) {
|
|
933
|
+
this.queryErrorMessage = 'Missing or malformed response from backend';
|
|
877
934
|
// @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'
|
|
878
935
|
window?.Sentry?.captureMessage?.(this.queryErrorMessage, 'error');
|
|
879
936
|
}
|
|
@@ -882,17 +939,19 @@ export class CollectionBrowserDataSource
|
|
|
882
939
|
this.pageFetchesInProgress[pageFetchQueryKey]?.delete(pageNumber + i);
|
|
883
940
|
}
|
|
884
941
|
|
|
885
|
-
this.
|
|
886
|
-
this.
|
|
942
|
+
this.setSearchResultsLoading(false);
|
|
943
|
+
this.requestHostUpdate();
|
|
887
944
|
return;
|
|
888
945
|
}
|
|
889
946
|
|
|
890
947
|
this.totalResults = success.response.totalResults - this.offset;
|
|
891
|
-
|
|
948
|
+
if (this.activeOnHost) {
|
|
949
|
+
this.host.setTotalResultCount(this.totalResults);
|
|
892
950
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
951
|
+
// display event to offshoot when result count is zero.
|
|
952
|
+
if (this.totalResults === 0) {
|
|
953
|
+
this.host.emitEmptyResults();
|
|
954
|
+
}
|
|
896
955
|
}
|
|
897
956
|
|
|
898
957
|
if (this.host.withinCollection) {
|
|
@@ -954,14 +1013,14 @@ export class CollectionBrowserDataSource
|
|
|
954
1013
|
if (resultCountDiscrepancy > 0) {
|
|
955
1014
|
console.log('End of data reached');
|
|
956
1015
|
this.endOfDataReached = true;
|
|
957
|
-
this.host.setTileCount(this.totalResults);
|
|
1016
|
+
if (this.activeOnHost) this.host.setTileCount(this.totalResults);
|
|
958
1017
|
}
|
|
959
1018
|
|
|
960
1019
|
for (let i = 0; i < numPages; i += 1) {
|
|
961
1020
|
this.pageFetchesInProgress[pageFetchQueryKey]?.delete(pageNumber + i);
|
|
962
1021
|
}
|
|
963
1022
|
|
|
964
|
-
this.
|
|
1023
|
+
this.requestHostUpdate();
|
|
965
1024
|
}
|
|
966
1025
|
|
|
967
1026
|
/**
|
|
@@ -974,10 +1033,6 @@ export class CollectionBrowserDataSource
|
|
|
974
1033
|
pageNumber: number,
|
|
975
1034
|
results: SearchResult[]
|
|
976
1035
|
): void {
|
|
977
|
-
// copy our existing datasource so when we set it below, it gets set
|
|
978
|
-
// instead of modifying the existing dataSource since object changes
|
|
979
|
-
// don't trigger a re-render
|
|
980
|
-
// const datasource = { ...this.dataSource };
|
|
981
1036
|
const tiles: TileModel[] = [];
|
|
982
1037
|
results?.forEach(result => {
|
|
983
1038
|
if (!result.identifier) return;
|
|
@@ -987,7 +1042,7 @@ export class CollectionBrowserDataSource
|
|
|
987
1042
|
const visiblePages = this.host.currentVisiblePageNumbers;
|
|
988
1043
|
const needsReload = visiblePages.includes(pageNumber);
|
|
989
1044
|
if (needsReload) {
|
|
990
|
-
this.
|
|
1045
|
+
this.refreshVisibleResults();
|
|
991
1046
|
}
|
|
992
1047
|
}
|
|
993
1048
|
|
|
@@ -1051,6 +1106,6 @@ export class CollectionBrowserDataSource
|
|
|
1051
1106
|
{}
|
|
1052
1107
|
);
|
|
1053
1108
|
|
|
1054
|
-
this.
|
|
1109
|
+
this.requestHostUpdate();
|
|
1055
1110
|
}
|
|
1056
1111
|
}
|
|
@@ -34,7 +34,6 @@ export interface CollectionBrowserQueryState {
|
|
|
34
34
|
export interface CollectionBrowserSearchInterface
|
|
35
35
|
extends CollectionBrowserQueryState {
|
|
36
36
|
searchService?: SearchServiceInterface;
|
|
37
|
-
queryErrorMessage?: string;
|
|
38
37
|
readonly sortParam: SortParam | null;
|
|
39
38
|
readonly suppressFacets?: boolean;
|
|
40
39
|
readonly initialPageNumber: number;
|
|
@@ -32,7 +32,7 @@ import type { SortFilterBar } from '../src/sort-filter-bar/sort-filter-bar';
|
|
|
32
32
|
*/
|
|
33
33
|
const nextTick = () => aTimeout(0);
|
|
34
34
|
|
|
35
|
-
describe
|
|
35
|
+
describe('Collection Browser', () => {
|
|
36
36
|
beforeEach(async () => {
|
|
37
37
|
// Apparently query params set by one test can bleed into other tests.
|
|
38
38
|
// Since collection browser restores its state from certain query params, we need
|