From 1b83dface9dbf567aac42284dcfdd1e38b8127ce Mon Sep 17 00:00:00 2001
From: futa-ikeda <futa.ikeda@gmail.com>
Date: Fri, 20 Dec 2024 18:37:26 -0500
Subject: [PATCH] WIP new version re-work

---
 .../preprint-state-machine/component.ts       | 55 ++++----------
 app/preprints/detail/controller.ts            | 25 +++++++
 app/preprints/detail/route.ts                 |  2 +-
 app/preprints/detail/template.hbs             |  8 +-
 app/preprints/new-version/route.ts            | 26 ++++---
 mirage/factories/preprint.ts                  |  8 +-
 mirage/scenarios/preprints.ts                 | 75 +++++++++----------
 7 files changed, 100 insertions(+), 99 deletions(-)

diff --git a/app/preprints/-components/submit/preprint-state-machine/component.ts b/app/preprints/-components/submit/preprint-state-machine/component.ts
index 45b07ce0ee..b079c25e15 100644
--- a/app/preprints/-components/submit/preprint-state-machine/component.ts
+++ b/app/preprints/-components/submit/preprint-state-machine/component.ts
@@ -61,7 +61,6 @@ export default class PreprintStateMachine extends Component<StateMachineArgs>{
 
     provider = this.args.provider;
     @tracked preprint: PreprintModel;
-    @tracked tempVersion?: PreprintModel;
     displayAuthorAssertions = false;
     @tracked statusFlowIndex = 1;
     @tracked isEditFlow = false;
@@ -73,9 +72,6 @@ export default class PreprintStateMachine extends Component<StateMachineArgs>{
         super(owner, args);
 
         if (this.args.newVersion) {
-            // Create ephemeral preprint to prevent the original preprint from being overwritten
-            // Also stores primary file for new version
-            this.tempVersion = this.store.createRecord('preprint');
             this.preprint = this.args.preprint;
             return;
         }
@@ -237,43 +233,22 @@ export default class PreprintStateMachine extends Component<StateMachineArgs>{
 
         if (this.isNewVersionFlow) {
             try {
-                const url = this.preprint.links.preprint_versions as string;
-                if (url && this.tempVersion) {
-                    const savedVersionData = await this.currentUser.authenticatedAJAX({
-                        url,
-                        type: 'POST',
-                        headers: {
-                            'Content-Type': 'application/json',
-                        },
-                        data: JSON.stringify({
-                            data: {
-                                type: 'preprints',
-                                attributes: {
-                                    primary_file: (await this.tempVersion.primaryFile)?.get('id'),
-                                },
-                            },
-                        }),
+                await this.preprint.save();
+                let toastMessage = this.intl.t('preprints.submit.new-version.success');
+
+                if (this.provider.reviewsWorkflow) {
+                    toastMessage = this.intl.t('preprints.submit.new-version.success-review');
+                    const reviewAction = this.store.createRecord('review-action', {
+                        actionTrigger: ReviewActionTrigger.Submit,
+                        target: this.preprint,
                     });
-                    this.store.pushPayload('preprint', savedVersionData);
-                    const storedPreprintRecord = this.store.peekRecord('preprint', savedVersionData.data.id);
-                    let toastMessage = this.intl.t('preprints.submit.new-version.success');
-
-                    if (this.provider.reviewsWorkflow) {
-                        toastMessage = this.intl.t('preprints.submit.new-version.success-review');
-                        const reviewAction = this.store.createRecord('review-action', {
-                            actionTrigger: ReviewActionTrigger.Submit,
-                            target: storedPreprintRecord,
-                        });
-                        await reviewAction.save();
-                    } else {
-                        storedPreprintRecord.isPublished = true;
-                        await storedPreprintRecord.save();
-                    }
-                    this.tempVersion.destroyRecord();
-                    await this.preprint.reload(); // Refresh the original preprint as this is no longer latest version
-                    this.toast.success(toastMessage);
-                    this.router.transitionTo('preprints.detail', this.provider.id, storedPreprintRecord.id);
+                    await reviewAction.save();
+                } else {
+                    this.preprint.isPublished = true;
+                    await this.preprint.save();
                 }
+                this.toast.success(toastMessage);
+                this.router.transitionTo('preprints.detail', this.provider.id, this.preprint.id);
             } catch (e) {
                 const errorTitle = this.intl.t('preprints.submit.new-version.error.title');
                 let errorMessage = this.intl.t('preprints.submit.new-version.error.description',
@@ -771,7 +746,7 @@ export default class PreprintStateMachine extends Component<StateMachineArgs>{
     @task
     @waitFor
     public async addProjectFile(file: FileModel): Promise<void>{
-        const target = (this.isNewVersionFlow ? this.tempVersion : this.preprint)  as PreprintModel;
+        const target = this.preprint;
         await file.copy(target, '/', 'osfstorage', {
             conflict: 'replace',
         });
diff --git a/app/preprints/detail/controller.ts b/app/preprints/detail/controller.ts
index a052aac70a..691d5d57c5 100644
--- a/app/preprints/detail/controller.ts
+++ b/app/preprints/detail/controller.ts
@@ -11,6 +11,9 @@ import { Permission } from 'ember-osf-web/models/osf-model';
 import { ReviewsState, PreprintProviderReviewsWorkFlow } from 'ember-osf-web/models/provider';
 import { tracked } from '@glimmer/tracking';
 import Media from 'ember-responsive';
+import Toast from 'ember-toastr/services/toast';
+import { task } from 'ember-concurrency';
+import { waitFor } from '@ember/test-waiters';
 
 
 /**
@@ -44,6 +47,7 @@ export default class PrePrintsDetailController extends Controller {
     @service features!: Features;
     @service intl!: Intl;
     @service media!: Media;
+    @service toast!: Toast;
 
     @tracked fullScreenMFR = false;
     @tracked plauditIsReady = false;
@@ -140,6 +144,27 @@ export default class PrePrintsDetailController extends Controller {
         this.send('click', category, label, url);
     }
 
+    @task
+    @waitFor
+    async createNewVersion() {
+        try {
+            const url = this.model.preprint.links.preprint_versions as string;
+            const newVersion = await this.currentUser.authenticatedAJAX({
+                url,
+                type: 'POST',
+            });
+            this.transitionToRoute('preprints.new-version', this.model.provider.id, newVersion.id);
+        } catch (e) {
+            const errorTitle = this.intl.t('preprints.submit.new-version.error.title');
+            let errorMessage = this.intl.t('preprints.submit.new-version.error.description',
+                { preprintWord: this.model.provider.documentType.singular });
+            if (e.errors[0].status === 409) { // Conflict
+                errorMessage = this.intl.t('preprints.submit.new-version.error.conflict');
+            }
+            this.toast.error(errorMessage, errorTitle);
+        }
+    }
+
     get isMobile() {
         return this.media.isMobile;
     }
diff --git a/app/preprints/detail/route.ts b/app/preprints/detail/route.ts
index 2d9d476f95..37d2a77b37 100644
--- a/app/preprints/detail/route.ts
+++ b/app/preprints/detail/route.ts
@@ -91,7 +91,7 @@ export default class PreprintsDetail extends Route {
 
         } catch (error) {
             captureException(error);
-            this.router.transitionTo('not-found', 'preprints');
+            this.router.transitionTo('not-found', this.router.currentURL.slice(1));
             return null;
         }
     }
diff --git a/app/preprints/detail/template.hbs b/app/preprints/detail/template.hbs
index 6a7a81b900..48a71ea298 100644
--- a/app/preprints/detail/template.hbs
+++ b/app/preprints/detail/template.hbs
@@ -25,15 +25,15 @@
                     {{/if}}
                 {{/unless}}
                 {{#if this.model.preprint.canCreateNewVersion}}
-                    <OsfLink
+                    <Button
                         data-test-create-new-version-button
                         data-analytics-name='Create new version'
                         local-class='btn btn-primary'
-                        @route='preprints.new-version'
-                        @models={{array this.model.provider.id this.model.preprint.id}}
+                        @layout='fake-link'
+                        {{on 'click' (perform this.createNewVersion)}}
                     >
                         {{t 'preprints.detail.create_new_version'}}
-                    </OsfLink>
+                    </Button>
                 {{/if}}
             </div>
         </div>
diff --git a/app/preprints/new-version/route.ts b/app/preprints/new-version/route.ts
index fe76765749..d7db18c1f0 100644
--- a/app/preprints/new-version/route.ts
+++ b/app/preprints/new-version/route.ts
@@ -3,6 +3,7 @@ import Route from '@ember/routing/route';
 import RouterService from '@ember/routing/router-service';
 import { inject as service } from '@ember/service';
 import Toast from 'ember-toastr/services/toast';
+import Intl from 'ember-intl/services/intl';
 
 import Theme from 'ember-osf-web/services/theme';
 import MetaTags, { HeadTagDef } from 'ember-osf-web/services/meta-tags';
@@ -35,19 +36,20 @@ export default class PreprintNewVersionRoute extends Route {
 
             const preprint: PreprintModel = await this.store.findRecord('preprint', args.guid);
 
-            if (!preprint.canCreateNewVersion) {
-                let message = this.intl.t('prperints.submit.new-version.redirect.latest-published',
-                    { preprintWord: provider.documentType.singular });
-                if (!preprint.currentUserIsAdmin) {
-                    message = this.intl.t('prperints.submit.new-version.redirect.permission',
-                        { preprintWord: provider.documentType.singular });
-                }
+            // TODO: Re-evaluate if re-route logic is necessary
+            // if (!preprint.canCreateNewVersion) {
+            //     let message = this.intl.t('preprints.submit.new-version.redirect.latest-published',
+            //         { preprintWord: provider.documentType.singular });
+            //     if (!preprint.currentUserIsAdmin) {
+            //         message = this.intl.t('preprints.submit.new-version.redirect.permission',
+            //             { preprintWord: provider.documentType.singular });
+            //     }
 
-                const title = this.intl.t('prperints.submit.new-version.redirect.title');
-                this.toast.info(message, title);
-                this.router.transitionTo('preprints.detail', args.provider_id, args.guid);
-                return null;
-            }
+            //     const title = this.intl.t('preprints.submit.new-version.redirect.title');
+            //     this.toast.info(message, title);
+            //     this.router.transitionTo('preprints.detail', args.provider_id, args.guid);
+            //     return null;
+            // }
 
             return {
                 provider,
diff --git a/mirage/factories/preprint.ts b/mirage/factories/preprint.ts
index 0e6e4854b8..77bcd06125 100644
--- a/mirage/factories/preprint.ts
+++ b/mirage/factories/preprint.ts
@@ -246,14 +246,15 @@ export default Factory.extend<PreprintMirageModel & PreprintTraits>({
         afterCreate(preprint, server) {
             const baseId = preprint.id;
             const versionedPreprints = [1, 2, 3].map((version: number) => {
-                server.create('preprint', {
+                const isLatestVersion = version === 3;
+                return server.create('preprint', {
                     title: preprint.title,
                     description: preprint.description,
                     provider: preprint.provider,
                     id: `${baseId}_v${version}`,
                     reviewsState: preprint.reviewsState,
                     preprintVersion: version,
-                    isLatestVersion: version === 3,
+                    isLatestVersion,
                 });
             });
             preprint.update({
@@ -261,8 +262,9 @@ export default Factory.extend<PreprintMirageModel & PreprintTraits>({
                 preprintVersion: 3,
                 isLatestVersion: true,
             });
+
             if (preprint.provider) {
-                preprint.provider.update({ preprints: versionedPreprints });
+                preprint.provider.preprints.models.pushObjects(versionedPreprints);
             }
         },
     }),
diff --git a/mirage/scenarios/preprints.ts b/mirage/scenarios/preprints.ts
index 601520e3e2..8a87ea69fa 100644
--- a/mirage/scenarios/preprints.ts
+++ b/mirage/scenarios/preprints.ts
@@ -39,7 +39,7 @@ function buildOSF(
     const currentUserModerator = server.create('moderator',
         { id: currentUser.id, user: currentUser, provider: osf }, 'asAdmin');
 
-    const rejectedAdminPreprint = server.create('preprint', {
+    server.create('preprint', {
         provider: osf,
         id: 'osf-rejected-admin',
         title: 'Preprint RWF: Pre-moderation, Admin and Rejected with Review Actions comment',
@@ -74,7 +74,7 @@ function buildOSF(
 
     approvedAdminPreprint.update({ identifiers: [osfApprovedAdminIdentifier] });
 
-    const notContributorPreprint = server.create('preprint', Object({
+    server.create('preprint', Object({
         provider: osf,
         id: 'osf-not-contributor',
         title: 'Preprint RWF: Pre-moderation, Non-Admin and Rejected',
@@ -88,7 +88,7 @@ function buildOSF(
         isPreprintDoi: false,
     }));
 
-    const rejectedPreprint = server.create('preprint', {
+    server.create('preprint', {
         provider: osf,
         id: 'osf-rejected',
         title: 'Preprint RWF: Pre-moderation, Non-Admin and Rejected',
@@ -99,7 +99,7 @@ function buildOSF(
         tags: [],
     }, 'isContributor');
 
-    const approvedPreprint = server.create('preprint', {
+    server.create('preprint', {
         provider: osf,
         id: 'osf-approved',
         title: 'Preprint RWF: Pre-moderation, Non-Admin and Approved',
@@ -120,7 +120,7 @@ function buildOSF(
         conflictOfInterestStatement: `${faker.lorem.sentence(200)}\n${faker.lorem.sentence(300)}`,
     }, 'isContributor');
 
-    const orphanedPreprint = server.create('preprint', {
+    server.create('preprint', {
         provider: osf,
         id: 'osf-orphan',
         title: 'Preprint RWF: Pre-moderation, Non-Admin and Approved',
@@ -129,7 +129,7 @@ function buildOSF(
         isPreprintOrphan: true,
     }, 'isContributor');
 
-    const privatePreprint = server.create('preprint', Object({
+    server.create('preprint', Object({
         provider: osf,
         id: 'osf-private',
         title: 'Preprint RWF: Pre-moderation, Non-Admin and Approved',
@@ -139,7 +139,7 @@ function buildOSF(
         isPreprintDoi: false,
     }), 'isContributor');
 
-    const publicDoiPreprint = server.create('preprint', Object({
+    server.create('preprint', Object({
         provider: osf,
         id: 'osf-public-doi',
         title: 'Preprint RWF: Pre-moderation, Non-Admin and Approved',
@@ -151,7 +151,7 @@ function buildOSF(
         isPublished: true,
     }), 'isContributor');
 
-    const notPublishedPreprint = server.create('preprint', {
+    server.create('preprint', {
         provider: osf,
         id: 'osf-not-published',
         title: 'Preprint RWF: Pre-moderation, Non-Admin and Approved',
@@ -160,7 +160,7 @@ function buildOSF(
         isPublished: false,
     }, 'isContributor');
 
-    const withdrawnPreprint = server.create('preprint', Object({
+    server.create('preprint', Object({
         provider: osf,
         id: 'osf-withdrawn',
         title: 'Preprint Non-Admin, Not Published and withdrawn - no license - no justification',
@@ -171,7 +171,7 @@ function buildOSF(
         addLicenseName: false,
     }), 'isContributor', 'withdrawn' );
 
-    const withdrawnLicensePreprint = server.create('preprint', Object({
+    server.create('preprint', Object({
         provider: osf,
         id: 'osf-withdrawn-license',
         title: 'Preprint Non-Admin, Not Published and withdrawn - license - justification - tombstone',
@@ -183,7 +183,7 @@ function buildOSF(
         description: `${faker.lorem.sentence(200)}\n${faker.lorem.sentence(100)}`,
     }), 'isContributor', 'withdrawn');
 
-    const pendingWithdrawalPreprint = server.create('preprint', {
+    server.create('preprint', {
         provider: osf,
         id: 'osf-pending-withdrawal',
         title: 'Preprint Non-Admin, Not Published and Pending Withdrawal',
@@ -192,7 +192,7 @@ function buildOSF(
         isPublished: false,
     }, 'pendingWithdrawal', 'isContributor');
 
-    const rejectedWithdrawalPreprintNoComment = server.create('preprint', {
+    server.create('preprint', {
         provider: osf,
         id: 'osf-rejected-withdrawal-no-comment',
         title: 'Preprint Non-Admin, Not Published and Rejected Withdrawal - No Comment',
@@ -201,7 +201,7 @@ function buildOSF(
         isPublished: false,
     }, 'rejectedWithdrawalNoComment', 'isContributor');
 
-    const rejectedWithdrawalPreprintComment = server.create('preprint', {
+    server.create('preprint', {
         provider: osf,
         id: 'osf-rejected-withdrawal-comment',
         title: 'Preprint Non-Admin, Not Published and Rejected Withdrawal - Comment - Reviews Allowed',
@@ -210,7 +210,7 @@ function buildOSF(
         isPublished: false,
     }, 'rejectedWithdrawalComment', 'isContributor');
 
-    const acceptedWithdrawalPreprintComment = server.create('preprint', {
+    server.create('preprint', {
         provider: osf,
         id: 'osf-accepted-withdrawal-comment',
         title: 'Preprint Non-Admin, Not Published and Accepted Withdrawal - Comment - Reviews Allowed',
@@ -219,7 +219,7 @@ function buildOSF(
         isPublished: false,
     }, 'acceptedWithdrawalComment');
 
-    const examplePreprint = server.create('preprint', {
+    server.create('preprint', {
         provider: osf,
         id: 'khbvy',
         title: 'The "See Example" hard-coded preprint',
@@ -234,7 +234,8 @@ function buildOSF(
         hasPreregLinks: PreprintPreregLinksEnum.NOT_APPLICABLE,
     });
 
-    const versionedPreprint = server.create('preprint', {
+    // Accepted with versions
+    server.create('preprint', {
         provider: osf,
         id: 'versioned-preprint',
         title: '3 Versions Preprint',
@@ -242,9 +243,25 @@ function buildOSF(
         reviewsState: ReviewsState.ACCEPTED,
         isPublished: true,
     }, 'withVersions');
-    const version1 = server.schema.preprints.find('versioned-preprint_v1');
-    const version2 = server.schema.preprints.find('versioned-preprint_v2');
-    const version3 = server.schema.preprints.find('versioned-preprint_v3');
+    // Withdrawn with versions
+    server.create('preprint', {
+        provider: osf,
+        id: 'withdrawn-preprint',
+        title: 'ReviewsState: Withdrawn Preprint',
+        currentUserPermissions: Object.values(Permission),
+        reviewsState: ReviewsState.WITHDRAWN,
+        isPublished: true,
+        dateWithdrawn: new Date(),
+    }, 'withVersions');
+    // Rejected with versions
+    server.create('preprint', {
+        provider: osf,
+        id: 'rejected-preprint',
+        title: 'ReviewsState: Rejected Preprint',
+        currentUserPermissions: Object.values(Permission),
+        reviewsState: ReviewsState.REJECTED,
+        isPublished: true,
+    }, 'withVersions');
 
     const subjects = server.createList('subject', 7);
 
@@ -259,26 +276,6 @@ function buildOSF(
         footer_links: '',
         brand,
         moderators: [currentUserModerator],
-        preprints: [
-            examplePreprint,
-            rejectedAdminPreprint,
-            approvedAdminPreprint,
-            approvedPreprint,
-            rejectedPreprint,
-            orphanedPreprint,
-            privatePreprint,
-            notPublishedPreprint,
-            withdrawnPreprint,
-            withdrawnLicensePreprint,
-            pendingWithdrawalPreprint,
-            rejectedWithdrawalPreprintNoComment,
-            rejectedWithdrawalPreprintComment,
-            acceptedWithdrawalPreprintComment,
-            notContributorPreprint,
-            publicDoiPreprint,
-            versionedPreprint,
-            version1, version2, version3,
-        ],
         description: 'This is the description for osf',
     });
 }