@gravitee/ui-particles-angular 5.14.0 → 5.15.0

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.
@@ -1,7 +1,7 @@
1
1
  import { trigger, transition, style, animate } from '@angular/animations';
2
2
  import * as i0 from '@angular/core';
3
3
  import { EventEmitter, Component, HostBinding, Input, Output, HostListener, NgModule, Optional, Self, ViewChild, Directive, Inject, forwardRef, ChangeDetectionStrategy, Injectable, ViewEncapsulation, ContentChildren, Host, ContentChild, InjectionToken } from '@angular/core';
4
- import { timer, Subject, fromEvent, of, BehaviorSubject, ReplaySubject } from 'rxjs';
4
+ import { timer, Subject, fromEvent, of, BehaviorSubject, combineLatest, ReplaySubject } from 'rxjs';
5
5
  import * as i1 from '@angular/material/card';
6
6
  import { MatCardModule } from '@angular/material/card';
7
7
  import * as i2 from '@angular/material/button';
@@ -14,7 +14,7 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion';
14
14
  import * as i3$1 from '@angular/material/form-field';
15
15
  import { MatFormFieldControl, MatFormFieldModule, MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
16
16
  import { isEmpty, toLower, dropRight, isNil, isArray, remove, isObject, cloneDeep, set, uniqueId } from 'lodash';
17
- import { startWith, map, distinctUntilChanged, tap, debounce, takeUntil, delay, filter, switchMap } from 'rxjs/operators';
17
+ import { startWith, map, distinctUntilChanged, tap, debounce, takeUntil, delay, filter, switchMap, debounceTime } from 'rxjs/operators';
18
18
  import * as i7 from '@angular/forms';
19
19
  import { FormsModule, FormArray, FormGroup, FormControl, NG_VALUE_ACCESSOR, ReactiveFormsModule, NgControl } from '@angular/forms';
20
20
  import * as i2$2 from '@angular/cdk/a11y';
@@ -2762,6 +2762,7 @@ class GioFormlyJsonSchemaService {
2762
2762
  return this.formlyJsonschema.toFieldConfig(jsonSchema, {
2763
2763
  map: (mappedField, mapSource) => {
2764
2764
  mappedField = this.uiTypeMap(mappedField, mapSource);
2765
+ mappedField = this.formatMap(mappedField, mapSource);
2765
2766
  mappedField = this.bannerMap(mappedField, mapSource);
2766
2767
  mappedField = this.toggleMap(mappedField, mapSource);
2767
2768
  return mappedField;
@@ -2773,6 +2774,16 @@ class GioFormlyJsonSchemaService {
2773
2774
  mappedField.type = (_b = (_a = mapSource.gioConfig) === null || _a === void 0 ? void 0 : _a.uiType) !== null && _b !== void 0 ? _b : mappedField.type;
2774
2775
  return mappedField;
2775
2776
  }
2777
+ formatMap(mappedField, mapSource) {
2778
+ if (mapSource.type === 'string' && mapSource.format === 'text') {
2779
+ mappedField.type = 'textarea';
2780
+ mappedField.props = Object.assign(Object.assign({}, mappedField.props), { autosize: true });
2781
+ }
2782
+ else if (mapSource.type === 'string' && mapSource.format === 'password') {
2783
+ mappedField.props = Object.assign(Object.assign({}, mappedField.props), { type: 'password' });
2784
+ }
2785
+ return mappedField;
2786
+ }
2776
2787
  bannerMap(mappedField, mapSource) {
2777
2788
  var _a;
2778
2789
  mappedField.props = Object.assign(Object.assign({}, mappedField.props), (((_a = mapSource.gioConfig) === null || _a === void 0 ? void 0 : _a.banner) ? getBannerProperties(mapSource.gioConfig.banner) : {}));
@@ -2823,9 +2834,11 @@ class GioFormJsonSchemaComponent {
2823
2834
  this.options = {};
2824
2835
  this.model = {};
2825
2836
  this.fields = [];
2837
+ this.loading = true;
2826
2838
  this._onChange = () => ({});
2827
2839
  this._onTouched = () => ({});
2828
2840
  this.touched = false;
2841
+ this.stateChanges$ = new Subject();
2829
2842
  if (ngControl) {
2830
2843
  // Setting the value accessor directly (instead of using
2831
2844
  // the providers `NG_VALUE_ACCESSOR`) to avoid running into a circular import.
@@ -2846,24 +2859,37 @@ class GioFormJsonSchemaComponent {
2846
2859
  }
2847
2860
  ngOnInit() {
2848
2861
  var _a, _b, _c;
2849
- // When the parent form is touched, mark all the sub formGroup as touched
2862
+ // When the parent form is touched, mark all the sub formGroup as touched ony once
2850
2863
  const parentControl = (_b = (_a = this.ngControl) === null || _a === void 0 ? void 0 : _a.control) === null || _b === void 0 ? void 0 : _b.parent;
2851
- (_c = parentControl === null || parentControl === void 0 ? void 0 : parentControl.statusChanges) === null || _c === void 0 ? void 0 : _c.pipe(takeUntil(this.unsubscribe$), map(() => parentControl === null || parentControl === void 0 ? void 0 : parentControl.touched), filter(touched => touched === true), tap(() => this.formGroup.markAllAsTouched())).subscribe();
2852
- this.formGroup.statusChanges.pipe(takeUntil(this.unsubscribe$)).subscribe(status => {
2853
- var _a, _b, _c, _d;
2854
- if (status === 'VALID') {
2855
- (_b = (_a = this.ngControl) === null || _a === void 0 ? void 0 : _a.control) === null || _b === void 0 ? void 0 : _b.setErrors(null);
2856
- }
2857
- if (status === 'INVALID') {
2858
- (_d = (_c = this.ngControl) === null || _c === void 0 ? void 0 : _c.control) === null || _d === void 0 ? void 0 : _d.setErrors({ invalid: true });
2859
- }
2864
+ (_c = parentControl === null || parentControl === void 0 ? void 0 : parentControl.statusChanges) === null || _c === void 0 ? void 0 : _c.pipe(takeUntil(this.unsubscribe$), map(() => parentControl === null || parentControl === void 0 ? void 0 : parentControl.touched), filter(touched => touched === true), distinctUntilChanged()).subscribe(() => {
2865
+ this.formGroup.markAllAsTouched();
2866
+ this.stateChanges$.next();
2860
2867
  });
2861
2868
  // To simulate the behavior of classic form controls, emit value only when the form is touched
2862
2869
  // Allow to keep the formControl pristine until the user interact with it
2863
- this.formGroup.valueChanges
2864
- .pipe(takeUntil(this.unsubscribe$), filter(() => this.touched))
2865
- .subscribe(value => {
2866
- this._onChange(value);
2870
+ combineLatest([this.formGroup.statusChanges, this.formGroup.valueChanges])
2871
+ .pipe(takeUntil(this.unsubscribe$),
2872
+ // Group all valueChanges events emit by formly in a single one
2873
+ debounceTime(100))
2874
+ .subscribe(() => {
2875
+ this.stateChanges$.next();
2876
+ });
2877
+ this.stateChanges$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
2878
+ var _a, _b, _c, _d;
2879
+ const { status, value, touched } = this.formGroup;
2880
+ if (touched) {
2881
+ this._onTouched();
2882
+ this.touched = true;
2883
+ }
2884
+ if (this.touched) {
2885
+ this._onChange(value);
2886
+ if (status === 'VALID') {
2887
+ (_b = (_a = this.ngControl) === null || _a === void 0 ? void 0 : _a.control) === null || _b === void 0 ? void 0 : _b.setErrors(null);
2888
+ }
2889
+ if (status === 'INVALID') {
2890
+ (_d = (_c = this.ngControl) === null || _c === void 0 ? void 0 : _c.control) === null || _d === void 0 ? void 0 : _d.setErrors({ invalid: true });
2891
+ }
2892
+ }
2867
2893
  });
2868
2894
  }
2869
2895
  ngOnDestroy() {
@@ -3329,7 +3355,7 @@ GioFjsMultiSchemaTypeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
3329
3355
  </div>
3330
3356
  <formly-field *ngFor="let f of field.fieldGroup" [field]="f"></formly-field>
3331
3357
  </div>
3332
- `, isInline: true, styles: [".wrapper{padding:8px;border:1px solid #d3d5dc;border-radius:8px}.wrapper__title{font-size:16px;font-weight:500;line-height:24px;font:600 14px/20px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:.4px;margin-bottom:4px}.wrapper:empty{display:none}.wrapper__error{font:400 12px/16px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:normal;color:#ec4899}\n"], components: [{ type: i1$4.ɵFormlyValidationMessage, selector: "formly-validation-message", inputs: ["field"] }, { type: i1$4.FormlyField, selector: "formly-field", inputs: ["field"] }], directives: [{ type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
3358
+ `, isInline: true, styles: [".wrapper__title{font-size:16px;font-weight:500;line-height:24px;font:600 14px/20px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:.4px;margin-bottom:4px}.wrapper:empty{display:none}.wrapper__error{font:400 12px/16px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:normal;color:#ec4899}\n"], components: [{ type: i1$4.ɵFormlyValidationMessage, selector: "formly-validation-message", inputs: ["field"] }, { type: i1$4.FormlyField, selector: "formly-field", inputs: ["field"] }], directives: [{ type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
3333
3359
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: GioFjsMultiSchemaTypeComponent, decorators: [{
3334
3360
  type: Component,
3335
3361
  args: [{ selector: 'gio-fjs-multi-schema-type', template: `
@@ -3341,7 +3367,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
3341
3367
  </div>
3342
3368
  <formly-field *ngFor="let f of field.fieldGroup" [field]="f"></formly-field>
3343
3369
  </div>
3344
- `, styles: [".wrapper{padding:8px;border:1px solid #d3d5dc;border-radius:8px}.wrapper__title{font-size:16px;font-weight:500;line-height:24px;font:600 14px/20px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:.4px;margin-bottom:4px}.wrapper:empty{display:none}.wrapper__error{font:400 12px/16px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:normal;color:#ec4899}\n"] }]
3370
+ `, styles: [".wrapper__title{font-size:16px;font-weight:500;line-height:24px;font:600 14px/20px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:.4px;margin-bottom:4px}.wrapper:empty{display:none}.wrapper__error{font:400 12px/16px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:normal;color:#ec4899}\n"] }]
3345
3371
  }] });
3346
3372
 
3347
3373
  /*
@@ -3479,6 +3505,74 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
3479
3505
  `, styles: [".wrapper{display:flex;flex-direction:column;padding:8px;border:1px solid #d3d5dc;border-radius:8px}.wrapper__header{display:flex}.wrapper__header__text{flex:1 1 auto}.wrapper__header__text__title{font:600 16px/24px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:.4px;margin-bottom:8px}.wrapper__header__collapse{flex:0 0 auto}.wrapper__header__collapse .collapse-open{transform:rotate(180deg);transition:transform 225ms cubic-bezier(.4,0,.2,1)}.wrapper__header__collapse .collapse-close{transform:rotate(0);transition:transform 225ms cubic-bezier(.4,0,.2,1)}.wrapper__error{font:400 12px/16px Golos UI,Roboto,Helvetica Neue,sans-serif;letter-spacing:normal;color:#ec4899}\n"] }]
3480
3506
  }] });
3481
3507
 
3508
+ /*
3509
+ * Copyright (C) 2023 The Gravitee team (http://gravitee.io)
3510
+ *
3511
+ * Licensed under the Apache License, Version 2.0 (the "License");
3512
+ * you may not use this file except in compliance with the License.
3513
+ * You may obtain a copy of the License at
3514
+ *
3515
+ * http://www.apache.org/licenses/LICENSE-2.0
3516
+ *
3517
+ * Unless required by applicable law or agreed to in writing, software
3518
+ * distributed under the License is distributed on an "AS IS" BASIS,
3519
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3520
+ * See the License for the specific language governing permissions and
3521
+ * limitations under the License.
3522
+ */
3523
+ class GioPasswordEyeWrapperComponent extends FieldWrapper {
3524
+ constructor() {
3525
+ super(...arguments);
3526
+ this.hide = true;
3527
+ }
3528
+ ngAfterViewInit() {
3529
+ if (this.matSuffix) {
3530
+ this.props.suffix = this.matSuffix;
3531
+ }
3532
+ }
3533
+ addonEyeClick($event) {
3534
+ $event.stopPropagation();
3535
+ this.hide = !this.hide;
3536
+ this.props.type = this.hide ? 'password' : 'text';
3537
+ }
3538
+ }
3539
+ GioPasswordEyeWrapperComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: GioPasswordEyeWrapperComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
3540
+ GioPasswordEyeWrapperComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: GioPasswordEyeWrapperComponent, selector: "gio-password-eye-wrapper", viewQueries: [{ propertyName: "matSuffix", first: true, predicate: ["matSuffix"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: `
3541
+ <ng-container #fieldComponent></ng-container>
3542
+
3543
+ <ng-template #matSuffix>
3544
+ <span style="cursor: pointer" (click)="addonEyeClick($event)">
3545
+ <mat-icon [svgIcon]="hide ? 'gio:eye-empty' : 'gio:eye-off'"></mat-icon>
3546
+ </span>
3547
+ </ng-template>
3548
+ `, isInline: true, components: [{ type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
3549
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: GioPasswordEyeWrapperComponent, decorators: [{
3550
+ type: Component,
3551
+ args: [{
3552
+ selector: 'gio-password-eye-wrapper',
3553
+ template: `
3554
+ <ng-container #fieldComponent></ng-container>
3555
+
3556
+ <ng-template #matSuffix>
3557
+ <span style="cursor: pointer" (click)="addonEyeClick($event)">
3558
+ <mat-icon [svgIcon]="hide ? 'gio:eye-empty' : 'gio:eye-off'"></mat-icon>
3559
+ </span>
3560
+ </ng-template>
3561
+ `,
3562
+ }]
3563
+ }], propDecorators: { matSuffix: [{
3564
+ type: ViewChild,
3565
+ args: ['matSuffix', { static: true }]
3566
+ }] } });
3567
+ function passwordEyeExtension(field) {
3568
+ if (!field.props || (field.wrappers && field.wrappers.indexOf('gio-password-eye') !== -1)) {
3569
+ return;
3570
+ }
3571
+ if (field.props.type === 'password') {
3572
+ field.wrappers = [...(field.wrappers || []), 'gio-password-eye'];
3573
+ }
3574
+ }
3575
+
3482
3576
  /*
3483
3577
  * Copyright (C) 2015 The Gravitee team (http://gravitee.io)
3484
3578
  *
@@ -3504,7 +3598,8 @@ GioFormJsonSchemaModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0",
3504
3598
  GioFjsArrayTypeComponent,
3505
3599
  GioFjsToggleTypeComponent,
3506
3600
  GioFjsHeadersTypeComponent,
3507
- GioFormFieldWrapperComponent], imports: [CommonModule,
3601
+ GioFormFieldWrapperComponent,
3602
+ GioPasswordEyeWrapperComponent], imports: [CommonModule,
3508
3603
  A11yModule,
3509
3604
  ReactiveFormsModule, i1$4.FormlyModule, FormlyMaterialModule,
3510
3605
  GioIconsModule,
@@ -3532,7 +3627,10 @@ GioFormJsonSchemaModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0",
3532
3627
  { name: 'uniqueItems', message: 'Should NOT have duplicate items' },
3533
3628
  { name: 'const', message: constValidationMessage },
3534
3629
  ],
3535
- wrappers: [{ name: 'gio-with-banner', component: GioFormFieldWrapperComponent }],
3630
+ wrappers: [
3631
+ { name: 'gio-with-banner', component: GioFormFieldWrapperComponent },
3632
+ { name: 'gio-password-eye', component: GioPasswordEyeWrapperComponent },
3633
+ ],
3536
3634
  types: [
3537
3635
  { name: 'null', component: GioFjsNullTypeComponent, wrappers: ['form-field'] },
3538
3636
  { name: 'array', component: GioFjsArrayTypeComponent },
@@ -3547,7 +3645,10 @@ GioFormJsonSchemaModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0",
3547
3645
  component: GioFjsHeadersTypeComponent,
3548
3646
  },
3549
3647
  ],
3550
- extensions: [{ name: 'banner', extension: { onPopulate: bannerExtension } }],
3648
+ extensions: [
3649
+ { name: 'banner', extension: { onPopulate: bannerExtension } },
3650
+ { name: 'password-eye', extension: { onPopulate: passwordEyeExtension } },
3651
+ ],
3551
3652
  extras: {
3552
3653
  checkExpressionOn: 'changeDetectionCheck',
3553
3654
  },
@@ -3571,6 +3672,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
3571
3672
  GioFjsToggleTypeComponent,
3572
3673
  GioFjsHeadersTypeComponent,
3573
3674
  GioFormFieldWrapperComponent,
3675
+ GioPasswordEyeWrapperComponent,
3574
3676
  ],
3575
3677
  imports: [
3576
3678
  CommonModule,
@@ -3592,7 +3694,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
3592
3694
  { name: 'uniqueItems', message: 'Should NOT have duplicate items' },
3593
3695
  { name: 'const', message: constValidationMessage },
3594
3696
  ],
3595
- wrappers: [{ name: 'gio-with-banner', component: GioFormFieldWrapperComponent }],
3697
+ wrappers: [
3698
+ { name: 'gio-with-banner', component: GioFormFieldWrapperComponent },
3699
+ { name: 'gio-password-eye', component: GioPasswordEyeWrapperComponent },
3700
+ ],
3596
3701
  types: [
3597
3702
  { name: 'null', component: GioFjsNullTypeComponent, wrappers: ['form-field'] },
3598
3703
  { name: 'array', component: GioFjsArrayTypeComponent },
@@ -3607,7 +3712,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImpo
3607
3712
  component: GioFjsHeadersTypeComponent,
3608
3713
  },
3609
3714
  ],
3610
- extensions: [{ name: 'banner', extension: { onPopulate: bannerExtension } }],
3715
+ extensions: [
3716
+ { name: 'banner', extension: { onPopulate: bannerExtension } },
3717
+ { name: 'password-eye', extension: { onPopulate: passwordEyeExtension } },
3718
+ ],
3611
3719
  extras: {
3612
3720
  checkExpressionOn: 'changeDetectionCheck',
3613
3721
  },
@@ -3647,17 +3755,17 @@ class GioFormFocusInvalidDirective {
3647
3755
  onFormSubmit() {
3648
3756
  const selector = '.ng-invalid[formControlName],input.ng-invalid,mat-select.ng-invalid,textarea.ng-invalid,.gio-ng-invalid';
3649
3757
  try {
3758
+ // Mark all controls as touched to display errors
3759
+ if (this.formGroupDirective) {
3760
+ this.formGroupDirective.control.markAllAsTouched();
3761
+ this.formGroupDirective.control.updateValueAndValidity();
3762
+ }
3650
3763
  let invalidControl = this.renderer.selectRootElement(selector, true);
3651
3764
  // If the form is a GioFormJsonSchema, we need to focus the first invalid control inside
3652
3765
  if (invalidControl.tagName === 'GIO-FORM-JSON-SCHEMA') {
3653
3766
  invalidControl = invalidControl.querySelector(selector);
3654
3767
  }
3655
3768
  if (invalidControl) {
3656
- // Mark all controls as touched to display errors
3657
- if (this.formGroupDirective) {
3658
- this.formGroupDirective.control.markAllAsTouched();
3659
- this.formGroupDirective.control.updateValueAndValidity();
3660
- }
3661
3769
  invalidControl.scrollIntoView({ behavior: 'smooth', block: 'center' });
3662
3770
  invalidControl.focus({ preventScroll: true });
3663
3771
  }