[IMP] web: SelectMenu: add autoSort props
By default, the SelectMenu component alphabetically sorts the choices. Before this commit, this wasn't avoidable. As there's now a usecase of SelectMenu where we want to enforce a specific order on the choices (the website AceEditor), this commit introduces a props `autoSort`, which is `true` by default, but which allows to disable the sort. Part-of: odoo/odoo#139154
This commit is contained in:
@@ -24,6 +24,7 @@ export class SelectMenu extends Component {
|
||||
onSelect: () => {},
|
||||
required: false,
|
||||
searchable: true,
|
||||
autoSort: true,
|
||||
searchPlaceholder: _t("Search..."),
|
||||
choices: [],
|
||||
groups: [],
|
||||
@@ -65,6 +66,7 @@ export class SelectMenu extends Component {
|
||||
togglerClass: { type: String, optional: true },
|
||||
required: { type: Boolean, optional: true },
|
||||
searchable: { type: Boolean, optional: true },
|
||||
autoSort: { type: Boolean, optional: true },
|
||||
searchPlaceholder: { type: String, optional: true },
|
||||
value: { optional: true },
|
||||
multiSelect: { type: Boolean, optional: true },
|
||||
@@ -246,9 +248,11 @@ export class SelectMenu extends Component {
|
||||
);
|
||||
} else {
|
||||
filteredOptions = group.choices;
|
||||
filteredOptions.sort((optionA, optionB) =>
|
||||
optionA.label.localeCompare(optionB.label)
|
||||
);
|
||||
if (this.props.autoSort) {
|
||||
filteredOptions.sort((optionA, optionB) =>
|
||||
optionA.label.localeCompare(optionB.label)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (filteredOptions.length === 0) {
|
||||
@@ -264,23 +268,6 @@ export class SelectMenu extends Component {
|
||||
this.sliceDisplayedOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the choices while keeping the groups separation
|
||||
* @param {[]} choices
|
||||
*/
|
||||
sortGroups(choices) {
|
||||
const groupsIndex = this.getGroupsIndex(choices);
|
||||
for (let i = 0; i < groupsIndex.length; i++) {
|
||||
const startIndex = choices[groupsIndex[i]].isGroup
|
||||
? groupsIndex[i] + 1
|
||||
: groupsIndex[i];
|
||||
const lastIndex = i === groupsIndex.length - 1 ? choices.length : groupsIndex[i + 1];
|
||||
const groupSlice = choices.slice(startIndex, lastIndex);
|
||||
groupSlice.sort((optionA, optionB) => optionA.label.localeCompare(optionB.label));
|
||||
choices.splice(startIndex, lastIndex - startIndex, ...groupSlice);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns each group starting index.
|
||||
* @param {[]} choices
|
||||
|
||||
@@ -315,7 +315,7 @@ QUnit.module("Web Components", (hooks) => {
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test("Items are sorted based on their label", async (assert) => {
|
||||
QUnit.test("Items are sorted based on their label by default", async (assert) => {
|
||||
class Parent extends Component {
|
||||
setup() {
|
||||
this.choices = [
|
||||
@@ -343,6 +343,30 @@ QUnit.module("Web Components", (hooks) => {
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("autoSort props set to false", async (assert) => {
|
||||
class Parent extends Component {
|
||||
setup() {
|
||||
this.choices = [
|
||||
{ label: "Hello", value: "hello" },
|
||||
{ label: "World", value: "world" },
|
||||
{ label: "Foo", value: "foo" },
|
||||
{ label: "Bar", value: "bar" },
|
||||
];
|
||||
}
|
||||
}
|
||||
Parent.components = { SelectMenu };
|
||||
Parent.template = xml`<SelectMenu choices="choices" autoSort="false"/>`;
|
||||
|
||||
await mount(Parent, target, { env });
|
||||
await open();
|
||||
|
||||
const choices = [...target.querySelectorAll(".o_select_menu_item_label")];
|
||||
assert.deepEqual(
|
||||
choices.map((el) => el.textContent),
|
||||
["Hello", "World", "Foo", "Bar"]
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("Custom toggler using default slot", async (assert) => {
|
||||
class Parent extends Component {
|
||||
setup() {
|
||||
|
||||
Reference in New Issue
Block a user