@internetarchive/collection-browser 0.2.21 → 0.2.22

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.
Files changed (70) hide show
  1. package/dist/src/app-root.d.ts +1 -0
  2. package/dist/src/app-root.js +34 -4
  3. package/dist/src/app-root.js.map +1 -1
  4. package/dist/src/assets/img/icons/arrow-left.d.ts +2 -0
  5. package/dist/src/assets/img/icons/arrow-left.js +10 -0
  6. package/dist/src/assets/img/icons/arrow-left.js.map +1 -0
  7. package/dist/src/assets/img/icons/arrow-right.d.ts +2 -0
  8. package/dist/src/assets/img/icons/arrow-right.js +10 -0
  9. package/dist/src/assets/img/icons/arrow-right.js.map +1 -0
  10. package/dist/src/collection-browser.d.ts +2 -0
  11. package/dist/src/collection-browser.js +10 -2
  12. package/dist/src/collection-browser.js.map +1 -1
  13. package/dist/src/collection-facets/facets-template.d.ts +16 -0
  14. package/dist/src/collection-facets/facets-template.js +266 -0
  15. package/dist/src/collection-facets/facets-template.js.map +1 -0
  16. package/dist/src/collection-facets/facets-util.d.ts +10 -0
  17. package/dist/src/collection-facets/facets-util.js +20 -0
  18. package/dist/src/collection-facets/facets-util.js.map +1 -0
  19. package/dist/src/collection-facets/more-facets-content.d.ts +83 -0
  20. package/dist/src/collection-facets/more-facets-content.js +475 -0
  21. package/dist/src/collection-facets/more-facets-content.js.map +1 -0
  22. package/dist/src/collection-facets/more-facets-pagination.d.ts +36 -0
  23. package/dist/src/collection-facets/more-facets-pagination.js +267 -0
  24. package/dist/src/collection-facets/more-facets-pagination.js.map +1 -0
  25. package/dist/src/collection-facets.d.ts +19 -5
  26. package/dist/src/collection-facets.js +138 -239
  27. package/dist/src/collection-facets.js.map +1 -1
  28. package/dist/src/models.d.ts +4 -1
  29. package/dist/src/models.js +24 -0
  30. package/dist/src/models.js.map +1 -1
  31. package/dist/src/restoration-state-handler.js +5 -6
  32. package/dist/src/restoration-state-handler.js.map +1 -1
  33. package/dist/src/tiles/collection-browser-loading-tile.js +2 -5
  34. package/dist/src/tiles/collection-browser-loading-tile.js.map +1 -1
  35. package/dist/test/collection-browser.test.js +5 -3
  36. package/dist/test/collection-browser.test.js.map +1 -1
  37. package/dist/test/collection-facets/facets-template.test.d.ts +1 -0
  38. package/dist/test/collection-facets/facets-template.test.js +75 -0
  39. package/dist/test/collection-facets/facets-template.test.js.map +1 -0
  40. package/dist/test/collection-facets/facets-util.test.d.ts +1 -0
  41. package/dist/test/collection-facets/facets-util.test.js +13 -0
  42. package/dist/test/collection-facets/facets-util.test.js.map +1 -0
  43. package/dist/test/collection-facets/more-facets-content.test.d.ts +1 -0
  44. package/dist/test/collection-facets/more-facets-content.test.js +104 -0
  45. package/dist/test/collection-facets/more-facets-content.test.js.map +1 -0
  46. package/dist/test/collection-facets/more-facets-pagination.test.d.ts +1 -0
  47. package/dist/test/collection-facets/more-facets-pagination.test.js +133 -0
  48. package/dist/test/collection-facets/more-facets-pagination.test.js.map +1 -0
  49. package/dist/test/collection-facets.test.d.ts +1 -0
  50. package/dist/test/collection-facets.test.js +98 -33
  51. package/dist/test/collection-facets.test.js.map +1 -1
  52. package/package.json +11 -4
  53. package/src/app-root.ts +34 -4
  54. package/src/assets/img/icons/arrow-left.ts +10 -0
  55. package/src/assets/img/icons/arrow-right.ts +10 -0
  56. package/src/collection-browser.ts +9 -2
  57. package/src/collection-facets/facets-template.ts +284 -0
  58. package/src/collection-facets/facets-util.ts +22 -0
  59. package/src/collection-facets/more-facets-content.ts +529 -0
  60. package/src/collection-facets/more-facets-pagination.ts +297 -0
  61. package/src/collection-facets.ts +175 -261
  62. package/src/models.ts +28 -1
  63. package/src/restoration-state-handler.ts +7 -6
  64. package/src/tiles/collection-browser-loading-tile.ts +2 -5
  65. package/test/collection-browser.test.ts +6 -3
  66. package/test/collection-facets/facets-template.test.ts +103 -0
  67. package/test/collection-facets/facets-util.test.ts +18 -0
  68. package/test/collection-facets/more-facets-content.test.ts +146 -0
  69. package/test/collection-facets/more-facets-pagination.test.ts +202 -0
  70. package/test/collection-facets.test.ts +127 -44
@@ -0,0 +1,266 @@
1
+ import { __decorate } from "tslib";
2
+ import { css, html, LitElement } from 'lit';
3
+ import { customElement, property } from 'lit/decorators.js';
4
+ import { repeat } from 'lit/directives/repeat.js';
5
+ import eyeIcon from '../assets/img/icons/eye';
6
+ import eyeClosedIcon from '../assets/img/icons/eye-closed';
7
+ import { defaultSelectedFacets, } from '../models';
8
+ let FacetsTemplate = class FacetsTemplate extends LitElement {
9
+ facetClicked(e, count, negative) {
10
+ const target = e.target;
11
+ const { checked, name, value } = target;
12
+ if (checked) {
13
+ this.facetChecked(name, value, count, negative);
14
+ }
15
+ else {
16
+ this.facetUnchecked(name, value);
17
+ }
18
+ }
19
+ facetChecked(key, value, count, negative) {
20
+ const { selectedFacets } = this;
21
+ let newFacets;
22
+ if (selectedFacets) {
23
+ newFacets = {
24
+ ...selectedFacets,
25
+ };
26
+ }
27
+ else {
28
+ newFacets = defaultSelectedFacets;
29
+ }
30
+ newFacets[key][value] = {
31
+ state: negative ? 'hidden' : 'selected',
32
+ count,
33
+ };
34
+ this.selectedFacets = newFacets;
35
+ this.dispatchSelectedFacetsChanged();
36
+ }
37
+ facetUnchecked(key, value) {
38
+ const { selectedFacets } = this;
39
+ let newFacets;
40
+ if (selectedFacets) {
41
+ newFacets = {
42
+ ...selectedFacets,
43
+ };
44
+ }
45
+ else {
46
+ newFacets = defaultSelectedFacets;
47
+ }
48
+ delete newFacets[key][value];
49
+ this.selectedFacets = newFacets;
50
+ this.dispatchSelectedFacetsChanged();
51
+ }
52
+ dispatchSelectedFacetsChanged() {
53
+ const event = new CustomEvent('selectedFacetsChanged', {
54
+ detail: this.selectedFacets,
55
+ bubbles: true,
56
+ composed: true,
57
+ });
58
+ this.dispatchEvent(event);
59
+ }
60
+ getFacetsTemplate(facetGroup) {
61
+ let facetsBucket = facetGroup === null || facetGroup === void 0 ? void 0 : facetGroup.buckets;
62
+ /**
63
+ * sorting FacetBucket before render page / modal
64
+ * - first, selected items should be at top having sorted
65
+ * - second, suppressed/hidden items should be after selected having sorted
66
+ * - and then no-selected / not suppressed items should render having sorted
67
+ */
68
+ facetsBucket = [
69
+ ...facetsBucket
70
+ .filter(x => x.state === 'selected')
71
+ .sort((a, b) => (a.count < b.count ? 1 : -1)),
72
+ ...facetsBucket
73
+ .filter(x => x.state === 'hidden')
74
+ .sort((a, b) => (a.count < b.count ? 1 : -1)),
75
+ ...facetsBucket.filter(x => x.state === 'none'),
76
+ ];
77
+ return html `
78
+ <div class="facets-on-${this.renderOn}">
79
+ ${repeat(facetsBucket, bucket => `${facetGroup.key}:${bucket.key}`, bucket => {
80
+ var _a, _b;
81
+ const showOnlyCheckboxId = `${facetGroup.key}:${bucket.key}-show-only`;
82
+ const negativeCheckboxId = `${facetGroup.key}:${bucket.key}-negative`;
83
+ // for collections, we need to asynchronously load the collection name
84
+ // so we use the `async-collection-name` widget and for the rest, we have
85
+ // a static value to use
86
+ const bucketTextDisplay = facetGroup.key !== 'collection'
87
+ ? html `${(_a = bucket.displayText) !== null && _a !== void 0 ? _a : bucket.key}`
88
+ : html `<a href="/details/${bucket.key}">
89
+ <async-collection-name
90
+ .collectionNameCache=${this.collectionNameCache}
91
+ .identifier=${bucket.key}
92
+ placeholder="-"
93
+ ></async-collection-name>
94
+ </a> `;
95
+ const facetHidden = bucket.state === 'hidden';
96
+ const facetSelected = bucket.state === 'selected';
97
+ const titleText = `${facetGroup.key}: ${(_b = bucket.displayText) !== null && _b !== void 0 ? _b : bucket.key}`;
98
+ const onlyShowText = facetSelected
99
+ ? `Show all ${facetGroup.key}s`
100
+ : `Only show ${titleText}`;
101
+ const hideText = `Hide ${titleText}`;
102
+ const unhideText = `Unhide ${titleText}`;
103
+ const showHideText = facetHidden ? unhideText : hideText;
104
+ return html `
105
+ <div class="facet-row">
106
+ <div class="facet-checkbox">
107
+ <input
108
+ type="checkbox"
109
+ .name=${facetGroup.key}
110
+ .value=${bucket.key}
111
+ @click=${(e) => {
112
+ this.facetClicked(e, bucket.count, false);
113
+ }}
114
+ .checked=${facetSelected}
115
+ class="select-facet-checkbox"
116
+ title=${onlyShowText}
117
+ id=${showOnlyCheckboxId}
118
+ />
119
+ <input
120
+ type="checkbox"
121
+ id=${negativeCheckboxId}
122
+ .name=${facetGroup.key}
123
+ .value=${bucket.key}
124
+ @click=${(e) => {
125
+ this.facetClicked(e, bucket.count, true);
126
+ }}
127
+ .checked=${facetHidden}
128
+ class="hide-facet-checkbox"
129
+ />
130
+ <label
131
+ for=${negativeCheckboxId}
132
+ class="hide-facet-icon${facetHidden ? ' active' : ''}"
133
+ title=${showHideText}
134
+ >
135
+ <span class="eye">${eyeIcon}</span>
136
+ <span class="eye-closed">${eyeClosedIcon}</span>
137
+ </label>
138
+ </div>
139
+ <div
140
+ for=${showOnlyCheckboxId}
141
+ class="facet-info-display"
142
+ title=${onlyShowText}
143
+ >
144
+ <div class="facet-title">${bucketTextDisplay}</div>
145
+ <div class="facet-count">${bucket.count}</div>
146
+ </div>
147
+ </div>
148
+ `;
149
+ })}
150
+ </div>
151
+ `;
152
+ }
153
+ render() {
154
+ return html `${this.getFacetsTemplate(this.facetGroup)}`;
155
+ }
156
+ static get styles() {
157
+ return css `
158
+ .facets-on-modal {
159
+ /* For Chrome, Safari, Opera browsers */
160
+ -webkit-column-width: 100px;
161
+ /* For Firefox browser */
162
+ -moz-column-width: 100px;
163
+ column-width: 25rem;
164
+ column-gap: 15px;
165
+ }
166
+ .facets-on-page .select-facet-checkbox {
167
+ margin-left: 0;
168
+ }
169
+ async-collection-name {
170
+ display: contents;
171
+ }
172
+ ul.facet-list {
173
+ list-style: none;
174
+ margin: 0;
175
+ padding: 0;
176
+ }
177
+ ul.facet-list li {
178
+ margin-bottom: 0.2rem;
179
+ display: grid;
180
+ }
181
+ .facet-checkbox {
182
+ margin: 0 5px 0 0;
183
+ display: inline-block;
184
+ align-items: baseline;
185
+ }
186
+ .facet-row {
187
+ display: flex;
188
+ font-weight: 500;
189
+ font-size: 1.2rem;
190
+ }
191
+ .facet-info-display {
192
+ display: flex;
193
+ flex: 1 1 0%;
194
+ cursor: pointer;
195
+ flex-wrap: wrap;
196
+ align-content: center;
197
+ }
198
+ .facet-title {
199
+ word-break: break-word;
200
+ display: inline-block;
201
+ flex: 1 1 0%;
202
+ }
203
+ .facet-count {
204
+ text-align: right;
205
+ }
206
+ .select-facet-checkbox {
207
+ cursor: pointer;
208
+ display: inline-block;
209
+ }
210
+ .hide-facet-checkbox {
211
+ display: none;
212
+ }
213
+ .hide-facet-icon {
214
+ width: 15px;
215
+ height: 15px;
216
+ cursor: pointer;
217
+ opacity: 0.3;
218
+ display: inline-block;
219
+ }
220
+ .hide-facet-icon:hover,
221
+ .active {
222
+ opacity: 1;
223
+ }
224
+ .hide-facet-icon:hover .eye,
225
+ .hide-facet-icon .eye-closed {
226
+ display: none;
227
+ }
228
+ .hide-facet-icon:hover .eye-closed,
229
+ .hide-facet-icon.active .eye-closed {
230
+ display: inline;
231
+ }
232
+ .hide-facet-icon.active .eye {
233
+ display: none;
234
+ }
235
+ .sorting-icon {
236
+ cursor: pointer;
237
+ }
238
+
239
+ a:link,
240
+ a:visited {
241
+ text-decoration: none;
242
+ color: var(--ia-theme-link-color, #4b64ff);
243
+ }
244
+ a:hover {
245
+ text-decoration: underline;
246
+ }
247
+ `;
248
+ }
249
+ };
250
+ __decorate([
251
+ property({ type: Object })
252
+ ], FacetsTemplate.prototype, "facetGroup", void 0);
253
+ __decorate([
254
+ property({ type: Object })
255
+ ], FacetsTemplate.prototype, "selectedFacets", void 0);
256
+ __decorate([
257
+ property({ type: String })
258
+ ], FacetsTemplate.prototype, "renderOn", void 0);
259
+ __decorate([
260
+ property({ type: Object })
261
+ ], FacetsTemplate.prototype, "collectionNameCache", void 0);
262
+ FacetsTemplate = __decorate([
263
+ customElement('facets-template')
264
+ ], FacetsTemplate);
265
+ export { FacetsTemplate };
266
+ //# sourceMappingURL=facets-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facets-template.js","sourceRoot":"","sources":["../../../src/collection-facets/facets-template.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAkC,MAAM,KAAK,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,OAAO,OAAO,MAAM,yBAAyB,CAAC;AAC9C,OAAO,aAAa,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAKL,qBAAqB,GACtB,MAAM,WAAW,CAAC;AAGnB,IAAa,cAAc,GAA3B,MAAa,cAAe,SAAQ,UAAU;IAUpC,YAAY,CAAC,CAAQ,EAAE,KAAa,EAAE,QAAiB;QAC7D,MAAM,MAAM,GAAG,CAAC,CAAC,MAA0B,CAAC;QAC5C,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;QACxC,IAAI,OAAO,EAAE;YACX,IAAI,CAAC,YAAY,CAAC,IAAmB,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;SAChE;aAAM;YACL,IAAI,CAAC,cAAc,CAAC,IAAmB,EAAE,KAAK,CAAC,CAAC;SACjD;IACH,CAAC;IAEO,YAAY,CAClB,GAAgB,EAChB,KAAa,EACb,KAAa,EACb,QAAiB;QAEjB,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;QAChC,IAAI,SAAyB,CAAC;QAC9B,IAAI,cAAc,EAAE;YAClB,SAAS,GAAG;gBACV,GAAG,cAAc;aAClB,CAAC;SACH;aAAM;YACL,SAAS,GAAG,qBAAqB,CAAC;SACnC;QACD,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG;YACtB,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU;YACvC,KAAK;SACS,CAAC;QAEjB,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAChC,IAAI,CAAC,6BAA6B,EAAE,CAAC;IACvC,CAAC;IAEO,cAAc,CAAC,GAAgB,EAAE,KAAa;QACpD,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;QAChC,IAAI,SAAyB,CAAC;QAC9B,IAAI,cAAc,EAAE;YAClB,SAAS,GAAG;gBACV,GAAG,cAAc;aAClB,CAAC;SACH;aAAM;YACL,SAAS,GAAG,qBAAqB,CAAC;SACnC;QACD,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAE7B,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAChC,IAAI,CAAC,6BAA6B,EAAE,CAAC;IACvC,CAAC;IAEO,6BAA6B;QACnC,MAAM,KAAK,GAAG,IAAI,WAAW,CAAiB,uBAAuB,EAAE;YACrE,MAAM,EAAE,IAAI,CAAC,cAAc;YAC3B,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAEO,iBAAiB,CAAC,UAAsB;QAC9C,IAAI,YAAY,GAAG,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,OAAwB,CAAC;QAExD;;;;;WAKG;QACH,YAAY,GAAG;YACb,GAAG,YAAY;iBACZ,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC;iBACnC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/C,GAAG,YAAY;iBACZ,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC;iBACjC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/C,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC;SAChD,CAAC;QAEF,OAAO,IAAI,CAAA;8BACe,IAAI,CAAC,QAAQ;UACjC,MAAM,CACN,YAAY,EACZ,MAAM,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,EAAE,EAC3C,MAAM,CAAC,EAAE;;YACP,MAAM,kBAAkB,GAAG,GAAG,UAAU,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,YAAY,CAAC;YACvE,MAAM,kBAAkB,GAAG,GAAG,UAAU,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,WAAW,CAAC;YACtE,sEAAsE;YACtE,yEAAyE;YACzE,wBAAwB;YACxB,MAAM,iBAAiB,GACrB,UAAU,CAAC,GAAG,KAAK,YAAY;gBAC7B,CAAC,CAAC,IAAI,CAAA,GAAG,MAAA,MAAM,CAAC,WAAW,mCAAI,MAAM,CAAC,GAAG,EAAE;gBAC3C,CAAC,CAAC,IAAI,CAAA,qBAAqB,MAAM,CAAC,GAAG;;6CAER,IAAI,CAAC,mBAAmB;oCACjC,MAAM,CAAC,GAAG;;;wBAGtB,CAAC;YACb,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC;YAC9C,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,KAAK,UAAU,CAAC;YAClD,MAAM,SAAS,GAAG,GAAG,UAAU,CAAC,GAAG,KACjC,MAAA,MAAM,CAAC,WAAW,mCAAI,MAAM,CAAC,GAC/B,EAAE,CAAC;YACH,MAAM,YAAY,GAAG,aAAa;gBAChC,CAAC,CAAC,YAAY,UAAU,CAAC,GAAG,GAAG;gBAC/B,CAAC,CAAC,aAAa,SAAS,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,QAAQ,SAAS,EAAE,CAAC;YACrC,MAAM,UAAU,GAAG,UAAU,SAAS,EAAE,CAAC;YACzC,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC;YACzD,OAAO,IAAI,CAAA;;;;;4BAKK,UAAU,CAAC,GAAG;6BACb,MAAM,CAAC,GAAG;6BACV,CAAC,CAAQ,EAAE,EAAE;gBACpB,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC5C,CAAC;+BACU,aAAa;;4BAEhB,YAAY;yBACf,kBAAkB;;;;yBAIlB,kBAAkB;4BACf,UAAU,CAAC,GAAG;6BACb,MAAM,CAAC,GAAG;6BACV,CAAC,CAAQ,EAAE,EAAE;gBACpB,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC3C,CAAC;+BACU,WAAW;;;;0BAIhB,kBAAkB;4CACA,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;4BAC5C,YAAY;;wCAEA,OAAO;+CACA,aAAa;;;;wBAIpC,kBAAkB;;0BAEhB,YAAY;;6CAEO,iBAAiB;6CACjB,MAAM,CAAC,KAAK;;;aAG5C,CAAC;QACJ,CAAC,CACF;;KAEJ,CAAC;IACJ,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAwB,CAAC,EAAE,CAAC;IACxE,CAAC;IAED,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA0FT,CAAC;IACJ,CAAC;CACF,CAAA;AA3Q6B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;kDAAyB;AAExB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sDAAiC;AAEhC;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gDAAmB;AAG9C;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;2DACwB;AARxC,cAAc;IAD1B,aAAa,CAAC,iBAAiB,CAAC;GACpB,cAAc,CA4Q1B;SA5QY,cAAc","sourcesContent":["import { css, html, LitElement, TemplateResult, CSSResultGroup } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport type { CollectionNameCacheInterface } from '@internetarchive/collection-name-cache';\nimport eyeIcon from '../assets/img/icons/eye';\nimport eyeClosedIcon from '../assets/img/icons/eye-closed';\nimport {\n FacetGroup,\n FacetOption,\n FacetBucket,\n SelectedFacets,\n defaultSelectedFacets,\n} from '../models';\n\n@customElement('facets-template')\nexport class FacetsTemplate extends LitElement {\n @property({ type: Object }) facetGroup?: FacetGroup;\n\n @property({ type: Object }) selectedFacets?: SelectedFacets;\n\n @property({ type: String }) renderOn?: string;\n\n @property({ type: Object })\n collectionNameCache?: CollectionNameCacheInterface;\n\n private facetClicked(e: Event, count: number, negative: boolean) {\n const target = e.target as HTMLInputElement;\n const { checked, name, value } = target;\n if (checked) {\n this.facetChecked(name as FacetOption, value, count, negative);\n } else {\n this.facetUnchecked(name as FacetOption, value);\n }\n }\n\n private facetChecked(\n key: FacetOption,\n value: string,\n count: number,\n negative: boolean\n ) {\n const { selectedFacets } = this;\n let newFacets: SelectedFacets;\n if (selectedFacets) {\n newFacets = {\n ...selectedFacets,\n };\n } else {\n newFacets = defaultSelectedFacets;\n }\n newFacets[key][value] = {\n state: negative ? 'hidden' : 'selected',\n count,\n } as FacetBucket;\n\n this.selectedFacets = newFacets;\n this.dispatchSelectedFacetsChanged();\n }\n\n private facetUnchecked(key: FacetOption, value: string) {\n const { selectedFacets } = this;\n let newFacets: SelectedFacets;\n if (selectedFacets) {\n newFacets = {\n ...selectedFacets,\n };\n } else {\n newFacets = defaultSelectedFacets;\n }\n delete newFacets[key][value];\n\n this.selectedFacets = newFacets;\n this.dispatchSelectedFacetsChanged();\n }\n\n private dispatchSelectedFacetsChanged() {\n const event = new CustomEvent<SelectedFacets>('selectedFacetsChanged', {\n detail: this.selectedFacets,\n bubbles: true,\n composed: true,\n });\n this.dispatchEvent(event);\n }\n\n private getFacetsTemplate(facetGroup: FacetGroup): TemplateResult {\n let facetsBucket = facetGroup?.buckets as FacetBucket[];\n\n /**\n * sorting FacetBucket before render page / modal\n * - first, selected items should be at top having sorted\n * - second, suppressed/hidden items should be after selected having sorted\n * - and then no-selected / not suppressed items should render having sorted\n */\n facetsBucket = [\n ...facetsBucket\n .filter(x => x.state === 'selected')\n .sort((a, b) => (a.count < b.count ? 1 : -1)),\n ...facetsBucket\n .filter(x => x.state === 'hidden')\n .sort((a, b) => (a.count < b.count ? 1 : -1)),\n ...facetsBucket.filter(x => x.state === 'none'),\n ];\n\n return html`\n <div class=\"facets-on-${this.renderOn}\">\n ${repeat(\n facetsBucket,\n bucket => `${facetGroup.key}:${bucket.key}`,\n bucket => {\n const showOnlyCheckboxId = `${facetGroup.key}:${bucket.key}-show-only`;\n const negativeCheckboxId = `${facetGroup.key}:${bucket.key}-negative`;\n // for collections, we need to asynchronously load the collection name\n // so we use the `async-collection-name` widget and for the rest, we have\n // a static value to use\n const bucketTextDisplay =\n facetGroup.key !== 'collection'\n ? html`${bucket.displayText ?? bucket.key}`\n : html`<a href=\"/details/${bucket.key}\">\n <async-collection-name\n .collectionNameCache=${this.collectionNameCache}\n .identifier=${bucket.key}\n placeholder=\"-\"\n ></async-collection-name>\n </a> `;\n const facetHidden = bucket.state === 'hidden';\n const facetSelected = bucket.state === 'selected';\n const titleText = `${facetGroup.key}: ${\n bucket.displayText ?? bucket.key\n }`;\n const onlyShowText = facetSelected\n ? `Show all ${facetGroup.key}s`\n : `Only show ${titleText}`;\n const hideText = `Hide ${titleText}`;\n const unhideText = `Unhide ${titleText}`;\n const showHideText = facetHidden ? unhideText : hideText;\n return html`\n <div class=\"facet-row\">\n <div class=\"facet-checkbox\">\n <input\n type=\"checkbox\"\n .name=${facetGroup.key}\n .value=${bucket.key}\n @click=${(e: Event) => {\n this.facetClicked(e, bucket.count, false);\n }}\n .checked=${facetSelected}\n class=\"select-facet-checkbox\"\n title=${onlyShowText}\n id=${showOnlyCheckboxId}\n />\n <input\n type=\"checkbox\"\n id=${negativeCheckboxId}\n .name=${facetGroup.key}\n .value=${bucket.key}\n @click=${(e: Event) => {\n this.facetClicked(e, bucket.count, true);\n }}\n .checked=${facetHidden}\n class=\"hide-facet-checkbox\"\n />\n <label\n for=${negativeCheckboxId}\n class=\"hide-facet-icon${facetHidden ? ' active' : ''}\"\n title=${showHideText}\n >\n <span class=\"eye\">${eyeIcon}</span>\n <span class=\"eye-closed\">${eyeClosedIcon}</span>\n </label>\n </div>\n <div\n for=${showOnlyCheckboxId}\n class=\"facet-info-display\"\n title=${onlyShowText}\n >\n <div class=\"facet-title\">${bucketTextDisplay}</div>\n <div class=\"facet-count\">${bucket.count}</div>\n </div>\n </div>\n `;\n }\n )}\n </div>\n `;\n }\n\n render() {\n return html`${this.getFacetsTemplate(this.facetGroup as FacetGroup)}`;\n }\n\n static get styles(): CSSResultGroup {\n return css`\n .facets-on-modal {\n /* For Chrome, Safari, Opera browsers */\n -webkit-column-width: 100px;\n /* For Firefox browser */\n -moz-column-width: 100px;\n column-width: 25rem;\n column-gap: 15px;\n }\n .facets-on-page .select-facet-checkbox {\n margin-left: 0;\n }\n async-collection-name {\n display: contents;\n }\n ul.facet-list {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n ul.facet-list li {\n margin-bottom: 0.2rem;\n display: grid;\n }\n .facet-checkbox {\n margin: 0 5px 0 0;\n display: inline-block;\n align-items: baseline;\n }\n .facet-row {\n display: flex;\n font-weight: 500;\n font-size: 1.2rem;\n }\n .facet-info-display {\n display: flex;\n flex: 1 1 0%;\n cursor: pointer;\n flex-wrap: wrap;\n align-content: center;\n }\n .facet-title {\n word-break: break-word;\n display: inline-block;\n flex: 1 1 0%;\n }\n .facet-count {\n text-align: right;\n }\n .select-facet-checkbox {\n cursor: pointer;\n display: inline-block;\n }\n .hide-facet-checkbox {\n display: none;\n }\n .hide-facet-icon {\n width: 15px;\n height: 15px;\n cursor: pointer;\n opacity: 0.3;\n display: inline-block;\n }\n .hide-facet-icon:hover,\n .active {\n opacity: 1;\n }\n .hide-facet-icon:hover .eye,\n .hide-facet-icon .eye-closed {\n display: none;\n }\n .hide-facet-icon:hover .eye-closed,\n .hide-facet-icon.active .eye-closed {\n display: inline;\n }\n .hide-facet-icon.active .eye {\n display: none;\n }\n .sorting-icon {\n cursor: pointer;\n }\n\n a:link,\n a:visited {\n text-decoration: none;\n color: var(--ia-theme-link-color, #4b64ff);\n }\n a:hover {\n text-decoration: underline;\n }\n `;\n }\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import { FacetOption } from '../models';
2
+ /**
3
+ * Parse the aggregate key title into the human readable title
4
+ *
5
+ * Example: user_aggs__terms__field:mediatypeSorter__size:6 => Media Type
6
+ *
7
+ * @param key
8
+ * @returns
9
+ */
10
+ export declare function getFacetOptionFromKey(key: string): FacetOption;
@@ -0,0 +1,20 @@
1
+ import { aggregationToFacetOption } from '../models';
2
+ /**
3
+ * Parse the aggregate key title into the human readable title
4
+ *
5
+ * Example: user_aggs__terms__field:mediatypeSorter__size:6 => Media Type
6
+ *
7
+ * @param key
8
+ * @returns
9
+ */
10
+ export function getFacetOptionFromKey(key) {
11
+ const parts = key.split('__');
12
+ const fieldNamePart = parts[2];
13
+ const fieldName = fieldNamePart.split(':')[1];
14
+ const facetMatch = Object.entries(aggregationToFacetOption).find(([key2]) => fieldName.includes(key2));
15
+ const option = facetMatch === null || facetMatch === void 0 ? void 0 : facetMatch[1];
16
+ if (!option)
17
+ throw new Error(`Could not find facet option for key: ${key}`);
18
+ return option;
19
+ }
20
+ //# sourceMappingURL=facets-util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facets-util.js","sourceRoot":"","sources":["../../../src/collection-facets/facets-util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAe,MAAM,WAAW,CAAC;AAElE;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAC1E,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CACzB,CAAC;IAEF,MAAM,MAAM,GAAG,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAG,CAAC,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,GAAG,EAAE,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { aggregationToFacetOption, FacetOption } from '../models';\n\n/**\n * Parse the aggregate key title into the human readable title\n *\n * Example: user_aggs__terms__field:mediatypeSorter__size:6 => Media Type\n *\n * @param key\n * @returns\n */\nexport function getFacetOptionFromKey(key: string): FacetOption {\n const parts = key.split('__');\n const fieldNamePart = parts[2];\n const fieldName = fieldNamePart.split(':')[1];\n const facetMatch = Object.entries(aggregationToFacetOption).find(([key2]) =>\n fieldName.includes(key2)\n );\n\n const option = facetMatch?.[1];\n if (!option) throw new Error(`Could not find facet option for key: ${key}`);\n return option;\n}\n"]}
@@ -0,0 +1,83 @@
1
+ import { CSSResultGroup, LitElement, PropertyValues, TemplateResult } from 'lit';
2
+ import type { Aggregation, SearchServiceInterface } from '@internetarchive/search-service';
3
+ import type { CollectionNameCacheInterface } from '@internetarchive/collection-name-cache';
4
+ import type { ModalManagerInterface } from '@internetarchive/modal-manager';
5
+ import { SelectedFacets, FacetGroup } from '../models';
6
+ import type { LanguageCodeHandlerInterface } from '../language-code-handler/language-code-handler';
7
+ import '@internetarchive/ia-activity-indicator/ia-activity-indicator';
8
+ import './more-facets-pagination';
9
+ import './facets-template';
10
+ export declare class MoreFacetsContent extends LitElement {
11
+ facetKey?: string;
12
+ facetAggregationKey?: string;
13
+ fullQuery?: string;
14
+ modalManager?: ModalManagerInterface;
15
+ searchService?: SearchServiceInterface;
16
+ collectionNameCache?: CollectionNameCacheInterface;
17
+ languageCodeHandler?: LanguageCodeHandlerInterface;
18
+ selectedFacets?: SelectedFacets;
19
+ sortedBy: string;
20
+ aggregations?: Record<string, Aggregation>;
21
+ facetGroup?: FacetGroup[];
22
+ facetGroupTitle?: String;
23
+ pageNumber: number;
24
+ /**
25
+ * Facets are loading on popup
26
+ */
27
+ facetsLoading: boolean;
28
+ paginationSize: number;
29
+ facetsType: string;
30
+ private facetsPerPage;
31
+ updated(changed: PropertyValues): void;
32
+ firstUpdated(): void;
33
+ /**
34
+ * Close more facets modal on Escape click
35
+ */
36
+ private setupEscapeListeners;
37
+ /**
38
+ * Get specific facets data from search-service API based of currently query params
39
+ * - this.aggregations - hold result of search service and being used for further processing.
40
+ */
41
+ updateSpecificFacets(): Promise<void>;
42
+ private pageNumberClicked;
43
+ /**
44
+ * Combines the selected facets with the aggregations to create a single list of facets
45
+ */
46
+ private get mergedFacets();
47
+ /**
48
+ * Converts the selected facets to a `FacetGroup` array,
49
+ * which is easier to work with
50
+ */
51
+ private get selectedFacetGroups();
52
+ /**
53
+ * Converts the raw `aggregations` to `FacetGroups`, which are easier to use
54
+ */
55
+ private get aggregationFacetGroups();
56
+ /**
57
+ * for collections, we need to asynchronously load the collection name
58
+ * so we use the `async-collection-name` widget and for the rest, we have a static value to use
59
+ *
60
+ * @param castedBuckets
61
+ */
62
+ private preloadCollectionNames;
63
+ /**
64
+ * sort the facets on modal
65
+ * - alpha sort perform in ascending order
66
+ * - count/frequency sort perform in descending order
67
+ *
68
+ * @param facetBucket as Bucket[]
69
+ *
70
+ * @return sortedFacetBucket as Bucket
71
+ */
72
+ private sortedFacets;
73
+ private get getMoreFacetsTemplate();
74
+ private get loaderTemplate();
75
+ private get facetsPaginationTemplate();
76
+ private get footerTemplate();
77
+ private sortFacetAggregation;
78
+ private get getModalHeaderTemplate();
79
+ render(): TemplateResult<1>;
80
+ private applySearchFacetsClicked;
81
+ private cancelClick;
82
+ static get styles(): CSSResultGroup;
83
+ }