diff --git a/dmp-frontend/src/app/core/model/recent-activity/recent-activity.model.ts b/dmp-frontend/src/app/core/model/recent-activity/recent-activity.model.ts new file mode 100644 index 000000000..b195e63b2 --- /dev/null +++ b/dmp-frontend/src/app/core/model/recent-activity/recent-activity.model.ts @@ -0,0 +1,16 @@ +export class RecentActivityModel { + id: String; + title: String; + description: String; + created: Date; + modified: Date; + status: number; + version: number; + grant: String; + grantAbbreviation: String; + grantId: String; + finalizedAt: Date; + publishedAt: Date; + profile: String; +} + diff --git a/dmp-frontend/src/app/core/model/recent-activity/recent-dataset-activity.model.ts b/dmp-frontend/src/app/core/model/recent-activity/recent-dataset-activity.model.ts new file mode 100644 index 000000000..5fb6bca2b --- /dev/null +++ b/dmp-frontend/src/app/core/model/recent-activity/recent-dataset-activity.model.ts @@ -0,0 +1,9 @@ +import { RecentActivityModel } from "./recent-activity.model"; + +export class RecentDatasetModel extends RecentActivityModel { + dmp: String; + dmpId: String; + dataRepositories: String; + registries: String; + services: String; +} diff --git a/dmp-frontend/src/app/core/model/recent-activity/recent-dmp-activity.model.ts b/dmp-frontend/src/app/core/model/recent-activity/recent-dmp-activity.model.ts new file mode 100644 index 000000000..88045ace9 --- /dev/null +++ b/dmp-frontend/src/app/core/model/recent-activity/recent-dmp-activity.model.ts @@ -0,0 +1,15 @@ +import { RecentActivityModel } from './recent-activity.model'; +import { RecentDatasetModel } from './recent-dataset-activity.model'; +import { DmpAssociatedProfileModel } from '../dmp-profile/dmp-associated-profile'; +import { UserInfoListingModel } from '../user/user-info-listing'; + +export class RecentDmpModel extends RecentActivityModel { + doi: String; + extraProperties: Map; + datasets: RecentDatasetModel[]; + associatedProfiles: DmpAssociatedProfileModel[]; + organisations: String; + groupId: string; + users: UserInfoListingModel[]; + isPublic: boolean; +} diff --git a/dmp-frontend/src/app/core/services/dashboard/dashboard.service.ts b/dmp-frontend/src/app/core/services/dashboard/dashboard.service.ts index b715942de..5c138a638 100644 --- a/dmp-frontend/src/app/core/services/dashboard/dashboard.service.ts +++ b/dmp-frontend/src/app/core/services/dashboard/dashboard.service.ts @@ -5,6 +5,7 @@ import { environment } from '../../../../environments/environment'; import { DashboardStatisticsModel } from '../../model/dashboard/dashboard-statistics-model'; import { BaseHttpService } from '../http/base-http.service'; import { ConfigurationService } from '../configuration/configuration.service'; +import { RecentActivityModel } from '@app/core/model/recent-activity/recent-activity.model'; @Injectable() export class DashboardService { @@ -25,7 +26,7 @@ export class DashboardService { return this.http.get(this.actionUrl + 'me/getStatistics', { headers: this.headers }); } - getRecentAcitvity(): Observable { - return this.http.get(this.actionUrl + 'recentActivity', {headers: this.headers}); + getRecentAcitvity(): Observable { + return this.http.get(this.actionUrl + 'recentActivity', {headers: this.headers}); } } diff --git a/dmp-frontend/src/app/ui/dashboard/dashboard.component.html b/dmp-frontend/src/app/ui/dashboard/dashboard.component.html index d6e9c7006..601ccf0bd 100644 --- a/dmp-frontend/src/app/ui/dashboard/dashboard.component.html +++ b/dmp-frontend/src/app/ui/dashboard/dashboard.component.html @@ -53,30 +53,21 @@
Latest activity
-
-
- -
- - - - +
- -
- -
+
- +
- -
- -
+ +
+ +
+
diff --git a/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts b/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts index 3db57fa5a..06a3f2939 100644 --- a/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts @@ -53,6 +53,11 @@ export class DashboardComponent extends BaseComponent implements OnInit, IBreadC dmpListingItems: DmpListingModel[] = []; datasetListingItems: DatasetListingModel[] = []; + totalDatasets: number; + totalDmps: number; + totalDraftDatasets: number; + + constructor( private router: Router, private route: ActivatedRoute, @@ -185,6 +190,18 @@ export class DashboardComponent extends BaseComponent implements OnInit, IBreadC this.isVisible = false; } + onCountDmps(event): void { + this.totalDmps = event; + } + + onCountDatasets(event): void { + this.totalDatasets = event; + } + + onCountDraftDatasets(event): void { + this.totalDraftDatasets = event; + } + // viewAllPublicDmpsClicked() { // this.router.navigate(['/explore-plans']); // } diff --git a/dmp-frontend/src/app/ui/dashboard/dashboard.module.ts b/dmp-frontend/src/app/ui/dashboard/dashboard.module.ts index 01b51d79d..0d5b845a2 100644 --- a/dmp-frontend/src/app/ui/dashboard/dashboard.module.ts +++ b/dmp-frontend/src/app/ui/dashboard/dashboard.module.ts @@ -15,8 +15,8 @@ import { WizardComponent } from '@app/ui/dashboard/wizard/wizard.component'; import { CommonUiModule } from '@common/ui/common-ui.module'; import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module'; import { RecentEditedDatasetActivityComponent } from './recent-edited-dataset-activity/recent-edited-dataset-activity.component'; -import { DatasetCopyDialogueComponent } from '../dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component'; import { DatasetCopyDialogModule } from '../dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.module'; +import { RecentEditedDmpActivityComponent } from './recent-edited-dmp-activity/recent-edited-dmp-activity.component'; @NgModule({ imports: [ @@ -38,7 +38,8 @@ import { DatasetCopyDialogModule } from '../dataset/dataset-wizard/dataset-copy- DraftsComponent, DmpInfoCounterComponent, DatasetInfoCounterComponent, - RecentEditedDatasetActivityComponent + RecentEditedDatasetActivityComponent, + RecentEditedDmpActivityComponent ], entryComponents: [ QuickWizardCreateAdd diff --git a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.css b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.css index fd3281a27..893d3700c 100644 --- a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.css +++ b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.css @@ -1,4 +1,181 @@ -.grey { +.latest-activity-title { + text-align: left; + font-weight: 300; + font-family: "Roboto", sans-serif; + font-size: 1.25rem; + letter-spacing: 0px; + color: #212121; + opacity: 0.6; + padding-bottom: 1.2rem; +} + +.dmp-card, +.dataset-card { + min-width: 712px; + /* min-height: 308px; */ + background: #ffffff 0% 0% no-repeat padding-box; + box-shadow: 0px 3px 6px #0000001a; + border-radius: 4px; + opacity: 1; + margin-top: 2.43rem; + margin-bottom: 1rem; +} + +.remove-border-bottom ::ng-deep .mat-tab-header { + border-bottom: none; +} + +input[type="text"] { + background: #fafafa 0% 0% no-repeat padding-box; + border: 1px solid #d1d1d1; + border-radius: 4px; + opacity: 1; + width: 347px; + height: 56px; + font-family: Arial, FontAwesome; + padding-left: 15px; +} + +.edited-date { + text-align: left; + font-weight: 300; + font-family: "Roboto", sans-serif; + line-height: 2.4; + letter-spacing: 0px; + color: #212121; + opacity: 0.6; +} + +.dmp-label { + background: #129d99 0% 0% no-repeat padding-box; + border-radius: 4px 0px; + opacity: 1; + width: 67px; + height: 37px; + color: #ffffff; + line-height: 2.4; + opacity: 0.75; +} + +.dataset-label { + width: 158px; + height: 37px; + background: #f7dd72 0% 0% no-repeat padding-box; + border-radius: 4px 0px; + text-align: left; + line-height: 2.8; + font-size: 0.875rem; + letter-spacing: 0px; + color: #212121; + opacity: 0.75; +} + +.dmp-title, +.dataset-title { + text-align: left; + font-weight: 500; + font-family: "Roboto", sans-serif; + font-size: 1rem; + opacity: 0.81; + padding-top: 0.75rem; + padding-bottom: 0.55rem; + color: #212121; +} + +.dataset-subtitle, +.dmp-subtitle { + display: flex; + flex-direction: row; + text-align: left; + font-weight: 400; + font-family: "Roboto", sans-serif; + font-size: 0.875rem; + opacity: 1; + align-items: center; + color: #848484; +} + +.dmp-title-draft { + text-align: left; + font-weight: 500; + font-family: "Roboto", sans-serif; + font-size: 1rem; + opacity: 0.81; + padding-top: 0.75rem; + padding-bottom: 0.55rem; + color: #f16868; +} + +.icon-align { + display: inline-flex; + vertical-align: middle; + padding-bottom: 0.4rem; +} + +.dataset-card-actions, +.dmp-card-actions { + display: flex; + flex-direction: row; + border-top: 1px solid #dbdbdb; + line-height: 4; + color: #848484; +} + +.dataset-card-actions a, +.dmp-card-actions a { + color: #848484 !important; + text-decoration: none !important; +} + +.dataset-card-actions a:hover, +.dmp-card-actions a:hover { + color: #129d99 !important; +} + +.dmp-dataset-descriptions-title { + color: #000000; + opacity: 0.6; + padding-top: 1.5rem; + padding-bottom: 0.8rem; +} + +.dmp-dataset-descriptions-name { + color: #000000; + opacity: 0.6; + font-weight: 700; +} + +.show-more { + color: black !important; +} + +.show-more:hover { + color: #129d99 !important; +} + +.btn-load-more { + border: 2px solid #212121; + border-radius: 30px; + opacity: 1; + width: 132px; + height: 40px; + margin-top: 4.125rem; +} + +.btn-load-more:hover { + background-color: black; + color: white; +} + +.draft { + color: #f16868; +} + +.pointer { + cursor: pointer; +} + +/* .grey { color: rgb(162, 162, 162); } @@ -66,4 +243,4 @@ td:hover .draft-desc:after { .view-all:hover { color: rgb(46, 117, 182) !important; -} +} */ 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 cca60626e..767a57fb7 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,69 @@ -
+
+
+
+ +
+
{{'DATASET-LISTING.DATASET-DESCRIPTION' | translate}}
+
{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{activity.modified | date:"longDate"}}
+
+
{{'DATASET-LISTING.DATASET-DESCRIPTION' | translate}}: {{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}}
+
+ +
{{'DATASET-LISTING.TOOLTIP.DMP-FOR' | translate}}: {{activity.dmp}}
+
+
+ + + + + + + + + + + + +
+
+
+ +
+ +
{{'GENERAL.NAMES.DATASET' | translate}}: {{ dataset.label }} {{'DRAFTS.FOR-DMP' | translate}} {{ dataset.dmp }} {{'DRAFTS.FOR-GRANT' | translate}} {{ dataset.grant }}
@@ -35,4 +97,4 @@
- + --> 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 1d18f127a..0d3a63409 100644 --- a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Input } from '@angular/core'; +import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core'; import { DatasetService } from '../../../core/services/dataset/dataset.service'; import { DataTableRequest } from '../../../core/model/data-table/data-table-request'; import { DatasetCriteria } from '../../../core/query/dataset/dataset-criteria'; @@ -7,32 +7,61 @@ import { AuthService } from '../../../core/services/auth/auth.service'; import { RecentActivityType } from '../../../core/common/enum/recent-activity-type'; import { 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 { 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 } from '@angular/forms'; +import { BaseComponent } from '@common/base/base.component'; +import { MatDialog } from '@angular/material'; +import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service'; +import { SnackBarNotificationLevel } from '@app/core/services/notification/ui-notification-service'; +import * as FileSaver from 'file-saver'; +import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; +import { UiNotificationService } from '@app/core/services/notification/ui-notification-service'; @Component({ selector: 'app-drafts', templateUrl: './drafts.component.html', styleUrls: ['./drafts.component.css'] }) -export class DraftsComponent implements OnInit { +export class DraftsComponent extends BaseComponent implements OnInit { + + @Input() routerLink: string; + @Output() totalCountDraftDatasets: EventEmitter = new EventEmitter(); + datasetDrafts: DatasetListingModel[]; datasetDraftsTypeEnum = RecentActivityType; - @Input() routerLink: string; status: number; + totalCount: number; + startIndex: number = 4; + pageSize: number = 5; + constructor( private router: Router, private datasetService: DatasetService, - private authentication: AuthService - ) { } + private authentication: AuthService, + private language: TranslateService, + public dialog: MatDialog, + private datasetWizardService: DatasetWizardService, + public enumUtils: EnumUtils, + private uiNotificationService: UiNotificationService + ) { + super(); + } ngOnInit() { const fields: Array = []; fields.push('-modified'); - const dmpDataTableRequest: DataTableRequest = new DataTableRequest(0, 2, { fields: fields }); + const dmpDataTableRequest: DataTableRequest = new DataTableRequest(0, 5, { fields: fields }); dmpDataTableRequest.criteria = new DatasetCriteria(); dmpDataTableRequest.criteria.status = DmpStatus.Draft; this.datasetService.getPaged(dmpDataTableRequest).subscribe(response => { this.datasetDrafts = response.data; + this.totalCount = response.totalCount; + this.totalCountDraftDatasets.emit(this.totalCount); }); } @@ -63,4 +92,147 @@ export class DraftsComponent implements OnInit { if (!this.isAuthenticated()) { return; } this.router.navigate(['/datasets'], { queryParams: { status: 0 } }); } + + roleDisplay(value: any) { + const principal: Principal = this.authentication.current(); + let role: number; + if (principal) { + value.forEach(element => { + if (principal.id === element.id) { + role = element.role; + } + }); + } + if (role === 0) { + return this.language.instant('DMP-LISTING.OWNER'); + } + else if (role === 1) { + return this.language.instant('DMP-LISTING.MEMBER'); + } + else { + return this.language.instant('DMP-LISTING.OWNER'); + } + } + + 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, + 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 + this.router.navigate(['/datasets/copy/' + result.datasetId], { queryParams: { newDmpId: newDmpId } }); + } + }); + } + + openConfirm(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.onCallbackSuccess(), + error => this.onCallbackError(error) + ); + } + }); + } + + 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); + } + + downloadPDF(dataset: DatasetListingModel): void { + this.datasetWizardService.downloadPDF(dataset.id as string) + .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); + }); + } + + downloadDOCX(dataset: DatasetListingModel): void { + this.datasetWizardService.downloadDOCX(dataset.id as string) + .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); + }); + + } + + downloadXML(dataset: DatasetListingModel): void { + this.datasetWizardService.downloadXML(dataset.id as string) + .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); + }); + } + + 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; + } + + public loadMore() { + const fields: Array = ["-modified"]; + const request = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }); + + request.criteria = new DatasetCriteria(); + request.criteria.like = ""; + + this.datasetService.getPaged(request).pipe(takeUntil(this._destroyed)).subscribe(result => { + if (!result) { return []; } + this.datasetDrafts = this.datasetDrafts.concat(result.data); + }); + this.startIndex = this.startIndex + this.pageSize; + } } 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 d46bd9a1d..0cf7f52f4 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 @@ -68,6 +68,9 @@ +
+ +
diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.html b/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.html index 93a39c637..3d057a645 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.html +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.html @@ -19,9 +19,11 @@ {{'DATASET-LISTING.COLUMNS.GRANT' | translate}}: {{activity.grant}}
-
{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}}
-
{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}
-
{{'DATASET-LISTING.TOOLTIP.DMP-FOR' | translate}}: {{activity.dmp}}
+
{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}} +
{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}
+
+ +
{{'DATASET-LISTING.TOOLTIP.DMP-FOR' | translate}}: {{activity.dmp}}
@@ -59,5 +61,8 @@
+
+ +
diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.ts index d46264e0f..769780f85 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, Output, EventEmitter } from '@angular/core'; import { DatasetListingModel } from '@app/core/model/dataset/dataset-listing'; import { DatasetService } from '@app/core/services/dataset/dataset.service'; import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; @@ -28,7 +28,12 @@ import { DatasetStatus } from '@app/core/common/enum/dataset-status'; }) export class RecentEditedDatasetActivityComponent extends BaseComponent implements OnInit { + @Output() totalCountDatasets: EventEmitter = new EventEmitter(); + datasetActivities: DatasetListingModel[]; + totalCount: number; + startIndex: number = 4; + pageSize: number = 5; // publicMode = false; constructor( @@ -47,17 +52,33 @@ export class RecentEditedDatasetActivityComponent extends BaseComponent implemen ngOnInit() { if (this.isAuthenticated()) { const fields: Array = ["-modified"]; - const datasetDataTableRequest: DataTableRequest = new DataTableRequest(0, 5, { fields: fields }); + const datasetDataTableRequest: DataTableRequest = new DataTableRequest(0, this.pageSize, { fields: fields }); datasetDataTableRequest.criteria = new DatasetCriteria(); datasetDataTableRequest.criteria.like = ""; this.datasetService .getPaged(datasetDataTableRequest) .subscribe(response => { this.datasetActivities = response.data; + this.totalCount = response.totalCount; + this.totalCountDatasets.emit(this.totalCount); }); } } + public loadMore() { + const fields: Array = ["-modified"]; + const request = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }); + + request.criteria = new DatasetCriteria(); + request.criteria.like = ""; + + this.datasetService.getPaged(request).pipe(takeUntil(this._destroyed)).subscribe(result => { + if (!result) { return []; } + this.datasetActivities = this.datasetActivities.concat(result.data); + }); + this.startIndex = this.startIndex + this.pageSize; + } + public isAuthenticated(): boolean { return !!this.authentication.current(); } diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.css b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.css new file mode 100644 index 000000000..c2ce5bb3c --- /dev/null +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.css @@ -0,0 +1,243 @@ +.latest-activity-title { + text-align: left; + font-weight: 300; + font-family: "Roboto", sans-serif; + font-size: 1.25rem; + letter-spacing: 0px; + color: #212121; + opacity: 0.6; + padding-bottom: 1.2rem; +} + +.dmp-card, +.dataset-card { + min-width: 712px; + /* min-height: 308px; */ + background: #ffffff 0% 0% no-repeat padding-box; + box-shadow: 0px 3px 6px #0000001a; + border-radius: 4px; + opacity: 1; + margin-top: 2.43rem; + margin-bottom: 1rem; +} + +.remove-border-bottom ::ng-deep .mat-tab-header { + border-bottom: none; +} + +input[type="text"] { + background: #fafafa 0% 0% no-repeat padding-box; + border: 1px solid #d1d1d1; + border-radius: 4px; + opacity: 1; + width: 347px; + height: 56px; + font-family: Arial, FontAwesome; + padding-left: 15px; +} + +.edited-date { + text-align: left; + font-weight: 300; + font-family: "Roboto", sans-serif; + line-height: 2.4; + letter-spacing: 0px; + color: #212121; + opacity: 0.6; +} + +.dmp-label { + background: #129d99 0% 0% no-repeat padding-box; + border-radius: 4px 0px; + opacity: 1; + width: 67px; + height: 37px; + color: #ffffff; + line-height: 2.4; + opacity: 0.75; +} + +.dataset-label { + width: 158px; + height: 37px; + background: #f7dd72 0% 0% no-repeat padding-box; + border-radius: 4px 0px; + text-align: left; + line-height: 2.8; + font-size: 0.875rem; + letter-spacing: 0px; + color: #212121; + opacity: 0.75; +} + +.dmp-title, +.dataset-title { + text-align: left; + font-weight: 500; + font-family: "Roboto", sans-serif; + font-size: 1rem; + opacity: 0.81; + padding-top: 0.75rem; + padding-bottom: 0.55rem; + color: #212121; +} + +.dataset-subtitle, +.dmp-subtitle { + display: flex; + flex-direction: row; + text-align: left; + font-weight: 400; + font-family: "Roboto", sans-serif; + font-size: 0.875rem; + opacity: 1; + align-items: center; + color: #848484; +} + +.dmp-title-draft { + text-align: left; + font-weight: 500; + font-family: "Roboto", sans-serif; + font-size: 1rem; + opacity: 0.81; + padding-top: 0.75rem; + padding-bottom: 0.55rem; + color: #f16868; +} + +.icon-align { + display: inline-flex; + vertical-align: middle; + padding-bottom: 0.4rem; +} + +.dataset-card-actions, +.dmp-card-actions { + display: flex; + flex-direction: row; + border-top: 1px solid #dbdbdb; + line-height: 4; + color: #848484; +} + +.dataset-card-actions a, +.dmp-card-actions a { + color: #848484 !important; + text-decoration: none !important; +} + +.dataset-card-actions a:hover, +.dmp-card-actions a:hover { + color: #129d99 !important; +} + +.dmp-dataset-descriptions-title { + color: #000000; + opacity: 0.6; + padding-top: 1.5rem; + padding-bottom: 0.8rem; +} + +.dmp-dataset-descriptions-name { + color: #000000; + opacity: 0.6; + font-weight: 700; +} + +.show-more { + color: black !important; +} + +.show-more:hover { + color: #129d99 !important; +} + +.btn-load-more { + border: 2px solid #212121; + border-radius: 30px; + opacity: 1; + width: 132px; + height: 40px; + margin-top: 4.125rem; +} + +.btn-load-more:hover { + background-color: black; + color: white; +} + +.draft { + color: #f16868; +} + +.pointer { + cursor: pointer; +} + +/* th { + text-transform: uppercase; +} + +a { + color: #212529; +} + +.table-row { + cursor: pointer; + display: table-row; +} + +.is-public { + padding-left: 5px; + padding-right: 5px; + border: 1px solid #00b29f3b; + color: #00b29f; + background-color: #00b29f0f; + border-radius: 10em; + text-align: center; +} + +.template-name { + padding-left: 0.5em; + border: 1px solid rgb(218, 227, 243); + color: rgb(43, 104, 209); + background-color: rgb(236, 241, 249); + border-radius: 10em; + text-align: center; + max-width: 160px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.chip { + padding: 0.1em 1em; + margin-bottom: 1em; + margin-left: 2.5em; + margin-right: 2.5em; + border-radius: 10em; + background-color: #0d7489; + color: #fff; + text-transform: uppercase; + text-align: center; + font-weight: 500; + max-width: 160px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.mat-icon-button :hover { + color: rgb(120, 173, 220); +} + +.view-all { + margin-left: auto; + margin-bottom: 0px !important; + color: #6aa4d9; +} + +.view-all:hover { + color: rgb(46, 117, 182) !important; +} */ diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.html b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.html new file mode 100644 index 000000000..76973f33e --- /dev/null +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.html @@ -0,0 +1,208 @@ +
+
+ +
+
+
+
{{ 'DMP-LISTING.DMP' | translate }}
+
{{ 'DMP-LISTING.EDITED' | translate }}: {{ activity.modifiedTime | date: "longDate" }}
+
+
{{activity.label}}
+
+ {{ roleDisplay(activity.users) }} + . + public{{'TYPES.DMP-VISIBILITY.PUBLIC' | translate}} + done{{ enumUtils.toDmpStatusString(activity.status) }} + create{{ enumUtils.toDmpStatusString(activity.status) }} + . + {{'DMP-LISTING.VERSION' | translate}} {{activity.version}} + . + {{ 'DMP-LISTING.GRANT' | translate }}: {{activity.grant}} +
+
{{'DMP-LISTING.CONTAINED-DATASETS' | translate}}: ({{activity.datasets.length}}) +
+
+
+
{{dataset.label}},
+
{{dataset.label}}
+
+
+ {{'GENERAL.ACTIONS.SHOW-MORE' | translate}} +
+ + + + + + + + + + + + + +
+
+
+ +
+
+ + + + + + + diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts new file mode 100644 index 000000000..7cc18c095 --- /dev/null +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts @@ -0,0 +1,328 @@ +import { Component, OnInit, Output, EventEmitter } from '@angular/core'; +import { MatDialog } from '@angular/material'; +import { Router } from '@angular/router'; +import { RecentActivityType } from '@app/core/common/enum/recent-activity-type'; +import { Principal } from '@app/core/model/auth/principal'; +import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; +import { DmpListingModel } from '@app/core/model/dmp/dmp-listing'; +import { DmpCriteria } from '@app/core/query/dmp/dmp-criteria'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { DmpService } from '@app/core/services/dmp/dmp.service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { BaseComponent } from '@common/base/base.component'; +import { TranslateService } from '@ngx-translate/core'; +import * as FileSaver from 'file-saver'; +import { takeUntil } from 'rxjs/operators'; +import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dmp-invitation.component'; +import { DmpStatus } from '@app/core/common/enum/dmp-status'; +import { DatasetService } from '@app/core/services/dataset/dataset.service'; +import { DatasetListingModel } from '@app/core/model/dataset/dataset-listing'; +import { Role } from '@app/core/common/enum/role'; + +@Component({ + selector: 'app-recent-edited-dmp-activity', + templateUrl: './recent-edited-dmp-activity.component.html', + styleUrls: ['./recent-edited-dmp-activity.component.css'] +}) +export class RecentEditedDmpActivityComponent extends BaseComponent implements OnInit { + + @Output() totalCountDmps: EventEmitter = new EventEmitter(); + + dmpActivities: DmpListingModel[]; + datasetActivities: DatasetListingModel[]; + // allRecentActivities: RecentActivity[] = []; + recentActivityTypeEnum = RecentActivityType; + isDraft: boolean; + + totalCount: number; + startIndex: number = 4; + pageSize: number = 5; + + constructor( + private router: Router, + public enumUtils: EnumUtils, + private authentication: AuthService, + private dmpService: DmpService, + private datasetService: DatasetService, + private language: TranslateService, + private dialog: MatDialog, + private uiNotificationService: UiNotificationService + ) { + super(); + } + + ngOnInit() { + if (this.isAuthenticated()) { + const fields: Array = ["-modified"]; + const dmpDataTableRequest: DataTableRequest = new DataTableRequest(0, 5, { fields: fields }); + dmpDataTableRequest.criteria = new DmpCriteria(); + dmpDataTableRequest.criteria.like = ""; + this.dmpService + .getPaged(dmpDataTableRequest, "listing") + .subscribe(response => { + this.dmpActivities = response.data; + this.totalCount = response.totalCount; + this.totalCountDmps.emit(this.totalCount); + // this.dmpActivities.forEach(dmpActivity => { + // const recentActivity: RecentActivity = { + // activityData: dmpActivity, + // activityType: RecentActivityType.Dmp + // }; + // this.allRecentActivities.push(recentActivity) + // }) + }); + + // const datasetDataTableRequest: DataTableRequest = new DataTableRequest(0, 5, { fields: fields }); + // datasetDataTableRequest.criteria = new DatasetCriteria(); + // datasetDataTableRequest.criteria.like = ""; + // this.datasetService + // .getPaged(datasetDataTableRequest) + // .subscribe(response => { + // this.datasetActivities = response.data; + // this.datasetActivities.forEach(datasetActivity => { + // const recentActivity: RecentActivity = { + // activityData: datasetActivity, + // activityType: RecentActivityType.Dataset + // }; + // this.allRecentActivities.push(recentActivity) + // }) + // }); + } + } + + public isAuthenticated(): boolean { + return !!this.authentication.current(); + } + + isUserOwner(activity: DmpListingModel): boolean { + const principal: Principal = this.authentication.current(); + if (principal) return principal.id === activity.users.find(x => x.role === Role.Owner).id; + } + + 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', + 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.onCallbackSuccess() }, + error => this.onDeleteCallbackError(error) + ); + } + }); + } + + openShareDialog(rowId: any, rowName: any) { + const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { + // height: '250px', + // width: '700px', + 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']); + } + + 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.Grant: { + this.router.navigate(["grants/edit/" + id]); + return; + } + case RecentActivityType.Dataset: { + this.router.navigate(["datasets/edit/" + id]); + return; + } + case RecentActivityType.Dmp: { + this.router.navigate(["plans/overview/" + id]); + return; + } + default: + throw new Error("Unsupported Activity Type "); + } + } + + // navigateToUrl() { + // this.router.navigate(["plans/"]); + // } + + roleDisplay(value: any) { + const principal: Principal = this.authentication.current(); + let role: number; + if (principal) { + value.forEach(element => { + if (principal.id === element.id) { + role = element.role; + } + }); + } + if (role === 0) { + return this.language.instant('DMP-LISTING.OWNER'); + } + else if (role === 1) { + return this.language.instant('DMP-LISTING.MEMBER'); + } + else { + return this.language.instant('DMP-LISTING.OWNER'); + } + } + + // dmpProfileDisplay(value: any) { + // if (value != null) { + // return value; + // } + // else { + // 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); + }); + } + + 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); + }) + } + + 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; + } + + addDataset(activityId: String) { + this.router.navigate(['/datasets/new/' + activityId]); + } + + newVersion(id: String, label: String) { + this.router.navigate(['/plans/new_version/' + id, { dmpLabel: label }]); + } + + viewVersions(rowId: String, rowLabel: String, activity: DmpListingModel) { + if (activity.public && !this.isUserOwner) { + this.router.navigate(['/explore-plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } }); + } else { + this.router.navigate(['/plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } }); + } + } + + public loadMore() { + const fields: Array = ["-modified"]; + const request = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }); + + request.criteria = new DmpCriteria(); + request.criteria.like = ""; + + this.dmpService.getPaged(request, "listing").pipe(takeUntil(this._destroyed)).subscribe(result => { + if (!result) { return []; } + this.dmpActivities = this.dmpActivities.concat(result.data); + }); + this.startIndex = this.startIndex + this.pageSize; + } + + // advancedClicked(dmp: DmpListingModel) { + // const dialogRef = this.dialog.open(ExportMethodDialogComponent, { + // maxWidth: '500px', + // data: { + // message: "Download as:", + // XMLButton: "XML", + // documentButton: "Document", + // pdfButton: "PDF", + // jsonButton: "JSON" + + // } + // }); + // 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); + // } else if (result == "json") { + // this.downloadJson(dmp.id) + // } + // }); + // } +}