Merge branch 'DEVELOP' of ssh://git.eclipse.org:29418/openk-usermodules/org.eclipse.openk-usermodules.gridFailureInformation.frontend into SI-176-sonstiges-und-bugs
+ [SI-176]: Bugs and other things

Signed-off-by: Dennis Schmitt <dennis.schmitt@pta.de>
diff --git a/angular.json b/angular.json
index b723b38..f0029a8 100644
--- a/angular.json
+++ b/angular.json
@@ -31,6 +31,7 @@
               "projects/grid-failure-information-app/src/assets",
               "projects/grid-failure-information-app/src/favicon.ico",
               "projects/grid-failure-information-app/src/service-worker.js",
+              "projects/grid-failure-information-app/src/WEB-INF",
               {
                 "glob": "**/*",
                 "input": "config",
@@ -120,7 +121,11 @@
             "polyfills": "projects/grid-failure-information-app/src/polyfills.ts",
             "tsConfig": "projects/grid-failure-information-app/tsconfig.spec.json",
             "karmaConfig": "projects/grid-failure-information-app/karma.conf.js",
-            "assets": ["projects/grid-failure-information-app/src/favicon.ico", "projects/grid-failure-information-app/src/assets"],
+            "assets": [
+              "projects/grid-failure-information-app/src/favicon.ico",
+              "projects/grid-failure-information-app/src/assets",
+              "projects/grid-failure-information-app/src/WEB-INF"
+            ],
             "styles": [
               "projects/grid-failure-information-app/src/styles.scss",
               "node_modules/leaflet/dist/leaflet.css",
@@ -130,7 +135,7 @@
             "scripts": [],
             "codeCoverage": true,
             "codeCoverageExclude": [
-              "src/environments/**",
+              "**/environments/**",
               "e2e/*.ts",
               "**/*.action.*",
               "**/*.model.*",
@@ -139,7 +144,8 @@
               "**/*api-client.*",
               "**/*.animation.*",
               "**/lib/**/*",
-              "**/testing/**/*"
+              "**/testing/**/*",
+              "**/assets/**/*"
             ]
           }
         },
@@ -262,7 +268,21 @@
             "karmaConfig": "projects/grid-failure-information-map-app/karma.conf.js",
             "assets": ["projects/grid-failure-information-map-app/src/favicon.ico", "projects/grid-failure-information-map-app/src/assets"],
             "styles": ["projects/grid-failure-information-map-app/src/styles.scss"],
-            "scripts": []
+            "scripts": [],
+            "codeCoverage": true,
+            "codeCoverageExclude": [
+              "**/environments/**",
+              "e2e/*.ts",
+              "**/*.action.*",
+              "**/*.model.*",
+              "**/*.module.*",
+              "**/*column-definition*",
+              "**/*api-client.*",
+              "**/*.animation.*",
+              "**/lib/**/*",
+              "**/testing/**/*",
+              "**/assets/**/*"
+            ]
           }
         },
         "lint": {
@@ -308,7 +328,20 @@
           "options": {
             "main": "projects/openk/grid-failure-information-map/src/test.ts",
             "tsConfig": "projects/openk/grid-failure-information-map/tsconfig.spec.json",
-            "karmaConfig": "projects/openk/grid-failure-information-map/karma.conf.js"
+            "karmaConfig": "projects/openk/grid-failure-information-map/karma.conf.js",
+            "codeCoverage": true,
+            "codeCoverageExclude": [
+              "**/environments/**",
+              "e2e/*.ts",
+              "**/*.action.*",
+              "**/*.model.*",
+              "**/*.module.*",
+              "**/*column-definition*",
+              "**/*api-client.*",
+              "**/*.animation.*",
+              "**/testing/**/*",
+              "**/assets/**/*"
+            ]
           }
         },
         "lint": {
diff --git a/create-map-output-elements.sh b/create-map-output-elements.sh
index 303ec80..533669e 100644
--- a/create-map-output-elements.sh
+++ b/create-map-output-elements.sh
@@ -2,6 +2,11 @@
 echo Starting...
 echo
 
+dist_path=./dist/grid-failure-information-map-app
+
+cd $dist_path
+echo navigate to $dist_path
+
 rm -rf outputElements.tar.gz
 echo old outputElements.tar.gz file removed
 echo
@@ -10,22 +15,22 @@
 echo outputElements folder created
 echo
 
-cp  ./dist/grid-failure-information-map-app/main*.js ./outputElements
+cp  main*.js ./outputElements
 echo main files copied
 
-cp  ./dist/grid-failure-information-map-app/runtime*.js ./outputElements
+cp  runtime*.js ./outputElements
 echo runtime files copied
 
-cp  ./dist/grid-failure-information-map-app/polyfills*.js ./outputElements
+cp  polyfills*.js ./outputElements
 echo polyfills files copied
 
-cp  ./dist/grid-failure-information-map-app/scripts*.js ./outputElements
+cp  scripts*.js ./outputElements
 echo scripts files copied
 
-cp  ./dist/grid-failure-information-map-app/styles*.css ./outputElements
+cp  styles*.css ./outputElements
 echo styles files copied
 
-cp  ./dist/grid-failure-information-map-app/index.html ./outputElements
+cp  index.html ./outputElements
 echo index file copied
 echo
 
diff --git a/package.json b/package.json
index e04426c..a3ce0ab 100644
--- a/package.json
+++ b/package.json
@@ -14,11 +14,11 @@
     "start-integration": "npm run sy-pre-start && npm run build-map-library && ng serve --proxy-config proxy.conf-integration.json",
     "start-local": "npm run sy-pre-start && ng serve --proxy-config proxy.conf-local.json",
     "test": "npm run sy-pre-test && ng test grid-failure-information-app",
-    "test-single-run": "npm run sy-pre-test && ng test --code-coverage grid-failure-information-app --watch=false",
-    "test-openk": "npm run sy-pre-test && ng test --code-coverage openk-grid-failure-information-map-lib",
-    "test-openk-single-run": "npm run sy-pre-test && ng test --code-coverage openk-grid-failure-information-map-lib --watch=false",
-    "test-map-app": "npm run sy-pre-test && ng test --code-coverage grid-failure-information-map-app",
-    "test-map-app-single-run": "npm run sy-pre-test && ng test --code-coverage grid-failure-information-map-app --watch=false",
+    "test-single-run": "npm run sy-pre-test && ng test grid-failure-information-app --watch=false",
+    "test-openk": "npm run sy-pre-test && ng test openk-grid-failure-information-map-lib",
+    "test-openk-single-run": "npm run sy-pre-test && ng test openk-grid-failure-information-map-lib --watch=false",
+    "test-map-app": "npm run sy-pre-test && ng test grid-failure-information-map-app",
+    "test-map-app-single-run": "npm run sy-pre-test && ng test grid-failure-information-map-app --watch=false",
     "test-all": "npm run test-single-run && npm run test-openk-single-run",
     "pree2e": "webdriver-manager update --standalone false --gecko false",
     "e2e": "ng e2e",
diff --git a/projects/grid-failure-information-app/src/WEB-INF/web.xml b/projects/grid-failure-information-app/src/WEB-INF/web.xml
new file mode 100644
index 0000000..94ac5db
--- /dev/null
+++ b/projects/grid-failure-information-app/src/WEB-INF/web.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
+  version="3.1">
+
+	<error-page>
+         <error-code>404</error-code>
+         <location>/index.html</location>
+    </error-page>
+
+</web-app>
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.html b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.html
index 7838c8f..00559eb 100644
--- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.html
+++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.html
@@ -265,6 +265,8 @@
                 <app-date-time-picker
                   (dateTimeChange)="setGridFailureDateTime($event, 'failureBegin')"
                   [dateString]="((gridFailureDetailsSandbox.gridFailureDetailsFormState$ | async)?.controls)['failureBegin']?.value"
+                  [disabled]="!gridFailureDetailsSandbox.saveEnabled"
+                  [class.isDisabled]="!gridFailureDetailsSandbox.saveEnabled"
                 ></app-date-time-picker>
               </div>
 
@@ -276,6 +278,7 @@
                 id="failureBegin"
                 [ngrxFormControlState]="((gridFailureDetailsSandbox.gridFailureDetailsFormState$ | async)?.controls)['failureBegin']"
                 [ngrxValueConverter]="gridFailureDetailsSandbox.dateTimeValueConverter"
+                [class.isDisabled]="!gridFailureDetailsSandbox.saveEnabled"
                 readonly
               />
               <div class="input-group-append">
@@ -283,6 +286,8 @@
                   class="btn btn-outline-primary calendar"
                   (click)="resetGridFailureDateTime(gridFailureDetailsSandbox.datePickerResetEnum.FailureBegin)"
                   type="button"
+                  [disabled]="!gridFailureDetailsSandbox.saveEnabled"
+                  [class.isDisabled]="!gridFailureDetailsSandbox.saveEnabled"
                 >
                   <em class="fa fa-times-circle" aria-hidden="true"></em>
                 </button>
@@ -298,6 +303,8 @@
                 <app-date-time-picker
                   (dateTimeChange)="setGridFailureDateTime($event, 'failureEndPlanned')"
                   [dateString]="((gridFailureDetailsSandbox.gridFailureDetailsFormState$ | async)?.controls)['failureEndPlanned']?.value"
+                  [disabled]="!gridFailureDetailsSandbox.saveEnabled"
+                  [class.isDisabled]="!gridFailureDetailsSandbox.saveEnabled"
                 ></app-date-time-picker>
               </div>
 
@@ -308,6 +315,7 @@
                 id="failureEndPlanned"
                 [ngrxFormControlState]="((gridFailureDetailsSandbox.gridFailureDetailsFormState$ | async)?.controls)['failureEndPlanned']"
                 [ngrxValueConverter]="gridFailureDetailsSandbox.dateTimeValueConverter"
+                [class.isDisabled]="!gridFailureDetailsSandbox.saveEnabled"
                 readonly
               />
               <div class="input-group-append">
@@ -315,6 +323,8 @@
                   class="btn btn-outline-primary calendar"
                   (click)="resetGridFailureDateTime(gridFailureDetailsSandbox.datePickerResetEnum.FailureEndPlanned)"
                   type="button"
+                  [disabled]="!gridFailureDetailsSandbox.saveEnabled"
+                  [class.isDisabled]="!gridFailureDetailsSandbox.saveEnabled"
                 >
                   <em class="fa fa-times-circle" aria-hidden="true"></em>
                 </button>
@@ -329,6 +339,8 @@
               <app-date-time-picker
                 (dateTimeChange)="setGridFailureDateTime($event, 'failureEndResupplied')"
                 [dateString]="((gridFailureDetailsSandbox.gridFailureDetailsFormState$ | async)?.controls)['failureEndResupplied']?.value"
+                [disabled]="!gridFailureDetailsSandbox.saveEnabled"
+                [class.isDisabled]="!gridFailureDetailsSandbox.saveEnabled"
               ></app-date-time-picker>
               <input
                 class="form-control editable"
@@ -337,6 +349,7 @@
                 id="failureEndResupplied"
                 [ngrxFormControlState]="((gridFailureDetailsSandbox.gridFailureDetailsFormState$ | async)?.controls)['failureEndResupplied']"
                 [ngrxValueConverter]="gridFailureDetailsSandbox.dateTimeValueConverter"
+                [class.isDisabled]="!gridFailureDetailsSandbox.saveEnabled"
                 readonly
               />
               <div class="input-group-append">
@@ -344,6 +357,8 @@
                   class="btn btn-outline-primary calendar"
                   (click)="resetGridFailureDateTime(gridFailureDetailsSandbox.datePickerResetEnum.FailureEndResupplied)"
                   type="button"
+                  [disabled]="!gridFailureDetailsSandbox.saveEnabled"
+                  [class.isDisabled]="!gridFailureDetailsSandbox.saveEnabled"
                 >
                   <em class="fa fa-times-circle" aria-hidden="true"></em>
                 </button>
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.scss b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.scss
index 5eb936a..8840f19 100644
--- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.scss
+++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.component.scss
@@ -53,3 +53,7 @@
 .version-select {
   margin: 8px;
 }
+
+.isDisabled {
+  background-color: rgb(233, 236, 239);
+}
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.spec.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.spec.ts
index f47c3a1..8833305 100644
--- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.spec.ts
+++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure-details/grid-failure-details.sandbox.spec.ts
@@ -18,6 +18,7 @@
 import { UtilService } from '@grid-failure-information-app/shared/utility/utility.service';
 import { Router } from '@angular/router';
 import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { GridFailure } from '@grid-failure-information-app/shared/models';
 
 describe('GridFailureDetailsSandbox', () => {
   let service: GridFailureDetailsSandbox;
@@ -26,6 +27,7 @@
   let utilService: UtilService;
   let router: Router;
   let modalService: NgbModal;
+  let dispatchSpy: any;
 
   beforeEach(() => {
     appState = { dispatch: () => {}, pipe: () => of(true), select: () => of(true) } as any;
@@ -33,7 +35,7 @@
     utilService = { displayNotification() {} } as any;
     router = { navigateByUrl() {} } as any;
     modalService = { open() {} } as any;
-    spyOn(appState, 'dispatch').and.callFake(() => {});
+    dispatchSpy = spyOn(appState, 'dispatch').and.callFake(() => {});
 
     service = new GridFailureDetailsSandbox(appState, actionSubject, router, utilService, modalService);
   });
@@ -117,4 +119,35 @@
 
     expect(appState.dispatch).toHaveBeenCalledTimes(3);
   });
+
+  it('should call dispatch and clear if save a valid grid failure detail', () => {
+    const spy1 = spyOn(service as any, '_clear');
+    const gfdetail = new GridFailure();
+    gfdetail.id = 'id';
+    gfdetail.responsibility = 'test';
+
+    service.currentFormState = {
+      ...service.currentFormState,
+      isValid: true,
+      value: gfdetail,
+    };
+    service.saveGridFailure();
+    expect(dispatchSpy).toHaveBeenCalledWith(Object({ payload: gfdetail, type: gridFailureActions.saveGridFailure.type }));
+    expect(spy1).toHaveBeenCalled();
+  });
+
+  it('should display a notification if the grid failure detail is invalid', () => {
+    const spy1 = spyOn(utilService, 'displayNotification');
+    const gfdetail = new GridFailure();
+    gfdetail.id = 'id';
+    gfdetail.responsibility = 'test';
+
+    service.currentFormState = {
+      ...service.currentFormState,
+      isValid: false,
+      value: gfdetail,
+    };
+    service.saveGridFailure();
+    expect(spy1).toHaveBeenCalled();
+  });
 });
diff --git a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.resolver.spec.ts b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.resolver.spec.ts
index c42bcf7..7d8e08d 100644
--- a/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.resolver.spec.ts
+++ b/projects/grid-failure-information-app/src/app/pages/grid-failure/grid-failure.resolver.spec.ts
@@ -45,8 +45,10 @@
 
   it('should call loadGridFailure', () => {
     const spy = spyOn(detailSandbox, 'loadGridFailure');
+    const spy2 = spyOn(detailSandbox, 'loadGridFailureVersions');
     let ar: any = { params: { gridFailureId: '6432a9c9-0384-44af-9bb8-34f2878d7b49' } };
     component.resolve(ar);
     expect(spy).toHaveBeenCalled();
+    expect(spy2).toHaveBeenCalled();
   });
 });
diff --git a/projects/grid-failure-information-app/src/app/pages/logout/logged-out/logged-out.component.spec.ts b/projects/grid-failure-information-app/src/app/pages/logout/logged-out/logged-out.component.spec.ts
index 4ae208c..d7b4841 100644
--- a/projects/grid-failure-information-app/src/app/pages/logout/logged-out/logged-out.component.spec.ts
+++ b/projects/grid-failure-information-app/src/app/pages/logout/logged-out/logged-out.component.spec.ts
@@ -22,4 +22,11 @@
   it('should create', () => {
     expect(component).toBeTruthy();
   });
+
+  it('should focus on button on init', () => {
+    component.button = { nativeElement: { focus() {} } };
+    const spy = spyOn(component.button.nativeElement, 'focus').and.callThrough();
+    component.ngOnInit();
+    expect(spy).toHaveBeenCalled();
+  });
 });
diff --git a/projects/grid-failure-information-app/src/app/shared/components/date-time-picker/date-time-picker.component.spec.ts b/projects/grid-failure-information-app/src/app/shared/components/date-time-picker/date-time-picker.component.spec.ts
index 75f1499..22dd63a 100644
--- a/projects/grid-failure-information-app/src/app/shared/components/date-time-picker/date-time-picker.component.spec.ts
+++ b/projects/grid-failure-information-app/src/app/shared/components/date-time-picker/date-time-picker.component.spec.ts
@@ -10,12 +10,15 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  ********************************************************************************/
-import { DateTimePickerComponent } from '@grid-failure-information-app/shared/components/date-time-picker/date-time-picker.component';
-import { NgbPopoverConfig, NgbPopover } from '@ng-bootstrap/ng-bootstrap';
+import { DateTimePickerComponent, CustomDatepickerI18n } 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 { async } from '@angular/core/testing';
 
 describe('DateTimePickerComponent', () => {
   let component: DateTimePickerComponent;
+  let customDatePicker: CustomDatepickerI18n;
+
   let config: NgbPopoverConfig;
 
   beforeEach(() => {
@@ -25,6 +28,7 @@
     } as any;
 
     component = new DateTimePickerComponent(config);
+    customDatePicker = new CustomDatepickerI18n();
     component.dateTime = new DateTimeModel();
   });
 
@@ -58,4 +62,40 @@
     expect(newDateTime.minute).toEqual(dateTime.minute);
     expect(newDateTime.second).toEqual(dateTime.second);
   });
+
+  it('should has providers and call getWeekdayShortName(weekday: number)', () => {
+    const selectMonday = customDatePicker.getWeekdayShortName(1);
+    expect(selectMonday).toEqual('Mo');
+  });
+  it('should has providers and call getMonthShortName(month: number)', () => {
+    const selectJanuary = customDatePicker.getMonthShortName(1);
+    expect(selectJanuary).toEqual('Jan');
+  });
+  it('should has providers and call getMonthFullName(month: number)', () => {
+    const selectJanuary = customDatePicker.getMonthFullName(1);
+    expect(selectJanuary).toEqual('Jan');
+  });
+  it('should has providers and call getDayAriaLabel(date: NgbDateStruct)', () => {
+    const date = {
+      year: 2001,
+      month: 1,
+      day: 1,
+    };
+    const getDate = customDatePicker.getDayAriaLabel(date);
+    expect(getDate).toEqual('1-1-2001');
+  });
+  it('should call changeDate() and check if it works', () => {
+    component.dateTime = null;
+    const date = {
+      year: 2001,
+      month: 1,
+      day: 1,
+    };
+    component.changeDate(date);
+    expect(component.dateTime).not.toBe(null);
+  });
+  it('should call set dateString() and check if it works', async(() => {
+    component.dateString = null;
+    expect(component.dateTime).toBe(null);
+  }));
 });
diff --git a/projects/grid-failure-information-app/src/app/shared/components/date-time-picker/date-time-picker.component.ts b/projects/grid-failure-information-app/src/app/shared/components/date-time-picker/date-time-picker.component.ts
index 2101afd..d48fd7d 100644
--- a/projects/grid-failure-information-app/src/app/shared/components/date-time-picker/date-time-picker.component.ts
+++ b/projects/grid-failure-information-app/src/app/shared/components/date-time-picker/date-time-picker.component.ts
@@ -10,14 +10,40 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  ********************************************************************************/
-import { Component, Input, Output, EventEmitter } from '@angular/core';
-import { NgbTimeStruct, NgbPopoverConfig, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap';
+import { Component, Input, Output, EventEmitter, Injectable } from '@angular/core';
+import { NgbTimeStruct, NgbPopoverConfig, NgbDateStruct, NgbDatepickerI18n } from '@ng-bootstrap/ng-bootstrap';
 import { DateTimeModel } from '@grid-failure-information-app/shared/models/date-time.model';
 
+@Injectable()
+export class CustomDatepickerI18n extends NgbDatepickerI18n {
+  private readonly _I18N_VALUES = {
+    weekdays: ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'],
+    months: ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
+  };
+  constructor() {
+    super();
+  }
+
+  public getWeekdayShortName(weekday: number): string {
+    return this._I18N_VALUES.weekdays[weekday - 1];
+  }
+  public getMonthShortName(month: number): string {
+    return this._I18N_VALUES.months[month - 1];
+  }
+  public getMonthFullName(month: number): string {
+    return this.getMonthShortName(month);
+  }
+
+  public getDayAriaLabel(date: NgbDateStruct): string {
+    return `${date.day}-${date.month}-${date.year}`;
+  }
+}
+
 @Component({
   selector: 'app-date-time-picker',
   templateUrl: './date-time-picker.component.html',
   styleUrls: ['./date-time-picker.component.scss'],
+  providers: [{ provide: NgbDatepickerI18n, useClass: CustomDatepickerI18n }],
 })
 export class DateTimePickerComponent {
   model: NgbDateStruct;
diff --git a/projects/grid-failure-information-app/src/app/shared/models/date-time.model.ts b/projects/grid-failure-information-app/src/app/shared/models/date-time.model.ts
index 234511a..04b5152 100644
--- a/projects/grid-failure-information-app/src/app/shared/models/date-time.model.ts
+++ b/projects/grid-failure-information-app/src/app/shared/models/date-time.model.ts
@@ -1,6 +1,16 @@
-import { getData } from './../store/reducers/grid-failures/grid-failure-versions.reducer';
+/********************************************************************************
+ * 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 { NgbTimeStruct, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap';
-import { DatePipe } from '@angular/common';
 
 export interface NgbDateTimeStruct extends NgbDateStruct, NgbTimeStruct {}
 
diff --git a/projects/grid-failure-information-app/src/app/shared/models/server-side.model.ts b/projects/grid-failure-information-app/src/app/shared/models/server-side.model.ts
index 4085140..98cac3f 100644
--- a/projects/grid-failure-information-app/src/app/shared/models/server-side.model.ts
+++ b/projects/grid-failure-information-app/src/app/shared/models/server-side.model.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
  * Copyright (c) 2020 Contributors to the Eclipse Foundation
  *
  * See the NOTICE file(s) distributed with this work for additional
@@ -10,13 +10,11 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  ********************************************************************************/
-import { Action } from '@ngrx/store';
-
 export class ServerSideModel {
   loadAction: any;
   successAction?: any;
   pageSize?: number;
-  filter?:any;
+  filter?: any;
 
   constructor() {}
 }
diff --git a/projects/grid-failure-information-app/src/app/shared/pipes/ngb-date-custom-parser-formatter.spec.ts b/projects/grid-failure-information-app/src/app/shared/pipes/ngb-date-custom-parser-formatter.spec.ts
index 21f4fa3..57ce33c 100644
--- a/projects/grid-failure-information-app/src/app/shared/pipes/ngb-date-custom-parser-formatter.spec.ts
+++ b/projects/grid-failure-information-app/src/app/shared/pipes/ngb-date-custom-parser-formatter.spec.ts
@@ -1,4 +1,17 @@
-import { NgbDateCustomParserFormatter, toInteger } from '@grid-failure-information-app/shared/pipes/ngb-date-custom-parser-formatter';
+/********************************************************************************
+ * 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 { DateTimeModel } from '@grid-failure-information-app/shared/models/date-time.model';
+import { NgbDateCustomParserFormatter } from '@grid-failure-information-app/shared/pipes/ngb-date-custom-parser-formatter';
 
 describe('NgbDateCustomParserFormatter', () => {
   let service: NgbDateCustomParserFormatter;
@@ -11,8 +24,48 @@
     expect(service).toBeTruthy();
   });
 
-  it('should parse string to Integer via toInteger()', () => {
-    let testValue = toInteger('1');
-    expect(testValue).toBe(parseInt(`${1}`, 10));
+  it('should format a date to string', () => {
+    const date: DateTimeModel = new DateTimeModel();
+    date.year = 2020;
+    date.month = 4;
+    date.day = 1;
+    date.hour = 12;
+    date.minute = 30;
+    date.second = 30;
+    expect(service.format(date)).toBe('01.04.2020 / 00:00');
+  });
+
+  it('should parse a string with 1 part into a date', () => {
+    const stringDate: string = '01';
+    expect(service.parse(stringDate)).toEqual(Object({ day: 1, month: null, year: null, hour: null, minute: null, second: null }));
+  });
+
+  it('should parse a string with 2 parts into a date', () => {
+    const stringDate: string = '01/04';
+    expect(service.parse(stringDate)).toEqual(Object({ day: 1, month: 4, year: null, hour: null, minute: null, second: null }));
+  });
+
+  it('should parse a string with 3 parts into a date', () => {
+    const stringDate: string = '01/04/2020';
+    expect(service.parse(stringDate)).toEqual(Object({ day: 1, month: 4, year: 2020, hour: null, minute: null, second: null }));
+  });
+
+  it('should parse a string with 4 parts into a date', () => {
+    const stringDate: string = '01/04/2020/12';
+    expect(service.parse(stringDate)).toEqual(Object({ day: 1, month: 4, year: 2020, hour: 12, minute: null, second: null }));
+  });
+
+  it('should parse a string with 5 parts into a date', () => {
+    const stringDate: string = '01/04/2020/12/30';
+    expect(service.parse(stringDate)).toEqual(Object({ day: 1, month: 4, year: 2020, hour: 12, minute: 30, second: null }));
+  });
+
+  it('should parse a string with 6 parts into a date', () => {
+    const stringDate: string = '01/04/2020/12/30/30';
+    expect(service.parse(stringDate)).toEqual(Object({ day: 1, month: 4, year: 2020, hour: 12, minute: 30, second: 30 }));
+  });
+
+  it('should return null parse called without value', () => {
+    expect(service.parse(null)).toEqual(null);
   });
 });
diff --git a/projects/grid-failure-information-app/src/app/shared/pipes/ngb-date-custom-parser-formatter.ts b/projects/grid-failure-information-app/src/app/shared/pipes/ngb-date-custom-parser-formatter.ts
index 1118ebe..bb51e4f 100644
--- a/projects/grid-failure-information-app/src/app/shared/pipes/ngb-date-custom-parser-formatter.ts
+++ b/projects/grid-failure-information-app/src/app/shared/pipes/ngb-date-custom-parser-formatter.ts
@@ -1,7 +1,19 @@
-import { DateTimeModel } from './../models/date-time.model';
+/********************************************************************************
+ * 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 { NgbDateParserFormatter } from '@ng-bootstrap/ng-bootstrap';
 import { Injectable } from '@angular/core';
-import { NgbDateTimeStruct } from '../models/date-time.model';
+import { NgbDateTimeStruct } from '@grid-failure-information-app/shared/models/date-time.model';
+import { toInteger, isNumber, padNumber } from '@grid-failure-information-app/shared/utility';
 
 @Injectable()
 export class NgbDateCustomParserFormatter extends NgbDateParserFormatter {
@@ -77,18 +89,3 @@
       : '';
   }
 }
-export function toInteger(value: any): number {
-  return parseInt(`${value}`, 10);
-}
-
-export function isNumber(value: any): value is number {
-  return !isNaN(toInteger(value));
-}
-
-export function padNumber(value: number) {
-  if (isNumber(value)) {
-    return `0${value}`.slice(-2);
-  } else {
-    return '';
-  }
-}
diff --git a/projects/grid-failure-information-app/src/app/shared/pipes/unique.pipe.spec.ts b/projects/grid-failure-information-app/src/app/shared/pipes/unique.pipe.spec.ts
index 2063a44..7aaa568 100644
--- a/projects/grid-failure-information-app/src/app/shared/pipes/unique.pipe.spec.ts
+++ b/projects/grid-failure-information-app/src/app/shared/pipes/unique.pipe.spec.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
  * Copyright (c) 2020 Contributors to the Eclipse Foundation
  *
  * See the NOTICE file(s) distributed with this work for additional
@@ -14,7 +14,6 @@
 import { UniquePipe } from './unique.pipe';
 
 describe('Pipe: Uniquee', () => {
-
   let uniquePipe: UniquePipe;
 
   // synchronous beforeEach
@@ -27,7 +26,6 @@
   });
 
   it('should return empty array if no items given', () => {
-
     const items = [];
 
     const filtered = uniquePipe.transform(items, 'filedNameText');
@@ -37,7 +35,6 @@
   });
 
   it('should return empty array if no items given (2)', () => {
-
     const items = [];
     items.push({ branch: 'W', title: 'its a test title', statusId: '3', createUser: 'otto' });
 
@@ -47,7 +44,6 @@
   });
 
   it('should return empty array if items are undefined', () => {
-
     const items = undefined;
     const filtered = uniquePipe.transform(items, 'filedNameText');
 
@@ -55,4 +51,19 @@
     expect(filtered).toEqual([]);
   });
 
+  it('should return the whole input array if all items are defined and unique', () => {
+    const items = [{ test: '1' }, { test: '2' }, { test: '3' }];
+    const filtered = uniquePipe.transform(items, 'test');
+
+    expect(filtered.length).toBe(3);
+    expect(filtered).toEqual([{ test: '1' }, { test: '2' }, { test: '3' }]);
+  });
+
+  it('should return only the unique elements of the input array', () => {
+    const items = [{ test: '1' }, { test: '2' }, { test: '3' }, { test: '3' }];
+    const filtered = uniquePipe.transform(items, 'test');
+
+    expect(filtered.length).toBe(3);
+    expect(filtered).toEqual([{ test: '1' }, { test: '2' }, { test: '3' }]);
+  });
 });
diff --git a/projects/grid-failure-information-app/src/app/shared/utility/utilityHelpers.spec.ts b/projects/grid-failure-information-app/src/app/shared/utility/utilityHelpers.spec.ts
index 02507d9..bbeb8f9 100644
--- a/projects/grid-failure-information-app/src/app/shared/utility/utilityHelpers.spec.ts
+++ b/projects/grid-failure-information-app/src/app/shared/utility/utilityHelpers.spec.ts
@@ -19,4 +19,35 @@
     utilityHelpers.navigateHome(router);
     expect(spy).toHaveBeenCalledWith('/grid-failures');
   });
+
+  it('should parse string to Integer via toInteger()', () => {
+    let testValue = utilityHelpers.toInteger('1');
+    expect(testValue).toBe(parseInt(`${1}`, 10));
+  });
+
+  it('should return true if a value is a number', () => {
+    let testValue = utilityHelpers.isNumber('1');
+    expect(testValue).toBe(true);
+  });
+
+  it('should return false if a value is not a number', () => {
+    let testValue = utilityHelpers.isNumber('a');
+    expect(testValue).toBe(false);
+  });
+
+  it('should pad the number if a value is a number', () => {
+    let testValue = utilityHelpers.padNumber(1);
+    expect(testValue).toBe('01');
+  });
+
+  it('should return empty string if a value is not a number', () => {
+    let testValue = utilityHelpers.padNumber(null);
+    expect(testValue).toBe('');
+  });
+
+  it('should convert a string date to a german date string', () => {
+    const dateString: string = '2020-12-01';
+    let testValue = utilityHelpers.localeDateString(dateString);
+    expect(testValue).toBe('1.12.2020');
+  });
 });
diff --git a/projects/grid-failure-information-app/src/app/shared/utility/utilityHelpers.ts b/projects/grid-failure-information-app/src/app/shared/utility/utilityHelpers.ts
index 057ce53..d845f3b 100644
--- a/projects/grid-failure-information-app/src/app/shared/utility/utilityHelpers.ts
+++ b/projects/grid-failure-information-app/src/app/shared/utility/utilityHelpers.ts
@@ -19,7 +19,7 @@
  * @param dateString
  * @param culture
  */
-export function localeDateString(dateString: string, culture: string = 'en-EN'): string {
+export function localeDateString(dateString: string, culture: string = 'de-DE'): string {
   let date = new Date(dateString);
   return date.toLocaleDateString(culture);
 }
diff --git a/proxy.conf-integration.json b/proxy.conf-integration.json
index 4539591..a45f017 100644
--- a/proxy.conf-integration.json
+++ b/proxy.conf-integration.json
@@ -1,6 +1,6 @@
 {
   "/api": {
-    "target": "http://entdockergss:9166/",
+    "target": "http://entdockergss:9165/",
     "secure": false,
     "pathRewrite": {
       "^/api": ""
diff --git a/sonar-project.properties b/sonar-project.properties
index 351f0b9..5d483ef 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -10,7 +10,7 @@
 
 sonar.sourceEncoding=UTF-8
 sonar.sources=projects/grid-failure-information-app/src, projects/openk/grid-failure-information-map/src
-sonar.exclusions=**/node_modules/**,projects/grid-failure-information-app/src/environments/**,e2e/*.ts,**/*.spec.ts,**/test-data/*.ts,**/testing/*.ts,**/assets/js/*.js,**/*.model.*,**/*.action.*,**/*.module.*,**/*column-definition*,**/*animation*,**/*api-client.*,**/styles.scss
+sonar.exclusions=**/node_modules/**,**/environments/**,e2e/*.ts,**/*.spec.ts,**/test-data/*.ts,**/testing/*.ts,**/assets/**/*,**/*.model.*,**/*.action.*,**/*.module.*,**/*column-definition*,**/*animation*,**/*api-client.*,**/styles.scss
 sonar.tests=projects/grid-failure-information-app/src, projects/openk/grid-failure-information-map/src
 sonar.test.inclusions=**/*.spec.ts
 sonar.test.exclusions=