@internetarchive/collection-browser 1.14.17-alpha.1 → 1.14.17-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.
Files changed (36) hide show
  1. package/dist/src/app-root.d.ts +1 -0
  2. package/dist/src/app-root.js +38 -0
  3. package/dist/src/app-root.js.map +1 -1
  4. package/dist/src/collection-browser.d.ts +14 -6
  5. package/dist/src/collection-browser.js +27 -20
  6. package/dist/src/collection-browser.js.map +1 -1
  7. package/dist/src/data-source/collection-browser-data-source.d.ts +24 -3
  8. package/dist/src/data-source/collection-browser-data-source.js +77 -55
  9. package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
  10. package/dist/src/data-source/models.d.ts +1 -0
  11. package/dist/src/data-source/models.js.map +1 -1
  12. package/dist/src/sort-filter-bar/sort-filter-bar.js +24 -16
  13. package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
  14. package/dist/src/tiles/list/tile-list-compact.js +1 -1
  15. package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
  16. package/dist/test/collection-browser.test.js +5 -1
  17. package/dist/test/collection-browser.test.js.map +1 -1
  18. package/dist/test/collection-facets.test.js +5 -0
  19. package/dist/test/collection-facets.test.js.map +1 -1
  20. package/package.json +1 -1
  21. package/src/app-root.ts +39 -0
  22. package/src/collection-browser.ts +39 -21
  23. package/src/data-source/collection-browser-data-source.ts +59 -10
  24. package/src/data-source/models.ts +1 -0
  25. package/src/sort-filter-bar/sort-filter-bar.ts +25 -16
  26. package/src/tiles/list/tile-list-compact.ts +1 -1
  27. package/test/collection-browser.test.ts +5 -1
  28. package/test/collection-facets.test.ts +5 -0
  29. package/dist/src/data-source/data-source-fetch-provider.d.ts +0 -13
  30. package/dist/src/data-source/data-source-fetch-provider.js +0 -61
  31. package/dist/src/data-source/data-source-fetch-provider.js.map +0 -1
  32. package/dist/src/selected-facets.d.ts +0 -67
  33. package/dist/src/selected-facets.js +0 -149
  34. package/dist/src/selected-facets.js.map +0 -1
  35. package/src/data-source/data-source-fetch-provider.ts +0 -79
  36. package/src/selected-facets.ts +0 -216
@@ -216,28 +216,37 @@ export class SortFilterBar
216
216
  private disconnectResizeObserver(
217
217
  resizeObserver: SharedResizeObserverInterface
218
218
  ) {
219
- resizeObserver.removeObserver({
220
- target: this.sortSelectorContainer,
221
- handler: this,
222
- });
219
+ if (this.sortSelectorContainer) {
220
+ resizeObserver.removeObserver({
221
+ target: this.sortSelectorContainer,
222
+ handler: this,
223
+ });
224
+ }
223
225
 
224
- resizeObserver.removeObserver({
225
- target: this.desktopSortContainer,
226
- handler: this,
227
- });
226
+ if (this.desktopSortContainer) {
227
+ resizeObserver.removeObserver({
228
+ target: this.desktopSortContainer,
229
+ handler: this,
230
+ });
231
+ }
228
232
  }
229
233
 
230
234
  private setupResizeObserver() {
231
235
  if (!this.resizeObserver) return;
232
- this.resizeObserver.addObserver({
233
- target: this.sortSelectorContainer,
234
- handler: this,
235
- });
236
236
 
237
- this.resizeObserver.addObserver({
238
- target: this.desktopSortContainer,
239
- handler: this,
240
- });
237
+ if (this.sortSelectorContainer) {
238
+ this.resizeObserver.addObserver({
239
+ target: this.sortSelectorContainer,
240
+ handler: this,
241
+ });
242
+ }
243
+
244
+ if (this.desktopSortContainer) {
245
+ this.resizeObserver.addObserver({
246
+ target: this.desktopSortContainer,
247
+ handler: this,
248
+ });
249
+ }
241
250
  }
242
251
 
243
252
  handleResize(entry: ResizeObserverEntry): void {
@@ -167,7 +167,7 @@ export class TileListCompact extends BaseTileComponent {
167
167
  align-items: center;
168
168
  line-height: 20px;
169
169
  padding-top: 5px;
170
- padding-bottom: 5px;
170
+ margin-bottom: -5px;
171
171
  }
172
172
 
173
173
  #list-line.mobile {
@@ -278,6 +278,7 @@ describe('Collection Browser', () => {
278
278
 
279
279
  el.baseQuery = 'hello';
280
280
  await el.updateComplete;
281
+ await nextTick();
281
282
 
282
283
  const facets = el.shadowRoot?.querySelector('collection-facets');
283
284
  const sortBar = el.shadowRoot?.querySelector('sort-filter-bar');
@@ -782,6 +783,7 @@ describe('Collection Browser', () => {
782
783
 
783
784
  el.baseQuery = 'foo';
784
785
  await el.updateComplete;
786
+ await nextTick();
785
787
 
786
788
  const sortBar = el.shadowRoot?.querySelector('sort-filter-bar');
787
789
  const sortSelector = sortBar?.shadowRoot?.querySelector(
@@ -1119,6 +1121,7 @@ describe('Collection Browser', () => {
1119
1121
  // infinite scroller does exist.
1120
1122
  el.baseQuery = 'collection:foo';
1121
1123
  await el.updateComplete;
1124
+ await nextTick();
1122
1125
 
1123
1126
  const infiniteScroller = el.shadowRoot?.querySelector(
1124
1127
  'infinite-scroller'
@@ -1181,7 +1184,7 @@ describe('Collection Browser', () => {
1181
1184
  await el.initialSearchComplete;
1182
1185
  await aTimeout(0);
1183
1186
 
1184
- expect(el.parentCollections).to.deep.equal(['foo', 'bar']);
1187
+ expect(el.dataSource.parentCollections).to.deep.equal(['foo', 'bar']);
1185
1188
  });
1186
1189
 
1187
1190
  it('refreshes when certain properties change - with some analytics event sampling', async () => {
@@ -1198,6 +1201,7 @@ describe('Collection Browser', () => {
1198
1201
  // Infinite scroller won't exist unless there's a base query
1199
1202
  el.baseQuery = 'collection:foo';
1200
1203
  await el.updateComplete;
1204
+ await nextTick();
1201
1205
 
1202
1206
  const infiniteScroller = el.shadowRoot?.querySelector('infinite-scroller');
1203
1207
  (infiniteScroller as InfiniteScroller).reload = infiniteScrollerRefreshSpy;
@@ -788,6 +788,11 @@ describe('Collection Facets', () => {
788
788
  .baseNavigationUrl=${''}
789
789
  .withinCollection=${'foo'}
790
790
  .parentCollections=${['bar', 'baz']}
791
+ .collectionTitles=${new Map([
792
+ ['foo', 'foo-name'],
793
+ ['bar', 'bar-name'],
794
+ ['baz', 'baz-name'],
795
+ ])}
791
796
  ></collection-facets>`
792
797
  );
793
798
 
@@ -1,13 +0,0 @@
1
- import type { CollectionBrowserDataSourceInterface } from "./collection-browser-data-source";
2
- export interface DataSourceFetchProviderInterface {
3
- fetchPage(dataSource: CollectionBrowserDataSourceInterface, pageNumber: number, initialPageNumber?: number): Promise<void>;
4
- fetchFacets(dataSource: CollectionBrowserDataSourceInterface): Promise<void>;
5
- fetchPrefixFilterBuckets(dataSource: CollectionBrowserDataSourceInterface): Promise<void>;
6
- }
7
- export declare class DataSourceFetchProvider {
8
- /**
9
- * Fires a backend request to fetch a set of aggregations (representing UI facets) for
10
- * the current search state.
11
- */
12
- private fetchFacets;
13
- }
@@ -1,61 +0,0 @@
1
- export class DataSourceFetchProvider {
2
- /**
3
- * Fires a backend request to fetch a set of aggregations (representing UI facets) for
4
- * the current search state.
5
- */
6
- async fetchFacets(dataSource) {
7
- // const trimmedQuery = dataSource.host.baseQuery?.trim();
8
- // if (!dataSource.canPerformSearch) return;
9
- // const { facetFetchQueryKey } = this;
10
- // const sortParams = this.host.sortParam ? [this.host.sortParam] : [];
11
- // const params: SearchParams = {
12
- // ...this.collectionParams,
13
- // query: trimmedQuery || '',
14
- // rows: 0,
15
- // filters: this.filterMap,
16
- // // Fetch a few extra buckets beyond the 6 we show, in case some get suppressed
17
- // aggregationsSize: 10,
18
- // // Note: we don't need an aggregations param to fetch the default aggregations from the PPS.
19
- // // The default aggregations for the search_results page type should be what we need here.
20
- // };
21
- // params.uid = await this.requestUID(
22
- // { ...params, sort: sortParams },
23
- // 'aggregations'
24
- // );
25
- // this.host.setFacetsLoading(true);
26
- // const searchResponse = await this.host.searchService?.search(
27
- // params,
28
- // this.host.searchType
29
- // );
30
- // const success = searchResponse?.success;
31
- // // This is checking to see if the query has changed since the data was fetched.
32
- // // If so, we just want to discard this set of aggregations because they are
33
- // // likely no longer valid for the newer query.
34
- // const queryChangedSinceFetch =
35
- // facetFetchQueryKey !== this.facetFetchQueryKey;
36
- // if (queryChangedSinceFetch) return;
37
- // if (!success) {
38
- // const errorMsg = searchResponse?.error?.message;
39
- // const detailMsg = searchResponse?.error?.details?.message;
40
- // if (!errorMsg && !detailMsg) {
41
- // // @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'
42
- // window?.Sentry?.captureMessage?.(
43
- // 'Missing or malformed facet response from backend',
44
- // 'error'
45
- // );
46
- // }
47
- // return;
48
- // }
49
- // const { aggregations, collectionTitles } = success.response;
50
- // this.aggregations = aggregations;
51
- // if (collectionTitles) {
52
- // for (const [id, title] of Object.entries(collectionTitles)) {
53
- // this.collectionTitles.set(id, title);
54
- // }
55
- // }
56
- // this.yearHistogramAggregation =
57
- // success?.response?.aggregations?.year_histogram;
58
- // this.host.setFacetsLoading(false);
59
- }
60
- }
61
- //# sourceMappingURL=data-source-fetch-provider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"data-source-fetch-provider.js","sourceRoot":"","sources":["../../../src/data-source/data-source-fetch-provider.ts"],"names":[],"mappings":"AAQA,MAAM,OAAO,uBAAuB;IAClC;;;OAGG;IACK,KAAK,CAAC,WAAW,CAAC,UAAgD;QACxE,0DAA0D;QAC1D,4CAA4C;QAE5C,uCAAuC;QAEvC,uEAAuE;QACvE,iCAAiC;QACjC,8BAA8B;QAC9B,+BAA+B;QAC/B,aAAa;QACb,6BAA6B;QAC7B,mFAAmF;QACnF,0BAA0B;QAC1B,iGAAiG;QACjG,8FAA8F;QAC9F,KAAK;QACL,sCAAsC;QACtC,qCAAqC;QACrC,mBAAmB;QACnB,KAAK;QAEL,oCAAoC;QACpC,gEAAgE;QAChE,YAAY;QACZ,yBAAyB;QACzB,KAAK;QACL,2CAA2C;QAE3C,kFAAkF;QAClF,8EAA8E;QAC9E,iDAAiD;QACjD,iCAAiC;QACjC,oDAAoD;QACpD,sCAAsC;QAEtC,kBAAkB;QAClB,qDAAqD;QACrD,+DAA+D;QAE/D,mCAAmC;QACnC,2FAA2F;QAC3F,wCAAwC;QACxC,4DAA4D;QAC5D,gBAAgB;QAChB,SAAS;QACT,MAAM;QAEN,YAAY;QACZ,IAAI;QAEJ,+DAA+D;QAC/D,oCAAoC;QAEpC,0BAA0B;QAC1B,kEAAkE;QAClE,4CAA4C;QAC5C,MAAM;QACN,IAAI;QAEJ,kCAAkC;QAClC,qDAAqD;QAErD,qCAAqC;IACvC,CAAC;CACF","sourcesContent":["import type { CollectionBrowserDataSourceInterface } from \"./collection-browser-data-source\";\n\nexport interface DataSourceFetchProviderInterface {\n fetchPage(dataSource: CollectionBrowserDataSourceInterface, pageNumber: number, initialPageNumber?: number): Promise<void>;\n fetchFacets(dataSource: CollectionBrowserDataSourceInterface): Promise<void>;\n fetchPrefixFilterBuckets(dataSource: CollectionBrowserDataSourceInterface): Promise<void>;\n}\n\nexport class DataSourceFetchProvider {\n /**\n * Fires a backend request to fetch a set of aggregations (representing UI facets) for\n * the current search state.\n */\n private async fetchFacets(dataSource: CollectionBrowserDataSourceInterface): Promise<void> {\n // const trimmedQuery = dataSource.host.baseQuery?.trim();\n // if (!dataSource.canPerformSearch) return;\n\n // const { facetFetchQueryKey } = this;\n\n // const sortParams = this.host.sortParam ? [this.host.sortParam] : [];\n // const params: SearchParams = {\n // ...this.collectionParams,\n // query: trimmedQuery || '',\n // rows: 0,\n // filters: this.filterMap,\n // // Fetch a few extra buckets beyond the 6 we show, in case some get suppressed\n // aggregationsSize: 10,\n // // Note: we don't need an aggregations param to fetch the default aggregations from the PPS.\n // // The default aggregations for the search_results page type should be what we need here.\n // };\n // params.uid = await this.requestUID(\n // { ...params, sort: sortParams },\n // 'aggregations'\n // );\n\n // this.host.setFacetsLoading(true);\n // const searchResponse = await this.host.searchService?.search(\n // params,\n // this.host.searchType\n // );\n // const success = searchResponse?.success;\n\n // // This is checking to see if the query has changed since the data was fetched.\n // // If so, we just want to discard this set of aggregations because they are\n // // likely no longer valid for the newer query.\n // const queryChangedSinceFetch =\n // facetFetchQueryKey !== this.facetFetchQueryKey;\n // if (queryChangedSinceFetch) return;\n\n // if (!success) {\n // const errorMsg = searchResponse?.error?.message;\n // const detailMsg = searchResponse?.error?.details?.message;\n\n // if (!errorMsg && !detailMsg) {\n // // @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'\n // window?.Sentry?.captureMessage?.(\n // 'Missing or malformed facet response from backend',\n // 'error'\n // );\n // }\n\n // return;\n // }\n\n // const { aggregations, collectionTitles } = success.response;\n // this.aggregations = aggregations;\n\n // if (collectionTitles) {\n // for (const [id, title] of Object.entries(collectionTitles)) {\n // this.collectionTitles.set(id, title);\n // }\n // }\n\n // this.yearHistogramAggregation =\n // success?.response?.aggregations?.year_histogram;\n\n // this.host.setFacetsLoading(false);\n }\n}"]}
@@ -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"]}
@@ -1,79 +0,0 @@
1
- import type { CollectionBrowserDataSourceInterface } from "./collection-browser-data-source";
2
-
3
- export interface DataSourceFetchProviderInterface {
4
- fetchPage(dataSource: CollectionBrowserDataSourceInterface, pageNumber: number, initialPageNumber?: number): Promise<void>;
5
- fetchFacets(dataSource: CollectionBrowserDataSourceInterface): Promise<void>;
6
- fetchPrefixFilterBuckets(dataSource: CollectionBrowserDataSourceInterface): Promise<void>;
7
- }
8
-
9
- export class DataSourceFetchProvider {
10
- /**
11
- * Fires a backend request to fetch a set of aggregations (representing UI facets) for
12
- * the current search state.
13
- */
14
- private async fetchFacets(dataSource: CollectionBrowserDataSourceInterface): Promise<void> {
15
- // const trimmedQuery = dataSource.host.baseQuery?.trim();
16
- // if (!dataSource.canPerformSearch) return;
17
-
18
- // const { facetFetchQueryKey } = this;
19
-
20
- // const sortParams = this.host.sortParam ? [this.host.sortParam] : [];
21
- // const params: SearchParams = {
22
- // ...this.collectionParams,
23
- // query: trimmedQuery || '',
24
- // rows: 0,
25
- // filters: this.filterMap,
26
- // // Fetch a few extra buckets beyond the 6 we show, in case some get suppressed
27
- // aggregationsSize: 10,
28
- // // Note: we don't need an aggregations param to fetch the default aggregations from the PPS.
29
- // // The default aggregations for the search_results page type should be what we need here.
30
- // };
31
- // params.uid = await this.requestUID(
32
- // { ...params, sort: sortParams },
33
- // 'aggregations'
34
- // );
35
-
36
- // this.host.setFacetsLoading(true);
37
- // const searchResponse = await this.host.searchService?.search(
38
- // params,
39
- // this.host.searchType
40
- // );
41
- // const success = searchResponse?.success;
42
-
43
- // // This is checking to see if the query has changed since the data was fetched.
44
- // // If so, we just want to discard this set of aggregations because they are
45
- // // likely no longer valid for the newer query.
46
- // const queryChangedSinceFetch =
47
- // facetFetchQueryKey !== this.facetFetchQueryKey;
48
- // if (queryChangedSinceFetch) return;
49
-
50
- // if (!success) {
51
- // const errorMsg = searchResponse?.error?.message;
52
- // const detailMsg = searchResponse?.error?.details?.message;
53
-
54
- // if (!errorMsg && !detailMsg) {
55
- // // @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'
56
- // window?.Sentry?.captureMessage?.(
57
- // 'Missing or malformed facet response from backend',
58
- // 'error'
59
- // );
60
- // }
61
-
62
- // return;
63
- // }
64
-
65
- // const { aggregations, collectionTitles } = success.response;
66
- // this.aggregations = aggregations;
67
-
68
- // if (collectionTitles) {
69
- // for (const [id, title] of Object.entries(collectionTitles)) {
70
- // this.collectionTitles.set(id, title);
71
- // }
72
- // }
73
-
74
- // this.yearHistogramAggregation =
75
- // success?.response?.aggregations?.year_histogram;
76
-
77
- // this.host.setFacetsLoading(false);
78
- }
79
- }