From eabcd21d7a90a7745f21b7709207ade335dedb18 Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Wed, 27 Oct 2021 18:21:17 +1100 Subject: [PATCH 01/43] Dev file for getting a PG service running locally via Docker. --- docker-compose-dev.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 docker-compose-dev.yml diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml new file mode 100644 index 0000000000..8bd604a5ed --- /dev/null +++ b/docker-compose-dev.yml @@ -0,0 +1,19 @@ +version: '2.4' + +services: + postgres: + image: postgres:12.6 + command: postgres -c listen_addresses='*' + environment: + - PGPORT=5433 + - POSTGRES_DB=seqrdb + - POSTGRES_PASSWORD=a-very-secure-password + volumes: + - ./data/postgres:/var/lib/postgresql/data + ports: + - "5433:5433" + healthcheck: + test: pg_isready -h postgres -U postgres + interval: 5s + timeout: 10s + retries: 100 From f6f62a858ad5d21c54328156819e840fc29f77b0 Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Wed, 27 Oct 2021 18:26:08 +1100 Subject: [PATCH 02/43] dotenv template file for devs --- .envrc.template | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .envrc.template diff --git a/.envrc.template b/.envrc.template new file mode 100644 index 0000000000..1e8d0585a8 --- /dev/null +++ b/.envrc.template @@ -0,0 +1,26 @@ +# Database settings for Django +export POSTGRES_SERVICE_HOSTNAME=localhost +export POSTGRES_SERVICE_PORT=5433 +export POSTGRES_USERNAME=postgres +export POSTGRES_PASSWORD=a-very-secure-password +export POSTGRES_DATABASE=seqrdb + +# Leave blank for local env +export DEPLOYMENT_TYPE= + +# Convenience commands for creating database +export CREATE_REF_DB_CMD="psql -W -U ${POSTGRES_USERNAME} -h ${POSTGRES_SERVICE_HOSTNAME} -p ${POSTGRES_SERVICE_PORT} -c 'create database reference_data_db;'" +export LIST_DBS_CMD="psql -W -U ${POSTGRES_USERNAME} -h ${POSTGRES_SERVICE_HOSTNAME} -p ${POSTGRES_SERVICE_PORT} -c '\list'" + +# ---------------------------------------------------------------------------- +# Apple Developers +# ---------------------------------------------------------------------------- +# Install libpg for the Postgres client library without the server (brew install libpg) +# Export these variables so that pip packages know where to find the appropriate binaries, libs and headers. +# export PATH="/opt/homebrew/opt/libpq/bin:$PATH" +# export LDFLAGS="-L/opt/homebrew/opt/libpq/lib $LDFLAGS" +# export CPPFLAGS="-I/opt/homebrew/opt/libpq/include $CPPFLAGS" + +# Apple silicon (M1 chip etc) fix for grpcio +# export GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1 +# export GRPC_PYTHON_BUILD_SYSTEM_ZLIB=1 From 247d6181a7d8015a82980765895897f1567634ea Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Wed, 27 Oct 2021 18:26:23 +1100 Subject: [PATCH 03/43] basic dev environment for conda --- environment-dev.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 environment-dev.yaml diff --git a/environment-dev.yaml b/environment-dev.yaml new file mode 100644 index 0000000000..88875070ad --- /dev/null +++ b/environment-dev.yaml @@ -0,0 +1,13 @@ +name: seqr + +channels: + - cpg + - bioconda + - conda-forge +dependencies: + - python=3.8 + - pip + - nodejs==16.10.0 + - pip: + - '-r requirements-dev.txt' + - '-r requirements.txt' From bbe5d13fa3f836a01049208e998d623f5bcd2d67 Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Wed, 27 Oct 2021 18:46:48 +1100 Subject: [PATCH 04/43] ignore .envrc and data/ directory created by Docker Compose --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8af164bee9..871a01e1b7 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,7 @@ deploy/secrets/gcloud*/* pedigree_images/* seqr_settings -django_key \ No newline at end of file +django_key +.envrc + +data/ \ No newline at end of file From 063f52e80dc2bf6e0409a2a7d4e2cb4f987888b8 Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Thu, 28 Oct 2021 15:19:12 +1100 Subject: [PATCH 05/43] Temp webpack fixes from current OpenSSL3 breaking changes. --- ui/config/webpack.config.dev.js | 4 ++++ ui/config/webpack.config.prod.js | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/ui/config/webpack.config.dev.js b/ui/config/webpack.config.dev.js index 7d083e12fa..3d103e69d2 100644 --- a/ui/config/webpack.config.dev.js +++ b/ui/config/webpack.config.dev.js @@ -12,6 +12,10 @@ const eslintFormatter = require('react-dev-utils/eslintFormatter'); const glob = require('glob'); const paths = require('./paths'); +// HACK: OpenSSL 3 does not support md4 any more, but webpack hardcodes it all over the place: https://github.com/webpack/webpack/issues/13572 +const crypto = require('crypto'); +const cryptoOriginalCreateHash = crypto.createHash; +crypto.createHash = algorithm => cryptoOriginalCreateHash(algorithm === 'md4' ? 'sha256' : algorithm); // This is the development configuration. //how to optimize webpack builds: diff --git a/ui/config/webpack.config.prod.js b/ui/config/webpack.config.prod.js index 3c5923dae7..1d55712543 100644 --- a/ui/config/webpack.config.prod.js +++ b/ui/config/webpack.config.prod.js @@ -14,6 +14,11 @@ const eslintFormatter = require('react-dev-utils/eslintFormatter'); const paths = require('./paths'); const getClientEnvironment = require('./env'); +// HACK: OpenSSL 3 does not support md4 any more, but webpack hardcodes it all over the place: https://github.com/webpack/webpack/issues/13572 +const crypto = require('crypto'); +const cryptoOriginalCreateHash = crypto.createHash; +crypto.createHash = algorithm => cryptoOriginalCreateHash(algorithm === 'md4' ? 'sha256' : algorithm); + // Webpack uses `publicPath` to determine where the app is being served from. // It requires a trailing slash, or the file assets will get an incorrect path. const publicPath = paths.servedPath; From 96bcbee7af943f1c44746d377ea3fdfb38c45b38 Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Thu, 28 Oct 2021 15:19:37 +1100 Subject: [PATCH 06/43] Parent wizard component and integration with Project routes --- ui/pages/Project/Project.jsx | 2 ++ .../OnboardingWizard/OnboardingWizard.jsx | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 ui/pages/Project/components/OnboardingWizard/OnboardingWizard.jsx diff --git a/ui/pages/Project/Project.jsx b/ui/pages/Project/Project.jsx index 8239bd3b8d..342fc8a917 100644 --- a/ui/pages/Project/Project.jsx +++ b/ui/pages/Project/Project.jsx @@ -12,6 +12,7 @@ import CaseReview from './components/CaseReview' import FamilyPage from './components/FamilyPage' import Matchmaker from './components/Matchmaker' import SavedVariants from './components/SavedVariants' +import OnboardingWizard from './components/OnboardingWizard/OnboardingWizard' class Project extends React.PureComponent { @@ -43,6 +44,7 @@ class Project extends React.PureComponent + } /> ) diff --git a/ui/pages/Project/components/OnboardingWizard/OnboardingWizard.jsx b/ui/pages/Project/components/OnboardingWizard/OnboardingWizard.jsx new file mode 100644 index 0000000000..c9e1d8fbac --- /dev/null +++ b/ui/pages/Project/components/OnboardingWizard/OnboardingWizard.jsx @@ -0,0 +1,26 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { connect } from 'react-redux' + +import { getCurrentProject } from '../../selectors' + +const OnboardingWizard = ({ match, project }) => { + return ( +
+

Hello, world!

+
{ JSON.stringify(match, null, 2) }
+
{ JSON.stringify(project, null, 2) }
+
+ ) +} + +OnboardingWizard.propTypes = { + match: PropTypes.object, + project: PropTypes.object, +} + +const mapStateToProps = state => ({ + project: getCurrentProject(state), +}) + +export default connect(mapStateToProps)(OnboardingWizard) From dbdffefd7195d6abe6e38ee520466e23d5aecc6b Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Fri, 29 Oct 2021 12:29:22 +1100 Subject: [PATCH 07/43] Ignore idea and vscode dirs --- .dockerignore | 4 +++- .gitignore | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index bf881194fb..52d1cb5546 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,3 @@ -ui/node_modules/ \ No newline at end of file +ui/node_modules/ +.idea/ +.vscode/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 871a01e1b7..6a356cf957 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .idea* +.vscode* *.iml *.sqlite3 *.log From ddf9b3e271533059a9af870bf9eebe1bc9d62808 Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Fri, 29 Oct 2021 12:30:45 +1100 Subject: [PATCH 08/43] Serve 401 if user doesn't have edit permissions --- .../components/OnboardingWizard/OnboardingWizard.jsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ui/pages/Project/components/OnboardingWizard/OnboardingWizard.jsx b/ui/pages/Project/components/OnboardingWizard/OnboardingWizard.jsx index c9e1d8fbac..c2cb29e1d6 100644 --- a/ui/pages/Project/components/OnboardingWizard/OnboardingWizard.jsx +++ b/ui/pages/Project/components/OnboardingWizard/OnboardingWizard.jsx @@ -2,14 +2,19 @@ import React from 'react' import PropTypes from 'prop-types' import { connect } from 'react-redux' +import { Error401 } from '../../../../shared/components/page/Errors' import { getCurrentProject } from '../../selectors' const OnboardingWizard = ({ match, project }) => { + if (!project.canEdit) { + return + } + return (

Hello, world!

-
{ JSON.stringify(match, null, 2) }
-
{ JSON.stringify(project, null, 2) }
+
{JSON.stringify(match, null, 2)}
+
{JSON.stringify(project, null, 2)}
) } From 3cb6275c479894c53bc788df29f55d0611d094c3 Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Mon, 1 Nov 2021 17:20:57 +1100 Subject: [PATCH 09/43] Renamed from OnboardingWizard --- .../components/DataLoadingWizardPage.jsx | 26 ++++++++++++++++ .../OnboardingWizard/OnboardingWizard.jsx | 31 ------------------- 2 files changed, 26 insertions(+), 31 deletions(-) create mode 100644 ui/pages/Project/components/DataLoadingWizardPage.jsx delete mode 100644 ui/pages/Project/components/OnboardingWizard/OnboardingWizard.jsx diff --git a/ui/pages/Project/components/DataLoadingWizardPage.jsx b/ui/pages/Project/components/DataLoadingWizardPage.jsx new file mode 100644 index 0000000000..79bbb72cee --- /dev/null +++ b/ui/pages/Project/components/DataLoadingWizardPage.jsx @@ -0,0 +1,26 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { connect } from 'react-redux' + +import { Error401 } from '../../../shared/components/page/Errors' +import { getCurrentProject } from '../selectors' + +import DataLoadingWizardForm from './DataLoadingWizardForm/DataLoadingWizardForm' + +const DataLoadingWizardPage = ({ project }) => { + if (!project.canEdit) { + return + } + + return +} + +DataLoadingWizardPage.propTypes = { + project: PropTypes.object, +} + +const mapStateToProps = state => ({ + project: getCurrentProject(state), +}) + +export default connect(mapStateToProps)(DataLoadingWizardPage) diff --git a/ui/pages/Project/components/OnboardingWizard/OnboardingWizard.jsx b/ui/pages/Project/components/OnboardingWizard/OnboardingWizard.jsx deleted file mode 100644 index c2cb29e1d6..0000000000 --- a/ui/pages/Project/components/OnboardingWizard/OnboardingWizard.jsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { connect } from 'react-redux' - -import { Error401 } from '../../../../shared/components/page/Errors' -import { getCurrentProject } from '../../selectors' - -const OnboardingWizard = ({ match, project }) => { - if (!project.canEdit) { - return - } - - return ( -
-

Hello, world!

-
{JSON.stringify(match, null, 2)}
-
{JSON.stringify(project, null, 2)}
-
- ) -} - -OnboardingWizard.propTypes = { - match: PropTypes.object, - project: PropTypes.object, -} - -const mapStateToProps = state => ({ - project: getCurrentProject(state), -}) - -export default connect(mapStateToProps)(OnboardingWizard) From 28a10b13e13889c7046f7943727230f7220122ec Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Mon, 1 Nov 2021 17:21:31 +1100 Subject: [PATCH 10/43] Re-usable form components relating to UI --- .../DataLoadingWizardForm/ui/Centered.jsx | 8 ++ .../DataLoadingWizardForm/ui/FormSection.jsx | 8 ++ .../ui/FormStepButtons.jsx | 84 +++++++++++++++++++ .../DataLoadingWizardForm/ui/index.js | 9 ++ 4 files changed, 109 insertions(+) create mode 100644 ui/pages/Project/components/DataLoadingWizardForm/ui/Centered.jsx create mode 100644 ui/pages/Project/components/DataLoadingWizardForm/ui/FormSection.jsx create mode 100644 ui/pages/Project/components/DataLoadingWizardForm/ui/FormStepButtons.jsx create mode 100644 ui/pages/Project/components/DataLoadingWizardForm/ui/index.js diff --git a/ui/pages/Project/components/DataLoadingWizardForm/ui/Centered.jsx b/ui/pages/Project/components/DataLoadingWizardForm/ui/Centered.jsx new file mode 100644 index 0000000000..0e82f3fd03 --- /dev/null +++ b/ui/pages/Project/components/DataLoadingWizardForm/ui/Centered.jsx @@ -0,0 +1,8 @@ +import styled from 'styled-components' + +const Centered = styled.div` + display: flex; + justify-content: center; +` + +export default Centered diff --git a/ui/pages/Project/components/DataLoadingWizardForm/ui/FormSection.jsx b/ui/pages/Project/components/DataLoadingWizardForm/ui/FormSection.jsx new file mode 100644 index 0000000000..66af0e103e --- /dev/null +++ b/ui/pages/Project/components/DataLoadingWizardForm/ui/FormSection.jsx @@ -0,0 +1,8 @@ +import styled from 'styled-components' + +const FormSection = styled.div` + margin-top: 2em; + margin-bottom: 2em; +` + +export default FormSection diff --git a/ui/pages/Project/components/DataLoadingWizardForm/ui/FormStepButtons.jsx b/ui/pages/Project/components/DataLoadingWizardForm/ui/FormStepButtons.jsx new file mode 100644 index 0000000000..bca91cb5d5 --- /dev/null +++ b/ui/pages/Project/components/DataLoadingWizardForm/ui/FormStepButtons.jsx @@ -0,0 +1,84 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Button } from 'semantic-ui-react' +import styled from 'styled-components' + +const FormButtonGroup = styled.div` + display: flex; + justify-content: right; +` + +const FormStepButtons = ({ isLastStep, onNext, onBack, onSubmit, disabled, loading, size }) => { + if (isLastStep) { + return ( + + + + + + ) + } + + return ( + + + + + ) +} + +FormStepButtons.propTypes = { + isLastStep: PropTypes.bool, + onNext: PropTypes.func, + onBack: PropTypes.func, + onSubmit: PropTypes.func, + disabled: PropTypes.bool, + loading: PropTypes.bool, + size: PropTypes.string, +} + +FormStepButtons.defaultProps = { + isLastStep: false, + onNext: () => {}, + onBack: () => {}, + onSubmit: () => {}, + disabled: false, + loading: false, + size: 'small', +} + +export default FormStepButtons diff --git a/ui/pages/Project/components/DataLoadingWizardForm/ui/index.js b/ui/pages/Project/components/DataLoadingWizardForm/ui/index.js new file mode 100644 index 0000000000..db2f38cca4 --- /dev/null +++ b/ui/pages/Project/components/DataLoadingWizardForm/ui/index.js @@ -0,0 +1,9 @@ +import Centered from './Centered' +import FormSection from './FormSection' +import FormStepButtons from './FormStepButtons' + +export { + Centered, + FormSection, + FormStepButtons, +} From 69eda78d0afa10ba921fc3bb3b809f30a795e1e1 Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Mon, 1 Nov 2021 17:21:43 +1100 Subject: [PATCH 11/43] Setting up the multi-step form --- .../DataLoadingWizardForm.jsx | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 ui/pages/Project/components/DataLoadingWizardForm/DataLoadingWizardForm.jsx diff --git a/ui/pages/Project/components/DataLoadingWizardForm/DataLoadingWizardForm.jsx b/ui/pages/Project/components/DataLoadingWizardForm/DataLoadingWizardForm.jsx new file mode 100644 index 0000000000..29c9303553 --- /dev/null +++ b/ui/pages/Project/components/DataLoadingWizardForm/DataLoadingWizardForm.jsx @@ -0,0 +1,75 @@ +import React, { useState, useEffect } from 'react' +import PropTypes from 'prop-types' +import { Breadcrumb, Header } from 'semantic-ui-react' + +import { Centered, FormSection, FormStepButtons } from './ui' +import { Welcome } from './steps' + +const FORM_STEPS = [ + { key: 0, content: 'Welcome', link: false, active: true, component: Welcome }, + { key: 1, content: 'Family metadata', link: false, active: false, component: () => {} }, + { key: 2, content: 'Individual metadata', link: false, active: false, component: () => {} }, + { key: 3, content: 'Sample mapping', link: false, active: false, component: () => {} }, + { key: 4, content: 'Submit', link: false, active: false, component: () => {} }, +] + +const DataLoadingWizardForm = ({ project }) => { + // const [formState, setFormState] = useState({}) + const [formStepIndex, setFormStepIndex] = useState(0) + const [formSteps, setFormSteps] = useState([...FORM_STEPS]) + + useEffect(() => { + setFormSteps( + formSteps.map( + (step) => { return { ...step, active: step.key === formStepIndex } }, + ), + ) + }, [formStepIndex]) + + return ( +
+ + + + + + + + {/* React Hook components are just functions under the hood. */} + {/* Get the component property from the current step and call it to add it to the DOM. */} + {formSteps[formStepIndex].component({ project })} +
DEBUG
+
{JSON.stringify(project, null, 2)}
+
+ + + setFormStepIndex(Math.min(formStepIndex + 1, formSteps.length - 1))} + onBack={() => setFormStepIndex(Math.max(0, formStepIndex - 1))} + onSubmit={() => alert('Yay')} + /> + + + + + + + +
+ ) +} + +DataLoadingWizardForm.propTypes = { + project: PropTypes.object, +} + +export default DataLoadingWizardForm From b4b8e7bbbe176bb9365904f51f434b56f14f4431 Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Mon, 1 Nov 2021 17:21:57 +1100 Subject: [PATCH 12/43] Welcome step --- .../DataLoadingWizardForm/steps/Welcome.jsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 ui/pages/Project/components/DataLoadingWizardForm/steps/Welcome.jsx diff --git a/ui/pages/Project/components/DataLoadingWizardForm/steps/Welcome.jsx b/ui/pages/Project/components/DataLoadingWizardForm/steps/Welcome.jsx new file mode 100644 index 0000000000..cf2b22ca95 --- /dev/null +++ b/ui/pages/Project/components/DataLoadingWizardForm/steps/Welcome.jsx @@ -0,0 +1,16 @@ +import React from 'react' + +const Welcome = () => { + return ( + +

+ Welcome to the seqr data loading wizard! This wizard will guide you through the process of uploading + the relevant individual template, family template and associated metadata files. Each step will validate + these files to ensure that the information relating individuals, families and samples is correctly formatted. +

+
+ ) +} + +export default Welcome + From 7d657e343749541195d1e910baf683bdc239d25d Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Mon, 1 Nov 2021 17:22:12 +1100 Subject: [PATCH 13/43] Export steps from `steps` module --- .../Project/components/DataLoadingWizardForm/steps/index.js | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ui/pages/Project/components/DataLoadingWizardForm/steps/index.js diff --git a/ui/pages/Project/components/DataLoadingWizardForm/steps/index.js b/ui/pages/Project/components/DataLoadingWizardForm/steps/index.js new file mode 100644 index 0000000000..c88905cec8 --- /dev/null +++ b/ui/pages/Project/components/DataLoadingWizardForm/steps/index.js @@ -0,0 +1,5 @@ +import Welcome from './Welcome' + +export { + Welcome, +} From 45afacde8f5dd39264b60c34a0825d5481183194 Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Mon, 1 Nov 2021 17:22:21 +1100 Subject: [PATCH 14/43] Renamed components --- ui/pages/Project/Project.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/pages/Project/Project.jsx b/ui/pages/Project/Project.jsx index 342fc8a917..5766a4c5cb 100644 --- a/ui/pages/Project/Project.jsx +++ b/ui/pages/Project/Project.jsx @@ -12,7 +12,7 @@ import CaseReview from './components/CaseReview' import FamilyPage from './components/FamilyPage' import Matchmaker from './components/Matchmaker' import SavedVariants from './components/SavedVariants' -import OnboardingWizard from './components/OnboardingWizard/OnboardingWizard' +import DataLoadingWizardPage from './components/DataLoadingWizardPage' class Project extends React.PureComponent { @@ -44,7 +44,7 @@ class Project extends React.PureComponent - + } /> ) From 6d4de64c9726735a8fb2a4840e351222b60af260 Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Mon, 8 Nov 2021 16:25:50 +1100 Subject: [PATCH 15/43] Outline of sections --- .../DataLoadingWizardForm/steps/Welcome.jsx | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/ui/pages/Project/components/DataLoadingWizardForm/steps/Welcome.jsx b/ui/pages/Project/components/DataLoadingWizardForm/steps/Welcome.jsx index cf2b22ca95..9b6abab997 100644 --- a/ui/pages/Project/components/DataLoadingWizardForm/steps/Welcome.jsx +++ b/ui/pages/Project/components/DataLoadingWizardForm/steps/Welcome.jsx @@ -1,14 +1,41 @@ import React from 'react' +import styled from 'styled-components' + +const WelcomeSection = styled.section` + margin: 1em 0; +` + +const ReadableText = styled.p` + font-size: 16px; + line-height: 1.6; +` const Welcome = () => { return ( - -

- Welcome to the seqr data loading wizard! This wizard will guide you through the process of uploading - the relevant individual template, family template and associated metadata files. Each step will validate - these files to ensure that the information relating individuals, families and samples is correctly formatted. -

-
+
+ + + Welcome to the seqr data loading wizard! This wizard will guide you through the process of uploading + the relevant individual template, family template and associated metadata files. Each step will validate + these files to ensure that the information relating individuals, families and samples is correctly formatted. + + + + +

Introduction

+ Overview of what the collaborator needs to do goes here +
+ + +

Resources

+ Overview of required template and mapping formats +
+ + +

FAQ

+ Frequently asked questions and answers +
+
) } From 43ef74811681ece4a16a9d47359959d771437010 Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Mon, 8 Nov 2021 16:26:01 +1100 Subject: [PATCH 16/43] Stubs --- .../steps/FamilyMetadataUpload.jsx | 15 +++++++++++++++ .../steps/IndividualMetadataUpload.jsx | 0 .../DataLoadingWizardForm/steps/Review.jsx | 0 .../DataLoadingWizardForm/steps/SampleMapping.jsx | 0 4 files changed, 15 insertions(+) create mode 100644 ui/pages/Project/components/DataLoadingWizardForm/steps/FamilyMetadataUpload.jsx create mode 100644 ui/pages/Project/components/DataLoadingWizardForm/steps/IndividualMetadataUpload.jsx create mode 100644 ui/pages/Project/components/DataLoadingWizardForm/steps/Review.jsx create mode 100644 ui/pages/Project/components/DataLoadingWizardForm/steps/SampleMapping.jsx diff --git a/ui/pages/Project/components/DataLoadingWizardForm/steps/FamilyMetadataUpload.jsx b/ui/pages/Project/components/DataLoadingWizardForm/steps/FamilyMetadataUpload.jsx new file mode 100644 index 0000000000..a62dea4624 --- /dev/null +++ b/ui/pages/Project/components/DataLoadingWizardForm/steps/FamilyMetadataUpload.jsx @@ -0,0 +1,15 @@ +import React from 'react' +import PropTypes from 'prop-types' + +// import styled from 'styled-components' + +const FamilyMetadataUpload = ({ project, onFormChange }) => { + return
+} + +FamilyMetadataUpload.propTypes = { + project: PropTypes.object.isRequired, + onFormChange: PropTypes.func.isRequired, +} + +export default FamilyMetadataUpload diff --git a/ui/pages/Project/components/DataLoadingWizardForm/steps/IndividualMetadataUpload.jsx b/ui/pages/Project/components/DataLoadingWizardForm/steps/IndividualMetadataUpload.jsx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ui/pages/Project/components/DataLoadingWizardForm/steps/Review.jsx b/ui/pages/Project/components/DataLoadingWizardForm/steps/Review.jsx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ui/pages/Project/components/DataLoadingWizardForm/steps/SampleMapping.jsx b/ui/pages/Project/components/DataLoadingWizardForm/steps/SampleMapping.jsx new file mode 100644 index 0000000000..e69de29bb2 From be3857218d532aaad2993c18bab4f0275efd710b Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Mon, 8 Nov 2021 16:26:11 +1100 Subject: [PATCH 17/43] Module export --- .../Project/components/DataLoadingWizardForm/steps/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/pages/Project/components/DataLoadingWizardForm/steps/index.js b/ui/pages/Project/components/DataLoadingWizardForm/steps/index.js index c88905cec8..91bccea233 100644 --- a/ui/pages/Project/components/DataLoadingWizardForm/steps/index.js +++ b/ui/pages/Project/components/DataLoadingWizardForm/steps/index.js @@ -1,5 +1,7 @@ import Welcome from './Welcome' +import FamilyMetadataUpload from './FamilyMetadataUpload' export { Welcome, + FamilyMetadataUpload, } From 20ae88f4a476b63ddd0f44154806858cf4160ae0 Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Mon, 8 Nov 2021 17:10:24 +1100 Subject: [PATCH 18/43] Implemented state handling for changes occurring in each form step --- .../DataLoadingWizardForm.jsx | 135 ++++++++++++++---- 1 file changed, 107 insertions(+), 28 deletions(-) diff --git a/ui/pages/Project/components/DataLoadingWizardForm/DataLoadingWizardForm.jsx b/ui/pages/Project/components/DataLoadingWizardForm/DataLoadingWizardForm.jsx index 29c9303553..61ddfc21f2 100644 --- a/ui/pages/Project/components/DataLoadingWizardForm/DataLoadingWizardForm.jsx +++ b/ui/pages/Project/components/DataLoadingWizardForm/DataLoadingWizardForm.jsx @@ -1,31 +1,112 @@ -import React, { useState, useEffect } from 'react' +import React, { useState, useEffect, useCallback } from 'react' import PropTypes from 'prop-types' -import { Breadcrumb, Header } from 'semantic-ui-react' +import { Breadcrumb } from 'semantic-ui-react' import { Centered, FormSection, FormStepButtons } from './ui' -import { Welcome } from './steps' - -const FORM_STEPS = [ - { key: 0, content: 'Welcome', link: false, active: true, component: Welcome }, - { key: 1, content: 'Family metadata', link: false, active: false, component: () => {} }, - { key: 2, content: 'Individual metadata', link: false, active: false, component: () => {} }, - { key: 3, content: 'Sample mapping', link: false, active: false, component: () => {} }, - { key: 4, content: 'Submit', link: false, active: false, component: () => {} }, +import { Welcome, FamilyMetadataUpload } from './steps' +import { Error404 } from '../../../../shared/components/page/Errors' + +const BREADCRUMBS = [ + { key: 0, content: 'Welcome', link: true, active: true }, + { key: 1, content: 'Family metadata', link: true, active: false }, + { key: 2, content: 'Individual metadata', link: true, active: false }, + { key: 3, content: 'Sample mapping', link: true, active: false }, + { key: 4, content: 'Review', link: true, active: false }, ] + const DataLoadingWizardForm = ({ project }) => { - // const [formState, setFormState] = useState({}) - const [formStepIndex, setFormStepIndex] = useState(0) - const [formSteps, setFormSteps] = useState([...FORM_STEPS]) + // ---- Debug ---- // + console.group('Project Object') + console.log(project) + console.groupEnd() + + // ---- State ----- // + const [breadCrumbs, setBreadcrumbs] = useState(BREADCRUMBS.map((b) => { return { ...b } })) + const [activeFormStepIndex, setActiveFormStepIndex] = useState(0) + const [formSteps, setFormSteps] = useState(BREADCRUMBS.map( + (_, index) => { + return { formData: {}, isComplete: (index === 0) } + }, + )) + + // ---- Callbacks ----- // + const updateFormStep = useCallback((stepNumber, { formData, isComplete }) => { + setFormSteps(formSteps.map( + (step, index) => { + if (stepNumber === index) { + return { formData, isComplete } + } + return { ...step } + }, + )) + }, []) + + const enableReview = useCallback(() => { + return formSteps + .slice(0, formSteps.length - 1) + .reduce((acc, step) => acc && step.isComplete, true) + }, [formSteps]) + + const enableNext = useCallback(() => { + if (activeFormStepIndex === (formSteps.length - 2)) { + return enableReview() + } + + return activeFormStepIndex < formSteps.length + }, [formSteps, activeFormStepIndex, enableReview]) + const getFormStepComponent = useCallback(() => { + switch (activeFormStepIndex) { + case 0: + return + case 1: + return updateFormStep(1, { formData, isComplete })} + /> + case 2: + return
{ breadCrumbs[activeFormStepIndex].content }
+ case 3: + return
{ breadCrumbs[activeFormStepIndex].content }
+ case 4: + return
{ breadCrumbs[activeFormStepIndex].content }
+ case 5: + return
{ breadCrumbs[activeFormStepIndex].content }
+ default: + return + } + }, [project, activeFormStepIndex, updateFormStep]) + + + // ---- Effects ---- // useEffect(() => { - setFormSteps( - formSteps.map( - (step) => { return { ...step, active: step.key === formStepIndex } }, - ), + setBreadcrumbs(breadCrumbs.map((b, index) => { + return { ...b, active: (index === activeFormStepIndex) } + })) + }, [activeFormStepIndex]) + + useEffect(() => { + setBreadcrumbs( + breadCrumbs.map((b, index) => { + if (index === (breadCrumbs.length - 1)) { + return { + ...b, + link: enableReview(), + onClick: enableReview() ? () => setActiveFormStepIndex(index) : null, + } + } + + return { + ...b, + link: true, + onClick: () => setActiveFormStepIndex(index), + } + }), ) - }, [formStepIndex]) + }, [enableReview]) + // ---- Render ----- // return (
@@ -33,24 +114,22 @@ const DataLoadingWizardForm = ({ project }) => { - {/* React Hook components are just functions under the hood. */} - {/* Get the component property from the current step and call it to add it to the DOM. */} - {formSteps[formStepIndex].component({ project })} -
DEBUG
-
{JSON.stringify(project, null, 2)}
+ {getFormStepComponent()}
setFormStepIndex(Math.min(formStepIndex + 1, formSteps.length - 1))} - onBack={() => setFormStepIndex(Math.max(0, formStepIndex - 1))} + isLastStep={activeFormStepIndex === (formSteps.length - 1)} + onNext={() => setActiveFormStepIndex(Math.min(activeFormStepIndex + 1, formSteps.length - 1))} + onBack={() => setActiveFormStepIndex(Math.max(0, activeFormStepIndex - 1))} + enableNext={enableNext()} + enableSubmit={enableReview()} onSubmit={() => alert('Yay')} /> @@ -60,7 +139,7 @@ const DataLoadingWizardForm = ({ project }) => { From 2d4f412416dd9c23717227c03583fc5d76d1e0d8 Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Mon, 8 Nov 2021 17:11:11 +1100 Subject: [PATCH 19/43] Minor refactoring favouring positivity over negativity in args --- .../ui/FormStepButtons.jsx | 55 +++++++------------ 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/ui/pages/Project/components/DataLoadingWizardForm/ui/FormStepButtons.jsx b/ui/pages/Project/components/DataLoadingWizardForm/ui/FormStepButtons.jsx index bca91cb5d5..d8bd26fce4 100644 --- a/ui/pages/Project/components/DataLoadingWizardForm/ui/FormStepButtons.jsx +++ b/ui/pages/Project/components/DataLoadingWizardForm/ui/FormStepButtons.jsx @@ -8,55 +8,38 @@ const FormButtonGroup = styled.div` justify-content: right; ` -const FormStepButtons = ({ isLastStep, onNext, onBack, onSubmit, disabled, loading, size }) => { - if (isLastStep) { - return ( - - - - - - ) - } +const FormStepButtons = ({ isLastStep, onNext, onBack, onSubmit, enableNext, enableSubmit, loading, size }) => { + const submitButton = ( + + ) return ( + { + isLastStep ? submitButton : null + } ) } @@ -66,7 +49,8 @@ FormStepButtons.propTypes = { onNext: PropTypes.func, onBack: PropTypes.func, onSubmit: PropTypes.func, - disabled: PropTypes.bool, + enableNext: PropTypes.bool, + enableSubmit: PropTypes.bool, loading: PropTypes.bool, size: PropTypes.string, } @@ -76,7 +60,8 @@ FormStepButtons.defaultProps = { onNext: () => {}, onBack: () => {}, onSubmit: () => {}, - disabled: false, + enableNext: false, + enableSubmit: false, loading: false, size: 'small', } From 58f3aeae127fec2dfdae08f72be6f8d65be901ef Mon Sep 17 00:00:00 2001 From: daniaki <7043686+daniaki@users.noreply.github.com> Date: Thu, 27 Jan 2022 16:32:30 +1100 Subject: [PATCH 20/43] Renamed directory to `DataLoadingWizard` --- .../DataLoadingWizard.jsx} | 54 ++++--- .../steps/FamilyMetadataUpload.jsx | 145 ++++++++++++++++++ .../steps/IndividualMetadataUpload.jsx | 0 .../steps/Review.jsx | 0 .../steps/SampleMapping.jsx | 0 .../DataLoadingWizard/steps/Welcome.jsx | 36 +++++ .../steps/index.js | 0 .../ui/Centered.jsx | 0 .../ui/FormSection.jsx | 0 .../ui/FormStepButtons.jsx | 3 +- .../ui/index.js | 2 + .../steps/FamilyMetadataUpload.jsx | 15 -- .../DataLoadingWizardForm/steps/Welcome.jsx | 43 ------ 13 files changed, 216 insertions(+), 82 deletions(-) rename ui/pages/Project/components/{DataLoadingWizardForm/DataLoadingWizardForm.jsx => DataLoadingWizard/DataLoadingWizard.jsx} (76%) create mode 100644 ui/pages/Project/components/DataLoadingWizard/steps/FamilyMetadataUpload.jsx rename ui/pages/Project/components/{DataLoadingWizardForm => DataLoadingWizard}/steps/IndividualMetadataUpload.jsx (100%) rename ui/pages/Project/components/{DataLoadingWizardForm => DataLoadingWizard}/steps/Review.jsx (100%) rename ui/pages/Project/components/{DataLoadingWizardForm => DataLoadingWizard}/steps/SampleMapping.jsx (100%) create mode 100644 ui/pages/Project/components/DataLoadingWizard/steps/Welcome.jsx rename ui/pages/Project/components/{DataLoadingWizardForm => DataLoadingWizard}/steps/index.js (100%) rename ui/pages/Project/components/{DataLoadingWizardForm => DataLoadingWizard}/ui/Centered.jsx (100%) rename ui/pages/Project/components/{DataLoadingWizardForm => DataLoadingWizard}/ui/FormSection.jsx (100%) rename ui/pages/Project/components/{DataLoadingWizardForm => DataLoadingWizard}/ui/FormStepButtons.jsx (98%) rename ui/pages/Project/components/{DataLoadingWizardForm => DataLoadingWizard}/ui/index.js (75%) delete mode 100644 ui/pages/Project/components/DataLoadingWizardForm/steps/FamilyMetadataUpload.jsx delete mode 100644 ui/pages/Project/components/DataLoadingWizardForm/steps/Welcome.jsx diff --git a/ui/pages/Project/components/DataLoadingWizardForm/DataLoadingWizardForm.jsx b/ui/pages/Project/components/DataLoadingWizard/DataLoadingWizard.jsx similarity index 76% rename from ui/pages/Project/components/DataLoadingWizardForm/DataLoadingWizardForm.jsx rename to ui/pages/Project/components/DataLoadingWizard/DataLoadingWizard.jsx index 61ddfc21f2..ec18354ac2 100644 --- a/ui/pages/Project/components/DataLoadingWizardForm/DataLoadingWizardForm.jsx +++ b/ui/pages/Project/components/DataLoadingWizard/DataLoadingWizard.jsx @@ -1,10 +1,16 @@ +/* eslint-disable react-perf/jsx-no-new-function-as-prop */ +/* eslint-disable no-console */ +/* eslint-disable no-alert */ + import React, { useState, useEffect, useCallback } from 'react' import PropTypes from 'prop-types' +import { connect } from 'react-redux' import { Breadcrumb } from 'semantic-ui-react' import { Centered, FormSection, FormStepButtons } from './ui' import { Welcome, FamilyMetadataUpload } from './steps' import { Error404 } from '../../../../shared/components/page/Errors' +import { getCurrentProject } from '../../selectors' const BREADCRUMBS = [ { key: 0, content: 'Welcome', link: true, active: true }, @@ -14,20 +20,17 @@ const BREADCRUMBS = [ { key: 4, content: 'Review', link: true, active: false }, ] - -const DataLoadingWizardForm = ({ project }) => { +const BaseMultistepForm = ({ project }) => { // ---- Debug ---- // console.group('Project Object') console.log(project) console.groupEnd() // ---- State ----- // - const [breadCrumbs, setBreadcrumbs] = useState(BREADCRUMBS.map((b) => { return { ...b } })) + const [breadCrumbs, setBreadcrumbs] = useState(BREADCRUMBS.map(b => ({ ...b }))) const [activeFormStepIndex, setActiveFormStepIndex] = useState(0) const [formSteps, setFormSteps] = useState(BREADCRUMBS.map( - (_, index) => { - return { formData: {}, isComplete: (index === 0) } - }, + (_, index) => ({ formData: {}, isComplete: (index === 0) }), )) // ---- Callbacks ----- // @@ -40,14 +43,12 @@ const DataLoadingWizardForm = ({ project }) => { return { ...step } }, )) - }, []) - - const enableReview = useCallback(() => { - return formSteps - .slice(0, formSteps.length - 1) - .reduce((acc, step) => acc && step.isComplete, true) }, [formSteps]) + const enableReview = useCallback(() => formSteps + .slice(0, formSteps.length - 1) + .reduce((acc, step) => acc && step.isComplete, true), [formSteps]) + const enableNext = useCallback(() => { if (activeFormStepIndex === (formSteps.length - 2)) { return enableReview() @@ -61,10 +62,12 @@ const DataLoadingWizardForm = ({ project }) => { case 0: return case 1: - return updateFormStep(1, { formData, isComplete })} - /> + return ( + updateFormStep(1, { formData, isComplete })} + /> + ) case 2: return
{ breadCrumbs[activeFormStepIndex].content }
case 3: @@ -78,12 +81,9 @@ const DataLoadingWizardForm = ({ project }) => { } }, [project, activeFormStepIndex, updateFormStep]) - // ---- Effects ---- // useEffect(() => { - setBreadcrumbs(breadCrumbs.map((b, index) => { - return { ...b, active: (index === activeFormStepIndex) } - })) + setBreadcrumbs(breadCrumbs.map((b, index) => ({ ...b, active: (index === activeFormStepIndex) }))) }, [activeFormStepIndex]) useEffect(() => { @@ -147,8 +147,16 @@ const DataLoadingWizardForm = ({ project }) => { ) } -DataLoadingWizardForm.propTypes = { - project: PropTypes.object, +BaseMultistepForm.propTypes = { + project: PropTypes.object.isRequired, } -export default DataLoadingWizardForm +const mapStateToProps = state => ({ + project: getCurrentProject(state), +}) + +export const MultistepForm = connect(mapStateToProps)(BaseMultistepForm) + +const DataLoadingWizard = () => + +export default DataLoadingWizard diff --git a/ui/pages/Project/components/DataLoadingWizard/steps/FamilyMetadataUpload.jsx b/ui/pages/Project/components/DataLoadingWizard/steps/FamilyMetadataUpload.jsx new file mode 100644 index 0000000000..41d3429ee1 --- /dev/null +++ b/ui/pages/Project/components/DataLoadingWizard/steps/FamilyMetadataUpload.jsx @@ -0,0 +1,145 @@ +import React, { useCallback, useState } from 'react' +import PropTypes from 'prop-types' + +import { Form, Table, Icon, List, Message } from 'semantic-ui-react' +import { ReadableText } from '../ui' +import TemplateFile from '../templates/TemplateFile' +import FamilyTemplateColumns from '../templates/Family' + +const TemplateDirectoryLink = () => ( + + here + +) + +const FamilyMetadataUpload = ({ project, onFormChange }) => { + const columns = FamilyTemplateColumns() + + const [isLoading, setIsLoading] = useState(false) + const [error, setError] = useState(null) + const [rows, setRows] = useState([]) + const [valid, setValid] = useState(null) + + const parseFile = useCallback((event) => { + if (event.target.files[0]) { + setError(null) + setValid(null) + setRows([]) + + if (!event.target.files[0].name.match(/\.(tsv|csv)$/)) { + setError('Please upload a TSV or CSV file.') + setValid(false) + return + } + + setIsLoading(true) + const parser = new TemplateFile(columns) + parser.parse( + event.target.files[0], + () => { + setError(null) + setIsLoading(false) + setValid(parser.valid) + setRows([...parser.rows]) + + console.debug(parser) + }, + (e) => { + setError(e) + setIsLoading(false) + setValid(false) + setRows([]) + }, + ) + } + }, [setIsLoading, setError, setRows]) + + return ( + <> + + In this section, you will provide all information relating to the families in your project. Please download + the families template from + {' '} + + { '. ' } + Once you have filled in this template, upload it via this step and correct any validation errors + before proceeding. + + +
+ + + + {valid === false ? ( + + ) : null} + + + + + + {columns.map(c => {`${c.key}${c.required ? ' *' : ''}`})} + Comments + + + + {error ? + ( + + {error ? error.toString() : 'No data loaded'} + + ) : + rows.map(row => ( + + + {row.valid ? : } + + {row.columns.map(([columnDef, columnValue]) => ( + + {Array.isArray(columnValue.value) ? columnValue.value.join(', ') : columnValue.value} + + ))} + + {row.valid ? null : ( + + { + row.columns.map(([columnDef, columnValue]) => { + if (columnValue.valid) return null + + const innerList = columnValue.errors.map((e, i) => ( + {e} + )) + return ( + +
{columnDef.key}
+ {innerList} +
+ ) + }) + } +
+ )} +
+
+ )) } +
+
+ + ) +} + +FamilyMetadataUpload.propTypes = { + project: PropTypes.object.isRequired, + onFormChange: PropTypes.func.isRequired, +} + +FamilyMetadataUpload.defaultProps = {} + +export default FamilyMetadataUpload diff --git a/ui/pages/Project/components/DataLoadingWizardForm/steps/IndividualMetadataUpload.jsx b/ui/pages/Project/components/DataLoadingWizard/steps/IndividualMetadataUpload.jsx similarity index 100% rename from ui/pages/Project/components/DataLoadingWizardForm/steps/IndividualMetadataUpload.jsx rename to ui/pages/Project/components/DataLoadingWizard/steps/IndividualMetadataUpload.jsx diff --git a/ui/pages/Project/components/DataLoadingWizardForm/steps/Review.jsx b/ui/pages/Project/components/DataLoadingWizard/steps/Review.jsx similarity index 100% rename from ui/pages/Project/components/DataLoadingWizardForm/steps/Review.jsx rename to ui/pages/Project/components/DataLoadingWizard/steps/Review.jsx diff --git a/ui/pages/Project/components/DataLoadingWizardForm/steps/SampleMapping.jsx b/ui/pages/Project/components/DataLoadingWizard/steps/SampleMapping.jsx similarity index 100% rename from ui/pages/Project/components/DataLoadingWizardForm/steps/SampleMapping.jsx rename to ui/pages/Project/components/DataLoadingWizard/steps/SampleMapping.jsx diff --git a/ui/pages/Project/components/DataLoadingWizard/steps/Welcome.jsx b/ui/pages/Project/components/DataLoadingWizard/steps/Welcome.jsx new file mode 100644 index 0000000000..fd916c7a4f --- /dev/null +++ b/ui/pages/Project/components/DataLoadingWizard/steps/Welcome.jsx @@ -0,0 +1,36 @@ +import React from 'react' +import styled from 'styled-components' +import { ReadableText } from '../ui' + +const WelcomeSection = styled.section` + margin: 1em 0; +` + +const Welcome = () => ( +
+ + + Welcome to the seqr data loading wizard! This wizard will guide you through the process of uploading + the relevant individual template, family template and associated metadata files. Each step will validate + these files to ensure that the information relating individuals, families and samples is correctly formatted. + + + + +

Introduction

+ Overview of what the collaborator needs to do goes here +
+ + +

Resources

+ Overview of required template and mapping formats +
+ + +

FAQ

+ Frequently asked questions and answers +
+
+) + +export default Welcome diff --git a/ui/pages/Project/components/DataLoadingWizardForm/steps/index.js b/ui/pages/Project/components/DataLoadingWizard/steps/index.js similarity index 100% rename from ui/pages/Project/components/DataLoadingWizardForm/steps/index.js rename to ui/pages/Project/components/DataLoadingWizard/steps/index.js diff --git a/ui/pages/Project/components/DataLoadingWizardForm/ui/Centered.jsx b/ui/pages/Project/components/DataLoadingWizard/ui/Centered.jsx similarity index 100% rename from ui/pages/Project/components/DataLoadingWizardForm/ui/Centered.jsx rename to ui/pages/Project/components/DataLoadingWizard/ui/Centered.jsx diff --git a/ui/pages/Project/components/DataLoadingWizardForm/ui/FormSection.jsx b/ui/pages/Project/components/DataLoadingWizard/ui/FormSection.jsx similarity index 100% rename from ui/pages/Project/components/DataLoadingWizardForm/ui/FormSection.jsx rename to ui/pages/Project/components/DataLoadingWizard/ui/FormSection.jsx diff --git a/ui/pages/Project/components/DataLoadingWizardForm/ui/FormStepButtons.jsx b/ui/pages/Project/components/DataLoadingWizard/ui/FormStepButtons.jsx similarity index 98% rename from ui/pages/Project/components/DataLoadingWizardForm/ui/FormStepButtons.jsx rename to ui/pages/Project/components/DataLoadingWizard/ui/FormStepButtons.jsx index d8bd26fce4..fec464d5ee 100644 --- a/ui/pages/Project/components/DataLoadingWizardForm/ui/FormStepButtons.jsx +++ b/ui/pages/Project/components/DataLoadingWizard/ui/FormStepButtons.jsx @@ -27,7 +27,8 @@ const FormStepButtons = ({ isLastStep, onNext, onBack, onSubmit, enableNext, ena size={size} onClick={onBack} loading={loading} - >Back + > + Back