@internetarchive/collection-browser 0.4.15 → 0.4.16-alpha.1

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.
@@ -29,6 +29,7 @@ import {
29
29
  FacetOption,
30
30
  facetTitles,
31
31
  suppressedCollections,
32
+ valueFacetSort,
32
33
  } from '../models';
33
34
  import '@internetarchive/ia-activity-indicator/ia-activity-indicator';
34
35
  import './more-facets-pagination';
@@ -86,7 +87,13 @@ export class MoreFacetsContent extends LitElement {
86
87
  private facetsPerPage = 35;
87
88
 
88
89
  updated(changed: PropertyValues) {
89
- if (changed.has('facetKey')) {
90
+ if (
91
+ changed.has('facetKey') ||
92
+ changed.has('facetAggregationKey') ||
93
+ changed.has('query') ||
94
+ changed.has('searchType') ||
95
+ changed.has('filterMap')
96
+ ) {
90
97
  this.facetsLoading = true;
91
98
  this.pageNumber = 1;
92
99
 
@@ -380,17 +387,22 @@ export class MoreFacetsContent extends LitElement {
380
387
  return html`<span class="sr-only">More facets for:</span>
381
388
  <span class="title">
382
389
  ${this.facetGroupTitle}
390
+
383
391
  <label class="sort-label">Sort by:</label>
384
- <toggle-switch
385
- class="sort-toggle"
386
- leftValue=${AggregationSortType.COUNT}
387
- leftLabel="Count"
388
- rightValue=${AggregationSortType.ALPHABETICAL}
389
- rightLabel=${this.facetGroupTitle}
390
- @change=${(e: CustomEvent<string>) => {
391
- this.sortFacetAggregation(Number(e.detail) as AggregationSortType);
392
- }}
393
- ></toggle-switch>
392
+ ${this.facetKey
393
+ ? html`<toggle-switch
394
+ class="sort-toggle"
395
+ leftValue=${AggregationSortType.COUNT}
396
+ leftLabel="Count"
397
+ rightValue=${valueFacetSort[this.facetKey]}
398
+ rightLabel=${this.facetGroupTitle}
399
+ @change=${(e: CustomEvent<string>) => {
400
+ this.sortFacetAggregation(
401
+ Number(e.detail) as AggregationSortType
402
+ );
403
+ }}
404
+ ></toggle-switch>`
405
+ : nothing}
394
406
  </span>`;
395
407
  }
396
408
 
@@ -11,6 +11,7 @@ import { customElement, property, state } from 'lit/decorators.js';
11
11
  import { map } from 'lit/directives/map.js';
12
12
  import type {
13
13
  Aggregation,
14
+ AggregationSortType,
14
15
  Bucket,
15
16
  FilterMap,
16
17
  SearchServiceInterface,
@@ -40,6 +41,7 @@ import {
40
41
  lendingFacetKeysVisibility,
41
42
  LendingFacetKey,
42
43
  suppressedCollections,
44
+ defaultFacetSort,
43
45
  } from './models';
44
46
  import './collection-facets/more-facets-content';
45
47
  import './collection-facets/facets-template';
@@ -309,7 +311,7 @@ export class CollectionFacets extends LitElement {
309
311
  */
310
312
  private get aggregationFacetGroups(): FacetGroup[] {
311
313
  const facetGroups: FacetGroup[] = [];
312
- Object.entries(this.aggregations ?? []).forEach(([key, buckets]) => {
314
+ Object.entries(this.aggregations ?? []).forEach(([key, aggregation]) => {
313
315
  // the year_histogram data is in a different format so can't be handled here
314
316
  if (key === 'year_histogram') return;
315
317
 
@@ -317,7 +319,9 @@ export class CollectionFacets extends LitElement {
317
319
  const title = facetTitles[option];
318
320
  if (!title) return;
319
321
 
320
- let castedBuckets = buckets.buckets as Bucket[];
322
+ let castedBuckets = aggregation.getSortedBuckets(
323
+ defaultFacetSort[option]
324
+ ) as Bucket[];
321
325
 
322
326
  if (option === 'collection') {
323
327
  // we are not showing fav- collections or certain deemphasized collections in facets
@@ -433,10 +437,13 @@ export class CollectionFacets extends LitElement {
433
437
  return nothing;
434
438
  }
435
439
 
440
+ // We sort years in numeric order by default, rather than bucket count
441
+ const facetSort = defaultFacetSort[facetGroup.key];
442
+
436
443
  return html`<button
437
444
  class="more-link"
438
445
  @click=${() => {
439
- this.showMoreFacetsModal(facetGroup, 'count');
446
+ this.showMoreFacetsModal(facetGroup, facetSort);
440
447
  this.analyticsHandler?.sendEvent({
441
448
  category: analyticsCategories.default,
442
449
  action: analyticsActions.showMoreFacetsModal,
@@ -453,7 +460,7 @@ export class CollectionFacets extends LitElement {
453
460
 
454
461
  async showMoreFacetsModal(
455
462
  facetGroup: FacetGroup,
456
- sortedBy: string
463
+ sortedBy: AggregationSortType
457
464
  ): Promise<void> {
458
465
  const facetAggrKey = facetGroup.key;
459
466
 
package/src/models.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import type { MediaType } from '@internetarchive/field-parsers';
2
- import type { SortDirection } from '@internetarchive/search-service';
2
+ import {
3
+ AggregationSortType,
4
+ SortDirection,
5
+ } from '@internetarchive/search-service';
3
6
 
4
7
  export interface TileModel {
5
8
  averageRating?: number;
@@ -254,6 +257,33 @@ export const facetTitles: Record<FacetOption, string> = {
254
257
  year: 'Year',
255
258
  };
256
259
 
260
+ /**
261
+ * The default sort type to use for each facet type
262
+ */
263
+ export const defaultFacetSort: Record<FacetOption, AggregationSortType> = {
264
+ subject: AggregationSortType.COUNT,
265
+ lending: AggregationSortType.COUNT,
266
+ mediatype: AggregationSortType.COUNT,
267
+ language: AggregationSortType.COUNT,
268
+ creator: AggregationSortType.COUNT,
269
+ collection: AggregationSortType.COUNT,
270
+ year: AggregationSortType.NUMERIC,
271
+ };
272
+
273
+ /**
274
+ * The sort type corresponding to facet bucket values, for each facet type
275
+ * (i.e., the opposite of "sort by count" for that type).
276
+ */
277
+ export const valueFacetSort: Record<FacetOption, AggregationSortType> = {
278
+ subject: AggregationSortType.ALPHABETICAL,
279
+ lending: AggregationSortType.ALPHABETICAL,
280
+ mediatype: AggregationSortType.ALPHABETICAL,
281
+ language: AggregationSortType.ALPHABETICAL,
282
+ creator: AggregationSortType.ALPHABETICAL,
283
+ collection: AggregationSortType.ALPHABETICAL,
284
+ year: AggregationSortType.NUMERIC,
285
+ };
286
+
257
287
  export type LendingFacetKey =
258
288
  | 'is_lendable'
259
289
  | 'is_borrowable'
@@ -233,9 +233,14 @@ export class RestorationStateHandler
233
233
  restorationState.baseQuery = legacySearchQuery;
234
234
  }
235
235
 
236
- if (searchInside) {
237
- restorationState.searchType =
238
- searchInside === 'TXT' ? SearchType.FULLTEXT : SearchType.METADATA;
236
+ switch (searchInside) {
237
+ // Eventually there will be TV/Radio search types here too.
238
+ case 'TXT':
239
+ restorationState.searchType = SearchType.FULLTEXT;
240
+ break;
241
+ default:
242
+ restorationState.searchType = SearchType.METADATA;
243
+ break;
239
244
  }
240
245
 
241
246
  if (pageNumber) {
@@ -261,13 +261,13 @@ describe('Collection Browser', () => {
261
261
  const searchService = new MockSearchService();
262
262
 
263
263
  const el = await fixture<CollectionBrowser>(
264
- html` <collection-browser
265
- .searchService=${searchService}
266
- .searchType=${SearchType.METADATA}
267
- >
264
+ html` <collection-browser .searchService=${searchService}>
268
265
  </collection-browser>`
269
266
  );
270
267
 
268
+ el.searchType = SearchType.METADATA;
269
+ await el.updateComplete;
270
+
271
271
  el.baseQuery = 'collection:foo';
272
272
  await el.updateComplete;
273
273
  await nextTick();
@@ -279,7 +279,7 @@ describe('Collection Browser', () => {
279
279
  ).to.contains('Results');
280
280
  });
281
281
 
282
- it('can request a search when changing search type', async () => {
282
+ it('can change search type', async () => {
283
283
  const searchService = new MockSearchService();
284
284
  const el = await fixture<CollectionBrowser>(
285
285
  html`<collection-browser .searchService=${searchService}>
@@ -290,7 +290,6 @@ describe('Collection Browser', () => {
290
290
  await el.updateComplete;
291
291
 
292
292
  el.searchType = SearchType.FULLTEXT;
293
- el.requestSearch();
294
293
  await el.updateComplete;
295
294
  await nextTick();
296
295
 
@@ -301,13 +300,13 @@ describe('Collection Browser', () => {
301
300
  const searchService = new MockSearchService();
302
301
 
303
302
  const el = await fixture<CollectionBrowser>(
304
- html` <collection-browser
305
- .searchService=${searchService}
306
- .searchType=${SearchType.FULLTEXT}
307
- >
303
+ html` <collection-browser .searchService=${searchService}>
308
304
  </collection-browser>`
309
305
  );
310
306
 
307
+ el.searchType = SearchType.FULLTEXT;
308
+ await el.updateComplete;
309
+
311
310
  el.baseQuery = 'collection:foo';
312
311
  await el.updateComplete;
313
312
  await nextTick();
@@ -26,6 +26,17 @@ describe('Restoration state handler', () => {
26
26
  expect(restorationState.searchType).to.equal(SearchType.METADATA);
27
27
  });
28
28
 
29
+ it('should restore metadata search type if sin explicitly empty in URL', async () => {
30
+ const handler = new RestorationStateHandler({ context: 'search' });
31
+
32
+ const url = new URL(window.location.href);
33
+ url.search = '?sin=';
34
+ window.history.replaceState({ path: url.href }, '', url.href);
35
+
36
+ const restorationState = handler.getRestorationState();
37
+ expect(restorationState.searchType).to.equal(SearchType.METADATA);
38
+ });
39
+
29
40
  it('should restore full text search type from URL', async () => {
30
41
  const handler = new RestorationStateHandler({ context: 'search' });
31
42