dmp ui fixes

This commit is contained in:
amentis 2024-03-01 18:50:46 +02:00
parent f0c076fe4f
commit b84cd93ce6
13 changed files with 151 additions and 79 deletions

View File

@ -6,8 +6,11 @@ import eu.eudat.convention.ConventionService;
import eu.eudat.data.DmpEntity; import eu.eudat.data.DmpEntity;
import eu.eudat.errorcode.ErrorThesaurusProperties; import eu.eudat.errorcode.ErrorThesaurusProperties;
import org.apache.commons.compress.utils.Lists; import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Scope;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -16,6 +19,7 @@ import java.util.UUID;
public class NewVersionDmpPersist { public class NewVersionDmpPersist {
private UUID id = null; private UUID id = null;
public static final String _id = "id";
private String label = null; private String label = null;
@ -85,6 +89,8 @@ public class NewVersionDmpPersist {
this.hash = hash; this.hash = hash;
} }
@Component(NewVersionDmpPersist.NewVersionDmpPersistValidator.ValidatorName)
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public static class NewVersionDmpPersistValidator extends BaseValidator<NewVersionDmpPersist> { public static class NewVersionDmpPersistValidator extends BaseValidator<NewVersionDmpPersist> {
public static final String ValidatorName = "NewVersionDmpPersistValidator"; public static final String ValidatorName = "NewVersionDmpPersistValidator";

View File

@ -803,7 +803,9 @@ public class DmpServiceImpl implements DmpService {
if (userId != null){ if (userId != null){
user.setUser(userId); user.setUser(userId);
this.assignUsers(id, List.of(user), null); this.assignUsers(id, List.of(user), null);
if (this.userScope.getUserId() != userId){
this.sendDmpInvitationExistingUser(user.getUser(), dmp, user.getRole()); this.sendDmpInvitationExistingUser(user.getUser(), dmp, user.getRole());
}
}else if (user.getEmail() != null) { }else if (user.getEmail() != null) {
this.sendDmpInvitationExternalUser(user.getEmail(),dmp, user.getRole()); this.sendDmpInvitationExternalUser(user.getEmail(),dmp, user.getRole());
} }

View File

@ -85,7 +85,7 @@ export class DmpService {
const options = { params: { f: reqFields } }; const options = { params: { f: reqFields } };
return this.http return this.http
.post<Dmp>(url, item).pipe( .post<Dmp>(url, item, options).pipe(
catchError((error: any) => throwError(error))); catchError((error: any) => throwError(error)));
} }
@ -94,7 +94,7 @@ export class DmpService {
const options = { params: { f: reqFields } }; const options = { params: { f: reqFields } };
return this.http return this.http
.post<Dmp>(url, item).pipe( .post<Dmp>(url, item, options ).pipe(
catchError((error: any) => throwError(error))); catchError((error: any) => throwError(error)));
} }

View File

@ -34,7 +34,7 @@
<div class="col-12" *ngIf="hasDescriptions()"> <div class="col-12" *ngIf="hasDescriptions()">
<h5>{{'DMP-CLONE-DIALOG.FIELDS.DESCRIPTIONS-HINT' | translate}}</h5> <h5>{{'DMP-CLONE-DIALOG.FIELDS.DESCRIPTIONS-HINT' | translate}}</h5>
</div> </div>
<div class="col-12"> <div class="col-12" *ngIf="hasDescriptions()">
<mat-card class="mat-card"> <mat-card class="mat-card">
<mat-selection-list #selectedItems [formControl]="formGroup.get('descriptions')"> <mat-selection-list #selectedItems [formControl]="formGroup.get('descriptions')">
<mat-list-option *ngFor="let description of dmp.descriptions;" [value]="description.id"> <mat-list-option *ngFor="let description of dmp.descriptions;" [value]="description.id">
@ -43,7 +43,7 @@
</mat-selection-list> </mat-selection-list>
</mat-card> </mat-card>
</div> </div>
<div class="col-12" *ngIf="hasDescriptions()"> <div class="col-12" *ngIf="!hasDescriptions()">
<h5 mat-subheader class="p-3">{{'DMP-CLONE-DIALOG.NO-DESCRIPTIONS' | translate}}</h5> <h5 mat-subheader class="p-3">{{'DMP-CLONE-DIALOG.NO-DESCRIPTIONS' | translate}}</h5>
</div> </div>
</div> </div>

View File

@ -8,6 +8,7 @@ import { BaseComponent } from '@common/base/base.component';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { DmpCloneDialogEditorModel } from './dmp-clone-dialog.editor.model'; import { DmpCloneDialogEditorModel } from './dmp-clone-dialog.editor.model';
import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver';
@Component({ @Component({
selector: 'app-dmp-clone-dialog', selector: 'app-dmp-clone-dialog',
@ -37,7 +38,7 @@ export class CloneDmpDialogComponent extends BaseComponent {
} }
hasDescriptions() { hasDescriptions() {
return this.dmp.descriptions.length > 0; return this.dmp.descriptions?.length > 0;
} }
close() { close() {
@ -51,7 +52,7 @@ export class CloneDmpDialogComponent extends BaseComponent {
confirm() { confirm() {
if (!this.formGroup.valid) { return; } if (!this.formGroup.valid) { return; }
const value: CloneDmpPersist = this.formGroup.value; const value: CloneDmpPersist = this.formGroup.value;
this.dmpService.clone(value).pipe(takeUntil(this._destroyed)).subscribe( this.dmpService.clone(value, DmpEditorResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe(
dmp => this.dialogRef.close(dmp), dmp => this.dialogRef.close(dmp),
error => this.onCallbackError(error) error => this.onCallbackError(error)
); );

View File

@ -295,6 +295,7 @@ export class DmpBlueprintValueEditorModel implements DmpBlueprintValuePersist {
this.fieldId = item.fieldId; this.fieldId = item.fieldId;
this.fieldValue = item.fieldValue; this.fieldValue = item.fieldValue;
// TODO check typeId field // TODO check typeId field
if(dmpReferences){
dmpReferences.forEach(dmpReference => { dmpReferences.forEach(dmpReference => {
if(dmpReference.data.blueprintFieldId == this.fieldId){ if(dmpReference.data.blueprintFieldId == this.fieldId){
this.references.push({ this.references.push({
@ -314,6 +315,7 @@ export class DmpBlueprintValueEditorModel implements DmpBlueprintValuePersist {
} }
}) })
}
return this; return this;
} }

View File

@ -18,7 +18,7 @@ import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service'
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; // import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
import { IsActive } from '@app/core/common/enum/is-active.enum'; import { IsActive } from '@app/core/common/enum/is-active.enum';
import { Description } from '@app/core/model/description/description'; import { Description } from '@app/core/model/description/description';
import { DmpBlueprint } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { Dmp, DmpUser } from '@app/core/model/dmp/dmp'; import { Dmp, DmpUser } from '@app/core/model/dmp/dmp';
import { DmpLookup } from '@app/core/query/dmp.lookup'; import { DmpLookup } from '@app/core/query/dmp.lookup';
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
@ -172,6 +172,8 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.id)].join('.'), [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.label)].join('.'), [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.label)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].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.dmp), nameof<Dmp>(x => x.id)].join('.'), // [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),

View File

@ -30,11 +30,11 @@
<div class="dmp-card-actions"> <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" [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(dmp)" [routerLink]="['/plans/edit/' + dmp.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="isDraftDmp(dmp)" [routerLink]="['/plans/edit/' + dmp.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="isDmpOwner(dmp)" (click)="inviteToDmp()"><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="canInviteDmpUsers(dmp)" (click)="inviteToDmp()"><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)="cloneClicked()"><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="canCloneDmp(dmp)" (click)="cloneClicked()"><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(dmp)"><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="!isAuthenticated()" (click)="viewVersions(dmp)"><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(dmp) && isDmpOwner(dmp)" (click)="deleteClicked(dmp.id)"><span class="material-icons icon-align pr-2">delete</span>{{ 'DMP-LISTING.ACTIONS.DELETE' | translate }}</a> <a class="col-auto border-right pointer" *ngIf="isDraftDmp(dmp) && canDeleteDmp(dmp)" (click)="deleteClicked(dmp.id)"><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> <a class="col-auto pointer" *ngIf="isAuthenticated()" [matMenuTriggerFor]="actionsMenu"><span class="material-icons icon-align pl-2">more_horiz</span></a>
</div> </div>
<mat-menu #exportMenu="matMenu" xPosition="before"> <mat-menu #exportMenu="matMenu" xPosition="before">

View File

@ -91,7 +91,9 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
autoFocus: false, autoFocus: false,
restoreFocus: false, restoreFocus: false,
data: { data: {
dmpId: this.dmp.id dmpId: this.dmp.id,
dmpName: this.dmp.label,
blueprint: this.dmp.blueprint
} }
}); });
} }
@ -223,4 +225,28 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
canCreateNewVersion(dmp: Dmp): boolean { canCreateNewVersion(dmp: Dmp): boolean {
return this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.CreateNewVersionDmp); return this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.CreateNewVersionDmp);
} }
canDeleteDmp(dmp: Dmp): boolean {
return this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.DeleteDmp);
}
canCloneDmp(dmp: Dmp): boolean {
return this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.CloneDmp);
}
canFinalizeDmp(dmp: Dmp): boolean {
return this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.FinalizeDmp);
}
canExportDmp(dmp: Dmp): boolean {
return this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.ExportDmp);
}
canInviteDmpUsers(dmp: Dmp): boolean {
return this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.InviteDmpUsers);
}
canAssignDmpUsers(dmp: Dmp): boolean {
return this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.AssignDmpUsers);
}
} }

View File

@ -46,7 +46,7 @@
<div class="col-12" *ngIf="hasDescriptions()"> <div class="col-12" *ngIf="hasDescriptions()">
<h5>{{'DMP-NEW-VERSION-DIALOG.FIELDS.DESCRIPTIONS-HINT' | translate}}</h5> <h5>{{'DMP-NEW-VERSION-DIALOG.FIELDS.DESCRIPTIONS-HINT' | translate}}</h5>
</div> </div>
<div class="col-12"> <div class="col-12" *ngIf="hasDescriptions()">
<mat-card class="mat-card"> <mat-card class="mat-card">
<mat-selection-list #selectedItems [formControl]="formGroup.get('descriptions')"> <mat-selection-list #selectedItems [formControl]="formGroup.get('descriptions')">
<mat-list-option *ngFor="let description of dmp.descriptions;" [value]="description.id"> <mat-list-option *ngFor="let description of dmp.descriptions;" [value]="description.id">
@ -55,7 +55,7 @@
</mat-selection-list> </mat-selection-list>
</mat-card> </mat-card>
</div> </div>
<div class="col-12" *ngIf="hasDescriptions()"> <div class="col-12" *ngIf="!hasDescriptions()">
<h5 mat-subheader class="p-3">{{'DMP-NEW-VERSION-DIALOG.NO-DESCRIPTIONS' | translate}}</h5> <h5 mat-subheader class="p-3">{{'DMP-NEW-VERSION-DIALOG.NO-DESCRIPTIONS' | translate}}</h5>
</div> </div>
</div> </div>

View File

@ -9,6 +9,7 @@ import { TranslateService } from '@ngx-translate/core';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { DmpNewVersionDialogEditorModel } from './dmp-new-version-dialog.editor.model'; import { DmpNewVersionDialogEditorModel } from './dmp-new-version-dialog.editor.model';
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver';
@Component({ @Component({
selector: 'app-dmp-new-version-dialog', selector: 'app-dmp-new-version-dialog',
@ -39,7 +40,7 @@ export class NewVersionDmpDialogComponent extends BaseComponent {
} }
hasDescriptions() { hasDescriptions() {
return this.dmp.descriptions.length > 0; return this.dmp.descriptions?.length > 0;
} }
close() { close() {
@ -53,7 +54,7 @@ export class NewVersionDmpDialogComponent extends BaseComponent {
confirm() { confirm() {
if (!this.formGroup.valid) { return; } if (!this.formGroup.valid) { return; }
const value: NewVersionDmpPersist = this.formGroup.value; const value: NewVersionDmpPersist = this.formGroup.value;
this.dmpService.newVersion(value).pipe(takeUntil(this._destroyed)).subscribe( this.dmpService.newVersion(value, DmpEditorResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe(
dmp => this.dialogRef.close(dmp), dmp => this.dialogRef.close(dmp),
error => this.onCallbackError(error) error => this.onCallbackError(error)
); );

View File

@ -43,14 +43,14 @@
</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-OVERVIEW.ACTIONS.EDIT' | translate}}" matTooltipPosition="above"> --> <!-- <button *ngIf="isDraftDmp(dmp) && isDmpOwner(dmp) && !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"> -->
<button *ngIf="isDraftDmp(dmp) && !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"> <button *ngIf="isDraftDmp(dmp) && !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-OVERVIEW.ACTIONS.CLONE' | translate}}" matTooltipPosition="above"> <button *ngIf="canCloneDmp()" (click)="cloneClicked()" 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-OVERVIEW.ACTIONS.DELETE' | translate}}" matTooltipPosition="above"> <button *ngIf="canDeleteDmp() && !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>
@ -133,7 +133,7 @@
</div> </div>
</div> </div>
<div class="frame mb-3 pt-4 pl-3 pr-5 pb-1"> <div class="frame mb-3 pt-4 pl-3 pr-5 pb-1">
<div *ngIf="isDraftDmp(dmp) && isUserOwner && !lockStatus"> <div *ngIf="isDraftDmp(dmp) && canFinalizeDmp() && !lockStatus">
<div class="row ml-0 mr-0 pl-4 d-flex align-items-center" (click)="finalize(dmp)"> <div class="row ml-0 mr-0 pl-4 d-flex align-items-center" (click)="finalize(dmp)">
<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>
@ -144,8 +144,8 @@
<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.length > 0" [inputRepos]="inputRepos" [dmp]="dmp" (outputReposEmitter)="afterDeposit($event)"></app-dmp-deposit-dropdown> <app-dmp-deposit-dropdown *ngIf="(hasDoi(dmp) || moreDeposit()) && isFinalizedDmp(dmp) && !this.isPublicView && isDmpOwner(dmp) && inputRepos.length > 0" [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) && isDmpOwner(dmp)" (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>
@ -158,7 +158,7 @@
<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-OVERVIEW.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="canCreateNewVersion()" class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center" (click)="newVersionClicked()">
<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>
@ -190,10 +190,10 @@
<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 === dmpStatusEnum.Draft && dmpUser.role != dmpUserRoleEnum.Owner" (click)="removeUserFromDmp(dmpUser)" class="remove-btn">{{ 'DMP-OVERVIEW.ACTIONS.REMOVE-AUTHOR' | translate}}</button> <button *ngIf="isDmpOwner(dmp) && 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="isDmpOwner(dmp)" 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-OVERVIEW.ACTIONS.INVITE-SHORT' | translate}} {{'DMP-OVERVIEW.ACTIONS.INVITE-SHORT' | translate}}

View File

@ -39,6 +39,9 @@ import { nameof } from 'ts-simple-nameof';
import { DmpInvitationDialogComponent } from '../invitation/dialog/dmp-invitation-dialog.component'; import { DmpInvitationDialogComponent } from '../invitation/dialog/dmp-invitation-dialog.component';
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service'; import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { CloneDmpDialogComponent } from '../clone-dialog/dmp-clone-dialog.component';
import { NewVersionDmpDialogComponent } from '../new-version-dialog/dmp-new-version-dialog.component';
import { AppPermission } from '@app/core/common/enum/permission.enum';
@Component({ @Component({
selector: 'app-dmp-overview', selector: 'app-dmp-overview',
@ -55,7 +58,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
isPublicView = true; isPublicView = true;
hasPublishButton: boolean = true; hasPublishButton: boolean = true;
// breadCrumbs: Observable<BreadcrumbItem[]> = observableOf(); // breadCrumbs: Observable<BreadcrumbItem[]> = observableOf();
isUserOwner: boolean; // isUserOwner: boolean;
lockStatus: Boolean; lockStatus: Boolean;
textMessage: any; textMessage: any;
pastVersions: Dmp[]; //TODO: get these from the backend pastVersions: Dmp[]; //TODO: get these from the backend
@ -116,7 +119,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
this.selectedModel = this.dmp.entityDois[0]; this.selectedModel = this.dmp.entityDois[0];
} }
this.checkLockStatus(this.dmp.id); this.checkLockStatus(this.dmp.id);
this.setIsUserOwner(); // this.setIsUserOwner();
this.getAllVersions(this.dmp); this.getAllVersions(this.dmp);
// const breadCrumbs = []; // const breadCrumbs = [];
// breadCrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.MY-DMPS'), url: "/plans" }); // breadCrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.MY-DMPS'), url: "/plans" });
@ -178,13 +181,6 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
this.router.navigate([redirectRoot]); this.router.navigate([redirectRoot]);
} }
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.user?.id));
}
}
isUserAuthor(userId: Guid): boolean { isUserAuthor(userId: Guid): boolean {
if (this.isAuthenticated()) { if (this.isAuthenticated()) {
const principalId: Guid = this.authentication.userId(); const principalId: Guid = this.authentication.userId();
@ -192,37 +188,73 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
} else return false; } else return false;
} }
isDmpOwner(): boolean {
const principalId: Guid = this.authentication.userId();
if (principalId) return !!this.dmp.dmpUsers?.find(x => (x.role === DmpUserRole.Owner) && (principalId === x.id));
}
canCreateNewVersion(): boolean {
return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.CreateNewVersionDmp);
}
canDeleteDmp(): boolean {
return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.DeleteDmp);
}
canCloneDmp(): boolean {
return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.CloneDmp);
}
canFinalizeDmp(): boolean {
return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.FinalizeDmp);
}
canExportDmp(): boolean {
return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.ExportDmp);
}
canInviteDmpUsers(): boolean {
return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.InviteDmpUsers);
}
canAssignDmpUsers(): boolean {
return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.AssignDmpUsers);
}
editClicked(dmp: Dmp) { editClicked(dmp: Dmp) {
this.router.navigate(['/plans/edit/', dmp.id]); this.router.navigate(['/plans/edit/', dmp.id]);
} }
cloneOrNewVersionClicked(dmp: Dmp, isNewVersion: boolean) { cloneClicked() {
//TODO: split the logic here to new version and clone seperately const dialogRef = this.dialog.open(CloneDmpDialogComponent, {
// this.dmpService.getSingle(this.dmp.id).pipe(map(data => data as Dmp)) maxWidth: '700px',
// .pipe(takeUntil(this._destroyed)) maxHeight: '80vh',
// .subscribe(data => { data: {
// this.dmp = new DmpEditorModel(); dmp: this.dmp
// this.dmp.grant = new GrantTabModel(); }
// this.dmp.project = new ProjectFormModel(); });
// this.dmp.funder = new FunderFormModel(); dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: Dmp) => {
// this.dmp.extraProperties = new ExtraPropertiesFormModel(); if (result) {
// this.dmp.fromModel(data); this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
// this.dmp.status = DmpStatus.Draft; this.router.navigate(['/plans/edit/', result.id]);
// this.formGroup = this.dmp.buildForm(); }
});
}
// if (!isNullOrUndefined(this.formGroup.get('profile').value)) { newVersionClicked() {
// this.getBlueprintDefinition(Guid.parse(this.formGroup.get('profile').value), result => { const dialogRef = this.dialog.open(NewVersionDmpDialogComponent, {
// this.checkForGrant(result.definition); maxWidth: '700px',
// this.checkForFunder(result.definition); maxHeight: '80vh',
// this.checkForProject(result.definition); data: {
// }); dmp: this.dmp
// } }
});
// if (!isNewVersion) { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: Dmp) => {
// this.formGroup.get('label').setValue(this.dmp.label + " New"); if (result) {
// } this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
// this.openCloneDialog(isNewVersion); this.router.navigate(['/plans/edit/', result.id]);
// }); }
});
} }
// private checkForGrant(blueprint: DmpBlueprintDefinition) { // private checkForGrant(blueprint: DmpBlueprintDefinition) {