@internetarchive/collection-browser 1.14.17-alpha.2 → 1.14.17-alpha.21

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.
Files changed (87) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/index.js.map +1 -1
  3. package/dist/src/app-root.d.ts +1 -0
  4. package/dist/src/app-root.js +38 -0
  5. package/dist/src/app-root.js.map +1 -1
  6. package/dist/src/collection-browser.d.ts +2 -15
  7. package/dist/src/collection-browser.js +22 -29
  8. package/dist/src/collection-browser.js.map +1 -1
  9. package/dist/src/data-source/collection-browser-data-source.d.ts +55 -32
  10. package/dist/src/data-source/collection-browser-data-source.js +155 -162
  11. package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
  12. package/dist/src/data-source/models.d.ts +6 -3
  13. package/dist/src/data-source/models.js.map +1 -1
  14. package/dist/src/manage/manage-bar.d.ts +1 -1
  15. package/dist/src/manage/manage-bar.js.map +1 -1
  16. package/dist/src/models.d.ts +20 -4
  17. package/dist/src/models.js +105 -0
  18. package/dist/src/models.js.map +1 -1
  19. package/dist/src/sort-filter-bar/sort-filter-bar.js +25 -16
  20. package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
  21. package/dist/src/tiles/grid/item-tile.d.ts +1 -0
  22. package/dist/src/tiles/grid/item-tile.js +28 -1
  23. package/dist/src/tiles/grid/item-tile.js.map +1 -1
  24. package/dist/src/tiles/grid/tile-stats.js +13 -8
  25. package/dist/src/tiles/grid/tile-stats.js.map +1 -1
  26. package/dist/src/tiles/list/tile-list-compact.js +1 -1
  27. package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
  28. package/dist/src/tiles/list/tile-list.d.ts +1 -0
  29. package/dist/src/tiles/list/tile-list.js +32 -1
  30. package/dist/src/tiles/list/tile-list.js.map +1 -1
  31. package/dist/src/tiles/tile-dispatcher.js +3 -2
  32. package/dist/src/tiles/tile-dispatcher.js.map +1 -1
  33. package/dist/src/tiles/tile-display-value-provider.d.ts +6 -2
  34. package/dist/src/tiles/tile-display-value-provider.js +15 -1
  35. package/dist/src/tiles/tile-display-value-provider.js.map +1 -1
  36. package/dist/src/utils/collapse-repeated-quotes.d.ts +11 -0
  37. package/dist/src/utils/collapse-repeated-quotes.js +14 -0
  38. package/dist/src/utils/collapse-repeated-quotes.js.map +1 -0
  39. package/dist/src/utils/resolve-mediatype.d.ts +8 -0
  40. package/dist/src/utils/resolve-mediatype.js +24 -0
  41. package/dist/src/utils/resolve-mediatype.js.map +1 -0
  42. package/dist/test/collection-browser.test.js +39 -19
  43. package/dist/test/collection-browser.test.js.map +1 -1
  44. package/dist/test/collection-facets/more-facets-content.test.js +2 -2
  45. package/dist/test/collection-facets/more-facets-content.test.js.map +1 -1
  46. package/dist/test/collection-facets.test.js +5 -0
  47. package/dist/test/collection-facets.test.js.map +1 -1
  48. package/dist/test/item-image.test.js +33 -34
  49. package/dist/test/item-image.test.js.map +1 -1
  50. package/dist/test/mocks/mock-search-responses.d.ts +1 -0
  51. package/dist/test/mocks/mock-search-responses.js +62 -0
  52. package/dist/test/mocks/mock-search-responses.js.map +1 -1
  53. package/dist/test/sort-filter-bar/sort-filter-bar.test.js +41 -4
  54. package/dist/test/sort-filter-bar/sort-filter-bar.test.js.map +1 -1
  55. package/dist/test/tiles/hover/hover-pane-controller.test.js +18 -17
  56. package/dist/test/tiles/hover/hover-pane-controller.test.js.map +1 -1
  57. package/package.json +2 -2
  58. package/src/app-root.ts +39 -0
  59. package/src/collection-browser.ts +24 -40
  60. package/src/data-source/collection-browser-data-source.ts +160 -132
  61. package/src/data-source/models.ts +6 -2
  62. package/src/manage/manage-bar.ts +1 -1
  63. package/src/models.ts +154 -3
  64. package/src/sort-filter-bar/sort-filter-bar.ts +26 -16
  65. package/src/tiles/grid/item-tile.ts +36 -1
  66. package/src/tiles/grid/tile-stats.ts +12 -7
  67. package/src/tiles/list/tile-list-compact.ts +1 -1
  68. package/src/tiles/list/tile-list.ts +43 -5
  69. package/src/tiles/tile-dispatcher.ts +2 -1
  70. package/src/tiles/tile-display-value-provider.ts +20 -2
  71. package/src/utils/collapse-repeated-quotes.ts +13 -0
  72. package/src/utils/resolve-mediatype.ts +26 -0
  73. package/test/collection-browser.test.ts +74 -19
  74. package/test/collection-facets/more-facets-content.test.ts +4 -2
  75. package/test/collection-facets.test.ts +5 -0
  76. package/test/item-image.test.ts +34 -36
  77. package/test/mocks/mock-search-responses.ts +66 -0
  78. package/test/sort-filter-bar/sort-filter-bar.test.ts +50 -4
  79. package/test/tiles/hover/hover-pane-controller.test.ts +19 -17
  80. package/dist/src/data-source/data-source-fetch-provider.d.ts +0 -13
  81. package/dist/src/data-source/data-source-fetch-provider.js +0 -61
  82. package/dist/src/data-source/data-source-fetch-provider.js.map +0 -1
  83. package/dist/src/selected-facets.d.ts +0 -67
  84. package/dist/src/selected-facets.js +0 -149
  85. package/dist/src/selected-facets.js.map +0 -1
  86. package/src/data-source/data-source-fetch-provider.ts +0 -79
  87. package/src/selected-facets.ts +0 -216
@@ -12,13 +12,13 @@ import {
12
12
  SearchResult,
13
13
  SearchType,
14
14
  } from '@internetarchive/search-service';
15
- import type { MediaType } from '@internetarchive/field-parsers';
16
15
  import {
17
16
  prefixFilterAggregationKeys,
18
17
  type FacetBucket,
19
18
  type PrefixFilterType,
20
- type TileModel,
19
+ TileModel,
21
20
  PrefixFilterCounts,
21
+ RequestKind,
22
22
  } from '../models';
23
23
  import type {
24
24
  CollectionBrowserSearchInterface,
@@ -27,8 +27,6 @@ import type {
27
27
  } from './models';
28
28
  import { sha1 } from '../utils/sha1';
29
29
 
30
- type RequestKind = 'full' | 'hits' | 'aggregations';
31
-
32
30
  export interface CollectionBrowserDataSourceInterface
33
31
  extends ReactiveController {
34
32
  /**
@@ -44,6 +42,12 @@ export interface CollectionBrowserDataSourceInterface
44
42
  */
45
43
  readonly canPerformSearch: boolean;
46
44
 
45
+ /**
46
+ * Whether the end of the set of results for the current query state has been
47
+ * encountered (i.e., the last page of results).
48
+ */
49
+ readonly endOfDataReached: boolean;
50
+
47
51
  /**
48
52
  * A string key compactly representing the current full search state, which can
49
53
  * be used to determine, e.g., when a new search is required or whether an arriving
@@ -128,6 +132,20 @@ export interface CollectionBrowserDataSourceInterface
128
132
  */
129
133
  readonly uncheckedTileModels: TileModel[];
130
134
 
135
+ /**
136
+ * A Promise which, after each query change, resolves once the fetches for the initial
137
+ * search have completed. Waits for *both* the hits and aggregations fetches to finish.
138
+ *
139
+ * Ensure you await this component's `updateComplete` promise before awaiting this
140
+ * one, to ensure you do not await an obsolete promise from the previous update.
141
+ */
142
+ readonly initialSearchComplete: Promise<boolean>;
143
+
144
+ /**
145
+ * Resets the data source to its empty state, with no result pages, aggregations, etc.
146
+ */
147
+ reset(): void;
148
+
131
149
  /**
132
150
  * Adds the given page of tile models to the data source.
133
151
  * If the given page number already exists, that page will be overwritten.
@@ -191,11 +209,6 @@ export interface CollectionBrowserDataSourceInterface
191
209
  */
192
210
  setPageSize(pageSize: number): void;
193
211
 
194
- /**
195
- * Resets the data source to its empty state, with no result pages, aggregations, etc.
196
- */
197
- reset(): void;
198
-
199
212
  /**
200
213
  * Notifies the data source that a query change has occurred, which may trigger a data
201
214
  * reset & new fetches.
@@ -242,8 +255,22 @@ export class CollectionBrowserDataSource
242
255
  */
243
256
  private pageFetchesInProgress: Record<string, Set<number>> = {};
244
257
 
258
+ /**
259
+ * A record of the query key used for the last search.
260
+ * If this changes, we need to load new results.
261
+ */
262
+ private previousQueryKey: string = '';
263
+
264
+ private id = Math.random();
265
+
266
+ /**
267
+ * @inheritdoc
268
+ */
245
269
  totalResults = 0;
246
270
 
271
+ /**
272
+ * @inheritdoc
273
+ */
247
274
  endOfDataReached = false;
248
275
 
249
276
  /**
@@ -287,6 +314,26 @@ export class CollectionBrowserDataSource
287
314
  prefixFilterCountMap: Partial<Record<PrefixFilterType, PrefixFilterCounts>> =
288
315
  {};
289
316
 
317
+ /**
318
+ * Internal property to store the `resolve` function for the most recent
319
+ * `initialSearchComplete` promise, allowing us to resolve it at the appropriate time.
320
+ */
321
+ private _initialSearchCompleteResolver!: (val: boolean) => void;
322
+
323
+ /**
324
+ * Internal property to store the private value backing the `initialSearchComplete` getter.
325
+ */
326
+ private _initialSearchCompletePromise: Promise<boolean> = new Promise(res => {
327
+ this._initialSearchCompleteResolver = res;
328
+ });
329
+
330
+ /**
331
+ * @inheritdoc
332
+ */
333
+ get initialSearchComplete(): Promise<boolean> {
334
+ return this._initialSearchCompletePromise;
335
+ }
336
+
290
337
  constructor(
291
338
  /** The host element to which this controller should attach listeners */
292
339
  private readonly host: ReactiveControllerHost &
@@ -297,6 +344,30 @@ export class CollectionBrowserDataSource
297
344
  this.host.addController(this as CollectionBrowserDataSourceInterface);
298
345
  }
299
346
 
347
+ hostUpdate(): void {
348
+ // This reactive controller hook is run whenever the host component (collection-browser) performs an update.
349
+ // We check whether the host's state has changed in a way which should trigger a reset & new results fetch.
350
+
351
+ // Only the currently-installed data source should react to the update
352
+ if (this.host.dataSource !== this) return;
353
+
354
+ // Can't perform searches without a search service
355
+ if (!this.host.searchService) return;
356
+
357
+ // We should only reset if part of the full query state has changed
358
+ const queryKeyChanged = this.pageFetchQueryKey !== this.previousQueryKey;
359
+ console.log('query keys', this.pageFetchQueryKey, this.previousQueryKey);
360
+ if (!queryKeyChanged) return;
361
+
362
+ // We should only reset if either:
363
+ // (a) our state permits a valid search, or
364
+ // (b) we have a blank query that we want to show empty results for
365
+ const shouldShowEmptyQueryResults = this.host.clearResultsOnEmptyQuery && this.host.baseQuery === '';
366
+ if (!(this.canPerformSearch || shouldShowEmptyQueryResults)) return;
367
+
368
+ this.handleQueryChange();
369
+ }
370
+
300
371
  /**
301
372
  * @inheritdoc
302
373
  */
@@ -304,6 +375,26 @@ export class CollectionBrowserDataSource
304
375
  return this.numTileModels;
305
376
  }
306
377
 
378
+ /**
379
+ * @inheritdoc
380
+ */
381
+ reset(): void {
382
+ this.pages = {};
383
+ this.aggregations = {};
384
+ this.yearHistogramAggregation = undefined;
385
+ this.pageFetchesInProgress = {};
386
+ this.pageElements = undefined;
387
+ this.parentCollections = [];
388
+ this.prefixFilterCountMap = {};
389
+
390
+ this.offset = 0;
391
+ this.numTileModels = 0;
392
+ this.totalResults = 0;
393
+ this.endOfDataReached = false;
394
+
395
+ this.host.requestUpdate();
396
+ }
397
+
307
398
  /**
308
399
  * @inheritdoc
309
400
  */
@@ -343,6 +434,9 @@ export class CollectionBrowserDataSource
343
434
  return this.pages[pageNum]?.[indexOnPage];
344
435
  }
345
436
 
437
+ /**
438
+ * @inheritdoc
439
+ */
346
440
  indexOf(tile: TileModel): number {
347
441
  return Object.values(this.pages).flat().indexOf(tile);
348
442
  }
@@ -355,35 +449,25 @@ export class CollectionBrowserDataSource
355
449
  this.pageSize = pageSize;
356
450
  }
357
451
 
358
- /**
359
- * @inheritdoc
360
- */
361
- reset(): void {
362
- this.pages = {};
363
- this.aggregations = {};
364
- this.yearHistogramAggregation = undefined;
365
- this.pageFetchesInProgress = {};
366
- this.pageElements = undefined;
367
- this.parentCollections = [];
368
- this.prefixFilterCountMap = {};
369
-
370
- this.offset = 0;
371
- this.numTileModels = 0;
372
- this.totalResults = 0;
373
- this.endOfDataReached = false;
374
-
375
- this.host.requestUpdate();
376
- }
377
-
378
452
  /**
379
453
  * @inheritdoc
380
454
  */
381
455
  async handleQueryChange(): Promise<void> {
382
456
  this.reset();
457
+
458
+ // Reset the `initialSearchComplete` promise with a new value for the imminent search
459
+ this._initialSearchCompletePromise = new Promise(res => {
460
+ this._initialSearchCompleteResolver = res;
461
+ });
462
+
463
+ // Fire the initial page & facet requests
383
464
  await Promise.all([
384
465
  this.doInitialPageFetch(),
385
466
  this.host.suppressFacets ? null : this.fetchFacets(),
386
467
  ]);
468
+
469
+ // Resolve the `initialSearchComplete` promise for this search
470
+ this._initialSearchCompleteResolver(true);
387
471
  }
388
472
 
389
473
  /**
@@ -401,26 +485,35 @@ export class CollectionBrowserDataSource
401
485
  ])
402
486
  );
403
487
  this.host.requestUpdate();
488
+ this.host.refreshVisibleResults();
404
489
  }
405
490
 
406
491
  /**
407
492
  * @inheritdoc
408
493
  */
409
- checkAllTiles(): void {
410
- this.map(model => ({ ...model, checked: true }));
411
- }
494
+ checkAllTiles = (): void => {
495
+ this.map(model => {
496
+ const cloned = model.clone();
497
+ cloned.checked = true;
498
+ return cloned;
499
+ });
500
+ };
412
501
 
413
502
  /**
414
503
  * @inheritdoc
415
504
  */
416
- uncheckAllTiles(): void {
417
- this.map(model => ({ ...model, checked: false }));
418
- }
505
+ uncheckAllTiles = (): void => {
506
+ this.map(model => {
507
+ const cloned = model.clone();
508
+ cloned.checked = false;
509
+ return cloned;
510
+ });
511
+ };
419
512
 
420
513
  /**
421
514
  * @inheritdoc
422
515
  */
423
- removeCheckedTiles(): void {
516
+ removeCheckedTiles = (): void => {
424
517
  // To make sure our data source remains page-aligned, we will offset our data source by
425
518
  // the number of removed tiles, so that we can just add the offset when the infinite
426
519
  // scroller queries for cell contents.
@@ -458,7 +551,8 @@ export class CollectionBrowserDataSource
458
551
  this.pages = newPages;
459
552
  this.numTileModels -= numChecked;
460
553
  this.host.requestUpdate();
461
- }
554
+ this.host.refreshVisibleResults();
555
+ };
462
556
 
463
557
  /**
464
558
  * @inheritdoc
@@ -526,15 +620,15 @@ export class CollectionBrowserDataSource
526
620
  * - Any currently-applied prefix filters
527
621
  * - The current sort options
528
622
  *
529
- * This lets us keep track of queries so we don't persist data that's
530
- * no longer relevant.
623
+ * This lets us internally keep track of queries so we don't persist data that's
624
+ * no longer relevant. Not meant to be human-readable.
531
625
  */
532
626
  get pageFetchQueryKey(): string {
533
- const profileKey = `${this.host.withinProfile}--${this.host.profileElement}`;
627
+ const profileKey = `pf;${this.host.withinProfile}--pe;${this.host.profileElement}`;
534
628
  const pageTarget = this.host.withinCollection ?? profileKey;
535
629
  const sortField = this.host.sortParam?.field ?? 'none';
536
630
  const sortDirection = this.host.sortParam?.direction ?? 'none';
537
- return `${this.fullQuery}-${pageTarget}-${this.host.searchType}-${sortField}-${sortDirection}`;
631
+ return `fq:${this.fullQuery}-pt:${pageTarget}-st:${this.host.searchType}-sf:${sortField}-sd:${sortDirection}`;
538
632
  }
539
633
 
540
634
  /**
@@ -810,8 +904,10 @@ export class CollectionBrowserDataSource
810
904
  * the current search state.
811
905
  */
812
906
  private async fetchFacets(): Promise<void> {
907
+ console.log('fetchFacets', this.id, this.host.profileElement);
813
908
  const trimmedQuery = this.host.baseQuery?.trim();
814
909
  if (!this.canPerformSearch) return;
910
+ console.log('will actually fetch facets');
815
911
 
816
912
  const { facetFetchQueryKey } = this;
817
913
 
@@ -843,7 +939,10 @@ export class CollectionBrowserDataSource
843
939
  // likely no longer valid for the newer query.
844
940
  const queryChangedSinceFetch =
845
941
  facetFetchQueryKey !== this.facetFetchQueryKey;
846
- if (queryChangedSinceFetch) return;
942
+ if (queryChangedSinceFetch) {
943
+ console.log('facet query has changed since fetch, returning. new/old:', this.facetFetchQueryKey, facetFetchQueryKey);
944
+ return;
945
+ }
847
946
 
848
947
  if (!success) {
849
948
  const errorMsg = searchResponse?.error?.message;
@@ -857,6 +956,7 @@ export class CollectionBrowserDataSource
857
956
  );
858
957
  }
859
958
 
959
+ this.host.setFacetsLoading(false);
860
960
  return;
861
961
  }
862
962
 
@@ -897,11 +997,13 @@ export class CollectionBrowserDataSource
897
997
  async fetchPage(pageNumber: number, numInitialPages = 1): Promise<void> {
898
998
  console.log(
899
999
  `fetchPage(${pageNumber})`,
1000
+ this.id,
900
1001
  this.canPerformSearch,
901
1002
  this.hasPage(pageNumber),
902
1003
  this.endOfDataReached,
903
1004
  this.host.baseQuery,
904
- JSON.stringify(this.host.selectedFacets)
1005
+ JSON.stringify(this.host.selectedFacets),
1006
+ this.pageFetchQueryKey
905
1007
  );
906
1008
  const trimmedQuery = this.host.baseQuery?.trim();
907
1009
  if (!this.canPerformSearch) return;
@@ -930,6 +1032,7 @@ export class CollectionBrowserDataSource
930
1032
  pageFetches.add(pageNumber + i);
931
1033
  }
932
1034
  this.pageFetchesInProgress[pageFetchQueryKey] = pageFetches;
1035
+ this.previousQueryKey = pageFetchQueryKey;
933
1036
 
934
1037
  const sortParams = this.host.sortParam ? [this.host.sortParam] : [];
935
1038
  const params: SearchParams = {
@@ -990,6 +1093,10 @@ export class CollectionBrowserDataSource
990
1093
  }
991
1094
 
992
1095
  if (this.host.withinCollection) {
1096
+ console.log(
1097
+ 'host is within collection, setting collection info:',
1098
+ success.response.collectionExtraInfo
1099
+ );
993
1100
  this.collectionExtraInfo = success.response.collectionExtraInfo;
994
1101
 
995
1102
  // For collections, we want the UI to respect the default sort option
@@ -1004,10 +1111,17 @@ export class CollectionBrowserDataSource
1004
1111
  } else if (this.host.withinProfile) {
1005
1112
  console.log(
1006
1113
  'host is within profile, setting acct info:',
1007
- success.response.accountExtraInfo
1114
+ success.response.accountExtraInfo,
1115
+ success.response.pageElements
1008
1116
  );
1009
1117
  this.accountExtraInfo = success.response.accountExtraInfo;
1010
1118
  this.pageElements = success.response.pageElements;
1119
+ } else {
1120
+ console.log(
1121
+ 'not within profile/collxn',
1122
+ this.host.withinCollection,
1123
+ this.host.withinProfile
1124
+ );
1011
1125
  }
1012
1126
 
1013
1127
  const { results, collectionTitles } = success.response;
@@ -1035,6 +1149,7 @@ export class CollectionBrowserDataSource
1035
1149
  // temporary estimates based on pages rendered so far).
1036
1150
  const resultCountDiscrepancy = numRows - results.length;
1037
1151
  if (resultCountDiscrepancy > 0) {
1152
+ console.log('End of data reached');
1038
1153
  this.endOfDataReached = true;
1039
1154
  this.host.setTileCount(this.totalResults);
1040
1155
  }
@@ -1063,56 +1178,7 @@ export class CollectionBrowserDataSource
1063
1178
  const tiles: TileModel[] = [];
1064
1179
  results?.forEach(result => {
1065
1180
  if (!result.identifier) return;
1066
-
1067
- let loginRequired = false;
1068
- let contentWarning = false;
1069
- // Check if item and item in "modifying" collection, setting above flags
1070
- if (
1071
- result.collection?.values.length &&
1072
- result.mediatype?.value !== 'collection'
1073
- ) {
1074
- for (const collection of result.collection?.values ?? []) {
1075
- if (collection === 'loggedin') {
1076
- loginRequired = true;
1077
- if (contentWarning) break;
1078
- }
1079
- if (collection === 'no-preview') {
1080
- contentWarning = true;
1081
- if (loginRequired) break;
1082
- }
1083
- }
1084
- }
1085
-
1086
- tiles.push({
1087
- averageRating: result.avg_rating?.value,
1088
- checked: false,
1089
- collections: result.collection?.values ?? [],
1090
- collectionFilesCount: result.collection_files_count?.value ?? 0,
1091
- collectionSize: result.collection_size?.value ?? 0,
1092
- commentCount: result.num_reviews?.value ?? 0,
1093
- creator: result.creator?.value,
1094
- creators: result.creator?.values ?? [],
1095
- dateAdded: result.addeddate?.value,
1096
- dateArchived: result.publicdate?.value,
1097
- datePublished: result.date?.value,
1098
- dateReviewed: result.reviewdate?.value,
1099
- description: result.description?.values.join('\n'),
1100
- favCount: result.num_favorites?.value ?? 0,
1101
- href: this.collapseRepeatedQuotes(result.__href__?.value),
1102
- identifier: result.identifier,
1103
- issue: result.issue?.value,
1104
- itemCount: result.item_count?.value ?? 0,
1105
- mediatype: this.getMediatype(result),
1106
- snippets: result.highlight?.values ?? [],
1107
- source: result.source?.value,
1108
- subjects: result.subject?.values ?? [],
1109
- title: result.title?.value ?? '',
1110
- volume: result.volume?.value,
1111
- viewCount: result.downloads?.value ?? 0,
1112
- weeklyViewCount: result.week?.value,
1113
- loginRequired,
1114
- contentWarning,
1115
- });
1181
+ tiles.push(new TileModel(result));
1116
1182
  });
1117
1183
  this.addPage(pageNumber, tiles);
1118
1184
  const visiblePages = this.host.currentVisiblePageNumbers;
@@ -1122,44 +1188,6 @@ export class CollectionBrowserDataSource
1122
1188
  }
1123
1189
  }
1124
1190
 
1125
- /**
1126
- * Returns the mediatype string for the given search result, taking into account
1127
- * the special `favorited_search` hit type.
1128
- * @param result The search result to extract a mediatype from
1129
- */
1130
- private getMediatype(result: SearchResult): MediaType {
1131
- /**
1132
- * hit_type == 'favorited_search' is basically a new hit_type
1133
- * - we are getting from PPS.
1134
- * - which gives response for fav- collection
1135
- * - having favorited items like account/collection/item etc..
1136
- * - as user can also favorite a search result (a search page)
1137
- * - so we need to have response (having fav- items and fav- search results)
1138
- *
1139
- * if backend hit_type == 'favorited_search'
1140
- * - let's assume a "search" as new mediatype
1141
- */
1142
- if (result?.rawMetadata?.hit_type === 'favorited_search') {
1143
- return 'search';
1144
- }
1145
-
1146
- return result.mediatype?.value ?? 'data';
1147
- }
1148
-
1149
- /**
1150
- * Returns the input string, but removing one set of quotes from all instances of
1151
- * ""clauses wrapped in two sets of quotes"". This assumes the quotes are already
1152
- * URL-encoded.
1153
- *
1154
- * This should be a temporary measure to address the fact that the __href__ field
1155
- * sometimes acquires extra quotation marks during query rewriting. Once there is a
1156
- * full Lucene parser in place that handles quoted queries correctly, this can likely
1157
- * be removed.
1158
- */
1159
- private collapseRepeatedQuotes(str?: string): string | undefined {
1160
- return str?.replace(/%22%22(?!%22%22)(.+?)%22%22/g, '%22$1%22');
1161
- }
1162
-
1163
1191
  /**
1164
1192
  * Fetches the aggregation buckets for the given prefix filter type.
1165
1193
  */
@@ -1,5 +1,6 @@
1
1
  import type {
2
2
  CollectionExtraInfo,
3
+ PageElementName,
3
4
  PageType,
4
5
  SearchServiceInterface,
5
6
  SearchType,
@@ -7,6 +8,7 @@ import type {
7
8
  SortParam,
8
9
  } from '@internetarchive/search-service';
9
10
  import type { SelectedFacets, SortField } from '../models';
11
+ import type { CollectionBrowserDataSourceInterface } from './collection-browser-data-source';
10
12
 
11
13
  /**
12
14
  * A Map from collection identifiers to their corresponding collection titles.
@@ -30,7 +32,7 @@ export type PageSpecifierParams = {
30
32
  * Which specific elements of a profile page to fetch. Corresponds to individual tab data
31
33
  * (e.g., "uploads", "reviews", ...)
32
34
  */
33
- pageElements?: string[];
35
+ pageElements?: PageElementName[];
34
36
  };
35
37
 
36
38
  /**
@@ -40,7 +42,7 @@ export interface CollectionBrowserQueryState {
40
42
  baseQuery?: string;
41
43
  withinCollection?: string;
42
44
  withinProfile?: string;
43
- profileElement?: string;
45
+ profileElement?: PageElementName;
44
46
  searchType: SearchType;
45
47
  selectedFacets?: SelectedFacets;
46
48
  minSelectedDate?: string;
@@ -63,6 +65,8 @@ export interface CollectionBrowserSearchInterface
63
65
  readonly suppressFacets?: boolean;
64
66
  readonly initialPageNumber: number;
65
67
  readonly currentVisiblePageNumbers: number[];
68
+ readonly clearResultsOnEmptyQuery?: boolean;
69
+ readonly dataSource: CollectionBrowserDataSourceInterface;
66
70
 
67
71
  getSessionId(): Promise<string>;
68
72
  setSearchResultsLoading(loading: boolean): void;
@@ -6,7 +6,7 @@ import { when } from 'lit/directives/when.js';
6
6
  export interface ManageableItem {
7
7
  identifier: string;
8
8
  title?: string;
9
- date?: string;
9
+ dateStr?: string;
10
10
  }
11
11
 
12
12
  @customElement('manage-bar')