-
-
+
+
-
- {{ feature.displayName }}
+
+ {{ feature.displayName }}
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 c225060370..71e5ae834e 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
@@ -119,6 +119,70 @@ export class FeatureManagementComponent
}
});
}
+
+ onCheckboxClick(val: boolean, feature: FeatureDto) {
+ if (val) {
+ this.checkToggleAncestors(feature);
+ } else {
+ this.uncheckToggleDescendants(feature);
+ }
+ }
+
+ private uncheckToggleDescendants(feature: FeatureDto) {
+ this.findAllDescendantsOfByType(feature, ValueTypes.ToggleStringValueType).forEach(node =>
+ this.setFeatureValue(node, false),
+ );
+ }
+
+ private checkToggleAncestors(feature: FeatureDto) {
+ this.findAllAncestorsOfByType(feature, ValueTypes.ToggleStringValueType).forEach(node =>
+ this.setFeatureValue(node, true),
+ );
+ }
+
+ private findAllAncestorsOfByType(feature: FeatureDto, type: ValueTypes) {
+ let parent = this.findParentByType(feature, type);
+ const ancestors = [];
+ while (parent) {
+ ancestors.push(parent);
+ parent = this.findParentByType(parent, type);
+ }
+ return ancestors;
+ }
+
+ private findAllDescendantsOfByType(feature: FeatureDto, type: ValueTypes) {
+ const descendants = [];
+ const queue = [feature];
+
+ while (queue.length) {
+ const node = queue.pop();
+ const newDescendants = this.findChildrenByType(node, type);
+ descendants.push(...newDescendants);
+ queue.push(...newDescendants);
+ }
+
+ return descendants;
+ }
+
+ private findParentByType(feature: FeatureDto, type: ValueTypes) {
+ return this.getCurrentGroup().find(
+ f => f.valueType.name === type && f.name === feature.parentName,
+ );
+ }
+
+ private findChildrenByType(feature: FeatureDto, type: ValueTypes) {
+ return this.getCurrentGroup().filter(
+ f => f.valueType.name === type && f.parentName === feature.name,
+ );
+ }
+
+ private getCurrentGroup() {
+ return this.features[this.selectedGroupDisplayName] ?? [];
+ }
+
+ private setFeatureValue(feature: FeatureDto, val: boolean) {
+ feature.value = val as any;
+ }
}
function mapFeatures(features: FeatureDto[], dir: LocaleDirection) {
diff --git a/npm/ng-packs/packages/feature-management/src/lib/directives/free-text-input.directive.ts b/npm/ng-packs/packages/feature-management/src/lib/directives/free-text-input.directive.ts
new file mode 100644
index 0000000000..f72729375a
--- /dev/null
+++ b/npm/ng-packs/packages/feature-management/src/lib/directives/free-text-input.directive.ts
@@ -0,0 +1,38 @@
+import { Directive, Input, HostBinding } from '@angular/core';
+
+// TODO: improve this type
+export interface FreeTextType {
+ valueType: {
+ validator: {
+ name: string;
+ };
+ };
+}
+
+export const INPUT_TYPES = {
+ numeric: 'number',
+ default: 'text',
+};
+
+@Directive({
+ selector: 'input[abpFeatureManagementFreeText]',
+ exportAs: 'inputAbpFeatureManagementFreeText',
+})
+export class FreeTextInputDirective {
+ _feature: FreeTextType;
+ @Input('abpFeatureManagementFreeText') set feature(val: FreeTextType) {
+ this._feature = val;
+ this.setInputType();
+ }
+
+ get feature() {
+ return this._feature;
+ }
+
+ @HostBinding('type') type: string;
+
+ private setInputType() {
+ const validatorType = this.feature?.valueType?.validator?.name.toLowerCase();
+ this.type = INPUT_TYPES[validatorType] ?? INPUT_TYPES.default;
+ }
+}
diff --git a/npm/ng-packs/packages/feature-management/src/lib/directives/index.ts b/npm/ng-packs/packages/feature-management/src/lib/directives/index.ts
new file mode 100644
index 0000000000..ec7eef1ded
--- /dev/null
+++ b/npm/ng-packs/packages/feature-management/src/lib/directives/index.ts
@@ -0,0 +1 @@
+export * from './free-text-input.directive';
diff --git a/npm/ng-packs/packages/feature-management/src/lib/feature-management.module.ts b/npm/ng-packs/packages/feature-management/src/lib/feature-management.module.ts
index 0a3d3b822e..4061965085 100644
--- a/npm/ng-packs/packages/feature-management/src/lib/feature-management.module.ts
+++ b/npm/ng-packs/packages/feature-management/src/lib/feature-management.module.ts
@@ -1,19 +1,22 @@
import { CoreModule } from '@abp/ng.core';
import { ThemeSharedModule } from '@abp/ng.theme.shared';
import { NgModule } from '@angular/core';
-import { FeatureManagementComponent } from './components/feature-management/feature-management.component';
import { NgxsModule } from '@ngxs/store';
-import { FeatureManagementState } from './states/feature-management.state';
import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { FreeTextInputDirective } from './directives/free-text-input.directive';
+import { FeatureManagementComponent } from './components/feature-management/feature-management.component';
+import { FeatureManagementState } from './states/feature-management.state';
+
+const exported = [FeatureManagementComponent, FreeTextInputDirective];
@NgModule({
- declarations: [FeatureManagementComponent],
+ declarations: [...exported],
imports: [
CoreModule,
ThemeSharedModule,
NgbNavModule,
NgxsModule.forFeature([FeatureManagementState]),
],
- exports: [FeatureManagementComponent],
+ exports: [...exported],
})
export class FeatureManagementModule {}