@internetarchive/collection-browser 1.8.0 → 1.9.0-alpha1
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/.editorconfig +29 -29
- package/.github/workflows/ci.yml +26 -26
- package/.github/workflows/gh-pages-main.yml +39 -39
- package/.github/workflows/npm-publish.yml +39 -39
- package/.github/workflows/pr-preview.yml +38 -38
- package/.husky/pre-commit +4 -4
- package/LICENSE +661 -661
- package/README.md +83 -83
- package/dist/index.d.ts +9 -9
- package/dist/index.js +9 -9
- package/dist/src/app-root.d.ts +54 -54
- package/dist/src/app-root.js +293 -293
- package/dist/src/assets/img/icons/arrow-left.d.ts +2 -2
- package/dist/src/assets/img/icons/arrow-left.js +2 -2
- package/dist/src/assets/img/icons/arrow-right.d.ts +2 -2
- package/dist/src/assets/img/icons/arrow-right.js +2 -2
- package/dist/src/assets/img/icons/chevron.d.ts +2 -2
- package/dist/src/assets/img/icons/chevron.js +2 -2
- package/dist/src/assets/img/icons/contract.d.ts +2 -2
- package/dist/src/assets/img/icons/contract.js +2 -2
- package/dist/src/assets/img/icons/empty-query.d.ts +2 -2
- package/dist/src/assets/img/icons/empty-query.js +2 -2
- package/dist/src/assets/img/icons/expand.d.ts +2 -2
- package/dist/src/assets/img/icons/expand.js +2 -2
- package/dist/src/assets/img/icons/eye-closed.d.ts +2 -2
- package/dist/src/assets/img/icons/eye-closed.js +2 -2
- package/dist/src/assets/img/icons/eye.d.ts +2 -2
- package/dist/src/assets/img/icons/eye.js +2 -2
- package/dist/src/assets/img/icons/favorite-filled.d.ts +1 -1
- package/dist/src/assets/img/icons/favorite-filled.js +2 -2
- package/dist/src/assets/img/icons/login-required.d.ts +1 -1
- package/dist/src/assets/img/icons/login-required.js +2 -2
- package/dist/src/assets/img/icons/mediatype/account.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/account.js +2 -2
- package/dist/src/assets/img/icons/mediatype/audio.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/audio.js +2 -2
- package/dist/src/assets/img/icons/mediatype/collection.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/collection.js +2 -2
- package/dist/src/assets/img/icons/mediatype/data.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/data.js +2 -2
- package/dist/src/assets/img/icons/mediatype/etree.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/etree.js +2 -2
- package/dist/src/assets/img/icons/mediatype/film.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/film.js +2 -2
- package/dist/src/assets/img/icons/mediatype/images.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/images.js +2 -2
- package/dist/src/assets/img/icons/mediatype/radio.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/radio.js +2 -2
- package/dist/src/assets/img/icons/mediatype/software.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/software.js +2 -2
- package/dist/src/assets/img/icons/mediatype/texts.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/texts.js +2 -2
- package/dist/src/assets/img/icons/mediatype/tv.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/tv.js +2 -2
- package/dist/src/assets/img/icons/mediatype/video.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/video.js +2 -2
- package/dist/src/assets/img/icons/mediatype/web.d.ts +1 -1
- package/dist/src/assets/img/icons/mediatype/web.js +2 -2
- package/dist/src/assets/img/icons/null-result.d.ts +2 -2
- package/dist/src/assets/img/icons/null-result.js +2 -2
- package/dist/src/assets/img/icons/restricted.d.ts +1 -1
- package/dist/src/assets/img/icons/restricted.js +2 -2
- package/dist/src/assets/img/icons/reviews.d.ts +1 -1
- package/dist/src/assets/img/icons/reviews.js +2 -2
- package/dist/src/assets/img/icons/upload.d.ts +1 -1
- package/dist/src/assets/img/icons/upload.js +2 -2
- package/dist/src/assets/img/icons/views.d.ts +1 -1
- package/dist/src/assets/img/icons/views.js +2 -2
- package/dist/src/circular-activity-indicator.d.ts +5 -5
- package/dist/src/circular-activity-indicator.js +17 -17
- package/dist/src/collection-browser.d.ts +469 -469
- package/dist/src/collection-browser.js +1666 -1653
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/facet-tombstone-row.d.ts +5 -5
- package/dist/src/collection-facets/facet-tombstone-row.js +15 -15
- package/dist/src/collection-facets/facets-template.d.ts +20 -20
- package/dist/src/collection-facets/facets-template.js +152 -152
- package/dist/src/collection-facets/more-facets-content.d.ts +77 -77
- package/dist/src/collection-facets/more-facets-content.js +359 -359
- package/dist/src/collection-facets/more-facets-pagination.d.ts +36 -36
- package/dist/src/collection-facets/more-facets-pagination.js +196 -196
- package/dist/src/collection-facets/toggle-switch.d.ts +41 -41
- package/dist/src/collection-facets/toggle-switch.js +94 -94
- package/dist/src/collection-facets.d.ts +99 -99
- package/dist/src/collection-facets.js +471 -471
- package/dist/src/empty-placeholder.d.ts +21 -21
- package/dist/src/empty-placeholder.js +69 -69
- package/dist/src/expanded-date-picker.d.ts +43 -43
- package/dist/src/expanded-date-picker.js +109 -109
- package/dist/src/language-code-handler/language-code-handler.d.ts +37 -37
- package/dist/src/language-code-handler/language-code-handler.js +26 -26
- package/dist/src/language-code-handler/language-code-mapping.d.ts +1 -1
- package/dist/src/language-code-handler/language-code-mapping.js +562 -562
- package/dist/src/mediatype/mediatype-config.d.ts +3 -3
- package/dist/src/mediatype/mediatype-config.js +85 -85
- package/dist/src/models.d.ts +162 -149
- package/dist/src/models.js +256 -195
- package/dist/src/models.js.map +1 -1
- package/dist/src/restoration-state-handler.d.ts +70 -63
- package/dist/src/restoration-state-handler.js +355 -326
- package/dist/src/restoration-state-handler.js.map +1 -1
- package/dist/src/sort-filter-bar/alpha-bar-tooltip.d.ts +6 -6
- package/dist/src/sort-filter-bar/alpha-bar-tooltip.js +24 -24
- package/dist/src/sort-filter-bar/alpha-bar.d.ts +21 -21
- package/dist/src/sort-filter-bar/alpha-bar.js +128 -128
- package/dist/src/sort-filter-bar/img/compact.d.ts +1 -1
- package/dist/src/sort-filter-bar/img/compact.js +2 -2
- package/dist/src/sort-filter-bar/img/list.d.ts +1 -1
- package/dist/src/sort-filter-bar/img/list.js +2 -2
- package/dist/src/sort-filter-bar/img/sort-toggle-disabled.d.ts +1 -1
- package/dist/src/sort-filter-bar/img/sort-toggle-disabled.js +2 -2
- package/dist/src/sort-filter-bar/img/sort-toggle-down.d.ts +1 -1
- package/dist/src/sort-filter-bar/img/sort-toggle-down.js +2 -2
- package/dist/src/sort-filter-bar/img/sort-toggle-up.d.ts +1 -1
- package/dist/src/sort-filter-bar/img/sort-toggle-up.js +2 -2
- package/dist/src/sort-filter-bar/img/sort-triangle.d.ts +1 -1
- package/dist/src/sort-filter-bar/img/sort-triangle.js +2 -2
- package/dist/src/sort-filter-bar/img/tile.d.ts +1 -1
- package/dist/src/sort-filter-bar/img/tile.js +2 -2
- package/dist/src/sort-filter-bar/sort-filter-bar.d.ts +201 -199
- package/dist/src/sort-filter-bar/sort-filter-bar.js +622 -617
- package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
- package/dist/src/styles/item-image-styles.d.ts +8 -8
- package/dist/src/styles/item-image-styles.js +9 -9
- package/dist/src/styles/sr-only.d.ts +1 -1
- package/dist/src/styles/sr-only.js +2 -2
- package/dist/src/tiles/base-tile-component.d.ts +18 -18
- package/dist/src/tiles/base-tile-component.js +59 -59
- package/dist/src/tiles/collection-browser-loading-tile.d.ts +5 -5
- package/dist/src/tiles/collection-browser-loading-tile.js +15 -15
- package/dist/src/tiles/grid/account-tile.d.ts +18 -18
- package/dist/src/tiles/grid/account-tile.js +72 -72
- package/dist/src/tiles/grid/collection-tile.d.ts +15 -15
- package/dist/src/tiles/grid/collection-tile.js +80 -80
- package/dist/src/tiles/grid/item-tile.d.ts +27 -27
- package/dist/src/tiles/grid/item-tile.js +134 -134
- package/dist/src/tiles/grid/styles/tile-grid-shared-styles.d.ts +1 -1
- package/dist/src/tiles/grid/styles/tile-grid-shared-styles.js +8 -8
- package/dist/src/tiles/grid/tile-stats.d.ts +11 -11
- package/dist/src/tiles/grid/tile-stats.js +48 -48
- package/dist/src/tiles/hover/hover-pane-controller.d.ts +219 -219
- package/dist/src/tiles/hover/hover-pane-controller.js +352 -352
- package/dist/src/tiles/hover/tile-hover-pane.d.ts +15 -15
- package/dist/src/tiles/hover/tile-hover-pane.js +38 -38
- package/dist/src/tiles/image-block.d.ts +17 -17
- package/dist/src/tiles/image-block.js +72 -72
- package/dist/src/tiles/item-image.d.ts +35 -35
- package/dist/src/tiles/item-image.js +117 -117
- package/dist/src/tiles/list/tile-list-compact-header.d.ts +6 -6
- package/dist/src/tiles/list/tile-list-compact-header.js +38 -38
- package/dist/src/tiles/list/tile-list-compact.d.ts +15 -15
- package/dist/src/tiles/list/tile-list-compact.js +114 -114
- package/dist/src/tiles/list/tile-list.d.ts +46 -46
- package/dist/src/tiles/list/tile-list.js +298 -298
- package/dist/src/tiles/mediatype-icon.d.ts +9 -9
- package/dist/src/tiles/mediatype-icon.js +47 -47
- package/dist/src/tiles/overlay/icon-overlay.d.ts +10 -10
- package/dist/src/tiles/overlay/icon-overlay.js +40 -40
- package/dist/src/tiles/overlay/icon-text-overlay.d.ts +9 -9
- package/dist/src/tiles/overlay/icon-text-overlay.js +38 -38
- package/dist/src/tiles/overlay/text-overlay.d.ts +10 -10
- package/dist/src/tiles/overlay/text-overlay.js +42 -42
- package/dist/src/tiles/text-snippet-block.d.ts +27 -27
- package/dist/src/tiles/text-snippet-block.js +73 -73
- package/dist/src/tiles/tile-dispatcher.d.ts +50 -50
- package/dist/src/tiles/tile-dispatcher.js +185 -185
- package/dist/src/tiles/tile-display-value-provider.d.ts +43 -43
- package/dist/src/tiles/tile-display-value-provider.js +80 -80
- package/dist/src/utils/analytics-events.d.ts +24 -24
- package/dist/src/utils/analytics-events.js +26 -26
- package/dist/src/utils/array-equals.d.ts +4 -4
- package/dist/src/utils/array-equals.js +10 -10
- package/dist/src/utils/format-count.d.ts +7 -7
- package/dist/src/utils/format-count.js +76 -76
- package/dist/src/utils/format-date.d.ts +2 -2
- package/dist/src/utils/format-date.js +25 -25
- package/dist/src/utils/format-unit-size.d.ts +2 -2
- package/dist/src/utils/format-unit-size.js +33 -33
- package/dist/src/utils/local-date-from-utc.d.ts +9 -9
- package/dist/src/utils/local-date-from-utc.js +15 -15
- package/dist/src/utils/sha1.d.ts +2 -2
- package/dist/src/utils/sha1.js +8 -8
- package/dist/test/collection-browser.test.d.ts +1 -1
- package/dist/test/collection-browser.test.js +808 -808
- package/dist/test/collection-facets/facets-template.test.d.ts +1 -1
- package/dist/test/collection-facets/facets-template.test.js +134 -134
- package/dist/test/collection-facets/more-facets-content.test.d.ts +1 -1
- package/dist/test/collection-facets/more-facets-content.test.js +133 -133
- package/dist/test/collection-facets/more-facets-pagination.test.d.ts +1 -1
- package/dist/test/collection-facets/more-facets-pagination.test.js +117 -117
- package/dist/test/collection-facets/toggle-switch.test.d.ts +1 -1
- package/dist/test/collection-facets/toggle-switch.test.js +73 -73
- package/dist/test/collection-facets.test.d.ts +2 -2
- package/dist/test/collection-facets.test.js +645 -645
- package/dist/test/empty-placeholder.test.d.ts +1 -1
- package/dist/test/empty-placeholder.test.js +56 -56
- package/dist/test/expanded-date-picker.test.d.ts +1 -1
- package/dist/test/expanded-date-picker.test.js +95 -95
- package/dist/test/icon-overlay.test.d.ts +1 -1
- package/dist/test/icon-overlay.test.js +24 -24
- package/dist/test/image-block.test.d.ts +1 -1
- package/dist/test/image-block.test.js +48 -48
- package/dist/test/item-image.test.d.ts +1 -1
- package/dist/test/item-image.test.js +84 -84
- package/dist/test/mediatype-config.test.d.ts +1 -1
- package/dist/test/mediatype-config.test.js +16 -16
- package/dist/test/mocks/mock-analytics-handler.d.ts +10 -10
- package/dist/test/mocks/mock-analytics-handler.js +15 -15
- package/dist/test/mocks/mock-collection-name-cache.d.ts +9 -9
- package/dist/test/mocks/mock-collection-name-cache.js +17 -17
- package/dist/test/mocks/mock-search-responses.d.ts +19 -19
- package/dist/test/mocks/mock-search-responses.js +623 -623
- package/dist/test/mocks/mock-search-service.d.ts +15 -15
- package/dist/test/mocks/mock-search-service.js +48 -48
- package/dist/test/restoration-state-handler.test.d.ts +1 -1
- package/dist/test/restoration-state-handler.test.js +270 -218
- package/dist/test/restoration-state-handler.test.js.map +1 -1
- package/dist/test/sort-filter-bar/alpha-bar-tooltip.test.d.ts +1 -1
- package/dist/test/sort-filter-bar/alpha-bar-tooltip.test.js +12 -12
- package/dist/test/sort-filter-bar/alpha-bar.test.d.ts +1 -1
- package/dist/test/sort-filter-bar/alpha-bar.test.js +73 -73
- package/dist/test/sort-filter-bar/sort-filter-bar.test.d.ts +1 -1
- package/dist/test/sort-filter-bar/sort-filter-bar.test.js +378 -378
- package/dist/test/text-overlay.test.d.ts +1 -1
- package/dist/test/text-overlay.test.js +48 -48
- package/dist/test/text-snippet-block.test.d.ts +1 -1
- package/dist/test/text-snippet-block.test.js +57 -57
- package/dist/test/tile-stats.test.d.ts +1 -1
- package/dist/test/tile-stats.test.js +33 -33
- package/dist/test/tiles/grid/account-tile.test.d.ts +1 -1
- package/dist/test/tiles/grid/account-tile.test.js +76 -76
- package/dist/test/tiles/grid/collection-tile.test.d.ts +1 -1
- package/dist/test/tiles/grid/collection-tile.test.js +73 -73
- package/dist/test/tiles/grid/item-tile.test.d.ts +1 -1
- package/dist/test/tiles/grid/item-tile.test.js +254 -254
- package/dist/test/tiles/hover/hover-pane-controller.test.d.ts +1 -1
- package/dist/test/tiles/hover/hover-pane-controller.test.js +257 -257
- package/dist/test/tiles/hover/tile-hover-pane.test.d.ts +1 -1
- package/dist/test/tiles/hover/tile-hover-pane.test.js +13 -13
- package/dist/test/tiles/list/tile-list-compact.test.d.ts +1 -1
- package/dist/test/tiles/list/tile-list-compact.test.js +143 -143
- package/dist/test/tiles/list/tile-list.test.d.ts +1 -1
- package/dist/test/tiles/list/tile-list.test.js +242 -242
- package/dist/test/tiles/tile-dispatcher.test.d.ts +1 -1
- package/dist/test/tiles/tile-dispatcher.test.js +67 -67
- package/dist/test/tiles/tile-display-value-provider.test.d.ts +1 -1
- package/dist/test/tiles/tile-display-value-provider.test.js +141 -141
- package/dist/test/utils/array-equals.test.d.ts +1 -1
- package/dist/test/utils/array-equals.test.js +26 -26
- package/dist/test/utils/format-count.test.d.ts +1 -1
- package/dist/test/utils/format-count.test.js +23 -23
- package/dist/test/utils/format-date.test.d.ts +1 -1
- package/dist/test/utils/format-date.test.js +17 -17
- package/dist/test/utils/format-unit-size.test.d.ts +1 -1
- package/dist/test/utils/format-unit-size.test.js +17 -17
- package/dist/test/utils/local-date-from-utc.test.d.ts +1 -1
- package/dist/test/utils/local-date-from-utc.test.js +26 -26
- package/local.archive.org.cert +86 -86
- package/local.archive.org.key +27 -27
- package/package.json +1 -1
- package/renovate.json +6 -6
- package/src/collection-browser.ts +24 -8
- package/src/models.ts +193 -109
- package/src/restoration-state-handler.ts +66 -40
- package/src/sort-filter-bar/sort-filter-bar.ts +34 -27
- package/test/restoration-state-handler.test.ts +68 -1
- package/tsconfig.json +21 -21
- package/web-dev-server.config.mjs +30 -30
- package/web-test-runner.config.mjs +41 -41
package/src/models.ts
CHANGED
|
@@ -56,6 +56,7 @@ export type CollectionBrowserContext = 'collection' | 'search';
|
|
|
56
56
|
*/
|
|
57
57
|
export enum SortField {
|
|
58
58
|
'default' = 'default',
|
|
59
|
+
'unrecognized' = 'unrecognized',
|
|
59
60
|
'relevance' = 'relevance',
|
|
60
61
|
'alltimeview' = 'alltimeview',
|
|
61
62
|
'weeklyview' = 'weeklyview',
|
|
@@ -67,120 +68,203 @@ export enum SortField {
|
|
|
67
68
|
'creator' = 'creator',
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
export const SortFieldToMetadataField: {
|
|
122
|
-
[key in SortField]: MetadataSortField | null;
|
|
123
|
-
} = {
|
|
124
|
-
default: null,
|
|
125
|
-
relevance: null,
|
|
126
|
-
alltimeview: 'downloads',
|
|
127
|
-
weeklyview: 'week',
|
|
128
|
-
title: 'titleSorter',
|
|
129
|
-
date: 'date',
|
|
130
|
-
datearchived: 'publicdate',
|
|
131
|
-
datereviewed: 'reviewdate',
|
|
132
|
-
dateadded: 'addeddate',
|
|
133
|
-
creator: 'creatorSorter',
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Maps the Metadata field to the corresponding SortField field in the API.
|
|
138
|
-
*/
|
|
139
|
-
export const MetadataFieldToSortField: {
|
|
140
|
-
[key in MetadataSortField]: SortField;
|
|
141
|
-
} = {
|
|
142
|
-
week: SortField.weeklyview,
|
|
143
|
-
downloads: SortField.alltimeview,
|
|
144
|
-
titleSorter: SortField.title,
|
|
145
|
-
date: SortField.date,
|
|
146
|
-
publicdate: SortField.datearchived,
|
|
147
|
-
reviewdate: SortField.datereviewed,
|
|
148
|
-
addeddate: SortField.dateadded,
|
|
149
|
-
creatorSorter: SortField.creator,
|
|
150
|
-
};
|
|
71
|
+
export interface SortOption {
|
|
72
|
+
/**
|
|
73
|
+
* The SortField enum member corresponding to this option.
|
|
74
|
+
*/
|
|
75
|
+
field: SortField;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The default sort direction to apply when this sort option is first selected.
|
|
79
|
+
*/
|
|
80
|
+
defaultSortDirection: SortDirection | null;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Whether this sort option allows its sort direction to be changed from the default.
|
|
84
|
+
*/
|
|
85
|
+
canSetDirection: boolean;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Whether this sort option may appear in the sort bar.
|
|
89
|
+
*/
|
|
90
|
+
shownInSortBar: boolean;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Whether this sort option should be saved to the URL.
|
|
94
|
+
* If false, then no `sort` param will be added to the URL when this sort option
|
|
95
|
+
* is selected.
|
|
96
|
+
*/
|
|
97
|
+
shownInURL: boolean;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Whether this sort option is passed to the search service.
|
|
101
|
+
* If false, then no sort param will be passed to the search service at all when
|
|
102
|
+
* this sort option is selected.
|
|
103
|
+
*/
|
|
104
|
+
handledBySearchService: boolean;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The string identifying this sort field to the search service & backend API.
|
|
108
|
+
*/
|
|
109
|
+
searchServiceKey?: string;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The human-readable name to use for this option in the sort bar (if applicable).
|
|
113
|
+
*/
|
|
114
|
+
displayName: string;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* A list of URL param keys that should be mapped to this sort option.
|
|
118
|
+
* E.g., both `title` and `titleSorter` in the URL map to the `SortField.title` option.
|
|
119
|
+
*/
|
|
120
|
+
urlNames: (string | null | undefined)[];
|
|
121
|
+
}
|
|
151
122
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
123
|
+
export const SORT_OPTIONS: Record<SortField, SortOption> = {
|
|
124
|
+
// Default sort is the case where the user has not specified a sort option via the sort bar or URL.
|
|
125
|
+
// In these cases, we defer to whatever sort the backend chooses.
|
|
126
|
+
// For the search page, the default is always relevance sort.
|
|
127
|
+
// For collection pages _without a query_, the default is usually weekly views, but this can be
|
|
128
|
+
// overridden by the collection's `sort-by` metadata entry. If a query _is_ specified, then the
|
|
129
|
+
// default is again relevance sort.
|
|
130
|
+
[SortField.default]: {
|
|
131
|
+
field: SortField.default,
|
|
132
|
+
defaultSortDirection: null,
|
|
133
|
+
canSetDirection: false,
|
|
134
|
+
shownInSortBar: false,
|
|
135
|
+
shownInURL: false,
|
|
136
|
+
handledBySearchService: false, // We rely on the PPS default sort handling in these cases
|
|
137
|
+
displayName: '',
|
|
138
|
+
urlNames: ['', null, undefined], // Empty or nullish sort params result in default sorting
|
|
139
|
+
},
|
|
140
|
+
// Unrecognized sort is the case where the user has specified a sort in the URL, but it is not
|
|
141
|
+
// one of the options listed in this map. We still want these unrecognized sorts to be applied
|
|
142
|
+
// when searching, but they are not displayed in the sort bar and we do not actively manage
|
|
143
|
+
// their URL param beyond flipping the direction as needed.
|
|
144
|
+
[SortField.unrecognized]: {
|
|
145
|
+
field: SortField.unrecognized,
|
|
146
|
+
defaultSortDirection: null,
|
|
147
|
+
canSetDirection: true,
|
|
148
|
+
shownInSortBar: false,
|
|
149
|
+
shownInURL: false,
|
|
150
|
+
handledBySearchService: true, // The unrecognized sort param is passed along as-is
|
|
151
|
+
displayName: '',
|
|
152
|
+
urlNames: [],
|
|
153
|
+
},
|
|
154
|
+
// Relevance sort is unique in that it does not produce a URL param when it is set.
|
|
155
|
+
// It is only available when there is a user-specified query that relevancy can be scored against.
|
|
156
|
+
// Therefore, it does not appear as a sort bar option when browsing a collection with no query set.
|
|
157
|
+
[SortField.relevance]: {
|
|
158
|
+
field: SortField.relevance,
|
|
159
|
+
defaultSortDirection: null,
|
|
160
|
+
canSetDirection: false,
|
|
161
|
+
shownInSortBar: true,
|
|
162
|
+
shownInURL: false,
|
|
163
|
+
handledBySearchService: false,
|
|
164
|
+
displayName: 'Relevance',
|
|
165
|
+
urlNames: ['_score'],
|
|
166
|
+
},
|
|
167
|
+
[SortField.alltimeview]: {
|
|
168
|
+
field: SortField.alltimeview,
|
|
169
|
+
defaultSortDirection: 'desc',
|
|
170
|
+
canSetDirection: true,
|
|
171
|
+
shownInSortBar: true,
|
|
172
|
+
shownInURL: true,
|
|
173
|
+
handledBySearchService: true,
|
|
174
|
+
searchServiceKey: 'downloads',
|
|
175
|
+
displayName: 'All-time views',
|
|
176
|
+
urlNames: ['downloads'],
|
|
177
|
+
},
|
|
178
|
+
[SortField.weeklyview]: {
|
|
179
|
+
field: SortField.weeklyview,
|
|
180
|
+
defaultSortDirection: 'desc',
|
|
181
|
+
canSetDirection: true,
|
|
182
|
+
shownInSortBar: true,
|
|
183
|
+
shownInURL: true,
|
|
184
|
+
handledBySearchService: true,
|
|
185
|
+
searchServiceKey: 'week',
|
|
186
|
+
displayName: 'Weekly views',
|
|
187
|
+
urlNames: ['week'],
|
|
188
|
+
},
|
|
189
|
+
[SortField.title]: {
|
|
190
|
+
field: SortField.title,
|
|
191
|
+
defaultSortDirection: 'asc',
|
|
192
|
+
canSetDirection: true,
|
|
193
|
+
shownInSortBar: true,
|
|
194
|
+
shownInURL: true,
|
|
195
|
+
handledBySearchService: true,
|
|
196
|
+
searchServiceKey: 'titleSorter',
|
|
197
|
+
displayName: 'Title',
|
|
198
|
+
urlNames: ['title', 'titleSorter'],
|
|
199
|
+
},
|
|
200
|
+
[SortField.date]: {
|
|
201
|
+
field: SortField.date,
|
|
202
|
+
defaultSortDirection: 'desc',
|
|
203
|
+
canSetDirection: true,
|
|
204
|
+
shownInSortBar: true,
|
|
205
|
+
shownInURL: true,
|
|
206
|
+
handledBySearchService: true,
|
|
207
|
+
searchServiceKey: 'date',
|
|
208
|
+
displayName: 'Date published',
|
|
209
|
+
urlNames: ['date'],
|
|
210
|
+
},
|
|
211
|
+
[SortField.datearchived]: {
|
|
212
|
+
field: SortField.datearchived,
|
|
213
|
+
defaultSortDirection: 'desc',
|
|
214
|
+
canSetDirection: true,
|
|
215
|
+
shownInSortBar: true,
|
|
216
|
+
shownInURL: true,
|
|
217
|
+
handledBySearchService: true,
|
|
218
|
+
searchServiceKey: 'publicdate',
|
|
219
|
+
displayName: 'Date archived',
|
|
220
|
+
urlNames: ['publicdate'],
|
|
221
|
+
},
|
|
222
|
+
[SortField.datereviewed]: {
|
|
223
|
+
field: SortField.datereviewed,
|
|
224
|
+
defaultSortDirection: 'desc',
|
|
225
|
+
canSetDirection: true,
|
|
226
|
+
shownInSortBar: true,
|
|
227
|
+
shownInURL: true,
|
|
228
|
+
handledBySearchService: true,
|
|
229
|
+
searchServiceKey: 'reviewdate',
|
|
230
|
+
displayName: 'Date reviewed',
|
|
231
|
+
urlNames: ['reviewdate'],
|
|
232
|
+
},
|
|
233
|
+
[SortField.dateadded]: {
|
|
234
|
+
field: SortField.dateadded,
|
|
235
|
+
defaultSortDirection: 'desc',
|
|
236
|
+
canSetDirection: true,
|
|
237
|
+
shownInSortBar: true,
|
|
238
|
+
shownInURL: true,
|
|
239
|
+
handledBySearchService: true,
|
|
240
|
+
searchServiceKey: 'addeddate',
|
|
241
|
+
displayName: 'Date added',
|
|
242
|
+
urlNames: ['addeddate'],
|
|
243
|
+
},
|
|
244
|
+
[SortField.creator]: {
|
|
245
|
+
field: SortField.creator,
|
|
246
|
+
defaultSortDirection: 'asc',
|
|
247
|
+
canSetDirection: true,
|
|
248
|
+
shownInSortBar: true,
|
|
249
|
+
shownInURL: true,
|
|
250
|
+
handledBySearchService: true,
|
|
251
|
+
searchServiceKey: 'creatorSorter',
|
|
252
|
+
displayName: 'Creator',
|
|
253
|
+
urlNames: ['creator', 'creatorSorter'],
|
|
254
|
+
},
|
|
166
255
|
};
|
|
167
256
|
|
|
168
257
|
/**
|
|
169
|
-
*
|
|
170
|
-
*
|
|
258
|
+
* Returns the SortOption corresponding to the given API sort name, or
|
|
259
|
+
* the "unrecognized" SortOption if none matches.
|
|
171
260
|
*/
|
|
172
|
-
export
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
reviewdate: SortField.datereviewed,
|
|
180
|
-
addeddate: SortField.dateadded,
|
|
181
|
-
creator: SortField.creator,
|
|
182
|
-
creatorSorter: SortField.creator,
|
|
183
|
-
};
|
|
261
|
+
export function sortOptionFromAPIString(sortName?: string | null): SortOption {
|
|
262
|
+
return (
|
|
263
|
+
Object.values(SORT_OPTIONS).find(opt =>
|
|
264
|
+
opt.urlNames.some(name => sortName === name)
|
|
265
|
+
) ?? SORT_OPTIONS[SortField.unrecognized]
|
|
266
|
+
);
|
|
267
|
+
}
|
|
184
268
|
|
|
185
269
|
/** A union of the fields that permit prefix filtering (e.g., alphabetical filtering) */
|
|
186
270
|
export type PrefixFilterType = 'title' | 'creator';
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SearchType,
|
|
3
|
-
SortDirection,
|
|
4
|
-
SortParam,
|
|
5
|
-
} from '@internetarchive/search-service';
|
|
1
|
+
import { SearchType, SortDirection } from '@internetarchive/search-service';
|
|
6
2
|
import { getCookie, setCookie } from 'typescript-cookie';
|
|
7
3
|
import {
|
|
8
|
-
MetadataSortField,
|
|
9
4
|
FacetOption,
|
|
10
5
|
CollectionBrowserContext,
|
|
11
6
|
CollectionDisplayMode,
|
|
@@ -13,17 +8,15 @@ import {
|
|
|
13
8
|
SortField,
|
|
14
9
|
FacetBucket,
|
|
15
10
|
FacetState,
|
|
16
|
-
URLFieldToSortField,
|
|
17
|
-
URLSortField,
|
|
18
11
|
getDefaultSelectedFacets,
|
|
19
|
-
|
|
12
|
+
sortOptionFromAPIString,
|
|
13
|
+
SORT_OPTIONS,
|
|
20
14
|
} from './models';
|
|
21
15
|
import { arrayEquals } from './utils/array-equals';
|
|
22
16
|
|
|
23
17
|
export interface RestorationState {
|
|
24
18
|
displayMode?: CollectionDisplayMode;
|
|
25
19
|
searchType?: SearchType;
|
|
26
|
-
sortParam?: SortParam;
|
|
27
20
|
selectedSort?: SortField;
|
|
28
21
|
sortDirection?: SortDirection;
|
|
29
22
|
selectedFacets: SelectedFacets;
|
|
@@ -120,11 +113,29 @@ export class RestorationStateHandler
|
|
|
120
113
|
}
|
|
121
114
|
}
|
|
122
115
|
|
|
123
|
-
if (state.
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
116
|
+
if (state.selectedSort) {
|
|
117
|
+
const sortOption = SORT_OPTIONS[state.selectedSort];
|
|
118
|
+
let prefix = this.sortDirectionPrefix(state.sortDirection);
|
|
119
|
+
|
|
120
|
+
if (sortOption.field === SortField.unrecognized) {
|
|
121
|
+
// For unrecognized sorts, use the existing param, possibly updating its direction
|
|
122
|
+
const oldSortParam = oldParams.get('sort') ?? '';
|
|
123
|
+
const { field, direction } =
|
|
124
|
+
this.getSortFieldAndDirection(oldSortParam);
|
|
125
|
+
|
|
126
|
+
// Use the state-specified direction if available, or extract one from the param if not
|
|
127
|
+
if (!state.sortDirection) prefix = this.sortDirectionPrefix(direction);
|
|
128
|
+
|
|
129
|
+
if (field) {
|
|
130
|
+
newParams.set('sort', `${prefix}${field}`);
|
|
131
|
+
} else {
|
|
132
|
+
newParams.set('sort', oldSortParam);
|
|
133
|
+
}
|
|
134
|
+
} else if (sortOption.shownInURL) {
|
|
135
|
+
// Otherwise, use the canonical API form of the sort option
|
|
136
|
+
const canonicalApiSort = sortOption.urlNames[0];
|
|
137
|
+
newParams.set('sort', `${prefix}${canonicalApiSort}`);
|
|
138
|
+
}
|
|
128
139
|
}
|
|
129
140
|
|
|
130
141
|
if (state.selectedFacets) {
|
|
@@ -197,7 +208,7 @@ export class RestorationStateHandler
|
|
|
197
208
|
query: state.baseQuery,
|
|
198
209
|
searchType: state.searchType,
|
|
199
210
|
page: state.currentPage,
|
|
200
|
-
sort: state.
|
|
211
|
+
sort: { field: state.selectedSort, direction: state.sortDirection },
|
|
201
212
|
minDate: state.minSelectedDate,
|
|
202
213
|
maxDate: state.maxSelectedDate,
|
|
203
214
|
facets: state.selectedFacets,
|
|
@@ -261,29 +272,13 @@ export class RestorationStateHandler
|
|
|
261
272
|
}
|
|
262
273
|
|
|
263
274
|
if (sortQuery) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
restorationState.selectedSort = metadataField;
|
|
272
|
-
}
|
|
273
|
-
if (direction === 'desc' || direction === 'asc') {
|
|
274
|
-
restorationState.sortDirection = direction as SortDirection;
|
|
275
|
-
}
|
|
276
|
-
} else {
|
|
277
|
-
const direction = sortQuery.startsWith('-') ? 'desc' : 'asc';
|
|
278
|
-
const field = sortQuery.startsWith('-')
|
|
279
|
-
? sortQuery.slice(1)
|
|
280
|
-
: sortQuery;
|
|
281
|
-
|
|
282
|
-
const metadataField = URLFieldToSortField[field as URLSortField];
|
|
283
|
-
if (metadataField) {
|
|
284
|
-
restorationState.selectedSort = metadataField;
|
|
285
|
-
restorationState.sortDirection = direction as SortDirection;
|
|
286
|
-
}
|
|
275
|
+
const { field, direction } = this.getSortFieldAndDirection(sortQuery);
|
|
276
|
+
|
|
277
|
+
const sortOption = sortOptionFromAPIString(field);
|
|
278
|
+
restorationState.selectedSort = sortOption.field;
|
|
279
|
+
|
|
280
|
+
if (['asc', 'desc'].includes(direction)) {
|
|
281
|
+
restorationState.sortDirection = direction as SortDirection;
|
|
287
282
|
}
|
|
288
283
|
}
|
|
289
284
|
|
|
@@ -296,6 +291,13 @@ export class RestorationStateHandler
|
|
|
296
291
|
// which we want to normalize to 'creator', 'language', etc. if redirected here.
|
|
297
292
|
field = field.replace(/Sorter$/, '');
|
|
298
293
|
|
|
294
|
+
// Legacy search also allowed a form of negative faceting like `and[]=-collection:foo`
|
|
295
|
+
// which we want to normalize to a not[] param instead
|
|
296
|
+
if (field.startsWith('-')) {
|
|
297
|
+
facetNots.push(and.slice(1));
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
|
|
299
301
|
switch (field) {
|
|
300
302
|
case 'year': {
|
|
301
303
|
const [minDate, maxDate] = value.split(' TO ');
|
|
@@ -354,7 +356,31 @@ export class RestorationStateHandler
|
|
|
354
356
|
return restorationState;
|
|
355
357
|
}
|
|
356
358
|
|
|
357
|
-
|
|
359
|
+
/**
|
|
360
|
+
* Converts a URL sort param into a field/direction pair, if possible.
|
|
361
|
+
* Either or both may be undefined if the param is not in a recognized format.
|
|
362
|
+
*/
|
|
363
|
+
private getSortFieldAndDirection(sortParam: string) {
|
|
364
|
+
// check for two different sort formats: `date desc` and `-date`
|
|
365
|
+
const hasSpace = sortParam.indexOf(' ') > -1;
|
|
366
|
+
let field;
|
|
367
|
+
let direction;
|
|
368
|
+
if (hasSpace) {
|
|
369
|
+
[field, direction] = sortParam.split(' ');
|
|
370
|
+
} else {
|
|
371
|
+
field = sortParam.startsWith('-') ? sortParam.slice(1) : sortParam;
|
|
372
|
+
direction = sortParam.startsWith('-') ? 'desc' : 'asc';
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
return { field, direction };
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/** Returns the `-` prefix for `desc` sort, or the empty string otherwise. */
|
|
379
|
+
private sortDirectionPrefix(sortDirection?: string) {
|
|
380
|
+
return sortDirection === 'desc' ? '-' : '';
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/** Remove optional opening and closing quotes from a string */
|
|
358
384
|
private stripQuotes(value: string): string {
|
|
359
385
|
if (value.startsWith('"') && value.endsWith('"')) {
|
|
360
386
|
return value.substring(1, value.length - 1);
|
|
@@ -16,11 +16,10 @@ import type { IaDropdown, optionInterface } from '@internetarchive/ia-dropdown';
|
|
|
16
16
|
import type { SortDirection } from '@internetarchive/search-service';
|
|
17
17
|
import {
|
|
18
18
|
CollectionDisplayMode,
|
|
19
|
-
DefaultSortDirection,
|
|
20
19
|
PrefixFilterCounts,
|
|
21
20
|
PrefixFilterType,
|
|
21
|
+
SORT_OPTIONS,
|
|
22
22
|
SortField,
|
|
23
|
-
SortFieldDisplayName,
|
|
24
23
|
} from '../models';
|
|
25
24
|
import './alpha-bar';
|
|
26
25
|
|
|
@@ -153,7 +152,8 @@ export class SortFilterBar
|
|
|
153
152
|
}
|
|
154
153
|
|
|
155
154
|
if (changed.has('selectedSort') && this.sortDirection === null) {
|
|
156
|
-
|
|
155
|
+
const sortOption = SORT_OPTIONS[this.finalizedSortField];
|
|
156
|
+
this.sortDirection = sortOption.defaultSortDirection;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
if (changed.has('selectedTitleFilter') && this.selectedTitleFilter) {
|
|
@@ -274,7 +274,7 @@ export class SortFilterBar
|
|
|
274
274
|
return html`
|
|
275
275
|
<button
|
|
276
276
|
class="sort-direction-selector"
|
|
277
|
-
?disabled=${this.
|
|
277
|
+
?disabled=${!this.canChangeSortDirection}
|
|
278
278
|
@click=${this.handleSortDirectionClicked}
|
|
279
279
|
>
|
|
280
280
|
<span class="sr-only">${srLabel}</span>
|
|
@@ -285,8 +285,8 @@ export class SortFilterBar
|
|
|
285
285
|
|
|
286
286
|
/** Template to render the sort direction button's icon in the correct current state */
|
|
287
287
|
private get sortDirectionIcon(): TemplateResult {
|
|
288
|
-
//
|
|
289
|
-
if (this.
|
|
288
|
+
// Show a fully disabled icon for sort options without direction support
|
|
289
|
+
if (!this.canChangeSortDirection) {
|
|
290
290
|
return html`<div class="sort-direction-icon">${sortDisabledIcon}</div>`;
|
|
291
291
|
}
|
|
292
292
|
|
|
@@ -354,9 +354,9 @@ export class SortFilterBar
|
|
|
354
354
|
|
|
355
355
|
/** The template to render all the sort options in mobile view */
|
|
356
356
|
private get mobileSortSelectorTemplate() {
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
(field !== SortField.relevance
|
|
357
|
+
const displayedOptions = Object.values(SORT_OPTIONS)
|
|
358
|
+
.filter(opt => opt.shownInSortBar)
|
|
359
|
+
.filter(opt => this.showRelevance || opt.field !== SortField.relevance);
|
|
360
360
|
|
|
361
361
|
return html`
|
|
362
362
|
<div
|
|
@@ -364,13 +364,13 @@ export class SortFilterBar
|
|
|
364
364
|
class=${this.mobileSelectorVisible ? 'visible' : 'hidden'}
|
|
365
365
|
>
|
|
366
366
|
${this.getSortDropdown({
|
|
367
|
-
displayName: html`${
|
|
368
|
-
|
|
367
|
+
displayName: html`${SORT_OPTIONS[this.finalizedSortField]
|
|
368
|
+
.displayName}`,
|
|
369
369
|
id: 'mobile-dropdown',
|
|
370
370
|
selected: true,
|
|
371
|
-
dropdownOptions:
|
|
372
|
-
.
|
|
373
|
-
|
|
371
|
+
dropdownOptions: displayedOptions.map(opt =>
|
|
372
|
+
this.getDropdownOption(opt.field)
|
|
373
|
+
),
|
|
374
374
|
selectedOption: this.finalizedSortField,
|
|
375
375
|
onOptionSelected: this.mobileSortChanged,
|
|
376
376
|
onDropdownClick: () => {
|
|
@@ -408,7 +408,8 @@ export class SortFilterBar
|
|
|
408
408
|
): TemplateResult {
|
|
409
409
|
const isSelected =
|
|
410
410
|
options?.selected ?? this.finalizedSortField === sortField;
|
|
411
|
-
const displayName =
|
|
411
|
+
const displayName =
|
|
412
|
+
options?.displayName ?? SORT_OPTIONS[sortField].displayName;
|
|
412
413
|
return html`
|
|
413
414
|
<button
|
|
414
415
|
class=${isSelected ? 'selected' : nothing}
|
|
@@ -488,7 +489,7 @@ export class SortFilterBar
|
|
|
488
489
|
},
|
|
489
490
|
label: html`
|
|
490
491
|
<span class="dropdown-option-label">
|
|
491
|
-
${
|
|
492
|
+
${SORT_OPTIONS[sortField].displayName}
|
|
492
493
|
</span>
|
|
493
494
|
`,
|
|
494
495
|
};
|
|
@@ -692,7 +693,8 @@ export class SortFilterBar
|
|
|
692
693
|
private setSelectedSort(sort: SortField) {
|
|
693
694
|
this.selectedSort = sort;
|
|
694
695
|
// Apply this field's default sort direction
|
|
695
|
-
|
|
696
|
+
const sortOption = SORT_OPTIONS[sort];
|
|
697
|
+
this.sortDirection = sortOption.defaultSortDirection;
|
|
696
698
|
this.emitSortChangedEvent();
|
|
697
699
|
}
|
|
698
700
|
|
|
@@ -710,6 +712,11 @@ export class SortFilterBar
|
|
|
710
712
|
: this.sortDirection;
|
|
711
713
|
}
|
|
712
714
|
|
|
715
|
+
/** Whether the sort direction button should be enabled for the current sort */
|
|
716
|
+
private get canChangeSortDirection(): boolean {
|
|
717
|
+
return SORT_OPTIONS[this.finalizedSortField].canSetDirection;
|
|
718
|
+
}
|
|
719
|
+
|
|
713
720
|
/**
|
|
714
721
|
* There are four date sort options.
|
|
715
722
|
*
|
|
@@ -757,11 +764,11 @@ export class SortFilterBar
|
|
|
757
764
|
* @memberof SortFilterBar
|
|
758
765
|
*/
|
|
759
766
|
private get dateSortField(): string {
|
|
760
|
-
const
|
|
761
|
-
const
|
|
762
|
-
?
|
|
763
|
-
:
|
|
764
|
-
return
|
|
767
|
+
const defaultDateSort = SORT_OPTIONS[SortField.date];
|
|
768
|
+
const currentDateSort = this.dateOptionSelected
|
|
769
|
+
? SORT_OPTIONS[this.finalizedSortField] ?? defaultDateSort
|
|
770
|
+
: defaultDateSort;
|
|
771
|
+
return currentDateSort.displayName;
|
|
765
772
|
}
|
|
766
773
|
|
|
767
774
|
/**
|
|
@@ -773,11 +780,11 @@ export class SortFilterBar
|
|
|
773
780
|
* @memberof SortFilterBar
|
|
774
781
|
*/
|
|
775
782
|
private get viewSortField(): string {
|
|
776
|
-
const
|
|
777
|
-
const
|
|
778
|
-
?
|
|
779
|
-
:
|
|
780
|
-
return
|
|
783
|
+
const defaultViewSort = SORT_OPTIONS[SortField.weeklyview];
|
|
784
|
+
const currentViewSort = this.viewOptionSelected
|
|
785
|
+
? SORT_OPTIONS[this.finalizedSortField] ?? defaultViewSort
|
|
786
|
+
: defaultViewSort;
|
|
787
|
+
return currentViewSort.displayName;
|
|
781
788
|
}
|
|
782
789
|
|
|
783
790
|
private get titleSelectorBar() {
|