@internetarchive/collection-browser 0.3.4 → 0.3.5
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/dist/src/app-root.d.ts +4 -0
- package/dist/src/app-root.js +99 -53
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/collection-browser.d.ts +1 -2
- package/dist/src/collection-browser.js +21 -49
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/facet-tombstone-row.d.ts +5 -0
- package/dist/src/collection-facets/facet-tombstone-row.js +43 -0
- package/dist/src/collection-facets/facet-tombstone-row.js.map +1 -0
- package/dist/src/collection-facets/facets-template.js +5 -3
- package/dist/src/collection-facets/facets-template.js.map +1 -1
- package/dist/src/collection-facets.d.ts +2 -0
- package/dist/src/collection-facets.js +44 -18
- package/dist/src/collection-facets.js.map +1 -1
- package/dist/src/models.d.ts +1 -0
- package/dist/src/models.js.map +1 -1
- package/dist/src/restoration-state-handler.d.ts +2 -1
- package/dist/src/restoration-state-handler.js +10 -0
- package/dist/src/restoration-state-handler.js.map +1 -1
- package/dist/src/tiles/grid/tile-stats.js +11 -5
- package/dist/src/tiles/grid/tile-stats.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact.d.ts +1 -0
- package/dist/src/tiles/list/tile-list-compact.js +8 -4
- package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
- package/dist/src/tiles/list/tile-list.js +5 -2
- package/dist/src/tiles/list/tile-list.js.map +1 -1
- package/dist/src/tiles/mediatype-icon.js +2 -0
- package/dist/src/tiles/mediatype-icon.js.map +1 -1
- package/dist/test/collection-browser.test.js +125 -3
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/collection-facets/facets-template.test.js +4 -4
- package/dist/test/collection-facets/facets-template.test.js.map +1 -1
- package/dist/test/mocks/mock-search-responses.d.ts +3 -0
- package/dist/test/mocks/mock-search-responses.js +95 -0
- package/dist/test/mocks/mock-search-responses.js.map +1 -1
- package/dist/test/mocks/mock-search-service.js +15 -8
- package/dist/test/mocks/mock-search-service.js.map +1 -1
- package/dist/test/restoration-state-handler.test.js +9 -0
- package/dist/test/restoration-state-handler.test.js.map +1 -1
- package/dist/test/tiles/list/tile-list-compact.test.js +99 -0
- package/dist/test/tiles/list/tile-list-compact.test.js.map +1 -1
- package/dist/test/tiles/list/tile-list.test.js +32 -0
- package/dist/test/tiles/list/tile-list.test.js.map +1 -1
- package/package.json +3 -3
- package/src/app-root.ts +104 -55
- package/src/collection-browser.ts +26 -48
- package/src/collection-facets/facet-tombstone-row.ts +40 -0
- package/src/collection-facets/facets-template.ts +5 -3
- package/src/collection-facets.ts +49 -18
- package/src/models.ts +1 -0
- package/src/restoration-state-handler.ts +19 -1
- package/src/tiles/grid/tile-stats.ts +18 -5
- package/src/tiles/list/tile-list-compact.ts +7 -3
- package/src/tiles/list/tile-list.ts +6 -1
- package/src/tiles/mediatype-icon.ts +2 -0
- package/test/collection-browser.test.ts +169 -3
- package/test/collection-facets/facets-template.test.ts +5 -3
- package/test/mocks/mock-search-responses.ts +107 -0
- package/test/mocks/mock-search-service.ts +16 -8
- package/test/restoration-state-handler.test.ts +12 -0
- package/test/tiles/list/tile-list-compact.test.ts +110 -0
- package/test/tiles/list/tile-list.test.ts +36 -0
package/src/app-root.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
} from '@internetarchive/analytics-manager';
|
|
6
6
|
import {
|
|
7
7
|
SearchService,
|
|
8
|
+
SearchServiceInterface,
|
|
8
9
|
SearchType,
|
|
9
10
|
StringField,
|
|
10
11
|
} from '@internetarchive/search-service';
|
|
@@ -22,7 +23,8 @@ import '../src/collection-browser';
|
|
|
22
23
|
|
|
23
24
|
@customElement('app-root')
|
|
24
25
|
export class AppRoot extends LitElement {
|
|
25
|
-
private searchService =
|
|
26
|
+
private searchService: SearchServiceInterface =
|
|
27
|
+
this.initSearchServiceFromUrlParams();
|
|
26
28
|
|
|
27
29
|
private resizeObserver = new SharedResizeObserver();
|
|
28
30
|
|
|
@@ -73,6 +75,15 @@ export class AppRoot extends LitElement {
|
|
|
73
75
|
this.analyticsManager?.sendEventNoSampling(ae);
|
|
74
76
|
}
|
|
75
77
|
|
|
78
|
+
private initSearchServiceFromUrlParams() {
|
|
79
|
+
const params = new URL(window.location.href).searchParams;
|
|
80
|
+
return new SearchService({
|
|
81
|
+
baseUrl: params.get('search_base_url') ?? undefined,
|
|
82
|
+
servicePath: params.get('search_service_path') ?? undefined,
|
|
83
|
+
debuggingEnabled: !!params.get('debugging') ?? undefined,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
76
87
|
private searchPressed(e: Event) {
|
|
77
88
|
e.preventDefault();
|
|
78
89
|
this.searchQuery = this.baseQueryField.value;
|
|
@@ -122,23 +133,28 @@ export class AppRoot extends LitElement {
|
|
|
122
133
|
|
|
123
134
|
<div id="search-types">
|
|
124
135
|
Search type:
|
|
125
|
-
<
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
136
|
+
<span class="search-type">
|
|
137
|
+
<input
|
|
138
|
+
type="radio"
|
|
139
|
+
id="metadata-search"
|
|
140
|
+
name="search-type"
|
|
141
|
+
value="metadata"
|
|
142
|
+
?checked=${this.searchType === SearchType.METADATA}
|
|
143
|
+
@click=${this.searchTypeSelected}
|
|
144
|
+
/>
|
|
145
|
+
<label for="metadata-search">Metadata</label>
|
|
146
|
+
</span>
|
|
147
|
+
<span class="search-type">
|
|
148
|
+
<input
|
|
149
|
+
type="radio"
|
|
150
|
+
id="fulltext-search"
|
|
151
|
+
name="search-type"
|
|
152
|
+
value="fulltext"
|
|
153
|
+
?checked=${this.searchType === SearchType.FULLTEXT}
|
|
154
|
+
@click=${this.searchTypeSelected}
|
|
155
|
+
/>
|
|
156
|
+
<label for="fulltext-search">Full text</label>
|
|
157
|
+
</span>
|
|
142
158
|
</div>
|
|
143
159
|
|
|
144
160
|
<div id="toggle-controls">
|
|
@@ -176,7 +192,7 @@ export class AppRoot extends LitElement {
|
|
|
176
192
|
<div id="cell-controls" class="hidden">
|
|
177
193
|
<div id="cell-size-control">
|
|
178
194
|
<div>
|
|
179
|
-
<label for="cell-width-slider">
|
|
195
|
+
<label for="cell-width-slider">Min cell width:</label>
|
|
180
196
|
<input
|
|
181
197
|
type="range"
|
|
182
198
|
min="10"
|
|
@@ -201,40 +217,6 @@ export class AppRoot extends LitElement {
|
|
|
201
217
|
/>
|
|
202
218
|
<span>${this.cellHeight}rem</span>
|
|
203
219
|
</div>
|
|
204
|
-
<div>
|
|
205
|
-
<label for="show-outline-check">Show outlines:</label>
|
|
206
|
-
<input
|
|
207
|
-
type="checkbox"
|
|
208
|
-
id="show-outline-check"
|
|
209
|
-
@click=${this.outlineChanged}
|
|
210
|
-
/>
|
|
211
|
-
</div>
|
|
212
|
-
<div>
|
|
213
|
-
<label for="show-facet-group-outline-check"
|
|
214
|
-
>Show Facet Group Outlines:</label
|
|
215
|
-
>
|
|
216
|
-
<input
|
|
217
|
-
type="checkbox"
|
|
218
|
-
id="show-facet-group-outline-check"
|
|
219
|
-
@click=${this.toggleFacetGroupOutline}
|
|
220
|
-
/>
|
|
221
|
-
</div>
|
|
222
|
-
<div>
|
|
223
|
-
<label for="simulate-login">Simulate Login:</label>
|
|
224
|
-
<input
|
|
225
|
-
type="checkbox"
|
|
226
|
-
id="simulate-login"
|
|
227
|
-
@click=${this.loginChanged}
|
|
228
|
-
/>
|
|
229
|
-
</div>
|
|
230
|
-
<div>
|
|
231
|
-
<label for="show-dummy-snippets">Show dummy snippets:</label>
|
|
232
|
-
<input
|
|
233
|
-
type="checkbox"
|
|
234
|
-
id="show-dummy-snippets"
|
|
235
|
-
@click=${this.snippetsChanged}
|
|
236
|
-
/>
|
|
237
|
-
</div>
|
|
238
220
|
</div>
|
|
239
221
|
<div id="cell-gap-control">
|
|
240
222
|
<div>
|
|
@@ -265,6 +247,42 @@ export class AppRoot extends LitElement {
|
|
|
265
247
|
</div>
|
|
266
248
|
</div>
|
|
267
249
|
</div>
|
|
250
|
+
<div id="checkbox-controls">
|
|
251
|
+
<div class="checkbox-control">
|
|
252
|
+
<input
|
|
253
|
+
type="checkbox"
|
|
254
|
+
id="show-outline-check"
|
|
255
|
+
@click=${this.outlineChanged}
|
|
256
|
+
/>
|
|
257
|
+
<label for="show-outline-check">Show cell outlines</label>
|
|
258
|
+
</div>
|
|
259
|
+
<div class="checkbox-control">
|
|
260
|
+
<input
|
|
261
|
+
type="checkbox"
|
|
262
|
+
id="show-facet-group-outline-check"
|
|
263
|
+
@click=${this.toggleFacetGroupOutline}
|
|
264
|
+
/>
|
|
265
|
+
<label for="show-facet-group-outline-check">
|
|
266
|
+
Show facet group outlines
|
|
267
|
+
</label>
|
|
268
|
+
</div>
|
|
269
|
+
<div class="checkbox-control">
|
|
270
|
+
<input
|
|
271
|
+
type="checkbox"
|
|
272
|
+
id="simulate-login"
|
|
273
|
+
@click=${this.loginChanged}
|
|
274
|
+
/>
|
|
275
|
+
<label for="simulate-login">Simulate login</label>
|
|
276
|
+
</div>
|
|
277
|
+
<div class="checkbox-control">
|
|
278
|
+
<input
|
|
279
|
+
type="checkbox"
|
|
280
|
+
id="show-dummy-snippets"
|
|
281
|
+
@click=${this.snippetsChanged}
|
|
282
|
+
/>
|
|
283
|
+
<label for="show-dummy-snippets">Show dummy snippets</label>
|
|
284
|
+
</div>
|
|
285
|
+
</div>
|
|
268
286
|
</div>
|
|
269
287
|
|
|
270
288
|
<div id="collection-browser-container">
|
|
@@ -281,6 +299,7 @@ export class AppRoot extends LitElement {
|
|
|
281
299
|
.analyticsHandler=${this.analyticsHandler}
|
|
282
300
|
@visiblePageChanged=${this.visiblePageChanged}
|
|
283
301
|
@baseQueryChanged=${this.baseQueryChanged}
|
|
302
|
+
@searchTypeChanged=${this.searchTypeChanged}
|
|
284
303
|
>
|
|
285
304
|
</collection-browser>
|
|
286
305
|
</div>
|
|
@@ -288,11 +307,17 @@ export class AppRoot extends LitElement {
|
|
|
288
307
|
`;
|
|
289
308
|
}
|
|
290
309
|
|
|
291
|
-
private baseQueryChanged(e: CustomEvent<{ baseQuery?: string }>) {
|
|
310
|
+
private baseQueryChanged(e: CustomEvent<{ baseQuery?: string }>): void {
|
|
292
311
|
this.searchQuery = e.detail.baseQuery;
|
|
293
312
|
}
|
|
294
313
|
|
|
295
|
-
|
|
314
|
+
/** Handler for search type changes coming from collection browser */
|
|
315
|
+
private searchTypeChanged(e: CustomEvent<SearchType>): void {
|
|
316
|
+
this.searchType = e.detail;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/** Handler for user input selecting a search type */
|
|
320
|
+
private searchTypeSelected(e: Event) {
|
|
296
321
|
const target = e.target as HTMLInputElement;
|
|
297
322
|
this.searchType =
|
|
298
323
|
target.value === 'fulltext' ? SearchType.FULLTEXT : SearchType.METADATA;
|
|
@@ -494,8 +519,17 @@ export class AppRoot extends LitElement {
|
|
|
494
519
|
display: flex;
|
|
495
520
|
}
|
|
496
521
|
|
|
522
|
+
#search-and-page-inputs > form {
|
|
523
|
+
margin-right: 1rem;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
.search-type {
|
|
527
|
+
margin-right: 1rem;
|
|
528
|
+
}
|
|
529
|
+
|
|
497
530
|
#cell-controls {
|
|
498
531
|
display: flex;
|
|
532
|
+
flex-wrap: wrap;
|
|
499
533
|
}
|
|
500
534
|
|
|
501
535
|
#cell-controls label {
|
|
@@ -503,10 +537,25 @@ export class AppRoot extends LitElement {
|
|
|
503
537
|
width: 10rem;
|
|
504
538
|
}
|
|
505
539
|
|
|
540
|
+
#cell-size-control,
|
|
541
|
+
#cell-gap-control {
|
|
542
|
+
flex-basis: calc(50% - 1rem);
|
|
543
|
+
flex-grow: 1;
|
|
544
|
+
}
|
|
545
|
+
|
|
506
546
|
#cell-gap-control {
|
|
507
547
|
margin-left: 1rem;
|
|
508
548
|
}
|
|
509
549
|
|
|
550
|
+
#checkbox-controls {
|
|
551
|
+
padding-top: 0.5rem;
|
|
552
|
+
flex-wrap: wrap;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
.checkbox-control {
|
|
556
|
+
flex-basis: 50%;
|
|
557
|
+
}
|
|
558
|
+
|
|
510
559
|
#last-event {
|
|
511
560
|
background-color: aliceblue;
|
|
512
561
|
padding: 5px;
|
|
@@ -155,8 +155,6 @@ export class CollectionBrowser
|
|
|
155
155
|
|
|
156
156
|
@state() private facetsLoading = false;
|
|
157
157
|
|
|
158
|
-
@state() private lendingFacetLoading = false;
|
|
159
|
-
|
|
160
158
|
@state() private fullYearAggregationLoading = false;
|
|
161
159
|
|
|
162
160
|
@state() private aggregations?: Record<string, Aggregation>;
|
|
@@ -306,7 +304,10 @@ export class CollectionBrowser
|
|
|
306
304
|
this.placeholderType = 'empty-query';
|
|
307
305
|
}
|
|
308
306
|
|
|
309
|
-
if (
|
|
307
|
+
if (
|
|
308
|
+
(!this.searchResultsLoading && this.totalResults === 0) ||
|
|
309
|
+
!this.searchService
|
|
310
|
+
) {
|
|
310
311
|
this.placeholderType = 'null-result';
|
|
311
312
|
}
|
|
312
313
|
}
|
|
@@ -348,7 +349,6 @@ export class CollectionBrowser
|
|
|
348
349
|
</div>
|
|
349
350
|
</div>
|
|
350
351
|
<div id="right-column" class="column">
|
|
351
|
-
${this.searchResultsLoading ? this.loadingTemplate : nothing}
|
|
352
352
|
${this.sortFilterBarTemplate}
|
|
353
353
|
${this.displayMode === `list-compact`
|
|
354
354
|
? this.listHeaderTemplate
|
|
@@ -499,11 +499,7 @@ export class CollectionBrowser
|
|
|
499
499
|
}
|
|
500
500
|
|
|
501
501
|
private get facetDataLoading(): boolean {
|
|
502
|
-
return
|
|
503
|
-
this.facetsLoading ||
|
|
504
|
-
this.lendingFacetLoading ||
|
|
505
|
-
this.fullYearAggregationLoading
|
|
506
|
-
);
|
|
502
|
+
return this.facetsLoading || this.fullYearAggregationLoading;
|
|
507
503
|
}
|
|
508
504
|
|
|
509
505
|
private get mobileFacetsTemplate() {
|
|
@@ -530,7 +526,6 @@ export class CollectionBrowser
|
|
|
530
526
|
|
|
531
527
|
private get facetsTemplate() {
|
|
532
528
|
return html`
|
|
533
|
-
${this.facetsLoading ? this.loadingTemplate : nothing}
|
|
534
529
|
<collection-facets
|
|
535
530
|
@facetsChanged=${this.facetsChanged}
|
|
536
531
|
@histogramDateRangeUpdated=${this.histogramDateRangeUpdated}
|
|
@@ -630,6 +625,9 @@ export class CollectionBrowser
|
|
|
630
625
|
if (changed.has('baseQuery')) {
|
|
631
626
|
this.emitBaseQueryChanged();
|
|
632
627
|
}
|
|
628
|
+
if (changed.has('searchType')) {
|
|
629
|
+
this.emitSearchTypeChanged();
|
|
630
|
+
}
|
|
633
631
|
if (changed.has('currentPage') || changed.has('displayMode')) {
|
|
634
632
|
this.persistState();
|
|
635
633
|
}
|
|
@@ -705,6 +703,14 @@ export class CollectionBrowser
|
|
|
705
703
|
);
|
|
706
704
|
}
|
|
707
705
|
|
|
706
|
+
private emitSearchTypeChanged() {
|
|
707
|
+
this.dispatchEvent(
|
|
708
|
+
new CustomEvent<SearchType>('searchTypeChanged', {
|
|
709
|
+
detail: this.searchType,
|
|
710
|
+
})
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
|
|
708
714
|
private disconnectResizeObserver(
|
|
709
715
|
resizeObserver: SharedResizeObserverInterface
|
|
710
716
|
) {
|
|
@@ -775,20 +781,15 @@ export class CollectionBrowser
|
|
|
775
781
|
this.initialQueryChangeHappened = true;
|
|
776
782
|
// if the query changed as part of a window.history pop event, we don't want to
|
|
777
783
|
// persist the state because it overwrites the forward history
|
|
784
|
+
|
|
778
785
|
if (!this.historyPopOccurred) {
|
|
779
786
|
this.persistState();
|
|
780
787
|
this.historyPopOccurred = false;
|
|
781
788
|
}
|
|
782
789
|
|
|
783
|
-
// Ensure lending aggregations don't carry over to non-metadata searches
|
|
784
|
-
if (this.searchType !== SearchType.METADATA) {
|
|
785
|
-
delete this.aggregations?.lending;
|
|
786
|
-
}
|
|
787
|
-
|
|
788
790
|
await Promise.all([
|
|
789
791
|
this.doInitialPageFetch(),
|
|
790
792
|
this.fetchFacets(),
|
|
791
|
-
this.fetchLendingFacet(),
|
|
792
793
|
this.fetchFullYearHistogram(),
|
|
793
794
|
]);
|
|
794
795
|
}
|
|
@@ -810,6 +811,8 @@ export class CollectionBrowser
|
|
|
810
811
|
private restoreState() {
|
|
811
812
|
const restorationState = this.restorationStateHandler.getRestorationState();
|
|
812
813
|
this.displayMode = restorationState.displayMode;
|
|
814
|
+
if (restorationState.searchType != null)
|
|
815
|
+
this.searchType = restorationState.searchType;
|
|
813
816
|
this.selectedSort = restorationState.selectedSort ?? SortField.relevance;
|
|
814
817
|
this.sortDirection = restorationState.sortDirection ?? null;
|
|
815
818
|
this.selectedTitleFilter = restorationState.selectedTitleFilter ?? null;
|
|
@@ -831,6 +834,7 @@ export class CollectionBrowser
|
|
|
831
834
|
private persistState() {
|
|
832
835
|
const restorationState: RestorationState = {
|
|
833
836
|
displayMode: this.displayMode,
|
|
837
|
+
searchType: this.searchType,
|
|
834
838
|
sortParam: this.sortParam ?? undefined,
|
|
835
839
|
selectedSort: this.selectedSort,
|
|
836
840
|
sortDirection: this.sortDirection ?? undefined,
|
|
@@ -957,34 +961,7 @@ export class CollectionBrowser
|
|
|
957
961
|
const results = await this.searchService?.search(params, this.searchType);
|
|
958
962
|
this.facetsLoading = false;
|
|
959
963
|
|
|
960
|
-
this.aggregations =
|
|
961
|
-
...this.aggregations,
|
|
962
|
-
...results?.success?.response.aggregations,
|
|
963
|
-
};
|
|
964
|
-
}
|
|
965
|
-
|
|
966
|
-
private async fetchLendingFacet() {
|
|
967
|
-
// Only retrieve lending facet for metadata searches
|
|
968
|
-
if (this.searchType !== SearchType.METADATA) return;
|
|
969
|
-
if (!this.fullQuery) return;
|
|
970
|
-
|
|
971
|
-
const params: SearchParams = {
|
|
972
|
-
query: this.fullQuery,
|
|
973
|
-
rows: 0,
|
|
974
|
-
aggregations: {
|
|
975
|
-
simpleParams: ['lending___status'],
|
|
976
|
-
},
|
|
977
|
-
aggregationsSize: 10, // Larger size to ensure we get all possible statuses
|
|
978
|
-
};
|
|
979
|
-
|
|
980
|
-
this.lendingFacetLoading = true;
|
|
981
|
-
const results = await this.searchService?.search(params, this.searchType);
|
|
982
|
-
this.lendingFacetLoading = false;
|
|
983
|
-
|
|
984
|
-
this.aggregations = {
|
|
985
|
-
...this.aggregations,
|
|
986
|
-
...results?.success?.response.aggregations,
|
|
987
|
-
};
|
|
964
|
+
this.aggregations = results?.success?.response.aggregations;
|
|
988
965
|
}
|
|
989
966
|
|
|
990
967
|
/**
|
|
@@ -1037,7 +1014,8 @@ export class CollectionBrowser
|
|
|
1037
1014
|
this.fullYearAggregationLoading = false;
|
|
1038
1015
|
|
|
1039
1016
|
this.fullYearsHistogramAggregation =
|
|
1040
|
-
results?.success?.response?.aggregations?.year_histogram
|
|
1017
|
+
results?.success?.response?.aggregations?.year_histogram ??
|
|
1018
|
+
results?.success?.response?.aggregations?.['year-histogram']; // Temp fix until PPS FTS key is fixed to use underscore
|
|
1041
1019
|
}
|
|
1042
1020
|
|
|
1043
1021
|
private scrollToPage(pageNumber: number) {
|
|
@@ -1233,6 +1211,7 @@ export class CollectionBrowser
|
|
|
1233
1211
|
),
|
|
1234
1212
|
volume: result.volume?.value,
|
|
1235
1213
|
viewCount: result.downloads?.value ?? 0,
|
|
1214
|
+
weeklyViewCount: result.week?.value,
|
|
1236
1215
|
loginRequired,
|
|
1237
1216
|
contentWarning,
|
|
1238
1217
|
});
|
|
@@ -1423,7 +1402,7 @@ export class CollectionBrowser
|
|
|
1423
1402
|
|
|
1424
1403
|
#results-total {
|
|
1425
1404
|
display: flex;
|
|
1426
|
-
align-items:
|
|
1405
|
+
align-items: baseline;
|
|
1427
1406
|
margin-bottom: 5rem;
|
|
1428
1407
|
}
|
|
1429
1408
|
|
|
@@ -1438,9 +1417,8 @@ export class CollectionBrowser
|
|
|
1438
1417
|
}
|
|
1439
1418
|
|
|
1440
1419
|
#big-results-label {
|
|
1441
|
-
font-size:
|
|
1420
|
+
font-size: 1.4rem;
|
|
1442
1421
|
font-weight: 200;
|
|
1443
|
-
text-transform: uppercase;
|
|
1444
1422
|
}
|
|
1445
1423
|
|
|
1446
1424
|
#list-header {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { css, html, LitElement, CSSResultGroup } from 'lit';
|
|
2
|
+
import { customElement } from 'lit/decorators.js';
|
|
3
|
+
|
|
4
|
+
@customElement('facet-tombstone-row')
|
|
5
|
+
export class FacetTombstoneRow extends LitElement {
|
|
6
|
+
render() {
|
|
7
|
+
return html`
|
|
8
|
+
<div id="row">
|
|
9
|
+
<input type="checkbox" disabled />
|
|
10
|
+
<div class="tombstone-line"></div>
|
|
11
|
+
<div class="tombstone-line"></div>
|
|
12
|
+
</div>
|
|
13
|
+
`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static get styles(): CSSResultGroup {
|
|
17
|
+
return css`
|
|
18
|
+
#row {
|
|
19
|
+
display: grid;
|
|
20
|
+
grid-template-columns: 15px 1fr 36px;
|
|
21
|
+
grid-gap: 9px 6px;
|
|
22
|
+
align-items: center;
|
|
23
|
+
margin: 2.5px auto;
|
|
24
|
+
border: 1px solid transparent;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.tombstone-line {
|
|
28
|
+
background: #ddd;
|
|
29
|
+
height: 6px;
|
|
30
|
+
border-radius: 50px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
input[type='checkbox'] {
|
|
34
|
+
width: 15px;
|
|
35
|
+
height: 15px;
|
|
36
|
+
margin: 0;
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -168,14 +168,16 @@ export class FacetsTemplate extends LitElement {
|
|
|
168
168
|
<span class="eye-closed">${eyeClosedIcon}</span>
|
|
169
169
|
</label>
|
|
170
170
|
</div>
|
|
171
|
-
<
|
|
171
|
+
<label
|
|
172
172
|
for=${showOnlyCheckboxId}
|
|
173
173
|
class="facet-info-display"
|
|
174
174
|
title=${onlyShowText}
|
|
175
175
|
>
|
|
176
176
|
<div class="facet-title">${bucketTextDisplay}</div>
|
|
177
|
-
<div class="facet-count"
|
|
178
|
-
|
|
177
|
+
<div class="facet-count">
|
|
178
|
+
${bucket.count.toLocaleString()}
|
|
179
|
+
</div>
|
|
180
|
+
</label>
|
|
179
181
|
</div>
|
|
180
182
|
`;
|
|
181
183
|
}
|
package/src/collection-facets.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
TemplateResult,
|
|
9
9
|
} from 'lit';
|
|
10
10
|
import { customElement, property, state } from 'lit/decorators.js';
|
|
11
|
+
import { map } from 'lit/directives/map.js';
|
|
11
12
|
import type {
|
|
12
13
|
Aggregation,
|
|
13
14
|
Bucket,
|
|
@@ -39,6 +40,7 @@ import {
|
|
|
39
40
|
import type { LanguageCodeHandlerInterface } from './language-code-handler/language-code-handler';
|
|
40
41
|
import './collection-facets/more-facets-content';
|
|
41
42
|
import './collection-facets/facets-template';
|
|
43
|
+
import './collection-facets/facet-tombstone-row';
|
|
42
44
|
import {
|
|
43
45
|
analyticsActions,
|
|
44
46
|
analyticsCategories,
|
|
@@ -111,7 +113,9 @@ export class CollectionFacets extends LitElement {
|
|
|
111
113
|
render() {
|
|
112
114
|
return html`
|
|
113
115
|
<div id="container" class="${this.facetsLoading ? 'loading' : ''}">
|
|
114
|
-
${this.showHistogramDatePicker &&
|
|
116
|
+
${(this.showHistogramDatePicker &&
|
|
117
|
+
this.fullYearsHistogramAggregation) ||
|
|
118
|
+
this.fullYearAggregationLoading
|
|
115
119
|
? html`
|
|
116
120
|
<div class="facet-group">
|
|
117
121
|
<h1>Year Published <feature-feedback></feature-feedback></h1>
|
|
@@ -146,19 +150,21 @@ export class CollectionFacets extends LitElement {
|
|
|
146
150
|
|
|
147
151
|
private get histogramTemplate() {
|
|
148
152
|
const { fullYearsHistogramAggregation } = this;
|
|
149
|
-
return
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
153
|
+
return this.fullYearAggregationLoading
|
|
154
|
+
? html`<div class="histogram-loading-indicator">…</div>` // Ellipsis block
|
|
155
|
+
: html`
|
|
156
|
+
<histogram-date-range
|
|
157
|
+
.minDate=${fullYearsHistogramAggregation?.first_bucket_key}
|
|
158
|
+
.maxDate=${fullYearsHistogramAggregation?.last_bucket_key}
|
|
159
|
+
.minSelectedDate=${this.minSelectedDate}
|
|
160
|
+
.maxSelectedDate=${this.maxSelectedDate}
|
|
161
|
+
.updateDelay=${100}
|
|
162
|
+
missingDataMessage="..."
|
|
163
|
+
.width=${180}
|
|
164
|
+
.bins=${fullYearsHistogramAggregation?.buckets as number[]}
|
|
165
|
+
@histogramDateRangeUpdated=${this.histogramDateRangeUpdated}
|
|
166
|
+
></histogram-date-range>
|
|
167
|
+
`;
|
|
162
168
|
}
|
|
163
169
|
|
|
164
170
|
private histogramDateRangeUpdated(
|
|
@@ -366,7 +372,8 @@ export class CollectionFacets extends LitElement {
|
|
|
366
372
|
private getFacetGroupTemplate(
|
|
367
373
|
facetGroup: FacetGroup
|
|
368
374
|
): TemplateResult | typeof nothing {
|
|
369
|
-
if (facetGroup.buckets.length === 0) return nothing;
|
|
375
|
+
if (!this.facetsLoading && facetGroup.buckets.length === 0) return nothing;
|
|
376
|
+
|
|
370
377
|
const { key } = facetGroup;
|
|
371
378
|
const isOpen = this.openFacets[key];
|
|
372
379
|
const collapser = html`
|
|
@@ -390,16 +397,32 @@ export class CollectionFacets extends LitElement {
|
|
|
390
397
|
>
|
|
391
398
|
${this.collapsableFacets ? collapser : nothing} ${facetGroup.title}
|
|
392
399
|
</h1>
|
|
393
|
-
${this.
|
|
400
|
+
${this.facetsLoading
|
|
401
|
+
? nothing
|
|
402
|
+
: this.moreFacetsSortingIcon(facetGroup)}
|
|
394
403
|
</div>
|
|
395
404
|
<div class="facet-group-content ${isOpen ? 'open' : ''}">
|
|
396
|
-
${this.
|
|
397
|
-
|
|
405
|
+
${this.facetsLoading
|
|
406
|
+
? this.getTombstoneFacetGroupTemplate()
|
|
407
|
+
: html`
|
|
408
|
+
${this.getFacetTemplate(facetGroup)}
|
|
409
|
+
${this.searchMoreFacetsLink(facetGroup)}
|
|
410
|
+
`}
|
|
398
411
|
</div>
|
|
399
412
|
</div>
|
|
400
413
|
`;
|
|
401
414
|
}
|
|
402
415
|
|
|
416
|
+
private getTombstoneFacetGroupTemplate(): TemplateResult {
|
|
417
|
+
// Render five tombstone rows
|
|
418
|
+
return html`
|
|
419
|
+
${map(
|
|
420
|
+
Array(5).fill(null),
|
|
421
|
+
() => html`<facet-tombstone-row></facet-tombstone-row>`
|
|
422
|
+
)}
|
|
423
|
+
`;
|
|
424
|
+
}
|
|
425
|
+
|
|
403
426
|
private moreFacetsSortingIcon(
|
|
404
427
|
facetGroup: FacetGroup
|
|
405
428
|
): TemplateResult | typeof nothing {
|
|
@@ -531,6 +554,14 @@ export class CollectionFacets extends LitElement {
|
|
|
531
554
|
opacity: 0.5;
|
|
532
555
|
}
|
|
533
556
|
|
|
557
|
+
.histogram-loading-indicator {
|
|
558
|
+
width: 100%;
|
|
559
|
+
height: 2.25rem;
|
|
560
|
+
margin-top: 1.75rem;
|
|
561
|
+
font-size: 1.4rem;
|
|
562
|
+
text-align: center;
|
|
563
|
+
}
|
|
564
|
+
|
|
534
565
|
.collapser {
|
|
535
566
|
display: inline-block;
|
|
536
567
|
cursor: pointer;
|
package/src/models.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
SearchType,
|
|
3
|
+
SortDirection,
|
|
4
|
+
SortParam,
|
|
5
|
+
} from '@internetarchive/search-service';
|
|
2
6
|
import { getCookie, setCookie } from 'typescript-cookie';
|
|
3
7
|
import {
|
|
4
8
|
MetadataFieldToSortField,
|
|
@@ -14,6 +18,7 @@ import {
|
|
|
14
18
|
|
|
15
19
|
export interface RestorationState {
|
|
16
20
|
displayMode?: CollectionDisplayMode;
|
|
21
|
+
searchType?: SearchType;
|
|
17
22
|
sortParam?: SortParam;
|
|
18
23
|
selectedSort?: SortField;
|
|
19
24
|
sortDirection?: SortDirection;
|
|
@@ -87,12 +92,20 @@ export class RestorationStateHandler
|
|
|
87
92
|
private persistQueryStateToUrl(state: RestorationState) {
|
|
88
93
|
const url = new URL(window.location.href);
|
|
89
94
|
const { searchParams } = url;
|
|
95
|
+
searchParams.delete('sin');
|
|
90
96
|
searchParams.delete('sort');
|
|
91
97
|
searchParams.delete('query');
|
|
92
98
|
searchParams.delete('page');
|
|
93
99
|
searchParams.delete('and[]');
|
|
94
100
|
searchParams.delete('not[]');
|
|
95
101
|
|
|
102
|
+
if (state.searchType) {
|
|
103
|
+
searchParams.set(
|
|
104
|
+
'sin',
|
|
105
|
+
state.searchType === SearchType.FULLTEXT ? 'TXT' : ''
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
96
109
|
if (state.sortParam) {
|
|
97
110
|
const prefix = state.sortParam.direction === 'desc' ? '-' : '';
|
|
98
111
|
searchParams.set('sort', `${prefix}${state.sortParam.field}`);
|
|
@@ -155,6 +168,7 @@ export class RestorationStateHandler
|
|
|
155
168
|
|
|
156
169
|
private loadQueryStateFromUrl(): RestorationState {
|
|
157
170
|
const url = new URL(window.location.href);
|
|
171
|
+
const searchInside = url.searchParams.get('sin');
|
|
158
172
|
const pageNumber = url.searchParams.get('page');
|
|
159
173
|
const searchQuery = url.searchParams.get('query');
|
|
160
174
|
const sortQuery = url.searchParams.get('sort');
|
|
@@ -173,6 +187,10 @@ export class RestorationStateHandler
|
|
|
173
187
|
},
|
|
174
188
|
};
|
|
175
189
|
|
|
190
|
+
if (searchInside) {
|
|
191
|
+
restorationState.searchType =
|
|
192
|
+
searchInside === 'TXT' ? SearchType.FULLTEXT : SearchType.METADATA;
|
|
193
|
+
}
|
|
176
194
|
if (pageNumber) {
|
|
177
195
|
const parsed = parseInt(pageNumber, 10);
|
|
178
196
|
restorationState.currentPage = parsed;
|