fixed tenant-permissions on dmp and description editor

This commit is contained in:
Sofia Papacharalampous 2024-06-19 13:04:51 +03:00
parent 76cefd90bc
commit ae75fd64b0
14 changed files with 219 additions and 89 deletions

View File

@ -8,7 +8,7 @@ import { LoggingService } from '@app/core/services/logging/logging-service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { ProgressIndicationService } from '@app/core/services/progress-indication/progress-indication-service';
import { DescriptionEditorModel } from '@app/ui/description/editor/description-editor.model';
import { DescriptionEditorResolver } from '@app/ui/description/editor/description-editor.resolver';
import { DescriptionEditorEntityResolver } from '@app/ui/description/editor/resolvers/description-editor-entity.resolver';
import { DescriptionFormService } from '@app/ui/description/editor/description-form/components/services/description-form.service';
import { VisibilityRulesService } from '@app/ui/description/editor/description-form/visibility-rules/visibility-rules.service';
import { BaseComponent } from '@common/base/base.component';
@ -52,7 +52,7 @@ export class DescriptionTemplatePreviewDialogComponent extends BaseComponent imp
if (this.data && this.data.descriptionTemplateId) {
this.descriptionTemplateService.getSingle(this.data.descriptionTemplateId, DescriptionEditorResolver.descriptionTemplateLookupFields())
this.descriptionTemplateService.getSingle(this.data.descriptionTemplateId, DescriptionEditorEntityResolver.descriptionTemplateLookupFields())
.pipe(takeUntil(this._destroyed))
.subscribe(item => {
this.descriptionTemplate = item;

View File

@ -42,7 +42,7 @@
</div>
<mat-divider *ngIf="formGroup.get('id').value && (!viewOnly || (!isLocked && !viewOnly) || isLocked || (hasReversableStatus() && !isLocked))" [vertical]="true" class="ml-2 mr-2"></mat-divider>
<mat-divider *ngIf="formGroup.get('id').value && canEdit && (!viewOnly || (!isLocked && canEdit && !viewOnly) || isLocked || (hasReversableStatus() && !isLocked))" [vertical]="true" class="ml-2 mr-2"></mat-divider>
<div *ngIf="!isPristine() && !viewOnly" class="col-auto d-flex align-items-center pr-0">
<button [disabled]="saving" type="button" mat-raised-button class="description-discard-btn" (click)="discardChanges()">
@ -50,7 +50,7 @@
</button>
</div>
<div class="col-auto d-flex align-items-center">
<button [disabled]="saving" *ngIf="!isLocked && !viewOnly && hasReversableStatus() == false" mat-raised-button class="description-save-btn mr-2" type="button">
<button [disabled]="saving" *ngIf="canEdit && !isLocked && !viewOnly && hasReversableStatus() == false" mat-raised-button class="description-save-btn mr-2" type="button">
<span class="d-flex flex-row row">
<span (click)="!saving?formSubmit():null" class="col">{{ 'DESCRIPTION-EDITOR.ACTIONS.SAVE' | translate }}</span>
<mat-divider [vertical]="true"></mat-divider>
@ -66,7 +66,7 @@
<button [disabled]="saving" mat-menu-item (click)="saveAndClose()" type="button">{{ 'DESCRIPTION-EDITOR.ACTIONS.SAVE-AND-CLOSE' | translate }}</button>
<button [disabled]="saving" mat-menu-item (click)="saveAndContinue()" type="button">{{ 'DESCRIPTION-EDITOR.ACTIONS.SAVE-AND-CONTINUE' | translate }}</button>
</mat-menu>
<button [disabled]="saving" *ngIf="!isLocked && !viewOnly && hasReversableStatus() == false && canEdit" mat-raised-button class="description-save-btn mr-2" type="button" (click)="finalize()">{{ 'DESCRIPTION-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
<button [disabled]="saving" *ngIf="canEdit && !isLocked && !viewOnly && hasReversableStatus() == false && canEdit" mat-raised-button class="description-save-btn mr-2" type="button" (click)="finalize()">{{ 'DESCRIPTION-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
<button [disabled]="saving" *ngIf="isLocked" mat-raised-button disabled class="description-save-btn cursor-default" type="button">{{ 'DMP-OVERVIEW.LOCKED' | translate}}</button>
<button [disabled]="saving" *ngIf="hasReversableStatus() && !isLocked && canEdit" mat-raised-button class="description-save-btn mr-2" (click)="reverse()" type="button">{{ 'DESCRIPTION-EDITOR.ACTIONS.REVERSE' | translate }}</button>
</div>

View File

@ -10,7 +10,7 @@ import { IsActive } from '@app/core/common/enum/is-active.enum';
import { LockTargetType } from '@app/core/common/enum/lock-target-type';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { DescriptionTemplate, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplatePage, DescriptionTemplateSection } from '@app/core/model/description-template/description-template';
import { Description, DescriptionPersist, DescriptionSectionPermissionResolver, DescriptionStatusPersist } from '@app/core/model/description/description';
import { Description, DescriptionPersist, DescriptionStatusPersist } from '@app/core/model/description/description';
import { DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { DmpDescriptionTemplate } from '@app/core/model/dmp/dmp';
import { AuthService } from '@app/core/services/auth/auth.service';
@ -21,10 +21,7 @@ import { FileTransformerService } from '@app/core/services/file-transformer/file
import { LockService } from '@app/core/services/lock/lock.service';
import { LoggingService } from '@app/core/services/logging/logging-service';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import {
SnackBarNotificationLevel,
UiNotificationService
} from '@app/core/services/notification/ui-notification-service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
import { VisibilityRulesService } from '@app/ui/description/editor/description-form/visibility-rules/visibility-rules.service';
@ -39,7 +36,7 @@ import { TranslateService } from '@ngx-translate/core';
import { map, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { DescriptionEditorModel, DescriptionFieldIndicator, DescriptionPropertyDefinitionEditorModel } from './description-editor.model';
import { DescriptionEditorResolver } from './description-editor.resolver';
import { DescriptionEditorEntityResolver } from './resolvers/description-editor-entity.resolver';
import { DescriptionEditorService } from './description-editor.service';
import { PrefillDescriptionDialogComponent } from './prefill-description/prefill-description.component';
import { ToCEntry } from './table-of-contents/models/toc-entry';
@ -78,6 +75,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
pageToFieldSetMap: Map<string, DescriptionFieldIndicator[]> = new Map<string, DescriptionFieldIndicator[]>();
private initialTemplateId: string = Guid.EMPTY;
private permissionPerSection: Map<Guid, string[]>;
constructor(
// BaseFormEditor injected dependencies
@ -119,6 +117,10 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
ngOnInit(): void {
this.analyticsService.trackPageView(AnalyticsService.DescriptionEditor);
this.permissionPerSection = this.route.snapshot.data['permissions'] as Map<Guid, string[]> ?? new Map<Guid, string[]>();
this.permissionPerSection = this.route.snapshot.data['permissions'] as Map<Guid, string[]> ?? new Map<Guid, string[]>();
super.ngOnInit();
@ -177,11 +179,10 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
}, 0);
}
});
}
getItem(itemId: Guid, successFunction: (item: Description) => void) {
this.descriptionService.getSingle(itemId, DescriptionEditorResolver.lookupFields())
this.descriptionService.getSingle(itemId, DescriptionEditorEntityResolver.lookupFields())
.pipe(map(data => data as Description), takeUntil(this._destroyed))
.subscribe(
data => successFunction(data),
@ -205,6 +206,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
this.buildForm();
if (this.formGroup && this.editorModel.belongsToCurrentTenant == false) {
this.formGroup.disable();
this.canEdit = false;
}
} catch (error) {
this.logger.error('Could not parse Description item: ' + data + error);
@ -213,16 +215,8 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
}
buildForm() {
const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = {
dmpId: this.item.dmp.id,
sectionIds: [this.item.dmpDescriptionTemplate.sectionId],
permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription, AppPermission.FinalizeDescription, AppPermission.ReviewDescription]
}
this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel)
.pipe(takeUntil(this._destroyed)).subscribe(
permissionPerSection => {
this.canEdit = permissionPerSection && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.EditDescription);
this.canReview = permissionPerSection && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.ReviewDescription);
this.canEdit = this.permissionPerSection && this.permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && this.permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.EditDescription);
this.canReview = this.permissionPerSection && this.permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && this.permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.ReviewDescription);
this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.canEdit, this.visibilityRulesService);
if (this.item.descriptionTemplate?.definition) this.visibilityRulesService.setContext(this.item.descriptionTemplate.definition, this.formGroup.get('properties'));
if (this.item.descriptionTemplate?.definition) this.pageToFieldSetMap = this.mapPageToFieldSet(this.item.descriptionTemplate);;
@ -238,9 +232,6 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
}
this.registerFormListeners();
},
error => this.onCallbackError(error)
);
}
calculateMultiplicityRejectedDmpDescriptionTemplates(section: DmpBlueprintDefinitionSection, descriptions: Description[]): DmpDescriptionTemplate[] {
@ -624,7 +615,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
descriptionTemplateValueChanged(descriptionTemplateId: Guid) {
if (descriptionTemplateId != null) {
this.descriptionTemplateService.getSingle(descriptionTemplateId, DescriptionEditorResolver.descriptionTemplateLookupFields()).pipe(takeUntil(this._destroyed))
this.descriptionTemplateService.getSingle(descriptionTemplateId, DescriptionEditorEntityResolver.descriptionTemplateLookupFields()).pipe(takeUntil(this._destroyed))
.subscribe(descriptionTemplate => {
this.initialTemplateId = descriptionTemplateId.toString();
@ -752,7 +743,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
status: DescriptionStatus.Draft,
hash: this.formGroup.get('hash').value
};
this.descriptionService.persistStatus(dmpUserRemovePersist, DescriptionEditorResolver.lookupFields()).pipe(takeUntil(this._destroyed))
this.descriptionService.persistStatus(dmpUserRemovePersist, DescriptionEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.isFinalized = false;
this.refreshData();

View File

@ -4,7 +4,8 @@ import { AuthGuard } from '@app/core/auth-guard.service';
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
import { PendingChangesGuard } from '@common/forms/pending-form-changes/pending-form-changes-guard.service';
import { DescriptionEditorComponent } from './description-editor.component';
import { DescriptionEditorResolver } from './description-editor.resolver';
import { DescriptionEditorEntityResolver } from './resolvers/description-editor-entity.resolver';
import { DescriptionEditorPermissionsResolver } from './resolvers/description-editor-permissions.resolver';
const routes: Routes = [
{
@ -13,7 +14,8 @@ const routes: Routes = [
component: DescriptionEditorComponent,
canDeactivate: [PendingChangesGuard],
resolve: {
'entity': DescriptionEditorResolver
'entity': DescriptionEditorEntityResolver,
'permissions': DescriptionEditorPermissionsResolver,
},
data: {
breadcrumbs: true,
@ -28,7 +30,8 @@ const routes: Routes = [
component: DescriptionEditorComponent,
canDeactivate: [PendingChangesGuard],
resolve: {
'entity': DescriptionEditorResolver
'entity': DescriptionEditorEntityResolver,
'permissions': DescriptionEditorPermissionsResolver,
},
data: {
breadcrumbs: true,
@ -44,7 +47,8 @@ const routes: Routes = [
component: DescriptionEditorComponent,
canDeactivate: [PendingChangesGuard],
resolve: {
'entity': DescriptionEditorResolver
'entity': DescriptionEditorEntityResolver,
'permissions': DescriptionEditorPermissionsResolver,
},
data: {
breadcrumbs: true,
@ -59,7 +63,8 @@ const routes: Routes = [
component: DescriptionEditorComponent,
canDeactivate: [PendingChangesGuard],
resolve: {
'entity': DescriptionEditorResolver
'entity': DescriptionEditorEntityResolver,
'permissions': DescriptionEditorPermissionsResolver,
},
data: {
breadcrumbs: true,
@ -76,6 +81,6 @@ const routes: Routes = [
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
providers: [DescriptionEditorResolver]
providers: [DescriptionEditorEntityResolver, DescriptionEditorPermissionsResolver]
})
export class DescriptionEditorRoutingModule { }

View File

@ -13,7 +13,7 @@ import { FormService } from "@common/forms/form-service";
import { Guid } from "@common/types/guid";
import { Observable } from "rxjs";
import { takeUntil } from "rxjs/operators";
import { DescriptionEditorResolver } from "../description-editor.resolver";
import { DescriptionEditorEntityResolver } from "../resolvers/description-editor-entity.resolver";
import { IsActive } from "@app/core/common/enum/is-active.enum";
import { DescriptionPrefillingRequestEditorModel } from "./prefill-description-editor.model";
import { HttpErrorHandlingService } from "@common/modules/errors/error-handling/http-error-handling.service";
@ -89,7 +89,7 @@ export class PrefillDescriptionDialogComponent extends BaseComponent implements
next() {
const formData = this.formService.getValue(this.prefillForm.value) as DescriptionPrefillingRequest;
this.prefillingSourceService.generate(formData, DescriptionEditorResolver.descriptionTemplateLookupFieldsForDescrption())
this.prefillingSourceService.generate(formData, DescriptionEditorEntityResolver.descriptionTemplateLookupFieldsForDescrption())
.pipe(takeUntil(this._destroyed)).subscribe(description => {
if (description) {
this.closeDialog(description);

View File

@ -20,7 +20,7 @@ import { concatMap, map, takeUntil, tap } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
@Injectable()
export class DescriptionEditorResolver extends BaseEditorResolver {
export class DescriptionEditorEntityResolver extends BaseEditorResolver {
constructor(
private descriptionService: DescriptionService,
@ -33,16 +33,16 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
public static lookupFields(): string[] {
return [
...DescriptionEditorResolver.descriptionLookupFields(),
...DescriptionEditorResolver.dmpLookupFields(nameof<Description>(x => x.dmp)),
...DescriptionEditorResolver.descriptionTemplateLookupFieldsForDescrption(),
...DescriptionEditorEntityResolver.descriptionLookupFields(),
...DescriptionEditorEntityResolver.dmpLookupFields(nameof<Description>(x => x.dmp)),
...DescriptionEditorEntityResolver.descriptionTemplateLookupFieldsForDescrption(),
]
}
public static cloneLookupFields(): string[] {
return [
...DescriptionEditorResolver.descriptionLookupFields(),
...DescriptionEditorResolver.descriptionTemplateLookupFieldsForDescrption(),
...DescriptionEditorEntityResolver.descriptionLookupFields(),
...DescriptionEditorEntityResolver.descriptionTemplateLookupFieldsForDescrption(),
]
}
@ -155,7 +155,7 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const fields = [
...DescriptionEditorResolver.lookupFields()
...DescriptionEditorEntityResolver.lookupFields()
];
const id = route.paramMap.get('id');
const dmpId = route.paramMap.get('dmpId');
@ -165,7 +165,7 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
if (id != null && copyDmpId == null && dmpSectionId == null) {
return this.descriptionService.getSingle(Guid.parse(id), fields).pipe(tap(d => this.breadcrumbService.addIdResolvedValue(d.id.toString(), d.label)));
} else if (dmpId != null && dmpSectionId != null && copyDmpId == null) {
return this.dmpService.getSingle(Guid.parse(dmpId), DescriptionEditorResolver.dmpLookupFields())
return this.dmpService.getSingle(Guid.parse(dmpId), DescriptionEditorEntityResolver.dmpLookupFields())
.pipe(tap(x => {
this.breadcrumbService.addExcludedParam(dmpId, true);
this.breadcrumbService.addIdResolvedValue(dmpSectionId, this.language.instant("DESCRIPTION-EDITOR.TITLE-NEW"));
@ -178,8 +178,8 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
return description;
}));
} else if (copyDmpId != null && id != null && dmpSectionId != null) {
return this.dmpService.getSingle(Guid.parse(copyDmpId), DescriptionEditorResolver.dmpLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), concatMap(dmp => {
return this.descriptionService.getSingle(Guid.parse(id), DescriptionEditorResolver.cloneLookupFields())
return this.dmpService.getSingle(Guid.parse(copyDmpId), DescriptionEditorEntityResolver.dmpLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), concatMap(dmp => {
return this.descriptionService.getSingle(Guid.parse(id), DescriptionEditorEntityResolver.cloneLookupFields())
.pipe(tap(x => {
this.breadcrumbService.addExcludedParam(copyDmpId, true)
this.breadcrumbService.addExcludedParam(dmpSectionId, true)

View File

@ -0,0 +1,99 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { Description, DescriptionSectionPermissionResolver } from '@app/core/model/description/description';
import { DescriptionService } from '@app/core/services/description/description.service';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
import { BaseEditorResolver } from '@common/base/base-editor.resolver';
import { Guid } from '@common/types/guid';
import { TranslateService } from '@ngx-translate/core';
import { concatMap, map, mergeMap, takeUntil, tap } from 'rxjs/operators';
import { DescriptionEditorEntityResolver } from './description-editor-entity.resolver';
import { AppPermission } from '@app/core/common/enum/permission.enum';
@Injectable()
export class DescriptionEditorPermissionsResolver extends BaseEditorResolver {
constructor(
private descriptionService: DescriptionService,
private breadcrumbService: BreadcrumbService,
private language: TranslateService,
private dmpService: DmpService
) {
super();
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const fields = [
...DescriptionEditorEntityResolver.lookupFields()
];
const id = route.paramMap.get('id');
const dmpId = route.paramMap.get('dmpId');
const dmpSectionId = route.paramMap.get('dmpSectionId');
const copyDmpId = route.paramMap.get('copyDmpId');
// const cloneid = route.paramMap.get('cloneid');
if (id != null && copyDmpId == null && dmpSectionId == null) {
return this.descriptionService.getSingle(Guid.parse(id), fields).pipe(tap(d => this.breadcrumbService.addIdResolvedValue(d.id.toString(), d.label)))
.pipe(mergeMap( description => {
const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = {
dmpId: description.dmp.id,
sectionIds: [description.dmpDescriptionTemplate.sectionId],
permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription, AppPermission.FinalizeDescription, AppPermission.ReviewDescription]
}
return this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel).pipe(takeUntil(this._destroyed));
}));
} else if (dmpId != null && dmpSectionId != null && copyDmpId == null) {
return this.dmpService.getSingle(Guid.parse(dmpId), DescriptionEditorEntityResolver.dmpLookupFields())
.pipe(tap(x => {
this.breadcrumbService.addExcludedParam(dmpId, true);
this.breadcrumbService.addIdResolvedValue(dmpSectionId, this.language.instant("DESCRIPTION-EDITOR.TITLE-NEW"));
}), takeUntil(this._destroyed), map(dmp => {
const description: Description = {};
description.dmp = dmp;
description.dmpDescriptionTemplate = {
sectionId: Guid.parse(dmpSectionId)
}
return description;
}))
.pipe(mergeMap( description => {
const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = {
dmpId: description.dmp.id,
sectionIds: [description.dmpDescriptionTemplate.sectionId],
permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription, AppPermission.FinalizeDescription, AppPermission.ReviewDescription]
}
return this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel).pipe(takeUntil(this._destroyed));
}));
} else if (copyDmpId != null && id != null && dmpSectionId != null) {
return this.dmpService.getSingle(Guid.parse(copyDmpId), DescriptionEditorEntityResolver.dmpLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), concatMap(dmp => {
//TODO
return this.descriptionService.getSingle(Guid.parse(id), DescriptionEditorEntityResolver.cloneLookupFields())
.pipe(tap(x => {
this.breadcrumbService.addExcludedParam(copyDmpId, true)
this.breadcrumbService.addExcludedParam(dmpSectionId, true)
this.breadcrumbService.addIdResolvedValue(id, x.label)
}), takeUntil(this._destroyed), map(description => {
description.id = null;
description.hash = null;
description.status = DescriptionStatus.Draft;
description.dmp = dmp;
description.dmpDescriptionTemplate = {
id: dmp.dmpDescriptionTemplates.filter(x => x.sectionId == Guid.parse(dmpSectionId) && x.descriptionTemplateGroupId == description.descriptionTemplate.groupId)[0].id,
sectionId: Guid.parse(dmpSectionId)
}
return description;
}));
})).pipe(mergeMap( description => {
const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = {
dmpId: description.dmp.id,
sectionIds: [description.dmpDescriptionTemplate.sectionId],
permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription, AppPermission.FinalizeDescription, AppPermission.ReviewDescription]
}
return this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel).pipe(takeUntil(this._destroyed));
}));
}
}
}

View File

@ -8,7 +8,7 @@ import { BaseComponent } from '@common/base/base.component';
import { TranslateService } from '@ngx-translate/core';
import { takeUntil } from 'rxjs/operators';
import { DmpCloneDialogEditorModel } from './dmp-clone-dialog.editor.model';
import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver';
import { DmpEditorEntityResolver } from '../dmp-editor-blueprint/resolvers/dmp-editor-enitity.resolver';
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
import { HttpErrorResponse } from '@angular/common/http';
@ -72,7 +72,7 @@ export class CloneDmpDialogComponent extends BaseComponent {
confirm() {
if (!this.formGroup.valid) { return; }
const value: CloneDmpPersist = this.formGroup.value;
this.dmpService.clone(value, DmpEditorResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe(
this.dmpService.clone(value, DmpEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe(
dmp => this.dialogRef.close(dmp),
error => this.onCallbackError(error)
);

View File

@ -50,7 +50,7 @@ import { TranslateService } from '@ngx-translate/core';
import { map, takeUntil } from 'rxjs/operators';
import { DmpContactPrefillDialogComponent } from '../dmp-contact-prefill-dialog/dmp-contact-prefill-dialog.component';
import { DmpEditorModel, DmpFieldIndicator } from './dmp-editor.model';
import { DmpEditorResolver } from './dmp-editor.resolver';
import { DmpEditorEntityResolver } from './resolvers/dmp-editor-enitity.resolver';
import { DmpEditorService } from './dmp-editor.service';
import { RouterUtilsService } from '@app/core/services/router/router-utils.service';
@ -183,13 +183,13 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
ngOnInit(): void {
this.analyticsService.trackPageView(AnalyticsService.DmpEditor);
this.permissionPerSection = this.route.snapshot.data['permissions'] as Map<Guid, string[]> ?? new Map<Guid, string[]>();
super.ngOnInit();
if (this.isNew === false && this.step === 0) this.nextStep();
}
getItem(itemId: Guid, successFunction: (item: Dmp) => void) {
this.dmpService.getSingle(itemId, DmpEditorResolver.lookupFields())
this.dmpService.getSingle(itemId, DmpEditorEntityResolver.lookupFields())
.pipe(map(data => data as Dmp), takeUntil(this._destroyed))
.subscribe(
data => successFunction(data),
@ -231,14 +231,7 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
sectionIds: data?.blueprint?.definition?.sections?.map(x => x.id),
permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription]
}
this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel)
.pipe(takeUntil(this._destroyed)).subscribe(
complete => {
this.permissionPerSection = complete,
this.buildForm();
},
error => this.onCallbackError(error)
);
} else {
this.buildForm();
}
@ -445,7 +438,7 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
//
//
selectBlueprint() {
this.dmpBlueprintService.getSingle(this.formGroup.get('blueprint').value, DmpEditorResolver.blueprintLookupFields()).pipe(takeUntil(this._destroyed))
this.dmpBlueprintService.getSingle(this.formGroup.get('blueprint').value, DmpEditorEntityResolver.blueprintLookupFields()).pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.selectedBlueprint = data;
this.buildFormAfterBlueprintSelection();
@ -455,7 +448,7 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
}
selectDefaultBlueprint(): void {
this.dmpBlueprintService.getSingle(this.configurationService.defaultBlueprintId, DmpEditorResolver.blueprintLookupFields()).pipe(takeUntil(this._destroyed))
this.dmpBlueprintService.getSingle(this.configurationService.defaultBlueprintId, DmpEditorEntityResolver.blueprintLookupFields()).pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.selectedBlueprint = data;
this.formGroup.get('blueprint').setValue(this.selectedBlueprint.id);

View File

@ -5,9 +5,9 @@ import { AppPermission } from '@app/core/common/enum/permission.enum';
import { PendingChangesGuard } from '@common/forms/pending-form-changes/pending-form-changes-guard.service';
// import { DmpOverviewComponent } from './overview/description-overview.component';
import { AuthGuard } from '@app/core/auth-guard.service';
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
import { DmpEditorComponent } from './dmp-editor.component';
import { DmpEditorResolver } from './dmp-editor.resolver';
import { DmpEditorEntityResolver } from './resolvers/dmp-editor-enitity.resolver';
import { DmpEditorPermissionsResolver } from './resolvers/dmp-editor-permissions.resolver';
const routes: Routes = [
{
@ -28,7 +28,8 @@ const routes: Routes = [
component: DmpEditorComponent,
canDeactivate: [PendingChangesGuard],
resolve: {
'entity': DmpEditorResolver
'entity': DmpEditorEntityResolver,
'permissions': DmpEditorPermissionsResolver
},
data: {
breadcrumb: true,
@ -42,6 +43,6 @@ const routes: Routes = [
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
providers: [DmpEditorResolver]
providers: [DmpEditorEntityResolver, DmpEditorPermissionsResolver]
})
export class DmpEditorRoutingModule { }

View File

@ -16,7 +16,7 @@ import { takeUntil, tap } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
@Injectable()
export class DmpEditorResolver extends BaseEditorResolver {
export class DmpEditorEntityResolver extends BaseEditorResolver {
constructor(private descriptionService: DmpService, private breadcrumbService: BreadcrumbService) {
super();
@ -85,7 +85,7 @@ export class DmpEditorResolver extends BaseEditorResolver {
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
...DmpEditorResolver.blueprintLookupFields(nameof<Dmp>(x => x.blueprint)),
...DmpEditorEntityResolver.blueprintLookupFields(nameof<Dmp>(x => x.blueprint)),
]
}
@ -121,7 +121,7 @@ export class DmpEditorResolver extends BaseEditorResolver {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const fields = [
...DmpEditorResolver.lookupFields()
...DmpEditorEntityResolver.lookupFields()
];
const id = route.paramMap.get('id');
if (id != null) {

View File

@ -0,0 +1,44 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { DescriptionSectionPermissionResolver } from '@app/core/model/description/description';
import { DescriptionService } from '@app/core/services/description/description.service';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
import { BaseEditorResolver } from '@common/base/base-editor.resolver';
import { Guid } from '@common/types/guid';
import { mergeMap, takeUntil, tap } from 'rxjs/operators';
import { DmpEditorEntityResolver } from './dmp-editor-enitity.resolver';
@Injectable()
export class DmpEditorPermissionsResolver extends BaseEditorResolver {
constructor(private dmpService: DmpService,
private breadcrumbService: BreadcrumbService,
private descriptionService: DescriptionService,
) {
super();
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const fields = [
...DmpEditorEntityResolver.lookupFields()
];
const id = route.paramMap.get('id');
if (id != null) {
return this.dmpService
.getSingle(Guid.parse(id), fields)
.pipe(tap(x => this.breadcrumbService.addIdResolvedValue(id, x.label)), takeUntil(this._destroyed))
.pipe(mergeMap( data => {
let descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = {
dmpId: data.id,
sectionIds: data?.blueprint?.definition?.sections?.map(x => x.id),
permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription]
};
return this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel).pipe(takeUntil(this._destroyed));
}
));
}
}
}

View File

@ -9,7 +9,7 @@ import { TranslateService } from '@ngx-translate/core';
import { map, takeUntil } from 'rxjs/operators';
import { DmpNewVersionDialogEditorModel } from './dmp-new-version-dialog.editor.model';
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver';
import { DmpEditorEntityResolver } from '../dmp-editor-blueprint/resolvers/dmp-editor-enitity.resolver';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status';
@ -186,7 +186,7 @@ export class NewVersionDmpDialogComponent extends BaseComponent {
if (formData.descriptions.length > 0){
formData.descriptions = formData.descriptions.filter(x => x.blueprintSectionId != null)
}
this.dmpService.newVersion(formData, DmpEditorResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe(
this.dmpService.newVersion(formData, DmpEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe(
dmp => this.dialogRef.close(dmp),
error => this.onCallbackError(error)
);

View File

@ -28,10 +28,7 @@ import { DmpService } from '@app/core/services/dmp/dmp.service';
import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service';
import { LockService } from '@app/core/services/lock/lock.service';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import {
SnackBarNotificationLevel,
UiNotificationService
} from '@app/core/services/notification/ui-notification-service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
import { ReferenceService } from '@app/core/services/reference/reference.service';
import { UserService } from '@app/core/services/user/user.service';
@ -48,7 +45,7 @@ import { map, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { CloneDmpDialogComponent } from '../clone-dialog/dmp-clone-dialog.component';
import { DmpDeleteDialogComponent } from '../dmp-delete-dialog/dmp-delete-dialog.component';
import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver';
import { DmpEditorEntityResolver } from '../dmp-editor-blueprint/resolvers/dmp-editor-enitity.resolver';
import { DmpFinalizeDialogComponent, DmpFinalizeDialogOutput } from '../dmp-finalize-dialog/dmp-finalize-dialog.component';
import { DmpInvitationDialogComponent } from '../invitation/dialog/dmp-invitation-dialog.component';
import { NewVersionDmpDialogComponent } from '../new-version-dialog/dmp-new-version-dialog.component';
@ -491,7 +488,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
this.dmpService.undoFinalize(this.dmp.id, DmpEditorResolver.lookupFields()).pipe(takeUntil(this._destroyed))
this.dmpService.undoFinalize(this.dmp.id, DmpEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed))
.subscribe(data => {
this.reloadPage();
this.onUpdateCallbackSuccess()