Add select custom field

[MAILPOET-2453]
This commit is contained in:
Pavel Dohnal
2019-12-18 12:11:13 +01:00
committed by Rostislav Wolný
parent 81c75fafc2
commit ea11fdf5fb
10 changed files with 273 additions and 2 deletions

View File

@@ -15,6 +15,7 @@ import * as customText from './custom_text/custom_text.jsx';
import * as customTextArea from './custom_textarea/custom_textarea.jsx';
import * as customRadio from './custom_radio/custom_radio.jsx';
import * as customCheckbox from './custom_checkbox/custom_checkbox.jsx';
import * as customSelect from './custom_select/custom_select.jsx';
const registerCustomFieldBlock = (customField) => {
const namesMap = {
@@ -34,6 +35,10 @@ const registerCustomFieldBlock = (customField) => {
name: customCheckbox.name,
settings: customCheckbox.getSettings(customField),
},
select: {
name: customSelect.name,
settings: customSelect.getSettings(customField),
},
};
if (!namesMap[customField.type]) return;

View File

@@ -16,6 +16,7 @@ const PreviewItem = ({
moveItem,
remove,
onUpdate,
onCheck,
dragFinished,
}) => {
const ref = useRef(null);
@@ -80,7 +81,7 @@ const PreviewItem = ({
>
<input
type="radio"
disabled
onChange={(event) => onCheck(value.id, event.target.value)}
key={`check-${value.id}`}
/>
<input
@@ -104,6 +105,7 @@ PreviewItem.propTypes = {
id: PropTypes.string.isRequired,
}).isRequired,
onUpdate: PropTypes.func.isRequired,
onCheck: PropTypes.func.isRequired,
moveItem: PropTypes.func.isRequired,
remove: PropTypes.func.isRequired,
index: PropTypes.number.isRequired,
@@ -142,6 +144,12 @@ const Preview = ({
update(value);
};
const onCheck = (valueId, checked) => {
const value = valuesWhileMoved.find((v) => v.id === valueId);
value.isChecked = checked;
update(value);
};
return (
<DndProvider backend={Backend}>
{valuesWhileMoved.map((value, index) => (
@@ -151,6 +159,7 @@ const Preview = ({
value={value}
moveItem={moveItem}
remove={remove}
onCheck={onCheck}
onUpdate={onUpdate}
dragFinished={() => onReorder(valuesWhileMoved)}
/>

View File

@@ -0,0 +1,44 @@
import Icon from '../custom_text/icon.jsx';
import Edit from './edit.jsx';
export const name = 'mailpoet-form/custom-select';
export function getSettings(customField) {
return {
title: customField.name,
description: '',
icon: Icon,
category: 'custom-fields',
attributes: {
label: {
type: 'string',
default: customField.name,
},
labelWithinInput: {
type: 'boolean',
default: true,
},
mandatory: {
type: 'boolean',
default: false,
},
values: {
type: 'array',
default: [],
},
customFieldId: {
type: 'string',
default: customField.id,
},
},
supports: {
html: false,
customClassName: false,
multiple: false,
},
edit: Edit,
save() {
return null;
},
};
}

View File

@@ -0,0 +1,115 @@
import React from 'react';
import {
Panel,
PanelBody,
SelectControl,
TextControl,
ToggleControl,
} from '@wordpress/components';
import { InspectorControls } from '@wordpress/block-editor';
import PropTypes from 'prop-types';
import MailPoet from 'mailpoet';
import { useDispatch, useSelect } from '@wordpress/data';
import CustomFieldSettings from '../custom_radio/custom_field_settings.jsx';
const CustomSelectEdit = ({ attributes, setAttributes }) => {
const isSaving = useSelect(
(sel) => sel('mailpoet-form-editor').getIsCustomFieldSaving(),
[]
);
const { saveCustomField } = useDispatch('mailpoet-form-editor');
const inspectorControls = (
<InspectorControls>
<Panel>
<PanelBody title={MailPoet.I18n.t('customFieldSettings')} initialOpen>
<CustomFieldSettings
mandatory={attributes.mandatory}
values={attributes.values}
isSaving={isSaving}
onSave={(params) => saveCustomField({
customFieldId: attributes.customFieldId,
data: {
params: {
required: params.mandatory ? '1' : undefined,
values: params.values.map((value) => ({
value: value.name,
is_checked: value.isChecked ? '1' : undefined,
})),
},
},
onFinish: () => setAttributes({
mandatory: params.mandatory,
values: params.values,
}),
})}
/>
</PanelBody>
</Panel>
<Panel>
<PanelBody title={MailPoet.I18n.t('formSettings')} initialOpen>
<TextControl
label={MailPoet.I18n.t('label')}
value={attributes.label}
data-automation-id="settings_custom_text_label_input"
onChange={(label) => (setAttributes({ label }))}
/>
<ToggleControl
label={MailPoet.I18n.t('displayLabelWithinInput')}
checked={attributes.labelWithinInput}
onChange={(labelWithinInput) => (setAttributes({ labelWithinInput }))}
/>
</PanelBody>
</Panel>
</InspectorControls>
);
const getLabel = () => {
if (attributes.mandatory) {
return `${attributes.label} *`;
}
return attributes.label;
};
const getInput = () => {
const options = [{
label: attributes.labelWithinInput ? getLabel() : '-',
value: null,
}];
if (Array.isArray(attributes.values) || !attributes.values.length) {
attributes.values.forEach((value) => options.push({ label: value.name }));
}
return (
<div className="mailpoet_custom_select">
<SelectControl
label={!attributes.labelWithinInput ? getLabel() : undefined}
options={options}
onChange={() => {}}
/>
</div>
);
};
return (
<>
{inspectorControls}
{getInput()}
</>
);
};
CustomSelectEdit.propTypes = {
attributes: PropTypes.shape({
label: PropTypes.string.isRequired,
values: PropTypes.arrayOf(PropTypes.shape({
name: PropTypes.string.isRequired,
isChecked: PropTypes.bool,
id: PropTypes.string.isRequired,
})),
mandatory: PropTypes.bool.isRequired,
}).isRequired,
setAttributes: PropTypes.func.isRequired,
};
export default CustomSelectEdit;

View File

@@ -20,6 +20,9 @@ const mapCustomField = (block, customFields, mappedCommonProperties) => {
if (block.name.startsWith('mailpoet-form/custom-checkbox')) {
mapped.type = 'checkbox';
}
if (block.name.startsWith('mailpoet-form/custom-select')) {
mapped.type = 'select';
}
if (has(block.attributes, 'validate')) {
mapped.params.validate = block.attributes.validate;
}

View File

@@ -10,6 +10,7 @@ const mapCustomField = (item, customFields, mappedCommonProperties) => {
textarea: 'mailpoet-form/custom-textarea',
radio: 'mailpoet-form/custom-radio',
checkbox: 'mailpoet-form/custom-checkbox',
select: 'mailpoet-form/custom-select',
};
const mapped = {
...mappedCommonProperties,