@internetarchive/collection-browser 4.1.0-alpha-webdev8186.1 → 4.1.0-alpha-webdev8186.3

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.
@@ -67,6 +67,18 @@ describe('Sort dropdown behavior', () => {
67
67
  const label = sortDropdown?.querySelector('.dropdown-label');
68
68
  expect(label?.textContent?.trim()).to.equal('All-time views');
69
69
  });
70
+ it('falls back to first available sort when default is unavailable', async () => {
71
+ el.selectedSort = SortField.default;
72
+ el.defaultSortField = SortField.relevance;
73
+ el.sortFieldAvailability = {
74
+ ...defaultSortAvailability,
75
+ [SortField.relevance]: false,
76
+ };
77
+ await el.updateComplete;
78
+ const label = sortDropdown?.querySelector('.dropdown-label');
79
+ // No relevance, so fall back to the first one in the list
80
+ expect(label?.textContent?.trim()).to.equal('All-time views');
81
+ });
70
82
  it('changes selected sort when dropdown option selected', async () => {
71
83
  expect(sortDropdown).to.exist;
72
84
  sortDropdown.selectedOption = 'title';
@@ -1 +1 @@
1
- {"version":3,"file":"sort-filter-bar.test.js","sourceRoot":"","sources":["../../../test/sort-filter-bar/sort-filter-bar.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture } from '@open-wc/testing';\nimport sinon from 'sinon';\nimport { html } from 'lit';\nimport type { IaDropdown } from '@internetarchive/ia-dropdown';\nimport type { SortFilterBar } from '../../src/sort-filter-bar/sort-filter-bar';\nimport { SortField, defaultSortAvailability } from '../../src/models';\n\nimport '../../src/sort-filter-bar/sort-filter-bar';\n\ndescribe('Sort dropdown behavior', () => {\n let el: SortFilterBar;\n let sortDropdown: IaDropdown;\n\n beforeEach(async () => {\n el = await fixture<SortFilterBar>(html`\n <sort-filter-bar></sort-filter-bar>\n `);\n sortDropdown = el.shadowRoot?.querySelector('#sort-dropdown') as IaDropdown;\n await el.updateComplete;\n });\n\n it('should render basic component', async () => {\n const sortSelectorContainer = el.shadowRoot?.querySelector(\n '#sort-selector-container',\n );\n expect(sortSelectorContainer).to.exist;\n });\n\n it('should render sort-by label', async () => {\n const sortByLabel = el.shadowRoot?.querySelector('.sort-by-text');\n expect(sortByLabel).to.exist;\n expect(sortByLabel?.textContent?.trim()).to.equal('Sort by:');\n });\n\n it('should render sort direction button', async () => {\n const sortDirections = el.shadowRoot?.querySelector(\n '.sort-direction-container',\n );\n expect(sortDirections).to.exist;\n expect(sortDirections?.querySelector('.sort-direction-icon')).to.exist;\n });\n\n it('renders default set of sort options in dropdown', async () => {\n expect(sortDropdown).to.exist;\n expect(sortDropdown.options.map(o => o.id)).to.deep.equal([\n SortField.relevance,\n SortField.alltimeview,\n SortField.weeklyview,\n SortField.title,\n SortField.date,\n SortField.datearchived,\n SortField.datereviewed,\n SortField.dateadded,\n SortField.creator,\n ]);\n });\n\n it('respects overridden sort field availability', async () => {\n const customSortAvailability: Record<SortField, boolean> = {\n ...defaultSortAvailability,\n [SortField.title]: false,\n [SortField.datearchived]: false,\n [SortField.datereviewed]: false,\n [SortField.creator]: false,\n };\n\n el.sortFieldAvailability = customSortAvailability;\n await el.updateComplete;\n\n const dropdown = el.shadowRoot?.querySelector(\n '#sort-dropdown',\n ) as IaDropdown;\n expect(dropdown.options.length).to.equal(5);\n expect(dropdown.options.map(o => o.id)).to.deep.equal([\n SortField.relevance,\n SortField.alltimeview,\n SortField.weeklyview,\n SortField.date,\n SortField.dateadded,\n ]);\n });\n\n it('shows the display name of the selected sort', async () => {\n el.selectedSort = SortField.alltimeview;\n await el.updateComplete;\n\n const label = sortDropdown?.querySelector('.dropdown-label');\n expect(label?.textContent?.trim()).to.equal('All-time views');\n });\n\n it('changes selected sort when dropdown option selected', async () => {\n expect(sortDropdown).to.exist;\n\n sortDropdown.selectedOption = 'title';\n const option = { id: 'title' };\n sortDropdown.dispatchEvent(\n new CustomEvent('optionSelected', { detail: { option } }),\n );\n await el.updateComplete;\n\n expect(el.selectedSort).to.equal('title');\n });\n\n it('selects a sort option by clicking it in the dropdown', async () => {\n el.selectedSort = SortField.title;\n await el.updateComplete;\n\n const dropdown = el.shadowRoot?.querySelector(\n '#sort-dropdown',\n ) as IaDropdown;\n expect(dropdown).to.exist;\n\n const firstOption = dropdown?.shadowRoot?.querySelector(\n 'li > button',\n ) as HTMLButtonElement;\n expect(firstOption).to.exist;\n\n firstOption?.click();\n await el.updateComplete;\n\n // The first option is relevance by default\n expect(el.selectedSort).to.equal(SortField.relevance);\n });\n\n it('emits sortChanged event when sort option selected', async () => {\n const sortChangedHandler = sinon.spy();\n el.addEventListener('sortChanged', sortChangedHandler);\n\n const option = { id: SortField.title };\n sortDropdown.dispatchEvent(\n new CustomEvent('optionSelected', { detail: { option } }),\n );\n await el.updateComplete;\n\n expect(sortChangedHandler.calledOnce).to.be.true;\n const eventDetail = sortChangedHandler.firstCall.args[0].detail;\n expect(eventDetail.selectedSort).to.equal(SortField.title);\n expect(eventDetail.sortDirection).to.equal('asc');\n });\n\n it('renders sort selector backdrop when dropdown is open', async () => {\n expect(sortDropdown).to.exist;\n\n const caret = sortDropdown?.shadowRoot?.querySelector(\n '.caret',\n ) as HTMLElement;\n expect(caret).to.exist;\n\n caret!.click();\n await el.updateComplete;\n\n let backdrop = el.shadowRoot?.querySelector(\n '#sort-selector-backdrop',\n ) as HTMLElement;\n expect(backdrop).to.exist;\n\n // Clicking the backdrop should close the dropdown\n backdrop!.click();\n await el.updateComplete;\n\n backdrop = el.shadowRoot?.querySelector(\n '#sort-selector-backdrop',\n ) as HTMLElement;\n expect(backdrop).not.to.exist;\n });\n\n it('pressing Escape key closes the dropdown', async () => {\n expect(sortDropdown).to.exist;\n\n const caret = sortDropdown?.shadowRoot?.querySelector(\n '.caret',\n ) as HTMLElement;\n expect(caret).to.exist;\n\n caret!.click();\n await el.updateComplete;\n\n let backdrop = el.shadowRoot?.querySelector(\n '#sort-selector-backdrop',\n ) as HTMLElement;\n expect(backdrop).to.exist;\n\n document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }));\n await el.updateComplete;\n\n backdrop = el.shadowRoot?.querySelector(\n '#sort-selector-backdrop',\n ) as HTMLElement;\n expect(backdrop).not.to.exist;\n });\n\n it('clears title filter when sort changed from title', async () => {\n el.selectedSort = 'title' as SortField;\n el.selectedTitleFilter = 'A';\n await el.updateComplete;\n\n const dropdown = el.shadowRoot?.querySelector(\n '#sort-dropdown',\n ) as IaDropdown;\n expect(dropdown).to.exist;\n\n dropdown.selectedOption = 'relevance';\n const option = { id: 'relevance' };\n dropdown.dispatchEvent(\n new CustomEvent('optionSelected', { detail: { option } }),\n );\n await el.updateComplete;\n\n expect(el.selectedSort).to.equal('relevance');\n expect(el.selectedTitleFilter).to.be.null;\n });\n\n it('clears creator filter when sort changed from creator', async () => {\n el.selectedSort = 'creator' as SortField;\n el.selectedCreatorFilter = 'A';\n await el.updateComplete;\n\n const dropdown = el.shadowRoot?.querySelector(\n '#sort-dropdown',\n ) as IaDropdown;\n expect(dropdown).to.exist;\n\n dropdown.selectedOption = 'relevance';\n const option = { id: 'relevance' };\n dropdown.dispatchEvent(\n new CustomEvent('optionSelected', { detail: { option } }),\n );\n await el.updateComplete;\n\n expect(el.selectedSort).to.equal('relevance');\n expect(el.selectedCreatorFilter).to.be.null;\n });\n\n it('contains sort-options slot when enabled', async () => {\n const slotEl = await fixture<SortFilterBar>(html`\n <sort-filter-bar .enableSortOptionsSlot=${true}></sort-filter-bar>\n `);\n await slotEl.updateComplete;\n\n const sortOptionsSlot = slotEl?.shadowRoot?.querySelector(\n 'slot[name=\"sort-options\"]',\n );\n expect(sortOptionsSlot).to.exist;\n\n expect(slotEl?.shadowRoot?.querySelector('#sort-selector-container')).to.not\n .exist;\n });\n});\n\ndescribe('Sort direction button behavior', () => {\n it('should disable sort direction button when sorting by relevance', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar> </sort-filter-bar>\n `);\n\n el.selectedSort = 'relevance' as SortField;\n await el.updateComplete;\n\n const sortDirectionButton = el.shadowRoot?.querySelector(\n '.sort-direction-selector',\n ) as HTMLButtonElement;\n expect(sortDirectionButton).to.exist;\n expect(sortDirectionButton.disabled).to.be.true;\n });\n\n it('should enable sort direction button when not sorting by relevance', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar> </sort-filter-bar>\n `);\n\n el.selectedSort = 'title' as SortField;\n await el.updateComplete;\n\n const sortDirectionButton = el.shadowRoot?.querySelector(\n '.sort-direction-selector',\n ) as HTMLButtonElement;\n expect(sortDirectionButton).to.exist;\n expect(sortDirectionButton.disabled).to.be.false;\n });\n\n it('should toggle sort direction when clicked', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar> </sort-filter-bar>\n `);\n\n el.selectedSort = 'title' as SortField;\n el.sortDirection = 'asc';\n await el.updateComplete;\n\n const sortDirectionButton = el.shadowRoot?.querySelector(\n '.sort-direction-selector',\n ) as HTMLButtonElement;\n\n sortDirectionButton.click();\n await el.updateComplete;\n expect(el.sortDirection).to.equal('desc');\n\n sortDirectionButton.click();\n await el.updateComplete;\n expect(el.sortDirection).to.equal('asc');\n });\n});\n\ndescribe('Display mode/style buttons', () => {\n it('should render all display mode buttons', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar> </sort-filter-bar>\n `);\n\n const displayModeButtonList = el.shadowRoot\n ?.querySelector('#display-style-selector')\n ?.querySelector('ul');\n\n const gridButton = displayModeButtonList?.children\n .item(0)\n ?.querySelector('#grid-button');\n expect(gridButton).to.exist;\n\n const detailListButton = displayModeButtonList?.children\n .item(1)\n ?.querySelector('#list-detail-button');\n expect(detailListButton).to.exist;\n\n const compactListButton = displayModeButtonList?.children\n .item(2)\n ?.querySelector('#list-compact-button');\n expect(compactListButton).to.exist;\n });\n\n it('should not render display mode buttons when suppressed', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar suppressDisplayModes></sort-filter-bar>\n `);\n\n const displayModeButtonList = el.shadowRoot?.querySelector(\n '#display-style-selector',\n );\n expect(displayModeButtonList).not.to.exist;\n });\n\n it('should active current display mode', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar> </sort-filter-bar>\n `);\n\n el.displayMode = 'grid';\n await el.updateComplete;\n\n const displayModeTitle = el.shadowRoot\n ?.querySelector('#display-style-selector')\n ?.querySelector('button.active')\n ?.getAttribute('title');\n expect(displayModeTitle).to.equal('Tile view');\n });\n\n it('should change displayMode prop to the one clicked', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar> </sort-filter-bar>\n `);\n\n el.displayMode = 'grid';\n await el.updateComplete;\n\n const extendedListButton = el.shadowRoot?.querySelector(\n '#list-detail-button',\n ) as HTMLElement;\n extendedListButton.click();\n await el.updateComplete;\n expect(el.displayMode).to.equal('list-detail');\n\n const compactListButton = el.shadowRoot?.querySelector(\n '#list-compact-button',\n ) as HTMLElement;\n compactListButton.click();\n await el.updateComplete;\n expect(el.displayMode).to.equal('list-compact');\n\n const gridModeButton = el.shadowRoot?.querySelector(\n '#grid-button',\n ) as HTMLElement;\n gridModeButton.click();\n await el.updateComplete;\n expect(el.displayMode).to.equal('grid');\n });\n});\n\ndescribe('Sort/filter bar letter behavior', () => {\n it('sets the selected title letter when clicked', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar></sort-filter-bar>\n `);\n\n el.selectedSort = 'title' as SortField;\n el.prefixFilterCountMap = { title: { T: 1 }, creator: {} };\n await el.updateComplete;\n\n const alphaBar = el.shadowRoot?.querySelector('alpha-bar');\n const letterLink = alphaBar?.shadowRoot?.querySelector(\n 'li > button:not(:disabled)',\n ) as HTMLAnchorElement;\n expect(letterLink?.textContent?.trim()).to.equal('T');\n\n letterLink?.click();\n await el.updateComplete;\n\n expect(el.selectedTitleFilter).to.equal('T');\n });\n\n it('sets the selected creator letter when clicked', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar></sort-filter-bar>\n `);\n\n el.selectedSort = 'creator' as SortField;\n el.prefixFilterCountMap = { title: {}, creator: { C: 1 } };\n await el.updateComplete;\n\n const alphaBar = el.shadowRoot?.querySelector('alpha-bar');\n const letterLink = alphaBar?.shadowRoot?.querySelector(\n 'li > button:not(:disabled)',\n ) as HTMLAnchorElement;\n expect(letterLink?.textContent?.trim()).to.equal('C');\n\n letterLink?.click();\n await el.updateComplete;\n\n expect(el.selectedCreatorFilter).to.equal('C');\n });\n});\n"]}
1
+ {"version":3,"file":"sort-filter-bar.test.js","sourceRoot":"","sources":["../../../test/sort-filter-bar/sort-filter-bar.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture } from '@open-wc/testing';\nimport sinon from 'sinon';\nimport { html } from 'lit';\nimport type { IaDropdown } from '@internetarchive/ia-dropdown';\nimport type { SortFilterBar } from '../../src/sort-filter-bar/sort-filter-bar';\nimport { SortField, defaultSortAvailability } from '../../src/models';\n\nimport '../../src/sort-filter-bar/sort-filter-bar';\n\ndescribe('Sort dropdown behavior', () => {\n let el: SortFilterBar;\n let sortDropdown: IaDropdown;\n\n beforeEach(async () => {\n el = await fixture<SortFilterBar>(html`\n <sort-filter-bar></sort-filter-bar>\n `);\n sortDropdown = el.shadowRoot?.querySelector('#sort-dropdown') as IaDropdown;\n await el.updateComplete;\n });\n\n it('should render basic component', async () => {\n const sortSelectorContainer = el.shadowRoot?.querySelector(\n '#sort-selector-container',\n );\n expect(sortSelectorContainer).to.exist;\n });\n\n it('should render sort-by label', async () => {\n const sortByLabel = el.shadowRoot?.querySelector('.sort-by-text');\n expect(sortByLabel).to.exist;\n expect(sortByLabel?.textContent?.trim()).to.equal('Sort by:');\n });\n\n it('should render sort direction button', async () => {\n const sortDirections = el.shadowRoot?.querySelector(\n '.sort-direction-container',\n );\n expect(sortDirections).to.exist;\n expect(sortDirections?.querySelector('.sort-direction-icon')).to.exist;\n });\n\n it('renders default set of sort options in dropdown', async () => {\n expect(sortDropdown).to.exist;\n expect(sortDropdown.options.map(o => o.id)).to.deep.equal([\n SortField.relevance,\n SortField.alltimeview,\n SortField.weeklyview,\n SortField.title,\n SortField.date,\n SortField.datearchived,\n SortField.datereviewed,\n SortField.dateadded,\n SortField.creator,\n ]);\n });\n\n it('respects overridden sort field availability', async () => {\n const customSortAvailability: Record<SortField, boolean> = {\n ...defaultSortAvailability,\n [SortField.title]: false,\n [SortField.datearchived]: false,\n [SortField.datereviewed]: false,\n [SortField.creator]: false,\n };\n\n el.sortFieldAvailability = customSortAvailability;\n await el.updateComplete;\n\n const dropdown = el.shadowRoot?.querySelector(\n '#sort-dropdown',\n ) as IaDropdown;\n expect(dropdown.options.length).to.equal(5);\n expect(dropdown.options.map(o => o.id)).to.deep.equal([\n SortField.relevance,\n SortField.alltimeview,\n SortField.weeklyview,\n SortField.date,\n SortField.dateadded,\n ]);\n });\n\n it('shows the display name of the selected sort', async () => {\n el.selectedSort = SortField.alltimeview;\n await el.updateComplete;\n\n const label = sortDropdown?.querySelector('.dropdown-label');\n expect(label?.textContent?.trim()).to.equal('All-time views');\n });\n\n it('falls back to first available sort when default is unavailable', async () => {\n el.selectedSort = SortField.default;\n el.defaultSortField = SortField.relevance;\n el.sortFieldAvailability = {\n ...defaultSortAvailability,\n [SortField.relevance]: false,\n };\n await el.updateComplete;\n\n const label = sortDropdown?.querySelector('.dropdown-label');\n // No relevance, so fall back to the first one in the list\n expect(label?.textContent?.trim()).to.equal('All-time views');\n });\n\n it('changes selected sort when dropdown option selected', async () => {\n expect(sortDropdown).to.exist;\n\n sortDropdown.selectedOption = 'title';\n const option = { id: 'title' };\n sortDropdown.dispatchEvent(\n new CustomEvent('optionSelected', { detail: { option } }),\n );\n await el.updateComplete;\n\n expect(el.selectedSort).to.equal('title');\n });\n\n it('selects a sort option by clicking it in the dropdown', async () => {\n el.selectedSort = SortField.title;\n await el.updateComplete;\n\n const dropdown = el.shadowRoot?.querySelector(\n '#sort-dropdown',\n ) as IaDropdown;\n expect(dropdown).to.exist;\n\n const firstOption = dropdown?.shadowRoot?.querySelector(\n 'li > button',\n ) as HTMLButtonElement;\n expect(firstOption).to.exist;\n\n firstOption?.click();\n await el.updateComplete;\n\n // The first option is relevance by default\n expect(el.selectedSort).to.equal(SortField.relevance);\n });\n\n it('emits sortChanged event when sort option selected', async () => {\n const sortChangedHandler = sinon.spy();\n el.addEventListener('sortChanged', sortChangedHandler);\n\n const option = { id: SortField.title };\n sortDropdown.dispatchEvent(\n new CustomEvent('optionSelected', { detail: { option } }),\n );\n await el.updateComplete;\n\n expect(sortChangedHandler.calledOnce).to.be.true;\n const eventDetail = sortChangedHandler.firstCall.args[0].detail;\n expect(eventDetail.selectedSort).to.equal(SortField.title);\n expect(eventDetail.sortDirection).to.equal('asc');\n });\n\n it('renders sort selector backdrop when dropdown is open', async () => {\n expect(sortDropdown).to.exist;\n\n const caret = sortDropdown?.shadowRoot?.querySelector(\n '.caret',\n ) as HTMLElement;\n expect(caret).to.exist;\n\n caret!.click();\n await el.updateComplete;\n\n let backdrop = el.shadowRoot?.querySelector(\n '#sort-selector-backdrop',\n ) as HTMLElement;\n expect(backdrop).to.exist;\n\n // Clicking the backdrop should close the dropdown\n backdrop!.click();\n await el.updateComplete;\n\n backdrop = el.shadowRoot?.querySelector(\n '#sort-selector-backdrop',\n ) as HTMLElement;\n expect(backdrop).not.to.exist;\n });\n\n it('pressing Escape key closes the dropdown', async () => {\n expect(sortDropdown).to.exist;\n\n const caret = sortDropdown?.shadowRoot?.querySelector(\n '.caret',\n ) as HTMLElement;\n expect(caret).to.exist;\n\n caret!.click();\n await el.updateComplete;\n\n let backdrop = el.shadowRoot?.querySelector(\n '#sort-selector-backdrop',\n ) as HTMLElement;\n expect(backdrop).to.exist;\n\n document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }));\n await el.updateComplete;\n\n backdrop = el.shadowRoot?.querySelector(\n '#sort-selector-backdrop',\n ) as HTMLElement;\n expect(backdrop).not.to.exist;\n });\n\n it('clears title filter when sort changed from title', async () => {\n el.selectedSort = 'title' as SortField;\n el.selectedTitleFilter = 'A';\n await el.updateComplete;\n\n const dropdown = el.shadowRoot?.querySelector(\n '#sort-dropdown',\n ) as IaDropdown;\n expect(dropdown).to.exist;\n\n dropdown.selectedOption = 'relevance';\n const option = { id: 'relevance' };\n dropdown.dispatchEvent(\n new CustomEvent('optionSelected', { detail: { option } }),\n );\n await el.updateComplete;\n\n expect(el.selectedSort).to.equal('relevance');\n expect(el.selectedTitleFilter).to.be.null;\n });\n\n it('clears creator filter when sort changed from creator', async () => {\n el.selectedSort = 'creator' as SortField;\n el.selectedCreatorFilter = 'A';\n await el.updateComplete;\n\n const dropdown = el.shadowRoot?.querySelector(\n '#sort-dropdown',\n ) as IaDropdown;\n expect(dropdown).to.exist;\n\n dropdown.selectedOption = 'relevance';\n const option = { id: 'relevance' };\n dropdown.dispatchEvent(\n new CustomEvent('optionSelected', { detail: { option } }),\n );\n await el.updateComplete;\n\n expect(el.selectedSort).to.equal('relevance');\n expect(el.selectedCreatorFilter).to.be.null;\n });\n\n it('contains sort-options slot when enabled', async () => {\n const slotEl = await fixture<SortFilterBar>(html`\n <sort-filter-bar .enableSortOptionsSlot=${true}></sort-filter-bar>\n `);\n await slotEl.updateComplete;\n\n const sortOptionsSlot = slotEl?.shadowRoot?.querySelector(\n 'slot[name=\"sort-options\"]',\n );\n expect(sortOptionsSlot).to.exist;\n\n expect(slotEl?.shadowRoot?.querySelector('#sort-selector-container')).to.not\n .exist;\n });\n});\n\ndescribe('Sort direction button behavior', () => {\n it('should disable sort direction button when sorting by relevance', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar> </sort-filter-bar>\n `);\n\n el.selectedSort = 'relevance' as SortField;\n await el.updateComplete;\n\n const sortDirectionButton = el.shadowRoot?.querySelector(\n '.sort-direction-selector',\n ) as HTMLButtonElement;\n expect(sortDirectionButton).to.exist;\n expect(sortDirectionButton.disabled).to.be.true;\n });\n\n it('should enable sort direction button when not sorting by relevance', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar> </sort-filter-bar>\n `);\n\n el.selectedSort = 'title' as SortField;\n await el.updateComplete;\n\n const sortDirectionButton = el.shadowRoot?.querySelector(\n '.sort-direction-selector',\n ) as HTMLButtonElement;\n expect(sortDirectionButton).to.exist;\n expect(sortDirectionButton.disabled).to.be.false;\n });\n\n it('should toggle sort direction when clicked', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar> </sort-filter-bar>\n `);\n\n el.selectedSort = 'title' as SortField;\n el.sortDirection = 'asc';\n await el.updateComplete;\n\n const sortDirectionButton = el.shadowRoot?.querySelector(\n '.sort-direction-selector',\n ) as HTMLButtonElement;\n\n sortDirectionButton.click();\n await el.updateComplete;\n expect(el.sortDirection).to.equal('desc');\n\n sortDirectionButton.click();\n await el.updateComplete;\n expect(el.sortDirection).to.equal('asc');\n });\n});\n\ndescribe('Display mode/style buttons', () => {\n it('should render all display mode buttons', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar> </sort-filter-bar>\n `);\n\n const displayModeButtonList = el.shadowRoot\n ?.querySelector('#display-style-selector')\n ?.querySelector('ul');\n\n const gridButton = displayModeButtonList?.children\n .item(0)\n ?.querySelector('#grid-button');\n expect(gridButton).to.exist;\n\n const detailListButton = displayModeButtonList?.children\n .item(1)\n ?.querySelector('#list-detail-button');\n expect(detailListButton).to.exist;\n\n const compactListButton = displayModeButtonList?.children\n .item(2)\n ?.querySelector('#list-compact-button');\n expect(compactListButton).to.exist;\n });\n\n it('should not render display mode buttons when suppressed', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar suppressDisplayModes></sort-filter-bar>\n `);\n\n const displayModeButtonList = el.shadowRoot?.querySelector(\n '#display-style-selector',\n );\n expect(displayModeButtonList).not.to.exist;\n });\n\n it('should active current display mode', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar> </sort-filter-bar>\n `);\n\n el.displayMode = 'grid';\n await el.updateComplete;\n\n const displayModeTitle = el.shadowRoot\n ?.querySelector('#display-style-selector')\n ?.querySelector('button.active')\n ?.getAttribute('title');\n expect(displayModeTitle).to.equal('Tile view');\n });\n\n it('should change displayMode prop to the one clicked', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar> </sort-filter-bar>\n `);\n\n el.displayMode = 'grid';\n await el.updateComplete;\n\n const extendedListButton = el.shadowRoot?.querySelector(\n '#list-detail-button',\n ) as HTMLElement;\n extendedListButton.click();\n await el.updateComplete;\n expect(el.displayMode).to.equal('list-detail');\n\n const compactListButton = el.shadowRoot?.querySelector(\n '#list-compact-button',\n ) as HTMLElement;\n compactListButton.click();\n await el.updateComplete;\n expect(el.displayMode).to.equal('list-compact');\n\n const gridModeButton = el.shadowRoot?.querySelector(\n '#grid-button',\n ) as HTMLElement;\n gridModeButton.click();\n await el.updateComplete;\n expect(el.displayMode).to.equal('grid');\n });\n});\n\ndescribe('Sort/filter bar letter behavior', () => {\n it('sets the selected title letter when clicked', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar></sort-filter-bar>\n `);\n\n el.selectedSort = 'title' as SortField;\n el.prefixFilterCountMap = { title: { T: 1 }, creator: {} };\n await el.updateComplete;\n\n const alphaBar = el.shadowRoot?.querySelector('alpha-bar');\n const letterLink = alphaBar?.shadowRoot?.querySelector(\n 'li > button:not(:disabled)',\n ) as HTMLAnchorElement;\n expect(letterLink?.textContent?.trim()).to.equal('T');\n\n letterLink?.click();\n await el.updateComplete;\n\n expect(el.selectedTitleFilter).to.equal('T');\n });\n\n it('sets the selected creator letter when clicked', async () => {\n const el = await fixture<SortFilterBar>(html`\n <sort-filter-bar></sort-filter-bar>\n `);\n\n el.selectedSort = 'creator' as SortField;\n el.prefixFilterCountMap = { title: {}, creator: { C: 1 } };\n await el.updateComplete;\n\n const alphaBar = el.shadowRoot?.querySelector('alpha-bar');\n const letterLink = alphaBar?.shadowRoot?.querySelector(\n 'li > button:not(:disabled)',\n ) as HTMLAnchorElement;\n expect(letterLink?.textContent?.trim()).to.equal('C');\n\n letterLink?.click();\n await el.updateComplete;\n\n expect(el.selectedCreatorFilter).to.equal('C');\n });\n});\n"]}
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.0-alpha-webdev8186.1",
6
+ "version": "4.1.0-alpha-webdev8186.3",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/index.js",
9
9
  "scripts": {
@@ -1633,7 +1633,6 @@ export class CollectionBrowser
1633
1633
  dataSource: CollectionBrowserDataSourceInterface,
1634
1634
  queryState: CollectionBrowserQueryState,
1635
1635
  ): Promise<void> {
1636
- log('Installing data source & query state in CB:', dataSource, queryState);
1637
1636
  if (this.dataSource) this.removeController(this.dataSource);
1638
1637
  this.dataSource = dataSource;
1639
1638
  this.addController(this.dataSource);
@@ -2249,12 +2248,8 @@ export class CollectionBrowser
2249
2248
  this.displayMode = restorationState.displayMode;
2250
2249
  if (!this.suppressURLSinParam && restorationState.searchType != null)
2251
2250
  this.searchType = restorationState.searchType;
2252
- this.selectedSort =
2253
- restorationState.selectedSort ??
2254
- this.defaultSortField ??
2255
- SortField.default;
2256
- this.sortDirection =
2257
- restorationState.sortDirection ?? this.defaultSortDirection ?? null;
2251
+ this.selectedSort = restorationState.selectedSort ?? SortField.default;
2252
+ this.sortDirection = restorationState.sortDirection ?? null;
2258
2253
  this.selectedTitleFilter = restorationState.selectedTitleFilter ?? null;
2259
2254
  this.selectedCreatorFilter = restorationState.selectedCreatorFilter ?? null;
2260
2255
  this.selectedFacets = restorationState.selectedFacets;
@@ -250,7 +250,6 @@ export class CollectionBrowserDataSource
250
250
  * @inheritdoc
251
251
  */
252
252
  reset(): void {
253
- log('Resetting CB data source');
254
253
  this.pages = {};
255
254
  this.aggregations = {};
256
255
  this.histogramAggregation = undefined;
@@ -7,7 +7,7 @@ import {
7
7
  TemplateResult,
8
8
  } from 'lit';
9
9
  import { customElement, property, query, state } from 'lit/decorators.js';
10
- import { msg } from '@lit/localize';
10
+ import { msg, str } from '@lit/localize';
11
11
  import type { IaDropdown, optionInterface } from '@internetarchive/ia-dropdown';
12
12
  import type { SortDirection } from '@internetarchive/search-service';
13
13
  import {
@@ -17,6 +17,7 @@ import {
17
17
  PrefixFilterType,
18
18
  SORT_OPTIONS,
19
19
  SortField,
20
+ SortOption,
20
21
  } from '../models';
21
22
 
22
23
  import { sortUpIcon } from './img/sort-toggle-up';
@@ -211,16 +212,19 @@ export class SortFilterBar extends LitElement {
211
212
  /** Template to render the sort direction toggle button */
212
213
  private get sortDirectionSelectorTemplate(): TemplateResult {
213
214
  const oppositeSortDirectionReadable =
214
- this.sortDirection === 'asc' ? 'descending' : 'ascending';
215
- const srLabel = `Change to ${oppositeSortDirectionReadable} sort`;
215
+ this.sortDirection === 'asc' ? msg('descending') : msg('ascending');
216
+ const buttonLabel = this.canChangeSortDirection
217
+ ? msg(str`Change to ${oppositeSortDirectionReadable} sort`)
218
+ : msg('Directions are not available for the current sort option');
216
219
 
217
220
  return html`
218
221
  <button
219
222
  class="sort-direction-selector"
223
+ title=${buttonLabel}
220
224
  ?disabled=${!this.canChangeSortDirection}
221
225
  @click=${this.handleSortDirectionClicked}
222
226
  >
223
- <span class="sr-only">${srLabel}</span>
227
+ <span class="sr-only">${buttonLabel}</span>
224
228
  ${this.sortDirectionIcon}
225
229
  </button>
226
230
  `;
@@ -463,9 +467,15 @@ export class SortFilterBar extends LitElement {
463
467
 
464
468
  /** The current sort field, or the default one if no explicit sort is set */
465
469
  private get finalizedSortField(): SortField {
466
- return this.selectedSort === SortField.default
467
- ? this.defaultSortField
468
- : this.selectedSort;
470
+ const resolvedField =
471
+ this.selectedSort === SortField.default
472
+ ? this.defaultSortField
473
+ : this.selectedSort;
474
+ if (this.sortFieldAvailability[resolvedField]) return resolvedField;
475
+
476
+ // Fall back to the first available sort option shown in the sort bar, if
477
+ // the requested one isn't available
478
+ return this.firstAvailableOption?.field ?? resolvedField;
469
479
  }
470
480
 
471
481
  /** The current sort direction, or the default one if no explicit direction is set */
@@ -475,6 +485,13 @@ export class SortFilterBar extends LitElement {
475
485
  : this.sortDirection;
476
486
  }
477
487
 
488
+ /** The first option shown in the sort dropdown, or undefined if none are available */
489
+ private get firstAvailableOption(): SortOption | undefined {
490
+ return Object.values(SORT_OPTIONS).find(
491
+ opt => opt.shownInSortBar && this.sortFieldAvailability[opt.field],
492
+ );
493
+ }
494
+
478
495
  /** Whether the sort direction button should be enabled for the current sort */
479
496
  private get canChangeSortDirection(): boolean {
480
497
  return SORT_OPTIONS[this.finalizedSortField].canSetDirection;
@@ -970,7 +970,7 @@ describe('Collection Browser', () => {
970
970
  </collection-browser>`,
971
971
  );
972
972
 
973
- expect(el.selectedSort).to.equal(SortField.relevance);
973
+ expect(el.selectedSort).to.equal(SortField.default);
974
974
 
975
975
  el.baseQuery = 'foo';
976
976
  await el.updateComplete;
@@ -88,6 +88,20 @@ describe('Sort dropdown behavior', () => {
88
88
  expect(label?.textContent?.trim()).to.equal('All-time views');
89
89
  });
90
90
 
91
+ it('falls back to first available sort when default is unavailable', async () => {
92
+ el.selectedSort = SortField.default;
93
+ el.defaultSortField = SortField.relevance;
94
+ el.sortFieldAvailability = {
95
+ ...defaultSortAvailability,
96
+ [SortField.relevance]: false,
97
+ };
98
+ await el.updateComplete;
99
+
100
+ const label = sortDropdown?.querySelector('.dropdown-label');
101
+ // No relevance, so fall back to the first one in the list
102
+ expect(label?.textContent?.trim()).to.equal('All-time views');
103
+ });
104
+
91
105
  it('changes selected sort when dropdown option selected', async () => {
92
106
  expect(sortDropdown).to.exist;
93
107