Checkbox implementation and refactor naming structure

[MAILPOET-3920]
This commit is contained in:
Mike Jolley 2021-11-03 15:14:52 +00:00 committed by Veljko V
parent 0f5b7d0ac7
commit 72d4db26e3
18 changed files with 393 additions and 253 deletions

View File

@ -0,0 +1,12 @@
/**
* External dependencies
*/
import { getSetting } from '@woocommerce/settings';
const { defaultText } = getSetting('mailpoet_data');
export default {
text: {
type: 'string',
default: defaultText,
},
};

View File

@ -1,8 +1,8 @@
{
"apiVersion": 2,
"name": "mailpoet/newsletter-block",
"name": "mailpoet/marketing-optin-block",
"version": "0.1.0",
"title": "MailPoet Subscribe to Newsletter block",
"title": "MailPoet Marketing Opt-in",
"category": "woocommerce",
"textdomain": "mailpoet",
"supports": {
@ -22,8 +22,6 @@
}
},
"parent": ["woocommerce/checkout-contact-information-block"],
"script": "file:../../../dist/js/newsletter_block/newsletter_block_frontend.js",
"style": "file:../../../dist/js/newsletter_block/newsletter_block.css",
"editorScript": "file:../../../dist/js/newsletter_block/newsletter_block.js",
"editorStyle": "file:../../../dist/js/newsletter_block/newsletter_block.css"
"editorScript": "file:../../../dist/js/marketing_optin_block/marketing-optin-block.js",
"editorStyle": "file:../../../dist/js/marketing_optin_block/marketing-optin-block.css"
}

View File

@ -0,0 +1,50 @@
/* eslint-disable react/react-in-jsx-scope */
/* eslint-disable import/no-unresolved */
/**
* External dependencies
*/
import { CheckboxControl } from '@woocommerce/blocks-checkout';
import { useState, useEffect } from '@wordpress/element';
import { getSetting } from '@woocommerce/settings';
const { optinEnabled, defaultText, defaultStatus } = getSetting('mailpoet_data');
const Block = (
{
text,
checkoutExtensionData,
}: {
text: string,
checkoutExtensionData: {
setExtensionData: (namespace: string, key: string, value: unknown) => void
}
}
): JSX.Element => {
const [checked, setChecked] = useState(defaultStatus);
const { setExtensionData } = checkoutExtensionData || {};
useEffect(() => {
if (optinEnabled && setExtensionData) {
setExtensionData('mailpoet', 'optin', checked);
}
}, [checked, setExtensionData]);
if (!optinEnabled) {
return null;
}
return (
<CheckboxControl
checked={checked}
onChange={setChecked}
>
{/* eslint-disable-next-line react/no-danger */}
<span dangerouslySetInnerHTML={{
__html: text || defaultText,
}}
/>
</CheckboxControl>
);
};
export default Block;

View File

@ -16,34 +16,32 @@ import { Icon, megaphone } from '@wordpress/icons';
*/
import './editor.scss';
const adminUrl = getSetting('adminUrl');
const { newsletterEnabled, newsletterDefaultText } = getSetting('mailpoet_data');
const adminUrl = getSetting('adminUrl') as string;
const { optinEnabled, defaultText } = getSetting('mailpoet_data');
const EmptyState = () => {
return (
<Placeholder
icon={<Icon icon={megaphone} />}
label={__('Marketing opt-in', 'automatewoo')}
className="wp-block-mailpoet-newsletter-block-placeholder"
const EmptyState = (): JSX.Element => (
<Placeholder
icon={<Icon icon={megaphone} />}
label={__('Marketing opt-in', 'mailpoet')}
className="wp-block-mailpoet-newsletter-block-placeholder"
>
<span className="wp-block-mailpoet-newsletter-block-placeholder__description">
{__(
'MailPoet marketing opt-in would be shown here if enabled. You can enable from the settings page.',
'mailpoet'
)}
</span>
<Button
isPrimary
href={`${adminUrl}admin.php?page=mailpoet-settings#/woocommerce`}
target="_blank"
rel="noopener noreferrer"
className="wp-block-mailpoet-newsletter-block-placeholder__button"
>
<span className="wp-block-mailpoet-newsletter-block-placeholder__description">
{__(
'MailPoet marketing opt in would be shown here, you can enable from AutomateWoo settings page.',
'mailpoet'
)}
</span>
<Button
isPrimary
href={`${adminUrl}admin.php?page=mailpoet-settings#/woocommerce`}
target="_blank"
rel="noopener noreferrer"
className="wp-block-mailpoet-newsletter-block-placeholder__button"
>
{__('Enable opt-in for Checkout', 'automatewoo')}
</Button>
</Placeholder>
);
};
{__('Enable opt-in for Checkout', 'mailpoet')}
</Button>
</Placeholder>
);
export const Edit = ({
attributes: { text },
@ -53,10 +51,10 @@ export const Edit = ({
setAttributes: (attributes: Record<string, unknown>) => void;
}): JSX.Element => {
const blockProps = useBlockProps();
const currentText = text || newsletterDefaultText;
const currentText = text || defaultText;
return (
<div {...blockProps}>
{newsletterEnabled ? (
{!optinEnabled ? (
<>
<div className="wc-block-checkout__newsletter">
<CheckboxControl id="subscribe-to-newsletter" checked={false} />

View File

@ -1,12 +0,0 @@
/**
* External dependencies
*/
import { getSetting } from "@woocommerce/settings";
const { newsletterDefaultText } = getSetting("mailpoet_data");
export default {
text: {
type: "string",
default: newsletterDefaultText,
},
};

View File

@ -1,33 +0,0 @@
/**
* External dependencies
*/
import React from 'react';
import { CheckboxControl } from '@woocommerce/blocks-checkout';
import { useState, useEffect } from '@wordpress/element';
import { getSetting } from '@woocommerce/settings';
const { newsletterEnabled, newsletterDefaultText } = getSetting('mailpoet_data');
const Block = ({ text, checkoutExtensionData }) => {
const [checked, setChecked] = useState(false);
const { setExtensionData } = checkoutExtensionData || {};
useEffect(() => {
if (newsletterEnabled && setExtensionData) {
setExtensionData('mailpoet', 'optin', checked);
}
}, [checked, setExtensionData]);
if (!newsletterEnabled) {
return null;
}
return (
<CheckboxControl
label={text || newsletterDefaultText}
checked={checked}
onChange={setChecked}
/>
);
};
export default Block;

View File

@ -1,3 +0,0 @@
body {
background: red;
}

View File

@ -6,8 +6,8 @@ use MailPoet\API\JSON\API;
use MailPoet\AutomaticEmails\AutomaticEmails;
use MailPoet\Cron\CronTrigger;
use MailPoet\InvalidStateException;
use MailPoet\PostEditorBlocks\NewsletterBlock;
use MailPoet\PostEditorBlocks\PostEditorBlock;
use MailPoet\PostEditorBlocks\WooCommerceBlocksIntegration;
use MailPoet\Router;
use MailPoet\Settings\SettingsController;
use MailPoet\Util\ConflictResolver;
@ -72,8 +72,8 @@ class Initializer {
/** @var \MailPoet\PostEditorBlocks\PostEditorBlock */
private $postEditorBlock;
/** @var \MailPoet\PostEditorBlocks\NewsletterBlock */
private $newsletterBlock;
/** @var \MailPoet\PostEditorBlocks\WooCommerceBlocksIntegration */
private $woocommerceBlocksIntegration;
/** @var Localizer */
private $localizer;
@ -99,7 +99,7 @@ class Initializer {
DatabaseInitializer $databaseInitializer,
WCTransactionalEmails $wcTransactionalEmails,
PostEditorBlock $postEditorBlock,
NewsletterBlock $newsletterBlock,
WooCommerceBlocksIntegration $woocommerceBlocksIntegration,
WooCommerceHelper $wcHelper,
Localizer $localizer,
AssetsLoader $assetsLoader
@ -120,7 +120,7 @@ class Initializer {
$this->wcTransactionalEmails = $wcTransactionalEmails;
$this->wcHelper = $wcHelper;
$this->postEditorBlock = $postEditorBlock;
$this->newsletterBlock = $newsletterBlock;
$this->woocommerceBlocksIntegration = $woocommerceBlocksIntegration;
$this->localizer = $localizer;
$this->assetsLoader = $assetsLoader;
}
@ -236,8 +236,8 @@ class Initializer {
$this->setupPermanentNotices();
$this->setupAutomaticEmails();
$this->setupWoocommerceBlocksIntegration();
$this->postEditorBlock->init();
$this->newsletterBlock->init();
WPFunctions::get()->doAction('mailpoet_initialized', MAILPOET_VERSION);
} catch (InvalidStateException $e) {
@ -389,4 +389,12 @@ class Initializer {
$this->wcTransactionalEmails->useTemplateForWoocommerceEmails();
}
}
private function setupWoocommerceBlocksIntegration() {
$wcEnabled = $this->wcHelper->isWooCommerceActive();
$wcBlocksEnabled = $this->wcHelper->isWooCommerceBlocksActive( '6.3.0-dev' );
if ($wcEnabled && $wcBlocksEnabled) {
$this->woocommerceBlocksIntegration->init();
}
}
}

View File

@ -135,7 +135,7 @@ class ContainerConfigurator implements IContainerConfigurator {
->setFactory([new Reference(\MailPoet\Doctrine\Validator\ValidatorFactory::class), 'createValidator']);
$container->autowire(\MailPoet\PostEditorBlocks\PostEditorBlock::class);
$container->autowire(\MailPoet\PostEditorBlocks\SubscriptionFormBlock::class);
$container->autowire(\MailPoet\PostEditorBlocks\NewsletterBlock::class);
$container->autowire(\MailPoet\PostEditorBlocks\WooCommerceBlocksIntegration::class);
// Cron
$container->autowire(\MailPoet\Cron\CronHelper::class)->setPublic(true);
$container->autowire(\MailPoet\Cron\CronTrigger::class)->setPublic(true);

View File

@ -0,0 +1,83 @@
<?php
namespace MailPoet\PostEditorBlocks;
use Automattic\WooCommerce\Blocks\Integrations\IntegrationInterface;
use MailPoet\Config\Env;
/**
* Class MarketingOptinBlock
*
* Class for integrating marketing optin block with WooCommerce Checkout.
*/
class MarketingOptinBlock implements IntegrationInterface {
/** @var array */
private $options;
public function __construct(
array $options
) {
$this->options = $options;
}
/**
* The name of the integration.
*
* @return string
*/
public function get_name() { // phpcs:ignore
return 'mailpoet';
}
/**
* Register block scripts and assets.
*/
public function initialize() {
$script_asset_path = Env::$assetsUrl . '/dist/js/marketing_optin_block/marketing-optin-block-frontend.asset.php';
$script_asset = file_exists($script_asset_path)
? require $script_asset_path
: [
'dependencies' => [],
'version' => Env::$version,
];
wp_register_script(
'mailpoet-marketing-optin-block-frontend',
Env::$assetsUrl . '/dist/js/marketing_optin_block/marketing-optin-block-frontend.js',
$script_asset['dependencies'],
$script_asset['version'],
true
);
wp_set_script_translations(
'mailpoet-marketing-optin-block-frontend',
'mailpoet',
Env::$languagesPath
);
}
/**
* Returns an array of script handles to enqueue in the frontend context.
*
* @return string[]
*/
public function get_script_handles() { // phpcs:ignore
return ['mailpoet-marketing-optin-block-frontend'];
}
/**
* Returns an array of script handles to enqueue in the editor context.
*
* @return string[]
*/
public function get_editor_script_handles() { // phpcs:ignore
return [];
}
/**
* An array of key, value pairs of data made available to the block on the client side.
*
* @return array
*/
public function get_script_data() { // phpcs:ignore
return $this->options;
}
}

View File

@ -1,93 +0,0 @@
<?php
namespace MailPoet\PostEditorBlocks;
use MailPoet\Config\Env;
use MailPoet\WP\Functions as WPFunctions;
use MailPoet\Settings\SettingsController;
use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;
use Automattic\WooCommerce\Blocks\Package;
use Automattic\WooCommerce\Blocks\Domain\Services\ExtendRestApi;
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\CheckoutSchema;
// @todo Disable if blocks is inactive
class NewsletterBlock {
/** @var SettingsController */
private $settings;
/** @var WPFunctions */
private $wp;
public function __construct(
WPFunctions $wp,
SettingsController $settings
) {
$this->wp = $wp;
$this->settings = $settings;
}
public function init() {
$this->wp->registerBlockType( Env::$assetsPath . '/js/src/newsletter_block' );
$this->wp->addFilter(
'__experimental_woocommerce_blocks_add_data_attributes_to_block',
[$this, 'addDataAttributesToBlock']
);
$this->wp->addAction(
'__experimental_woocommerce_blocks_checkout_update_order_from_request',
[$this, 'process_checkout_block_optin']
);
$this->addScriptData();
$this->extendRestApi();
}
public function addDataAttributesToBlock( array $blocks ) {
$blocks[] = 'mailpoet/newsletter-block';
return $blocks;
}
public function addScriptData() {
$data_registry = Package::container()->get(
AssetDataRegistry::class
);
$data_registry->add( 'mailpoet_data', array(
'newsletterDefaultText' => $this->settings->get('woocommerce.optin_on_checkout.message', ''),
'newsletterEnabled' => $this->settings->get('woocommerce.optin_on_checkout.enabled', false),
) );
}
public function extendRestApi() {
$extend = Package::container()->get(
ExtendRestApi::class
);
$extend->register_endpoint_data(
array(
'endpoint' => CheckoutSchema::IDENTIFIER,
'namespace' => 'mailpoet',
'schema_callback' => function() {
return array(
'newsletter-opt-in' => array(
'description' => __( 'Subscribe to newsletter opt-in.', 'woo-gutenberg-products-block' ),
'type' => 'boolean',
),
);
},
)
);
}
public function process_checkout_block_optin( \WC_Order $order, array $request ) {
if ( ! $this->settings->get('woocommerce.optin_on_checkout.enabled', false) ) {
return;
}
if ( ! $order ) {
return;
}
if ( ! isset( $request['extensions']['mailpoet'][ 'optin' ] ) ) {
return;
}
// @todo do optin
}
}

View File

@ -0,0 +1,109 @@
<?php
namespace MailPoet\PostEditorBlocks;
use Automattic\WooCommerce\Blocks\Domain\Services\ExtendRestApi;
use Automattic\WooCommerce\Blocks\Package;
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\CheckoutSchema;
use MailPoet\Config\Env;
use MailPoet\Models\Subscriber;
use MailPoet\Settings\SettingsController;
use MailPoet\WooCommerce\Subscription as WooCommerceSubscription;
use MailPoet\WP\Functions as WPFunctions;
// @todo Disable if blocks is inactive
class WooCommerceBlocksIntegration {
/** @var SettingsController */
private $settings;
/** @var WPFunctions */
private $wp;
public function __construct(
WPFunctions $wp,
SettingsController $settings,
WooCommerceSubscription $woocommerceSubscription
) {
$this->wp = $wp;
$this->settings = $settings;
$this->woocommerceSubscription = $woocommerceSubscription;
}
public function init() {
$this->wp->addAction(
'woocommerce_blocks_checkout_block_registration',
[$this, 'registerCheckoutFrontendBlocks']
);
$this->wp->addAction(
'__experimental_woocommerce_blocks_checkout_update_order_from_request',
[$this, 'processCheckoutBlockOptin'],
10,
2
);
$this->wp->addFilter(
'__experimental_woocommerce_blocks_add_data_attributes_to_block',
[$this, 'addDataAttributesToBlock']
);
$this->wp->registerBlockType(Env::$assetsPath . '/js/src/marketing_optin_block');
$this->extendRestApi();
}
/**
* Load blocks in frontend with Checkout.
*/
public function registerCheckoutFrontendBlocks($integration_registry) {
$integration_registry->register(new MarketingOptinBlock([
'defaultText' => $this->settings->get('woocommerce.optin_on_checkout.message', ''),
'optinEnabled' => $this->settings->get('woocommerce.optin_on_checkout.enabled', false),
'defaultStatus' => $this->woocommerceSubscription->isCurrentUserSubscribed(),
]));
}
public function addDataAttributesToBlock(array $blocks) {
$blocks[] = 'mailpoet/marketing-optin-block';
return $blocks;
}
public function extendRestApi() {
$extend = Package::container()->get(ExtendRestApi::class);
$extend->register_endpoint_data(
[
'endpoint' => CheckoutSchema::IDENTIFIER,
'namespace' => 'mailpoet',
'schema_callback' => function () {
return [
'optin' => [
'description' => __('Subscribe to marketing opt-in.', 'mailpoet'),
'type' => 'boolean',
],
];
},
]
);
}
public function processCheckoutBlockOptin(\WC_Order $order, $request) {
if (!$this->settings->get('woocommerce.optin_on_checkout.enabled', false)) {
return;
}
if (!$order || !$order->get_billing_email()) {
return;
}
if (!isset($request['extensions']['mailpoet']['optin'])) {
return;
}
// See Subscription::subscribeOnCheckout
$subscriber = Subscriber::where('email', $order->get_billing_email())
->where('is_woocommerce_user', 1)
->findOne();
if (!$subscriber) {
return null;
}
$this->woocommerceSubscription->handleSubscriberOptin($subscriber, (bool)$request['extensions']['mailpoet']['optin']);
}
}

View File

@ -7,6 +7,16 @@ class Helper {
return class_exists('WooCommerce');
}
public function isWooCommerceBlocksActive($min_version = '') {
if (!class_exists('\Automattic\WooCommerce\Blocks\Package')) {
return false;
}
if ($min_version) {
return version_compare(\Automattic\WooCommerce\Blocks\Package::get_version(), $min_version, '>=');
}
return true;
}
public function WC() {
return WC();
}
@ -53,10 +63,10 @@ class Helper {
public function getOrdersCountCreatedBefore($dateTime) {
global $wpdb;
$result = $wpdb->get_var( "
$result = $wpdb->get_var("
SELECT DISTINCT count(p.ID) FROM {$wpdb->prefix}posts as p
WHERE p.post_type = 'shop_order' AND p.post_date < '{$dateTime}'
" );
");
return (int)$result;
}

View File

@ -116,7 +116,7 @@ class Subscription {
return str_replace('type="text', 'type="hidden"', $field);
}
private function isCurrentUserSubscribed() {
public function isCurrentUserSubscribed() {
$subscriber = $this->subscribersRepository->getCurrentWPUser();
if (!$subscriber instanceof SubscriberEntity) {
return false;
@ -148,44 +148,59 @@ class Subscription {
$subscriber = Subscriber::where('email', $data['billing_email'])
->where('is_woocommerce_user', 1)
->findOne();
if (!$subscriber) {
// no subscriber: WooCommerce sync didn't work
return null;
}
$checkoutOptinEnabled = (bool)$this->settings->get(self::OPTIN_ENABLED_SETTING_NAME);
$checkoutOptinEnabled = (bool)$this->settings->get( self::OPTIN_ENABLED_SETTING_NAME );
$checkoutOptin = ! empty( $_POST[self::CHECKOUT_OPTIN_INPUT_NAME] );
return $this->handleSubscriberOptin( $subscriber, $checkoutOptinEnabled && $checkoutOptin );
}
/**
* Subscribe or unsubscribe a subscriber.
*
* @param Subscriber $subscriber Subscriber object
* @param bool $optin Opting in or opting out.
*/
public function handleSubscriberOptin( Subscriber $subscriber, $optin = true ) {
$wcSegment = Segment::getWooCommerceSegment();
$moreSegmentsToSubscribe = (array)$this->settings->get(self::OPTIN_SEGMENTS_SETTING_NAME, []);
if (!$checkoutOptinEnabled || empty($_POST[self::CHECKOUT_OPTIN_INPUT_NAME])) {
$signupConfirmation = $this->settings->get('signup_confirmation');
if ( ! $optin ) {
// Opt-in is disabled or checkbox is unchecked
SubscriberSegment::unsubscribeFromSegments(
$subscriber,
[$wcSegment->id]
);
if ($checkoutOptinEnabled) {
$this->updateSubscriberStatus($subscriber);
}
$this->updateSubscriberStatus($subscriber);
return false;
}
$subscriber->source = Source::WOOCOMMERCE_CHECKOUT;
$signupConfirmation = $this->settings->get('signup_confirmation');
// checkbox is checked
if (
($subscriber->status === Subscriber::STATUS_SUBSCRIBED)
|| ((bool)$signupConfirmation['enabled'] === false)
) {
$this->subscribe($subscriber);
} else {
$this->requireSubscriptionConfirmation($subscriber);
if ( $optin ) {
$subscriber->source = Source::WOOCOMMERCE_CHECKOUT;
if (
($subscriber->status === Subscriber::STATUS_SUBSCRIBED)
|| ((bool)$signupConfirmation['enabled'] === false)
) {
$this->subscribe($subscriber);
} else {
$this->requireSubscriptionConfirmation($subscriber);
}
SubscriberSegment::subscribeToSegments(
$subscriber,
array_merge([$wcSegment->id], $moreSegmentsToSubscribe)
);
return true;
}
SubscriberSegment::subscribeToSegments(
$subscriber,
array_merge([$wcSegment->id], $moreSegmentsToSubscribe)
);
return true;
}
private function subscribe(Subscriber $subscriber) {

View File

@ -408,58 +408,58 @@ const postEditorBlock = {
},
};
const requestToExternal = ( request ) => {
// The following default externals are bundled for compatibility with older versions of WP
// Note CSS for specific components is bundled via admin/assets/src/index.scss
// WP 5.4 is the min version for <Card* />, <TabPanel />
const bundled = [
'@wordpress/compose',
'@wordpress/components',
'@wordpress/warning',
'@wordpress/primitives',
];
if ( bundled.includes( request ) ) {
return false;
}
const requestToExternal = (request) => {
// The following default externals are bundled for compatibility with older versions of WP
// Note CSS for specific components is bundled via admin/assets/src/index.scss
// WP 5.4 is the min version for <Card* />, <TabPanel />
const bundled = [
"@wordpress/compose",
"@wordpress/components",
"@wordpress/warning",
"@wordpress/primitives",
];
if (bundled.includes(request)) {
return false;
}
const wcDepMap = {
'@woocommerce/settings': [ 'wc', 'wcSettings' ],
'@woocommerce/blocks-checkout': [ 'wc', 'blocksCheckout' ],
};
if ( wcDepMap[ request ] ) {
return wcDepMap[ request ];
}
const wcDepMap = {
"@woocommerce/settings": ["wc", "wcSettings"],
"@woocommerce/blocks-checkout": ["wc", "blocksCheckout"],
};
if (wcDepMap[request]) {
return wcDepMap[request];
}
};
const requestToHandle = ( request ) => {
const wcHandleMap = {
'@woocommerce/settings': 'wc-settings',
'@woocommerce/blocks-checkout': 'wc-blocks-checkout',
};
if ( wcHandleMap[ request ] ) {
return wcHandleMap[ request ];
}
const requestToHandle = (request) => {
const wcHandleMap = {
"@woocommerce/settings": "wc-settings",
"@woocommerce/blocks-checkout": "wc-blocks-checkout",
};
if (wcHandleMap[request]) {
return wcHandleMap[request];
}
};
// Newsletter config
const newsletterBlock = {
// Marketing Optin config
const marketingOptinBlock = {
...wpScriptConfig,
name: "newsletter_block",
name: "marketing_optin_block",
entry: {
newsletter_block: path.resolve(
"marketing-optin-block": path.resolve(
process.cwd(),
"assets/js/src/newsletter_block",
"assets/js/src/marketing_optin_block",
"index.tsx"
),
newsletter_block_frontend: path.resolve(
"marketing-optin-block-frontend": path.resolve(
process.cwd(),
"assets/js/src/newsletter_block",
"assets/js/src/marketing_optin_block",
"frontend.tsx"
),
},
output: {
filename: "[name].js",
path: path.resolve(process.cwd(), "assets/dist/js/newsletter_block"),
path: path.resolve(process.cwd(), "assets/dist/js/marketing_optin_block"),
},
module: {
...wpScriptConfig.module,
@ -469,24 +469,22 @@ const newsletterBlock = {
test: /\.(t|j)sx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader?cacheDirectory',
loader: "babel-loader?cacheDirectory",
options: {
presets: [ '@wordpress/babel-preset-default' ],
presets: ["@wordpress/babel-preset-default"],
plugins: [
require.resolve("@babel/plugin-proposal-class-properties"),
require.resolve(
'@babel/plugin-proposal-class-properties'
"@babel/plugin-proposal-nullish-coalescing-operator"
),
require.resolve(
'@babel/plugin-proposal-nullish-coalescing-operator'
),
].filter( Boolean ),
].filter(Boolean),
},
},
},
],
},
resolve: {
extensions: [ '.js', '.jsx', '.ts', '.tsx' ],
extensions: [".js", ".jsx", ".ts", ".tsx"],
},
plugins: [
...wpScriptConfig.plugins.filter(
@ -524,5 +522,5 @@ module.exports = [
}
return Object.assign({}, baseConfig, config);
}),
newsletterBlock,
];
marketingOptinBlock,
];