Skip to content

Commit

Permalink
Merge pull request #718 from open-formulieren/feature/4544-configurab…
Browse files Browse the repository at this point in the history
…le-formstep-previous-button

✨ [open-formulieren/open-forms#4544] Configurable form 'previous' link
  • Loading branch information
sergei-maertens authored Oct 10, 2024
2 parents 8ba7da2 + 11ab95f commit 06d6ac1
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 78 deletions.
2 changes: 1 addition & 1 deletion design-tokens
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"@floating-ui/react": "^0.26.9",
"@formio/protected-eval": "^1.2.1",
"@fortawesome/fontawesome-free": "6.4.0",
"@open-formulieren/design-tokens": "^0.53.0",
"@open-formulieren/design-tokens": "^0.54.0",
"@open-formulieren/formiojs": "^4.13.14",
"@open-formulieren/leaflet-tools": "^1.0.0",
"@sentry/react": "^6.13.2",
Expand Down
88 changes: 41 additions & 47 deletions src/components/ButtonsToolbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ import React from 'react';

import AbortButton from 'components/AbortButton';
import {OFButton} from 'components/Button';
import Link from 'components/Link';
import {Literal, LiteralsProvider} from 'components/Literal';
import {Literal} from 'components/Literal';
import Loader from 'components/Loader';
import PreviousLink from 'components/PreviousLink';
import {Toolbar, ToolbarList} from 'components/Toolbar';
import {SUBMISSION_ALLOWED} from 'components/constants';

const ButtonsToolbar = ({
literals,
canSubmitStep,
canSubmitForm,
canSuspendForm,
Expand All @@ -27,58 +26,53 @@ const ButtonsToolbar = ({

return (
<>
<LiteralsProvider literals={literals}>
<Toolbar modifiers={['mobile-reverse-order', 'bottom']}>
<Toolbar modifiers={['mobile-reverse-order', 'bottom']}>
<ToolbarList>
{previousPage && (
<PreviousLink to={previousPage} onClick={onNavigatePrevPage} position="end" />
)}
</ToolbarList>
<ToolbarList>
{/* TODO: refactor: `const canSuspendForm = onFormSave === undefined` - this does not
need to be its own prop */}
{canSuspendForm && (
<OFButton
type="button"
appearance="secondary-action-button"
name="save"
onClick={onFormSave}
>
<Literal name="saveText" />
</OFButton>
)}
{showSubmitButton && (
<OFButton
type="submit"
appearance="primary-action-button"
name="next"
disabled={!canSubmitStep}
>
{isCheckingLogic ? (
<Loader modifiers={['centered', 'only-child', 'small', 'gray']} />
) : (
<Literal name="nextText" />
)}
</OFButton>
)}
</ToolbarList>
</Toolbar>
{!hideAbortButton && (
<Toolbar modifiers={['bottom', 'reverse']}>
<ToolbarList>
{previousPage && (
<Link to={previousPage} onClick={onNavigatePrevPage}>
<Literal name="previousText" />
</Link>
)}
</ToolbarList>
<ToolbarList>
{/* TODO: refactor: `const canSuspendForm = onFormSave === undefined` - this does not
need to be its own prop */}
{canSuspendForm && (
<OFButton
type="button"
appearance="secondary-action-button"
name="save"
onClick={onFormSave}
>
<Literal name="saveText" />
</OFButton>
)}
{showSubmitButton && (
<OFButton
type="submit"
appearance="primary-action-button"
name="next"
disabled={!canSubmitStep}
>
{isCheckingLogic ? (
<Loader modifiers={['centered', 'only-child', 'small', 'gray']} />
) : (
<Literal name="nextText" />
)}
</OFButton>
)}
<AbortButton isAuthenticated={isAuthenticated} onDestroySession={onDestroySession} />
</ToolbarList>
</Toolbar>
{!hideAbortButton && (
<Toolbar modifiers={['bottom', 'reverse']}>
<ToolbarList>
<AbortButton isAuthenticated={isAuthenticated} onDestroySession={onDestroySession} />
</ToolbarList>
</Toolbar>
)}
</LiteralsProvider>
)}
</>
);
};

ButtonsToolbar.propTypes = {
literals: PropTypes.object,
canSubmitStep: PropTypes.bool.isRequired,
canSubmitForm: PropTypes.string.isRequired,
canSuspendForm: PropTypes.bool.isRequired,
Expand Down
11 changes: 4 additions & 7 deletions src/components/ButtonsToolbar/test.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {act} from 'react-dom/test-utils';
import {IntlProvider} from 'react-intl';
import {MemoryRouter} from 'react-router-dom';

import {LiteralsProvider} from 'components/Literal';
import {SUBMISSION_ALLOWED} from 'components/constants';

import ButtonsToolbar from './index';
Expand Down Expand Up @@ -37,7 +38,9 @@ const LITERALS = {

const Wrap = ({children}) => (
<IntlProvider locale="nl" messages={messagesNL}>
<MemoryRouter>{children}</MemoryRouter>
<MemoryRouter>
<LiteralsProvider literals={LITERALS}>{children}</LiteralsProvider>
</MemoryRouter>
</IntlProvider>
);

Expand All @@ -48,7 +51,6 @@ it('Last step of submittable form, button is present', () => {
root.render(
<Wrap>
<ButtonsToolbar
literals={LITERALS}
canSubmitStep={true}
canSubmitForm={SUBMISSION_ALLOWED.yes}
canSuspendForm={true}
Expand Down Expand Up @@ -80,7 +82,6 @@ it('Last step of non-submittable form with overview, button is present', () => {
root.render(
<Wrap>
<ButtonsToolbar
literals={LITERALS}
canSubmitStep={true}
canSubmitForm={SUBMISSION_ALLOWED.noWithOverview}
canSuspendForm={true}
Expand Down Expand Up @@ -112,7 +113,6 @@ it('Last step of non-submittable form without overview, button is NOT present',
root.render(
<Wrap>
<ButtonsToolbar
literals={LITERALS}
canSubmitStep={true}
canSubmitForm={SUBMISSION_ALLOWED.noWithoutOverview}
canSuspendForm={true}
Expand Down Expand Up @@ -143,7 +143,6 @@ it('Non-last step of non-submittable form without overview, button IS present',
root.render(
<Wrap>
<ButtonsToolbar
literals={LITERALS}
canSubmitStep={true}
canSubmitForm={SUBMISSION_ALLOWED.noWithoutOverview}
canSuspendForm={true}
Expand Down Expand Up @@ -174,7 +173,6 @@ it('Suspending form allowed, button is present', () => {
renderTest(
<Wrap>
<ButtonsToolbar
literals={LITERALS}
canSubmitStep={true}
canSubmitForm={SUBMISSION_ALLOWED.yes}
canSuspendForm={true}
Expand All @@ -198,7 +196,6 @@ it('Suspending form not allowed, button is NOT present', () => {
renderTest(
<Wrap>
<ButtonsToolbar
literals={LITERALS}
canSubmitStep={true}
canSubmitForm={SUBMISSION_ALLOWED.yes}
canSuspendForm={false}
Expand Down
12 changes: 8 additions & 4 deletions src/components/FormStep/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ import ButtonsToolbar from 'components/ButtonsToolbar';
import Card, {CardTitle} from 'components/Card';
import {EmailVerificationModal} from 'components/EmailVerification';
import FormStepDebug from 'components/FormStepDebug';
import {LiteralsProvider} from 'components/Literal';
import Loader from 'components/Loader';
import PreviousLink from 'components/PreviousLink';
import SummaryProgress from 'components/SummaryProgress';
import FormStepSaveModal from 'components/modals/FormStepSaveModal';
import {
Expand Down Expand Up @@ -838,11 +840,14 @@ const FormStep = ({form, submission, onLogicChecked, onStepSubmitted, onDestroyS
const applicableSteps = submission.steps.filter(step => step.isApplicable === true);
const currentSubmissionStepIndex = applicableSteps.indexOf(submissionStep);

const previousPage = getPreviousPageHref();
return (
<>
<LiteralsProvider literals={formStep.literals}>
<Card title={form.name} titleComponent="h1" modifiers={['mobile-header-hidden']}>
{isLoadingSomething ? <Loader modifiers={['centered']} /> : null}

{previousPage && <PreviousLink to={previousPage} onClick={onPrevPage} position="start" />}

{!isLoadingSomething && form.showSummaryProgress && (
<SummaryProgress
current={currentSubmissionStepIndex + 1}
Expand Down Expand Up @@ -904,7 +909,6 @@ const FormStep = ({form, submission, onLogicChecked, onStepSubmitted, onDestroyS
/>
{config.debug ? <FormStepDebug data={getCurrentFormData()} /> : null}
<ButtonsToolbar
literals={formStep.literals}
canSubmitStep={canSubmit}
canSubmitForm={submission.submissionAllowed}
canSuspendForm={form.suspensionAllowed}
Expand All @@ -914,7 +918,7 @@ const FormStep = ({form, submission, onLogicChecked, onStepSubmitted, onDestroyS
loginRequired={form.loginRequired}
onFormSave={onFormSave}
onNavigatePrevPage={onPrevPage}
previousPage={getPreviousPageHref()}
previousPage={previousPage}
onDestroySession={onDestroySession}
/>
</form>
Expand All @@ -937,7 +941,7 @@ const FormStep = ({form, submission, onLogicChecked, onStepSubmitted, onDestroyS
componentKey={emailVerificationModal.componentKey}
emailAddress={emailVerificationModal.emailAddress}
/>
</>
</LiteralsProvider>
);
};

Expand Down
11 changes: 9 additions & 2 deletions src/components/IntroductionPage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {Navigate} from 'react-router-dom';
import {FormContext} from 'Context';
import Body from 'components/Body';
import Card from 'components/Card';
import FAIcon from 'components/FAIcon';
import Link from 'components/Link';

const IntroductionPage = () => {
Expand All @@ -21,11 +22,17 @@ const IntroductionPage = () => {
dangerouslySetInnerHTML={{__html: introductionPageContent}}
/>

<Link to="/startpagina" component={ButtonLink} appearance="primary-action-button">
<Link
to="/startpagina"
component={ButtonLink}
appearance="primary-action-button"
className="openforms-start-link"
>
<FormattedMessage
description="Button text for link to continue from introduction page to start page"
defaultMessage="Continue"
defaultMessage="Continue"
/>
<FAIcon icon="arrow-right-long" />
</Link>
</Card>
);
Expand Down
29 changes: 29 additions & 0 deletions src/components/PreviousLink.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';

import FAIcon from 'components/FAIcon';
import Link from 'components/Link';
import Literal from 'components/Literal';

const VARIANTS = ['start', 'end'];

const PreviousLink = ({to, onClick, position}) => {
const className = classNames('openforms-previous-link', {
[`openforms-previous-link--${position}`]: position,
});
return (
<Link to={to} onClick={onClick} className={className}>
<FAIcon icon="arrow-left-long" extraClassName="openforms-previous-link__icon" />
<Literal name="previousText" />
</Link>
);
};

PreviousLink.propTypes = {
to: PropTypes.string.isRequired,
onClick: PropTypes.func,
position: PropTypes.oneOf(VARIANTS),
};

export default PreviousLink;
32 changes: 18 additions & 14 deletions src/components/appointments/SubmitRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,34 @@ import React from 'react';
import {useNavigate} from 'react-router-dom';

import ButtonsToolbar from 'components/ButtonsToolbar';
import {LiteralsProvider} from 'components/Literal';
import {SUBMISSION_ALLOWED} from 'components/constants';

const SubmitRow = ({canSubmit, nextText, previousText = '', navigateBackTo = ''}) => {
const navigate = useNavigate();

return (
<ButtonsToolbar
<LiteralsProvider
literals={{
nextText: {resolved: nextText},
previousText: {resolved: previousText},
}}
canSubmitStep={canSubmit}
canSubmitForm={SUBMISSION_ALLOWED.yes}
canSuspendForm={false}
isAuthenticated={false} // TODO -> if authenticated (for prefill), logout must be shown
isLastStep={false}
isCheckingLogic={false}
loginRequired={false}
hideAbortButton
previousPage={navigateBackTo ? `../${navigateBackTo}` : ''}
onFormSave={() => {}}
onNavigatePrevPage={navigateBackTo ? () => navigate(`../${navigateBackTo}`) : undefined}
onDestroySession={() => {}}
/>
>
<ButtonsToolbar
canSubmitStep={canSubmit}
canSubmitForm={SUBMISSION_ALLOWED.yes}
canSuspendForm={false}
isAuthenticated={false} // TODO -> if authenticated (for prefill), logout must be shown
isLastStep={false}
isCheckingLogic={false}
loginRequired={false}
hideAbortButton
previousPage={navigateBackTo ? `../${navigateBackTo}` : ''}
onFormSave={() => {}}
onNavigatePrevPage={navigateBackTo ? () => navigate(`../${navigateBackTo}`) : undefined}
onDestroySession={() => {}}
/>
</LiteralsProvider>
);
};

Expand Down
22 changes: 22 additions & 0 deletions src/scss/components/_previous-link.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@use 'microscope-sass/lib/bem';

.openforms-previous-link {
flex-direction: row;
column-gap: 8px;

@include bem.modifier('start') {
margin-block-end: 20px;
// NOTE: usually block elements should not define margins, but this is done deliberately
// See https://github.com/open-formulieren/open-forms-sdk/pull/718#discussion_r1791617060 for
// more discussion context.
display: var(--of-previous-link-display-start, none);
}

@include bem.modifier('end') {
display: var(--of-previous-link-display-end, inline-flex);
}

@include bem.element('icon') {
display: var(--of-previous-link-icon-display, none);
}
}
Loading

0 comments on commit 06d6ac1

Please sign in to comment.