rule target cannot be same field or fieldset
This commit is contained in:
parent
cc877d8e53
commit
ea46c6af80
|
@ -120,7 +120,8 @@ public class FieldPersist {
|
||||||
|
|
||||||
private final ValidatorFactory validatorFactory;
|
private final ValidatorFactory validatorFactory;
|
||||||
private final FieldDataHelperServiceProvider fieldDataHelperServiceProvider;
|
private final FieldDataHelperServiceProvider fieldDataHelperServiceProvider;
|
||||||
|
private String fieldSetId;
|
||||||
|
|
||||||
protected FieldPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory, FieldDataHelperServiceProvider fieldDataHelperServiceProvider) {
|
protected FieldPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory, FieldDataHelperServiceProvider fieldDataHelperServiceProvider) {
|
||||||
super(conventionService, errors);
|
super(conventionService, errors);
|
||||||
this.messageSource = messageSource;
|
this.messageSource = messageSource;
|
||||||
|
@ -128,6 +129,11 @@ public class FieldPersist {
|
||||||
this.fieldDataHelperServiceProvider = fieldDataHelperServiceProvider;
|
this.fieldDataHelperServiceProvider = fieldDataHelperServiceProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FieldPersistValidator withFieldSetId(String fieldSetId) {
|
||||||
|
this.fieldSetId = fieldSetId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<FieldPersist> modelClass() {
|
protected Class<FieldPersist> modelClass() {
|
||||||
return FieldPersist.class;
|
return FieldPersist.class;
|
||||||
|
@ -150,7 +156,7 @@ public class FieldPersist {
|
||||||
.iff(() -> !this.isListNullOrEmpty(item.getVisibilityRules()))
|
.iff(() -> !this.isListNullOrEmpty(item.getVisibilityRules()))
|
||||||
.on(FieldPersist._visibilityRules)
|
.on(FieldPersist._visibilityRules)
|
||||||
.over(item.getVisibilityRules())
|
.over(item.getVisibilityRules())
|
||||||
.using((itm) -> this.validatorFactory.validator(RulePersist.RulePersistValidator.class).withFieldPersist(item)),
|
.using((itm) -> this.validatorFactory.validator(RulePersist.RulePersistValidator.class).withFieldPersist(item).withFieldSetId(fieldSetId)),
|
||||||
this.refSpec()
|
this.refSpec()
|
||||||
.iff(() -> !this.isNull(item.getDefaultValue()))
|
.iff(() -> !this.isNull(item.getDefaultValue()))
|
||||||
.on(FieldPersist._defaultValue)
|
.on(FieldPersist._defaultValue)
|
||||||
|
|
|
@ -176,7 +176,7 @@ public class FieldSetPersist {
|
||||||
.iff(() -> !this.isListNullOrEmpty(item.getFields()))
|
.iff(() -> !this.isListNullOrEmpty(item.getFields()))
|
||||||
.on(FieldSetPersist._fields)
|
.on(FieldSetPersist._fields)
|
||||||
.over(item.getFields())
|
.over(item.getFields())
|
||||||
.using((itm) -> this.validatorFactory.validator(FieldPersist.FieldPersistValidator.class))
|
.using((itm) -> this.validatorFactory.validator(FieldPersist.FieldPersistValidator.class).withFieldSetId(item.getId()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,7 @@ public class RulePersist {
|
||||||
private final MessageSource messageSource;
|
private final MessageSource messageSource;
|
||||||
private final ValidatorFactory validatorFactory;
|
private final ValidatorFactory validatorFactory;
|
||||||
private org.opencdmp.model.persist.descriptiontemplatedefinition.FieldPersist fieldEntity;
|
private org.opencdmp.model.persist.descriptiontemplatedefinition.FieldPersist fieldEntity;
|
||||||
|
private String fieldSetId;
|
||||||
|
|
||||||
protected RulePersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) {
|
protected RulePersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) {
|
||||||
super(conventionService, errors);
|
super(conventionService, errors);
|
||||||
|
@ -96,6 +97,11 @@ public class RulePersist {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RulePersistValidator withFieldSetId(String fieldSetId) {
|
||||||
|
this.fieldSetId = fieldSetId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<RulePersist> modelClass() {
|
protected Class<RulePersist> modelClass() {
|
||||||
return RulePersist.class;
|
return RulePersist.class;
|
||||||
|
@ -108,6 +114,10 @@ public class RulePersist {
|
||||||
this.spec()
|
this.spec()
|
||||||
.must(() -> !this.isEmpty(item.getTarget()))
|
.must(() -> !this.isEmpty(item.getTarget()))
|
||||||
.failOn(RulePersist._target).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{RulePersist._target}, LocaleContextHolder.getLocale())),
|
.failOn(RulePersist._target).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{RulePersist._target}, LocaleContextHolder.getLocale())),
|
||||||
|
this.spec()
|
||||||
|
.iff(() -> !this.isEmpty(item.getTarget()))
|
||||||
|
.must(() -> !item.getTarget().equals(this.fieldEntity.getId()) && !item.getTarget().equals(this.fieldSetId))
|
||||||
|
.failOn(RulePersist._target).failWith(this.messageSource.getMessage("Validation_UnexpectedValue", new Object[]{RulePersist._target}, LocaleContextHolder.getLocale())),
|
||||||
this.spec()
|
this.spec()
|
||||||
.iff(() -> this.isNull(fieldType))
|
.iff(() -> this.isNull(fieldType))
|
||||||
.must(() -> !FieldType.TAGS.equals(fieldType) && !FieldType.INTERNAL_ENTRIES_DESCRIPTIONS.equals(fieldType) && !FieldType.INTERNAL_ENTRIES_PLANS.equals(fieldType) &&
|
.must(() -> !FieldType.TAGS.equals(fieldType) && !FieldType.INTERNAL_ENTRIES_DESCRIPTIONS.equals(fieldType) && !FieldType.INTERNAL_ENTRIES_PLANS.equals(fieldType) &&
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
<!-- FIELDS -->
|
<!-- FIELDS -->
|
||||||
<div #inputs transition-group class="col-12" *ngIf="hasFocus" [@fade-in]>
|
<div #inputs transition-group class="col-12" *ngIf="hasFocus" [@fade-in]>
|
||||||
<div *ngFor="let field of fieldsArray.controls; let i=index;" class="row bg-white field-input mt-3" (click)="setTargetField(field)" transition-group-item>
|
<div *ngFor="let field of fieldsArray.controls; let i=index;" class="row bg-white field-input mt-3" (click)="setTargetField(field)" transition-group-item>
|
||||||
<app-description-template-editor-field-component class="col-12" [form]="field" [showOrdinal]="false" [viewOnly]="viewOnly" [expandView]="hasFocus" [canBeDeleted]="fieldsArray.length !=1" [validationErrorModel]="validationErrorModel" [validationRootPath]="validationRootPath + '.fields[' + i + '].'" (delete)="deleteField(i)">
|
<app-description-template-editor-field-component class="col-12" [form]="field" [showOrdinal]="false" [viewOnly]="viewOnly" [expandView]="hasFocus" [canBeDeleted]="fieldsArray.length !=1" [validationErrorModel]="validationErrorModel" [validationRootPath]="validationRootPath + '.fields[' + i + '].'" [fieldSetId]="form.get('id').value" (delete)="deleteField(i)">
|
||||||
<div class="arrows mt-2">
|
<div class="arrows mt-2">
|
||||||
<ul class="list-unstyled list-inline d-flex align-items-center">
|
<ul class="list-unstyled list-inline d-flex align-items-center">
|
||||||
<li *ngIf="canGoUp(i)" class="text-muted">
|
<li *ngIf="canGoUp(i)" class="text-muted">
|
||||||
|
|
|
@ -155,7 +155,7 @@
|
||||||
<ng-container *ngIf="form.get('visibilityRules')?.value.length">
|
<ng-container *ngIf="form.get('visibilityRules')?.value.length">
|
||||||
<h4 class="col-12" style="font-weight: bold">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.RULES-TITLE' | translate}}
|
<h4 class="col-12" style="font-weight: bold">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.RULES-TITLE' | translate}}
|
||||||
</h4>
|
</h4>
|
||||||
<app-description-template-editor-visibility-rule-component class="col-12" [form]="form.get('visibilityRules')" [validationErrorModel]="validationErrorModel" [validationRootPath]="validationRootPath" [fieldTypeForCheck]="form.get('data').get('fieldType').value" [formArrayOptionsForCheck]="this.form.get('data')?.get('options')" [viewOnly]="viewOnly"></app-description-template-editor-visibility-rule-component>
|
<app-description-template-editor-visibility-rule-component class="col-12" [form]="form.get('visibilityRules')" [validationErrorModel]="validationErrorModel" [validationRootPath]="validationRootPath" [fieldId]="form.get('id').value" [fieldTypeForCheck]="form.get('data').get('fieldType').value" [formArrayOptionsForCheck]="this.form.get('data')?.get('options')" [fieldSetId]="fieldSetId" [viewOnly]="viewOnly"></app-description-template-editor-visibility-rule-component>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" [ngSwitch]="form.get('data')?.get('fieldType')?.value">
|
<div class="row" [ngSwitch]="form.get('data')?.get('fieldType')?.value">
|
||||||
|
|
|
@ -35,6 +35,7 @@ export class DescriptionTemplateEditorFieldComponent extends BaseComponent imple
|
||||||
@Output() delete = new EventEmitter<void>();
|
@Output() delete = new EventEmitter<void>();
|
||||||
@Input() validationErrorModel: ValidationErrorModel;
|
@Input() validationErrorModel: ValidationErrorModel;
|
||||||
@Input() validationRootPath: string;
|
@Input() validationRootPath: string;
|
||||||
|
@Input() fieldSetId: string;
|
||||||
|
|
||||||
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
|
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<mat-select formControlName="target" (openedChange)="computeOptions($event)">
|
<mat-select formControlName="target" (openedChange)="computeOptions($event)">
|
||||||
<!-- SHOW FIELDSETS -->
|
<!-- SHOW FIELDSETS -->
|
||||||
<mat-optgroup [label]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.RULE.FIELDS.FIELDSETS' | translate">
|
<mat-optgroup [label]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.RULE.FIELDS.FIELDSETS' | translate">
|
||||||
<mat-option *ngFor="let option of fieldSetOptions" [value]="option.id" style="line-height: normal;" [disabled]="parentIds.includes(option.id) || hiddenBy.includes(option.id)" [matTooltip]="getToolTipMessage(option.id)" [matTooltipShowDelay]="700">
|
<mat-option *ngFor="let option of fieldSetOptions" [value]="option.id" style="line-height: normal;" [disabled]="parentIds.includes(option.id) || hiddenBy.includes(option.id) || option.id == fieldSetId" [matTooltip]="getToolTipMessage(option.id)" [matTooltipShowDelay]="700">
|
||||||
<div class="row mt-2 mb-2">
|
<div class="row mt-2 mb-2">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<span class="title-text">
|
<span class="title-text">
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
</mat-optgroup>
|
</mat-optgroup>
|
||||||
<!-- SHOW FIELDS -->
|
<!-- SHOW FIELDS -->
|
||||||
<mat-optgroup [label]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.RULE.FIELDS.FIELDS' | translate">
|
<mat-optgroup [label]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.RULE.FIELDS.FIELDS' | translate">
|
||||||
<mat-option *ngFor="let option of fieldOptions" [value]="option.id" style="line-height: normal;" [disabled]="parentIds.includes(option.id) ||hiddenBy.includes(option.id)" [matTooltip]="getToolTipMessage(option.id)" [matTooltipShowDelay]="700">
|
<mat-option *ngFor="let option of fieldOptions" [value]="option.id" style="line-height: normal;" [disabled]="parentIds.includes(option.id) ||hiddenBy.includes(option.id) || option.id == fieldId" [matTooltip]="getToolTipMessage(option.id)" [matTooltipShowDelay]="700">
|
||||||
<div class="row mt-2 mb-2">
|
<div class="row mt-2 mb-2">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<span class="title-text">
|
<span class="title-text">
|
||||||
|
|
|
@ -23,6 +23,8 @@ export class DescriptionTemplateEditorRuleComponent implements OnInit {
|
||||||
@Input() viewOnly: boolean;
|
@Input() viewOnly: boolean;
|
||||||
@Input() validationErrorModel: ValidationErrorModel;
|
@Input() validationErrorModel: ValidationErrorModel;
|
||||||
@Input() validationRootPath: string;
|
@Input() validationRootPath: string;
|
||||||
|
@Input() fieldId: string = null;
|
||||||
|
@Input() fieldSetId: string = null;
|
||||||
|
|
||||||
|
|
||||||
options: OptionItem[];
|
options: OptionItem[];
|
||||||
|
@ -83,6 +85,11 @@ export class DescriptionTemplateEditorRuleComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.form.controls?.forEach(
|
||||||
|
(control, index) => {
|
||||||
|
if (control.get('target').value == this.fieldId || control.get('target').value == this.fieldSetId) control.get('target').setValue(null);
|
||||||
|
}
|
||||||
|
);
|
||||||
this.rootForm = this.findRootForm();
|
this.rootForm = this.findRootForm();
|
||||||
this._computeOptions();
|
this._computeOptions();
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,6 +256,9 @@ export class VisibilityRulesService {
|
||||||
|
|
||||||
for (let i = 0; i < rulesForParentKey.length; i++) {
|
for (let i = 0; i < rulesForParentKey.length; i++) {
|
||||||
const ruleForParentKey = rulesForParentKey[i];
|
const ruleForParentKey = rulesForParentKey[i];
|
||||||
|
|
||||||
|
if (ruleForParentKey.source == ruleForParentKey.target) continue; //Invalid rule where source and target are equal
|
||||||
|
|
||||||
const field: DescriptionFieldPersist = fieldsMap.get(ruleForParentKey.source);
|
const field: DescriptionFieldPersist = fieldsMap.get(ruleForParentKey.source);
|
||||||
|
|
||||||
const rulesForGrandParentKey: RuleWithTarget[] = this.getChainParentRules(ruleForParentKey);
|
const rulesForGrandParentKey: RuleWithTarget[] = this.getChainParentRules(ruleForParentKey);
|
||||||
|
|
Loading…
Reference in New Issue