Move default props to default parameters - simple cases
React throws a deprecation warning for defaultProps. This commit refactors default props to default values in easy-to-fix cases. [MAILPOET-6108]
This commit is contained in:
committed by
Jan Lysý
parent
b19c30d203
commit
a3514377c8
@ -4,25 +4,31 @@ import ReactDOMServer from 'react-dom/server';
|
||||
|
||||
import { MailPoet } from 'mailpoet';
|
||||
|
||||
function ConfirmAlert(props) {
|
||||
function ConfirmAlert({
|
||||
message,
|
||||
onConfirm,
|
||||
title = __('Confirm to proceed', 'mailpoet'),
|
||||
cancelLabel = __('Cancel', 'mailpoet'),
|
||||
confirmLabel = __('Confirm', 'mailpoet'),
|
||||
}) {
|
||||
MailPoet.Modal.popup({
|
||||
title: props.title,
|
||||
title,
|
||||
template: ReactDOMServer.renderToString(
|
||||
<>
|
||||
<p>{props.message}</p>
|
||||
<p>{message}</p>
|
||||
<button
|
||||
id="mailpoet_alert_cancel"
|
||||
className="button button-secondary"
|
||||
type="button"
|
||||
>
|
||||
{props.cancelLabel}
|
||||
{cancelLabel}
|
||||
</button>
|
||||
<button
|
||||
id="mailpoet_alert_confirm"
|
||||
className="button button-primary"
|
||||
type="submit"
|
||||
>
|
||||
{props.confirmLabel}
|
||||
{confirmLabel}
|
||||
</button>
|
||||
</>,
|
||||
),
|
||||
@ -31,7 +37,7 @@ function ConfirmAlert(props) {
|
||||
.getElementById('mailpoet_alert_confirm')
|
||||
.addEventListener('click', () => {
|
||||
MailPoet.Modal.close();
|
||||
props.onConfirm();
|
||||
onConfirm();
|
||||
});
|
||||
|
||||
document
|
||||
@ -50,12 +56,6 @@ ConfirmAlert.propTypes = {
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
ConfirmAlert.defaultProps = {
|
||||
title: __('Confirm to proceed', 'mailpoet'),
|
||||
cancelLabel: __('Cancel', 'mailpoet'),
|
||||
confirmLabel: __('Confirm', 'mailpoet'),
|
||||
};
|
||||
|
||||
export function confirmAlert(props) {
|
||||
// the below render is only to invoke proptypes on ConfirmAlert
|
||||
ReactDOMServer.renderToString(
|
||||
|
@ -1,10 +1,10 @@
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
function KeyValueTable(props) {
|
||||
function KeyValueTable({ rows, max_width: maxWidth = 'auto' }) {
|
||||
return (
|
||||
<table className="widefat fixed" style={{ maxWidth: props.max_width }}>
|
||||
<table className="widefat fixed" style={{ maxWidth }}>
|
||||
<tbody>
|
||||
{props.rows.map((row) => (
|
||||
{rows.map((row) => (
|
||||
<tr key={`row_${row.key}`}>
|
||||
<td className="row-title">{row.key}</td>
|
||||
<td>{row.value}</td>
|
||||
@ -29,8 +29,4 @@ KeyValueTable.propTypes = {
|
||||
).isRequired,
|
||||
};
|
||||
|
||||
KeyValueTable.defaultProps = {
|
||||
max_width: 'auto',
|
||||
};
|
||||
|
||||
export { KeyValueTable };
|
||||
|
@ -18,7 +18,7 @@ function Badge({
|
||||
tooltipId,
|
||||
tooltipPlace,
|
||||
type,
|
||||
isInverted,
|
||||
isInverted = true,
|
||||
}: BadgeProps) {
|
||||
return (
|
||||
<span>
|
||||
@ -38,8 +38,4 @@ function Badge({
|
||||
);
|
||||
}
|
||||
|
||||
Badge.defaultProps = {
|
||||
isInverted: true,
|
||||
};
|
||||
|
||||
export { Badge };
|
||||
|
@ -69,6 +69,7 @@ export const getBadgeType = (statName, rate) => {
|
||||
};
|
||||
|
||||
function StatsBadge(props: StatsBadgeProps) {
|
||||
const { isInverted = true } = props;
|
||||
const badges = {
|
||||
excellent: {
|
||||
name: __('Excellent', 'mailpoet'),
|
||||
@ -119,7 +120,7 @@ function StatsBadge(props: StatsBadgeProps) {
|
||||
|
||||
const content = (
|
||||
<Badge
|
||||
isInverted={props.isInverted}
|
||||
isInverted={isInverted}
|
||||
type={badgeType}
|
||||
name={badge.name}
|
||||
tooltip={tooltipText}
|
||||
@ -131,8 +132,4 @@ function StatsBadge(props: StatsBadgeProps) {
|
||||
return content;
|
||||
}
|
||||
|
||||
StatsBadge.defaultProps = {
|
||||
isInverted: true,
|
||||
};
|
||||
|
||||
export { StatsBadge };
|
||||
|
@ -20,7 +20,7 @@ function MssActiveMessage({ canUseSuccessClass }: MssActiveMessageProps) {
|
||||
|
||||
type NotValidMessageProps = { message?: string };
|
||||
|
||||
function NotValidMessage({ message }: NotValidMessageProps) {
|
||||
function NotValidMessage({ message = '' }: NotValidMessageProps) {
|
||||
return (
|
||||
<div className="mailpoet_error">
|
||||
{message
|
||||
@ -45,10 +45,6 @@ function NotValidMessage({ message }: NotValidMessageProps) {
|
||||
);
|
||||
}
|
||||
|
||||
NotValidMessage.defaultProps = {
|
||||
message: '',
|
||||
};
|
||||
|
||||
type MssNotActiveMessageProps = { activationCallback?: () => void };
|
||||
|
||||
function MssNotActiveMessage({ activationCallback }: MssNotActiveMessageProps) {
|
||||
@ -74,19 +70,21 @@ type Props = {
|
||||
canUseSuccessClass: boolean;
|
||||
};
|
||||
|
||||
export function MssMessages(props: Props) {
|
||||
export function MssMessages({
|
||||
activationCallback,
|
||||
canUseSuccessClass,
|
||||
keyMessage = '',
|
||||
}: Props) {
|
||||
const { mssStatus, mssAccessRestriction } = useSelector(
|
||||
'getKeyActivationState',
|
||||
)();
|
||||
switch (mssStatus) {
|
||||
case MssStatus.VALID_MSS_ACTIVE:
|
||||
return <MssActiveMessage canUseSuccessClass={props.canUseSuccessClass} />;
|
||||
return <MssActiveMessage canUseSuccessClass={canUseSuccessClass} />;
|
||||
case MssStatus.VALID_MSS_NOT_ACTIVE:
|
||||
return (
|
||||
<MssNotActiveMessage activationCallback={props.activationCallback} />
|
||||
);
|
||||
return <MssNotActiveMessage activationCallback={activationCallback} />;
|
||||
case MssStatus.INVALID:
|
||||
return <NotValidMessage message={props.keyMessage} />;
|
||||
return <NotValidMessage message={keyMessage} />;
|
||||
|
||||
case MssStatus.VALID_UNDERPRIVILEGED:
|
||||
if (
|
||||
@ -101,7 +99,3 @@ export function MssMessages(props: Props) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
MssMessages.defaultProps = {
|
||||
keyMessage: '',
|
||||
};
|
||||
|
@ -65,7 +65,7 @@ function PremiumMessageWithModal(props: PremiumMessageProps) {
|
||||
|
||||
type NotValidMessageProps = { message?: string };
|
||||
|
||||
function NotValidMessage({ message }: NotValidMessageProps) {
|
||||
function NotValidMessage({ message = '' }: NotValidMessageProps) {
|
||||
return (
|
||||
<div className="mailpoet_error">
|
||||
{message
|
||||
@ -87,21 +87,17 @@ function NotValidMessage({ message }: NotValidMessageProps) {
|
||||
);
|
||||
}
|
||||
|
||||
NotValidMessage.defaultProps = {
|
||||
message: '',
|
||||
};
|
||||
|
||||
type Props = {
|
||||
keyMessage?: string;
|
||||
canUseSuccessClass: boolean;
|
||||
};
|
||||
|
||||
function PremiumMessages(props: Props) {
|
||||
function PremiumMessages({ canUseSuccessClass, keyMessage = '' }: Props) {
|
||||
const { premiumStatus: status } = useSelector('getKeyActivationState')();
|
||||
|
||||
switch (status) {
|
||||
case PremiumStatus.VALID_PREMIUM_PLUGIN_ACTIVE:
|
||||
return <ActiveMessage canUseSuccessClass={props.canUseSuccessClass} />;
|
||||
return <ActiveMessage canUseSuccessClass={canUseSuccessClass} />;
|
||||
case PremiumStatus.VALID_PREMIUM_PLUGIN_NOT_INSTALLED:
|
||||
return (
|
||||
<PremiumMessageWithModal
|
||||
@ -132,14 +128,10 @@ function PremiumMessages(props: Props) {
|
||||
/>
|
||||
);
|
||||
case PremiumStatus.INVALID:
|
||||
return <NotValidMessage message={props.keyMessage} />;
|
||||
return <NotValidMessage message={keyMessage} />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
PremiumMessages.defaultProps = {
|
||||
keyMessage: '',
|
||||
};
|
||||
|
||||
export { PremiumMessages, PremiumMessageWithModal };
|
||||
|
@ -5,7 +5,11 @@ import classnames from 'classnames';
|
||||
import { MobileIcon } from './mobile-icon';
|
||||
import { DesktopIcon } from './desktop-icon';
|
||||
|
||||
function Preview({ children, onDisplayTypeChange, selectedDisplayType }) {
|
||||
function Preview({
|
||||
children,
|
||||
onDisplayTypeChange = (type) => type,
|
||||
selectedDisplayType = 'desktop',
|
||||
}) {
|
||||
const [displayType, setDisplayType] = useState(selectedDisplayType);
|
||||
const changeType = (type) => {
|
||||
setDisplayType(type);
|
||||
@ -76,9 +80,5 @@ Preview.propTypes = {
|
||||
selectedDisplayType: PropTypes.string,
|
||||
};
|
||||
|
||||
Preview.defaultProps = {
|
||||
onDisplayTypeChange: () => {},
|
||||
selectedDisplayType: 'desktop',
|
||||
};
|
||||
Preview.displayName = 'FormEditorPreview';
|
||||
export { Preview };
|
||||
|
@ -1,12 +1,17 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
function PrintBoolean(props) {
|
||||
function PrintBoolean({
|
||||
truthy = __('Yes', 'mailpoet'),
|
||||
falsy = __('No', 'mailpoet'),
|
||||
unknown = __('Unknown', 'mailpoet'),
|
||||
children = null,
|
||||
}) {
|
||||
return (
|
||||
<span>
|
||||
{(props.children === true && props.truthy) ||
|
||||
(props.children === false && props.falsy) ||
|
||||
props.unknown}
|
||||
{(children === true && truthy) ||
|
||||
(children === false && falsy) ||
|
||||
unknown}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
@ -18,11 +23,4 @@ PrintBoolean.propTypes = {
|
||||
children: PropTypes.bool,
|
||||
};
|
||||
|
||||
PrintBoolean.defaultProps = {
|
||||
truthy: __('Yes', 'mailpoet'),
|
||||
falsy: __('No', 'mailpoet'),
|
||||
unknown: __('Unknown', 'mailpoet'),
|
||||
children: null,
|
||||
};
|
||||
|
||||
export { PrintBoolean };
|
||||
|
@ -88,7 +88,10 @@ type Props = {
|
||||
setAuthorizedAddress?: (address: string) => void;
|
||||
};
|
||||
|
||||
function SetFromAddressModal({ onRequestClose, setAuthorizedAddress }: Props) {
|
||||
function SetFromAddressModal({
|
||||
onRequestClose,
|
||||
setAuthorizedAddress = noop,
|
||||
}: Props) {
|
||||
const [address, setAddress] = useState<string>();
|
||||
const [showAuthorizedEmailModal, setShowAuthorizedEmailModal] =
|
||||
useState(false);
|
||||
@ -230,8 +233,4 @@ function SetFromAddressModal({ onRequestClose, setAuthorizedAddress }: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
SetFromAddressModal.defaultProps = {
|
||||
setAuthorizedAddress: noop,
|
||||
};
|
||||
|
||||
export { SetFromAddressModal };
|
||||
|
@ -10,7 +10,7 @@ type Props = {
|
||||
doneCallback?: (step: string) => void;
|
||||
};
|
||||
|
||||
function StepsComponent({ count, current, titles, doneCallback }: Props) {
|
||||
function StepsComponent({ count, current, doneCallback, titles = [] }: Props) {
|
||||
return (
|
||||
<div className="mailpoet-steps">
|
||||
<ContentWrapperFix />
|
||||
@ -54,9 +54,6 @@ function StepsComponent({ count, current, titles, doneCallback }: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
StepsComponent.defaultProps = {
|
||||
titles: [],
|
||||
};
|
||||
StepsComponent.displayName = 'StepsComponent';
|
||||
const Steps = withBoundary(StepsComponent);
|
||||
export { Steps };
|
||||
|
@ -12,15 +12,15 @@ import { MailPoet } from 'mailpoet';
|
||||
import { CustomFieldDelete } from '../custom-field-delete.jsx';
|
||||
|
||||
function CustomFieldSettings({
|
||||
label,
|
||||
mandatory,
|
||||
isSaving,
|
||||
onSave,
|
||||
isChecked,
|
||||
checkboxLabel,
|
||||
isDeleting,
|
||||
onCustomFieldDelete,
|
||||
onChange,
|
||||
label = '',
|
||||
mandatory = false,
|
||||
isSaving = false,
|
||||
onSave = null,
|
||||
isChecked = false,
|
||||
checkboxLabel = '',
|
||||
isDeleting = false,
|
||||
onCustomFieldDelete = null,
|
||||
onChange = () => {},
|
||||
}) {
|
||||
const [localLabel, setLocalLabel] = useState(label);
|
||||
const [localMandatory, setLocalMandatory] = useState(mandatory);
|
||||
@ -108,16 +108,4 @@ CustomFieldSettings.propTypes = {
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
CustomFieldSettings.defaultProps = {
|
||||
label: '',
|
||||
mandatory: false,
|
||||
onSave: null,
|
||||
isSaving: false,
|
||||
isChecked: false,
|
||||
checkboxLabel: '',
|
||||
isDeleting: false,
|
||||
onCustomFieldDelete: null,
|
||||
onChange: () => {},
|
||||
};
|
||||
|
||||
export { CustomFieldSettings };
|
||||
|
@ -11,17 +11,17 @@ import { MailPoet } from 'mailpoet';
|
||||
import { CustomFieldDelete } from '../custom-field-delete.jsx';
|
||||
|
||||
function CustomFieldSettings({
|
||||
label,
|
||||
mandatory,
|
||||
dateType,
|
||||
dateFormat,
|
||||
defaultToday,
|
||||
dateSettings,
|
||||
isSaving,
|
||||
onSave,
|
||||
isDeleting,
|
||||
onCustomFieldDelete,
|
||||
onChange,
|
||||
label = '',
|
||||
mandatory = false,
|
||||
dateType = null,
|
||||
dateFormat = null,
|
||||
defaultToday = false,
|
||||
isSaving = false,
|
||||
onSave = null,
|
||||
isDeleting = false,
|
||||
onCustomFieldDelete = null,
|
||||
onChange = null,
|
||||
}) {
|
||||
const [localLabel, setLocalLabel] = useState(label);
|
||||
const [localMandatory, setLocalMandatory] = useState(mandatory);
|
||||
@ -161,17 +161,4 @@ CustomFieldSettings.propTypes = {
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
CustomFieldSettings.defaultProps = {
|
||||
label: '',
|
||||
mandatory: false,
|
||||
isSaving: false,
|
||||
dateType: null,
|
||||
dateFormat: null,
|
||||
defaultToday: false,
|
||||
isDeleting: false,
|
||||
onCustomFieldDelete: null,
|
||||
onSave: null,
|
||||
onChange: null,
|
||||
};
|
||||
|
||||
export { CustomFieldSettings };
|
||||
|
@ -236,12 +236,13 @@ class FormFieldDate extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { field, addDefaultClasses = false } = this.props;
|
||||
const monthNames = window.mailpoet_month_names || [];
|
||||
const dateFormats = window.mailpoet_date_formats || {};
|
||||
const dateType = this.props.field.params.date_type;
|
||||
const dateType = field.params.date_type;
|
||||
let dateFormat = dateFormats[dateType][0];
|
||||
if (this.props.field.params.date_format) {
|
||||
dateFormat = this.props.field.params.date_format;
|
||||
if (field.params.date_format) {
|
||||
dateFormat = field.params.date_format;
|
||||
}
|
||||
const dateSelects = dateFormat.split('/');
|
||||
|
||||
@ -252,10 +253,10 @@ class FormFieldDate extends Component {
|
||||
<FormFieldDateYear
|
||||
onValueChange={this.onValueChange}
|
||||
key="year"
|
||||
name={this.props.field.name}
|
||||
addDefaultClasses={this.props.addDefaultClasses}
|
||||
name={field.name}
|
||||
addDefaultClasses={addDefaultClasses}
|
||||
year={this.state.year}
|
||||
placeholder={this.props.field.year_placeholder}
|
||||
placeholder={field.year_placeholder}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -264,11 +265,11 @@ class FormFieldDate extends Component {
|
||||
<FormFieldDateMonth
|
||||
onValueChange={this.onValueChange}
|
||||
key="month"
|
||||
name={this.props.field.name}
|
||||
addDefaultClasses={this.props.addDefaultClasses}
|
||||
name={field.name}
|
||||
addDefaultClasses={addDefaultClasses}
|
||||
month={this.state.month}
|
||||
monthNames={monthNames}
|
||||
placeholder={this.props.field.month_placeholder}
|
||||
placeholder={field.month_placeholder}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -277,10 +278,10 @@ class FormFieldDate extends Component {
|
||||
<FormFieldDateDay
|
||||
onValueChange={this.onValueChange}
|
||||
key="day"
|
||||
name={this.props.field.name}
|
||||
addDefaultClasses={this.props.addDefaultClasses}
|
||||
name={field.name}
|
||||
addDefaultClasses={addDefaultClasses}
|
||||
day={this.state.day}
|
||||
placeholder={this.props.field.day_placeholder}
|
||||
placeholder={field.day_placeholder}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -306,8 +307,4 @@ FormFieldDate.propTypes = {
|
||||
addDefaultClasses: PropTypes.bool,
|
||||
};
|
||||
|
||||
FormFieldDate.defaultProps = {
|
||||
addDefaultClasses: false,
|
||||
};
|
||||
|
||||
export { FormFieldDate };
|
||||
|
@ -3,7 +3,7 @@ import { Button } from '@wordpress/components';
|
||||
import PropTypes from 'prop-types';
|
||||
import { MailPoet } from 'mailpoet';
|
||||
|
||||
function CustomFieldDelete({ isBusy, onDelete }) {
|
||||
function CustomFieldDelete({ isBusy = false, onDelete = () => {} }) {
|
||||
const displayConfirm = useCallback(() => {
|
||||
const result = window.confirm(MailPoet.I18n.t('customFieldDeleteConfirm')); // eslint-disable-line no-alert
|
||||
if (result) {
|
||||
@ -29,9 +29,4 @@ CustomFieldDelete.propTypes = {
|
||||
onDelete: PropTypes.func,
|
||||
};
|
||||
|
||||
CustomFieldDelete.defaultProps = {
|
||||
isBusy: false,
|
||||
onDelete: () => {},
|
||||
};
|
||||
|
||||
export { CustomFieldDelete };
|
||||
|
@ -8,15 +8,15 @@ import { CustomFieldDelete } from '../custom-field-delete.jsx';
|
||||
import { Preview } from './settings-preview.jsx';
|
||||
|
||||
function CustomFieldSettings({
|
||||
label,
|
||||
mandatory,
|
||||
values,
|
||||
isSaving,
|
||||
onSave,
|
||||
isDeleting,
|
||||
onCustomFieldDelete,
|
||||
onChange,
|
||||
useDragAndDrop,
|
||||
label = '',
|
||||
mandatory = false,
|
||||
values = [],
|
||||
isSaving = false,
|
||||
onSave = null,
|
||||
isDeleting = false,
|
||||
onCustomFieldDelete = null,
|
||||
onChange = null,
|
||||
useDragAndDrop = true,
|
||||
}) {
|
||||
const [localLabel, setLocalLabel] = useState(label);
|
||||
const [localMandatory, setLocalMandatory] = useState(mandatory);
|
||||
@ -149,16 +149,4 @@ CustomFieldSettings.propTypes = {
|
||||
useDragAndDrop: PropTypes.bool,
|
||||
};
|
||||
|
||||
CustomFieldSettings.defaultProps = {
|
||||
label: '',
|
||||
mandatory: false,
|
||||
isSaving: false,
|
||||
values: [],
|
||||
isDeleting: false,
|
||||
onCustomFieldDelete: null,
|
||||
onSave: null,
|
||||
onChange: null,
|
||||
useDragAndDrop: true,
|
||||
};
|
||||
|
||||
export { CustomFieldSettings };
|
||||
|
@ -11,15 +11,15 @@ import { MailPoet } from 'mailpoet';
|
||||
import { CustomFieldDelete } from '../custom-field-delete.jsx';
|
||||
|
||||
function CustomFieldSettings({
|
||||
label,
|
||||
mandatory,
|
||||
validate,
|
||||
isSaving,
|
||||
onSave,
|
||||
isDeleting,
|
||||
onCustomFieldDelete,
|
||||
onChange,
|
||||
fieldType,
|
||||
label = '',
|
||||
mandatory = false,
|
||||
validate = '',
|
||||
isSaving = false,
|
||||
onSave = null,
|
||||
isDeleting = false,
|
||||
onCustomFieldDelete = null,
|
||||
onChange = null,
|
||||
fieldType = '',
|
||||
}) {
|
||||
const [localLabel, setLocalLabel] = useState(label);
|
||||
const [localMandatory, setLocalMandatory] = useState(mandatory);
|
||||
@ -116,16 +116,4 @@ CustomFieldSettings.propTypes = {
|
||||
fieldType: PropTypes.string,
|
||||
};
|
||||
|
||||
CustomFieldSettings.defaultProps = {
|
||||
label: '',
|
||||
mandatory: false,
|
||||
fieldType: '',
|
||||
isSaving: false,
|
||||
validate: '',
|
||||
isDeleting: false,
|
||||
onCustomFieldDelete: null,
|
||||
onSave: null,
|
||||
onChange: null,
|
||||
};
|
||||
|
||||
export { CustomFieldSettings };
|
||||
|
@ -1,7 +1,7 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
|
||||
function ParagraphEdit({ children, className }) {
|
||||
function ParagraphEdit({ children, className = '' }) {
|
||||
return (
|
||||
<div className={classnames('mailpoet_paragraph', className)}>
|
||||
{children}
|
||||
@ -14,8 +14,4 @@ ParagraphEdit.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
ParagraphEdit.defaultProps = {
|
||||
className: '',
|
||||
};
|
||||
|
||||
export { ParagraphEdit };
|
||||
|
@ -14,7 +14,7 @@ function TextInputEdit({
|
||||
name,
|
||||
mandatory,
|
||||
styles,
|
||||
className,
|
||||
className = '',
|
||||
}) {
|
||||
const settings = useSelect(
|
||||
(select) => select(storeName).getFormSettings(),
|
||||
@ -125,8 +125,4 @@ TextInputEdit.propTypes = {
|
||||
styles: inputStylesPropTypes.isRequired,
|
||||
};
|
||||
|
||||
TextInputEdit.defaultProps = {
|
||||
className: '',
|
||||
};
|
||||
|
||||
export { TextInputEdit };
|
||||
|
@ -3,7 +3,17 @@ import codemirror from 'codemirror';
|
||||
import 'codemirror/mode/css/css'; // Side effect
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
function CodemirrorWrap({ options, value, onChange }) {
|
||||
function CodemirrorWrap({
|
||||
value,
|
||||
onChange,
|
||||
options = {
|
||||
lineNumbers: true,
|
||||
tabMode: 'indent',
|
||||
matchBrackets: true,
|
||||
theme: 'neo',
|
||||
mode: 'css',
|
||||
},
|
||||
}) {
|
||||
const textArea = useRef(null);
|
||||
const editor = useRef(null);
|
||||
|
||||
@ -56,14 +66,4 @@ CodemirrorWrap.propTypes = {
|
||||
}),
|
||||
};
|
||||
|
||||
CodemirrorWrap.defaultProps = {
|
||||
options: {
|
||||
lineNumbers: true,
|
||||
tabMode: 'indent',
|
||||
matchBrackets: true,
|
||||
theme: 'neo',
|
||||
mode: 'css',
|
||||
},
|
||||
};
|
||||
|
||||
export { CodemirrorWrap };
|
||||
|
@ -12,7 +12,7 @@ function FormPlacementOption({
|
||||
label,
|
||||
icon,
|
||||
active,
|
||||
canBeActive,
|
||||
canBeActive = true,
|
||||
onClick,
|
||||
}: Props): JSX.Element {
|
||||
return (
|
||||
@ -32,8 +32,4 @@ function FormPlacementOption({
|
||||
);
|
||||
}
|
||||
|
||||
FormPlacementOption.defaultProps = {
|
||||
canBeActive: true,
|
||||
};
|
||||
|
||||
export { FormPlacementOption };
|
||||
|
@ -18,12 +18,12 @@ type Props = {
|
||||
function SelectionItem({
|
||||
label,
|
||||
active,
|
||||
canBeActive,
|
||||
onClick,
|
||||
children,
|
||||
className,
|
||||
automationId,
|
||||
displaySettingsIcon,
|
||||
canBeActive = true,
|
||||
className = undefined,
|
||||
automationId = undefined,
|
||||
displaySettingsIcon = true,
|
||||
}: Props): JSX.Element {
|
||||
const [hover, setHover] = useState(false);
|
||||
return (
|
||||
@ -75,11 +75,4 @@ function SelectionItem({
|
||||
);
|
||||
}
|
||||
|
||||
SelectionItem.defaultProps = {
|
||||
canBeActive: true,
|
||||
displaySettingsIcon: true,
|
||||
className: undefined,
|
||||
automationId: undefined,
|
||||
};
|
||||
|
||||
export { SelectionItem };
|
||||
|
@ -180,6 +180,7 @@ class FormField extends Component {
|
||||
|
||||
render() {
|
||||
let field = false;
|
||||
const { onValueChange = () => {} } = this.props;
|
||||
|
||||
if (this.props.field.fields !== undefined) {
|
||||
field = this.props.field.fields.map((subfield, index) =>
|
||||
@ -187,7 +188,7 @@ class FormField extends Component {
|
||||
index,
|
||||
field: subfield,
|
||||
item: this.props.item,
|
||||
onValueChange: this.props.onValueChange || false,
|
||||
onValueChange: onValueChange || false,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
@ -237,10 +238,4 @@ FormField.propTypes = {
|
||||
item: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
};
|
||||
|
||||
FormField.defaultProps = {
|
||||
onValueChange: function onValueChange() {
|
||||
// no-op
|
||||
},
|
||||
};
|
||||
|
||||
export { FormField };
|
||||
|
@ -9,7 +9,10 @@ class FormFieldRadio extends Component {
|
||||
this.onValueChange = this.onValueChange.bind(this);
|
||||
}
|
||||
|
||||
onValueChange = (value, e) => this.props.onValueChange(e);
|
||||
onValueChange = (value, e) => {
|
||||
const { onValueChange = () => {} } = this.props.onValueChange;
|
||||
onValueChange(e);
|
||||
};
|
||||
|
||||
render() {
|
||||
if (this.props.field.values === undefined) {
|
||||
@ -43,10 +46,4 @@ FormFieldRadio.propTypes = {
|
||||
item: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
};
|
||||
|
||||
FormFieldRadio.defaultProps = {
|
||||
onValueChange: function onValueChange() {
|
||||
// no-op
|
||||
},
|
||||
};
|
||||
|
||||
export { FormFieldRadio };
|
||||
|
@ -9,6 +9,8 @@ export class FormFieldSelect extends Component {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { automationId = '', onValueChange = () => {} } = this.props;
|
||||
|
||||
let filter = false;
|
||||
let placeholder = false;
|
||||
let sortBy = false;
|
||||
@ -55,8 +57,8 @@ export class FormFieldSelect extends Component {
|
||||
name={this.props.field.name}
|
||||
id={`field_${this.props.field.name}`}
|
||||
value={this.props.item[this.props.field.name] || ''}
|
||||
onChange={this.props.onValueChange}
|
||||
automationId={this.props.automationId}
|
||||
onChange={onValueChange}
|
||||
automationId={automationId}
|
||||
{...this.props.field.validation}
|
||||
>
|
||||
{placeholder}
|
||||
@ -85,10 +87,3 @@ FormFieldSelect.propTypes = {
|
||||
item: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
automationId: PropTypes.string,
|
||||
};
|
||||
|
||||
FormFieldSelect.defaultProps = {
|
||||
automationId: '',
|
||||
onValueChange: function onValueChange() {
|
||||
// no-op
|
||||
},
|
||||
};
|
||||
|
@ -19,10 +19,13 @@ class Selection extends Component {
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { item = undefined } = this.props;
|
||||
const { item: prevItem = undefined } = prevProps;
|
||||
|
||||
if (
|
||||
this.props.item !== undefined &&
|
||||
prevProps.item !== undefined &&
|
||||
this.props.item.id !== prevProps.item.id
|
||||
item !== undefined &&
|
||||
prevItem !== undefined &&
|
||||
item.id !== prevItem.id
|
||||
) {
|
||||
jQuery(`#${this.selectRef.current.id}`)
|
||||
.val(this.getSelectedValues())
|
||||
@ -50,16 +53,17 @@ class Selection extends Component {
|
||||
};
|
||||
|
||||
getSelectedValues = () => {
|
||||
if (this.props.field.selected !== undefined) {
|
||||
return this.props.field.selected(this.props.item);
|
||||
const { field, item = undefined } = this.props;
|
||||
if (field.selected !== undefined) {
|
||||
return field.selected(item);
|
||||
}
|
||||
if (this.props.item !== undefined && this.props.field.name !== undefined) {
|
||||
if (item !== undefined && field.name !== undefined) {
|
||||
if (this.allowMultipleValues()) {
|
||||
if (_.isArray(this.props.item[this.props.field.name])) {
|
||||
return this.props.item[this.props.field.name].map((item) => item.id);
|
||||
if (_.isArray(item[field.name])) {
|
||||
return item[field.name].map((it) => it.id);
|
||||
}
|
||||
} else {
|
||||
return this.props.item[this.props.field.name];
|
||||
return item[field.name];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -85,36 +89,41 @@ class Selection extends Component {
|
||||
};
|
||||
|
||||
getLabel = (item) => {
|
||||
if (this.props.field.getLabel !== undefined) {
|
||||
return this.props.field.getLabel(item, this.props.item);
|
||||
const { field, item: propsItem = undefined } = this.props;
|
||||
if (field.getLabel !== undefined) {
|
||||
return field.getLabel(item, propsItem);
|
||||
}
|
||||
return item.name;
|
||||
};
|
||||
|
||||
getSearchLabel = (item) => {
|
||||
if (this.props.field.getSearchLabel !== undefined) {
|
||||
return this.props.field.getSearchLabel(item, this.props.item);
|
||||
const { field, item: propsItem = undefined } = this.props;
|
||||
if (field.getSearchLabel !== undefined) {
|
||||
return field.getSearchLabel(item, propsItem);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
getValue = (item) => {
|
||||
if (this.props.field.getValue !== undefined) {
|
||||
return this.props.field.getValue(item, this.props.item);
|
||||
const { field, item: propsItem = undefined } = this.props;
|
||||
if (field.getValue !== undefined) {
|
||||
return field.getValue(item, propsItem);
|
||||
}
|
||||
return item.id;
|
||||
};
|
||||
|
||||
getCount = (item) => {
|
||||
if (this.props.field.getCount !== undefined) {
|
||||
return this.props.field.getCount(item, this.props.item);
|
||||
const { field, item: propsItem = undefined } = this.props;
|
||||
if (field.getCount !== undefined) {
|
||||
return field.getCount(item, propsItem);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
getTag = (item) => {
|
||||
if (this.props.field.getTag !== undefined) {
|
||||
return this.props.field.getTag(item, this.props.item);
|
||||
const { field, item: propsItem = undefined } = this.props;
|
||||
if (field.getTag !== undefined) {
|
||||
return field.getTag(item, propsItem);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@ -135,9 +144,11 @@ class Selection extends Component {
|
||||
return tpl;
|
||||
};
|
||||
|
||||
const { width = '', disabled = false } = this.props;
|
||||
|
||||
let select2Options = {
|
||||
disabled: this.props.disabled || false,
|
||||
width: this.props.width || '',
|
||||
disabled: disabled || false,
|
||||
width: width || '',
|
||||
placeholder: {
|
||||
id: '', // the value of the option
|
||||
text: this.props.field.placeholder,
|
||||
@ -266,7 +277,7 @@ class Selection extends Component {
|
||||
this.allowMultipleValues() || this.props.field.forceSelect2;
|
||||
|
||||
handleChange = (e) => {
|
||||
if (this.props.onValueChange === undefined) return;
|
||||
const { onValueChange = () => {} } = this.props;
|
||||
|
||||
const valueTextPair = jQuery(`#${this.selectRef.current.id}`)
|
||||
.children(':selected')
|
||||
@ -278,7 +289,7 @@ class Selection extends Component {
|
||||
: _.pluck(valueTextPair, 'id').toString();
|
||||
const transformedValue = this.transformChangedValue(value, valueTextPair);
|
||||
|
||||
this.props.onValueChange({
|
||||
onValueChange({
|
||||
target: {
|
||||
value: transformedValue,
|
||||
name: this.props.field.name,
|
||||
@ -390,13 +401,4 @@ Selection.propTypes = {
|
||||
width: PropTypes.string,
|
||||
};
|
||||
|
||||
Selection.defaultProps = {
|
||||
onValueChange: function onValueChange() {
|
||||
// no-op
|
||||
},
|
||||
disabled: false,
|
||||
width: '',
|
||||
item: undefined,
|
||||
};
|
||||
|
||||
export { Selection };
|
||||
|
@ -5,12 +5,13 @@ import { Input } from 'common/form/input/input';
|
||||
// eslint-disable-next-line react/prefer-stateless-function, max-len
|
||||
class FormFieldText extends Component {
|
||||
render() {
|
||||
const { onValueChange = () => {}, onBlurEvent = () => {} } = this.props;
|
||||
const name = this.props.field.name || null;
|
||||
const item = this.props.item || {};
|
||||
let value;
|
||||
let defaultValue;
|
||||
// value should only be set when onChangeValue is configured
|
||||
if (this.props.onValueChange instanceof Function) {
|
||||
if (onValueChange instanceof Function) {
|
||||
value = item[this.props.field.name];
|
||||
// set value to defaultValue if available
|
||||
value = value === undefined ? this.props.field.defaultValue || '' : value;
|
||||
@ -54,8 +55,8 @@ class FormFieldText extends Component {
|
||||
value={value}
|
||||
defaultValue={defaultValue}
|
||||
placeholder={this.props.field.placeholder}
|
||||
onChange={this.props.onValueChange}
|
||||
onBlur={this.props.onBlurEvent}
|
||||
onChange={onValueChange}
|
||||
onBlur={onBlurEvent}
|
||||
customLabel={this.props.field.customLabel}
|
||||
tooltip={this.props.field.tooltip}
|
||||
{...this.props.field.validation}
|
||||
@ -88,13 +89,4 @@ FormFieldText.propTypes = {
|
||||
item: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
};
|
||||
|
||||
FormFieldText.defaultProps = {
|
||||
onValueChange: function onValueChange() {
|
||||
// no-op
|
||||
},
|
||||
onBlurEvent: function onValueChange() {
|
||||
// no-op
|
||||
},
|
||||
};
|
||||
|
||||
export { FormFieldText };
|
||||
|
@ -56,10 +56,4 @@ Tooltip.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
Tooltip.defaultProps = {
|
||||
tooltipId: undefined,
|
||||
place: undefined,
|
||||
className: undefined,
|
||||
};
|
||||
|
||||
export { Tooltip };
|
||||
|
@ -2,39 +2,38 @@ import PropTypes from 'prop-types';
|
||||
import { MailPoet } from 'mailpoet';
|
||||
import parseDate from 'date-fns/parse';
|
||||
|
||||
function TasksListDataRow(props) {
|
||||
let scheduled = props.task.scheduled_at;
|
||||
function TasksListDataRow({
|
||||
task,
|
||||
show_scheduled_at: showScheduledAt = false,
|
||||
}) {
|
||||
let scheduled = task.scheduled_at;
|
||||
if (scheduled) {
|
||||
scheduled = parseDate(scheduled, 'yyyy-MM-dd HH:mm:ss', new Date());
|
||||
}
|
||||
|
||||
const updated = parseDate(
|
||||
props.task.updated_at,
|
||||
'yyyy-MM-dd HH:mm:ss',
|
||||
new Date(),
|
||||
);
|
||||
const updated = parseDate(task.updated_at, 'yyyy-MM-dd HH:mm:ss', new Date());
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td className="column column-primary">{props.task.id}</td>
|
||||
<td className="column">{props.task.type}</td>
|
||||
<td className="column column-primary">{task.id}</td>
|
||||
<td className="column">{task.type}</td>
|
||||
<td className="column">
|
||||
{props.task.newsletter ? (
|
||||
{task.newsletter ? (
|
||||
<a
|
||||
href={props.task.newsletter.preview_url}
|
||||
data-newsletter-id={props.task.newsletter.newsletter_id}
|
||||
data-queue-id={props.task.newsletter.queue_id}
|
||||
href={task.newsletter.preview_url}
|
||||
data-newsletter-id={task.newsletter.newsletter_id}
|
||||
data-queue-id={task.newsletter.queue_id}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{props.task.newsletter.subject || MailPoet.I18n.t('preview')}
|
||||
{task.newsletter.subject || MailPoet.I18n.t('preview')}
|
||||
</a>
|
||||
) : (
|
||||
MailPoet.I18n.t('none')
|
||||
)}
|
||||
</td>
|
||||
<td className="column">{props.task.priority}</td>
|
||||
{props.show_scheduled_at ? (
|
||||
<td className="column">{task.priority}</td>
|
||||
{showScheduledAt ? (
|
||||
<td className="column-date">
|
||||
<abbr>{`${MailPoet.Date.short(scheduled)} ${MailPoet.Date.time(
|
||||
scheduled,
|
||||
@ -68,8 +67,4 @@ TasksListDataRow.propTypes = {
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
TasksListDataRow.defaultProps = {
|
||||
show_scheduled_at: false,
|
||||
};
|
||||
|
||||
export { TasksListDataRow };
|
||||
|
@ -1,14 +1,14 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { MailPoet } from 'mailpoet';
|
||||
|
||||
function TasksListLabelsRow(props) {
|
||||
function TasksListLabelsRow({ show_scheduled_at: showScheduledAt = false }) {
|
||||
return (
|
||||
<tr>
|
||||
<th className="row-title">Id</th>
|
||||
<th className="row-title">{MailPoet.I18n.t('type')}</th>
|
||||
<th className="row-title">{MailPoet.I18n.t('email')}</th>
|
||||
<th className="row-title">{MailPoet.I18n.t('priority')}</th>
|
||||
{props.show_scheduled_at ? (
|
||||
{showScheduledAt ? (
|
||||
<th className="row-title">{MailPoet.I18n.t('scheduledAt')}</th>
|
||||
) : null}
|
||||
<th className="row-title">{MailPoet.I18n.t('updatedAt')}</th>
|
||||
@ -20,8 +20,4 @@ TasksListLabelsRow.propTypes = {
|
||||
show_scheduled_at: PropTypes.bool,
|
||||
};
|
||||
|
||||
TasksListLabelsRow.defaultProps = {
|
||||
show_scheduled_at: false,
|
||||
};
|
||||
|
||||
export { TasksListLabelsRow };
|
||||
|
@ -3,21 +3,21 @@ import { MailPoet } from 'mailpoet';
|
||||
import { TasksListDataRow } from './tasks-list-data-row.jsx';
|
||||
import { TasksListLabelsRow } from './tasks-list-labels-row.jsx';
|
||||
|
||||
function TasksList(props) {
|
||||
const colsCount = props.show_scheduled_at ? 6 : 5;
|
||||
function TasksList({ tasks, show_scheduled_at: showScheduledAt = false }) {
|
||||
const colsCount = showScheduledAt ? 6 : 5;
|
||||
|
||||
return (
|
||||
<table className="widefat fixed striped">
|
||||
<thead>
|
||||
<TasksListLabelsRow show_scheduled_at={props.show_scheduled_at} />
|
||||
<TasksListLabelsRow show_scheduled_at={showScheduledAt} />
|
||||
</thead>
|
||||
<tbody>
|
||||
{props.tasks.length ? (
|
||||
props.tasks.map((task) => (
|
||||
{tasks.length ? (
|
||||
tasks.map((task) => (
|
||||
<TasksListDataRow
|
||||
key={task.id}
|
||||
task={task}
|
||||
show_scheduled_at={props.show_scheduled_at}
|
||||
show_scheduled_at={showScheduledAt}
|
||||
/>
|
||||
))
|
||||
) : (
|
||||
@ -27,7 +27,7 @@ function TasksList(props) {
|
||||
)}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<TasksListLabelsRow show_scheduled_at={props.show_scheduled_at} />
|
||||
<TasksListLabelsRow show_scheduled_at={showScheduledAt} />
|
||||
</tfoot>
|
||||
</table>
|
||||
);
|
||||
@ -38,8 +38,4 @@ TasksList.propTypes = {
|
||||
tasks: PropTypes.arrayOf(TasksListDataRow.propTypes.task).isRequired,
|
||||
};
|
||||
|
||||
TasksList.defaultProps = {
|
||||
show_scheduled_at: false,
|
||||
};
|
||||
|
||||
export { TasksList };
|
||||
|
@ -33,14 +33,15 @@ class ListingFilters extends Component {
|
||||
handleEmptyTrash = () => this.props.onEmptyTrash();
|
||||
|
||||
handleFilterAction = () => {
|
||||
const { onSelectFilter, onBeforeSelectFilter = undefined } = this.props;
|
||||
const filters = {};
|
||||
this.getAvailableFilters().forEach((filter, i) => {
|
||||
filters[this[`filter-${i}`].name] = this[`filter-${i}`].value;
|
||||
});
|
||||
if (this.props.onBeforeSelectFilter) {
|
||||
this.props.onBeforeSelectFilter(filters);
|
||||
if (onBeforeSelectFilter) {
|
||||
onBeforeSelectFilter(filters);
|
||||
}
|
||||
return this.props.onSelectFilter(filters);
|
||||
return onSelectFilter(filters);
|
||||
};
|
||||
|
||||
render() {
|
||||
@ -98,9 +99,6 @@ ListingFilters.propTypes = {
|
||||
group: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
ListingFilters.defaultProps = {
|
||||
onBeforeSelectFilter: undefined,
|
||||
};
|
||||
ListingFilters.displayName = 'ListingFilters';
|
||||
const ListingFiltersWithBoundary = withBoundary(ListingFilters);
|
||||
export { ListingFiltersWithBoundary as ListingFilters };
|
||||
|
@ -16,15 +16,22 @@ class ListingHeader extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const columns = this.props.columns.map((column, index) => {
|
||||
const {
|
||||
onSort,
|
||||
sort_by: sortBy,
|
||||
sort_order: sortOrder,
|
||||
is_selectable: isSelectable,
|
||||
selection,
|
||||
columns: propsColumns = [],
|
||||
} = this.props;
|
||||
const columns = propsColumns.map((column, index) => {
|
||||
const renderColumn = column;
|
||||
renderColumn.is_primary = index === 0;
|
||||
renderColumn.sorted =
|
||||
this.props.sort_by === column.name ? this.props.sort_order : 'desc';
|
||||
renderColumn.sorted = sortBy === column.name ? sortOrder : 'desc';
|
||||
return (
|
||||
<ListingColumn
|
||||
onSort={this.props.onSort}
|
||||
sort_by={this.props.sort_by}
|
||||
onSort={onSort}
|
||||
sort_by={sortBy}
|
||||
key={`column-${column.name}`}
|
||||
column={renderColumn}
|
||||
/>
|
||||
@ -33,7 +40,7 @@ class ListingHeader extends Component {
|
||||
|
||||
let checkbox;
|
||||
|
||||
if (this.props.is_selectable === true) {
|
||||
if (isSelectable === true) {
|
||||
checkbox = (
|
||||
<th className="manage-column column-cb mailpoet-listing-check-column">
|
||||
<label className="screen-reader-text" htmlFor="select_all">
|
||||
@ -43,7 +50,7 @@ class ListingHeader extends Component {
|
||||
name="select_all"
|
||||
id="select_all"
|
||||
automationId="select_all"
|
||||
checked={this.props.selection}
|
||||
checked={selection}
|
||||
onCheck={() => {}}
|
||||
onChange={this.handleSelectItems}
|
||||
/>
|
||||
@ -70,10 +77,4 @@ ListingHeader.propTypes = {
|
||||
selection: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]).isRequired,
|
||||
};
|
||||
|
||||
ListingHeader.defaultProps = {
|
||||
columns: [],
|
||||
sort_by: undefined,
|
||||
sort_order: 'desc',
|
||||
};
|
||||
|
||||
export { ListingHeader };
|
||||
|
@ -10,17 +10,18 @@ class ListingColumn extends Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { column, sort_by: sortBy = undefined } = this.props;
|
||||
const classes = classnames(
|
||||
'manage-column',
|
||||
{ 'column-primary': this.props.column.is_primary },
|
||||
{ sortable: this.props.column.sortable },
|
||||
this.props.column.sorted,
|
||||
{ sorted: this.props.sort_by === this.props.column.name },
|
||||
this.props.column.className,
|
||||
{ 'column-primary': column.is_primary },
|
||||
{ sortable: column.sortable },
|
||||
column.sorted,
|
||||
{ sorted: sortBy === column.name },
|
||||
column.className,
|
||||
);
|
||||
let label;
|
||||
|
||||
if (this.props.column.sortable === true) {
|
||||
if (column.sortable === true) {
|
||||
label = (
|
||||
<a
|
||||
onClick={this.handleSort}
|
||||
@ -36,21 +37,21 @@ class ListingColumn extends Component {
|
||||
}
|
||||
}}
|
||||
>
|
||||
<span>{this.props.column.label}</span>
|
||||
<span>{column.label}</span>
|
||||
<span className="mailpoet-listing-sorting-arrow" />
|
||||
</a>
|
||||
);
|
||||
} else {
|
||||
label = this.props.column.label;
|
||||
label = column.label;
|
||||
}
|
||||
return (
|
||||
<th
|
||||
role="columnheader"
|
||||
className={classes}
|
||||
id={this.props.column.name}
|
||||
id={column.name}
|
||||
scope="col"
|
||||
width={this.props.column.width || null}
|
||||
data-automation-id={`listing-column-header-${this.props.column.name}`}
|
||||
width={column.width || null}
|
||||
data-automation-id={`listing-column-header-${column.name}`}
|
||||
>
|
||||
{label}
|
||||
</th>
|
||||
@ -72,8 +73,4 @@ ListingColumn.propTypes = {
|
||||
onSort: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
ListingColumn.defaultProps = {
|
||||
sort_by: undefined,
|
||||
};
|
||||
|
||||
export { ListingColumn };
|
||||
|
@ -27,7 +27,22 @@ class ListingItem extends Component {
|
||||
render() {
|
||||
let checkbox = false;
|
||||
|
||||
if (this.props.is_selectable === true) {
|
||||
const {
|
||||
is_selectable: isSelectable,
|
||||
item,
|
||||
columns,
|
||||
group,
|
||||
selection,
|
||||
item_actions: propsItemActions,
|
||||
onRefreshItems,
|
||||
isItemInactive,
|
||||
onRenderItem,
|
||||
location = undefined,
|
||||
isItemDeletable = () => true,
|
||||
isItemToggleable = () => false,
|
||||
} = this.props;
|
||||
|
||||
if (isSelectable === true) {
|
||||
checkbox = (
|
||||
<th
|
||||
className="mailpoet-listing-check-column mailpoet-hide-on-mobile"
|
||||
@ -35,24 +50,24 @@ class ListingItem extends Component {
|
||||
>
|
||||
<label
|
||||
className="screen-reader-text"
|
||||
htmlFor={`listing-row-checkbox-${this.props.item.id}`}
|
||||
htmlFor={`listing-row-checkbox-${item.id}`}
|
||||
>
|
||||
{`Select ${this.props.item[this.props.columns[0].name]}`}
|
||||
{`Select ${item[columns[0].name]}`}
|
||||
</label>
|
||||
<Checkbox
|
||||
value={this.props.item.id}
|
||||
checked={this.props.item.selected || this.props.selection === 'all'}
|
||||
value={item.id}
|
||||
checked={item.selected || selection === 'all'}
|
||||
onCheck={() => {}}
|
||||
onChange={this.handleSelectItem}
|
||||
disabled={this.props.selection === 'all'}
|
||||
id={`listing-row-checkbox-${this.props.item.id}`}
|
||||
automationId={`listing-row-checkbox-${this.props.item.id}`}
|
||||
disabled={selection === 'all'}
|
||||
id={`listing-row-checkbox-${item.id}`}
|
||||
automationId={`listing-row-checkbox-${item.id}`}
|
||||
/>
|
||||
</th>
|
||||
);
|
||||
}
|
||||
|
||||
const customActions = this.props.item_actions;
|
||||
const customActions = propsItemActions;
|
||||
let itemActions = false;
|
||||
|
||||
if (customActions.length > 0) {
|
||||
@ -75,10 +90,10 @@ class ListingItem extends Component {
|
||||
href="#"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
this.handleTrashItem(this.props.item.id);
|
||||
this.handleTrashItem(item.id);
|
||||
}}
|
||||
>
|
||||
{this.props.isItemToggleable(this.props.item)
|
||||
{isItemToggleable(item)
|
||||
? __('Trash and disable', 'mailpoet')
|
||||
: __('Move to trash', 'mailpoet')}
|
||||
</a>
|
||||
@ -87,7 +102,7 @@ class ListingItem extends Component {
|
||||
} else if (action.refresh) {
|
||||
customAction = (
|
||||
<span
|
||||
onClick={this.props.onRefreshItems}
|
||||
onClick={onRefreshItems}
|
||||
key={`action-${action.name}`}
|
||||
className={classnames(action.name, action.className)}
|
||||
role="button"
|
||||
@ -98,11 +113,11 @@ class ListingItem extends Component {
|
||||
['Enter', ' '].includes(event.key)
|
||||
) {
|
||||
event.preventDefault();
|
||||
this.props.onRefreshItems();
|
||||
onRefreshItems();
|
||||
}
|
||||
}}
|
||||
>
|
||||
{action.link(this.props.item)}
|
||||
{action.link(item)}
|
||||
</span>
|
||||
);
|
||||
} else if (action.link) {
|
||||
@ -111,7 +126,7 @@ class ListingItem extends Component {
|
||||
key={`action-${action.name}`}
|
||||
className={classnames(action.name, action.className)}
|
||||
>
|
||||
{action.link(this.props.item, this.props.location)}
|
||||
{action.link(item, location)}
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
@ -125,10 +140,7 @@ class ListingItem extends Component {
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
if (action.onClick !== undefined) {
|
||||
action.onClick(
|
||||
this.props.item,
|
||||
this.props.onRefreshItems,
|
||||
);
|
||||
action.onClick(item, onRefreshItems);
|
||||
}
|
||||
}}
|
||||
>
|
||||
@ -144,9 +156,9 @@ class ListingItem extends Component {
|
||||
<span className="edit mailpoet-hide-on-mobile">
|
||||
<Link
|
||||
to={{
|
||||
pathname: `/edit/${this.props.item.id}`,
|
||||
pathname: `/edit/${item.id}`,
|
||||
state: {
|
||||
backUrl: this.props.location?.pathname,
|
||||
backUrl: location?.pathname,
|
||||
},
|
||||
}}
|
||||
>
|
||||
@ -158,7 +170,7 @@ class ListingItem extends Component {
|
||||
|
||||
let actions;
|
||||
|
||||
if (this.props.group === 'trash') {
|
||||
if (group === 'trash') {
|
||||
actions = (
|
||||
<div className="mailpoet-listing-actions-holder">
|
||||
<div className="mailpoet-listing-actions">
|
||||
@ -167,22 +179,22 @@ class ListingItem extends Component {
|
||||
href="#"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
this.handleRestoreItem(this.props.item.id);
|
||||
this.handleRestoreItem(item.id);
|
||||
}}
|
||||
>
|
||||
{this.props.isItemToggleable(this.props.item)
|
||||
{isItemToggleable(item)
|
||||
? __('Restore and enable', 'mailpoet')
|
||||
: __('Restore', 'mailpoet')}
|
||||
</a>
|
||||
</span>
|
||||
{this.props.isItemDeletable(this.props.item) && (
|
||||
{isItemDeletable(item) && (
|
||||
<span className="delete">
|
||||
<a
|
||||
className="submitdelete"
|
||||
href="#"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
this.handleDeleteItem(this.props.item.id);
|
||||
this.handleDeleteItem(item.id);
|
||||
}}
|
||||
>
|
||||
{__('Delete permanently', 'mailpoet')}
|
||||
@ -201,20 +213,14 @@ class ListingItem extends Component {
|
||||
}
|
||||
|
||||
const rowClasses = classnames({
|
||||
'mailpoet-listing-row-selected':
|
||||
this.props.item.selected || this.props.selection === 'all',
|
||||
'mailpoet-listing-row-inactive': this.props.isItemInactive(
|
||||
this.props.item,
|
||||
),
|
||||
'mailpoet-listing-row-selected': item.selected || selection === 'all',
|
||||
'mailpoet-listing-row-inactive': isItemInactive(item),
|
||||
});
|
||||
|
||||
return (
|
||||
<tr
|
||||
className={rowClasses}
|
||||
data-automation-id={`listing_item_${this.props.item.id}`}
|
||||
>
|
||||
<tr className={rowClasses} data-automation-id={`listing_item_${item.id}`}>
|
||||
{checkbox}
|
||||
{this.props.onRenderItem(this.props.item, actions)}
|
||||
{onRenderItem(item, actions)}
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
@ -245,10 +251,4 @@ ListingItem.propTypes = {
|
||||
isItemToggleable: PropTypes.func,
|
||||
};
|
||||
|
||||
ListingItem.defaultProps = {
|
||||
location: undefined,
|
||||
isItemDeletable: () => true,
|
||||
isItemToggleable: () => false,
|
||||
};
|
||||
|
||||
export { ListingItem };
|
||||
|
@ -10,20 +10,43 @@ import { ListingItem } from 'listing/listing-item.jsx';
|
||||
// eslint-disable-next-line react/prefer-stateless-function, max-len
|
||||
class ListingItems extends Component {
|
||||
render() {
|
||||
if (this.props.items.length === 0) {
|
||||
const {
|
||||
bulk_actions: bulkActions,
|
||||
count,
|
||||
columns,
|
||||
group,
|
||||
items,
|
||||
is_selectable: isSelectable,
|
||||
isItemInactive,
|
||||
item_actions: itemActions,
|
||||
limit,
|
||||
loading,
|
||||
messages,
|
||||
onBulkAction,
|
||||
onDeleteItem,
|
||||
onRefreshItems,
|
||||
onRenderItem,
|
||||
onRestoreItem,
|
||||
onSelectAll,
|
||||
onSelectItem,
|
||||
onTrashItem,
|
||||
selected_ids: selectedIds,
|
||||
selection,
|
||||
getListingItemKey = undefined,
|
||||
search = undefined,
|
||||
location = undefined,
|
||||
isItemDeletable = () => true,
|
||||
isItemToggleable = () => false,
|
||||
} = this.props;
|
||||
if (items.length === 0) {
|
||||
let message;
|
||||
if (this.props.loading === true) {
|
||||
if (loading === true) {
|
||||
message =
|
||||
(this.props.messages.onLoadingItems &&
|
||||
this.props.messages.onLoadingItems(this.props.group)) ||
|
||||
(messages.onLoadingItems && messages.onLoadingItems(group)) ||
|
||||
__('Loading ...', 'mailpoet');
|
||||
} else {
|
||||
message =
|
||||
(this.props.messages.onNoItemsFound &&
|
||||
this.props.messages.onNoItemsFound(
|
||||
this.props.group,
|
||||
this.props.search,
|
||||
)) ||
|
||||
(messages.onNoItemsFound && messages.onNoItemsFound(group, search)) ||
|
||||
__('No items found.', 'mailpoet');
|
||||
}
|
||||
|
||||
@ -31,9 +54,7 @@ class ListingItems extends Component {
|
||||
<tbody>
|
||||
<tr className="mailpoet-listing-no-items">
|
||||
<td
|
||||
colSpan={
|
||||
this.props.columns.length + (this.props.is_selectable ? 1 : 0)
|
||||
}
|
||||
colSpan={columns.length + (isSelectable ? 1 : 0)}
|
||||
className="colspanchange"
|
||||
>
|
||||
{message}
|
||||
@ -43,11 +64,8 @@ class ListingItems extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
const isSelectAllHidden =
|
||||
this.props.selection === false || this.props.count <= this.props.limit;
|
||||
const areBulkActionsHidden = !(
|
||||
this.props.selected_ids.length > 0 || this.props.selection
|
||||
);
|
||||
const isSelectAllHidden = selection === false || count <= limit;
|
||||
const areBulkActionsHidden = !(selectedIds.length > 0 || selection);
|
||||
|
||||
const actionAndSelectAllRowClasses = classnames(
|
||||
'mailpoet-listing-actions-and-select-all-row',
|
||||
@ -62,39 +80,35 @@ class ListingItems extends Component {
|
||||
return (
|
||||
<tbody>
|
||||
<tr className={actionAndSelectAllRowClasses}>
|
||||
<td
|
||||
colSpan={
|
||||
this.props.columns.length + (this.props.is_selectable ? 1 : 0)
|
||||
}
|
||||
>
|
||||
<td colSpan={columns.length + (isSelectable ? 1 : 0)}>
|
||||
<Grid.SpaceBetween verticalAlign="center">
|
||||
<div className="mailpoet-listing-bulk-actions-container">
|
||||
{!areBulkActionsHidden && (
|
||||
<ListingBulkActions
|
||||
count={this.props.count}
|
||||
bulk_actions={this.props.bulk_actions}
|
||||
selection={this.props.selection}
|
||||
selected_ids={this.props.selected_ids}
|
||||
onBulkAction={this.props.onBulkAction}
|
||||
count={count}
|
||||
bulk_actions={bulkActions}
|
||||
selection={selection}
|
||||
selected_ids={selectedIds}
|
||||
onBulkAction={onBulkAction}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className={selectAllClasses}>
|
||||
{this.props.selection !== 'all'
|
||||
{selection !== 'all'
|
||||
? __('All items on this page are selected.', 'mailpoet')
|
||||
: __('All %d items are selected.', 'mailpoet').replace(
|
||||
'%d',
|
||||
this.props.count.toLocaleString(),
|
||||
count.toLocaleString(),
|
||||
)}
|
||||
|
||||
<a
|
||||
href="#"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
this.props.onSelectAll(event);
|
||||
onSelectAll(event);
|
||||
}}
|
||||
>
|
||||
{this.props.selection !== 'all'
|
||||
{selection !== 'all'
|
||||
? __('Select all items on all pages', 'mailpoet')
|
||||
: __('Clear selection', 'mailpoet')}
|
||||
</a>
|
||||
@ -104,35 +118,34 @@ class ListingItems extends Component {
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{this.props.items.map((item) => {
|
||||
{items.map((item) => {
|
||||
const renderItem = item;
|
||||
renderItem.id = parseInt(item.id, 10);
|
||||
renderItem.selected =
|
||||
this.props.selected_ids.indexOf(renderItem.id) !== -1;
|
||||
renderItem.selected = selectedIds.indexOf(renderItem.id) !== -1;
|
||||
let key = `item-${renderItem.id}-${item.id}`;
|
||||
if (typeof this.props.getListingItemKey === 'function') {
|
||||
key = this.props.getListingItemKey(item);
|
||||
if (typeof getListingItemKey === 'function') {
|
||||
key = getListingItemKey(item);
|
||||
}
|
||||
|
||||
return (
|
||||
<ListingItem
|
||||
columns={this.props.columns}
|
||||
isItemInactive={this.props.isItemInactive}
|
||||
onSelectItem={this.props.onSelectItem}
|
||||
onRenderItem={this.props.onRenderItem}
|
||||
onDeleteItem={this.props.onDeleteItem}
|
||||
onRestoreItem={this.props.onRestoreItem}
|
||||
onTrashItem={this.props.onTrashItem}
|
||||
onRefreshItems={this.props.onRefreshItems}
|
||||
selection={this.props.selection}
|
||||
is_selectable={this.props.is_selectable}
|
||||
item_actions={this.props.item_actions}
|
||||
group={this.props.group}
|
||||
location={this.props.location}
|
||||
columns={columns}
|
||||
isItemInactive={isItemInactive}
|
||||
onSelectItem={onSelectItem}
|
||||
onRenderItem={onRenderItem}
|
||||
onDeleteItem={onDeleteItem}
|
||||
onRestoreItem={onRestoreItem}
|
||||
onTrashItem={onTrashItem}
|
||||
onRefreshItems={onRefreshItems}
|
||||
selection={selection}
|
||||
is_selectable={isSelectable}
|
||||
item_actions={itemActions}
|
||||
group={group}
|
||||
location={location}
|
||||
key={key}
|
||||
item={renderItem}
|
||||
isItemDeletable={this.props.isItemDeletable}
|
||||
isItemToggleable={this.props.isItemToggleable}
|
||||
isItemDeletable={isItemDeletable}
|
||||
isItemToggleable={isItemToggleable}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@ -179,12 +192,4 @@ ListingItems.propTypes = {
|
||||
isItemToggleable: PropTypes.func,
|
||||
};
|
||||
|
||||
ListingItems.defaultProps = {
|
||||
getListingItemKey: undefined,
|
||||
search: undefined,
|
||||
location: undefined,
|
||||
isItemDeletable: () => true,
|
||||
isItemToggleable: () => false,
|
||||
};
|
||||
|
||||
export { ListingItems };
|
||||
|
@ -60,7 +60,8 @@ class ListingPages extends Component {
|
||||
Math.min(Math.max(1, Math.abs(Number(page))), this.getLastPage());
|
||||
|
||||
render() {
|
||||
if (this.props.count === 0) {
|
||||
const { count, limit, page, position = '' } = this.props;
|
||||
if (count === 0) {
|
||||
return false;
|
||||
}
|
||||
let pagination = false;
|
||||
@ -87,8 +88,8 @@ class ListingPages extends Component {
|
||||
</span>
|
||||
);
|
||||
|
||||
if (this.props.limit > 0 && this.props.count > this.props.limit) {
|
||||
if (this.props.page > 1) {
|
||||
if (limit > 0 && count > limit) {
|
||||
if (page > 1) {
|
||||
previousPage = (
|
||||
<a
|
||||
href="#"
|
||||
@ -108,7 +109,7 @@ class ListingPages extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.page > 2) {
|
||||
if (page > 2) {
|
||||
firstPage = (
|
||||
<a
|
||||
href="#"
|
||||
@ -129,7 +130,7 @@ class ListingPages extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.page < this.getLastPage()) {
|
||||
if (page < this.getLastPage()) {
|
||||
nextPage = (
|
||||
<a
|
||||
href="#"
|
||||
@ -149,7 +150,7 @@ class ListingPages extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.page < this.getLastPage() - 1) {
|
||||
if (page < this.getLastPage() - 1) {
|
||||
lastPage = (
|
||||
<a
|
||||
href="#"
|
||||
@ -170,7 +171,7 @@ class ListingPages extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
let pageValue = this.props.page;
|
||||
let pageValue = page;
|
||||
if (this.state.page !== null) {
|
||||
pageValue = this.state.page;
|
||||
}
|
||||
@ -184,7 +185,7 @@ class ListingPages extends Component {
|
||||
<span className="mailpoet-listing-paging-input">
|
||||
<label
|
||||
className="screen-reader-text"
|
||||
htmlFor={`current-page-selector-${this.props.position}`}
|
||||
htmlFor={`current-page-selector-${position}`}
|
||||
>
|
||||
{__('Current page', 'mailpoet')}
|
||||
</label>
|
||||
@ -197,13 +198,13 @@ class ListingPages extends Component {
|
||||
size="2"
|
||||
value={pageValue}
|
||||
name="paged"
|
||||
id={`current-page-selector-${this.props.position}`}
|
||||
id={`current-page-selector-${position}`}
|
||||
className="mailpoet-listing-current-page"
|
||||
/>
|
||||
{__('of', 'mailpoet')}
|
||||
|
||||
<span className="mailpoet-listing-total-pages">
|
||||
{Math.ceil(this.props.count / this.props.limit).toLocaleString()}
|
||||
{Math.ceil(count / limit).toLocaleString()}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
@ -215,16 +216,16 @@ class ListingPages extends Component {
|
||||
}
|
||||
|
||||
const classes = classnames('mailpoet-listing-pages', {
|
||||
'one-page': this.props.count <= this.props.limit,
|
||||
'one-page': count <= limit,
|
||||
});
|
||||
|
||||
let numberOfItemsLabel;
|
||||
if (Number(this.props.count) === 1) {
|
||||
if (Number(count) === 1) {
|
||||
numberOfItemsLabel = __('1 item', 'mailpoet');
|
||||
} else {
|
||||
numberOfItemsLabel = __('%1$d items', 'mailpoet').replace(
|
||||
'%1$d',
|
||||
parseInt(this.props.count, 10).toLocaleString(),
|
||||
parseInt(count, 10).toLocaleString(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -245,16 +246,12 @@ ListingPages.propTypes = {
|
||||
limit: PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
ListingPages.defaultProps = {
|
||||
position: '',
|
||||
};
|
||||
|
||||
/* type ArrowProps = {
|
||||
direction?: 'right',
|
||||
disabled?: boolean
|
||||
} */
|
||||
|
||||
function Arrow({ direction, disabled }) {
|
||||
function Arrow({ direction = 'right', disabled = false }) {
|
||||
const arrowLeftPath =
|
||||
'M8 10V2c0-.552-.448-1-1-1-.216 0-.427.07-.6.2l-5.333 4c-.442.331-.532.958-.2 1.4.057.076.124.143.2.2l5.333 4c.442.331 1.069.242 1.4-.2.13-.173.2-.384.2-.6z';
|
||||
const arrowRightPath =
|
||||
@ -279,9 +276,4 @@ Arrow.propTypes = {
|
||||
disabled: PropTypes.bool,
|
||||
};
|
||||
|
||||
Arrow.defaultProps = {
|
||||
direction: 'right',
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
export { ListingPages };
|
||||
|
@ -95,7 +95,10 @@ class EventScheduling extends Component {
|
||||
}
|
||||
|
||||
displayAfterTimeNumberField() {
|
||||
const { afterTimeNumberSize, event } = this.props;
|
||||
const {
|
||||
event,
|
||||
afterTimeNumberSize = defaultAfterTimeNumberInputFieldSize,
|
||||
} = this.props;
|
||||
const { afterTimeType, afterTimeNumber } = this.state;
|
||||
if (afterTimeType === 'immediate') return null;
|
||||
if (
|
||||
@ -135,7 +138,7 @@ class EventScheduling extends Component {
|
||||
}
|
||||
|
||||
propagateChange(data) {
|
||||
const { onValueChange } = this.props;
|
||||
const { onValueChange = null } = this.props;
|
||||
if (!onValueChange) return;
|
||||
|
||||
onValueChange(data);
|
||||
@ -197,9 +200,5 @@ EventScheduling.propTypes = {
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
EventScheduling.defaultProps = {
|
||||
afterTimeNumberSize: defaultAfterTimeNumberInputFieldSize,
|
||||
onValueChange: null,
|
||||
};
|
||||
EventScheduling.displayName = 'EventScheduling';
|
||||
export { EventScheduling };
|
||||
|
@ -149,7 +149,7 @@ class SendEventConditions extends Component {
|
||||
segment,
|
||||
eventOptionValue,
|
||||
} = this.state;
|
||||
const { onValueChange } = this.props;
|
||||
const { onValueChange = null } = this.props;
|
||||
if (!onValueChange) return;
|
||||
|
||||
const options = {
|
||||
@ -193,8 +193,5 @@ SendEventConditions.propTypes = {
|
||||
onValueChange: PropTypes.func,
|
||||
};
|
||||
|
||||
SendEventConditions.defaultProps = {
|
||||
onValueChange: null,
|
||||
};
|
||||
SendEventConditions.displayName = 'SendEventConditions';
|
||||
export { SendEventConditions };
|
||||
|
@ -30,7 +30,11 @@ const wrapInLink = (content, params, id, totalSent) => {
|
||||
);
|
||||
};
|
||||
|
||||
function Statistics({ newsletter, isSent, currentTime }) {
|
||||
function Statistics({
|
||||
newsletter,
|
||||
isSent = undefined,
|
||||
currentTime = undefined,
|
||||
}) {
|
||||
let sent = isSent;
|
||||
if (sent === undefined) {
|
||||
// condition for standard and post notification listings
|
||||
@ -199,10 +203,6 @@ Statistics.propTypes = {
|
||||
currentTime: PropTypes.string,
|
||||
};
|
||||
|
||||
Statistics.defaultProps = {
|
||||
isSent: undefined,
|
||||
currentTime: undefined,
|
||||
};
|
||||
Statistics.displayName = 'NewsletterStatistics';
|
||||
const StatisticsWithBoundary = withBoundary(Statistics);
|
||||
export { StatisticsWithBoundary as Statistics };
|
||||
|
@ -39,11 +39,12 @@ class SenderField extends Component {
|
||||
}
|
||||
|
||||
onChange(event) {
|
||||
const { onValueChange = () => {} } = this.props.onValueChange;
|
||||
const emailAddress = event.target.value.toLowerCase();
|
||||
this.setState({
|
||||
emailAddress,
|
||||
});
|
||||
this.props.onValueChange({
|
||||
onValueChange({
|
||||
...event,
|
||||
target: {
|
||||
...event.target,
|
||||
@ -178,10 +179,5 @@ SenderField.propTypes = {
|
||||
onValueChange: PropTypes.func,
|
||||
};
|
||||
|
||||
SenderField.defaultProps = {
|
||||
onValueChange: function onValueChange() {
|
||||
// no-op
|
||||
},
|
||||
};
|
||||
SenderField.displayName = 'SenderField';
|
||||
export { SenderField };
|
||||
|
@ -5,20 +5,28 @@ import { Select } from 'common/form/select/select.tsx';
|
||||
// eslint-disable-next-line react/prefer-stateless-function
|
||||
class TimeSelect extends Component {
|
||||
render() {
|
||||
const options = Object.keys(this.props.timeOfDayItems).map((value) => (
|
||||
<option key={`option-${this.props.timeOfDayItems[value]}`} value={value}>
|
||||
{this.props.timeOfDayItems[value]}
|
||||
const {
|
||||
onChange,
|
||||
timeOfDayItems,
|
||||
value,
|
||||
disabled = false,
|
||||
name = 'time',
|
||||
validation = {},
|
||||
} = this.props;
|
||||
const options = Object.keys(timeOfDayItems).map((val) => (
|
||||
<option key={`option-${timeOfDayItems[value]}`} value={val}>
|
||||
{timeOfDayItems[val]}
|
||||
</option>
|
||||
));
|
||||
|
||||
return (
|
||||
<Select
|
||||
name={this.props.name || 'time'}
|
||||
value={this.props.value}
|
||||
disabled={this.props.disabled}
|
||||
onChange={this.props.onChange}
|
||||
name={name || 'time'}
|
||||
value={value}
|
||||
disabled={disabled}
|
||||
onChange={onChange}
|
||||
isMinWidth
|
||||
{...this.props.validation}
|
||||
{...validation}
|
||||
>
|
||||
{options}
|
||||
</Select>
|
||||
@ -35,10 +43,5 @@ TimeSelect.propTypes = {
|
||||
validation: PropTypes.object, // eslint-disable-line react/forbid-prop-types
|
||||
};
|
||||
|
||||
TimeSelect.defaultProps = {
|
||||
name: 'time',
|
||||
disabled: false,
|
||||
validation: {},
|
||||
};
|
||||
TimeSelect.displayName = 'TimeSelect';
|
||||
export { TimeSelect };
|
||||
|
@ -134,7 +134,13 @@ SendingStatusListing.propTypes = {
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
function StatsLink({ newsletter }) {
|
||||
function StatsLink({
|
||||
newsletter = {
|
||||
id: null,
|
||||
subject: null,
|
||||
sent: false,
|
||||
},
|
||||
}) {
|
||||
if (!newsletter.id || !newsletter.subject || !newsletter.sent) return null;
|
||||
return (
|
||||
<p>
|
||||
@ -150,16 +156,8 @@ StatsLink.propTypes = {
|
||||
sent: PropTypes.bool,
|
||||
}),
|
||||
};
|
||||
StatsLink.defaultProps = {
|
||||
newsletter: {
|
||||
id: null,
|
||||
subject: null,
|
||||
sent: false,
|
||||
},
|
||||
};
|
||||
|
||||
function ListingItem({
|
||||
error,
|
||||
failed,
|
||||
taskId,
|
||||
processed,
|
||||
@ -167,6 +165,7 @@ function ListingItem({
|
||||
subscriberId,
|
||||
lastName,
|
||||
firstName,
|
||||
error = '',
|
||||
}) {
|
||||
const resend = () => {
|
||||
MailPoet.Ajax.post({
|
||||
@ -263,9 +262,6 @@ ListingItem.propTypes = {
|
||||
processed: PropTypes.number.isRequired,
|
||||
subscriberId: PropTypes.number.isRequired,
|
||||
};
|
||||
ListingItem.defaultProps = {
|
||||
error: '',
|
||||
};
|
||||
ListingItem.displayName = 'ListingItem';
|
||||
SendingStatus.displayName = 'SendingStatus';
|
||||
export { SendingStatus };
|
||||
|
@ -91,7 +91,7 @@ class TemplateBox extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { index, name, thumbnail, readonly } = this.props;
|
||||
const { index, name, readonly, thumbnail = null } = this.props;
|
||||
|
||||
let preview = '';
|
||||
if (typeof thumbnail === 'string' && thumbnail.length > 0) {
|
||||
@ -151,8 +151,5 @@ TemplateBox.propTypes = {
|
||||
afterSelect: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
TemplateBox.defaultProps = {
|
||||
thumbnail: null,
|
||||
};
|
||||
TemplateBox.displayName = 'TemplateBox';
|
||||
export { TemplateBox };
|
||||
|
@ -29,8 +29,8 @@ const MenuItem = WpMenuItem as React.FC<
|
||||
>;
|
||||
|
||||
function NewsletterTypesComponent({
|
||||
filter,
|
||||
history,
|
||||
filter = null,
|
||||
hideScreenOptions = true,
|
||||
}: Props): JSX.Element {
|
||||
const [isCreating, setIsCreating] = useState(false);
|
||||
@ -291,11 +291,6 @@ function NewsletterTypesComponent({
|
||||
);
|
||||
}
|
||||
|
||||
NewsletterTypesComponent.defaultProps = {
|
||||
filter: null,
|
||||
hideScreenOptions: true,
|
||||
};
|
||||
|
||||
export const NewsletterTypes = withRouter(
|
||||
NewsletterTypesComponent as ComponentType<RouteComponentProps>,
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { Notice } from 'notices/notice.tsx';
|
||||
|
||||
function MailerStatusNotice({ error }) {
|
||||
function MailerStatusNotice({ error = null }) {
|
||||
if (!error || error.operation !== 'authorization') return null;
|
||||
return (
|
||||
<Notice type="error" timeout={false} closable={false}>
|
||||
@ -15,8 +15,5 @@ MailerStatusNotice.propTypes = {
|
||||
error_message: PropTypes.string,
|
||||
}),
|
||||
};
|
||||
MailerStatusNotice.defaultProps = {
|
||||
error: null,
|
||||
};
|
||||
|
||||
export { MailerStatusNotice };
|
||||
|
@ -22,14 +22,14 @@ type Props = {
|
||||
};
|
||||
|
||||
function Notice({
|
||||
onClose,
|
||||
onDisplay,
|
||||
renderInPlace,
|
||||
timeout,
|
||||
scroll,
|
||||
children,
|
||||
closable,
|
||||
type,
|
||||
closable = true,
|
||||
onClose = undefined,
|
||||
onDisplay = undefined,
|
||||
renderInPlace = false,
|
||||
timeout = 10000,
|
||||
scroll = false,
|
||||
}: Props) {
|
||||
const [hidden, setHidden] = useState(false);
|
||||
const elementRef = useRef(null);
|
||||
@ -88,14 +88,6 @@ function Notice({
|
||||
);
|
||||
}
|
||||
|
||||
Notice.defaultProps = {
|
||||
timeout: 10000,
|
||||
scroll: false,
|
||||
closable: true,
|
||||
renderInPlace: false,
|
||||
onDisplay: undefined,
|
||||
onClose: undefined,
|
||||
};
|
||||
Notice.displayName = 'Notice';
|
||||
const NoticeWithBoundary = withBoundary(Notice);
|
||||
export { NoticeWithBoundary as Notice };
|
||||
|
@ -10,7 +10,7 @@ type Props = {
|
||||
onRequestClose?: () => void;
|
||||
};
|
||||
|
||||
function App({ onRequestClose }: Props) {
|
||||
function App({ onRequestClose = noop }: Props) {
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
|
||||
// use jQuery since some of the targeted notices are added to the DOM using the old
|
||||
@ -36,10 +36,6 @@ function App({ onRequestClose }: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
App.defaultProps = {
|
||||
onRequestClose: noop,
|
||||
};
|
||||
|
||||
// nothing is actually rendered to the container because the <Modal> component uses
|
||||
// ReactDOM.createPortal() but we need an element as a React root on all pages
|
||||
const container = document.getElementById('mailpoet_set_from_address_modal');
|
||||
|
@ -3,11 +3,11 @@ import { MailPoet } from 'mailpoet';
|
||||
import { Button } from 'common/button/button';
|
||||
|
||||
function PreviousNextStepButtons({
|
||||
hidePrevious,
|
||||
isLastStep,
|
||||
canGoNext,
|
||||
onPreviousAction,
|
||||
onNextAction,
|
||||
hidePrevious = false,
|
||||
isLastStep = false,
|
||||
canGoNext = true,
|
||||
onPreviousAction = () => {},
|
||||
onNextAction = () => {},
|
||||
}) {
|
||||
return (
|
||||
<div className="mailpoet-settings-save">
|
||||
@ -40,12 +40,5 @@ PreviousNextStepButtons.propTypes = {
|
||||
onNextAction: PropTypes.func,
|
||||
};
|
||||
|
||||
PreviousNextStepButtons.defaultProps = {
|
||||
hidePrevious: false,
|
||||
isLastStep: false,
|
||||
canGoNext: true,
|
||||
onPreviousAction: () => {},
|
||||
onNextAction: () => {},
|
||||
};
|
||||
PreviousNextStepButtons.displayName = 'PreviousNextStepButtons';
|
||||
export { PreviousNextStepButtons };
|
||||
|
@ -26,9 +26,9 @@ function getPreviousStepLink(importData, subscribersLimitForValidation) {
|
||||
|
||||
function StepDataManipulationComponent({
|
||||
history,
|
||||
stepMethodSelectionData,
|
||||
subscribersLimitForValidation,
|
||||
setStepDataManipulationData,
|
||||
stepMethodSelectionData = undefined,
|
||||
}) {
|
||||
const [selectedSegments, setSelectedSegments] = useState([]);
|
||||
const [updateExistingSubscribers, setUpdateExistingSubscribers] =
|
||||
@ -132,8 +132,4 @@ StepDataManipulationComponent.propTypes = {
|
||||
setStepDataManipulationData: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
StepDataManipulationComponent.defaultProps = {
|
||||
stepMethodSelectionData: undefined,
|
||||
};
|
||||
|
||||
export const StepDataManipulation = withRouter(StepDataManipulationComponent);
|
||||
|
@ -7,7 +7,7 @@ import { matchColumns } from './match-columns.jsx';
|
||||
|
||||
const MAX_SUBSCRIBERS_SHOWN = 10;
|
||||
|
||||
function ColumnDataMatch({ header, subscribers }) {
|
||||
function ColumnDataMatch({ header = [], subscribers }) {
|
||||
const matchedColumnTypes = matchColumns(subscribers, header);
|
||||
return (
|
||||
<tr>
|
||||
@ -43,10 +43,6 @@ ColumnDataMatch.propTypes = {
|
||||
header: PropTypes.arrayOf(PropTypes.string),
|
||||
};
|
||||
|
||||
ColumnDataMatch.defaultProps = {
|
||||
header: [],
|
||||
};
|
||||
|
||||
function Header({ header }) {
|
||||
return (
|
||||
<tr className="mailpoet_header">
|
||||
@ -127,7 +123,7 @@ Subscribers.propTypes = {
|
||||
).isRequired,
|
||||
};
|
||||
|
||||
function MatchTable({ subscribersCount, subscribers, header }) {
|
||||
function MatchTable({ subscribersCount = 0, subscribers = [], header = [] }) {
|
||||
useLayoutEffect(() => {
|
||||
generateColumnSelection();
|
||||
});
|
||||
@ -165,10 +161,4 @@ MatchTable.propTypes = {
|
||||
header: PropTypes.arrayOf(PropTypes.string),
|
||||
};
|
||||
|
||||
MatchTable.defaultProps = {
|
||||
subscribersCount: 0,
|
||||
subscribers: [],
|
||||
header: [],
|
||||
};
|
||||
|
||||
export { MatchTable };
|
||||
|
@ -24,7 +24,13 @@ SingleWarning.propTypes = {
|
||||
subscribers: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
};
|
||||
|
||||
function Warnings({ stepMethodSelectionData }) {
|
||||
function Warnings({
|
||||
stepMethodSelectionData = {
|
||||
invalid: [],
|
||||
duplicate: [],
|
||||
role: [],
|
||||
},
|
||||
}) {
|
||||
const { invalid, duplicate, role } = stepMethodSelectionData;
|
||||
|
||||
const [detailsShown, setDetailsShown] = useState(false);
|
||||
@ -125,12 +131,4 @@ Warnings.propTypes = {
|
||||
}),
|
||||
};
|
||||
|
||||
Warnings.defaultProps = {
|
||||
stepMethodSelectionData: {
|
||||
invalid: [],
|
||||
duplicate: [],
|
||||
role: [],
|
||||
},
|
||||
};
|
||||
|
||||
export { Warnings };
|
||||
|
@ -22,8 +22,8 @@ type Props = {
|
||||
};
|
||||
|
||||
function StepInputValidationComponent({
|
||||
stepMethodSelectionData,
|
||||
history,
|
||||
stepMethodSelectionData = undefined,
|
||||
}: Props): JSX.Element {
|
||||
const [importSource, setImportSource] = useState(undefined);
|
||||
const [lastSent, setLastSent] = useState(undefined);
|
||||
@ -69,10 +69,6 @@ function StepInputValidationComponent({
|
||||
);
|
||||
}
|
||||
|
||||
StepInputValidationComponent.defaultProps = {
|
||||
stepMethodSelectionData: undefined,
|
||||
};
|
||||
|
||||
StepInputValidationComponent.displayName = 'StepInputValidationComponent';
|
||||
|
||||
export const StepInputValidation = withRouter(
|
||||
|
@ -7,7 +7,7 @@ import { Selection } from 'form/fields/selection.jsx';
|
||||
import ReactStringReplace from 'react-string-replace';
|
||||
import { PreviousNextStepButtons } from '../previous-next-step-buttons.jsx';
|
||||
|
||||
function MethodMailChimp({ onFinish, onPrevious }) {
|
||||
function MethodMailChimp({ onFinish = () => {}, onPrevious = () => {} }) {
|
||||
const [key, setKey] = useState('');
|
||||
const [mailChimpLoadedLists, setMailChimpLoadedLists] = useState(undefined);
|
||||
const [selectedLists, setSelectedLists] = useState([]);
|
||||
@ -148,11 +148,6 @@ MethodMailChimp.propTypes = {
|
||||
onPrevious: PropTypes.func,
|
||||
};
|
||||
|
||||
MethodMailChimp.defaultProps = {
|
||||
onFinish: () => {},
|
||||
onPrevious: () => {},
|
||||
};
|
||||
|
||||
MethodMailChimp.displayName = 'MethodMailChimp';
|
||||
|
||||
export { MethodMailChimp };
|
||||
|
@ -10,7 +10,13 @@ const kbLink =
|
||||
const placeholder =
|
||||
'Email, First Name, Last Name\njohn@doe.com, John, Doe\nmary@smith.com, Mary, Smith\njohnny@walker.com, Johnny, Walker';
|
||||
|
||||
function MethodPaste({ onValueChange, canFinish, onFinish, data, onPrevious }) {
|
||||
function MethodPaste({
|
||||
canFinish,
|
||||
onValueChange,
|
||||
data = '',
|
||||
onFinish = () => {},
|
||||
onPrevious = () => {},
|
||||
}) {
|
||||
const onChange = (e) => {
|
||||
onValueChange(e.target.value);
|
||||
};
|
||||
@ -64,10 +70,5 @@ MethodPaste.propTypes = {
|
||||
data: PropTypes.string,
|
||||
};
|
||||
|
||||
MethodPaste.defaultProps = {
|
||||
onFinish: () => {},
|
||||
onPrevious: () => {},
|
||||
data: '',
|
||||
};
|
||||
MethodPaste.displayName = 'MethodPaste';
|
||||
export { MethodPaste };
|
||||
|
@ -7,7 +7,12 @@ import { PreviousNextStepButtons } from '../previous-next-step-buttons.jsx';
|
||||
const kbLink =
|
||||
'https://kb.mailpoet.com/article/126-importing-subscribers-with-csv-files';
|
||||
|
||||
function MethodUpload({ onValueChange, canFinish, onFinish, onPrevious }) {
|
||||
function MethodUpload({
|
||||
onValueChange,
|
||||
canFinish,
|
||||
onFinish = () => {},
|
||||
onPrevious = () => {},
|
||||
}) {
|
||||
const onChange = (e) => {
|
||||
const ext = e.target.value.match(/[^.]+$/);
|
||||
MailPoet.Notice.hide();
|
||||
@ -66,9 +71,5 @@ MethodUpload.propTypes = {
|
||||
onValueChange: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
MethodUpload.defaultProps = {
|
||||
onFinish: () => {},
|
||||
onPrevious: () => {},
|
||||
};
|
||||
MethodUpload.displayName = 'MethodUpload';
|
||||
export { MethodUpload };
|
||||
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
||||
import { Radio } from 'common/form/radio/radio';
|
||||
import { Tag } from 'common/tag/tag';
|
||||
|
||||
function SelectImportMethod({ activeMethod, onMethodChange }) {
|
||||
function SelectImportMethod({ onMethodChange, activeMethod = undefined }) {
|
||||
return (
|
||||
<>
|
||||
<div className="mailpoet-settings-label">
|
||||
@ -74,8 +74,5 @@ SelectImportMethod.propTypes = {
|
||||
onMethodChange: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
SelectImportMethod.defaultProps = {
|
||||
activeMethod: undefined,
|
||||
};
|
||||
SelectImportMethod.displayName = 'SelectImportMethod';
|
||||
export { SelectImportMethod };
|
||||
|
@ -8,7 +8,11 @@ import ReactStringReplace from 'react-string-replace';
|
||||
import { Button } from 'common/button/button';
|
||||
import { ErrorBoundary } from 'common';
|
||||
|
||||
function ResultMessage({ subscribersCount, segments, initialMessage }) {
|
||||
function ResultMessage({
|
||||
subscribersCount = 0,
|
||||
segments = [],
|
||||
initialMessage = '',
|
||||
}) {
|
||||
if (subscribersCount) {
|
||||
let message = ReactStringReplace(initialMessage, '%1$s', () => (
|
||||
<strong key="%1$s">{subscribersCount.toLocaleString()}</strong>
|
||||
@ -29,14 +33,9 @@ ResultMessage.propTypes = {
|
||||
initialMessage: PropTypes.string,
|
||||
};
|
||||
|
||||
ResultMessage.defaultProps = {
|
||||
segments: [],
|
||||
subscribersCount: 0,
|
||||
initialMessage: '',
|
||||
};
|
||||
ResultMessage.displayName = 'ResultMessage';
|
||||
|
||||
function NoAction({ createdSubscribers, updatedSubscribers }) {
|
||||
function NoAction({ createdSubscribers = 0, updatedSubscribers = 0 }) {
|
||||
if (!createdSubscribers && !updatedSubscribers) {
|
||||
return <p>{MailPoet.I18n.t('importNoAction')}</p>;
|
||||
}
|
||||
@ -48,13 +47,12 @@ NoAction.propTypes = {
|
||||
updatedSubscribers: PropTypes.number,
|
||||
};
|
||||
|
||||
NoAction.defaultProps = {
|
||||
createdSubscribers: 0,
|
||||
updatedSubscribers: 0,
|
||||
};
|
||||
NoAction.displayName = 'NoAction';
|
||||
|
||||
function SuppressionListReminder({ createdSubscribers, updatedSubscribers }) {
|
||||
function SuppressionListReminder({
|
||||
createdSubscribers = 0,
|
||||
updatedSubscribers = 0,
|
||||
}) {
|
||||
if (createdSubscribers || updatedSubscribers) {
|
||||
return (
|
||||
<>
|
||||
@ -89,13 +87,9 @@ SuppressionListReminder.propTypes = {
|
||||
updatedSubscribers: PropTypes.number,
|
||||
};
|
||||
|
||||
SuppressionListReminder.defaultProps = {
|
||||
createdSubscribers: 0,
|
||||
updatedSubscribers: 0,
|
||||
};
|
||||
SuppressionListReminder.displayName = 'SuppressionListReminder';
|
||||
|
||||
function NoWelcomeEmail({ addedToSegmentWithWelcomeNotification }) {
|
||||
function NoWelcomeEmail({ addedToSegmentWithWelcomeNotification = false }) {
|
||||
if (addedToSegmentWithWelcomeNotification) {
|
||||
return <p>{MailPoet.I18n.t('importNoWelcomeEmail')}</p>;
|
||||
}
|
||||
@ -106,18 +100,15 @@ NoWelcomeEmail.propTypes = {
|
||||
addedToSegmentWithWelcomeNotification: PropTypes.bool,
|
||||
};
|
||||
|
||||
NoWelcomeEmail.defaultProps = {
|
||||
addedToSegmentWithWelcomeNotification: false,
|
||||
};
|
||||
NoWelcomeEmail.diplayName = 'NoWelcomeEmail';
|
||||
|
||||
function StepResultsComponent({
|
||||
errors,
|
||||
createdSubscribers,
|
||||
updatedSubscribers,
|
||||
segments,
|
||||
addedToSegmentWithWelcomeNotification,
|
||||
history,
|
||||
errors = [],
|
||||
createdSubscribers = undefined,
|
||||
updatedSubscribers = undefined,
|
||||
segments = undefined,
|
||||
addedToSegmentWithWelcomeNotification = undefined,
|
||||
}) {
|
||||
useEffect(() => {
|
||||
if (
|
||||
@ -204,12 +195,5 @@ StepResultsComponent.propTypes = {
|
||||
addedToSegmentWithWelcomeNotification: PropTypes.bool,
|
||||
};
|
||||
|
||||
StepResultsComponent.defaultProps = {
|
||||
errors: [],
|
||||
segments: undefined,
|
||||
createdSubscribers: undefined,
|
||||
updatedSubscribers: undefined,
|
||||
addedToSegmentWithWelcomeNotification: undefined,
|
||||
};
|
||||
StepResultsComponent.displayName = 'StepResultsComponent';
|
||||
export const StepResults = withRouter(StepResultsComponent);
|
||||
|
@ -38,6 +38,7 @@ module.exports = [
|
||||
'no-underscore-dangle': 0, // Backbone uses underscores, we cannot remove them
|
||||
'import/no-default-export': 1, // no default exports
|
||||
'no-only-tests/no-only-tests': 2,
|
||||
'react/require-default-props': 0, // deprecated in react 18.3.1
|
||||
'check-file/filename-naming-convention': [
|
||||
'error',
|
||||
{ '**/*.*': 'KEBAB_CASE' },
|
||||
|
@ -47,6 +47,7 @@ module.exports = [
|
||||
'no-only-tests/no-only-tests': 2,
|
||||
'class-methods-use-this': 0,
|
||||
'react/jsx-props-no-spreading': 0,
|
||||
'react/require-default-props': 0, // deprecated in react 18.3.1
|
||||
'import/extensions': 0, // we wouldn't be able to import jQuery without this line
|
||||
'import/prefer-default-export': 0, // we want to stop using default exports and start using named exports
|
||||
'import/no-default-export': 1, // no default exports
|
||||
|
Reference in New Issue
Block a user