Skip to content

Commit

Permalink
#25: made pageNavigation component more simple and independence of ch…
Browse files Browse the repository at this point in the history
…ildren

Fixed tests;
Replaced NavButton with more common LinkButton
  • Loading branch information
Igor Poplavsky committed Jan 18, 2021
1 parent 59d7dfe commit 865b453
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 143 deletions.
4 changes: 2 additions & 2 deletions src/__tests__/integration/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,8 @@ export const navigateWithHeaderLink = (component, linkSelector) => {
component.update();
};

export const getNextStepButton = component => component.find('.page-navigation__end button');
export const getPrevStepButton = component => component.find('.page-navigation__start button');
export const getNextStepButton = component => component.find('.page-navigation > .nav-button_forward');
export const getPrevStepButton = component => component.find('.page-navigation > .nav-button_back');

export const moveBack = component => {
getPrevStepButton(component).simulate('click', { button: 0 });
Expand Down
44 changes: 21 additions & 23 deletions src/components/layouts/pages/results/Results.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useMemo } from 'react';
import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Redirect, useHistory, useParams } from 'react-router-dom';
Expand All @@ -7,32 +7,18 @@ import _ from 'lodash';
import AppPages from '../../../AppPages';
import { JOB_STATUS, TASK_STATUS } from '../../../../store/constants';
import { getJobStatus, getTaskStatus } from '../../../../store/job/selectors';
import { isCompliant } from '../../../../store/job/result/selectors';
import { reset } from '../../../../store/application/actions';
import Button from '../../../shared/button/Button';
import WizardStep from '../../wizardStep/WizardStep';
import Summary from './summary/Summary';
import PageNavigation from '../../../shared/pageNavigation/PageNavigation';
import { isCompliant } from '../../../../store/job/result/selectors';
import LinkButton from '../../../shared/linkButton/LinkButton';

function Results({ jobStatus, taskStatus, compliant, onBackClick }) {
function Results({ jobStatus, taskStatus, compliant, resetApp }) {
const { id: jobId } = useParams();
const history = useHistory();

const backButton = useMemo(
() => ({
label: 'Validate another file',
onClick: () => onBackClick(history),
}),
[history, onBackClick]
);

const forwardButton = useMemo(
() => ({
label: 'Inspect errors',
to: AppPages.INSPECT.url(jobId),
disabled: compliant,
}),
[compliant, jobId]
);
const onBackClick = useCallback(() => resetApp(history), [history, resetApp]);

if (jobStatus === JOB_STATUS.NOT_FOUND) {
return <Redirect to={AppPages.NOT_FOUND} />;
Expand All @@ -44,7 +30,19 @@ function Results({ jobStatus, taskStatus, compliant, onBackClick }) {
return (
<WizardStep stepIndex={AppPages.RESULTS.route} className="results">
<Summary />
<PageNavigation back={backButton} forward={forwardButton} />
<PageNavigation>
<Button className="nav-button_back" variant="outlined" color="primary" onClick={onBackClick}>
Validate another file
</Button>
<LinkButton
className="nav-button_forward"
to={AppPages.INSPECT.url(jobId)}
disabled={compliant}
variant="contained"
>
Inspect errors
</LinkButton>
</PageNavigation>
</WizardStep>
);
}
Expand All @@ -53,7 +51,7 @@ Results.propTypes = {
jobStatus: PropTypes.oneOf(_.values(JOB_STATUS)),
taskStatus: PropTypes.oneOf(_.values(TASK_STATUS)),
compliant: PropTypes.bool.isRequired,
onBackClick: PropTypes.func.isRequired,
resetApp: PropTypes.func.isRequired,
};

function mapStateToProps(state) {
Expand All @@ -66,7 +64,7 @@ function mapStateToProps(state) {

function mapDispatchToProps(dispatch) {
return {
onBackClick: history => dispatch(reset(history)),
resetApp: history => dispatch(reset(history)),
};
}

Expand Down
34 changes: 18 additions & 16 deletions src/components/layouts/pages/settings/Settings.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,23 @@
import React, { useMemo } from 'react';
import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';

import AppPages from '../../../AppPages';
import WizardStep from '../../wizardStep/WizardStep';
import ProfileSelect from './profile/ProfileSelect';
import Button from '../../../shared/button/Button';
import LinkButton from '../../../shared/linkButton/LinkButton';
import PageNavigation from '../../../shared/pageNavigation/PageNavigation';
import { getServerGeneralStatus } from '../../../../store/serverInfo/selectors';
import { getJobId } from '../../../../store/job/selectors';
import { validate } from '../../../../store/job/actions';

import './Settings.scss';

const backButton = {
label: 'Upload files',
to: AppPages.UPLOAD,
};

function Settings(props) {
const { allServicesAvailable, jobId, onValidateClick } = props;

const forwardButton = useMemo(
() => ({
label: 'Validate',
disabled: !allServicesAvailable,
onClick: () => onValidateClick(),
}),
[allServicesAvailable, onValidateClick]
);
const onForwardClick = useCallback(() => onValidateClick(), [onValidateClick]);

if (jobId) {
// Once job is initialized and we know its ID redirect to status page to track its progress
Expand All @@ -42,7 +31,20 @@ function Settings(props) {
<ProfileSelect />
</form>
</section>
<PageNavigation back={backButton} forward={forwardButton} />
<PageNavigation>
<LinkButton className="nav-button_back" to={AppPages.UPLOAD} type="back" variant="outlined">
Upload files
</LinkButton>
<Button
className="nav-button_forward"
variant="contained"
color="primary"
disabled={!allServicesAvailable}
onClick={onForwardClick}
>
Validate
</Button>
</PageNavigation>
</WizardStep>
);
}
Expand Down
36 changes: 21 additions & 15 deletions src/components/layouts/pages/upload/Upload.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';
import { Redirect, useHistory } from 'react-router-dom';

import AppPages from '../../../AppPages';
import { validate } from '../../../../store/job/actions';
Expand All @@ -12,23 +12,18 @@ import Dropzone from './dropzone/Dropzone';
import WizardStep from '../../wizardStep/WizardStep';
import PageNavigation from '../../../shared/pageNavigation/PageNavigation';
import SettingsCheckbox from './settingsCheckbox/SettingsCheckbox';
import Button from '../../../shared/button/Button';

function Upload({ filesAttached, isUseSettings, jobId, onValidateClick }) {
const forwardButton = useMemo(() => {
const button = { disabled: !filesAttached };
const history = useHistory();
const forwardLabel = useMemo(() => (isUseSettings ? 'Configure' : 'Validate'), [isUseSettings]);
const onForwardClick = useMemo(() => {
if (isUseSettings) {
return {
...button,
label: 'Configure job',
to: AppPages.SETTINGS,
};
return () => history.push(AppPages.SETTINGS);
}
return {
...button,
label: 'Validate',
onClick: onValidateClick,
};
}, [filesAttached, onValidateClick, isUseSettings]);

return onValidateClick;
}, [history, isUseSettings, onValidateClick]);

if (!isUseSettings && jobId) {
// Once job is initialized and we know its ID redirect to status page to track its progress
Expand All @@ -38,7 +33,18 @@ function Upload({ filesAttached, isUseSettings, jobId, onValidateClick }) {
return (
<WizardStep stepIndex={AppPages.UPLOAD}>
<Dropzone />
<PageNavigation back={<SettingsCheckbox />} forward={forwardButton} />
<PageNavigation>
<SettingsCheckbox />
<Button
className="nav-button_forward"
variant="contained"
color="primary"
disabled={!filesAttached}
onClick={onForwardClick}
>
{forwardLabel}
</Button>
</PageNavigation>
</WizardStep>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/layouts/pages/upload/dropzone/Dropzone.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
flex-direction: column;

&__container {
width: 70%;
width: 80%;
height: 100px;
margin: auto;
padding: 20px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,25 @@ import React from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import Button from '../button/Button';

function NavButton(props) {
const { to, disabled, type, variant } = props;
function LinkButton(props) {
const { to, disabled, variant, className } = props;

return (
<Link
to={to}
className={classNames('app-link nav-button', `nav-button_${type}`, { 'app-link_disabled': disabled })}
>
<Link to={to} className={classNames('app-link', { 'app-link_disabled': disabled }, className)}>
<Button variant={variant} color="primary" disabled={disabled}>
{props.children}
</Button>
</Link>
);
}

NavButton.propTypes = {
LinkButton.propTypes = {
to: PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.func]).isRequired,
type: PropTypes.string.isRequired,
variant: PropTypes.string,
disabled: PropTypes.bool,
};

export default NavButton;
export default LinkButton;
67 changes: 3 additions & 64 deletions src/components/shared/pageNavigation/PageNavigation.js
Original file line number Diff line number Diff line change
@@ -1,70 +1,9 @@
import React from 'react';
import PropTypes from 'prop-types';
import NavButton from './NavButton';
import Button from '../button/Button';
import './PageNavigation.scss';

const TYPE = {
BACK: 'back',
CENTER: 'center',
FORWARD: 'forward',
};
const VARIANTS = {
[TYPE.BACK]: 'outlined',
[TYPE.CENTER]: 'contained',
[TYPE.FORWARD]: 'contained',
};

function PageNavigation(props) {
const { back, forward, center } = props;
return (
<nav className="page-navigation">
<section className="page-navigation__start">{getComponent(back, TYPE.BACK)}</section>
<section className="page-navigation__center">{getComponent(center, TYPE.CENTER)}</section>
<section className="page-navigation__end">{getComponent(forward, TYPE.FORWARD)}</section>
</nav>
);
}

function getComponent(componentObject, type) {
if (React.isValidElement(componentObject)) {
return componentObject;
}

if (componentObject?.to) {
return (
<NavButton to={componentObject.to} type={type} disabled={componentObject.disabled} variant={VARIANTS[type]}>
{componentObject.label}
</NavButton>
);
}

if (componentObject?.onClick) {
return (
<Button
variant={VARIANTS[type]}
color="primary"
disabled={componentObject.disabled}
onClick={componentObject.onClick}
>
{componentObject.label}
</Button>
);
}
import './PageNavigation.scss';

return null;
function PageNavigation({ children }) {
return <nav className="page-navigation">{children}</nav>;
}

const ButtonInterface = PropTypes.shape({
to: PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.func]),
label: PropTypes.string.isRequired,
disabled: PropTypes.bool,
onClick: PropTypes.func,
});

PageNavigation.propTypes = {
back: PropTypes.oneOfType([ButtonInterface, PropTypes.element]),
forward: PropTypes.oneOfType([ButtonInterface, PropTypes.element]),
};

export default PageNavigation;
16 changes: 3 additions & 13 deletions src/components/shared/pageNavigation/PageNavigation.scss
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
.page-navigation {
display: flex;
padding: 20px 0 10px 0;

section {
display: flex;
flex-grow: 1;
flex-basis: 0;
justify-content: center;
align-items: start;

.app-link {
color: inherit;
display: flex;
}
}
justify-content: space-between;
width: 80%;
margin: auto;
}

0 comments on commit 865b453

Please sign in to comment.