From a9a761ef0aa826513e70cf91c77aca0054a86554 Mon Sep 17 00:00:00 2001 From: mkovalua Date: Tue, 9 Dec 2025 03:19:30 +0200 Subject: [PATCH 1/6] get contributors for registry moderation cards --- .../preprint-submission-item.component.ts | 1 + .../registry-submission-item.component.html | 128 ++++++++++-------- .../registry-submission-item.component.ts | 34 ++++- .../registry-submissions.component.html | 2 + .../registry-submissions.component.ts | 21 ++- .../mappers/registry-moderation.mapper.ts | 4 + .../models/registry-moderation.model.ts | 5 + .../registry-moderation.actions.ts | 15 ++ .../registry-moderation.state.ts | 89 +++++++++++- 9 files changed, 240 insertions(+), 59 deletions(-) diff --git a/src/app/features/moderation/components/preprint-submission-item/preprint-submission-item.component.ts b/src/app/features/moderation/components/preprint-submission-item/preprint-submission-item.component.ts index a20e7b46f..353d17da8 100644 --- a/src/app/features/moderation/components/preprint-submission-item/preprint-submission-item.component.ts +++ b/src/app/features/moderation/components/preprint-submission-item/preprint-submission-item.component.ts @@ -52,6 +52,7 @@ export class PreprintSubmissionItemComponent { hasMoreContributors = computed(() => { const submission = this.submission(); + console.log('submission ', submission); return submission.contributors.length < submission.totalContributors; }); diff --git a/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.html b/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.html index 86c6bbef2..006ce75fc 100644 --- a/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.html +++ b/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.html @@ -1,54 +1,76 @@ -
- - -
- @if (isRejected) { -

{{ submission().title }}

- } @else { - - } - - @if (submission().public && !submission().embargoEndDate) { -

{{ 'registry.overview.statuses.accepted.text' | translate }}

- } - - @if (submission().embargoEndDate) { -

- {{ 'moderation.registryEmbargoedWithEndDate' | translate }} - {{ submission().embargoEndDate | date: 'MMM d, y' }} -

- } - - @for (action of showAll ? submission().actions : submission().actions.slice(0, limitValue); track $index) { -
- {{ registryActionLabel[action.toState] | translate }} - {{ action.dateModified | dateAgo }} - {{ 'moderation.submissionReview.by' | translate }} - {{ action.creator?.name }} - - @if (action.toState === registryActionState.Accepted) { - {{ 'moderation.withNoEmbargo' | translate }} - } - - @if (action.comment.length) { - - } -
- } - - @if (submission().actions.length > 1) { - - } -
+
+ + + +
+ + +
+ @if (isRejected) { +

{{ submission().title }}

+ } @else { + + } + + @if (submission().public && !submission().embargoEndDate) { +

{{ 'registry.overview.statuses.accepted.text' | translate }}

+ } + + @if (submission().embargoEndDate) { +

+ {{ 'moderation.registryEmbargoedWithEndDate' | translate }} + {{ submission().embargoEndDate | date: 'MMM d, y' }} +

+ } + + @for (action of showAll ? submission().actions : submission().actions.slice(0, limitValue); track $index) { +
+ {{ registryActionLabel[action.toState] | translate }} + {{ action.dateModified | dateAgo }} + {{ 'moderation.submissionReview.by' | translate }} + {{ action.creator?.name }} + + @if (action.toState === registryActionState.Accepted) { + {{ 'moderation.withNoEmbargo' | translate }} + } + + @if (action.comment.length) { + + } +
+ } + + @if (submission().actions.length > 1) { + + } +
+
+
+ + +
+

{{ 'common.labels.contributors' | translate }}:

+ + + +
+
+
+
diff --git a/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts b/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts index 38f265cf8..64a3b7473 100644 --- a/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts +++ b/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts @@ -1,10 +1,12 @@ import { TranslatePipe } from '@ngx-translate/core'; +import { Accordion, AccordionContent, AccordionHeader, AccordionPanel } from 'primeng/accordion'; import { Button } from 'primeng/button'; import { DatePipe } from '@angular/common'; -import { ChangeDetectionStrategy, Component, input, output } from '@angular/core'; +import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core'; +import { ContributorsListComponent } from '@osf/shared/components/contributors-list/contributors-list.component'; import { IconComponent } from '@osf/shared/components/icon/icon.component'; import { TruncatedTextComponent } from '@osf/shared/components/truncated-text/truncated-text.component'; import { DateAgoPipe } from '@osf/shared/pipes/date-ago.pipe'; @@ -15,7 +17,19 @@ import { RegistryModeration } from '../../models'; @Component({ selector: 'osf-registry-submission-item', - imports: [IconComponent, DateAgoPipe, Button, TranslatePipe, DatePipe, TruncatedTextComponent], + imports: [ + IconComponent, + DateAgoPipe, + Button, + TranslatePipe, + DatePipe, + TruncatedTextComponent, + Accordion, + AccordionPanel, + AccordionHeader, + AccordionContent, + ContributorsListComponent, + ], templateUrl: './registry-submission-item.component.html', styleUrl: './registry-submission-item.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, @@ -23,6 +37,8 @@ import { RegistryModeration } from '../../models'; export class RegistrySubmissionItemComponent { status = input.required(); submission = input.required(); + loadContributors = output(); + loadMoreContributors = output(); selected = output(); @@ -40,4 +56,18 @@ export class RegistrySubmissionItemComponent { toggleHistory() { this.showAll = !this.showAll; } + + hasMoreContributors = computed(() => { + console.log('hasMoreContributors'); + const submission = this.submission(); + console.log('submission'); + console.log(submission); + console.log('after submission'); + return submission.contributors.length < submission.totalContributors; + }); + + handleOpen() { + console.log('test test'); + this.loadContributors.emit(); + } } diff --git a/src/app/features/moderation/components/registry-submissions/registry-submissions.component.html b/src/app/features/moderation/components/registry-submissions/registry-submissions.component.html index 53a842857..5066d15f7 100644 --- a/src/app/features/moderation/components/registry-submissions/registry-submissions.component.html +++ b/src/app/features/moderation/components/registry-submissions/registry-submissions.component.html @@ -39,6 +39,8 @@ [submission]="item" [status]="selectedReviewOption()" (selected)="navigateToRegistration(item)" + (loadContributors)="loadContributors(item)" + (loadMoreContributors)="loadMoreContributors(item)" >
} diff --git a/src/app/features/moderation/components/registry-submissions/registry-submissions.component.ts b/src/app/features/moderation/components/registry-submissions/registry-submissions.component.ts index 86afd1975..e664daacc 100644 --- a/src/app/features/moderation/components/registry-submissions/registry-submissions.component.ts +++ b/src/app/features/moderation/components/registry-submissions/registry-submissions.component.ts @@ -24,7 +24,12 @@ import { Primitive } from '@osf/shared/helpers/types.helper'; import { REGISTRY_SORT_OPTIONS, SUBMITTED_SUBMISSION_REVIEW_OPTIONS } from '../../constants'; import { RegistrySort, SubmissionReviewStatus } from '../../enums'; import { RegistryModeration } from '../../models'; -import { GetRegistrySubmissions, RegistryModerationSelectors } from '../../store/registry-moderation'; +import { + GetRegistrySubmissionContributors, + GetRegistrySubmissions, + LoadMoreRegistrySubmissionContributors, + RegistryModerationSelectors, +} from '../../store/registry-moderation'; import { RegistrySubmissionItemComponent } from '..'; @Component({ @@ -54,7 +59,11 @@ export class RegistrySubmissionsComponent implements OnInit { this.route.parent?.params.pipe(map((params) => params['providerId'])) ?? of(undefined) ); - readonly actions = createDispatchMap({ getRegistrySubmissions: GetRegistrySubmissions }); + readonly actions = createDispatchMap({ + getRegistrySubmissions: GetRegistrySubmissions, + getRegistrySubmissionContributors: GetRegistrySubmissionContributors, + loadMoreRegistrySubmissionContributors: LoadMoreRegistrySubmissionContributors, + }); readonly submissions = select(RegistryModerationSelectors.getRegistrySubmissions); readonly isLoading = select(RegistryModerationSelectors.areRegistrySubmissionLoading); @@ -112,6 +121,14 @@ export class RegistrySubmissionsComponent implements OnInit { window.open(url, '_blank'); } + loadContributors(item: RegistryModeration) { + this.actions.getRegistrySubmissionContributors(item.id); + } + + loadMoreContributors(item: RegistryModeration) { + this.actions.loadMoreRegistrySubmissionContributors(item.id); + } + private getStatusFromQueryParams() { const queryParams = this.route.snapshot.queryParams; const statusValues = Object.values(SubmissionReviewStatus); diff --git a/src/app/features/moderation/mappers/registry-moderation.mapper.ts b/src/app/features/moderation/mappers/registry-moderation.mapper.ts index 70ab5fdb4..728b59f1c 100644 --- a/src/app/features/moderation/mappers/registry-moderation.mapper.ts +++ b/src/app/features/moderation/mappers/registry-moderation.mapper.ts @@ -12,6 +12,8 @@ import { export class RegistryModerationMapper { static fromResponse(response: RegistryDataJsonApi): RegistryModeration { + console.log(response, 'response mapper'); + return { id: response.id, title: replaceBadEncodedChars(response.attributes.title), @@ -22,6 +24,8 @@ export class RegistryModerationMapper { embargoEndDate: response.attributes.embargo_end_date, actions: [], revisionId: response.embeds?.schema_responses?.data?.[0]?.id || null, + totalContributors: 0, + contributors: [], }; } diff --git a/src/app/features/moderation/models/registry-moderation.model.ts b/src/app/features/moderation/models/registry-moderation.model.ts index cf2cc9662..ade24c589 100644 --- a/src/app/features/moderation/models/registry-moderation.model.ts +++ b/src/app/features/moderation/models/registry-moderation.model.ts @@ -2,6 +2,7 @@ import { RegistrationReviewStates } from '@osf/shared/enums/registration-review- import { RevisionReviewStates } from '@osf/shared/enums/revision-review-states.enum'; import { ReviewAction } from './review-action.model'; +import {ContributorModel} from '@shared/models/contributors/contributor.model'; export interface RegistryModeration { id: string; @@ -13,4 +14,8 @@ export interface RegistryModeration { embargoEndDate: string | null; actions: ReviewAction[]; revisionId?: string | null; + contributorsLoading?: boolean; + contributors: ContributorModel[]; + totalContributors: number; + contributorsPage?: number; } diff --git a/src/app/features/moderation/store/registry-moderation/registry-moderation.actions.ts b/src/app/features/moderation/store/registry-moderation/registry-moderation.actions.ts index 3f7026c0a..3e350142c 100644 --- a/src/app/features/moderation/store/registry-moderation/registry-moderation.actions.ts +++ b/src/app/features/moderation/store/registry-moderation/registry-moderation.actions.ts @@ -12,3 +12,18 @@ export class GetRegistrySubmissions { public sort?: RegistrySort ) {} } + +export class GetRegistrySubmissionContributors { + static readonly type = `${ACTION_SCOPE} Get Registry Submission Contributors`; + + constructor( + public registryId: string, + public page = 1 + ) {} +} + +export class LoadMoreRegistrySubmissionContributors { + static readonly type = `${ACTION_SCOPE} Load More Registry Submission Contributors`; + + constructor(public registryId: string) {} +} diff --git a/src/app/features/moderation/store/registry-moderation/registry-moderation.state.ts b/src/app/features/moderation/store/registry-moderation/registry-moderation.state.ts index a7ac4561b..52b068e89 100644 --- a/src/app/features/moderation/store/registry-moderation/registry-moderation.state.ts +++ b/src/app/features/moderation/store/registry-moderation/registry-moderation.state.ts @@ -1,5 +1,5 @@ import { Action, State, StateContext } from '@ngxs/store'; -import { patch } from '@ngxs/store/operators'; +import { patch, updateItem } from '@ngxs/store/operators'; import { catchError, forkJoin, map, of, switchMap, tap } from 'rxjs'; @@ -7,11 +7,18 @@ import { inject, Injectable } from '@angular/core'; import { handleSectionError } from '@osf/shared/helpers/state-error.handler'; import { PaginatedData } from '@osf/shared/models/paginated-data.model'; +import { DEFAULT_TABLE_PARAMS } from '@shared/constants/default-table-params.constants'; +import { ResourceType } from '@shared/enums/resource-type.enum'; +import { ContributorsService } from '@shared/services/contributors.service'; import { RegistryModeration } from '../../models'; import { RegistryModerationService } from '../../services'; -import { GetRegistrySubmissions } from './registry-moderation.actions'; +import { + GetRegistrySubmissionContributors, + GetRegistrySubmissions, + LoadMoreRegistrySubmissionContributors, +} from './registry-moderation.actions'; import { REGISTRY_MODERATION_STATE_DEFAULTS, RegistryModerationStateModel } from './registry-moderation.model'; @State({ @@ -21,6 +28,84 @@ import { REGISTRY_MODERATION_STATE_DEFAULTS, RegistryModerationStateModel } from @Injectable() export class RegistryModerationState { private readonly registryModerationService = inject(RegistryModerationService); + private readonly contributorsService = inject(ContributorsService); + + @Action(GetRegistrySubmissionContributors) + getRegistrySubmissionContributors( + ctx: StateContext, + { registryId, page }: GetRegistrySubmissionContributors + ) { + const state = ctx.getState(); + const submission = state.submissions.data.find((s) => s.id === registryId); + + if (submission?.contributors && submission.contributors.length > 0 && page === 1) { + return; + } + + ctx.setState( + patch({ + submissions: patch({ + data: updateItem( + (submission) => submission.id === registryId, + patch({ contributorsLoading: true }) + ), + }), + }) + ); + + return this.contributorsService + .getBibliographicContributors(ResourceType.Registration, registryId, page, DEFAULT_TABLE_PARAMS.rows) + .pipe( + tap((res) => { + const currentSubmission = state.submissions.data.find((s) => s.id === registryId); + const existingContributors = currentSubmission?.contributors || []; + const newContributors = page === 1 ? res.data : [...existingContributors, ...res.data]; + + ctx.setState( + patch({ + submissions: patch({ + data: updateItem( + (submission) => submission.id === registryId, + patch({ + contributors: newContributors, + totalContributors: res.totalCount, + contributorsLoading: false, + contributorsPage: page, + }) + ), + }), + }) + ); + }), + catchError((error) => { + ctx.setState( + patch({ + submissions: patch({ + data: updateItem( + (submission) => submission.id === registryId, + patch({ contributorsLoading: false }) + ), + }), + }) + ); + + return handleSectionError(ctx, 'submissions', error); + }) + ); + } + + @Action(LoadMoreRegistrySubmissionContributors) + loadMoreRegistrySubmissionContributors( + ctx: StateContext, + { registryId }: LoadMoreRegistrySubmissionContributors + ) { + const state = ctx.getState(); + const submission = state.submissions.data.find((s) => s.id === registryId); + const currentPage = submission?.contributorsPage || 1; + const nextPage = currentPage + 1; + + return ctx.dispatch(new GetRegistrySubmissionContributors(registryId, nextPage)); + } @Action(GetRegistrySubmissions) getRegistrySubmissions( From dec5cdeb822f382019b75122572e11ec2878416b Mon Sep 17 00:00:00 2001 From: mkovalua Date: Tue, 9 Dec 2025 12:50:43 +0200 Subject: [PATCH 2/6] get contributors for registry pending moderation cards --- ...egistry-pending-submissions.component.html | 2 ++ .../registry-pending-submissions.component.ts | 21 +++++++++++++++++-- .../models/registry-moderation.model.ts | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/app/features/moderation/components/registry-pending-submissions/registry-pending-submissions.component.html b/src/app/features/moderation/components/registry-pending-submissions/registry-pending-submissions.component.html index 8c9be9cf7..77f120b97 100644 --- a/src/app/features/moderation/components/registry-pending-submissions/registry-pending-submissions.component.html +++ b/src/app/features/moderation/components/registry-pending-submissions/registry-pending-submissions.component.html @@ -39,6 +39,8 @@ [submission]="item" [status]="selectedReviewOption()" (selected)="navigateToRegistration(item)" + (loadContributors)="loadContributors(item)" + (loadMoreContributors)="loadMoreContributors(item)" > } diff --git a/src/app/features/moderation/components/registry-pending-submissions/registry-pending-submissions.component.ts b/src/app/features/moderation/components/registry-pending-submissions/registry-pending-submissions.component.ts index 7f21e3fc5..ac0f00e76 100644 --- a/src/app/features/moderation/components/registry-pending-submissions/registry-pending-submissions.component.ts +++ b/src/app/features/moderation/components/registry-pending-submissions/registry-pending-submissions.component.ts @@ -24,7 +24,12 @@ import { Primitive } from '@osf/shared/helpers/types.helper'; import { PENDING_SUBMISSION_REVIEW_OPTIONS, REGISTRY_SORT_OPTIONS } from '../../constants'; import { RegistrySort, SubmissionReviewStatus } from '../../enums'; import { RegistryModeration } from '../../models'; -import { GetRegistrySubmissions, RegistryModerationSelectors } from '../../store/registry-moderation'; +import { + GetRegistrySubmissionContributors, + GetRegistrySubmissions, + LoadMoreRegistrySubmissionContributors, + RegistryModerationSelectors, +} from '../../store/registry-moderation'; import { RegistrySubmissionItemComponent } from '../registry-submission-item/registry-submission-item.component'; @Component({ @@ -54,7 +59,11 @@ export class RegistryPendingSubmissionsComponent implements OnInit { this.route.parent?.params.pipe(map((params) => params['providerId'])) ?? of(undefined) ); - readonly actions = createDispatchMap({ getRegistrySubmissions: GetRegistrySubmissions }); + readonly actions = createDispatchMap({ + getRegistrySubmissions: GetRegistrySubmissions, + getRegistrySubmissionContributors: GetRegistrySubmissionContributors, + loadMoreRegistrySubmissionContributors: LoadMoreRegistrySubmissionContributors, + }); readonly submissions = select(RegistryModerationSelectors.getRegistrySubmissions); readonly isLoading = select(RegistryModerationSelectors.areRegistrySubmissionLoading); @@ -112,6 +121,14 @@ export class RegistryPendingSubmissionsComponent implements OnInit { window.open(url, '_blank'); } + loadContributors(item: RegistryModeration) { + this.actions.getRegistrySubmissionContributors(item.id); + } + + loadMoreContributors(item: RegistryModeration) { + this.actions.loadMoreRegistrySubmissionContributors(item.id); + } + private getStatusFromQueryParams() { const queryParams = this.route.snapshot.queryParams; const statusValues = Object.values(SubmissionReviewStatus); diff --git a/src/app/features/moderation/models/registry-moderation.model.ts b/src/app/features/moderation/models/registry-moderation.model.ts index ade24c589..351b888aa 100644 --- a/src/app/features/moderation/models/registry-moderation.model.ts +++ b/src/app/features/moderation/models/registry-moderation.model.ts @@ -1,8 +1,8 @@ import { RegistrationReviewStates } from '@osf/shared/enums/registration-review-states.enum'; import { RevisionReviewStates } from '@osf/shared/enums/revision-review-states.enum'; +import { ContributorModel } from '@shared/models/contributors/contributor.model'; import { ReviewAction } from './review-action.model'; -import {ContributorModel} from '@shared/models/contributors/contributor.model'; export interface RegistryModeration { id: string; From c59579f70d0562220d87ab293ff3dbbe8d63f3f0 Mon Sep 17 00:00:00 2001 From: mkovalua Date: Tue, 9 Dec 2025 17:11:36 +0200 Subject: [PATCH 3/6] get contributors for collections moderation cards --- .../collection-submission-item.component.html | 2 +- .../collection-submission-item.component.ts | 5 +- ...collection-submissions-list.component.html | 7 +- .../collection-submissions-list.component.ts | 21 ++++- .../collections-moderation.actions.ts | 15 +++ .../collections-moderation.state.ts | 93 +++++++++++++++++++ .../models/collections/collections.models.ts | 3 + 7 files changed, 141 insertions(+), 5 deletions(-) diff --git a/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html b/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html index b5bfb2c65..cebc063fa 100644 --- a/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html +++ b/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html @@ -42,7 +42,7 @@ | }

- {{ attribute.label }}: {{ attribute.value }} + test {{ attribute.label }}: {{ attribute.value }}

} diff --git a/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.ts b/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.ts index c24ba1577..f21ddcae8 100644 --- a/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.ts +++ b/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.ts @@ -4,7 +4,7 @@ import { TranslatePipe } from '@ngx-translate/core'; import { Button } from 'primeng/button'; -import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core'; +import { ChangeDetectionStrategy, Component, computed, inject, input, output } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { collectionFilterNames } from '@osf/features/collections/constants'; @@ -29,7 +29,8 @@ export class CollectionSubmissionItemComponent { private activatedRoute = inject(ActivatedRoute); submission = input.required(); - + loadContributors = output(); + loadMoreContributors = output(); collectionProvider = select(CollectionsSelectors.getCollectionProvider); readonly reviewStatusIcon = ReviewStatusIcon; diff --git a/src/app/features/moderation/components/collection-submissions-list/collection-submissions-list.component.html b/src/app/features/moderation/components/collection-submissions-list/collection-submissions-list.component.html index 5e6d11a21..fc38d9de7 100644 --- a/src/app/features/moderation/components/collection-submissions-list/collection-submissions-list.component.html +++ b/src/app/features/moderation/components/collection-submissions-list/collection-submissions-list.component.html @@ -2,7 +2,12 @@
@for (item of submissions(); track $index) {
- + +
}
diff --git a/src/app/features/moderation/components/collection-submissions-list/collection-submissions-list.component.ts b/src/app/features/moderation/components/collection-submissions-list/collection-submissions-list.component.ts index 1bf63272c..e87f597fd 100644 --- a/src/app/features/moderation/components/collection-submissions-list/collection-submissions-list.component.ts +++ b/src/app/features/moderation/components/collection-submissions-list/collection-submissions-list.component.ts @@ -1,9 +1,15 @@ -import { select } from '@ngxs/store'; +import { createDispatchMap, select } from '@ngxs/store'; import { TranslatePipe } from '@ngx-translate/core'; import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { + GetCollectionSubmissionContributors, + LoadMoreCollectionSubmissionContributors, +} from '@osf/features/moderation/store/collections-moderation'; +import { CollectionSubmissionWithGuid } from '@shared/models/collections/collections.models'; + import { CollectionsModerationSelectors } from '../../store/collections-moderation'; import { CollectionSubmissionItemComponent } from '../collection-submission-item/collection-submission-item.component'; @@ -16,4 +22,17 @@ import { CollectionSubmissionItemComponent } from '../collection-submission-item }) export class CollectionSubmissionsListComponent { submissions = select(CollectionsModerationSelectors.getCollectionSubmissions); + + readonly actions = createDispatchMap({ + getCollectionSubmissionContributors: GetCollectionSubmissionContributors, + loadMoreCollectionSubmissionContributors: LoadMoreCollectionSubmissionContributors, + }); + + loadContributors(item: CollectionSubmissionWithGuid) { + this.actions.getCollectionSubmissionContributors(item.id, 1); + } + + loadMoreContributors(item: CollectionSubmissionWithGuid) { + this.actions.loadMoreCollectionSubmissionContributors(item.id); + } } diff --git a/src/app/features/moderation/store/collections-moderation/collections-moderation.actions.ts b/src/app/features/moderation/store/collections-moderation/collections-moderation.actions.ts index dc44a8e29..a71fbfd7b 100644 --- a/src/app/features/moderation/store/collections-moderation/collections-moderation.actions.ts +++ b/src/app/features/moderation/store/collections-moderation/collections-moderation.actions.ts @@ -29,3 +29,18 @@ export class CreateCollectionSubmissionAction { export class ClearCollectionModeration { static readonly type = '[Collections Moderation] ClearCollectionModeration'; } + +export class GetCollectionSubmissionContributors { + static readonly type = `[Collections Moderation] Get Registry Submission Contributors`; + + constructor( + public collectionId: string, + public page = 1 + ) {} +} + +export class LoadMoreCollectionSubmissionContributors { + static readonly type = `[Collections Moderation] Load More Collection Submission Contributors`; + + constructor(public collectionId: string) {} +} diff --git a/src/app/features/moderation/store/collections-moderation/collections-moderation.state.ts b/src/app/features/moderation/store/collections-moderation/collections-moderation.state.ts index 5e4d94010..ceab73cd8 100644 --- a/src/app/features/moderation/store/collections-moderation/collections-moderation.state.ts +++ b/src/app/features/moderation/store/collections-moderation/collections-moderation.state.ts @@ -6,16 +6,25 @@ import { catchError, forkJoin, map, of, switchMap, tap } from 'rxjs'; import { inject, Injectable } from '@angular/core'; import { CollectionsService } from '@osf/shared/services/collections.service'; +import { DEFAULT_TABLE_PARAMS } from '@shared/constants/default-table-params.constants'; +import { ResourceType } from '@shared/enums/resource-type.enum'; import { handleSectionError } from '@shared/helpers/state-error.handler'; +import { ContributorsService } from '@shared/services/contributors.service'; import { ClearCollectionModeration, CreateCollectionSubmissionAction, + GetCollectionSubmissionContributors, GetCollectionSubmissions, GetSubmissionsReviewActions, + LoadMoreCollectionSubmissionContributors, } from './collections-moderation.actions'; import { COLLECTIONS_MODERATION_STATE_DEFAULTS, CollectionsModerationStateModel } from './collections-moderation.model'; +// import { CollectionSubmissionWithGuid } from '@shared/services/collections.services/models'; +// 'models/collections/collections.models'; +// import { CollectionSubmissionWithGuid } from '@shared/services/collections.services/models'; + @State({ name: 'collectionsModeration', defaults: COLLECTIONS_MODERATION_STATE_DEFAULTS, @@ -23,6 +32,7 @@ import { COLLECTIONS_MODERATION_STATE_DEFAULTS, CollectionsModerationStateModel @Injectable() export class CollectionsModerationState { collectionsService = inject(CollectionsService); + contributorsService = inject(ContributorsService); @Action(GetCollectionSubmissions) getCollectionSubmissions(ctx: StateContext, action: GetCollectionSubmissions) { @@ -117,4 +127,87 @@ export class CollectionsModerationState { clearCollectionModeration(ctx: StateContext) { ctx.setState(COLLECTIONS_MODERATION_STATE_DEFAULTS); } + + @Action(GetCollectionSubmissionContributors) + getCollectionSubmissionContributors( + ctx: StateContext, + action: GetCollectionSubmissionContributors + ) { + const state = ctx.getState(); + const submission = state.collectionSubmissions.data.find((s) => s.id === action.collectionId); + + if (submission?.contributors && submission.contributors.length > 0 && action.page === 1) { + return; + } + + ctx.setState( + patch({ + collectionSubmissions: { + ...state.collectionSubmissions, + isSubmitting: true, + }, + }) + ); + + return this.contributorsService + .getBibliographicContributors( + ResourceType.Collection, + action.collectionId, + action.page, + DEFAULT_TABLE_PARAMS.rows + ) + .pipe( + tap((res) => { + const currentSubmission = state.collectionSubmissions.data.find((s) => s.id === action.collectionId); + const existingContributors = currentSubmission?.contributors || []; + const newContributors = action.page === 1 ? res.data : [...existingContributors, ...res.data]; + + ctx.patchState({ + collectionSubmissions: { + ...state.collectionSubmissions, + data: state.collectionSubmissions.data.map((submission) => + submission.id === action.collectionId + ? { + ...submission, + contributors: newContributors, + totalContributors: res.totalCount, + contributorsLoading: false, + contributorsPage: action.page, + } + : submission + ), + }, + }); + }), + catchError((error) => { + ctx.patchState({ + collectionSubmissions: { + ...state.collectionSubmissions, + data: state.collectionSubmissions.data.map((submission) => + submission.id === action.collectionId + ? { + ...submission, + contributorsLoading: false, + } + : submission + ), + }, + }); + return handleSectionError(ctx, 'collectionSubmissions', error); + }) + ); + } + + @Action(LoadMoreCollectionSubmissionContributors) + loadMoreCollectionSubmissionContributors( + ctx: StateContext, + action: LoadMoreCollectionSubmissionContributors + ) { + const state = ctx.getState(); + const submission = state.collectionSubmissions.data.find((s) => s.id === action.collectionId); + const currentPage = submission?.contributorsPage || 1; + const nextPage = currentPage + 1; + + return ctx.dispatch(new GetCollectionSubmissionContributors(action.collectionId, nextPage)); + } } diff --git a/src/app/shared/models/collections/collections.models.ts b/src/app/shared/models/collections/collections.models.ts index 887851807..b50125b8c 100644 --- a/src/app/shared/models/collections/collections.models.ts +++ b/src/app/shared/models/collections/collections.models.ts @@ -89,6 +89,9 @@ export interface CollectionSubmissionWithGuid { fullName: string; }; actions?: CollectionSubmissionReviewAction[]; + totalContributors?: number; + contributorsLoading?: boolean; + contributorsPage?: number; } export type CollectionSubmissionActionType = 'collection_submission_actions'; From 0cef559e4af5ece781d691d7c5b631488d6dadbf Mon Sep 17 00:00:00 2001 From: mkovalua Date: Wed, 10 Dec 2025 23:06:29 +0200 Subject: [PATCH 4/6] get contributors for collections moderation cards --- .../collection-submission-item.component.html | 117 +++++++++++------- .../collection-submission-item.component.ts | 26 +++- .../preprint-submission-item.component.ts | 2 +- .../registry-submission-item.component.ts | 2 +- 4 files changed, 100 insertions(+), 47 deletions(-) diff --git a/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html b/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html index cebc063fa..91af5bc0c 100644 --- a/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html +++ b/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html @@ -2,53 +2,82 @@ @let attributes = currentSubmissionAttributes(); @if (action && attributes) { -
-
- +
+ + + +
+
+
+ - -
+ +
-

- @switch (action.toState) { - @case (SubmissionReviewStatus.Pending) { - {{ 'moderation.submissionReview.submitted' | translate }} - } - @case (SubmissionReviewStatus.Accepted) { - @if (!collectionProvider()?.reviewsWorkflow) { - {{ 'moderation.submissionReview.submitted' | translate }} - } @else { - {{ 'moderation.submissionReview.accepted' | translate }} - } - } - @case (SubmissionReviewStatus.Rejected) { - {{ 'moderation.submissionReview.rejected' | translate }} - } - @case (SubmissionReviewStatus.Removed) { - {{ 'moderation.submissionReview.withdrawn' | translate }} - } - } - {{ action.dateCreated | dateAgo }} - {{ 'moderation.submissionReview.by' | translate }} - {{ action.createdBy }} -

+

+ @switch (action.toState) { + @case (SubmissionReviewStatus.Pending) { + {{ 'moderation.submissionReview.submitted' | translate }} + } + @case (SubmissionReviewStatus.Accepted) { + @if (!collectionProvider()?.reviewsWorkflow) { + {{ 'moderation.submissionReview.submitted' | translate }} + } @else { + {{ 'moderation.submissionReview.accepted' | translate }} + } + } + @case (SubmissionReviewStatus.Rejected) { + {{ 'moderation.submissionReview.rejected' | translate }} + } + @case (SubmissionReviewStatus.Removed) { + {{ 'moderation.submissionReview.withdrawn' | translate }} + } + } + {{ action.dateCreated | dateAgo }} + {{ 'moderation.submissionReview.by' | translate }} + {{ action.createdBy }} +

-
- @for (attribute of attributes; track attribute.key) { - @if (!$first) { - | - } -

- test {{ attribute.label }}: {{ attribute.value }} -

- } -
+
+ @for (attribute of attributes; track attribute.key) { + @if (!$first) { + | + } +

+ test {{ attribute.label }}: {{ attribute.value }} +

+ } +
- @if (action.comment) { - - } + @if (action.comment) { + + } +
+
+ + + +
+

{{ 'common.labels.contributors' | translate }}:

+

{{ !!submission().contributorsLoading }}

+ + +
+
+ +
} diff --git a/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.ts b/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.ts index f21ddcae8..2f06693b7 100644 --- a/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.ts +++ b/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.ts @@ -16,10 +16,23 @@ import { CollectionsSelectors } from '@osf/shared/stores/collections'; import { ReviewStatusIcon } from '../../constants'; import { SubmissionReviewStatus } from '../../enums'; +import { Accordion, AccordionContent, AccordionHeader, AccordionPanel } from 'primeng/accordion'; +import { ContributorsListComponent } from '@osf/shared/components/contributors-list/contributors-list.component'; @Component({ selector: 'osf-submission-item', - imports: [TranslatePipe, IconComponent, DateAgoPipe, Button, TruncatedTextComponent], + imports: [ + TranslatePipe, + IconComponent, + DateAgoPipe, + Button, + TruncatedTextComponent, + Accordion, + AccordionPanel, + AccordionHeader, + AccordionContent, + ContributorsListComponent, + ], templateUrl: './collection-submission-item.component.html', styleUrl: './collection-submission-item.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, @@ -56,6 +69,17 @@ export class CollectionSubmissionItemComponent { .filter((attribute) => attribute.value); }); + hasMoreContributors = computed(() => { + // alert('hasMoreContributors', submission.contributors, submission.totalContributors); + const submission = this.submission(); + console.log('hasMoreContributors', submission.contributors, submission.totalContributors); + if (submission.contributors && submission.totalContributors) { + return submission.contributors.length < submission.totalContributors; + } + + return false; + }); + handleNavigation() { const currentStatus = this.activatedRoute.snapshot.queryParams['status']; const queryParams = currentStatus ? { status: currentStatus, mode: 'moderation' } : {}; diff --git a/src/app/features/moderation/components/preprint-submission-item/preprint-submission-item.component.ts b/src/app/features/moderation/components/preprint-submission-item/preprint-submission-item.component.ts index 353d17da8..d65723fab 100644 --- a/src/app/features/moderation/components/preprint-submission-item/preprint-submission-item.component.ts +++ b/src/app/features/moderation/components/preprint-submission-item/preprint-submission-item.component.ts @@ -52,7 +52,7 @@ export class PreprintSubmissionItemComponent { hasMoreContributors = computed(() => { const submission = this.submission(); - console.log('submission ', submission); + console.log('hasMoreContributors ', submission); return submission.contributors.length < submission.totalContributors; }); diff --git a/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts b/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts index 64a3b7473..e1a5d9e81 100644 --- a/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts +++ b/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts @@ -62,7 +62,7 @@ export class RegistrySubmissionItemComponent { const submission = this.submission(); console.log('submission'); console.log(submission); - console.log('after submission'); + console.log('after submission', submission.contributors.length, submission.totalContributors); return submission.contributors.length < submission.totalContributors; }); From a19e410ed2cf8519738ac82693e195e8663b0266 Mon Sep 17 00:00:00 2001 From: mkovalua Date: Thu, 11 Dec 2025 00:16:27 +0200 Subject: [PATCH 5/6] get contributors for collections moderation cards --- .../collection-submission-item.component.html | 1 - .../collection-submission-item.component.ts | 10 ++++++---- .../preprint-submission-item.component.ts | 1 - .../registry-submission-item.component.ts | 5 ----- .../moderation/mappers/registry-moderation.mapper.ts | 2 -- .../collections-moderation.state.ts | 8 +------- 6 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html b/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html index 91af5bc0c..121fefcd9 100644 --- a/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html +++ b/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html @@ -67,7 +67,6 @@

{{ 'common.labels.contributors' | translate }}:

-

{{ !!submission().contributorsLoading }}

{ - // alert('hasMoreContributors', submission.contributors, submission.totalContributors); const submission = this.submission(); - console.log('hasMoreContributors', submission.contributors, submission.totalContributors); if (submission.contributors && submission.totalContributors) { return submission.contributors.length < submission.totalContributors; } @@ -93,4 +91,8 @@ export class CollectionSubmissionItemComponent { window.open(url, '_blank'); } + + handleOpen() { + this.loadContributors.emit(); + } } diff --git a/src/app/features/moderation/components/preprint-submission-item/preprint-submission-item.component.ts b/src/app/features/moderation/components/preprint-submission-item/preprint-submission-item.component.ts index d65723fab..a20e7b46f 100644 --- a/src/app/features/moderation/components/preprint-submission-item/preprint-submission-item.component.ts +++ b/src/app/features/moderation/components/preprint-submission-item/preprint-submission-item.component.ts @@ -52,7 +52,6 @@ export class PreprintSubmissionItemComponent { hasMoreContributors = computed(() => { const submission = this.submission(); - console.log('hasMoreContributors ', submission); return submission.contributors.length < submission.totalContributors; }); diff --git a/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts b/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts index e1a5d9e81..f86e32d2b 100644 --- a/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts +++ b/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts @@ -58,16 +58,11 @@ export class RegistrySubmissionItemComponent { } hasMoreContributors = computed(() => { - console.log('hasMoreContributors'); const submission = this.submission(); - console.log('submission'); - console.log(submission); - console.log('after submission', submission.contributors.length, submission.totalContributors); return submission.contributors.length < submission.totalContributors; }); handleOpen() { - console.log('test test'); this.loadContributors.emit(); } } diff --git a/src/app/features/moderation/mappers/registry-moderation.mapper.ts b/src/app/features/moderation/mappers/registry-moderation.mapper.ts index 728b59f1c..e9405b1d7 100644 --- a/src/app/features/moderation/mappers/registry-moderation.mapper.ts +++ b/src/app/features/moderation/mappers/registry-moderation.mapper.ts @@ -12,8 +12,6 @@ import { export class RegistryModerationMapper { static fromResponse(response: RegistryDataJsonApi): RegistryModeration { - console.log(response, 'response mapper'); - return { id: response.id, title: replaceBadEncodedChars(response.attributes.title), diff --git a/src/app/features/moderation/store/collections-moderation/collections-moderation.state.ts b/src/app/features/moderation/store/collections-moderation/collections-moderation.state.ts index ceab73cd8..a9048ad73 100644 --- a/src/app/features/moderation/store/collections-moderation/collections-moderation.state.ts +++ b/src/app/features/moderation/store/collections-moderation/collections-moderation.state.ts @@ -148,14 +148,8 @@ export class CollectionsModerationState { }, }) ); - return this.contributorsService - .getBibliographicContributors( - ResourceType.Collection, - action.collectionId, - action.page, - DEFAULT_TABLE_PARAMS.rows - ) + .getBibliographicContributors(ResourceType.Project, action.collectionId, action.page, DEFAULT_TABLE_PARAMS.rows) .pipe( tap((res) => { const currentSubmission = state.collectionSubmissions.data.find((s) => s.id === action.collectionId); From 5aba34f4d5464d0d2753283ca2b586fe8b30fcb6 Mon Sep 17 00:00:00 2001 From: mkovalua Date: Thu, 11 Dec 2025 12:38:45 +0200 Subject: [PATCH 6/6] refactor code and resolve linter issues --- .../collection-submission-item.component.html | 2 +- .../registry-submission-item.component.ts | 6 +++++- .../moderation/mappers/registry-moderation.mapper.ts | 2 -- .../features/moderation/models/registry-moderation.model.ts | 4 ++-- .../collections-moderation/collections-moderation.state.ts | 4 ---- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html b/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html index 121fefcd9..e411a6cc2 100644 --- a/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html +++ b/src/app/features/moderation/components/collection-submission-item/collection-submission-item.component.html @@ -52,7 +52,7 @@ | }

- test {{ attribute.label }}: {{ attribute.value }} + {{ attribute.label }}: {{ attribute.value }}

}
diff --git a/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts b/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts index f86e32d2b..770db64d4 100644 --- a/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts +++ b/src/app/features/moderation/components/registry-submission-item/registry-submission-item.component.ts @@ -59,7 +59,11 @@ export class RegistrySubmissionItemComponent { hasMoreContributors = computed(() => { const submission = this.submission(); - return submission.contributors.length < submission.totalContributors; + if (submission.contributors && submission.totalContributors) { + return submission.contributors.length < submission.totalContributors; + } + + return false; }); handleOpen() { diff --git a/src/app/features/moderation/mappers/registry-moderation.mapper.ts b/src/app/features/moderation/mappers/registry-moderation.mapper.ts index e9405b1d7..70ab5fdb4 100644 --- a/src/app/features/moderation/mappers/registry-moderation.mapper.ts +++ b/src/app/features/moderation/mappers/registry-moderation.mapper.ts @@ -22,8 +22,6 @@ export class RegistryModerationMapper { embargoEndDate: response.attributes.embargo_end_date, actions: [], revisionId: response.embeds?.schema_responses?.data?.[0]?.id || null, - totalContributors: 0, - contributors: [], }; } diff --git a/src/app/features/moderation/models/registry-moderation.model.ts b/src/app/features/moderation/models/registry-moderation.model.ts index 351b888aa..2d59b2681 100644 --- a/src/app/features/moderation/models/registry-moderation.model.ts +++ b/src/app/features/moderation/models/registry-moderation.model.ts @@ -15,7 +15,7 @@ export interface RegistryModeration { actions: ReviewAction[]; revisionId?: string | null; contributorsLoading?: boolean; - contributors: ContributorModel[]; - totalContributors: number; + contributors?: ContributorModel[]; + totalContributors?: number; contributorsPage?: number; } diff --git a/src/app/features/moderation/store/collections-moderation/collections-moderation.state.ts b/src/app/features/moderation/store/collections-moderation/collections-moderation.state.ts index a9048ad73..fb5132c9b 100644 --- a/src/app/features/moderation/store/collections-moderation/collections-moderation.state.ts +++ b/src/app/features/moderation/store/collections-moderation/collections-moderation.state.ts @@ -21,10 +21,6 @@ import { } from './collections-moderation.actions'; import { COLLECTIONS_MODERATION_STATE_DEFAULTS, CollectionsModerationStateModel } from './collections-moderation.model'; -// import { CollectionSubmissionWithGuid } from '@shared/services/collections.services/models'; -// 'models/collections/collections.models'; -// import { CollectionSubmissionWithGuid } from '@shared/services/collections.services/models'; - @State({ name: 'collectionsModeration', defaults: COLLECTIONS_MODERATION_STATE_DEFAULTS,