Dataset Wizard. Table Of Contents entries show error state (not visible yet, only implementation). Fix Bug on DMP Editor: "Save & Add" doesn't validate datasets to proceed anymore.
This commit is contained in:
parent
6f52f77459
commit
97db10be12
|
@ -54,7 +54,7 @@
|
||||||
<div (click)="changeStep(0)" *ngIf="datasetInfoValid()" class="main-info" [ngClass]="{'active': this.step === 0}">0. {{'DMP-EDITOR.STEPPER.MAIN-INFO' | translate}} (<mat-icon class="done-icon">done</mat-icon>)</div>
|
<div (click)="changeStep(0)" *ngIf="datasetInfoValid()" class="main-info" [ngClass]="{'active': this.step === 0}">0. {{'DMP-EDITOR.STEPPER.MAIN-INFO' | translate}} (<mat-icon class="done-icon">done</mat-icon>)</div>
|
||||||
<div class="row toc-pane-container" #boundary (click)="changeStep(1)">
|
<div class="row toc-pane-container" #boundary (click)="changeStep(1)">
|
||||||
<div #spacer></div>
|
<div #spacer></div>
|
||||||
<table-of-contents [TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX" [hasFocus]="step === 1" [formGroup]="formGroup" *ngIf="formGroup && formGroup.get('datasetProfileDefinition')" [links]="links" [boundary]="boundary" [spacer]="spacer" [isActive]="step !== 0" stickyThing (stepFound)="onStepFound($event)" (currentLinks)="getLinks($event)" [visibilityRules]="formGroup.get('datasetProfileDefinition').get('rules').value"></table-of-contents>
|
<table-of-contents [showErrors]="showtocentriesErrors" [TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX" [hasFocus]="step === 1" [formGroup]="formGroup" *ngIf="formGroup && formGroup.get('datasetProfileDefinition')" [links]="links" [boundary]="boundary" [spacer]="spacer" [isActive]="step !== 0" stickyThing (stepFound)="onStepFound($event)" (currentLinks)="getLinks($event)" [visibilityRules]="formGroup.get('datasetProfileDefinition').get('rules').value"></table-of-contents>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -88,6 +88,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- <mat-slide-toggle [(ngModel)]="showtocentriesErrors">
|
||||||
|
|
||||||
|
</mat-slide-toggle> -->
|
||||||
|
|
||||||
<!-- <div class="row">
|
<!-- <div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
|
|
@ -92,6 +92,7 @@ export class DatasetWizardComponent extends BaseComponent implements OnInit, IBr
|
||||||
links: Link[] = [];
|
links: Link[] = [];
|
||||||
//the table seraches for elements to scroll on page with id (TOCENTRY_ID_PREFIX+fieldsetId<Tocentry>)
|
//the table seraches for elements to scroll on page with id (TOCENTRY_ID_PREFIX+fieldsetId<Tocentry>)
|
||||||
TOCENTRY_ID_PREFIX="TocEntRy";
|
TOCENTRY_ID_PREFIX="TocEntRy";
|
||||||
|
showtocentriesErrors = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private datasetWizardService: DatasetWizardService,
|
private datasetWizardService: DatasetWizardService,
|
||||||
|
@ -615,7 +616,7 @@ export class DatasetWizardComponent extends BaseComponent implements OnInit, IBr
|
||||||
|
|
||||||
if(aControl.invalid){
|
if(aControl.invalid){
|
||||||
|
|
||||||
if(aControl.errors){//although here should always be true
|
if(aControl.errors){
|
||||||
//check if has placeholder
|
//check if has placeholder
|
||||||
if( (<any>aControl).nativeElement !== undefined && (<any>aControl).nativeElement !== null){
|
if( (<any>aControl).nativeElement !== undefined && (<any>aControl).nativeElement !== null){
|
||||||
controlName = this._getPlaceHolder(aControl);
|
controlName = this._getPlaceHolder(aControl);
|
||||||
|
@ -625,6 +626,9 @@ export class DatasetWizardComponent extends BaseComponent implements OnInit, IBr
|
||||||
errmess.push(...errorMessage);
|
errmess.push(...errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*in case the aControl is FormControl then the it should have provided its error messages above.
|
||||||
|
No need to check case of FormControl below*/
|
||||||
|
|
||||||
if(aControl instanceof FormGroup){
|
if(aControl instanceof FormGroup){
|
||||||
|
|
||||||
const fg = aControl as FormGroup;
|
const fg = aControl as FormGroup;
|
||||||
|
|
|
@ -429,16 +429,31 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
|
||||||
return this.formGroup.get('datasets')['controls'][0].valid;
|
return this.formGroup.get('datasets')['controls'][0].valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private showValidationErrorsDialog(projectOnly?: boolean) {
|
private showValidationErrorsDialog(projectOnly?: boolean, errmess?: string[]) {
|
||||||
const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, {
|
|
||||||
disableClose: true,
|
if(errmess){
|
||||||
autoFocus: false,
|
|
||||||
restoreFocus: false,
|
const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, {
|
||||||
data: {
|
disableClose: true,
|
||||||
formGroup: this.formGroup,
|
autoFocus: false,
|
||||||
projectOnly: projectOnly
|
restoreFocus: false,
|
||||||
},
|
data: {
|
||||||
});
|
errorMessages:errmess,
|
||||||
|
projectOnly: projectOnly
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, {
|
||||||
|
disableClose: true,
|
||||||
|
autoFocus: false,
|
||||||
|
restoreFocus: false,
|
||||||
|
data: {
|
||||||
|
formGroup: this.formGroup,
|
||||||
|
projectOnly: projectOnly
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit(addNew?: boolean, showAddDatasetDialog?: boolean): void {
|
onSubmit(addNew?: boolean, showAddDatasetDialog?: boolean): void {
|
||||||
|
@ -734,8 +749,124 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC
|
||||||
this.formSubmit(true);
|
this.formSubmit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//checks if the dpm is valid not taking into account the datasets validity
|
||||||
|
private _isDMPDescriptionValid():boolean{
|
||||||
|
|
||||||
|
const form: FormGroup = this.formGroup;
|
||||||
|
if(form.controls){
|
||||||
|
return Object.keys(form.controls)
|
||||||
|
.map(controlName=>{//get validity of each control
|
||||||
|
if(controlName === 'datasets'){//we dont care if datasets are valid
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !form.get(controlName).invalid;//!! in case the control is disabled, we consider it valid
|
||||||
|
})
|
||||||
|
.reduce((isFormValid,isControlValid)=>{//aggregate validities
|
||||||
|
return isControlValid && isFormValid;
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getErrorMessage(formControl: AbstractControl, name: string): string[] {
|
||||||
|
const errors: string[] = [];
|
||||||
|
Object.keys(formControl.errors).forEach(key => {
|
||||||
|
if (key === 'required') { errors.push(this.language.instant(name + ": " + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.REQUIRED'))); }
|
||||||
|
// if (key === 'required') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + this.getPlaceHolder(formControl) + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.REQUIRED')); }
|
||||||
|
else if (key === 'email') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.EMAIL')); }
|
||||||
|
else if (key === 'min') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.MIN-VALUE', { 'min': formControl.getError('min').min })); }
|
||||||
|
else if (key === 'max') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.MAX-VALUE', { 'max': formControl.getError('max').max })); }
|
||||||
|
else { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + formControl.errors[key].message); }
|
||||||
|
});
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getPlaceHolder(formControl: any): string {
|
||||||
|
if (formControl.nativeElement.localName === 'input' || formControl.nativeElement.localName === 'textarea') {
|
||||||
|
return formControl.nativeElement.getAttribute('placeholder');
|
||||||
|
} else if (formControl.nativeElement.localName === 'mat-select') {
|
||||||
|
return formControl.nativeElement.getAttribute('aria-label');
|
||||||
|
} else if (formControl.nativeElement.localName === 'app-single-auto-complete') {
|
||||||
|
return (Array.from(formControl.nativeElement.firstChild.children).filter((x: any) => x.localName === 'input')[0] as any).getAttribute('placeholder');
|
||||||
|
} else if (formControl.nativeElement.localName === 'app-multiple-auto-complete') {
|
||||||
|
return (Array.from(formControl.nativeElement.firstChild.children).filter((x: any) => x.localName === 'input')[0] as any).getAttribute('placeholder');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private _buildDMPDescriptionErrorMessages(): string[]{//not including datasets
|
||||||
|
const errmess: string[] = [];
|
||||||
|
Object.keys(this.formGroup.controls).forEach(controlName=>{
|
||||||
|
if(controlName != 'datasets' && this.formGroup.get(controlName).invalid){
|
||||||
|
errmess.push(...this._buildErrorMessagesForAbstractControl(this.formGroup.get(controlName), controlName));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return errmess;
|
||||||
|
}
|
||||||
|
|
||||||
|
// takes as an input an abstract control and gets its error messages[]
|
||||||
|
private _buildErrorMessagesForAbstractControl(aControl: AbstractControl, controlName: string):string[]{
|
||||||
|
const errmess:string[] = [];
|
||||||
|
|
||||||
|
if(aControl.invalid){
|
||||||
|
|
||||||
|
if(aControl.errors){
|
||||||
|
//check if has placeholder
|
||||||
|
if( (<any>aControl).nativeElement !== undefined && (<any>aControl).nativeElement !== null){
|
||||||
|
controlName = this._getPlaceHolder(aControl);
|
||||||
|
}
|
||||||
|
const errorMessage = this._getErrorMessage(aControl, controlName);
|
||||||
|
|
||||||
|
errmess.push(...errorMessage);
|
||||||
|
}
|
||||||
|
/*in case the aControl is FormControl then the it should have provided its error messages above.
|
||||||
|
No need to check case of FormControl below*/
|
||||||
|
|
||||||
|
if(aControl instanceof FormGroup){
|
||||||
|
|
||||||
|
const fg = aControl as FormGroup;
|
||||||
|
//check children
|
||||||
|
Object.keys(fg.controls).forEach(controlName=>{
|
||||||
|
errmess.push(...this._buildErrorMessagesForAbstractControl(fg.get(controlName), controlName));
|
||||||
|
});
|
||||||
|
}else if(aControl instanceof FormArray){
|
||||||
|
|
||||||
|
const fa = aControl as FormArray;
|
||||||
|
|
||||||
|
fa.controls.forEach((control,index)=>{
|
||||||
|
errmess.push(... this._buildErrorMessagesForAbstractControl(control, `${controlName} --> ${index+1}`));
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return errmess;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
addDataset() {
|
addDataset() {
|
||||||
this.formSubmit(true, false);
|
|
||||||
|
|
||||||
|
if(!this._isDMPDescriptionValid()){
|
||||||
|
const errmess = this._buildDMPDescriptionErrorMessages();
|
||||||
|
this.showValidationErrorsDialog(undefined, errmess);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this.onSubmit(true, false);
|
||||||
|
// this.formSubmit(true, false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Add dataset to list
|
// Add dataset to list
|
||||||
// if (!this.formGroup.get('datasets')) {
|
// if (!this.formGroup.get('datasets')) {
|
||||||
// this.formGroup.addControl('datasets', new FormBuilder().array(new Array<FormControl>()));
|
// this.formGroup.addControl('datasets', new FormBuilder().array(new Array<FormControl>()));
|
||||||
|
|
|
@ -10,9 +10,13 @@
|
||||||
[ngStyle]="calculateStyle(entry)"
|
[ngStyle]="calculateStyle(entry)"
|
||||||
[ngClass]="calculateClass(entry)"
|
[ngClass]="calculateClass(entry)"
|
||||||
>
|
>
|
||||||
<span>
|
<span [class.text-danger]="showErrors && entry.form.invalid && entry.type === tocEntryTypeEnum.FieldSet">
|
||||||
{{entry.numbering}}. {{entry.label}}
|
{{entry.numbering}}. {{entry.label}}
|
||||||
</span>
|
</span>
|
||||||
|
<mat-icon style="transform: translateY(3px);" class="text-danger"
|
||||||
|
*ngIf="showErrors && entry.form.invalid && entry.type !== tocEntryTypeEnum.FieldSet && !expandChildren[idx]">
|
||||||
|
priority_high
|
||||||
|
</mat-icon>
|
||||||
<!-- <ng-container *ngIf="entry.subEntries && entry.subEntries.length && !expandChildren[idx]">
|
<!-- <ng-container *ngIf="entry.subEntries && entry.subEntries.length && !expandChildren[idx]">
|
||||||
<small>
|
<small>
|
||||||
({{entry.subEntries.length}})
|
({{entry.subEntries.length}})
|
||||||
|
@ -28,7 +32,8 @@
|
||||||
*ngIf="entry.subEntries && entry.subEntries.length && expandChildren[idx]"
|
*ngIf="entry.subEntries && entry.subEntries.length && expandChildren[idx]"
|
||||||
(entrySelected)="onEntrySelected($event)"
|
(entrySelected)="onEntrySelected($event)"
|
||||||
[selected]="selected"
|
[selected]="selected"
|
||||||
[TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX">
|
[TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX"
|
||||||
|
[showErrors]="showErrors">
|
||||||
|
|
||||||
</table-of-contents-internal>
|
</table-of-contents-internal>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
.internal-table{
|
.internal-table{
|
||||||
margin-left: 1em;
|
margin-left: 1em;
|
||||||
padding-left: 0.2rem;
|
padding-left: 0.2rem;
|
||||||
|
|
||||||
}
|
}
|
||||||
.table-entry{
|
.table-entry{
|
||||||
|
|
||||||
|
@ -26,3 +27,7 @@
|
||||||
font-weight: 700 !important;
|
font-weight: 700 !important;
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.section{
|
||||||
|
line-height: 1.7em;
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ export class TableOfContentsInternal implements OnInit {
|
||||||
expandChildren:boolean[];
|
expandChildren:boolean[];
|
||||||
tocEntryTypeEnum = ToCEntryType;
|
tocEntryTypeEnum = ToCEntryType;
|
||||||
@Input() TOCENTRY_ID_PREFIX="";
|
@Input() TOCENTRY_ID_PREFIX="";
|
||||||
|
@Input() showErrors: boolean = false;
|
||||||
|
|
||||||
|
|
||||||
constructor(public visibilityRulesService: VisibilityRulesService){
|
constructor(public visibilityRulesService: VisibilityRulesService){
|
||||||
|
@ -84,11 +85,16 @@ export class TableOfContentsInternal implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateClass(entry:ToCEntry){
|
calculateClass(entry:ToCEntry){
|
||||||
|
const myClass= {};
|
||||||
|
|
||||||
if(this.selected && entry.id === this.selected.id){
|
if(this.selected && entry.id === this.selected.id){
|
||||||
return{'selected': true};
|
myClass['selected'] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
if(entry.type != this.tocEntryTypeEnum.FieldSet){
|
||||||
|
myClass['section'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return myClass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
<div class="scroll-container col-12 internal-table">
|
<div class="scroll-container col-12 internal-table">
|
||||||
<table-of-contents-internal [TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX" [tocentries]="tocentries"
|
<table-of-contents-internal [TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX" [tocentries]="tocentries"
|
||||||
|
[showErrors]="showErrors"
|
||||||
(entrySelected)="onToCentrySelected($event)"
|
(entrySelected)="onToCentrySelected($event)"
|
||||||
[selected]="tocentrySelected"
|
[selected]="tocentrySelected"
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,10 @@ import {TableOfContents} from './table-of-contents';
|
||||||
import {RouterModule} from '@angular/router';
|
import {RouterModule} from '@angular/router';
|
||||||
import { TableOfContentsInternal } from './table-of-contents-internal/table-of-contents-internal';
|
import { TableOfContentsInternal } from './table-of-contents-internal/table-of-contents-internal';
|
||||||
import { VisibilityRulesService } from '../visibility-rules/visibility-rules.service';
|
import { VisibilityRulesService } from '../visibility-rules/visibility-rules.service';
|
||||||
|
import { MatIconModule } from '@angular/material';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [CommonModule, RouterModule],
|
imports: [CommonModule, RouterModule, MatIconModule],
|
||||||
declarations: [TableOfContents, TableOfContentsInternal],
|
declarations: [TableOfContents, TableOfContentsInternal],
|
||||||
exports: [TableOfContents],
|
exports: [TableOfContents],
|
||||||
entryComponents: [TableOfContents],
|
entryComponents: [TableOfContents],
|
||||||
|
|
|
@ -48,6 +48,7 @@ export class TableOfContents extends BaseComponent implements OnInit {
|
||||||
@Input() TOCENTRY_ID_PREFIX = '';
|
@Input() TOCENTRY_ID_PREFIX = '';
|
||||||
// visibilityRules:Rule[] = [];
|
// visibilityRules:Rule[] = [];
|
||||||
@Input() visibilityRules:Rule[] = [];
|
@Input() visibilityRules:Rule[] = [];
|
||||||
|
@Input() showErrors: boolean = false;
|
||||||
|
|
||||||
private _tocentrySelected:ToCEntry = null;
|
private _tocentrySelected:ToCEntry = null;
|
||||||
get tocentrySelected(){
|
get tocentrySelected(){
|
||||||
|
|
Loading…
Reference in New Issue