Merge branch 'DEVELOP' of ssh://git.eclipse.org:29418/openk-usermodules/org.eclipse.openk-usermodules.gridFailureInformation.frontend into SI-1392-date-filter
diff --git a/package.json b/package.json
index 38f0438..ff5723d 100644
--- a/package.json
+++ b/package.json
@@ -59,8 +59,8 @@
     "@ngrx/store-devtools": "8.6.0",
     "@ngx-translate/core": "11.0.1",
     "@ngx-translate/http-loader": "4.0.0",
-    "ag-grid-angular": "21.2.2",
-    "ag-grid-community": "21.2.2",
+    "ag-grid-angular": "23.2.1",
+    "ag-grid-community": "23.2.1",
     "angular-font-awesome": "3.1.2",
     "angular2-notifications": "2.0.0",
     "bootstrap": "4.4.1",
diff --git a/projects/grid-failure-information-app/src/app/app-config.service.spec.ts b/projects/grid-failure-information-app/src/app/app-config.service.spec.ts
index 088f839..d9f8031 100644
--- a/projects/grid-failure-information-app/src/app/app-config.service.spec.ts
+++ b/projects/grid-failure-information-app/src/app/app-config.service.spec.ts
@@ -1,3 +1,4 @@
+import { getExportChannels } from './shared/store/index';
 /********************************************************************************
  * Copyright (c) 2020 Contributors to the Eclipse Foundation
  *
@@ -60,4 +61,10 @@
     component.load();
     expect((component as any).config).toBeDefined();
   });
+
+  it('should transform config response', () => {
+    const response: any = { exportChannels: ['X'] };
+    const item = ConfigService.configAdapter(response);
+    expect(item.exportChannels).toBe(response.exportChannels);
+  });
 });
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.spec.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.spec.ts
index e6e5cd0..b099e56 100644
--- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.spec.ts
+++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.spec.ts
@@ -1,5 +1,3 @@
-import { INITIAL_STATE } from './../../../shared/store/reducers/grid-failures/grid-failure-details-form.reducer';
-import { logging } from 'protractor';
 /********************************************************************************
  * Copyright (c) 2020 Contributors to the Eclipse Foundation
  *
@@ -18,6 +16,8 @@
 import { State } from '@grid-failure-information-app/shared/store';
 import { async } from '@angular/core/testing';
 import { Globals } from '@grid-failure-information-app/shared/constants/globals';
+import { INITIAL_STATE } from '@grid-failure-information-app/shared/store/reducers/grid-failures/grid-failure-details-form.reducer';
+import * as models from '@grid-failure-information-app/shared/models';
 
 describe('GridFailureDetailsComponent', () => {
   let component: GridFailureDetailsComponent;
@@ -47,7 +47,9 @@
       resetStationId() {},
       resetPostCode() {},
       disableUnnecessaryRequiredProperties() {},
+      setSelectedStation() {},
       gridFailureDetailsFormState$: of(gridFailureDetailsFormResponse as any),
+      disableStationAttributes: false,
     } as any;
     component = new GridFailureDetailsComponent(gridFailureSandbox, appState);
   });
@@ -104,6 +106,7 @@
     (component as any)._initialFailureLocationState();
     expect(component.mapInteractionMode).toBeFalsy();
   }));
+
   it('checks if _initialFailureLocationState works fine for NS', async(() => {
     component.failureLocationView === Globals.FAILURE_LOCATION_MAP;
 
@@ -120,6 +123,7 @@
     (component as any)._initialFailureLocationState();
     expect(component.mapInteractionMode).toBeFalsy();
   }));
+
   it('checks if _initialFailureLocationState works fine for MS', async(() => {
     component.failureLocationView === Globals.FAILURE_LOCATION_MAP;
     //MS
@@ -147,4 +151,37 @@
     component.setLocation();
     expect(spy).toHaveBeenCalled();
   });
+
+  it('should reset selected station if no value exists', () => {
+    const spy = spyOn(gridFailureSandbox, 'setSelectedStation');
+    component.resetSelectedStation(null);
+    expect(spy).toHaveBeenCalled();
+  });
+
+  it('should resize map via forceResize$.next(true)', () => {
+    const spy = spyOn(component.mapOptions.forceResize$, 'next');
+    component.resizeSetMap();
+    expect(spy).toHaveBeenCalled();
+  });
+
+  it('should change to currentVersionMode in response to disableStationAttributes=false', () => {
+    const spy = spyOn(component.events$, 'next');
+    gridFailureSandbox.gridFailureStations$ = of([new models.FailureStation()]);
+    component.changeMode();
+    expect(spy).toHaveBeenCalledWith({ eventType: component['_modeEnum'].currentVersionMode });
+  });
+
+  it('should change to oldVersionMode in response to disableStationAttributes=false', () => {
+    const spy = spyOn(component.events$, 'next');
+    gridFailureSandbox.disableStationAttributes = true;
+    gridFailureSandbox.gridFailureStations$ = of([new models.FailureStation()]);
+    component.changeMode();
+    expect(spy).toHaveBeenCalledWith({ eventType: component['_modeEnum'].oldVersionMode });
+  });
+
+  it('should determine mapInteractionMode correctly', () => {
+    component.failureLocationView = Globals.FAILURE_LOCATION_MAP;
+    gridFailureSandbox.disableStationAttributes = false;
+    expect(component.mapInteractionMode).toBeTruthy();
+  });
 });
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure-list-column-definition.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure-list-column-definition.ts
index 56e49ea..62ff9c2 100644
--- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure-list-column-definition.ts
+++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-list/grid-failure-list-column-definition.ts
@@ -98,6 +98,8 @@
     filterParams: {
       comparator: dateTimeComparator,
       browserDatePicker: true,
+      buttons: ['apply', 'reset'],
+      closeOnApply: false,
     },
     cellRendererFramework: DateTimeCellRendererComponent,
   },
@@ -111,6 +113,8 @@
     filterParams: {
       comparator: dateTimeComparator,
       browserDatePicker: true,
+      buttons: ['apply', 'reset'],
+      closeOnApply: false,
     },
     cellRendererFramework: DateTimeCellRendererComponent,
   },
@@ -124,6 +128,8 @@
     filterParams: {
       comparator: dateTimeComparator,
       browserDatePicker: true,
+      buttons: ['apply', 'reset'],
+      closeOnApply: false,
     },
     cellRendererFramework: DateTimeCellRendererComponent,
   },
diff --git a/projects/grid-failure-information-app/src/app/shared/constants/globals.ts b/projects/grid-failure-information-app/src/app/shared/constants/globals.ts
index 69e5ee9..ff90549 100644
--- a/projects/grid-failure-information-app/src/app/shared/constants/globals.ts
+++ b/projects/grid-failure-information-app/src/app/shared/constants/globals.ts
@@ -32,6 +32,8 @@
     inRange: 'ist zwischen',
     andCondition: 'und',
     orCondition: 'oder',
+    resetFilter: 'Filter löschen',
+    applyFilter: 'Filter anwenden',
   };
   public static PROPERTIES_TO_BOX: string[] = ['addressPolygonPoints', '__formBranch', 'distributionGroupUuids', 'stationIds', 'publicationChannels'];
 
diff --git a/projects/grid-failure-information-app/src/app/shared/directives/date-time-picker-view-adapter.directive.spec.ts b/projects/grid-failure-information-app/src/app/shared/directives/date-time-picker-view-adapter.directive.spec.ts
index 2d86709..4e6bc9f 100644
--- a/projects/grid-failure-information-app/src/app/shared/directives/date-time-picker-view-adapter.directive.spec.ts
+++ b/projects/grid-failure-information-app/src/app/shared/directives/date-time-picker-view-adapter.directive.spec.ts
@@ -1,8 +1,67 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
 import { DateTimePickerViewAdapterDirective } from '@grid-failure-information-app/shared/directives/date-time-picker-view-adapter.directive';
+import { DateTimePickerComponent } from '@grid-failure-information-app/shared/components/date-time-picker/date-time-picker.component';
+import { NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap';
+import { DateTimeModel } from '@grid-failure-information-app/shared/models/date-time.model';
+import { dateTimePickerValueConverter } from '@grid-failure-information-app/shared/utility';
+import { FormControlState } from 'ngrx-forms';
 
 describe('DateTimePickerViewAdapaterDirective', () => {
+  let config: NgbPopoverConfig;
+  let component: DateTimePickerComponent;
+  let directive: DateTimePickerViewAdapterDirective;
+
+  beforeEach(() => {
+    config = new NgbPopoverConfig();
+    component = new DateTimePickerComponent(config);
+    directive = new DateTimePickerViewAdapterDirective(component);
+  });
+
   it('should create an instance', () => {
-    const directive = new DateTimePickerViewAdapterDirective({} as any);
     expect(directive).toBeTruthy();
   });
+
+  it('should set dateTimeViewValue to null', () => {
+    directive.setViewValue(null);
+    expect(directive['_dateTimePickerComponent'].dateTimeViewValue).toBeNull;
+  });
+
+  it('should set dateTimeViewValue to model', () => {
+    directive.setViewValue('20200618');
+    directive['dateTimeModel'] = DateTimeModel.fromLocalString('20200618');
+    expect(directive['_dateTimePickerComponent'].dateTimeViewValue).toBe(dateTimePickerValueConverter.convertStateToViewValue(directive['dateTimeModel']));
+  });
+
+  it('should set onChangeCallback', () => {
+    let onChangeCallback = value => {};
+    directive.setOnChangeCallback(onChangeCallback);
+    expect(directive['_dateTimePickerComponent'].onValueChangeCallBack).toBeDefined();
+  });
+
+  it('should set markTouchedCallBack', () => {
+    directive.setOnTouchedCallback(() => {});
+    expect(directive['_dateTimePickerComponent'].markTouched).toBeDefined();
+  });
+
+  it('should set isDisabled', () => {
+    directive.setIsDisabled(true);
+    expect(directive['_dateTimePickerComponent'].isDisabled).toBeTruthy();
+  });
+
+  it('should set isValid property', () => {
+    let state: FormControlState<any> = { isValid: true } as any;
+    directive.ngrxFormControlState = state;
+    expect(directive['_dateTimePickerComponent'].isValid).toBeTruthy();
+  });
 });
diff --git a/projects/grid-failure-information-app/src/app/shared/directives/form-disable.directive.spec.ts b/projects/grid-failure-information-app/src/app/shared/directives/form-disable.directive.spec.ts
index 7c4d223..445d934 100644
--- a/projects/grid-failure-information-app/src/app/shared/directives/form-disable.directive.spec.ts
+++ b/projects/grid-failure-information-app/src/app/shared/directives/form-disable.directive.spec.ts
@@ -13,10 +13,15 @@
 import { FormDisableDirective } from '@grid-failure-information-app/shared/directives/form-disable.directive';
 import { async } from '@angular/core/testing';
 import { of } from 'rxjs/observable/of';
+import { FormState } from 'ngrx-forms';
+import { PermissionsModel } from '@grid-failure-information-app/shared/models/permissions.model';
+import { RolesEnum } from '@grid-failure-information-app/shared/constants/enums';
 
 describe('FormDisableDirective', () => {
+  let directive: FormDisableDirective;
   let viewContainerRef: any;
   let appState: any;
+
   beforeEach(async(() => {
     viewContainerRef = {
       createEmbeddedView: () => {},
@@ -30,10 +35,26 @@
       select: () => of({ roles: ['grid-failure-reader'] }),
       map: () => of({ reader: true }),
     };
+    directive = new FormDisableDirective(appState as any);
   }));
 
   it('should create an instance', () => {
-    const directive = new FormDisableDirective(appState as any);
     expect(directive).toBeTruthy();
   });
+
+  it('should not dispatch action if formState is disabled', () => {
+    let state: FormState<any> = { isDisabled: true } as any;
+    let dispatchSpy = spyOn(directive['_appState$'], 'dispatch');
+    directive.ngrxFormState = state;
+    expect(dispatchSpy).toHaveBeenCalledTimes(0);
+  });
+
+  it('should dispatch action if formState is not disabled', () => {
+    let permission: PermissionsModel = new PermissionsModel([RolesEnum.READER]);
+    directive['_permissions$'] = of(permission);
+    let state: FormState<any> = { isDisabled: false } as any;
+    let dispatchSpy = spyOn(directive['_appState$'], 'dispatch');
+    directive.ngrxFormState = state;
+    expect(dispatchSpy).toHaveBeenCalled();
+  });
 });
diff --git a/projects/grid-failure-information-app/src/app/shared/directives/form-validator.directive.spec.ts b/projects/grid-failure-information-app/src/app/shared/directives/form-validator.directive.spec.ts
index 6c48822..7b531d5 100644
--- a/projects/grid-failure-information-app/src/app/shared/directives/form-validator.directive.spec.ts
+++ b/projects/grid-failure-information-app/src/app/shared/directives/form-validator.directive.spec.ts
@@ -13,8 +13,25 @@
 import { FormValidatorDirective } from '@grid-failure-information-app/shared/directives/form-validator.directive';
 
 describe('FormValidator.DirectiveDirective', () => {
+  let directive: FormValidatorDirective;
+
+  beforeEach(() => {
+    directive = new FormValidatorDirective();
+  });
+
   it('should create an instance', () => {
-    const directive = new FormValidatorDirective();
     expect(directive).toBeTruthy();
   });
+
+  it('should set invalid property correctly', () => {
+    directive.required = true;
+    directive.ngrxFormControlState = { isDisabled: true, value: null } as any;
+    expect(directive.invalid).toBeTruthy();
+  });
+
+  it('should set valid property correctly', () => {
+    directive.required = true;
+    directive.ngrxFormControlState = { isDisabled: true, value: 'x' } as any;
+    expect(directive.valid).toBeTruthy();
+  });
 });
diff --git a/projects/grid-failure-information-app/src/app/shared/directives/forms/form-control-ui-state.directive.spec.ts b/projects/grid-failure-information-app/src/app/shared/directives/forms/form-control-ui-state.directive.spec.ts
index 479ae5e..e21d9ef 100644
--- a/projects/grid-failure-information-app/src/app/shared/directives/forms/form-control-ui-state.directive.spec.ts
+++ b/projects/grid-failure-information-app/src/app/shared/directives/forms/form-control-ui-state.directive.spec.ts
@@ -1,15 +1,57 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
 import { FormControlVisibilityDirective } from './form-control-ui-state.directive';
 import { of } from 'rxjs/observable/of';
+import { State } from '@grid-failure-information-app/shared/store';
+import { Store } from '@ngrx/store';
+import { DisableAction, EnableAction, ResetAction, SetValueAction, NgrxFormControlDirective } from 'ngrx-forms';
 
 describe('FormControlVisibilityDirective ', () => {
-  it('should create an instance', () => {
-    let appState = of({
+  let directive: FormControlVisibilityDirective;
+  let appState: Store<State>;
+
+  beforeEach(() => {
+    appState = of({
       pipe: () => {},
       dispatch: () => {},
       select: () => {},
       map: () => {},
-    });
-    const directive = new FormControlVisibilityDirective(appState as any);
+    }) as any;
+    directive = new FormControlVisibilityDirective(appState as any);
+  });
+
+  it('should create an instance', () => {
     expect(directive).toBeTruthy();
   });
+
+  it('should set isVisible property', () => {
+    directive.visibleByDependentField = true;
+    expect(directive['_isVisible']).toBeTruthy();
+  });
+
+  it('should dispatch EnableAction if isVisible = true', () => {
+    directive = new FormControlVisibilityDirective({ dispatch: () => null } as any);
+    let dispatchSpy = spyOn(directive['_appState$'], 'dispatch');
+    directive.ngrxFormControl = { state: { id: 'x' } } as any;
+    directive.visibleByDependentField = true;
+    expect(dispatchSpy).toHaveBeenCalledWith(new EnableAction(directive.ngrxFormControl.state.id));
+  });
+
+  it('should dispatch ResetAction if isVisible = false', () => {
+    directive = new FormControlVisibilityDirective({ dispatch: () => null } as any);
+    let dispatchSpy = spyOn(directive['_appState$'], 'dispatch');
+    directive.ngrxFormControl = { state: { id: 'x' } } as any;
+    directive.visibleByDependentField = false;
+    expect(dispatchSpy).toHaveBeenCalledWith(new ResetAction(directive.ngrxFormControl.state.id));
+  });
 });
diff --git a/projects/grid-failure-information-app/src/app/shared/directives/forms/form-control-ui-state.directive.ts b/projects/grid-failure-information-app/src/app/shared/directives/forms/form-control-ui-state.directive.ts
index beee708..3cd9687 100644
--- a/projects/grid-failure-information-app/src/app/shared/directives/forms/form-control-ui-state.directive.ts
+++ b/projects/grid-failure-information-app/src/app/shared/directives/forms/form-control-ui-state.directive.ts
@@ -1,3 +1,15 @@
+/********************************************************************************
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
 import { Directive, Input, HostBinding, ContentChild } from '@angular/core';
 import * as store from '@grid-failure-information-app/shared/store';
 import { Store } from '@ngrx/store';