@internetarchive/collection-browser 2.7.2-alpha.1 → 2.7.2-alpha.3
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/.github/workflows/ci.yml +3 -2
- package/dist/src/app-root.d.ts +4 -0
- package/dist/src/app-root.js +15 -0
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/assets/img/icons/filter.d.ts +2 -0
- package/dist/src/assets/img/icons/filter.js +10 -0
- package/dist/src/assets/img/icons/filter.js.map +1 -0
- package/dist/src/collection-browser.d.ts +3 -6
- package/dist/src/collection-browser.js +25 -22
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/smart-facets/dedupe.d.ts +10 -0
- package/dist/src/collection-facets/smart-facets/dedupe.js +34 -0
- package/dist/src/collection-facets/smart-facets/dedupe.js.map +1 -0
- package/dist/src/collection-facets/smart-facets/heuristics/browser-language-heuristic.d.ts +5 -0
- package/dist/src/collection-facets/smart-facets/heuristics/browser-language-heuristic.js +24 -0
- package/dist/src/collection-facets/smart-facets/heuristics/browser-language-heuristic.js.map +1 -0
- package/dist/src/collection-facets/smart-facets/heuristics/query-keywords-heuristic.d.ts +5 -0
- package/dist/src/collection-facets/smart-facets/heuristics/query-keywords-heuristic.js +45 -0
- package/dist/src/collection-facets/smart-facets/heuristics/query-keywords-heuristic.js.map +1 -0
- package/dist/src/collection-facets/smart-facets/heuristics/wikidata-heuristic.d.ts +5 -0
- package/dist/src/collection-facets/smart-facets/heuristics/wikidata-heuristic.js +173 -0
- package/dist/src/collection-facets/smart-facets/heuristics/wikidata-heuristic.js.map +1 -0
- package/dist/src/collection-facets/smart-facets/models.d.ts +26 -0
- package/dist/src/collection-facets/smart-facets/models.js +2 -0
- package/dist/src/collection-facets/smart-facets/models.js.map +1 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-bar.d.ts +30 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-bar.js +282 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-bar.js.map +1 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-button.d.ts +11 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-button.js +117 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-button.js.map +1 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-dropdown.d.ts +14 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-dropdown.js +130 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-dropdown.js.map +1 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-equals.d.ts +2 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-equals.js +13 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-equals.js.map +1 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-heuristics.d.ts +5 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-heuristics.js +16 -0
- package/dist/src/collection-facets/smart-facets/smart-facet-heuristics.js.map +1 -0
- package/dist/src/data-source/collection-browser-data-source.js +6 -7
- package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
- package/package.json +1 -1
- package/src/app-root.ts +16 -0
- package/src/assets/img/icons/filter.ts +10 -0
- package/src/collection-browser.ts +21 -43
- package/src/collection-facets/smart-facets/dedupe.ts +42 -0
- package/src/collection-facets/smart-facets/heuristics/browser-language-heuristic.ts +27 -0
- package/src/collection-facets/smart-facets/heuristics/query-keywords-heuristic.ts +55 -0
- package/src/collection-facets/smart-facets/heuristics/wikidata-heuristic.ts +191 -0
- package/src/collection-facets/smart-facets/models.ts +32 -0
- package/src/collection-facets/smart-facets/smart-facet-bar.ts +330 -0
- package/src/collection-facets/smart-facets/smart-facet-button.ts +123 -0
- package/src/collection-facets/smart-facets/smart-facet-dropdown.ts +137 -0
- package/src/collection-facets/smart-facets/smart-facet-equals.ts +16 -0
- package/src/collection-facets/smart-facets/smart-facet-heuristics.ts +21 -0
- package/src/data-source/collection-browser-data-source.ts +8 -14
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/* eslint-disable no-continue */
|
|
2
|
+
import { __decorate } from "tslib";
|
|
3
|
+
import { css, html, LitElement, nothing, } from 'lit';
|
|
4
|
+
import { repeat } from 'lit/directives/repeat.js';
|
|
5
|
+
import { customElement, property, state } from 'lit/decorators.js';
|
|
6
|
+
import { updateSelectedFacetBucket } from '../../utils/facet-utils';
|
|
7
|
+
import { SmartQueryHeuristicGroup } from './smart-facet-heuristics';
|
|
8
|
+
import filterIcon from '../../assets/img/icons/filter';
|
|
9
|
+
import './smart-facet-button';
|
|
10
|
+
import './smart-facet-dropdown';
|
|
11
|
+
import { smartFacetEquals } from './smart-facet-equals';
|
|
12
|
+
import { dedupe } from './dedupe';
|
|
13
|
+
const fieldPrefixes = {
|
|
14
|
+
collection: 'Collection: ',
|
|
15
|
+
creator: 'By: ',
|
|
16
|
+
subject: 'About: ',
|
|
17
|
+
};
|
|
18
|
+
function capitalize(str) {
|
|
19
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
20
|
+
}
|
|
21
|
+
let SmartFacetBar = class SmartFacetBar extends LitElement {
|
|
22
|
+
constructor() {
|
|
23
|
+
super(...arguments);
|
|
24
|
+
this.filterToggleActive = false;
|
|
25
|
+
this.heuristicRecs = [];
|
|
26
|
+
this.smartFacets = [];
|
|
27
|
+
}
|
|
28
|
+
//
|
|
29
|
+
// COMPONENT LIFECYCLE METHODS
|
|
30
|
+
//
|
|
31
|
+
render() {
|
|
32
|
+
return html `
|
|
33
|
+
<div id="smart-facets-container">
|
|
34
|
+
${this.filtersToggleTemplate}
|
|
35
|
+
${repeat(this.smartFacets, f => `${f[0].label}|${f[0].facets[0].facetType}|${f[0].facets[0].bucketKey}`, facet => this.makeSmartFacet(facet))}
|
|
36
|
+
</div>
|
|
37
|
+
`;
|
|
38
|
+
}
|
|
39
|
+
willUpdate(changed) {
|
|
40
|
+
if (changed.has('query')) {
|
|
41
|
+
this.updateSmartFacets();
|
|
42
|
+
this.lastAggregations = undefined;
|
|
43
|
+
}
|
|
44
|
+
if (changed.has('aggregations') &&
|
|
45
|
+
!this.lastAggregations &&
|
|
46
|
+
this.aggregations &&
|
|
47
|
+
Object.keys(this.aggregations).length > 0) {
|
|
48
|
+
this.lastAggregations = this.aggregations;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async updateSmartFacets() {
|
|
52
|
+
console.log('updating smart facets');
|
|
53
|
+
if (this.query) {
|
|
54
|
+
this.heuristicRecs =
|
|
55
|
+
await new SmartQueryHeuristicGroup().getRecommendedFacets(this.query);
|
|
56
|
+
this.smartFacets = dedupe(this.facetsToDisplay);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//
|
|
60
|
+
// OTHER METHODS
|
|
61
|
+
//
|
|
62
|
+
makeSmartFacet(facets) {
|
|
63
|
+
if (facets.length === 0) {
|
|
64
|
+
return nothing;
|
|
65
|
+
}
|
|
66
|
+
if (facets.length === 1) {
|
|
67
|
+
return this.smartFacetButton(facets[0]);
|
|
68
|
+
}
|
|
69
|
+
return this.smartFacetDropdown(facets);
|
|
70
|
+
}
|
|
71
|
+
smartFacetButton(facet) {
|
|
72
|
+
var _a;
|
|
73
|
+
return html `
|
|
74
|
+
<smart-facet-button
|
|
75
|
+
.facetInfo=${facet}
|
|
76
|
+
.labelPrefix=${fieldPrefixes[facet.facets[0].facetType]}
|
|
77
|
+
.selected=${(_a = facet.selected) !== null && _a !== void 0 ? _a : false}
|
|
78
|
+
@facetClick=${this.facetClicked}
|
|
79
|
+
></smart-facet-button>
|
|
80
|
+
`;
|
|
81
|
+
}
|
|
82
|
+
smartFacetDropdown(facets) {
|
|
83
|
+
return html `
|
|
84
|
+
<smart-facet-dropdown
|
|
85
|
+
.facetInfo=${facets}
|
|
86
|
+
.labelPrefix=${fieldPrefixes[facets[0].facets[0].facetType]}
|
|
87
|
+
.activeFacetRef=${facets[0].facets[0]}
|
|
88
|
+
@facetClick=${this.facetDropdownClicked}
|
|
89
|
+
></smart-facet-dropdown>
|
|
90
|
+
`;
|
|
91
|
+
}
|
|
92
|
+
get filtersToggleTemplate() {
|
|
93
|
+
return html `
|
|
94
|
+
<button
|
|
95
|
+
id="filters-toggle"
|
|
96
|
+
class=${this.filterToggleActive ? 'active' : ''}
|
|
97
|
+
title="${this.filterToggleActive ? 'Hide' : 'Show'} filters pane"
|
|
98
|
+
@click=${this.filterToggleClicked}
|
|
99
|
+
>
|
|
100
|
+
${filterIcon}
|
|
101
|
+
</button>
|
|
102
|
+
`;
|
|
103
|
+
}
|
|
104
|
+
get facetsToDisplay() {
|
|
105
|
+
if (!this.lastAggregations)
|
|
106
|
+
return [];
|
|
107
|
+
const facets = [];
|
|
108
|
+
if (this.heuristicRecs.length > 0) {
|
|
109
|
+
for (const rec of this.heuristicRecs) {
|
|
110
|
+
facets.push([rec]);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const keys = [
|
|
114
|
+
'mediatype',
|
|
115
|
+
'year',
|
|
116
|
+
'language',
|
|
117
|
+
'creator',
|
|
118
|
+
'subject',
|
|
119
|
+
'collection',
|
|
120
|
+
];
|
|
121
|
+
for (const key of keys) {
|
|
122
|
+
const agg = this.lastAggregations[key];
|
|
123
|
+
if (!agg)
|
|
124
|
+
continue;
|
|
125
|
+
if (agg.buckets.length === 0)
|
|
126
|
+
continue;
|
|
127
|
+
if (['lending', 'year_histogram'].includes(key))
|
|
128
|
+
continue;
|
|
129
|
+
if (typeof agg.buckets[0] === 'number')
|
|
130
|
+
continue;
|
|
131
|
+
if (key === 'mediatype' &&
|
|
132
|
+
this.selectedFacets &&
|
|
133
|
+
Object.values(this.selectedFacets.mediatype).some(bucket => bucket.state !== 'none')) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const facetType = key;
|
|
137
|
+
const buckets = agg.buckets;
|
|
138
|
+
const unusedBuckets = buckets.filter(b => {
|
|
139
|
+
var _a;
|
|
140
|
+
const selectedFacetBucket = (_a = this.selectedFacets) === null || _a === void 0 ? void 0 : _a[facetType][b.key];
|
|
141
|
+
if (selectedFacetBucket && selectedFacetBucket.state !== 'none') {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
return true;
|
|
145
|
+
});
|
|
146
|
+
if (facetType === 'mediatype') {
|
|
147
|
+
facets.push([this.toSmartFacet(facetType, [unusedBuckets[0]])], [this.toSmartFacet(facetType, [unusedBuckets[1]])]);
|
|
148
|
+
}
|
|
149
|
+
else if (facetType === 'collection' || facetType === 'subject') {
|
|
150
|
+
const topBuckets = unusedBuckets.slice(0, 5);
|
|
151
|
+
facets.push(topBuckets.map(b => this.toSmartFacet(facetType, [b])));
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
facets.push([this.toSmartFacet(facetType, [unusedBuckets[0]])]);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return facets;
|
|
158
|
+
}
|
|
159
|
+
toSmartFacet(facetType, buckets
|
|
160
|
+
// prefix = true
|
|
161
|
+
) {
|
|
162
|
+
return {
|
|
163
|
+
facets: buckets.map(bucket => {
|
|
164
|
+
var _a;
|
|
165
|
+
let displayText = capitalize(bucket.key.toString());
|
|
166
|
+
if (facetType === 'collection') {
|
|
167
|
+
const title = (_a = this.collectionTitles) === null || _a === void 0 ? void 0 : _a.get(bucket.key.toString());
|
|
168
|
+
if (title)
|
|
169
|
+
displayText = title;
|
|
170
|
+
}
|
|
171
|
+
// if (prefix && fieldPrefixes[facetType]) {
|
|
172
|
+
// displayText = fieldPrefixes[facetType] + displayText;
|
|
173
|
+
// }
|
|
174
|
+
return {
|
|
175
|
+
facetType,
|
|
176
|
+
bucketKey: bucket.key.toString(),
|
|
177
|
+
displayText,
|
|
178
|
+
};
|
|
179
|
+
}),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
facetClicked(e) {
|
|
183
|
+
this.smartFacets = [
|
|
184
|
+
[{ ...e.detail.smartFacet, selected: !e.detail.smartFacet.selected }],
|
|
185
|
+
...this.smartFacets.filter(f => f[0] !== e.detail.smartFacet),
|
|
186
|
+
];
|
|
187
|
+
for (const facet of e.detail.details) {
|
|
188
|
+
this.selectedFacets = updateSelectedFacetBucket(this.selectedFacets, facet.facetType, facet.bucket, true);
|
|
189
|
+
}
|
|
190
|
+
const event = new CustomEvent('facetsChanged', {
|
|
191
|
+
detail: this.selectedFacets,
|
|
192
|
+
});
|
|
193
|
+
this.dispatchEvent(event);
|
|
194
|
+
}
|
|
195
|
+
facetDropdownClicked(e) {
|
|
196
|
+
if (this.smartFacets.find(sf => smartFacetEquals(sf[0], e.detail.smartFacet))) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
this.smartFacets = [
|
|
200
|
+
[{ ...e.detail.smartFacet, selected: true }],
|
|
201
|
+
...this.smartFacets,
|
|
202
|
+
];
|
|
203
|
+
for (const facet of e.detail.details) {
|
|
204
|
+
this.selectedFacets = updateSelectedFacetBucket(this.selectedFacets, facet.facetType, facet.bucket, true);
|
|
205
|
+
}
|
|
206
|
+
const event = new CustomEvent('facetsChanged', {
|
|
207
|
+
detail: this.selectedFacets,
|
|
208
|
+
});
|
|
209
|
+
this.dispatchEvent(event);
|
|
210
|
+
}
|
|
211
|
+
filterToggleClicked() {
|
|
212
|
+
this.dispatchEvent(new CustomEvent('filtersToggled'));
|
|
213
|
+
}
|
|
214
|
+
//
|
|
215
|
+
// STYLES
|
|
216
|
+
//
|
|
217
|
+
static get styles() {
|
|
218
|
+
return css `
|
|
219
|
+
#smart-facets-container {
|
|
220
|
+
display: flex;
|
|
221
|
+
align-items: center;
|
|
222
|
+
flex-wrap: wrap;
|
|
223
|
+
gap: 5px;
|
|
224
|
+
padding: 10px 0;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
#filters-toggle {
|
|
228
|
+
margin: 0;
|
|
229
|
+
border: 0;
|
|
230
|
+
padding: 5px 10px;
|
|
231
|
+
border-radius: 15px;
|
|
232
|
+
background: #194880;
|
|
233
|
+
color: white;
|
|
234
|
+
font-size: 1.6rem;
|
|
235
|
+
font-family: inherit;
|
|
236
|
+
text-decoration: none;
|
|
237
|
+
box-shadow: 1px 1px rgba(0, 0, 0, 0.4);
|
|
238
|
+
cursor: pointer;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
#filters-toggle.active {
|
|
242
|
+
background: #09294d;
|
|
243
|
+
box-shadow: -1px -1px rgba(0, 0, 0, 0.1);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
#filters-toggle > svg {
|
|
247
|
+
width: 15px;
|
|
248
|
+
filter: invert(1);
|
|
249
|
+
vertical-align: text-bottom;
|
|
250
|
+
}
|
|
251
|
+
`;
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
__decorate([
|
|
255
|
+
property({ type: String })
|
|
256
|
+
], SmartFacetBar.prototype, "query", void 0);
|
|
257
|
+
__decorate([
|
|
258
|
+
property({ type: Object })
|
|
259
|
+
], SmartFacetBar.prototype, "aggregations", void 0);
|
|
260
|
+
__decorate([
|
|
261
|
+
property({ type: Object })
|
|
262
|
+
], SmartFacetBar.prototype, "selectedFacets", void 0);
|
|
263
|
+
__decorate([
|
|
264
|
+
property({ type: Object })
|
|
265
|
+
], SmartFacetBar.prototype, "collectionTitles", void 0);
|
|
266
|
+
__decorate([
|
|
267
|
+
property({ type: Boolean })
|
|
268
|
+
], SmartFacetBar.prototype, "filterToggleActive", void 0);
|
|
269
|
+
__decorate([
|
|
270
|
+
state()
|
|
271
|
+
], SmartFacetBar.prototype, "heuristicRecs", void 0);
|
|
272
|
+
__decorate([
|
|
273
|
+
state()
|
|
274
|
+
], SmartFacetBar.prototype, "smartFacets", void 0);
|
|
275
|
+
__decorate([
|
|
276
|
+
state()
|
|
277
|
+
], SmartFacetBar.prototype, "lastAggregations", void 0);
|
|
278
|
+
SmartFacetBar = __decorate([
|
|
279
|
+
customElement('smart-facet-bar')
|
|
280
|
+
], SmartFacetBar);
|
|
281
|
+
export { SmartFacetBar };
|
|
282
|
+
//# sourceMappingURL=smart-facet-bar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-facet-bar.js","sourceRoot":"","sources":["../../../../src/collection-facets/smart-facets/smart-facet-bar.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-continue */\n\nimport {\n css,\n html,\n LitElement,\n TemplateResult,\n CSSResultGroup,\n nothing,\n PropertyValues,\n} from 'lit';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport type { Aggregation, Bucket } from '@internetarchive/search-service';\nimport type { CollectionTitles } from '../../data-source/models';\nimport type { FacetOption, SelectedFacets } from '../../models';\nimport { updateSelectedFacetBucket } from '../../utils/facet-utils';\nimport { SmartQueryHeuristicGroup } from './smart-facet-heuristics';\nimport type { SmartFacet, SmartFacetEvent } from './models';\nimport filterIcon from '../../assets/img/icons/filter';\n\nimport './smart-facet-button';\nimport './smart-facet-dropdown';\nimport { smartFacetEquals } from './smart-facet-equals';\nimport { dedupe } from './dedupe';\n\nconst fieldPrefixes: Partial<Record<FacetOption, string>> = {\n collection: 'Collection: ',\n creator: 'By: ',\n subject: 'About: ',\n};\n\nfunction capitalize(str: string) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n@customElement('smart-facet-bar')\nexport class SmartFacetBar extends LitElement {\n @property({ type: String }) query?: string;\n\n @property({ type: Object }) aggregations?: Record<string, Aggregation>;\n\n @property({ type: Object }) selectedFacets?: SelectedFacets;\n\n /** The map from collection identifiers to their titles */\n @property({ type: Object })\n collectionTitles?: CollectionTitles;\n\n @property({ type: Boolean }) filterToggleActive = false;\n\n @state() private heuristicRecs: SmartFacet[] = [];\n\n @state() private smartFacets: SmartFacet[][] = [];\n\n @state() private lastAggregations?: Record<string, Aggregation>;\n\n //\n // COMPONENT LIFECYCLE METHODS\n //\n\n render() {\n return html`\n <div id=\"smart-facets-container\">\n ${this.filtersToggleTemplate}\n ${repeat(\n this.smartFacets,\n f =>\n `${f[0].label}|${f[0].facets[0].facetType}|${f[0].facets[0].bucketKey}`,\n facet => this.makeSmartFacet(facet)\n )}\n </div>\n `;\n }\n\n protected willUpdate(changed: PropertyValues): void {\n if (changed.has('query')) {\n this.updateSmartFacets();\n this.lastAggregations = undefined;\n }\n\n if (\n changed.has('aggregations') &&\n !this.lastAggregations &&\n this.aggregations &&\n Object.keys(this.aggregations).length > 0\n ) {\n this.lastAggregations = this.aggregations;\n }\n }\n\n private async updateSmartFacets(): Promise<void> {\n console.log('updating smart facets');\n if (this.query) {\n this.heuristicRecs =\n await new SmartQueryHeuristicGroup().getRecommendedFacets(this.query);\n this.smartFacets = dedupe(this.facetsToDisplay);\n }\n }\n\n //\n // OTHER METHODS\n //\n\n private makeSmartFacet(facets: SmartFacet[]) {\n if (facets.length === 0) {\n return nothing;\n }\n if (facets.length === 1) {\n return this.smartFacetButton(facets[0]);\n }\n return this.smartFacetDropdown(facets);\n }\n\n private smartFacetButton(facet: SmartFacet) {\n return html`\n <smart-facet-button\n .facetInfo=${facet}\n .labelPrefix=${fieldPrefixes[facet.facets[0].facetType]}\n .selected=${facet.selected ?? false}\n @facetClick=${this.facetClicked}\n ></smart-facet-button>\n `;\n }\n\n private smartFacetDropdown(facets: SmartFacet[]) {\n return html`\n <smart-facet-dropdown\n .facetInfo=${facets}\n .labelPrefix=${fieldPrefixes[facets[0].facets[0].facetType]}\n .activeFacetRef=${facets[0].facets[0]}\n @facetClick=${this.facetDropdownClicked}\n ></smart-facet-dropdown>\n `;\n }\n\n private get filtersToggleTemplate(): TemplateResult {\n return html`\n <button\n id=\"filters-toggle\"\n class=${this.filterToggleActive ? 'active' : ''}\n title=\"${this.filterToggleActive ? 'Hide' : 'Show'} filters pane\"\n @click=${this.filterToggleClicked}\n >\n ${filterIcon}\n </button>\n `;\n }\n\n private get facetsToDisplay(): SmartFacet[][] {\n if (!this.lastAggregations) return [];\n\n const facets: SmartFacet[][] = [];\n\n if (this.heuristicRecs.length > 0) {\n for (const rec of this.heuristicRecs) {\n facets.push([rec]);\n }\n }\n\n const keys = [\n 'mediatype',\n 'year',\n 'language',\n 'creator',\n 'subject',\n 'collection',\n ];\n for (const key of keys) {\n const agg = this.lastAggregations[key];\n if (!agg) continue;\n if (agg.buckets.length === 0) continue;\n if (['lending', 'year_histogram'].includes(key)) continue;\n if (typeof agg.buckets[0] === 'number') continue;\n\n if (\n key === 'mediatype' &&\n this.selectedFacets &&\n Object.values(this.selectedFacets.mediatype).some(\n bucket => bucket.state !== 'none'\n )\n ) {\n continue;\n }\n\n const facetType = key as FacetOption;\n const buckets = agg.buckets as Bucket[];\n\n const unusedBuckets = buckets.filter(b => {\n const selectedFacetBucket = this.selectedFacets?.[facetType][b.key];\n if (selectedFacetBucket && selectedFacetBucket.state !== 'none') {\n return false;\n }\n return true;\n });\n\n if (facetType === 'mediatype') {\n facets.push(\n [this.toSmartFacet(facetType, [unusedBuckets[0]])],\n [this.toSmartFacet(facetType, [unusedBuckets[1]])]\n );\n } else if (facetType === 'collection' || facetType === 'subject') {\n const topBuckets = unusedBuckets.slice(0, 5);\n facets.push(topBuckets.map(b => this.toSmartFacet(facetType, [b])));\n } else {\n facets.push([this.toSmartFacet(facetType, [unusedBuckets[0]])]);\n }\n }\n\n return facets;\n }\n\n private toSmartFacet(\n facetType: FacetOption,\n buckets: Bucket[]\n // prefix = true\n ): SmartFacet {\n return {\n facets: buckets.map(bucket => {\n let displayText = capitalize(bucket.key.toString());\n if (facetType === 'collection') {\n const title = this.collectionTitles?.get(bucket.key.toString());\n if (title) displayText = title;\n }\n\n // if (prefix && fieldPrefixes[facetType]) {\n // displayText = fieldPrefixes[facetType] + displayText;\n // }\n\n return {\n facetType,\n bucketKey: bucket.key.toString(),\n displayText,\n };\n }),\n } as SmartFacet;\n }\n\n private facetClicked(e: CustomEvent<SmartFacetEvent>): void {\n this.smartFacets = [\n [{ ...e.detail.smartFacet, selected: !e.detail.smartFacet.selected }],\n ...this.smartFacets.filter(f => f[0] !== e.detail.smartFacet),\n ];\n\n for (const facet of e.detail.details) {\n this.selectedFacets = updateSelectedFacetBucket(\n this.selectedFacets,\n facet.facetType,\n facet.bucket,\n true\n );\n }\n\n const event = new CustomEvent<SelectedFacets>('facetsChanged', {\n detail: this.selectedFacets,\n });\n this.dispatchEvent(event);\n }\n\n private facetDropdownClicked(e: CustomEvent<SmartFacetEvent>): void {\n if (\n this.smartFacets.find(sf => smartFacetEquals(sf[0], e.detail.smartFacet))\n ) {\n return;\n }\n\n this.smartFacets = [\n [{ ...e.detail.smartFacet, selected: true }],\n ...this.smartFacets,\n ];\n\n for (const facet of e.detail.details) {\n this.selectedFacets = updateSelectedFacetBucket(\n this.selectedFacets,\n facet.facetType,\n facet.bucket,\n true\n );\n }\n\n const event = new CustomEvent<SelectedFacets>('facetsChanged', {\n detail: this.selectedFacets,\n });\n this.dispatchEvent(event);\n }\n\n private filterToggleClicked(): void {\n this.dispatchEvent(new CustomEvent('filtersToggled'));\n }\n\n //\n // STYLES\n //\n\n static get styles(): CSSResultGroup {\n return css`\n #smart-facets-container {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 5px;\n padding: 10px 0;\n }\n\n #filters-toggle {\n margin: 0;\n border: 0;\n padding: 5px 10px;\n border-radius: 15px;\n background: #194880;\n color: white;\n font-size: 1.6rem;\n font-family: inherit;\n text-decoration: none;\n box-shadow: 1px 1px rgba(0, 0, 0, 0.4);\n cursor: pointer;\n }\n\n #filters-toggle.active {\n background: #09294d;\n box-shadow: -1px -1px rgba(0, 0, 0, 0.1);\n }\n\n #filters-toggle > svg {\n width: 15px;\n filter: invert(1);\n vertical-align: text-bottom;\n }\n `;\n }\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { LitElement, CSSResultGroup, nothing } from 'lit';
|
|
2
|
+
import type { SmartFacet } from './models';
|
|
3
|
+
export declare class SmartFacetButton extends LitElement {
|
|
4
|
+
facetInfo?: SmartFacet;
|
|
5
|
+
labelPrefix?: string;
|
|
6
|
+
selected: boolean;
|
|
7
|
+
render(): import("lit-html").TemplateResult<1> | typeof nothing;
|
|
8
|
+
private get href();
|
|
9
|
+
private facetClicked;
|
|
10
|
+
static get styles(): CSSResultGroup;
|
|
11
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { css, html, LitElement, nothing } from 'lit';
|
|
3
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
4
|
+
import { mediatypeConfig } from '../../mediatype/mediatype-config';
|
|
5
|
+
function capitalize(str) {
|
|
6
|
+
if (!str)
|
|
7
|
+
return str;
|
|
8
|
+
return str.charAt(0).toLocaleUpperCase() + str.slice(1);
|
|
9
|
+
}
|
|
10
|
+
let SmartFacetButton = class SmartFacetButton extends LitElement {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.selected = false;
|
|
14
|
+
}
|
|
15
|
+
//
|
|
16
|
+
// COMPONENT LIFECYCLE METHODS
|
|
17
|
+
//
|
|
18
|
+
render() {
|
|
19
|
+
var _a, _b;
|
|
20
|
+
if (!this.facetInfo)
|
|
21
|
+
return nothing;
|
|
22
|
+
const isSingleFacet = this.facetInfo.facets.length === 1;
|
|
23
|
+
const firstFacet = this.facetInfo.facets[0];
|
|
24
|
+
const displayText = capitalize((this.labelPrefix ? `${this.labelPrefix} ` : '') +
|
|
25
|
+
((_b = (_a = this.facetInfo.label) !== null && _a !== void 0 ? _a : firstFacet.displayText) !== null && _b !== void 0 ? _b : firstFacet.bucketKey));
|
|
26
|
+
if (!displayText)
|
|
27
|
+
return nothing;
|
|
28
|
+
const icon = isSingleFacet && firstFacet.facetType === 'mediatype'
|
|
29
|
+
? mediatypeConfig[firstFacet.bucketKey].icon
|
|
30
|
+
: nothing;
|
|
31
|
+
return html `
|
|
32
|
+
<a
|
|
33
|
+
class="smart-facet-button ${this.selected ? 'selected' : ''}"
|
|
34
|
+
href=${this.href}
|
|
35
|
+
@click=${this.facetClicked}
|
|
36
|
+
>
|
|
37
|
+
${icon} ${displayText}
|
|
38
|
+
${this.selected
|
|
39
|
+
? html `<span style="margin-left: 5px;">×</span>`
|
|
40
|
+
: nothing}
|
|
41
|
+
</a>
|
|
42
|
+
`;
|
|
43
|
+
}
|
|
44
|
+
//
|
|
45
|
+
// OTHER METHODS
|
|
46
|
+
//
|
|
47
|
+
get href() {
|
|
48
|
+
const url = new URL(window.location.href);
|
|
49
|
+
if (this.facetInfo) {
|
|
50
|
+
for (const facet of this.facetInfo.facets) {
|
|
51
|
+
url.searchParams.append('and[]', encodeURIComponent(`${facet.facetType}:"${facet.bucketKey}"`));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return url.toString();
|
|
55
|
+
}
|
|
56
|
+
facetClicked(e) {
|
|
57
|
+
e.preventDefault();
|
|
58
|
+
if (!this.facetInfo)
|
|
59
|
+
return;
|
|
60
|
+
this.selected = !this.selected;
|
|
61
|
+
this.dispatchEvent(new CustomEvent('facetClick', {
|
|
62
|
+
detail: {
|
|
63
|
+
smartFacet: this.facetInfo,
|
|
64
|
+
details: this.facetInfo.facets.map(f => ({
|
|
65
|
+
facetType: f.facetType,
|
|
66
|
+
bucket: {
|
|
67
|
+
key: f.bucketKey,
|
|
68
|
+
count: 0,
|
|
69
|
+
state: this.selected ? 'selected' : 'none',
|
|
70
|
+
},
|
|
71
|
+
negative: false,
|
|
72
|
+
})),
|
|
73
|
+
},
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
//
|
|
77
|
+
// STYLES
|
|
78
|
+
//
|
|
79
|
+
static get styles() {
|
|
80
|
+
return css `
|
|
81
|
+
.smart-facet-button {
|
|
82
|
+
padding: 5px 10px;
|
|
83
|
+
border-radius: 15px;
|
|
84
|
+
background: #194880;
|
|
85
|
+
color: white;
|
|
86
|
+
font-size: 1.6rem;
|
|
87
|
+
font-family: inherit;
|
|
88
|
+
text-decoration: none;
|
|
89
|
+
box-shadow: 1px 1px rgba(0, 0, 0, 0.4);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.smart-facet-button.selected {
|
|
93
|
+
background: #4c76aa;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.smart-facet-button > svg {
|
|
97
|
+
width: 15px;
|
|
98
|
+
filter: invert(1);
|
|
99
|
+
vertical-align: text-top;
|
|
100
|
+
}
|
|
101
|
+
`;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
__decorate([
|
|
105
|
+
property({ type: Object })
|
|
106
|
+
], SmartFacetButton.prototype, "facetInfo", void 0);
|
|
107
|
+
__decorate([
|
|
108
|
+
property({ type: String })
|
|
109
|
+
], SmartFacetButton.prototype, "labelPrefix", void 0);
|
|
110
|
+
__decorate([
|
|
111
|
+
property({ type: Boolean })
|
|
112
|
+
], SmartFacetButton.prototype, "selected", void 0);
|
|
113
|
+
SmartFacetButton = __decorate([
|
|
114
|
+
customElement('smart-facet-button')
|
|
115
|
+
], SmartFacetButton);
|
|
116
|
+
export { SmartFacetButton };
|
|
117
|
+
//# sourceMappingURL=smart-facet-button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-facet-button.js","sourceRoot":"","sources":["../../../../src/collection-facets/smart-facets/smart-facet-button.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, CSSResultGroup, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { mediatypeConfig } from '../../mediatype/mediatype-config';\nimport type { SmartFacet } from './models';\n\nfunction capitalize(str?: string): string | undefined {\n if (!str) return str;\n return str.charAt(0).toLocaleUpperCase() + str.slice(1);\n}\n\n@customElement('smart-facet-button')\nexport class SmartFacetButton extends LitElement {\n @property({ type: Object }) facetInfo?: SmartFacet;\n\n @property({ type: String }) labelPrefix?: string;\n\n @property({ type: Boolean }) selected = false;\n\n //\n // COMPONENT LIFECYCLE METHODS\n //\n\n render() {\n if (!this.facetInfo) return nothing;\n\n const isSingleFacet = this.facetInfo.facets.length === 1;\n const firstFacet = this.facetInfo.facets[0];\n\n const displayText = capitalize(\n (this.labelPrefix ? `${this.labelPrefix} ` : '') +\n (this.facetInfo.label ?? firstFacet.displayText ?? firstFacet.bucketKey)\n );\n if (!displayText) return nothing;\n\n const icon =\n isSingleFacet && firstFacet.facetType === 'mediatype'\n ? mediatypeConfig[firstFacet.bucketKey].icon\n : nothing;\n\n return html`\n <a\n class=\"smart-facet-button ${this.selected ? 'selected' : ''}\"\n href=${this.href}\n @click=${this.facetClicked}\n >\n ${icon} ${displayText}\n ${this.selected\n ? html`<span style=\"margin-left: 5px;\">×</span>`\n : nothing}\n </a>\n `;\n }\n\n //\n // OTHER METHODS\n //\n\n private get href(): string {\n const url = new URL(window.location.href);\n if (this.facetInfo) {\n for (const facet of this.facetInfo.facets) {\n url.searchParams.append(\n 'and[]',\n encodeURIComponent(`${facet.facetType}:\"${facet.bucketKey}\"`)\n );\n }\n }\n return url.toString();\n }\n\n private facetClicked(e: Event): void {\n e.preventDefault();\n if (!this.facetInfo) return;\n\n this.selected = !this.selected;\n\n this.dispatchEvent(\n new CustomEvent('facetClick', {\n detail: {\n smartFacet: this.facetInfo,\n details: this.facetInfo.facets.map(f => ({\n facetType: f.facetType,\n bucket: {\n key: f.bucketKey,\n count: 0,\n state: this.selected ? 'selected' : 'none',\n },\n negative: false,\n })),\n },\n })\n );\n }\n\n //\n // STYLES\n //\n\n static get styles(): CSSResultGroup {\n return css`\n .smart-facet-button {\n padding: 5px 10px;\n border-radius: 15px;\n background: #194880;\n color: white;\n font-size: 1.6rem;\n font-family: inherit;\n text-decoration: none;\n box-shadow: 1px 1px rgba(0, 0, 0, 0.4);\n }\n\n .smart-facet-button.selected {\n background: #4c76aa;\n }\n\n .smart-facet-button > svg {\n width: 15px;\n filter: invert(1);\n vertical-align: text-top;\n }\n `;\n }\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { LitElement, CSSResultGroup, nothing } from 'lit';
|
|
2
|
+
import type { IaDropdown } from '@internetarchive/ia-dropdown';
|
|
3
|
+
import type { FacetRef, SmartFacet } from './models';
|
|
4
|
+
export declare class SmartFacetDropdown extends LitElement {
|
|
5
|
+
facetInfo?: SmartFacet[];
|
|
6
|
+
labelPrefix?: string;
|
|
7
|
+
activeFacetRef?: FacetRef;
|
|
8
|
+
dropdown?: IaDropdown;
|
|
9
|
+
render(): import("lit-html").TemplateResult<1> | typeof nothing;
|
|
10
|
+
private get dropdownOptions();
|
|
11
|
+
private get activeDropdownOption();
|
|
12
|
+
private optionSelected;
|
|
13
|
+
static get styles(): CSSResultGroup;
|
|
14
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { css, html, LitElement, nothing } from 'lit';
|
|
3
|
+
import { customElement, property, query } from 'lit/decorators.js';
|
|
4
|
+
let SmartFacetDropdown = class SmartFacetDropdown extends LitElement {
|
|
5
|
+
//
|
|
6
|
+
// COMPONENT LIFECYCLE METHODS
|
|
7
|
+
//
|
|
8
|
+
render() {
|
|
9
|
+
var _a, _b;
|
|
10
|
+
if (!this.facetInfo || !this.activeFacetRef)
|
|
11
|
+
return nothing;
|
|
12
|
+
if (this.facetInfo.length === 0)
|
|
13
|
+
return nothing;
|
|
14
|
+
const displayText = (_a = this.activeFacetRef.displayText) !== null && _a !== void 0 ? _a : this.activeFacetRef.bucketKey;
|
|
15
|
+
if (!displayText)
|
|
16
|
+
return nothing;
|
|
17
|
+
return html `
|
|
18
|
+
<div class="dropdown-container">
|
|
19
|
+
<ia-dropdown
|
|
20
|
+
class="dropdown"
|
|
21
|
+
displayCaret
|
|
22
|
+
openViaButton
|
|
23
|
+
closeOnSelect
|
|
24
|
+
includeSelectedOption
|
|
25
|
+
.options=${this.dropdownOptions}
|
|
26
|
+
.selectedOption=${this.activeDropdownOption}
|
|
27
|
+
@optionSelected=${this.optionSelected}
|
|
28
|
+
>
|
|
29
|
+
<span class="dropdown-label" slot="dropdown-label"
|
|
30
|
+
>${(_b = this.labelPrefix) !== null && _b !== void 0 ? _b : nothing} ${displayText}</span
|
|
31
|
+
>
|
|
32
|
+
</ia-dropdown>
|
|
33
|
+
</div>
|
|
34
|
+
`;
|
|
35
|
+
}
|
|
36
|
+
//
|
|
37
|
+
// OTHER METHODS
|
|
38
|
+
//
|
|
39
|
+
get dropdownOptions() {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
return ((_b = (_a = this.facetInfo) === null || _a === void 0 ? void 0 : _a.map(smartFacet => {
|
|
42
|
+
var _a, _b;
|
|
43
|
+
const firstFacet = smartFacet.facets[0];
|
|
44
|
+
return {
|
|
45
|
+
id: firstFacet.bucketKey,
|
|
46
|
+
label: (_b = (_a = smartFacet.label) !== null && _a !== void 0 ? _a : firstFacet.displayText) !== null && _b !== void 0 ? _b : firstFacet.bucketKey,
|
|
47
|
+
};
|
|
48
|
+
})) !== null && _b !== void 0 ? _b : []);
|
|
49
|
+
}
|
|
50
|
+
get activeDropdownOption() {
|
|
51
|
+
if (!this.activeFacetRef)
|
|
52
|
+
return undefined;
|
|
53
|
+
return this.dropdownOptions.find(opt => { var _a; return opt.id === ((_a = this.activeFacetRef) === null || _a === void 0 ? void 0 : _a.bucketKey); });
|
|
54
|
+
}
|
|
55
|
+
optionSelected(e) {
|
|
56
|
+
if (!this.facetInfo || !this.activeFacetRef)
|
|
57
|
+
return;
|
|
58
|
+
let selectedSmartFacet;
|
|
59
|
+
for (const smartFacet of this.facetInfo) {
|
|
60
|
+
const selectedRef = smartFacet.facets.find(b => b.bucketKey === e.detail.option.id);
|
|
61
|
+
if (selectedRef) {
|
|
62
|
+
this.activeFacetRef = selectedRef;
|
|
63
|
+
selectedSmartFacet = smartFacet;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (!selectedSmartFacet)
|
|
67
|
+
return;
|
|
68
|
+
this.dispatchEvent(new CustomEvent('facetClick', {
|
|
69
|
+
detail: {
|
|
70
|
+
smartFacet: selectedSmartFacet,
|
|
71
|
+
details: [
|
|
72
|
+
{
|
|
73
|
+
facetType: this.activeFacetRef.facetType,
|
|
74
|
+
bucket: {
|
|
75
|
+
key: this.activeFacetRef.bucketKey,
|
|
76
|
+
count: 0,
|
|
77
|
+
state: 'selected',
|
|
78
|
+
},
|
|
79
|
+
negative: false,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
//
|
|
86
|
+
// STYLES
|
|
87
|
+
//
|
|
88
|
+
static get styles() {
|
|
89
|
+
return css `
|
|
90
|
+
.dropdown-container {
|
|
91
|
+
padding: 5px 8px;
|
|
92
|
+
border-radius: 5px;
|
|
93
|
+
background: #194880;
|
|
94
|
+
color: white;
|
|
95
|
+
font-size: 1.6rem;
|
|
96
|
+
font-family: inherit;
|
|
97
|
+
box-shadow: 1px 1px rgba(0, 0, 0, 0.4);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.dropdown-label {
|
|
101
|
+
font-size: 1.6rem;
|
|
102
|
+
font-family: inherit;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.dropdown {
|
|
106
|
+
--dropdownBorderWidth: 5px;
|
|
107
|
+
--dropdownBorderColor: transparent;
|
|
108
|
+
--caretWidth: 14px;
|
|
109
|
+
--caretHeight: 14px;
|
|
110
|
+
}
|
|
111
|
+
`;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
__decorate([
|
|
115
|
+
property({ type: Array })
|
|
116
|
+
], SmartFacetDropdown.prototype, "facetInfo", void 0);
|
|
117
|
+
__decorate([
|
|
118
|
+
property({ type: String })
|
|
119
|
+
], SmartFacetDropdown.prototype, "labelPrefix", void 0);
|
|
120
|
+
__decorate([
|
|
121
|
+
property({ type: Object })
|
|
122
|
+
], SmartFacetDropdown.prototype, "activeFacetRef", void 0);
|
|
123
|
+
__decorate([
|
|
124
|
+
query('ia-dropdown')
|
|
125
|
+
], SmartFacetDropdown.prototype, "dropdown", void 0);
|
|
126
|
+
SmartFacetDropdown = __decorate([
|
|
127
|
+
customElement('smart-facet-dropdown')
|
|
128
|
+
], SmartFacetDropdown);
|
|
129
|
+
export { SmartFacetDropdown };
|
|
130
|
+
//# sourceMappingURL=smart-facet-dropdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-facet-dropdown.js","sourceRoot":"","sources":["../../../../src/collection-facets/smart-facets/smart-facet-dropdown.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, CSSResultGroup, nothing } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport type { IaDropdown, optionInterface } from '@internetarchive/ia-dropdown';\nimport type { FacetRef, SmartFacet, SmartFacetEvent } from './models';\n\n@customElement('smart-facet-dropdown')\nexport class SmartFacetDropdown extends LitElement {\n @property({ type: Array }) facetInfo?: SmartFacet[];\n\n @property({ type: String }) labelPrefix?: string;\n\n @property({ type: Object }) activeFacetRef?: FacetRef;\n\n @query('ia-dropdown') dropdown?: IaDropdown;\n\n //\n // COMPONENT LIFECYCLE METHODS\n //\n\n render() {\n if (!this.facetInfo || !this.activeFacetRef) return nothing;\n if (this.facetInfo.length === 0) return nothing;\n\n const displayText =\n this.activeFacetRef.displayText ?? this.activeFacetRef.bucketKey;\n if (!displayText) return nothing;\n\n return html`\n <div class=\"dropdown-container\">\n <ia-dropdown\n class=\"dropdown\"\n displayCaret\n openViaButton\n closeOnSelect\n includeSelectedOption\n .options=${this.dropdownOptions}\n .selectedOption=${this.activeDropdownOption}\n @optionSelected=${this.optionSelected}\n >\n <span class=\"dropdown-label\" slot=\"dropdown-label\"\n >${this.labelPrefix ?? nothing} ${displayText}</span\n >\n </ia-dropdown>\n </div>\n `;\n }\n\n //\n // OTHER METHODS\n //\n\n private get dropdownOptions(): optionInterface[] {\n return (\n this.facetInfo?.map(smartFacet => {\n const firstFacet = smartFacet.facets[0];\n return {\n id: firstFacet.bucketKey,\n label:\n smartFacet.label ?? firstFacet.displayText ?? firstFacet.bucketKey,\n };\n }) ?? []\n );\n }\n\n private get activeDropdownOption(): optionInterface | undefined {\n if (!this.activeFacetRef) return undefined;\n return this.dropdownOptions.find(\n opt => opt.id === this.activeFacetRef?.bucketKey\n );\n }\n\n private optionSelected(e: CustomEvent<{ option: optionInterface }>): void {\n if (!this.facetInfo || !this.activeFacetRef) return;\n\n let selectedSmartFacet;\n for (const smartFacet of this.facetInfo) {\n const selectedRef = smartFacet.facets.find(\n b => b.bucketKey === e.detail.option.id\n );\n if (selectedRef) {\n this.activeFacetRef = selectedRef;\n selectedSmartFacet = smartFacet;\n }\n }\n\n if (!selectedSmartFacet) return;\n\n this.dispatchEvent(\n new CustomEvent<SmartFacetEvent>('facetClick', {\n detail: {\n smartFacet: selectedSmartFacet,\n details: [\n {\n facetType: this.activeFacetRef.facetType,\n bucket: {\n key: this.activeFacetRef.bucketKey,\n count: 0,\n state: 'selected',\n },\n negative: false,\n },\n ],\n },\n })\n );\n }\n\n //\n // STYLES\n //\n\n static get styles(): CSSResultGroup {\n return css`\n .dropdown-container {\n padding: 5px 8px;\n border-radius: 5px;\n background: #194880;\n color: white;\n font-size: 1.6rem;\n font-family: inherit;\n box-shadow: 1px 1px rgba(0, 0, 0, 0.4);\n }\n\n .dropdown-label {\n font-size: 1.6rem;\n font-family: inherit;\n }\n\n .dropdown {\n --dropdownBorderWidth: 5px;\n --dropdownBorderColor: transparent;\n --caretWidth: 14px;\n --caretHeight: 14px;\n }\n `;\n }\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
function facetRefEquals(ref1, ref2) {
|
|
2
|
+
if (ref1 === undefined)
|
|
3
|
+
return ref2 !== undefined;
|
|
4
|
+
if (ref2 === undefined)
|
|
5
|
+
return ref1 !== undefined;
|
|
6
|
+
return ref1.facetType === ref2.facetType && ref1.bucketKey === ref2.bucketKey;
|
|
7
|
+
}
|
|
8
|
+
export function smartFacetEquals(sf1, sf2) {
|
|
9
|
+
return (sf1.label === sf2.label &&
|
|
10
|
+
sf1.facets.length === sf2.facets.length &&
|
|
11
|
+
sf1.facets.every((sf, i) => facetRefEquals(sf, sf2.facets[i])));
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=smart-facet-equals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-facet-equals.js","sourceRoot":"","sources":["../../../../src/collection-facets/smart-facets/smart-facet-equals.ts"],"names":[],"mappings":"AAEA,SAAS,cAAc,CAAC,IAAe,EAAE,IAAe;IACtD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,KAAK,SAAS,CAAC;IAClD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,KAAK,SAAS,CAAC;IAElD,OAAO,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAe,EAAE,GAAe;IAC/D,OAAO,CACL,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK;QACvB,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,MAAM;QACvC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAC/D,CAAC;AACJ,CAAC","sourcesContent":["import type { FacetRef, SmartFacet } from './models';\n\nfunction facetRefEquals(ref1?: FacetRef, ref2?: FacetRef): boolean {\n if (ref1 === undefined) return ref2 !== undefined;\n if (ref2 === undefined) return ref1 !== undefined;\n\n return ref1.facetType === ref2.facetType && ref1.bucketKey === ref2.bucketKey;\n}\n\nexport function smartFacetEquals(sf1: SmartFacet, sf2: SmartFacet) {\n return (\n sf1.label === sf2.label &&\n sf1.facets.length === sf2.facets.length &&\n sf1.facets.every((sf, i) => facetRefEquals(sf, sf2.facets[i]))\n );\n}\n"]}
|