diff --git a/src/migrations/data.ts b/src/migrations/data.ts index 29edde107d..a44a62e500 100644 --- a/src/migrations/data.ts +++ b/src/migrations/data.ts @@ -4,7 +4,15 @@ import { FORBIDDEN_IN_EXCEL_REGEX, FORMULA_REF_IDENTIFIER, } from "../constants"; -import { deepCopy, getItemId, toXC, toZone, UuidGenerator } from "../helpers/index"; +import { + deepCopy, + getItemId, + overlap, + toXC, + toZone, + UuidGenerator, + zoneToXc, +} from "../helpers/index"; import { StateUpdateMessage } from "../types/collaborative/transport_service"; import { CoreCommand, @@ -14,6 +22,7 @@ import { SheetData, UID, WorkbookData, + Zone, } from "../types/index"; import { XlsxReader } from "../xlsx/xlsx_reader"; import { normalizeV9 } from "./legacy_tools"; @@ -23,7 +32,7 @@ import { normalizeV9 } from "./legacy_tools"; * a breaking change is made in the way the state is handled, and an upgrade * function should be defined */ -export const CURRENT_VERSION = 12; +export const CURRENT_VERSION = 12.5; const INITIAL_SHEET_ID = "Sheet1"; /** @@ -305,6 +314,33 @@ const MIGRATIONS: Migration[] = [ return data; }, }, + { + description: "Fix datafilter duplication", + from: 12, + to: 12.5, + applyMigration(data: any): any { + for (let sheet of data.sheets || []) { + let knownDataFilterZones: Zone[] = []; + for (let filterTable of sheet.filterTables || []) { + const zone = toZone(filterTable.range); + // See commit message for the details + const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => + overlap(knownZone, zone) + ); + if (intersectZoneIndex !== -1) { + knownDataFilterZones[intersectZoneIndex] = zone; + } else { + knownDataFilterZones.push(zone); + } + } + + sheet.filterTables = knownDataFilterZones.map((zone) => ({ + range: zoneToXc(zone), + })); + } + return data; + }, + }, ]; /** diff --git a/tests/__snapshots__/model.test.ts.snap b/tests/__snapshots__/model.test.ts.snap index 7c7a8e674b..1dfab50209 100644 --- a/tests/__snapshots__/model.test.ts.snap +++ b/tests/__snapshots__/model.test.ts.snap @@ -36,6 +36,6 @@ Object { ], "styles": Object {}, "uniqueFigureIds": true, - "version": 12, + "version": 12.5, } `; diff --git a/tests/components/filter_icon_overlay.test.ts b/tests/components/filter_icon_overlay.test.ts new file mode 100644 index 0000000000..6cb0ec070c --- /dev/null +++ b/tests/components/filter_icon_overlay.test.ts @@ -0,0 +1,19 @@ +import { Model } from "../../src"; +import { mountSpreadsheet } from "../test_helpers/helpers"; + +describe("Filter Icon Overlay component", () => { + test("Overlapping filters are overwritten bythe latest inserted", async () => { + const model = new Model({ + version: 12, + sheets: [ + { + name: "Sheet1", + id: "sh1", + filterTables: [{ range: "A2:B3" }, { range: "A2:C4" }], + }, + ], + }); + const { fixture } = await mountSpreadsheet({ model }); + expect(fixture.querySelectorAll(".o-filter-icon").length).toBe(3); + }); +}); diff --git a/tests/plugins/import_export.test.ts b/tests/plugins/import_export.test.ts index 8f63954cf5..f2f032c617 100644 --- a/tests/plugins/import_export.test.ts +++ b/tests/plugins/import_export.test.ts @@ -33,7 +33,7 @@ describe("data", () => { }); describe("Migrations", () => { - test("Can upgrade from 1 to 12", () => { + test("Can upgrade from 1 to 12.5", () => { const model = new Model({ version: 1, sheets: [ @@ -53,7 +53,7 @@ describe("Migrations", () => { ], }); const data = model.exportData(); - expect(data.version).toBe(12); + expect(data.version).toBe(12.5); expect(data.sheets[0].id).toBeDefined(); expect(data.sheets[0].figures).toBeDefined(); expect(data.sheets[0].cells.A1!.content).toBe("=A1"); @@ -76,7 +76,7 @@ describe("Migrations", () => { }); const data = model.exportData(); const cells = data.sheets[0].cells; - expect(data.version).toBe(12); + expect(data.version).toBe(12.5); // formulas are de-normalized with version 9 expect(cells.A1?.content).toBe("=A1"); expect(cells.A2?.content).toBe("=1"); @@ -397,6 +397,20 @@ describe("Migrations", () => { expect(data.sheets[1].cells["A1"]?.format).toEqual(1); expect(data.sheets[1].cells["A2"]?.format).toEqual(2); }); + + test("migrate version 12.5: Fix Overlapping datafilters", () => { + const model = new Model({ + version: 12, + sheets: [ + { + id: "1", + filterTables: [{ range: "A1:B2" }, { range: "A1:C2" }], + }, + ], + }); + const data = model.exportData(); + expect(data.sheets[0].filterTables).toEqual([{ range: "A1:C2" }]); + }); }); describe("Import", () => {