Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui5-filter-item, ui5-sort-item,..): add filterItems to ui5-confirm event details #9838

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
9 changes: 9 additions & 0 deletions packages/fiori/src/FilterItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ class FilterItem extends UI5Element {
*/
@slot()
values!: Array<FilterItemOption>;

/**
* Defines a unique identifier for the component.
* @default undefined
* @public
* @since 2.3.0
*/
@property()
itemKey?: string;
}

FilterItem.define();
Expand Down
9 changes: 9 additions & 0 deletions packages/fiori/src/FilterItemOption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ class FilterItemOption extends UI5Element {
*/
@property({ type: Boolean })
selected = false;

/**
* Defines a unique identifier for the component.
* @default undefined
* @public
* @since 2.3.0
*/
@property()
itemKey?: string;
}

FilterItemOption.define();
Expand Down
9 changes: 9 additions & 0 deletions packages/fiori/src/SortItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ class SortItem extends UI5Element {
*/
@property({ type: Boolean })
selected = false;

/**
* Defines a unique identifier for the component.
* @default undefined
* @public
* @since 2.3.0
*/
@property()
itemKey?: string;
}

SortItem.define();
Expand Down
35 changes: 34 additions & 1 deletion packages/fiori/src/ViewSettingsDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ type ViewSettingsDialogCancelEventDetail = VSDSettings & {
}

// Common properties for several VSDInternalSettings fields
type VSDItem = {text?: string, selected: boolean}
type VSDItem = {text?: string, itemKey?: string, selected: boolean}

// Used for the private properties _initialSettings, _confirmedSettings and _currentSettings
type VSDInternalSettings = {
Expand All @@ -75,6 +75,12 @@ type VSDInternalSettings = {
filters: Array<VSDItem & {filterOptions: Array<VSDItem>}>,
}

type FilterSelection = {
filterItem: VSDItem & {
filterOptions: Array<VSDItem>;
};
};

/**
* @class
* ### Overview
Expand Down Expand Up @@ -447,10 +453,12 @@ class ViewSettingsDialog extends UI5Element {
filters: this.filterItems.map(item => {
return {
text: item.text || "",
itemKey: item.itemKey || "",
selected: false,
filterOptions: item.values.map(optionValue => {
return {
text: optionValue.text || "",
itemKey: optionValue.itemKey || "",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to: item: optionValue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe I can even remove that line, as we can just return the slotted filterItems in the get eventsParams(). This way the app developers could execute their own logic for filtering the selected items based on their HTML Property they have provided (f.e data-key);

selected: optionValue.selected,
};
}),
Expand Down Expand Up @@ -624,6 +632,7 @@ class ViewSettingsDialog extends UI5Element {
sortBy,
sortByItem,
filters: this.selectedFilters,
filterItems: this.selectedFilterItems,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this new field really necessary? Can't the app do this if they need such information? Or is this code required by the control somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The app cannot do this themself because until now we only return the text of the provided filters in the details, therefore we would have to provide the ui5-filter-item, and its ui5-filter-item-option's in the event details.
This way providing for example data-key="filterText1" to the ui5-filter-item or ui5-filter-item-option would make them able to be accessed by $0.dataset.key HTML Property.

};
}

Expand All @@ -648,6 +657,30 @@ class ViewSettingsDialog extends UI5Element {
return result;
}

get selectedFilterItems() {
const result: Array<FilterSelection> = [];

this._currentSettings.filters.forEach(filter => {
const selectedOptions: Array<VSDItem> = [];

filter.filterOptions.forEach(option => {
if (option.selected) {
selectedOptions.push(option);
}
});

if (selectedOptions.length) {
const filterItemObject: FilterSelection = {
filterItem: filter,
};

result.push(filterItemObject);
}
});

return result;
}

/**
* If the dialog is closed by [Escape] key, do the same as if the `Cancel` button is pressed.
* @param evt
Expand Down
41 changes: 41 additions & 0 deletions packages/fiori/test/pages/ViewSettingsDialog.html
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,48 @@ <h3> ViewSettingsDialog</h3>
<ui5-input id="sortByItem" style="display: none"></ui5-input>
<ui5-input id="sortOrder" style="display: none"></ui5-input>

<h3>ViewSettingsDialog with item-keys</h3>

<ui5-button id="btnOpenDialogWithItemKey">Show ViewSettingsDialog</ui5-button>
<ui5-view-settings-dialog id="vsdWithItemKey">
<ui5-sort-item slot="sortItems" text="Name" item-key="sortName"></ui5-sort-item>
<ui5-sort-item slot="sortItems" text="Position" item-key="sortPosition"></ui5-sort-item>
<ui5-sort-item slot="sortItems" text="Company" item-key="sortCompany"></ui5-sort-item>

<ui5-filter-item slot="filterItems" text="Category" item-key="filterCategory">
<ui5-filter-item-option slot="values" text="Electronics" item-key="filterOptionElectronics"></ui5-filter-item-option>
<ui5-filter-item-option slot="values" text="Clothing" item-key="filterOptionClothing"></ui5-filter-item-option>
</ui5-filter-item>

<ui5-filter-item slot="filterItems" text="Color" item-key="filterColor">
<ui5-filter-item-option slot="values" text="Red" item-key="filterOptionRed"></ui5-filter-item-option>
<ui5-filter-item-option slot="values" text="Blue" item-key="filterOptionBlue"></ui5-filter-item-option>
</ui5-filter-item>

</ui5-view-settings-dialog>

<script>
btnOpenDialogWithItemKey.addEventListener("click", function () {
vsdWithItemKey.open = true;
});

vsdWithItemKey.addEventListener("ui5-confirm", function(e) {
const filterItems = e.detail.filterItems || [];
const selectedFilterItems = filterItems.flatMap(item => item.filterItem.filterOptions.filter(option => option.selected));
console.log("Selected Filters: ", e.detail.filters || []);

if (filterItems.length > 0) {
console.log("First Filter Item Key: ", filterItems[0].filterItem.itemKey);
}

if (selectedFilterItems.length > 0) {
console.log("First Selected Option Text: ", selectedFilterItems[0].text);
console.log("First Selected Option Item Key: ", selectedFilterItems[0].itemKey);
}

alert("OK button clicked, returned info is: " + JSON.stringify(e.detail));
});

btnOpenDialog.addEventListener("click", function () {
vsd.open = true;
});
Expand Down
34 changes: 33 additions & 1 deletion packages/fiori/test/specs/ViewSettingsDialog.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ describe("ViewSettingsDialog general interaction", () => {
await viewSettingsDialog.shadow$("ui5-dialog").$(".ui5-vsd-header").$("ui5-button").click();

const sortByLiText = await viewSettingsDialog.shadow$("[sort-by]").$("ui5-li").getText();
assert.include(sortByLiText, "Name", "sortBy should have an option selected");
assert.include(sortByLiText, "Name", "sortBy should have an option selected");

await browser.keys("Escape");
});
Expand Down Expand Up @@ -176,4 +176,36 @@ describe("ViewSettingsDialog general interaction", () => {

await browser.keys("Escape");
});

it("should access the same sort item via item-key, after text being changed", async () => {
const btnOpenDialog = await browser.$("#btnOpenDialogWithItemKey");
const viewSettingsDialog = await browser.$("#vsdWithItemKey");

await btnOpenDialog.click();

// Access the sort item using item-key
const sortItem = await viewSettingsDialog.$(`[item-key="sortCompany"]`);
const secondSortItemLi = await viewSettingsDialog.shadow$("[sort-by]").$$("ui5-li")[1];

// Get the text of the list item
let sortItemLiText = await viewSettingsDialog.shadow$("[sort-by]").$$("ui5-li")[2].getText();
sortItemLiText = sortItemLiText.split("\n")[0]; // Trim the text because it returns 'Company\nNot Selected';

let sortItemText = await sortItem.getAttribute("text");

assert.strictEqual(sortItemLiText, sortItemText, "The sort item text is the same as the li text before update");

// Change the text of the item
await sortItem.setAttribute("text", "Cooperation");

await browser.keys("Escape");
await btnOpenDialog.click();
secondSortItemLi.click(); // Click on another item to re-render, so the text changes successfully.

sortItemLiText = await viewSettingsDialog.shadow$("[sort-by]").$$("ui5-li")[2].getText();
sortItemLiText = sortItemLiText.split("\n")[0];
sortItemText = await sortItem.getAttribute("text");

assert.strictEqual(sortItemLiText, sortItemText, "The sort item text is the same as the li text after update");
});
});