@internetarchive/collection-browser 0.2.10 → 0.2.13
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/index.js +1 -0
- package/package.json +4 -3
- package/renovate.json +6 -0
- package/src/assets/img/icons/empty-query.ts +5 -0
- package/src/assets/img/icons/login-required.ts +30 -0
- package/src/assets/img/icons/null-result.ts +5 -0
- package/src/collection-browser.ts +107 -72
- package/src/collection-facets.ts +3 -3
- package/src/empty-placeholder.ts +79 -0
- package/src/restoration-state-handler.ts +1 -1
- package/src/sort-filter-bar/sort-filter-bar.ts +1 -1
- package/src/styles/item-image-styles.ts +4 -3
- package/src/tiles/grid/account-tile.ts +1 -1
- package/src/tiles/grid/collection-tile.ts +1 -1
- package/src/tiles/grid/item-tile.ts +24 -21
- package/src/tiles/image-block.ts +124 -0
- package/src/tiles/item-image.ts +4 -2
- package/src/tiles/list/tile-list-compact-header.ts +2 -2
- package/src/tiles/list/tile-list-compact.ts +21 -58
- package/src/tiles/list/tile-list.ts +22 -58
- package/src/tiles/overlay/icon-overlay.ts +34 -0
- package/src/tiles/overlay/text-overlay.ts +48 -0
- package/src/tiles/tile-dispatcher.ts +15 -6
- package/test/collection-browser.test.ts +4 -1
- package/test/empty-placeholder.test.ts +47 -0
- package/test/icon-overlay.test.ts +41 -0
- package/test/item-image.test.ts +82 -0
- package/test/mocks/mock-collection-name-cache.ts +1 -1
- package/test/mocks/mock-search-responses.ts +1 -1
- package/test/mocks/mock-search-service.ts +2 -2
- package/test/text-overlay.test.ts +57 -0
- package/test/tile-stats.test.ts +1 -1
- package/test/tiles/grid/item-tile.test.ts +3 -3
- package/tsconfig.json +2 -1
- package/src/tiles/item-tile-image.ts +0 -61
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/* eslint-disable import/no-duplicates */
|
|
2
|
+
import { expect, fixture } from '@open-wc/testing';
|
|
3
|
+
import { html } from 'lit';
|
|
4
|
+
import '../src/empty-placeholder';
|
|
5
|
+
|
|
6
|
+
import type { EmptyPlaceholder } from '../src/empty-placeholder';
|
|
7
|
+
|
|
8
|
+
describe('Empty Placeholder', () => {
|
|
9
|
+
it('should render with empty-query placeholder', async () => {
|
|
10
|
+
const el = await fixture<EmptyPlaceholder>(
|
|
11
|
+
html`<empty-placeholder></empty-placeholder>`
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
el.placeholderType = 'empty-query';
|
|
15
|
+
await el.updateComplete;
|
|
16
|
+
|
|
17
|
+
expect(el.shadowRoot?.querySelector('.empty-query')).to.exist;
|
|
18
|
+
expect(el.shadowRoot?.querySelector('.null-result')).to.not.exist;
|
|
19
|
+
expect(el.shadowRoot?.querySelector('infinite-scroller')).to.not.exist;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should render with null-result placeholder', async () => {
|
|
23
|
+
const el = await fixture<EmptyPlaceholder>(
|
|
24
|
+
html`<empty-placeholder></empty-placeholder>`
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
el.placeholderType = 'null-result';
|
|
28
|
+
await el.updateComplete;
|
|
29
|
+
|
|
30
|
+
expect(el.shadowRoot?.querySelector('.null-result')).to.exist;
|
|
31
|
+
expect(el.shadowRoot?.querySelector('.empty-query')).to.not.exist;
|
|
32
|
+
expect(el.shadowRoot?.querySelector('collection-facets')).to.not.exist;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should not render any empty placeholder', async () => {
|
|
36
|
+
const el = await fixture<EmptyPlaceholder>(
|
|
37
|
+
html`<empty-placeholder></empty-placeholder>`
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
el.placeholderType = null;
|
|
41
|
+
await el.updateComplete;
|
|
42
|
+
|
|
43
|
+
expect(el.shadowRoot?.querySelector('.empty-query')).to.not.exist;
|
|
44
|
+
expect(el.shadowRoot?.querySelector('.null-result')).to.not.exist;
|
|
45
|
+
expect(el.shadowRoot?.querySelector('collection-facets')).to.not.exist;
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/* eslint-disable import/no-duplicates */
|
|
2
|
+
import { expect, fixture } from '@open-wc/testing';
|
|
3
|
+
import { html } from 'lit';
|
|
4
|
+
import type { IconOverlay } from '../src/tiles/overlay/icon-overlay';
|
|
5
|
+
|
|
6
|
+
import '../src/tiles/overlay/icon-overlay';
|
|
7
|
+
|
|
8
|
+
describe('Icon Overlay component', () => {
|
|
9
|
+
it('should render component if loggedIn required', async () => {
|
|
10
|
+
const el = await fixture<IconOverlay>(html`
|
|
11
|
+
<icon-overlay .loggedIn=${false} .loginRequired=${true}> </icon-overlay>
|
|
12
|
+
`);
|
|
13
|
+
|
|
14
|
+
const svgTitle = el.shadowRoot
|
|
15
|
+
?.querySelector('svg')
|
|
16
|
+
?.querySelector('title')?.textContent;
|
|
17
|
+
expect(svgTitle).to.equal('Log in to view this item');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should render component if content warning', async () => {
|
|
21
|
+
const el = await fixture<IconOverlay>(html`
|
|
22
|
+
<icon-overlay .loggedIn=${false} .loginRequired=${false}> </icon-overlay>
|
|
23
|
+
`);
|
|
24
|
+
|
|
25
|
+
const svgTitle = el.shadowRoot
|
|
26
|
+
?.querySelector('svg')
|
|
27
|
+
?.querySelector('title')?.textContent;
|
|
28
|
+
expect(svgTitle).to.equal('Content may be inappropriate');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should render component if content warning', async () => {
|
|
32
|
+
const el = await fixture<IconOverlay>(html`
|
|
33
|
+
<icon-overlay .loggedIn=${true} .loginRequired=${true}> </icon-overlay>
|
|
34
|
+
`);
|
|
35
|
+
|
|
36
|
+
const svgTitle = el.shadowRoot
|
|
37
|
+
?.querySelector('svg')
|
|
38
|
+
?.querySelector('title')?.textContent;
|
|
39
|
+
expect(svgTitle).to.equal('Content may be inappropriate');
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/* eslint-disable import/no-duplicates */
|
|
2
|
+
import { expect, fixture } from '@open-wc/testing';
|
|
3
|
+
import { html } from 'lit';
|
|
4
|
+
|
|
5
|
+
import type { TileModel } from '../src/models';
|
|
6
|
+
import type { ItemImage } from '../src/tiles/item-image';
|
|
7
|
+
|
|
8
|
+
import '../src/tiles/item-image';
|
|
9
|
+
|
|
10
|
+
const baseImageUrl = 'https://archive.org';
|
|
11
|
+
const testBookModel: TileModel = {
|
|
12
|
+
collections: [],
|
|
13
|
+
commentCount: 0,
|
|
14
|
+
creators: [],
|
|
15
|
+
favCount: 0,
|
|
16
|
+
identifier: '18730130BloomfieldRecordCompleteIssue',
|
|
17
|
+
itemCount: 0,
|
|
18
|
+
mediatype: 'texts',
|
|
19
|
+
subjects: [],
|
|
20
|
+
title: 'Sample Waveform',
|
|
21
|
+
viewCount: 0,
|
|
22
|
+
loginRequired: false,
|
|
23
|
+
contentWarning: false,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const testAudioModel: TileModel = {
|
|
27
|
+
collections: [],
|
|
28
|
+
commentCount: 0,
|
|
29
|
+
creators: [],
|
|
30
|
+
favCount: 0,
|
|
31
|
+
identifier: 'dwd2015-01-24',
|
|
32
|
+
itemCount: 0,
|
|
33
|
+
mediatype: 'audio',
|
|
34
|
+
subjects: [],
|
|
35
|
+
title: 'Sample Waveform',
|
|
36
|
+
viewCount: 0,
|
|
37
|
+
loginRequired: false,
|
|
38
|
+
contentWarning: false,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
describe('ItemImage component', () => {
|
|
42
|
+
it('should render initial component', async () => {
|
|
43
|
+
const el = await fixture<ItemImage>(html`
|
|
44
|
+
<item-image
|
|
45
|
+
.isListTile=${false}
|
|
46
|
+
.isCompactTile=${false}
|
|
47
|
+
.model=${testBookModel}
|
|
48
|
+
.baseImageUrl=${baseImageUrl}
|
|
49
|
+
>
|
|
50
|
+
</item-image>
|
|
51
|
+
`);
|
|
52
|
+
|
|
53
|
+
const dropShadow = el.shadowRoot?.querySelector('.drop-shadow');
|
|
54
|
+
const imgClassName = dropShadow?.querySelector('img')?.className;
|
|
55
|
+
|
|
56
|
+
expect(dropShadow).to.exist;
|
|
57
|
+
expect(imgClassName).to.eql(' contain ');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should render component if mediatype is waveform', async () => {
|
|
61
|
+
const el = await fixture<ItemImage>(html`
|
|
62
|
+
<item-image
|
|
63
|
+
.isListTile=${false}
|
|
64
|
+
.isCompactTile=${false}
|
|
65
|
+
.model=${testAudioModel}
|
|
66
|
+
.baseImageUrl=${baseImageUrl}
|
|
67
|
+
>
|
|
68
|
+
</item-image>
|
|
69
|
+
`);
|
|
70
|
+
|
|
71
|
+
const dropShadow = el.shadowRoot?.querySelector('.drop-shadow');
|
|
72
|
+
const image = dropShadow?.querySelector('img');
|
|
73
|
+
expect(dropShadow).to.exist;
|
|
74
|
+
expect(image).to.exist;
|
|
75
|
+
|
|
76
|
+
// simulate image onLoad event check if image className is waveform
|
|
77
|
+
setTimeout(() => {
|
|
78
|
+
const imgClassName = image?.className;
|
|
79
|
+
expect(imgClassName).to.eql(' waveform ');
|
|
80
|
+
}, 1000);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CollectionNameCacheInterface } from '@internetarchive/collection-name-cache';
|
|
1
|
+
import type { CollectionNameCacheInterface } from '@internetarchive/collection-name-cache';
|
|
2
2
|
|
|
3
3
|
export class MockCollectionNameCache implements CollectionNameCacheInterface {
|
|
4
4
|
collectionNamesRequested: string[] = [];
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/* eslint-disable import/no-duplicates */
|
|
2
|
+
import { expect, fixture } from '@open-wc/testing';
|
|
3
|
+
import { html } from 'lit';
|
|
4
|
+
import type { TextOverlay } from '../src/tiles/overlay/text-overlay';
|
|
5
|
+
|
|
6
|
+
import '../src/tiles/overlay/text-overlay';
|
|
7
|
+
|
|
8
|
+
describe('Text Overlay component', () => {
|
|
9
|
+
it('should render initial component', async () => {
|
|
10
|
+
const el = await fixture<TextOverlay>(html`<text-overlay></text-overlay>`);
|
|
11
|
+
|
|
12
|
+
const overlay = el.shadowRoot?.querySelector('.overlay');
|
|
13
|
+
const noPreview = el.shadowRoot?.querySelector('.no-preview');
|
|
14
|
+
|
|
15
|
+
expect(overlay).to.exist;
|
|
16
|
+
expect(noPreview).to.exist;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should render component if loggedIn required', async () => {
|
|
20
|
+
const el = await fixture<TextOverlay>(html`
|
|
21
|
+
<text-overlay .loggedIn=${false} .loginRequired=${true}> </text-overlay>
|
|
22
|
+
`);
|
|
23
|
+
|
|
24
|
+
const overlay = el.shadowRoot?.querySelector('.overlay');
|
|
25
|
+
const noPreview = el.shadowRoot?.querySelector('.no-preview');
|
|
26
|
+
|
|
27
|
+
expect(overlay).to.exist;
|
|
28
|
+
expect(noPreview).to.exist;
|
|
29
|
+
expect(noPreview?.textContent).to.equal('Log in\nto view this item');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should render component if content warning', async () => {
|
|
33
|
+
const el = await fixture<TextOverlay>(html`
|
|
34
|
+
<text-overlay .loggedIn=${false} .loginRequired=${false}> </text-overlay>
|
|
35
|
+
`);
|
|
36
|
+
|
|
37
|
+
const overlay = el.shadowRoot?.querySelector('.overlay');
|
|
38
|
+
const noPreview = el.shadowRoot?.querySelector('.no-preview');
|
|
39
|
+
|
|
40
|
+
expect(overlay).to.exist;
|
|
41
|
+
expect(noPreview).to.exist;
|
|
42
|
+
expect(noPreview?.textContent).to.equal('Content may be inappropriate');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should render component if content warning', async () => {
|
|
46
|
+
const el = await fixture<TextOverlay>(html`
|
|
47
|
+
<text-overlay .loggedIn=${true} .loginRequired=${true}> </text-overlay>
|
|
48
|
+
`);
|
|
49
|
+
|
|
50
|
+
const overlay = el.shadowRoot?.querySelector('.overlay');
|
|
51
|
+
const noPreview = el.shadowRoot?.querySelector('.no-preview');
|
|
52
|
+
|
|
53
|
+
expect(overlay).to.exist;
|
|
54
|
+
expect(noPreview).to.exist;
|
|
55
|
+
expect(noPreview?.textContent).to.equal('Content may be inappropriate');
|
|
56
|
+
});
|
|
57
|
+
});
|
package/test/tile-stats.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable import/no-duplicates */
|
|
2
2
|
import { expect, fixture } from '@open-wc/testing';
|
|
3
3
|
import { html } from 'lit';
|
|
4
|
-
import { TileStats } from '../src/tiles/grid/tile-stats';
|
|
4
|
+
import type { TileStats } from '../src/tiles/grid/tile-stats';
|
|
5
5
|
|
|
6
6
|
import '../src/tiles/grid/tile-stats';
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable import/no-duplicates */
|
|
2
2
|
import { expect, fixture } from '@open-wc/testing';
|
|
3
3
|
import { html } from 'lit';
|
|
4
|
-
import { ItemTile } from '../../../src/tiles/grid/item-tile';
|
|
4
|
+
import type { ItemTile } from '../../../src/tiles/grid/item-tile';
|
|
5
5
|
|
|
6
6
|
import '../../../src/tiles/grid/item-tile';
|
|
7
7
|
|
|
@@ -10,11 +10,11 @@ describe('Item Tile', () => {
|
|
|
10
10
|
const el = await fixture<ItemTile>(html`<item-tile></item-tile>`);
|
|
11
11
|
|
|
12
12
|
const itemInfo = el.shadowRoot?.querySelector('.item-info');
|
|
13
|
-
const itemImage = el.shadowRoot?.querySelector('item-image');
|
|
14
13
|
const itemTitle = el.shadowRoot?.querySelector('#title');
|
|
14
|
+
const imageBlock = el.shadowRoot?.querySelector('image-block');
|
|
15
15
|
|
|
16
16
|
expect(itemInfo).to.exist;
|
|
17
|
-
expect(
|
|
17
|
+
expect(imageBlock).to.exist;
|
|
18
18
|
expect(itemTitle).to.exist;
|
|
19
19
|
});
|
|
20
20
|
|
package/tsconfig.json
CHANGED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { html, LitElement } from 'lit';
|
|
2
|
-
import { customElement, property } from 'lit/decorators.js';
|
|
3
|
-
|
|
4
|
-
import { TileModel } from '../models';
|
|
5
|
-
|
|
6
|
-
import './image/item-image';
|
|
7
|
-
import './image/waveform-image';
|
|
8
|
-
|
|
9
|
-
@customElement('item-tile-image')
|
|
10
|
-
export class ItemTileImage extends LitElement {
|
|
11
|
-
@property({ type: Object }) model?: TileModel;
|
|
12
|
-
|
|
13
|
-
@property({ type: String }) baseImageUrl?: string;
|
|
14
|
-
|
|
15
|
-
@property({ type: Boolean }) isListTile = false;
|
|
16
|
-
|
|
17
|
-
@property({ type: Boolean }) isCompactTile = false;
|
|
18
|
-
|
|
19
|
-
render() {
|
|
20
|
-
return html`
|
|
21
|
-
${this.isWithWaveformMediatype
|
|
22
|
-
? this.waveformImageTemplate
|
|
23
|
-
: this.itemImageTemplate}
|
|
24
|
-
`;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
private get imageSrc() {
|
|
28
|
-
return `${this.baseImageUrl}/services/img/${this.model?.identifier}`;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
private get isWithWaveformMediatype() {
|
|
32
|
-
return (
|
|
33
|
-
this.model?.mediatype === 'audio' || this.model?.mediatype === 'etree'
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Templates
|
|
38
|
-
private get itemImageTemplate() {
|
|
39
|
-
return html`
|
|
40
|
-
<item-image
|
|
41
|
-
.model=${this.model}
|
|
42
|
-
.imageSrc=${this.imageSrc}
|
|
43
|
-
.isCompactTile=${this.isCompactTile}
|
|
44
|
-
.isListTile=${this.isListTile}
|
|
45
|
-
>
|
|
46
|
-
</item-image>
|
|
47
|
-
`;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
private get waveformImageTemplate() {
|
|
51
|
-
return html`
|
|
52
|
-
<waveform-image
|
|
53
|
-
.imageSrc=${this.imageSrc}
|
|
54
|
-
.identifier=${this.model?.identifier}
|
|
55
|
-
.isCompactTile=${this.isCompactTile}
|
|
56
|
-
.isListTile=${this.isListTile}
|
|
57
|
-
>
|
|
58
|
-
</waveform-image>
|
|
59
|
-
`;
|
|
60
|
-
}
|
|
61
|
-
}
|