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