Skip to content

Commit

Permalink
Feat/combine gwas workflow progress bar (#1125)
Browse files Browse the repository at this point in the history
* Update node js and fix failing unit tests (#1119)

* fixed unhandled promise rejection

...which fixes locally failing jest test

* fix failing unit test for UserProfile

* udpate node js and npm for CI tests

* make test a bit more specific

* set node js to 16.x

* update node js to 16.x and npm to 8.15 in Dockerfile

* revert npm version change

* feat(CombineGWASWorkflowProgressBar): Initial commit

* feat(CombineGWASWorkflowProgressBar): created partially working prototype

* feat(CombineGWASWorkflowProgressBar): added logic for displaying select or edit for each step

* feat(CombineGWASWorkflowProgressBar): created CSS style sheet for new component and began overriding AntD styles to match design

* feat(CombineGWASWorkflowProgressBar): fixed colors to match design for numeric icons

* feat(CombineGWASWorkflowProgressBar): set width to container to 100%

* feat(CombineGWASWorkflowProgressBar): added animation

* feat(CombineGWASWorkflowProgressBar): added styles for Get Started button

* feat(CombineGWASWorkflowProgressBar): positioned get started button

* feat(CombineGWASWorkflowProgressBar): removed inline styles from ProgressBar.jsx

* feat(CombineGWASWorkflowProgressBar): formatted GWASContainer.jsx

* feat(CombineGWASWorkflowProgressBar): changed class name to progress-bar

* feat(CombineGWASWorkflowProgressBar): began authoring JEST test

* feat(CombineGWASWorkflowProgressBar): Added clarifying comment to jest test

* feat(CombineGWASWorkflowProgressBar): Formatted test code

* feat(CombineGWASWorkflowProgressBar): Added Story Book for ProgressBar

* feat(CombineGWASWorkflowProgressBar): ran eslint on ProgressBar.test.jsx

* feat(CombineGWASWorkflowProgressBar): ran autoformatters eslint and stylelint

* feat(CombineGWASWorkflowProgressBar): Resolved style lint error in ProgressBar.css

* feat(CombineGWASWorkflowProgressBar): Resolved remaining style lint errors in ProgressBar.css

* feat(CombineGWASWorkflowProgressBar): reverted unintentionally changed file

* feat(CombineGWASWorkflowProgressBar): reverted unintentionally changed file

* feat(CombineGWASWorkflowProgressBar): reverted unintentionally changed file

* feat(CombineGWASWorkflowProgressBar): reverted unintentionally changed file Dockerfile

* feat(CombineGWASWorkflowProgressBar): reverted unintentionally changed file Submission/MapDataModel.jsx

* feat(CombineGWASWorkflowProgressBar): reverted unintentionally changed file UserProfile/UserProfile.test.jsx

* feat(CombineGWASWorkflowProgressBar): reverted unintentionally changed file again  UserProfile/UserProfile.test.jsx

* feat(CombineGWASWorkflowProgressBar): Ran ESLINT fix

* feat(CombineGWASWorkflowProgressBar): Refactored code to use a constants file to make code more DRY

* feat(CombineGWASWorkflowProgressBar): Ran ESLINT on recently updated files

* feat(CombineGWASWorkflowProgressBar): Ran ESLINT on recently updated files

* feat(CombineGWASWorkflowProgressBar): Added media query so that button will not overlap progress bar on smaller screens

* feat(CombineGWASWorkflowProgressBar): Formatted CSS with line break

* feat(CombineGWASWorkflowProgressBar): Updated JEST test to use for loops

* feat(CombineGWASWorkflowProgressBar): Updated GWASContainer.jsx to use nextButtonEnabled boolean for disabling or enabling next button

* feat(CombineGWASWorkflowProgressBar): Ran eslint on  GWASContainer.jsx

Co-authored-by: pieterlukasse <pieterlukasse@gmail.com>
  • Loading branch information
jarvisraymond-uchicago and pieterlukasse authored Oct 20, 2022
1 parent bbd1c59 commit 83d47d0
Show file tree
Hide file tree
Showing 6 changed files with 338 additions and 65 deletions.
126 changes: 61 additions & 65 deletions src/Analysis/GWASV2/GWASContainer.jsx
Original file line number Diff line number Diff line change
@@ -1,110 +1,106 @@
import React, { useState } from "react";
import { Space, Button, Popconfirm } from "antd";
import SelectStudyPopulation from "./SelectStudyPopulation/SelectStudyPopulation";
import "./GWASV2.css";
import React, { useState } from 'react';
import { Space, Button, Popconfirm } from 'antd';
import SelectStudyPopulation from './SelectStudyPopulation/SelectStudyPopulation';
import ProgressBar from './Shared/ProgressBar/ProgressBar';
import { gwasV2Steps } from './Shared/constants';
import './GWASV2.css';

const GWASContainer = () => {
const [current, setCurrent] = useState(0);
const [
selectedStudyPopulationCohort,
setSelectedStudyPopulationCohort,
] = useState({});
const gwasSteps = [
{
title: "Step 1",
description: "Select Study Population",
},
{
title: "Step 2",
description: "Select Outcome Phenotypes",
},
{
title: "Step 3",
description: "Select Covariate Phenotype",
},
{
title: "Step 4",
description: "Configure GWAS",
},
];

const generateStep = () => {
// steps 2 & 3 very similar
switch (current) {
case 0:
// select study population
return (
<SelectStudyPopulation
selectedStudyPopulationCohort={selectedStudyPopulationCohort}
setSelectedStudyPopulationCohort={setSelectedStudyPopulationCohort}
current={current}
/>
);
case 1:
// outcome (customdichotomous or not)
return <React.Fragment>step 2</React.Fragment>;
case 2:
// covariates (customdichtomous or not)
return <React.Fragment>step 3</React.Fragment>;
case 3:
// all other input (mafs, imputation, etc), review, and submit
return <React.Fragment>step 4</React.Fragment>;
default:
// required for eslint
return null;
case 0:
// select study population
return (
<SelectStudyPopulation
selectedStudyPopulationCohort={selectedStudyPopulationCohort}
setSelectedStudyPopulationCohort={setSelectedStudyPopulationCohort}
current={current}
/>
);
case 1:
// outcome (customdichotomous or not)
return <React.Fragment>step 2</React.Fragment>;
case 2:
// covariates (customdichtomous or not)
return <React.Fragment>step 3</React.Fragment>;
case 3:
// all other input (mafs, imputation, etc), review, and submit
return <React.Fragment>step 4</React.Fragment>;
default:
// required for eslint
return null;
}
};

let nextButtonEnabled = true;
if (
current === 0
&& Object.keys(selectedStudyPopulationCohort).length === 0
) {
nextButtonEnabled = false;
}

return (
<React.Fragment>
<ProgressBar current={current} />
{/* Inline style block needed so centering rule doesn't impact other workflows */}
<style>{`.analysis-app__actions > div:nth-child(1) {margin: 0 auto; }`}</style>
<div className="GWASV2">
<Space direction={"vertical"} style={{ width: "100%" }}>
<div className="steps-content">
<style>
{'.analysis-app__actions > div:nth-child(1) { width: 100%; }'}
</style>
<div className='GWASV2'>
<Space direction={'vertical'} style={{ width: '100%' }}>
<div className='steps-content'>
<Space
direction={"vertical"}
align={"center"}
style={{ width: "100%" }}
direction={'vertical'}
align={'center'}
style={{ width: '100%' }}
>
{generateStep(current)}
</Space>
</div>
<div className="steps-action">
<div className='steps-action'>
<Button
className="GWASUI-navBtn GWASUI-navBtn__next"
type="primary"
className='GWASUI-navBtn GWASUI-navBtn__next'
type='primary'
onClick={() => {
setCurrent(current - 1);
}}
disabled={current < 1 ? true : false}
disabled={current < 1}
>
Previous
</Button>
<Popconfirm
title="Are you sure you want to leave this page?"
title='Are you sure you want to leave this page?'
// onConfirm={() => resetGWASType()}
okText="Yes"
cancelText="No"
okText='Yes'
cancelText='No'
>
<Button type="link" size="medium">
<Button type='link' size='medium'>
Select Different GWAS Type
</Button>
</Popconfirm>
{current < gwasSteps.length - 1 && (
{current < gwasV2Steps.length - 1 && (
<Button
data-tour="next-button"
className="GWASUI-navBtn GWASUI-navBtn__next"
type="primary"
data-tour='next-button'
className='GWASUI-navBtn GWASUI-navBtn__next'
type='primary'
onClick={() => {
setCurrent(current + 1);
}}
// disabled={!nextButtonEnabled}
disabled={!nextButtonEnabled}
>
Next
</Button>
)}
{current === gwasSteps.length - 1 && (
<div className="GWASUI-navBtn" />
{current === gwasV2Steps.length - 1 && (
<div className='GWASUI-navBtn' />
)}
</div>
</Space>
Expand Down
119 changes: 119 additions & 0 deletions src/Analysis/GWASV2/Shared/ProgressBar/ProgressBar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
.progress-bar {
width: 100%;
}

.progress-bar__steps {
width: 60%;
float: left;
}

.progress-bar button.ant-btn-default {
float: right;
color: #2e77b8;
border: 1px solid #2e77b8;
transition: none;
margin-top: 5px;
}

@media only screen and (max-width: 1350px) {
.progress-bar button.ant-btn-default,
.progress-bar__steps {
float: none;
}
.progress-bar button.ant-btn-default {
margin-top: 25px;
}
}

.progress-bar button.ant-btn-default:hover {
background: var(--g3-secondary-btn__bg-color--hover);
color: white;
}

.progress-bar .ant-steps-item-icon {
font-size: 22px;
text-align: left;
width: auto;
}

.progress-bar .ant-steps-item-container {
border-bottom: 3px solid black;
}

.progress-bar .ant-steps-item-active:before {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 0;
border-bottom: solid 3px #ef8523;
animation: border_anim 0.3s linear forwards;
}

.progress-bar .ant-steps-item-title {
line-height: 37px;
}

.progress-bar .ant-steps-item-wait .ant-steps-item-icon > .ant-steps-icon,
.progress-bar .ant-steps-item-finish .ant-steps-item-icon > .ant-steps-icon,
.progress-bar
.ant-steps-item-process
> .ant-steps-item-container
> .ant-steps-item-icon
.ant-steps-icon,
.ant-steps-item-wait
> .ant-steps-item-container
> .ant-steps-item-content
> .ant-steps-item-title {
color: black;
}

.progress-bar
.ant-steps-item-active.ant-steps-item-process
> .ant-steps-item-container
> .ant-steps-item-icon
.ant-steps-icon {
color: #ab590d;
}

.progress-bar
.ant-steps-item-active.ant-steps-item-process
> .ant-steps-item-container
> .ant-steps-item-content
> .ant-steps-item-title {
color: #ab590d;
}

.progress-bar .ant-steps-item-active .ant-steps-item-container {
border-bottom: none;
}

.progress-bar .ant-steps-item-wait .ant-steps-item-icon,
.progress-bar
.ant-steps-item-process
> .ant-steps-item-container
> .ant-steps-item-icon {
background: none;
border: none;
}

.progress-bar
.ant-steps-horizontal:not(.ant-steps-label-vertical)
.ant-steps-item {
min-width: 250px;
padding-left: 0;
margin-right: 16px;
}

.progress-bar .ant-steps-item-title::after {
display: none;
}

@keyframes border_anim {
0% {
width: 0%;
}
100% {
width: 100%;
}
}
29 changes: 29 additions & 0 deletions src/Analysis/GWASV2/Shared/ProgressBar/ProgressBar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button, Steps } from 'antd';
import { gwasV2Steps } from '../constants';
import './ProgressBar.css';

const { Step } = Steps;
const ProgressBar = ({ current }) => (
<div className='progress-bar'>
<div className='progress-bar__steps'>
<Steps current={current}>
{gwasV2Steps.map((item, index) => (
<Step
key={item.title}
icon={<React.Fragment>{index + 1}</React.Fragment>}
title={`${current <= index ? item.title : item.secondaryTitle}`}
/>
))}
</Steps>
</div>
<Button>New to GWAS? Get started here</Button>
</div>
);

ProgressBar.propTypes = {
current: PropTypes.number.isRequired,
};

export default ProgressBar;
29 changes: 29 additions & 0 deletions src/Analysis/GWASV2/Shared/ProgressBar/ProgressBar.stories.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { useState } from "react";
import ProgressBar from "./ProgressBar";

export default {
title: "Tests3/GWASV2/ProgressBar",
component: ProgressBar,
};

const Template = (args) => <ProgressBar {...args} />;

export const FirstStepActive = Template.bind({});
FirstStepActive.args = {
current: 0,
};

export const SecondStepActive = Template.bind({});
SecondStepActive.args = {
current: 1,
};

export const ThirdStepActive = Template.bind({});
ThirdStepActive.args = {
current: 2,
};

export const FourthStepActive = Template.bind({});
FourthStepActive.args = {
current: 3,
};
Loading

0 comments on commit 83d47d0

Please sign in to comment.