snapshot of https://github.com/dream-num/univer.git (dev, 2026-09-16; blobs > 131072B omitted)
Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled
Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,317 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { ILogService, Injector, ISheetDataValidationRule, IWorkbookData, Workbook } from '@univerjs/core';
|
||||
import {
|
||||
DataValidationOperator,
|
||||
DataValidationType,
|
||||
ICommandService,
|
||||
IResourceLoaderService,
|
||||
IResourceManagerService,
|
||||
LocaleType,
|
||||
Univer,
|
||||
UniverInstanceType,
|
||||
} from '@univerjs/core';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import {
|
||||
AddDataValidationMutation,
|
||||
RemoveDataValidationMutation,
|
||||
UpdateDataValidationMutation,
|
||||
} from '../commands/mutations/data-validation.mutation';
|
||||
import { DataValidationResourceController } from '../controllers/dv-resource.controller';
|
||||
import { DataValidationModel } from '../models/data-validation-model';
|
||||
import { UpdateRuleType } from '../types/enum/update-rule-type';
|
||||
|
||||
function createWorkbookData(): IWorkbookData {
|
||||
return {
|
||||
id: 'unit-1',
|
||||
appVersion: '3.0.0-alpha',
|
||||
locale: LocaleType.EN_US,
|
||||
name: 'Workbook',
|
||||
sheetOrder: ['sheet-1', 'sheet-2'],
|
||||
styles: {},
|
||||
sheets: {
|
||||
'sheet-1': {
|
||||
id: 'sheet-1',
|
||||
name: 'Sheet1',
|
||||
cellData: {},
|
||||
},
|
||||
'sheet-2': {
|
||||
id: 'sheet-2',
|
||||
name: 'Sheet2',
|
||||
cellData: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function createRule(uid: string, overrides: Partial<ISheetDataValidationRule> = {}): ISheetDataValidationRule {
|
||||
return {
|
||||
uid,
|
||||
type: DataValidationType.DECIMAL,
|
||||
operator: DataValidationOperator.BETWEEN,
|
||||
formula1: '1',
|
||||
formula2: '5',
|
||||
allowBlank: true,
|
||||
showErrorMessage: true,
|
||||
error: `Rule ${uid} failed`,
|
||||
ranges: [{ startRow: 0, endRow: 0, startColumn: 0, endColumn: 0 }],
|
||||
...overrides,
|
||||
} as ISheetDataValidationRule;
|
||||
}
|
||||
|
||||
describe('data validation integration', () => {
|
||||
let univer: Univer;
|
||||
let get: Injector['get'];
|
||||
let commandService: ICommandService;
|
||||
let resourceManagerService: IResourceManagerService;
|
||||
let resourceLoaderService: IResourceLoaderService;
|
||||
let dataValidationModel: DataValidationModel;
|
||||
|
||||
beforeEach(() => {
|
||||
univer = new Univer();
|
||||
|
||||
const injector = univer.__getInjector();
|
||||
get = injector.get.bind(injector);
|
||||
|
||||
injector.add([DataValidationModel]);
|
||||
injector.add([DataValidationResourceController]);
|
||||
|
||||
commandService = get(ICommandService);
|
||||
commandService.registerCommand(AddDataValidationMutation);
|
||||
commandService.registerCommand(RemoveDataValidationMutation);
|
||||
commandService.registerCommand(UpdateDataValidationMutation);
|
||||
|
||||
dataValidationModel = get(DataValidationModel);
|
||||
resourceManagerService = get(IResourceManagerService);
|
||||
resourceLoaderService = get(IResourceLoaderService);
|
||||
|
||||
get(DataValidationResourceController);
|
||||
univer.createUnit<IWorkbookData, Workbook>(UniverInstanceType.UNIVER_SHEET, createWorkbookData());
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
univer.dispose();
|
||||
});
|
||||
|
||||
it('applies add, update, and remove mutations through the real command service', async () => {
|
||||
const changes: Array<{ type: string; ruleId: string; source: string }> = [];
|
||||
const sub = dataValidationModel.ruleChange$.subscribe((change) => {
|
||||
changes.push({ type: change.type, ruleId: change.rule.uid, source: change.source });
|
||||
});
|
||||
|
||||
await commandService.executeCommand(AddDataValidationMutation.id, {
|
||||
unitId: 'unit-1',
|
||||
subUnitId: 'sheet-1',
|
||||
rule: createRule('rule-1'),
|
||||
});
|
||||
|
||||
await commandService.executeCommand(AddDataValidationMutation.id, {
|
||||
unitId: 'unit-1',
|
||||
subUnitId: 'sheet-1',
|
||||
index: 0,
|
||||
rule: [createRule('rule-2'), createRule('rule-1'), createRule('rule-3')],
|
||||
});
|
||||
|
||||
await commandService.executeCommand(UpdateDataValidationMutation.id, {
|
||||
unitId: 'unit-1',
|
||||
subUnitId: 'sheet-1',
|
||||
ruleId: 'rule-1',
|
||||
payload: {
|
||||
type: UpdateRuleType.SETTING,
|
||||
payload: {
|
||||
type: DataValidationType.TEXT_LENGTH,
|
||||
operator: DataValidationOperator.GREATER_THAN,
|
||||
formula1: '3',
|
||||
formula2: undefined,
|
||||
allowBlank: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await commandService.executeCommand(UpdateDataValidationMutation.id, {
|
||||
unitId: 'unit-1',
|
||||
subUnitId: 'sheet-1',
|
||||
ruleId: 'rule-1',
|
||||
payload: {
|
||||
type: UpdateRuleType.OPTIONS,
|
||||
payload: {
|
||||
prompt: 'Type a longer value',
|
||||
promptTitle: 'Length rule',
|
||||
showErrorMessage: false,
|
||||
bizInfo: {
|
||||
source: 'integration-spec',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await commandService.executeCommand(UpdateDataValidationMutation.id, {
|
||||
unitId: 'unit-1',
|
||||
subUnitId: 'sheet-1',
|
||||
ruleId: 'rule-2',
|
||||
payload: {
|
||||
type: UpdateRuleType.RANGE,
|
||||
payload: [{ startRow: 2, endRow: 3, startColumn: 1, endColumn: 2 }],
|
||||
},
|
||||
});
|
||||
|
||||
await commandService.executeCommand(UpdateDataValidationMutation.id, {
|
||||
unitId: 'unit-1',
|
||||
subUnitId: 'sheet-1',
|
||||
ruleId: 'rule-3',
|
||||
payload: {
|
||||
type: UpdateRuleType.ALL,
|
||||
payload: createRule('rule-3', {
|
||||
type: DataValidationType.LIST,
|
||||
operator: undefined,
|
||||
formula1: 'Yes,No',
|
||||
formula2: undefined,
|
||||
showDropDown: false,
|
||||
ranges: [{ startRow: 4, endRow: 4, startColumn: 0, endColumn: 1 }],
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
await commandService.executeCommand(RemoveDataValidationMutation.id, {
|
||||
unitId: 'unit-1',
|
||||
subUnitId: 'sheet-1',
|
||||
ruleId: ['rule-2', 'rule-3'],
|
||||
});
|
||||
|
||||
const rules = dataValidationModel.getRules('unit-1', 'sheet-1');
|
||||
expect(rules.map((rule) => rule.uid)).toEqual(['rule-1']);
|
||||
expect(dataValidationModel.getRuleIndex('unit-1', 'sheet-1', 'rule-1')).toBe(0);
|
||||
expect(dataValidationModel.getRuleById('unit-1', 'sheet-1', 'rule-1')).toMatchObject({
|
||||
type: DataValidationType.TEXT_LENGTH,
|
||||
operator: DataValidationOperator.GREATER_THAN,
|
||||
formula1: '3',
|
||||
allowBlank: false,
|
||||
prompt: 'Type a longer value',
|
||||
promptTitle: 'Length rule',
|
||||
showErrorMessage: false,
|
||||
bizInfo: {
|
||||
source: 'integration-spec',
|
||||
},
|
||||
});
|
||||
|
||||
expect(changes.map((change) => change.type)).toEqual([
|
||||
'add',
|
||||
'add',
|
||||
'add',
|
||||
'update',
|
||||
'update',
|
||||
'update',
|
||||
'update',
|
||||
'remove',
|
||||
'remove',
|
||||
]);
|
||||
expect(changes.every((change) => change.source === 'command')).toBe(true);
|
||||
|
||||
sub.unsubscribe();
|
||||
});
|
||||
|
||||
it('serializes, unloads, and loads rule resources through the resource manager', async () => {
|
||||
await commandService.executeCommand(AddDataValidationMutation.id, {
|
||||
unitId: 'unit-1',
|
||||
subUnitId: 'sheet-1',
|
||||
rule: createRule('sheet-1-rule'),
|
||||
});
|
||||
await commandService.executeCommand(AddDataValidationMutation.id, {
|
||||
unitId: 'unit-1',
|
||||
subUnitId: 'sheet-2',
|
||||
rule: createRule('sheet-2-rule', {
|
||||
ranges: [{ startRow: 9, endRow: 9, startColumn: 0, endColumn: 0 }],
|
||||
}),
|
||||
});
|
||||
|
||||
const snapshot = resourceLoaderService.saveUnit('unit-1');
|
||||
const resource = snapshot?.resources.find((item) => item.name === 'SHEET_DATA_VALIDATION_PLUGIN');
|
||||
|
||||
expect(resource).toBeDefined();
|
||||
expect(JSON.parse(resource!.data)).toEqual({
|
||||
'sheet-1': [createRule('sheet-1-rule')],
|
||||
'sheet-2': [createRule('sheet-2-rule', {
|
||||
ranges: [{ startRow: 9, endRow: 9, startColumn: 0, endColumn: 0 }],
|
||||
})],
|
||||
});
|
||||
|
||||
resourceManagerService.unloadResources('unit-1', UniverInstanceType.UNIVER_SHEET);
|
||||
expect(dataValidationModel.getUnitRules('unit-1')).toEqual([]);
|
||||
|
||||
resourceManagerService.loadResources('unit-1', [{
|
||||
name: 'SHEET_DATA_VALIDATION_PLUGIN',
|
||||
data: JSON.stringify({
|
||||
'sheet-1': [createRule('loaded-rule')],
|
||||
'sheet-2': [createRule('loaded-rule-2', {
|
||||
type: DataValidationType.LIST,
|
||||
formula1: 'A,B',
|
||||
operator: undefined,
|
||||
})],
|
||||
}),
|
||||
}]);
|
||||
|
||||
expect(dataValidationModel.getRules('unit-1', 'sheet-1')).toEqual([createRule('loaded-rule')]);
|
||||
expect(dataValidationModel.getRules('unit-1', 'sheet-2')).toEqual([
|
||||
createRule('loaded-rule-2', {
|
||||
type: DataValidationType.LIST,
|
||||
formula1: 'A,B',
|
||||
operator: undefined,
|
||||
}),
|
||||
]);
|
||||
|
||||
resourceManagerService.loadResources('unit-1', [{
|
||||
name: 'SHEET_DATA_VALIDATION_PLUGIN',
|
||||
data: '{invalid-json',
|
||||
}]);
|
||||
|
||||
expect(dataValidationModel.getSubUnitIds('unit-1')).toEqual(['sheet-1', 'sheet-2']);
|
||||
});
|
||||
|
||||
it('reports model errors and exposes unit level getters without changing source code', () => {
|
||||
const logService = {
|
||||
error: vi.fn(),
|
||||
} as unknown as ILogService;
|
||||
const model = new DataValidationModel(logService);
|
||||
|
||||
model.addRule('unit-2', 'sheet-x', createRule('rule-a'), 'patched');
|
||||
model.addRule('unit-2', 'sheet-y', createRule('rule-b'), 'patched');
|
||||
|
||||
expect(model.getSubUnitIds('unit-2')).toEqual(['sheet-x', 'sheet-y']);
|
||||
expect(model.getUnitRules('unit-2')).toEqual([
|
||||
['sheet-x', [createRule('rule-a')]],
|
||||
['sheet-y', [createRule('rule-b')]],
|
||||
]);
|
||||
expect(model.getAll()).toContainEqual([
|
||||
'unit-2',
|
||||
[
|
||||
['sheet-x', [createRule('rule-a')]],
|
||||
['sheet-y', [createRule('rule-b')]],
|
||||
],
|
||||
]);
|
||||
|
||||
model.updateRule('unit-2', 'sheet-x', 'missing-rule', {
|
||||
type: UpdateRuleType.ALL,
|
||||
payload: createRule('missing-rule'),
|
||||
}, 'patched');
|
||||
|
||||
expect(logService.error).toHaveBeenCalled();
|
||||
|
||||
model.deleteUnitRules('unit-2');
|
||||
expect(model.getUnitRules('unit-2')).toEqual([]);
|
||||
model.dispose();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,282 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { IDataValidationRule, Injector } from '@univerjs/core';
|
||||
import type { IFormulaResult, IFormulaValidResult, IValidatorCellInfo } from '../validators/base-data-validator';
|
||||
import {
|
||||
DataValidationOperator,
|
||||
DataValidationType,
|
||||
LocaleService,
|
||||
LocaleType,
|
||||
Univer,
|
||||
} from '@univerjs/core';
|
||||
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
||||
import { DataValidatorRegistryScope, DataValidatorRegistryService } from '../services/data-validator-registry.service';
|
||||
import { BaseDataValidator } from '../validators/base-data-validator';
|
||||
|
||||
function createRule(overrides: Partial<IDataValidationRule> = {}): IDataValidationRule {
|
||||
return {
|
||||
uid: 'rule-1',
|
||||
type: DataValidationType.DECIMAL,
|
||||
operator: DataValidationOperator.BETWEEN,
|
||||
formula1: '1',
|
||||
formula2: '5',
|
||||
allowBlank: true,
|
||||
showErrorMessage: true,
|
||||
error: 'Explicit error',
|
||||
ranges: [{ startRow: 0, endRow: 0, startColumn: 0, endColumn: 0 }],
|
||||
...overrides,
|
||||
} as IDataValidationRule;
|
||||
}
|
||||
|
||||
function createCellInfo(value: unknown): IValidatorCellInfo {
|
||||
return {
|
||||
value: value as never,
|
||||
interceptValue: null,
|
||||
row: 0,
|
||||
column: 0,
|
||||
unitId: 'unit-1',
|
||||
subUnitId: 'sheet-1',
|
||||
worksheet: null as never,
|
||||
workbook: null as never,
|
||||
t: null,
|
||||
};
|
||||
}
|
||||
|
||||
class TestDataValidator extends BaseDataValidator {
|
||||
id = 'validator.number';
|
||||
title = 'validator.number';
|
||||
operators = [
|
||||
DataValidationOperator.BETWEEN,
|
||||
DataValidationOperator.EQUAL,
|
||||
DataValidationOperator.GREATER_THAN,
|
||||
DataValidationOperator.GREATER_THAN_OR_EQUAL,
|
||||
DataValidationOperator.LESS_THAN,
|
||||
DataValidationOperator.LESS_THAN_OR_EQUAL,
|
||||
DataValidationOperator.NOT_BETWEEN,
|
||||
DataValidationOperator.NOT_EQUAL,
|
||||
];
|
||||
|
||||
scopes = [DataValidatorRegistryScope.SHEET, 'custom-scope'];
|
||||
order = 1;
|
||||
|
||||
formulaResult: IFormulaResult<number | undefined> = {
|
||||
formula1: 1,
|
||||
formula2: 5,
|
||||
isFormulaValid: true,
|
||||
};
|
||||
|
||||
validType = true;
|
||||
|
||||
override async parseFormula(rule: IDataValidationRule, _unitId: string, _subUnitId: string, _row: number, _column: number): Promise<IFormulaResult<number | undefined>> {
|
||||
return {
|
||||
...this.formulaResult,
|
||||
formula1: Number(rule.formula1 ?? this.formulaResult.formula1),
|
||||
formula2: rule.formula2 == null ? undefined : Number(rule.formula2),
|
||||
};
|
||||
}
|
||||
|
||||
override validatorFormula(rule: IDataValidationRule, _unitId: string, _subUnitId: string): IFormulaValidResult {
|
||||
return {
|
||||
success: true,
|
||||
formula1: rule.formula1,
|
||||
formula2: rule.formula2,
|
||||
};
|
||||
}
|
||||
|
||||
override async isValidType(): Promise<boolean> {
|
||||
return this.validType;
|
||||
}
|
||||
|
||||
override transform(cellInfo: IValidatorCellInfo): IValidatorCellInfo<number> {
|
||||
return {
|
||||
...cellInfo,
|
||||
value: Number(cellInfo.value),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
describe('data validator behavior', () => {
|
||||
let univer: Univer;
|
||||
let get: Injector['get'];
|
||||
let localeService: LocaleService;
|
||||
let registryService: DataValidatorRegistryService;
|
||||
let validator: TestDataValidator;
|
||||
|
||||
beforeEach(() => {
|
||||
univer = new Univer();
|
||||
const injector = univer.__getInjector();
|
||||
get = injector.get.bind(injector);
|
||||
|
||||
injector.add([DataValidatorRegistryService]);
|
||||
|
||||
localeService = get(LocaleService);
|
||||
localeService.load({
|
||||
[LocaleType.EN_US]: {
|
||||
validator: {
|
||||
number: 'Number',
|
||||
},
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'between',
|
||||
equal: 'equal',
|
||||
greaterThan: 'greater than',
|
||||
greaterThanOrEqual: 'greater than or equal',
|
||||
lessThan: 'less than',
|
||||
lessThanOrEqual: 'less than or equal',
|
||||
notBetween: 'not between',
|
||||
notEqual: 'not equal',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'between {FORMULA1} and {FORMULA2}',
|
||||
equal: 'equal to {FORMULA1}',
|
||||
greaterThan: 'greater than {FORMULA1}',
|
||||
greaterThanOrEqual: 'greater than or equal to {FORMULA1}',
|
||||
lessThan: 'less than {FORMULA1}',
|
||||
lessThanOrEqual: 'less than or equal to {FORMULA1}',
|
||||
notBetween: 'not between {FORMULA1} and {FORMULA2}',
|
||||
notEqual: 'not equal to {FORMULA1}',
|
||||
legal: 'Legal {TYPE}',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'Value must be between {FORMULA1} and {FORMULA2}',
|
||||
equal: 'Value must equal {FORMULA1}',
|
||||
greaterThan: 'Value must be greater than {FORMULA1}',
|
||||
greaterThanOrEqual: 'Value must be greater than or equal to {FORMULA1}',
|
||||
lessThan: 'Value must be less than {FORMULA1}',
|
||||
lessThanOrEqual: 'Value must be less than or equal to {FORMULA1}',
|
||||
notBetween: 'Value must not be between {FORMULA1} and {FORMULA2}',
|
||||
notEqual: 'Value must not equal {FORMULA1}',
|
||||
legal: 'Value must satisfy {TYPE}',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
localeService.setLocale(LocaleType.EN_US);
|
||||
|
||||
registryService = get(DataValidatorRegistryService);
|
||||
validator = new TestDataValidator(localeService, injector);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
univer.dispose();
|
||||
});
|
||||
|
||||
it('registers validators by scope and removes them with the returned disposable', () => {
|
||||
const changes: number[] = [];
|
||||
const sub = registryService.validatorsChange$.subscribe(() => changes.push(changes.length));
|
||||
|
||||
const disposable = registryService.register(validator);
|
||||
|
||||
expect(registryService.getValidatorItem(validator.id)).toBe(validator);
|
||||
expect(registryService.getValidatorsByScope(DataValidatorRegistryScope.SHEET)).toContain(validator);
|
||||
expect(registryService.getValidatorsByScope('custom-scope')).toContain(validator);
|
||||
|
||||
expect(() => registryService.register(new TestDataValidator(localeService, get as never))).toThrow(/same id/);
|
||||
|
||||
disposable.dispose();
|
||||
|
||||
expect(registryService.getValidatorItem(validator.id)).toBeUndefined();
|
||||
expect(registryService.getValidatorsByScope(DataValidatorRegistryScope.SHEET)).toEqual([]);
|
||||
expect(changes.length).toBeGreaterThanOrEqual(3);
|
||||
|
||||
sub.unsubscribe();
|
||||
});
|
||||
|
||||
it('generates translated rule labels and validates values through the main validator flow', async () => {
|
||||
expect(validator.operatorNames).toEqual([
|
||||
'between',
|
||||
'equal',
|
||||
'greater than',
|
||||
'greater than or equal',
|
||||
'less than',
|
||||
'less than or equal',
|
||||
'not between',
|
||||
'not equal',
|
||||
]);
|
||||
expect(validator.titleStr).toBe('Number');
|
||||
expect(validator.generateRuleName(createRule())).toBe('Number between 1 and 5');
|
||||
expect(validator.generateRuleName(createRule({ operator: undefined }))).toBe('Legal Number');
|
||||
expect(validator.generateRuleErrorMessage(createRule({ operator: DataValidationOperator.LESS_THAN, formula1: '10' }), {
|
||||
row: 0,
|
||||
col: 0,
|
||||
unitId: 'unit-1',
|
||||
subUnitId: 'sheet-1',
|
||||
})).toBe('Value must be less than 10');
|
||||
|
||||
expect(validator.getRuleFinalError(createRule(), {
|
||||
row: 0,
|
||||
col: 0,
|
||||
unitId: 'unit-1',
|
||||
subUnitId: 'sheet-1',
|
||||
})).toBe('Explicit error');
|
||||
expect(validator.getRuleFinalError(createRule({ showErrorMessage: false, error: 'ignored' }), {
|
||||
row: 0,
|
||||
col: 0,
|
||||
unitId: 'unit-1',
|
||||
subUnitId: 'sheet-1',
|
||||
})).toBe('Value must be between 1 and 5');
|
||||
|
||||
expect(validator.isEmptyCellValue('')).toBe(true);
|
||||
expect(validator.isEmptyCellValue(null)).toBe(true);
|
||||
expect(validator.isEmptyCellValue(0)).toBe(false);
|
||||
expect(validator.normalizeFormula(createRule({ formula1: '=A1', formula2: '=B1' }), 'unit-1', 'sheet-1')).toEqual({
|
||||
formula1: '=A1',
|
||||
formula2: '=B1',
|
||||
});
|
||||
expect(validator.validatorFormula(createRule({ formula1: '7', formula2: '9' }), 'unit-1', 'sheet-1')).toEqual({
|
||||
success: true,
|
||||
formula1: '7',
|
||||
formula2: '9',
|
||||
});
|
||||
|
||||
await expect(validator.validator(createCellInfo(''), createRule({ allowBlank: false }))).resolves.toBe(false);
|
||||
|
||||
validator.formulaResult = {
|
||||
formula1: 1,
|
||||
formula2: 5,
|
||||
isFormulaValid: false,
|
||||
};
|
||||
await expect(validator.validator(createCellInfo(3), createRule())).resolves.toBe(false);
|
||||
|
||||
validator.formulaResult = {
|
||||
formula1: 1,
|
||||
formula2: 5,
|
||||
isFormulaValid: true,
|
||||
};
|
||||
validator.validType = false;
|
||||
await expect(validator.validator(createCellInfo(3), createRule())).resolves.toBe(false);
|
||||
|
||||
validator.validType = true;
|
||||
await expect(validator.validator(createCellInfo(3), createRule({ operator: undefined }))).resolves.toBe(true);
|
||||
await expect(validator.validator(createCellInfo(3), createRule({ operator: DataValidationOperator.BETWEEN }))).resolves.toBe(true);
|
||||
await expect(validator.validator(createCellInfo(9), createRule({ operator: DataValidationOperator.NOT_BETWEEN }))).resolves.toBe(true);
|
||||
await expect(validator.validator(createCellInfo(5), createRule({ operator: DataValidationOperator.EQUAL, formula1: '5' }))).resolves.toBe(true);
|
||||
await expect(validator.validator(createCellInfo(5), createRule({ operator: DataValidationOperator.NOT_EQUAL, formula1: '6' }))).resolves.toBe(true);
|
||||
await expect(validator.validator(createCellInfo(6), createRule({ operator: DataValidationOperator.GREATER_THAN, formula1: '5' }))).resolves.toBe(true);
|
||||
await expect(validator.validator(createCellInfo(5), createRule({ operator: DataValidationOperator.GREATER_THAN_OR_EQUAL, formula1: '5' }))).resolves.toBe(true);
|
||||
await expect(validator.validator(createCellInfo(4), createRule({ operator: DataValidationOperator.LESS_THAN, formula1: '5' }))).resolves.toBe(true);
|
||||
await expect(validator.validator(createCellInfo(5), createRule({ operator: DataValidationOperator.LESS_THAN_OR_EQUAL, formula1: '5' }))).resolves.toBe(true);
|
||||
|
||||
validator.formulaResult = {
|
||||
formula1: Number.NaN,
|
||||
formula2: Number.NaN,
|
||||
isFormulaValid: true,
|
||||
};
|
||||
await expect(validator.validator(createCellInfo(10), createRule({ operator: DataValidationOperator.BETWEEN, formula1: 'NaN', formula2: 'NaN' }))).resolves.toBe(true);
|
||||
await expect(validator.validator(createCellInfo(10), createRule({ operator: 'unexpected' as DataValidationOperator }))).rejects.toThrow('Unknown operator.');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { ISheetDataValidationRule } from '@univerjs/core';
|
||||
import { DataValidationOperator, DataValidationType, ICommandService, Univer } from '@univerjs/core';
|
||||
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
||||
import { DataValidationModel } from '../../../models/data-validation-model';
|
||||
import { UpdateRuleType } from '../../../types/enum/update-rule-type';
|
||||
import {
|
||||
AddDataValidationMutation,
|
||||
RemoveDataValidationMutation,
|
||||
UpdateDataValidationMutation,
|
||||
} from '../data-validation.mutation';
|
||||
|
||||
const unitId = 'validation-workbook';
|
||||
const subUnitId = 'validation-sheet';
|
||||
|
||||
function createRule(uid: string, overrides: Partial<ISheetDataValidationRule> = {}): ISheetDataValidationRule {
|
||||
return {
|
||||
uid,
|
||||
type: DataValidationType.DECIMAL,
|
||||
operator: DataValidationOperator.BETWEEN,
|
||||
formula1: '1',
|
||||
formula2: '10',
|
||||
allowBlank: true,
|
||||
showErrorMessage: true,
|
||||
ranges: [{ startRow: 0, endRow: 0, startColumn: 0, endColumn: 0 }],
|
||||
...overrides,
|
||||
} as ISheetDataValidationRule;
|
||||
}
|
||||
|
||||
describe('data validation mutations', () => {
|
||||
let univer: Univer;
|
||||
let commandService: ICommandService;
|
||||
let dataValidationModel: DataValidationModel;
|
||||
|
||||
beforeEach(() => {
|
||||
univer = new Univer();
|
||||
const injector = univer.__getInjector();
|
||||
injector.add([DataValidationModel]);
|
||||
|
||||
commandService = injector.get(ICommandService);
|
||||
commandService.registerCommand(AddDataValidationMutation);
|
||||
commandService.registerCommand(UpdateDataValidationMutation);
|
||||
commandService.registerCommand(RemoveDataValidationMutation);
|
||||
dataValidationModel = injector.get(DataValidationModel);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
univer.dispose();
|
||||
});
|
||||
|
||||
it('keeps validation rules in user-defined order while ignoring duplicate rule ids', async () => {
|
||||
await commandService.executeCommand(AddDataValidationMutation.id, {
|
||||
unitId,
|
||||
subUnitId,
|
||||
rule: createRule('rule-1'),
|
||||
});
|
||||
await commandService.executeCommand(AddDataValidationMutation.id, {
|
||||
unitId,
|
||||
subUnitId,
|
||||
index: 0,
|
||||
rule: [createRule('rule-2'), createRule('rule-1'), createRule('rule-3')],
|
||||
});
|
||||
|
||||
const ruleIds: string[] = [];
|
||||
for (const rule of dataValidationModel.getRules(unitId, subUnitId)) {
|
||||
ruleIds.push(rule.uid);
|
||||
}
|
||||
|
||||
expect(ruleIds).toEqual(['rule-2', 'rule-3', 'rule-1']);
|
||||
expect(dataValidationModel.getRuleIndex(unitId, subUnitId, 'rule-1')).toBe(2);
|
||||
});
|
||||
|
||||
it('updates validation behavior and removes obsolete rules from the worksheet', async () => {
|
||||
await commandService.executeCommand(AddDataValidationMutation.id, {
|
||||
unitId,
|
||||
subUnitId,
|
||||
rule: [
|
||||
createRule('keep-rule'),
|
||||
createRule('remove-rule'),
|
||||
],
|
||||
});
|
||||
|
||||
await commandService.executeCommand(UpdateDataValidationMutation.id, {
|
||||
unitId,
|
||||
subUnitId,
|
||||
ruleId: 'keep-rule',
|
||||
payload: {
|
||||
type: UpdateRuleType.ALL,
|
||||
payload: createRule('keep-rule', {
|
||||
type: DataValidationType.TEXT_LENGTH,
|
||||
operator: DataValidationOperator.GREATER_THAN,
|
||||
formula1: '3',
|
||||
formula2: undefined,
|
||||
allowBlank: false,
|
||||
prompt: 'Enter at least four characters',
|
||||
promptTitle: 'Length check',
|
||||
ranges: [{ startRow: 2, endRow: 4, startColumn: 1, endColumn: 1 }],
|
||||
}),
|
||||
},
|
||||
});
|
||||
await commandService.executeCommand(RemoveDataValidationMutation.id, {
|
||||
unitId,
|
||||
subUnitId,
|
||||
ruleId: 'remove-rule',
|
||||
});
|
||||
|
||||
expect(dataValidationModel.getRuleById(unitId, subUnitId, 'remove-rule')).toBeUndefined();
|
||||
expect(dataValidationModel.getRuleById(unitId, subUnitId, 'keep-rule')).toMatchObject({
|
||||
type: DataValidationType.TEXT_LENGTH,
|
||||
operator: DataValidationOperator.GREATER_THAN,
|
||||
formula1: '3',
|
||||
formula2: undefined,
|
||||
allowBlank: false,
|
||||
prompt: 'Enter at least four characters',
|
||||
promptTitle: 'Length check',
|
||||
ranges: [{ startRow: 2, endRow: 4, startColumn: 1, endColumn: 1 }],
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { ICommand, IDataValidationRule } from '@univerjs/core';
|
||||
import type { DataValidationChangeSource } from '../../models/data-validation-model';
|
||||
import type { IUpdateRulePayload } from '../../types/interfaces/i-update-rule-payload';
|
||||
import { CommandType } from '@univerjs/core';
|
||||
import { DataValidationModel } from '../../models/data-validation-model';
|
||||
|
||||
export interface IAddDataValidationMutationParams {
|
||||
rule: IDataValidationRule | IDataValidationRule[];
|
||||
index?: number;
|
||||
source?: DataValidationChangeSource;
|
||||
unitId: string;
|
||||
subUnitId: string;
|
||||
}
|
||||
|
||||
export const AddDataValidationMutation: ICommand<IAddDataValidationMutationParams> = {
|
||||
type: CommandType.MUTATION,
|
||||
id: 'data-validation.mutation.addRule',
|
||||
handler(accessor, params) {
|
||||
if (!params) {
|
||||
return false;
|
||||
}
|
||||
const { unitId, subUnitId, rule, index, source = 'command' } = params;
|
||||
const dataValidationModel = accessor.get(DataValidationModel);
|
||||
dataValidationModel.addRule(unitId, subUnitId, rule, source, index);
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
export interface IRemoveDataValidationMutationParams {
|
||||
ruleId: string | string[];
|
||||
source?: DataValidationChangeSource;
|
||||
unitId: string;
|
||||
subUnitId: string;
|
||||
}
|
||||
|
||||
export const RemoveDataValidationMutation: ICommand<IRemoveDataValidationMutationParams> = {
|
||||
type: CommandType.MUTATION,
|
||||
id: 'data-validation.mutation.removeRule',
|
||||
handler(accessor, params) {
|
||||
if (!params) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { unitId, subUnitId, ruleId, source = 'command' } = params;
|
||||
const dataValidationModel = accessor.get(DataValidationModel);
|
||||
if (Array.isArray(ruleId)) {
|
||||
ruleId.forEach((item) => {
|
||||
dataValidationModel.removeRule(unitId, subUnitId, item, source);
|
||||
});
|
||||
} else {
|
||||
dataValidationModel.removeRule(unitId, subUnitId, ruleId, source);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
export interface IUpdateDataValidationMutationParams {
|
||||
payload: IUpdateRulePayload;
|
||||
ruleId: string;
|
||||
source?: DataValidationChangeSource;
|
||||
unitId: string;
|
||||
subUnitId: string;
|
||||
}
|
||||
|
||||
export const UpdateDataValidationMutation: ICommand<IUpdateDataValidationMutationParams> = {
|
||||
type: CommandType.MUTATION,
|
||||
id: 'data-validation.mutation.updateRule',
|
||||
handler(accessor, params) {
|
||||
if (!params) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { unitId, subUnitId, ruleId, payload, source = 'command' } = params;
|
||||
const dataValidationModel = accessor.get(DataValidationModel);
|
||||
dataValidationModel.updateRule(unitId, subUnitId, ruleId, payload, source);
|
||||
return true;
|
||||
},
|
||||
};
|
||||
43
packages/data-validation/src/common/util.ts
Normal file
43
packages/data-validation/src/common/util.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { IDataValidationRuleBase, IDataValidationRuleOptions } from '@univerjs/core';
|
||||
|
||||
export function getRuleSetting(rule: IDataValidationRuleBase): IDataValidationRuleBase {
|
||||
return {
|
||||
type: rule.type,
|
||||
operator: rule.operator,
|
||||
formula1: rule.formula1,
|
||||
formula2: rule.formula2,
|
||||
allowBlank: rule.allowBlank,
|
||||
};
|
||||
}
|
||||
|
||||
export function getRuleOptions(rule: IDataValidationRuleOptions): IDataValidationRuleOptions {
|
||||
return {
|
||||
error: rule.error,
|
||||
errorStyle: rule.errorStyle,
|
||||
errorTitle: rule.errorTitle,
|
||||
imeMode: rule.imeMode,
|
||||
prompt: rule.prompt,
|
||||
promptTitle: rule.promptTitle,
|
||||
showDropDown: rule.showDropDown,
|
||||
showErrorMessage: rule.showErrorMessage,
|
||||
showInputMessage: rule.showInputMessage,
|
||||
renderMode: rule.renderMode,
|
||||
bizInfo: rule.bizInfo,
|
||||
};
|
||||
}
|
||||
24
packages/data-validation/src/config/config.ts
Normal file
24
packages/data-validation/src/config/config.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export const DATA_VALIDATION_PLUGIN_CONFIG_KEY = 'data-validation.config';
|
||||
|
||||
export const configSymbol = Symbol(DATA_VALIDATION_PLUGIN_CONFIG_KEY);
|
||||
|
||||
export interface IUniverDataValidationConfig {
|
||||
}
|
||||
|
||||
export const defaultPluginConfig: IUniverDataValidationConfig = {};
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { ISheetDataValidationRule } from '@univerjs/core';
|
||||
import { Disposable, Inject, IResourceManagerService, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
||||
import { DataValidationModel } from '../models/data-validation-model';
|
||||
|
||||
type DataValidationJSON = Record<string, ISheetDataValidationRule[]>;
|
||||
|
||||
const DATA_VALIDATION_PLUGIN_NAME = 'SHEET_DATA_VALIDATION_PLUGIN';
|
||||
|
||||
export class DataValidationResourceController extends Disposable {
|
||||
constructor(
|
||||
@IResourceManagerService private readonly _resourceManagerService: IResourceManagerService,
|
||||
@IUniverInstanceService private readonly _univerInstanceService: IUniverInstanceService,
|
||||
@Inject(DataValidationModel) private readonly _dataValidationModel: DataValidationModel
|
||||
) {
|
||||
super();
|
||||
this._initSnapshot();
|
||||
}
|
||||
|
||||
private _initSnapshot() {
|
||||
const toJson = (unitID: string) => {
|
||||
const map = this._dataValidationModel.getUnitRules(unitID);
|
||||
const resultMap: DataValidationJSON = {};
|
||||
if (map) {
|
||||
map.forEach(([key, v]) => {
|
||||
resultMap[key] = v;
|
||||
});
|
||||
return JSON.stringify(resultMap);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
const parseJson = (json: string): DataValidationJSON => {
|
||||
if (!json) {
|
||||
return {};
|
||||
}
|
||||
try {
|
||||
return JSON.parse(json);
|
||||
} catch (err) {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
this.disposeWithMe(
|
||||
this._resourceManagerService.registerPluginResource<DataValidationJSON>({
|
||||
pluginName: DATA_VALIDATION_PLUGIN_NAME,
|
||||
businesses: [UniverInstanceType.UNIVER_SHEET],
|
||||
toJson: (unitID) => toJson(unitID),
|
||||
parseJson: (json) => parseJson(json),
|
||||
onUnLoad: (unitID) => {
|
||||
this._dataValidationModel.deleteUnitRules(unitID);
|
||||
},
|
||||
onLoad: (unitID, value) => {
|
||||
Object.keys(value).forEach((subunitId) => {
|
||||
const ruleList = value[subunitId];
|
||||
ruleList.forEach((rule) => {
|
||||
this._dataValidationModel.addRule(unitID, subunitId, rule, 'patched');
|
||||
});
|
||||
});
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
51
packages/data-validation/src/index.ts
Normal file
51
packages/data-validation/src/index.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export {
|
||||
AddDataValidationMutation,
|
||||
RemoveDataValidationMutation,
|
||||
UpdateDataValidationMutation,
|
||||
} from './commands/mutations/data-validation.mutation';
|
||||
export type {
|
||||
IAddDataValidationMutationParams,
|
||||
IRemoveDataValidationMutationParams,
|
||||
IUpdateDataValidationMutationParams,
|
||||
} from './commands/mutations/data-validation.mutation';
|
||||
export { getRuleOptions, getRuleSetting } from './common/util';
|
||||
export { type IUniverDataValidationConfig } from './config/config';
|
||||
export { DataValidationResourceController } from './controllers/dv-resource.controller';
|
||||
export { DataValidationModel } from './models/data-validation-model';
|
||||
export type { DataValidationChangeSource, DataValidationChangeType, IRuleChange } from './models/data-validation-model';
|
||||
export { UniverDataValidationPlugin } from './plugin';
|
||||
export { DataValidatorRegistryScope, DataValidatorRegistryService } from './services/data-validator-registry.service';
|
||||
export { TWO_FORMULA_OPERATOR_COUNT } from './types/const/two-formula-operators';
|
||||
export { UpdateRuleType } from './types/enum/update-rule-type';
|
||||
export type { IDataValidationDropdownProps } from './types/interfaces/i-data-validation-drop-down';
|
||||
export type { IDataValidatorOperatorConfig } from './types/interfaces/i-data-validator-operator-config';
|
||||
export type { IFormulaValue } from './types/interfaces/i-formula-input';
|
||||
export type {
|
||||
IUpdateRuleOptionsPayload,
|
||||
IUpdateRulePayload,
|
||||
IUpdateRuleRangePayload,
|
||||
IUpdateRuleSettingPayload,
|
||||
} from './types/interfaces/i-update-rule-payload';
|
||||
export { BaseDataValidator } from './validators/base-data-validator';
|
||||
export type { IFormulaResult, IValidatorCellInfo } from './validators/base-data-validator';
|
||||
export type { IFormulaValidResult } from './validators/base-data-validator';
|
||||
export { DataValidatorDropdownType } from './validators/base-data-validator';
|
||||
export { FORMULA1, FORMULA2, TYPE } from './validators/base-data-validator';
|
||||
|
||||
export type { IBaseDataValidationWidget } from './validators/base-widget';
|
||||
56
packages/data-validation/src/locale/ar-SA.ts
Normal file
56
packages/data-validation/src/locale/ar-SA.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'بين',
|
||||
greaterThan: 'أكبر من',
|
||||
greaterThanOrEqual: 'أكبر من أو يساوي',
|
||||
lessThan: 'أقل من',
|
||||
lessThanOrEqual: 'أقل من أو يساوي',
|
||||
equal: 'يساوي',
|
||||
notEqual: 'لا يساوي',
|
||||
notBetween: 'ليس بين',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'بين {FORMULA1} و{FORMULA2}',
|
||||
greaterThan: 'أكبر من {FORMULA1}',
|
||||
greaterThanOrEqual: 'أكبر من أو يساوي {FORMULA1}',
|
||||
lessThan: 'أقل من {FORMULA1}',
|
||||
lessThanOrEqual: 'أقل من أو يساوي {FORMULA1}',
|
||||
equal: 'يساوي {FORMULA1}',
|
||||
notEqual: 'لا يساوي {FORMULA1}',
|
||||
notBetween: 'ليس بين {FORMULA1} و{FORMULA2}',
|
||||
legal: 'نوع قانوني {TYPE}',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'يجب أن تكون القيمة بين {FORMULA1} و{FORMULA2}',
|
||||
greaterThan: 'يجب أن تكون القيمة أكبر من {FORMULA1}',
|
||||
greaterThanOrEqual: 'يجب أن تكون القيمة أكبر من أو تساوي {FORMULA1}',
|
||||
lessThan: 'يجب أن تكون القيمة أقل من {FORMULA1}',
|
||||
lessThanOrEqual: 'يجب أن تكون القيمة أقل من أو تساوي {FORMULA1}',
|
||||
equal: 'يجب أن تكون القيمة تساوي {FORMULA1}',
|
||||
notEqual: 'يجب ألا تكون القيمة تساوي {FORMULA1}',
|
||||
notBetween: 'يجب ألا تكون القيمة بين {FORMULA1} و{FORMULA2}',
|
||||
legal: 'يجب أن تكون القيمة من نوع قانوني {TYPE}',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/ca-ES.ts
Normal file
56
packages/data-validation/src/locale/ca-ES.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'entre',
|
||||
greaterThan: 'més gran que',
|
||||
greaterThanOrEqual: 'més gran o igual que',
|
||||
lessThan: 'menys que',
|
||||
lessThanOrEqual: 'menys o igual que',
|
||||
equal: 'igual',
|
||||
notEqual: 'no igual',
|
||||
notBetween: 'no entre',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'Està entre {FORMULA1} i {FORMULA2}',
|
||||
greaterThan: 'És més gran que {FORMULA1}',
|
||||
greaterThanOrEqual: 'És més gran o igual que {FORMULA1}',
|
||||
lessThan: 'És menys que {FORMULA1}',
|
||||
lessThanOrEqual: 'És menys o igual que {FORMULA1}',
|
||||
equal: 'És igual a {FORMULA1}',
|
||||
notEqual: 'No és igual a {FORMULA1}',
|
||||
notBetween: 'No està entre {FORMULA1} i {FORMULA2}',
|
||||
legal: 'És un {TYPE} legal',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'El valor ha d’estar entre {FORMULA1} i {FORMULA2}',
|
||||
greaterThan: 'El valor ha de ser més gran que {FORMULA1}',
|
||||
greaterThanOrEqual: 'El valor ha de ser més gran o igual que {FORMULA1}',
|
||||
lessThan: 'El valor ha de ser menys que {FORMULA1}',
|
||||
lessThanOrEqual: 'El valor ha de ser menys o igual que {FORMULA1}',
|
||||
equal: 'El valor ha de ser igual a {FORMULA1}',
|
||||
notEqual: 'El valor no ha de ser igual a {FORMULA1}',
|
||||
notBetween: 'El valor no ha d’estar entre {FORMULA1} i {FORMULA2}',
|
||||
legal: 'El valor ha de ser un {TYPE} legal',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/de-DE.ts
Normal file
56
packages/data-validation/src/locale/de-DE.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'zwischen',
|
||||
greaterThan: 'größer als',
|
||||
greaterThanOrEqual: 'größer als oder gleich',
|
||||
lessThan: 'kleiner als',
|
||||
lessThanOrEqual: 'kleiner als oder gleich',
|
||||
equal: 'gleich',
|
||||
notEqual: 'ungleich',
|
||||
notBetween: 'nicht zwischen',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'Ist zwischen {FORMULA1} und {FORMULA2}',
|
||||
greaterThan: 'Ist größer als {FORMULA1}',
|
||||
greaterThanOrEqual: 'Ist größer als oder gleich {FORMULA1}',
|
||||
lessThan: 'Ist kleiner als {FORMULA1}',
|
||||
lessThanOrEqual: 'Ist kleiner als oder gleich {FORMULA1}',
|
||||
equal: 'Ist gleich {FORMULA1}',
|
||||
notEqual: 'Ist ungleich {FORMULA1}',
|
||||
notBetween: 'Ist nicht zwischen {FORMULA1} und {FORMULA2}',
|
||||
legal: 'Ist ein gültiger {TYPE}',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'Wert muss zwischen {FORMULA1} und {FORMULA2} liegen',
|
||||
greaterThan: 'Wert muss größer als {FORMULA1} sein',
|
||||
greaterThanOrEqual: 'Wert muss größer als oder gleich {FORMULA1} sein',
|
||||
lessThan: 'Wert muss kleiner als {FORMULA1} sein',
|
||||
lessThanOrEqual: 'Wert muss kleiner als oder gleich {FORMULA1} sein',
|
||||
equal: 'Wert muss gleich {FORMULA1} sein',
|
||||
notEqual: 'Wert muss ungleich {FORMULA1} sein',
|
||||
notBetween: 'Wert muss nicht zwischen {FORMULA1} und {FORMULA2} liegen',
|
||||
legal: 'Wert muss ein gültiger {TYPE} sein',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
54
packages/data-validation/src/locale/en-US.ts
Normal file
54
packages/data-validation/src/locale/en-US.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const locale = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'between',
|
||||
greaterThan: 'greater than',
|
||||
greaterThanOrEqual: 'greater than or equal',
|
||||
lessThan: 'less than',
|
||||
lessThanOrEqual: 'less than or equal',
|
||||
equal: 'equal',
|
||||
notEqual: 'not equal',
|
||||
notBetween: 'not between',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'Is between {FORMULA1} and {FORMULA2}',
|
||||
greaterThan: 'Is greater than {FORMULA1}',
|
||||
greaterThanOrEqual: 'Is greater than or equal to {FORMULA1}',
|
||||
lessThan: 'Is less than {FORMULA1}',
|
||||
lessThanOrEqual: 'Is less than or equal to {FORMULA1}',
|
||||
equal: 'Is equal to {FORMULA1}',
|
||||
notEqual: 'Is not equal to {FORMULA1}',
|
||||
notBetween: 'Is not between {FORMULA1} and {FORMULA2}',
|
||||
legal: 'Is a legal {TYPE}',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'Value must be between {FORMULA1} and {FORMULA2}',
|
||||
greaterThan: 'Value must be greater than {FORMULA1}',
|
||||
greaterThanOrEqual: 'Value must be greater than or equal to {FORMULA1}',
|
||||
lessThan: 'Value must be less than {FORMULA1}',
|
||||
lessThanOrEqual: 'Value must be less than or equal to {FORMULA1}',
|
||||
equal: 'Value must be equal to {FORMULA1}',
|
||||
notEqual: 'Value must be not equal to {FORMULA1}',
|
||||
notBetween: 'Value must be not between {FORMULA1} and {FORMULA2}',
|
||||
legal: 'Value must be a legal {TYPE}',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/es-ES.ts
Normal file
56
packages/data-validation/src/locale/es-ES.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'entre',
|
||||
greaterThan: 'mayor que',
|
||||
greaterThanOrEqual: 'mayor o igual que',
|
||||
lessThan: 'menor que',
|
||||
lessThanOrEqual: 'menor o igual que',
|
||||
equal: 'igual',
|
||||
notEqual: 'no igual',
|
||||
notBetween: 'no entre',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'Está entre {FORMULA1} y {FORMULA2}',
|
||||
greaterThan: 'Es mayor que {FORMULA1}',
|
||||
greaterThanOrEqual: 'Es mayor o igual que {FORMULA1}',
|
||||
lessThan: 'Es menor que {FORMULA1}',
|
||||
lessThanOrEqual: 'Es menor o igual que {FORMULA1}',
|
||||
equal: 'Es igual a {FORMULA1}',
|
||||
notEqual: 'No es igual a {FORMULA1}',
|
||||
notBetween: 'No está entre {FORMULA1} y {FORMULA2}',
|
||||
legal: 'Es un {TYPE} legal',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'El valor debe estar entre {FORMULA1} y {FORMULA2}',
|
||||
greaterThan: 'El valor debe ser mayor que {FORMULA1}',
|
||||
greaterThanOrEqual: 'El valor debe ser mayor o igual que {FORMULA1}',
|
||||
lessThan: 'El valor debe ser menor que {FORMULA1}',
|
||||
lessThanOrEqual: 'El valor debe ser menor o igual que {FORMULA1}',
|
||||
equal: 'El valor debe ser igual a {FORMULA1}',
|
||||
notEqual: 'El valor no debe ser igual a {FORMULA1}',
|
||||
notBetween: 'El valor no debe estar entre {FORMULA1} y {FORMULA2}',
|
||||
legal: 'El valor debe ser un {TYPE} legal',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/fa-IR.ts
Normal file
56
packages/data-validation/src/locale/fa-IR.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'بین',
|
||||
greaterThan: 'بزرگتر از',
|
||||
greaterThanOrEqual: 'بزرگتر از یا برابر با',
|
||||
lessThan: 'کوچکتر از',
|
||||
lessThanOrEqual: 'کوچکتر از یا برابر با',
|
||||
equal: 'برابر با',
|
||||
notEqual: 'نابرابر با',
|
||||
notBetween: 'بین نیست',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'بین {FORMULA1} و {FORMULA2} است',
|
||||
greaterThan: 'بزرگتر از {FORMULA1} است',
|
||||
greaterThanOrEqual: 'بزرگتر از یا برابر با {FORMULA1} است',
|
||||
lessThan: 'کوچکتر از {FORMULA1} است',
|
||||
lessThanOrEqual: 'کوچکتر از یا برابر با {FORMULA1} است',
|
||||
equal: 'برابر است با {FORMULA1}',
|
||||
notEqual: 'برابر نیست با {FORMULA1}',
|
||||
notBetween: 'بین {FORMULA1} و {FORMULA2} نیست',
|
||||
legal: 'یک {TYPE} قانونی است',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'مقدار باید بین {FORMULA1} و {FORMULA2} باشد',
|
||||
greaterThan: 'مقدار باید بزرگتر از {FORMULA1} باشد',
|
||||
greaterThanOrEqual: 'مقدار باید بزرگتر از یا برابر با {FORMULA1} باشد',
|
||||
lessThan: 'مقدار باید کوچکتر از {FORMULA1} باشد',
|
||||
lessThanOrEqual: 'مقدار باید کوچکتر از یا برابر با {FORMULA1} باشد',
|
||||
equal: 'مقدار باید برابر با {FORMULA1} باشد',
|
||||
notEqual: 'مقدار باید برابر نیست با {FORMULA1}',
|
||||
notBetween: 'مقدار باید بین {FORMULA1} و {FORMULA2} نباشد',
|
||||
legal: 'مقدار باید یک {TYPE} قانونی باشد',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/fr-FR.ts
Normal file
56
packages/data-validation/src/locale/fr-FR.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'entre',
|
||||
greaterThan: 'supérieur à',
|
||||
greaterThanOrEqual: 'supérieur ou égal à',
|
||||
lessThan: 'inférieur à',
|
||||
lessThanOrEqual: 'inférieur ou égal à',
|
||||
equal: 'égal à',
|
||||
notEqual: 'différent de',
|
||||
notBetween: 'pas entre',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'est entre {FORMULA1} et {FORMULA2}',
|
||||
greaterThan: 'est supérieur à {FORMULA1}',
|
||||
greaterThanOrEqual: 'est supérieur ou égal à {FORMULA1}',
|
||||
lessThan: 'est inférieur à {FORMULA1}',
|
||||
lessThanOrEqual: 'est inférieur ou égal à {FORMULA1}',
|
||||
equal: 'est égal à {FORMULA1}',
|
||||
notEqual: 'est différent de {FORMULA1}',
|
||||
notBetween: 'n\'est pas entre {FORMULA1} et {FORMULA2}',
|
||||
legal: 'est un {TYPE} légal',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'La valeur doit être entre {FORMULA1} et {FORMULA2}',
|
||||
greaterThan: 'La valeur doit être supérieure à {FORMULA1}',
|
||||
greaterThanOrEqual: 'La valeur doit être supérieure ou égale à {FORMULA1}',
|
||||
lessThan: 'La valeur doit être inférieure à {FORMULA1}',
|
||||
lessThanOrEqual: 'La valeur doit être inférieure ou égale à {FORMULA1}',
|
||||
equal: 'La valeur doit être égale à {FORMULA1}',
|
||||
notEqual: 'La valeur doit être différente de {FORMULA1}',
|
||||
notBetween: 'La valeur ne doit pas être entre {FORMULA1} et {FORMULA2}',
|
||||
legal: 'La valeur doit être un {TYPE} légal',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/id-ID.ts
Normal file
56
packages/data-validation/src/locale/id-ID.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'antara',
|
||||
greaterThan: 'lebih besar dari',
|
||||
greaterThanOrEqual: 'lebih besar dari atau sama dengan',
|
||||
lessThan: 'lebih kecil dari',
|
||||
lessThanOrEqual: 'lebih kecil dari atau sama dengan',
|
||||
equal: 'sama dengan',
|
||||
notEqual: 'tidak sama dengan',
|
||||
notBetween: 'tidak antara',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'Di antara {FORMULA1} dan {FORMULA2}',
|
||||
greaterThan: 'Lebih besar dari {FORMULA1}',
|
||||
greaterThanOrEqual: 'Lebih besar dari atau sama dengan {FORMULA1}',
|
||||
lessThan: 'Lebih kecil dari {FORMULA1}',
|
||||
lessThanOrEqual: 'Lebih kecil dari atau sama dengan {FORMULA1}',
|
||||
equal: 'Sama dengan {FORMULA1}',
|
||||
notEqual: 'Tidak sama dengan {FORMULA1}',
|
||||
notBetween: 'Tidak di antara {FORMULA1} dan {FORMULA2}',
|
||||
legal: 'Adalah {TYPE} yang valid',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'Nilai harus di antara {FORMULA1} dan {FORMULA2}',
|
||||
greaterThan: 'Nilai harus lebih besar dari {FORMULA1}',
|
||||
greaterThanOrEqual: 'Nilai harus lebih besar dari atau sama dengan {FORMULA1}',
|
||||
lessThan: 'Nilai harus lebih kecil dari {FORMULA1}',
|
||||
lessThanOrEqual: 'Nilai harus lebih kecil dari atau sama dengan {FORMULA1}',
|
||||
equal: 'Nilai harus sama dengan {FORMULA1}',
|
||||
notEqual: 'Nilai harus tidak sama dengan {FORMULA1}',
|
||||
notBetween: 'Nilai harus tidak di antara {FORMULA1} dan {FORMULA2}',
|
||||
legal: 'Nilai harus merupakan {TYPE} yang valid',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/it-IT.ts
Normal file
56
packages/data-validation/src/locale/it-IT.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'tra',
|
||||
greaterThan: 'maggiore di',
|
||||
greaterThanOrEqual: 'maggiore o uguale a',
|
||||
lessThan: 'minore di',
|
||||
lessThanOrEqual: 'minore o uguale a',
|
||||
equal: 'uguale a',
|
||||
notEqual: 'diverso da',
|
||||
notBetween: 'non tra',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'È tra {FORMULA1} e {FORMULA2}',
|
||||
greaterThan: 'È maggiore di {FORMULA1}',
|
||||
greaterThanOrEqual: 'È maggiore o uguale a {FORMULA1}',
|
||||
lessThan: 'È minore di {FORMULA1}',
|
||||
lessThanOrEqual: 'È minore o uguale a {FORMULA1}',
|
||||
equal: 'È uguale a {FORMULA1}',
|
||||
notEqual: 'È diverso da {FORMULA1}',
|
||||
notBetween: 'Non è tra {FORMULA1} e {FORMULA2}',
|
||||
legal: 'È un {TYPE} valido',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'Il valore deve essere tra {FORMULA1} e {FORMULA2}',
|
||||
greaterThan: 'Il valore deve essere maggiore di {FORMULA1}',
|
||||
greaterThanOrEqual: 'Il valore deve essere maggiore o uguale a {FORMULA1}',
|
||||
lessThan: 'Il valore deve essere minore di {FORMULA1}',
|
||||
lessThanOrEqual: 'Il valore deve essere minore o uguale a {FORMULA1}',
|
||||
equal: 'Il valore deve essere uguale a {FORMULA1}',
|
||||
notEqual: 'Il valore deve essere diverso da {FORMULA1}',
|
||||
notBetween: 'Il valore non deve essere tra {FORMULA1} e {FORMULA2}',
|
||||
legal: 'Il valore deve essere un {TYPE} valido',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/ja-JP.ts
Normal file
56
packages/data-validation/src/locale/ja-JP.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: '次の値の間',
|
||||
greaterThan: '次の値より大きい',
|
||||
greaterThanOrEqual: '次の値以上',
|
||||
lessThan: '次の値より小さい',
|
||||
lessThanOrEqual: '次の値以下',
|
||||
equal: '次の値に等しい',
|
||||
notEqual: '次の値に等しくない',
|
||||
notBetween: '次の値の間以外',
|
||||
},
|
||||
ruleName: {
|
||||
between: '{FORMULA1} と {FORMULA2} の間',
|
||||
greaterThan: '{FORMULA1} より大きい',
|
||||
greaterThanOrEqual: '{FORMULA1} 以上',
|
||||
lessThan: '{FORMULA1} より小さい',
|
||||
lessThanOrEqual: '{FORMULA1} 以下',
|
||||
equal: '{FORMULA1} に等しい',
|
||||
notEqual: '{FORMULA1} に等しくない',
|
||||
notBetween: '{FORMULA1} と {FORMULA2} の間以外',
|
||||
legal: '有効な {TYPE} 形式',
|
||||
},
|
||||
errorMsg: {
|
||||
between: '値は {FORMULA1} と {FORMULA2} の間である必要があります',
|
||||
greaterThan: '値は {FORMULA1} より大きい必要があります',
|
||||
greaterThanOrEqual: '値は {FORMULA1} 以上である必要があります',
|
||||
lessThan: '値は {FORMULA1} より小さい必要があります',
|
||||
lessThanOrEqual: '値は {FORMULA1} 以下である必要があります',
|
||||
equal: '値は {FORMULA1} に等しい必要があります',
|
||||
notEqual: '値は {FORMULA1} に等しくない必要があります',
|
||||
notBetween: '値は {FORMULA1} と {FORMULA2} の間以外である必要があります',
|
||||
legal: '値は有効な {TYPE} 形式である必要があります',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/ko-KR.ts
Normal file
56
packages/data-validation/src/locale/ko-KR.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: '사이',
|
||||
greaterThan: '초과',
|
||||
greaterThanOrEqual: '이상',
|
||||
lessThan: '미만',
|
||||
lessThanOrEqual: '이하',
|
||||
equal: '같음',
|
||||
notEqual: '같지 않음',
|
||||
notBetween: '사이가 아님',
|
||||
},
|
||||
ruleName: {
|
||||
between: '{FORMULA1}와 {FORMULA2} 사이',
|
||||
greaterThan: '{FORMULA1} 초과',
|
||||
greaterThanOrEqual: '{FORMULA1} 이상',
|
||||
lessThan: '{FORMULA1} 미만',
|
||||
lessThanOrEqual: '{FORMULA1} 이하',
|
||||
equal: '{FORMULA1}와 같음',
|
||||
notEqual: '{FORMULA1}와 다름',
|
||||
notBetween: '{FORMULA1}와 {FORMULA2} 사이 아님',
|
||||
legal: '유효한 {TYPE} 형식',
|
||||
},
|
||||
errorMsg: {
|
||||
between: '값은 {FORMULA1}와 {FORMULA2} 사이여야 합니다',
|
||||
greaterThan: '값은 {FORMULA1} 초과여야 합니다',
|
||||
greaterThanOrEqual: '값은 {FORMULA1} 이상이어야 합니다',
|
||||
lessThan: '값은 {FORMULA1} 미만이어야 합니다',
|
||||
lessThanOrEqual: '값은 {FORMULA1} 이하이어야 합니다',
|
||||
equal: '값은 {FORMULA1}와 같아야 합니다',
|
||||
notEqual: '값은 {FORMULA1}와 달라야 합니다',
|
||||
notBetween: '값은 {FORMULA1}와 {FORMULA2} 사이가 아니어야 합니다',
|
||||
legal: '값은 유효한 {TYPE} 형식이어야 합니다',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/pl-PL.ts
Normal file
56
packages/data-validation/src/locale/pl-PL.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'między',
|
||||
greaterThan: 'większe niż',
|
||||
greaterThanOrEqual: 'większe lub równe',
|
||||
lessThan: 'mniejsze niż',
|
||||
lessThanOrEqual: 'mniejsze lub równe',
|
||||
equal: 'równe',
|
||||
notEqual: 'różne od',
|
||||
notBetween: 'nie między',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'Jest między {FORMULA1} a {FORMULA2}',
|
||||
greaterThan: 'Jest większe niż {FORMULA1}',
|
||||
greaterThanOrEqual: 'Jest większe lub równe {FORMULA1}',
|
||||
lessThan: 'Jest mniejsze niż {FORMULA1}',
|
||||
lessThanOrEqual: 'Jest mniejsze lub równe {FORMULA1}',
|
||||
equal: 'Jest równe {FORMULA1}',
|
||||
notEqual: 'Jest różne od {FORMULA1}',
|
||||
notBetween: 'Nie jest między {FORMULA1} a {FORMULA2}',
|
||||
legal: 'Jest prawidłowym {TYPE}',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'Wartość musi być między {FORMULA1} a {FORMULA2}',
|
||||
greaterThan: 'Wartość musi być większa niż {FORMULA1}',
|
||||
greaterThanOrEqual: 'Wartość musi być większa lub równa {FORMULA1}',
|
||||
lessThan: 'Wartość musi być mniejsza niż {FORMULA1}',
|
||||
lessThanOrEqual: 'Wartość musi być mniejsza lub równa {FORMULA1}',
|
||||
equal: 'Wartość musi być równa {FORMULA1}',
|
||||
notEqual: 'Wartość musi być różna od {FORMULA1}',
|
||||
notBetween: 'Wartość nie może być między {FORMULA1} a {FORMULA2}',
|
||||
legal: 'Wartość musi być prawidłowym {TYPE}',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/pt-BR.ts
Normal file
56
packages/data-validation/src/locale/pt-BR.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'entre',
|
||||
greaterThan: 'maior que',
|
||||
greaterThanOrEqual: 'maior ou igual',
|
||||
lessThan: 'menor que',
|
||||
lessThanOrEqual: 'menor ou igual',
|
||||
equal: 'igual',
|
||||
notEqual: 'diferente',
|
||||
notBetween: 'não está entre',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'Está entre {FORMULA1} e {FORMULA2}',
|
||||
greaterThan: 'É maior que {FORMULA1}',
|
||||
greaterThanOrEqual: 'É maior ou igual a {FORMULA1}',
|
||||
lessThan: 'É menor que {FORMULA1}',
|
||||
lessThanOrEqual: 'É menor ou igual a {FORMULA1}',
|
||||
equal: 'É igual a {FORMULA1}',
|
||||
notEqual: 'É diferente de {FORMULA1}',
|
||||
notBetween: 'Não está entre {FORMULA1} e {FORMULA2}',
|
||||
legal: 'É um {TYPE} válido',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'O valor deve estar entre {FORMULA1} e {FORMULA2}',
|
||||
greaterThan: 'O valor deve ser maior que {FORMULA1}',
|
||||
greaterThanOrEqual: 'O valor deve ser maior ou igual a {FORMULA1}',
|
||||
lessThan: 'O valor deve ser menor que {FORMULA1}',
|
||||
lessThanOrEqual: 'O valor deve ser menor ou igual a {FORMULA1}',
|
||||
equal: 'O valor deve ser igual a {FORMULA1}',
|
||||
notEqual: 'O valor deve ser diferente de {FORMULA1}',
|
||||
notBetween: 'O valor não deve estar entre {FORMULA1} e {FORMULA2}',
|
||||
legal: 'O valor deve ser um {TYPE} válido',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/ru-RU.ts
Normal file
56
packages/data-validation/src/locale/ru-RU.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'между',
|
||||
greaterThan: 'больше чем',
|
||||
greaterThanOrEqual: 'больше или равно',
|
||||
lessThan: 'меньше чем',
|
||||
lessThanOrEqual: 'меньше или равно',
|
||||
equal: 'равно',
|
||||
notEqual: 'не равно',
|
||||
notBetween: 'не между',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'между {FORMULA1} и {FORMULA2}',
|
||||
greaterThan: 'больше чем {FORMULA1}',
|
||||
greaterThanOrEqual: 'больше или равно {FORMULA1}',
|
||||
lessThan: 'меньше чем {FORMULA1}',
|
||||
lessThanOrEqual: 'меньше или равно {FORMULA1}',
|
||||
equal: 'равно {FORMULA1}',
|
||||
notEqual: 'не равно {FORMULA1}',
|
||||
notBetween: 'не между {FORMULA1} и {FORMULA2}',
|
||||
legal: 'является допустимым {TYPE}',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'Значение должно быть между {FORMULA1} и {FORMULA2}',
|
||||
greaterThan: 'Значение должно быть больше {FORMULA1}',
|
||||
greaterThanOrEqual: 'Значение должно быть больше или равно {FORMULA1}',
|
||||
lessThan: 'Значение должно быть меньше {FORMULA1}',
|
||||
lessThanOrEqual: 'Значение должно быть меньше или равно {FORMULA1}',
|
||||
equal: 'Значение должно быть равно {FORMULA1}',
|
||||
notEqual: 'Значение должно быть не равно {FORMULA1}',
|
||||
notBetween: 'Значение должно быть не между {FORMULA1} и {FORMULA2}',
|
||||
legal: 'Значение должно быть допустимым {TYPE}',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/sk-SK.ts
Normal file
56
packages/data-validation/src/locale/sk-SK.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'medzi',
|
||||
greaterThan: 'väčšie ako',
|
||||
greaterThanOrEqual: 'väčšie alebo rovné',
|
||||
lessThan: 'menšie ako',
|
||||
lessThanOrEqual: 'menšie alebo rovné',
|
||||
equal: 'rovné',
|
||||
notEqual: 'nerovné',
|
||||
notBetween: 'nie medzi',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'Je medzi {FORMULA1} a {FORMULA2}',
|
||||
greaterThan: 'Je väčšie ako {FORMULA1}',
|
||||
greaterThanOrEqual: 'Je väčšie alebo rovné {FORMULA1}',
|
||||
lessThan: 'Je menšie ako {FORMULA1}',
|
||||
lessThanOrEqual: 'Je menšie alebo rovné {FORMULA1}',
|
||||
equal: 'Je rovné {FORMULA1}',
|
||||
notEqual: 'Nie je rovné {FORMULA1}',
|
||||
notBetween: 'Nie je medzi {FORMULA1} a {FORMULA2}',
|
||||
legal: 'Je platný {TYPE}',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'Hodnota musí byť medzi {FORMULA1} a {FORMULA2}',
|
||||
greaterThan: 'Hodnota musí byť väčšia ako {FORMULA1}',
|
||||
greaterThanOrEqual: 'Hodnota musí byť väčšia alebo rovná {FORMULA1}',
|
||||
lessThan: 'Hodnota musí byť menšia ako {FORMULA1}',
|
||||
lessThanOrEqual: 'Hodnota musí byť menšia alebo rovná {FORMULA1}',
|
||||
equal: 'Hodnota musí byť rovná {FORMULA1}',
|
||||
notEqual: 'Hodnota nesmie byť rovná {FORMULA1}',
|
||||
notBetween: 'Hodnota nesmie byť medzi {FORMULA1} a {FORMULA2}',
|
||||
legal: 'Hodnota musí byť platný {TYPE}',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
20
packages/data-validation/src/locale/types.ts
Normal file
20
packages/data-validation/src/locale/types.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { LocaleLeafKeys } from '@univerjs/core';
|
||||
import type enUS from './en-US';
|
||||
|
||||
export type LocaleKey = LocaleLeafKeys<typeof enUS>;
|
||||
56
packages/data-validation/src/locale/vi-VN.ts
Normal file
56
packages/data-validation/src/locale/vi-VN.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: 'Giữa',
|
||||
greaterThan: 'Lớn hơn',
|
||||
greaterThanOrEqual: 'Lớn hơn hoặc bằng',
|
||||
lessThan: 'Nhỏ hơn',
|
||||
lessThanOrEqual: 'Nhỏ hơn hoặc bằng',
|
||||
equal: 'Bằng',
|
||||
notEqual: 'Không bằng',
|
||||
notBetween: 'Không nằm giữa',
|
||||
},
|
||||
ruleName: {
|
||||
between: 'Giữa {FORMULA1} và {FORMULA2}',
|
||||
greaterThan: 'Lớn hơn {FORMULA1}',
|
||||
greaterThanOrEqual: 'Lớn hơn hoặc bằng {FORMULA1}',
|
||||
lessThan: 'Nhỏ hơn {FORMULA1}',
|
||||
lessThanOrEqual: 'Nhỏ hơn hoặc bằng {FORMULA1}',
|
||||
equal: 'Bằng {FORMULA1}',
|
||||
notEqual: 'Không bằng {FORMULA1}',
|
||||
notBetween: 'Không nằm giữa {FORMULA1} và {FORMULA2}',
|
||||
legal: 'là một {TYPE} hợp lệ',
|
||||
},
|
||||
errorMsg: {
|
||||
between: 'Giá trị phải nằm giữa {FORMULA1} và {FORMULA2}',
|
||||
greaterThan: 'Giá trị phải lớn hơn {FORMULA1}',
|
||||
greaterThanOrEqual: 'Giá trị phải lớn hơn hoặc bằng {FORMULA1}',
|
||||
lessThan: 'Giá trị phải nhỏ hơn {FORMULA1}',
|
||||
lessThanOrEqual: 'Giá trị phải nhỏ hơn hoặc bằng {FORMULA1}',
|
||||
equal: 'Giá trị phải bằng {FORMULA1}',
|
||||
notEqual: 'Giá trị phải không bằng {FORMULA1}',
|
||||
notBetween: 'Giá trị phải không nằm giữa {FORMULA1} và {FORMULA2}',
|
||||
legal: 'Giá trị phải là một {TYPE} hợp lệ',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/zh-CN.ts
Normal file
56
packages/data-validation/src/locale/zh-CN.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: '介于',
|
||||
greaterThan: '大于',
|
||||
greaterThanOrEqual: '大于或等于',
|
||||
lessThan: '小于',
|
||||
lessThanOrEqual: '小于或等于',
|
||||
equal: '等于',
|
||||
notEqual: '不等于',
|
||||
notBetween: '未介于',
|
||||
},
|
||||
ruleName: {
|
||||
between: '介于 {FORMULA1} 和 {FORMULA2} 之间',
|
||||
greaterThan: '大于 {FORMULA1}',
|
||||
greaterThanOrEqual: '大于或等于 {FORMULA1}',
|
||||
lessThan: '小于 {FORMULA1}',
|
||||
lessThanOrEqual: '小于或等于 {FORMULA1}',
|
||||
equal: '等于 {FORMULA1}',
|
||||
notEqual: '不等于 {FORMULA1}',
|
||||
notBetween: '在 {FORMULA1} 和 {FORMULA2} 范围之外',
|
||||
legal: '是一个合法的 {TYPE}',
|
||||
},
|
||||
errorMsg: {
|
||||
between: '值必须介于 {FORMULA1} 和 {FORMULA2} 之间',
|
||||
greaterThan: '值必须大于 {FORMULA1}',
|
||||
greaterThanOrEqual: '值必须大于或等于 {FORMULA1}',
|
||||
lessThan: '值必须小于 {FORMULA1}',
|
||||
lessThanOrEqual: '值必须小于或等于 {FORMULA1}',
|
||||
equal: '值必须等于 {FORMULA1}',
|
||||
notEqual: '值必须不等于 {FORMULA1}',
|
||||
notBetween: '值必须在 {FORMULA1} 和 {FORMULA2} 范围之外',
|
||||
legal: '值必须是一个合法的 {TYPE}',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/zh-HK.ts
Normal file
56
packages/data-validation/src/locale/zh-HK.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: '介於',
|
||||
greaterThan: '大於',
|
||||
greaterThanOrEqual: '大於或等於',
|
||||
lessThan: '小於',
|
||||
lessThanOrEqual: '小於或等於',
|
||||
equal: '等於',
|
||||
notEqual: '不等於',
|
||||
notBetween: '未介於',
|
||||
},
|
||||
ruleName: {
|
||||
between: '介於 {FORMULA1} 和 {FORMULA2} 之間',
|
||||
greaterThan: '大於 {FORMULA1}',
|
||||
greaterThanOrEqual: '大於或等於 {FORMULA1}',
|
||||
lessThan: '小於 {FORMULA1}',
|
||||
lessThanOrEqual: '小於或等於 {FORMULA1}',
|
||||
equal: '等於 {FORMULA1}',
|
||||
notEqual: '不等於 {FORMULA1}',
|
||||
notBetween: '在 {FORMULA1} 和 {FORMULA2} 範圍之外',
|
||||
legal: '是一個合法的 {TYPE}',
|
||||
},
|
||||
errorMsg: {
|
||||
between: '值必須介於 {FORMULA1} 和 {FORMULA2} 之間',
|
||||
greaterThan: '值必須大於 {FORMULA1}',
|
||||
greaterThanOrEqual: '值必須大於或等於 {FORMULA1}',
|
||||
lessThan: '值必須小於 {FORMULA1}',
|
||||
lessThanOrEqual: '值必須小於或等於 {FORMULA1}',
|
||||
equal: '值必須等於 {FORMULA1}',
|
||||
notEqual: '值必須不等於 {FORMULA1}',
|
||||
notBetween: '值必須在 {FORMULA1} 和 {FORMULA2} 範圍之外',
|
||||
legal: '值必須是一個合法的 {TYPE}',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
56
packages/data-validation/src/locale/zh-TW.ts
Normal file
56
packages/data-validation/src/locale/zh-TW.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 enUS from './en-US';
|
||||
|
||||
const locale: typeof enUS = {
|
||||
'data-validation': {
|
||||
operators: {
|
||||
between: '介於',
|
||||
greaterThan: '大於',
|
||||
greaterThanOrEqual: '大於或等於',
|
||||
lessThan: '小於',
|
||||
lessThanOrEqual: '小於或等於',
|
||||
equal: '等於',
|
||||
notEqual: '不等於',
|
||||
notBetween: '未介於',
|
||||
},
|
||||
ruleName: {
|
||||
between: '介於 {FORMULA1} 和 {FORMULA2} 之間',
|
||||
greaterThan: '大於 {FORMULA1}',
|
||||
greaterThanOrEqual: '大於或等於 {FORMULA1}',
|
||||
lessThan: '小於 {FORMULA1}',
|
||||
lessThanOrEqual: '小於或等於 {FORMULA1}',
|
||||
equal: '等於 {FORMULA1}',
|
||||
notEqual: '不等於 {FORMULA1}',
|
||||
notBetween: '在 {FORMULA1} 和 {FORMULA2} 範圍之外',
|
||||
legal: '是一個合法的 {TYPE}',
|
||||
},
|
||||
errorMsg: {
|
||||
between: '值必須介於 {FORMULA1} 和 {FORMULA2} 之間',
|
||||
greaterThan: '值必須大於 {FORMULA1}',
|
||||
greaterThanOrEqual: '值必須大於或等於 {FORMULA1}',
|
||||
lessThan: '值必須小於 {FORMULA1}',
|
||||
lessThanOrEqual: '值必須小於或等於 {FORMULA1}',
|
||||
equal: '值必須等於 {FORMULA1}',
|
||||
notEqual: '值必須不等於 {FORMULA1}',
|
||||
notBetween: '值必須在 {FORMULA1} 和 {FORMULA2} 範圍之外',
|
||||
legal: '值必須是一個合法的 {TYPE}',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default locale;
|
||||
255
packages/data-validation/src/models/data-validation-model.ts
Normal file
255
packages/data-validation/src/models/data-validation-model.ts
Normal file
@@ -0,0 +1,255 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { IDataValidationRule } from '@univerjs/core';
|
||||
import type { IUpdateRulePayload } from '../types/interfaces/i-update-rule-payload';
|
||||
import { Disposable, ILogService, Tools } from '@univerjs/core';
|
||||
import { debounceTime, Subject } from 'rxjs';
|
||||
import { getRuleOptions, getRuleSetting } from '../common/util';
|
||||
import { UpdateRuleType } from '../types/enum/update-rule-type';
|
||||
|
||||
export type DataValidationChangeType = 'update' | 'add' | 'remove';
|
||||
export type DataValidationChangeSource = 'command' | 'patched';
|
||||
|
||||
export interface IRuleChange {
|
||||
rule: IDataValidationRule;
|
||||
type: DataValidationChangeType;
|
||||
unitId: string;
|
||||
subUnitId: string;
|
||||
source: DataValidationChangeSource;
|
||||
updatePayload?: IUpdateRulePayload;
|
||||
oldRule?: IDataValidationRule;
|
||||
}
|
||||
|
||||
interface ISubUnitDataValidation {
|
||||
map: Map<string, IDataValidationRule>;
|
||||
list: IDataValidationRule[];
|
||||
}
|
||||
|
||||
export class DataValidationModel extends Disposable {
|
||||
private readonly _model = new Map<string, Map<string, ISubUnitDataValidation>>();
|
||||
private readonly _ruleChange$ = new Subject<IRuleChange>();
|
||||
|
||||
ruleChange$ = this._ruleChange$.asObservable();
|
||||
ruleChangeDebounce$ = this.ruleChange$.pipe(debounceTime(20));
|
||||
|
||||
constructor(
|
||||
@ILogService private readonly _logService: ILogService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.disposeWithMe({
|
||||
dispose: () => {
|
||||
this._ruleChange$.complete();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private _ensureMap(unitId: string, subUnitId: string) {
|
||||
if (!this._model.has(unitId)) {
|
||||
this._model.set(unitId, new Map());
|
||||
}
|
||||
const unitMap = this._model.get(unitId)!;
|
||||
|
||||
if (unitMap.has(subUnitId)) {
|
||||
return unitMap.get(subUnitId)!;
|
||||
}
|
||||
|
||||
const map = { map: new Map<string, IDataValidationRule>(), list: [] as IDataValidationRule[] };
|
||||
unitMap.set(subUnitId, map);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private _addSubUnitRule(subUnit: ISubUnitDataValidation, rule: IDataValidationRule | IDataValidationRule[], index?: number) {
|
||||
const { map: dataValidationMap, list: dataValidations } = subUnit;
|
||||
const _rules = Array.isArray(rule) ? rule : [rule];
|
||||
const rules = _rules.filter((item) => !dataValidationMap.has(item.uid));
|
||||
|
||||
if (typeof index === 'number' && index < dataValidations.length) {
|
||||
dataValidations.splice(index, 0, ...rules);
|
||||
} else {
|
||||
dataValidations.push(...rules);
|
||||
}
|
||||
|
||||
rules.forEach((item) => {
|
||||
dataValidationMap.set(item.uid, item);
|
||||
});
|
||||
}
|
||||
|
||||
private _removeSubUnitRule(subUnit: ISubUnitDataValidation, ruleId: string) {
|
||||
const { map: dataValidationMap, list: dataValidations } = subUnit;
|
||||
const index = dataValidations.findIndex((item) => item.uid === ruleId);
|
||||
if (index > -1) {
|
||||
dataValidations.splice(index, 1);
|
||||
dataValidationMap.delete(ruleId);
|
||||
}
|
||||
}
|
||||
|
||||
private _updateSubUnitRule(subUnit: ISubUnitDataValidation, ruleId: string, payload: IUpdateRulePayload): IDataValidationRule {
|
||||
const { map: dataValidationMap, list: dataValidations } = subUnit;
|
||||
const oldRule = dataValidationMap.get(ruleId);
|
||||
const index = dataValidations.findIndex((rule) => ruleId === rule.uid);
|
||||
|
||||
if (!oldRule) {
|
||||
throw new Error(`Data validation rule is not found, ruleId: ${ruleId}.`);
|
||||
}
|
||||
|
||||
const rule = { ...oldRule };
|
||||
|
||||
switch (payload.type) {
|
||||
case UpdateRuleType.RANGE: {
|
||||
rule.ranges = payload.payload;
|
||||
break;
|
||||
}
|
||||
case UpdateRuleType.SETTING: {
|
||||
Object.assign(rule, getRuleSetting(payload.payload));
|
||||
break;
|
||||
}
|
||||
|
||||
case UpdateRuleType.OPTIONS: {
|
||||
Object.assign(rule, getRuleOptions(payload.payload));
|
||||
break;
|
||||
}
|
||||
|
||||
case UpdateRuleType.ALL: {
|
||||
Object.assign(rule, payload.payload);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
dataValidations[index] = rule;
|
||||
dataValidationMap.set(ruleId, rule);
|
||||
return rule;
|
||||
}
|
||||
|
||||
private _addRuleSideEffect(unitId: string, subUnitId: string, rule: IDataValidationRule, source: DataValidationChangeSource) {
|
||||
const subUnitMap = this._ensureMap(unitId, subUnitId);
|
||||
const oldRule = subUnitMap.map.get(rule.uid);
|
||||
if (oldRule) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
rule,
|
||||
type: 'add',
|
||||
unitId,
|
||||
subUnitId,
|
||||
source,
|
||||
} as const;
|
||||
}
|
||||
|
||||
addRule(unitId: string, subUnitId: string, rule: IDataValidationRule | IDataValidationRule[], source: DataValidationChangeSource, index?: number) {
|
||||
try {
|
||||
const subUnitMap = this._ensureMap(unitId, subUnitId);
|
||||
const rules = Array.isArray(rule) ? rule : [rule];
|
||||
const effects = rules.map((item) => this._addRuleSideEffect(unitId, subUnitId, item, source));
|
||||
|
||||
this._addSubUnitRule(subUnitMap, rule, index);
|
||||
effects.forEach((effect) => {
|
||||
if (effect) {
|
||||
this._ruleChange$.next(effect);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
this._logService.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
updateRule(unitId: string, subUnitId: string, ruleId: string, payload: IUpdateRulePayload, source: DataValidationChangeSource) {
|
||||
try {
|
||||
const subUnitMap = this._ensureMap(unitId, subUnitId);
|
||||
const oldRule = Tools.deepClone(subUnitMap.map.get(ruleId));
|
||||
if (!oldRule) {
|
||||
throw new Error(`Data validation rule is not found, ruleId: ${ruleId}.`);
|
||||
}
|
||||
const rule = this._updateSubUnitRule(subUnitMap, ruleId, payload);
|
||||
this._ruleChange$.next({
|
||||
rule,
|
||||
type: 'update',
|
||||
unitId,
|
||||
subUnitId,
|
||||
source,
|
||||
updatePayload: payload,
|
||||
oldRule,
|
||||
});
|
||||
} catch (error) {
|
||||
this._logService.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
removeRule(unitId: string, subUnitId: string, ruleId: string, source: DataValidationChangeSource) {
|
||||
try {
|
||||
const map = this._ensureMap(unitId, subUnitId);
|
||||
const oldRule = map.map.get(ruleId);
|
||||
if (oldRule) {
|
||||
this._removeSubUnitRule(map, ruleId);
|
||||
this._ruleChange$.next({
|
||||
rule: oldRule,
|
||||
type: 'remove',
|
||||
unitId,
|
||||
subUnitId,
|
||||
source,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
this._logService.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
getRuleById(unitId: string, subUnitId: string, ruleId: string) {
|
||||
const map = this._ensureMap(unitId, subUnitId);
|
||||
return map.map.get(ruleId);
|
||||
}
|
||||
|
||||
getRuleIndex(unitId: string, subUnitId: string, ruleId: string) {
|
||||
const map = this._ensureMap(unitId, subUnitId);
|
||||
return map.list.findIndex((rule) => rule.uid === ruleId);
|
||||
}
|
||||
|
||||
getRules(unitId: string, subUnitId: string) {
|
||||
const manager = this._ensureMap(unitId, subUnitId);
|
||||
return [...manager.list];
|
||||
}
|
||||
|
||||
getUnitRules(unitId: string) {
|
||||
const unitMap = this._model.get(unitId);
|
||||
if (!unitMap) {
|
||||
return [];
|
||||
}
|
||||
const res = [] as [string, IDataValidationRule[]][];
|
||||
|
||||
unitMap.forEach((manager, subUnitId) => {
|
||||
res.push([subUnitId, manager.list]);
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
deleteUnitRules(unitId: string) {
|
||||
this._model.delete(unitId);
|
||||
}
|
||||
|
||||
getSubUnitIds(unitId: string) {
|
||||
return Array.from(this._model.get(unitId)?.keys() ?? []);
|
||||
}
|
||||
|
||||
getAll() {
|
||||
return Array.from(this._model.keys()).map((unitId) => [unitId, this.getUnitRules(unitId)] as const);
|
||||
}
|
||||
}
|
||||
74
packages/data-validation/src/plugin.ts
Normal file
74
packages/data-validation/src/plugin.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { Dependency } from '@univerjs/core';
|
||||
import type { IUniverDataValidationConfig } from './config/config';
|
||||
import { ICommandService, IConfigService, Inject, Injector, merge, Plugin, UniverInstanceType } from '@univerjs/core';
|
||||
import pkg from '../package.json';
|
||||
import {
|
||||
AddDataValidationMutation,
|
||||
RemoveDataValidationMutation,
|
||||
UpdateDataValidationMutation,
|
||||
} from './commands/mutations/data-validation.mutation';
|
||||
import { DATA_VALIDATION_PLUGIN_CONFIG_KEY, defaultPluginConfig } from './config/config';
|
||||
import { DataValidationResourceController } from './controllers/dv-resource.controller';
|
||||
import { DataValidationModel } from './models/data-validation-model';
|
||||
import { DataValidatorRegistryService } from './services/data-validator-registry.service';
|
||||
|
||||
export class UniverDataValidationPlugin extends Plugin {
|
||||
static override pluginName = 'UNIVER_DATA_VALIDATION_PLUGIN';
|
||||
static override packageName = pkg.name;
|
||||
static override version = pkg.version;
|
||||
static override type = UniverInstanceType.UNIVER_SHEET;
|
||||
|
||||
constructor(
|
||||
private readonly _config: Partial<IUniverDataValidationConfig> = defaultPluginConfig,
|
||||
@Inject(Injector) protected _injector: Injector,
|
||||
@ICommandService private _commandService: ICommandService,
|
||||
@IConfigService private readonly _configService: IConfigService
|
||||
) {
|
||||
super();
|
||||
|
||||
// Manage the plugin configuration.
|
||||
const { ...rest } = merge(
|
||||
{},
|
||||
defaultPluginConfig,
|
||||
this._config
|
||||
);
|
||||
this._configService.setConfig(DATA_VALIDATION_PLUGIN_CONFIG_KEY, rest);
|
||||
}
|
||||
|
||||
override onStarting(): void {
|
||||
([
|
||||
[DataValidationModel],
|
||||
[DataValidatorRegistryService],
|
||||
[DataValidationResourceController],
|
||||
] as Dependency[]).forEach((d) => this._injector.add(d));
|
||||
|
||||
[
|
||||
// mutation
|
||||
AddDataValidationMutation,
|
||||
UpdateDataValidationMutation,
|
||||
RemoveDataValidationMutation,
|
||||
].forEach((command) => {
|
||||
this._commandService.registerCommand(command);
|
||||
});
|
||||
}
|
||||
|
||||
override onReady(): void {
|
||||
this._injector.get(DataValidationResourceController);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { Injector } from '@univerjs/core';
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
import { DataValidatorRegistryScope, DataValidatorRegistryService } from '../data-validator-registry.service';
|
||||
|
||||
describe('DataValidatorRegistryService', () => {
|
||||
let service: DataValidatorRegistryService;
|
||||
|
||||
beforeEach(() => {
|
||||
const injector = new Injector();
|
||||
injector.add([DataValidatorRegistryService]);
|
||||
service = injector.get(DataValidatorRegistryService);
|
||||
});
|
||||
|
||||
it('registers validators by business scope and unregisters them with the disposable', () => {
|
||||
const changes: number[] = [];
|
||||
service.validatorsChange$.subscribe(() => changes.push(1));
|
||||
const validator = { id: 'decimal', scopes: DataValidatorRegistryScope.SHEET };
|
||||
|
||||
const disposable = service.register(validator as never);
|
||||
|
||||
expect(service.getValidatorItem('decimal')).toBe(validator);
|
||||
expect(service.getValidatorsByScope(DataValidatorRegistryScope.SHEET)).toEqual([validator]);
|
||||
|
||||
disposable.dispose();
|
||||
|
||||
expect(service.getValidatorItem('decimal')).toBeUndefined();
|
||||
expect(service.getValidatorsByScope(DataValidatorRegistryScope.SHEET)).toEqual([]);
|
||||
expect(changes.length).toBe(3);
|
||||
});
|
||||
|
||||
it('rejects duplicate validators in the same scope', () => {
|
||||
service.register({ id: 'decimal', scopes: DataValidatorRegistryScope.SHEET } as never);
|
||||
|
||||
expect(() => service.register({ id: 'decimal', scopes: DataValidatorRegistryScope.SHEET } as never)).toThrow(
|
||||
'Validator item with the same id decimal has already been added!'
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { BaseDataValidator } from '../validators/base-data-validator';
|
||||
import { toDisposable } from '@univerjs/core';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
export enum DataValidatorRegistryScope {
|
||||
SHEET = 'sheet',
|
||||
}
|
||||
|
||||
/**
|
||||
* Register data validator
|
||||
*/
|
||||
export class DataValidatorRegistryService {
|
||||
private _validatorByScopes = new Map<string, Array<BaseDataValidator>>();
|
||||
|
||||
private _validatorMap = new Map<string, BaseDataValidator>();
|
||||
|
||||
private _validatorsChange$ = new BehaviorSubject<void>(undefined);
|
||||
validatorsChange$ = this._validatorsChange$.asObservable();
|
||||
|
||||
private _addValidatorToScope(validator: BaseDataValidator, scope: string) {
|
||||
if (!this._validatorByScopes.has(scope)) {
|
||||
this._validatorByScopes.set(scope, []);
|
||||
}
|
||||
|
||||
const validators = this._validatorByScopes.get(scope)!;
|
||||
if (validators.findIndex((m) => m.id === validator.id) > -1) {
|
||||
throw new Error(`Validator item with the same id ${validator.id} has already been added!`);
|
||||
}
|
||||
validators.push(validator);
|
||||
}
|
||||
|
||||
private _removeValidatorFromScope(validator: BaseDataValidator, scope: string) {
|
||||
const validators = this._validatorByScopes.get(scope);
|
||||
if (!validators) {
|
||||
return;
|
||||
}
|
||||
|
||||
const index = validators.findIndex((v) => v.id === validator.id);
|
||||
if (index > -1) {
|
||||
validators.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
register(validator: BaseDataValidator) {
|
||||
this._validatorMap.set(validator.id, validator);
|
||||
|
||||
if (Array.isArray(validator.scopes)) {
|
||||
validator.scopes.forEach((scope) => {
|
||||
this._addValidatorToScope(validator, scope);
|
||||
});
|
||||
} else {
|
||||
this._addValidatorToScope(validator, validator.scopes);
|
||||
}
|
||||
|
||||
this._validatorsChange$.next();
|
||||
|
||||
return toDisposable(() => {
|
||||
this._validatorMap.delete(validator.id);
|
||||
|
||||
if (Array.isArray(validator.scopes)) {
|
||||
validator.scopes.forEach((scope) => {
|
||||
this._removeValidatorFromScope(validator, scope);
|
||||
});
|
||||
} else {
|
||||
this._removeValidatorFromScope(validator, validator.scopes);
|
||||
}
|
||||
|
||||
this._validatorsChange$.next();
|
||||
});
|
||||
}
|
||||
|
||||
getValidatorItem(id: string) {
|
||||
return this._validatorMap.get(id);
|
||||
}
|
||||
|
||||
getValidatorsByScope(scope: string) {
|
||||
return this._validatorByScopes.get(scope);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { DataValidationOperator } from '@univerjs/core';
|
||||
|
||||
export const OperatorTextMap: Record<DataValidationOperator, string> = {
|
||||
[DataValidationOperator.BETWEEN]: 'data-validation.operators.between',
|
||||
[DataValidationOperator.EQUAL]: 'data-validation.operators.equal',
|
||||
[DataValidationOperator.GREATER_THAN]: 'data-validation.operators.greaterThan',
|
||||
[DataValidationOperator.GREATER_THAN_OR_EQUAL]: 'data-validation.operators.greaterThanOrEqual',
|
||||
[DataValidationOperator.LESS_THAN]: 'data-validation.operators.lessThan',
|
||||
[DataValidationOperator.LESS_THAN_OR_EQUAL]: 'data-validation.operators.lessThanOrEqual',
|
||||
[DataValidationOperator.NOT_BETWEEN]: 'data-validation.operators.notBetween',
|
||||
[DataValidationOperator.NOT_EQUAL]: 'data-validation.operators.notEqual',
|
||||
};
|
||||
|
||||
export const OperatorTitleMap: Record<DataValidationOperator | 'NONE', string> = {
|
||||
[DataValidationOperator.BETWEEN]: 'data-validation.ruleName.between',
|
||||
[DataValidationOperator.EQUAL]: 'data-validation.ruleName.equal',
|
||||
[DataValidationOperator.GREATER_THAN]: 'data-validation.ruleName.greaterThan',
|
||||
[DataValidationOperator.GREATER_THAN_OR_EQUAL]: 'data-validation.ruleName.greaterThanOrEqual',
|
||||
[DataValidationOperator.LESS_THAN]: 'data-validation.ruleName.lessThan',
|
||||
[DataValidationOperator.LESS_THAN_OR_EQUAL]: 'data-validation.ruleName.lessThanOrEqual',
|
||||
[DataValidationOperator.NOT_BETWEEN]: 'data-validation.ruleName.notBetween',
|
||||
[DataValidationOperator.NOT_EQUAL]: 'data-validation.ruleName.notEqual',
|
||||
NONE: 'data-validation.ruleName.legal',
|
||||
};
|
||||
|
||||
export const OperatorErrorTitleMap: Record<DataValidationOperator | 'NONE', string> = {
|
||||
[DataValidationOperator.BETWEEN]: 'data-validation.errorMsg.between',
|
||||
[DataValidationOperator.EQUAL]: 'data-validation.errorMsg.equal',
|
||||
[DataValidationOperator.GREATER_THAN]: 'data-validation.errorMsg.greaterThan',
|
||||
[DataValidationOperator.GREATER_THAN_OR_EQUAL]: 'data-validation.errorMsg.greaterThanOrEqual',
|
||||
[DataValidationOperator.LESS_THAN]: 'data-validation.errorMsg.lessThan',
|
||||
[DataValidationOperator.LESS_THAN_OR_EQUAL]: 'data-validation.errorMsg.lessThanOrEqual',
|
||||
[DataValidationOperator.NOT_BETWEEN]: 'data-validation.errorMsg.notBetween',
|
||||
[DataValidationOperator.NOT_EQUAL]: 'data-validation.errorMsg.notEqual',
|
||||
NONE: 'data-validation.errorMsg.legal',
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { DataValidationOperator } from '@univerjs/core';
|
||||
|
||||
export const TWO_FORMULA_OPERATOR_COUNT: DataValidationOperator[] = [
|
||||
DataValidationOperator.BETWEEN,
|
||||
DataValidationOperator.NOT_BETWEEN,
|
||||
];
|
||||
22
packages/data-validation/src/types/enum/update-rule-type.ts
Normal file
22
packages/data-validation/src/types/enum/update-rule-type.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export enum UpdateRuleType {
|
||||
SETTING,
|
||||
RANGE,
|
||||
OPTIONS,
|
||||
ALL,
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export interface IDataValidationDropdownProps {
|
||||
top: number;
|
||||
left: number;
|
||||
width: number;
|
||||
height: number;
|
||||
unitId: string;
|
||||
subUnitId: string;
|
||||
row: number;
|
||||
col: number;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { DataValidationOperator } from '@univerjs/core';
|
||||
|
||||
export interface IDataValidatorOperatorConfig {
|
||||
operator: DataValidationOperator;
|
||||
text: string;
|
||||
placeholder1?: string;
|
||||
placeholder2?: string;
|
||||
formulaCount: 1 | 2;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export interface IFormulaValue {
|
||||
formula1?: string;
|
||||
formula2?: string;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { IDataValidationRule, IDataValidationRuleBase, IDataValidationRuleOptions } from '@univerjs/core';
|
||||
import type { UpdateRuleType } from '../enum/update-rule-type';
|
||||
|
||||
export interface IUpdateRuleRangePayload {
|
||||
type: UpdateRuleType.RANGE;
|
||||
payload: any[];
|
||||
}
|
||||
|
||||
export interface IUpdateRuleSettingPayload {
|
||||
type: UpdateRuleType.SETTING;
|
||||
payload: IDataValidationRuleBase;
|
||||
}
|
||||
|
||||
export interface IUpdateRuleOptionsPayload {
|
||||
type: UpdateRuleType.OPTIONS;
|
||||
payload: Partial<IDataValidationRuleOptions>;
|
||||
}
|
||||
|
||||
export interface IUpdateRuleAllPayload {
|
||||
type: UpdateRuleType.ALL;
|
||||
payload: Omit<IDataValidationRule, 'uid'>;
|
||||
}
|
||||
|
||||
export type IUpdateRulePayload =
|
||||
IUpdateRuleRangePayload
|
||||
| IUpdateRuleSettingPayload
|
||||
| IUpdateRuleOptionsPayload
|
||||
| IUpdateRuleAllPayload;
|
||||
281
packages/data-validation/src/validators/base-data-validator.ts
Normal file
281
packages/data-validation/src/validators/base-data-validator.ts
Normal file
@@ -0,0 +1,281 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { CellValue, IDataValidationRule, IDataValidationRuleBase, IStyleData, Nullable, Workbook, Worksheet } from '@univerjs/core';
|
||||
import type { CellValueType } from '@univerjs/protocol';
|
||||
import type { ISheetLocationBase } from '@univerjs/sheets';
|
||||
import type { IBaseDataValidationWidget } from './base-widget';
|
||||
import { DataValidationOperator, Inject, Injector, LocaleService } from '@univerjs/core';
|
||||
import { OperatorErrorTitleMap, OperatorTitleMap } from '../types/const/operator-text-map';
|
||||
|
||||
export const FORMULA1 = '{FORMULA1}';
|
||||
export const FORMULA2 = '{FORMULA2}';
|
||||
export const TYPE = '{TYPE}';
|
||||
|
||||
const operatorNameMap: Record<DataValidationOperator, string> = {
|
||||
[DataValidationOperator.BETWEEN]: 'data-validation.operators.between',
|
||||
[DataValidationOperator.EQUAL]: 'data-validation.operators.equal',
|
||||
[DataValidationOperator.GREATER_THAN]: 'data-validation.operators.greaterThan',
|
||||
[DataValidationOperator.GREATER_THAN_OR_EQUAL]: 'data-validation.operators.greaterThanOrEqual',
|
||||
[DataValidationOperator.LESS_THAN]: 'data-validation.operators.lessThan',
|
||||
[DataValidationOperator.LESS_THAN_OR_EQUAL]: 'data-validation.operators.lessThanOrEqual',
|
||||
[DataValidationOperator.NOT_BETWEEN]: 'data-validation.operators.notBetween',
|
||||
[DataValidationOperator.NOT_EQUAL]: 'data-validation.operators.notEqual',
|
||||
};
|
||||
|
||||
export interface IValidatorCellInfo<DataType = Nullable<CellValue>> {
|
||||
value: DataType;
|
||||
interceptValue: Nullable<CellValue>;
|
||||
row: number;
|
||||
column: number;
|
||||
unitId: string;
|
||||
subUnitId: string;
|
||||
worksheet: Worksheet;
|
||||
workbook: Workbook;
|
||||
t: Nullable<CellValueType>;
|
||||
}
|
||||
|
||||
export interface IFormulaResult<T = any> {
|
||||
formula1: T;
|
||||
formula2: T;
|
||||
isFormulaValid: boolean;
|
||||
}
|
||||
|
||||
export interface IFormulaValidResult {
|
||||
success: boolean;
|
||||
formula1?: string;
|
||||
formula2?: string;
|
||||
}
|
||||
|
||||
export enum DataValidatorDropdownType {
|
||||
DATE = 'date',
|
||||
TIME = 'time',
|
||||
DATETIME = 'datetime',
|
||||
LIST = 'list',
|
||||
MULTIPLE_LIST = 'multipleList',
|
||||
COLOR = 'color',
|
||||
CASCADE = 'cascade',
|
||||
}
|
||||
|
||||
export abstract class BaseDataValidator {
|
||||
abstract id: string;
|
||||
abstract title: string;
|
||||
abstract operators: DataValidationOperator[];
|
||||
abstract scopes: string[] | string;
|
||||
abstract order: number;
|
||||
|
||||
offsetFormulaByRange = true;
|
||||
|
||||
// #region UI related
|
||||
|
||||
formulaInput: string | undefined = undefined;
|
||||
canvasRender: Nullable<IBaseDataValidationWidget> = null;
|
||||
dropdownType: DataValidatorDropdownType | undefined = undefined;
|
||||
optionsInput: string | undefined = undefined;
|
||||
|
||||
// #endregion
|
||||
|
||||
constructor(
|
||||
@Inject(LocaleService) readonly localeService: LocaleService,
|
||||
@Inject(Injector) readonly injector: Injector
|
||||
) {
|
||||
// empty
|
||||
}
|
||||
|
||||
get operatorNames() {
|
||||
return this.operators.map((operator) => this.localeService.t(operatorNameMap[operator]));
|
||||
}
|
||||
|
||||
get titleStr() {
|
||||
return this.localeService.t(this.title);
|
||||
}
|
||||
|
||||
skipDefaultFontRender: ((rule: IDataValidationRule, cellValue: Nullable<CellValue>, pos: any) => boolean) | undefined;
|
||||
|
||||
generateRuleName(rule: IDataValidationRuleBase): string {
|
||||
if (!rule.operator) {
|
||||
return this.localeService.t(OperatorTitleMap.NONE).replace(TYPE, this.titleStr);
|
||||
}
|
||||
|
||||
const ruleName = this.localeService.t(OperatorTitleMap[rule.operator]).replace(FORMULA1, rule.formula1 ?? '').replace(FORMULA2, rule.formula2 ?? '');
|
||||
return `${this.titleStr} ${ruleName}`;
|
||||
}
|
||||
|
||||
generateRuleErrorMessage(rule: IDataValidationRuleBase, position: ISheetLocationBase) {
|
||||
if (!rule.operator) {
|
||||
return this.localeService.t(OperatorErrorTitleMap.NONE).replace(TYPE, this.titleStr); ;
|
||||
}
|
||||
|
||||
const errorMsg = this.localeService.t(OperatorErrorTitleMap[rule.operator]).replace(FORMULA1, rule.formula1 ?? '').replace(FORMULA2, rule.formula2 ?? '');
|
||||
return `${errorMsg}`;
|
||||
}
|
||||
|
||||
getExtraStyle(rule: IDataValidationRuleBase, value: Nullable<CellValue>, ctx: { style: IStyleData }, row: number, column: number): Nullable<IStyleData> {}
|
||||
|
||||
getRuleFinalError(rule: IDataValidationRule, position: ISheetLocationBase) {
|
||||
if (rule.showErrorMessage && rule.error) {
|
||||
return rule.error;
|
||||
}
|
||||
|
||||
return this.generateRuleErrorMessage(rule, position);
|
||||
}
|
||||
|
||||
isEmptyCellValue(cellValue: Nullable<CellValue>): cellValue is null | undefined | void {
|
||||
if (cellValue === '' || cellValue === undefined || cellValue === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
abstract parseFormula(rule: IDataValidationRule, unitId: string, subUnitId: string, row: number, column: number): Promise<IFormulaResult<number | undefined>>;
|
||||
|
||||
abstract validatorFormula(rule: IDataValidationRule, unitId: string, subUnitId: string): IFormulaValidResult;
|
||||
|
||||
normalizeFormula(rule: IDataValidationRule, unitId: string, subUnitId: string) {
|
||||
return {
|
||||
formula1: rule.formula1,
|
||||
formula2: rule.formula2,
|
||||
};
|
||||
}
|
||||
|
||||
async isValidType(cellInfo: IValidatorCellInfo, formula: IFormulaResult, rule: IDataValidationRule): Promise<boolean> {
|
||||
return true;
|
||||
};
|
||||
|
||||
transform(cellInfo: IValidatorCellInfo, formula: IFormulaResult, rule: IDataValidationRule): IValidatorCellInfo<number> {
|
||||
return cellInfo as IValidatorCellInfo<number>;
|
||||
};
|
||||
|
||||
async validatorIsEqual(cellInfo: IValidatorCellInfo<CellValue>, formula: IFormulaResult, rule: IDataValidationRule) {
|
||||
const { formula1 } = formula;
|
||||
const { value: cellValue } = cellInfo;
|
||||
if (Number.isNaN(formula1)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return cellValue === formula1;
|
||||
}
|
||||
|
||||
async validatorIsNotEqual(cellInfo: IValidatorCellInfo<number>, formula: IFormulaResult, _rule: IDataValidationRule) {
|
||||
const { formula1 } = formula;
|
||||
if (Number.isNaN(formula1)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return cellInfo.value !== formula1;
|
||||
}
|
||||
|
||||
async validatorIsBetween(cellInfo: IValidatorCellInfo<number>, formula: IFormulaResult, _rule: IDataValidationRule) {
|
||||
const { formula1, formula2 } = formula;
|
||||
if (Number.isNaN(formula1) || Number.isNaN(formula2)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const start = Math.min(formula1, formula2);
|
||||
const end = Math.max(formula1, formula2);
|
||||
return cellInfo.value >= start && cellInfo.value <= end;
|
||||
}
|
||||
|
||||
async validatorIsNotBetween(cellInfo: IValidatorCellInfo<number>, formula: IFormulaResult, _rule: IDataValidationRule) {
|
||||
const { formula1, formula2 } = formula;
|
||||
if (Number.isNaN(formula1) || Number.isNaN(formula2)) {
|
||||
return true;
|
||||
}
|
||||
const start = Math.min(formula1, formula2);
|
||||
const end = Math.max(formula1, formula2);
|
||||
return cellInfo.value < start || cellInfo.value > end;
|
||||
}
|
||||
|
||||
async validatorIsGreaterThan(cellInfo: IValidatorCellInfo<number>, formula: IFormulaResult, _rule: IDataValidationRule) {
|
||||
const { formula1 } = formula;
|
||||
if (Number.isNaN(formula1)) {
|
||||
return true;
|
||||
}
|
||||
return cellInfo.value > formula1;
|
||||
}
|
||||
|
||||
async validatorIsGreaterThanOrEqual(cellInfo: IValidatorCellInfo<number>, formula: IFormulaResult, _rule: IDataValidationRule) {
|
||||
const { formula1 } = formula;
|
||||
if (Number.isNaN(formula1)) {
|
||||
return true;
|
||||
}
|
||||
return cellInfo.value >= formula1;
|
||||
}
|
||||
|
||||
async validatorIsLessThan(cellInfo: IValidatorCellInfo<number>, formula: IFormulaResult, _rule: IDataValidationRule) {
|
||||
const { formula1 } = formula;
|
||||
if (Number.isNaN(formula1)) {
|
||||
return true;
|
||||
}
|
||||
return cellInfo.value < formula1;
|
||||
}
|
||||
|
||||
async validatorIsLessThanOrEqual(cellInfo: IValidatorCellInfo<number>, formula: IFormulaResult, _rule: IDataValidationRule) {
|
||||
const { formula1 } = formula;
|
||||
if (Number.isNaN(formula1)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return cellInfo.value <= formula1;
|
||||
}
|
||||
|
||||
async validator(cellInfo: IValidatorCellInfo, rule: IDataValidationRule): Promise<boolean> {
|
||||
const { value: cellValue, unitId, subUnitId } = cellInfo;
|
||||
const isEmpty = this.isEmptyCellValue(cellValue);
|
||||
const { allowBlank = true, operator } = rule;
|
||||
if (isEmpty) {
|
||||
return allowBlank;
|
||||
}
|
||||
|
||||
const formulaInfo = await this.parseFormula(rule, unitId, subUnitId, cellInfo.row, cellInfo.column);
|
||||
|
||||
if (!formulaInfo.isFormulaValid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(await this.isValidType(cellInfo, formulaInfo, rule))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!operator) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const transformedCell = this.transform(cellInfo, formulaInfo, rule);
|
||||
|
||||
switch (operator) {
|
||||
case DataValidationOperator.BETWEEN:
|
||||
return this.validatorIsBetween(transformedCell, formulaInfo, rule);
|
||||
case DataValidationOperator.EQUAL:
|
||||
return this.validatorIsEqual(transformedCell, formulaInfo, rule);
|
||||
case DataValidationOperator.GREATER_THAN:
|
||||
return this.validatorIsGreaterThan(transformedCell, formulaInfo, rule);
|
||||
case DataValidationOperator.GREATER_THAN_OR_EQUAL:
|
||||
return this.validatorIsGreaterThanOrEqual(transformedCell, formulaInfo, rule);
|
||||
case DataValidationOperator.LESS_THAN:
|
||||
return this.validatorIsLessThan(transformedCell, formulaInfo, rule);
|
||||
case DataValidationOperator.LESS_THAN_OR_EQUAL:
|
||||
return this.validatorIsLessThanOrEqual(transformedCell, formulaInfo, rule);
|
||||
case DataValidationOperator.NOT_BETWEEN:
|
||||
return this.validatorIsNotBetween(transformedCell, formulaInfo, rule);
|
||||
case DataValidationOperator.NOT_EQUAL:
|
||||
return this.validatorIsNotEqual(transformedCell, formulaInfo, rule);
|
||||
default:
|
||||
throw new Error('Unknown operator.');
|
||||
}
|
||||
}
|
||||
}
|
||||
22
packages/data-validation/src/validators/base-widget.ts
Normal file
22
packages/data-validation/src/validators/base-widget.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { ICellCustomRender, ICellRenderContext } from '@univerjs/core';
|
||||
|
||||
export interface IBaseDataValidationWidget extends ICellCustomRender {
|
||||
calcCellAutoHeight(info: ICellRenderContext): number | undefined;
|
||||
calcCellAutoWidth(info: ICellRenderContext): number | undefined;
|
||||
}
|
||||
Reference in New Issue
Block a user