@enigmatry/entry-components 1.14.6 → 1.14.8

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.
Files changed (38) hide show
  1. package/esm2020/header/entry-header.component.mjs +3 -3
  2. package/esm2020/public-api.mjs +2 -1
  3. package/esm2020/validation/enigmatry-entry-components-validation.mjs +5 -0
  4. package/esm2020/validation/entry-display-control-validation.directive.mjs +53 -0
  5. package/esm2020/validation/entry-form-errors.component.mjs +25 -0
  6. package/esm2020/validation/entry-validation-config.model.mjs +21 -0
  7. package/esm2020/validation/entry-validation.mjs +51 -0
  8. package/esm2020/validation/entry-validation.module.mjs +40 -0
  9. package/esm2020/validation/public-api.mjs +6 -0
  10. package/esm2020/validation/validation-problem-details.interface.mjs +2 -0
  11. package/fesm2015/enigmatry-entry-components-header.mjs +2 -2
  12. package/fesm2015/enigmatry-entry-components-header.mjs.map +1 -1
  13. package/fesm2015/enigmatry-entry-components-validation.mjs +189 -0
  14. package/fesm2015/enigmatry-entry-components-validation.mjs.map +1 -0
  15. package/fesm2015/enigmatry-entry-components.mjs +1 -0
  16. package/fesm2015/enigmatry-entry-components.mjs.map +1 -1
  17. package/fesm2020/enigmatry-entry-components-header.mjs +2 -2
  18. package/fesm2020/enigmatry-entry-components-header.mjs.map +1 -1
  19. package/fesm2020/enigmatry-entry-components-validation.mjs +185 -0
  20. package/fesm2020/enigmatry-entry-components-validation.mjs.map +1 -0
  21. package/fesm2020/enigmatry-entry-components.mjs +1 -0
  22. package/fesm2020/enigmatry-entry-components.mjs.map +1 -1
  23. package/header/styles/modules/components/buttons/_general.scss +4 -4
  24. package/header/styles/modules/components/headers/_general.scss +2 -1
  25. package/header/styles/modules/theming/_default-theming.scss +1 -0
  26. package/header/styles/partials/core/components/buttons/_general.scss +5 -6
  27. package/header/styles/partials/core/components/headers/_general.scss +1 -17
  28. package/package.json +9 -1
  29. package/public-api.d.ts +1 -0
  30. package/validation/README.md +85 -0
  31. package/validation/entry-display-control-validation.directive.d.ts +16 -0
  32. package/validation/entry-form-errors.component.d.ts +17 -0
  33. package/validation/entry-validation-config.model.d.ts +23 -0
  34. package/validation/entry-validation.d.ts +13 -0
  35. package/validation/entry-validation.module.d.ts +11 -0
  36. package/validation/index.d.ts +5 -0
  37. package/validation/public-api.d.ts +6 -0
  38. package/validation/validation-problem-details.interface.d.ts +10 -0
@@ -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=\"header-item title\">{{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 });
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=\"header-item title\">{{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>" }]
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50cnktaGVhZGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvZW50cnktY29tcG9uZW50cy9oZWFkZXIvZW50cnktaGVhZGVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL2xpYnMvZW50cnktY29tcG9uZW50cy9oZWFkZXIvZW50cnktaGVhZGVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQVExRSxNQUFNLE9BQU8sb0JBQW9COztpSEFBcEIsb0JBQW9CO3FHQUFwQixvQkFBb0IsZ0ZDUmpDLDRSQVFTOzJGREFJLG9CQUFvQjtrQkFOaEMsU0FBUzsrQkFDRSxjQUFjLG1CQUdQLHVCQUF1QixDQUFDLE1BQU07OEJBR3RDLEtBQUs7c0JBQWIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2VudHJ5LWhlYWRlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9lbnRyeS1oZWFkZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9lbnRyeS1oZWFkZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgRW50cnlIZWFkZXJDb21wb25lbnQge1xuICBASW5wdXQoKSB0aXRsZTogc3RyaW5nO1xufVxuIiwiPGhlYWRlciBjbGFzcz1cImVudHJ5LWhlYWRlclwiPlxuICA8ZGl2IGNsYXNzPVwic3BhY2UtYmV0d2VlblwiPlxuICAgIDxoMSBjbGFzcz1cImhlYWRlci1pdGVtIHRpdGxlXCI+e3t0aXRsZX19PC9oMT5cbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbYnV0dG9uc11cIj48L25nLWNvbnRlbnQ+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwicm93IGNvbnRlbnRcIj5cbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbY29udGVudF1cIj48L25nLWNvbnRlbnQ+XG4gIDwvZGl2PlxuPC9oZWFkZXI+Il19
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50cnktaGVhZGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvZW50cnktY29tcG9uZW50cy9oZWFkZXIvZW50cnktaGVhZGVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL2xpYnMvZW50cnktY29tcG9uZW50cy9oZWFkZXIvZW50cnktaGVhZGVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQVExRSxNQUFNLE9BQU8sb0JBQW9COztpSEFBcEIsb0JBQW9CO3FHQUFwQixvQkFBb0IsZ0ZDUmpDLHFSQVFTOzJGREFJLG9CQUFvQjtrQkFOaEMsU0FBUzsrQkFDRSxjQUFjLG1CQUdQLHVCQUF1QixDQUFDLE1BQU07OEJBR3RDLEtBQUs7c0JBQWIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2VudHJ5LWhlYWRlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9lbnRyeS1oZWFkZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9lbnRyeS1oZWFkZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgRW50cnlIZWFkZXJDb21wb25lbnQge1xuICBASW5wdXQoKSB0aXRsZTogc3RyaW5nO1xufVxuIiwiPGhlYWRlciBjbGFzcz1cImVudHJ5LWhlYWRlclwiPlxuICA8ZGl2IGNsYXNzPVwic3BhY2UtYmV0d2VlblwiPlxuICAgIDxoMSBjbGFzcz1cInRpdGxlIGl0ZW1cIj57e3RpdGxlfX08L2gxPlxuICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIltidXR0b25zXVwiPjwvbmctY29udGVudD5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJyb3cgY29udGVudFwiPlxuICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIltjb250ZW50XVwiPjwvbmctY29udGVudD5cbiAgPC9kaXY+XG48L2hlYWRlcj4iXX0=
@@ -5,4 +5,5 @@ export * from '@enigmatry/entry-components/header';
5
5
  export * from '@enigmatry/entry-components/dialog';
6
6
  export * from '@enigmatry/entry-components/search-filter';
7
7
  export * from '@enigmatry/entry-components/toolbar';
8
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYnMvZW50cnktY29tcG9uZW50cy9wdWJsaWMtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxvQ0FBb0MsQ0FBQztBQUNuRCxjQUFjLG9DQUFvQyxDQUFDO0FBQ25ELGNBQWMsMkNBQTJDLENBQUM7QUFDMUQsY0FBYyxxQ0FBcUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBQdWJsaWMgQVBJIFN1cmZhY2Ugb2YgZW50cnktY29tcG9uZW50c1xuICovXG5cbmV4cG9ydCAqIGZyb20gJ0BlbmlnbWF0cnkvZW50cnktY29tcG9uZW50cy9oZWFkZXInO1xuZXhwb3J0ICogZnJvbSAnQGVuaWdtYXRyeS9lbnRyeS1jb21wb25lbnRzL2RpYWxvZyc7XG5leHBvcnQgKiBmcm9tICdAZW5pZ21hdHJ5L2VudHJ5LWNvbXBvbmVudHMvc2VhcmNoLWZpbHRlcic7XG5leHBvcnQgKiBmcm9tICdAZW5pZ21hdHJ5L2VudHJ5LWNvbXBvbmVudHMvdG9vbGJhcic7XG4iXX0=
8
+ export * from '@enigmatry/entry-components/validation';
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2xpYnMvZW50cnktY29tcG9uZW50cy9wdWJsaWMtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxvQ0FBb0MsQ0FBQztBQUNuRCxjQUFjLG9DQUFvQyxDQUFDO0FBQ25ELGNBQWMsMkNBQTJDLENBQUM7QUFDMUQsY0FBYyxxQ0FBcUMsQ0FBQztBQUNwRCxjQUFjLHdDQUF3QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIFB1YmxpYyBBUEkgU3VyZmFjZSBvZiBlbnRyeS1jb21wb25lbnRzXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnQGVuaWdtYXRyeS9lbnRyeS1jb21wb25lbnRzL2hlYWRlcic7XG5leHBvcnQgKiBmcm9tICdAZW5pZ21hdHJ5L2VudHJ5LWNvbXBvbmVudHMvZGlhbG9nJztcbmV4cG9ydCAqIGZyb20gJ0BlbmlnbWF0cnkvZW50cnktY29tcG9uZW50cy9zZWFyY2gtZmlsdGVyJztcbmV4cG9ydCAqIGZyb20gJ0BlbmlnbWF0cnkvZW50cnktY29tcG9uZW50cy90b29sYmFyJztcbmV4cG9ydCAqIGZyb20gJ0BlbmlnbWF0cnkvZW50cnktY29tcG9uZW50cy92YWxpZGF0aW9uJztcbiJdfQ==
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './public-api';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5pZ21hdHJ5LWVudHJ5LWNvbXBvbmVudHMtdmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvZW50cnktY29tcG9uZW50cy92YWxpZGF0aW9uL2VuaWdtYXRyeS1lbnRyeS1jb21wb25lbnRzLXZhbGlkYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWMtYXBpJztcbiJdfQ==
@@ -0,0 +1,53 @@
1
+ import { Directive, Inject, Input } from '@angular/core';
2
+ import { ENTRY_VALIDATION_CONFIG } from './entry-validation-config.model';
3
+ import { FORM_FIELD_ERROR_KEY } from './entry-validation';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "./entry-validation-config.model";
6
+ export class EntryDisplayControlValidationDirective {
7
+ constructor(_config, _element) {
8
+ this._config = _config;
9
+ this._element = _element;
10
+ }
11
+ ngOnInit() {
12
+ this._controlSubscription = this.control.statusChanges
13
+ .subscribe((controlStatus) => {
14
+ if (controlStatus === 'INVALID') {
15
+ this._element.nativeElement.innerText = this.extractValidationMessages();
16
+ }
17
+ });
18
+ }
19
+ ngOnDestroy() {
20
+ if (this._controlSubscription) {
21
+ this._controlSubscription.unsubscribe();
22
+ }
23
+ }
24
+ extractValidationMessages() {
25
+ if (!this.control.errors) {
26
+ return '';
27
+ }
28
+ const errorsString = this._config.validationMessages
29
+ .map(validationMessage => this.control.errors[validationMessage.name]
30
+ ? typeof (validationMessage.message) === 'string'
31
+ ? validationMessage.message : validationMessage.message(this.control)
32
+ : '')
33
+ .filter(message => message !== '')
34
+ .join(', ');
35
+ const serverErrors = this.control.errors[FORM_FIELD_ERROR_KEY];
36
+ const serverErrorsString = serverErrors instanceof Array ? serverErrors.join(', ') : '';
37
+ return [errorsString, serverErrorsString].filter(x => x !== '').join(', ');
38
+ }
39
+ }
40
+ EntryDisplayControlValidationDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryDisplayControlValidationDirective, deps: [{ token: ENTRY_VALIDATION_CONFIG }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
41
+ EntryDisplayControlValidationDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: EntryDisplayControlValidationDirective, selector: "[entryDisplayControlValidation]", inputs: { control: "control" }, ngImport: i0 });
42
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryDisplayControlValidationDirective, decorators: [{
43
+ type: Directive,
44
+ args: [{
45
+ selector: '[entryDisplayControlValidation]'
46
+ }]
47
+ }], ctorParameters: function () { return [{ type: i1.EntryValidationConfig, decorators: [{
48
+ type: Inject,
49
+ args: [ENTRY_VALIDATION_CONFIG]
50
+ }] }, { type: i0.ElementRef }]; }, propDecorators: { control: [{
51
+ type: Input
52
+ }] } });
53
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50cnktZGlzcGxheS1jb250cm9sLXZhbGlkYXRpb24uZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy9lbnRyeS1jb21wb25lbnRzL3ZhbGlkYXRpb24vZW50cnktZGlzcGxheS1jb250cm9sLXZhbGlkYXRpb24uZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWMsTUFBTSxFQUFFLEtBQUssRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFDeEYsT0FBTyxFQUFFLHVCQUF1QixFQUF5QixNQUFNLGlDQUFpQyxDQUFDO0FBR2pHLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDOzs7QUFLMUQsTUFBTSxPQUFPLHNDQUFzQztJQUtqRCxZQUNvRCxPQUE4QixFQUMvRCxRQUFvQjtRQURhLFlBQU8sR0FBUCxPQUFPLENBQXVCO1FBQy9ELGFBQVEsR0FBUixRQUFRLENBQVk7SUFBRyxDQUFDO0lBRTNDLFFBQVE7UUFDTixJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhO2FBQ25ELFNBQVMsQ0FBQyxDQUFDLGFBQWdDLEVBQUUsRUFBRTtZQUM5QyxJQUFJLGFBQWEsS0FBSyxTQUFTLEVBQUU7Z0JBQy9CLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQzthQUMxRTtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRTtZQUM3QixJQUFJLENBQUMsb0JBQW9CLENBQUMsV0FBVyxFQUFFLENBQUM7U0FDekM7SUFDSCxDQUFDO0lBRU8seUJBQXlCO1FBQy9CLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRTtZQUN4QixPQUFPLEVBQUUsQ0FBQztTQUNYO1FBQ0QsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0I7YUFDakQsR0FBRyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUM7WUFDbkUsQ0FBQyxDQUFDLE9BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsS0FBSyxRQUFRO2dCQUM5QyxDQUFDLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztZQUN2RSxDQUFDLENBQUMsRUFBRSxDQUNMO2FBQ0EsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQzthQUNqQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFZCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQy9ELE1BQU0sa0JBQWtCLEdBQUcsWUFBWSxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRXhGLE9BQU8sQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdFLENBQUM7O21JQXpDVSxzQ0FBc0Msa0JBTXZDLHVCQUF1Qjt1SEFOdEIsc0NBQXNDOzJGQUF0QyxzQ0FBc0M7a0JBSGxELFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGlDQUFpQztpQkFDNUM7OzBCQU9JLE1BQU07MkJBQUMsdUJBQXVCO3FFQUx4QixPQUFPO3NCQUFmLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIEluamVjdCwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBFTlRSWV9WQUxJREFUSU9OX0NPTkZJRywgRW50cnlWYWxpZGF0aW9uQ29uZmlnIH0gZnJvbSAnLi9lbnRyeS12YWxpZGF0aW9uLWNvbmZpZy5tb2RlbCc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIEZvcm1Db250cm9sU3RhdHVzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBGT1JNX0ZJRUxEX0VSUk9SX0tFWSB9IGZyb20gJy4vZW50cnktdmFsaWRhdGlvbic7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tlbnRyeURpc3BsYXlDb250cm9sVmFsaWRhdGlvbl0nXG59KVxuZXhwb3J0IGNsYXNzIEVudHJ5RGlzcGxheUNvbnRyb2xWYWxpZGF0aW9uRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBjb250cm9sOiBBYnN0cmFjdENvbnRyb2w7XG5cbiAgcHJpdmF0ZSBfY29udHJvbFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uIHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoRU5UUllfVkFMSURBVElPTl9DT05GSUcpIHByaXZhdGUgcmVhZG9ubHkgX2NvbmZpZzogRW50cnlWYWxpZGF0aW9uQ29uZmlnLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2VsZW1lbnQ6IEVsZW1lbnRSZWYpIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5fY29udHJvbFN1YnNjcmlwdGlvbiA9IHRoaXMuY29udHJvbC5zdGF0dXNDaGFuZ2VzXG4gICAgICAuc3Vic2NyaWJlKChjb250cm9sU3RhdHVzOiBGb3JtQ29udHJvbFN0YXR1cykgPT4ge1xuICAgICAgICBpZiAoY29udHJvbFN0YXR1cyA9PT0gJ0lOVkFMSUQnKSB7XG4gICAgICAgICAgdGhpcy5fZWxlbWVudC5uYXRpdmVFbGVtZW50LmlubmVyVGV4dCA9IHRoaXMuZXh0cmFjdFZhbGlkYXRpb25NZXNzYWdlcygpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9jb250cm9sU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLl9jb250cm9sU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0VmFsaWRhdGlvbk1lc3NhZ2VzKCk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2wuZXJyb3JzKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIGNvbnN0IGVycm9yc1N0cmluZyA9IHRoaXMuX2NvbmZpZy52YWxpZGF0aW9uTWVzc2FnZXNcbiAgICAgIC5tYXAodmFsaWRhdGlvbk1lc3NhZ2UgPT4gdGhpcy5jb250cm9sLmVycm9yc1t2YWxpZGF0aW9uTWVzc2FnZS5uYW1lXVxuICAgICAgICA/IHR5cGVvZih2YWxpZGF0aW9uTWVzc2FnZS5tZXNzYWdlKSA9PT0gJ3N0cmluZydcbiAgICAgICAgICA/IHZhbGlkYXRpb25NZXNzYWdlLm1lc3NhZ2UgOiB2YWxpZGF0aW9uTWVzc2FnZS5tZXNzYWdlKHRoaXMuY29udHJvbClcbiAgICAgICAgOiAnJ1xuICAgICAgKVxuICAgICAgLmZpbHRlcihtZXNzYWdlID0+IG1lc3NhZ2UgIT09ICcnKVxuICAgICAgLmpvaW4oJywgJyk7XG5cbiAgICBjb25zdCBzZXJ2ZXJFcnJvcnMgPSB0aGlzLmNvbnRyb2wuZXJyb3JzW0ZPUk1fRklFTERfRVJST1JfS0VZXTtcbiAgICBjb25zdCBzZXJ2ZXJFcnJvcnNTdHJpbmcgPSBzZXJ2ZXJFcnJvcnMgaW5zdGFuY2VvZiBBcnJheSA/IHNlcnZlckVycm9ycy5qb2luKCcsICcpIDogJyc7XG5cbiAgICByZXR1cm4gW2Vycm9yc1N0cmluZywgc2VydmVyRXJyb3JzU3RyaW5nXS5maWx0ZXIoeCA9PiB4ICE9PSAnJykuam9pbignLCAnKTtcbiAgfVxufVxuIl19
@@ -0,0 +1,25 @@
1
+ import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "@angular/common";
4
+ import * as i2 from "@angular/material/form-field";
5
+ /**
6
+ * A component used to display back-end validation errors on form level (errors that are not connected to the specific form field).
7
+ *
8
+ * This component will list validation errors one after another, each in separate row.
9
+ *
10
+ * @example
11
+ * ```html
12
+ * <entry-form-errors [form]="myForm"></entry-form-errors>
13
+ * ```
14
+ */
15
+ export class EntryFormErrorsComponent {
16
+ }
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: "<div *ngIf=\"form.errors\">\n <mat-error *ngFor=\"let error of form.errors.general\">{{error}}</mat-error>\n</div>", styles: [""], 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
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryFormErrorsComponent, decorators: [{
20
+ type: Component,
21
+ args: [{ selector: 'entry-form-errors', changeDetection: ChangeDetectionStrategy.Default, template: "<div *ngIf=\"form.errors\">\n <mat-error *ngFor=\"let error of form.errors.general\">{{error}}</mat-error>\n</div>" }]
22
+ }], propDecorators: { form: [{
23
+ type: Input
24
+ }] } });
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50cnktZm9ybS1lcnJvcnMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy9lbnRyeS1jb21wb25lbnRzL3ZhbGlkYXRpb24vZW50cnktZm9ybS1lcnJvcnMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vbGlicy9lbnRyeS1jb21wb25lbnRzL3ZhbGlkYXRpb24vZW50cnktZm9ybS1lcnJvcnMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7Ozs7QUFHMUU7Ozs7Ozs7OztHQVNHO0FBT0gsTUFBTSxPQUFPLHdCQUF3Qjs7cUhBQXhCLHdCQUF3Qjt5R0FBeEIsd0JBQXdCLG1GQ25CckMsdUhBRU07MkZEaUJPLHdCQUF3QjtrQkFOcEMsU0FBUzsrQkFDRSxtQkFBbUIsbUJBR1osdUJBQXVCLENBQUMsT0FBTzs4QkFHdkMsSUFBSTtzQkFBWixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFVudHlwZWRGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbi8qKlxuICogQSBjb21wb25lbnQgdXNlZCB0byBkaXNwbGF5IGJhY2stZW5kIHZhbGlkYXRpb24gZXJyb3JzIG9uIGZvcm0gbGV2ZWwgKGVycm9ycyB0aGF0IGFyZSBub3QgY29ubmVjdGVkIHRvIHRoZSBzcGVjaWZpYyBmb3JtIGZpZWxkKS5cbiAqXG4gKiBUaGlzIGNvbXBvbmVudCB3aWxsIGxpc3QgdmFsaWRhdGlvbiBlcnJvcnMgb25lIGFmdGVyIGFub3RoZXIsIGVhY2ggaW4gc2VwYXJhdGUgcm93LlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBodG1sXG4gKiA8ZW50cnktZm9ybS1lcnJvcnMgW2Zvcm1dPVwibXlGb3JtXCI+PC9lbnRyeS1mb3JtLWVycm9ycz5cbiAqIGBgYFxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdlbnRyeS1mb3JtLWVycm9ycycsXG4gIHRlbXBsYXRlVXJsOiAnLi9lbnRyeS1mb3JtLWVycm9ycy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2VudHJ5LWZvcm0tZXJyb3JzLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuRGVmYXVsdFxufSlcbmV4cG9ydCBjbGFzcyBFbnRyeUZvcm1FcnJvcnNDb21wb25lbnQge1xuICBASW5wdXQoKSBmb3JtOiBVbnR5cGVkRm9ybUdyb3VwO1xufVxuIiwiPGRpdiAqbmdJZj1cImZvcm0uZXJyb3JzXCI+XG4gICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgZXJyb3Igb2YgZm9ybS5lcnJvcnMuZ2VuZXJhbFwiPnt7ZXJyb3J9fTwvbWF0LWVycm9yPlxuPC9kaXY+Il19
@@ -0,0 +1,21 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ /**
3
+ * Used to provide default configurations on module level.
4
+ */
5
+ export class EntryValidationConfig {
6
+ constructor(config = {}) {
7
+ this.validationMessages = config.validationMessages ?? [];
8
+ }
9
+ }
10
+ /**
11
+ * Entry validation injection token of EntryValidationConfig type containing validation default configurations.
12
+ * Can be updated with custom configuration.
13
+ *
14
+ * Defaults:
15
+ * - validationMessages: []
16
+ */
17
+ export const ENTRY_VALIDATION_CONFIG = new InjectionToken('EntryValidationConfig', {
18
+ providedIn: 'root',
19
+ factory: () => new EntryValidationConfig()
20
+ });
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50cnktdmFsaWRhdGlvbi1jb25maWcubW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL2VudHJ5LWNvbXBvbmVudHMvdmFsaWRhdGlvbi9lbnRyeS12YWxpZGF0aW9uLWNvbmZpZy5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBVy9DOztHQUVHO0FBQ0gsTUFBTSxPQUFPLHFCQUFxQjtJQUk5QixZQUFZLFNBQXlDLEVBQUU7UUFDbkQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsSUFBSSxFQUFFLENBQUM7SUFDOUQsQ0FBQztDQUNKO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsSUFBSSxjQUFjLENBQ3JELHVCQUF1QixFQUN2QjtJQUNJLFVBQVUsRUFBRSxNQUFNO0lBQ2xCLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLHFCQUFxQixFQUFFO0NBQzdDLENBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGlvblRva2VuIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbi8qKiBWYWxpZGF0aW9uIG1lc3NhZ2UgY29uZmlndXJhdGlvbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJRW50cnlWYWxpZGF0aW9uTWVzc2FnZSB7XG4gICAgLy8gVmFsaWRhdGlvbiBrZXlcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgLy8gVmFsaWRhdGlvbiBtZXNzYWdlLiBDYW4gYmUgcmVzb2x2ZWQgZHluYW1pY2FsbHkgKGUuZy4gd2hlbiBpdCBuZWVkcyB0byBiZSB0cmFuc2xhdGVkKS5cbiAgICBtZXNzYWdlOiBzdHJpbmcgfCAoKGM6IEFic3RyYWN0Q29udHJvbCkgPT4gc3RyaW5nKTtcbn1cblxuLyoqXG4gKiBVc2VkIHRvIHByb3ZpZGUgZGVmYXVsdCBjb25maWd1cmF0aW9ucyBvbiBtb2R1bGUgbGV2ZWwuXG4gKi9cbmV4cG9ydCBjbGFzcyBFbnRyeVZhbGlkYXRpb25Db25maWcge1xuICAgIC8qKiBWYWxpZGF0aW9uIGtleSB0byBtZXNzYWdlIGNvbmZpZ3VyYXRpb24gb24gbW9kdWxlIGxldmVsLiAqL1xuICAgIHZhbGlkYXRpb25NZXNzYWdlczogSUVudHJ5VmFsaWRhdGlvbk1lc3NhZ2VbXTtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZzogUGFydGlhbDxFbnRyeVZhbGlkYXRpb25Db25maWc+ID0ge30pIHtcbiAgICAgICAgdGhpcy52YWxpZGF0aW9uTWVzc2FnZXMgPSBjb25maWcudmFsaWRhdGlvbk1lc3NhZ2VzID8/IFtdO1xuICAgIH1cbn1cblxuLyoqXG4gKiBFbnRyeSB2YWxpZGF0aW9uIGluamVjdGlvbiB0b2tlbiBvZiBFbnRyeVZhbGlkYXRpb25Db25maWcgdHlwZSBjb250YWluaW5nIHZhbGlkYXRpb24gZGVmYXVsdCBjb25maWd1cmF0aW9ucy5cbiAqIENhbiBiZSB1cGRhdGVkIHdpdGggY3VzdG9tIGNvbmZpZ3VyYXRpb24uXG4gKlxuICogRGVmYXVsdHM6XG4gKiAtIHZhbGlkYXRpb25NZXNzYWdlczogW11cbiAqL1xuZXhwb3J0IGNvbnN0IEVOVFJZX1ZBTElEQVRJT05fQ09ORklHID0gbmV3IEluamVjdGlvblRva2VuPEVudHJ5VmFsaWRhdGlvbkNvbmZpZz4oXG4gICAgJ0VudHJ5VmFsaWRhdGlvbkNvbmZpZycsXG4gICAge1xuICAgICAgICBwcm92aWRlZEluOiAncm9vdCcsXG4gICAgICAgIGZhY3Rvcnk6ICgpID0+IG5ldyBFbnRyeVZhbGlkYXRpb25Db25maWcoKVxuICAgIH1cbik7XG4iXX0=
@@ -0,0 +1,51 @@
1
+ import { FormArray, FormGroup } from '@angular/forms';
2
+ /** A key used to map server side validation errors on form level */
3
+ const FORM_ERROR_KEY = 'general';
4
+ /** A key used to map server side validation errors on form field level */
5
+ const FORM_FIELD_ERROR_KEY = 'fromServer';
6
+ const getFormControl = (formControl, keys) => {
7
+ if (keys.length === 0) {
8
+ return formControl;
9
+ }
10
+ if (formControl instanceof FormGroup) {
11
+ return getFormControl(formControl.controls[keys[0].charAt(0).toLowerCase() + keys[0].slice(1)], keys.slice(1));
12
+ }
13
+ if (formControl instanceof FormArray && +keys[0] >= 0) {
14
+ return getFormControl(formControl.controls[+keys[0]], keys.slice(1));
15
+ }
16
+ return null;
17
+ };
18
+ /**
19
+ * Applies validation errors received from server side to the form.
20
+ * The errors are applied to multiple levels: form, form group, form array, and form field.
21
+ *
22
+ * @param form Form to apply validation errors to.
23
+ * @param error Server side validation errors response.
24
+ */
25
+ const handleValidationProblemDetails = (form, error) => {
26
+ form.setErrors(null);
27
+ const validationErrors = error?.errors;
28
+ const formErrors = {};
29
+ if (validationErrors) {
30
+ // eslint-disable-next-line guard-for-in
31
+ for (const key in validationErrors) {
32
+ const control = getFormControl(form, key.split(/[.[\]]+/gu));
33
+ if (control) {
34
+ const fieldErrors = {};
35
+ fieldErrors[FORM_FIELD_ERROR_KEY] = validationErrors[key];
36
+ control.setErrors(fieldErrors);
37
+ control.markAsTouched();
38
+ }
39
+ else {
40
+ formErrors[FORM_ERROR_KEY] =
41
+ formErrors[FORM_ERROR_KEY]?.concat(validationErrors[key]) || validationErrors[key];
42
+ }
43
+ }
44
+ }
45
+ else {
46
+ formErrors[FORM_ERROR_KEY] = [`An error occurred on the server.`];
47
+ }
48
+ form.setErrors(formErrors);
49
+ };
50
+ export { FORM_FIELD_ERROR_KEY, handleValidationProblemDetails };
51
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50cnktdmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvZW50cnktY29tcG9uZW50cy92YWxpZGF0aW9uL2VudHJ5LXZhbGlkYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFtQixTQUFTLEVBQUUsU0FBUyxFQUFzQyxNQUFNLGdCQUFnQixDQUFDO0FBRzNHLG9FQUFvRTtBQUNwRSxNQUFNLGNBQWMsR0FBRyxTQUFTLENBQUM7QUFDakMsMEVBQTBFO0FBQzFFLE1BQU0sb0JBQW9CLEdBQUcsWUFBWSxDQUFDO0FBRTFDLE1BQU0sY0FBYyxHQUFHLENBQUMsV0FBK0MsRUFBRSxJQUFjLEVBQXNDLEVBQUU7SUFDM0gsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtRQUNuQixPQUFPLFdBQVcsQ0FBQztLQUN0QjtJQUNELElBQUksV0FBVyxZQUFZLFNBQVMsRUFBRTtRQUNsQyxPQUFPLGNBQWMsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUNsSDtJQUNELElBQUksV0FBVyxZQUFZLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDbkQsT0FBTyxjQUFjLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUN4RTtJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2hCLENBQUMsQ0FBQztBQUVGOzs7Ozs7R0FNRztBQUNILE1BQU0sOEJBQThCLEdBQUcsQ0FBQyxJQUFzQixFQUFFLEtBQWdDLEVBQUUsRUFBRTtJQUNoRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3JCLE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxFQUFFLE1BQU0sQ0FBQztJQUN2QyxNQUFNLFVBQVUsR0FBcUIsRUFBRSxDQUFDO0lBRXhDLElBQUksZ0JBQWdCLEVBQUU7UUFDbEIsd0NBQXdDO1FBQ3hDLEtBQUssTUFBTSxHQUFHLElBQUksZ0JBQWdCLEVBQUU7WUFDaEMsTUFBTSxPQUFPLEdBQUcsY0FBYyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7WUFFN0QsSUFBSSxPQUFPLEVBQUU7Z0JBQ1QsTUFBTSxXQUFXLEdBQUcsRUFBc0IsQ0FBQztnQkFDM0MsV0FBVyxDQUFDLG9CQUFvQixDQUFDLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzFELE9BQU8sQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQy9CLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQzthQUMzQjtpQkFBTTtnQkFDSCxVQUFVLENBQUMsY0FBYyxDQUFDO29CQUN0QixVQUFVLENBQUMsY0FBYyxDQUFDLEVBQUUsTUFBTSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDMUY7U0FDSjtLQUNKO1NBQU07UUFDSCxVQUFVLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBRSxrQ0FBa0MsQ0FBRSxDQUFDO0tBQ3ZFO0lBRUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUMvQixDQUFDLENBQUM7QUFFRixPQUFPLEVBQ0gsb0JBQW9CLEVBQ3BCLDhCQUE4QixFQUNqQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBGb3JtQXJyYXksIEZvcm1Hcm91cCwgVW50eXBlZEZvcm1Hcm91cCwgVmFsaWRhdGlvbkVycm9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IElWYWxpZGF0aW9uUHJvYmxlbURldGFpbHMgfSBmcm9tICcuL3ZhbGlkYXRpb24tcHJvYmxlbS1kZXRhaWxzLmludGVyZmFjZSc7XG5cbi8qKiBBIGtleSB1c2VkIHRvIG1hcCBzZXJ2ZXIgc2lkZSB2YWxpZGF0aW9uIGVycm9ycyBvbiBmb3JtIGxldmVsICovXG5jb25zdCBGT1JNX0VSUk9SX0tFWSA9ICdnZW5lcmFsJztcbi8qKiBBIGtleSB1c2VkIHRvIG1hcCBzZXJ2ZXIgc2lkZSB2YWxpZGF0aW9uIGVycm9ycyBvbiBmb3JtIGZpZWxkIGxldmVsICovXG5jb25zdCBGT1JNX0ZJRUxEX0VSUk9SX0tFWSA9ICdmcm9tU2VydmVyJztcblxuY29uc3QgZ2V0Rm9ybUNvbnRyb2wgPSAoZm9ybUNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCB8IG51bGwgfCB1bmRlZmluZWQsIGtleXM6IHN0cmluZ1tdKTogQWJzdHJhY3RDb250cm9sIHwgbnVsbCB8IHVuZGVmaW5lZCA9PiB7XG4gICAgaWYgKGtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBmb3JtQ29udHJvbDtcbiAgICB9XG4gICAgaWYgKGZvcm1Db250cm9sIGluc3RhbmNlb2YgRm9ybUdyb3VwKSB7XG4gICAgICAgIHJldHVybiBnZXRGb3JtQ29udHJvbChmb3JtQ29udHJvbC5jb250cm9sc1trZXlzWzBdLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpICsga2V5c1swXS5zbGljZSgxKV0sIGtleXMuc2xpY2UoMSkpO1xuICAgIH1cbiAgICBpZiAoZm9ybUNvbnRyb2wgaW5zdGFuY2VvZiBGb3JtQXJyYXkgJiYgK2tleXNbMF0gPj0gMCkge1xuICAgICAgICByZXR1cm4gZ2V0Rm9ybUNvbnRyb2woZm9ybUNvbnRyb2wuY29udHJvbHNbK2tleXNbMF1dLCBrZXlzLnNsaWNlKDEpKTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIEFwcGxpZXMgdmFsaWRhdGlvbiBlcnJvcnMgcmVjZWl2ZWQgZnJvbSBzZXJ2ZXIgc2lkZSB0byB0aGUgZm9ybS5cbiAqIFRoZSBlcnJvcnMgYXJlIGFwcGxpZWQgdG8gbXVsdGlwbGUgbGV2ZWxzOiBmb3JtLCBmb3JtIGdyb3VwLCBmb3JtIGFycmF5LCBhbmQgZm9ybSBmaWVsZC5cbiAqXG4gKiBAcGFyYW0gZm9ybSBGb3JtIHRvIGFwcGx5IHZhbGlkYXRpb24gZXJyb3JzIHRvLlxuICogQHBhcmFtIGVycm9yIFNlcnZlciBzaWRlIHZhbGlkYXRpb24gZXJyb3JzIHJlc3BvbnNlLlxuICovXG5jb25zdCBoYW5kbGVWYWxpZGF0aW9uUHJvYmxlbURldGFpbHMgPSAoZm9ybTogVW50eXBlZEZvcm1Hcm91cCwgZXJyb3I6IElWYWxpZGF0aW9uUHJvYmxlbURldGFpbHMpID0+IHtcbiAgICBmb3JtLnNldEVycm9ycyhudWxsKTtcbiAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gZXJyb3I/LmVycm9ycztcbiAgICBjb25zdCBmb3JtRXJyb3JzOiBWYWxpZGF0aW9uRXJyb3JzID0ge307XG5cbiAgICBpZiAodmFsaWRhdGlvbkVycm9ycykge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ3VhcmQtZm9yLWluXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHZhbGlkYXRpb25FcnJvcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRyb2wgPSBnZXRGb3JtQ29udHJvbChmb3JtLCBrZXkuc3BsaXQoL1suW1xcXV0rL2d1KSk7XG5cbiAgICAgICAgICAgIGlmIChjb250cm9sKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmllbGRFcnJvcnMgPSB7fSBhcyBWYWxpZGF0aW9uRXJyb3JzO1xuICAgICAgICAgICAgICAgIGZpZWxkRXJyb3JzW0ZPUk1fRklFTERfRVJST1JfS0VZXSA9IHZhbGlkYXRpb25FcnJvcnNba2V5XTtcbiAgICAgICAgICAgICAgICBjb250cm9sLnNldEVycm9ycyhmaWVsZEVycm9ycyk7XG4gICAgICAgICAgICAgICAgY29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvcm1FcnJvcnNbRk9STV9FUlJPUl9LRVldID1cbiAgICAgICAgICAgICAgICAgICAgZm9ybUVycm9yc1tGT1JNX0VSUk9SX0tFWV0/LmNvbmNhdCh2YWxpZGF0aW9uRXJyb3JzW2tleV0pIHx8IHZhbGlkYXRpb25FcnJvcnNba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGZvcm1FcnJvcnNbRk9STV9FUlJPUl9LRVldID0gWyBgQW4gZXJyb3Igb2NjdXJyZWQgb24gdGhlIHNlcnZlci5gIF07XG4gICAgfVxuXG4gICAgZm9ybS5zZXRFcnJvcnMoZm9ybUVycm9ycyk7XG59O1xuXG5leHBvcnQge1xuICAgIEZPUk1fRklFTERfRVJST1JfS0VZLFxuICAgIGhhbmRsZVZhbGlkYXRpb25Qcm9ibGVtRGV0YWlsc1xufTtcbiJdfQ==
@@ -0,0 +1,40 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { EntryFormErrorsComponent } from './entry-form-errors.component';
4
+ import { MatInputModule } from '@angular/material/input';
5
+ import { EntryDisplayControlValidationDirective } from './entry-display-control-validation.directive';
6
+ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
7
+ import * as i0 from "@angular/core";
8
+ export class EntryValidationModule {
9
+ }
10
+ EntryValidationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryValidationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
11
+ EntryValidationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: EntryValidationModule, declarations: [EntryFormErrorsComponent,
12
+ EntryDisplayControlValidationDirective], imports: [CommonModule,
13
+ FormsModule,
14
+ ReactiveFormsModule,
15
+ MatInputModule], exports: [EntryFormErrorsComponent,
16
+ EntryDisplayControlValidationDirective] });
17
+ EntryValidationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryValidationModule, imports: [CommonModule,
18
+ FormsModule,
19
+ ReactiveFormsModule,
20
+ MatInputModule] });
21
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryValidationModule, decorators: [{
22
+ type: NgModule,
23
+ args: [{
24
+ declarations: [
25
+ EntryFormErrorsComponent,
26
+ EntryDisplayControlValidationDirective
27
+ ],
28
+ imports: [
29
+ CommonModule,
30
+ FormsModule,
31
+ ReactiveFormsModule,
32
+ MatInputModule
33
+ ],
34
+ exports: [
35
+ EntryFormErrorsComponent,
36
+ EntryDisplayControlValidationDirective
37
+ ]
38
+ }]
39
+ }] });
40
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50cnktdmFsaWRhdGlvbi5tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL2VudHJ5LWNvbXBvbmVudHMvdmFsaWRhdGlvbi9lbnRyeS12YWxpZGF0aW9uLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUN6RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDekQsT0FBTyxFQUFFLHNDQUFzQyxFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDdEcsT0FBTyxFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDOztBQWtCbEUsTUFBTSxPQUFPLHFCQUFxQjs7a0hBQXJCLHFCQUFxQjttSEFBckIscUJBQXFCLGlCQWQ5Qix3QkFBd0I7UUFDeEIsc0NBQXNDLGFBR3RDLFlBQVk7UUFDWixXQUFXO1FBQ1gsbUJBQW1CO1FBQ25CLGNBQWMsYUFHZCx3QkFBd0I7UUFDeEIsc0NBQXNDO21IQUc3QixxQkFBcUIsWUFWOUIsWUFBWTtRQUNaLFdBQVc7UUFDWCxtQkFBbUI7UUFDbkIsY0FBYzsyRkFPTCxxQkFBcUI7a0JBaEJqQyxRQUFRO21CQUFDO29CQUNSLFlBQVksRUFBRTt3QkFDWix3QkFBd0I7d0JBQ3hCLHNDQUFzQztxQkFDdkM7b0JBQ0QsT0FBTyxFQUFFO3dCQUNQLFlBQVk7d0JBQ1osV0FBVzt3QkFDWCxtQkFBbUI7d0JBQ25CLGNBQWM7cUJBQ2Y7b0JBQ0QsT0FBTyxFQUFFO3dCQUNQLHdCQUF3Qjt3QkFDeEIsc0NBQXNDO3FCQUN2QztpQkFDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRW50cnlGb3JtRXJyb3JzQ29tcG9uZW50IH0gZnJvbSAnLi9lbnRyeS1mb3JtLWVycm9ycy5jb21wb25lbnQnO1xuaW1wb3J0IHsgTWF0SW5wdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XG5pbXBvcnQgeyBFbnRyeURpc3BsYXlDb250cm9sVmFsaWRhdGlvbkRpcmVjdGl2ZSB9IGZyb20gJy4vZW50cnktZGlzcGxheS1jb250cm9sLXZhbGlkYXRpb24uZGlyZWN0aXZlJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5ATmdNb2R1bGUoe1xuICBkZWNsYXJhdGlvbnM6IFtcbiAgICBFbnRyeUZvcm1FcnJvcnNDb21wb25lbnQsXG4gICAgRW50cnlEaXNwbGF5Q29udHJvbFZhbGlkYXRpb25EaXJlY3RpdmVcbiAgXSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICAgIE1hdElucHV0TW9kdWxlXG4gIF0sXG4gIGV4cG9ydHM6IFtcbiAgICBFbnRyeUZvcm1FcnJvcnNDb21wb25lbnQsXG4gICAgRW50cnlEaXNwbGF5Q29udHJvbFZhbGlkYXRpb25EaXJlY3RpdmVcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBFbnRyeVZhbGlkYXRpb25Nb2R1bGUgeyB9XG4iXX0=
@@ -0,0 +1,6 @@
1
+ export { EntryFormErrorsComponent } from './entry-form-errors.component';
2
+ export { EntryDisplayControlValidationDirective } from './entry-display-control-validation.directive';
3
+ export { EntryValidationModule } from './entry-validation.module';
4
+ export * from './entry-validation';
5
+ export { ENTRY_VALIDATION_CONFIG, EntryValidationConfig } from './entry-validation-config.model';
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvZW50cnktY29tcG9uZW50cy92YWxpZGF0aW9uL3B1YmxpYy1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDekUsT0FBTyxFQUFFLHNDQUFzQyxFQUFFLE1BQU0sOENBQThDLENBQUM7QUFFdEcsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFHbEUsY0FBYyxvQkFBb0IsQ0FBQztBQUVuQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUscUJBQXFCLEVBQTJCLE1BQU0saUNBQWlDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBFbnRyeUZvcm1FcnJvcnNDb21wb25lbnQgfSBmcm9tICcuL2VudHJ5LWZvcm0tZXJyb3JzLmNvbXBvbmVudCc7XG5leHBvcnQgeyBFbnRyeURpc3BsYXlDb250cm9sVmFsaWRhdGlvbkRpcmVjdGl2ZSB9IGZyb20gJy4vZW50cnktZGlzcGxheS1jb250cm9sLXZhbGlkYXRpb24uZGlyZWN0aXZlJztcblxuZXhwb3J0IHsgRW50cnlWYWxpZGF0aW9uTW9kdWxlIH0gZnJvbSAnLi9lbnRyeS12YWxpZGF0aW9uLm1vZHVsZSc7XG5cbmV4cG9ydCB7IElWYWxpZGF0aW9uUHJvYmxlbURldGFpbHMgfSBmcm9tICcuL3ZhbGlkYXRpb24tcHJvYmxlbS1kZXRhaWxzLmludGVyZmFjZSc7XG5leHBvcnQgKiBmcm9tICcuL2VudHJ5LXZhbGlkYXRpb24nO1xuXG5leHBvcnQgeyBFTlRSWV9WQUxJREFUSU9OX0NPTkZJRywgRW50cnlWYWxpZGF0aW9uQ29uZmlnLCBJRW50cnlWYWxpZGF0aW9uTWVzc2FnZSB9IGZyb20gJy4vZW50cnktdmFsaWRhdGlvbi1jb25maWcubW9kZWwnO1xuIl19
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi1wcm9ibGVtLWRldGFpbHMuaW50ZXJmYWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy9lbnRyeS1jb21wb25lbnRzL3ZhbGlkYXRpb24vdmFsaWRhdGlvbi1wcm9ibGVtLWRldGFpbHMuaW50ZXJmYWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIERlZmluZXMgdGhlIGFwaSwgYSBzdWItc2V0IG9mIGBNaWNyb3NvZnQuQXNwTmV0Q29yZS5NdmMuVmFsaWRhdGlvblByb2JsZW1EZXRhaWxzYCBjbGFzcyxcbiAqICB3aGljaCB1c2VkIGFzIGEgY29udGFpbmVyIGZvciBzZXJ2ZXIgc2lkZSB2YWxpZGF0aW9uIGVycm9ycy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJVmFsaWRhdGlvblByb2JsZW1EZXRhaWxzIHtcbiAgICBba2V5OiBzdHJpbmddOiBhbnk7XG4gICAgZXJyb3JzPzogeyBba2V5OiBzdHJpbmddOiBzdHJpbmdbXSB9O1xufVxuIl19
@@ -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=\"header-item title\">{{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 });
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=\"header-item title\">{{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>" }]
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=\"header-item title\">{{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,4RAQS,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,4RAAA,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;;;;"}
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;;;;"}
@@ -0,0 +1,189 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Component, ChangeDetectionStrategy, Input, InjectionToken, Directive, Inject, NgModule } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import * as i2 from '@angular/material/form-field';
6
+ import { FormGroup, FormArray, FormsModule, ReactiveFormsModule } from '@angular/forms';
7
+ import { MatInputModule } from '@angular/material/input';
8
+
9
+ /**
10
+ * A component used to display back-end validation errors on form level (errors that are not connected to the specific form field).
11
+ *
12
+ * This component will list validation errors one after another, each in separate row.
13
+ *
14
+ * @example
15
+ * ```html
16
+ * <entry-form-errors [form]="myForm"></entry-form-errors>
17
+ * ```
18
+ */
19
+ class EntryFormErrorsComponent {
20
+ }
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: "<div *ngIf=\"form.errors\">\n <mat-error *ngFor=\"let error of form.errors.general\">{{error}}</mat-error>\n</div>", styles: [""], 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
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryFormErrorsComponent, decorators: [{
24
+ type: Component,
25
+ args: [{ selector: 'entry-form-errors', changeDetection: ChangeDetectionStrategy.Default, template: "<div *ngIf=\"form.errors\">\n <mat-error *ngFor=\"let error of form.errors.general\">{{error}}</mat-error>\n</div>" }]
26
+ }], propDecorators: { form: [{
27
+ type: Input
28
+ }] } });
29
+
30
+ /**
31
+ * Used to provide default configurations on module level.
32
+ */
33
+ class EntryValidationConfig {
34
+ constructor(config = {}) {
35
+ var _a;
36
+ this.validationMessages = (_a = config.validationMessages) !== null && _a !== void 0 ? _a : [];
37
+ }
38
+ }
39
+ /**
40
+ * Entry validation injection token of EntryValidationConfig type containing validation default configurations.
41
+ * Can be updated with custom configuration.
42
+ *
43
+ * Defaults:
44
+ * - validationMessages: []
45
+ */
46
+ const ENTRY_VALIDATION_CONFIG = new InjectionToken('EntryValidationConfig', {
47
+ providedIn: 'root',
48
+ factory: () => new EntryValidationConfig()
49
+ });
50
+
51
+ /** A key used to map server side validation errors on form level */
52
+ const FORM_ERROR_KEY = 'general';
53
+ /** A key used to map server side validation errors on form field level */
54
+ const FORM_FIELD_ERROR_KEY = 'fromServer';
55
+ const getFormControl = (formControl, keys) => {
56
+ if (keys.length === 0) {
57
+ return formControl;
58
+ }
59
+ if (formControl instanceof FormGroup) {
60
+ return getFormControl(formControl.controls[keys[0].charAt(0).toLowerCase() + keys[0].slice(1)], keys.slice(1));
61
+ }
62
+ if (formControl instanceof FormArray && +keys[0] >= 0) {
63
+ return getFormControl(formControl.controls[+keys[0]], keys.slice(1));
64
+ }
65
+ return null;
66
+ };
67
+ /**
68
+ * Applies validation errors received from server side to the form.
69
+ * The errors are applied to multiple levels: form, form group, form array, and form field.
70
+ *
71
+ * @param form Form to apply validation errors to.
72
+ * @param error Server side validation errors response.
73
+ */
74
+ const handleValidationProblemDetails = (form, error) => {
75
+ var _a;
76
+ form.setErrors(null);
77
+ const validationErrors = error === null || error === void 0 ? void 0 : error.errors;
78
+ const formErrors = {};
79
+ if (validationErrors) {
80
+ // eslint-disable-next-line guard-for-in
81
+ for (const key in validationErrors) {
82
+ const control = getFormControl(form, key.split(/[.[\]]+/gu));
83
+ if (control) {
84
+ const fieldErrors = {};
85
+ fieldErrors[FORM_FIELD_ERROR_KEY] = validationErrors[key];
86
+ control.setErrors(fieldErrors);
87
+ control.markAsTouched();
88
+ }
89
+ else {
90
+ formErrors[FORM_ERROR_KEY] =
91
+ ((_a = formErrors[FORM_ERROR_KEY]) === null || _a === void 0 ? void 0 : _a.concat(validationErrors[key])) || validationErrors[key];
92
+ }
93
+ }
94
+ }
95
+ else {
96
+ formErrors[FORM_ERROR_KEY] = [`An error occurred on the server.`];
97
+ }
98
+ form.setErrors(formErrors);
99
+ };
100
+
101
+ class EntryDisplayControlValidationDirective {
102
+ constructor(_config, _element) {
103
+ this._config = _config;
104
+ this._element = _element;
105
+ }
106
+ ngOnInit() {
107
+ this._controlSubscription = this.control.statusChanges
108
+ .subscribe((controlStatus) => {
109
+ if (controlStatus === 'INVALID') {
110
+ this._element.nativeElement.innerText = this.extractValidationMessages();
111
+ }
112
+ });
113
+ }
114
+ ngOnDestroy() {
115
+ if (this._controlSubscription) {
116
+ this._controlSubscription.unsubscribe();
117
+ }
118
+ }
119
+ extractValidationMessages() {
120
+ if (!this.control.errors) {
121
+ return '';
122
+ }
123
+ const errorsString = this._config.validationMessages
124
+ .map(validationMessage => this.control.errors[validationMessage.name]
125
+ ? typeof (validationMessage.message) === 'string'
126
+ ? validationMessage.message : validationMessage.message(this.control)
127
+ : '')
128
+ .filter(message => message !== '')
129
+ .join(', ');
130
+ const serverErrors = this.control.errors[FORM_FIELD_ERROR_KEY];
131
+ const serverErrorsString = serverErrors instanceof Array ? serverErrors.join(', ') : '';
132
+ return [errorsString, serverErrorsString].filter(x => x !== '').join(', ');
133
+ }
134
+ }
135
+ EntryDisplayControlValidationDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryDisplayControlValidationDirective, deps: [{ token: ENTRY_VALIDATION_CONFIG }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
136
+ EntryDisplayControlValidationDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: EntryDisplayControlValidationDirective, selector: "[entryDisplayControlValidation]", inputs: { control: "control" }, ngImport: i0 });
137
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryDisplayControlValidationDirective, decorators: [{
138
+ type: Directive,
139
+ args: [{
140
+ selector: '[entryDisplayControlValidation]'
141
+ }]
142
+ }], ctorParameters: function () {
143
+ return [{ type: EntryValidationConfig, decorators: [{
144
+ type: Inject,
145
+ args: [ENTRY_VALIDATION_CONFIG]
146
+ }] }, { type: i0.ElementRef }];
147
+ }, propDecorators: { control: [{
148
+ type: Input
149
+ }] } });
150
+
151
+ class EntryValidationModule {
152
+ }
153
+ EntryValidationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryValidationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
154
+ EntryValidationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: EntryValidationModule, declarations: [EntryFormErrorsComponent,
155
+ EntryDisplayControlValidationDirective], imports: [CommonModule,
156
+ FormsModule,
157
+ ReactiveFormsModule,
158
+ MatInputModule], exports: [EntryFormErrorsComponent,
159
+ EntryDisplayControlValidationDirective] });
160
+ EntryValidationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryValidationModule, imports: [CommonModule,
161
+ FormsModule,
162
+ ReactiveFormsModule,
163
+ MatInputModule] });
164
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryValidationModule, decorators: [{
165
+ type: NgModule,
166
+ args: [{
167
+ declarations: [
168
+ EntryFormErrorsComponent,
169
+ EntryDisplayControlValidationDirective
170
+ ],
171
+ imports: [
172
+ CommonModule,
173
+ FormsModule,
174
+ ReactiveFormsModule,
175
+ MatInputModule
176
+ ],
177
+ exports: [
178
+ EntryFormErrorsComponent,
179
+ EntryDisplayControlValidationDirective
180
+ ]
181
+ }]
182
+ }] });
183
+
184
+ /**
185
+ * Generated bundle index. Do not edit.
186
+ */
187
+
188
+ export { ENTRY_VALIDATION_CONFIG, EntryDisplayControlValidationDirective, EntryFormErrorsComponent, EntryValidationConfig, EntryValidationModule, FORM_FIELD_ERROR_KEY, handleValidationProblemDetails };
189
+ //# sourceMappingURL=enigmatry-entry-components-validation.mjs.map
@@ -0,0 +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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"}
@@ -2,6 +2,7 @@ export * from '@enigmatry/entry-components/header';
2
2
  export * from '@enigmatry/entry-components/dialog';
3
3
  export * from '@enigmatry/entry-components/search-filter';
4
4
  export * from '@enigmatry/entry-components/toolbar';
5
+ export * from '@enigmatry/entry-components/validation';
5
6
 
6
7
  /*
7
8
  * Public API Surface of entry-components
@@ -1 +1 @@
1
- {"version":3,"file":"enigmatry-entry-components.mjs","sources":["../../../../libs/entry-components/public-api.ts","../../../../libs/entry-components/enigmatry-entry-components.ts"],"sourcesContent":["/*\n * Public API Surface of entry-components\n */\n\nexport * from '@enigmatry/entry-components/header';\nexport * from '@enigmatry/entry-components/dialog';\nexport * from '@enigmatry/entry-components/search-filter';\nexport * from '@enigmatry/entry-components/toolbar';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;AAAA;;AAEG;;ACFH;;AAEG"}
1
+ {"version":3,"file":"enigmatry-entry-components.mjs","sources":["../../../../libs/entry-components/public-api.ts","../../../../libs/entry-components/enigmatry-entry-components.ts"],"sourcesContent":["/*\n * Public API Surface of entry-components\n */\n\nexport * from '@enigmatry/entry-components/header';\nexport * from '@enigmatry/entry-components/dialog';\nexport * from '@enigmatry/entry-components/search-filter';\nexport * from '@enigmatry/entry-components/toolbar';\nexport * from '@enigmatry/entry-components/validation';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;AAAA;;AAEG;;ACFH;;AAEG"}
@@ -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=\"header-item title\">{{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 });
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=\"header-item title\">{{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>" }]
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=\"header-item title\">{{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,4RAQS,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,4RAAA,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;;;;"}
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;;;;"}
@@ -0,0 +1,185 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Component, ChangeDetectionStrategy, Input, InjectionToken, Directive, Inject, NgModule } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import * as i2 from '@angular/material/form-field';
6
+ import { FormGroup, FormArray, FormsModule, ReactiveFormsModule } from '@angular/forms';
7
+ import { MatInputModule } from '@angular/material/input';
8
+
9
+ /**
10
+ * A component used to display back-end validation errors on form level (errors that are not connected to the specific form field).
11
+ *
12
+ * This component will list validation errors one after another, each in separate row.
13
+ *
14
+ * @example
15
+ * ```html
16
+ * <entry-form-errors [form]="myForm"></entry-form-errors>
17
+ * ```
18
+ */
19
+ class EntryFormErrorsComponent {
20
+ }
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: "<div *ngIf=\"form.errors\">\n <mat-error *ngFor=\"let error of form.errors.general\">{{error}}</mat-error>\n</div>", styles: [""], 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
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryFormErrorsComponent, decorators: [{
24
+ type: Component,
25
+ args: [{ selector: 'entry-form-errors', changeDetection: ChangeDetectionStrategy.Default, template: "<div *ngIf=\"form.errors\">\n <mat-error *ngFor=\"let error of form.errors.general\">{{error}}</mat-error>\n</div>" }]
26
+ }], propDecorators: { form: [{
27
+ type: Input
28
+ }] } });
29
+
30
+ /**
31
+ * Used to provide default configurations on module level.
32
+ */
33
+ class EntryValidationConfig {
34
+ constructor(config = {}) {
35
+ this.validationMessages = config.validationMessages ?? [];
36
+ }
37
+ }
38
+ /**
39
+ * Entry validation injection token of EntryValidationConfig type containing validation default configurations.
40
+ * Can be updated with custom configuration.
41
+ *
42
+ * Defaults:
43
+ * - validationMessages: []
44
+ */
45
+ const ENTRY_VALIDATION_CONFIG = new InjectionToken('EntryValidationConfig', {
46
+ providedIn: 'root',
47
+ factory: () => new EntryValidationConfig()
48
+ });
49
+
50
+ /** A key used to map server side validation errors on form level */
51
+ const FORM_ERROR_KEY = 'general';
52
+ /** A key used to map server side validation errors on form field level */
53
+ const FORM_FIELD_ERROR_KEY = 'fromServer';
54
+ const getFormControl = (formControl, keys) => {
55
+ if (keys.length === 0) {
56
+ return formControl;
57
+ }
58
+ if (formControl instanceof FormGroup) {
59
+ return getFormControl(formControl.controls[keys[0].charAt(0).toLowerCase() + keys[0].slice(1)], keys.slice(1));
60
+ }
61
+ if (formControl instanceof FormArray && +keys[0] >= 0) {
62
+ return getFormControl(formControl.controls[+keys[0]], keys.slice(1));
63
+ }
64
+ return null;
65
+ };
66
+ /**
67
+ * Applies validation errors received from server side to the form.
68
+ * The errors are applied to multiple levels: form, form group, form array, and form field.
69
+ *
70
+ * @param form Form to apply validation errors to.
71
+ * @param error Server side validation errors response.
72
+ */
73
+ const handleValidationProblemDetails = (form, error) => {
74
+ form.setErrors(null);
75
+ const validationErrors = error?.errors;
76
+ const formErrors = {};
77
+ if (validationErrors) {
78
+ // eslint-disable-next-line guard-for-in
79
+ for (const key in validationErrors) {
80
+ const control = getFormControl(form, key.split(/[.[\]]+/gu));
81
+ if (control) {
82
+ const fieldErrors = {};
83
+ fieldErrors[FORM_FIELD_ERROR_KEY] = validationErrors[key];
84
+ control.setErrors(fieldErrors);
85
+ control.markAsTouched();
86
+ }
87
+ else {
88
+ formErrors[FORM_ERROR_KEY] =
89
+ formErrors[FORM_ERROR_KEY]?.concat(validationErrors[key]) || validationErrors[key];
90
+ }
91
+ }
92
+ }
93
+ else {
94
+ formErrors[FORM_ERROR_KEY] = [`An error occurred on the server.`];
95
+ }
96
+ form.setErrors(formErrors);
97
+ };
98
+
99
+ class EntryDisplayControlValidationDirective {
100
+ constructor(_config, _element) {
101
+ this._config = _config;
102
+ this._element = _element;
103
+ }
104
+ ngOnInit() {
105
+ this._controlSubscription = this.control.statusChanges
106
+ .subscribe((controlStatus) => {
107
+ if (controlStatus === 'INVALID') {
108
+ this._element.nativeElement.innerText = this.extractValidationMessages();
109
+ }
110
+ });
111
+ }
112
+ ngOnDestroy() {
113
+ if (this._controlSubscription) {
114
+ this._controlSubscription.unsubscribe();
115
+ }
116
+ }
117
+ extractValidationMessages() {
118
+ if (!this.control.errors) {
119
+ return '';
120
+ }
121
+ const errorsString = this._config.validationMessages
122
+ .map(validationMessage => this.control.errors[validationMessage.name]
123
+ ? typeof (validationMessage.message) === 'string'
124
+ ? validationMessage.message : validationMessage.message(this.control)
125
+ : '')
126
+ .filter(message => message !== '')
127
+ .join(', ');
128
+ const serverErrors = this.control.errors[FORM_FIELD_ERROR_KEY];
129
+ const serverErrorsString = serverErrors instanceof Array ? serverErrors.join(', ') : '';
130
+ return [errorsString, serverErrorsString].filter(x => x !== '').join(', ');
131
+ }
132
+ }
133
+ EntryDisplayControlValidationDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryDisplayControlValidationDirective, deps: [{ token: ENTRY_VALIDATION_CONFIG }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
134
+ EntryDisplayControlValidationDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: EntryDisplayControlValidationDirective, selector: "[entryDisplayControlValidation]", inputs: { control: "control" }, ngImport: i0 });
135
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryDisplayControlValidationDirective, decorators: [{
136
+ type: Directive,
137
+ args: [{
138
+ selector: '[entryDisplayControlValidation]'
139
+ }]
140
+ }], ctorParameters: function () { return [{ type: EntryValidationConfig, decorators: [{
141
+ type: Inject,
142
+ args: [ENTRY_VALIDATION_CONFIG]
143
+ }] }, { type: i0.ElementRef }]; }, propDecorators: { control: [{
144
+ type: Input
145
+ }] } });
146
+
147
+ class EntryValidationModule {
148
+ }
149
+ EntryValidationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryValidationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
150
+ EntryValidationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: EntryValidationModule, declarations: [EntryFormErrorsComponent,
151
+ EntryDisplayControlValidationDirective], imports: [CommonModule,
152
+ FormsModule,
153
+ ReactiveFormsModule,
154
+ MatInputModule], exports: [EntryFormErrorsComponent,
155
+ EntryDisplayControlValidationDirective] });
156
+ EntryValidationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryValidationModule, imports: [CommonModule,
157
+ FormsModule,
158
+ ReactiveFormsModule,
159
+ MatInputModule] });
160
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: EntryValidationModule, decorators: [{
161
+ type: NgModule,
162
+ args: [{
163
+ declarations: [
164
+ EntryFormErrorsComponent,
165
+ EntryDisplayControlValidationDirective
166
+ ],
167
+ imports: [
168
+ CommonModule,
169
+ FormsModule,
170
+ ReactiveFormsModule,
171
+ MatInputModule
172
+ ],
173
+ exports: [
174
+ EntryFormErrorsComponent,
175
+ EntryDisplayControlValidationDirective
176
+ ]
177
+ }]
178
+ }] });
179
+
180
+ /**
181
+ * Generated bundle index. Do not edit.
182
+ */
183
+
184
+ export { ENTRY_VALIDATION_CONFIG, EntryDisplayControlValidationDirective, EntryFormErrorsComponent, EntryValidationConfig, EntryValidationModule, FORM_FIELD_ERROR_KEY, handleValidationProblemDetails };
185
+ //# sourceMappingURL=enigmatry-entry-components-validation.mjs.map
@@ -0,0 +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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"}
@@ -2,6 +2,7 @@ export * from '@enigmatry/entry-components/header';
2
2
  export * from '@enigmatry/entry-components/dialog';
3
3
  export * from '@enigmatry/entry-components/search-filter';
4
4
  export * from '@enigmatry/entry-components/toolbar';
5
+ export * from '@enigmatry/entry-components/validation';
5
6
 
6
7
  /*
7
8
  * Public API Surface of entry-components
@@ -1 +1 @@
1
- {"version":3,"file":"enigmatry-entry-components.mjs","sources":["../../../../libs/entry-components/public-api.ts","../../../../libs/entry-components/enigmatry-entry-components.ts"],"sourcesContent":["/*\n * Public API Surface of entry-components\n */\n\nexport * from '@enigmatry/entry-components/header';\nexport * from '@enigmatry/entry-components/dialog';\nexport * from '@enigmatry/entry-components/search-filter';\nexport * from '@enigmatry/entry-components/toolbar';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;AAAA;;AAEG;;ACFH;;AAEG"}
1
+ {"version":3,"file":"enigmatry-entry-components.mjs","sources":["../../../../libs/entry-components/public-api.ts","../../../../libs/entry-components/enigmatry-entry-components.ts"],"sourcesContent":["/*\n * Public API Surface of entry-components\n */\n\nexport * from '@enigmatry/entry-components/header';\nexport * from '@enigmatry/entry-components/dialog';\nexport * from '@enigmatry/entry-components/search-filter';\nexport * from '@enigmatry/entry-components/toolbar';\nexport * from '@enigmatry/entry-components/validation';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;AAAA;;AAEG;;ACFH;;AAEG"}
@@ -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-size');
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
  }
@@ -4,6 +4,7 @@ $theme: (
4
4
  header: (
5
5
  background: vars.$primary-lightest,
6
6
  title-size: 32px,
7
+ title-color: vars.$primary,
7
8
  ),
8
9
  button-primary: (
9
10
  default-background: vars.$primary,
@@ -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
- .item {
35
+ .button {
37
36
  margin-left: 12px;
38
-
39
- &:first-child {
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: 4px vars.$large-gap vars.$default-gap;
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.6",
3
+ "version": "1.14.8",
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",
@@ -73,6 +73,14 @@
73
73
  "es2015": "./fesm2015/enigmatry-entry-components-toolbar.mjs",
74
74
  "node": "./fesm2015/enigmatry-entry-components-toolbar.mjs",
75
75
  "default": "./fesm2020/enigmatry-entry-components-toolbar.mjs"
76
+ },
77
+ "./validation": {
78
+ "types": "./validation/index.d.ts",
79
+ "esm2020": "./esm2020/validation/enigmatry-entry-components-validation.mjs",
80
+ "es2020": "./fesm2020/enigmatry-entry-components-validation.mjs",
81
+ "es2015": "./fesm2015/enigmatry-entry-components-validation.mjs",
82
+ "node": "./fesm2015/enigmatry-entry-components-validation.mjs",
83
+ "default": "./fesm2020/enigmatry-entry-components-validation.mjs"
76
84
  }
77
85
  },
78
86
  "sideEffects": false
package/public-api.d.ts CHANGED
@@ -2,3 +2,4 @@ export * from '@enigmatry/entry-components/header';
2
2
  export * from '@enigmatry/entry-components/dialog';
3
3
  export * from '@enigmatry/entry-components/search-filter';
4
4
  export * from '@enigmatry/entry-components/toolbar';
5
+ export * from '@enigmatry/entry-components/validation';
@@ -0,0 +1,85 @@
1
+ # Entry Validation
2
+
3
+ These components are used to apply server side validation messages, supplied in form of [Microsoft.AspNetCore.Mvc.ValidationProblemDetails](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.validationproblemdetails?view=aspnetcore-7.0), to the forms.
4
+
5
+ The validation errors can be applied on form or form field level.
6
+
7
+ * `<entry-form-errors>` component is used to render form level errors.
8
+ * `<entry-form-field-errors>` component is used to render form field level errors.
9
+
10
+ ## Imports
11
+
12
+ ```ts
13
+ import { EntryDialogModule } from '@enigmatry/entry-components/validation';
14
+ ```
15
+
16
+ Styles import:
17
+
18
+ ```css
19
+ @use '@enigmatry/entry-components/styles/generate' as entry;
20
+
21
+ @include entry.generate(APP_THEME, APP_TYPOGRAPHY);
22
+ ```
23
+
24
+ Where `APP_THEME` represents application theming configuration, while `APP_TYPOGRAPHY` represents application fonts configuration.
25
+
26
+ ## Basic usage
27
+
28
+ 1st, all API end-points that will be validated should be decorated with `ProducesResponseType` attribute that will map _BadRequest (400)_ errors to `ValidationProblemDetails` model. This is required, when using _NSwag_ so it knows how to generate 400 error response models:
29
+
30
+ ```csharp
31
+ using Microsoft.AspNetCore.Mvc;
32
+
33
+ // ...
34
+
35
+ [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
36
+ public async Task<ActionResult<Response>> Post([FromBody] Command command)
37
+
38
+ // ...
39
+ ```
40
+
41
+ Then, Formly needs to be configured so it knows how to map server side errors to the fields:
42
+
43
+ ```ts
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';
47
+
48
+ // ...
49
+
50
+ @NgModule({
51
+ // ...
52
+ imports: [
53
+ EntryValidationModule,
54
+ FormlyMaterialModule,
55
+ FormlyModule.forChild({
56
+ validationMessages: [
57
+ { name: FORM_FIELD_ERROR_KEY, message: (error, _) => error }
58
+ })
59
+ ]
60
+ // ...
61
+ })
62
+ export class AppModule { }
63
+ ```
64
+
65
+ Generated form component template with `entry-form-errors` component that displays form level server validations:
66
+
67
+ ```html
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
+ ```
72
+
73
+ And the last step, form submit _BadRequest (400)_ errors should be handled using `handleValidationProblemDetails()` method:
74
+
75
+ ```ts
76
+ import { IValidationProblemDetails, handleValidationProblemDetails } from '@enigmatry/entry-components';
77
+
78
+ // ...
79
+ submitForm() {
80
+ this._apiService.post()
81
+ .subscribe({
82
+ error: (error: IValidationProblemDetails) => handleValidationProblemDetails(this.form, error)
83
+ });
84
+ }
85
+ ```
@@ -0,0 +1,16 @@
1
+ import { ElementRef, OnDestroy, OnInit } from '@angular/core';
2
+ import { EntryValidationConfig } from './entry-validation-config.model';
3
+ import { AbstractControl } from '@angular/forms';
4
+ import * as i0 from "@angular/core";
5
+ export declare class EntryDisplayControlValidationDirective implements OnInit, OnDestroy {
6
+ private readonly _config;
7
+ private readonly _element;
8
+ control: AbstractControl;
9
+ private _controlSubscription;
10
+ constructor(_config: EntryValidationConfig, _element: ElementRef);
11
+ ngOnInit(): void;
12
+ ngOnDestroy(): void;
13
+ private extractValidationMessages;
14
+ static ɵfac: i0.ɵɵFactoryDeclaration<EntryDisplayControlValidationDirective, never>;
15
+ static ɵdir: i0.ɵɵDirectiveDeclaration<EntryDisplayControlValidationDirective, "[entryDisplayControlValidation]", never, { "control": "control"; }, {}, never, never, false>;
16
+ }
@@ -0,0 +1,17 @@
1
+ import { UntypedFormGroup } from '@angular/forms';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * A component used to display back-end validation errors on form level (errors that are not connected to the specific form field).
5
+ *
6
+ * This component will list validation errors one after another, each in separate row.
7
+ *
8
+ * @example
9
+ * ```html
10
+ * <entry-form-errors [form]="myForm"></entry-form-errors>
11
+ * ```
12
+ */
13
+ export declare class EntryFormErrorsComponent {
14
+ form: UntypedFormGroup;
15
+ static ɵfac: i0.ɵɵFactoryDeclaration<EntryFormErrorsComponent, never>;
16
+ static ɵcmp: i0.ɵɵComponentDeclaration<EntryFormErrorsComponent, "entry-form-errors", never, { "form": "form"; }, {}, never, never, false>;
17
+ }
@@ -0,0 +1,23 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ import { AbstractControl } from '@angular/forms';
3
+ /** Validation message configuration */
4
+ export interface IEntryValidationMessage {
5
+ name: string;
6
+ message: string | ((c: AbstractControl) => string);
7
+ }
8
+ /**
9
+ * Used to provide default configurations on module level.
10
+ */
11
+ export declare class EntryValidationConfig {
12
+ /** Validation key to message configuration on module level. */
13
+ validationMessages: IEntryValidationMessage[];
14
+ constructor(config?: Partial<EntryValidationConfig>);
15
+ }
16
+ /**
17
+ * Entry validation injection token of EntryValidationConfig type containing validation default configurations.
18
+ * Can be updated with custom configuration.
19
+ *
20
+ * Defaults:
21
+ * - validationMessages: []
22
+ */
23
+ export declare const ENTRY_VALIDATION_CONFIG: InjectionToken<EntryValidationConfig>;
@@ -0,0 +1,13 @@
1
+ import { UntypedFormGroup } from '@angular/forms';
2
+ import { IValidationProblemDetails } from './validation-problem-details.interface';
3
+ /** A key used to map server side validation errors on form field level */
4
+ declare const FORM_FIELD_ERROR_KEY = "fromServer";
5
+ /**
6
+ * Applies validation errors received from server side to the form.
7
+ * The errors are applied to multiple levels: form, form group, form array, and form field.
8
+ *
9
+ * @param form Form to apply validation errors to.
10
+ * @param error Server side validation errors response.
11
+ */
12
+ declare const handleValidationProblemDetails: (form: UntypedFormGroup, error: IValidationProblemDetails) => void;
13
+ export { FORM_FIELD_ERROR_KEY, handleValidationProblemDetails };
@@ -0,0 +1,11 @@
1
+ import * as i0 from "@angular/core";
2
+ import * as i1 from "./entry-form-errors.component";
3
+ import * as i2 from "./entry-display-control-validation.directive";
4
+ import * as i3 from "@angular/common";
5
+ import * as i4 from "@angular/forms";
6
+ import * as i5 from "@angular/material/input";
7
+ export declare class EntryValidationModule {
8
+ static ɵfac: i0.ɵɵFactoryDeclaration<EntryValidationModule, never>;
9
+ static ɵmod: i0.ɵɵNgModuleDeclaration<EntryValidationModule, [typeof i1.EntryFormErrorsComponent, typeof i2.EntryDisplayControlValidationDirective], [typeof i3.CommonModule, typeof i4.FormsModule, typeof i4.ReactiveFormsModule, typeof i5.MatInputModule], [typeof i1.EntryFormErrorsComponent, typeof i2.EntryDisplayControlValidationDirective]>;
10
+ static ɵinj: i0.ɵɵInjectorDeclaration<EntryValidationModule>;
11
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="@enigmatry/entry-components/validation" />
5
+ export * from './public-api';
@@ -0,0 +1,6 @@
1
+ export { EntryFormErrorsComponent } from './entry-form-errors.component';
2
+ export { EntryDisplayControlValidationDirective } from './entry-display-control-validation.directive';
3
+ export { EntryValidationModule } from './entry-validation.module';
4
+ export { IValidationProblemDetails } from './validation-problem-details.interface';
5
+ export * from './entry-validation';
6
+ export { ENTRY_VALIDATION_CONFIG, EntryValidationConfig, IEntryValidationMessage } from './entry-validation-config.model';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Defines the api, a sub-set of `Microsoft.AspNetCore.Mvc.ValidationProblemDetails` class,
3
+ * which used as a container for server side validation errors.
4
+ */
5
+ export interface IValidationProblemDetails {
6
+ [key: string]: any;
7
+ errors?: {
8
+ [key: string]: string[];
9
+ };
10
+ }