@internetarchive/collection-browser 4.1.1-alpha-webdev8185.1 → 4.1.1

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/index.ts CHANGED
@@ -6,15 +6,10 @@ export { SortFilterBar } from './src/sort-filter-bar/sort-filter-bar';
6
6
  export {
7
7
  CollectionDisplayMode,
8
8
  SortField,
9
- ExplicitSortField,
10
9
  TileModel,
11
10
  FacetOption,
12
11
  SelectedFacets,
13
12
  getDefaultSelectedFacets,
14
- sortOptionFromAPIString,
15
- resolveCollectionDefaultSort,
16
- SORT_OPTIONS,
17
- defaultProfileElementSorts,
18
13
  } from './src/models';
19
14
  export { CollectionBrowserLoadingTile } from './src/tiles/collection-browser-loading-tile';
20
15
  export { CollectionTile } from './src/tiles/grid/collection-tile';
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "The Internet Archive Collection Browser.",
4
4
  "license": "AGPL-3.0-only",
5
5
  "author": "Internet Archive",
6
- "version": "4.1.1-alpha-webdev8185.1",
6
+ "version": "4.1.1",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/index.js",
9
9
  "scripts": {
@@ -36,13 +36,14 @@ import type { IAComboBox } from '@internetarchive/elements/ia-combo-box/ia-combo
36
36
  import {
37
37
  SelectedFacets,
38
38
  SortField,
39
- type ExplicitSortField,
40
39
  CollectionBrowserContext,
41
40
  getDefaultSelectedFacets,
42
41
  TileModel,
43
42
  CollectionDisplayMode,
44
43
  FacetEventDetails,
44
+ sortOptionFromAPIString,
45
45
  SORT_OPTIONS,
46
+ defaultProfileElementSorts,
46
47
  FacetLoadStrategy,
47
48
  defaultFacetDisplayOrder,
48
49
  tvFacetDisplayOrder,
@@ -150,8 +151,10 @@ export class CollectionBrowser
150
151
 
151
152
  @property({ type: String }) sortDirection: SortDirection | null = null;
152
153
 
153
- @property({ type: String }) defaultSortField: ExplicitSortField =
154
- SortField.relevance;
154
+ @property({ type: String }) defaultSortField: Exclude<
155
+ SortField,
156
+ SortField.default
157
+ > = SortField.relevance;
155
158
 
156
159
  @property({ type: String }) defaultSortDirection: SortDirection | null = null;
157
160
 
@@ -598,6 +601,10 @@ export class CollectionBrowser
598
601
 
599
602
  willUpdate(changed: PropertyValues): void {
600
603
  this.setPlaceholderType();
604
+
605
+ if (changed.has('searchType') && this.searchType === SearchType.TV) {
606
+ this.applyDefaultTVSearchSort();
607
+ }
601
608
  }
602
609
 
603
610
  render() {
@@ -1639,12 +1646,6 @@ export class CollectionBrowser
1639
1646
  this.maxSelectedDate = queryState.maxSelectedDate;
1640
1647
  this.selectedSort = queryState.selectedSort ?? SortField.default;
1641
1648
  this.sortDirection = queryState.sortDirection;
1642
- if (queryState.defaultSortField) {
1643
- this.defaultSortField = queryState.defaultSortField;
1644
- }
1645
- if (queryState.defaultSortDirection !== undefined) {
1646
- this.defaultSortDirection = queryState.defaultSortDirection;
1647
- }
1648
1649
  this.selectedTitleFilter = queryState.selectedTitleFilter;
1649
1650
  this.selectedCreatorFilter = queryState.selectedCreatorFilter;
1650
1651
 
@@ -1755,6 +1756,21 @@ export class CollectionBrowser
1755
1756
  }
1756
1757
  }
1757
1758
 
1759
+ if (changed.has('profileElement')) {
1760
+ this.applyDefaultProfileSort();
1761
+ }
1762
+
1763
+ if (changed.has('withinCollection') && this.withinCollection) {
1764
+ // Set a sensible default collection sort while we load results, which we will later
1765
+ // adjust based on any sort-by metadata once the response arrives.
1766
+ if (!this.baseQuery) {
1767
+ this.defaultSortField = this.withinCollection.startsWith('fav-')
1768
+ ? SortField.datefavorited
1769
+ : SortField.weeklyview;
1770
+ this.defaultSortDirection = 'desc';
1771
+ }
1772
+ }
1773
+
1758
1774
  if (changed.has('baseQuery')) {
1759
1775
  this.emitBaseQueryChanged();
1760
1776
  }
@@ -2067,22 +2083,6 @@ export class CollectionBrowser
2067
2083
  );
2068
2084
  }
2069
2085
 
2070
- /**
2071
- * Emits a `collectionExtraInfoLoaded` event when the data source has received
2072
- * collection metadata from the backend. This allows parent components to react
2073
- * to the metadata (e.g., to update their default sort based on the collection's
2074
- * `sort-by` metadata field).
2075
- */
2076
- emitCollectionExtraInfoLoaded(
2077
- collectionExtraInfo?: CollectionExtraInfo,
2078
- ): void {
2079
- this.dispatchEvent(
2080
- new CustomEvent('collectionExtraInfoLoaded', {
2081
- detail: collectionExtraInfo,
2082
- }),
2083
- );
2084
- }
2085
-
2086
2086
  /**
2087
2087
  * Emits a `queryStateChanged` event indicating that one or more of this component's
2088
2088
  * properties have changed in a way that could affect the set of search results.
@@ -2382,6 +2382,75 @@ export class CollectionBrowser
2382
2382
  }
2383
2383
  }
2384
2384
 
2385
+ /**
2386
+ * Applies the default sort options for the TV search results page
2387
+ */
2388
+ applyDefaultTVSearchSort(): void {
2389
+ this.defaultSortField = SortField.datearchived;
2390
+ this.defaultSortDirection = 'desc';
2391
+ }
2392
+
2393
+ /**
2394
+ * Applies any default sort option for the current collection, by checking
2395
+ * for one in the collection's metadata. If none is found, defaults to sorting
2396
+ * descending by:
2397
+ * - Date Favorited for fav-* collections
2398
+ * - Weekly views for all other collections
2399
+ */
2400
+ applyDefaultCollectionSort(collectionInfo?: CollectionExtraInfo): void {
2401
+ if (this.baseQuery) {
2402
+ // If there's a query set, then we default to relevance sorting regardless of
2403
+ // the collection metadata-specified sort.
2404
+ this.defaultSortField = SortField.relevance;
2405
+ this.defaultSortDirection = null;
2406
+ return;
2407
+ }
2408
+
2409
+ // Favorite collections sort on Date Favorited by default.
2410
+ // Other collections fall back to sorting on weekly views.
2411
+ const baseDefaultSort: string =
2412
+ collectionInfo?.public_metadata?.identifier?.startsWith('fav-')
2413
+ ? '-favoritedate'
2414
+ : '-week';
2415
+
2416
+ // The collection metadata may override the default sorting with something else
2417
+ const metadataSort: string | undefined =
2418
+ collectionInfo?.public_metadata?.['sort-by'];
2419
+
2420
+ // Prefer the metadata-specified sort if one exists
2421
+ const defaultSortToApply = metadataSort ?? baseDefaultSort;
2422
+
2423
+ // Account for both -field and field:dir formats
2424
+ let [field, dir] = defaultSortToApply.split(':');
2425
+ if (field.startsWith('-')) {
2426
+ field = field.slice(1);
2427
+ dir = 'desc';
2428
+ } else if (!['asc', 'desc'].includes(dir)) {
2429
+ dir = 'asc';
2430
+ }
2431
+
2432
+ const sortOption = sortOptionFromAPIString(field);
2433
+ const sortField = sortOption.field;
2434
+ if (sortField && sortField !== SortField.default) {
2435
+ this.defaultSortField = sortField;
2436
+ this.defaultSortDirection = dir as SortDirection;
2437
+ }
2438
+ }
2439
+
2440
+ /**
2441
+ * Applies the default sort option for the current profile element
2442
+ */
2443
+ applyDefaultProfileSort(): void {
2444
+ if (this.profileElement) {
2445
+ const defaultSortField = defaultProfileElementSorts[this.profileElement];
2446
+ this.defaultSortField = defaultSortField ?? SortField.weeklyview;
2447
+ } else {
2448
+ this.defaultSortField = SortField.weeklyview;
2449
+ }
2450
+
2451
+ this.defaultSortDirection = 'desc';
2452
+ }
2453
+
2385
2454
  /**
2386
2455
  * This is useful for determining whether we need to reload the scroller.
2387
2456
  *
@@ -1194,9 +1194,10 @@ export class CollectionBrowserDataSource
1194
1194
  if (withinCollection) {
1195
1195
  this.collectionExtraInfo = success.response.collectionExtraInfo;
1196
1196
 
1197
- // Emit the collection metadata so the parent page can set default sort
1197
+ // For collections, we want the UI to respect the default sort option
1198
+ // which can be specified in metadata, or otherwise assumed to be week:desc
1198
1199
  if (this.activeOnHost) {
1199
- this.host.emitCollectionExtraInfoLoaded(this.collectionExtraInfo);
1200
+ this.host.applyDefaultCollectionSort(this.collectionExtraInfo);
1200
1201
  }
1201
1202
 
1202
1203
  if (this.collectionExtraInfo) {
@@ -6,12 +6,7 @@ import type {
6
6
  SortDirection,
7
7
  SortParam,
8
8
  } from '@internetarchive/search-service';
9
- import type {
10
- ExplicitSortField,
11
- FacetLoadStrategy,
12
- SelectedFacets,
13
- SortField,
14
- } from '../models';
9
+ import type { FacetLoadStrategy, SelectedFacets, SortField } from '../models';
15
10
  import type { CollectionBrowserDataSourceInterface } from './collection-browser-data-source-interface';
16
11
 
17
12
  /**
@@ -32,8 +27,6 @@ export interface CollectionBrowserQueryState {
32
27
  selectedCreatorFilter: string | null;
33
28
  selectedSort?: SortField;
34
29
  sortDirection: SortDirection | null;
35
- defaultSortField?: ExplicitSortField;
36
- defaultSortDirection?: SortDirection | null;
37
30
  }
38
31
 
39
32
  /**
@@ -45,7 +38,7 @@ export interface CollectionBrowserSearchInterface
45
38
  searchService?: SearchServiceInterface;
46
39
  isTVCollection: boolean;
47
40
  readonly sortParam: SortParam | null;
48
- readonly defaultSortField: ExplicitSortField;
41
+ readonly defaultSortField: SortField | null;
49
42
  readonly defaultSortDirection: SortDirection | null;
50
43
  readonly facetLoadStrategy: FacetLoadStrategy;
51
44
  readonly initialPageNumber: number;
@@ -59,9 +52,7 @@ export interface CollectionBrowserSearchInterface
59
52
  setFacetsLoading(loading: boolean): void;
60
53
  setTotalResultCount(count: number): void;
61
54
  setTileCount(count: number): void;
62
- emitCollectionExtraInfoLoaded(
63
- collectionExtraInfo?: CollectionExtraInfo,
64
- ): void;
55
+ applyDefaultCollectionSort(collectionInfo?: CollectionExtraInfo): void;
65
56
  emitEmptyResults(): void;
66
57
  emitSearchError(): void;
67
58
  emitQueryStateChanged(): void;
package/src/models.ts CHANGED
@@ -3,7 +3,6 @@ import { msg } from '@lit/localize';
3
3
  import type { MediaType } from '@internetarchive/field-parsers';
4
4
  import {
5
5
  AggregationSortType,
6
- CollectionExtraInfo,
7
6
  HitType,
8
7
  SearchReview,
9
8
  SearchResult,
@@ -323,16 +322,6 @@ export enum SortField {
323
322
  'creator' = 'creator',
324
323
  }
325
324
 
326
- /**
327
- * A sort field other than the abstract "default" placeholder.
328
- * This is useful because the "default" sort field is just an indicator to
329
- * revert to an explicitly defined fallback value. So when defining default
330
- * sort logic, this type should be preferred to avoid accidentally permitting
331
- * that fallback to itself equal the "default" placeholder (which would be
332
- * rather circular/ill-defined).
333
- */
334
- export type ExplicitSortField = Exclude<SortField, SortField.default>;
335
-
336
325
  /**
337
326
  * Views-related sort fields
338
327
  */
@@ -564,47 +553,6 @@ export function sortOptionFromAPIString(sortName?: string | null): SortOption {
564
553
  );
565
554
  }
566
555
 
567
- /**
568
- * Resolves the default sort option for a collection based on its metadata.
569
- *
570
- * - Favorite collections (`fav-*`) default to Date Favorited descending.
571
- * - Other collections default to Weekly Views descending.
572
- * - If the collection metadata specifies a `sort-by` field, that overrides the above.
573
- *
574
- * Supports both `-field` (dash prefix = desc) and `field:dir` metadata formats.
575
- *
576
- * Note: This does NOT handle the "relevance when a query is present" rule,
577
- * which is managed separately by collection-browser itself.
578
- */
579
- export function resolveCollectionDefaultSort(
580
- collectionInfo?: CollectionExtraInfo,
581
- ): { field: ExplicitSortField; direction: SortDirection } {
582
- const isFav = collectionInfo?.public_metadata?.identifier?.startsWith('fav-');
583
- const baseDefaultSort: string = isFav ? '-favoritedate' : '-week';
584
- const metadataSort: string | undefined =
585
- collectionInfo?.public_metadata?.['sort-by'];
586
- const defaultSortToApply = metadataSort ?? baseDefaultSort;
587
-
588
- // Account for both -field and field:dir formats
589
- let [field, dir] = defaultSortToApply.split(':');
590
- if (field.startsWith('-')) {
591
- field = field.slice(1);
592
- dir = 'desc';
593
- } else if (!['asc', 'desc'].includes(dir)) {
594
- dir = 'asc';
595
- }
596
-
597
- const sortOption = sortOptionFromAPIString(field);
598
- const sortField = sortOption.field;
599
- if (sortField && sortField !== SortField.default) {
600
- return {
601
- field: sortField as ExplicitSortField,
602
- direction: dir as SortDirection,
603
- };
604
- }
605
- return { field: SortField.weeklyview, direction: 'desc' };
606
- }
607
-
608
556
  export const defaultSortAvailability: Record<SortField, boolean> = {
609
557
  [SortField.relevance]: true,
610
558
  [SortField.weeklyview]: true,
@@ -632,7 +580,10 @@ export const tvSortAvailability: Record<SortField, boolean> = {
632
580
  [SortField.dateadded]: false,
633
581
  };
634
582
 
635
- export const defaultProfileElementSorts: Record<string, ExplicitSortField> = {
583
+ export const defaultProfileElementSorts: Record<
584
+ string,
585
+ Exclude<SortField, SortField.default>
586
+ > = {
636
587
  uploads: SortField.datearchived,
637
588
  reviews: SortField.datereviewed,
638
589
  collections: SortField.datearchived,