Merge branch 'KON-13-Uebersicht-kontakte-dsgvo' of ssh://git.eclipse.org:29418/openk-usermodules/org.eclipse.openk-usermodules.contactBaseData.frontend into DEVELOP
Signed-off-by: Dimitrios Chalepakis <dimitrios.chalepakis@pta.de>
diff --git a/i18n/contacts.de.json b/i18n/contacts.de.json
index dbe91b2..e1aa16e 100644
--- a/i18n/contacts.de.json
+++ b/i18n/contacts.de.json
@@ -20,6 +20,11 @@
"CommunicationsDataList": "Kommunikationskanäle",
"ContactPersonList": "Ansprechpartner",
"CommunicationsDataList": "Kommunikationskanäle",
- "ModuleAssignment": "Modulzuordnung"
+ "ModuleAssignment": "Modulzuordnung",
+ "AllModuleAssignments": "Alle Modulzuordnungen",
+ "WithoutModuleAssignment": "Keine Modulzuordnung",
+ "DSGVO-advanced-filter": "DSGVO - Filtererweiterung",
+ "DSGVO-advanced-filter-deletion-lock-exceeded": "Filterung nach Kontakten mit abgelaufener Löschsperre",
+ "DSGVO-advanced-filter-expiring-data-in-past": "Filterung nach Kontakten mit überschrittenem Ablaufdatum"
}
}
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 745f47e..f1eb052 100644
--- a/src/app/pages/contacts/contacts-api-client.ts
+++ b/src/app/pages/contacts/contacts-api-client.ts
@@ -34,11 +34,25 @@
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
+ );
}
}
@@ -51,6 +65,10 @@
@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> {
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..027e603 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,71 @@
</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="{{ 'Contacts.DSGVO-advanced-filter' | translate }}"
>
- <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="{{ 'Contacts.DSGVO-advanced-filter-expiring-data-in-past' | translate }}">
+ <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="{{ 'Contacts.DSGVO-advanced-filter-deletion-lock-exceeded' | translate }}">
+ <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.spec.ts b/src/app/pages/contacts/contacts-list/contacts-list.component.spec.ts
index 295e22f..222b05f 100644
--- a/src/app/pages/contacts/contacts-list/contacts-list.component.spec.ts
+++ b/src/app/pages/contacts/contacts-list/contacts-list.component.spec.ts
@@ -17,11 +17,12 @@
describe('ContactsListComponent', () => {
let component: ContactsListComponent;
let contactsSandbox: any = {};
+ let userModuleAssignmentSandbox: any = {};
let router: any = {};
beforeEach(() => {
router = { navigateByUrl() {}, navigate() {} } as any;
- component = new ContactsListComponent(contactsSandbox, router);
+ component = new ContactsListComponent(contactsSandbox, userModuleAssignmentSandbox, router);
});
it('should create', () => {
@@ -170,7 +171,7 @@
expect((component as any)._sortingOrder).toBe('asc');
});
- it('checks if function _setModifiedContactsSortProperty() works', () => {
+ it('checks if function _setModifiedContactsSort() works', () => {
component.setSortingContactType('name');
(component as any)._setModifiedContactsSort();
expect(component.modifiedContacts.sort).toBe('name,asc');
@@ -183,4 +184,31 @@
(component as any)._setModifiedContactsSort();
expect(component.modifiedContacts.sort).toBe(null);
});
+
+ it('checks if function setModifiedContactsExpiryDateFilter() works', () => {
+ expect(component.modifiedContacts.expiringDataInPast).toBeFalsy();
+ component.setModifiedContactsExpiryDateFilter();
+ expect(component.modifiedContacts.expiringDataInPast).toBeTruthy();
+ });
+
+ it('checks if function setModifiedContactsDeletionLockExceedFilter() works', () => {
+ expect(component.modifiedContacts.deletionLockExceeded).toBeFalsy();
+ component.setModifiedContactsDeletionLockExceedFilter();
+ expect(component.modifiedContacts.deletionLockExceeded).toBeTruthy();
+ });
+
+ it('checks if function setModifiedContactsModuleAssignmentFilter() works', () => {
+ let moduleName = '-1';
+ component.setModifiedContactsModuleAssignmentFilter(moduleName);
+ expect(component.modifiedContacts.moduleName).toBe(null);
+ expect(component.modifiedContacts.withoutAssignedModule).toBeTruthy();
+ moduleName = '';
+ component.setModifiedContactsModuleAssignmentFilter(moduleName);
+ expect(component.modifiedContacts.moduleName).toBe(null);
+ expect(component.modifiedContacts.withoutAssignedModule).toBeFalsy();
+ moduleName = 'Betriebstagebuch';
+ component.setModifiedContactsModuleAssignmentFilter(moduleName);
+ expect(component.modifiedContacts.moduleName).toBe(moduleName);
+ expect(component.modifiedContacts.withoutAssignedModule).toBeFalsy();
+ });
});
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..56a3d9e 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,32 @@
this.modifiedContacts.contactTypeId = contactTypeId;
}
+ public setModifiedContactsModuleAssignmentFilter(moduleName: string) {
+ if (moduleName === '-1') {
+ //show contacts without module assignments
+ this.modifiedContacts.moduleName = null;
+ this.modifiedContacts.withoutAssignedModule = true;
+ } else if (moduleName == '') {
+ //show contacts with all module assignments
+ this.modifiedContacts.moduleName = null;
+ this.modifiedContacts.withoutAssignedModule = false;
+ } else {
+ //show contacts with specific module assignments
+ 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
+}