From ef27a15524f3636ade66aefab0b33c5bf4ea2fe9 Mon Sep 17 00:00:00 2001 From: Florian Damhaut Date: Wed, 4 Dec 2024 17:20:22 +0100 Subject: [PATCH] [IMP] selection: alleviate size of revision on 'move header' Aleviate the size of the message dispatched on the server by grouping the dispatch per size and only if it's different from the current size. closes odoo/o-spreadsheet#5310 Task: 4378896 Signed-off-by: Pierre Rousseau (pro) --- src/plugins/ui_stateful/selection.ts | 17 +++++-- tests/sheet/selection_plugin.test.ts | 70 ++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/src/plugins/ui_stateful/selection.ts b/src/plugins/ui_stateful/selection.ts index bef4b3316a..adc946f008 100644 --- a/src/plugins/ui_stateful/selection.ts +++ b/src/plugins/ui_stateful/selection.ts @@ -580,15 +580,26 @@ export class GridSelectionPlugin extends UIPlugin { const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements; let currentIndex = cmd.base; + + const resizingGroups: Record = {}; + for (const element of toRemove) { const size = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, element); + const currentSize = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, currentIndex); + if (size != currentSize) { + resizingGroups[size] ??= []; + resizingGroups[size].push(currentIndex); + currentIndex += 1; + } + } + + for (const size in resizingGroups) { this.dispatch("RESIZE_COLUMNS_ROWS", { dimension: cmd.dimension, sheetId: cmd.sheetId, - size, - elements: [currentIndex], + size: parseInt(size, 10), + elements: resizingGroups[size], }); - currentIndex += 1; } this.dispatch("REMOVE_COLUMNS_ROWS", { diff --git a/tests/sheet/selection_plugin.test.ts b/tests/sheet/selection_plugin.test.ts index 1ff26f9022..145efeb126 100644 --- a/tests/sheet/selection_plugin.test.ts +++ b/tests/sheet/selection_plugin.test.ts @@ -1,3 +1,4 @@ +import { CoreCommand, CorePlugin } from "../../src"; import { DEFAULT_CELL_HEIGHT, DEFAULT_CELL_WIDTH } from "../../src/constants"; import { numberToLetters, @@ -8,6 +9,7 @@ import { zoneToXc, } from "../../src/helpers"; import { Model } from "../../src/model"; +import { corePluginRegistry } from "../../src/plugins"; import { CommandResult, Direction } from "../../src/types"; import { activateSheet, @@ -42,6 +44,7 @@ import { getCellContent, getSelectionAnchorCellXc, } from "../test_helpers/getters_helpers"; +import { addTestPlugin } from "../test_helpers/helpers"; let model: Model; const hiddenContent = "hidden content to be skipped"; @@ -925,6 +928,39 @@ describe("move elements(s)", () => { expect(model.getters.getColSize(sheetId, 2)).toEqual(10); }); + test("Move resized columns preserves their sizes", () => { + let cmds: CoreCommand[] = []; + class CommandSpy extends CorePlugin { + static getters = []; + handle(command: CoreCommand) { + if (command.type === "RESIZE_COLUMNS_ROWS") { + cmds.push(command); + } + } + } + addTestPlugin(corePluginRegistry, CommandSpy); + + const model = new Model(); + resizeColumns(model, ["A", "B"], 10); + resizeColumns(model, ["C", "D"], 20); + + moveColumns(model, "A", ["C", "D"]); + + const sheetId = model.getters.getActiveSheetId(); + expect(model.getters.getColSize(sheetId, 0)).toEqual(20); + expect(model.getters.getColSize(sheetId, 1)).toEqual(20); + expect(model.getters.getColSize(sheetId, 2)).toEqual(10); + expect(model.getters.getColSize(sheetId, 3)).toEqual(10); + + expect(cmds[2]).toStrictEqual({ + type: "RESIZE_COLUMNS_ROWS", + dimension: "COL", + sheetId, + elements: [0, 1], + size: 20, + }); + }); + test("Move a resized row preserves its size", () => { const model = new Model(); resizeRows(model, [0], 10); @@ -936,6 +972,40 @@ describe("move elements(s)", () => { expect(model.getters.getRowSize(sheetId, 2)).toEqual(10); }); + test("Move resized rows preserves their sizes", () => { + let cmds: CoreCommand[] = []; + class CommandSpy extends CorePlugin { + static getters = []; + handle(command: CoreCommand) { + if (command.type === "RESIZE_COLUMNS_ROWS") { + cmds.push(command); + } + } + } + addTestPlugin(corePluginRegistry, CommandSpy); + + const model = new Model(); + + resizeRows(model, [1, 2], 10); + resizeRows(model, [3, 4], 20); + + moveRows(model, 1, [3, 4]); + + const sheetId = model.getters.getActiveSheetId(); + expect(model.getters.getRowSize(sheetId, 1)).toEqual(20); + expect(model.getters.getRowSize(sheetId, 2)).toEqual(20); + expect(model.getters.getRowSize(sheetId, 3)).toEqual(10); + expect(model.getters.getRowSize(sheetId, 4)).toEqual(10); + + expect(cmds[2]).toStrictEqual({ + type: "RESIZE_COLUMNS_ROWS", + dimension: "ROW", + sheetId, + elements: [1, 2], + size: 20, + }); + }); + test("Can move a column to the end of the sheet", () => { const model = new Model(); setCellContent(model, "A1", "5");