diff --git a/src/collection-browser.ts b/src/collection-browser.ts index 87305b7fc..1dec79ddb 100644 --- a/src/collection-browser.ts +++ b/src/collection-browser.ts @@ -122,8 +122,6 @@ export class CollectionBrowser */ @property({ type: String }) displayMode?: CollectionDisplayMode; - @property({ type: Object }) defaultSortParam: SortParam | null = null; - @property({ type: String }) selectedSort: SortField = SortField.default; @property({ type: String }) selectedTitleFilter: string | null = null; @@ -132,6 +130,13 @@ export class CollectionBrowser @property({ type: String }) sortDirection: SortDirection | null = null; + @property({ type: String }) defaultSortField: Exclude< + SortField, + SortField.default + > = SortField.relevance; + + @property({ type: String }) defaultSortDirection: SortDirection | null = null; + @property({ type: Number }) pageSize = 50; @property({ type: Number }) currentPage?: number; @@ -278,11 +283,6 @@ export class CollectionBrowser @state() private contentWidth?: number; - @state() private defaultSortField: Exclude = - SortField.relevance; - - @state() private defaultSortDirection: SortDirection | null = null; - @state() private placeholderType: PlaceholderType = null; @query('#content-container') private contentContainer!: HTMLDivElement; @@ -844,6 +844,17 @@ export class CollectionBrowser return { field: sortField, direction: this.sortDirection }; } + /** + * An object representing the default sort field & direction, if none are explicitly set. + */ + get defaultSortParam(): SortParam | null { + const direction = this.defaultSortDirection ?? 'asc'; + const field = SORT_OPTIONS[this.defaultSortField].searchServiceKey; + if (!field) return null; + + return { field, direction }; + } + /** * Handler for when the display mode option is changed (grid/list/compact-list views). */ @@ -1876,10 +1887,6 @@ export class CollectionBrowser if (sortField && sortField !== SortField.default) { this.defaultSortField = sortField; this.defaultSortDirection = dir as SortDirection; - this.defaultSortParam = { - field: this.defaultSortField, - direction: this.defaultSortDirection, - }; } } @@ -1895,10 +1902,6 @@ export class CollectionBrowser } this.defaultSortDirection = 'desc'; - this.defaultSortParam = { - field: this.defaultSortField, - direction: this.defaultSortDirection, - }; } /** diff --git a/src/data-source/collection-browser-data-source.ts b/src/data-source/collection-browser-data-source.ts index c5c14b3a6..2d82f9454 100644 --- a/src/data-source/collection-browser-data-source.ts +++ b/src/data-source/collection-browser-data-source.ts @@ -1025,9 +1025,8 @@ export class CollectionBrowserDataSource // TODO eventually the PPS should handle these defaults natively const isDefaultProfileSort = this.host.withinProfile && this.host.selectedSort === SortField.default; - if (isDefaultProfileSort && this.host.defaultSortParam) { - const sortOption = - SORT_OPTIONS[this.host.defaultSortParam.field as SortField]; + if (isDefaultProfileSort && this.host.defaultSortField) { + const sortOption = SORT_OPTIONS[this.host.defaultSortField]; if (sortOption.searchServiceKey) { sortParams = [ { diff --git a/src/data-source/collection-browser-query-state.ts b/src/data-source/collection-browser-query-state.ts index bfd056a02..6dbb8f802 100644 --- a/src/data-source/collection-browser-query-state.ts +++ b/src/data-source/collection-browser-query-state.ts @@ -35,7 +35,7 @@ export interface CollectionBrowserSearchInterface extends CollectionBrowserQueryState { searchService?: SearchServiceInterface; readonly sortParam: SortParam | null; - readonly defaultSortParam: SortParam | null; + readonly defaultSortField: SortField | null; readonly facetLoadStrategy: FacetLoadStrategy; readonly initialPageNumber: number; readonly currentVisiblePageNumbers: number[]; diff --git a/src/tiles/base-tile-component.ts b/src/tiles/base-tile-component.ts index 3a22d2399..9c320a996 100644 --- a/src/tiles/base-tile-component.ts +++ b/src/tiles/base-tile-component.ts @@ -36,13 +36,14 @@ export abstract class BaseTileComponent extends LitElement { changed.has('baseNavigationUrl') || changed.has('collectionPagePath') || changed.has('sortParam') || + changed.has('defaultSortParam') || changed.has('creatorFilter') ) { this.displayValueProvider = new TileDisplayValueProvider({ model: this.model, baseNavigationUrl: this.baseNavigationUrl, collectionPagePath: this.collectionPagePath, - sortParam: this.sortParam ?? undefined, + sortParam: this.sortParam ?? this.defaultSortParam ?? undefined, creatorFilter: this.creatorFilter, }); } diff --git a/src/tiles/grid/item-tile.ts b/src/tiles/grid/item-tile.ts index f6323ffc4..ce7803765 100644 --- a/src/tiles/grid/item-tile.ts +++ b/src/tiles/grid/item-tile.ts @@ -5,6 +5,7 @@ import { ifDefined } from 'lit/directives/if-defined.js'; import { msg } from '@lit/localize'; import { map } from 'lit/directives/map.js'; +import type { SortParam } from '@internetarchive/search-service'; import { DateFormat, formatDate } from '../../utils/format-date'; import { isFirstMillisecondOfUTCYear } from '../../utils/local-date-from-utc'; import { BaseTileComponent } from '../base-tile-component'; @@ -28,6 +29,7 @@ export class ItemTile extends BaseTileComponent { * - baseImageUrl?: string; * - collectionPagePath?: string; * - sortParam: SortParam | null = null; + * - defaultSortParam: SortParam | null = null; * - creatorFilter?: string; * - mobileBreakpoint?: number; * - loggedIn = false; @@ -37,8 +39,9 @@ export class ItemTile extends BaseTileComponent { render() { const itemTitle = this.model?.title; + const effectiveSort = this.sortParam ?? this.defaultSortParam; const [viewCount, viewLabel] = - this.sortParam?.field === 'week' + effectiveSort?.field === 'week' ? [this.model?.weeklyViewCount, 'weekly views'] : [this.model?.viewCount, 'all-time views']; @@ -110,7 +113,7 @@ export class ItemTile extends BaseTileComponent { private get sortedDateInfoTemplate() { let sortedValue; let format: DateFormat = 'long'; - switch (this.sortParam?.field) { + switch (this.effectiveSort?.field) { case 'date': { const datePublished = this.model?.datePublished; sortedValue = { field: 'published', value: datePublished }; @@ -212,10 +215,17 @@ export class ItemTile extends BaseTileComponent { private get isSortedByDate(): boolean { return ['date', 'reviewdate', 'addeddate', 'publicdate'].includes( - this.sortParam?.field as string + this.effectiveSort?.field as string ); } + /** + * Returns the active sort param if one is set, or the default sort param otherwise. + */ + private get effectiveSort(): SortParam | null { + return this.sortParam ?? this.defaultSortParam; + } + private get hasSnippets(): boolean { return !!this.model?.snippets?.length; } diff --git a/src/tiles/grid/tile-stats.ts b/src/tiles/grid/tile-stats.ts index 1f278c2c8..8d724882f 100644 --- a/src/tiles/grid/tile-stats.ts +++ b/src/tiles/grid/tile-stats.ts @@ -18,7 +18,7 @@ export class TileStats extends LitElement { @property({ type: Number }) viewCount?: number; - @property({ type: String }) viewLabel?: number; + @property({ type: String }) viewLabel?: string; @property({ type: Number }) favCount?: number; diff --git a/src/tiles/list/tile-list-compact-header.ts b/src/tiles/list/tile-list-compact-header.ts index 1c90afd2b..94f9fad6c 100644 --- a/src/tiles/list/tile-list-compact-header.ts +++ b/src/tiles/list/tile-list-compact-header.ts @@ -25,7 +25,9 @@ export class TileListCompactHeader extends BaseTileComponent {
${msg('Title')}
${msg('Creator')}
-
${this.displayValueProvider.dateLabel}
+
+ ${this.displayValueProvider.dateLabel || msg('Published')} +
${msg('Type')}
${msg('Views')}
diff --git a/src/tiles/list/tile-list-compact.ts b/src/tiles/list/tile-list-compact.ts index 75f4ef3f2..6ae68e059 100644 --- a/src/tiles/list/tile-list-compact.ts +++ b/src/tiles/list/tile-list-compact.ts @@ -1,6 +1,7 @@ import { css, html, nothing } from 'lit'; import { customElement } from 'lit/decorators.js'; import DOMPurify from 'dompurify'; +import type { SortParam } from '@internetarchive/search-service'; import { BaseTileComponent } from '../base-tile-component'; import { formatCount, NumberFormat } from '../../utils/format-count'; @@ -21,6 +22,7 @@ export class TileListCompact extends BaseTileComponent { * - baseImageUrl?: string; * - collectionPagePath?: string; * - sortParam: SortParam | null = null; + * - defaultSortParam: SortParam | null = null; * - creatorFilter?: string; * - mobileBreakpoint?: number; * - loggedIn = false; @@ -91,7 +93,7 @@ export class TileListCompact extends BaseTileComponent { // In contrast, the search engine metadata uses 'date' to refer to the actual // publication date of the underlying media ("Date Published" in the UI). // Refer to the full metadata schema for more info. - switch (this.sortParam?.field) { + switch (this.effectiveSort?.field) { case 'publicdate': return this.model?.dateArchived; case 'reviewdate': @@ -104,11 +106,18 @@ export class TileListCompact extends BaseTileComponent { } private get views(): number | undefined { - return this.sortParam?.field === 'week' + return this.effectiveSort?.field === 'week' ? this.model?.weeklyViewCount // weekly views : this.model?.viewCount; // all-time views } + /** + * Returns the active sort param if one is set, or the default sort param otherwise. + */ + private get effectiveSort(): SortParam | null { + return this.sortParam ?? this.defaultSortParam; + } + private get classSize(): string { if ( this.mobileBreakpoint && @@ -125,7 +134,7 @@ export class TileListCompact extends BaseTileComponent { // This is because items with only a year for their publication date are normalized to // Jan 1 at midnight timestamps in the search engine documents. if ( - (!this.isSortedByDate || this.sortParam?.field === 'date') && // Any sort except dates that aren't published date + (!this.isSortedByDate || this.effectiveSort?.field === 'date') && // Any sort except dates that aren't published date isFirstMillisecondOfUTCYear(this.model?.datePublished) ) { return 'year-only'; @@ -146,7 +155,7 @@ export class TileListCompact extends BaseTileComponent { private get isSortedByDate(): boolean { return ['date', 'reviewdate', 'addeddate', 'publicdate'].includes( - this.sortParam?.field as string + this.effectiveSort?.field as string ); } diff --git a/src/tiles/list/tile-list.ts b/src/tiles/list/tile-list.ts index cbfd6dfae..5f6b6e32c 100644 --- a/src/tiles/list/tile-list.ts +++ b/src/tiles/list/tile-list.ts @@ -7,6 +7,7 @@ import { customElement, property, state } from 'lit/decorators.js'; import { msg } from '@lit/localize'; import DOMPurify from 'dompurify'; +import type { SortParam } from '@internetarchive/search-service'; import { suppressedCollections } from '../../models'; import type { CollectionTitles } from '../../data-source/models'; import { BaseTileComponent } from '../base-tile-component'; @@ -31,6 +32,7 @@ export class TileList extends BaseTileComponent { * - baseImageUrl?: string; * - collectionPagePath?: string; * - sortParam: SortParam | null = null; + * - defaultSortParam: SortParam | null = null; * - creatorFilter?: string; * - mobileBreakpoint?: number; * - loggedIn = false; @@ -224,10 +226,10 @@ export class TileList extends BaseTileComponent { // Except datePublished which is always shown private get dateSortByTemplate() { if ( - this.sortParam && - (this.sortParam.field === 'addeddate' || - this.sortParam.field === 'reviewdate' || - this.sortParam.field === 'publicdate') + this.effectiveSort && + (this.effectiveSort.field === 'addeddate' || + this.effectiveSort.field === 'reviewdate' || + this.effectiveSort.field === 'publicdate') ) { return this.metadataTemplate( formatDate(this.date, 'long'), @@ -239,7 +241,7 @@ export class TileList extends BaseTileComponent { private get viewsTemplate() { const viewCount = - this.sortParam?.field === 'week' + this.effectiveSort?.field === 'week' ? this.model?.weeklyViewCount // weekly views : this.model?.viewCount; // all-time views if (viewCount == null) return nothing; @@ -459,7 +461,7 @@ export class TileList extends BaseTileComponent { * @see src/models.ts */ private get date(): Date | undefined { - switch (this.sortParam?.field) { + switch (this.effectiveSort?.field) { case 'date': return this.model?.datePublished; case 'reviewdate': @@ -471,6 +473,13 @@ export class TileList extends BaseTileComponent { } } + /** + * Returns the active sort param if one is set, or the default sort param otherwise. + */ + private get effectiveSort(): SortParam | null { + return this.sortParam ?? this.defaultSortParam; + } + private get classSize(): string { if ( this.mobileBreakpoint && diff --git a/src/tiles/tile-dispatcher.ts b/src/tiles/tile-dispatcher.ts index fab32c61f..c6ee0b625 100644 --- a/src/tiles/tile-dispatcher.ts +++ b/src/tiles/tile-dispatcher.ts @@ -41,6 +41,7 @@ export class TileDispatcher * - baseImageUrl?: string; * - collectionPagePath?: string; * - sortParam: SortParam | null = null; + * - defaultSortParam: SortParam | null = null; * - creatorFilter?: string; * - mobileBreakpoint?: number; * - loggedIn = false; @@ -111,7 +112,7 @@ export class TileDispatcher @@ -334,7 +335,8 @@ export class TileDispatcher .currentWidth=${this.currentWidth} .currentHeight=${this.currentHeight} .baseImageUrl=${this.baseImageUrl} - .sortParam=${sortParam || defaultSortParam} + .sortParam=${sortParam} + .defaultSortParam=${defaultSortParam} .creatorFilter=${creatorFilter} .loggedIn=${this.loggedIn} .isManageView=${this.isManageView} @@ -350,7 +352,8 @@ export class TileDispatcher .currentWidth=${currentWidth} .currentHeight=${currentHeight} .baseNavigationUrl=${baseNavigationUrl} - .sortParam=${sortParam || defaultSortParam} + .sortParam=${sortParam} + .defaultSortParam=${defaultSortParam} .creatorFilter=${creatorFilter} .mobileBreakpoint=${mobileBreakpoint} .baseImageUrl=${this.baseImageUrl} @@ -365,7 +368,8 @@ export class TileDispatcher .currentWidth=${currentWidth} .currentHeight=${currentHeight} .baseNavigationUrl=${baseNavigationUrl} - .sortParam=${sortParam || defaultSortParam} + .sortParam=${sortParam} + .defaultSortParam=${defaultSortParam} .creatorFilter=${creatorFilter} .mobileBreakpoint=${mobileBreakpoint} .baseImageUrl=${this.baseImageUrl} diff --git a/test/collection-browser.test.ts b/test/collection-browser.test.ts index 7e389775c..8db424354 100644 --- a/test/collection-browser.test.ts +++ b/test/collection-browser.test.ts @@ -1111,7 +1111,7 @@ describe('Collection Browser', () => { el.applyDefaultProfileSort(); expect(el.defaultSortParam).to.deep.equal({ - field: SortField.weeklyview, + field: 'week', direction: 'desc', }); });