Adds button to export all user emails (as admin)

This commit is contained in:
apapachristou 2020-10-07 16:35:23 +03:00
parent f4f3099b50
commit 7439281c50
10 changed files with 84 additions and 29 deletions

View File

@ -1,4 +1,4 @@
import { HttpHeaders } from '@angular/common/http'; import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { environment } from '../../../../environments/environment'; import { environment } from '../../../../environments/environment';
@ -15,7 +15,7 @@ export class UserService {
private actionUrl: string; private actionUrl: string;
private headers: HttpHeaders; private headers: HttpHeaders;
constructor(private http: BaseHttpService, private configurationService: ConfigurationService) { constructor(private http: BaseHttpService, private httpClient: HttpClient, private configurationService: ConfigurationService) {
this.actionUrl = configurationService.server + 'user/'; this.actionUrl = configurationService.server + 'user/';
} }
@ -62,4 +62,9 @@ export class UserService {
const url = this.actionUrl + 'deleteDOIToken'; const url = this.actionUrl + 'deleteDOIToken';
return this.http.delete(url, { headers: this.headers }); return this.http.delete(url, { headers: this.headers });
} }
downloadCSV(): Observable<HttpResponse<Blob>> {
let headerCsv: HttpHeaders = this.headers.set('Content-Type', 'application/csv')
return this.httpClient.get(this.actionUrl + 'getCsv/', { responseType: 'blob', observe: 'response', headers: headerCsv });
}
} }

View File

@ -2,6 +2,9 @@
<div class="container-fluid user-listing"> <div class="container-fluid user-listing">
<h3>{{'USERS.LISTING.TITLE' | translate}}</h3> <h3>{{'USERS.LISTING.TITLE' | translate}}</h3>
<div class="d-flex mb-3"><button mat-raised-button type="button" class="export-btn ml-auto" (click)="exportUsers()">
<mat-icon class="mr-2 export-icon">save_alt</mat-icon>{{'USERS.LISTING.EXPORT' | translate}}
</button></div>
<app-user-criteria-component></app-user-criteria-component> <app-user-criteria-component></app-user-criteria-component>
<mat-card class="mat-card"> <mat-card class="mat-card">
<mat-table [dataSource]="dataSource" matSort> <mat-table [dataSource]="dataSource" matSort>

View File

@ -15,6 +15,16 @@
background-color: #0c748914; background-color: #0c748914;
// background-color: #eef0fb; // background-color: #eef0fb;
} }
.export-btn {
background: #129D99 0% 0% no-repeat padding-box;
border-radius: 30px;
color: #ffffff;
}
.export-icon {
font-size: 20px;
}
} }
::ng-deep .mat-paginator-container { ::ng-deep .mat-paginator-container {

View File

@ -1,7 +1,7 @@
import {of as observableOf, merge as observableMerge, Observable } from 'rxjs'; import {of as observableOf, merge as observableMerge, Observable } from 'rxjs';
import {map, catchError, switchMap, startWith} from 'rxjs/operators'; import {map, catchError, switchMap, startWith, takeUntil} from 'rxjs/operators';
import { DataSource } from '@angular/cdk/table'; import { DataSource } from '@angular/cdk/table';
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core'; import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator'; import { MatPaginator } from '@angular/material/paginator';
@ -15,6 +15,8 @@ import { SnackBarNotificationComponent } from '../../../../library/notification/
import { DataTableRequest } from '../../../../core/model/data-table/data-table-request'; import { DataTableRequest } from '../../../../core/model/data-table/data-table-request';
import { UserCriteriaComponent } from './criteria/user-criteria.component'; import { UserCriteriaComponent } from './criteria/user-criteria.component';
import { BreadcrumbItem } from '../../../misc/breadcrumb/definition/breadcrumb-item'; import { BreadcrumbItem } from '../../../misc/breadcrumb/definition/breadcrumb-item';
import { BaseComponent } from '@common/base/base.component';
import * as FileSaver from 'file-saver';
export class UsersDataSource extends DataSource<UserListingModel> { export class UsersDataSource extends DataSource<UserListingModel> {
@ -93,7 +95,7 @@ export class UsersDataSource extends DataSource<UserListingModel> {
templateUrl: './user-listing.component.html', templateUrl: './user-listing.component.html',
styleUrls: ['./user-listing.component.scss'] styleUrls: ['./user-listing.component.scss']
}) })
export class UserListingComponent implements OnInit, AfterViewInit { export class UserListingComponent extends BaseComponent implements OnInit, AfterViewInit {
@ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator; @ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator;
@ViewChild(MatSort, { static: true }) sort: MatSort; @ViewChild(MatSort, { static: true }) sort: MatSort;
@ -108,7 +110,7 @@ export class UserListingComponent implements OnInit, AfterViewInit {
private languageService: TranslateService, private languageService: TranslateService,
public snackBar: MatSnackBar public snackBar: MatSnackBar
) { ) {
super();
} }
ngOnInit() { ngOnInit() {
@ -138,4 +140,33 @@ export class UserListingComponent implements OnInit, AfterViewInit {
const defaultCriteria = new UserCriteria(); const defaultCriteria = new UserCriteria();
return defaultCriteria; return defaultCriteria;
} }
// Export user mails
exportUsers(){
this.userService.downloadCSV()
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
const blob = new Blob([response.body], { type: 'application/csv' });
const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
});
}
getFilenameFromContentDispositionHeader(header: string): string {
const regex: RegExp = new RegExp(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/g);
const matches = header.match(regex);
let filename: string;
for (let i = 0; i < matches.length; i++) {
const match = matches[i];
if (match.includes('filename="')) {
filename = match.substring(10, match.length - 1);
break;
} else if (match.includes('filename=')) {
filename = match.substring(9);
break;
}
}
return filename;
}
} }

View File

@ -89,7 +89,7 @@
"INVITATION-DIALOG": { "INVITATION-DIALOG": {
"HINT": "Press comma or enter between authors", "HINT": "Press comma or enter between authors",
"SUCCESS": "Invitation successfully sent", "SUCCESS": "Invitation successfully sent",
"ERROR": "Invitation sent failed" "ERROR": "Invitation sent failed"
}, },
"DMP-TO-DATASET-DIALOG": { "DMP-TO-DATASET-DIALOG": {
"FROM-DMP": "You have successfully created your", "FROM-DMP": "You have successfully created your",
@ -1068,7 +1068,8 @@
"LABEL": "Label", "LABEL": "Label",
"ROLES": "Rollen", "ROLES": "Rollen",
"NAME": "Name", "NAME": "Name",
"PERMISSIONS": "Berechtigungen" "PERMISSIONS": "Berechtigungen",
"EXPORT": "Export users"
} }
}, },
"TYPES": { "TYPES": {
@ -1535,4 +1536,4 @@
"DRAFT": "Draft", "DRAFT": "Draft",
"FINALIZED": "Finalized" "FINALIZED": "Finalized"
} }
} }

View File

@ -1068,7 +1068,8 @@
"LABEL": "Label", "LABEL": "Label",
"ROLES": "Roles", "ROLES": "Roles",
"NAME": "Name", "NAME": "Name",
"PERMISSIONS": "Permissions" "PERMISSIONS": "Permissions",
"EXPORT": "Export users"
} }
}, },
"TYPES": { "TYPES": {

View File

@ -1068,7 +1068,8 @@
"LABEL": "Etiqueta", "LABEL": "Etiqueta",
"ROLES": "Función", "ROLES": "Función",
"NAME": "Nombre", "NAME": "Nombre",
"PERMISSIONS": "Permisos" "PERMISSIONS": "Permisos",
"EXPORT": "Export users"
} }
}, },
"TYPES": { "TYPES": {
@ -1535,4 +1536,4 @@
"DRAFT": "Borrador", "DRAFT": "Borrador",
"FINALIZED": "Finalizado" "FINALIZED": "Finalizado"
} }
} }

View File

@ -1068,7 +1068,8 @@
"LABEL": "Ετικέτα", "LABEL": "Ετικέτα",
"ROLES": "Ρόλος", "ROLES": "Ρόλος",
"NAME": "Όνομα", "NAME": "Όνομα",
"PERMISSIONS": "ʼδειες" "PERMISSIONS": "ʼδειες",
"EXPORT": "Export users"
} }
}, },
"TYPES": { "TYPES": {
@ -1535,4 +1536,4 @@
"DRAFT": "Πρόχειρα", "DRAFT": "Πρόχειρα",
"FINALIZED": "Οριστικοποιημένα" "FINALIZED": "Οριστικοποιημένα"
} }
} }

View File

@ -155,7 +155,7 @@
"LANGUAGE-EDITOR": "Úprava jazyka", "LANGUAGE-EDITOR": "Úprava jazyka",
"GUIDE-EDITOR": "Úprava používateľskej príručky", "GUIDE-EDITOR": "Úprava používateľskej príručky",
"LANGUAGE": "Jazyk", "LANGUAGE": "Jazyk",
"SIGN-IN": "Sign in to account" "SIGN-IN": "Sign in to account"
}, },
"FILE-TYPES": { "FILE-TYPES": {
"PDF": "PDF", "PDF": "PDF",
@ -427,7 +427,7 @@
}, },
"DMP-LISTING": { "DMP-LISTING": {
"DMP": "DMP", "DMP": "DMP",
"GRANT": "Grant", "GRANT": "Grant",
"TITLE": "Data Management Plány (DMP)", "TITLE": "Data Management Plány (DMP)",
"OWNER": "Vlastník", "OWNER": "Vlastník",
"MEMBER": "Člen", "MEMBER": "Člen",
@ -441,7 +441,7 @@
"TEXT-INFO-QUESTION": "Not sure how a DMP looks in practice? Browse Public DMPs and", "TEXT-INFO-QUESTION": "Not sure how a DMP looks in practice? Browse Public DMPs and",
"LINK-ZENODO": "LIBER community in Zenodo", "LINK-ZENODO": "LIBER community in Zenodo",
"GET-IDEA": "to get an idea!", "GET-IDEA": "to get an idea!",
"SORT-BY": "Sort by", "SORT-BY": "Sort by",
"COLUMNS": { "COLUMNS": {
"NAME": "Názov", "NAME": "Názov",
"GRANT": "Grant", "GRANT": "Grant",
@ -591,16 +591,16 @@
}, },
"DMP-OVERVIEW": { "DMP-OVERVIEW": {
"GRANT": "Grant", "GRANT": "Grant",
"DMP-AUTHORS": "DΜP Authors", "DMP-AUTHORS": "DΜP Authors",
"RESEARCHERS": "Výskumníci", "RESEARCHERS": "Výskumníci",
"DATASETS-USED": "Datasets used", "DATASETS-USED": "Datasets used",
"COLLABORATORS": "Spolupracovníci", "COLLABORATORS": "Spolupracovníci",
"PUBLIC": "Public", "PUBLIC": "Public",
"PRIVATE": "Private", "PRIVATE": "Private",
"LOCKED": "Locked", "LOCKED": "Locked",
"UNLOCKED": "Unlocked", "UNLOCKED": "Unlocked",
"YOU": "you", "YOU": "you",
"LOCK": "Lock", "LOCK": "Lock",
"TOOLTIP": { "TOOLTIP": {
"LEVEL-OF-ACCESS": "Úroveň prístupu", "LEVEL-OF-ACCESS": "Úroveň prístupu",
"INVOLVED-DATASETS": "Zapojené popisy Datasetu", "INVOLVED-DATASETS": "Zapojené popisy Datasetu",
@ -687,7 +687,7 @@
"GRANT": "Grant", "GRANT": "Grant",
"TEMPLATES-INVOLVED": "Šablóna popisu Datasetu" "TEMPLATES-INVOLVED": "Šablóna popisu Datasetu"
}, },
"EMPTY-LIST": "Nothing here yet." "EMPTY-LIST": "Nothing here yet."
}, },
"DATASET-PROFILE-LISTING": { "DATASET-PROFILE-LISTING": {
"TITLE": "Šablóny popisu Datasetu", "TITLE": "Šablóny popisu Datasetu",
@ -833,7 +833,7 @@
"PUBLICATION": "Publication Date", "PUBLICATION": "Publication Date",
"CONTACT": "Contact", "CONTACT": "Contact",
"COST": "Costs", "COST": "Costs",
"DATASETS": "Datasets" "DATASETS": "Datasets"
}, },
"ACTIONS": { "ACTIONS": {
"GO-TO-GRANT": "Prejsť na DMP Grantu", "GO-TO-GRANT": "Prejsť na DMP Grantu",
@ -843,7 +843,7 @@
"CANCEL": "Zrušiť", "CANCEL": "Zrušiť",
"DELETE": "Vymazať", "DELETE": "Vymazať",
"DELETE-DATASET": "Delete Dataset", "DELETE-DATASET": "Delete Dataset",
"DISCARD": "Discard", "DISCARD": "Discard",
"FINALISE": "Dokončiť", "FINALISE": "Dokončiť",
"LOCK": "DMP je uzamknutý iným používateľom", "LOCK": "DMP je uzamknutý iným používateľom",
"PERMISSION": "Nemáte povolenie na úpravu tohto DMP", "PERMISSION": "Nemáte povolenie na úpravu tohto DMP",
@ -1068,7 +1068,8 @@
"LABEL": "Označenie", "LABEL": "Označenie",
"ROLES": "Role", "ROLES": "Role",
"NAME": "Názov", "NAME": "Názov",
"PERMISSIONS": "Povolenia" "PERMISSIONS": "Povolenia",
"EXPORT": "Export users"
} }
}, },
"TYPES": { "TYPES": {
@ -1139,7 +1140,7 @@
"RESEARCHERS": "Researchers", "RESEARCHERS": "Researchers",
"ORGANIZATIONS": "Organizations", "ORGANIZATIONS": "Organizations",
"DATASET-IDENTIFIER": "Dataset Identifier", "DATASET-IDENTIFIER": "Dataset Identifier",
"CURRENCY": "Currency" "CURRENCY": "Currency"
}, },
"DATASET-PROFILE-COMBO-BOX-TYPE": { "DATASET-PROFILE-COMBO-BOX-TYPE": {
"WORD-LIST": "Zoznam slov", "WORD-LIST": "Zoznam slov",
@ -1162,7 +1163,7 @@
"MODIFIED": "Modified", "MODIFIED": "Modified",
"FINALIZED": "Finalized", "FINALIZED": "Finalized",
"PUBLISHED": "Published", "PUBLISHED": "Published",
"STATUS": "Status" "STATUS": "Status"
} }
}, },
"ADDRESEARCHERS-EDITOR": { "ADDRESEARCHERS-EDITOR": {
@ -1292,7 +1293,7 @@
}, },
"COOKIES-POLICY": { "COOKIES-POLICY": {
"TITLE": "Cookies Policy" "TITLE": "Cookies Policy"
}, },
"CONTACT": { "CONTACT": {
"SUPPORT": { "SUPPORT": {
"TITLE": "Kontaktovať podporu", "TITLE": "Kontaktovať podporu",
@ -1535,4 +1536,4 @@
"DRAFT": "Draft", "DRAFT": "Draft",
"FINALIZED": "Finalized" "FINALIZED": "Finalized"
} }
} }

View File

@ -1069,7 +1069,8 @@
"LABEL": "Etiket", "LABEL": "Etiket",
"ROLES": "Görevler", "ROLES": "Görevler",
"NAME": "İsim", "NAME": "İsim",
"PERMISSIONS": "İzinler" "PERMISSIONS": "İzinler",
"EXPORT": "Export users"
} }
}, },
"TYPES": { "TYPES": {
@ -1535,4 +1536,4 @@
"DRAFT": "Taslak", "DRAFT": "Taslak",
"FINALIZED": "Tamamlandı" "FINALIZED": "Tamamlandı"
} }
} }