@internetarchive/collection-browser 0.2.15-0 → 0.2.16-alpha1
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/app-root.d.ts +1 -0
- package/dist/src/app-root.js +29 -2
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/assets/img/icons/arrow-left.d.ts +2 -0
- package/dist/src/assets/img/icons/arrow-left.js +10 -0
- package/dist/src/assets/img/icons/arrow-left.js.map +1 -0
- package/dist/src/assets/img/icons/arrow-right.d.ts +2 -0
- package/dist/src/assets/img/icons/arrow-right.js +10 -0
- package/dist/src/assets/img/icons/arrow-right.js.map +1 -0
- package/dist/src/collection-browser.d.ts +2 -0
- package/dist/src/collection-browser.js +9 -13
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/more-facets-content.d.ts +56 -0
- package/dist/src/collection-facets/more-facets-content.js +374 -0
- package/dist/src/collection-facets/more-facets-content.js.map +1 -0
- package/dist/src/collection-facets/more-facets-pagination.d.ts +27 -0
- package/dist/src/collection-facets/more-facets-pagination.js +193 -0
- package/dist/src/collection-facets/more-facets-pagination.js.map +1 -0
- package/dist/src/collection-facets.d.ts +19 -2
- package/dist/src/collection-facets.js +102 -0
- package/dist/src/collection-facets.js.map +1 -1
- package/dist/src/models.d.ts +3 -2
- package/dist/src/models.js +8 -4
- package/dist/src/models.js.map +1 -1
- package/dist/src/sort-filter-bar/sort-filter-bar.d.ts +23 -1
- package/dist/src/sort-filter-bar/sort-filter-bar.js +96 -12
- package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
- package/dist/test/collection-browser.test.js +35 -0
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/collection-facets/more-facets-content.test.d.ts +1 -0
- package/dist/test/collection-facets/more-facets-content.test.js +75 -0
- package/dist/test/collection-facets/more-facets-content.test.js.map +1 -0
- package/dist/test/collection-facets/more-facets-pagination.test.d.ts +1 -0
- package/dist/test/collection-facets/more-facets-pagination.test.js +38 -0
- package/dist/test/collection-facets/more-facets-pagination.test.js.map +1 -0
- package/dist/test/mocks/mock-search-responses.js +13 -0
- package/dist/test/mocks/mock-search-responses.js.map +1 -1
- package/dist/test/sort-filter-bar/sort-filter-bar.test.d.ts +1 -0
- package/dist/test/sort-filter-bar/sort-filter-bar.test.js +122 -0
- package/dist/test/sort-filter-bar/sort-filter-bar.test.js.map +1 -0
- package/package.json +3 -1
- package/src/app-root.ts +29 -2
- package/src/assets/img/icons/arrow-left.ts +10 -0
- package/src/assets/img/icons/arrow-right.ts +10 -0
- package/src/collection-browser.ts +8 -13
- package/src/collection-facets/more-facets-content.ts +393 -0
- package/src/collection-facets/more-facets-pagination.ts +201 -0
- package/src/collection-facets.ts +117 -1
- package/src/models.ts +9 -4
- package/src/sort-filter-bar/sort-filter-bar.ts +98 -12
- package/test/collection-browser.test.ts +43 -0
- package/test/collection-facets/more-facets-content.test.ts +113 -0
- package/test/collection-facets/more-facets-pagination.test.ts +70 -0
- package/test/mocks/mock-search-responses.ts +13 -0
- package/test/sort-filter-bar/sort-filter-bar.test.ts +187 -0
package/src/collection-facets.ts
CHANGED
|
@@ -9,11 +9,19 @@ import {
|
|
|
9
9
|
} from 'lit';
|
|
10
10
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
11
11
|
import { repeat } from 'lit/directives/repeat.js';
|
|
12
|
-
import type {
|
|
12
|
+
import type {
|
|
13
|
+
Aggregation,
|
|
14
|
+
Bucket,
|
|
15
|
+
SearchServiceInterface,
|
|
16
|
+
} from '@internetarchive/search-service';
|
|
13
17
|
import '@internetarchive/histogram-date-range';
|
|
14
18
|
import '@internetarchive/feature-feedback';
|
|
15
19
|
import '@internetarchive/collection-name-cache';
|
|
16
20
|
import type { CollectionNameCacheInterface } from '@internetarchive/collection-name-cache';
|
|
21
|
+
import {
|
|
22
|
+
ModalConfig,
|
|
23
|
+
ModalManagerInterface,
|
|
24
|
+
} from '@internetarchive/modal-manager';
|
|
17
25
|
import eyeIcon from './assets/img/icons/eye';
|
|
18
26
|
import eyeClosedIcon from './assets/img/icons/eye-closed';
|
|
19
27
|
import chevronIcon from './assets/img/icons/chevron';
|
|
@@ -25,6 +33,7 @@ import {
|
|
|
25
33
|
defaultSelectedFacets,
|
|
26
34
|
} from './models';
|
|
27
35
|
import type { LanguageCodeHandlerInterface } from './language-code-handler/language-code-handler';
|
|
36
|
+
import './collection-facets/more-facets-content';
|
|
28
37
|
|
|
29
38
|
const facetDisplayOrder: FacetOption[] = [
|
|
30
39
|
'mediatype',
|
|
@@ -55,6 +64,8 @@ const facetTitles: Record<FacetOption, string> = {
|
|
|
55
64
|
|
|
56
65
|
@customElement('collection-facets')
|
|
57
66
|
export class CollectionFacets extends LitElement {
|
|
67
|
+
@property({ type: Object }) searchService?: SearchServiceInterface;
|
|
68
|
+
|
|
58
69
|
@property({ type: Object }) aggregations?: Record<string, Aggregation>;
|
|
59
70
|
|
|
60
71
|
@property({ type: Object }) fullYearsHistogramAggregation?: Aggregation;
|
|
@@ -73,6 +84,10 @@ export class CollectionFacets extends LitElement {
|
|
|
73
84
|
|
|
74
85
|
@property({ type: Boolean }) showHistogramDatePicker = false;
|
|
75
86
|
|
|
87
|
+
@property({ type: String }) fullQuery?: string;
|
|
88
|
+
|
|
89
|
+
@property({ type: Object }) modalManager?: ModalManagerInterface;
|
|
90
|
+
|
|
76
91
|
@property({ type: Object })
|
|
77
92
|
languageCodeHandler?: LanguageCodeHandlerInterface;
|
|
78
93
|
|
|
@@ -88,6 +103,12 @@ export class CollectionFacets extends LitElement {
|
|
|
88
103
|
year: false,
|
|
89
104
|
};
|
|
90
105
|
|
|
106
|
+
/**
|
|
107
|
+
* If listed facets on page more then this number,
|
|
108
|
+
* - show the more link button just below the facets group
|
|
109
|
+
*/
|
|
110
|
+
private moreLinkEligibilityCount = 5;
|
|
111
|
+
|
|
91
112
|
render() {
|
|
92
113
|
return html`
|
|
93
114
|
<div id="container" class="${this.facetsLoading ? 'loading' : ''}">
|
|
@@ -112,6 +133,7 @@ export class CollectionFacets extends LitElement {
|
|
|
112
133
|
}
|
|
113
134
|
}
|
|
114
135
|
|
|
136
|
+
// TODO: want to fire analytics?
|
|
115
137
|
private dispatchFacetsChangedEvent() {
|
|
116
138
|
const event = new CustomEvent<SelectedFacets>('facetsChanged', {
|
|
117
139
|
detail: this.selectedFacets,
|
|
@@ -322,11 +344,92 @@ export class CollectionFacets extends LitElement {
|
|
|
322
344
|
</h1>
|
|
323
345
|
<div class="facet-group-content ${isOpen ? 'open' : ''}">
|
|
324
346
|
${this.getFacetTemplate(facetGroup)}
|
|
347
|
+
${this.searchMoreFacetsLink(facetGroup)}
|
|
325
348
|
</div>
|
|
326
349
|
</div>
|
|
327
350
|
`;
|
|
328
351
|
}
|
|
329
352
|
|
|
353
|
+
/**
|
|
354
|
+
* Generate the More... link button just below the facets group
|
|
355
|
+
*
|
|
356
|
+
* TODO: want to fire analytics?
|
|
357
|
+
*/
|
|
358
|
+
private searchMoreFacetsLink(
|
|
359
|
+
facetGroup: FacetGroup
|
|
360
|
+
): TemplateResult | typeof nothing {
|
|
361
|
+
// don't render More... link if the number of facets is < this.moreLinkEligibilityCount
|
|
362
|
+
if (Object.keys(facetGroup.buckets).length < this.moreLinkEligibilityCount)
|
|
363
|
+
return nothing;
|
|
364
|
+
|
|
365
|
+
return html`<button
|
|
366
|
+
class="more-link"
|
|
367
|
+
@click=${() => {
|
|
368
|
+
this.showMoreFacetsModal(facetGroup);
|
|
369
|
+
}}
|
|
370
|
+
>
|
|
371
|
+
More...
|
|
372
|
+
</button>`;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
async showMoreFacetsModal(facetGroup: FacetGroup): Promise<void> {
|
|
376
|
+
const facetAggrKey = Object.keys(aggregationToFacetOption).find(
|
|
377
|
+
value => aggregationToFacetOption[value] === facetGroup.key
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
// TODO - lets move sr-only style into modal-manager component as well
|
|
381
|
+
const headline = html`
|
|
382
|
+
<span
|
|
383
|
+
style="display:block;text-align:left;font-size:1.8rem;padding:0 10px;"
|
|
384
|
+
>
|
|
385
|
+
<span
|
|
386
|
+
style="position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip: rect(0,0,0,0);border:0;"
|
|
387
|
+
>More facets for:
|
|
388
|
+
</span>
|
|
389
|
+
${facetTitles[facetGroup.key]}
|
|
390
|
+
<img
|
|
391
|
+
src="https://archive.org/images/filter-count.png"
|
|
392
|
+
style="height: 1.5rem;vertical-align: baseline;"
|
|
393
|
+
alt=""
|
|
394
|
+
/>
|
|
395
|
+
</span>
|
|
396
|
+
`;
|
|
397
|
+
|
|
398
|
+
const message = html`
|
|
399
|
+
<more-facets-content
|
|
400
|
+
@facetsChanged=${(e: CustomEvent) => {
|
|
401
|
+
const event = new CustomEvent<SelectedFacets>('facetsChanged', {
|
|
402
|
+
detail: e.detail,
|
|
403
|
+
bubbles: true,
|
|
404
|
+
composed: true,
|
|
405
|
+
});
|
|
406
|
+
this.dispatchEvent(event);
|
|
407
|
+
}}
|
|
408
|
+
.facetKey=${facetGroup.key}
|
|
409
|
+
.facetAggregationKey=${facetAggrKey}
|
|
410
|
+
.fullQuery=${this.fullQuery}
|
|
411
|
+
.modalManager=${this.modalManager}
|
|
412
|
+
.searchService=${this.searchService}
|
|
413
|
+
.collectionNameCache=${this.collectionNameCache}
|
|
414
|
+
.languageCodeHandler=${this.languageCodeHandler}
|
|
415
|
+
.selectedFacets=${this.selectedFacets}
|
|
416
|
+
>
|
|
417
|
+
</more-facets-content>
|
|
418
|
+
`;
|
|
419
|
+
|
|
420
|
+
const config = new ModalConfig({
|
|
421
|
+
bodyColor: '#fff',
|
|
422
|
+
headerColor: '#194880',
|
|
423
|
+
showHeaderLogo: false,
|
|
424
|
+
closeOnBackdropClick: true, // TODO: want to fire analytics
|
|
425
|
+
title: html`Select filters`,
|
|
426
|
+
headline,
|
|
427
|
+
message,
|
|
428
|
+
});
|
|
429
|
+
this.modalManager?.classList.add('more-search-facets');
|
|
430
|
+
this.modalManager?.showModal({ config });
|
|
431
|
+
}
|
|
432
|
+
|
|
330
433
|
/**
|
|
331
434
|
* Generate the list template for each bucket in a facet group
|
|
332
435
|
*/
|
|
@@ -605,6 +708,19 @@ export class CollectionFacets extends LitElement {
|
|
|
605
708
|
.hide-facet-icon.active .eye {
|
|
606
709
|
display: none;
|
|
607
710
|
}
|
|
711
|
+
|
|
712
|
+
.more-link {
|
|
713
|
+
font-size: 1.2rem;
|
|
714
|
+
text-decoration: none;
|
|
715
|
+
padding: 0px 4px;
|
|
716
|
+
background: inherit;
|
|
717
|
+
border: 0;
|
|
718
|
+
color: blue;
|
|
719
|
+
cursor: pointer;
|
|
720
|
+
}
|
|
721
|
+
.sorting-icon {
|
|
722
|
+
cursor: pointer;
|
|
723
|
+
}
|
|
608
724
|
`;
|
|
609
725
|
}
|
|
610
726
|
}
|
package/src/models.ts
CHANGED
|
@@ -47,7 +47,8 @@ export type CollectionBrowserContext = 'collection' | 'search';
|
|
|
47
47
|
*/
|
|
48
48
|
export enum SortField {
|
|
49
49
|
'relevance' = 'relevance',
|
|
50
|
-
'
|
|
50
|
+
'alltimeview' = 'alltimeview',
|
|
51
|
+
'weeklyview' = 'weeklyview',
|
|
51
52
|
'title' = 'title',
|
|
52
53
|
'datearchived' = 'datearchived',
|
|
53
54
|
'date' = 'date',
|
|
@@ -60,6 +61,7 @@ export enum SortField {
|
|
|
60
61
|
* The metadata fields we sort by that map to the SortFields above
|
|
61
62
|
*/
|
|
62
63
|
export type MetadataSortField =
|
|
64
|
+
| 'downloads'
|
|
63
65
|
| 'week'
|
|
64
66
|
| 'titleSorter'
|
|
65
67
|
| 'date'
|
|
@@ -72,7 +74,8 @@ export const SortFieldDisplayName: {
|
|
|
72
74
|
[key in SortField]: string;
|
|
73
75
|
} = {
|
|
74
76
|
relevance: 'Relevance',
|
|
75
|
-
|
|
77
|
+
alltimeview: 'All-time Views',
|
|
78
|
+
weeklyview: 'Weekly Views',
|
|
76
79
|
title: 'Title',
|
|
77
80
|
datearchived: 'Date Archived',
|
|
78
81
|
date: 'Date Published',
|
|
@@ -88,7 +91,8 @@ export const SortFieldToMetadataField: {
|
|
|
88
91
|
[key in SortField]: MetadataSortField | null;
|
|
89
92
|
} = {
|
|
90
93
|
relevance: null,
|
|
91
|
-
|
|
94
|
+
alltimeview: 'downloads',
|
|
95
|
+
weeklyview: 'week',
|
|
92
96
|
title: 'titleSorter',
|
|
93
97
|
datearchived: 'publicdate',
|
|
94
98
|
date: 'date',
|
|
@@ -103,13 +107,14 @@ export const SortFieldToMetadataField: {
|
|
|
103
107
|
export const MetadataFieldToSortField: {
|
|
104
108
|
[key in MetadataSortField]: SortField;
|
|
105
109
|
} = {
|
|
110
|
+
week: SortField.weeklyview,
|
|
111
|
+
downloads: SortField.alltimeview,
|
|
106
112
|
titleSorter: SortField.title,
|
|
107
113
|
date: SortField.date,
|
|
108
114
|
publicdate: SortField.datearchived,
|
|
109
115
|
reviewdate: SortField.datereviewed,
|
|
110
116
|
addeddate: SortField.dateadded,
|
|
111
117
|
creatorSorter: SortField.creator,
|
|
112
|
-
week: SortField.views,
|
|
113
118
|
};
|
|
114
119
|
|
|
115
120
|
export type FacetOption =
|
|
@@ -48,6 +48,8 @@ export class SortFilterBar
|
|
|
48
48
|
|
|
49
49
|
@state() dateSortSelectorVisible = false;
|
|
50
50
|
|
|
51
|
+
@state() viewSortSelectorVisible = false;
|
|
52
|
+
|
|
51
53
|
@state() desktopSelectorBarWidth = 0;
|
|
52
54
|
|
|
53
55
|
@state() selectorBarContainerWidth = 0;
|
|
@@ -76,6 +78,9 @@ export class SortFilterBar
|
|
|
76
78
|
<div id="display-style-selector">${this.displayOptionTemplate}</div>
|
|
77
79
|
</div>
|
|
78
80
|
|
|
81
|
+
${this.viewSortSelectorVisible && !this.mobileSelectorVisible
|
|
82
|
+
? this.viewSortSelector
|
|
83
|
+
: nothing}
|
|
79
84
|
${this.dateSortSelectorVisible && !this.mobileSelectorVisible
|
|
80
85
|
? this.dateSortSelector
|
|
81
86
|
: nothing}
|
|
@@ -103,7 +108,10 @@ export class SortFilterBar
|
|
|
103
108
|
this.alphaSelectorVisible = 'creator';
|
|
104
109
|
}
|
|
105
110
|
|
|
106
|
-
if (
|
|
111
|
+
if (
|
|
112
|
+
changed.has('dateSortSelectorVisible') ||
|
|
113
|
+
changed.has('viewSortSelectorVisible')
|
|
114
|
+
) {
|
|
107
115
|
this.setupEscapeListeners();
|
|
108
116
|
}
|
|
109
117
|
|
|
@@ -117,21 +125,22 @@ export class SortFilterBar
|
|
|
117
125
|
}
|
|
118
126
|
|
|
119
127
|
private setupEscapeListeners() {
|
|
120
|
-
if (this.dateSortSelectorVisible) {
|
|
128
|
+
if (this.dateSortSelectorVisible || this.viewSortSelectorVisible) {
|
|
121
129
|
document.addEventListener(
|
|
122
130
|
'keydown',
|
|
123
|
-
this.
|
|
131
|
+
this.boundSortBarSelectorEscapeListener
|
|
124
132
|
);
|
|
125
133
|
} else {
|
|
126
134
|
document.removeEventListener(
|
|
127
135
|
'keydown',
|
|
128
|
-
this.
|
|
136
|
+
this.boundSortBarSelectorEscapeListener
|
|
129
137
|
);
|
|
130
138
|
}
|
|
131
139
|
}
|
|
132
140
|
|
|
133
|
-
private
|
|
141
|
+
private boundSortBarSelectorEscapeListener = (e: KeyboardEvent) => {
|
|
134
142
|
if (e.key === 'Escape') {
|
|
143
|
+
this.viewSortSelectorVisible = false;
|
|
135
144
|
this.dateSortSelectorVisible = false;
|
|
136
145
|
}
|
|
137
146
|
};
|
|
@@ -235,13 +244,30 @@ export class SortFilterBar
|
|
|
235
244
|
? this.getSortDisplayOption(SortField.relevance)
|
|
236
245
|
: nothing}
|
|
237
246
|
</li>
|
|
238
|
-
<li
|
|
247
|
+
<li>
|
|
248
|
+
${this.getSortDisplayOption(SortField.weeklyview, {
|
|
249
|
+
clickEvent: () => {
|
|
250
|
+
if (!this.viewOptionSelected)
|
|
251
|
+
this.setSelectedSort(SortField.weeklyview);
|
|
252
|
+
this.viewSortSelectorVisible = !this.viewSortSelectorVisible;
|
|
253
|
+
this.dateSortSelectorVisible = false;
|
|
254
|
+
this.alphaSelectorVisible = null;
|
|
255
|
+
this.selectedTitleFilter = null;
|
|
256
|
+
this.selectedCreatorFilter = null;
|
|
257
|
+
this.emitTitleLetterChangedEvent();
|
|
258
|
+
this.emitCreatorLetterChangedEvent();
|
|
259
|
+
},
|
|
260
|
+
displayName: html`${this.viewSortField}`,
|
|
261
|
+
isSelected: () => this.viewOptionSelected,
|
|
262
|
+
})}
|
|
263
|
+
</li>
|
|
239
264
|
<li>
|
|
240
265
|
${this.getSortDisplayOption(SortField.title, {
|
|
241
266
|
clickEvent: () => {
|
|
242
267
|
this.alphaSelectorVisible = 'title';
|
|
243
268
|
this.selectedCreatorFilter = null;
|
|
244
269
|
this.dateSortSelectorVisible = false;
|
|
270
|
+
this.viewSortSelectorVisible = false;
|
|
245
271
|
this.setSelectedSort(SortField.title);
|
|
246
272
|
this.emitCreatorLetterChangedEvent();
|
|
247
273
|
},
|
|
@@ -253,6 +279,7 @@ export class SortFilterBar
|
|
|
253
279
|
if (!this.dateOptionSelected)
|
|
254
280
|
this.setSelectedSort(SortField.date);
|
|
255
281
|
this.dateSortSelectorVisible = !this.dateSortSelectorVisible;
|
|
282
|
+
this.viewSortSelectorVisible = false;
|
|
256
283
|
this.alphaSelectorVisible = null;
|
|
257
284
|
this.selectedTitleFilter = null;
|
|
258
285
|
this.selectedCreatorFilter = null;
|
|
@@ -366,7 +393,7 @@ export class SortFilterBar
|
|
|
366
393
|
</li>
|
|
367
394
|
<li>
|
|
368
395
|
<button
|
|
369
|
-
id="
|
|
396
|
+
id="list-detail-button"
|
|
370
397
|
@click=${() => {
|
|
371
398
|
this.displayMode = 'list-detail';
|
|
372
399
|
}}
|
|
@@ -378,7 +405,7 @@ export class SortFilterBar
|
|
|
378
405
|
</li>
|
|
379
406
|
<li>
|
|
380
407
|
<button
|
|
381
|
-
id="list-button"
|
|
408
|
+
id="list-compact-button"
|
|
382
409
|
@click=${() => {
|
|
383
410
|
this.displayMode = 'list-compact';
|
|
384
411
|
}}
|
|
@@ -414,6 +441,26 @@ export class SortFilterBar
|
|
|
414
441
|
`;
|
|
415
442
|
}
|
|
416
443
|
|
|
444
|
+
private get viewSortSelector() {
|
|
445
|
+
return html`
|
|
446
|
+
<div
|
|
447
|
+
id="view-sort-selector-backdrop"
|
|
448
|
+
@keyup=${() => {
|
|
449
|
+
this.viewSortSelectorVisible = false;
|
|
450
|
+
}}
|
|
451
|
+
@click=${() => {
|
|
452
|
+
this.viewSortSelectorVisible = false;
|
|
453
|
+
}}
|
|
454
|
+
></div>
|
|
455
|
+
<div id="view-sort-selector">
|
|
456
|
+
<ul>
|
|
457
|
+
<li>${this.getDateSortButton(SortField.alltimeview)}</li>
|
|
458
|
+
<li>${this.getDateSortButton(SortField.weeklyview)}</li>
|
|
459
|
+
</ul>
|
|
460
|
+
</div>
|
|
461
|
+
`;
|
|
462
|
+
}
|
|
463
|
+
|
|
417
464
|
private getDateSortButton(sortField: SortField) {
|
|
418
465
|
return html`
|
|
419
466
|
<button
|
|
@@ -429,6 +476,7 @@ export class SortFilterBar
|
|
|
429
476
|
|
|
430
477
|
private selectDateSort(sortField: SortField) {
|
|
431
478
|
this.dateSortSelectorVisible = false;
|
|
479
|
+
this.viewSortSelectorVisible = false;
|
|
432
480
|
this.setSelectedSort(sortField);
|
|
433
481
|
}
|
|
434
482
|
|
|
@@ -462,6 +510,24 @@ export class SortFilterBar
|
|
|
462
510
|
return dateSortFields.includes(this.selectedSort);
|
|
463
511
|
}
|
|
464
512
|
|
|
513
|
+
/**
|
|
514
|
+
* There are two view sort options.
|
|
515
|
+
*
|
|
516
|
+
* This checks to see if the current sort is one of them.
|
|
517
|
+
*
|
|
518
|
+
* @readonly
|
|
519
|
+
* @private
|
|
520
|
+
* @type {boolean}
|
|
521
|
+
* @memberof SortFilterBar
|
|
522
|
+
*/
|
|
523
|
+
private get viewOptionSelected(): boolean {
|
|
524
|
+
const viewSortFields: SortField[] = [
|
|
525
|
+
SortField.alltimeview,
|
|
526
|
+
SortField.weeklyview,
|
|
527
|
+
];
|
|
528
|
+
return viewSortFields.includes(this.selectedSort);
|
|
529
|
+
}
|
|
530
|
+
|
|
465
531
|
/**
|
|
466
532
|
* The display name of the current date field
|
|
467
533
|
*
|
|
@@ -478,6 +544,22 @@ export class SortFilterBar
|
|
|
478
544
|
return name;
|
|
479
545
|
}
|
|
480
546
|
|
|
547
|
+
/**
|
|
548
|
+
* The display name of the current view field
|
|
549
|
+
*
|
|
550
|
+
* @readonly
|
|
551
|
+
* @private
|
|
552
|
+
* @type {string}
|
|
553
|
+
* @memberof SortFilterBar
|
|
554
|
+
*/
|
|
555
|
+
private get viewSortField(): string {
|
|
556
|
+
const defaultSort = SortFieldDisplayName[SortField.weeklyview];
|
|
557
|
+
const name = this.viewOptionSelected
|
|
558
|
+
? SortFieldDisplayName[this.selectedSort] ?? defaultSort
|
|
559
|
+
: defaultSort;
|
|
560
|
+
return name;
|
|
561
|
+
}
|
|
562
|
+
|
|
481
563
|
private get titleSelectorBar() {
|
|
482
564
|
return html` <alpha-bar
|
|
483
565
|
.selectedLetter=${this.selectedTitleFilter}
|
|
@@ -607,7 +689,8 @@ export class SortFilterBar
|
|
|
607
689
|
cursor: default;
|
|
608
690
|
}
|
|
609
691
|
|
|
610
|
-
#date-sort-selector
|
|
692
|
+
#date-sort-selector,
|
|
693
|
+
#view-sort-selector {
|
|
611
694
|
position: absolute;
|
|
612
695
|
left: 150px;
|
|
613
696
|
top: 45px;
|
|
@@ -619,7 +702,8 @@ export class SortFilterBar
|
|
|
619
702
|
border: 1px solid #404142;
|
|
620
703
|
}
|
|
621
704
|
|
|
622
|
-
#date-sort-selector button
|
|
705
|
+
#date-sort-selector button,
|
|
706
|
+
#view-sort-selector button {
|
|
623
707
|
background: none;
|
|
624
708
|
border-radius: 15px;
|
|
625
709
|
color: #404142;
|
|
@@ -632,7 +716,8 @@ export class SortFilterBar
|
|
|
632
716
|
padding: 0.5rem 1.2rem;
|
|
633
717
|
}
|
|
634
718
|
|
|
635
|
-
#date-sort-selector button.selected
|
|
719
|
+
#date-sort-selector button.selected,
|
|
720
|
+
#view-sort-selector button.selected {
|
|
636
721
|
background-color: #404142;
|
|
637
722
|
color: white;
|
|
638
723
|
}
|
|
@@ -679,7 +764,8 @@ export class SortFilterBar
|
|
|
679
764
|
display: none;
|
|
680
765
|
}
|
|
681
766
|
|
|
682
|
-
#date-sort-selector-backdrop
|
|
767
|
+
#date-sort-selector-backdrop,
|
|
768
|
+
#view-sort-selector-backdrop {
|
|
683
769
|
position: fixed;
|
|
684
770
|
top: 0;
|
|
685
771
|
left: 0;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/* eslint-disable import/no-duplicates */
|
|
2
2
|
import { expect, fixture } from '@open-wc/testing';
|
|
3
3
|
import { html } from 'lit';
|
|
4
|
+
import sinon from 'sinon';
|
|
5
|
+
import type { InfiniteScroller } from '@internetarchive/infinite-scroller';
|
|
4
6
|
import type { CollectionBrowser } from '../src/collection-browser';
|
|
5
7
|
import '../src/collection-browser';
|
|
6
8
|
import { MockSearchService } from './mocks/mock-search-service';
|
|
@@ -59,4 +61,45 @@ describe('Collection Browser', () => {
|
|
|
59
61
|
'boop',
|
|
60
62
|
]);
|
|
61
63
|
});
|
|
64
|
+
it('refreshes when certain properties change', async () => {
|
|
65
|
+
const searchService = new MockSearchService();
|
|
66
|
+
const collectionNameCache = new MockCollectionNameCache();
|
|
67
|
+
const el = await fixture<CollectionBrowser>(
|
|
68
|
+
html`<collection-browser
|
|
69
|
+
.searchService=${searchService}
|
|
70
|
+
.collectionNameCache=${collectionNameCache}
|
|
71
|
+
></collection-browser>`
|
|
72
|
+
);
|
|
73
|
+
const infiniteScrollerRefreshSpy = sinon.spy();
|
|
74
|
+
|
|
75
|
+
const infiniteScroller = el.shadowRoot?.querySelector('infinite-scroller');
|
|
76
|
+
(infiniteScroller as InfiniteScroller).reload = infiniteScrollerRefreshSpy;
|
|
77
|
+
expect(infiniteScrollerRefreshSpy.called).to.be.false;
|
|
78
|
+
expect(infiniteScrollerRefreshSpy.callCount).to.equal(0);
|
|
79
|
+
|
|
80
|
+
// testing: `loggedIn`
|
|
81
|
+
el.loggedIn = true;
|
|
82
|
+
await el.updateComplete;
|
|
83
|
+
expect(infiniteScrollerRefreshSpy.called).to.be.true;
|
|
84
|
+
expect(infiniteScrollerRefreshSpy.callCount).to.equal(1);
|
|
85
|
+
|
|
86
|
+
el.loggedIn = false;
|
|
87
|
+
await el.updateComplete;
|
|
88
|
+
expect(infiniteScrollerRefreshSpy.callCount).to.equal(2);
|
|
89
|
+
|
|
90
|
+
// testing: `displayMode`
|
|
91
|
+
el.displayMode = 'list-compact';
|
|
92
|
+
await el.updateComplete;
|
|
93
|
+
expect(infiniteScrollerRefreshSpy.callCount).to.equal(3);
|
|
94
|
+
|
|
95
|
+
// testing: `baseNavigationUrl`
|
|
96
|
+
el.baseNavigationUrl = 'https://funtestsite.com';
|
|
97
|
+
await el.updateComplete;
|
|
98
|
+
expect(infiniteScrollerRefreshSpy.callCount).to.equal(4);
|
|
99
|
+
|
|
100
|
+
// testing: `baseImageUrl`
|
|
101
|
+
el.baseImageUrl = 'https://funtestsiteforimages.com';
|
|
102
|
+
await el.updateComplete;
|
|
103
|
+
expect(infiniteScrollerRefreshSpy.callCount).to.equal(5);
|
|
104
|
+
});
|
|
62
105
|
});
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/* eslint-disable import/no-duplicates */
|
|
2
|
+
import { expect, fixture, oneEvent } from '@open-wc/testing';
|
|
3
|
+
import { html } from 'lit';
|
|
4
|
+
import type { MoreFacetsContent } from '../../src/collection-facets/more-facets-content';
|
|
5
|
+
import '../../src/collection-facets/more-facets-content';
|
|
6
|
+
import { MockSearchService } from '../mocks/mock-search-service';
|
|
7
|
+
|
|
8
|
+
describe('More facets content', () => {
|
|
9
|
+
it('should render more facets template', async () => {
|
|
10
|
+
const el = await fixture<MoreFacetsContent>(
|
|
11
|
+
html`<more-facets-content></more-facets-content>`
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
el.facetsLoading = false;
|
|
15
|
+
await el.updateComplete;
|
|
16
|
+
|
|
17
|
+
expect(el.shadowRoot?.querySelector('.facets-content')).to.exist;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should render more facets loader template', async () => {
|
|
21
|
+
const el = await fixture<MoreFacetsContent>(
|
|
22
|
+
html`<more-facets-content></more-facets-content>`
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
el.facetsLoading = true;
|
|
26
|
+
await el.updateComplete;
|
|
27
|
+
|
|
28
|
+
expect(el.shadowRoot?.querySelector('.facets-loader')).to.exist;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should render more facets empty template', async () => {
|
|
32
|
+
const el = await fixture<MoreFacetsContent>(
|
|
33
|
+
html`<more-facets-content></more-facets-content>`
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
el.facetsLoading = false;
|
|
37
|
+
el.paginationSize = 0;
|
|
38
|
+
await el.updateComplete;
|
|
39
|
+
|
|
40
|
+
expect(
|
|
41
|
+
el.shadowRoot?.querySelector('#more-facets-page')?.textContent
|
|
42
|
+
).to.contains('No result found. please try again later.');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should render pagination for more facets', async () => {
|
|
46
|
+
const searchService = new MockSearchService();
|
|
47
|
+
|
|
48
|
+
const el = await fixture<MoreFacetsContent>(
|
|
49
|
+
html`<more-facets-content
|
|
50
|
+
.searchService=${searchService}
|
|
51
|
+
></more-facets-content>`
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
el.facetKey = 'mediatype';
|
|
55
|
+
el.facetsLoading = false;
|
|
56
|
+
el.paginationSize = 6;
|
|
57
|
+
await el.updateComplete;
|
|
58
|
+
|
|
59
|
+
expect(el.shadowRoot?.querySelectorAll('more-facets-pagination')).to.exist;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('query for more facets content using search service', async () => {
|
|
63
|
+
const searchService = new MockSearchService();
|
|
64
|
+
|
|
65
|
+
const el = await fixture<MoreFacetsContent>(
|
|
66
|
+
html`<more-facets-content
|
|
67
|
+
.searchService=${searchService}
|
|
68
|
+
></more-facets-content>`
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
el.facetKey = 'collection';
|
|
72
|
+
el.fullQuery = 'title:hello';
|
|
73
|
+
await el.updateComplete;
|
|
74
|
+
|
|
75
|
+
expect(searchService.searchParams?.query).to.equal('title:hello');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('query for specific facets data', async () => {
|
|
79
|
+
const searchService = new MockSearchService();
|
|
80
|
+
|
|
81
|
+
const el = await fixture<MoreFacetsContent>(
|
|
82
|
+
html`<more-facets-content
|
|
83
|
+
.searchService=${searchService}
|
|
84
|
+
></more-facets-content>`
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
el.facetKey = 'language';
|
|
88
|
+
el.facetsLoading = false;
|
|
89
|
+
await el.updateComplete;
|
|
90
|
+
|
|
91
|
+
expect(el.paginationSize).to.equal(1);
|
|
92
|
+
expect(el.shadowRoot?.querySelector('.facet-list')).to.exist;
|
|
93
|
+
expect(Object.keys(el.castedBuckets as []).length).to.equal(7);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('page number clicked event', async () => {
|
|
97
|
+
const searchService = new MockSearchService();
|
|
98
|
+
|
|
99
|
+
const el = await fixture<MoreFacetsContent>(
|
|
100
|
+
html`<more-facets-content
|
|
101
|
+
.searchService=${searchService}
|
|
102
|
+
></more-facets-content>`
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
setTimeout(() =>
|
|
106
|
+
el.dispatchEvent(
|
|
107
|
+
new CustomEvent('pageNumberClicked', { detail: { page: 15 } })
|
|
108
|
+
)
|
|
109
|
+
);
|
|
110
|
+
const { detail } = await oneEvent(el, 'pageNumberClicked');
|
|
111
|
+
expect(detail?.page).to.equal(15);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/* eslint-disable import/no-duplicates */
|
|
2
|
+
import { expect, fixture } from '@open-wc/testing';
|
|
3
|
+
import { html } from 'lit';
|
|
4
|
+
import type { MoreFacetsPagination } from '../../src/collection-facets/more-facets-pagination';
|
|
5
|
+
import '../../src/collection-facets/more-facets-pagination';
|
|
6
|
+
|
|
7
|
+
describe('More facets pagination', () => {
|
|
8
|
+
it('should render pagination container', async () => {
|
|
9
|
+
const el = await fixture<MoreFacetsPagination>(
|
|
10
|
+
html`<more-facets-pagination></more-facets-pagination>`
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
expect(el.shadowRoot?.querySelector('.facets-pagination')).to.exist;
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should render pagination arrow icon', async () => {
|
|
17
|
+
const el = await fixture<MoreFacetsPagination>(
|
|
18
|
+
html`<more-facets-pagination></more-facets-pagination>`
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
expect(
|
|
22
|
+
el.shadowRoot
|
|
23
|
+
?.querySelectorAll('.arrow-icon')[0]
|
|
24
|
+
?.querySelector('svg')
|
|
25
|
+
?.querySelector('title')?.textContent
|
|
26
|
+
).to.equal('Go left icon');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should render pagination right arrow icon', async () => {
|
|
30
|
+
const el = await fixture<MoreFacetsPagination>(
|
|
31
|
+
html`<more-facets-pagination></more-facets-pagination>`
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
expect(
|
|
35
|
+
el.shadowRoot
|
|
36
|
+
?.querySelectorAll('.arrow-icon')[1]
|
|
37
|
+
?.querySelector('svg')
|
|
38
|
+
?.querySelector('title')?.textContent
|
|
39
|
+
).to.equal('Go right icon');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should render pagination pages', async () => {
|
|
43
|
+
const el = await fixture<MoreFacetsPagination>(
|
|
44
|
+
html`<more-facets-pagination></more-facets-pagination>`
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
el.size = 2;
|
|
48
|
+
await el.updateComplete;
|
|
49
|
+
|
|
50
|
+
// at a time we render 5 pages
|
|
51
|
+
expect(
|
|
52
|
+
el.shadowRoot?.querySelector('.page-numbers')?.children.length
|
|
53
|
+
).to.equal(5);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should render current page as active page', async () => {
|
|
57
|
+
const el = await fixture<MoreFacetsPagination>(
|
|
58
|
+
html`<more-facets-pagination></more-facets-pagination>`
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
el.size = 2;
|
|
62
|
+
el.currentPage = 3;
|
|
63
|
+
await el.updateComplete;
|
|
64
|
+
|
|
65
|
+
expect(
|
|
66
|
+
el.shadowRoot?.querySelector('.page-numbers')?.querySelector('.current')
|
|
67
|
+
?.textContent
|
|
68
|
+
).to.contains(3);
|
|
69
|
+
});
|
|
70
|
+
});
|