ng-configcat-publicapi-ui 2.3.2 → 2.3.3

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 (50) hide show
  1. package/bundles/ng-configcat-publicapi-ui.umd.js +1029 -870
  2. package/bundles/ng-configcat-publicapi-ui.umd.js.map +1 -1
  3. package/esm2015/lib/_services/form-helper.js +3 -3
  4. package/esm2015/lib/_services/public-api.service.js +9 -11
  5. package/esm2015/lib/_services/setting-list-form-helper.js +25 -18
  6. package/esm2015/lib/authorization/authorization.component.js +23 -18
  7. package/esm2015/lib/base/base.component.js +18 -16
  8. package/esm2015/lib/configuration.js +7 -4
  9. package/esm2015/lib/dialogs/concurrent-dialog/concurrent-dialog.component.js +15 -12
  10. package/esm2015/lib/dialogs/expand-dialog/expand-dialog.component.js +31 -20
  11. package/esm2015/lib/dialogs/reason-dialog/reason-dialog.component.js +19 -14
  12. package/esm2015/lib/dialogs/save-snackbar/save-snackbar.component.js +12 -9
  13. package/esm2015/lib/ng-configcat-publicapi-ui.module.js +116 -57
  14. package/esm2015/lib/selects/config-select/config-select.component.js +36 -23
  15. package/esm2015/lib/selects/environment-select/environment-select.component.js +23 -16
  16. package/esm2015/lib/selects/product-select/product-select.component.js +21 -15
  17. package/esm2015/lib/selects/setting-select/setting-select.component.js +23 -16
  18. package/esm2015/lib/setting-item/setting-item.component.js +46 -31
  19. package/esm2015/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.js +32 -14
  20. package/esm2015/lib/setting-list/setting/rollout-rules/rollout-rules.component.js +53 -26
  21. package/esm2015/lib/setting-list/setting/setting.component.js +45 -26
  22. package/esm2015/lib/setting-list/setting/value/value.component.js +24 -16
  23. package/esm2015/lib/setting-list/setting-list.component.js +43 -27
  24. package/esm2015/ng-configcat-publicapi-ui.js +1 -15
  25. package/fesm2015/ng-configcat-publicapi-ui.js +986 -828
  26. package/fesm2015/ng-configcat-publicapi-ui.js.map +1 -1
  27. package/lib/_services/form-helper.d.ts +1 -1
  28. package/lib/_services/public-api.service.d.ts +10 -7
  29. package/lib/_services/setting-list-form-helper.d.ts +5 -2
  30. package/lib/authorization/authorization.component.d.ts +4 -1
  31. package/lib/base/base.component.d.ts +6 -3
  32. package/lib/configuration.d.ts +3 -0
  33. package/lib/dialogs/concurrent-dialog/concurrent-dialog.component.d.ts +3 -0
  34. package/lib/dialogs/expand-dialog/expand-dialog.component.d.ts +7 -3
  35. package/lib/dialogs/reason-dialog/reason-dialog.component.d.ts +3 -0
  36. package/lib/dialogs/save-snackbar/save-snackbar.component.d.ts +3 -0
  37. package/lib/ng-configcat-publicapi-ui.module.d.ts +38 -0
  38. package/lib/selects/config-select/config-select.component.d.ts +3 -0
  39. package/lib/selects/environment-select/environment-select.component.d.ts +3 -0
  40. package/lib/selects/product-select/product-select.component.d.ts +3 -0
  41. package/lib/selects/setting-select/setting-select.component.d.ts +3 -0
  42. package/lib/setting-item/setting-item.component.d.ts +3 -0
  43. package/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.d.ts +7 -2
  44. package/lib/setting-list/setting/rollout-rules/rollout-rules.component.d.ts +10 -4
  45. package/lib/setting-list/setting/setting.component.d.ts +3 -0
  46. package/lib/setting-list/setting/value/value.component.d.ts +3 -0
  47. package/lib/setting-list/setting-list.component.d.ts +5 -1
  48. package/ng-configcat-publicapi-ui.d.ts +1 -14
  49. package/package.json +8 -10
  50. package/ng-configcat-publicapi-ui.metadata.json +0 -1
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common/http'), require('ng-configcat-publicapi'), require('rxjs'), require('rxjs/operators'), require('@angular/forms'), require('@angular/common'), require('@angular/material/form-field'), require('@angular/material/core'), require('@angular/material/select'), require('@angular/material/button'), require('@angular/material/input'), require('@angular/material/dialog'), require('@angular/cdk/drag-drop'), require('semver'), require('@angular/material/snack-bar'), require('@angular/platform-browser/animations'), require('@angular/material/icon'), require('@angular/material/tooltip'), require('@angular/material/chips'), require('@angular/material/autocomplete'), require('@angular/router'), require('@angular/material/menu')) :
3
- typeof define === 'function' && define.amd ? define('ng-configcat-publicapi-ui', ['exports', '@angular/core', '@angular/common/http', 'ng-configcat-publicapi', 'rxjs', 'rxjs/operators', '@angular/forms', '@angular/common', '@angular/material/form-field', '@angular/material/core', '@angular/material/select', '@angular/material/button', '@angular/material/input', '@angular/material/dialog', '@angular/cdk/drag-drop', 'semver', '@angular/material/snack-bar', '@angular/platform-browser/animations', '@angular/material/icon', '@angular/material/tooltip', '@angular/material/chips', '@angular/material/autocomplete', '@angular/router', '@angular/material/menu'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['ng-configcat-publicapi-ui'] = {}, global.ng.core, global.ng.common.http, global['ng-configcat-publicapi'], global.rxjs, global.rxjs.operators, global.ng.forms, global.ng.common, global.ng.material.formField, global.ng.material.core, global.ng.material.select, global.ng.material.button, global.ng.material.input, global.ng.material.dialog, global.ng.cdk.dragDrop, global.semver, global.ng.material.snackBar, global.ng.platformBrowser.animations, global.ng.material.icon, global.ng.material.tooltip, global.ng.material.chips, global.ng.material.autocomplete, global.ng.router, global.ng.material.menu));
5
- }(this, (function (exports, i0, i1, ngConfigcatPublicapi, rxjs, operators, i1$1, common, formField, core, select, button, input, dialog, dragDrop, semver, snackBar, animations, icon, tooltip, chips, autocomplete, router, menu) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('ng-configcat-publicapi'), require('@angular/common/http'), require('rxjs'), require('rxjs/operators'), require('@angular/forms'), require('@angular/material/dialog'), require('@angular/material/form-field'), require('@angular/material/button'), require('@angular/material/input'), require('@angular/common'), require('@angular/router'), require('@angular/material/snack-bar'), require('@angular/material/icon'), require('@angular/cdk/drag-drop'), require('semver'), require('@angular/material/chips'), require('@angular/material/autocomplete'), require('@angular/material/core'), require('@angular/material/tooltip'), require('@angular/material/select'), require('@angular/platform-browser/animations'), require('@angular/material/menu')) :
3
+ typeof define === 'function' && define.amd ? define('ng-configcat-publicapi-ui', ['exports', '@angular/core', 'ng-configcat-publicapi', '@angular/common/http', 'rxjs', 'rxjs/operators', '@angular/forms', '@angular/material/dialog', '@angular/material/form-field', '@angular/material/button', '@angular/material/input', '@angular/common', '@angular/router', '@angular/material/snack-bar', '@angular/material/icon', '@angular/cdk/drag-drop', 'semver', '@angular/material/chips', '@angular/material/autocomplete', '@angular/material/core', '@angular/material/tooltip', '@angular/material/select', '@angular/platform-browser/animations', '@angular/material/menu'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["ng-configcat-publicapi-ui"] = {}, global.ng.core, global["ng-configcat-publicapi"], global.ng.common.http, global.rxjs, global.rxjs.operators, global.ng.forms, global.ng.material.dialog, global.ng.material.formField, global.ng.material.button, global.ng.material.input, global.ng.common, global.ng.router, global.ng.material.snackBar, global.ng.material.icon, global.ng.cdk.dragDrop, global.semver, global.ng.material.chips, global.ng.material.autocomplete, global.ng.material.core, global.ng.material.tooltip, global.ng.material.select, global.ng.platformBrowser.animations, global.ng.material.menu));
5
+ })(this, (function (exports, i0, ngConfigcatPublicapi, i1, rxjs, operators, i2, i1$1, i3, i4, i5, i5$1, i3$1, i2$2, i2$1, i8, semver, i3$2, i4$1, i4$2, i5$2, i3$3, animations, menu) { 'use strict';
6
6
 
7
7
  function _interopNamespace(e) {
8
8
  if (e && e.__esModule) return e;
@@ -13,21 +13,32 @@
13
13
  var d = Object.getOwnPropertyDescriptor(e, k);
14
14
  Object.defineProperty(n, k, d.get ? d : {
15
15
  enumerable: true,
16
- get: function () {
17
- return e[k];
18
- }
16
+ get: function () { return e[k]; }
19
17
  });
20
18
  }
21
19
  });
22
20
  }
23
- n['default'] = e;
21
+ n["default"] = e;
24
22
  return Object.freeze(n);
25
23
  }
26
24
 
27
25
  var i0__namespace = /*#__PURE__*/_interopNamespace(i0);
28
26
  var i1__namespace = /*#__PURE__*/_interopNamespace(i1);
27
+ var i2__namespace = /*#__PURE__*/_interopNamespace(i2);
29
28
  var i1__namespace$1 = /*#__PURE__*/_interopNamespace(i1$1);
30
- var semver__namespace = /*#__PURE__*/_interopNamespace(semver);
29
+ var i3__namespace = /*#__PURE__*/_interopNamespace(i3);
30
+ var i4__namespace = /*#__PURE__*/_interopNamespace(i4);
31
+ var i5__namespace = /*#__PURE__*/_interopNamespace(i5);
32
+ var i5__namespace$1 = /*#__PURE__*/_interopNamespace(i5$1);
33
+ var i3__namespace$1 = /*#__PURE__*/_interopNamespace(i3$1);
34
+ var i2__namespace$2 = /*#__PURE__*/_interopNamespace(i2$2);
35
+ var i2__namespace$1 = /*#__PURE__*/_interopNamespace(i2$1);
36
+ var i8__namespace = /*#__PURE__*/_interopNamespace(i8);
37
+ var i3__namespace$2 = /*#__PURE__*/_interopNamespace(i3$2);
38
+ var i4__namespace$1 = /*#__PURE__*/_interopNamespace(i4$1);
39
+ var i4__namespace$2 = /*#__PURE__*/_interopNamespace(i4$2);
40
+ var i5__namespace$2 = /*#__PURE__*/_interopNamespace(i5$2);
41
+ var i3__namespace$3 = /*#__PURE__*/_interopNamespace(i3$3);
31
42
 
32
43
  /*! *****************************************************************************
33
44
  Copyright (c) Microsoft Corporation.
@@ -255,10 +266,16 @@
255
266
  r[k] = a[j];
256
267
  return r;
257
268
  }
258
- function __spreadArray(to, from) {
259
- for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
260
- to[j] = from[i];
261
- return to;
269
+ function __spreadArray(to, from, pack) {
270
+ if (pack || arguments.length === 2)
271
+ for (var i = 0, l = from.length, ar; i < l; i++) {
272
+ if (ar || !(i in from)) {
273
+ if (!ar)
274
+ ar = Array.prototype.slice.call(from, 0, i);
275
+ ar[i] = from[i];
276
+ }
277
+ }
278
+ return to.concat(ar || Array.prototype.slice.call(from));
262
279
  }
263
280
  function __await(v) {
264
281
  return this instanceof __await ? (this.v = v, this) : new __await(v);
@@ -324,18 +341,21 @@
324
341
  function __importDefault(mod) {
325
342
  return (mod && mod.__esModule) ? mod : { default: mod };
326
343
  }
327
- function __classPrivateFieldGet(receiver, privateMap) {
328
- if (!privateMap.has(receiver)) {
329
- throw new TypeError("attempted to get private field on non-instance");
330
- }
331
- return privateMap.get(receiver);
344
+ function __classPrivateFieldGet(receiver, state, kind, f) {
345
+ if (kind === "a" && !f)
346
+ throw new TypeError("Private accessor was defined without a getter");
347
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
348
+ throw new TypeError("Cannot read private member from an object whose class did not declare it");
349
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
332
350
  }
333
- function __classPrivateFieldSet(receiver, privateMap, value) {
334
- if (!privateMap.has(receiver)) {
335
- throw new TypeError("attempted to set private field on non-instance");
336
- }
337
- privateMap.set(receiver, value);
338
- return value;
351
+ function __classPrivateFieldSet(receiver, state, value, kind, f) {
352
+ if (kind === "m")
353
+ throw new TypeError("Private method is not writable");
354
+ if (kind === "a" && !f)
355
+ throw new TypeError("Private accessor was defined without a setter");
356
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
357
+ throw new TypeError("Cannot write private member to an object whose class did not declare it");
358
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
339
359
  }
340
360
 
341
361
  var Configuration = /** @class */ (function () {
@@ -344,9 +364,11 @@
344
364
  }
345
365
  return Configuration;
346
366
  }());
347
- Configuration.decorators = [
348
- { type: i0.Injectable }
349
- ];
367
+ Configuration.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: Configuration, deps: [], target: i0__namespace.ɵɵFactoryTarget.Injectable });
368
+ Configuration.ɵprov = i0__namespace.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: Configuration });
369
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: Configuration, decorators: [{
370
+ type: i0.Injectable
371
+ }] });
350
372
 
351
373
  var PublicApiService = /** @class */ (function () {
352
374
  function PublicApiService(httpClient, configuration) {
@@ -425,14 +447,16 @@
425
447
  };
426
448
  return PublicApiService;
427
449
  }());
428
- PublicApiService.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function PublicApiService_Factory() { return new PublicApiService(i0__namespace.ɵɵinject(i1__namespace.HttpClient), i0__namespace.ɵɵinject(Configuration, 8)); }, token: PublicApiService, providedIn: "root" });
429
- PublicApiService.decorators = [
430
- { type: i0.Injectable, args: [{ providedIn: 'root' },] }
431
- ];
432
- PublicApiService.ctorParameters = function () { return [
433
- { type: i1.HttpClient },
434
- { type: Configuration, decorators: [{ type: i0.Optional }] }
435
- ]; };
450
+ PublicApiService.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: PublicApiService, deps: [{ token: i1__namespace.HttpClient }, { token: Configuration, optional: true }], target: i0__namespace.ɵɵFactoryTarget.Injectable });
451
+ PublicApiService.ɵprov = i0__namespace.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: PublicApiService, providedIn: 'root' });
452
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: PublicApiService, decorators: [{
453
+ type: i0.Injectable,
454
+ args: [{ providedIn: 'root' }]
455
+ }], ctorParameters: function () {
456
+ return [{ type: i1__namespace.HttpClient }, { type: Configuration, decorators: [{
457
+ type: i0.Optional
458
+ }] }];
459
+ } });
436
460
 
437
461
  var BaseComponent = /** @class */ (function () {
438
462
  function BaseComponent(publicApiService) {
@@ -458,357 +482,71 @@
458
482
  };
459
483
  return BaseComponent;
460
484
  }());
461
- BaseComponent.decorators = [
462
- { type: i0.Component, args: [{
463
- selector: 'base',
464
- template: '<div></div>'
465
- },] }
466
- ];
467
- BaseComponent.ctorParameters = function () { return [
468
- { type: PublicApiService }
469
- ]; };
470
- BaseComponent.propDecorators = {
471
- basePath: [{ type: i0.Input }],
472
- basicAuthUsername: [{ type: i0.Input }],
473
- basicAuthPassword: [{ type: i0.Input }]
474
- };
475
-
476
- var SettingItemComponent = /** @class */ (function (_super) {
477
- __extends(SettingItemComponent, _super);
478
- function SettingItemComponent(publicApiService) {
479
- var _this = _super.call(this, publicApiService) || this;
480
- _this.canEditSetting = true;
481
- _this.canDeleteSetting = true;
482
- _this.deleteSettingText = 'Delete setting';
483
- _this.showEnvironmentName = true;
484
- _this.editSettingRequested = new i0.EventEmitter();
485
- _this.deleteSettingRequested = new i0.EventEmitter();
486
- _this.loadSucceeded = new i0.EventEmitter();
487
- _this.loadFailed = new i0.EventEmitter();
488
- _this.saveSucceeded = new i0.EventEmitter();
489
- _this.saveFailed = new i0.EventEmitter();
490
- _this.formValuesChanged = new i0.EventEmitter();
491
- _this.loadSettingValues = function () {
492
- return _this.createSettingValuesService().getSettingValue(_this.environmentId, _this.settingId)
493
- .pipe(operators.map(function (settingValue) {
494
- _this.settingValue = settingValue;
495
- var settingValues = {
496
- settingValues: [settingValue],
497
- readOnly: settingValue.readOnly,
498
- config: settingValue.config,
499
- environment: settingValue.environment
500
- };
501
- _this.loadSucceeded.emit(settingValues);
502
- return settingValues;
503
- }), operators.catchError(function (error) {
504
- _this.loadFailed.emit(error);
505
- return rxjs.throwError(error);
506
- }));
507
- };
508
- _this.handleSave = function (model) {
509
- if (model.settingValues.length === 0) {
510
- return;
511
- }
512
- var updateModel = model.settingValues[0];
513
- return _this.createSettingValuesService().replaceSettingValue(_this.environmentId, _this.settingId, updateModel, model.reason)
514
- .pipe(operators.map(function (settingValue) {
515
- _this.settingValue = settingValue;
516
- var settingValues = {
517
- settingValues: [settingValue],
518
- readOnly: settingValue.readOnly,
519
- config: settingValue.config,
520
- environment: settingValue.environment
521
- };
522
- _this.saveSucceeded.emit(settingValues);
523
- return settingValues;
524
- }), operators.catchError(function (error) {
525
- _this.saveFailed.emit(error);
526
- return rxjs.throwError(error);
527
- }));
528
- };
529
- return _this;
530
- }
531
- SettingItemComponent.prototype.ngOnInit = function () {
532
- };
533
- SettingItemComponent.prototype.onEditSettingRequested = function (setting) {
534
- this.editSettingRequested.emit({
535
- setting: setting.setting,
536
- environment: this.settingValue.environment,
537
- config: this.settingValue.config
538
- });
539
- };
540
- SettingItemComponent.prototype.onDeleteSettingRequested = function (setting) {
541
- this.deleteSettingRequested.emit({
542
- setting: setting.setting,
543
- environment: this.settingValue.environment,
544
- config: this.settingValue.config
545
- });
546
- };
547
- SettingItemComponent.prototype.onFormValuesChanged = function () {
548
- this.formValuesChanged.emit();
549
- };
550
- return SettingItemComponent;
551
- }(BaseComponent));
552
- SettingItemComponent.decorators = [
553
- { type: i0.Component, args: [{
554
- selector: 'configcat-setting-item',
555
- template: "<configcat-setting-list [canEditSetting]=\"canEditSetting\" [canDeleteSetting]=\"canDeleteSetting\"\n [onSave]=\"handleSave\" [loadSettingValues]=\"loadSettingValues\"\n (editSettingRequested)=\"onEditSettingRequested($event)\" (deleteSettingRequested)=\"onDeleteSettingRequested($event)\"\n [deleteSettingText]=\"deleteSettingText\"\n [showEnvironmentName]=\"showEnvironmentName\" (formValuesChanged)=\"onFormValuesChanged()\">\n</configcat-setting-list>",
556
- 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:bold;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"]
557
- },] }
558
- ];
559
- SettingItemComponent.ctorParameters = function () { return [
560
- { type: PublicApiService }
561
- ]; };
562
- SettingItemComponent.propDecorators = {
563
- productId: [{ type: i0.Input }],
564
- environmentId: [{ type: i0.Input }],
565
- configId: [{ type: i0.Input }],
566
- settingId: [{ type: i0.Input }],
567
- canEditSetting: [{ type: i0.Input }],
568
- canDeleteSetting: [{ type: i0.Input }],
569
- deleteSettingText: [{ type: i0.Input }],
570
- showEnvironmentName: [{ type: i0.Input }],
571
- editSettingRequested: [{ type: i0.Output }],
572
- deleteSettingRequested: [{ type: i0.Output }],
573
- loadSucceeded: [{ type: i0.Output }],
574
- loadFailed: [{ type: i0.Output }],
575
- saveSucceeded: [{ type: i0.Output }],
576
- saveFailed: [{ type: i0.Output }],
577
- formValuesChanged: [{ type: i0.Output }]
578
- };
579
-
580
- var SettingSelectComponent = /** @class */ (function (_super) {
581
- __extends(SettingSelectComponent, _super);
582
- function SettingSelectComponent(publicApiService) {
583
- return _super.call(this, publicApiService) || this;
584
- }
585
- SettingSelectComponent.prototype.ngOnInit = function () {
586
- this.settings = [];
587
- this.reloadSettings();
588
- };
589
- SettingSelectComponent.prototype.ngOnChanges = function () {
590
- this.reloadSettings();
591
- };
592
- SettingSelectComponent.prototype.reloadSettings = function () {
593
- var _this = this;
594
- if (this.configId) {
595
- this.createSettingsService().getSettings(this.configId).subscribe(function (settings) {
596
- _this.settings = settings;
597
- if (_this.settings.length > 0) {
598
- _this.valueFormControl.setValue(_this.settings[0].settingId);
599
- }
600
- });
601
- }
602
- };
603
- return SettingSelectComponent;
604
- }(BaseComponent));
605
- SettingSelectComponent.decorators = [
606
- { type: i0.Component, args: [{
607
- selector: 'configcat-setting-select',
608
- template: "<mat-form-field class=\"form-field\">\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>",
609
- styles: [".form-field{width:100%}\n"]
610
- },] }
611
- ];
612
- SettingSelectComponent.ctorParameters = function () { return [
613
- { type: PublicApiService }
614
- ]; };
615
- SettingSelectComponent.propDecorators = {
616
- valueFormControl: [{ type: i0.Input }],
617
- configId: [{ type: i0.Input }]
618
- };
485
+ BaseComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: BaseComponent, deps: [{ token: PublicApiService }], target: i0__namespace.ɵɵFactoryTarget.Component });
486
+ BaseComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: BaseComponent, selector: "base", inputs: { basePath: "basePath", basicAuthUsername: "basicAuthUsername", basicAuthPassword: "basicAuthPassword" }, ngImport: i0__namespace, template: '<div></div>', isInline: true });
487
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: BaseComponent, decorators: [{
488
+ type: i0.Component,
489
+ args: [{
490
+ selector: 'base',
491
+ template: '<div></div>'
492
+ }]
493
+ }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { basePath: [{
494
+ type: i0.Input
495
+ }], basicAuthUsername: [{
496
+ type: i0.Input
497
+ }], basicAuthPassword: [{
498
+ type: i0.Input
499
+ }] } });
619
500
 
620
- var ProductSelectComponent = /** @class */ (function (_super) {
621
- __extends(ProductSelectComponent, _super);
622
- function ProductSelectComponent(publicApiService) {
623
- return _super.call(this, publicApiService) || this;
501
+ var ReasonDialogComponent = /** @class */ (function () {
502
+ function ReasonDialogComponent(dialogRef, formBuilder) {
503
+ this.dialogRef = dialogRef;
504
+ this.formBuilder = formBuilder;
624
505
  }
625
- ProductSelectComponent.prototype.ngOnInit = function () {
626
- var _this = this;
627
- this.products = [];
628
- this.createProductsService().getProducts().subscribe(function (products) {
629
- _this.products = products;
630
- if (_this.products.length > 0) {
631
- _this.valueFormControl.setValue(_this.products[0].productId, {
632
- emitEvent: true,
633
- emitModelToViewChange: true, emitViewToModelChange: true
634
- });
635
- }
506
+ ReasonDialogComponent.prototype.ngOnInit = function () {
507
+ this.formGroup = this.formBuilder.group({
508
+ reason: ['', [i2.Validators.required, i2.Validators.maxLength(1000)]]
636
509
  });
637
510
  };
638
- return ProductSelectComponent;
639
- }(BaseComponent));
640
- ProductSelectComponent.decorators = [
641
- { type: i0.Component, args: [{
642
- selector: 'configcat-product-select',
643
- template: "<mat-form-field class=\"form-field\">\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>",
644
- styles: [".form-field{width:100%}\n"]
645
- },] }
646
- ];
647
- ProductSelectComponent.ctorParameters = function () { return [
648
- { type: PublicApiService }
649
- ]; };
650
- ProductSelectComponent.propDecorators = {
651
- valueFormControl: [{ type: i0.Input }]
652
- };
653
-
654
- var ConfigSelectComponent = /** @class */ (function (_super) {
655
- __extends(ConfigSelectComponent, _super);
656
- function ConfigSelectComponent(publicApiService) {
657
- return _super.call(this, publicApiService) || this;
658
- }
659
- ConfigSelectComponent.prototype.ngOnInit = function () {
660
- this.configs = [];
661
- this.reloadConfigs();
662
- };
663
- ConfigSelectComponent.prototype.ngOnChanges = function () {
664
- this.reloadConfigs();
665
- };
666
- ConfigSelectComponent.prototype.reloadConfigs = function () {
667
- var _this = this;
668
- if (this.productId) {
669
- this.createConfigsService().getConfigs(this.productId).subscribe(function (configs) {
670
- _this.configs = configs;
671
- if (_this.configs.length > 0) {
672
- _this.valueFormControl.setValue(_this.configs[0].configId);
673
- }
674
- });
675
- }
676
- };
677
- return ConfigSelectComponent;
678
- }(BaseComponent));
679
- ConfigSelectComponent.decorators = [
680
- { type: i0.Component, args: [{
681
- selector: 'configcat-config-select',
682
- template: "<mat-form-field class=\"form-field\">\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>",
683
- providers: [
684
- {
685
- provide: i1$1.NG_VALUE_ACCESSOR,
686
- useExisting: i0.forwardRef(function () { return ConfigSelectComponent; }),
687
- multi: true
688
- }
689
- ],
690
- styles: [".form-field{width:100%}\n"]
691
- },] }
692
- ];
693
- ConfigSelectComponent.ctorParameters = function () { return [
694
- { type: PublicApiService }
695
- ]; };
696
- ConfigSelectComponent.propDecorators = {
697
- valueFormControl: [{ type: i0.Input }],
698
- productId: [{ type: i0.Input }]
699
- };
700
-
701
- var EnvironmentSelectComponent = /** @class */ (function (_super) {
702
- __extends(EnvironmentSelectComponent, _super);
703
- function EnvironmentSelectComponent(publicApiService) {
704
- return _super.call(this, publicApiService) || this;
705
- }
706
- EnvironmentSelectComponent.prototype.ngOnInit = function () {
707
- this.environments = [];
708
- this.reloadEnvironments();
709
- };
710
- EnvironmentSelectComponent.prototype.ngOnChanges = function () {
711
- this.reloadEnvironments();
712
- };
713
- EnvironmentSelectComponent.prototype.reloadEnvironments = function () {
714
- var _this = this;
715
- if (this.productId) {
716
- this.createEnvironmentsService().getEnvironments(this.productId).subscribe(function (environments) {
717
- _this.environments = environments;
718
- if (_this.environments.length > 0) {
719
- _this.valueFormControl.setValue(_this.environments[0].environmentId);
720
- }
721
- });
722
- }
723
- };
724
- return EnvironmentSelectComponent;
725
- }(BaseComponent));
726
- EnvironmentSelectComponent.decorators = [
727
- { type: i0.Component, args: [{
728
- selector: 'configcat-environment-select',
729
- template: "<mat-form-field class=\"form-field\">\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>",
730
- styles: [".form-field{width:100%}\n"]
731
- },] }
732
- ];
733
- EnvironmentSelectComponent.ctorParameters = function () { return [
734
- { type: PublicApiService }
735
- ]; };
736
- EnvironmentSelectComponent.propDecorators = {
737
- valueFormControl: [{ type: i0.Input }],
738
- productId: [{ type: i0.Input }]
739
- };
740
-
741
- var FormHelper = /** @class */ (function () {
742
- function FormHelper() {
743
- }
744
- FormHelper.getErrorMessage = function (control, hint) {
745
- if (hint === void 0) { hint = ''; }
746
- if (!control || control.valid) {
511
+ ReasonDialogComponent.prototype.handleSaveButton = function () {
512
+ if (!this.formGroup.valid) {
747
513
  return;
748
514
  }
749
- if (control.hasError('required')) {
750
- return hint + " The field is required.";
751
- }
752
- if (control.hasError('pattern')) {
753
- return 'Not a valid e-mail address.';
754
- }
755
- if (control.hasError('minlength')) {
756
- return 'The field must be at least ' + control.errors.minlength.requiredLength + ' characters long';
757
- }
758
- if (control.hasError('maxlength')) {
759
- return 'The field must be at max ' + control.errors.maxlength.requiredLength + ' characters long';
760
- }
761
- return;
515
+ this.dialogRef.close({ button: 'save', reason: this.formGroup.controls.reason.value });
762
516
  };
763
- return FormHelper;
517
+ ReasonDialogComponent.prototype.cancel = function () {
518
+ this.dialogRef.close({ button: 'cancel' });
519
+ };
520
+ return ReasonDialogComponent;
764
521
  }());
522
+ ReasonDialogComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: ReasonDialogComponent, deps: [{ token: i1__namespace$1.MatDialogRef }, { token: i2__namespace.FormBuilder }], target: i0__namespace.ɵɵFactoryTarget.Component });
523
+ ReasonDialogComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: ReasonDialogComponent, selector: "configcat-reason-dialog", ngImport: i0__namespace, 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-raised-button color=\"primary\">Add notes & Save</button>\n <button type=\"button\" mat-raised-button (click)=\"cancel()\">Cancel</button>\n </div>\n</form>", styles: [".container>*{width:100%}\n"], components: [{ type: i3__namespace.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i4__namespace.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"] }], directives: [{ type: i1__namespace$1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i2__namespace.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i2__namespace.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2__namespace.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i1__namespace$1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i3__namespace.MatLabel, selector: "mat-label" }, { type: i5__namespace.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["id", "disabled", "required", "type", "value", "readonly", "placeholder", "errorStateMatcher", "aria-describedby"], exportAs: ["matInput"] }, { type: i2__namespace.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2__namespace.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2__namespace.FormControlName, selector: "[formControlName]", inputs: ["disabled", "formControlName", "ngModel"], outputs: ["ngModelChange"] }, { type: i5__namespace$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.MatError, selector: "mat-error", inputs: ["id"] }, { type: i1__namespace$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
524
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: ReasonDialogComponent, decorators: [{
525
+ type: i0.Component,
526
+ args: [{
527
+ selector: 'configcat-reason-dialog',
528
+ templateUrl: './reason-dialog.component.html',
529
+ styleUrls: ['./reason-dialog.component.scss']
530
+ }]
531
+ }], ctorParameters: function () { return [{ type: i1__namespace$1.MatDialogRef }, { type: i2__namespace.FormBuilder }]; } });
765
532
 
766
- var AuthorizationComponent = /** @class */ (function () {
767
- function AuthorizationComponent(formBuilder, publicApiService) {
768
- this.formBuilder = formBuilder;
769
- this.publicApiService = publicApiService;
770
- this.basePath = null;
771
- this.authorized = new i0.EventEmitter();
772
- this.FormHelper = FormHelper;
533
+ var SaveSnackbarComponent = /** @class */ (function () {
534
+ function SaveSnackbarComponent() {
773
535
  }
774
- AuthorizationComponent.prototype.ngOnInit = function () {
775
- this.formGroup = this.formBuilder.group({
776
- basicAuthUsername: ['', i1$1.Validators.required],
777
- basicAuthPassword: ['', i1$1.Validators.required],
778
- });
779
- };
780
- AuthorizationComponent.prototype.onSubmit = function () {
781
- var _this = this;
782
- if (!this.formGroup.valid) {
783
- return;
784
- }
785
- var meService = this.publicApiService.createMeService(this.formGroup.controls.basicAuthUsername.value, this.formGroup.controls.basicAuthPassword.value, this.basePath);
786
- meService.getMe().subscribe(function (me) {
787
- _this.authorized.emit({
788
- basicAuthUsername: _this.formGroup.controls.basicAuthUsername.value,
789
- basicAuthPassword: _this.formGroup.controls.basicAuthPassword.value
790
- });
791
- }, function (error) {
792
- _this.formGroup.setErrors({ invalidAuthorization: 'Invalid Basic auth user name or password' });
793
- });
536
+ SaveSnackbarComponent.prototype.ngOnInit = function () {
794
537
  };
795
- return AuthorizationComponent;
538
+ return SaveSnackbarComponent;
796
539
  }());
797
- AuthorizationComponent.decorators = [
798
- { type: i0.Component, args: [{
799
- selector: 'configcat-authorization',
800
- template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n <div class=\"container\">\n <div class=\"form\">\n <p>\n <a href=\"https://app.configcat.com/my-account/public-api-credentials\" target=\"_blank\">\n Get your Basic Auth user name and password</a> to access ConfigCat Public API.\n <br /><br />\n <b>Note!</b> Your ConfigCat account's email address and password will not work here.\n </p>\n\n <mat-form-field class=\"form-field\">\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\">\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-raised-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>",
801
- styles: [".container{display:flex;margin:8px}.form{width:100%}.form-field{width:100%;margin-bottom:8px}.submit{margin-top:8px;margin-bottom:8px}\n"]
802
- },] }
803
- ];
804
- AuthorizationComponent.ctorParameters = function () { return [
805
- { type: i1$1.FormBuilder },
806
- { type: PublicApiService }
807
- ]; };
808
- AuthorizationComponent.propDecorators = {
809
- basePath: [{ type: i0.Input }],
810
- authorized: [{ type: i0.Output }]
811
- };
540
+ SaveSnackbarComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: SaveSnackbarComponent, deps: [], target: i0__namespace.ɵɵFactoryTarget.Component });
541
+ SaveSnackbarComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: SaveSnackbarComponent, selector: "configcat-save-snackbar", ngImport: i0__namespace, template: "<p class=\"header\">Settings saved successfully.</p>", styles: ["p{text-align:center;font-weight:bold}.header{font-size:1.2em}\n"] });
542
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: SaveSnackbarComponent, decorators: [{
543
+ type: i0.Component,
544
+ args: [{
545
+ selector: 'configcat-save-snackbar',
546
+ templateUrl: './save-snackbar.component.html',
547
+ styleUrls: ['./save-snackbar.component.scss']
548
+ }]
549
+ }], ctorParameters: function () { return []; } });
812
550
 
813
551
  var ConcurrentDialogComponent = /** @class */ (function () {
814
552
  function ConcurrentDialogComponent(dialogRef) {
@@ -824,38 +562,174 @@
824
562
  };
825
563
  return ConcurrentDialogComponent;
826
564
  }());
827
- ConcurrentDialogComponent.decorators = [
828
- { type: i0.Component, args: [{
829
- selector: 'configcat-concurrent-dialog',
830
- 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-raised-button color=\"primary\" (click)=\"discard()\">Discard\n local changes & reload</button>\n <button type=\"button\" mat-raised-button (click)=\"save()\">Save anyway</button>\n</div>",
831
- styles: [""]
832
- },] }
833
- ];
834
- ConcurrentDialogComponent.ctorParameters = function () { return [
835
- { type: dialog.MatDialogRef }
836
- ]; };
565
+ ConcurrentDialogComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: ConcurrentDialogComponent, deps: [{ token: i1__namespace$1.MatDialogRef }], target: i0__namespace.ɵɵFactoryTarget.Component });
566
+ ConcurrentDialogComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: ConcurrentDialogComponent, selector: "configcat-concurrent-dialog", ngImport: i0__namespace, 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-raised-button color=\"primary\" (click)=\"discard()\">Discard\n local changes & reload</button>\n <button type=\"button\" mat-raised-button (click)=\"save()\">Save anyway</button>\n</div>", styles: [""], components: [{ type: i4__namespace.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"] }], directives: [{ type: i1__namespace$1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i3__namespace$1.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["routerLink", "target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo"] }, { type: i1__namespace$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
567
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: ConcurrentDialogComponent, decorators: [{
568
+ type: i0.Component,
569
+ args: [{
570
+ selector: 'configcat-concurrent-dialog',
571
+ templateUrl: './concurrent-dialog.component.html',
572
+ styleUrls: ['./concurrent-dialog.component.scss']
573
+ }]
574
+ }], ctorParameters: function () { return [{ type: i1__namespace$1.MatDialogRef }]; } });
837
575
 
838
- var ExpandDialogComponent = /** @class */ (function () {
839
- function ExpandDialogComponent(dialogRef, formBuilder, data) {
840
- this.dialogRef = dialogRef;
576
+ var SettingListFormHelper = /** @class */ (function () {
577
+ function SettingListFormHelper(formBuilder) {
841
578
  this.formBuilder = formBuilder;
842
- this.data = data;
843
579
  }
844
- ExpandDialogComponent.prototype.ngOnInit = function () {
580
+ SettingListFormHelper.prototype.createSettingValuesFormGroup = function (settingValuesModel) {
845
581
  var _this = this;
846
- if (this.data.multiline) {
847
- this.buildFormGroup();
848
- }
849
- else {
850
- this.formControlSubscription = this.data.control.valueChanges.subscribe(function (value) {
582
+ var formGroup = this.formBuilder.group({
583
+ settingValues: this.formBuilder.array(settingValuesModel.settingValues.map(function (sv) {
584
+ return _this.createSettingValueFormGroup(sv, settingValuesModel.readOnly);
585
+ })),
586
+ // Decorator
587
+ environment: this.formBuilder.group({
588
+ environmentId: [{ value: settingValuesModel.environment.environmentId, disabled: true }],
589
+ name: [{ value: settingValuesModel.environment.name, disabled: true }],
590
+ }),
591
+ comparisonAttributes: [[]],
592
+ allRolloutRulesCount: [0]
593
+ });
594
+ var rolloutRules = this.getAllRolloutRules(formGroup);
595
+ var comparisonAttributes = this.getComparisonAttributes(rolloutRules);
596
+ formGroup.patchValue({ allRolloutRulesCount: rolloutRules.length });
597
+ formGroup.patchValue({ comparisonAttributes: comparisonAttributes });
598
+ return formGroup;
599
+ };
600
+ SettingListFormHelper.prototype.createSettingValueFormGroup = function (settingValueModel, readOnly) {
601
+ var _this = this;
602
+ if (!settingValueModel.setting) {
603
+ return this.formBuilder.group({});
604
+ }
605
+ return this.formBuilder.group({
606
+ settingId: [settingValueModel.setting.settingId],
607
+ value: [
608
+ { value: settingValueModel.value, disabled: readOnly },
609
+ this.getValidatorsForSettingType(settingValueModel.setting.settingType)
610
+ ],
611
+ rolloutPercentageItems: settingValueModel.rolloutPercentageItems
612
+ ? this.formBuilder.array(settingValueModel.rolloutPercentageItems.map(function (p) {
613
+ // @ts-ignore()
614
+ return _this.createRolloutPercentageItemFormGroup(p, readOnly, settingValueModel.setting.settingType);
615
+ }))
616
+ : this.formBuilder.array([]), rolloutRules: settingValueModel.rolloutRules
617
+ ? this.formBuilder.array(settingValueModel.rolloutRules.map(function (r) {
618
+ // @ts-ignore()
619
+ return _this.createRolloutRuleFormGroup(r, readOnly, settingValueModel.setting.settingType);
620
+ }))
621
+ : this.formBuilder.array([]),
622
+ updatedAt: [{ value: settingValueModel.updatedAt, disabled: true }],
623
+ lastUpdaterUserEmail: [{ value: settingValueModel.lastUpdaterUserEmail, disabled: true }],
624
+ lastUpdaterUserFullName: [{ value: settingValueModel.lastUpdaterUserFullName, disabled: true }],
625
+ rolloutPercentageItemsSum: [{ value: 100, disabled: false }, [i2.Validators.min(100), i2.Validators.max(100)]],
626
+ // Decoration
627
+ setting: this.formBuilder.group({
628
+ settingId: [{ value: settingValueModel.setting.settingId, disabled: true }],
629
+ key: [{ value: settingValueModel.setting.key, disabled: true }],
630
+ name: [{ value: settingValueModel.setting.name, disabled: true }],
631
+ hint: [{ value: settingValueModel.setting.hint, disabled: true }],
632
+ settingType: [{ value: settingValueModel.setting.settingType, disabled: true }],
633
+ creatorEmail: [{ value: settingValueModel.setting.creatorEmail, disabled: true }],
634
+ creatorFullName: [{ value: settingValueModel.setting.creatorFullName, disabled: true }],
635
+ createdAt: [{ value: settingValueModel.setting.createdAt, disabled: true }]
636
+ }),
637
+ integrationLinks: settingValueModel.integrationLinks ? this.formBuilder.array(settingValueModel.integrationLinks.map(function (il) {
638
+ return _this.formBuilder.group({
639
+ key: [{ value: il.key, disabled: true }],
640
+ description: [{ value: il.description, disabled: true }],
641
+ integrationLinkType: [{ value: il.integrationLinkType, disabled: true }],
642
+ url: [{ value: il.url, disabled: true }],
643
+ });
644
+ })) : this.formBuilder.array([])
645
+ });
646
+ };
647
+ SettingListFormHelper.prototype.createRolloutPercentageItemFormGroup = function (p, readOnly, settingType) {
648
+ return this.formBuilder.group({
649
+ percentage: [{ value: p.percentage, disabled: readOnly }, [i2.Validators.required, i2.Validators.min(0), i2.Validators.max(100)]],
650
+ value: [
651
+ { value: p.value, disabled: readOnly },
652
+ this.getValidatorsForSettingType(settingType)
653
+ ],
654
+ valueDisabled: [
655
+ { value: p.value, disabled: true }, // For percentage item value
656
+ ]
657
+ });
658
+ };
659
+ SettingListFormHelper.prototype.createRolloutRuleFormGroup = function (r, readOnly, settingType) {
660
+ return this.formBuilder.group({
661
+ comparisonAttribute: [{ value: r.comparisonAttribute, disabled: readOnly }, [i2.Validators.required]],
662
+ comparator: [{ value: r.comparator, disabled: readOnly }, [i2.Validators.required]],
663
+ comparisonValue: [{ value: r.comparisonValue, disabled: readOnly }, [i2.Validators.required]],
664
+ value: [
665
+ { value: r.value, disabled: readOnly },
666
+ this.getValidatorsForSettingType(settingType)
667
+ ],
668
+ });
669
+ };
670
+ SettingListFormHelper.prototype.getValidatorsForSettingType = function (settingType) {
671
+ switch (settingType) {
672
+ case ngConfigcatPublicapi.SettingType.Int:
673
+ return [i2.Validators.required,
674
+ i2.Validators.min(-2147483648), i2.Validators.max(2147483647), i2.Validators.pattern('^[-+]?[0-9]\\d*$')];
675
+ case ngConfigcatPublicapi.SettingType.Double:
676
+ return [i2.Validators.required, i2.Validators.min(-1.79769313486232E+308), i2.Validators.max(1.79769313486232E+308)];
677
+ case ngConfigcatPublicapi.SettingType.String:
678
+ case ngConfigcatPublicapi.SettingType.Boolean:
679
+ return [i2.Validators.required];
680
+ default:
681
+ return [];
682
+ }
683
+ };
684
+ SettingListFormHelper.prototype.getAllRolloutRules = function (formGroup) {
685
+ var settingValues = formGroup.get('settingValues');
686
+ var rolloutRules = settingValues.controls.map(function (cv) { return cv.get('rolloutRules').value; });
687
+ return rolloutRules.length === 0 ? rolloutRules : rolloutRules.reduce(function (a, b) { return a.concat(b); });
688
+ };
689
+ SettingListFormHelper.prototype.getComparisonAttributes = function (rolloutRules) {
690
+ if (rolloutRules.length > 0) {
691
+ var currentComparisonAttributes = rolloutRules.map(function (r) { return r.comparisonAttribute; });
692
+ var defaultComparisonAttributes_1 = ['Identifier', 'Email', 'Country'];
693
+ var comparisonAttributes = currentComparisonAttributes.filter(function (c) { return defaultComparisonAttributes_1.indexOf(c) === -1; });
694
+ return Array.from(new Set(comparisonAttributes));
695
+ }
696
+ else {
697
+ return [];
698
+ }
699
+ };
700
+ return SettingListFormHelper;
701
+ }());
702
+ SettingListFormHelper.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: SettingListFormHelper, deps: [{ token: i2__namespace.FormBuilder }], target: i0__namespace.ɵɵFactoryTarget.Injectable });
703
+ SettingListFormHelper.ɵprov = i0__namespace.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: SettingListFormHelper, providedIn: 'root' });
704
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: SettingListFormHelper, decorators: [{
705
+ type: i0.Injectable,
706
+ args: [{ providedIn: 'root' }]
707
+ }], ctorParameters: function () { return [{ type: i2__namespace.FormBuilder }]; } });
708
+
709
+ var ExpandDialogComponent = /** @class */ (function () {
710
+ function ExpandDialogComponent(dialogRef, formBuilder, data) {
711
+ this.dialogRef = dialogRef;
712
+ this.formBuilder = formBuilder;
713
+ this.data = data;
714
+ }
715
+ ExpandDialogComponent.prototype.ngOnInit = function () {
716
+ var _this = this;
717
+ if (this.data.multiline) {
718
+ this.buildFormGroup();
719
+ }
720
+ else {
721
+ this.formControlSubscription = this.data.control.valueChanges.subscribe(function (value) {
851
722
  _this.data.control.setValue(value, { onlySelf: true, emitEvent: false, emitModelToViewChange: true });
852
723
  _this.data.control.markAsDirty();
853
- }, function (error) { }, function () { });
724
+ }, function () { }, function () { });
854
725
  }
855
726
  };
856
727
  ExpandDialogComponent.prototype.values = function () {
857
728
  return this.formGroup.get('values');
858
729
  };
730
+ ExpandDialogComponent.prototype.getValueControls = function () {
731
+ return this.values().controls.map(function (c) { return c; });
732
+ };
859
733
  ExpandDialogComponent.prototype.buildFormGroup = function () {
860
734
  var _this = this;
861
735
  var value = this.data.control.value ? this.data.control.value : '';
@@ -892,139 +766,57 @@
892
766
  };
893
767
  return ExpandDialogComponent;
894
768
  }());
895
- ExpandDialogComponent.decorators = [
896
- { type: i0.Component, args: [{
897
- selector: 'configcat-expand-dialog',
898
- 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 values().controls; let i = index;\" 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-raised-button color=\"primary\" (click)=\"close()\">Done</button>\n</div>",
899
- 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"]
900
- },] }
901
- ];
902
- ExpandDialogComponent.ctorParameters = function () { return [
903
- { type: dialog.MatDialogRef },
904
- { type: i1$1.FormBuilder },
905
- { type: undefined, decorators: [{ type: i0.Inject, args: [dialog.MAT_DIALOG_DATA,] }] }
906
- ]; };
907
-
908
- var ReasonDialogComponent = /** @class */ (function () {
909
- function ReasonDialogComponent(dialogRef, formBuilder) {
910
- this.dialogRef = dialogRef;
911
- this.formBuilder = formBuilder;
912
- }
913
- ReasonDialogComponent.prototype.ngOnInit = function () {
914
- this.formGroup = this.formBuilder.group({
915
- reason: ['', [i1$1.Validators.required, i1$1.Validators.maxLength(1000)]]
916
- });
917
- };
918
- ReasonDialogComponent.prototype.handleSaveButton = function () {
919
- if (!this.formGroup.valid) {
920
- return;
921
- }
922
- this.dialogRef.close({ button: 'save', reason: this.formGroup.controls.reason.value });
923
- };
924
- ReasonDialogComponent.prototype.cancel = function () {
925
- this.dialogRef.close({ button: 'cancel' });
926
- };
927
- return ReasonDialogComponent;
928
- }());
929
- ReasonDialogComponent.decorators = [
930
- { type: i0.Component, args: [{
931
- selector: 'configcat-reason-dialog',
932
- 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-raised-button color=\"primary\">Add notes & Save</button>\n <button type=\"button\" mat-raised-button (click)=\"cancel()\">Cancel</button>\n </div>\n</form>",
933
- styles: [".container>*{width:100%}\n"]
934
- },] }
935
- ];
936
- ReasonDialogComponent.ctorParameters = function () { return [
937
- { type: dialog.MatDialogRef },
938
- { type: i1$1.FormBuilder }
939
- ]; };
940
-
941
- var SaveSnackbarComponent = /** @class */ (function () {
942
- function SaveSnackbarComponent() {
943
- }
944
- SaveSnackbarComponent.prototype.ngOnInit = function () {
945
- };
946
- return SaveSnackbarComponent;
947
- }());
948
- SaveSnackbarComponent.decorators = [
949
- { type: i0.Component, args: [{
950
- selector: 'configcat-save-snackbar',
951
- template: "<p class=\"header\">Settings saved successfully.</p>",
952
- styles: ["p{text-align:center;font-weight:bold}.header{font-size:1.2em}\n"]
953
- },] }
954
- ];
955
- SaveSnackbarComponent.ctorParameters = function () { return []; };
769
+ ExpandDialogComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: ExpandDialogComponent, deps: [{ token: i1__namespace$1.MatDialogRef }, { token: i2__namespace.FormBuilder }, { token: i1$1.MAT_DIALOG_DATA }], target: i0__namespace.ɵɵFactoryTarget.Component });
770
+ ExpandDialogComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: ExpandDialogComponent, selector: "configcat-expand-dialog", ngImport: i0__namespace, 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-raised-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"], components: [{ type: i3__namespace.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i4__namespace.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"] }, { type: i2__namespace$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i1__namespace$1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i5__namespace$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.MatLabel, selector: "mat-label" }, { type: i5__namespace.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["id", "disabled", "required", "type", "value", "readonly", "placeholder", "errorStateMatcher", "aria-describedby"], exportAs: ["matInput"] }, { type: i2__namespace.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2__namespace.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2__namespace.FormControlDirective, selector: "[formControl]", inputs: ["disabled", "formControl", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i2__namespace.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2__namespace.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5__namespace$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1__namespace$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }] });
771
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: ExpandDialogComponent, decorators: [{
772
+ type: i0.Component,
773
+ args: [{
774
+ selector: 'configcat-expand-dialog',
775
+ templateUrl: './expand-dialog.component.html',
776
+ styleUrls: ['./expand-dialog.component.scss']
777
+ }]
778
+ }], ctorParameters: function () {
779
+ return [{ type: i1__namespace$1.MatDialogRef }, { type: i2__namespace.FormBuilder }, { type: undefined, decorators: [{
780
+ type: i0.Inject,
781
+ args: [i1$1.MAT_DIALOG_DATA]
782
+ }] }];
783
+ } });
956
784
 
957
- var RolloutPercentageItemsComponent = /** @class */ (function () {
958
- function RolloutPercentageItemsComponent() {
785
+ var ValueComponent = /** @class */ (function () {
786
+ function ValueComponent(dialog) {
787
+ this.dialog = dialog;
959
788
  this.SettingType = ngConfigcatPublicapi.SettingType;
960
789
  }
961
- RolloutPercentageItemsComponent.prototype.setting = function () {
962
- return this.formGroup.get('setting').value;
963
- };
964
- RolloutPercentageItemsComponent.prototype.rolloutRules = function () {
965
- return this.formGroup.get('rolloutRules');
966
- };
967
- RolloutPercentageItemsComponent.prototype.rolloutPercentageItems = function () {
968
- return this.formGroup.get('rolloutPercentageItems');
969
- };
970
- RolloutPercentageItemsComponent.prototype.rolloutPercentageItemsSum = function () {
971
- return this.formGroup.get('rolloutPercentageItemsSum');
972
- };
973
- RolloutPercentageItemsComponent.prototype.value = function (rolloutPercentageItem) {
974
- return this.setting().settingType === ngConfigcatPublicapi.SettingType.Boolean ?
975
- rolloutPercentageItem.get('valueDisabled') :
976
- rolloutPercentageItem.get('value');
977
- };
978
- RolloutPercentageItemsComponent.prototype.percentageChanged = function (index) {
979
- if (this.rolloutPercentageItems().controls[index].value.percentage < 0) {
980
- this.rolloutPercentageItems().controls[index].controls.percentage.setValue(0);
981
- }
982
- if (this.rolloutPercentageItems().controls[index].value.percentage > 100) {
983
- this.rolloutPercentageItems().controls[index].controls.percentage.setValue(100);
984
- }
985
- if (this.rolloutPercentageItems().controls.length === 2) {
986
- this.rolloutPercentageItems().controls[1 - index].controls.percentage
987
- .setValue(100 - this.rolloutPercentageItems().controls[index].value.percentage);
988
- }
989
- this.updateSum();
990
- };
991
- RolloutPercentageItemsComponent.prototype.updateSum = function () {
992
- if (this.rolloutPercentageItems().controls.length === 0) {
993
- this.rolloutPercentageItemsSum().setValue(100);
994
- }
995
- else {
996
- this.rolloutPercentageItemsSum().setValue(this.rolloutPercentageItems().controls.map(function (v) { return v.value.percentage; })
997
- .reduce(function (a, b) { return a + b; }));
998
- }
999
- };
1000
- RolloutPercentageItemsComponent.prototype.removeRolloutPercentageItem = function (index) {
1001
- this.rolloutPercentageItems().removeAt(index);
1002
- this.rolloutPercentageItems().markAsDirty();
1003
- this.updateSum();
1004
- };
1005
- RolloutPercentageItemsComponent.prototype.removeAll = function () {
1006
- this.rolloutPercentageItems().clear();
1007
- this.rolloutPercentageItems().markAsDirty();
1008
- this.updateSum();
790
+ ValueComponent.prototype.popOut = function () {
791
+ this.dialog.open(ExpandDialogComponent, {
792
+ width: '640px',
793
+ data: { control: this.valueFormControl }
794
+ });
1009
795
  };
1010
- return RolloutPercentageItemsComponent;
796
+ return ValueComponent;
1011
797
  }());
1012
- RolloutPercentageItemsComponent.decorators = [
1013
- { type: i0.Component, args: [{
1014
- selector: 'configcat-rollout-percentage-items',
1015
- 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 rolloutPercentageItems().controls; let i = index\">\n <div class=\"flex\">\n <input type=\"number\" [formControl]=\"rolloutPercentageItem.controls.percentage\"\n (input)=\"percentageChanged(i)\">%\n <span class=\"users\">of <a href=\"https://configcat.com/docs/advanced/user-object\"\n target=\"_blank\" 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 data-tooltip=\"The sum of percentages must be equal to 100.\"\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)\" [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>",
1016
- styles: [".percentage-wrapper{border:1px solid #d5d5d5;background-color:#fff;border-radius:4px;margin:.5em 1em;position:relative;padding:.5em 0;display:flex}.percentage-wrapper .delete{position:absolute;color:#d6a9a9;cursor:pointer;top:-8px;right:-12px}.percentage-wrapper .delete:hover{color:#ed5251}.percentage-wrapper .delete mat-icon{font-size:20px}.percentage-wrapper .delete-option{color:#d6a9a9;cursor:pointer;margin-left:1rem;margin-top:4px}.percentage-wrapper .delete-option:hover{color:#ed5251}.percentage-wrapper .delete-option mat-icon{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;min-width:100px}.value .value-name{display:none}input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;width:40px;margin-right:5px;font-size:15px;padding:0 5px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300}.users{margin-left:20px}@media (max-width: 700px){.percentage-wrapper{margin:.5em .3em}}\n"]
1017
- },] }
1018
- ];
1019
- RolloutPercentageItemsComponent.ctorParameters = function () { return []; };
1020
- RolloutPercentageItemsComponent.propDecorators = {
1021
- formGroup: [{ type: i0.Input }],
1022
- readOnly: [{ type: i0.Input }]
1023
- };
798
+ ValueComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: ValueComponent, deps: [{ token: i1__namespace$1.MatDialog }], target: i0__namespace.ɵɵFactoryTarget.Component });
799
+ ValueComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: ValueComponent, selector: "configcat-value", inputs: { valueFormControl: "valueFormControl", setting: "setting" }, ngImport: i0__namespace, 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:20px;align-items:center}.flex .spacer{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;font-size:15px;padding:0 30px 0 10px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300;min-width:170px}.flex .container .invalid{border:1px solid #ff5252}.flex .container .error{color:#ff5252;margin-right:5px}@media (max-width: 1200px){.flex .container input{min-width:auto}}.flex .variationId{margin-left: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)}\n"], components: [{ type: i2__namespace$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i5__namespace$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i5__namespace$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i5__namespace$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2__namespace.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i5__namespace$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2__namespace.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2__namespace.FormControlDirective, selector: "[formControl]", inputs: ["disabled", "formControl", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i5__namespace$2.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i2__namespace.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i2__namespace.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }] });
800
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: ValueComponent, decorators: [{
801
+ type: i0.Component,
802
+ args: [{
803
+ selector: 'configcat-value',
804
+ templateUrl: './value.component.html',
805
+ styleUrls: [
806
+ './slider.scss',
807
+ './value.component.scss'
808
+ ]
809
+ }]
810
+ }], ctorParameters: function () { return [{ type: i1__namespace$1.MatDialog }]; }, propDecorators: { valueFormControl: [{
811
+ type: i0.Input
812
+ }], setting: [{
813
+ type: i0.Input
814
+ }] } });
1024
815
 
1025
816
  var RolloutRulesComponent = /** @class */ (function () {
1026
817
  function RolloutRulesComponent(dialog) {
1027
818
  this.dialog = dialog;
819
+ this.readOnly = false;
1028
820
  this.SettingType = ngConfigcatPublicapi.SettingType;
1029
821
  this.defaultComparisonAttributes = ['Identifier', 'Email', 'Country'];
1030
822
  this.rolloutRuleComparators = [
@@ -1049,16 +841,19 @@
1049
841
  ];
1050
842
  }
1051
843
  RolloutRulesComponent.prototype.onlyFirstTooltip = function () {
1052
- return this.formGroup.root.get('allRolloutRulesCount').value > 20 || this.rolloutRules().controls.length > 10;
844
+ var _a;
845
+ return ((_a = this.formGroup.root.get('allRolloutRulesCount')) === null || _a === void 0 ? void 0 : _a.value) > 20 || this.rolloutRules().controls.length > 10;
1053
846
  };
1054
847
  RolloutRulesComponent.prototype.setting = function () {
1055
- return this.formGroup.get('setting').value;
848
+ var _a;
849
+ return (_a = this.formGroup.get('setting')) === null || _a === void 0 ? void 0 : _a.value;
1056
850
  };
1057
851
  RolloutRulesComponent.prototype.rolloutRules = function () {
1058
852
  return this.formGroup.get('rolloutRules');
1059
853
  };
1060
854
  RolloutRulesComponent.prototype.comparisonAttributes = function () {
1061
- return this.formGroup.root.get('comparisonAttributes').value;
855
+ var _a;
856
+ return (_a = this.formGroup.root.get('comparisonAttributes')) === null || _a === void 0 ? void 0 : _a.value;
1062
857
  };
1063
858
  RolloutRulesComponent.prototype.removeRule = function (index) {
1064
859
  this.rolloutRules().removeAt(index);
@@ -1066,13 +861,13 @@
1066
861
  };
1067
862
  RolloutRulesComponent.prototype.onDrop = function (event) {
1068
863
  var rolloutRules = this.rolloutRules().controls;
1069
- dragDrop.moveItemInArray(rolloutRules, event.previousIndex, event.currentIndex);
864
+ i8.moveItemInArray(rolloutRules, event.previousIndex, event.currentIndex);
1070
865
  this.formGroup.markAsDirty();
1071
866
  };
1072
867
  RolloutRulesComponent.prototype.attributeChanged = function (event, comparisonAttribute) {
1073
- if (this.defaultComparisonAttributes.indexOf(event) !== -1) {
1074
- if (comparisonAttribute.value !== event) {
1075
- comparisonAttribute.setValue(event);
868
+ if (this.defaultComparisonAttributes.indexOf(event.value) !== -1) {
869
+ if (comparisonAttribute.value !== event.value) {
870
+ comparisonAttribute.setValue(event.value);
1076
871
  this.formGroup.markAsDirty();
1077
872
  }
1078
873
  }
@@ -1182,17 +977,17 @@
1182
977
  case ngConfigcatPublicapi.RolloutRuleComparator.SensitiveIsNotOneOf:
1183
978
  case ngConfigcatPublicapi.RolloutRuleComparator.Contains:
1184
979
  case ngConfigcatPublicapi.RolloutRuleComparator.DoesNotContain:
1185
- validators = [i1$1.Validators.required, i1$1.Validators.maxLength(65535)];
980
+ validators = [i2.Validators.required, i2.Validators.maxLength(65535)];
1186
981
  break;
1187
982
  case ngConfigcatPublicapi.RolloutRuleComparator.SemVerIsOneOf:
1188
983
  case ngConfigcatPublicapi.RolloutRuleComparator.SemVerIsNotOneOf:
1189
- validators = [i1$1.Validators.required, this.validateSemVerList];
984
+ validators = [i2.Validators.required, this.validateSemVerList];
1190
985
  break;
1191
986
  case ngConfigcatPublicapi.RolloutRuleComparator.SemVerLessOrEquals:
1192
987
  case ngConfigcatPublicapi.RolloutRuleComparator.SemVerLess:
1193
988
  case ngConfigcatPublicapi.RolloutRuleComparator.SemVerGreater:
1194
989
  case ngConfigcatPublicapi.RolloutRuleComparator.SemVerGreaterOrEquals:
1195
- validators = [i1$1.Validators.required, this.validateSemVer];
990
+ validators = [i2.Validators.required, this.validateSemVer];
1196
991
  break;
1197
992
  case ngConfigcatPublicapi.RolloutRuleComparator.NumberEquals:
1198
993
  case ngConfigcatPublicapi.RolloutRuleComparator.NumberDoesNotEqual:
@@ -1200,7 +995,7 @@
1200
995
  case ngConfigcatPublicapi.RolloutRuleComparator.NumberLessOrEquals:
1201
996
  case ngConfigcatPublicapi.RolloutRuleComparator.NumberGreater:
1202
997
  case ngConfigcatPublicapi.RolloutRuleComparator.NumberGreaterOrEquals:
1203
- validators = [i1$1.Validators.required, i1$1.Validators.min(-1.79769313486232E+308), i1$1.Validators.max(1.79769313486232E+308)];
998
+ validators = [i2.Validators.required, i2.Validators.min(-1.79769313486232E+308), i2.Validators.max(1.79769313486232E+308)];
1204
999
  break;
1205
1000
  }
1206
1001
  rolloutRule.controls.comparisonValue.setValidators(validators);
@@ -1220,7 +1015,7 @@
1220
1015
  }
1221
1016
  };
1222
1017
  RolloutRulesComponent.prototype.validateSemVer = function (c) {
1223
- if (semver__namespace.valid(c.value) === null) {
1018
+ if (semver.valid(c.value) === null) {
1224
1019
  return {
1225
1020
  validateSemVer: {
1226
1021
  valid: false
@@ -1238,7 +1033,7 @@
1238
1033
  };
1239
1034
  }
1240
1035
  var semvers = c.value.split(',').map(function (s) { return s.trim(); });
1241
- if (semvers.find(function (s) { return s && s !== '' && semver__namespace.valid(s) === null; })) {
1036
+ if (semvers.find(function (s) { return s && s !== '' && semver.valid(s) === null; })) {
1242
1037
  return {
1243
1038
  validateSemVerList: {
1244
1039
  valid: false
@@ -1259,182 +1054,241 @@
1259
1054
  RolloutRulesComponent.prototype.trackByIndex = function (index) {
1260
1055
  return index;
1261
1056
  };
1057
+ RolloutRulesComponent.prototype.getRolloutRuleValueFormControl = function (rolloutRule) {
1058
+ return rolloutRule.controls.value;
1059
+ };
1060
+ RolloutRulesComponent.prototype.getRolloutRuleComparisonValueFormControl = function (rolloutRule) {
1061
+ return rolloutRule.controls.comparisonValue;
1062
+ };
1063
+ RolloutRulesComponent.prototype.getRolloutRuleComparisonAttributeFormControl = function (rolloutRule) {
1064
+ return rolloutRule.controls.comparisonAttribute;
1065
+ };
1066
+ RolloutRulesComponent.prototype.getRolloutRuleComparatorFormControl = function (rolloutRule) {
1067
+ return rolloutRule.controls.comparator;
1068
+ };
1262
1069
  return RolloutRulesComponent;
1263
1070
  }());
1264
- RolloutRulesComponent.decorators = [
1265
- { type: i0.Component, args: [{
1266
- selector: 'configcat-rollout-rules',
1267
- 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\">\n <div class=\"drag-handle\" cdkDragHandle data-tooltip=\"Drag here to reorder\" *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\" rel=\"noopener noreferrer\">user's</a>\n </div>\n\n <select class=\"custom-select attribute-select\" matTooltip=\"Comparison attribute\"\n matTooltipPosition=\"above\" [matTooltipDisabled]=\"onlyFirstTooltip() && i !== 0\"\n (change)=\"attributeChanged($event.target.value, rolloutRule.controls.comparisonAttribute)\">\n <option *ngFor=\"let comparisonAttribute of defaultComparisonAttributes\"\n [selected]=\"comparisonAttribute === rolloutRule.controls.comparisonAttribute.value\">\n {{comparisonAttribute}}</option>\n <option\n [selected]=\"defaultComparisonAttributes.indexOf(rolloutRule.controls.comparisonAttribute.value) === -1\">\n Custom\n </option>\n </select>\n\n\n <span class=\"attribute-span\" data-tooltip=\"Custom user attribute\"\n [hidden]=\"defaultComparisonAttributes.indexOf(rolloutRule.controls.comparisonAttribute.value) !== -1\">\n <span class=\"attribute-error\" *ngIf=\"rolloutRule.controls.comparisonAttribute.invalid\">*</span>\n <input [ngClass]=\"{'invalid': rolloutRule.controls.comparisonAttribute.invalid}\" type=\"text\"\n matInput [matAutocomplete]=\"auto\" [formControl]=\"rolloutRule.controls.comparisonAttribute\"\n class=\"attribute\" 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]=\"rolloutRule.controls.comparator\"\n matTooltip=\"Comparator\" matTooltipPosition=\"above\"\n [matTooltipDisabled]=\"onlyFirstTooltip() && i !== 0\"\n (change)=\"comparatorChanged(rolloutRule)\">\n <optgroup label=\"SENSITIVE 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 [matTooltipDisabled]=\"onlyFirstTooltip() && i !== 0\">\n <a href=\"https://configcat.com/docs/advanced/targeting/#comparator\" target=\"_blank\" rel=\"noopener noreferrer\">\n <mat-icon>info</mat-icon>\n </a>\n </div>\n </div>\n\n <div class=\"comparison-value\" data-tooltip=\"Comparison value\">\n <span class=\"error\" *ngIf=\"rolloutRule.controls.comparisonValue.invalid\">*</span>\n\n <input [ngClass]=\"{'invalid': rolloutRule.controls.comparisonValue.invalid}\"\n [formControl]=\"rolloutRule.controls.comparisonValue\"\n [type]=\"getComparisonValueType(rolloutRule)\" [placeholder]=\"getPlaceHolder(rolloutRule)\">\n <div class=\"expand\" matTooltip=\"Pop-out Editor\" (click)=\"popOut(rolloutRule)\" *ngIf=\"getComparisonValueType(rolloutRule)==='text'\">\n <mat-icon>height</mat-icon>\n </div>\n </div>\n\n <div class=\"delete\" matTooltip=\"Remove targeting rule\"\n [matTooltipDisabled]=\"onlyFirstTooltip() && i !== 0\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\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\" [valueFormControl]=\"rolloutRule.controls.value\"\n [setting]=\"setting()\">\n </configcat-value>\n </div>\n </div>\n </div>\n </div>\n</div>",
1268
- 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;border-radius:4px;background-color:#fff;margin:.5em 1em;display:flex;position:relative;padding:.5em 0}.targeting-row .select-wrapper{position:relative}.targeting-row .info{position:absolute;cursor:pointer;top:-8px;left:166px}.targeting-row .info a{color:#7fb3fd}.targeting-row .info a:hover{color:#0068f0}.targeting-row .info mat-icon{font-size:18px}.targeting-row .warn{position:absolute;cursor:pointer;top:-8px;left:128px}.targeting-row .warn a{color:#fdc67f}.targeting-row .warn a:hover{color:#ff9200}.targeting-row .warn mat-icon{font-size:18px}.chip{background-color:#67b1fc3d}.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:46px}.fields .attribute-span{margin-left:.5em}.fields .attribute{width:170px;background-color:#fff;border:1px solid #e5e5e5;min-height:28px;min-width:170px;font-size:15px;padding:0 10px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300}.fields .invalid{border:1px solid #ff5252}.fields .attribute-error{color:#ff5252;margin-right:5px}.fields .delete{position:absolute;color:#d6a9a9;cursor:pointer;top:-8px;right:-12px;z-index:999}.fields .delete:hover{color:#ed5251}.fields .delete mat-icon{font-size:20px}.fields .drag-handle{position:absolute;cursor:-webkit-grab;cursor:-moz-grab;left:-20px;top:14px}.fields .drag-handle mat-icon{font-size:20px}.fields .custom-select{margin-left:.5em;width:170px;background-color:#fff;border:1px solid #e5e5e5;min-height:30px;min-width:170px;font-size:.8em;padding:0 5px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300}.fields .attribute-select{min-width:100px;width:100px;margin-left:0}.fields .comparison-value{flex-grow:100;min-width:200px;display:flex;align-items:center;margin-left:.5em}.fields .comparison-value .error{color:#ff5252;margin:0 5px}.fields .comparison-value input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;min-width:170px;flex-grow:100;font-size:15px;padding:0 30px 0 10px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300}.fields .comparison-value .invalid{border:1px solid #ff5252}.value{margin-left:auto;flex-wrap:nowrap}.value .serve{margin:0 5px}.warn{padding-left:3em;font-size:.8em}.flex{display:flex;flex-wrap:wrap;align-items:center}.expand{position:absolute;right:2px;font-size:8px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.expand mat-icon{transform:rotate(45deg)}@media (max-width: 1200px){.targeting-row{flex-wrap:wrap}.targeting-row .fields{max-width:500px}}@media (max-width: 700px){.targeting-row{flex-direction:column;margin:.5em .3em}.targeting-row .help{left:161px}.targeting-row .fields{flex-direction:column;align-items:stretch}.targeting-row .fields .custom-select{margin:0}.targeting-row .fields .comparison-value{margin:0}}\n"]
1269
- },] }
1270
- ];
1271
- RolloutRulesComponent.ctorParameters = function () { return [
1272
- { type: dialog.MatDialog }
1273
- ]; };
1274
- RolloutRulesComponent.propDecorators = {
1275
- formGroup: [{ type: i0.Input }],
1276
- readOnly: [{ type: i0.Input }]
1277
- };
1071
+ RolloutRulesComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: RolloutRulesComponent, deps: [{ token: i1__namespace$1.MatDialog }], target: i0__namespace.ɵɵFactoryTarget.Component });
1072
+ RolloutRulesComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: RolloutRulesComponent, selector: "configcat-rollout-rules", inputs: { formGroup: "formGroup", readOnly: "readOnly" }, ngImport: i0__namespace, 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\">\n <div class=\"drag-handle\" cdkDragHandle data-tooltip=\"Drag here to reorder\" *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\" [matTooltipDisabled]=\"onlyFirstTooltip() && i !== 0\"\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\" data-tooltip=\"Custom user attribute\"\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 [matTooltipDisabled]=\"onlyFirstTooltip() && i !== 0\"\n (change)=\"comparatorChanged(rolloutRule)\">\n <optgroup label=\"SENSITIVE 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 [matTooltipDisabled]=\"onlyFirstTooltip() && i !== 0\">\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\" data-tooltip=\"Comparison value\">\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\"\n [matTooltipDisabled]=\"onlyFirstTooltip() && i !== 0\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\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;border-radius:4px;background-color:#fff;margin:.5em 1em;display:flex;position:relative;padding:.5em 0}.targeting-row .select-wrapper{position:relative}.targeting-row .info{position:absolute;cursor:pointer;top:-8px;left:166px}.targeting-row .info a{color:#7fb3fd}.targeting-row .info a:hover{color:#0068f0}.targeting-row .info mat-icon{font-size:18px}.targeting-row .warn{position:absolute;cursor:pointer;top:-8px;left:128px}.targeting-row .warn a{color:#fdc67f}.targeting-row .warn a:hover{color:#ff9200}.targeting-row .warn mat-icon{font-size:18px}.chip{background-color:#67b1fc3d}.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:46px}.fields .attribute-span{margin-left:.5em}.fields .attribute{width:170px;background-color:#fff;border:1px solid #e5e5e5;min-height:28px;min-width:170px;font-size:15px;padding:0 10px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300}.fields .invalid{border:1px solid #ff5252}.fields .attribute-error{color:#ff5252;margin-right:5px}.fields .delete{position:absolute;color:#d6a9a9;cursor:pointer;top:-8px;right:-12px;z-index:999}.fields .delete:hover{color:#ed5251}.fields .delete mat-icon{font-size:20px}.fields .drag-handle{position:absolute;cursor:-moz-grab;left:-20px;top:14px}.fields .drag-handle mat-icon{font-size:20px}.fields .custom-select{margin-left:.5em;width:170px;background-color:#fff;border:1px solid #e5e5e5;min-height:30px;min-width:170px;font-size:.8em;padding:0 5px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300}.fields .attribute-select{min-width:100px;width:100px;margin-left:0}.fields .comparison-value{flex-grow:100;min-width:200px;display:flex;align-items:center;margin-left:.5em}.fields .comparison-value .error{color:#ff5252;margin:0 5px}.fields .comparison-value input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;min-width:170px;flex-grow:100;font-size:15px;padding:0 30px 0 10px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300}.fields .comparison-value .invalid{border:1px solid #ff5252}.value{margin-left:auto;flex-wrap:nowrap}.value .serve{margin:0 5px}.warn{padding-left:3em;font-size:.8em}.flex{display:flex;flex-wrap:wrap;align-items:center}.expand{position:absolute;right:2px;font-size:8px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.expand mat-icon{transform:rotate(45deg)}@media (max-width: 1200px){.targeting-row{flex-wrap:wrap}.targeting-row .fields{max-width:500px}}@media (max-width: 700px){.targeting-row{flex-direction:column;margin:.5em .3em}.targeting-row .help{left:161px}.targeting-row .fields{flex-direction:column;align-items:stretch}.targeting-row .fields .custom-select{margin:0}.targeting-row .fields .comparison-value{margin:0}}\n"], components: [{ type: i2__namespace$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i3__namespace$2.MatChipList, selector: "mat-chip-list", inputs: ["aria-orientation", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "selectable", "tabIndex", "errorStateMatcher"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { type: i4__namespace$1.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { type: i4__namespace$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: ValueComponent, selector: "configcat-value", inputs: ["valueFormControl", "setting"] }], directives: [{ type: i2__namespace.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2__namespace.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i8__namespace.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "id", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListAutoScrollDisabled", "cdkDropListOrientation", "cdkDropListLockAxis", "cdkDropListData", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { type: i5__namespace$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i8__namespace.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragDisabled", "cdkDragStartDelay", "cdkDragLockAxis", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragBoundary", "cdkDragRootElement", "cdkDragPreviewContainer", "cdkDragData", "cdkDragFreeDragPosition"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { type: i5__namespace$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8__namespace.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { type: i3__namespace$2.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { type: i5__namespace$2.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i2__namespace.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i2__namespace.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i5__namespace.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["id", "disabled", "required", "type", "value", "readonly", "placeholder", "errorStateMatcher", "aria-describedby"], exportAs: ["matInput"] }, { type: i4__namespace$1.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { type: i2__namespace.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i5__namespace$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2__namespace.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2__namespace.FormControlDirective, selector: "[formControl]", inputs: ["disabled", "formControl", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i2__namespace.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }] });
1073
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: RolloutRulesComponent, decorators: [{
1074
+ type: i0.Component,
1075
+ args: [{
1076
+ selector: 'configcat-rollout-rules',
1077
+ templateUrl: './rollout-rules.component.html',
1078
+ styleUrls: ['./rollout-rules.component.scss']
1079
+ }]
1080
+ }], ctorParameters: function () { return [{ type: i1__namespace$1.MatDialog }]; }, propDecorators: { formGroup: [{
1081
+ type: i0.Input
1082
+ }], readOnly: [{
1083
+ type: i0.Input
1084
+ }] } });
1278
1085
 
1279
- var ValueComponent = /** @class */ (function () {
1280
- function ValueComponent(dialog) {
1281
- this.dialog = dialog;
1086
+ var RolloutPercentageItemsComponent = /** @class */ (function () {
1087
+ function RolloutPercentageItemsComponent() {
1088
+ this.readOnly = false;
1282
1089
  this.SettingType = ngConfigcatPublicapi.SettingType;
1283
1090
  }
1284
- ValueComponent.prototype.popOut = function () {
1285
- this.dialog.open(ExpandDialogComponent, {
1286
- width: '640px',
1287
- data: { control: this.valueFormControl }
1288
- });
1091
+ RolloutPercentageItemsComponent.prototype.setting = function () {
1092
+ var _a;
1093
+ return (_a = this.formGroup.get('setting')) === null || _a === void 0 ? void 0 : _a.value;
1289
1094
  };
1290
- return ValueComponent;
1291
- }());
1292
- ValueComponent.decorators = [
1293
- { type: i0.Component, args: [{
1294
- selector: 'configcat-value',
1295
- 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",
1296
- 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:20px;align-items:center}.flex .spacer{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;font-size:15px;padding:0 30px 0 10px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300;min-width:170px}.flex .container .invalid{border:1px solid #ff5252}.flex .container .error{color:#ff5252;margin-right:5px}@media (max-width: 1200px){.flex .container input{min-width:auto}}.flex .variationId{margin-left: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)}\n"]
1297
- },] }
1298
- ];
1299
- ValueComponent.ctorParameters = function () { return [
1300
- { type: dialog.MatDialog }
1301
- ]; };
1302
- ValueComponent.propDecorators = {
1303
- valueFormControl: [{ type: i0.Input }],
1304
- setting: [{ type: i0.Input }]
1305
- };
1306
-
1307
- var SettingListFormHelper = /** @class */ (function () {
1308
- function SettingListFormHelper(formBuilder) {
1309
- this.formBuilder = formBuilder;
1310
- }
1311
- SettingListFormHelper.prototype.createSettingValuesFormGroup = function (settingValuesModel) {
1312
- var _this = this;
1313
- var formGroup = this.formBuilder.group({
1314
- settingValues: this.formBuilder.array(settingValuesModel.settingValues.map(function (sv) {
1315
- return _this.createSettingValueFormGroup(sv, settingValuesModel.readOnly);
1316
- })),
1317
- // Decorator
1318
- environment: this.formBuilder.group({
1319
- environmentId: [{ value: settingValuesModel.environment.environmentId, disabled: true }],
1320
- name: [{ value: settingValuesModel.environment.name, disabled: true }],
1321
- }),
1322
- comparisonAttributes: [[]],
1323
- allRolloutRulesCount: [0]
1324
- });
1325
- var rolloutRules = this.getAllRolloutRules(formGroup);
1326
- var comparisonAttributes = this.getComparisonAttributes(rolloutRules);
1327
- formGroup.patchValue({ allRolloutRulesCount: rolloutRules.length });
1328
- formGroup.patchValue({ comparisonAttributes: comparisonAttributes });
1329
- return formGroup;
1095
+ RolloutPercentageItemsComponent.prototype.rolloutRules = function () {
1096
+ return this.formGroup.get('rolloutRules');
1330
1097
  };
1331
- SettingListFormHelper.prototype.createSettingValueFormGroup = function (settingValueModel, readOnly) {
1332
- var _this = this;
1333
- return this.formBuilder.group({
1334
- settingId: [settingValueModel.setting.settingId],
1335
- value: [
1336
- { value: settingValueModel.value, disabled: readOnly },
1337
- this.getValidatorsForSettingType(settingValueModel.setting.settingType)
1338
- ],
1339
- rolloutPercentageItems: this.formBuilder.array(settingValueModel.rolloutPercentageItems.map(function (p) {
1340
- return _this.createRolloutPercentageItemFormGroup(p, readOnly, settingValueModel.setting.settingType);
1341
- })),
1342
- rolloutRules: this.formBuilder.array(settingValueModel.rolloutRules.map(function (r) {
1343
- return _this.createRolloutRuleFormGroup(r, readOnly, settingValueModel.setting.settingType);
1344
- })),
1345
- updatedAt: [{ value: settingValueModel.updatedAt, disabled: true }],
1346
- lastUpdaterUserEmail: [{ value: settingValueModel.lastUpdaterUserEmail, disabled: true }],
1347
- lastUpdaterUserFullName: [{ value: settingValueModel.lastUpdaterUserFullName, disabled: true }],
1348
- rolloutPercentageItemsSum: [{ value: 100, disabled: false }, [i1$1.Validators.min(100), i1$1.Validators.max(100)]],
1349
- // Decoration
1350
- setting: this.formBuilder.group({
1351
- settingId: [{ value: settingValueModel.setting.settingId, disabled: true }],
1352
- key: [{ value: settingValueModel.setting.key, disabled: true }],
1353
- name: [{ value: settingValueModel.setting.name, disabled: true }],
1354
- hint: [{ value: settingValueModel.setting.hint, disabled: true }],
1355
- settingType: [{ value: settingValueModel.setting.settingType, disabled: true }],
1356
- creatorEmail: [{ value: settingValueModel.setting.creatorEmail, disabled: true }],
1357
- creatorFullName: [{ value: settingValueModel.setting.creatorFullName, disabled: true }],
1358
- createdAt: [{ value: settingValueModel.setting.createdAt, disabled: true }]
1359
- }),
1360
- integrationLinks: this.formBuilder.array(settingValueModel.integrationLinks.map(function (il) {
1361
- return _this.formBuilder.group({
1362
- key: [{ value: il.key, disabled: true }],
1363
- description: [{ value: il.description, disabled: true }],
1364
- integrationLinkType: [{ value: il.integrationLinkType, disabled: true }],
1365
- url: [{ value: il.url, disabled: true }],
1366
- });
1367
- }))
1368
- });
1098
+ RolloutPercentageItemsComponent.prototype.rolloutPercentageItems = function () {
1099
+ return this.formGroup.get('rolloutPercentageItems');
1369
1100
  };
1370
- SettingListFormHelper.prototype.createRolloutPercentageItemFormGroup = function (p, readOnly, settingType) {
1371
- return this.formBuilder.group({
1372
- percentage: [{ value: p.percentage, disabled: readOnly }, [i1$1.Validators.required, i1$1.Validators.min(0), i1$1.Validators.max(100)]],
1373
- value: [
1374
- { value: p.value, disabled: readOnly },
1375
- [].concat.apply([], [i1$1.Validators.required, this.getValidatorsForSettingType(settingType)])
1376
- ],
1377
- valueDisabled: [
1378
- { value: p.value, disabled: true }, // For percentage item value
1379
- ]
1380
- });
1101
+ RolloutPercentageItemsComponent.prototype.rolloutPercentageItemsSum = function () {
1102
+ return this.formGroup.get('rolloutPercentageItemsSum');
1381
1103
  };
1382
- SettingListFormHelper.prototype.createRolloutRuleFormGroup = function (r, readOnly, settingType) {
1383
- return this.formBuilder.group({
1384
- comparisonAttribute: [{ value: r.comparisonAttribute, disabled: readOnly }, [i1$1.Validators.required]],
1385
- comparator: [{ value: r.comparator, disabled: readOnly }, [i1$1.Validators.required]],
1386
- comparisonValue: [{ value: r.comparisonValue, disabled: readOnly }, [i1$1.Validators.required]],
1387
- value: [
1388
- { value: r.value, disabled: readOnly },
1389
- this.getValidatorsForSettingType(settingType)
1390
- ],
1391
- });
1104
+ RolloutPercentageItemsComponent.prototype.value = function (rolloutPercentageItem) {
1105
+ return this.setting().settingType === ngConfigcatPublicapi.SettingType.Boolean ?
1106
+ rolloutPercentageItem.get('valueDisabled') :
1107
+ rolloutPercentageItem.get('value');
1392
1108
  };
1393
- SettingListFormHelper.prototype.getValidatorsForSettingType = function (settingType) {
1394
- switch (settingType) {
1395
- case ngConfigcatPublicapi.SettingType.Int:
1396
- return [i1$1.Validators.required,
1397
- i1$1.Validators.min(-2147483648), i1$1.Validators.max(2147483647), i1$1.Validators.pattern('^[-+]?[0-9]\\d*$')];
1398
- case ngConfigcatPublicapi.SettingType.Double:
1399
- return [i1$1.Validators.required, i1$1.Validators.min(-1.79769313486232E+308), i1$1.Validators.max(1.79769313486232E+308)];
1400
- case ngConfigcatPublicapi.SettingType.String:
1401
- case ngConfigcatPublicapi.SettingType.Boolean:
1402
- return [i1$1.Validators.required];
1403
- default:
1404
- return [];
1109
+ RolloutPercentageItemsComponent.prototype.percentageChanged = function (index) {
1110
+ if (this.rolloutPercentageItems().controls[index].value.percentage < 0) {
1111
+ this.rolloutPercentageItems().controls[index].controls.percentage.setValue(0);
1405
1112
  }
1113
+ if (this.rolloutPercentageItems().controls[index].value.percentage > 100) {
1114
+ this.rolloutPercentageItems().controls[index].controls.percentage.setValue(100);
1115
+ }
1116
+ if (this.rolloutPercentageItems().controls.length === 2) {
1117
+ this.rolloutPercentageItems().controls[1 - index].controls.percentage
1118
+ .setValue(100 - this.rolloutPercentageItems().controls[index].value.percentage);
1119
+ }
1120
+ this.updateSum();
1406
1121
  };
1407
- SettingListFormHelper.prototype.getAllRolloutRules = function (formGroup) {
1408
- var settingValues = formGroup.get('settingValues');
1409
- var rolloutRules = settingValues.controls.map(function (cv) { return cv.get('rolloutRules').value; });
1410
- return rolloutRules.length === 0 ? rolloutRules : rolloutRules.reduce(function (a, b) { return a.concat(b); });
1411
- };
1412
- SettingListFormHelper.prototype.getComparisonAttributes = function (rolloutRules) {
1413
- if (rolloutRules.length > 0) {
1414
- var currentComparisonAttributes = rolloutRules.map(function (r) { return r.comparisonAttribute; });
1415
- var defaultComparisonAttributes_1 = ['Identifier', 'Email', 'Country'];
1416
- var comparisonAttributes = currentComparisonAttributes.filter(function (c) { return defaultComparisonAttributes_1.indexOf(c) === -1; });
1417
- return Array.from(new Set(comparisonAttributes));
1122
+ RolloutPercentageItemsComponent.prototype.updateSum = function () {
1123
+ if (this.rolloutPercentageItems().controls.length === 0) {
1124
+ this.rolloutPercentageItemsSum().setValue(100);
1418
1125
  }
1419
1126
  else {
1420
- return [];
1127
+ this.rolloutPercentageItemsSum().setValue(this.rolloutPercentageItems().controls.map(function (v) { return v.value.percentage; })
1128
+ .reduce(function (a, b) { return a + b; }));
1421
1129
  }
1422
1130
  };
1423
- return SettingListFormHelper;
1131
+ RolloutPercentageItemsComponent.prototype.removeRolloutPercentageItem = function (index) {
1132
+ this.rolloutPercentageItems().removeAt(index);
1133
+ this.rolloutPercentageItems().markAsDirty();
1134
+ this.updateSum();
1135
+ };
1136
+ RolloutPercentageItemsComponent.prototype.removeAll = function () {
1137
+ this.rolloutPercentageItems().clear();
1138
+ this.rolloutPercentageItems().markAsDirty();
1139
+ this.updateSum();
1140
+ };
1141
+ RolloutPercentageItemsComponent.prototype.getRolloutPercentageItemFormGroups = function () {
1142
+ var _a, _b;
1143
+ return (_b = (_a = this.rolloutPercentageItems()) === null || _a === void 0 ? void 0 : _a.controls) === null || _b === void 0 ? void 0 : _b.map(function (c) { return c; });
1144
+ };
1145
+ RolloutPercentageItemsComponent.prototype.getPercentageFormControl = function (rolloutPercentageItem) {
1146
+ return rolloutPercentageItem.controls.percentage;
1147
+ };
1148
+ return RolloutPercentageItemsComponent;
1424
1149
  }());
1425
- SettingListFormHelper.ɵprov = i0__namespace.ɵɵdefineInjectable({ factory: function SettingListFormHelper_Factory() { return new SettingListFormHelper(i0__namespace.ɵɵinject(i1__namespace$1.FormBuilder)); }, token: SettingListFormHelper, providedIn: "root" });
1426
- SettingListFormHelper.decorators = [
1427
- { type: i0.Injectable, args: [{ providedIn: 'root' },] }
1428
- ];
1429
- SettingListFormHelper.ctorParameters = function () { return [
1430
- { type: i1$1.FormBuilder }
1431
- ]; };
1150
+ RolloutPercentageItemsComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: RolloutPercentageItemsComponent, deps: [], target: i0__namespace.ɵɵFactoryTarget.Component });
1151
+ RolloutPercentageItemsComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: RolloutPercentageItemsComponent, selector: "configcat-rollout-percentage-items", inputs: { formGroup: "formGroup", readOnly: "readOnly" }, ngImport: i0__namespace, 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 data-tooltip=\"The sum of percentages must be equal to 100.\"\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;border-radius:4px;margin:.5em 1em;position:relative;padding:.5em 0;display:flex}.percentage-wrapper .delete{position:absolute;color:#d6a9a9;cursor:pointer;top:-8px;right:-12px}.percentage-wrapper .delete:hover{color:#ed5251}.percentage-wrapper .delete mat-icon{font-size:20px}.percentage-wrapper .delete-option{color:#d6a9a9;cursor:pointer;margin-left:1rem;margin-top:4px}.percentage-wrapper .delete-option:hover{color:#ed5251}.percentage-wrapper .delete-option mat-icon{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;min-width:100px}.value .value-name{display:none}input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;width:40px;margin-right:5px;font-size:15px;padding:0 5px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300}.users{margin-left:20px}@media (max-width: 700px){.percentage-wrapper{margin:.5em .3em}}\n"], components: [{ type: i3__namespace$2.MatChipList, selector: "mat-chip-list", inputs: ["aria-orientation", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "selectable", "tabIndex", "errorStateMatcher"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { type: i2__namespace$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: ValueComponent, selector: "configcat-value", inputs: ["valueFormControl", "setting"] }], directives: [{ type: i2__namespace.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2__namespace.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5__namespace$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace$2.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { type: i5__namespace$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2__namespace.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i2__namespace.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2__namespace.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2__namespace.FormControlDirective, selector: "[formControl]", inputs: ["disabled", "formControl", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i5__namespace$2.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
1152
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: RolloutPercentageItemsComponent, decorators: [{
1153
+ type: i0.Component,
1154
+ args: [{
1155
+ selector: 'configcat-rollout-percentage-items',
1156
+ templateUrl: './rollout-percentage-items.component.html',
1157
+ styleUrls: ['./rollout-percentage-items.component.scss']
1158
+ }]
1159
+ }], ctorParameters: function () { return []; }, propDecorators: { formGroup: [{
1160
+ type: i0.Input
1161
+ }], readOnly: [{
1162
+ type: i0.Input
1163
+ }] } });
1164
+
1165
+ var SettingComponent = /** @class */ (function () {
1166
+ function SettingComponent(formHelper, cdRef) {
1167
+ this.formHelper = formHelper;
1168
+ this.cdRef = cdRef;
1169
+ this.readOnly = false;
1170
+ this.canEditSetting = false;
1171
+ this.canDeleteSetting = false;
1172
+ this.deleteSettingText = 'Delete setting';
1173
+ this.showEnvironmentName = false;
1174
+ this.editSettingRequested = new i0.EventEmitter();
1175
+ this.deleteSettingRequested = new i0.EventEmitter();
1176
+ this.rulesBeingRendered = false;
1177
+ this.SettingType = ngConfigcatPublicapi.SettingType;
1178
+ }
1179
+ SettingComponent.prototype.ngOnInit = function () { };
1180
+ SettingComponent.prototype.environment = function () {
1181
+ var _a;
1182
+ return (_a = this.formGroup.root.get('environment')) === null || _a === void 0 ? void 0 : _a.value;
1183
+ };
1184
+ SettingComponent.prototype.setting = function () {
1185
+ var _a;
1186
+ return (_a = this.formGroup.get('setting')) === null || _a === void 0 ? void 0 : _a.value;
1187
+ };
1188
+ SettingComponent.prototype.integrationLinks = function () {
1189
+ return this.formGroup.get('integrationLinks');
1190
+ };
1191
+ SettingComponent.prototype.rolloutRules = function () {
1192
+ return this.formGroup.get('rolloutRules');
1193
+ };
1194
+ SettingComponent.prototype.rolloutPercentageItems = function () {
1195
+ return this.formGroup.get('rolloutPercentageItems');
1196
+ };
1197
+ SettingComponent.prototype.value = function () {
1198
+ return this.formGroup.get('value');
1199
+ };
1200
+ SettingComponent.prototype.addRolloutRule = function () {
1201
+ this.rolloutRules().push(this.formHelper.createRolloutRuleFormGroup({
1202
+ comparisonAttribute: 'Identifier',
1203
+ comparator: ngConfigcatPublicapi.RolloutRuleComparator.SensitiveIsOneOf,
1204
+ comparisonValue: '',
1205
+ value: this.setting().settingType === ngConfigcatPublicapi.SettingType.Boolean ? false : null
1206
+ }, this.readOnly, this.setting().settingType));
1207
+ this.rolloutRules().markAsDirty();
1208
+ };
1209
+ SettingComponent.prototype.removeRolloutRules = function () {
1210
+ this.rolloutRules().clear();
1211
+ this.rolloutRules().markAsDirty();
1212
+ };
1213
+ SettingComponent.prototype.addRolloutPercentageItem = function () {
1214
+ if (this.rolloutPercentageItems().length === 0) {
1215
+ switch (this.setting().settingType) {
1216
+ case ngConfigcatPublicapi.SettingType.Boolean:
1217
+ this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1218
+ percentage: 0,
1219
+ value: true
1220
+ }, this.readOnly, this.setting().settingType));
1221
+ this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1222
+ percentage: 100,
1223
+ value: false
1224
+ }, this.readOnly, this.setting().settingType));
1225
+ break;
1226
+ case ngConfigcatPublicapi.SettingType.String:
1227
+ case ngConfigcatPublicapi.SettingType.Int:
1228
+ case ngConfigcatPublicapi.SettingType.Double:
1229
+ for (var i = 0; i < 4; i++) {
1230
+ this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1231
+ percentage: 25,
1232
+ value: null
1233
+ }, this.readOnly, this.setting().settingType));
1234
+ }
1235
+ break;
1236
+ }
1237
+ }
1238
+ else if (this.setting().settingType !== ngConfigcatPublicapi.SettingType.Boolean) {
1239
+ this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1240
+ percentage: 0,
1241
+ value: null
1242
+ }, this.readOnly, this.setting().settingType));
1243
+ }
1244
+ this.rolloutPercentageItems().markAsDirty();
1245
+ };
1246
+ SettingComponent.prototype.removeRolloutPercentageItems = function () {
1247
+ this.rolloutPercentageItems().clear();
1248
+ this.rolloutPercentageItems().markAsDirty();
1249
+ };
1250
+ SettingComponent.prototype.editSetting = function () {
1251
+ this.editSettingRequested.emit({ setting: this.setting() });
1252
+ };
1253
+ SettingComponent.prototype.deleteSetting = function () {
1254
+ this.deleteSettingRequested.emit({ setting: this.setting() });
1255
+ };
1256
+ return SettingComponent;
1257
+ }());
1258
+ SettingComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: SettingComponent, deps: [{ token: SettingListFormHelper }, { token: i0__namespace.ChangeDetectorRef }], target: i0__namespace.ɵɵFactoryTarget.Component });
1259
+ SettingComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: SettingComponent, selector: "setting", inputs: { formGroup: "formGroup", readOnly: "readOnly", canEditSetting: "canEditSetting", canDeleteSetting: "canDeleteSetting", deleteSettingText: "deleteSettingText", showEnvironmentName: "showEnvironmentName" }, outputs: { editSettingRequested: "editSettingRequested", deleteSettingRequested: "deleteSettingRequested" }, ngImport: i0__namespace, template: "<div class=\"setting-full\"\n [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>\n\n <div class=\"rules-list\">\n <div>\n <configcat-rollout-rules *ngIf=\"rolloutRules().controls.length !== 0\" [formGroup]=\"formGroup\">\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 data-tooltip=\"This value will be served to all users who the above rules don't apply.\">\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 data-tooltip=\"This fallback value will be served in case the user can't be identified.\">\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)=\"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>\n", styles: [".setting-full{position:relative;display:flex;flex-wrap:nowrap;flex-direction:column;border-radius:3px}.setting-full .delete{position:absolute;right:-15px;top:-10px;color:#d6a9a9;cursor:pointer}.setting-full .delete:hover{color:#ed5251}.setting-full .delete mat-icon{font-size:20px}.setting-full .setting-header{padding:1.5em 1.5em 0}.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:bold;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 1em 1em}.setting-full .setting-content .setting-details>*{margin:.5em}.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 1em 1em}.setting-full .setting-content .targeting-button{margin-left:.5rem;margin-right:.5rem;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}.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;border-radius:2px;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}@media (max-width: 1200px){.setting-details{width:300px}}@media (max-width: 700px){.setting-full .setting-content{flex-wrap:wrap}.setting-full .setting-content .rules-list{padding:0}.buttons{flex-direction:column}.updated-date{display:none}.setting-details{padding:.2em 0 .2em .2em}.all-other{margin:.5em .3em}}\n"], components: [{ type: i2__namespace$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: RolloutRulesComponent, selector: "configcat-rollout-rules", inputs: ["formGroup", "readOnly"] }, { type: RolloutPercentageItemsComponent, selector: "configcat-rollout-percentage-items", inputs: ["formGroup", "readOnly"] }, { type: i3__namespace$2.MatChipList, selector: "mat-chip-list", inputs: ["aria-orientation", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "selectable", "tabIndex", "errorStateMatcher"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { type: ValueComponent, selector: "configcat-value", inputs: ["valueFormControl", "setting"] }], directives: [{ type: i2__namespace.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2__namespace.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5__namespace$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5__namespace$2.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i3__namespace$2.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }] });
1260
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: SettingComponent, decorators: [{
1261
+ type: i0.Component,
1262
+ args: [{
1263
+ selector: 'setting',
1264
+ templateUrl: './setting.component.html',
1265
+ styleUrls: ['./setting.component.scss']
1266
+ }]
1267
+ }], ctorParameters: function () { return [{ type: SettingListFormHelper }, { type: i0__namespace.ChangeDetectorRef }]; }, propDecorators: { formGroup: [{
1268
+ type: i0.Input
1269
+ }], readOnly: [{
1270
+ type: i0.Input
1271
+ }], canEditSetting: [{
1272
+ type: i0.Input
1273
+ }], canDeleteSetting: [{
1274
+ type: i0.Input
1275
+ }], deleteSettingText: [{
1276
+ type: i0.Input
1277
+ }], showEnvironmentName: [{
1278
+ type: i0.Input
1279
+ }], editSettingRequested: [{
1280
+ type: i0.Output
1281
+ }], deleteSettingRequested: [{
1282
+ type: i0.Output
1283
+ }] } });
1432
1284
 
1433
1285
  var SettingListComponent = /** @class */ (function () {
1434
1286
  function SettingListComponent(formHelper, snackBar, dialog) {
1435
1287
  this.formHelper = formHelper;
1436
1288
  this.snackBar = snackBar;
1437
1289
  this.dialog = dialog;
1290
+ this.canEditSetting = false;
1291
+ this.canDeleteSetting = false;
1438
1292
  this.deleteSettingText = 'Delete setting';
1439
1293
  this.showEnvironmentName = false;
1440
1294
  this.editSettingRequested = new i0.EventEmitter();
@@ -1482,6 +1336,9 @@
1482
1336
  SettingListComponent.prototype.settingValuesFormArray = function () {
1483
1337
  return this.formGroup.get('settingValues');
1484
1338
  };
1339
+ SettingListComponent.prototype.getSettingValueFormGroups = function () {
1340
+ return this.settingValuesFormArray().controls.map(function (c) { return c; });
1341
+ };
1485
1342
  SettingListComponent.prototype.submit = function () {
1486
1343
  var _this = this;
1487
1344
  if (!this.formGroup || !this.formGroup.valid) {
@@ -1583,139 +1440,396 @@
1583
1440
  };
1584
1441
  return SettingListComponent;
1585
1442
  }());
1586
- SettingListComponent.decorators = [
1587
- { type: i0.Component, args: [{
1588
- selector: 'configcat-setting-list',
1589
- template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"submit()\" *ngIf=\"!loading\">\n <div class=\"wrapper\" *ngFor=\"let settingValueFromGroup of settingValuesFormArray().controls; let i = index\">\n <setting [formGroup]=\"settingValueFromGroup\" [readOnly]=\"readOnly\"\n [canEditSetting]=\"canEditSetting\" [canDeleteSetting]=\"canDeleteSetting\"\n (editSettingRequested)=\"onEditSettingRequested($event)\"\n (deleteSettingRequested)=\"onDeleteSettingRequested($event)\" [deleteSettingText]=\"deleteSettingText\"\n [showEnvironmentName]=\"showEnvironmentName\">\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>\n",
1590
- styles: [".wrapper{background-color:#f3f3f3;border:1px solid rgba(0,0,0,.12);border-radius:4px;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{-webkit-animation:shadow-pulse 1s 3;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"]
1591
- },] }
1592
- ];
1593
- SettingListComponent.ctorParameters = function () { return [
1594
- { type: SettingListFormHelper },
1595
- { type: snackBar.MatSnackBar },
1596
- { type: dialog.MatDialog }
1597
- ]; };
1598
- SettingListComponent.propDecorators = {
1599
- canEditSetting: [{ type: i0.Input }],
1600
- canDeleteSetting: [{ type: i0.Input }],
1601
- onSave: [{ type: i0.Input }],
1602
- loadSettingValues: [{ type: i0.Input }],
1603
- deleteSettingText: [{ type: i0.Input }],
1604
- showEnvironmentName: [{ type: i0.Input }],
1605
- editSettingRequested: [{ type: i0.Output }],
1606
- deleteSettingRequested: [{ type: i0.Output }],
1607
- formValuesChanged: [{ type: i0.Output }]
1608
- };
1443
+ SettingListComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: SettingListComponent, deps: [{ token: SettingListFormHelper }, { token: i2__namespace$2.MatSnackBar }, { token: i1__namespace$1.MatDialog }], target: i0__namespace.ɵɵFactoryTarget.Component });
1444
+ SettingListComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: SettingListComponent, selector: "configcat-setting-list", inputs: { canEditSetting: "canEditSetting", canDeleteSetting: "canDeleteSetting", onSave: "onSave", loadSettingValues: "loadSettingValues", deleteSettingText: "deleteSettingText", showEnvironmentName: "showEnvironmentName" }, outputs: { editSettingRequested: "editSettingRequested", deleteSettingRequested: "deleteSettingRequested", formValuesChanged: "formValuesChanged" }, usesOnChanges: true, ngImport: i0__namespace, 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\">\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);border-radius:4px;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"], components: [{ type: SettingComponent, selector: "setting", inputs: ["formGroup", "readOnly", "canEditSetting", "canDeleteSetting", "deleteSettingText", "showEnvironmentName"], outputs: ["editSettingRequested", "deleteSettingRequested"] }, { type: i4__namespace.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"] }, { type: i2__namespace$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i5__namespace$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2__namespace.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i2__namespace.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2__namespace.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5__namespace$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
1445
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: SettingListComponent, decorators: [{
1446
+ type: i0.Component,
1447
+ args: [{
1448
+ selector: 'configcat-setting-list',
1449
+ templateUrl: './setting-list.component.html',
1450
+ styleUrls: ['./setting-list.component.scss']
1451
+ }]
1452
+ }], ctorParameters: function () { return [{ type: SettingListFormHelper }, { type: i2__namespace$2.MatSnackBar }, { type: i1__namespace$1.MatDialog }]; }, propDecorators: { canEditSetting: [{
1453
+ type: i0.Input
1454
+ }], canDeleteSetting: [{
1455
+ type: i0.Input
1456
+ }], onSave: [{
1457
+ type: i0.Input
1458
+ }], loadSettingValues: [{
1459
+ type: i0.Input
1460
+ }], deleteSettingText: [{
1461
+ type: i0.Input
1462
+ }], showEnvironmentName: [{
1463
+ type: i0.Input
1464
+ }], editSettingRequested: [{
1465
+ type: i0.Output
1466
+ }], deleteSettingRequested: [{
1467
+ type: i0.Output
1468
+ }], formValuesChanged: [{
1469
+ type: i0.Output
1470
+ }] } });
1609
1471
 
1610
- var SettingComponent = /** @class */ (function () {
1611
- function SettingComponent(formHelper, cdRef) {
1612
- this.formHelper = formHelper;
1613
- this.cdRef = cdRef;
1614
- this.deleteSettingText = 'Delete setting';
1615
- this.showEnvironmentName = false;
1616
- this.editSettingRequested = new i0.EventEmitter();
1617
- this.deleteSettingRequested = new i0.EventEmitter();
1618
- this.rulesBeingRendered = false;
1619
- this.SettingType = ngConfigcatPublicapi.SettingType;
1472
+ var SettingItemComponent = /** @class */ (function (_super) {
1473
+ __extends(SettingItemComponent, _super);
1474
+ function SettingItemComponent(publicApiService) {
1475
+ var _this = _super.call(this, publicApiService) || this;
1476
+ _this.canEditSetting = true;
1477
+ _this.canDeleteSetting = true;
1478
+ _this.deleteSettingText = 'Delete setting';
1479
+ _this.showEnvironmentName = true;
1480
+ _this.editSettingRequested = new i0.EventEmitter();
1481
+ _this.deleteSettingRequested = new i0.EventEmitter();
1482
+ _this.loadSucceeded = new i0.EventEmitter();
1483
+ _this.loadFailed = new i0.EventEmitter();
1484
+ _this.saveSucceeded = new i0.EventEmitter();
1485
+ _this.saveFailed = new i0.EventEmitter();
1486
+ _this.formValuesChanged = new i0.EventEmitter();
1487
+ _this.loadSettingValues = function () {
1488
+ return _this.createSettingValuesService().getSettingValue(_this.environmentId, _this.settingId)
1489
+ .pipe(operators.map(function (settingValue) {
1490
+ _this.settingValue = settingValue;
1491
+ var settingValues = {
1492
+ settingValues: [settingValue],
1493
+ readOnly: settingValue.readOnly,
1494
+ config: settingValue.config,
1495
+ environment: settingValue.environment
1496
+ };
1497
+ _this.loadSucceeded.emit(settingValues);
1498
+ return settingValues;
1499
+ }), operators.catchError(function (error) {
1500
+ _this.loadFailed.emit(error);
1501
+ return rxjs.throwError(error);
1502
+ }));
1503
+ };
1504
+ _this.handleSave = function (model) {
1505
+ if (model.settingValues.length === 0) {
1506
+ return rxjs.of();
1507
+ }
1508
+ var updateModel = model.settingValues[0];
1509
+ return _this.createSettingValuesService().replaceSettingValue(_this.environmentId, _this.settingId, updateModel, model.reason)
1510
+ .pipe(operators.map(function (settingValue) {
1511
+ _this.settingValue = settingValue;
1512
+ var settingValues = {
1513
+ settingValues: [settingValue],
1514
+ readOnly: settingValue.readOnly,
1515
+ config: settingValue.config,
1516
+ environment: settingValue.environment
1517
+ };
1518
+ _this.saveSucceeded.emit(settingValues);
1519
+ return settingValues;
1520
+ }), operators.catchError(function (error) {
1521
+ _this.saveFailed.emit(error);
1522
+ return rxjs.throwError(error);
1523
+ }));
1524
+ };
1525
+ return _this;
1620
1526
  }
1621
- SettingComponent.prototype.ngOnInit = function () { };
1622
- SettingComponent.prototype.environment = function () {
1623
- return this.formGroup.root.get('environment').value;
1624
- };
1625
- SettingComponent.prototype.setting = function () {
1626
- return this.formGroup.get('setting').value;
1527
+ SettingItemComponent.prototype.ngOnInit = function () {
1627
1528
  };
1628
- SettingComponent.prototype.integrationLinks = function () {
1629
- return this.formGroup.get('integrationLinks');
1529
+ SettingItemComponent.prototype.onEditSettingRequested = function (setting) {
1530
+ this.editSettingRequested.emit({
1531
+ setting: setting.setting,
1532
+ environment: this.settingValue.environment,
1533
+ config: this.settingValue.config
1534
+ });
1630
1535
  };
1631
- SettingComponent.prototype.rolloutRules = function () {
1632
- return this.formGroup.get('rolloutRules');
1536
+ SettingItemComponent.prototype.onDeleteSettingRequested = function (setting) {
1537
+ this.deleteSettingRequested.emit({
1538
+ setting: setting.setting,
1539
+ environment: this.settingValue.environment,
1540
+ config: this.settingValue.config
1541
+ });
1633
1542
  };
1634
- SettingComponent.prototype.rolloutPercentageItems = function () {
1635
- return this.formGroup.get('rolloutPercentageItems');
1543
+ SettingItemComponent.prototype.onFormValuesChanged = function () {
1544
+ this.formValuesChanged.emit();
1636
1545
  };
1637
- SettingComponent.prototype.value = function () {
1638
- return this.formGroup.get('value');
1546
+ return SettingItemComponent;
1547
+ }(BaseComponent));
1548
+ SettingItemComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: SettingItemComponent, deps: [{ token: PublicApiService }], target: i0__namespace.ɵɵFactoryTarget.Component });
1549
+ SettingItemComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.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__namespace, template: "<configcat-setting-list [canEditSetting]=\"canEditSetting\" [canDeleteSetting]=\"canDeleteSetting\"\n [onSave]=\"handleSave\" [loadSettingValues]=\"loadSettingValues\"\n (editSettingRequested)=\"onEditSettingRequested($event)\" (deleteSettingRequested)=\"onDeleteSettingRequested($event)\"\n [deleteSettingText]=\"deleteSettingText\"\n [showEnvironmentName]=\"showEnvironmentName\" (formValuesChanged)=\"onFormValuesChanged()\">\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:bold;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"], components: [{ type: SettingListComponent, selector: "configcat-setting-list", inputs: ["canEditSetting", "canDeleteSetting", "onSave", "loadSettingValues", "deleteSettingText", "showEnvironmentName"], outputs: ["editSettingRequested", "deleteSettingRequested", "formValuesChanged"] }] });
1550
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: SettingItemComponent, decorators: [{
1551
+ type: i0.Component,
1552
+ args: [{
1553
+ selector: 'configcat-setting-item',
1554
+ templateUrl: './setting-item.component.html',
1555
+ styleUrls: ['./setting-item.component.scss']
1556
+ }]
1557
+ }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { productId: [{
1558
+ type: i0.Input
1559
+ }], environmentId: [{
1560
+ type: i0.Input
1561
+ }], configId: [{
1562
+ type: i0.Input
1563
+ }], settingId: [{
1564
+ type: i0.Input
1565
+ }], canEditSetting: [{
1566
+ type: i0.Input
1567
+ }], canDeleteSetting: [{
1568
+ type: i0.Input
1569
+ }], deleteSettingText: [{
1570
+ type: i0.Input
1571
+ }], showEnvironmentName: [{
1572
+ type: i0.Input
1573
+ }], editSettingRequested: [{
1574
+ type: i0.Output
1575
+ }], deleteSettingRequested: [{
1576
+ type: i0.Output
1577
+ }], loadSucceeded: [{
1578
+ type: i0.Output
1579
+ }], loadFailed: [{
1580
+ type: i0.Output
1581
+ }], saveSucceeded: [{
1582
+ type: i0.Output
1583
+ }], saveFailed: [{
1584
+ type: i0.Output
1585
+ }], formValuesChanged: [{
1586
+ type: i0.Output
1587
+ }] } });
1588
+
1589
+ var SettingSelectComponent = /** @class */ (function (_super) {
1590
+ __extends(SettingSelectComponent, _super);
1591
+ function SettingSelectComponent(publicApiService) {
1592
+ var _this = _super.call(this, publicApiService) || this;
1593
+ _this.settings = [];
1594
+ return _this;
1595
+ }
1596
+ SettingSelectComponent.prototype.ngOnInit = function () {
1597
+ this.settings = [];
1598
+ this.reloadSettings();
1639
1599
  };
1640
- SettingComponent.prototype.addRolloutRule = function () {
1641
- this.rolloutRules().push(this.formHelper.createRolloutRuleFormGroup({
1642
- comparisonAttribute: 'Identifier',
1643
- comparator: ngConfigcatPublicapi.RolloutRuleComparator.SensitiveIsOneOf,
1644
- comparisonValue: '',
1645
- value: this.setting().settingType === ngConfigcatPublicapi.SettingType.Boolean ? false : null
1646
- }, this.readOnly, this.setting().settingType));
1647
- this.rolloutRules().markAsDirty();
1600
+ SettingSelectComponent.prototype.ngOnChanges = function () {
1601
+ this.reloadSettings();
1648
1602
  };
1649
- SettingComponent.prototype.removeRolloutRules = function () {
1650
- this.rolloutRules().clear();
1651
- this.rolloutRules().markAsDirty();
1603
+ SettingSelectComponent.prototype.reloadSettings = function () {
1604
+ var _this = this;
1605
+ if (this.configId) {
1606
+ this.createSettingsService().getSettings(this.configId).subscribe(function (settings) {
1607
+ _this.settings = settings;
1608
+ if (_this.settings.length > 0) {
1609
+ _this.valueFormControl.setValue(_this.settings[0].settingId);
1610
+ }
1611
+ });
1612
+ }
1652
1613
  };
1653
- SettingComponent.prototype.addRolloutPercentageItem = function () {
1654
- if (this.rolloutPercentageItems().length === 0) {
1655
- switch (this.setting().settingType) {
1656
- case ngConfigcatPublicapi.SettingType.Boolean:
1657
- this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1658
- percentage: 0,
1659
- value: true
1660
- }, this.readOnly, this.setting().settingType));
1661
- this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1662
- percentage: 100,
1663
- value: false
1664
- }, this.readOnly, this.setting().settingType));
1665
- break;
1666
- case ngConfigcatPublicapi.SettingType.String:
1667
- case ngConfigcatPublicapi.SettingType.Int:
1668
- case ngConfigcatPublicapi.SettingType.Double:
1669
- for (var i = 0; i < 4; i++) {
1670
- this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1671
- percentage: 25,
1672
- value: null
1673
- }, this.readOnly, this.setting().settingType));
1674
- }
1675
- break;
1614
+ return SettingSelectComponent;
1615
+ }(BaseComponent));
1616
+ SettingSelectComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: SettingSelectComponent, deps: [{ token: PublicApiService }], target: i0__namespace.ɵɵFactoryTarget.Component });
1617
+ SettingSelectComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: SettingSelectComponent, selector: "configcat-setting-select", inputs: { valueFormControl: "valueFormControl", configId: "configId" }, usesInheritance: true, usesOnChanges: true, ngImport: i0__namespace, template: "<mat-form-field class=\"form-field\">\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"], components: [{ type: i3__namespace.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i3__namespace$3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i4__namespace$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i5__namespace$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2__namespace.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2__namespace.FormControlDirective, selector: "[formControl]", inputs: ["disabled", "formControl", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i5__namespace$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
1618
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: SettingSelectComponent, decorators: [{
1619
+ type: i0.Component,
1620
+ args: [{
1621
+ selector: 'configcat-setting-select',
1622
+ templateUrl: './setting-select.component.html',
1623
+ styleUrls: ['./setting-select.component.css']
1624
+ }]
1625
+ }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { valueFormControl: [{
1626
+ type: i0.Input
1627
+ }], configId: [{
1628
+ type: i0.Input
1629
+ }] } });
1630
+
1631
+ var ProductSelectComponent = /** @class */ (function (_super) {
1632
+ __extends(ProductSelectComponent, _super);
1633
+ function ProductSelectComponent(publicApiService) {
1634
+ var _this = _super.call(this, publicApiService) || this;
1635
+ _this.products = [];
1636
+ return _this;
1637
+ }
1638
+ ProductSelectComponent.prototype.ngOnInit = function () {
1639
+ var _this = this;
1640
+ this.products = [];
1641
+ this.createProductsService().getProducts().subscribe(function (products) {
1642
+ _this.products = products;
1643
+ if (_this.products.length > 0) {
1644
+ _this.valueFormControl.setValue(_this.products[0].productId, {
1645
+ emitEvent: true,
1646
+ emitModelToViewChange: true, emitViewToModelChange: true
1647
+ });
1676
1648
  }
1649
+ });
1650
+ };
1651
+ return ProductSelectComponent;
1652
+ }(BaseComponent));
1653
+ ProductSelectComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: ProductSelectComponent, deps: [{ token: PublicApiService }], target: i0__namespace.ɵɵFactoryTarget.Component });
1654
+ ProductSelectComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: ProductSelectComponent, selector: "configcat-product-select", inputs: { valueFormControl: "valueFormControl" }, usesInheritance: true, ngImport: i0__namespace, template: "<mat-form-field class=\"form-field\">\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"], components: [{ type: i3__namespace.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i3__namespace$3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i4__namespace$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i2__namespace.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2__namespace.FormControlDirective, selector: "[formControl]", inputs: ["disabled", "formControl", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i5__namespace$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
1655
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: ProductSelectComponent, decorators: [{
1656
+ type: i0.Component,
1657
+ args: [{
1658
+ selector: 'configcat-product-select',
1659
+ templateUrl: './product-select.component.html',
1660
+ styleUrls: ['./product-select.component.css']
1661
+ }]
1662
+ }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { valueFormControl: [{
1663
+ type: i0.Input
1664
+ }] } });
1665
+
1666
+ var ConfigSelectComponent = /** @class */ (function (_super) {
1667
+ __extends(ConfigSelectComponent, _super);
1668
+ function ConfigSelectComponent(publicApiService) {
1669
+ var _this = _super.call(this, publicApiService) || this;
1670
+ _this.configs = [];
1671
+ return _this;
1672
+ }
1673
+ ConfigSelectComponent.prototype.ngOnInit = function () {
1674
+ this.configs = [];
1675
+ this.reloadConfigs();
1676
+ };
1677
+ ConfigSelectComponent.prototype.ngOnChanges = function () {
1678
+ this.reloadConfigs();
1679
+ };
1680
+ ConfigSelectComponent.prototype.reloadConfigs = function () {
1681
+ var _this = this;
1682
+ if (this.productId) {
1683
+ this.createConfigsService().getConfigs(this.productId).subscribe(function (configs) {
1684
+ _this.configs = configs;
1685
+ if (_this.configs.length > 0) {
1686
+ _this.valueFormControl.setValue(_this.configs[0].configId);
1687
+ }
1688
+ });
1677
1689
  }
1678
- else if (this.setting().settingType !== ngConfigcatPublicapi.SettingType.Boolean) {
1679
- this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1680
- percentage: 0,
1681
- value: null
1682
- }, this.readOnly, this.setting().settingType));
1690
+ };
1691
+ return ConfigSelectComponent;
1692
+ }(BaseComponent));
1693
+ ConfigSelectComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: ConfigSelectComponent, deps: [{ token: PublicApiService }], target: i0__namespace.ɵɵFactoryTarget.Component });
1694
+ ConfigSelectComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: ConfigSelectComponent, selector: "configcat-config-select", inputs: { valueFormControl: "valueFormControl", productId: "productId" }, providers: [
1695
+ {
1696
+ provide: i2.NG_VALUE_ACCESSOR,
1697
+ useExisting: i0.forwardRef(function () { return ConfigSelectComponent; }),
1698
+ multi: true
1683
1699
  }
1684
- this.rolloutPercentageItems().markAsDirty();
1700
+ ], usesInheritance: true, usesOnChanges: true, ngImport: i0__namespace, template: "<mat-form-field class=\"form-field\">\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"], components: [{ type: i3__namespace.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i3__namespace$3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i4__namespace$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i5__namespace$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2__namespace.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2__namespace.FormControlDirective, selector: "[formControl]", inputs: ["disabled", "formControl", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i5__namespace$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
1701
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: ConfigSelectComponent, decorators: [{
1702
+ type: i0.Component,
1703
+ args: [{
1704
+ selector: 'configcat-config-select',
1705
+ templateUrl: './config-select.component.html',
1706
+ styleUrls: ['./config-select.component.css'],
1707
+ providers: [
1708
+ {
1709
+ provide: i2.NG_VALUE_ACCESSOR,
1710
+ useExisting: i0.forwardRef(function () { return ConfigSelectComponent; }),
1711
+ multi: true
1712
+ }
1713
+ ]
1714
+ }]
1715
+ }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { valueFormControl: [{
1716
+ type: i0.Input
1717
+ }], productId: [{
1718
+ type: i0.Input
1719
+ }] } });
1720
+
1721
+ var EnvironmentSelectComponent = /** @class */ (function (_super) {
1722
+ __extends(EnvironmentSelectComponent, _super);
1723
+ function EnvironmentSelectComponent(publicApiService) {
1724
+ var _this = _super.call(this, publicApiService) || this;
1725
+ _this.environments = [];
1726
+ return _this;
1727
+ }
1728
+ EnvironmentSelectComponent.prototype.ngOnInit = function () {
1729
+ this.environments = [];
1730
+ this.reloadEnvironments();
1685
1731
  };
1686
- SettingComponent.prototype.removeRolloutPercentageItems = function () {
1687
- this.rolloutPercentageItems().clear();
1688
- this.rolloutPercentageItems().markAsDirty();
1732
+ EnvironmentSelectComponent.prototype.ngOnChanges = function () {
1733
+ this.reloadEnvironments();
1689
1734
  };
1690
- SettingComponent.prototype.editSetting = function () {
1691
- this.editSettingRequested.emit({ setting: this.setting() });
1735
+ EnvironmentSelectComponent.prototype.reloadEnvironments = function () {
1736
+ var _this = this;
1737
+ if (this.productId) {
1738
+ this.createEnvironmentsService().getEnvironments(this.productId).subscribe(function (environments) {
1739
+ _this.environments = environments;
1740
+ if (_this.environments.length > 0) {
1741
+ _this.valueFormControl.setValue(_this.environments[0].environmentId);
1742
+ }
1743
+ });
1744
+ }
1692
1745
  };
1693
- SettingComponent.prototype.deleteSetting = function () {
1694
- this.deleteSettingRequested.emit({ setting: this.setting() });
1746
+ return EnvironmentSelectComponent;
1747
+ }(BaseComponent));
1748
+ EnvironmentSelectComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: EnvironmentSelectComponent, deps: [{ token: PublicApiService }], target: i0__namespace.ɵɵFactoryTarget.Component });
1749
+ EnvironmentSelectComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: EnvironmentSelectComponent, selector: "configcat-environment-select", inputs: { valueFormControl: "valueFormControl", productId: "productId" }, usesInheritance: true, usesOnChanges: true, ngImport: i0__namespace, template: "<mat-form-field class=\"form-field\">\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"], components: [{ type: i3__namespace.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i3__namespace$3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i4__namespace$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }], directives: [{ type: i5__namespace$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2__namespace.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2__namespace.FormControlDirective, selector: "[formControl]", inputs: ["disabled", "formControl", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i5__namespace$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
1750
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: EnvironmentSelectComponent, decorators: [{
1751
+ type: i0.Component,
1752
+ args: [{
1753
+ selector: 'configcat-environment-select',
1754
+ templateUrl: './environment-select.component.html',
1755
+ styleUrls: ['./environment-select.component.css']
1756
+ }]
1757
+ }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { valueFormControl: [{
1758
+ type: i0.Input
1759
+ }], productId: [{
1760
+ type: i0.Input
1761
+ }] } });
1762
+
1763
+ var FormHelper = /** @class */ (function () {
1764
+ function FormHelper() {
1765
+ }
1766
+ FormHelper.getErrorMessage = function (control, hint) {
1767
+ if (hint === void 0) { hint = ''; }
1768
+ if (!control || control.valid) {
1769
+ return;
1770
+ }
1771
+ if (control.hasError('required')) {
1772
+ return hint + " The field is required.";
1773
+ }
1774
+ if (control.hasError('pattern')) {
1775
+ return 'Not a valid e-mail address.';
1776
+ }
1777
+ if (control.hasError('minlength')) {
1778
+ return 'The field must be at least ' + control.getError('minlength').requiredLength + ' characters long';
1779
+ }
1780
+ if (control.hasError('maxlength')) {
1781
+ return 'The field must be at max ' + control.getError('maxlength').requiredLength + ' characters long';
1782
+ }
1783
+ return;
1695
1784
  };
1696
- return SettingComponent;
1785
+ return FormHelper;
1697
1786
  }());
1698
- SettingComponent.decorators = [
1699
- { type: i0.Component, args: [{
1700
- selector: 'setting',
1701
- template: "<div class=\"setting-full\"\n [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>\n\n <div class=\"rules-list\">\n <div>\n <configcat-rollout-rules *ngIf=\"rolloutRules().controls.length !== 0\" [formGroup]=\"formGroup\">\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 data-tooltip=\"This value will be served to all users who the above rules don't apply.\">\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 data-tooltip=\"This fallback value will be served in case the user can't be identified.\">\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)=\"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>\n",
1702
- styles: [".setting-full{position:relative;display:flex;flex-wrap:nowrap;flex-direction:column;border-radius:3px}.setting-full .delete{position:absolute;right:-15px;top:-10px;color:#d6a9a9;cursor:pointer}.setting-full .delete:hover{color:#ed5251}.setting-full .delete mat-icon{font-size:20px}.setting-full .setting-header{padding:1.5em 1.5em 0}.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:bold;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 1em 1em}.setting-full .setting-content .setting-details>*{margin:.5em}.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 1em 1em}.setting-full .setting-content .targeting-button{margin-left:.5rem;margin-right:.5rem;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}.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;border-radius:2px;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}@media (max-width: 1200px){.setting-details{width:300px}}@media (max-width: 700px){.setting-full .setting-content{flex-wrap:wrap}.setting-full .setting-content .rules-list{padding:0}.buttons{flex-direction:column}.updated-date{display:none}.setting-details{padding:.2em 0 .2em .2em}.all-other{margin:.5em .3em}}\n"]
1703
- },] }
1704
- ];
1705
- SettingComponent.ctorParameters = function () { return [
1706
- { type: SettingListFormHelper },
1707
- { type: i0.ChangeDetectorRef }
1708
- ]; };
1709
- SettingComponent.propDecorators = {
1710
- formGroup: [{ type: i0.Input }],
1711
- readOnly: [{ type: i0.Input }],
1712
- canEditSetting: [{ type: i0.Input }],
1713
- canDeleteSetting: [{ type: i0.Input }],
1714
- deleteSettingText: [{ type: i0.Input }],
1715
- showEnvironmentName: [{ type: i0.Input }],
1716
- editSettingRequested: [{ type: i0.Output }],
1717
- deleteSettingRequested: [{ type: i0.Output }]
1718
- };
1787
+
1788
+ var AuthorizationComponent = /** @class */ (function () {
1789
+ function AuthorizationComponent(formBuilder, publicApiService) {
1790
+ this.formBuilder = formBuilder;
1791
+ this.publicApiService = publicApiService;
1792
+ this.basePath = null;
1793
+ this.authorized = new i0.EventEmitter();
1794
+ this.FormHelper = FormHelper;
1795
+ }
1796
+ AuthorizationComponent.prototype.ngOnInit = function () {
1797
+ this.formGroup = this.formBuilder.group({
1798
+ basicAuthUsername: ['', i2.Validators.required],
1799
+ basicAuthPassword: ['', i2.Validators.required],
1800
+ });
1801
+ };
1802
+ AuthorizationComponent.prototype.onSubmit = function () {
1803
+ var _this = this;
1804
+ if (!this.formGroup.valid) {
1805
+ return;
1806
+ }
1807
+ var meService = this.publicApiService.createMeService(this.formGroup.controls.basicAuthUsername.value, this.formGroup.controls.basicAuthPassword.value, this.basePath);
1808
+ meService.getMe().subscribe(function (me) {
1809
+ _this.authorized.emit({
1810
+ basicAuthUsername: _this.formGroup.controls.basicAuthUsername.value,
1811
+ basicAuthPassword: _this.formGroup.controls.basicAuthPassword.value
1812
+ });
1813
+ }, function (error) {
1814
+ _this.formGroup.setErrors({ invalidAuthorization: 'Invalid Basic auth user name or password' });
1815
+ });
1816
+ };
1817
+ return AuthorizationComponent;
1818
+ }());
1819
+ AuthorizationComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: AuthorizationComponent, deps: [{ token: i2__namespace.FormBuilder }, { token: PublicApiService }], target: i0__namespace.ɵɵFactoryTarget.Component });
1820
+ AuthorizationComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.12", type: AuthorizationComponent, selector: "configcat-authorization", inputs: { basePath: "basePath" }, outputs: { authorized: "authorized" }, ngImport: i0__namespace, template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n <div class=\"container\">\n <div class=\"form\">\n <p>\n <a href=\"https://app.configcat.com/my-account/public-api-credentials\" target=\"_blank\">\n Get your Basic Auth user name and password</a> to access ConfigCat Public API.\n <br /><br />\n <b>Note!</b> Your ConfigCat account's email address and password will not work here.\n </p>\n\n <mat-form-field class=\"form-field\">\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\">\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-raised-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"], components: [{ type: i3__namespace.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i4__namespace.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"] }], directives: [{ type: i2__namespace.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i2__namespace.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2__namespace.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i3__namespace.MatLabel, selector: "mat-label" }, { type: i5__namespace.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["id", "disabled", "required", "type", "value", "readonly", "placeholder", "errorStateMatcher", "aria-describedby"], exportAs: ["matInput"] }, { type: i2__namespace.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2__namespace.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2__namespace.FormControlName, selector: "[formControlName]", inputs: ["disabled", "formControlName", "ngModel"], outputs: ["ngModelChange"] }, { type: i5__namespace$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3__namespace.MatError, selector: "mat-error", inputs: ["id"] }] });
1821
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: AuthorizationComponent, decorators: [{
1822
+ type: i0.Component,
1823
+ args: [{
1824
+ selector: 'configcat-authorization',
1825
+ templateUrl: './authorization.component.html',
1826
+ styleUrls: ['./authorization.component.scss']
1827
+ }]
1828
+ }], ctorParameters: function () { return [{ type: i2__namespace.FormBuilder }, { type: PublicApiService }]; }, propDecorators: { basePath: [{
1829
+ type: i0.Input
1830
+ }], authorized: [{
1831
+ type: i0.Output
1832
+ }] } });
1719
1833
 
1720
1834
  var NgConfigCatPublicApiUIModule = /** @class */ (function () {
1721
1835
  function NgConfigCatPublicApiUIModule() {
@@ -1728,60 +1842,119 @@
1728
1842
  };
1729
1843
  return NgConfigCatPublicApiUIModule;
1730
1844
  }());
1731
- NgConfigCatPublicApiUIModule.decorators = [
1732
- { type: i0.NgModule, args: [{
1733
- declarations: [
1734
- BaseComponent,
1735
- ProductSelectComponent,
1736
- ConfigSelectComponent,
1737
- EnvironmentSelectComponent,
1738
- SettingSelectComponent,
1739
- SettingItemComponent,
1740
- AuthorizationComponent,
1741
- SettingListComponent,
1742
- SettingComponent,
1743
- RolloutPercentageItemsComponent,
1744
- RolloutRulesComponent,
1745
- ValueComponent,
1746
- ReasonDialogComponent,
1747
- ConcurrentDialogComponent,
1748
- SaveSnackbarComponent,
1749
- ExpandDialogComponent
1750
- ],
1751
- imports: [
1752
- common.CommonModule,
1753
- i1$1.FormsModule,
1754
- i1$1.ReactiveFormsModule,
1755
- animations.BrowserAnimationsModule,
1756
- i1.HttpClientModule,
1757
- ngConfigcatPublicapi.ApiModule,
1758
- formField.MatFormFieldModule,
1759
- core.MatOptionModule,
1760
- select.MatSelectModule,
1761
- button.MatButtonModule,
1762
- input.MatInputModule,
1763
- icon.MatIconModule,
1764
- tooltip.MatTooltipModule,
1765
- chips.MatChipsModule,
1766
- autocomplete.MatAutocompleteModule,
1767
- dragDrop.DragDropModule,
1768
- router.RouterModule,
1769
- snackBar.MatSnackBarModule,
1770
- dialog.MatDialogModule,
1771
- menu.MatMenuModule
1772
- ],
1773
- exports: [
1774
- ngConfigcatPublicapi.ApiModule,
1775
- AuthorizationComponent,
1776
- ProductSelectComponent,
1777
- ConfigSelectComponent,
1778
- EnvironmentSelectComponent,
1779
- SettingSelectComponent,
1780
- SettingItemComponent
1781
- ]
1782
- },] }
1783
- ];
1784
- NgConfigCatPublicApiUIModule.ctorParameters = function () { return []; };
1845
+ NgConfigCatPublicApiUIModule.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: NgConfigCatPublicApiUIModule, deps: [], target: i0__namespace.ɵɵFactoryTarget.NgModule });
1846
+ NgConfigCatPublicApiUIModule.ɵmod = i0__namespace.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: NgConfigCatPublicApiUIModule, declarations: [BaseComponent,
1847
+ ProductSelectComponent,
1848
+ ConfigSelectComponent,
1849
+ EnvironmentSelectComponent,
1850
+ SettingSelectComponent,
1851
+ SettingItemComponent,
1852
+ AuthorizationComponent,
1853
+ SettingListComponent,
1854
+ SettingComponent,
1855
+ RolloutPercentageItemsComponent,
1856
+ RolloutRulesComponent,
1857
+ ValueComponent,
1858
+ ReasonDialogComponent,
1859
+ ConcurrentDialogComponent,
1860
+ SaveSnackbarComponent,
1861
+ ExpandDialogComponent], imports: [i5$1.CommonModule,
1862
+ i2.FormsModule,
1863
+ i2.ReactiveFormsModule,
1864
+ animations.BrowserAnimationsModule,
1865
+ i3.MatFormFieldModule,
1866
+ i4$2.MatOptionModule,
1867
+ i3$3.MatSelectModule,
1868
+ i4.MatButtonModule,
1869
+ i5.MatInputModule,
1870
+ i2$1.MatIconModule,
1871
+ i5$2.MatTooltipModule,
1872
+ i3$2.MatChipsModule,
1873
+ i4$1.MatAutocompleteModule,
1874
+ i8.DragDropModule,
1875
+ i3$1.RouterModule,
1876
+ i2$2.MatSnackBarModule,
1877
+ i1$1.MatDialogModule,
1878
+ menu.MatMenuModule,
1879
+ ngConfigcatPublicapi.ApiModule], exports: [AuthorizationComponent,
1880
+ ProductSelectComponent,
1881
+ ConfigSelectComponent,
1882
+ EnvironmentSelectComponent,
1883
+ SettingSelectComponent,
1884
+ SettingItemComponent] });
1885
+ NgConfigCatPublicApiUIModule.ɵinj = i0__namespace.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: NgConfigCatPublicApiUIModule, imports: [[
1886
+ i5$1.CommonModule,
1887
+ i2.FormsModule,
1888
+ i2.ReactiveFormsModule,
1889
+ animations.BrowserAnimationsModule,
1890
+ i3.MatFormFieldModule,
1891
+ i4$2.MatOptionModule,
1892
+ i3$3.MatSelectModule,
1893
+ i4.MatButtonModule,
1894
+ i5.MatInputModule,
1895
+ i2$1.MatIconModule,
1896
+ i5$2.MatTooltipModule,
1897
+ i3$2.MatChipsModule,
1898
+ i4$1.MatAutocompleteModule,
1899
+ i8.DragDropModule,
1900
+ i3$1.RouterModule,
1901
+ i2$2.MatSnackBarModule,
1902
+ i1$1.MatDialogModule,
1903
+ menu.MatMenuModule,
1904
+ ngConfigcatPublicapi.ApiModule
1905
+ ]] });
1906
+ i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.12", ngImport: i0__namespace, type: NgConfigCatPublicApiUIModule, decorators: [{
1907
+ type: i0.NgModule,
1908
+ args: [{
1909
+ declarations: [
1910
+ BaseComponent,
1911
+ ProductSelectComponent,
1912
+ ConfigSelectComponent,
1913
+ EnvironmentSelectComponent,
1914
+ SettingSelectComponent,
1915
+ SettingItemComponent,
1916
+ AuthorizationComponent,
1917
+ SettingListComponent,
1918
+ SettingComponent,
1919
+ RolloutPercentageItemsComponent,
1920
+ RolloutRulesComponent,
1921
+ ValueComponent,
1922
+ ReasonDialogComponent,
1923
+ ConcurrentDialogComponent,
1924
+ SaveSnackbarComponent,
1925
+ ExpandDialogComponent
1926
+ ],
1927
+ imports: [
1928
+ i5$1.CommonModule,
1929
+ i2.FormsModule,
1930
+ i2.ReactiveFormsModule,
1931
+ animations.BrowserAnimationsModule,
1932
+ i3.MatFormFieldModule,
1933
+ i4$2.MatOptionModule,
1934
+ i3$3.MatSelectModule,
1935
+ i4.MatButtonModule,
1936
+ i5.MatInputModule,
1937
+ i2$1.MatIconModule,
1938
+ i5$2.MatTooltipModule,
1939
+ i3$2.MatChipsModule,
1940
+ i4$1.MatAutocompleteModule,
1941
+ i8.DragDropModule,
1942
+ i3$1.RouterModule,
1943
+ i2$2.MatSnackBarModule,
1944
+ i1$1.MatDialogModule,
1945
+ menu.MatMenuModule,
1946
+ ngConfigcatPublicapi.ApiModule
1947
+ ],
1948
+ exports: [
1949
+ AuthorizationComponent,
1950
+ ProductSelectComponent,
1951
+ ConfigSelectComponent,
1952
+ EnvironmentSelectComponent,
1953
+ SettingSelectComponent,
1954
+ SettingItemComponent
1955
+ ]
1956
+ }]
1957
+ }], ctorParameters: function () { return []; } });
1785
1958
 
1786
1959
  /*
1787
1960
  * Public API Surface of ng-configcat-publicapi-ui
@@ -1799,22 +1972,8 @@
1799
1972
  exports.PublicApiService = PublicApiService;
1800
1973
  exports.SettingItemComponent = SettingItemComponent;
1801
1974
  exports.SettingSelectComponent = SettingSelectComponent;
1802
- exports.ɵa = BaseComponent;
1803
- exports.ɵb = PublicApiService;
1804
- exports.ɵc = Configuration;
1805
- exports.ɵd = PublicApiService;
1806
- exports.ɵe = SettingListComponent;
1807
- exports.ɵf = SettingListFormHelper;
1808
- exports.ɵg = SettingComponent;
1809
- exports.ɵh = RolloutPercentageItemsComponent;
1810
- exports.ɵi = RolloutRulesComponent;
1811
- exports.ɵj = ValueComponent;
1812
- exports.ɵk = ReasonDialogComponent;
1813
- exports.ɵl = ConcurrentDialogComponent;
1814
- exports.ɵm = SaveSnackbarComponent;
1815
- exports.ɵn = ExpandDialogComponent;
1816
1975
 
1817
1976
  Object.defineProperty(exports, '__esModule', { value: true });
1818
1977
 
1819
- })));
1978
+ }));
1820
1979
  //# sourceMappingURL=ng-configcat-publicapi-ui.umd.js.map