@enigmatry/entry-components 1.14.7 → 1.14.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/header/entry-header.component.mjs +3 -3
- package/esm2020/validation/entry-display-control-validation.directive.mjs +11 -1
- package/esm2020/validation/entry-form-errors.component.mjs +19 -7
- package/esm2020/validation/entry-validation-config.model.mjs +1 -1
- package/esm2020/validation/entry-validation.mjs +4 -4
- package/esm2020/validation/validation-problem-details.interface.mjs +1 -1
- package/fesm2015/enigmatry-entry-components-header.mjs +2 -2
- package/fesm2015/enigmatry-entry-components-header.mjs.map +1 -1
- package/fesm2015/enigmatry-entry-components-validation.mjs +31 -9
- package/fesm2015/enigmatry-entry-components-validation.mjs.map +1 -1
- package/fesm2020/enigmatry-entry-components-header.mjs +2 -2
- package/fesm2020/enigmatry-entry-components-header.mjs.map +1 -1
- package/fesm2020/enigmatry-entry-components-validation.mjs +31 -9
- package/fesm2020/enigmatry-entry-components-validation.mjs.map +1 -1
- package/header/styles/modules/components/buttons/_general.scss +4 -4
- package/header/styles/modules/components/headers/_general.scss +2 -1
- package/header/styles/modules/theming/_default-theming.scss +1 -0
- package/header/styles/partials/core/components/buttons/_general.scss +5 -6
- package/header/styles/partials/core/components/headers/_general.scss +1 -17
- package/package.json +1 -1
- package/validation/README.md +59 -39
- package/validation/entry-display-control-validation.directive.d.ts +11 -0
- package/validation/entry-form-errors.component.d.ts +5 -4
- package/validation/entry-validation-config.model.d.ts +24 -3
- package/validation/entry-validation.d.ts +3 -3
- package/validation/validation-problem-details.interface.d.ts +1 -2
|
@@ -3,11 +3,11 @@ import * as i0 from "@angular/core";
|
|
|
3
3
|
export class EntryHeaderComponent {
|
|
4
4
|
}
|
|
5
5
|
EntryHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6
|
-
EntryHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: EntryHeaderComponent, selector: "entry-header", inputs: { title: "title" }, ngImport: i0, template: "<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"
|
|
6
|
+
EntryHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: EntryHeaderComponent, selector: "entry-header", inputs: { title: "title" }, ngImport: i0, template: "<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"title item\">{{title}}</h1>\n <ng-content select=\"[buttons]\"></ng-content>\n </div>\n <div class=\"row content\">\n <ng-content select=\"[content]\"></ng-content>\n </div>\n</header>", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7
7
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryHeaderComponent, decorators: [{
|
|
8
8
|
type: Component,
|
|
9
|
-
args: [{ selector: 'entry-header', changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"
|
|
9
|
+
args: [{ selector: 'entry-header', changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"title item\">{{title}}</h1>\n <ng-content select=\"[buttons]\"></ng-content>\n </div>\n <div class=\"row content\">\n <ng-content select=\"[content]\"></ng-content>\n </div>\n</header>" }]
|
|
10
10
|
}], propDecorators: { title: [{
|
|
11
11
|
type: Input
|
|
12
12
|
}] } });
|
|
13
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50cnktaGVhZGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvZW50cnktY29tcG9uZW50cy9oZWFkZXIvZW50cnktaGVhZGVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL2xpYnMvZW50cnktY29tcG9uZW50cy9oZWFkZXIvZW50cnktaGVhZGVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQVExRSxNQUFNLE9BQU8sb0JBQW9COztpSEFBcEIsb0JBQW9CO3FHQUFwQixvQkFBb0IsZ0ZDUmpDLHFSQVFTOzJGREFJLG9CQUFvQjtrQkFOaEMsU0FBUzsrQkFDRSxjQUFjLG1CQUdQLHVCQUF1QixDQUFDLE1BQU07OEJBR3RDLEtBQUs7c0JBQWIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2VudHJ5LWhlYWRlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9lbnRyeS1oZWFkZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9lbnRyeS1oZWFkZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgRW50cnlIZWFkZXJDb21wb25lbnQge1xuICBASW5wdXQoKSB0aXRsZTogc3RyaW5nO1xufVxuIiwiPGhlYWRlciBjbGFzcz1cImVudHJ5LWhlYWRlclwiPlxuICA8ZGl2IGNsYXNzPVwic3BhY2UtYmV0d2VlblwiPlxuICAgIDxoMSBjbGFzcz1cInRpdGxlIGl0ZW1cIj57e3RpdGxlfX08L2gxPlxuICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIltidXR0b25zXVwiPjwvbmctY29udGVudD5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJyb3cgY29udGVudFwiPlxuICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIltjb250ZW50XVwiPjwvbmctY29udGVudD5cbiAgPC9kaXY+XG48L2hlYWRlcj4iXX0=
|
|
@@ -3,6 +3,16 @@ import { ENTRY_VALIDATION_CONFIG } from './entry-validation-config.model';
|
|
|
3
3
|
import { FORM_FIELD_ERROR_KEY } from './entry-validation';
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
5
|
import * as i1 from "./entry-validation-config.model";
|
|
6
|
+
/**
|
|
7
|
+
* A directive that displays configured validation messages or server side validations for given form control.
|
|
8
|
+
* The messages are separated with coma(,) and displayed as _innerHTML_ value of host component.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```html
|
|
12
|
+
* <div entryDisplayControlValidation [control]="myForm.controls.firstName">
|
|
13
|
+
* </div
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
6
16
|
export class EntryDisplayControlValidationDirective {
|
|
7
17
|
constructor(_config, _element) {
|
|
8
18
|
this._config = _config;
|
|
@@ -50,4 +60,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
50
60
|
}] }, { type: i0.ElementRef }]; }, propDecorators: { control: [{
|
|
51
61
|
type: Input
|
|
52
62
|
}] } });
|
|
53
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
63
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50cnktZGlzcGxheS1jb250cm9sLXZhbGlkYXRpb24uZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy9lbnRyeS1jb21wb25lbnRzL3ZhbGlkYXRpb24vZW50cnktZGlzcGxheS1jb250cm9sLXZhbGlkYXRpb24uZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWMsTUFBTSxFQUFFLEtBQUssRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFDeEYsT0FBTyxFQUFFLHVCQUF1QixFQUF5QixNQUFNLGlDQUFpQyxDQUFDO0FBR2pHLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDOzs7QUFFMUQ7Ozs7Ozs7OztHQVNHO0FBSUgsTUFBTSxPQUFPLHNDQUFzQztJQU1qRCxZQUNvRCxPQUE4QixFQUMvRCxRQUFvQjtRQURhLFlBQU8sR0FBUCxPQUFPLENBQXVCO1FBQy9ELGFBQVEsR0FBUixRQUFRLENBQVk7SUFBRyxDQUFDO0lBRTNDLFFBQVE7UUFDTixJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhO2FBQ25ELFNBQVMsQ0FBQyxDQUFDLGFBQWdDLEVBQUUsRUFBRTtZQUM5QyxJQUFJLGFBQWEsS0FBSyxTQUFTLEVBQUU7Z0JBQy9CLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQzthQUMxRTtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRTtZQUM3QixJQUFJLENBQUMsb0JBQW9CLENBQUMsV0FBVyxFQUFFLENBQUM7U0FDekM7SUFDSCxDQUFDO0lBRU8seUJBQXlCO1FBQy9CLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRTtZQUN4QixPQUFPLEVBQUUsQ0FBQztTQUNYO1FBQ0QsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0I7YUFDakQsR0FBRyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUM7WUFDbkUsQ0FBQyxDQUFDLE9BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsS0FBSyxRQUFRO2dCQUM5QyxDQUFDLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztZQUN2RSxDQUFDLENBQUMsRUFBRSxDQUNMO2FBQ0EsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQzthQUNqQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFZCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQy9ELE1BQU0sa0JBQWtCLEdBQUcsWUFBWSxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRXhGLE9BQU8sQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdFLENBQUM7O21JQTFDVSxzQ0FBc0Msa0JBT3ZDLHVCQUF1Qjt1SEFQdEIsc0NBQXNDOzJGQUF0QyxzQ0FBc0M7a0JBSGxELFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGlDQUFpQztpQkFDNUM7OzBCQVFJLE1BQU07MkJBQUMsdUJBQXVCO3FFQUx4QixPQUFPO3NCQUFmLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIEluamVjdCwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBFTlRSWV9WQUxJREFUSU9OX0NPTkZJRywgRW50cnlWYWxpZGF0aW9uQ29uZmlnIH0gZnJvbSAnLi9lbnRyeS12YWxpZGF0aW9uLWNvbmZpZy5tb2RlbCc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIEZvcm1Db250cm9sU3RhdHVzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBGT1JNX0ZJRUxEX0VSUk9SX0tFWSB9IGZyb20gJy4vZW50cnktdmFsaWRhdGlvbic7XG5cbi8qKlxuICogQSBkaXJlY3RpdmUgdGhhdCBkaXNwbGF5cyBjb25maWd1cmVkIHZhbGlkYXRpb24gbWVzc2FnZXMgb3Igc2VydmVyIHNpZGUgdmFsaWRhdGlvbnMgZm9yIGdpdmVuIGZvcm0gY29udHJvbC5cbiAqIFRoZSBtZXNzYWdlcyBhcmUgc2VwYXJhdGVkIHdpdGggY29tYSgsKSBhbmQgZGlzcGxheWVkIGFzIF9pbm5lckhUTUxfIHZhbHVlIG9mIGhvc3QgY29tcG9uZW50LlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBodG1sXG4gKiA8ZGl2IGVudHJ5RGlzcGxheUNvbnRyb2xWYWxpZGF0aW9uIFtjb250cm9sXT1cIm15Rm9ybS5jb250cm9scy5maXJzdE5hbWVcIj5cbiAqIDwvZGl2XG4gKiBgYGBcbiAqL1xuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2VudHJ5RGlzcGxheUNvbnRyb2xWYWxpZGF0aW9uXSdcbn0pXG5leHBvcnQgY2xhc3MgRW50cnlEaXNwbGF5Q29udHJvbFZhbGlkYXRpb25EaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIC8qKiBGb3JtIGNvbnRyb2wgZm9yIHdoaWNoIHRoZSB2YWxpZGF0aW9uIG1lc3NhZ2VzIGFyZSBkaXNwbGF5ZWQgZm9yLiAqL1xuICBASW5wdXQoKSBjb250cm9sOiBBYnN0cmFjdENvbnRyb2w7XG5cbiAgcHJpdmF0ZSBfY29udHJvbFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uIHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoRU5UUllfVkFMSURBVElPTl9DT05GSUcpIHByaXZhdGUgcmVhZG9ubHkgX2NvbmZpZzogRW50cnlWYWxpZGF0aW9uQ29uZmlnLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2VsZW1lbnQ6IEVsZW1lbnRSZWYpIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5fY29udHJvbFN1YnNjcmlwdGlvbiA9IHRoaXMuY29udHJvbC5zdGF0dXNDaGFuZ2VzXG4gICAgICAuc3Vic2NyaWJlKChjb250cm9sU3RhdHVzOiBGb3JtQ29udHJvbFN0YXR1cykgPT4ge1xuICAgICAgICBpZiAoY29udHJvbFN0YXR1cyA9PT0gJ0lOVkFMSUQnKSB7XG4gICAgICAgICAgdGhpcy5fZWxlbWVudC5uYXRpdmVFbGVtZW50LmlubmVyVGV4dCA9IHRoaXMuZXh0cmFjdFZhbGlkYXRpb25NZXNzYWdlcygpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9jb250cm9sU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLl9jb250cm9sU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0VmFsaWRhdGlvbk1lc3NhZ2VzKCk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2wuZXJyb3JzKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIGNvbnN0IGVycm9yc1N0cmluZyA9IHRoaXMuX2NvbmZpZy52YWxpZGF0aW9uTWVzc2FnZXNcbiAgICAgIC5tYXAodmFsaWRhdGlvbk1lc3NhZ2UgPT4gdGhpcy5jb250cm9sLmVycm9yc1t2YWxpZGF0aW9uTWVzc2FnZS5uYW1lXVxuICAgICAgICA/IHR5cGVvZih2YWxpZGF0aW9uTWVzc2FnZS5tZXNzYWdlKSA9PT0gJ3N0cmluZydcbiAgICAgICAgICA/IHZhbGlkYXRpb25NZXNzYWdlLm1lc3NhZ2UgOiB2YWxpZGF0aW9uTWVzc2FnZS5tZXNzYWdlKHRoaXMuY29udHJvbClcbiAgICAgICAgOiAnJ1xuICAgICAgKVxuICAgICAgLmZpbHRlcihtZXNzYWdlID0+IG1lc3NhZ2UgIT09ICcnKVxuICAgICAgLmpvaW4oJywgJyk7XG5cbiAgICBjb25zdCBzZXJ2ZXJFcnJvcnMgPSB0aGlzLmNvbnRyb2wuZXJyb3JzW0ZPUk1fRklFTERfRVJST1JfS0VZXTtcbiAgICBjb25zdCBzZXJ2ZXJFcnJvcnNTdHJpbmcgPSBzZXJ2ZXJFcnJvcnMgaW5zdGFuY2VvZiBBcnJheSA/IHNlcnZlckVycm9ycy5qb2luKCcsICcpIDogJyc7XG5cbiAgICByZXR1cm4gW2Vycm9yc1N0cmluZywgc2VydmVyRXJyb3JzU3RyaW5nXS5maWx0ZXIoeCA9PiB4ICE9PSAnJykuam9pbignLCAnKTtcbiAgfVxufVxuIl19
|
|
@@ -3,23 +3,35 @@ import * as i0 from "@angular/core";
|
|
|
3
3
|
import * as i1 from "@angular/common";
|
|
4
4
|
import * as i2 from "@angular/material/form-field";
|
|
5
5
|
/**
|
|
6
|
-
* A component used to display
|
|
7
|
-
*
|
|
8
|
-
* This component will list validation errors one after another, each in separate row.
|
|
6
|
+
* A component used to display generic (form level) server side validation messages.
|
|
7
|
+
* The messages are displayed as a list, each message in a new row.
|
|
9
8
|
*
|
|
10
9
|
* @example
|
|
11
10
|
* ```html
|
|
12
|
-
* <entry-form-errors [form]="myForm"
|
|
11
|
+
* <entry-form-errors [form]="myForm">
|
|
12
|
+
* </entry-form-errors>
|
|
13
13
|
* ```
|
|
14
14
|
*/
|
|
15
15
|
export class EntryFormErrorsComponent {
|
|
16
16
|
}
|
|
17
17
|
EntryFormErrorsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryFormErrorsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18
|
-
EntryFormErrorsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: EntryFormErrorsComponent, selector: "entry-form-errors", inputs: { form: "form" }, ngImport: i0, template:
|
|
18
|
+
EntryFormErrorsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: EntryFormErrorsComponent, selector: "entry-form-errors", inputs: { form: "form" }, ngImport: i0, template: `
|
|
19
|
+
<div *ngIf="form.errors">
|
|
20
|
+
<mat-error *ngFor="let error of form.errors.general">{{error}}</mat-error>
|
|
21
|
+
</div>
|
|
22
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.MatError, selector: "mat-error", inputs: ["id"] }], changeDetection: i0.ChangeDetectionStrategy.Default });
|
|
19
23
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryFormErrorsComponent, decorators: [{
|
|
20
24
|
type: Component,
|
|
21
|
-
args: [{
|
|
25
|
+
args: [{
|
|
26
|
+
selector: 'entry-form-errors',
|
|
27
|
+
template: `
|
|
28
|
+
<div *ngIf="form.errors">
|
|
29
|
+
<mat-error *ngFor="let error of form.errors.general">{{error}}</mat-error>
|
|
30
|
+
</div>
|
|
31
|
+
`,
|
|
32
|
+
changeDetection: ChangeDetectionStrategy.Default
|
|
33
|
+
}]
|
|
22
34
|
}], propDecorators: { form: [{
|
|
23
35
|
type: Input
|
|
24
36
|
}] } });
|
|
25
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
37
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50cnktZm9ybS1lcnJvcnMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy9lbnRyeS1jb21wb25lbnRzL3ZhbGlkYXRpb24vZW50cnktZm9ybS1lcnJvcnMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7O0FBRzFFOzs7Ozs7Ozs7R0FTRztBQVVILE1BQU0sT0FBTyx3QkFBd0I7O3FIQUF4Qix3QkFBd0I7eUdBQXhCLHdCQUF3QixtRkFQekI7Ozs7R0FJVDsyRkFHVSx3QkFBd0I7a0JBVHBDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLG1CQUFtQjtvQkFDN0IsUUFBUSxFQUFFOzs7O0dBSVQ7b0JBQ0QsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE9BQU87aUJBQ2pEOzhCQUdVLElBQUk7c0JBQVosS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBVbnR5cGVkRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG4vKipcbiAqIEEgY29tcG9uZW50IHVzZWQgdG8gZGlzcGxheSBnZW5lcmljIChmb3JtIGxldmVsKSBzZXJ2ZXIgc2lkZSB2YWxpZGF0aW9uIG1lc3NhZ2VzLlxuICogVGhlIG1lc3NhZ2VzIGFyZSBkaXNwbGF5ZWQgYXMgYSBsaXN0LCBlYWNoIG1lc3NhZ2UgaW4gYSBuZXcgcm93LlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBodG1sXG4gKiA8ZW50cnktZm9ybS1lcnJvcnMgW2Zvcm1dPVwibXlGb3JtXCI+XG4gKiA8L2VudHJ5LWZvcm0tZXJyb3JzPlxuICogYGBgXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2VudHJ5LWZvcm0tZXJyb3JzJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2ICpuZ0lmPVwiZm9ybS5lcnJvcnNcIj5cbiAgICAgIDxtYXQtZXJyb3IgKm5nRm9yPVwibGV0IGVycm9yIG9mIGZvcm0uZXJyb3JzLmdlbmVyYWxcIj57e2Vycm9yfX08L21hdC1lcnJvcj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5EZWZhdWx0XG59KVxuZXhwb3J0IGNsYXNzIEVudHJ5Rm9ybUVycm9yc0NvbXBvbmVudCB7XG4gIC8qKiBBIGZvcm0gZ3JvdXAgZm9yIHdoaWNoIHRoZSB2YWxpZGF0aW9uIGVycm9ycyBhcmUgYmVpbmcgZGlzcGxheWVkLiAqL1xuICBASW5wdXQoKSBmb3JtOiBVbnR5cGVkRm9ybUdyb3VwO1xufVxuIl19
|
|
@@ -18,4 +18,4 @@ export const ENTRY_VALIDATION_CONFIG = new InjectionToken('EntryValidationConfig
|
|
|
18
18
|
providedIn: 'root',
|
|
19
19
|
factory: () => new EntryValidationConfig()
|
|
20
20
|
});
|
|
21
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50cnktdmFsaWRhdGlvbi1jb25maWcubW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL2VudHJ5LWNvbXBvbmVudHMvdmFsaWRhdGlvbi9lbnRyeS12YWxpZGF0aW9uLWNvbmZpZy5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBYy9DOztHQUVHO0FBQ0gsTUFBTSxPQUFPLHFCQUFxQjtJQW9COUIsWUFBWSxTQUF5QyxFQUFFO1FBQ25ELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxNQUFNLENBQUMsa0JBQWtCLElBQUksRUFBRSxDQUFDO0lBQzlELENBQUM7Q0FDSjtBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLElBQUksY0FBYyxDQUNyRCx1QkFBdUIsRUFDdkI7SUFDSSxVQUFVLEVBQUUsTUFBTTtJQUNsQixPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxxQkFBcUIsRUFBRTtDQUM3QyxDQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3Rpb25Ub2tlbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG4vKiogVXNlZCB0byBjb25maWd1cmUgbWFwcGluZyBiZXR3ZWVuIHZhbGlkYXRpb24ga2V5cyBhbmQgbWVzc2FnZXMgKi9cbmV4cG9ydCBpbnRlcmZhY2UgSUVudHJ5VmFsaWRhdGlvbk1lc3NhZ2Uge1xuICAgIC8qKiBWYWxpZGF0aW9uIGtleSAoZS5nLiAnX3JlcXVpcmVkXycsICdfbWlubGVuZ3RoXycsICdfZW1haWxfJywgZXRjLikgKi9cbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogVmFsaWRhdGlvbiBtZXNzYWdlLiBDYW4gYmUgc3RhdGljIHN0cmluZyBvciBleHByZXNzaW9uIHJldHVybmluZyBzdHJpbmdcbiAgICAgKiAgKHdoZW4gbWVzc2FnZXMgbmVlZCB0byBiZSByZXNvbHZlZCBkeW5hbWljYWxseTogcGFyYW1ldHJpemF0aW9uLCBsb2NhbGl6YXRpb24sIGV0Yy4pLlxuICAgICAqL1xuICAgIG1lc3NhZ2U6IHN0cmluZyB8ICgoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiBzdHJpbmcpO1xufVxuXG4vKipcbiAqIFVzZWQgdG8gcHJvdmlkZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb25zIG9uIG1vZHVsZSBsZXZlbC5cbiAqL1xuZXhwb3J0IGNsYXNzIEVudHJ5VmFsaWRhdGlvbkNvbmZpZyB7XG4gICAgLyoqXG4gICAgICogVmFsaWRhdGlvbiBrZXkgdG8gbWVzc2FnZSBjb25maWd1cmF0aW9uIG9uIG1vZHVsZSBsZXZlbC4gVXNlZCB0byBjb25maWd1cmUgY2xpZW50IHNpZGUgdmFsaWRhdGlvbiBtZXNzYWdlc1xuICAgICAqIGZvciBzdGFuZGFyZCB2YWxpZGF0b3JzIChfcmVxdWlyZWRfLCBfbWluTGVuZ3RoXywgX2VtYWlsXywgZXRjLikuXG4gICAgICpcbiAgICAgKiAqKk5PVEU6KiogSWYgdXNpbmcgX0Zvcm1seV8gcGFja2FnZSB0byByZW5kZXIgZm9ybXMsIHRoaXMgY29uZmlndXJhdGlvbiBzaG91bGQgbm90IGJlIHVzZWQuXG4gICAgICogSW5zdGVhZCwgdXNlIGBGb3JtbHlNb2R1bGVgIHRvIGNvbmZpZ3VyZSB2YWxpZGF0aW9uIG1lc3NhZ2VzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGB0c1xuICAgICAqIG5ldyBFbnRyeVZhbGlkYXRpb25Db25maWcoKSB7XG4gICAgICogICB2YWxpZGF0aW9uTWVzc2FnZXM6IFtcbiAgICAgKiAgICAgeyBuYW1lOiAncmVxdWlyZWQnOiBtZXNzYWdlOiAnVGhpcyBmaWVsZCBpcyBtYW5kYXRvcnknIH0sXG4gICAgICogICAgIHsgbmFtZTogJ21pbmxlbmd0aCcsIG1lc3NhZ2U6IChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpID0+IGBNaW5pbWFsIGxlbmd0aCBpcyAke2NvbnRyb2wuZXJyb3JzLm1pbmxlbmd0aC5yZXF1aXJlZExlbmd0aH1gfVxuICAgICAqICAgXVxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICB2YWxpZGF0aW9uTWVzc2FnZXM6IElFbnRyeVZhbGlkYXRpb25NZXNzYWdlW107XG5cbiAgICBjb25zdHJ1Y3Rvcihjb25maWc6IFBhcnRpYWw8RW50cnlWYWxpZGF0aW9uQ29uZmlnPiA9IHt9KSB7XG4gICAgICAgIHRoaXMudmFsaWRhdGlvbk1lc3NhZ2VzID0gY29uZmlnLnZhbGlkYXRpb25NZXNzYWdlcyA/PyBbXTtcbiAgICB9XG59XG5cbi8qKlxuICogRW50cnkgdmFsaWRhdGlvbiBpbmplY3Rpb24gdG9rZW4gb2YgRW50cnlWYWxpZGF0aW9uQ29uZmlnIHR5cGUgY29udGFpbmluZyB2YWxpZGF0aW9uIGRlZmF1bHQgY29uZmlndXJhdGlvbnMuXG4gKiBDYW4gYmUgdXBkYXRlZCB3aXRoIGN1c3RvbSBjb25maWd1cmF0aW9uLlxuICpcbiAqIERlZmF1bHRzOlxuICogLSB2YWxpZGF0aW9uTWVzc2FnZXM6IFtdXG4gKi9cbmV4cG9ydCBjb25zdCBFTlRSWV9WQUxJREFUSU9OX0NPTkZJRyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxFbnRyeVZhbGlkYXRpb25Db25maWc+KFxuICAgICdFbnRyeVZhbGlkYXRpb25Db25maWcnLFxuICAgIHtcbiAgICAgICAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxuICAgICAgICBmYWN0b3J5OiAoKSA9PiBuZXcgRW50cnlWYWxpZGF0aW9uQ29uZmlnKClcbiAgICB9XG4pO1xuIl19
|
|
@@ -19,10 +19,10 @@ const getFormControl = (formControl, keys) => {
|
|
|
19
19
|
* Applies validation errors received from server side to the form.
|
|
20
20
|
* The errors are applied to multiple levels: form, form group, form array, and form field.
|
|
21
21
|
*
|
|
22
|
-
* @param form Form to apply validation errors to.
|
|
23
22
|
* @param error Server side validation errors response.
|
|
23
|
+
* @param form Form to apply validation errors to.
|
|
24
24
|
*/
|
|
25
|
-
const
|
|
25
|
+
const setServerSideValidationErrors = (error, form) => {
|
|
26
26
|
form.setErrors(null);
|
|
27
27
|
const validationErrors = error?.errors;
|
|
28
28
|
const formErrors = {};
|
|
@@ -47,5 +47,5 @@ const handleValidationProblemDetails = (form, error) => {
|
|
|
47
47
|
}
|
|
48
48
|
form.setErrors(formErrors);
|
|
49
49
|
};
|
|
50
|
-
export { FORM_FIELD_ERROR_KEY,
|
|
51
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
50
|
+
export { FORM_FIELD_ERROR_KEY, setServerSideValidationErrors };
|
|
51
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50cnktdmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvZW50cnktY29tcG9uZW50cy92YWxpZGF0aW9uL2VudHJ5LXZhbGlkYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFtQixTQUFTLEVBQUUsU0FBUyxFQUFzQyxNQUFNLGdCQUFnQixDQUFDO0FBRzNHLG9FQUFvRTtBQUNwRSxNQUFNLGNBQWMsR0FBRyxTQUFTLENBQUM7QUFDakMsMEVBQTBFO0FBQzFFLE1BQU0sb0JBQW9CLEdBQUcsWUFBWSxDQUFDO0FBRTFDLE1BQU0sY0FBYyxHQUFHLENBQUMsV0FBK0MsRUFBRSxJQUFjLEVBQXNDLEVBQUU7SUFDM0gsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtRQUNuQixPQUFPLFdBQVcsQ0FBQztLQUN0QjtJQUNELElBQUksV0FBVyxZQUFZLFNBQVMsRUFBRTtRQUNsQyxPQUFPLGNBQWMsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUNsSDtJQUNELElBQUksV0FBVyxZQUFZLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDbkQsT0FBTyxjQUFjLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUN4RTtJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2hCLENBQUMsQ0FBQztBQUVGOzs7Ozs7R0FNRztBQUNILE1BQU0sNkJBQTZCLEdBQUcsQ0FBQyxLQUFnQyxFQUFFLElBQXNCLEVBQUUsRUFBRTtJQUMvRixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3JCLE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxFQUFFLE1BQU0sQ0FBQztJQUN2QyxNQUFNLFVBQVUsR0FBcUIsRUFBRSxDQUFDO0lBRXhDLElBQUksZ0JBQWdCLEVBQUU7UUFDbEIsd0NBQXdDO1FBQ3hDLEtBQUssTUFBTSxHQUFHLElBQUksZ0JBQWdCLEVBQUU7WUFDaEMsTUFBTSxPQUFPLEdBQUcsY0FBYyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7WUFFN0QsSUFBSSxPQUFPLEVBQUU7Z0JBQ1QsTUFBTSxXQUFXLEdBQUcsRUFBc0IsQ0FBQztnQkFDM0MsV0FBVyxDQUFDLG9CQUFvQixDQUFDLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzFELE9BQU8sQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQy9CLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQzthQUMzQjtpQkFBTTtnQkFDSCxVQUFVLENBQUMsY0FBYyxDQUFDO29CQUN0QixVQUFVLENBQUMsY0FBYyxDQUFDLEVBQUUsTUFBTSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDMUY7U0FDSjtLQUNKO1NBQU07UUFDSCxVQUFVLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO0tBQ3JFO0lBRUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUMvQixDQUFDLENBQUM7QUFFRixPQUFPLEVBQ0gsb0JBQW9CLEVBQ3BCLDZCQUE2QixFQUNoQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBGb3JtQXJyYXksIEZvcm1Hcm91cCwgVW50eXBlZEZvcm1Hcm91cCwgVmFsaWRhdGlvbkVycm9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IElWYWxpZGF0aW9uUHJvYmxlbURldGFpbHMgfSBmcm9tICcuL3ZhbGlkYXRpb24tcHJvYmxlbS1kZXRhaWxzLmludGVyZmFjZSc7XG5cbi8qKiBBIGtleSB1c2VkIHRvIG1hcCBzZXJ2ZXIgc2lkZSB2YWxpZGF0aW9uIGVycm9ycyBvbiBmb3JtIGxldmVsICovXG5jb25zdCBGT1JNX0VSUk9SX0tFWSA9ICdnZW5lcmFsJztcbi8qKiBBIGtleSB1c2VkIHRvIG1hcCBzZXJ2ZXIgc2lkZSB2YWxpZGF0aW9uIGVycm9ycyBvbiBmb3JtIGZpZWxkIGxldmVsICovXG5jb25zdCBGT1JNX0ZJRUxEX0VSUk9SX0tFWSA9ICdmcm9tU2VydmVyJztcblxuY29uc3QgZ2V0Rm9ybUNvbnRyb2wgPSAoZm9ybUNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCB8IG51bGwgfCB1bmRlZmluZWQsIGtleXM6IHN0cmluZ1tdKTogQWJzdHJhY3RDb250cm9sIHwgbnVsbCB8IHVuZGVmaW5lZCA9PiB7XG4gICAgaWYgKGtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBmb3JtQ29udHJvbDtcbiAgICB9XG4gICAgaWYgKGZvcm1Db250cm9sIGluc3RhbmNlb2YgRm9ybUdyb3VwKSB7XG4gICAgICAgIHJldHVybiBnZXRGb3JtQ29udHJvbChmb3JtQ29udHJvbC5jb250cm9sc1trZXlzWzBdLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpICsga2V5c1swXS5zbGljZSgxKV0sIGtleXMuc2xpY2UoMSkpO1xuICAgIH1cbiAgICBpZiAoZm9ybUNvbnRyb2wgaW5zdGFuY2VvZiBGb3JtQXJyYXkgJiYgK2tleXNbMF0gPj0gMCkge1xuICAgICAgICByZXR1cm4gZ2V0Rm9ybUNvbnRyb2woZm9ybUNvbnRyb2wuY29udHJvbHNbK2tleXNbMF1dLCBrZXlzLnNsaWNlKDEpKTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIEFwcGxpZXMgdmFsaWRhdGlvbiBlcnJvcnMgcmVjZWl2ZWQgZnJvbSBzZXJ2ZXIgc2lkZSB0byB0aGUgZm9ybS5cbiAqIFRoZSBlcnJvcnMgYXJlIGFwcGxpZWQgdG8gbXVsdGlwbGUgbGV2ZWxzOiBmb3JtLCBmb3JtIGdyb3VwLCBmb3JtIGFycmF5LCBhbmQgZm9ybSBmaWVsZC5cbiAqXG4gKiBAcGFyYW0gZXJyb3IgU2VydmVyIHNpZGUgdmFsaWRhdGlvbiBlcnJvcnMgcmVzcG9uc2UuXG4gKiBAcGFyYW0gZm9ybSBGb3JtIHRvIGFwcGx5IHZhbGlkYXRpb24gZXJyb3JzIHRvLlxuICovXG5jb25zdCBzZXRTZXJ2ZXJTaWRlVmFsaWRhdGlvbkVycm9ycyA9IChlcnJvcjogSVZhbGlkYXRpb25Qcm9ibGVtRGV0YWlscywgZm9ybTogVW50eXBlZEZvcm1Hcm91cCkgPT4ge1xuICAgIGZvcm0uc2V0RXJyb3JzKG51bGwpO1xuICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSBlcnJvcj8uZXJyb3JzO1xuICAgIGNvbnN0IGZvcm1FcnJvcnM6IFZhbGlkYXRpb25FcnJvcnMgPSB7fTtcblxuICAgIGlmICh2YWxpZGF0aW9uRXJyb3JzKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBndWFyZC1mb3ItaW5cbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gdmFsaWRhdGlvbkVycm9ycykge1xuICAgICAgICAgICAgY29uc3QgY29udHJvbCA9IGdldEZvcm1Db250cm9sKGZvcm0sIGtleS5zcGxpdCgvWy5bXFxdXSsvZ3UpKTtcblxuICAgICAgICAgICAgaWYgKGNvbnRyb2wpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWVsZEVycm9ycyA9IHt9IGFzIFZhbGlkYXRpb25FcnJvcnM7XG4gICAgICAgICAgICAgICAgZmllbGRFcnJvcnNbRk9STV9GSUVMRF9FUlJPUl9LRVldID0gdmFsaWRhdGlvbkVycm9yc1trZXldO1xuICAgICAgICAgICAgICAgIGNvbnRyb2wuc2V0RXJyb3JzKGZpZWxkRXJyb3JzKTtcbiAgICAgICAgICAgICAgICBjb250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9ybUVycm9yc1tGT1JNX0VSUk9SX0tFWV0gPVxuICAgICAgICAgICAgICAgICAgICBmb3JtRXJyb3JzW0ZPUk1fRVJST1JfS0VZXT8uY29uY2F0KHZhbGlkYXRpb25FcnJvcnNba2V5XSkgfHwgdmFsaWRhdGlvbkVycm9yc1trZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZm9ybUVycm9yc1tGT1JNX0VSUk9SX0tFWV0gPSBbYEFuIGVycm9yIG9jY3VycmVkIG9uIHRoZSBzZXJ2ZXIuYF07XG4gICAgfVxuXG4gICAgZm9ybS5zZXRFcnJvcnMoZm9ybUVycm9ycyk7XG59O1xuXG5leHBvcnQge1xuICAgIEZPUk1fRklFTERfRVJST1JfS0VZLFxuICAgIHNldFNlcnZlclNpZGVWYWxpZGF0aW9uRXJyb3JzXG59O1xuIl19
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export {};
|
|
2
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi1wcm9ibGVtLWRldGFpbHMuaW50ZXJmYWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy9lbnRyeS1jb21wb25lbnRzL3ZhbGlkYXRpb24vdmFsaWRhdGlvbi1wcm9ibGVtLWRldGFpbHMuaW50ZXJmYWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIERlZmluZXMgdGhlIGFwaSB1c2VkIGFzIGEgY29udGFpbmVyIGZvciBzZXJ2ZXIgc2lkZSB2YWxpZGF0aW9uIGVycm9ycy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJVmFsaWRhdGlvblByb2JsZW1EZXRhaWxzIHtcbiAgICBba2V5OiBzdHJpbmddOiBhbnk7XG4gICAgZXJyb3JzPzogeyBba2V5OiBzdHJpbmddOiBzdHJpbmdbXSB9O1xufVxuIl19
|
|
@@ -5,10 +5,10 @@ import { CommonModule } from '@angular/common';
|
|
|
5
5
|
class EntryHeaderComponent {
|
|
6
6
|
}
|
|
7
7
|
EntryHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8
|
-
EntryHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: EntryHeaderComponent, selector: "entry-header", inputs: { title: "title" }, ngImport: i0, template: "<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"
|
|
8
|
+
EntryHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: EntryHeaderComponent, selector: "entry-header", inputs: { title: "title" }, ngImport: i0, template: "<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"title item\">{{title}}</h1>\n <ng-content select=\"[buttons]\"></ng-content>\n </div>\n <div class=\"row content\">\n <ng-content select=\"[content]\"></ng-content>\n </div>\n</header>", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
9
9
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryHeaderComponent, decorators: [{
|
|
10
10
|
type: Component,
|
|
11
|
-
args: [{ selector: 'entry-header', changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"
|
|
11
|
+
args: [{ selector: 'entry-header', changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"title item\">{{title}}</h1>\n <ng-content select=\"[buttons]\"></ng-content>\n </div>\n <div class=\"row content\">\n <ng-content select=\"[content]\"></ng-content>\n </div>\n</header>" }]
|
|
12
12
|
}], propDecorators: { title: [{
|
|
13
13
|
type: Input
|
|
14
14
|
}] } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enigmatry-entry-components-header.mjs","sources":["../../../../libs/entry-components/header/entry-header.component.ts","../../../../libs/entry-components/header/entry-header.component.html","../../../../libs/entry-components/header/entry-header.module.ts","../../../../libs/entry-components/header/enigmatry-entry-components-header.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\n\n@Component({\n selector: 'entry-header',\n templateUrl: './entry-header.component.html',\n styleUrls: ['./entry-header.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class EntryHeaderComponent {\n @Input() title: string;\n}\n","<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"
|
|
1
|
+
{"version":3,"file":"enigmatry-entry-components-header.mjs","sources":["../../../../libs/entry-components/header/entry-header.component.ts","../../../../libs/entry-components/header/entry-header.component.html","../../../../libs/entry-components/header/entry-header.module.ts","../../../../libs/entry-components/header/enigmatry-entry-components-header.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\n\n@Component({\n selector: 'entry-header',\n templateUrl: './entry-header.component.html',\n styleUrls: ['./entry-header.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class EntryHeaderComponent {\n @Input() title: string;\n}\n","<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"title item\">{{title}}</h1>\n <ng-content select=\"[buttons]\"></ng-content>\n </div>\n <div class=\"row content\">\n <ng-content select=\"[content]\"></ng-content>\n </div>\n</header>","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { EntryHeaderComponent } from './entry-header.component';\n\n@NgModule({\n declarations: [\n EntryHeaderComponent\n ],\n imports: [\n CommonModule\n ],\n exports: [\n EntryHeaderComponent\n ]\n})\nexport class EntryHeaderModule { }\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;MAQa,oBAAoB,CAAA;;iHAApB,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAApB,oBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,oBAAoB,gFCRjC,qRAQS,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;2FDAI,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBANhC,SAAS;+BACE,cAAc,EAAA,eAAA,EAGP,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,qRAAA,EAAA,CAAA;8BAGtC,KAAK,EAAA,CAAA;sBAAb,KAAK;;;MEMK,iBAAiB,CAAA;;8GAAjB,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;AAAjB,iBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,EAT1B,YAAA,EAAA,CAAA,oBAAoB,CAGpB,EAAA,OAAA,EAAA,CAAA,YAAY,aAGZ,oBAAoB,CAAA,EAAA,CAAA,CAAA;AAGX,iBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,YAN1B,YAAY,CAAA,EAAA,CAAA,CAAA;2FAMH,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAX7B,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,YAAY,EAAE;wBACZ,oBAAoB;AACrB,qBAAA;AACD,oBAAA,OAAO,EAAE;wBACP,YAAY;AACb,qBAAA;AACD,oBAAA,OAAO,EAAE;wBACP,oBAAoB;AACrB,qBAAA;iBACF,CAAA;;;ACdD;;AAEG;;;;"}
|
|
@@ -7,22 +7,34 @@ import { FormGroup, FormArray, FormsModule, ReactiveFormsModule } from '@angular
|
|
|
7
7
|
import { MatInputModule } from '@angular/material/input';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* A component used to display
|
|
11
|
-
*
|
|
12
|
-
* This component will list validation errors one after another, each in separate row.
|
|
10
|
+
* A component used to display generic (form level) server side validation messages.
|
|
11
|
+
* The messages are displayed as a list, each message in a new row.
|
|
13
12
|
*
|
|
14
13
|
* @example
|
|
15
14
|
* ```html
|
|
16
|
-
* <entry-form-errors [form]="myForm"
|
|
15
|
+
* <entry-form-errors [form]="myForm">
|
|
16
|
+
* </entry-form-errors>
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
class EntryFormErrorsComponent {
|
|
20
20
|
}
|
|
21
21
|
EntryFormErrorsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryFormErrorsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
22
|
-
EntryFormErrorsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: EntryFormErrorsComponent, selector: "entry-form-errors", inputs: { form: "form" }, ngImport: i0, template:
|
|
22
|
+
EntryFormErrorsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: EntryFormErrorsComponent, selector: "entry-form-errors", inputs: { form: "form" }, ngImport: i0, template: `
|
|
23
|
+
<div *ngIf="form.errors">
|
|
24
|
+
<mat-error *ngFor="let error of form.errors.general">{{error}}</mat-error>
|
|
25
|
+
</div>
|
|
26
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.MatError, selector: "mat-error", inputs: ["id"] }], changeDetection: i0.ChangeDetectionStrategy.Default });
|
|
23
27
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryFormErrorsComponent, decorators: [{
|
|
24
28
|
type: Component,
|
|
25
|
-
args: [{
|
|
29
|
+
args: [{
|
|
30
|
+
selector: 'entry-form-errors',
|
|
31
|
+
template: `
|
|
32
|
+
<div *ngIf="form.errors">
|
|
33
|
+
<mat-error *ngFor="let error of form.errors.general">{{error}}</mat-error>
|
|
34
|
+
</div>
|
|
35
|
+
`,
|
|
36
|
+
changeDetection: ChangeDetectionStrategy.Default
|
|
37
|
+
}]
|
|
26
38
|
}], propDecorators: { form: [{
|
|
27
39
|
type: Input
|
|
28
40
|
}] } });
|
|
@@ -68,10 +80,10 @@ const getFormControl = (formControl, keys) => {
|
|
|
68
80
|
* Applies validation errors received from server side to the form.
|
|
69
81
|
* The errors are applied to multiple levels: form, form group, form array, and form field.
|
|
70
82
|
*
|
|
71
|
-
* @param form Form to apply validation errors to.
|
|
72
83
|
* @param error Server side validation errors response.
|
|
84
|
+
* @param form Form to apply validation errors to.
|
|
73
85
|
*/
|
|
74
|
-
const
|
|
86
|
+
const setServerSideValidationErrors = (error, form) => {
|
|
75
87
|
var _a;
|
|
76
88
|
form.setErrors(null);
|
|
77
89
|
const validationErrors = error === null || error === void 0 ? void 0 : error.errors;
|
|
@@ -98,6 +110,16 @@ const handleValidationProblemDetails = (form, error) => {
|
|
|
98
110
|
form.setErrors(formErrors);
|
|
99
111
|
};
|
|
100
112
|
|
|
113
|
+
/**
|
|
114
|
+
* A directive that displays configured validation messages or server side validations for given form control.
|
|
115
|
+
* The messages are separated with coma(,) and displayed as _innerHTML_ value of host component.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```html
|
|
119
|
+
* <div entryDisplayControlValidation [control]="myForm.controls.firstName">
|
|
120
|
+
* </div
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
101
123
|
class EntryDisplayControlValidationDirective {
|
|
102
124
|
constructor(_config, _element) {
|
|
103
125
|
this._config = _config;
|
|
@@ -185,5 +207,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
185
207
|
* Generated bundle index. Do not edit.
|
|
186
208
|
*/
|
|
187
209
|
|
|
188
|
-
export { ENTRY_VALIDATION_CONFIG, EntryDisplayControlValidationDirective, EntryFormErrorsComponent, EntryValidationConfig, EntryValidationModule, FORM_FIELD_ERROR_KEY,
|
|
210
|
+
export { ENTRY_VALIDATION_CONFIG, EntryDisplayControlValidationDirective, EntryFormErrorsComponent, EntryValidationConfig, EntryValidationModule, FORM_FIELD_ERROR_KEY, setServerSideValidationErrors };
|
|
189
211
|
//# sourceMappingURL=enigmatry-entry-components-validation.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enigmatry-entry-components-validation.mjs","sources":["../../../../libs/entry-components/validation/entry-form-errors.component.ts","../../../../libs/entry-components/validation/entry-form-errors.component.html","../../../../libs/entry-components/validation/entry-validation-config.model.ts","../../../../libs/entry-components/validation/entry-validation.ts","../../../../libs/entry-components/validation/entry-display-control-validation.directive.ts","../../../../libs/entry-components/validation/entry-validation.module.ts","../../../../libs/entry-components/validation/enigmatry-entry-components-validation.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { UntypedFormGroup } from '@angular/forms';\n\n/**\n * A component used to display back-end validation errors on form level (errors that are not connected to the specific form field).\n *\n * This component will list validation errors one after another, each in separate row.\n *\n * @example\n * ```html\n * <entry-form-errors [form]=\"myForm\"></entry-form-errors>\n * ```\n */\n@Component({\n selector: 'entry-form-errors',\n templateUrl: './entry-form-errors.component.html',\n styleUrls: ['./entry-form-errors.component.scss'],\n changeDetection: ChangeDetectionStrategy.Default\n})\nexport class EntryFormErrorsComponent {\n @Input() form: UntypedFormGroup;\n}\n","<div *ngIf=\"form.errors\">\n <mat-error *ngFor=\"let error of form.errors.general\">{{error}}</mat-error>\n</div>","import { InjectionToken } from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\n\n/** Validation message configuration */\nexport interface IEntryValidationMessage {\n // Validation key\n name: string;\n // Validation message. Can be resolved dynamically (e.g. when it needs to be translated).\n message: string | ((c: AbstractControl) => string);\n}\n\n/**\n * Used to provide default configurations on module level.\n */\nexport class EntryValidationConfig {\n /** Validation key to message configuration on module level. */\n validationMessages: IEntryValidationMessage[];\n\n constructor(config: Partial<EntryValidationConfig> = {}) {\n this.validationMessages = config.validationMessages ?? [];\n }\n}\n\n/**\n * Entry validation injection token of EntryValidationConfig type containing validation default configurations.\n * Can be updated with custom configuration.\n *\n * Defaults:\n * - validationMessages: []\n */\nexport const ENTRY_VALIDATION_CONFIG = new InjectionToken<EntryValidationConfig>(\n 'EntryValidationConfig',\n {\n providedIn: 'root',\n factory: () => new EntryValidationConfig()\n }\n);\n","import { AbstractControl, FormArray, FormGroup, UntypedFormGroup, ValidationErrors } from '@angular/forms';\nimport { IValidationProblemDetails } from './validation-problem-details.interface';\n\n/** A key used to map server side validation errors on form level */\nconst FORM_ERROR_KEY = 'general';\n/** A key used to map server side validation errors on form field level */\nconst FORM_FIELD_ERROR_KEY = 'fromServer';\n\nconst getFormControl = (formControl: AbstractControl | null | undefined, keys: string[]): AbstractControl | null | undefined => {\n if (keys.length === 0) {\n return formControl;\n }\n if (formControl instanceof FormGroup) {\n return getFormControl(formControl.controls[keys[0].charAt(0).toLowerCase() + keys[0].slice(1)], keys.slice(1));\n }\n if (formControl instanceof FormArray && +keys[0] >= 0) {\n return getFormControl(formControl.controls[+keys[0]], keys.slice(1));\n }\n return null;\n};\n\n/**\n * Applies validation errors received from server side to the form.\n * The errors are applied to multiple levels: form, form group, form array, and form field.\n *\n * @param form Form to apply validation errors to.\n * @param error Server side validation errors response.\n */\nconst handleValidationProblemDetails = (form: UntypedFormGroup, error: IValidationProblemDetails) => {\n form.setErrors(null);\n const validationErrors = error?.errors;\n const formErrors: ValidationErrors = {};\n\n if (validationErrors) {\n // eslint-disable-next-line guard-for-in\n for (const key in validationErrors) {\n const control = getFormControl(form, key.split(/[.[\\]]+/gu));\n\n if (control) {\n const fieldErrors = {} as ValidationErrors;\n fieldErrors[FORM_FIELD_ERROR_KEY] = validationErrors[key];\n control.setErrors(fieldErrors);\n control.markAsTouched();\n } else {\n formErrors[FORM_ERROR_KEY] =\n formErrors[FORM_ERROR_KEY]?.concat(validationErrors[key]) || validationErrors[key];\n }\n }\n } else {\n formErrors[FORM_ERROR_KEY] = [ `An error occurred on the server.` ];\n }\n\n form.setErrors(formErrors);\n};\n\nexport {\n FORM_FIELD_ERROR_KEY,\n handleValidationProblemDetails\n};\n","import { Directive, ElementRef, Inject, Input, OnDestroy, OnInit } from '@angular/core';\nimport { ENTRY_VALIDATION_CONFIG, EntryValidationConfig } from './entry-validation-config.model';\nimport { AbstractControl, FormControlStatus } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport { FORM_FIELD_ERROR_KEY } from './entry-validation';\n\n@Directive({\n selector: '[entryDisplayControlValidation]'\n})\nexport class EntryDisplayControlValidationDirective implements OnInit, OnDestroy {\n @Input() control: AbstractControl;\n\n private _controlSubscription: Subscription | undefined;\n\n constructor(\n @Inject(ENTRY_VALIDATION_CONFIG) private readonly _config: EntryValidationConfig,\n private readonly _element: ElementRef) {}\n\n ngOnInit(): void {\n this._controlSubscription = this.control.statusChanges\n .subscribe((controlStatus: FormControlStatus) => {\n if (controlStatus === 'INVALID') {\n this._element.nativeElement.innerText = this.extractValidationMessages();\n }\n });\n }\n\n ngOnDestroy(): void {\n if (this._controlSubscription) {\n this._controlSubscription.unsubscribe();\n }\n }\n\n private extractValidationMessages(): string {\n if (!this.control.errors) {\n return '';\n }\n const errorsString = this._config.validationMessages\n .map(validationMessage => this.control.errors[validationMessage.name]\n ? typeof(validationMessage.message) === 'string'\n ? validationMessage.message : validationMessage.message(this.control)\n : ''\n )\n .filter(message => message !== '')\n .join(', ');\n\n const serverErrors = this.control.errors[FORM_FIELD_ERROR_KEY];\n const serverErrorsString = serverErrors instanceof Array ? serverErrors.join(', ') : '';\n\n return [errorsString, serverErrorsString].filter(x => x !== '').join(', ');\n }\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { EntryFormErrorsComponent } from './entry-form-errors.component';\nimport { MatInputModule } from '@angular/material/input';\nimport { EntryDisplayControlValidationDirective } from './entry-display-control-validation.directive';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\n\n@NgModule({\n declarations: [\n EntryFormErrorsComponent,\n EntryDisplayControlValidationDirective\n ],\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n MatInputModule\n ],\n exports: [\n EntryFormErrorsComponent,\n EntryDisplayControlValidationDirective\n ]\n})\nexport class EntryValidationModule { }\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"enigmatry-entry-components-validation.mjs","sources":["../../../../libs/entry-components/validation/entry-form-errors.component.ts","../../../../libs/entry-components/validation/entry-validation-config.model.ts","../../../../libs/entry-components/validation/entry-validation.ts","../../../../libs/entry-components/validation/entry-display-control-validation.directive.ts","../../../../libs/entry-components/validation/entry-validation.module.ts","../../../../libs/entry-components/validation/enigmatry-entry-components-validation.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { UntypedFormGroup } from '@angular/forms';\n\n/**\n * A component used to display generic (form level) server side validation messages.\n * The messages are displayed as a list, each message in a new row.\n *\n * @example\n * ```html\n * <entry-form-errors [form]=\"myForm\">\n * </entry-form-errors>\n * ```\n */\n@Component({\n selector: 'entry-form-errors',\n template: `\n <div *ngIf=\"form.errors\">\n <mat-error *ngFor=\"let error of form.errors.general\">{{error}}</mat-error>\n </div>\n `,\n changeDetection: ChangeDetectionStrategy.Default\n})\nexport class EntryFormErrorsComponent {\n /** A form group for which the validation errors are being displayed. */\n @Input() form: UntypedFormGroup;\n}\n","import { InjectionToken } from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\n\n/** Used to configure mapping between validation keys and messages */\nexport interface IEntryValidationMessage {\n /** Validation key (e.g. '_required_', '_minlength_', '_email_', etc.) */\n name: string;\n /**\n * Validation message. Can be static string or expression returning string\n * (when messages need to be resolved dynamically: parametrization, localization, etc.).\n */\n message: string | ((control: AbstractControl) => string);\n}\n\n/**\n * Used to provide default configurations on module level.\n */\nexport class EntryValidationConfig {\n /**\n * Validation key to message configuration on module level. Used to configure client side validation messages\n * for standard validators (_required_, _minLength_, _email_, etc.).\n *\n * **NOTE:** If using _Formly_ package to render forms, this configuration should not be used.\n * Instead, use `FormlyModule` to configure validation messages.\n *\n * @example\n * ```ts\n * new EntryValidationConfig() {\n * validationMessages: [\n * { name: 'required': message: 'This field is mandatory' },\n * { name: 'minlength', message: (control: AbstractControl) => `Minimal length is ${control.errors.minlength.requiredLength}`}\n * ]\n * }\n * ```\n */\n validationMessages: IEntryValidationMessage[];\n\n constructor(config: Partial<EntryValidationConfig> = {}) {\n this.validationMessages = config.validationMessages ?? [];\n }\n}\n\n/**\n * Entry validation injection token of EntryValidationConfig type containing validation default configurations.\n * Can be updated with custom configuration.\n *\n * Defaults:\n * - validationMessages: []\n */\nexport const ENTRY_VALIDATION_CONFIG = new InjectionToken<EntryValidationConfig>(\n 'EntryValidationConfig',\n {\n providedIn: 'root',\n factory: () => new EntryValidationConfig()\n }\n);\n","import { AbstractControl, FormArray, FormGroup, UntypedFormGroup, ValidationErrors } from '@angular/forms';\nimport { IValidationProblemDetails } from './validation-problem-details.interface';\n\n/** A key used to map server side validation errors on form level */\nconst FORM_ERROR_KEY = 'general';\n/** A key used to map server side validation errors on form field level */\nconst FORM_FIELD_ERROR_KEY = 'fromServer';\n\nconst getFormControl = (formControl: AbstractControl | null | undefined, keys: string[]): AbstractControl | null | undefined => {\n if (keys.length === 0) {\n return formControl;\n }\n if (formControl instanceof FormGroup) {\n return getFormControl(formControl.controls[keys[0].charAt(0).toLowerCase() + keys[0].slice(1)], keys.slice(1));\n }\n if (formControl instanceof FormArray && +keys[0] >= 0) {\n return getFormControl(formControl.controls[+keys[0]], keys.slice(1));\n }\n return null;\n};\n\n/**\n * Applies validation errors received from server side to the form.\n * The errors are applied to multiple levels: form, form group, form array, and form field.\n *\n * @param error Server side validation errors response.\n * @param form Form to apply validation errors to.\n */\nconst setServerSideValidationErrors = (error: IValidationProblemDetails, form: UntypedFormGroup) => {\n form.setErrors(null);\n const validationErrors = error?.errors;\n const formErrors: ValidationErrors = {};\n\n if (validationErrors) {\n // eslint-disable-next-line guard-for-in\n for (const key in validationErrors) {\n const control = getFormControl(form, key.split(/[.[\\]]+/gu));\n\n if (control) {\n const fieldErrors = {} as ValidationErrors;\n fieldErrors[FORM_FIELD_ERROR_KEY] = validationErrors[key];\n control.setErrors(fieldErrors);\n control.markAsTouched();\n } else {\n formErrors[FORM_ERROR_KEY] =\n formErrors[FORM_ERROR_KEY]?.concat(validationErrors[key]) || validationErrors[key];\n }\n }\n } else {\n formErrors[FORM_ERROR_KEY] = [`An error occurred on the server.`];\n }\n\n form.setErrors(formErrors);\n};\n\nexport {\n FORM_FIELD_ERROR_KEY,\n setServerSideValidationErrors\n};\n","import { Directive, ElementRef, Inject, Input, OnDestroy, OnInit } from '@angular/core';\nimport { ENTRY_VALIDATION_CONFIG, EntryValidationConfig } from './entry-validation-config.model';\nimport { AbstractControl, FormControlStatus } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport { FORM_FIELD_ERROR_KEY } from './entry-validation';\n\n/**\n * A directive that displays configured validation messages or server side validations for given form control.\n * The messages are separated with coma(,) and displayed as _innerHTML_ value of host component.\n *\n * @example\n * ```html\n * <div entryDisplayControlValidation [control]=\"myForm.controls.firstName\">\n * </div\n * ```\n */\n@Directive({\n selector: '[entryDisplayControlValidation]'\n})\nexport class EntryDisplayControlValidationDirective implements OnInit, OnDestroy {\n /** Form control for which the validation messages are displayed for. */\n @Input() control: AbstractControl;\n\n private _controlSubscription: Subscription | undefined;\n\n constructor(\n @Inject(ENTRY_VALIDATION_CONFIG) private readonly _config: EntryValidationConfig,\n private readonly _element: ElementRef) {}\n\n ngOnInit(): void {\n this._controlSubscription = this.control.statusChanges\n .subscribe((controlStatus: FormControlStatus) => {\n if (controlStatus === 'INVALID') {\n this._element.nativeElement.innerText = this.extractValidationMessages();\n }\n });\n }\n\n ngOnDestroy(): void {\n if (this._controlSubscription) {\n this._controlSubscription.unsubscribe();\n }\n }\n\n private extractValidationMessages(): string {\n if (!this.control.errors) {\n return '';\n }\n const errorsString = this._config.validationMessages\n .map(validationMessage => this.control.errors[validationMessage.name]\n ? typeof(validationMessage.message) === 'string'\n ? validationMessage.message : validationMessage.message(this.control)\n : ''\n )\n .filter(message => message !== '')\n .join(', ');\n\n const serverErrors = this.control.errors[FORM_FIELD_ERROR_KEY];\n const serverErrorsString = serverErrors instanceof Array ? serverErrors.join(', ') : '';\n\n return [errorsString, serverErrorsString].filter(x => x !== '').join(', ');\n }\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { EntryFormErrorsComponent } from './entry-form-errors.component';\nimport { MatInputModule } from '@angular/material/input';\nimport { EntryDisplayControlValidationDirective } from './entry-display-control-validation.directive';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\n\n@NgModule({\n declarations: [\n EntryFormErrorsComponent,\n EntryDisplayControlValidationDirective\n ],\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n MatInputModule\n ],\n exports: [\n EntryFormErrorsComponent,\n EntryDisplayControlValidationDirective\n ]\n})\nexport class EntryValidationModule { }\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -5,10 +5,10 @@ import { CommonModule } from '@angular/common';
|
|
|
5
5
|
class EntryHeaderComponent {
|
|
6
6
|
}
|
|
7
7
|
EntryHeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8
|
-
EntryHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: EntryHeaderComponent, selector: "entry-header", inputs: { title: "title" }, ngImport: i0, template: "<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"
|
|
8
|
+
EntryHeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: EntryHeaderComponent, selector: "entry-header", inputs: { title: "title" }, ngImport: i0, template: "<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"title item\">{{title}}</h1>\n <ng-content select=\"[buttons]\"></ng-content>\n </div>\n <div class=\"row content\">\n <ng-content select=\"[content]\"></ng-content>\n </div>\n</header>", styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
9
9
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryHeaderComponent, decorators: [{
|
|
10
10
|
type: Component,
|
|
11
|
-
args: [{ selector: 'entry-header', changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"
|
|
11
|
+
args: [{ selector: 'entry-header', changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"title item\">{{title}}</h1>\n <ng-content select=\"[buttons]\"></ng-content>\n </div>\n <div class=\"row content\">\n <ng-content select=\"[content]\"></ng-content>\n </div>\n</header>" }]
|
|
12
12
|
}], propDecorators: { title: [{
|
|
13
13
|
type: Input
|
|
14
14
|
}] } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enigmatry-entry-components-header.mjs","sources":["../../../../libs/entry-components/header/entry-header.component.ts","../../../../libs/entry-components/header/entry-header.component.html","../../../../libs/entry-components/header/entry-header.module.ts","../../../../libs/entry-components/header/enigmatry-entry-components-header.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\n\n@Component({\n selector: 'entry-header',\n templateUrl: './entry-header.component.html',\n styleUrls: ['./entry-header.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class EntryHeaderComponent {\n @Input() title: string;\n}\n","<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"
|
|
1
|
+
{"version":3,"file":"enigmatry-entry-components-header.mjs","sources":["../../../../libs/entry-components/header/entry-header.component.ts","../../../../libs/entry-components/header/entry-header.component.html","../../../../libs/entry-components/header/entry-header.module.ts","../../../../libs/entry-components/header/enigmatry-entry-components-header.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\n\n@Component({\n selector: 'entry-header',\n templateUrl: './entry-header.component.html',\n styleUrls: ['./entry-header.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class EntryHeaderComponent {\n @Input() title: string;\n}\n","<header class=\"entry-header\">\n <div class=\"space-between\">\n <h1 class=\"title item\">{{title}}</h1>\n <ng-content select=\"[buttons]\"></ng-content>\n </div>\n <div class=\"row content\">\n <ng-content select=\"[content]\"></ng-content>\n </div>\n</header>","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { EntryHeaderComponent } from './entry-header.component';\n\n@NgModule({\n declarations: [\n EntryHeaderComponent\n ],\n imports: [\n CommonModule\n ],\n exports: [\n EntryHeaderComponent\n ]\n})\nexport class EntryHeaderModule { }\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;MAQa,oBAAoB,CAAA;;iHAApB,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAApB,oBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,oBAAoB,gFCRjC,qRAQS,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;2FDAI,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBANhC,SAAS;+BACE,cAAc,EAAA,eAAA,EAGP,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,qRAAA,EAAA,CAAA;8BAGtC,KAAK,EAAA,CAAA;sBAAb,KAAK;;;MEMK,iBAAiB,CAAA;;8GAAjB,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;AAAjB,iBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,EAT1B,YAAA,EAAA,CAAA,oBAAoB,CAGpB,EAAA,OAAA,EAAA,CAAA,YAAY,aAGZ,oBAAoB,CAAA,EAAA,CAAA,CAAA;AAGX,iBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,YAN1B,YAAY,CAAA,EAAA,CAAA,CAAA;2FAMH,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAX7B,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,YAAY,EAAE;wBACZ,oBAAoB;AACrB,qBAAA;AACD,oBAAA,OAAO,EAAE;wBACP,YAAY;AACb,qBAAA;AACD,oBAAA,OAAO,EAAE;wBACP,oBAAoB;AACrB,qBAAA;AACF,iBAAA,CAAA;;;ACdD;;AAEG;;;;"}
|
|
@@ -7,22 +7,34 @@ import { FormGroup, FormArray, FormsModule, ReactiveFormsModule } from '@angular
|
|
|
7
7
|
import { MatInputModule } from '@angular/material/input';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* A component used to display
|
|
11
|
-
*
|
|
12
|
-
* This component will list validation errors one after another, each in separate row.
|
|
10
|
+
* A component used to display generic (form level) server side validation messages.
|
|
11
|
+
* The messages are displayed as a list, each message in a new row.
|
|
13
12
|
*
|
|
14
13
|
* @example
|
|
15
14
|
* ```html
|
|
16
|
-
* <entry-form-errors [form]="myForm"
|
|
15
|
+
* <entry-form-errors [form]="myForm">
|
|
16
|
+
* </entry-form-errors>
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
class EntryFormErrorsComponent {
|
|
20
20
|
}
|
|
21
21
|
EntryFormErrorsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryFormErrorsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
22
|
-
EntryFormErrorsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: EntryFormErrorsComponent, selector: "entry-form-errors", inputs: { form: "form" }, ngImport: i0, template:
|
|
22
|
+
EntryFormErrorsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: EntryFormErrorsComponent, selector: "entry-form-errors", inputs: { form: "form" }, ngImport: i0, template: `
|
|
23
|
+
<div *ngIf="form.errors">
|
|
24
|
+
<mat-error *ngFor="let error of form.errors.general">{{error}}</mat-error>
|
|
25
|
+
</div>
|
|
26
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.MatError, selector: "mat-error", inputs: ["id"] }], changeDetection: i0.ChangeDetectionStrategy.Default });
|
|
23
27
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryFormErrorsComponent, decorators: [{
|
|
24
28
|
type: Component,
|
|
25
|
-
args: [{
|
|
29
|
+
args: [{
|
|
30
|
+
selector: 'entry-form-errors',
|
|
31
|
+
template: `
|
|
32
|
+
<div *ngIf="form.errors">
|
|
33
|
+
<mat-error *ngFor="let error of form.errors.general">{{error}}</mat-error>
|
|
34
|
+
</div>
|
|
35
|
+
`,
|
|
36
|
+
changeDetection: ChangeDetectionStrategy.Default
|
|
37
|
+
}]
|
|
26
38
|
}], propDecorators: { form: [{
|
|
27
39
|
type: Input
|
|
28
40
|
}] } });
|
|
@@ -67,10 +79,10 @@ const getFormControl = (formControl, keys) => {
|
|
|
67
79
|
* Applies validation errors received from server side to the form.
|
|
68
80
|
* The errors are applied to multiple levels: form, form group, form array, and form field.
|
|
69
81
|
*
|
|
70
|
-
* @param form Form to apply validation errors to.
|
|
71
82
|
* @param error Server side validation errors response.
|
|
83
|
+
* @param form Form to apply validation errors to.
|
|
72
84
|
*/
|
|
73
|
-
const
|
|
85
|
+
const setServerSideValidationErrors = (error, form) => {
|
|
74
86
|
form.setErrors(null);
|
|
75
87
|
const validationErrors = error?.errors;
|
|
76
88
|
const formErrors = {};
|
|
@@ -96,6 +108,16 @@ const handleValidationProblemDetails = (form, error) => {
|
|
|
96
108
|
form.setErrors(formErrors);
|
|
97
109
|
};
|
|
98
110
|
|
|
111
|
+
/**
|
|
112
|
+
* A directive that displays configured validation messages or server side validations for given form control.
|
|
113
|
+
* The messages are separated with coma(,) and displayed as _innerHTML_ value of host component.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```html
|
|
117
|
+
* <div entryDisplayControlValidation [control]="myForm.controls.firstName">
|
|
118
|
+
* </div
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
99
121
|
class EntryDisplayControlValidationDirective {
|
|
100
122
|
constructor(_config, _element) {
|
|
101
123
|
this._config = _config;
|
|
@@ -181,5 +203,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
181
203
|
* Generated bundle index. Do not edit.
|
|
182
204
|
*/
|
|
183
205
|
|
|
184
|
-
export { ENTRY_VALIDATION_CONFIG, EntryDisplayControlValidationDirective, EntryFormErrorsComponent, EntryValidationConfig, EntryValidationModule, FORM_FIELD_ERROR_KEY,
|
|
206
|
+
export { ENTRY_VALIDATION_CONFIG, EntryDisplayControlValidationDirective, EntryFormErrorsComponent, EntryValidationConfig, EntryValidationModule, FORM_FIELD_ERROR_KEY, setServerSideValidationErrors };
|
|
185
207
|
//# sourceMappingURL=enigmatry-entry-components-validation.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enigmatry-entry-components-validation.mjs","sources":["../../../../libs/entry-components/validation/entry-form-errors.component.ts","../../../../libs/entry-components/validation/entry-form-errors.component.html","../../../../libs/entry-components/validation/entry-validation-config.model.ts","../../../../libs/entry-components/validation/entry-validation.ts","../../../../libs/entry-components/validation/entry-display-control-validation.directive.ts","../../../../libs/entry-components/validation/entry-validation.module.ts","../../../../libs/entry-components/validation/enigmatry-entry-components-validation.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { UntypedFormGroup } from '@angular/forms';\n\n/**\n * A component used to display back-end validation errors on form level (errors that are not connected to the specific form field).\n *\n * This component will list validation errors one after another, each in separate row.\n *\n * @example\n * ```html\n * <entry-form-errors [form]=\"myForm\"></entry-form-errors>\n * ```\n */\n@Component({\n selector: 'entry-form-errors',\n templateUrl: './entry-form-errors.component.html',\n styleUrls: ['./entry-form-errors.component.scss'],\n changeDetection: ChangeDetectionStrategy.Default\n})\nexport class EntryFormErrorsComponent {\n @Input() form: UntypedFormGroup;\n}\n","<div *ngIf=\"form.errors\">\n <mat-error *ngFor=\"let error of form.errors.general\">{{error}}</mat-error>\n</div>","import { InjectionToken } from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\n\n/** Validation message configuration */\nexport interface IEntryValidationMessage {\n // Validation key\n name: string;\n // Validation message. Can be resolved dynamically (e.g. when it needs to be translated).\n message: string | ((c: AbstractControl) => string);\n}\n\n/**\n * Used to provide default configurations on module level.\n */\nexport class EntryValidationConfig {\n /** Validation key to message configuration on module level. */\n validationMessages: IEntryValidationMessage[];\n\n constructor(config: Partial<EntryValidationConfig> = {}) {\n this.validationMessages = config.validationMessages ?? [];\n }\n}\n\n/**\n * Entry validation injection token of EntryValidationConfig type containing validation default configurations.\n * Can be updated with custom configuration.\n *\n * Defaults:\n * - validationMessages: []\n */\nexport const ENTRY_VALIDATION_CONFIG = new InjectionToken<EntryValidationConfig>(\n 'EntryValidationConfig',\n {\n providedIn: 'root',\n factory: () => new EntryValidationConfig()\n }\n);\n","import { AbstractControl, FormArray, FormGroup, UntypedFormGroup, ValidationErrors } from '@angular/forms';\nimport { IValidationProblemDetails } from './validation-problem-details.interface';\n\n/** A key used to map server side validation errors on form level */\nconst FORM_ERROR_KEY = 'general';\n/** A key used to map server side validation errors on form field level */\nconst FORM_FIELD_ERROR_KEY = 'fromServer';\n\nconst getFormControl = (formControl: AbstractControl | null | undefined, keys: string[]): AbstractControl | null | undefined => {\n if (keys.length === 0) {\n return formControl;\n }\n if (formControl instanceof FormGroup) {\n return getFormControl(formControl.controls[keys[0].charAt(0).toLowerCase() + keys[0].slice(1)], keys.slice(1));\n }\n if (formControl instanceof FormArray && +keys[0] >= 0) {\n return getFormControl(formControl.controls[+keys[0]], keys.slice(1));\n }\n return null;\n};\n\n/**\n * Applies validation errors received from server side to the form.\n * The errors are applied to multiple levels: form, form group, form array, and form field.\n *\n * @param form Form to apply validation errors to.\n * @param error Server side validation errors response.\n */\nconst handleValidationProblemDetails = (form: UntypedFormGroup, error: IValidationProblemDetails) => {\n form.setErrors(null);\n const validationErrors = error?.errors;\n const formErrors: ValidationErrors = {};\n\n if (validationErrors) {\n // eslint-disable-next-line guard-for-in\n for (const key in validationErrors) {\n const control = getFormControl(form, key.split(/[.[\\]]+/gu));\n\n if (control) {\n const fieldErrors = {} as ValidationErrors;\n fieldErrors[FORM_FIELD_ERROR_KEY] = validationErrors[key];\n control.setErrors(fieldErrors);\n control.markAsTouched();\n } else {\n formErrors[FORM_ERROR_KEY] =\n formErrors[FORM_ERROR_KEY]?.concat(validationErrors[key]) || validationErrors[key];\n }\n }\n } else {\n formErrors[FORM_ERROR_KEY] = [ `An error occurred on the server.` ];\n }\n\n form.setErrors(formErrors);\n};\n\nexport {\n FORM_FIELD_ERROR_KEY,\n handleValidationProblemDetails\n};\n","import { Directive, ElementRef, Inject, Input, OnDestroy, OnInit } from '@angular/core';\nimport { ENTRY_VALIDATION_CONFIG, EntryValidationConfig } from './entry-validation-config.model';\nimport { AbstractControl, FormControlStatus } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport { FORM_FIELD_ERROR_KEY } from './entry-validation';\n\n@Directive({\n selector: '[entryDisplayControlValidation]'\n})\nexport class EntryDisplayControlValidationDirective implements OnInit, OnDestroy {\n @Input() control: AbstractControl;\n\n private _controlSubscription: Subscription | undefined;\n\n constructor(\n @Inject(ENTRY_VALIDATION_CONFIG) private readonly _config: EntryValidationConfig,\n private readonly _element: ElementRef) {}\n\n ngOnInit(): void {\n this._controlSubscription = this.control.statusChanges\n .subscribe((controlStatus: FormControlStatus) => {\n if (controlStatus === 'INVALID') {\n this._element.nativeElement.innerText = this.extractValidationMessages();\n }\n });\n }\n\n ngOnDestroy(): void {\n if (this._controlSubscription) {\n this._controlSubscription.unsubscribe();\n }\n }\n\n private extractValidationMessages(): string {\n if (!this.control.errors) {\n return '';\n }\n const errorsString = this._config.validationMessages\n .map(validationMessage => this.control.errors[validationMessage.name]\n ? typeof(validationMessage.message) === 'string'\n ? validationMessage.message : validationMessage.message(this.control)\n : ''\n )\n .filter(message => message !== '')\n .join(', ');\n\n const serverErrors = this.control.errors[FORM_FIELD_ERROR_KEY];\n const serverErrorsString = serverErrors instanceof Array ? serverErrors.join(', ') : '';\n\n return [errorsString, serverErrorsString].filter(x => x !== '').join(', ');\n }\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { EntryFormErrorsComponent } from './entry-form-errors.component';\nimport { MatInputModule } from '@angular/material/input';\nimport { EntryDisplayControlValidationDirective } from './entry-display-control-validation.directive';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\n\n@NgModule({\n declarations: [\n EntryFormErrorsComponent,\n EntryDisplayControlValidationDirective\n ],\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n MatInputModule\n ],\n exports: [\n EntryFormErrorsComponent,\n EntryDisplayControlValidationDirective\n ]\n})\nexport class EntryValidationModule { }\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"enigmatry-entry-components-validation.mjs","sources":["../../../../libs/entry-components/validation/entry-form-errors.component.ts","../../../../libs/entry-components/validation/entry-validation-config.model.ts","../../../../libs/entry-components/validation/entry-validation.ts","../../../../libs/entry-components/validation/entry-display-control-validation.directive.ts","../../../../libs/entry-components/validation/entry-validation.module.ts","../../../../libs/entry-components/validation/enigmatry-entry-components-validation.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\nimport { UntypedFormGroup } from '@angular/forms';\n\n/**\n * A component used to display generic (form level) server side validation messages.\n * The messages are displayed as a list, each message in a new row.\n *\n * @example\n * ```html\n * <entry-form-errors [form]=\"myForm\">\n * </entry-form-errors>\n * ```\n */\n@Component({\n selector: 'entry-form-errors',\n template: `\n <div *ngIf=\"form.errors\">\n <mat-error *ngFor=\"let error of form.errors.general\">{{error}}</mat-error>\n </div>\n `,\n changeDetection: ChangeDetectionStrategy.Default\n})\nexport class EntryFormErrorsComponent {\n /** A form group for which the validation errors are being displayed. */\n @Input() form: UntypedFormGroup;\n}\n","import { InjectionToken } from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\n\n/** Used to configure mapping between validation keys and messages */\nexport interface IEntryValidationMessage {\n /** Validation key (e.g. '_required_', '_minlength_', '_email_', etc.) */\n name: string;\n /**\n * Validation message. Can be static string or expression returning string\n * (when messages need to be resolved dynamically: parametrization, localization, etc.).\n */\n message: string | ((control: AbstractControl) => string);\n}\n\n/**\n * Used to provide default configurations on module level.\n */\nexport class EntryValidationConfig {\n /**\n * Validation key to message configuration on module level. Used to configure client side validation messages\n * for standard validators (_required_, _minLength_, _email_, etc.).\n *\n * **NOTE:** If using _Formly_ package to render forms, this configuration should not be used.\n * Instead, use `FormlyModule` to configure validation messages.\n *\n * @example\n * ```ts\n * new EntryValidationConfig() {\n * validationMessages: [\n * { name: 'required': message: 'This field is mandatory' },\n * { name: 'minlength', message: (control: AbstractControl) => `Minimal length is ${control.errors.minlength.requiredLength}`}\n * ]\n * }\n * ```\n */\n validationMessages: IEntryValidationMessage[];\n\n constructor(config: Partial<EntryValidationConfig> = {}) {\n this.validationMessages = config.validationMessages ?? [];\n }\n}\n\n/**\n * Entry validation injection token of EntryValidationConfig type containing validation default configurations.\n * Can be updated with custom configuration.\n *\n * Defaults:\n * - validationMessages: []\n */\nexport const ENTRY_VALIDATION_CONFIG = new InjectionToken<EntryValidationConfig>(\n 'EntryValidationConfig',\n {\n providedIn: 'root',\n factory: () => new EntryValidationConfig()\n }\n);\n","import { AbstractControl, FormArray, FormGroup, UntypedFormGroup, ValidationErrors } from '@angular/forms';\nimport { IValidationProblemDetails } from './validation-problem-details.interface';\n\n/** A key used to map server side validation errors on form level */\nconst FORM_ERROR_KEY = 'general';\n/** A key used to map server side validation errors on form field level */\nconst FORM_FIELD_ERROR_KEY = 'fromServer';\n\nconst getFormControl = (formControl: AbstractControl | null | undefined, keys: string[]): AbstractControl | null | undefined => {\n if (keys.length === 0) {\n return formControl;\n }\n if (formControl instanceof FormGroup) {\n return getFormControl(formControl.controls[keys[0].charAt(0).toLowerCase() + keys[0].slice(1)], keys.slice(1));\n }\n if (formControl instanceof FormArray && +keys[0] >= 0) {\n return getFormControl(formControl.controls[+keys[0]], keys.slice(1));\n }\n return null;\n};\n\n/**\n * Applies validation errors received from server side to the form.\n * The errors are applied to multiple levels: form, form group, form array, and form field.\n *\n * @param error Server side validation errors response.\n * @param form Form to apply validation errors to.\n */\nconst setServerSideValidationErrors = (error: IValidationProblemDetails, form: UntypedFormGroup) => {\n form.setErrors(null);\n const validationErrors = error?.errors;\n const formErrors: ValidationErrors = {};\n\n if (validationErrors) {\n // eslint-disable-next-line guard-for-in\n for (const key in validationErrors) {\n const control = getFormControl(form, key.split(/[.[\\]]+/gu));\n\n if (control) {\n const fieldErrors = {} as ValidationErrors;\n fieldErrors[FORM_FIELD_ERROR_KEY] = validationErrors[key];\n control.setErrors(fieldErrors);\n control.markAsTouched();\n } else {\n formErrors[FORM_ERROR_KEY] =\n formErrors[FORM_ERROR_KEY]?.concat(validationErrors[key]) || validationErrors[key];\n }\n }\n } else {\n formErrors[FORM_ERROR_KEY] = [`An error occurred on the server.`];\n }\n\n form.setErrors(formErrors);\n};\n\nexport {\n FORM_FIELD_ERROR_KEY,\n setServerSideValidationErrors\n};\n","import { Directive, ElementRef, Inject, Input, OnDestroy, OnInit } from '@angular/core';\nimport { ENTRY_VALIDATION_CONFIG, EntryValidationConfig } from './entry-validation-config.model';\nimport { AbstractControl, FormControlStatus } from '@angular/forms';\nimport { Subscription } from 'rxjs';\nimport { FORM_FIELD_ERROR_KEY } from './entry-validation';\n\n/**\n * A directive that displays configured validation messages or server side validations for given form control.\n * The messages are separated with coma(,) and displayed as _innerHTML_ value of host component.\n *\n * @example\n * ```html\n * <div entryDisplayControlValidation [control]=\"myForm.controls.firstName\">\n * </div\n * ```\n */\n@Directive({\n selector: '[entryDisplayControlValidation]'\n})\nexport class EntryDisplayControlValidationDirective implements OnInit, OnDestroy {\n /** Form control for which the validation messages are displayed for. */\n @Input() control: AbstractControl;\n\n private _controlSubscription: Subscription | undefined;\n\n constructor(\n @Inject(ENTRY_VALIDATION_CONFIG) private readonly _config: EntryValidationConfig,\n private readonly _element: ElementRef) {}\n\n ngOnInit(): void {\n this._controlSubscription = this.control.statusChanges\n .subscribe((controlStatus: FormControlStatus) => {\n if (controlStatus === 'INVALID') {\n this._element.nativeElement.innerText = this.extractValidationMessages();\n }\n });\n }\n\n ngOnDestroy(): void {\n if (this._controlSubscription) {\n this._controlSubscription.unsubscribe();\n }\n }\n\n private extractValidationMessages(): string {\n if (!this.control.errors) {\n return '';\n }\n const errorsString = this._config.validationMessages\n .map(validationMessage => this.control.errors[validationMessage.name]\n ? typeof(validationMessage.message) === 'string'\n ? validationMessage.message : validationMessage.message(this.control)\n : ''\n )\n .filter(message => message !== '')\n .join(', ');\n\n const serverErrors = this.control.errors[FORM_FIELD_ERROR_KEY];\n const serverErrorsString = serverErrors instanceof Array ? serverErrors.join(', ') : '';\n\n return [errorsString, serverErrorsString].filter(x => x !== '').join(', ');\n }\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { EntryFormErrorsComponent } from './entry-form-errors.component';\nimport { MatInputModule } from '@angular/material/input';\nimport { EntryDisplayControlValidationDirective } from './entry-display-control-validation.directive';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\n\n@NgModule({\n declarations: [\n EntryFormErrorsComponent,\n EntryDisplayControlValidationDirective\n ],\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n MatInputModule\n ],\n exports: [\n EntryFormErrorsComponent,\n EntryDisplayControlValidationDirective\n ]\n})\nexport class EntryValidationModule { }\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
@use '../../../../../styles/modules/states/hover';
|
|
3
3
|
|
|
4
4
|
@mixin generate-buttons-from($theme) {
|
|
5
|
-
.button-primary {
|
|
5
|
+
.entry-button-primary {
|
|
6
6
|
@include hover.background-hover(
|
|
7
|
-
map.value-from($theme, 'button-primary.default-background'),
|
|
7
|
+
map.value-from($theme, 'button-primary.default-background'),
|
|
8
8
|
map.value-from($theme, 'button-primary.hover-background'));
|
|
9
9
|
color: map.value-from($theme, 'button-primary.default-font-color');
|
|
10
10
|
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
.button-accent {
|
|
16
|
+
.entry-button-accent {
|
|
17
17
|
@include hover.background-hover(
|
|
18
|
-
map.value-from($theme, 'button-accent.default-background'),
|
|
18
|
+
map.value-from($theme, 'button-accent.default-background'),
|
|
19
19
|
map.value-from($theme, 'button-accent.hover-background'));
|
|
20
20
|
color: map.value-from($theme, 'button-accent.default-font-color');
|
|
21
21
|
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
background-color: map.value-from($theme, 'header.background');
|
|
7
7
|
|
|
8
8
|
.title {
|
|
9
|
-
font-size: map.value-from($theme, 'header.title
|
|
9
|
+
font-size: map.value-from($theme, 'header.title.size');
|
|
10
|
+
color: map.value-from($theme, 'header.title.color');
|
|
10
11
|
}
|
|
11
12
|
}
|
|
12
13
|
}
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
background-color: transparent;
|
|
12
12
|
color: vars.$font-color-light;
|
|
13
13
|
line-height: 1.25;
|
|
14
|
-
cursor: pointer;
|
|
15
14
|
text: {
|
|
16
15
|
align: center;
|
|
17
16
|
decoration: none;
|
|
@@ -28,16 +27,16 @@
|
|
|
28
27
|
}
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
.button-primary, .button-accent {
|
|
30
|
+
.entry-button-primary, .entry-button-accent {
|
|
32
31
|
@extend %button;
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
.action-buttons {
|
|
36
|
-
.
|
|
35
|
+
.button {
|
|
37
36
|
margin-left: 12px;
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
|
|
38
|
+
.first-button {
|
|
40
39
|
margin-left: 0;
|
|
41
40
|
}
|
|
42
41
|
}
|
|
43
|
-
}
|
|
42
|
+
}
|
|
@@ -1,25 +1,9 @@
|
|
|
1
1
|
@use '../../../../../../styles/modules/variables' as vars;
|
|
2
|
-
// @use '../../../../../../styles/modules/breakpoints' as breakpoints;
|
|
3
2
|
|
|
4
3
|
.entry-header {
|
|
5
|
-
padding:
|
|
6
|
-
|
|
7
|
-
// @include breakpoints.apply-on-tablet() {
|
|
8
|
-
// padding: {
|
|
9
|
-
// top: vars.$default-gap;
|
|
10
|
-
// bottom: vars.$large-gap;
|
|
11
|
-
// };
|
|
12
|
-
// }
|
|
13
|
-
|
|
14
|
-
.header-item {
|
|
15
|
-
margin-top: 20px;
|
|
16
|
-
}
|
|
4
|
+
padding: 24px vars.$default-gap;
|
|
17
5
|
|
|
18
6
|
.content {
|
|
19
7
|
padding-top: 20px;
|
|
20
|
-
|
|
21
|
-
// @include breakpoints.apply-on-tablet() {
|
|
22
|
-
// padding-top: vars.$large-gap;
|
|
23
|
-
// }
|
|
24
8
|
}
|
|
25
9
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enigmatry/entry-components",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.9",
|
|
4
4
|
"author": "Enigmatry",
|
|
5
5
|
"description": "Enigmatry entry angular material components",
|
|
6
6
|
"homepage": "https://github.com/enigmatry/entry-angular-building-blocks/tree/master/libs/entry-components#readme",
|
package/validation/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Entry Validation
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Enables configuring forms (Reactive or [Formly](https://formly.dev/) forms) so that server or client side validation errors are displayed correctly. To accomplish this, it offers the following features:
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* `<entry-form-errors>`
|
|
8
|
-
*
|
|
5
|
+
* `setServerSideValidationErrors(error, form)` - a method that maps received server side validation errors to the form and its fields.
|
|
6
|
+
* `entryDisplayControlValidation` - a directive that displays field level validation errors.
|
|
7
|
+
* `<entry-form-errors>` - a component that displays form level validation errors.
|
|
8
|
+
* `ENTRY_VALIDATION_CONFIG` - configuration provider used to configure default client side validation messages on module level.
|
|
9
9
|
|
|
10
10
|
## Imports
|
|
11
11
|
|
|
@@ -25,61 +25,81 @@ Where `APP_THEME` represents application theming configuration, while `APP_TYPOG
|
|
|
25
25
|
|
|
26
26
|
## Basic usage
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Reactive form example with configured validation components (`entryDisplayControlValidation` & `<entry-form-errors>`):
|
|
29
29
|
|
|
30
|
-
```
|
|
31
|
-
|
|
30
|
+
```html
|
|
31
|
+
<form [formGroup]="form" (ngSubmit)="submitForm()">
|
|
32
|
+
<mat-form-field class="example-form-field">
|
|
33
|
+
<mat-label>First name</mat-label>
|
|
34
|
+
<input matInput type="text" formControlName="firstName">
|
|
35
|
+
<mat-error entryDisplayControlValidation [control]="form.controls.firstName"></mat-error>
|
|
36
|
+
</mat-form-field>
|
|
32
37
|
|
|
33
|
-
|
|
38
|
+
<entry-form-errors [form]="form"></entry-form-errors>
|
|
34
39
|
|
|
35
|
-
|
|
36
|
-
|
|
40
|
+
<button mat-flat-button color="accent" type="submit">Submit</button>
|
|
41
|
+
</form>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
On submit, in case of _BadRequest (400)_ errors, response must be handled using `setServerSideValidationErrors(error, form)` method:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { IValidationProblemDetails, setServerSideValidationErrors } from '@enigmatry/entry-components/validation';
|
|
37
48
|
|
|
38
49
|
// ...
|
|
50
|
+
submitForm() {
|
|
51
|
+
this._apiService.post()
|
|
52
|
+
.subscribe({
|
|
53
|
+
error: (error: IValidationProblemDetails) => setServerSideValidationErrors(error, this.form)
|
|
54
|
+
});
|
|
55
|
+
}
|
|
39
56
|
```
|
|
40
57
|
|
|
41
|
-
|
|
58
|
+
## Configuration
|
|
42
59
|
|
|
43
|
-
|
|
44
|
-
import { EntryValidationModule, FORM_FIELD_ERROR_KEY } from '@enigmatry/entry-components';
|
|
45
|
-
import { FormlyModule } from '@ngx-formly/core';
|
|
46
|
-
import { FormlyMaterialModule } from '@ngx-formly/material';
|
|
60
|
+
Optionally, when using Reactive form we can configure validation messages on module level for form validators in use:
|
|
47
61
|
|
|
62
|
+
```ts
|
|
48
63
|
// ...
|
|
64
|
+
import { AbstractControl } from '@angular/forms';
|
|
65
|
+
import { ENTRY_VALIDATION_CONFIG, EntryValidationConfig, EntryValidationModule } from '@enigmatry/entry-components/validation';
|
|
49
66
|
|
|
50
67
|
@NgModule({
|
|
68
|
+
imports: [
|
|
51
69
|
// ...
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
70
|
+
EntryValidationModule
|
|
71
|
+
]
|
|
72
|
+
providers: [
|
|
73
|
+
{
|
|
74
|
+
provide: ENTRY_VALIDATION_CONFIG,
|
|
75
|
+
useFactory: () => new EntryValidationConfig({
|
|
56
76
|
validationMessages: [
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
77
|
+
{ name: 'required', message: 'This field is mandatory!' },
|
|
78
|
+
{ name: 'minlength', message: (control: AbstractControl) => `Minimal length is ${control.errors.minlength.requiredLength}!`}
|
|
79
|
+
]
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
]
|
|
61
83
|
})
|
|
62
84
|
export class AppModule { }
|
|
63
85
|
```
|
|
64
86
|
|
|
65
|
-
|
|
87
|
+
## Microsoft WEB.API & NSwag configuration
|
|
66
88
|
|
|
67
|
-
|
|
68
|
-
<app-g-product-edit #editComponent [model]="model"></app-g-product-edit>
|
|
69
|
-
<!-- Renders form level server side validation errors -->
|
|
70
|
-
<entry-form-errors [form]="form"></entry-form-errors>
|
|
71
|
-
```
|
|
89
|
+
To configure your REST API (_Microsoft WEB.API_) so it returns _Bad Request_ response in uniform format we should decorate all end-points that trigger validation with `ProducesResponseType` attribute that maps [ValidationProblemDetails](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.validationproblemdetails?view=aspnetcore-7.0) to _Bad Request_ responses:
|
|
72
90
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
```ts
|
|
76
|
-
import { IValidationProblemDetails, handleValidationProblemDetails } from '@enigmatry/entry-components';
|
|
91
|
+
```csharp
|
|
92
|
+
using Microsoft.AspNetCore.Mvc;
|
|
77
93
|
|
|
78
94
|
// ...
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
95
|
+
|
|
96
|
+
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
|
97
|
+
public async Task<ActionResult<Response>> Post([FromBody] Command command)
|
|
98
|
+
{
|
|
99
|
+
// ...
|
|
84
100
|
}
|
|
85
101
|
```
|
|
102
|
+
|
|
103
|
+
When set like this, we can generate, using [NSwag](https://github.com/RicoSuter/NSwag), client side models for _Bad Request_ responses, that can be then used with `setServerSideValidationErrors(error, form)` method as input parameter.
|
|
104
|
+
|
|
105
|
+
This is because we based our `IValidationProblemDetails` interface on [ValidationProblemDetails](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.validationproblemdetails?view=aspnetcore-7.0) class.
|
|
@@ -2,9 +2,20 @@ import { ElementRef, OnDestroy, OnInit } from '@angular/core';
|
|
|
2
2
|
import { EntryValidationConfig } from './entry-validation-config.model';
|
|
3
3
|
import { AbstractControl } from '@angular/forms';
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
* A directive that displays configured validation messages or server side validations for given form control.
|
|
7
|
+
* The messages are separated with coma(,) and displayed as _innerHTML_ value of host component.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```html
|
|
11
|
+
* <div entryDisplayControlValidation [control]="myForm.controls.firstName">
|
|
12
|
+
* </div
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
5
15
|
export declare class EntryDisplayControlValidationDirective implements OnInit, OnDestroy {
|
|
6
16
|
private readonly _config;
|
|
7
17
|
private readonly _element;
|
|
18
|
+
/** Form control for which the validation messages are displayed for. */
|
|
8
19
|
control: AbstractControl;
|
|
9
20
|
private _controlSubscription;
|
|
10
21
|
constructor(_config: EntryValidationConfig, _element: ElementRef);
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { UntypedFormGroup } from '@angular/forms';
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
3
|
/**
|
|
4
|
-
* A component used to display
|
|
5
|
-
*
|
|
6
|
-
* This component will list validation errors one after another, each in separate row.
|
|
4
|
+
* A component used to display generic (form level) server side validation messages.
|
|
5
|
+
* The messages are displayed as a list, each message in a new row.
|
|
7
6
|
*
|
|
8
7
|
* @example
|
|
9
8
|
* ```html
|
|
10
|
-
* <entry-form-errors [form]="myForm"
|
|
9
|
+
* <entry-form-errors [form]="myForm">
|
|
10
|
+
* </entry-form-errors>
|
|
11
11
|
* ```
|
|
12
12
|
*/
|
|
13
13
|
export declare class EntryFormErrorsComponent {
|
|
14
|
+
/** A form group for which the validation errors are being displayed. */
|
|
14
15
|
form: UntypedFormGroup;
|
|
15
16
|
static ɵfac: i0.ɵɵFactoryDeclaration<EntryFormErrorsComponent, never>;
|
|
16
17
|
static ɵcmp: i0.ɵɵComponentDeclaration<EntryFormErrorsComponent, "entry-form-errors", never, { "form": "form"; }, {}, never, never, false>;
|
|
@@ -1,15 +1,36 @@
|
|
|
1
1
|
import { InjectionToken } from '@angular/core';
|
|
2
2
|
import { AbstractControl } from '@angular/forms';
|
|
3
|
-
/**
|
|
3
|
+
/** Used to configure mapping between validation keys and messages */
|
|
4
4
|
export interface IEntryValidationMessage {
|
|
5
|
+
/** Validation key (e.g. '_required_', '_minlength_', '_email_', etc.) */
|
|
5
6
|
name: string;
|
|
6
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Validation message. Can be static string or expression returning string
|
|
9
|
+
* (when messages need to be resolved dynamically: parametrization, localization, etc.).
|
|
10
|
+
*/
|
|
11
|
+
message: string | ((control: AbstractControl) => string);
|
|
7
12
|
}
|
|
8
13
|
/**
|
|
9
14
|
* Used to provide default configurations on module level.
|
|
10
15
|
*/
|
|
11
16
|
export declare class EntryValidationConfig {
|
|
12
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Validation key to message configuration on module level. Used to configure client side validation messages
|
|
19
|
+
* for standard validators (_required_, _minLength_, _email_, etc.).
|
|
20
|
+
*
|
|
21
|
+
* **NOTE:** If using _Formly_ package to render forms, this configuration should not be used.
|
|
22
|
+
* Instead, use `FormlyModule` to configure validation messages.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* new EntryValidationConfig() {
|
|
27
|
+
* validationMessages: [
|
|
28
|
+
* { name: 'required': message: 'This field is mandatory' },
|
|
29
|
+
* { name: 'minlength', message: (control: AbstractControl) => `Minimal length is ${control.errors.minlength.requiredLength}`}
|
|
30
|
+
* ]
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
13
34
|
validationMessages: IEntryValidationMessage[];
|
|
14
35
|
constructor(config?: Partial<EntryValidationConfig>);
|
|
15
36
|
}
|
|
@@ -6,8 +6,8 @@ declare const FORM_FIELD_ERROR_KEY = "fromServer";
|
|
|
6
6
|
* Applies validation errors received from server side to the form.
|
|
7
7
|
* The errors are applied to multiple levels: form, form group, form array, and form field.
|
|
8
8
|
*
|
|
9
|
-
* @param form Form to apply validation errors to.
|
|
10
9
|
* @param error Server side validation errors response.
|
|
10
|
+
* @param form Form to apply validation errors to.
|
|
11
11
|
*/
|
|
12
|
-
declare const
|
|
13
|
-
export { FORM_FIELD_ERROR_KEY,
|
|
12
|
+
declare const setServerSideValidationErrors: (error: IValidationProblemDetails, form: UntypedFormGroup) => void;
|
|
13
|
+
export { FORM_FIELD_ERROR_KEY, setServerSideValidationErrors };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Defines the api
|
|
3
|
-
* which used as a container for server side validation errors.
|
|
2
|
+
* Defines the api used as a container for server side validation errors.
|
|
4
3
|
*/
|
|
5
4
|
export interface IValidationProblemDetails {
|
|
6
5
|
[key: string]: any;
|