Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
18d44e7
refactor(preprints-state): Renamed Preprints -> PreprintProviders
rrromchIk Jul 3, 2025
31bc13f
Merge branch 'main' into feat/submit-preprint
rrromchIk Jul 3, 2025
187896c
refactor(preprints-services): Renamed services to have 'preprints' pr…
rrromchIk Jul 3, 2025
0665024
fix(json-api-post): Fixed errors during to merge conflict
rrromchIk Jul 3, 2025
13e082d
refactor(preprints-state): Renamed Preprints -> PreprintProviders
rrromchIk Jul 3, 2025
a55bd93
refactor(preprints-models): Decomposed, used shared models. Moved som…
rrromchIk Jul 3, 2025
cf8cd63
refactor(router): Moved preprint routes to root folder of feature
rrromchIk Jul 3, 2025
c27d8da
refactor(preprints-components): Rename and reorganize component files…
rrromchIk Jul 3, 2025
f6bfb32
fix(preprints-models): Removed unused model
rrromchIk Jul 3, 2025
189d6cb
refactor(license): Made license more reusable by removing card wrapper
rrromchIk Jul 3, 2025
fe5e33e
refactor(metadata-license): Removed redundant wrapper
rrromchIk Jul 3, 2025
04d15f2
fix(comments): Fixed comments
rrromchIk Jul 3, 2025
ec9c9fb
feat(author-assertions): Partly implemented step with missing availab…
rrromchIk Jul 3, 2025
14051fe
refactor(validators): Moved linkValidator from helper function to sha…
rrromchIk Jul 3, 2025
ddd89b2
feat(array-input): Implemented reusable component for array input
rrromchIk Jul 3, 2025
d547779
feat(array-input): Used array-input for data links and prereg links
rrromchIk Jul 3, 2025
97e73e9
Merge branch 'main' into feat/submit-preprint
rrromchIk Jul 3, 2025
1ad7a34
Merge branch 'main' into feat/submit-preprint
rrromchIk Jul 4, 2025
83a6b8e
refactor(author-assertions): Refactored step. Fixed minor issues
rrromchIk Jul 4, 2025
26e4f44
fix(translations): Update URL validation message for clarity
rrromchIk Jul 4, 2025
3959764
fix(comments): Fixed comments
rrromchIk Jul 4, 2025
011a608
refactor(subjects): Refactored shared subjects component and service
rrromchIk Jul 4, 2025
4732431
feat(metadata-subjects): Implemented Subjects section on metadata step
rrromchIk Jul 4, 2025
ad6ce17
Merge branch 'main' into feat/submit-preprint
rrromchIk Jul 4, 2025
970d9b8
fix(discover-state): Removed selectSnapshot that selects data within …
rrromchIk Jul 4, 2025
6f3d20f
feat(regions): Introduced shared state for fetching regions
rrromchIk Jul 7, 2025
91bc446
feat(supplements): Implemented template for 'Choose existing' option
rrromchIk Jul 7, 2025
7864e8f
refactor(add-project-form): Refactored form component to be more reus…
rrromchIk Jul 7, 2025
05f7f65
refactor(node-models): Reorganized shared node models
rrromchIk Jul 7, 2025
2083379
feat(supplements-step): Implemented connecting project step
rrromchIk Jul 7, 2025
01a604a
Merge branch 'refs/heads/main' into feat/submit-preprint
rrromchIk Jul 7, 2025
deae84c
fix(conflict): Fixed things after merge conflict
rrromchIk Jul 7, 2025
39c0b45
fix(conflict): Fixed things after merge conflict
rrromchIk Jul 7, 2025
dc24f68
fix(registries-subjects): Use constant for OSF provider ID in fetchSu…
rrromchIk Jul 8, 2025
b5ea752
Merge branch 'main' into feat/submit-preprint
rrromchIk Jul 8, 2025
587f639
fix(submit-preprint): Fixes after merge conflict
rrromchIk Jul 8, 2025
a489aa4
fix(author-assertions): Fixed link info dropdown options
rrromchIk Jul 8, 2025
2b017f6
fix(file-step): Using preprint word from provider on UI
rrromchIk Jul 8, 2025
0675cb5
feat(review-step): Implemented UI for review step
rrromchIk Jul 8, 2025
2f47913
Merge branch 'main' into feat/submit-preprint
rrromchIk Jul 8, 2025
19265b6
fix(supplement-step): Fixed next button disable status
rrromchIk Jul 8, 2025
4fff0e8
fix(submit-stepper): Made steps variable computed based on provider
rrromchIk Jul 8, 2025
0667136
Merge branch 'main' into feat/submit-preprint
rrromchIk Jul 9, 2025
13bdf98
refactor(subjects): Refactored subjects validation logic
rrromchIk Jul 9, 2025
62ac09a
feat(review-step): Integrated API to submit preprint
rrromchIk Jul 9, 2025
1afb51f
feat(submit-preprint): Handled loosing unsaved data when moving back …
rrromchIk Jul 9, 2025
e234133
Merge branch 'main' into feat/submit-preprint
rrromchIk Jul 9, 2025
9ce4492
fix(conflict): Fixed after merge conflict
rrromchIk Jul 9, 2025
7ee579e
fix(submit-preprint): Minor fixes as a result of manual testing
rrromchIk Jul 9, 2025
f806245
feat(submit-preprint): Extracted static string to en.json
rrromchIk Jul 10, 2025
9b66fa5
fix(comments): Moved payload forming to mapper
rrromchIk Jul 10, 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
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
<h2>Author Assertions</h2>
<h2>{{ 'preprints.preprintStepper.authorAssertions.title' | translate }}</h2>

<p-card styleClass="m-t-24" class="card">
<div>
<h2>Conflict of Interest</h2>
<h2>{{ 'preprints.preprintStepper.authorAssertions.conflictOfInterest.title' | translate }}</h2>

<p class="m-t-12">
The Conflict of Interest (COI) assertion is made on behalf of all the authors listed for this preprint. COIs
include: financial involvement in any entity such as honoraria, grants, speaking fees, employment, consultancies,
stock ownership, expert testimony, and patents or licenses. COIs can also include non-financial interests such as
personal or professional relationships or pre-existing beliefs in the subject matter or materials discussed in
this preprint.
{{ 'preprints.preprintStepper.authorAssertions.conflictOfInterest.description' | translate }}
</p>

<div class="m-t-24 flex flex-row gap-4">
Expand All @@ -20,7 +16,7 @@ <h2>Conflict of Interest</h2>
[value]="true"
[formControl]="authorAssertionsForm.controls['hasCoi']"
/>
<label for="coi-yes">Yes</label>
<label for="coi-yes">{{ 'common.labels.yes' | translate }}</label>
</div>

<div class="flex flex-row gap-2">
Expand All @@ -30,7 +26,7 @@ <h2>Conflict of Interest</h2>
[value]="false"
[formControl]="authorAssertionsForm.controls['hasCoi']"
/>
<label for="coi-no">No</label>
<label for="coi-no">{{ 'common.labels.no' | translate }}</label>
</div>
</div>

Expand All @@ -43,8 +39,8 @@ <h2>Conflict of Interest</h2>
[formControl]="authorAssertionsForm.controls['coiStatement']"
[placeholder]="
authorAssertionsForm.value.hasCoi
? 'Describe'
: 'Author asserted there is no Conflict of Interest with this preprint.'
? ('preprints.preprintStepper.common.placeholders.describe' | translate)
: ('preprints.preprintStepper.authorAssertions.conflictOfInterest.noCoiPlaceholder' | translate)
"
></textarea>
@let coiStatementControl = authorAssertionsForm.controls['coiStatement'];
Expand All @@ -58,14 +54,10 @@ <h2>Conflict of Interest</h2>

<p-card styleClass="m-t-24" class="card">
<div>
<h2>Public Data</h2>
<h2>{{ 'preprints.preprintStepper.authorAssertions.publicData.title' | translate }}</h2>

<p class="m-t-12">
Data refers to raw and/or processed information (quantitative or qualitative) used for the analyses, case studies,
and/or descriptive interpretation in the preprint. Public data could include data posted to open-access
repositories, public archival library collection, or government archive. For data that is available under limited
circumstances (e.g., after signing a data sharing agreement), choose the ‘No’ option and use the comment box to
explain how others could access the data.
{{ 'preprints.preprintStepper.authorAssertions.publicData.description' | translate }}
</p>

<div class="m-t-24 flex flex-row gap-4">
Expand All @@ -76,7 +68,7 @@ <h2>Public Data</h2>
[value]="ApplicabilityStatus.Applicable"
[formControl]="authorAssertionsForm.controls['hasDataLinks']"
/>
<label for="publicDataAvailable">Available</label>
<label for="publicDataAvailable">{{ 'common.labels.available' | translate }}</label>
</div>

<div class="flex flex-row gap-2">
Expand All @@ -86,7 +78,7 @@ <h2>Public Data</h2>
[value]="ApplicabilityStatus.Unavailable"
[formControl]="authorAssertionsForm.controls['hasDataLinks']"
/>
<label for="publicDataUnavailable">No</label>
<label for="publicDataUnavailable">{{ 'common.labels.unavailable' | translate }}</label>
</div>

<div class="flex flex-row gap-2">
Expand All @@ -96,7 +88,7 @@ <h2>Public Data</h2>
[value]="ApplicabilityStatus.NotApplicable"
[formControl]="authorAssertionsForm.controls['hasDataLinks']"
/>
<label for="publicDataNotApplicable">Not Applicable</label>
<label for="publicDataNotApplicable">{{ 'common.labels.notApplicable' | translate }}</label>
</div>
</div>

Expand All @@ -113,8 +105,8 @@ <h2>Public Data</h2>
[rows]="3"
[placeholder]="
hasDataLinks === ApplicabilityStatus.Unavailable
? 'Describe'
: 'Author asserted there is no data associated with this preprint.'
? ('preprints.preprintStepper.common.placeholders.describe' | translate)
: ('preprints.preprintStepper.authorAssertions.publicData.notApplicablePlaceholder' | translate)
"
></textarea>
@let whyNoDataControl = authorAssertionsForm.controls['whyNoData'];
Expand All @@ -127,7 +119,7 @@ <h2>Public Data</h2>
<div class="m-t-24">
<osf-array-input
[formArray]="authorAssertionsForm.controls['dataLinks']"
inputPlaceholder="Link to data"
[inputPlaceholder]="'preprints.preprintStepper.common.placeholders.linkToData' | translate"
[validators]="linkValidators"
/>
</div>
Expand All @@ -137,12 +129,10 @@ <h2>Public Data</h2>

<p-card styleClass="m-t-24" class="card">
<div>
<h2>Public Preregistration</h2>
<h2>{{ 'preprints.preprintStepper.authorAssertions.publicPreregistration.title' | translate }}</h2>

<p class="m-t-12">
A preregistration is a description of the research design and/or analysis plan that is created and registered
before researchers collected data or before they have seen/interacted with preexisting data. The description
should appear in a public registry (e.g., clinicaltrials.gov, OSF, AEA registry).
{{ 'preprints.preprintStepper.authorAssertions.publicPreregistration.description' | translate }}
</p>
</div>

Expand All @@ -154,7 +144,7 @@ <h2>Public Preregistration</h2>
[value]="ApplicabilityStatus.Applicable"
[formControl]="authorAssertionsForm.controls['hasPreregLinks']"
/>
<label for="preregistrationAvailable">Available</label>
<label for="preregistrationAvailable">{{ 'common.labels.available' | translate }}</label>
</div>

<div class="flex flex-row gap-2">
Expand All @@ -164,7 +154,7 @@ <h2>Public Preregistration</h2>
[value]="ApplicabilityStatus.Unavailable"
[formControl]="authorAssertionsForm.controls['hasPreregLinks']"
/>
<label for="preregistrationUnavailable">No</label>
<label for="preregistrationUnavailable">{{ 'common.labels.unavailable' | translate }}</label>
</div>

<div class="flex flex-row gap-2">
Expand All @@ -174,7 +164,7 @@ <h2>Public Preregistration</h2>
[value]="ApplicabilityStatus.NotApplicable"
[formControl]="authorAssertionsForm.controls['hasPreregLinks']"
/>
<label for="preregistrationNotApplicable">Not Applicable</label>
<label for="preregistrationNotApplicable">{{ 'common.labels.notApplicable' | translate }}</label>
</div>
</div>
@let hasPreregLinks = authorAssertionsForm.value.hasPreregLinks!;
Expand All @@ -190,8 +180,8 @@ <h2>Public Preregistration</h2>
[formControl]="authorAssertionsForm.controls['whyNoPrereg']"
[placeholder]="
hasPreregLinks === ApplicabilityStatus.Unavailable
? 'Describe'
: 'The author asserts that a preregistration is not applicable because no data collection, extraction, or analysis is reported in the preprint.'
? ('preprints.preprintStepper.common.placeholders.describe' | translate)
: ('preprints.preprintStepper.authorAssertions.publicPreregistration.notApplicablePlaceholder' | translate)
"
></textarea>
@let hasPreregLinksControl = authorAssertionsForm.controls['hasPreregLinks'];
Expand All @@ -201,35 +191,40 @@ <h2>Public Preregistration</h2>
</p-message>
}
} @else {
<p-select
id="links-info"
class="w-12 md:w-6"
styleClass="m-t-24"
placeholder="Choose one"
[formControl]="authorAssertionsForm.controls['preregLinkInfo']"
[options]="preregLinkOptions"
optionLabel="label"
optionValue="value"
[showClear]="false"
/>
<div class="m-t-24 w-12 md:w-6">
<osf-form-select
[control]="authorAssertionsForm.controls['preregLinkInfo']"
[options]="preregLinkOptions"
[placeholder]="'preprints.preprintStepper.authorAssertions.publicPreregistration.selectType' | translate"
[fullWidth]="true"
/>
</div>

<div class="m-t-24">
<osf-array-input
[formArray]="authorAssertionsForm.controls['preregLinks']"
inputPlaceholder="Link to data"
[inputPlaceholder]="'preprints.preprintStepper.common.placeholders.linkToData' | translate"
[validators]="linkValidators"
/>
</div>
}
</p-card>

<section class="m-t-48 flex flex-row justify-content-end align-items-center gap-2">
<p-button class="w-6 md:w-6rem" styleClass="w-full" label="Back" severity="info" />
<p-button
class="w-6 md:w-6rem"
styleClass="w-full"
[label]="'common.buttons.back' | translate"
severity="info"
(click)="backButtonClicked()"
/>
<p-button
class="w-6 md:w-9rem"
styleClass="w-full"
label="Next"
[pTooltip]="authorAssertionsForm.invalid ? 'Fill in \'Required\' fields to continue' : ''"
[label]="'common.buttons.next' | translate"
[pTooltip]="
authorAssertionsForm.invalid ? ('preprints.preprintStepper.common.validation.fillRequiredFields' | translate) : ''
"
tooltipPosition="top"
[disabled]="authorAssertionsForm.invalid"
[loading]="isUpdatingPreprint()"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ import { Button } from 'primeng/button';
import { Card } from 'primeng/card';
import { Message } from 'primeng/message';
import { RadioButton } from 'primeng/radiobutton';
import { Select } from 'primeng/select';
import { Textarea } from 'primeng/textarea';
import { Tooltip } from 'primeng/tooltip';

import { NgClass } from '@angular/common';
import { ChangeDetectionStrategy, Component, effect, HostListener, inject, output } from '@angular/core';
import { ChangeDetectionStrategy, Component, effect, inject, output } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import {
AbstractControl,
Expand All @@ -26,12 +25,14 @@ import {

import { StringOrNull } from '@core/helpers';
import { ArrayInputComponent } from '@osf/features/preprints/components/stepper/author-assertion-step/array-input/array-input.component';
import { formInputLimits } from '@osf/features/preprints/constants';
import { formInputLimits, preregLinksOptions } from '@osf/features/preprints/constants';
import { ApplicabilityStatus, PreregLinkInfo } from '@osf/features/preprints/enums';
import { Preprint } from '@osf/features/preprints/models';
import { SubmitPreprintSelectors, UpdatePreprint } from '@osf/features/preprints/store/submit-preprint';
import { FormSelectComponent } from '@shared/components';
import { INPUT_VALIDATION_MESSAGES } from '@shared/constants';
import { ToastService } from '@shared/services';
import { CustomValidators } from '@shared/utils';
import { CustomConfirmationService, ToastService } from '@shared/services';
import { CustomValidators, findChangedFields } from '@shared/utils';

@Component({
selector: 'osf-author-assertions-step',
Expand All @@ -46,15 +47,16 @@ import { CustomValidators } from '@shared/utils';
NgClass,
Button,
Tooltip,
Select,
ArrayInputComponent,
FormSelectComponent,
],
templateUrl: './author-assertions-step.component.html',
styleUrl: './author-assertions-step.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AuthorAssertionsStepComponent {
private toastService = inject(ToastService);
private confirmationService = inject(CustomConfirmationService);
private actions = createDispatchMap({
updatePreprint: UpdatePreprint,
});
Expand All @@ -63,10 +65,7 @@ export class AuthorAssertionsStepComponent {
readonly ApplicabilityStatus = ApplicabilityStatus;
readonly inputLimits = formInputLimits;
readonly INPUT_VALIDATION_MESSAGES = INPUT_VALIDATION_MESSAGES;
readonly preregLinkOptions = Object.entries(PreregLinkInfo).map(([key, value]) => ({
label: key,
value,
}));
readonly preregLinkOptions = preregLinksOptions;
readonly linkValidators = [CustomValidators.linkValidator(), CustomValidators.requiredTrimmed()];

createdPreprint = select(SubmitPreprintSelectors.getCreatedPreprint);
Expand Down Expand Up @@ -126,6 +125,7 @@ export class AuthorAssertionsStepComponent {
});

nextClicked = output<void>();
backClicked = output<void>();

constructor() {
effect(() => {
Expand Down Expand Up @@ -193,25 +193,19 @@ export class AuthorAssertionsStepComponent {
});
}

@HostListener('window:beforeunload', ['$event'])
public onBeforeUnload($event: BeforeUnloadEvent): boolean {
$event.preventDefault();
return false;
}

nextButtonClicked() {
const formValue = this.authorAssertionsForm.value;
const formValue = this.authorAssertionsForm.getRawValue();

const hasCoi = formValue.hasCoi;
const coiStatement = formValue.coiStatement || null;
const coiStatement = formValue.coiStatement;

const hasDataLinks = formValue.hasDataLinks;
const whyNoData = formValue.whyNoData || null;
const dataLinks: string[] = formValue.dataLinks || [];
const whyNoData = formValue.whyNoData;
const dataLinks = formValue.dataLinks;

const hasPreregLinks = formValue.hasPreregLinks;
const whyNoPrereg = formValue.whyNoPrereg || null;
const preregLinks: string[] = formValue.preregLinks || [];
const whyNoPrereg = formValue.whyNoPrereg;
const preregLinks = formValue.preregLinks;
const preregLinkInfo = formValue.preregLinkInfo || undefined;

this.actions
Expand All @@ -228,12 +222,31 @@ export class AuthorAssertionsStepComponent {
})
.subscribe({
complete: () => {
this.toastService.showSuccess('Preprint saved successfully.');
this.toastService.showSuccess('preprints.preprintStepper.common.successMessages.preprintSaved');
this.nextClicked.emit();
},
});
}

backButtonClicked() {
const formValue = this.authorAssertionsForm.getRawValue();
const changedFields = findChangedFields<Preprint>(formValue, this.createdPreprint()!);

if (!Object.keys(changedFields).length) {
this.backClicked.emit();
return;
}

this.confirmationService.confirmContinue({
headerKey: 'common.discardChanges.header',
messageKey: 'common.discardChanges.message',
onConfirm: () => {
this.backClicked.emit();
},
onReject: () => null,
});
}

private disableAndClearValidators(control: AbstractControl) {
if (control instanceof FormArray) {
while (control.length !== 0) {
Expand Down
Loading