diff --git a/common/changes/@visactor/vtable/fix-issue-5214-delete-selected-rows_2026-07-14-21-21.json b/common/changes/@visactor/vtable/fix-issue-5214-delete-selected-rows_2026-07-14-21-21.json new file mode 100644 index 0000000000..3857992a67 --- /dev/null +++ b/common/changes/@visactor/vtable/fix-issue-5214-delete-selected-rows_2026-07-14-21-21.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "fix: delete reverse-selected rows from context menu", + "type": "none", + "packageName": "@visactor/vtable" + } + ], + "packageName": "@visactor/vtable", + "email": "biukam.w@gmail.com" +} \ No newline at end of file diff --git a/packages/vtable-plugins/__tests__/context-menu/handle-menu-helper.test.ts b/packages/vtable-plugins/__tests__/context-menu/handle-menu-helper.test.ts new file mode 100644 index 0000000000..1c777b352a --- /dev/null +++ b/packages/vtable-plugins/__tests__/context-menu/handle-menu-helper.test.ts @@ -0,0 +1,65 @@ +// @ts-nocheck +import { ListTable } from '@visactor/vtable'; +import { createDiv } from '../../../vtable/__tests__/dom'; +import { MenuHandler } from '../../src/contextmenu/handle-menu-helper'; +import { TableSeriesNumber } from '../../src/table-series-number'; + +global.__VERSION__ = 'none'; + +describe('Context menu row deletion', () => { + let table: ListTable; + + afterEach(() => { + table?.release(); + document.body.innerHTML = ''; + }); + + test('deletes all rows in a reverse-dragged row selection', () => { + const container = createDiv(); + container.style.width = '600px'; + container.style.height = '400px'; + + const seriesNumberPlugin = new TableSeriesNumber({ + rowCount: 5, + colCount: 2 + }); + table = new ListTable({ + container, + showHeader: false, + columns: [ + { field: 'id', title: 'ID' }, + { field: 'name', title: 'Name' } + ], + records: [ + { id: 0, name: 'A' }, + { id: 1, name: 'B' }, + { id: 2, name: 'C' }, + { id: 3, name: 'D' }, + { id: 4, name: 'E' } + ], + syncRecordOperationsToSourceRecords: true, + plugins: [seriesNumberPlugin] + }); + + table.stateManager.select.ranges = [ + { + start: { col: 0, row: 3 }, + end: { col: table.colCount - 1, row: 1 } + } + ]; + + const selectCells = jest.spyOn(table, 'selectCells'); + seriesNumberPlugin['handleSeriesNumberCellRightClick']({ + detail: { + seriesNumberCell: { id: 2, name: 'row-series-number-cell' }, + event: new MouseEvent('contextmenu') + } + }); + + expect(selectCells).not.toHaveBeenCalled(); + + new MenuHandler().handleDeleteRow(table); + + expect(table.records.map(record => record.id)).toEqual([0, 4]); + }); +}); diff --git a/packages/vtable-plugins/src/contextmenu/handle-menu-helper.ts b/packages/vtable-plugins/src/contextmenu/handle-menu-helper.ts index 1528a775e9..94fdf081e4 100644 --- a/packages/vtable-plugins/src/contextmenu/handle-menu-helper.ts +++ b/packages/vtable-plugins/src/contextmenu/handle-menu-helper.ts @@ -105,7 +105,9 @@ export class MenuHandler { const deleteRowIndexs: number[] = []; for (let i = 0; i < selectRanges.length; i++) { const range = selectRanges[i]; - for (let j = range.start.row; j <= range.end.row; j++) { + const startRow = Math.min(range.start.row, range.end.row); + const endRow = Math.max(range.start.row, range.end.row); + for (let j = startRow; j <= endRow; j++) { if (!deleteRowIndexs.includes(j)) { deleteRowIndexs.push(j); } diff --git a/packages/vtable-plugins/src/table-series-number.ts b/packages/vtable-plugins/src/table-series-number.ts index 8919a1cded..4d581d8c9b 100644 --- a/packages/vtable-plugins/src/table-series-number.ts +++ b/packages/vtable-plugins/src/table-series-number.ts @@ -289,9 +289,11 @@ export class TableSeriesNumber implements pluginsDefinition.IVTablePlugin { const rowIndex = seriesNumberCell.id; //判断rowIndex整行是否被选中 const isRowSelected = this.table.stateManager.select.ranges.some(range => { + const startRow = Math.min(range.start.row, range.end.row); + const endRow = Math.max(range.start.row, range.end.row); return ( - range.start.row <= rowIndex && - rowIndex <= range.end.row && + startRow <= rowIndex && + rowIndex <= endRow && range.start.col === 0 && range.end.col === this.table.colCount - 1 );