Skip to content

Commit

Permalink
Refactor: update Honorific block to only accept labels and add field …
Browse files Browse the repository at this point in the history
…validation (#7564)

Co-authored-by: Jon Waldstein <[email protected]>
Co-authored-by: Jon Waldstein <[email protected]>
  • Loading branch information
3 people authored Oct 16, 2024
1 parent 2b5a79e commit b3d615c
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 66 deletions.
14 changes: 7 additions & 7 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 @@ -69,7 +69,7 @@
"@fortawesome/free-solid-svg-icons": "^5.15.1",
"@fortawesome/react-fontawesome": "^0.1.12",
"@givewp/design-system-foundation": "^1.1.0",
"@givewp/form-builder-library": "^1.6.0",
"@givewp/form-builder-library": "^1.7.0",
"@hookform/error-message": "^2.0.1",
"@hookform/resolvers": "^2.9.10",
"@paypal/paypal-js": "^5.1.4",
Expand Down
16 changes: 13 additions & 3 deletions src/DonationForms/Actions/ConvertDonationFormBlocksToFieldsApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ protected function createNodeFromBlockWithUniqueAttributes(BlockModel $block, in
}

/**
* @unreleased updated honorific field with validation, global options, and user defaults
*
* @since 3.0.0
*/
protected function createNodeFromDonorNameBlock(BlockModel $block): Node
Expand Down Expand Up @@ -293,9 +295,17 @@ protected function createNodeFromDonorNameBlock(BlockModel $block): Node


if ($block->hasAttribute('showHonorific') && $block->getAttribute('showHonorific') === true) {
$group->getNodeByName('honorific')
->label('Title')
->options(...array_values($block->getAttribute('honorifics')));
$options = array_filter(array_values((array)$block->getAttribute('honorifics')));
if ($block->hasAttribute('useGlobalSettings') && $block->getAttribute('useGlobalSettings') === true) {
$options = give_get_option('title_prefixes', give_get_default_title_prefixes());
}

if (!empty($options)){
$group->getNodeByName('honorific')
->label(__('Title', 'give'))
->options(...$options)
->rules('max:255', 'in:' . implode(',', $options));
}
} else {
$group->remove('honorific');
}
Expand Down
2 changes: 1 addition & 1 deletion src/FormBuilder/ViewModels/FormBuilderViewModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public function storageData(int $donationFormId): array
],
'goalTypeOptions' => $this->getGoalTypeOptions(),
'goalProgressOptions' => $this->getGoalProgressOptions(),
'nameTitlePrefixes' => give_get_option('title_prefixes'),
'nameTitlePrefixes' => give_get_option('title_prefixes', array_values(give_get_default_title_prefixes())),
'isExcerptEnabled' => give_is_setting_enabled(give_get_option('forms_excerpt')),
'intlTelInputSettings' => IntlTelInput::getSettings(),
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,84 +2,89 @@ import {__} from '@wordpress/i18n';
import {BlockEditProps} from '@wordpress/blocks';
import {PanelBody, PanelRow, SelectControl, TextControl, ToggleControl} from '@wordpress/components';
import {InspectorControls} from '@wordpress/block-editor';
import {useEffect, useState} from 'react';
import {useState} from 'react';
import {OptionsPanel} from '@givewp/form-builder-library';
import type {OptionProps} from '@givewp/form-builder-library/build/OptionsPanel/types';
import {getFormBuilderWindowData} from '@givewp/form-builder/common/getWindowData';

const titleLabelTransform = (token = '') => token.charAt(0).toUpperCase() + token.slice(1);
const titleValueTransform = (token = '') => token.trim().toLowerCase();
const convertHonorificsToOptions = (honorifics: string[], defaultValue?: string) =>
honorifics?.filter(label => label.length > 0).map((honorific: string) => ({
label: titleLabelTransform(honorific),
value: titleValueTransform(honorific),
checked: defaultValue ? defaultValue === honorific : honorifics[0] === honorific
}) as OptionProps
);

const convertOptionsToHonorifics = (options: OptionProps[]) => {
const honorifics = [];
Object.values(options).forEach((option) => {
if (option.label.length > 0) {
honorifics.push(option.label);
}
});

return honorifics;
}

type Attributes = {
showHonorific: boolean;
useGlobalSettings: boolean;
honorifics: string[];
firstNameLabel: string;
firstNamePlaceholder: string;
lastNameLabel: string;
lastNamePlaceholder: string;
requireLastName: boolean;
}

export default function Edit({
attributes: {
attributes,
setAttributes
}: BlockEditProps<any>) {
const {
showHonorific,
useGlobalSettings,
honorifics,
firstNameLabel,
firstNamePlaceholder,
lastNameLabel,
lastNamePlaceholder,
requireLastName,
},
setAttributes,
}: BlockEditProps<any>) {
requireLastName
} = attributes as Attributes;
const globalHonorifics = getFormBuilderWindowData().nameTitlePrefixes;
const [selectedTitle, setSelectedTitle] = useState<string>((Object.values(honorifics)[0] as string) ?? '');
const [honorificOptions, setHonorificOptions] = useState<OptionProps[]>(
Object.values(honorifics).map((token: string) => {
return {
label: titleLabelTransform(token),
value: titleValueTransform(token),
checked: selectedTitle === token,
} as OptionProps;
})
convertHonorificsToOptions(Object.values(honorifics), selectedTitle)
);

const setOptions = (options: OptionProps[]) => {
setHonorificOptions(options);

const filtered = {};
// Filter options
Object.values(options).forEach((option) => {
Object.assign(filtered, {[option.label]: option.label});
});

setAttributes({honorifics: filtered});
setAttributes({ honorifics: convertOptionsToHonorifics(options) });
};

if (typeof useGlobalSettings === 'undefined') {
setAttributes({useGlobalSettings: true});
setAttributes({ useGlobalSettings: true });
}

useEffect(() => {
const options = !!useGlobalSettings ? getFormBuilderWindowData().nameTitlePrefixes : ['Mr', 'Ms', 'Mrs'];

setOptions(
Object.values(options).map((token: string) => {
return {
label: titleLabelTransform(token),
value: titleValueTransform(token),
checked: selectedTitle === token,
} as OptionProps;
})
);
}, [useGlobalSettings]);

return (
<>
<div
style={{
display: 'grid',
gridTemplateColumns: showHonorific && honorificOptions.length > 0 ? '1fr 2fr 2fr' : '1fr 1fr',
gap: '15px',
gap: '15px'
}}
>
{!!showHonorific && (
<SelectControl
label={__('Title', 'give')}
options={honorificOptions}
options={!useGlobalSettings ? honorificOptions : convertHonorificsToOptions(globalHonorifics)}
value={selectedTitle}
onChange={setSelectedTitle}
style={{padding: '16px 38px 16px 16px'}}
style={{ padding: '16px 38px 16px 16px' }}
/>
)}
<TextControl
Expand Down Expand Up @@ -108,24 +113,24 @@ export default function Edit({
<ToggleControl
label={__('Show Name Title Prefix', 'give')}
checked={showHonorific}
onChange={() => setAttributes({showHonorific: !showHonorific})}
onChange={() => setAttributes({ showHonorific: !showHonorific })}
help={__(
"Do you want to add a name title prefix dropdown field before the donor's first name field? This will display a dropdown with options such as Mrs, Miss, Ms, Sir, and Dr for the donor to choose from.",
'Do you want to add a name title prefix dropdown field before the donor\'s first name field? This will display a dropdown with options such as Mrs, Miss, Ms, Sir, and Dr for the donor to choose from.',
'give'
)}
/>
</PanelRow>
{!!showHonorific && (
<PanelRow>
<div style={{width: '100%'}}>
<div style={{ width: '100%' }}>
<div>
<SelectControl
label={__('Options', 'give')}
onChange={() => setAttributes({useGlobalSettings: !useGlobalSettings})}
value={useGlobalSettings}
onChange={() => setAttributes({ useGlobalSettings: !useGlobalSettings })}
value={useGlobalSettings ? 'true' : 'false'}
options={[
{label: __('Global', 'give'), value: 'true'},
{label: __('Customize', 'give'), value: 'false'},
{ label: __('Global', 'give'), value: 'true' },
{ label: __('Customize', 'give'), value: 'false' }
]}
/>
</div>
Expand All @@ -137,7 +142,7 @@ export default function Edit({
fontSize: '0.75rem',
lineHeight: '120%',
fontWeight: 400,
marginTop: '0.5rem',
marginTop: '0.5rem'
}}
>
{__(' Go to the settings to change the ')}
Expand All @@ -155,12 +160,13 @@ export default function Edit({
)}

{!!showHonorific && !useGlobalSettings && (
<div style={{marginTop: '1rem'}}>
<div style={{ marginTop: '1rem' }}>
<OptionsPanel
multiple={false}
selectable={false}
options={honorificOptions}
setOptions={setOptions}
toggleEnabled={false}
defaultControlsTooltip={__('Title Prefixes', 'give')}
/>
</div>
Expand All @@ -171,14 +177,14 @@ export default function Edit({
<TextControl
label={__('Label')}
value={firstNameLabel}
onChange={(value) => setAttributes({firstNameLabel: value})}
onChange={(value) => setAttributes({ firstNameLabel: value })}
/>
</PanelRow>
<PanelRow>
<TextControl
label={__('Placeholder')}
value={firstNamePlaceholder}
onChange={(value) => setAttributes({firstNamePlaceholder: value})}
onChange={(value) => setAttributes({ firstNamePlaceholder: value })}
/>
</PanelRow>
</PanelBody>
Expand All @@ -187,21 +193,21 @@ export default function Edit({
<TextControl
label={__('Label')}
value={lastNameLabel}
onChange={(value) => setAttributes({lastNameLabel: value})}
onChange={(value) => setAttributes({ lastNameLabel: value })}
/>
</PanelRow>
<PanelRow>
<TextControl
label={__('Placeholder')}
value={lastNamePlaceholder}
onChange={(value) => setAttributes({lastNamePlaceholder: value})}
onChange={(value) => setAttributes({ lastNamePlaceholder: value })}
/>
</PanelRow>
<PanelRow>
<ToggleControl
label={__('Required', 'give')}
checked={requireLastName}
onChange={() => setAttributes({requireLastName: !requireLastName})}
onChange={() => setAttributes({ requireLastName: !requireLastName })}
help={__('Do you want to force the Last Name field to be required?', 'give')}
/>
</PanelRow>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const settings: FieldBlock['settings'] = {
},
honorifics: {
type: 'array',
default: ['Mr', 'Ms', 'Mrs'],
default: [__('Mr.', 'give'), __('Ms.', 'give'), __('Mrs.', 'give')],
},
firstNameLabel: {
type: 'string',
Expand Down
2 changes: 1 addition & 1 deletion tests/Unit/ViewModels/FormBuilderViewModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public function testShouldReturnStorageData()
],
'goalTypeOptions' => $viewModel->getGoalTypeOptions(),
'goalProgressOptions' => $viewModel->getGoalProgressOptions(),
'nameTitlePrefixes' => give_get_option('title_prefixes'),
'nameTitlePrefixes' => give_get_option('title_prefixes', array_values(give_get_default_title_prefixes())),
'isExcerptEnabled' => give_is_setting_enabled(give_get_option('forms_excerpt')),
'intlTelInputSettings' => IntlTelInput::getSettings(),
],
Expand Down

0 comments on commit b3d615c

Please sign in to comment.