@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.
@@ -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.host.dataSource !== this) return;
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.host.requestUpdate();
225
+ this.requestHostUpdate();
206
226
  }
207
227
 
208
228
  /**
@@ -286,8 +306,8 @@ export class CollectionBrowserDataSource
286
306
  ),
287
307
  ])
288
308
  );
289
- this.host.requestUpdate();
290
- this.host.refreshVisibleResults();
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.host.requestUpdate();
356
- this.host.refreshVisibleResults();
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.host.setFacetsLoading(true);
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.host.setFacetsLoading(false);
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.host.setFacetsLoading(false);
782
- this.host.requestUpdate();
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.host.setSearchResultsLoading(true);
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.host.setSearchResultsLoading(false);
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.host.queryErrorMessage = `${errorMsg ?? ''}${
928
+ this.queryErrorMessage = `${errorMsg ?? ''}${
870
929
  detailMsg ? `; ${detailMsg}` : ''
871
930
  }`;
872
931
 
873
- if (!this.host.queryErrorMessage) {
874
- this.host.queryErrorMessage =
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.host.setSearchResultsLoading(false);
885
- this.host.requestUpdate();
942
+ this.setSearchResultsLoading(false);
943
+ this.requestHostUpdate();
886
944
  return;
887
945
  }
888
946
 
889
947
  this.totalResults = success.response.totalResults - this.offset;
890
- this.host.setTotalResultCount(this.totalResults);
948
+ if (this.activeOnHost) {
949
+ this.host.setTotalResultCount(this.totalResults);
891
950
 
892
- // display event to offshoot when result count is zero.
893
- if (this.totalResults === 0) {
894
- this.host.emitEmptyResults();
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.host.requestUpdate();
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.host.refreshVisibleResults();
1045
+ this.refreshVisibleResults();
990
1046
  }
991
1047
  }
992
1048
 
@@ -1050,6 +1106,6 @@ export class CollectionBrowserDataSource
1050
1106
  {}
1051
1107
  );
1052
1108
 
1053
- this.host.requestUpdate();
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.skip('Collection Browser', () => {
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