dmp overview page refactor

This commit is contained in:
Diamantis Tziotzios 2023-12-04 19:37:52 +02:00
parent a72c7001f9
commit ad1539af59
15 changed files with 227 additions and 163 deletions

View File

@ -14,7 +14,8 @@ public class DmpDescriptionTemplateLookup extends Lookup {
private List<UUID> ids; private List<UUID> ids;
private List<UUID> dmpIds; private List<UUID> dmpIds;
private List<UUID> descriptionTemplateIds; private List<UUID> descriptionTemplateGroupIds;
private List<UUID> sectionIds;
private List<UUID> excludedIds; private List<UUID> excludedIds;
@ -52,19 +53,28 @@ public class DmpDescriptionTemplateLookup extends Lookup {
this.dmpIds = dmpIds; this.dmpIds = dmpIds;
} }
public List<UUID> getDescriptionTemplateIds() { public List<UUID> getDescriptionTemplateGroupIds() {
return descriptionTemplateIds; return descriptionTemplateGroupIds;
} }
public void setDescriptionTemplateIds(List<UUID> descriptionTemplateIds) { public List<UUID> getSectionIds() {
this.descriptionTemplateIds = descriptionTemplateIds; return sectionIds;
}
public void setSectionIds(List<UUID> sectionIds) {
this.sectionIds = sectionIds;
}
public void setDescriptionTemplateGroupIds(List<UUID> descriptionTemplateGroupIds) {
this.descriptionTemplateGroupIds = descriptionTemplateGroupIds;
} }
public DmpDescriptionTemplateQuery enrich(QueryFactory queryFactory) { public DmpDescriptionTemplateQuery enrich(QueryFactory queryFactory) {
DmpDescriptionTemplateQuery query = queryFactory.query(DmpDescriptionTemplateQuery.class); DmpDescriptionTemplateQuery query = queryFactory.query(DmpDescriptionTemplateQuery.class);
if (this.ids != null) query.ids(this.ids); if (this.ids != null) query.ids(this.ids);
if (this.dmpIds != null) query.ids(this.dmpIds); if (this.dmpIds != null) query.ids(this.dmpIds);
if (this.descriptionTemplateIds != null) query.ids(this.descriptionTemplateIds); if (this.descriptionTemplateGroupIds != null) query.descriptionTemplateGroupIds(this.descriptionTemplateGroupIds);
if (this.sectionIds != null) query.sectionIds(this.sectionIds);
if (this.excludedIds != null) query.excludedIds(this.excludedIds); if (this.excludedIds != null) query.excludedIds(this.excludedIds);
if (this.isActive != null) query.isActive(this.isActive); if (this.isActive != null) query.isActive(this.isActive);

View File

@ -0,0 +1,26 @@
import { Lookup } from '@common/model/lookup';
import { Guid } from '@common/types/guid';
import { IsActive } from '../common/enum/is-active.enum';
export class DmpDescriptionTemplateLookup extends Lookup implements DmpDescriptionTemplateFilter {
ids: Guid[];
excludedIds: Guid[];
dmpIds: Guid[];
descriptionTemplateGroupIds: Guid[];
sectionIds: Guid[];
isActive: IsActive[];
constructor() {
super();
}
}
export interface DmpDescriptionTemplateFilter {
ids: Guid[];
excludedIds: Guid[];
dmpIds: Guid[];
descriptionTemplateGroupIds: Guid[];
sectionIds: Guid[];
isActive: IsActive[];
}

View File

@ -1,9 +1,10 @@
import { Lookup } from '@common/model/lookup'; import { Lookup } from '@common/model/lookup';
import { Guid } from '@common/types/guid'; import { Guid } from '@common/types/guid';
import { IsActive } from '../common/enum/is-active.enum'; import { DmpAccessType } from '../common/enum/dmp-access-type';
import { DmpStatus } from '../common/enum/dmp-status'; import { DmpStatus } from '../common/enum/dmp-status';
import { DmpVersionStatus } from '../common/enum/dmp-version-status'; import { DmpVersionStatus } from '../common/enum/dmp-version-status';
import { DmpAccessType } from '../common/enum/dmp-access-type'; import { IsActive } from '../common/enum/is-active.enum';
import { DmpDescriptionTemplateLookup } from './dmp-description-template.lookup';
export class DmpLookup extends Lookup implements DmpFilter { export class DmpLookup extends Lookup implements DmpFilter {
ids: Guid[]; ids: Guid[];
@ -14,6 +15,7 @@ export class DmpLookup extends Lookup implements DmpFilter {
statuses: DmpStatus[]; statuses: DmpStatus[];
accessTypes: DmpAccessType[]; accessTypes: DmpAccessType[];
versions: Number[]; versions: Number[];
dmpDescriptionTemplateSubQuery: DmpDescriptionTemplateLookup;
constructor() { constructor() {

View File

@ -33,6 +33,7 @@ import { ConfigurationService } from '../configuration/configuration.service';
import { BaseHttpV2Service } from '../http/base-http-v2.service'; import { BaseHttpV2Service } from '../http/base-http-v2.service';
import { BaseHttpService } from '../http/base-http.service'; import { BaseHttpService } from '../http/base-http.service';
import { DmpStatus } from '@app/core/common/enum/dmp-status'; import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { DmpDescriptionTemplateLookup } from '@app/core/query/dmp-description-template.lookup';
@Injectable() @Injectable()
export class DmpServiceNew { export class DmpServiceNew {
@ -160,7 +161,7 @@ export class DmpServiceNew {
valueAssign: (item: Dmp) => item.id, valueAssign: (item: Dmp) => item.id,
}; };
public buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[], statuses?: DmpStatus[]): DmpLookup { public buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[], statuses?: DmpStatus[], dmpDescriptionTemplateSubQuery?: DmpDescriptionTemplateLookup): DmpLookup {
const lookup: DmpLookup = new DmpLookup(); const lookup: DmpLookup = new DmpLookup();
lookup.page = { size: 100, offset: 0 }; lookup.page = { size: 100, offset: 0 };
if (excludedIds && excludedIds.length > 0) { lookup.excludedIds = excludedIds; } if (excludedIds && excludedIds.length > 0) { lookup.excludedIds = excludedIds; }
@ -173,6 +174,7 @@ export class DmpServiceNew {
nameof<Dmp>(x => x.label) nameof<Dmp>(x => x.label)
] ]
}; };
if (dmpDescriptionTemplateSubQuery != null) lookup.dmpDescriptionTemplateSubQuery = dmpDescriptionTemplateSubQuery;
lookup.order = { items: [nameof<Dmp>(x => x.label)] }; lookup.order = { items: [nameof<Dmp>(x => x.label)] };
if (like) { lookup.like = this.filterService.transformLike(like); } if (like) { lookup.like = this.filterService.transformLike(like); }
return lookup; return lookup;

View File

@ -119,6 +119,10 @@ export class ReferenceService {
// //
// //
hasRerefenceOfTypes(dmpReferences: DmpReference[], referenceTypes: ReferenceType[]): boolean {
return this.getReferencesForTypes(dmpReferences, referenceTypes)?.length > 0;
}
getReferencesForTypes(dmpReferences: DmpReference[], referenceTypes: ReferenceType[]): DmpReference[] { getReferencesForTypes(dmpReferences: DmpReference[], referenceTypes: ReferenceType[]): DmpReference[] {
return dmpReferences?.filter(x => referenceTypes?.includes(x?.reference?.type)); return dmpReferences?.filter(x => referenceTypes?.includes(x?.reference?.type));
} }
@ -126,4 +130,5 @@ export class ReferenceService {
getReferencesForTypesFirstSafe(dmpReferences: DmpReference[], referenceTypes: ReferenceType[]): DmpReference { getReferencesForTypesFirstSafe(dmpReferences: DmpReference[], referenceTypes: ReferenceType[]): DmpReference {
return this.getReferencesForTypes(dmpReferences, referenceTypes)?.find(Boolean); return this.getReferencesForTypes(dmpReferences, referenceTypes)?.find(Boolean);
} }
} }

View File

@ -9,6 +9,8 @@ import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/sing
import { Dmp } from '@app/core/model/dmp/dmp'; import { Dmp } from '@app/core/model/dmp/dmp';
import { DmpServiceNew } from '@app/core/services/dmp/dmp.service'; import { DmpServiceNew } from '@app/core/services/dmp/dmp.service';
import { DescriptionService } from '@app/core/services/description/description.service'; import { DescriptionService } from '@app/core/services/description/description.service';
import { DmpDescriptionTemplateLookup } from '@app/core/query/dmp-description-template.lookup';
import { IsActive } from '@app/core/common/enum/is-active.enum';
@Component({ @Component({
selector: 'description-copy-dialog-component', selector: 'description-copy-dialog-component',
@ -20,14 +22,18 @@ export class DescriptionCopyDialogComponent {
dmpModel: Dmp; dmpModel: Dmp;
descriptionDescriptionTemplateLabel: String; descriptionDescriptionTemplateLabel: String;
dmpAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { //TODO: add filter to only get DMPs that have connection with the same Description Template group. dmpAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { //TODO: add filter to only get DMPs that have connection with the same Description Template group.
initialItems: (data?: any) => this.dmpService.query(this.dmpService.buildAutocompleteLookup()).pipe(map(x => x.items)), initialItems: (data?: any) => this.dmpService.query(this.dmpService.buildAutocompleteLookup(null,null,null,null, this.dmpDescriptionTemplateLookup)).pipe(map(x => x.items)),
filterFn: (searchQuery: string, data?: any) => this.dmpService.query(this.dmpService.buildAutocompleteLookup(searchQuery)).pipe(map(x => x.items)), filterFn: (searchQuery: string, data?: any) => this.dmpService.query(this.dmpService.buildAutocompleteLookup(searchQuery, null, null, null, this.dmpDescriptionTemplateLookup)).pipe(map(x => x.items)),
getSelectedItem: (selectedItem: any) => this.dmpService.query(this.dmpService.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])), getSelectedItem: (selectedItem: any) => this.dmpService.query(this.dmpService.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])),
displayFn: (item: Dmp) => item.label, displayFn: (item: Dmp) => item.label,
titleFn: (item: Dmp) => item.label, titleFn: (item: Dmp) => item.label,
valueAssign: (item: Dmp) => item.id, valueAssign: (item: Dmp) => item.id,
}; };
dmpDescriptionTemplateLookup: DmpDescriptionTemplateLookup = {
descriptionTemplateGroupIds: [this.data.descriptionTemplate.groupId],
isActive: [IsActive.Active]
} as DmpDescriptionTemplateLookup;
constructor( constructor(
public dialogRef: MatDialogRef<DescriptionCopyDialogComponent>, public dialogRef: MatDialogRef<DescriptionCopyDialogComponent>,

View File

@ -7,7 +7,6 @@ import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort'; import { MatSort } from '@angular/material/sort';
import { ActivatedRoute, Params, Router } from '@angular/router'; import { ActivatedRoute, Params, Router } from '@angular/router';
import { DescriptionStatus } from '@app/core/common/enum/description-status'; import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { IsActive } from '@app/core/common/enum/is-active.enum'; import { IsActive } from '@app/core/common/enum/is-active.enum';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order'; import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
@ -107,9 +106,6 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit
this.dmpId = queryParams['dmpId']; this.dmpId = queryParams['dmpId'];
this.status = queryParams['status']; this.status = queryParams['status'];
this.lookup.dmpSubQuery = new DmpLookup();
this.lookup.dmpSubQuery.statuses = [DmpStatus.Draft];
this.lookup.page = { size: this.pageSize, offset: 0 }; this.lookup.page = { size: this.pageSize, offset: 0 };
this.lookup.order = { items: ['-' + nameof<Description>(x => x.updatedAt)] }; this.lookup.order = { items: ['-' + nameof<Description>(x => x.updatedAt)] };
this.lookup.metadata = { countAll: true }; this.lookup.metadata = { countAll: true };
@ -191,6 +187,7 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit
nameof<Description>(x => x.updatedAt), nameof<Description>(x => x.updatedAt),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].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.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.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.label)].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.accessType)].join('.'),

View File

@ -165,7 +165,7 @@ export class DescriptionListingItemComponent extends BaseComponent implements On
data: { data: {
formControl: formControl, formControl: formControl,
descriptionId: description.id, descriptionId: description.id,
descriptionProfileId: description.descriptionTemplate.id, descriptionTemplate: description.descriptionTemplate,
descriptionProfileExist: false, descriptionProfileExist: false,
confirmButton: this.language.instant('DESCRIPTION-LISTING.COPY-DIALOG.COPY'), confirmButton: this.language.instant('DESCRIPTION-LISTING.COPY-DIALOG.COPY'),
cancelButton: this.language.instant('DESCRIPTION-LISTING.COPY-DIALOG.CANCEL') cancelButton: this.language.instant('DESCRIPTION-LISTING.COPY-DIALOG.CANCEL')

View File

@ -59,7 +59,7 @@
</button> </button>
</div> </div>
<div *ngIf="description.grant"> <div *ngIf="referenceService.hasRerefenceOfTypes(description?.dmp?.dmpReferences, [referenceTypeEnum.Grants])">
<div class="row header">{{'DESCRIPTION-OVERVIEW.GRANT' | translate}}</div> <div class="row header">{{'DESCRIPTION-OVERVIEW.GRANT' | translate}}</div>
<div class="row description-label">{{referenceService.getReferencesForTypesFirstSafe(description?.dmp?.dmpReferences, [referenceTypeEnum.Grants])?.reference?.label}}</div> <div class="row description-label">{{referenceService.getReferencesForTypesFirstSafe(description?.dmp?.dmpReferences, [referenceTypeEnum.Grants])?.reference?.label}}</div>
</div> </div>
@ -149,7 +149,7 @@
<p class="authors-role">{{ enumUtils.toDmpUserRoleString(dmpUser.role) }}</p> <p class="authors-role">{{ enumUtils.toDmpUserRoleString(dmpUser.role) }}</p>
</div> </div>
</div> </div>
<button *ngIf="isUserOwner && !description.status && dmpUser.role" (click)="removeUserFromDmp(dmpUser)" class="remove-btn">{{ 'GENERAL.CONFIRMATION-DIALOG.ACTIONS.REMOVE' | translate}}</button> <button *ngIf="isUserOwner && description.dmp?.status === dmpStatusEnum.Draft && dmpUser.role === dmpUserRoleEnum.Owner" (click)="removeUserFromDmp(dmpUser)" class="remove-btn">{{ 'DESCRIPTION-OVERVIEW.ACTIONS.REMOVE-AUTHOR' | translate}}</button>
</div> </div>
</div> </div>
<div *ngIf="isUserOwner" class="row mt-3 mb-3 d-flex align-items-center justify-content-center"> <div *ngIf="isUserOwner" class="row mt-3 mb-3 d-flex align-items-center justify-content-center">

View File

@ -55,6 +55,8 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
descriptionStatusEnum = DescriptionStatus; descriptionStatusEnum = DescriptionStatus;
dmpAccessTypeEnum = DmpAccessType; dmpAccessTypeEnum = DmpAccessType;
referenceTypeEnum = ReferenceType; referenceTypeEnum = ReferenceType;
dmpStatusEnum = DmpStatus;
dmpUserRoleEnum = DmpUserRole;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
@ -335,7 +337,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
data: { data: {
formControl: formControl, formControl: formControl,
descriptionId: this.description.id, descriptionId: this.description.id,
descriptionProfileId: this.description.descriptionTemplate.id, descriptionTemplate: this.description.descriptionTemplate,
descriptionProfileExist: false, descriptionProfileExist: false,
confirmButton: this.language.instant('DESCRIPTION-OVERVIEW.COPY-DIALOG.COPY'), confirmButton: this.language.instant('DESCRIPTION-OVERVIEW.COPY-DIALOG.COPY'),
cancelButton: this.language.instant('DESCRIPTION-OVERVIEW.COPY-DIALOG.CANCEL') cancelButton: this.language.instant('DESCRIPTION-OVERVIEW.COPY-DIALOG.CANCEL')
@ -440,6 +442,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
nameof<Description>(x => x.updatedAt), nameof<Description>(x => x.updatedAt),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].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.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.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.label)].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.accessType)].join('.'),

View File

@ -24,7 +24,14 @@ const routes: Routes = [
breadcrumb: true breadcrumb: true
}, },
}, },
{
path: 'overview/:id',
component: DmpOverviewComponent,
data: {
breadcrumb: true,
title: 'GENERAL.TITLES.DMP-OVERVIEW'
},
},
// { // {
// path: 'edit/:id', // path: 'edit/:id',
// component: DmpEditorBlueprintComponent, // component: DmpEditorBlueprintComponent,
@ -43,14 +50,7 @@ const routes: Routes = [
// }, // },
// canDeactivate: [CanDeactivateGuard] // canDeactivate: [CanDeactivateGuard]
// }, // },
// {
// path: 'overview/:id',
// component: DmpOverviewComponent,
// data: {
// breadcrumb: true,
// title: 'GENERAL.TITLES.DMP-OVERVIEW'
// },
// },
// { // {
// path: 'publicOverview/:publicId', // path: 'publicOverview/:publicId',
// component: DmpOverviewComponent, // component: DmpOverviewComponent,

View File

@ -3,12 +3,12 @@
<div *ngIf="dmp"> <div *ngIf="dmp">
<a class="row mb-2 pl-1" (click)="goBack()" role="button"> <a class="row mb-2 pl-1" (click)="goBack()" role="button">
<mat-icon class="back-icon pointer">chevron_left</mat-icon> <mat-icon class="back-icon pointer">chevron_left</mat-icon>
<p class="label-txt pointer">{{'DMP-WIZARD.ACTIONS.BACK' | translate}}</p> <p class="label-txt pointer">{{'DMP-OVERVIEW.ACTIONS.BACK' | translate}}</p>
</a> </a>
<div class="row"> <div class="row">
<div class="col-md-8 col-lg-8 pl-4"> <div class="col-md-8 col-lg-8 pl-4">
<div class="row"> <div class="row">
<span class="dmp-logo">{{ 'DATASET-LISTING.COLUMNS.DMP' | translate }}</span> <span class="dmp-logo">{{ 'DMP-OVERVIEW.TITLE' | translate }}</span>
<p class="dmp-label ml-3 mb-0">{{ dmp.label }}</p> <p class="dmp-label ml-3 mb-0">{{ dmp.label }}</p>
</div> </div>
<div class="row d-flex align-items-center mt-3 mb-4 label-txt"> <div class="row d-flex align-items-center mt-3 mb-4 label-txt">
@ -16,114 +16,114 @@
<p class="ml-0 mb-0 label2-txt"> <p class="ml-0 mb-0 label2-txt">
{{ enumUtils.toDmpUserRolesString(dmpService.getCurrentUserRolesInDmp(dmp?.dmpUsers)) }} {{ enumUtils.toDmpUserRolesString(dmpService.getCurrentUserRolesInDmp(dmp?.dmpUsers)) }}
</div> </div>
<span *ngIf="isUserDmpRelated() && (dmp.isPublic || lockStatus)" class="ml-2 mr-2">.</span> <span *ngIf="isUserDmpRelated() && (isPublishedDmp() || lockStatus)" class="ml-2 mr-2">.</span>
<div *ngIf="dmp.isPublic" class="d-flex flex-row"> <div *ngIf="isPublishedDmp()" class="d-flex flex-row">
<mat-icon class="status-icon">public</mat-icon> <mat-icon class="status-icon">public</mat-icon>
{{'DMP-OVERVIEW.PUBLIC' | translate}} {{'DMP-OVERVIEW.PUBLIC' | translate}}
</div> </div>
<span *ngIf="dmp.isPublic && lockStatus" class="ml-2 mr-2">.</span> <span *ngIf="isPublishedDmp() && lockStatus" class="ml-2 mr-2">.</span>
<div *ngIf="lockStatus" class="d-flex flex-row"> <div *ngIf="lockStatus" class="d-flex flex-row">
<mat-icon class="status-icon">lock_outline</mat-icon> <mat-icon class="status-icon">lock_outline</mat-icon>
{{'DMP-OVERVIEW.LOCKED' | translate}} {{'DMP-OVERVIEW.LOCKED' | translate}}
</div> </div>
<mat-form-field appearance="outline" class="versions-select ml-3 mr-3"> <mat-form-field appearance="outline" class="versions-select ml-3 mr-3">
<mat-select placeholder="{{'DMP-LISTING.VERSION' | translate}} {{dmp.version}}" [(ngModel)]="version" (ngModelChange)="versionChanged(version.id)"> <mat-select placeholder="{{'DMP-OVERVIEW.VERSION' | translate}} {{dmp.version}}" [(ngModel)]="version" (ngModelChange)="versionChanged(version.id)">
<mat-option *ngFor="let version of versions" [value]="version"> <mat-option *ngFor="let version of pastVersions" [value]="version">
{{'DMP-LISTING.VERSION' | translate}} {{version.version}}</mat-option> {{'DMP-OVERVIEW.VERSION' | translate}} {{version.version}}</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<div class="d-flex mr-4">{{'GENERAL.STATUSES.EDIT' | translate}} : <div class="d-flex mr-4">{{'DMP-OVERVIEW.EDITED' | translate}} :
{{dmp.modifiedTime | dateTimeCultureFormatter: "d MMMM y"}} {{dmp.updatedAt | dateTimeCultureFormatter: "d MMMM y"}}
</div> </div>
<div class="d-flex mr-4"> <div class="d-flex mr-4">
<div *ngIf="dmp.status" class="d-flex flex-row uppercase"> <div *ngIf="dmp.status" class="d-flex flex-row uppercase">
<mat-icon class="status-icon">check</mat-icon> <mat-icon class="status-icon">check</mat-icon>
{{'TYPES.DMP.FINALISED' | translate}} {{'DMP-OVERVIEW.FINALISED' | translate}}
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<button *ngIf="isDraftDmp(dmp) && isUserOwner && !lockStatus" (click)="editClicked(dmp)" mat-mini-fab class="mr-3 d-flex justify-content-center align-items-center" matTooltip="{{'DMP-LISTING.ACTIONS.EDIT' | translate}}" matTooltipPosition="above"> <button *ngIf="isDraftDmp(dmp) && isUserOwner && !lockStatus" (click)="editClicked(dmp)" mat-mini-fab class="mr-3 d-flex justify-content-center align-items-center" matTooltip="{{'DMP-OVERVIEW.ACTIONS.EDIT' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-mini-fab-icon">create</mat-icon> <mat-icon class="mat-mini-fab-icon">create</mat-icon>
</button> </button>
<button *ngIf="isAuthenticated()" (click)="cloneOrNewVersionClicked(dmp, false)" mat-mini-fab class="mr-3 d-flex justify-content-center align-items-center" matTooltip="{{'DMP-LISTING.ACTIONS.CLONE' | translate}}" matTooltipPosition="above"> <button *ngIf="isAuthenticated()" (click)="cloneOrNewVersionClicked(dmp, false)" mat-mini-fab class="mr-3 d-flex justify-content-center align-items-center" matTooltip="{{'DMP-OVERVIEW.ACTIONS.CLONE' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-mini-fab-icon">content_copy</mat-icon> <mat-icon class="mat-mini-fab-icon">content_copy</mat-icon>
</button> </button>
<button *ngIf="isUserOwner && !lockStatus" (click)="deleteClicked()" mat-mini-fab class="mr-3 d-flex justify-content-center align-items-center" matTooltip="{{'DMP-LISTING.ACTIONS.DELETE' | translate}}" matTooltipPosition="above"> <button *ngIf="isUserOwner && !lockStatus" (click)="deleteClicked()" mat-mini-fab class="mr-3 d-flex justify-content-center align-items-center" matTooltip="{{'DMP-OVERVIEW.ACTIONS.DELETE' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-mini-fab-icon">delete</mat-icon> <mat-icon class="mat-mini-fab-icon">delete</mat-icon>
</button> </button>
</div> </div>
<div *ngIf="dmp.grant"> <div *ngIf="referenceService.hasRerefenceOfTypes(dmp?.dmpReferences, [referenceTypeEnum.Grants])">
<div class="row header">{{'DMP-OVERVIEW.GRANT' | translate}}</div> <div class="row header">{{'DMP-OVERVIEW.GRANT' | translate}}</div>
<div class="row dmp-label">{{ dmp.grant.label }}</div> <div class="row dmp-label">{{referenceService.getReferencesForTypesFirstSafe(dmp?.dmpReferences, [referenceTypeEnum.Grants])?.reference?.label}}</div>
</div> </div>
<div class="row header">{{'DMP-OVERVIEW.RESEARCHERS' | translate}}</div> <div class="row header">{{'DESCRIPTION-OVERVIEW.RESEARCHERS' | translate}}</div>
<div class="row"> <div class="row">
<div *ngFor="let researcher of dmp.researchers; let last = last"> <div *ngFor="let dmpReference of researchers let last = last">
<span *ngIf="isOrcid(researcher.reference)"> <span *ngIf="isOrcid(dmpReference.reference)">
<a href="{{ getOrcidPathForResearcher(researcher.reference) }}" target="blank" class="researcher"> <a href="{{ getOrcidPathForResearcher(dmpReference.reference?.reference) }}" target="blank" class="researcher">
<div class="id-btn">&nbsp;</div> <div class="id-btn">&nbsp;</div>
<div *ngIf="!last">{{ researcher.name }}, </div> <div *ngIf="!last">{{ dmpReference.reference?.data?.name }}, </div> <!-- TODO: data is missign after refactor -->
<div *ngIf="last">{{ researcher.name }}</div> <div *ngIf="last">{{ dmpReference.reference?.data?.name }}</div><!-- TODO: data is missign after refactor -->
</a> </a>
</span> </span>
<span *ngIf="!isOrcid(researcher.reference)"> <span *ngIf="!isOrcid(dmpReference.reference)">
<div *ngIf="!last">{{ researcher.name }}, </div> <div *ngIf="!last">{{ dmpReference.reference?.data?.name }}, </div> <!-- TODO: data is missign after refactor -->
<div *ngIf="last">{{ researcher.name }}</div> <div *ngIf="last">{{ dmpReference.reference?.data?.name }}</div> <!-- TODO: data is missign after refactor -->
</span> </span>
</div> </div>
<span *ngIf="!dmp.researchers || dmp.researchers.length === 0" class="material-icons">horizontal_rule</span> <span *ngIf="!researchers || researchers.length === 0" class="material-icons">horizontal_rule</span>
</div> </div>
<div class="row header">{{'DATASET-LISTING.COLUMNS.DESCRIPTION' | translate}}</div> <div class="row header">{{'DMP-OVERVIEW.DESCRIPTION' | translate}}</div>
<div class="row" *ngIf="dmp.description"> <div class="row" *ngIf="dmp.description">
<p class="desc-txt" [innerHTML]="dmp.description"></p> <p class="desc-txt" [innerHTML]="dmp.description"></p>
</div> </div>
<div class="row" *ngIf="!dmp.description"> <div class="row" *ngIf="!dmp.description">
<span class="material-icons">horizontal_rule</span> <span class="material-icons">horizontal_rule</span>
</div> </div>
<div class="row header">{{'DMP-OVERVIEW.DESCRIPTIONS-USED' | translate}}</div> <div class="row header">{{'DMP-OVERVIEW.DESCRIPTIONS' | translate}}</div>
<div class="d-flex flex-column"> <div class="d-flex flex-column">
<div *ngFor="let dataset of dmp.datasets"> <div *ngFor="let description of dmp.descriptions">
<a class="row dataset" [routerLink]="isPublicView ? ['/datasets/publicOverview/' + dataset.id] : ['/datasets/overview/' + dataset.id]" target="_blank"> <a class="row description" [routerLink]="isPublicView ? ['/descriptions/publicOverview/' + description.id] : ['/descriptions/overview/' + description.id]" target="_blank">
<button mat-raised-button class="mb-2 mr-2 pl-0 pr-0"> <button mat-raised-button class="mb-2 mr-2 pl-0 pr-0">
<div matTooltip="{{ dataset.label }}" class="col-auto" [ngClass]="{'dataset-btn': dataset.status === 0, 'dataset-finalized-btn': dataset.status === 1}"> <div matTooltip="{{ description.label }}" class="col-auto" [ngClass]="{'description-btn': description.status === descriptionStatusEnum.Draft, 'description-finalized-btn': description.status === descriptionStatusEnum.Finalized}">
<div class="dataset-btn-label">{{ dataset.label }}</div> <div class="description-btn-label">{{ description.label }}</div>
<mat-icon>launch</mat-icon> <mat-icon>launch</mat-icon>
</div> </div>
</button> </button>
</a> </a>
</div> </div>
<div class="row" *ngIf="!dmp.datasets || dmp.datasets.length === 0"> <div class="row" *ngIf="!dmp.descriptions || dmp.descriptions.length === 0">
<span class="material-icons">horizontal_rule</span> <span class="material-icons">horizontal_rule</span>
</div> </div>
</div> </div>
<div class="row mt-2 add-dataset-txt" *ngIf="!lockStatus"> <div class="row mt-2 add-description-txt" *ngIf="!lockStatus">
<a class="add-dataset-btn" *ngIf="isDraftDmp(dmp)" [routerLink]="['/plans/edit/' + dmp.id]" target="_blank"> <a class="add-description-btn" *ngIf="isDraftDmp(dmp)" [routerLink]="['/plans/edit/' + dmp.id]" target="_blank">
<mat-icon>add</mat-icon> <mat-icon>add</mat-icon>
{{'DMP-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}} {{'DMP-OVERVIEW.ACTIONS.ADD-DESCRIPTION' | translate}}
</a> </a>
</div> </div>
</div> </div>
<div class="col-md-4 col-lg-4 p-0"> <div class="col-md-4 col-lg-4 p-0">
<div *ngIf="!hasDoi(dmp)" class="row d-flex flex-column ml-0 mr-0 mb-3"> <div *ngIf="!hasDoi(dmp)" class="row d-flex flex-column ml-0 mr-0 mb-3">
<div class="d-flex align-items-center doi-label"> <div class="d-flex align-items-center doi-label">
<span class="mr-3">{{'DMP-EDITOR.TITLE.SUBTITLE' | translate}}: </span> <span class="mr-3">{{'DMP-OVERVIEW.DOI-PROVIDED' | translate}}: </span>
<ng-container *ngIf="selectedModel"> <ng-container *ngIf="selectedModel">
<mat-select class="max-width-80 select-repo" [placeholder]="selectedModel.repositoryId"> <mat-select class="max-width-80 select-repo" [placeholder]="selectedModel.repositoryId">
<mat-option *ngFor="let doi of dmp.dois" (click)="selectDoi(doi)"> <mat-option *ngFor="let entityDoi of dmp.entityDois" (click)="selectDoi(entityDoi)">
{{doi.repositoryId}} {{entityDoi.repositoryId}}
</mat-option> </mat-option>
</mat-select> </mat-select>
</ng-container> </ng-container>
</div> </div>
<div *ngIf="dmp.dois && selectedModel" class="doi-panel"> <div *ngIf="dmp.entityDois && selectedModel" class="doi-panel">
<span class="ml-3 mr-3">{{selectedModel.doi}}</span> <span class="ml-3 mr-3">{{selectedModel.doi}}</span>
<div class="d-flex justify-content-end ml-3"> <div class="d-flex justify-content-end ml-3">
<button (click)="copyDoi(selectedModel.doi)" mat-mini-fab class="mr-2 d-flex justify-content-center align-items-center" matTooltip="{{'DMP-LISTING.ACTIONS.COPY' | translate}}" matTooltipPosition="above"> <button (click)="copyDoi(selectedModel.doi)" mat-mini-fab class="mr-2 d-flex justify-content-center align-items-center" matTooltip="{{'DMP-OVERVIEW.ACTIONS.COPY' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-mini-fab-icon">content_copy</mat-icon> <mat-icon class="mat-mini-fab-icon">content_copy</mat-icon>
</button> </button>
<button *ngIf="depositRepos?.length > 0" mat-mini-fab class="mr-2 d-flex justify-content-center align-items-center" matTooltip="{{'GRANT-EDITOR.ACTIONS.VISIT-WEBSITE' | translate}}" matTooltipPosition="above"> <button *ngIf="depositRepos?.length > 0" mat-mini-fab class="mr-2 d-flex justify-content-center align-items-center" matTooltip="{{'DMP-OVERVIEW.ACTIONS.VISIT-WEBSITE' | translate}}" matTooltipPosition="above">
<a [href]="createDoiLink(selectedModel)" class="doi-link" target="_blank"> <a [href]="createDoiLink(selectedModel)" class="doi-link" target="_blank">
<mat-icon class="mat-mini-fab-icon">launch</mat-icon> <mat-icon class="mat-mini-fab-icon">launch</mat-icon>
</a> </a>
@ -137,31 +137,31 @@
<button mat-mini-fab class="finalize-btn"> <button mat-mini-fab class="finalize-btn">
<mat-icon class="mat-mini-fab-icon">check</mat-icon> <mat-icon class="mat-mini-fab-icon">check</mat-icon>
</button> </button>
<p class="mb-0 pl-2 finalize-txt">{{ 'DMP-LISTING.ACTIONS.FINALIZE' | translate }}</p> <p class="mb-0 pl-2 finalize-txt">{{ 'DMP-OVERVIEW.ACTIONS.FINALIZE' | translate }}</p>
</div> </div>
<div class="row ml-0 mr-0 pl-4 d-flex align-items-center"> <div class="row ml-0 mr-0 pl-4 d-flex align-items-center">
<hr class="hr-line"> <hr class="hr-line">
</div> </div>
</div> </div>
<app-dmp-deposit-dropdown *ngIf="(hasDoi(dmp) || moreDeposit()) && isFinalizedDmp(dmp) && !this.isPublicView && isUserOwner" [inputRepos]="inputRepos" [dmp]="dmp" (outputReposEmitter)="afterDeposit($event)"></app-dmp-deposit-dropdown> <app-dmp-deposit-dropdown *ngIf="(hasDoi(dmp) || moreDeposit()) && isFinalizedDmp(dmp) && !this.isPublicView && isUserOwner" [inputRepos]="inputRepos" [dmp]="dmp" (outputReposEmitter)="afterDeposit($event)"></app-dmp-deposit-dropdown>
<div *ngIf="isFinalizedDmp(dmp) && hasDoi(dmp) && !isPublishedDMP(dmp) && isUserOwner" (click)="reverseFinalization()" class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center"> <div *ngIf="isFinalizedDmp(dmp) && hasDoi(dmp) && !isPublishedDmp(dmp) && isUserOwner" (click)="reverseFinalization()" class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center">
<button mat-mini-fab class="frame-btn"> <button mat-mini-fab class="frame-btn">
<mat-icon class="mat-mini-fab-icon">unarchive</mat-icon> <mat-icon class="mat-mini-fab-icon">unarchive</mat-icon>
</button> </button>
<p class="mb-0 pl-2 frame-txt">{{ 'DMP-LISTING.ACTIONS.UNFINALIZE' | translate }}</p> <p class="mb-0 pl-2 frame-txt">{{ 'DMP-OVERVIEW.ACTIONS.REVERSE' | translate }}</p>
</div> </div>
<div class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center"> <div class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center">
<button mat-mini-fab class="frame-btn" [matMenuTriggerFor]="exportMenu"> <button mat-mini-fab class="frame-btn" [matMenuTriggerFor]="exportMenu">
<mat-icon class="mat-mini-fab-icon">open_in_new</mat-icon> <mat-icon class="mat-mini-fab-icon">open_in_new</mat-icon>
</button> </button>
<p class="mb-0 mr-0 pl-2 frame-txt" [matMenuTriggerFor]="exportMenu"> <p class="mb-0 mr-0 pl-2 frame-txt" [matMenuTriggerFor]="exportMenu">
{{ 'DMP-LISTING.ACTIONS.EXPORT' | translate }}</p> {{ 'DMP-OVERVIEW.ACTIONS.EXPORT' | translate }}</p>
</div> </div>
<div *ngIf="isUserOwner" class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center" (click)="cloneOrNewVersionClicked(dmp, true)"> <div *ngIf="isUserOwner" class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center" (click)="cloneOrNewVersionClicked(dmp, true)">
<button mat-mini-fab class="frame-btn"> <button mat-mini-fab class="frame-btn">
<mat-icon class="mat-mini-fab-icon">add_to_photos</mat-icon> <mat-icon class="mat-mini-fab-icon">add_to_photos</mat-icon>
</button> </button>
<p class="mb-0 pl-2 frame-txt">{{ 'DMP-LISTING.ACTIONS.START-NEW-VERSION' | translate }} <p class="mb-0 pl-2 frame-txt">{{ 'DMP-OVERVIEW.OVERVIEW.NEW-VERSION' | translate }}
</p> </p>
</div> </div>
<mat-menu #exportMenu="matMenu" xPosition="before"> <mat-menu #exportMenu="matMenu" xPosition="before">
@ -188,25 +188,26 @@
<p class="header">{{ 'DMP-OVERVIEW.DMP-AUTHORS' | translate }}</p> <p class="header">{{ 'DMP-OVERVIEW.DMP-AUTHORS' | translate }}</p>
</div> </div>
<div class="row ml-0 mr-0 pl-4 ml-2 pb-3 d-flex align-items-center"> <div class="row ml-0 mr-0 pl-4 ml-2 pb-3 d-flex align-items-center">
<div *ngFor="let user of dmp.users" class="row authors"> <div *ngFor="let dmpUser of dmp.dmpUsers" class="row authors">
<div class="d-flex flex-row"> <div class="d-flex flex-row">
<button class="account_btn mr-3 pl-0"> <button class="account_btn mr-3 pl-0">
<mat-icon class="account-icon">account_circle</mat-icon> <mat-icon class="account-icon">account_circle</mat-icon>
</button> </button>
<div> <div>
<p class="authors-label">{{ user.name }} <p class="authors-label">{{ dmpUser.user?.name }}
<span *ngIf="isUserAuthor(user.id)">({{ 'DMP-OVERVIEW.YOU' | translate }})</span> <span *ngIf="isUserAuthor(dmpUser.user?.id)">
({{ 'DMP-OVERVIEW.YOU' | translate }})</span>
</p> </p>
<p class="authors-role">{{ enumUtils.toDmpUserRoleString(dmpUser.role) }}</p> <p class="authors-role">{{ enumUtils.toDmpUserRoleString(dmpUser.role) }}</p>
</div> </div>
</div> </div>
<button *ngIf="isUserOwner && !dmp.status && user.role" (click)="removeUserFromDmp(user)" class="remove-btn">{{ 'GENERAL.CONFIRMATION-DIALOG.ACTIONS.REMOVE' | translate}}</button> <button *ngIf="isUserOwner && dmp.status === dmpStatusEnum.Draft && dmpUser.role === dmpUserRoleEnum.Owner" (click)="removeUserFromDmp(dmpUser)" class="remove-btn">{{ 'DMP-OVERVIEW.ACTIONS.REMOVE-AUTHOR' | translate}}</button>
</div> </div>
</div> </div>
<div *ngIf="isUserOwner" class="row mt-3 mb-3 d-flex align-items-center justify-content-center"> <div *ngIf="isUserOwner" class="row mt-3 mb-3 d-flex align-items-center justify-content-center">
<button mat-raised-button class="invite-btn" (click)="openShareDialog(dmp.id,dmp.label)"> <button mat-raised-button class="invite-btn" (click)="openShareDialog(dmp.id,dmp.label)">
<mat-icon>group_add</mat-icon> <mat-icon>group_add</mat-icon>
{{'DMP-LISTING.ACTIONS.INVITE-SHORT' | translate}} {{'DMP-OVERVIEW.ACTIONS.INVITE-SHORT' | translate}}
</button> </button>
</div> </div>
</div> </div>

View File

@ -31,7 +31,9 @@
.account-icon { .account-icon {
font-size: 2.5em; font-size: 2.5em;
} height: auto;
width: auto;
}
// ********BUTTONS******** // ********BUTTONS********
@ -42,7 +44,7 @@
align-self: center; align-self: center;
} }
.dataset-btn { .description-btn {
width: 36.1em; width: 36.1em;
padding: 0 1.1em; padding: 0 1.1em;
background-color: var(--secondary-color); background-color: var(--secondary-color);
@ -52,7 +54,7 @@
// opacity: 0.8; // opacity: 0.8;
} }
.dataset-finalized-btn { .description-finalized-btn {
width: 36.1em; width: 36.1em;
padding: 0 1.1em; padding: 0 1.1em;
background-color: #b2f772; background-color: #b2f772;
@ -179,11 +181,11 @@
margin-bottom: 1.875em; margin-bottom: 1.875em;
} }
.dataset { .description {
width: fit-content; width: fit-content;
} }
.dataset-btn-label { .description-btn-label {
margin-right: 1em; margin-right: 1em;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
@ -291,20 +293,20 @@
} }
.dmp-label, .dmp-label,
.dataset-btn, .description-btn,
.dataset-finalized-btn, .description-finalized-btn,
.add-dataset-btn, .add-description-btn,
.doi-panel, .doi-panel,
.researcher { .researcher {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.add-dataset-btn { .add-description-btn {
color: #212121 !important; color: #212121 !important;
} }
.add-dataset-btn:hover { .add-description-btn:hover {
color: var(--primary-color) !important; color: var(--primary-color) !important;
} }
@ -456,7 +458,7 @@
// color: var(--primary-color-3); // color: var(--primary-color-3);
// } // }
// .dataset-card { // .description-card {
// display: flex; // display: flex;
// flex-direction: column; // flex-direction: column;
// min-width: 0; // min-width: 0;
@ -473,7 +475,7 @@
// box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.14); // box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.14);
// } // }
// .dataset-card h4 { // .description-card h4 {
// padding-left: 1em; // padding-left: 1em;
// margin: 1em 1.5em; // margin: 1em 1.5em;
// } // }
@ -544,12 +546,12 @@
// text-overflow: ellipsis; // text-overflow: ellipsis;
// } // }
// .datasets-counter { // .descriptions-counter {
// display: flex; // display: flex;
// cursor: pointer; // cursor: pointer;
// } // }
// .datasets-counter :hover { // .descriptions-counter :hover {
// color: var(--primary-color-3) !important; // color: var(--primary-color-3) !important;
// } // }

View File

@ -1,61 +1,41 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Params, Router } from '@angular/router'; import { ActivatedRoute, Params, Router } from '@angular/router';
import { DatasetStatus } from '@app/core/common/enum/dataset-status';
import { DmpStatus } from '@app/core/common/enum/dmp-status'; import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { DatasetOverviewModel } from '@app/core/model/dataset/dataset-overview';
import { DatasetsToBeFinalized } from '@app/core/model/dataset/datasets-toBeFinalized';
import { UserInfoListingModel } from '@app/core/model/user/user-info-listing'; import { UserInfoListingModel } from '@app/core/model/user/user-info-listing';
import { AuthService } from '@app/core/services/auth/auth.service'; import { AuthService } from '@app/core/services/auth/auth.service';
import { DmpService, DmpServiceNew } from '@app/core/services/dmp/dmp.service'; import { DmpServiceNew } from '@app/core/services/dmp/dmp.service';
import { import {
SnackBarNotificationLevel, SnackBarNotificationLevel,
UiNotificationService UiNotificationService
} from '@app/core/services/notification/ui-notification-service'; } from '@app/core/services/notification/ui-notification-service';
import {
DmpFinalizeDialogComponent,
DmpFinalizeDialogInput,
DmpFinalizeDialogOutput
} from '@app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
// import {BreadcrumbItem} from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; // import {BreadcrumbItem} from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
import { Location } from '@angular/common'; import { Location } from '@angular/common';
import { UntypedFormGroup } from '@angular/forms'; import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { DmpBlueprintSectionFieldCategory } from '@app/core/common/enum/dmp-blueprint-section-field-category'; import { DmpAccessType } from '@app/core/common/enum/dmp-access-type';
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type'; import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
import { Role } from "@app/core/common/enum/role"; import { ReferenceType } from '@app/core/common/enum/reference-type';
import { DepositConfigurationModel } from '@app/core/model/deposit/deposit-configuration'; import { DepositConfigurationModel } from '@app/core/model/deposit/deposit-configuration';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection, FieldInSection } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { Description } from '@app/core/model/description/description';
import { Dmp, Dmp, DmpUser } from '@app/core/model/dmp/dmp'; import { Dmp, DmpUser } from '@app/core/model/dmp/dmp';
import { DoiModel } from '@app/core/model/doi/doi'; import { DoiModel } from '@app/core/model/doi/doi';
import { VersionListingModel } from '@app/core/model/version/version-listing.model'; import { EntityDoi } from '@app/core/model/entity-doi/entity-doi';
import { DmpReference, Reference } from '@app/core/model/reference/reference';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
import { DepositRepositoriesService } from '@app/core/services/deposit-repositories/deposit-repositories.service'; import { DepositRepositoriesService } from '@app/core/services/deposit-repositories/deposit-repositories.service';
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
import { LockService } from '@app/core/services/lock/lock.service'; import { LockService } from '@app/core/services/lock/lock.service';
import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { MatomoService } from '@app/core/services/matomo/matomo-service';
import { ReferenceService } from '@app/core/services/reference/reference.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { FileUtils } from '@app/core/services/utilities/file-utils.service'; import { FileUtils } from '@app/core/services/utilities/file-utils.service';
import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component';
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
import { Guid } from '@common/types/guid'; import { Guid } from '@common/types/guid';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import * as FileSaver from 'file-saver'; import { takeUntil } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof'; import { nameof } from 'ts-simple-nameof';
import { CloneDialogComponent } from '../clone/clone-dialog/clone-dialog.component';
import { DmpEditorModel } from '../editor/dmp-editor.model';
import { ExtraPropertiesFormModel } from '../editor/general-tab/extra-properties-form.model';
import { FunderFormModel } from '../editor/grant-tab/funder-form-model';
import { GrantTabModel } from '../editor/grant-tab/grant-tab-model';
import { ProjectFormModel } from '../editor/grant-tab/project-form-model';
import { DmpInvitationDialogComponent } from '../invitation/dmp-invitation-dialog.component';
import { StartNewDmpDialogComponent } from '../start-new-dmp-dialogue/start-new-dmp-dialog.component';
import { EntityDoi } from '@app/core/model/entity-doi/entity-doi';
import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
import { DmpAccessType } from '@app/core/common/enum/dmp-access-type';
import { Description } from '@app/core/model/description/description';
@Component({ @Component({
selector: 'app-dmp-overview', selector: 'app-dmp-overview',
@ -65,6 +45,7 @@ import { Description } from '@app/core/model/description/description';
export class DmpOverviewComponent extends BaseComponent implements OnInit { export class DmpOverviewComponent extends BaseComponent implements OnInit {
dmp: Dmp; dmp: Dmp;
researchers: DmpReference[] = [];
isNew = true; isNew = true;
isFinalized = false; isFinalized = false;
isPublicView = true; isPublicView = true;
@ -73,8 +54,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
isUserOwner: boolean; isUserOwner: boolean;
lockStatus: Boolean; lockStatus: Boolean;
textMessage: any; textMessage: any;
versions: VersionListingModel[]; pastVersions: Dmp[]; //TODO: get these from the backend
version: VersionListingModel;
selectedModel: EntityDoi; selectedModel: EntityDoi;
@ViewChild('doi') @ViewChild('doi')
@ -82,7 +62,11 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
depositRepos: DepositConfigurationModel[] = []; depositRepos: DepositConfigurationModel[] = [];
formGroup: UntypedFormGroup; descriptionStatusEnum = DescriptionStatus;
dmpAccessTypeEnum = DmpAccessType;
referenceTypeEnum = ReferenceType;
dmpStatusEnum = DmpStatus;
dmpUserRoleEnum = DmpUserRole;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
@ -99,7 +83,9 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
private location: Location, private location: Location,
private lockService: LockService, private lockService: LockService,
private matomoService: MatomoService, private matomoService: MatomoService,
private fileUtils: FileUtils private fileUtils: FileUtils,
public referenceService: ReferenceService,
public enumUtils: EnumUtils
) { ) {
super(); super();
} }
@ -119,6 +105,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe(data => { .subscribe(data => {
this.dmp = data; this.dmp = data;
this.researchers = this.referenceService.getReferencesForTypes(this.dmp?.dmpReferences, [ReferenceType.Researcher]);
if (!this.hasDoi()) { if (!this.hasDoi()) {
this.selectedModel = this.dmp.entityDois[0]; this.selectedModel = this.dmp.entityDois[0];
} }
@ -146,6 +133,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe(data => { .subscribe(data => {
this.dmp = data; this.dmp = data;
this.researchers = this.referenceService.getReferencesForTypes(this.dmp?.dmpReferences, [ReferenceType.Researcher]);
if (!this.hasDoi()) { if (!this.hasDoi()) {
this.selectedModel = this.dmp.entityDois[0]; this.selectedModel = this.dmp.entityDois[0];
} }
@ -279,7 +267,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
// maxHeight: '80vh', // maxHeight: '80vh',
// data: { // data: {
// formGroup: this.formGroup, // formGroup: this.formGroup,
// datasets: this.dmp.datasets, // descriptions: this.dmp.descriptions,
// isNewVersion: isNewVersion, // isNewVersion: isNewVersion,
// confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.SAVE'), // confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.SAVE'),
// cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'), // cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'),
@ -426,8 +414,8 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
return dmp.status == DmpStatus.Finalized; return dmp.status == DmpStatus.Finalized;
} }
isPublishedDMP(dmp: Dmp) { isPublishedDmp() {
return (dmp.status == DmpStatus.Finalized && dmp.accessType === DmpAccessType.Public); return (this.dmp.status == DmpStatus.Finalized && this.dmp.accessType === DmpAccessType.Public);
} }
hasDoi() { hasDoi() {
@ -471,7 +459,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
// const dialogInputModel: DmpFinalizeDialogInput = { // const dialogInputModel: DmpFinalizeDialogInput = {
// dmpLabel: this.dmp.label, // dmpLabel: this.dmp.label,
// dmpDescription: this.dmp.description, // dmpDescription: this.dmp.description,
// datasets: this.dmp.datasets.map(x => { // descriptions: this.dmp.descriptions.map(x => {
// return { label: x.label, id: x.id, status: x.status } // return { label: x.label, id: x.id, status: x.status }
// }), // }),
// accessRights: extraProperties.visible // accessRights: extraProperties.visible
@ -492,10 +480,10 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
// if (result && !result.cancelled) { // if (result && !result.cancelled) {
// this.checkIfAnyProfileIsUsedLessThanMin(data).subscribe(checked => { // this.checkIfAnyProfileIsUsedLessThanMin(data).subscribe(checked => {
// if (!checked) { // if (!checked) {
// var datasetsToBeFinalized: DatasetsToBeFinalized = { // var descriptionsToBeFinalized: DescriptionsToBeFinalized = {
// uuids: result.datasetsToBeFinalized // uuids: result.descriptionsToBeFinalized
// }; // };
// this.dmpService.finalize(datasetsToBeFinalized, this.dmp.id) // this.dmpService.finalize(descriptionsToBeFinalized, this.dmp.id)
// .pipe(takeUntil(this._destroyed)) // .pipe(takeUntil(this._destroyed))
// .subscribe( // .subscribe(
// complete => { // complete => {
@ -536,8 +524,8 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
// if (!(template.minMultiplicity > 0)) // if (!(template.minMultiplicity > 0))
// return false; // return false;
// let count = 0; // let count = 0;
// dmp.datasets.filter(dataset => dataset.dmpSectionIndex === (section.ordinal - 1)).forEach(dataset => { // dmp.descriptions.filter(description => description.dmpSectionIndex === (section.ordinal - 1)).forEach(description => {
// if (Guid.parse(dataset.profile.id) === template.descriptionTemplateId) { // if (Guid.parse(description.profile.id) === template.descriptionTemplateId) {
// count++; // count++;
// } // }
// }) // })
@ -693,15 +681,13 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
return this.configurationService.orcidPath; return this.configurationService.orcidPath;
} }
isOrcid(reference: string) { isOrcid(reference: Reference) {
const head = reference.split(':')[0]; return reference.source === 'orcid';
return head === 'orcid';
} }
getOrcidPathForResearcher(reference: string): string { getOrcidPathForResearcher(reference: string): string {
const path = this.getOrcidPath(); const path = this.getOrcidPath();
const userId = reference.split(':')[1]; return path + reference;
return path + userId;
} }
checkLockStatus(id: Guid) { checkLockStatus(id: Guid) {
@ -727,24 +713,24 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
nameof<Dmp>(x => x.accessType), nameof<Dmp>(x => x.accessType),
nameof<Dmp>(x => x.version), nameof<Dmp>(x => x.version),
nameof<Dmp>(x => x.groupId), nameof<Dmp>(x => x.groupId),
nameof<Dmp>(x => x.version),
nameof<Dmp>(x => x.updatedAt), nameof<Dmp>(x => x.updatedAt),
[nameof<Dmp>(x => x.entityDois), nameof<EntityDoi>(x => x.id)].join('.'), [nameof<Dmp>(x => x.entityDois), nameof<EntityDoi>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.entityDois), nameof<EntityDoi>(x => x.repositoryId)].join('.'), [nameof<Dmp>(x => x.entityDois), nameof<EntityDoi>(x => x.repositoryId)].join('.'),
[nameof<Dmp>(x => x.entityDois), nameof<EntityDoi>(x => x.doi)].join('.'), [nameof<Dmp>(x => x.entityDois), nameof<EntityDoi>(x => x.doi)].join('.'),
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.id)].join('.'), [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.label)].join('.'), [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.label)].join('.'),
// [nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'), [nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.status)].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<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'), [nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'), [nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.name)].join('.'),
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'), [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<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<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<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<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('.'), [nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.source)].join('.'),
[nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.reference)].join('.'),
] ]
} }
} }

View File

@ -872,16 +872,39 @@
} }
}, },
"DMP-OVERVIEW": { "DMP-OVERVIEW": {
"GRANT": "Grant", "TITLE": "DMP",
"DMP-AUTHORS": "DΜP Authors",
"RESEARCHERS": "Researchers",
"DESCRIPTIONS-USED": "Descriptions used",
"COLLABORATORS": "Collaborators",
"PUBLIC": "Public", "PUBLIC": "Public",
"PRIVATE": "Private",
"LOCKED": "Locked", "LOCKED": "Locked",
"UNLOCKED": "Unlocked", "VERSION":"Version",
"EDITED": "Edited",
"FINALISED": "Finalized",
"GRANT": "Grant",
"RESEARCHERS": "Researchers",
"DESCRIPTION": "Description",
"DESCRIPTIONS": "Descriptions included",
"DOI-PROVIDED": "DOI provided by",
"DMP-AUTHORS": "DΜP Authors",
"YOU": "you", "YOU": "you",
"ACTIONS": {
"BACK":"Back",
"EDIT":"Edit",
"CLONE":"Clone",
"DELETE":"Delete",
"ADD-DESCRIPTION": "Add Description",
"COPY":"Copy",
"FINALIZE":"Finalize",
"VISIT-WEBSITE": "Visit Website",
"REVERSE":"Undo Finalization",
"EXPORT":"Export",
"NEW-VERSION":"Start new version",
"INVITE-SHORT": "Invite",
"REMOVE-AUTHOR": "Remove"
},
"COLLABORATORS": "Collaborators",
"PRIVATE": "Private",
"UNLOCKED": "Unlocked",
"LOCK": "Lock", "LOCK": "Lock",
"TOOLTIP": { "TOOLTIP": {
"LEVEL-OF-ACCESS": "Level of Access", "LEVEL-OF-ACCESS": "Level of Access",
@ -937,7 +960,8 @@
"FINALIZE":"Finalize", "FINALIZE":"Finalize",
"REVERSE":"Undo Finalization", "REVERSE":"Undo Finalization",
"EXPORT":"Export", "EXPORT":"Export",
"INVITE-SHORT": "Invite" "INVITE-SHORT": "Invite",
"REMOVE-AUTHOR": "Remove"
}, },
"COPY-DIALOG": { "COPY-DIALOG": {
"COPY": "Copy", "COPY": "Copy",