@internetarchive/collection-browser 4.2.1-alpha-webdev8165.0 → 4.3.0
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/.claude/settings.local.json +11 -0
- package/dist/src/data-source/collection-browser-data-source.d.ts +7 -0
- package/dist/src/data-source/collection-browser-data-source.js +24 -8
- package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
- package/dist/src/models.d.ts +6 -0
- package/dist/src/models.js +16 -7
- package/dist/src/models.js.map +1 -1
- package/dist/src/restoration-state-handler.js +3 -1
- package/dist/src/restoration-state-handler.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact-header.js +45 -45
- package/dist/src/tiles/list/tile-list-compact-header.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact.js +99 -99
- package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
- package/dist/src/tiles/list/tile-list.js +300 -299
- package/dist/src/tiles/list/tile-list.js.map +1 -1
- package/dist/src/tiles/tile-display-value-provider.d.ts +5 -0
- package/dist/src/tiles/tile-display-value-provider.js +9 -0
- package/dist/src/tiles/tile-display-value-provider.js.map +1 -1
- package/dist/test/data-source/collection-browser-data-source.test.js +54 -2
- package/dist/test/data-source/collection-browser-data-source.test.js.map +1 -1
- package/dist/test/restoration-state-handler.test.js +0 -70
- package/dist/test/restoration-state-handler.test.js.map +1 -1
- package/dist/test/tiles/list/tile-list-compact-header.test.d.ts +1 -0
- package/dist/test/tiles/list/tile-list-compact-header.test.js +36 -0
- package/dist/test/tiles/list/tile-list-compact-header.test.js.map +1 -0
- package/dist/test/tiles/list/tile-list.test.js +147 -127
- package/dist/test/tiles/list/tile-list.test.js.map +1 -1
- package/package.json +1 -1
- package/src/data-source/collection-browser-data-source.ts +1465 -1445
- package/src/models.ts +23 -7
- package/src/restoration-state-handler.ts +5 -1
- package/src/tiles/list/tile-list-compact-header.ts +86 -86
- package/src/tiles/list/tile-list-compact.ts +239 -239
- package/src/tiles/list/tile-list.ts +700 -700
- package/src/tiles/tile-display-value-provider.ts +134 -124
- package/test/data-source/collection-browser-data-source.test.ts +193 -131
- package/test/restoration-state-handler.test.ts +0 -89
- package/test/tiles/list/tile-list-compact-header.test.ts +43 -0
- package/test/tiles/list/tile-list.test.ts +576 -552
package/src/models.ts
CHANGED
|
@@ -364,6 +364,13 @@ export interface SortOption {
|
|
|
364
364
|
*/
|
|
365
365
|
shownInSortBar: boolean;
|
|
366
366
|
|
|
367
|
+
/**
|
|
368
|
+
* Whether this sort option should be saved to the URL.
|
|
369
|
+
* If false, then no `sort` param will be added to the URL when this sort option
|
|
370
|
+
* is selected.
|
|
371
|
+
*/
|
|
372
|
+
shownInURL: boolean;
|
|
373
|
+
|
|
367
374
|
/**
|
|
368
375
|
* Whether this sort option is passed to the search service.
|
|
369
376
|
* If false, then no sort param will be passed to the search service at all when
|
|
@@ -401,6 +408,7 @@ export const SORT_OPTIONS: Record<SortField, SortOption> = {
|
|
|
401
408
|
defaultSortDirection: null,
|
|
402
409
|
canSetDirection: false,
|
|
403
410
|
shownInSortBar: false,
|
|
411
|
+
shownInURL: false,
|
|
404
412
|
handledBySearchService: false, // We rely on the PPS default sort handling in these cases
|
|
405
413
|
displayName: '',
|
|
406
414
|
urlNames: ['', null, undefined], // Empty or nullish sort params result in default sorting
|
|
@@ -414,30 +422,30 @@ export const SORT_OPTIONS: Record<SortField, SortOption> = {
|
|
|
414
422
|
defaultSortDirection: null,
|
|
415
423
|
canSetDirection: true,
|
|
416
424
|
shownInSortBar: false,
|
|
425
|
+
shownInURL: false,
|
|
417
426
|
handledBySearchService: true, // The unrecognized sort param is passed along as-is
|
|
418
427
|
displayName: '',
|
|
419
428
|
urlNames: [],
|
|
420
429
|
},
|
|
421
|
-
// Relevance sort is
|
|
422
|
-
//
|
|
423
|
-
//
|
|
424
|
-
// remapped to SortField.default and does not produce a URL param. When it is NOT the default
|
|
425
|
-
// (e.g., TV searches), it writes `sort=relevance` to the URL. The `_score` alias is retained
|
|
426
|
-
// for backwards compatibility (it's what the PPS uses under the hood).
|
|
430
|
+
// Relevance sort is unique in that it does not produce a URL param when it is set.
|
|
431
|
+
// It is only available when there is a user-specified query that relevancy can be scored against.
|
|
432
|
+
// Therefore, it does not appear as a sort bar option when browsing a collection with no query set.
|
|
427
433
|
[SortField.relevance]: {
|
|
428
434
|
field: SortField.relevance,
|
|
429
435
|
defaultSortDirection: null,
|
|
430
436
|
canSetDirection: false,
|
|
431
437
|
shownInSortBar: true,
|
|
438
|
+
shownInURL: false,
|
|
432
439
|
handledBySearchService: false,
|
|
433
440
|
displayName: 'Relevance',
|
|
434
|
-
urlNames: ['
|
|
441
|
+
urlNames: ['_score'],
|
|
435
442
|
},
|
|
436
443
|
[SortField.alltimeview]: {
|
|
437
444
|
field: SortField.alltimeview,
|
|
438
445
|
defaultSortDirection: 'desc',
|
|
439
446
|
canSetDirection: true,
|
|
440
447
|
shownInSortBar: true,
|
|
448
|
+
shownInURL: true,
|
|
441
449
|
handledBySearchService: true,
|
|
442
450
|
searchServiceKey: 'downloads',
|
|
443
451
|
displayName: 'All-time views',
|
|
@@ -448,6 +456,7 @@ export const SORT_OPTIONS: Record<SortField, SortOption> = {
|
|
|
448
456
|
defaultSortDirection: 'desc',
|
|
449
457
|
canSetDirection: true,
|
|
450
458
|
shownInSortBar: true,
|
|
459
|
+
shownInURL: true,
|
|
451
460
|
handledBySearchService: true,
|
|
452
461
|
searchServiceKey: 'week',
|
|
453
462
|
displayName: 'Weekly views',
|
|
@@ -458,6 +467,7 @@ export const SORT_OPTIONS: Record<SortField, SortOption> = {
|
|
|
458
467
|
defaultSortDirection: 'asc',
|
|
459
468
|
canSetDirection: true,
|
|
460
469
|
shownInSortBar: true,
|
|
470
|
+
shownInURL: true,
|
|
461
471
|
handledBySearchService: true,
|
|
462
472
|
searchServiceKey: 'titleSorter',
|
|
463
473
|
displayName: 'Title',
|
|
@@ -468,6 +478,7 @@ export const SORT_OPTIONS: Record<SortField, SortOption> = {
|
|
|
468
478
|
defaultSortDirection: 'desc',
|
|
469
479
|
canSetDirection: true,
|
|
470
480
|
shownInSortBar: true,
|
|
481
|
+
shownInURL: true,
|
|
471
482
|
handledBySearchService: true,
|
|
472
483
|
searchServiceKey: 'date',
|
|
473
484
|
displayName: 'Date published',
|
|
@@ -478,6 +489,7 @@ export const SORT_OPTIONS: Record<SortField, SortOption> = {
|
|
|
478
489
|
defaultSortDirection: 'desc',
|
|
479
490
|
canSetDirection: true,
|
|
480
491
|
shownInSortBar: true,
|
|
492
|
+
shownInURL: true,
|
|
481
493
|
handledBySearchService: true,
|
|
482
494
|
searchServiceKey: 'publicdate',
|
|
483
495
|
displayName: 'Date archived',
|
|
@@ -488,6 +500,7 @@ export const SORT_OPTIONS: Record<SortField, SortOption> = {
|
|
|
488
500
|
defaultSortDirection: 'desc',
|
|
489
501
|
canSetDirection: true,
|
|
490
502
|
shownInSortBar: true,
|
|
503
|
+
shownInURL: true,
|
|
491
504
|
handledBySearchService: true,
|
|
492
505
|
searchServiceKey: 'reviewdate',
|
|
493
506
|
displayName: 'Date reviewed',
|
|
@@ -498,6 +511,7 @@ export const SORT_OPTIONS: Record<SortField, SortOption> = {
|
|
|
498
511
|
defaultSortDirection: 'desc',
|
|
499
512
|
canSetDirection: true,
|
|
500
513
|
shownInSortBar: true,
|
|
514
|
+
shownInURL: true,
|
|
501
515
|
handledBySearchService: true,
|
|
502
516
|
searchServiceKey: 'addeddate',
|
|
503
517
|
displayName: 'Date added',
|
|
@@ -508,6 +522,7 @@ export const SORT_OPTIONS: Record<SortField, SortOption> = {
|
|
|
508
522
|
defaultSortDirection: 'desc',
|
|
509
523
|
canSetDirection: false,
|
|
510
524
|
shownInSortBar: true, // But only when viewing fav-* collections
|
|
525
|
+
shownInURL: false,
|
|
511
526
|
handledBySearchService: false,
|
|
512
527
|
searchServiceKey: 'favoritedate',
|
|
513
528
|
displayName: 'Date favorited',
|
|
@@ -518,6 +533,7 @@ export const SORT_OPTIONS: Record<SortField, SortOption> = {
|
|
|
518
533
|
defaultSortDirection: 'asc',
|
|
519
534
|
canSetDirection: true,
|
|
520
535
|
shownInSortBar: true,
|
|
536
|
+
shownInURL: true,
|
|
521
537
|
handledBySearchService: true,
|
|
522
538
|
searchServiceKey: 'creatorSorter',
|
|
523
539
|
displayName: 'Creator',
|
|
@@ -147,6 +147,10 @@ export class RestorationStateHandler
|
|
|
147
147
|
const sortOption = SORT_OPTIONS[state.selectedSort];
|
|
148
148
|
let prefix = this.sortDirectionPrefix(state.sortDirection);
|
|
149
149
|
|
|
150
|
+
const isTVRelevanceSort =
|
|
151
|
+
state.searchType === SearchType.TV &&
|
|
152
|
+
state.selectedSort === SortField.relevance;
|
|
153
|
+
|
|
150
154
|
if (sortOption.field === SortField.unrecognized) {
|
|
151
155
|
// For unrecognized sorts, use the existing param, possibly updating its direction
|
|
152
156
|
const oldSortParam = oldParams.get('sort') ?? '';
|
|
@@ -161,7 +165,7 @@ export class RestorationStateHandler
|
|
|
161
165
|
} else {
|
|
162
166
|
newParams.set('sort', oldSortParam);
|
|
163
167
|
}
|
|
164
|
-
} else if (sortOption.
|
|
168
|
+
} else if (sortOption.shownInURL || isTVRelevanceSort) {
|
|
165
169
|
// Otherwise, use the canonical API form of the sort option
|
|
166
170
|
const canonicalApiSort = sortOption.urlNames[0];
|
|
167
171
|
newParams.set('sort', `${prefix}${canonicalApiSort}`);
|
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
import { css, html } from 'lit';
|
|
2
|
-
import { customElement } from 'lit/decorators.js';
|
|
3
|
-
import { msg } from '@lit/localize';
|
|
4
|
-
import { BaseTileComponent } from '../base-tile-component';
|
|
5
|
-
|
|
6
|
-
@customElement('tile-list-compact-header')
|
|
7
|
-
export class TileListCompactHeader extends BaseTileComponent {
|
|
8
|
-
/*
|
|
9
|
-
* Reactive properties inherited from BaseTileComponent:
|
|
10
|
-
* - model?: TileModel;
|
|
11
|
-
* - currentWidth?: number;
|
|
12
|
-
* - currentHeight?: number;
|
|
13
|
-
* - baseNavigationUrl?: string;
|
|
14
|
-
* - baseImageUrl?: string;
|
|
15
|
-
* - collectionPagePath?: string;
|
|
16
|
-
* - sortParam: SortParam | null = null;
|
|
17
|
-
* - creatorFilter?: string;
|
|
18
|
-
* - mobileBreakpoint?: number;
|
|
19
|
-
* - loggedIn = false;
|
|
20
|
-
* - suppressBlurring = false;
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
render() {
|
|
24
|
-
return html`
|
|
25
|
-
<div id="list-line-header" class="${this.classSize}">
|
|
26
|
-
<div id="thumb"></div>
|
|
27
|
-
<div id="title">${msg('Title')}</div>
|
|
28
|
-
<div id="creator">${msg('Creator')}</div>
|
|
29
|
-
<div id="date">
|
|
30
|
-
${this.displayValueProvider.dateLabel || msg('Published')}
|
|
31
|
-
</div>
|
|
32
|
-
<div id="icon">${msg('Type')}</div>
|
|
33
|
-
<div id="views">${
|
|
34
|
-
</div>
|
|
35
|
-
`;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
private get classSize(): string {
|
|
39
|
-
if (
|
|
40
|
-
this.mobileBreakpoint &&
|
|
41
|
-
this.currentWidth &&
|
|
42
|
-
this.currentWidth < this.mobileBreakpoint
|
|
43
|
-
) {
|
|
44
|
-
return 'mobile';
|
|
45
|
-
}
|
|
46
|
-
return 'desktop';
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
static get styles() {
|
|
50
|
-
return css`
|
|
51
|
-
html {
|
|
52
|
-
font-size: unset;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
div {
|
|
56
|
-
font-size: 14px;
|
|
57
|
-
font-weight: bold;
|
|
58
|
-
line-height: 20px;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.mobile #views {
|
|
62
|
-
display: none;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
#views {
|
|
66
|
-
text-align: right;
|
|
67
|
-
padding-right: 8px;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
#list-line-header {
|
|
71
|
-
display: grid;
|
|
72
|
-
column-gap: 10px;
|
|
73
|
-
align-items: flex-end;
|
|
74
|
-
padding-bottom: 2px;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
#list-line-header.mobile {
|
|
78
|
-
grid-template-columns: 36px 3fr 2fr 68px 35px;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
#list-line-header.desktop {
|
|
82
|
-
grid-template-columns: 51px 3fr 2fr 95px 30px
|
|
83
|
-
}
|
|
84
|
-
`;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
1
|
+
import { css, html } from 'lit';
|
|
2
|
+
import { customElement } from 'lit/decorators.js';
|
|
3
|
+
import { msg } from '@lit/localize';
|
|
4
|
+
import { BaseTileComponent } from '../base-tile-component';
|
|
5
|
+
|
|
6
|
+
@customElement('tile-list-compact-header')
|
|
7
|
+
export class TileListCompactHeader extends BaseTileComponent {
|
|
8
|
+
/*
|
|
9
|
+
* Reactive properties inherited from BaseTileComponent:
|
|
10
|
+
* - model?: TileModel;
|
|
11
|
+
* - currentWidth?: number;
|
|
12
|
+
* - currentHeight?: number;
|
|
13
|
+
* - baseNavigationUrl?: string;
|
|
14
|
+
* - baseImageUrl?: string;
|
|
15
|
+
* - collectionPagePath?: string;
|
|
16
|
+
* - sortParam: SortParam | null = null;
|
|
17
|
+
* - creatorFilter?: string;
|
|
18
|
+
* - mobileBreakpoint?: number;
|
|
19
|
+
* - loggedIn = false;
|
|
20
|
+
* - suppressBlurring = false;
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
render() {
|
|
24
|
+
return html`
|
|
25
|
+
<div id="list-line-header" class="${this.classSize}">
|
|
26
|
+
<div id="thumb"></div>
|
|
27
|
+
<div id="title">${msg('Title')}</div>
|
|
28
|
+
<div id="creator">${msg('Creator')}</div>
|
|
29
|
+
<div id="date">
|
|
30
|
+
${this.displayValueProvider.dateLabel || msg('Published')}
|
|
31
|
+
</div>
|
|
32
|
+
<div id="icon">${msg('Type')}</div>
|
|
33
|
+
<div id="views">${this.displayValueProvider.viewsLabel}</div>
|
|
34
|
+
</div>
|
|
35
|
+
`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private get classSize(): string {
|
|
39
|
+
if (
|
|
40
|
+
this.mobileBreakpoint &&
|
|
41
|
+
this.currentWidth &&
|
|
42
|
+
this.currentWidth < this.mobileBreakpoint
|
|
43
|
+
) {
|
|
44
|
+
return 'mobile';
|
|
45
|
+
}
|
|
46
|
+
return 'desktop';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static get styles() {
|
|
50
|
+
return css`
|
|
51
|
+
html {
|
|
52
|
+
font-size: unset;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
div {
|
|
56
|
+
font-size: 14px;
|
|
57
|
+
font-weight: bold;
|
|
58
|
+
line-height: 20px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.mobile #views {
|
|
62
|
+
display: none;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
#views {
|
|
66
|
+
text-align: right;
|
|
67
|
+
padding-right: 8px;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
#list-line-header {
|
|
71
|
+
display: grid;
|
|
72
|
+
column-gap: 10px;
|
|
73
|
+
align-items: flex-end;
|
|
74
|
+
padding-bottom: 2px;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
#list-line-header.mobile {
|
|
78
|
+
grid-template-columns: 36px 3fr 2fr 68px 35px;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#list-line-header.desktop {
|
|
82
|
+
grid-template-columns: 51px 3fr 2fr 95px 30px 115px;
|
|
83
|
+
}
|
|
84
|
+
`;
|
|
85
|
+
}
|
|
86
|
+
}
|