Dmp Listing (1st Commit)

This commit is contained in:
apapachristou 2020-07-03 17:17:23 +03:00
parent e315bee7f7
commit 6d9dcc4ec9
8 changed files with 685 additions and 148 deletions

View File

@ -38,7 +38,7 @@
</div>
<mat-menu #exportMenu="matMenu" xPosition="before">
<button mat-menu-item (click)="downloadPDF(activity.id)">
<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>

View File

@ -239,7 +239,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn
});
}
downloadPDF(id: string) {
downloadPdf(id: string) {
this.dmpService.downloadPDF(id)
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
@ -260,6 +260,40 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn
})
}
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);
@ -341,29 +375,6 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn
});
}
downloadDOCX(dataset: RecentDatasetModel): 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: RecentDatasetModel): 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);
});
}
public loadMore() {
const fields: Array<string> = ["-modified"];
const request = new DataTableRequest<RecentActivityCriteria>(this.startIndex, this.pageSize, { fields: fields });

View File

@ -1,4 +1,33 @@
<div class="header-image" *ngIf="isPublic">
<div class="main-content listing-main-container h-100">
<div class="container-fluid">
<div class="card mt-0" [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>
<div class="card-content info-text mb-0 pt-0">
<p>{{'DMP-LISTING.TEXT-INFO' | translate}}</p>
<p class="mt-4 pt-2">{{'DMP-LISTING.TEXT-INFO-QUESTION' | translate}} <u>{{'DMP-LISTING.LINK-ZENODO' | translate}}</u> {{'DMP-LISTING.GET-IDEA' | translate}}</p>
</div>
</div>
<div>
<div class="listing row pb-2">
<div class="col-12 col-sm-12 col-md-3">
<app-dmp-criteria-component [showGrant]="showGrant" [isPublic]="isPublic" class="col-auto"></app-dmp-criteria-component>
</div>
<div class="col-12 col-sm-12 col-md-9 pt-4">
<div *ngFor="let item of listingItems; let i = index">
<app-dmp-listing-item-component [showDivider]="i != (listingItems.length - 1)" [dmp]="item" [isPublic]="isPublic"></app-dmp-listing-item-component>
</div>
<div *ngIf="listingItems && listingItems.length > 0" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Version 1 -->
<!-- <div class="header-image" *ngIf="isPublic">
<div class="header-text-container">
<h3>{{ 'ABOUT.WELCOME' | translate }}</h3>
<h4>{{ 'ABOUT.WELCOME-MESSAGE' | translate }}</h4>
@ -18,10 +47,8 @@
{{this.groupLabel}}
</span>
</div>
<!-- <p class="card-category">{{'DMP-LISTING.SUBTITLE' | translate}}</p> -->
</div>
<div class="row ml-auto p-2" *ngIf="!isPublic">
<!-- Import Button -->
<button mat-icon-button [matMenuTriggerFor]="actionsMenu" class="ml-auto more-icon" (click)="$event.stopImmediatePropagation();">
<mat-icon class="more-horiz">more_horiz</mat-icon>
</button>
@ -30,7 +57,6 @@
<mat-icon>cloud_upload</mat-icon> {{'DMP-UPLOAD.ACTIONS.IMPORT' | translate}}
</button>
</mat-menu>
<!-- <button mat-raised-button color="primary" class="text-uppercase lightblue-btn m-1" [routerLink]="grantId ? ['/plans/new/grant/', grantId] : ['./new']"> -->
<button mat-raised-button color="primary" class="text-uppercase lightblue-btn m-1" [routerLink]="['./new']">
<mat-icon>add</mat-icon> {{'DMP-LISTING.ACTIONS.NEW' | translate}}
</button>
@ -45,7 +71,6 @@
<app-dmp-criteria-component [showGrant]="showGrant" [isPublic]="isPublic" class="col-auto"></app-dmp-criteria-component>
</div>
<div class="col-12 col-sm-12 col-md-9 pt-4">
<!-- <mat-paginator #paginator [length]="totalCount" [pageSizeOptions]="[10, 25, 100]" (page)="pageThisEvent($event)" class="top-paginator"></mat-paginator> -->
<div *ngFor="let item of listingItems; let i = index">
<app-dmp-listing-item-component [showDivider]="i != (listingItems.length - 1)" [dmp]="item" [isPublic]="isPublic"></app-dmp-listing-item-component>
</div>
@ -59,81 +84,84 @@
</div>
</div>
</div>
</div>
</div> -->
<!-- Version 0 -->
<!-- <mat-table [dataSource]="dataSource" matSort (matSortChange)="refresh()">
<ng-container cdkColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header="label">{{'DMP-LISTING.COLUMNS.NAME' | translate}}
</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.label}}</mat-cell>
</ng-container>
<ng-container cdkColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header="label">{{'DMP-LISTING.COLUMNS.NAME' | translate}}
</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.label}}</mat-cell>
</ng-container>
<ng-container cdkColumnDef="grant">
<mat-header-cell *matHeaderCellDef mat-sort-header="|join|grant:label">{{'DMP-LISTING.COLUMNS.GRANT' |
translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.grant}} </mat-cell>
</ng-container>
<ng-container cdkColumnDef="grant">
<mat-header-cell *matHeaderCellDef mat-sort-header="|join|grant:label">{{'DMP-LISTING.COLUMNS.GRANT' |
translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.grant}} </mat-cell>
</ng-container>
<ng-container cdkColumnDef="status">
<mat-header-cell *matHeaderCellDef>{{'DMP-LISTING.COLUMNS.STATUS' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{enumUtils.toDmpStatusString(row.status)}} </mat-cell>
</ng-container>
<ng-container cdkColumnDef="status">
<mat-header-cell *matHeaderCellDef>{{'DMP-LISTING.COLUMNS.STATUS' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{enumUtils.toDmpStatusString(row.status)}} </mat-cell>
</ng-container>
<ng-container cdkColumnDef="creationTime">
<mat-header-cell *matHeaderCellDef mat-sort-header="created">
{{'DMP-LISTING.COLUMNS.CREATION-TIME' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.creationTime | date:'shortDate'}} </mat-cell>
</ng-container>
<ng-container cdkColumnDef="creationTime">
<mat-header-cell *matHeaderCellDef mat-sort-header="created">
{{'DMP-LISTING.COLUMNS.CREATION-TIME' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.creationTime | date:'shortDate'}} </mat-cell>
</ng-container>
<ng-container cdkColumnDef="organisations">
<mat-header-cell *matHeaderCellDef>{{'DMP-LISTING.COLUMNS.ORGANISATIONS' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.organisations}} </mat-cell>
</ng-container>
<ng-container cdkColumnDef="organisations">
<mat-header-cell *matHeaderCellDef>{{'DMP-LISTING.COLUMNS.ORGANISATIONS' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.organisations}} </mat-cell>
</ng-container>
<ng-container cdkColumnDef="version">
<mat-header-cell *matHeaderCellDef mat-sort-header="version">
{{'DMP-LISTING.COLUMNS.LATEST_VERSION' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row">
{{row.version}}
</mat-cell>
</ng-container>
<ng-container cdkColumnDef="version">
<mat-header-cell *matHeaderCellDef mat-sort-header="version">
{{'DMP-LISTING.COLUMNS.LATEST_VERSION' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row">
{{row.version}}
</mat-cell>
</ng-container>
<ng-container cdkColumnDef="datasets">
<mat-header-cell *matHeaderCellDef mat-sort-header="|count|dataset">
{{'DMP-LISTING.COLUMNS.DATASETS' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row" (click)="$event.stopPropagation()">
<app-url-listing [items]="row.datasets" [urlLimit]="5" [parameters]="{ datasetLabel: row.label }">
</app-url-listing>
</mat-cell>
</ng-container>
<ng-container cdkColumnDef="datasets">
<mat-header-cell *matHeaderCellDef mat-sort-header="|count|dataset">
{{'DMP-LISTING.COLUMNS.DATASETS' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row" (click)="$event.stopPropagation()">
<app-url-listing [items]="row.datasets" [urlLimit]="5" [parameters]="{ datasetLabel: row.label }">
</app-url-listing>
</mat-cell>
</ng-container>
<ng-container cdkColumnDef="actions">
<mat-header-cell *matHeaderCellDef>{{'DMP-LISTING.COLUMNS.ACTIONS' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row" (click)="$event.stopPropagation()">
<mat-menu #actionsMenu="matMenu">
<button mat-menu-item (click)="openShareDialog(row.id,row.label)">
<mat-icon>share</mat-icon>{{'DMP-LISTING.ACTIONS.INVITE' | translate}}
</button>
<button mat-menu-item (click)="addDataset(row.id)">
<mat-icon>add</mat-icon>{{'DMP-LISTING.ACTIONS.ADD-DATASET' | translate}}
</button>
<button mat-menu-item (click)="showDatasets(row.id, row.label)">
<mat-icon>list</mat-icon>{{'DMP-LISTING.ACTIONS.DATASETS' | translate}}
</button>
<button mat-menu-item (click)="viewVersions(row.groupId, row.label)">
<mat-icon>library_books</mat-icon>{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}}
</button>
</mat-menu>
<button mat-icon-button [matMenuTriggerFor]="actionsMenu">
<mat-icon>more_vert</mat-icon>
</button>
</mat-cell>
</ng-container>
<ng-container cdkColumnDef="actions">
<mat-header-cell *matHeaderCellDef>{{'DMP-LISTING.COLUMNS.ACTIONS' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row" (click)="$event.stopPropagation()">
<mat-menu #actionsMenu="matMenu">
<button mat-menu-item (click)="openShareDialog(row.id,row.label)">
<mat-icon>share</mat-icon>{{'DMP-LISTING.ACTIONS.INVITE' | translate}}
</button>
<button mat-menu-item (click)="addDataset(row.id)">
<mat-icon>add</mat-icon>{{'DMP-LISTING.ACTIONS.ADD-DATASET' | translate}}
</button>
<button mat-menu-item (click)="showDatasets(row.id, row.label)">
<mat-icon>list</mat-icon>{{'DMP-LISTING.ACTIONS.DATASETS' | translate}}
</button>
<button mat-menu-item (click)="viewVersions(row.groupId, row.label)">
<mat-icon>library_books</mat-icon>{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}}
</button>
</mat-menu>
<button mat-icon-button [matMenuTriggerFor]="actionsMenu">
<mat-icon>more_vert</mat-icon>
</button>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns" (click)="rowClick(row.id);"></mat-row>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns" (click)="rowClick(row.id);"></mat-row>
</mat-table>
<mat-paginator #paginator [length]="dataSource?.totalCount" [pageSizeOptions]="[10, 25, 100]">
</mat-paginator> -->
</mat-table>
<mat-paginator #paginator [length]="dataSource?.totalCount" [pageSizeOptions]="[10, 25, 100]">
</mat-paginator> -->

View File

@ -52,48 +52,138 @@
}
.all-versions {
color: #999999 !important;
color: #999999 !important;
}
.dmp-label {
color: #089dbb !important;
color: #089dbb !important;
}
.import {
margin: 10px;
padding: 0px;
}
margin: 10px;
padding: 0px;
}
.more-horiz {
font-size: 28px;
color: #aaaaaa;
}
.more-horiz {
font-size: 28px;
color: #aaaaaa;
}
.more-icon :hover {
color: #00b29f;
}
.more-icon :hover {
color: #00b29f;
}
.header-image {
background: url("/assets/images/new-dashboard-bg.png") no-repeat;
background-size: cover;
margin-top: 70px;
min-height: 15em;
position: relative;
}
.header-image {
background: url("/assets/images/new-dashboard-bg.png") no-repeat;
background-size: cover;
margin-top: 70px;
min-height: 15em;
position: relative;
}
.header-text-container {
background: rgba(255, 255, 255, 0.7);
position: absolute;
bottom: 0px;
padding-left: 5em;
padding-right: 10em;
padding-top: 2em;
padding-bottom: 2em;
}
.explore-dmp-content {
padding: 30px 15px;
}
.header-text-container {
background: rgba(255, 255, 255, 0.7);
position: absolute;
bottom: 0px;
padding-left: 5em;
padding-right: 10em;
padding-top: 2em;
padding-bottom: 2em;
}
.explore-dmp-content {
padding: 30px 15px;
}
.main-content {
background-color: #f5f5f5;
padding-top: 9.68rem;
padding-bottom: 3rem;
padding-left: 3rem;
padding-right: 3rem;
margin: 0;
display: flex;
flex-grow: 1;
}
.card {
background: #ffffff 0% 0% no-repeat padding-box;
box-shadow: 0px 3px 6px #00000029;
border-radius: 4px;
// width: 987px;
margin-bottom: 3.75rem;
/* height: 407px; */
opacity: 1;
}
.card-title {
text-align: left;
font: Bold 20px/30px Roboto;
letter-spacing: 0px;
color: #212121;
padding-left: 40px;
/* padding-top: 40px; */
padding-right: 55px;
opacity: 1;
}
.card-content {
text-align: left;
font: Light 16px/26px Roboto;
letter-spacing: 0px;
color: #212121;
padding-left: 40px;
padding-top: 36px;
padding-bottom: 36px;
padding-right: 55px;
opacity: 1;
}
.clear-icon {
cursor: pointer;
}
.normal-btn {
min-width: 162px;
max-width: 256px;
height: 40px;
cursor: pointer;
background: #129d99 0% 0% no-repeat padding-box;
box-shadow: 0px 3px 6px #1e202029;
border-radius: 30px;
border: none;
color: #ffffff;
opacity: 1;
line-height: 1;
font-size: 0.87rem;
padding: 0.62rem 1.87rem;
margin-left: 40px;
}
.yellow-btn {
min-width: 162px;
max-width: 256px;
height: 40px;
cursor: pointer;
background: #f7dd72 0% 0% no-repeat padding-box;
border-radius: 30px;
opacity: 1;
border: none;
color: #000000;
opacity: 1;
line-height: 1;
font-size: 0.87rem;
padding: 0.62rem 1.87rem;
margin-left: 40px;
}
.info-text {
text-align: left;
font-weight: 300;
font-size: 1rem;
letter-spacing: 0px;
color: #212121;
}
// .bot-paginator {
// margin-top: auto;

View File

@ -46,6 +46,10 @@ export class DmpListingComponent extends BaseComponent implements OnInit, IBread
allVersions: boolean = false;
groupLabel: string;
isPublic: boolean = false;
public isVisible = true
startIndex: number = 0;
pageSize: number = 5;
constructor(
private dmpService: DmpService,
@ -144,13 +148,15 @@ export class DmpListingComponent extends BaseComponent implements OnInit, IBread
}
refresh(resetPages = false) {
if (this._paginator.pageSize === undefined) this._paginator.pageSize = 10;
if (resetPages) this._paginator.pageIndex = 0;
const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
// if (this._paginator.pageSize === undefined) this._paginator.pageSize = 10;
// if (resetPages) this._paginator.pageIndex = 0;
// const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
let fields: Array<string> = new Array();
// if (this.sort && this.sort.active) { fields = this.sort.direction === 'asc' ? ['+' + this.sort.active] : ['-' + this.sort.active]; }
fields.push('-modified');
const request = new DataTableRequest<DmpCriteria>(startIndex, this._paginator.pageSize, { fields: fields });
const request = new DataTableRequest<DmpCriteria>(this.startIndex, this.pageSize, { fields: fields });
let value = this.criteria.formGroup.value;
request.criteria = {
like: value.like,
@ -180,7 +186,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit, IBread
request.criteria.grantStatus = value.grantStatus;
this.dmpService.getPaged(request, "listing").pipe(takeUntil(this._destroyed)).subscribe(result => {
if (!result) { return []; }
if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; }
// if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; }
result.data.map(item => {
item['datasets'].map(dmp => {
dmp.url = 'datasets/edit/' + dmp.url;
@ -193,6 +199,56 @@ export class DmpListingComponent extends BaseComponent implements OnInit, IBread
});
}
public loadMore() {
this.startIndex = this.startIndex + this.pageSize;
const fields: Array<string> = ["-modified"];
const request = new DataTableRequest<DmpCriteria>(this.startIndex, this.pageSize, { fields: fields });
// request.criteria = new DmpCriteria();
// request.criteria.like = "";
let value = this.criteria.formGroup.value;
request.criteria = {
like: value.like,
grants: value.grants,
role: value.role
}
if (value.status == 2) {
request.criteria.isPublic = true;
} else {
request.criteria.status = value.status;
request.criteria.isPublic = false;
}
request.criteria.onlyPublic = this.isPublic;
if (this.isPublic) {
request.criteria.isPublic = true;
}
if (value.datasetTemplates)
request.criteria.datasetTemplates = value.datasetTemplates.map(x => x.id);
if (value.collaborators)
request.criteria.collaborators = value.collaborators.map(x => x.id);
if (value.organisations)
request.criteria.organisations = value.organisations.map(x => x.id);
if (this.itemId) {
request.criteria.groupIds = [this.itemId];
request.criteria.allVersions = true;
}
request.criteria.grantStatus = value.grantStatus;
this.dmpService.getPaged(request, "listing").pipe(takeUntil(this._destroyed)).subscribe(result => {
if (!result) { return []; }
result.data.map(item => {
item['datasets'].map(dmp => {
dmp.url = 'datasets/edit/' + dmp.url;
dmp.all = 'datasets/dmp/' + item.id;
return dmp;
});
return item;
});
this.listingItems = this.listingItems.concat(result.data);
});
}
pageThisEvent(event) {
this.refresh();
}
@ -201,6 +257,10 @@ export class DmpListingComponent extends BaseComponent implements OnInit, IBread
// this.router.navigate(['/plans/overview/' + dmp.id]);
// }
public closeCard(): void {
this.isVisible = false;
}
addDataset(rowId: String) {
this.router.navigate(['/datasets/new/' + rowId]);
}
@ -242,7 +302,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit, IBread
this.dmpService.uploadXml(result.fileList, result.dmpTitle, result.dmpProfiles)
.pipe(takeUntil(this._destroyed))
.subscribe((complete) => this.onCallbackImportComplete(),
(error) => this.onCallbackImportFail(error.error));
(error) => this.onCallbackImportFail(error.error));
}
});
}

View File

@ -1,4 +1,71 @@
<div class="listing-item">
<div class="dmp-card">
<a [routerLink]="isPublic ? ['/explore-plans/publicOverview/' + dmp.id] : ['/plans/overview/' + dmp.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 }}: {{ dmp.modifiedTime | date: "longDate" }}</div>
</div>
<div class="col-auto" [ngClass]="{'dmp-title': !isDraft, 'dmp-title-draft': isDraft}">{{dmp.label}}</div>
<div class="dmp-subtitle">
<span class="col-auto">{{ roleDisplay(dmp.users) }}</span>
<span>.</span>
<span class="col-auto" *ngIf="dmp.status === 1 && dmp.public === true"><span class="material-icons icon-align">public</span>{{'TYPES.DMP-VISIBILITY.PUBLIC' | translate}}</span>
<span *ngIf="dmp.status === 1 && dmp.public === false" class="col-auto"><span class="material-icons icon-align">done</span>{{ enumUtils.toDmpStatusString(dmp.status) }}</span>
<span *ngIf="dmp.status === 0" class=" col-auto draft"><span class="material-icons icon-align">create</span>{{ enumUtils.toDmpStatusString(dmp.status) }}</span>
<span>.</span>
<span class="col-auto">{{'DMP-LISTING.VERSION' | translate}} {{dmp.version}}</span>
<span>.</span>
<span class="col">{{ 'DMP-LISTING.GRANT' | translate }}: {{dmp.grant}}</span>
</div>
<div class="col-auto dmp-dataset-descriptions-title">{{'DMP-LISTING.CONTAINED-DATASETS' | translate}}: ({{ dmp.datasets.length }})
</div>
<div *ngFor="let dataset of dmp.datasets; let i = index; let last = last" [ngClass]="{'pb-3': i === dmp.datasets.length - 1}">
<div *ngIf="i < 3">
<div class="col-auto dmp-dataset-descriptions-name" *ngIf="!last && i !== 2">{{dataset.label}},</div>
<div class="col-auto dmp-dataset-descriptions-name" *ngIf="last || i == 2">{{dataset.label}}</div>
</div>
</div>
<a class="d-flex justify-content-center pb-3 show-more" *ngIf="dmp.datasets.length > 3" [routerLink]="['../plans/overview/' + dmp.id]"><u>{{'GENERAL.ACTIONS.SHOW-MORE' | translate}}</u></a>
</a>
<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(dmp.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(dmp.id, dmp.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(dmp)"><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(dmp.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(dmp.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(dmp.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(dmp.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(dmp)" mat-menu-item (click)="newVersion(dmp.id, dmp.label)">
<mat-icon>queue</mat-icon>{{'DMP-LISTING.ACTIONS.NEW-VERSION' | translate}}
</button>
<button mat-menu-item (click)="viewVersions(dmp.groupId, dmp.label)">
<mat-icon>library_books</mat-icon>{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}}
</button>
<button mat-menu-item *ngIf="isDraftDmp(dmp) && isUserOwner(dmp)" (click)="deleteClicked()" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'DMP-LISTING.ACTIONS.DELETE' | translate }}
</button>
</mat-menu>
</div>
<!-- <div class="listing-item">
<a [routerLink]="isPublic ? ['/explore-plans/publicOverview/' + dmp.id] : ['/plans/overview/' + dmp.id]">
<div class="col">
<div class="row">
@ -35,18 +102,15 @@
lock
</mat-icon>
<div *ngIf="isPublished" class="outer-circle"><div class="inner-circle" matTooltip="{{'DMP-LISTING.TOOLTIP.DMP-STATUS.PUBLISHED' | translate}}"></div></div>
<!-- <mat-icon *ngIf="isPublished" matTooltip="{{'DMP-LISTING.TOOLTIP.DMP-STATUS.PUBLISHED' | translate}}" class="published-icon">radio_button_checked</mat-icon> -->
</div>
<div class="col">
<div class="row d-flex flex-wrap">
<!-- <div class="col-12 d-flex flex-wrap"> -->
<div class="col pl-0">
<h4 class="title pl-0" *ngIf="isDraft">
<span>{{ 'TYPES.DMP.DRAFT' | translate }}:</span> {{dmp.label}}
</h4>
<h4 class="title pl-0" *ngIf="!isDraft">{{dmp.label}}</h4>
</div>
<!-- </div> -->
</div>
<div class="row">
<div class="col-auto pl-0">
@ -85,13 +149,7 @@
</div>
</div>
</div>
<!-- <div class="row d-flex align-items-center my-1">
<mat-icon class="col-auto gray-icon">group</mat-icon>
<div class="row" *ngFor="let user of dmp.users">
<div class="col-auto squared-chip mr-2">{{user.name}}</div>
</div>
</div> -->
</div>
</a>
</div>
</div> -->
<!-- <mat-divider *ngIf="showDivider"></mat-divider> -->

View File

@ -111,6 +111,172 @@ p {
min-width: 74px;
}
.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;
}
::ng-deep .mat-menu-panel {
max-width: 282px !important;
}

View File

@ -8,13 +8,21 @@ import { AuthService } from '../../../../core/services/auth/auth.service';
import { Principal } from '../../../../core/model/auth/principal';
import { TranslateService } from '@ngx-translate/core';
import { DmpStatus } from '../../../../core/common/enum/dmp-status';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { takeUntil } from 'rxjs/operators';
import { BaseComponent } from '@common/base/base.component';
import * as FileSaver from 'file-saver';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import { UiNotificationService, SnackBarNotificationLevel } from '@app/core/services/notification/ui-notification-service';
import { Role } from '@app/core/common/enum/role';
@Component({
selector: 'app-dmp-listing-item-component',
templateUrl: './dmp-listing-item.component.html',
styleUrls: ['./dmp-listing-item.component.scss'],
})
export class DmpListingItemComponent implements OnInit {
export class DmpListingItemComponent extends BaseComponent implements OnInit {
@Input() dmp: DmpListingModel;
@Input() showDivider: boolean = true;
@ -29,7 +37,13 @@ export class DmpListingItemComponent implements OnInit {
private router: Router,
private dialog: MatDialog,
private authentication: AuthService,
private translate: TranslateService) { }
public enumUtils: EnumUtils,
private dmpService: DmpService,
private language: TranslateService,
private translate: TranslateService,
private uiNotificationService: UiNotificationService) {
super();
}
ngOnInit() {
if (this.dmp.status == DmpStatus.Draft) {
@ -105,4 +119,114 @@ export class DmpListingItemComponent implements OnInit {
return this.translate.instant('DMP-LISTING.OWNER');
}
}
cloneClicked(dmp: DmpListingModel) {
this.router.navigate(['/plans/clone/' + dmp.id]);
}
newVersion(id: String, label: String) {
this.router.navigate(['/plans/new_version/' + id, { dmpLabel: label }]);
}
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;
}
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)
);
}
});
}
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);
}
isUserOwner(activity: DmpListingModel): boolean {
const principal: Principal = this.authentication.current();
if (principal) return principal.id === activity.users.find(x => x.role === Role.Owner).id;
}
}