This commit is contained in:
amentis 2024-03-22 17:22:12 +02:00
parent 5e1cbc94a0
commit d69b30df49
8 changed files with 52 additions and 21 deletions

View File

@ -34,6 +34,7 @@ import { TranslateService } from '@ngx-translate/core';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { StartNewDescriptionDialogComponent } from '../start-new-description-dialog/start-new-description-dialog.component';
import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
@Component({
selector: 'app-description-listing-component',
@ -202,6 +203,7 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit
[nameof<Description>(x => x.authorizationFlags), AppPermission.EditDescription].join('.'),
[nameof<Description>(x => x.authorizationFlags), AppPermission.DeleteDescription].join('.'),
[nameof<Description>(x => x.authorizationFlags), AppPermission.InviteDmpUsers].join('.'),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].join('.'),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
@ -210,9 +212,14 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.status)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.label)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), 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.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.dmpUsers), nameof<DmpUser>(x => x.isActive)].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('.'),

View File

@ -8,8 +8,8 @@
<div *ngIf="description.status === descriptionStatusEnum.Finalized" class="col-auto description-title">{{description.label}}</div>
<div *ngIf="description.status === descriptionStatusEnum.Draft" class="col-auto description-title-draft">{{description.label}}</div>
<div class="description-subtitle">
<span *ngIf="canEdit" class="col-auto">{{ enumUtils.toDmpUserRolesString(dmpService.getCurrentUserRolesInDmp(description?.dmp?.dmpUsers)) }}</span>
<span *ngIf="canEdit">.</span>
<span *ngIf="isUserDMPRelated" class="col-auto">{{ enumUtils.toDmpUserRolesString(dmpService.getCurrentUserRolesInDmp(description?.dmp?.dmpUsers)) }}</span>
<span *ngIf="isUserDMPRelated">.</span>
<span class="col-auto" *ngIf="description.status === descriptionStatusEnum.Finalized && description.dmp.accessType === dmpAccessTypeEnum.Public"><span class="material-icons icon-align">public</span>{{'DESCRIPTION-LISTING.STATES.PUBLIC' | translate}}</span>
<span *ngIf="description.status === descriptionStatusEnum.Finalized && description.dmp.accessType != dmpAccessTypeEnum.Public" class="col-auto"><span class="material-icons icon-align">done</span>{{ enumUtils.toDescriptionStatusString(description.status) }}</span>
<span *ngIf="description.status === descriptionStatusEnum.Draft" class=" col-auto draft"><span class="material-icons icon-align">create</span>{{ enumUtils.toDescriptionStatusString(description.status) }}</span>
@ -25,7 +25,7 @@
</a>
<div class="description-card-actions">
<a class="col-auto border-right pointer" *ngIf="fileTransformerService.availableFormats && fileTransformerService.availableFormats.length > 0" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'DESCRIPTION-LISTING.ACTIONS.EXPORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isUserOwner" (click)="openShareDialog(description.dmp.id, description.dmp.label)"><span class="material-icons icon-align pr-2">group_add</span>{{'DESCRIPTION-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="canInviteDmpUsers" (click)="openShareDialog()"><span class="material-icons icon-align pr-2">group_add</span>{{'DESCRIPTION-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" (click)="copyToDmp(description)"><span class="material-icons icon-align pr-2">file_copy</span>{{'DESCRIPTION-LISTING.ACTIONS.COPY-DESCRIPTION' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="canDelete" (click)="deleteClicked(description.id)"><span class="material-icons icon-align pr-2">delete</span>{{ 'DESCRIPTION-LISTING.ACTIONS.DELETE' | translate }}</a>
</div>

View File

@ -47,6 +47,7 @@ export class DescriptionListingItemComponent extends BaseComponent implements On
dmpAccessTypeEnum = DmpAccessType;
canDelete: boolean = false;
canEdit: boolean = false;
canInviteDmpUsers: boolean = false;
constructor(
@ -90,6 +91,9 @@ export class DescriptionListingItemComponent extends BaseComponent implements On
this.canEdit = this.authService.hasPermission(AppPermission.EditDescription) ||
this.description.authorizationFlags?.some(x => x === AppPermission.EditDescription);
this.canInviteDmpUsers = this.authService.hasPermission(AppPermission.InviteDmpUsers) ||
this.description.authorizationFlags?.some(x => x === AppPermission.InviteDmpUsers);
}
setIsUserOwner() {
@ -100,6 +104,11 @@ export class DescriptionListingItemComponent extends BaseComponent implements On
}
}
isUserDMPRelated() {
const principalId: Guid = this.authService.userId();
return this.description.dmp.dmpUsers?.some(x => (x.user.id === principalId));
}
public isAuthenticated(): boolean {
return this.authService.currentAccountIsAuthenticated();
}
@ -151,7 +160,7 @@ export class DescriptionListingItemComponent extends BaseComponent implements On
// });
}
openShareDialog(dmpRowId: any, dmpRowName: any) {
openShareDialog() {
// TODO: This is a shared component. Put it in a seperate module.
const dialogRef = this.dialog.open(DmpInvitationDialogComponent, {
// height: '250px',
@ -159,8 +168,9 @@ export class DescriptionListingItemComponent extends BaseComponent implements On
autoFocus: false,
restoreFocus: false,
data: {
dmpId: dmpRowId,
dmpName: dmpRowName
dmpId: this.description.dmp.id,
dmpName: this.description.dmp.label,
blueprint: this.description.dmp.blueprint
}
});
}

View File

@ -145,7 +145,7 @@
</div>
</div>
<div *ngIf="canInviteDmpUsers" class="row mt-3 mb-3 d-flex align-items-center justify-content-center">
<button mat-raised-button class="invite-btn" (click)="openShareDialog(description.dmp.id, description.dmp.label)">
<button mat-raised-button class="invite-btn" (click)="openShareDialog()">
<mat-icon>group_add</mat-icon>
{{'DESCRIPTION-OVERVIEW.ACTIONS.INVITE-SHORT' | translate}}
</button>

View File

@ -37,6 +37,9 @@ import { AppPermission } from '@app/core/common/enum/permission.enum';
import { DescriptionValidationOutput } from '@app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.component';
import { LockService } from '@app/core/services/lock/lock.service';
import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dialog/dmp-invitation-dialog.component';
import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
@Component({
@ -108,6 +111,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
.pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.description = data;
this.description.dmp.dmpUsers = data.dmp.dmpUsers.filter(x => x.isActive === IsActive.Active);
this.researchers = this.referenceService.getReferencesForTypes(this.description?.dmp?.dmpReferences, [this.referenceTypeService.getResearcherReferenceType()]);
// this.users = this.description.dmp.users;
this.checkLockStatus(this.description.id);
@ -121,7 +125,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
this.description.authorizationFlags?.some(x => x === AppPermission.FinalizeDescription);
this.canInviteDmpUsers = this.authService.hasPermission(AppPermission.InviteDmpUsers) ||
this.description.dmp?.authorizationFlags?.some(x => x === AppPermission.InviteDmpUsers);
this.description.authorizationFlags?.some(x => x === AppPermission.InviteDmpUsers);
// const breadCrumbs = [];
// breadCrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.MY-DESCRIPTION-DESCRIPTIONS'), url: "/descriptions" });
// breadCrumbs.push({ parentComponentName: 'DescriptionListingComponent', label: this.description.label, url: '/descriptions/overview/' + this.description.id });
@ -205,16 +209,16 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
}
openShareDialog(rowId: any, rowName: any) {
// TODO: add dialog
// const dialogRef = this.dialog.open(DmpInvitationDialogComponent, {
// autoFocus: false,
// restoreFocus: false,
// data: {
// dmpId: rowId,
// dmpName: rowName
// }
// });
openShareDialog() {
const dialogRef = this.dialog.open(DmpInvitationDialogComponent, {
autoFocus: false,
restoreFocus: false,
data: {
dmpId: this.description.dmp.id,
dmpName: this.description.dmp.label,
blueprint: this.description.dmp.blueprint
}
});
}
public isAuthenticated(): boolean {
@ -428,7 +432,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
}
hasReversableStatus(description: Description): boolean {
return description.dmp.status == DmpStatus.Draft && description.status == DescriptionStatus.Finalized
return description.dmp.status == DmpStatus.Draft && description.status == DescriptionStatus.Finalized && this.canFinalize
}
reverseFinalization(description: Description) {
@ -471,6 +475,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
[nameof<Description>(x => x.authorizationFlags), AppPermission.EditDescription].join('.'),
[nameof<Description>(x => x.authorizationFlags), AppPermission.DeleteDescription].join('.'),
[nameof<Description>(x => x.authorizationFlags), AppPermission.FinalizeDescription].join('.'),
[nameof<Description>(x => x.authorizationFlags), AppPermission.InviteDmpUsers].join('.'),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].join('.'),
[nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
@ -483,10 +488,15 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.status)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags),AppPermission.InviteDmpUsers].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.label)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), 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.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.user.name)].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.dmpUsers), nameof<DmpUser>(x => x.isActive)].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('.'),

View File

@ -29,7 +29,7 @@
</a>
<div class="dmp-card-actions">
<a class="col-auto border-right pointer" *ngIf="canExportDmp(dmp) && fileTransformerService.availableFormats.length > 0" [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) && canEditDmp(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="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="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>

View File

@ -217,6 +217,10 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error);
}
canEditDmp(dmp: Dmp): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.EditDmp) || this.authentication.hasPermission(AppPermission.EditDmp)) && this.isPublic == false;
}
canCreateNewVersion(dmp: Dmp): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.CreateNewVersionDmp) || this.authentication.hasPermission(AppPermission.CreateNewVersionDmp)) && this.isPublic == false;
}

View File

@ -8,7 +8,7 @@
</button>
</mat-chip-row>
</mat-chip-grid>
<input placeholder="{{'DESCRIPTION-EDITOR.BASE-INFO.FIELDS.TAGS-PLACEHOLDER' | translate}}" #tagInput [formControl]="form" [matChipInputFor]="chipGrid" [matAutocomplete]="auto" [matChipInputSeparatorKeyCodes]="separatorKeysCodes" (matChipInputTokenEnd)="add($event)" />
<input placeholder="{{'DESCRIPTION-EDITOR.BASE-INFO.FIELDS.TAGS-PLACEHOLDER' | translate}}" #tagInput [formControl]="form" [matChipInputFor]="chipGrid" [matAutocomplete]="auto" [matChipInputSeparatorKeyCodes]="separatorKeysCodes" (matChipInputTokenEnd)="add($event)" [readOnly]="form.disabled"/>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngFor="let tag of filteredTags | async" [value]="tag">
{{tag}}