Skip to content

Commit

Permalink
♻️ Merge payment/registration shared options config modal
Browse files Browse the repository at this point in the history
Replaced the duplicated code with a dedicated 'generic' component for
both payment/registration plugin configuration option forms.
  • Loading branch information
sergei-maertens committed Nov 8, 2024
1 parent f1886c5 commit f20a7f9
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,103 +5,28 @@ import {FormattedMessage, useIntl} from 'react-intl';

import {SubmitAction} from 'components/admin/forms/ActionButton';
import Field from 'components/admin/forms/Field';
import ModalOptionsConfiguration from 'components/admin/forms/ModalOptionsConfiguration';
import SubmitRow from 'components/admin/forms/SubmitRow';
import {ErrorIcon} from 'components/admin/icons';
import {FormModal} from 'components/admin/modals';

// TODO: see if we can merge this with the registration options configuration component?
const OptionsConfiguration = ({
numErrors,
modalTitle,
initialFormData,
onSubmit,
modalSize = '',
children,
}) => {
const intl = useIntl();
const [modalOpen, setModalOpen] = useState(false);
return (
<Field
name="form.paymentBackendOptions"
label={
<FormattedMessage
description="Payment backend options label"
defaultMessage="Payment backend options"
/>
}
>
<>
<span style={{display: 'inline-flex', gap: '10px', alignItems: 'center'}}>
<button
type="button"
className="button"
onClick={e => {
e.preventDefault();
setModalOpen(true);
}}
// admin style overrides...
style={{
paddingInline: '15px',
paddingBlock: '10px',
}}
>
<FormattedMessage
description="Link label to open payment provider options modal"
defaultMessage="Configure options"
/>
</button>
{numErrors > 0 && (
<ErrorIcon
text={intl.formatMessage(
{
description:
'Payment provider validation errors icon next to button to configure options',
defaultMessage: `{numErrors, plural,
one {There is a validation error.}
other {There are {numErrors} validation errors.}
}`,
},
{numErrors}
)}
extraClassname="fa-lg icon icon--danger icon--compact icon--no-pointer"
/>
)}
</span>

<FormModal
isOpen={modalOpen}
title={modalTitle}
closeModal={() => setModalOpen(false)}
extraModifiers={modalSize ? [modalSize] : undefined}
>
<Formik
initialValues={initialFormData}
onSubmit={(values, actions) => {
onSubmit(values);
actions.setSubmitting(false);
setModalOpen(false);
}}
>
{({handleSubmit}) => (
<>
{children}

<SubmitRow>
<SubmitAction
onClick={event => {
event.preventDefault();
handleSubmit(event);
}}
/>
</SubmitRow>
</>
)}
</Formik>
</FormModal>
</>
</Field>
);
};
const OptionsConfiguration = ({numErrors, modalTitle, initialFormData, onSubmit, children}) => (
<ModalOptionsConfiguration
name="form.paymentBackendOptions"
label={
<FormattedMessage
description="Payment backend options label"
defaultMessage="Payment backend options"
/>
}
numErrors={numErrors}
modalTitle={modalTitle}
initialFormData={initialFormData}
onSubmit={onSubmit}
modalSize=""
children={children}
/>
);

OptionsConfiguration.propTypes = {
modalTitle: PropTypes.node.isRequired,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ OgoneLegacyOptionsForm.propTypes = {
schema: PropTypes.shape({
type: PropTypes.oneOf(['object']), // it's the JSON schema root, it has to be
properties: PropTypes.shape({
merchantId: {
merchantId: PropTypes.shape({
enum: PropTypes.arrayOf(PropTypes.number),
enumNames: PropTypes.arrayOf(PropTypes.string),
},
}),
}),
required: PropTypes.arrayOf(PropTypes.string),
}).isRequired,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const MerchantID = ({options}) => (
MerchantID.propTypes = {
options: PropTypes.arrayOf(
PropTypes.shape({
value: PropTypes.bool,
value: PropTypes.number,
label: PropTypes.node.isRequired,
})
).isRequired,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import PropTypes from 'prop-types';
import React, {useContext} from 'react';
import {FormattedMessage} from 'react-intl';

import OptionsConfiguration from 'components/admin/form_design/registrations/shared/OptionsConfiguration';
import Field from 'components/admin/forms/Field';
import Fieldset from 'components/admin/forms/Fieldset';
import FormRow from 'components/admin/forms/FormRow';
import {TextInput} from 'components/admin/forms/Inputs';
import ModalOptionsConfiguration from 'components/admin/forms/ModalOptionsConfiguration';
import {
ValidationErrorContext,
ValidationErrorsProvider,
Expand Down Expand Up @@ -37,7 +37,7 @@ const DemoOptionsForm = ({name, label, formData, onChange}) => {
const validationErrors = useContext(ValidationErrorContext);
const relevantErrors = filterErrors(name, validationErrors);
return (
<OptionsConfiguration
<ModalOptionsConfiguration
name={name}
label={label}
numErrors={relevantErrors.length}
Expand All @@ -56,7 +56,7 @@ const DemoOptionsForm = ({name, label, formData, onChange}) => {
<ExtraLine />
</Fieldset>
</ValidationErrorsProvider>
</OptionsConfiguration>
</ModalOptionsConfiguration>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React, {useContext} from 'react';
import {FormattedMessage} from 'react-intl';

import OptionsConfiguration from 'components/admin/form_design/registrations/shared/OptionsConfiguration';
import ModalOptionsConfiguration from 'components/admin/forms/ModalOptionsConfiguration';
import {ValidationErrorContext, filterErrors} from 'components/admin/forms/ValidationErrors';

import EmailOptionsFormFields from './EmailOptionsFormFields';
Expand All @@ -12,7 +12,7 @@ const EmailOptionsForm = ({name, label, schema, formData, onChange}) => {
const numErrors = filterErrors(name, validationErrors).length;

return (
<OptionsConfiguration
<ModalOptionsConfiguration
name={name}
label={label}
numErrors={numErrors}
Expand All @@ -30,7 +30,7 @@ const EmailOptionsForm = ({name, label, schema, formData, onChange}) => {
onSubmit={values => onChange({formData: values})}
>
<EmailOptionsFormFields name={name} schema={schema} />
</OptionsConfiguration>
</ModalOptionsConfiguration>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import PropTypes from 'prop-types';
import React, {useContext} from 'react';
import {FormattedMessage} from 'react-intl';

import OptionsConfiguration from 'components/admin/form_design/registrations/shared/OptionsConfiguration';
import Fieldset from 'components/admin/forms/Fieldset';
import ModalOptionsConfiguration from 'components/admin/forms/ModalOptionsConfiguration';
import {
ValidationErrorContext,
ValidationErrorsProvider,
Expand All @@ -16,7 +16,7 @@ const MSGraphOptionsForm = ({name, label, formData, onChange}) => {
const validationErrors = useContext(ValidationErrorContext);
const relevantErrors = filterErrors(name, validationErrors);
return (
<OptionsConfiguration
<ModalOptionsConfiguration
name={name}
label={label}
numErrors={relevantErrors.length}
Expand All @@ -36,7 +36,7 @@ const MSGraphOptionsForm = ({name, label, formData, onChange}) => {
<DriveID />
</Fieldset>
</ValidationErrorsProvider>
</OptionsConfiguration>
</ModalOptionsConfiguration>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React, {useContext} from 'react';
import {FormattedMessage} from 'react-intl';

import OptionsConfiguration from 'components/admin/form_design/registrations/shared/OptionsConfiguration';
import ModalOptionsConfiguration from 'components/admin/forms/ModalOptionsConfiguration';
import {ValidationErrorContext, filterErrors} from 'components/admin/forms/ValidationErrors';
import {getChoicesFromSchema} from 'utils/json-schema';

Expand All @@ -16,7 +16,7 @@ const ObjectsApiOptionsForm = ({index, name, label, schema, formData, onChange})
const defaultGroup = apiGroupChoices.length === 1 ? apiGroupChoices[0][0] : undefined;

return (
<OptionsConfiguration
<ModalOptionsConfiguration
name={name}
label={label}
numErrors={numErrors}
Expand All @@ -34,7 +34,7 @@ const ObjectsApiOptionsForm = ({index, name, label, schema, formData, onChange})
onSubmit={values => onChange({formData: values})}
>
<ObjectsApiOptionsFormFields index={index} name={name} apiGroupChoices={apiGroupChoices} />
</OptionsConfiguration>
</ModalOptionsConfiguration>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React, {useContext} from 'react';
import {FormattedMessage} from 'react-intl';

import OptionsConfiguration from 'components/admin/form_design/registrations/shared/OptionsConfiguration';
import ModalOptionsConfiguration from 'components/admin/forms/ModalOptionsConfiguration';
import {ValidationErrorContext, filterErrors} from 'components/admin/forms/ValidationErrors';

import StufZDSOptionsFormFields from './StufZDSOptionsFormFields';
Expand Down Expand Up @@ -33,7 +33,7 @@ const StufZDSOptionsForm = ({name, label, schema, formData, onChange}) => {
}

return (
<OptionsConfiguration
<ModalOptionsConfiguration
name={name}
label={label}
numErrors={numErrors}
Expand All @@ -47,7 +47,7 @@ const StufZDSOptionsForm = ({name, label, schema, formData, onChange}) => {
onSubmit={values => onChange({formData: values})}
>
<StufZDSOptionsFormFields name={name} schema={schema} />
</OptionsConfiguration>
</ModalOptionsConfiguration>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React, {useContext} from 'react';
import {FormattedMessage} from 'react-intl';

import OptionsConfiguration from 'components/admin/form_design/registrations/shared/OptionsConfiguration';
import ModalOptionsConfiguration from 'components/admin/forms/ModalOptionsConfiguration';
import {ValidationErrorContext, filterErrors} from 'components/admin/forms/ValidationErrors';
import {getChoicesFromSchema} from 'utils/json-schema';

Expand All @@ -22,7 +22,7 @@ const ZGWOptionsForm = ({name, label, schema, formData, onChange}) => {
const defaultGroup = apiGroupChoices.length === 1 ? apiGroupChoices[0][0] : undefined;

return (
<OptionsConfiguration
<ModalOptionsConfiguration
name={name}
label={label}
numErrors={numErrors}
Expand Down Expand Up @@ -53,7 +53,7 @@ const ZGWOptionsForm = ({name, label, schema, formData, onChange}) => {
apiGroupChoices={apiGroupChoices}
confidentialityLevelChoices={confidentialityLevelChoices}
/>
</OptionsConfiguration>
</ModalOptionsConfiguration>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@ import SubmitRow from 'components/admin/forms/SubmitRow';
import {ErrorIcon} from 'components/admin/icons';
import {FormModal} from 'components/admin/modals';

const OptionsConfiguration = ({
/**
* A generic container/wrapper for configuration options that display in a modal,
* after clicking the button to configure the options. Next to the button the number
* of validation errors is displayed.
*
* This relies on form state being managed with Formik. Pass the actual configuration
* fields as children.
*/
const ModalOptionsConfiguration = ({
name,
label,
numErrors,
Expand Down Expand Up @@ -96,7 +104,7 @@ const OptionsConfiguration = ({
);
};

OptionsConfiguration.propTypes = {
ModalOptionsConfiguration.propTypes = {
name: PropTypes.string.isRequired,
label: PropTypes.node.isRequired,
modalTitle: PropTypes.node.isRequired,
Expand All @@ -106,4 +114,4 @@ OptionsConfiguration.propTypes = {
modalSize: PropTypes.oneOf(['', 'small', 'large']),
};

export default OptionsConfiguration;
export default ModalOptionsConfiguration;

0 comments on commit f20a7f9

Please sign in to comment.