diff --git a/src/collection-browser.ts b/src/collection-browser.ts index b8b415f7a..90962c0a7 100644 --- a/src/collection-browser.ts +++ b/src/collection-browser.ts @@ -239,6 +239,13 @@ export class CollectionBrowser */ private isResizeToMobile = false; + /** + * Flag indicating that a new data source is currently being installed. + * During the install, any URL persistence operation should replace the current entry + * instead of creating a new one. + */ + private dataSourceInstallInProgress = false; + private leftColIntersectionObserver?: IntersectionObserver; private facetsIntersectionObserver?: IntersectionObserver; @@ -1009,8 +1016,12 @@ export class CollectionBrowser this.selectedTitleFilter = queryState.selectedTitleFilter; this.selectedCreatorFilter = queryState.selectedCreatorFilter; + // We set this flag during the update to prevent the URL state persistence + // from creating an unwanted extra history entry. + this.dataSourceInstallInProgress = true; this.requestUpdate(); await this.updateComplete; + this.dataSourceInstallInProgress = false; if (!this.searchResultsLoading) { this.setTotalResultCount(this.dataSource.totalResults); @@ -1021,7 +1032,6 @@ export class CollectionBrowser } firstUpdated(): void { - this.setupStateRestorationObserver(); this.restoreState(); } @@ -1175,6 +1185,11 @@ export class CollectionBrowser } } + connectedCallback(): void { + super.connectedCallback?.(); + this.setupStateRestorationObserver(); + } + disconnectedCallback(): void { if (this.resizeObserver) { this.disconnectResizeObserver(this.resizeObserver); @@ -1435,8 +1450,9 @@ export class CollectionBrowser } private setupStateRestorationObserver() { - if (this.boundNavigationHandler) return; - this.boundNavigationHandler = this.historyNavigationHandler.bind(this); + if (!this.boundNavigationHandler) { + this.boundNavigationHandler = this.historyNavigationHandler.bind(this); + } // when the user navigates back, we want to update the UI to match the URL window.addEventListener('popstate', this.boundNavigationHandler); } @@ -1483,7 +1499,10 @@ export class CollectionBrowser selectedTitleFilter: this.selectedTitleFilter ?? undefined, selectedCreatorFilter: this.selectedCreatorFilter ?? undefined, }; - this.restorationStateHandler.persistState(restorationState); + this.restorationStateHandler.persistState( + restorationState, + this.dataSourceInstallInProgress + ); } private emitSearchResultsLoadingChanged(): void { diff --git a/src/restoration-state-handler.ts b/src/restoration-state-handler.ts index 7e5a404ed..4199a3adc 100644 --- a/src/restoration-state-handler.ts +++ b/src/restoration-state-handler.ts @@ -31,7 +31,7 @@ export interface RestorationState { } export interface RestorationStateHandlerInterface { - persistState(state: RestorationState): void; + persistState(state: RestorationState, forceReplace?: boolean): void; getRestorationState(): RestorationState; } @@ -50,9 +50,9 @@ export class RestorationStateHandler this.context = options.context; } - persistState(state: RestorationState): void { + persistState(state: RestorationState, forceReplace = false): void { if (state.displayMode) this.persistViewStateToCookies(state.displayMode); - this.persistQueryStateToUrl(state); + this.persistQueryStateToUrl(state, forceReplace); } getRestorationState(): RestorationState { @@ -85,7 +85,10 @@ export class RestorationStateHandler return 'list-compact'; } - private persistQueryStateToUrl(state: RestorationState) { + private persistQueryStateToUrl( + state: RestorationState, + forceReplace = false + ) { const url = new URL(window.location.href); const oldParams = new URLSearchParams(url.searchParams); const newParams = this.removeRecognizedParams(url.searchParams); @@ -176,7 +179,9 @@ export class RestorationStateHandler // - If the state has changed, we push a new history entry. // - If only the page number has changed, we replace the current history entry. // - If the state hasn't changed, then do nothing. - let historyMethod: 'pushState' | 'replaceState' = 'pushState'; + let historyMethod: 'pushState' | 'replaceState' = forceReplace + ? 'replaceState' + : 'pushState'; const nonQueryParamsMatch = this.paramsMatch(oldParams, newParams, [ 'sin', 'sort', diff --git a/src/sort-filter-bar/sort-filter-bar.ts b/src/sort-filter-bar/sort-filter-bar.ts index d844dc86d..6c9b33d42 100644 --- a/src/sort-filter-bar/sort-filter-bar.ts +++ b/src/sort-filter-bar/sort-filter-bar.ts @@ -167,8 +167,14 @@ export class SortFilterBar } willUpdate(changed: PropertyValues) { - if (changed.has('selectedSort')) { - if (this.sortDirection === null) { + if (changed.has('selectedSort') || changed.has('defaultSortField')) { + // If the sort is changed from its default without a direction set, + // we adopt the default sort direction for that sort type. + if ( + this.selectedSort && + this.selectedSort !== SortField.default && + this.sortDirection === null + ) { const sortOption = SORT_OPTIONS[this.finalizedSortField]; this.sortDirection = sortOption.defaultSortDirection; }