ng-configcat-publicapi-ui 3.0.8 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/esm2022/lib/_directives/input-display-normalizer.directive.mjs +38 -0
  2. package/esm2022/lib/_services/form-helper.mjs +104 -0
  3. package/{esm2020 → esm2022}/lib/_services/public-api.service.mjs +6 -6
  4. package/esm2022/lib/_services/setting-list-form-helper.mjs +171 -0
  5. package/esm2022/lib/authorization/authorization.component.mjs +62 -0
  6. package/{esm2020 → esm2022}/lib/base/base-select.component.mjs +4 -4
  7. package/{esm2020 → esm2022}/lib/base/base.component.mjs +5 -5
  8. package/{esm2020 → esm2022}/lib/configuration.mjs +4 -4
  9. package/{esm2020 → esm2022}/lib/dialogs/delete-setting-dialog/delete-setting-dialog.component.mjs +6 -6
  10. package/esm2022/lib/dialogs/expand-dialog/expand-dialog.component.mjs +80 -0
  11. package/esm2022/lib/dialogs/reason-dialog/reason-dialog.component.mjs +36 -0
  12. package/{esm2020 → esm2022}/lib/dialogs/save-snackbar/save-snackbar.component.mjs +5 -5
  13. package/esm2022/lib/ng-configcat-publicapi-ui.module.mjs +179 -0
  14. package/esm2022/lib/selects/config-select/config-select.component.mjs +60 -0
  15. package/esm2022/lib/selects/environment-select/environment-select.component.mjs +47 -0
  16. package/esm2022/lib/selects/product-select/product-select.component.mjs +40 -0
  17. package/esm2022/lib/selects/setting-select/setting-select.component.mjs +47 -0
  18. package/esm2022/lib/setting-item/setting-item.component.mjs +116 -0
  19. package/esm2022/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.mjs +81 -0
  20. package/esm2022/lib/setting-list/setting/rollout-rules/rollout-rules.component.mjs +293 -0
  21. package/{esm2020 → esm2022}/lib/setting-list/setting/setting.component.mjs +5 -5
  22. package/esm2022/lib/setting-list/setting/value/value.component.mjs +37 -0
  23. package/esm2022/lib/setting-list/setting-list.component.mjs +194 -0
  24. package/{fesm2020 → fesm2022}/ng-configcat-publicapi-ui.mjs +163 -163
  25. package/{fesm2020 → fesm2022}/ng-configcat-publicapi-ui.mjs.map +1 -1
  26. package/lib/_services/setting-list-form-helper.d.ts +1 -1
  27. package/lib/authorization/authorization.component.d.ts +1 -1
  28. package/lib/base/base-select.component.d.ts +1 -1
  29. package/lib/base/base.component.d.ts +1 -1
  30. package/lib/selects/config-select/config-select.component.d.ts +1 -1
  31. package/lib/selects/environment-select/environment-select.component.d.ts +1 -1
  32. package/lib/selects/product-select/product-select.component.d.ts +1 -1
  33. package/lib/selects/setting-select/setting-select.component.d.ts +1 -1
  34. package/lib/setting-item/setting-item.component.d.ts +1 -1
  35. package/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.d.ts +1 -1
  36. package/lib/setting-list/setting/rollout-rules/rollout-rules.component.d.ts +2 -2
  37. package/lib/setting-list/setting/setting.component.d.ts +1 -1
  38. package/lib/setting-list/setting/value/value.component.d.ts +1 -1
  39. package/lib/setting-list/setting-list.component.d.ts +1 -1
  40. package/package.json +9 -15
  41. package/public-api.scss +0 -1
  42. package/esm2020/lib/_directives/input-display-normalizer.directive.mjs +0 -38
  43. package/esm2020/lib/_services/form-helper.mjs +0 -104
  44. package/esm2020/lib/_services/setting-list-form-helper.mjs +0 -171
  45. package/esm2020/lib/authorization/authorization.component.mjs +0 -62
  46. package/esm2020/lib/dialogs/expand-dialog/expand-dialog.component.mjs +0 -80
  47. package/esm2020/lib/dialogs/reason-dialog/reason-dialog.component.mjs +0 -36
  48. package/esm2020/lib/ng-configcat-publicapi-ui.module.mjs +0 -179
  49. package/esm2020/lib/selects/config-select/config-select.component.mjs +0 -60
  50. package/esm2020/lib/selects/environment-select/environment-select.component.mjs +0 -47
  51. package/esm2020/lib/selects/product-select/product-select.component.mjs +0 -40
  52. package/esm2020/lib/selects/setting-select/setting-select.component.mjs +0 -47
  53. package/esm2020/lib/setting-item/setting-item.component.mjs +0 -116
  54. package/esm2020/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.mjs +0 -81
  55. package/esm2020/lib/setting-list/setting/rollout-rules/rollout-rules.component.mjs +0 -293
  56. package/esm2020/lib/setting-list/setting/value/value.component.mjs +0 -37
  57. package/esm2020/lib/setting-list/setting-list.component.mjs +0 -194
  58. package/fesm2015/ng-configcat-publicapi-ui.mjs +0 -1786
  59. package/fesm2015/ng-configcat-publicapi-ui.mjs.map +0 -1
  60. /package/{esm2020 → esm2022}/lib/_directives/index.mjs +0 -0
  61. /package/{esm2020 → esm2022}/lib/_models/deleteSettingModel.mjs +0 -0
  62. /package/{esm2020 → esm2022}/lib/_models/index.mjs +0 -0
  63. /package/{esm2020 → esm2022}/lib/_models/settingValuesModel.mjs +0 -0
  64. /package/{esm2020 → esm2022}/lib/_models/updateSettingValuesModel.mjs +0 -0
  65. /package/{esm2020 → esm2022}/lib/_services/index.mjs +0 -0
  66. /package/{esm2020 → esm2022}/lib/_services/platform-helper.mjs +0 -0
  67. /package/{esm2020 → esm2022}/ng-configcat-publicapi-ui.mjs +0 -0
  68. /package/{esm2020 → esm2022}/public-api.mjs +0 -0
@@ -1,1786 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { Injectable, Optional, Component, Input, Inject, Directive, HostListener, EventEmitter, Output, forwardRef, NgModule } from '@angular/core';
3
- import { MeService, Configuration as Configuration$1, ProductsService, ConfigsService, EnvironmentsService, FeatureFlagsSettingsService, FeatureFlagSettingValuesService, IntegrationLinksService, SegmentsService, SettingType, RolloutRuleComparator, SegmentComparator, ApiModule } from 'ng-configcat-publicapi';
4
- import * as i1 from '@angular/common/http';
5
- import { HttpErrorResponse } from '@angular/common/http';
6
- import { forkJoin, throwError, of } from 'rxjs';
7
- import { map, catchError } from 'rxjs/operators';
8
- import * as i2 from '@angular/forms';
9
- import { Validators, NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule } from '@angular/forms';
10
- import * as i1$1 from '@angular/material/dialog';
11
- import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
12
- import * as i2$1 from '@angular/common';
13
- import { CommonModule } from '@angular/common';
14
- import * as i4 from '@angular/material/form-field';
15
- import { MatFormFieldModule } from '@angular/material/form-field';
16
- import * as i5 from '@angular/material/button';
17
- import { MatButtonModule } from '@angular/material/button';
18
- import * as i6 from '@angular/material/input';
19
- import { MatInputModule } from '@angular/material/input';
20
- import * as i2$2 from '@angular/material/snack-bar';
21
- import { MatSnackBarModule } from '@angular/material/snack-bar';
22
- import * as i7 from '@angular/material/icon';
23
- import { MatIconModule } from '@angular/material/icon';
24
- import * as i7$1 from '@angular/material/tooltip';
25
- import { MatTooltipModule, MAT_TOOLTIP_DEFAULT_OPTIONS } from '@angular/material/tooltip';
26
- import * as i5$1 from '@angular/material/chips';
27
- import { MatChipsModule } from '@angular/material/chips';
28
- import * as i11 from '@angular/cdk/drag-drop';
29
- import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
30
- import { valid } from 'semver';
31
- import * as i5$2 from '@angular/material/core';
32
- import { MatOptionModule } from '@angular/material/core';
33
- import * as i10 from '@angular/material/autocomplete';
34
- import { MatAutocompleteModule } from '@angular/material/autocomplete';
35
- import * as i6$1 from '@angular/material/select';
36
- import { MatSelectModule } from '@angular/material/select';
37
- import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
38
- import { RouterModule } from '@angular/router';
39
- import { MatMenuModule } from '@angular/material/menu';
40
-
41
- class Configuration {
42
- constructor() {
43
- this.basePath = 'https://api.configcat.com';
44
- this.dashboardBasePath = 'https://app.configcat.com';
45
- }
46
- }
47
- Configuration.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: Configuration, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
48
- Configuration.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: Configuration });
49
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: Configuration, decorators: [{
50
- type: Injectable
51
- }] });
52
-
53
- class PublicApiService {
54
- constructor(httpClient, configuration) {
55
- this.httpClient = httpClient;
56
- this.configuration = configuration;
57
- }
58
- createMeService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
59
- var _a, _b, _c;
60
- return new MeService(this.httpClient, basePath !== null && basePath !== void 0 ? basePath : (_a = this.configuration) === null || _a === void 0 ? void 0 : _a.basePath, new Configuration$1({
61
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
62
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
63
- }));
64
- }
65
- createProductsService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
66
- var _a, _b, _c;
67
- return new ProductsService(this.httpClient, basePath !== null && basePath !== void 0 ? basePath : (_a = this.configuration) === null || _a === void 0 ? void 0 : _a.basePath, new Configuration$1({
68
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
69
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
70
- }));
71
- }
72
- createConfigsService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
73
- var _a, _b, _c;
74
- return new ConfigsService(this.httpClient, basePath !== null && basePath !== void 0 ? basePath : (_a = this.configuration) === null || _a === void 0 ? void 0 : _a.basePath, new Configuration$1({
75
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
76
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
77
- }));
78
- }
79
- createEnvironmentsService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
80
- var _a, _b, _c;
81
- return new EnvironmentsService(this.httpClient, basePath !== null && basePath !== void 0 ? basePath : (_a = this.configuration) === null || _a === void 0 ? void 0 : _a.basePath, new Configuration$1({
82
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
83
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
84
- }));
85
- }
86
- createSettingsService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
87
- var _a, _b, _c;
88
- return new FeatureFlagsSettingsService(this.httpClient, basePath !== null && basePath !== void 0 ? basePath : (_a = this.configuration) === null || _a === void 0 ? void 0 : _a.basePath, new Configuration$1({
89
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
90
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
91
- }));
92
- }
93
- createSettingValuesService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
94
- var _a, _b, _c;
95
- return new FeatureFlagSettingValuesService(this.httpClient, basePath !== null && basePath !== void 0 ? basePath : (_a = this.configuration) === null || _a === void 0 ? void 0 : _a.basePath, new Configuration$1({
96
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
97
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
98
- }));
99
- }
100
- createIntegrationLinksService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
101
- var _a, _b, _c;
102
- return new IntegrationLinksService(this.httpClient, basePath !== null && basePath !== void 0 ? basePath : (_a = this.configuration) === null || _a === void 0 ? void 0 : _a.basePath, new Configuration$1({
103
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
104
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
105
- }));
106
- }
107
- createSegmentsService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
108
- var _a, _b, _c;
109
- return new SegmentsService(this.httpClient, basePath !== null && basePath !== void 0 ? basePath : (_a = this.configuration) === null || _a === void 0 ? void 0 : _a.basePath, new Configuration$1({
110
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
111
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
112
- }));
113
- }
114
- getDashboardBasePath() {
115
- var _a, _b;
116
- return (_b = (_a = this.configuration) === null || _a === void 0 ? void 0 : _a.dashboardBasePath) !== null && _b !== void 0 ? _b : 'https://app.configcat.com';
117
- }
118
- }
119
- PublicApiService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PublicApiService, deps: [{ token: i1.HttpClient }, { token: Configuration, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
120
- PublicApiService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PublicApiService, providedIn: 'root' });
121
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PublicApiService, decorators: [{
122
- type: Injectable,
123
- args: [{ providedIn: 'root' }]
124
- }], ctorParameters: function () {
125
- return [{ type: i1.HttpClient }, { type: Configuration, decorators: [{
126
- type: Optional
127
- }] }];
128
- } });
129
-
130
- class BaseComponent {
131
- constructor(publicApiService) {
132
- this.publicApiService = publicApiService;
133
- this.basePath = null;
134
- this.basicAuthUsername = null;
135
- this.basicAuthPassword = null;
136
- }
137
- createProductsService() {
138
- return this.publicApiService.createProductsService(this.basicAuthUsername, this.basicAuthPassword, this.basePath);
139
- }
140
- createConfigsService() {
141
- return this.publicApiService.createConfigsService(this.basicAuthUsername, this.basicAuthPassword, this.basePath);
142
- }
143
- createEnvironmentsService() {
144
- return this.publicApiService.createEnvironmentsService(this.basicAuthUsername, this.basicAuthPassword, this.basePath);
145
- }
146
- createSettingsService() {
147
- return this.publicApiService.createSettingsService(this.basicAuthUsername, this.basicAuthPassword, this.basePath);
148
- }
149
- createSettingValuesService() {
150
- return this.publicApiService.createSettingValuesService(this.basicAuthUsername, this.basicAuthPassword, this.basePath);
151
- }
152
- createSegmentsService() {
153
- return this.publicApiService.createSegmentsService(this.basicAuthUsername, this.basicAuthPassword, this.basePath);
154
- }
155
- }
156
- BaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: BaseComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
157
- BaseComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: BaseComponent, selector: "base", inputs: { basePath: "basePath", basicAuthUsername: "basicAuthUsername", basicAuthPassword: "basicAuthPassword" }, ngImport: i0, template: '<div></div>', isInline: true });
158
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: BaseComponent, decorators: [{
159
- type: Component,
160
- args: [{
161
- selector: 'base',
162
- template: '<div></div>'
163
- }]
164
- }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { basePath: [{
165
- type: Input
166
- }], basicAuthUsername: [{
167
- type: Input
168
- }], basicAuthPassword: [{
169
- type: Input
170
- }] } });
171
-
172
- class PlatformHelper {
173
- static isChromium() {
174
- // https://stackoverflow.com/a/62797156/8656352
175
- return !!window.chrome;
176
- }
177
- }
178
-
179
- class FormHelper {
180
- static getErrorMessage(control, hint = '') {
181
- if (!control || control.valid) {
182
- return;
183
- }
184
- if (control.hasError('required')) {
185
- return `${hint} The field is required.`;
186
- }
187
- if (control.hasError('pattern')) {
188
- return 'Not a valid e-mail address.';
189
- }
190
- if (control.hasError('minlength')) {
191
- return 'The field must be at least ' + control.getError('minlength').requiredLength + ' characters long';
192
- }
193
- if (control.hasError('maxlength')) {
194
- return 'The field must be at max ' + control.getError('maxlength').requiredLength + ' characters long';
195
- }
196
- return;
197
- }
198
- static handleErrors(formGroup, error) {
199
- var _a, _b, _c, _d, _e, _f;
200
- if (error instanceof HttpErrorResponse) {
201
- const response = error;
202
- switch (response.status) {
203
- case 400:
204
- let unknownFieldName = false;
205
- for (const fieldName in error.error) {
206
- if (error.error.hasOwnProperty(fieldName) && error.error[fieldName] &&
207
- (((_a = error.error[fieldName]) === null || _a === void 0 ? void 0 : _a.length) > 0 || ((_c = (_b = error.error[fieldName]) === null || _b === void 0 ? void 0 : _b.Errors) === null || _c === void 0 ? void 0 : _c.length) > 0)) {
208
- let jsonFieldName = fieldName;
209
- if (jsonFieldName.length > 0) {
210
- jsonFieldName = jsonFieldName[0].toLowerCase() + jsonFieldName.slice(1);
211
- }
212
- const errorMessage = ((_e = (_d = error.error[fieldName]) === null || _d === void 0 ? void 0 : _d.Errors) === null || _e === void 0 ? void 0 : _e.length) > 0 ?
213
- ((_f = error.error[fieldName]) === null || _f === void 0 ? void 0 : _f.Errors.map((e) => e.ErrorMessage)).join(', ')
214
- : error.error[fieldName];
215
- if (formGroup.controls.hasOwnProperty(jsonFieldName)) {
216
- formGroup.controls[jsonFieldName].setErrors({ serverSide: errorMessage });
217
- }
218
- else {
219
- unknownFieldName = true;
220
- }
221
- }
222
- }
223
- if (unknownFieldName) {
224
- formGroup.setErrors({ serverSide: 'Something went wrong.' });
225
- }
226
- break;
227
- // in these cases we do not show errors on the form, they're handled by the http
228
- // interceptor in src\app\_interceptors\httpstatuscode.interceptor.ts
229
- case 402:
230
- case 429:
231
- return;
232
- }
233
- }
234
- else {
235
- formGroup.setErrors({ serverSide: 'Something went wrong on our side. This is not your fault. Please try again.' });
236
- }
237
- }
238
- /**
239
- * Converts a value representing a number to a `number` value.
240
- * Returns `NaN` in the case of non-numerical values.
241
- */
242
- static normalizeNumber(value) {
243
- switch (typeof value) {
244
- case "number":
245
- return value;
246
- case "string":
247
- // NOTE: `Number()` converts whitespace strings to 0.
248
- return value.trim() === '' ? NaN : Number(value);
249
- case "bigint":
250
- return Number(value);
251
- default:
252
- return NaN;
253
- }
254
- }
255
- /**
256
- * Converts a value representing a number to the normalized `string`
257
- * representation of the number. (e.g. `.1` --> `'0.1'`, `3.14e2` --> `'314'`).
258
- * Returns `''` in the case of non-numerical values or non-finite numerical values.
259
- */
260
- static normalizeNumberStoredAsString(value) {
261
- value = FormHelper.normalizeNumber(value);
262
- // NOTE: `NaN` is not considered finite.
263
- return isFinite(value) ? value + '' : '';
264
- }
265
- static formatNumberForDisplay(value) {
266
- if (!isFinite(value)) {
267
- return '';
268
- }
269
- // Chromium-based browsers don't respect the `lang` attribute,
270
- // they use a display format corresponding to the browser's language setting.
271
- if (PlatformHelper.isChromium()) {
272
- return value.toLocaleString();
273
- }
274
- // Firefox (and probably other browsers) respect the `lang` attribute,
275
- // which is currently set to the fixed value of "en" (see index.html),
276
- // so in these cases dot should be used as the decimal separator.
277
- // (In case localization is implemented in the application, this logic should be revised!)
278
- return value + '';
279
- }
280
- }
281
-
282
- class ReasonDialogComponent {
283
- constructor(dialogRef, formBuilder) {
284
- this.dialogRef = dialogRef;
285
- this.formBuilder = formBuilder;
286
- }
287
- ngOnInit() {
288
- this.formGroup = this.formBuilder.group({
289
- reason: ['', [Validators.required, Validators.maxLength(1000)]]
290
- });
291
- }
292
- handleSaveButton() {
293
- if (!this.formGroup.valid) {
294
- return;
295
- }
296
- this.dialogRef.close({ button: 'save', reason: this.formGroup.controls.reason.value });
297
- }
298
- cancel() {
299
- this.dialogRef.close({ button: 'cancel' });
300
- }
301
- }
302
- ReasonDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ReasonDialogComponent, deps: [{ token: i1$1.MatDialogRef }, { token: i2.UntypedFormBuilder }], target: i0.ɵɵFactoryTarget.Component });
303
- ReasonDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ReasonDialogComponent, selector: "configcat-reason-dialog", ngImport: i0, template: "<h1 mat-dialog-title>Add notes</h1>\n<form [formGroup]=\"formGroup\" (ngSubmit)=\"handleSaveButton()\">\n <div mat-dialog-content class=\"container\">\n <p>This will appear in the Why column of the Audit Log.</p>\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 <div mat-dialog-actions>\n <button type=\"submit\" style=\"margin-right: 10px;\" mat-flat-button color=\"primary\">Add notes & Save</button>\n <button type=\"button\" mat-stroked-button (click)=\"cancel()\">Cancel</button>\n </div>\n</form>", styles: [".container>*{width:100%}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i5.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i1$1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }] });
304
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ReasonDialogComponent, decorators: [{
305
- type: Component,
306
- args: [{ selector: 'configcat-reason-dialog', template: "<h1 mat-dialog-title>Add notes</h1>\n<form [formGroup]=\"formGroup\" (ngSubmit)=\"handleSaveButton()\">\n <div mat-dialog-content class=\"container\">\n <p>This will appear in the Why column of the Audit Log.</p>\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 <div mat-dialog-actions>\n <button type=\"submit\" style=\"margin-right: 10px;\" mat-flat-button color=\"primary\">Add notes & Save</button>\n <button type=\"button\" mat-stroked-button (click)=\"cancel()\">Cancel</button>\n </div>\n</form>", styles: [".container>*{width:100%}\n"] }]
307
- }], ctorParameters: function () { return [{ type: i1$1.MatDialogRef }, { type: i2.UntypedFormBuilder }]; } });
308
-
309
- class SaveSnackbarComponent {
310
- constructor() { }
311
- ngOnInit() {
312
- }
313
- }
314
- SaveSnackbarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SaveSnackbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
315
- SaveSnackbarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: SaveSnackbarComponent, selector: "configcat-save-snackbar", ngImport: i0, template: "<p class=\"header\">Settings saved successfully.</p>", styles: ["p{text-align:center;font-weight:700}.header{font-size:1.2em}\n"] });
316
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SaveSnackbarComponent, decorators: [{
317
- type: Component,
318
- args: [{ selector: 'configcat-save-snackbar', template: "<p class=\"header\">Settings saved successfully.</p>", styles: ["p{text-align:center;font-weight:700}.header{font-size:1.2em}\n"] }]
319
- }], ctorParameters: function () { return []; } });
320
-
321
- class SettingListFormHelper {
322
- constructor(formBuilder) {
323
- this.formBuilder = formBuilder;
324
- }
325
- createSettingValuesFormGroup(settingValuesModel) {
326
- const formGroup = this.formBuilder.group({
327
- settingValues: this.formBuilder.array(settingValuesModel.settingValues.map(sv => {
328
- return this.createSettingValueFormGroup(sv, settingValuesModel.readOnly);
329
- })),
330
- // Decorator
331
- environment: this.formBuilder.group({
332
- environmentId: [{ value: settingValuesModel.environment.environmentId, disabled: true }],
333
- name: [{ value: settingValuesModel.environment.name, disabled: true }],
334
- }),
335
- comparisonAttributes: [[]]
336
- });
337
- const rolloutRules = this.getAllRolloutRules(formGroup);
338
- const comparisonAttributes = this.getComparisonAttributes(rolloutRules);
339
- formGroup.patchValue({ comparisonAttributes: comparisonAttributes });
340
- return formGroup;
341
- }
342
- createSettingValueFormGroup(settingValueModel, readOnly) {
343
- if (!settingValueModel.setting) {
344
- return this.formBuilder.group({});
345
- }
346
- return this.formBuilder.group({
347
- settingId: [settingValueModel.setting.settingId],
348
- value: [
349
- { value: settingValueModel.value, disabled: readOnly },
350
- this.getValidatorsForSettingType(settingValueModel.setting.settingType)
351
- ],
352
- rolloutPercentageItems: settingValueModel.rolloutPercentageItems
353
- ? this.formBuilder.array(settingValueModel.rolloutPercentageItems.map(p => {
354
- // @ts-ignore()
355
- return this.createRolloutPercentageItemFormGroup(p, readOnly, settingValueModel.setting.settingType);
356
- }))
357
- : this.formBuilder.array([]), rolloutRules: settingValueModel.rolloutRules
358
- ? this.formBuilder.array(settingValueModel.rolloutRules.map(r => {
359
- // @ts-ignore()
360
- return this.createRolloutRuleFormGroup(r, readOnly, settingValueModel.setting.settingType);
361
- }))
362
- : this.formBuilder.array([]),
363
- updatedAt: [{ value: settingValueModel.updatedAt, disabled: true }],
364
- lastUpdaterUserEmail: [{ value: settingValueModel.lastUpdaterUserEmail, disabled: true }],
365
- lastUpdaterUserFullName: [{ value: settingValueModel.lastUpdaterUserFullName, disabled: true }],
366
- rolloutPercentageItemsSum: [{ value: 100, disabled: false }, [Validators.min(100), Validators.max(100)]],
367
- // Decoration
368
- setting: this.formBuilder.group({
369
- settingId: [{ value: settingValueModel.setting.settingId, disabled: true }],
370
- key: [{ value: settingValueModel.setting.key, disabled: true }],
371
- name: [{ value: settingValueModel.setting.name, disabled: true }],
372
- hint: [{ value: settingValueModel.setting.hint, disabled: true }],
373
- settingType: [{ value: settingValueModel.setting.settingType, disabled: true }],
374
- creatorEmail: [{ value: settingValueModel.setting.creatorEmail, disabled: true }],
375
- creatorFullName: [{ value: settingValueModel.setting.creatorFullName, disabled: true }],
376
- createdAt: [{ value: settingValueModel.setting.createdAt, disabled: true }]
377
- }),
378
- integrationLinks: settingValueModel.integrationLinks ? this.formBuilder.array(settingValueModel.integrationLinks.map(il => {
379
- return this.formBuilder.group({
380
- key: [{ value: il.key, disabled: true }],
381
- description: [{ value: il.description, disabled: true }],
382
- integrationLinkType: [{ value: il.integrationLinkType, disabled: true }],
383
- url: [{ value: il.url, disabled: true }],
384
- });
385
- })) : this.formBuilder.array([])
386
- });
387
- }
388
- createRolloutPercentageItemFormGroup(p, readOnly, settingType) {
389
- return this.formBuilder.group({
390
- percentage: [{ value: p.percentage, disabled: readOnly }, [Validators.required, Validators.min(0), Validators.max(100)]],
391
- value: [
392
- { value: p.value, disabled: readOnly },
393
- this.getValidatorsForSettingType(settingType)
394
- ],
395
- valueDisabled: [
396
- { value: p.value, disabled: true }, // For percentage item value
397
- ]
398
- });
399
- }
400
- createRolloutRuleFormGroup(r, readOnly, settingType) {
401
- if (r.comparator) {
402
- return this.formBuilder.group({
403
- type: [{ value: 0, disabled: true }],
404
- comparisonAttribute: [{ value: r.comparisonAttribute, disabled: readOnly }, [Validators.required]],
405
- comparator: [{ value: r.comparator, disabled: readOnly }, [Validators.required]],
406
- comparisonValue: [{ value: r.comparisonValue, disabled: readOnly }, [Validators.required]],
407
- value: [
408
- { value: r.value, disabled: readOnly },
409
- this.getValidatorsForSettingType(settingType)
410
- ],
411
- });
412
- }
413
- else if (r.segmentComparator) {
414
- return this.formBuilder.group({
415
- type: [{ value: 1, disabled: true }],
416
- segmentComparator: [{ value: r.segmentComparator, disabled: readOnly }, [Validators.required]],
417
- segmentId: [{ value: r.segmentId, disabled: readOnly }, [Validators.required]],
418
- value: [
419
- { value: r.value, disabled: readOnly },
420
- this.getValidatorsForSettingType(settingType)
421
- ],
422
- });
423
- }
424
- else {
425
- throw new Error('Invalid rollout rule');
426
- }
427
- }
428
- getValidatorsForSettingType(settingType) {
429
- switch (settingType) {
430
- case SettingType.Int:
431
- return [Validators.required,
432
- Validators.min(-2147483648), Validators.max(2147483647), Validators.pattern('^[-+]?[0-9]\\d*$')];
433
- case SettingType.Double:
434
- return [Validators.required, Validators.min(-1.79769313486232E+308), Validators.max(1.79769313486232E+308)];
435
- case SettingType.String:
436
- case SettingType.Boolean:
437
- return [Validators.required];
438
- default:
439
- return [];
440
- }
441
- }
442
- getAllRolloutRules(formGroup) {
443
- const settingValues = formGroup.get('settingValues');
444
- const rolloutRules = settingValues.controls.map(cv => cv.get('rolloutRules').value);
445
- return rolloutRules.length === 0 ? rolloutRules : rolloutRules.reduce((a, b) => a.concat(b));
446
- }
447
- getComparisonAttributes(rolloutRules) {
448
- if (rolloutRules.length > 0) {
449
- const currentComparisonAttributes = rolloutRules.map(r => r.comparisonAttribute);
450
- const defaultComparisonAttributes = ['Identifier', 'Email', 'Country'];
451
- const comparisonAttributes = currentComparisonAttributes.filter(c => defaultComparisonAttributes.indexOf(c) === -1);
452
- return Array.from(new Set(comparisonAttributes));
453
- }
454
- else {
455
- return [];
456
- }
457
- }
458
- getComparisonValueType(comparator) {
459
- switch (comparator) {
460
- case RolloutRuleComparator.NumberEquals:
461
- case RolloutRuleComparator.NumberDoesNotEqual:
462
- case RolloutRuleComparator.NumberLess:
463
- case RolloutRuleComparator.NumberLessOrEquals:
464
- case RolloutRuleComparator.NumberGreater:
465
- case RolloutRuleComparator.NumberGreaterOrEquals:
466
- return 'number';
467
- default:
468
- return 'text';
469
- }
470
- }
471
- normalizeComparisonValue(comparator, comparisonValue) {
472
- // In the case of number inputs value is a number but API expects
473
- // a string, so we need to make sure that it's converted to string.
474
- return comparator && this.getComparisonValueType(comparator) === "number"
475
- ? FormHelper.normalizeNumberStoredAsString(comparisonValue)
476
- : comparisonValue;
477
- }
478
- }
479
- SettingListFormHelper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SettingListFormHelper, deps: [{ token: i2.UntypedFormBuilder }], target: i0.ɵɵFactoryTarget.Injectable });
480
- SettingListFormHelper.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SettingListFormHelper, providedIn: 'root' });
481
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SettingListFormHelper, decorators: [{
482
- type: Injectable,
483
- args: [{ providedIn: 'root' }]
484
- }], ctorParameters: function () { return [{ type: i2.UntypedFormBuilder }]; } });
485
-
486
- class ExpandDialogComponent {
487
- constructor(dialogRef, formBuilder, data) {
488
- this.dialogRef = dialogRef;
489
- this.formBuilder = formBuilder;
490
- this.data = data;
491
- this.readOnly = false;
492
- }
493
- ngOnInit() {
494
- this.readOnly = this.data.control.disabled;
495
- if (this.data.multiline) {
496
- this.buildFormGroup();
497
- }
498
- else {
499
- this.formControlSubscription = this.data.control.valueChanges.subscribe((value) => {
500
- this.data.control.setValue(value, { onlySelf: true, emitEvent: false, emitModelToViewChange: true });
501
- this.data.control.markAsDirty();
502
- }, () => { }, () => { });
503
- }
504
- }
505
- values() {
506
- return this.formGroup.get('values');
507
- }
508
- getValueControls() {
509
- return this.values().controls.map(c => c);
510
- }
511
- buildFormGroup() {
512
- const value = this.data.control.value ? this.data.control.value : '';
513
- const list = value.split(',').map((v) => v.trim()).filter((v) => !!v);
514
- this.formGroup = this.formBuilder.group({
515
- values: this.formBuilder.array(list.map((v) => this.formBuilder.control({ value: v, disabled: this.data.control.disabled })))
516
- });
517
- this.formGroupSubscription = this.formGroup.valueChanges.subscribe((formGroupValue) => {
518
- this.data.control.setValue(formGroupValue.values
519
- .filter((v) => !!v)
520
- .join(','), { onlySelf: true, emitEvent: false, emitModelToViewChange: true });
521
- this.data.control.updateValueAndValidity();
522
- this.data.control.markAsDirty();
523
- });
524
- }
525
- add() {
526
- this.formGroup.controls.values.push(this.formBuilder.control(''));
527
- }
528
- remove(index) {
529
- this.formGroup.controls.values.removeAt(index);
530
- }
531
- ngOnDestroy() {
532
- if (this.formControlSubscription) {
533
- this.formControlSubscription.unsubscribe();
534
- this.formControlSubscription = null;
535
- }
536
- if (this.formGroupSubscription) {
537
- this.formGroupSubscription.unsubscribe();
538
- this.formGroupSubscription = null;
539
- }
540
- }
541
- close() {
542
- this.dialogRef.close();
543
- }
544
- }
545
- ExpandDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ExpandDialogComponent, deps: [{ token: i1$1.MatDialogRef }, { token: i2.UntypedFormBuilder }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
546
- ExpandDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ExpandDialogComponent, selector: "configcat-expand-dialog", ngImport: i0, template: "<div mat-dialog-content class=\"container\">\n <mat-form-field appearance=\"outline\" *ngIf=\"!data.multiline\" subscriptSizing=\"dynamic\">\n <mat-label></mat-label>\n <textarea matInput [formControl]=\"data.control\" rows=\"10\"></textarea>\n </mat-form-field>\n <div [formGroup]=\"formGroup\" *ngIf=\"data.multiline\">\n <div *ngFor=\"let valueControl of getValueControls(); let i = index;\" class=\"value-field\">\n <mat-form-field appearance=\"outline\">\n <input matInput [formControl]=\"valueControl\" />\n </mat-form-field>\n <button (click)=\"remove(i)\" mat-icon-button type=\"button\" class=\"no-density-mat-icon-button\"\n matTooltip=\"Remove item\" *ngIf=\"!readOnly\">\n <mat-icon>delete_outline</mat-icon>\n </button>\n </div>\n <button (click)=\"add()\" mat-stroked-button type=\"button\" *ngIf=\"!readOnly\">\n <mat-icon>add</mat-icon>Add item\n </button>\n </div>\n</div>\n<div mat-dialog-actions>\n <button type=\"button\" mat-flat-button color=\"primary\" (click)=\"close()\">Done</button>\n</div>", styles: [".container>*{width:100%}.container>* .value-field{display:flex;font-size:12px;flex-wrap:nowrap}.container>* .value-field mat-form-field{flex-grow:1}.container>* .no-density-mat-icon-button{width:48px;height:48px;padding:12px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: i1$1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }] });
547
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ExpandDialogComponent, decorators: [{
548
- type: Component,
549
- args: [{ selector: 'configcat-expand-dialog', template: "<div mat-dialog-content class=\"container\">\n <mat-form-field appearance=\"outline\" *ngIf=\"!data.multiline\" subscriptSizing=\"dynamic\">\n <mat-label></mat-label>\n <textarea matInput [formControl]=\"data.control\" rows=\"10\"></textarea>\n </mat-form-field>\n <div [formGroup]=\"formGroup\" *ngIf=\"data.multiline\">\n <div *ngFor=\"let valueControl of getValueControls(); let i = index;\" class=\"value-field\">\n <mat-form-field appearance=\"outline\">\n <input matInput [formControl]=\"valueControl\" />\n </mat-form-field>\n <button (click)=\"remove(i)\" mat-icon-button type=\"button\" class=\"no-density-mat-icon-button\"\n matTooltip=\"Remove item\" *ngIf=\"!readOnly\">\n <mat-icon>delete_outline</mat-icon>\n </button>\n </div>\n <button (click)=\"add()\" mat-stroked-button type=\"button\" *ngIf=\"!readOnly\">\n <mat-icon>add</mat-icon>Add item\n </button>\n </div>\n</div>\n<div mat-dialog-actions>\n <button type=\"button\" mat-flat-button color=\"primary\" (click)=\"close()\">Done</button>\n</div>", styles: [".container>*{width:100%}.container>* .value-field{display:flex;font-size:12px;flex-wrap:nowrap}.container>* .value-field mat-form-field{flex-grow:1}.container>* .no-density-mat-icon-button{width:48px;height:48px;padding:12px}\n"] }]
550
- }], ctorParameters: function () {
551
- return [{ type: i1$1.MatDialogRef }, { type: i2.UntypedFormBuilder }, { type: undefined, decorators: [{
552
- type: Inject,
553
- args: [MAT_DIALOG_DATA]
554
- }] }];
555
- } });
556
-
557
- /**
558
- * Makes sure that values entered into HTML input fields are displayed in the correct format,
559
- * where correct means normalized (e.g. `'.10'` --> `'0.1'`) and corresponding to the locale setting.
560
- *
561
- * The format is adjusted on the blur event. Only the format of number inputs is adjusted currently.
562
- */
563
- class InputDisplayNormalizerDirective {
564
- constructor() { }
565
- onChange($event) {
566
- const target = $event.target;
567
- if (target.type === 'number') {
568
- let value = target.value;
569
- value = value.trim() !== '' ? Number(value) : NaN;
570
- if (isFinite(value)) {
571
- // The string returned by the `value` property and the string displayed in the input field are not necessarily equal.
572
- // HACK: When the returned and the displayed value differs only in the decimal separator,
573
- // Chrome won't update the displayed value unless the value is changed first...
574
- target.value = '';
575
- target.value = value;
576
- }
577
- }
578
- }
579
- }
580
- InputDisplayNormalizerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputDisplayNormalizerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
581
- InputDisplayNormalizerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: InputDisplayNormalizerDirective, selector: "input[inputDisplayNormalizer]", host: { listeners: { "blur": "onChange($event)" } }, ngImport: i0 });
582
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputDisplayNormalizerDirective, decorators: [{
583
- type: Directive,
584
- args: [{
585
- // eslint-disable-next-line @angular-eslint/directive-selector
586
- selector: 'input[inputDisplayNormalizer]'
587
- }]
588
- }], ctorParameters: function () { return []; }, propDecorators: { onChange: [{
589
- type: HostListener,
590
- args: ['blur', ['$event']]
591
- }] } });
592
-
593
- class ValueComponent {
594
- constructor(dialog) {
595
- this.dialog = dialog;
596
- this.SettingType = SettingType;
597
- }
598
- popOut() {
599
- this.dialog.open(ExpandDialogComponent, {
600
- width: '640px',
601
- data: { control: this.valueFormControl }
602
- });
603
- }
604
- formatDecimalNumber(value) {
605
- return FormHelper.formatNumberForDisplay(value);
606
- }
607
- }
608
- ValueComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ValueComponent, deps: [{ token: i1$1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
609
- ValueComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ValueComponent, selector: "configcat-value", inputs: { valueFormControl: "valueFormControl", setting: "setting" }, ngImport: i0, template: "<div class=\"flex\">\n <div class=\"container\" [ngSwitch]=\"setting.settingType\">\n <div *ngSwitchCase=\"SettingType.String\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"text\"\n [formControl]=\"valueFormControl\" placeholder=\"my value\" name=\"value\">\n <div class=\"expand\" (click)=\"popOut()\" matTooltip=\"Pop-out Editor\">\n <mat-icon>height</mat-icon>\n </div>\n </div>\n <div *ngSwitchCase=\"SettingType.Int\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"number\" [formControl]=\"valueFormControl\"\n placeholder=\"42\" name=\"value\" />\n </div>\n <div *ngSwitchCase=\"SettingType.Double\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"number\" [formControl]=\"valueFormControl\"\n placeholder=\"{{ formatDecimalNumber(3.14) }}\" name=\"value\" inputDisplayNormalizer>\n </div>\n <div *ngSwitchCase=\"SettingType.Boolean\" class=\"toggle\">\n <label class=\"switch\">\n <input type=\"checkbox\" [formControl]=\"valueFormControl\" name=\"value\" />\n <span class=\"slider round\"></span>\n </label>\n </div>\n </div>\n <div *ngIf=\"setting.settingType === SettingType.Boolean\" class=\"spacer\"></div>\n\n</div>\n", styles: [".switch{position:relative;width:66px;height:30px;margin-left:4px;margin-top:0;margin-bottom:0}.switch input{display:none}.slider{position:absolute;cursor:pointer;inset:0;background-color:#ff5252;transition:.4s;width:66px;height:30px}.slider:before{position:absolute;content:\"\";height:22px;width:22px;left:4px;bottom:4px;background-color:#fff;transition:.4s}input:checked+.slider{background-color:#9acd32}input:focus+.slider{box-shadow:0 0 1px #9acd32}input:checked+.slider:before{transform:translate(36px)}.slider.round{border-radius:34px}.slider.round:before{border-radius:50%}.slider:after{content:\"Off\";color:#fff;display:block;position:absolute;transform:translate(-14%,-50%);top:50%;left:50%;font-size:10px;font-family:Verdana,sans-serif}input:checked+.slider:after{content:\"On\";transform:translate(-91%,-50%)}\n", ".flex{display:flex;margin-right:10px;align-items:center}.flex .spacer{min-width:15px}.flex .container .with-validation{display:flex;flex-wrap:nowrap}.flex .container .toggle{width:66px;height:30px}.flex .container input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;padding:0 30px 0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300;min-width:150px;margin:0 3px}.flex .container input[type=number]{padding:0 2px 0 5px}.flex .container .invalid{border:1px solid #ff5252}.flex .container .error{color:#ff5252;margin-right:5px}.flex .variationId{margin:0 4px 0 5px;cursor:pointer;color:#888;display:flex;align-items:center}.flex .expand{position:relative;top:2px;height:24px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.flex .expand mat-icon{transform:rotate(45deg)}@media (max-width: 920px){.flex{margin-right:0!important}.flex .spacer{min-width:5px}}@media (max-width: 510px){.flex .container .error{display:none}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: InputDisplayNormalizerDirective, selector: "input[inputDisplayNormalizer]" }] });
610
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ValueComponent, decorators: [{
611
- type: Component,
612
- args: [{ selector: 'configcat-value', template: "<div class=\"flex\">\n <div class=\"container\" [ngSwitch]=\"setting.settingType\">\n <div *ngSwitchCase=\"SettingType.String\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"text\"\n [formControl]=\"valueFormControl\" placeholder=\"my value\" name=\"value\">\n <div class=\"expand\" (click)=\"popOut()\" matTooltip=\"Pop-out Editor\">\n <mat-icon>height</mat-icon>\n </div>\n </div>\n <div *ngSwitchCase=\"SettingType.Int\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"number\" [formControl]=\"valueFormControl\"\n placeholder=\"42\" name=\"value\" />\n </div>\n <div *ngSwitchCase=\"SettingType.Double\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"number\" [formControl]=\"valueFormControl\"\n placeholder=\"{{ formatDecimalNumber(3.14) }}\" name=\"value\" inputDisplayNormalizer>\n </div>\n <div *ngSwitchCase=\"SettingType.Boolean\" class=\"toggle\">\n <label class=\"switch\">\n <input type=\"checkbox\" [formControl]=\"valueFormControl\" name=\"value\" />\n <span class=\"slider round\"></span>\n </label>\n </div>\n </div>\n <div *ngIf=\"setting.settingType === SettingType.Boolean\" class=\"spacer\"></div>\n\n</div>\n", styles: [".switch{position:relative;width:66px;height:30px;margin-left:4px;margin-top:0;margin-bottom:0}.switch input{display:none}.slider{position:absolute;cursor:pointer;inset:0;background-color:#ff5252;transition:.4s;width:66px;height:30px}.slider:before{position:absolute;content:\"\";height:22px;width:22px;left:4px;bottom:4px;background-color:#fff;transition:.4s}input:checked+.slider{background-color:#9acd32}input:focus+.slider{box-shadow:0 0 1px #9acd32}input:checked+.slider:before{transform:translate(36px)}.slider.round{border-radius:34px}.slider.round:before{border-radius:50%}.slider:after{content:\"Off\";color:#fff;display:block;position:absolute;transform:translate(-14%,-50%);top:50%;left:50%;font-size:10px;font-family:Verdana,sans-serif}input:checked+.slider:after{content:\"On\";transform:translate(-91%,-50%)}\n", ".flex{display:flex;margin-right:10px;align-items:center}.flex .spacer{min-width:15px}.flex .container .with-validation{display:flex;flex-wrap:nowrap}.flex .container .toggle{width:66px;height:30px}.flex .container input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;padding:0 30px 0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300;min-width:150px;margin:0 3px}.flex .container input[type=number]{padding:0 2px 0 5px}.flex .container .invalid{border:1px solid #ff5252}.flex .container .error{color:#ff5252;margin-right:5px}.flex .variationId{margin:0 4px 0 5px;cursor:pointer;color:#888;display:flex;align-items:center}.flex .expand{position:relative;top:2px;height:24px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.flex .expand mat-icon{transform:rotate(45deg)}@media (max-width: 920px){.flex{margin-right:0!important}.flex .spacer{min-width:5px}}@media (max-width: 510px){.flex .container .error{display:none}}\n"] }]
613
- }], ctorParameters: function () { return [{ type: i1$1.MatDialog }]; }, propDecorators: { valueFormControl: [{
614
- type: Input
615
- }], setting: [{
616
- type: Input
617
- }] } });
618
-
619
- class RolloutPercentageItemsComponent {
620
- setting() {
621
- var _a;
622
- return (_a = this.formGroup.get('setting')) === null || _a === void 0 ? void 0 : _a.value;
623
- }
624
- rolloutRules() {
625
- return this.formGroup.get('rolloutRules');
626
- }
627
- rolloutPercentageItems() {
628
- return this.formGroup.get('rolloutPercentageItems');
629
- }
630
- rolloutPercentageItemsSum() {
631
- return this.formGroup.get('rolloutPercentageItemsSum');
632
- }
633
- value(rolloutPercentageItem) {
634
- return this.setting().settingType === SettingType.Boolean ?
635
- rolloutPercentageItem.get('valueDisabled') :
636
- rolloutPercentageItem.get('value');
637
- }
638
- constructor() {
639
- this.readOnly = false;
640
- this.SettingType = SettingType;
641
- }
642
- percentageChanged(index) {
643
- if (this.rolloutPercentageItems().controls[index].value.percentage < 0) {
644
- this.rolloutPercentageItems().controls[index].controls.percentage.setValue(0);
645
- }
646
- if (this.rolloutPercentageItems().controls[index].value.percentage > 100) {
647
- this.rolloutPercentageItems().controls[index].controls.percentage.setValue(100);
648
- }
649
- if (this.rolloutPercentageItems().controls.length === 2) {
650
- this.rolloutPercentageItems().controls[1 - index].controls.percentage
651
- .setValue(100 - this.rolloutPercentageItems().controls[index].value.percentage);
652
- }
653
- this.updateSum();
654
- }
655
- updateSum() {
656
- if (this.rolloutPercentageItems().controls.length === 0) {
657
- this.rolloutPercentageItemsSum().setValue(100);
658
- }
659
- else {
660
- this.rolloutPercentageItemsSum().setValue(this.rolloutPercentageItems().controls.map(v => v.value.percentage)
661
- .reduce((a, b) => a + b));
662
- }
663
- }
664
- removeRolloutPercentageItem(index) {
665
- this.rolloutPercentageItems().removeAt(index);
666
- this.rolloutPercentageItems().markAsDirty();
667
- this.updateSum();
668
- }
669
- removeAll() {
670
- this.rolloutPercentageItems().clear();
671
- this.rolloutPercentageItems().markAsDirty();
672
- this.updateSum();
673
- }
674
- getRolloutPercentageItemFormGroups() {
675
- var _a, _b;
676
- return (_b = (_a = this.rolloutPercentageItems()) === null || _a === void 0 ? void 0 : _a.controls) === null || _b === void 0 ? void 0 : _b.map(c => c);
677
- }
678
- getPercentageFormControl(rolloutPercentageItem) {
679
- return rolloutPercentageItem.controls.percentage;
680
- }
681
- }
682
- RolloutPercentageItemsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RolloutPercentageItemsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
683
- RolloutPercentageItemsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: RolloutPercentageItemsComponent, selector: "configcat-rollout-percentage-items", inputs: { formGroup: "formGroup", readOnly: "readOnly" }, ngImport: i0, template: "<div class=\"percentage-wrapper\" [formGroup]=\"formGroup\">\n\n <div class=\"if\" *ngIf=\"rolloutRules().controls.length > 0\">\n <mat-chip-set>\n <mat-chip class=\"chip\">ELSE IF</mat-chip>\n </mat-chip-set>\n </div>\n <div class=\"grow\">\n <div class=\"percentage-row flex\"\n *ngFor=\"let rolloutPercentageItem of getRolloutPercentageItemFormGroups(); let i = index\">\n <div class=\"flex\">\n <input type=\"number\" [formControl]=\"getPercentageFormControl(rolloutPercentageItem)\"\n (input)=\"percentageChanged(i)\">%\n <span class=\"users\">of <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">users</a>\n </span>\n </div>\n\n <div class=\"delete-option\" matTooltip=\"Remove this % option\"\n *ngIf=\"!readOnly && rolloutPercentageItems().controls.length > 2\"\n (click)=\"removeRolloutPercentageItem(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n\n <span matTooltip=\"The sum of percentages must be equal to 100.\" matTooltipPosition=\"above\"\n *ngIf=\"(i === rolloutPercentageItems().controls.length -1) && (rolloutPercentageItemsSum().invalid)\">\n <mat-icon color=\"warn\">\n error_outline\n </mat-icon>\n </span>\n\n <div class=\"value flex\">\n <span class=\"value-name\" *ngIf=\"setting().settingType !== SettingType.Boolean\">Served value:</span>\n <configcat-value class=\"served-value\" [valueFormControl]=\"value(rolloutPercentageItem)\"\n [setting]=\"setting()\">\n </configcat-value>\n </div>\n <div class=\"delete\" matTooltip=\"Remove % options\" (click)=\"removeAll()\" *ngIf=\"!readOnly\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n </div>\n</div>", styles: [".percentage-wrapper{border:1px solid #d5d5d5;background-color:#fff;margin:.5em 1em;position:relative;padding:.5em 0;display:flex;flex-wrap:wrap}.percentage-wrapper .delete{position:absolute;cursor:pointer;top:-9px;right:-10px;z-index:999;border-radius:50%;background-color:#fff;height:20px;width:20px;color:#ed5251}.percentage-wrapper .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.percentage-wrapper .delete:hover mat-icon{opacity:1}.percentage-wrapper .delete-option{color:#ed5251;cursor:pointer;margin-left:1rem;margin-top:4px}.percentage-wrapper .delete-option:hover mat-icon{opacity:1}.percentage-wrapper .delete-option mat-icon{opacity:.5;font-size:20px}.if{display:flex;align-items:center}.if>*{margin:0 .5em}.if .spacing{margin-right:44px}.if .chip{font-size:12px;background-color:#67b1fc3d}.grow{flex-grow:1}.percentage-row{min-height:40px;margin-left:.5em}.flex{display:flex;flex-wrap:wrap;align-items:center}.value{margin-left:auto}.value .value-name{display:none}input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;width:40px;margin-top:3px;margin-right:5px;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}input:focus{outline-color:#e5e5e5;outline-offset:-1px}.users{margin-left:20px}@media (max-width: 920px){.value{min-width:0!important}.value .served-value{margin:3px 7px 3px 0}}@media (max-width: 650px){.users{margin-left:5px}}@media (max-width: 540px){.users{font-size:12px}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i5$1.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disabled", "disableRipple", "tabIndex", "role", "id", "aria-label", "aria-description", "value", "removable", "highlighted"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i5$1.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role"] }, { kind: "component", type: ValueComponent, selector: "configcat-value", inputs: ["valueFormControl", "setting"] }] });
684
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RolloutPercentageItemsComponent, decorators: [{
685
- type: Component,
686
- args: [{ selector: 'configcat-rollout-percentage-items', template: "<div class=\"percentage-wrapper\" [formGroup]=\"formGroup\">\n\n <div class=\"if\" *ngIf=\"rolloutRules().controls.length > 0\">\n <mat-chip-set>\n <mat-chip class=\"chip\">ELSE IF</mat-chip>\n </mat-chip-set>\n </div>\n <div class=\"grow\">\n <div class=\"percentage-row flex\"\n *ngFor=\"let rolloutPercentageItem of getRolloutPercentageItemFormGroups(); let i = index\">\n <div class=\"flex\">\n <input type=\"number\" [formControl]=\"getPercentageFormControl(rolloutPercentageItem)\"\n (input)=\"percentageChanged(i)\">%\n <span class=\"users\">of <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">users</a>\n </span>\n </div>\n\n <div class=\"delete-option\" matTooltip=\"Remove this % option\"\n *ngIf=\"!readOnly && rolloutPercentageItems().controls.length > 2\"\n (click)=\"removeRolloutPercentageItem(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n\n <span matTooltip=\"The sum of percentages must be equal to 100.\" matTooltipPosition=\"above\"\n *ngIf=\"(i === rolloutPercentageItems().controls.length -1) && (rolloutPercentageItemsSum().invalid)\">\n <mat-icon color=\"warn\">\n error_outline\n </mat-icon>\n </span>\n\n <div class=\"value flex\">\n <span class=\"value-name\" *ngIf=\"setting().settingType !== SettingType.Boolean\">Served value:</span>\n <configcat-value class=\"served-value\" [valueFormControl]=\"value(rolloutPercentageItem)\"\n [setting]=\"setting()\">\n </configcat-value>\n </div>\n <div class=\"delete\" matTooltip=\"Remove % options\" (click)=\"removeAll()\" *ngIf=\"!readOnly\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n </div>\n</div>", styles: [".percentage-wrapper{border:1px solid #d5d5d5;background-color:#fff;margin:.5em 1em;position:relative;padding:.5em 0;display:flex;flex-wrap:wrap}.percentage-wrapper .delete{position:absolute;cursor:pointer;top:-9px;right:-10px;z-index:999;border-radius:50%;background-color:#fff;height:20px;width:20px;color:#ed5251}.percentage-wrapper .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.percentage-wrapper .delete:hover mat-icon{opacity:1}.percentage-wrapper .delete-option{color:#ed5251;cursor:pointer;margin-left:1rem;margin-top:4px}.percentage-wrapper .delete-option:hover mat-icon{opacity:1}.percentage-wrapper .delete-option mat-icon{opacity:.5;font-size:20px}.if{display:flex;align-items:center}.if>*{margin:0 .5em}.if .spacing{margin-right:44px}.if .chip{font-size:12px;background-color:#67b1fc3d}.grow{flex-grow:1}.percentage-row{min-height:40px;margin-left:.5em}.flex{display:flex;flex-wrap:wrap;align-items:center}.value{margin-left:auto}.value .value-name{display:none}input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;width:40px;margin-top:3px;margin-right:5px;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}input:focus{outline-color:#e5e5e5;outline-offset:-1px}.users{margin-left:20px}@media (max-width: 920px){.value{min-width:0!important}.value .served-value{margin:3px 7px 3px 0}}@media (max-width: 650px){.users{margin-left:5px}}@media (max-width: 540px){.users{font-size:12px}}\n"] }]
687
- }], ctorParameters: function () { return []; }, propDecorators: { formGroup: [{
688
- type: Input
689
- }], readOnly: [{
690
- type: Input
691
- }] } });
692
-
693
- class RolloutRulesComponent {
694
- constructor(dialog, settingListFormHelper) {
695
- this.dialog = dialog;
696
- this.settingListFormHelper = settingListFormHelper;
697
- this.readOnly = false;
698
- this.SettingType = SettingType;
699
- this.defaultComparisonAttributes = ['Identifier', 'Email', 'Country'];
700
- this.rolloutRuleComparators = [
701
- { value: RolloutRuleComparator.IsOneOf, label: 'IS ONE OF (cleartext)' },
702
- { value: RolloutRuleComparator.IsNotOneOf, label: 'IS NOT ONE OF (cleartext)' },
703
- { value: RolloutRuleComparator.Contains, label: 'CONTAINS (cleartext)' },
704
- { value: RolloutRuleComparator.DoesNotContain, label: 'DOES NOT CONTAIN (cleartext)' },
705
- { value: RolloutRuleComparator.SemVerIsOneOf, label: 'IS ONE OF (SemVer)' },
706
- { value: RolloutRuleComparator.SemVerIsNotOneOf, label: 'IS NOT ONE OF (SemVer)' },
707
- { value: RolloutRuleComparator.SemVerLess, label: '< (SemVer)' },
708
- { value: RolloutRuleComparator.SemVerLessOrEquals, label: '<= (SemVer)' },
709
- { value: RolloutRuleComparator.SemVerGreater, label: '> (SemVer)' },
710
- { value: RolloutRuleComparator.SemVerGreaterOrEquals, label: '>= (SemVer)' },
711
- { value: RolloutRuleComparator.NumberEquals, label: '= (Number)' },
712
- { value: RolloutRuleComparator.NumberDoesNotEqual, label: '!= (Number)' },
713
- { value: RolloutRuleComparator.NumberLess, label: '< (Number)' },
714
- { value: RolloutRuleComparator.NumberLessOrEquals, label: '<= (Number)' },
715
- { value: RolloutRuleComparator.NumberGreater, label: '> (Number)' },
716
- { value: RolloutRuleComparator.NumberGreaterOrEquals, label: '>= (Number)' },
717
- { value: RolloutRuleComparator.SensitiveIsOneOf, label: 'IS ONE OF (hashed)' },
718
- { value: RolloutRuleComparator.SensitiveIsNotOneOf, label: 'IS NOT ONE OF (hashed)' },
719
- ];
720
- this.segmentComparators = [
721
- { value: SegmentComparator.IsIn, label: 'IS IN SEGMENT' },
722
- { value: SegmentComparator.IsNotIn, label: 'IS NOT IN SEGMENT' },
723
- ];
724
- }
725
- setting() {
726
- var _a;
727
- return (_a = this.formGroup.get('setting')) === null || _a === void 0 ? void 0 : _a.value;
728
- }
729
- rolloutRules() {
730
- return this.formGroup.get('rolloutRules');
731
- }
732
- comparisonAttributes() {
733
- var _a;
734
- return (_a = this.formGroup.root.get('comparisonAttributes')) === null || _a === void 0 ? void 0 : _a.value;
735
- }
736
- removeRule(index) {
737
- this.rolloutRules().removeAt(index);
738
- this.rolloutRules().markAsDirty();
739
- }
740
- onDrop(event) {
741
- const rolloutRules = this.rolloutRules().controls;
742
- moveItemInArray(rolloutRules, event.previousIndex, event.currentIndex);
743
- this.formGroup.markAsDirty();
744
- }
745
- attributeChanged(event, comparisonAttribute) {
746
- if (this.defaultComparisonAttributes.indexOf(event.value) !== -1) {
747
- if (comparisonAttribute.value !== event.value) {
748
- comparisonAttribute.setValue(event.value);
749
- this.formGroup.markAsDirty();
750
- }
751
- }
752
- else {
753
- if (comparisonAttribute.value !== '') {
754
- comparisonAttribute.setValue('');
755
- this.formGroup.markAsDirty();
756
- }
757
- }
758
- }
759
- getPlaceHolder(rolloutRule) {
760
- if (!rolloutRule.controls.comparisonAttribute.value) {
761
- return '';
762
- }
763
- switch (rolloutRule.controls.comparator.value) {
764
- case RolloutRuleComparator.IsOneOf:
765
- case RolloutRuleComparator.IsNotOneOf:
766
- case RolloutRuleComparator.SensitiveIsOneOf:
767
- case RolloutRuleComparator.SensitiveIsNotOneOf:
768
- switch (rolloutRule.controls.comparisonAttribute.value.toLowerCase()) {
769
- case 'identifier':
770
- return 'e.g: user_id1, user_id2, user_id3';
771
- case 'email':
772
- return 'e.g: jane@example.com, john@example.com';
773
- case 'country':
774
- return 'e.g: France, Brazil';
775
- default:
776
- return 'e.g: value1, value2, value3';
777
- }
778
- case RolloutRuleComparator.Contains:
779
- case RolloutRuleComparator.DoesNotContain:
780
- switch (rolloutRule.controls.comparisonAttribute.value.toLowerCase()) {
781
- case 'identifier':
782
- return 'part-of-id';
783
- case 'email':
784
- return 'e.g: @example.com';
785
- case 'country':
786
- return 'e.g: United';
787
- default:
788
- return 'e.g: any-part-of-your-value-string';
789
- }
790
- case RolloutRuleComparator.SemVerIsOneOf:
791
- case RolloutRuleComparator.SemVerIsNotOneOf:
792
- return 'e.g: 1.0.0, 2.0.1';
793
- case RolloutRuleComparator.SemVerLessOrEquals:
794
- case RolloutRuleComparator.SemVerLess:
795
- case RolloutRuleComparator.SemVerGreater:
796
- case RolloutRuleComparator.SemVerGreaterOrEquals:
797
- return 'e.g: 1.0.0';
798
- case RolloutRuleComparator.NumberEquals:
799
- case RolloutRuleComparator.NumberDoesNotEqual:
800
- case RolloutRuleComparator.NumberLess:
801
- case RolloutRuleComparator.NumberLessOrEquals:
802
- case RolloutRuleComparator.NumberGreater:
803
- case RolloutRuleComparator.NumberGreaterOrEquals:
804
- return 'e.g: 42';
805
- }
806
- return '';
807
- }
808
- getComparisonValueType(rolloutRule) {
809
- return this.settingListFormHelper.getComparisonValueType(rolloutRule.controls.comparator.value);
810
- }
811
- getInfoClass(rolloutRule) {
812
- if (!rolloutRule.controls.comparisonAttribute.value) {
813
- return 'info';
814
- }
815
- switch (rolloutRule.controls.comparator.value) {
816
- case RolloutRuleComparator.IsOneOf:
817
- case RolloutRuleComparator.IsNotOneOf:
818
- case RolloutRuleComparator.Contains:
819
- case RolloutRuleComparator.DoesNotContain:
820
- return 'warn';
821
- default:
822
- return 'info';
823
- }
824
- }
825
- getInfoTooltip(rolloutRule) {
826
- if (!rolloutRule.controls.comparisonAttribute.value) {
827
- return 'Learn more about comparators';
828
- }
829
- switch (rolloutRule.controls.comparator.value) {
830
- case RolloutRuleComparator.IsOneOf:
831
- case RolloutRuleComparator.IsNotOneOf:
832
- case RolloutRuleComparator.Contains:
833
- case RolloutRuleComparator.DoesNotContain:
834
- return 'Consider using sensitive text comparators. Click to learn more.';
835
- default:
836
- return 'Click to learn more about comparators';
837
- }
838
- }
839
- comparatorChanged(rolloutRule) {
840
- let validators = [];
841
- switch (rolloutRule.controls.comparator.value) {
842
- case RolloutRuleComparator.IsOneOf:
843
- case RolloutRuleComparator.IsNotOneOf:
844
- case RolloutRuleComparator.SensitiveIsOneOf:
845
- case RolloutRuleComparator.SensitiveIsNotOneOf:
846
- case RolloutRuleComparator.Contains:
847
- case RolloutRuleComparator.DoesNotContain:
848
- validators = [Validators.required, Validators.maxLength(65535)];
849
- break;
850
- case RolloutRuleComparator.SemVerIsOneOf:
851
- case RolloutRuleComparator.SemVerIsNotOneOf:
852
- validators = [Validators.required, this.validateSemVerList];
853
- break;
854
- case RolloutRuleComparator.SemVerLessOrEquals:
855
- case RolloutRuleComparator.SemVerLess:
856
- case RolloutRuleComparator.SemVerGreater:
857
- case RolloutRuleComparator.SemVerGreaterOrEquals:
858
- validators = [Validators.required, this.validateSemVer];
859
- break;
860
- case RolloutRuleComparator.NumberEquals:
861
- case RolloutRuleComparator.NumberDoesNotEqual:
862
- case RolloutRuleComparator.NumberLess:
863
- case RolloutRuleComparator.NumberLessOrEquals:
864
- case RolloutRuleComparator.NumberGreater:
865
- case RolloutRuleComparator.NumberGreaterOrEquals:
866
- validators = [Validators.required, Validators.min(-1.79769313486232E+308), Validators.max(1.79769313486232E+308)];
867
- break;
868
- }
869
- rolloutRule.controls.comparisonValue.setValidators(validators);
870
- if (this.getComparisonValueType(rolloutRule) === "number") {
871
- const oldValue = rolloutRule.controls.comparisonValue.value;
872
- rolloutRule.controls.comparisonValue.setValue(FormHelper.normalizeNumberStoredAsString(rolloutRule.controls.comparisonValue.value));
873
- if (oldValue !== rolloutRule.controls.comparisonValue.value) {
874
- rolloutRule.controls.comparisonValue.markAsTouched();
875
- }
876
- }
877
- rolloutRule.controls.comparisonValue.updateValueAndValidity();
878
- }
879
- isListType(rolloutRule) {
880
- switch (rolloutRule.controls.comparator.value) {
881
- case RolloutRuleComparator.IsOneOf:
882
- case RolloutRuleComparator.IsNotOneOf:
883
- case RolloutRuleComparator.SensitiveIsOneOf:
884
- case RolloutRuleComparator.SensitiveIsNotOneOf:
885
- case RolloutRuleComparator.SemVerIsOneOf:
886
- case RolloutRuleComparator.SemVerIsNotOneOf:
887
- return true;
888
- default:
889
- return false;
890
- }
891
- }
892
- validateSemVer(c) {
893
- if (valid(c.value) === null) {
894
- return {
895
- validateSemVer: {
896
- valid: false
897
- }
898
- };
899
- }
900
- return null;
901
- }
902
- validateSemVerList(c) {
903
- if (!c.value) {
904
- return {
905
- validateSemVerList: {
906
- valid: false
907
- }
908
- };
909
- }
910
- const semvers = c.value.split(',').map((s) => s.trim());
911
- if (semvers.find((s) => s && s !== '' && valid(s) === null)) {
912
- return {
913
- validateSemVerList: {
914
- valid: false
915
- }
916
- };
917
- }
918
- return null;
919
- }
920
- popOut(rolloutRule) {
921
- this.dialog.open(ExpandDialogComponent, {
922
- width: '640px',
923
- data: {
924
- control: rolloutRule.controls.comparisonValue,
925
- multiline: this.isListType(rolloutRule)
926
- }
927
- });
928
- }
929
- trackByIndex(index) {
930
- return index;
931
- }
932
- getRolloutRuleValueFormControl(rolloutRule) {
933
- return rolloutRule.controls.value;
934
- }
935
- getRolloutRuleComparisonValueFormControl(rolloutRule) {
936
- return rolloutRule.controls.comparisonValue;
937
- }
938
- getRolloutRuleComparisonAttributeFormControl(rolloutRule) {
939
- return rolloutRule.controls.comparisonAttribute;
940
- }
941
- getRolloutRuleTypeFormControl(rolloutRule) {
942
- return rolloutRule.controls.type;
943
- }
944
- getRolloutRuleComparatorFormControl(rolloutRule) {
945
- return rolloutRule.controls.comparator;
946
- }
947
- getRolloutRuleSegmentComparatorFormControl(rolloutRule) {
948
- return rolloutRule.controls.segmentComparator;
949
- }
950
- getRolloutRuleSegmentIdFormControl(rolloutRule) {
951
- return rolloutRule.controls.segmentId;
952
- }
953
- }
954
- RolloutRulesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RolloutRulesComponent, deps: [{ token: i1$1.MatDialog }, { token: SettingListFormHelper }], target: i0.ɵɵFactoryTarget.Component });
955
- RolloutRulesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: RolloutRulesComponent, selector: "configcat-rollout-rules", inputs: { formGroup: "formGroup", readOnly: "readOnly", segments: "segments" }, ngImport: i0, template: "<div [formGroup]=\"formGroup\">\n <div cdkDropList (cdkDropListDropped)=\"onDrop($event)\" [cdkDropListDisabled]=\"readOnly\"\n [cdkDropListData]=\"rolloutRules().controls\">\n <div *ngFor=\"let rolloutRule of rolloutRules().controls; trackBy: trackByIndex; let i = index\" cdkDrag>\n <div class=\"targeting-row\">\n <div class=\"fields flex\" *ngIf=\"getRolloutRuleTypeFormControl(rolloutRule).value === 0\">\n <div class=\"drag-handle\" cdkDragHandle matTooltip=\"Drag here to reorder\" matTooltipPosition=\"above\"\n *ngIf=\"!readOnly\">\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"if\">\n <mat-chip-set [class.spacing]=\"i === 0\">\n <mat-chip class=\"chip\">{{ i === 0 ? 'IF' : 'ELSE IF' }}</mat-chip>\n </mat-chip-set>\n <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">user's</a>\n </div>\n\n <select class=\"custom-select attribute-select\" matTooltip=\"Comparison attribute\"\n matTooltipPosition=\"above\"\n (change)=\"attributeChanged($event.target, getRolloutRuleComparisonAttributeFormControl(rolloutRule))\"\n [disabled]=\"readOnly\">\n <option *ngFor=\"let comparisonAttribute of defaultComparisonAttributes\"\n [selected]=\"comparisonAttribute === getRolloutRuleComparisonAttributeFormControl(rolloutRule).value\">\n {{comparisonAttribute}}</option>\n <option\n [selected]=\"defaultComparisonAttributes.indexOf(getRolloutRuleComparisonAttributeFormControl(rolloutRule).value) === -1\">\n Custom\n </option>\n </select>\n\n\n <span class=\"attribute-span\" matTooltip=\"Custom user attribute\" matTooltipPosition=\"above\"\n [hidden]=\"defaultComparisonAttributes.indexOf(getRolloutRuleComparisonAttributeFormControl(rolloutRule).value) !== -1\">\n <span class=\"attribute-error\"\n *ngIf=\"getRolloutRuleComparisonAttributeFormControl(rolloutRule).invalid\">*</span>\n <input\n [ngClass]=\"{'invalid': getRolloutRuleComparisonAttributeFormControl(rolloutRule).invalid}\"\n type=\"text\" matInput [matAutocomplete]=\"auto\"\n [formControl]=\"getRolloutRuleComparisonAttributeFormControl(rolloutRule)\" class=\"attribute\"\n placeholder=\"e.g. Eye color\">\n </span>\n\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let option of comparisonAttributes()\" [value]=\"option\">\n {{option}}\n </mat-option>\n </mat-autocomplete>\n\n <div class=\"select-wrapper\">\n <select class=\"custom-select\" [formControl]=\"getRolloutRuleComparatorFormControl(rolloutRule)\"\n matTooltip=\"Comparator\" matTooltipPosition=\"above\"\n (change)=\"comparatorChanged(rolloutRule)\">\n <optgroup label=\"CONFIDENTIAL TEXT\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(16, 18)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"TEXT\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(0, 4)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"SEMANTIC VERSION\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(4, 10)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"NUMBER\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(10, 16)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n </select>\n <div [class]=\"getInfoClass(rolloutRule)\" [matTooltip]=\"getInfoTooltip(rolloutRule)\">\n <a href=\"https://configcat.com/docs/advanced/targeting/#comparator\" target=\"_blank\"\n rel=\"noopener noreferrer\">\n <mat-icon>info</mat-icon>\n </a>\n </div>\n </div>\n\n <div class=\"comparison-value\">\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 matTooltip=\"Comparison value\" matTooltipPosition=\"above\" inputDisplayNormalizer>\n <div class=\"expand\" matTooltip=\"Pop-out Editor\" matTooltipPosition=\"above\"\n (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\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n\n <div class=\"fields flex\" *ngIf=\"getRolloutRuleTypeFormControl(rolloutRule).value === 1\">\n <div class=\"drag-handle\" cdkDragHandle matTooltip=\"Drag here to reorder\" matTooltipPosition=\"above\"\n *ngIf=\"!readOnly\">\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"if\">\n <mat-chip-set [class.spacing]=\"i === 0\">\n <mat-chip class=\"chip\">{{ i === 0 ? 'IF' : 'ELSE IF' }}</mat-chip>\n </mat-chip-set>\n <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">user</a>\n </div>\n\n\n <div class=\"select-wrapper\">\n <select class=\"custom-select segment-comparator\"\n [formControl]=\"getRolloutRuleSegmentComparatorFormControl(rolloutRule)\"\n matTooltip=\"Segment comparator\" matTooltipPosition=\"above\">\n <option *ngFor=\"let comparator of segmentComparators\" [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </select>\n </div>\n\n <div class=\"select-wrapper\">\n <span class=\"attribute-error\"\n *ngIf=\"getRolloutRuleSegmentIdFormControl(rolloutRule).invalid\">*</span>\n <select class=\"custom-select segment-select\"\n [formControl]=\"getRolloutRuleSegmentIdFormControl(rolloutRule)\" matTooltip=\"Segment\"\n matTooltipPosition=\"above\"\n [ngClass]=\"{'invalid': getRolloutRuleSegmentIdFormControl(rolloutRule).invalid}\">\n <option *ngFor=\"let segment of segments\" [ngValue]=\"segment.segmentId\">\n {{segment.name}}\n </option>\n </select>\n </div>\n\n\n <div class=\"delete\" matTooltip=\"Remove targeting rule\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n\n\n <div class=\"value flex\">\n <div class=\"serve\" *ngIf=\"setting().settingType !== SettingType.Boolean\">\n <mat-chip-set>\n <mat-chip class=\"chip\">Serve:</mat-chip>\n </mat-chip-set>\n </div>\n\n <configcat-value class=\"served-value\"\n [valueFormControl]=\"getRolloutRuleValueFormControl(rolloutRule)\" [setting]=\"setting()\">\n </configcat-value>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [".cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-animating{transition:transform .3s cubic-bezier(0,0,.2,1)}.targeting-row{border:1px solid #d5d5d5;background-color:#fff;margin:1em;display:flex;position:relative;padding:.5em 0}.targeting-row:hover{background-color:#dbedff}.targeting-row .select-wrapper{position:relative}.targeting-row .info{position:absolute;cursor:pointer;top:-8px;left:166px;border-radius:50%;background-color:#fff;height:18px;width:18px}.targeting-row .info a{color:#0068f0;opacity:.5}.targeting-row .info a:hover{opacity:1}.targeting-row .info mat-icon{font-size:18px;height:18px;width:18px}.targeting-row .warn{position:absolute;cursor:pointer;top:-8px;left:166px;height:18px;width:18px;border-radius:50%;background-color:#fff}.targeting-row .warn a{color:#fdc67f}.targeting-row .warn a:hover{color:#ff9200}.targeting-row .warn mat-icon{font-size:18px;height:18px;width:18px}.custom-select{margin-left:.5em;width:170px;background-color:#fff;border:1px solid #e5e5e5;height:30px;min-height:30px;line-height:30px;min-width:170px;font-size:.8em;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.custom-select:focus{outline-color:#e5e5e5;outline-offset:-1px}.fields{justify-content:left;max-width:1060px;flex-grow:100}.fields .if{display:flex;align-items:center}.fields .if>*{margin:0 .5em}.fields .if .spacing{margin-right:41px}.fields .if .user-link{width:40px}.fields .if .chip{font-size:12px;background-color:#67b1fc3d}.fields .attribute-span{margin-left:.5em;display:flex;align-items:center}.fields .attribute-span[hidden]{display:none}.fields .attribute{width:170px;background-color:#fff;border:1px solid #e5e5e5;margin:3px 0;min-height:28px;flex-grow:100;min-width:170px;padding:0 30px 0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300;font-size:13.3px}.fields .invalid{border:1px solid #ff5252}.fields .attribute-error{color:#ff5252;margin:0 5px}.fields .delete{position:absolute;cursor:pointer;top:-9px;right:-10px;z-index:999;border-radius:50%;background-color:#fff;height:20px;width:20px;color:#ed5251}.fields .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.fields .delete:hover mat-icon{opacity:1}.fields .drag-handle{position:absolute;cursor:-moz-grab;left:-20px;top:14px}.fields .drag-handle mat-icon{font-size:20px}.fields .attribute-select{min-width:100px;width:100px;margin-left:0}.fields .segment-comparator,.fields .segment-select{margin-left:0;margin-right:.5em}.fields .segment-more mat-icon{position:relative;top:3px;cursor:pointer;font-size:16px;height:16px;width:16px;color:#797979;margin-top:3px}.fields .comparison-value{flex-grow:100;min-width:150px;display:flex;align-items:center;margin-left:.5em;margin-right:.5em}.fields .comparison-value .error{color:#ff5252;margin:0 5px}.fields .comparison-value input{background-color:#fff;border:1px solid #e5e5e5;margin:3px 0;min-height:28px;min-width:150px;flex-grow:100;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.fields .comparison-value input[type=text]{padding-right:30px}.fields .comparison-value input:focus{outline-color:#e5e5e5;outline-offset:-1px}.fields .comparison-value .invalid{border:1px solid #ff5252}.fields .comparison-value .expand{position:relative;height:24px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.fields .comparison-value .expand mat-icon{transform:rotate(45deg)}.value{margin-left:auto;flex-wrap:nowrap}.value .serve{margin:0 2px 0 5px}.value .serve .chip{font-size:12px;background-color:#67b1fc3d}.value .served-value{margin:3px 0}.flex{display:flex;flex-wrap:wrap;align-items:center}@media (max-width: 1200px){.targeting-row{flex-wrap:wrap}.targeting-row .fields{max-width:500px}}@media (max-width: 920px){.value .served-value{margin:3px 7px 3px 0}.targeting-row .fields .drag-handle{left:-18px}}@media (max-width: 410px){.value .served-value{margin:7px 7px 3px 4px}}@media (max-width: 510px){.fields .comparison-value .error{display:none}}@media (max-width: 650px){.targeting-row{flex-direction:column}.targeting-row .help{left:161px}.targeting-row .fields{flex-direction:column;align-items:stretch}.targeting-row .fields .custom-select{margin:7px 7px 0}.targeting-row .fields .comparison-value{margin:7px}.targeting-row .fields .comparison-value input{margin:0 4px 0 0}.targeting-row .fields .attribute-span{margin:7px 7px 0}.targeting-row .fields .if{font-size:12px}.targeting-row .fields .if .spacing{margin-right:3px}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i5$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i5$1.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disabled", "disableRipple", "tabIndex", "role", "id", "aria-label", "aria-description", "value", "removable", "highlighted"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i5$1.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role"] }, { kind: "component", type: i10.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple", "hideSingleSelectionIndicator"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i10.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "directive", type: i11.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i11.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i11.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: ValueComponent, selector: "configcat-value", inputs: ["valueFormControl", "setting"] }, { kind: "directive", type: InputDisplayNormalizerDirective, selector: "input[inputDisplayNormalizer]" }] });
956
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RolloutRulesComponent, decorators: [{
957
- type: Component,
958
- args: [{ selector: 'configcat-rollout-rules', template: "<div [formGroup]=\"formGroup\">\n <div cdkDropList (cdkDropListDropped)=\"onDrop($event)\" [cdkDropListDisabled]=\"readOnly\"\n [cdkDropListData]=\"rolloutRules().controls\">\n <div *ngFor=\"let rolloutRule of rolloutRules().controls; trackBy: trackByIndex; let i = index\" cdkDrag>\n <div class=\"targeting-row\">\n <div class=\"fields flex\" *ngIf=\"getRolloutRuleTypeFormControl(rolloutRule).value === 0\">\n <div class=\"drag-handle\" cdkDragHandle matTooltip=\"Drag here to reorder\" matTooltipPosition=\"above\"\n *ngIf=\"!readOnly\">\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"if\">\n <mat-chip-set [class.spacing]=\"i === 0\">\n <mat-chip class=\"chip\">{{ i === 0 ? 'IF' : 'ELSE IF' }}</mat-chip>\n </mat-chip-set>\n <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">user's</a>\n </div>\n\n <select class=\"custom-select attribute-select\" matTooltip=\"Comparison attribute\"\n matTooltipPosition=\"above\"\n (change)=\"attributeChanged($event.target, getRolloutRuleComparisonAttributeFormControl(rolloutRule))\"\n [disabled]=\"readOnly\">\n <option *ngFor=\"let comparisonAttribute of defaultComparisonAttributes\"\n [selected]=\"comparisonAttribute === getRolloutRuleComparisonAttributeFormControl(rolloutRule).value\">\n {{comparisonAttribute}}</option>\n <option\n [selected]=\"defaultComparisonAttributes.indexOf(getRolloutRuleComparisonAttributeFormControl(rolloutRule).value) === -1\">\n Custom\n </option>\n </select>\n\n\n <span class=\"attribute-span\" matTooltip=\"Custom user attribute\" matTooltipPosition=\"above\"\n [hidden]=\"defaultComparisonAttributes.indexOf(getRolloutRuleComparisonAttributeFormControl(rolloutRule).value) !== -1\">\n <span class=\"attribute-error\"\n *ngIf=\"getRolloutRuleComparisonAttributeFormControl(rolloutRule).invalid\">*</span>\n <input\n [ngClass]=\"{'invalid': getRolloutRuleComparisonAttributeFormControl(rolloutRule).invalid}\"\n type=\"text\" matInput [matAutocomplete]=\"auto\"\n [formControl]=\"getRolloutRuleComparisonAttributeFormControl(rolloutRule)\" class=\"attribute\"\n placeholder=\"e.g. Eye color\">\n </span>\n\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let option of comparisonAttributes()\" [value]=\"option\">\n {{option}}\n </mat-option>\n </mat-autocomplete>\n\n <div class=\"select-wrapper\">\n <select class=\"custom-select\" [formControl]=\"getRolloutRuleComparatorFormControl(rolloutRule)\"\n matTooltip=\"Comparator\" matTooltipPosition=\"above\"\n (change)=\"comparatorChanged(rolloutRule)\">\n <optgroup label=\"CONFIDENTIAL TEXT\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(16, 18)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"TEXT\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(0, 4)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"SEMANTIC VERSION\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(4, 10)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"NUMBER\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(10, 16)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n </select>\n <div [class]=\"getInfoClass(rolloutRule)\" [matTooltip]=\"getInfoTooltip(rolloutRule)\">\n <a href=\"https://configcat.com/docs/advanced/targeting/#comparator\" target=\"_blank\"\n rel=\"noopener noreferrer\">\n <mat-icon>info</mat-icon>\n </a>\n </div>\n </div>\n\n <div class=\"comparison-value\">\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 matTooltip=\"Comparison value\" matTooltipPosition=\"above\" inputDisplayNormalizer>\n <div class=\"expand\" matTooltip=\"Pop-out Editor\" matTooltipPosition=\"above\"\n (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\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n\n <div class=\"fields flex\" *ngIf=\"getRolloutRuleTypeFormControl(rolloutRule).value === 1\">\n <div class=\"drag-handle\" cdkDragHandle matTooltip=\"Drag here to reorder\" matTooltipPosition=\"above\"\n *ngIf=\"!readOnly\">\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"if\">\n <mat-chip-set [class.spacing]=\"i === 0\">\n <mat-chip class=\"chip\">{{ i === 0 ? 'IF' : 'ELSE IF' }}</mat-chip>\n </mat-chip-set>\n <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\"\n rel=\"noopener noreferrer\">user</a>\n </div>\n\n\n <div class=\"select-wrapper\">\n <select class=\"custom-select segment-comparator\"\n [formControl]=\"getRolloutRuleSegmentComparatorFormControl(rolloutRule)\"\n matTooltip=\"Segment comparator\" matTooltipPosition=\"above\">\n <option *ngFor=\"let comparator of segmentComparators\" [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </select>\n </div>\n\n <div class=\"select-wrapper\">\n <span class=\"attribute-error\"\n *ngIf=\"getRolloutRuleSegmentIdFormControl(rolloutRule).invalid\">*</span>\n <select class=\"custom-select segment-select\"\n [formControl]=\"getRolloutRuleSegmentIdFormControl(rolloutRule)\" matTooltip=\"Segment\"\n matTooltipPosition=\"above\"\n [ngClass]=\"{'invalid': getRolloutRuleSegmentIdFormControl(rolloutRule).invalid}\">\n <option *ngFor=\"let segment of segments\" [ngValue]=\"segment.segmentId\">\n {{segment.name}}\n </option>\n </select>\n </div>\n\n\n <div class=\"delete\" matTooltip=\"Remove targeting rule\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n\n\n <div class=\"value flex\">\n <div class=\"serve\" *ngIf=\"setting().settingType !== SettingType.Boolean\">\n <mat-chip-set>\n <mat-chip class=\"chip\">Serve:</mat-chip>\n </mat-chip-set>\n </div>\n\n <configcat-value class=\"served-value\"\n [valueFormControl]=\"getRolloutRuleValueFormControl(rolloutRule)\" [setting]=\"setting()\">\n </configcat-value>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [".cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-animating{transition:transform .3s cubic-bezier(0,0,.2,1)}.targeting-row{border:1px solid #d5d5d5;background-color:#fff;margin:1em;display:flex;position:relative;padding:.5em 0}.targeting-row:hover{background-color:#dbedff}.targeting-row .select-wrapper{position:relative}.targeting-row .info{position:absolute;cursor:pointer;top:-8px;left:166px;border-radius:50%;background-color:#fff;height:18px;width:18px}.targeting-row .info a{color:#0068f0;opacity:.5}.targeting-row .info a:hover{opacity:1}.targeting-row .info mat-icon{font-size:18px;height:18px;width:18px}.targeting-row .warn{position:absolute;cursor:pointer;top:-8px;left:166px;height:18px;width:18px;border-radius:50%;background-color:#fff}.targeting-row .warn a{color:#fdc67f}.targeting-row .warn a:hover{color:#ff9200}.targeting-row .warn mat-icon{font-size:18px;height:18px;width:18px}.custom-select{margin-left:.5em;width:170px;background-color:#fff;border:1px solid #e5e5e5;height:30px;min-height:30px;line-height:30px;min-width:170px;font-size:.8em;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.custom-select:focus{outline-color:#e5e5e5;outline-offset:-1px}.fields{justify-content:left;max-width:1060px;flex-grow:100}.fields .if{display:flex;align-items:center}.fields .if>*{margin:0 .5em}.fields .if .spacing{margin-right:41px}.fields .if .user-link{width:40px}.fields .if .chip{font-size:12px;background-color:#67b1fc3d}.fields .attribute-span{margin-left:.5em;display:flex;align-items:center}.fields .attribute-span[hidden]{display:none}.fields .attribute{width:170px;background-color:#fff;border:1px solid #e5e5e5;margin:3px 0;min-height:28px;flex-grow:100;min-width:170px;padding:0 30px 0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300;font-size:13.3px}.fields .invalid{border:1px solid #ff5252}.fields .attribute-error{color:#ff5252;margin:0 5px}.fields .delete{position:absolute;cursor:pointer;top:-9px;right:-10px;z-index:999;border-radius:50%;background-color:#fff;height:20px;width:20px;color:#ed5251}.fields .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.fields .delete:hover mat-icon{opacity:1}.fields .drag-handle{position:absolute;cursor:-moz-grab;left:-20px;top:14px}.fields .drag-handle mat-icon{font-size:20px}.fields .attribute-select{min-width:100px;width:100px;margin-left:0}.fields .segment-comparator,.fields .segment-select{margin-left:0;margin-right:.5em}.fields .segment-more mat-icon{position:relative;top:3px;cursor:pointer;font-size:16px;height:16px;width:16px;color:#797979;margin-top:3px}.fields .comparison-value{flex-grow:100;min-width:150px;display:flex;align-items:center;margin-left:.5em;margin-right:.5em}.fields .comparison-value .error{color:#ff5252;margin:0 5px}.fields .comparison-value input{background-color:#fff;border:1px solid #e5e5e5;margin:3px 0;min-height:28px;min-width:150px;flex-grow:100;padding:0 5px;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;font-weight:300}.fields .comparison-value input[type=text]{padding-right:30px}.fields .comparison-value input:focus{outline-color:#e5e5e5;outline-offset:-1px}.fields .comparison-value .invalid{border:1px solid #ff5252}.fields .comparison-value .expand{position:relative;height:24px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.fields .comparison-value .expand mat-icon{transform:rotate(45deg)}.value{margin-left:auto;flex-wrap:nowrap}.value .serve{margin:0 2px 0 5px}.value .serve .chip{font-size:12px;background-color:#67b1fc3d}.value .served-value{margin:3px 0}.flex{display:flex;flex-wrap:wrap;align-items:center}@media (max-width: 1200px){.targeting-row{flex-wrap:wrap}.targeting-row .fields{max-width:500px}}@media (max-width: 920px){.value .served-value{margin:3px 7px 3px 0}.targeting-row .fields .drag-handle{left:-18px}}@media (max-width: 410px){.value .served-value{margin:7px 7px 3px 4px}}@media (max-width: 510px){.fields .comparison-value .error{display:none}}@media (max-width: 650px){.targeting-row{flex-direction:column}.targeting-row .help{left:161px}.targeting-row .fields{flex-direction:column;align-items:stretch}.targeting-row .fields .custom-select{margin:7px 7px 0}.targeting-row .fields .comparison-value{margin:7px}.targeting-row .fields .comparison-value input{margin:0 4px 0 0}.targeting-row .fields .attribute-span{margin:7px 7px 0}.targeting-row .fields .if{font-size:12px}.targeting-row .fields .if .spacing{margin-right:3px}}\n"] }]
959
- }], ctorParameters: function () { return [{ type: i1$1.MatDialog }, { type: SettingListFormHelper }]; }, propDecorators: { formGroup: [{
960
- type: Input
961
- }], readOnly: [{
962
- type: Input
963
- }], segments: [{
964
- type: Input
965
- }] } });
966
-
967
- class SettingComponent {
968
- constructor(formHelper) {
969
- this.formHelper = formHelper;
970
- this.dashboardBasePath = 'https://app.configcat.com';
971
- this.readOnly = false;
972
- this.canDeleteSetting = false;
973
- this.deleteSettingText = 'Delete setting';
974
- this.showEnvironmentName = false;
975
- this.deleteSettingRequested = new EventEmitter();
976
- this.rulesBeingRendered = false;
977
- this.SettingType = SettingType;
978
- }
979
- ngOnInit() { }
980
- environment() {
981
- var _a;
982
- return (_a = this.formGroup.root.get('environment')) === null || _a === void 0 ? void 0 : _a.value;
983
- }
984
- setting() {
985
- var _a;
986
- return (_a = this.formGroup.get('setting')) === null || _a === void 0 ? void 0 : _a.value;
987
- }
988
- integrationLinks() {
989
- return this.formGroup.get('integrationLinks');
990
- }
991
- rolloutRules() {
992
- return this.formGroup.get('rolloutRules');
993
- }
994
- rolloutPercentageItems() {
995
- return this.formGroup.get('rolloutPercentageItems');
996
- }
997
- value() {
998
- return this.formGroup.get('value');
999
- }
1000
- addRolloutRule() {
1001
- this.rolloutRules().push(this.formHelper.createRolloutRuleFormGroup({
1002
- comparisonAttribute: 'Identifier',
1003
- comparator: RolloutRuleComparator.SensitiveIsOneOf,
1004
- comparisonValue: '',
1005
- value: this.setting().settingType === SettingType.Boolean ? false : null
1006
- }, this.readOnly, this.setting().settingType));
1007
- this.rolloutRules().markAsDirty();
1008
- }
1009
- addSegmentRolloutRule() {
1010
- this.rolloutRules().push(this.formHelper.createRolloutRuleFormGroup({
1011
- segmentComparator: SegmentComparator.IsIn,
1012
- value: this.setting().settingType === SettingType.Boolean ? false : null
1013
- }, this.readOnly, this.setting().settingType));
1014
- this.rolloutRules().markAsDirty();
1015
- }
1016
- removeRolloutRules() {
1017
- this.rolloutRules().clear();
1018
- this.rolloutRules().markAsDirty();
1019
- }
1020
- addRolloutPercentageItem() {
1021
- if (this.rolloutPercentageItems().length === 0) {
1022
- switch (this.setting().settingType) {
1023
- case SettingType.Boolean:
1024
- this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1025
- percentage: 0,
1026
- value: true
1027
- }, this.readOnly, this.setting().settingType));
1028
- this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1029
- percentage: 100,
1030
- value: false
1031
- }, this.readOnly, this.setting().settingType));
1032
- break;
1033
- case SettingType.String:
1034
- case SettingType.Int:
1035
- case SettingType.Double:
1036
- for (let i = 0; i < 4; i++) {
1037
- this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1038
- percentage: 25,
1039
- value: null
1040
- }, this.readOnly, this.setting().settingType));
1041
- }
1042
- break;
1043
- }
1044
- }
1045
- else if (this.setting().settingType !== SettingType.Boolean) {
1046
- this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1047
- percentage: 0,
1048
- value: null
1049
- }, this.readOnly, this.setting().settingType));
1050
- }
1051
- this.rolloutPercentageItems().markAsDirty();
1052
- }
1053
- removeRolloutPercentageItems() {
1054
- this.rolloutPercentageItems().clear();
1055
- this.rolloutPercentageItems().markAsDirty();
1056
- }
1057
- deleteSetting() {
1058
- this.deleteSettingRequested.emit({ setting: this.setting() });
1059
- }
1060
- getDashboardUrl() {
1061
- return this.dashboardBasePath + '/' + this.productId + '/' + this.configId + '/' + this.environmentId + '?settingId=' + this.setting().settingId;
1062
- }
1063
- }
1064
- SettingComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SettingComponent, deps: [{ token: SettingListFormHelper }], target: i0.ɵɵFactoryTarget.Component });
1065
- SettingComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: SettingComponent, selector: "setting", inputs: { dashboardBasePath: "dashboardBasePath", productId: "productId", environmentId: "environmentId", configId: "configId", formGroup: "formGroup", readOnly: "readOnly", canDeleteSetting: "canDeleteSetting", deleteSettingText: "deleteSettingText", showEnvironmentName: "showEnvironmentName", segments: "segments" }, outputs: { deleteSettingRequested: "deleteSettingRequested" }, ngImport: i0, template: "<div class=\"setting-full\" [formGroup]=\"formGroup\">\n <div class=\"delete\" (click)=\"deleteSetting()\" *ngIf=\"canDeleteSetting\" [matTooltip]=\"deleteSettingText\"\n data-robot=\"deleteSetting\">\n <mat-icon>cancel</mat-icon>\n </div>\n <div class=\"setting-header\">\n <div class=\"setting-name\">\n <div class=\"name\" data-robot=\"settingName\">\n {{setting().name}}\n <span *ngIf=\"showEnvironmentName\"> ({{environment().name}})</span>\n </div>\n </div>\n </div>\n <div class=\"setting-content\">\n <div class=\"setting-details\">\n <div class=\"setting-key\"><code data-robot=\"settingKey\">{{setting().key}}</code></div>\n <span *ngIf=\"setting().hint\" class=\"description\">{{setting().hint}}</span>\n <div class=\"open\"><a [href]=\"getDashboardUrl()\" target=\"_blank\" rel=\"noopener noreferrer\">Open in ConfigCat</a>\n </div>\n </div>\n\n <div class=\"rules-list\">\n <div>\n <configcat-rollout-rules *ngIf=\"rolloutRules().controls.length !== 0\" [formGroup]=\"formGroup\"\n [segments]=\"segments\" [readOnly]=\"readOnly\">\n </configcat-rollout-rules>\n </div>\n\n <configcat-rollout-percentage-items *ngIf=\"rolloutPercentageItems().controls.length !== 0\" [formGroup]=\"formGroup\"\n [readOnly]=\"readOnly\">\n </configcat-rollout-percentage-items>\n\n <div class=\"all-other flex\">\n <div *ngIf=\"rolloutPercentageItems().length === 0 && rolloutRules().length !== 0\"\n matTooltip=\"This value will be served to all users who the above rules don't apply.\"\n matTooltipPosition=\"above\">\n <mat-chip-set>\n <mat-chip class=\"chip\">To all other users, serve:</mat-chip>\n </mat-chip-set>\n </div>\n <div *ngIf=\"rolloutPercentageItems().length !== 0\"\n matTooltip=\"This fallback value will be served in case the user can't be identified.\"\n matTooltipPosition=\"above\">\n <mat-chip-set>\n <mat-chip class=\"chip\">To unidentified users, serve:</mat-chip>\n </mat-chip-set>\n </div>\n <div *ngIf=\"rolloutPercentageItems().length === 0 && rolloutRules().length === 0\">\n <mat-chip-set>\n <mat-chip class=\"chip\">To all users, serve:</mat-chip>\n </mat-chip-set>\n </div>\n <configcat-value class=\"served-value\" [valueFormControl]=\"value()\" [setting]=\"setting()\">\n </configcat-value>\n </div>\n <div class=\"buttons\">\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addRolloutRule()\" *ngIf=\"!readOnly\">\n {{rolloutRules().length === 0 ? 'Target specific users' : 'Add new targeting rule'}}\n </button>\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addSegmentRolloutRule()\" *ngIf=\"!readOnly\">\n {{rolloutRules().length === 0 ? 'Target segment' : 'Target new segment'}}\n </button>\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addRolloutPercentageItem()\"\n *ngIf=\"!readOnly\"\n [disabled]=\"setting().settingType === SettingType.Boolean && rolloutPercentageItems().length !== 0\">\n {{rolloutPercentageItems().length === 0 ? 'Target % of users' : 'Add new % option'}}\n </button>\n </div>\n </div>\n </div>\n</div>", styles: [".setting-full{position:relative;display:flex;flex-wrap:nowrap;flex-direction:column}.setting-full .delete{position:absolute;right:-10px;top:-10px;color:#ed5251;background-color:#fff;border-radius:50%;height:20px;width:20px;cursor:pointer}.setting-full .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.setting-full .delete:hover mat-icon{opacity:1}.setting-full .setting-header{padding:1.5em .8em 0 1em}.setting-full .setting-header .setting-name{flex-direction:row}.setting-full .setting-header .setting-name:hover>.edit{visibility:visible}.setting-full .setting-header .setting-name .name{font-weight:700;word-wrap:break-word;max-width:100%}.setting-full .setting-header .setting-name .edit{margin:5px 0 0 5px;cursor:pointer;visibility:hidden;color:gray}.setting-full .setting-header .setting-name .edit:hover{visibility:visible}.setting-full .setting-header .setting-name .edit mat-icon{font-size:18px}.setting-full .setting-header .setting-meta{margin-left:auto;margin-right:14px;font-size:.7em;color:gray}.setting-full .setting-content{display:flex}.setting-full .setting-content .setting-details{display:flex;flex-direction:column;width:400px;padding:0 0 .5em .5em}.setting-full .setting-content .setting-details>*{margin:.5em}.setting-full .setting-content .setting-details .open{font-size:14px}.setting-full .setting-content .setting-details .integrations{font-size:.8rem}.setting-full .setting-content .setting-details .integrations>div{margin:3px}.setting-full .setting-content .setting-details .integrations>div>a:hover{text-decoration:underline}.setting-full .setting-content .setting-details .setting-key{word-wrap:break-word}.setting-full .setting-content .setting-details .description{font-size:.8em;white-space:pre-wrap;word-wrap:break-word;max-width:300px}.setting-full .setting-content .setting-details code{background-color:#d3d3d3;padding:3px 6px}.setting-full .setting-content .rules-list{width:100%;padding:0 .3em .3em 1em}.setting-full .setting-content .targeting-button{margin-left:.5rem;margin-right:.5rem;margin-bottom:1.5em;text-transform:uppercase}.all-other{min-height:40px;justify-content:flex-start;border:1px solid #d5d5d5;background-color:#fff;margin:.5em 1em;padding:4px 0 4px .5em}.all-other .chip{font-size:12px;background-color:#67b1fc3d}.all-other .served-value{margin-left:auto;margin-top:3px;margin-bottom:3px}.end{margin-left:auto}.buttons{display:flex;margin-left:.5rem;margin-right:.5rem}.buttons .updated-date{font-size:.7em;margin-left:auto;margin-right:22px;color:gray}.flex{display:flex;flex-wrap:wrap;align-items:center}.show-hide-toggle{margin-left:1em;cursor:pointer}.show-hide-toggle a{font-size:.8rem}.sige-button{background-color:#d9eadc;color:#363636;cursor:pointer;justify-content:center;padding:.375em .75em;text-align:center;white-space:nowrap;font-size:.75rem;border:1px solid #dbdbdb;box-shadow:none;display:inline-flex;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif}.sige-button:hover{background-color:#bad0be}.sige-button:disabled{background-color:#fff;color:#b3b3b3}@media (max-width: 1200px){.setting-details{width:300px!important}}@media (max-width: 920px){.setting-full .setting-content{flex-wrap:wrap}.setting-full .setting-content .rules-list{padding:0}.setting-full .setting-content .targeting-button{margin-bottom:.5em;margin-top:.5em;padding:.6em 0}.colorbar{min-width:5px}.buttons{flex-direction:column;margin-bottom:.5em;margin-left:.4em;margin-right:.4em}.created-date,.updated-date{display:none}.setting-details{width:100%!important;padding:.2em 0 .2em .2em}.setting-details .description{max-width:none!important}.rollout-rules{margin-bottom:1em}.all-other{margin:1em;padding:7px 0 7px .5em}.all-other .served-value{margin:7px 7px 4px auto}}@media (max-width: 380px){.mat-mdc-standard-chip{min-height:auto!important;height:auto!important}.mat-chip-list-wrapper{padding-right:7px}.sige-button{font-size:.65rem}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i5$1.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disabled", "disableRipple", "tabIndex", "role", "id", "aria-label", "aria-description", "value", "removable", "highlighted"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i5$1.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role"] }, { kind: "component", type: RolloutPercentageItemsComponent, selector: "configcat-rollout-percentage-items", inputs: ["formGroup", "readOnly"] }, { kind: "component", type: RolloutRulesComponent, selector: "configcat-rollout-rules", inputs: ["formGroup", "readOnly", "segments"] }, { kind: "component", type: ValueComponent, selector: "configcat-value", inputs: ["valueFormControl", "setting"] }] });
1066
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SettingComponent, decorators: [{
1067
- type: Component,
1068
- args: [{ selector: 'setting', template: "<div class=\"setting-full\" [formGroup]=\"formGroup\">\n <div class=\"delete\" (click)=\"deleteSetting()\" *ngIf=\"canDeleteSetting\" [matTooltip]=\"deleteSettingText\"\n data-robot=\"deleteSetting\">\n <mat-icon>cancel</mat-icon>\n </div>\n <div class=\"setting-header\">\n <div class=\"setting-name\">\n <div class=\"name\" data-robot=\"settingName\">\n {{setting().name}}\n <span *ngIf=\"showEnvironmentName\"> ({{environment().name}})</span>\n </div>\n </div>\n </div>\n <div class=\"setting-content\">\n <div class=\"setting-details\">\n <div class=\"setting-key\"><code data-robot=\"settingKey\">{{setting().key}}</code></div>\n <span *ngIf=\"setting().hint\" class=\"description\">{{setting().hint}}</span>\n <div class=\"open\"><a [href]=\"getDashboardUrl()\" target=\"_blank\" rel=\"noopener noreferrer\">Open in ConfigCat</a>\n </div>\n </div>\n\n <div class=\"rules-list\">\n <div>\n <configcat-rollout-rules *ngIf=\"rolloutRules().controls.length !== 0\" [formGroup]=\"formGroup\"\n [segments]=\"segments\" [readOnly]=\"readOnly\">\n </configcat-rollout-rules>\n </div>\n\n <configcat-rollout-percentage-items *ngIf=\"rolloutPercentageItems().controls.length !== 0\" [formGroup]=\"formGroup\"\n [readOnly]=\"readOnly\">\n </configcat-rollout-percentage-items>\n\n <div class=\"all-other flex\">\n <div *ngIf=\"rolloutPercentageItems().length === 0 && rolloutRules().length !== 0\"\n matTooltip=\"This value will be served to all users who the above rules don't apply.\"\n matTooltipPosition=\"above\">\n <mat-chip-set>\n <mat-chip class=\"chip\">To all other users, serve:</mat-chip>\n </mat-chip-set>\n </div>\n <div *ngIf=\"rolloutPercentageItems().length !== 0\"\n matTooltip=\"This fallback value will be served in case the user can't be identified.\"\n matTooltipPosition=\"above\">\n <mat-chip-set>\n <mat-chip class=\"chip\">To unidentified users, serve:</mat-chip>\n </mat-chip-set>\n </div>\n <div *ngIf=\"rolloutPercentageItems().length === 0 && rolloutRules().length === 0\">\n <mat-chip-set>\n <mat-chip class=\"chip\">To all users, serve:</mat-chip>\n </mat-chip-set>\n </div>\n <configcat-value class=\"served-value\" [valueFormControl]=\"value()\" [setting]=\"setting()\">\n </configcat-value>\n </div>\n <div class=\"buttons\">\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addRolloutRule()\" *ngIf=\"!readOnly\">\n {{rolloutRules().length === 0 ? 'Target specific users' : 'Add new targeting rule'}}\n </button>\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addSegmentRolloutRule()\" *ngIf=\"!readOnly\">\n {{rolloutRules().length === 0 ? 'Target segment' : 'Target new segment'}}\n </button>\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addRolloutPercentageItem()\"\n *ngIf=\"!readOnly\"\n [disabled]=\"setting().settingType === SettingType.Boolean && rolloutPercentageItems().length !== 0\">\n {{rolloutPercentageItems().length === 0 ? 'Target % of users' : 'Add new % option'}}\n </button>\n </div>\n </div>\n </div>\n</div>", styles: [".setting-full{position:relative;display:flex;flex-wrap:nowrap;flex-direction:column}.setting-full .delete{position:absolute;right:-10px;top:-10px;color:#ed5251;background-color:#fff;border-radius:50%;height:20px;width:20px;cursor:pointer}.setting-full .delete mat-icon{font-size:20px;height:20px;width:20px;opacity:.5}.setting-full .delete:hover mat-icon{opacity:1}.setting-full .setting-header{padding:1.5em .8em 0 1em}.setting-full .setting-header .setting-name{flex-direction:row}.setting-full .setting-header .setting-name:hover>.edit{visibility:visible}.setting-full .setting-header .setting-name .name{font-weight:700;word-wrap:break-word;max-width:100%}.setting-full .setting-header .setting-name .edit{margin:5px 0 0 5px;cursor:pointer;visibility:hidden;color:gray}.setting-full .setting-header .setting-name .edit:hover{visibility:visible}.setting-full .setting-header .setting-name .edit mat-icon{font-size:18px}.setting-full .setting-header .setting-meta{margin-left:auto;margin-right:14px;font-size:.7em;color:gray}.setting-full .setting-content{display:flex}.setting-full .setting-content .setting-details{display:flex;flex-direction:column;width:400px;padding:0 0 .5em .5em}.setting-full .setting-content .setting-details>*{margin:.5em}.setting-full .setting-content .setting-details .open{font-size:14px}.setting-full .setting-content .setting-details .integrations{font-size:.8rem}.setting-full .setting-content .setting-details .integrations>div{margin:3px}.setting-full .setting-content .setting-details .integrations>div>a:hover{text-decoration:underline}.setting-full .setting-content .setting-details .setting-key{word-wrap:break-word}.setting-full .setting-content .setting-details .description{font-size:.8em;white-space:pre-wrap;word-wrap:break-word;max-width:300px}.setting-full .setting-content .setting-details code{background-color:#d3d3d3;padding:3px 6px}.setting-full .setting-content .rules-list{width:100%;padding:0 .3em .3em 1em}.setting-full .setting-content .targeting-button{margin-left:.5rem;margin-right:.5rem;margin-bottom:1.5em;text-transform:uppercase}.all-other{min-height:40px;justify-content:flex-start;border:1px solid #d5d5d5;background-color:#fff;margin:.5em 1em;padding:4px 0 4px .5em}.all-other .chip{font-size:12px;background-color:#67b1fc3d}.all-other .served-value{margin-left:auto;margin-top:3px;margin-bottom:3px}.end{margin-left:auto}.buttons{display:flex;margin-left:.5rem;margin-right:.5rem}.buttons .updated-date{font-size:.7em;margin-left:auto;margin-right:22px;color:gray}.flex{display:flex;flex-wrap:wrap;align-items:center}.show-hide-toggle{margin-left:1em;cursor:pointer}.show-hide-toggle a{font-size:.8rem}.sige-button{background-color:#d9eadc;color:#363636;cursor:pointer;justify-content:center;padding:.375em .75em;text-align:center;white-space:nowrap;font-size:.75rem;border:1px solid #dbdbdb;box-shadow:none;display:inline-flex;font-family:Montserrat,Roboto,Helvetica Neue,sans-serif}.sige-button:hover{background-color:#bad0be}.sige-button:disabled{background-color:#fff;color:#b3b3b3}@media (max-width: 1200px){.setting-details{width:300px!important}}@media (max-width: 920px){.setting-full .setting-content{flex-wrap:wrap}.setting-full .setting-content .rules-list{padding:0}.setting-full .setting-content .targeting-button{margin-bottom:.5em;margin-top:.5em;padding:.6em 0}.colorbar{min-width:5px}.buttons{flex-direction:column;margin-bottom:.5em;margin-left:.4em;margin-right:.4em}.created-date,.updated-date{display:none}.setting-details{width:100%!important;padding:.2em 0 .2em .2em}.setting-details .description{max-width:none!important}.rollout-rules{margin-bottom:1em}.all-other{margin:1em;padding:7px 0 7px .5em}.all-other .served-value{margin:7px 7px 4px auto}}@media (max-width: 380px){.mat-mdc-standard-chip{min-height:auto!important;height:auto!important}.mat-chip-list-wrapper{padding-right:7px}.sige-button{font-size:.65rem}}\n"] }]
1069
- }], ctorParameters: function () { return [{ type: SettingListFormHelper }]; }, propDecorators: { dashboardBasePath: [{
1070
- type: Input
1071
- }], productId: [{
1072
- type: Input
1073
- }], environmentId: [{
1074
- type: Input
1075
- }], configId: [{
1076
- type: Input
1077
- }], formGroup: [{
1078
- type: Input
1079
- }], readOnly: [{
1080
- type: Input
1081
- }], canDeleteSetting: [{
1082
- type: Input
1083
- }], deleteSettingText: [{
1084
- type: Input
1085
- }], showEnvironmentName: [{
1086
- type: Input
1087
- }], segments: [{
1088
- type: Input
1089
- }], deleteSettingRequested: [{
1090
- type: Output
1091
- }] } });
1092
-
1093
- class SettingListComponent {
1094
- constructor(formHelper, snackBar, dialog) {
1095
- this.formHelper = formHelper;
1096
- this.snackBar = snackBar;
1097
- this.dialog = dialog;
1098
- this.dashboardBasePath = 'https://app.configcat.com';
1099
- this.canDeleteSetting = false;
1100
- this.deleteSettingText = 'Delete setting';
1101
- this.showEnvironmentName = false;
1102
- this.loadSucceeded = new EventEmitter();
1103
- this.deleteSettingRequested = new EventEmitter();
1104
- this.formValuesChanged = new EventEmitter();
1105
- this.loading = true;
1106
- this.submitting = false;
1107
- this.showRevertQuestion = false;
1108
- this.showFeedBackMessage = false;
1109
- this.readOnly = false;
1110
- }
1111
- ngOnChanges() {
1112
- this.reloadSettingValues();
1113
- }
1114
- ngOnDestroy() {
1115
- if (this.formValuesChangedSubscription) {
1116
- this.formValuesChangedSubscription.unsubscribe();
1117
- this.formValuesChangedSubscription = null;
1118
- }
1119
- }
1120
- reloadSettingValues() {
1121
- this.showFeedBackMessage = false;
1122
- this.loading = true;
1123
- forkJoin({
1124
- segments: this.loadSegments(),
1125
- settingValues: this.loadSettingValues()
1126
- }).subscribe(result => {
1127
- this.readOnly = result.settingValues.readOnly;
1128
- this.settingValues = result.settingValues;
1129
- this.segments = result.segments;
1130
- this.createFormGroup();
1131
- this.loading = false;
1132
- this.loadSucceeded.emit(true);
1133
- }, () => {
1134
- this.snackBar.open('Ooops. We could not load your Feature Flags and Settings. Please try again or contact us.', 'Dismiss', { duration: 60000, panelClass: 'red-snackbar' });
1135
- });
1136
- }
1137
- createFormGroup() {
1138
- this.formGroup = this.formHelper.createSettingValuesFormGroup(this.settingValues);
1139
- this.formValuesChangedSubscription = this.formGroup.valueChanges.subscribe(() => {
1140
- this.formValuesChanged.emit();
1141
- });
1142
- }
1143
- settingValuesFormArray() {
1144
- return this.formGroup.get('settingValues');
1145
- }
1146
- getSettingValueFormGroups() {
1147
- return this.settingValuesFormArray().controls.map(c => c);
1148
- }
1149
- buildUpdateSettingValuesModel(settingValuesVM) {
1150
- return settingValuesVM.map(settingValueVM => {
1151
- var _a, _b;
1152
- return {
1153
- rolloutRules: (_a = settingValueVM.rolloutRules) === null || _a === void 0 ? void 0 : _a.map(rolloutRuleVM => ({
1154
- comparisonAttribute: rolloutRuleVM.comparisonAttribute,
1155
- comparator: rolloutRuleVM.comparator,
1156
- comparisonValue: this.formHelper.normalizeComparisonValue(rolloutRuleVM.comparator, rolloutRuleVM.comparisonValue),
1157
- segmentComparator: rolloutRuleVM.segmentComparator,
1158
- segmentId: rolloutRuleVM.segmentId,
1159
- value: rolloutRuleVM.value
1160
- })),
1161
- rolloutPercentageItems: (_b = settingValueVM.rolloutPercentageItems) === null || _b === void 0 ? void 0 : _b.map(rolloutPercentageItemVM => ({
1162
- percentage: rolloutPercentageItemVM.percentage,
1163
- value: rolloutPercentageItemVM.value
1164
- })),
1165
- value: settingValueVM.value
1166
- };
1167
- });
1168
- }
1169
- submit() {
1170
- if (!this.formGroup || !this.formGroup.valid) {
1171
- this.showFeedBackMessage = true;
1172
- this.formGroup.markAsTouched();
1173
- return;
1174
- }
1175
- this.showFeedBackMessage = false;
1176
- this.submitting = true;
1177
- const updateSettingValuesModel = {
1178
- settingValues: this.buildUpdateSettingValuesModel(this.formGroup.controls.settingValues.value),
1179
- knownLastUpdatedAt: this.settingValues.lastUpdatedAt,
1180
- forced: false
1181
- };
1182
- if (this.settingValues.reasonRequired) {
1183
- const dialogRef = this.dialog.open(ReasonDialogComponent, {
1184
- width: '450px'
1185
- });
1186
- dialogRef.afterClosed()
1187
- .subscribe(result => {
1188
- if (result && result.button === 'save' && result.reason) {
1189
- updateSettingValuesModel.reason = result.reason;
1190
- this.updateSettingValues(updateSettingValuesModel);
1191
- }
1192
- else {
1193
- this.submitting = false;
1194
- }
1195
- });
1196
- return;
1197
- }
1198
- this.updateSettingValues(updateSettingValuesModel);
1199
- }
1200
- updateSettingValues(updateSettingValuesModel) {
1201
- this.onSave(updateSettingValuesModel).subscribe(settingValues => {
1202
- this.settingValues = settingValues;
1203
- this.createFormGroup();
1204
- this.submitting = false;
1205
- this.snackBar.openFromComponent(SaveSnackbarComponent, { duration: 5000, panelClass: 'green-snackbar' });
1206
- }, (error) => {
1207
- if (error.status === 400 && error.error && error.error.Reason && error.error.Reason[0] === 'Reason required') {
1208
- const dialogRef = this.dialog.open(ReasonDialogComponent, {
1209
- width: '450px'
1210
- });
1211
- dialogRef.afterClosed()
1212
- .subscribe(result => {
1213
- if (result && result.button === 'save' && result.reason) {
1214
- updateSettingValuesModel.reason = result.reason;
1215
- this.updateSettingValues(updateSettingValuesModel);
1216
- }
1217
- else {
1218
- this.submitting = false;
1219
- }
1220
- });
1221
- return;
1222
- }
1223
- this.formGroup.setErrors({ internalServerError: 'Internal server error' });
1224
- this.showFeedBackMessage = true;
1225
- });
1226
- }
1227
- handleRevertYes() {
1228
- this.showRevertQuestion = false;
1229
- this.reloadSettingValues();
1230
- }
1231
- handleRevertCancel() {
1232
- this.showRevertQuestion = false;
1233
- }
1234
- onDeleteSettingRequested(setting) {
1235
- this.deleteSettingRequested.emit({
1236
- setting: setting.setting,
1237
- environment: this.settingValues.environment,
1238
- config: this.settingValues.config
1239
- });
1240
- }
1241
- }
1242
- SettingListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SettingListComponent, deps: [{ token: SettingListFormHelper }, { token: i2$2.MatSnackBar }, { token: i1$1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
1243
- SettingListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: SettingListComponent, selector: "configcat-setting-list", inputs: { productId: "productId", environmentId: "environmentId", configId: "configId", dashboardBasePath: "dashboardBasePath", canDeleteSetting: "canDeleteSetting", onSave: "onSave", loadSettingValues: "loadSettingValues", loadSegments: "loadSegments", deleteSettingText: "deleteSettingText", showEnvironmentName: "showEnvironmentName" }, outputs: { loadSucceeded: "loadSucceeded", deleteSettingRequested: "deleteSettingRequested", formValuesChanged: "formValuesChanged" }, usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"submit()\" *ngIf=\"!loading\">\n <div class=\"wrapper\" *ngFor=\"let settingValueFromGroup of getSettingValueFormGroups(); let i = index\">\n <setting [formGroup]=\"settingValueFromGroup\" [readOnly]=\"readOnly\" [canDeleteSetting]=\"canDeleteSetting\"\n (deleteSettingRequested)=\"onDeleteSettingRequested($event)\" [deleteSettingText]=\"deleteSettingText\"\n [showEnvironmentName]=\"showEnvironmentName\" [segments]=\"segments\" [productId]=\"productId\" [configId]=\"configId\"\n [environmentId]=\"environmentId\" [dashboardBasePath]=\"dashboardBasePath\">\n </setting>\n </div>\n\n <div class=\"save\" *ngIf=\"!readOnly && !submitting && formGroup.dirty\">\n <div class=\"feedback\" *ngIf=\"formGroup.touched && formGroup.invalid && showFeedBackMessage\">\n <div class=\"error\" *ngIf=\"formGroup.errors && formGroup.errors.internalServerError\">\n <span>Something went wrong and we could not save your settings. You can try again or <a\n href=\"https://configcat.com/support\" target=\"_blank\" rel=\"noopener noreferrer\">contact us.</a></span>\n </div>\n <div class=\"error\" *ngIf=\"!formGroup.errors || !formGroup.errors.internalServerError\">\n <span>Oh no! A feature flag has invalid or missing data.</span>\n </div>\n </div>\n <button type=\"button\" mat-stroked-button *ngIf=\"!showRevertQuestion\" (click)=\"showRevertQuestion = true\">\n <mat-icon>history</mat-icon><span>Revert changes</span>\n </button>\n <div *ngIf=\"showRevertQuestion\">\n <span class=\"revert\">Revert to last saved state?</span>\n <button type=\"button\" class=\"yes\" mat-stroked-button (click)=\"handleRevertYes()\">Yes</button>\n <button type=\"button\" mat-stroked-button (click)=\"handleRevertCancel()\">No</button>\n </div>\n <button class=\"save-button\" mat-flat-button color=\"warn\" type=\"submit\" [disabled]=\"submitting\">\n <mat-icon>backup</mat-icon> <span> Save & publish changes</span>\n </button>\n </div>\n</form>", styles: [".wrapper{background-color:#f3f3f3;border:1px solid rgba(0,0,0,.12);margin:1em 0}.show-hide a{cursor:pointer;font-size:.8rem}.save{position:sticky;bottom:0;min-height:38px;padding:.5rem .5rem .5rem 0;background-color:#fff;display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:flex-end;z-index:1000}.save .save-button{animation:shadow-pulse 1s 3;margin-left:1rem}.save>*{margin:.3em}.save .revert{margin:0 16px;font-size:14px}.save .yes{margin:0 5px}.error{background-color:#a32b2d;color:#fff;padding:5px;font-size:.9em}.error a{color:#fff;text-decoration:underline}@media (max-width: 700px){.save{padding:.5rem 0}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i5.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: SettingComponent, selector: "setting", inputs: ["dashboardBasePath", "productId", "environmentId", "configId", "formGroup", "readOnly", "canDeleteSetting", "deleteSettingText", "showEnvironmentName", "segments"], outputs: ["deleteSettingRequested"] }] });
1244
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SettingListComponent, decorators: [{
1245
- type: Component,
1246
- args: [{ selector: 'configcat-setting-list', template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"submit()\" *ngIf=\"!loading\">\n <div class=\"wrapper\" *ngFor=\"let settingValueFromGroup of getSettingValueFormGroups(); let i = index\">\n <setting [formGroup]=\"settingValueFromGroup\" [readOnly]=\"readOnly\" [canDeleteSetting]=\"canDeleteSetting\"\n (deleteSettingRequested)=\"onDeleteSettingRequested($event)\" [deleteSettingText]=\"deleteSettingText\"\n [showEnvironmentName]=\"showEnvironmentName\" [segments]=\"segments\" [productId]=\"productId\" [configId]=\"configId\"\n [environmentId]=\"environmentId\" [dashboardBasePath]=\"dashboardBasePath\">\n </setting>\n </div>\n\n <div class=\"save\" *ngIf=\"!readOnly && !submitting && formGroup.dirty\">\n <div class=\"feedback\" *ngIf=\"formGroup.touched && formGroup.invalid && showFeedBackMessage\">\n <div class=\"error\" *ngIf=\"formGroup.errors && formGroup.errors.internalServerError\">\n <span>Something went wrong and we could not save your settings. You can try again or <a\n href=\"https://configcat.com/support\" target=\"_blank\" rel=\"noopener noreferrer\">contact us.</a></span>\n </div>\n <div class=\"error\" *ngIf=\"!formGroup.errors || !formGroup.errors.internalServerError\">\n <span>Oh no! A feature flag has invalid or missing data.</span>\n </div>\n </div>\n <button type=\"button\" mat-stroked-button *ngIf=\"!showRevertQuestion\" (click)=\"showRevertQuestion = true\">\n <mat-icon>history</mat-icon><span>Revert changes</span>\n </button>\n <div *ngIf=\"showRevertQuestion\">\n <span class=\"revert\">Revert to last saved state?</span>\n <button type=\"button\" class=\"yes\" mat-stroked-button (click)=\"handleRevertYes()\">Yes</button>\n <button type=\"button\" mat-stroked-button (click)=\"handleRevertCancel()\">No</button>\n </div>\n <button class=\"save-button\" mat-flat-button color=\"warn\" type=\"submit\" [disabled]=\"submitting\">\n <mat-icon>backup</mat-icon> <span> Save & publish changes</span>\n </button>\n </div>\n</form>", styles: [".wrapper{background-color:#f3f3f3;border:1px solid rgba(0,0,0,.12);margin:1em 0}.show-hide a{cursor:pointer;font-size:.8rem}.save{position:sticky;bottom:0;min-height:38px;padding:.5rem .5rem .5rem 0;background-color:#fff;display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:flex-end;z-index:1000}.save .save-button{animation:shadow-pulse 1s 3;margin-left:1rem}.save>*{margin:.3em}.save .revert{margin:0 16px;font-size:14px}.save .yes{margin:0 5px}.error{background-color:#a32b2d;color:#fff;padding:5px;font-size:.9em}.error a{color:#fff;text-decoration:underline}@media (max-width: 700px){.save{padding:.5rem 0}}\n"] }]
1247
- }], ctorParameters: function () { return [{ type: SettingListFormHelper }, { type: i2$2.MatSnackBar }, { type: i1$1.MatDialog }]; }, propDecorators: { productId: [{
1248
- type: Input
1249
- }], environmentId: [{
1250
- type: Input
1251
- }], configId: [{
1252
- type: Input
1253
- }], dashboardBasePath: [{
1254
- type: Input
1255
- }], canDeleteSetting: [{
1256
- type: Input
1257
- }], onSave: [{
1258
- type: Input
1259
- }], loadSettingValues: [{
1260
- type: Input
1261
- }], loadSegments: [{
1262
- type: Input
1263
- }], deleteSettingText: [{
1264
- type: Input
1265
- }], showEnvironmentName: [{
1266
- type: Input
1267
- }], loadSucceeded: [{
1268
- type: Output
1269
- }], deleteSettingRequested: [{
1270
- type: Output
1271
- }], formValuesChanged: [{
1272
- type: Output
1273
- }] } });
1274
-
1275
- class SettingItemComponent extends BaseComponent {
1276
- constructor(publicApiService) {
1277
- super(publicApiService);
1278
- this.canDeleteSetting = true;
1279
- this.deleteSettingText = 'Delete setting';
1280
- this.showEnvironmentName = true;
1281
- this.deleteSettingRequested = new EventEmitter();
1282
- this.loadSucceeded = new EventEmitter();
1283
- this.loadFailed = new EventEmitter();
1284
- this.saveSucceeded = new EventEmitter();
1285
- this.saveFailed = new EventEmitter();
1286
- this.formValuesChanged = new EventEmitter();
1287
- this.loadSettingValues = () => {
1288
- return this.createSettingValuesService().getSettingValue(this.environmentId, this.settingId)
1289
- .pipe(map(settingValue => {
1290
- this.settingValue = settingValue;
1291
- const settingValues = {
1292
- settingValues: [settingValue],
1293
- readOnly: settingValue.readOnly,
1294
- config: settingValue.config,
1295
- environment: settingValue.environment
1296
- };
1297
- return settingValues;
1298
- }), catchError(error => {
1299
- this.loadFailed.emit(error);
1300
- return throwError(error);
1301
- }));
1302
- };
1303
- this.loadSegments = () => {
1304
- return this.createSegmentsService().getSegments(this.productId)
1305
- .pipe(map(segments => {
1306
- this.segments = segments;
1307
- return segments;
1308
- }), catchError(error => {
1309
- return throwError(error);
1310
- }));
1311
- };
1312
- this.handleSave = (model) => {
1313
- if (model.settingValues.length === 0) {
1314
- return of();
1315
- }
1316
- const updateModel = model.settingValues[0];
1317
- return this.createSettingValuesService().replaceSettingValue(this.environmentId, this.settingId, updateModel, model.reason)
1318
- .pipe(map(settingValue => {
1319
- this.settingValue = settingValue;
1320
- const settingValues = {
1321
- settingValues: [settingValue],
1322
- readOnly: settingValue.readOnly,
1323
- config: settingValue.config,
1324
- environment: settingValue.environment
1325
- };
1326
- this.saveSucceeded.emit(settingValues);
1327
- return settingValues;
1328
- }), catchError(error => {
1329
- this.saveFailed.emit(error);
1330
- return throwError(error);
1331
- }));
1332
- };
1333
- this.dashboardBasePath = publicApiService.getDashboardBasePath();
1334
- }
1335
- ngOnInit() {
1336
- }
1337
- itemLoadSucceeded() {
1338
- this.loadSucceeded.emit(true);
1339
- }
1340
- onDeleteSettingRequested(setting) {
1341
- this.deleteSettingRequested.emit({
1342
- setting: setting.setting,
1343
- environment: this.settingValue.environment,
1344
- config: this.settingValue.config
1345
- });
1346
- }
1347
- onFormValuesChanged() {
1348
- this.formValuesChanged.emit();
1349
- }
1350
- }
1351
- SettingItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SettingItemComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1352
- SettingItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: SettingItemComponent, selector: "configcat-setting-item", inputs: { productId: "productId", environmentId: "environmentId", configId: "configId", settingId: "settingId", canDeleteSetting: "canDeleteSetting", deleteSettingText: "deleteSettingText", showEnvironmentName: "showEnvironmentName" }, outputs: { deleteSettingRequested: "deleteSettingRequested", loadSucceeded: "loadSucceeded", loadFailed: "loadFailed", saveSucceeded: "saveSucceeded", saveFailed: "saveFailed", formValuesChanged: "formValuesChanged" }, usesInheritance: true, ngImport: i0, template: "<configcat-setting-list [canDeleteSetting]=\"canDeleteSetting\" [onSave]=\"handleSave\"\n [loadSettingValues]=\"loadSettingValues\" [loadSegments]=\"loadSegments\" (loadSucceeded)=\"itemLoadSucceeded()\"\n (deleteSettingRequested)=\"onDeleteSettingRequested($event)\" [deleteSettingText]=\"deleteSettingText\"\n [showEnvironmentName]=\"showEnvironmentName\" (formValuesChanged)=\"onFormValuesChanged()\" [productId]=\"productId\"\n [configId]=\"configId\" [environmentId]=\"environmentId\" [dashboardBasePath]=\"dashboardBasePath\">\n</configcat-setting-list>", styles: [".container{font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;background-color:#f3f3f3;border:1px solid rgba(0,0,0,.12);border-radius:4px;margin:1em 0}.container .setting-full{position:relative;display:flex;flex-wrap:nowrap}.container .setting-full .setting-details{display:flex;flex-direction:column;width:400px;padding:1em 0 1em 1em}.container .setting-full .setting-details>*{margin:.5em}.container .setting-full .setting-details .setting-name{flex-direction:row}.container .setting-full .setting-details .setting-name .name{font-weight:700;word-wrap:break-word;max-width:100%}.container .setting-full .setting-details .setting-key{word-wrap:break-word}.container .setting-full .setting-details .description{font-size:.8em}.container .setting-full .setting-details code{background-color:#d3d3d3;padding:3px 6px}.container .setting-full .rules-list{width:100%;padding:1em}.container .setting-full .targeting-button{margin-left:1rem;margin-bottom:1em}.all-other{min-height:40px;justify-content:flex-start;border:1px solid #d5d5d5;border-radius:4px;background-color:#fff;margin:.5em 1em;padding:4px 0 4px .5em}.all-other .chip{background-color:#67b1fc3d}.all-other .served-value{margin-left:auto;min-width:100px}.end{margin-left:auto}.flex{display:flex;flex-wrap:wrap;align-items:center}.show-hide-toggle{margin-left:1em;cursor:pointer}@media (max-width: 1200px){.setting-full .setting-details{width:300px}}@media (max-width: 700px){.setting-full{flex-wrap:wrap}.setting-full .setting-details{padding:.2em 0 .2em .2em}.setting-full .all-other{margin:.5em .3em}}\n"], dependencies: [{ kind: "component", type: SettingListComponent, selector: "configcat-setting-list", inputs: ["productId", "environmentId", "configId", "dashboardBasePath", "canDeleteSetting", "onSave", "loadSettingValues", "loadSegments", "deleteSettingText", "showEnvironmentName"], outputs: ["loadSucceeded", "deleteSettingRequested", "formValuesChanged"] }] });
1353
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SettingItemComponent, decorators: [{
1354
- type: Component,
1355
- args: [{ selector: 'configcat-setting-item', template: "<configcat-setting-list [canDeleteSetting]=\"canDeleteSetting\" [onSave]=\"handleSave\"\n [loadSettingValues]=\"loadSettingValues\" [loadSegments]=\"loadSegments\" (loadSucceeded)=\"itemLoadSucceeded()\"\n (deleteSettingRequested)=\"onDeleteSettingRequested($event)\" [deleteSettingText]=\"deleteSettingText\"\n [showEnvironmentName]=\"showEnvironmentName\" (formValuesChanged)=\"onFormValuesChanged()\" [productId]=\"productId\"\n [configId]=\"configId\" [environmentId]=\"environmentId\" [dashboardBasePath]=\"dashboardBasePath\">\n</configcat-setting-list>", styles: [".container{font-family:Montserrat,Roboto,Helvetica Neue,sans-serif;background-color:#f3f3f3;border:1px solid rgba(0,0,0,.12);border-radius:4px;margin:1em 0}.container .setting-full{position:relative;display:flex;flex-wrap:nowrap}.container .setting-full .setting-details{display:flex;flex-direction:column;width:400px;padding:1em 0 1em 1em}.container .setting-full .setting-details>*{margin:.5em}.container .setting-full .setting-details .setting-name{flex-direction:row}.container .setting-full .setting-details .setting-name .name{font-weight:700;word-wrap:break-word;max-width:100%}.container .setting-full .setting-details .setting-key{word-wrap:break-word}.container .setting-full .setting-details .description{font-size:.8em}.container .setting-full .setting-details code{background-color:#d3d3d3;padding:3px 6px}.container .setting-full .rules-list{width:100%;padding:1em}.container .setting-full .targeting-button{margin-left:1rem;margin-bottom:1em}.all-other{min-height:40px;justify-content:flex-start;border:1px solid #d5d5d5;border-radius:4px;background-color:#fff;margin:.5em 1em;padding:4px 0 4px .5em}.all-other .chip{background-color:#67b1fc3d}.all-other .served-value{margin-left:auto;min-width:100px}.end{margin-left:auto}.flex{display:flex;flex-wrap:wrap;align-items:center}.show-hide-toggle{margin-left:1em;cursor:pointer}@media (max-width: 1200px){.setting-full .setting-details{width:300px}}@media (max-width: 700px){.setting-full{flex-wrap:wrap}.setting-full .setting-details{padding:.2em 0 .2em .2em}.setting-full .all-other{margin:.5em .3em}}\n"] }]
1356
- }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { productId: [{
1357
- type: Input
1358
- }], environmentId: [{
1359
- type: Input
1360
- }], configId: [{
1361
- type: Input
1362
- }], settingId: [{
1363
- type: Input
1364
- }], canDeleteSetting: [{
1365
- type: Input
1366
- }], deleteSettingText: [{
1367
- type: Input
1368
- }], showEnvironmentName: [{
1369
- type: Input
1370
- }], deleteSettingRequested: [{
1371
- type: Output
1372
- }], loadSucceeded: [{
1373
- type: Output
1374
- }], loadFailed: [{
1375
- type: Output
1376
- }], saveSucceeded: [{
1377
- type: Output
1378
- }], saveFailed: [{
1379
- type: Output
1380
- }], formValuesChanged: [{
1381
- type: Output
1382
- }] } });
1383
-
1384
- class BaseSelectComponent extends BaseComponent {
1385
- constructor() {
1386
- super(...arguments);
1387
- this.customDropdown = false;
1388
- this.dropdownOpened = new EventEmitter();
1389
- }
1390
- openChanged(event) {
1391
- this.dropdownOpened.emit(event);
1392
- }
1393
- }
1394
- BaseSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: BaseSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1395
- BaseSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: BaseSelectComponent, selector: "base-select", inputs: { customDropdown: "customDropdown" }, outputs: { dropdownOpened: "dropdownOpened" }, usesInheritance: true, ngImport: i0, template: '<div></div>', isInline: true });
1396
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: BaseSelectComponent, decorators: [{
1397
- type: Component,
1398
- args: [{
1399
- selector: 'base-select',
1400
- template: '<div></div>'
1401
- }]
1402
- }], propDecorators: { customDropdown: [{
1403
- type: Input
1404
- }], dropdownOpened: [{
1405
- type: Output
1406
- }] } });
1407
-
1408
- class SettingSelectComponent extends BaseSelectComponent {
1409
- constructor(publicApiService) {
1410
- super(publicApiService);
1411
- this.settings = [];
1412
- }
1413
- ngOnInit() {
1414
- this.settings = [];
1415
- this.reloadSettings();
1416
- }
1417
- ngOnChanges() {
1418
- this.reloadSettings();
1419
- }
1420
- reloadSettings() {
1421
- if (this.configId) {
1422
- this.createSettingsService().getSettings(this.configId).subscribe(settings => {
1423
- this.settings = settings;
1424
- if (this.settings.length > 0) {
1425
- this.valueFormControl.setValue(this.settings[0].settingId);
1426
- }
1427
- else {
1428
- this.valueFormControl.setValue("");
1429
- }
1430
- });
1431
- }
1432
- }
1433
- }
1434
- SettingSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SettingSelectComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1435
- SettingSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: SettingSelectComponent, selector: "configcat-setting-select", inputs: { valueFormControl: "valueFormControl", configId: "configId" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<mat-form-field class=\"form-field\" appearance=\"outline\" *ngIf=\"settings\">\n <mat-label>Feature flag or setting</mat-label>\n <mat-select placeholder=\"Feature flag or setting\" [formControl]=\"valueFormControl\" name=\"value\"\n (openedChange)=\"openChanged($event)\" [panelClass]=\"customDropdown ? 'custom-dropdown-below' : ''\">\n <mat-option *ngFor=\"let setting of settings\" [value]=\"setting.settingId\" matTooltip=\"{{setting.name}}\"\n [matTooltipShowDelay]=\"1000\">{{setting.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
1436
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SettingSelectComponent, decorators: [{
1437
- type: Component,
1438
- args: [{ selector: 'configcat-setting-select', template: "<mat-form-field class=\"form-field\" appearance=\"outline\" *ngIf=\"settings\">\n <mat-label>Feature flag or setting</mat-label>\n <mat-select placeholder=\"Feature flag or setting\" [formControl]=\"valueFormControl\" name=\"value\"\n (openedChange)=\"openChanged($event)\" [panelClass]=\"customDropdown ? 'custom-dropdown-below' : ''\">\n <mat-option *ngFor=\"let setting of settings\" [value]=\"setting.settingId\" matTooltip=\"{{setting.name}}\"\n [matTooltipShowDelay]=\"1000\">{{setting.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"] }]
1439
- }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { valueFormControl: [{
1440
- type: Input
1441
- }], configId: [{
1442
- type: Input
1443
- }] } });
1444
-
1445
- class ProductSelectComponent extends BaseSelectComponent {
1446
- constructor(publicApiService) {
1447
- super(publicApiService);
1448
- this.products = [];
1449
- }
1450
- ngOnInit() {
1451
- this.products = [];
1452
- this.createProductsService().getProducts().subscribe(products => {
1453
- this.products = products;
1454
- if (this.products.length > 0) {
1455
- this.valueFormControl.setValue(this.products[0].productId, {
1456
- emitEvent: true,
1457
- emitModelToViewChange: true, emitViewToModelChange: true
1458
- });
1459
- }
1460
- else {
1461
- this.valueFormControl.setValue("");
1462
- }
1463
- });
1464
- }
1465
- }
1466
- ProductSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ProductSelectComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1467
- ProductSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ProductSelectComponent, selector: "configcat-product-select", inputs: { valueFormControl: "valueFormControl" }, usesInheritance: true, ngImport: i0, template: "<mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Product</mat-label>\n <mat-select placeholder=\"Product\" [formControl]=\"valueFormControl\" name=\"productValue\"\n (openedChange)=\"openChanged($event)\" [panelClass]=\"customDropdown ? 'custom-dropdown-below' : ''\">\n <mat-option *ngFor=\"let product of products\" [value]=\"product.productId\" matTooltip=\"{{product.name}}\"\n [matTooltipShowDelay]=\"1000\">{{product.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
1468
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ProductSelectComponent, decorators: [{
1469
- type: Component,
1470
- args: [{ selector: 'configcat-product-select', template: "<mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Product</mat-label>\n <mat-select placeholder=\"Product\" [formControl]=\"valueFormControl\" name=\"productValue\"\n (openedChange)=\"openChanged($event)\" [panelClass]=\"customDropdown ? 'custom-dropdown-below' : ''\">\n <mat-option *ngFor=\"let product of products\" [value]=\"product.productId\" matTooltip=\"{{product.name}}\"\n [matTooltipShowDelay]=\"1000\">{{product.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"] }]
1471
- }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { valueFormControl: [{
1472
- type: Input
1473
- }] } });
1474
-
1475
- class ConfigSelectComponent extends BaseSelectComponent {
1476
- constructor(publicApiService) {
1477
- super(publicApiService);
1478
- this.configs = [];
1479
- }
1480
- ngOnInit() {
1481
- this.configs = [];
1482
- this.reloadConfigs();
1483
- }
1484
- ngOnChanges() {
1485
- this.reloadConfigs();
1486
- }
1487
- reloadConfigs() {
1488
- if (this.productId) {
1489
- this.createConfigsService().getConfigs(this.productId).subscribe(configs => {
1490
- this.configs = configs;
1491
- if (this.configs.length > 0) {
1492
- this.valueFormControl.setValue(this.configs[0].configId);
1493
- }
1494
- else {
1495
- this.valueFormControl.setValue("");
1496
- }
1497
- });
1498
- }
1499
- }
1500
- }
1501
- ConfigSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ConfigSelectComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1502
- ConfigSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: ConfigSelectComponent, selector: "configcat-config-select", inputs: { valueFormControl: "valueFormControl", productId: "productId" }, providers: [
1503
- {
1504
- provide: NG_VALUE_ACCESSOR,
1505
- useExisting: forwardRef(() => ConfigSelectComponent),
1506
- multi: true
1507
- }
1508
- ], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<mat-form-field class=\"form-field\" appearance=\"outline\" *ngIf=\"configs\">\n <mat-label>Config</mat-label>\n <mat-select placeholder=\"Config\" [formControl]=\"valueFormControl\" name=\"value\" disableOptionCentering\n (openedChange)=\"openChanged($event)\" [panelClass]=\"customDropdown ? 'custom-dropdown-below' : ''\">\n <mat-option *ngFor=\"let config of configs\" [value]=\"config.configId\" matTooltip=\"{{config.name}}\"\n [matTooltipShowDelay]=\"1000\">{{config.name}}</mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
1509
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ConfigSelectComponent, decorators: [{
1510
- type: Component,
1511
- args: [{ selector: 'configcat-config-select', providers: [
1512
- {
1513
- provide: NG_VALUE_ACCESSOR,
1514
- useExisting: forwardRef(() => ConfigSelectComponent),
1515
- multi: true
1516
- }
1517
- ], template: "<mat-form-field class=\"form-field\" appearance=\"outline\" *ngIf=\"configs\">\n <mat-label>Config</mat-label>\n <mat-select placeholder=\"Config\" [formControl]=\"valueFormControl\" name=\"value\" disableOptionCentering\n (openedChange)=\"openChanged($event)\" [panelClass]=\"customDropdown ? 'custom-dropdown-below' : ''\">\n <mat-option *ngFor=\"let config of configs\" [value]=\"config.configId\" matTooltip=\"{{config.name}}\"\n [matTooltipShowDelay]=\"1000\">{{config.name}}</mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"] }]
1518
- }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { valueFormControl: [{
1519
- type: Input
1520
- }], productId: [{
1521
- type: Input
1522
- }] } });
1523
-
1524
- class EnvironmentSelectComponent extends BaseSelectComponent {
1525
- constructor(publicApiService) {
1526
- super(publicApiService);
1527
- this.environments = [];
1528
- }
1529
- ngOnInit() {
1530
- this.environments = [];
1531
- this.reloadEnvironments();
1532
- }
1533
- ngOnChanges() {
1534
- this.reloadEnvironments();
1535
- }
1536
- reloadEnvironments() {
1537
- if (this.productId) {
1538
- this.createEnvironmentsService().getEnvironments(this.productId).subscribe(environments => {
1539
- this.environments = environments;
1540
- if (this.environments.length > 0) {
1541
- this.valueFormControl.setValue(this.environments[0].environmentId);
1542
- }
1543
- else {
1544
- this.valueFormControl.setValue("");
1545
- }
1546
- });
1547
- }
1548
- }
1549
- }
1550
- EnvironmentSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EnvironmentSelectComponent, deps: [{ token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1551
- EnvironmentSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: EnvironmentSelectComponent, selector: "configcat-environment-select", inputs: { valueFormControl: "valueFormControl", productId: "productId" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<mat-form-field class=\"form-field\" appearance=\"outline\" *ngIf=\"environments\">\n <mat-label>Environment</mat-label>\n <mat-select placeholder=\"Environment\" [formControl]=\"valueFormControl\" name=\"value\"\n (openedChange)=\"openChanged($event)\" [panelClass]=\"customDropdown ? 'custom-dropdown-below' : ''\">\n <mat-option *ngFor=\"let environment of environments\" [value]=\"environment.environmentId\"\n matTooltip=\"{{environment.name}}\" [matTooltipShowDelay]=\"1000\">{{environment.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"], dependencies: [{ kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i5$2.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "directive", type: i7$1.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
1552
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: EnvironmentSelectComponent, decorators: [{
1553
- type: Component,
1554
- args: [{ selector: 'configcat-environment-select', template: "<mat-form-field class=\"form-field\" appearance=\"outline\" *ngIf=\"environments\">\n <mat-label>Environment</mat-label>\n <mat-select placeholder=\"Environment\" [formControl]=\"valueFormControl\" name=\"value\"\n (openedChange)=\"openChanged($event)\" [panelClass]=\"customDropdown ? 'custom-dropdown-below' : ''\">\n <mat-option *ngFor=\"let environment of environments\" [value]=\"environment.environmentId\"\n matTooltip=\"{{environment.name}}\" [matTooltipShowDelay]=\"1000\">{{environment.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>", styles: [".form-field{width:100%}\n"] }]
1555
- }], ctorParameters: function () { return [{ type: PublicApiService }]; }, propDecorators: { valueFormControl: [{
1556
- type: Input
1557
- }], productId: [{
1558
- type: Input
1559
- }] } });
1560
-
1561
- class AuthorizationComponent {
1562
- constructor(formBuilder, publicApiService) {
1563
- this.formBuilder = formBuilder;
1564
- this.publicApiService = publicApiService;
1565
- this.basePath = null;
1566
- this.integrationName = 'ConfigCat Feature Flags';
1567
- this.authorized = new EventEmitter();
1568
- this.error = new EventEmitter();
1569
- this.FormHelper = FormHelper;
1570
- }
1571
- ngOnInit() {
1572
- this.formGroup = this.formBuilder.group({
1573
- basicAuthUsername: ['', Validators.required],
1574
- basicAuthPassword: ['', Validators.required],
1575
- });
1576
- }
1577
- onSubmit() {
1578
- if (!this.formGroup.valid) {
1579
- return;
1580
- }
1581
- const meService = this.publicApiService.createMeService(this.formGroup.controls.basicAuthUsername.value, this.formGroup.controls.basicAuthPassword.value, this.basePath);
1582
- meService.getMe().subscribe(me => {
1583
- this.authorized.emit({
1584
- basicAuthUsername: this.formGroup.controls.basicAuthUsername.value,
1585
- basicAuthPassword: this.formGroup.controls.basicAuthPassword.value,
1586
- email: me.email,
1587
- fullName: me.fullName
1588
- });
1589
- }, () => {
1590
- this.formGroup.setErrors({ invalidAuthorization: 'Invalid Basic auth user name or password' });
1591
- this.error.emit();
1592
- });
1593
- }
1594
- getPublicApiUrl() {
1595
- return this.publicApiService.getDashboardBasePath() + '/my-account/public-api-credentials';
1596
- }
1597
- }
1598
- AuthorizationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AuthorizationComponent, deps: [{ token: i2.UntypedFormBuilder }, { token: PublicApiService }], target: i0.ɵɵFactoryTarget.Component });
1599
- AuthorizationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: AuthorizationComponent, selector: "configcat-authorization", inputs: { basePath: "basePath", integrationName: "integrationName" }, outputs: { authorized: "authorized", error: "error" }, ngImport: i0, template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n <div class=\"container\">\n <div class=\"form\">\n <p>\n In order to use {{integrationName}} you have to authorize first with your ConfigCat Public API\n credentials.\n </p>\n <ul>\n <li>\n <a [href]=\"getPublicApiUrl()\" target=\"_blank\">\n Get your Basic Auth user name and password</a> to access ConfigCat Public API.\n <br />\n <b>Note!</b> Your ConfigCat account's email address and password will not work here.\n </li>\n <li>\n Type your credentials here and click the Authorize button.\n </li>\n </ul>\n\n <mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Basic auth user name</mat-label>\n <input matInput placeholder=\"Basic auth user name\" formControlName=\"basicAuthUsername\">\n <mat-error *ngIf=\"formGroup.controls.basicAuthUsername.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.basicAuthUsername)}}\n </mat-error>\n </mat-form-field>\n <mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Basic auth password</mat-label>\n <input matInput placeholder=\"Basic auth password\" formControlName=\"basicAuthPassword\" type=\"password\"\n autocomplete=\"current-password\">\n <mat-error *ngIf=\"formGroup.controls.basicAuthPassword.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.basicAuthPassword)}}\n </mat-error>\n </mat-form-field>\n <div>\n <button mat-flat-button color=\"primary\" type=\"submit\" class=\"submit\">Authorize</button>\n <mat-error *ngIf=\"formGroup.invalid && formGroup.errors && formGroup.errors.invalidAuthorization\">\n {{formGroup.errors.invalidAuthorization}}</mat-error>\n </div>\n </div>\n </div>\n</form>", styles: [".container{display:flex;margin:8px}.form{width:100%}.form-field{width:100%;margin-bottom:8px}.submit{margin-top:8px;margin-bottom:8px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i5.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }] });
1600
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AuthorizationComponent, decorators: [{
1601
- type: Component,
1602
- args: [{ selector: 'configcat-authorization', template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n <div class=\"container\">\n <div class=\"form\">\n <p>\n In order to use {{integrationName}} you have to authorize first with your ConfigCat Public API\n credentials.\n </p>\n <ul>\n <li>\n <a [href]=\"getPublicApiUrl()\" target=\"_blank\">\n Get your Basic Auth user name and password</a> to access ConfigCat Public API.\n <br />\n <b>Note!</b> Your ConfigCat account's email address and password will not work here.\n </li>\n <li>\n Type your credentials here and click the Authorize button.\n </li>\n </ul>\n\n <mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Basic auth user name</mat-label>\n <input matInput placeholder=\"Basic auth user name\" formControlName=\"basicAuthUsername\">\n <mat-error *ngIf=\"formGroup.controls.basicAuthUsername.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.basicAuthUsername)}}\n </mat-error>\n </mat-form-field>\n <mat-form-field class=\"form-field\" appearance=\"outline\">\n <mat-label>Basic auth password</mat-label>\n <input matInput placeholder=\"Basic auth password\" formControlName=\"basicAuthPassword\" type=\"password\"\n autocomplete=\"current-password\">\n <mat-error *ngIf=\"formGroup.controls.basicAuthPassword.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.basicAuthPassword)}}\n </mat-error>\n </mat-form-field>\n <div>\n <button mat-flat-button color=\"primary\" type=\"submit\" class=\"submit\">Authorize</button>\n <mat-error *ngIf=\"formGroup.invalid && formGroup.errors && formGroup.errors.invalidAuthorization\">\n {{formGroup.errors.invalidAuthorization}}</mat-error>\n </div>\n </div>\n </div>\n</form>", styles: [".container{display:flex;margin:8px}.form{width:100%}.form-field{width:100%;margin-bottom:8px}.submit{margin-top:8px;margin-bottom:8px}\n"] }]
1603
- }], ctorParameters: function () { return [{ type: i2.UntypedFormBuilder }, { type: PublicApiService }]; }, propDecorators: { basePath: [{
1604
- type: Input
1605
- }], integrationName: [{
1606
- type: Input
1607
- }], authorized: [{
1608
- type: Output
1609
- }], error: [{
1610
- type: Output
1611
- }] } });
1612
-
1613
- class DeleteSettingDialogComponent {
1614
- constructor(dialogRef, data) {
1615
- this.dialogRef = dialogRef;
1616
- this.data = data;
1617
- }
1618
- remove() {
1619
- this.dialogRef.close({ button: 'remove' });
1620
- }
1621
- cancel() {
1622
- this.dialogRef.close({ button: 'cancel' });
1623
- }
1624
- }
1625
- DeleteSettingDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DeleteSettingDialogComponent, deps: [{ token: i1$1.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
1626
- DeleteSettingDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: DeleteSettingDialogComponent, selector: "app-delete-setting-dialog", ngImport: i0, template: "<h1 mat-dialog-title>Remove Feature Flag or Setting from {{data.system}}</h1>\n<div mat-dialog-actions class=\"container\">\n <button type=\"button\" mat-raised-button color=\"primary\" (click)=\"remove()\">Remove from {{data.ticketType}}</button>\n <button type=\"button\" mat-raised-button (click)=\"cancel()\">Cancel</button>\n</div>", styles: [""], dependencies: [{ kind: "component", type: i5.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i1$1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }] });
1627
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DeleteSettingDialogComponent, decorators: [{
1628
- type: Component,
1629
- args: [{ selector: 'app-delete-setting-dialog', template: "<h1 mat-dialog-title>Remove Feature Flag or Setting from {{data.system}}</h1>\n<div mat-dialog-actions class=\"container\">\n <button type=\"button\" mat-raised-button color=\"primary\" (click)=\"remove()\">Remove from {{data.ticketType}}</button>\n <button type=\"button\" mat-raised-button (click)=\"cancel()\">Cancel</button>\n</div>" }]
1630
- }], ctorParameters: function () {
1631
- return [{ type: i1$1.MatDialogRef }, { type: undefined, decorators: [{
1632
- type: Inject,
1633
- args: [MAT_DIALOG_DATA]
1634
- }] }];
1635
- } });
1636
-
1637
- class NgConfigCatPublicApiUIModule {
1638
- static forRoot(configurationFactory) {
1639
- return {
1640
- ngModule: NgConfigCatPublicApiUIModule,
1641
- providers: [{ provide: Configuration, useFactory: configurationFactory }]
1642
- };
1643
- }
1644
- constructor() { }
1645
- }
1646
- NgConfigCatPublicApiUIModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgConfigCatPublicApiUIModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1647
- NgConfigCatPublicApiUIModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: NgConfigCatPublicApiUIModule, declarations: [BaseComponent,
1648
- BaseSelectComponent,
1649
- ProductSelectComponent,
1650
- ConfigSelectComponent,
1651
- EnvironmentSelectComponent,
1652
- SettingSelectComponent,
1653
- SettingItemComponent,
1654
- AuthorizationComponent,
1655
- SettingListComponent,
1656
- SettingComponent,
1657
- RolloutPercentageItemsComponent,
1658
- RolloutRulesComponent,
1659
- ValueComponent,
1660
- ReasonDialogComponent,
1661
- SaveSnackbarComponent,
1662
- ExpandDialogComponent,
1663
- DeleteSettingDialogComponent,
1664
- InputDisplayNormalizerDirective], imports: [CommonModule,
1665
- FormsModule,
1666
- ReactiveFormsModule,
1667
- BrowserAnimationsModule,
1668
- MatFormFieldModule,
1669
- MatOptionModule,
1670
- MatSelectModule,
1671
- MatButtonModule,
1672
- MatInputModule,
1673
- MatIconModule,
1674
- MatTooltipModule,
1675
- MatChipsModule,
1676
- MatAutocompleteModule,
1677
- DragDropModule,
1678
- RouterModule,
1679
- MatSnackBarModule,
1680
- MatDialogModule,
1681
- MatMenuModule,
1682
- ApiModule], exports: [AuthorizationComponent,
1683
- ProductSelectComponent,
1684
- ConfigSelectComponent,
1685
- EnvironmentSelectComponent,
1686
- SettingSelectComponent,
1687
- SettingItemComponent,
1688
- InputDisplayNormalizerDirective,
1689
- DeleteSettingDialogComponent] });
1690
- NgConfigCatPublicApiUIModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgConfigCatPublicApiUIModule, providers: [
1691
- {
1692
- provide: MAT_TOOLTIP_DEFAULT_OPTIONS,
1693
- useValue: { disableTooltipInteractivity: true },
1694
- },
1695
- ], imports: [CommonModule,
1696
- FormsModule,
1697
- ReactiveFormsModule,
1698
- BrowserAnimationsModule,
1699
- MatFormFieldModule,
1700
- MatOptionModule,
1701
- MatSelectModule,
1702
- MatButtonModule,
1703
- MatInputModule,
1704
- MatIconModule,
1705
- MatTooltipModule,
1706
- MatChipsModule,
1707
- MatAutocompleteModule,
1708
- DragDropModule,
1709
- RouterModule,
1710
- MatSnackBarModule,
1711
- MatDialogModule,
1712
- MatMenuModule,
1713
- ApiModule] });
1714
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgConfigCatPublicApiUIModule, decorators: [{
1715
- type: NgModule,
1716
- args: [{
1717
- declarations: [
1718
- BaseComponent,
1719
- BaseSelectComponent,
1720
- ProductSelectComponent,
1721
- ConfigSelectComponent,
1722
- EnvironmentSelectComponent,
1723
- SettingSelectComponent,
1724
- SettingItemComponent,
1725
- AuthorizationComponent,
1726
- SettingListComponent,
1727
- SettingComponent,
1728
- RolloutPercentageItemsComponent,
1729
- RolloutRulesComponent,
1730
- ValueComponent,
1731
- ReasonDialogComponent,
1732
- SaveSnackbarComponent,
1733
- ExpandDialogComponent,
1734
- DeleteSettingDialogComponent,
1735
- InputDisplayNormalizerDirective
1736
- ],
1737
- imports: [
1738
- CommonModule,
1739
- FormsModule,
1740
- ReactiveFormsModule,
1741
- BrowserAnimationsModule,
1742
- MatFormFieldModule,
1743
- MatOptionModule,
1744
- MatSelectModule,
1745
- MatButtonModule,
1746
- MatInputModule,
1747
- MatIconModule,
1748
- MatTooltipModule,
1749
- MatChipsModule,
1750
- MatAutocompleteModule,
1751
- DragDropModule,
1752
- RouterModule,
1753
- MatSnackBarModule,
1754
- MatDialogModule,
1755
- MatMenuModule,
1756
- ApiModule
1757
- ],
1758
- exports: [
1759
- AuthorizationComponent,
1760
- ProductSelectComponent,
1761
- ConfigSelectComponent,
1762
- EnvironmentSelectComponent,
1763
- SettingSelectComponent,
1764
- SettingItemComponent,
1765
- InputDisplayNormalizerDirective,
1766
- DeleteSettingDialogComponent
1767
- ],
1768
- providers: [
1769
- {
1770
- provide: MAT_TOOLTIP_DEFAULT_OPTIONS,
1771
- useValue: { disableTooltipInteractivity: true },
1772
- },
1773
- ]
1774
- }]
1775
- }], ctorParameters: function () { return []; } });
1776
-
1777
- /*
1778
- * Public API Surface of ng-configcat-publicapi-ui
1779
- */
1780
-
1781
- /**
1782
- * Generated bundle index. Do not edit.
1783
- */
1784
-
1785
- export { AuthorizationComponent, ConfigSelectComponent, DeleteSettingDialogComponent, EnvironmentSelectComponent, FormHelper, InputDisplayNormalizerDirective, NgConfigCatPublicApiUIModule, ProductSelectComponent, PublicApiService, SettingItemComponent, SettingSelectComponent };
1786
- //# sourceMappingURL=ng-configcat-publicapi-ui.mjs.map