diff --git a/assets/js/src/experimental_features/experimental_features.jsx b/assets/js/src/experimental_features/experimental_features.jsx index d13c0ffb95..50c59138e9 100644 --- a/assets/js/src/experimental_features/experimental_features.jsx +++ b/assets/js/src/experimental_features/experimental_features.jsx @@ -7,24 +7,28 @@ import Notices from 'notices/notices.jsx'; const ExperimentalFeatures = () => { const [flags, setFlags] = useState(null); const contextValue = useGlobalContextValue(window); + const [mounted, setMounted] = useState(false); useEffect(() => { - MailPoet.Ajax.post({ - api_version: window.mailpoet_api_version, - endpoint: 'featureFlags', - action: 'getAll', - }).done((response) => { - const flagsMap = response.data.reduce((obj, item) => ({ ...obj, [item.name]: item }), {}); - setFlags(flagsMap); - }).fail((response) => { - if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), - { scroll: true } - ); - } - }); - }, []); + if (!mounted) { + MailPoet.Ajax.post({ + api_version: window.mailpoet_api_version, + endpoint: 'featureFlags', + action: 'getAll', + }).done((response) => { + const flagsMap = response.data.reduce((obj, item) => ({ ...obj, [item.name]: item }), {}); + setFlags(flagsMap); + }).fail((response) => { + if (response.errors.length > 0) { + contextValue.notices.error( + <>{response.errors.map((error) =>

{error.message}

)}, + { scroll: true } + ); + } + }); + setMounted(true); + } + }, [contextValue.notices, mounted]); function handleChange(event) { const name = event.target.name; @@ -41,11 +45,12 @@ const ExperimentalFeatures = () => { const flag = flags[name]; flag.value = value; setFlags({ ...flags, [name]: flag }); - MailPoet.Notice.success(`Feature '${name}' was ${value ? 'enabled' : 'disabled'}.`); + const message = `Feature '${name}' was ${value ? 'enabled' : 'disabled'}.`; + contextValue.notices.success(

{message}

); }).fail((response) => { if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + contextValue.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); } diff --git a/assets/js/src/listing/listing.jsx b/assets/js/src/listing/listing.jsx index 166e928d70..2b20c901cb 100644 --- a/assets/js/src/listing/listing.jsx +++ b/assets/js/src/listing/listing.jsx @@ -13,6 +13,7 @@ import ListingFilters from 'listing/filters.jsx'; import ListingItems from 'listing/listing_items.jsx'; import MailerError from 'listing/notices.jsx'; import { withRouter } from 'react-router-dom'; +import { GlobalContext } from 'context/index.jsx'; class Listing extends React.Component { constructor(props) { @@ -190,8 +191,8 @@ class Listing extends React.Component { }); }).fail((response) => { if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); } @@ -266,8 +267,8 @@ class Listing extends React.Component { } this.getItems(); }).fail((response) => { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); }); @@ -295,8 +296,8 @@ class Listing extends React.Component { } this.getItems(); }).fail((response) => { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); }); @@ -324,8 +325,8 @@ class Listing extends React.Component { } this.getItems(); }).fail((response) => { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); }); @@ -344,8 +345,8 @@ class Listing extends React.Component { // redirect to default group this.handleGroup('all'); }).fail((response) => { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); }); @@ -383,8 +384,8 @@ class Listing extends React.Component { this.getItems(); }).fail((response) => { if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); } @@ -685,6 +686,8 @@ class Listing extends React.Component { } } +Listing.contextType = GlobalContext; + /* eslint-disable react/require-default-props */ Listing.propTypes = { limit: PropTypes.number, diff --git a/assets/js/src/newsletters/automatic_emails/events_conditions.jsx b/assets/js/src/newsletters/automatic_emails/events_conditions.jsx index da9c7b6d7b..179d26aa08 100644 --- a/assets/js/src/newsletters/automatic_emails/events_conditions.jsx +++ b/assets/js/src/newsletters/automatic_emails/events_conditions.jsx @@ -6,6 +6,7 @@ import EventOptions from 'newsletters/automatic_emails/events/event_options.jsx' import MailPoet from 'mailpoet'; import _ from 'underscore'; import PropTypes from 'prop-types'; +import { GlobalContext } from 'context/index.jsx'; const defaultAfterTimeType = 'immediate'; const defaultAfterTimeNumber = 1; @@ -205,8 +206,8 @@ class EventsConditions extends React.Component { history.push(`/template/${response.data.id}`); }).fail((response) => { if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); } @@ -245,6 +246,8 @@ class EventsConditions extends React.Component { } } +EventsConditions.contextType = GlobalContext; + EventsConditions.propTypes = { history: PropTypes.shape({ push: PropTypes.func.isRequired, diff --git a/assets/js/src/newsletters/send.jsx b/assets/js/src/newsletters/send.jsx index f260efefa8..9209901572 100644 --- a/assets/js/src/newsletters/send.jsx +++ b/assets/js/src/newsletters/send.jsx @@ -15,6 +15,7 @@ import { withRouter } from 'react-router-dom'; import ReactStringReplace from 'react-string-replace'; import SubscribersLimitNotice from 'notices/subscribers_limit_notice.jsx'; import slugify from 'slugify'; +import { GlobalContext } from 'context/index.jsx'; const generateGaTrackingCampaignName = (id, subject) => { const name = slugify(subject, { lower: true }) @@ -242,16 +243,16 @@ class NewsletterSend extends React.Component { if (_.isFunction(customResponse)) { customResponse(); } else if (response.data.status === 'scheduled') { - MailPoet.Notice.success( - MailPoet.I18n.t('newsletterHasBeenScheduled') + this.context.notices.success( +

{MailPoet.I18n.t('newsletterHasBeenScheduled')}

); MailPoet.trackEvent('Emails > Newsletter sent', { scheduled: true, 'MailPoet Free version': window.mailpoet_version, }); } else { - MailPoet.Notice.success( - MailPoet.I18n.t('newsletterBeingSent'), + this.context.notices.success( +

{MailPoet.I18n.t('newsletterBeingSent')}

, { id: 'mailpoet_notice_being_sent' } ); MailPoet.trackEvent('Emails > Newsletter sent', { @@ -288,8 +289,8 @@ class NewsletterSend extends React.Component { const opts = this.state.item.options; // display success message depending on newsletter type if (response.data.type === 'welcome') { - MailPoet.Notice.success( - MailPoet.I18n.t('welcomeEmailActivated') + this.context.notices.success( +

{MailPoet.I18n.t('welcomeEmailActivated')}

); MailPoet.trackEvent('Emails > Welcome email activated', { 'MailPoet Free version': window.mailpoet_version, @@ -297,8 +298,8 @@ class NewsletterSend extends React.Component { Delay: `${opts.afterTimeNumber} ${opts.afterTimeType}`, }); } else if (response.data.type === 'notification') { - MailPoet.Notice.success( - MailPoet.I18n.t('postNotificationActivated') + this.context.notices.success( +

{MailPoet.I18n.t('postNotificationActivated')}

); MailPoet.trackEvent('Emails > Post notifications activated', { 'MailPoet Free version': window.mailpoet_version, @@ -330,16 +331,11 @@ class NewsletterSend extends React.Component { }, }).done(() => { this.props.history.push(`/${this.state.item.type || ''}`); - MailPoet.Notice.success( - MailPoet.I18n.t('newsletterSendingHasBeenResumed') + this.context.notices.success( +

{MailPoet.I18n.t('newsletterSendingHasBeenResumed')}

); }).fail((response) => { - if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), - { scroll: true } - ); - } + this.showError(response); }); }) .fail((err) => { @@ -356,8 +352,8 @@ class NewsletterSend extends React.Component { e.preventDefault(); this.saveNewsletter(e).done(() => { - MailPoet.Notice.success( - MailPoet.I18n.t('newsletterUpdated') + this.context.notices.success( +

{MailPoet.I18n.t('newsletterUpdated')}

); }).done(() => { const path = this.state.item.type === 'automatic' ? this.state.item.options.group : this.state.item.type; @@ -372,8 +368,8 @@ class NewsletterSend extends React.Component { const redirectTo = e.target.href; this.saveNewsletter(e).done(() => { - MailPoet.Notice.success( - MailPoet.I18n.t('newsletterUpdated') + this.context.notices.success( +

{MailPoet.I18n.t('newsletterUpdated')}

); }).done(() => { window.location = redirectTo; @@ -407,8 +403,8 @@ class NewsletterSend extends React.Component { showError = (response) => { if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); } @@ -528,6 +524,8 @@ class NewsletterSend extends React.Component { } } +NewsletterSend.contextType = GlobalContext; + NewsletterSend.propTypes = { match: PropTypes.shape({ params: PropTypes.shape({ diff --git a/assets/js/src/newsletters/templates.jsx b/assets/js/src/newsletters/templates.jsx index e23148f8d2..16e7ee536d 100644 --- a/assets/js/src/newsletters/templates.jsx +++ b/assets/js/src/newsletters/templates.jsx @@ -8,6 +8,7 @@ import ImportTemplate from 'newsletters/templates/import_template.jsx'; import Hooks from 'wp-js-hooks'; import _ from 'underscore'; import PropTypes from 'prop-types'; +import { GlobalContext } from 'context/index.jsx'; const getEditorUrl = (id) => `admin.php?page=mailpoet-newsletter-editor&id=${id}`; @@ -87,8 +88,8 @@ class NewsletterTemplates extends React.Component { this.sortTemplates(); }).fail((response) => { if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); } @@ -158,8 +159,8 @@ class NewsletterTemplates extends React.Component { } }).fail((response) => { if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); } @@ -277,6 +278,8 @@ class NewsletterTemplates extends React.Component { } } +NewsletterTemplates.contextType = GlobalContext; + NewsletterTemplates.propTypes = { match: PropTypes.shape({ params: PropTypes.shape({ diff --git a/assets/js/src/newsletters/templates/import_template.jsx b/assets/js/src/newsletters/templates/import_template.jsx index df84417a7f..473d1d4da2 100644 --- a/assets/js/src/newsletters/templates/import_template.jsx +++ b/assets/js/src/newsletters/templates/import_template.jsx @@ -3,6 +3,7 @@ import _ from 'underscore'; import MailPoet from 'mailpoet'; import HelpTooltip from 'help-tooltip.jsx'; import PropTypes from 'prop-types'; +import { GlobalContext } from 'context/index.jsx'; class ImportTemplate extends React.Component { constructor(props) { @@ -51,8 +52,8 @@ class ImportTemplate extends React.Component { afterImport(true, response.data); }).fail((response) => { if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); } @@ -77,7 +78,7 @@ class ImportTemplate extends React.Component { 'MailPoet Free version': window.mailpoet_version, }); } catch (err) { - MailPoet.Notice.error(MailPoet.I18n.t('templateFileMalformedError')); + this.context.notices.error(

{MailPoet.I18n.t('templateFileMalformedError')}

); } }; @@ -115,6 +116,8 @@ class ImportTemplate extends React.Component { } } +ImportTemplate.contextType = GlobalContext; + ImportTemplate.propTypes = { beforeImport: PropTypes.func.isRequired, afterImport: PropTypes.func.isRequired, diff --git a/assets/js/src/newsletters/templates/template_box.jsx b/assets/js/src/newsletters/templates/template_box.jsx index 4658f5c60e..cb18c529e8 100644 --- a/assets/js/src/newsletters/templates/template_box.jsx +++ b/assets/js/src/newsletters/templates/template_box.jsx @@ -3,6 +3,7 @@ import MailPoet from 'mailpoet'; import PropTypes from 'prop-types'; import confirmAlert from 'common/confirm_alert.jsx'; +import { GlobalContext } from 'context/index.jsx'; /** * props = { @@ -35,8 +36,8 @@ class TemplateBox extends React.Component { afterDelete(true, id); }).fail((response) => { if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); } @@ -81,8 +82,8 @@ class TemplateBox extends React.Component { afterSelect(true, response.data.id); }).fail((response) => { if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); } @@ -158,6 +159,8 @@ class TemplateBox extends React.Component { } } +TemplateBox.contextType = GlobalContext; + TemplateBox.propTypes = { index: PropTypes.number.isRequired, id: PropTypes.string.isRequired, diff --git a/assets/js/src/newsletters/types.jsx b/assets/js/src/newsletters/types.jsx index 13d669ae11..5b928d64f1 100644 --- a/assets/js/src/newsletters/types.jsx +++ b/assets/js/src/newsletters/types.jsx @@ -5,6 +5,7 @@ import Breadcrumb from 'newsletters/breadcrumb.jsx'; import Hooks from 'wp-js-hooks'; import _ from 'underscore'; import { withRouter } from 'react-router-dom'; +import { GlobalContext } from 'context/index.jsx'; class NewsletterTypes extends React.Component { constructor(props) { @@ -108,7 +109,12 @@ class NewsletterTypes extends React.Component { 'MailPoet Free version': window.mailpoet_version, }); } catch (response) { - MailPoet.Notice.showApiErrorNotice(response, { scroll: true }); + if (response.errors.length > 0) { + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), + { scroll: true } + ); + } return; } } @@ -134,8 +140,8 @@ class NewsletterTypes extends React.Component { }).fail((response) => { this.setState({ isCreating: false }); if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); } @@ -289,6 +295,8 @@ class NewsletterTypes extends React.Component { } } +NewsletterTypes.contextType = GlobalContext; + NewsletterTypes.propTypes = { filter: PropTypes.func, history: PropTypes.shape({ diff --git a/assets/js/src/newsletters/types/notification/notification.jsx b/assets/js/src/newsletters/types/notification/notification.jsx index df1b59944d..dcfe8a8271 100644 --- a/assets/js/src/newsletters/types/notification/notification.jsx +++ b/assets/js/src/newsletters/types/notification/notification.jsx @@ -5,6 +5,7 @@ import Breadcrumb from 'newsletters/breadcrumb.jsx'; import _ from 'underscore'; import Scheduling from 'newsletters/types/notification/scheduling.jsx'; import { withRouter } from 'react-router-dom'; +import { GlobalContext } from 'context/index.jsx'; const field = { name: 'options', @@ -45,8 +46,8 @@ class NewsletterNotification extends React.Component { this.showTemplateSelection(response.data.id); }).fail((response) => { if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); } @@ -84,6 +85,8 @@ class NewsletterNotification extends React.Component { } } +NewsletterNotification.contextType = GlobalContext; + NewsletterNotification.propTypes = { history: PropTypes.shape({ push: PropTypes.func.isRequired, diff --git a/assets/js/src/newsletters/types/standard.jsx b/assets/js/src/newsletters/types/standard.jsx index fcaebccf41..7efd124acc 100644 --- a/assets/js/src/newsletters/types/standard.jsx +++ b/assets/js/src/newsletters/types/standard.jsx @@ -3,6 +3,7 @@ import React from 'react'; import MailPoet from 'mailpoet'; import Breadcrumb from 'newsletters/breadcrumb.jsx'; import { withRouter } from 'react-router-dom'; +import { GlobalContext } from 'context/index.jsx'; class NewsletterStandard extends React.Component { componentDidMount() { @@ -18,8 +19,8 @@ class NewsletterStandard extends React.Component { this.showTemplateSelection(response.data.id); }).fail((response) => { if (response.errors.length > 0) { - MailPoet.Notice.error( - response.errors.map((error) => error.message), + this.context.notices.error( + response.errors.map((error) =>

{error.message}

), { scroll: true } ); } @@ -40,6 +41,8 @@ class NewsletterStandard extends React.Component { } } +NewsletterStandard.contextType = GlobalContext; + NewsletterStandard.propTypes = { history: PropTypes.shape({ push: PropTypes.func.isRequired,