@internetarchive/collection-browser 1.14.13 → 1.14.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/app-root.d.ts +1 -0
- package/dist/src/app-root.js +13 -0
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/collection-browser.d.ts +1 -0
- package/dist/src/collection-browser.js +20 -1
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/test/collection-browser.test.js +12 -0
- package/dist/test/collection-browser.test.js.map +1 -1
- package/package.json +1 -1
- package/src/app-root.ts +14 -0
- package/src/collection-browser.ts +19 -1
- package/test/collection-browser.test.ts +18 -0
- package/dist/src/selected-facets.d.ts +0 -67
- package/dist/src/selected-facets.js +0 -149
- package/dist/src/selected-facets.js.map +0 -1
- package/src/selected-facets.ts +0 -216
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from 'lit';
|
|
10
10
|
import { customElement, property, query, state } from 'lit/decorators.js';
|
|
11
11
|
import { classMap } from 'lit/directives/class-map.js';
|
|
12
|
+
import { msg } from '@lit/localize';
|
|
12
13
|
|
|
13
14
|
import type { AnalyticsManagerInterface } from '@internetarchive/analytics-manager';
|
|
14
15
|
import type {
|
|
@@ -131,6 +132,8 @@ export class CollectionBrowser
|
|
|
131
132
|
|
|
132
133
|
@property({ type: Boolean }) suppressResultCount = false;
|
|
133
134
|
|
|
135
|
+
@property({ type: Boolean }) suppressFacets = false;
|
|
136
|
+
|
|
134
137
|
@property({ type: Boolean }) clearResultsOnEmptyQuery = false;
|
|
135
138
|
|
|
136
139
|
@property({ type: String }) collectionPagePath: string = '/details/';
|
|
@@ -954,6 +957,14 @@ export class CollectionBrowser
|
|
|
954
957
|
* The template for the facets component alone, without any surrounding wrappers.
|
|
955
958
|
*/
|
|
956
959
|
private get facetsTemplate() {
|
|
960
|
+
if (this.suppressFacets) {
|
|
961
|
+
return html`
|
|
962
|
+
<p class="facets-message">
|
|
963
|
+
${msg('Facets are temporarily unavailable.')}
|
|
964
|
+
</p>
|
|
965
|
+
`;
|
|
966
|
+
}
|
|
967
|
+
|
|
957
968
|
return html`
|
|
958
969
|
<collection-facets
|
|
959
970
|
@facetsChanged=${this.facetsChanged}
|
|
@@ -1480,7 +1491,10 @@ export class CollectionBrowser
|
|
|
1480
1491
|
});
|
|
1481
1492
|
|
|
1482
1493
|
// Fire the initial page and facets requests
|
|
1483
|
-
await Promise.all([
|
|
1494
|
+
await Promise.all([
|
|
1495
|
+
this.doInitialPageFetch(),
|
|
1496
|
+
this.suppressFacets ? null : this.fetchFacets(),
|
|
1497
|
+
]);
|
|
1484
1498
|
|
|
1485
1499
|
// Resolve the `initialSearchComplete` promise for this search
|
|
1486
1500
|
this._initialSearchCompleteResolver(true);
|
|
@@ -2582,6 +2596,10 @@ export class CollectionBrowser
|
|
|
2582
2596
|
height: 0;
|
|
2583
2597
|
}
|
|
2584
2598
|
|
|
2599
|
+
.facets-message {
|
|
2600
|
+
font-size: 1.4rem;
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2585
2603
|
.desktop #left-column-scroll-sentinel {
|
|
2586
2604
|
width: 1px;
|
|
2587
2605
|
height: 100vh;
|
|
@@ -1495,6 +1495,24 @@ describe('Collection Browser', () => {
|
|
|
1495
1495
|
expect(el.maxSelectedDate).not.to.exist;
|
|
1496
1496
|
});
|
|
1497
1497
|
|
|
1498
|
+
it('shows temporarily unavailable message when facets suppressed', async () => {
|
|
1499
|
+
const searchService = new MockSearchService();
|
|
1500
|
+
const el = await fixture<CollectionBrowser>(
|
|
1501
|
+
html`<collection-browser .searchService=${searchService} suppressFacets>
|
|
1502
|
+
</collection-browser>`
|
|
1503
|
+
);
|
|
1504
|
+
|
|
1505
|
+
el.baseQuery = 'foo';
|
|
1506
|
+
await el.updateComplete;
|
|
1507
|
+
await el.initialSearchComplete;
|
|
1508
|
+
|
|
1509
|
+
const facetsMsg = el.shadowRoot?.querySelector('.facets-message');
|
|
1510
|
+
expect(facetsMsg).to.exist;
|
|
1511
|
+
expect(facetsMsg?.textContent?.trim()).to.equal(
|
|
1512
|
+
'Facets are temporarily unavailable.'
|
|
1513
|
+
);
|
|
1514
|
+
});
|
|
1515
|
+
|
|
1498
1516
|
it('shows manage bar interface instead of sort bar when in manage view', async () => {
|
|
1499
1517
|
const searchService = new MockSearchService();
|
|
1500
1518
|
const el = await fixture<CollectionBrowser>(
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { type FacetBucket, type FacetGroup, type FacetOption, type FacetValue } from './models';
|
|
2
|
-
/**
|
|
3
|
-
* A record of all the facet buckets for a particular facet type, indexed by their bucket key
|
|
4
|
-
*/
|
|
5
|
-
export declare type FacetBucketsRecord = Record<FacetValue, FacetBucket>;
|
|
6
|
-
declare type SelectedFacetsModel = Record<FacetOption, FacetBucketsRecord>;
|
|
7
|
-
/**
|
|
8
|
-
* A class to hold, query, and manipulate state about selected/hidden facets.
|
|
9
|
-
*/
|
|
10
|
-
export declare class SelectedFacets implements SelectedFacetsModel {
|
|
11
|
-
readonly collection: FacetBucketsRecord;
|
|
12
|
-
readonly creator: FacetBucketsRecord;
|
|
13
|
-
readonly language: FacetBucketsRecord;
|
|
14
|
-
readonly lending: FacetBucketsRecord;
|
|
15
|
-
readonly mediatype: FacetBucketsRecord;
|
|
16
|
-
readonly subject: FacetBucketsRecord;
|
|
17
|
-
readonly year: FacetBucketsRecord;
|
|
18
|
-
constructor(initValues?: Partial<SelectedFacetsModel>);
|
|
19
|
-
/**
|
|
20
|
-
* Executes the given function on every facet bucket within the current SelectedFacets object.
|
|
21
|
-
* @param fn The function to execute for each facet bucket
|
|
22
|
-
*/
|
|
23
|
-
forEach(fn: (bucket: FacetBucket, bucketKey: FacetValue, facetType: FacetOption) => unknown): void;
|
|
24
|
-
/**
|
|
25
|
-
* Executes the given function on every facet type within the current SelectedFacets object.
|
|
26
|
-
* Similar to `SelectedFacets.forEach`, but operating on the full set of buckets for each type
|
|
27
|
-
* (rather than individual buckets).
|
|
28
|
-
* @param fn The function to execute for each facet type
|
|
29
|
-
*/
|
|
30
|
-
forEachFacetType(fn: (buckets: FacetBucketsRecord, facetType: FacetOption) => unknown): void;
|
|
31
|
-
/**
|
|
32
|
-
* Like `Array.some`, returns whether the given predicate function returns true for
|
|
33
|
-
* any of the facet buckets contained in this object.
|
|
34
|
-
* @param predicate Function returning a boolean for each bucket
|
|
35
|
-
* @returns Whether any of the facet buckets satisfy the predicate
|
|
36
|
-
*/
|
|
37
|
-
some(predicate: (bucket: FacetBucket, bucketKey: FacetValue, facetType: FacetOption) => boolean): boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Like `Array.every`, returns whether the given predicate function returns true for
|
|
40
|
-
* *all* of the facet buckets contained in this object.
|
|
41
|
-
* @param predicate Function returning a boolean for each bucket
|
|
42
|
-
* @returns Whether all of the facet buckets satisfy the predicate
|
|
43
|
-
*/
|
|
44
|
-
every(predicate: (bucket: FacetBucket, bucketKey: FacetValue, facetType: FacetOption) => boolean): boolean;
|
|
45
|
-
/**
|
|
46
|
-
* Returns a new SelectedFacets object deeply cloned from this one (same contents).
|
|
47
|
-
*/
|
|
48
|
-
clone(): SelectedFacets;
|
|
49
|
-
/**
|
|
50
|
-
* Returns a new SelectedFacets object cloned from this one with all of the given `otherFacets`
|
|
51
|
-
* applied overtop. Facets from this object will be overwritten by those in `otherFacets`
|
|
52
|
-
* that have the same facet type and bucket key.
|
|
53
|
-
*
|
|
54
|
-
* @param otherFacets The other SelectedFacets object to merge into this one.
|
|
55
|
-
*/
|
|
56
|
-
merge(otherFacets?: SelectedFacets): SelectedFacets;
|
|
57
|
-
/**
|
|
58
|
-
* Returns a new SelectedFacets object with facet buckets normalized, such that any
|
|
59
|
-
* buckets with a state of 'none' are removed entirely.
|
|
60
|
-
*/
|
|
61
|
-
normalize(): SelectedFacets;
|
|
62
|
-
/**
|
|
63
|
-
* Converts this SelectedFacets object into an array of equivalent FacetGroups.
|
|
64
|
-
*/
|
|
65
|
-
toFacetGroups(): FacetGroup[];
|
|
66
|
-
}
|
|
67
|
-
export {};
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { facetTitles, lendingFacetDisplayNames, } from './models';
|
|
2
|
-
const VALID_FACET_OPTIONS = new Set([
|
|
3
|
-
'collection',
|
|
4
|
-
'creator',
|
|
5
|
-
'language',
|
|
6
|
-
'lending',
|
|
7
|
-
'mediatype',
|
|
8
|
-
'subject',
|
|
9
|
-
'year',
|
|
10
|
-
]);
|
|
11
|
-
/**
|
|
12
|
-
* A class to hold, query, and manipulate state about selected/hidden facets.
|
|
13
|
-
*/
|
|
14
|
-
export class SelectedFacets {
|
|
15
|
-
constructor(initValues) {
|
|
16
|
-
this.collection = {};
|
|
17
|
-
this.creator = {};
|
|
18
|
-
this.language = {};
|
|
19
|
-
this.lending = {};
|
|
20
|
-
this.mediatype = {};
|
|
21
|
-
this.subject = {};
|
|
22
|
-
this.year = {};
|
|
23
|
-
if (initValues) {
|
|
24
|
-
for (const [facetType, buckets] of Object.entries(initValues)) {
|
|
25
|
-
if (VALID_FACET_OPTIONS.has(facetType)) {
|
|
26
|
-
for (const [bucketKey, bucket] of Object.entries(buckets)) {
|
|
27
|
-
this[facetType][bucketKey] = { ...bucket };
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Executes the given function on every facet bucket within the current SelectedFacets object.
|
|
35
|
-
* @param fn The function to execute for each facet bucket
|
|
36
|
-
*/
|
|
37
|
-
forEach(fn) {
|
|
38
|
-
for (const [facetType, buckets] of Object.entries(this)) {
|
|
39
|
-
for (const [bucketKey, bucket] of Object.entries(buckets)) {
|
|
40
|
-
fn(bucket, bucketKey, facetType);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Executes the given function on every facet type within the current SelectedFacets object.
|
|
46
|
-
* Similar to `SelectedFacets.forEach`, but operating on the full set of buckets for each type
|
|
47
|
-
* (rather than individual buckets).
|
|
48
|
-
* @param fn The function to execute for each facet type
|
|
49
|
-
*/
|
|
50
|
-
forEachFacetType(fn) {
|
|
51
|
-
for (const [facetType, buckets] of Object.entries(this)) {
|
|
52
|
-
fn(buckets, facetType);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Like `Array.some`, returns whether the given predicate function returns true for
|
|
57
|
-
* any of the facet buckets contained in this object.
|
|
58
|
-
* @param predicate Function returning a boolean for each bucket
|
|
59
|
-
* @returns Whether any of the facet buckets satisfy the predicate
|
|
60
|
-
*/
|
|
61
|
-
some(predicate) {
|
|
62
|
-
for (const [facetType, buckets] of Object.entries(this)) {
|
|
63
|
-
for (const [bucketKey, bucket] of Object.entries(buckets)) {
|
|
64
|
-
if (predicate(bucket, bucketKey, facetType))
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Like `Array.every`, returns whether the given predicate function returns true for
|
|
72
|
-
* *all* of the facet buckets contained in this object.
|
|
73
|
-
* @param predicate Function returning a boolean for each bucket
|
|
74
|
-
* @returns Whether all of the facet buckets satisfy the predicate
|
|
75
|
-
*/
|
|
76
|
-
every(predicate) {
|
|
77
|
-
for (const [facetType, buckets] of Object.entries(this)) {
|
|
78
|
-
for (const [bucketKey, bucket] of Object.entries(buckets)) {
|
|
79
|
-
if (!predicate(bucket, bucketKey, facetType))
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return true;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Returns a new SelectedFacets object deeply cloned from this one (same contents).
|
|
87
|
-
*/
|
|
88
|
-
clone() {
|
|
89
|
-
return new SelectedFacets(this);
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Returns a new SelectedFacets object cloned from this one with all of the given `otherFacets`
|
|
93
|
-
* applied overtop. Facets from this object will be overwritten by those in `otherFacets`
|
|
94
|
-
* that have the same facet type and bucket key.
|
|
95
|
-
*
|
|
96
|
-
* @param otherFacets The other SelectedFacets object to merge into this one.
|
|
97
|
-
*/
|
|
98
|
-
merge(otherFacets) {
|
|
99
|
-
const merged = this.clone();
|
|
100
|
-
otherFacets === null || otherFacets === void 0 ? void 0 : otherFacets.forEach((bucket, bucketKey, facetType) => {
|
|
101
|
-
merged[facetType][bucketKey] = { ...bucket };
|
|
102
|
-
});
|
|
103
|
-
return merged;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Returns a new SelectedFacets object with facet buckets normalized, such that any
|
|
107
|
-
* buckets with a state of 'none' are removed entirely.
|
|
108
|
-
*/
|
|
109
|
-
normalize() {
|
|
110
|
-
const normalized = this.clone();
|
|
111
|
-
normalized.forEach((bucket, bucketKey, facetType) => {
|
|
112
|
-
if (bucket.state === 'none') {
|
|
113
|
-
delete normalized[facetType][bucketKey];
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
return normalized;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Converts this SelectedFacets object into an array of equivalent FacetGroups.
|
|
120
|
-
*/
|
|
121
|
-
toFacetGroups() {
|
|
122
|
-
const facetGroups = {};
|
|
123
|
-
this.forEach((bucket, bucketKey, facetType) => {
|
|
124
|
-
var _a;
|
|
125
|
-
const title = facetTitles[facetType];
|
|
126
|
-
let displayText = bucketKey;
|
|
127
|
-
// For lending facets, convert the key to a more readable format
|
|
128
|
-
if (facetType === 'lending') {
|
|
129
|
-
displayText =
|
|
130
|
-
(_a = lendingFacetDisplayNames[bucketKey]) !== null && _a !== void 0 ? _a : bucketKey;
|
|
131
|
-
}
|
|
132
|
-
if (!facetGroups[facetType]) {
|
|
133
|
-
facetGroups[facetType] = {
|
|
134
|
-
title,
|
|
135
|
-
key: facetType,
|
|
136
|
-
buckets: [],
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
facetGroups[facetType].buckets.push({
|
|
140
|
-
displayText,
|
|
141
|
-
key: bucketKey,
|
|
142
|
-
count: bucket.count,
|
|
143
|
-
state: bucket.state,
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
return Object.values(facetGroups);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
//# sourceMappingURL=selected-facets.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"selected-facets.js","sourceRoot":"","sources":["../../src/selected-facets.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n facetTitles,\n type FacetBucket,\n type FacetGroup,\n type FacetOption,\n type FacetValue,\n lendingFacetDisplayNames,\n LendingFacetKey,\n} from './models';\n\n/**\n * A record of all the facet buckets for a particular facet type, indexed by their bucket key\n */\nexport type FacetBucketsRecord = Record<FacetValue, FacetBucket>;\n\n// Implementing this model ensures that every facet type is accounted for\ntype SelectedFacetsModel = Record<FacetOption, FacetBucketsRecord>;\n\nconst VALID_FACET_OPTIONS: Set<FacetOption> = new Set([\n 'collection',\n 'creator',\n 'language',\n 'lending',\n 'mediatype',\n 'subject',\n 'year',\n]);\n\n/**\n * A class to hold, query, and manipulate state about selected/hidden facets.\n */\nexport class SelectedFacets implements SelectedFacetsModel {\n readonly collection: FacetBucketsRecord = {};\n\n readonly creator: FacetBucketsRecord = {};\n\n readonly language: FacetBucketsRecord = {};\n\n readonly lending: FacetBucketsRecord = {};\n\n readonly mediatype: FacetBucketsRecord = {};\n\n readonly subject: FacetBucketsRecord = {};\n\n readonly year: FacetBucketsRecord = {};\n\n constructor(initValues?: Partial<SelectedFacetsModel>) {\n if (initValues) {\n for (const [facetType, buckets] of Object.entries(initValues)) {\n if (VALID_FACET_OPTIONS.has(facetType as FacetOption)) {\n for (const [bucketKey, bucket] of Object.entries(buckets)) {\n this[facetType as FacetOption][bucketKey] = { ...bucket };\n }\n }\n }\n }\n }\n\n /**\n * Executes the given function on every facet bucket within the current SelectedFacets object.\n * @param fn The function to execute for each facet bucket\n */\n forEach(\n fn: (\n bucket: FacetBucket,\n bucketKey: FacetValue,\n facetType: FacetOption\n ) => unknown\n ): void {\n for (const [facetType, buckets] of Object.entries(\n this as SelectedFacetsModel\n )) {\n for (const [bucketKey, bucket] of Object.entries(buckets)) {\n fn(bucket, bucketKey, facetType as FacetOption);\n }\n }\n }\n\n /**\n * Executes the given function on every facet type within the current SelectedFacets object.\n * Similar to `SelectedFacets.forEach`, but operating on the full set of buckets for each type\n * (rather than individual buckets).\n * @param fn The function to execute for each facet type\n */\n forEachFacetType(\n fn: (buckets: FacetBucketsRecord, facetType: FacetOption) => unknown\n ): void {\n for (const [facetType, buckets] of Object.entries(\n this as SelectedFacetsModel\n )) {\n fn(buckets, facetType as FacetOption);\n }\n }\n\n /**\n * Like `Array.some`, returns whether the given predicate function returns true for\n * any of the facet buckets contained in this object.\n * @param predicate Function returning a boolean for each bucket\n * @returns Whether any of the facet buckets satisfy the predicate\n */\n some(\n predicate: (\n bucket: FacetBucket,\n bucketKey: FacetValue,\n facetType: FacetOption\n ) => boolean\n ): boolean {\n for (const [facetType, buckets] of Object.entries(\n this as SelectedFacetsModel\n )) {\n for (const [bucketKey, bucket] of Object.entries(buckets)) {\n if (predicate(bucket, bucketKey, facetType as FacetOption)) return true;\n }\n }\n\n return false;\n }\n\n /**\n * Like `Array.every`, returns whether the given predicate function returns true for\n * *all* of the facet buckets contained in this object.\n * @param predicate Function returning a boolean for each bucket\n * @returns Whether all of the facet buckets satisfy the predicate\n */\n every(\n predicate: (\n bucket: FacetBucket,\n bucketKey: FacetValue,\n facetType: FacetOption\n ) => boolean\n ): boolean {\n for (const [facetType, buckets] of Object.entries(\n this as SelectedFacetsModel\n )) {\n for (const [bucketKey, bucket] of Object.entries(buckets)) {\n if (!predicate(bucket, bucketKey, facetType as FacetOption))\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Returns a new SelectedFacets object deeply cloned from this one (same contents).\n */\n clone(): SelectedFacets {\n return new SelectedFacets(this);\n }\n\n /**\n * Returns a new SelectedFacets object cloned from this one with all of the given `otherFacets`\n * applied overtop. Facets from this object will be overwritten by those in `otherFacets`\n * that have the same facet type and bucket key.\n *\n * @param otherFacets The other SelectedFacets object to merge into this one.\n */\n merge(otherFacets?: SelectedFacets): SelectedFacets {\n const merged = this.clone();\n otherFacets?.forEach((bucket, bucketKey, facetType) => {\n merged[facetType][bucketKey] = { ...bucket };\n });\n\n return merged;\n }\n\n /**\n * Returns a new SelectedFacets object with facet buckets normalized, such that any\n * buckets with a state of 'none' are removed entirely.\n */\n normalize(): SelectedFacets {\n const normalized = this.clone();\n normalized.forEach((bucket, bucketKey, facetType) => {\n if (bucket.state === 'none') {\n delete normalized[facetType][bucketKey];\n }\n });\n\n return normalized;\n }\n\n /**\n * Converts this SelectedFacets object into an array of equivalent FacetGroups.\n */\n toFacetGroups(): FacetGroup[] {\n const facetGroups: Record<string, FacetGroup> = {};\n\n this.forEach((bucket, bucketKey, facetType) => {\n const title = facetTitles[facetType];\n let displayText = bucketKey;\n\n // For lending facets, convert the key to a more readable format\n if (facetType === 'lending') {\n displayText =\n lendingFacetDisplayNames[bucketKey as LendingFacetKey] ?? bucketKey;\n }\n\n if (!facetGroups[facetType]) {\n facetGroups[facetType] = {\n title,\n key: facetType,\n buckets: [],\n };\n }\n\n facetGroups[facetType].buckets.push({\n displayText,\n key: bucketKey,\n count: bucket.count,\n state: bucket.state,\n });\n });\n\n return Object.values(facetGroups);\n }\n}\n"]}
|
package/src/selected-facets.ts
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
facetTitles,
|
|
3
|
-
type FacetBucket,
|
|
4
|
-
type FacetGroup,
|
|
5
|
-
type FacetOption,
|
|
6
|
-
type FacetValue,
|
|
7
|
-
lendingFacetDisplayNames,
|
|
8
|
-
LendingFacetKey,
|
|
9
|
-
} from './models';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* A record of all the facet buckets for a particular facet type, indexed by their bucket key
|
|
13
|
-
*/
|
|
14
|
-
export type FacetBucketsRecord = Record<FacetValue, FacetBucket>;
|
|
15
|
-
|
|
16
|
-
// Implementing this model ensures that every facet type is accounted for
|
|
17
|
-
type SelectedFacetsModel = Record<FacetOption, FacetBucketsRecord>;
|
|
18
|
-
|
|
19
|
-
const VALID_FACET_OPTIONS: Set<FacetOption> = new Set([
|
|
20
|
-
'collection',
|
|
21
|
-
'creator',
|
|
22
|
-
'language',
|
|
23
|
-
'lending',
|
|
24
|
-
'mediatype',
|
|
25
|
-
'subject',
|
|
26
|
-
'year',
|
|
27
|
-
]);
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* A class to hold, query, and manipulate state about selected/hidden facets.
|
|
31
|
-
*/
|
|
32
|
-
export class SelectedFacets implements SelectedFacetsModel {
|
|
33
|
-
readonly collection: FacetBucketsRecord = {};
|
|
34
|
-
|
|
35
|
-
readonly creator: FacetBucketsRecord = {};
|
|
36
|
-
|
|
37
|
-
readonly language: FacetBucketsRecord = {};
|
|
38
|
-
|
|
39
|
-
readonly lending: FacetBucketsRecord = {};
|
|
40
|
-
|
|
41
|
-
readonly mediatype: FacetBucketsRecord = {};
|
|
42
|
-
|
|
43
|
-
readonly subject: FacetBucketsRecord = {};
|
|
44
|
-
|
|
45
|
-
readonly year: FacetBucketsRecord = {};
|
|
46
|
-
|
|
47
|
-
constructor(initValues?: Partial<SelectedFacetsModel>) {
|
|
48
|
-
if (initValues) {
|
|
49
|
-
for (const [facetType, buckets] of Object.entries(initValues)) {
|
|
50
|
-
if (VALID_FACET_OPTIONS.has(facetType as FacetOption)) {
|
|
51
|
-
for (const [bucketKey, bucket] of Object.entries(buckets)) {
|
|
52
|
-
this[facetType as FacetOption][bucketKey] = { ...bucket };
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Executes the given function on every facet bucket within the current SelectedFacets object.
|
|
61
|
-
* @param fn The function to execute for each facet bucket
|
|
62
|
-
*/
|
|
63
|
-
forEach(
|
|
64
|
-
fn: (
|
|
65
|
-
bucket: FacetBucket,
|
|
66
|
-
bucketKey: FacetValue,
|
|
67
|
-
facetType: FacetOption
|
|
68
|
-
) => unknown
|
|
69
|
-
): void {
|
|
70
|
-
for (const [facetType, buckets] of Object.entries(
|
|
71
|
-
this as SelectedFacetsModel
|
|
72
|
-
)) {
|
|
73
|
-
for (const [bucketKey, bucket] of Object.entries(buckets)) {
|
|
74
|
-
fn(bucket, bucketKey, facetType as FacetOption);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Executes the given function on every facet type within the current SelectedFacets object.
|
|
81
|
-
* Similar to `SelectedFacets.forEach`, but operating on the full set of buckets for each type
|
|
82
|
-
* (rather than individual buckets).
|
|
83
|
-
* @param fn The function to execute for each facet type
|
|
84
|
-
*/
|
|
85
|
-
forEachFacetType(
|
|
86
|
-
fn: (buckets: FacetBucketsRecord, facetType: FacetOption) => unknown
|
|
87
|
-
): void {
|
|
88
|
-
for (const [facetType, buckets] of Object.entries(
|
|
89
|
-
this as SelectedFacetsModel
|
|
90
|
-
)) {
|
|
91
|
-
fn(buckets, facetType as FacetOption);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Like `Array.some`, returns whether the given predicate function returns true for
|
|
97
|
-
* any of the facet buckets contained in this object.
|
|
98
|
-
* @param predicate Function returning a boolean for each bucket
|
|
99
|
-
* @returns Whether any of the facet buckets satisfy the predicate
|
|
100
|
-
*/
|
|
101
|
-
some(
|
|
102
|
-
predicate: (
|
|
103
|
-
bucket: FacetBucket,
|
|
104
|
-
bucketKey: FacetValue,
|
|
105
|
-
facetType: FacetOption
|
|
106
|
-
) => boolean
|
|
107
|
-
): boolean {
|
|
108
|
-
for (const [facetType, buckets] of Object.entries(
|
|
109
|
-
this as SelectedFacetsModel
|
|
110
|
-
)) {
|
|
111
|
-
for (const [bucketKey, bucket] of Object.entries(buckets)) {
|
|
112
|
-
if (predicate(bucket, bucketKey, facetType as FacetOption)) return true;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Like `Array.every`, returns whether the given predicate function returns true for
|
|
121
|
-
* *all* of the facet buckets contained in this object.
|
|
122
|
-
* @param predicate Function returning a boolean for each bucket
|
|
123
|
-
* @returns Whether all of the facet buckets satisfy the predicate
|
|
124
|
-
*/
|
|
125
|
-
every(
|
|
126
|
-
predicate: (
|
|
127
|
-
bucket: FacetBucket,
|
|
128
|
-
bucketKey: FacetValue,
|
|
129
|
-
facetType: FacetOption
|
|
130
|
-
) => boolean
|
|
131
|
-
): boolean {
|
|
132
|
-
for (const [facetType, buckets] of Object.entries(
|
|
133
|
-
this as SelectedFacetsModel
|
|
134
|
-
)) {
|
|
135
|
-
for (const [bucketKey, bucket] of Object.entries(buckets)) {
|
|
136
|
-
if (!predicate(bucket, bucketKey, facetType as FacetOption))
|
|
137
|
-
return false;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return true;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Returns a new SelectedFacets object deeply cloned from this one (same contents).
|
|
146
|
-
*/
|
|
147
|
-
clone(): SelectedFacets {
|
|
148
|
-
return new SelectedFacets(this);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Returns a new SelectedFacets object cloned from this one with all of the given `otherFacets`
|
|
153
|
-
* applied overtop. Facets from this object will be overwritten by those in `otherFacets`
|
|
154
|
-
* that have the same facet type and bucket key.
|
|
155
|
-
*
|
|
156
|
-
* @param otherFacets The other SelectedFacets object to merge into this one.
|
|
157
|
-
*/
|
|
158
|
-
merge(otherFacets?: SelectedFacets): SelectedFacets {
|
|
159
|
-
const merged = this.clone();
|
|
160
|
-
otherFacets?.forEach((bucket, bucketKey, facetType) => {
|
|
161
|
-
merged[facetType][bucketKey] = { ...bucket };
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
return merged;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Returns a new SelectedFacets object with facet buckets normalized, such that any
|
|
169
|
-
* buckets with a state of 'none' are removed entirely.
|
|
170
|
-
*/
|
|
171
|
-
normalize(): SelectedFacets {
|
|
172
|
-
const normalized = this.clone();
|
|
173
|
-
normalized.forEach((bucket, bucketKey, facetType) => {
|
|
174
|
-
if (bucket.state === 'none') {
|
|
175
|
-
delete normalized[facetType][bucketKey];
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
return normalized;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Converts this SelectedFacets object into an array of equivalent FacetGroups.
|
|
184
|
-
*/
|
|
185
|
-
toFacetGroups(): FacetGroup[] {
|
|
186
|
-
const facetGroups: Record<string, FacetGroup> = {};
|
|
187
|
-
|
|
188
|
-
this.forEach((bucket, bucketKey, facetType) => {
|
|
189
|
-
const title = facetTitles[facetType];
|
|
190
|
-
let displayText = bucketKey;
|
|
191
|
-
|
|
192
|
-
// For lending facets, convert the key to a more readable format
|
|
193
|
-
if (facetType === 'lending') {
|
|
194
|
-
displayText =
|
|
195
|
-
lendingFacetDisplayNames[bucketKey as LendingFacetKey] ?? bucketKey;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
if (!facetGroups[facetType]) {
|
|
199
|
-
facetGroups[facetType] = {
|
|
200
|
-
title,
|
|
201
|
-
key: facetType,
|
|
202
|
-
buckets: [],
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
facetGroups[facetType].buckets.push({
|
|
207
|
-
displayText,
|
|
208
|
-
key: bucketKey,
|
|
209
|
-
count: bucket.count,
|
|
210
|
-
state: bucket.state,
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
return Object.values(facetGroups);
|
|
215
|
-
}
|
|
216
|
-
}
|