diff --git a/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.html b/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.html index 6ee1766db7..cceef3409c 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.html +++ b/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.html @@ -1,35 +1,107 @@ - +

{{ 'AbpFeatureManagement::Features' | abpLocalization }}

-
-
-
{{ feature.displayName }}
-
- -
-
- -
+
+
+
-
+ + + {{ description }} + + +
+ +
{{ 'AbpFeatureManagement::NoFeatureFoundMessage' | abpLocalization }}
- +
- + - + {{ 'AbpFeatureManagement::Save' | abpLocalization }} diff --git a/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts b/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts index a6a13d4140..4e1df0b294 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts +++ b/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts @@ -1,11 +1,15 @@ -import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; -import { Select, Store } from '@ngxs/store'; -import { Observable } from 'rxjs'; -import { GetFeatures, UpdateFeatures } from '../../actions'; +import { TrackByService } from '@abp/ng.core'; +import { LocaleDirection } from '@abp/ng.theme.shared'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { finalize } from 'rxjs/operators'; import { FeatureManagement } from '../../models/feature-management'; -import { FeatureManagementState } from '../../states'; -import { FormGroup, FormControl } from '@angular/forms'; -import { pluck, finalize } from 'rxjs/operators'; +import { FeatureDto, FeaturesService, UpdateFeatureDto } from '../../proxy/feature-management'; + +enum ValueTypes { + ToggleStringValueType = 'ToggleStringValueType', + FreeTextStringValueType = 'FreeTextStringValueType', + SelectionStringValueType = 'SelectionStringValueType', +} @Component({ selector: 'abp-feature-management', @@ -22,6 +26,16 @@ export class FeatureManagementComponent @Input() providerName: string; + selectedGroup: string; + + groups: string[] = []; + + features: { + [group: string]: Array; + }; + + valueTypes = ValueTypes; + protected _visible; @Input() @@ -30,22 +44,18 @@ export class FeatureManagementComponent } set visible(value: boolean) { + if (this._visible === value) return; + this._visible = value; this.visibleChange.emit(value); - if (value) this.openModal(); } @Output() readonly visibleChange = new EventEmitter(); - @Select(FeatureManagementState.getFeatures) - features$: Observable; - modalBusy = false; - form: FormGroup; - - constructor(private store: Store) {} + constructor(public readonly track: TrackByService, private service: FeaturesService) {} openModal() { if (!this.providerName) { @@ -56,52 +66,60 @@ export class FeatureManagementComponent } getFeatures() { - this.store - .dispatch( - new GetFeatures({ - providerKey: this.providerKey, - providerName: this.providerName, + this.service.get(this.providerName, this.providerKey).subscribe(res => { + this.groups = res.groups.map(group => group.displayName); + this.selectedGroup = this.groups[0]; + this.features = res.groups.reduce( + (acc, val) => ({ + ...acc, + [val.name]: mapFeatures(val.features, document.body.dir as LocaleDirection), }), - ) - .pipe(pluck('FeatureManagementState', 'features')) - .subscribe(features => { - this.buildForm(features); - }); - } - - buildForm(features) { - const formGroupObj = {}; - - for (let i = 0; i < features.length; i++) { - formGroupObj[i] = new FormControl(features[i].value === 'false' ? null : features[i].value); - } - - this.form = new FormGroup(formGroupObj); + {}, + ); + }); } save() { if (this.modalBusy) return; - this.modalBusy = true; + const changedFeatures = [] as UpdateFeatureDto[]; - let features = this.store.selectSnapshot(FeatureManagementState.getFeatures); + Object.keys(this.features).forEach(key => { + this.features[key].forEach(feature => { + if (feature.value !== feature.initialValue) + changedFeatures.push({ name: feature.name, value: feature.value }); + }); + }); - features = features.map((feature, i) => ({ - ...feature, - value: this.form.value[i], - })); - - this.store - .dispatch( - new UpdateFeatures({ - providerKey: this.providerKey, - providerName: this.providerName, - features, - }), - ) + if (!changedFeatures.length) { + this.visible = false; + return; + } + + this.modalBusy = true; + this.service + .update(this.providerName, this.providerKey, { features: changedFeatures }) .pipe(finalize(() => (this.modalBusy = false))) .subscribe(() => { this.visible = false; }); } } + +function mapFeatures(features: FeatureDto[], dir: LocaleDirection) { + const margin = `margin-${dir === 'rtl' ? 'right' : 'left'}.px`; + + return features.map(feature => { + const value = + feature.valueType?.name === ValueTypes.ToggleStringValueType + ? (feature.value || '').toLowerCase() === 'true' + : feature.value; + + return { + ...feature, + value, + initialValue: value, + style: { [margin]: feature.depth * 20 }, + }; + }); +}