mirror of
https://github.com/SuiteCRM/SuiteCRM-Core.git
synced 2025-08-29 04:47:10 +08:00
Add support for field specific validations
- Allow adding validations to specific fields - Allow excluding validations to specific fields - Add string matrix into common
This commit is contained in:
parent
3eb305ba4f
commit
10d4c687dd
4 changed files with 93 additions and 34 deletions
|
@ -21,6 +21,7 @@ export * from './statistics/statistics.model';
|
||||||
export * from './types/messages';
|
export * from './types/messages';
|
||||||
export * from './types/overridable-map';
|
export * from './types/overridable-map';
|
||||||
export * from './types/string-map';
|
export * from './types/string-map';
|
||||||
|
export * from './types/string-matrix';
|
||||||
export * from './types/user';
|
export * from './types/user';
|
||||||
export * from './utils/object-utils';
|
export * from './utils/object-utils';
|
||||||
export * from './utils/value-utils';
|
export * from './utils/value-utils';
|
||||||
|
|
5
core/app/common/src/lib/types/string-matrix.ts
Normal file
5
core/app/common/src/lib/types/string-matrix.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import {StringMap} from './string-map';
|
||||||
|
|
||||||
|
export interface StringMatrix {
|
||||||
|
[key: string]: StringMap;
|
||||||
|
}
|
|
@ -26,7 +26,6 @@
|
||||||
|
|
||||||
import {Observable, of} from 'rxjs';
|
import {Observable, of} from 'rxjs';
|
||||||
import {shareReplay} from 'rxjs/operators';
|
import {shareReplay} from 'rxjs/operators';
|
||||||
import {EntityMutationGQL} from '../../../api/graphql-api';
|
|
||||||
import {FetchResult} from '@apollo/client/core';
|
import {FetchResult} from '@apollo/client/core';
|
||||||
import {ProcessService} from '../../process.service';
|
import {ProcessService} from '../../process.service';
|
||||||
import {appStateStoreMock} from '../../../../store/app-state/app-state.store.spec.mock';
|
import {appStateStoreMock} from '../../../../store/app-state/app-state.store.spec.mock';
|
||||||
|
@ -34,6 +33,7 @@ import {AsyncActionService} from './async-action';
|
||||||
import {messageServiceMock} from '../../../message/message.service.spec.mock';
|
import {messageServiceMock} from '../../../message/message.service.spec.mock';
|
||||||
import {redirectBulkActionMock} from './actions/redirect/redirect.async-action.spec.mock';
|
import {redirectBulkActionMock} from './actions/redirect/redirect.async-action.spec.mock';
|
||||||
import {exportBulkActionMock} from './actions/export/export.async-action.spec.mock';
|
import {exportBulkActionMock} from './actions/export/export.async-action.spec.mock';
|
||||||
|
import {EntityMutationGQL} from '../../../api/graphql-api/api.record.create';
|
||||||
|
|
||||||
export const bulkActionMockData = {
|
export const bulkActionMockData = {
|
||||||
'bulk-merge': {
|
'bulk-merge': {
|
||||||
|
|
|
@ -26,11 +26,9 @@
|
||||||
|
|
||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
import {ValidatorInterface} from './validator.Interface';
|
import {ValidatorInterface} from './validator.Interface';
|
||||||
import {Record} from 'common';
|
import {MapEntry, OverridableMap, Record, StringMap, StringMatrix, ViewFieldDefinition} from 'common';
|
||||||
import {ViewFieldDefinition} from 'common';
|
|
||||||
import {AsyncValidatorFn, ValidatorFn} from '@angular/forms';
|
import {AsyncValidatorFn, ValidatorFn} from '@angular/forms';
|
||||||
import {AsyncValidatorInterface} from './aync-validator.Interface';
|
import {AsyncValidatorInterface} from './aync-validator.Interface';
|
||||||
import {MapEntry, OverridableMap} from 'common';
|
|
||||||
import {RequiredValidator} from './validators/required.validator';
|
import {RequiredValidator} from './validators/required.validator';
|
||||||
import {CurrencyValidator} from './validators/currency.validator';
|
import {CurrencyValidator} from './validators/currency.validator';
|
||||||
import {DateValidator} from './validators/date.validator';
|
import {DateValidator} from './validators/date.validator';
|
||||||
|
@ -68,6 +66,12 @@ export class ValidationManager implements ValidationManagerInterface {
|
||||||
protected saveValidators: OverridableMap<ValidatorInterface>;
|
protected saveValidators: OverridableMap<ValidatorInterface>;
|
||||||
protected asyncSaveValidators: OverridableMap<AsyncValidatorInterface>;
|
protected asyncSaveValidators: OverridableMap<AsyncValidatorInterface>;
|
||||||
protected filterValidators: OverridableMap<ValidatorInterface>;
|
protected filterValidators: OverridableMap<ValidatorInterface>;
|
||||||
|
protected filterFieldExclusion: StringMatrix = {
|
||||||
|
default: {}
|
||||||
|
};
|
||||||
|
protected saveFieldExclusions: StringMatrix = {
|
||||||
|
default: {}
|
||||||
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected requiredValidator: RequiredValidator,
|
protected requiredValidator: RequiredValidator,
|
||||||
|
@ -85,56 +89,81 @@ export class ValidationManager implements ValidationManagerInterface {
|
||||||
this.asyncSaveValidators = new OverridableMap<AsyncValidatorInterface>();
|
this.asyncSaveValidators = new OverridableMap<AsyncValidatorInterface>();
|
||||||
this.filterValidators = new OverridableMap<ValidatorInterface>();
|
this.filterValidators = new OverridableMap<ValidatorInterface>();
|
||||||
|
|
||||||
this.saveValidators.addEntry('default', 'required', requiredValidator);
|
this.saveValidators.addEntry('default', this.getKey('required', 'all'), requiredValidator);
|
||||||
this.saveValidators.addEntry('default', 'range', rangeValidator);
|
this.saveValidators.addEntry('default', this.getKey('range', 'all'), rangeValidator);
|
||||||
this.saveValidators.addEntry('default', 'currency', currencyValidator);
|
this.saveValidators.addEntry('default', this.getKey('currency', 'all'), currencyValidator);
|
||||||
this.saveValidators.addEntry('default', 'date', dateValidator);
|
this.saveValidators.addEntry('default', this.getKey('date', 'all'), dateValidator);
|
||||||
this.saveValidators.addEntry('default', 'datetime', datetimeValidator);
|
this.saveValidators.addEntry('default', this.getKey('datetime', 'all'), datetimeValidator);
|
||||||
this.saveValidators.addEntry('default', 'email', emailValidator);
|
this.saveValidators.addEntry('default', this.getKey('email', 'all'), emailValidator);
|
||||||
this.saveValidators.addEntry('default', 'float', floatValidator);
|
this.saveValidators.addEntry('default', this.getKey('float', 'all'), floatValidator);
|
||||||
this.saveValidators.addEntry('default', 'int', intValidator);
|
this.saveValidators.addEntry('default', this.getKey('int', 'all'), intValidator);
|
||||||
this.saveValidators.addEntry('default', 'phone', phoneValidator);
|
this.saveValidators.addEntry('default', this.getKey('phone', 'all'), phoneValidator);
|
||||||
|
|
||||||
this.filterValidators.addEntry('default', 'date', dateValidator);
|
this.filterValidators.addEntry('default', this.getKey('date', 'all'), dateValidator);
|
||||||
this.filterValidators.addEntry('default', 'datetime', datetimeValidator);
|
this.filterValidators.addEntry('default', this.getKey('datetime', 'all'), datetimeValidator);
|
||||||
this.filterValidators.addEntry('default', 'float', floatValidator);
|
this.filterValidators.addEntry('default', this.getKey('float', 'all'), floatValidator);
|
||||||
this.filterValidators.addEntry('default', 'currency', currencyValidator);
|
this.filterValidators.addEntry('default', this.getKey('currency', 'all'), currencyValidator);
|
||||||
this.filterValidators.addEntry('default', 'int', intValidator);
|
this.filterValidators.addEntry('default', this.getKey('int', 'all'), intValidator);
|
||||||
this.filterValidators.addEntry('default', 'phone', phoneValidator);
|
this.filterValidators.addEntry('default', this.getKey('phone', 'all'), phoneValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerSaveValidator(module: string, key: string, validator: ValidatorInterface): void {
|
public registerFieldSaveValidator(module: string, type: string, field: string, validator: ValidatorInterface): void {
|
||||||
this.filterValidators.addEntry(module, key, validator);
|
this.saveValidators.addEntry(module, this.getKey(type, field), validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerFilterValidator(module: string, key: string, validator: ValidatorInterface): void {
|
public registerSaveValidator(module: string, type: string, validator: ValidatorInterface): void {
|
||||||
this.saveValidators.addEntry(module, key, validator);
|
this.saveValidators.addEntry(module, this.getKey(type, 'all'), validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public excludeSaveValidator(module: string, key: string): void {
|
public registerFieldFilterValidator(module: string, type: string, field: string, validator: ValidatorInterface): void {
|
||||||
this.saveValidators.excludeEntry(module, key);
|
this.filterValidators.addEntry(module, this.getKey(type, field), validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public excludeFilterValidator(module: string, key: string): void {
|
public registerFilterValidator(module: string, type: string, validator: ValidatorInterface): void {
|
||||||
this.filterValidators.excludeEntry(module, key);
|
this.filterValidators.addEntry(module, this.getKey(type, 'all'), validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerAsyncSaveValidator(module: string, key: string, validator: AsyncValidatorInterface): void {
|
public excludeFieldSaveValidator(module: string, type: string, field: string): void {
|
||||||
this.asyncSaveValidators.addEntry(module, key, validator);
|
|
||||||
|
const moduleExclusions = this.saveFieldExclusions[module] || {};
|
||||||
|
const key = this.getKey(type, field);
|
||||||
|
moduleExclusions[key] = key;
|
||||||
|
this.saveFieldExclusions[module] = moduleExclusions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public excludeAsyncSaveValidator(module: string, key: string): void {
|
public excludeSaveValidator(module: string, type: string): void {
|
||||||
this.saveValidators.excludeEntry(module, key);
|
this.saveValidators.excludeEntry(module, this.getKey(type, 'all'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public excludeFieldFilterValidator(module: string, type: string, field: string): void {
|
||||||
|
const moduleExclusions = this.filterFieldExclusion[module] || {};
|
||||||
|
const key = this.getKey(type, field);
|
||||||
|
moduleExclusions[key] = key;
|
||||||
|
this.filterFieldExclusion[module] = moduleExclusions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public excludeFilterValidator(module: string, type: string): void {
|
||||||
|
this.filterValidators.excludeEntry(module, this.getKey(type, 'all'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public registerAsyncSaveValidator(module: string, type: string, validator: AsyncValidatorInterface): void {
|
||||||
|
this.asyncSaveValidators.addEntry(module, this.getKey(type, 'all'), validator);
|
||||||
|
}
|
||||||
|
|
||||||
|
public excludeAsyncSaveValidator(module: string, type: string): void {
|
||||||
|
this.saveValidators.excludeEntry(module, this.getKey(type, 'all'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public getSaveValidations(module: string, viewField: ViewFieldDefinition, record: Record): ValidatorFn[] {
|
public getSaveValidations(module: string, viewField: ViewFieldDefinition, record: Record): ValidatorFn[] {
|
||||||
const entries = this.saveValidators.getGroupEntries(module);
|
const entries = this.saveValidators.getGroupEntries(module);
|
||||||
return this.filterValidations(entries, record, viewField);
|
const exclusions = this.getExclusions(module, this.saveFieldExclusions);
|
||||||
|
return this.filterValidations(entries, exclusions, record, viewField);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getFilterValidations(module: string, viewField: ViewFieldDefinition, record: Record): ValidatorFn[] {
|
public getFilterValidations(module: string, viewField: ViewFieldDefinition, record: Record): ValidatorFn[] {
|
||||||
const entries = this.filterValidators.getGroupEntries(module);
|
const entries = this.filterValidators.getGroupEntries(module);
|
||||||
return this.filterValidations(entries, record, viewField);
|
const exclusions = this.getExclusions(module, this.filterFieldExclusion);
|
||||||
|
return this.filterValidations(entries, exclusions, record, viewField);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getAsyncSaveValidations(module: string, viewField: ViewFieldDefinition, record: Record): AsyncValidatorFn[] {
|
public getAsyncSaveValidations(module: string, viewField: ViewFieldDefinition, record: Record): AsyncValidatorFn[] {
|
||||||
|
@ -154,10 +183,34 @@ export class ValidationManager implements ValidationManagerInterface {
|
||||||
return validations;
|
return validations;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected filterValidations(entries: MapEntry<ValidatorInterface>, record: Record, viewField: ViewFieldDefinition): ValidatorFn[] {
|
public getKey(type: string, field: string): string {
|
||||||
|
return `${type}.${field}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected parseType(key: string): string {
|
||||||
|
const partsType = key.split('.') || [];
|
||||||
|
return partsType[0] || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getExclusions(module: string, exclusionMap: StringMatrix): StringMap {
|
||||||
|
const defaultExclusions = exclusionMap['default'] || {};
|
||||||
|
const moduleExclusions = exclusionMap[module] || {};
|
||||||
|
return {...defaultExclusions, ...moduleExclusions};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected filterValidations(
|
||||||
|
entries: MapEntry<ValidatorInterface>,
|
||||||
|
fieldExclusions: StringMap,
|
||||||
|
record: Record,
|
||||||
|
viewField: ViewFieldDefinition
|
||||||
|
): ValidatorFn[] {
|
||||||
let validations = [];
|
let validations = [];
|
||||||
|
|
||||||
Object.keys(entries).forEach(validatorKey => {
|
Object.keys(entries).forEach(validatorKey => {
|
||||||
|
const defaultTypeKey = this.getKey(this.parseType(validatorKey), viewField.name);
|
||||||
|
if (fieldExclusions[validatorKey] || fieldExclusions[defaultTypeKey]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const validator = entries[validatorKey];
|
const validator = entries[validatorKey];
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue