@abp/ng.feature-management 7.2.2 → 7.3.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +129 -2
  2. package/{esm2020 → esm2022}/abp-ng.feature-management.mjs +4 -4
  3. package/esm2022/lib/components/feature-management/feature-management.component.mjs +179 -0
  4. package/esm2022/lib/components/feature-management-tab/feature-management-tab.component.mjs +25 -0
  5. package/{esm2020 → esm2022}/lib/components/index.mjs +2 -2
  6. package/esm2022/lib/directives/free-text-input.directive.mjs +37 -0
  7. package/{esm2020 → esm2022}/lib/directives/index.mjs +1 -1
  8. package/{esm2020 → esm2022}/lib/enums/components.mjs +1 -1
  9. package/{esm2020 → esm2022}/lib/enums/feature-management-tab-names.mjs +1 -1
  10. package/esm2022/lib/feature-management.module.mjs +39 -0
  11. package/{esm2020 → esm2022}/lib/models/feature-management.mjs +1 -1
  12. package/{esm2020 → esm2022}/lib/models/index.mjs +1 -1
  13. package/{esm2020 → esm2022}/lib/providers/feature-management-settings.provider.mjs +23 -23
  14. package/{esm2020 → esm2022}/lib/providers/index.mjs +1 -1
  15. package/{esm2020 → esm2022}/proxy/abp-ng.feature-management-proxy.mjs +4 -4
  16. package/{esm2020 → esm2022}/proxy/lib/index.mjs +2 -2
  17. package/esm2022/proxy/lib/proxy/feature-management/features.service.mjs +36 -0
  18. package/{esm2020 → esm2022}/proxy/lib/proxy/feature-management/index.mjs +2 -2
  19. package/{esm2020 → esm2022}/proxy/lib/proxy/feature-management/models.mjs +1 -1
  20. package/{esm2020 → esm2022}/proxy/lib/proxy/validation/index.mjs +2 -2
  21. package/{esm2020 → esm2022}/proxy/lib/proxy/validation/string-values/index.mjs +1 -1
  22. package/{esm2020 → esm2022}/proxy/lib/proxy/validation/string-values/models.mjs +1 -1
  23. package/{esm2020 → esm2022}/proxy/public-api.mjs +1 -1
  24. package/{esm2020 → esm2022}/public-api.mjs +6 -6
  25. package/{fesm2015 → fesm2022}/abp-ng.feature-management-proxy.mjs +32 -32
  26. package/{fesm2015 → fesm2022}/abp-ng.feature-management-proxy.mjs.map +1 -1
  27. package/{fesm2020 → fesm2022}/abp-ng.feature-management.mjs +261 -261
  28. package/fesm2022/abp-ng.feature-management.mjs.map +1 -0
  29. package/index.d.ts +5 -5
  30. package/lib/components/feature-management/feature-management.component.d.ts +53 -53
  31. package/lib/components/feature-management-tab/feature-management-tab.component.d.ts +9 -9
  32. package/lib/components/index.d.ts +2 -2
  33. package/lib/directives/free-text-input.directive.d.ts +21 -21
  34. package/lib/directives/index.d.ts +1 -1
  35. package/lib/enums/components.d.ts +3 -3
  36. package/lib/enums/feature-management-tab-names.d.ts +3 -3
  37. package/lib/feature-management.module.d.ts +14 -14
  38. package/lib/models/feature-management.d.ts +11 -11
  39. package/lib/models/index.d.ts +1 -1
  40. package/lib/providers/feature-management-settings.provider.d.ts +8 -8
  41. package/lib/providers/index.d.ts +1 -1
  42. package/package.json +11 -19
  43. package/proxy/index.d.ts +5 -5
  44. package/proxy/lib/index.d.ts +2 -2
  45. package/proxy/lib/proxy/feature-management/features.service.d.ts +13 -13
  46. package/proxy/lib/proxy/feature-management/index.d.ts +2 -2
  47. package/proxy/lib/proxy/feature-management/models.d.ts +30 -30
  48. package/proxy/lib/proxy/validation/index.d.ts +2 -2
  49. package/proxy/lib/proxy/validation/string-values/index.d.ts +1 -1
  50. package/proxy/lib/proxy/validation/string-values/models.d.ts +11 -11
  51. package/proxy/public-api.d.ts +1 -1
  52. package/public-api.d.ts +6 -6
  53. package/esm2020/lib/components/feature-management/feature-management.component.mjs +0 -178
  54. package/esm2020/lib/components/feature-management-tab/feature-management-tab.component.mjs +0 -24
  55. package/esm2020/lib/directives/free-text-input.directive.mjs +0 -36
  56. package/esm2020/lib/feature-management.module.mjs +0 -38
  57. package/esm2020/proxy/lib/proxy/feature-management/features.service.mjs +0 -35
  58. package/fesm2015/abp-ng.feature-management.mjs +0 -285
  59. package/fesm2015/abp-ng.feature-management.mjs.map +0 -1
  60. package/fesm2020/abp-ng.feature-management-proxy.mjs +0 -45
  61. package/fesm2020/abp-ng.feature-management-proxy.mjs.map +0 -1
  62. package/fesm2020/abp-ng.feature-management.mjs.map +0 -1
  63. package/proxy/src/lib/proxy/README.md +0 -17
@@ -12,277 +12,277 @@ import * as i6 from '@ng-bootstrap/ng-bootstrap';
12
12
  import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
13
13
  import { SettingTabsService } from '@abp/ng.setting-management/config';
14
14
 
15
- const INPUT_TYPES = {
16
- numeric: 'number',
17
- default: 'text',
18
- };
19
- class FreeTextInputDirective {
20
- // eslint-disable-next-line @angular-eslint/no-input-rename
21
- set feature(val) {
22
- this._feature = val;
23
- this.setInputType();
24
- }
25
- get feature() {
26
- return this._feature;
27
- }
28
- setInputType() {
29
- const validatorType = this.feature?.valueType?.validator?.name.toLowerCase();
30
- this.type = INPUT_TYPES[validatorType] ?? INPUT_TYPES.default;
31
- }
32
- }
33
- FreeTextInputDirectivefac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: FreeTextInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
34
- FreeTextInputDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.4", type: FreeTextInputDirective, selector: "input[abpFeatureManagementFreeText]", inputs: { feature: ["abpFeatureManagementFreeText", "feature"] }, host: { properties: { "type": "this.type" } }, exportAs: ["inputAbpFeatureManagementFreeText"], ngImport: i0 });
35
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: FreeTextInputDirective, decorators: [{
36
- type: Directive,
37
- args: [{
38
- selector: 'input[abpFeatureManagementFreeText]',
39
- exportAs: 'inputAbpFeatureManagementFreeText',
40
- }]
41
- }], propDecorators: { feature: [{
42
- type: Input,
43
- args: ['abpFeatureManagementFreeText']
44
- }], type: [{
45
- type: HostBinding,
46
- args: ['type']
15
+ const INPUT_TYPES = {
16
+ numeric: 'number',
17
+ default: 'text',
18
+ };
19
+ class FreeTextInputDirective {
20
+ // eslint-disable-next-line @angular-eslint/no-input-rename
21
+ set feature(val) {
22
+ this._feature = val;
23
+ this.setInputType();
24
+ }
25
+ get feature() {
26
+ return this._feature;
27
+ }
28
+ setInputType() {
29
+ const validatorType = this.feature?.valueType?.validator?.name.toLowerCase();
30
+ this.type = INPUT_TYPES[validatorType] ?? INPUT_TYPES.default;
31
+ }
32
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FreeTextInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
33
+ static { thisdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.1", type: FreeTextInputDirective, selector: "input[abpFeatureManagementFreeText]", inputs: { feature: ["abpFeatureManagementFreeText", "feature"] }, host: { properties: { "type": "this.type" } }, exportAs: ["inputAbpFeatureManagementFreeText"], ngImport: i0 }); }
34
+ }
35
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FreeTextInputDirective, decorators: [{
36
+ type: Directive,
37
+ args: [{
38
+ selector: 'input[abpFeatureManagementFreeText]',
39
+ exportAs: 'inputAbpFeatureManagementFreeText',
40
+ }]
41
+ }], propDecorators: { feature: [{
42
+ type: Input,
43
+ args: ['abpFeatureManagementFreeText']
44
+ }], type: [{
45
+ type: HostBinding,
46
+ args: ['type']
47
47
  }] } });
48
48
 
49
- var ValueTypes;
50
- (function (ValueTypes) {
51
- ValueTypes["ToggleStringValueType"] = "ToggleStringValueType";
52
- ValueTypes["FreeTextStringValueType"] = "FreeTextStringValueType";
53
- ValueTypes["SelectionStringValueType"] = "SelectionStringValueType";
54
- })(ValueTypes || (ValueTypes = {}));
55
- class FeatureManagementComponent {
56
- constructor(track, toasterService, service, configState, confirmationService) {
57
- this.track = track;
58
- this.toasterService = toasterService;
59
- this.service = service;
60
- this.configState = configState;
61
- this.confirmationService = confirmationService;
62
- this.groups = [];
63
- this.valueTypes = ValueTypes;
64
- this.visibleChange = new EventEmitter();
65
- this.modalBusy = false;
66
- }
67
- get visible() {
68
- return this._visible;
69
- }
70
- set visible(value) {
71
- if (this._visible === value)
72
- return;
73
- this._visible = value;
74
- this.visibleChange.emit(value);
75
- if (value)
76
- this.openModal();
77
- }
78
- openModal() {
79
- if (!this.providerName) {
80
- throw new Error('providerName is required.');
81
- }
82
- this.getFeatures();
83
- }
84
- getFeatures() {
85
- this.service.get(this.providerName, this.providerKey).subscribe(res => {
86
- if (!res.groups?.length)
87
- return;
88
- this.groups = res.groups.map(({ name, displayName }) => ({ name, displayName }));
89
- this.selectedGroupDisplayName = this.groups[0].displayName;
90
- this.features = res.groups.reduce((acc, val) => ({
91
- ...acc,
92
- [val.name]: mapFeatures(val.features, document.body.dir),
93
- }), {});
94
- });
95
- }
96
- save() {
97
- if (this.modalBusy)
98
- return;
99
- const changedFeatures = [];
100
- Object.keys(this.features).forEach(key => {
101
- this.features[key].forEach(feature => {
102
- if (feature.value !== feature.initialValue)
103
- changedFeatures.push({ name: feature.name, value: `${feature.value}` });
104
- });
105
- });
106
- if (!changedFeatures.length) {
107
- this.visible = false;
108
- return;
109
- }
110
- this.modalBusy = true;
111
- this.service
112
- .update(this.providerName, this.providerKey, { features: changedFeatures })
113
- .pipe(finalize(() => (this.modalBusy = false)))
114
- .subscribe(() => {
115
- this.visible = false;
116
- if (!this.providerKey) {
117
- // to refresh host's features
118
- this.configState.refreshAppState().subscribe();
119
- }
120
- });
121
- }
122
- resetToDefault() {
123
- this.confirmationService
124
- .warn('AbpFeatureManagement::AreYouSureToResetToDefault', 'AbpFeatureManagement::AreYouSure')
125
- .subscribe((status) => {
126
- if (status === Confirmation.Status.confirm) {
127
- this.service.delete(this.providerName, this.providerKey).subscribe(() => {
128
- this.toasterService.success('AbpFeatureManagement::ResetedToDefault');
129
- this.visible = false;
130
- if (!this.providerKey) {
131
- // to refresh host's features
132
- this.configState.refreshAppState().subscribe();
133
- }
134
- });
135
- }
136
- });
137
- }
138
- onCheckboxClick(val, feature) {
139
- if (val) {
140
- this.checkToggleAncestors(feature);
141
- }
142
- else {
143
- this.uncheckToggleDescendants(feature);
144
- }
145
- }
146
- uncheckToggleDescendants(feature) {
147
- this.findAllDescendantsOfByType(feature, ValueTypes.ToggleStringValueType).forEach(node => this.setFeatureValue(node, false));
148
- }
149
- checkToggleAncestors(feature) {
150
- this.findAllAncestorsOfByType(feature, ValueTypes.ToggleStringValueType).forEach(node => this.setFeatureValue(node, true));
151
- }
152
- findAllAncestorsOfByType(feature, type) {
153
- let parent = this.findParentByType(feature, type);
154
- const ancestors = [];
155
- while (parent) {
156
- ancestors.push(parent);
157
- parent = this.findParentByType(parent, type);
158
- }
159
- return ancestors;
160
- }
161
- findAllDescendantsOfByType(feature, type) {
162
- const descendants = [];
163
- const queue = [feature];
164
- while (queue.length) {
165
- const node = queue.pop();
166
- const newDescendants = this.findChildrenByType(node, type);
167
- descendants.push(...newDescendants);
168
- queue.push(...newDescendants);
169
- }
170
- return descendants;
171
- }
172
- findParentByType(feature, type) {
173
- return this.getCurrentGroup().find(f => f.valueType.name === type && f.name === feature.parentName);
174
- }
175
- findChildrenByType(feature, type) {
176
- return this.getCurrentGroup().filter(f => f.valueType.name === type && f.parentName === feature.name);
177
- }
178
- getCurrentGroup() {
179
- return this.features[this.selectedGroupDisplayName] ?? [];
180
- }
181
- setFeatureValue(feature, val) {
182
- feature.value = val;
183
- }
184
- }
185
- FeatureManagementComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: FeatureManagementComponent, deps: [{ token: i1.TrackByService }, { token: i2.ToasterService }, { token: i3.FeaturesService }, { token: i1.ConfigStateService }, { token: i2.ConfirmationService }], target: i0.ɵɵFactoryTarget.Component });
186
- FeatureManagementComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: FeatureManagementComponent, selector: "abp-feature-management", inputs: { providerKey: "providerKey", providerName: "providerName", visible: "visible" }, outputs: { visibleChange: "visibleChange" }, exportAs: ["abpFeatureManagement"], ngImport: i0, template: "<abp-modal *ngIf=\"visible\" [(visible)]=\"visible\" [busy]=\"modalBusy\" [options]=\"{ size: 'lg' }\">\r\n <ng-template #abpHeader>\r\n <h3>{{ 'AbpFeatureManagement::Features' | abpLocalization }}</h3>\r\n </ng-template>\r\n\r\n <ng-template #abpBody>\r\n <div class=\"row\">\r\n <ng-container *ngIf=\"groups.length\">\r\n <div class=\"col-md-4\">\r\n <ul\r\n ngbNav\r\n #nav=\"ngbNav\"\r\n [(activeId)]=\"selectedGroupDisplayName\"\r\n class=\"nav-pills\"\r\n orientation=\"vertical\"\r\n >\r\n <li\r\n *ngFor=\"let group of groups; trackBy: track.by('name')\"\r\n [ngbNavItem]=\"group.displayName\"\r\n >\r\n <a ngbNavLink>{{ group.displayName }}</a>\r\n <ng-template ngbNavContent>\r\n <h4>{{ selectedGroupDisplayName }}</h4>\r\n <hr class=\"mt-2 mb-3\" />\r\n\r\n <div\r\n class=\"mt-2\"\r\n *ngFor=\"\r\n let feature of features[group.name];\r\n let i = index;\r\n trackBy: track.by('id')\r\n \"\r\n [ngStyle]=\"feature.style\"\r\n [ngSwitch]=\"feature.valueType?.name\"\r\n (keyup.enter)=\"save()\"\r\n >\r\n <ng-container *ngSwitchCase=\"valueTypes.ToggleStringValueType\">\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"feature.name\"\r\n [(ngModel)]=\"feature.value\"\r\n (ngModelChange)=\"onCheckboxClick($event, feature)\"\r\n />\r\n\r\n <label class=\"form-check-label\" [htmlFor]=\"feature.name\">{{\r\n feature.displayName\r\n }}</label>\r\n <ng-container\r\n *ngTemplateOutlet=\"descTmp; context: { $implicit: feature.description }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"valueTypes.FreeTextStringValueType\">\r\n <div class=\"mb-3 form-group\">\r\n <label [htmlFor]=\"feature.name\" class=\"form-label\">{{\r\n feature.displayName\r\n }}</label>\r\n <input\r\n class=\"form-control\"\r\n type=\"text\"\r\n [id]=\"feature.name\"\r\n [(ngModel)]=\"feature.value\"\r\n [abpFeatureManagementFreeText]=\"feature\"\r\n />\r\n\r\n <ng-container\r\n *ngTemplateOutlet=\"descTmp; context: { $implicit: feature.description }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"valueTypes.SelectionStringValueType\">\r\n <ng-container *ngIf=\"feature.valueType.itemSource?.items?.length\">\r\n <div class=\"mb-3 form-group\">\r\n <label [htmlFor]=\"feature.name\" class=\"form-label\">{{\r\n feature.displayName\r\n }}</label>\r\n <select class=\"form-select\" [id]=\"feature.name\" [(ngModel)]=\"feature.value\">\r\n <option\r\n *ngFor=\"\r\n let item of feature.valueType.itemSource?.items;\r\n trackBy: track.by('value')\r\n \"\r\n [ngValue]=\"item.value\"\r\n >\r\n {{\r\n item.displayText?.resourceName + '::' + item.displayText?.name\r\n | abpLocalization\r\n }}\r\n </option>\r\n </select>\r\n <ng-container\r\n *ngTemplateOutlet=\"descTmp; context: { $implicit: feature.description }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchDefault>{{ feature.displayName }}</ng-container>\r\n </div>\r\n </ng-template>\r\n </li>\r\n </ul>\r\n </div>\r\n\r\n <ng-template #descTmp let-description>\r\n <small *ngIf=\"description\" class=\"d-block form-text text-muted\">{{ description }}</small>\r\n </ng-template>\r\n\r\n <div class=\"col-md-8\"><div [ngbNavOutlet]=\"nav\"></div></div>\r\n </ng-container>\r\n\r\n <div class=\"col\" *ngIf=\"!groups.length\">\r\n {{ 'AbpFeatureManagement::NoFeatureFoundMessage' | abpLocalization }}\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #abpFooter>\r\n <abp-button\r\n *ngIf=\"groups.length\"\r\n iconClass=\"fa fa-refresh\"\r\n [disabled]=\"modalBusy\"\r\n (click)=\"resetToDefault()\"\r\n >\r\n {{ 'AbpFeatureManagement::ResetToDefault' | abpLocalization }}\r\n </abp-button>\r\n\r\n <button abpClose type=\"button\" class=\"btn btn-secondary\">\r\n {{ 'AbpFeatureManagement::Cancel' | abpLocalization }}\r\n </button>\r\n <abp-button\r\n *ngIf=\"groups.length\"\r\n iconClass=\"fa fa-check\"\r\n [disabled]=\"modalBusy\"\r\n (click)=\"save()\"\r\n >\r\n {{ 'AbpFeatureManagement::Save' | abpLocalization }}\r\n </abp-button>\r\n </ng-template>\r\n</abp-modal>\r\n", dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i4.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i4.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i4.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.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: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.ButtonComponent, selector: "abp-button", inputs: ["buttonId", "buttonClass", "buttonType", "formName", "iconClass", "loading", "disabled", "attributes"], outputs: ["click", "focus", "blur", "abpClick", "abpFocus", "abpBlur"] }, { kind: "component", type: i2.ModalComponent, selector: "abp-modal", inputs: ["visible", "busy", "options", "suppressUnsavedChangesWarning"], outputs: ["visibleChange", "init", "appear", "disappear"] }, { kind: "directive", type: i2.ModalCloseDirective, selector: "[abpClose]" }, { kind: "directive", type: i6.NgbNavContent, selector: "ng-template[ngbNavContent]" }, { kind: "directive", type: i6.NgbNav, selector: "[ngbNav]", inputs: ["activeId", "animation", "destroyOnHide", "orientation", "roles", "keyboard"], outputs: ["activeIdChange", "shown", "hidden", "navChange"], exportAs: ["ngbNav"] }, { kind: "directive", type: i6.NgbNavItem, selector: "[ngbNavItem]", inputs: ["destroyOnHide", "disabled", "domId", "ngbNavItem"], outputs: ["shown", "hidden"], exportAs: ["ngbNavItem"] }, { kind: "directive", type: i6.NgbNavItemRole, selector: "[ngbNavItem]:not(ng-container)" }, { kind: "directive", type: i6.NgbNavLink, selector: "a[ngbNavLink]" }, { kind: "directive", type: i6.NgbNavLinkBase, selector: "[ngbNavLink]" }, { kind: "component", type: i6.NgbNavOutlet, selector: "[ngbNavOutlet]", inputs: ["paneRole", "ngbNavOutlet"] }, { kind: "directive", type: FreeTextInputDirective, selector: "input[abpFeatureManagementFreeText]", inputs: ["abpFeatureManagementFreeText"], exportAs: ["inputAbpFeatureManagementFreeText"] }, { kind: "pipe", type: i1.LocalizationPipe, name: "abpLocalization" }] });
187
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: FeatureManagementComponent, decorators: [{
188
- type: Component,
189
- args: [{ selector: 'abp-feature-management', exportAs: 'abpFeatureManagement', template: "<abp-modal *ngIf=\"visible\" [(visible)]=\"visible\" [busy]=\"modalBusy\" [options]=\"{ size: 'lg' }\">\r\n <ng-template #abpHeader>\r\n <h3>{{ 'AbpFeatureManagement::Features' | abpLocalization }}</h3>\r\n </ng-template>\r\n\r\n <ng-template #abpBody>\r\n <div class=\"row\">\r\n <ng-container *ngIf=\"groups.length\">\r\n <div class=\"col-md-4\">\r\n <ul\r\n ngbNav\r\n #nav=\"ngbNav\"\r\n [(activeId)]=\"selectedGroupDisplayName\"\r\n class=\"nav-pills\"\r\n orientation=\"vertical\"\r\n >\r\n <li\r\n *ngFor=\"let group of groups; trackBy: track.by('name')\"\r\n [ngbNavItem]=\"group.displayName\"\r\n >\r\n <a ngbNavLink>{{ group.displayName }}</a>\r\n <ng-template ngbNavContent>\r\n <h4>{{ selectedGroupDisplayName }}</h4>\r\n <hr class=\"mt-2 mb-3\" />\r\n\r\n <div\r\n class=\"mt-2\"\r\n *ngFor=\"\r\n let feature of features[group.name];\r\n let i = index;\r\n trackBy: track.by('id')\r\n \"\r\n [ngStyle]=\"feature.style\"\r\n [ngSwitch]=\"feature.valueType?.name\"\r\n (keyup.enter)=\"save()\"\r\n >\r\n <ng-container *ngSwitchCase=\"valueTypes.ToggleStringValueType\">\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"feature.name\"\r\n [(ngModel)]=\"feature.value\"\r\n (ngModelChange)=\"onCheckboxClick($event, feature)\"\r\n />\r\n\r\n <label class=\"form-check-label\" [htmlFor]=\"feature.name\">{{\r\n feature.displayName\r\n }}</label>\r\n <ng-container\r\n *ngTemplateOutlet=\"descTmp; context: { $implicit: feature.description }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"valueTypes.FreeTextStringValueType\">\r\n <div class=\"mb-3 form-group\">\r\n <label [htmlFor]=\"feature.name\" class=\"form-label\">{{\r\n feature.displayName\r\n }}</label>\r\n <input\r\n class=\"form-control\"\r\n type=\"text\"\r\n [id]=\"feature.name\"\r\n [(ngModel)]=\"feature.value\"\r\n [abpFeatureManagementFreeText]=\"feature\"\r\n />\r\n\r\n <ng-container\r\n *ngTemplateOutlet=\"descTmp; context: { $implicit: feature.description }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"valueTypes.SelectionStringValueType\">\r\n <ng-container *ngIf=\"feature.valueType.itemSource?.items?.length\">\r\n <div class=\"mb-3 form-group\">\r\n <label [htmlFor]=\"feature.name\" class=\"form-label\">{{\r\n feature.displayName\r\n }}</label>\r\n <select class=\"form-select\" [id]=\"feature.name\" [(ngModel)]=\"feature.value\">\r\n <option\r\n *ngFor=\"\r\n let item of feature.valueType.itemSource?.items;\r\n trackBy: track.by('value')\r\n \"\r\n [ngValue]=\"item.value\"\r\n >\r\n {{\r\n item.displayText?.resourceName + '::' + item.displayText?.name\r\n | abpLocalization\r\n }}\r\n </option>\r\n </select>\r\n <ng-container\r\n *ngTemplateOutlet=\"descTmp; context: { $implicit: feature.description }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchDefault>{{ feature.displayName }}</ng-container>\r\n </div>\r\n </ng-template>\r\n </li>\r\n </ul>\r\n </div>\r\n\r\n <ng-template #descTmp let-description>\r\n <small *ngIf=\"description\" class=\"d-block form-text text-muted\">{{ description }}</small>\r\n </ng-template>\r\n\r\n <div class=\"col-md-8\"><div [ngbNavOutlet]=\"nav\"></div></div>\r\n </ng-container>\r\n\r\n <div class=\"col\" *ngIf=\"!groups.length\">\r\n {{ 'AbpFeatureManagement::NoFeatureFoundMessage' | abpLocalization }}\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #abpFooter>\r\n <abp-button\r\n *ngIf=\"groups.length\"\r\n iconClass=\"fa fa-refresh\"\r\n [disabled]=\"modalBusy\"\r\n (click)=\"resetToDefault()\"\r\n >\r\n {{ 'AbpFeatureManagement::ResetToDefault' | abpLocalization }}\r\n </abp-button>\r\n\r\n <button abpClose type=\"button\" class=\"btn btn-secondary\">\r\n {{ 'AbpFeatureManagement::Cancel' | abpLocalization }}\r\n </button>\r\n <abp-button\r\n *ngIf=\"groups.length\"\r\n iconClass=\"fa fa-check\"\r\n [disabled]=\"modalBusy\"\r\n (click)=\"save()\"\r\n >\r\n {{ 'AbpFeatureManagement::Save' | abpLocalization }}\r\n </abp-button>\r\n </ng-template>\r\n</abp-modal>\r\n" }]
190
- }], ctorParameters: function () { return [{ type: i1.TrackByService }, { type: i2.ToasterService }, { type: i3.FeaturesService }, { type: i1.ConfigStateService }, { type: i2.ConfirmationService }]; }, propDecorators: { providerKey: [{
191
- type: Input
192
- }], providerName: [{
193
- type: Input
194
- }], visible: [{
195
- type: Input
196
- }], visibleChange: [{
197
- type: Output
198
- }] } });
199
- function mapFeatures(features, dir) {
200
- const margin = `margin-${dir === 'rtl' ? 'right' : 'left'}.px`;
201
- return features.map(feature => {
202
- const value = feature.valueType?.name === ValueTypes.ToggleStringValueType
203
- ? (feature.value || '').toLowerCase() === 'true'
204
- : feature.value;
205
- return {
206
- ...feature,
207
- value,
208
- initialValue: value,
209
- style: { [margin]: feature.depth * 20 },
210
- };
211
- });
49
+ var ValueTypes;
50
+ (function (ValueTypes) {
51
+ ValueTypes["ToggleStringValueType"] = "ToggleStringValueType";
52
+ ValueTypes["FreeTextStringValueType"] = "FreeTextStringValueType";
53
+ ValueTypes["SelectionStringValueType"] = "SelectionStringValueType";
54
+ })(ValueTypes || (ValueTypes = {}));
55
+ class FeatureManagementComponent {
56
+ get visible() {
57
+ return this._visible;
58
+ }
59
+ set visible(value) {
60
+ if (this._visible === value)
61
+ return;
62
+ this._visible = value;
63
+ this.visibleChange.emit(value);
64
+ if (value)
65
+ this.openModal();
66
+ }
67
+ constructor(track, toasterService, service, configState, confirmationService) {
68
+ this.track = track;
69
+ this.toasterService = toasterService;
70
+ this.service = service;
71
+ this.configState = configState;
72
+ this.confirmationService = confirmationService;
73
+ this.groups = [];
74
+ this.valueTypes = ValueTypes;
75
+ this.visibleChange = new EventEmitter();
76
+ this.modalBusy = false;
77
+ }
78
+ openModal() {
79
+ if (!this.providerName) {
80
+ throw new Error('providerName is required.');
81
+ }
82
+ this.getFeatures();
83
+ }
84
+ getFeatures() {
85
+ this.service.get(this.providerName, this.providerKey).subscribe(res => {
86
+ if (!res.groups?.length)
87
+ return;
88
+ this.groups = res.groups.map(({ name, displayName }) => ({ name, displayName }));
89
+ this.selectedGroupDisplayName = this.groups[0].displayName;
90
+ this.features = res.groups.reduce((acc, val) => ({
91
+ ...acc,
92
+ [val.name]: mapFeatures(val.features, document.body.dir),
93
+ }), {});
94
+ });
95
+ }
96
+ save() {
97
+ if (this.modalBusy)
98
+ return;
99
+ const changedFeatures = [];
100
+ Object.keys(this.features).forEach(key => {
101
+ this.features[key].forEach(feature => {
102
+ if (feature.value !== feature.initialValue)
103
+ changedFeatures.push({ name: feature.name, value: `${feature.value}` });
104
+ });
105
+ });
106
+ if (!changedFeatures.length) {
107
+ this.visible = false;
108
+ return;
109
+ }
110
+ this.modalBusy = true;
111
+ this.service
112
+ .update(this.providerName, this.providerKey, { features: changedFeatures })
113
+ .pipe(finalize(() => (this.modalBusy = false)))
114
+ .subscribe(() => {
115
+ this.visible = false;
116
+ if (!this.providerKey) {
117
+ // to refresh host's features
118
+ this.configState.refreshAppState().subscribe();
119
+ }
120
+ });
121
+ }
122
+ resetToDefault() {
123
+ this.confirmationService
124
+ .warn('AbpFeatureManagement::AreYouSureToResetToDefault', 'AbpFeatureManagement::AreYouSure')
125
+ .subscribe((status) => {
126
+ if (status === Confirmation.Status.confirm) {
127
+ this.service.delete(this.providerName, this.providerKey).subscribe(() => {
128
+ this.toasterService.success('AbpFeatureManagement::ResetedToDefault');
129
+ this.visible = false;
130
+ if (!this.providerKey) {
131
+ // to refresh host's features
132
+ this.configState.refreshAppState().subscribe();
133
+ }
134
+ });
135
+ }
136
+ });
137
+ }
138
+ onCheckboxClick(val, feature) {
139
+ if (val) {
140
+ this.checkToggleAncestors(feature);
141
+ }
142
+ else {
143
+ this.uncheckToggleDescendants(feature);
144
+ }
145
+ }
146
+ uncheckToggleDescendants(feature) {
147
+ this.findAllDescendantsOfByType(feature, ValueTypes.ToggleStringValueType).forEach(node => this.setFeatureValue(node, false));
148
+ }
149
+ checkToggleAncestors(feature) {
150
+ this.findAllAncestorsOfByType(feature, ValueTypes.ToggleStringValueType).forEach(node => this.setFeatureValue(node, true));
151
+ }
152
+ findAllAncestorsOfByType(feature, type) {
153
+ let parent = this.findParentByType(feature, type);
154
+ const ancestors = [];
155
+ while (parent) {
156
+ ancestors.push(parent);
157
+ parent = this.findParentByType(parent, type);
158
+ }
159
+ return ancestors;
160
+ }
161
+ findAllDescendantsOfByType(feature, type) {
162
+ const descendants = [];
163
+ const queue = [feature];
164
+ while (queue.length) {
165
+ const node = queue.pop();
166
+ const newDescendants = this.findChildrenByType(node, type);
167
+ descendants.push(...newDescendants);
168
+ queue.push(...newDescendants);
169
+ }
170
+ return descendants;
171
+ }
172
+ findParentByType(feature, type) {
173
+ return this.getCurrentGroup().find(f => f.valueType.name === type && f.name === feature.parentName);
174
+ }
175
+ findChildrenByType(feature, type) {
176
+ return this.getCurrentGroup().filter(f => f.valueType.name === type && f.parentName === feature.name);
177
+ }
178
+ getCurrentGroup() {
179
+ return this.features[this.selectedGroupDisplayName] ?? [];
180
+ }
181
+ setFeatureValue(feature, val) {
182
+ feature.value = val;
183
+ }
184
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FeatureManagementComponent, deps: [{ token: i1.TrackByService }, { token: i2.ToasterService }, { token: i3.FeaturesService }, { token: i1.ConfigStateService }, { token: i2.ConfirmationService }], target: i0.ɵɵFactoryTarget.Component }); }
185
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: FeatureManagementComponent, selector: "abp-feature-management", inputs: { providerKey: "providerKey", providerName: "providerName", visible: "visible" }, outputs: { visibleChange: "visibleChange" }, exportAs: ["abpFeatureManagement"], ngImport: i0, template: "<abp-modal *ngIf=\"visible\" [(visible)]=\"visible\" [busy]=\"modalBusy\" [options]=\"{ size: 'lg' }\">\r\n <ng-template #abpHeader>\r\n <h3>{{ 'AbpFeatureManagement::Features' | abpLocalization }}</h3>\r\n </ng-template>\r\n\r\n <ng-template #abpBody>\r\n <div class=\"row\">\r\n <ng-container *ngIf=\"groups.length\">\r\n <div class=\"col-md-4\">\r\n <ul\r\n ngbNav\r\n #nav=\"ngbNav\"\r\n [(activeId)]=\"selectedGroupDisplayName\"\r\n class=\"nav-pills\"\r\n orientation=\"vertical\"\r\n >\r\n <li\r\n *ngFor=\"let group of groups; trackBy: track.by('name')\"\r\n [ngbNavItem]=\"group.displayName\"\r\n >\r\n <a ngbNavLink>{{ group.displayName }}</a>\r\n <ng-template ngbNavContent>\r\n <h4>{{ selectedGroupDisplayName }}</h4>\r\n <hr class=\"mt-2 mb-3\" />\r\n\r\n <div\r\n class=\"mt-2\"\r\n *ngFor=\"\r\n let feature of features[group.name];\r\n let i = index;\r\n trackBy: track.by('id')\r\n \"\r\n [ngStyle]=\"feature.style\"\r\n [ngSwitch]=\"feature.valueType?.name\"\r\n (keyup.enter)=\"save()\"\r\n >\r\n <ng-container *ngSwitchCase=\"valueTypes.ToggleStringValueType\">\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"feature.name\"\r\n [(ngModel)]=\"feature.value\"\r\n (ngModelChange)=\"onCheckboxClick($event, feature)\"\r\n />\r\n\r\n <label class=\"form-check-label\" [htmlFor]=\"feature.name\">{{\r\n feature.displayName\r\n }}</label>\r\n <ng-container\r\n *ngTemplateOutlet=\"descTmp; context: { $implicit: feature.description }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"valueTypes.FreeTextStringValueType\">\r\n <div class=\"mb-3 form-group\">\r\n <label [htmlFor]=\"feature.name\" class=\"form-label\">{{\r\n feature.displayName\r\n }}</label>\r\n <input\r\n class=\"form-control\"\r\n type=\"text\"\r\n [id]=\"feature.name\"\r\n [(ngModel)]=\"feature.value\"\r\n [abpFeatureManagementFreeText]=\"feature\"\r\n />\r\n\r\n <ng-container\r\n *ngTemplateOutlet=\"descTmp; context: { $implicit: feature.description }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"valueTypes.SelectionStringValueType\">\r\n <ng-container *ngIf=\"feature.valueType.itemSource?.items?.length\">\r\n <div class=\"mb-3 form-group\">\r\n <label [htmlFor]=\"feature.name\" class=\"form-label\">{{\r\n feature.displayName\r\n }}</label>\r\n <select class=\"form-select\" [id]=\"feature.name\" [(ngModel)]=\"feature.value\">\r\n <option\r\n *ngFor=\"\r\n let item of feature.valueType.itemSource?.items;\r\n trackBy: track.by('value')\r\n \"\r\n [ngValue]=\"item.value\"\r\n >\r\n {{\r\n item.displayText?.resourceName + '::' + item.displayText?.name\r\n | abpLocalization\r\n }}\r\n </option>\r\n </select>\r\n <ng-container\r\n *ngTemplateOutlet=\"descTmp; context: { $implicit: feature.description }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchDefault>{{ feature.displayName }}</ng-container>\r\n </div>\r\n </ng-template>\r\n </li>\r\n </ul>\r\n </div>\r\n\r\n <ng-template #descTmp let-description>\r\n <small *ngIf=\"description\" class=\"d-block form-text text-muted\">{{ description }}</small>\r\n </ng-template>\r\n\r\n <div class=\"col-md-8\"><div [ngbNavOutlet]=\"nav\"></div></div>\r\n </ng-container>\r\n\r\n <div class=\"col\" *ngIf=\"!groups.length\">\r\n {{ 'AbpFeatureManagement::NoFeatureFoundMessage' | abpLocalization }}\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #abpFooter>\r\n <abp-button\r\n *ngIf=\"groups.length\"\r\n iconClass=\"fa fa-refresh\"\r\n [disabled]=\"modalBusy\"\r\n (click)=\"resetToDefault()\"\r\n aria-hidden=\"true\"\r\n >\r\n {{ 'AbpFeatureManagement::ResetToDefault' | abpLocalization }}\r\n </abp-button>\r\n\r\n <button abpClose type=\"button\" class=\"btn btn-secondary\">\r\n {{ 'AbpFeatureManagement::Cancel' | abpLocalization }}\r\n </button>\r\n <abp-button\r\n *ngIf=\"groups.length\"\r\n iconClass=\"fa fa-check\"\r\n [disabled]=\"modalBusy\"\r\n (click)=\"save()\"\r\n aria-hidden=\"true\"\r\n >\r\n {{ 'AbpFeatureManagement::Save' | abpLocalization }}\r\n </abp-button>\r\n </ng-template>\r\n</abp-modal>\r\n", dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i4.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i4.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i4.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.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: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.ButtonComponent, selector: "abp-button", inputs: ["buttonId", "buttonClass", "buttonType", "formName", "iconClass", "loading", "disabled", "attributes"], outputs: ["click", "focus", "blur", "abpClick", "abpFocus", "abpBlur"] }, { kind: "component", type: i2.ModalComponent, selector: "abp-modal", inputs: ["visible", "busy", "options", "suppressUnsavedChangesWarning"], outputs: ["visibleChange", "init", "appear", "disappear"] }, { kind: "directive", type: i2.ModalCloseDirective, selector: "[abpClose]" }, { kind: "directive", type: i6.NgbNavContent, selector: "ng-template[ngbNavContent]" }, { kind: "directive", type: i6.NgbNav, selector: "[ngbNav]", inputs: ["activeId", "animation", "destroyOnHide", "orientation", "roles", "keyboard"], outputs: ["activeIdChange", "shown", "hidden", "navChange"], exportAs: ["ngbNav"] }, { kind: "directive", type: i6.NgbNavItem, selector: "[ngbNavItem]", inputs: ["destroyOnHide", "disabled", "domId", "ngbNavItem"], outputs: ["shown", "hidden"], exportAs: ["ngbNavItem"] }, { kind: "directive", type: i6.NgbNavItemRole, selector: "[ngbNavItem]:not(ng-container)" }, { kind: "directive", type: i6.NgbNavLink, selector: "a[ngbNavLink]" }, { kind: "directive", type: i6.NgbNavLinkBase, selector: "[ngbNavLink]" }, { kind: "component", type: i6.NgbNavOutlet, selector: "[ngbNavOutlet]", inputs: ["paneRole", "ngbNavOutlet"] }, { kind: "directive", type: FreeTextInputDirective, selector: "input[abpFeatureManagementFreeText]", inputs: ["abpFeatureManagementFreeText"], exportAs: ["inputAbpFeatureManagementFreeText"] }, { kind: "pipe", type: i1.LocalizationPipe, name: "abpLocalization" }] }); }
186
+ }
187
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FeatureManagementComponent, decorators: [{
188
+ type: Component,
189
+ args: [{ selector: 'abp-feature-management', exportAs: 'abpFeatureManagement', template: "<abp-modal *ngIf=\"visible\" [(visible)]=\"visible\" [busy]=\"modalBusy\" [options]=\"{ size: 'lg' }\">\r\n <ng-template #abpHeader>\r\n <h3>{{ 'AbpFeatureManagement::Features' | abpLocalization }}</h3>\r\n </ng-template>\r\n\r\n <ng-template #abpBody>\r\n <div class=\"row\">\r\n <ng-container *ngIf=\"groups.length\">\r\n <div class=\"col-md-4\">\r\n <ul\r\n ngbNav\r\n #nav=\"ngbNav\"\r\n [(activeId)]=\"selectedGroupDisplayName\"\r\n class=\"nav-pills\"\r\n orientation=\"vertical\"\r\n >\r\n <li\r\n *ngFor=\"let group of groups; trackBy: track.by('name')\"\r\n [ngbNavItem]=\"group.displayName\"\r\n >\r\n <a ngbNavLink>{{ group.displayName }}</a>\r\n <ng-template ngbNavContent>\r\n <h4>{{ selectedGroupDisplayName }}</h4>\r\n <hr class=\"mt-2 mb-3\" />\r\n\r\n <div\r\n class=\"mt-2\"\r\n *ngFor=\"\r\n let feature of features[group.name];\r\n let i = index;\r\n trackBy: track.by('id')\r\n \"\r\n [ngStyle]=\"feature.style\"\r\n [ngSwitch]=\"feature.valueType?.name\"\r\n (keyup.enter)=\"save()\"\r\n >\r\n <ng-container *ngSwitchCase=\"valueTypes.ToggleStringValueType\">\r\n <div class=\"form-check\">\r\n <input\r\n class=\"form-check-input\"\r\n type=\"checkbox\"\r\n [id]=\"feature.name\"\r\n [(ngModel)]=\"feature.value\"\r\n (ngModelChange)=\"onCheckboxClick($event, feature)\"\r\n />\r\n\r\n <label class=\"form-check-label\" [htmlFor]=\"feature.name\">{{\r\n feature.displayName\r\n }}</label>\r\n <ng-container\r\n *ngTemplateOutlet=\"descTmp; context: { $implicit: feature.description }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"valueTypes.FreeTextStringValueType\">\r\n <div class=\"mb-3 form-group\">\r\n <label [htmlFor]=\"feature.name\" class=\"form-label\">{{\r\n feature.displayName\r\n }}</label>\r\n <input\r\n class=\"form-control\"\r\n type=\"text\"\r\n [id]=\"feature.name\"\r\n [(ngModel)]=\"feature.value\"\r\n [abpFeatureManagementFreeText]=\"feature\"\r\n />\r\n\r\n <ng-container\r\n *ngTemplateOutlet=\"descTmp; context: { $implicit: feature.description }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"valueTypes.SelectionStringValueType\">\r\n <ng-container *ngIf=\"feature.valueType.itemSource?.items?.length\">\r\n <div class=\"mb-3 form-group\">\r\n <label [htmlFor]=\"feature.name\" class=\"form-label\">{{\r\n feature.displayName\r\n }}</label>\r\n <select class=\"form-select\" [id]=\"feature.name\" [(ngModel)]=\"feature.value\">\r\n <option\r\n *ngFor=\"\r\n let item of feature.valueType.itemSource?.items;\r\n trackBy: track.by('value')\r\n \"\r\n [ngValue]=\"item.value\"\r\n >\r\n {{\r\n item.displayText?.resourceName + '::' + item.displayText?.name\r\n | abpLocalization\r\n }}\r\n </option>\r\n </select>\r\n <ng-container\r\n *ngTemplateOutlet=\"descTmp; context: { $implicit: feature.description }\"\r\n ></ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchDefault>{{ feature.displayName }}</ng-container>\r\n </div>\r\n </ng-template>\r\n </li>\r\n </ul>\r\n </div>\r\n\r\n <ng-template #descTmp let-description>\r\n <small *ngIf=\"description\" class=\"d-block form-text text-muted\">{{ description }}</small>\r\n </ng-template>\r\n\r\n <div class=\"col-md-8\"><div [ngbNavOutlet]=\"nav\"></div></div>\r\n </ng-container>\r\n\r\n <div class=\"col\" *ngIf=\"!groups.length\">\r\n {{ 'AbpFeatureManagement::NoFeatureFoundMessage' | abpLocalization }}\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template #abpFooter>\r\n <abp-button\r\n *ngIf=\"groups.length\"\r\n iconClass=\"fa fa-refresh\"\r\n [disabled]=\"modalBusy\"\r\n (click)=\"resetToDefault()\"\r\n aria-hidden=\"true\"\r\n >\r\n {{ 'AbpFeatureManagement::ResetToDefault' | abpLocalization }}\r\n </abp-button>\r\n\r\n <button abpClose type=\"button\" class=\"btn btn-secondary\">\r\n {{ 'AbpFeatureManagement::Cancel' | abpLocalization }}\r\n </button>\r\n <abp-button\r\n *ngIf=\"groups.length\"\r\n iconClass=\"fa fa-check\"\r\n [disabled]=\"modalBusy\"\r\n (click)=\"save()\"\r\n aria-hidden=\"true\"\r\n >\r\n {{ 'AbpFeatureManagement::Save' | abpLocalization }}\r\n </abp-button>\r\n </ng-template>\r\n</abp-modal>\r\n" }]
190
+ }], ctorParameters: function () { return [{ type: i1.TrackByService }, { type: i2.ToasterService }, { type: i3.FeaturesService }, { type: i1.ConfigStateService }, { type: i2.ConfirmationService }]; }, propDecorators: { providerKey: [{
191
+ type: Input
192
+ }], providerName: [{
193
+ type: Input
194
+ }], visible: [{
195
+ type: Input
196
+ }], visibleChange: [{
197
+ type: Output
198
+ }] } });
199
+ function mapFeatures(features, dir) {
200
+ const margin = `margin-${dir === 'rtl' ? 'right' : 'left'}.px`;
201
+ return features.map(feature => {
202
+ const value = feature.valueType?.name === ValueTypes.ToggleStringValueType
203
+ ? (feature.value || '').toLowerCase() === 'true'
204
+ : feature.value;
205
+ return {
206
+ ...feature,
207
+ value,
208
+ initialValue: value,
209
+ style: { [margin]: feature.depth * 20 },
210
+ };
211
+ });
212
212
  }
213
213
 
214
- class FeatureManagementTabComponent {
215
- constructor() {
216
- this.visibleFeatures = false;
217
- this.onVisibleFeaturesChange = (value) => {
218
- this.visibleFeatures = value;
219
- };
220
- }
221
- openFeaturesModal() {
222
- setTimeout(() => {
223
- this.visibleFeatures = true;
224
- }, 0);
225
- }
226
- }
227
- FeatureManagementTabComponentfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: FeatureManagementTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
228
- FeatureManagementTabComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: FeatureManagementTabComponent, selector: "abp-feature-management-tab", ngImport: i0, template: "<p class=\"text-wrap\">{{ 'AbpFeatureManagement::ManageHostFeaturesText' | abpLocalization }}</p>\r\n\r\n<button class=\"btn btn-primary\" type=\"button\" (click)=\"openFeaturesModal()\">\r\n <i class=\"fa fa-cog\"></i>\r\n {{ 'AbpFeatureManagement::ManageHostFeatures' | abpLocalization }}\r\n</button>\r\n<abp-feature-management\r\n *abpReplaceableTemplate=\"{\r\n inputs: {\r\n providerName: { value: 'T' },\r\n providerKey: { value: providerKey },\r\n visible: { value: visibleFeatures, twoWay: true }\r\n },\r\n outputs: { visibleChange: onVisibleFeaturesChange },\r\n componentKey: 'FeatureManagement.FeatureManagementComponent'\r\n }\"\r\n [(visible)]=\"visibleFeatures\"\r\n providerName=\"T\"\r\n [providerKey]=\"providerKey\"\r\n>\r\n</abp-feature-management>\r\n", dependencies: [{ kind: "directive", type: i1.ReplaceableTemplateDirective, selector: "[abpReplaceableTemplate]", inputs: ["abpReplaceableTemplate"] }, { kind: "component", type: FeatureManagementComponent, selector: "abp-feature-management", inputs: ["providerKey", "providerName", "visible"], outputs: ["visibleChange"], exportAs: ["abpFeatureManagement"] }, { kind: "pipe", type: i1.LocalizationPipe, name: "abpLocalization" }] });
229
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: FeatureManagementTabComponent, decorators: [{
230
- type: Component,
231
- args: [{ selector: 'abp-feature-management-tab', template: "<p class=\"text-wrap\">{{ 'AbpFeatureManagement::ManageHostFeaturesText' | abpLocalization }}</p>\r\n\r\n<button class=\"btn btn-primary\" type=\"button\" (click)=\"openFeaturesModal()\">\r\n <i class=\"fa fa-cog\"></i>\r\n {{ 'AbpFeatureManagement::ManageHostFeatures' | abpLocalization }}\r\n</button>\r\n<abp-feature-management\r\n *abpReplaceableTemplate=\"{\r\n inputs: {\r\n providerName: { value: 'T' },\r\n providerKey: { value: providerKey },\r\n visible: { value: visibleFeatures, twoWay: true }\r\n },\r\n outputs: { visibleChange: onVisibleFeaturesChange },\r\n componentKey: 'FeatureManagement.FeatureManagementComponent'\r\n }\"\r\n [(visible)]=\"visibleFeatures\"\r\n providerName=\"T\"\r\n [providerKey]=\"providerKey\"\r\n>\r\n</abp-feature-management>\r\n" }]
214
+ class FeatureManagementTabComponent {
215
+ constructor() {
216
+ this.visibleFeatures = false;
217
+ this.onVisibleFeaturesChange = (value) => {
218
+ this.visibleFeatures = value;
219
+ };
220
+ }
221
+ openFeaturesModal() {
222
+ setTimeout(() => {
223
+ this.visibleFeatures = true;
224
+ }, 0);
225
+ }
226
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FeatureManagementTabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
227
+ static { thiscmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: FeatureManagementTabComponent, selector: "abp-feature-management-tab", ngImport: i0, template: "<p class=\"text-wrap\">{{ 'AbpFeatureManagement::ManageHostFeaturesText' | abpLocalization }}</p>\r\n\r\n<button class=\"btn btn-primary\" type=\"button\" (click)=\"openFeaturesModal()\">\r\n <i class=\"fa fa-cog\" aria-hidden=\"true\"></i>\r\n {{ 'AbpFeatureManagement::ManageHostFeatures' | abpLocalization }}\r\n</button>\r\n<abp-feature-management\r\n *abpReplaceableTemplate=\"{\r\n inputs: {\r\n providerName: { value: 'T' },\r\n providerKey: { value: providerKey },\r\n visible: { value: visibleFeatures, twoWay: true }\r\n },\r\n outputs: { visibleChange: onVisibleFeaturesChange },\r\n componentKey: 'FeatureManagement.FeatureManagementComponent'\r\n }\"\r\n [(visible)]=\"visibleFeatures\"\r\n providerName=\"T\"\r\n [providerKey]=\"providerKey\"\r\n>\r\n</abp-feature-management>\r\n", dependencies: [{ kind: "directive", type: i1.ReplaceableTemplateDirective, selector: "[abpReplaceableTemplate]", inputs: ["abpReplaceableTemplate"] }, { kind: "component", type: FeatureManagementComponent, selector: "abp-feature-management", inputs: ["providerKey", "providerName", "visible"], outputs: ["visibleChange"], exportAs: ["abpFeatureManagement"] }, { kind: "pipe", type: i1.LocalizationPipe, name: "abpLocalization" }] }); }
228
+ }
229
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FeatureManagementTabComponent, decorators: [{
230
+ type: Component,
231
+ args: [{ selector: 'abp-feature-management-tab', template: "<p class=\"text-wrap\">{{ 'AbpFeatureManagement::ManageHostFeaturesText' | abpLocalization }}</p>\r\n\r\n<button class=\"btn btn-primary\" type=\"button\" (click)=\"openFeaturesModal()\">\r\n <i class=\"fa fa-cog\" aria-hidden=\"true\"></i>\r\n {{ 'AbpFeatureManagement::ManageHostFeatures' | abpLocalization }}\r\n</button>\r\n<abp-feature-management\r\n *abpReplaceableTemplate=\"{\r\n inputs: {\r\n providerName: { value: 'T' },\r\n providerKey: { value: providerKey },\r\n visible: { value: visibleFeatures, twoWay: true }\r\n },\r\n outputs: { visibleChange: onVisibleFeaturesChange },\r\n componentKey: 'FeatureManagement.FeatureManagementComponent'\r\n }\"\r\n [(visible)]=\"visibleFeatures\"\r\n providerName=\"T\"\r\n [providerKey]=\"providerKey\"\r\n>\r\n</abp-feature-management>\r\n" }]
232
232
  }] });
233
233
 
234
- const FEATURE_MANAGEMENT_SETTINGS_PROVIDERS = [
235
- {
236
- provide: APP_INITIALIZER,
237
- useFactory: configureSettingTabs,
238
- deps: [SettingTabsService],
239
- multi: true,
240
- },
241
- ];
242
- function configureSettingTabs(settingtabs) {
243
- return () => {
244
- settingtabs.add([
245
- {
246
- name: "AbpFeatureManagement::Permission:FeatureManagement" /* eFeatureManagementTabNames.FeatureManagement */,
247
- order: 104,
248
- requiredPolicy: 'FeatureManagement.ManageHostFeatures',
249
- component: FeatureManagementTabComponent,
250
- },
251
- ]);
252
- };
234
+ const FEATURE_MANAGEMENT_SETTINGS_PROVIDERS = [
235
+ {
236
+ provide: APP_INITIALIZER,
237
+ useFactory: configureSettingTabs,
238
+ deps: [SettingTabsService],
239
+ multi: true,
240
+ },
241
+ ];
242
+ function configureSettingTabs(settingtabs) {
243
+ return () => {
244
+ settingtabs.add([
245
+ {
246
+ name: "AbpFeatureManagement::Permission:FeatureManagement" /* eFeatureManagementTabNames.FeatureManagement */,
247
+ order: 104,
248
+ requiredPolicy: 'FeatureManagement.ManageHostFeatures',
249
+ component: FeatureManagementTabComponent,
250
+ },
251
+ ]);
252
+ };
253
253
  }
254
254
 
255
- const exported = [
256
- FeatureManagementComponent,
257
- FreeTextInputDirective,
258
- FeatureManagementTabComponent,
259
- ];
260
- class FeatureManagementModule {
261
- static forRoot() {
262
- return {
263
- ngModule: FeatureManagementModule,
264
- providers: [FEATURE_MANAGEMENT_SETTINGS_PROVIDERS],
265
- };
266
- }
267
- }
268
- FeatureManagementModulefac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: FeatureManagementModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
269
- FeatureManagementModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.4", ngImport: i0, type: FeatureManagementModule, declarations: [FeatureManagementComponent,
270
- FreeTextInputDirective,
271
- FeatureManagementTabComponent], imports: [CoreModule, ThemeSharedModule, NgbNavModule], exports: [FeatureManagementComponent,
272
- FreeTextInputDirective,
273
- FeatureManagementTabComponent] });
274
- FeatureManagementModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: FeatureManagementModule, imports: [CoreModule, ThemeSharedModule, NgbNavModule] });
275
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: FeatureManagementModule, decorators: [{
276
- type: NgModule,
277
- args: [{
278
- declarations: [...exported],
279
- imports: [CoreModule, ThemeSharedModule, NgbNavModule],
280
- exports: [...exported],
281
- }]
255
+ const exported = [
256
+ FeatureManagementComponent,
257
+ FreeTextInputDirective,
258
+ FeatureManagementTabComponent,
259
+ ];
260
+ class FeatureManagementModule {
261
+ static forRoot() {
262
+ return {
263
+ ngModule: FeatureManagementModule,
264
+ providers: [FEATURE_MANAGEMENT_SETTINGS_PROVIDERS],
265
+ };
266
+ }
267
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FeatureManagementModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
268
+ static { thismod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.0.1", ngImport: i0, type: FeatureManagementModule, declarations: [FeatureManagementComponent,
269
+ FreeTextInputDirective,
270
+ FeatureManagementTabComponent], imports: [CoreModule, ThemeSharedModule, NgbNavModule], exports: [FeatureManagementComponent,
271
+ FreeTextInputDirective,
272
+ FeatureManagementTabComponent] }); }
273
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FeatureManagementModule, imports: [CoreModule, ThemeSharedModule, NgbNavModule] }); }
274
+ }
275
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: FeatureManagementModule, decorators: [{
276
+ type: NgModule,
277
+ args: [{
278
+ declarations: [...exported],
279
+ imports: [CoreModule, ThemeSharedModule, NgbNavModule],
280
+ exports: [...exported],
281
+ }]
282
282
  }] });
283
283
 
284
- /**
285
- * Generated bundle index. Do not edit.
284
+ /**
285
+ * Generated bundle index. Do not edit.
286
286
  */
287
287
 
288
288
  export { FEATURE_MANAGEMENT_SETTINGS_PROVIDERS, FeatureManagementComponent, FeatureManagementModule, FeatureManagementTabComponent, FreeTextInputDirective, INPUT_TYPES, configureSettingTabs };