Skip to content

Commit

Permalink
fix(sheets-data-validation): data-validation absolute offset (#3091)
Browse files Browse the repository at this point in the history
  • Loading branch information
weird94 authored Aug 17, 2024
1 parent d127e02 commit 135e5c0
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 107 deletions.
63 changes: 0 additions & 63 deletions packages/engine-formula/src/engine/utils/relative-formula.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/engine-formula/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ export { FormulaExecutedStateType, type IAllRuntimeData } from './services/runti
export { isReferenceString } from './basics/regex';
export { matchRefDrawToken } from './basics/match-token';
export { IDefinedNamesService, DefinedNamesService, type IDefinedNamesServiceParam, type IDefinedNameMapItem } from './services/defined-names.service';
export { isFormulaTransformable, transformFormula } from './engine/utils/relative-formula';
export { IFormulaRuntimeService, FormulaRuntimeService } from './services/runtime.service';
export { IFormulaCurrentConfigService, FormulaCurrentConfigService, type IFormulaDirtyData } from './services/current-data.service';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
*/

import type { IRange, ISheetDataValidationRule } from '@univerjs/core';
import { DataValidationType, Disposable, Inject, isFormulaString, IUniverInstanceService, ObjectMatrix, Range, UniverInstanceType } from '@univerjs/core';
import { isFormulaTransformable, LexerTreeBuilder, transformFormula } from '@univerjs/engine-formula';
import { DataValidationType, Disposable, ILogService, Inject, isFormulaString, IUniverInstanceService, ObjectMatrix, Range, UniverInstanceType } from '@univerjs/core';
import { LexerTreeBuilder } from '@univerjs/engine-formula';
import { DataValidationModel } from '@univerjs/data-validation';
import { RegisterOtherFormulaService } from '@univerjs/sheets-formula';
import { DataValidationCacheService } from './dv-cache.service';
Expand Down Expand Up @@ -46,7 +46,10 @@ type UnitId = string;
type SubUnitId = string;
type FormulaId = string;

//
function transformFormula(lexerTreeBuilder: LexerTreeBuilder, formula: string, originRow: number, originCol: number, targetRow: number, targetCol: number) {
return lexerTreeBuilder.moveFormulaRefOffset(formula, targetCol - originCol, targetRow - originRow);
}

export class DataValidationCustomFormulaService extends Disposable {
private _formulaMap: Map<UnitId, Map<SubUnitId, ObjectMatrix<IDataValidationFormula>>> = new Map();
/**
Expand All @@ -64,7 +67,8 @@ export class DataValidationCustomFormulaService extends Disposable {
@Inject(RegisterOtherFormulaService) private _registerOtherFormulaService: RegisterOtherFormulaService,
@Inject(LexerTreeBuilder) private _lexerTreeBuilder: LexerTreeBuilder,
@Inject(DataValidationModel) private readonly _dataValidationModel: DataValidationModel,
@Inject(DataValidationCacheService) private readonly _dataValidationCacheService: DataValidationCacheService
@Inject(DataValidationCacheService) private readonly _dataValidationCacheService: DataValidationCacheService,
@ILogService private readonly _logService: ILogService
) {
super();

Expand Down Expand Up @@ -175,54 +179,36 @@ export class DataValidationCustomFormulaService extends Disposable {
return;
}

const isTransformable = isFormulaTransformable(
this._lexerTreeBuilder,
formula
);

const originRow = ranges[0].startRow;
const originCol = ranges[0].startColumn;

let originFormulaId: string | undefined;
if (isTransformable) {
ranges.forEach((range) => {
Range.foreach(range, (row, column) => {
const relativeFormula = transformFormula(
this._lexerTreeBuilder,
formula,
originRow,
originCol,
row,
column
);
const formulaId = this._registerFormula(unitId, subUnitId, ruleId, relativeFormula);
formulaMap.setValue(row, column, {
formulaId,
ranges.forEach((range) => {
Range.foreach(range, (row, column) => {
const relativeFormula = transformFormula(
this._lexerTreeBuilder,
formula,
originRow,
originCol,
row,
column
);
const formulaId = this._registerFormula(unitId, subUnitId, ruleId, relativeFormula);
formulaMap.setValue(row, column, {
formulaId,
// formulaText: relativeFormula,
ruleId,
});
formulaCellMap.set(formulaId, { row, column });
ruleId,
});
formulaCellMap.set(formulaId, { row, column });
});
} else {
originFormulaId = this._registerFormula(unitId, subUnitId, ruleId, formula);
ranges.forEach((range) => {
Range.foreach(range, (row, col) => {
formulaMap.setValue(row, col, {
formulaId: originFormulaId!,
// formulaText: formula,
ruleId,
});
});
});
}
});

ruleFormulaMap.set(ruleId, {
formula,
originCol,
originRow,
isTransformable,
formulaId: originFormulaId,
isTransformable: true,
});
}

Expand Down Expand Up @@ -266,7 +252,6 @@ export class DataValidationCustomFormulaService extends Disposable {
const relativeText = transformFormula(this._lexerTreeBuilder, formula, originRow, originCol, row, col);
const formulaId = this._registerFormula(unitId, subUnitId, ruleId, relativeText);
formulaMap.setValue(row, col, {
// formulaText: relativeText,
ruleId,
formulaId,
});
Expand Down
4 changes: 4 additions & 0 deletions packages/sheets-data-validation/src/utils/formula.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ import type { ICellData, Nullable } from '@univerjs/core';
export function getFormulaResult(result: Nullable<Nullable<ICellData>[][]>) {
return result?.[0]?.[0]?.v;
}

export function getFormulaCellData(result: Nullable<Nullable<ICellData>[][]>) {
return result?.[0]?.[0];
}
33 changes: 30 additions & 3 deletions packages/sheets-data-validation/src/validators/custom-validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,18 @@
* limitations under the License.
*/

import { DataValidationType, isFormulaString } from '@univerjs/core';
import { CellValueType, DataValidationType, isFormulaString, Tools } from '@univerjs/core';
import type { CellValue, DataValidationOperator, IDataValidationRule, IDataValidationRuleBase } from '@univerjs/core';
import type { IFormulaResult, IFormulaValidResult, IValidatorCellInfo } from '@univerjs/data-validation';
import { BaseDataValidator } from '@univerjs/data-validation';
import { ERROR_TYPE_SET } from '@univerjs/engine-formula';
import { CUSTOM_FORMULA_INPUT_NAME } from '../views/formula-input';
import { DataValidationCustomFormulaService } from '../services/dv-custom-formula.service';
import { getFormulaResult } from '../utils/formula';
import { getFormulaCellData } from '../utils/formula';

function isLegalFormulaResult(res: string) {
return !(ERROR_TYPE_SET as Set<string>).has(res);
}

export class CustomFormulaValidator extends BaseDataValidator {
override id: string = DataValidationType.CUSTOM;
Expand Down Expand Up @@ -49,8 +54,30 @@ export class CustomFormulaValidator extends BaseDataValidator {
override async isValidType(cellInfo: IValidatorCellInfo<CellValue>, _formula: IFormulaResult, _rule: IDataValidationRule): Promise<boolean> {
const { column, row, unitId, subUnitId } = cellInfo;
const result = await this._customFormulaService.getCellFormulaValue(unitId, subUnitId, row, column);
const cellData = getFormulaCellData(result?.result);
const formulaResult = cellData?.v;

if (Tools.isDefine(formulaResult) && formulaResult !== '') {
if (cellData!.t === CellValueType.BOOLEAN) {
return Boolean(formulaResult);
}

if (typeof formulaResult === 'boolean') {
return formulaResult;
}

if (typeof formulaResult === 'number') {
return Boolean(formulaResult);
}

if (typeof formulaResult === 'string') {
return isLegalFormulaResult(formulaResult);
}

return Boolean(formulaResult);
}

return Boolean(getFormulaResult(result?.result));
return false;
}

override generateRuleErrorMessage(rule: IDataValidationRuleBase): string {
Expand Down

0 comments on commit 135e5c0

Please sign in to comment.