@internetarchive/collection-browser 0.4.4-alpha.1 → 0.4.4
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.js +17 -2
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/collection-browser.d.ts +2 -40
- package/dist/src/collection-browser.js +45 -116
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/sort-filter-bar/sort-filter-bar.js +11 -1
- package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
- package/dist/src/styles/item-image-styles.js +5 -1
- package/dist/src/styles/item-image-styles.js.map +1 -1
- package/dist/src/tiles/grid/item-tile.js +15 -2
- package/dist/src/tiles/grid/item-tile.js.map +1 -1
- package/dist/src/tiles/grid/styles/tile-grid-shared-styles.js +6 -6
- package/dist/src/tiles/grid/styles/tile-grid-shared-styles.js.map +1 -1
- package/dist/src/tiles/grid/tile-stats.js +15 -7
- package/dist/src/tiles/grid/tile-stats.js.map +1 -1
- package/dist/src/tiles/hover/hover-pane-controller.d.ts +197 -0
- package/dist/src/tiles/hover/hover-pane-controller.js +349 -0
- package/dist/src/tiles/hover/hover-pane-controller.js.map +1 -0
- package/dist/src/tiles/hover/tile-hover-pane.d.ts +15 -0
- package/dist/src/tiles/hover/tile-hover-pane.js +88 -0
- package/dist/src/tiles/hover/tile-hover-pane.js.map +1 -0
- package/dist/src/tiles/image-block.js +4 -0
- package/dist/src/tiles/image-block.js.map +1 -1
- package/dist/src/tiles/list/date-label.js +3 -3
- package/dist/src/tiles/list/date-label.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact-header.js +4 -3
- package/dist/src/tiles/list/tile-list-compact-header.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact.js +15 -5
- package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
- package/dist/src/tiles/list/tile-list.d.ts +2 -0
- package/dist/src/tiles/list/tile-list.js +63 -5
- package/dist/src/tiles/list/tile-list.js.map +1 -1
- package/dist/src/tiles/text-snippet-block.js +4 -4
- package/dist/src/tiles/text-snippet-block.js.map +1 -1
- package/dist/src/tiles/tile-dispatcher.d.ts +21 -2
- package/dist/src/tiles/tile-dispatcher.js +79 -9
- package/dist/src/tiles/tile-dispatcher.js.map +1 -1
- package/dist/test/collection-browser.test.js +6 -72
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/sort-filter-bar/sort-filter-bar.test.js +64 -0
- package/dist/test/sort-filter-bar/sort-filter-bar.test.js.map +1 -1
- package/dist/test/tiles/grid/account-tile.test.js +1 -1
- package/dist/test/tiles/grid/account-tile.test.js.map +1 -1
- package/dist/test/tiles/hover/hover-pane-controller.test.d.ts +1 -0
- package/dist/test/tiles/hover/hover-pane-controller.test.js +279 -0
- package/dist/test/tiles/hover/hover-pane-controller.test.js.map +1 -0
- package/dist/test/tiles/hover/tile-hover-pane.test.d.ts +1 -0
- package/dist/test/tiles/hover/tile-hover-pane.test.js +14 -0
- package/dist/test/tiles/hover/tile-hover-pane.test.js.map +1 -0
- package/dist/test/tiles/list/tile-list.test.js +46 -1
- package/dist/test/tiles/list/tile-list.test.js.map +1 -1
- package/index.html +1 -0
- package/package.json +2 -2
- package/src/app-root.ts +17 -2
- package/src/collection-browser.ts +42 -138
- package/src/sort-filter-bar/sort-filter-bar.ts +12 -1
- package/src/styles/item-image-styles.ts +5 -1
- package/src/tiles/grid/item-tile.ts +15 -2
- package/src/tiles/grid/styles/tile-grid-shared-styles.ts +6 -6
- package/src/tiles/grid/tile-stats.ts +15 -7
- package/src/tiles/hover/hover-pane-controller.ts +469 -0
- package/src/tiles/hover/tile-hover-pane.ts +79 -0
- package/src/tiles/image-block.ts +4 -0
- package/src/tiles/list/date-label.ts +3 -3
- package/src/tiles/list/tile-list-compact-header.ts +4 -3
- package/src/tiles/list/tile-list-compact.ts +15 -5
- package/src/tiles/list/tile-list.ts +67 -5
- package/src/tiles/text-snippet-block.ts +4 -4
- package/src/tiles/tile-dispatcher.ts +95 -7
- package/test/collection-browser.test.ts +7 -101
- package/test/sort-filter-bar/sort-filter-bar.test.ts +89 -0
- package/test/tiles/grid/account-tile.test.ts +1 -1
- package/test/tiles/hover/hover-pane-controller.test.ts +349 -0
- package/test/tiles/hover/tile-hover-pane.test.ts +19 -0
- package/test/tiles/list/tile-list.test.ts +58 -1
|
@@ -90,7 +90,13 @@ export class TileList extends LitElement {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
private get imageBlockTemplate() {
|
|
93
|
-
return
|
|
93
|
+
if (!this.model) return nothing;
|
|
94
|
+
|
|
95
|
+
return html`<a
|
|
96
|
+
href="${this.baseNavigationUrl}/details/${encodeURI(
|
|
97
|
+
this.model.identifier
|
|
98
|
+
)}"
|
|
99
|
+
>
|
|
94
100
|
<image-block
|
|
95
101
|
.model=${this.model}
|
|
96
102
|
.baseImageUrl=${this.baseImageUrl}
|
|
@@ -100,7 +106,7 @@ export class TileList extends LitElement {
|
|
|
100
106
|
.loggedIn=${this.loggedIn}
|
|
101
107
|
>
|
|
102
108
|
</image-block>
|
|
103
|
-
`;
|
|
109
|
+
</a> `;
|
|
104
110
|
}
|
|
105
111
|
|
|
106
112
|
private get detailsTemplate() {
|
|
@@ -120,13 +126,13 @@ export class TileList extends LitElement {
|
|
|
120
126
|
// Data templates
|
|
121
127
|
private get iconRightTemplate() {
|
|
122
128
|
return html`
|
|
123
|
-
<
|
|
129
|
+
<a id="icon-right" href=${this.mediatypeURL} target="_blank">
|
|
124
130
|
<mediatype-icon
|
|
125
131
|
.mediatype=${this.model?.mediatype}
|
|
126
132
|
.collections=${this.model?.collections}
|
|
127
133
|
>
|
|
128
134
|
</mediatype-icon>
|
|
129
|
-
</
|
|
135
|
+
</a>
|
|
130
136
|
`;
|
|
131
137
|
}
|
|
132
138
|
|
|
@@ -331,6 +337,23 @@ export class TileList extends LitElement {
|
|
|
331
337
|
>`;
|
|
332
338
|
}
|
|
333
339
|
|
|
340
|
+
/** The URL of this item's mediatype collection, if defined. */
|
|
341
|
+
private get mediatypeURL(): string | typeof nothing {
|
|
342
|
+
if (!this.baseNavigationUrl || !this.model?.mediatype) return nothing;
|
|
343
|
+
|
|
344
|
+
// Need special handling for certain mediatypes that don't have a top-level collection page
|
|
345
|
+
switch (this.model.mediatype) {
|
|
346
|
+
case 'collection':
|
|
347
|
+
return `${this.baseNavigationUrl}/search?query=mediatype:collection&sort=-downloads`;
|
|
348
|
+
case 'account':
|
|
349
|
+
return nothing;
|
|
350
|
+
default:
|
|
351
|
+
return `${this.baseNavigationUrl}/details/${encodeURI(
|
|
352
|
+
this.model.mediatype
|
|
353
|
+
)}`;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
334
357
|
protected updated(changed: PropertyValues): void {
|
|
335
358
|
if (changed.has('model')) {
|
|
336
359
|
this.fetchCollectionNames();
|
|
@@ -459,6 +482,12 @@ export class TileList extends LitElement {
|
|
|
459
482
|
margin-top: -4px;
|
|
460
483
|
padding-bottom: 2px;
|
|
461
484
|
flex-grow: 1;
|
|
485
|
+
|
|
486
|
+
display: -webkit-box;
|
|
487
|
+
-webkit-box-orient: vertical;
|
|
488
|
+
-webkit-line-clamp: 3;
|
|
489
|
+
overflow: hidden;
|
|
490
|
+
overflow-wrap: anywhere;
|
|
462
491
|
}
|
|
463
492
|
|
|
464
493
|
.metadata {
|
|
@@ -479,6 +508,14 @@ export class TileList extends LitElement {
|
|
|
479
508
|
line-clamp: 3;
|
|
480
509
|
}
|
|
481
510
|
|
|
511
|
+
#collections {
|
|
512
|
+
display: -webkit-box;
|
|
513
|
+
-webkit-box-orient: vertical;
|
|
514
|
+
-webkit-line-clamp: 3;
|
|
515
|
+
overflow: hidden;
|
|
516
|
+
overflow-wrap: anywhere;
|
|
517
|
+
}
|
|
518
|
+
|
|
482
519
|
#icon {
|
|
483
520
|
padding-top: 5px;
|
|
484
521
|
}
|
|
@@ -515,6 +552,18 @@ export class TileList extends LitElement {
|
|
|
515
552
|
width: 100%;
|
|
516
553
|
}
|
|
517
554
|
|
|
555
|
+
/*
|
|
556
|
+
* If the container becomes very tiny, don't let the thumbnail side take
|
|
557
|
+
* up too much space. Shouldn't make a difference on ordinary viewport sizes.
|
|
558
|
+
*/
|
|
559
|
+
#list-line-left {
|
|
560
|
+
max-width: 25%;
|
|
561
|
+
|
|
562
|
+
display: flex;
|
|
563
|
+
flex-direction: column;
|
|
564
|
+
row-gap: 5px;
|
|
565
|
+
}
|
|
566
|
+
|
|
518
567
|
div a:hover {
|
|
519
568
|
text-decoration: underline;
|
|
520
569
|
}
|
|
@@ -526,7 +575,20 @@ export class TileList extends LitElement {
|
|
|
526
575
|
#title-line {
|
|
527
576
|
display: flex;
|
|
528
577
|
flex-direction: row;
|
|
529
|
-
gap: 10px;
|
|
578
|
+
column-gap: 10px;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/*
|
|
582
|
+
* With the exception of the title line, allow these to wrap if
|
|
583
|
+
* the space becomes too small to accommodate them together.
|
|
584
|
+
*
|
|
585
|
+
* The title line is excluded because it contains the mediatype icon
|
|
586
|
+
* which we don't want to wrap.
|
|
587
|
+
*/
|
|
588
|
+
#item-line,
|
|
589
|
+
#dates-line,
|
|
590
|
+
#views-line {
|
|
591
|
+
flex-wrap: wrap;
|
|
530
592
|
}
|
|
531
593
|
`;
|
|
532
594
|
}
|
|
@@ -85,11 +85,12 @@ export class TextSnippetBlock extends LitElement {
|
|
|
85
85
|
display: flex;
|
|
86
86
|
flex-direction: row;
|
|
87
87
|
flex-wrap: wrap;
|
|
88
|
-
width: 100
|
|
88
|
+
width: calc(100% - 10px);
|
|
89
89
|
border-left: 5px solid #194880;
|
|
90
90
|
margin-top: var(--containerTopMargin, 10px);
|
|
91
91
|
margin-left: var(--containerLeftMargin, 0px);
|
|
92
92
|
border-radius: 3px;
|
|
93
|
+
box-sizing: border-box;
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
.snippet-view {
|
|
@@ -101,17 +102,16 @@ export class TextSnippetBlock extends LitElement {
|
|
|
101
102
|
-webkit-line-clamp: var(--maxLines, 3);
|
|
102
103
|
-webkit-box-orient: vertical;
|
|
103
104
|
margin-left: 5px;
|
|
104
|
-
margin-right: 10px;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
.grid {
|
|
108
|
-
margin: 0px 15px 0px 5px;
|
|
109
108
|
font-size: 1.2rem;
|
|
110
109
|
line-height: 1.5rem;
|
|
111
110
|
}
|
|
112
111
|
|
|
113
112
|
.list {
|
|
114
|
-
|
|
113
|
+
margin: 0;
|
|
114
|
+
padding-left: 15px;
|
|
115
115
|
font-size: 1.4rem;
|
|
116
116
|
line-height: 2rem;
|
|
117
117
|
}
|
|
@@ -11,14 +11,24 @@ import type { TileDisplayMode, TileModel } from '../models';
|
|
|
11
11
|
import './grid/collection-tile';
|
|
12
12
|
import './grid/item-tile';
|
|
13
13
|
import './grid/account-tile';
|
|
14
|
+
import './hover/tile-hover-pane';
|
|
14
15
|
import './list/tile-list';
|
|
15
16
|
import './list/tile-list-compact';
|
|
16
17
|
import './list/tile-list-compact-header';
|
|
18
|
+
import type { TileHoverPane } from './hover/tile-hover-pane';
|
|
19
|
+
import {
|
|
20
|
+
HoverPaneController,
|
|
21
|
+
HoverPaneControllerInterface,
|
|
22
|
+
HoverPaneProperties,
|
|
23
|
+
HoverPaneProviderInterface,
|
|
24
|
+
} from './hover/hover-pane-controller';
|
|
17
25
|
|
|
18
26
|
@customElement('tile-dispatcher')
|
|
19
27
|
export class TileDispatcher
|
|
20
28
|
extends LitElement
|
|
21
|
-
implements
|
|
29
|
+
implements
|
|
30
|
+
SharedResizeObserverResizeHandlerInterface,
|
|
31
|
+
HoverPaneProviderInterface
|
|
22
32
|
{
|
|
23
33
|
@property({ type: String }) tileDisplayMode?: TileDisplayMode;
|
|
24
34
|
|
|
@@ -37,24 +47,57 @@ export class TileDispatcher
|
|
|
37
47
|
|
|
38
48
|
@property({ type: Object }) sortParam: SortParam | null = null;
|
|
39
49
|
|
|
40
|
-
@query('#container') private container!: HTMLDivElement;
|
|
41
|
-
|
|
42
50
|
@property({ type: Number }) mobileBreakpoint?: number;
|
|
43
51
|
|
|
44
52
|
@property({ type: String }) baseImageUrl?: string;
|
|
45
53
|
|
|
46
54
|
@property({ type: Boolean }) loggedIn = false;
|
|
47
55
|
|
|
56
|
+
/** Whether this tile should include a hover pane at all (for applicable tile modes) */
|
|
57
|
+
@property({ type: Boolean }) enableHoverPane = false;
|
|
58
|
+
|
|
59
|
+
private hoverPaneController?: HoverPaneControllerInterface;
|
|
60
|
+
|
|
61
|
+
@query('#container')
|
|
62
|
+
private container!: HTMLDivElement;
|
|
63
|
+
|
|
64
|
+
@query('tile-hover-pane')
|
|
65
|
+
private hoverPane?: TileHoverPane;
|
|
66
|
+
|
|
67
|
+
/** Maps each display mode to whether hover panes should appear in that mode */
|
|
68
|
+
private static readonly HOVER_PANE_DISPLAY_MODES: Record<
|
|
69
|
+
TileDisplayMode,
|
|
70
|
+
boolean
|
|
71
|
+
> = {
|
|
72
|
+
grid: true,
|
|
73
|
+
'list-compact': true,
|
|
74
|
+
'list-detail': false,
|
|
75
|
+
'list-header': false,
|
|
76
|
+
};
|
|
77
|
+
|
|
48
78
|
render() {
|
|
79
|
+
const isGridMode = this.tileDisplayMode === 'grid';
|
|
80
|
+
const hoverPaneTemplate =
|
|
81
|
+
this.hoverPaneController?.getTemplate() ?? nothing;
|
|
49
82
|
return html`
|
|
50
|
-
<div id="container">
|
|
83
|
+
<div id="container" class=${isGridMode ? 'hoverable' : nothing}>
|
|
51
84
|
${this.tileDisplayMode === 'list-header'
|
|
52
85
|
? this.headerTemplate
|
|
53
86
|
: this.tileTemplate}
|
|
87
|
+
${hoverPaneTemplate}
|
|
54
88
|
</div>
|
|
55
89
|
`;
|
|
56
90
|
}
|
|
57
91
|
|
|
92
|
+
protected firstUpdated(): void {
|
|
93
|
+
if (this.shouldPrepareHoverPane) {
|
|
94
|
+
this.hoverPaneController = new HoverPaneController(this, {
|
|
95
|
+
mobileBreakpoint: this.mobileBreakpoint,
|
|
96
|
+
enableLongPress: false,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
58
101
|
private get headerTemplate() {
|
|
59
102
|
const { currentWidth, sortParam, mobileBreakpoint } = this;
|
|
60
103
|
return html`
|
|
@@ -80,7 +123,9 @@ export class TileDispatcher
|
|
|
80
123
|
return html`
|
|
81
124
|
<a
|
|
82
125
|
href="${this.baseNavigationUrl}/details/${this.model?.identifier}"
|
|
83
|
-
title=${
|
|
126
|
+
title=${this.shouldPrepareHoverPane
|
|
127
|
+
? nothing // Don't show title tooltips when we have the tile info popups
|
|
128
|
+
: ifDefined(this.model?.title)}
|
|
84
129
|
@click=${() =>
|
|
85
130
|
this.dispatchEvent(
|
|
86
131
|
new CustomEvent('resultSelected', { detail: this.model })
|
|
@@ -91,6 +136,28 @@ export class TileDispatcher
|
|
|
91
136
|
`;
|
|
92
137
|
}
|
|
93
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Whether hover pane behavior should be prepared for this tile
|
|
141
|
+
* (e.g., whether mouse listeners should be attached, etc.)
|
|
142
|
+
*/
|
|
143
|
+
private get shouldPrepareHoverPane(): boolean {
|
|
144
|
+
return (
|
|
145
|
+
this.enableHoverPane &&
|
|
146
|
+
!!this.tileDisplayMode &&
|
|
147
|
+
TileDispatcher.HOVER_PANE_DISPLAY_MODES[this.tileDisplayMode]
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** @inheritdoc */
|
|
152
|
+
getHoverPane(): TileHoverPane | undefined {
|
|
153
|
+
return this.hoverPane;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** @inheritdoc */
|
|
157
|
+
getHoverPaneProps(): HoverPaneProperties {
|
|
158
|
+
return this;
|
|
159
|
+
}
|
|
160
|
+
|
|
94
161
|
handleResize(entry: ResizeObserverEntry): void {
|
|
95
162
|
this.currentWidth = entry.contentRect.width;
|
|
96
163
|
this.currentHeight = entry.contentRect.height;
|
|
@@ -222,11 +289,14 @@ export class TileDispatcher
|
|
|
222
289
|
}
|
|
223
290
|
|
|
224
291
|
#container {
|
|
292
|
+
position: relative;
|
|
225
293
|
height: 100%;
|
|
294
|
+
border-radius: 4px;
|
|
226
295
|
}
|
|
227
296
|
|
|
228
|
-
#
|
|
229
|
-
|
|
297
|
+
#container.hoverable:hover {
|
|
298
|
+
box-shadow: 0 0 6px 2px rgba(8, 8, 32, 0.8);
|
|
299
|
+
transition: box-shadow 0.1s ease;
|
|
230
300
|
}
|
|
231
301
|
|
|
232
302
|
a {
|
|
@@ -234,12 +304,30 @@ export class TileDispatcher
|
|
|
234
304
|
height: 100%;
|
|
235
305
|
color: unset;
|
|
236
306
|
text-decoration: none;
|
|
307
|
+
transition: transform 0.05s ease;
|
|
237
308
|
}
|
|
238
309
|
|
|
239
310
|
a :first-child {
|
|
240
311
|
display: block;
|
|
241
312
|
height: 100%;
|
|
242
313
|
}
|
|
314
|
+
|
|
315
|
+
#touch-backdrop {
|
|
316
|
+
position: fixed;
|
|
317
|
+
width: 100vw;
|
|
318
|
+
height: 100vh;
|
|
319
|
+
top: 0;
|
|
320
|
+
left: 0;
|
|
321
|
+
z-index: 1;
|
|
322
|
+
background: transparent;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
tile-hover-pane {
|
|
326
|
+
position: absolute;
|
|
327
|
+
top: 0;
|
|
328
|
+
left: -9999px;
|
|
329
|
+
z-index: 2;
|
|
330
|
+
}
|
|
243
331
|
`;
|
|
244
332
|
}
|
|
245
333
|
}
|
|
@@ -318,100 +318,6 @@ describe('Collection Browser', () => {
|
|
|
318
318
|
});
|
|
319
319
|
});
|
|
320
320
|
|
|
321
|
-
it('fires a separate date histogram query when year facets are applied', async () => {
|
|
322
|
-
const searchService = new MockSearchService();
|
|
323
|
-
const selectedFacets: SelectedFacets = {
|
|
324
|
-
subject: {},
|
|
325
|
-
lending: {},
|
|
326
|
-
mediatype: {},
|
|
327
|
-
language: {},
|
|
328
|
-
creator: {},
|
|
329
|
-
collection: {},
|
|
330
|
-
year: {
|
|
331
|
-
'2000': {
|
|
332
|
-
key: '2000',
|
|
333
|
-
state: 'selected',
|
|
334
|
-
count: 123,
|
|
335
|
-
},
|
|
336
|
-
},
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
const el = await fixture<CollectionBrowser>(
|
|
340
|
-
html`<collection-browser .searchService=${searchService}>
|
|
341
|
-
</collection-browser>`
|
|
342
|
-
);
|
|
343
|
-
|
|
344
|
-
el.baseQuery = 'collection:foo';
|
|
345
|
-
el.showHistogramDatePicker = true;
|
|
346
|
-
el.selectedFacets = selectedFacets;
|
|
347
|
-
await el.updateComplete;
|
|
348
|
-
|
|
349
|
-
expect(
|
|
350
|
-
searchService.searchParams?.aggregations?.simpleParams
|
|
351
|
-
).to.deep.equal(['year']); // Explicitly requests year aggregations
|
|
352
|
-
expect(searchService.searchParams?.query).to.equal(
|
|
353
|
-
'collection:foo' // No date clause on query
|
|
354
|
-
);
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
it('fires a separate date histogram query when a date range is applied', async () => {
|
|
358
|
-
const searchService = new MockSearchService();
|
|
359
|
-
|
|
360
|
-
const el = await fixture<CollectionBrowser>(
|
|
361
|
-
html`<collection-browser .searchService=${searchService}>
|
|
362
|
-
</collection-browser>`
|
|
363
|
-
);
|
|
364
|
-
|
|
365
|
-
el.baseQuery = 'collection:foo';
|
|
366
|
-
el.showHistogramDatePicker = true;
|
|
367
|
-
el.minSelectedDate = '1995';
|
|
368
|
-
el.maxSelectedDate = '2005';
|
|
369
|
-
await el.updateComplete;
|
|
370
|
-
|
|
371
|
-
expect(
|
|
372
|
-
searchService.searchParams?.aggregations?.simpleParams
|
|
373
|
-
).to.deep.equal(['year']); // Explicitly requests year aggregations
|
|
374
|
-
expect(searchService.searchParams?.query).to.equal(
|
|
375
|
-
'collection:foo' // No date clause on query
|
|
376
|
-
);
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
it('does not fire a separate date histogram query when no date filters are applied', async () => {
|
|
380
|
-
const searchService = new MockSearchService();
|
|
381
|
-
|
|
382
|
-
const el = await fixture<CollectionBrowser>(
|
|
383
|
-
html`<collection-browser .searchService=${searchService}>
|
|
384
|
-
</collection-browser>`
|
|
385
|
-
);
|
|
386
|
-
|
|
387
|
-
el.baseQuery = 'collection:foo';
|
|
388
|
-
el.showHistogramDatePicker = true;
|
|
389
|
-
await el.updateComplete;
|
|
390
|
-
|
|
391
|
-
expect(searchService.searchParams?.aggregations?.simpleParams).to.satisfy(
|
|
392
|
-
(aggTypes: string[]) => !aggTypes || !aggTypes.includes('year') // Not requesting year aggregations explicitly
|
|
393
|
-
);
|
|
394
|
-
});
|
|
395
|
-
|
|
396
|
-
it('does not fire a separate date histogram query when date picker is disabled', async () => {
|
|
397
|
-
const searchService = new MockSearchService();
|
|
398
|
-
|
|
399
|
-
const el = await fixture<CollectionBrowser>(
|
|
400
|
-
html`<collection-browser .searchService=${searchService}>
|
|
401
|
-
</collection-browser>`
|
|
402
|
-
);
|
|
403
|
-
|
|
404
|
-
el.baseQuery = 'collection:foo';
|
|
405
|
-
el.showHistogramDatePicker = false;
|
|
406
|
-
el.minSelectedDate = '1995';
|
|
407
|
-
el.maxSelectedDate = '2005';
|
|
408
|
-
await el.updateComplete;
|
|
409
|
-
|
|
410
|
-
expect(searchService.searchParams?.aggregations?.simpleParams).to.satisfy(
|
|
411
|
-
(aggTypes: string[]) => !aggTypes || !aggTypes.includes('year') // Not requesting year aggregations explicitly
|
|
412
|
-
);
|
|
413
|
-
});
|
|
414
|
-
|
|
415
321
|
it('fails gracefully if no search service provided', async () => {
|
|
416
322
|
const el = await fixture<CollectionBrowser>(
|
|
417
323
|
html`<collection-browser></collection-browser>`
|
|
@@ -845,7 +751,12 @@ describe('Collection Browser', () => {
|
|
|
845
751
|
</collection-browser>`
|
|
846
752
|
);
|
|
847
753
|
|
|
848
|
-
// Infinite scroller won't exist unless there's a base query
|
|
754
|
+
// Infinite scroller won't exist unless there's a base query.
|
|
755
|
+
// First ensure that we don't throw errors when it doesn't exist.
|
|
756
|
+
await el.goToPage(1);
|
|
757
|
+
|
|
758
|
+
// And make sure it correctly calls scrollToCell when the
|
|
759
|
+
// infinite scroller does exist.
|
|
849
760
|
el.baseQuery = 'collection:foo';
|
|
850
761
|
await el.updateComplete;
|
|
851
762
|
|
|
@@ -858,12 +769,7 @@ describe('Collection Browser', () => {
|
|
|
858
769
|
const spy = sinon.spy();
|
|
859
770
|
infiniteScroller.scrollToCell = spy;
|
|
860
771
|
|
|
861
|
-
el.goToPage(1);
|
|
862
|
-
|
|
863
|
-
// Give it a second to scroll
|
|
864
|
-
await new Promise(res => {
|
|
865
|
-
setTimeout(res, 1000);
|
|
866
|
-
});
|
|
772
|
+
await el.goToPage(1);
|
|
867
773
|
|
|
868
774
|
expect(spy.callCount).to.equal(1);
|
|
869
775
|
|
|
@@ -229,3 +229,92 @@ describe('Sort/filter bar letter behavior', () => {
|
|
|
229
229
|
expect(el.selectedCreatorFilter).to.equal('C');
|
|
230
230
|
});
|
|
231
231
|
});
|
|
232
|
+
|
|
233
|
+
describe('Sort/filter bar mobile view', () => {
|
|
234
|
+
let origWindowSize: { width: number; height: number };
|
|
235
|
+
before(() => {
|
|
236
|
+
origWindowSize = { width: window.innerWidth, height: window.innerHeight };
|
|
237
|
+
window.resizeTo(500, 600);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
after(() => {
|
|
241
|
+
window.resizeTo(origWindowSize.width, origWindowSize.height);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it('renders in mobile view', async () => {
|
|
245
|
+
const el = await fixture<SortFilterBar>(html`
|
|
246
|
+
<sort-filter-bar></sort-filter-bar>
|
|
247
|
+
`);
|
|
248
|
+
|
|
249
|
+
const mobileSortSelector = el.shadowRoot?.querySelector(
|
|
250
|
+
'#mobile-sort-selector'
|
|
251
|
+
);
|
|
252
|
+
const desktopSortSelector = el.shadowRoot?.querySelector(
|
|
253
|
+
'#desktop-sort-selector'
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
expect(mobileSortSelector?.classList?.contains('visible')).to.be.true;
|
|
257
|
+
expect(desktopSortSelector?.classList?.contains('hidden')).to.be.true;
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('changes selected sort in mobile view', async () => {
|
|
261
|
+
const el = await fixture<SortFilterBar>(html`
|
|
262
|
+
<sort-filter-bar></sort-filter-bar>
|
|
263
|
+
`);
|
|
264
|
+
|
|
265
|
+
const mobileSortSelector = el.shadowRoot?.querySelector(
|
|
266
|
+
'#mobile-sort-selector'
|
|
267
|
+
) as HTMLSelectElement;
|
|
268
|
+
expect(mobileSortSelector).to.exist;
|
|
269
|
+
|
|
270
|
+
mobileSortSelector.value = 'title';
|
|
271
|
+
mobileSortSelector.dispatchEvent(new Event('change'));
|
|
272
|
+
await el.updateComplete;
|
|
273
|
+
|
|
274
|
+
expect(el.selectedSort).to.equal('title');
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('clears title filter when sort changed from title in mobile view', async () => {
|
|
278
|
+
const el = await fixture<SortFilterBar>(html`
|
|
279
|
+
<sort-filter-bar></sort-filter-bar>
|
|
280
|
+
`);
|
|
281
|
+
|
|
282
|
+
el.selectedSort = 'title' as SortField;
|
|
283
|
+
el.selectedTitleFilter = 'A';
|
|
284
|
+
await el.updateComplete;
|
|
285
|
+
|
|
286
|
+
const mobileSortSelector = el.shadowRoot?.querySelector(
|
|
287
|
+
'#mobile-sort-selector'
|
|
288
|
+
) as HTMLSelectElement;
|
|
289
|
+
expect(mobileSortSelector).to.exist;
|
|
290
|
+
|
|
291
|
+
mobileSortSelector.value = 'relevance';
|
|
292
|
+
mobileSortSelector.dispatchEvent(new Event('change'));
|
|
293
|
+
await el.updateComplete;
|
|
294
|
+
|
|
295
|
+
expect(el.selectedSort).to.equal('relevance');
|
|
296
|
+
expect(el.selectedTitleFilter).to.be.null;
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it('clears creator filter when sort changed from creator in mobile view', async () => {
|
|
300
|
+
const el = await fixture<SortFilterBar>(html`
|
|
301
|
+
<sort-filter-bar></sort-filter-bar>
|
|
302
|
+
`);
|
|
303
|
+
|
|
304
|
+
el.selectedSort = 'creator' as SortField;
|
|
305
|
+
el.selectedCreatorFilter = 'A';
|
|
306
|
+
await el.updateComplete;
|
|
307
|
+
|
|
308
|
+
const mobileSortSelector = el.shadowRoot?.querySelector(
|
|
309
|
+
'#mobile-sort-selector'
|
|
310
|
+
) as HTMLSelectElement;
|
|
311
|
+
expect(mobileSortSelector).to.exist;
|
|
312
|
+
|
|
313
|
+
mobileSortSelector.value = 'relevance';
|
|
314
|
+
mobileSortSelector.dispatchEvent(new Event('change'));
|
|
315
|
+
await el.updateComplete;
|
|
316
|
+
|
|
317
|
+
expect(el.selectedSort).to.equal('relevance');
|
|
318
|
+
expect(el.selectedCreatorFilter).to.be.null;
|
|
319
|
+
});
|
|
320
|
+
});
|