@internetarchive/collection-browser 0.0.1-alpha.21 → 0.0.1-alpha.24

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 (58) hide show
  1. package/demo/app-root.ts +10 -0
  2. package/dist/demo/app-root.d.ts +2 -0
  3. package/dist/demo/app-root.js +8 -0
  4. package/dist/demo/app-root.js.map +1 -1
  5. package/dist/src/async-collection-name.d.ts +11 -0
  6. package/dist/src/async-collection-name.js +38 -0
  7. package/dist/src/async-collection-name.js.map +1 -0
  8. package/dist/src/collection-browser.d.ts +4 -2
  9. package/dist/src/collection-browser.js +36 -13
  10. package/dist/src/collection-browser.js.map +1 -1
  11. package/dist/src/collection-facets.d.ts +3 -0
  12. package/dist/src/collection-facets.js +18 -1
  13. package/dist/src/collection-facets.js.map +1 -1
  14. package/dist/src/collection-name-cache.d.ts +18 -0
  15. package/dist/src/collection-name-cache.js +89 -0
  16. package/dist/src/collection-name-cache.js.map +1 -0
  17. package/dist/src/models.d.ts +3 -0
  18. package/dist/src/models.js.map +1 -1
  19. package/dist/src/tiles/grid/item-tile.d.ts +3 -0
  20. package/dist/src/tiles/grid/item-tile.js +13 -3
  21. package/dist/src/tiles/grid/item-tile.js.map +1 -1
  22. package/dist/src/tiles/list/tile-list.d.ts +5 -0
  23. package/dist/src/tiles/list/tile-list.js +73 -70
  24. package/dist/src/tiles/list/tile-list.js.map +1 -1
  25. package/dist/src/tiles/tile-dispatcher.d.ts +3 -0
  26. package/dist/src/tiles/tile-dispatcher.js +10 -1
  27. package/dist/src/tiles/tile-dispatcher.js.map +1 -1
  28. package/dist/test/collection-name-cache.test.d.ts +1 -0
  29. package/dist/test/collection-name-cache.test.js +158 -0
  30. package/dist/test/collection-name-cache.test.js.map +1 -0
  31. package/dist/test/mocks/mock-search-response.d.ts +5 -0
  32. package/dist/test/mocks/mock-search-response.js +62 -0
  33. package/dist/test/mocks/mock-search-response.js.map +1 -0
  34. package/dist/test/mocks/mock-search-service.d.ts +13 -0
  35. package/dist/test/mocks/mock-search-service.js +20 -0
  36. package/dist/test/mocks/mock-search-service.js.map +1 -0
  37. package/package.json +4 -1
  38. package/src/collection-browser.ts +32 -3
  39. package/src/collection-facets.ts +21 -1
  40. package/src/models.ts +3 -0
  41. package/src/tiles/grid/item-tile.ts +14 -3
  42. package/src/tiles/list/tile-list.ts +84 -66
  43. package/src/tiles/tile-dispatcher.ts +11 -0
  44. package/dist/src/assets/img/icons/arrow-right.d.ts +0 -2
  45. package/dist/src/assets/img/icons/arrow-right.js +0 -4
  46. package/dist/src/assets/img/icons/arrow-right.js.map +0 -1
  47. package/dist/src/data-manager.d.ts +0 -68
  48. package/dist/src/data-manager.js +0 -266
  49. package/dist/src/data-manager.js.map +0 -1
  50. package/dist/src/url-manager.d.ts +0 -0
  51. package/dist/src/url-manager.js +0 -2
  52. package/dist/src/url-manager.js.map +0 -1
  53. package/dist/src/your-webcomponent.d.ts +0 -8
  54. package/dist/src/your-webcomponent.js +0 -38
  55. package/dist/src/your-webcomponent.js.map +0 -1
  56. package/dist/test/your-webcomponent.test.d.ts +0 -1
  57. package/dist/test/your-webcomponent.test.js +0 -23
  58. package/dist/test/your-webcomponent.test.js.map +0 -1
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable lit/no-invalid-html */
2
2
  import { css, html, LitElement, nothing } from 'lit';
3
+ import { ifDefined } from 'lit/directives/if-defined.js';
3
4
  import { join } from 'lit/directives/join.js';
4
5
  import { map } from 'lit/directives/map.js';
5
6
  import { customElement, property } from 'lit/decorators.js';
@@ -30,9 +31,9 @@ export class TileList extends LitElement {
30
31
  ${this.iconLeftTemplate}
31
32
  </div>
32
33
  <div id="list-line-right">
33
- <div id="title">${DOMPurify.sanitize(this.model?.title ?? '')}</div>
34
+ <div id="title">${this.titleTemplate}</div>
34
35
  ${this.itemLineTemplate} ${this.creatorTemplate}
35
- <div id="date">
36
+ <div id="date" class="metadata">
36
37
  <span class="label">Published:</span> ${formatDate(
37
38
  this.date,
38
39
  this.formatSize
@@ -48,6 +49,7 @@ export class TileList extends LitElement {
48
49
  `;
49
50
  }
50
51
 
52
+ // Display templates
51
53
  private get imgTemplate() {
52
54
  if (!this.model?.identifier) {
53
55
  return nothing;
@@ -75,12 +77,29 @@ export class TileList extends LitElement {
75
77
  `;
76
78
  }
77
79
 
80
+ private get titleTemplate() {
81
+ if (!this.model?.title) {
82
+ return nothing;
83
+ }
84
+ return html` ${this.detailsLink(this.model.identifier, this.model.title)} `;
85
+ }
86
+
78
87
  private get itemLineTemplate() {
79
88
  const source = this.sourceTemplate;
80
- if (!source) {
89
+ const volume = this.volumeTemplate;
90
+ const issue = this.issueTemplate;
91
+ if (!source && !volume && !issue) {
81
92
  return nothing;
82
93
  }
83
- return html` <div id="item-line">${source}</div> `;
94
+ return html` <div id="item-line">${source} ${volume} ${issue}</div> `;
95
+ }
96
+
97
+ private get volumeTemplate() {
98
+ return this.metadataTemplate(this.model?.volume, 'Volume');
99
+ }
100
+
101
+ private get issueTemplate() {
102
+ return this.metadataTemplate(this.model?.issue, 'Issue');
84
103
  }
85
104
 
86
105
  private get sourceTemplate() {
@@ -89,65 +108,53 @@ export class TileList extends LitElement {
89
108
  }
90
109
  return html`
91
110
  <div id="source">
92
- <span class="label">Source: </span>
111
+ ${this.labelTemplate('Source')}
93
112
  ${this.searchLink('source', this.model.source)}
94
113
  </div>
95
114
  `;
96
115
  }
97
116
 
98
117
  private get creatorTemplate() {
99
- if (!this.model?.creator) {
118
+ if (!this.model?.creators || this.model.creators.length === 0) {
100
119
  return nothing;
101
120
  }
102
121
  return html`
103
- <div id="creator">
104
- <span class="label">By: </span>
105
- ${DOMPurify.sanitize(this.model?.creator ?? '')}
122
+ <div id="creator" class="metadata">
123
+ ${this.labelTemplate('By')}
124
+ ${join(
125
+ map(this.model.creators, id => this.searchLink('creator', id)),
126
+ html`, `
127
+ )}
106
128
  </div>
107
129
  `;
108
130
  }
109
131
 
110
132
  private get viewsTemplate() {
111
- return html`
112
- <div id="views">
113
- <span class="label">Views: </span>
114
- ${formatCount(this.model?.viewCount ?? 0, this.formatSize)}
115
- </div>
116
- `;
133
+ return this.metadataTemplate(
134
+ `${formatCount(this.model?.viewCount ?? 0, this.formatSize)}`,
135
+ 'Views'
136
+ );
117
137
  }
118
138
 
119
139
  private get ratingTemplate() {
120
- if (!this.model?.averageRating) {
121
- return nothing;
122
- }
123
- return html`
124
- <div id="reviews">
125
- <span class="label">Avg Rating: </span>
126
- ${this.model?.averageRating}
127
- </div>
128
- `;
140
+ return this.metadataTemplate(this.model?.averageRating, 'Avg Rating');
129
141
  }
130
142
 
131
143
  private get reviewsTemplate() {
132
- if (!this.model?.commentCount) {
133
- return nothing;
134
- }
135
- return html`
136
- <div id="reviews">
137
- <span class="label">Reviews: </span>
138
- ${this.model?.commentCount}
139
- </div>
140
- `;
144
+ return this.metadataTemplate(this.model?.commentCount, 'Reviews');
141
145
  }
142
146
 
143
147
  private get topicsTemplate() {
144
- if (!this.model?.subjects[0]) {
148
+ if (!this.model?.subjects || this.model.subjects.length === 0) {
145
149
  return nothing;
146
150
  }
147
151
  return html`
148
- <div id="topics">
149
- <span class="label">Topics: </span>
150
- ${DOMPurify.sanitize(this.model?.subjects[0])}
152
+ <div id="topics" class="metadata">
153
+ ${this.labelTemplate('Topics')}
154
+ ${join(
155
+ map(this.model.subjects, id => this.searchLink('subject', id)),
156
+ html`, `
157
+ )}
151
158
  </div>
152
159
  `;
153
160
  }
@@ -157,8 +164,8 @@ export class TileList extends LitElement {
157
164
  return nothing;
158
165
  }
159
166
  return html`
160
- <div id="collections">
161
- <span class="label">Collections: </span>
167
+ <div id="collections" class="metadata">
168
+ ${this.labelTemplate('Collections')}
162
169
  ${join(
163
170
  map(this.model.collections, id => this.detailsLink(id)),
164
171
  html`, `
@@ -168,11 +175,27 @@ export class TileList extends LitElement {
168
175
  }
169
176
 
170
177
  private get descriptionTemplate() {
171
- if (!this.model?.description) {
172
- return nothing;
173
- }
174
- const description = DOMPurify.sanitize(`${this.model?.description}`);
175
- return html` <div id="description">${description}</div> `;
178
+ return this.metadataTemplate(
179
+ DOMPurify.sanitize(this.model?.description ?? ''),
180
+ '',
181
+ 'description'
182
+ );
183
+ }
184
+
185
+ // Utility functions
186
+ private metadataTemplate(text: any, label = '', id?: string) {
187
+ if (!text) return nothing;
188
+ return html`
189
+ <div id=${ifDefined(id)} class="metadata">
190
+ ${this.labelTemplate(label)} ${text}
191
+ </div>
192
+ `;
193
+ }
194
+
195
+ private labelTemplate(label: string) {
196
+ return html`${label
197
+ ? html`<span class="label">${label}: </span>`
198
+ : nothing}`;
176
199
  }
177
200
 
178
201
  private searchLink(field: string, searchTerm: string) {
@@ -180,21 +203,20 @@ export class TileList extends LitElement {
180
203
  return nothing;
181
204
  }
182
205
  const query = encodeURIComponent(`${field}:"${searchTerm}"`);
183
- // eslint-disable-next-line lit/no-invalid-html
184
- return html`
185
- <a href="${this.baseNavigationUrl}/search.php?query=${query}">
186
- ${DOMPurify.sanitize(searchTerm)}
187
- </a>
188
- `;
206
+ // No whitespace after closing tag
207
+ return html` <a href="${this.baseNavigationUrl}/search.php?query=${query}">
208
+ ${DOMPurify.sanitize(searchTerm)}</a
209
+ >`;
189
210
  }
190
211
 
191
- private detailsLink(identifier: string) {
212
+ private detailsLink(identifier: string, text?: string) {
192
213
  if (!identifier) {
193
214
  return nothing;
194
215
  }
216
+ const linkText = text ?? identifier;
195
217
  // No whitespace after closing tag
196
218
  return html` <a href="${this.baseNavigationUrl}/details/${identifier}"
197
- >${DOMPurify.sanitize(identifier)}</a
219
+ >${DOMPurify.sanitize(linkText)}</a
198
220
  >`;
199
221
  }
200
222
 
@@ -234,6 +256,10 @@ export class TileList extends LitElement {
234
256
  font-size: 14px;
235
257
  }
236
258
 
259
+ div a {
260
+ text-decoration: none;
261
+ }
262
+
237
263
  .label {
238
264
  font-weight: bold;
239
265
  }
@@ -291,18 +317,16 @@ export class TileList extends LitElement {
291
317
  text-decoration: none;
292
318
  font-size: 22px;
293
319
  font-weight: bold;
294
- line-height: 30px;
320
+ /* align top of text with image */
321
+ line-height: 25px;
322
+ margin-top: -4px;
323
+ padding-bottom: 2px;
295
324
  }
296
325
 
297
- #creator,
298
- #date,
299
- #collections,
300
- #topics,
301
- #item-line {
326
+ .metadata {
302
327
  line-height: 20px;
303
328
  }
304
329
 
305
- #title,
306
330
  #creator,
307
331
  #topic,
308
332
  #source {
@@ -310,11 +334,6 @@ export class TileList extends LitElement {
310
334
  overflow: hidden;
311
335
  }
312
336
 
313
- #title,
314
- #creator {
315
- white-space: nowrap;
316
- }
317
-
318
337
  #icon {
319
338
  padding-top: 5px;
320
339
  }
@@ -344,7 +363,7 @@ export class TileList extends LitElement {
344
363
  column-gap: 5px;
345
364
  }
346
365
 
347
- #list-line:hover #title {
366
+ div a:hover {
348
367
  text-decoration: underline;
349
368
  }
350
369
 
@@ -353,7 +372,6 @@ export class TileList extends LitElement {
353
372
  display: flex;
354
373
  flex-direction: row;
355
374
  gap: 10px;
356
- line-height: 20px;
357
375
  }
358
376
  `;
359
377
  }
@@ -6,6 +6,7 @@ import {
6
6
  SharedResizeObserverResizeHandlerInterface,
7
7
  } from '@internetarchive/shared-resize-observer';
8
8
  import { SortParam } from '@internetarchive/search-service';
9
+ import type { CollectionNameCacheInterface } from '@internetarchive/collection-name-cache';
9
10
  import type { CollectionDisplayMode, TileModel } from '../models';
10
11
  import './grid/collection-tile';
11
12
  import './grid/item-tile';
@@ -35,6 +36,9 @@ export class TileDispatcher
35
36
 
36
37
  @property({ type: Object }) sortParam?: SortParam;
37
38
 
39
+ @property({ type: Object })
40
+ collectionNameCache?: CollectionNameCacheInterface;
41
+
38
42
  @query('#container') private container!: HTMLDivElement;
39
43
 
40
44
  render() {
@@ -64,6 +68,12 @@ export class TileDispatcher
64
68
  ${this.showDeleteButton
65
69
  ? html`<button id="delete-button">X</button>`
66
70
  : nothing}
71
+ ${this.displayMode === 'list-detail' ? this.tile : this.linkTileTemplate}
72
+ `;
73
+ }
74
+
75
+ private get linkTileTemplate() {
76
+ return html`
67
77
  <a
68
78
  href="${this.baseNavigationUrl}/details/${this.model?.identifier}"
69
79
  title=${ifDefined(this.model?.title)}
@@ -135,6 +145,7 @@ export class TileDispatcher
135
145
  .baseNavigationUrl=${baseNavigationUrl}
136
146
  .currentWidth=${currentWidth}
137
147
  .currentHeight=${currentHeight}
148
+ .collectionNameCache=${this.collectionNameCache}
138
149
  ></item-tile>`;
139
150
  }
140
151
  case 'list-compact':
@@ -1,2 +0,0 @@
1
- declare const _default: import("lit-html").TemplateResult<2>;
2
- export default _default;
@@ -1,4 +0,0 @@
1
- import { svg } from 'lit';
2
- export default svg `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="m79.8883285 50.0035012.1116715-.1085359-43.1159942-46.61088155c-2.401537-2.18938917-4.6902018-3.28408375-6.8659943-3.28408375s-4.1642651.63837733-5.9654178 1.91513199c-1.8011528 1.27675467-3.1520173 2.97248092-4.0525937 5.08717877l39.4020173 42.99768924-39.4020173 42.9976892c.9005764 2.1146979 2.2514409 3.8104241 4.0525937 5.0871788 1.8011527 1.2767547 3.7896253 1.915132 5.9654178 1.915132 2.1013449 0 4.3900096-1.0573489 6.8659943-3.1720468l43.1159942-46.7194174z"/></svg>
3
- `;
4
- //# sourceMappingURL=arrow-right.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"arrow-right.js","sourceRoot":"","sources":["../../../../../src/assets/img/icons/arrow-right.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,eAAe,GAAG,CAAA;CACjB,CAAA","sourcesContent":["import { svg } from 'lit';\n\nexport default svg`<svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m79.8883285 50.0035012.1116715-.1085359-43.1159942-46.61088155c-2.401537-2.18938917-4.6902018-3.28408375-6.8659943-3.28408375s-4.1642651.63837733-5.9654178 1.91513199c-1.8011528 1.27675467-3.1520173 2.97248092-4.0525937 5.08717877l39.4020173 42.99768924-39.4020173 42.9976892c.9005764 2.1146979 2.2514409 3.8104241 4.0525937 5.0871788 1.8011527 1.2767547 3.7896253 1.915132 5.9654178 1.915132 2.1013449 0 4.3900096-1.0573489 6.8659943-3.1720468l43.1159942-46.7194174z\"/></svg>\n`\n"]}
@@ -1,68 +0,0 @@
1
- import { Aggregation, SortParam, SearchServiceInterface } from '@internetarchive/search-service';
2
- import { SelectedFacets } from './models';
3
- import type { TileModel } from './models';
4
- export interface DataManagerInterface {
5
- fetchFullYearHistogram(): Promise<Aggregation | undefined>;
6
- fetchFacets(): Promise<Record<string, Aggregation> | undefined>;
7
- }
8
- export declare class DataManager implements DataManagerInterface {
9
- searchService: SearchServiceInterface;
10
- dataSource: Record<string, TileModel[]>;
11
- titleQuery?: string;
12
- creatorQuery?: string;
13
- baseQuery?: string;
14
- sortParam: SortParam | null;
15
- dateRangeQueryClause?: string;
16
- pageSize: number;
17
- selectedFacets: SelectedFacets;
18
- endOfDataReached: boolean;
19
- private pageFetchesInProgress;
20
- /**
21
- * The query key is a string that uniquely identifies the current query
22
- * without the date range.
23
- *
24
- * If this doesn't change, we don't need to re-fetch the histogram date range
25
- */
26
- private get fullQueryNoDateKey();
27
- /**
28
- * If we haven't changed the query, we don't need to fetch the full year histogram
29
- *
30
- * @private
31
- * @type {string}
32
- * @memberof CollectionBrowser
33
- */
34
- private previousFullQueryNoDate?;
35
- /**
36
- * This method is similar to fetching the facets above,
37
- * but only fetching the year histogram. There is a subtle difference
38
- * in how you have to fetch the year histogram where you can't use the
39
- * advanced JSON syntax like the other aggregations. It's a special
40
- * case that @ximm put it place.
41
- */
42
- fetchFullYearHistogram(): Promise<Aggregation | undefined>;
43
- fetchFacets(): Promise<Record<string, Aggregation> | undefined>;
44
- /**
45
- * Generates a query string for the given facets
46
- *
47
- * Example: `mediatype:("collection" OR "audio" OR -"etree") AND year:("2000" OR "2001")`
48
- */
49
- private get facetQuery();
50
- private get sortFilterQueries();
51
- private get fullQueryWithoutDate();
52
- private get fullQuery();
53
- /**
54
- * The query key is a string that uniquely identifies the current query
55
- *
56
- * This lets us keep track of queries so we don't persist data that's
57
- * no longer relevant.
58
- */
59
- private get pageFetchQueryKey();
60
- fetchPage(pageNumber: number): Promise<void>;
61
- /**
62
- * Update the datasource from the fetch response
63
- *
64
- * @param pageNumber
65
- * @param docs
66
- */
67
- private updateDataSource;
68
- }
@@ -1,266 +0,0 @@
1
- import { SearchParams, SearchService, AggregateSearchParams, } from '@internetarchive/search-service';
2
- export class DataManager {
3
- constructor() {
4
- this.searchService = SearchService.default;
5
- this.dataSource = {};
6
- this.sortParam = null;
7
- this.pageSize = 50;
8
- this.selectedFacets = {
9
- subject: {},
10
- creator: {},
11
- mediatype: {},
12
- language: {},
13
- collection: {},
14
- year: {},
15
- };
16
- this.endOfDataReached = false;
17
- // this maps the query to the pages being fetched for that query
18
- this.pageFetchesInProgress = {};
19
- }
20
- /**
21
- * The query key is a string that uniquely identifies the current query
22
- * without the date range.
23
- *
24
- * If this doesn't change, we don't need to re-fetch the histogram date range
25
- */
26
- get fullQueryNoDateKey() {
27
- var _a;
28
- return `${this.fullQueryWithoutDate}-${(_a = this.sortParam) === null || _a === void 0 ? void 0 : _a.asString}`;
29
- }
30
- /**
31
- * This method is similar to fetching the facets above,
32
- * but only fetching the year histogram. There is a subtle difference
33
- * in how you have to fetch the year histogram where you can't use the
34
- * advanced JSON syntax like the other aggregations. It's a special
35
- * case that @ximm put it place.
36
- */
37
- async fetchFullYearHistogram() {
38
- var _a, _b, _c, _d;
39
- const { fullQueryNoDateKey } = this;
40
- if (!this.fullQueryWithoutDate ||
41
- fullQueryNoDateKey === this.previousFullQueryNoDate)
42
- return undefined;
43
- this.previousFullQueryNoDate = fullQueryNoDateKey;
44
- const aggregations = new AggregateSearchParams({
45
- simpleParams: ['year'],
46
- });
47
- const params = new SearchParams({
48
- query: this.fullQueryWithoutDate,
49
- fields: ['identifier'],
50
- aggregations,
51
- rows: 1,
52
- });
53
- // this.fullYearAggregationLoading = true;
54
- const results = await ((_a = this.searchService) === null || _a === void 0 ? void 0 : _a.search(params));
55
- // this.fullYearAggregationLoading = false;
56
- // this.fullYearsHistogramAggregation =
57
- return (_d = (_c = (_b = results === null || results === void 0 ? void 0 : results.success) === null || _b === void 0 ? void 0 : _b.response) === null || _c === void 0 ? void 0 : _c.aggregations) === null || _d === void 0 ? void 0 : _d.year_histogram;
58
- }
59
- async fetchFacets() {
60
- var _a, _b;
61
- if (!this.fullQuery)
62
- return undefined;
63
- const aggregations = new AggregateSearchParams({
64
- advancedParams: [
65
- {
66
- field: 'subjectSorter',
67
- size: 6,
68
- },
69
- {
70
- field: 'mediatypeSorter',
71
- size: 6,
72
- },
73
- {
74
- field: 'languageSorter',
75
- size: 6,
76
- },
77
- {
78
- field: 'creatorSorter',
79
- size: 6,
80
- },
81
- {
82
- field: 'collection',
83
- size: 12,
84
- },
85
- {
86
- field: 'year',
87
- size: 50,
88
- },
89
- ],
90
- });
91
- const params = new SearchParams({
92
- query: this.fullQuery,
93
- fields: ['identifier'],
94
- aggregations,
95
- rows: 1,
96
- });
97
- // this.facetsLoading = true;
98
- const results = await ((_a = this.searchService) === null || _a === void 0 ? void 0 : _a.search(params));
99
- // this.facetsLoading = false;
100
- return (_b = results === null || results === void 0 ? void 0 : results.success) === null || _b === void 0 ? void 0 : _b.response.aggregations;
101
- }
102
- /**
103
- * Generates a query string for the given facets
104
- *
105
- * Example: `mediatype:("collection" OR "audio" OR -"etree") AND year:("2000" OR "2001")`
106
- */
107
- get facetQuery() {
108
- const facetQuery = [];
109
- for (const [facetName, facetValues] of Object.entries(this.selectedFacets)) {
110
- const facetEntries = Object.entries(facetValues);
111
- // eslint-disable-next-line no-continue
112
- if (facetEntries.length === 0)
113
- continue;
114
- const facetValuesArray = [];
115
- for (const [key, facetState] of facetEntries) {
116
- facetValuesArray.push(`${facetState === 'hidden' ? '-' : ''}"${key}"`);
117
- }
118
- const valueQuery = facetValuesArray.join(` OR `);
119
- facetQuery.push(`${facetName}:(${valueQuery})`);
120
- }
121
- return facetQuery.length > 0 ? `(${facetQuery.join(' AND ')})` : undefined;
122
- }
123
- get sortFilterQueries() {
124
- const queries = [this.titleQuery, this.creatorQuery];
125
- return queries.filter(q => q).join(' AND ');
126
- }
127
- get fullQueryWithoutDate() {
128
- if (!this.baseQuery)
129
- return undefined;
130
- let fullQuery = this.baseQuery;
131
- const { facetQuery, sortFilterQueries } = this;
132
- if (facetQuery) {
133
- fullQuery += ` AND ${facetQuery}`;
134
- }
135
- if (sortFilterQueries) {
136
- fullQuery += ` AND ${sortFilterQueries}`;
137
- }
138
- return fullQuery;
139
- }
140
- get fullQuery() {
141
- let { fullQueryWithoutDate } = this;
142
- const { dateRangeQueryClause } = this;
143
- if (dateRangeQueryClause) {
144
- fullQueryWithoutDate += ` AND ${dateRangeQueryClause}`;
145
- }
146
- return fullQueryWithoutDate;
147
- }
148
- /**
149
- * The query key is a string that uniquely identifies the current query
150
- *
151
- * This lets us keep track of queries so we don't persist data that's
152
- * no longer relevant.
153
- */
154
- get pageFetchQueryKey() {
155
- var _a;
156
- return `${this.fullQuery}-${(_a = this.sortParam) === null || _a === void 0 ? void 0 : _a.asString}`;
157
- }
158
- async fetchPage(pageNumber) {
159
- var _a, _b, _c, _d;
160
- if (!this.fullQuery)
161
- return;
162
- // if we already have data, don't fetch again
163
- if (this.dataSource[pageNumber])
164
- return;
165
- if (this.endOfDataReached)
166
- return;
167
- // if a fetch is already in progress for this query and page, don't fetch again
168
- const { pageFetchQueryKey } = this;
169
- const pageFetches = (_a = this.pageFetchesInProgress[pageFetchQueryKey]) !== null && _a !== void 0 ? _a : new Set();
170
- if (pageFetches.has(pageNumber))
171
- return;
172
- pageFetches.add(pageNumber);
173
- this.pageFetchesInProgress[pageFetchQueryKey] = pageFetches;
174
- const sortParams = this.sortParam ? [this.sortParam] : [];
175
- const params = new SearchParams({
176
- query: this.fullQuery,
177
- fields: [
178
- 'identifier',
179
- 'title',
180
- 'mediatype',
181
- 'downloads',
182
- 'avg_rating',
183
- 'num_favorites',
184
- 'num_reviews',
185
- 'item_count',
186
- 'description',
187
- 'date',
188
- 'addeddate',
189
- 'publicdate',
190
- 'reviewdate',
191
- 'creator',
192
- 'collections_raw',
193
- ],
194
- page: pageNumber,
195
- rows: this.pageSize,
196
- sort: sortParams,
197
- });
198
- const results = await ((_b = this.searchService) === null || _b === void 0 ? void 0 : _b.search(params));
199
- const success = results === null || results === void 0 ? void 0 : results.success;
200
- if (!success)
201
- return;
202
- // this.totalResults = success.response.numFound;
203
- // this is checking to see if the query has changed since the data was fetched
204
- // if so, we just want to discard the data since there should be a new query
205
- // right behind it
206
- const searchQuery = success.responseHeader.params.qin;
207
- const searchSort = success.responseHeader.params.sort;
208
- const queryChangedSinceFetch = searchQuery !== this.fullQuery || searchSort !== ((_c = this.sortParam) === null || _c === void 0 ? void 0 : _c.asString);
209
- if (queryChangedSinceFetch)
210
- return;
211
- const { docs } = success.response;
212
- if (docs && docs.length > 0) {
213
- this.updateDataSource(pageNumber, docs);
214
- }
215
- if (docs.length < this.pageSize) {
216
- this.endOfDataReached = true;
217
- // this updates the infinite scroller to show the actual size
218
- // this.infiniteScroller.itemCount = this.actualTileCount;
219
- }
220
- (_d = this.pageFetchesInProgress[pageFetchQueryKey]) === null || _d === void 0 ? void 0 : _d.delete(pageNumber);
221
- // this.searchResultsLoading = false;
222
- }
223
- /**
224
- * Update the datasource from the fetch response
225
- *
226
- * @param pageNumber
227
- * @param docs
228
- */
229
- updateDataSource(pageNumber, docs) {
230
- // copy our existing datasource so when we set it below, it gets set
231
- // instead of modifying the existing dataSource since object changes
232
- // don't trigger a re-render
233
- const datasource = { ...this.dataSource };
234
- const tiles = [];
235
- docs === null || docs === void 0 ? void 0 : docs.forEach(doc => {
236
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
237
- if (!doc.identifier)
238
- return;
239
- tiles.push({
240
- identifier: doc.identifier,
241
- title: (_b = (_a = doc.title) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '',
242
- mediatype: (_d = (_c = doc.mediatype) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : 'data',
243
- viewCount: (_f = (_e = doc.downloads) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : 0,
244
- favCount: (_h = (_g = doc.num_favorites) === null || _g === void 0 ? void 0 : _g.value) !== null && _h !== void 0 ? _h : 0,
245
- commentCount: (_k = (_j = doc.num_reviews) === null || _j === void 0 ? void 0 : _j.value) !== null && _k !== void 0 ? _k : 0,
246
- itemCount: (_m = (_l = doc.item_count) === null || _l === void 0 ? void 0 : _l.value) !== null && _m !== void 0 ? _m : 0,
247
- description: (_o = doc.description) === null || _o === void 0 ? void 0 : _o.value,
248
- dateAdded: (_p = doc.addeddate) === null || _p === void 0 ? void 0 : _p.value,
249
- dateArchived: (_q = doc.publicdate) === null || _q === void 0 ? void 0 : _q.value,
250
- dateReviewed: (_r = doc.reviewdate) === null || _r === void 0 ? void 0 : _r.value,
251
- datePublished: (_s = doc.date) === null || _s === void 0 ? void 0 : _s.value,
252
- creator: (_t = doc.creator) === null || _t === void 0 ? void 0 : _t.value,
253
- averageRating: (_u = doc.avg_rating) === null || _u === void 0 ? void 0 : _u.value,
254
- collections: (_w = (_v = doc.collections_raw) === null || _v === void 0 ? void 0 : _v.values) !== null && _w !== void 0 ? _w : [],
255
- });
256
- });
257
- datasource[pageNumber] = tiles;
258
- this.dataSource = datasource;
259
- // const visiblePages = this.currentVisiblePageNumbers;
260
- // const needsReload = visiblePages.includes(pageNumber);
261
- // if (needsReload) {
262
- // this.infiniteScroller.reload();
263
- // }
264
- }
265
- }
266
- //# sourceMappingURL=data-manager.js.map