frontend dashboard changes

This commit is contained in:
Diamantis Tziotzios 2023-12-05 22:36:00 +02:00
parent 9685b323e1
commit 9e13eb4d01
55 changed files with 868 additions and 4797 deletions

View File

@ -20,11 +20,10 @@ const appRoutes: Routes = [
pathMatch: 'full'
},
{
path: 'datasetcreatewizard',
loadChildren: () => import('./ui/dataset-create-wizard/dataset-create-wizard.module').then(m => m.DatasetCreateWizardModule),
path: 'home',
loadChildren: () => import('./ui/dashboard/dashboard.module').then(m => m.DashboardModule),
data: {
breadcrumb: true,
title: 'GENERAL.TITLES.DATASETCREATEWIZARD'
breadcrumb: true
}
},
{
@ -43,23 +42,6 @@ const appRoutes: Routes = [
title: 'GENERAL.TITLES.EXPLORE'
}
},
{
path: 'about',
loadChildren: () => import('./ui/about/about.module').then(m => m.AboutModule),
data: {
breadcrumb: true,
title: 'GENERAL.TITLES.ABOUT'
}
},
// ----------- UNCOMMENT TO ADD AGAIN GRANTS --------
// {
// path: 'grants',
// loadChildren: () => import('./ui/grant/grant.module').then(m => m.GrantModule),
// data: {
// breadcrumb: true,
// title: 'GENERAL.TITLES.GRANTS'
// }
// },
{
path: 'plans',
loadChildren: () => import('./ui/dmp/dmp.module').then(m => m.DmpModule),
@ -88,6 +70,36 @@ const appRoutes: Routes = [
})
}
},
{
path: 'datasetcreatewizard',
loadChildren: () => import('./ui/dataset-create-wizard/dataset-create-wizard.module').then(m => m.DatasetCreateWizardModule),
data: {
breadcrumb: true,
title: 'GENERAL.TITLES.DATASETCREATEWIZARD'
}
},
{
path: 'about',
loadChildren: () => import('./ui/about/about.module').then(m => m.AboutModule),
data: {
breadcrumb: true,
title: 'GENERAL.TITLES.ABOUT'
}
},
// ----------- UNCOMMENT TO ADD AGAIN GRANTS --------
// {
// path: 'grants',
// loadChildren: () => import('./ui/grant/grant.module').then(m => m.GrantModule),
// data: {
// breadcrumb: true,
// title: 'GENERAL.TITLES.GRANTS'
// }
// },
{
path: 'quick-wizard',
loadChildren: () => import('./ui/quick-wizard/quick-wizard.module').then(m => m.OuickWizardModule),
@ -192,13 +204,7 @@ const appRoutes: Routes = [
title: 'GENERAL.TITLES.COOKIES-POLICY'
}
},
{
path: 'home',
loadChildren: () => import('./ui/dashboard/dashboard.module').then(m => m.DashboardModule),
data: {
breadcrumb: true
}
},
// {
// path: 'splash',
// loadChildren: () => import('./ui/splash/splash.module').then(m => m.SplashModule),

View File

@ -0,0 +1,4 @@
export enum RecentActivityItemType {
Dmp = 0,
Description = 1
}

View File

@ -1,4 +1,9 @@
export enum RecentActivityOrder {
UpdatedAt = 0,
Label = 1,
Status = 2,
//TODO: delete them since these are from the prerefactor model
LABEL = "label",
CREATED = "created",
MODIFIED = "modified",

View File

@ -1,5 +0,0 @@
export enum RecentActivityType {
Grant = 0,
Dataset = 1,
Dmp = 2
}

View File

@ -1,6 +0,0 @@
export interface DashboardStatisticsModel {
totalDataManagementPlanCount: number;
totalGrantCount: number;
totalDataSetCount: number;
totalOrganisationCount: number;
}

View File

@ -0,0 +1,6 @@
export interface DashboardStatistics {
dmpCount: number;
descriptionCount: number;
organizationCount: number;
grantCount: number;
}

View File

@ -0,0 +1,9 @@
import { RecentActivityItemType } from "@app/core/common/enum/recent-activity-item-type";
import { Description } from "../description/description";
import { Dmp } from "../dmp/dmp";
export interface RecentActivityItem {
type: RecentActivityItemType;
dmp: Dmp;
description: Description;
}

View File

@ -1,23 +0,0 @@
import { RecentActivityType } from '@app/core/common/enum/recent-activity-type';
import { UserInfoListingModel } from '../user/user-info-listing';
import { DatasetProfileModel } from '../dataset/dataset-profile';
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: DatasetProfileModel;
type: RecentActivityType;
users: UserInfoListingModel[];
public: boolean;
}

View File

@ -1,9 +0,0 @@
import { RecentActivityModel } from "./recent-activity.model";
export class RecentDatasetModel extends RecentActivityModel {
dmp: String;
dmpId: String;
dataRepositories: String;
registries: String;
services: String;
}

View File

@ -1,10 +0,0 @@
import { DatasetUrlListing } from '../dataset/dataset-url-listing';
import { RecentActivityModel } from './recent-activity.model';
export class RecentDmpModel extends RecentActivityModel {
doi: String;
extraProperties: Map<String, any>;
datasets: DatasetUrlListing[];
organisations: String;
groupId: string;
}

View File

@ -0,0 +1,25 @@
import { Lookup } from "@common/model/lookup";
import { RecentActivityOrder } from "../common/enum/recent-activity-order";
import { ReferenceType } from "../common/enum/reference-type";
export class RecentActivityItemLookup implements RecentActivityItemFilter {
like: string;
onlyDraft: boolean;
userIds: string;
page: Lookup.Paging;
project: Lookup.FieldDirectives;
orderField: RecentActivityOrder;
constructor() {
}
}
export interface RecentActivityItemFilter {
like: string;
onlyDraft: boolean;
userIds: string;
page: Lookup.Paging;
project: Lookup.FieldDirectives;
orderField: RecentActivityOrder;
}

View File

@ -1,7 +0,0 @@
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { BaseCriteria } from '../base-criteria';
export class RecentActivityCriteria extends BaseCriteria{
public status?: Number;
public order: RecentActivityOrder = RecentActivityOrder.MODIFIED;
}

View File

@ -1,38 +1,38 @@
import { HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from '../../../../environments/environment';
import { DashboardStatisticsModel } from '../../model/dashboard/dashboard-statistics-model';
import { BaseHttpService } from '../http/base-http.service';
import { DashboardStatistics } from '@app/core/model/dashboard/dashboard-statistics';
import { RecentActivityItem } from '@app/core/model/dashboard/recent-activity-item';
import { RecentActivityItemLookup } from '@app/core/query/recent-activity-item-lookup.lookup';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
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';
import { DataTableRequest, DataTableMultiTypeRequest } from '@app/core/model/data-table/data-table-request';
import { BaseHttpV2Service } from '../http/base-http-v2.service';
@Injectable()
export class DashboardService {
private headers: HttpHeaders;
private headers = new HttpHeaders();
constructor(
private http: BaseHttpV2Service,
private configurationService: ConfigurationService,
) {
}
private get apiBase(): string { return `${this.configurationService.server}dashboard`; }
constructor(private http: BaseHttpService,
private configurationService: ConfigurationService) {
getMyRecentActivityItems(q: RecentActivityItemLookup): Observable<RecentActivityItem[]> {
const url = `${this.apiBase}/mine/recent-activity`;
return this.http.post<RecentActivityItem[]>(url, q).pipe(catchError((error: any) => throwError(error)));
}
getStatistics(): Observable<DashboardStatisticsModel> {
return this.http.get<DashboardStatisticsModel>(`${this.apiBase}/getStatistics`, { headers: this.headers });
getMyDashboardStatistics(): Observable<DashboardStatistics> {
const url = `${this.apiBase}/mine/get-statistics`;
return this.http.get<DashboardStatistics>(url).pipe(catchError((error: any) => throwError(error)));
}
getUserStatistics(): Observable<DashboardStatisticsModel> {
return this.http.get<DashboardStatisticsModel>(`${this.apiBase}/me/getStatistics`, { headers: this.headers });
getPublicDashboardStatistics(): Observable<DashboardStatistics> {
const url = `${this.apiBase}/public/get-statistics`;
return this.http.get<DashboardStatistics>(url).pipe(catchError((error: any) => throwError(error)));
}
getRecentActivity(request: DataTableMultiTypeRequest<RecentActivityCriteria>): Observable<RecentActivityModel[]> {
return this.http.post<RecentActivityModel[]>(`${this.apiBase}/recentActivity`, request, {headers: this.headers});
}
// getRecentActivity(request: DataTableRequest<RecentActivityCriteria>): Observable<DataTableData<RecentActivityModel>> {
// return this.http.post<DataTableData<RecentActivityModel>>(this.actionUrl + 'recentActivity', request, {headers: this.headers});
// }
}

View File

@ -1,14 +0,0 @@
<div class="figure-card card">
<div class="card-header" [class.clickable]="isAuthenticated()" (click)="navigateToUrl()" [ngStyle]="{ 'background': linearColor, 'box-shadow': boxShadow }">
<i class="material-icons">{{ headerIcon }}</i>
</div>
<div class="card-content">
<p class="category">{{ category | translate }}</p>
<h3 class="title">{{ title }}</h3>
<button *ngIf="isAuthenticated()" mat-raised-button color="primary" (click)="createNew()">
<mat-icon>create_new_folder</mat-icon>
</button>
</div>
<div *ngIf="hasFootContent" class="card-footer">
</div>
</div>

View File

@ -1,68 +0,0 @@
.figure-card {
display: inline-block;
position: relative;
width: 100%;
margin: 25px 0;
}
.card-content {
text-align: center;
padding: 15px 20px 13px 20px;
}
.card-header {
float: left;
text-align: center;
/*background: linear-gradient(60deg, #ffa726, #fb8c00);*/
/*box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), 0 7px 10px -5px rgba(255, 152, 0, 0.4);*/
margin: -20px 15px 0;
border-radius: 3px;
padding: 15px;
position: relative;
}
.clickable{
cursor: pointer;
}
.card-header i {
font-size: 36px;
line-height: 56px;
width: 56px;
height: 56px;
color: #fff;
}
.category {
color: #999;
}
.card-footer {
margin: 0 20px 10px;
padding-top: 10px;
border-top: 1px solid #eee;
color: #999;
font-size: 12px;
position: relative;
}
.card-footer i {
font-size: 16px;
position: relative;
top: 4px;
color: #999;
}
.card {
padding: 25px 20px 20px 20px;
display: flex;
flex-direction: column;
align-items: center;
}
.card {
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.14);
border-radius: 6px;
color: rgba(0, 0, 0, 0.87);
background: #fff;
}

View File

@ -1,41 +0,0 @@
import { Component, Input, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from '../../../core/services/auth/auth.service';
@Component({
selector: 'app-dashboard-card',
templateUrl: './card.component.html',
styleUrls: ['./card.component.scss']
})
export class CardComponent implements OnInit {
@Input() headerIcon: string;
@Input() category: string;
@Input() title: string;
@Input() footerIcon: string;
@Input() footContent: string;
@Input() linearColor: string;
@Input() boxShadow: string;
@Input() routelLink: string;
@Input() hasFootContent = false;
@Input() buttonTitle: string;
@Input() buttonRedirectLink: string;
constructor(private router: Router, private authService: AuthService) { }
ngOnInit() {
}
navigateToUrl() {
if (!this.isAuthenticated()) { return; }
this.router.navigate([this.routelLink]);
}
createNew() {
this.router.navigate([this.buttonRedirectLink]);
}
isAuthenticated() {
return this.authService.currentAccountIsAuthenticated();
}
}

View File

@ -1,6 +1,6 @@
<div class="main-content dashboard-main-container h-100" [class.non-auth-main-container]="!this.isAuthenticated()">
<div *ngIf="this.isAuthenticated()" class="container-fluid">
<div *ngIf="this.dashboardStatisticsData">
<div *ngIf="this.dashboardStatistics">
<div class="main-content">
<div class="col">
<div class="card col-auto mt-0" [style.display]="isVisible ? 'block' : 'none'">
@ -32,24 +32,19 @@
<div *ngIf="this.hasDmps()" class="col">
<div class="latest-activity-title">{{'DASHBOARD.LATEST-ACTIVITY' | translate}}</div>
<mat-tab-group mat-align-tabs="start" class="remove-border-bottom"
[selectedIndex]="indexFromCurrentType" (selectedTabChange)="currentType = $event.tab.ariaLabel">
<!-- <mat-tab aria-label="recent" label="{{'DASHBOARD.ALL' | translate}} ({{totalRecents}})">-->
<mat-tab-group mat-align-tabs="start" class="remove-border-bottom" [selectedIndex]="indexFromCurrentType" (selectedTabChange)="currentType = $event.tab.ariaLabel">
<mat-tab aria-label="recent" label="{{'DASHBOARD.ALL' | translate}}">
<app-recent-edited-activity (totalCountRecentEdited)="onCountAllRecent($event)" [isActive]="currentType == 'recent'"></app-recent-edited-activity>
<div *ngIf="totalRecents === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div>
</mat-tab>
<!-- <mat-tab aria-label="draft" label="{{'DASHBOARD.DRAFTS' | translate}} ({{totalDraftDatasets}})">-->
<mat-tab aria-label="drafts" label="{{'DASHBOARD.DRAFTS' | translate}}">
<app-drafts (totalCountDraftDatasets)="onCountDraftDatasets($event)" [isActive]="currentType == 'drafts'"></app-drafts>
<div *ngIf="totalDraftDatasets === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div>
</mat-tab>>
<!-- <mat-tab aria-label="dmps" label="{{'DASHBOARD.DMPS' | translate}} ({{totalDmps}})">-->
<mat-tab aria-label="dmps" label="{{'DASHBOARD.DMPS' | translate}}">
<app-recent-edited-dmp-activity (totalCountDmps)="onCountDmps($event)" [isActive]="currentType == 'dmps'"></app-recent-edited-dmp-activity>
<div *ngIf="totalDmps === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div>
</mat-tab>
<!-- <mat-tab aria-label="datasets" label="{{'DASHBOARD.DESCRIPTIONS' | translate}} ({{totalDatasets}})">-->
<mat-tab aria-label="datasets" label="{{'DASHBOARD.DESCRIPTIONS' | translate}}">
<app-recent-edited-dataset-activity (totalCountDatasets)="onCountDatasets($event)" [isActive]="currentType == 'datasets'"></app-recent-edited-dataset-activity>
<div *ngIf="totalDatasets === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div>
@ -78,17 +73,17 @@
<div *ngIf="this.hasDmps()" class="col-auto stats">
<div class="personal-usage">{{'DASHBOARD.PERSONAL-USAGE' | translate}}</div>
<div [ngClass]="{'counter': dashboardStatisticsData?.totalDataManagementPlanCount != 0, 'counter-zero': dashboardStatisticsData?.totalDataManagementPlanCount == 0}">
{{dashboardStatisticsData?.totalDataManagementPlanCount}}</div>
<div [ngClass]="{'counter': dashboardStatistics?.dmpCount != 0, 'counter-zero': dashboardStatistics?.dmpCount == 0}">
{{dashboardStatistics?.dmpCount}}</div>
<a [routerLink]="['/plans']" class="link">{{'DASHBOARD.DMPS' | translate}}</a>
<div [ngClass]="{'counter': dashboardStatisticsData?.totalDataSetCount != 0, 'counter-zero': dashboardStatisticsData?.totalDataSetCount == 0}">
{{dashboardStatisticsData?.totalDataSetCount}}</div>
<div [ngClass]="{'counter': dashboardStatistics?.descriptionCount != 0, 'counter-zero': dashboardStatistics?.descriptionCount == 0}">
{{dashboardStatistics?.descriptionCount}}</div>
<a [routerLink]="['/datasets']" class="link">{{'DASHBOARD.DESCRIPTIONS' | translate}}</a>
<div [ngClass]="{'counter': dashboardStatisticsData?.totalGrantCount != 0, 'counter-zero': dashboardStatisticsData?.totalGrantCount == 0}">
{{dashboardStatisticsData?.totalGrantCount}}</div>
<div [ngClass]="{'counter': dashboardStatistics?.grantCount != 0, 'counter-zero': dashboardStatistics?.grantCount == 0}">
{{dashboardStatistics?.grantCount}}</div>
<a href="#" class="link-disabled">{{'DASHBOARD.GRANTS' | translate}}</a>
<div [ngClass]="{'counter': dashboardStatisticsData?.totalOrganisationCount != 0, 'counter-zero': dashboardStatisticsData?.totalOrganisationCount == 0}">
{{dashboardStatisticsData?.totalOrganisationCount}}</div>
<div [ngClass]="{'counter': dashboardStatistics?.organizationCount != 0, 'counter-zero': dashboardStatistics?.organizationCount == 0}">
{{dashboardStatistics?.organizationCount}}</div>
<a href="#" class="link-disabled">{{'DASHBOARD.RELATED-ORGANISATIONS' | translate}}</a>
</div>
</div>
@ -105,12 +100,6 @@
<!-- Home screen on log out -->
<div class="col p-0" *ngIf="!this.isAuthenticated()">
<div class="col-auto">
<!-- <div class="row">
<div class="col header-text-container">
<h3>{{ 'ABOUT.WELCOME' | translate }}</h3>
<h4>{{ 'ABOUT.WELCOME-MESSAGE' | translate }}</h4>
</div>
</div> -->
<div class="main-content">
<div class="col">
<div class="row">
@ -122,37 +111,26 @@
<p class="col-auto app-info">{{'DASHBOARD.INFO-TEXT' | translate}}</p>
</div>
<div class="d-flex">
<!-- <button type="button" class="col-auto align-self-center normal-btn" (click)="openNewDmpDialog()">{{'DASHBOARD.START-YOUR-FIRST-DMP' | translate}}</button> -->
<img class="col-auto ml-auto laptop-img" src="../../../assets/images/dashboard-popup.png">
<!-- <img class="col-auto ml-auto laptop-img"> -->
</div>
</div>
<div *ngIf="hasDmps()" class="col activity">
<!-- <div *ngIf="hasDmps()" class="col activity">
<div class="latest-activity-title">{{'DASHBOARD.LATEST-ACTIVITY' | translate}}</div>
<mat-tab-group mat-align-tabs="start" class="remove-border-bottom" (
[selectedIndex]="indexFromCurrentType" selectedTabChange)="currentType = $event.tab.ariaLabel">
<!-- <mat-tab aria-label="recent" label="{{'DASHBOARD.ALL' | translate}} ({{totalRecents}})">-->
<mat-tab-group mat-align-tabs="start" class="remove-border-bottom" ( [selectedIndex]="indexFromCurrentType" selectedTabChange)="currentType = $event.tab.ariaLabel">
<mat-tab aria-label="recent" label="{{'DASHBOARD.ALL' | translate}}">
<app-recent-edited-activity (totalCountRecentEdited)="onCountAllRecent($event)" [isActive]="currentType == 'recent'"></app-recent-edited-activity>
<div *ngIf="totalRecents === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div>
</mat-tab>
<!-- <mat-tab aria-label="dmps" label="{{'DASHBOARD.PUBLIC-DMPS' | translate}} ({{totalDmps}})">-->
<mat-tab aria-label="dmps" label="{{'DASHBOARD.PUBLIC-DMPS' | translate}}">
<app-recent-edited-dmp-activity (totalCountDmps)="onCountDmps($event)" [isActive]="currentType == 'dmps'"></app-recent-edited-dmp-activity>
<div *ngIf="totalDmps === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div>
</mat-tab>
<!-- <mat-tab aria-label="datasets" label="{{'DASHBOARD.PUBLIC-DATASETS' | translate}} ({{totalDatasets}})">-->
<mat-tab aria-label="datasets" label="{{'DASHBOARD.PUBLIC-DATASETS' | translate}}">
<app-recent-edited-dataset-activity (totalCountDatasets)="onCountDatasets($event)" [isActive]="currentType == 'datasets'"></app-recent-edited-dataset-activity>
<div *ngIf="totalDatasets === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div>
<!-- <div *ngIf="totalDatasets === 0" class="col-auto d-flex justify-content-center">
<button mat-raised-button class="add-dataset" [routerLink]="['/datasets/new']">
<mat-icon>add</mat-icon> {{'DASHBOARD.ACTIONS.ADD-DESCRIPTION' | translate}}
</button>
</div> -->
</mat-tab>
</mat-tab-group>
</div>
</div> -->
</div>
<div class="col-auto">
<div *ngIf="!hasDmps()" class="ml-auto pl-4 personal-usage-block">
@ -168,17 +146,17 @@
</div>
<div *ngIf="hasDmps()" class="ml-auto stats">
<div class="personal-usage">{{'DASHBOARD.PUBLIC-USAGE' | translate}}</div>
<div [ngClass]="{'counter': dashboardStatisticsData?.totalDataManagementPlanCount != 0, 'counter-zero': dashboardStatisticsData?.totalDataManagementPlanCount == 0}">
{{dashboardStatisticsData?.totalDataManagementPlanCount}}</div>
<div [ngClass]="{'counter': dashboardStatistics?.dmpCount != 0, 'counter-zero': dashboardStatistics?.dmpCount == 0}">
{{dashboardStatistics?.dmpCount}}</div>
<a [routerLink]="['/plans']" class="link">{{'DASHBOARD.PUBLIC-DMPS' | translate}}</a>
<div [ngClass]="{'counter': dashboardStatisticsData?.totalDataSetCount != 0, 'counter-zero': dashboardStatisticsData?.totalDataSetCount == 0}">
{{dashboardStatisticsData?.totalDataSetCount}}</div>
<div [ngClass]="{'counter': dashboardStatistics?.descriptionCount != 0, 'counter-zero': dashboardStatistics?.descriptionCount == 0}">
{{dashboardStatistics?.descriptionCount}}</div>
<a [routerLink]="['/datasets']" class="link">{{'DASHBOARD.PUBLIC-DATASETS' | translate}}</a>
<div [ngClass]="{'counter': dashboardStatisticsData?.totalGrantCount != 0, 'counter-zero': dashboardStatisticsData?.totalGrantCount == 0}">
{{dashboardStatisticsData?.totalGrantCount}}</div>
<div [ngClass]="{'counter': dashboardStatistics?.grantCount != 0, 'counter-zero': dashboardStatistics?.grantCount == 0}">
{{dashboardStatistics?.grantCount}}</div>
<a href="#" class="link-disabled">{{'DASHBOARD.GRANTS' | translate}}</a>
<div [ngClass]="{'counter': dashboardStatisticsData?.totalOrganisationCount != 0, 'counter-zero': dashboardStatisticsData?.totalOrganisationCount == 0}">
{{dashboardStatisticsData?.totalOrganisationCount}}</div>
<div [ngClass]="{'counter': dashboardStatistics?.organizationCount != 0, 'counter-zero': dashboardStatistics?.organizationCount == 0}">
{{dashboardStatistics?.organizationCount}}</div>
<a href="#" class="link-disabled">{{'DASHBOARD.RELATED-ORGANISATIONS' | translate}}</a>
</div>
</div>
@ -187,108 +165,4 @@
</div>
</div>
</div>
</div>
<!-- <div class="header-image">
<div class="header-text-container">
<h3>{{ 'ABOUT.WELCOME' | translate }}</h3>
<h4>{{ 'ABOUT.WELCOME-MESSAGE' | translate }}</h4>
</div>
</div>
<div class="main-content dashboard-main-container" [class.non-auth-main-container]="!this.isAuthenticated()">
<div *ngIf="this.isAuthenticated()" class="container-fluid">
<div class="row" *ngIf="this.isAuthenticated()">
<div class="col-sm-6 col-md-6 col-lg-6">
<app-wizard title="{{'QUICKWIZARD.CREATE-ADD.CREATE.TITLE' | translate}}" subtitle="{{'QUICKWIZARD.CREATE-ADD.CREATE.SUBTITLE' | translate}}" routerLink="/quick-wizard" icon="play_circle_outline">
</app-wizard>
</div>
<div class="col-sm-6 col-md-6 col-lg-6">
<app-wizard title="{{'QUICKWIZARD.CREATE-ADD.ADD.TITLE' | translate}}" subtitle="{{'QUICKWIZARD.CREATE-ADD.ADD.SUBTITLE' | translate}}" routerLink="/datasetcreatewizard" icon="play_circle_outline"></app-wizard>
</div>
</div>
<div class="row">
<div class="col-md-9">
<div class="row">
<div class="col-lg-3 col-md-6 col-sm-6">
<app-info-counter [title]="'DASHBOARD.MY-DMPS'" [subtitle]="dashboardStatisticsData?.totalDataManagementPlanCount" routerLink='/plans' buttonRedirectLink="/plans/new" icon="view_agenda"></app-info-counter>
</div>
<div class="col-lg-3 col-md-6 col-sm-6">
<app-info-counter [title]="'DASHBOARD.MY-DATASETS'" [subtitle]="dashboardStatisticsData?.totalDataSetCount" routerLink='/datasets' buttonRedirectLink="/datasets/new" icon="library_books"></app-info-counter>
</div>
<div class="col-lg-3 col-md-6 col-sm-6">
<app-info-counter [title]="'DASHBOARD.MY-GRANTS'" [subtitle]="dashboardStatisticsData?.totalGrantCount" icon="work_outline"></app-info-counter>
</div>
<div class="col-lg-3 col-md-6 col-sm-6">
<app-info-counter [title]="'DASHBOARD.ORGANIZATIONS'" [subtitle]="dashboardStatisticsData?.totalOrganisationCount" icon="scatter_plot">
</app-info-counter>
</div>
</div>
<div class="row">
<div class="col-lg-12 col-md-12">
<app-recent-edited-activity></app-recent-edited-activity>
</div>
</div>
</div>
<div class="col-md-3">
<app-drafts></app-drafts>
</div>
</div>
</div>
<div *ngIf="!this.isAuthenticated()" class="container-fluid">
<div class="row non-auth-stats">
<div class="col-lg-3 col-md-6 col-sm-6">
<app-info-counter [title]="'DASHBOARD.DMPS'" [subtitle]="dashboardStatisticsData?.totalDataManagementPlanCount" routerLink='/explore-plans' buttonRedirectLink="/plans/new" icon="view_agenda"></app-info-counter>
</div>
<div class="col-lg-3 col-md-6 col-sm-6">
<app-info-counter [title]="'DASHBOARD.DATASETS'" [subtitle]="dashboardStatisticsData?.totalDataSetCount" routerLink='/explore' buttonRedirectLink="/datasets/new" icon="library_books"></app-info-counter>
</div>
<div class="col-lg-3 col-md-6 col-sm-6">
<app-info-counter [title]="'DASHBOARD.GRANTS'" [subtitle]="dashboardStatisticsData?.totalGrantCount" icon="work_outline"></app-info-counter>
</div>
<div class="col-lg-3 col-md-6 col-sm-6">
<app-info-counter title="Related Organizations" [subtitle]="dashboardStatisticsData?.totalOrganisationCount" icon="scatter_plot"></app-info-counter>
</div>
</div>
<div class="d-flex flex-column align-items-center non-auth-title-container">
<h4>{{'DASHBOARD.TITLE' | translate}}</h4>
<p>{{'DASHBOARD.INFO-TEXT' | translate}}</p>
</div>
<div class="row">
<div class="col-lg-6 mt-4">
<div class="title">
<h4> {{'DASHBOARD.DATA-MANAGEMENT-PLANS' | translate}} </h4>
<div class="info">
<p class="subtitle">{{ dashboardStatisticsData?.totalDataManagementPlanCount }} {{'HOME.DMPS' | translate}}</p>
<a class="view-all" [routerLink]="['/explore-plans']">{{ 'GENERAL.ACTIONS.VIEW-ALL' | translate }}</a>
</div>
</div>
<mat-divider></mat-divider>
<div *ngFor="let dmp of dmpListingItems">
<app-dmp-info-counter [dmp]="dmp" (onClick)="dmpClicked($event)"></app-dmp-info-counter>
</div>
</div>
<div class="col-lg-6 mt-4">
<div class="row">
<div class="col-12 title">
<h4> DATASETS </h4>
<div class="info">
<p class="subtitle">{{ dashboardStatisticsData?.totalDataSetCount }} {{'HOME.DATASETS' | translate}}</p>
<a class="view-all" [routerLink]="['/explore']">{{ 'GENERAL.ACTIONS.VIEW-ALL' | translate }}</a>
</div>
</div>
<mat-divider class="col-12"></mat-divider>
<div class="col-12">
<div class="row">
<div *ngFor="let dataset of datasetListingItems" class="col-md-6">
<app-dataset-info-counter [dataset]="dataset" (onClick)="datasetClicked($event)">
</app-dataset-info-counter>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div> -->

View File

@ -424,130 +424,3 @@ input[type="text"] {
::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix {
padding: 0.3rem 0rem 0.6rem 0rem !important;
}
/* ::ng-deep .mat-tab-group {
height: 100%;
}
::ng-deep .mat-tab-body-wrapper {
flex-grow: 1;
}
::ng-deep .mat-tab-body {
display: flex !important;
flex-direction: column;
}
::ng-deep .mat-tab-body-content {
display: flex;
flex-direction: column;
flex-grow: 1;
} */
// .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;
// }
// .dashboard-main-container {
// margin-top: 0px;
// }
// .non-auth-main-container {
// padding: 0;
// }
// .non-auth-stats {
// background-color: rgba(255, 255, 255, 0.5);
// }
// .non-auth-title-container {
// margin-top: 3em;
// }
// .dashboard {
// .card {
// padding: 25px 20px 20px 20px;
// display: flex;
// flex-direction: column;
// align-items: center;
// }
// .card h6,
// p {
// color: #999;
// }
// .icon {
// margin-top: 20px;
// width: 130px;
// height: 130px;
// border: 1px solid #e5e5e5;
// border-radius: 50%;
// display: flex;
// justify-content: center;
// align-items: center;
// }
// .icon i {
// font-size: 55px;
// color: #e91e63;
// }
// .card-title {
// margin-top: 30px;
// margin-bottom: 3px;
// }
// .card-description {
// margin-bottom: 20px;
// }
// .card-dataset {
// display: flex;
// flex-direction: column;
// padding: 20px;
// position: relative;
// margin-top: 40px;
// }
// .card {
// box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.14);
// border-radius: 6px;
// color: rgba(0, 0, 0, 0.87);
// background: #fff;
// }
// .card-raised {
// box-shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.42), 0 4px 25px 0px rgba(0, 0, 0, 0.12),
// 0 8px 10px -5px rgba(0, 0, 0, 0.2);
// }
// .full-width {
// width: 100%;
// }
// }
// .info {
// display: flex;
// flex-wrap: nowrap;
// }
// .subtitle {
// margin-bottom: 0px !important;
// }
// .view-all {
// margin-left: auto;
// margin-bottom: 0px !important;
// color: #6aa4d9;
// }
// .view-all:hover {
// color: rgb(46, 117, 182) !important;
// }

View File

@ -1,38 +1,17 @@
import { Component, OnInit } from '@angular/core';
import { UntypedFormControl } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { RecentActivityType } from '@app/core/common/enum/recent-activity-type';
import { DashboardStatisticsModel } from '@app/core/model/dashboard/dashboard-statistics-model';
import { SearchBarItem } from '@app/core/model/dashboard/search-bar-item';
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
import { DatasetListingModel } from '@app/core/model/dataset/dataset-listing';
import { DmpListingModel } from '@app/core/model/dmp/dmp-listing';
import { GrantCriteria } from '@app/core/query/grant/grant-criteria';
import { RequestItem } from '@app/core/query/request-item';
import { DashboardStatistics } from '@app/core/model/dashboard/dashboard-statistics';
import { AuthService } from '@app/core/services/auth/auth.service';
import { DashboardService } from '@app/core/services/dashboard/dashboard.service';
import { DatasetService } from '@app/core/services/dataset/dataset.service';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { GrantService } from '@app/core/services/grant/grant.service';
import { SearchBarService } from '@app/core/services/search-bar/search-bar.service';
import { UserServiceOld } from '@app/core/services/user/user.service-old';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
import { BaseComponent } from '@common/base/base.component';
import { Observable, of as observableOf } from 'rxjs';
import { mergeMap, takeUntil } from 'rxjs/operators';
import { DmpCriteria } from '@app/core/query/dmp/dmp-criteria';
import { DatasetCriteria } from '@app/core/query/dataset/dataset-criteria';
import { MatDialog } from '@angular/material/dialog';
import { StartNewDmpDialogComponent } from '../dmp/start-new-dmp-dialogue/start-new-dmp-dialog.component';
import { StartNewDatasetDialogComponent } from '../dmp/start-new-dataset-dialogue/start-new-dataset-dialog.component';
import { DatasetWizardEditorModel } from '../dataset/dataset-wizard/dataset-wizard-editor.model';
import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service';
import { TranslateService } from '@ngx-translate/core';
import { UiNotificationService, SnackBarNotificationLevel } from '@app/core/services/notification/ui-notification-service';
import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service';
import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants';
import { MatomoService } from '@app/core/services/matomo/matomo-service';
import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants';
import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service';
import { BaseComponent } from '@common/base/base.component';
import { TranslateService } from '@ngx-translate/core';
import { takeUntil } from 'rxjs/operators';
import { StartNewDmpDialogComponent } from '../dmp/start-new-dmp-dialogue/start-new-dmp-dialog.component';
@Component({
@ -42,62 +21,27 @@ import { MatomoService } from '@app/core/services/matomo/matomo-service';
})
export class DashboardComponent extends BaseComponent implements OnInit {
public isVisible = true
public userInfo: any;
datasetActivities: any[];
grantActivities: any[];
dmpActivities: any[];
organisationActivities: any[];
public dashboardStatisticsData: DashboardStatisticsModel;
public formControl = new UntypedFormControl();
grantAutoCompleteConfiguration: SingleAutoCompleteConfiguration;
public searchControl = new UntypedFormControl();
filteredOptions: Observable<SearchBarItem[]>;
recentActivityTypeEnum = RecentActivityType;
public search = false;
dmpListingItems: DmpListingModel[] = [];
datasetListingItems: DatasetListingModel[] = [];
totalDatasets: number;
totalDmps: number;
totalDraftDatasets: number;
totalRecents: number;
dmpText: string;
datasetText: string;
importFileText: string;
startWizardText: string;
public dashboardStatistics: DashboardStatistics;
currentType: string = "recent";
constructor(
private router: Router,
private route: ActivatedRoute,
private grantService: GrantService,
private dmpService: DmpService,
private datasetService: DatasetService,
private datasetWizardService: DatasetWizardService,
private dashboardService: DashboardService,
private searchBarService: SearchBarService,
private authentication: AuthService,
private userService: UserServiceOld,
private dialog: MatDialog,
private language: TranslateService,
private uiNotificationService: UiNotificationService,
private guidedTourService: GuidedTourService,
private matomoService: MatomoService
) {
super();
// this.dashboardStatisticsData.totalDataManagementPlanCount = 0;
// this.dashboardStatisticsData.totalDataSetCount = 0;
// this.dashboardStatisticsData.totalGrantCount = 0;
}
ngOnInit() {
this.route.queryParams.subscribe(params => {
let type = params['type'];
if(type || type == "recent" || (type == "drafts" && this.isAuthenticated()) || type == "dmps" || type == "datasets") {
if (type || type == "recent" || (type == "drafts" && this.isAuthenticated()) || type == "dmps" || type == "descriptions") {
this.currentType = type;
} else {
this.currentType = "recent";
@ -105,157 +49,47 @@ export class DashboardComponent extends BaseComponent implements OnInit {
});
this.matomoService.trackPageView('Home Dashboard');
// if (this.isAuthenticated()) {
// this.userService.getRecentActivity()
// .pipe(takeUntil(this._destroyed))
// .subscribe(response => {
// this.datasetActivities = response['recentDatasetActivities'];
// this.dmpActivities = response['recentDmpActivities'];
// this.grantActivities = response['recentGrantActivities'];
// this.organisationActivities = response['totalOrganisationCount'];
// });
// }
// this.grantAutoCompleteConfiguration = {
// filterFn: this.searchGrant.bind(this),
// items: this.searchGrant(''),
// displayFn: (item) => item['label'],
// titleFn: (item) => item['label']
// };
if (!this.isAuthenticated()) {
this.dashboardService.getStatistics()
this.dashboardService.getPublicDashboardStatistics()
.pipe(takeUntil(this._destroyed))
.subscribe(results => {
//let data = results['payload'];
this.dashboardStatisticsData = results;
this.dashboardStatistics = results;
});
// this.getPublicDmps();
// this.getPublicDatasets();
} else {
this.dashboardService.getUserStatistics()
this.dashboardService.getMyDashboardStatistics()
.pipe(takeUntil(this._destroyed))
.subscribe(results => {
this.dashboardStatisticsData = results;
this.dashboardStatistics = results;
if (this.dashboardStatisticsData && this.dashboardStatisticsData.totalDataManagementPlanCount === 0) {
if (this.dashboardStatistics && this.dashboardStatistics.dmpCount === 0) {
this.openDashboardTour();
}
});
}
this.filteredOptions = this.searchControl.valueChanges.pipe(mergeMap(x => {
return this.searchBarService.search(x);
}));
}
public get indexFromCurrentType() {
if(this.currentType == "recent") {
if (this.currentType == "recent") {
return 0;
}
if(this.currentType == "drafts") {
if (this.currentType == "drafts") {
return 1;
}
if(this.currentType == "dmps") {
if (this.currentType == "dmps") {
return this.isAuthenticated() ? 2 : 1;
}
if(this.currentType == "datasets") {
if (this.currentType == "descriptions") {
return this.isAuthenticated() ? 3 : 2;
}
return 0;
}
// ngAfterContentChecked(): void {
// if (this.dashboardStatisticsData && this.dashboardStatisticsData.totalDataManagementPlanCount === 0) {
// this.openTour();
// }
// }
public isAuthenticated(): boolean {
return this.authentication.currentAccountIsAuthenticated();
}
searchGrant(query: string) {
const grantRequestItem: RequestItem<GrantCriteria> = new RequestItem();
grantRequestItem.criteria = new GrantCriteria();
grantRequestItem.criteria.like = query;
return this.grantService.getWithExternal(grantRequestItem);
}
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/edit/' + id]);
return;
}
default: throw new Error('Unsupported Activity Type ');
}
}
getPublicDmps() {
const dmpCriteria = new DmpCriteria();
dmpCriteria.allVersions = false;
dmpCriteria.isPublic = true;
dmpCriteria.onlyPublic = true;
const fields: Array<string> = new Array<string>();
fields.push('-finalizedAt');
const dataTableRequest: DataTableRequest<DmpCriteria> = new DataTableRequest(0, 2, { fields: fields });
dataTableRequest.criteria = dmpCriteria;
return this.dmpService.getPaged(dataTableRequest, "listing").pipe(takeUntil(this._destroyed)).subscribe(result => { this.dmpListingItems = result.data; });
}
getPublicDatasets() {
const dmpCriteria = new DatasetCriteria();
dmpCriteria.allVersions = false;
dmpCriteria.isPublic = true;
const fields: Array<string> = new Array<string>();
fields.push('-modified');
const dataTableRequest: DataTableRequest<DatasetCriteria> = new DataTableRequest(0, 4, { fields: fields });
dataTableRequest.criteria = dmpCriteria;
return this.datasetService.getPaged(dataTableRequest).pipe(takeUntil(this._destroyed)).subscribe(result => { this.datasetListingItems = result.data; });
}
dmpClicked(dmp: DmpListingModel) {
if (!this.isAuthenticated()) {
this.router.navigate(['../explore-plans/publicOverview', dmp.id], { relativeTo: this.route });
} else {
this.router.navigate(['/plans/publicEdit/' + dmp.id]);
}
}
datasetClicked(dataset: DatasetListingModel) {
this.router.navigate(['/datasets/publicEdit/' + dataset.id]);
}
public closeCard(): void {
this.isVisible = false;
}
onCountDmps(event): void {
this.totalDmps = event;
}
onCountDatasets(event): void {
this.totalDatasets = event;
}
onCountDraftDatasets(event): void {
this.totalDraftDatasets = event;
}
onCountAllRecent(event): void {
this.totalRecents = event;
}
openNewDmpDialog() {
if (this.dialog.openDialogs.length > 0) {
this.dialog.closeAll();
@ -271,43 +105,35 @@ export class DashboardComponent extends BaseComponent implements OnInit {
}
public hasDmps(): boolean {
if (this.dashboardStatisticsData) {
return this.dashboardStatisticsData.totalDataManagementPlanCount !== 0
|| this.dashboardStatisticsData.totalDataSetCount !== 0
|| this.dashboardStatisticsData.totalGrantCount !== 0
|| this.dashboardStatisticsData.totalOrganisationCount !== 0;
if (this.dashboardStatistics) {
return this.dashboardStatistics.dmpCount !== 0
|| this.dashboardStatistics.descriptionCount !== 0
|| this.dashboardStatistics.grantCount !== 0
|| this.dashboardStatistics.organizationCount !== 0;
} else {
return false;
}
}
addNewDataset() {
const dialogRef = this.dialog.open(StartNewDatasetDialogComponent, {
disableClose: false,
restoreFocus: false,
data: {
startNewDmp: false,
formGroup: new DatasetWizardEditorModel().buildForm()
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
if (result.startNewDmp) {
this.openNewDmpDialog();
} else {
this.router.navigate(['/plans', 'edit', result.formGroup.get('dmp').value.id]);
// Save dataset direct but missing title and template
// this.datasetWizardService.createDataset(result.formGroup.getRawValue())
// .pipe(takeUntil(this._destroyed))
// .subscribe(
// data => {
// this.onCallbackSuccess(data);
// },
// error => this.onCallbackError(error)
// );
}
}
});
addNewDescription() {
//TODO: add this
// const dialogRef = this.dialog.open(StartNewDescriptionDialogComponent, {
// disableClose: false,
// restoreFocus: false,
// data: {
// startNewDmp: false,
// formGroup: new DescriptionWizardEditorModel().buildForm()
// }
// });
// dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
// if (result) {
// if (result.startNewDmp) {
// this.openNewDmpDialog();
// } else {
// this.router.navigate(['/plans', 'edit', result.formGroup.get('dmp').value.id]);
// }
// }
// });
}
public dashboardTour: GuidedTour = {
@ -338,7 +164,7 @@ export class DashboardComponent extends BaseComponent implements OnInit {
closeAction: () => this.dialog.closeAll()
},
{
selector: '.new-dataset-tour',
selector: '.new-description-tour',
content: 'Step 4',
orientation: Orientation.BottomLeft,
isStepUnique: false,
@ -348,49 +174,32 @@ export class DashboardComponent extends BaseComponent implements OnInit {
};
public setDashboardTourDmpText(): void {
this.dmpText = this.language.instant('DASHBOARD.TOUR-GUIDE.DMP') + '\n\n' +
const dmpText = this.language.instant('DASHBOARD.TOUR-GUIDE.DMP') + '\n\n' +
this.language.instant('DASHBOARD.TOUR-GUIDE.START-NEW');
this.dashboardTour.steps[0].title = this.dmpText;
this.dashboardTour.steps[0].title = dmpText;
}
public setDashboardImportFileText(): void {
this.importFileText = this.language.instant('DASHBOARD.TOUR-GUIDE.IMPORT-DMP');
this.dashboardTour.steps[1].title = this.importFileText;
const importFileText = this.language.instant('DASHBOARD.TOUR-GUIDE.IMPORT-DMP');
this.dashboardTour.steps[1].title = importFileText;
}
public setDashboardStartWizardText(): void {
this.startWizardText = this.language.instant('DASHBOARD.TOUR-GUIDE.START-WIZARD');
this.dashboardTour.steps[2].title = this.startWizardText;
const startWizardText = this.language.instant('DASHBOARD.TOUR-GUIDE.START-WIZARD');
this.dashboardTour.steps[2].title = startWizardText;
}
public setDatasetText(): void {
this.datasetText = this.language.instant('DASHBOARD.TOUR-GUIDE.DATASET') + '\n\n' +
this.language.instant('DASHBOARD.TOUR-GUIDE.NEW-DATASET');
this.dashboardTour.steps[3].title = this.datasetText;
public setDescriptionText(): void {
const descriptionText = this.language.instant('DASHBOARD.TOUR-GUIDE.description') + '\n\n' +
this.language.instant('DASHBOARD.TOUR-GUIDE.NEW-description');
this.dashboardTour.steps[3].title = descriptionText;
}
openDashboardTour() {
this.setDashboardTourDmpText();
this.setDashboardImportFileText();
this.setDashboardStartWizardText();
this.setDatasetText();
this.setDescriptionText();
this.guidedTourService.startTour(this.dashboardTour);
}
// onCallbackSuccess(datasetId: String): void {
// this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION'), SnackBarNotificationLevel.Success);
// this.router.navigate(['/reload']).then(() => { this.router.navigate(['/datasets', 'edit', datasetId]); });
// }
// onCallbackError(error: any) {
// this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Error);
// }
// viewAllPublicDmpsClicked() {
// this.router.navigate(['/explore-plans']);
// }
// viewAllPublicDatasetsClicked() {
// this.router.navigate(['explore']);
// }
}

View File

@ -1,23 +1,18 @@
import { NgModule } from '@angular/core';
import { ExportMethodDialogModule } from '@app/library/export-method-dialog/export-method-dialog.module';
import { CardComponent } from '@app/ui/dashboard/card/card.component';
import { DashboardComponent } from '@app/ui/dashboard/dashboard.component';
import { DashboardRoutingModule } from '@app/ui/dashboard/dashboard.routing';
import { DatasetInfoCounterComponent } from '@app/ui/dashboard/dataset-info-counter/dataset-info-counter.component';
import { DraftsComponent } from '@app/ui/dashboard/drafts/drafts.component';
import { InfoCounterComponent } from '@app/ui/dashboard/info-counter/info-counter.component';
import { QuickWizardCreateAdd } from '@app/ui/dashboard/quick-wizard-create-add/quick-wizard-create-add.component';
import { RecentActivityComponent } from '@app/ui/dashboard/recent-activity/recent-activity.component';
import { RecentEditedActivityComponent } from '@app/ui/dashboard/recent-edited-activity/recent-edited-activity.component';
import { RecentVisitedActivityComponent } from '@app/ui/dashboard/recent-visited-activity/recent-visited-activity.component';
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 { DatasetCopyDialogModule } from '../dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.module';
import { RecentEditedDmpActivityComponent } from './recent-edited-dmp-activity/recent-edited-dmp-activity.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { FormattingModule } from '@app/core/formatting.module';
import { ExportMethodDialogModule } from '@app/library/export-method-dialog/export-method-dialog.module';
import { DashboardComponent } from '@app/ui/dashboard/dashboard.component';
import { DashboardRoutingModule } from '@app/ui/dashboard/dashboard.routing';
import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module';
import { CommonUiModule } from '@common/ui/common-ui.module';
import { DatasetCopyDialogModule } from '../dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.module';
import { DescriptionModule } from '../description/description.module';
import { DmpModule } from '../dmp/dmp.module';
import { DraftsComponent } from './drafts/drafts.component';
import { RecentEditedActivityComponent } from './recent-edited-activity/recent-edited-activity.component';
import { RecentEditedDescriptionActivityComponent } from './recent-edited-description-activity/recent-edited-description-activity.component';
import { RecentEditedDmpActivityComponent } from './recent-edited-dmp-activity/recent-edited-dmp-activity.component';
@NgModule({
imports: [
@ -28,21 +23,17 @@ import { FormattingModule } from '@app/core/formatting.module';
ConfirmationDialogModule,
DatasetCopyDialogModule,
FormsModule,
ReactiveFormsModule
ReactiveFormsModule,
DmpModule, //TODO: add only listing component to a seperate module
DescriptionModule //TODO: add only listing component to a seperate module
],
declarations: [
DashboardComponent,
RecentActivityComponent,
CardComponent,
QuickWizardCreateAdd,
WizardComponent,
InfoCounterComponent,
RecentVisitedActivityComponent,
RecentEditedActivityComponent,
DraftsComponent,
DatasetInfoCounterComponent,
RecentEditedDatasetActivityComponent,
RecentEditedDmpActivityComponent
RecentEditedDmpActivityComponent,
RecentEditedDescriptionActivityComponent,
DraftsComponent
]
})
export class DashboardModule { }

View File

@ -1,7 +1,6 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { DashboardComponent } from './dashboard.component';
import { QuickWizardCreateAdd } from './quick-wizard-create-add/quick-wizard-create-add.component';
const routes: Routes = [
{

View File

@ -1,77 +0,0 @@
.listing-item {
background-color: #ffffff;
}
.gray-container {
letter-spacing: 5px;
color: #aaaaaa;
}
.container-header {
display: flex;
align-items: baseline;
margin-top: 0px;
padding-top: 10px;
text-transform: uppercase;
min-height: 2.1em;
}
.container-header p {
letter-spacing: 5px;
color: #aaaaaa;
/* padding: 5px 30px; */
margin-bottom: 0px;
}
/* h4 {
display: inline;
padding-left: 1em;
} */
/* .title h4 {
padding-left: 30px;
line-height: 2em;
} */
.about-item {
display: flex;
}
.about-item .length {
color: var(--primary-color-3);
/* color: #089dbb; */
}
.about-item .title {
margin: 2px 10px;
}
.about-item p {
margin-left: auto;
margin-bottom: 0px;
padding-top: 7px;
color: #aaaaaa;
}
.icon {
color: #08bd63;
/* color: #92d050; */
}
hr {
margin: 0.6em 0em;
}
.date {
display: flex;
}
.date p {
margin-left: auto;
margin-bottom: 0em;
color: #aaaaaa;
}
.desc {
min-height: 1.5em;
}

View File

@ -1,31 +0,0 @@
<div class="row listing-item" (click)="itemClicked()">
<div class="col-12">
<div class="row">
<div class="col-12 gray-container container-header">
<p>{{ dataset.grantAbbreviation }}</p>
</div>
</div>
<div class="row">
<div class="col-12 about-item">
<mat-icon class="icon">bookmark</mat-icon>
<h4 class="title">{{ dataset.label }}</h4>
</div>
</div>
<div class="row">
<div class="col-12">
<p class="mt-1 mb-2 desc">{{dataset.description}}</p>
</div>
</div>
<div class="row">
<div class="col-12 about-item">
<div class="pt-1">
<div matTooltip="{{ dataset.profile }}" class="chip ml-2 mr-2">{{ dataset.profile }}</div>
</div>
</div>
</div>
<hr>
<div class="date">
<p>{{'DATASET-LISTING.COLUMNS.PUBLISHED' | translate}} {{dataset.created | date: "shortDate"}}</p>
</div>
</div>
</div>

View File

@ -1,26 +0,0 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { DatasetInfoCounterComponent } from './dataset-info-counter.component';
describe('DatasetInfoCounterComponent', () => {
let component: DatasetInfoCounterComponent;
let fixture: ComponentFixture<DatasetInfoCounterComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [DatasetInfoCounterComponent],
teardown: { destroyAfterEach: false }
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DatasetInfoCounterComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,22 +0,0 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { DatasetListingModel } from '../../../core/model/dataset/dataset-listing';
@Component({
selector: 'app-dataset-info-counter',
templateUrl: './dataset-info-counter.component.html',
styleUrls: ['./dataset-info-counter.component.css']
})
export class DatasetInfoCounterComponent implements OnInit {
@Input() dataset: DatasetListingModel;
@Output() onClick: EventEmitter<DatasetListingModel> = new EventEmitter();
constructor() { }
ngOnInit() {
}
itemClicked() {
this.onClick.emit(this.dataset);
}
}

View File

@ -1,7 +1,7 @@
<div class="col-md-12 d-flex justify-content-center" *ngIf="allRecentActivities == null">
<div class="col-md-12 d-flex justify-content-center" *ngIf="listingItems == null">
<span class="empty-list">{{'DMP-LISTING.EMPTY-LIST' | translate}}</span>
</div>
<div *ngIf="allRecentActivities != null" id="results" #results>
<div *ngIf="listingItems != null" id="results" #results>
<div class="d-flex flex-direction-row pt-4">
<!-- Sort by -->
<span class="d-flex align-items-center">{{'DMP-LISTING.SORT-BY' | translate}}:</span>
@ -9,8 +9,6 @@
<mat-select placeholder="{{'CRITERIA.LIKE'| translate}}" [formControl]="formGroup.get('order')">
<mat-option [value]="order.MODIFIED">{{enumUtils.toRecentActivityOrderString(order.MODIFIED)}}</mat-option>
<mat-option [value]="order.LABEL">{{enumUtils.toRecentActivityOrderString(order.LABEL)}}</mat-option>
<!-- <mat-option [value]="order.STATUS">{{enumUtils.toRecentActivityOrderString(order.STATUS)}}</mat-option> -->
<!-- <mat-option [value]="order.CREATED">{{enumUtils.toRecentActivityOrderString(order.CREATED)}}</mat-option> -->
</mat-select>
</mat-form-field>
<!-- End of Sort by -->
@ -22,144 +20,17 @@
</mat-form-field>
<!-- End of Search Filter -->
</div>
<div *ngIf="allRecentActivities && allRecentActivities.length > 0 && page > 1" class="d-flex justify-content-center">
<div *ngIf="listingItems && listingItems.length > 0 && page > 1" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadNextOrPrevious(false)">{{'GENERAL.ACTIONS.LOAD-LESS' | translate}}</button>
</div>
<div *ngFor="let activity of allRecentActivities">
<div *ngIf="activity && activity.type === recentActivityTypeEnum.Dmp.valueOf()">
<div class="dmp-card">
<!-- <a (click)="redirect(activity.id, activity.type)" class="pointer"> -->
<a [routerLink]="navigateToUrl(activity.id, activity.type)" class="pointer">
<div class="d-flex flex-direction-row">
<div class="col-auto dmp-label">{{ 'DMP-LISTING.DMP' | translate }}</div>
<div *ngIf="!publicMode" class="col-auto ml-auto edited-date">{{ 'DMP-LISTING.EDITED' | translate }}: {{ activity.modified | dateTimeCultureFormatter: "d MMMM y" }}</div>
<div *ngIf="publicMode" class="col-auto ml-auto edited-date">{{ 'DMP-LISTING.PUBLISHED' | translate }}: {{ activity.publishedAt | dateTimeCultureFormatter: "d MMMM y" }}</div>
<div *ngFor="let item of listingItems; let i = index">
<app-dmp-listing-item-component *ngIf="item.dmp" [showDivider]="i != (listingItems.length - 1)" [dmp]="item.dmp" [isPublic]="isPublic"></app-dmp-listing-item-component>
<app-description-listing-item-component *ngIf="item.description" [showDivider]="i != (listingItems.length - 1)" [description]="item.description" [isPublic]="isPublic" ></app-description-listing-item-component>
</div>
<div class="col-auto dmp-title-draft">{{activity.title}}</div>
<div class="dmp-subtitle">
<span class="col-auto">{{ roleDisplay(activity.users) }}</span>
<span>.</span>
<span 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-DESCRIPTIONS' | translate}}: ({{ getDatasets(activity).length }})
</div>
<div *ngFor="let dataset of getDatasets(activity); 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 && 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="getDatasets(activity).length > 3" (click)="redirect(activity.id, activity.type)"><u>{{'GENERAL.ACTIONS.SHOW-MORE' | translate}}</u></a> -->
<a class="d-flex justify-content-center pb-3 show-more" *ngIf="getDatasets(activity).length > 3" [routerLink]="navigateToUrl(activity.id, activity.type)"><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" *ngIf="isDraftDmp(activity)" [routerLink]="['/plans/edit/' + activity.id]" target="_blank"><span class="material-icons icon-align">add</span>{{'DMP-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isUserOwner(activity)" (click)="openShareDialog(activity.id, activity.title)"><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" *ngIf="isAuthenticated()" (click)="cloneOrNewVersionClicked(activity, false)"><span class="material-icons icon-align pr-2">filter_none</span>{{'DMP-LISTING.ACTIONS.CLONE' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="!isAuthenticated()" (click)="viewVersions(getGroupId(activity), activity.title, activity)"><span class="material-icons icon-align pr-2">library_books</span>{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="!isDraftDmp(activity) && isUserOwner(activity)" (click)="deleteDmpClicked(activity)"><span class="material-icons icon-align pr-2">delete</span>{{ 'DMP-LISTING.ACTIONS.DELETE' | translate }}</a>
<a class="col-auto pointer" *ngIf="isAuthenticated()" [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)="cloneOrNewVersionClicked(activity, true)">
<mat-icon>queue</mat-icon>{{'DMP-LISTING.ACTIONS.NEW-VERSION' | translate}}
</button>
<button mat-menu-item (click)="viewVersions(getGroupId(activity), activity.title, activity)">
<mat-icon>library_books</mat-icon>{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}}
</button>
<button mat-menu-item *ngIf="isDraftDmp(activity) && isUserOwner(activity)" (click)="deleteDmpClicked(activity)" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'DMP-LISTING.ACTIONS.DELETE' | translate }}
</button>
</mat-menu>
</div>
</div>
<div *ngIf="activity && activity.type === recentActivityTypeEnum.Dataset.valueOf()">
<div class="dataset-card">
<!-- <a (click)="redirect(activity.id, activity.type)" class="pointer"> -->
<a [routerLink]="navigateToUrl(activity.id, activity.type)" class="pointer">
<div class="d-flex flex-direction-row">
<div class="col-auto dataset-label">{{'DATASET-LISTING.DESCRIPTION' | translate}}</div>
<div *ngIf="!publicMode" class="col-auto ml-auto edited-date">{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{activity.modified | dateTimeCultureFormatter: "d MMMM y"}}</div>
<div *ngIf="publicMode" class="col-auto ml-auto edited-date">{{'DATASET-LISTING.STATES.PUBLISHED' | translate}}: {{activity.publishedAt | dateTimeCultureFormatter: "d MMMM y"}}</div>
</div>
<div class="col-auto dataset-title-draft">{{activity.title}}</div>
<div class="dataset-subtitle">
<span class="col-auto">{{ roleDisplay(activity.users) }}</span>
<span>.</span>
<span 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 pr-0">{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}}
<div class="col-auto dmp-label ml-3">{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}</div>
</div>
<!-- <div class="col-auto dmp-label">{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}</div> -->
<div class="col dmp-title">{{ getDmp(activity) }}</div>
</div>
</a>
<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" *ngIf="isAuthenticated()" (click)="openShareDialog(getDmpId(activity), getDmp(activity))"><span class="material-icons icon-align pr-2">group_add</span>{{'DATASET-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" (click)="openDmpSearchDialogue(activity)"><span class="material-icons icon-align pr-2">file_copy</span>{{'DATASET-WIZARD.ACTIONS.COPY-DESCRIPTION' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" (click)="deleteDatasetClicked(activity.id)"><span class="material-icons icon-align pr-2">delete</span>{{ 'DATASET-WIZARD.ACTIONS.DELETE' | 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)" class="menu-item">
<mat-icon>file_copy</mat-icon>{{'DATASET-WIZARD.ACTIONS.COPY-DESCRIPTION' | translate}}
</button>
<button mat-menu-item (click)="deleteDatasetClicked(activity.id)" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'DATASET-WIZARD.ACTIONS.DELETE' | 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>
<div class="text-muted d-flex justify-content-center mt-5" *ngIf="!hasMoreActivity && allRecentActivities && allRecentActivities.length > 0">
<div class="text-muted d-flex justify-content-center mt-5" *ngIf="!hasMoreActivity && listingItems && listingItems.length > 0">
{{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}}
</div>
<div *ngIf="allRecentActivities && allRecentActivities.length > 0 && (allRecentActivities.length >= startIndex + pageSize) && hasMoreActivity" class="d-flex justify-content-center">
<div *ngIf="listingItems && listingItems.length > 0 && (listingItems.length >= startIndex + pageSize) && hasMoreActivity" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadNextOrPrevious()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
</div>

View File

@ -1,48 +1,20 @@
import { Location } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { DmpBlueprintSectionFieldCategory } from '@app/core/common/enum/dmp-blueprint-section-field-category';
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { Role } from '@app/core/common/enum/role';
import { DatasetUrlListing } from "@app/core/model/dataset/dataset-url-listing";
import { DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { DmpModel } from "@app/core/model/dmp/dmp";
import { DmpListingModel } from "@app/core/model/dmp/dmp-listing";
import { RecentActivityModel } from "@app/core/model/recent-activity/recent-activity.model";
import { RecentDatasetModel } from "@app/core/model/recent-activity/recent-dataset-activity.model";
import { RecentDmpModel } from "@app/core/model/recent-activity/recent-dmp-activity.model";
import { RecentActivityCriteria } from "@app/core/query/recent-activity/recent-activity-criteria";
import { RecentActivityItem } from '@app/core/model/dashboard/recent-activity-item';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { Description } from '@app/core/model/description/description';
import { Dmp, DmpUser } from "@app/core/model/dmp/dmp";
import { DmpReference, Reference } from '@app/core/model/reference/reference';
import { RecentActivityItemLookup } from '@app/core/query/recent-activity-item-lookup.lookup';
import { DashboardService } from "@app/core/services/dashboard/dashboard.service";
import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service';
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
import { DmpService } from "@app/core/services/dmp/dmp.service";
import { LockService } from '@app/core/services/lock/lock.service';
import { MatomoService } from '@app/core/services/matomo/matomo-service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
import { DatasetCopyDialogueComponent } from '@app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component';
import { CloneDialogComponent } from "@app/ui/dmp/clone/clone-dialog/clone-dialog.component";
import { DmpEditorModel } from "@app/ui/dmp/editor/dmp-editor.model";
import { ExtraPropertiesFormModel } from "@app/ui/dmp/editor/general-tab/extra-properties-form.model";
import { FunderFormModel } from "@app/ui/dmp/editor/grant-tab/funder-form-model";
import { GrantTabModel } from "@app/ui/dmp/editor/grant-tab/grant-tab-model";
import { ProjectFormModel } from "@app/ui/dmp/editor/grant-tab/project-form-model";
import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dmp-invitation-dialog.component';
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
import { BaseComponent } from '@common/base/base.component';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import { TranslateService } from '@ngx-translate/core';
import * as FileSaver from 'file-saver';
import { debounceTime, map, takeUntil } from 'rxjs/operators';
import { DmpStatus } from '../../../core/common/enum/dmp-status';
import { RecentActivityType } from '../../../core/common/enum/recent-activity-type';
import { DataTableMultiTypeRequest } from '../../../core/model/data-table/data-table-request';
import { DatasetListingModel } from '../../../core/model/dataset/dataset-listing';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { AuthService } from '../../../core/services/auth/auth.service';
@Component({
@ -52,21 +24,10 @@ import { AuthService } from '../../../core/services/auth/auth.service';
})
export class DraftsComponent extends BaseComponent implements OnInit {
@Output() totalCountRecentEdited: EventEmitter<any> = new EventEmitter();
@ViewChild("results") resultsContainer;
allRecentActivities: RecentActivityModel[];
recentActivityTypeEnum = RecentActivityType;
dmpModel: DmpEditorModel;
isDraft: boolean;
totalCount: number;
startIndex: number = 0;
dmpOffset: number = 0;
datasetOffset: number = 0;
offsetLess: number = 0;
lookup: RecentActivityItemLookup = new RecentActivityItemLookup();
pageSize: number = 5;
dmpFormGroup: UntypedFormGroup;
hasMoreActivity: boolean = true;
listingItems: RecentActivityItem[];
public formGroup = new UntypedFormBuilder().group({
like: new UntypedFormControl(),
order: new UntypedFormControl()
@ -75,6 +36,9 @@ export class DraftsComponent extends BaseComponent implements OnInit {
order = RecentActivityOrder;
totalCount: number;
startIndex: number = 0;
offsetLess: number = 0;
page: number = 1;
@Input() isActive: boolean = false;
@ -83,38 +47,34 @@ export class DraftsComponent extends BaseComponent implements OnInit {
private router: Router,
public enumUtils: EnumUtils,
private authentication: AuthService,
private dmpService: DmpService,
private dmpBlueprintService: DmpBlueprintService,
private dashboardService: DashboardService,
private language: TranslateService,
private dialog: MatDialog,
private uiNotificationService: UiNotificationService,
private datasetWizardService: DatasetWizardService,
private location: Location,
private lockService: LockService,
private httpClient: HttpClient,
private matomoService: MatomoService,
private fileUtils: FileUtils
private matomoService: MatomoService
) {
super();
}
ngOnInit() {
this.matomoService.trackPageView('Drafts');
this.matomoService.trackPageView('Recent DMP Activity');
this.route.queryParams.subscribe(params => {
if (this.isActive) {
let page = (params['page'] === undefined) ? 1 : +params['page'];
this.page = (page <= 0) ? 1 : page;
this.datasetOffset = (this.page - 1) * this.pageSize;
this.dmpOffset = (this.page - 1) * this.pageSize;
this.startIndex = (this.page - 1) * this.pageSize;
if (this.page > 1) {
this.offsetLess = (this.page - 2) * this.pageSize;
}
let order = params['order'];
if (order === undefined || (order != this.order.MODIFIED && order != this.order.LABEL)) {
order = this.order.MODIFIED;
if (this.isAuthenticated()) {
if (order === undefined || (order != this.order.UpdatedAt && order != this.order.Label && order != this.order.Status)) {
order = this.order.UpdatedAt;
}
} else {
if (order === undefined || (order != this.order.PUBLISHED && order != this.order.LABEL)) {
order = this.order.PUBLISHED;
}
}
this.formGroup.get('order').setValue(order);
@ -125,49 +85,7 @@ export class DraftsComponent extends BaseComponent implements OnInit {
}
});
if (this.isAuthenticated()) {
if (!this.formGroup.get('order').value) {
this.formGroup.get('order').setValue(this.order.MODIFIED);
}
const fields: Array<string> = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value];
const allDataTableRequest: DataTableMultiTypeRequest<RecentActivityCriteria> = new DataTableMultiTypeRequest(this.dmpOffset, this.datasetOffset, 5, { fields: fields });
allDataTableRequest.criteria = new RecentActivityCriteria();
allDataTableRequest.criteria.like = this.formGroup.get('like').value;
allDataTableRequest.criteria.order = this.formGroup.get('order').value;
allDataTableRequest.criteria.status = 0;
this.dashboardService
.getRecentActivity(allDataTableRequest)
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
this.allRecentActivities = response;
this.allRecentActivities.forEach(recentActivity => {
if (recentActivity.type === RecentActivityType.Dataset) {
// this.datasetOffset = this.datasetOffset + 1;
this.datasetOffset = this.page * this.pageSize;
} else if (recentActivity.type === RecentActivityType.Dmp) {
// this.dmpOffset = this.dmpOffset + 1;
this.dmpOffset = this.page * this.pageSize;
}
});
this.totalCountRecentEdited.emit(this.allRecentActivities.length);
if (this.allRecentActivities.length == 0 && this.page > 1) {
let queryParams = { type: "recent", page: 1, order: this.formGroup.get("order").value };
if (this.formGroup.get("like").value) {
queryParams['keyword'] = this.formGroup.get("like").value;
}
this.router.navigate(["/home"], { queryParams: queryParams })
}
});
this.formGroup.get('like').valueChanges
.pipe(takeUntil(this._destroyed), debounceTime(500))
.subscribe(x => {
this.refresh()
});
this.formGroup.get('order').valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => {
this.refresh()
});
this.refresh();
}
}
@ -178,578 +96,93 @@ export class DraftsComponent extends BaseComponent implements OnInit {
}
updateUrl() {
let parameters = "?type=drafts" +
let parameters = "?type=dmps" +
(this.page != 1 ? "&page=" + this.page : "") +
(this.formGroup.get("order").value != this.order.MODIFIED ? "&order=" + this.formGroup.get("order").value : "") +
(((this.formGroup.get("order").value != this.order.MODIFIED && !this.publicMode) || (this.formGroup.get("order").value != this.order.PUBLISHED && this.publicMode)) ? "&order=" + this.formGroup.get("order").value : "") +
(this.formGroup.get("like").value ? ("&keyword=" + this.formGroup.get("like").value) : "");
this.location.go(this.router.url.split('?')[0] + parameters);
}
getDatasets(activity: RecentDmpModel): DatasetUrlListing[] {
return activity.datasets;
}
getGroupId(activity: RecentDmpModel): string {
return activity.groupId;
}
getDmp(activity: RecentDatasetModel): String {
return activity.dmp;
}
getDmpId(activity: RecentDatasetModel): String {
return activity.dmpId;
}
public isAuthenticated(): boolean {
return this.authentication.currentAccountIsAuthenticated();
}
isUserOwner(activity: DmpListingModel): boolean {
const principalId: string = this.authentication.userId()?.toString();
if (principalId) return !!activity.users.find(x => (x.role === Role.Owner) && (principalId === x.id));
}
editClicked(dmp: DmpListingModel) {
this.router.navigate(['/plans/edit/' + dmp.id]);
}
deleteDmpClicked(dmp: DmpListingModel) {
this.lockService.checkLockStatus(dmp.id).pipe(takeUntil(this._destroyed))
.subscribe(lockStatus => {
if (!lockStatus) {
this.openDeleteDmpDialog(dmp);
} else {
this.openDmpLockedByUserDialog();
}
});
}
cloneOrNewVersionClicked(dmp: RecentActivityModel, isNewVersion: boolean) {
this.dmpService.getSingle(dmp.id).pipe(map(data => data as DmpModel))
.pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.dmpModel = new DmpEditorModel();
this.dmpModel.grant = new GrantTabModel();
this.dmpModel.project = new ProjectFormModel();
this.dmpModel.funder = new FunderFormModel();
this.dmpModel.extraProperties = new ExtraPropertiesFormModel();
this.dmpModel.fromModel(data);
this.dmpModel.status = DmpStatus.Draft;
this.dmpFormGroup = this.dmpModel.buildForm();
if (!isNullOrUndefined(this.formGroup.get('profile').value)) {
this.dmpBlueprintService.getSingle(this.formGroup.get('profile').value)
.pipe(takeUntil(this._destroyed))
.subscribe(result => {
this.checkForGrant(result.definition);
this.checkForFunder(result.definition);
this.checkForProject(result.definition);
});
}
if (!isNewVersion) {
this.dmpFormGroup.get('label').setValue(dmp.title + " New");
}
this.openCloneDialog(isNewVersion);
});
}
private checkForGrant(blueprint: DmpBlueprintDefinition) {
let hasGrant = false;
blueprint.sections.forEach(section => section.fields.forEach(
field => {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
hasGrant = true;
}
}
));
if (!hasGrant) {
this.formGroup.removeControl('grant');
}
}
private checkForFunder(blueprint: DmpBlueprintDefinition) {
let hasFunder = false;
blueprint.sections.forEach(section => section.fields.forEach(
field => {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
hasFunder = true;
}
}
));
if (!hasFunder) {
this.formGroup.removeControl('funder');
}
}
private checkForProject(blueprint: DmpBlueprintDefinition) {
let hasProject = false;
blueprint.sections.forEach(section => section.fields.forEach(
field => {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
hasProject = true;
}
}
));
if (!hasProject) {
this.formGroup.removeControl('project');
}
}
openCloneDialog(isNewVersion: boolean) {
const dialogRef = this.dialog.open(CloneDialogComponent, {
maxWidth: '700px',
maxHeight: '80vh',
data: {
formGroup: this.dmpFormGroup,
datasets: this.dmpFormGroup.get('datasets').value,
isNewVersion: isNewVersion,
confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.SAVE'),
cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'),
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
if (!isNewVersion) {
this.dmpService.clone(this.dmpFormGroup.getRawValue(), this.dmpFormGroup.get('id').value)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onCloneOrNewVersionCallbackSuccess(complete),
error => this.onCloneOrNewVersionCallbackError(error)
);
} else if (isNewVersion) {
this.dmpService.newVersion(this.dmpFormGroup.getRawValue(), this.dmpFormGroup.get('id').value)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onCloneOrNewVersionCallbackSuccess(complete),
error => this.onCloneOrNewVersionCallbackError(error)
);
}
}
});
}
openDeleteDmpDialog(dmp: DmpListingModel) {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
maxWidth: '300px',
restoreFocus: false,
data: {
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'),
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
isDeleteConfirmation: true
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
this.dmpService.delete(dmp.id)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onDeleteCallbackSuccess(),
error => this.onDeleteCallbackError(error)
);
}
});
}
openDmpLockedByUserDialog() {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
maxWidth: '400px',
restoreFocus: false,
data: {
message: this.language.instant('DMP-EDITOR.ACTIONS.LOCK')
}
});
}
openShareDialog(rowId: any, rowName: any) {
const dialogRef = this.dialog.open(DmpInvitationDialogComponent, {
// height: '250px',
// width: '700px',
autoFocus: false,
restoreFocus: false,
data: {
dmpId: rowId,
dmpName: rowName
}
});
}
isDraftDmp(activity: DmpListingModel) {
return activity.status == DmpStatus.Draft;
}
onCallbackSuccess(): void {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
this.router.navigate(['/plans']);
}
reloadPage(): void {
const path = this.location.path();
this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => {
this.router.navigate([path]);
});
}
onDeleteCallbackSuccess(): void {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success);
this.reloadPage();
}
onDeleteCallbackError(error) {
this.uiNotificationService.snackBarNotification(error.error.message ? this.language.instant(error.error.message) : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error);
}
onCloneOrNewVersionCallbackSuccess(dmpId: String): void {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
this.router.navigate(['/plans/edit/', dmpId]);
}
onCloneOrNewVersionCallbackError(error: any) {
this.uiNotificationService.snackBarNotification(error.error.message ? this.language.instant(error.error.message) : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-CLONE'), SnackBarNotificationLevel.Error);
}
redirect(id: string, type: RecentActivityType) {
switch (type) {
case RecentActivityType.Grant: {
this.router.navigate(["grants/edit/" + id]);
return;
}
case RecentActivityType.Dataset: {
if (this.isAuthenticated()) {
this.router.navigate(['../datasets/overview/' + id]);
}
return;
}
case RecentActivityType.Dmp: {
if (this.isAuthenticated()) {
this.router.navigate(['../plans/overview/' + id]);
}
return;
}
default:
throw new Error("Unsupported Activity Type ");
}
}
navigateToUrl(id: string, type: RecentActivityType): string[] {
switch (type) {
case RecentActivityType.Grant: {
return ["grants/edit/" + id];
}
case RecentActivityType.Dataset: {
if (this.isAuthenticated()) {
return ['../datasets/overview/' + id];
} else {
return ['../explore/publicOverview', id];
}
}
case RecentActivityType.Dmp: {
if (this.isAuthenticated()) {
return ['../plans/overview/' + id];
} else {
return ['../explore-plans/publicOverview', id];
}
}
default:
throw new Error("Unsupported Activity Type ");
}
}
roleDisplay(value: any) {
const principalId: string = this.authentication.userId()?.toString();
let role: number;
if (principalId) {
value.forEach(element => {
if (principalId === 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');
}
}
// dmpBlueprintDisplay(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.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.matomoService.trackDownload('dmps', "xml", id);
});
}
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.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.matomoService.trackDownload('dmps', "docx", id);
});
}
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.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.matomoService.trackDownload('dmps', "pdf", id);
});
}
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.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.matomoService.trackDownload('dmps', "json", id);
}, async error => {
this.onExportCallbackError(error);
});
}
async onExportCallbackError(error: any) {
const errorJsonText = await error.error.text();
const errorObj = JSON.parse(errorJsonText);
this.uiNotificationService.snackBarNotification(errorObj.message, SnackBarNotificationLevel.Error);
}
downloadPDF(dataset: DatasetListingModel): void {
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.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.matomoService.trackDownload('datasets', "pdf", dataset.id);
});
}
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.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.matomoService.trackDownload('datasets', "docx", dataset.id);
});
}
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.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.matomoService.trackDownload('datasets', "xml", dataset.id);
});
}
viewVersions(rowId: String, rowLabel: String, activity: DmpListingModel) {
if (activity.public && !this.isUserOwner(activity)) {
let url = this.router.createUrlTree(['/explore-plans/versions/', rowId, { groupLabel: rowLabel }]);
window.open(url.toString(), '_blank');
// this.router.navigate(['/explore-plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } });
} else {
let url = this.router.createUrlTree(['/plans/versions/', rowId, { groupLabel: rowLabel }]);
window.open(url.toString(), '_blank');
// this.router.navigate(['/plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } });
}
}
openDmpSearchDialogue(dataset: RecentDatasetModel) {
const formControl = new UntypedFormControl();
const dialogRef = this.dialog.open(DatasetCopyDialogueComponent, {
width: '500px',
restoreFocus: false,
data: {
formControl: formControl,
datasetId: dataset.id,
datasetProfileId: dataset.profile.id,
datasetProfileExist: false,
confirmButton: this.language.instant('DATASET-WIZARD.DIALOGUE.COPY'),
cancelButton: this.language.instant('DATASET-WIZARD.DIALOGUE.CANCEL')
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed))
.subscribe(result => {
if (result && result.datasetProfileExist) {
const newDmpId = result.formControl.value.id;
// let url = this.router.createUrlTree(['/datasets/copy/', result.datasetId, { newDmpId: newDmpId }]);
// window.open(url.toString(), '_blank');
this.router.navigate(['/datasets/copy/' + result.datasetId], { queryParams: { newDmpId: newDmpId } });
}
});
}
deleteDatasetClicked(id: string) {
this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed))
.subscribe(lockStatus => {
if (!lockStatus) {
this.openDeleteDatasetDialog(id);
} else {
this.openDatasetLockedByUserDialog();
}
});
}
openDeleteDatasetDialog(id: string): void {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
maxWidth: '300px',
restoreFocus: false,
data: {
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'),
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
isDeleteConfirmation: true
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
this.datasetWizardService.delete(id)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onDeleteCallbackSuccess(),
error => this.onDeleteCallbackError(error)
);
}
});
}
openDatasetLockedByUserDialog() {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
maxWidth: '400px',
restoreFocus: false,
data: {
message: this.language.instant('DATASET-WIZARD.ACTIONS.LOCK')
}
});
}
refresh(): void {
this.datasetOffset = 0;
this.dmpOffset = 0;
this.page = 1;
this.updateUrl();
if (!this.formGroup.get('order').value) {
this.formGroup.get('order').setValue(this.order.UpdatedAt);
}
this.lookup.onlyDraft = true;
this.lookup.page = { size: this.pageSize, offset: 0 };
this.lookup.orderField = this.formGroup.get('order').value;
this.lookup.like = this.formGroup.get('like').value;
this.lookup.project = {
const fields: Array<string> = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value];
// const fields: Array<string> = ["-modified"];
this.startIndex = 0;
const allDataTableRequest: DataTableMultiTypeRequest<RecentActivityCriteria> = new DataTableMultiTypeRequest(0, 0, this.pageSize, { fields: fields });
allDataTableRequest.criteria = new RecentActivityCriteria();
allDataTableRequest.criteria.like = this.formGroup.get("like").value;
allDataTableRequest.criteria.order = this.formGroup.get("order").value;
allDataTableRequest.criteria.status = 0;
fields: [
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.status)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.version)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.groupId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.updatedAt)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.status)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.updatedAt)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.groupId)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.type)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.reference)].join('.'),
]
};
this.dashboardService
.getRecentActivity(allDataTableRequest)
.getMyRecentActivityItems(this.lookup)
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
this.allRecentActivities = response;
this.allRecentActivities.forEach(recentActivity => {
if (recentActivity.type === RecentActivityType.Dataset) {
// this.datasetOffset = this.datasetOffset + 1;
this.datasetOffset = this.page * this.pageSize;
} else if (recentActivity.type === RecentActivityType.Dmp) {
// this.dmpOffset = this.dmpOffset + 1;
this.dmpOffset = this.page * this.pageSize;
}
});
this.listingItems = response;
//this.totalCount = response.totalCount;
if (response.length < this.pageSize) {
this.hasMoreActivity = false;
} else {
this.hasMoreActivity = true;
}
this.totalCountRecentEdited.emit(this.allRecentActivities.length);
});
}
public loadNextOrPrevious(more: boolean = true) {
const fields: Array<string> = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value];
// const fields: Array<string> = ["-modified"];
let request;
if (more) {
request = new DataTableMultiTypeRequest<RecentActivityCriteria>(this.dmpOffset, this.datasetOffset, this.pageSize, { fields: fields });
} else {
request = new DataTableMultiTypeRequest<RecentActivityCriteria>(this.offsetLess, this.offsetLess, this.pageSize, { fields: fields });
}
request.criteria = new RecentActivityCriteria();
request.criteria.like = this.formGroup.get("like").value ? this.formGroup.get("like").value : "";
request.criteria.order = this.formGroup.get("order").value;
request.criteria.status = 0;
this.dashboardService.getRecentActivity(request).pipe(takeUntil(this._destroyed)).subscribe(result => {
if (!result || result.length == 0) {
this.hasMoreActivity = false;
// return [];
} else {
this.page = this.page + (more ? 1 : -1);
this.updateUrl();
// if(more) {
// result.forEach(recentActivity => {
// if (recentActivity.type === RecentActivityType.Dataset) {
// this.datasetOffset = this.datasetOffset + 1;
this.datasetOffset = this.page * this.pageSize;
// } else if (recentActivity.type === RecentActivityType.Dmp) {
// this.dmpOffset = this.dmpOffset + 1;
this.dmpOffset = this.page * this.pageSize;
//this.totalCountDmps.emit(this.dmpActivities.length);
// if (this.totalCount > 0 && this.totalCount <= (this.page - 1) * this.pageSize && this.page > 1) {
// let queryParams = { type: "dmps", page: 1, order: this.formGroup.get("order").value };
// if (this.formGroup.get("like").value) {
// queryParams['keyword'] = this.formGroup.get("like").value;
// }
// });
// this.router.navigate(["/home"], { queryParams: queryParams })
// }
if (this.page > 1) {
this.offsetLess = (this.page - 2) * this.pageSize;
}
if (result.length < this.pageSize) {
this.hasMoreActivity = false;
} else {
this.hasMoreActivity = true;
}
// this.allRecentActivities = this.allRecentActivities.concat(result);
// this.allRecentActivities = this.allRecentActivities.length > 0 ? this.mergeTwoSortedLists(this.allRecentActivities, result, this.formGroup.get('order').value) : result;
this.allRecentActivities = result;
this.totalCountRecentEdited.emit(this.allRecentActivities.length);
if (more) {
this.resultsContainer.nativeElement.scrollIntoView();
}
}
// this.totalCount < this.pageSize ? this.totalCountDmps.emit(response.totalCount) : this.totalCountDmps.emit(this.pageSize);
// this.totalCountDmps.emit(this.totalCount);
// this.dmpActivities.forEach(dmpActivity => {
// const recentActivity: RecentActivity = {
// activityData: dmpActivity,
// activityType: RecentActivityType.Dmp
// };
// this.allRecentActivities.push(recentActivity)
// })
});
this.formGroup.get('like').valueChanges
.pipe(takeUntil(this._destroyed), debounceTime(500))
.subscribe(x => this.refresh());
this.formGroup.get('order').valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => this.refresh());
}
}

View File

@ -1,20 +0,0 @@
<div class="card card-stats">
<div class="card-header card-header-default card-header-icon" [class.clickable]="isAuthenticated()" (click)="navigateToUrl()">
<div *ngIf="routerLink" class="card-icon">
<i class="material-icons-outlined">{{ icon }}</i>
</div>
<div *ngIf="!routerLink" class="card-icon card-icon-nocursor">
<i class="material-icons-outlined">{{ icon }}</i>
</div>
<p class="card-category">{{ title | translate }}</p>
<h3 class="card-title">
<b>{{ subtitle }}</b>
</h3>
</div>
<div class="card-footer">
<div class="stats">
<a *ngIf="routerLink" class="view-all" [class.clickable]="isAuthenticated()" [routerLink]="[routerLink]">{{ 'GENERAL.ACTIONS.VIEW-ALL' | translate}}</a>
<a *ngIf="!routerLink" class="view-all-hidden" [class.clickable]="isAuthenticated()">{{ 'GENERAL.ACTIONS.VIEW-ALL' | translate}}</a>
</div>
</div>
</div>

View File

@ -1,55 +0,0 @@
import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core";
import { Router } from "@angular/router";
import { AuthService } from "../../../core/services/auth/auth.service";
// declare interface RouteInfo {
// path: string;
// title: string;
// subtitle: string;
// icon: string;
// }
// export const INFO_COUNTER_ROUTES: RouteInfo[] = [
// { path: '', title: 'DATA MANAGEMENT PLANS', subtitle: '4', icon: 'view_agenda' },
// { path: '', title: 'RELATED DATA DESCRIPTIONS', subtitle: '20', icon: 'library_books' },
// { path: '', title: 'RELATED GRANTS', subtitle: '4', icon: 'work_outline' },
// { path: '', title: 'ORGANIZATIONS', subtitle: '20', icon: 'scatter_plot' }
// ];
@Component({
selector: "app-info-counter",
templateUrl: "./info-counter.component.html",
styleUrls: ["./info-counter.component.css"]
})
export class InfoCounterComponent implements OnInit {
@Input() title: string;
@Input() subtitle: string;
@Input() icon: string;
@Input() routerLink: string;
@Input() buttonRedirectLink: string;
@Output() onClick: EventEmitter<void> = new EventEmitter<void>();
infoCounterItems: any[];
constructor(private router: Router, private authService: AuthService) {}
ngOnInit() {
// this.infoCounterItems = INFO_COUNTER_ROUTES.filter(infoCounterItem => infoCounterItem);
}
navigateToUrl() {
if (!this.isAuthenticated()) { return; }
this.router.navigate([this.routerLink]);
}
createNew() {
this.router.navigate([this.buttonRedirectLink]);
}
isAuthenticated() {
return this.authService.currentAccountIsAuthenticated();
}
viewAllClicked() {
this.onClick.emit();
}
}

View File

@ -1,21 +0,0 @@
<div class="row">
<div class="col-2"></div>
<div class="col-8 ">
<div class="row conteiner">
<div class="col">
<button mat-button class="buttonNav navbar-button figure-card card" routerLink="/quick-wizard">
<h3 class="title">{{'QUICKWIZARD.CREATE-ADD.CREATE.TITLE' | translate}}</h3>
</button>
</div>
<div class="col-auto">
<div class="vl"></div>
</div>
<div class="col">
<button mat-button class="buttonNav navbar-button figure-card card" routerLink="/datasetcreatewizard">
<h3 class="title">{{'QUICKWIZARD.CREATE-ADD.ADD.TITLE' | translate}}</h3>
</button>
</div>
</div>
</div>
<div class="com-2"></div>
</div>

View File

@ -1,33 +0,0 @@
.figure-card {
display: inline-block;
position: relative;
width: 100%;
margin: 25px 0;
}
.card {
padding: 25px 20px 20px 20px;
display: flex;
flex-direction: column;
align-items: center;
}
.card {
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.14);
border-radius: 6px;
color: rgba(0, 0, 0, 0.87);
background: #fff;
}
.vl {
border-left: solid #999;
height: 100%;
}
a {
text-decoration: none;
}
.conteiner{
padding: 1em;
background-color: #eef1f5;
}

View File

@ -1,38 +0,0 @@
import { Component, OnInit } from "@angular/core";
import { MatSnackBar } from "@angular/material/snack-bar";
import { ActivatedRoute, Router } from "@angular/router";
import { BaseComponent } from '@common/base/base.component';
import { TranslateService } from "@ngx-translate/core";
@Component({
selector: 'app-quick-wizard-create-add-component',
templateUrl: 'quick-wizard-create-add.component.html',
styleUrls: ['./quick-wizard-create-add.component.scss']
})
export class QuickWizardCreateAdd extends BaseComponent implements OnInit {
constructor(
private router: Router,
private languageService: TranslateService,
public snackBar: MatSnackBar,
public route: ActivatedRoute
) {
super();
}
ngOnInit(): void {
}
navigateToCreate() {
this.router.navigate(["/quick-wizard"]);
}
navigateToAdd() {
this.router.navigate(["/datasetcreatewizard"]);
}
}

View File

@ -1,67 +0,0 @@
<div class="container row">
<div class="col-md-3">
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>
{{'RECENT-ACTIVITY.MY-TITLE-DMP' | translate}}
</mat-card-title>
</mat-card-header>
<mat-card-content>
<mat-nav-list *ngIf="dmpActivities != null">
<mat-list-item (click)="redirect(activity.id, recentActivityTypeEnum.Dmp)" *ngFor="let activity of dmpActivities">
<p mat-line>
{{activity.label}}
</p>
<p mat-line>
{{activity.timestamp | date:'shortDate'}}
</p>
</mat-list-item>
</mat-nav-list>
</mat-card-content>
</mat-card>
</div>
<div class="col-md-3">
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>
{{'RECENT-ACTIVITY.MY-TITLE-GRANT' | translate}}
</mat-card-title>
</mat-card-header>
<mat-card-content>
<mat-nav-list *ngIf="grantActivities!=null">
<mat-list-item (click)="redirect(activity.id, recentActivityTypeEnum.Grant)" *ngFor="let activity of grantActivities">
<p mat-line>
{{activity.label}}
</p>
<p mat-line>
{{activity.timestamp | date:'shortDate'}}
</p>
</mat-list-item>
</mat-nav-list>
</mat-card-content>
</mat-card>
</div>
<div class="col-md-3">
<mat-card class="example-card">
<mat-card-header>
<mat-card-title>
{{'RECENT-ACTIVITY.MY-TITLE-DATASET' | translate}}
</mat-card-title>
</mat-card-header>
<mat-card-content>
<mat-nav-list *ngIf="datasetActivities!=null">
<mat-list-item (click)="redirect(activity.id, recentActivityTypeEnum.Dataset)" *ngFor="let activity of datasetActivities">
<p mat-line>
{{activity.label}}
</p>
<p mat-line>
{{activity.timestamp | date:'shortDate'}}
</p>
</mat-list-item>
</mat-nav-list>
</mat-card-content>
</mat-card>
</div>
</div>

View File

@ -1,53 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { RecentActivityType } from '@app/core/common/enum/recent-activity-type';
import { UserServiceOld } from '@app/core/services/user/user.service-old';
import { BaseComponent } from '@common/base/base.component';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-recent-activity',
templateUrl: './recent-activity.component.html',
styleUrls: ['./recent-activity.component.scss']
})
export class RecentActivityComponent extends BaseComponent implements OnInit {
datasetActivities: any[];
grantActivities: any[];
dmpActivities: any[];
recentActivityTypeEnum = RecentActivityType;
constructor(
private router: Router,
private userService: UserServiceOld
) { super(); }
ngOnInit() {
this.userService.getRecentActivity()
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
this.datasetActivities = response['recentDatasetActivities'];
this.dmpActivities = response['recentDmpActivities'];
this.grantActivities = response['recentGrantActivities'];
});
}
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/edit/' + id]);
return;
}
default: throw new Error('Unsupported Activity Type ');
}
}
}

View File

@ -1,7 +1,7 @@
<div class="col-md-12 d-flex justify-content-center" *ngIf="allRecentActivities == null">
<div class="col-md-12 d-flex justify-content-center" *ngIf="listingItems == null">
<span class="empty-list">{{'DMP-LISTING.EMPTY-LIST' | translate}}</span>
</div>
<div *ngIf="allRecentActivities != null" id="results" #results>
<div *ngIf="listingItems != null" id="results" #results>
<div class="d-flex flex-direction-row pt-4">
<!-- Sort by -->
<span class="d-flex align-items-center">{{'DMP-LISTING.SORT-BY' | translate}}:</span>
@ -11,7 +11,6 @@
<mat-option *ngIf="publicMode" [value]="order.PUBLISHED">{{enumUtils.toRecentActivityOrderString(order.PUBLISHED)}}</mat-option>
<mat-option [value]="order.LABEL">{{enumUtils.toRecentActivityOrderString(order.LABEL)}}</mat-option>
<mat-option *ngIf="!publicMode" [value]="order.STATUS">{{enumUtils.toRecentActivityOrderString(order.STATUS)}}</mat-option>
<!-- <mat-option [value]="order.CREATED">{{enumUtils.toRecentActivityOrderString(order.CREATED)}}</mat-option> -->
</mat-select>
</mat-form-field>
<!-- End of Sort by -->
@ -26,143 +25,9 @@
<div *ngIf="allRecentActivities && allRecentActivities.length > 0 && page > 1" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadNextOrPrevious(false)">{{'GENERAL.ACTIONS.LOAD-LESS' | translate}}</button>
</div>
<div *ngFor="let activity of allRecentActivities">
<div *ngIf="activity && activity.type === recentActivityTypeEnum.Dmp.valueOf()">
<div class="dmp-card">
<!-- <a (click)="redirect(activity.id, activity.type)" class="pointer"> -->
<a [routerLink]="navigateToUrl(activity.id, activity.type)" class="pointer">
<div class="d-flex flex-direction-row">
<div class="col-auto dmp-label">{{ 'DMP-LISTING.DMP' | translate }}</div>
<div *ngIf="!publicMode" class="col-auto ml-auto edited-date">{{ 'DMP-LISTING.EDITED' | translate }}: {{ activity.modified | dateTimeCultureFormatter: "d MMMM y" }}</div>
<div *ngIf="publicMode" class="col-auto ml-auto edited-date">{{ 'DMP-LISTING.PUBLISHED' | translate }}: {{ activity.publishedAt | dateTimeCultureFormatter: "d MMMM y" }}</div>
</div>
<div class="col-auto" [ngClass]="{'dmp-title': activity.status === 1, 'dmp-title-draft': activity.status === 0}">{{activity.title}}</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-DESCRIPTIONS' | translate}}: ({{ getDatasets(activity).length }})
</div>
<div *ngFor="let dataset of getDatasets(activity); 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 && 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="getDatasets(activity).length > 3" (click)="redirect(activity.id, activity.type)"><u>{{'GENERAL.ACTIONS.SHOW-MORE' | translate}}</u></a> -->
<a class="d-flex justify-content-center pb-3 show-more" *ngIf="getDatasets(activity).length > 3" [routerLink]="navigateToUrl(activity.id, activity.type)"><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" *ngIf="isDraftDmp(activity)" [routerLink]="['/plans/edit/' + activity.id]" target="_blank"><span class="material-icons icon-align">add</span>{{'DMP-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isUserOwner(activity)" (click)="openShareDialog(activity.id, activity.title)"><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" *ngIf="isAuthenticated()" (click)="cloneOrNewVersionClicked(activity, false)"><span class="material-icons icon-align pr-2">filter_none</span>{{'DMP-LISTING.ACTIONS.CLONE' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="!isAuthenticated()" (click)="viewVersions(getGroupId(activity), activity.title, activity)"><span class="material-icons icon-align pr-2">library_books</span>{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="!isDraftDmp(activity) && isUserOwner(activity)" (click)="deleteDmpClicked(activity)"><span class="material-icons icon-align pr-2">delete</span>{{ 'DMP-LISTING.ACTIONS.DELETE' | translate }}</a>
<a class="col-auto pointer" *ngIf="isAuthenticated()" [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)="cloneOrNewVersionClicked(activity, true)">
<mat-icon>queue</mat-icon>{{'DMP-LISTING.ACTIONS.NEW-VERSION' | translate}}
</button>
<button mat-menu-item (click)="viewVersions(getGroupId(activity), activity.title, activity)">
<mat-icon>library_books</mat-icon>{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}}
</button>
<button mat-menu-item *ngIf="isDraftDmp(activity) && isUserOwner(activity)" (click)="deleteDmpClicked(activity)" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'DMP-LISTING.ACTIONS.DELETE' | translate }}
</button>
</mat-menu>
</div>
</div>
<div *ngIf="activity && activity.type === recentActivityTypeEnum.Dataset.valueOf()">
<div class="dataset-card">
<!-- <a (click)="redirect(activity.id, activity.type)" class="pointer"> -->
<a [routerLink]="navigateToUrl(activity.id, activity.type)" class="pointer">
<div class="d-flex flex-direction-row">
<div class="col-auto dataset-label">{{'DATASET-LISTING.DESCRIPTION' | translate}}</div>
<div *ngIf="!publicMode" class="col-auto ml-auto edited-date">{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{activity.modified | dateTimeCultureFormatter: "d MMMM y"}}</div>
<div *ngIf="publicMode" class="col-auto ml-auto edited-date">{{'DATASET-LISTING.STATES.PUBLISHED' | translate}}: {{activity.publishedAt | dateTimeCultureFormatter: "d MMMM y"}}</div>
</div>
<div *ngIf="activity.status === 1" class="col-auto dataset-title">{{activity.title}}</div>
<div *ngIf="activity.status === 0" class="col-auto dataset-title-draft">{{activity.title}}</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 pr-0">{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}}
<div class="col-auto dmp-label ml-3">{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}</div>
</div>
<!-- <div class="col-auto dmp-label">{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}</div> -->
<div class="col dmp-title">{{ getDmp(activity) }}</div>
</div>
</a>
<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" *ngIf="isAuthenticated()" (click)="openShareDialog(getDmpId(activity), getDmp(activity))"><span class="material-icons icon-align pr-2">group_add</span>{{'DATASET-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" (click)="openDmpSearchDialogue(activity)"><span class="material-icons icon-align pr-2">file_copy</span>{{'DATASET-WIZARD.ACTIONS.COPY-DESCRIPTION' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" (click)="deleteDatasetClicked(activity.id)"><span class="material-icons icon-align pr-2">delete</span>{{ 'DATASET-WIZARD.ACTIONS.DELETE' | 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)" class="menu-item">
<mat-icon>file_copy</mat-icon>{{'DATASET-WIZARD.ACTIONS.COPY-DESCRIPTION' | translate}}
</button>
<button mat-menu-item (click)="deleteDatasetClicked(activity.id)" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'DATASET-WIZARD.ACTIONS.DELETE' | 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 *ngFor="let item of listingItems; let i = index">
<app-dmp-listing-item-component *ngIf="item.dmp" [showDivider]="i != (listingItems.length - 1)" [dmp]="item.dmp" [isPublic]="isPublic"></app-dmp-listing-item-component>
<app-description-listing-item-component *ngIf="item.description" [showDivider]="i != (listingItems.length - 1)" [description]="item.description" [isPublic]="isPublic" ></app-description-listing-item-component>
</div>
<div class="text-muted d-flex justify-content-center mt-5" *ngIf="!hasMoreActivity && allRecentActivities && allRecentActivities.length > 0">
{{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}}
@ -171,108 +36,3 @@
<button type="button" class="btn-load-more" (click)="loadNextOrPrevious()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</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

@ -1,93 +0,0 @@
<div *ngIf="datasetActivities != null" id="datasets" #datasets>
<div class="d-flex flex-direction-row pt-4">
<!-- Sort by -->
<span class="d-flex align-items-center">{{'DMP-LISTING.SORT-BY' | translate}}:</span>
<mat-form-field appearance="outline" class="sort-form col-auto">
<mat-select placeholder="{{'CRITERIA.LIKE'| translate}}" [formControl]="formGroup.get('order')">
<mat-option *ngIf="!publicMode" [value]="order.MODIFIED">{{enumUtils.toRecentActivityOrderString(order.MODIFIED)}}</mat-option>
<mat-option *ngIf="publicMode" [value]="order.DATASETPUBLISHED">{{enumUtils.toRecentActivityOrderString(order.DATASETPUBLISHED)}}</mat-option>
<mat-option [value]="order.LABEL">{{enumUtils.toRecentActivityOrderString(order.LABEL)}}</mat-option>
<mat-option *ngIf="!publicMode" [value]="order.STATUS">{{enumUtils.toRecentActivityOrderString(order.STATUS)}}</mat-option>
<!-- <mat-option [value]="order.CREATED">{{enumUtils.toRecentActivityOrderString(order.CREATED)}}</mat-option> -->
</mat-select>
</mat-form-field>
<!-- End of Sort by -->
<!-- Search Filter-->
<mat-form-field appearance="outline" class="search-form ml-auto col-auto pr-0" floatLabel="never">
<mat-icon matSuffix>search</mat-icon>
<input matInput placeholder="{{'CRITERIA.DATA-SETS.LIKE'| translate}}" name="likeCriteria" [formControl]="formGroup.get('like')">
<mat-error *ngIf="formGroup.get('like').hasError('backendError')">{{formGroup.get('like').getError('backendError').message}}</mat-error>
</mat-form-field>
<!-- End of Search Filter -->
</div>
<div *ngIf="datasetActivities && datasetActivities.length > 0 && page > 1" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadNextOrPrevious(false)">{{'GENERAL.ACTIONS.LOAD-LESS' | translate}}</button>
</div>
<div *ngFor="let activity of datasetActivities">
<div class="dataset-card">
<a [routerLink]="goToOverview(activity.id)" class="pointer">
<div class="d-flex flex-direction-row">
<div class="col-auto dataset-label">{{'DATASET-LISTING.DESCRIPTION' | translate}}</div>
<div *ngIf="!publicMode" class="col-auto ml-auto edited-date">{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{activity.modified | dateTimeCultureFormatter: "d MMMM y"}}</div>
<div *ngIf="publicMode" class="col-auto ml-auto edited-date">{{'DATASET-LISTING.STATES.PUBLISHED' | translate}}: {{activity.dmpPublishedAt | dateTimeCultureFormatter: "d MMMM y"}}</div>
</div>
<div *ngIf="activity.status === 1" class="col-auto dataset-title">{{activity.label}}</div>
<div *ngIf="activity.status === 0" class="col-auto dataset-title-draft">{{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 pr-0">{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}}
<div class="col-auto dmp-label ml-3">{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}</div>
</div>
<!-- <div class="col-auto dmp-label">{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}</div> -->
<div class="col dmp-title">{{activity.dmp}}</div>
</div>
</a>
<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" *ngIf="isUserOwner(activity)" (click)="openShareDialog(activity.dmpId, activity.dmp)"><span class="material-icons icon-align pr-2">group_add</span>{{'DATASET-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" (click)="openDmpSearchDialogue(activity)"><span class="material-icons icon-align pr-2">file_copy</span>{{'DATASET-WIZARD.ACTIONS.COPY-DESCRIPTION' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" (click)="deleteClicked(activity.id)"><span class="material-icons icon-align pr-2">delete</span>{{ 'DATASET-WIZARD.ACTIONS.DELETE' | translate }}</a>
<!-- <a *ngIf="this.isAuthenticated()" 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 *ngIf="isAuthenticated()" (click)="openDmpSearchDialogue(activity)" class="menu-item">
<mat-icon>file_copy</mat-icon>{{'DATASET-WIZARD.ACTIONS.COPY-DESCRIPTION' | translate}}
</button>
<button mat-menu-item (click)="deleteClicked(activity.id)" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'DATASET-WIZARD.ACTIONS.DELETE' | 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="text-muted d-flex justify-content-center mt-5" *ngIf="!hasMoreResults && datasetActivities && datasetActivities.length > 0">
{{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}}
</div>
<div *ngIf="datasetActivities && datasetActivities.length > 0 && datasetActivities.length >= pageSize && hasMoreResults" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadNextOrPrevious()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
</div>

View File

@ -1,518 +0,0 @@
import { Location } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { DatasetStatus } from '@app/core/common/enum/dataset-status';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { Role } from '@app/core/common/enum/role';
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
import { DatasetListingModel } from '@app/core/model/dataset/dataset-listing';
import { DatasetCriteria } from '@app/core/query/dataset/dataset-criteria';
import { AuthService } from '@app/core/services/auth/auth.service';
import { ConfigurationService } from "@app/core/services/configuration/configuration.service";
import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service';
import { DatasetService } from '@app/core/services/dataset/dataset.service';
import { LockService } from '@app/core/services/lock/lock.service';
import { MatomoService } from '@app/core/services/matomo/matomo-service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
import { DatasetCopyDialogueComponent } from '@app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component';
import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dmp-invitation-dialog.component';
import { BaseComponent } from '@common/base/base.component';
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import { TranslateService } from '@ngx-translate/core';
import * as FileSaver from 'file-saver';
import { debounceTime, takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-recent-edited-dataset-activity',
templateUrl: './recent-edited-dataset-activity.component.html',
styleUrls: ['./recent-edited-dataset-activity.component.scss']
})
export class RecentEditedDatasetActivityComponent extends BaseComponent implements OnInit {
@Output() totalCountDatasets: EventEmitter<any> = new EventEmitter();
@ViewChild("datasets") resultsContainer;
datasetActivities: DatasetListingModel[];
totalCount: number;
startIndex: number = 0;
offsetLess: number = 0;
hasMoreResults: boolean = true;
pageSize: number = 5;
public formGroup = new UntypedFormBuilder().group({
like: new UntypedFormControl(),
order: new UntypedFormControl()
});
publicMode = false;
order = RecentActivityOrder;
page: number = 1;
@Input() isActive: boolean = false;
constructor(
private route: ActivatedRoute,
private authentication: AuthService,
private datasetService: DatasetService,
private language: TranslateService,
public enumUtils: EnumUtils,
public dialog: MatDialog,
public router: Router,
private datasetWizardService: DatasetWizardService,
private uiNotificationService: UiNotificationService,
private location: Location,
private lockService: LockService,
private httpClient: HttpClient,
private matomoService: MatomoService,
private configurationService: ConfigurationService,
private fileUtils: FileUtils
) {
super();
}
ngOnInit() {
this.matomoService.trackPageView('Recent Dataset Activity');
this.route.queryParams.subscribe(params => {
if (this.isActive) {
let page = (params['page'] === undefined) ? 1 : +params['page'];
this.page = (page <= 0) ? 1 : page;
this.startIndex = (this.page - 1) * this.pageSize;
if (this.page > 1) {
this.offsetLess = (this.page - 2) * this.pageSize;
}
let order = params['order'];
if (this.isAuthenticated()) {
if (order === undefined || (order != this.order.MODIFIED && order != this.order.LABEL && order != this.order.STATUS)) {
order = this.order.MODIFIED;
}
} else {
if (order === undefined || (order != this.order.DATASETPUBLISHED && order != this.order.LABEL)) {
order = this.order.DATASETPUBLISHED;
}
}
this.formGroup.get('order').setValue(order);
let keyword = (params['keyword'] === undefined || params['keyword'].length <= 0) ? "" : params['keyword'];
this.formGroup.get("like").setValue(keyword);
this.updateUrl();
}
});
if (this.isAuthenticated()) {
// const fields: Array<string> = ["-modified"];
if (!this.formGroup.get('order').value) {
this.formGroup.get('order').setValue(this.order.MODIFIED);
}
const fields: Array<string> = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value];
const datasetDataTableRequest: DataTableRequest<DatasetCriteria> = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields });
datasetDataTableRequest.criteria = new DatasetCriteria();
datasetDataTableRequest.criteria.like = this.formGroup.get('like').value;
this.datasetService
.getPaged(datasetDataTableRequest)
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
this.datasetActivities = response.data;
this.totalCount = response.totalCount;
this.totalCountDatasets.emit(this.datasetActivities.length)
if (this.totalCount > 0 && this.totalCount <= (this.page - 1) * this.pageSize && this.page > 1) {
let queryParams = { type: "datasets", page: 1, order: this.formGroup.get("order").value };
if (this.formGroup.get("like").value) {
queryParams['keyword'] = this.formGroup.get("like").value;
}
this.router.navigate(["/home"], { queryParams: queryParams })
}
});
this.formGroup.get('like').valueChanges
.pipe(takeUntil(this._destroyed), debounceTime(500))
.subscribe(x => this.refresh());
this.formGroup.get('order').valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => this.refresh());
} else {
this.publicMode = true;
if (!this.formGroup.get('order').value) {
this.formGroup.get('order').setValue(this.order.DATASETPUBLISHED);
}
const dataTableRequest = this.setPublicDataTableRequest();
this.datasetService.getPaged(dataTableRequest).pipe(takeUntil(this._destroyed)).subscribe(response => {
this.datasetActivities = response.data;
this.totalCount = response.totalCount;
this.totalCountDatasets.emit(this.datasetActivities.length);
if (this.totalCount > 0 && this.totalCount <= (this.page - 1) * this.pageSize && this.page > 1) {
let queryParams = { type: "datasets", page: 1, order: this.formGroup.get("order").value };
if (this.formGroup.get("like").value) {
queryParams['keyword'] = this.formGroup.get("like").value;
}
this.router.navigate(["/home"], { queryParams: queryParams })
}
});
this.formGroup.get('like').valueChanges
.pipe(takeUntil(this._destroyed), debounceTime(500))
.subscribe(x => this.refresh());
this.formGroup.get('order').valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => this.refresh());
}
}
ngOnChanges() {
if (this.isActive) {
this.updateUrl();
}
}
updateUrl() {
let parameters = "?type=datasets" +
(this.page != 1 ? "&page=" + this.page : "") +
(((this.formGroup.get("order").value != this.order.MODIFIED && !this.publicMode) || (this.formGroup.get("order").value != this.order.DATASETPUBLISHED && this.publicMode)) ? "&order=" + this.formGroup.get("order").value : "") +
(this.formGroup.get("like").value ? ("&keyword=" + this.formGroup.get("like").value) : "");
this.location.go(this.router.url.split('?')[0] + parameters);
}
setPublicDataTableRequest(fields?: Array<string>, more: boolean = true): DataTableRequest<DatasetCriteria> {
const datasetCriteria = new DatasetCriteria();
datasetCriteria.allVersions = false;
datasetCriteria.isPublic = true;
datasetCriteria.like = this.formGroup.get("like").value ? this.formGroup.get("like").value : "";
if (!fields) {
fields = new Array<string>('-dmp:publishedAt|join|');
}
const dataTableRequest: DataTableRequest<DatasetCriteria> = more ? new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }) : new DataTableRequest(this.offsetLess, this.pageSize, { fields: fields });
dataTableRequest.criteria = datasetCriteria;
return dataTableRequest;
}
refresh(): void {
this.startIndex = 0;
this.page = 1;
this.updateUrl();
const fields: Array<string> = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value];
const datasetDataTableRequest = this.isAuthenticated() ? new DataTableRequest<DatasetCriteria>(this.startIndex, this.pageSize, { fields: fields }) : this.setPublicDataTableRequest(fields);
if (this.isAuthenticated()) {
datasetDataTableRequest.criteria = new DatasetCriteria();
datasetDataTableRequest.criteria.like = this.formGroup.get("like").value ? this.formGroup.get("like").value : "";
}
this.datasetService
.getPaged(datasetDataTableRequest)
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
this.datasetActivities = response.data;
this.totalCount = response.totalCount;
this.totalCountDatasets.emit(this.datasetActivities.length);
if (response.data.length < this.pageSize) {
this.hasMoreResults = false;
} else {
this.hasMoreResults = true;
}
});
}
public loadNextOrPrevious(more: boolean = true) {
this.startIndex = this.startIndex + this.pageSize;
const fields: Array<string> = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value];
let request;
this.startIndex = (this.page) * this.pageSize;
if (this.page > 1) {
this.offsetLess = (this.page - 2) * this.pageSize;
}
if (this.isAuthenticated()) {
if (more) {
request = new DataTableRequest<DatasetCriteria>(this.startIndex, this.pageSize, { fields: fields });
} else {
request = new DataTableRequest<DatasetCriteria>(this.offsetLess, this.pageSize, { fields: fields });
}
} else {
request = this.setPublicDataTableRequest(fields, more);
}
if (this.isAuthenticated()) {
request.criteria = new DatasetCriteria();
request.criteria.like = this.formGroup.get("like").value ? this.formGroup.get("like").value : "";
}
this.datasetService.getPaged(request).pipe(takeUntil(this._destroyed)).subscribe(result => {
if (!result || !result.data || result.data.length == 0) {
this.hasMoreResults = false;
// return [];
} else {
this.page = this.page + (more ? 1 : -1);
this.updateUrl();
// this.datasetActivities = this.datasetActivities.concat(result.data);
// this.datasetActivities = this.datasetActivities.length > 0 ? this.mergeTwoSortedLists(this.datasetActivities, result.data, this.formGroup.get('order').value) : result.data;
this.datasetActivities = result.data;
if (result.data.length < this.pageSize) {
this.hasMoreResults = false;
} else {
this.hasMoreResults = true;
}
this.totalCountDatasets.emit(this.datasetActivities.length);
if (more) {
this.resultsContainer.nativeElement.scrollIntoView();
}
}
});
}
public isAuthenticated(): boolean {
return this.authentication.currentAccountIsAuthenticated();
}
isUserOwner(activity: DatasetListingModel): boolean {
const principalId: string = this.authentication.userId()?.toString();
if (principalId) return !!activity.users.find(x => (x.role === Role.Owner) && (principalId === x.id));
}
goToOverview(id: string): string[] {
if (this.isAuthenticated()) {
return ['../datasets/overview/' + id];
} else {
return ['../explore/publicOverview', id];
}
}
roleDisplay(value: any) {
const principalId: string = this.authentication.userId()?.toString();
let role: number;
if (principalId) {
value.forEach(element => {
if (principalId === 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 UntypedFormControl();
const dialogRef = this.dialog.open(DatasetCopyDialogueComponent, {
width: '500px',
restoreFocus: false,
data: {
formControl: formControl,
datasetId: dataset.id,
datasetProfileId: dataset.profile.id,
datasetProfileExist: false,
confirmButton: this.language.instant('DATASET-WIZARD.DIALOGUE.COPY'),
cancelButton: this.language.instant('DATASET-WIZARD.DIALOGUE.CANCEL')
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed))
.subscribe(result => {
if (result && result.datasetProfileExist) {
const newDmpId = result.formControl.value.id;
this.router.navigate(['/datasets/copy/' + result.datasetId], { queryParams: { newDmpId: newDmpId } });
// let url = this.router.createUrlTree(['/datasets/copy/', result.datasetId, { newDmpId: newDmpId }]);
// window.open(url.toString(), '_blank');
}
});
}
deleteClicked(id: string) {
this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed))
.subscribe(lockStatus => {
if (!lockStatus) {
this.openDeleteDialog(id);
} else {
this.openLockedByUserDialog();
}
});
}
openDeleteDialog(id: string): void {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
maxWidth: '300px',
restoreFocus: false,
data: {
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'),
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
isDeleteConfirmation: true
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
this.datasetWizardService.delete(id)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onDeleteCallbackSuccess(),
error => this.onDeleteCallbackError(error)
);
}
});
}
openLockedByUserDialog() {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
maxWidth: '400px',
restoreFocus: false,
data: {
message: this.language.instant('DATASET-WIZARD.ACTIONS.LOCK')
}
});
}
openShareDialog(dmpRowId: any, dmpRowName: any, activity: any) {
const dialogRef = this.dialog.open(DmpInvitationDialogComponent, {
// height: '250px',
// width: '700px',
autoFocus: false,
restoreFocus: false,
data: {
dmpId: dmpRowId,
dmpName: dmpRowName
}
});
}
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.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.matomoService.trackDownload('datasets', "pdf", dataset.id);
});
}
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.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.matomoService.trackDownload('datasets', "docx", dataset.id);
});
}
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.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.matomoService.trackDownload('datasets', "xml", dataset.id);
});
}
onCallbackSuccess(id?: String): void {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
id ? this.router.navigate(['/reload']).then(() => { this.router.navigate(['/datasets', 'edit', id]); }) : this.router.navigate(['/datasets']);
}
onCallbackError(error: any) {
this.setErrorModel(error.error);
}
reloadPage(): void {
const path = this.location.path();
this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => {
this.router.navigate([path]);
});
}
onDeleteCallbackSuccess(): void {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success);
this.reloadPage();
}
onDeleteCallbackError(error) {
this.uiNotificationService.snackBarNotification(error.error.message ? this.language.instant(error.error.message) : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error);
}
public setErrorModel(validationErrorModel: ValidationErrorModel) {
}
needsUpdate(activity: DatasetListingModel) {
if (activity.isProfileLatestVersion || (activity.status === DatasetStatus.Finalized)
|| (activity.isProfileLatestVersion == undefined && activity.status == undefined)) {
return false;
}
else {
return true;
}
}
private mergeTwoSortedLists(arr1: DatasetListingModel[], arr2: DatasetListingModel[], order: string): DatasetListingModel[] {
let merged = [];
let index1 = 0;
let index2 = 0;
let current = 0;
while (current < (arr1.length + arr2.length)) {
let isArr1Depleted = index1 >= arr1.length;
let isArr2Depleted = index2 >= arr2.length;
if (order === 'modified') {
if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].modified) > new Date(arr2[index2].modified)))) {
merged[current] = arr1[index1];
index1++;
} else {
merged[current] = arr2[index2];
index2++;
}
} else if (order === 'created') {
if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].created) > new Date(arr2[index2].created)))) {
merged[current] = arr1[index1];
index1++;
} else {
merged[current] = arr2[index2];
index2++;
}
} else if (order === 'label') {
if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].label.localeCompare(arr2[index2].label)))) {
merged[current] = arr1[index1];
index1++;
} else {
merged[current] = arr2[index2];
index2++;
}
} else if (order === 'status') {
if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].status < arr2[index2].status))) {
merged[current] = arr1[index1];
index1++;
} else {
merged[current] = arr2[index2];
index2++;
}
} else if (order === 'dmp:publishedAt|join|') {
if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].dmpPublishedAt) > new Date(arr2[index2].dmpPublishedAt)))) {
merged[current] = arr1[index1];
index1++;
} else {
merged[current] = arr2[index2];
index2++;
}
}
current++;
}
return merged;
}
}

View File

@ -0,0 +1,35 @@
<div *ngIf="listingItems != null" id="descriptions" #descriptions>
<div class="d-flex flex-direction-row pt-4">
<!-- Sort by -->
<span class="d-flex align-items-center">{{'DMP-LISTING.SORT-BY' | translate}}:</span>
<mat-form-field appearance="outline" class="sort-form col-auto">
<mat-select placeholder="{{'CRITERIA.LIKE'| translate}}" [formControl]="formGroup.get('order')">
<mat-option *ngIf="!publicMode" [value]="order.MODIFIED">{{enumUtils.toRecentActivityOrderString(order.MODIFIED)}}</mat-option>
<mat-option *ngIf="publicMode" [value]="order.DATASETPUBLISHED">{{enumUtils.toRecentActivityOrderString(order.DATASETPUBLISHED)}}</mat-option>
<mat-option [value]="order.LABEL">{{enumUtils.toRecentActivityOrderString(order.LABEL)}}</mat-option>
<mat-option *ngIf="!publicMode" [value]="order.STATUS">{{enumUtils.toRecentActivityOrderString(order.STATUS)}}</mat-option>
<!-- <mat-option [value]="order.CREATED">{{enumUtils.toRecentActivityOrderString(order.CREATED)}}</mat-option> -->
</mat-select>
</mat-form-field>
<!-- End of Sort by -->
<!-- Search Filter-->
<mat-form-field appearance="outline" class="search-form ml-auto col-auto pr-0" floatLabel="never">
<mat-icon matSuffix>search</mat-icon>
<input matInput placeholder="{{'CRITERIA.DATA-SETS.LIKE'| translate}}" name="likeCriteria" [formControl]="formGroup.get('like')">
<mat-error *ngIf="formGroup.get('like').hasError('backendError')">{{formGroup.get('like').getError('backendError').message}}</mat-error>
</mat-form-field>
<!-- End of Search Filter -->
</div>
<div *ngIf="listingItems && listingItems.length > 0 && page > 1" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadNextOrPrevious(false)">{{'GENERAL.ACTIONS.LOAD-LESS' | translate}}</button>
</div>
<div *ngFor="let item of listingItems; let i = index">
<app-description-listing-item-component [showDivider]="i != (listingItems.length - 1)" [description]="item" [isPublic]="isPublic" ></app-description-listing-item-component>
</div>
<div class="text-muted d-flex justify-content-center mt-5" *ngIf="!hasMoreResults && listingItems && listingItems.length > 0">
{{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}}
</div>
<div *ngIf="listingItems && listingItems.length > 0 && listingItems.length >= pageSize && hasMoreResults" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadNextOrPrevious()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
</div>

View File

@ -10,7 +10,7 @@
}
.dmp-card,
.dataset-card {
.description-card {
min-width: 712px;
/* min-height: 308px; */
background: #ffffff 0% 0% no-repeat padding-box;
@ -56,7 +56,7 @@ input[type="text"] {
line-height: 2.4;
}
.dataset-label {
.description-label {
width: auto;
height: 37px;
background: var(--secondary-color) 0% 0% no-repeat padding-box;
@ -70,7 +70,7 @@ input[type="text"] {
}
.dmp-title,
.dataset-title {
.description-title {
text-align: left;
font-weight: 600;
font-family: "Roboto", sans-serif;
@ -81,7 +81,7 @@ input[type="text"] {
color: #212121;
}
.dataset-subtitle,
.description-subtitle,
.dmp-subtitle {
display: flex;
flex-direction: row;
@ -95,7 +95,7 @@ input[type="text"] {
}
.dmp-title-draft,
.dataset-title-draft {
.description-title-draft {
text-align: left;
font-weight: 600;
font-family: "Roboto", sans-serif;
@ -114,7 +114,7 @@ input[type="text"] {
}
.dmp-subtitle,
.dataset-subtitle {
.description-subtitle {
.icon-align {
display: inline-flex;
@ -124,7 +124,7 @@ input[type="text"] {
}
}
.dataset-card-actions,
.description-card-actions,
.dmp-card-actions {
display: flex;
flex-direction: row;
@ -133,25 +133,25 @@ input[type="text"] {
color: #848484;
}
.dataset-card-actions a,
.description-card-actions a,
.dmp-card-actions a {
color: #848484 !important;
text-decoration: none !important;
}
.dataset-card-actions a:hover,
.description-card-actions a:hover,
.dmp-card-actions a:hover {
color: var(--primary-color) !important;
}
.dmp-dataset-descriptions-title {
.dmp-description-descriptions-title {
color: #000000;
opacity: 0.6;
padding-top: 1.5rem;
padding-bottom: 0.8rem;
}
.dmp-dataset-descriptions-name {
.dmp-description-descriptions-name {
color: #000000;
opacity: 0.6;
font-weight: 700;

View File

@ -0,0 +1,174 @@
import { Location } from '@angular/common';
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { Description } from '@app/core/model/description/description';
import { Dmp, DmpUser } from '@app/core/model/dmp/dmp';
import { DmpReference, Reference } from '@app/core/model/reference/reference';
import { DescriptionLookup } from '@app/core/query/description.lookup';
import { AuthService } from '@app/core/services/auth/auth.service';
import { DescriptionService } from '@app/core/services/description/description.service';
import { MatomoService } from '@app/core/services/matomo/matomo-service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { BaseComponent } from '@common/base/base.component';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
@Component({
selector: 'app-recent-edited-description-activity',
templateUrl: './recent-edited-description-activity.component.html',
styleUrls: ['./recent-edited-description-activity.component.scss']
})
export class RecentEditedDescriptionActivityComponent extends BaseComponent implements OnInit {
lookup: DescriptionLookup = new DescriptionLookup();
pageSize: number = 5;
listingItems: Description[];
public formGroup = new UntypedFormBuilder().group({
like: new UntypedFormControl(),
order: new UntypedFormControl()
});
publicMode = false;
order = RecentActivityOrder;
totalCount: number;
startIndex: number = 0;
offsetLess: number = 0;
page: number = 1;
@Input() isActive: boolean = false;
constructor(
private route: ActivatedRoute,
private router: Router,
public enumUtils: EnumUtils,
private authentication: AuthService,
private descriptionService: DescriptionService,
private location: Location,
private matomoService: MatomoService
) {
super();
}
ngOnInit() {
this.matomoService.trackPageView('Recent DMP Activity');
this.route.queryParams.subscribe(params => {
if (this.isActive) {
let page = (params['page'] === undefined) ? 1 : +params['page'];
this.page = (page <= 0) ? 1 : page;
this.startIndex = (this.page - 1) * this.pageSize;
if (this.page > 1) {
this.offsetLess = (this.page - 2) * this.pageSize;
}
let order = params['order'];
if (this.isAuthenticated()) {
if (order === undefined || (order != this.order.UpdatedAt && order != this.order.Label && order != this.order.Status)) {
order = this.order.UpdatedAt;
}
} else {
if (order === undefined || (order != this.order.PUBLISHED && order != this.order.LABEL)) {
order = this.order.PUBLISHED;
}
}
this.formGroup.get('order').setValue(order);
let keyword = (params['keyword'] === undefined || params['keyword'].length <= 0) ? "" : params['keyword'];
this.formGroup.get("like").setValue(keyword);
this.updateUrl();
}
});
if (this.isAuthenticated()) {
this.refresh();
}
}
ngOnChanges() {
if (this.isActive) {
this.updateUrl();
}
}
updateUrl() {
let parameters = "?type=dmps" +
(this.page != 1 ? "&page=" + this.page : "") +
(((this.formGroup.get("order").value != this.order.MODIFIED && !this.publicMode) || (this.formGroup.get("order").value != this.order.PUBLISHED && this.publicMode)) ? "&order=" + this.formGroup.get("order").value : "") +
(this.formGroup.get("like").value ? ("&keyword=" + this.formGroup.get("like").value) : "");
this.location.go(this.router.url.split('?')[0] + parameters);
}
public isAuthenticated(): boolean {
return this.authentication.currentAccountIsAuthenticated();
}
refresh(): void {
if (!this.formGroup.get('order').value) {
this.formGroup.get('order').setValue(this.order.UpdatedAt);
}
this.lookup.page = { size: this.pageSize, offset: 0 };
this.lookup.order = { items: ['-' + this.formGroup.get('order').value] };
this.lookup.like = this.formGroup.get('like').value;
this.lookup.project = {
fields: [
[nameof<Description>(x => x.id)].join('.'),
[nameof<Description>(x => x.label)].join('.'),
[nameof<Description>(x => x.status)].join('.'),
[nameof<Description>(x => x.updatedAt)].join('.'),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].join('.'),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.groupId)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.label)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.type)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.reference)].join('.'),
]
};
this.descriptionService
.query(this.lookup)
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
this.listingItems = response.items;
this.totalCount = response.count;
//this.totalCountDmps.emit(this.dmpActivities.length);
// if (this.totalCount > 0 && this.totalCount <= (this.page - 1) * this.pageSize && this.page > 1) {
// let queryParams = { type: "dmps", page: 1, order: this.formGroup.get("order").value };
// if (this.formGroup.get("like").value) {
// queryParams['keyword'] = this.formGroup.get("like").value;
// }
// this.router.navigate(["/home"], { queryParams: queryParams })
// }
// this.totalCount < this.pageSize ? this.totalCountDmps.emit(response.totalCount) : this.totalCountDmps.emit(this.pageSize);
// this.totalCountDmps.emit(this.totalCount);
// this.dmpActivities.forEach(dmpActivity => {
// const recentActivity: RecentActivity = {
// activityData: dmpActivity,
// activityType: RecentActivityType.Dmp
// };
// this.allRecentActivities.push(recentActivity)
// })
});
this.formGroup.get('like').valueChanges
.pipe(takeUntil(this._destroyed), debounceTime(500))
.subscribe(x => this.refresh());
this.formGroup.get('order').valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => this.refresh());
}
}

View File

@ -1,4 +1,4 @@
<div *ngIf="dmpActivities != null" id="dmps" #dmps>
<div *ngIf="listingItems != null" id="dmps" #dmps>
<div class="d-flex flex-direction-row pt-4">
<!-- Sort by -->
<span class="d-flex align-items-center">{{'DMP-LISTING.SORT-BY' | translate}}:</span>
@ -20,10 +20,13 @@
</mat-form-field>
<!-- End of Search Filter -->
</div>
<div *ngIf="dmpActivities && dmpActivities.length > 0 && page > 1" class="d-flex justify-content-center">
<div *ngIf="listingItems && listingItems.length > 0 && page > 1" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadNextOrPrevious(false)">{{'GENERAL.ACTIONS.LOAD-LESS' | translate}}</button>
</div>
<div *ngFor="let activity of dmpActivities">
<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 *ngFor="let activity of listingItems">
<div class="dmp-card">
<a [routerLink]="navigateToUrl(activity.id)" class="pointer">
<div class="d-flex flex-direction-row">
@ -94,11 +97,11 @@
</button>
</mat-menu>
</div>
</div>
<div class="text-muted d-flex justify-content-center mt-5" *ngIf="!hasMoreResults && dmpActivities && dmpActivities.length > 0">
</div> -->
<div class="text-muted d-flex justify-content-center mt-5" *ngIf="!hasMoreResults && listingItems && listingItems.length > 0">
{{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}}
</div>
<div *ngIf="dmpActivities && dmpActivities.length > 0 && dmpActivities.length >= pageSize && hasMoreResults" class="d-flex justify-content-center">
<div *ngIf="listingItems && listingItems.length > 0 && listingItems.length >= pageSize && hasMoreResults" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadNextOrPrevious()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
</div>

View File

@ -1,44 +1,20 @@
import { Location } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { DmpBlueprintSectionFieldCategory } from '@app/core/common/enum/dmp-blueprint-section-field-category';
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { RecentActivityType } from '@app/core/common/enum/recent-activity-type';
import { Role } from '@app/core/common/enum/role';
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
import { RecentActivityItem } from '@app/core/model/dashboard/recent-activity-item';
import { DatasetListingModel } from '@app/core/model/dataset/dataset-listing';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection, FieldInSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { DmpModel } from '@app/core/model/dmp/dmp';
import { DmpListingModel } from '@app/core/model/dmp/dmp-listing';
import { DmpCriteria } from '@app/core/query/dmp/dmp-criteria';
import { Description } from '@app/core/model/description/description';
import { Dmp, DmpUser } from '@app/core/model/dmp/dmp';
import { RecentActivityItemLookup } from '@app/core/query/recent-activity-item-lookup.lookup';
import { AuthService } from '@app/core/services/auth/auth.service';
import { DatasetService } from '@app/core/services/dataset/dataset.service';
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { LockService } from '@app/core/services/lock/lock.service';
import { DashboardService } from '@app/core/services/dashboard/dashboard.service';
import { MatomoService } from '@app/core/services/matomo/matomo-service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
import { CloneDialogComponent } from '@app/ui/dmp/clone/clone-dialog/clone-dialog.component';
import { DmpEditorModel } from '@app/ui/dmp/editor/dmp-editor.model';
import { ExtraPropertiesFormModel } from '@app/ui/dmp/editor/general-tab/extra-properties-form.model';
import { FunderFormModel } from '@app/ui/dmp/editor/grant-tab/funder-form-model';
import { GrantTabModel } from '@app/ui/dmp/editor/grant-tab/grant-tab-model';
import { ProjectFormModel } from '@app/ui/dmp/editor/grant-tab/project-form-model';
import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dmp-invitation-dialog.component';
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
import { BaseComponent } from '@common/base/base.component';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import { Guid } from '@common/types/guid';
import { TranslateService } from '@ngx-translate/core';
import * as FileSaver from 'file-saver';
import { debounceTime, map, takeUntil } from 'rxjs/operators';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
@Component({
@ -48,21 +24,23 @@ import { nameof } from 'ts-simple-nameof';
})
export class RecentEditedDmpActivityComponent extends BaseComponent implements OnInit {
lookup: RecentActivityItemLookup = new RecentActivityItemLookup();
pageSize: number = 5;
@Output() totalCountDmps: EventEmitter<any> = new EventEmitter();
@ViewChild("dmps") resultsContainer;
dmpActivities: DmpListingModel[];
listingItems: RecentActivityItem[];
datasetActivities: DatasetListingModel[];
dmpModel: DmpEditorModel;
recentActivityTypeEnum = RecentActivityType;
isDraft: boolean;
totalCount: number;
startIndex: number = 0;
offsetLess: number = 0;
hasMoreResults: boolean = true;
pageSize: number = 5;
dmpFormGroup: UntypedFormGroup;
public formGroup = new UntypedFormBuilder().group({
like: new UntypedFormControl(),
@ -80,17 +58,9 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O
private router: Router,
public enumUtils: EnumUtils,
private authentication: AuthService,
private dmpService: DmpService,
private dmpBlueprintService: DmpBlueprintService,
private datasetService: DatasetService,
private language: TranslateService,
private dialog: MatDialog,
private uiNotificationService: UiNotificationService,
private dashboardService: DashboardService,
private location: Location,
private lockService: LockService,
private httpClient: HttpClient,
private matomoService: MatomoService,
private fileUtils: FileUtils
) {
super();
}
@ -126,28 +96,68 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O
}
});
if (this.isAuthenticated()) {
// const fields: Array<string> = ["-modified"];
if (!this.formGroup.get('order').value) {
this.formGroup.get('order').setValue(this.order.MODIFIED);
this.refresh();
}
const fields: Array<string> = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value];
const dmpDataTableRequest: DataTableRequest<DmpCriteria> = new DataTableRequest(this.startIndex, 5, { fields: fields });
dmpDataTableRequest.criteria = new DmpCriteria();
dmpDataTableRequest.criteria.like = this.formGroup.get('like').value;
this.dmpService
.getPaged(dmpDataTableRequest, "listing")
}
ngOnChanges() {
if (this.isActive) {
this.updateUrl();
}
}
updateUrl() {
let parameters = "?type=dmps" +
(this.page != 1 ? "&page=" + this.page : "") +
(((this.formGroup.get("order").value != this.order.MODIFIED && !this.publicMode) || (this.formGroup.get("order").value != this.order.PUBLISHED && this.publicMode)) ? "&order=" + this.formGroup.get("order").value : "") +
(this.formGroup.get("like").value ? ("&keyword=" + this.formGroup.get("like").value) : "");
this.location.go(this.router.url.split('?')[0] + parameters);
}
public isAuthenticated(): boolean {
return this.authentication.currentAccountIsAuthenticated();
}
refresh(): void {
if (!this.formGroup.get('order').value) {
this.formGroup.get('order').setValue(this.order.UpdatedAt);
}
this.lookup.page = { size: this.pageSize, offset: 0 };
this.lookup.orderField = this.formGroup.get('order').value;
this.lookup.like = this.formGroup.get('like').value;
this.lookup.project = {
fields: [
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.status)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.version)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.groupId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.updatedAt)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
]
};
this.dashboardService
.getMyRecentActivityItems(this.lookup)
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
this.dmpActivities = response.data;
this.totalCount = response.totalCount;
this.totalCountDmps.emit(this.dmpActivities.length);
if (this.totalCount > 0 && this.totalCount <= (this.page - 1) * this.pageSize && this.page > 1) {
let queryParams = { type: "dmps", page: 1, order: this.formGroup.get("order").value };
if (this.formGroup.get("like").value) {
queryParams['keyword'] = this.formGroup.get("like").value;
}
this.router.navigate(["/home"], { queryParams: queryParams })
}
this.listingItems = response;
//this.totalCount = response.totalCount;
//this.totalCountDmps.emit(this.dmpActivities.length);
// if (this.totalCount > 0 && this.totalCount <= (this.page - 1) * this.pageSize && this.page > 1) {
// let queryParams = { type: "dmps", page: 1, order: this.formGroup.get("order").value };
// if (this.formGroup.get("like").value) {
// queryParams['keyword'] = this.formGroup.get("like").value;
// }
// this.router.navigate(["/home"], { queryParams: queryParams })
// }
// this.totalCount < this.pageSize ? this.totalCountDmps.emit(response.totalCount) : this.totalCountDmps.emit(this.pageSize);
// this.totalCountDmps.emit(this.totalCount);
// this.dmpActivities.forEach(dmpActivity => {
@ -179,571 +189,5 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O
// this.allRecentActivities.push(recentActivity)
// })
// });
} else {
this.publicMode = true;
if (!this.formGroup.get('order').value) {
this.formGroup.get('order').setValue(this.order.PUBLISHED);
}
const dataTableRequest = this.setPublicDataTableRequest();
this.dmpService.getPaged(dataTableRequest, "listing").pipe(takeUntil(this._destroyed)).subscribe(response => {
if (!response) { return []; }
this.dmpActivities = response.data;
this.totalCount = response.totalCount;
this.totalCountDmps.emit(this.dmpActivities.length);
if (this.totalCount > 0 && this.totalCount <= (this.page - 1) * this.pageSize && this.page > 1) {
let queryParams = { type: "dmps", page: 1, order: this.formGroup.get("order").value };
if (this.formGroup.get("like").value) {
queryParams['keyword'] = this.formGroup.get("like").value;
}
this.router.navigate(["/home"], { queryParams: queryParams })
}
});
this.formGroup.get('like').valueChanges
.pipe(takeUntil(this._destroyed), debounceTime(500))
.subscribe(x => this.refresh());
this.formGroup.get('order').valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => this.refresh());
}
}
ngOnChanges() {
if (this.isActive) {
this.updateUrl();
}
}
updateUrl() {
let parameters = "?type=dmps" +
(this.page != 1 ? "&page=" + this.page : "") +
(((this.formGroup.get("order").value != this.order.MODIFIED && !this.publicMode) || (this.formGroup.get("order").value != this.order.PUBLISHED && this.publicMode)) ? "&order=" + this.formGroup.get("order").value : "") +
(this.formGroup.get("like").value ? ("&keyword=" + this.formGroup.get("like").value) : "");
this.location.go(this.router.url.split('?')[0] + parameters);
}
public isAuthenticated(): boolean {
return this.authentication.currentAccountIsAuthenticated();
}
private setPublicDataTableRequest(fields?: Array<string>, more: boolean = true): DataTableRequest<DmpCriteria> {
const dmpCriteria = new DmpCriteria();
dmpCriteria.allVersions = false;
dmpCriteria.isPublic = true;
dmpCriteria.onlyPublic = true;
dmpCriteria.like = this.formGroup.get("like").value ? this.formGroup.get("like").value : "";
if (!fields) {
fields = new Array<string>('-publishedAt');
}
const dataTableRequest: DataTableRequest<DmpCriteria> = more ? new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }) : new DataTableRequest(this.offsetLess, this.pageSize, { fields: fields });
dataTableRequest.criteria = dmpCriteria;
return dataTableRequest;
}
isUserOwner(activity: DmpListingModel): boolean {
const principalId: string = this.authentication.userId()?.toString();
if (principalId) return !!activity.users.find(x => (x.role === Role.Owner) && (principalId === x.id));
}
editClicked(dmp: DmpListingModel) {
this.router.navigate(['/plans/edit/' + dmp.id]);
}
cloneOrNewVersionClicked(dmp: DmpListingModel, isNewVersion: boolean) {
this.dmpService.getSingle(dmp.id).pipe(map(data => data as DmpModel))
.pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.dmpModel = new DmpEditorModel();
this.dmpModel.grant = new GrantTabModel();
this.dmpModel.project = new ProjectFormModel();
this.dmpModel.funder = new FunderFormModel();
this.dmpModel.extraProperties = new ExtraPropertiesFormModel();
this.dmpModel.fromModel(data);
this.dmpModel.status = DmpStatus.Draft;
this.dmpFormGroup = this.dmpModel.buildForm();
if (!isNullOrUndefined(this.formGroup.get('profile').value)) {
this.getBlueprintDefinition(Guid.parse(this.formGroup.get('profile').value), result => {
this.checkForGrant(result.definition);
this.checkForFunder(result.definition);
this.checkForProject(result.definition);
});
}
if (!isNewVersion) {
this.dmpFormGroup.get('label').setValue(dmp.label + " New");
}
this.openCloneDialog(isNewVersion);
});
}
private getBlueprintDefinition(blueprintId: Guid, successFunction) {
this.dmpBlueprintService.getSingle(blueprintId, [
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.description)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.ordinal)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.id)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.category)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.dataType)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.systemFieldType)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.label)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.placeholder)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.description)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.required)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.ordinal)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.id)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateId)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.label)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.minMultiplicity)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.maxMultiplicity)].join('.'),
]
)
.pipe(map(data => data as DmpBlueprint), takeUntil(this._destroyed))
.subscribe(
data => successFunction(data),
);
}
private checkForGrant(blueprint: DmpBlueprintDefinition) {
let hasGrant = false;
blueprint.sections.forEach(section => section.fields.forEach(
field => {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
hasGrant = true;
}
}
));
if (!hasGrant) {
this.formGroup.removeControl('grant');
}
}
private checkForFunder(blueprint: DmpBlueprintDefinition) {
let hasFunder = false;
blueprint.sections.forEach(section => section.fields.forEach(
field => {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
hasFunder = true;
}
}
));
if (!hasFunder) {
this.formGroup.removeControl('funder');
}
}
private checkForProject(blueprint: DmpBlueprintDefinition) {
let hasProject = false;
blueprint.sections.forEach(section => section.fields.forEach(
field => {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
hasProject = true;
}
}
));
if (!hasProject) {
this.formGroup.removeControl('project');
}
}
openCloneDialog(isNewVersion: boolean) {
const dialogRef = this.dialog.open(CloneDialogComponent, {
maxWidth: '700px',
maxHeight: '80vh',
data: {
formGroup: this.dmpFormGroup,
datasets: this.dmpFormGroup.get('datasets').value,
isNewVersion: isNewVersion,
confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.SAVE'),
cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'),
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
if (!isNewVersion) {
this.dmpService.clone(this.dmpFormGroup.getRawValue(), this.dmpFormGroup.get('id').value)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onCloneOrNewVersionCallbackSuccess(complete),
error => this.onCloneOrNewVersionCallbackError(error)
);
} else if (isNewVersion) {
this.dmpService.newVersion(this.dmpFormGroup.getRawValue(), this.dmpFormGroup.get('id').value)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onCloneOrNewVersionCallbackSuccess(complete),
error => this.onCloneOrNewVersionCallbackError(error)
);
}
}
});
}
deleteClicked(id: string) {
this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed))
.subscribe(lockStatus => {
if (!lockStatus) {
this.openDeleteDialog(id);
} else {
this.openLockedByUserDialog();
}
});
}
openDeleteDialog(id: string) {
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(id)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => this.onDeleteCallbackSuccess(),
error => this.onDeleteCallbackError(error)
);
}
});
}
openLockedByUserDialog() {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
maxWidth: '400px',
restoreFocus: false,
data: {
message: this.language.instant('DMP-EDITOR.ACTIONS.LOCK')
}
});
}
openShareDialog(rowId: any, rowName: any) {
const dialogRef = this.dialog.open(DmpInvitationDialogComponent, {
// height: '250px',
// width: '700px',
autoFocus: false,
restoreFocus: false,
data: {
dmpId: rowId,
dmpName: rowName
}
});
}
isDraftDmp(activity: DmpListingModel) {
return activity.status == DmpStatus.Draft;
}
onCallbackSuccess(): void {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
this.router.navigate(['/plans']);
}
reloadPage(): void {
const path = this.location.path();
this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => {
this.router.navigate([path]);
});
}
onDeleteCallbackSuccess(): void {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success);
this.reloadPage();
}
onDeleteCallbackError(error) {
this.uiNotificationService.snackBarNotification(error.error.message ? this.language.instant(error.error.message) : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error);
}
onCloneOrNewVersionCallbackSuccess(dmpId: String): void {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
this.router.navigate(['/plans/edit/', dmpId]);
}
onCloneOrNewVersionCallbackError(error: any) {
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Error);
}
redirect(id: string) {
if (this.isAuthenticated()) {
this.router.navigate(['../plans/overview/' + id]);
} else {
this.router.navigate(['../explore-plans/publicOverview', id]);
}
}
navigateToUrl(id: string): string[] {
if (this.isAuthenticated()) {
return ['../plans/overview/' + id];
} else {
return ['../explore-plans/publicOverview', id];
}
}
roleDisplay(value: any) {
const principalId: string = this.authentication.userId()?.toString();
let role: number;
if (principalId) {
value.forEach(element => {
if (principalId === 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');
}
}
// dmpBlueprintDisplay(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.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.matomoService.trackDownload('dmps', "xml", id);
});
}
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.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.matomoService.trackDownload('dmps', "docx", id);
});
}
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.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.matomoService.trackDownload('dmps', "pdf", id);
});
}
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.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.matomoService.trackDownload('dmps', "json", id);
}, async error => {
this.onExportCallbackError(error);
});
}
async onExportCallbackError(error: any) {
const errorJsonText = await error.error.text();
const errorObj = JSON.parse(errorJsonText);
this.uiNotificationService.snackBarNotification(errorObj.message, SnackBarNotificationLevel.Error);
}
// newVersion(id: String, label: String) {
// let url = this.router.createUrlTree(['/plans/new_version/', id, { dmpLabel: label }]);
// window.open(url.toString(), '_blank');
// }
viewVersions(rowId: String, rowLabel: String, activity: DmpListingModel) {
if (activity.public && !this.isUserOwner(activity)) {
let url = this.router.createUrlTree(['/explore-plans/versions/', rowId, { groupLabel: rowLabel }]);
window.open(url.toString(), '_blank');
// this.router.navigate(['/explore-plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } });
} else {
let url = this.router.createUrlTree(['/plans/versions/', rowId, { groupLabel: rowLabel }]);
window.open(url.toString(), '_blank');
// this.router.navigate(['/plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } });
}
}
refresh(): void {
this.page = 1;
this.updateUrl();
const fields: Array<string> = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value];
this.startIndex = 0;
const dmpDataTableRequest = this.isAuthenticated() ? new DataTableRequest<DmpCriteria>(this.startIndex, this.pageSize, { fields: fields }) : this.setPublicDataTableRequest(fields);
if (this.isAuthenticated()) {
dmpDataTableRequest.criteria = new DmpCriteria();
dmpDataTableRequest.criteria.like = this.formGroup.get("like").value ? this.formGroup.get("like").value : "";
}
this.dmpService
.getPaged(dmpDataTableRequest, "listing")
.subscribe(response => {
this.dmpActivities = response.data;
this.totalCount = response.totalCount;
this.totalCountDmps.emit(this.dmpActivities.length);
if (response.data.length < this.pageSize) {
this.hasMoreResults = false;
} else {
this.hasMoreResults = true;
}
});
}
public loadNextOrPrevious(more: boolean = true) {
this.startIndex = this.startIndex + this.pageSize;
const fields: Array<string> = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value];
let request;
this.startIndex = (this.page) * this.pageSize;
if (this.page > 1) {
this.offsetLess = (this.page - 2) * this.pageSize;
}
if (this.isAuthenticated()) {
if (more) {
request = new DataTableRequest<DmpCriteria>(this.startIndex, this.pageSize, { fields: fields })
} else {
request = new DataTableRequest<DmpCriteria>(this.offsetLess, this.pageSize, { fields: fields })
}
} else {
request = this.setPublicDataTableRequest(fields, more);
}
if (this.isAuthenticated()) {
request.criteria = new DmpCriteria();
request.criteria.like = this.formGroup.get("like").value ? this.formGroup.get("like").value : "";
}
this.dmpService.getPaged(request, "listing").pipe(takeUntil(this._destroyed)).subscribe(result => {
if (!result || !result.data || result.data.length == 0) {
this.hasMoreResults = false;
// return [];
} else {
this.page = this.page + (more ? 1 : -1);
this.updateUrl();
// this.dmpActivities = this.dmpActivities.concat(result.data);
// this.dmpActivities = this.dmpActivities.length > 0 ? this.mergeTwoSortedLists(this.dmpActivities, result.data, this.formGroup.get('order').value) : result.data;
this.dmpActivities = result.data;
if (result.data.length < this.pageSize) {
this.hasMoreResults = false;
} else {
this.hasMoreResults = true;
}
this.totalCountDmps.emit(this.dmpActivities.length);
if (more) {
this.resultsContainer.nativeElement.scrollIntoView();
}
}
});
}
private mergeTwoSortedLists(arr1: DmpListingModel[], arr2: DmpListingModel[], order: string): DmpListingModel[] {
let merged = [];
let index1 = 0;
let index2 = 0;
let current = 0;
while (current < (arr1.length + arr2.length)) {
let isArr1Depleted = index1 >= arr1.length;
let isArr2Depleted = index2 >= arr2.length;
if (order === 'modified') {
if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].modifiedTime) > new Date(arr2[index2].modifiedTime)))) {
merged[current] = arr1[index1];
index1++;
} else {
merged[current] = arr2[index2];
index2++;
}
} else if (order === 'created') {
if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].creationTime) > new Date(arr2[index2].creationTime)))) {
merged[current] = arr1[index1];
index1++;
} else {
merged[current] = arr2[index2];
index2++;
}
} else if (order === 'label') {
if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].label.localeCompare(arr2[index2].label)))) {
merged[current] = arr1[index1];
index1++;
} else {
merged[current] = arr2[index2];
index2++;
}
} else if (order === 'status') {
if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].status < arr2[index2].status))) {
merged[current] = arr1[index1];
index1++;
} else {
merged[current] = arr2[index2];
index2++;
}
} else if (order === "publishedAt") {
if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].publishedAt) > new Date(arr2[index2].publishedAt)))) {
merged[current] = arr1[index1];
index1++;
} else {
merged[current] = arr2[index2];
index2++;
}
}
current++;
}
return merged;
}
// 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,22 +0,0 @@
th {
text-transform: uppercase;
}
.is-public {
padding-left: 5px;
padding-right: 5px;
border: 1px solid var(--primary-color-3)3b;
color: var(--primary-color-3);
background-color: var(--primary-color-3)0f;
border-radius: 10em;
text-align: center;
}
.template-name {
padding-left: 0px;
border: 1px solid rgb(218, 227, 243);
color: rgb(43, 104, 209);
background-color: rgb(236, 241, 249);
border-radius: 10em;
text-align: center;
}

View File

@ -1,63 +0,0 @@
<div class="card">
<div class="card-header card-header-plain">
<div class="card-desc">
<h4 class="card-title">
{{ 'RECENT-ACTIVITY.LAST-VISITED-DMP' | translate}}
</h4>
<p class="card-category">
{{ 'RECENT-ACTIVITY.LICENSE' | translate}}
</p>
</div>
<div class="view-all" [class.clickable]="isAuthenticated()" (click)="navigateToUrl()">
{{ 'GENERAL.ACTIONS.VIEW-ALL' | translate}}</div>
</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.VISITED' | translate }}</th>
<th></th>
</thead>
<tbody *ngIf="dmpActivities != null">
<tr (click)="redirect(activity.id, recentActivityTypeEnum.Dmp)" *ngFor="let activity of dmpActivities" style="cursor: pointer;">
<td>{{ activity.label }}</td>
<td>
<div class="template-name">
--
</div>
</td>
<td>{{ activity.grant }}</td>
<td>Role Name</td>
<td>{{ activity.organisations }}</td>
<td *ngIf="activity.status === 1">
<div class="is-public">
{{ enumUtils.toDmpStatusString(activity.status) }}
</div>
</td>
<td *ngIf="activity.status === 0" style="padding-left: 12px">
{{ enumUtils.toDmpStatusString(activity.status) }}
</td>
<td>{{ activity.creationTime | date: "shortDate" }}</td>
<td><i class="material-icons more-icon">more_horiz</i></td>
</tr>
</tbody>
<tbody *ngIf="dmpActivities == null">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><i class="material-icons more-icon">more_horiz</i></td>
</tr>
</tbody>
</table>
</div>
</div>

View File

@ -1,73 +0,0 @@
import { Component, OnInit } from "@angular/core";
import { Router } from '@angular/router';
import { RecentActivityType } from '@app/core/common/enum/recent-activity-type';
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 { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { BaseComponent } from '@common/base/base.component';
import { takeUntil } from "rxjs/operators";
@Component({
selector: "app-recent-visited-activity",
templateUrl: "./recent-visited-activity.component.html",
styleUrls: ["./recent-visited-activity.component.css"]
})
export class RecentVisitedActivityComponent extends BaseComponent
implements OnInit {
dmpActivities: DmpListingModel[];
recentActivityItems: any[];
recentActivityTypeEnum = RecentActivityType;
public: boolean = false;
constructor(
private router: Router,
private authentication: AuthService,
private dmpService: DmpService,
public enumUtils: EnumUtils
) {
super();
}
ngOnInit() {
if (this.isAuthenticated()) {
const fields: Array<string> = ["-created"];
const dmpDataTableRequest: DataTableRequest<DmpCriteria> = new DataTableRequest(0, null, { fields: fields });
dmpDataTableRequest.criteria = new DmpCriteria();
dmpDataTableRequest.criteria.like = "";
this.dmpService
.getPaged(dmpDataTableRequest, "listing")
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
this.dmpActivities = response.data;
});
}
}
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/edit/" + id]);
return;
}
default:
throw new Error("Unsupported Activity Type ");
}
}
public isAuthenticated(): boolean {
return this.authentication.currentAccountIsAuthenticated();
}
navigateToUrl() { }
}

View File

@ -1,10 +0,0 @@
.clickable {
cursor: pointer;
}
.play_circle {
display: flex;
align-self: center;
margin: 0px 10px 0px 0px;
font-size: 40px;
}

View File

@ -1,10 +0,0 @@
<a [routerLink]="[routerLink]" class="card clickable">
<div class="row card-header card-header-blue">
<div class="col card-desc">
<h4 class="card-title pb-1">{{ title }}</h4>
<p class="card-category">{{ subtitle }}</p>
</div>
<i class="col-auto material-icons play_circle">{{ icon }}</i>
</div>
<div class="card-body table-responsive"></div>
</a>

View File

@ -1,30 +0,0 @@
import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core";
import { Router } from "@angular/router";
@Component({
selector: "app-wizard",
templateUrl: "./wizard.component.html",
styleUrls: ["./wizard.component.css"]
})
export class WizardComponent {
@Input() title: string;
@Input() subtitle: string;
@Input() icon: string;
@Input() routerLink: string;
@Output() onClick: EventEmitter<void> = new EventEmitter<void>();
wizardItems: any[];
constructor(private router: Router) {}
cardClicked() {
this.onClick.emit();
}
navigateToCreate() {
this.router.navigate(["/quick-wizard"]);
}
navigateToAdd() {
this.router.navigate(["/datasetcreatewizard"]);
}
}

View File

@ -108,6 +108,9 @@ import { DmpEditorBlueprintComponent } from './dmp-editor-blueprint/dmp-editor-b
LicenseInfoComponent,
DatasetPreviewDialogComponent,
DmpEditorBlueprintComponent
],
exports: [
DmpListingItemComponent
]
})
export class DmpModule { }

View File

@ -18,6 +18,7 @@ import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service'
// import { IBreadCrumbComponent } from '@app/ui/misc/breadcrumb/definition/IBreadCrumbComponent';
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { Description } from '@app/core/model/description/description';
import { Dmp, DmpUser } from '@app/core/model/dmp/dmp';
import { DmpLookup } from '@app/core/query/dmp.lookup';
import { BaseComponent } from '@common/base/base.component';
@ -26,7 +27,6 @@ import { TranslateService } from '@ngx-translate/core';
import { NgDialogAnimationService } from "ng-dialog-animation";
import { debounceTime, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { Description } from '@app/core/model/description/description';
@Component({
selector: 'app-dmp-listing-component',
@ -37,30 +37,13 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
@ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
// @ViewChild(DmpCriteriaComponent, { static: true }) criteria: DmpCriteriaComponent;
// breadCrumbs: Observable<BreadcrumbItem[]> = observableOf([{ parentComponentName: null, label: 'DMPs', url: "/plans" }]);
lookup: DmpLookup = new DmpLookup();
groupId: string;
// itemId: string;
// showGrant: boolean;
// titlePrefix: string;
totalCount: number;
listingItems: Dmp[] = [];
// allVersions: boolean = false;
// groupLabel: string;
isPublic: boolean = false;
// public isVisible = true
hasListingItems = null;
// startIndex: number = 0;
pageSize: number = 5;
// criteria: DmpCriteria;
// criteriaFormGroup: UntypedFormGroup;
public formGroup = new UntypedFormBuilder().group({
like: new UntypedFormControl(),
order: new UntypedFormControl()
@ -68,8 +51,6 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
scrollbar: boolean;
order = RecentActivityOrder;
// dmpText: string;
// datasetText: string;
constructor(
private dmpService: DmpService,

View File

@ -6,10 +6,9 @@ import { Router } from '@angular/router';
import { DmpAccessType } from '@app/core/common/enum/dmp-access-type';
import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
import { ReferenceType } from '@app/core/common/enum/reference-type';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection, FieldInSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { Dmp } from '@app/core/model/dmp/dmp';
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { DmpServiceNew } from '@app/core/services/dmp/dmp.service';
import { LockService } from '@app/core/services/lock/lock.service';
import { MatomoService } from '@app/core/services/matomo/matomo-service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
@ -20,8 +19,7 @@ import { BaseComponent } from '@common/base/base.component';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import { Guid } from '@common/types/guid';
import { TranslateService } from '@ngx-translate/core';
import { map, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { takeUntil } from 'rxjs/operators';
import { DmpStatus } from '../../../../core/common/enum/dmp-status';
import { AuthService } from '../../../../core/services/auth/auth.service';
@ -48,7 +46,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
private dialog: MatDialog,
private authentication: AuthService,
public enumUtils: EnumUtils,
private dmpService: DmpService,
private dmpService: DmpServiceNew,
private dmpBlueprintService: DmpBlueprintService,
private language: TranslateService,
private uiNotificationService: UiNotificationService,
@ -116,7 +114,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
isUserDMPRelated() {
const principalId: Guid = this.authentication.userId();
return this.dmp.dmpUsers.some(x => (x.user.id === principalId));
return this.dmp.dmpUsers?.some(x => (x.user.id === principalId));
}
cloneOrNewVersionClicked(dmp: Dmp, isNewVersion: boolean) {
@ -147,37 +145,6 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
// });
}
private getBlueprintDefinition(blueprintId: Guid, successFunction) {
this.dmpBlueprintService.getSingle(blueprintId, [
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.description)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.ordinal)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.id)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.category)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.dataType)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.systemFieldType)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.label)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.placeholder)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.description)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.required)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.ordinal)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.id)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateId)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.label)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.minMultiplicity)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.maxMultiplicity)].join('.'),
]
)
.pipe(map(data => data as DmpBlueprint), takeUntil(this._destroyed))
.subscribe(
data => successFunction(data),
);
}
openCloneDialog(isNewVersion: boolean) {
// TODO: fix this
// const dialogRef = this.dialog.open(CloneDialogComponent, {
@ -271,8 +238,8 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
// this.uiNotificationService.snackBarNotification(errorObj.message, SnackBarNotificationLevel.Error);
// }
deleteClicked(id: string) {
this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed))
deleteClicked(id: Guid) {
this.lockService.checkLockStatus(id.toString()).pipe(takeUntil(this._destroyed))
.subscribe(lockStatus => {
if (!lockStatus) {
this.openDeleteDialog(id);
@ -282,7 +249,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
});
}
openDeleteDialog(id: string) {
openDeleteDialog(id: Guid) {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
maxWidth: '300px',
restoreFocus: false,
@ -351,6 +318,6 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
isUserOwner(dmp: Dmp): boolean {
const principalId: Guid = this.authentication.userId();
if (principalId) return !!dmp.dmpUsers.find(x => (x.role === DmpUserRole.Owner) && (principalId === x.id));
if (principalId) return !!dmp.dmpUsers?.find(x => (x.role === DmpUserRole.Owner) && (principalId === x.id));
}
}

View File

@ -175,7 +175,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
setIsUserOwner() {
if (this.dmp) {
const principalId: Guid = this.authentication.userId();
if (principalId) this.isUserOwner = !!this.dmp.dmpUsers.find(x => (x.role === DmpUserRole.Owner) && (principalId === x.id));
if (principalId) this.isUserOwner = !!this.dmp.dmpUsers?.find(x => (x.role === DmpUserRole.Owner) && (principalId === x.id));
}
}
@ -403,7 +403,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
isUserDmpRelated(): boolean {
const principalId: Guid = this.authentication.userId();
return this.dmp.dmpUsers.some(x => (x.user.id === principalId));
return this.dmp.dmpUsers?.some(x => (x.user.id === principalId));
}
isDraftDmp(dmp: Dmp) {