Skip to content

Commit

Permalink
fix: auto fill should delete dv rules (#4075)
Browse files Browse the repository at this point in the history
  • Loading branch information
lumixraku authored Nov 25, 2024
1 parent a5041d2 commit b9439c5
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 39 deletions.
9 changes: 9 additions & 0 deletions packages/core/src/sheets/worksheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,15 @@ export class Worksheet {
return this._spanModel;
}

getStyleDataByHash(hash: string): Nullable<IStyleData> {
const data = this._styles.get(hash);
return { ...data };
}

setStyleData(style: IStyleData): Nullable<string> {
return this._styles.setValue(style);
}

/**
* Get the style of the column.
* @param {number} column The column index
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { APPLY_TYPE, getAutoFillRepeatRange, IAutoFillService, virtualizeDiscret
export class DataValidationAutoFillController extends Disposable {
constructor(
@IAutoFillService private readonly _autoFillService: IAutoFillService,
@Inject(SheetDataValidationModel) private readonly _dataValidationModel: SheetDataValidationModel,
@Inject(SheetDataValidationModel) private readonly _sheetDataValidationModel: SheetDataValidationModel,
@Inject(Injector) private readonly _injector: Injector
) {
super();
Expand All @@ -37,7 +37,7 @@ export class DataValidationAutoFillController extends Disposable {

const generalApplyFunc = (location: IAutoFillLocation, applyType: APPLY_TYPE) => {
const { source: sourceRange, target: targetRange, unitId, subUnitId } = location;
const ruleMatrixCopy = this._dataValidationModel.getRuleObjectMatrix(unitId, subUnitId).clone();
const ruleMatrixCopy = this._sheetDataValidationModel.getRuleObjectMatrix(unitId, subUnitId).clone();

const virtualRange = virtualizeDiscreteRanges([sourceRange, targetRange]);
const [vSourceRange, vTargetRange] = virtualRange.ranges;
Expand Down Expand Up @@ -75,27 +75,26 @@ export class DataValidationAutoFillController extends Disposable {
sourceRange
);
const { row: sourceRow, col: sourceCol } = mapFunc(sourcePositionRange.startRow, sourcePositionRange.startColumn);
const ruleId = this._dataValidationModel.getRuleIdByLocation(unitId, subUnitId, sourceRow, sourceCol);
if (ruleId) {
const targetPositionRange = Rectangle.getPositionRange(
{
startRow: row,
startColumn: col,
endColumn: col,
endRow: row,
},
targetRange
);
const { row: targetRow, col: targetCol } = mapFunc(targetPositionRange.startRow, targetPositionRange.startColumn);
// if ruleId exists, set more dv rules, if not, clear dv rules.
const ruleId = this._sheetDataValidationModel.getRuleIdByLocation(unitId, subUnitId, sourceRow, sourceCol) || '';
const targetPositionRange = Rectangle.getPositionRange(
{
startRow: row,
startColumn: col,
endColumn: col,
endRow: row,
},
targetRange
);
const { row: targetRow, col: targetCol } = mapFunc(targetPositionRange.startRow, targetPositionRange.startColumn);

additionMatrix.setValue(targetRow, targetCol, ruleId);
additionRules.add(ruleId);
}
additionMatrix.setValue(targetRow, targetCol, ruleId);
additionRules.add(ruleId);
});
});
const additions = Array.from(additionRules).map((id) => ({ id, ranges: queryObjectMatrix(additionMatrix, (value) => value === id) }));
ruleMatrixCopy.addRangeRules(additions);
const diffs = ruleMatrixCopy.diff(this._dataValidationModel.getRules(unitId, subUnitId));
const diffs = ruleMatrixCopy.diff(this._sheetDataValidationModel.getRules(unitId, subUnitId));
const { redoMutations, undoMutations } = getDataValidationDiffMutations(unitId, subUnitId, diffs, this._injector, 'patched', applyType === APPLY_TYPE.ONLY_FORMAT);
return {
undos: undoMutations,
Expand All @@ -111,7 +110,7 @@ export class DataValidationAutoFillController extends Disposable {
const { source: sourceRange, unitId, subUnitId } = location;
for (const row of sourceRange.rows) {
for (const col of sourceRange.cols) {
const dv = this._dataValidationModel.getRuleByLocation(unitId, subUnitId, row, col);
const dv = this._sheetDataValidationModel.getRuleByLocation(unitId, subUnitId, row, col);
if (dv && disabledDataVallation.indexOf(dv.type) > -1) {
this._autoFillService.setDisableApplyType(APPLY_TYPE.SERIES, true);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,34 @@ export function getDataValidationDiffMutations(
},
} as IUpdateDataValidationMutationParams,
});
} else {
redoMutations.push({
id: UpdateDataValidationMutation.id,
params: {
unitId,
subUnitId,
ruleId: diff.ruleId,
payload: {
type: UpdateRuleType.RANGE,
payload: diff.newRanges,
},
source,
} as IUpdateDataValidationMutationParams,
});

undoMutations.unshift({
id: UpdateDataValidationMutation.id,
params: {
unitId,
subUnitId,
ruleId: diff.ruleId,
payload: {
type: UpdateRuleType.RANGE,
payload: diff.oldRanges,
},
source,
} as IUpdateDataValidationMutationParams,
});
}
} else {
redoMutations.push({
Expand Down
10 changes: 9 additions & 1 deletion packages/sheets-data-validation/src/utils/formula.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,13 @@ export function isLegalFormulaResult(res: string) {
* Judge if the data-validation's formula need to be offseted by ranges
*/
export function isCustomFormulaType(type: DataValidationType) {
return type !== DataValidationType.LIST && type !== DataValidationType.LIST_MULTIPLE && type !== DataValidationType.CHECKBOX && type !== DataValidationType.ANY;
// types not in this list is formula type
const invalidTypes = [
DataValidationType.LIST,
DataValidationType.LIST_MULTIPLE,
DataValidationType.CHECKBOX,
DataValidationType.ANY,
];

return !invalidTypes.includes(type);
}
36 changes: 18 additions & 18 deletions packages/sheets-ui/src/services/clipboard/clipboard.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@
* limitations under the License.
*/

import type {
ICellData, IDisposable,
IMutationInfo,
IRange,
Nullable, Workbook, Worksheet,
} from '@univerjs/core';
import type { ISetSelectionsOperationParams } from '@univerjs/sheets';
import type { IDiscreteRange } from '../../controllers/utils/range-tools';
import type {
ICellDataWithSpanInfo,
IClipboardPropertyItem,
IPasteTarget,
ISheetClipboardHook,
ISheetDiscreteRangeLocation,
IUniverSheetCopyDataModel,
} from './type';
import {
createIdentifier, Disposable, ErrorService, extractPureTextFromCell, ICommandService,
ILogService,
Expand All @@ -29,43 +45,27 @@ import {
UniverInstanceType,
} from '@univerjs/core';
import { IRenderManagerService } from '@univerjs/engine-render';

import {
getPrimaryForRange,
SetSelectionsOperation,
SheetsSelectionsService,
} from '@univerjs/sheets';
import { HTML_CLIPBOARD_MIME_TYPE, IClipboardInterfaceService, INotificationService, IPlatformService, PLAIN_TEXT_CLIPBOARD_MIME_TYPE } from '@univerjs/ui';
import { BehaviorSubject } from 'rxjs';
import type {
ICellData, IDisposable,
IMutationInfo,
IRange,
Nullable, Workbook, Worksheet,
} from '@univerjs/core';

import type { ISetSelectionsOperationParams } from '@univerjs/sheets';
import { rangeToDiscreteRange, virtualizeDiscreteRanges } from '../../controllers/utils/range-tools';
import { IMarkSelectionService } from '../mark-selection/mark-selection.service';
import { SheetSkeletonManagerService } from '../sheet-skeleton-manager.service';
import { createCopyPasteSelectionStyle } from '../utils/selection-util';
import { CopyContentCache, extractId, genId } from './copy-content-cache';

import { HtmlToUSMService } from './html-to-usm/converter';
import { LarkPastePlugin } from './html-to-usm/paste-plugins/plugin-lark';

import { UniverPastePlugin } from './html-to-usm/paste-plugins/plugin-univer';
import { WordPastePlugin } from './html-to-usm/paste-plugins/plugin-word';
import { COPY_TYPE } from './type';
import { USMToHtmlService } from './usm-to-html/convertor';
import { clipboardItemIsFromExcel, convertTextToTable, discreteRangeContainsRange, mergeSetRangeValues, rangeIntersectWithDiscreteRange } from './utils';
import type { IDiscreteRange } from '../../controllers/utils/range-tools';
import type {
ICellDataWithSpanInfo,
IClipboardPropertyItem,
IPasteTarget,
ISheetClipboardHook,
ISheetDiscreteRangeLocation,
IUniverSheetCopyDataModel,
} from './type';

export const PREDEFINED_HOOK_NAME = {
DEFAULT_COPY: 'default-copy',
Expand Down
39 changes: 38 additions & 1 deletion packages/sheets/src/commands/commands/utils/selection-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,6 @@ export function createRangeIteratorWithSkipFilteredRows(sheet: Worksheet) {
* @param endColumn
* @param isRow
* @param styleRowOrColumn
* @returns
*/
export function copyRangeStyles(
worksheet: Worksheet,
Expand All @@ -269,3 +268,41 @@ export function copyRangeStyles(
}
return cellValue;
}

export function copyRangeStylesWithoutBorder(
worksheet: Worksheet,
startRow: number,
endRow: number,
startColumn: number,
endColumn: number,
isRow: boolean,
styleRowOrColumn: number
): IObjectMatrixPrimitiveType<ICellData> {
const cellValue: IObjectMatrixPrimitiveType<ICellData> = {};
for (let row = startRow; row <= endRow; row++) {
for (let column = startColumn; column <= endColumn; column++) {
const cell = isRow ? worksheet.getCell(styleRowOrColumn, column) : worksheet.getCell(row, styleRowOrColumn);
if (!cell || !cell.s) {
continue;
}
if (!cellValue[row]) {
cellValue[row] = {};
}

// univer-pro/issues/3016 insert row/column should not reuse border style
if (typeof cell.s === 'string') {
const styleData = worksheet.getStyleDataByHash(cell.s);
if (styleData) {
delete styleData.bd;
cell.s = worksheet.setStyleData(styleData);
}
} else {
const styleData = { ...cell.s };
delete styleData.bd;
cell.s = worksheet.setStyleData(styleData);
}
cellValue[row][column] = { s: cell.s };
}
}
return cellValue;
}

0 comments on commit b9439c5

Please sign in to comment.