Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
cfb9150
feat(preprint-citation): Implemented citation section
rrromchIk Aug 4, 2025
fa76113
fix(preprint-download): Fixed download preprint link
rrromchIk Aug 4, 2025
1f7ed43
feat(preprint-doi): Showing doi link
rrromchIk Aug 4, 2025
7355062
fix(preprint-general-info): Fixed links
rrromchIk Aug 4, 2025
384199b
feat(preprint-share): Added socials with links to share preprint
rrromchIk Aug 4, 2025
894d728
fix(preprint-stepper): Fixed stepper styles for update and create new…
rrromchIk Aug 6, 2025
ef50e06
fix(preprint-doi): Improved doi rendering
rrromchIk Aug 6, 2025
11a0ae4
fix(preprint-share): Using facebookAppId from provider
rrromchIk Aug 6, 2025
13d9e76
feat(preprint-details): Added condition for 'Create New Version' butt…
rrromchIk Aug 6, 2025
bac4f44
fix(state-error): Resetting isSubmitting flag in the state-error handler
rrromchIk Aug 6, 2025
4ae5aec
fix(preprint-general-info): Conditionally render section based on pro…
rrromchIk Aug 6, 2025
864e13c
feat(preprint-details): Enhance file section with provider reviews wo…
rrromchIk Aug 6, 2025
198cb0d
feat(preprint-details): Conditions for 'Edit' and 'Create New Version…
rrromchIk Aug 6, 2025
a0f50d1
feat(preprint-status-banner): Implemented status banner for preprint …
rrromchIk Aug 7, 2025
ad54c09
Merge branch 'main' into feat/preprint-details
rrromchIk Aug 7, 2025
80086cc
fix(user-permission-model): Using existing enum and removed newly cre…
rrromchIk Aug 7, 2025
a4b1b9e
style(status-banner): Fixed styles
rrromchIk Aug 8, 2025
666b6c9
feat(preprint-document-type): Introduced helper function that calcula…
rrromchIk Aug 8, 2025
6d47cc7
feat(preprint-withdrawal): Implement withdrawal functionality
rrromchIk Aug 8, 2025
ad3ef75
Merge branch 'main' into feat/preprint-details
rrromchIk Aug 8, 2025
313e8e1
Merge branch 'main' into feat/preprint-details
rrromchIk Aug 11, 2025
97fcf38
feat(preprint-details): Extracted static string to en.json. Refactore…
rrromchIk Aug 11, 2025
c7ef246
Merge branch 'main' into feat/preprint-details
rrromchIk Aug 11, 2025
f6690d5
test(preprint-details): Skipped some failing test permanently
rrromchIk Aug 11, 2025
9675d7e
style(preprint-details): Fixed margin top for details page
rrromchIk Aug 11, 2025
551b2f8
style(my-preprint): Removed full height
rrromchIk Aug 11, 2025
31287e5
style(preprint-status-banner): Adjusted status banner for mobile and …
rrromchIk Aug 11, 2025
eebcf30
feat(preprint-details): Labels for actions
rrromchIk Aug 11, 2025
82e0f25
feat(preprint-details): Implemented and used tombstone component for …
rrromchIk Aug 11, 2025
620bd78
fix(preprint-details): Fixed PR comments
rrromchIk Aug 12, 2025
dc6c995
Merge branch 'main' into feat/preprint-details
rrromchIk Aug 12, 2025
db8fdab
Merge branch 'main' into feat/preprint-details
rrromchIk Aug 12, 2025
290e3fb
feat(nav-menu): Checking whether to show Preprint Moderation page in …
rrromchIk Aug 12, 2025
2911326
refactor(preprint-details): Extracted logic of handling preprint vers…
rrromchIk Aug 12, 2025
06ab859
Merge branch 'main' into feat/preprint-details
rrromchIk Aug 12, 2025
ccd653d
feat(preprint-provider): Resolved TODO, added link to example preprint
rrromchIk Aug 12, 2025
4e5af67
fix(preprint-details): Fixed bugs related to withdrawal requests loading
rrromchIk Aug 12, 2025
52be62b
feat(moderation): Restricted moderator permissions on Moderators tab
rrromchIk Aug 12, 2025
b816ba9
fix(preprint-details): Fixed evaluation whether current user id contrib
rrromchIk Aug 12, 2025
cdf3a4d
feat(preprint-details): Evaluating moderation mode on the details page
rrromchIk Aug 12, 2025
fc2fe33
feat(preprint-moderation): Partly implemented moderation status banner
rrromchIk Aug 13, 2025
57457af
Merge branch 'refs/heads/main' into feat/preprint-details
rrromchIk Aug 13, 2025
0979ef4
fix(preprint-moderation): Changed translations, discovered bug
rrromchIk Aug 14, 2025
3cd368a
Merge branch 'main' into feat/preprint-details
rrromchIk Aug 14, 2025
6b5183d
fix(preprint-moderation): Fixed endpoint version error
rrromchIk Aug 14, 2025
2c73d8c
feat(preprint-moderation-banner): Added request activity to the banner
rrromchIk Aug 14, 2025
dbc762d
feat(preprint-moderation-make-decision): Partly implemented make deci…
rrromchIk Aug 14, 2025
77e4467
Merge branch 'refs/heads/main' into feat/preprint-details
rrromchIk Aug 14, 2025
3d5cac7
feat(preprint-moderation): Fully implemented preprint moderation logic
rrromchIk Aug 18, 2025
7e5639e
Merge branch 'refs/heads/main' into feat/preprint-details
rrromchIk Aug 18, 2025
58534d2
fix(preprint-status-banner): Fixed bug related to status banner feedback
rrromchIk Aug 19, 2025
0adc132
feat(preprint-tombstone): Added missing Reason for withdrawal
rrromchIk Aug 19, 2025
96e63c0
feat(preprint-additional-info): Added missing publication doi
rrromchIk Aug 19, 2025
29b276c
feat(preprint-general-info): Added missing supplemental materials
rrromchIk Aug 19, 2025
e17c987
Merge branch 'refs/heads/main' into feat/preprint-details
rrromchIk Aug 19, 2025
aa77eeb
fix(review-step): Fixed bug related to creating review action for acc…
rrromchIk Aug 19, 2025
f980d90
fix(preprint-moderation): Removed redundant TODO
rrromchIk Aug 19, 2025
143aa30
fix(tests): Skipped test
rrromchIk Aug 19, 2025
af5f242
fix(comments): Fixed PR comments
rrromchIk Aug 20, 2025
27cad1c
Merge branch 'refs/heads/main' into feat/preprint-details
rrromchIk Aug 20, 2025
95dcfa7
fix(conflict): Fixes due to merge conflict
rrromchIk Aug 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/app/core/components/nav-menu/nav-menu.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export class NavMenuComponent {
isProject: this.isProjectRoute() && !this.isRegistryRoute() && !this.isPreprintRoute(),
isRegistry: this.isRegistryRoute(),
isPreprint: this.isPreprintRoute(),
preprintReviewsPageVisible: this.canUserViewReviews(),
isCollections: this.isCollectionsRoute() || false,
currentUrl: this.router.url,
};
Expand All @@ -69,6 +70,7 @@ export class NavMenuComponent {
protected readonly isCollectionsRoute = computed(() => this.currentRoute().isCollectionsWithId);
protected readonly isRegistryRoute = computed(() => this.currentRoute().isRegistryRoute);
protected readonly isPreprintRoute = computed(() => this.currentRoute().isPreprintRoute);
protected readonly canUserViewReviews = select(UserSelectors.getCanViewReviews);

private getRouteInfo() {
const urlSegments = this.router.url.split('/').filter((segment) => segment);
Expand Down
3 changes: 3 additions & 0 deletions src/app/core/helpers/nav-menu.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ function updatePreprintMenuItem(item: MenuItem, ctx: RouteContext): MenuItem {
}
return { ...subItem, visible: false, expanded: false };
}
if (subItem.id === 'preprints-moderation') {
return { ...subItem, visible: ctx.preprintReviewsPageVisible };
}
return subItem;
});

Expand Down
1 change: 1 addition & 0 deletions src/app/core/models/route-context.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface RouteContext {
isProject: boolean;
isRegistry: boolean;
isPreprint: boolean;
preprintReviewsPageVisible?: boolean;
isCollections: boolean;
currentUrl?: string;
}
5 changes: 5 additions & 0 deletions src/app/core/store/user/user.selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ export class UserSelectors {
return !!state.currentUser.data?.isModerator;
}

@Selector([UserState])
static getCanViewReviews(state: UserStateModel): boolean {
return state.currentUser.data?.canViewReviews || false;
}

@Selector([UserState])
static isAuthenticated(state: UserStateModel): boolean {
return !!state.currentUser.data || !!localStorage.getItem('currentUser');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
<div class="flex flex-column gap-4 md:flex-row md:gap-6">
<div class="md:w-8">
<osf-search-input [control]="searchControl" [placeholder]="'common.search.title' | translate" />
</div>
<osf-search-input class="w-full" [control]="searchControl" [placeholder]="'common.search.title' | translate" />

<div class="ml-auto w-full md:w-4">
<p-button
class="w-full"
styleClass="w-full"
[label]="'moderation.addModerator' | translate"
(click)="openAddModeratorDialog()"
[disabled]="isModeratorsLoading()"
></p-button>
</div>
@if (isCurrentUserAdminModerator()) {
<div class="ml-auto w-full md:w-4">
<p-button
class="w-full"
styleClass="w-full"
[label]="'moderation.addModerator' | translate"
(click)="openAddModeratorDialog()"
[disabled]="isModeratorsLoading()"
/>
</div>
}
</div>

<div class="block w-full my-5">
<osf-moderators-table
[items]="moderators()"
[isLoading]="isModeratorsLoading()"
[currentUserId]="currentUser()?.id"
[isCurrentUserAdminModerator]="isCurrentUserAdminModerator()"
(update)="updateModerator($event)"
(remove)="removeModerator($event)"
></osf-moderators-table>
/>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,23 @@ import { DialogService } from 'primeng/dynamicdialog';

import { debounceTime, distinctUntilChanged, filter, forkJoin, map, of, skip } from 'rxjs';

import { ChangeDetectionStrategy, Component, DestroyRef, effect, inject, OnInit, Signal, signal } from '@angular/core';
import {
ChangeDetectionStrategy,
Component,
computed,
DestroyRef,
effect,
inject,
OnInit,
Signal,
signal,
} from '@angular/core';
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
import { FormControl } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';

import { AddModeratorType } from '@osf/features/moderation/enums';
import { UserSelectors } from '@core/store/user';
import { AddModeratorType, ModeratorPermission } from '@osf/features/moderation/enums';
import { ModeratorDialogAddModel, ModeratorModel } from '@osf/features/moderation/models';
import {
AddModerator,
Expand Down Expand Up @@ -58,6 +69,17 @@ export class ModeratorsListComponent implements OnInit {
moderators = signal([]);
initialModerators = select(ModeratorsSelectors.getModerators);
isModeratorsLoading = select(ModeratorsSelectors.isModeratorsLoading);
currentUser = select(UserSelectors.getCurrentUser);

isCurrentUserAdminModerator = computed(() => {
const currentUserId = this.currentUser()?.id;
const initialModerators = this.initialModerators();
if (!currentUserId) return false;

return initialModerators.some((moderator: ModeratorModel) => {
return moderator.userId === currentUserId && moderator.permission === ModeratorPermission.Admin;
});
});

protected actions = createDispatchMap({
loadModerators: LoadModerators,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,25 @@
</td>
<td>
<div>
<osf-select
[options]="permissionsOptions"
[placeholder]="'project.contributors.permissionFilter'"
[appendTo]="'body'"
[noBorder]="true"
[(selectedValue)]="item.permission"
(changeValue)="updatePermission(item)"
></osf-select>
@if (isCurrentUserAdminModerator()) {
<osf-select
[options]="permissionsOptions"
[placeholder]="'project.contributors.permissionFilter'"
[appendTo]="'body'"
[noBorder]="true"
[(selectedValue)]="item.permission"
(changeValue)="updatePermission(item)"
/>
} @else {
@switch (item.permission) {
@case (ModeratorPermission.Admin) {
<span>{{ 'moderation.moderatorPermissions.administrator' | translate }}</span>
}
@case (ModeratorPermission.Moderator) {
<span>{{ 'moderation.moderatorPermissions.moderator' | translate }}</span>
}
}
}
</div>
</td>
<td>
Expand Down Expand Up @@ -79,8 +90,16 @@
</div>
</td>
<td>
<p-button class="danger-icon-btn" icon="fas fa-trash" severity="danger" text (click)="removeModerator(item)">
</p-button>
@if (isCurrentUserAdminModerator() || currentUserId() === item.id) {
<p-button
class="danger-icon-btn"
icon="fas fa-trash"
severity="danger"
text
(click)="removeModerator(item)"
[disabled]="!isCurrentUserAdminModerator() && currentUserId() !== item.id"
/>
}
</td>
</tr>
} @else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ChangeDetectionStrategy, Component, inject, input, output, signal } fro
import { FormsModule } from '@angular/forms';

import { MODERATION_PERMISSIONS } from '@osf/features/moderation/constants';
import { ModeratorPermission } from '@osf/features/moderation/enums';
import { ModeratorModel } from '@osf/features/moderation/models';
import {
EducationHistoryDialogComponent,
Expand All @@ -29,6 +30,8 @@ import { TableParameters } from '@osf/shared/models';
export class ModeratorsTableComponent {
items = input<ModeratorModel[]>([]);
isLoading = input(false);
currentUserId = input.required<string | undefined>();
isCurrentUserAdminModerator = input.required<boolean>();

update = output<ModeratorModel>();
remove = output<ModeratorModel>();
Expand All @@ -38,6 +41,7 @@ export class ModeratorsTableComponent {

protected readonly tableParams = signal<TableParameters>({ ...MY_PROJECTS_TABLE_PARAMS });
protected readonly permissionsOptions = MODERATION_PERMISSIONS;
protected readonly ModeratorPermission = ModeratorPermission;

skeletonData: ModeratorModel[] = Array.from({ length: 3 }, () => ({}) as ModeratorModel);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export class PreprintSubmissionsComponent implements OnInit {
}

navigateToPreprint(item: PreprintSubmission) {
this.router.navigate(['/preprints/', item.id, 'overview'], { queryParams: { mode: 'moderator' } });
this.router.navigate(['/preprints/', this.providerId(), item.id], { queryParams: { mode: 'moderator' } });
}

private getStatusFromQueryParams() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export class PreprintWithdrawalSubmissionsComponent implements OnInit {
}

navigateToPreprint(item: PreprintWithdrawalSubmission) {
this.router.navigate(['/preprints/', item.preprintId, 'overview'], { queryParams: { mode: 'moderator' } });
this.router.navigate(['/preprints/', this.providerId(), item.preprintId], { queryParams: { mode: 'moderator' } });
}

private getStatusFromQueryParams() {
Expand Down
4 changes: 2 additions & 2 deletions src/app/features/moderation/constants/submission.const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ export const WITHDRAWAL_SUBMISSION_REVIEW_OPTIONS: SubmissionReviewOption[] = [
{
value: SubmissionReviewStatus.Accepted,
icon: 'fas fa-circle-check',
label: 'moderation.submissionReviewStatus.accepted',
label: 'moderation.submissionReviewStatus.approved',
count: 0,
},
{
value: SubmissionReviewStatus.Rejected,
icon: 'fas fa-circle-minus',
label: 'moderation.submissionReviewStatus.rejected',
label: 'moderation.submissionReviewStatus.declined',
count: 0,
},
];
Expand Down
1 change: 0 additions & 1 deletion src/app/features/moderation/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,4 @@ export * from './registry-json-api.model';
export * from './registry-moderation.model';
export * from './review-action.model';
export * from './review-action-json-api.model';
export * from './submission.model';
export * from './submission-review-option.model';
7 changes: 0 additions & 7 deletions src/app/features/moderation/models/submission.model.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/app/features/moderation/services/moderators.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class ModeratorsService {
private readonly urlMap = new Map<ResourceType, string>([
[ResourceType.Collection, 'providers/collections'],
[ResourceType.Registration, 'providers/registrations'],
[ResourceType.Preprint, 'preprint_providers'],
[ResourceType.Preprint, 'providers/preprints'],
]);

getModerators(resourceId: string, resourceType: ResourceType): Observable<ModeratorModel[]> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class PreprintModerationService {
private readonly jsonApiService = inject(JsonApiService);

getPreprintProviders(): Observable<PreprintProviderModerationInfo[]> {
const baseUrl = `${environment.apiUrl}/preprint_providers/?filter[permissions]=view_actions,set_up_moderation`;
const baseUrl = `${environment.apiUrl}/providers/preprints/?filter[permissions]=view_actions,set_up_moderation`;

return this.jsonApiService
.get<JsonApiResponse<PreprintRelatedCountJsonApi[], null>>(baseUrl)
Expand Down
3 changes: 3 additions & 0 deletions src/app/features/preprints/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export { PreprintsInstitutionFilterComponent } from './filters/preprints-institu
export { PreprintsLicenseFilterComponent } from './filters/preprints-license-filter/preprints-license-filter.component';
export { AdditionalInfoComponent } from './preprint-details/additional-info/additional-info.component';
export { GeneralInformationComponent } from './preprint-details/general-information/general-information.component';
export { ModerationStatusBannerComponent } from './preprint-details/moderation-status-banner/moderation-status-banner.component';
export { PreprintFileSectionComponent } from './preprint-details/preprint-file-section/preprint-file-section.component';
export { ShareAndDownloadComponent } from './preprint-details/share-and-downlaod/share-and-download.component';
export { StatusBannerComponent } from './preprint-details/status-banner/status-banner.component';
Expand All @@ -19,6 +20,8 @@ export { PreprintsFilterChipsComponent } from '@osf/features/preprints/component
export { PreprintsResourcesComponent } from '@osf/features/preprints/components/filters/preprints-resources/preprints-resources.component';
export { PreprintsResourcesFiltersComponent } from '@osf/features/preprints/components/filters/preprints-resources-filters/preprints-resources-filters.component';
export { PreprintsSubjectFilterComponent } from '@osf/features/preprints/components/filters/preprints-subject-filter/preprints-subject-filter.component';
export { MakeDecisionComponent } from '@osf/features/preprints/components/preprint-details/make-decision/make-decision.component';
export { PreprintTombstoneComponent } from '@osf/features/preprints/components/preprint-details/preprint-tombstone/preprint-tombstone.component';
export { WithdrawDialogComponent } from '@osf/features/preprints/components/preprint-details/withdraw-dialog/withdraw-dialog.component';
export { FileStepComponent } from '@osf/features/preprints/components/stepper/file-step/file-step.component';
export { MetadataStepComponent } from '@osf/features/preprints/components/stepper/metadata-step/metadata-step.component';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,22 @@ <h3>{{ 'preprints.preprintStepper.review.sections.metadata.publicationCitation'

@if (preprintValue.originalPublicationDate) {
<section class="flex flex-column gap-2">
<h3>{{ 'preprints.preprintStepper.review.sections.metadata.publicationDate' | translate }}</h3>
<h3>{{ 'preprints.details.originalPublicationDate' | translate }}</h3>

{{ preprintValue.originalPublicationDate | date: 'MMM d, y, h:mm a' }}
</section>
}

@if (preprintValue.doi) {
<section class="flex flex-column gap-2">
<h3>{{ 'preprints.details.publicationDoi' | translate }}</h3>

<a [href]="preprint()?.articleDoiLink">
{{ preprint()?.articleDoiLink }}
</a>
</section>
}

<section class="license flex flex-column gap-2">
<h3>{{ 'preprints.preprintStepper.review.sections.metadata.license' | translate }}</h3>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ <h3>{{ 'preprints.preprintStepper.review.sections.metadata.affiliatedInstitution
</section>
}

@if (preprintValue.nodeId) {
<section class="flex flex-column gap-2">
<h3>{{ 'preprints.details.supplementalMaterials' | translate }}</h3>
<a [routerLink]="nodeLink()" class="flex gap-1">
{{ nodeLink() }}
<osf-icon iconClass="fa fa-external-link-alt" />
</a>
</section>
}

<section class="flex flex-column gap-2">
<h3>{{ 'preprints.preprintStepper.review.sections.metadata.authors' | translate }}</h3>

Expand Down Expand Up @@ -108,7 +118,10 @@ <h3>
</section>
}

<osf-preprint-doi-section [preprintProvider]="preprintProvider()" />
<osf-preprint-doi-section
[preprintProvider]="preprintProvider()"
(preprintVersionSelected)="preprintVersionSelected.emit($event)"
/>
</div>
}

Expand Down
Loading