Improve validation

urls
Max Ehrlicher-Schmidt 4 years ago
parent 98817feb64
commit 47086c3c35

@ -18,7 +18,7 @@
<app-cell <app-cell
*ngIf="prop.type !== 'NumRange'" *ngIf="prop.type !== 'NumRange'"
[editable]="data.isLockedByMe && prop.acceptedForUpdating" [editable]="data.isLockedByMe && prop.acceptedForUpdating"
[required]="prop.requiredForUpdating" [required]="prop.required && data.isLockedByMe"
(validityChange)="validityChange(prop.dataPath, $event)" (validityChange)="validityChange(prop.dataPath, $event)"
[(value)]="data[prop.dataPath]" [(value)]="data[prop.dataPath]"
[label]="prop.translation || prop.dataPath" [label]="prop.translation || prop.dataPath"

@ -15,7 +15,7 @@ interface PropertyTypeInfo {
dataPath: string; dataPath: string;
translation: string; translation: string;
acceptedForUpdating?: boolean; acceptedForUpdating?: boolean;
requiredForUpdating?: boolean; required?: boolean;
type?: string; type?: string;
} }
@ -121,6 +121,9 @@ export class DataPageComponent implements OnInit, OnDestroy {
prop.dataPath prop.dataPath
); );
prop.type = prop.type || typeInformation.type; prop.type = prop.type || typeInformation.type;
prop.required =
prop.required != null ? prop.required : typeInformation.isRequired;
const updateTypeInformation = this.schemaService.getTypeInformation( const updateTypeInformation = this.schemaService.getTypeInformation(
this.pageDataGQLUpdateInputType, this.pageDataGQLUpdateInputType,
prop.dataPath prop.dataPath
@ -129,10 +132,6 @@ export class DataPageComponent implements OnInit, OnDestroy {
prop.acceptedForUpdating != null prop.acceptedForUpdating != null
? prop.acceptedForUpdating ? prop.acceptedForUpdating
: updateTypeInformation.isPartOfType; : updateTypeInformation.isPartOfType;
prop.requiredForUpdating =
prop.requiredForUpdating != null
? prop.requiredForUpdating
: updateTypeInformation.isRequired;
} }
} }
} }
@ -141,8 +140,8 @@ export class DataPageComponent implements OnInit, OnDestroy {
this.lockEvent.emit(deepen(this.data)); this.lockEvent.emit(deepen(this.data));
} }
validityChange(columnName: string, isValid: Event) { validityChange(propName: string, isValid: Event) {
this.propertyValidity[columnName] = isValid; this.propertyValidity[propName] = isValid;
} }
countUnvalidProperties() { countUnvalidProperties() {

@ -131,8 +131,8 @@
(column.acceptedForUpdating && element.isLockedByMe) (column.acceptedForUpdating && element.isLockedByMe)
" "
[required]=" [required]="
(element.newObject && column.requiredForCreation) || (element.newObject && column.required) ||
(element.isLockedByMe && column.requiredForCreation) (element.isLockedByMe && column.required)
" "
(validityChange)=" (validityChange)="
validityChange(element, column.dataPath, $event) validityChange(element, column.dataPath, $event)
@ -159,8 +159,8 @@
(column.acceptedForUpdating && element.isLockedByMe) (column.acceptedForUpdating && element.isLockedByMe)
" "
[required]=" [required]="
(element.newObject && column.requiredForCreation) || (element.newObject && column.required) ||
(element.isLockedByMe && column.requiredForCreation) (element.isLockedByMe && column.required)
" "
(validityChange)=" (validityChange)="
validityChange(element, column.dataPath, $event) validityChange(element, column.dataPath, $event)

@ -36,10 +36,9 @@ export class TableComponent implements AfterViewInit {
dataPath: string; dataPath: string;
translation: string; translation: string;
acceptedForCreation?: boolean; acceptedForCreation?: boolean;
requiredForCreation?: boolean;
sticky?: boolean; sticky?: boolean;
acceptedForUpdating?: boolean; acceptedForUpdating?: boolean;
requiredForUpdating?: boolean; required?: boolean;
type?: string; type?: string;
link?: (row: any) => string; link?: (row: any) => string;
}[] = []; }[] = [];
@ -189,6 +188,8 @@ export class TableComponent implements AfterViewInit {
column.dataPath column.dataPath
); );
column.type = column.type || typeInformation.type; column.type = column.type || typeInformation.type;
column.required =
column.required != null ? column.required : typeInformation.isRequired;
} }
for (const column of this.columnInfo) { for (const column of this.columnInfo) {
const typeInformation = this.schemaService.getTypeInformation( const typeInformation = this.schemaService.getTypeInformation(
@ -199,20 +200,12 @@ export class TableComponent implements AfterViewInit {
column.acceptedForUpdating != null column.acceptedForUpdating != null
? column.acceptedForUpdating ? column.acceptedForUpdating
: typeInformation.isPartOfType; : typeInformation.isPartOfType;
column.requiredForUpdating =
column.requiredForUpdating != null
? column.requiredForUpdating
: typeInformation.isRequired;
} }
for (const column of this.columnInfo) { for (const column of this.columnInfo) {
const typeInformation = this.schemaService.getTypeInformation( const typeInformation = this.schemaService.getTypeInformation(
this.tableDataGQLCreateInputType, this.tableDataGQLCreateInputType,
column.dataPath column.dataPath
); );
column.requiredForCreation =
column.requiredForCreation != null
? column.requiredForCreation
: typeInformation.isRequired;
column.acceptedForCreation = column.acceptedForCreation =
column.acceptedForCreation != null column.acceptedForCreation != null
? column.acceptedForCreation ? column.acceptedForCreation

@ -23,21 +23,21 @@ export class CellComponent implements AfterViewInit {
setTimeout(() => { setTimeout(() => {
this.checkIfValid(); this.checkIfValid();
}); });
} // number | string | boolean | { start: string; end: string; }; }
get value(): any { get value(): any {
return this._value; return this._value;
} }
_value: any; _value: number | string | boolean;
rangeForm: FormGroup;
minValue: number;
maxValue: number;
@Output() valueChange = new EventEmitter< @Output() valueChange = new EventEmitter<number | string | boolean>();
number | string | boolean | { start: string; end: string }
>();
@Input() @Input()
editable = false; set editable(value: boolean) {
this._editable = value;
}
get editable(): boolean {
return this._editable;
}
_editable = false;
_inputType = 'text'; _inputType = 'text';
get inputType(): string { get inputType(): string {
return this._inputType; return this._inputType;
@ -48,7 +48,17 @@ export class CellComponent implements AfterViewInit {
this.getHtmlInputType(type); this.getHtmlInputType(type);
} }
@Input() @Input()
required = false; set required(value) {
this._required = value;
if (value) {
this.input?.control?.markAsTouched();
this.checkIfValid();
}
}
get required(): boolean {
return this._required;
}
_required = false;
@Input() @Input()
link: string = null; link: string = null;
@Input() @Input()
@ -73,13 +83,12 @@ export class CellComponent implements AfterViewInit {
this.cdr.detectChanges(); this.cdr.detectChanges();
if ( if (
this.value === undefined &&
this.inputType === 'Boolean' && this.inputType === 'Boolean' &&
this.editable this.editable
) { ) {
setTimeout(() => { setTimeout(() => {
this.change(false); this.change(false);
}, 0); });
} }
} }
} }
@ -98,21 +107,6 @@ export class CellComponent implements AfterViewInit {
this.htmlInputType = 'date'; this.htmlInputType = 'date';
} else if (type === 'DateRange') { } else if (type === 'DateRange') {
this.htmlInputType = 'dateRange'; this.htmlInputType = 'dateRange';
} else if (type === 'NumRange') {
this.htmlInputType = 'numberRange';
if (
!this.value ||
this.value.min === undefined ||
this.value.max === undefined
) {
this.value = { min: null, max: null };
}
this.rangeForm = new FormGroup({
minValue: new FormControl(),
maxValue: new FormControl(),
});
this.rangeForm.controls['minValue'].markAsTouched();
this.rangeForm.controls['maxValue'].markAsTouched();
} }
} }
@ -144,41 +138,6 @@ export class CellComponent implements AfterViewInit {
this.valueChange.emit(this.value); this.valueChange.emit(this.value);
} }
minValueChange(event) {
this.value.min = Math.abs(this.toNumber(event.target.value));
this.valueChange.emit(this.value);
this.checkIfRangeIsValid();
}
maxValueChange(event) {
this.value.max = Math.abs(this.toNumber(event.target.value));
this.valueChange.emit(this.value);
this.checkIfRangeIsValid();
}
checkIfRangeIsValid() {
if (this.value.min === null || this.value.max === null) {
this.setRangeError(false);
return;
}
if (this.value.min <= this.value.max) {
this.setRangeError(false);
return;
}
this.setRangeError(true);
}
setRangeError(error: boolean): void {
this.validityChange.emit(!error);
if (error) {
this.rangeForm.controls['minValue'].setErrors({ rangeError: true });
this.rangeForm.controls['maxValue'].setErrors({ rangeError: true });
} else {
this.rangeForm.controls['minValue'].setErrors(null);
this.rangeForm.controls['maxValue'].setErrors(null);
}
}
transformDate(date) { transformDate(date) {
return this.datepipe.transform(date, 'yyyy-MM-dd'); return this.datepipe.transform(date, 'yyyy-MM-dd');
} }
@ -189,11 +148,4 @@ export class CellComponent implements AfterViewInit {
this.validityChange.emit(this.isValid); this.validityChange.emit(this.isValid);
} }
} }
toNumber(str: string): number {
if (str === '') {
return null;
}
return +str;
}
} }

@ -1,5 +1,6 @@
{ {
"__schema": { "__schema": {
"description": null,
"queryType": { "queryType": {
"name": "Query" "name": "Query"
}, },

Loading…
Cancel
Save