Skip to content

Commit

Permalink
feat(sheets-data-validation): add validator service allowing develope…
Browse files Browse the repository at this point in the history
…r to get status of data-validation (#2412)

* feat: add data-validation validator service

* feat: fixed onCompete

* feat: update

* feat: update
  • Loading branch information
weird94 authored Jun 6, 2024
1 parent d497b03 commit 12d531d
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export class DataValidationManager<T extends IDataValidationRule> extends Dispos
return this._dataValidations;
}

validator(_content: Nullable<CellValue>, _rule: IDataValidationRule, _pos: any, _onCompele: (status: DataValidationStatus) => void) {
validator(_content: Nullable<CellValue>, _rule: IDataValidationRule, _pos: any, _onComplete: (status: DataValidationStatus, changed: boolean) => void) {
return DataValidationStatus.VALID;
}
}
20 changes: 13 additions & 7 deletions packages/data-validation/src/models/data-validation-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,15 @@ export class DataValidationModel<T extends IDataValidationRule = IDataValidation
validator(content: Nullable<CellValue>, rule: T, pos: any) {
const { unitId, subUnitId } = pos;
const manager = this.ensureManager(unitId, subUnitId);
return manager.validator(content, rule, pos, (status: DataValidationStatus) => {
this._validStatusChange$.next({
unitId,
subUnitId,
ruleId: rule.uid,
status,
});
return manager.validator(content, rule, pos, (status, changed) => {
if (changed) {
this._validStatusChange$.next({
unitId,
subUnitId,
ruleId: rule.uid,
status,
});
}
});
}

Expand All @@ -185,4 +187,8 @@ export class DataValidationModel<T extends IDataValidationRule = IDataValidation
deleteUnitRules(unitId: string) {
this._model.delete(unitId);
}

getSubUnitIds(unitId: string) {
return Array.from(this._model.get(unitId)?.keys() ?? []);
}
}
1 change: 1 addition & 0 deletions packages/sheets-data-validation/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ export { DataValidationCopyPasteController } from './controllers/dv-copy-paste.c
export { HideDataValidationDropdown, ShowDataValidationDropdown } from './commands/operations/data-validation.operation';
export { DataValidationRejectInputController } from './controllers/dv-reject-input.controller';
export { DataValidationFormulaController } from './controllers/dv-formula.controller';
export { SheetsDataValidationValidatorService } from './services/dv-validator-service';
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type { CellValue, ISheetDataValidationRule, Nullable } from '@univerjs/co
import { DataValidationManager, DataValidatorRegistryService, UpdateRuleType } from '@univerjs/data-validation';
import { DataValidationStatus, DataValidationType, ObjectMatrix, Range } from '@univerjs/core';
import type { IUpdateRulePayload } from '@univerjs/data-validation';
import type { ISheetLocation } from '@univerjs/sheets';
import type { ISheetLocationBase } from '@univerjs/sheets';
import type { Injector } from '@wendellhu/redi';
import { isReferenceString } from '@univerjs/engine-formula';
import type { IDataValidationResCache } from '../services/dv-cache.service';
Expand Down Expand Up @@ -138,7 +138,7 @@ export class SheetDataValidationManager extends DataValidationManager<ISheetData
return this.getRuleById(ruleId);
}

override validator(cellValue: Nullable<CellValue>, rule: ISheetDataValidationRule, pos: ISheetLocation, onCompete: (status: DataValidationStatus) => void): DataValidationStatus {
override validator(cellValue: Nullable<CellValue>, rule: ISheetDataValidationRule, pos: ISheetLocationBase, onCompete: (status: DataValidationStatus, changed: boolean) => void): DataValidationStatus {
const { col, row, unitId, subUnitId } = pos;
const ruleId = rule.uid;
const validator = this._dataValidatorRegistryService.getValidatorItem(rule.type);
Expand All @@ -157,12 +157,14 @@ export class SheetDataValidationManager extends DataValidationManager<ISheetData
status: realStatus,
ruleId,
});
onCompete(realStatus);
onCompete(realStatus, true);
});
return DataValidationStatus.VALIDATING;
}
onCompete(current.status, false);
return current.status;
} else {
onCompete(DataValidationStatus.VALID, false);
return DataValidationStatus.VALID;
}
}
Expand Down
2 changes: 2 additions & 0 deletions packages/sheets-data-validation/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { DataValidationRejectInputController } from './controllers/dv-reject-inp
import { DataValidationPanelService } from './services/data-validation-panel.service';
import { DataValidationFormulaController } from './controllers/dv-formula.controller';
import { DataValidationPermissionController } from './controllers/dv-permission.controller';
import { SheetsDataValidationValidatorService } from './services/dv-validator-service';

@DependentOn(UniverDataValidationPlugin, UniverSheetsPlugin, UniverSheetsUIPlugin)
export class UniverSheetsDataValidationPlugin extends Plugin {
Expand All @@ -64,6 +65,7 @@ export class UniverSheetsDataValidationPlugin extends Plugin {
[DataValidationFormulaService],
[DataValidationCustomFormulaService],
[DataValidationDropdownManagerService],
[SheetsDataValidationValidatorService],

// controller
[DataValidationModelController],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import type { Nullable, ObjectMatrix, Workbook } from '@univerjs/core';
import { DataValidationStatus, IUniverInstanceService, Range, UniverInstanceType } from '@univerjs/core';
import { DataValidationModel } from '@univerjs/data-validation';
import { Inject } from '@wendellhu/redi';
import type { SheetDataValidationManager } from '../models/sheet-data-validation-manager';
import { getCellValueOrigin } from '../utils/get-cell-data-origin';
import type { IDataValidationResCache } from './dv-cache.service';
import { DataValidationCacheService } from './dv-cache.service';

export class SheetsDataValidationValidatorService {
constructor(
@IUniverInstanceService private readonly _univerInstanceService: IUniverInstanceService,
@Inject(DataValidationModel) private readonly _dataValidationModel: DataValidationModel,
@Inject(DataValidationCacheService) private readonly _dataValidationCacheService: DataValidationCacheService
) {

}

async validatorCell(unitId: string, subUnitId: string, row: number, col: number) {
const workbook = this._univerInstanceService.getUnit<Workbook>(unitId, UniverInstanceType.UNIVER_SHEET);
if (!workbook) {
throw new Error(`cannot find current workbook, unitId: ${unitId}`);
}

const worksheet = workbook.getSheetBySheetId(subUnitId);
if (!worksheet) {
throw new Error(`cannot find current worksheet, sheetId: ${subUnitId}`);
}

const cellRaw = worksheet.getCellRaw(row, col);
const manager = this._dataValidationModel.ensureManager(unitId, subUnitId) as SheetDataValidationManager;
const rule = manager.getRuleByLocation(row, col);
if (!rule) {
return DataValidationStatus.VALID;
}

return new Promise<DataValidationStatus>((resolve) => {
manager.validator(getCellValueOrigin(cellRaw), rule, { unitId, subUnitId, row, col }, resolve);
});
}

async validatorWorksheet(unitId: string, subUnitId: string) {
const manager = this._dataValidationModel.ensureManager(unitId, subUnitId) as SheetDataValidationManager;
const rules = manager.getDataValidations();
await Promise.all(rules.map((rule) => {
return Promise.all(rule.ranges.map((range) => {
const promises: Promise<DataValidationStatus>[] = [];
Range.foreach(range, (row, col) => {
promises.push(this.validatorCell(unitId, subUnitId, row, col));
});
return promises;
}));
}));

return this._dataValidationCacheService.ensureCache(unitId, subUnitId);
}

async validatorWorkbook(unitId: string) {
const sheetIds = this._dataValidationModel.getSubUnitIds(unitId);
const results = await Promise.all(sheetIds.map((id) => this.validatorWorksheet(unitId, id)));

const map: Record<string, ObjectMatrix<Nullable<IDataValidationResCache>>> = {};

results.forEach((result, i) => {
map[sheetIds[i]] = result;
});

return map;
}
}

0 comments on commit 12d531d

Please sign in to comment.