diff --git a/dmp-frontend/src/app/core/model/dmp/dmp-listing.ts b/dmp-frontend/src/app/core/model/dmp/dmp-listing.ts index 060198a5c..6cc2e8dee 100644 --- a/dmp-frontend/src/app/core/model/dmp/dmp-listing.ts +++ b/dmp-frontend/src/app/core/model/dmp/dmp-listing.ts @@ -1,7 +1,7 @@ import { DmpStatus } from "../../common/enum/dmp-status"; export interface DmpListingModel { - id: String; + id: string; label: String; description: String; status: DmpStatus; diff --git a/dmp-frontend/src/app/ui/dashboard/dashboard.module.ts b/dmp-frontend/src/app/ui/dashboard/dashboard.module.ts index 04d764ec5..95dac0bc1 100644 --- a/dmp-frontend/src/app/ui/dashboard/dashboard.module.ts +++ b/dmp-frontend/src/app/ui/dashboard/dashboard.module.ts @@ -12,12 +12,14 @@ import { RecentVisitedActivityComponent } from './recent-visited-activity/recent import { WizardComponent } from './wizard/wizard.component'; import { DmpInfoCounterComponent } from './dmp-info-counter/dmp-info-counter.component'; import { DatasetInfoCounterComponent } from './dataset-info-counter/dataset-info-counter.component'; +import { ExportMethodDialogModule } from '../../library/export-method-dialog/export-method-dialog.module'; @NgModule({ imports: [ CommonUiModule, - DashboardRoutingModule + DashboardRoutingModule, + ExportMethodDialogModule ], declarations: [ DashboardComponent, diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.css b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.css index 3e20b81eb..77d54cc2c 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.css +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.css @@ -41,3 +41,7 @@ th { overflow: hidden; text-overflow: ellipsis; } + +.mat-icon-button :hover { + color: rgb(120, 173, 220); +} diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.html b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.html index 3a3435207..d2d70dead 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.html +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.html @@ -44,7 +44,27 @@ {{ enumUtils.toDmpStatusString(activity.status) }} {{ activity.modifiedTime | date: "shortDate" }} - more_horiz + + + + + + + + + + diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts index 75c1b4ea8..ca78faa1b 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts @@ -9,13 +9,20 @@ import { RecentActivityType } from '../../../core/common/enum/recent-activity-ty import { Router } from '@angular/router'; import { Principal } from '../../../core/model/auth/Principal'; import { TranslateService } from '@ngx-translate/core'; +import { ConfirmationDialogComponent } from '../../../library/confirmation-dialog/confirmation-dialog.component'; +import { MatDialog } from '@angular/material'; +import { ExportMethodDialogComponent } from '../../../library/export-method-dialog/export-method-dialog.component'; +import { BaseComponent } from '../../../core/common/base/base.component'; +import { UiNotificationService, SnackBarNotificationLevel } from '../../../core/services/notification/ui-notification-service'; +import * as FileSaver from 'file-saver'; +import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'app-recent-edited-activity', templateUrl: './recent-edited-activity.component.html', styleUrls: ['./recent-edited-activity.component.css'] }) -export class RecentEditedActivityComponent implements OnInit { +export class RecentEditedActivityComponent extends BaseComponent implements OnInit { dmpActivities: DmpListingModel[]; recentActivityTypeEnum = RecentActivityType; @@ -24,8 +31,12 @@ export class RecentEditedActivityComponent implements OnInit { public enumUtils: EnumUtils, private authentication: AuthService, private dmpService: DmpService, - private language: TranslateService - ) { } + private language: TranslateService, + private dialog: MatDialog, + private uiNotificationService: UiNotificationService + ) { + super(); + } ngOnInit() { if (this.isAuthenticated()) { @@ -45,6 +56,65 @@ export class RecentEditedActivityComponent implements OnInit { return !!this.authentication.current(); } + editClicked(dmp: DmpListingModel) { + this.router.navigate(['/plans/edit/' + dmp.id]); + } + + cloneClicked(dmp: DmpListingModel) { + this.router.navigate(['/plans/clone/' + dmp.id]); + } + + deleteClicked(dmp: DmpListingModel) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '300px', + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.dmpService.delete(dmp.id) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => { this.onCallbackSuccess() }, + error => this.onDeleteCallbackError(error) + ); + } + }); + } + + advancedClicked(dmp: DmpListingModel) { + const dialogRef = this.dialog.open(ExportMethodDialogComponent, { + maxWidth: '400px', + data: { + message: "Download as:", + XMLButton: "XML", + documentButton: "Document", + pdfButton: "PDF" + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result == "pdf") { + this.downloadPDF(dmp.id); + } else if (result == "xml") { + this.downloadXml(dmp.id); + } else if (result == "doc") { + this.downloadDocx(dmp.id); + } + }); + } + + onCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + this.router.navigate(['/plans']); + } + + onDeleteCallbackError(error) { + this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error); + } + redirect(id: string, type: RecentActivityType) { switch (type) { case RecentActivityType.Project: { @@ -95,4 +165,55 @@ export class RecentEditedActivityComponent implements OnInit { return "--"; } } + + downloadXml(id: string) { + this.dmpService.downloadXML(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/xml' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + + FileSaver.saveAs(blob, filename); + }); + } + + downloadDocx(id: string) { + this.dmpService.downloadDocx(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/msword' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + + FileSaver.saveAs(blob, filename); + }); + } + + downloadPDF(id: string) { + this.dmpService.downloadPDF(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/pdf' }); + 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; + } }