@internetarchive/collection-browser 1.7.1-alpha.0 → 1.9.0
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/dist/src/collection-browser.js +18 -11
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/more-facets-content.d.ts +1 -0
- package/dist/src/collection-facets/more-facets-content.js +9 -2
- package/dist/src/collection-facets/more-facets-content.js.map +1 -1
- package/dist/src/collection-facets.d.ts +1 -0
- package/dist/src/collection-facets.js +4 -0
- package/dist/src/collection-facets.js.map +1 -1
- package/dist/src/models.d.ts +48 -35
- package/dist/src/models.js +139 -78
- package/dist/src/models.js.map +1 -1
- package/dist/src/restoration-state-handler.d.ts +9 -2
- package/dist/src/restoration-state-handler.js +61 -32
- package/dist/src/restoration-state-handler.js.map +1 -1
- package/dist/src/sort-filter-bar/sort-filter-bar.d.ts +2 -0
- package/dist/src/sort-filter-bar/sort-filter-bar.js +30 -25
- package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
- package/dist/test/collection-facets/more-facets-content.test.js +25 -0
- package/dist/test/collection-facets/more-facets-content.test.js.map +1 -1
- package/dist/test/restoration-state-handler.test.js +53 -1
- package/dist/test/restoration-state-handler.test.js.map +1 -1
- package/package.json +3 -3
- package/src/collection-browser.ts +16 -8
- package/src/collection-facets/more-facets-content.ts +9 -2
- package/src/collection-facets.ts +3 -0
- package/src/models.ts +193 -109
- package/src/restoration-state-handler.ts +66 -40
- package/src/sort-filter-bar/sort-filter-bar.ts +34 -27
- package/test/collection-facets/more-facets-content.test.ts +35 -0
- package/test/restoration-state-handler.test.ts +68 -1
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SearchType,
|
|
3
|
-
SortDirection,
|
|
4
|
-
SortParam,
|
|
5
|
-
} from '@internetarchive/search-service';
|
|
1
|
+
import { SearchType, SortDirection } from '@internetarchive/search-service';
|
|
6
2
|
import { getCookie, setCookie } from 'typescript-cookie';
|
|
7
3
|
import {
|
|
8
|
-
MetadataSortField,
|
|
9
4
|
FacetOption,
|
|
10
5
|
CollectionBrowserContext,
|
|
11
6
|
CollectionDisplayMode,
|
|
@@ -13,17 +8,15 @@ import {
|
|
|
13
8
|
SortField,
|
|
14
9
|
FacetBucket,
|
|
15
10
|
FacetState,
|
|
16
|
-
URLFieldToSortField,
|
|
17
|
-
URLSortField,
|
|
18
11
|
getDefaultSelectedFacets,
|
|
19
|
-
|
|
12
|
+
sortOptionFromAPIString,
|
|
13
|
+
SORT_OPTIONS,
|
|
20
14
|
} from './models';
|
|
21
15
|
import { arrayEquals } from './utils/array-equals';
|
|
22
16
|
|
|
23
17
|
export interface RestorationState {
|
|
24
18
|
displayMode?: CollectionDisplayMode;
|
|
25
19
|
searchType?: SearchType;
|
|
26
|
-
sortParam?: SortParam;
|
|
27
20
|
selectedSort?: SortField;
|
|
28
21
|
sortDirection?: SortDirection;
|
|
29
22
|
selectedFacets: SelectedFacets;
|
|
@@ -120,11 +113,29 @@ export class RestorationStateHandler
|
|
|
120
113
|
}
|
|
121
114
|
}
|
|
122
115
|
|
|
123
|
-
if (state.
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
116
|
+
if (state.selectedSort) {
|
|
117
|
+
const sortOption = SORT_OPTIONS[state.selectedSort];
|
|
118
|
+
let prefix = this.sortDirectionPrefix(state.sortDirection);
|
|
119
|
+
|
|
120
|
+
if (sortOption.field === SortField.unrecognized) {
|
|
121
|
+
// For unrecognized sorts, use the existing param, possibly updating its direction
|
|
122
|
+
const oldSortParam = oldParams.get('sort') ?? '';
|
|
123
|
+
const { field, direction } =
|
|
124
|
+
this.getSortFieldAndDirection(oldSortParam);
|
|
125
|
+
|
|
126
|
+
// Use the state-specified direction if available, or extract one from the param if not
|
|
127
|
+
if (!state.sortDirection) prefix = this.sortDirectionPrefix(direction);
|
|
128
|
+
|
|
129
|
+
if (field) {
|
|
130
|
+
newParams.set('sort', `${prefix}${field}`);
|
|
131
|
+
} else {
|
|
132
|
+
newParams.set('sort', oldSortParam);
|
|
133
|
+
}
|
|
134
|
+
} else if (sortOption.shownInURL) {
|
|
135
|
+
// Otherwise, use the canonical API form of the sort option
|
|
136
|
+
const canonicalApiSort = sortOption.urlNames[0];
|
|
137
|
+
newParams.set('sort', `${prefix}${canonicalApiSort}`);
|
|
138
|
+
}
|
|
128
139
|
}
|
|
129
140
|
|
|
130
141
|
if (state.selectedFacets) {
|
|
@@ -197,7 +208,7 @@ export class RestorationStateHandler
|
|
|
197
208
|
query: state.baseQuery,
|
|
198
209
|
searchType: state.searchType,
|
|
199
210
|
page: state.currentPage,
|
|
200
|
-
sort: state.
|
|
211
|
+
sort: { field: state.selectedSort, direction: state.sortDirection },
|
|
201
212
|
minDate: state.minSelectedDate,
|
|
202
213
|
maxDate: state.maxSelectedDate,
|
|
203
214
|
facets: state.selectedFacets,
|
|
@@ -261,29 +272,13 @@ export class RestorationStateHandler
|
|
|
261
272
|
}
|
|
262
273
|
|
|
263
274
|
if (sortQuery) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
restorationState.selectedSort = metadataField;
|
|
272
|
-
}
|
|
273
|
-
if (direction === 'desc' || direction === 'asc') {
|
|
274
|
-
restorationState.sortDirection = direction as SortDirection;
|
|
275
|
-
}
|
|
276
|
-
} else {
|
|
277
|
-
const direction = sortQuery.startsWith('-') ? 'desc' : 'asc';
|
|
278
|
-
const field = sortQuery.startsWith('-')
|
|
279
|
-
? sortQuery.slice(1)
|
|
280
|
-
: sortQuery;
|
|
281
|
-
|
|
282
|
-
const metadataField = URLFieldToSortField[field as URLSortField];
|
|
283
|
-
if (metadataField) {
|
|
284
|
-
restorationState.selectedSort = metadataField;
|
|
285
|
-
restorationState.sortDirection = direction as SortDirection;
|
|
286
|
-
}
|
|
275
|
+
const { field, direction } = this.getSortFieldAndDirection(sortQuery);
|
|
276
|
+
|
|
277
|
+
const sortOption = sortOptionFromAPIString(field);
|
|
278
|
+
restorationState.selectedSort = sortOption.field;
|
|
279
|
+
|
|
280
|
+
if (['asc', 'desc'].includes(direction)) {
|
|
281
|
+
restorationState.sortDirection = direction as SortDirection;
|
|
287
282
|
}
|
|
288
283
|
}
|
|
289
284
|
|
|
@@ -296,6 +291,13 @@ export class RestorationStateHandler
|
|
|
296
291
|
// which we want to normalize to 'creator', 'language', etc. if redirected here.
|
|
297
292
|
field = field.replace(/Sorter$/, '');
|
|
298
293
|
|
|
294
|
+
// Legacy search also allowed a form of negative faceting like `and[]=-collection:foo`
|
|
295
|
+
// which we want to normalize to a not[] param instead
|
|
296
|
+
if (field.startsWith('-')) {
|
|
297
|
+
facetNots.push(and.slice(1));
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
|
|
299
301
|
switch (field) {
|
|
300
302
|
case 'year': {
|
|
301
303
|
const [minDate, maxDate] = value.split(' TO ');
|
|
@@ -354,7 +356,31 @@ export class RestorationStateHandler
|
|
|
354
356
|
return restorationState;
|
|
355
357
|
}
|
|
356
358
|
|
|
357
|
-
|
|
359
|
+
/**
|
|
360
|
+
* Converts a URL sort param into a field/direction pair, if possible.
|
|
361
|
+
* Either or both may be undefined if the param is not in a recognized format.
|
|
362
|
+
*/
|
|
363
|
+
private getSortFieldAndDirection(sortParam: string) {
|
|
364
|
+
// check for two different sort formats: `date desc` and `-date`
|
|
365
|
+
const hasSpace = sortParam.indexOf(' ') > -1;
|
|
366
|
+
let field;
|
|
367
|
+
let direction;
|
|
368
|
+
if (hasSpace) {
|
|
369
|
+
[field, direction] = sortParam.split(' ');
|
|
370
|
+
} else {
|
|
371
|
+
field = sortParam.startsWith('-') ? sortParam.slice(1) : sortParam;
|
|
372
|
+
direction = sortParam.startsWith('-') ? 'desc' : 'asc';
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
return { field, direction };
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/** Returns the `-` prefix for `desc` sort, or the empty string otherwise. */
|
|
379
|
+
private sortDirectionPrefix(sortDirection?: string) {
|
|
380
|
+
return sortDirection === 'desc' ? '-' : '';
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/** Remove optional opening and closing quotes from a string */
|
|
358
384
|
private stripQuotes(value: string): string {
|
|
359
385
|
if (value.startsWith('"') && value.endsWith('"')) {
|
|
360
386
|
return value.substring(1, value.length - 1);
|
|
@@ -16,11 +16,10 @@ import type { IaDropdown, optionInterface } from '@internetarchive/ia-dropdown';
|
|
|
16
16
|
import type { SortDirection } from '@internetarchive/search-service';
|
|
17
17
|
import {
|
|
18
18
|
CollectionDisplayMode,
|
|
19
|
-
DefaultSortDirection,
|
|
20
19
|
PrefixFilterCounts,
|
|
21
20
|
PrefixFilterType,
|
|
21
|
+
SORT_OPTIONS,
|
|
22
22
|
SortField,
|
|
23
|
-
SortFieldDisplayName,
|
|
24
23
|
} from '../models';
|
|
25
24
|
import './alpha-bar';
|
|
26
25
|
|
|
@@ -153,7 +152,8 @@ export class SortFilterBar
|
|
|
153
152
|
}
|
|
154
153
|
|
|
155
154
|
if (changed.has('selectedSort') && this.sortDirection === null) {
|
|
156
|
-
|
|
155
|
+
const sortOption = SORT_OPTIONS[this.finalizedSortField];
|
|
156
|
+
this.sortDirection = sortOption.defaultSortDirection;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
if (changed.has('selectedTitleFilter') && this.selectedTitleFilter) {
|
|
@@ -274,7 +274,7 @@ export class SortFilterBar
|
|
|
274
274
|
return html`
|
|
275
275
|
<button
|
|
276
276
|
class="sort-direction-selector"
|
|
277
|
-
?disabled=${this.
|
|
277
|
+
?disabled=${!this.canChangeSortDirection}
|
|
278
278
|
@click=${this.handleSortDirectionClicked}
|
|
279
279
|
>
|
|
280
280
|
<span class="sr-only">${srLabel}</span>
|
|
@@ -285,8 +285,8 @@ export class SortFilterBar
|
|
|
285
285
|
|
|
286
286
|
/** Template to render the sort direction button's icon in the correct current state */
|
|
287
287
|
private get sortDirectionIcon(): TemplateResult {
|
|
288
|
-
//
|
|
289
|
-
if (this.
|
|
288
|
+
// Show a fully disabled icon for sort options without direction support
|
|
289
|
+
if (!this.canChangeSortDirection) {
|
|
290
290
|
return html`<div class="sort-direction-icon">${sortDisabledIcon}</div>`;
|
|
291
291
|
}
|
|
292
292
|
|
|
@@ -354,9 +354,9 @@ export class SortFilterBar
|
|
|
354
354
|
|
|
355
355
|
/** The template to render all the sort options in mobile view */
|
|
356
356
|
private get mobileSortSelectorTemplate() {
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
(field !== SortField.relevance
|
|
357
|
+
const displayedOptions = Object.values(SORT_OPTIONS)
|
|
358
|
+
.filter(opt => opt.shownInSortBar)
|
|
359
|
+
.filter(opt => this.showRelevance || opt.field !== SortField.relevance);
|
|
360
360
|
|
|
361
361
|
return html`
|
|
362
362
|
<div
|
|
@@ -364,13 +364,13 @@ export class SortFilterBar
|
|
|
364
364
|
class=${this.mobileSelectorVisible ? 'visible' : 'hidden'}
|
|
365
365
|
>
|
|
366
366
|
${this.getSortDropdown({
|
|
367
|
-
displayName: html`${
|
|
368
|
-
|
|
367
|
+
displayName: html`${SORT_OPTIONS[this.finalizedSortField]
|
|
368
|
+
.displayName}`,
|
|
369
369
|
id: 'mobile-dropdown',
|
|
370
370
|
selected: true,
|
|
371
|
-
dropdownOptions:
|
|
372
|
-
.
|
|
373
|
-
|
|
371
|
+
dropdownOptions: displayedOptions.map(opt =>
|
|
372
|
+
this.getDropdownOption(opt.field)
|
|
373
|
+
),
|
|
374
374
|
selectedOption: this.finalizedSortField,
|
|
375
375
|
onOptionSelected: this.mobileSortChanged,
|
|
376
376
|
onDropdownClick: () => {
|
|
@@ -408,7 +408,8 @@ export class SortFilterBar
|
|
|
408
408
|
): TemplateResult {
|
|
409
409
|
const isSelected =
|
|
410
410
|
options?.selected ?? this.finalizedSortField === sortField;
|
|
411
|
-
const displayName =
|
|
411
|
+
const displayName =
|
|
412
|
+
options?.displayName ?? SORT_OPTIONS[sortField].displayName;
|
|
412
413
|
return html`
|
|
413
414
|
<button
|
|
414
415
|
class=${isSelected ? 'selected' : nothing}
|
|
@@ -488,7 +489,7 @@ export class SortFilterBar
|
|
|
488
489
|
},
|
|
489
490
|
label: html`
|
|
490
491
|
<span class="dropdown-option-label">
|
|
491
|
-
${
|
|
492
|
+
${SORT_OPTIONS[sortField].displayName}
|
|
492
493
|
</span>
|
|
493
494
|
`,
|
|
494
495
|
};
|
|
@@ -692,7 +693,8 @@ export class SortFilterBar
|
|
|
692
693
|
private setSelectedSort(sort: SortField) {
|
|
693
694
|
this.selectedSort = sort;
|
|
694
695
|
// Apply this field's default sort direction
|
|
695
|
-
|
|
696
|
+
const sortOption = SORT_OPTIONS[sort];
|
|
697
|
+
this.sortDirection = sortOption.defaultSortDirection;
|
|
696
698
|
this.emitSortChangedEvent();
|
|
697
699
|
}
|
|
698
700
|
|
|
@@ -710,6 +712,11 @@ export class SortFilterBar
|
|
|
710
712
|
: this.sortDirection;
|
|
711
713
|
}
|
|
712
714
|
|
|
715
|
+
/** Whether the sort direction button should be enabled for the current sort */
|
|
716
|
+
private get canChangeSortDirection(): boolean {
|
|
717
|
+
return SORT_OPTIONS[this.finalizedSortField].canSetDirection;
|
|
718
|
+
}
|
|
719
|
+
|
|
713
720
|
/**
|
|
714
721
|
* There are four date sort options.
|
|
715
722
|
*
|
|
@@ -757,11 +764,11 @@ export class SortFilterBar
|
|
|
757
764
|
* @memberof SortFilterBar
|
|
758
765
|
*/
|
|
759
766
|
private get dateSortField(): string {
|
|
760
|
-
const
|
|
761
|
-
const
|
|
762
|
-
?
|
|
763
|
-
:
|
|
764
|
-
return
|
|
767
|
+
const defaultDateSort = SORT_OPTIONS[SortField.date];
|
|
768
|
+
const currentDateSort = this.dateOptionSelected
|
|
769
|
+
? SORT_OPTIONS[this.finalizedSortField] ?? defaultDateSort
|
|
770
|
+
: defaultDateSort;
|
|
771
|
+
return currentDateSort.displayName;
|
|
765
772
|
}
|
|
766
773
|
|
|
767
774
|
/**
|
|
@@ -773,11 +780,11 @@ export class SortFilterBar
|
|
|
773
780
|
* @memberof SortFilterBar
|
|
774
781
|
*/
|
|
775
782
|
private get viewSortField(): string {
|
|
776
|
-
const
|
|
777
|
-
const
|
|
778
|
-
?
|
|
779
|
-
:
|
|
780
|
-
return
|
|
783
|
+
const defaultViewSort = SORT_OPTIONS[SortField.weeklyview];
|
|
784
|
+
const currentViewSort = this.viewOptionSelected
|
|
785
|
+
? SORT_OPTIONS[this.finalizedSortField] ?? defaultViewSort
|
|
786
|
+
: defaultViewSort;
|
|
787
|
+
return currentViewSort.displayName;
|
|
781
788
|
}
|
|
782
789
|
|
|
783
790
|
private get titleSelectorBar() {
|
|
@@ -86,6 +86,41 @@ describe('More facets content', () => {
|
|
|
86
86
|
expect(searchService.searchParams?.query).to.equal('title:hello');
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
+
it('queries for more facets using search service within a collection (no query)', async () => {
|
|
90
|
+
const searchService = new MockSearchService();
|
|
91
|
+
|
|
92
|
+
const el = await fixture<MoreFacetsContent>(
|
|
93
|
+
html`<more-facets-content
|
|
94
|
+
.searchService=${searchService}
|
|
95
|
+
.withinCollection=${'foobar'}
|
|
96
|
+
></more-facets-content>`
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
el.facetKey = 'subject';
|
|
100
|
+
await el.updateComplete;
|
|
101
|
+
|
|
102
|
+
expect(searchService.searchParams?.query).to.be.empty;
|
|
103
|
+
expect(searchService.searchParams?.pageTarget).to.equal('foobar');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('queries for more facets using search service within a collection (with query)', async () => {
|
|
107
|
+
const searchService = new MockSearchService();
|
|
108
|
+
|
|
109
|
+
const el = await fixture<MoreFacetsContent>(
|
|
110
|
+
html`<more-facets-content
|
|
111
|
+
.searchService=${searchService}
|
|
112
|
+
.withinCollection=${'foobar'}
|
|
113
|
+
></more-facets-content>`
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
el.facetKey = 'subject';
|
|
117
|
+
el.query = 'title:hello';
|
|
118
|
+
await el.updateComplete;
|
|
119
|
+
|
|
120
|
+
expect(searchService.searchParams?.query).to.equal('title:hello');
|
|
121
|
+
expect(searchService.searchParams?.pageTarget).to.equal('foobar');
|
|
122
|
+
});
|
|
123
|
+
|
|
89
124
|
it('filter raw selectedFacets object', async () => {
|
|
90
125
|
const searchService = new MockSearchService();
|
|
91
126
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SearchType } from '@internetarchive/search-service';
|
|
2
2
|
import { expect } from '@open-wc/testing';
|
|
3
|
-
import { getDefaultSelectedFacets } from '../src/models';
|
|
3
|
+
import { SortField, getDefaultSelectedFacets } from '../src/models';
|
|
4
4
|
import { RestorationStateHandler } from '../src/restoration-state-handler';
|
|
5
5
|
|
|
6
6
|
describe('Restoration state handler', () => {
|
|
@@ -245,6 +245,73 @@ describe('Restoration state handler', () => {
|
|
|
245
245
|
expect(restorationState.sortDirection).to.equal('asc');
|
|
246
246
|
});
|
|
247
247
|
|
|
248
|
+
it('should restore sort from URL (space format)', async () => {
|
|
249
|
+
const handler = new RestorationStateHandler({ context: 'search' });
|
|
250
|
+
|
|
251
|
+
const url = new URL(window.location.href);
|
|
252
|
+
url.search = '?sort=foo+desc';
|
|
253
|
+
window.history.replaceState({ path: url.href }, '', url.href);
|
|
254
|
+
|
|
255
|
+
const restorationState = handler.getRestorationState();
|
|
256
|
+
expect(restorationState.selectedSort).to.equal('unrecognized');
|
|
257
|
+
expect(restorationState.sortDirection).to.equal('desc');
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('should restore unrecognized sort from URL (prefix format)', async () => {
|
|
261
|
+
const handler = new RestorationStateHandler({ context: 'search' });
|
|
262
|
+
|
|
263
|
+
const url = new URL(window.location.href);
|
|
264
|
+
url.search = '?sort=-foo';
|
|
265
|
+
window.history.replaceState({ path: url.href }, '', url.href);
|
|
266
|
+
|
|
267
|
+
const restorationState = handler.getRestorationState();
|
|
268
|
+
expect(restorationState.selectedSort).to.equal('unrecognized');
|
|
269
|
+
expect(restorationState.sortDirection).to.equal('desc');
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('should save direction to URL even for unrecognized sort fields', async () => {
|
|
273
|
+
const url = new URL(window.location.href);
|
|
274
|
+
url.search = '?sort=foo';
|
|
275
|
+
window.history.replaceState({ path: url.href }, '', url.href);
|
|
276
|
+
|
|
277
|
+
const handler = new RestorationStateHandler({ context: 'search' });
|
|
278
|
+
handler.persistState({
|
|
279
|
+
selectedSort: SortField.unrecognized,
|
|
280
|
+
sortDirection: 'desc',
|
|
281
|
+
selectedFacets: getDefaultSelectedFacets(),
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
expect(window.location.search).to.equal('?sort=-foo');
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
it('should keep existing direction for unrecognized sort fields when unspecified in state', async () => {
|
|
288
|
+
const url = new URL(window.location.href);
|
|
289
|
+
url.search = '?sort=foo+desc';
|
|
290
|
+
window.history.replaceState({ path: url.href }, '', url.href);
|
|
291
|
+
|
|
292
|
+
const handler = new RestorationStateHandler({ context: 'search' });
|
|
293
|
+
handler.persistState({
|
|
294
|
+
selectedSort: SortField.unrecognized,
|
|
295
|
+
selectedFacets: getDefaultSelectedFacets(),
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
expect(window.location.search).to.equal('?sort=-foo');
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
it('should just ignore unrecognized sort fields w/ unknown formats', async () => {
|
|
302
|
+
const url = new URL(window.location.href);
|
|
303
|
+
url.search = '?sort=+foo';
|
|
304
|
+
window.history.replaceState({ path: url.href }, '', url.href);
|
|
305
|
+
|
|
306
|
+
const handler = new RestorationStateHandler({ context: 'search' });
|
|
307
|
+
handler.persistState({
|
|
308
|
+
selectedSort: SortField.unrecognized,
|
|
309
|
+
selectedFacets: getDefaultSelectedFacets(),
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
expect(window.location.search).to.equal('?sort=+foo');
|
|
313
|
+
});
|
|
314
|
+
|
|
248
315
|
it('should not save current page state to the URL for page 1', async () => {
|
|
249
316
|
const url = new URL(window.location.href);
|
|
250
317
|
url.search = '';
|