From d037b89fe3711c89f80602c0f25134623d3dc9aa Mon Sep 17 00:00:00 2001 From: Aashish Sharma Date: Wed, 20 Aug 2025 14:33:35 +0530 Subject: [PATCH] mgr/dashboard: Fix duplicate selection on multi-select in table component Fixes: https://tracker.ceph.com/issues/72656 Signed-off-by: Aashish Sharma (cherry picked from commit bfe5aac3f12bed56749c4710acb3a114555bdb51) --- .../shared/datatable/table/table.component.ts | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts index 1e372643810c4..59855240bb57f 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts @@ -995,15 +995,23 @@ export class TableComponent implements AfterViewInit, OnInit, OnChanges, OnDestr } } }); - if (newSelected.size === 0) return; + const newSelectedArray = Array.from(newSelected.values()); - newSelectedArray?.forEach?.((selection: any) => { + if (newSelectedArray.length === 0) { + this.selection.selected = []; + this.updateSelection.emit(_.clone(this.selection)); + return; + } + + newSelectedArray.forEach((selection: any) => { const rowIndex = this.model.data.findIndex( (row: TableItem[]) => _.get(row, [0, 'selected', this.identifier]) === selection[this.identifier] ); - rowIndex > -1 && this.model.selectRow(rowIndex, true); + if (rowIndex > -1) { + this.model.selectRow(rowIndex, true); + } }); if ( @@ -1015,11 +1023,9 @@ export class TableComponent implements AfterViewInit, OnInit, OnChanges, OnDestr this.selection.selected = newSelectedArray; - if (this.updateSelectionOnRefresh === 'never') { - return; + if (this.updateSelectionOnRefresh !== 'never') { + this.updateSelection.emit(_.clone(this.selection)); } - - this.updateSelection.emit(_.clone(this.selection)); } updateExpanded() { @@ -1040,7 +1046,12 @@ export class TableComponent implements AfterViewInit, OnInit, OnChanges, OnDestr _toggleSelection(rowIndex: number, isSelected: boolean) { const selectedData = _.get(this.model.data?.[rowIndex], [0, 'selected']); if (isSelected) { - this.selection.selected = [...this.selection.selected, selectedData]; + const alreadySelected = this.selection.selected.some( + (s) => s[this.identifier] === selectedData[this.identifier] + ); + if (!alreadySelected) { + this.selection.selected = [...this.selection.selected, selectedData]; + } } else { this.selection.selected = this.selection.selected.filter( (s) => s[this.identifier] !== selectedData[this.identifier] @@ -1049,14 +1060,15 @@ export class TableComponent implements AfterViewInit, OnInit, OnChanges, OnDestr } onSelect(selectedRowIndex: number) { - const selectedData = _.get(this.model.data?.[selectedRowIndex], [0, 'selected']); if (this.selectionType === 'single') { this.model.selectAll(false); - this.selection.selected = [selectedData]; + this.selection.selected = [_.get(this.model.data?.[selectedRowIndex], [0, 'selected'])]; + this.model.selectRow(selectedRowIndex, true); } else { - this.selection.selected = [...this.selection.selected, selectedData]; + const isSelected = this.model.rowsSelected[selectedRowIndex] ?? false; + this._toggleSelection(selectedRowIndex, !isSelected); + this.model.selectRow(selectedRowIndex, !isSelected); } - this.model.selectRow(selectedRowIndex, true); this.updateSelection.emit(this.selection); } -- 2.39.5