Merge remote-tracking branch 'origin/ui-redesign' into ui-redesign

# Conflicts:
#	dmp-frontend/src/app/core/services/dashboard/dashboard.service.ts
This commit is contained in:
George Kalampokis 2020-07-02 12:02:47 +03:00
commit 626b499ecc
24 changed files with 1804 additions and 280 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<String, any>;
datasets: RecentDatasetModel[];
associatedProfiles: DmpAssociatedProfileModel[];
organisations: String;
groupId: string;
users: UserInfoListingModel[];
isPublic: boolean;
}

View File

@ -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';
import { RecentActivityCriteria } from '@app/core/query/recent-activity/recent-activity-criteria';
@Injectable()
@ -26,7 +27,7 @@ export class DashboardService {
return this.http.get<DashboardStatisticsModel>(this.actionUrl + 'me/getStatistics', { headers: this.headers });
}
getRecentAcitvity(criteria: RecentActivityCriteria): Observable<any[]> {
return this.http.post<any[]>(this.actionUrl + 'recentActivity', criteria, {headers: this.headers});
getRecentAcitvity(criteria: RecentActivityCriteria): Observable<RecentActivityModel[]> {
return this.http.post<RecentActivityModel[]>(this.actionUrl + 'recentActivity', criteria, {headers: this.headers});
}
}

View File

@ -8,12 +8,10 @@
<div class="col-md-8">
<div class="card" [style.display]="isVisible ? 'block' : 'none'">
<!-- <a class="col-auto d-flex" (click)="closeCard()"><span class="ml-auto pt-3 material-icons clear-icon">clear</span></a> -->
<p class="card-title mb-0">What is a DMP in ARGOS</p>
<p class="card-content mb-0">A Data Management Plan (DMP) is a living document describing the datasets that are generated and/ or re-used
during and after a research lifetime. DMPs aim to provide researchers with essential information to re-produce,
re-distribute and re-purpose research results thus assuring for their validity and exploitation.</p>
<p class="card-title mb-0">{{'DASHBOARD.DMP-QUESTION' | translate}}</p>
<p class="card-content mb-0">{{'DASHBOARD.INFO-DMP-TEXT' | translate}}</p>
<p class="card-content pt-3 mb-0">
New with DMPs? Visit <a><u>OpenAIREs Guide for Researchers</u></a> to learn more about how to create one!
{{'DASHBOARD.NEW-QUESTION' | translate}} <a><u>{{'DASHBOARD.OPEN-AIR-GUIDE' | translate}}</u></a> {{'DASHBOARD.LEARN-MORE' | translate}}
</p>
<div class="d-flex">
<button type="button" class="col-auto align-self-center normal-btn">Start your first DMP</button>
@ -22,15 +20,15 @@
</div>
</div>
<div class="col-md-4">
<div class="personal-usage">Personal usage</div>
<div class="personal-usage">{{'DASHBOARD.PERSONAL-USAGE' | translate}}</div>
<div class="counter-zero">0</div>
<a href="#" class="link">DMP's</a>
<a href="#" class="link">{{'DASHBOARD.DMPS' | translate}}</a>
<div class="counter-zero">0</div>
<a href="#" class="link">Dataset Descriptions</a>
<a href="#" class="link">{{'DASHBOARD.DATASET-DESCRIPTIONS' | translate}}</a>
<div class="counter-zero">0</div>
<a href="#" class="link-disabled">Grants</a>
<a href="#" class="link-disabled">{{'DASHBOARD.GRANTS' | translate}}</a>
<div class="counter-zero">0</div>
<a href="#" class="link-disabled">Related organizations</a>
<a href="#" class="link-disabled">{{'DASHBOARD.RELATED-ORGANISATIONS' | translate}}</a>
</div>
</div>
</div>
@ -53,30 +51,21 @@
</div>
<div class="latest-activity-title">Latest activity</div>
<mat-tab-group mat-align-tabs="start" class="remove-border-bottom">
<!-- +counter -->
<mat-tab label="All">
<div class="col-auto pt-3"><input type="text" class="d-flex ml-auto" placeholder="&nbsp;&nbsp;&#xf002;&nbsp;&nbsp;Search"></div>
<app-recent-edited-activity></app-recent-edited-activity>
<div class="d-flex justify-content-center">
<button type="button" class="btn-load-more">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
</mat-tab>
<mat-tab label="{{'DASHBOARD.DRAFTS' | translate}}">
<app-drafts></app-drafts>
</mat-tab>
<mat-tab label="{{'DASHBOARD.DMPS' | translate}}">
<mat-tab label="{{'DASHBOARD.DRAFTS' | translate}} ({{this.totalDraftDatasets}})">
<div class="col-auto pt-3"><input type="text" class="d-flex ml-auto" placeholder="&nbsp;&nbsp;&#xf002;&nbsp;&nbsp;Search"></div>
<app-recent-edited-activity></app-recent-edited-activity>
<div class="d-flex justify-content-center">
<button type="button" class="btn-load-more">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
<app-drafts (totalCountDraftDatasets)="onCountDraftDatasets($event)"></app-drafts>
</mat-tab>
<mat-tab label="{{'DASHBOARD.DATASET-DESCRIPTIONS' | translate}}">
<mat-tab label="{{'DASHBOARD.DMPS' | translate}} ({{this.totalDmps}})">
<div class="col-auto pt-3"><input type="text" class="d-flex ml-auto" placeholder="&nbsp;&nbsp;&#xf002;&nbsp;&nbsp;Search"></div>
<app-recent-edited-dataset-activity></app-recent-edited-dataset-activity>
<div class="d-flex justify-content-center">
<button type="button" class="btn-load-more">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
<app-recent-edited-dmp-activity (totalCountDmps)="onCountDmps($event)"></app-recent-edited-dmp-activity>
</mat-tab>
<mat-tab label="{{'DASHBOARD.DATASET-DESCRIPTIONS' | translate}} ({{this.totalDatasets}})">
<div class="col-auto pt-3"><input type="text" class="d-flex ml-auto" placeholder="&nbsp;&nbsp;&#xf002;&nbsp;&nbsp;Search"></div>
<app-recent-edited-dataset-activity (totalCountDatasets)="onCountDatasets($event)"></app-recent-edited-dataset-activity>
</mat-tab>
</mat-tab-group>
</div>

View File

@ -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']);
// }

View File

@ -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

View File

@ -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;
}
} */

View File

@ -1,4 +1,69 @@
<div class="card card-draft">
<div *ngFor="let activity of datasetDrafts">
<div class="dataset-card">
<div>
<!-- <div [routerLink]="['../datasets/overview/' + activity.id]"> -->
<div class="d-flex flex-direction-row">
<div class="col-auto dataset-label">{{'DATASET-LISTING.DATASET-DESCRIPTION' | translate}}</div>
<div class="col-auto ml-auto edited-date">{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{activity.modified | date:"longDate"}}</div>
</div>
<div class="col-auto dataset-title">{{'DATASET-LISTING.DATASET-DESCRIPTION' | translate}}: {{activity.label}}</div>
<div class="dataset-subtitle">
<span class="col-auto">{{ roleDisplay(activity.users) }}</span>
<span>.</span>
<span class="col-auto" *ngIf="activity.status === 1 && activity.public === true"><span class="material-icons icon-align">public</span>{{'DATASET-LISTING.STATES.PUBLIC' | translate}}</span>
<span *ngIf="activity.status === 1 && activity.public === false" class="col-auto"><span class="material-icons icon-align">done</span>{{ enumUtils.toDmpStatusString(activity.status) }}</span>
<span *ngIf="activity.status === 0" class=" col-auto draft"><span class="material-icons icon-align">create</span>{{ enumUtils.toDmpStatusString(activity.status) }}</span>
<span>.</span>
<span class="col">{{'DATASET-LISTING.COLUMNS.GRANT' | translate}}: {{activity.grant}}</span>
</div>
<div class="d-flex flex-direction-row pt-3 pb-3">
<div class="col-auto dataset-subtitle">{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}}
<div class="col-auto dmp-label ml-4">{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}</div>
</div>
<!-- <div class="col-auto dmp-label">{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}</div> -->
<div class="col dmp-title">{{'DATASET-LISTING.TOOLTIP.DMP-FOR' | translate}}: {{activity.dmp}}</div>
</div>
</div>
<div class="dataset-card-actions">
<a class="col-auto border-right pointer" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'DATASET-LISTING.ACTIONS.EXPORT' | translate}}</a>
<a class="col-auto border-right pointer" (click)="openShareDialog(activity.dmpId, activity.dmp)"><span class="material-icons icon-align pr-2">group_add</span>{{'DATASET-LISTING.ACTIONS.INVITE-COLLABORATORS' | translate}}</a>
<a class="col-auto pointer" [matMenuTriggerFor]="actionsMenu"><span class="material-icons icon-align pl-2">more_horiz</span></a>
<!-- <a class="col-auto" [matMenuTriggerFor]="actionsMenu" *ngIf="!publicMode"><span class="material-icons icon-align pl-2">more_horiz</span></a> -->
</div>
<mat-menu #actionsMenu="matMenu">
<button mat-menu-item (click)="openDmpSearchDialogue(activity.id)" class="menu-item">
<mat-icon>file_copy</mat-icon>{{'DATASET-WIZARD.ACTIONS.COPY-DATASET' | translate}}
</button>
<button mat-menu-item (click)="openConfirm(activity.id)" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'DATASET-WIZARD.ACTIONS.DELETE' | translate }}
</button>
<!-- <button mat-menu-item *ngIf="needsUpdate(activity)" class="menu-item" (click)="openUpdateDatasetProfileDialogue(activity.id);">
<mat-icon>update</mat-icon>
{{ 'DATASET-WIZARD.ACTIONS.UPDATE-DATASET-PROFILE' | translate }}
</button> -->
</mat-menu>
<mat-menu #exportMenu="matMenu" xPosition="before">
<button mat-menu-item (click)="downloadPDF(activity)">
<i class="fa fa-file-pdf-o pr-2"></i>
<span>{{'GENERAL.FILE-TYPES.PDF' | translate}}</span>
</button>
<button mat-menu-item (click)="downloadDOCX(activity)">
<i class="fa fa-file-word-o pr-2"></i>
<span>{{'GENERAL.FILE-TYPES.DOC' | translate}}</span>
</button>
<button mat-menu-item (click)="downloadXML(activity)">
<i class="fa fa-file-code-o pr-2"></i>
<span>{{'GENERAL.FILE-TYPES.XML' | translate}}</span>
</button>
</mat-menu>
</div>
</div>
<div class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
<!-- <div class="card card-draft">
<div class="card-header card-header-plain">
<div class="card-desc">
<h4 class="card-title">{{ 'TYPES.DATASET-STATUS.DRAFT' | translate }}</h4>
@ -16,9 +81,6 @@
<i class="material-icons-outlined grey">library_books</i>
</div>
<div class="col-md-10">
<!-- <div class="drafts-more-btn">
<i class="material-icons more-icon">more_horiz</i>
</div> -->
<div class="draft-title">
{{'GENERAL.NAMES.DATASET' | translate}}: {{ dataset.label }} {{'DRAFTS.FOR-DMP' | translate}} {{ dataset.dmp }} {{'DRAFTS.FOR-GRANT' | translate}} {{ dataset.grant }}
</div>
@ -35,4 +97,4 @@
</tbody>
</table>
</div>
</div>
</div> -->

View File

@ -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,62 @@ 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';
import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dmp-invitation.component';
@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<any> = 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<string> = [];
fields.push('-modified');
const dmpDataTableRequest: DataTableRequest<DatasetCriteria> = new DataTableRequest(0, 2, { fields: fields });
const dmpDataTableRequest: DataTableRequest<DatasetCriteria> = 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 +93,159 @@ 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)
);
}
});
}
openShareDialog(dmpRowId: any, dmpRowName: any) {
const dialogRef = this.dialog.open(DmpInvitationDialogComponent, {
// height: '250px',
// width: '700px',
restoreFocus: false,
data: {
dmpId: dmpRowId,
dmpName: dmpRowName
}
});
}
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<string> = ["-modified"];
const request = new DataTableRequest<DatasetCriteria>(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;
}
}

View File

@ -68,6 +68,9 @@
</mat-menu>
</div>
</div>
<div class="d-flex justify-content-center">
<button type="button" class="btn-load-more">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
</div>
<!-- if dataset -->

View File

@ -19,14 +19,16 @@
<span class="col">{{'DATASET-LISTING.COLUMNS.GRANT' | translate}}: {{activity.grant}}</span>
</div>
<div class="d-flex flex-direction-row pt-3 pb-3">
<div class="col-auto dataset-subtitle">{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}}</div>
<div class="col-auto dmp-label">{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}</div>
<div class="col-auto dmp-title">{{'DATASET-LISTING.TOOLTIP.DMP-FOR' | translate}}: {{activity.dmp}}</div>
<div class="col-auto dataset-subtitle">{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}}
<div class="col-auto dmp-label ml-4">{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}</div>
</div>
<!-- <div class="col-auto dmp-label">{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}</div> -->
<div class="col dmp-title">{{'DATASET-LISTING.TOOLTIP.DMP-FOR' | translate}}: {{activity.dmp}}</div>
</div>
</div>
<div class="dataset-card-actions">
<a class="col-auto border-right pointer" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'DATASET-LISTING.ACTIONS.EXPORT' | translate}}</a>
<a class="col-auto border-right pointer"><span class="material-icons icon-align pr-2">group_add</span>{{'DATASET-LISTING.ACTIONS.INVITE-COLLABORATORS' | translate}}</a>
<a class="col-auto border-right pointer" (click)="openShareDialog(activity.dmpId, activity.dmp)"><span class="material-icons icon-align pr-2">group_add</span>{{'DATASET-LISTING.ACTIONS.INVITE-COLLABORATORS' | translate}}</a>
<a class="col-auto pointer" [matMenuTriggerFor]="actionsMenu"><span class="material-icons icon-align pl-2">more_horiz</span></a>
<!-- <a class="col-auto" [matMenuTriggerFor]="actionsMenu" *ngIf="!publicMode"><span class="material-icons icon-align pl-2">more_horiz</span></a> -->
</div>
@ -59,5 +61,8 @@
</mat-menu>
</div>
</div>
<div class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
</div>

View File

@ -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';
@ -20,6 +20,7 @@ import { ValidationErrorModel } from '@common/forms/validation/error-model/valid
import { UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { SnackBarNotificationLevel } from '@common/modules/notification/ui-notification-service';
import { DatasetStatus } from '@app/core/common/enum/dataset-status';
import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dmp-invitation.component';
@Component({
selector: 'app-recent-edited-dataset-activity',
@ -28,7 +29,12 @@ import { DatasetStatus } from '@app/core/common/enum/dataset-status';
})
export class RecentEditedDatasetActivityComponent extends BaseComponent implements OnInit {
@Output() totalCountDatasets: EventEmitter<any> = new EventEmitter();
datasetActivities: DatasetListingModel[];
totalCount: number;
startIndex: number = 4;
pageSize: number = 5;
// publicMode = false;
constructor(
@ -47,17 +53,33 @@ export class RecentEditedDatasetActivityComponent extends BaseComponent implemen
ngOnInit() {
if (this.isAuthenticated()) {
const fields: Array<string> = ["-modified"];
const datasetDataTableRequest: DataTableRequest<DatasetCriteria> = new DataTableRequest(0, 5, { fields: fields });
const datasetDataTableRequest: DataTableRequest<DatasetCriteria> = 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<string> = ["-modified"];
const request = new DataTableRequest<DatasetCriteria>(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();
}
@ -130,6 +152,18 @@ export class RecentEditedDatasetActivityComponent extends BaseComponent implemen
});
}
openShareDialog(dmpRowId: any, dmpRowName: any, activity: any) {
const dialogRef = this.dialog.open(DmpInvitationDialogComponent, {
// height: '250px',
// width: '700px',
restoreFocus: false,
data: {
dmpId: dmpRowId,
dmpName: dmpRowName
}
});
}
getFilenameFromContentDispositionHeader(header: string): string {
const regex: RegExp = new RegExp(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/g);

View File

@ -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;
} */

View File

@ -0,0 +1,208 @@
<div *ngIf="dmpActivities != null">
<div *ngFor="let activity of dmpActivities">
<!-- if dmp -->
<div class="dmp-card">
<div [routerLink]="['../plans/overview/' + activity.id]" class="pointer">
<div class="d-flex flex-direction-row">
<div class="col-auto dmp-label">{{ 'DMP-LISTING.DMP' | translate }}</div>
<div class="col-auto ml-auto edited-date">{{ 'DMP-LISTING.EDITED' | translate }}: {{ activity.modifiedTime | date: "longDate" }}</div>
</div>
<div class="col-auto" [ngClass]="{'dmp-title': !isDraft, 'dmp-title-draft': isDraft}">{{activity.label}}</div>
<div class="dmp-subtitle">
<span class="col-auto">{{ roleDisplay(activity.users) }}</span>
<span>.</span>
<span class="col-auto" *ngIf="activity.status === 1 && activity.public === true"><span class="material-icons icon-align">public</span>{{'TYPES.DMP-VISIBILITY.PUBLIC' | translate}}</span>
<span *ngIf="activity.status === 1 && activity.public === false" class="col-auto"><span class="material-icons icon-align">done</span>{{ enumUtils.toDmpStatusString(activity.status) }}</span>
<span *ngIf="activity.status === 0" class=" col-auto draft"><span class="material-icons icon-align">create</span>{{ enumUtils.toDmpStatusString(activity.status) }}</span>
<span>.</span>
<span class="col-auto">{{'DMP-LISTING.VERSION' | translate}} {{activity.version}}</span>
<span>.</span>
<span class="col">{{ 'DMP-LISTING.GRANT' | translate }}: {{activity.grant}}</span>
</div>
<div class="col-auto dmp-dataset-descriptions-title">{{'DMP-LISTING.CONTAINED-DATASETS' | translate}}: ({{activity.datasets.length}})
</div>
<div *ngFor="let dataset of activity.datasets; let i = index; let last = last" [ngClass]="{'pb-3': i === activity.datasets.length - 1}">
<div *ngIf="i < 3">
<div class="col-auto dmp-dataset-descriptions-name" *ngIf="!last">{{dataset.label}},</div>
<div class="col-auto dmp-dataset-descriptions-name" *ngIf="last">{{dataset.label}}</div>
</div>
</div>
<a class="d-flex justify-content-center pb-3 show-more" *ngIf="activity.datasets.length > 3" [routerLink]="['../plans/overview/' + activity.id]"><u>{{'GENERAL.ACTIONS.SHOW-MORE' | translate}}</u></a>
</div>
<div class="dmp-card-actions">
<a class="col-auto border-right pointer" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'DMP-LISTING.ACTIONS.EXPORT' | translate}}</a>
<a class="col-auto border-right pointer" (click)="addDataset(activity.id)"><span class="material-icons icon-align">add</span>{{'DMP-LISTING.ACTIONS.ADD-DATASET-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" (click)="openShareDialog(activity.id, activity.label)"><span class="material-icons icon-align pr-2">group_add</span>{{'DMP-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" (click)="cloneClicked(activity)"><span class="material-icons icon-align pr-2">filter_none</span>{{'DMP-LISTING.ACTIONS.CLONE' | translate}}</a>
<a class="col-auto pointer" [matMenuTriggerFor]="actionsMenu"><span class="material-icons icon-align pl-2">more_horiz</span></a>
</div>
<mat-menu #exportMenu="matMenu" xPosition="before">
<button mat-menu-item (click)="downloadPDF(activity.id)">
<i class="fa fa-file-pdf-o pr-2"></i>
<span>{{'GENERAL.FILE-TYPES.PDF' | translate}}</span>
</button>
<button mat-menu-item (click)="downloadDocx(activity.id)">
<i class="fa fa-file-word-o pr-2"></i>
<span>{{'GENERAL.FILE-TYPES.DOC' | translate}}</span>
</button>
<button mat-menu-item (click)="downloadXml(activity.id)">
<i class="fa fa-file-code-o pr-2"></i>
<span>{{'GENERAL.FILE-TYPES.XML' | translate}}</span>
</button>
<button mat-menu-item (click)="downloadJson(activity.id)">
<i class="fa fa-file-o pr-2"></i>
<span>{{'GENERAL.FILE-TYPES.JSON' | translate}}</span>
</button>
</mat-menu>
<mat-menu #actionsMenu="matMenu" xPosition="before">
<button *ngIf="isUserOwner(activity)" mat-menu-item (click)="newVersion(activity.id, activity.label)">
<mat-icon>queue</mat-icon>{{'DMP-LISTING.ACTIONS.NEW-VERSION' | translate}}
</button>
<button mat-menu-item (click)="viewVersions(activity.groupId, activity.label)">
<mat-icon>library_books</mat-icon>{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}}
</button>
<button mat-menu-item *ngIf="isDraftDmp(activity) && isUserOwner(activity)" (click)="deleteClicked()" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'DMP-LISTING.ACTIONS.DELETE' | translate }}
</button>
</mat-menu>
</div>
</div>
<div class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
</div>
<!-- if dataset -->
<!-- <div *ngIf="true" class="dataset-card">
<div class="d-flex flex-direction-row">
<div class="col-auto dataset-label">Dataset Description</div>
<div class="col-auto ml-auto edited-date">Edited: 9 May 2020</div>
</div>
<div class="col-auto dataset-title">Dataset description: Horizon 2020 for Grant DMP of
Dataset description</div>
<div class="dataset-subtitle">
<span class="col-auto">Owner</span>
<span>.</span>
<span class="col-auto"><span class="material-icons icon-align">done</span>Finalized</span>
<span>.</span>
<span class="col-auto">Grant: NEANIAS Project</span>
</div>
<div class="d-flex flex-direction-row pt-3 pb-3">
<div class="col-auto dataset-subtitle">Part of</div>
<div class="col-auto dmp-label">DMP</div>
<div class="col-auto dmp-title">DMP for: Horizon 2020 for Grant DMP of the NEANIAS
DMP plan</div>
</div>
<div class="dataset-card-actions">
<a href="#" class="col-auto border-right"><span class="material-icons icon-align pr-2">open_in_new</span>Export</a>
<a href="#" class="col-auto border-right"><span class="material-icons icon-align pr-2">group_add</span>Invite
collaborators</a>
<a href="#" class="col-auto"><span class="material-icons icon-align pl-2">more_horiz</span></a>
</div>
</div> -->
<!-- Old version of dashboard -->
<!-- <div class="card">
<div class="card-header card-header-plain">
<div class="card-desc">
<h4 class="card-title">
{{ 'RECENT-ACTIVITY.LAST-EDITED-DMP' | translate}}
</h4>
</div>
<a class="view-all" [class.clickable]="isAuthenticated()" [routerLink]="['/plans/']">
{{ 'GENERAL.ACTIONS.VIEW-ALL' | translate}}</a>
</div>
<div class="card-body table-responsive">
<table class="table table-hover">
<thead class="text-default">
<th>{{ 'DATASET-PROFILE-LISTING.COLUMNS.NAME' | translate}}</th>
<th>{{ 'DATASET-PROFILE-LISTING.COLUMNS.TEMPLATE' | translate }}</th>
<th>{{ 'DATASET-PROFILE-LISTING.COLUMNS.GRANT' | translate }}</th>
<th>{{ 'DATASET-PROFILE-LISTING.COLUMNS.ROLE' | translate }}</th>
<th>{{ 'DATASET-PROFILE-LISTING.COLUMNS.ORGANIZATION' | translate }}</th>
<th>{{ 'DATASET-PROFILE-LISTING.COLUMNS.STATUS' | translate }}</th>
<th>{{ 'DATASET-PROFILE-LISTING.COLUMNS.EDITED' | translate }}</th>
<th></th>
</thead>
<tbody *ngIf="dmpActivities != null">
<a *ngFor="let activity of dmpActivities" class="table-row" [routerLink]="['../plans/overview/' + activity.id]">
<td>{{ activity.label }}</td>
<td>
<div *ngIf="activity.profile" matTooltip="{{ activity.profile }}" class="template-name">
{{ activity.profile }}
</div>
<div *ngIf="!(activity.profile)" class="template-name">--</div>
</td>
<td>{{ activity.grant }}</td>
<td>{{ roleDisplay(activity.users)}}</td>
<td>{{ activity.organisations }}</td>
<td *ngIf="activity.status === 1 && activity.public === true">
<div class="is-public">
{{'TYPES.DMP-VISIBILITY.PUBLIC' | translate}}
</div>
</td>
<td *ngIf="activity.status === 1 && activity.public === false" class="text-center">
{{ enumUtils.toDmpStatusString(activity.status) }}
</td>
<td *ngIf="activity.status === 0" class="text-center">
{{ enumUtils.toDmpStatusString(activity.status) }}
</td>
<td>
{{ activity.modifiedTime | date: "shortDate" }}
</td>
<td>
<button mat-icon-button [matMenuTriggerFor]="actionsMenu" class="ml-auto more-icon" (click)="$event.preventDefault(); $event.stopPropagation();">
<mat-icon class="more-horiz">more_horiz</mat-icon>
</button>
<mat-menu #actionsMenu="matMenu">
<button mat-menu-item (click)="editClicked(activity)" class="menu-item">
<mat-icon>edit</mat-icon>{{ 'DMP-LISTING.ACTIONS.EDIT' | translate }}
</button>
<button mat-menu-item (click)="cloneClicked(activity)" class="menu-item">
<mat-icon>add</mat-icon>{{ 'DMP-LISTING.ACTIONS.CLONE' | translate }}
</button>
<button mat-menu-item (click)="deleteClicked(activity)" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'DMP-LISTING.ACTIONS.DELETE' | translate }}
</button>
<button mat-menu-item [matMenuTriggerFor]="exportMethod" class="menu-item">
<mat-icon>save_alt</mat-icon>{{ 'DMP-LISTING.ACTIONS.EXP-AS' | translate }}
</button>
</mat-menu>
<mat-menu #exportMethod>
<button mat-menu-item (click)="downloadPDF(activity.id)">
<i class="fa fa-file-pdf-o pr-2"></i>
<span>{{'GENERAL.FILE-TYPES.PDF' | translate}}</span>
</button>
<button mat-menu-item (click)="downloadDocx(activity.id)">
<i class="fa fa-file-word-o pr-2"></i>
<span>{{'GENERAL.FILE-TYPES.DOC' | translate}}</span>
</button>
<button mat-menu-item (click)="downloadXml(activity.id)">
<i class="fa fa-file-code-o pr-2"></i>
<span>{{'GENERAL.FILE-TYPES.XML' | translate}}</span>
</button>
<button mat-menu-item (click)="downloadJson(activity.id)">
<i class="fa fa-file-o pr-2"></i>
<span>{{'GENERAL.FILE-TYPES.JSON' | translate}}</span>
</button>
</mat-menu>
</td>
</a>
</tbody>
<tbody *ngIf="dmpActivities == null">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
</div> -->

View File

@ -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<any> = 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<string> = ["-modified"];
const dmpDataTableRequest: DataTableRequest<DmpCriteria> = 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<DatasetCriteria> = 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<string> = ["-modified"];
const request = new DataTableRequest<DmpCriteria>(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)
// }
// });
// }
}

View File

@ -1,77 +1,108 @@
<div class="main-content pl-5 pr-5">
<div class="container-fluid ml-5 mr-5">
<div class="container-fluid pl-0 pr-0">
<div *ngIf="dmp">
<div class="row mb-2">
<mat-icon class="chevron-icon">chevron_left</mat-icon>
<p class="label-text">{{'DMP-WIZARD.ACTIONS.BACK' | translate}}</p>
</div>
<a class="row mb-2 pl-1" (click)="goBack()" role="button">
<mat-icon class="back-icon">chevron_left</mat-icon>
<p class="label-txt">{{'DMP-WIZARD.ACTIONS.BACK' | translate}}</p>
</a>
<div class="row">
<div class="col-md-8 col-lg-8">
<div class="col-md-8 col-lg-8 pl-4">
<div class="row">
<a mat-raised-button primary class="dmp-btn">
<span class="dmp-btn-text">{{ 'DATASET-LISTING.COLUMNS.DMP' | translate }}</span>
</a>
<span class="dmp-logo">{{ 'DATASET-LISTING.COLUMNS.DMP' | translate }}</span>
<p class="dmp-label ml-2 mb-0">{{ dmp.label }}</p>
</div>
<div class="row d-flex align-items-center mt-3 mb-4 label-text">
<div class="row d-flex align-items-center mt-3 mb-4 label-txt">
<div *ngIf="isUserDMPRelated()" class="d-flex">
<p class="ml-0 mr-3 mb-0 label-text"
matTooltip="{{'DMP-OVERVIEW.TOOLTIP.LEVEL-OF-ACCESS' | translate}}"
matTooltipPosition="above">
<p class="ml-0 mr-3 mb-0 label2-txt">
{{ roleDisplayFromList(dmp.users) }}</p>
</div>
<div class="d-flex mr-4">Public: {{ dmp.isPublic}}</div>
<div class="d-flex mr-4">Locked: {{ dmp.status}}</div>
<button class="d-flex mr-4 version-btn label-text">
{{'DMP-LISTING.COLUMNS.VERSION' | translate}}
<mat-select>
<mat-option *ngFor="let version of dmp.version" [value]="version">
{{version}}
</mat-option>
</mat-select>
<div class="d-flex mr-4">
<div *ngIf="dmp.isPublic" class="d-flex flex-row">
<mat-icon class="status-icon">public</mat-icon>
{{'DMP-OVERVIEW.PUBLIC' | translate}}
</div>
<div *ngIf="!dmp.isPublic" class="d-flex flex-row">
<mat-icon class="status-icon">public_off</mat-icon>
{{'DMP-OVERVIEW.PRIVATE' | translate}}
</div>
</div>
<div class="d-flex mr-4" (click)="checkLockStatus(dmp.id)">
<div *ngIf="lockStatus" class="d-flex flex-row">
<mat-icon class="status-icon">lock_outline</mat-icon>
{{'DMP-OVERVIEW.LOCKED' | translate}}
</div>
<div *ngIf="!lockStatus" class="d-flex flex-row">
<mat-icon class="status-icon">lock_open</mat-icon>
{{'DMP-OVERVIEW.UNLOCKED' | translate}}
</div>
</div>
<button class="d-flex mr-4 version-btn label2-txt"
(click)="viewVersions(dmp.groupId, dmp.label)">
{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}}
</button>
<div class="d-flex mr-4">{{'GENERAL.STATUSES.EDIT' | translate}} :
{{dmp.modifiedTime | date:"longDate"}}</div>
{{dmp.modifiedTime | date:"longDate"}}
</div>
<div class="d-flex mr-4">
<div *ngIf="dmp.status" class="d-flex flex-row uppercase">
<mat-icon class="status-icon">check</mat-icon>
{{'DATASET-LISTING.COLUMNS.FINALIZED' | translate}}
</div>
</div>
</div>
<div class="row">
<button *ngIf="isAuthenticated()" (click)="cloneClicked(dmp)" mat-mini-fab
class="mr-3 d-flex justify-content-center align-items-center"
matTooltip="{{'DMP-LISTING.ACTIONS.CLONE' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-icon-1">content_copy</mat-icon>
<mat-icon class="mat-mini-fab-icon">content_copy</mat-icon>
</button>
<button *ngIf="isDraftDmp(dmp) && isUserOwner" (click)="editClicked(dmp)" mat-mini-fab
class="mr-3 d-flex justify-content-center align-items-center"
matTooltip="{{'DMP-LISTING.ACTIONS.EDIT' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-icon-1">create</mat-icon>
<mat-icon class="mat-mini-fab-icon">create</mat-icon>
</button>
<button *ngIf="isDraftDmp(dmp) && isUserOwner" (click)="deleteClicked()" mat-mini-fab
class="mr-3 d-flex justify-content-center align-items-center"
matTooltip="{{'DMP-LISTING.ACTIONS.DELETE' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-icon-1">delete</mat-icon>
<mat-icon class="mat-mini-fab-icon">delete</mat-icon>
</button>
<button *ngIf="isDraftDmp(dmp) && isUserOwner" (click)="finalize(dmp)" mat-mini-fab
<!-- <button *ngIf="isDraftDmp(dmp) && isUserOwner" (click)="finalize(dmp)" mat-mini-fab
class="mr-3 d-flex justify-content-center align-items-center"
matTooltip="{{'DMP-LISTING.ACTIONS.FINALIZE' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-icon-1">lock_outline</mat-icon>
<mat-icon class="mat-mini-fab-icon">lock_outline</mat-icon>
</button> -->
<button *ngIf="isDraftDmp(dmp) && isUserOwner" mat-mini-fab
class="mr-3 d-flex justify-content-center align-items-center">
<div>
<div *ngIf="checkLockStatus(dmp.id)">
<mat-icon (click)="createOrUpdate(dmp.id)" class="mat-mini-fab-icon"
matTooltip="{{'DMP-OVERVIEW.LOCK' | translate}}" matTooltipPosition="above">
lock_outline
</mat-icon>
</div>
</div>
</button>
</div>
<div class="row title">{{'DMP-OVERVIEW.GRANT' | translate}}</div>
<div class="row header">{{'DMP-OVERVIEW.GRANT' | translate}}</div>
<div class="row dmp-label">{{ dmp.grant.label }}</div>
<div class="row title">{{'DMP-OVERVIEW.RESEARCHERS' | translate}}</div>
<div class="row header">{{'DMP-OVERVIEW.RESEARCHERS' | translate}}</div>
<div class="row">
<div *ngFor="let researcher of dmp.researchers" class="d-flex flex-row align-items-center">
<div *ngFor="let researcher of dmp.researchers; let last = last"
class="d-flex flex-row align-items-center">
<div class="id-btn">&nbsp;</div>
<div class="avatar">{{ researcher.name }},</div>
<div class="researcher" *ngIf="!last">{{ researcher.name }}, </div>
<div class="researcher" *ngIf="last">{{ researcher.name }}</div>
</div>
</div>
<div class="row title">{{'DATASET-LISTING.COLUMNS.DESCRIPTION' | translate}}</div>
<div class="row desc-text" *ngIf="dmp.grant.description">
<p>{{ dmp.grant.description }}</p>
<div class="row header">{{'DATASET-LISTING.COLUMNS.DESCRIPTION' | translate}}</div>
<div class="row" *ngIf="dmp.description">
<p class="desc-txt">{{ dmp.description }}</p>
</div>
<div class="row title">{{'DMP-OVERVIEW.DATASETS-USED' | translate}}</div>
<div class="row">
<div class="row header">{{'DMP-OVERVIEW.DATASETS-USED' | translate}}</div>
<div class="row d-flex flex-column">
<div *ngFor="let dataset of dmp.datasets; let i=index">
<div *ngIf="i < 9" (click)="datasetClicked(dataset.id)">
<div *ngIf="i < 3" (click)="datasetClicked(dataset.id)">
<!-- <mat-icon *ngIf="isDraftDataset(dataset)" class="draft-bookmark">bookmark</mat-icon>
<mat-icon *ngIf="!isDraftDataset(dataset)" class="finalized-bookmark">bookmark</mat-icon>
<h4 *ngIf="isDraftDataset(dataset)">
@ -88,25 +119,27 @@
</button>
</div>
</div>
<div *ngIf="dmp.datasets.length > 3" class="show-more-btn">
<button mat-button (click)="datasetsClicked(dmp.id)">
<mat-icon class="mr-2">expand_more</mat-icon>
{{ 'GENERAL.ACTIONS.SHOW-MORE' | translate }}
</button>
</div>
</div>
<div *ngIf="dmp.datasets.length > 9" class="d-flex justify-content-center">
<button mat-button (click)="datasetsClicked(dmp.id)" class="show-more">
<mat-icon class="mr-2">expand_more</mat-icon>{{ 'GENERAL.ACTIONS.SHOW-MORE' | translate }}
</button>
</div>
<div class="row mt-2 d-flex align-items-center">
<button class="add-dataset d-flex align-items-center" *ngIf="isDraftDmp(dmp) && isUserOwner"
<div class="row mt-2 add-dataset-txt">
<button class="add-dataset-btn" *ngIf="isDraftDmp(dmp) && isUserOwner"
(click)="addDataset(dmp.id)">
<mat-icon>add</mat-icon>
{{'DMP-LISTING.ACTIONS.ADD-DATASET-SHORT' | translate}}
</button>
<span class="add-dataset">{{'DMP-LISTING.ACTIONS.ADD-DATASET-SHORT' | translate}}</span>
</div>
</div>
<div class="col-md-4 col-lg-4">
<div class="row d-flex flex-column m-1">
<div class="col-md-4 col-lg-4 p-0">
<div *ngIf="!hasDoi(dmp)" class="row d-flex flex-column ml-0 mr-0 mb-3">
<p class="doi-label">{{'DMP-EDITOR.TITLE.SUBTITLE' | translate}}</p>
<div class="doi-panel">
<p class="doi-text mb-0 ml-2">{{ dmp.modifiedTime }}</p>
<p *ngIf="!hasDoi(dmp)" class="mb-0 ml-3">
<span class="doi-txt">{{ dmp.doi }}</span></p>
<div class="d-flex justify-content-end">
<button *ngIf="isAuthenticated()" (click)="cloneClicked(dmp)" mat-mini-fab
class="mr-2 d-flex justify-content-center align-items-center"
@ -114,39 +147,55 @@
<mat-icon class="mat-mini-fab-icon">content_copy</mat-icon>
</button>
<button mat-mini-fab class="mr-2 d-flex justify-content-center align-items-center"
matTooltip="{{'DMP-LISTING.ACTIONS.EDIT' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-mini-fab-icon">launch</mat-icon>
matTooltip="{{'GRANT-EDITOR.ACTIONS.VISIT-WEBSITE' | translate}}"
matTooltipPosition="above">
<a [href]="createDoiLink(dmp.doi)" class="doi-link" target="_blank">
<mat-icon class="mat-mini-fab-icon">launch</mat-icon>
</a>
</button>
</div>
</div>
</div>
<div class="frame m-1">
<div class="row ml-2 pl-4 pt-4 pb-3 d-flex align-items-center">
<div class="frame mb-3 pt-4 pl-3 pr-5 pb-1">
<div *ngIf="!dmp.status && isDraftDmp(dmp) && isUserOwner">
<div class="row ml-0 mr-0 pl-4 d-flex align-items-center" (click)="finalize(dmp)">
<button mat-mini-fab class="finalize-btn">
<mat-icon class="mat-mini-fab-icon">check</mat-icon>
</button>
<p class="mb-0 pl-2 finalize-txt">{{ 'DMP-LISTING.ACTIONS.FINALIZE' | translate }}</p>
</div>
<div class="row ml-0 mr-0 pl-4 d-flex align-items-center">
<hr class="hr-line">
</div>
</div>
<div *ngIf="hasDoi(dmp) && isFinalizedDmp(dmp) && !this.isPublicView && isUserOwner"
(click)="getDoi(dmp)" class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center">
<button mat-mini-fab class="frame-btn">
<mat-icon class="mat-mini-fab-icon">archive</mat-icon>
</button>
<p class="mb-0 pl-2 actions-text">{{ 'DMP-LISTING.ACTIONS.DEPOSIT' | translate }}</p>
<p class="mb-0 pl-2 frame-txt">{{ 'DMP-LISTING.ACTIONS.DEPOSIT' | translate }}</p>
</div>
<div class="row ml-2 pl-4 pb-3 d-flex align-items-center">
<div class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center">
<button mat-mini-fab class="frame-btn" [matMenuTriggerFor]="exportMenu">
<mat-icon class="mat-mini-fab-icon">open_in_new</mat-icon>
</button>
<p class="mb-0 pl-2 actions-text" [matMenuTriggerFor]="exportMenu">
<p class="mb-0 mr-0 pl-2 frame-txt" [matMenuTriggerFor]="exportMenu">
{{ 'DMP-LISTING.ACTIONS.EXPORT' | translate }}</p>
</div>
<div class="row ml-2 pl-4 pb-3 d-flex align-items-center" *ngIf="isUserOwner"
<div class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center" *ngIf="isUserOwner"
(click)="newVersion(dmp.id, dmp.label)">
<button mat-mini-fab class="frame-btn">
<mat-icon class="mat-mini-fab-icon">add_to_photos</mat-icon>
</button>
<p class="mb-0 pl-2 actions-text">{{ 'DMP-LISTING.ACTIONS.START-NEW-VERSION' | translate }}
<p class="mb-0 pl-2 frame-txt">{{ 'DMP-LISTING.ACTIONS.START-NEW-VERSION' | translate }}
</p>
</div>
<div class="row ml-2 pl-4 pb-3 d-flex align-items-center">
<div *ngIf="!dmp.isPublic && showPublishButton(dmp) && isUserOwner"
class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center" (click)="publish(dmp.id)">
<button mat-mini-fab class="frame-btn">
<mat-icon class="mat-mini-fab-icon">public</mat-icon>
</button>
<p class="mb-0 pl-2 actions-text">{{ 'DMP-LISTING.ACTIONS.MAKE-PUBLIC' | translate }}</p>
<p class="mb-0 pl-2 frame-txt">{{ 'DMP-LISTING.ACTIONS.MAKE-PUBLIC' | translate }}</p>
</div>
<mat-menu #exportMenu="matMenu" xPosition="before">
<button mat-menu-item (click)="downloadPDF(dmp.id)">
@ -167,25 +216,31 @@
</button>
</mat-menu>
</div>
<div class="frame m-1">
<div class="row ml-2 pl-4 pt-4 pb-3">
<p class="title">{{ 'DMP-OVERVIEW.DMP-AUTHORS' | translate }}</p>
<div class="frame mb-3 pt-4 pl-3 pr-3 pb-1">
<div class="row ml-0 mr-0 pl-4 pb-3">
<p class="header">{{ 'DMP-OVERVIEW.DMP-AUTHORS' | translate }}</p>
</div>
<div class="row ml-2 pl-4 pb-3 d-flex align-items-center" *ngIf="!isPublicView">
<button class="account_circle mr-3 pl-0">
<mat-icon class="mat-icon-2">account_circle</mat-icon>
</button>
<div class="row">
<div *ngFor="let user of dmp.users">
<p class="mb-0 pl-2 actions-text">{{ user.name }}</p>
<p class="mb-0 pl-2 actions-text">{{ roleDisplay(user) }}</p>
<div class="row ml-0 mr-0 pl-4 ml-2 pb-3 d-flex align-items-center">
<div *ngFor="let user of dmp.users" class="row authors">
<div class="d-flex flex-row">
<button class="account_btn mr-3 pl-0">
<mat-icon class="account-icon">account_circle</mat-icon>
</button>
<div>
<p class="authors-label">{{ user.name }}
<span *ngIf="!user.role"> ({{ 'DMP-OVERVIEW.YOU' | translate }})</span>
</p>
<p class="authors-role">{{ roleDisplay(user) }}</p>
</div>
</div>
<button *ngIf="isUserOwner && !dmp.status && user.role"
(click)="removeCollaborator(user.id)"
class="remove-btn">{{ 'GENERAL.CONFIRMATION-DIALOG.ACTIONS.REMOVE' | translate}}</button>
</div>
</div>
<div *ngIf="isUserOwner" (click)="openShareDialog(dmp.id,dmp.label)"
class="row ml-2 pl-4 pb-3 d-flex align-items-center">
<button mat-raised-button class="frame-button invite-button">
class="row mt-3 mb-3 d-flex align-items-center justify-content-center">
<button mat-raised-button class="invite-btn">
<mat-icon>group_add</mat-icon>
{{'DMP-LISTING.ACTIONS.INVITE-SHORT' | translate}}
</button>

View File

@ -1,179 +1,270 @@
.container-fluid {
padding: 30px;
margin: 2em 4em;
padding: 2em;
}
.chevron-icon {
height: 12px;
// ********ICONS********
.back-icon {
opacity: 0.4;
}
.label-text {
font-size: 14px;
color: #848484;
}
.dmp-btn {
background: #129D99;
border-radius: 4px;
}
.dmp-btn-text {
width: 30px;
font-size: 14px;
color: #FFFFFF;
opacity: 0.8;
}
.dmp-label {
font-size: 20px;
font-weight: bold;
color: #212121;
display: flex;
align-items: center;
}
.version-btn {
width: 94px;
height: 25px;
border: 1px solid #707070;
border-radius: 4px;
}
.mat-mini-fab {
width: 35px;
height: 35px;
width: 2.5em;
height: 2.5em;
background-color: #129D99;
}
.mat-icon-1 {
font-size: 1.25em;
.mat-mini-fab-icon, .status-icon {
font-size: 1.2em;
}
.mat-icon-2 {
.status-icon {
color: #A7A7A7;
}
.account-icon {
font-size: 2.5em;
}
.mat-icon-1 .mat-icon-2{
display: flex;
justify-content: center;
align-items: center;
// ********BUTTONS********
.version-btn {
// width: 6.7em;
height: 1.8em;
border: 1px solid #707070;
border-radius: 4px;
background-color: transparent;
}
.id-btn {
background: url('../../../../assets/images/NoPath.png') no-repeat center;
width: 16px;
margin-right: 5px;
width: 1em;
margin-right: 0.3em;
align-self: center;
}
.avatar {
font-size: 14px;
.dataset-btn {
width: 36.1em;
padding: 0 1.1em;
background-color: #F7DD72;
border-radius: 4px;
justify-content: space-between;
color: #212121;
opacity: 0.8;
}
.show-more-btn {
width: 31.6em;
padding: 0 1em;
background-color: #ffffff00;
color: #129D99;
font-weight: 700;
}
.add-dataset-btn {
border: none;
font: Bold 0.875em Open Sans;
color: #444444;
background-color: transparent;
}
.frame-btn {
border: 1px solid #212121;
color: black;
}
.finalize-btn {
border: 1px solid #129D99;
color: #129D99;
}
.frame-btn, .finalize-btn {
background: #FFFFFF;
box-shadow: 0px 2px 6px #00000029;
}
.remove-btn {
border: none;
background-color: transparent;
font-size: 0.875em;
font-weight: bold;
margin-left: auto;
}
.invite-btn{
width: 9.4em;
height: 2.9em;
background: #FFFFFF;
box-shadow: 0px 3px 6px #1E202029;
border: 2px solid #212121;
border-radius: 30px;
}
.account_btn {
background: white;
color: #D5D5D5;
border: none;
height: 2.9em;
}
// ********TEXT********
.dmp-logo {
width: 4.8em;
height: 2.6em;
background: #129D99;
border-radius: 4px;
font-size: 0.875em;
color: #FFFFFF;
opacity: 0.8;
}
.label-txt {
font-size: 0.875em;
}
.label2-txt {
font-size: 1em;
}
.label-txt, .label2-txt {
color: #848484;
}
.dmp-label {
font-weight: bold;
}
.uppercase {
text-transform: uppercase;
}
.researcher {
font-size: 0.875em;
color: #008887;
padding-right: 0.5em;
align-self: center;
}
.title {
font-size: 20px;
color: #212121;
.header {
opacity: 0.6;
margin-top: 20px;
margin-bottom: 5px;
margin-top: 1em;
margin-bottom: 0.25em;
}
.desc-text {
font-size: 16px;
.dmp-label, .header {
font-size: 1.25em;
color: #212121;
margin-bottom: 30px;
}
.dataset-btn {
width: 506px;
padding: 0 16px;
background-color: #F7DD72;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: space-between;
.desc-txt {
width: 48.25em;
font-size: 1em;
color: #212121;
opacity: 0.8;
margin-bottom: 1.875em;
}
.dataset-btn-label {
margin-right: 16px;
margin-right: 1em;
overflow: hidden;
}
.add-dataset {
border: none;
font: Bold 14px/19px Open Sans;
color: #444444;
}
.show-more {
background-color: #ffffff00;
color: #00b29f;
font-weight: 700;
justify-self: center;
}
.doi-label {
font-size: 16px;
font-size: 1em;
color: #212121;
opacity: 0.6;
margin-bottom: 5px;
margin-bottom: 0.3em;
}
.doi-text {
font-size: 16px;
letter-spacing: 0.15px;
.doi-txt {
font-size: 0.8em;
letter-spacing: 0.009em;
color: #7D7D7D;
}
.doi-panel {
height: 56px;
height: 3.5em;
background: #FAFAFA;
border: 1px solid #D1D1D1;
border-radius: 4px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.doi-link {
color: white;
}
.frame {
height: 234px;
background: #FFFFFF;
box-shadow: 0px 1px 5px #00000026;
border-radius: 4px;
overflow: hidden;
}
.actions-text {
font: Bold 12px/17px Open Sans;
letter-spacing: 0px;
.frame-txt {
color: #000000;
}
.finalize-txt {
color: #129D99;
}
.frame-txt, .finalize-txt {
font-size: 0.75em;
font-weight: bold;
letter-spacing: 0px;
text-transform: uppercase;
cursor: pointer;
}
.frame-btn {
border: 1px solid #212121;
background: #FFFFFF;
box-shadow: 0px 2px 6px #00000029;
color: black;
.hr-line {
border: 1px solid #DBDBDB;
// width: 274px;
// width: 17em;
width: 100%;
}
.authors {
display: flex;
flex-direction: row;
justify-content: space-between;
width: 100%;
}
.authors-label {
font-size: 0.875em;
color: #212121;
height: 1.4em;
margin-bottom: 0px;
}
.authors-role {
font-size: 0.875em;
color: #A8A8A8;
height: 1.4em;
margin-bottom: 0px;
}
// ********CENTER ELEMENTS********
.mat-mini-fab, .mat-mini-fab-icon,
.status-icon, .dmp-logo, .frame-btn, .finalize-btn {
display: flex;
justify-content: center;
align-items: center;
}
.account_circle {
background: white;
color: #D5D5D5;
border: none;
.dmp-label, .dataset-btn, .add-dataset-btn,
.doi-panel {
display: flex;
align-items: center;
}
.invite-button{
border-radius: 30px;
.show-more-btn {
display: flex;
justify-content: center;
}

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, Input } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { DatasetStatus } from '@app/core/common/enum/dataset-status';
@ -29,6 +29,11 @@ import { Oauth2DialogComponent } from '@app/ui/misc/oauth2-dialog/oauth2-dialog.
import { Oauth2DialogService } from '@app/ui/misc/oauth2-dialog/service/oauth2-dialog.service';
import { isNullOrUndefined } from 'util';
import { UserService } from '@app/core/services/user/user.service';
import { Location } from '@angular/common';
import { FormGroup } from '@angular/forms';
import { LockService } from '@app/core/services/lock/lock.service';
import { ReturnStatement } from '@angular/compiler';
import { LockModel } from '@app/core/model/lock/lock.model';
@Component({
selector: 'app-dmp-overview',
@ -46,6 +51,10 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
isUserOwner: boolean;
expand = false;
hasDOIToken = false;
lock: LockModel;
lockStatus: Boolean;
@Input() formGroup: FormGroup;
constructor(
private route: ActivatedRoute,
@ -58,7 +67,9 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
private uiNotificationService: UiNotificationService,
private configurationService: ConfigurationService,
private oauth2DialogService: Oauth2DialogService,
private userService: UserService
private userService: UserService,
private location: Location,
private lockService: LockService
) {
super();
}
@ -530,15 +541,49 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
reverse() {
this.dmpService.unfinalize(this.dmp.id).pipe(takeUntil(this._destroyed))
.subscribe(
complete => {
this.dmp.status = DmpStatus.Draft;
this.onCallbackSuccess()
},
error => this.onFinalizeCallbackError(error)
);;
.subscribe(
complete => {
this.dmp.status = DmpStatus.Draft;
this.onCallbackSuccess()
},
error => this.onFinalizeCallbackError(error)
);;
}
goBack(): void {
this.location.back();
}
removeCollaborator(id: string) {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
maxWidth: '300px',
data: {
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-USER'),
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.REMOVE'),
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
isDeleteConfirmation: false
}
});
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.formGroup.get('users').setValue(this.formGroup.get('users').value.filter(function (val, index, arr) {
return val.id !== id;
}));
}
});
}
checkLockStatus(id: string): Observable<boolean> {
return this.lockService.checkLockStatus(id);
}
createOrUpdate(id: string): Observable<string> {
// this.lock = new LockModel(id, this.getUserFromDMP());
return this.lockService.createOrUpdate(this.lock);
}
// advancedClicked() {
// const dialogRef = this.dialog.open(ExportMethodDialogComponent, {
// maxWidth: '500px',

View File

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from '@app/core/services/auth/auth.service';
import { LanguageService } from '@app/core/services/language/language.service';
@ -9,53 +9,55 @@ import { BaseComponent } from '@common/base/base.component';
const availableLanguages: any[] = require('../../../../assets/resources/language.json');
@Component({
selector: 'app-language',
templateUrl: './language.component.html',
styleUrls: ['./language.component.scss']
selector: 'app-language',
templateUrl: './language.component.html',
styleUrls: ['./language.component.scss']
})
export class LanguageComponent extends BaseComponent implements OnInit {
@Output() languageChange: EventEmitter<any> = new EventEmitter();
languages = availableLanguages;
constructor(
private router: Router,
private authentication: AuthService,
private languageService: LanguageService,
private userService: UserService
) { super(); }
constructor(
private router: Router,
private authentication: AuthService,
private languageService: LanguageService,
private userService: UserService
) { super(); }
ngOnInit() {
}
public isAuthenticated(): boolean {
return !(!this.authentication.current());
}
public getCurrentLanguage(): any {
const lang = this.languages.find(lang => lang.value === this.languageService.getCurrentLanguage());
return lang;
}
onLanguageSelected(selectedLanguage: any) {
if (this.isAuthenticated()) {
const langMap = new Map<string, string>();
langMap.set('language', selectedLanguage.value);
this.userService.updateUserSettings({language: this.languages.find(lang => lang.value === selectedLanguage.value)})
.pipe(takeUntil(this._destroyed))
.subscribe((response) => {
this.languageService.changeLanguage(selectedLanguage.value);
this.authentication.me()
.pipe(takeUntil(this._destroyed))
.subscribe ( innerResponse =>
{this.router.navigateByUrl(this.router.url);});
},
error => {
console.log(error);
});
} else {
this.languageService.changeLanguage(selectedLanguage.value);
this.router.navigateByUrl(this.router.url);
ngOnInit() {
this.languageChange.emit(this.getCurrentLanguage().value)
}
public isAuthenticated(): boolean {
return !(!this.authentication.current());
}
public getCurrentLanguage(): any {
const lang = this.languages.find(lang => lang.value === this.languageService.getCurrentLanguage());
return lang;
}
onLanguageSelected(selectedLanguage: any) {
if (this.isAuthenticated()) {
const langMap = new Map<string, string>();
langMap.set('language', selectedLanguage.value);
this.userService.updateUserSettings({ language: this.languages.find(lang => lang.value === selectedLanguage.value) })
.pipe(takeUntil(this._destroyed))
.subscribe((response) => {
this.languageService.changeLanguage(selectedLanguage.value);
this.authentication.me()
.pipe(takeUntil(this._destroyed))
.subscribe(innerResponse => { this.router.navigateByUrl(this.router.url); });
},
error => {
console.log(error);
});
} else {
this.languageService.changeLanguage(selectedLanguage.value);
this.router.navigateByUrl(this.router.url);
}
this.languageChange.emit(selectedLanguage.value);
}
}
}

View File

@ -36,3 +36,8 @@ $mat-card-header-size: 30px !default;
.active a i{
color: #23BCBA;
}
mat-list-item {
display: flex !important;
height: auto !important;
}

View File

@ -541,6 +541,12 @@
"RESEARCHERS": "Researchers",
"DATASETS-USED": "Datasets used",
"COLLABORATORS": "Collaborators",
"PUBLIC": "Public",
"PRIVATE": "Private",
"LOCKED": "Locked",
"UNLOCKED": "Unlocked",
"YOU": "you",
"LOCK": "Lock",
"TOOLTIP": {
"LEVEL-OF-ACCESS": "Level of Access",
"INVOLVED-DATASETS": "Involved Dataset Descriptions",
@ -1117,7 +1123,12 @@
"GRANTS": "Grants",
"MY-DMPS": "My DMPs",
"TITLE": "What is ARGOS?",
"DMP-QUESTION": "What is a DMP in ARGOS?",
"INFO-TEXT": "ARGOS is an open extensible service that simplifies the management, validation, monitoring and maintenance and of Data Management Plans. It allows actors (researchers, managers, supervisors etc) to create actionable DMPs that may be freely exchanged among infrastructures for carrying out specific aspects of the Data management process in accordance with the intentions and commitment of Data owners.",
"INFO-DMP-TEXT": "A Data Management Plan (DMP) is a living document describing the datasets that are generated and/ or re-used during and after a research lifetime. DMPs aim to provide researchers with essential information to re-produce,re-distribute and re-purpose research results thus assuring for their validity and exploitation.",
"NEW-QUESTION": "New with DMPs? Visit",
"OPEN-AIR-GUIDE": "OpenAIREs Guide for Researchers",
"LEARN-MORE": "to learn more about how to create one!",
"ORGANIZATIONS": "Related Organizations",
"DMPS": "DMPs",
"MY-DATASETS": "My Dataset Descriptions",

View File

@ -539,6 +539,12 @@
"RESEARCHERS": "Investigadores",
"DATASETS-USED": "Descripciones del Dataset Utilizadas",
"COLLABORATORS": "Colaboradores",
"PUBLIC": "Público",
"PRIVATE": "Privado",
"LOCKED": "Bloqueado",
"UNLOCKED": "Desbloqueado",
"YOU": "tú",
"LOCK": "Bloquear",
"TOOLTIP": {
"LEVEL-OF-ACCESS": "Nivel de acceso",
"INVOLVED-DATASETS": "Descripciones del Dataset implicadas",
@ -1104,7 +1110,12 @@
"GRANTS": "Subvenciones",
"MY-DMPS": "Mis PGDs",
"TITLE": "¿Qué es ARGOS?",
"DMP-QUESTION": "¿Que es un DMP en ARGOS?",
"INFO-TEXT": "ARGOS es un servicio extensible y abierto que simplifica la gestión, validación, monitorización y mantenimiento de los Plan de Gestión de Datos. Permite a los participantes (investigadores, gestores, supervisores, etc) crear un PGDs visible que puede ser compartido libremente entre distintas infraestructuras para llevar a cabo aspectos específicos del proceso de Gestión de Datos de acuerdo con los propósitos y el compromiso de los propietarios de los datos.",
"INFO-DMP-TEXT": "A Data Management Plan (DMP) is a living document describing the datasets that are generated and/ or re-used during and after a research lifetime. DMPs aim to provide researchers with essential information to re-produce,re-distribute and re-purpose research results thus assuring for their validity and exploitation.",
"NEW-QUESTION": "¿Nuevo con DMP? Visitar",
"OPEN-AIR-GUIDE": "Guía de OpenAIRE para investigadores",
"LEARN-MORE": "para aprender más sobre cómo crear uno!",
"ORGANIZATIONS": "Organizaciones relacionadas",
"DMPS": "PGDs",
"MY-DATASETS": "Mis descripciones del Dataset",

View File

@ -540,6 +540,12 @@
"RESEARCHERS": "Ερευνητές",
"DATASETS-USED": "Περιγραφές Συνόλων Δεδομένων Που Χρησιμοποιήθηκαν",
"COLLABORATORS": "Συνεργάτες",
"PUBLIC": "Δημόσιο",
"PRIVATE": "Ιδιωτικό",
"LOCKED": "Κλειδωμένο",
"UNLOCKED": "Ακλείδωτο",
"YOU": "εσύ",
"LOCK": "Κλείδωσε",
"TOOLTIP": {
"LEVEL-OF-ACCESS": "Επίπεδο Πρόσβασης",
"INVOLVED-DATASETS": "Εμπλεκόμενες Περιγραφές Συνόλου Δεδομένων",
@ -1091,8 +1097,13 @@
"MY-GRANTS": "Οι Επιχορηγήσεις μου",
"GRANTS": "Επιχορηγήσεις",
"MY-DMPS": "Τα Σχέδια Διαχείρισης Δεδομένων μου",
"TITLE": "Τi είναι το ARGOS?",
"TITLE": "Τι είναι το ARGOS?",
"DMP-QUESTION": "Τι είναι το DMP στο ARGOS?",
"NEW-QUESTION": "Νέος με τα DMP; Επίσκεψου",
"OPEN-AIR-GUIDE": "Οδηγός για ερευνητές του OpenAIRE",
"LEARN-MORE": "για να μάθετε περισσότερα για το πώς να δημιουργήσετε ένα!",
"INFO-TEXT": "Το ARGOS είναι μια ανοικτή επεκτάσιμη υπηρεσία που απλοποιεί τη διαχείριση, την επικύρωση, την παρακολούθηση και τη συντήρηση των Σχεδίων Διαχείρισης Δεδομένων. Επιτρέπει στους φορείς (ερευνητές, υπεύθυνους έρευνας, διευθυντές κλπ.) να δημιουργούν ζωντανά Σχέδια Διαχείρισης Δεδομένων που μπορούν να ανταλλάσσονται ελεύθερα μεταξύ των υποδομών για τη διεξαγωγή συγκεκριμένων πτυχών της διαδικασίας διαχείρισης Δεδομένων, σύμφωνα με τις προθέσεις και τη δέσμευση των κατόχων Δεδομένων.",
"INFO-DMP-TEXT": "A Data Management Plan (DMP) is a living document describing the datasets that are generated and/ or re-used during and after a research lifetime. DMPs aim to provide researchers with essential information to re-produce,re-distribute and re-purpose research results thus assuring for their validity and exploitation.",
"ORGANIZATIONS": "Σχετικοί Οργανισμοί",
"DMPS": "Σχέδια Διαχείρισης Δεδομένων",
"MY-DATASETS": "Οι Περιγραφές Συνόλων Δεδομένων μου",