Refactor dynamic segments form to doctrind

[MAILPOET-3476]
This commit is contained in:
Pavel Dohnal
2021-03-18 13:26:14 +01:00
committed by Veljko V
parent 1e2d855138
commit dd20f066e7
2 changed files with 48 additions and 33 deletions

View File

@@ -1,9 +1,13 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import _ from 'underscore'; import _ from 'underscore';
import { Link, withRouter } from 'react-router-dom'; import {
Link,
match as matchType,
RouteComponentProps,
withRouter,
} from 'react-router-dom';
import MailPoet from 'mailpoet'; import MailPoet from 'mailpoet';
import Form from 'form/form.jsx'; import Form from 'form/form.jsx';
import PropTypes from 'prop-types';
import Background from 'common/background/background'; import Background from 'common/background/background';
import Heading from 'common/typography/heading/heading'; import Heading from 'common/typography/heading/heading';
@@ -11,12 +15,14 @@ import HideScreenOptions from 'common/hide_screen_options/hide_screen_options';
import wordpressRoleFields from './dynamic_segments_filters/wordpress_role.jsx'; import wordpressRoleFields from './dynamic_segments_filters/wordpress_role.jsx';
import emailFields from './dynamic_segments_filters/email.jsx'; import emailFields from './dynamic_segments_filters/email.jsx';
import woocommerceFields from './dynamic_segments_filters/woocommerce.jsx'; import woocommerceFields from './dynamic_segments_filters/woocommerce.jsx';
import { loadCount } from './subscribers_calculator.ts'; import { loadCount, Result } from './subscribers_calculator';
import { SubscribersCounter } from './subscribers_counter.tsx'; import { SubscribersCounter } from './subscribers_counter';
type Filters = Record<string, string>;
const messages = { const messages = {
onUpdate: () => MailPoet.Notice.success(MailPoet.I18n.t('dynamicSegmentUpdated')), onUpdate: (): void => MailPoet.Notice.success(MailPoet.I18n.t('dynamicSegmentUpdated')),
onCreate: (data) => { onCreate: (data): void => {
MailPoet.Notice.success(MailPoet.I18n.t('dynamicSegmentAdded')); MailPoet.Notice.success(MailPoet.I18n.t('dynamicSegmentAdded'));
MailPoet.trackEvent('Segments > Add new', { MailPoet.trackEvent('Segments > Add new', {
'MailPoet Free version': MailPoet.version, 'MailPoet Free version': MailPoet.version,
@@ -26,18 +32,33 @@ const messages = {
}, },
}; };
function getAvailableFilters() { function getAvailableFilters(): Filters {
const filters = { const filters: Filters = {
email: MailPoet.I18n.t('email'), email: MailPoet.I18n.t('email'),
userRole: MailPoet.I18n.t('wpUserRole'), userRole: MailPoet.I18n.t('wpUserRole'),
}; };
if (window.is_woocommerce_active) { if (MailPoet.isWoocommerceActive) {
filters.woocommerce = MailPoet.I18n.t('woocommerce'); filters.woocommerce = MailPoet.I18n.t('woocommerce');
} }
return filters; return filters;
} }
const DynamicSegmentForm = ({ match, history }) => { interface UrlProps {
id?: string;
}
interface Props {
history: RouteComponentProps['history'];
match: matchType<UrlProps>;
}
// object/any for now until we have properly typed form fields
interface FilterFieldType {
isValid: boolean;
fields: object[];
}
const DynamicSegmentForm: React.FunctionComponent<Props> = ({ match, history }) => {
const [item, setItem] = useState({ const [item, setItem] = useState({
segmentType: 'email', segmentType: 'email',
subscribersCount: { subscribersCount: {
@@ -50,7 +71,7 @@ const DynamicSegmentForm = ({ match, history }) => {
const [errors, setErrors] = useState(undefined); const [errors, setErrors] = useState(undefined);
const [isFormValid, setIsFormValid] = useState(false); const [isFormValid, setIsFormValid] = useState(false);
function getCount() { function getCount(): Promise<Result | void> {
if (isFormValid) { if (isFormValid) {
return loadCount(item); return loadCount(item);
} }
@@ -58,7 +79,7 @@ const DynamicSegmentForm = ({ match, history }) => {
return Promise.resolve(); return Promise.resolve();
} }
function countLoad() { function countLoad(): void {
item.subscribersCount = { item.subscribersCount = {
loading: true, loading: true,
count: undefined, count: undefined,
@@ -73,10 +94,15 @@ const DynamicSegmentForm = ({ match, history }) => {
item.subscribersCount.errors = response.errors; item.subscribersCount.errors = response.errors;
} }
setItem(item); setItem(item);
}, (errorResponse) => {
item.subscribersCount.loading = false;
item.subscribersCount.count = undefined;
item.subscribersCount.errors = errorResponse.errors.map((error) => error.message);
setItem(item);
}); });
} }
function getChildFields() { function getChildFields(): Promise<FilterFieldType> {
switch (item.segmentType) { switch (item.segmentType) {
case 'userRole': case 'userRole':
return wordpressRoleFields(item); return wordpressRoleFields(item);
@@ -87,11 +113,11 @@ const DynamicSegmentForm = ({ match, history }) => {
case 'woocommerce': case 'woocommerce':
return woocommerceFields(item); return woocommerceFields(item);
default: return []; default: return Promise.resolve({ fields: [], isValid: false });
} }
} }
function loadFields() { function loadFields(): void {
getChildFields() getChildFields()
.then((response) => { .then((response) => {
setChildFields(response.fields); setChildFields(response.fields);
@@ -105,12 +131,12 @@ const DynamicSegmentForm = ({ match, history }) => {
}); });
function onItemLoad(loadedData) { function onItemLoad(loadedData): void {
setItem(_.mapObject(loadedData, (val) => (_.isNull(val) ? '' : val))); setItem(_.mapObject(loadedData, (val) => (_.isNull(val) ? '' : val)));
loadFields(); loadFields();
} }
function getFields() { function getFields(): object[] {
return [ return [
{ {
name: 'name', name: 'name',
@@ -144,7 +170,7 @@ const DynamicSegmentForm = ({ match, history }) => {
]; ];
} }
function handleValueChange(e) { function handleValueChange(e): boolean {
const field = e.target.name; const field = e.target.name;
item[field] = e.target.value; item[field] = e.target.value;
@@ -154,11 +180,11 @@ const DynamicSegmentForm = ({ match, history }) => {
return true; return true;
} }
function handleSave(e) { function handleSave(e): void {
e.preventDefault(); e.preventDefault();
setErrors(undefined); setErrors(undefined);
MailPoet.Ajax.post({ MailPoet.Ajax.post({
api_version: window.mailpoet_api_version, api_version: MailPoet.apiVersion,
endpoint: 'dynamic_segments', endpoint: 'dynamic_segments',
action: 'save', action: 'save',
data: item, data: item,
@@ -190,7 +216,7 @@ const DynamicSegmentForm = ({ match, history }) => {
<Form <Form
endpoint="dynamic_segments" endpoint="dynamic_segments"
fields={getFields()} fields={getFields()}
params={getFields()} params={match.params}
messages={messages} messages={messages}
onChange={handleValueChange} onChange={handleValueChange}
onSubmit={handleSave} onSubmit={handleSave}
@@ -202,15 +228,4 @@ const DynamicSegmentForm = ({ match, history }) => {
); );
}; };
DynamicSegmentForm.propTypes = {
match: PropTypes.shape({
params: PropTypes.shape({
id: PropTypes.string,
}).isRequired,
}).isRequired,
history: PropTypes.shape({
push: PropTypes.func.isRequired,
}).isRequired,
};
export default withRouter(DynamicSegmentForm); export default withRouter(DynamicSegmentForm);

View File

@@ -23,7 +23,7 @@ interface EmailFormItem extends FormItem {
type AnyFormItem = WordpressRoleFormItem | WooCommerceFormItem | EmailFormItem; type AnyFormItem = WordpressRoleFormItem | WooCommerceFormItem | EmailFormItem;
interface Result { export interface Result {
count: number; count: number;
errors: string[]; errors: string[];
} }