• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CenterForOpenScience / ember-osf-web / 12472120664

23 Dec 2024 07:45PM UTC coverage: 67.891%. First build
12472120664

Pull #2436

github

web-flow
Merge 1ae93c6dd into 5515ddc22
Pull Request #2436: [ENG-6470] Withdrawn version picker

2930 of 4698 branches covered (62.37%)

Branch coverage included in aggregate %.

26 of 66 new or added lines in 6 files covered. (39.39%)

7327 of 10410 relevant lines covered (70.38%)

204.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

45.89
/app/preprints/-components/submit/preprint-state-machine/component.ts
1
import Component from '@glimmer/component';
2
import PreprintModel, { PreprintDataLinksEnum, PreprintPreregLinksEnum } from 'ember-osf-web/models/preprint';
3
import PreprintProviderModel from 'ember-osf-web/models/preprint-provider';
4
import Store from '@ember-data/store';
5
import { inject as service } from '@ember/service';
6
import RouterService from '@ember/routing/router-service';
7
import { tracked } from '@glimmer/tracking';
8
import { action } from '@ember/object';
9
import Intl from 'ember-intl/services/intl';
10
import { task } from 'ember-concurrency';
11
import { waitFor } from '@ember/test-waiters';
12
import FileModel from 'ember-osf-web/models/file';
13
import Toast from 'ember-toastr/services/toast';
14
import captureException, { getApiErrorMessage } from 'ember-osf-web/utils/capture-exception';
15
import { Permission } from 'ember-osf-web/models/osf-model';
16
import { ReviewsState } from 'ember-osf-web/models/provider';
17
import { taskFor } from 'ember-concurrency-ts';
18
import InstitutionModel from 'ember-osf-web/models/institution';
19
import CurrentUserService from 'ember-osf-web/services/current-user';
20
import { ReviewActionTrigger } from 'ember-osf-web/models/review-action';
21

22
export enum PreprintStatusTypeEnum {
23
    titleAndAbstract = 'titleAndAbstract',
24
    file = 'file',
25
    metadata = 'metadata',
26
    authorAssertions = 'authorAssertions',
27
    supplements = 'supplements',
28
    review = 'review',
29
}
30

31
/**
32
 * The State Machine Args
33
 */
34
interface StateMachineArgs {
35
    provider: PreprintProviderModel;
36
    preprint: PreprintModel;
37
    setPageDirty: () => void;
38
    resetPageDirty: () => void;
39
    newVersion?: boolean;
40
}
41

42
/**
43
 * The Preprint State Machine
44
 */
45
export default class PreprintStateMachine extends Component<StateMachineArgs>{
46
    @service store!: Store;
47
    @service router!: RouterService;
48
    @service intl!: Intl;
49
    @service toast!: Toast;
50
    @service currentUser!: CurrentUserService;
51

52
    titleAndAbstractValidation = false;
10✔
53
    fileValidation = false;
10✔
54
    metadataValidation = false;
10✔
55
    authorAssertionValidation = false;
10✔
56
    supplementValidation = false;
10✔
57
    @tracked isNextButtonDisabled = true;
5✔
58
    @tracked isPreviousButtonDisabled = true;
10✔
59
    @tracked isDeleteButtonDisplayed = false;
1✔
60
    @tracked isWithdrawalButtonDisplayed = false;
6✔
61

62
    provider = this.args.provider;
10✔
63
    @tracked preprint: PreprintModel;
64
    displayAuthorAssertions = false;
10✔
65
    @tracked statusFlowIndex = 1;
10✔
66
    @tracked isEditFlow = false;
5✔
67
    @tracked displayFileUploadStep = true;
1✔
68
    @tracked isNewVersionFlow = this.args.newVersion;
10✔
69
    affiliatedInstitutions = [] as InstitutionModel[];
10✔
70

71
    constructor(owner: unknown, args: StateMachineArgs) {
72
        super(owner, args);
10✔
73

74
        if (this.args.newVersion) {
10✔
75
            this.preprint = this.args.preprint;
1✔
76
            return;
1✔
77
        }
78
        if (this.args.preprint) {
9✔
79
            this.preprint = this.args.preprint;
5✔
80
            this.setValidationForEditFlow();
5✔
81
            this.isEditFlow = true;
5✔
82
            if (this.args.preprint.reviewsState === ReviewsState.REJECTED) {
5✔
83
                this.displayFileUploadStep = true;
2✔
84
            } else {
85
                this.displayFileUploadStep = false;
3✔
86
            }
87
            this.isDeleteButtonDisplayed = false;
5✔
88
            taskFor(this.canDisplayWitdrawalButton).perform();
5✔
89
        } else {
90
            this.isDeleteButtonDisplayed = true;
4✔
91
            this.isWithdrawalButtonDisplayed = false;
4✔
92
            this.displayFileUploadStep = true;
4✔
93
            this.preprint = this.store.createRecord('preprint', {
4✔
94
                provider: this.provider,
95
            });
96
        }
97

98
        this.displayAuthorAssertions = this.provider.assertionsEnabled;
9✔
99
    }
100

101
    @task
102
    @waitFor
103
    private async canDisplayWitdrawalButton(): Promise<void> {
104
        let isWithdrawalRejected = false;
5✔
105

106
        const withdrawalRequests = await this.preprint.requests;
5✔
107
        const withdrawalRequest = withdrawalRequests.firstObject;
5✔
108
        if (withdrawalRequest) {
5!
109
            const requestActions = await withdrawalRequest.queryHasMany('actions', {
×
110
                sort: '-modified',
111
            });
112

113
            const latestRequestAction = requestActions.firstObject;
×
114
            // @ts-ignore: ActionTrigger is never
115
            if (latestRequestAction && latestRequestAction.actionTrigger === 'reject') {
×
116
                isWithdrawalRejected = true;
×
117
            }
118
        }
119

120
        this.isWithdrawalButtonDisplayed = this.isAdmin() &&
5✔
121
        (this.preprint.reviewsState === ReviewsState.ACCEPTED ||
122
        this.preprint.reviewsState === ReviewsState.PENDING) && !isWithdrawalRejected;
123

124
    }
125

126
    private setValidationForEditFlow(): void {
127
        this.titleAndAbstractValidation = true;
5✔
128
        this.fileValidation = true;
5✔
129
        this.metadataValidation = true;
5✔
130
        this.authorAssertionValidation = true;
5✔
131
        this.supplementValidation = true;
5✔
132
        this.isNextButtonDisabled = false;
5✔
133
    }
134

135
    /**
136
     * Callback for the action-flow component
137
     */
138
    @task
139
    @waitFor
140
    public async onDelete(): Promise<void> {
141
        await this.preprint.deleteRecord();
×
142
        await this.router.transitionTo('preprints.discover', this.provider.id);
×
143
    }
144

145
    /**
146
     * Callback for the action-flow component
147
     */
148
    @task
149
    @waitFor
150
    public async onCancel(): Promise<void> {
151
        await this.router.transitionTo('preprints.detail', this.provider.id, this.preprint.id);
×
152
    }
153

154

155
    /**
156
     * Callback for the action-flow component
157
     */
158
    @task
159
    @waitFor
160
    public async onWithdrawal(): Promise<void> {
161
        try {
×
162
            const preprintRequest = await this.store.createRecord('preprint-request', {
×
163
                comment: this.preprint.withdrawalJustification,
164
                requestType: 'withdrawal',
165
                target: this.preprint,
166
            });
167

168
            await preprintRequest.save();
×
169

170
            this.toast.success(
×
171
                this.intl.t('preprints.submit.action-flow.success-withdrawal',
172
                    {
173
                        singularCapitalizedPreprintWord: this.provider.documentType.singularCapitalized,
174
                    }),
175
            );
176

177
            await this.router.transitionTo('preprints.detail', this.provider.id, this.preprint.id);
×
178
        } catch (e) {
179
            const errorMessage = this.intl.t('preprints.submit.action-flow.error-withdrawal',
×
180
                {
181
                    singularPreprintWord: this.provider.documentType.singular,
182
                });
183
            this.toast.error(errorMessage);
×
184
            captureException(e, { errorMessage });
×
185
        }
186
    }
187

188

189
    /**
190
     * saveOnStep
191
     *
192
     * @description Abstracted method to save after each step
193
     */
194
    private async saveOnStep(): Promise<void> {
195
        try {
×
196
            await this.preprint.save();
×
197
            this.toast.success(
×
198
                this.intl.t('preprints.submit.action-flow.success',
199
                    {
200
                        singularPreprintWord: this.provider.documentType.singular,
201
                    }),
202
            );
203
        } catch (e) {
204
            const errorMessage = this.intl.t('preprints.submit.action-flow.error',
×
205
                {
206
                    singularPreprintWord: this.provider.documentType.singular,
207
                });
208
            this.toast.error(errorMessage);
×
209
            captureException(e, { errorMessage });
×
210
        }
211
        this.statusFlowIndex++;
×
212
        this.determinePreviousButtonState();
×
213
    }
214

215
    /**
216
     * determinePreviousButtonState
217
     *
218
     * @description Abstracted method to determine the state of the previous button
219
     *
220
     * @returns void
221
     */
222
    private determinePreviousButtonState(): void {
223
        this.isPreviousButtonDisabled = this.statusFlowIndex === 1;
×
224
    }
225

226
    /**
227
     * Callback for the action-flow component
228
     */
229
    @task
230
    @waitFor
231
    public async onSubmit(): Promise<void> {
232
        this.args.resetPageDirty();
×
233

NEW
234
        if (this.isNewVersionFlow) {
×
NEW
235
            try {
×
NEW
236
                await this.preprint.save();
×
NEW
237
                let toastMessage = this.intl.t('preprints.submit.new-version.success');
×
238

NEW
239
                if (this.provider.reviewsWorkflow) {
×
NEW
240
                    toastMessage = this.intl.t('preprints.submit.new-version.success-review');
×
NEW
241
                    const reviewAction = this.store.createRecord('review-action', {
×
242
                        actionTrigger: ReviewActionTrigger.Submit,
243
                        target: this.preprint,
244
                    });
NEW
245
                    await reviewAction.save();
×
246
                } else {
NEW
247
                    this.preprint.isPublished = true;
×
NEW
248
                    await this.preprint.save();
×
249
                }
NEW
250
                this.toast.success(toastMessage);
×
NEW
251
                this.router.transitionTo('preprints.detail', this.provider.id, this.preprint.id);
×
252
            } catch (e) {
NEW
253
                const errorTitle = this.intl.t('preprints.submit.new-version.error.title');
×
NEW
254
                let errorMessage = this.intl.t('preprints.submit.new-version.error.description',
×
255
                    { preprintWord: this.provider.documentType.singular });
NEW
256
                if (e.errors[0].status === 409) { // Conflict
×
NEW
257
                    errorMessage = this.intl.t('preprints.submit.new-version.error.conflict');
×
258
                }
NEW
259
                this.toast.error(errorMessage, errorTitle);
×
260
            }
NEW
261
            return;
×
262
        }
263

264
        if (this.preprint.reviewsState === ReviewsState.ACCEPTED) {
×
265
            await this.preprint.save();
×
266
        } else if (this.provider.reviewsWorkflow) {
×
267
            const reviewAction = this.store.createRecord('review-action', {
×
268
                actionTrigger: ReviewActionTrigger.Submit,
269
                target: this.preprint,
270
            });
271
            await reviewAction.save();
×
272
        } else {
273
            this.preprint.isPublished = true;
×
274
            await this.preprint.save();
×
275
        }
276

277
        await this.preprint.reload();
×
278
        await this.router.transitionTo('preprints.detail', this.provider.id, this.preprint.id);
×
279
    }
280

281
    /**
282
     * Callback for the action-flow component
283
     */
284
    @task
285
    @waitFor
286
    public async onNext(): Promise<void> {
NEW
287
        if (this.isNewVersionFlow) {
×
288
            // no need to save original or new version on new version flow
NEW
289
            this.statusFlowIndex++;
×
NEW
290
            return;
×
291
        }
292

293
        if (this.isEditFlow) {
×
294
            this.args.resetPageDirty();
×
295
        } else {
296
            this.args.setPageDirty();
×
297
        }
298
        this.isNextButtonDisabled = true;
×
299

300
        if (
×
301
            this.statusFlowIndex === this.getTypeIndex(PreprintStatusTypeEnum.titleAndAbstract) &&
×
302
            this.titleAndAbstractValidation
303
        ) {
304
            await this.saveOnStep();
×
305
            if (this.displayFileUploadStep) {
×
306
                await this.preprint.files;
×
307
                this.isNextButtonDisabled = !this.fileValidation;
×
308
            } else {
309
                this.isNextButtonDisabled = !this.metadataValidation;
×
310
            }
311
            return;
×
312
        } else if (
×
313
            this.statusFlowIndex === this.getTypeIndex(PreprintStatusTypeEnum.file) &&
×
314
            this.fileValidation
315
        ) {
316
            await this.saveOnStep();
×
317
            this.isNextButtonDisabled = !this.metadataValidation;
×
318
            return;
×
319
        } else if (
×
320
            this.statusFlowIndex === this.getTypeIndex(PreprintStatusTypeEnum.metadata) &&
×
321
            this.metadataValidation
322
        ) {
323
            await this.saveOnStep();
×
324

325
            if (this.preprint.currentUserPermissions.includes(Permission.Write)) {
×
326
                try {
×
327
                    await this.preprint.updateM2MRelationship(
×
328
                        'affiliatedInstitutions',
329
                        this.affiliatedInstitutions,
330
                    );
331
                    await this.preprint.reload();
×
332
                } catch (e) {
333
                    // eslint-disable-next-line max-len
334
                    const errorMessage = this.intl.t('preprints.submit.step-metadata.institutions.save-institutions-error');
×
335
                    captureException(e, { errorMessage });
×
336
                    this.toast.error(getApiErrorMessage(e), errorMessage);
×
337
                    throw e;
×
338
                }
339
            }
340

341
            if (this.displayAuthorAssertions) {
×
342
                this.isNextButtonDisabled = !this.authorAssertionValidation;
×
343
            } else {
344
                this.isNextButtonDisabled = !this.supplementValidation;
×
345
            }
346
            return;
×
347
        } else if (
×
348
            this.statusFlowIndex === this.getTypeIndex(PreprintStatusTypeEnum.authorAssertions) &&
×
349
            this.authorAssertionValidation
350
        ) {
351
            await this.saveOnStep();
×
352
            this.isNextButtonDisabled = !this.supplementValidation;
×
353
            return;
×
354
        } else if (
×
355
            this.statusFlowIndex === this.getTypeIndex(PreprintStatusTypeEnum.supplements) &&
×
356
            this.supplementValidation
357
        ) {
358
            await this.saveOnStep();
×
359
            return;
×
360
        }
361
    }
362

363
    private setPageDirty(): void {
364
        if (this.isEditFlow) {
1!
365
            this.args.setPageDirty();
×
366
        }
367
    }
368

369
    /**
370
     * Callback for the action-flow component
371
     */
372
    @action
373
    public validateTitleAndAbstract(valid: boolean): void {
374
        this.titleAndAbstractValidation = valid;
×
375
        this.isNextButtonDisabled = !valid;
×
376
        this.setPageDirty();
×
377
    }
378

379
    /**
380
     * Callback for the action-flow component
381
     */
382
    @action
383
    public validateFile(valid: boolean): void {
384
        this.fileValidation = valid;
1✔
385
        this.isNextButtonDisabled = !valid;
1✔
386
        this.setPageDirty();
1✔
387
    }
388

389
    /**
390
     * Callback for the action-flow component
391
     */
392
    @action
393
    public validateMetadata(valid: boolean): void {
394
        this.metadataValidation = valid;
×
395
        this.isNextButtonDisabled = !valid;
×
396
        this.setPageDirty();
×
397
    }
398

399
    /**
400
     * Callback for the action-flow component
401
     */
402
    @action
403
    public validateAuthorAssertions(valid: boolean): void {
404
        if (this.preprint.hasCoi === false) {
×
405
            this.preprint.conflictOfInterestStatement = null;
×
406
        }
407
        if (this.preprint.hasDataLinks === PreprintDataLinksEnum.NOT_APPLICABLE) {
×
408
            this.preprint.whyNoData = null;
×
409
        }
410
        if (this.preprint.hasPreregLinks === PreprintPreregLinksEnum.NOT_APPLICABLE) {
×
411
            this.preprint.whyNoPrereg = null;
×
412
        }
413
        this.authorAssertionValidation = valid;
×
414
        this.isNextButtonDisabled = !valid;
×
415
        this.setPageDirty();
×
416
    }
417

418
    /**
419
     * Callback for the action-flow component
420
     */
421
    @action
422
    public validateSupplements(valid: boolean): void {
423
        this.supplementValidation = valid;
×
424
        this.isNextButtonDisabled = !valid;
×
425
        this.setPageDirty();
×
426
    }
427

428
    @action
429
    public onPrevious(): void {
430
        if (this.statusFlowIndex > 1) {
×
431
            this.statusFlowIndex--;
×
432
        }
433
        this.determinePreviousButtonState();
×
434
        this.isNextButtonDisabled = false;
×
435
    }
436

437
    @action
438
    public onClickStep(type: string): void {
439
        this.isNextButtonDisabled = !this.isFinished(type);
×
440
        if (
×
441
            type === PreprintStatusTypeEnum.titleAndAbstract &&
×
442
            this.statusFlowIndex > this.getTypeIndex(type)
443
        ) {
444
            this.statusFlowIndex = this.getTypeIndex(type);
×
445
        } else if (
×
446
            type === PreprintStatusTypeEnum.file &&
×
447
            this.statusFlowIndex > this.getTypeIndex(type)
448
        ) {
449
            this.statusFlowIndex = this.getTypeIndex(type);
×
450
        } else if (
×
451
            type === PreprintStatusTypeEnum.metadata &&
×
452
            this.statusFlowIndex > this.getTypeIndex(type)
453
        ) {
454
            this.statusFlowIndex = this.getTypeIndex(type);
×
455
        } else if (
×
456
            type === PreprintStatusTypeEnum.authorAssertions &&
×
457
            this.statusFlowIndex > this.getTypeIndex(type) &&
458
            this.displayAuthorAssertions
459
        ) {
460
            this.statusFlowIndex = this.getTypeIndex(type);
×
461
        } else if (
×
462
            type === PreprintStatusTypeEnum.supplements &&
×
463
            this.statusFlowIndex > this.getTypeIndex(type)
464
        ) {
465
            this.statusFlowIndex = this.getTypeIndex(type);
×
466
        } else if (
×
467
            type === PreprintStatusTypeEnum.review &&
×
468
            this.statusFlowIndex > this.getTypeIndex(type)
469
        ) {
470
            this.statusFlowIndex = this.getTypeIndex(type);
×
471
        }
472

473
        this.determinePreviousButtonState();
×
474
    }
475

476
    @action
477
    public isSelected(type: string): boolean {
478
        if (
337✔
479
            type === PreprintStatusTypeEnum.titleAndAbstract &&
395✔
480
            this.getTypeIndex(type) === this.statusFlowIndex
481
        ) {
482
            return true;
56✔
483
        } else if (
281✔
484
            type === PreprintStatusTypeEnum.file &&
327✔
485
            this.getTypeIndex(type) === this.statusFlowIndex
486
        ) {
487
            return true;
8✔
488
        } else if (
273!
489
            type === PreprintStatusTypeEnum.metadata &&
331✔
490
            this.getTypeIndex(type) === this.statusFlowIndex
491
        ) {
492
            return true;
×
493
        } else if (
273!
494
            type === PreprintStatusTypeEnum.authorAssertions &&
316!
495
            this.getTypeIndex(type) === this.statusFlowIndex &&
496
            this.displayAuthorAssertions
497
        ) {
498
            return true;
×
499
        } else if (
273!
500
            type === PreprintStatusTypeEnum.supplements &&
331✔
501
            this.getTypeIndex(type) === this.statusFlowIndex
502
        ) {
503
            return true;
×
504
        } else if (
273!
505
            type === PreprintStatusTypeEnum.review &&
347✔
506
            this.getTypeIndex(type) === this.statusFlowIndex
507
        ) {
508
            return true;
×
509
        } else {
510
            return false;
273✔
511
        }
512
    }
513

514
    @action
515
    public getAnalytics(type: string): string {
516
        return this.intl.t('preprints.submit.data-analytics', {statusType: this.getStatusTitle(type)  } );
×
517
    }
518

519

520
    @action
521
    public isDisabled(type: string): boolean {
522
        if (
×
523
            type === PreprintStatusTypeEnum.titleAndAbstract &&
×
524
            this.getTypeIndex(type) === this.statusFlowIndex
525
        ) {
526
            return true;
×
527
        } else if (
×
528
            type === PreprintStatusTypeEnum.file &&
×
529
            this.getTypeIndex(type) === this.statusFlowIndex
530
        ) {
531
            return true;
×
532
        } else if (
×
533
            type === PreprintStatusTypeEnum.metadata &&
×
534
            this.getTypeIndex(type) === this.statusFlowIndex
535
        ) {
536
            return true;
×
537
        } else if (
×
538
            type === PreprintStatusTypeEnum.authorAssertions &&
×
539
            this.getTypeIndex(type) === this.statusFlowIndex &&
540
            this.displayAuthorAssertions
541
        ) {
542
            return true;
×
543
        } else if (
×
544
            type === PreprintStatusTypeEnum.supplements &&
×
545
            this.getTypeIndex(type) === this.statusFlowIndex
546
        ) {
547
            return true;
×
548
        } else if (
×
549
            type === PreprintStatusTypeEnum.review &&
×
550
            this.getTypeIndex(type) === this.statusFlowIndex
551
        ) {
552
            return true;
×
553
        } else {
554
            return false;
×
555
        }
556
    }
557

558
    private getTypeIndex(type: string): number {
559
        if (this.isNewVersionFlow) {
613✔
560
            if (type === PreprintStatusTypeEnum.file) {
37✔
561
                return 1;
12✔
562
            } else if (type === PreprintStatusTypeEnum.review) {
25✔
563
                return 2;
17✔
564
            } else {
565
                return 0;
8✔
566
            }
567
        }
568

569
        if (this.displayFileUploadStep) {
576✔
570
            if (type === PreprintStatusTypeEnum.titleAndAbstract) {
353✔
571
                return 1;
48✔
572
            } else if (type === PreprintStatusTypeEnum.file) {
305✔
573
                return 2;
64✔
574
            } else if (type === PreprintStatusTypeEnum.metadata) {
241✔
575
                return 3;
64✔
576
            } else if (type === PreprintStatusTypeEnum.authorAssertions) {
177✔
577
                return 4;
43✔
578
            } else if (type === PreprintStatusTypeEnum.supplements && this.displayAuthorAssertions) {
134✔
579
                return 5;
40✔
580
            } else if (type === PreprintStatusTypeEnum.supplements && !this.displayAuthorAssertions) {
94✔
581
                return 4;
24✔
582
            } else if (type === PreprintStatusTypeEnum.review && this.displayAuthorAssertions) {
70✔
583
                return 6;
44✔
584
            } else if (type === PreprintStatusTypeEnum.review && !this.displayAuthorAssertions) {
26!
585
                return 5;
26✔
586
            } else {
587
                return 0;
×
588
            }
589
        } else {
590
            if (type === PreprintStatusTypeEnum.titleAndAbstract) {
223✔
591
                return 1;
36✔
592
            } else if (type === PreprintStatusTypeEnum.metadata) {
187✔
593
                return 2;
48✔
594
            } else if (type === PreprintStatusTypeEnum.authorAssertions) {
139✔
595
                return 3;
34✔
596
            } else if (type === PreprintStatusTypeEnum.supplements && this.displayAuthorAssertions) {
105✔
597
                return 4;
32✔
598
            } else if (type === PreprintStatusTypeEnum.supplements && !this.displayAuthorAssertions) {
73✔
599
                return 3;
16✔
600
            } else if (type === PreprintStatusTypeEnum.review && this.displayAuthorAssertions) {
57✔
601
                return 5;
34✔
602
            } else if (type === PreprintStatusTypeEnum.review && !this.displayAuthorAssertions) {
23✔
603
                return 4;
17✔
604
            } else {
605
                return 0;
6✔
606
            }
607
        }
608
    }
609

610
    @action
611
    public isFinished(type: string): boolean {
612
        if (this.displayAuthorAssertions && this.statusFlowIndex > this.getTypeIndex(type)) {
138!
613
            return true;
×
614
        } else if (!this.displayAuthorAssertions && this.statusFlowIndex > this.getTypeIndex(type)) {
138!
615
            return true;
×
616
        } else if (this.statusFlowIndex > this.getTypeIndex(type)) {
138!
617
            return true;
×
618
        } else {
619
            return false;
138✔
620
        }
621
    }
622

623
    @action
624
    public getStatusTitle(type: string): string {
625
        switch (type) {
77!
626
        case PreprintStatusTypeEnum.titleAndAbstract:
627
            return this.intl.t('preprints.submit.status-flow.step-title-and-abstract');
14✔
628
        case PreprintStatusTypeEnum.file:
629
            return this.intl.t('preprints.submit.status-flow.step-file');
10✔
630
        case PreprintStatusTypeEnum.metadata:
631
            return this.intl.t('preprints.submit.status-flow.step-metadata');
14✔
632
        case PreprintStatusTypeEnum.authorAssertions:
633
            return this.intl.t('preprints.submit.status-flow.step-author-assertions');
9✔
634
        case PreprintStatusTypeEnum.supplements:
635
            return this.intl.t('preprints.submit.status-flow.step-supplements');
14✔
636
        case PreprintStatusTypeEnum.review:
637
            return this.intl.t('preprints.submit.status-flow.step-review');
16✔
638
        default:
639
            return '';
×
640
        }
641
    }
642

643
    @action
644
    public getFaIcon(type: string): string {
645
        if (this.isSelected(type)) {
77✔
646
            return 'dot-circle';
16✔
647
        } else if (this.isFinished(type)) {
61!
648
            return 'check-circle';
×
649
        } else {
650
            return 'circle';
61✔
651
        }
652
    }
653

654
    /**
655
     * shoulddisplayStatusType
656
     *
657
     * @description Determines if the status type should be displayed
658
     *
659
     * @returns boolean
660
     */
661
    public shouldDisplayStatusType(type: string): boolean{
662
        if (this.isNewVersionFlow) {
96✔
663
            if (type === PreprintStatusTypeEnum.file) {
12✔
664
                return true;
2✔
665
            } else if (type === PreprintStatusTypeEnum.review) {
10✔
666
                return true;
2✔
667
            } else {
668
                return false;
8✔
669
            }
670
        }
671

672
        if (type === PreprintStatusTypeEnum.file) {
84✔
673
            return this.displayFileUploadStep;
14✔
674
        } else if (type === PreprintStatusTypeEnum.authorAssertions) {
70✔
675
            return this.displayAuthorAssertions;
14✔
676
        }
677
        return true;
56✔
678
    }
679

680
    /**
681
     * getTitleAndAbstractType
682
     *
683
     * @description Provides the enum type to limit strings in the hbs files
684
     *
685
     * @returns strings
686
     */
687
    public get getTitleAndAbstractType(): string {
688
        return PreprintStatusTypeEnum.titleAndAbstract;
10✔
689
    }
690

691
    /**
692
     * getFileType
693
     *
694
     * @description Provides the enum type to limit strings in the hbs files
695
     *
696
     * @returns strings
697
     */
698
    public get getFileType(): string {
699
        return PreprintStatusTypeEnum.file;
10✔
700
    }
701

702
    /**
703
     * getMetadataType
704
     *
705
     * @description Provides the enum type to limit strings in the hbs files
706
     *
707
     * @returns strings
708
     */
709
    public get getMetadataType(): string {
710
        return PreprintStatusTypeEnum.metadata;
10✔
711
    }
712

713
    /**
714
     * getAuthorAssertionsType
715
     *
716
     * @description Provides the enum type to limit strings in the hbs files
717
     *
718
     * @returns strings
719
     */
720
    public get getAuthorAssertionsType(): string {
721
        return PreprintStatusTypeEnum.authorAssertions;
10✔
722
    }
723

724
    /**
725
     * getSupplementsType
726
     *
727
     * @description Provides the enum type to limit strings in the hbs files
728
     *
729
     * @returns strings
730
     */
731
    public get getSupplementsType(): string {
732
        return PreprintStatusTypeEnum.supplements;
10✔
733
    }
734

735
    /**
736
     * getReviewType
737
     *
738
     * @description Provides the enum type to limit strings in the hbs files
739
     *
740
     * @returns strings
741
     */
742
    public get getReviewType(): string {
743
        return PreprintStatusTypeEnum.review;
10✔
744
    }
745

746
    @task
747
    @waitFor
748
    public async addProjectFile(file: FileModel): Promise<void>{
NEW
749
        const target = this.preprint;
×
NEW
750
        await file.copy(target, '/', 'osfstorage', {
×
751
            conflict: 'replace',
752
        });
NEW
753
        const theFiles = await target.files;
×
754
        const rootFolder = await theFiles.firstObject!.rootFolder;
×
755
        const primaryFile = await rootFolder!.files;
×
NEW
756
        target.set('primaryFile', primaryFile.lastObject);
×
757
    }
758

759
    @action
760
    public updateAffiliatedInstitution(institution: InstitutionModel): void {
761
        if (this.isInstitutionAffiliated(institution.id)) {
×
762
            this.affiliatedInstitutions.removeObject(institution);
×
763
        } else {
764
            this.affiliatedInstitutions.addObject(institution);
×
765
        }
766
    }
767

768
    private isInstitutionAffiliated(id: string): boolean {
769
        return this.affiliatedInstitutions.find(
×
770
            institution => institution.id === id,
×
771
        ) !== undefined;
772
    }
773

774
    @action
775
    public resetAffiliatedInstitutions(): void {
776
        this.affiliatedInstitutions.length = 0;
×
777
    }
778

779
    public isAdmin(): boolean {
780
        return this.preprint.currentUserPermissions?.includes(Permission.Admin);
5✔
781
    }
782

783
    public isElementDisabled(): boolean {
784
        return !this.isAdmin();
×
785
    }
786

787
    public isAffiliatedInstitutionsDisabled(): boolean {
788
        return !this.preprint.currentUserPermissions.includes(Permission.Write);
×
789
    }
790
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc