ng-configcat-publicapi-ui 2.3.2 → 2.5.1

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 (81) hide show
  1. package/{esm2015/lib/_models/index.js → esm2020/lib/_models/index.mjs} +0 -0
  2. package/{esm2015/lib/_models/settingValuesModel.js → esm2020/lib/_models/settingValuesModel.mjs} +0 -0
  3. package/{esm2015/lib/_models/updateSettingValuesModel.js → esm2020/lib/_models/updateSettingValuesModel.mjs} +0 -0
  4. package/esm2020/lib/_services/form-helper.mjs +21 -0
  5. package/{esm2015/lib/_services/index.js → esm2020/lib/_services/index.mjs} +0 -0
  6. package/esm2020/lib/_services/public-api.service.mjs +68 -0
  7. package/esm2020/lib/_services/setting-list-form-helper.mjs +152 -0
  8. package/esm2020/lib/authorization/authorization.component.mjs +50 -0
  9. package/esm2020/lib/base/base.component.mjs +45 -0
  10. package/esm2020/lib/configuration.mjs +13 -0
  11. package/esm2020/lib/dialogs/concurrent-dialog/concurrent-dialog.component.mjs +25 -0
  12. package/esm2020/lib/dialogs/expand-dialog/expand-dialog.component.mjs +77 -0
  13. package/esm2020/lib/dialogs/reason-dialog/reason-dialog.component.mjs +36 -0
  14. package/esm2020/lib/dialogs/save-snackbar/save-snackbar.component.mjs +14 -0
  15. package/esm2020/lib/ng-configcat-publicapi-ui.module.mjs +160 -0
  16. package/esm2020/lib/selects/config-select/config-select.component.mjs +56 -0
  17. package/esm2020/lib/selects/environment-select/environment-select.component.mjs +43 -0
  18. package/esm2020/lib/selects/product-select/product-select.component.mjs +36 -0
  19. package/esm2020/lib/selects/setting-select/setting-select.component.mjs +43 -0
  20. package/esm2020/lib/setting-item/setting-item.component.mjs +129 -0
  21. package/esm2020/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.mjs +81 -0
  22. package/esm2020/lib/setting-list/setting/rollout-rules/rollout-rules.component.mjs +295 -0
  23. package/esm2020/lib/setting-list/setting/setting.component.mjs +137 -0
  24. package/esm2020/lib/setting-list/setting/value/value.component.mjs +32 -0
  25. package/esm2020/lib/setting-list/setting-list.component.mjs +200 -0
  26. package/esm2020/ng-configcat-publicapi-ui.mjs +5 -0
  27. package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
  28. package/fesm2015/ng-configcat-publicapi-ui.mjs +1588 -0
  29. package/fesm2015/ng-configcat-publicapi-ui.mjs.map +1 -0
  30. package/fesm2020/ng-configcat-publicapi-ui.mjs +1569 -0
  31. package/fesm2020/ng-configcat-publicapi-ui.mjs.map +1 -0
  32. package/lib/_services/form-helper.d.ts +1 -1
  33. package/lib/_services/public-api.service.d.ts +12 -8
  34. package/lib/_services/setting-list-form-helper.d.ts +5 -2
  35. package/lib/authorization/authorization.component.d.ts +4 -1
  36. package/lib/base/base.component.d.ts +7 -3
  37. package/lib/configuration.d.ts +3 -0
  38. package/lib/dialogs/concurrent-dialog/concurrent-dialog.component.d.ts +3 -0
  39. package/lib/dialogs/expand-dialog/expand-dialog.component.d.ts +7 -3
  40. package/lib/dialogs/reason-dialog/reason-dialog.component.d.ts +3 -0
  41. package/lib/dialogs/save-snackbar/save-snackbar.component.d.ts +3 -0
  42. package/lib/ng-configcat-publicapi-ui.module.d.ts +38 -0
  43. package/lib/selects/config-select/config-select.component.d.ts +3 -0
  44. package/lib/selects/environment-select/environment-select.component.d.ts +3 -0
  45. package/lib/selects/product-select/product-select.component.d.ts +3 -0
  46. package/lib/selects/setting-select/setting-select.component.d.ts +3 -0
  47. package/lib/setting-item/setting-item.component.d.ts +7 -1
  48. package/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.d.ts +7 -2
  49. package/lib/setting-list/setting/rollout-rules/rollout-rules.component.d.ts +19 -5
  50. package/lib/setting-list/setting/setting.component.d.ts +7 -1
  51. package/lib/setting-list/setting/value/value.component.d.ts +3 -0
  52. package/lib/setting-list/setting-list.component.d.ts +9 -1
  53. package/ng-configcat-publicapi-ui.d.ts +1 -14
  54. package/package.json +26 -15
  55. package/bundles/ng-configcat-publicapi-ui.umd.js +0 -1820
  56. package/bundles/ng-configcat-publicapi-ui.umd.js.map +0 -1
  57. package/esm2015/lib/_services/form-helper.js +0 -21
  58. package/esm2015/lib/_services/public-api.service.js +0 -71
  59. package/esm2015/lib/_services/setting-list-form-helper.js +0 -128
  60. package/esm2015/lib/authorization/authorization.component.js +0 -49
  61. package/esm2015/lib/base/base.component.js +0 -40
  62. package/esm2015/lib/configuration.js +0 -10
  63. package/esm2015/lib/dialogs/concurrent-dialog/concurrent-dialog.component.js +0 -26
  64. package/esm2015/lib/dialogs/expand-dialog/expand-dialog.component.js +0 -70
  65. package/esm2015/lib/dialogs/reason-dialog/reason-dialog.component.js +0 -35
  66. package/esm2015/lib/dialogs/save-snackbar/save-snackbar.component.js +0 -15
  67. package/esm2015/lib/ng-configcat-publicapi-ui.module.js +0 -101
  68. package/esm2015/lib/selects/config-select/config-select.component.js +0 -48
  69. package/esm2015/lib/selects/environment-select/environment-select.component.js +0 -40
  70. package/esm2015/lib/selects/product-select/product-select.component.js +0 -34
  71. package/esm2015/lib/selects/setting-select/setting-select.component.js +0 -40
  72. package/esm2015/lib/setting-item/setting-item.component.js +0 -106
  73. package/esm2015/lib/setting-list/setting/rollout-percentage-items/rollout-percentage-items.component.js +0 -69
  74. package/esm2015/lib/setting-list/setting/rollout-rules/rollout-rules.component.js +0 -260
  75. package/esm2015/lib/setting-list/setting/setting.component.js +0 -112
  76. package/esm2015/lib/setting-list/setting/value/value.component.js +0 -31
  77. package/esm2015/lib/setting-list/setting-list.component.js +0 -179
  78. package/esm2015/ng-configcat-publicapi-ui.js +0 -19
  79. package/fesm2015/ng-configcat-publicapi-ui.js +0 -1416
  80. package/fesm2015/ng-configcat-publicapi-ui.js.map +0 -1
  81. package/ng-configcat-publicapi-ui.metadata.json +0 -1
@@ -1,1416 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { Injectable, Optional, Component, Input, EventEmitter, Output, forwardRef, Inject, ChangeDetectorRef, NgModule } from '@angular/core';
3
- import * as i1 from '@angular/common/http';
4
- import { HttpClient, HttpClientModule } from '@angular/common/http';
5
- import { MeService, Configuration as Configuration$1, ProductsService, ConfigsService, EnvironmentsService, FeatureFlagsSettingsService, FeatureFlagSettingValuesService, IntegrationLinksService, SettingType, RolloutRuleComparator, ApiModule } from 'ng-configcat-publicapi';
6
- import { throwError } from 'rxjs';
7
- import { map, catchError } from 'rxjs/operators';
8
- import * as i1$1 from '@angular/forms';
9
- import { NG_VALUE_ACCESSOR, Validators, FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
10
- import { CommonModule } from '@angular/common';
11
- import { MatFormFieldModule } from '@angular/material/form-field';
12
- import { MatOptionModule } from '@angular/material/core';
13
- import { MatSelectModule } from '@angular/material/select';
14
- import { MatButtonModule } from '@angular/material/button';
15
- import { MatInputModule } from '@angular/material/input';
16
- import { MatDialogRef, MAT_DIALOG_DATA, MatDialog, MatDialogModule } from '@angular/material/dialog';
17
- import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
18
- import * as semver from 'semver';
19
- import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
20
- import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
21
- import { MatIconModule } from '@angular/material/icon';
22
- import { MatTooltipModule } from '@angular/material/tooltip';
23
- import { MatChipsModule } from '@angular/material/chips';
24
- import { MatAutocompleteModule } from '@angular/material/autocomplete';
25
- import { RouterModule } from '@angular/router';
26
- import { MatMenuModule } from '@angular/material/menu';
27
-
28
- class Configuration {
29
- constructor() {
30
- this.basePath = 'https://api.configcat.com';
31
- }
32
- }
33
- Configuration.decorators = [
34
- { type: Injectable }
35
- ];
36
-
37
- class PublicApiService {
38
- constructor(httpClient, configuration) {
39
- this.httpClient = httpClient;
40
- this.configuration = configuration;
41
- }
42
- createMeService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
43
- var _a, _b, _c;
44
- 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({
45
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
46
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
47
- }));
48
- }
49
- createProductsService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
50
- var _a, _b, _c;
51
- 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({
52
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
53
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
54
- }));
55
- }
56
- createConfigsService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
57
- var _a, _b, _c;
58
- 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({
59
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
60
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
61
- }));
62
- }
63
- createEnvironmentsService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
64
- var _a, _b, _c;
65
- 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({
66
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
67
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
68
- }));
69
- }
70
- createSettingsService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
71
- var _a, _b, _c;
72
- 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({
73
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
74
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
75
- }));
76
- }
77
- createSettingValuesService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
78
- var _a, _b, _c;
79
- 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({
80
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
81
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
82
- }));
83
- }
84
- createIntegrationLinksService(basicAuthUsername = null, basicAuthPassword = null, basePath = null) {
85
- var _a, _b, _c;
86
- 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({
87
- username: basicAuthUsername !== null && basicAuthUsername !== void 0 ? basicAuthUsername : (_b = this.configuration) === null || _b === void 0 ? void 0 : _b.basicAuthUsername,
88
- password: basicAuthPassword !== null && basicAuthPassword !== void 0 ? basicAuthPassword : (_c = this.configuration) === null || _c === void 0 ? void 0 : _c.basicAuthPassword
89
- }));
90
- }
91
- }
92
- PublicApiService.ɵprov = i0.ɵɵdefineInjectable({ factory: function PublicApiService_Factory() { return new PublicApiService(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(Configuration, 8)); }, token: PublicApiService, providedIn: "root" });
93
- PublicApiService.decorators = [
94
- { type: Injectable, args: [{ providedIn: 'root' },] }
95
- ];
96
- PublicApiService.ctorParameters = () => [
97
- { type: HttpClient },
98
- { type: Configuration, decorators: [{ type: Optional }] }
99
- ];
100
-
101
- class BaseComponent {
102
- constructor(publicApiService) {
103
- this.publicApiService = publicApiService;
104
- this.basePath = null;
105
- this.basicAuthUsername = null;
106
- this.basicAuthPassword = null;
107
- }
108
- createProductsService() {
109
- return this.publicApiService.createProductsService(this.basicAuthUsername, this.basicAuthPassword, this.basePath);
110
- }
111
- createConfigsService() {
112
- return this.publicApiService.createConfigsService(this.basicAuthUsername, this.basicAuthPassword, this.basePath);
113
- }
114
- createEnvironmentsService() {
115
- return this.publicApiService.createEnvironmentsService(this.basicAuthUsername, this.basicAuthPassword, this.basePath);
116
- }
117
- createSettingsService() {
118
- return this.publicApiService.createSettingsService(this.basicAuthUsername, this.basicAuthPassword, this.basePath);
119
- }
120
- createSettingValuesService() {
121
- return this.publicApiService.createSettingValuesService(this.basicAuthUsername, this.basicAuthPassword, this.basePath);
122
- }
123
- }
124
- BaseComponent.decorators = [
125
- { type: Component, args: [{
126
- selector: 'base',
127
- template: '<div></div>'
128
- },] }
129
- ];
130
- BaseComponent.ctorParameters = () => [
131
- { type: PublicApiService }
132
- ];
133
- BaseComponent.propDecorators = {
134
- basePath: [{ type: Input }],
135
- basicAuthUsername: [{ type: Input }],
136
- basicAuthPassword: [{ type: Input }]
137
- };
138
-
139
- class SettingItemComponent extends BaseComponent {
140
- constructor(publicApiService) {
141
- super(publicApiService);
142
- this.canEditSetting = true;
143
- this.canDeleteSetting = true;
144
- this.deleteSettingText = 'Delete setting';
145
- this.showEnvironmentName = true;
146
- this.editSettingRequested = new EventEmitter();
147
- this.deleteSettingRequested = new EventEmitter();
148
- this.loadSucceeded = new EventEmitter();
149
- this.loadFailed = new EventEmitter();
150
- this.saveSucceeded = new EventEmitter();
151
- this.saveFailed = new EventEmitter();
152
- this.formValuesChanged = new EventEmitter();
153
- this.loadSettingValues = () => {
154
- return this.createSettingValuesService().getSettingValue(this.environmentId, this.settingId)
155
- .pipe(map(settingValue => {
156
- this.settingValue = settingValue;
157
- const settingValues = {
158
- settingValues: [settingValue],
159
- readOnly: settingValue.readOnly,
160
- config: settingValue.config,
161
- environment: settingValue.environment
162
- };
163
- this.loadSucceeded.emit(settingValues);
164
- return settingValues;
165
- }), catchError(error => {
166
- this.loadFailed.emit(error);
167
- return throwError(error);
168
- }));
169
- };
170
- this.handleSave = (model) => {
171
- if (model.settingValues.length === 0) {
172
- return;
173
- }
174
- const updateModel = model.settingValues[0];
175
- return this.createSettingValuesService().replaceSettingValue(this.environmentId, this.settingId, updateModel, model.reason)
176
- .pipe(map(settingValue => {
177
- this.settingValue = settingValue;
178
- const settingValues = {
179
- settingValues: [settingValue],
180
- readOnly: settingValue.readOnly,
181
- config: settingValue.config,
182
- environment: settingValue.environment
183
- };
184
- this.saveSucceeded.emit(settingValues);
185
- return settingValues;
186
- }), catchError(error => {
187
- this.saveFailed.emit(error);
188
- return throwError(error);
189
- }));
190
- };
191
- }
192
- ngOnInit() {
193
- }
194
- onEditSettingRequested(setting) {
195
- this.editSettingRequested.emit({
196
- setting: setting.setting,
197
- environment: this.settingValue.environment,
198
- config: this.settingValue.config
199
- });
200
- }
201
- onDeleteSettingRequested(setting) {
202
- this.deleteSettingRequested.emit({
203
- setting: setting.setting,
204
- environment: this.settingValue.environment,
205
- config: this.settingValue.config
206
- });
207
- }
208
- onFormValuesChanged() {
209
- this.formValuesChanged.emit();
210
- }
211
- }
212
- SettingItemComponent.decorators = [
213
- { type: Component, args: [{
214
- selector: 'configcat-setting-item',
215
- template: "<configcat-setting-list [canEditSetting]=\"canEditSetting\" [canDeleteSetting]=\"canDeleteSetting\"\n [onSave]=\"handleSave\" [loadSettingValues]=\"loadSettingValues\"\n (editSettingRequested)=\"onEditSettingRequested($event)\" (deleteSettingRequested)=\"onDeleteSettingRequested($event)\"\n [deleteSettingText]=\"deleteSettingText\"\n [showEnvironmentName]=\"showEnvironmentName\" (formValuesChanged)=\"onFormValuesChanged()\">\n</configcat-setting-list>",
216
- styles: [".container{font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;background-color:#f3f3f3;border:1px solid rgba(0,0,0,.12);border-radius:4px;margin:1em 0}.container .setting-full{position:relative;display:flex;flex-wrap:nowrap}.container .setting-full .setting-details{display:flex;flex-direction:column;width:400px;padding:1em 0 1em 1em}.container .setting-full .setting-details>*{margin:.5em}.container .setting-full .setting-details .setting-name{flex-direction:row}.container .setting-full .setting-details .setting-name .name{font-weight:bold;word-wrap:break-word;max-width:100%}.container .setting-full .setting-details .setting-key{word-wrap:break-word}.container .setting-full .setting-details .description{font-size:.8em}.container .setting-full .setting-details code{background-color:#d3d3d3;padding:3px 6px}.container .setting-full .rules-list{width:100%;padding:1em}.container .setting-full .targeting-button{margin-left:1rem;margin-bottom:1em}.all-other{min-height:40px;justify-content:flex-start;border:1px solid #d5d5d5;border-radius:4px;background-color:#fff;margin:.5em 1em;padding:4px 0 4px .5em}.all-other .chip{background-color:#67b1fc3d}.all-other .served-value{margin-left:auto;min-width:100px}.end{margin-left:auto}.flex{display:flex;flex-wrap:wrap;align-items:center}.show-hide-toggle{margin-left:1em;cursor:pointer}@media (max-width: 1200px){.setting-full .setting-details{width:300px}}@media (max-width: 700px){.setting-full{flex-wrap:wrap}.setting-full .setting-details{padding:.2em 0 .2em .2em}.setting-full .all-other{margin:.5em .3em}}\n"]
217
- },] }
218
- ];
219
- SettingItemComponent.ctorParameters = () => [
220
- { type: PublicApiService }
221
- ];
222
- SettingItemComponent.propDecorators = {
223
- productId: [{ type: Input }],
224
- environmentId: [{ type: Input }],
225
- configId: [{ type: Input }],
226
- settingId: [{ type: Input }],
227
- canEditSetting: [{ type: Input }],
228
- canDeleteSetting: [{ type: Input }],
229
- deleteSettingText: [{ type: Input }],
230
- showEnvironmentName: [{ type: Input }],
231
- editSettingRequested: [{ type: Output }],
232
- deleteSettingRequested: [{ type: Output }],
233
- loadSucceeded: [{ type: Output }],
234
- loadFailed: [{ type: Output }],
235
- saveSucceeded: [{ type: Output }],
236
- saveFailed: [{ type: Output }],
237
- formValuesChanged: [{ type: Output }]
238
- };
239
-
240
- class SettingSelectComponent extends BaseComponent {
241
- constructor(publicApiService) {
242
- super(publicApiService);
243
- }
244
- ngOnInit() {
245
- this.settings = [];
246
- this.reloadSettings();
247
- }
248
- ngOnChanges() {
249
- this.reloadSettings();
250
- }
251
- reloadSettings() {
252
- if (this.configId) {
253
- this.createSettingsService().getSettings(this.configId).subscribe(settings => {
254
- this.settings = settings;
255
- if (this.settings.length > 0) {
256
- this.valueFormControl.setValue(this.settings[0].settingId);
257
- }
258
- });
259
- }
260
- }
261
- }
262
- SettingSelectComponent.decorators = [
263
- { type: Component, args: [{
264
- selector: 'configcat-setting-select',
265
- template: "<mat-form-field class=\"form-field\">\n <mat-select placeholder=\"Feature flag or setting\" [formControl]=\"valueFormControl\" *ngIf=\"settings\" name=\"value\">\n <mat-option *ngFor=\"let setting of settings\" [value]=\"setting.settingId\">{{setting.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>",
266
- styles: [".form-field{width:100%}\n"]
267
- },] }
268
- ];
269
- SettingSelectComponent.ctorParameters = () => [
270
- { type: PublicApiService }
271
- ];
272
- SettingSelectComponent.propDecorators = {
273
- valueFormControl: [{ type: Input }],
274
- configId: [{ type: Input }]
275
- };
276
-
277
- class ProductSelectComponent extends BaseComponent {
278
- constructor(publicApiService) {
279
- super(publicApiService);
280
- }
281
- ngOnInit() {
282
- this.products = [];
283
- this.createProductsService().getProducts().subscribe(products => {
284
- this.products = products;
285
- if (this.products.length > 0) {
286
- this.valueFormControl.setValue(this.products[0].productId, {
287
- emitEvent: true,
288
- emitModelToViewChange: true, emitViewToModelChange: true
289
- });
290
- }
291
- });
292
- }
293
- }
294
- ProductSelectComponent.decorators = [
295
- { type: Component, args: [{
296
- selector: 'configcat-product-select',
297
- template: "<mat-form-field class=\"form-field\">\n <mat-select placeholder=\"Product\" [formControl]=\"valueFormControl\" name=\"productValue\">\n <mat-option *ngFor=\"let product of products\" [value]=\"product.productId\">{{product.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>",
298
- styles: [".form-field{width:100%}\n"]
299
- },] }
300
- ];
301
- ProductSelectComponent.ctorParameters = () => [
302
- { type: PublicApiService }
303
- ];
304
- ProductSelectComponent.propDecorators = {
305
- valueFormControl: [{ type: Input }]
306
- };
307
-
308
- class ConfigSelectComponent extends BaseComponent {
309
- constructor(publicApiService) {
310
- super(publicApiService);
311
- }
312
- ngOnInit() {
313
- this.configs = [];
314
- this.reloadConfigs();
315
- }
316
- ngOnChanges() {
317
- this.reloadConfigs();
318
- }
319
- reloadConfigs() {
320
- if (this.productId) {
321
- this.createConfigsService().getConfigs(this.productId).subscribe(configs => {
322
- this.configs = configs;
323
- if (this.configs.length > 0) {
324
- this.valueFormControl.setValue(this.configs[0].configId);
325
- }
326
- });
327
- }
328
- }
329
- }
330
- ConfigSelectComponent.decorators = [
331
- { type: Component, args: [{
332
- selector: 'configcat-config-select',
333
- template: "<mat-form-field class=\"form-field\">\n <mat-select placeholder=\"Config\" [formControl]=\"valueFormControl\" *ngIf=\"configs\" name=\"value\">\n <mat-option *ngFor=\"let config of configs\" [value]=\"config.configId\">{{config.name}}</mat-option>\n </mat-select>\n</mat-form-field>",
334
- providers: [
335
- {
336
- provide: NG_VALUE_ACCESSOR,
337
- useExisting: forwardRef(() => ConfigSelectComponent),
338
- multi: true
339
- }
340
- ],
341
- styles: [".form-field{width:100%}\n"]
342
- },] }
343
- ];
344
- ConfigSelectComponent.ctorParameters = () => [
345
- { type: PublicApiService }
346
- ];
347
- ConfigSelectComponent.propDecorators = {
348
- valueFormControl: [{ type: Input }],
349
- productId: [{ type: Input }]
350
- };
351
-
352
- class EnvironmentSelectComponent extends BaseComponent {
353
- constructor(publicApiService) {
354
- super(publicApiService);
355
- }
356
- ngOnInit() {
357
- this.environments = [];
358
- this.reloadEnvironments();
359
- }
360
- ngOnChanges() {
361
- this.reloadEnvironments();
362
- }
363
- reloadEnvironments() {
364
- if (this.productId) {
365
- this.createEnvironmentsService().getEnvironments(this.productId).subscribe(environments => {
366
- this.environments = environments;
367
- if (this.environments.length > 0) {
368
- this.valueFormControl.setValue(this.environments[0].environmentId);
369
- }
370
- });
371
- }
372
- }
373
- }
374
- EnvironmentSelectComponent.decorators = [
375
- { type: Component, args: [{
376
- selector: 'configcat-environment-select',
377
- template: "<mat-form-field class=\"form-field\">\n <mat-select placeholder=\"Environment\" [formControl]=\"valueFormControl\" *ngIf=\"environments\" name=\"value\">\n <mat-option *ngFor=\"let environment of environments\" [value]=\"environment.environmentId\">{{environment.name}}\n </mat-option>\n </mat-select>\n</mat-form-field>",
378
- styles: [".form-field{width:100%}\n"]
379
- },] }
380
- ];
381
- EnvironmentSelectComponent.ctorParameters = () => [
382
- { type: PublicApiService }
383
- ];
384
- EnvironmentSelectComponent.propDecorators = {
385
- valueFormControl: [{ type: Input }],
386
- productId: [{ type: Input }]
387
- };
388
-
389
- class FormHelper {
390
- static getErrorMessage(control, hint = '') {
391
- if (!control || control.valid) {
392
- return;
393
- }
394
- if (control.hasError('required')) {
395
- return `${hint} The field is required.`;
396
- }
397
- if (control.hasError('pattern')) {
398
- return 'Not a valid e-mail address.';
399
- }
400
- if (control.hasError('minlength')) {
401
- return 'The field must be at least ' + control.errors.minlength.requiredLength + ' characters long';
402
- }
403
- if (control.hasError('maxlength')) {
404
- return 'The field must be at max ' + control.errors.maxlength.requiredLength + ' characters long';
405
- }
406
- return;
407
- }
408
- }
409
-
410
- class AuthorizationComponent {
411
- constructor(formBuilder, publicApiService) {
412
- this.formBuilder = formBuilder;
413
- this.publicApiService = publicApiService;
414
- this.basePath = null;
415
- this.authorized = new EventEmitter();
416
- this.FormHelper = FormHelper;
417
- }
418
- ngOnInit() {
419
- this.formGroup = this.formBuilder.group({
420
- basicAuthUsername: ['', Validators.required],
421
- basicAuthPassword: ['', Validators.required],
422
- });
423
- }
424
- onSubmit() {
425
- if (!this.formGroup.valid) {
426
- return;
427
- }
428
- const meService = this.publicApiService.createMeService(this.formGroup.controls.basicAuthUsername.value, this.formGroup.controls.basicAuthPassword.value, this.basePath);
429
- meService.getMe().subscribe(me => {
430
- this.authorized.emit({
431
- basicAuthUsername: this.formGroup.controls.basicAuthUsername.value,
432
- basicAuthPassword: this.formGroup.controls.basicAuthPassword.value
433
- });
434
- }, error => {
435
- this.formGroup.setErrors({ invalidAuthorization: 'Invalid Basic auth user name or password' });
436
- });
437
- }
438
- }
439
- AuthorizationComponent.decorators = [
440
- { type: Component, args: [{
441
- selector: 'configcat-authorization',
442
- template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\">\n <div class=\"container\">\n <div class=\"form\">\n <p>\n <a href=\"https://app.configcat.com/my-account/public-api-credentials\" target=\"_blank\">\n Get your Basic Auth user name and password</a> to access ConfigCat Public API.\n <br /><br />\n <b>Note!</b> Your ConfigCat account's email address and password will not work here.\n </p>\n\n <mat-form-field class=\"form-field\">\n <mat-label>Basic auth user name</mat-label>\n <input matInput placeholder=\"Basic auth user name\" formControlName=\"basicAuthUsername\">\n <mat-error *ngIf=\"formGroup.controls.basicAuthUsername.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.basicAuthUsername)}}\n </mat-error>\n </mat-form-field>\n <mat-form-field class=\"form-field\">\n <mat-label>Basic auth password</mat-label>\n <input matInput placeholder=\"Basic auth password\" formControlName=\"basicAuthPassword\" type=\"password\"\n autocomplete=\"current-password\">\n <mat-error *ngIf=\"formGroup.controls.basicAuthPassword.invalid\">\n {{FormHelper.getErrorMessage(formGroup.controls.basicAuthPassword)}}\n </mat-error>\n </mat-form-field>\n <div>\n <button mat-raised-button color=\"primary\" type=\"submit\" class=\"submit\">Authorize</button>\n <mat-error *ngIf=\"formGroup.invalid && formGroup.errors && formGroup.errors.invalidAuthorization\">\n {{formGroup.errors.invalidAuthorization}}</mat-error>\n </div>\n </div>\n </div>\n</form>",
443
- styles: [".container{display:flex;margin:8px}.form{width:100%}.form-field{width:100%;margin-bottom:8px}.submit{margin-top:8px;margin-bottom:8px}\n"]
444
- },] }
445
- ];
446
- AuthorizationComponent.ctorParameters = () => [
447
- { type: FormBuilder },
448
- { type: PublicApiService }
449
- ];
450
- AuthorizationComponent.propDecorators = {
451
- basePath: [{ type: Input }],
452
- authorized: [{ type: Output }]
453
- };
454
-
455
- class ConcurrentDialogComponent {
456
- constructor(dialogRef) {
457
- this.dialogRef = dialogRef;
458
- }
459
- ngOnInit() {
460
- }
461
- save() {
462
- this.dialogRef.close({ button: 'save' });
463
- }
464
- discard() {
465
- this.dialogRef.close({ button: 'discard' });
466
- }
467
- }
468
- ConcurrentDialogComponent.decorators = [
469
- { type: Component, args: [{
470
- selector: 'configcat-concurrent-dialog',
471
- template: "<h3 mat-dialog-title>Concurrent update detected</h3>\n<p>\n Somebody updated the feature flags & settings while you were editing them.\n</p>\n<ul>\n <li>\n To discard your local changes and reload the updated values, click <strong>Discard my changes & reload</strong>\n </li>\n <li>\n To save you local values and overwrite the remote changes, click <strong>Save anyway</strong>\n </li>\n</ul>\n<p>For more info about the changes check the <a [routerLink]=\"['/auditlog']\" target=\"_blank\" rel=\"noopener noreferrer\" >audit logs</a> in a new tab.</p>\n<div mat-dialog-actions>\n <button type=\"button\" style=\"margin-right: 10px;\" mat-raised-button color=\"primary\" (click)=\"discard()\">Discard\n local changes & reload</button>\n <button type=\"button\" mat-raised-button (click)=\"save()\">Save anyway</button>\n</div>",
472
- styles: [""]
473
- },] }
474
- ];
475
- ConcurrentDialogComponent.ctorParameters = () => [
476
- { type: MatDialogRef }
477
- ];
478
-
479
- class ExpandDialogComponent {
480
- constructor(dialogRef, formBuilder, data) {
481
- this.dialogRef = dialogRef;
482
- this.formBuilder = formBuilder;
483
- this.data = data;
484
- }
485
- ngOnInit() {
486
- if (this.data.multiline) {
487
- this.buildFormGroup();
488
- }
489
- else {
490
- this.formControlSubscription = this.data.control.valueChanges.subscribe(value => {
491
- this.data.control.setValue(value, { onlySelf: true, emitEvent: false, emitModelToViewChange: true });
492
- this.data.control.markAsDirty();
493
- }, error => { }, () => { });
494
- }
495
- }
496
- values() {
497
- return this.formGroup.get('values');
498
- }
499
- buildFormGroup() {
500
- const value = this.data.control.value ? this.data.control.value : '';
501
- const list = value.split(',').map(v => v.trim()).filter(v => !!v);
502
- this.formGroup = this.formBuilder.group({
503
- values: this.formBuilder.array(list.map(v => this.formBuilder.control(v)))
504
- });
505
- this.formGroupSubscription = this.formGroup.valueChanges.subscribe((formGroupValue) => {
506
- this.data.control.setValue(formGroupValue.values
507
- .filter(v => !!v)
508
- .join(','), { onlySelf: true, emitEvent: false, emitModelToViewChange: true });
509
- this.data.control.updateValueAndValidity();
510
- this.data.control.markAsDirty();
511
- });
512
- }
513
- add() {
514
- this.formGroup.controls.values.push(this.formBuilder.control(''));
515
- }
516
- remove(index) {
517
- this.formGroup.controls.values.removeAt(index);
518
- }
519
- ngOnDestroy() {
520
- if (this.formControlSubscription) {
521
- this.formControlSubscription.unsubscribe();
522
- this.formControlSubscription = null;
523
- }
524
- if (this.formGroupSubscription) {
525
- this.formGroupSubscription.unsubscribe();
526
- this.formGroupSubscription = null;
527
- }
528
- }
529
- close() {
530
- this.dialogRef.close();
531
- }
532
- }
533
- ExpandDialogComponent.decorators = [
534
- { type: Component, args: [{
535
- selector: 'configcat-expand-dialog',
536
- template: "<div mat-dialog-content class=\"container\">\n\n <mat-form-field appearance=\"outline\" *ngIf=\"!data.multiline\">\n <mat-label></mat-label>\n <textarea matInput [formControl]=\"data.control\" rows=\"15\"></textarea>\n </mat-form-field>\n <div [formGroup]=\"formGroup\" *ngIf=\"data.multiline\">\n <div *ngFor=\"let valueControl of values().controls; let i = index;\" class=\"value-field\">\n <mat-form-field appearance=\"outline\">\n <input matInput [formControl]=\"valueControl\" rows=\"15\" />\n </mat-form-field>\n <button (click)=\"remove(i)\" mat-icon-button type=\"button\">\n <mat-icon>delete_outline</mat-icon>\n </button>\n </div>\n <button (click)=\"add()\" mat-icon-button type=\"button\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n</div>\n<div mat-dialog-actions>\n <button type=\"button\" mat-raised-button color=\"primary\" (click)=\"close()\">Done</button>\n</div>",
537
- styles: [".container>*{width:100%}.container>* .value-field{display:flex;font-size:12px;flex-wrap:nowrap}.container>* .value-field mat-form-field{flex-grow:1}\n"]
538
- },] }
539
- ];
540
- ExpandDialogComponent.ctorParameters = () => [
541
- { type: MatDialogRef },
542
- { type: FormBuilder },
543
- { type: undefined, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] }
544
- ];
545
-
546
- class ReasonDialogComponent {
547
- constructor(dialogRef, formBuilder) {
548
- this.dialogRef = dialogRef;
549
- this.formBuilder = formBuilder;
550
- }
551
- ngOnInit() {
552
- this.formGroup = this.formBuilder.group({
553
- reason: ['', [Validators.required, Validators.maxLength(1000)]]
554
- });
555
- }
556
- handleSaveButton() {
557
- if (!this.formGroup.valid) {
558
- return;
559
- }
560
- this.dialogRef.close({ button: 'save', reason: this.formGroup.controls.reason.value });
561
- }
562
- cancel() {
563
- this.dialogRef.close({ button: 'cancel' });
564
- }
565
- }
566
- ReasonDialogComponent.decorators = [
567
- { type: Component, args: [{
568
- selector: 'configcat-reason-dialog',
569
- template: "<h3 mat-dialog-title>Add notes</h3>\n<p>This will appear in the Why column of the Audit Log.</p>\n<form [formGroup]=\"formGroup\" (ngSubmit)=\"handleSaveButton()\">\n <div mat-dialog-content class=\"container\">\n <mat-form-field appearance=\"outline\">\n <mat-label></mat-label>\n <textarea matInput formControlName=\"reason\" name=\"reason\" placeholder=\"I'm changing settings because...\"\n rows=\"3\"></textarea>\n <mat-error *ngIf=\"formGroup.controls.reason.invalid\">The field is required.</mat-error>\n </mat-form-field>\n </div>\n <br>\n <div mat-dialog-actions>\n <button type=\"submit\" style=\"margin-right: 10px;\" mat-raised-button color=\"primary\">Add notes & Save</button>\n <button type=\"button\" mat-raised-button (click)=\"cancel()\">Cancel</button>\n </div>\n</form>",
570
- styles: [".container>*{width:100%}\n"]
571
- },] }
572
- ];
573
- ReasonDialogComponent.ctorParameters = () => [
574
- { type: MatDialogRef },
575
- { type: FormBuilder }
576
- ];
577
-
578
- class SaveSnackbarComponent {
579
- constructor() { }
580
- ngOnInit() {
581
- }
582
- }
583
- SaveSnackbarComponent.decorators = [
584
- { type: Component, args: [{
585
- selector: 'configcat-save-snackbar',
586
- template: "<p class=\"header\">Settings saved successfully.</p>",
587
- styles: ["p{text-align:center;font-weight:bold}.header{font-size:1.2em}\n"]
588
- },] }
589
- ];
590
- SaveSnackbarComponent.ctorParameters = () => [];
591
-
592
- class RolloutPercentageItemsComponent {
593
- constructor() {
594
- this.SettingType = SettingType;
595
- }
596
- setting() {
597
- return this.formGroup.get('setting').value;
598
- }
599
- rolloutRules() {
600
- return this.formGroup.get('rolloutRules');
601
- }
602
- rolloutPercentageItems() {
603
- return this.formGroup.get('rolloutPercentageItems');
604
- }
605
- rolloutPercentageItemsSum() {
606
- return this.formGroup.get('rolloutPercentageItemsSum');
607
- }
608
- value(rolloutPercentageItem) {
609
- return this.setting().settingType === SettingType.Boolean ?
610
- rolloutPercentageItem.get('valueDisabled') :
611
- rolloutPercentageItem.get('value');
612
- }
613
- percentageChanged(index) {
614
- if (this.rolloutPercentageItems().controls[index].value.percentage < 0) {
615
- this.rolloutPercentageItems().controls[index].controls.percentage.setValue(0);
616
- }
617
- if (this.rolloutPercentageItems().controls[index].value.percentage > 100) {
618
- this.rolloutPercentageItems().controls[index].controls.percentage.setValue(100);
619
- }
620
- if (this.rolloutPercentageItems().controls.length === 2) {
621
- this.rolloutPercentageItems().controls[1 - index].controls.percentage
622
- .setValue(100 - this.rolloutPercentageItems().controls[index].value.percentage);
623
- }
624
- this.updateSum();
625
- }
626
- updateSum() {
627
- if (this.rolloutPercentageItems().controls.length === 0) {
628
- this.rolloutPercentageItemsSum().setValue(100);
629
- }
630
- else {
631
- this.rolloutPercentageItemsSum().setValue(this.rolloutPercentageItems().controls.map(v => v.value.percentage)
632
- .reduce((a, b) => a + b));
633
- }
634
- }
635
- removeRolloutPercentageItem(index) {
636
- this.rolloutPercentageItems().removeAt(index);
637
- this.rolloutPercentageItems().markAsDirty();
638
- this.updateSum();
639
- }
640
- removeAll() {
641
- this.rolloutPercentageItems().clear();
642
- this.rolloutPercentageItems().markAsDirty();
643
- this.updateSum();
644
- }
645
- }
646
- RolloutPercentageItemsComponent.decorators = [
647
- { type: Component, args: [{
648
- selector: 'configcat-rollout-percentage-items',
649
- template: "<div class=\"percentage-wrapper\" [formGroup]=\"formGroup\">\n\n <div class=\"if\" *ngIf=\"rolloutRules().controls.length > 0\">\n <mat-chip-list>\n <mat-chip class=\"chip\">ELSE IF</mat-chip>\n </mat-chip-list>\n </div>\n <div class=\"grow\">\n <div class=\"percentage-row flex\"\n *ngFor=\"let rolloutPercentageItem of rolloutPercentageItems().controls; let i = index\">\n <div class=\"flex\">\n <input type=\"number\" [formControl]=\"rolloutPercentageItem.controls.percentage\"\n (input)=\"percentageChanged(i)\">%\n <span class=\"users\">of <a href=\"https://configcat.com/docs/advanced/user-object\"\n target=\"_blank\" rel=\"noopener noreferrer\">users</a>\n </span>\n </div>\n\n <div class=\"delete-option\" matTooltip=\"Remove this % option\"\n *ngIf=\"!readOnly && rolloutPercentageItems().controls.length > 2\"\n (click)=\"removeRolloutPercentageItem(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n\n <span data-tooltip=\"The sum of percentages must be equal to 100.\"\n *ngIf=\"(i === rolloutPercentageItems().controls.length -1) && (rolloutPercentageItemsSum().invalid)\">\n <mat-icon color=\"warn\">\n error_outline\n </mat-icon>\n </span>\n\n <div class=\"value flex\">\n <span class=\"value-name\" *ngIf=\"setting().settingType !== SettingType.Boolean\">Served value:</span>\n <configcat-value class=\"served-value\" [valueFormControl]=\"value(rolloutPercentageItem)\" [setting]=\"setting()\">\n </configcat-value>\n </div>\n <div class=\"delete\" matTooltip=\"Remove % options\" (click)=\"removeAll()\" *ngIf=\"!readOnly\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n </div>\n</div>",
650
- styles: [".percentage-wrapper{border:1px solid #d5d5d5;background-color:#fff;border-radius:4px;margin:.5em 1em;position:relative;padding:.5em 0;display:flex}.percentage-wrapper .delete{position:absolute;color:#d6a9a9;cursor:pointer;top:-8px;right:-12px}.percentage-wrapper .delete:hover{color:#ed5251}.percentage-wrapper .delete mat-icon{font-size:20px}.percentage-wrapper .delete-option{color:#d6a9a9;cursor:pointer;margin-left:1rem;margin-top:4px}.percentage-wrapper .delete-option:hover{color:#ed5251}.percentage-wrapper .delete-option mat-icon{font-size:20px}.if{display:flex;align-items:center}.if>*{margin:0 .5em}.if .spacing{margin-right:44px}.if .chip{background-color:#67b1fc3d}.grow{flex-grow:1}.percentage-row{min-height:40px;margin-left:.5em}.flex{display:flex;flex-wrap:wrap;align-items:center}.value{margin-left:auto;min-width:100px}.value .value-name{display:none}input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;width:40px;margin-right:5px;font-size:15px;padding:0 5px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300}.users{margin-left:20px}@media (max-width: 700px){.percentage-wrapper{margin:.5em .3em}}\n"]
651
- },] }
652
- ];
653
- RolloutPercentageItemsComponent.ctorParameters = () => [];
654
- RolloutPercentageItemsComponent.propDecorators = {
655
- formGroup: [{ type: Input }],
656
- readOnly: [{ type: Input }]
657
- };
658
-
659
- class RolloutRulesComponent {
660
- constructor(dialog) {
661
- this.dialog = dialog;
662
- this.SettingType = SettingType;
663
- this.defaultComparisonAttributes = ['Identifier', 'Email', 'Country'];
664
- this.rolloutRuleComparators = [
665
- { value: RolloutRuleComparator.IsOneOf, label: 'IS ONE OF' },
666
- { value: RolloutRuleComparator.IsNotOneOf, label: 'IS NOT ONE OF' },
667
- { value: RolloutRuleComparator.Contains, label: 'CONTAINS' },
668
- { value: RolloutRuleComparator.DoesNotContain, label: 'DOES NOT CONTAIN' },
669
- { value: RolloutRuleComparator.SemVerIsOneOf, label: 'IS ONE OF (SemVer)' },
670
- { value: RolloutRuleComparator.SemVerIsNotOneOf, label: 'IS NOT ONE OF (SemVer)' },
671
- { value: RolloutRuleComparator.SemVerLess, label: '< (SemVer)' },
672
- { value: RolloutRuleComparator.SemVerLessOrEquals, label: '<= (SemVer)' },
673
- { value: RolloutRuleComparator.SemVerGreater, label: '> (SemVer)' },
674
- { value: RolloutRuleComparator.SemVerGreaterOrEquals, label: '>= (SemVer)' },
675
- { value: RolloutRuleComparator.NumberEquals, label: '= (Number)' },
676
- { value: RolloutRuleComparator.NumberDoesNotEqual, label: '!= (Number)' },
677
- { value: RolloutRuleComparator.NumberLess, label: '< (Number)' },
678
- { value: RolloutRuleComparator.NumberLessOrEquals, label: '<= (Number)' },
679
- { value: RolloutRuleComparator.NumberGreater, label: '> (Number)' },
680
- { value: RolloutRuleComparator.NumberGreaterOrEquals, label: '>= (Number)' },
681
- { value: RolloutRuleComparator.SensitiveIsOneOf, label: 'IS ONE OF (Sensitive)' },
682
- { value: RolloutRuleComparator.SensitiveIsNotOneOf, label: 'IS NOT ONE OF (Sensitive)' },
683
- ];
684
- }
685
- onlyFirstTooltip() {
686
- return this.formGroup.root.get('allRolloutRulesCount').value > 20 || this.rolloutRules().controls.length > 10;
687
- }
688
- setting() {
689
- return this.formGroup.get('setting').value;
690
- }
691
- rolloutRules() {
692
- return this.formGroup.get('rolloutRules');
693
- }
694
- comparisonAttributes() {
695
- return this.formGroup.root.get('comparisonAttributes').value;
696
- }
697
- removeRule(index) {
698
- this.rolloutRules().removeAt(index);
699
- this.rolloutRules().markAsDirty();
700
- }
701
- onDrop(event) {
702
- const rolloutRules = this.rolloutRules().controls;
703
- moveItemInArray(rolloutRules, event.previousIndex, event.currentIndex);
704
- this.formGroup.markAsDirty();
705
- }
706
- attributeChanged(event, comparisonAttribute) {
707
- if (this.defaultComparisonAttributes.indexOf(event) !== -1) {
708
- if (comparisonAttribute.value !== event) {
709
- comparisonAttribute.setValue(event);
710
- this.formGroup.markAsDirty();
711
- }
712
- }
713
- else {
714
- if (comparisonAttribute.value !== '') {
715
- comparisonAttribute.setValue('');
716
- this.formGroup.markAsDirty();
717
- }
718
- }
719
- }
720
- getPlaceHolder(rolloutRule) {
721
- if (!rolloutRule.controls.comparisonAttribute.value) {
722
- return '';
723
- }
724
- switch (rolloutRule.controls.comparator.value) {
725
- case RolloutRuleComparator.IsOneOf:
726
- case RolloutRuleComparator.IsNotOneOf:
727
- case RolloutRuleComparator.SensitiveIsOneOf:
728
- case RolloutRuleComparator.SensitiveIsNotOneOf:
729
- switch (rolloutRule.controls.comparisonAttribute.value.toLowerCase()) {
730
- case 'identifier':
731
- return 'e.g: user_id1, user_id2, user_id3';
732
- case 'email':
733
- return 'e.g: jane@example.com, john@example.com';
734
- case 'country':
735
- return 'e.g: France, Brazil';
736
- default:
737
- return 'e.g: value1, value2, value3';
738
- }
739
- case RolloutRuleComparator.Contains:
740
- case RolloutRuleComparator.DoesNotContain:
741
- switch (rolloutRule.controls.comparisonAttribute.value.toLowerCase()) {
742
- case 'identifier':
743
- return 'part-of-id';
744
- case 'email':
745
- return 'e.g: @example.com';
746
- case 'country':
747
- return 'e.g: United';
748
- default:
749
- return 'e.g: any-part-of-your-value-string';
750
- }
751
- case RolloutRuleComparator.SemVerIsOneOf:
752
- case RolloutRuleComparator.SemVerIsNotOneOf:
753
- return 'e.g: 1.0.0, 2.0.1';
754
- case RolloutRuleComparator.SemVerLessOrEquals:
755
- case RolloutRuleComparator.SemVerLess:
756
- case RolloutRuleComparator.SemVerGreater:
757
- case RolloutRuleComparator.SemVerGreaterOrEquals:
758
- return 'e.g: 1.0.0';
759
- case RolloutRuleComparator.NumberEquals:
760
- case RolloutRuleComparator.NumberDoesNotEqual:
761
- case RolloutRuleComparator.NumberLess:
762
- case RolloutRuleComparator.NumberLessOrEquals:
763
- case RolloutRuleComparator.NumberGreater:
764
- case RolloutRuleComparator.NumberGreaterOrEquals:
765
- return 'e.g: 42';
766
- }
767
- return '';
768
- }
769
- getComparisonValueType(rolloutRule) {
770
- switch (rolloutRule.controls.comparator.value) {
771
- case RolloutRuleComparator.NumberEquals:
772
- case RolloutRuleComparator.NumberDoesNotEqual:
773
- case RolloutRuleComparator.NumberLess:
774
- case RolloutRuleComparator.NumberLessOrEquals:
775
- case RolloutRuleComparator.NumberGreater:
776
- case RolloutRuleComparator.NumberGreaterOrEquals:
777
- return 'number';
778
- default:
779
- return 'text';
780
- }
781
- }
782
- getInfoClass(rolloutRule) {
783
- if (!rolloutRule.controls.comparisonAttribute.value) {
784
- return 'info';
785
- }
786
- switch (rolloutRule.controls.comparator.value) {
787
- case RolloutRuleComparator.IsOneOf:
788
- case RolloutRuleComparator.IsNotOneOf:
789
- case RolloutRuleComparator.Contains:
790
- case RolloutRuleComparator.DoesNotContain:
791
- return 'warn';
792
- default:
793
- return 'info';
794
- }
795
- }
796
- getInfoTooltip(rolloutRule) {
797
- if (!rolloutRule.controls.comparisonAttribute.value) {
798
- return 'Learn more about comparators';
799
- }
800
- switch (rolloutRule.controls.comparator.value) {
801
- case RolloutRuleComparator.IsOneOf:
802
- case RolloutRuleComparator.IsNotOneOf:
803
- case RolloutRuleComparator.Contains:
804
- case RolloutRuleComparator.DoesNotContain:
805
- return 'Consider using sensitive text comparators. Click to learn more.';
806
- default:
807
- return 'Click to learn more about comparators';
808
- }
809
- }
810
- comparatorChanged(rolloutRule) {
811
- let validators = [];
812
- switch (rolloutRule.controls.comparator.value) {
813
- case RolloutRuleComparator.IsOneOf:
814
- case RolloutRuleComparator.IsNotOneOf:
815
- case RolloutRuleComparator.SensitiveIsOneOf:
816
- case RolloutRuleComparator.SensitiveIsNotOneOf:
817
- case RolloutRuleComparator.Contains:
818
- case RolloutRuleComparator.DoesNotContain:
819
- validators = [Validators.required, Validators.maxLength(65535)];
820
- break;
821
- case RolloutRuleComparator.SemVerIsOneOf:
822
- case RolloutRuleComparator.SemVerIsNotOneOf:
823
- validators = [Validators.required, this.validateSemVerList];
824
- break;
825
- case RolloutRuleComparator.SemVerLessOrEquals:
826
- case RolloutRuleComparator.SemVerLess:
827
- case RolloutRuleComparator.SemVerGreater:
828
- case RolloutRuleComparator.SemVerGreaterOrEquals:
829
- validators = [Validators.required, this.validateSemVer];
830
- break;
831
- case RolloutRuleComparator.NumberEquals:
832
- case RolloutRuleComparator.NumberDoesNotEqual:
833
- case RolloutRuleComparator.NumberLess:
834
- case RolloutRuleComparator.NumberLessOrEquals:
835
- case RolloutRuleComparator.NumberGreater:
836
- case RolloutRuleComparator.NumberGreaterOrEquals:
837
- validators = [Validators.required, Validators.min(-1.79769313486232E+308), Validators.max(1.79769313486232E+308)];
838
- break;
839
- }
840
- rolloutRule.controls.comparisonValue.setValidators(validators);
841
- rolloutRule.controls.comparisonValue.updateValueAndValidity();
842
- }
843
- isListType(rolloutRule) {
844
- switch (rolloutRule.controls.comparator.value) {
845
- case RolloutRuleComparator.IsOneOf:
846
- case RolloutRuleComparator.IsNotOneOf:
847
- case RolloutRuleComparator.SensitiveIsOneOf:
848
- case RolloutRuleComparator.SensitiveIsNotOneOf:
849
- case RolloutRuleComparator.SemVerIsOneOf:
850
- case RolloutRuleComparator.SemVerIsNotOneOf:
851
- return true;
852
- default:
853
- return false;
854
- }
855
- }
856
- validateSemVer(c) {
857
- if (semver.valid(c.value) === null) {
858
- return {
859
- validateSemVer: {
860
- valid: false
861
- }
862
- };
863
- }
864
- return null;
865
- }
866
- validateSemVerList(c) {
867
- if (!c.value) {
868
- return {
869
- validateSemVerList: {
870
- valid: false
871
- }
872
- };
873
- }
874
- const semvers = c.value.split(',').map(s => s.trim());
875
- if (semvers.find(s => s && s !== '' && semver.valid(s) === null)) {
876
- return {
877
- validateSemVerList: {
878
- valid: false
879
- }
880
- };
881
- }
882
- return null;
883
- }
884
- popOut(rolloutRule) {
885
- this.dialog.open(ExpandDialogComponent, {
886
- width: '640px',
887
- data: {
888
- control: rolloutRule.controls.comparisonValue,
889
- multiline: this.isListType(rolloutRule)
890
- }
891
- });
892
- }
893
- trackByIndex(index) {
894
- return index;
895
- }
896
- }
897
- RolloutRulesComponent.decorators = [
898
- { type: Component, args: [{
899
- selector: 'configcat-rollout-rules',
900
- template: "<div [formGroup]=\"formGroup\">\n <div cdkDropList (cdkDropListDropped)=\"onDrop($event)\" [cdkDropListDisabled]=\"readOnly\"\n [cdkDropListData]=\"rolloutRules().controls\">\n <div *ngFor=\"let rolloutRule of rolloutRules().controls; trackBy: trackByIndex; let i = index\" cdkDrag>\n <div class=\"targeting-row\">\n <div class=\"fields flex\">\n <div class=\"drag-handle\" cdkDragHandle data-tooltip=\"Drag here to reorder\" *ngIf=\"!readOnly\">\n <mat-icon>drag_indicator</mat-icon>\n </div>\n <div class=\"if\">\n <mat-chip-list [class.spacing]=\"i === 0\">\n <mat-chip class=\"chip\">{{ i === 0 ? 'IF' : 'ELSE IF' }}</mat-chip>\n </mat-chip-list>\n <a href=\"https://configcat.com/docs/advanced/user-object\" target=\"_blank\" rel=\"noopener noreferrer\">user's</a>\n </div>\n\n <select class=\"custom-select attribute-select\" matTooltip=\"Comparison attribute\"\n matTooltipPosition=\"above\" [matTooltipDisabled]=\"onlyFirstTooltip() && i !== 0\"\n (change)=\"attributeChanged($event.target.value, rolloutRule.controls.comparisonAttribute)\">\n <option *ngFor=\"let comparisonAttribute of defaultComparisonAttributes\"\n [selected]=\"comparisonAttribute === rolloutRule.controls.comparisonAttribute.value\">\n {{comparisonAttribute}}</option>\n <option\n [selected]=\"defaultComparisonAttributes.indexOf(rolloutRule.controls.comparisonAttribute.value) === -1\">\n Custom\n </option>\n </select>\n\n\n <span class=\"attribute-span\" data-tooltip=\"Custom user attribute\"\n [hidden]=\"defaultComparisonAttributes.indexOf(rolloutRule.controls.comparisonAttribute.value) !== -1\">\n <span class=\"attribute-error\" *ngIf=\"rolloutRule.controls.comparisonAttribute.invalid\">*</span>\n <input [ngClass]=\"{'invalid': rolloutRule.controls.comparisonAttribute.invalid}\" type=\"text\"\n matInput [matAutocomplete]=\"auto\" [formControl]=\"rolloutRule.controls.comparisonAttribute\"\n class=\"attribute\" placeholder=\"e.g. Eye color\">\n </span>\n\n <mat-autocomplete #auto=\"matAutocomplete\">\n <mat-option *ngFor=\"let option of comparisonAttributes()\" [value]=\"option\">\n {{option}}\n </mat-option>\n </mat-autocomplete>\n\n <div class=\"select-wrapper\">\n <select class=\"custom-select\" [formControl]=\"rolloutRule.controls.comparator\"\n matTooltip=\"Comparator\" matTooltipPosition=\"above\"\n [matTooltipDisabled]=\"onlyFirstTooltip() && i !== 0\"\n (change)=\"comparatorChanged(rolloutRule)\">\n <optgroup label=\"SENSITIVE TEXT\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(16, 18)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"TEXT\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(0, 4)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"SEMANTIC VERSION\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(4, 10)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n <optgroup label=\"NUMBER\">\n <option *ngFor=\"let comparator of rolloutRuleComparators.slice(10, 16)\"\n [ngValue]=\"comparator.value\">\n {{comparator.label}}\n </option>\n </optgroup>\n </select>\n <div [class]=\"getInfoClass(rolloutRule)\" [matTooltip]=\"getInfoTooltip(rolloutRule)\"\n [matTooltipDisabled]=\"onlyFirstTooltip() && i !== 0\">\n <a href=\"https://configcat.com/docs/advanced/targeting/#comparator\" target=\"_blank\" rel=\"noopener noreferrer\">\n <mat-icon>info</mat-icon>\n </a>\n </div>\n </div>\n\n <div class=\"comparison-value\" data-tooltip=\"Comparison value\">\n <span class=\"error\" *ngIf=\"rolloutRule.controls.comparisonValue.invalid\">*</span>\n\n <input [ngClass]=\"{'invalid': rolloutRule.controls.comparisonValue.invalid}\"\n [formControl]=\"rolloutRule.controls.comparisonValue\"\n [type]=\"getComparisonValueType(rolloutRule)\" [placeholder]=\"getPlaceHolder(rolloutRule)\">\n <div class=\"expand\" matTooltip=\"Pop-out Editor\" (click)=\"popOut(rolloutRule)\" *ngIf=\"getComparisonValueType(rolloutRule)==='text'\">\n <mat-icon>height</mat-icon>\n </div>\n </div>\n\n <div class=\"delete\" matTooltip=\"Remove targeting rule\"\n [matTooltipDisabled]=\"onlyFirstTooltip() && i !== 0\" *ngIf=\"!readOnly\" (click)=\"removeRule(i)\">\n <mat-icon>cancel</mat-icon>\n </div>\n </div>\n <div class=\"value flex\">\n <div class=\"serve\" *ngIf=\"setting().settingType !== SettingType.Boolean\">\n <mat-chip-list>\n <mat-chip class=\"chip\">Serve:</mat-chip>\n </mat-chip-list>\n </div>\n\n <configcat-value class=\"served-value\" [valueFormControl]=\"rolloutRule.controls.value\"\n [setting]=\"setting()\">\n </configcat-value>\n </div>\n </div>\n </div>\n </div>\n</div>",
901
- styles: [".cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}.cdk-drag-animating{transition:transform .3s cubic-bezier(0,0,.2,1)}.targeting-row{border:1px solid #d5d5d5;border-radius:4px;background-color:#fff;margin:.5em 1em;display:flex;position:relative;padding:.5em 0}.targeting-row .select-wrapper{position:relative}.targeting-row .info{position:absolute;cursor:pointer;top:-8px;left:166px}.targeting-row .info a{color:#7fb3fd}.targeting-row .info a:hover{color:#0068f0}.targeting-row .info mat-icon{font-size:18px}.targeting-row .warn{position:absolute;cursor:pointer;top:-8px;left:128px}.targeting-row .warn a{color:#fdc67f}.targeting-row .warn a:hover{color:#ff9200}.targeting-row .warn mat-icon{font-size:18px}.chip{background-color:#67b1fc3d}.fields{justify-content:left;max-width:1060px;flex-grow:100}.fields .if{display:flex;align-items:center}.fields .if>*{margin:0 .5em}.fields .if .spacing{margin-right:46px}.fields .attribute-span{margin-left:.5em}.fields .attribute{width:170px;background-color:#fff;border:1px solid #e5e5e5;min-height:28px;min-width:170px;font-size:15px;padding:0 10px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300}.fields .invalid{border:1px solid #ff5252}.fields .attribute-error{color:#ff5252;margin-right:5px}.fields .delete{position:absolute;color:#d6a9a9;cursor:pointer;top:-8px;right:-12px;z-index:999}.fields .delete:hover{color:#ed5251}.fields .delete mat-icon{font-size:20px}.fields .drag-handle{position:absolute;cursor:-webkit-grab;cursor:-moz-grab;left:-20px;top:14px}.fields .drag-handle mat-icon{font-size:20px}.fields .custom-select{margin-left:.5em;width:170px;background-color:#fff;border:1px solid #e5e5e5;min-height:30px;min-width:170px;font-size:.8em;padding:0 5px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300}.fields .attribute-select{min-width:100px;width:100px;margin-left:0}.fields .comparison-value{flex-grow:100;min-width:200px;display:flex;align-items:center;margin-left:.5em}.fields .comparison-value .error{color:#ff5252;margin:0 5px}.fields .comparison-value input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;min-width:170px;flex-grow:100;font-size:15px;padding:0 30px 0 10px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300}.fields .comparison-value .invalid{border:1px solid #ff5252}.value{margin-left:auto;flex-wrap:nowrap}.value .serve{margin:0 5px}.warn{padding-left:3em;font-size:.8em}.flex{display:flex;flex-wrap:wrap;align-items:center}.expand{position:absolute;right:2px;font-size:8px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.expand mat-icon{transform:rotate(45deg)}@media (max-width: 1200px){.targeting-row{flex-wrap:wrap}.targeting-row .fields{max-width:500px}}@media (max-width: 700px){.targeting-row{flex-direction:column;margin:.5em .3em}.targeting-row .help{left:161px}.targeting-row .fields{flex-direction:column;align-items:stretch}.targeting-row .fields .custom-select{margin:0}.targeting-row .fields .comparison-value{margin:0}}\n"]
902
- },] }
903
- ];
904
- RolloutRulesComponent.ctorParameters = () => [
905
- { type: MatDialog }
906
- ];
907
- RolloutRulesComponent.propDecorators = {
908
- formGroup: [{ type: Input }],
909
- readOnly: [{ type: Input }]
910
- };
911
-
912
- class ValueComponent {
913
- constructor(dialog) {
914
- this.dialog = dialog;
915
- this.SettingType = SettingType;
916
- }
917
- popOut() {
918
- this.dialog.open(ExpandDialogComponent, {
919
- width: '640px',
920
- data: { control: this.valueFormControl }
921
- });
922
- }
923
- }
924
- ValueComponent.decorators = [
925
- { type: Component, args: [{
926
- selector: 'configcat-value',
927
- template: "<div class=\"flex\">\n <div class=\"container\" [ngSwitch]=\"setting.settingType\">\n <div *ngSwitchCase=\"SettingType.String\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"text\"\n [formControl]=\"valueFormControl\" placeholder=\"my value\" name=\"value\">\n <div class=\"expand\" (click)=\"popOut()\" matTooltip=\"Pop-out Editor\">\n <mat-icon>height</mat-icon>\n </div>\n </div>\n <div *ngSwitchCase=\"SettingType.Int\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"number\" [formControl]=\"valueFormControl\"\n placeholder=\"42\" name=\"value\" />\n </div>\n <div *ngSwitchCase=\"SettingType.Double\" class=\"with-validation\">\n <span *ngIf=\"valueFormControl.invalid\" class=\"error\">*</span>\n <input [ngClass]=\"{'invalid': valueFormControl.invalid}\" type=\"number\" [formControl]=\"valueFormControl\"\n placeholder=\"3.14\" name=\"value\">\n </div>\n <div *ngSwitchCase=\"SettingType.Boolean\" class=\"toggle\">\n <label class=\"switch\">\n <input type=\"checkbox\" [formControl]=\"valueFormControl\" name=\"value\" />\n <span class=\"slider round\"></span>\n </label>\n </div>\n </div>\n <div *ngIf=\"setting.settingType === SettingType.Boolean\" class=\"spacer\"></div>\n\n</div>\n",
928
- styles: [".switch{position:relative;width:66px;height:30px;margin-left:4px;margin-top:0;margin-bottom:0}.switch input{display:none}.slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ff5252;transition:.4s;width:66px;height:30px}.slider:before{position:absolute;content:\"\";height:22px;width:22px;left:4px;bottom:4px;background-color:#fff;transition:.4s}input:checked+.slider{background-color:#9acd32}input:focus+.slider{box-shadow:0 0 1px #9acd32}input:checked+.slider:before{transform:translate(36px)}.slider.round{border-radius:34px}.slider.round:before{border-radius:50%}.slider:after{content:\"Off\";color:#fff;display:block;position:absolute;transform:translate(-14%,-50%);top:50%;left:50%;font-size:10px;font-family:Verdana,sans-serif}input:checked+.slider:after{content:\"On\";transform:translate(-91%,-50%)}\n", ".flex{display:flex;margin-right:20px;align-items:center}.flex .spacer{width:15px}.flex .container .with-validation{display:flex;flex-wrap:nowrap}.flex .container .toggle{width:66px;height:30px}.flex .container input{background-color:#fff;border:1px solid #e5e5e5;min-height:28px;font-size:15px;padding:0 30px 0 10px;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif;font-weight:300;min-width:170px}.flex .container .invalid{border:1px solid #ff5252}.flex .container .error{color:#ff5252;margin-right:5px}@media (max-width: 1200px){.flex .container input{min-width:auto}}.flex .variationId{margin-left:5px;cursor:pointer;color:#888;display:flex;align-items:center}.flex .expand{position:relative;top:2px;height:24px;cursor:pointer;margin-left:-28px;z-index:1;color:#b3b3b3;background-color:#fff}.flex .expand mat-icon{transform:rotate(45deg)}\n"]
929
- },] }
930
- ];
931
- ValueComponent.ctorParameters = () => [
932
- { type: MatDialog }
933
- ];
934
- ValueComponent.propDecorators = {
935
- valueFormControl: [{ type: Input }],
936
- setting: [{ type: Input }]
937
- };
938
-
939
- class SettingListFormHelper {
940
- constructor(formBuilder) {
941
- this.formBuilder = formBuilder;
942
- }
943
- createSettingValuesFormGroup(settingValuesModel) {
944
- const formGroup = this.formBuilder.group({
945
- settingValues: this.formBuilder.array(settingValuesModel.settingValues.map(sv => {
946
- return this.createSettingValueFormGroup(sv, settingValuesModel.readOnly);
947
- })),
948
- // Decorator
949
- environment: this.formBuilder.group({
950
- environmentId: [{ value: settingValuesModel.environment.environmentId, disabled: true }],
951
- name: [{ value: settingValuesModel.environment.name, disabled: true }],
952
- }),
953
- comparisonAttributes: [[]],
954
- allRolloutRulesCount: [0]
955
- });
956
- const rolloutRules = this.getAllRolloutRules(formGroup);
957
- const comparisonAttributes = this.getComparisonAttributes(rolloutRules);
958
- formGroup.patchValue({ allRolloutRulesCount: rolloutRules.length });
959
- formGroup.patchValue({ comparisonAttributes: comparisonAttributes });
960
- return formGroup;
961
- }
962
- createSettingValueFormGroup(settingValueModel, readOnly) {
963
- return this.formBuilder.group({
964
- settingId: [settingValueModel.setting.settingId],
965
- value: [
966
- { value: settingValueModel.value, disabled: readOnly },
967
- this.getValidatorsForSettingType(settingValueModel.setting.settingType)
968
- ],
969
- rolloutPercentageItems: this.formBuilder.array(settingValueModel.rolloutPercentageItems.map(p => {
970
- return this.createRolloutPercentageItemFormGroup(p, readOnly, settingValueModel.setting.settingType);
971
- })),
972
- rolloutRules: this.formBuilder.array(settingValueModel.rolloutRules.map(r => {
973
- return this.createRolloutRuleFormGroup(r, readOnly, settingValueModel.setting.settingType);
974
- })),
975
- updatedAt: [{ value: settingValueModel.updatedAt, disabled: true }],
976
- lastUpdaterUserEmail: [{ value: settingValueModel.lastUpdaterUserEmail, disabled: true }],
977
- lastUpdaterUserFullName: [{ value: settingValueModel.lastUpdaterUserFullName, disabled: true }],
978
- rolloutPercentageItemsSum: [{ value: 100, disabled: false }, [Validators.min(100), Validators.max(100)]],
979
- // Decoration
980
- setting: this.formBuilder.group({
981
- settingId: [{ value: settingValueModel.setting.settingId, disabled: true }],
982
- key: [{ value: settingValueModel.setting.key, disabled: true }],
983
- name: [{ value: settingValueModel.setting.name, disabled: true }],
984
- hint: [{ value: settingValueModel.setting.hint, disabled: true }],
985
- settingType: [{ value: settingValueModel.setting.settingType, disabled: true }],
986
- creatorEmail: [{ value: settingValueModel.setting.creatorEmail, disabled: true }],
987
- creatorFullName: [{ value: settingValueModel.setting.creatorFullName, disabled: true }],
988
- createdAt: [{ value: settingValueModel.setting.createdAt, disabled: true }]
989
- }),
990
- integrationLinks: this.formBuilder.array(settingValueModel.integrationLinks.map(il => {
991
- return this.formBuilder.group({
992
- key: [{ value: il.key, disabled: true }],
993
- description: [{ value: il.description, disabled: true }],
994
- integrationLinkType: [{ value: il.integrationLinkType, disabled: true }],
995
- url: [{ value: il.url, disabled: true }],
996
- });
997
- }))
998
- });
999
- }
1000
- createRolloutPercentageItemFormGroup(p, readOnly, settingType) {
1001
- return this.formBuilder.group({
1002
- percentage: [{ value: p.percentage, disabled: readOnly }, [Validators.required, Validators.min(0), Validators.max(100)]],
1003
- value: [
1004
- { value: p.value, disabled: readOnly },
1005
- [].concat(...[Validators.required, this.getValidatorsForSettingType(settingType)])
1006
- ],
1007
- valueDisabled: [
1008
- { value: p.value, disabled: true }, // For percentage item value
1009
- ]
1010
- });
1011
- }
1012
- createRolloutRuleFormGroup(r, readOnly, settingType) {
1013
- return this.formBuilder.group({
1014
- comparisonAttribute: [{ value: r.comparisonAttribute, disabled: readOnly }, [Validators.required]],
1015
- comparator: [{ value: r.comparator, disabled: readOnly }, [Validators.required]],
1016
- comparisonValue: [{ value: r.comparisonValue, disabled: readOnly }, [Validators.required]],
1017
- value: [
1018
- { value: r.value, disabled: readOnly },
1019
- this.getValidatorsForSettingType(settingType)
1020
- ],
1021
- });
1022
- }
1023
- getValidatorsForSettingType(settingType) {
1024
- switch (settingType) {
1025
- case SettingType.Int:
1026
- return [Validators.required,
1027
- Validators.min(-2147483648), Validators.max(2147483647), Validators.pattern('^[-+]?[0-9]\\d*$')];
1028
- case SettingType.Double:
1029
- return [Validators.required, Validators.min(-1.79769313486232E+308), Validators.max(1.79769313486232E+308)];
1030
- case SettingType.String:
1031
- case SettingType.Boolean:
1032
- return [Validators.required];
1033
- default:
1034
- return [];
1035
- }
1036
- }
1037
- getAllRolloutRules(formGroup) {
1038
- const settingValues = formGroup.get('settingValues');
1039
- const rolloutRules = settingValues.controls.map(cv => cv.get('rolloutRules').value);
1040
- return rolloutRules.length === 0 ? rolloutRules : rolloutRules.reduce((a, b) => a.concat(b));
1041
- }
1042
- getComparisonAttributes(rolloutRules) {
1043
- if (rolloutRules.length > 0) {
1044
- const currentComparisonAttributes = rolloutRules.map(r => r.comparisonAttribute);
1045
- const defaultComparisonAttributes = ['Identifier', 'Email', 'Country'];
1046
- const comparisonAttributes = currentComparisonAttributes.filter(c => defaultComparisonAttributes.indexOf(c) === -1);
1047
- return Array.from(new Set(comparisonAttributes));
1048
- }
1049
- else {
1050
- return [];
1051
- }
1052
- }
1053
- }
1054
- SettingListFormHelper.ɵprov = i0.ɵɵdefineInjectable({ factory: function SettingListFormHelper_Factory() { return new SettingListFormHelper(i0.ɵɵinject(i1$1.FormBuilder)); }, token: SettingListFormHelper, providedIn: "root" });
1055
- SettingListFormHelper.decorators = [
1056
- { type: Injectable, args: [{ providedIn: 'root' },] }
1057
- ];
1058
- SettingListFormHelper.ctorParameters = () => [
1059
- { type: FormBuilder }
1060
- ];
1061
-
1062
- class SettingListComponent {
1063
- constructor(formHelper, snackBar, dialog) {
1064
- this.formHelper = formHelper;
1065
- this.snackBar = snackBar;
1066
- this.dialog = dialog;
1067
- this.deleteSettingText = 'Delete setting';
1068
- this.showEnvironmentName = false;
1069
- this.editSettingRequested = new EventEmitter();
1070
- this.deleteSettingRequested = new EventEmitter();
1071
- this.formValuesChanged = new EventEmitter();
1072
- this.loading = true;
1073
- this.submitting = false;
1074
- this.showRevertQuestion = false;
1075
- this.showFeedBackMessage = false;
1076
- this.readOnly = false;
1077
- }
1078
- ngOnInit() {
1079
- this.reloadSettingValues();
1080
- }
1081
- ngOnChanges() {
1082
- this.reloadSettingValues();
1083
- }
1084
- ngOnDestroy() {
1085
- if (this.formValuesChangedSubscription) {
1086
- this.formValuesChangedSubscription.unsubscribe();
1087
- this.formValuesChangedSubscription = null;
1088
- }
1089
- }
1090
- reloadSettingValues() {
1091
- this.showFeedBackMessage = false;
1092
- this.loading = true;
1093
- this.loadSettingValues()
1094
- .subscribe(settingValues => {
1095
- this.readOnly = settingValues.readOnly;
1096
- this.settingValues = settingValues;
1097
- this.createFormGroup();
1098
- this.loading = false;
1099
- }, error => {
1100
- 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' });
1101
- });
1102
- }
1103
- createFormGroup() {
1104
- this.formGroup = this.formHelper.createSettingValuesFormGroup(this.settingValues);
1105
- this.formValuesChangedSubscription = this.formGroup.valueChanges.subscribe(() => {
1106
- this.formValuesChanged.emit();
1107
- });
1108
- }
1109
- settingValuesFormArray() {
1110
- return this.formGroup.get('settingValues');
1111
- }
1112
- submit() {
1113
- if (!this.formGroup || !this.formGroup.valid) {
1114
- this.showFeedBackMessage = true;
1115
- this.formGroup.markAsTouched();
1116
- return;
1117
- }
1118
- this.showFeedBackMessage = false;
1119
- this.submitting = true;
1120
- const updateSettingValuesModel = {
1121
- settingValues: this.formGroup.controls.settingValues.value,
1122
- knownLastUpdatedAt: this.settingValues.lastUpdatedAt,
1123
- forced: false
1124
- };
1125
- if (this.settingValues.reasonRequired) {
1126
- const dialogRef = this.dialog.open(ReasonDialogComponent, {
1127
- width: '450px'
1128
- });
1129
- dialogRef.afterClosed()
1130
- .subscribe(result => {
1131
- if (result && result.button === 'save' && result.reason) {
1132
- updateSettingValuesModel.reason = result.reason;
1133
- this.updateSettingValues(updateSettingValuesModel);
1134
- }
1135
- else {
1136
- this.submitting = false;
1137
- }
1138
- });
1139
- return;
1140
- }
1141
- this.updateSettingValues(updateSettingValuesModel);
1142
- }
1143
- updateSettingValues(updateSettingValuesModel) {
1144
- this.onSave(updateSettingValuesModel).subscribe(settingValues => {
1145
- this.settingValues = settingValues;
1146
- this.createFormGroup();
1147
- this.submitting = false;
1148
- this.snackBar.openFromComponent(SaveSnackbarComponent, { duration: 5000, panelClass: 'green-snackbar' });
1149
- }, (error) => {
1150
- if (error.status === 400 && error.error
1151
- && error.error.KnownLastUpdatedAt && error.error.KnownLastUpdatedAt[0] === 'Concurrent update') {
1152
- const dialogRef = this.dialog.open(ConcurrentDialogComponent, {
1153
- width: '560px'
1154
- });
1155
- dialogRef.afterClosed()
1156
- .subscribe(result => {
1157
- if (result && result.button === 'save') {
1158
- updateSettingValuesModel.forced = true;
1159
- this.updateSettingValues(updateSettingValuesModel);
1160
- }
1161
- else {
1162
- this.reloadSettingValues();
1163
- this.submitting = false;
1164
- }
1165
- });
1166
- return;
1167
- }
1168
- if (error.status === 400 && error.error && error.error.Reason && error.error.Reason[0] === 'Reason required') {
1169
- const dialogRef = this.dialog.open(ReasonDialogComponent, {
1170
- width: '450px'
1171
- });
1172
- dialogRef.afterClosed()
1173
- .subscribe(result => {
1174
- if (result && result.button === 'save' && result.reason) {
1175
- updateSettingValuesModel.reason = result.reason;
1176
- this.updateSettingValues(updateSettingValuesModel);
1177
- }
1178
- else {
1179
- this.submitting = false;
1180
- }
1181
- });
1182
- return;
1183
- }
1184
- this.formGroup.setErrors({ internalServerError: 'Internal server error' });
1185
- this.showFeedBackMessage = true;
1186
- });
1187
- }
1188
- handleRevertYes() {
1189
- this.showRevertQuestion = false;
1190
- this.reloadSettingValues();
1191
- }
1192
- handleRevertCancel() {
1193
- this.showRevertQuestion = false;
1194
- }
1195
- onEditSettingRequested(setting) {
1196
- this.editSettingRequested.emit({
1197
- setting: setting.setting,
1198
- environment: this.settingValues.environment,
1199
- config: this.settingValues.config
1200
- });
1201
- }
1202
- onDeleteSettingRequested(setting) {
1203
- this.deleteSettingRequested.emit({
1204
- setting: setting.setting,
1205
- environment: this.settingValues.environment,
1206
- config: this.settingValues.config
1207
- });
1208
- }
1209
- }
1210
- SettingListComponent.decorators = [
1211
- { type: Component, args: [{
1212
- selector: 'configcat-setting-list',
1213
- template: "<form [formGroup]=\"formGroup\" (ngSubmit)=\"submit()\" *ngIf=\"!loading\">\n <div class=\"wrapper\" *ngFor=\"let settingValueFromGroup of settingValuesFormArray().controls; let i = index\">\n <setting [formGroup]=\"settingValueFromGroup\" [readOnly]=\"readOnly\"\n [canEditSetting]=\"canEditSetting\" [canDeleteSetting]=\"canDeleteSetting\"\n (editSettingRequested)=\"onEditSettingRequested($event)\"\n (deleteSettingRequested)=\"onDeleteSettingRequested($event)\" [deleteSettingText]=\"deleteSettingText\"\n [showEnvironmentName]=\"showEnvironmentName\">\n </setting>\n </div>\n\n <div class=\"save\" *ngIf=\"!readOnly && !submitting && formGroup.dirty\">\n <div class=\"feedback\" *ngIf=\"formGroup.touched && formGroup.invalid && showFeedBackMessage\">\n <div class=\"error\" *ngIf=\"formGroup.errors && formGroup.errors.internalServerError\">\n <span>Something went wrong and we could not save your settings. You can try again or <a\n href=\"https://configcat.com/support\" target=\"_blank\" rel=\"noopener noreferrer\">contact us.</a></span>\n </div>\n <div class=\"error\" *ngIf=\"!formGroup.errors || !formGroup.errors.internalServerError\">\n <span>Oh no! A feature flag has invalid or missing data.</span>\n </div>\n </div>\n <button type=\"button\" mat-stroked-button *ngIf=\"!showRevertQuestion\" (click)=\"showRevertQuestion = true\">\n <mat-icon>history</mat-icon><span>Revert changes</span>\n </button>\n <div *ngIf=\"showRevertQuestion\">\n <span class=\"revert\">Revert to last saved state?</span>\n <button type=\"button\" class=\"yes\" mat-stroked-button (click)=\"handleRevertYes()\">Yes</button>\n <button type=\"button\" mat-stroked-button (click)=\"handleRevertCancel()\">No</button>\n </div>\n <button class=\"save-button\" mat-flat-button color=\"warn\" type=\"submit\" [disabled]=\"submitting\">\n <mat-icon>backup</mat-icon> <span> Save & publish changes</span>\n </button>\n </div>\n</form>\n",
1214
- styles: [".wrapper{background-color:#f3f3f3;border:1px solid rgba(0,0,0,.12);border-radius:4px;margin:1em 0}.show-hide a{cursor:pointer;font-size:.8rem}.save{position:sticky;bottom:0;min-height:38px;padding:.5rem .5rem .5rem 0;background-color:#fff;display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:flex-end;z-index:1000}.save .save-button{-webkit-animation:shadow-pulse 1s 3;animation:shadow-pulse 1s 3;margin-left:1rem}.save>*{margin:.3em}.save .revert{margin:0 16px;font-size:14px}.save .yes{margin:0 5px}.error{background-color:#a32b2d;color:#fff;padding:5px;font-size:.9em}.error a{color:#fff;text-decoration:underline}@media (max-width: 700px){.save{padding:.5rem 0}}\n"]
1215
- },] }
1216
- ];
1217
- SettingListComponent.ctorParameters = () => [
1218
- { type: SettingListFormHelper },
1219
- { type: MatSnackBar },
1220
- { type: MatDialog }
1221
- ];
1222
- SettingListComponent.propDecorators = {
1223
- canEditSetting: [{ type: Input }],
1224
- canDeleteSetting: [{ type: Input }],
1225
- onSave: [{ type: Input }],
1226
- loadSettingValues: [{ type: Input }],
1227
- deleteSettingText: [{ type: Input }],
1228
- showEnvironmentName: [{ type: Input }],
1229
- editSettingRequested: [{ type: Output }],
1230
- deleteSettingRequested: [{ type: Output }],
1231
- formValuesChanged: [{ type: Output }]
1232
- };
1233
-
1234
- class SettingComponent {
1235
- constructor(formHelper, cdRef) {
1236
- this.formHelper = formHelper;
1237
- this.cdRef = cdRef;
1238
- this.deleteSettingText = 'Delete setting';
1239
- this.showEnvironmentName = false;
1240
- this.editSettingRequested = new EventEmitter();
1241
- this.deleteSettingRequested = new EventEmitter();
1242
- this.rulesBeingRendered = false;
1243
- this.SettingType = SettingType;
1244
- }
1245
- ngOnInit() { }
1246
- environment() {
1247
- return this.formGroup.root.get('environment').value;
1248
- }
1249
- setting() {
1250
- return this.formGroup.get('setting').value;
1251
- }
1252
- integrationLinks() {
1253
- return this.formGroup.get('integrationLinks');
1254
- }
1255
- rolloutRules() {
1256
- return this.formGroup.get('rolloutRules');
1257
- }
1258
- rolloutPercentageItems() {
1259
- return this.formGroup.get('rolloutPercentageItems');
1260
- }
1261
- value() {
1262
- return this.formGroup.get('value');
1263
- }
1264
- addRolloutRule() {
1265
- this.rolloutRules().push(this.formHelper.createRolloutRuleFormGroup({
1266
- comparisonAttribute: 'Identifier',
1267
- comparator: RolloutRuleComparator.SensitiveIsOneOf,
1268
- comparisonValue: '',
1269
- value: this.setting().settingType === SettingType.Boolean ? false : null
1270
- }, this.readOnly, this.setting().settingType));
1271
- this.rolloutRules().markAsDirty();
1272
- }
1273
- removeRolloutRules() {
1274
- this.rolloutRules().clear();
1275
- this.rolloutRules().markAsDirty();
1276
- }
1277
- addRolloutPercentageItem() {
1278
- if (this.rolloutPercentageItems().length === 0) {
1279
- switch (this.setting().settingType) {
1280
- case SettingType.Boolean:
1281
- this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1282
- percentage: 0,
1283
- value: true
1284
- }, this.readOnly, this.setting().settingType));
1285
- this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1286
- percentage: 100,
1287
- value: false
1288
- }, this.readOnly, this.setting().settingType));
1289
- break;
1290
- case SettingType.String:
1291
- case SettingType.Int:
1292
- case SettingType.Double:
1293
- for (let i = 0; i < 4; i++) {
1294
- this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1295
- percentage: 25,
1296
- value: null
1297
- }, this.readOnly, this.setting().settingType));
1298
- }
1299
- break;
1300
- }
1301
- }
1302
- else if (this.setting().settingType !== SettingType.Boolean) {
1303
- this.rolloutPercentageItems().push(this.formHelper.createRolloutPercentageItemFormGroup({
1304
- percentage: 0,
1305
- value: null
1306
- }, this.readOnly, this.setting().settingType));
1307
- }
1308
- this.rolloutPercentageItems().markAsDirty();
1309
- }
1310
- removeRolloutPercentageItems() {
1311
- this.rolloutPercentageItems().clear();
1312
- this.rolloutPercentageItems().markAsDirty();
1313
- }
1314
- editSetting() {
1315
- this.editSettingRequested.emit({ setting: this.setting() });
1316
- }
1317
- deleteSetting() {
1318
- this.deleteSettingRequested.emit({ setting: this.setting() });
1319
- }
1320
- }
1321
- SettingComponent.decorators = [
1322
- { type: Component, args: [{
1323
- selector: 'setting',
1324
- template: "<div class=\"setting-full\"\n [formGroup]=\"formGroup\">\n <div class=\"delete\" (click)=\"deleteSetting()\" *ngIf=\"canDeleteSetting\" [matTooltip]=\"deleteSettingText\"\n data-robot=\"deleteSetting\">\n <mat-icon>cancel</mat-icon>\n </div>\n <div class=\"setting-header flex\">\n <div class=\"setting-name flex\">\n <div class=\"name\" data-robot=\"settingName\">\n {{setting().name}}\n <span *ngIf=\"showEnvironmentName\"> ({{environment().name}})</span>\n </div>\n <div class=\"edit\" matTooltip=\"Edit name and description\" (click)=\"editSetting()\" *ngIf=\"canEditSetting\"\n data-robot=\"renameSetting\">\n <mat-icon>edit</mat-icon>\n </div>\n </div>\n </div>\n <div class=\"setting-content\">\n <div class=\"setting-details\">\n <div class=\"setting-key\"><code data-robot=\"settingKey\">{{setting().key}}</code></div>\n <span *ngIf=\"setting().hint\" class=\"description\">{{setting().hint}}</span>\n </div>\n\n <div class=\"rules-list\">\n <div>\n <configcat-rollout-rules *ngIf=\"rolloutRules().controls.length !== 0\" [formGroup]=\"formGroup\">\n </configcat-rollout-rules>\n </div>\n\n <configcat-rollout-percentage-items *ngIf=\"rolloutPercentageItems().controls.length !== 0\"\n [formGroup]=\"formGroup\">\n </configcat-rollout-percentage-items>\n\n <div class=\"all-other flex\">\n <div *ngIf=\"rolloutPercentageItems().length === 0 && rolloutRules().length !== 0\"\n data-tooltip=\"This value will be served to all users who the above rules don't apply.\">\n <mat-chip-list>\n <mat-chip class=\"chip\">To all other users, serve:</mat-chip>\n </mat-chip-list>\n </div>\n <div *ngIf=\"rolloutPercentageItems().length !== 0\"\n data-tooltip=\"This fallback value will be served in case the user can't be identified.\">\n <mat-chip-list>\n <mat-chip class=\"chip\">To unidentified users, serve:</mat-chip>\n </mat-chip-list>\n </div>\n <div *ngIf=\"rolloutPercentageItems().length === 0 && rolloutRules().length === 0\">\n <mat-chip-list>\n <mat-chip class=\"chip\">To all users, serve:</mat-chip>\n </mat-chip-list>\n </div>\n <configcat-value class=\"served-value\" [valueFormControl]=\"value()\" [setting]=\"setting()\">\n </configcat-value>\n </div>\n <div class=\"buttons\">\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addRolloutRule()\" *ngIf=\"!readOnly\">\n {{rolloutRules().length === 0 ? 'Target specific users' : 'Add new targeting rule'}}\n </button>\n <button type=\"button\" class=\"sige-button targeting-button\" (click)=\"addRolloutPercentageItem()\"\n *ngIf=\"!readOnly\"\n [disabled]=\"setting().settingType === SettingType.Boolean && rolloutPercentageItems().length !== 0\">\n {{rolloutPercentageItems().length === 0 ? 'Target % of users' : 'Add new % option'}}\n </button>\n </div>\n </div>\n </div>\n</div>\n",
1325
- styles: [".setting-full{position:relative;display:flex;flex-wrap:nowrap;flex-direction:column;border-radius:3px}.setting-full .delete{position:absolute;right:-15px;top:-10px;color:#d6a9a9;cursor:pointer}.setting-full .delete:hover{color:#ed5251}.setting-full .delete mat-icon{font-size:20px}.setting-full .setting-header{padding:1.5em 1.5em 0}.setting-full .setting-header .setting-name{flex-direction:row}.setting-full .setting-header .setting-name:hover>.edit{visibility:visible}.setting-full .setting-header .setting-name .name{font-weight:bold;word-wrap:break-word;max-width:100%}.setting-full .setting-header .setting-name .edit{margin:5px 0 0 5px;cursor:pointer;visibility:hidden;color:gray}.setting-full .setting-header .setting-name .edit:hover{visibility:visible}.setting-full .setting-header .setting-name .edit mat-icon{font-size:18px}.setting-full .setting-header .setting-meta{margin-left:auto;margin-right:14px;font-size:.7em;color:gray}.setting-full .setting-content{display:flex}.setting-full .setting-content .setting-details{display:flex;flex-direction:column;width:400px;padding:0 0 1em 1em}.setting-full .setting-content .setting-details>*{margin:.5em}.setting-full .setting-content .setting-details .integrations{font-size:.8rem}.setting-full .setting-content .setting-details .integrations>div{margin:3px}.setting-full .setting-content .setting-details .integrations>div>a:hover{text-decoration:underline}.setting-full .setting-content .setting-details .setting-key{word-wrap:break-word}.setting-full .setting-content .setting-details .description{font-size:.8em;white-space:pre-wrap;word-wrap:break-word;max-width:300px}.setting-full .setting-content .setting-details code{background-color:#d3d3d3;padding:3px 6px}.setting-full .setting-content .rules-list{width:100%;padding:0 1em 1em}.setting-full .setting-content .targeting-button{margin-left:.5rem;margin-right:.5rem;margin-bottom:1em}.all-other{min-height:40px;justify-content:flex-start;border:1px solid #d5d5d5;border-radius:4px;background-color:#fff;margin:.5em 1em;padding:4px 0 4px .5em}.all-other .chip{background-color:#67b1fc3d}.all-other .served-value{margin-left:auto;min-width:100px}.end{margin-left:auto}.buttons{display:flex;margin-left:.5rem;margin-right:.5rem}.buttons .updated-date{font-size:.7em;margin-left:auto;margin-right:22px;color:gray}.flex{display:flex;flex-wrap:wrap;align-items:center}.show-hide-toggle{margin-left:1em;cursor:pointer}.show-hide-toggle a{font-size:.8rem}.sige-button{background-color:#d9eadc;color:#363636;cursor:pointer;justify-content:center;padding:.375em .75em;text-align:center;white-space:nowrap;border-radius:2px;font-size:.75rem;border:1px solid #dbdbdb;box-shadow:none;display:inline-flex;font-family:Montserrat,Roboto,\"Helvetica Neue\",sans-serif}.sige-button:hover{background-color:#bad0be}.sige-button:disabled{background-color:#fff;color:#b3b3b3}@media (max-width: 1200px){.setting-details{width:300px}}@media (max-width: 700px){.setting-full .setting-content{flex-wrap:wrap}.setting-full .setting-content .rules-list{padding:0}.buttons{flex-direction:column}.updated-date{display:none}.setting-details{padding:.2em 0 .2em .2em}.all-other{margin:.5em .3em}}\n"]
1326
- },] }
1327
- ];
1328
- SettingComponent.ctorParameters = () => [
1329
- { type: SettingListFormHelper },
1330
- { type: ChangeDetectorRef }
1331
- ];
1332
- SettingComponent.propDecorators = {
1333
- formGroup: [{ type: Input }],
1334
- readOnly: [{ type: Input }],
1335
- canEditSetting: [{ type: Input }],
1336
- canDeleteSetting: [{ type: Input }],
1337
- deleteSettingText: [{ type: Input }],
1338
- showEnvironmentName: [{ type: Input }],
1339
- editSettingRequested: [{ type: Output }],
1340
- deleteSettingRequested: [{ type: Output }]
1341
- };
1342
-
1343
- class NgConfigCatPublicApiUIModule {
1344
- constructor() { }
1345
- static forRoot(configurationFactory) {
1346
- return {
1347
- ngModule: NgConfigCatPublicApiUIModule,
1348
- providers: [{ provide: Configuration, useFactory: configurationFactory }]
1349
- };
1350
- }
1351
- }
1352
- NgConfigCatPublicApiUIModule.decorators = [
1353
- { type: NgModule, args: [{
1354
- declarations: [
1355
- BaseComponent,
1356
- ProductSelectComponent,
1357
- ConfigSelectComponent,
1358
- EnvironmentSelectComponent,
1359
- SettingSelectComponent,
1360
- SettingItemComponent,
1361
- AuthorizationComponent,
1362
- SettingListComponent,
1363
- SettingComponent,
1364
- RolloutPercentageItemsComponent,
1365
- RolloutRulesComponent,
1366
- ValueComponent,
1367
- ReasonDialogComponent,
1368
- ConcurrentDialogComponent,
1369
- SaveSnackbarComponent,
1370
- ExpandDialogComponent
1371
- ],
1372
- imports: [
1373
- CommonModule,
1374
- FormsModule,
1375
- ReactiveFormsModule,
1376
- BrowserAnimationsModule,
1377
- HttpClientModule,
1378
- ApiModule,
1379
- MatFormFieldModule,
1380
- MatOptionModule,
1381
- MatSelectModule,
1382
- MatButtonModule,
1383
- MatInputModule,
1384
- MatIconModule,
1385
- MatTooltipModule,
1386
- MatChipsModule,
1387
- MatAutocompleteModule,
1388
- DragDropModule,
1389
- RouterModule,
1390
- MatSnackBarModule,
1391
- MatDialogModule,
1392
- MatMenuModule
1393
- ],
1394
- exports: [
1395
- ApiModule,
1396
- AuthorizationComponent,
1397
- ProductSelectComponent,
1398
- ConfigSelectComponent,
1399
- EnvironmentSelectComponent,
1400
- SettingSelectComponent,
1401
- SettingItemComponent
1402
- ]
1403
- },] }
1404
- ];
1405
- NgConfigCatPublicApiUIModule.ctorParameters = () => [];
1406
-
1407
- /*
1408
- * Public API Surface of ng-configcat-publicapi-ui
1409
- */
1410
-
1411
- /**
1412
- * Generated bundle index. Do not edit.
1413
- */
1414
-
1415
- export { AuthorizationComponent, ConfigSelectComponent, EnvironmentSelectComponent, NgConfigCatPublicApiUIModule, ProductSelectComponent, PublicApiService, SettingItemComponent, SettingSelectComponent, BaseComponent as ɵa, PublicApiService as ɵb, Configuration as ɵc, PublicApiService as ɵd, SettingListComponent as ɵe, SettingListFormHelper as ɵf, SettingComponent as ɵg, RolloutPercentageItemsComponent as ɵh, RolloutRulesComponent as ɵi, ValueComponent as ɵj, ReasonDialogComponent as ɵk, ConcurrentDialogComponent as ɵl, SaveSnackbarComponent as ɵm, ExpandDialogComponent as ɵn };
1416
- //# sourceMappingURL=ng-configcat-publicapi-ui.js.map