Skip to content

Commit

Permalink
Merge pull request #161 from CSCfi/feature/edit-replace-saved-objects
Browse files Browse the repository at this point in the history
Edit saved form & replace saved XML functionality
  • Loading branch information
blankdots authored Feb 12, 2021
2 parents 3a9be06 + 39f03eb commit 8e1952e
Show file tree
Hide file tree
Showing 17 changed files with 555 additions and 204 deletions.
34 changes: 34 additions & 0 deletions cypress/fixtures/study_test_modified.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<STUDY_SET>
<STUDY alias="GSE10966" center_name="GEO">
<IDENTIFIERS>
<PRIMARY_ID>SRP000539</PRIMARY_ID>
<EXTERNAL_ID label="primary" namespace="BioProject">PRJNA108793</EXTERNAL_ID>
<EXTERNAL_ID namespace="GEO">GSE10966</EXTERNAL_ID>
</IDENTIFIERS>
<DESCRIPTOR>
<STUDY_TITLE>Different title for testing purposes
</STUDY_TITLE>
<STUDY_TYPE existing_study_type="Other" />
<STUDY_ABSTRACT>Part of a set of highly integrated epigenome maps for Arabidopsis thaliana. Keywords:
Illumina high-throughput bisulfite sequencing Overall design: Whole genome shotgun bisulfite sequencing
of wildtype Arabidopsis plants (Columbia-0), and met1, drm1 drm2 cmt3, and ros1 dml2 dml3 null mutants
using the Illumina Genetic Analyzer.
</STUDY_ABSTRACT>
<CENTER_PROJECT_NAME>GSE10966</CENTER_PROJECT_NAME>
</DESCRIPTOR>
<STUDY_LINKS>
<STUDY_LINK>
<XREF_LINK>
<DB>pubmed</DB>
<ID>18423832</ID>
</XREF_LINK>
</STUDY_LINK>
</STUDY_LINKS>
<STUDY_ATTRIBUTES>
<STUDY_ATTRIBUTE>
<TAG>parent_bioproject</TAG>
<VALUE>PRJNA107265</VALUE>
</STUDY_ATTRIBUTE>
</STUDY_ATTRIBUTES>
</STUDY>
</STUDY_SET>
27 changes: 27 additions & 0 deletions cypress/integration/app.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ describe("Basic e2e", function () {
cy.get("button[type=submit]").contains("Submit").click()
cy.get(".MuiListItem-container", { timeout: 10000 }).should("have.length", 1)

// Edit saved submission
cy.get("button[type=button]").contains("New form").click()
cy.get("button[type=button]").contains("Edit").click()
cy.get("input[name='descriptor.studyTitle']").should("have.value", "New title")
cy.get("input[name='descriptor.studyTitle']").type(" edited")
cy.get("input[name='descriptor.studyTitle']").should("have.value", "New title edited")
cy.get("button[type=button]").contains("Update").click()
cy.get("div[role=alert]").contains("Object updated")
cy.get("button[type=button]").contains("New form").click()
cy.get("button[type=button]").contains("Edit").click()
cy.get("input[name='descriptor.studyTitle']").should("have.value", "New title edited")

// Upload a Study xml file.
cy.get("div[role=button]").contains("Upload XML File").click()
cy.fixture("study_test.xml").then(fileContent => {
Expand All @@ -51,6 +63,21 @@ describe("Basic e2e", function () {
// Saved objects list should have newly added item from Study object
cy.get(".MuiListItem-container", { timeout: 10000 }).should("have.length", 2)

// Replace XML
cy.get("button[type=button]").contains("Replace").click()
cy.get(".MuiCardHeader-action").contains("Replace")
cy.fixture("study_test_modified.xml").then(fileContent => {
cy.get('input[type="file"]').attachFile({
fileContent: fileContent.toString(),
fileName: "testFile_replace.xml",
mimeType: "text/xml",
force: true,
})
})
cy.get("form").submit()
cy.get(".MuiListItem-container", { timeout: 10000 }).should("have.length", 2)
cy.contains(".MuiAlert-message", "Object replaced")

// Fill an Analysis form and submit object
cy.get("div[role=button]").contains("Analysis").click()
cy.get("div[role=button]")
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/WizardShowSummaryStep.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ describe("WizardShowSummaryStep", () => {
it("should have uploaded objects listed", async () => {
render(wrapper)
const items = await screen.findAllByRole("button")
expect(items).toHaveLength(4) // Screen renders stepper back and next buttons
expect(items).toHaveLength(8) // Screen renders stepper back and next buttons and object actions
})
})
157 changes: 111 additions & 46 deletions src/components/NewDraftWizard/WizardComponents/WizardAlert.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ import { useDispatch, useSelector } from "react-redux"

import { resetDraftStatus } from "features/draftStatusSlice"
import { setAlert, resetAlert } from "features/wizardAlertSlice"
import { resetDraftObject } from "features/wizardDraftObjectSlice"
import { resetCurrentObject } from "features/wizardCurrentObjectSlice"
import { updateStatus } from "features/wizardStatusMessageSlice"
import { addObjectToDrafts } from "features/wizardSubmissionFolderSlice"
import draftAPIService from "services/draftAPI"
import objectAPIService from "services/objectAPI"

// Simple template for error messages
const ErrorMessage = message => {
return <Alert severity="error">{message}</Alert>
return <Alert severity="error">{message.message}</Alert>
}

/*
Expand All @@ -37,7 +38,7 @@ const CancelFormDialog = ({
currentSubmissionType: string,
}) => {
const submissionFolder = useSelector(state => state.submissionFolder)
const draftObject = useSelector(state => state.draftObject)
const currentObject = useSelector(state => state.currentObject)
const objectType = useSelector(state => state.objectType)
const [error, setError] = useState(false)
const [errorMessage, setErrorMessage] = useState("")
Expand All @@ -47,8 +48,13 @@ const CancelFormDialog = ({
const saveDraft = async () => {
setError(false)
const err = "Connection error, cannot save draft."
if (draftObject.draftId) {
const response = await draftAPIService.patchFromJSON(objectType, draftObject.draftId, draftObject)

if ((currentObject.accessionId || currentObject.objectId) && currentObject.type === "draft") {
const response = await draftAPIService.patchFromJSON(
objectType,
currentObject.accessionId || currentObject.objectId,
currentObject.cleanedValues
)
if (response.ok) {
dispatch(resetDraftStatus())
dispatch(
Expand All @@ -58,14 +64,14 @@ const CancelFormDialog = ({
errorPrefix: "",
})
)
dispatch(resetDraftObject())
dispatch(resetCurrentObject())
handleDialog(true)
} else {
setError(true)
setErrorMessage(err)
}
} else {
const response = await draftAPIService.createFromJSON(objectType, draftObject)
const response = await draftAPIService.createFromJSON(objectType, currentObject)
if (response.ok) {
dispatch(
updateStatus({
Expand All @@ -81,7 +87,7 @@ const CancelFormDialog = ({
schema: "draft-" + objectType,
})
)
dispatch(resetDraftObject())
dispatch(resetCurrentObject())
handleDialog(true)
} else {
setError(true)
Expand All @@ -90,53 +96,112 @@ const CancelFormDialog = ({
}
}

const updateForm = async () => {
const err = "Connection error, cannot update object"
const response = await objectAPIService.patchFromJSON(
objectType,
currentObject.accessionId,
currentObject.cleanedValues
)
if (response.ok) {
dispatch(resetDraftStatus())
dispatch(
updateStatus({
successStatus: "success",
response: response,
errorPrefix: "",
})
)
dispatch(resetCurrentObject())
handleDialog(true)
} else {
setError(true)
setErrorMessage(err)
}
}

let [dialogTitle, dialogContent] = ["", ""]
let dialogActions
const formContent = "If you save form as a draft, you can continue filling it later."
const xmlContent = "If you save xml as a draft, you can upload it later."
const objectContent = "If you save object as a draft, you can upload it later."

switch (parentLocation) {
case "submission": {
switch (alertType) {
case "form": {
dialogTitle = "Would you like to save draft version of this form"
dialogContent = formContent
break
}
case "xml": {
dialogTitle = "Would you like to save draft version of this xml upload"
dialogContent = xmlContent
break
}
case "existing": {
dialogTitle = "Would you like to save draft version of this existing object upload"
dialogContent = objectContent
break
}
default: {
dialogTitle = "default"
dialogContent = "default content"
if (currentObject?.type === "saved") {
dialogTitle = "Would you like to save edited form data?"
dialogContent = "Unsaved changes will be lost. If you save form as a draft, you can continue filling it later."
dialogActions = (
<DialogActions>
<Button variant="contained" onClick={() => handleDialog(false)} color="secondary">
Cancel
</Button>
<Button variant="contained" onClick={() => handleDialog(true)} color="primary">
Do not save
</Button>
<Button
variant="contained"
onClick={() => {
saveDraft()
}}
color="primary"
>
Save as a draft
</Button>
<Button
variant="contained"
onClick={() => {
updateForm()
}}
color="primary"
>
Update
</Button>
</DialogActions>
)
} else {
switch (alertType) {
case "form": {
dialogTitle = "Would you like to save draft version of this form"
dialogContent = formContent
break
}
case "xml": {
dialogTitle = "Would you like to save draft version of this xml upload"
dialogContent = xmlContent
break
}
case "existing": {
dialogTitle = "Would you like to save draft version of this existing object upload"
dialogContent = objectContent
break
}
default: {
dialogTitle = "default"
dialogContent = "default content"
}
}
dialogActions = (
<DialogActions>
<Button variant="contained" onClick={() => handleDialog(false)} color="secondary">
Cancel
</Button>
<Button variant="contained" onClick={() => handleDialog(true)} color="primary">
Do not save
</Button>
<Button
variant="contained"
onClick={() => {
saveDraft()
}}
color="primary"
>
Save
</Button>
</DialogActions>
)
}
dialogActions = (
<DialogActions>
<Button variant="contained" onClick={() => handleDialog(false)} color="secondary">
Cancel
</Button>
<Button variant="contained" onClick={() => handleDialog(true)} color="primary">
Do not save
</Button>
<Button
variant="contained"
onClick={() => {
saveDraft()
}}
color="primary"
>
Save
</Button>
</DialogActions>
)

break
}
case "footer": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { useSelector, useDispatch } from "react-redux"
import WizardStatusMessageHandler from "../WizardForms/WizardStatusMessageHandler"

import { resetFocus } from "features/focusSlice"
import { setDraftObject } from "features/wizardDraftObjectSlice"
import { setCurrentObject } from "features/wizardCurrentObjectSlice"
import { deleteObjectFromFolder } from "features/wizardSubmissionFolderSlice"
import { setSubmissionType } from "features/wizardSubmissionTypeSlice"
import draftAPIService from "services/draftAPI"
Expand Down Expand Up @@ -78,7 +78,7 @@ const WizardDraftObjectPicker = () => {
setConnError(false)
const response = await draftAPIService.getObjectByAccessionId(objectType, objectId)
if (response.ok) {
dispatch(setDraftObject(response.data))
dispatch(setCurrentObject({ ...response.data, type: "draft" }))
dispatch(setSubmissionType("form"))
} else {
setConnError(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import WizardAlert from "./WizardAlert"

import { resetDraftStatus } from "features/draftStatusSlice"
import { setFocus } from "features/focusSlice"
import { resetDraftObject } from "features/wizardDraftObjectSlice"
import { resetCurrentObject } from "features/wizardCurrentObjectSlice"
import { setObjectType } from "features/wizardObjectTypeSlice"
import { setSubmissionType } from "features/wizardSubmissionTypeSlice"

Expand Down Expand Up @@ -247,7 +247,7 @@ const WizardObjectIndex = () => {
setClickedSubmissionType(submissionType)
setCancelFormOpen(true)
} else {
dispatch(resetDraftObject())
dispatch(resetCurrentObject())
dispatch(resetDraftStatus())
dispatch(setSubmissionType(submissionType))
dispatch(setObjectType(expandedObjectType))
Expand All @@ -262,6 +262,7 @@ const WizardObjectIndex = () => {
dispatch(resetDraftStatus())
dispatch(setSubmissionType(clickedSubmissionType))
dispatch(setObjectType(expandedObjectType))
dispatch(resetCurrentObject())
}
}

Expand Down
Loading

0 comments on commit 8e1952e

Please sign in to comment.