diff --git a/dmp-frontend/src/app/core/services/user/user.service.ts b/dmp-frontend/src/app/core/services/user/user.service.ts index 27165ca96..0e938cb8b 100644 --- a/dmp-frontend/src/app/core/services/user/user.service.ts +++ b/dmp-frontend/src/app/core/services/user/user.service.ts @@ -1,4 +1,4 @@ -import { HttpHeaders } from '@angular/common/http'; +import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { environment } from '../../../../environments/environment'; @@ -15,7 +15,7 @@ export class UserService { private actionUrl: string; 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/'; } @@ -62,4 +62,9 @@ export class UserService { const url = this.actionUrl + 'deleteDOIToken'; return this.http.delete(url, { headers: this.headers }); } + + downloadCSV(): Observable> { + let headerCsv: HttpHeaders = this.headers.set('Content-Type', 'application/csv') + return this.httpClient.get(this.actionUrl + 'getCsv/', { responseType: 'blob', observe: 'response', headers: headerCsv }); + } } diff --git a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.html b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.html index b136f7f07..f0cf640ed 100644 --- a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.html +++ b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.html @@ -2,6 +2,9 @@

{{'USERS.LISTING.TITLE' | translate}}

+
diff --git a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss index 4f28a0670..e7a607be4 100644 --- a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss +++ b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss @@ -15,6 +15,16 @@ background-color: #0c748914; // 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 { diff --git a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.ts b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.ts index 36e12bdad..9debb9ee7 100644 --- a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.ts +++ b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.ts @@ -1,7 +1,7 @@ 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 { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core'; 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 { UserCriteriaComponent } from './criteria/user-criteria.component'; 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 { @@ -93,7 +95,7 @@ export class UsersDataSource extends DataSource { templateUrl: './user-listing.component.html', 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(MatSort, { static: true }) sort: MatSort; @@ -108,7 +110,7 @@ export class UserListingComponent implements OnInit, AfterViewInit { private languageService: TranslateService, public snackBar: MatSnackBar ) { - + super(); } ngOnInit() { @@ -138,4 +140,33 @@ export class UserListingComponent implements OnInit, AfterViewInit { const defaultCriteria = new UserCriteria(); 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; + } } diff --git a/dmp-frontend/src/assets/i18n/de.json b/dmp-frontend/src/assets/i18n/de.json index 5ee09c9d1..480e86136 100644 --- a/dmp-frontend/src/assets/i18n/de.json +++ b/dmp-frontend/src/assets/i18n/de.json @@ -89,7 +89,7 @@ "INVITATION-DIALOG": { "HINT": "Press comma or enter between authors", "SUCCESS": "Invitation successfully sent", - "ERROR": "Invitation sent failed" + "ERROR": "Invitation sent failed" }, "DMP-TO-DATASET-DIALOG": { "FROM-DMP": "You have successfully created your", @@ -1068,7 +1068,8 @@ "LABEL": "Label", "ROLES": "Rollen", "NAME": "Name", - "PERMISSIONS": "Berechtigungen" + "PERMISSIONS": "Berechtigungen", + "EXPORT": "Export users" } }, "TYPES": { @@ -1535,4 +1536,4 @@ "DRAFT": "Draft", "FINALIZED": "Finalized" } -} \ No newline at end of file +} diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index 1e2f10afa..5a582e9c3 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -1068,7 +1068,8 @@ "LABEL": "Label", "ROLES": "Roles", "NAME": "Name", - "PERMISSIONS": "Permissions" + "PERMISSIONS": "Permissions", + "EXPORT": "Export users" } }, "TYPES": { diff --git a/dmp-frontend/src/assets/i18n/es.json b/dmp-frontend/src/assets/i18n/es.json index 81465bab3..e3f893807 100644 --- a/dmp-frontend/src/assets/i18n/es.json +++ b/dmp-frontend/src/assets/i18n/es.json @@ -1068,7 +1068,8 @@ "LABEL": "Etiqueta", "ROLES": "Función", "NAME": "Nombre", - "PERMISSIONS": "Permisos" + "PERMISSIONS": "Permisos", + "EXPORT": "Export users" } }, "TYPES": { @@ -1535,4 +1536,4 @@ "DRAFT": "Borrador", "FINALIZED": "Finalizado" } -} \ No newline at end of file +} diff --git a/dmp-frontend/src/assets/i18n/gr.json b/dmp-frontend/src/assets/i18n/gr.json index 78dc76509..460cfb65a 100644 --- a/dmp-frontend/src/assets/i18n/gr.json +++ b/dmp-frontend/src/assets/i18n/gr.json @@ -1068,7 +1068,8 @@ "LABEL": "Ετικέτα", "ROLES": "Ρόλος", "NAME": "Όνομα", - "PERMISSIONS": "ʼδειες" + "PERMISSIONS": "ʼδειες", + "EXPORT": "Export users" } }, "TYPES": { @@ -1535,4 +1536,4 @@ "DRAFT": "Πρόχειρα", "FINALIZED": "Οριστικοποιημένα" } -} \ No newline at end of file +} diff --git a/dmp-frontend/src/assets/i18n/sk.json b/dmp-frontend/src/assets/i18n/sk.json index 26c3fbd5d..f81cf4aba 100644 --- a/dmp-frontend/src/assets/i18n/sk.json +++ b/dmp-frontend/src/assets/i18n/sk.json @@ -155,7 +155,7 @@ "LANGUAGE-EDITOR": "Úprava jazyka", "GUIDE-EDITOR": "Úprava používateľskej príručky", "LANGUAGE": "Jazyk", - "SIGN-IN": "Sign in to account" + "SIGN-IN": "Sign in to account" }, "FILE-TYPES": { "PDF": "PDF", @@ -427,7 +427,7 @@ }, "DMP-LISTING": { "DMP": "DMP", - "GRANT": "Grant", + "GRANT": "Grant", "TITLE": "Data Management Plány (DMP)", "OWNER": "Vlastník", "MEMBER": "Člen", @@ -441,7 +441,7 @@ "TEXT-INFO-QUESTION": "Not sure how a DMP looks in practice? Browse Public DMPs and", "LINK-ZENODO": "LIBER community in Zenodo", "GET-IDEA": "to get an idea!", - "SORT-BY": "Sort by", + "SORT-BY": "Sort by", "COLUMNS": { "NAME": "Názov", "GRANT": "Grant", @@ -591,16 +591,16 @@ }, "DMP-OVERVIEW": { "GRANT": "Grant", - "DMP-AUTHORS": "DΜP Authors", + "DMP-AUTHORS": "DΜP Authors", "RESEARCHERS": "Výskumníci", - "DATASETS-USED": "Datasets used", + "DATASETS-USED": "Datasets used", "COLLABORATORS": "Spolupracovníci", "PUBLIC": "Public", "PRIVATE": "Private", "LOCKED": "Locked", "UNLOCKED": "Unlocked", "YOU": "you", - "LOCK": "Lock", + "LOCK": "Lock", "TOOLTIP": { "LEVEL-OF-ACCESS": "Úroveň prístupu", "INVOLVED-DATASETS": "Zapojené popisy Datasetu", @@ -687,7 +687,7 @@ "GRANT": "Grant", "TEMPLATES-INVOLVED": "Šablóna popisu Datasetu" }, - "EMPTY-LIST": "Nothing here yet." + "EMPTY-LIST": "Nothing here yet." }, "DATASET-PROFILE-LISTING": { "TITLE": "Šablóny popisu Datasetu", @@ -833,7 +833,7 @@ "PUBLICATION": "Publication Date", "CONTACT": "Contact", "COST": "Costs", - "DATASETS": "Datasets" + "DATASETS": "Datasets" }, "ACTIONS": { "GO-TO-GRANT": "Prejsť na DMP Grantu", @@ -843,7 +843,7 @@ "CANCEL": "Zrušiť", "DELETE": "Vymazať", "DELETE-DATASET": "Delete Dataset", - "DISCARD": "Discard", + "DISCARD": "Discard", "FINALISE": "Dokončiť", "LOCK": "DMP je uzamknutý iným používateľom", "PERMISSION": "Nemáte povolenie na úpravu tohto DMP", @@ -1068,7 +1068,8 @@ "LABEL": "Označenie", "ROLES": "Role", "NAME": "Názov", - "PERMISSIONS": "Povolenia" + "PERMISSIONS": "Povolenia", + "EXPORT": "Export users" } }, "TYPES": { @@ -1139,7 +1140,7 @@ "RESEARCHERS": "Researchers", "ORGANIZATIONS": "Organizations", "DATASET-IDENTIFIER": "Dataset Identifier", - "CURRENCY": "Currency" + "CURRENCY": "Currency" }, "DATASET-PROFILE-COMBO-BOX-TYPE": { "WORD-LIST": "Zoznam slov", @@ -1162,7 +1163,7 @@ "MODIFIED": "Modified", "FINALIZED": "Finalized", "PUBLISHED": "Published", - "STATUS": "Status" + "STATUS": "Status" } }, "ADDRESEARCHERS-EDITOR": { @@ -1292,7 +1293,7 @@ }, "COOKIES-POLICY": { "TITLE": "Cookies Policy" - }, + }, "CONTACT": { "SUPPORT": { "TITLE": "Kontaktovať podporu", @@ -1535,4 +1536,4 @@ "DRAFT": "Draft", "FINALIZED": "Finalized" } -} \ No newline at end of file +} diff --git a/dmp-frontend/src/assets/i18n/tr.json b/dmp-frontend/src/assets/i18n/tr.json index dc9ec2ba8..927885e9e 100644 --- a/dmp-frontend/src/assets/i18n/tr.json +++ b/dmp-frontend/src/assets/i18n/tr.json @@ -1069,7 +1069,8 @@ "LABEL": "Etiket", "ROLES": "Görevler", "NAME": "İsim", - "PERMISSIONS": "İzinler" + "PERMISSIONS": "İzinler", + "EXPORT": "Export users" } }, "TYPES": { @@ -1535,4 +1536,4 @@ "DRAFT": "Taslak", "FINALIZED": "Tamamlandı" } -} \ No newline at end of file +}