@internetarchive/collection-browser 4.1.1-alpha-webdev8185.1 → 4.1.2-alpha-webdev8332.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/src/collection-browser.d.ts +18 -9
- package/dist/src/collection-browser.js +77 -18
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/data-source/collection-browser-data-source.js +3 -2
- package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
- package/dist/src/data-source/collection-browser-query-state.d.ts +3 -5
- package/dist/src/data-source/collection-browser-query-state.js.map +1 -1
- package/dist/src/models.d.ts +2 -27
- package/dist/src/models.js +0 -36
- package/dist/src/models.js.map +1 -1
- package/dist/src/restoration-state-handler.js +9 -3
- package/dist/src/restoration-state-handler.js.map +1 -1
- package/dist/src/sort-filter-bar/sort-filter-bar.d.ts +2 -2
- package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
- package/dist/src/tiles/hover/hover-pane-controller.js +2 -1
- package/dist/src/tiles/hover/hover-pane-controller.js.map +1 -1
- package/dist/src/tiles/tile-dispatcher.d.ts +6 -0
- package/dist/src/tiles/tile-dispatcher.js +11 -3
- package/dist/src/tiles/tile-dispatcher.js.map +1 -1
- package/dist/test/collection-browser.test.js +17 -15
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/tiles/tile-dispatcher.test.js +14 -0
- package/dist/test/tiles/tile-dispatcher.test.js.map +1 -1
- package/index.ts +0 -5
- package/package.json +1 -1
- package/src/collection-browser.ts +94 -25
- package/src/data-source/collection-browser-data-source.ts +3 -2
- package/src/data-source/collection-browser-query-state.ts +3 -12
- package/src/models.ts +4 -53
- package/src/restoration-state-handler.ts +7 -3
- package/src/sort-filter-bar/sort-filter-bar.ts +4 -3
- package/src/tiles/hover/hover-pane-controller.ts +2 -1
- package/src/tiles/tile-dispatcher.ts +12 -3
- package/test/collection-browser.test.ts +17 -15
- package/test/tiles/tile-dispatcher.test.ts +17 -0
|
@@ -159,6 +159,20 @@ describe('Tile Dispatcher', () => {
|
|
|
159
159
|
await el.updateComplete;
|
|
160
160
|
expect(el.getHoverPane()).not.to.exist;
|
|
161
161
|
});
|
|
162
|
+
it('should not show info button when hover pane is not enabled', async () => {
|
|
163
|
+
const el = await fixture(html `
|
|
164
|
+
<tile-dispatcher
|
|
165
|
+
.tileDisplayMode=${'grid'}
|
|
166
|
+
.model=${{ mediatype: 'texts' }}
|
|
167
|
+
.enableHoverPane=${false}
|
|
168
|
+
>
|
|
169
|
+
</tile-dispatcher>
|
|
170
|
+
`);
|
|
171
|
+
const itemTile = el.shadowRoot?.querySelector('item-tile');
|
|
172
|
+
expect(itemTile).to.exist;
|
|
173
|
+
const infoButton = itemTile.shadowRoot?.querySelector('.info-button');
|
|
174
|
+
expect(infoButton).to.not.exist;
|
|
175
|
+
});
|
|
162
176
|
});
|
|
163
177
|
describe('Accessibility', () => {
|
|
164
178
|
it('should have proper aria-label on tile link', async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tile-dispatcher.test.js","sourceRoot":"","sources":["../../../test/tiles/tile-dispatcher.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { aTimeout, expect, fixture } from '@open-wc/testing';\nimport { html } from 'lit';\nimport sinon from 'sinon';\nimport type { TileDispatcher } from '../../src/tiles/tile-dispatcher';\n\nimport '../../src/tiles/tile-dispatcher';\nimport type { ItemTile } from '../../src/tiles/grid/item-tile';\nimport { TileHoverPane } from '../../src/tiles/hover/tile-hover-pane';\nimport type { HoverPaneProperties } from '../../src/tiles/hover/hover-pane-controller';\n\ndescribe('Tile Dispatcher', () => {\n it('should render item-tile for grid mode by default', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{ mediatype: 'texts' }}\n >\n </tile-dispatcher>\n `);\n\n const itemTile = el.shadowRoot?.querySelector('item-tile');\n expect(itemTile).to.exist;\n });\n\n it('should render collection-tile for grid mode and collection mediatype', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{ mediatype: 'collection' }}\n >\n </tile-dispatcher>\n `);\n\n const collectionTile = el.shadowRoot?.querySelector('collection-tile');\n expect(collectionTile).to.exist;\n });\n\n it('should render account-tile for grid mode and account mediatype', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{ mediatype: 'account' }}\n >\n </tile-dispatcher>\n `);\n\n const accountTile = el.shadowRoot?.querySelector('account-tile');\n expect(accountTile).to.exist;\n });\n\n it('should render search-tile for grid mode and search mediatype', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{ mediatype: 'search' }}\n >\n </tile-dispatcher>\n `);\n\n const searchTile = el.shadowRoot?.querySelector('search-tile');\n expect(searchTile).to.exist;\n });\n\n it('should render tile-list for extended list mode', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher .tileDisplayMode=${'list-detail'} .model=${{}}>\n </tile-dispatcher>\n `);\n\n const listTile = el.shadowRoot?.querySelector('tile-list');\n expect(listTile).to.exist;\n });\n\n it('should render tile-list-compact for compact list mode', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher .tileDisplayMode=${'list-compact'} .model=${{}}>\n </tile-dispatcher>\n `);\n\n const compactListTile = el.shadowRoot?.querySelector('tile-list-compact');\n expect(compactListTile).to.exist;\n });\n\n it('should open item in new tab when right-clicked in manage mode', async () => {\n const oldWindowOpen = window.open;\n const spy = sinon.spy();\n window.open = spy;\n\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n isManageView\n .model=${{ identifier: 'foo', href: '/foo' }}\n .baseNavigationUrl=${''}\n >\n </tile-dispatcher>\n `);\n\n const tileLink = el.shadowRoot?.querySelector(\n 'a[href]',\n ) as HTMLAnchorElement;\n expect(tileLink).to.exist;\n\n tileLink.dispatchEvent(new Event('contextmenu'));\n await el.updateComplete;\n\n expect(spy.callCount).to.equal(1);\n expect(spy.args[0][0]).to.equal('/foo');\n expect(spy.args[0][1]).to.equal('_blank');\n\n window.open = oldWindowOpen;\n });\n\n it('should toggle model checked state when manage check clicked', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n isManageView\n .model=${{ identifier: 'foo', href: '/foo' }}\n .tileDisplayMode=${'grid'}\n ></tile-dispatcher>\n `);\n\n const manageCheck = el.shadowRoot?.querySelector(\n '.manage-check > input[type=\"checkbox\"]',\n ) as HTMLButtonElement;\n\n manageCheck.click();\n await el.updateComplete;\n expect(el.model?.checked).to.be.true;\n\n manageCheck.click();\n await el.updateComplete;\n expect(el.model?.checked).to.be.false;\n });\n\n it('should return hover pane props', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher .model=${{ identifier: 'foo' }}> </tile-dispatcher>\n `);\n\n expect(el.getHoverPaneProps()).to.satisfy(\n (props: HoverPaneProperties) => props?.model?.identifier === 'foo',\n );\n });\n\n it('should focus the tile link when requested', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher .tileDisplayMode=${'grid'}> </tile-dispatcher>\n `);\n\n const tileLink = el.shadowRoot?.querySelector(\n '.tile-link',\n ) as HTMLAnchorElement;\n expect(tileLink).to.exist;\n\n const spyFocus = sinon.spy(tileLink, 'focus');\n el.acquireFocus();\n expect(spyFocus.callCount).to.equal(1);\n });\n\n it('should blur the tile link when requested', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher .tileDisplayMode=${'grid'}> </tile-dispatcher>\n `);\n\n const tileLink = el.shadowRoot?.querySelector(\n '.tile-link',\n ) as HTMLAnchorElement;\n expect(tileLink).to.exist;\n\n const spyBlur = sinon.spy(tileLink, 'blur');\n el.releaseFocus();\n expect(spyBlur.callCount).to.equal(1);\n });\n\n describe('Hover pane info button behavior', () => {\n let oldMatchMedia: typeof window.matchMedia;\n\n before(() => {\n oldMatchMedia = window.matchMedia;\n // Pretend that there is no hover-capable input device\n window.matchMedia = () => ({ matches: false }) as MediaQueryList;\n });\n\n after(() => {\n window.matchMedia = oldMatchMedia;\n });\n\n it('should toggle hover pane when tile info button is pressed', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{ mediatype: 'texts' }}\n .enableHoverPane=${true}\n >\n </tile-dispatcher>\n `);\n\n const itemTile = el.shadowRoot?.querySelector('item-tile') as ItemTile;\n expect(itemTile).to.exist;\n\n const infoButton = itemTile.shadowRoot?.querySelector(\n '.info-button',\n ) as HTMLButtonElement;\n expect(infoButton).to.exist;\n\n infoButton.click();\n await aTimeout(500);\n await el.updateComplete;\n expect(el.getHoverPane()).to.be.instanceOf(TileHoverPane);\n\n infoButton.click();\n await aTimeout(500);\n await el.updateComplete;\n expect(el.getHoverPane()).not.to.exist;\n });\n });\n\n describe('Accessibility', () => {\n it('should have proper aria-label on tile link', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{\n title: 'Example Title',\n mediatype: 'texts',\n }}\n >\n </tile-dispatcher>\n `);\n\n const tileLink = el.shadowRoot?.querySelector(\n '.tile-link',\n ) as HTMLAnchorElement;\n expect(tileLink).to.exist;\n expect(tileLink.getAttribute('aria-label')).to.equal('Example Title');\n });\n\n it('should fallback to untitled aria-label on tile link when no title', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{\n mediatype: 'texts',\n }}\n >\n </tile-dispatcher>\n `);\n\n const tileLink = el.shadowRoot?.querySelector(\n '.tile-link',\n ) as HTMLAnchorElement;\n expect(tileLink).to.exist;\n expect(tileLink.getAttribute('aria-label')).to.equal('Untitled item');\n });\n\n it('should have no accessibility violations in grid mode', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{\n title: 'Example Title',\n mediatype: 'texts',\n }}\n >\n </tile-dispatcher>\n `);\n\n await expect(el).to.be.accessible();\n });\n\n it('should have no accessibility violations in list mode', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'list-detail'}\n .model=${{ mediatype: 'texts' }}\n >\n </tile-dispatcher>\n `);\n\n await expect(el).to.be.accessible();\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"tile-dispatcher.test.js","sourceRoot":"","sources":["../../../test/tiles/tile-dispatcher.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { aTimeout, expect, fixture } from '@open-wc/testing';\nimport { html } from 'lit';\nimport sinon from 'sinon';\nimport type { TileDispatcher } from '../../src/tiles/tile-dispatcher';\n\nimport '../../src/tiles/tile-dispatcher';\nimport type { ItemTile } from '../../src/tiles/grid/item-tile';\nimport { TileHoverPane } from '../../src/tiles/hover/tile-hover-pane';\nimport type { HoverPaneProperties } from '../../src/tiles/hover/hover-pane-controller';\n\ndescribe('Tile Dispatcher', () => {\n it('should render item-tile for grid mode by default', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{ mediatype: 'texts' }}\n >\n </tile-dispatcher>\n `);\n\n const itemTile = el.shadowRoot?.querySelector('item-tile');\n expect(itemTile).to.exist;\n });\n\n it('should render collection-tile for grid mode and collection mediatype', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{ mediatype: 'collection' }}\n >\n </tile-dispatcher>\n `);\n\n const collectionTile = el.shadowRoot?.querySelector('collection-tile');\n expect(collectionTile).to.exist;\n });\n\n it('should render account-tile for grid mode and account mediatype', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{ mediatype: 'account' }}\n >\n </tile-dispatcher>\n `);\n\n const accountTile = el.shadowRoot?.querySelector('account-tile');\n expect(accountTile).to.exist;\n });\n\n it('should render search-tile for grid mode and search mediatype', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{ mediatype: 'search' }}\n >\n </tile-dispatcher>\n `);\n\n const searchTile = el.shadowRoot?.querySelector('search-tile');\n expect(searchTile).to.exist;\n });\n\n it('should render tile-list for extended list mode', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher .tileDisplayMode=${'list-detail'} .model=${{}}>\n </tile-dispatcher>\n `);\n\n const listTile = el.shadowRoot?.querySelector('tile-list');\n expect(listTile).to.exist;\n });\n\n it('should render tile-list-compact for compact list mode', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher .tileDisplayMode=${'list-compact'} .model=${{}}>\n </tile-dispatcher>\n `);\n\n const compactListTile = el.shadowRoot?.querySelector('tile-list-compact');\n expect(compactListTile).to.exist;\n });\n\n it('should open item in new tab when right-clicked in manage mode', async () => {\n const oldWindowOpen = window.open;\n const spy = sinon.spy();\n window.open = spy;\n\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n isManageView\n .model=${{ identifier: 'foo', href: '/foo' }}\n .baseNavigationUrl=${''}\n >\n </tile-dispatcher>\n `);\n\n const tileLink = el.shadowRoot?.querySelector(\n 'a[href]',\n ) as HTMLAnchorElement;\n expect(tileLink).to.exist;\n\n tileLink.dispatchEvent(new Event('contextmenu'));\n await el.updateComplete;\n\n expect(spy.callCount).to.equal(1);\n expect(spy.args[0][0]).to.equal('/foo');\n expect(spy.args[0][1]).to.equal('_blank');\n\n window.open = oldWindowOpen;\n });\n\n it('should toggle model checked state when manage check clicked', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n isManageView\n .model=${{ identifier: 'foo', href: '/foo' }}\n .tileDisplayMode=${'grid'}\n ></tile-dispatcher>\n `);\n\n const manageCheck = el.shadowRoot?.querySelector(\n '.manage-check > input[type=\"checkbox\"]',\n ) as HTMLButtonElement;\n\n manageCheck.click();\n await el.updateComplete;\n expect(el.model?.checked).to.be.true;\n\n manageCheck.click();\n await el.updateComplete;\n expect(el.model?.checked).to.be.false;\n });\n\n it('should return hover pane props', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher .model=${{ identifier: 'foo' }}> </tile-dispatcher>\n `);\n\n expect(el.getHoverPaneProps()).to.satisfy(\n (props: HoverPaneProperties) => props?.model?.identifier === 'foo',\n );\n });\n\n it('should focus the tile link when requested', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher .tileDisplayMode=${'grid'}> </tile-dispatcher>\n `);\n\n const tileLink = el.shadowRoot?.querySelector(\n '.tile-link',\n ) as HTMLAnchorElement;\n expect(tileLink).to.exist;\n\n const spyFocus = sinon.spy(tileLink, 'focus');\n el.acquireFocus();\n expect(spyFocus.callCount).to.equal(1);\n });\n\n it('should blur the tile link when requested', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher .tileDisplayMode=${'grid'}> </tile-dispatcher>\n `);\n\n const tileLink = el.shadowRoot?.querySelector(\n '.tile-link',\n ) as HTMLAnchorElement;\n expect(tileLink).to.exist;\n\n const spyBlur = sinon.spy(tileLink, 'blur');\n el.releaseFocus();\n expect(spyBlur.callCount).to.equal(1);\n });\n\n describe('Hover pane info button behavior', () => {\n let oldMatchMedia: typeof window.matchMedia;\n\n before(() => {\n oldMatchMedia = window.matchMedia;\n // Pretend that there is no hover-capable input device\n window.matchMedia = () => ({ matches: false }) as MediaQueryList;\n });\n\n after(() => {\n window.matchMedia = oldMatchMedia;\n });\n\n it('should toggle hover pane when tile info button is pressed', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{ mediatype: 'texts' }}\n .enableHoverPane=${true}\n >\n </tile-dispatcher>\n `);\n\n const itemTile = el.shadowRoot?.querySelector('item-tile') as ItemTile;\n expect(itemTile).to.exist;\n\n const infoButton = itemTile.shadowRoot?.querySelector(\n '.info-button',\n ) as HTMLButtonElement;\n expect(infoButton).to.exist;\n\n infoButton.click();\n await aTimeout(500);\n await el.updateComplete;\n expect(el.getHoverPane()).to.be.instanceOf(TileHoverPane);\n\n infoButton.click();\n await aTimeout(500);\n await el.updateComplete;\n expect(el.getHoverPane()).not.to.exist;\n });\n\n it('should not show info button when hover pane is not enabled', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{ mediatype: 'texts' }}\n .enableHoverPane=${false}\n >\n </tile-dispatcher>\n `);\n\n const itemTile = el.shadowRoot?.querySelector('item-tile') as ItemTile;\n expect(itemTile).to.exist;\n\n const infoButton = itemTile.shadowRoot?.querySelector('.info-button');\n expect(infoButton).to.not.exist;\n });\n });\n\n describe('Accessibility', () => {\n it('should have proper aria-label on tile link', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{\n title: 'Example Title',\n mediatype: 'texts',\n }}\n >\n </tile-dispatcher>\n `);\n\n const tileLink = el.shadowRoot?.querySelector(\n '.tile-link',\n ) as HTMLAnchorElement;\n expect(tileLink).to.exist;\n expect(tileLink.getAttribute('aria-label')).to.equal('Example Title');\n });\n\n it('should fallback to untitled aria-label on tile link when no title', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{\n mediatype: 'texts',\n }}\n >\n </tile-dispatcher>\n `);\n\n const tileLink = el.shadowRoot?.querySelector(\n '.tile-link',\n ) as HTMLAnchorElement;\n expect(tileLink).to.exist;\n expect(tileLink.getAttribute('aria-label')).to.equal('Untitled item');\n });\n\n it('should have no accessibility violations in grid mode', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'grid'}\n .model=${{\n title: 'Example Title',\n mediatype: 'texts',\n }}\n >\n </tile-dispatcher>\n `);\n\n await expect(el).to.be.accessible();\n });\n\n it('should have no accessibility violations in list mode', async () => {\n const el = await fixture<TileDispatcher>(html`\n <tile-dispatcher\n .tileDisplayMode=${'list-detail'}\n .model=${{ mediatype: 'texts' }}\n >\n </tile-dispatcher>\n `);\n\n await expect(el).to.be.accessible();\n });\n });\n});\n"]}
|
package/index.ts
CHANGED
|
@@ -6,15 +6,10 @@ export { SortFilterBar } from './src/sort-filter-bar/sort-filter-bar';
|
|
|
6
6
|
export {
|
|
7
7
|
CollectionDisplayMode,
|
|
8
8
|
SortField,
|
|
9
|
-
ExplicitSortField,
|
|
10
9
|
TileModel,
|
|
11
10
|
FacetOption,
|
|
12
11
|
SelectedFacets,
|
|
13
12
|
getDefaultSelectedFacets,
|
|
14
|
-
sortOptionFromAPIString,
|
|
15
|
-
resolveCollectionDefaultSort,
|
|
16
|
-
SORT_OPTIONS,
|
|
17
|
-
defaultProfileElementSorts,
|
|
18
13
|
} from './src/models';
|
|
19
14
|
export { CollectionBrowserLoadingTile } from './src/tiles/collection-browser-loading-tile';
|
|
20
15
|
export { CollectionTile } from './src/tiles/grid/collection-tile';
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "The Internet Archive Collection Browser.",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"author": "Internet Archive",
|
|
6
|
-
"version": "4.1.
|
|
6
|
+
"version": "4.1.2-alpha-webdev8332.0",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"module": "dist/index.js",
|
|
9
9
|
"scripts": {
|
|
@@ -36,13 +36,14 @@ import type { IAComboBox } from '@internetarchive/elements/ia-combo-box/ia-combo
|
|
|
36
36
|
import {
|
|
37
37
|
SelectedFacets,
|
|
38
38
|
SortField,
|
|
39
|
-
type ExplicitSortField,
|
|
40
39
|
CollectionBrowserContext,
|
|
41
40
|
getDefaultSelectedFacets,
|
|
42
41
|
TileModel,
|
|
43
42
|
CollectionDisplayMode,
|
|
44
43
|
FacetEventDetails,
|
|
44
|
+
sortOptionFromAPIString,
|
|
45
45
|
SORT_OPTIONS,
|
|
46
|
+
defaultProfileElementSorts,
|
|
46
47
|
FacetLoadStrategy,
|
|
47
48
|
defaultFacetDisplayOrder,
|
|
48
49
|
tvFacetDisplayOrder,
|
|
@@ -150,8 +151,10 @@ export class CollectionBrowser
|
|
|
150
151
|
|
|
151
152
|
@property({ type: String }) sortDirection: SortDirection | null = null;
|
|
152
153
|
|
|
153
|
-
@property({ type: String }) defaultSortField:
|
|
154
|
-
SortField
|
|
154
|
+
@property({ type: String }) defaultSortField: Exclude<
|
|
155
|
+
SortField,
|
|
156
|
+
SortField.default
|
|
157
|
+
> = SortField.relevance;
|
|
155
158
|
|
|
156
159
|
@property({ type: String }) defaultSortDirection: SortDirection | null = null;
|
|
157
160
|
|
|
@@ -598,6 +601,10 @@ export class CollectionBrowser
|
|
|
598
601
|
|
|
599
602
|
willUpdate(changed: PropertyValues): void {
|
|
600
603
|
this.setPlaceholderType();
|
|
604
|
+
|
|
605
|
+
if (changed.has('searchType') && this.searchType === SearchType.TV) {
|
|
606
|
+
this.applyDefaultTVSearchSort();
|
|
607
|
+
}
|
|
601
608
|
}
|
|
602
609
|
|
|
603
610
|
render() {
|
|
@@ -1639,12 +1646,6 @@ export class CollectionBrowser
|
|
|
1639
1646
|
this.maxSelectedDate = queryState.maxSelectedDate;
|
|
1640
1647
|
this.selectedSort = queryState.selectedSort ?? SortField.default;
|
|
1641
1648
|
this.sortDirection = queryState.sortDirection;
|
|
1642
|
-
if (queryState.defaultSortField) {
|
|
1643
|
-
this.defaultSortField = queryState.defaultSortField;
|
|
1644
|
-
}
|
|
1645
|
-
if (queryState.defaultSortDirection !== undefined) {
|
|
1646
|
-
this.defaultSortDirection = queryState.defaultSortDirection;
|
|
1647
|
-
}
|
|
1648
1649
|
this.selectedTitleFilter = queryState.selectedTitleFilter;
|
|
1649
1650
|
this.selectedCreatorFilter = queryState.selectedCreatorFilter;
|
|
1650
1651
|
|
|
@@ -1755,6 +1756,21 @@ export class CollectionBrowser
|
|
|
1755
1756
|
}
|
|
1756
1757
|
}
|
|
1757
1758
|
|
|
1759
|
+
if (changed.has('profileElement')) {
|
|
1760
|
+
this.applyDefaultProfileSort();
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
if (changed.has('withinCollection') && this.withinCollection) {
|
|
1764
|
+
// Set a sensible default collection sort while we load results, which we will later
|
|
1765
|
+
// adjust based on any sort-by metadata once the response arrives.
|
|
1766
|
+
if (!this.baseQuery) {
|
|
1767
|
+
this.defaultSortField = this.withinCollection.startsWith('fav-')
|
|
1768
|
+
? SortField.datefavorited
|
|
1769
|
+
: SortField.weeklyview;
|
|
1770
|
+
this.defaultSortDirection = 'desc';
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1758
1774
|
if (changed.has('baseQuery')) {
|
|
1759
1775
|
this.emitBaseQueryChanged();
|
|
1760
1776
|
}
|
|
@@ -2067,22 +2083,6 @@ export class CollectionBrowser
|
|
|
2067
2083
|
);
|
|
2068
2084
|
}
|
|
2069
2085
|
|
|
2070
|
-
/**
|
|
2071
|
-
* Emits a `collectionExtraInfoLoaded` event when the data source has received
|
|
2072
|
-
* collection metadata from the backend. This allows parent components to react
|
|
2073
|
-
* to the metadata (e.g., to update their default sort based on the collection's
|
|
2074
|
-
* `sort-by` metadata field).
|
|
2075
|
-
*/
|
|
2076
|
-
emitCollectionExtraInfoLoaded(
|
|
2077
|
-
collectionExtraInfo?: CollectionExtraInfo,
|
|
2078
|
-
): void {
|
|
2079
|
-
this.dispatchEvent(
|
|
2080
|
-
new CustomEvent('collectionExtraInfoLoaded', {
|
|
2081
|
-
detail: collectionExtraInfo,
|
|
2082
|
-
}),
|
|
2083
|
-
);
|
|
2084
|
-
}
|
|
2085
|
-
|
|
2086
2086
|
/**
|
|
2087
2087
|
* Emits a `queryStateChanged` event indicating that one or more of this component's
|
|
2088
2088
|
* properties have changed in a way that could affect the set of search results.
|
|
@@ -2382,6 +2382,75 @@ export class CollectionBrowser
|
|
|
2382
2382
|
}
|
|
2383
2383
|
}
|
|
2384
2384
|
|
|
2385
|
+
/**
|
|
2386
|
+
* Applies the default sort options for the TV search results page
|
|
2387
|
+
*/
|
|
2388
|
+
applyDefaultTVSearchSort(): void {
|
|
2389
|
+
this.defaultSortField = SortField.datearchived;
|
|
2390
|
+
this.defaultSortDirection = 'desc';
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
/**
|
|
2394
|
+
* Applies any default sort option for the current collection, by checking
|
|
2395
|
+
* for one in the collection's metadata. If none is found, defaults to sorting
|
|
2396
|
+
* descending by:
|
|
2397
|
+
* - Date Favorited for fav-* collections
|
|
2398
|
+
* - Weekly views for all other collections
|
|
2399
|
+
*/
|
|
2400
|
+
applyDefaultCollectionSort(collectionInfo?: CollectionExtraInfo): void {
|
|
2401
|
+
if (this.baseQuery) {
|
|
2402
|
+
// If there's a query set, then we default to relevance sorting regardless of
|
|
2403
|
+
// the collection metadata-specified sort.
|
|
2404
|
+
this.defaultSortField = SortField.relevance;
|
|
2405
|
+
this.defaultSortDirection = null;
|
|
2406
|
+
return;
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
// Favorite collections sort on Date Favorited by default.
|
|
2410
|
+
// Other collections fall back to sorting on weekly views.
|
|
2411
|
+
const baseDefaultSort: string =
|
|
2412
|
+
collectionInfo?.public_metadata?.identifier?.startsWith('fav-')
|
|
2413
|
+
? '-favoritedate'
|
|
2414
|
+
: '-week';
|
|
2415
|
+
|
|
2416
|
+
// The collection metadata may override the default sorting with something else
|
|
2417
|
+
const metadataSort: string | undefined =
|
|
2418
|
+
collectionInfo?.public_metadata?.['sort-by'];
|
|
2419
|
+
|
|
2420
|
+
// Prefer the metadata-specified sort if one exists
|
|
2421
|
+
const defaultSortToApply = metadataSort ?? baseDefaultSort;
|
|
2422
|
+
|
|
2423
|
+
// Account for both -field and field:dir formats
|
|
2424
|
+
let [field, dir] = defaultSortToApply.split(':');
|
|
2425
|
+
if (field.startsWith('-')) {
|
|
2426
|
+
field = field.slice(1);
|
|
2427
|
+
dir = 'desc';
|
|
2428
|
+
} else if (!['asc', 'desc'].includes(dir)) {
|
|
2429
|
+
dir = 'asc';
|
|
2430
|
+
}
|
|
2431
|
+
|
|
2432
|
+
const sortOption = sortOptionFromAPIString(field);
|
|
2433
|
+
const sortField = sortOption.field;
|
|
2434
|
+
if (sortField && sortField !== SortField.default) {
|
|
2435
|
+
this.defaultSortField = sortField;
|
|
2436
|
+
this.defaultSortDirection = dir as SortDirection;
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
|
|
2440
|
+
/**
|
|
2441
|
+
* Applies the default sort option for the current profile element
|
|
2442
|
+
*/
|
|
2443
|
+
applyDefaultProfileSort(): void {
|
|
2444
|
+
if (this.profileElement) {
|
|
2445
|
+
const defaultSortField = defaultProfileElementSorts[this.profileElement];
|
|
2446
|
+
this.defaultSortField = defaultSortField ?? SortField.weeklyview;
|
|
2447
|
+
} else {
|
|
2448
|
+
this.defaultSortField = SortField.weeklyview;
|
|
2449
|
+
}
|
|
2450
|
+
|
|
2451
|
+
this.defaultSortDirection = 'desc';
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2385
2454
|
/**
|
|
2386
2455
|
* This is useful for determining whether we need to reload the scroller.
|
|
2387
2456
|
*
|
|
@@ -1194,9 +1194,10 @@ export class CollectionBrowserDataSource
|
|
|
1194
1194
|
if (withinCollection) {
|
|
1195
1195
|
this.collectionExtraInfo = success.response.collectionExtraInfo;
|
|
1196
1196
|
|
|
1197
|
-
//
|
|
1197
|
+
// For collections, we want the UI to respect the default sort option
|
|
1198
|
+
// which can be specified in metadata, or otherwise assumed to be week:desc
|
|
1198
1199
|
if (this.activeOnHost) {
|
|
1199
|
-
this.host.
|
|
1200
|
+
this.host.applyDefaultCollectionSort(this.collectionExtraInfo);
|
|
1200
1201
|
}
|
|
1201
1202
|
|
|
1202
1203
|
if (this.collectionExtraInfo) {
|
|
@@ -6,12 +6,7 @@ import type {
|
|
|
6
6
|
SortDirection,
|
|
7
7
|
SortParam,
|
|
8
8
|
} from '@internetarchive/search-service';
|
|
9
|
-
import type {
|
|
10
|
-
ExplicitSortField,
|
|
11
|
-
FacetLoadStrategy,
|
|
12
|
-
SelectedFacets,
|
|
13
|
-
SortField,
|
|
14
|
-
} from '../models';
|
|
9
|
+
import type { FacetLoadStrategy, SelectedFacets, SortField } from '../models';
|
|
15
10
|
import type { CollectionBrowserDataSourceInterface } from './collection-browser-data-source-interface';
|
|
16
11
|
|
|
17
12
|
/**
|
|
@@ -32,8 +27,6 @@ export interface CollectionBrowserQueryState {
|
|
|
32
27
|
selectedCreatorFilter: string | null;
|
|
33
28
|
selectedSort?: SortField;
|
|
34
29
|
sortDirection: SortDirection | null;
|
|
35
|
-
defaultSortField?: ExplicitSortField;
|
|
36
|
-
defaultSortDirection?: SortDirection | null;
|
|
37
30
|
}
|
|
38
31
|
|
|
39
32
|
/**
|
|
@@ -45,7 +38,7 @@ export interface CollectionBrowserSearchInterface
|
|
|
45
38
|
searchService?: SearchServiceInterface;
|
|
46
39
|
isTVCollection: boolean;
|
|
47
40
|
readonly sortParam: SortParam | null;
|
|
48
|
-
readonly defaultSortField:
|
|
41
|
+
readonly defaultSortField: SortField | null;
|
|
49
42
|
readonly defaultSortDirection: SortDirection | null;
|
|
50
43
|
readonly facetLoadStrategy: FacetLoadStrategy;
|
|
51
44
|
readonly initialPageNumber: number;
|
|
@@ -59,9 +52,7 @@ export interface CollectionBrowserSearchInterface
|
|
|
59
52
|
setFacetsLoading(loading: boolean): void;
|
|
60
53
|
setTotalResultCount(count: number): void;
|
|
61
54
|
setTileCount(count: number): void;
|
|
62
|
-
|
|
63
|
-
collectionExtraInfo?: CollectionExtraInfo,
|
|
64
|
-
): void;
|
|
55
|
+
applyDefaultCollectionSort(collectionInfo?: CollectionExtraInfo): void;
|
|
65
56
|
emitEmptyResults(): void;
|
|
66
57
|
emitSearchError(): void;
|
|
67
58
|
emitQueryStateChanged(): void;
|
package/src/models.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { msg } from '@lit/localize';
|
|
|
3
3
|
import type { MediaType } from '@internetarchive/field-parsers';
|
|
4
4
|
import {
|
|
5
5
|
AggregationSortType,
|
|
6
|
-
CollectionExtraInfo,
|
|
7
6
|
HitType,
|
|
8
7
|
SearchReview,
|
|
9
8
|
SearchResult,
|
|
@@ -323,16 +322,6 @@ export enum SortField {
|
|
|
323
322
|
'creator' = 'creator',
|
|
324
323
|
}
|
|
325
324
|
|
|
326
|
-
/**
|
|
327
|
-
* A sort field other than the abstract "default" placeholder.
|
|
328
|
-
* This is useful because the "default" sort field is just an indicator to
|
|
329
|
-
* revert to an explicitly defined fallback value. So when defining default
|
|
330
|
-
* sort logic, this type should be preferred to avoid accidentally permitting
|
|
331
|
-
* that fallback to itself equal the "default" placeholder (which would be
|
|
332
|
-
* rather circular/ill-defined).
|
|
333
|
-
*/
|
|
334
|
-
export type ExplicitSortField = Exclude<SortField, SortField.default>;
|
|
335
|
-
|
|
336
325
|
/**
|
|
337
326
|
* Views-related sort fields
|
|
338
327
|
*/
|
|
@@ -564,47 +553,6 @@ export function sortOptionFromAPIString(sortName?: string | null): SortOption {
|
|
|
564
553
|
);
|
|
565
554
|
}
|
|
566
555
|
|
|
567
|
-
/**
|
|
568
|
-
* Resolves the default sort option for a collection based on its metadata.
|
|
569
|
-
*
|
|
570
|
-
* - Favorite collections (`fav-*`) default to Date Favorited descending.
|
|
571
|
-
* - Other collections default to Weekly Views descending.
|
|
572
|
-
* - If the collection metadata specifies a `sort-by` field, that overrides the above.
|
|
573
|
-
*
|
|
574
|
-
* Supports both `-field` (dash prefix = desc) and `field:dir` metadata formats.
|
|
575
|
-
*
|
|
576
|
-
* Note: This does NOT handle the "relevance when a query is present" rule,
|
|
577
|
-
* which is managed separately by collection-browser itself.
|
|
578
|
-
*/
|
|
579
|
-
export function resolveCollectionDefaultSort(
|
|
580
|
-
collectionInfo?: CollectionExtraInfo,
|
|
581
|
-
): { field: ExplicitSortField; direction: SortDirection } {
|
|
582
|
-
const isFav = collectionInfo?.public_metadata?.identifier?.startsWith('fav-');
|
|
583
|
-
const baseDefaultSort: string = isFav ? '-favoritedate' : '-week';
|
|
584
|
-
const metadataSort: string | undefined =
|
|
585
|
-
collectionInfo?.public_metadata?.['sort-by'];
|
|
586
|
-
const defaultSortToApply = metadataSort ?? baseDefaultSort;
|
|
587
|
-
|
|
588
|
-
// Account for both -field and field:dir formats
|
|
589
|
-
let [field, dir] = defaultSortToApply.split(':');
|
|
590
|
-
if (field.startsWith('-')) {
|
|
591
|
-
field = field.slice(1);
|
|
592
|
-
dir = 'desc';
|
|
593
|
-
} else if (!['asc', 'desc'].includes(dir)) {
|
|
594
|
-
dir = 'asc';
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
const sortOption = sortOptionFromAPIString(field);
|
|
598
|
-
const sortField = sortOption.field;
|
|
599
|
-
if (sortField && sortField !== SortField.default) {
|
|
600
|
-
return {
|
|
601
|
-
field: sortField as ExplicitSortField,
|
|
602
|
-
direction: dir as SortDirection,
|
|
603
|
-
};
|
|
604
|
-
}
|
|
605
|
-
return { field: SortField.weeklyview, direction: 'desc' };
|
|
606
|
-
}
|
|
607
|
-
|
|
608
556
|
export const defaultSortAvailability: Record<SortField, boolean> = {
|
|
609
557
|
[SortField.relevance]: true,
|
|
610
558
|
[SortField.weeklyview]: true,
|
|
@@ -632,7 +580,10 @@ export const tvSortAvailability: Record<SortField, boolean> = {
|
|
|
632
580
|
[SortField.dateadded]: false,
|
|
633
581
|
};
|
|
634
582
|
|
|
635
|
-
export const defaultProfileElementSorts: Record<
|
|
583
|
+
export const defaultProfileElementSorts: Record<
|
|
584
|
+
string,
|
|
585
|
+
Exclude<SortField, SortField.default>
|
|
586
|
+
> = {
|
|
636
587
|
uploads: SortField.datearchived,
|
|
637
588
|
reviews: SortField.datereviewed,
|
|
638
589
|
collections: SortField.datearchived,
|
|
@@ -337,7 +337,9 @@ export class RestorationStateHandler
|
|
|
337
337
|
if (facetAnds) {
|
|
338
338
|
facetAnds.forEach(and => {
|
|
339
339
|
// eslint-disable-next-line prefer-const
|
|
340
|
-
let [field,
|
|
340
|
+
let [field, ...valueParts] = and.split(':');
|
|
341
|
+
if (!valueParts.length) return;
|
|
342
|
+
const value = valueParts.join(':');
|
|
341
343
|
|
|
342
344
|
// Legacy search allowed and[] fields like 'creatorSorter', 'languageSorter', etc.
|
|
343
345
|
// which we want to normalize to 'creator', 'language', etc. if redirected here.
|
|
@@ -396,7 +398,9 @@ export class RestorationStateHandler
|
|
|
396
398
|
|
|
397
399
|
if (facetNots) {
|
|
398
400
|
facetNots.forEach(not => {
|
|
399
|
-
const [field,
|
|
401
|
+
const [field, ...valueParts] = not.split(':');
|
|
402
|
+
if (!valueParts.length) return;
|
|
403
|
+
const value = valueParts.join(':');
|
|
400
404
|
this.setSelectedFacetState(
|
|
401
405
|
restorationState.selectedFacets,
|
|
402
406
|
field as FacetOption,
|
|
@@ -531,7 +535,7 @@ export class RestorationStateHandler
|
|
|
531
535
|
if (!facet) return; // Unrecognized facet group, ignore it.
|
|
532
536
|
|
|
533
537
|
const unQuotedValue = this.stripQuotes(value);
|
|
534
|
-
facet[unQuotedValue] ??= this.getDefaultBucket(
|
|
538
|
+
facet[unQuotedValue] ??= this.getDefaultBucket(unQuotedValue);
|
|
535
539
|
facet[unQuotedValue].state = state;
|
|
536
540
|
}
|
|
537
541
|
|
|
@@ -13,7 +13,6 @@ import type { SortDirection } from '@internetarchive/search-service';
|
|
|
13
13
|
import {
|
|
14
14
|
CollectionDisplayMode,
|
|
15
15
|
defaultSortAvailability,
|
|
16
|
-
type ExplicitSortField,
|
|
17
16
|
PrefixFilterCounts,
|
|
18
17
|
PrefixFilterType,
|
|
19
18
|
SORT_OPTIONS,
|
|
@@ -43,8 +42,10 @@ export class SortFilterBar extends LitElement {
|
|
|
43
42
|
@property({ type: String }) defaultSortDirection: SortDirection | null = null;
|
|
44
43
|
|
|
45
44
|
/** The default sort field to use if none is set */
|
|
46
|
-
@property({ type: String }) defaultSortField:
|
|
47
|
-
SortField
|
|
45
|
+
@property({ type: String }) defaultSortField: Exclude<
|
|
46
|
+
SortField,
|
|
47
|
+
SortField.default
|
|
48
|
+
> = SortField.relevance;
|
|
48
49
|
|
|
49
50
|
/** The current sort direction (asc/desc), or null if none is set */
|
|
50
51
|
@property({ type: String }) sortDirection: SortDirection | null = null;
|
|
@@ -227,7 +227,7 @@ export class HoverPaneController implements HoverPaneControllerInterface {
|
|
|
227
227
|
|
|
228
228
|
/** @inheritdoc */
|
|
229
229
|
toggleHoverPane(options: ToggleHoverPaneOptions): void {
|
|
230
|
-
if (this.hoverPaneState
|
|
230
|
+
if (this.hoverPaneState !== 'hidden') {
|
|
231
231
|
this.fadeOutHoverPane();
|
|
232
232
|
this.forceTouchBackdrop = false;
|
|
233
233
|
} else {
|
|
@@ -546,6 +546,7 @@ export class HoverPaneController implements HoverPaneControllerInterface {
|
|
|
546
546
|
if (this.hoverPaneState !== 'hidden') {
|
|
547
547
|
this.fadeOutHoverPane();
|
|
548
548
|
}
|
|
549
|
+
e.preventDefault();
|
|
549
550
|
e.stopPropagation();
|
|
550
551
|
};
|
|
551
552
|
|
|
@@ -218,6 +218,15 @@ export class TileDispatcher
|
|
|
218
218
|
return window.matchMedia('(hover: hover)').matches;
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
+
/**
|
|
222
|
+
* Whether the info button should be shown on this tile.
|
|
223
|
+
* Only shown on touch/non-hover devices where a hover pane is available,
|
|
224
|
+
* so the button always has something to toggle.
|
|
225
|
+
*/
|
|
226
|
+
private get shouldShowInfoButton(): boolean {
|
|
227
|
+
return !this.isHoverEnabled && this.shouldPrepareHoverPane;
|
|
228
|
+
}
|
|
229
|
+
|
|
221
230
|
/** @inheritdoc */
|
|
222
231
|
getHoverPane(): TileHoverPane | undefined {
|
|
223
232
|
return this.hoverPane;
|
|
@@ -326,7 +335,7 @@ export class TileDispatcher
|
|
|
326
335
|
.suppressBlurring=${this.suppressBlurring}
|
|
327
336
|
.isManageView=${this.isManageView}
|
|
328
337
|
.layoutType=${this.layoutType}
|
|
329
|
-
?showInfoButton=${
|
|
338
|
+
?showInfoButton=${this.shouldShowInfoButton}
|
|
330
339
|
@infoButtonPressed=${this.tileInfoButtonPressed}
|
|
331
340
|
>
|
|
332
341
|
</collection-tile>`;
|
|
@@ -340,7 +349,7 @@ export class TileDispatcher
|
|
|
340
349
|
.creatorFilter=${creatorFilter}
|
|
341
350
|
.suppressBlurring=${this.suppressBlurring}
|
|
342
351
|
.isManageView=${this.isManageView}
|
|
343
|
-
?showInfoButton=${
|
|
352
|
+
?showInfoButton=${this.shouldShowInfoButton}
|
|
344
353
|
@infoButtonPressed=${this.tileInfoButtonPressed}
|
|
345
354
|
>
|
|
346
355
|
</account-tile>`;
|
|
@@ -373,7 +382,7 @@ export class TileDispatcher
|
|
|
373
382
|
.isManageView=${this.isManageView}
|
|
374
383
|
.layoutType=${this.layoutType}
|
|
375
384
|
?showTvClips=${this.showTvClips}
|
|
376
|
-
?showInfoButton=${
|
|
385
|
+
?showInfoButton=${this.shouldShowInfoButton}
|
|
377
386
|
?useLocalTime=${this.useLocalTime}
|
|
378
387
|
@infoButtonPressed=${this.tileInfoButtonPressed}
|
|
379
388
|
>
|
|
@@ -1313,19 +1313,20 @@ describe('Collection Browser', () => {
|
|
|
1313
1313
|
);
|
|
1314
1314
|
});
|
|
1315
1315
|
|
|
1316
|
-
it('sets default sort from
|
|
1316
|
+
it('sets default sort from collection metadata', async () => {
|
|
1317
1317
|
const searchService = new MockSearchService();
|
|
1318
1318
|
const el = await fixture<CollectionBrowser>(
|
|
1319
1319
|
html`<collection-browser
|
|
1320
1320
|
.searchService=${searchService}
|
|
1321
1321
|
.baseNavigationUrl=${''}
|
|
1322
|
-
.withinCollection=${'test-collection'}
|
|
1323
|
-
.defaultSortField=${SortField.title}
|
|
1324
|
-
.defaultSortDirection=${'asc'}
|
|
1325
1322
|
></collection-browser>`,
|
|
1326
1323
|
);
|
|
1327
1324
|
|
|
1325
|
+
el.withinCollection = 'default-sort';
|
|
1326
|
+
await el.updateComplete;
|
|
1327
|
+
await el.initialSearchComplete;
|
|
1328
1328
|
await el.updateComplete;
|
|
1329
|
+
await aTimeout(50);
|
|
1329
1330
|
|
|
1330
1331
|
const sortBar = el.shadowRoot?.querySelector(
|
|
1331
1332
|
'sort-filter-bar',
|
|
@@ -1337,19 +1338,20 @@ describe('Collection Browser', () => {
|
|
|
1337
1338
|
expect(sortBar.sortDirection).to.be.null;
|
|
1338
1339
|
});
|
|
1339
1340
|
|
|
1340
|
-
it('
|
|
1341
|
+
it('sets default sort from collection metadata in "-field" format', async () => {
|
|
1341
1342
|
const searchService = new MockSearchService();
|
|
1342
1343
|
const el = await fixture<CollectionBrowser>(
|
|
1343
1344
|
html`<collection-browser
|
|
1344
1345
|
.searchService=${searchService}
|
|
1345
1346
|
.baseNavigationUrl=${''}
|
|
1346
|
-
.withinCollection=${'test-collection'}
|
|
1347
|
-
.defaultSortField=${SortField.dateadded}
|
|
1348
|
-
.defaultSortDirection=${'desc'}
|
|
1349
1347
|
></collection-browser>`,
|
|
1350
1348
|
);
|
|
1351
1349
|
|
|
1350
|
+
el.withinCollection = 'default-sort-concise';
|
|
1351
|
+
await el.updateComplete;
|
|
1352
|
+
await el.initialSearchComplete;
|
|
1352
1353
|
await el.updateComplete;
|
|
1354
|
+
await aTimeout(50);
|
|
1353
1355
|
|
|
1354
1356
|
const sortBar = el.shadowRoot?.querySelector(
|
|
1355
1357
|
'sort-filter-bar',
|
|
@@ -1361,15 +1363,14 @@ describe('Collection Browser', () => {
|
|
|
1361
1363
|
expect(sortBar.sortDirection).to.be.null;
|
|
1362
1364
|
});
|
|
1363
1365
|
|
|
1364
|
-
it('
|
|
1366
|
+
it('falls back to weekly views default sorting on profiles when tab not set', async () => {
|
|
1365
1367
|
const el = await fixture<CollectionBrowser>(
|
|
1366
1368
|
html`<collection-browser
|
|
1367
1369
|
.withinProfile=${'@foobar'}
|
|
1368
|
-
.defaultSortField=${SortField.weeklyview}
|
|
1369
|
-
.defaultSortDirection=${'desc'}
|
|
1370
1370
|
></collection-browser>`,
|
|
1371
1371
|
);
|
|
1372
1372
|
|
|
1373
|
+
el.applyDefaultProfileSort();
|
|
1373
1374
|
expect(el.defaultSortParam).to.deep.equal({
|
|
1374
1375
|
field: 'week',
|
|
1375
1376
|
direction: 'desc',
|
|
@@ -1402,19 +1403,20 @@ describe('Collection Browser', () => {
|
|
|
1402
1403
|
expect(sortBar.sortDirection).to.be.null;
|
|
1403
1404
|
});
|
|
1404
1405
|
|
|
1405
|
-
it('uses date favorited sort as default when
|
|
1406
|
+
it('uses date favorited sort as default when targeting fav- collection', async () => {
|
|
1406
1407
|
const searchService = new MockSearchService();
|
|
1407
1408
|
const el = await fixture<CollectionBrowser>(
|
|
1408
1409
|
html`<collection-browser
|
|
1409
1410
|
.searchService=${searchService}
|
|
1410
1411
|
.baseNavigationUrl=${''}
|
|
1411
|
-
.withinCollection=${'fav-sort'}
|
|
1412
|
-
.defaultSortField=${SortField.datefavorited}
|
|
1413
|
-
.defaultSortDirection=${'desc'}
|
|
1414
1412
|
></collection-browser>`,
|
|
1415
1413
|
);
|
|
1416
1414
|
|
|
1415
|
+
el.withinCollection = 'fav-sort';
|
|
1417
1416
|
await el.updateComplete;
|
|
1417
|
+
await el.initialSearchComplete;
|
|
1418
|
+
await el.updateComplete;
|
|
1419
|
+
await aTimeout(50);
|
|
1418
1420
|
|
|
1419
1421
|
const sortBar = el.shadowRoot?.querySelector(
|
|
1420
1422
|
'sort-filter-bar',
|