[KON-13]: Total Commit

Signed-off-by: Dennis Schmitt <dennis.schmitt@pta.de>
diff --git a/i18n/contacts.de.json b/i18n/contacts.de.json
index dbe91b2..2906142 100644
--- a/i18n/contacts.de.json
+++ b/i18n/contacts.de.json
@@ -20,6 +20,8 @@
     "CommunicationsDataList": "Kommunikationskanäle",
     "ContactPersonList": "Ansprechpartner",
     "CommunicationsDataList": "Kommunikationskanäle",
-    "ModuleAssignment": "Modulzuordnung"
+    "ModuleAssignment": "Modulzuordnung",
+    "AllModuleAssignments": "Alle Modulzuordnungen",
+    "WithoutModuleAssignment": "Keine Modulzuordnung"
   }
 }
diff --git a/package.json b/package.json
index 602c2b6..67da642 100644
--- a/package.json
+++ b/package.json
@@ -17,9 +17,8 @@
     "sy-post-build": "node hooks/post-build.js",
     "sy-build": "npm run sy-pre-build && ng build --base-href /contactdatabase/ --prod --aot && npm run sy-post-build",
     "sy-build-noprod": "npm run sy-pre-build && ng build --base-href /contactdatabase/ && npm run sy-post-build",
-    "start-in-docker": "npm run sy-pre-start && ng serve --optimization=false --vendor-chunk --common-chunk --host=0.0.0.0 --disableHostCheck=true --proxy-config proxy-docker.conf.json",    
-	"start-in-docker-unsecure": "npm run sy-pre-start && ng serve --optimization=false --vendor-chunk --common-chunk --host=0.0.0.0 --disableHostCheck=true --proxy-config proxy-docker-unsecure.conf.json"
-
+    "start-in-docker": "npm run sy-pre-start && ng serve --optimization=false --vendor-chunk --common-chunk --host=0.0.0.0 --disableHostCheck=true --proxy-config proxy-docker.conf.json",
+    "start-in-docker-unsecure": "npm run sy-pre-start && ng serve --optimization=false --vendor-chunk --common-chunk --host=0.0.0.0 --disableHostCheck=true --proxy-config proxy-docker-unsecure.conf.json"
   },
   "private": true,
   "dependencies": {
diff --git a/src/app/pages/contacts/contacts-api-client.ts b/src/app/pages/contacts/contacts-api-client.ts
index e431d36..654e284 100644
--- a/src/app/pages/contacts/contacts-api-client.ts
+++ b/src/app/pages/contacts/contacts-api-client.ts
@@ -1,4 +1,4 @@
- /********************************************************************************
+/********************************************************************************
  * Copyright (c) 2020 Contributors to the Eclipse Foundation
  *
  * See the NOTICE file(s) distributed with this work for additional
@@ -22,19 +22,38 @@
 
 @Injectable()
 @DefaultHeaders({
-  'Accept': 'application/json',
+  Accept: 'application/json',
   'Content-Type': 'application/json',
 })
 export class ContactsApiClient extends HttpService {
   public getContacts(request: PageRequestInterface = null): Observable<PageModel<Contact>> {
     let modifiedContacts: ModifiedContacts = null;
-    if(request != null){
+    if (request != null) {
       modifiedContacts = request.queryParameter || {};
-      return this._getContactsPage(modifiedContacts.searchText, modifiedContacts.contactTypeId, modifiedContacts.sort, request.pageNumber ? (request.pageNumber - 1) : 0, request.pageSize);
+      return this._getContactsPage(
+        modifiedContacts.searchText,
+        modifiedContacts.contactTypeId,
+        modifiedContacts.sort,
+        modifiedContacts.moduleName,
+        modifiedContacts.withoutAssignedModule,
+        modifiedContacts.expiringDataInPast,
+        modifiedContacts.deletionLockExceeded,
+        request.pageNumber ? request.pageNumber - 1 : 0,
+        request.pageSize
+      );
     } else {
-      return this._getContactsPage(modifiedContacts.searchText, modifiedContacts.contactTypeId, modifiedContacts.sort, 1, 3);
+      return this._getContactsPage(
+        modifiedContacts.searchText,
+        modifiedContacts.contactTypeId,
+        modifiedContacts.sort,
+        modifiedContacts.moduleName,
+        modifiedContacts.withoutAssignedModule,
+        modifiedContacts.expiringDataInPast,
+        modifiedContacts.deletionLockExceeded,
+        1,
+        3
+      );
     }
-    
   }
 
   /**
@@ -42,7 +61,17 @@
    */
   @GET('/contacts')
   @Adapter(ContactsService.gridPageAdapter)
-  private _getContactsPage(@Query('searchText') searchtext: string, @Query('contactType') contactTypeId: string, @Query('sort') sort: string, @Query('page') pageNumber: number, @Query('size') pageSize: number): Observable<any> {
+  private _getContactsPage(
+    @Query('searchText') searchtext: string,
+    @Query('contactType') contactTypeId: string,
+    @Query('sort') sort: string,
+    @Query('moduleName') moduleName: string,
+    @Query('withoutAssignedModule') withoutAssignedModule: boolean,
+    @Query('expiringDataInPast') expiringDataInPast: boolean,
+    @Query('deletionLockExceeded') deletionLockExceeded: boolean,
+    @Query('page') pageNumber: number,
+    @Query('size') pageSize: number
+  ): Observable<any> {
     return null;
   }
 
diff --git a/src/app/pages/contacts/contacts-list/contacts-list.component.html b/src/app/pages/contacts/contacts-list/contacts-list.component.html
index ba03537..06cdb55 100644
--- a/src/app/pages/contacts/contacts-list/contacts-list.component.html
+++ b/src/app/pages/contacts/contacts-list/contacts-list.component.html
@@ -16,34 +16,70 @@
   </div>
   <div class="contacts-grid-wrapper" body>
     <div class="diverse-options">
-      <div class="searching diverse-options-item">
-        <div class="search-options">
-          <input
-            type="text"
-            class="item"
-            id="searchText"
-            placeholder="Suche"
-            (keyup)="setModifiedContactsSearchText($event.target.value); searchContacts($event)"
-          />
+      <div class="search-options diverse-options-item">
+        <input
+          type="text"
+          class="item"
+          id="search-text"
+          placeholder="Suche"
+          (keyup)="setModifiedContactsSearchText($event.target.value); searchContacts($event)"
+        />
 
-          <select
-            [required]="false"
-            type="text"
-            class="form-control item"
-            (change)="setModifiedContactsContactTypeId($event.target.value); searchContacts($event)"
+        <select
+          [required]="false"
+          type="text"
+          class="form-control item"
+          (change)="setModifiedContactsContactTypeId($event.target.value); searchContacts($event)"
+        >
+          <option value="{{ INTERNAL_PERSON }}">{{ 'Contacts.InternalContact' | translate }}</option>
+          <option value="{{ EXTERNAL_PERSON }}">{{ 'Contacts.ExternalContact' | translate }}</option>
+          <option value="{{ COMPANY }}">{{ 'Contacts.Company' | translate }}</option>
+          <option value="" selected>{{ 'Contacts.AllContactTypes' | translate }}</option>
+        </select>
+
+        <div class="dsgvo-filter-container search-btn">
+          <button
+            type="button"
+            class="btn btn-default btn-sm"
+            (click)="isDSGVOFilterAdvancedVisible = !isDSGVOFilterAdvancedVisible"
+            title="DSGVO - Filtererweiterung"
           >
-            <option value="{{ INTERNAL_PERSON }}">{{ 'Contacts.InternalContact' | translate }}</option>
-            <option value="{{ EXTERNAL_PERSON }}">{{ 'Contacts.ExternalContact' | translate }}</option>
-            <option value="{{ COMPANY }}">{{ 'Contacts.Company' | translate }}</option>
-            <option value="" selected>{{ 'Contacts.AllContactTypes' | translate }}</option>
-          </select>
+            DSGVO
+          </button>
+          <div class="dsgvo-filter-options" *ngIf="isDSGVOFilterAdvancedVisible">
+            <select
+              [required]="false"
+              type="text"
+              class="form-control"
+              style="margin-right: 12px;"
+              (change)="setModifiedContactsModuleAssignmentFilter($event.target.value); searchContacts($event)"
+            >
+              <option *ngFor="let moduleType of userModuleAssignmentSandbox.userModuleTypes$ | async" [value]="moduleType.id">{{ moduleType.id }}</option>
+              <option [value]="'-1'">{{ 'Contacts.WithoutModuleAssignment' | translate }}</option>
+              <option [value]="''" selected>{{ 'Contacts.AllModuleAssignments' | translate }}</option>
+            </select>
 
-          <div class="search-btn">
-            <button type="button" class="btn btn-default btn-sm" (click)="searchContacts($event)" title="suchen">
-              <em class="fa fa-search fa-lg " aria-hidden="true "></em>
-            </button>
+            <div class="dsgvo-filter-item custom-control custom-switch" title="Filterung nach Kontakten mit überschrittenem Ablaufdatum">
+              <input type="checkbox" class="custom-control-input" id="expiry-date" (change)="setModifiedContactsExpiryDateFilter(); searchContacts($event)" />
+              <label class="custom-control-label" style="position: 0px;" for="expiry-date"></label>
+            </div>
+            <div class="dsgvo-filter-item custom-control custom-switch" title="Filterung nach Kontakten mit abgelaufener Löschsperre">
+              <input
+                type="checkbox"
+                class="custom-control-input"
+                id="deletion-lock-until"
+                (change)="setModifiedContactsDeletionLockExceedFilter(); searchContacts($event)"
+              />
+              <label class="custom-control-label" for="deletion-lock-until"></label>
+            </div>
           </div>
         </div>
+
+        <div class="search-btn">
+          <button type="button" class="btn btn-default btn-sm" (click)="searchContacts($event)" title="suchen">
+            <em class="fa fa-search fa-lg " aria-hidden="true "></em>
+          </button>
+        </div>
       </div>
 
       <div class="sorting-options diverse-options-item">
diff --git a/src/app/pages/contacts/contacts-list/contacts-list.component.scss b/src/app/pages/contacts/contacts-list/contacts-list.component.scss
index 83462b7..7b3ad89 100644
--- a/src/app/pages/contacts/contacts-list/contacts-list.component.scss
+++ b/src/app/pages/contacts/contacts-list/contacts-list.component.scss
@@ -46,24 +46,23 @@
   margin-right: 2px;
 }
 
-.searching {
-  display: flex;
-  flex-wrap: nowrap;
-  justify-content: flex-start;
-}
-
 .search-options {
   display: flex;
   flex-wrap: nowrap;
   justify-content: flex-start;
   align-items: center;
+  flex-grow: 1;
 }
 
 .item {
-  min-width: 170px;
+  flex-basis: 185px;
   margin: 5px;
 }
 
+#search-text {
+  max-width: 160px;
+}
+
 .search-btn {
   display: flex;
   align-items: center;
@@ -80,6 +79,7 @@
   flex-wrap: nowrap;
   justify-content: flex-start;
   align-items: center;
+  min-width: 380px;
 }
 
 .diverse-btn {
@@ -102,3 +102,21 @@
   margin-right: 2px;
   margin-bottom: 2px;
 }
+.dsgvo-filter-container {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  justify-content: flex-start;
+  justify-self: center;
+}
+.dsgvo-filter-options {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  justify-content: flex-start;
+  align-items: center;
+  flex-grow: 1;
+}
+.dsgvo-filter-item {
+  margin: 4px 0px 0px 12px;
+}
diff --git a/src/app/pages/contacts/contacts-list/contacts-list.component.ts b/src/app/pages/contacts/contacts-list/contacts-list.component.ts
index 99b8d8d..7d7064a 100644
--- a/src/app/pages/contacts/contacts-list/contacts-list.component.ts
+++ b/src/app/pages/contacts/contacts-list/contacts-list.component.ts
@@ -17,6 +17,8 @@
 import { Router } from '@angular/router';
 import { Globals } from '@shared/constants/globals';
 import { ModifiedContacts } from '@shared/models/modifiedContacts.model';
+import { UserModuleAssignmentSandBox } from './../../../shared/components/list-details-view/user-module-assignment/user-module-assignment.sandbox';
+import { ofType } from '@ngrx/effects';
 
 @Component({
   selector: 'app-contacts-list',
@@ -34,11 +36,14 @@
 
   public columnDefinition: any = CONTACTS_COLDEF;
   public modifiedContacts: ModifiedContacts = new ModifiedContacts();
+  public isDSGVOFilterAdvancedVisible = false;
 
   private _sortingOrder: string = 'asc';
   private _sortingContactType: string = '';
+  private _expiringDataInPast = false;
+  private _deletionLockExceeded = false;
 
-  constructor(public contactsSandbox: ContactsSandbox, private router: Router) {
+  constructor(public contactsSandbox: ContactsSandbox, public userModuleAssignmentSandbox: UserModuleAssignmentSandBox, private router: Router) {
     super();
   }
 
@@ -104,6 +109,29 @@
     this.modifiedContacts.contactTypeId = contactTypeId;
   }
 
+  public setModifiedContactsModuleAssignmentFilter(moduleName: string) {
+    if (moduleName === '-1') {
+      this.modifiedContacts.moduleName = null;
+      this.modifiedContacts.withoutAssignedModule = true;
+    } else if (moduleName == '') {
+      this.modifiedContacts.moduleName = null;
+      this.modifiedContacts.withoutAssignedModule = false;
+    } else {
+      this.modifiedContacts.moduleName = moduleName;
+      this.modifiedContacts.withoutAssignedModule = false;
+    }
+  }
+
+  public setModifiedContactsExpiryDateFilter() {
+    this._expiringDataInPast = !this._expiringDataInPast;
+    this.modifiedContacts.expiringDataInPast = this._expiringDataInPast;
+  }
+
+  public setModifiedContactsDeletionLockExceedFilter() {
+    this._deletionLockExceeded = !this._deletionLockExceeded;
+    this.modifiedContacts.deletionLockExceeded = this._deletionLockExceeded;
+  }
+
   public setSortingContactType(sortingContactType: string) {
     this._sortingContactType = sortingContactType;
   }
diff --git a/src/app/shared/components/list-details-view/user-module-assignment/details/details.component.html b/src/app/shared/components/list-details-view/user-module-assignment/details/details.component.html
index 69931c7..d88aa5e 100644
--- a/src/app/shared/components/list-details-view/user-module-assignment/details/details.component.html
+++ b/src/app/shared/components/list-details-view/user-module-assignment/details/details.component.html
@@ -31,7 +31,7 @@
       <div class="input-group col-sm-7">
         <div class="input-group-prepend">
           <button class="btn btn-outline-primary calendar" (click)="expiringDateCalendar.toggle()" type="button">
-            <i class="fa fa-calendar"></i>
+            <em class="fa fa-calendar"></em>
           </button>
         </div>
         <input
@@ -49,7 +49,7 @@
         />
         <div class="input-group-append">
           <button class="btn btn-outline-primary calendar" (click)="reset('expiringDate')" type="button">
-            <i class="fa fa-times-circle" aria-hidden="true"></i>
+            <em class="fa fa-times-circle" aria-hidden="true"></em>
           </button>
         </div>
       </div>
diff --git a/src/app/shared/models/modifiedContacts.model.ts b/src/app/shared/models/modifiedContacts.model.ts
index 886e071..e7817a9 100644
--- a/src/app/shared/models/modifiedContacts.model.ts
+++ b/src/app/shared/models/modifiedContacts.model.ts
@@ -1,15 +1,17 @@
 import { Contact } from '@shared/models';
 
 export class ModifiedContacts {
+  public searchText: string = null;
+  public contactTypeId: string = '';
+  public sort: string = null;
+  public moduleName: string = null;
+  public withoutAssignedModule: boolean = null;
+  public expiringDataInPast: boolean = null;
+  public deletionLockExceeded: boolean = null;
 
-    public searchText: string = null;
-    public contactTypeId: string = '';
-    public sort: string = null;
-  
-    public constructor(data: any = null) {
-      Object.keys(data || {})
-        .filter(property => this.hasOwnProperty(property))
-        .forEach(property => (this[property] = data[property]));
-    }
+  public constructor(data: any = null) {
+    Object.keys(data || {})
+      .filter(property => this.hasOwnProperty(property))
+      .forEach(property => (this[property] = data[property]));
   }
-  
\ No newline at end of file
+}