Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ENG-6460] [ENG-6640] Add new preprint version workflow #2427

Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
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: 1 addition & 1 deletion app/preprints/-components/submit/file/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export default class PreprintFile extends Component<FileArgs>{
}

@action
public async addNewfile(): Promise<void> {
public addNewfile(): void {
cslzchen marked this conversation as resolved.
Show resolved Hide resolved
this.file = null;
this.isFileAttached = false;
this.isFileUploadDisplayed = false;
Expand Down
100 changes: 96 additions & 4 deletions app/preprints/-components/submit/preprint-state-machine/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { Permission } from 'ember-osf-web/models/osf-model';
import { ReviewsState } from 'ember-osf-web/models/provider';
import { taskFor } from 'ember-concurrency-ts';
import InstitutionModel from 'ember-osf-web/models/institution';
import CurrentUserService from 'ember-osf-web/services/current-user';
import { ReviewActionTrigger } from 'ember-osf-web/models/review-action';

export enum PreprintStatusTypeEnum {
titleAndAbstract = 'titleAndAbstract',
Expand All @@ -34,6 +36,7 @@ interface StateMachineArgs {
preprint: PreprintModel;
setPageDirty: () => void;
resetPageDirty: () => void;
newVersion?: boolean;
}

/**
Expand All @@ -44,6 +47,8 @@ export default class PreprintStateMachine extends Component<StateMachineArgs>{
@service router!: RouterService;
@service intl!: Intl;
@service toast!: Toast;
@service currentUser!: CurrentUserService;

titleAndAbstractValidation = false;
fileValidation = false;
metadataValidation = false;
Expand All @@ -56,15 +61,24 @@ 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;
@tracked displayFileUploadStep = true;
@tracked isNewVersionFlow = this.args.newVersion;
affiliatedInstitutions = [] as InstitutionModel[];

constructor(owner: unknown, args: 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting

this.tempVersion = this.store.createRecord('preprint');
this.preprint = this.args.preprint;
return;
}
if (this.args.preprint) {
this.preprint = this.args.preprint;
this.setValidationForEditFlow();
Expand Down Expand Up @@ -221,11 +235,62 @@ export default class PreprintStateMachine extends Component<StateMachineArgs>{
public async onSubmit(): Promise<void> {
this.args.resetPageDirty();

if (this.isNewVersionFlow) {
try {
const url = this.preprint.links.preprint_versions as string;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this is a POST to create a new version. Just want to double check that this onSubmit is for when user clicks the create-new-version button instead of when user clicks the submit button.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, maybe it's not ... here is my expected behavior:

  • Click the create button makes the POST request to create the new version. BE returns the newly created version and FE switch to the version creation flow.
  • Once we get into the flow, it works the same way as new submission. This means the Submit button should behave the same way as if we were creating a preprint object.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed this workflow so that the new version is created before going in to this workflow, as you had previously said. I implemented this workflow incorrectly, so sorry for the confusion!

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'),
},
},
}),
});
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);
}
} 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.provider.documentType.singular });
if (e.errors[0].status === 409) { // Conflict
cslzchen marked this conversation as resolved.
Show resolved Hide resolved
errorMessage = this.intl.t('preprints.submit.new-version.error.conflict');
}
this.toast.error(errorMessage, errorTitle);
}
return;
}

if (this.preprint.reviewsState === ReviewsState.ACCEPTED) {
await this.preprint.save();
} else if (this.provider.reviewsWorkflow) {
const reviewAction = this.store.createRecord('review-action', {
actionTrigger: 'submit',
actionTrigger: ReviewActionTrigger.Submit,
target: this.preprint,
});
await reviewAction.save();
Expand All @@ -244,6 +309,12 @@ export default class PreprintStateMachine extends Component<StateMachineArgs>{
@task
@waitFor
public async onNext(): Promise<void> {
if (this.isNewVersionFlow) {
// no need to save original or new version on new version flow
this.statusFlowIndex++;
return;
}

if (this.isEditFlow) {
this.args.resetPageDirty();
} else {
Expand Down Expand Up @@ -510,6 +581,16 @@ export default class PreprintStateMachine extends Component<StateMachineArgs>{
}

private getTypeIndex(type: string): number {
if (this.isNewVersionFlow) {
if (type === PreprintStatusTypeEnum.file) {
return 1;
} else if (type === PreprintStatusTypeEnum.review) {
return 2;
} else {
return 0;
}
}

if (this.displayFileUploadStep) {
if (type === PreprintStatusTypeEnum.titleAndAbstract) {
return 1;
Expand Down Expand Up @@ -603,6 +684,16 @@ export default class PreprintStateMachine extends Component<StateMachineArgs>{
* @returns boolean
*/
public shouldDisplayStatusType(type: string): boolean{
if (this.isNewVersionFlow) {
if (type === PreprintStatusTypeEnum.file) {
return true;
} else if (type === PreprintStatusTypeEnum.review) {
return true;
} else {
return false;
}
}

if (type === PreprintStatusTypeEnum.file) {
return this.displayFileUploadStep;
} else if (type === PreprintStatusTypeEnum.authorAssertions) {
Expand Down Expand Up @@ -680,13 +771,14 @@ export default class PreprintStateMachine extends Component<StateMachineArgs>{
@task
@waitFor
public async addProjectFile(file: FileModel): Promise<void>{
await file.copy(this.preprint, '/', 'osfstorage', {
const target = (this.isNewVersionFlow ? this.tempVersion : this.preprint) as PreprintModel;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to my last comment, once your are in the flow, we should already have the new version and we should only have the new version.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I have updated the workflow and I've made it so that the new version is created before moving into this page!

await file.copy(target, '/', 'osfstorage', {
conflict: 'replace',
});
const theFiles = await this.preprint.files;
const theFiles = await target.files;
const rootFolder = await theFiles.firstObject!.rootFolder;
const primaryFile = await rootFolder!.files;
this.preprint.set('primaryFile', primaryFile.lastObject);
target.set('primaryFile', primaryFile.lastObject);
}

@action
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
&.long {
height: 175px;
}

&.short {
height: 40px;
}
}

&.mobile {
Expand All @@ -32,6 +36,10 @@
&.long {
height: fit-content;
}

&.short {
height: fit-content;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div local-class='status-flow-container {{if (is-mobile) 'mobile'}}'>
<div local-class='line {{if @manager.displayAuthorAssertions 'long'}}'/>
<div local-class='line {{if @manager.displayAuthorAssertions 'long' (if @manager.isNewVersionFlow 'short')}}'/>
<Preprints::-Components::Submit::PreprintStateMachine::StatusFlow::StatusFlowDisplay
@manager={{@manager}}
@type={{@manager.getTitleAndAbstractType}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
isPreviousButtonDisabled=this.isPreviousButtonDisabled
isEditFlow=this.isEditFlow
displayFileUploadStep=this.displayFileUploadStep
isNewVersionFlow=this.isNewVersionFlow

isDeleteButtonDisplayed=this.isDeleteButtonDisplayed
isWithdrawalButtonDisplayed=this.isWithdrawalButtonDisplayed

Expand Down
7 changes: 4 additions & 3 deletions app/preprints/-components/submit/submission-flow/template.hbs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
{{page-title (t @header documentType=this.provider.documentType)}}

<Preprints::-Components::Submit::PreprintStateMachine
<Preprints::-Components::Submit::PreprintStateMachine
@provider={{@provider}}
@preprint={{@preprint}}
@setPageDirty={{@setPageDirty}}
@resetPageDirty={{@resetPageDirty}}
@newVersion={{@newVersion}}
as |manager|>
<OsfLayout @backgroundClass={{local-class 'submit-page-container'}} as |layout|>
<layout.heading local-class='header-container'
{{with-branding @brand}}
{{with-branding @brand}}
>
<div local-class='header {{if (is-mobile) 'mobile'}}'>
{{t @header
{{t @header
documentType = @provider.documentType.singularCapitalized
}}
</div>
Expand Down
3 changes: 1 addition & 2 deletions app/preprints/detail/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
data-test-create-new-version-button
data-analytics-name='Create new version'
local-class='btn btn-primary'
{{!-- TODO: Update when new version route is implemented --}}
@route='preprints.edit'
@route='preprints.new-version'
@models={{array this.model.provider.id this.model.preprint.id}}
>
{{t 'preprints.detail.create_new_version'}}
Expand Down
9 changes: 9 additions & 0 deletions app/preprints/new-version/controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Controller from '@ember/controller';
import { action } from '@ember/object';

export default class PreprintNewVersionController extends Controller {
@action
noop() {
return;
}
}
76 changes: 76 additions & 0 deletions app/preprints/new-version/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import Store from '@ember-data/store';
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 Theme from 'ember-osf-web/services/theme';
import MetaTags, { HeadTagDef } from 'ember-osf-web/services/meta-tags';
import PreprintModel from 'ember-osf-web/models/preprint';

export default class PreprintNewVersionRoute extends Route {
@service store!: Store;
@service theme!: Theme;
@service router!: RouterService;
@service metaTags!: MetaTags;
@service toast!: Toast;
@service intl!: Intl;


headTags?: HeadTagDef[];

buildRouteInfoMetadata() {
return {
osfMetrics: {
providerId: this.theme.id,
},
};
}

async model(args: any) {
try {
const provider = await this.store.findRecord('preprint-provider', args.provider_id);
this.theme.providerType = 'preprint';
this.theme.id = args.provider_id;

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 });
}

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;
}

return {
provider,
preprint,
brand: provider.brand.content,
};
} catch (e) {
this.router.transitionTo('not-found', `preprints/${args.provider_id}`);
return null;
}
}

afterModel(model: any) {
const {provider} = model;
if (provider && provider.assets && provider.assets.favicon) {
const headTags = [{
type: 'link',
attrs: {
rel: 'icon',
href: provider.assets.favicon,
},
}];
this.set('headTags', headTags);
}
}
}
9 changes: 9 additions & 0 deletions app/preprints/new-version/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Preprints::-Components::submit::submission-flow
@provider={{this.model.provider}}
@brand={{this.model.brand}}
@newVersion={{true}}
@preprint={{this.model.preprint}}
@header='preprints.submit.title-new-version'
@setPageDirty={{this.noop}}
@resetPageDirty={{this.noop}}
/>
1 change: 1 addition & 0 deletions app/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Router.map(function() {
this.route('detail', { path: '/:provider_id/:guid' });
this.route('submit', { path: '/:provider_id/submit' });
this.route('edit', { path: '/:provider_id/edit/:guid' });
this.route('new-version', { path: '/:provider_id/new-version/:guid' });
this.route('select');
this.route('my-preprints');
});
Expand Down
5 changes: 3 additions & 2 deletions mirage/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import {
import { updatePassword } from './views/user-password';
import * as userSettings from './views/user-setting';
import * as wb from './views/wb';
import { createPreprint, getPreprintVersions } from './views/preprint';
import { createPreprint, getPreprintVersions, createPreprintVersion } from './views/preprint';

const { OSF: { apiUrl, shareBaseUrl, url: osfUrl } } = config;

Expand Down Expand Up @@ -356,7 +356,7 @@ export default function(this: Server) {
});

this.get('/preprints/:id/versions', getPreprintVersions);
// TODO: add post view
this.post('/preprints/:id/versions', createPreprintVersion);

osfNestedResource(this, 'preprint', 'contributors', {
path: '/preprints/:parentID/contributors/',
Expand Down Expand Up @@ -416,6 +416,7 @@ export default function(this: Server) {
defaultSortKey: 'index',
relatedModelName: 'review-action',
});
this.post('/preprints/:parentID/review_actions', createReviewAction);

/**
* Preprint Requests
Expand Down
Loading
Loading