GlCollapsibleListbox: Add ability to emit the entire selected item rather than just the value property
Currently for the listbox, when using v-model or a select listener, the emitted event only emits the item's value property. However, in many cases we need to get the item object itself rather than its value property. This is causing us to add a lot of boilerplate code where despite passing in the item objects to listbox:
const items = [
{ value: 1, text: 'Item 1', fullPath: 'item/1' },
{ value: 2, text: 'Item 2', fullPath: 'item/2' },
{ value: 3, text: 'Item 3', fullPath: 'item/3' },
]
<gl-collapsible-listbox
:items="items"
@select="selectItem"
/>
in the select listener callback we need to do a find() to get back the selected item object:
selectItem(value) {
this.selectedItem = this.items.find(({ id }) => id === value)
}
Examples of boilerplate code usage:
projects_dropdown_filter.vueiteration_dropdown.vueprotected_branches_selector.vuetopic_select.vueboard_add_new_column.vueprojects_dropdown.vuegroup_select.vuetype_select.vueproject_dropdown.vuetype_select.vuerole_dropdown.vue
Proposal
In addition to the item's value, also emit the item itself. It can be added as a second parameter to preserve backwards compatibility with existing code. Patch:
Index: src/components/base/new_dropdowns/listbox/listbox.vue
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/components/base/new_dropdowns/listbox/listbox.vue b/src/components/base/new_dropdowns/listbox/listbox.vue
--- a/src/components/base/new_dropdowns/listbox/listbox.vue (revision 5c2c59687b68f66906a9b246b3e7cddee5f67e01)
+++ b/src/components/base/new_dropdowns/listbox/listbox.vue (date 1701510050790)
@@ -627,9 +627,9 @@
},
onSelect(item, isSelected) {
if (this.multiple) {
- this.onMultiSelect(item.value, isSelected);
+ this.onMultiSelect(item, isSelected);
} else {
- this.onSingleSelect(item.value, isSelected);
+ this.onSingleSelect(item, isSelected);
}
},
isSelected(item) {
@@ -638,25 +638,28 @@
isFocused(item) {
return this.nextFocusedItemIndex === this.flattenedOptions.indexOf(item);
},
- onSingleSelect(value, isSelected) {
+ onSingleSelect(item, isSelected) {
if (isSelected) {
/**
* Emitted when selection is changed
*
* @event select
*/
- this.$emit('select', value);
+ this.$emit('select', item.value, item);
}
this.closeAndFocus();
},
- onMultiSelect(value, isSelected) {
+ onMultiSelect(item, isSelected) {
+ const selectedItems = this.items.filter(({ value }) => this.selectedValues.includes(value));
+
if (isSelected) {
- this.$emit('select', [...this.selectedValues, value]);
+ this.$emit('select', [...this.selectedValues, item.value], [...selectedItems, item]);
} else {
this.$emit(
'select',
- this.selectedValues.filter((selectedValue) => selectedValue !== value)
+ this.selectedValues.filter((selectedValue) => selectedValue !== item.value),
+ selectedItems.filter(({ value }) => value !== item.value)
);
}
},
Edited by Daniel Tian