Fix code style by updated eslint
[MAILPOET-3511]
This commit is contained in:
@ -31,6 +31,7 @@
|
|||||||
// PropTypes
|
// PropTypes
|
||||||
"react/prop-types": 0,
|
"react/prop-types": 0,
|
||||||
"react/jsx-props-no-spreading": 0,
|
"react/jsx-props-no-spreading": 0,
|
||||||
|
"react/require-default-props": 0,
|
||||||
// Hooks
|
// Hooks
|
||||||
"react-hooks/rules-of-hooks": "error",
|
"react-hooks/rules-of-hooks": "error",
|
||||||
"react-hooks/exhaustive-deps": "warn",
|
"react-hooks/exhaustive-deps": "warn",
|
||||||
@ -255,4 +256,3 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
/* eslint-disable react/no-unused-prop-types */
|
||||||
interface Props extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
interface Props extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
dimension?: 'extra-small' | 'small' | 'large';
|
dimension?: 'extra-small' | 'small' | 'large';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import MailPoet from 'mailpoet';
|
import MailPoet from 'mailpoet';
|
||||||
|
|
||||||
export default async function ({ endpoint, action, data }) {
|
export default async function callApi({ endpoint, action, data }) {
|
||||||
try {
|
try {
|
||||||
const res = await MailPoet.Ajax.post({
|
const res = await MailPoet.Ajax.post({
|
||||||
api_version: MailPoet.apiVersion,
|
api_version: MailPoet.apiVersion,
|
||||||
|
@ -2,7 +2,7 @@ import MailPoet from 'mailpoet';
|
|||||||
|
|
||||||
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
|
||||||
export default async function ({ name, data, timeout = 0 }) {
|
export default async function trackEvent({ name, data, timeout = 0 }) {
|
||||||
MailPoet.trackEvent(name, data);
|
MailPoet.trackEvent(name, data);
|
||||||
return sleep(timeout);
|
return sleep(timeout);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
/* eslint-disable react/no-unused-prop-types */
|
||||||
type Props = {
|
type Props = {
|
||||||
title?: string;
|
title?: string;
|
||||||
iconStart?: JSX.Element;
|
iconStart?: JSX.Element;
|
||||||
|
@ -5,5 +5,6 @@ export default function useSegmentsContext(data) {
|
|||||||
all: data.mailpoetSegments,
|
all: data.mailpoetSegments,
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
updateAll: (segments) => { data.mailpoetSegments = segments; },
|
updateAll: (segments) => { data.mailpoetSegments = segments; },
|
||||||
|
/* eslint-disable-next-line react-hooks/exhaustive-deps */
|
||||||
}), [data.mailpoetSegments]);
|
}), [data.mailpoetSegments]);
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ FormFieldCheckbox.propTypes = {
|
|||||||
onValueChange: PropTypes.func.isRequired,
|
onValueChange: PropTypes.func.isRequired,
|
||||||
field: PropTypes.shape({
|
field: PropTypes.shape({
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
values: PropTypes.object.isRequired,
|
values: PropTypes.objectOf(PropTypes.string),
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
item: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
item: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||||
};
|
};
|
||||||
|
@ -191,13 +191,13 @@ FormField.propTypes = {
|
|||||||
onValueChange: PropTypes.func,
|
onValueChange: PropTypes.func,
|
||||||
field: PropTypes.shape({
|
field: PropTypes.shape({
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
values: PropTypes.object,
|
values: PropTypes.objectOf(PropTypes.string),
|
||||||
tip: PropTypes.oneOfType([
|
tip: PropTypes.oneOfType([
|
||||||
PropTypes.array,
|
PropTypes.array,
|
||||||
PropTypes.string,
|
PropTypes.string,
|
||||||
]),
|
]),
|
||||||
label: PropTypes.string,
|
label: PropTypes.string,
|
||||||
fields: PropTypes.array,
|
fields: PropTypes.arrayOf(PropTypes.object),
|
||||||
description: PropTypes.string,
|
description: PropTypes.string,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
item: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
item: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||||
|
@ -43,7 +43,7 @@ FormFieldRadio.propTypes = {
|
|||||||
onValueChange: PropTypes.func,
|
onValueChange: PropTypes.func,
|
||||||
field: PropTypes.shape({
|
field: PropTypes.shape({
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
values: PropTypes.object,
|
values: PropTypes.objectOf(PropTypes.string),
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
item: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
item: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||||
};
|
};
|
||||||
@ -54,5 +54,4 @@ FormFieldRadio.defaultProps = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export default FormFieldRadio;
|
export default FormFieldRadio;
|
||||||
|
@ -78,11 +78,17 @@ FormFieldSelect.propTypes = {
|
|||||||
onValueChange: PropTypes.func,
|
onValueChange: PropTypes.func,
|
||||||
field: PropTypes.shape({
|
field: PropTypes.shape({
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
values: PropTypes.object,
|
values: PropTypes.objectOf(PropTypes.string),
|
||||||
placeholder: PropTypes.string,
|
placeholder: PropTypes.string,
|
||||||
filter: PropTypes.func,
|
filter: PropTypes.func,
|
||||||
sortBy: PropTypes.func,
|
sortBy: PropTypes.func,
|
||||||
validation: PropTypes.object,
|
validation: PropTypes.shape({
|
||||||
|
'data-parsley-required': PropTypes.bool,
|
||||||
|
'data-parsley-required-message': PropTypes.string,
|
||||||
|
'data-parsley-type': PropTypes.string,
|
||||||
|
'data-parsley-errors-container': PropTypes.string,
|
||||||
|
maxLength: PropTypes.number,
|
||||||
|
}),
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
item: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
item: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||||
automationId: PropTypes.string,
|
automationId: PropTypes.string,
|
||||||
@ -95,5 +101,4 @@ FormFieldSelect.defaultProps = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export default FormFieldSelect;
|
export default FormFieldSelect;
|
||||||
|
@ -346,13 +346,19 @@ Selection.propTypes = {
|
|||||||
getCount: PropTypes.func,
|
getCount: PropTypes.func,
|
||||||
getTag: PropTypes.func,
|
getTag: PropTypes.func,
|
||||||
placeholder: PropTypes.string,
|
placeholder: PropTypes.string,
|
||||||
remoteQuery: PropTypes.object,
|
remoteQuery: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||||
extendSelect2Options: PropTypes.object,
|
extendSelect2Options: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||||
multiple: PropTypes.bool,
|
multiple: PropTypes.bool,
|
||||||
forceSelect2: PropTypes.bool,
|
forceSelect2: PropTypes.bool,
|
||||||
transformChangedValue: PropTypes.func,
|
transformChangedValue: PropTypes.func,
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
validation: PropTypes.object,
|
validation: PropTypes.shape({
|
||||||
|
'data-parsley-required': PropTypes.bool,
|
||||||
|
'data-parsley-required-message': PropTypes.string,
|
||||||
|
'data-parsley-type': PropTypes.string,
|
||||||
|
'data-parsley-errors-container': PropTypes.string,
|
||||||
|
maxLength: PropTypes.number,
|
||||||
|
}),
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
item: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
item: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
@ -368,5 +374,4 @@ Selection.defaultProps = {
|
|||||||
item: undefined,
|
item: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export default Selection;
|
export default Selection;
|
||||||
|
@ -71,7 +71,13 @@ FormFieldText.propTypes = {
|
|||||||
]),
|
]),
|
||||||
disabled: PropTypes.func,
|
disabled: PropTypes.func,
|
||||||
placeholder: PropTypes.string,
|
placeholder: PropTypes.string,
|
||||||
validation: PropTypes.object,
|
validation: PropTypes.shape({
|
||||||
|
'data-parsley-required': PropTypes.bool,
|
||||||
|
'data-parsley-required-message': PropTypes.string,
|
||||||
|
'data-parsley-type': PropTypes.string,
|
||||||
|
'data-parsley-errors-container': PropTypes.string,
|
||||||
|
maxLength: PropTypes.number,
|
||||||
|
}),
|
||||||
customLabel: PropTypes.string,
|
customLabel: PropTypes.string,
|
||||||
tooltip: PropTypes.string,
|
tooltip: PropTypes.string,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
|
@ -24,7 +24,13 @@ FormFieldTextarea.propTypes = {
|
|||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
placeholder: PropTypes.string,
|
placeholder: PropTypes.string,
|
||||||
defaultValue: PropTypes.string,
|
defaultValue: PropTypes.string,
|
||||||
validation: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
validation: PropTypes.shape({
|
||||||
|
'data-parsley-required': PropTypes.bool,
|
||||||
|
'data-parsley-required-message': PropTypes.string,
|
||||||
|
'data-parsley-type': PropTypes.string,
|
||||||
|
'data-parsley-errors-container': PropTypes.string,
|
||||||
|
maxLength: PropTypes.number,
|
||||||
|
}),
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
customLabel: PropTypes.string,
|
customLabel: PropTypes.string,
|
||||||
tooltip: PropTypes.string,
|
tooltip: PropTypes.string,
|
||||||
|
@ -11,7 +11,6 @@ import MailPoet from 'mailpoet';
|
|||||||
import icon from './icon.jsx';
|
import icon from './icon.jsx';
|
||||||
import AddCustomFieldForm from './add_custom_field_form.jsx';
|
import AddCustomFieldForm from './add_custom_field_form.jsx';
|
||||||
|
|
||||||
|
|
||||||
const AddCustomField = ({ clientId }) => {
|
const AddCustomField = ({ clientId }) => {
|
||||||
const { createCustomField } = useDispatch('mailpoet-form-editor');
|
const { createCustomField } = useDispatch('mailpoet-form-editor');
|
||||||
|
|
||||||
|
@ -105,7 +105,6 @@ const CustomCheckboxEdit = ({ attributes, setAttributes, clientId }) => {
|
|||||||
return attributes.label;
|
return attributes.label;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
let checkboxLabel = getCheckboxLabel();
|
let checkboxLabel = getCheckboxLabel();
|
||||||
if (attributes.mandatory) {
|
if (attributes.mandatory) {
|
||||||
checkboxLabel += ' *';
|
checkboxLabel += ' *';
|
||||||
|
@ -46,6 +46,7 @@ const CustomHtmlEdit = ({ attributes, setAttributes, clientId }) => {
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
const [renderedContent, setRenderedContent] = useState(attributes.content);
|
const [renderedContent, setRenderedContent] = useState(attributes.content);
|
||||||
|
/* eslint-disable-next-line react-hooks/exhaustive-deps -- because we use external function */
|
||||||
const setRenderedContentDebounced = useCallback(debounce((content) => {
|
const setRenderedContentDebounced = useCallback(debounce((content) => {
|
||||||
setRenderedContent(content);
|
setRenderedContent(content);
|
||||||
}, 300), []);
|
}, 300), []);
|
||||||
|
@ -63,7 +63,6 @@ const Preview = ({
|
|||||||
updateSegment(segment);
|
updateSegment(segment);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const onDragEnd = (result) => {
|
const onDragEnd = (result) => {
|
||||||
const from = result.source.index;
|
const from = result.source.index;
|
||||||
const to = result.destination.index;
|
const to = result.destination.index;
|
||||||
|
@ -33,7 +33,6 @@ export const Settings: React.FunctionComponent = () => (
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
export const SettingsInSidebar: React.FunctionComponent = () => (
|
export const SettingsInSidebar: React.FunctionComponent = () => (
|
||||||
<div className="edit-post-sidebar mailpoet_form_editor_sidebar">
|
<div className="edit-post-sidebar mailpoet_form_editor_sidebar">
|
||||||
<SizeSettings
|
<SizeSettings
|
||||||
|
@ -25,7 +25,6 @@ const CustomCssPanel = ({ onToggle, isOpened }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
CustomCssPanel.propTypes = {
|
CustomCssPanel.propTypes = {
|
||||||
onToggle: PropTypes.func.isRequired,
|
onToggle: PropTypes.func.isRequired,
|
||||||
isOpened: PropTypes.bool.isRequired,
|
isOpened: PropTypes.bool.isRequired,
|
||||||
|
@ -321,13 +321,19 @@ Selection.propTypes = {
|
|||||||
getSearchLabel: PropTypes.func,
|
getSearchLabel: PropTypes.func,
|
||||||
getValue: PropTypes.func,
|
getValue: PropTypes.func,
|
||||||
placeholder: PropTypes.string,
|
placeholder: PropTypes.string,
|
||||||
remoteQuery: PropTypes.object,
|
remoteQuery: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||||
extendSelect2Options: PropTypes.object,
|
extendSelect2Options: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||||
multiple: PropTypes.bool,
|
multiple: PropTypes.bool,
|
||||||
forceSelect2: PropTypes.bool,
|
forceSelect2: PropTypes.bool,
|
||||||
transformChangedValue: PropTypes.func,
|
transformChangedValue: PropTypes.func,
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
validation: PropTypes.object,
|
validation: PropTypes.shape({
|
||||||
|
'data-parsley-required': PropTypes.bool,
|
||||||
|
'data-parsley-required-message': PropTypes.string,
|
||||||
|
'data-parsley-type': PropTypes.string,
|
||||||
|
'data-parsley-errors-container': PropTypes.string,
|
||||||
|
maxLength: PropTypes.number,
|
||||||
|
}),
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
item: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
item: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
@ -345,5 +351,4 @@ Selection.defaultProps = {
|
|||||||
dropDownParent: undefined,
|
dropDownParent: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export default Selection;
|
export default Selection;
|
||||||
|
@ -11,7 +11,6 @@ import Preview from 'common/preview/preview.jsx';
|
|||||||
import Modal from 'common/modal/modal';
|
import Modal from 'common/modal/modal';
|
||||||
import PlacementSettingsPanel from 'form_editor/components/form_settings/form_placement_options/settings_panel';
|
import PlacementSettingsPanel from 'form_editor/components/form_settings/form_placement_options/settings_panel';
|
||||||
|
|
||||||
|
|
||||||
const FormPreview: React.FunctionComponent = () => {
|
const FormPreview: React.FunctionComponent = () => {
|
||||||
const iframeElement = useRef(null);
|
const iframeElement = useRef(null);
|
||||||
const [iframeLoaded, setIframeLoaded] = useState(false);
|
const [iframeLoaded, setIframeLoaded] = useState(false);
|
||||||
|
@ -2,6 +2,6 @@ import '@wordpress/format-library'; // load default formats (bold, italic, ...)
|
|||||||
import { registerFormatType } from '@wordpress/rich-text';
|
import { registerFormatType } from '@wordpress/rich-text';
|
||||||
import * as FontSelectionFormat from './font_selection_format';
|
import * as FontSelectionFormat from './font_selection_format';
|
||||||
|
|
||||||
export default function (): void {
|
export default function Init(): void {
|
||||||
registerFormatType(FontSelectionFormat.name, FontSelectionFormat.settings);
|
registerFormatType(FontSelectionFormat.name, FontSelectionFormat.settings);
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,6 @@ const historyMove = (state, increment: number) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const historyUndo = (state) => (historyMove(state, 1));
|
export const historyUndo = (state) => (historyMove(state, 1));
|
||||||
|
|
||||||
export const historyRedo = (state) => (historyMove(state, -1));
|
export const historyRedo = (state) => (historyMove(state, -1));
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
function asNum(num?: string): number | undefined {
|
function asNum(num?: string): number | undefined {
|
||||||
const numI = parseInt(num, 10);
|
const numI = parseInt(num, 10);
|
||||||
if (Number.isNaN(numI)) {
|
if (Number.isNaN(numI)) {
|
||||||
|
@ -93,7 +93,6 @@ Handlebars.registerHelper('lookup', function lookupHelper(obj, field) {
|
|||||||
return obj && obj[field];
|
return obj && obj[field];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Handlebars.registerHelper('rsa_key', function rsaKeyHelper(value) {
|
Handlebars.registerHelper('rsa_key', function rsaKeyHelper(value) {
|
||||||
var lines;
|
var lines;
|
||||||
// extract all lines into an array
|
// extract all lines into an array
|
||||||
|
@ -11,18 +11,6 @@ class ListingBulkActions extends React.Component {
|
|||||||
this.handleApplyAction = this.handleApplyAction.bind(this);
|
this.handleApplyAction = this.handleApplyAction.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
getSelectedAction(actionName) {
|
|
||||||
const selectedAction = actionName;
|
|
||||||
if (selectedAction.length > 0) {
|
|
||||||
const action = this.props.bulk_actions.filter((act) => (act.name === selectedAction));
|
|
||||||
|
|
||||||
if (action.length > 0) {
|
|
||||||
return action[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleApplyAction(actionName) {
|
handleApplyAction(actionName) {
|
||||||
const action = this.getSelectedAction(actionName);
|
const action = this.getSelectedAction(actionName);
|
||||||
|
|
||||||
@ -67,6 +55,18 @@ class ListingBulkActions extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSelectedAction(actionName) {
|
||||||
|
const selectedAction = actionName;
|
||||||
|
if (selectedAction.length > 0) {
|
||||||
|
const action = this.props.bulk_actions.filter((act) => (act.name === selectedAction));
|
||||||
|
|
||||||
|
if (action.length > 0) {
|
||||||
|
return action[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.props.bulk_actions.length === 0) {
|
if (this.props.bulk_actions.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -42,17 +42,17 @@ class ListingSearch extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(e) {
|
|
||||||
this.setState({ search: e.target.value });
|
|
||||||
this.debouncedHandleSearch();
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSearch() {
|
handleSearch() {
|
||||||
this.props.onSearch(
|
this.props.onSearch(
|
||||||
this.state.search.trim()
|
this.state.search.trim()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onChange(e) {
|
||||||
|
this.setState({ search: e.target.value });
|
||||||
|
this.debouncedHandleSearch();
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.props.search === false) {
|
if (this.props.search === false) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -59,7 +59,6 @@ const Log: React.FunctionComponent<LogProps> = ({ log }: LogProps) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export type FilterType = {
|
export type FilterType = {
|
||||||
from?: string;
|
from?: string;
|
||||||
to?: string;
|
to?: string;
|
||||||
|
@ -81,7 +81,6 @@ BL.DraggableBehavior = Marionette.Behavior.extend({
|
|||||||
|
|
||||||
event.interaction.element = clone;
|
event.interaction.element = clone;
|
||||||
|
|
||||||
|
|
||||||
if (that.options.hideOriginal === true) {
|
if (that.options.hideOriginal === true) {
|
||||||
that.view.$el.addClass('mailpoet_hidden');
|
that.view.$el.addClass('mailpoet_hidden');
|
||||||
}
|
}
|
||||||
|
@ -105,5 +105,4 @@ App.on('before:start', function beforeAppStart(BeforeStartApp) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
export default Module;
|
export default Module;
|
||||||
|
@ -113,5 +113,4 @@ App.on('start', function appOnStart(Application, options) {
|
|||||||
}, this);
|
}, this);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
export default Module;
|
export default Module;
|
||||||
|
@ -95,10 +95,4 @@ export const EventOptions = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
EventOptions.defaultProps = {
|
|
||||||
eventOptions: null,
|
|
||||||
selected: [],
|
|
||||||
onValueChange: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EventOptions;
|
export default EventOptions;
|
||||||
|
@ -33,34 +33,25 @@ class EventScheduling extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
displayAfterTimeNumberField() {
|
handleChange(e, property) {
|
||||||
const { afterTimeNumberSize, event } = this.props;
|
let { value } = e.target;
|
||||||
const { afterTimeType, afterTimeNumber } = this.state;
|
if (property === 'afterTimeNumber') {
|
||||||
if (afterTimeType === 'immediate') return null;
|
value = parseInt(e.target.value, 10);
|
||||||
if (
|
value = Number.isNaN(value) ? null : value;
|
||||||
event.timeDelayValues
|
}
|
||||||
&& event.timeDelayValues[afterTimeType]
|
const data = { [property]: value };
|
||||||
&& !event.timeDelayValues[afterTimeType].displayAfterTimeNumberField
|
|
||||||
) return null;
|
|
||||||
|
|
||||||
const props = {
|
// Reset afterTimeNumber to default when switching between minutes and other types
|
||||||
field: {
|
const { afterTimeType } = this.state;
|
||||||
id: 'scheduling_time_duration',
|
if (property === 'afterTimeType' && afterTimeType !== value) {
|
||||||
name: 'scheduling_time_duration',
|
if (afterTimeType === 'minutes') {
|
||||||
defaultValue: afterTimeNumber ? afterTimeNumber.toString() : '',
|
data.afterTimeNumber = defaultAfterTimeNumber;
|
||||||
size: afterTimeNumberSize,
|
}
|
||||||
},
|
if (value === 'minutes') {
|
||||||
item: {},
|
data.afterTimeNumber = defaultAfterTimeNumberForMinutes;
|
||||||
onValueChange: _.partial(this.handleChange, _, 'afterTimeNumber'),
|
}
|
||||||
};
|
}
|
||||||
|
this.setState(data, this.propagateChange(data));
|
||||||
return (
|
|
||||||
<Text
|
|
||||||
field={props.field}
|
|
||||||
item={props.item}
|
|
||||||
onValueChange={props.onValueChange}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
displayAfterTimeTypeOptions() {
|
displayAfterTimeTypeOptions() {
|
||||||
@ -97,25 +88,34 @@ class EventScheduling extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChange(e, property) {
|
displayAfterTimeNumberField() {
|
||||||
let { value } = e.target;
|
const { afterTimeNumberSize, event } = this.props;
|
||||||
if (property === 'afterTimeNumber') {
|
const { afterTimeType, afterTimeNumber } = this.state;
|
||||||
value = parseInt(e.target.value, 10);
|
if (afterTimeType === 'immediate') return null;
|
||||||
value = Number.isNaN(value) ? null : value;
|
if (
|
||||||
}
|
event.timeDelayValues
|
||||||
const data = { [property]: value };
|
&& event.timeDelayValues[afterTimeType]
|
||||||
|
&& !event.timeDelayValues[afterTimeType].displayAfterTimeNumberField
|
||||||
|
) return null;
|
||||||
|
|
||||||
// Reset afterTimeNumber to default when switching between minutes and other types
|
const props = {
|
||||||
const { afterTimeType } = this.state;
|
field: {
|
||||||
if (property === 'afterTimeType' && afterTimeType !== value) {
|
id: 'scheduling_time_duration',
|
||||||
if (afterTimeType === 'minutes') {
|
name: 'scheduling_time_duration',
|
||||||
data.afterTimeNumber = defaultAfterTimeNumber;
|
defaultValue: afterTimeNumber ? afterTimeNumber.toString() : '',
|
||||||
}
|
size: afterTimeNumberSize,
|
||||||
if (value === 'minutes') {
|
},
|
||||||
data.afterTimeNumber = defaultAfterTimeNumberForMinutes;
|
item: {},
|
||||||
}
|
onValueChange: _.partial(this.handleChange, _, 'afterTimeNumber'),
|
||||||
}
|
};
|
||||||
this.setState(data, this.propagateChange(data));
|
|
||||||
|
return (
|
||||||
|
<Text
|
||||||
|
field={props.field}
|
||||||
|
item={props.item}
|
||||||
|
onValueChange={props.onValueChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
propagateChange(data) {
|
propagateChange(data) {
|
||||||
|
@ -50,6 +50,78 @@ class EventsConditions extends React.Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleChange(data) {
|
||||||
|
const { segment, afterTimeNumber } = this.state;
|
||||||
|
const newState = data;
|
||||||
|
|
||||||
|
if (newState.eventSlug) {
|
||||||
|
newState.event = this.getEvent(newState.eventSlug);
|
||||||
|
|
||||||
|
// keep the existing segment (if set) or set it to the first segment in the list
|
||||||
|
newState.segment = (newState.event.sendToLists)
|
||||||
|
? segment || this.constructor.getFirstSegment() : null;
|
||||||
|
|
||||||
|
// if the new event doesn't have options, reset the currently selected option value
|
||||||
|
const eventOptions = this.constructor.getEventOptions(newState.event);
|
||||||
|
newState.eventOptionValue = (eventOptions)
|
||||||
|
? this.constructor.getEventOptionsFirstValue(eventOptions) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newState.afterTimeType && newState.afterTimeType === 'immediate') {
|
||||||
|
newState.afterTimeNumber = null;
|
||||||
|
} else if (newState.afterTimeType && !newState.afterTimeNumber && !afterTimeNumber) {
|
||||||
|
newState.afterTimeNumber = defaultAfterTimeNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState(newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNextStep() {
|
||||||
|
const { history } = this.props;
|
||||||
|
const {
|
||||||
|
eventSlug, afterTimeType, afterTimeNumber, event, segment, eventOptionValue,
|
||||||
|
} = this.state;
|
||||||
|
const options = {
|
||||||
|
group: this.email.slug,
|
||||||
|
event: eventSlug,
|
||||||
|
afterTimeType,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (afterTimeNumber) options.afterTimeNumber = afterTimeNumber;
|
||||||
|
options.sendTo = (event.sendToLists) ? 'segment' : 'user';
|
||||||
|
if (segment) options.segment = segment;
|
||||||
|
if (eventOptionValue) {
|
||||||
|
options.meta = JSON.stringify({ option: eventOptionValue });
|
||||||
|
}
|
||||||
|
|
||||||
|
MailPoet.Ajax.post({
|
||||||
|
api_version: window.mailpoet_api_version,
|
||||||
|
endpoint: 'newsletters',
|
||||||
|
action: 'create',
|
||||||
|
data: {
|
||||||
|
type: 'automatic',
|
||||||
|
subject: MailPoet.I18n.t('draftNewsletterTitle'),
|
||||||
|
options,
|
||||||
|
},
|
||||||
|
}).done((response) => {
|
||||||
|
MailPoet.trackEvent('Emails > New Automatic Email Created', {
|
||||||
|
'MailPoet Premium version': window.mailpoet_premium_version,
|
||||||
|
'MailPoet Free version': window.mailpoet_version,
|
||||||
|
'Event type': options.event,
|
||||||
|
'Schedule type': options.afterTimeType,
|
||||||
|
'Schedule value': options.afterTimeNumber,
|
||||||
|
});
|
||||||
|
history.push(`/template/${response.data.id}`);
|
||||||
|
}).fail((response) => {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
this.context.notices.error(
|
||||||
|
response.errors.map((error) => <p key={error.message}>{error.message}</p>),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
getEvent(eventSlug) {
|
getEvent(eventSlug) {
|
||||||
return this.emailEvents[eventSlug];
|
return this.emailEvents[eventSlug];
|
||||||
}
|
}
|
||||||
@ -140,78 +212,6 @@ class EventsConditions extends React.Component {
|
|||||||
) : null;
|
) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChange(data) {
|
|
||||||
const { segment, afterTimeNumber } = this.state;
|
|
||||||
const newState = data;
|
|
||||||
|
|
||||||
if (newState.eventSlug) {
|
|
||||||
newState.event = this.getEvent(newState.eventSlug);
|
|
||||||
|
|
||||||
// keep the existing segment (if set) or set it to the first segment in the list
|
|
||||||
newState.segment = (newState.event.sendToLists)
|
|
||||||
? segment || this.constructor.getFirstSegment() : null;
|
|
||||||
|
|
||||||
// if the new event doesn't have options, reset the currently selected option value
|
|
||||||
const eventOptions = this.constructor.getEventOptions(newState.event);
|
|
||||||
newState.eventOptionValue = (eventOptions)
|
|
||||||
? this.constructor.getEventOptionsFirstValue(eventOptions) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newState.afterTimeType && newState.afterTimeType === 'immediate') {
|
|
||||||
newState.afterTimeNumber = null;
|
|
||||||
} else if (newState.afterTimeType && !newState.afterTimeNumber && !afterTimeNumber) {
|
|
||||||
newState.afterTimeNumber = defaultAfterTimeNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState(newState);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleNextStep() {
|
|
||||||
const { history } = this.props;
|
|
||||||
const {
|
|
||||||
eventSlug, afterTimeType, afterTimeNumber, event, segment, eventOptionValue,
|
|
||||||
} = this.state;
|
|
||||||
const options = {
|
|
||||||
group: this.email.slug,
|
|
||||||
event: eventSlug,
|
|
||||||
afterTimeType,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (afterTimeNumber) options.afterTimeNumber = afterTimeNumber;
|
|
||||||
options.sendTo = (event.sendToLists) ? 'segment' : 'user';
|
|
||||||
if (segment) options.segment = segment;
|
|
||||||
if (eventOptionValue) {
|
|
||||||
options.meta = JSON.stringify({ option: eventOptionValue });
|
|
||||||
}
|
|
||||||
|
|
||||||
MailPoet.Ajax.post({
|
|
||||||
api_version: window.mailpoet_api_version,
|
|
||||||
endpoint: 'newsletters',
|
|
||||||
action: 'create',
|
|
||||||
data: {
|
|
||||||
type: 'automatic',
|
|
||||||
subject: MailPoet.I18n.t('draftNewsletterTitle'),
|
|
||||||
options,
|
|
||||||
},
|
|
||||||
}).done((response) => {
|
|
||||||
MailPoet.trackEvent('Emails > New Automatic Email Created', {
|
|
||||||
'MailPoet Premium version': window.mailpoet_premium_version,
|
|
||||||
'MailPoet Free version': window.mailpoet_version,
|
|
||||||
'Event type': options.event,
|
|
||||||
'Schedule type': options.afterTimeType,
|
|
||||||
'Schedule value': options.afterTimeNumber,
|
|
||||||
});
|
|
||||||
history.push(`/template/${response.data.id}`);
|
|
||||||
}).fail((response) => {
|
|
||||||
if (response.errors.length > 0) {
|
|
||||||
this.context.notices.error(
|
|
||||||
response.errors.map((error) => <p key={error.message}>{error.message}</p>),
|
|
||||||
{ scroll: true }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -34,9 +34,64 @@ class SendEventConditions extends React.Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
displayHeader() {
|
handleChange(data) {
|
||||||
const { event } = this.state;
|
const { afterTimeNumber } = this.state;
|
||||||
return event.title;
|
const newState = data;
|
||||||
|
|
||||||
|
if (newState.afterTimeType && newState.afterTimeType === 'immediate') {
|
||||||
|
newState.afterTimeNumber = null;
|
||||||
|
} else if (newState.afterTimeType && !newState.afterTimeNumber && !afterTimeNumber) {
|
||||||
|
newState.afterTimeNumber = defaultAfterTimeNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState(data, this.propagateChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
displayScheduling() {
|
||||||
|
const { afterTimeNumber, afterTimeType, event } = this.state;
|
||||||
|
const props = {
|
||||||
|
item: {
|
||||||
|
afterTimeNumber,
|
||||||
|
afterTimeType,
|
||||||
|
},
|
||||||
|
event,
|
||||||
|
onValueChange: this.handleChange,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EventScheduling
|
||||||
|
item={props.item}
|
||||||
|
event={props.event}
|
||||||
|
onValueChange={props.onValueChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
displaySegments() {
|
||||||
|
const { segment } = this.state;
|
||||||
|
if (this.emailOptions.sendTo === 'user') return null;
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
field: {
|
||||||
|
id: 'segments',
|
||||||
|
forceSelect2: true,
|
||||||
|
values: this.segments,
|
||||||
|
extendSelect2Options: {
|
||||||
|
minimumResultsForSearch: Infinity,
|
||||||
|
},
|
||||||
|
selected: () => segment,
|
||||||
|
},
|
||||||
|
onValueChange: (e) => this.handleChange({ segment: e.target.value }),
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="event-segment-selection">
|
||||||
|
<Selection
|
||||||
|
field={props.field}
|
||||||
|
onValueChange={props.onValueChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
displayEventOptions() {
|
displayEventOptions() {
|
||||||
@ -75,64 +130,9 @@ class SendEventConditions extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
displaySegments() {
|
displayHeader() {
|
||||||
const { segment } = this.state;
|
const { event } = this.state;
|
||||||
if (this.emailOptions.sendTo === 'user') return null;
|
return event.title;
|
||||||
|
|
||||||
const props = {
|
|
||||||
field: {
|
|
||||||
id: 'segments',
|
|
||||||
forceSelect2: true,
|
|
||||||
values: this.segments,
|
|
||||||
extendSelect2Options: {
|
|
||||||
minimumResultsForSearch: Infinity,
|
|
||||||
},
|
|
||||||
selected: () => segment,
|
|
||||||
},
|
|
||||||
onValueChange: (e) => this.handleChange({ segment: e.target.value }),
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="event-segment-selection">
|
|
||||||
<Selection
|
|
||||||
field={props.field}
|
|
||||||
onValueChange={props.onValueChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
displayScheduling() {
|
|
||||||
const { afterTimeNumber, afterTimeType, event } = this.state;
|
|
||||||
const props = {
|
|
||||||
item: {
|
|
||||||
afterTimeNumber,
|
|
||||||
afterTimeType,
|
|
||||||
},
|
|
||||||
event,
|
|
||||||
onValueChange: this.handleChange,
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<EventScheduling
|
|
||||||
item={props.item}
|
|
||||||
event={props.event}
|
|
||||||
onValueChange={props.onValueChange}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleChange(data) {
|
|
||||||
const { afterTimeNumber } = this.state;
|
|
||||||
const newState = data;
|
|
||||||
|
|
||||||
if (newState.afterTimeType && newState.afterTimeType === 'immediate') {
|
|
||||||
newState.afterTimeNumber = null;
|
|
||||||
} else if (newState.afterTimeType && !newState.afterTimeNumber && !afterTimeNumber) {
|
|
||||||
newState.afterTimeNumber = defaultAfterTimeNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState(data, this.propagateChange);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
propagateChange() {
|
propagateChange() {
|
||||||
|
@ -274,7 +274,6 @@ class NewsletterListNotification extends React.Component {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
{ sendingToSegments }
|
{ sendingToSegments }
|
||||||
|
@ -201,7 +201,9 @@ NewsletterListNotificationHistory.propTypes = {
|
|||||||
pathname: PropTypes.string,
|
pathname: PropTypes.string,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
match: PropTypes.shape({
|
match: PropTypes.shape({
|
||||||
params: PropTypes.object,
|
params: PropTypes.shape({
|
||||||
|
id: PropTypes.node,
|
||||||
|
}).isRequired,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ const QueuePropType = PropTypes.shape({
|
|||||||
|
|
||||||
const NewsletterPropType = PropTypes.shape({
|
const NewsletterPropType = PropTypes.shape({
|
||||||
id: PropTypes.number.isRequired,
|
id: PropTypes.number.isRequired,
|
||||||
|
sent_at: PropTypes.string,
|
||||||
|
status: PropTypes.string.isRequired,
|
||||||
queue: PropTypes.oneOfType([
|
queue: PropTypes.oneOfType([
|
||||||
QueuePropType,
|
QueuePropType,
|
||||||
PropTypes.bool,
|
PropTypes.bool,
|
||||||
|
@ -138,7 +138,13 @@ DateText.propTypes = {
|
|||||||
storageFormat: PropTypes.string.isRequired,
|
storageFormat: PropTypes.string.isRequired,
|
||||||
value: PropTypes.string.isRequired,
|
value: PropTypes.string.isRequired,
|
||||||
disabled: PropTypes.bool.isRequired,
|
disabled: PropTypes.bool.isRequired,
|
||||||
validation: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
validation: PropTypes.shape({
|
||||||
|
'data-parsley-required': PropTypes.bool,
|
||||||
|
'data-parsley-required-message': PropTypes.string,
|
||||||
|
'data-parsley-type': PropTypes.string,
|
||||||
|
'data-parsley-errors-container': PropTypes.string,
|
||||||
|
maxLength: PropTypes.number,
|
||||||
|
}).isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
DateText.defaultProps = {
|
DateText.defaultProps = {
|
||||||
|
@ -12,6 +12,31 @@ class ImportTemplate extends React.Component {
|
|||||||
this.handleSubmit = this.handleSubmit.bind(this);
|
this.handleSubmit = this.handleSubmit.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleSubmit(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (_.size(this.fileRef.current.files) <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const file = _.first(this.fileRef.current.files);
|
||||||
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
reader.onload = (evt) => {
|
||||||
|
try {
|
||||||
|
this.saveTemplate(JSON.parse(evt.target.result));
|
||||||
|
MailPoet.trackEvent('Emails > Template imported', {
|
||||||
|
'MailPoet Free version': window.mailpoet_version,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
this.context.notices.error(<p>{MailPoet.I18n.t('templateFileMalformedError')}</p>);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.readAsText(file);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
saveTemplate(saveTemplate) {
|
saveTemplate(saveTemplate) {
|
||||||
const template = saveTemplate;
|
const template = saveTemplate;
|
||||||
const { beforeImport, afterImport } = this.props;
|
const { beforeImport, afterImport } = this.props;
|
||||||
@ -41,7 +66,6 @@ class ImportTemplate extends React.Component {
|
|||||||
|
|
||||||
template.categories = JSON.stringify(template.categories);
|
template.categories = JSON.stringify(template.categories);
|
||||||
|
|
||||||
|
|
||||||
beforeImport();
|
beforeImport();
|
||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
api_version: window.mailpoet_api_version,
|
api_version: window.mailpoet_api_version,
|
||||||
@ -61,31 +85,6 @@ class ImportTemplate extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmit(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
if (_.size(this.fileRef.current.files) <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const file = _.first(this.fileRef.current.files);
|
|
||||||
const reader = new FileReader();
|
|
||||||
|
|
||||||
reader.onload = (evt) => {
|
|
||||||
try {
|
|
||||||
this.saveTemplate(JSON.parse(evt.target.result));
|
|
||||||
MailPoet.trackEvent('Emails > Template imported', {
|
|
||||||
'MailPoet Free version': window.mailpoet_version,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
this.context.notices.error(<p>{MailPoet.I18n.t('templateFileMalformedError')}</p>);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
reader.readAsText(file);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -77,7 +77,6 @@ const NewsletterTypes: React.FunctionComponent<Props> = ({
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const renderType = (type): JSX.Element => {
|
const renderType = (type): JSX.Element => {
|
||||||
const badgeClassName = (window.mailpoet_is_new_user === true) ? 'mailpoet_badge mailpoet_badge_video' : 'mailpoet_badge mailpoet_badge_video mailpoet_badge_video_grey';
|
const badgeClassName = (window.mailpoet_is_new_user === true) ? 'mailpoet_badge mailpoet_badge_video' : 'mailpoet_badge mailpoet_badge_video mailpoet_badge_video_grey';
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ jQuery(($) => {
|
|||||||
setTimeout(renderCaptcha, 400, element, 1);
|
setTimeout(renderCaptcha, 400, element, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param form jQuery object of form form.mailpoet_form
|
* @param form jQuery object of form form.mailpoet_form
|
||||||
*/
|
*/
|
||||||
|
@ -59,6 +59,45 @@ class DynamicSegmentForm extends React.Component {
|
|||||||
this.onItemLoad = this.onItemLoad.bind(this);
|
this.onItemLoad = this.onItemLoad.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleValueChange(e) {
|
||||||
|
const { item } = this.state;
|
||||||
|
const field = e.target.name;
|
||||||
|
|
||||||
|
item[field] = e.target.value;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
item,
|
||||||
|
});
|
||||||
|
this.loadFields();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSave(e) {
|
||||||
|
const { item } = this.state;
|
||||||
|
const { history, match } = this.props;
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
this.setState({ errors: undefined });
|
||||||
|
MailPoet.Ajax.post({
|
||||||
|
api_version: window.mailpoet_api_version,
|
||||||
|
endpoint: 'dynamic_segments',
|
||||||
|
action: 'save',
|
||||||
|
data: item,
|
||||||
|
}).done(() => {
|
||||||
|
history.push('/segments');
|
||||||
|
|
||||||
|
if (match.params.id !== undefined) {
|
||||||
|
messages.onUpdate();
|
||||||
|
} else {
|
||||||
|
messages.onCreate(item);
|
||||||
|
}
|
||||||
|
}).fail((response) => {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
this.setState({ errors: response.errors });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onItemLoad(loadedData) {
|
onItemLoad(loadedData) {
|
||||||
const item = _.mapObject(loadedData, (val) => (_.isNull(val) ? '' : val));
|
const item = _.mapObject(loadedData, (val) => (_.isNull(val) ? '' : val));
|
||||||
this.setState({ item }, this.loadFields);
|
this.setState({ item }, this.loadFields);
|
||||||
@ -165,45 +204,6 @@ class DynamicSegmentForm extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleValueChange(e) {
|
|
||||||
const { item } = this.state;
|
|
||||||
const field = e.target.name;
|
|
||||||
|
|
||||||
item[field] = e.target.value;
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
item,
|
|
||||||
});
|
|
||||||
this.loadFields();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSave(e) {
|
|
||||||
const { item } = this.state;
|
|
||||||
const { history, match } = this.props;
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
this.setState({ errors: undefined });
|
|
||||||
MailPoet.Ajax.post({
|
|
||||||
api_version: window.mailpoet_api_version,
|
|
||||||
endpoint: 'dynamic_segments',
|
|
||||||
action: 'save',
|
|
||||||
data: item,
|
|
||||||
}).done(() => {
|
|
||||||
history.push('/segments');
|
|
||||||
|
|
||||||
if (match.params.id !== undefined) {
|
|
||||||
messages.onUpdate();
|
|
||||||
} else {
|
|
||||||
messages.onCreate(item);
|
|
||||||
}
|
|
||||||
}).fail((response) => {
|
|
||||||
if (response.errors.length > 0) {
|
|
||||||
this.setState({ errors: response.errors });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const fields = this.getFields();
|
const fields = this.getFields();
|
||||||
const { match } = this.props;
|
const { match } = this.props;
|
||||||
|
@ -30,7 +30,6 @@ const MssNotActiveMessage = ({ activationCallback }: MssNotActiveMessageProps) =
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
keyMessage?: string;
|
keyMessage?: string;
|
||||||
activationCallback: () => void;
|
activationCallback: () => void;
|
||||||
|
@ -33,7 +33,7 @@ const NotValidMessage = ({ message }: NotValidMessageProps) => (
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
NotValidMessage.defaultProps = {
|
NotValidMessage.defaultProps = {
|
||||||
keyMessage: '',
|
message: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -15,5 +15,4 @@ export type Tail<T extends any[]> =
|
|||||||
export type ExcludeFirstParam<F extends ((...args: any[]) => any)> =
|
export type ExcludeFirstParam<F extends ((...args: any[]) => any)> =
|
||||||
(...args: Tail<Parameters<F>>) => ReturnType<F>
|
(...args: Tail<Parameters<F>>) => ReturnType<F>
|
||||||
|
|
||||||
|
|
||||||
export type ValueAndSetter<T> = [T, (value: T) => any]
|
export type ValueAndSetter<T> = [T, (value: T) => any]
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import jQuery from 'jquery';
|
import jQuery from 'jquery';
|
||||||
import MailPoet from 'mailpoet';
|
import MailPoet from 'mailpoet';
|
||||||
|
|
||||||
|
|
||||||
export default (onCreateSegment) => {
|
export default (onCreateSegment) => {
|
||||||
MailPoet.Modal.popup({
|
MailPoet.Modal.popup({
|
||||||
title: MailPoet.I18n.t('addNewList'),
|
title: MailPoet.I18n.t('addNewList'),
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
export default (subscribers, header) => {
|
export default (subscribers, header) => {
|
||||||
const displayedColumns = [];
|
const displayedColumns = [];
|
||||||
const displayedColumnsIds = [];
|
const displayedColumnsIds = [];
|
||||||
|
@ -53,5 +53,4 @@ LastSentQuestion.propTypes = {
|
|||||||
onSubmit: PropTypes.func.isRequired,
|
onSubmit: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export default LastSentQuestion;
|
export default LastSentQuestion;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
const notFreeAddress = ({ name, address }) => ({
|
const notFreeAddress = ({ name, address }) => ({
|
||||||
sender: { name, address },
|
sender: { name, address },
|
||||||
reply_to: { name, address },
|
reply_to: { name, address },
|
||||||
|
@ -24,7 +24,6 @@ export const Controls = (props) => (
|
|||||||
href={props.mailpoetAccountUrl}
|
href={props.mailpoetAccountUrl}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
|
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
window.open(props.mailpoetAccountUrl);
|
window.open(props.mailpoetAccountUrl);
|
||||||
|
@ -33,7 +33,6 @@ const data = {
|
|||||||
deleted_at: null,
|
deleted_at: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
describe('Form Data Load Mapper', () => {
|
describe('Form Data Load Mapper', () => {
|
||||||
it('Returns ID', () => {
|
it('Returns ID', () => {
|
||||||
expect(map(data)).to.have.property('id', '1');
|
expect(map(data)).to.have.property('id', '1');
|
||||||
|
@ -33,7 +33,6 @@ const data = {
|
|||||||
deleted_at: null,
|
deleted_at: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
describe('Form Data Save Mapper', () => {
|
describe('Form Data Save Mapper', () => {
|
||||||
it('Returns ID', () => {
|
it('Returns ID', () => {
|
||||||
expect(map(data)).to.have.property('id', '1');
|
expect(map(data)).to.have.property('id', '1');
|
||||||
@ -50,7 +49,7 @@ describe('Form Data Save Mapper', () => {
|
|||||||
it('Returns dates', () => {
|
it('Returns dates', () => {
|
||||||
expect(map(data)).to.have.property('created_at', '2020-01-15 07:39:15');
|
expect(map(data)).to.have.property('created_at', '2020-01-15 07:39:15');
|
||||||
expect(map(data)).to.have.property('updated_at', '2020-01-28 10:28:02');
|
expect(map(data)).to.have.property('updated_at', '2020-01-28 10:28:02');
|
||||||
expect(map(data)).to.have.property('deleted_at').that.is.null;
|
expect(map(data)).to.have.property('deleted_at').that.is.null;// eslint-disable-line no-unused-expressions
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Settings', () => {
|
describe('Settings', () => {
|
||||||
|
@ -33,7 +33,6 @@ global.$ = jQuery;
|
|||||||
global.jQuery = jQuery;
|
global.jQuery = jQuery;
|
||||||
global.window.jQuery = jQuery;
|
global.window.jQuery = jQuery;
|
||||||
|
|
||||||
|
|
||||||
testHelpers.loadScript('tests/javascript_newsletter_editor/testBundles/vendor.js', global.window);
|
testHelpers.loadScript('tests/javascript_newsletter_editor/testBundles/vendor.js', global.window);
|
||||||
const Handlebars = global.window.Handlebars;
|
const Handlebars = global.window.Handlebars;
|
||||||
global.Handlebars = global.window.Handlebars;
|
global.Handlebars = global.window.Handlebars;
|
||||||
@ -186,7 +185,6 @@ testHelpers.loadTemplate('components/sidebar/layout.hbs', window, { id: 'newslet
|
|||||||
testHelpers.loadTemplate('components/sidebar/preview.hbs', window, { id: 'newsletter_editor_template_sidebar_preview' });
|
testHelpers.loadTemplate('components/sidebar/preview.hbs', window, { id: 'newsletter_editor_template_sidebar_preview' });
|
||||||
testHelpers.loadTemplate('components/sidebar/styles.hbs', window, { id: 'newsletter_editor_template_sidebar_styles' });
|
testHelpers.loadTemplate('components/sidebar/styles.hbs', window, { id: 'newsletter_editor_template_sidebar_styles' });
|
||||||
|
|
||||||
|
|
||||||
global.templates = {
|
global.templates = {
|
||||||
styles: Handlebars.compile(jQuery('#newsletter_editor_template_styles').html()),
|
styles: Handlebars.compile(jQuery('#newsletter_editor_template_styles').html()),
|
||||||
save: Handlebars.compile(jQuery('#newsletter_editor_template_save').html()),
|
save: Handlebars.compile(jQuery('#newsletter_editor_template_save').html()),
|
||||||
|
Reference in New Issue
Block a user