diff --git a/src/app/core/store/provider/provider.selectors.ts b/src/app/core/store/provider/provider.selectors.ts index c63f3b537..1da68985e 100644 --- a/src/app/core/store/provider/provider.selectors.ts +++ b/src/app/core/store/provider/provider.selectors.ts @@ -1,5 +1,6 @@ import { Selector } from '@ngxs/store'; +import { ReviewPermissions } from '@osf/shared/enums'; import { ProviderShortInfoModel } from '@osf/shared/models'; import { ProviderStateModel } from './provider.model'; @@ -10,4 +11,12 @@ export class ProviderSelectors { static getCurrentProvider(state: ProviderStateModel): ProviderShortInfoModel | null { return state.currentProvider; } + + @Selector([ProviderState]) + static hasAdminAccess(state: ProviderStateModel): boolean { + return ( + state.currentProvider?.permissions?.some((permission) => permission === ReviewPermissions.SetUpModeration) || + false + ); + } } diff --git a/src/app/features/moderation/components/moderators-list/moderators-list.component.html b/src/app/features/moderation/components/moderators-list/moderators-list.component.html index b221012f6..65e154244 100644 --- a/src/app/features/moderation/components/moderators-list/moderators-list.component.html +++ b/src/app/features/moderation/components/moderators-list/moderators-list.component.html @@ -1,7 +1,7 @@
- @if (isCurrentUserAdminModerator()) { + @if (hasAdminAccess()) {
(() => ({ @@ -78,17 +80,6 @@ export class ModeratorsListComponent implements OnInit { paginator: this.moderatorsTotalCount() > DEFAULT_TABLE_PARAMS.rows, })); - isCurrentUserAdminModerator = computed(() => { - const currentUserId = this.currentUser()?.id; - const initialModerators = this.initialModerators(); - if (!currentUserId) return false; - - return initialModerators.some( - (moderator: ModeratorModel) => - moderator.userId === currentUserId && moderator.permission === ModeratorPermission.Admin - ); - }); - actions = createDispatchMap({ loadModerators: LoadModerators, updateSearchValue: UpdateModeratorsSearchValue, diff --git a/src/app/features/moderation/components/moderators-table/moderators-table.component.html b/src/app/features/moderation/components/moderators-table/moderators-table.component.html index 15588e823..03af03e71 100644 --- a/src/app/features/moderation/components/moderators-table/moderators-table.component.html +++ b/src/app/features/moderation/components/moderators-table/moderators-table.component.html @@ -37,7 +37,7 @@
- @if (isCurrentUserAdminModerator()) { + @if (hasAdminAccess()) { - @if (isCurrentUserAdminModerator() || currentUserId() === item.id) { + @if (hasAdminAccess() || currentUserId() === item.id) { } diff --git a/src/app/features/moderation/components/moderators-table/moderators-table.component.ts b/src/app/features/moderation/components/moderators-table/moderators-table.component.ts index 058bb7977..80e61d8d7 100644 --- a/src/app/features/moderation/components/moderators-table/moderators-table.component.ts +++ b/src/app/features/moderation/components/moderators-table/moderators-table.component.ts @@ -31,7 +31,7 @@ export class ModeratorsTableComponent { isLoading = input(false); tableParams = input.required(); currentUserId = input.required(); - isCurrentUserAdminModerator = input.required(); + hasAdminAccess = input.required(); update = output(); remove = output(); diff --git a/src/app/features/moderation/mappers/preprint-moderation.mapper.ts b/src/app/features/moderation/mappers/preprint-moderation.mapper.ts index 0912104be..cf4500f0b 100644 --- a/src/app/features/moderation/mappers/preprint-moderation.mapper.ts +++ b/src/app/features/moderation/mappers/preprint-moderation.mapper.ts @@ -50,6 +50,7 @@ export class PreprintModerationMapper { return { id: response.id, name: response.attributes.name, + permissions: response.attributes.permissions, reviewsCommentsAnonymous: response.attributes.reviews_comments_anonymous, reviewsCommentsPrivate: response.attributes.reviews_comments_private, reviewsWorkflow: response.attributes.reviews_workflow, diff --git a/src/app/features/moderation/models/preprint-provider-moderation-info.model.ts b/src/app/features/moderation/models/preprint-provider-moderation-info.model.ts index af069ba44..73649885b 100644 --- a/src/app/features/moderation/models/preprint-provider-moderation-info.model.ts +++ b/src/app/features/moderation/models/preprint-provider-moderation-info.model.ts @@ -1,9 +1,12 @@ +import { ReviewPermissions } from '@osf/shared/enums'; + export interface PreprintProviderModerationInfo { id: string; name: string; - submissionCount?: number; + permissions: ReviewPermissions[]; reviewsCommentsAnonymous: boolean; reviewsCommentsPrivate: boolean; reviewsWorkflow: string; + submissionCount?: number; supportEmail: string | null; } diff --git a/src/app/features/moderation/pages/preprint-moderation/preprint-moderation.component.ts b/src/app/features/moderation/pages/preprint-moderation/preprint-moderation.component.ts index 5a07a1385..90d1538d1 100644 --- a/src/app/features/moderation/pages/preprint-moderation/preprint-moderation.component.ts +++ b/src/app/features/moderation/pages/preprint-moderation/preprint-moderation.component.ts @@ -1,3 +1,5 @@ +import { createDispatchMap } from '@ngxs/store'; + import { TranslatePipe } from '@ngx-translate/core'; import { Tab, TabList, TabPanels, Tabs } from 'primeng/tabs'; @@ -13,6 +15,7 @@ import { IS_MEDIUM, Primitive } from '@osf/shared/helpers'; import { PREPRINT_MODERATION_TABS } from '../../constants'; import { PreprintModerationTab } from '../../enums'; +import { GetPreprintProvider } from '../../store/preprint-moderation'; @Component({ selector: 'osf-preprint-moderation', @@ -41,8 +44,19 @@ export class PreprintModerationComponent implements OnInit { selectedTab = PreprintModerationTab.Submissions; + private readonly actions = createDispatchMap({ getPreprintProvider: GetPreprintProvider }); + ngOnInit(): void { this.selectedTab = this.route.snapshot.firstChild?.data['tab'] as PreprintModerationTab; + + const id = this.route.snapshot.params['providerId']; + + if (!id) { + this.router.navigate(['/not-found']); + return; + } + + this.actions.getPreprintProvider(id); } onTabChange(value: Primitive): void { diff --git a/src/app/features/moderation/services/preprint-moderation.service.ts b/src/app/features/moderation/services/preprint-moderation.service.ts index c33a8dd9b..0696c5f2c 100644 --- a/src/app/features/moderation/services/preprint-moderation.service.ts +++ b/src/app/features/moderation/services/preprint-moderation.service.ts @@ -3,7 +3,7 @@ import { catchError, forkJoin, map, Observable, of, switchMap } from 'rxjs'; import { inject, Injectable } from '@angular/core'; import { ENVIRONMENT } from '@core/provider/environment.provider'; -import { JsonApiResponse, PaginatedData, ResponseJsonApi } from '@osf/shared/models'; +import { PaginatedData, ResponseJsonApi } from '@osf/shared/models'; import { JsonApiService } from '@osf/shared/services'; import { PreprintSubmissionsSort } from '../enums'; @@ -36,7 +36,7 @@ export class PreprintModerationService { const baseUrl = `${this.apiUrl}/providers/preprints/?filter[permissions]=view_actions,set_up_moderation`; return this.jsonApiService - .get>(baseUrl) + .get>(baseUrl) .pipe(map((response) => response.data.map((x) => PreprintModerationMapper.fromPreprintRelatedCounts(x)))); } @@ -44,7 +44,7 @@ export class PreprintModerationService { const baseUrl = `${this.apiUrl}/providers/preprints/${id}/?related_counts=true`; return this.jsonApiService - .get>(baseUrl) + .get>(baseUrl) .pipe(map((response) => PreprintModerationMapper.fromPreprintRelatedCounts(response.data))); } diff --git a/src/app/features/moderation/store/moderators/moderators.state.ts b/src/app/features/moderation/store/moderators/moderators.state.ts index 866b7d17d..51138ccfb 100644 --- a/src/app/features/moderation/store/moderators/moderators.state.ts +++ b/src/app/features/moderation/store/moderators/moderators.state.ts @@ -88,7 +88,7 @@ export class ModeratorsState { } @Action(UpdateModerator) - updateCollectionModerator(ctx: StateContext, action: UpdateModerator) { + updateModerator(ctx: StateContext, action: UpdateModerator) { const state = ctx.getState(); if (!action.resourceType) { @@ -108,7 +108,7 @@ export class ModeratorsState { } @Action(DeleteModerator) - deleteCollectionModerator(ctx: StateContext, action: DeleteModerator) { + deleteModerator(ctx: StateContext, action: DeleteModerator) { const state = ctx.getState(); if (!action.resourceType) { diff --git a/src/app/features/moderation/store/preprint-moderation/preprint-moderation.state.ts b/src/app/features/moderation/store/preprint-moderation/preprint-moderation.state.ts index a8189c0fc..bae189e49 100644 --- a/src/app/features/moderation/store/preprint-moderation/preprint-moderation.state.ts +++ b/src/app/features/moderation/store/preprint-moderation/preprint-moderation.state.ts @@ -5,8 +5,9 @@ import { catchError, forkJoin, map, switchMap, tap } from 'rxjs'; import { inject, Injectable } from '@angular/core'; +import { SetCurrentProvider } from '@core/store/provider'; import { DEFAULT_TABLE_PARAMS } from '@osf/shared/constants'; -import { ResourceType } from '@osf/shared/enums'; +import { CurrentResourceType, ResourceType } from '@osf/shared/enums'; import { handleSectionError } from '@osf/shared/helpers'; import { ContributorsService } from '@osf/shared/services'; @@ -92,6 +93,16 @@ export class PreprintModerationState { tap((data) => { const exists = ctx.getState().preprintProviders.data.some((p) => p.id === data.id); + ctx.dispatch( + new SetCurrentProvider({ + id: data.id, + name: data.name, + type: CurrentResourceType.Preprints, + permissions: data.permissions, + reviewsWorkflow: data.reviewsWorkflow, + }) + ); + ctx.setState( patch({ preprintProviders: patch({