diff --git a/packages/fiori/cypress/specs/ViewSettingsDialog.cy.tsx b/packages/fiori/cypress/specs/ViewSettingsDialog.cy.tsx new file mode 100644 index 000000000000..3523de294d29 --- /dev/null +++ b/packages/fiori/cypress/specs/ViewSettingsDialog.cy.tsx @@ -0,0 +1,176 @@ +import ViewSettingsDialog from "../../src/ViewSettingsDialog.js"; +import SortItem from "../../src/SortItem.js"; +import FilterItem from "../../src/FilterItem.js"; +import FilterItemOption from "../../src/FilterItemOption.js"; + +describe("View settings dialog - selection", () => { + it("tests clicking on sort items (both on the text and radio button)", () => { + cy.mount( + + + + + ); + + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(100); // Wait after mounting the component temporarily, until the component is fully rendered TODO: remove this after the issue is fixed + + // Open the dialog and wait until it's visible + cy.get("[ui5-view-settings-dialog]") + .as("vsd") + .invoke("prop", "open", true); + + cy.get("@vsd") + .shadow() + .find("[ui5-dialog]") + .should("be.visible"); + + // There should be 4 list items in the dialog - Ascending, Descending, Name, Position + cy.get("@vsd") + .shadow() + .find("[ui5-li]") + .should("have.length", 4); + + // Click the TEXT of the 4th item (Position) + cy.get("@vsd") + .shadow() + .find("[ui5-li]") + .eq(3) + .shadow() + .find("span[part=title]") // we click the text itself first + .realClick(); + + // Click the OK button of the dialog + cy.get("@vsd") + .shadow() + .find("ui5-button[design=Emphasized]") + .realClick(); + + // Check if the confirm event was fired with sortBy = "Position" + cy.get("@confirm") + .should("be.called") + .its("firstCall.args.0.detail.sortBy") + .should("equal", "Position"); + + // Wait until the dialog is closed + cy.get("@vsd") + .shadow() + .find("[ui5-dialog]") + .should("not.be.visible"); + + // Open the dialog again and wait until it's visible + cy.get("@vsd") + .invoke("prop", "open", true); + + cy.get("@vsd") + .shadow() + .find("[ui5-dialog]") + .should("be.visible"); + + // Click the RADIO BUTTON of the 3th item (Name) instead of the text this time + cy.get("@vsd") + .shadow() + .find("[ui5-li]") + .eq(2) + .shadow() + .find("[ui5-radio-button]") + .realClick(); + + // Click the OK button of the dialog again + cy.get("@vsd") + .shadow() + .find("ui5-button[design=Emphasized]") + .realClick(); + + // Check if the confirm event was fired for a second time, now with sortBy = "Name" + cy.get("@confirm") + .should("be.called") + .its("secondCall.args.0.detail.sortBy") + .should("equal", "Name"); + }); + + it("tests clicking on filter items, and filter item options (both on the text and checkbox)", () => { + cy.mount( + + + + + + + + + + + + + ); + + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(100); // Wait after mounting the component temporarily, until the component is fully rendered TODO: remove this after the issue is fixed + + // Open the dialog and wait until it's visible + cy.get("[ui5-view-settings-dialog]") + .as("vsd") + .invoke("prop", "open", true) + .shadow() + .find("[ui5-dialog]") + .should("be.visible"); + + // There should be 2 list items in the dialog - Filter 1 and Filter 2 + cy.get("@vsd") + .shadow() + .find("[ui5-li]") + .should("have.length", 2); + + // Click the "Filter 1" item + cy.get("@vsd") + .shadow() + .find("[ui5-li]") + .eq(0) + .shadow() + .find("span[part=title]") + .realClick(); + + // There should be 3 list items in the dialog - Some filter 1, Some filter 2, Some filter 3 + cy.get("@vsd") + .shadow() + .find("[ui5-li]") + .should("have.length", 3); + + // Click on the text of the first list item (Some filter 1) + cy.get("@vsd") + .shadow() + .find("[ui5-li]") + .eq(0) + .shadow() + .find("span[part=title]") + .realClick(); + + // Click on the checkbox of the third list item (Some filter 3) + cy.get("@vsd") + .shadow() + .find("[ui5-li]") + .eq(2) + .shadow() + .find("[ui5-checkbox]") + .realClick(); + + // Click the OK button of the dialog + cy.get("@vsd") + .shadow() + .find("ui5-button[design=Emphasized]") + .realClick(); + + // Check if the confirm event was fired with: filters = [{"Filter 1":["Some filter 1","Some filter 3"]}] + cy.get("@confirm") + .should("be.called") + .its("firstCall.args.0.detail.filters") + .should("deep.equal", [{ "Filter 1": ["Some filter 1", "Some filter 3"] }]); + + // Wait until the dialog is closed + cy.get("@vsd") + .shadow() + .find("[ui5-dialog]") + .should("not.be.visible"); + }); +}); diff --git a/packages/fiori/src/ViewSettingsDialog.ts b/packages/fiori/src/ViewSettingsDialog.ts index 2e5e4eb7594a..dba97ded634e 100644 --- a/packages/fiori/src/ViewSettingsDialog.ts +++ b/packages/fiori/src/ViewSettingsDialog.ts @@ -10,7 +10,7 @@ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import type { ChangeInfo } from "@ui5/webcomponents-base/dist/UI5Element.js"; import type Dialog from "@ui5/webcomponents/dist/Dialog.js"; import type List from "@ui5/webcomponents/dist/List.js"; -import type { ListItemClickEventDetail } from "@ui5/webcomponents/dist/List.js"; +import type { ListItemClickEventDetail, ListSelectionChangeEventDetail } from "@ui5/webcomponents/dist/List.js"; import announce from "@ui5/webcomponents-base/dist/util/InvisibleMessage.js"; import InvisibleMessageMode from "@ui5/webcomponents-base/dist/types/InvisibleMessageMode.js"; @@ -515,12 +515,14 @@ class ViewSettingsDialog extends UI5Element { this._currentMode = ViewSettingsDialogMode[mode]; } - _handleFilterValueItemClick(e: CustomEvent) { + _handleFilterValueItemClick(e: CustomEvent) { + const itemText = e.detail.targetItem.innerText; + // Update the component state this._currentSettings.filters = this._currentSettings.filters.map(filter => { if (filter.selected) { filter.filterOptions.forEach(option => { - if (option.text === e.detail.item.innerText) { + if (option.text === itemText) { option.selected = !option.selected; } }); @@ -528,20 +530,19 @@ class ViewSettingsDialog extends UI5Element { return filter; }); - this._setSelectedProp(e); + this._setSelectedProp(itemText); this._currentSettings = JSON.parse(JSON.stringify(this._currentSettings)); } /** * Sets the selected property of the clicked item. - * @param e * @private */ - _setSelectedProp(e: CustomEvent) { + _setSelectedProp(itemText: string) { this.filterItems.forEach(filterItem => { filterItem.values.forEach(option => { - if (option.text === e.detail.item.innerText) { + if (option.text === itemText) { option.selected = !option.selected; } }); @@ -669,10 +670,10 @@ class ViewSettingsDialog extends UI5Element { /** * Stores `Sort Order` list as recently used control and its selected item in current state. */ - _onSortOrderChange(e: CustomEvent) { + _onSortOrderChange(e: CustomEvent) { this._recentlyFocused = this._sortOrder!; this._currentSettings.sortOrder = this.initSortOrderItems.map(item => { - item.selected = item.text === e.detail.item.innerText; + item.selected = item.text === e.detail.targetItem.innerText; return item; }); @@ -683,8 +684,8 @@ class ViewSettingsDialog extends UI5Element { /** * Stores `Sort By` list as recently used control and its selected item in current state. */ - _onSortByChange(e: CustomEvent) { - const selectedItemIndex = Number(e.detail.item.getAttribute("data-ui5-external-action-item-index")); + _onSortByChange(e: CustomEvent) { + const selectedItemIndex = Number(e.detail.targetItem.getAttribute("data-ui5-external-action-item-index")); this._recentlyFocused = this._sortBy!; this._currentSettings.sortBy = this.initSortByItems.map((item, index) => { item.selected = index === selectedItemIndex; diff --git a/packages/fiori/src/ViewSettingsDialogTemplate.tsx b/packages/fiori/src/ViewSettingsDialogTemplate.tsx index 97ef24f49990..cf8b69361bd6 100644 --- a/packages/fiori/src/ViewSettingsDialogTemplate.tsx +++ b/packages/fiori/src/ViewSettingsDialogTemplate.tsx @@ -78,7 +78,7 @@ function ViewSettingsDialogTemplateContent(this: ViewSettingsDialog) {
@@ -92,7 +92,7 @@ function ViewSettingsDialogTemplateContent(this: ViewSettingsDialog) { @@ -110,7 +110,7 @@ function ViewSettingsDialogTemplateContent(this: ViewSettingsDialog) { {this._filterStepTwo ? ( {this._currentSettings.filters.filter(item => item.selected).map(item => (<> @@ -123,7 +123,7 @@ function ViewSettingsDialogTemplateContent(this: ViewSettingsDialog) { ) : ( // else