ng-configcat-publicapi-ui 2.13.0 → 2.13.2

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 (40) hide show
  1. package/esm2020/lib/_directives/index.mjs +2 -0
  2. package/esm2020/lib/_directives/input-display-normalizer.directive.mjs +38 -0
  3. package/esm2020/lib/_services/form-helper.mjs +44 -1
  4. package/esm2020/lib/_services/platform-helper.mjs +7 -0
  5. package/esm2020/lib/_services/public-api.service.mjs +4 -4
  6. package/esm2020/lib/_services/setting-list-form-helper.mjs +26 -5
  7. package/esm2020/lib/authorization/authorization.component.mjs +4 -4
  8. package/esm2020/lib/base/base.component.mjs +4 -4
  9. package/esm2020/lib/configuration.mjs +4 -4
  10. package/esm2020/lib/dialogs/concurrent-dialog/concurrent-dialog.component.mjs +4 -4
  11. package/esm2020/lib/dialogs/expand-dialog/expand-dialog.component.mjs +4 -4
  12. package/esm2020/lib/dialogs/reason-dialog/reason-dialog.component.mjs +4 -4
  13. package/esm2020/lib/dialogs/save-snackbar/save-snackbar.component.mjs +4 -4
  14. package/esm2020/lib/ng-configcat-publicapi-ui.module.mjs +14 -9
  15. package/esm2020/lib/selects/config-select/config-select.component.mjs +4 -4
  16. package/esm2020/lib/selects/environment-select/environment-select.component.mjs +4 -4
  17. package/esm2020/lib/selects/product-select/product-select.component.mjs +4 -4
  18. package/esm2020/lib/selects/setting-select/setting-select.component.mjs +4 -4
  19. package/esm2020/lib/setting-item/setting-item.component.mjs +4 -4
  20. package/esm2020/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.mjs +4 -4
  21. package/esm2020/lib/setting-list/setting/rollout-rules/rollout-rules.component.mjs +29 -28
  22. package/esm2020/lib/setting-list/setting/setting.component.mjs +4 -4
  23. package/esm2020/lib/setting-list/setting/value/value.component.mjs +10 -5
  24. package/esm2020/lib/setting-list/setting-list.component.mjs +24 -5
  25. package/esm2020/public-api.mjs +2 -1
  26. package/fesm2015/ng-configcat-publicapi-ui.mjs +226 -96
  27. package/fesm2015/ng-configcat-publicapi-ui.mjs.map +1 -1
  28. package/fesm2020/ng-configcat-publicapi-ui.mjs +225 -96
  29. package/fesm2020/ng-configcat-publicapi-ui.mjs.map +1 -1
  30. package/lib/_directives/index.d.ts +1 -0
  31. package/lib/_directives/input-display-normalizer.directive.d.ts +13 -0
  32. package/lib/_services/form-helper.d.ts +12 -0
  33. package/lib/_services/platform-helper.d.ts +3 -0
  34. package/lib/_services/setting-list-form-helper.d.ts +3 -1
  35. package/lib/ng-configcat-publicapi-ui.module.d.ts +20 -19
  36. package/lib/setting-list/setting/rollout-rules/rollout-rules.component.d.ts +3 -1
  37. package/lib/setting-list/setting/value/value.component.d.ts +1 -0
  38. package/lib/setting-list/setting-list.component.d.ts +1 -0
  39. package/package.json +4 -4
  40. package/public-api.d.ts +1 -0
@@ -1,15 +1,15 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, Optional, Component, Input, Inject, EventEmitter, Output, forwardRef, NgModule } from '@angular/core';
2
+ import { Injectable, Optional, Component, Input, Inject, Directive, HostListener, EventEmitter, Output, forwardRef, NgModule } from '@angular/core';
3
3
  import { MeService, Configuration as Configuration$1, ProductsService, ConfigsService, EnvironmentsService, FeatureFlagsSettingsService, FeatureFlagSettingValuesService, IntegrationLinksService, SegmentsService, SettingType, RolloutRuleComparator, SegmentComparator, ApiModule } from 'ng-configcat-publicapi';
4
4
  import * as i1 from '@angular/common/http';
5
5
  import { HttpErrorResponse } from '@angular/common/http';
6
6
  import { forkJoin, throwError, of } from 'rxjs';
7
7
  import { map, catchError } from 'rxjs/operators';
8
- import * as i3 from '@angular/forms';
8
+ import * as i2 from '@angular/forms';
9
9
  import { Validators, NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule } from '@angular/forms';
10
10
  import * as i1$1 from '@angular/material/dialog';
11
11
  import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
12
- import * as i2 from '@angular/common';
12
+ import * as i2$1 from '@angular/common';
13
13
  import { CommonModule } from '@angular/common';
14
14
  import * as i4 from '@angular/material/form-field';
15
15
  import { MatFormFieldModule } from '@angular/material/form-field';
@@ -17,22 +17,22 @@ import * as i5 from '@angular/material/button';
17
17
  import { MatButtonModule } from '@angular/material/button';
18
18
  import * as i6 from '@angular/material/input';
19
19
  import { MatInputModule } from '@angular/material/input';
20
- import * as i3$1 from '@angular/router';
20
+ import * as i3 from '@angular/router';
21
21
  import { RouterModule } from '@angular/router';
22
- import * as i2$1 from '@angular/material/snack-bar';
22
+ import * as i2$2 from '@angular/material/snack-bar';
23
23
  import { MatSnackBarModule } from '@angular/material/snack-bar';
24
- import * as i4$1 from '@angular/material/icon';
24
+ import * as i7 from '@angular/material/icon';
25
25
  import { MatIconModule } from '@angular/material/icon';
26
26
  import * as i5$1 from '@angular/material/tooltip';
27
27
  import { MatTooltipModule } from '@angular/material/tooltip';
28
28
  import * as i5$2 from '@angular/material/chips';
29
29
  import { MatChipsModule } from '@angular/material/chips';
30
- import * as i10 from '@angular/cdk/drag-drop';
30
+ import * as i11 from '@angular/cdk/drag-drop';
31
31
  import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
32
32
  import { valid } from 'semver';
33
33
  import * as i5$3 from '@angular/material/core';
34
34
  import { MatOptionModule } from '@angular/material/core';
35
- import * as i9 from '@angular/material/autocomplete';
35
+ import * as i10 from '@angular/material/autocomplete';
36
36
  import { MatAutocompleteModule } from '@angular/material/autocomplete';
37
37
  import * as i6$1 from '@angular/material/select';
38
38
  import { MatSelectModule } from '@angular/material/select';
@@ -45,9 +45,9 @@ class Configuration {
45
45
  this.dashboardBasePath = 'https://app.configcat.com';
46
46
  }
47
47
  }
48
- Configuration.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: Configuration, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
49
- Configuration.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: Configuration });
50
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: Configuration, decorators: [{
48
+ Configuration.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: Configuration, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
49
+ Configuration.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: Configuration });
50
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: Configuration, decorators: [{
51
51
  type: Injectable
52
52
  }] });
53
53
 
@@ -117,9 +117,9 @@ class PublicApiService {
117
117
  return (_b = (_a = this.configuration) === null || _a === void 0 ? void 0 : _a.dashboardBasePath) !== null && _b !== void 0 ? _b : 'https://app.configcat.com';
118
118
  }
119
119
  }
120
- PublicApiService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: PublicApiService, deps: [{ token: i1.HttpClient }, { token: Configuration, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
121
- PublicApiService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: PublicApiService, providedIn: 'root' });
122
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: PublicApiService, decorators: [{
120
+ PublicApiService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: PublicApiService, deps: [{ token: i1.HttpClient }, { token: Configuration, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
121
+ PublicApiService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: PublicApiService, providedIn: 'root' });
122
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: PublicApiService, decorators: [{
123
123
  type: Injectable,
124
124
  args: [{ providedIn: 'root' }]
125
125
  }], ctorParameters: function () {
@@ -154,9 +154,9 @@ class BaseComponent {
154
154
  return this.publicApiService.createSegmentsService(this.basicAuthUsername, this.basicAuthPassword, this.basePath);
155
155
  }
156
156
  }
157
- BaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BaseComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
158
- BaseComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: BaseComponent, selector: "base", inputs: { basePath: "basePath", basicAuthUsername: "basicAuthUsername", basicAuthPassword: "basicAuthPassword" }, ngImport: i0, template: '<div></div>', isInline: true });
159
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BaseComponent, decorators: [{
157
+ BaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BaseComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
158
+ BaseComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: BaseComponent, selector: "base", inputs: { basePath: "basePath", basicAuthUsername: "basicAuthUsername", basicAuthPassword: "basicAuthPassword" }, ngImport: i0, template: '<div></div>', isInline: true });
159
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BaseComponent, decorators: [{
160
160
  type: Component,
161
161
  args: [{
162
162
  selector: 'base',
@@ -170,6 +170,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
170
170
  type: Input
171
171
  }] } });
172
172
 
173
+ class PlatformHelper {
174
+ static isChromium() {
175
+ // https://stackoverflow.com/a/62797156/8656352
176
+ return !!window.chrome;
177
+ }
178
+ }
179
+
173
180
  class FormHelper {
174
181
  static getErrorMessage(control, hint = '') {
175
182
  if (!control || control.valid) {
@@ -229,6 +236,48 @@ class FormHelper {
229
236
  formGroup.setErrors({ serverSide: 'Something went wrong on our side. This is not your fault. Please try again.' });
230
237
  }
231
238
  }
239
+ /**
240
+ * Converts a value representing a number to a `number` value.
241
+ * Returns `NaN` in the case of non-numerical values.
242
+ */
243
+ static normalizeNumber(value) {
244
+ switch (typeof value) {
245
+ case "number":
246
+ return value;
247
+ case "string":
248
+ // NOTE: `Number()` converts whitespace strings to 0.
249
+ return value.trim() === '' ? NaN : Number(value);
250
+ case "bigint":
251
+ return Number(value);
252
+ default:
253
+ return NaN;
254
+ }
255
+ }
256
+ /**
257
+ * Converts a value representing a number to the normalized `string`
258
+ * representation of the number. (e.g. `.1` --> `'0.1'`, `3.14e2` --> `'314'`).
259
+ * Returns `''` in the case of non-numerical values or non-finite numerical values.
260
+ */
261
+ static normalizeNumberStoredAsString(value) {
262
+ value = FormHelper.normalizeNumber(value);
263
+ // NOTE: `NaN` is not considered finite.
264
+ return isFinite(value) ? value + '' : '';
265
+ }
266
+ static formatNumberForDisplay(value) {
267
+ if (!isFinite(value)) {
268
+ return '';
269
+ }
270
+ // Chromium-based browsers don't respect the `lang` attribute,
271
+ // they use a display format corresponding to the browser's language setting.
272
+ if (PlatformHelper.isChromium()) {
273
+ return value.toLocaleString();
274
+ }
275
+ // Firefox (and probably other browsers) respect the `lang` attribute,
276
+ // which is currently set to the fixed value of "en" (see index.html),
277
+ // so in these cases dot should be used as the decimal separator.
278
+ // (In case localization is implemented in the application, this logic should be revised!)
279
+ return value + '';
280
+ }
232
281
  }
233
282
 
234
283
  class ReasonDialogComponent {
@@ -251,21 +300,21 @@ class ReasonDialogComponent {
251
300
  this.dialogRef.close({ button: 'cancel' });
252
301
  }
253
302
  }
254
- ReasonDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: ReasonDialogComponent, deps: [{ token: i1$1.MatDialogRef }, { token: i3.UntypedFormBuilder }], target: i0.ɵɵFactoryTarget.Component });
255
- ReasonDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: ReasonDialogComponent, selector: "configcat-reason-dialog", ngImport: i0, template: "<h3 mat-dialog-title>Add notes</h3>\n<p>This will appear in the Why column of the Audit Log.</p>\n<form [formGroup]=\"formGroup\" (ngSubmit)=\"handleSaveButton()\">\n <div mat-dialog-content class=\"container\">\n <mat-form-field appearance=\"outline\">\n <mat-label></mat-label>\n <textarea matInput formControlName=\"reason\" name=\"reason\" placeholder=\"I'm changing settings because...\"\n rows=\"3\"></textarea>\n <mat-error *ngIf=\"formGroup.controls.reason.invalid\">The field is required.</mat-error>\n </mat-form-field>\n </div>\n <br>\n <div mat-dialog-actions>\n <button type=\"submit\" style=\"margin-right: 10px;\" mat-flat-button color=\"primary\">Add notes & Save</button>\n <button type=\"button\" mat-stroked-button (click)=\"cancel()\">Cancel</button>\n </div>\n</form>", styles: [".container>*{width:100%}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i4.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i1$1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }] });
256
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: ReasonDialogComponent, decorators: [{
303
+ ReasonDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ReasonDialogComponent, deps: [{ token: i1$1.MatDialogRef }, { token: i2.UntypedFormBuilder }], target: i0.ɵɵFactoryTarget.Component });
304
+ ReasonDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: ReasonDialogComponent, selector: "configcat-reason-dialog", ngImport: i0, template: "<h3 mat-dialog-title>Add notes</h3>\n<p>This will appear in the Why column of the Audit Log.</p>\n<form [formGroup]=\"formGroup\" (ngSubmit)=\"handleSaveButton()\">\n <div mat-dialog-content class=\"container\">\n <mat-form-field appearance=\"outline\">\n <mat-label></mat-label>\n <textarea matInput formControlName=\"reason\" name=\"reason\" placeholder=\"I'm changing settings because...\"\n rows=\"3\"></textarea>\n <mat-error *ngIf=\"formGroup.controls.reason.invalid\">The field is required.</mat-error>\n </mat-form-field>\n </div>\n <br>\n <div mat-dialog-actions>\n <button type=\"submit\" style=\"margin-right: 10px;\" mat-flat-button color=\"primary\">Add notes & Save</button>\n <button type=\"button\" mat-stroked-button (click)=\"cancel()\">Cancel</button>\n </div>\n</form>", styles: [".container>*{width:100%}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i4.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i1$1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }] });
305
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ReasonDialogComponent, decorators: [{
257
306
  type: Component,
258
307
  args: [{ selector: 'configcat-reason-dialog', template: "<h3 mat-dialog-title>Add notes</h3>\n<p>This will appear in the Why column of the Audit Log.</p>\n<form [formGroup]=\"formGroup\" (ngSubmit)=\"handleSaveButton()\">\n <div mat-dialog-content class=\"container\">\n <mat-form-field appearance=\"outline\">\n <mat-label></mat-label>\n <textarea matInput formControlName=\"reason\" name=\"reason\" placeholder=\"I'm changing settings because...\"\n rows=\"3\"></textarea>\n <mat-error *ngIf=\"formGroup.controls.reason.invalid\">The field is required.</mat-error>\n </mat-form-field>\n </div>\n <br>\n <div mat-dialog-actions>\n <button type=\"submit\" style=\"margin-right: 10px;\" mat-flat-button color=\"primary\">Add notes & Save</button>\n <button type=\"button\" mat-stroked-button (click)=\"cancel()\">Cancel</button>\n </div>\n</form>", styles: [".container>*{width:100%}\n"] }]
259
- }], ctorParameters: function () { return [{ type: i1$1.MatDialogRef }, { type: i3.UntypedFormBuilder }]; } });
308
+ }], ctorParameters: function () { return [{ type: i1$1.MatDialogRef }, { type: i2.UntypedFormBuilder }]; } });
260
309
 
261
310
  class SaveSnackbarComponent {
262
311
  constructor() { }
263
312
  ngOnInit() {
264
313
  }
265
314
  }
266
- SaveSnackbarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: SaveSnackbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
267
- SaveSnackbarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: SaveSnackbarComponent, selector: "configcat-save-snackbar", ngImport: i0, template: "<p class=\"header\">Settings saved successfully.</p>", styles: ["p{text-align:center;font-weight:700}.header{font-size:1.2em}\n"] });
268
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: SaveSnackbarComponent, decorators: [{
315
+ SaveSnackbarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SaveSnackbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
316
+ SaveSnackbarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: SaveSnackbarComponent, selector: "configcat-save-snackbar", ngImport: i0, template: "<p class=\"header\">Settings saved successfully.</p>", styles: ["p{text-align:center;font-weight:700}.header{font-size:1.2em}\n"] });
317
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SaveSnackbarComponent, decorators: [{
269
318
  type: Component,
270
319
  args: [{ selector: 'configcat-save-snackbar', template: "<p class=\"header\">Settings saved successfully.</p>", styles: ["p{text-align:center;font-weight:700}.header{font-size:1.2em}\n"] }]
271
320
  }], ctorParameters: function () { return []; } });
@@ -283,9 +332,9 @@ class ConcurrentDialogComponent {
283
332
  this.dialogRef.close({ button: 'discard' });
284
333
  }
285
334
  }
286
- ConcurrentDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: ConcurrentDialogComponent, deps: [{ token: i1$1.MatDialogRef }], target: i0.ɵɵFactoryTarget.Component });
287
- ConcurrentDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: ConcurrentDialogComponent, selector: "configcat-concurrent-dialog", ngImport: i0, template: "<h3 mat-dialog-title>Concurrent update detected</h3>\n<p>\n Somebody updated the feature flags & settings while you were editing them.\n</p>\n<ul>\n <li>\n To discard your local changes and reload the updated values, click <strong>Discard my changes & reload</strong>\n </li>\n <li>\n To save you local values and overwrite the remote changes, click <strong>Save anyway</strong>\n </li>\n</ul>\n<p>For more info about the changes check the <a [routerLink]=\"['/auditlog']\" target=\"_blank\" rel=\"noopener noreferrer\" >audit logs</a> in a new tab.</p>\n<div mat-dialog-actions>\n <button type=\"button\" style=\"margin-right: 10px;\" mat-flat-button color=\"primary\" (click)=\"discard()\">Discard\n local changes & reload</button>\n <button type=\"button\" mat-stroked-button (click)=\"save()\">Save anyway</button>\n</div>", styles: [""], dependencies: [{ kind: "component", type: i5.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i3$1.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { kind: "directive", type: i1$1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }] });
288
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: ConcurrentDialogComponent, decorators: [{
335
+ ConcurrentDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ConcurrentDialogComponent, deps: [{ token: i1$1.MatDialogRef }], target: i0.ɵɵFactoryTarget.Component });
336
+ ConcurrentDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: ConcurrentDialogComponent, selector: "configcat-concurrent-dialog", ngImport: i0, template: "<h3 mat-dialog-title>Concurrent update detected</h3>\n<p>\n Somebody updated the feature flags & settings while you were editing them.\n</p>\n<ul>\n <li>\n To discard your local changes and reload the updated values, click <strong>Discard my changes & reload</strong>\n </li>\n <li>\n To save you local values and overwrite the remote changes, click <strong>Save anyway</strong>\n </li>\n</ul>\n<p>For more info about the changes check the <a [routerLink]=\"['/auditlog']\" target=\"_blank\" rel=\"noopener noreferrer\" >audit logs</a> in a new tab.</p>\n<div mat-dialog-actions>\n <button type=\"button\" style=\"margin-right: 10px;\" mat-flat-button color=\"primary\" (click)=\"discard()\">Discard\n local changes & reload</button>\n <button type=\"button\" mat-stroked-button (click)=\"save()\">Save anyway</button>\n</div>", styles: [""], dependencies: [{ kind: "component", type: i5.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i3.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1$1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }] });
337
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ConcurrentDialogComponent, decorators: [{
289
338
  type: Component,
290
339
  args: [{ selector: 'configcat-concurrent-dialog', template: "<h3 mat-dialog-title>Concurrent update detected</h3>\n<p>\n Somebody updated the feature flags & settings while you were editing them.\n</p>\n<ul>\n <li>\n To discard your local changes and reload the updated values, click <strong>Discard my changes & reload</strong>\n </li>\n <li>\n To save you local values and overwrite the remote changes, click <strong>Save anyway</strong>\n </li>\n</ul>\n<p>For more info about the changes check the <a [routerLink]=\"['/auditlog']\" target=\"_blank\" rel=\"noopener noreferrer\" >audit logs</a> in a new tab.</p>\n<div mat-dialog-actions>\n <button type=\"button\" style=\"margin-right: 10px;\" mat-flat-button color=\"primary\" (click)=\"discard()\">Discard\n local changes & reload</button>\n <button type=\"button\" mat-stroked-button (click)=\"save()\">Save anyway</button>\n</div>" }]
291
340
  }], ctorParameters: function () { return [{ type: i1$1.MatDialogRef }]; } });
@@ -427,13 +476,33 @@ class SettingListFormHelper {
427
476
  return [];
428
477
  }
429
478
  }
479
+ getComparisonValueType(comparator) {
480
+ switch (comparator) {
481
+ case RolloutRuleComparator.NumberEquals:
482
+ case RolloutRuleComparator.NumberDoesNotEqual:
483
+ case RolloutRuleComparator.NumberLess:
484
+ case RolloutRuleComparator.NumberLessOrEquals:
485
+ case RolloutRuleComparator.NumberGreater:
486
+ case RolloutRuleComparator.NumberGreaterOrEquals:
487
+ return 'number';
488
+ default:
489
+ return 'text';
490
+ }
491
+ }
492
+ normalizeComparisonValue(comparator, comparisonValue) {
493
+ // In the case of number inputs value is a number but API expects
494
+ // a string, so we need to make sure that it's converted to string.
495
+ return comparator && this.getComparisonValueType(comparator) === "number"
496
+ ? FormHelper.normalizeNumberStoredAsString(comparisonValue)
497
+ : comparisonValue;
498
+ }
430
499
  }
431
- SettingListFormHelper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: SettingListFormHelper, deps: [{ token: i3.UntypedFormBuilder }], target: i0.ɵɵFactoryTarget.Injectable });
432
- SettingListFormHelper.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: SettingListFormHelper, providedIn: 'root' });
433
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: SettingListFormHelper, decorators: [{
500
+ SettingListFormHelper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SettingListFormHelper, deps: [{ token: i2.UntypedFormBuilder }], target: i0.ɵɵFactoryTarget.Injectable });
501
+ SettingListFormHelper.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SettingListFormHelper, providedIn: 'root' });
502
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SettingListFormHelper, decorators: [{
434
503
  type: Injectable,
435
504
  args: [{ providedIn: 'root' }]
436
- }], ctorParameters: function () { return [{ type: i3.UntypedFormBuilder }]; } });
505
+ }], ctorParameters: function () { return [{ type: i2.UntypedFormBuilder }]; } });
437
506
 
438
507
  class ExpandDialogComponent {
439
508
  constructor(dialogRef, formBuilder, data) {
@@ -492,18 +561,54 @@ class ExpandDialogComponent {
492
561
  this.dialogRef.close();
493
562
  }
494
563
  }
495
- ExpandDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: ExpandDialogComponent, deps: [{ token: i1$1.MatDialogRef }, { token: i3.UntypedFormBuilder }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
496
- ExpandDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: ExpandDialogComponent, selector: "configcat-expand-dialog", ngImport: i0, template: "<div mat-dialog-content class=\"container\">\n\n <mat-form-field appearance=\"outline\" *ngIf=\"!data.multiline\">\n <mat-label></mat-label>\n <textarea matInput [formControl]=\"data.control\" rows=\"15\"></textarea>\n </mat-form-field>\n <div [formGroup]=\"formGroup\" *ngIf=\"data.multiline\">\n <div *ngFor=\"let valueControl of getValueControls(); let i = index;\"\n class=\"value-field\">\n <mat-form-field appearance=\"outline\">\n <input matInput [formControl]=\"valueControl\" rows=\"15\" />\n </mat-form-field>\n <button (click)=\"remove(i)\" mat-icon-button type=\"button\">\n <mat-icon>delete_outline</mat-icon>\n </button>\n </div>\n <button (click)=\"add()\" mat-icon-button type=\"button\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n</div>\n<div mat-dialog-actions>\n <button type=\"button\" mat-flat-button color=\"primary\" (click)=\"close()\">Done</button>\n</div>", styles: [".container>*{width:100%}.container>* .value-field{display:flex;font-size:12px;flex-wrap:nowrap}.container>* .value-field mat-form-field{flex-grow:1}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }] });
497
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: ExpandDialogComponent, decorators: [{
564
+ ExpandDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ExpandDialogComponent, deps: [{ token: i1$1.MatDialogRef }, { token: i2.UntypedFormBuilder }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
565
+ ExpandDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: ExpandDialogComponent, selector: "configcat-expand-dialog", ngImport: i0, template: "<div mat-dialog-content class=\"container\">\n\n <mat-form-field appearance=\"outline\" *ngIf=\"!data.multiline\">\n <mat-label></mat-label>\n <textarea matInput [formControl]=\"data.control\" rows=\"15\"></textarea>\n </mat-form-field>\n <div [formGroup]=\"formGroup\" *ngIf=\"data.multiline\">\n <div *ngFor=\"let valueControl of getValueControls(); let i = index;\"\n class=\"value-field\">\n <mat-form-field appearance=\"outline\">\n <input matInput [formControl]=\"valueControl\" rows=\"15\" />\n </mat-form-field>\n <button (click)=\"remove(i)\" mat-icon-button type=\"button\">\n <mat-icon>delete_outline</mat-icon>\n </button>\n </div>\n <button (click)=\"add()\" mat-icon-button type=\"button\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n</div>\n<div mat-dialog-actions>\n <button type=\"button\" mat-flat-button color=\"primary\" (click)=\"close()\">Done</button>\n</div>", styles: [".container>*{width:100%}.container>* .value-field{display:flex;font-size:12px;flex-wrap:nowrap}.container>* .value-field mat-form-field{flex-grow:1}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }] });
566
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ExpandDialogComponent, decorators: [{
498
567
  type: Component,
499
568
  args: [{ selector: 'configcat-expand-dialog', template: "<div mat-dialog-content class=\"container\">\n\n <mat-form-field appearance=\"outline\" *ngIf=\"!data.multiline\">\n <mat-label></mat-label>\n <textarea matInput [formControl]=\"data.control\" rows=\"15\"></textarea>\n </mat-form-field>\n <div [formGroup]=\"formGroup\" *ngIf=\"data.multiline\">\n <div *ngFor=\"let valueControl of getValueControls(); let i = index;\"\n class=\"value-field\">\n <mat-form-field appearance=\"outline\">\n <input matInput [formControl]=\"valueControl\" rows=\"15\" />\n </mat-form-field>\n <button (click)=\"remove(i)\" mat-icon-button type=\"button\">\n <mat-icon>delete_outline</mat-icon>\n </button>\n </div>\n <button (click)=\"add()\" mat-icon-button type=\"button\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n</div>\n<div mat-dialog-actions>\n <button type=\"button\" mat-flat-button color=\"primary\" (click)=\"close()\">Done</button>\n</div>", styles: [".container>*{width:100%}.container>* .value-field{display:flex;font-size:12px;flex-wrap:nowrap}.container>* .value-field mat-form-field{flex-grow:1}\n"] }]
500
569
  }], ctorParameters: function () {
501
- return [{ type: i1$1.MatDialogRef }, { type: i3.UntypedFormBuilder }, { type: undefined, decorators: [{
570
+ return [{ type: i1$1.MatDialogRef }, { type: i2.UntypedFormBuilder }, { type: undefined, decorators: [{
502
571
  type: Inject,
503
572
  args: [MAT_DIALOG_DATA]
504
573
  }] }];
505
574
  } });
506
575
 
576
+ /**
577
+ * Makes sure that values entered into HTML input fields are displayed in the correct format,
578
+ * where correct means normalized (e.g. `'.10'` --> `'0.1'`) and corresponding to the locale setting.
579
+ *
580
+ * The format is adjusted on the blur event. Only the format of number inputs is adjusted currently.
581
+ */
582
+ class InputDisplayNormalizerDirective {
583
+ constructor() { }
584
+ onChange($event) {
585
+ const target = $event.target;
586
+ if (target.type === 'number') {
587
+ let value = target.value;
588
+ value = value.trim() !== '' ? Number(value) : NaN;
589
+ if (isFinite(value)) {
590
+ // The string returned by the `value` property and the string displayed in the input field are not necessarily equal.
591
+ // HACK: When the returned and the displayed value differs only in the decimal separator,
592
+ // Chrome won't update the displayed value unless the value is changed first...
593
+ target.value = '';
594
+ target.value = value;
595
+ }
596
+ }
597
+ }
598
+ }
599
+ InputDisplayNormalizerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: InputDisplayNormalizerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
600
+ InputDisplayNormalizerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: InputDisplayNormalizerDirective, selector: "input[inputDisplayNormalizer]", host: { listeners: { "blur": "onChange($event)" } }, ngImport: i0 });
601
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: InputDisplayNormalizerDirective, decorators: [{
602
+ type: Directive,
603
+ args: [{
604
+ // eslint-disable-next-line @angular-eslint/directive-selector
605
+ selector: 'input[inputDisplayNormalizer]'
606
+ }]
607
+ }], ctorParameters: function () { return []; }, propDecorators: { onChange: [{
608
+ type: HostListener,
609
+ args: ['blur', ['$event']]
610
+ }] } });
611
+
507
612
  class ValueComponent {
508
613
  constructor(dialog) {
509
614
  this.dialog = dialog;
@@ -515,12 +620,15 @@ class ValueComponent {
515
620
  data: { control: this.valueFormControl }
516
621
  });
517
622
  }
623
+ formatDecimalNumber(value) {
624
+ return FormHelper.formatNumberForDisplay(value);
625
+ }
518
626
  }
519
- ValueComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: ValueComponent, deps: [{ token: i1$1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
520
- ValueComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: ValueComponent, selector: "configcat-value", inputs: { valueFormControl: "valueFormControl", setting: "setting" }, ngImport: i0, template: "<div class=\"flex\">\n <div class=\"container\" [ngSwitch]=\"setting.settingType\">\n <div *ngSwitchCase=\"SettingType.String\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"text\"\n [formControl]=\"valueFormControl\" placeholder=\"my value\" name=\"value\">\n <div class=\"expand\" (click)=\"popOut()\" matTooltip=\"Pop-out Editor\">\n <mat-icon>height</mat-icon>\n </div>\n </div>\n <div *ngSwitchCase=\"SettingType.Int\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"number\" [formControl]=\"valueFormControl\"\n placeholder=\"42\" name=\"value\" />\n </div>\n <div *ngSwitchCase=\"SettingType.Double\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"number\" [formControl]=\"valueFormControl\"\n placeholder=\"3.14\" name=\"value\">\n </div>\n <div *ngSwitchCase=\"SettingType.Boolean\" class=\"toggle\">\n <label class=\"switch\">\n <input type=\"checkbox\" [formControl]=\"valueFormControl\" name=\"value\" />\n <span class=\"slider round\"></span>\n </label>\n </div>\n </div>\n <div *ngIf=\"setting.settingType === SettingType.Boolean\" class=\"spacer\"></div>\n\n</div>\n", styles: [".switch{position:relative;width:66px;height:30px;margin-left:4px;margin-top:0;margin-bottom:0}.switch input{display:none}.slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ff5252;transition:.4s;width:66px;height:30px}.slider:before{position:absolute;content:\"\";height:22px;width:22px;left:4px;bottom:4px;background-color:#fff;transition:.4s}input:checked+.slider{background-color:#9acd32}input:focus+.slider{box-shadow:0 0 1px #9acd32}input:checked+.slider:before{transform:translate(36px)}.slider.round{border-radius:34px}.slider.round:before{border-radius:50%}.slider:after{content:\"Off\";color:#fff;display:block;position:absolute;transform:translate(-14%,-50%);top:50%;left:50%;font-size:10px;font-family:Verdana,sans-serif}input:checked+.slider:after{content:\"On\";transform:translate(-91%,-50%)}\n", ".flex{display:flex;margin-right:10px;align-items:center}.flex .spacer{min-width:15px}.flex .container .with-validation{display:flex;flex-wrap:nowrap}.flex .container .toggle{width:66px;height:30px}.flex .container input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;padding:0 30px 0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300;min-width:150px;margin:0 3px}.flex .container input[type=number]{padding:0 2px 0 5px}.flex .container .invalid{border:1px solid #ff5252}.flex .container .error{color:#ff5252;margin-right:5px}.flex .variationId{margin:0 4px 0 5px;cursor:pointer;color:#888;display:flex;align-items:center}.flex .expand{position:relative;top:2px;height:24px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.flex .expand mat-icon{transform:rotate(45deg)}@media (max-width: 920px){.flex{margin-right:0!important}.flex .spacer{min-width:5px}}@media (max-width: 510px){.flex .container .error{display:none}}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
521
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: ValueComponent, decorators: [{
627
+ ValueComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ValueComponent, deps: [{ token: i1$1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
628
+ ValueComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: ValueComponent, selector: "configcat-value", inputs: { valueFormControl: "valueFormControl", setting: "setting" }, ngImport: i0, template: "<div class=\"flex\">\n <div class=\"container\" [ngSwitch]=\"setting.settingType\">\n <div *ngSwitchCase=\"SettingType.String\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"text\"\n [formControl]=\"valueFormControl\" placeholder=\"my value\" name=\"value\">\n <div class=\"expand\" (click)=\"popOut()\" matTooltip=\"Pop-out Editor\">\n <mat-icon>height</mat-icon>\n </div>\n </div>\n <div *ngSwitchCase=\"SettingType.Int\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"number\" [formControl]=\"valueFormControl\"\n placeholder=\"42\" name=\"value\" />\n </div>\n <div *ngSwitchCase=\"SettingType.Double\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"number\" [formControl]=\"valueFormControl\"\n placeholder=\"{{ formatDecimalNumber(3.14) }}\" name=\"value\" inputDisplayNormalizer>\n </div>\n <div *ngSwitchCase=\"SettingType.Boolean\" class=\"toggle\">\n <label class=\"switch\">\n <input type=\"checkbox\" [formControl]=\"valueFormControl\" name=\"value\" />\n <span class=\"slider round\"></span>\n </label>\n </div>\n </div>\n <div *ngIf=\"setting.settingType === SettingType.Boolean\" class=\"spacer\"></div>\n\n</div>\n", styles: [".switch{position:relative;width:66px;height:30px;margin-left:4px;margin-top:0;margin-bottom:0}.switch input{display:none}.slider{position:absolute;cursor:pointer;inset:0;background-color:#ff5252;transition:.4s;width:66px;height:30px}.slider:before{position:absolute;content:\"\";height:22px;width:22px;left:4px;bottom:4px;background-color:#fff;transition:.4s}input:checked+.slider{background-color:#9acd32}input:focus+.slider{box-shadow:0 0 1px #9acd32}input:checked+.slider:before{transform:translate(36px)}.slider.round{border-radius:34px}.slider.round:before{border-radius:50%}.slider:after{content:\"Off\";color:#fff;display:block;position:absolute;transform:translate(-14%,-50%);top:50%;left:50%;font-size:10px;font-family:Verdana,sans-serif}input:checked+.slider:after{content:\"On\";transform:translate(-91%,-50%)}\n", ".flex{display:flex;margin-right:10px;align-items:center}.flex .spacer{min-width:15px}.flex .container .with-validation{display:flex;flex-wrap:nowrap}.flex .container .toggle{width:66px;height:30px}.flex .container input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;padding:0 30px 0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300;min-width:150px;margin:0 3px}.flex .container input[type=number]{padding:0 2px 0 5px}.flex .container .invalid{border:1px solid #ff5252}.flex .container .error{color:#ff5252;margin-right:5px}.flex .variationId{margin:0 4px 0 5px;cursor:pointer;color:#888;display:flex;align-items:center}.flex .expand{position:relative;top:2px;height:24px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.flex .expand mat-icon{transform:rotate(45deg)}@media (max-width: 920px){.flex{margin-right:0!important}.flex .spacer{min-width:5px}}@media (max-width: 510px){.flex .container .error{display:none}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: InputDisplayNormalizerDirective, selector: "input[inputDisplayNormalizer]" }] });
629
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ValueComponent, decorators: [{
522
630
  type: Component,
523
- args: [{ selector: 'configcat-value', template: "<div class=\"flex\">\n <div class=\"container\" [ngSwitch]=\"setting.settingType\">\n <div *ngSwitchCase=\"SettingType.String\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"text\"\n [formControl]=\"valueFormControl\" placeholder=\"my value\" name=\"value\">\n <div class=\"expand\" (click)=\"popOut()\" matTooltip=\"Pop-out Editor\">\n <mat-icon>height</mat-icon>\n </div>\n </div>\n <div *ngSwitchCase=\"SettingType.Int\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"number\" [formControl]=\"valueFormControl\"\n placeholder=\"42\" name=\"value\" />\n </div>\n <div *ngSwitchCase=\"SettingType.Double\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"number\" [formControl]=\"valueFormControl\"\n placeholder=\"3.14\" name=\"value\">\n </div>\n <div *ngSwitchCase=\"SettingType.Boolean\" class=\"toggle\">\n <label class=\"switch\">\n <input type=\"checkbox\" [formControl]=\"valueFormControl\" name=\"value\" />\n <span class=\"slider round\"></span>\n </label>\n </div>\n </div>\n <div *ngIf=\"setting.settingType === SettingType.Boolean\" class=\"spacer\"></div>\n\n</div>\n", styles: [".switch{position:relative;width:66px;height:30px;margin-left:4px;margin-top:0;margin-bottom:0}.switch input{display:none}.slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ff5252;transition:.4s;width:66px;height:30px}.slider:before{position:absolute;content:\"\";height:22px;width:22px;left:4px;bottom:4px;background-color:#fff;transition:.4s}input:checked+.slider{background-color:#9acd32}input:focus+.slider{box-shadow:0 0 1px #9acd32}input:checked+.slider:before{transform:translate(36px)}.slider.round{border-radius:34px}.slider.round:before{border-radius:50%}.slider:after{content:\"Off\";color:#fff;display:block;position:absolute;transform:translate(-14%,-50%);top:50%;left:50%;font-size:10px;font-family:Verdana,sans-serif}input:checked+.slider:after{content:\"On\";transform:translate(-91%,-50%)}\n", ".flex{display:flex;margin-right:10px;align-items:center}.flex .spacer{min-width:15px}.flex .container .with-validation{display:flex;flex-wrap:nowrap}.flex .container .toggle{width:66px;height:30px}.flex .container input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;padding:0 30px 0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300;min-width:150px;margin:0 3px}.flex .container input[type=number]{padding:0 2px 0 5px}.flex .container .invalid{border:1px solid #ff5252}.flex .container .error{color:#ff5252;margin-right:5px}.flex .variationId{margin:0 4px 0 5px;cursor:pointer;color:#888;display:flex;align-items:center}.flex .expand{position:relative;top:2px;height:24px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.flex .expand mat-icon{transform:rotate(45deg)}@media (max-width: 920px){.flex{margin-right:0!important}.flex .spacer{min-width:5px}}@media (max-width: 510px){.flex .container .error{display:none}}\n"] }]
631
+ args: [{ selector: 'configcat-value', template: "<div class=\"flex\">\n <div class=\"container\" [ngSwitch]=\"setting.settingType\">\n <div *ngSwitchCase=\"SettingType.String\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"text\"\n [formControl]=\"valueFormControl\" placeholder=\"my value\" name=\"value\">\n <div class=\"expand\" (click)=\"popOut()\" matTooltip=\"Pop-out Editor\">\n <mat-icon>height</mat-icon>\n </div>\n </div>\n <div *ngSwitchCase=\"SettingType.Int\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"number\" [formControl]=\"valueFormControl\"\n placeholder=\"42\" name=\"value\" />\n </div>\n <div *ngSwitchCase=\"SettingType.Double\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"number\" [formControl]=\"valueFormControl\"\n placeholder=\"{{ formatDecimalNumber(3.14) }}\" name=\"value\" inputDisplayNormalizer>\n </div>\n <div *ngSwitchCase=\"SettingType.Boolean\" class=\"toggle\">\n <label class=\"switch\">\n <input type=\"checkbox\" [formControl]=\"valueFormControl\" name=\"value\" />\n <span class=\"slider round\"></span>\n </label>\n </div>\n </div>\n <div *ngIf=\"setting.settingType === SettingType.Boolean\" class=\"spacer\"></div>\n\n</div>\n", styles: [".switch{position:relative;width:66px;height:30px;margin-left:4px;margin-top:0;margin-bottom:0}.switch input{display:none}.slider{position:absolute;cursor:pointer;inset:0;background-color:#ff5252;transition:.4s;width:66px;height:30px}.slider:before{position:absolute;content:\"\";height:22px;width:22px;left:4px;bottom:4px;background-color:#fff;transition:.4s}input:checked+.slider{background-color:#9acd32}input:focus+.slider{box-shadow:0 0 1px #9acd32}input:checked+.slider:before{transform:translate(36px)}.slider.round{border-radius:34px}.slider.round:before{border-radius:50%}.slider:after{content:\"Off\";color:#fff;display:block;position:absolute;transform:translate(-14%,-50%);top:50%;left:50%;font-size:10px;font-family:Verdana,sans-serif}input:checked+.slider:after{content:\"On\";transform:translate(-91%,-50%)}\n", ".flex{display:flex;margin-right:10px;align-items:center}.flex .spacer{min-width:15px}.flex .container .with-validation{display:flex;flex-wrap:nowrap}.flex .container .toggle{width:66px;height:30px}.flex .container input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;padding:0 30px 0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300;min-width:150px;margin:0 3px}.flex .container input[type=number]{padding:0 2px 0 5px}.flex .container .invalid{border:1px solid #ff5252}.flex .container .error{color:#ff5252;margin-right:5px}.flex .variationId{margin:0 4px 0 5px;cursor:pointer;color:#888;display:flex;align-items:center}.flex .expand{position:relative;top:2px;height:24px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.flex .expand mat-icon{transform:rotate(45deg)}@media (max-width: 920px){.flex{margin-right:0!important}.flex .spacer{min-width:5px}}@media (max-width: 510px){.flex .container .error{display:none}}\n"] }]
524
632
  }], ctorParameters: function () { return [{ type: i1$1.MatDialog }]; }, propDecorators: { valueFormControl: [{
525
633
  type: Input
526
634
  }], setting: [{
@@ -590,9 +698,9 @@ class RolloutPercentageItemsComponent {
590
698
  return rolloutPercentageItem.controls.percentage;
591
699
  }
592
700
  }
593
- RolloutPercentageItemsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: RolloutPercentageItemsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
594
- RolloutPercentageItemsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: RolloutPercentageItemsComponent, selector: "configcat-rollout-percentage-items", inputs: { formGroup: "formGroup", readOnly: "readOnly" }, ngImport: i0, template: "<div class=\"percentage-wrapper\" [formGroup]=\"formGroup\">\n\n <div class=\"if\" *ngIf=\"rolloutRules().controls.length > 0\">\n <mat-chip-list>\n <mat-chip class=\"chip\">ELSE IF</mat-chip>\n </mat-chip-list>\n </div>\n <div class=\"grow\">\n <div class=\"percentage-row flex\"\n *ngFor=\"let rolloutPercentageItem of getRolloutPercentageItemFormGroups(); let i = index\">\n <div class=\"flex\">\n <input type=\"number\" [formControl]=\"getPercentageFormControl(rolloutPercentageItem)\"\n (input)=\"percentageChanged(i)\">%\n <span class=\"users\">of <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">users</a>\n </span>\n </div>\n\n <div class=\"delete-option\" matTooltip=\"Remove this % option\"\n *ngIf=\"!readOnly && rolloutPercentageItems().controls.length > 2\"\n (click)=\"removeRolloutPercentageItem(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n\n <span matTooltip=\"The sum of percentages must be equal to 100.\" matTooltipPosition=\"above\"\n *ngIf=\"(i === rolloutPercentageItems().controls.length -1) && (rolloutPercentageItemsSum().invalid)\">\n <mat-icon color=\"warn\">\n error_outline\n </mat-icon>\n </span>\n\n <div class=\"value flex\">\n <span class=\"value-name\" *ngIf=\"setting().settingType !== SettingType.Boolean\">Served value:</span>\n <configcat-value class=\"served-value\" [valueFormControl]=\"value(rolloutPercentageItem)\"\n [setting]=\"setting()\">\n </configcat-value>\n </div>\n <div class=\"delete\" matTooltip=\"Remove % options\" (click)=\"removeAll()\" *ngIf=\"!readOnly\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n </div>\n</div>", styles: [".percentage-wrapper{border:1px solid #d5d5d5;background-color:#fff;margin:.5em 1em;position:relative;padding:.5em 0;display:flex;flex-wrap:wrap}.percentage-wrapper .delete{position:absolute;cursor:pointer;top:-9px;right:-10px;z-index:999;border-radius:50%;background-color:#fff;height:20px;width:20px;color:#ed5251}.percentage-wrapper .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.percentage-wrapper .delete:hover mat-icon{opacity:1}.percentage-wrapper .delete-option{color:#ed5251;cursor:pointer;margin-left:1rem;margin-top:4px}.percentage-wrapper .delete-option:hover mat-icon{opacity:1}.percentage-wrapper .delete-option mat-icon{opacity:.5;font-size:20px}.if{display:flex;align-items:center}.if>*{margin:0 .5em}.if .spacing{margin-right:44px}.if .chip{background-color:#67b1fc3d}.grow{flex-grow:1}.percentage-row{min-height:40px;margin-left:.5em}.flex{display:flex;flex-wrap:wrap;align-items:center}.value{margin-left:auto}.value .value-name{display:none}input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;width:40px;margin-top:3px;margin-right:5px;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.users{margin-left:20px}.mat-chip{font-size:12px}@media (max-width: 920px){.value{min-width:0!important}.value .served-value{margin:3px 7px 3px 0}}@media (max-width: 650px){.users{margin-left:5px}}@media (max-width: 540px){.users{font-size:12px}}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i5$2.MatChipList, selector: "mat-chip-list", inputs: ["role", "aria-describedby", "errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { kind: "directive", type: i5$2.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "role", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { kind: "component", type: ValueComponent, selector: "configcat-value", inputs: ["valueFormControl", "setting"] }] });
595
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: RolloutPercentageItemsComponent, decorators: [{
701
+ RolloutPercentageItemsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: RolloutPercentageItemsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
702
+ RolloutPercentageItemsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: RolloutPercentageItemsComponent, selector: "configcat-rollout-percentage-items", inputs: { formGroup: "formGroup", readOnly: "readOnly" }, ngImport: i0, template: "<div class=\"percentage-wrapper\" [formGroup]=\"formGroup\">\n\n <div class=\"if\" *ngIf=\"rolloutRules().controls.length > 0\">\n <mat-chip-list>\n <mat-chip class=\"chip\">ELSE IF</mat-chip>\n </mat-chip-list>\n </div>\n <div class=\"grow\">\n <div class=\"percentage-row flex\"\n *ngFor=\"let rolloutPercentageItem of getRolloutPercentageItemFormGroups(); let i = index\">\n <div class=\"flex\">\n <input type=\"number\" [formControl]=\"getPercentageFormControl(rolloutPercentageItem)\"\n (input)=\"percentageChanged(i)\">%\n <span class=\"users\">of <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">users</a>\n </span>\n </div>\n\n <div class=\"delete-option\" matTooltip=\"Remove this % option\"\n *ngIf=\"!readOnly && rolloutPercentageItems().controls.length > 2\"\n (click)=\"removeRolloutPercentageItem(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n\n <span matTooltip=\"The sum of percentages must be equal to 100.\" matTooltipPosition=\"above\"\n *ngIf=\"(i === rolloutPercentageItems().controls.length -1) && (rolloutPercentageItemsSum().invalid)\">\n <mat-icon color=\"warn\">\n error_outline\n </mat-icon>\n </span>\n\n <div class=\"value flex\">\n <span class=\"value-name\" *ngIf=\"setting().settingType !== SettingType.Boolean\">Served value:</span>\n <configcat-value class=\"served-value\" [valueFormControl]=\"value(rolloutPercentageItem)\"\n [setting]=\"setting()\">\n </configcat-value>\n </div>\n <div class=\"delete\" matTooltip=\"Remove % options\" (click)=\"removeAll()\" *ngIf=\"!readOnly\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n </div>\n</div>", styles: [".percentage-wrapper{border:1px solid #d5d5d5;background-color:#fff;margin:.5em 1em;position:relative;padding:.5em 0;display:flex;flex-wrap:wrap}.percentage-wrapper .delete{position:absolute;cursor:pointer;top:-9px;right:-10px;z-index:999;border-radius:50%;background-color:#fff;height:20px;width:20px;color:#ed5251}.percentage-wrapper .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.percentage-wrapper .delete:hover mat-icon{opacity:1}.percentage-wrapper .delete-option{color:#ed5251;cursor:pointer;margin-left:1rem;margin-top:4px}.percentage-wrapper .delete-option:hover mat-icon{opacity:1}.percentage-wrapper .delete-option mat-icon{opacity:.5;font-size:20px}.if{display:flex;align-items:center}.if>*{margin:0 .5em}.if .spacing{margin-right:44px}.if .chip{background-color:#67b1fc3d}.grow{flex-grow:1}.percentage-row{min-height:40px;margin-left:.5em}.flex{display:flex;flex-wrap:wrap;align-items:center}.value{margin-left:auto}.value .value-name{display:none}input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;width:40px;margin-top:3px;margin-right:5px;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.users{margin-left:20px}.mat-chip{font-size:12px}@media (max-width: 920px){.value{min-width:0!important}.value .served-value{margin:3px 7px 3px 0}}@media (max-width: 650px){.users{margin-left:5px}}@media (max-width: 540px){.users{font-size:12px}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i5$2.MatChipList, selector: "mat-chip-list", inputs: ["role", "aria-describedby", "errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { kind: "directive", type: i5$2.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "role", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { kind: "component", type: ValueComponent, selector: "configcat-value", inputs: ["valueFormControl", "setting"] }] });
703
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: RolloutPercentageItemsComponent, decorators: [{
596
704
  type: Component,
597
705
  args: [{ selector: 'configcat-rollout-percentage-items', template: "<div class=\"percentage-wrapper\" [formGroup]=\"formGroup\">\n\n <div class=\"if\" *ngIf=\"rolloutRules().controls.length > 0\">\n <mat-chip-list>\n <mat-chip class=\"chip\">ELSE IF</mat-chip>\n </mat-chip-list>\n </div>\n <div class=\"grow\">\n <div class=\"percentage-row flex\"\n *ngFor=\"let rolloutPercentageItem of getRolloutPercentageItemFormGroups(); let i = index\">\n <div class=\"flex\">\n <input type=\"number\" [formControl]=\"getPercentageFormControl(rolloutPercentageItem)\"\n (input)=\"percentageChanged(i)\">%\n <span class=\"users\">of <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">users</a>\n </span>\n </div>\n\n <div class=\"delete-option\" matTooltip=\"Remove this % option\"\n *ngIf=\"!readOnly && rolloutPercentageItems().controls.length > 2\"\n (click)=\"removeRolloutPercentageItem(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n\n <span matTooltip=\"The sum of percentages must be equal to 100.\" matTooltipPosition=\"above\"\n *ngIf=\"(i === rolloutPercentageItems().controls.length -1) && (rolloutPercentageItemsSum().invalid)\">\n <mat-icon color=\"warn\">\n error_outline\n </mat-icon>\n </span>\n\n <div class=\"value flex\">\n <span class=\"value-name\" *ngIf=\"setting().settingType !== SettingType.Boolean\">Served value:</span>\n <configcat-value class=\"served-value\" [valueFormControl]=\"value(rolloutPercentageItem)\"\n [setting]=\"setting()\">\n </configcat-value>\n </div>\n <div class=\"delete\" matTooltip=\"Remove % options\" (click)=\"removeAll()\" *ngIf=\"!readOnly\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n </div>\n</div>", styles: [".percentage-wrapper{border:1px solid #d5d5d5;background-color:#fff;margin:.5em 1em;position:relative;padding:.5em 0;display:flex;flex-wrap:wrap}.percentage-wrapper .delete{position:absolute;cursor:pointer;top:-9px;right:-10px;z-index:999;border-radius:50%;background-color:#fff;height:20px;width:20px;color:#ed5251}.percentage-wrapper .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.percentage-wrapper .delete:hover mat-icon{opacity:1}.percentage-wrapper .delete-option{color:#ed5251;cursor:pointer;margin-left:1rem;margin-top:4px}.percentage-wrapper .delete-option:hover mat-icon{opacity:1}.percentage-wrapper .delete-option mat-icon{opacity:.5;font-size:20px}.if{display:flex;align-items:center}.if>*{margin:0 .5em}.if .spacing{margin-right:44px}.if .chip{background-color:#67b1fc3d}.grow{flex-grow:1}.percentage-row{min-height:40px;margin-left:.5em}.flex{display:flex;flex-wrap:wrap;align-items:center}.value{margin-left:auto}.value .value-name{display:none}input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;width:40px;margin-top:3px;margin-right:5px;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.users{margin-left:20px}.mat-chip{font-size:12px}@media (max-width: 920px){.value{min-width:0!important}.value .served-value{margin:3px 7px 3px 0}}@media (max-width: 650px){.users{margin-left:5px}}@media (max-width: 540px){.users{font-size:12px}}\n"] }]
598
706
  }], ctorParameters: function () { return []; }, propDecorators: { formGroup: [{
@@ -602,8 +710,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
602
710
  }] } });
603
711
 
604
712
  class RolloutRulesComponent {
605
- constructor(dialog) {
713
+ constructor(dialog, settingListFormHelper) {
606
714
  this.dialog = dialog;
715
+ this.settingListFormHelper = settingListFormHelper;
607
716
  this.readOnly = false;
608
717
  this.SettingType = SettingType;
609
718
  this.defaultComparisonAttributes = ['Identifier', 'Email', 'Country'];
@@ -716,17 +825,7 @@ class RolloutRulesComponent {
716
825
  return '';
717
826
  }
718
827
  getComparisonValueType(rolloutRule) {
719
- switch (rolloutRule.controls.comparator.value) {
720
- case RolloutRuleComparator.NumberEquals:
721
- case RolloutRuleComparator.NumberDoesNotEqual:
722
- case RolloutRuleComparator.NumberLess:
723
- case RolloutRuleComparator.NumberLessOrEquals:
724
- case RolloutRuleComparator.NumberGreater:
725
- case RolloutRuleComparator.NumberGreaterOrEquals:
726
- return 'number';
727
- default:
728
- return 'text';
729
- }
828
+ return this.settingListFormHelper.getComparisonValueType(rolloutRule.controls.comparator.value);
730
829
  }
731
830
  getInfoClass(rolloutRule) {
732
831
  if (!rolloutRule.controls.comparisonAttribute.value) {
@@ -787,6 +886,13 @@ class RolloutRulesComponent {
787
886
  break;
788
887
  }
789
888
  rolloutRule.controls.comparisonValue.setValidators(validators);
889
+ if (this.getComparisonValueType(rolloutRule) === "number") {
890
+ const oldValue = rolloutRule.controls.comparisonValue.value;
891
+ rolloutRule.controls.comparisonValue.setValue(FormHelper.normalizeNumberStoredAsString(rolloutRule.controls.comparisonValue.value));
892
+ if (oldValue !== rolloutRule.controls.comparisonValue.value) {
893
+ rolloutRule.controls.comparisonValue.markAsTouched();
894
+ }
895
+ }
790
896
  rolloutRule.controls.comparisonValue.updateValueAndValidity();
791
897
  }
792
898
  isListType(rolloutRule) {
@@ -864,12 +970,12 @@ class RolloutRulesComponent {
864
970
  return rolloutRule.controls.segmentId;
865
971
  }
866
972
  }
867
- RolloutRulesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: RolloutRulesComponent, deps: [{ token: i1$1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
868
- RolloutRulesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: RolloutRulesComponent, selector: "configcat-rollout-rules", inputs: { formGroup: "formGroup", readOnly: "readOnly", segments: "segments" }, ngImport: i0, template: "<div [formGroup]=\"formGroup\">\n <div cdkDropList (cdkDropListDropped)=\"onDrop($event)\" [cdkDropListDisabled]=\"readOnly\"\n [cdkDropListData]=\"rolloutRules().controls\">\n <div *ngFor=\"let rolloutRule of rolloutRules().controls; trackBy: trackByIndex; let i = index\" cdkDrag>\n <div class=\"targeting-row\">\n <div class=\"fields flex\" *ngIf=\"getRolloutRuleTypeFormControl(rolloutRule).value === 0\">\n <div class=\"drag-handle\" cdkDragHandle matTooltip=\"Drag here to reorder\" matTooltipPosition=\"above\"\n *ngIf=\"!readOnly\">\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"if\">\n <mat-chip-list [class.spacing]=\"i === 0\">\n <mat-chip class=\"chip\">{{ i === 0 ? 'IF' : 'ELSE IF' }}</mat-chip>\n </mat-chip-list>\n <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">user's</a>\n </div>\n\n <select class=\"custom-select attribute-select\" matTooltip=\"Comparison attribute\"\n matTooltipPosition=\"above\"\n (change)=\"attributeChanged($event.target, getRolloutRuleComparisonAttributeFormControl(rolloutRule))\">\n <option *ngFor=\"let comparisonAttribute of defaultComparisonAttributes\"\n [selected]=\"comparisonAttribute === getRolloutRuleComparisonAttributeFormControl(rolloutRule).value\">\n {{comparisonAttribute}}</option>\n <option\n [selected]=\"defaultComparisonAttributes.indexOf(getRolloutRuleComparisonAttributeFormControl(rolloutRule).value) === -1\">\n Custom\n </option>\n </select>\n\n\n <span class=\"attribute-span\" matTooltip=\"Custom user attribute\" matTooltipPosition=\"above\"\n [hidden]=\"defaultComparisonAttributes.indexOf(getRolloutRuleComparisonAttributeFormControl(rolloutRule).value) !== -1\">\n <span class=\"attribute-error\"\n *ngIf=\"getRolloutRuleComparisonAttributeFormControl(rolloutRule).invalid\">*</span>\n <input\n [ngClass]=\"{'invalid': getRolloutRuleComparisonAttributeFormControl(rolloutRule).invalid}\"\n type=\"text\" matInput [matAutocomplete]=\"auto\"\n [formControl]=\"getRolloutRuleComparisonAttributeFormControl(rolloutRule)\" class=\"attribute\"\n placeholder=\"e.g. Eye color\">\n </span>\n\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let option of comparisonAttributes()\" [value]=\"option\">\n {{option}}\n </mat-option>\n </mat-autocomplete>\n\n <div class=\"select-wrapper\">\n <select class=\"custom-select\" [formControl]=\"getRolloutRuleComparatorFormControl(rolloutRule)\"\n matTooltip=\"Comparator\" matTooltipPosition=\"above\"\n (change)=\"comparatorChanged(rolloutRule)\">\n <optgroup label=\"CONFIDENTIAL TEXT\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(16, 18)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"TEXT\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(0, 4)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"SEMANTIC VERSION\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(4, 10)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"NUMBER\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(10, 16)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n </select>\n <div [class]=\"getInfoClass(rolloutRule)\" [matTooltip]=\"getInfoTooltip(rolloutRule)\">\n <a href=\"https://configcat.com/docs/advanced/targeting/#comparator\" target=\"_blank\"\n rel=\"noopener noreferrer\">\n <mat-icon>info</mat-icon>\n </a>\n </div>\n </div>\n\n <div class=\"comparison-value\" matTooltip=\"Comparison value\" matTooltipPosition=\"above\">\n <span class=\"error\"\n *ngIf=\"getRolloutRuleComparisonValueFormControl(rolloutRule).invalid\">*</span>\n\n <input [ngClass]=\"{'invalid': getRolloutRuleComparisonValueFormControl(rolloutRule).invalid}\"\n [formControl]=\"getRolloutRuleComparisonValueFormControl(rolloutRule)\"\n [type]=\"getComparisonValueType(rolloutRule)\" [placeholder]=\"getPlaceHolder(rolloutRule)\">\n <div class=\"expand\" matTooltip=\"Pop-out Editor\" (click)=\"popOut(rolloutRule)\"\n *ngIf=\"getComparisonValueType(rolloutRule)==='text'\">\n <mat-icon>height</mat-icon>\n </div>\n </div>\n\n <div class=\"delete\" matTooltip=\"Remove targeting rule\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n\n <div class=\"fields flex\" *ngIf=\"getRolloutRuleTypeFormControl(rolloutRule).value === 1\">\n <div class=\"drag-handle\" cdkDragHandle matTooltip=\"Drag here to reorder\" matTooltipPosition=\"above\"\n *ngIf=\"!readOnly\">\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"if\">\n <mat-chip-list [class.spacing]=\"i === 0\">\n <mat-chip class=\"chip\">{{ i === 0 ? 'IF' : 'ELSE IF' }}</mat-chip>\n </mat-chip-list>\n <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">user</a>\n </div>\n\n\n <div class=\"select-wrapper\">\n <select class=\"custom-select segment-comparator\"\n [formControl]=\"getRolloutRuleSegmentComparatorFormControl(rolloutRule)\"\n matTooltip=\"Segment comparator\" matTooltipPosition=\"above\">\n <option *ngFor=\"let comparator of segmentComparators\" [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </select>\n </div>\n\n <div class=\"select-wrapper\">\n <span class=\"attribute-error\"\n *ngIf=\"getRolloutRuleSegmentIdFormControl(rolloutRule).invalid\">*</span>\n <select class=\"custom-select segment-select\"\n [formControl]=\"getRolloutRuleSegmentIdFormControl(rolloutRule)\" matTooltip=\"Segment\"\n matTooltipPosition=\"above\"\n [ngClass]=\"{'invalid': getRolloutRuleSegmentIdFormControl(rolloutRule).invalid}\">\n <option *ngFor=\"let segment of segments\" [ngValue]=\"segment.segmentId\">\n {{segment.name}}\n </option>\n </select>\n </div>\n\n\n <div class=\"delete\" matTooltip=\"Remove targeting rule\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n\n\n <div class=\"value flex\">\n <div class=\"serve\" *ngIf=\"setting().settingType !== SettingType.Boolean\">\n <mat-chip-list>\n <mat-chip class=\"chip\">Serve:</mat-chip>\n </mat-chip-list>\n </div>\n\n <configcat-value class=\"served-value\"\n [valueFormControl]=\"getRolloutRuleValueFormControl(rolloutRule)\" [setting]=\"setting()\">\n </configcat-value>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [".cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-animating{transition:transform .3s cubic-bezier(0,0,.2,1)}.targeting-row{border:1px solid #d5d5d5;background-color:#fff;margin:1em;display:flex;position:relative;padding:.5em 0}.targeting-row:hover{background-color:#dbedff}.targeting-row .select-wrapper{position:relative}.targeting-row .info{position:absolute;cursor:pointer;top:-8px;left:166px;border-radius:50%;background-color:#fff;height:18px;width:18px}.targeting-row .info a{color:#0068f0;opacity:.5}.targeting-row .info a:hover{opacity:1}.targeting-row .info mat-icon{font-size:18px;height:18px;width:18px}.targeting-row .warn{position:absolute;cursor:pointer;top:-8px;left:166px;height:18px;width:18px;border-radius:50%;background-color:#fff}.targeting-row .warn a{color:#fdc67f}.targeting-row .warn a:hover{color:#ff9200}.targeting-row .warn mat-icon{font-size:18px;height:18px;width:18px}.chip{background-color:#67b1fc3d}.custom-select{margin-left:.5em;width:170px;background-color:#fff;border:1px solid #e5e5e5;height:30px;min-height:30px;line-height:30px;min-width:170px;font-size:.8em;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.fields{justify-content:left;max-width:1060px;flex-grow:100}.fields .if{display:flex;align-items:center}.fields .if>*{margin:0 .5em}.fields .if .spacing{margin-right:41px}.fields .if .user-link{width:40px}.fields .attribute-span{margin-left:.5em;display:flex;align-items:center}.fields .attribute{width:170px;background-color:#fff;border:1px solid #e5e5e5;margin:3px 0;min-height:28px;flex-grow:100;min-width:170px;padding:0 30px 0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300;font-size:13.3px}.fields .invalid{border:1px solid #ff5252}.fields .attribute-error{color:#ff5252;margin:0 5px}.fields .delete{position:absolute;cursor:pointer;top:-9px;right:-10px;z-index:999;border-radius:50%;background-color:#fff;height:20px;width:20px;color:#ed5251}.fields .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.fields .delete:hover mat-icon{opacity:1}.fields .drag-handle{position:absolute;cursor:-moz-grab;left:-20px;top:14px}.fields .drag-handle mat-icon{font-size:20px}.fields .attribute-select{min-width:100px;width:100px;margin-left:0}.fields .segment-comparator,.fields .segment-select{margin-left:0;margin-right:.5em}.fields .segment-more mat-icon{position:relative;top:3px;cursor:pointer;font-size:16px;height:16px;width:16px;color:#797979;margin-top:3px}.fields .comparison-value{flex-grow:100;min-width:150px;display:flex;align-items:center;margin-left:.5em;margin-right:.5em}.fields .comparison-value .error{color:#ff5252;margin:0 5px}.fields .comparison-value input{background-color:#fff;border:1px solid #e5e5e5;margin:3px 0;min-height:28px;min-width:150px;flex-grow:100;padding:0 30px 0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.fields .comparison-value .invalid{border:1px solid #ff5252}.fields .comparison-value .expand{position:relative;height:24px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.fields .comparison-value .expand mat-icon{transform:rotate(45deg)}.value{margin-left:auto;flex-wrap:nowrap}.value .serve{margin:0 2px 0 5px}.value .served-value{margin:3px 0}.flex{display:flex;flex-wrap:wrap;align-items:center}.mat-chip{font-size:12px}@media (max-width: 1200px){.targeting-row{flex-wrap:wrap}.targeting-row .fields{max-width:500px}}@media (max-width: 920px){.value .served-value{margin:3px 7px 3px 0}.targeting-row .fields .drag-handle{left:-18px}}@media (max-width: 410px){.value .served-value{margin:7px 7px 3px 4px}}@media (max-width: 510px){.fields .comparison-value .error{display:none}}@media (max-width: 650px){.targeting-row{flex-direction:column}.targeting-row .help{left:161px}.targeting-row .fields{flex-direction:column;align-items:stretch}.targeting-row .fields .custom-select{margin:7px 7px 0}.targeting-row .fields .comparison-value{margin:7px}.targeting-row .fields .comparison-value input{margin:0 4px 0 0}.targeting-row .fields .attribute-span{margin:7px 7px 0}.targeting-row .fields .if{font-size:12px}.targeting-row .fields .if .spacing{margin-right:3px}}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i5$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i5$2.MatChipList, selector: "mat-chip-list", inputs: ["role", "aria-describedby", "errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { kind: "directive", type: i5$2.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "role", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { kind: "component", type: i9.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i9.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "directive", type: i10.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i10.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i10.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: ValueComponent, selector: "configcat-value", inputs: ["valueFormControl", "setting"] }] });
869
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: RolloutRulesComponent, decorators: [{
973
+ RolloutRulesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: RolloutRulesComponent, deps: [{ token: i1$1.MatDialog }, { token: SettingListFormHelper }], target: i0.ɵɵFactoryTarget.Component });
974
+ RolloutRulesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: RolloutRulesComponent, selector: "configcat-rollout-rules", inputs: { formGroup: "formGroup", readOnly: "readOnly", segments: "segments" }, ngImport: i0, template: "<div [formGroup]=\"formGroup\">\n <div cdkDropList (cdkDropListDropped)=\"onDrop($event)\" [cdkDropListDisabled]=\"readOnly\"\n [cdkDropListData]=\"rolloutRules().controls\">\n <div *ngFor=\"let rolloutRule of rolloutRules().controls; trackBy: trackByIndex; let i = index\" cdkDrag>\n <div class=\"targeting-row\">\n <div class=\"fields flex\" *ngIf=\"getRolloutRuleTypeFormControl(rolloutRule).value === 0\">\n <div class=\"drag-handle\" cdkDragHandle matTooltip=\"Drag here to reorder\" matTooltipPosition=\"above\"\n *ngIf=\"!readOnly\">\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"if\">\n <mat-chip-list [class.spacing]=\"i === 0\">\n <mat-chip class=\"chip\">{{ i === 0 ? 'IF' : 'ELSE IF' }}</mat-chip>\n </mat-chip-list>\n <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">user's</a>\n </div>\n\n <select class=\"custom-select attribute-select\" matTooltip=\"Comparison attribute\"\n matTooltipPosition=\"above\"\n (change)=\"attributeChanged($event.target, getRolloutRuleComparisonAttributeFormControl(rolloutRule))\">\n <option *ngFor=\"let comparisonAttribute of defaultComparisonAttributes\"\n [selected]=\"comparisonAttribute === getRolloutRuleComparisonAttributeFormControl(rolloutRule).value\">\n {{comparisonAttribute}}</option>\n <option\n [selected]=\"defaultComparisonAttributes.indexOf(getRolloutRuleComparisonAttributeFormControl(rolloutRule).value) === -1\">\n Custom\n </option>\n </select>\n\n\n <span class=\"attribute-span\" matTooltip=\"Custom user attribute\" matTooltipPosition=\"above\"\n [hidden]=\"defaultComparisonAttributes.indexOf(getRolloutRuleComparisonAttributeFormControl(rolloutRule).value) !== -1\">\n <span class=\"attribute-error\"\n *ngIf=\"getRolloutRuleComparisonAttributeFormControl(rolloutRule).invalid\">*</span>\n <input\n [ngClass]=\"{'invalid': getRolloutRuleComparisonAttributeFormControl(rolloutRule).invalid}\"\n type=\"text\" matInput [matAutocomplete]=\"auto\"\n [formControl]=\"getRolloutRuleComparisonAttributeFormControl(rolloutRule)\" class=\"attribute\"\n placeholder=\"e.g. Eye color\">\n </span>\n\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let option of comparisonAttributes()\" [value]=\"option\">\n {{option}}\n </mat-option>\n </mat-autocomplete>\n\n <div class=\"select-wrapper\">\n <select class=\"custom-select\" [formControl]=\"getRolloutRuleComparatorFormControl(rolloutRule)\"\n matTooltip=\"Comparator\" matTooltipPosition=\"above\"\n (change)=\"comparatorChanged(rolloutRule)\">\n <optgroup label=\"CONFIDENTIAL TEXT\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(16, 18)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"TEXT\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(0, 4)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"SEMANTIC VERSION\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(4, 10)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"NUMBER\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(10, 16)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n </select>\n <div [class]=\"getInfoClass(rolloutRule)\" [matTooltip]=\"getInfoTooltip(rolloutRule)\">\n <a href=\"https://configcat.com/docs/advanced/targeting/#comparator\" target=\"_blank\"\n rel=\"noopener noreferrer\">\n <mat-icon>info</mat-icon>\n </a>\n </div>\n </div>\n\n <div class=\"comparison-value\" matTooltip=\"Comparison value\" matTooltipPosition=\"above\">\n <span class=\"error\"\n *ngIf=\"getRolloutRuleComparisonValueFormControl(rolloutRule).invalid\">*</span>\n\n <input [ngClass]=\"{'invalid': getRolloutRuleComparisonValueFormControl(rolloutRule).invalid}\"\n [formControl]=\"getRolloutRuleComparisonValueFormControl(rolloutRule)\"\n [type]=\"getComparisonValueType(rolloutRule)\" [placeholder]=\"getPlaceHolder(rolloutRule)\"\n inputDisplayNormalizer>\n <div class=\"expand\" matTooltip=\"Pop-out Editor\" (click)=\"popOut(rolloutRule)\"\n *ngIf=\"getComparisonValueType(rolloutRule)==='text'\">\n <mat-icon>height</mat-icon>\n </div>\n </div>\n\n <div class=\"delete\" matTooltip=\"Remove targeting rule\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n\n <div class=\"fields flex\" *ngIf=\"getRolloutRuleTypeFormControl(rolloutRule).value === 1\">\n <div class=\"drag-handle\" cdkDragHandle matTooltip=\"Drag here to reorder\" matTooltipPosition=\"above\"\n *ngIf=\"!readOnly\">\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"if\">\n <mat-chip-list [class.spacing]=\"i === 0\">\n <mat-chip class=\"chip\">{{ i === 0 ? 'IF' : 'ELSE IF' }}</mat-chip>\n </mat-chip-list>\n <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">user</a>\n </div>\n\n\n <div class=\"select-wrapper\">\n <select class=\"custom-select segment-comparator\"\n [formControl]=\"getRolloutRuleSegmentComparatorFormControl(rolloutRule)\"\n matTooltip=\"Segment comparator\" matTooltipPosition=\"above\">\n <option *ngFor=\"let comparator of segmentComparators\" [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </select>\n </div>\n\n <div class=\"select-wrapper\">\n <span class=\"attribute-error\"\n *ngIf=\"getRolloutRuleSegmentIdFormControl(rolloutRule).invalid\">*</span>\n <select class=\"custom-select segment-select\"\n [formControl]=\"getRolloutRuleSegmentIdFormControl(rolloutRule)\" matTooltip=\"Segment\"\n matTooltipPosition=\"above\"\n [ngClass]=\"{'invalid': getRolloutRuleSegmentIdFormControl(rolloutRule).invalid}\">\n <option *ngFor=\"let segment of segments\" [ngValue]=\"segment.segmentId\">\n {{segment.name}}\n </option>\n </select>\n </div>\n\n\n <div class=\"delete\" matTooltip=\"Remove targeting rule\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n\n\n <div class=\"value flex\">\n <div class=\"serve\" *ngIf=\"setting().settingType !== SettingType.Boolean\">\n <mat-chip-list>\n <mat-chip class=\"chip\">Serve:</mat-chip>\n </mat-chip-list>\n </div>\n\n <configcat-value class=\"served-value\"\n [valueFormControl]=\"getRolloutRuleValueFormControl(rolloutRule)\" [setting]=\"setting()\">\n </configcat-value>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [".cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-animating{transition:transform .3s cubic-bezier(0,0,.2,1)}.targeting-row{border:1px solid #d5d5d5;background-color:#fff;margin:1em;display:flex;position:relative;padding:.5em 0}.targeting-row:hover{background-color:#dbedff}.targeting-row .select-wrapper{position:relative}.targeting-row .info{position:absolute;cursor:pointer;top:-8px;left:166px;border-radius:50%;background-color:#fff;height:18px;width:18px}.targeting-row .info a{color:#0068f0;opacity:.5}.targeting-row .info a:hover{opacity:1}.targeting-row .info mat-icon{font-size:18px;height:18px;width:18px}.targeting-row .warn{position:absolute;cursor:pointer;top:-8px;left:166px;height:18px;width:18px;border-radius:50%;background-color:#fff}.targeting-row .warn a{color:#fdc67f}.targeting-row .warn a:hover{color:#ff9200}.targeting-row .warn mat-icon{font-size:18px;height:18px;width:18px}.chip{background-color:#67b1fc3d}.custom-select{margin-left:.5em;width:170px;background-color:#fff;border:1px solid #e5e5e5;height:30px;min-height:30px;line-height:30px;min-width:170px;font-size:.8em;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.fields{justify-content:left;max-width:1060px;flex-grow:100}.fields .if{display:flex;align-items:center}.fields .if>*{margin:0 .5em}.fields .if .spacing{margin-right:41px}.fields .if .user-link{width:40px}.fields .attribute-span{margin-left:.5em;display:flex;align-items:center}.fields .attribute-span[hidden]{display:none}.fields .attribute{width:170px;background-color:#fff;border:1px solid #e5e5e5;margin:3px 0;min-height:28px;flex-grow:100;min-width:170px;padding:0 30px 0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300;font-size:13.3px}.fields .invalid{border:1px solid #ff5252}.fields .attribute-error{color:#ff5252;margin:0 5px}.fields .delete{position:absolute;cursor:pointer;top:-9px;right:-10px;z-index:999;border-radius:50%;background-color:#fff;height:20px;width:20px;color:#ed5251}.fields .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.fields .delete:hover mat-icon{opacity:1}.fields .drag-handle{position:absolute;cursor:-moz-grab;left:-20px;top:14px}.fields .drag-handle mat-icon{font-size:20px}.fields .attribute-select{min-width:100px;width:100px;margin-left:0}.fields .segment-comparator,.fields .segment-select{margin-left:0;margin-right:.5em}.fields .segment-more mat-icon{position:relative;top:3px;cursor:pointer;font-size:16px;height:16px;width:16px;color:#797979;margin-top:3px}.fields .comparison-value{flex-grow:100;min-width:150px;display:flex;align-items:center;margin-left:.5em;margin-right:.5em}.fields .comparison-value .error{color:#ff5252;margin:0 5px}.fields .comparison-value input{background-color:#fff;border:1px solid #e5e5e5;margin:3px 0;min-height:28px;min-width:150px;flex-grow:100;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.fields .comparison-value input[type=text]{padding-right:30px}.fields .comparison-value .invalid{border:1px solid #ff5252}.fields .comparison-value .expand{position:relative;height:24px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.fields .comparison-value .expand mat-icon{transform:rotate(45deg)}.value{margin-left:auto;flex-wrap:nowrap}.value .serve{margin:0 2px 0 5px}.value .served-value{margin:3px 0}.flex{display:flex;flex-wrap:wrap;align-items:center}.mat-chip{font-size:12px}@media (max-width: 1200px){.targeting-row{flex-wrap:wrap}.targeting-row .fields{max-width:500px}}@media (max-width: 920px){.value .served-value{margin:3px 7px 3px 0}.targeting-row .fields .drag-handle{left:-18px}}@media (max-width: 410px){.value .served-value{margin:7px 7px 3px 4px}}@media (max-width: 510px){.fields .comparison-value .error{display:none}}@media (max-width: 650px){.targeting-row{flex-direction:column}.targeting-row .help{left:161px}.targeting-row .fields{flex-direction:column;align-items:stretch}.targeting-row .fields .custom-select{margin:7px 7px 0}.targeting-row .fields .comparison-value{margin:7px}.targeting-row .fields .comparison-value input{margin:0 4px 0 0}.targeting-row .fields .attribute-span{margin:7px 7px 0}.targeting-row .fields .if{font-size:12px}.targeting-row .fields .if .spacing{margin-right:3px}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i5$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i5$2.MatChipList, selector: "mat-chip-list", inputs: ["role", "aria-describedby", "errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { kind: "directive", type: i5$2.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "role", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { kind: "component", type: i10.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i10.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "directive", type: i11.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i11.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i11.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: ValueComponent, selector: "configcat-value", inputs: ["valueFormControl", "setting"] }, { kind: "directive", type: InputDisplayNormalizerDirective, selector: "input[inputDisplayNormalizer]" }] });
975
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: RolloutRulesComponent, decorators: [{
870
976
  type: Component,
871
- args: [{ selector: 'configcat-rollout-rules', template: "<div [formGroup]=\"formGroup\">\n <div cdkDropList (cdkDropListDropped)=\"onDrop($event)\" [cdkDropListDisabled]=\"readOnly\"\n [cdkDropListData]=\"rolloutRules().controls\">\n <div *ngFor=\"let rolloutRule of rolloutRules().controls; trackBy: trackByIndex; let i = index\" cdkDrag>\n <div class=\"targeting-row\">\n <div class=\"fields flex\" *ngIf=\"getRolloutRuleTypeFormControl(rolloutRule).value === 0\">\n <div class=\"drag-handle\" cdkDragHandle matTooltip=\"Drag here to reorder\" matTooltipPosition=\"above\"\n *ngIf=\"!readOnly\">\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"if\">\n <mat-chip-list [class.spacing]=\"i === 0\">\n <mat-chip class=\"chip\">{{ i === 0 ? 'IF' : 'ELSE IF' }}</mat-chip>\n </mat-chip-list>\n <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">user's</a>\n </div>\n\n <select class=\"custom-select attribute-select\" matTooltip=\"Comparison attribute\"\n matTooltipPosition=\"above\"\n (change)=\"attributeChanged($event.target, getRolloutRuleComparisonAttributeFormControl(rolloutRule))\">\n <option *ngFor=\"let comparisonAttribute of defaultComparisonAttributes\"\n [selected]=\"comparisonAttribute === getRolloutRuleComparisonAttributeFormControl(rolloutRule).value\">\n {{comparisonAttribute}}</option>\n <option\n [selected]=\"defaultComparisonAttributes.indexOf(getRolloutRuleComparisonAttributeFormControl(rolloutRule).value) === -1\">\n Custom\n </option>\n </select>\n\n\n <span class=\"attribute-span\" matTooltip=\"Custom user attribute\" matTooltipPosition=\"above\"\n [hidden]=\"defaultComparisonAttributes.indexOf(getRolloutRuleComparisonAttributeFormControl(rolloutRule).value) !== -1\">\n <span class=\"attribute-error\"\n *ngIf=\"getRolloutRuleComparisonAttributeFormControl(rolloutRule).invalid\">*</span>\n <input\n [ngClass]=\"{'invalid': getRolloutRuleComparisonAttributeFormControl(rolloutRule).invalid}\"\n type=\"text\" matInput [matAutocomplete]=\"auto\"\n [formControl]=\"getRolloutRuleComparisonAttributeFormControl(rolloutRule)\" class=\"attribute\"\n placeholder=\"e.g. Eye color\">\n </span>\n\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let option of comparisonAttributes()\" [value]=\"option\">\n {{option}}\n </mat-option>\n </mat-autocomplete>\n\n <div class=\"select-wrapper\">\n <select class=\"custom-select\" [formControl]=\"getRolloutRuleComparatorFormControl(rolloutRule)\"\n matTooltip=\"Comparator\" matTooltipPosition=\"above\"\n (change)=\"comparatorChanged(rolloutRule)\">\n <optgroup label=\"CONFIDENTIAL TEXT\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(16, 18)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"TEXT\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(0, 4)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"SEMANTIC VERSION\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(4, 10)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"NUMBER\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(10, 16)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n </select>\n <div [class]=\"getInfoClass(rolloutRule)\" [matTooltip]=\"getInfoTooltip(rolloutRule)\">\n <a href=\"https://configcat.com/docs/advanced/targeting/#comparator\" target=\"_blank\"\n rel=\"noopener noreferrer\">\n <mat-icon>info</mat-icon>\n </a>\n </div>\n </div>\n\n <div class=\"comparison-value\" matTooltip=\"Comparison value\" matTooltipPosition=\"above\">\n <span class=\"error\"\n *ngIf=\"getRolloutRuleComparisonValueFormControl(rolloutRule).invalid\">*</span>\n\n <input [ngClass]=\"{'invalid': getRolloutRuleComparisonValueFormControl(rolloutRule).invalid}\"\n [formControl]=\"getRolloutRuleComparisonValueFormControl(rolloutRule)\"\n [type]=\"getComparisonValueType(rolloutRule)\" [placeholder]=\"getPlaceHolder(rolloutRule)\">\n <div class=\"expand\" matTooltip=\"Pop-out Editor\" (click)=\"popOut(rolloutRule)\"\n *ngIf=\"getComparisonValueType(rolloutRule)==='text'\">\n <mat-icon>height</mat-icon>\n </div>\n </div>\n\n <div class=\"delete\" matTooltip=\"Remove targeting rule\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n\n <div class=\"fields flex\" *ngIf=\"getRolloutRuleTypeFormControl(rolloutRule).value === 1\">\n <div class=\"drag-handle\" cdkDragHandle matTooltip=\"Drag here to reorder\" matTooltipPosition=\"above\"\n *ngIf=\"!readOnly\">\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"if\">\n <mat-chip-list [class.spacing]=\"i === 0\">\n <mat-chip class=\"chip\">{{ i === 0 ? 'IF' : 'ELSE IF' }}</mat-chip>\n </mat-chip-list>\n <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">user</a>\n </div>\n\n\n <div class=\"select-wrapper\">\n <select class=\"custom-select segment-comparator\"\n [formControl]=\"getRolloutRuleSegmentComparatorFormControl(rolloutRule)\"\n matTooltip=\"Segment comparator\" matTooltipPosition=\"above\">\n <option *ngFor=\"let comparator of segmentComparators\" [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </select>\n </div>\n\n <div class=\"select-wrapper\">\n <span class=\"attribute-error\"\n *ngIf=\"getRolloutRuleSegmentIdFormControl(rolloutRule).invalid\">*</span>\n <select class=\"custom-select segment-select\"\n [formControl]=\"getRolloutRuleSegmentIdFormControl(rolloutRule)\" matTooltip=\"Segment\"\n matTooltipPosition=\"above\"\n [ngClass]=\"{'invalid': getRolloutRuleSegmentIdFormControl(rolloutRule).invalid}\">\n <option *ngFor=\"let segment of segments\" [ngValue]=\"segment.segmentId\">\n {{segment.name}}\n </option>\n </select>\n </div>\n\n\n <div class=\"delete\" matTooltip=\"Remove targeting rule\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n\n\n <div class=\"value flex\">\n <div class=\"serve\" *ngIf=\"setting().settingType !== SettingType.Boolean\">\n <mat-chip-list>\n <mat-chip class=\"chip\">Serve:</mat-chip>\n </mat-chip-list>\n </div>\n\n <configcat-value class=\"served-value\"\n [valueFormControl]=\"getRolloutRuleValueFormControl(rolloutRule)\" [setting]=\"setting()\">\n </configcat-value>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [".cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-animating{transition:transform .3s cubic-bezier(0,0,.2,1)}.targeting-row{border:1px solid #d5d5d5;background-color:#fff;margin:1em;display:flex;position:relative;padding:.5em 0}.targeting-row:hover{background-color:#dbedff}.targeting-row .select-wrapper{position:relative}.targeting-row .info{position:absolute;cursor:pointer;top:-8px;left:166px;border-radius:50%;background-color:#fff;height:18px;width:18px}.targeting-row .info a{color:#0068f0;opacity:.5}.targeting-row .info a:hover{opacity:1}.targeting-row .info mat-icon{font-size:18px;height:18px;width:18px}.targeting-row .warn{position:absolute;cursor:pointer;top:-8px;left:166px;height:18px;width:18px;border-radius:50%;background-color:#fff}.targeting-row .warn a{color:#fdc67f}.targeting-row .warn a:hover{color:#ff9200}.targeting-row .warn mat-icon{font-size:18px;height:18px;width:18px}.chip{background-color:#67b1fc3d}.custom-select{margin-left:.5em;width:170px;background-color:#fff;border:1px solid #e5e5e5;height:30px;min-height:30px;line-height:30px;min-width:170px;font-size:.8em;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.fields{justify-content:left;max-width:1060px;flex-grow:100}.fields .if{display:flex;align-items:center}.fields .if>*{margin:0 .5em}.fields .if .spacing{margin-right:41px}.fields .if .user-link{width:40px}.fields .attribute-span{margin-left:.5em;display:flex;align-items:center}.fields .attribute{width:170px;background-color:#fff;border:1px solid #e5e5e5;margin:3px 0;min-height:28px;flex-grow:100;min-width:170px;padding:0 30px 0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300;font-size:13.3px}.fields .invalid{border:1px solid #ff5252}.fields .attribute-error{color:#ff5252;margin:0 5px}.fields .delete{position:absolute;cursor:pointer;top:-9px;right:-10px;z-index:999;border-radius:50%;background-color:#fff;height:20px;width:20px;color:#ed5251}.fields .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.fields .delete:hover mat-icon{opacity:1}.fields .drag-handle{position:absolute;cursor:-moz-grab;left:-20px;top:14px}.fields .drag-handle mat-icon{font-size:20px}.fields .attribute-select{min-width:100px;width:100px;margin-left:0}.fields .segment-comparator,.fields .segment-select{margin-left:0;margin-right:.5em}.fields .segment-more mat-icon{position:relative;top:3px;cursor:pointer;font-size:16px;height:16px;width:16px;color:#797979;margin-top:3px}.fields .comparison-value{flex-grow:100;min-width:150px;display:flex;align-items:center;margin-left:.5em;margin-right:.5em}.fields .comparison-value .error{color:#ff5252;margin:0 5px}.fields .comparison-value input{background-color:#fff;border:1px solid #e5e5e5;margin:3px 0;min-height:28px;min-width:150px;flex-grow:100;padding:0 30px 0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.fields .comparison-value .invalid{border:1px solid #ff5252}.fields .comparison-value .expand{position:relative;height:24px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.fields .comparison-value .expand mat-icon{transform:rotate(45deg)}.value{margin-left:auto;flex-wrap:nowrap}.value .serve{margin:0 2px 0 5px}.value .served-value{margin:3px 0}.flex{display:flex;flex-wrap:wrap;align-items:center}.mat-chip{font-size:12px}@media (max-width: 1200px){.targeting-row{flex-wrap:wrap}.targeting-row .fields{max-width:500px}}@media (max-width: 920px){.value .served-value{margin:3px 7px 3px 0}.targeting-row .fields .drag-handle{left:-18px}}@media (max-width: 410px){.value .served-value{margin:7px 7px 3px 4px}}@media (max-width: 510px){.fields .comparison-value .error{display:none}}@media (max-width: 650px){.targeting-row{flex-direction:column}.targeting-row .help{left:161px}.targeting-row .fields{flex-direction:column;align-items:stretch}.targeting-row .fields .custom-select{margin:7px 7px 0}.targeting-row .fields .comparison-value{margin:7px}.targeting-row .fields .comparison-value input{margin:0 4px 0 0}.targeting-row .fields .attribute-span{margin:7px 7px 0}.targeting-row .fields .if{font-size:12px}.targeting-row .fields .if .spacing{margin-right:3px}}\n"] }]
872
- }], ctorParameters: function () { return [{ type: i1$1.MatDialog }]; }, propDecorators: { formGroup: [{
977
+ args: [{ selector: 'configcat-rollout-rules', template: "<div [formGroup]=\"formGroup\">\n <div cdkDropList (cdkDropListDropped)=\"onDrop($event)\" [cdkDropListDisabled]=\"readOnly\"\n [cdkDropListData]=\"rolloutRules().controls\">\n <div *ngFor=\"let rolloutRule of rolloutRules().controls; trackBy: trackByIndex; let i = index\" cdkDrag>\n <div class=\"targeting-row\">\n <div class=\"fields flex\" *ngIf=\"getRolloutRuleTypeFormControl(rolloutRule).value === 0\">\n <div class=\"drag-handle\" cdkDragHandle matTooltip=\"Drag here to reorder\" matTooltipPosition=\"above\"\n *ngIf=\"!readOnly\">\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"if\">\n <mat-chip-list [class.spacing]=\"i === 0\">\n <mat-chip class=\"chip\">{{ i === 0 ? 'IF' : 'ELSE IF' }}</mat-chip>\n </mat-chip-list>\n <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">user's</a>\n </div>\n\n <select class=\"custom-select attribute-select\" matTooltip=\"Comparison attribute\"\n matTooltipPosition=\"above\"\n (change)=\"attributeChanged($event.target, getRolloutRuleComparisonAttributeFormControl(rolloutRule))\">\n <option *ngFor=\"let comparisonAttribute of defaultComparisonAttributes\"\n [selected]=\"comparisonAttribute === getRolloutRuleComparisonAttributeFormControl(rolloutRule).value\">\n {{comparisonAttribute}}</option>\n <option\n [selected]=\"defaultComparisonAttributes.indexOf(getRolloutRuleComparisonAttributeFormControl(rolloutRule).value) === -1\">\n Custom\n </option>\n </select>\n\n\n <span class=\"attribute-span\" matTooltip=\"Custom user attribute\" matTooltipPosition=\"above\"\n [hidden]=\"defaultComparisonAttributes.indexOf(getRolloutRuleComparisonAttributeFormControl(rolloutRule).value) !== -1\">\n <span class=\"attribute-error\"\n *ngIf=\"getRolloutRuleComparisonAttributeFormControl(rolloutRule).invalid\">*</span>\n <input\n [ngClass]=\"{'invalid': getRolloutRuleComparisonAttributeFormControl(rolloutRule).invalid}\"\n type=\"text\" matInput [matAutocomplete]=\"auto\"\n [formControl]=\"getRolloutRuleComparisonAttributeFormControl(rolloutRule)\" class=\"attribute\"\n placeholder=\"e.g. Eye color\">\n </span>\n\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let option of comparisonAttributes()\" [value]=\"option\">\n {{option}}\n </mat-option>\n </mat-autocomplete>\n\n <div class=\"select-wrapper\">\n <select class=\"custom-select\" [formControl]=\"getRolloutRuleComparatorFormControl(rolloutRule)\"\n matTooltip=\"Comparator\" matTooltipPosition=\"above\"\n (change)=\"comparatorChanged(rolloutRule)\">\n <optgroup label=\"CONFIDENTIAL TEXT\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(16, 18)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"TEXT\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(0, 4)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"SEMANTIC VERSION\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(4, 10)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"NUMBER\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(10, 16)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n </select>\n <div [class]=\"getInfoClass(rolloutRule)\" [matTooltip]=\"getInfoTooltip(rolloutRule)\">\n <a href=\"https://configcat.com/docs/advanced/targeting/#comparator\" target=\"_blank\"\n rel=\"noopener noreferrer\">\n <mat-icon>info</mat-icon>\n </a>\n </div>\n </div>\n\n <div class=\"comparison-value\" matTooltip=\"Comparison value\" matTooltipPosition=\"above\">\n <span class=\"error\"\n *ngIf=\"getRolloutRuleComparisonValueFormControl(rolloutRule).invalid\">*</span>\n\n <input [ngClass]=\"{'invalid': getRolloutRuleComparisonValueFormControl(rolloutRule).invalid}\"\n [formControl]=\"getRolloutRuleComparisonValueFormControl(rolloutRule)\"\n [type]=\"getComparisonValueType(rolloutRule)\" [placeholder]=\"getPlaceHolder(rolloutRule)\"\n inputDisplayNormalizer>\n <div class=\"expand\" matTooltip=\"Pop-out Editor\" (click)=\"popOut(rolloutRule)\"\n *ngIf=\"getComparisonValueType(rolloutRule)==='text'\">\n <mat-icon>height</mat-icon>\n </div>\n </div>\n\n <div class=\"delete\" matTooltip=\"Remove targeting rule\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n\n <div class=\"fields flex\" *ngIf=\"getRolloutRuleTypeFormControl(rolloutRule).value === 1\">\n <div class=\"drag-handle\" cdkDragHandle matTooltip=\"Drag here to reorder\" matTooltipPosition=\"above\"\n *ngIf=\"!readOnly\">\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"if\">\n <mat-chip-list [class.spacing]=\"i === 0\">\n <mat-chip class=\"chip\">{{ i === 0 ? 'IF' : 'ELSE IF' }}</mat-chip>\n </mat-chip-list>\n <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">user</a>\n </div>\n\n\n <div class=\"select-wrapper\">\n <select class=\"custom-select segment-comparator\"\n [formControl]=\"getRolloutRuleSegmentComparatorFormControl(rolloutRule)\"\n matTooltip=\"Segment comparator\" matTooltipPosition=\"above\">\n <option *ngFor=\"let comparator of segmentComparators\" [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </select>\n </div>\n\n <div class=\"select-wrapper\">\n <span class=\"attribute-error\"\n *ngIf=\"getRolloutRuleSegmentIdFormControl(rolloutRule).invalid\">*</span>\n <select class=\"custom-select segment-select\"\n [formControl]=\"getRolloutRuleSegmentIdFormControl(rolloutRule)\" matTooltip=\"Segment\"\n matTooltipPosition=\"above\"\n [ngClass]=\"{'invalid': getRolloutRuleSegmentIdFormControl(rolloutRule).invalid}\">\n <option *ngFor=\"let segment of segments\" [ngValue]=\"segment.segmentId\">\n {{segment.name}}\n </option>\n </select>\n </div>\n\n\n <div class=\"delete\" matTooltip=\"Remove targeting rule\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n\n\n <div class=\"value flex\">\n <div class=\"serve\" *ngIf=\"setting().settingType !== SettingType.Boolean\">\n <mat-chip-list>\n <mat-chip class=\"chip\">Serve:</mat-chip>\n </mat-chip-list>\n </div>\n\n <configcat-value class=\"served-value\"\n [valueFormControl]=\"getRolloutRuleValueFormControl(rolloutRule)\" [setting]=\"setting()\">\n </configcat-value>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [".cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-animating{transition:transform .3s cubic-bezier(0,0,.2,1)}.targeting-row{border:1px solid #d5d5d5;background-color:#fff;margin:1em;display:flex;position:relative;padding:.5em 0}.targeting-row:hover{background-color:#dbedff}.targeting-row .select-wrapper{position:relative}.targeting-row .info{position:absolute;cursor:pointer;top:-8px;left:166px;border-radius:50%;background-color:#fff;height:18px;width:18px}.targeting-row .info a{color:#0068f0;opacity:.5}.targeting-row .info a:hover{opacity:1}.targeting-row .info mat-icon{font-size:18px;height:18px;width:18px}.targeting-row .warn{position:absolute;cursor:pointer;top:-8px;left:166px;height:18px;width:18px;border-radius:50%;background-color:#fff}.targeting-row .warn a{color:#fdc67f}.targeting-row .warn a:hover{color:#ff9200}.targeting-row .warn mat-icon{font-size:18px;height:18px;width:18px}.chip{background-color:#67b1fc3d}.custom-select{margin-left:.5em;width:170px;background-color:#fff;border:1px solid #e5e5e5;height:30px;min-height:30px;line-height:30px;min-width:170px;font-size:.8em;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.fields{justify-content:left;max-width:1060px;flex-grow:100}.fields .if{display:flex;align-items:center}.fields .if>*{margin:0 .5em}.fields .if .spacing{margin-right:41px}.fields .if .user-link{width:40px}.fields .attribute-span{margin-left:.5em;display:flex;align-items:center}.fields .attribute-span[hidden]{display:none}.fields .attribute{width:170px;background-color:#fff;border:1px solid #e5e5e5;margin:3px 0;min-height:28px;flex-grow:100;min-width:170px;padding:0 30px 0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300;font-size:13.3px}.fields .invalid{border:1px solid #ff5252}.fields .attribute-error{color:#ff5252;margin:0 5px}.fields .delete{position:absolute;cursor:pointer;top:-9px;right:-10px;z-index:999;border-radius:50%;background-color:#fff;height:20px;width:20px;color:#ed5251}.fields .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.fields .delete:hover mat-icon{opacity:1}.fields .drag-handle{position:absolute;cursor:-moz-grab;left:-20px;top:14px}.fields .drag-handle mat-icon{font-size:20px}.fields .attribute-select{min-width:100px;width:100px;margin-left:0}.fields .segment-comparator,.fields .segment-select{margin-left:0;margin-right:.5em}.fields .segment-more mat-icon{position:relative;top:3px;cursor:pointer;font-size:16px;height:16px;width:16px;color:#797979;margin-top:3px}.fields .comparison-value{flex-grow:100;min-width:150px;display:flex;align-items:center;margin-left:.5em;margin-right:.5em}.fields .comparison-value .error{color:#ff5252;margin:0 5px}.fields .comparison-value input{background-color:#fff;border:1px solid #e5e5e5;margin:3px 0;min-height:28px;min-width:150px;flex-grow:100;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.fields .comparison-value input[type=text]{padding-right:30px}.fields .comparison-value .invalid{border:1px solid #ff5252}.fields .comparison-value .expand{position:relative;height:24px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.fields .comparison-value .expand mat-icon{transform:rotate(45deg)}.value{margin-left:auto;flex-wrap:nowrap}.value .serve{margin:0 2px 0 5px}.value .served-value{margin:3px 0}.flex{display:flex;flex-wrap:wrap;align-items:center}.mat-chip{font-size:12px}@media (max-width: 1200px){.targeting-row{flex-wrap:wrap}.targeting-row .fields{max-width:500px}}@media (max-width: 920px){.value .served-value{margin:3px 7px 3px 0}.targeting-row .fields .drag-handle{left:-18px}}@media (max-width: 410px){.value .served-value{margin:7px 7px 3px 4px}}@media (max-width: 510px){.fields .comparison-value .error{display:none}}@media (max-width: 650px){.targeting-row{flex-direction:column}.targeting-row .help{left:161px}.targeting-row .fields{flex-direction:column;align-items:stretch}.targeting-row .fields .custom-select{margin:7px 7px 0}.targeting-row .fields .comparison-value{margin:7px}.targeting-row .fields .comparison-value input{margin:0 4px 0 0}.targeting-row .fields .attribute-span{margin:7px 7px 0}.targeting-row .fields .if{font-size:12px}.targeting-row .fields .if .spacing{margin-right:3px}}\n"] }]
978
+ }], ctorParameters: function () { return [{ type: i1$1.MatDialog }, { type: SettingListFormHelper }]; }, propDecorators: { formGroup: [{
873
979
  type: Input
874
980
  }], readOnly: [{
875
981
  type: Input
@@ -980,9 +1086,9 @@ class SettingComponent {
980
1086
  return this.dashboardBasePath + '/' + this.productId + '/' + this.configId + '/' + this.environmentId + '?settingId=' + this.setting().settingId;
981
1087
  }
982
1088
  }
983
- SettingComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: SettingComponent, deps: [{ token: SettingListFormHelper }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
984
- SettingComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: SettingComponent, selector: "setting", inputs: { dashboardBasePath: "dashboardBasePath", productId: "productId", environmentId: "environmentId", configId: "configId", formGroup: "formGroup", readOnly: "readOnly", canEditSetting: "canEditSetting", canDeleteSetting: "canDeleteSetting", deleteSettingText: "deleteSettingText", showEnvironmentName: "showEnvironmentName", segments: "segments" }, outputs: { editSettingRequested: "editSettingRequested", deleteSettingRequested: "deleteSettingRequested" }, ngImport: i0, template: "<div class=\"setting-full\" [formGroup]=\"formGroup\">\n <div class=\"delete\" (click)=\"deleteSetting()\" *ngIf=\"canDeleteSetting\" [matTooltip]=\"deleteSettingText\"\n data-robot=\"deleteSetting\">\n <mat-icon>cancel</mat-icon>\n </div>\n <div class=\"setting-header flex\">\n <div class=\"setting-name flex\">\n <div class=\"name\" data-robot=\"settingName\">\n {{setting().name}}\n <span *ngIf=\"showEnvironmentName\"> ({{environment().name}})</span>\n </div>\n <div class=\"edit\" matTooltip=\"Edit name and description\" (click)=\"editSetting()\" *ngIf=\"canEditSetting\"\n data-robot=\"renameSetting\">\n <mat-icon>edit</mat-icon>\n </div>\n </div>\n </div>\n <div class=\"setting-content\">\n <div class=\"setting-details\">\n <div class=\"setting-key\"><code data-robot=\"settingKey\">{{setting().key}}</code></div>\n <span *ngIf=\"setting().hint\" class=\"description\">{{setting().hint}}</span>\n <div class=\"open\"><a [href]=\"getDashboardUrl()\" target=\"_blank\" rel=\"noopener noreferrer\">Open in ConfigCat</a>\n </div>\n </div>\n\n <div class=\"rules-list\">\n <div>\n <configcat-rollout-rules *ngIf=\"rolloutRules().controls.length !== 0\" [formGroup]=\"formGroup\"\n [segments]=\"segments\">\n </configcat-rollout-rules>\n </div>\n\n <configcat-rollout-percentage-items *ngIf=\"rolloutPercentageItems().controls.length !== 0\"\n [formGroup]=\"formGroup\">\n </configcat-rollout-percentage-items>\n\n <div class=\"all-other flex\">\n <div *ngIf=\"rolloutPercentageItems().length === 0 && rolloutRules().length !== 0\"\n matTooltip=\"This value will be served to all users who the above rules don't apply.\"\n matTooltipPosition=\"above\">\n <mat-chip-list>\n <mat-chip class=\"chip\">To all other users, serve:</mat-chip>\n </mat-chip-list>\n </div>\n <div *ngIf=\"rolloutPercentageItems().length !== 0\"\n matTooltip=\"This fallback value will be served in case the user can't be identified.\"\n matTooltipPosition=\"above\">\n <mat-chip-list>\n <mat-chip class=\"chip\">To unidentified users, serve:</mat-chip>\n </mat-chip-list>\n </div>\n <div *ngIf=\"rolloutPercentageItems().length === 0 && rolloutRules().length === 0\">\n <mat-chip-list>\n <mat-chip class=\"chip\">To all users, serve:</mat-chip>\n </mat-chip-list>\n </div>\n <configcat-value class=\"served-value\" [valueFormControl]=\"value()\" [setting]=\"setting()\">\n </configcat-value>\n </div>\n <div class=\"buttons\">\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addRolloutRule()\" *ngIf=\"!readOnly\">\n {{rolloutRules().length === 0 ? 'Target specific users' : 'Add new targeting rule'}}\n </button>\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addSegmentRolloutRule()\" *ngIf=\"!readOnly\">\n {{rolloutRules().length === 0 ? 'Target segment' : 'Target new segment'}}\n </button>\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addRolloutPercentageItem()\"\n *ngIf=\"!readOnly\"\n [disabled]=\"setting().settingType === SettingType.Boolean && rolloutPercentageItems().length !== 0\">\n {{rolloutPercentageItems().length === 0 ? 'Target % of users' : 'Add new % option'}}\n </button>\n </div>\n </div>\n </div>\n</div>", styles: [".setting-full{position:relative;display:flex;flex-wrap:nowrap;flex-direction:column}.setting-full .delete{position:absolute;right:-10px;top:-10px;color:#ed5251;background-color:#fff;border-radius:50%;height:20px;width:20px;cursor:pointer}.setting-full .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.setting-full .delete:hover mat-icon{opacity:1}.setting-full .setting-header{padding:1.5em .8em 0 1em}.setting-full .setting-header .setting-name{flex-direction:row}.setting-full .setting-header .setting-name:hover>.edit{visibility:visible}.setting-full .setting-header .setting-name .name{font-weight:700;word-wrap:break-word;max-width:100%}.setting-full .setting-header .setting-name .edit{margin:5px 0 0 5px;cursor:pointer;visibility:hidden;color:gray}.setting-full .setting-header .setting-name .edit:hover{visibility:visible}.setting-full .setting-header .setting-name .edit mat-icon{font-size:18px}.setting-full .setting-header .setting-meta{margin-left:auto;margin-right:14px;font-size:.7em;color:gray}.setting-full .setting-content{display:flex}.setting-full .setting-content .setting-details{display:flex;flex-direction:column;width:400px;padding:0 0 .5em .5em}.setting-full .setting-content .setting-details>*{margin:.5em}.setting-full .setting-content .setting-details .open{font-size:14px}.setting-full .setting-content .setting-details .integrations{font-size:.8rem}.setting-full .setting-content .setting-details .integrations>div{margin:3px}.setting-full .setting-content .setting-details .integrations>div>a:hover{text-decoration:underline}.setting-full .setting-content .setting-details .setting-key{word-wrap:break-word}.setting-full .setting-content .setting-details .description{font-size:.8em;white-space:pre-wrap;word-wrap:break-word;max-width:300px}.setting-full .setting-content .setting-details code{background-color:#d3d3d3;padding:3px 6px}.setting-full .setting-content .rules-list{width:100%;padding:0 .3em .3em 1em}.setting-full .setting-content .targeting-button{margin-left:.5rem;margin-right:.5rem;margin-bottom:1.5em;text-transform:uppercase}.all-other{min-height:40px;justify-content:flex-start;border:1px solid #d5d5d5;background-color:#fff;margin:.5em 1em;padding:4px 0 4px .5em}.all-other .chip{background-color:#67b1fc3d}.all-other .served-value{margin-left:auto;margin-top:3px;margin-bottom:3px}.end{margin-left:auto}.buttons{display:flex;margin-left:.5rem;margin-right:.5rem}.buttons .updated-date{font-size:.7em;margin-left:auto;margin-right:22px;color:gray}.flex{display:flex;flex-wrap:wrap;align-items:center}.show-hide-toggle{margin-left:1em;cursor:pointer}.show-hide-toggle a{font-size:.8rem}.sige-button{background-color:#d9eadc;color:#363636;cursor:pointer;justify-content:center;padding:.375em .75em;text-align:center;white-space:nowrap;font-size:.75rem;border:1px solid #dbdbdb;box-shadow:none;display:inline-flex;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif}.sige-button:hover{background-color:#bad0be}.sige-button:disabled{background-color:#fff;color:#b3b3b3}.mat-chip{font-size:12px}@media (max-width: 1200px){.setting-details{width:300px!important}}@media (max-width: 920px){.setting-full .setting-content{flex-wrap:wrap}.setting-full .setting-content .rules-list{padding:0}.setting-full .setting-content .targeting-button{margin-bottom:.5em;margin-top:.5em;padding:.6em 0}.colorbar{min-width:5px}.buttons{flex-direction:column;margin-bottom:.5em;margin-left:.4em;margin-right:.4em}.created-date,.updated-date{display:none}.setting-details{width:100%!important;padding:.2em 0 .2em .2em}.setting-details .description{max-width:none!important}.rollout-rules{margin-bottom:1em}.all-other{margin:1em;padding:7px 0 7px .5em}.all-other .served-value{margin:7px 7px 4px auto}}@media (max-width: 380px){.mat-standard-chip{min-height:auto!important;height:auto!important}.mat-chip-list-wrapper{padding-right:7px}.sige-button{font-size:.65rem}}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i5$2.MatChipList, selector: "mat-chip-list", inputs: ["role", "aria-describedby", "errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { kind: "directive", type: i5$2.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "role", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { kind: "component", type: RolloutPercentageItemsComponent, selector: "configcat-rollout-percentage-items", inputs: ["formGroup", "readOnly"] }, { kind: "component", type: RolloutRulesComponent, selector: "configcat-rollout-rules", inputs: ["formGroup", "readOnly", "segments"] }, { kind: "component", type: ValueComponent, selector: "configcat-value", inputs: ["valueFormControl", "setting"] }] });
985
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: SettingComponent, decorators: [{
1089
+ SettingComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SettingComponent, deps: [{ token: SettingListFormHelper }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1090
+ SettingComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: SettingComponent, selector: "setting", inputs: { dashboardBasePath: "dashboardBasePath", productId: "productId", environmentId: "environmentId", configId: "configId", formGroup: "formGroup", readOnly: "readOnly", canEditSetting: "canEditSetting", canDeleteSetting: "canDeleteSetting", deleteSettingText: "deleteSettingText", showEnvironmentName: "showEnvironmentName", segments: "segments" }, outputs: { editSettingRequested: "editSettingRequested", deleteSettingRequested: "deleteSettingRequested" }, ngImport: i0, template: "<div class=\"setting-full\" [formGroup]=\"formGroup\">\n <div class=\"delete\" (click)=\"deleteSetting()\" *ngIf=\"canDeleteSetting\" [matTooltip]=\"deleteSettingText\"\n data-robot=\"deleteSetting\">\n <mat-icon>cancel</mat-icon>\n </div>\n <div class=\"setting-header flex\">\n <div class=\"setting-name flex\">\n <div class=\"name\" data-robot=\"settingName\">\n {{setting().name}}\n <span *ngIf=\"showEnvironmentName\"> ({{environment().name}})</span>\n </div>\n <div class=\"edit\" matTooltip=\"Edit name and description\" (click)=\"editSetting()\" *ngIf=\"canEditSetting\"\n data-robot=\"renameSetting\">\n <mat-icon>edit</mat-icon>\n </div>\n </div>\n </div>\n <div class=\"setting-content\">\n <div class=\"setting-details\">\n <div class=\"setting-key\"><code data-robot=\"settingKey\">{{setting().key}}</code></div>\n <span *ngIf=\"setting().hint\" class=\"description\">{{setting().hint}}</span>\n <div class=\"open\"><a [href]=\"getDashboardUrl()\" target=\"_blank\" rel=\"noopener noreferrer\">Open in ConfigCat</a>\n </div>\n </div>\n\n <div class=\"rules-list\">\n <div>\n <configcat-rollout-rules *ngIf=\"rolloutRules().controls.length !== 0\" [formGroup]=\"formGroup\"\n [segments]=\"segments\">\n </configcat-rollout-rules>\n </div>\n\n <configcat-rollout-percentage-items *ngIf=\"rolloutPercentageItems().controls.length !== 0\"\n [formGroup]=\"formGroup\">\n </configcat-rollout-percentage-items>\n\n <div class=\"all-other flex\">\n <div *ngIf=\"rolloutPercentageItems().length === 0 && rolloutRules().length !== 0\"\n matTooltip=\"This value will be served to all users who the above rules don't apply.\"\n matTooltipPosition=\"above\">\n <mat-chip-list>\n <mat-chip class=\"chip\">To all other users, serve:</mat-chip>\n </mat-chip-list>\n </div>\n <div *ngIf=\"rolloutPercentageItems().length !== 0\"\n matTooltip=\"This fallback value will be served in case the user can't be identified.\"\n matTooltipPosition=\"above\">\n <mat-chip-list>\n <mat-chip class=\"chip\">To unidentified users, serve:</mat-chip>\n </mat-chip-list>\n </div>\n <div *ngIf=\"rolloutPercentageItems().length === 0 && rolloutRules().length === 0\">\n <mat-chip-list>\n <mat-chip class=\"chip\">To all users, serve:</mat-chip>\n </mat-chip-list>\n </div>\n <configcat-value class=\"served-value\" [valueFormControl]=\"value()\" [setting]=\"setting()\">\n </configcat-value>\n </div>\n <div class=\"buttons\">\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addRolloutRule()\" *ngIf=\"!readOnly\">\n {{rolloutRules().length === 0 ? 'Target specific users' : 'Add new targeting rule'}}\n </button>\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addSegmentRolloutRule()\" *ngIf=\"!readOnly\">\n {{rolloutRules().length === 0 ? 'Target segment' : 'Target new segment'}}\n </button>\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addRolloutPercentageItem()\"\n *ngIf=\"!readOnly\"\n [disabled]=\"setting().settingType === SettingType.Boolean && rolloutPercentageItems().length !== 0\">\n {{rolloutPercentageItems().length === 0 ? 'Target % of users' : 'Add new % option'}}\n </button>\n </div>\n </div>\n </div>\n</div>", styles: [".setting-full{position:relative;display:flex;flex-wrap:nowrap;flex-direction:column}.setting-full .delete{position:absolute;right:-10px;top:-10px;color:#ed5251;background-color:#fff;border-radius:50%;height:20px;width:20px;cursor:pointer}.setting-full .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.setting-full .delete:hover mat-icon{opacity:1}.setting-full .setting-header{padding:1.5em .8em 0 1em}.setting-full .setting-header .setting-name{flex-direction:row}.setting-full .setting-header .setting-name:hover>.edit{visibility:visible}.setting-full .setting-header .setting-name .name{font-weight:700;word-wrap:break-word;max-width:100%}.setting-full .setting-header .setting-name .edit{margin:5px 0 0 5px;cursor:pointer;visibility:hidden;color:gray}.setting-full .setting-header .setting-name .edit:hover{visibility:visible}.setting-full .setting-header .setting-name .edit mat-icon{font-size:18px}.setting-full .setting-header .setting-meta{margin-left:auto;margin-right:14px;font-size:.7em;color:gray}.setting-full .setting-content{display:flex}.setting-full .setting-content .setting-details{display:flex;flex-direction:column;width:400px;padding:0 0 .5em .5em}.setting-full .setting-content .setting-details>*{margin:.5em}.setting-full .setting-content .setting-details .open{font-size:14px}.setting-full .setting-content .setting-details .integrations{font-size:.8rem}.setting-full .setting-content .setting-details .integrations>div{margin:3px}.setting-full .setting-content .setting-details .integrations>div>a:hover{text-decoration:underline}.setting-full .setting-content .setting-details .setting-key{word-wrap:break-word}.setting-full .setting-content .setting-details .description{font-size:.8em;white-space:pre-wrap;word-wrap:break-word;max-width:300px}.setting-full .setting-content .setting-details code{background-color:#d3d3d3;padding:3px 6px}.setting-full .setting-content .rules-list{width:100%;padding:0 .3em .3em 1em}.setting-full .setting-content .targeting-button{margin-left:.5rem;margin-right:.5rem;margin-bottom:1.5em;text-transform:uppercase}.all-other{min-height:40px;justify-content:flex-start;border:1px solid #d5d5d5;background-color:#fff;margin:.5em 1em;padding:4px 0 4px .5em}.all-other .chip{background-color:#67b1fc3d}.all-other .served-value{margin-left:auto;margin-top:3px;margin-bottom:3px}.end{margin-left:auto}.buttons{display:flex;margin-left:.5rem;margin-right:.5rem}.buttons .updated-date{font-size:.7em;margin-left:auto;margin-right:22px;color:gray}.flex{display:flex;flex-wrap:wrap;align-items:center}.show-hide-toggle{margin-left:1em;cursor:pointer}.show-hide-toggle a{font-size:.8rem}.sige-button{background-color:#d9eadc;color:#363636;cursor:pointer;justify-content:center;padding:.375em .75em;text-align:center;white-space:nowrap;font-size:.75rem;border:1px solid #dbdbdb;box-shadow:none;display:inline-flex;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif}.sige-button:hover{background-color:#bad0be}.sige-button:disabled{background-color:#fff;color:#b3b3b3}.mat-chip{font-size:12px}@media (max-width: 1200px){.setting-details{width:300px!important}}@media (max-width: 920px){.setting-full .setting-content{flex-wrap:wrap}.setting-full .setting-content .rules-list{padding:0}.setting-full .setting-content .targeting-button{margin-bottom:.5em;margin-top:.5em;padding:.6em 0}.colorbar{min-width:5px}.buttons{flex-direction:column;margin-bottom:.5em;margin-left:.4em;margin-right:.4em}.created-date,.updated-date{display:none}.setting-details{width:100%!important;padding:.2em 0 .2em .2em}.setting-details .description{max-width:none!important}.rollout-rules{margin-bottom:1em}.all-other{margin:1em;padding:7px 0 7px .5em}.all-other .served-value{margin:7px 7px 4px auto}}@media (max-width: 380px){.mat-standard-chip{min-height:auto!important;height:auto!important}.mat-chip-list-wrapper{padding-right:7px}.sige-button{font-size:.65rem}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i5$2.MatChipList, selector: "mat-chip-list", inputs: ["role", "aria-describedby", "errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { kind: "directive", type: i5$2.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "role", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { kind: "component", type: RolloutPercentageItemsComponent, selector: "configcat-rollout-percentage-items", inputs: ["formGroup", "readOnly"] }, { kind: "component", type: RolloutRulesComponent, selector: "configcat-rollout-rules", inputs: ["formGroup", "readOnly", "segments"] }, { kind: "component", type: ValueComponent, selector: "configcat-value", inputs: ["valueFormControl", "setting"] }] });
1091
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SettingComponent, decorators: [{
986
1092
  type: Component,
987
1093
  args: [{ selector: 'setting', template: "<div class=\"setting-full\" [formGroup]=\"formGroup\">\n <div class=\"delete\" (click)=\"deleteSetting()\" *ngIf=\"canDeleteSetting\" [matTooltip]=\"deleteSettingText\"\n data-robot=\"deleteSetting\">\n <mat-icon>cancel</mat-icon>\n </div>\n <div class=\"setting-header flex\">\n <div class=\"setting-name flex\">\n <div class=\"name\" data-robot=\"settingName\">\n {{setting().name}}\n <span *ngIf=\"showEnvironmentName\"> ({{environment().name}})</span>\n </div>\n <div class=\"edit\" matTooltip=\"Edit name and description\" (click)=\"editSetting()\" *ngIf=\"canEditSetting\"\n data-robot=\"renameSetting\">\n <mat-icon>edit</mat-icon>\n </div>\n </div>\n </div>\n <div class=\"setting-content\">\n <div class=\"setting-details\">\n <div class=\"setting-key\"><code data-robot=\"settingKey\">{{setting().key}}</code></div>\n <span *ngIf=\"setting().hint\" class=\"description\">{{setting().hint}}</span>\n <div class=\"open\"><a [href]=\"getDashboardUrl()\" target=\"_blank\" rel=\"noopener noreferrer\">Open in ConfigCat</a>\n </div>\n </div>\n\n <div class=\"rules-list\">\n <div>\n <configcat-rollout-rules *ngIf=\"rolloutRules().controls.length !== 0\" [formGroup]=\"formGroup\"\n [segments]=\"segments\">\n </configcat-rollout-rules>\n </div>\n\n <configcat-rollout-percentage-items *ngIf=\"rolloutPercentageItems().controls.length !== 0\"\n [formGroup]=\"formGroup\">\n </configcat-rollout-percentage-items>\n\n <div class=\"all-other flex\">\n <div *ngIf=\"rolloutPercentageItems().length === 0 && rolloutRules().length !== 0\"\n matTooltip=\"This value will be served to all users who the above rules don't apply.\"\n matTooltipPosition=\"above\">\n <mat-chip-list>\n <mat-chip class=\"chip\">To all other users, serve:</mat-chip>\n </mat-chip-list>\n </div>\n <div *ngIf=\"rolloutPercentageItems().length !== 0\"\n matTooltip=\"This fallback value will be served in case the user can't be identified.\"\n matTooltipPosition=\"above\">\n <mat-chip-list>\n <mat-chip class=\"chip\">To unidentified users, serve:</mat-chip>\n </mat-chip-list>\n </div>\n <div *ngIf=\"rolloutPercentageItems().length === 0 && rolloutRules().length === 0\">\n <mat-chip-list>\n <mat-chip class=\"chip\">To all users, serve:</mat-chip>\n </mat-chip-list>\n </div>\n <configcat-value class=\"served-value\" [valueFormControl]=\"value()\" [setting]=\"setting()\">\n </configcat-value>\n </div>\n <div class=\"buttons\">\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addRolloutRule()\" *ngIf=\"!readOnly\">\n {{rolloutRules().length === 0 ? 'Target specific users' : 'Add new targeting rule'}}\n </button>\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addSegmentRolloutRule()\" *ngIf=\"!readOnly\">\n {{rolloutRules().length === 0 ? 'Target segment' : 'Target new segment'}}\n </button>\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addRolloutPercentageItem()\"\n *ngIf=\"!readOnly\"\n [disabled]=\"setting().settingType === SettingType.Boolean && rolloutPercentageItems().length !== 0\">\n {{rolloutPercentageItems().length === 0 ? 'Target % of users' : 'Add new % option'}}\n </button>\n </div>\n </div>\n </div>\n</div>", styles: [".setting-full{position:relative;display:flex;flex-wrap:nowrap;flex-direction:column}.setting-full .delete{position:absolute;right:-10px;top:-10px;color:#ed5251;background-color:#fff;border-radius:50%;height:20px;width:20px;cursor:pointer}.setting-full .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.setting-full .delete:hover mat-icon{opacity:1}.setting-full .setting-header{padding:1.5em .8em 0 1em}.setting-full .setting-header .setting-name{flex-direction:row}.setting-full .setting-header .setting-name:hover>.edit{visibility:visible}.setting-full .setting-header .setting-name .name{font-weight:700;word-wrap:break-word;max-width:100%}.setting-full .setting-header .setting-name .edit{margin:5px 0 0 5px;cursor:pointer;visibility:hidden;color:gray}.setting-full .setting-header .setting-name .edit:hover{visibility:visible}.setting-full .setting-header .setting-name .edit mat-icon{font-size:18px}.setting-full .setting-header .setting-meta{margin-left:auto;margin-right:14px;font-size:.7em;color:gray}.setting-full .setting-content{display:flex}.setting-full .setting-content .setting-details{display:flex;flex-direction:column;width:400px;padding:0 0 .5em .5em}.setting-full .setting-content .setting-details>*{margin:.5em}.setting-full .setting-content .setting-details .open{font-size:14px}.setting-full .setting-content .setting-details .integrations{font-size:.8rem}.setting-full .setting-content .setting-details .integrations>div{margin:3px}.setting-full .setting-content .setting-details .integrations>div>a:hover{text-decoration:underline}.setting-full .setting-content .setting-details .setting-key{word-wrap:break-word}.setting-full .setting-content .setting-details .description{font-size:.8em;white-space:pre-wrap;word-wrap:break-word;max-width:300px}.setting-full .setting-content .setting-details code{background-color:#d3d3d3;padding:3px 6px}.setting-full .setting-content .rules-list{width:100%;padding:0 .3em .3em 1em}.setting-full .setting-content .targeting-button{margin-left:.5rem;margin-right:.5rem;margin-bottom:1.5em;text-transform:uppercase}.all-other{min-height:40px;justify-content:flex-start;border:1px solid #d5d5d5;background-color:#fff;margin:.5em 1em;padding:4px 0 4px .5em}.all-other .chip{background-color:#67b1fc3d}.all-other .served-value{margin-left:auto;margin-top:3px;margin-bottom:3px}.end{margin-left:auto}.buttons{display:flex;margin-left:.5rem;margin-right:.5rem}.buttons .updated-date{font-size:.7em;margin-left:auto;margin-right:22px;color:gray}.flex{display:flex;flex-wrap:wrap;align-items:center}.show-hide-toggle{margin-left:1em;cursor:pointer}.show-hide-toggle a{font-size:.8rem}.sige-button{background-color:#d9eadc;color:#363636;cursor:pointer;justify-content:center;padding:.375em .75em;text-align:center;white-space:nowrap;font-size:.75rem;border:1px solid #dbdbdb;box-shadow:none;display:inline-flex;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif}.sige-button:hover{background-color:#bad0be}.sige-button:disabled{background-color:#fff;color:#b3b3b3}.mat-chip{font-size:12px}@media (max-width: 1200px){.setting-details{width:300px!important}}@media (max-width: 920px){.setting-full .setting-content{flex-wrap:wrap}.setting-full .setting-content .rules-list{padding:0}.setting-full .setting-content .targeting-button{margin-bottom:.5em;margin-top:.5em;padding:.6em 0}.colorbar{min-width:5px}.buttons{flex-direction:column;margin-bottom:.5em;margin-left:.4em;margin-right:.4em}.created-date,.updated-date{display:none}.setting-details{width:100%!important;padding:.2em 0 .2em .2em}.setting-details .description{max-width:none!important}.rollout-rules{margin-bottom:1em}.all-other{margin:1em;padding:7px 0 7px .5em}.all-other .served-value{margin:7px 7px 4px auto}}@media (max-width: 380px){.mat-standard-chip{min-height:auto!important;height:auto!important}.mat-chip-list-wrapper{padding-right:7px}.sige-button{font-size:.65rem}}\n"] }]
988
1094
  }], ctorParameters: function () { return [{ type: SettingListFormHelper }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { dashboardBasePath: [{
@@ -1072,6 +1178,26 @@ class SettingListComponent {
1072
1178
  getSettingValueFormGroups() {
1073
1179
  return this.settingValuesFormArray().controls.map(c => c);
1074
1180
  }
1181
+ buildUpdateSettingValuesModel(settingValuesVM) {
1182
+ return settingValuesVM.map(settingValueVM => {
1183
+ var _a, _b;
1184
+ return {
1185
+ rolloutRules: (_a = settingValueVM.rolloutRules) === null || _a === void 0 ? void 0 : _a.map(rolloutRuleVM => ({
1186
+ comparisonAttribute: rolloutRuleVM.comparisonAttribute,
1187
+ comparator: rolloutRuleVM.comparator,
1188
+ comparisonValue: this.formHelper.normalizeComparisonValue(rolloutRuleVM.comparator, rolloutRuleVM.comparisonValue),
1189
+ segmentComparator: rolloutRuleVM.segmentComparator,
1190
+ segmentId: rolloutRuleVM.segmentId,
1191
+ value: rolloutRuleVM.value
1192
+ })),
1193
+ rolloutPercentageItems: (_b = settingValueVM.rolloutPercentageItems) === null || _b === void 0 ? void 0 : _b.map(rolloutPercentageItemVM => ({
1194
+ percentage: rolloutPercentageItemVM.percentage,
1195
+ value: rolloutPercentageItemVM.value
1196
+ })),
1197
+ value: settingValueVM.value
1198
+ };
1199
+ });
1200
+ }
1075
1201
  submit() {
1076
1202
  if (!this.formGroup || !this.formGroup.valid) {
1077
1203
  this.showFeedBackMessage = true;
@@ -1081,7 +1207,7 @@ class SettingListComponent {
1081
1207
  this.showFeedBackMessage = false;
1082
1208
  this.submitting = true;
1083
1209
  const updateSettingValuesModel = {
1084
- settingValues: this.formGroup.controls.settingValues.value,
1210
+ settingValues: this.buildUpdateSettingValuesModel(this.formGroup.controls.settingValues.value),
1085
1211
  knownLastUpdatedAt: this.settingValues.lastUpdatedAt,
1086
1212
  forced: false
1087
1213
  };
@@ -1170,12 +1296,12 @@ class SettingListComponent {
1170
1296
  });
1171
1297
  }
1172
1298
  }
1173
- SettingListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: SettingListComponent, deps: [{ token: SettingListFormHelper }, { token: i2$1.MatSnackBar }, { token: i1$1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
1174
- SettingListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: SettingListComponent, selector: "configcat-setting-list", inputs: { productId: "productId", environmentId: "environmentId", configId: "configId", dashboardBasePath: "dashboardBasePath", canEditSetting: "canEditSetting", canDeleteSetting: "canDeleteSetting", onSave: "onSave", loadSettingValues: "loadSettingValues", loadSegments: "loadSegments", deleteSettingText: "deleteSettingText", showEnvironmentName: "showEnvironmentName" }, outputs: { editSettingRequested: "editSettingRequested", deleteSettingRequested: "deleteSettingRequested", formValuesChanged: "formValuesChanged" }, usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"submit()\" *ngIf=\"!loading\">\n <div class=\"wrapper\" *ngFor=\"let settingValueFromGroup of getSettingValueFormGroups(); let i = index\">\n <setting [formGroup]=\"settingValueFromGroup\" [readOnly]=\"readOnly\" [canEditSetting]=\"canEditSetting\"\n [canDeleteSetting]=\"canDeleteSetting\" (editSettingRequested)=\"onEditSettingRequested($event)\"\n (deleteSettingRequested)=\"onDeleteSettingRequested($event)\" [deleteSettingText]=\"deleteSettingText\"\n [showEnvironmentName]=\"showEnvironmentName\" [segments]=\"segments\" [productId]=\"productId\" [configId]=\"configId\"\n [environmentId]=\"environmentId\" [dashboardBasePath]=\"dashboardBasePath\">\n </setting>\n </div>\n\n <div class=\"save\" *ngIf=\"!readOnly && !submitting && formGroup.dirty\">\n <div class=\"feedback\" *ngIf=\"formGroup.touched && formGroup.invalid && showFeedBackMessage\">\n <div class=\"error\" *ngIf=\"formGroup.errors && formGroup.errors.internalServerError\">\n <span>Something went wrong and we could not save your settings. You can try again or <a\n href=\"https://configcat.com/support\" target=\"_blank\" rel=\"noopener noreferrer\">contact us.</a></span>\n </div>\n <div class=\"error\" *ngIf=\"!formGroup.errors || !formGroup.errors.internalServerError\">\n <span>Oh no! A feature flag has invalid or missing data.</span>\n </div>\n </div>\n <button type=\"button\" mat-stroked-button *ngIf=\"!showRevertQuestion\" (click)=\"showRevertQuestion = true\">\n <mat-icon>history</mat-icon><span>Revert changes</span>\n </button>\n <div *ngIf=\"showRevertQuestion\">\n <span class=\"revert\">Revert to last saved state?</span>\n <button type=\"button\" class=\"yes\" mat-stroked-button (click)=\"handleRevertYes()\">Yes</button>\n <button type=\"button\" mat-stroked-button (click)=\"handleRevertCancel()\">No</button>\n </div>\n <button class=\"save-button\" mat-flat-button color=\"warn\" type=\"submit\" [disabled]=\"submitting\">\n <mat-icon>backup</mat-icon> <span> Save & publish changes</span>\n </button>\n </div>\n</form>", styles: [".wrapper{background-color:#f3f3f3;border:1px solid rgba(0,0,0,.12);margin:1em 0}.show-hide a{cursor:pointer;font-size:.8rem}.save{position:sticky;bottom:0;min-height:38px;padding:.5rem .5rem .5rem 0;background-color:#fff;display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:flex-end;z-index:1000}.save .save-button{animation:shadow-pulse 1s 3;margin-left:1rem}.save>*{margin:.3em}.save .revert{margin:0 16px;font-size:14px}.save .yes{margin:0 5px}.error{background-color:#a32b2d;color:#fff;padding:5px;font-size:.9em}.error a{color:#fff;text-decoration:underline}@media (max-width: 700px){.save{padding:.5rem 0}}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i5.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: SettingComponent, selector: "setting", inputs: ["dashboardBasePath", "productId", "environmentId", "configId", "formGroup", "readOnly", "canEditSetting", "canDeleteSetting", "deleteSettingText", "showEnvironmentName", "segments"], outputs: ["editSettingRequested", "deleteSettingRequested"] }] });
1175
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: SettingListComponent, decorators: [{
1299
+ SettingListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SettingListComponent, deps: [{ token: SettingListFormHelper }, { token: i2$2.MatSnackBar }, { token: i1$1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
1300
+ SettingListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: SettingListComponent, selector: "configcat-setting-list", inputs: { productId: "productId", environmentId: "environmentId", configId: "configId", dashboardBasePath: "dashboardBasePath", canEditSetting: "canEditSetting", canDeleteSetting: "canDeleteSetting", onSave: "onSave", loadSettingValues: "loadSettingValues", loadSegments: "loadSegments", deleteSettingText: "deleteSettingText", showEnvironmentName: "showEnvironmentName" }, outputs: { editSettingRequested: "editSettingRequested", deleteSettingRequested: "deleteSettingRequested", formValuesChanged: "formValuesChanged" }, usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"submit()\" *ngIf=\"!loading\">\n <div class=\"wrapper\" *ngFor=\"let settingValueFromGroup of getSettingValueFormGroups(); let i = index\">\n <setting [formGroup]=\"settingValueFromGroup\" [readOnly]=\"readOnly\" [canEditSetting]=\"canEditSetting\"\n [canDeleteSetting]=\"canDeleteSetting\" (editSettingRequested)=\"onEditSettingRequested($event)\"\n (deleteSettingRequested)=\"onDeleteSettingRequested($event)\" [deleteSettingText]=\"deleteSettingText\"\n [showEnvironmentName]=\"showEnvironmentName\" [segments]=\"segments\" [productId]=\"productId\" [configId]=\"configId\"\n [environmentId]=\"environmentId\" [dashboardBasePath]=\"dashboardBasePath\">\n </setting>\n </div>\n\n <div class=\"save\" *ngIf=\"!readOnly && !submitting && formGroup.dirty\">\n <div class=\"feedback\" *ngIf=\"formGroup.touched && formGroup.invalid && showFeedBackMessage\">\n <div class=\"error\" *ngIf=\"formGroup.errors && formGroup.errors.internalServerError\">\n <span>Something went wrong and we could not save your settings. You can try again or <a\n href=\"https://configcat.com/support\" target=\"_blank\" rel=\"noopener noreferrer\">contact us.</a></span>\n </div>\n <div class=\"error\" *ngIf=\"!formGroup.errors || !formGroup.errors.internalServerError\">\n <span>Oh no! A feature flag has invalid or missing data.</span>\n </div>\n </div>\n <button type=\"button\" mat-stroked-button *ngIf=\"!showRevertQuestion\" (click)=\"showRevertQuestion = true\">\n <mat-icon>history</mat-icon><span>Revert changes</span>\n </button>\n <div *ngIf=\"showRevertQuestion\">\n <span class=\"revert\">Revert to last saved state?</span>\n <button type=\"button\" class=\"yes\" mat-stroked-button (click)=\"handleRevertYes()\">Yes</button>\n <button type=\"button\" mat-stroked-button (click)=\"handleRevertCancel()\">No</button>\n </div>\n <button class=\"save-button\" mat-flat-button color=\"warn\" type=\"submit\" [disabled]=\"submitting\">\n <mat-icon>backup</mat-icon> <span> Save & publish changes</span>\n </button>\n </div>\n</form>", styles: [".wrapper{background-color:#f3f3f3;border:1px solid rgba(0,0,0,.12);margin:1em 0}.show-hide a{cursor:pointer;font-size:.8rem}.save{position:sticky;bottom:0;min-height:38px;padding:.5rem .5rem .5rem 0;background-color:#fff;display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:flex-end;z-index:1000}.save .save-button{animation:shadow-pulse 1s 3;margin-left:1rem}.save>*{margin:.3em}.save .revert{margin:0 16px;font-size:14px}.save .yes{margin:0 5px}.error{background-color:#a32b2d;color:#fff;padding:5px;font-size:.9em}.error a{color:#fff;text-decoration:underline}@media (max-width: 700px){.save{padding:.5rem 0}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i5.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: SettingComponent, selector: "setting", inputs: ["dashboardBasePath", "productId", "environmentId", "configId", "formGroup", "readOnly", "canEditSetting", "canDeleteSetting", "deleteSettingText", "showEnvironmentName", "segments"], outputs: ["editSettingRequested", "deleteSettingRequested"] }] });
1301
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SettingListComponent, decorators: [{
1176
1302
  type: Component,
1177
1303
  args: [{ selector: 'configcat-setting-list', template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"submit()\" *ngIf=\"!loading\">\n <div class=\"wrapper\" *ngFor=\"let settingValueFromGroup of getSettingValueFormGroups(); let i = index\">\n <setting [formGroup]=\"settingValueFromGroup\" [readOnly]=\"readOnly\" [canEditSetting]=\"canEditSetting\"\n [canDeleteSetting]=\"canDeleteSetting\" (editSettingRequested)=\"onEditSettingRequested($event)\"\n (deleteSettingRequested)=\"onDeleteSettingRequested($event)\" [deleteSettingText]=\"deleteSettingText\"\n [showEnvironmentName]=\"showEnvironmentName\" [segments]=\"segments\" [productId]=\"productId\" [configId]=\"configId\"\n [environmentId]=\"environmentId\" [dashboardBasePath]=\"dashboardBasePath\">\n </setting>\n </div>\n\n <div class=\"save\" *ngIf=\"!readOnly && !submitting && formGroup.dirty\">\n <div class=\"feedback\" *ngIf=\"formGroup.touched && formGroup.invalid && showFeedBackMessage\">\n <div class=\"error\" *ngIf=\"formGroup.errors && formGroup.errors.internalServerError\">\n <span>Something went wrong and we could not save your settings. You can try again or <a\n href=\"https://configcat.com/support\" target=\"_blank\" rel=\"noopener noreferrer\">contact us.</a></span>\n </div>\n <div class=\"error\" *ngIf=\"!formGroup.errors || !formGroup.errors.internalServerError\">\n <span>Oh no! A feature flag has invalid or missing data.</span>\n </div>\n </div>\n <button type=\"button\" mat-stroked-button *ngIf=\"!showRevertQuestion\" (click)=\"showRevertQuestion = true\">\n <mat-icon>history</mat-icon><span>Revert changes</span>\n </button>\n <div *ngIf=\"showRevertQuestion\">\n <span class=\"revert\">Revert to last saved state?</span>\n <button type=\"button\" class=\"yes\" mat-stroked-button (click)=\"handleRevertYes()\">Yes</button>\n <button type=\"button\" mat-stroked-button (click)=\"handleRevertCancel()\">No</button>\n </div>\n <button class=\"save-button\" mat-flat-button color=\"warn\" type=\"submit\" [disabled]=\"submitting\">\n <mat-icon>backup</mat-icon> <span> Save & publish changes</span>\n </button>\n </div>\n</form>", styles: [".wrapper{background-color:#f3f3f3;border:1px solid rgba(0,0,0,.12);margin:1em 0}.show-hide a{cursor:pointer;font-size:.8rem}.save{position:sticky;bottom:0;min-height:38px;padding:.5rem .5rem .5rem 0;background-color:#fff;display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:flex-end;z-index:1000}.save .save-button{animation:shadow-pulse 1s 3;margin-left:1rem}.save>*{margin:.3em}.save .revert{margin:0 16px;font-size:14px}.save .yes{margin:0 5px}.error{background-color:#a32b2d;color:#fff;padding:5px;font-size:.9em}.error a{color:#fff;text-decoration:underline}@media (max-width: 700px){.save{padding:.5rem 0}}\n"] }]
1178
- }], ctorParameters: function () { return [{ type: SettingListFormHelper }, { type: i2$1.MatSnackBar }, { type: i1$1.MatDialog }]; }, propDecorators: { productId: [{
1304
+ }], ctorParameters: function () { return [{ type: SettingListFormHelper }, { type: i2$2.MatSnackBar }, { type: i1$1.MatDialog }]; }, propDecorators: { productId: [{
1179
1305
  type: Input
1180
1306
  }], environmentId: [{
1181
1307
  type: Input
@@ -1288,9 +1414,9 @@ class SettingItemComponent extends BaseComponent {
1288
1414
  this.formValuesChanged.emit();
1289
1415
  }
1290
1416
  }
1291
- SettingItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: SettingItemComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1292
- SettingItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: SettingItemComponent, selector: "configcat-setting-item", inputs: { productId: "productId", environmentId: "environmentId", configId: "configId", settingId: "settingId", canEditSetting: "canEditSetting", canDeleteSetting: "canDeleteSetting", deleteSettingText: "deleteSettingText", showEnvironmentName: "showEnvironmentName" }, outputs: { editSettingRequested: "editSettingRequested", deleteSettingRequested: "deleteSettingRequested", loadSucceeded: "loadSucceeded", loadFailed: "loadFailed", saveSucceeded: "saveSucceeded", saveFailed: "saveFailed", formValuesChanged: "formValuesChanged" }, usesInheritance: true, ngImport: i0, template: "<configcat-setting-list [canEditSetting]=\"canEditSetting\" [canDeleteSetting]=\"canDeleteSetting\" [onSave]=\"handleSave\"\n [loadSettingValues]=\"loadSettingValues\" [loadSegments]=\"loadSegments\"\n (editSettingRequested)=\"onEditSettingRequested($event)\" (deleteSettingRequested)=\"onDeleteSettingRequested($event)\"\n [deleteSettingText]=\"deleteSettingText\" [showEnvironmentName]=\"showEnvironmentName\"\n (formValuesChanged)=\"onFormValuesChanged()\" [productId]=\"productId\" [configId]=\"configId\" [environmentId]=\"environmentId\"\n [dashboardBasePath]=\"dashboardBasePath\">\n</configcat-setting-list>", styles: [".container{font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;background-color:#f3f3f3;border:1px solid rgba(0,0,0,.12);border-radius:4px;margin:1em 0}.container .setting-full{position:relative;display:flex;flex-wrap:nowrap}.container .setting-full .setting-details{display:flex;flex-direction:column;width:400px;padding:1em 0 1em 1em}.container .setting-full .setting-details>*{margin:.5em}.container .setting-full .setting-details .setting-name{flex-direction:row}.container .setting-full .setting-details .setting-name .name{font-weight:700;word-wrap:break-word;max-width:100%}.container .setting-full .setting-details .setting-key{word-wrap:break-word}.container .setting-full .setting-details .description{font-size:.8em}.container .setting-full .setting-details code{background-color:#d3d3d3;padding:3px 6px}.container .setting-full .rules-list{width:100%;padding:1em}.container .setting-full .targeting-button{margin-left:1rem;margin-bottom:1em}.all-other{min-height:40px;justify-content:flex-start;border:1px solid #d5d5d5;border-radius:4px;background-color:#fff;margin:.5em 1em;padding:4px 0 4px .5em}.all-other .chip{background-color:#67b1fc3d}.all-other .served-value{margin-left:auto;min-width:100px}.end{margin-left:auto}.flex{display:flex;flex-wrap:wrap;align-items:center}.show-hide-toggle{margin-left:1em;cursor:pointer}@media (max-width: 1200px){.setting-full .setting-details{width:300px}}@media (max-width: 700px){.setting-full{flex-wrap:wrap}.setting-full .setting-details{padding:.2em 0 .2em .2em}.setting-full .all-other{margin:.5em .3em}}\n"], dependencies: [{ kind: "component", type: SettingListComponent, selector: "configcat-setting-list", inputs: ["productId", "environmentId", "configId", "dashboardBasePath", "canEditSetting", "canDeleteSetting", "onSave", "loadSettingValues", "loadSegments", "deleteSettingText", "showEnvironmentName"], outputs: ["editSettingRequested", "deleteSettingRequested", "formValuesChanged"] }] });
1293
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: SettingItemComponent, decorators: [{
1417
+ SettingItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SettingItemComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1418
+ SettingItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: SettingItemComponent, selector: "configcat-setting-item", inputs: { productId: "productId", environmentId: "environmentId", configId: "configId", settingId: "settingId", canEditSetting: "canEditSetting", canDeleteSetting: "canDeleteSetting", deleteSettingText: "deleteSettingText", showEnvironmentName: "showEnvironmentName" }, outputs: { editSettingRequested: "editSettingRequested", deleteSettingRequested: "deleteSettingRequested", loadSucceeded: "loadSucceeded", loadFailed: "loadFailed", saveSucceeded: "saveSucceeded", saveFailed: "saveFailed", formValuesChanged: "formValuesChanged" }, usesInheritance: true, ngImport: i0, template: "<configcat-setting-list [canEditSetting]=\"canEditSetting\" [canDeleteSetting]=\"canDeleteSetting\" [onSave]=\"handleSave\"\n [loadSettingValues]=\"loadSettingValues\" [loadSegments]=\"loadSegments\"\n (editSettingRequested)=\"onEditSettingRequested($event)\" (deleteSettingRequested)=\"onDeleteSettingRequested($event)\"\n [deleteSettingText]=\"deleteSettingText\" [showEnvironmentName]=\"showEnvironmentName\"\n (formValuesChanged)=\"onFormValuesChanged()\" [productId]=\"productId\" [configId]=\"configId\" [environmentId]=\"environmentId\"\n [dashboardBasePath]=\"dashboardBasePath\">\n</configcat-setting-list>", styles: [".container{font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;background-color:#f3f3f3;border:1px solid rgba(0,0,0,.12);border-radius:4px;margin:1em 0}.container .setting-full{position:relative;display:flex;flex-wrap:nowrap}.container .setting-full .setting-details{display:flex;flex-direction:column;width:400px;padding:1em 0 1em 1em}.container .setting-full .setting-details>*{margin:.5em}.container .setting-full .setting-details .setting-name{flex-direction:row}.container .setting-full .setting-details .setting-name .name{font-weight:700;word-wrap:break-word;max-width:100%}.container .setting-full .setting-details .setting-key{word-wrap:break-word}.container .setting-full .setting-details .description{font-size:.8em}.container .setting-full .setting-details code{background-color:#d3d3d3;padding:3px 6px}.container .setting-full .rules-list{width:100%;padding:1em}.container .setting-full .targeting-button{margin-left:1rem;margin-bottom:1em}.all-other{min-height:40px;justify-content:flex-start;border:1px solid #d5d5d5;border-radius:4px;background-color:#fff;margin:.5em 1em;padding:4px 0 4px .5em}.all-other .chip{background-color:#67b1fc3d}.all-other .served-value{margin-left:auto;min-width:100px}.end{margin-left:auto}.flex{display:flex;flex-wrap:wrap;align-items:center}.show-hide-toggle{margin-left:1em;cursor:pointer}@media (max-width: 1200px){.setting-full .setting-details{width:300px}}@media (max-width: 700px){.setting-full{flex-wrap:wrap}.setting-full .setting-details{padding:.2em 0 .2em .2em}.setting-full .all-other{margin:.5em .3em}}\n"], dependencies: [{ kind: "component", type: SettingListComponent, selector: "configcat-setting-list", inputs: ["productId", "environmentId", "configId", "dashboardBasePath", "canEditSetting", "canDeleteSetting", "onSave", "loadSettingValues", "loadSegments", "deleteSettingText", "showEnvironmentName"], outputs: ["editSettingRequested", "deleteSettingRequested", "formValuesChanged"] }] });
1419
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SettingItemComponent, decorators: [{
1294
1420
  type: Component,
1295
1421
  args: [{ selector: 'configcat-setting-item', template: "<configcat-setting-list [canEditSetting]=\"canEditSetting\" [canDeleteSetting]=\"canDeleteSetting\" [onSave]=\"handleSave\"\n [loadSettingValues]=\"loadSettingValues\" [loadSegments]=\"loadSegments\"\n (editSettingRequested)=\"onEditSettingRequested($event)\" (deleteSettingRequested)=\"onDeleteSettingRequested($event)\"\n [deleteSettingText]=\"deleteSettingText\" [showEnvironmentName]=\"showEnvironmentName\"\n (formValuesChanged)=\"onFormValuesChanged()\" [productId]=\"productId\" [configId]=\"configId\" [environmentId]=\"environmentId\"\n [dashboardBasePath]=\"dashboardBasePath\">\n</configcat-setting-list>", styles: [".container{font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;background-color:#f3f3f3;border:1px solid rgba(0,0,0,.12);border-radius:4px;margin:1em 0}.container .setting-full{position:relative;display:flex;flex-wrap:nowrap}.container .setting-full .setting-details{display:flex;flex-direction:column;width:400px;padding:1em 0 1em 1em}.container .setting-full .setting-details>*{margin:.5em}.container .setting-full .setting-details .setting-name{flex-direction:row}.container .setting-full .setting-details .setting-name .name{font-weight:700;word-wrap:break-word;max-width:100%}.container .setting-full .setting-details .setting-key{word-wrap:break-word}.container .setting-full .setting-details .description{font-size:.8em}.container .setting-full .setting-details code{background-color:#d3d3d3;padding:3px 6px}.container .setting-full .rules-list{width:100%;padding:1em}.container .setting-full .targeting-button{margin-left:1rem;margin-bottom:1em}.all-other{min-height:40px;justify-content:flex-start;border:1px solid #d5d5d5;border-radius:4px;background-color:#fff;margin:.5em 1em;padding:4px 0 4px .5em}.all-other .chip{background-color:#67b1fc3d}.all-other .served-value{margin-left:auto;min-width:100px}.end{margin-left:auto}.flex{display:flex;flex-wrap:wrap;align-items:center}.show-hide-toggle{margin-left:1em;cursor:pointer}@media (max-width: 1200px){.setting-full .setting-details{width:300px}}@media (max-width: 700px){.setting-full{flex-wrap:wrap}.setting-full .setting-details{padding:.2em 0 .2em .2em}.setting-full .all-other{margin:.5em .3em}}\n"] }]
1296
1422
  }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { productId: [{
@@ -1348,9 +1474,9 @@ class SettingSelectComponent extends BaseComponent {
1348
1474
  }
1349
1475
  }
1350
1476
  }
1351
- SettingSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: SettingSelectComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1352
- SettingSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: SettingSelectComponent, selector: "configcat-setting-select", inputs: { valueFormControl: "valueFormControl", configId: "configId" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Feature flag or setting</mat-label>\n <mat-select placeholder=\"Feature flag or setting\" [formControl]=\"valueFormControl\" *ngIf=\"settings\" name=\"value\">\n <mat-option *ngFor=\"let setting of settings\" [value]=\"setting.settingId\">{{setting.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }] });
1353
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: SettingSelectComponent, decorators: [{
1477
+ SettingSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SettingSelectComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1478
+ SettingSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: SettingSelectComponent, selector: "configcat-setting-select", inputs: { valueFormControl: "valueFormControl", configId: "configId" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Feature flag or setting</mat-label>\n <mat-select placeholder=\"Feature flag or setting\" [formControl]=\"valueFormControl\" *ngIf=\"settings\" name=\"value\">\n <mat-option *ngFor=\"let setting of settings\" [value]=\"setting.settingId\">{{setting.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }] });
1479
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SettingSelectComponent, decorators: [{
1354
1480
  type: Component,
1355
1481
  args: [{ selector: 'configcat-setting-select', template: "<mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Feature flag or setting</mat-label>\n <mat-select placeholder=\"Feature flag or setting\" [formControl]=\"valueFormControl\" *ngIf=\"settings\" name=\"value\">\n <mat-option *ngFor=\"let setting of settings\" [value]=\"setting.settingId\">{{setting.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"] }]
1356
1482
  }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { valueFormControl: [{
@@ -1377,9 +1503,9 @@ class ProductSelectComponent extends BaseComponent {
1377
1503
  });
1378
1504
  }
1379
1505
  }
1380
- ProductSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: ProductSelectComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1381
- ProductSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: ProductSelectComponent, selector: "configcat-product-select", inputs: { valueFormControl: "valueFormControl" }, usesInheritance: true, ngImport: i0, template: "<mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Product</mat-label>\n <mat-select placeholder=\"Product\" [formControl]=\"valueFormControl\" name=\"productValue\">\n <mat-option *ngFor=\"let product of products\" [value]=\"product.productId\">{{product.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }] });
1382
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: ProductSelectComponent, decorators: [{
1506
+ ProductSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ProductSelectComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1507
+ ProductSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: ProductSelectComponent, selector: "configcat-product-select", inputs: { valueFormControl: "valueFormControl" }, usesInheritance: true, ngImport: i0, template: "<mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Product</mat-label>\n <mat-select placeholder=\"Product\" [formControl]=\"valueFormControl\" name=\"productValue\">\n <mat-option *ngFor=\"let product of products\" [value]=\"product.productId\">{{product.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }] });
1508
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ProductSelectComponent, decorators: [{
1383
1509
  type: Component,
1384
1510
  args: [{ selector: 'configcat-product-select', template: "<mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Product</mat-label>\n <mat-select placeholder=\"Product\" [formControl]=\"valueFormControl\" name=\"productValue\">\n <mat-option *ngFor=\"let product of products\" [value]=\"product.productId\">{{product.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"] }]
1385
1511
  }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { valueFormControl: [{
@@ -1409,15 +1535,15 @@ class ConfigSelectComponent extends BaseComponent {
1409
1535
  }
1410
1536
  }
1411
1537
  }
1412
- ConfigSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: ConfigSelectComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1413
- ConfigSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: ConfigSelectComponent, selector: "configcat-config-select", inputs: { valueFormControl: "valueFormControl", productId: "productId" }, providers: [
1538
+ ConfigSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ConfigSelectComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1539
+ ConfigSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: ConfigSelectComponent, selector: "configcat-config-select", inputs: { valueFormControl: "valueFormControl", productId: "productId" }, providers: [
1414
1540
  {
1415
1541
  provide: NG_VALUE_ACCESSOR,
1416
1542
  useExisting: forwardRef(() => ConfigSelectComponent),
1417
1543
  multi: true
1418
1544
  }
1419
- ], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Config</mat-label>\n <mat-select placeholder=\"Config\" [formControl]=\"valueFormControl\" *ngIf=\"configs\" name=\"value\">\n <mat-option *ngFor=\"let config of configs\" [value]=\"config.configId\">{{config.name}}</mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }] });
1420
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: ConfigSelectComponent, decorators: [{
1545
+ ], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Config</mat-label>\n <mat-select placeholder=\"Config\" [formControl]=\"valueFormControl\" *ngIf=\"configs\" name=\"value\">\n <mat-option *ngFor=\"let config of configs\" [value]=\"config.configId\">{{config.name}}</mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }] });
1546
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ConfigSelectComponent, decorators: [{
1421
1547
  type: Component,
1422
1548
  args: [{ selector: 'configcat-config-select', providers: [
1423
1549
  {
@@ -1455,9 +1581,9 @@ class EnvironmentSelectComponent extends BaseComponent {
1455
1581
  }
1456
1582
  }
1457
1583
  }
1458
- EnvironmentSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: EnvironmentSelectComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1459
- EnvironmentSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: EnvironmentSelectComponent, selector: "configcat-environment-select", inputs: { valueFormControl: "valueFormControl", productId: "productId" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Environment</mat-label>\n <mat-select placeholder=\"Environment\" [formControl]=\"valueFormControl\" *ngIf=\"environments\" name=\"value\">\n <mat-option *ngFor=\"let environment of environments\" [value]=\"environment.environmentId\">{{environment.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }] });
1460
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: EnvironmentSelectComponent, decorators: [{
1584
+ EnvironmentSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EnvironmentSelectComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1585
+ EnvironmentSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: EnvironmentSelectComponent, selector: "configcat-environment-select", inputs: { valueFormControl: "valueFormControl", productId: "productId" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Environment</mat-label>\n <mat-select placeholder=\"Environment\" [formControl]=\"valueFormControl\" *ngIf=\"environments\" name=\"value\">\n <mat-option *ngFor=\"let environment of environments\" [value]=\"environment.environmentId\">{{environment.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5$3.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }] });
1586
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EnvironmentSelectComponent, decorators: [{
1461
1587
  type: Component,
1462
1588
  args: [{ selector: 'configcat-environment-select', template: "<mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Environment</mat-label>\n <mat-select placeholder=\"Environment\" [formControl]=\"valueFormControl\" *ngIf=\"environments\" name=\"value\">\n <mat-option *ngFor=\"let environment of environments\" [value]=\"environment.environmentId\">{{environment.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"] }]
1463
1589
  }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { valueFormControl: [{
@@ -1501,12 +1627,12 @@ class AuthorizationComponent {
1501
1627
  return this.publicApiService.getDashboardBasePath() + '/my-account/public-api-credentials';
1502
1628
  }
1503
1629
  }
1504
- AuthorizationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: AuthorizationComponent, deps: [{ token: i3.UntypedFormBuilder }, { token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1505
- AuthorizationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.1", type: AuthorizationComponent, selector: "configcat-authorization", inputs: { basePath: "basePath", integrationName: "integrationName" }, outputs: { authorized: "authorized" }, ngImport: i0, template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n <div class=\"container\">\n <div class=\"form\">\n <p>\n In order to use {{integrationName}} you have to authorize first with your ConfigCat Public API\n credentials.\n </p>\n <ul>\n <li>\n <a [href]=\"getPublicApiUrl()\" target=\"_blank\">\n Get your Basic Auth user name and password</a> to access ConfigCat Public API.\n <br />\n <b>Note!</b> Your ConfigCat account's email address and password will not work here.\n </li>\n <li>\n Type your credentials here and click the Authorize button.\n </li>\n </ul>\n\n <mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Basic auth user name</mat-label>\n <input matInput placeholder=\"Basic auth user name\" formControlName=\"basicAuthUsername\">\n <mat-error *ngIf=\"formGroup.controls.basicAuthUsername.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.basicAuthUsername)}}\n </mat-error>\n </mat-form-field>\n <mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Basic auth password</mat-label>\n <input matInput placeholder=\"Basic auth password\" formControlName=\"basicAuthPassword\" type=\"password\"\n autocomplete=\"current-password\">\n <mat-error *ngIf=\"formGroup.controls.basicAuthPassword.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.basicAuthPassword)}}\n </mat-error>\n </mat-form-field>\n <div>\n <button mat-flat-button color=\"primary\" type=\"submit\" class=\"submit\">Authorize</button>\n <mat-error *ngIf=\"formGroup.invalid && formGroup.errors && formGroup.errors.invalidAuthorization\">\n {{formGroup.errors.invalidAuthorization}}</mat-error>\n </div>\n </div>\n </div>\n</form>", styles: [".container{display:flex;margin:8px}.form{width:100%}.form-field{width:100%;margin-bottom:8px}.submit{margin-top:8px;margin-bottom:8px}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i4.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }] });
1506
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: AuthorizationComponent, decorators: [{
1630
+ AuthorizationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AuthorizationComponent, deps: [{ token: i2.UntypedFormBuilder }, { token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1631
+ AuthorizationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: AuthorizationComponent, selector: "configcat-authorization", inputs: { basePath: "basePath", integrationName: "integrationName" }, outputs: { authorized: "authorized" }, ngImport: i0, template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n <div class=\"container\">\n <div class=\"form\">\n <p>\n In order to use {{integrationName}} you have to authorize first with your ConfigCat Public API\n credentials.\n </p>\n <ul>\n <li>\n <a [href]=\"getPublicApiUrl()\" target=\"_blank\">\n Get your Basic Auth user name and password</a> to access ConfigCat Public API.\n <br />\n <b>Note!</b> Your ConfigCat account's email address and password will not work here.\n </li>\n <li>\n Type your credentials here and click the Authorize button.\n </li>\n </ul>\n\n <mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Basic auth user name</mat-label>\n <input matInput placeholder=\"Basic auth user name\" formControlName=\"basicAuthUsername\">\n <mat-error *ngIf=\"formGroup.controls.basicAuthUsername.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.basicAuthUsername)}}\n </mat-error>\n </mat-form-field>\n <mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Basic auth password</mat-label>\n <input matInput placeholder=\"Basic auth password\" formControlName=\"basicAuthPassword\" type=\"password\"\n autocomplete=\"current-password\">\n <mat-error *ngIf=\"formGroup.controls.basicAuthPassword.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.basicAuthPassword)}}\n </mat-error>\n </mat-form-field>\n <div>\n <button mat-flat-button color=\"primary\" type=\"submit\" class=\"submit\">Authorize</button>\n <mat-error *ngIf=\"formGroup.invalid && formGroup.errors && formGroup.errors.invalidAuthorization\">\n {{formGroup.errors.invalidAuthorization}}</mat-error>\n </div>\n </div>\n </div>\n</form>", styles: [".container{display:flex;margin:8px}.form{width:100%}.form-field{width:100%;margin-bottom:8px}.submit{margin-top:8px;margin-bottom:8px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i4.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }] });
1632
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AuthorizationComponent, decorators: [{
1507
1633
  type: Component,
1508
1634
  args: [{ selector: 'configcat-authorization', template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n <div class=\"container\">\n <div class=\"form\">\n <p>\n In order to use {{integrationName}} you have to authorize first with your ConfigCat Public API\n credentials.\n </p>\n <ul>\n <li>\n <a [href]=\"getPublicApiUrl()\" target=\"_blank\">\n Get your Basic Auth user name and password</a> to access ConfigCat Public API.\n <br />\n <b>Note!</b> Your ConfigCat account's email address and password will not work here.\n </li>\n <li>\n Type your credentials here and click the Authorize button.\n </li>\n </ul>\n\n <mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Basic auth user name</mat-label>\n <input matInput placeholder=\"Basic auth user name\" formControlName=\"basicAuthUsername\">\n <mat-error *ngIf=\"formGroup.controls.basicAuthUsername.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.basicAuthUsername)}}\n </mat-error>\n </mat-form-field>\n <mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Basic auth password</mat-label>\n <input matInput placeholder=\"Basic auth password\" formControlName=\"basicAuthPassword\" type=\"password\"\n autocomplete=\"current-password\">\n <mat-error *ngIf=\"formGroup.controls.basicAuthPassword.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.basicAuthPassword)}}\n </mat-error>\n </mat-form-field>\n <div>\n <button mat-flat-button color=\"primary\" type=\"submit\" class=\"submit\">Authorize</button>\n <mat-error *ngIf=\"formGroup.invalid && formGroup.errors && formGroup.errors.invalidAuthorization\">\n {{formGroup.errors.invalidAuthorization}}</mat-error>\n </div>\n </div>\n </div>\n</form>", styles: [".container{display:flex;margin:8px}.form{width:100%}.form-field{width:100%;margin-bottom:8px}.submit{margin-top:8px;margin-bottom:8px}\n"] }]
1509
- }], ctorParameters: function () { return [{ type: i3.UntypedFormBuilder }, { type: PublicApiService }]; }, propDecorators: { basePath: [{
1635
+ }], ctorParameters: function () { return [{ type: i2.UntypedFormBuilder }, { type: PublicApiService }]; }, propDecorators: { basePath: [{
1510
1636
  type: Input
1511
1637
  }], integrationName: [{
1512
1638
  type: Input
@@ -1523,8 +1649,8 @@ class NgConfigCatPublicApiUIModule {
1523
1649
  };
1524
1650
  }
1525
1651
  }
1526
- NgConfigCatPublicApiUIModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NgConfigCatPublicApiUIModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1527
- NgConfigCatPublicApiUIModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.1.1", ngImport: i0, type: NgConfigCatPublicApiUIModule, declarations: [BaseComponent,
1652
+ NgConfigCatPublicApiUIModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NgConfigCatPublicApiUIModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1653
+ NgConfigCatPublicApiUIModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: NgConfigCatPublicApiUIModule, declarations: [BaseComponent,
1528
1654
  ProductSelectComponent,
1529
1655
  ConfigSelectComponent,
1530
1656
  EnvironmentSelectComponent,
@@ -1539,7 +1665,8 @@ NgConfigCatPublicApiUIModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.
1539
1665
  ReasonDialogComponent,
1540
1666
  ConcurrentDialogComponent,
1541
1667
  SaveSnackbarComponent,
1542
- ExpandDialogComponent], imports: [CommonModule,
1668
+ ExpandDialogComponent,
1669
+ InputDisplayNormalizerDirective], imports: [CommonModule,
1543
1670
  FormsModule,
1544
1671
  ReactiveFormsModule,
1545
1672
  BrowserAnimationsModule,
@@ -1562,8 +1689,9 @@ NgConfigCatPublicApiUIModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.
1562
1689
  ConfigSelectComponent,
1563
1690
  EnvironmentSelectComponent,
1564
1691
  SettingSelectComponent,
1565
- SettingItemComponent] });
1566
- NgConfigCatPublicApiUIModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NgConfigCatPublicApiUIModule, imports: [CommonModule,
1692
+ SettingItemComponent,
1693
+ InputDisplayNormalizerDirective] });
1694
+ NgConfigCatPublicApiUIModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NgConfigCatPublicApiUIModule, imports: [CommonModule,
1567
1695
  FormsModule,
1568
1696
  ReactiveFormsModule,
1569
1697
  BrowserAnimationsModule,
@@ -1582,7 +1710,7 @@ NgConfigCatPublicApiUIModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.
1582
1710
  MatDialogModule,
1583
1711
  MatMenuModule,
1584
1712
  ApiModule] });
1585
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: NgConfigCatPublicApiUIModule, decorators: [{
1713
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NgConfigCatPublicApiUIModule, decorators: [{
1586
1714
  type: NgModule,
1587
1715
  args: [{
1588
1716
  declarations: [
@@ -1601,7 +1729,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
1601
1729
  ReasonDialogComponent,
1602
1730
  ConcurrentDialogComponent,
1603
1731
  SaveSnackbarComponent,
1604
- ExpandDialogComponent
1732
+ ExpandDialogComponent,
1733
+ InputDisplayNormalizerDirective
1605
1734
  ],
1606
1735
  imports: [
1607
1736
  CommonModule,
@@ -1630,7 +1759,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
1630
1759
  ConfigSelectComponent,
1631
1760
  EnvironmentSelectComponent,
1632
1761
  SettingSelectComponent,
1633
- SettingItemComponent
1762
+ SettingItemComponent,
1763
+ InputDisplayNormalizerDirective
1634
1764
  ]
1635
1765
  }]
1636
1766
  }], ctorParameters: function () { return []; } });
@@ -1643,5 +1773,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImpor
1643
1773
  * Generated bundle index. Do not edit.
1644
1774
  */
1645
1775
 
1646
- export { AuthorizationComponent, ConfigSelectComponent, EnvironmentSelectComponent, FormHelper, NgConfigCatPublicApiUIModule, ProductSelectComponent, PublicApiService, SettingItemComponent, SettingSelectComponent };
1776
+ export { AuthorizationComponent, ConfigSelectComponent, EnvironmentSelectComponent, FormHelper, InputDisplayNormalizerDirective, NgConfigCatPublicApiUIModule, ProductSelectComponent, PublicApiService, SettingItemComponent, SettingSelectComponent };
1647
1777
  //# sourceMappingURL=ng-configcat-publicapi-ui.mjs.map