Skip to content

Commit

Permalink
feat(sheets): multiple ranges in remove rows/columns
Browse files Browse the repository at this point in the history
  • Loading branch information
Dushusir committed Dec 24, 2024
1 parent 862e70b commit 8fc0526
Show file tree
Hide file tree
Showing 10 changed files with 251 additions and 223 deletions.
2 changes: 2 additions & 0 deletions examples/src/sheets/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,5 @@ declare global {
univerAPI?: ReturnType<typeof FUniver.newAPI>;
}
}

generateRandomId;
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import type { ICommandInfo, IDrawingParam, IMutationInfo, IRange, ITransformState, Nullable, Workbook } from '@univerjs/core';
import type { IInsertColCommandParams, IInsertRowCommandParams, IMoveColsCommandParams, IMoveRangeCommandParams, IMoveRowsCommandParams, IRemoveRowColCommandParams, ISetColHiddenMutationParams, ISetColVisibleMutationParams, ISetRowHiddenMutationParams, ISetRowVisibleMutationParams, ISetSpecificColsVisibleCommandParams, ISetSpecificRowsVisibleCommandParams, ISetWorksheetActiveOperationParams, ISetWorksheetColWidthMutationParams, ISetWorksheetRowHeightMutationParams, ISetWorksheetRowIsAutoHeightMutationParams } from '@univerjs/sheets';
import type { IDeleteRangeMoveLeftCommandParams, IDeleteRangeMoveUpCommandParams, IInsertColCommandParams, IInsertRowCommandParams, IMoveColsCommandParams, IMoveRangeCommandParams, IMoveRowsCommandParams, InsertRangeMoveDownCommandParams, InsertRangeMoveRightCommandParams, IRemoveRowColCommandParams, ISetColHiddenMutationParams, ISetColVisibleMutationParams, ISetRowHiddenMutationParams, ISetRowVisibleMutationParams, ISetSpecificColsVisibleCommandParams, ISetSpecificRowsVisibleCommandParams, ISetWorksheetActiveOperationParams, ISetWorksheetColWidthMutationParams, ISetWorksheetRowHeightMutationParams, ISetWorksheetRowIsAutoHeightMutationParams } from '@univerjs/sheets';
import type { ISheetDrawing, ISheetDrawingPosition } from '@univerjs/sheets-drawing';
import { Disposable, ICommandService, Inject, IUniverInstanceService, Rectangle } from '@univerjs/core';
import { type IDrawingJsonUndo1, IDrawingManagerService } from '@univerjs/drawing';
Expand Down Expand Up @@ -87,6 +87,7 @@ export class SheetDrawingTransformAffectedController extends Disposable implemen
this.disposeWithMe(
this._sheetInterceptorService.interceptCommand({

// eslint-disable-next-line complexity
getMutations: (commandInfo) => {
if (!UPDATE_COMMANDS.includes(commandInfo.id)) {
return { redos: [], undos: [] };
Expand All @@ -106,16 +107,16 @@ export class SheetDrawingTransformAffectedController extends Disposable implemen
} else if (cId === RemoveColCommand.id) {
return this._moveColInterceptor(commandInfo.params as IRemoveRowColCommandParams, 'remove');
} else if (cId === DeleteRangeMoveLeftCommand.id) {
const { range } = commandInfo.params as IRemoveRowColCommandParams;
const { range } = commandInfo.params as IDeleteRangeMoveLeftCommandParams;
return this._getRangeMoveUndo(range, RangeMoveUndoType.deleteLeft);
} else if (cId === DeleteRangeMoveUpCommand.id) {
const { range } = commandInfo.params as IRemoveRowColCommandParams;
const { range } = commandInfo.params as IDeleteRangeMoveUpCommandParams;
return this._getRangeMoveUndo(range, RangeMoveUndoType.deleteUp);
} else if (cId === InsertRangeMoveDownCommand.id) {
const { range } = commandInfo.params as IRemoveRowColCommandParams;
const { range } = commandInfo.params as InsertRangeMoveDownCommandParams;
return this._getRangeMoveUndo(range, RangeMoveUndoType.insertDown);
} else if (cId === InsertRangeMoveRightCommand.id) {
const { range } = commandInfo.params as IRemoveRowColCommandParams;
const { range } = commandInfo.params as InsertRangeMoveRightCommandParams;
return this._getRangeMoveUndo(range, RangeMoveUndoType.insertRight);
} else if (cId === SetRowHiddenCommand.id || cId === SetSpecificRowsVisibleCommand.id) {
const params = commandInfo.params as ISetRowHiddenMutationParams | ISetSpecificRowsVisibleCommandParams;
Expand Down Expand Up @@ -569,7 +570,7 @@ export class SheetDrawingTransformAffectedController extends Disposable implemen
return this._createUndoAndRedoMutation(unitId, subUnitId, updateDrawings);
}

private _getUnitIdAndSubUnitId(params: IInsertRowCommandParams | IRemoveRowColCommandParams, type: 'insert' | 'remove') {
private _getUnitIdAndSubUnitId(params: IInsertRowCommandParams | IRemoveRowColCommandParams | IInsertColCommandParams, type: 'insert' | 'remove') {
let unitId: string;
let subUnitId: string;
if (type === 'insert') {
Expand Down Expand Up @@ -677,16 +678,20 @@ export class SheetDrawingTransformAffectedController extends Disposable implemen
return { redos, undos };
}

// eslint-disable-next-line max-lines-per-function
private _moveRowInterceptor(params: IInsertRowCommandParams | IRemoveRowColCommandParams, type: 'insert' | 'remove') {
const ids = this._getUnitIdAndSubUnitId(params, type);
if (ids == null) {
return { redos: [], undos: [] };
}
const { unitId, subUnitId } = ids;
const { range } = params;

const rowStartIndex = range.startRow;
const rowEndIndex = range.endRow;
let ranges: IRange[] = [];
if (type === 'insert') {
ranges = (params as IRemoveRowColCommandParams).ranges;
} else {
ranges = [(params as IInsertRowCommandParams).range];
}

const redos: IMutationInfo[] = [];
const undos: IMutationInfo[] = [];
Expand All @@ -695,37 +700,42 @@ export class SheetDrawingTransformAffectedController extends Disposable implemen
const updateDrawings: Partial<ISheetDrawing>[] = [];
const deleteDrawings: Partial<ISheetDrawing>[] = [];

Object.keys(data).forEach((drawingId) => {
const drawing = data[drawingId];
const { sheetTransform, transform, anchorType = SheetDrawingAnchorType.Position } = drawing;
ranges.forEach((range) => {
const rowStartIndex = range.startRow;
const rowEndIndex = range.endRow;

if (sheetTransform == null || transform == null) {
return;
}
let newSheetTransform: Nullable<ISheetDrawingPosition>;
let newTransform: Nullable<ITransformState>;
if (type === 'insert') {
const param = this._expandRow(sheetTransform, transform, rowStartIndex, rowEndIndex, anchorType);
newSheetTransform = param?.newSheetTransform;
newTransform = param?.newTransform;
} else {
const { from, to } = sheetTransform;
const { row: fromRow } = from;
const { row: toRow } = to;
if (anchorType === SheetDrawingAnchorType.Both && fromRow >= rowStartIndex && toRow <= rowEndIndex) {
// delete drawing
deleteDrawings.push({ unitId, subUnitId, drawingId });
} else {
const param = this._shrinkRow(sheetTransform, transform, rowStartIndex, rowEndIndex, anchorType);
Object.keys(data).forEach((drawingId) => {
const drawing = data[drawingId];
const { sheetTransform, transform, anchorType = SheetDrawingAnchorType.Position } = drawing;

if (sheetTransform == null || transform == null) {
return;
}
let newSheetTransform: Nullable<ISheetDrawingPosition>;
let newTransform: Nullable<ITransformState>;
if (type === 'insert') {
const param = this._expandRow(sheetTransform, transform, rowStartIndex, rowEndIndex, anchorType);
newSheetTransform = param?.newSheetTransform;
newTransform = param?.newTransform;
} else {
const { from, to } = sheetTransform;
const { row: fromRow } = from;
const { row: toRow } = to;
if (anchorType === SheetDrawingAnchorType.Both && fromRow >= rowStartIndex && toRow <= rowEndIndex) {
// delete drawing
deleteDrawings.push({ unitId, subUnitId, drawingId });
} else {
const param = this._shrinkRow(sheetTransform, transform, rowStartIndex, rowEndIndex, anchorType);
newSheetTransform = param?.newSheetTransform;
newTransform = param?.newTransform;
}
}
}
if (!newSheetTransform || !newTransform) {
return;
}
const params = { unitId, subUnitId, drawingId, transform: newTransform, sheetTransform: newSheetTransform };
updateDrawings.push(params);
if (!newSheetTransform || !newTransform) {
return;
}
const params = { unitId, subUnitId, drawingId, transform: newTransform, sheetTransform: newSheetTransform };
updateDrawings.push(params);
});
});

if (updateDrawings.length === 0 && deleteDrawings.length === 0) {
Expand Down Expand Up @@ -757,16 +767,20 @@ export class SheetDrawingTransformAffectedController extends Disposable implemen
};
}

// eslint-disable-next-line max-lines-per-function
private _moveColInterceptor(params: IInsertColCommandParams | IRemoveRowColCommandParams, type: 'insert' | 'remove') {
const ids = this._getUnitIdAndSubUnitId(params, type);
if (ids == null) {
return { redos: [], undos: [] };
}
const { unitId, subUnitId } = ids;
const { range } = params;

const colStartIndex = range.startColumn;
const colEndIndex = range.endColumn;
let ranges: IRange[] = [];
if (type === 'insert') {
ranges = (params as IRemoveRowColCommandParams).ranges;
} else {
ranges = [(params as IInsertColCommandParams).range];
}

const redos: IMutationInfo[] = [];
const undos: IMutationInfo[] = [];
Expand All @@ -775,39 +789,44 @@ export class SheetDrawingTransformAffectedController extends Disposable implemen
const updateDrawings: Partial<ISheetDrawing>[] = [];
const deleteDrawings: Partial<ISheetDrawing>[] = [];

Object.keys(data).forEach((drawingId) => {
const drawing = data[drawingId];
const { sheetTransform, transform, anchorType = SheetDrawingAnchorType.Position } = drawing;
ranges.forEach((range) => {
const colStartIndex = range.startColumn;
const colEndIndex = range.endColumn;

if (sheetTransform == null || transform == null) {
return;
}
let newSheetTransform: Nullable<ISheetDrawingPosition>;
let newTransform: Nullable<ITransformState>;
if (type === 'insert') {
const param = this._expandCol(sheetTransform, transform, colStartIndex, colEndIndex, anchorType);
newSheetTransform = param?.newSheetTransform;
newTransform = param?.newTransform;
} else {
const { from, to } = sheetTransform;
const { column: fromColumn } = from;
const { column: toColumn } = to;
if (anchorType === SheetDrawingAnchorType.Both && fromColumn >= colStartIndex && toColumn <= colEndIndex) {
// delete drawing
deleteDrawings.push({ unitId, subUnitId, drawingId });
} else {
const param = this._shrinkCol(sheetTransform, transform, colStartIndex, colEndIndex, anchorType);
Object.keys(data).forEach((drawingId) => {
const drawing = data[drawingId];
const { sheetTransform, transform, anchorType = SheetDrawingAnchorType.Position } = drawing;

if (sheetTransform == null || transform == null) {
return;
}
let newSheetTransform: Nullable<ISheetDrawingPosition>;
let newTransform: Nullable<ITransformState>;
if (type === 'insert') {
const param = this._expandCol(sheetTransform, transform, colStartIndex, colEndIndex, anchorType);
newSheetTransform = param?.newSheetTransform;
newTransform = param?.newTransform;
} else {
const { from, to } = sheetTransform;
const { column: fromColumn } = from;
const { column: toColumn } = to;
if (anchorType === SheetDrawingAnchorType.Both && fromColumn >= colStartIndex && toColumn <= colEndIndex) {
// delete drawing
deleteDrawings.push({ unitId, subUnitId, drawingId });
} else {
const param = this._shrinkCol(sheetTransform, transform, colStartIndex, colEndIndex, anchorType);
newSheetTransform = param?.newSheetTransform;
newTransform = param?.newTransform;
}
}
}

if (!newSheetTransform || !newTransform) {
return;
}
if (!newSheetTransform || !newTransform) {
return;
}

const params = { unitId, subUnitId, drawingId, transform: newTransform, sheetTransform: newSheetTransform };
updateDrawings.push(params);
const params = { unitId, subUnitId, drawingId, transform: newTransform, sheetTransform: newSheetTransform };
updateDrawings.push(params);
});
});

if (updateDrawings.length === 0 && deleteDrawings.length === 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
* limitations under the License.
*/

import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import type { Dependency, IWorkbookData, LocaleType } from '@univerjs/core';
import type { IInsertColCommandParams, IInsertRowCommandParams, IMoveColsCommandParams, IMoveRowsCommandParams, IRemoveRowColCommandParams, IRemoveSheetCommandParams, ISetSelectionsOperationParams } from '@univerjs/sheets';
import { Direction, ICommandService, Inject, Injector, Plugin, RANGE_TYPE, Univer, UniverInstanceType } from '@univerjs/core';

import type { IInsertColCommandParams, IInsertRowCommandParams, IMoveColsCommandParams, IMoveRowsCommandParams, IRemoveRowColCommandParams, IRemoveSheetCommandParams, ISetSelectionsOperationParams } from '@univerjs/sheets';
import { InsertColCommand, InsertColMutation, InsertRowCommand, InsertRowMutation, MoveColsCommand, MoveColsMutation, MoveRowsCommand, MoveRowsMutation, RefRangeService, RemoveColCommand, RemoveColMutation, RemoveRowCommand, RemoveRowMutation, RemoveSheetCommand, RemoveSheetMutation, SetSelectionsOperation, SheetInterceptorService, SheetsSelectionsService } from '@univerjs/sheets';
import { SHEET_FILTER_SNAPSHOT_ID, SheetsFilterService } from '../../services/sheet-filter.service';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { SheetsFilterController } from '../../controllers/sheets-filter.controller';
import { SHEET_FILTER_SNAPSHOT_ID, SheetsFilterService } from '../../services/sheet-filter.service';

describe('Test "Filter Interceptor"', () => {
let univer: Univer;
Expand Down Expand Up @@ -89,19 +89,19 @@ describe('Test "Filter Interceptor"', () => {
describe('Test "remove Command"', () => {
it('remove col command, in filter range', async () => {
const removeColCommandParams = {
unitId: 'workbookId', subUnitId: 'worksheetId', range: {
startColumn: 1, endColumn: 1, startRow: 0, endRow: 4, type: RANGE_TYPE.COLUMN,
}, direction: Direction.RIGHT,
unitId: 'workbookId', subUnitId: 'worksheetId', ranges: [{
startColumn: 1, endColumn: 1, startRow: 0, endRow: 4, rangeType: RANGE_TYPE.COLUMN,
}], direction: Direction.RIGHT,
} as IRemoveRowColCommandParams;
await commandService.executeCommand(RemoveColCommand.id, removeColCommandParams);
expect(sheetsFilterService.getFilterModel('workbookId', 'worksheetId')!.getRange()).toStrictEqual({ startColumn: 1, endColumn: 1, startRow: 1, endRow: 2 });
expect(sheetsFilterService.getFilterModel('workbookId', 'worksheetId')!.getAllFilterColumns().map((x) => x[0])).toStrictEqual([1]);
});
it('remove col command, before filter range', async () => {
const removeColCommandParams = {
unitId: 'workbookId', subUnitId: 'worksheetId', range: {
startColumn: 0, endColumn: 0, startRow: 0, endRow: 4, type: RANGE_TYPE.COLUMN,
}, direction: Direction.RIGHT,
unitId: 'workbookId', subUnitId: 'worksheetId', ranges: [{
startColumn: 0, endColumn: 0, startRow: 0, endRow: 4, rangeType: RANGE_TYPE.COLUMN,
}], direction: Direction.RIGHT,
} as IRemoveRowColCommandParams;
await commandService.executeCommand(RemoveColCommand.id, removeColCommandParams);
expect(sheetsFilterService.getFilterModel('workbookId', 'worksheetId')!.getRange()).toStrictEqual({ startColumn: 0, endColumn: 1, startRow: 1, endRow: 2 });
Expand All @@ -110,19 +110,19 @@ describe('Test "Filter Interceptor"', () => {

it('remove row command, in filter range', async () => {
const removeRowCommandParams = {
unitId: 'workbookId', subUnitId: 'worksheetId', range: {
startColumn: 0, endColumn: 3, startRow: 1, endRow: 1, type: RANGE_TYPE.ROW,
}, direction: Direction.DOWN,
unitId: 'workbookId', subUnitId: 'worksheetId', ranges: [{
startColumn: 0, endColumn: 3, startRow: 1, endRow: 1, rangeType: RANGE_TYPE.ROW,
}], direction: Direction.DOWN,
} as IRemoveRowColCommandParams;
await commandService.executeCommand(RemoveRowCommand.id, removeRowCommandParams);
expect(sheetsFilterService.getFilterModel('workbookId', 'worksheetId')).toBe(null);
});

it('remove row command, before filter range', async () => {
const removeRowCommandParams = {
unitId: 'workbookId', subUnitId: 'worksheetId', range: {
startColumn: 0, endColumn: 3, startRow: 0, endRow: 0, type: RANGE_TYPE.ROW,
}, direction: Direction.DOWN,
unitId: 'workbookId', subUnitId: 'worksheetId', ranges: [{
startColumn: 0, endColumn: 3, startRow: 0, endRow: 0, rangeType: RANGE_TYPE.ROW,
}], direction: Direction.DOWN,
} as IRemoveRowColCommandParams;
await commandService.executeCommand(RemoveRowCommand.id, removeRowCommandParams);
expect(sheetsFilterService.getFilterModel('workbookId', 'worksheetId')!.getRange()).toStrictEqual({ startColumn: 1, endColumn: 2, startRow: 0, endRow: 1 });
Expand Down
Loading

0 comments on commit 8fc0526

Please sign in to comment.