From e0f57fe33db9c717e15404abe8576e94e4eb5e83 Mon Sep 17 00:00:00 2001 From: Irmantas Kaukas Date: Wed, 20 Dec 2023 14:29:38 +0100 Subject: [PATCH] fix: Project Member cannot add instances of resources #DEV-3121 (#1327) --- .../src/app/project/project.component.html | 2 +- .../src/app/project/project.component.ts | 25 ++++++++++++------- .../src/lib/project.service.ts | 6 ++--- .../src/lib/projects/projects.state.ts | 24 +++++++++++------- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/apps/dsp-app/src/app/project/project.component.html b/apps/dsp-app/src/app/project/project.component.html index c11868a073..20e271b43f 100644 --- a/apps/dsp-app/src/app/project/project.component.html +++ b/apps/dsp-app/src/app/project/project.component.html @@ -89,7 +89,7 @@ + [projectMember]="(isAdmin$ | async) || (isMember$ | async)"> diff --git a/apps/dsp-app/src/app/project/project.component.ts b/apps/dsp-app/src/app/project/project.component.ts index c7f20875e6..63df68688f 100644 --- a/apps/dsp-app/src/app/project/project.component.ts +++ b/apps/dsp-app/src/app/project/project.component.ts @@ -2,13 +2,13 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostListener, On import { MatSidenav } from '@angular/material/sidenav'; import { Title } from '@angular/platform-browser'; import { ActivatedRoute, Router } from '@angular/router'; -import { ReadOntology, ReadProject } from '@dasch-swiss/dsp-js'; +import { ReadOntology, ReadProject, ReadUser } from '@dasch-swiss/dsp-js'; import { ClassAndPropertyDefinitions } from '@dasch-swiss/dsp-js/src/models/v2/ontologies/ClassAndPropertyDefinitions'; import { MaterialColor, RouteConstants, getAllEntityDefinitionsAsArray } from '@dasch-swiss/vre/shared/app-config'; import { ProjectService } from '@dasch-swiss/vre/shared/app-helper-services'; -import { OntologiesSelectors, ProjectsSelectors } from '@dasch-swiss/vre/shared/app-state'; +import { OntologiesSelectors, ProjectsSelectors, UserSelectors } from '@dasch-swiss/vre/shared/app-state'; import { Actions, Select, Store } from '@ngxs/store'; -import { Observable, Subscription, of, combineLatest } from 'rxjs'; +import { Observable, Subscription, combineLatest, of } from 'rxjs'; import { map, take } from 'rxjs/operators'; import { ComponentCommunicationEventService, Events } from '../main/services/component-communication-event.service'; import { ProjectBase } from './project-base'; @@ -44,6 +44,14 @@ export class ProjectComponent extends ProjectBase implements OnInit { dataModelsRoute: AvailableRoute = RouteConstants.dataModels; advancedSearchRoute: AvailableRoute = RouteConstants.advancedSearch; + get isMember$(): Observable { + return combineLatest([this.user$, this.userProjectAdminGroups$]).pipe( + map(([user, userProjectAdminGroups]) => + ProjectService.IsProjectMember(user, userProjectAdminGroups, this.projectUuid) + ) + ); + } + get color$(): Observable { return this.readProject$.pipe( map(readProject => (!readProject.status ? MaterialColor.Warn : MaterialColor.Primary)) @@ -84,13 +92,12 @@ export class ProjectComponent extends ProjectBase implements OnInit { ); } + @Select(UserSelectors.user) user$: Observable; + @Select(UserSelectors.userProjects) userProjects$: Observable; @Select(ProjectsSelectors.readProjects) readProjects$: Observable; - @Select(ProjectsSelectors.isProjectsLoading) - isProjectsLoading$: Observable; - @Select(OntologiesSelectors.isLoading) - isOntologiesLoading$: Observable; - @Select(OntologiesSelectors.hasLoadingErrors) - hasLoadingErrors$: Observable; + @Select(ProjectsSelectors.isProjectsLoading) isProjectsLoading$: Observable; + @Select(OntologiesSelectors.isLoading) isOntologiesLoading$: Observable; + @Select(OntologiesSelectors.hasLoadingErrors) hasLoadingErrors$: Observable; constructor( private _componentCommsService: ComponentCommunicationEventService, diff --git a/libs/vre/shared/app-helper-services/src/lib/project.service.ts b/libs/vre/shared/app-helper-services/src/lib/project.service.ts index 3e8a1c5896..9a6e9eb2dc 100644 --- a/libs/vre/shared/app-helper-services/src/lib/project.service.ts +++ b/libs/vre/shared/app-helper-services/src/lib/project.service.ts @@ -43,13 +43,11 @@ export class ProjectService { userProjectGroups.some(e => e === projectIri); static IsMemberOfProjectAdminGroup = (groupsPerProject: { [key: string]: string[] }, projectIri: string): boolean => - groupsPerProject && - groupsPerProject[projectIri] && + (groupsPerProject && groupsPerProject[projectIri]) !== undefined && groupsPerProject[projectIri].indexOf(Constants.ProjectAdminGroupIRI) > -1; static IsMemberOfSystemAdminGroup = (groupsPerProject: { [key: string]: string[] }): boolean => - groupsPerProject && - groupsPerProject[Constants.SystemProjectIRI] && + (groupsPerProject && groupsPerProject[Constants.SystemProjectIRI]) !== undefined && groupsPerProject[Constants.SystemProjectIRI].indexOf(Constants.SystemAdminGroupIRI) > -1; static IsProjectAdmin( diff --git a/libs/vre/shared/app-state/src/lib/projects/projects.state.ts b/libs/vre/shared/app-state/src/lib/projects/projects.state.ts index 4c352517fc..f0e83f8200 100644 --- a/libs/vre/shared/app-state/src/lib/projects/projects.state.ts +++ b/libs/vre/shared/app-state/src/lib/projects/projects.state.ts @@ -8,6 +8,7 @@ import { ProjectResponse, ProjectsResponse, ReadGroup, + ReadUser, UserResponse, } from '@dasch-swiss/dsp-js'; import { DspApiConnectionToken } from '@dasch-swiss/vre/shared/app-config'; @@ -21,15 +22,15 @@ import { IKeyValuePairs } from '../model-interfaces'; import { SetUserAction } from '../user/user.actions'; import { UserSelectors } from '../user/user.selectors'; import { - LoadProjectsAction, - LoadProjectAction, - ClearProjectsAction, - RemoveUserFromProjectAction, AddUserToProjectMembershipAction, - LoadProjectMembersAction, + ClearProjectsAction, + LoadProjectAction, LoadProjectGroupsAction, - UpdateProjectAction, + LoadProjectMembersAction, + LoadProjectsAction, + RemoveUserFromProjectAction, SetProjectMemberAction, + UpdateProjectAction, } from './projects.actions'; import { ProjectsStateModel } from './projects.state-model'; @@ -124,9 +125,14 @@ export class ProjectsState { this.errorHandler.showMessage(error); }, }), - concatMap(() => - ctx.dispatch([new LoadProjectMembersAction(projectUuid), new LoadProjectGroupsAction(projectUuid)]) - ), + concatMap(() => { + const user = this.store.selectSnapshot(UserSelectors.user) as ReadUser; + const userProjectAdminGroups = this.store.selectSnapshot(UserSelectors.userProjectAdminGroups); + const isProjectAdmin = ProjectService.IsProjectAdminOrSysAdmin(user, userProjectAdminGroups, projectIri); + return isProjectAdmin + ? ctx.dispatch([new LoadProjectMembersAction(projectUuid), new LoadProjectGroupsAction(projectUuid)]) + : EMPTY; + }), finalize(() => { ctx.patchState({ isLoading: false }); })