@internetarchive/collection-browser 0.0.1-alpha.7 → 0.1.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/README.md +8 -11
- package/demo/app-root.ts +30 -96
- package/dist/demo/app-root.d.ts +3 -5
- package/dist/demo/app-root.js +28 -87
- package/dist/demo/app-root.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/src/assets/img/icons/chevron.d.ts +2 -0
- package/dist/src/assets/img/icons/chevron.js +4 -0
- package/dist/src/assets/img/icons/chevron.js.map +1 -0
- package/dist/src/assets/img/icons/eye-closed.d.ts +2 -0
- package/dist/src/assets/img/icons/eye-closed.js +5 -0
- package/dist/src/assets/img/icons/eye-closed.js.map +1 -0
- package/dist/src/assets/img/icons/eye.d.ts +2 -0
- package/dist/src/assets/img/icons/eye.js +5 -0
- package/dist/src/assets/img/icons/eye.js.map +1 -0
- package/dist/src/assets/img/icons/mediatype/account.d.ts +1 -2
- package/dist/src/assets/img/icons/mediatype/account.js +6 -4
- package/dist/src/assets/img/icons/mediatype/account.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/audio.js +7 -4
- package/dist/src/assets/img/icons/mediatype/audio.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/collection.js +7 -4
- package/dist/src/assets/img/icons/mediatype/collection.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/data.d.ts +1 -0
- package/dist/src/assets/img/icons/mediatype/data.js +15 -0
- package/dist/src/assets/img/icons/mediatype/data.js.map +1 -0
- package/dist/src/assets/img/icons/mediatype/etree.js +10 -5
- package/dist/src/assets/img/icons/mediatype/etree.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/film.js +2 -1
- package/dist/src/assets/img/icons/mediatype/film.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/images.js +9 -6
- package/dist/src/assets/img/icons/mediatype/images.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/radio.d.ts +1 -0
- package/dist/src/assets/img/icons/mediatype/radio.js +15 -0
- package/dist/src/assets/img/icons/mediatype/radio.js.map +1 -0
- package/dist/src/assets/img/icons/mediatype/software.js +9 -6
- package/dist/src/assets/img/icons/mediatype/software.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/texts.js +9 -6
- package/dist/src/assets/img/icons/mediatype/texts.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/tv.js +10 -5
- package/dist/src/assets/img/icons/mediatype/tv.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/video.js +10 -6
- package/dist/src/assets/img/icons/mediatype/video.js.map +1 -1
- package/dist/src/assets/img/icons/mediatype/web.js +9 -6
- package/dist/src/assets/img/icons/mediatype/web.js.map +1 -1
- package/dist/src/collection-browser.d.ts +57 -20
- package/dist/src/collection-browser.js +511 -128
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets.d.ts +27 -6
- package/dist/src/collection-facets.js +316 -100
- package/dist/src/collection-facets.js.map +1 -1
- package/dist/src/language-code-handler/language-code-handler.d.ts +37 -0
- package/dist/src/language-code-handler/language-code-handler.js +27 -0
- package/dist/src/language-code-handler/language-code-handler.js.map +1 -0
- package/dist/src/language-code-handler/language-code-mapping.d.ts +1 -0
- package/dist/src/language-code-handler/language-code-mapping.js +563 -0
- package/dist/src/language-code-handler/language-code-mapping.js.map +1 -0
- package/dist/src/mediatype/mediatype-config.d.ts +3 -0
- package/dist/src/mediatype/mediatype-config.js +86 -0
- package/dist/src/mediatype/mediatype-config.js.map +1 -0
- package/dist/src/models.d.ts +72 -13
- package/dist/src/models.js +57 -1
- package/dist/src/models.js.map +1 -1
- package/dist/src/restoration-state-handler.d.ts +38 -0
- package/dist/src/restoration-state-handler.js +204 -0
- package/dist/src/restoration-state-handler.js.map +1 -0
- package/dist/src/sort-filter-bar/alpha-bar.d.ts +1 -2
- package/dist/src/sort-filter-bar/alpha-bar.js +12 -8
- package/dist/src/sort-filter-bar/alpha-bar.js.map +1 -1
- package/dist/src/sort-filter-bar/img/compact.d.ts +1 -0
- package/dist/src/sort-filter-bar/img/compact.js +5 -0
- package/dist/src/sort-filter-bar/img/compact.js.map +1 -0
- package/dist/src/sort-filter-bar/img/list.d.ts +1 -0
- package/dist/src/sort-filter-bar/img/list.js +5 -0
- package/dist/src/sort-filter-bar/img/list.js.map +1 -0
- package/dist/src/sort-filter-bar/img/sort-triangle.d.ts +1 -0
- package/dist/src/sort-filter-bar/img/sort-triangle.js +5 -0
- package/dist/src/sort-filter-bar/img/sort-triangle.js.map +1 -0
- package/dist/src/sort-filter-bar/img/tile.d.ts +1 -0
- package/dist/src/sort-filter-bar/img/tile.js +5 -0
- package/dist/src/sort-filter-bar/img/tile.js.map +1 -0
- package/dist/src/sort-filter-bar/sort-filter-bar.d.ts +74 -13
- package/dist/src/sort-filter-bar/sort-filter-bar.js +547 -172
- package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
- package/dist/src/tiles/{loading-tile.d.ts → collection-browser-loading-tile.d.ts} +1 -1
- package/dist/src/tiles/collection-browser-loading-tile.js +32 -0
- package/dist/src/tiles/collection-browser-loading-tile.js.map +1 -0
- package/dist/src/tiles/grid/account-tile.d.ts +1 -1
- package/dist/src/tiles/grid/account-tile.js +5 -5
- package/dist/src/tiles/grid/account-tile.js.map +1 -1
- package/dist/src/tiles/grid/collection-tile.js +1 -2
- package/dist/src/tiles/grid/collection-tile.js.map +1 -1
- package/dist/src/tiles/grid/icons/views.d.ts +1 -1
- package/dist/src/tiles/grid/icons/views.js +2 -2
- package/dist/src/tiles/grid/icons/views.js.map +1 -1
- package/dist/src/tiles/grid/item-tile.d.ts +2 -2
- package/dist/src/tiles/grid/item-tile.js +58 -150
- package/dist/src/tiles/grid/item-tile.js.map +1 -1
- package/dist/src/tiles/item-image.d.ts +19 -0
- package/dist/src/tiles/item-image.js +204 -0
- package/dist/src/tiles/item-image.js.map +1 -0
- package/dist/src/tiles/list/account-label.d.ts +1 -0
- package/dist/src/tiles/list/account-label.js +7 -0
- package/dist/src/tiles/list/account-label.js.map +1 -0
- package/dist/src/tiles/list/date-label.d.ts +1 -0
- package/dist/src/tiles/list/date-label.js +13 -0
- package/dist/src/tiles/list/date-label.js.map +1 -0
- package/dist/src/tiles/list/tile-list-compact-header.d.ts +12 -0
- package/dist/src/tiles/list/tile-list-compact-header.js +84 -0
- package/dist/src/tiles/list/tile-list-compact-header.js.map +1 -0
- package/dist/src/tiles/list/tile-list-compact.d.ts +12 -0
- package/dist/src/tiles/list/tile-list-compact.js +203 -6
- package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
- package/dist/src/tiles/list/tile-list.d.ts +35 -10
- package/dist/src/tiles/list/tile-list.js +368 -104
- package/dist/src/tiles/list/tile-list.js.map +1 -1
- package/dist/src/{mediatype-icon.d.ts → tiles/mediatype-icon.d.ts} +2 -2
- package/dist/src/tiles/mediatype-icon.js +78 -0
- package/dist/src/tiles/mediatype-icon.js.map +1 -0
- package/dist/src/tiles/tile-dispatcher.d.ts +11 -4
- package/dist/src/tiles/tile-dispatcher.js +56 -19
- package/dist/src/tiles/tile-dispatcher.js.map +1 -1
- package/dist/src/utils/format-date.js +2 -2
- package/dist/src/utils/format-date.js.map +1 -1
- package/dist/test/collection-browser.test.d.ts +1 -0
- package/dist/test/collection-browser.test.js +16 -2
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/{utils/format-string.test.d.ts → mediatype-config.test.d.ts} +0 -0
- package/dist/test/mediatype-config.test.js +17 -0
- package/dist/test/mediatype-config.test.js.map +1 -0
- package/dist/test/utils/format-date.test.js +1 -1
- package/dist/test/utils/format-date.test.js.map +1 -1
- package/index.ts +6 -0
- package/local.archive.org.cert +86 -0
- package/local.archive.org.key +27 -0
- package/package.json +9 -5
- package/src/assets/img/icons/chevron.ts +4 -0
- package/src/assets/img/icons/eye-closed.ts +5 -0
- package/src/assets/img/icons/eye.ts +5 -0
- package/src/assets/img/icons/mediatype/account.ts +6 -4
- package/src/assets/img/icons/mediatype/audio.ts +7 -4
- package/src/assets/img/icons/mediatype/collection.ts +7 -4
- package/src/assets/img/icons/mediatype/data.ts +15 -0
- package/src/assets/img/icons/mediatype/etree.ts +10 -5
- package/src/assets/img/icons/mediatype/film.ts +2 -1
- package/src/assets/img/icons/mediatype/images.ts +9 -6
- package/src/assets/img/icons/mediatype/radio.ts +15 -0
- package/src/assets/img/icons/mediatype/software.ts +9 -6
- package/src/assets/img/icons/mediatype/texts.ts +9 -6
- package/src/assets/img/icons/mediatype/tv.ts +10 -5
- package/src/assets/img/icons/mediatype/video.ts +10 -6
- package/src/assets/img/icons/mediatype/web.ts +9 -6
- package/src/collection-browser.ts +537 -123
- package/src/collection-facets.ts +352 -132
- package/src/language-code-handler/language-code-handler.ts +64 -0
- package/src/language-code-handler/language-code-mapping.ts +564 -0
- package/src/mediatype/mediatype-config.ts +86 -0
- package/src/models.ts +141 -13
- package/src/restoration-state-handler.ts +266 -0
- package/src/sort-filter-bar/alpha-bar.ts +12 -8
- package/src/sort-filter-bar/img/compact.ts +5 -0
- package/src/sort-filter-bar/img/list.ts +5 -0
- package/src/sort-filter-bar/img/sort-triangle.ts +5 -0
- package/src/sort-filter-bar/img/tile.ts +5 -0
- package/src/sort-filter-bar/sort-filter-bar.ts +604 -176
- package/src/tiles/collection-browser-loading-tile.ts +29 -0
- package/src/tiles/grid/account-tile.ts +1 -1
- package/src/tiles/grid/collection-tile.ts +1 -2
- package/src/tiles/grid/icons/views.ts +2 -2
- package/src/tiles/grid/item-tile.ts +57 -162
- package/src/tiles/item-image.ts +206 -0
- package/src/tiles/list/account-label.ts +6 -0
- package/src/tiles/list/date-label.ts +12 -0
- package/src/tiles/list/tile-list-compact-header.ts +77 -0
- package/src/tiles/list/tile-list-compact.ts +218 -0
- package/src/tiles/list/tile-list.ts +412 -107
- package/src/tiles/mediatype-icon.ts +75 -0
- package/src/tiles/tile-dispatcher.ts +66 -18
- package/src/utils/format-date.ts +2 -2
- package/test/collection-browser.test.ts +20 -1
- package/test/mediatype-config.test.ts +18 -0
- package/test/utils/format-date.test.ts +1 -1
- package/web-dev-server.config.mjs +3 -1
- package/dist/src/assets/img/icons/audio.d.ts +0 -1
- package/dist/src/assets/img/icons/audio.js +0 -9
- package/dist/src/assets/img/icons/audio.js.map +0 -1
- package/dist/src/assets/img/icons/collection.d.ts +0 -1
- package/dist/src/assets/img/icons/collection.js +0 -9
- package/dist/src/assets/img/icons/collection.js.map +0 -1
- package/dist/src/assets/img/icons/etree.d.ts +0 -1
- package/dist/src/assets/img/icons/etree.js +0 -9
- package/dist/src/assets/img/icons/etree.js.map +0 -1
- package/dist/src/assets/img/icons/images.d.ts +0 -1
- package/dist/src/assets/img/icons/images.js +0 -10
- package/dist/src/assets/img/icons/images.js.map +0 -1
- package/dist/src/assets/img/icons/mediatype/etree copy.d.ts +0 -1
- package/dist/src/assets/img/icons/mediatype/etree copy.js +0 -9
- package/dist/src/assets/img/icons/mediatype/etree copy.js.map +0 -1
- package/dist/src/assets/img/icons/mediatype/livemusic.d.ts +0 -1
- package/dist/src/assets/img/icons/mediatype/livemusic.js +0 -7
- package/dist/src/assets/img/icons/mediatype/livemusic.js.map +0 -1
- package/dist/src/assets/img/icons/mediatype/photos.d.ts +0 -1
- package/dist/src/assets/img/icons/mediatype/photos.js +0 -7
- package/dist/src/assets/img/icons/mediatype/photos.js.map +0 -1
- package/dist/src/assets/img/icons/software.d.ts +0 -1
- package/dist/src/assets/img/icons/software.js +0 -10
- package/dist/src/assets/img/icons/software.js.map +0 -1
- package/dist/src/assets/img/icons/texts.d.ts +0 -1
- package/dist/src/assets/img/icons/texts.js +0 -10
- package/dist/src/assets/img/icons/texts.js.map +0 -1
- package/dist/src/assets/img/icons/tv.d.ts +0 -1
- package/dist/src/assets/img/icons/tv.js +0 -9
- package/dist/src/assets/img/icons/tv.js.map +0 -1
- package/dist/src/assets/img/icons/video.d.ts +0 -1
- package/dist/src/assets/img/icons/video.js +0 -10
- package/dist/src/assets/img/icons/video.js.map +0 -1
- package/dist/src/assets/img/icons/web.d.ts +0 -1
- package/dist/src/assets/img/icons/web.js +0 -10
- package/dist/src/assets/img/icons/web.js.map +0 -1
- package/dist/src/mediatype-icon.js +0 -89
- package/dist/src/mediatype-icon.js.map +0 -1
- package/dist/src/search-handler.d.ts +0 -11
- package/dist/src/search-handler.js +0 -34
- package/dist/src/search-handler.js.map +0 -1
- package/dist/src/tiles/list/tile-list-detail.d.ts +0 -7
- package/dist/src/tiles/list/tile-list-detail.js +0 -28
- package/dist/src/tiles/list/tile-list-detail.js.map +0 -1
- package/dist/src/tiles/loading-tile.js +0 -73
- package/dist/src/tiles/loading-tile.js.map +0 -1
- package/dist/src/utils/format-string.d.ts +0 -2
- package/dist/src/utils/format-string.js +0 -7
- package/dist/src/utils/format-string.js.map +0 -1
- package/dist/test/utils/format-string.test.js +0 -17
- package/dist/test/utils/format-string.test.js.map +0 -1
- package/src/assets/img/icons/mediatype/foo.svg +0 -5
- package/src/mediatype-icon.ts +0 -83
- package/src/tiles/loading-tile.ts +0 -70
package/src/collection-facets.ts
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
/* eslint-disable import/no-duplicates */
|
|
2
|
+
import {
|
|
3
|
+
css,
|
|
4
|
+
html,
|
|
5
|
+
LitElement,
|
|
6
|
+
PropertyValues,
|
|
7
|
+
nothing,
|
|
8
|
+
TemplateResult,
|
|
9
|
+
} from 'lit';
|
|
10
|
+
import { customElement, property, state } from 'lit/decorators.js';
|
|
3
11
|
import { repeat } from 'lit/directives/repeat.js';
|
|
4
|
-
import { Aggregation } from '@internetarchive/search-service';
|
|
12
|
+
import { Aggregation, Bucket } from '@internetarchive/search-service';
|
|
5
13
|
import '@internetarchive/histogram-date-range';
|
|
6
14
|
import '@internetarchive/feature-feedback';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
import '@internetarchive/collection-name-cache';
|
|
16
|
+
import { CollectionNameCacheInterface } from '@internetarchive/collection-name-cache';
|
|
17
|
+
import eyeIcon from './assets/img/icons/eye';
|
|
18
|
+
import eyeClosedIcon from './assets/img/icons/eye-closed';
|
|
19
|
+
import chevronIcon from './assets/img/icons/chevron';
|
|
20
|
+
import {
|
|
21
|
+
FacetOption,
|
|
22
|
+
SelectedFacets,
|
|
23
|
+
FacetGroup,
|
|
24
|
+
FacetBucket,
|
|
25
|
+
defaultSelectedFacets,
|
|
26
|
+
} from './models';
|
|
27
|
+
import { LanguageCodeHandlerInterface } from './language-code-handler/language-code-handler';
|
|
15
28
|
|
|
16
29
|
const facetDisplayOrder: FacetOption[] = [
|
|
17
30
|
'mediatype',
|
|
@@ -40,82 +53,88 @@ const facetTitles: Record<FacetOption, string> = {
|
|
|
40
53
|
year: 'Year',
|
|
41
54
|
};
|
|
42
55
|
|
|
43
|
-
interface FacetBucket {
|
|
44
|
-
// for some facets, we augment the key with a display value
|
|
45
|
-
displayText?: string;
|
|
46
|
-
key: string;
|
|
47
|
-
count: number;
|
|
48
|
-
selected: boolean;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
interface FacetGroup {
|
|
52
|
-
title: string;
|
|
53
|
-
key: string;
|
|
54
|
-
buckets: FacetBucket[];
|
|
55
|
-
}
|
|
56
|
-
|
|
57
56
|
@customElement('collection-facets')
|
|
58
57
|
export class CollectionFacets extends LitElement {
|
|
59
58
|
@property({ type: Object }) aggregations?: Record<string, Aggregation>;
|
|
60
59
|
|
|
61
60
|
@property({ type: Object }) fullYearsHistogramAggregation?: Aggregation;
|
|
62
61
|
|
|
63
|
-
@property({ type:
|
|
62
|
+
@property({ type: String }) minSelectedDate?: string;
|
|
63
|
+
|
|
64
|
+
@property({ type: String }) maxSelectedDate?: string;
|
|
64
65
|
|
|
65
66
|
@property({ type: Boolean }) facetsLoading = false;
|
|
66
67
|
|
|
67
68
|
@property({ type: Boolean }) fullYearAggregationLoading = false;
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
70
|
+
@property({ type: Object }) selectedFacets?: SelectedFacets;
|
|
71
|
+
|
|
72
|
+
@property({ type: Boolean }) collapsableFacets = false;
|
|
73
|
+
|
|
74
|
+
@property({ type: Boolean }) showHistogramDatePicker = false;
|
|
75
|
+
|
|
76
|
+
@property({ type: Object })
|
|
77
|
+
languageCodeHandler?: LanguageCodeHandlerInterface;
|
|
78
|
+
|
|
79
|
+
@property({ type: Object })
|
|
80
|
+
collectionNameCache?: CollectionNameCacheInterface;
|
|
81
|
+
|
|
82
|
+
@state() openFacets: Record<FacetOption, boolean> = {
|
|
83
|
+
subject: false,
|
|
84
|
+
mediatype: false,
|
|
85
|
+
language: false,
|
|
86
|
+
creator: false,
|
|
87
|
+
collection: false,
|
|
88
|
+
year: false,
|
|
89
|
+
};
|
|
80
90
|
|
|
81
91
|
render() {
|
|
82
92
|
return html`
|
|
83
93
|
<div id="container" class="${this.facetsLoading ? 'loading' : ''}">
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
${this.histogramTemplate}
|
|
87
|
-
</div>
|
|
88
|
-
|
|
89
|
-
${this.mergedFacets.map(
|
|
90
|
-
facetGroup =>
|
|
91
|
-
html`
|
|
94
|
+
${this.showHistogramDatePicker && this.fullYearsHistogramAggregation
|
|
95
|
+
? html`
|
|
92
96
|
<div class="facet-group">
|
|
93
|
-
<h1
|
|
94
|
-
${this.
|
|
97
|
+
<h1>Year Published <feature-feedback></feature-feedback></h1>
|
|
98
|
+
${this.histogramTemplate}
|
|
95
99
|
</div>
|
|
96
100
|
`
|
|
101
|
+
: nothing}
|
|
102
|
+
${this.mergedFacets.map(facetGroup =>
|
|
103
|
+
this.getFacetGroupTemplate(facetGroup)
|
|
97
104
|
)}
|
|
98
105
|
</div>
|
|
99
106
|
`;
|
|
100
107
|
}
|
|
101
108
|
|
|
109
|
+
updated(changed: PropertyValues) {
|
|
110
|
+
if (changed.has('selectedFacets')) {
|
|
111
|
+
this.dispatchFacetsChangedEvent();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private dispatchFacetsChangedEvent() {
|
|
116
|
+
const event = new CustomEvent<SelectedFacets>('facetsChanged', {
|
|
117
|
+
detail: this.selectedFacets,
|
|
118
|
+
});
|
|
119
|
+
this.dispatchEvent(event);
|
|
120
|
+
}
|
|
121
|
+
|
|
102
122
|
private get currentYearsHistogramAggregation(): Aggregation | undefined {
|
|
103
123
|
return this.aggregations?.year_histogram;
|
|
104
124
|
}
|
|
105
125
|
|
|
106
126
|
private get histogramTemplate() {
|
|
107
|
-
const {
|
|
108
|
-
this;
|
|
127
|
+
const { fullYearsHistogramAggregation } = this;
|
|
109
128
|
return html`
|
|
110
129
|
<histogram-date-range
|
|
111
130
|
.minDate=${fullYearsHistogramAggregation?.first_bucket_key}
|
|
112
131
|
.maxDate=${fullYearsHistogramAggregation?.last_bucket_key}
|
|
113
|
-
.minSelectedDate=${
|
|
114
|
-
.maxSelectedDate=${
|
|
132
|
+
.minSelectedDate=${this.minSelectedDate}
|
|
133
|
+
.maxSelectedDate=${this.maxSelectedDate}
|
|
115
134
|
.updateDelay=${100}
|
|
116
135
|
missingDataMessage="..."
|
|
117
136
|
.width=${180}
|
|
118
|
-
.bins=${fullYearsHistogramAggregation?.buckets}
|
|
137
|
+
.bins=${fullYearsHistogramAggregation?.buckets as number[]}
|
|
119
138
|
@histogramDateRangeUpdated=${this.histogramDateRangeUpdated}
|
|
120
139
|
></histogram-date-range>
|
|
121
140
|
`;
|
|
@@ -166,13 +185,12 @@ export class CollectionFacets extends LitElement {
|
|
|
166
185
|
const selectedBucket = aggregateFacetGroup.buckets.find(
|
|
167
186
|
b => b.key === bucket.key
|
|
168
187
|
);
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
return bucket;
|
|
188
|
+
return selectedBucket
|
|
189
|
+
? {
|
|
190
|
+
...bucket,
|
|
191
|
+
count: selectedBucket.count,
|
|
192
|
+
}
|
|
193
|
+
: bucket;
|
|
176
194
|
}) ?? [];
|
|
177
195
|
|
|
178
196
|
// append any additional buckets that were not selected
|
|
@@ -183,8 +201,6 @@ export class CollectionFacets extends LitElement {
|
|
|
183
201
|
});
|
|
184
202
|
facetGroup.buckets = bucketsWithCount.splice(0, 5);
|
|
185
203
|
|
|
186
|
-
if (facetGroup.buckets.length === 0) return;
|
|
187
|
-
|
|
188
204
|
facetGroups.push(facetGroup);
|
|
189
205
|
});
|
|
190
206
|
|
|
@@ -192,24 +208,46 @@ export class CollectionFacets extends LitElement {
|
|
|
192
208
|
}
|
|
193
209
|
|
|
194
210
|
/**
|
|
195
|
-
* Converts the
|
|
211
|
+
* Converts the selected facets to a `FacetGroup` array,
|
|
212
|
+
* which is easier to work with
|
|
196
213
|
*/
|
|
197
214
|
private get selectedFacetGroups(): FacetGroup[] {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
215
|
+
if (!this.selectedFacets) return [];
|
|
216
|
+
|
|
217
|
+
const facetGroups: FacetGroup[] = Object.entries(this.selectedFacets).map(
|
|
218
|
+
([key, selectedFacets]) => {
|
|
219
|
+
const option = key as FacetOption;
|
|
220
|
+
const title = facetTitles[option];
|
|
221
|
+
|
|
222
|
+
const buckets: FacetBucket[] = Object.entries(selectedFacets).map(
|
|
223
|
+
([value, facetState]) => {
|
|
224
|
+
let displayText = value;
|
|
225
|
+
// for selected languages, we store the language code instead of the
|
|
226
|
+
// display name, so look up the name from the mapping
|
|
227
|
+
if (option === 'language') {
|
|
228
|
+
displayText =
|
|
229
|
+
this.languageCodeHandler?.getLanguageNameFromCodeString(
|
|
230
|
+
value
|
|
231
|
+
) ?? value;
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
displayText,
|
|
235
|
+
key: value,
|
|
236
|
+
count: 0,
|
|
237
|
+
state: facetState,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
return {
|
|
243
|
+
title,
|
|
244
|
+
key: option,
|
|
245
|
+
buckets,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
return facetGroups;
|
|
213
251
|
}
|
|
214
252
|
|
|
215
253
|
/**
|
|
@@ -218,14 +256,30 @@ export class CollectionFacets extends LitElement {
|
|
|
218
256
|
private get aggregationFacetGroups(): FacetGroup[] {
|
|
219
257
|
const facetGroups: FacetGroup[] = [];
|
|
220
258
|
Object.entries(this.aggregations ?? []).forEach(([key, buckets]) => {
|
|
259
|
+
// the year_histogram data is in a different format so can't be handled here
|
|
221
260
|
if (key === 'year_histogram') return;
|
|
222
261
|
const option = this.getFacetOptionFromKey(key);
|
|
223
262
|
const title = facetTitles[option];
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
263
|
+
const castedBuckets = buckets.buckets as Bucket[];
|
|
264
|
+
const facetBuckets: FacetBucket[] = castedBuckets.map(bucket => {
|
|
265
|
+
let bucketKey = bucket.key;
|
|
266
|
+
// for languages, we need to search by language code instead of the
|
|
267
|
+
// display name, which is what we get from the search engine result
|
|
268
|
+
if (option === 'language') {
|
|
269
|
+
// const languageCodeKey = languageToCodeMap[bucket.key];
|
|
270
|
+
bucketKey =
|
|
271
|
+
this.languageCodeHandler?.getCodeStringFromLanguageName(
|
|
272
|
+
`${bucket.key}`
|
|
273
|
+
) ?? bucket.key;
|
|
274
|
+
// bucketKey = languageCodeKey ?? bucket.key;
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
displayText: `${bucket.key}`,
|
|
278
|
+
key: `${bucketKey}`,
|
|
279
|
+
count: bucket.doc_count,
|
|
280
|
+
state: 'none',
|
|
281
|
+
};
|
|
282
|
+
});
|
|
229
283
|
const group: FacetGroup = {
|
|
230
284
|
title,
|
|
231
285
|
key: option,
|
|
@@ -236,74 +290,177 @@ export class CollectionFacets extends LitElement {
|
|
|
236
290
|
return facetGroups;
|
|
237
291
|
}
|
|
238
292
|
|
|
239
|
-
|
|
293
|
+
/**
|
|
294
|
+
* Generate the template for a facet group with a header and the collapsible
|
|
295
|
+
* chevron for the mobile view
|
|
296
|
+
*/
|
|
297
|
+
private getFacetGroupTemplate(
|
|
298
|
+
facetGroup: FacetGroup
|
|
299
|
+
): TemplateResult | typeof nothing {
|
|
300
|
+
if (facetGroup.buckets.length === 0) return nothing;
|
|
301
|
+
const { key } = facetGroup;
|
|
302
|
+
const isOpen = this.openFacets[key];
|
|
303
|
+
const collapser = html`
|
|
304
|
+
<span class="collapser ${isOpen ? 'open' : ''}"> ${chevronIcon} </span>
|
|
305
|
+
`;
|
|
306
|
+
|
|
307
|
+
return html`
|
|
308
|
+
<div class="facet-group ${this.collapsableFacets ? 'mobile' : ''}">
|
|
309
|
+
<h1
|
|
310
|
+
@click=${() => {
|
|
311
|
+
const newOpenFacets = { ...this.openFacets };
|
|
312
|
+
newOpenFacets[key] = !isOpen;
|
|
313
|
+
this.openFacets = newOpenFacets;
|
|
314
|
+
}}
|
|
315
|
+
@keyup=${() => {
|
|
316
|
+
const newOpenFacets = { ...this.openFacets };
|
|
317
|
+
newOpenFacets[key] = !isOpen;
|
|
318
|
+
this.openFacets = newOpenFacets;
|
|
319
|
+
}}
|
|
320
|
+
>
|
|
321
|
+
${this.collapsableFacets ? collapser : nothing} ${facetGroup.title}
|
|
322
|
+
</h1>
|
|
323
|
+
<div class="facet-group-content ${isOpen ? 'open' : ''}">
|
|
324
|
+
${this.getFacetTemplate(facetGroup)}
|
|
325
|
+
</div>
|
|
326
|
+
</div>
|
|
327
|
+
`;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Generate the list template for each bucket in a facet group
|
|
332
|
+
*/
|
|
333
|
+
private getFacetTemplate(facetGroup: FacetGroup): TemplateResult {
|
|
334
|
+
const bucketsNoFavorites = facetGroup.buckets.filter(
|
|
335
|
+
bucket => bucket.key.startsWith('fav-') === false
|
|
336
|
+
);
|
|
337
|
+
const bucketsMaxSix = bucketsNoFavorites.slice(0, 6);
|
|
338
|
+
|
|
240
339
|
return html`
|
|
241
340
|
<ul class="facet-list">
|
|
242
341
|
${repeat(
|
|
243
|
-
|
|
342
|
+
bucketsMaxSix,
|
|
244
343
|
bucket => `${facetGroup.key}:${bucket.key}`,
|
|
245
|
-
bucket =>
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
344
|
+
bucket => {
|
|
345
|
+
const showOnlyCheckboxId = `${facetGroup.key}:${bucket.key}-show-only`;
|
|
346
|
+
const negativeCheckboxId = `${facetGroup.key}:${bucket.key}-negative`;
|
|
347
|
+
|
|
348
|
+
// for collections, we need to asynchronously load the collection name
|
|
349
|
+
// so we use the `async-collection-name` widget and for the rest, we have
|
|
350
|
+
// a static value to use
|
|
351
|
+
const bucketTextDisplay =
|
|
352
|
+
facetGroup.key !== 'collection'
|
|
353
|
+
? html`${bucket.displayText ?? bucket.key}`
|
|
354
|
+
: html`
|
|
355
|
+
<async-collection-name
|
|
356
|
+
.collectionNameCache=${this.collectionNameCache}
|
|
357
|
+
.identifier=${bucket.key}
|
|
358
|
+
placeholder="-"
|
|
359
|
+
></async-collection-name>
|
|
360
|
+
`;
|
|
361
|
+
|
|
362
|
+
const facetHidden = bucket.state === 'hidden';
|
|
363
|
+
const facetSelected = bucket.state === 'selected';
|
|
364
|
+
|
|
365
|
+
const titleText = `${facetGroup.key}: ${
|
|
366
|
+
bucket.displayText ?? bucket.key
|
|
367
|
+
}`;
|
|
368
|
+
const onlyShowText = facetSelected
|
|
369
|
+
? `Show all ${facetGroup.key}s`
|
|
370
|
+
: `Only show ${titleText}`;
|
|
371
|
+
const hideText = `Hide ${titleText}`;
|
|
372
|
+
const unhideText = `Unhide ${titleText}`;
|
|
373
|
+
const showHideText = facetHidden ? unhideText : hideText;
|
|
374
|
+
|
|
375
|
+
return html`
|
|
376
|
+
<li>
|
|
377
|
+
<div class="facet-row">
|
|
378
|
+
<div class="facet-checkbox">
|
|
379
|
+
<input
|
|
380
|
+
type="checkbox"
|
|
381
|
+
.name=${facetGroup.key}
|
|
382
|
+
.value=${bucket.key}
|
|
383
|
+
@click=${(e: Event) => {
|
|
384
|
+
this.facetClicked(e, bucket, false);
|
|
385
|
+
}}
|
|
386
|
+
.checked=${facetSelected}
|
|
387
|
+
class="select-facet-checkbox"
|
|
388
|
+
title=${onlyShowText}
|
|
389
|
+
id=${showOnlyCheckboxId}
|
|
390
|
+
/>
|
|
391
|
+
<input
|
|
392
|
+
type="checkbox"
|
|
393
|
+
id=${negativeCheckboxId}
|
|
394
|
+
.name=${facetGroup.key}
|
|
395
|
+
.value=${bucket.key}
|
|
396
|
+
@click=${(e: Event) => {
|
|
397
|
+
this.facetClicked(e, bucket, true);
|
|
398
|
+
}}
|
|
399
|
+
.checked=${facetHidden}
|
|
400
|
+
class="hide-facet-checkbox"
|
|
401
|
+
/>
|
|
402
|
+
<label
|
|
403
|
+
for=${negativeCheckboxId}
|
|
404
|
+
class="hide-facet-icon"
|
|
405
|
+
title=${showHideText}
|
|
406
|
+
>
|
|
407
|
+
${facetHidden ? eyeClosedIcon : eyeIcon}
|
|
408
|
+
</label>
|
|
409
|
+
</div>
|
|
410
|
+
|
|
411
|
+
<label
|
|
412
|
+
for=${showOnlyCheckboxId}
|
|
413
|
+
class="facet-info-display"
|
|
414
|
+
title=${onlyShowText}
|
|
415
|
+
>
|
|
416
|
+
<div class="facet-title">${bucketTextDisplay}</div>
|
|
417
|
+
<div class="facet-count">${bucket.count}</div>
|
|
418
|
+
</label>
|
|
256
419
|
</div>
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
</li>
|
|
261
|
-
`
|
|
420
|
+
</li>
|
|
421
|
+
`;
|
|
422
|
+
}
|
|
262
423
|
)}
|
|
263
424
|
</ul>
|
|
264
425
|
`;
|
|
265
426
|
}
|
|
266
427
|
|
|
267
|
-
private
|
|
268
|
-
const
|
|
269
|
-
const
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
currentFacetValues.push(value);
|
|
273
|
-
facetClone[name] = currentFacetValues;
|
|
428
|
+
private facetClicked(e: Event, bucket: FacetBucket, negative: boolean) {
|
|
429
|
+
const target = e.target as HTMLInputElement;
|
|
430
|
+
const { checked, name, value } = target;
|
|
431
|
+
if (checked) {
|
|
432
|
+
this.facetChecked(name as FacetOption, value, negative);
|
|
274
433
|
} else {
|
|
275
|
-
|
|
434
|
+
this.facetUnchecked(name as FacetOption, value);
|
|
276
435
|
}
|
|
277
|
-
this.selectedFacets = facetClone;
|
|
278
436
|
}
|
|
279
437
|
|
|
280
|
-
private
|
|
438
|
+
private facetChecked(key: FacetOption, value: string, negative: boolean) {
|
|
281
439
|
const { selectedFacets } = this;
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
440
|
+
let newFacets: SelectedFacets;
|
|
441
|
+
if (selectedFacets) {
|
|
442
|
+
newFacets = {
|
|
443
|
+
...selectedFacets,
|
|
444
|
+
};
|
|
445
|
+
} else {
|
|
446
|
+
newFacets = defaultSelectedFacets;
|
|
290
447
|
}
|
|
291
|
-
|
|
448
|
+
newFacets[key][value] = negative ? 'hidden' : 'selected';
|
|
449
|
+
this.selectedFacets = newFacets;
|
|
292
450
|
}
|
|
293
451
|
|
|
294
|
-
private
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
if (
|
|
298
|
-
|
|
452
|
+
private facetUnchecked(key: FacetOption, value: string) {
|
|
453
|
+
const { selectedFacets } = this;
|
|
454
|
+
let newFacets: SelectedFacets;
|
|
455
|
+
if (selectedFacets) {
|
|
456
|
+
newFacets = {
|
|
457
|
+
...selectedFacets,
|
|
458
|
+
};
|
|
299
459
|
} else {
|
|
300
|
-
|
|
460
|
+
newFacets = defaultSelectedFacets;
|
|
301
461
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
detail: this.selectedFacets,
|
|
305
|
-
});
|
|
306
|
-
this.dispatchEvent(event);
|
|
462
|
+
delete newFacets[key][value];
|
|
463
|
+
this.selectedFacets = newFacets;
|
|
307
464
|
}
|
|
308
465
|
|
|
309
466
|
/**
|
|
@@ -332,12 +489,52 @@ export class CollectionFacets extends LitElement {
|
|
|
332
489
|
opacity: 0.5;
|
|
333
490
|
}
|
|
334
491
|
|
|
492
|
+
.collapser {
|
|
493
|
+
display: inline-block;
|
|
494
|
+
cursor: pointer;
|
|
495
|
+
width: 10px;
|
|
496
|
+
height: 10px;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
.collapser svg {
|
|
500
|
+
transition: transform 0.2s ease-in-out;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
.collapser.open svg {
|
|
504
|
+
transform: rotate(90deg);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
.facet-group {
|
|
508
|
+
margin-bottom: 2rem;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
.facet-group h1 {
|
|
512
|
+
margin-bottom: 0.7rem;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
.facet-group.mobile h1 {
|
|
516
|
+
cursor: pointer;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
.facet-group-content {
|
|
520
|
+
transition: max-height 0.2s ease-in-out;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
.facet-group.mobile .facet-group-content {
|
|
524
|
+
max-height: 0;
|
|
525
|
+
overflow: hidden;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
.facet-group.mobile .facet-group-content.open {
|
|
529
|
+
max-height: 2000px;
|
|
530
|
+
}
|
|
531
|
+
|
|
335
532
|
h1 {
|
|
336
533
|
font-size: 1.4rem;
|
|
337
534
|
font-weight: 200;
|
|
338
535
|
border-bottom: 1px solid rgb(232, 232, 232);
|
|
339
536
|
padding-bottom: 3px;
|
|
340
|
-
margin:
|
|
537
|
+
margin: 0;
|
|
341
538
|
}
|
|
342
539
|
|
|
343
540
|
ul.facet-list {
|
|
@@ -352,15 +549,23 @@ export class CollectionFacets extends LitElement {
|
|
|
352
549
|
|
|
353
550
|
.facet-checkbox {
|
|
354
551
|
margin-right: 0.5rem;
|
|
552
|
+
display: flex;
|
|
553
|
+
align-items: center;
|
|
355
554
|
}
|
|
356
555
|
|
|
357
556
|
.facet-row {
|
|
358
557
|
display: flex;
|
|
359
|
-
align-items:
|
|
558
|
+
align-items: start;
|
|
360
559
|
font-weight: 500;
|
|
361
560
|
font-size: 1.2rem;
|
|
362
561
|
}
|
|
363
562
|
|
|
563
|
+
.facet-info-display {
|
|
564
|
+
display: flex;
|
|
565
|
+
flex: 1;
|
|
566
|
+
cursor: pointer;
|
|
567
|
+
}
|
|
568
|
+
|
|
364
569
|
.facet-title {
|
|
365
570
|
flex: 1;
|
|
366
571
|
}
|
|
@@ -368,6 +573,21 @@ export class CollectionFacets extends LitElement {
|
|
|
368
573
|
.facet-count {
|
|
369
574
|
margin-left: 0.5rem;
|
|
370
575
|
}
|
|
576
|
+
|
|
577
|
+
.select-facet-checkbox {
|
|
578
|
+
cursor: pointer;
|
|
579
|
+
margin-right: 5px;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
.hide-facet-checkbox {
|
|
583
|
+
display: none;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
.hide-facet-icon {
|
|
587
|
+
width: 15px;
|
|
588
|
+
height: 15px;
|
|
589
|
+
cursor: pointer;
|
|
590
|
+
}
|
|
371
591
|
`;
|
|
372
592
|
}
|
|
373
593
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { codeToLanguageMap } from './language-code-mapping';
|
|
2
|
+
|
|
3
|
+
// To serialize the list of potential language codes, we store
|
|
4
|
+
// the string in the format `en-us|en|en-gb` with `|` being the separator.
|
|
5
|
+
// This allows us to generate a query of `language:(en-us OR en OR en-gb)`
|
|
6
|
+
// when we deserialize the string.
|
|
7
|
+
export interface LanguageCodeHandlerInterface {
|
|
8
|
+
/**
|
|
9
|
+
* This takes a list of codes in the format `en-us|en|en-gb` and
|
|
10
|
+
* returns the first language code in the list.
|
|
11
|
+
*
|
|
12
|
+
* The codes in the string should always represent the same language name.
|
|
13
|
+
* eg `en-us`, `en-gb`, and `en` should always be "English"
|
|
14
|
+
*
|
|
15
|
+
* @param languageCodes
|
|
16
|
+
*/
|
|
17
|
+
getLanguageNameFromCodeString(languageCodes: string): string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* This creates a serialized string of language codes for the given language.
|
|
21
|
+
*
|
|
22
|
+
* eg. `English` becomes `en-us|en|en-gb|.....`
|
|
23
|
+
*
|
|
24
|
+
* @param languageName
|
|
25
|
+
*/
|
|
26
|
+
getCodeStringFromLanguageName(languageName: string): string;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get an array of langauge codes from a serialized string.
|
|
30
|
+
*
|
|
31
|
+
* eg. `en-us|en|en-gb` becomes `['en-us', 'en', 'en-gb']`
|
|
32
|
+
*
|
|
33
|
+
* @param languageCodes
|
|
34
|
+
*/
|
|
35
|
+
getCodeArrayFromCodeString(languageCodes: string): string[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class LanguageCodeHandler implements LanguageCodeHandlerInterface {
|
|
39
|
+
private delimeter = '|';
|
|
40
|
+
|
|
41
|
+
/** @inheritdoc */
|
|
42
|
+
getLanguageNameFromCodeString(languageCodes: string): string {
|
|
43
|
+
const split = this.getCodeArrayFromCodeString(languageCodes);
|
|
44
|
+
if (split.length === 0) return '';
|
|
45
|
+
const languageCode = split[0];
|
|
46
|
+
const languageName = codeToLanguageMap[languageCode];
|
|
47
|
+
return languageName ?? languageCodes;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** @inheritdoc */
|
|
51
|
+
getCodeStringFromLanguageName(languageName: string): string {
|
|
52
|
+
const languageCodes = Object.keys(codeToLanguageMap).filter(
|
|
53
|
+
code => codeToLanguageMap[code] === languageName
|
|
54
|
+
);
|
|
55
|
+
const stringifiedCodes = languageCodes?.join(this.delimeter);
|
|
56
|
+
return stringifiedCodes;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** @inheritdoc */
|
|
60
|
+
getCodeArrayFromCodeString(languageCodes: string): string[] {
|
|
61
|
+
const split = languageCodes.split(this.delimeter);
|
|
62
|
+
return split;
|
|
63
|
+
}
|
|
64
|
+
}
|