merge from ecomp a88f0072 - Modern UI

Issue-ID: VID-378
Change-Id: Ibcb23dd27f550cf32ce2fe0239f0f496ae014ff6
Signed-off-by: Ittay Stern <ittay.stern@att.com>
diff --git a/vid-webpack-master/src/app/featureFlag/directive/basic/basic.featureFlag.directive.spec.ts b/vid-webpack-master/src/app/featureFlag/directive/basic/basic.featureFlag.directive.spec.ts
new file mode 100644
index 0000000..5722aa7
--- /dev/null
+++ b/vid-webpack-master/src/app/featureFlag/directive/basic/basic.featureFlag.directive.spec.ts
@@ -0,0 +1,93 @@
+import {TestBed, ComponentFixture, tick, inject} from '@angular/core/testing';
+import {Component, DebugElement, Renderer2, Type} from "@angular/core";
+import {By} from "@angular/platform-browser";
+import {BasicFeatureFlagDirective} from "./basic.featureFlag.directive";
+import {FeatureFlagService} from "../../service/featureFlag.service";
+import {ConfigurationService} from "../../../shared/services/configuration.service";
+import {HttpClientTestingModule, HttpTestingController} from "@angular/common/http/testing";
+import {NgRedux} from "@angular-redux/store";
+import {of} from "rxjs";
+
+@Component({
+  template: `
+    <div
+      id="featureFlagOff"
+      featureFlag
+      [flagName]='"featureFlagOff"'>
+    </div>
+    <div
+      id="featureFlagOn"
+      featureFlag
+      [flagName]='"featureFlagOn"'>
+    </div>`
+})
+class TestFeatureFlagComponent {
+}
+
+class MockRenderer<T> {
+  setStyle() {
+
+  }
+}
+
+class MockAppStore<T> {
+  getState() {
+    return {
+      global: {
+        flags : {
+
+        }
+      }
+    }
+  }
+}
+
+
+describe('Basic Feature Flag Directive', () => {
+  let component: TestFeatureFlagComponent;
+  let fixture: ComponentFixture<TestFeatureFlagComponent>;
+  let directiveInstance: BasicFeatureFlagDirective;
+  let elementOff: DebugElement;
+  let elementOn: DebugElement;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({
+      imports: [
+        HttpClientTestingModule
+      ],
+      declarations: [
+        TestFeatureFlagComponent,
+        BasicFeatureFlagDirective],
+      providers: [
+        FeatureFlagService,
+        ConfigurationService,
+        {provide: NgRedux, useClass: MockAppStore},
+        {provide: Renderer2, useClass: MockRenderer}]
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(TestFeatureFlagComponent);
+    component = fixture.componentInstance;
+    elementOff = fixture.debugElement.query(By.css('#featureFlagOff'));
+    elementOn = fixture.debugElement.query(By.css('#featureFlagOn'));
+    directiveInstance = elementOff.injector.get(BasicFeatureFlagDirective);
+  });
+
+
+  test('directive should be defined', () => {
+    expect(directiveInstance).toBeDefined();
+  });
+
+  test('should hide element if feature flag is off', () => {
+    directiveInstance.flagName  = 'featureFlagOff';
+
+    directiveInstance.ngAfterContentChecked();
+    expect(elementOff.nativeElement.style.display).toEqual('none');
+  });
+
+  test('should show element if feature flag is on', () => {
+    directiveInstance.flagName  = 'featureFlagOn';
+
+    directiveInstance.ngAfterContentChecked();
+    expect(elementOn.nativeElement.style.display).toEqual('');
+  });
+});
diff --git a/vid-webpack-master/src/app/featureFlag/directive/basic/basic.featureFlag.directive.ts b/vid-webpack-master/src/app/featureFlag/directive/basic/basic.featureFlag.directive.ts
new file mode 100644
index 0000000..e6cbb4f
--- /dev/null
+++ b/vid-webpack-master/src/app/featureFlag/directive/basic/basic.featureFlag.directive.ts
@@ -0,0 +1,29 @@
+import {AfterContentChecked, Directive, ElementRef, Input} from '@angular/core';
+import {FeatureFlagService} from "../../service/featureFlag.service";
+import * as _ from 'lodash';
+
+/************************************************************************
+    Feature Flag Directive
+    Example:
+    <div featureFlag [flagName]='"<flag name>"'></div>
+ ************************************************************************/
+@Directive({
+  selector: '[featureFlag]'
+})
+export class BasicFeatureFlagDirective implements AfterContentChecked {
+  @Input() flagName: string;
+  element: ElementRef;
+
+  constructor(el: ElementRef, private _featureToggleService: FeatureFlagService) {
+    this.element = el;
+  }
+
+  ngAfterContentChecked(): void {
+    if (!_.isNil(this.element)) {
+      const isFeatureOn: boolean = this._featureToggleService.isFeatureOn(this.flagName);
+        if(!isFeatureOn){
+          this._featureToggleService.hideElement(this.element)
+        }
+    }
+  }
+}
diff --git a/vid-webpack-master/src/app/featureFlag/featureFlag.module.ts b/vid-webpack-master/src/app/featureFlag/featureFlag.module.ts
new file mode 100644
index 0000000..d220766
--- /dev/null
+++ b/vid-webpack-master/src/app/featureFlag/featureFlag.module.ts
@@ -0,0 +1,32 @@
+import {ModuleWithProviders, NgModule} from '@angular/core';
+import {CommonModule} from '@angular/common';
+import {BrowserModule} from "@angular/platform-browser";
+import {HttpClientModule} from "@angular/common/http";
+import {FeatureFlagService} from "./service/featureFlag.service";
+import {BasicFeatureFlagDirective} from "./directive/basic/basic.featureFlag.directive";
+
+
+@NgModule({
+  imports: [
+    BrowserModule,
+    HttpClientModule,
+    CommonModule
+  ],
+  declarations: [
+    BasicFeatureFlagDirective
+  ],
+  exports: [
+    BasicFeatureFlagDirective
+  ],
+  providers: [
+    FeatureFlagService
+  ]
+})
+export class FeatureFlagModule {
+  static forRoot(): ModuleWithProviders {
+    return {
+      ngModule: FeatureFlagModule,
+      providers: []
+    };
+  }
+}
diff --git a/vid-webpack-master/src/app/featureFlag/service/featureFlag.service.ts b/vid-webpack-master/src/app/featureFlag/service/featureFlag.service.ts
new file mode 100644
index 0000000..09ce7bb
--- /dev/null
+++ b/vid-webpack-master/src/app/featureFlag/service/featureFlag.service.ts
@@ -0,0 +1,28 @@
+import {ElementRef, Injectable, Renderer2, RendererFactory2} from "@angular/core";
+import {ConfigurationService} from "../../shared/services/configuration.service";
+
+@Injectable()
+export class FeatureFlagService{
+  private features :  { [key: string]: boolean } = {};
+  private renderer: Renderer2;
+  constructor(private _configurationService: ConfigurationService,
+              rendererFactory: RendererFactory2){
+    this.renderer = rendererFactory.createRenderer(null, null);
+    this._configurationService.getFlags().subscribe((res: { [key: string]: boolean }) =>{
+      this.features = res;
+    })
+  }
+
+
+  isFeatureOn(feature : string) : boolean {
+    return this.features && this.getFeatureFlag()[feature] === true;
+  }
+
+  getFeatureFlag() : { [key: string]: boolean } {
+    return this.features;
+  }
+
+  hideElement(element: ElementRef) {
+    this.renderer.setStyle(element.nativeElement, 'display', 'none');
+  }
+}