From cb220ce268b523abee4899423c99bbc219ed5496 Mon Sep 17 00:00:00 2001
From: jorgep <jorgep@verdnatura.es>
Date: Tue, 25 Feb 2025 18:14:32 +0100
Subject: [PATCH] fix: refs #8078 enhance row selection logic in VnTable
 component

---
 src/components/VnTable/VnTable.vue            | 10 ++++-
 .../VnTable/__tests__/VnTable.spec.js         | 40 ++++++++++++++++---
 2 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue
index 6e5f9fef4c6..a5173374bfa 100644
--- a/src/components/VnTable/VnTable.vue
+++ b/src/components/VnTable/VnTable.vue
@@ -295,8 +295,14 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
     if (evt?.shiftKey && added) {
         const rowIndex = selectedRows[0].$index;
         const selectedIndexes = new Set(selected.value.map((row) => row.$index));
-        for (const row of rows) {
-            if (row.$index == rowIndex) break;
+        const minIndex = selectedIndexes.size
+            ? Math.min(...selectedIndexes, rowIndex)
+            : 0;
+        const maxIndex = Math.max(...selectedIndexes, rowIndex);
+
+        for (let i = minIndex; i <= maxIndex; i++) {
+            const row = rows[i];
+            if (row.$index == rowIndex) continue;
             if (!selectedIndexes.has(row.$index)) {
                 selected.value.push(row);
                 selectedIndexes.add(row.$index);
diff --git a/src/components/VnTable/__tests__/VnTable.spec.js b/src/components/VnTable/__tests__/VnTable.spec.js
index 74ba0698765..e5e38a63c6c 100644
--- a/src/components/VnTable/__tests__/VnTable.spec.js
+++ b/src/components/VnTable/__tests__/VnTable.spec.js
@@ -27,30 +27,58 @@ describe('VnTable', () => {
     beforeEach(() => (vm.selected = []));
 
     describe('handleSelection()', () => {
-        const rows = [{ $index: 0 }, { $index: 1 }, { $index: 2 }];
-        const selectedRows = [{ $index: 1 }];
-        it('should add rows to selected when shift key is pressed and rows are added except last one', () => {
+        const rows = [
+            { $index: 0 },
+            { $index: 1 },
+            { $index: 2 },
+            { $index: 3 },
+            { $index: 4 },
+        ];
+
+        it('should add rows to selected when shift key is pressed and rows are added in ascending order', () => {
+            const selectedRows = [{ $index: 1 }];
             vm.handleSelection(
                 { evt: { shiftKey: true }, added: true, rows: selectedRows },
-                rows
+                rows,
             );
             expect(vm.selected).toEqual([{ $index: 0 }]);
         });
 
+        it('should add rows to selected when shift key is pressed and rows are added in descending order', () => {
+            const selectedRows = [{ $index: 3 }];
+            vm.handleSelection(
+                { evt: { shiftKey: true }, added: true, rows: selectedRows },
+                rows,
+            );
+            expect(vm.selected).toEqual([{ $index: 0 }, { $index: 1 }, { $index: 2 }]);
+        });
+
         it('should not add rows to selected when shift key is not pressed', () => {
+            const selectedRows = [{ $index: 1 }];
             vm.handleSelection(
                 { evt: { shiftKey: false }, added: true, rows: selectedRows },
-                rows
+                rows,
             );
             expect(vm.selected).toEqual([]);
         });
 
         it('should not add rows to selected when rows are not added', () => {
+            const selectedRows = [{ $index: 1 }];
             vm.handleSelection(
                 { evt: { shiftKey: true }, added: false, rows: selectedRows },
-                rows
+                rows,
             );
             expect(vm.selected).toEqual([]);
         });
+
+        it('should add all rows between the smallest and largest selected indexes', () => {
+            vm.selected = [{ $index: 1 }, { $index: 3 }];
+            const selectedRows = [{ $index: 4 }];
+            vm.handleSelection(
+                { evt: { shiftKey: true }, added: true, rows: selectedRows },
+                rows,
+            );
+            expect(vm.selected).toEqual([{ $index: 1 }, { $index: 3 }, { $index: 2 }]);
+        });
     });
 });