From 77f40570ac191007812c65b0060b6adac8de4c9b Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Mon, 17 Jul 2023 18:04:39 +0300 Subject: [PATCH] #8834: Home page: Drafts query for both Datasets and DMPs. 1. recent-activity-criteria.ts: Added in RecentActivityCriteria optional field "public status?: Number;" (to get only drafts). 2. drafts.component.ts & drafts.component.html: Updated calls and display to query for both Datasets and DMPs (same as recent-edited-activity, but include only drafts). 4. recent-edited-activity.component.ts: Removed old unnecessary logs. --- .../recent-activity-criteria.ts | 1 + .../ui/dashboard/drafts/drafts.component.html | 236 +++--- .../ui/dashboard/drafts/drafts.component.ts | 751 ++++++++++++------ .../recent-edited-activity.component.ts | 11 - 4 files changed, 630 insertions(+), 369 deletions(-) diff --git a/dmp-frontend/src/app/core/query/recent-activity/recent-activity-criteria.ts b/dmp-frontend/src/app/core/query/recent-activity/recent-activity-criteria.ts index 1c21402b9..8b6e134db 100644 --- a/dmp-frontend/src/app/core/query/recent-activity/recent-activity-criteria.ts +++ b/dmp-frontend/src/app/core/query/recent-activity/recent-activity-criteria.ts @@ -2,5 +2,6 @@ import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order import { BaseCriteria } from '../base-criteria'; export class RecentActivityCriteria extends BaseCriteria{ + public status?: Number; public order: RecentActivityOrder = RecentActivityOrder.MODIFIED; } diff --git a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html index 752fe315a..565092451 100644 --- a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html +++ b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html @@ -1,4 +1,7 @@ -
+
+ {{'DMP-LISTING.EMPTY-LIST' | translate}} +
+
{{'DMP-LISTING.SORT-BY' | translate}}: @@ -12,118 +15,157 @@ - + search - + {{formGroup.get('like').getError('backendError').message}}
-
+
-
-
- -
-
{{'DATASET-LISTING.DATASET-DESCRIPTION' | translate}}
-
{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{activity.modified | dateTimeCultureFormatter: "d MMMM y"}}
-
-
{{activity.label}}
-
- {{ roleDisplay(activity.users) }} - . - public{{'DATASET-LISTING.STATES.PUBLIC' | translate}} - done{{ enumUtils.toDmpStatusString(activity.status) }} - create{{ enumUtils.toDmpStatusString(activity.status) }} - . - {{'DATASET-LISTING.COLUMNS.GRANT' | translate}}: {{activity.grant}} -
-
-
{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}} -
{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}
+
+
+
+ + +
+
{{ 'DMP-LISTING.DMP' | translate }}
+
{{ 'DMP-LISTING.EDITED' | translate }}: {{ activity.modified | dateTimeCultureFormatter: "d MMMM y" }}
+
{{ 'DMP-LISTING.PUBLISHED' | translate }}: {{ activity.publishedAt | dateTimeCultureFormatter: "d MMMM y" }}
- -
{{activity.dmp}}
+
{{activity.title}}
+
+ {{ roleDisplay(activity.users) }} + . + create{{ enumUtils.toDmpStatusString(activity.status) }} + . + {{'DMP-LISTING.VERSION' | translate}} {{activity.version}} + . + {{ 'DMP-LISTING.GRANT' | translate }}: {{activity.grant}} +
+
{{'DMP-LISTING.CONTAINED-DATASETS' | translate}}: ({{ getDatasets(activity).length }}) +
+
+
+
{{dataset.label}},
+
{{dataset.label}}
+
+
+ +
{{'GENERAL.ACTIONS.SHOW-MORE' | translate}} + + - -
- open_in_new{{'DATASET-LISTING.ACTIONS.EXPORT' | translate}} - group_add{{'DATASET-LISTING.ACTIONS.INVITE-SHORT' | translate}} - file_copy{{'DATASET-WIZARD.ACTIONS.COPY-DATASET' | translate}} - delete{{ 'DATASET-WIZARD.ACTIONS.DELETE' | translate }} - - + + + + + + + + + + +
- - - - - +
+
+
-
+
{{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}}
-
+
- diff --git a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts index be73632c5..81f04cb48 100644 --- a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts @@ -1,6 +1,6 @@ import {Component, OnInit, Input, EventEmitter, Output, ViewChild} from '@angular/core'; import { DatasetService } from '../../../core/services/dataset/dataset.service'; -import { DataTableRequest } from '../../../core/model/data-table/data-table-request'; +import {DataTableMultiTypeRequest, DataTableRequest} from '../../../core/model/data-table/data-table-request'; import { DatasetCriteria } from '../../../core/query/dataset/dataset-criteria'; import { DatasetListingModel } from '../../../core/model/dataset/dataset-listing'; import { AuthService } from '../../../core/services/auth/auth.service'; @@ -9,10 +9,10 @@ import {ActivatedRoute, Router} from '@angular/router'; import { DmpStatus } from '../../../core/common/enum/dmp-status'; import { Principal } from '@app/core/model/auth/principal'; import { TranslateService } from '@ngx-translate/core'; -import { debounceTime, takeUntil } from 'rxjs/operators'; +import {debounceTime, map, takeUntil} from 'rxjs/operators'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { DatasetCopyDialogueComponent } from '@app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component'; -import { FormControl, FormBuilder } from '@angular/forms'; +import {FormControl, FormBuilder, FormGroup} from '@angular/forms'; import { BaseComponent } from '@common/base/base.component'; import { MatDialog } from '@angular/material/dialog'; import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service'; @@ -27,6 +27,21 @@ import { Role } from '@app/core/common/enum/role'; import { LockService } from '@app/core/services/lock/lock.service'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { HttpClient } from '@angular/common/http'; +import {RecentActivityModel} from "@app/core/model/recent-activity/recent-activity.model"; +import {DmpEditorModel} from "@app/ui/dmp/editor/dmp-editor.model"; +import {DmpService} from "@app/core/services/dmp/dmp.service"; +import {DashboardService} from "@app/core/services/dashboard/dashboard.service"; +import {RecentActivityCriteria} from "@app/core/query/recent-activity/recent-activity-criteria"; +import {RecentDmpModel} from "@app/core/model/recent-activity/recent-dmp-activity.model"; +import {DatasetUrlListing} from "@app/core/model/dataset/dataset-url-listing"; +import {RecentDatasetModel} from "@app/core/model/recent-activity/recent-dataset-activity.model"; +import {DmpListingModel} from "@app/core/model/dmp/dmp-listing"; +import {DmpModel} from "@app/core/model/dmp/dmp"; +import {GrantTabModel} from "@app/ui/dmp/editor/grant-tab/grant-tab-model"; +import {ProjectFormModel} from "@app/ui/dmp/editor/grant-tab/project-form-model"; +import {FunderFormModel} from "@app/ui/dmp/editor/grant-tab/funder-form-model"; +import {ExtraPropertiesFormModel} from "@app/ui/dmp/editor/general-tab/extra-properties-form.model"; +import {CloneDialogComponent} from "@app/ui/dmp/clone/clone-dialog/clone-dialog.component"; @Component({ selector: 'app-drafts', @@ -35,39 +50,43 @@ import { HttpClient } from '@angular/common/http'; }) export class DraftsComponent extends BaseComponent implements OnInit { - @Input() routerLink: string; - @Output() totalCountDraftDatasets: EventEmitter = new EventEmitter(); - - @ViewChild("drafts") resultsContainer; - datasetDrafts: DatasetListingModel[]; - datasetDraftsTypeEnum = RecentActivityType; - status: number; + @Output() totalCountRecentEdited: EventEmitter = new EventEmitter(); + @ViewChild("results") resultsContainer; + allRecentActivities: RecentActivityModel[]; + recentActivityTypeEnum = RecentActivityType; + dmpModel: DmpEditorModel; + isDraft: boolean; totalCount: number; startIndex: number = 0; - pageSize: number = 5; + dmpOffset: number = 0; + datasetOffset: number = 0; offsetLess: number = 0; - hasMoreResults:boolean = true; - + pageSize: number = 5; + dmpFormGroup: FormGroup; + hasMoreActivity:boolean = true; public formGroup = new FormBuilder().group({ like: new FormControl(), order: new FormControl() }); + publicMode = false; order = RecentActivityOrder; page: number = 1; @Input() isActive: boolean = false; + constructor( private route: ActivatedRoute, private router: Router, - private datasetService: DatasetService, - private authentication: AuthService, - private language: TranslateService, - public dialog: MatDialog, - private datasetWizardService: DatasetWizardService, public enumUtils: EnumUtils, + private authentication: AuthService, + private dmpService: DmpService, + private dashboardService: DashboardService, + private language: TranslateService, + private dialog: MatDialog, private uiNotificationService: UiNotificationService, + private datasetWizardService: DatasetWizardService, private location: Location, private lockService: LockService, private httpClient: HttpClient, @@ -83,7 +102,8 @@ export class DraftsComponent extends BaseComponent implements OnInit { let page = (params['page'] === undefined) ? 1 : +params['page']; this.page = (page <= 0) ? 1 : page; - this.startIndex = (this.page-1)*this.pageSize; + this.datasetOffset = (this.page-1)*this.pageSize; + this.dmpOffset = (this.page-1)*this.pageSize; if(this.page > 1) { this.offsetLess = (this.page-2)*this.pageSize; } @@ -94,48 +114,57 @@ export class DraftsComponent extends BaseComponent implements OnInit { } this.formGroup.get('order').setValue(order); - let keyword = (params['keyword'] === undefined || params['keyword'].length <= 0) ? "" : params['keyword']; this.formGroup.get("like").setValue(keyword); this.updateUrl(); } - // else { - // this.page = 1; - // this.formGroup.get('order').setValue(this.order.MODIFIED); - // this.formGroup.get("like").setValue(""); - // } }); - // const fields: Array = []; - // fields.push('-modified'); - if(!this.formGroup.get('order').value) { - this.formGroup.get('order').setValue(this.order.MODIFIED); - } - const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - const dmpDataTableRequest: DataTableRequest = new DataTableRequest(this.startIndex, 5, { fields: fields }); - dmpDataTableRequest.criteria = new DatasetCriteria(); - dmpDataTableRequest.criteria.like = this.formGroup.get('like').value; - dmpDataTableRequest.criteria.status = DmpStatus.Draft; - this.datasetService.getPaged(dmpDataTableRequest) - .pipe(takeUntil(this._destroyed)) - .subscribe(response => { - this.datasetDrafts = response.data; - this.totalCount = response.totalCount; - this.totalCountDraftDatasets.emit(this.datasetDrafts.length); - if(this.totalCount > 0 && this.totalCount <= (this.page-1)*this.pageSize && this.page > 1) { - let queryParams = { type: "drafts", page: 1, order: this.formGroup.get("order").value }; - if(this.formGroup.get("like").value) { - queryParams['keyword'] = this.formGroup.get("like").value; - } - this.router.navigate(["/home"], { queryParams: queryParams }) + if (this.isAuthenticated()) { + if (!this.formGroup.get('order').value) { + this.formGroup.get('order').setValue(this.order.MODIFIED); } - }); - this.formGroup.get('like').valueChanges - .pipe(takeUntil(this._destroyed), debounceTime(500)) - .subscribe(x => this.refresh()); - this.formGroup.get('order').valueChanges - .pipe(takeUntil(this._destroyed)) - .subscribe(x => this.refresh()); + const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; + const allDataTableRequest: DataTableMultiTypeRequest = new DataTableMultiTypeRequest(this.dmpOffset, this.datasetOffset, 5, {fields: fields}); + allDataTableRequest.criteria = new RecentActivityCriteria(); + allDataTableRequest.criteria.like = this.formGroup.get('like').value; + allDataTableRequest.criteria.order = this.formGroup.get('order').value; + allDataTableRequest.criteria.status = 0; + + this.dashboardService + .getRecentActivity(allDataTableRequest) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + this.allRecentActivities = response; + this.allRecentActivities.forEach(recentActivity => { + if (recentActivity.type === RecentActivityType.Dataset) { + // this.datasetOffset = this.datasetOffset + 1; + this.datasetOffset = this.page * this.pageSize; + } else if (recentActivity.type === RecentActivityType.Dmp) { + // this.dmpOffset = this.dmpOffset + 1; + this.dmpOffset = this.page * this.pageSize; + } + }); + this.totalCountRecentEdited.emit(this.allRecentActivities.length); + if (this.allRecentActivities.length == 0 && this.page > 1) { + let queryParams = {type: "recent", page: 1, order: this.formGroup.get("order").value}; + if (this.formGroup.get("like").value) { + queryParams['keyword'] = this.formGroup.get("like").value; + } + this.router.navigate(["/home"], {queryParams: queryParams}) + } + }); + this.formGroup.get('like').valueChanges + .pipe(takeUntil(this._destroyed), debounceTime(500)) + .subscribe(x => { + this.refresh() + }); + this.formGroup.get('order').valueChanges + .pipe(takeUntil(this._destroyed)) + .subscribe(x => { + this.refresh() + }); + } } ngOnChanges() { @@ -152,6 +181,178 @@ export class DraftsComponent extends BaseComponent implements OnInit { this.location.go(this.router.url.split('?')[0]+parameters); } + getDatasets(activity: RecentDmpModel): DatasetUrlListing[] { + return activity.datasets; + } + + getGroupId(activity: RecentDmpModel): string { + return activity.groupId; + } + + getDmp(activity: RecentDatasetModel): String { + return activity.dmp; + } + + getDmpId(activity: RecentDatasetModel): String { + return activity.dmpId; + } + + public isAuthenticated(): boolean { + return !!this.authentication.current(); + } + + isUserOwner(activity: DmpListingModel): boolean { + const principal: Principal = this.authentication.current(); + if (principal) return !!activity.users.find(x => (x.role === Role.Owner) && (principal.id === x.id)); + } + + editClicked(dmp: DmpListingModel) { + this.router.navigate(['/plans/edit/' + dmp.id]); + } + + deleteDmpClicked(dmp: DmpListingModel) { + this.lockService.checkLockStatus(dmp.id).pipe(takeUntil(this._destroyed)) + .subscribe(lockStatus => { + if (!lockStatus) { + this.openDeleteDmpDialog(dmp); + } else { + this.openDmpLockedByUserDialog(); + } + }); + } + + cloneOrNewVersionClicked(dmp: RecentActivityModel, isNewVersion: boolean) { + this.dmpService.getSingle(dmp.id).pipe(map(data => data as DmpModel)) + .pipe(takeUntil(this._destroyed)) + .subscribe(data => { + this.dmpModel = new DmpEditorModel(); + this.dmpModel.grant = new GrantTabModel(); + this.dmpModel.project = new ProjectFormModel(); + this.dmpModel.funder = new FunderFormModel(); + this.dmpModel.extraProperties = new ExtraPropertiesFormModel(); + this.dmpModel.fromModel(data); + this.dmpModel.status = DmpStatus.Draft; + this.dmpFormGroup = this.dmpModel.buildForm(); + if (!isNewVersion) { + this.dmpFormGroup.get('label').setValue(dmp.title + " New"); + } + this.openCloneDialog(isNewVersion); + }); + } + + openCloneDialog(isNewVersion: boolean) { + const dialogRef = this.dialog.open(CloneDialogComponent, { + maxWidth: '700px', + maxHeight: '80vh', + data: { + formGroup: this.dmpFormGroup, + datasets: this.dmpFormGroup.get('datasets').value, + isNewVersion: isNewVersion, + confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.SAVE'), + cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'), + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + if (!isNewVersion) { + this.dmpService.clone(this.dmpFormGroup.getRawValue(), this.dmpFormGroup.get('id').value) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCloneOrNewVersionCallbackSuccess(complete), + error => this.onCloneOrNewVersionCallbackError(error) + ); + } else if (isNewVersion) { + this.dmpService.newVersion(this.dmpFormGroup.getRawValue(), this.dmpFormGroup.get('id').value) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCloneOrNewVersionCallbackSuccess(complete), + error => this.onCloneOrNewVersionCallbackError(error) + ); + } + } + }); + } + + openDeleteDmpDialog(dmp: DmpListingModel) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '300px', + restoreFocus: false, + 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'), + isDeleteConfirmation: true + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.dmpService.delete(dmp.id) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onDeleteCallbackSuccess(), + error => this.onDeleteCallbackError(error) + ); + } + }); + } + + openDmpLockedByUserDialog() { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '400px', + restoreFocus: false, + data: { + message: this.language.instant('DMP-EDITOR.ACTIONS.LOCK') + } + }); + } + + openShareDialog(rowId: any, rowName: any) { + const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { + // height: '250px', + // width: '700px', + autoFocus: false, + restoreFocus: false, + data: { + dmpId: rowId, + dmpName: rowName + } + }); + } + + isDraftDmp(activity: DmpListingModel) { + return activity.status == DmpStatus.Draft; + } + + onCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + this.router.navigate(['/plans']); + } + + reloadPage(): void { + const path = this.location.path(); + this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => { + this.router.navigate([path]); + }); + } + + onDeleteCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success); + this.reloadPage(); + } + + onDeleteCallbackError(error) { + this.uiNotificationService.snackBarNotification(error.error.message ? this.language.instant(error.error.message) : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error); + } + + onCloneOrNewVersionCallbackSuccess(dmpId: String): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + this.router.navigate(['/plans/edit/', dmpId]); + } + + onCloneOrNewVersionCallbackError(error: any) { + this.uiNotificationService.snackBarNotification(error.error.message ? this.language.instant(error.error.message) : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-CLONE'), SnackBarNotificationLevel.Error); + } + redirect(id: string, type: RecentActivityType) { switch (type) { case RecentActivityType.Grant: { @@ -159,11 +360,15 @@ export class DraftsComponent extends BaseComponent implements OnInit { return; } case RecentActivityType.Dataset: { - this.router.navigate(["datasets/edit/" + id]); + if (this.isAuthenticated()) { + this.router.navigate(['../datasets/overview/' + id]); + } return; } case RecentActivityType.Dmp: { - this.router.navigate(["plans/edit/" + id]); + if (this.isAuthenticated()) { + this.router.navigate(['../plans/overview/' + id]); + } return; } default: @@ -171,13 +376,28 @@ export class DraftsComponent extends BaseComponent implements OnInit { } } - public isAuthenticated(): boolean { - return !!this.authentication.current(); - } - - navigateToUrl() { - if (!this.isAuthenticated()) { return; } - this.router.navigate(['/datasets'], { queryParams: { status: 0 } }); + navigateToUrl(id: string, type: RecentActivityType): string[] { + switch (type) { + case RecentActivityType.Grant: { + return ["grants/edit/" + id]; + } + case RecentActivityType.Dataset: { + if (this.isAuthenticated()) { + return ['../datasets/overview/' + id]; + } else { + return ['../explore/publicOverview', id]; + } + } + case RecentActivityType.Dmp: { + if (this.isAuthenticated()) { + return ['../plans/overview/' + id]; + } else { + return ['../explore-plans/publicOverview', id]; + } + } + default: + throw new Error("Unsupported Activity Type "); + } } roleDisplay(value: any) { @@ -201,117 +421,68 @@ export class DraftsComponent extends BaseComponent implements OnInit { } } - openDmpSearchDialogue(dataset: DatasetListingModel) { - const formControl = new FormControl(); - const dialogRef = this.dialog.open(DatasetCopyDialogueComponent, { - width: '500px', - restoreFocus: false, - data: { - formControl: formControl, - datasetId: dataset.id, - datasetProfileId: dataset.profile.id, - datasetProfileExist: false, - confirmButton: this.language.instant('DATASET-WIZARD.DIALOGUE.COPY'), - cancelButton: this.language.instant('DATASET-WIZARD.DIALOGUE.CANCEL') - } - }); + // dmpProfileDisplay(value: any) { + // if (value != null) { + // return value; + // } + // else { + // return "--"; + // } + // } - dialogRef.afterClosed().pipe(takeUntil(this._destroyed)) - .subscribe(result => { - if (result && result.datasetProfileExist) { - const newDmpId = result.formControl.value.id; - this.router.navigate(['/datasets/copy/' + result.datasetId], { queryParams: { newDmpId: newDmpId } }); - // let url = this.router.createUrlTree(['/datasets/copy/', result.datasetId, { newDmpId: newDmpId } ]); - // window.open(url.toString(), '_blank'); - } + 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); + this.matomoService.trackDownload('dmps', "xml", id); }); } - deleteClicked(id: string) { - this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed)) - .subscribe(lockStatus => { - if (!lockStatus) { - this.openDeleteDialog(id); - } else { - this.openLockedByUserDialog(); - } + 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); + this.matomoService.trackDownload('dmps', "docx", id); }); } - openDeleteDialog(id: string): void { - const dialogRef = this.dialog.open(ConfirmationDialogComponent, { - maxWidth: '300px', - restoreFocus: false, - 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'), - isDeleteConfirmation: true - } - }); - dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - if (result) { - this.datasetWizardService.delete(id) - .pipe(takeUntil(this._destroyed)) - .subscribe( - complete => this.onDeleteCallbackSuccess(), - error => this.onDeleteCallbackError(error) - ); - } - }); + 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); + this.matomoService.trackDownload('dmps', "pdf", id); + }); } - openLockedByUserDialog() { - const dialogRef = this.dialog.open(ConfirmationDialogComponent, { - maxWidth: '400px', - restoreFocus: false, - data: { - message: this.language.instant('DATASET-WIZARD.ACTIONS.LOCK') - } - }); + downloadJson(id: string) { + this.dmpService.downloadJson(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/json' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "json", id); + }, async error => { + this.onExportCallbackError(error); + }); } - openShareDialog(dmpRowId: any, dmpRowName: any) { - const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { - // height: '250px', - // width: '700px', - autoFocus: false, - restoreFocus: false, - data: { - dmpId: dmpRowId, - dmpName: dmpRowName - } - }); - } - - isUserOwner(activity: DatasetListingModel): boolean { - const principal: Principal = this.authentication.current(); - if (principal) return !!activity.users.find(x => (x.role === Role.Owner) && (principal.id === x.id)); - } - - onCallbackSuccess(id?: String): void { - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); - id ? this.router.navigate(['/reload']).then(() => { this.router.navigate(['/datasets', 'edit', id]); }) : this.router.navigate(['/datasets']); - } - - onCallbackError(error: any) { - // this.setErrorModel(error.error); - } - - reloadPage(): void { - const path = this.location.path(); - this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => { - this.router.navigate([path]); - }); - } - - onDeleteCallbackSuccess(): void { - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success); - this.reloadPage(); - } - - onDeleteCallbackError(error) { - this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error); + async onExportCallbackError(error: any) { + const errorJsonText = await error.error.text(); + const errorObj = JSON.parse(errorJsonText); + this.uiNotificationService.snackBarNotification(errorObj.message, SnackBarNotificationLevel.Error); } downloadPDF(dataset: DatasetListingModel): void { @@ -369,119 +540,177 @@ export class DraftsComponent extends BaseComponent implements OnInit { return filename; } - refresh(): void { - this.page = 1; - this.updateUrl(); + viewVersions(rowId: String, rowLabel: String, activity: DmpListingModel) { + if (activity.public && !this.isUserOwner(activity)) { + let url = this.router.createUrlTree(['/explore-plans/versions/', rowId, { groupLabel: rowLabel }]); + window.open(url.toString(), '_blank'); + // this.router.navigate(['/explore-plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } }); + } else { + let url = this.router.createUrlTree(['/plans/versions/', rowId, { groupLabel: rowLabel }]); + window.open(url.toString(), '_blank'); + // this.router.navigate(['/plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } }); + } + } - // const fields: Array = []; - // fields.push('-modified'); - const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - this.startIndex = 0; - const dmpDataTableRequest: DataTableRequest = new DataTableRequest(0, 5, { fields: fields }); - dmpDataTableRequest.criteria = new DatasetCriteria(); - dmpDataTableRequest.criteria.status = DmpStatus.Draft; - dmpDataTableRequest.criteria.like = this.formGroup.get("like").value; - this.datasetService.getPaged(dmpDataTableRequest) - .pipe(takeUntil(this._destroyed)) - .subscribe(response => { - this.datasetDrafts = response.data; - this.totalCount = response.totalCount; - this.totalCountDraftDatasets.emit(this.datasetDrafts.length); - if(response.data.length< this.pageSize) { - this.hasMoreResults = false; - } else { - this.hasMoreResults = true; + openDmpSearchDialogue(dataset: RecentDatasetModel) { + const formControl = new FormControl(); + const dialogRef = this.dialog.open(DatasetCopyDialogueComponent, { + width: '500px', + restoreFocus: false, + data: { + formControl: formControl, + datasetId: dataset.id, + datasetProfileId: dataset.profile.id, + datasetProfileExist: false, + confirmButton: this.language.instant('DATASET-WIZARD.DIALOGUE.COPY'), + cancelButton: this.language.instant('DATASET-WIZARD.DIALOGUE.CANCEL') + } + }); + + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)) + .subscribe(result => { + if (result && result.datasetProfileExist) { + const newDmpId = result.formControl.value.id; + // let url = this.router.createUrlTree(['/datasets/copy/', result.datasetId, { newDmpId: newDmpId }]); + // window.open(url.toString(), '_blank'); + this.router.navigate(['/datasets/copy/' + result.datasetId], { queryParams: { newDmpId: newDmpId } }); + } + }); + } + + deleteDatasetClicked(id: string) { + this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed)) + .subscribe(lockStatus => { + if (!lockStatus) { + this.openDeleteDatasetDialog(id); + } else { + this.openDatasetLockedByUserDialog(); + } + }); + } + + openDeleteDatasetDialog(id: string): void { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '300px', + restoreFocus: false, + 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'), + isDeleteConfirmation: true + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.datasetWizardService.delete(id) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onDeleteCallbackSuccess(), + error => this.onDeleteCallbackError(error) + ); } }); } - public loadNextOrPrevious(more: boolean = true) { - // const fields: Array = ["-modified"]; - const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - let request; - this.startIndex = (this.page)*this.pageSize; - if(this.page > 1) { - this.offsetLess = (this.page-2)*this.pageSize; - } - if(more) { - // this.startIndex = this.startIndex + this.pageSize; - request = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }); - } else { - request = new DataTableRequest(this.offsetLess, this.pageSize, {fields: fields}); - } - request.criteria = new DatasetCriteria(); - request.criteria.status = DmpStatus.Draft; - request.criteria.like = this.formGroup.get("like").value;; + openDatasetLockedByUserDialog() { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '400px', + restoreFocus: false, + data: { + message: this.language.instant('DATASET-WIZARD.ACTIONS.LOCK') + } + }); + } - this.datasetService.getPaged(request).pipe(takeUntil(this._destroyed)).subscribe(result => { - if (!result || !result.data || result.data.length == 0) { - this.hasMoreResults = false; + refresh(): void { + this.datasetOffset = 0; + this.dmpOffset = 0; + this.page = 1; + this.updateUrl(); + + const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; + // const fields: Array = ["-modified"]; + this.startIndex = 0; + const allDataTableRequest: DataTableMultiTypeRequest = new DataTableMultiTypeRequest(0, 0, this.pageSize, { fields: fields }); + allDataTableRequest.criteria = new RecentActivityCriteria(); + allDataTableRequest.criteria.like = this.formGroup.get("like").value; + allDataTableRequest.criteria.order = this.formGroup.get("order").value; + allDataTableRequest.criteria.status = 0; + + this.dashboardService + .getRecentActivity(allDataTableRequest) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + this.allRecentActivities = response; + this.allRecentActivities.forEach(recentActivity => { + if (recentActivity.type === RecentActivityType.Dataset) { + // this.datasetOffset = this.datasetOffset + 1; + this.datasetOffset = this.page*this.pageSize; + } else if (recentActivity.type === RecentActivityType.Dmp) { + // this.dmpOffset = this.dmpOffset + 1; + this.dmpOffset = this.page*this.pageSize; + } + }); + + if(response.length< this.pageSize) { + this.hasMoreActivity = false; + } else { + this.hasMoreActivity = true; + } + this.totalCountRecentEdited.emit(this.allRecentActivities.length); + }); + } + + public loadNextOrPrevious(more: boolean = true) { + const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; + // const fields: Array = ["-modified"]; + let request; + if(more) { + request = new DataTableMultiTypeRequest(this.dmpOffset, this.datasetOffset, this.pageSize, {fields: fields}); + } else { + request = new DataTableMultiTypeRequest(this.offsetLess, this.offsetLess, this.pageSize, {fields: fields}); + } + request.criteria = new RecentActivityCriteria(); + request.criteria.like = this.formGroup.get("like").value ? this.formGroup.get("like").value : ""; + request.criteria.order = this.formGroup.get("order").value; + request.criteria.status = 0; + + this.dashboardService.getRecentActivity(request).pipe(takeUntil(this._destroyed)).subscribe(result => { + if (!result || result.length == 0) { + this.hasMoreActivity = false; // return []; } else { - // this.datasetDrafts = this.datasetDrafts.concat(result.data); - // this.datasetDrafts = this.datasetDrafts.length > 0 ? this.mergeTwoSortedLists(this.datasetDrafts, result.data, this.formGroup.get('order').value) : result.data; this.page = this.page + (more ? 1 : -1); this.updateUrl(); - this.datasetDrafts = result.data; - if(result.data.length < this.pageSize) { - this.hasMoreResults = false; - } else { - this.hasMoreResults = true; + // if(more) { + // result.forEach(recentActivity => { + // if (recentActivity.type === RecentActivityType.Dataset) { + // this.datasetOffset = this.datasetOffset + 1; + this.datasetOffset = this.page * this.pageSize; + // } else if (recentActivity.type === RecentActivityType.Dmp) { + // this.dmpOffset = this.dmpOffset + 1; + this.dmpOffset = this.page * this.pageSize; + // } + // }); + // } + if (this.page > 1) { + this.offsetLess = (this.page - 2) * this.pageSize; } - this.totalCountDraftDatasets.emit(this.datasetDrafts.length); + + if(result.length < this.pageSize) { + this.hasMoreActivity = false; + } else { + this.hasMoreActivity = true; + } + + // this.allRecentActivities = this.allRecentActivities.concat(result); + // this.allRecentActivities = this.allRecentActivities.length > 0 ? this.mergeTwoSortedLists(this.allRecentActivities, result, this.formGroup.get('order').value) : result; + this.allRecentActivities = result; + this.totalCountRecentEdited.emit(this.allRecentActivities.length); if (more) { this.resultsContainer.nativeElement.scrollIntoView(); } } }); } - - private mergeTwoSortedLists(arr1: DatasetListingModel[], arr2: DatasetListingModel[], order: string): DatasetListingModel[] { - let merged = []; - let index1 = 0; - let index2 = 0; - let current = 0; - - while (current < (arr1.length + arr2.length)) { - - let isArr1Depleted = index1 >= arr1.length; - let isArr2Depleted = index2 >= arr2.length; - - if (order === 'modified') { - if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].modified) > new Date(arr2[index2].modified)))) { - merged[current] = arr1[index1]; - index1++; - } else { - merged[current] = arr2[index2]; - index2++; - } - } else if (order === 'created') { - if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].created) > new Date(arr2[index2].created)))) { - merged[current] = arr1[index1]; - index1++; - } else { - merged[current] = arr2[index2]; - index2++; - } - } else if (order === 'label') { - if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].label < arr2[index2].label))) { - merged[current] = arr1[index1]; - index1++; - } else { - merged[current] = arr2[index2]; - index2++; - } - } else if (order === 'status') { - if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].status < arr2[index2].status))) { - merged[current] = arr1[index1]; - index1++; - } else { - merged[current] = arr2[index2]; - index2++; - } - } - current++; - } - return merged; - } } 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 ee7d19c82..0c9e41e52 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 @@ -123,7 +123,6 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn let keyword = (params['keyword'] === undefined || params['keyword'].length <= 0) ? "" : params['keyword']; this.formGroup.get("like").setValue(keyword); - console.log("init"); this.updateUrl(); } }); @@ -157,20 +156,17 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn if(this.formGroup.get("like").value) { queryParams['keyword'] = this.formGroup.get("like").value; } - console.log(queryParams); this.router.navigate(["/home"], { queryParams: queryParams }) } }); this.formGroup.get('like').valueChanges .pipe(takeUntil(this._destroyed), debounceTime(500)) .subscribe(x => { - console.log("like changed"); this.refresh() }); this.formGroup.get('order').valueChanges .pipe(takeUntil(this._destroyed)) .subscribe(x => { - console.log("order changed"); this.refresh() }); } else { @@ -199,20 +195,17 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn if(this.formGroup.get("like").value) { queryParams['keyword'] = this.formGroup.get("like").value; } - console.log(queryParams); this.router.navigate(["/home"], { queryParams: queryParams }) } }); this.formGroup.get('like').valueChanges .pipe(takeUntil(this._destroyed), debounceTime(500)) .subscribe(x => { - console.log("like changed 1"); this.refresh() }); this.formGroup.get('order').valueChanges .pipe(takeUntil(this._destroyed)) .subscribe(x => { - console.log("order changed 1"); this.refresh() }); } @@ -220,7 +213,6 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn ngOnChanges() { if(this.isActive) { - console.log("active"); this.updateUrl(); } } @@ -233,7 +225,6 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn if(parameters) { parameters = "?type=recent" + parameters; } - console.log(parameters); this.location.go(this.router.url.split('?')[0]+parameters); } @@ -710,7 +701,6 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn this.datasetOffset = 0; this.dmpOffset = 0; this.page = 1; - console.log("refresh"); this.updateUrl(); const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; @@ -763,7 +753,6 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn // return []; } else { this.page = this.page + (more ? 1 : -1); - console.log("loadNextOrPrevious"); this.updateUrl(); // if(more) { // result.forEach(recentActivity => {