@internetarchive/collection-browser 0.2.14-a1 → 0.2.14-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 +28 -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 +7 -0
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/more-facets-content.d.ts +50 -0
- package/dist/src/collection-facets/more-facets-content.js +354 -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/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/package.json +3 -1
- package/src/app-root.ts +28 -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 +6 -0
- package/src/collection-facets/more-facets-content.ts +371 -0
- package/src/collection-facets/more-facets-pagination.ts +201 -0
- package/src/collection-facets.ts +117 -1
- 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/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 you 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: white;
|
|
717
|
+
border: 0;
|
|
718
|
+
color: blue;
|
|
719
|
+
cursor: pointer;
|
|
720
|
+
}
|
|
721
|
+
.sorting-icon {
|
|
722
|
+
cursor: pointer;
|
|
723
|
+
}
|
|
608
724
|
`;
|
|
609
725
|
}
|
|
610
726
|
}
|
|
@@ -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
|
+
});
|
|
@@ -21,6 +21,19 @@ export const mockSuccessResponse: Result<SearchResponse, SearchServiceError> = {
|
|
|
21
21
|
}),
|
|
22
22
|
],
|
|
23
23
|
start: 0,
|
|
24
|
+
aggregations: {
|
|
25
|
+
'user_aggs__terms__field:mediatypeSorter__size:100': {
|
|
26
|
+
buckets: [
|
|
27
|
+
{ key: 'audio', doc_count: 121 },
|
|
28
|
+
{ key: 'movies', doc_count: 2195 },
|
|
29
|
+
{ key: 'texts', doc_count: 1392 },
|
|
30
|
+
{ key: 'data', doc_count: 605 },
|
|
31
|
+
{ key: 'web', doc_count: 301 },
|
|
32
|
+
{ key: 'collection', doc_count: 167 },
|
|
33
|
+
{ key: 'account', doc_count: 167 },
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
24
37
|
},
|
|
25
38
|
responseHeader: {
|
|
26
39
|
status: 0,
|