@internetarchive/collection-browser 1.14.17-alpha.35 → 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 +3 -7
- 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 +82 -34
- 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 +3 -6
- package/src/data-source/collection-browser-data-source-interface.ts +5 -0
- package/src/data-source/collection-browser-data-source.ts +92 -36
- package/src/data-source/collection-browser-query-state.ts +0 -1
- package/test/collection-browser.test.ts +1 -1
|
@@ -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.
|
|
@@ -145,7 +154,11 @@ export class CollectionBrowserDataSource
|
|
|
145
154
|
// We check whether the host's state has changed in a way which should trigger a reset & new results fetch.
|
|
146
155
|
|
|
147
156
|
// Only the currently-installed data source should react to the update
|
|
148
|
-
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);
|
|
149
162
|
|
|
150
163
|
// Can't perform searches without a search service
|
|
151
164
|
if (!this.host.searchService) return;
|
|
@@ -162,10 +175,17 @@ export class CollectionBrowserDataSource
|
|
|
162
175
|
this.host.clearResultsOnEmptyQuery && this.host.baseQuery === '';
|
|
163
176
|
if (!(this.canPerformSearch || shouldShowEmptyQueryResults)) return;
|
|
164
177
|
|
|
165
|
-
this.host.emitQueryStateChanged();
|
|
178
|
+
if (this.activeOnHost) this.host.emitQueryStateChanged();
|
|
166
179
|
this.handleQueryChange();
|
|
167
180
|
}
|
|
168
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
|
+
|
|
169
189
|
/**
|
|
170
190
|
* @inheritdoc
|
|
171
191
|
*/
|
|
@@ -184,6 +204,7 @@ export class CollectionBrowserDataSource
|
|
|
184
204
|
this.pageElements = undefined;
|
|
185
205
|
this.parentCollections = [];
|
|
186
206
|
this.prefixFilterCountMap = {};
|
|
207
|
+
this.queryErrorMessage = undefined;
|
|
187
208
|
|
|
188
209
|
this.offset = 0;
|
|
189
210
|
this.numTileModels = 0;
|
|
@@ -191,9 +212,8 @@ export class CollectionBrowserDataSource
|
|
|
191
212
|
this.endOfDataReached = false;
|
|
192
213
|
this.queryInitialized = false;
|
|
193
214
|
|
|
194
|
-
this.host.setTotalResultCount(0);
|
|
195
|
-
|
|
196
|
-
this.host.requestUpdate();
|
|
215
|
+
if (this.activeOnHost) this.host.setTotalResultCount(0);
|
|
216
|
+
this.requestHostUpdate();
|
|
197
217
|
}
|
|
198
218
|
|
|
199
219
|
/**
|
|
@@ -202,7 +222,7 @@ export class CollectionBrowserDataSource
|
|
|
202
222
|
addPage(pageNum: number, pageTiles: TileModel[]): void {
|
|
203
223
|
this.pages[pageNum] = pageTiles;
|
|
204
224
|
this.numTileModels += pageTiles.length;
|
|
205
|
-
this.
|
|
225
|
+
this.requestHostUpdate();
|
|
206
226
|
}
|
|
207
227
|
|
|
208
228
|
/**
|
|
@@ -286,8 +306,8 @@ export class CollectionBrowserDataSource
|
|
|
286
306
|
),
|
|
287
307
|
])
|
|
288
308
|
);
|
|
289
|
-
this.
|
|
290
|
-
this.
|
|
309
|
+
this.requestHostUpdate();
|
|
310
|
+
this.refreshVisibleResults();
|
|
291
311
|
}
|
|
292
312
|
|
|
293
313
|
/**
|
|
@@ -352,8 +372,8 @@ export class CollectionBrowserDataSource
|
|
|
352
372
|
// Swap in the new pages
|
|
353
373
|
this.pages = newPages;
|
|
354
374
|
this.numTileModels -= numChecked;
|
|
355
|
-
this.
|
|
356
|
-
this.
|
|
375
|
+
this.requestHostUpdate();
|
|
376
|
+
this.refreshVisibleResults();
|
|
357
377
|
};
|
|
358
378
|
|
|
359
379
|
/**
|
|
@@ -387,8 +407,6 @@ export class CollectionBrowserDataSource
|
|
|
387
407
|
);
|
|
388
408
|
}
|
|
389
409
|
|
|
390
|
-
// DATA FETCHES
|
|
391
|
-
|
|
392
410
|
/**
|
|
393
411
|
* @inheritdoc
|
|
394
412
|
*/
|
|
@@ -411,6 +429,47 @@ export class CollectionBrowserDataSource
|
|
|
411
429
|
);
|
|
412
430
|
}
|
|
413
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
|
+
|
|
414
473
|
/**
|
|
415
474
|
* The query key is a string that uniquely identifies the current search.
|
|
416
475
|
* It consists of:
|
|
@@ -729,7 +788,7 @@ export class CollectionBrowserDataSource
|
|
|
729
788
|
'aggregations'
|
|
730
789
|
);
|
|
731
790
|
|
|
732
|
-
this.
|
|
791
|
+
this.setFacetsLoading(true);
|
|
733
792
|
const searchResponse = await this.host.searchService?.search(
|
|
734
793
|
params,
|
|
735
794
|
this.host.searchType
|
|
@@ -762,7 +821,7 @@ export class CollectionBrowserDataSource
|
|
|
762
821
|
);
|
|
763
822
|
}
|
|
764
823
|
|
|
765
|
-
this.
|
|
824
|
+
this.setFacetsLoading(false);
|
|
766
825
|
return;
|
|
767
826
|
}
|
|
768
827
|
|
|
@@ -778,18 +837,18 @@ export class CollectionBrowserDataSource
|
|
|
778
837
|
this.yearHistogramAggregation =
|
|
779
838
|
success?.response?.aggregations?.year_histogram;
|
|
780
839
|
|
|
781
|
-
this.
|
|
782
|
-
this.
|
|
840
|
+
this.setFacetsLoading(false);
|
|
841
|
+
this.requestHostUpdate();
|
|
783
842
|
}
|
|
784
843
|
|
|
785
844
|
/**
|
|
786
845
|
* Performs the initial page fetch(es) for the current search state.
|
|
787
846
|
*/
|
|
788
847
|
private async doInitialPageFetch(): Promise<void> {
|
|
789
|
-
this.
|
|
848
|
+
this.setSearchResultsLoading(true);
|
|
790
849
|
// Try to batch 2 initial page requests when possible
|
|
791
850
|
await this.fetchPage(this.host.initialPageNumber, 2);
|
|
792
|
-
this.
|
|
851
|
+
this.setSearchResultsLoading(false);
|
|
793
852
|
}
|
|
794
853
|
|
|
795
854
|
/**
|
|
@@ -866,13 +925,12 @@ export class CollectionBrowserDataSource
|
|
|
866
925
|
const errorMsg = searchResponse?.error?.message;
|
|
867
926
|
const detailMsg = searchResponse?.error?.details?.message;
|
|
868
927
|
|
|
869
|
-
this.
|
|
928
|
+
this.queryErrorMessage = `${errorMsg ?? ''}${
|
|
870
929
|
detailMsg ? `; ${detailMsg}` : ''
|
|
871
930
|
}`;
|
|
872
931
|
|
|
873
|
-
if (!this.
|
|
874
|
-
this.
|
|
875
|
-
'Missing or malformed response from backend';
|
|
932
|
+
if (!this.queryErrorMessage) {
|
|
933
|
+
this.queryErrorMessage = 'Missing or malformed response from backend';
|
|
876
934
|
// @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'
|
|
877
935
|
window?.Sentry?.captureMessage?.(this.queryErrorMessage, 'error');
|
|
878
936
|
}
|
|
@@ -881,17 +939,19 @@ export class CollectionBrowserDataSource
|
|
|
881
939
|
this.pageFetchesInProgress[pageFetchQueryKey]?.delete(pageNumber + i);
|
|
882
940
|
}
|
|
883
941
|
|
|
884
|
-
this.
|
|
885
|
-
this.
|
|
942
|
+
this.setSearchResultsLoading(false);
|
|
943
|
+
this.requestHostUpdate();
|
|
886
944
|
return;
|
|
887
945
|
}
|
|
888
946
|
|
|
889
947
|
this.totalResults = success.response.totalResults - this.offset;
|
|
890
|
-
|
|
948
|
+
if (this.activeOnHost) {
|
|
949
|
+
this.host.setTotalResultCount(this.totalResults);
|
|
891
950
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
951
|
+
// display event to offshoot when result count is zero.
|
|
952
|
+
if (this.totalResults === 0) {
|
|
953
|
+
this.host.emitEmptyResults();
|
|
954
|
+
}
|
|
895
955
|
}
|
|
896
956
|
|
|
897
957
|
if (this.host.withinCollection) {
|
|
@@ -953,14 +1013,14 @@ export class CollectionBrowserDataSource
|
|
|
953
1013
|
if (resultCountDiscrepancy > 0) {
|
|
954
1014
|
console.log('End of data reached');
|
|
955
1015
|
this.endOfDataReached = true;
|
|
956
|
-
this.host.setTileCount(this.totalResults);
|
|
1016
|
+
if (this.activeOnHost) this.host.setTileCount(this.totalResults);
|
|
957
1017
|
}
|
|
958
1018
|
|
|
959
1019
|
for (let i = 0; i < numPages; i += 1) {
|
|
960
1020
|
this.pageFetchesInProgress[pageFetchQueryKey]?.delete(pageNumber + i);
|
|
961
1021
|
}
|
|
962
1022
|
|
|
963
|
-
this.
|
|
1023
|
+
this.requestHostUpdate();
|
|
964
1024
|
}
|
|
965
1025
|
|
|
966
1026
|
/**
|
|
@@ -973,10 +1033,6 @@ export class CollectionBrowserDataSource
|
|
|
973
1033
|
pageNumber: number,
|
|
974
1034
|
results: SearchResult[]
|
|
975
1035
|
): void {
|
|
976
|
-
// copy our existing datasource so when we set it below, it gets set
|
|
977
|
-
// instead of modifying the existing dataSource since object changes
|
|
978
|
-
// don't trigger a re-render
|
|
979
|
-
// const datasource = { ...this.dataSource };
|
|
980
1036
|
const tiles: TileModel[] = [];
|
|
981
1037
|
results?.forEach(result => {
|
|
982
1038
|
if (!result.identifier) return;
|
|
@@ -986,7 +1042,7 @@ export class CollectionBrowserDataSource
|
|
|
986
1042
|
const visiblePages = this.host.currentVisiblePageNumbers;
|
|
987
1043
|
const needsReload = visiblePages.includes(pageNumber);
|
|
988
1044
|
if (needsReload) {
|
|
989
|
-
this.
|
|
1045
|
+
this.refreshVisibleResults();
|
|
990
1046
|
}
|
|
991
1047
|
}
|
|
992
1048
|
|
|
@@ -1050,6 +1106,6 @@ export class CollectionBrowserDataSource
|
|
|
1050
1106
|
{}
|
|
1051
1107
|
);
|
|
1052
1108
|
|
|
1053
|
-
this.
|
|
1109
|
+
this.requestHostUpdate();
|
|
1054
1110
|
}
|
|
1055
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
|