feat(sheets-data-validation): data validation optimize (#3422)

This commit is contained in:
zhangw
2024-09-18 22:23:44 +08:00
committed by GitHub
parent 3cf7b461dc
commit 93c3659490
4 changed files with 49 additions and 63 deletions
@@ -15,7 +15,7 @@
*/
import { DataValidationOperator, Inject, Injector, LocaleService, Tools } from '@univerjs/core';
import type { CellValue, IDataValidationRule, IDataValidationRuleBase, Nullable, Workbook, Worksheet } from '@univerjs/core';
import type { CellValue, IDataValidationRule, IDataValidationRuleBase, IStyleData, Nullable, Workbook, Worksheet } from '@univerjs/core';
import type { CellValueType } from '@univerjs/protocol';
import { OperatorErrorTitleMap, OperatorTitleMap } from '../types/const/operator-text-map';
import type { IBaseDataValidationWidget } from './base-widget';
@@ -111,6 +111,8 @@ export abstract class BaseDataValidator<DataType = CellValue> {
return `${errorMsg}`;
}
getExtraStyle(rule: IDataValidationRuleBase, value: Nullable<CellValue>, ctx: { style: IStyleData }): Nullable<IStyleData> {}
getRuleFinalError(rule: IDataValidationRule) {
if (rule.showErrorMessage && rule.error) {
return rule.error;
@@ -164,26 +164,16 @@ export class SheetsDataValidationRenderController extends RxDisposable {
{
// must be after numfmt
priority: InterceptCellContentPriority.DATA_VALIDATION,
// eslint-disable-next-line max-lines-per-function, complexity
// eslint-disable-next-line complexity
handler: (cell, pos, next) => {
const { row, col, unitId, subUnitId, workbook, worksheet } = pos;
const skeleton = this._renderManagerService.getRenderById(unitId)
?.with(SheetSkeletonManagerService)
.getWorksheetSkeleton(subUnitId)
?.skeleton;
if (!skeleton) {
return next(cell);
}
const styleMap = pos.workbook.getStyles();
const styleMap = workbook.getStyles();
const defaultStyle = (typeof cell?.s === 'string' ? styleMap.get(cell?.s) : cell?.s) || {};
const ruleId = this._sheetDataValidationModel.getRuleIdByLocation(unitId, subUnitId, row, col);
if (!ruleId) {
return next(cell);
}
const rule = this._sheetDataValidationModel.getRuleById(unitId, subUnitId, ruleId);
if (!rule) {
return next(cell);
}
@@ -191,46 +181,10 @@ export class SheetsDataValidationRenderController extends RxDisposable {
const validator = this._dataValidatorRegistryService.getValidatorItem(rule.type);
const cellOrigin = worksheet.getCellRaw(row, col);
const cellValue = getCellValueOrigin(cellOrigin);
let extra: ICellDataForSheetInterceptor = {};
if (rule.type === DataValidationType.LIST || rule.type === DataValidationType.LIST_MULTIPLE) {
extra = {
interceptorStyle: {
...cell?.interceptorStyle,
tb: (defaultStyle.tb !== WrapStrategy.OVERFLOW ? defaultStyle.tb : WrapStrategy.CLIP) ?? WrapStrategy.WRAP,
},
};
}
if (rule.type === DataValidationType.CHECKBOX) {
extra = {
interceptorStyle: {
...cell?.interceptorStyle,
tb: WrapStrategy.CLIP,
},
};
}
if (rule.type === DataValidationType.LIST && (rule.renderMode === DataValidationRenderMode.ARROW || rule.renderMode === DataValidationRenderMode.TEXT)) {
const colorMap = (validator as ListValidator).getListWithColorMap(rule);
const valueStr = `${getCellValueOrigin(cellOrigin) ?? ''}`;
const color = colorMap[valueStr];
if (color) {
extra = {
...extra,
interceptorStyle: {
...extra.interceptorStyle,
bg: {
rgb: color,
},
},
};
}
}
const valueStr = `${getCellValueOrigin(cellOrigin) ?? ''}`;
return next({
...cell,
...extra,
dataValidation: {
ruleId,
validStatus,
@@ -251,13 +205,16 @@ export class SheetsDataValidationRenderController extends RxDisposable {
},
interceptorStyle: {
...cell?.interceptorStyle,
...extra.interceptorStyle,
...validator?.getExtraStyle(rule, valueStr, { style: defaultStyle }),
},
interceptorAutoHeight: () => {
// const mergeCell = skeleton.mergeData.find((range) => {
// const { startColumn, startRow, endColumn, endRow } = range;
// return row >= startRow && col >= startColumn && row <= endRow && col <= endColumn;
// });
const skeleton = this._renderManagerService.getRenderById(unitId)
?.with(SheetSkeletonManagerService)
.getWorksheetSkeleton(subUnitId)
?.skeleton;
if (!skeleton) {
return undefined;
}
const mergeCell = skeleton.worksheet.getMergedCell(row, col);
const info: ICellRenderContext = {
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { DataValidationType, isFormulaString, Tools } from '@univerjs/core';
import { DataValidationType, isFormulaString, Tools, WrapStrategy } from '@univerjs/core';
import { BaseDataValidator } from '@univerjs/data-validation';
import type { CellValue, DataValidationOperator, IDataValidationRule, IDataValidationRuleBase, ISheetDataValidationRule, LocaleService, Nullable } from '@univerjs/core';
import type { IFormulaResult, IFormulaValidResult, IValidatorCellInfo } from '@univerjs/data-validation';
@@ -111,6 +111,12 @@ export class CheckboxValidator extends BaseDataValidator {
};
}
override getExtraStyle(rule: IDataValidationRule, value: Nullable<CellValue>) {
return {
tb: WrapStrategy.CLIP,
};
}
parseFormulaSync(rule: IDataValidationRule, unitId: string, subUnitId: string) {
const { formula1 = CHECKBOX_FORMULA_1, formula2 = CHECKBOX_FORMULA_2 } = rule;
const results = this._formulaService.getRuleFormulaResultSync(unitId, subUnitId, rule.uid);
@@ -14,17 +14,17 @@
* limitations under the License.
*/
import { DataValidationRenderMode, DataValidationType, isFormulaString, IUniverInstanceService, numfmt, Rectangle, Tools, UniverInstanceType } from '@univerjs/core';
import type { CellValue, DataValidationOperator, ICellData, IDataValidationRule, IRange, ISheetDataValidationRule, Nullable, Workbook } from '@univerjs/core';
import type { IBaseDataValidationWidget, IFormulaResult, IFormulaValidResult, IValidatorCellInfo } from '@univerjs/data-validation';
import { DataValidationRenderMode, DataValidationType, isFormulaString, IUniverInstanceService, numfmt, Rectangle, Tools, UniverInstanceType, WrapStrategy } from '@univerjs/core';
import { BaseDataValidator } from '@univerjs/data-validation';
import { deserializeRangeWithSheet, isReferenceString, LexerTreeBuilder, sequenceNodeType } from '@univerjs/engine-formula';
import { LIST_FORMULA_INPUT_NAME } from '../views/formula-input';
import { LIST_DROPDOWN_KEY } from '../views';
import { DropdownWidget } from '../widgets/dropdown-widget';
import { ListRenderModeInput } from '../views/render-mode';
import type { CellValue, DataValidationOperator, ICellData, IDataValidationRule, IRange, ISheetDataValidationRule, IStyleData, Nullable, Workbook } from '@univerjs/core';
import type { IBaseDataValidationWidget, IFormulaResult, IFormulaValidResult, IValidatorCellInfo } from '@univerjs/data-validation';
import { DataValidationFormulaService } from '../services/dv-formula.service';
import { getCellValueOrigin } from '../utils/get-cell-data-origin';
import { LIST_DROPDOWN_KEY } from '../views';
import { LIST_FORMULA_INPUT_NAME } from '../views/formula-input';
import { ListRenderModeInput } from '../views/render-mode';
import { DropdownWidget } from '../widgets/dropdown-widget';
import { deserializeListOptions } from './util';
export function getRuleFormulaResultSet(result: Nullable<Nullable<ICellData>[][]>) {
@@ -127,6 +127,27 @@ export class ListValidator extends BaseDataValidator {
};
}
override getExtraStyle(rule: IDataValidationRule, value: Nullable<CellValue>, { style: defaultStyle }: { style: IStyleData }): Nullable<IStyleData> {
const tb = (defaultStyle.tb !== WrapStrategy.OVERFLOW ? defaultStyle.tb : WrapStrategy.CLIP) ?? WrapStrategy.WRAP;
if (rule.type === DataValidationType.LIST && (rule.renderMode === DataValidationRenderMode.ARROW || rule.renderMode === DataValidationRenderMode.TEXT)) {
const colorMap = this.getListWithColorMap(rule);
const valueStr = `${value ?? ''}`;
const color = colorMap[valueStr];
if (color) {
return {
bg: {
rgb: color,
},
tb,
};
}
}
return {
tb,
};
}
parseCellValue(cellValue: CellValue) {
const cellString = cellValue.toString();
return deserializeListOptions(cellString);