Compare commits

..

1 Commits

Author SHA1 Message Date
6dbcdd5638 Release 3.101.0 2022-10-17 14:57:59 +02:00
1915 changed files with 14749 additions and 26154 deletions

View File

@ -71,6 +71,13 @@ anchors:
- trunk
- release
only_trunk_and_cot: &only_trunk_and_cot
filters:
branches:
only:
- trunk
- /^cot-.*/
multisite_acceptance_config: &multisite_acceptance_config
multisite: 1
requires:
@ -179,10 +186,10 @@ jobs:
- run:
name: Download additional WP Plugins for tests
command: |
./do download:woo-commerce-zip 7.1.0
./do download:woo-commerce-subscriptions-zip 4.6.0
./do download:woo-commerce-memberships-zip 1.23.1
./do download:woo-commerce-blocks-zip 8.8.2
./do download:woo-commerce-zip 6.8.2
./do download:woo-commerce-subscriptions-zip 4.5.1
./do download:woo-commerce-memberships-zip 1.23.0
./do download:woo-commerce-blocks-zip 8.4.0
- run:
name: Dump tests ENV variables for acceptance tests
command: |
@ -311,8 +318,7 @@ jobs:
parallelism: 20
working_directory: /home/circleci/mailpoet/mailpoet
machine:
image: ubuntu-2204:2022.10.2
docker_layer_caching: false
image: ubuntu-2204:2022.07.1
parameters:
multisite:
type: integer
@ -323,7 +329,7 @@ jobs:
mysql_command:
type: string
default: ''
mysql_image:
mysql_image_version:
type: string
default: ''
codeception_image_version:
@ -350,9 +356,12 @@ jobs:
enable_cot_sync:
type: integer
default: 0
allow_fail:
type: integer
default: 0
environment:
MYSQL_COMMAND: << parameters.mysql_command >>
MYSQL_IMAGE: << parameters.mysql_image >>
MYSQL_IMAGE_VERSION: << parameters.mysql_image_version >>
CODECEPTION_IMAGE_VERSION: << parameters.codeception_image_version >>
WORDPRESS_IMAGE_VERSION: << parameters.wordpress_image_version >>
steps:
@ -401,9 +410,7 @@ jobs:
name: Group acceptance tests
command: |
# Convert test result filename values to be relative paths because the circleci CLI's split command requires exact matches
if [ -e $CIRCLE_INTERNAL_TASK_DATA/circle-test-results/results.json ]; then
sed -i.bak 's#/wp-core/wp-content/plugins/mailpoet/##g' $CIRCLE_INTERNAL_TASK_DATA/circle-test-results/results.json
fi
sed -i.bak 's#/wp-core/wp-content/plugins/mailpoet/##g' $CIRCLE_INTERNAL_TASK_DATA/circle-test-results/results.json
# `circleci tests split` returns different values based on the container it's run on
# in case group is defined find only tests containing the group
if [[ -n '<< parameters.group >>' ]]; then
@ -412,12 +419,6 @@ jobs:
circleci tests glob "tests/acceptance/**/*Cest.php" | circleci tests split --split-by=timings > tests/acceptance/_groups/circleci_split_group
fi
cat tests/acceptance/_groups/circleci_split_group
- run:
name: Create docker containers for test
# We experienced some failures when creating containers so we do it explicitly with one retry
command: |
cd tests/docker
docker-compose create || docker-compose create
- run:
name: Run acceptance tests
command: |
@ -431,6 +432,9 @@ jobs:
--xml
-g circleci_split_group
)
if [[ << parameters.allow_fail >> == 1 ]]; then
args+=(--no-exit)
fi
docker-compose run -e SKIP_DEPS=1 \
-e CIRCLE_BRANCH=${CIRCLE_BRANCH} \
-e CIRCLE_JOB=${CIRCLE_JOB} \
@ -438,13 +442,18 @@ jobs:
-e ENABLE_COT=<< parameters.enable_cot >> \
-e ENABLE_COT_SYNC=<< parameters.enable_cot_sync >> \
codeception_acceptance "${args[@]}"
- run:
name: Check exceptions
command: |
if [ "$(ls tests/_output/exceptions/*.html)" ]; then
echo "There were some exceptions during the tests run"
exit 1
fi
- when:
condition:
not:
equal: [1, << parameters.allow_fail >>]
steps:
- run:
name: Check exceptions
command: |
if [ "$(ls tests/_output/exceptions/*.html)" ]; then
echo "There were some exceptions during the tests run"
exit 1
fi
- store_artifacts:
path: tests/_output
- store_test_results:
@ -483,12 +492,9 @@ jobs:
integration_tests:
working_directory: /home/circleci/mailpoet/mailpoet
machine:
image: ubuntu-2204:2022.10.2
docker_layer_caching: false
image: ubuntu-2204:2022.07.1
environment:
CODECEPTION_IMAGE_VERSION: << parameters.codeception_image_version >>
MYSQL_COMMAND: << parameters.mysql_command >>
MYSQL_IMAGE: << parameters.mysql_image >>
parameters:
codeception_image_version:
type: string
@ -511,12 +517,12 @@ jobs:
multisite:
type: integer
default: 0
mysql_command:
type: string
default: ''
mysql_image:
woo_core_version:
type: string
default: ''
allow_fail:
type: integer
default: 0
steps:
- attach_workspace:
at: /home/circleci
@ -524,6 +530,14 @@ jobs:
name: 'Pull test docker images'
# Pull docker images with 3 retries
command: i='0';while ! docker-compose -f tests/docker/docker-compose.yml pull && ((i < 3)); do sleep 3 && i=$[$i+1]; done
- when:
condition: << parameters.woo_core_version >>
steps:
- run:
name: Download WooCommerce Core
command: |
cd tests/docker
docker-compose run --rm -w /project --entrypoint "./do download:woo-commerce-zip << parameters.woo_core_version >>" --no-deps codeception_integration
- run:
name: 'PHP Integration tests'
command: |
@ -542,6 +556,9 @@ jobs:
if [[ -n '<< parameters.skip_group >>' ]]; then
args+=(--skip-group << parameters.skip_group >>)
fi
if [[ << parameters.allow_fail >> == 1 ]]; then
args+=(--no-exit)
fi
docker-compose run -e SKIP_DEPS=1 \
-e CIRCLE_BRANCH=${CIRCLE_BRANCH} \
-e CIRCLE_JOB=${CIRCLE_JOB} \
@ -634,7 +651,7 @@ workflows:
- build
- acceptance_tests:
<<: *slack-fail-post-step
name: acceptance_tests_base_and_woo_cot_off
name: acceptance_tests
requires:
- unit_tests
- static_analysis_php8
@ -642,10 +659,13 @@ workflows:
- qa_php
- acceptance_tests:
<<: *slack-fail-post-step
<<: *only_trunk_and_cot
name: acceptance_tests_woo_cot_sync
group: woo
enable_cot: 1
enable_cot_sync: 1
allow_fail: 1
woo_core_version: woo-cot-beta # Temporarily force COT beta version
requires:
- unit_tests
- static_analysis_php8
@ -653,10 +673,24 @@ workflows:
- qa_php
- acceptance_tests:
<<: *slack-fail-post-step
<<: *only_trunk_and_cot
name: acceptance_tests_woo_cot_no_sync
group: woo
enable_cot: 1
enable_cot_sync: 0
allow_fail: 1
woo_core_version: woo-cot-beta # Temporarily force COT beta version
requires:
- unit_tests
- static_analysis_php8
- qa_js
- qa_php
- acceptance_tests:
<<: *slack-fail-post-step
<<: *only_trunk_and_cot
name: acceptance_tests_woo_cot_off
group: woo
woo_core_version: woo-cot-beta # Temporarily force COT beta version
requires:
- unit_tests
- static_analysis_php8
@ -669,8 +703,20 @@ workflows:
- integration_tests:
<<: *slack-fail-post-step
group: woo
name: integration_test_woocommerce
requires:
- unit_tests
- static_analysis_php8
- qa_js
- qa_php
- integration_tests:
<<: *slack-fail-post-step
<<: *only_trunk_and_cot
group: woo
enable_cot: 1
enable_cot_sync: 1
allow_fail: 1
woo_core_version: woo-cot-beta # Temporarily force COT beta version
name: integration_test_woo_cot_sync
requires:
- unit_tests
@ -679,9 +725,12 @@ workflows:
- qa_php
- integration_tests:
<<: *slack-fail-post-step
<<: *only_trunk_and_cot
group: woo
enable_cot: 1
enable_cot_sync: 0
allow_fail: 1
woo_core_version: woo-cot-beta # Temporarily force COT beta version
name: integration_test_woo_cot_no_sync
requires:
- unit_tests
@ -690,7 +739,9 @@ workflows:
- qa_php
- integration_tests:
<<: *slack-fail-post-step
<<: *only_trunk_and_cot
group: woo
woo_core_version: woo-cot-beta # Temporarily force COT beta version
name: integration_test_woo_cot_off
requires:
- unit_tests
@ -726,14 +777,10 @@ workflows:
<<: *slack-fail-post-step
requires:
- build
- acceptance_tests_base_and_woo_cot_off
- acceptance_tests
- js_tests
- integration_test_woocommerce
- integration_test_base
- integration_test_woo_cot_no_sync
- integration_test_woo_cot_off
- integration_test_woo_cot_sync
- acceptance_tests_woo_cot_sync
- acceptance_tests_woo_cot_no_sync
nightly:
triggers:
@ -758,14 +805,14 @@ workflows:
- acceptance_tests:
<<: *slack-fail-post-step
name: acceptance_oldest
woo_core_version: 6.8.0
woo_core_version: 6.2.2
woo_subscriptions_version: 4.3.0
woo_memberships_version: 1.21.0
woo_blocks_version: 6.8.0
mysql_command: --max_allowed_packet=100M --default-storage-engine=MYISAM
mysql_image: mysql:5.5
codeception_image_version: 7.4-cli_20220605.0
wordpress_image_version: wp-5.8_php7.3_20221104.1
woo_blocks_version: 5.3.2
mysql_command: --max_allowed_packet=100M
mysql_image_version: 5.7.36
codeception_image_version: 7.4-cli_20210126.1
wordpress_image_version: wp-5.6_php7.2_20220406.1
requires:
- build
- unit_tests:
@ -788,8 +835,6 @@ workflows:
<<: *slack-fail-post-step
name: integration_oldest
codeception_image_version: 7.2-cli_20220605.0
mysql_command: --max_allowed_packet=100M --default-storage-engine=MYISAM
mysql_image: mysql:5.5
requires:
- build
- build_premium:

View File

@ -126,24 +126,23 @@ You can access this help in your command line running `./do` without parameters.
[Read the article.](https://mailpoet.atlassian.net/wiki/spaces/MAILPOET/pages/629374977/Adding+new+templates+to+the+plugin)
## 🚥 Testing with different PHP versions
## 🚥 Testing with PHP 7.4 or PHP 8.0
To switch the environment to a different PHP version:
To switch the environment to PHP 7.4/8.0:
1. Check https://github.com/mailpoet/mailpoet/tree/trunk/dev for a list of available PHP versions. Each directory starting with `php` corresponds to a available version.
2. Configure the `wordpress` service in `docker-compose.override.yml` to build from the desired PHP version Dockerfile (replace {PHP_VERSION} with the name of the directory that corresponds to the version that you want to use):
1. Configure the `wordpress` service in `docker-compose.override.yml` to build from the php74 Dockerfile:
```yaml
wordpress:
build:
context: .
dockerfile: dev/{PHP_VERSION}/Dockerfile
dockerfile: dev/php74/Dockerfile # OR dev/php80/Dockerfile
```
3. Run `docker-compose build wordpress`.
4. Start the stack with `./do start`.
2. Run `docker-compose build wordpress`.
3. Start the stack with `./do start`.
To switch back to the default PHP version remove what was added in 2) and, run `docker-compose build wordpress` for application container and `docker-compose build test_wordpress` for tests container,
To switch back to PHP 8.1 remove what was added in 1) and, run `docker-compose build wordpress` for application container and `docker-compose build test_wordpress` for tests container,
and start the stack using `./do start`.
## ✅ TODO

View File

@ -1,46 +0,0 @@
FROM php:8.2.0RC6-apache
ARG UID=1000
ARG GID=1000
# additinal extensions
RUN apt-get update \
&& apt-get install -y git zlib1g-dev libzip-dev zip wget gnupg msmtp libpng-dev gettext subversion \
&& \
# Install NodeJS, enable Corepack
curl -sL https://deb.nodesource.com/setup_17.x | bash - && \
apt-get install -y nodejs build-essential && \
corepack enable && \
\
# Install WP-CLI
curl -o /usr/local/bin/wp https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && \
chmod +x /usr/local/bin/wp && \
\
# Clean up
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
COPY dev/php.ini /usr/local/etc/php/conf.d/php_user.ini
# msmtp config
RUN printf "account default\nhost smtp\nport 1025" > /etc/msmtprc
# xdebug build an config
ENV XDEBUGINI_PATH=/usr/local/etc/php/conf.d/xdebug.ini
RUN git clone -b "3.2.0RC2" --depth 1 https://github.com/xdebug/xdebug.git /usr/src/php/ext/xdebug \
&& docker-php-ext-configure xdebug --enable-xdebug-dev \
&& docker-php-ext-install xdebug \
&& mkdir /tmp/debug
COPY dev/xdebug.ini /tmp/xdebug.ini
RUN cat /tmp/xdebug.ini >> $XDEBUGINI_PATH
# php extensions
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install mysqli
# allow .htaccess files (between <Directory /var/www/> and </Directory>, which is WordPress installation)
RUN sed -i '/<Directory \/var\/www\/>/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf
# ensure existing content in /var/www/html respects UID and GID, give Node permissions for Corepack
RUN chown -R ${UID}:${GID} /var/www/html && \
mkdir -p /.node && chown -R ${UID}:${GID} /.node

View File

@ -28,7 +28,6 @@ Class `\MailPoet\API\API` becomes available once MailPoet plugin is loaded by Wo
- [Add List (addList)](api_methods/AddList.md)
- [Add Subscriber (addSubscriber)](api_methods/AddSubscriber.md)
- [Add Subscriber Field (addSubscriberField)](api_methods/AddSubscriberField.md)
- [Delete List (deleteList)](api_methods/DeleteList.md)
- [Get Lists (getLists)](api_methods/GetLists.md)
- [Get Subscriber (getSubscriber)](api_methods/GetSubscriber.md)
- [Get Subscribers (getSubscribers)](api_methods/GetSubscribers.md)
@ -39,7 +38,6 @@ Class `\MailPoet\API\API` becomes available once MailPoet plugin is loaded by Wo
- [Subscribe to Lists (subscribeToLists)](api_methods/SubscribeToLists.md)
- [Unsubscribe from List (unsubscribeFromList)](api_methods/UnsubscribeFromList.md)
- [Unsubscribe from Lists (unsubscribeFromLists)](api_methods/UnsubscribeFromLists.md)
- [Update List (updateList)](api_methods/UpdateList.md)
### Usage examples

View File

@ -1,27 +0,0 @@
[back to list](../Readme.md)
# Delete List
## `bool deleteList(string $list_id)`
This method provides functionality for deleting a list that is of the type 'default'.
It returns a boolean value.
## Error handling
All expected errors from the API are exceptions of class `\MailPoet\API\MP\v1\APIException`.
Code of the exception is populated to distinguish between different errors.
An exception of base class `\Exception` can be thrown when something unexpected happens.
Codes description:
| Code | Description |
| ---- | --------------------------------------------------------------- |
| 5 | List does not exist |
| 18 | List id is empty |
| 20 | List cannot be deleted because its used for an automatic email |
| 21 | List cannot be deleted because its used for a form |
| 22 | The list couldnt be deleted from the database |
| 23 | Only lists of the type 'default' can be deleted |

View File

@ -18,8 +18,8 @@ This method returns a list of subscribers. To see the subscriber data structure,
Filter argument supports following array keys.
| Key | Type | Description |
| ------------ | ------------ | ----------------------------------------------------------------------------------------------------------------- |
| status | string | Specific status of subscribers. One of values: `unconfirmed`, `subscribed`, `unsubscribed`, `bounced`, `inactive` |
| listId | int | List id or dynamic segment id |
| minUpdatedAt | DateTime\int | DateTime object or timestamp of the minimal last update of subscribers |
| Key | Type | Description |
| -------------- | ------------ | ----------------------------------------------------------------------------------------------------------------- |
| status | string | Specific status of subscribers. One of values: `unconfirmed`, `subscribed`, `unsubscribed`, `bounced`, `inactive` |
| list_id | int | List id or dynamic segment id |
| min_updated_at | DateTime\int | DateTime object or timestamp of the minimal last update of subscribers |

View File

@ -1,39 +0,0 @@
[back to list](../Readme.md)
# Add Subscriber
## `array updateList(array $list)`
This method provides functionality for updating a list name or description. Only lists of type 'default' are supported.
It returns the updated list. See [Get Lists](GetLists.md) for a list data structure description.
## Arguments
### `$list` (required)
An associative array which contains list data.
| Property | Type | Limits | Description |
| ---------------------- | ------------ | --------- | -------------------------- |
| id (required) | string | 11 chars | A id of the list. |
| name (required) | string | 90 chars | A name of the list. |
| description (optional) | string\|null | 250 chars | A description of the list. |
## Error handling
All expected errors from the API are exceptions of class `\MailPoet\API\MP\v1\APIException`.
Code of the exception is populated to distinguish between different errors.
An exception of base class `\Exception` can be thrown when something unexpected happens.
Codes description:
| Code | Description |
| ---- | ----------------------------------------------- |
| 5 | The list was not found by id |
| 14 | Missing list name |
| 15 | Trying to use a list name that is already used |
| 18 | Missing list id |
| 19 | The list couldnt be updated in the database |
| 23 | Only lists of the type 'default' can be updated |

View File

@ -15,7 +15,6 @@ services:
volumes:
- my-datavolume:/var/lib/mysql
- ./dev/database/create_test_db.sh:/docker-entrypoint-initdb.d/10-create_test_db.sh
command: --sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,ANSI,ONLY_FULL_GROUP_BY
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress

View File

@ -5,6 +5,7 @@
"@babel/preset-env"
],
"plugins": [
"babel-plugin-typescript-to-proptypes",
[
"@babel/plugin-transform-runtime",
{

View File

@ -1,4 +1,4 @@
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
<?php
// phpcs:disable PSR1.Classes.ClassDeclaration
// phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
@ -117,45 +117,11 @@ class RoboFile extends \Robo\Tasks {
}
public function translationsBuild() {
$exclude = implode(',', [
'.mp_svn',
'assets/css',
'assets/img',
'assets/js',
'generated',
'lang',
'lib-3rd-party',
'mailpoet-premium',
'node_modules',
'plugin_repository',
'prefixer',
'tasks',
'temp',
'tests',
'tools',
'vendor',
'vendor-prefixed',
]);
$headers = escapeshellarg(
json_encode([
'Report-Msgid-Bugs-To' => 'http://support.mailpoet.com/',
'Last-Translator' => 'MailPoet i18n (https://www.transifex.com/organization/wysija)',
'Language-Team' => 'MailPoet i18n <https://www.transifex.com/organization/wysija>',
'Plural-Forms' => 'nplurals=2; plural=(n != 1);',
])
);
$this->collectionBuilder()
->taskExec('mkdir -p ' . __DIR__ . '/lang')
// HTML, HBS
->taskExec("php -d memory_limit=-1 tasks/makepot/makepot-views.php . > lang/mailpoet.pot")
// PHP, JS/TS
->taskExec("vendor/bin/wp i18n make-pot --merge --slug=mailpoet --domain=mailpoet --exclude=$exclude --headers=$headers . lang/mailpoet.pot")
->run();
->taskExec(
'php -d memory_limit=-1 tasks/makepot/grunt-makepot.php wp-plugin . lang/mailpoet.pot mailpoet .mp_svn,assets,lang,node_modules,plugin_repository,tasks,tests,vendor'
)->run();
}
public function translationsGetPotFileFromBuild() {
@ -385,25 +351,6 @@ class RoboFile extends \Robo\Tasks {
$this->say("Validator metadata generated to: $validatorMetadataDir");
}
public function migrationsNew() {
$generator = new \MailPoet\Migrator\Repository();
$result = $generator->create();
$path = realpath($result['path']);
$this->output->writeln('MAILPOET DATABASE MIGRATIONS');
$this->output->writeln("============================\n");
$this->output->writeln("New migration created ✔\n");
$this->output->writeln(" Name: {$result['name']}");
$this->output->writeln(" Path: $path");
}
public function migrationsStatus() {
return $this->taskExec('vendor/bin/wp mailpoet:migrations:status');
}
public function migrationsRun() {
return $this->taskExec('vendor/bin/wp mailpoet:migrations:run');
}
public function qa() {
$collection = $this->collectionBuilder();
$collection->addCode([$this, 'qaPhp']);
@ -425,9 +372,6 @@ class RoboFile extends \Robo\Tasks {
$collection->addCode(function() {
return $this->qaCodeSniffer([]);
});
$collection->addCode(function() {
return $this->qaMinimalPluginStandard([]);
});
return $collection->run();
}
@ -504,56 +448,7 @@ class RoboFile extends \Robo\Tasks {
'./tasks/code_sniffer/vendor/bin/phpcs',
'--extensions=php',
$severityFlag,
'--standard=tasks/code_sniffer/MailPoet/free-ruleset.xml',
'-s',
]);
$ignorePaths = [
'.mp_svn',
'assets',
'doc',
'generated',
'lib/Config/PopulatorData/Templates',
'lib-3rd-party',
'node_modules',
'plugin_repository',
'prefixer/build',
'prefixer/vendor',
'tasks/code_sniffer/vendor',
'tasks/phpstan/vendor',
'tasks/makepot',
'tools/vendor',
'temp',
'tests/_data',
'tests/_output',
'tests/_support/_generated',
'vendor',
'vendor-prefixed',
'views',
];
// the "--ignore" arg takes a list of regexes, we need to anchor and escape them
$ignorePatterns = array_map(function (string $path): string {
return '^' . preg_quote(__DIR__ . DIRECTORY_SEPARATOR . $path);
}, $ignorePaths);
$stringFilesToCheck = !empty($filesToCheck) ? implode(' ', $filesToCheck) : '.';
return $this->taskExec($task)
->arg('--ignore=' . implode(',', $ignorePatterns))
->rawArg($stringFilesToCheck)
->run();
}
public function qaMinimalPluginStandard(array $filesToCheck, $opts = ['severity' => 'all']) {
$severityFlag = $opts['severity'] === 'all' ? '-w' : '-n';
$task = implode(' ', [
'php -d memory_limit=-1',
'./tasks/code_sniffer/vendor/bin/phpcs',
'--extensions=php',
$severityFlag,
'--standard=tasks/code_sniffer/vendor/wporg/plugin-directory/MinimalPluginStandard',
'--standard=tasks/code_sniffer/MailPoet',
'-s',
]);
@ -851,9 +746,6 @@ class RoboFile extends \Robo\Tasks {
->addCode(function () use ($version) {
$this->releaseCreatePullRequest($version);
})
->addCode(function () use ($version) {
$this->releaseRerunCircleWorkflow(\MailPoetTasks\Release\CircleCiController::PROJECT_PREMIUM);
})
->addCode(function () use ($version) {
$this->translationsPrepareLanguagePacks($version);
})
@ -1171,18 +1063,6 @@ class RoboFile extends \Robo\Tasks {
$this->say("Release '$version[name]' info was published on Slack.");
}
public function releaseRerunCircleWorkflow(string $project = null) {
$circleciController = $this->createCircleCiController();
$result = $circleciController->rerunLatestWorkflow($project);
// Sometimes can be useful to know which Circle project workflow was restarted
$project = $project ? " for the project '{$project}'" : '';
if (!$result) {
$this->yell("Circle Workflow{$project} was not restarted", 40, 'red');
} else {
$this->say("Circle Workflow{$project} was started from the beginning");
}
}
public function downloadWooCommerceBlocksZip($tag = null) {
$this->createWpOrgDownloader('woo-gutenberg-products-block')
->downloadPluginZip('woo-gutenberg-products-block.zip', __DIR__ . '/tests/plugins/', $tag);
@ -1207,10 +1087,20 @@ class RoboFile extends \Robo\Tasks {
}
public function downloadWooCommerceZip($tag = null) {
if ($tag === 'woo-cot-beta') {
$this->downloadWooCommerceCotZip();
return;
}
$this->createWpOrgDownloader('woocommerce')
->downloadPluginZip('woocommerce.zip', __DIR__ . '/tests/plugins/', $tag);
}
public function downloadWooCommerceCotZip() {
$cotBuildUrl = 'https://github.com/woocommerce/woocommerce/files/9706609/woocommerce.zip';
file_put_contents(__DIR__ . '/tests/plugins/woocommerce.zip', file_get_contents($cotBuildUrl));
file_put_contents(__DIR__ . '/tests/plugins/woocommerce.zip-info', $cotBuildUrl);
}
public function generateData($generatorName = null, $threads = 1) {
require_once __DIR__ . '/tests/DataGenerator/_bootstrap.php';
$generator = new \MailPoet\Test\DataGenerator\DataGenerator(new \Codeception\Lib\Console\Output([]));

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,4 @@
.mailpoet-automation-add-trigger {
.mailpoet-automation-workflow-add-trigger {
align-items: center;
border: 1px dashed #c3c4c7;
border-radius: 4px;

View File

@ -1,37 +0,0 @@
.mailpoet-automation-editor-automation {
background: #fbfbfb;
flex-grow: 1;
}
.mailpoet-automation-editor-automation-wrapper {
display: grid;
padding: 50px 20px;
}
.mailpoet-automation-editor-automation-end {
background: #8c8f94;
border-radius: 999999px;
fill: white;
height: 18px;
margin: 4px auto;
padding: 3px;
width: 18px;
}
.mailpoet-automation-editor-stats {
margin: 0 auto 32px;
max-width: 480px;
width: 100%;
.mailpoet-automation-stats-item {
line-height: 22px;
}
.mailpoet-automation-stats-label {
color: #787c82;
}
.mailpoet-automation-stats-value {
font-size: 14px;
}
}

View File

@ -1,44 +0,0 @@
.mailpoet-automatoin-deactivate-modal {
color: #1d2327;
font-size: 13px;
line-height: 21px;
max-width: 480px;
.mailpoet-automation-options {
li {
margin-bottom: 12px;
}
}
.mailpoet-automation-option {
border: 2px solid #dcdcde;
border-radius: 4px;
color: #646970;
display: grid;
font-size: 12px;
grid-gap: 8px;
grid-template-columns: 20px auto;
line-height: 16px;
padding: 8px;
&.active {
border-color: #2271b1;
}
strong {
color: #1d2327;
display: block;
font-size: 13px;
font-weight: normal;
line-height: 21px;
}
}
.components-button {
float: right;
&.is-tertiary {
margin-right: 12px;
}
}
}

View File

@ -1,4 +1,4 @@
.mailpoet-automation-editor-empty-automation {
.mailpoet-automation-editor-empty-workflow {
align-items: center;
display: grid;
height: 100%;

View File

@ -30,32 +30,3 @@
outline: none;
}
}
.mailpoet-automation-field__error {
position: relative;
input,
select,
textarea,
input[type='text'].components-form-token-field__input {
background: right top/26px no-repeat url('../../img/icons/alert.svg');
padding-right: 26px;
}
select,
input[type=number] {
background-position-x: calc(100% - 26px);
padding-right: 8px !important;
}
.components-base-control__help,
.mailpoet-automation-field-message {
color: #d63638;
}
.components-button.mailpoet-automation-button-sidebar-primary,
.components-button.mailpoet-automation-button-sidebar-primary.has-text,
.components-button.mailpoet-automation-button-sidebar-primary.has-icon {
background: #d63638;
}
}

View File

@ -12,10 +12,6 @@
font-weight: 500;
line-height: normal;
padding: 16px 48px 16px 16px;
label & {
padding: 0;
}
}
.mailpoet-automation-panel-plain-body-title-action {
@ -61,78 +57,3 @@
color: #757575;
font-style: italic;
}
.mailpoet-automation-activate-panel {
animation: mailpoet-automation-activate-panel-animation .1s forwards;
background: #fff;
border-left: 1px solid #ddd;
bottom: 0;
height: 100%;
left: auto;
overflow: auto;
position: fixed;
right: 0;
top: 0;
transform: translateX(100%);
width: 281px;
z-index: 999999;
button {
justify-content: center;
width: 100%;
}
}
.mailpoet-automation-activate-panel__header {
align-content: space-between;
align-items: center;
display: flex;
height: 61px;
.has-icon {
margin-left: auto;
width: auto;
}
}
.mailpoet-automation-activate-panel__header,
.mailpoet-automation-activate-panel__section {
border-bottom: 1px solid #ddd;
}
.mailpoet-automation-activate-panel__header,
.mailpoet-automation-activate-panel__body {
padding-left: 16px;
padding-right: 16px;
.components-spinner {
display: block;
margin: 100px auto 0;
}
}
.mailpoet-automation-activate-panel__section {
margin-left: -16px;
margin-right: -16px;
padding: 16px;
}
.mailpoet-automation-activate-panel__header-activate-button,
.mailpoet-automation-activate-panel__header-cancel-button {
flex-grow: 1;
max-width: 160px;
}
.mailpoet-automation-activate-panel__header-activate-button {
padding-right: 4px;
}
.mailpoet-automation-activate-panel__header-cancel-button {
padding-left: 4px;
}
@keyframes mailpoet-automation-activate-panel-animation {
100% {
transform: translateX(0);
}
}

View File

@ -0,0 +1,19 @@
.mailpoet-automation-editor-workflow {
background: #fbfbfb;
flex-grow: 1;
}
.mailpoet-automation-editor-workflow-wrapper {
display: grid;
padding: 50px 20px;
}
.mailpoet-automation-editor-workflow-end {
background: #8c8f94;
border-radius: 999999px;
fill: white;
height: 18px;
margin: 4px auto;
padding: 3px;
width: 18px;
}

View File

@ -4,64 +4,18 @@
.mailpoet-add-new-button {
padding-right: 12px;
}
}
.mailpoet-automation-is-onboarding {
.notice {
display: none;
}
}
.mailpoet-automation-listing-heading {
margin-bottom: 16px;
}
.mailpoet-automation-listing {
box-shadow: none;
margin-bottom: 0;
}
.mailpoet-automation-listing-cell-name {
position: relative;
width: 100%;
> a:only-child {
bottom: 2px;
display: flex;
left: 0;
padding: 16px 24px;
position: absolute;
right: 0;
top: 0;
.mailpoet-automation-listing {
/* Prevent border radius beneath tabs */
border-radius: 0 0 1px 1px;
}
}
.mailpoet-filter-tab-panel {
background-color: #fff;
border: 1px solid #dcdcde;
border-radius: 2px;
.components-tab-panel__tabs {
box-shadow: inset 0 -1px 0 0 #dcdcde;
}
.components-tab-panel__tabs-item:focus {
box-shadow: none;
}
.components-tab-panel__tabs-item.is-active {
box-shadow: inset 0 -4px 0 0 var(--wp-admin-theme-color);
}
.components-tab-panel__tabs-item:focus-visible {
box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
}
.components-tab-panel__tabs-item.is-active:focus-visible {
box-shadow:
inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color),
inset 0 -4px 0 0 var(--wp-admin-theme-color);
}
border-radius: 1px;
box-shadow: 0 0 0 1px rgba(0, 0, 0, .1);
outline: none;
.count {
background-color: #f0f0f1;
@ -73,13 +27,6 @@
}
}
.mailpoet-automation-listing-more-button button.components-button {
height: 36px;
padding: 0;
width: 36px;
svg {
height: 28px;
width: 28px;
}
.mailpoet-automation-listing-heading {
margin-bottom: 16px;
}

View File

@ -1,201 +0,0 @@
@mixin full-width {
margin-left: -20px;
padding-left: 104px;
padding-right: 104px;
width: calc(100% + 60px);
@media screen and (max-width: 782px) {
margin-left: -10px;
width: calc(100% + 34px);
}
}
.mailpoet-automation-section {
@include full-width;
}
.mailpoet-automation-white-background {
background: #fff;
}
.mailpoet-automation-section-content {
display: block;
margin: auto;
max-width: 1072px;
padding: 65px 0;
h2 {
font-size: 23px;
font-weight: 400;
line-height: 32px;
margin: 0;
padding: 0 0 8px;
}
p {
font-size: 14px;
font-weight: 400;
line-height: 22px;
margin: 0;
padding: 0 0 40px;
}
}
.mailpoet-automation-section-hero {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-top: -20px;
h1 {
font-size: 32px;
font-weight: 400;
line-height: 40px;
}
p {
font-size: 14px;
line-height: 22px;
margin-bottom: 32px;
}
> div {
width: 400px;
}
img {
margin-top: 16px;
max-width: 100%;
width: 532px;
@media screen and (min-width: 1305px) {
height: 100%;
margin-top: 0;
max-height: 294px;
width: auto;
}
}
}
.mailpoet-automation-preheading {
display: block;
font-size: 11px;
letter-spacing: .2px;
line-height: 16px;
margin-bottom: 32px;
text-transform: uppercase;
}
.mailpoet-section-templates {
padding: 48px 0;
.components-button {
display: block;
font-size: 16px;
font-weight: 400;
line-height: 25px;
text-align: center;
text-underline-offset: 5px;
}
}
.mailpoet-section-template-list {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-bottom: 40px;
> li {
flex-grow: 1;
margin-right: 8px;
max-width: 336px;
&:last-child {
margin-right: 0;
}
button {
background: #fff;
border: 1px solid #dcdcde;
border-radius: 0;
color: #1d2327;
cursor: pointer;
padding: 24px;
text-align: left;
h3 {
font-size: 16px;
font-weight: 600;
line-height: 24px;
}
}
}
}
.mailpoet-section-build-list-button {
background: transparent;
border: 0;
color: #000;
cursor: pointer;
font-size: 16px;
font-weight: 400;
line-height: 24px;
padding: 0;
text-align: left;
width: 100%;
}
.mailpoet-section-build-your-own {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
ol {
list-style: decimal-leading-zero inside;
margin: 0;
max-width: 373px;
padding: 0;
> li {
border-bottom: 1px solid #dcdcde;
display: grid;
grid-gap: 16px;
grid-template-columns: 16px auto;
margin-bottom: 16px;
padding-bottom: 16px;
&.open {
p {
display: block;
}
.mailpoet-section-build-list-button {
font-weight: 600;
}
}
&:last-of-type {
border: 0;
}
}
.marker {
color: #ff5301;
display: inline-block;
font-size: 16px;
font-weight: 600;
line-height: 24px;
}
p {
display: none;
padding: 0;
}
}
img {
height: auto;
max-width: 400px;
width: 100%;
}
}

View File

@ -1,7 +0,0 @@
.mailpoet-automation-listing-cell-actions {
align-items: center;
display: grid;
gap: 8px;
grid-auto-flow: column;
white-space: nowrap;
}

View File

@ -1,8 +1,6 @@
.mailpoet-automation-listing-cell-status {
align-items: center;
display: grid;
grid-auto-flow: column;
white-space: nowrap;
display: flex;
> div.components-base-control > div.components-base-control__field {
margin-bottom: 0;

View File

@ -1,33 +0,0 @@
.mailpoet-option-button {
display: flex;
margin-top: 8px;
position: relative;
}
.mailpoet-option-button-main {
border-radius: 2px 0 0 2px;
margin-right: 1px;
}
.mailpoet-option-button-opener {
background: var(--wp-admin-theme-color);
border-radius: 0 2px 2px 0;
color: white;
}
.mailpoet-option-button-opener svg {
fill: white;
}
.mailpoet-option-button-opener .is-opened svg {
transform: scale(-1, -1);
transform-origin: center 12.5px;
}
.mailpoet-option-button-opener.is-busy {
animation: components-button__busy-animation 2500ms infinite linear;
background-color: var(--wp-admin-theme-color);
background-image: linear-gradient(-45deg, var(--wp-admin-theme-color) 33%, var(--wp-admin-theme-color-darker-20) 33%, var(--wp-admin-theme-color-darker-20) 70%, var(--wp-admin-theme-color) 70%);
background-size: 100px 100%;
border-color: var(--wp-admin-theme-color);
}

View File

@ -1,32 +0,0 @@
.mailpoet-automation-stats {
display: grid;
grid-auto-flow: column;
justify-content: space-between;
}
.mailpoet-automation-stats-item {
color: $color-wordpress-heading;
display: grid;
font-size: 12px;
line-height: 16px;
text-align: center;
}
.mailpoet-automation-stats-label {
color: #646970;
display: block;
&.display-after {
order: 1;
}
}
.mailpoet-automation-stats-value {
font-weight: 600;
}
.mailpoet-automation-stats-item-separator {
color: #a7aaad;
font-size: 20px;
margin: 0 16px;
}

View File

@ -51,8 +51,4 @@
.mailpoet_form_field_block {
display: block;
}
.mailpoet_form_field_input_nowrap {
white-space: nowrap;
}
}

View File

@ -1,41 +0,0 @@
.mailpoet_coupon_block {
.mailpoet_editor_coupon {
text-align: center;
}
.mailpoet_editor_coupon_overlay {
background: rgba(255, 255, 255, .5);
color: #000;
cursor: pointer;
display: none;
font-size: 18px;
height: 100%;
position: absolute;
text-align: center;
top: 0;
width: 100%;
}
:hover {
.mailpoet_editor_coupon {
opacity: .5;
}
.mailpoet_editor_coupon_overlay {
display: block;
}
}
}
.coupon_amount_wrapper {
position: relative;
}
.amount_percentage_sign {
font-size: 18px;
font-weight: bold;
left: 150px; // .mailpoet_input_medium width
line-height: 30px;
margin-left: 10px;
position: absolute;
}

View File

@ -1,26 +0,0 @@
.mailpoet-homepage-section__container {
background-color: $color-white;
box-shadow: rgb(0 0 0 / 10%) 0 0 0 1px;
margin: $grid-gap-xl 0 $grid-gap-medium;
}
.mailpoet-homepage-section__heading {
align-items: center;
border-bottom: 1px solid $color-homepage-borders;
display: grid;
grid-template-columns: auto $grid-gap-medium;
height: 60px;
padding: 0 $grid-gap-medium;
position: relative;
h2 {
font-size: 20px;
font-weight: normal;
line-height: 28px;
margin: 0;
}
@include respond-to(small-screen) {
padding: $grid-gap-half $grid-gap-medium;
}
}

View File

@ -1,5 +0,0 @@
.mailpoet-homepage__container {
margin: 0 auto;
margin-top: $grid-gap-xl;
max-width: 680px;
}

View File

@ -1,68 +0,0 @@
.mailpoet-homepage-product-discovery {
ul {
margin: 0;
}
}
.mailpoet-product-discovery__task {
align-items: center;
border-bottom: 1px solid $color-homepage-borders;
box-sizing: border-box;
cursor: pointer;
display: grid;
font-weight: 600;
grid-template-columns: (124px + $grid-gap-medium) auto $grid-gap-xl;
margin: 0;
padding: $grid-gap-medium;
position: relative;
width: 100%;
@include respond-to(small-screen) {
grid-template-columns: auto $grid-gap-xl;
img {
display: none;
}
}
&:last-child {
border-bottom: none;
}
&:hover {
box-shadow: inset 5px 0 0 0 var(--wp-admin-theme-color);
}
}
.mailpoet-product-discovery__task--completed {
cursor: inherit;
&:hover {
box-shadow: none;
}
}
.mailpoet-product-discovery__task-content {
h3 {
color: var(--wp-admin-theme-color);
font-size: 14px;
line-height: 20px;
margin: 0;
}
p {
color: $color-text-light;
font-weight: normal;
margin: 3px 0 0;
}
}
.mailpoet-product-discovery__task-after {
.mailpoet-task-list__task-icon {
background-color: var(--wp-admin-theme-color);
svg {
fill: $color-white;
}
}
}

View File

@ -1,126 +0,0 @@
$task-icon-size: 32px;
.mailpoet-task-list__task {
background-color: $color-white;
border-bottom: 1px solid $color-homepage-borders;
box-sizing: border-box;
cursor: pointer;
display: grid;
font-weight: 600;
grid-template-columns: $grid-gap-xl auto $grid-gap-xl;
margin: 0;
padding: $grid-gap $grid-gap-medium;
position: relative;
width: 100%;
&:hover {
background-color: $color-grey-0;
}
}
.mailpoet-task-list__task-content {
align-content: center;
color: var(--wp-admin-theme-color);
display: flex;
flex-direction: column;
font-size: 14px;
justify-content: center;
line-height: 20px;
p {
color: $color-text-light;
font-weight: normal;
margin: 3px 0 0;
}
a {
color: var(--wp-admin-theme-color);
&:hover {
color: var(--wp-admin-theme-color-darker-20);
}
}
}
.mailpoet-task-list__task-before {
color: var(--wp-admin-theme-color);
display: flex;
flex-direction: column;
justify-content: center;
}
.mailpoet-task-list__task-icon {
border: 1px solid var(--wp-admin-theme-color);
border-radius: 50%;
box-sizing: border-box;
height: $task-icon-size;
line-height: $task-icon-size;
text-align: center;
width: $task-icon-size;
svg {
fill: var(--wp-admin-theme-color);
margin: 3px;
}
}
.mailpoet-task-list__task--completed {
cursor: inherit;
&:hover {
background-color: $color-white;
}
.mailpoet-task-list__task-icon {
background-color: var(--wp-admin-theme-color);
svg {
fill: $color-white;
}
}
}
.mailpoet-task-list__task--active {
box-shadow: inset 5px 0 0 0 var(--wp-admin-theme-color);
&:after {
background-color: var(--wp-admin-theme-color);
content: '';
height: 100%;
left: 0;
opacity: .1;
pointer-events: none;
position: absolute;
top: 0;
width: 100%;
}
}
.mailpoet-task-list__heading p,
.mailpoet-task-list__all-set {
color: $color-text-light;
font-size: $heading-font-size-h4;
line-height: 1.5;
margin-top: $grid-gap-large;
text-align: center;
}
.mailpoet-task-list__heading {
margin-bottom: $grid-gap-large;
position: relative;
h1 {
margin: 0;
}
p {
margin-top: $grid-gap-half;
text-align: left;
}
.components-dropdown {
position: absolute;
right: 0;
top: 6px;
}
}

View File

@ -122,21 +122,3 @@ body .components-modal__screen-overlay {
justify-content: flex-end;
margin-top: $grid-gap-half;
}
.mailpoet-locked-badge {
align-items: center;
background: #fcf9e8;
border: .5px solid #f5e6ab;
border-radius: 4px;
color: #bd8600;
display: flex;
font-size: 11px;
font-weight: 500;
gap: 4px;
height: 20px;
letter-spacing: .2px;
line-height: 16px;
padding: 2px 8px 2px 4px;
text-transform: uppercase;
width: 82px;
}

View File

@ -232,7 +232,3 @@ progress::-moz-progress-bar {
.mailpoet-form-field-tags label.components-form-token-field__label {
display: none;
}
.mailpoet-form-field-disabled {
cursor: not-allowed;
}

View File

@ -1,196 +0,0 @@
#mailpoet_landingpage_container {
$content-padding: 32px 65px;
$mobile-content-padding: 25px;
.mailpoet-content-center {
text-align: center;
}
.mailpoet-content-padding {
padding: $content-padding;
@include respond-to(small-screen) {
padding: $mobile-content-padding
}
}
.landing-header {
padding: $content-padding;
@include respond-to(small-screen) {
padding: $mobile-content-padding
}
}
.landing-footer {
background-color: $color-landingpage-background-light;
padding: $content-padding;
.landing-footer-content {
box-shadow: 0 -1px 0 0 $color-tertiary-light;
padding: 25px 0;
}
}
.landing-faq {
background-color: $color-landingpage-background-light;
padding: $content-padding;
.mailpoet-faq-accordion {
margin: 25px 0;
}
.landing-faq-mobile {
display: none;
}
@include respond-to(small-screen) {
padding: $mobile-content-padding;
.landing-faq-header {
display: none;
}
.landing-faq-mobile {
display: block;
}
}
}
.landing-content {
.hero-section {
$hero-image-offset: 6rem;
background-color: $color-landingpage-background-light;
margin-top: $hero-image-offset;
padding: $content-padding;
.hero-image {
margin-top: -($hero-image-offset + 2rem);
}
@include respond-to(small-screen) {
padding: $mobile-content-padding
}
}
.landingpage-images {
@include respond-to(medium-screen) {
width: 100%;
}
}
.landingpage-general-features {
p:last-child {
margin: 10px auto;
width: 60%;
}
.landingpage-feature-icon {
display: block;
margin: 0 auto;
padding: 20px;
text-align: center;
}
@include respond-to(medium-screen) {
p:last-child {
width: 100%;
}
}
}
.landingpage-wooCommerce-features {
margin-top: 30px;
padding: 2rem 10rem;
.landingpage-wooCommerce-feature-item {
padding: 30px;
@media screen and (min-width: 960px) and (max-width: 1460px) {
.landingpage-images {
width: 100%;
}
}
div:last-child {
margin: auto;
}
}
@include respond-to(small-screen) {
padding: $mobile-content-padding;
.landingpage-wooCommerce-feature-item {
padding: 25px 0;
div:last-child {
text-align: center;
}
}
}
}
}
}
.mailpoet-faq-accordion {
details {
overflow: hidden;
&:not(:first-child) {
border-top: 1px solid $color-editor-border-structure;
}
summary {
cursor: pointer;
padding: 20px 5px;
position: relative;
&::-webkit-details-marker { // remove default marker
content: '';
display: none;
}
&::marker { // remove default marker
content: '';
display: none;
}
&:after {
content: '';
font-size: 30px;
position: absolute;
right: 20px;
top: 0;
transform: rotate(90deg);
transform-origin: center;
transition: .2s transform ease;
}
@include respond-to(small-screen) {
&:after {
right: -1px;
}
}
}
.content {
max-height: 0;
overflow: hidden;
padding: 10px 5px;
transition: max-height .3s ease;
}
// when accordion is opened
&[open] {
summary:after {
transform: rotate(-90deg);
transition: .5s transform ease;
}
.content {
max-height: 400px;
transition: max-height .5s ease-in;
}
}
}
}

View File

@ -119,10 +119,6 @@
color: $color-stats-average;
}
.mailpoet-statistics-value-number-critical {
color: $color-stats-critical;
}
.mailpoet-statistics-value-number-excellent {
color: $color-stats-excellent;
}

View File

@ -22,12 +22,6 @@
}
}
#mailpoet-wizard-container {
.mailpoet-top-bar {
left: 0;
}
}
.mailpoet-wizard-logo {
margin-bottom: 100px;
text-align: center;
@ -41,7 +35,6 @@
align-items: center;
display: flex;
justify-content: center;
margin-top: 8px;
@include respond-to(medium-screen) {
flex-direction: column;
@ -49,7 +42,7 @@
}
.mailpoet-wizard-step-illustration {
margin-right: $grid-gap-xl;
margin-right: $grid-gap;
max-width: $grid-column;
text-align: center;
width: 100%;
@ -70,16 +63,12 @@
}
.mailpoet-wizard-step-content {
max-width: 480px;
max-width: $grid-column-small + $grid-gap + $grid-column;
width: 100%;
@include respond-to(medium-screen) {
max-width: $grid-column;
}
.mailpoet-button {
height: 36px;
}
}
.mailpoet-wizard-label {
@ -122,16 +111,12 @@
.mailpoet-wizard-woocommerce-option {
align-items: center;
box-shadow: 0 1px 0 0 $color-tertiary-light;
box-shadow: 0 -1px 0 0 $color-tertiary-light;
display: flex;
flex-direction: row-reverse;
justify-content: space-between;
padding-bottom: 25px;
padding-top: 1px;
&:last-child {
box-shadow: 0 0;
}
}
.mailpoet-wizard-note {

View File

@ -63,11 +63,6 @@ $form-line-height: 1.4;
.mailpoet-has-font-size {
line-height: $form-line-height;
}
.mailpoet_submit {
white-space: normal;
word-wrap: break-word;
}
}
/* Reset fieldset styles in form for backward compatibility. */

View File

@ -1,12 +0,0 @@
.mailpoet_captcha_form {
.mailpoet_icon_button {
background: transparent;
border: 0;
cursor: pointer;
img {
height: 20px;
width: 20px;
}
}
}

View File

@ -0,0 +1,63 @@
.mailpoet-automation-stats {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
margin: auto;
@at-root #mailpoet_automation_editor #{&} {
justify-content: center;
margin-bottom: 32px;
max-width: 560px;
}
.mailpoet-automation-stats-item {
color: $color-wordpress-heading;
font-size: 12px;
font-weight: 600;
line-height: 16px;
padding: 0 16px;
position: relative;
text-align: center;
@at-root #mailpoet_automation_editor #{&} {
flex-grow: 1;
}
&:first-of-type {
@at-root #mailpoet_automation #{&} {
padding-left: 0;
}
}
@at-root #mailpoet_automation_editor #{&} {
font-size: 14px;
line-height: 22px;
}
&:after {
align-items: center;
color: #a7aaad;
content: '';
display: flex;
font-size: 20px;
font-weight: normal;
height: 100%;
justify-content: center;
position: absolute;
right: 0;
top: 0;
}
&:last-of-type:after {
content: '';
}
.mailpoet-automation-stats-label {
color: #646970;
display: block;
font-size: 12px;
font-weight: 400;
line-height: 16px;
}
}
}

View File

@ -112,11 +112,3 @@
max-width: 100%;
width: 100%;
}
.authorize-sender-email-and-domain-modal {
z-index: 30; // overlay other modals
}
.authorize-sender-email-and-domain-modal-overlay {
z-index: $modal-screen-overlay-z-index + 4; // overlay other modals
}

View File

@ -41,15 +41,6 @@
}
}
.mailpoet-tag-critical {
border-color: $color-stats-critical;
color: $color-stats-critical;
&.mailpoet-tag-inverted {
background: $color-stats-critical;
}
}
.mailpoet-tag-good {
border-color: $color-stats-good;
color: $color-stats-good;

View File

@ -29,6 +29,7 @@ $beamer-dot-size: 8px;
}
.mailpoet-top-bar-logo {
cursor: pointer;
position: relative;
top: 2px;
z-index: 1;
@ -38,10 +39,6 @@ $beamer-dot-size: 8px;
max-width: 100%;
}
}
a.mailpoet-top-bar-logo {
cursor: pointer;
}
}
.mailpoet-top-bar-logo-desktop {

View File

@ -2,29 +2,22 @@
@import '../../../node_modules/@wordpress/edit-site/build-style/style';
@import '../../../node_modules/@wordpress/block-editor/build-style/style'; // for inserter styles
@import 'settings/colors';
// automation components
@import './components-automation/statistics';
// automation editor
@import './components-automation-editor/add-step-button';
@import './components-automation-editor/add-trigger';
@import './components-automation-editor/automation';
@import './components-automation-editor/block-icon';
@import './components-automation-editor/chip';
@import './components-automation-editor/dropdown';
@import './components-automation-editor/empty-automation';
@import './components-automation-editor/empty-workflow';
@import './components-automation-editor/errors';
@import './components-automation-editor/panel';
@import './components-automation-editor/separator';
@import './components-automation-editor/status';
@import './components-automation-editor/step';
@import './components-automation-editor/step-card';
@import './components-automation-editor/workflow';
@import './components-automation-editor/notices';
@import './components-automation-editor/deactivate-modal';
// integrations
@import './components-automation-integrations/mailpoet';
@import './components/automation_statistics';

View File

@ -13,34 +13,18 @@ ul.mailpoet-automation-templates {
margin: auto;
max-width: 982px;
padding: 48px 0;
}
.mailpoet-automation-template-list-item {
button.components-button {
align-content: baseline;
align-items: flex-start;
background: #fff;
border: 1px solid #dcdcde;
border-radius: 4px;
cursor: pointer;
display: grid;
grid-template-rows: 40px auto auto;
display: block;
height: 100%;
padding: 24px 24px 26px;
text-align: left;
width: 100%;
&:disabled,
&[aria-disabled='true'] {
color: #787c82;
cursor: not-allowed;
opacity: 1;
h2 {
color: #787c82;
}
}
&:hover {
background: #fff;
border: 1px solid #dcdcde;
@ -53,15 +37,12 @@ ul.mailpoet-automation-templates {
box-shadow: 0 3px 6px rgba(0, 0, 0, .15);
color: inherit;
}
>* {
width: 100%
}
}
h2 {
background: transparent;
border: none;
color: #2271b1;
font-size: 14px;
font-weight: 600;
line-height: 21px;
@ -73,7 +54,7 @@ ul.mailpoet-automation-templates {
margin: 8px 0 0;
}
&.mailpoet-automation-from-scratch {
.mailpoet-automation-from-scratch {
button {
align-content: center;
border: 2px dashed #dcdcde;
@ -90,27 +71,4 @@ ul.mailpoet-automation-templates {
fill: #dcdcde;
}
}
.badge {
text-align: right;
transform: translateX(24px);
span {
padding: 3px 8px;
}
}
}
.mailpoet-automation-template-list-item-coming-soon {
.badge span {
background: #ffe9cc;
color: #1d2327;
}
}
.mailpoet-automation-template-list-item-premium {
.badge span {
background: #ff5301;
color: #fff;
}
}

View File

@ -1,17 +1,7 @@
@import '../../../node_modules/@woocommerce/components/build-style/style';
@import 'settings/colors';
// automation components
@import './components-automation/statistics';
@import './components-automation/option-button';
// automation listing
@import './components-automation-listing/sections';
@import './components-automation-listing/listing';
@import './components-automation-listing/header';
@import './components-automation-listing/search';
@import './components-automation-listing/cells/actions';
@import './components-automation-listing/cells/status';
@import './mailpoet-automation-templates';
@import './components/automation_statistics';

View File

@ -53,7 +53,6 @@
@import 'components-editor/content-blocks/unknown_block_fallback';
@import 'components-editor/content-blocks/woocommerce-heading';
@import 'components-editor/content-blocks/woocommerce-content';
@import 'components-editor/content-blocks/coupon';
// Utilities
// Helpers and overrides.

View File

@ -1,23 +0,0 @@
@import '../../../node_modules/@woocommerce/components/build-style/style'; // Needed to load WP admin themes color variables
// Settings
// Global variables, config switches. Not producing any CSS.
@import 'settings/breakpoints';
@import 'settings/colors';
@import 'settings/grid';
@import 'settings/typography';
// Tools
// Default mixins and functions. Still not producing any CSS.
@import 'mixins/breakpoints';
// Components
// Actual UI components.
@import 'components-homepage/_layout';
@import 'components-homepage/_task-list';
@import 'components-homepage/_content-section';
@import 'components-homepage/_product-discovery';

View File

@ -85,4 +85,3 @@
@import 'components-plugin/set-from-address-modal';
@import 'components-plugin/stats';
@import 'components-plugin/import-export';
@import 'components-plugin/landingpage';

View File

@ -19,4 +19,3 @@
@import 'components-public/public';
@import 'components-public/animation';
@import 'components-public/form_colors';
@import 'components-public/captcha';

View File

@ -69,7 +69,6 @@ $color-badge-video-guide: #46b450;
$color-stats-average: #f559c3;
$color-stats-good: #ff9f00;
$color-stats-excellent: #7ed321;
$color-stats-critical: #f00;
$color-stats-unknown: $color-primary-inactive;
// Automation editor
@ -79,9 +78,3 @@ $color-chip-success-bg: #b8e6bf;
$color-chip-success-text: #005c12;
$color-chip-danger-bg: #facfd2;
$color-chip-danger-text: #8a2424;
// Landing page
$color-landingpage-background-light: #fbfbfb;
// Homepage
$color-homepage-borders: #e0e0e0;

View File

@ -1,5 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 4.75C7.99594 4.75 4.75 7.99594 4.75 12C4.75 16.0041 7.99594 19.25 12 19.25C16.0041 19.25 19.25 16.0041 19.25 12C19.25 7.99594 16.0041 4.75 12 4.75ZM3.25 12C3.25 7.16751 7.16751 3.25 12 3.25C16.8325 3.25 20.75 7.16751 20.75 12C20.75 16.8325 16.8325 20.75 12 20.75C7.16751 20.75 3.25 16.8325 3.25 12Z" fill="#d63638"/>
<path d="M13 7H11V13H13V7Z" fill="#d63638"/>
<path d="M13 15H11V17H13V15Z" fill="#d63638"/>
</svg>

Before

Width:  |  Height:  |  Size: 565 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M2 7h4l5-4v14l-5-4H2V7zm12.69-2.46C14.82 4.59 18 5.92 18 10s-3.18 5.41-3.31 5.46c-.06.03-.13.04-.19.04-.2 0-.39-.12-.46-.31-.11-.26.02-.55.27-.65.11-.05 2.69-1.15 2.69-4.54 0-3.41-2.66-4.53-2.69-4.54-.25-.1-.38-.39-.27-.65.1-.25.39-.38.65-.27zM16 10c0 2.57-2.23 3.43-2.32 3.47-.06.02-.12.03-.18.03-.2 0-.39-.12-.47-.32-.1-.26.04-.55.29-.65.07-.02 1.68-.67 1.68-2.53s-1.61-2.51-1.68-2.53c-.25-.1-.38-.39-.29-.65.1-.25.39-.39.65-.29.09.04 2.32.9 2.32 3.47z"/></g></svg>

Before

Width:  |  Height:  |  Size: 587 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path d="M10.25 1.02c5.1 0 8.75 4.04 8.75 9s-3.65 9-8.75 9c-3.2 0-6.02-1.59-7.68-3.99l2.59-1.52c1.1 1.5 2.86 2.51 4.84 2.51 3.3 0 6-2.79 6-6s-2.7-6-6-6c-1.97 0-3.72 1-4.82 2.49L7 8.02l-6 2v-7L2.89 4.6c1.69-2.17 4.36-3.58 7.36-3.58z"/></g></svg>

Before

Width:  |  Height:  |  Size: 355 B

View File

@ -18,7 +18,7 @@ import _ from 'underscore';
*/
var eventsCache = [];
function track(name, data = [], options = {}, callback = null) {
function track(name, data = []) {
let trackedData = data;
if (typeof window.mixpanel.track !== 'function') {
@ -33,7 +33,7 @@ function track(name, data = [], options = {}, callback = null) {
trackedData['MailPoet Premium version'] = window.mailpoet_premium_version;
}
window.mixpanel.track(name, trackedData, options, callback);
window.mixpanel.track(name, trackedData);
}
function exportMixpanel() {
@ -45,37 +45,24 @@ function exportMixpanel() {
) {
window.MailPoet.trackEvent = track;
} else {
window.MailPoet.trackEvent = function emptyFunction(
name,
data,
options,
callback,
) {
if (typeof callback === 'function') {
callback();
}
};
window.MailPoet.trackEvent = function emptyFunction() {};
}
}
function trackCachedEvents() {
eventsCache.forEach(function trackIfEnabled(event) {
if (window.mailpoet_analytics_enabled || event.forced) {
track(event.name, event.data, event.options);
track(event.name, event.data);
}
});
}
function cacheEvent(forced, name, data, options, callback) {
function cacheEvent(forced, name, data) {
eventsCache.push({
name: name,
data: data,
options: options,
forced: forced,
});
if (typeof callback === 'function') {
callback();
}
}
function initializeMixpanelWhenLoaded() {

View File

@ -0,0 +1,81 @@
import { useCallback, useEffect, useState } from 'react';
import { api } from '../config';
const API_URL = `${api.root}/mailpoet/v1/automation`;
export const request = (
path: string,
init?: RequestInit,
): ReturnType<typeof fetch> => fetch(`${API_URL}/${path}`, init);
type Error<T> = {
response?: Response;
data?: T;
};
type State<T> = {
data?: T;
loading: boolean;
error?: Error<T>;
};
type Result<T> = [(init?: RequestInit) => Promise<void>, State<T>];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Data = Record<string, any>;
export const useMutation = <T extends Data>(
path: string,
config?: RequestInit,
): Result<T> => {
const [state, setState] = useState<State<T>>({
data: undefined,
loading: false,
error: undefined,
});
const mutation = useCallback(
async (init?: RequestInit) => {
setState((prevState) => ({ ...prevState, loading: true }));
const response = await request(path, {
...config,
...init,
headers: {
'content-type': 'application/json',
...(init?.headers ?? {}),
'x-wp-nonce': api.nonce,
},
});
try {
const data = await response.json();
const error = response.ok ? null : { ...response, data };
setState((prevState) => ({ ...prevState, data, error }));
} catch (_) {
const error = { response };
setState((prevState) => ({ ...prevState, error }));
} finally {
setState((prevState) => ({ ...prevState, loading: false }));
}
},
[config, path],
);
return [mutation, state];
};
export const useQuery = <T extends Data>(
path: string,
init?: RequestInit,
): State<T> => {
const [mutation, result] = useMutation<T>(path, init);
useEffect(
() => {
void mutation();
},
[] /* eslint-disable-line react-hooks/exhaustive-deps -- request only on initial load */,
);
return result;
};

View File

@ -1,7 +1,9 @@
import apiFetch from '@wordpress/api-fetch';
import { api } from '../config';
const apiUrl = `${api.root}/mailpoet/v1/`;
export * from './hooks';
const apiUrl = `${api.root}/mailpoet/v1/automation/`;
export type ApiError = {
code?: string;

View File

@ -1,92 +1,136 @@
import { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { TopBarWithBeamer } from 'common/top_bar/top_bar';
import { Popover, SlotFillProvider } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { initializeApi } from './api';
import { registerTranslations } from './i18n';
import { createStore, storeName } from './listing/store';
import { AutomationListing, AutomationListingHeader } from './listing';
import { registerApiErrorHandler } from './listing/api-error-handler';
import { Notices } from './listing/components/notices';
import { BuildYourOwnSection, HeroSection, TemplatesSection } from './sections';
import { plusIcon } from 'common/button/icon/plus';
import { Button, Flex } from '@wordpress/components';
import { Workflow } from './listing/workflow';
import { AutomationListing } from './listing';
import { Onboarding } from './onboarding';
import {
CreateEmptyWorkflowButton,
CreateWorkflowFromTemplateButton,
} from './testing';
import { useMutation, useQuery } from './api';
import { WorkflowListingNotices } from './listing/workflow-listing-notices';
import { MailPoet } from '../mailpoet';
const trackOpenEvent = () => {
MailPoet.trackEvent('Automations > Listing viewed');
};
function Content(): JSX.Element {
const [isBooting, setIsBooting] = useState(true);
const count = useSelect((select) => select(storeName).getAutomationCount());
const { data, loading, error } = useQuery<{ data: Workflow[] }>('workflows');
useEffect(() => {
if (!isBooting || count === 0) {
return;
}
trackOpenEvent();
setIsBooting(false);
}, [isBooting, count]);
const content =
count > 0 ? (
<>
<AutomationListingHeader />
<AutomationListing />
</>
) : (
<HeroSection />
);
if (error) {
return <div>Error: {error}</div>;
}
// Hide notices on onboarding screen
useEffect(() => {
const onboardingClass = 'mailpoet-automation-is-onboarding';
const element = document.querySelector('body');
if (count === 0 && !element.classList.contains(onboardingClass)) {
element.classList.add(onboardingClass);
}
if (count > 0 && element.classList.contains(onboardingClass)) {
element.classList.remove(onboardingClass);
}
}, [count]);
return (
<>
{content}
<TemplatesSection />
<BuildYourOwnSection />
</>
if (loading) {
return <div>Loading workflows...</div>;
}
const workflows = data?.data ?? [];
return workflows.length > 0 ? (
<AutomationListing workflows={workflows} loading={loading} />
) : (
<Onboarding />
);
}
function Automations(): JSX.Element {
function Workflows(): JSX.Element {
return (
<>
<TopBarWithBeamer />
<Notices />
<Flex className="mailpoet-automation-listing-heading">
<h1 className="wp-heading-inline">Automations</h1>
<Button
href={MailPoet.urls.automationTemplates}
icon={plusIcon}
variant="primary"
className="mailpoet-add-new-button"
>
New automation
</Button>
</Flex>
<Content />
</>
);
}
function RecreateSchemaButton(): JSX.Element {
const [createSchema, { loading, error }] = useMutation('system/database', {
method: 'POST',
});
return (
<div>
<WorkflowListingNotices />
<button
className="button button-link-delete"
type="button"
onClick={() => createSchema()}
disabled={loading}
>
Recreate DB schema (data will be lost)
</button>
{error && (
<div>{error?.data?.message ?? 'An unknown error occurred'}</div>
)}
</div>
);
}
function DeleteSchemaButton(): JSX.Element {
const [deleteSchema, { loading, error }] = useMutation('system/database', {
method: 'DELETE',
});
return (
<div>
<button
className="button button-link-delete"
type="button"
onClick={async () => {
await deleteSchema();
window.location.href =
'/wp-admin/admin.php?page=mailpoet-experimental';
}}
disabled={loading}
>
Delete DB schema & deactivate feature
</button>
{error && (
<div>{error?.data?.message ?? 'An unknown error occurred'}</div>
)}
</div>
);
}
function App(): JSX.Element {
return (
<SlotFillProvider>
<BrowserRouter>
<Automations />
<Popover.Slot />
</BrowserRouter>
</SlotFillProvider>
<BrowserRouter>
<div>
<Workflows />
<div style={{ marginTop: 30, display: 'grid', gridGap: 8 }}>
<CreateEmptyWorkflowButton />
<CreateWorkflowFromTemplateButton slug="simple-welcome-email">
Create testing workflow from template (welcome email)
</CreateWorkflowFromTemplateButton>
<CreateWorkflowFromTemplateButton slug="welcome-email-sequence">
Create testing workflow from template (welcome sequence, only
premium)
</CreateWorkflowFromTemplateButton>
<CreateWorkflowFromTemplateButton slug="advanced-welcome-email-sequence">
Create testing workflow from template (advanced welcome sequence,
only premium)
</CreateWorkflowFromTemplateButton>
<RecreateSchemaButton />
<DeleteSchemaButton />
</div>
</div>
</BrowserRouter>
);
}
window.addEventListener('DOMContentLoaded', () => {
createStore();
const root = document.getElementById('mailpoet_automation');
if (root) {
registerTranslations();
registerApiErrorHandler();
initializeApi();
ReactDOM.render(<App />, root);
}
});

View File

@ -1,64 +0,0 @@
import { Dispatch, SetStateAction, useState } from 'react';
import { Button, DropdownMenu } from '@wordpress/components';
import { chevronDown } from '@wordpress/icons';
import { __ } from '@wordpress/i18n';
import { Fragment } from '@wordpress/element';
import { StepMoreControlsType } from '../../types/filters';
type OptionButtonPropType = {
variant: Button.ButtonVariant;
controls: StepMoreControlsType;
title: string;
onClick: (setIsBusy: Dispatch<SetStateAction<boolean>>) => void;
};
export function OptionButton({
controls,
title,
onClick,
variant,
}: OptionButtonPropType): JSX.Element {
const [isBusy, setIsBusy] = useState(false);
const slots = Object.values(controls).filter((item) => item.slot);
const dropDownMenuClassNames = isBusy
? `mailpoet-option-button-opener is-busy`
: `mailpoet-option-button-opener`;
return (
<div className="mailpoet-option-button">
<Button
isBusy={isBusy}
disabled={isBusy}
variant={variant}
className="mailpoet-option-button-main"
onClick={() => {
setIsBusy(true);
onClick(setIsBusy);
}}
>
{title}
</Button>
{slots.length > 0 &&
slots.map(({ key, slot }) => (
<Fragment key={`slot-${key}`}>{slot}</Fragment>
))}
{Object.values(controls).length > 0 && (
<DropdownMenu
className={dropDownMenuClassNames}
label={__('More', 'mailpoet')}
icon={chevronDown}
controls={Object.values(controls).map((item) => {
const control = {
...item.control,
onClick: () => {
setIsBusy(true);
item.control.onClick(setIsBusy);
},
};
return control;
})}
popoverProps={{ position: 'bottom left' }}
/>
)}
</div>
);
}

View File

@ -1,41 +0,0 @@
import { Fragment } from '@wordpress/element';
type Item = {
key: string;
label: string;
value: number;
};
type Props = {
items: Item[];
labelPosition?: 'before' | 'after';
};
export function Statistics({
items,
labelPosition = 'before',
}: Props): JSX.Element {
const intl = new Intl.NumberFormat();
return (
<div className="mailpoet-automation-stats">
{items.map((item, i) => (
<Fragment key={item.key}>
<div key={item.key} className="mailpoet-automation-stats-item">
<span
className={`mailpoet-automation-stats-label display-${labelPosition}`}
>
{item.label}
</span>
<span className="mailpoet-automation-stats-value">
{intl.format(item.value)}
</span>
</div>
{i < items.length - 1 && (
<div className="mailpoet-automation-stats-item-separator"></div>
)}
</Fragment>
))}
</div>
);
}

View File

@ -4,9 +4,7 @@ declare global {
root: string;
nonce: string;
};
mailpoet_automation_count: number;
}
}
export const api = window.mailpoet_automation_api;
export const automationCount = window.mailpoet_automation_count;

View File

@ -19,7 +19,7 @@ export const registerApiErrorHandler = (): void =>
const status = errorObject.data?.status;
const code = errorObject.code;
if (code === 'mailpoet_automation_not_valid') {
if (code === 'mailpoet_automation_workflow_not_valid') {
dispatch(storeName).setErrors({ steps: errorObject.data.errors });
return undefined;
}
@ -30,7 +30,6 @@ export const registerApiErrorHandler = (): void =>
message ?? __('An unknown error occurred.', 'mailpoet'),
{ explicitDismiss: true },
);
dispatch(storeName).setErrors({ steps: [] });
return undefined;
}

View File

@ -4,14 +4,13 @@ import {
Button,
} from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
import { __, sprintf } from '@wordpress/i18n';
import { storeName } from '../../store';
export function TrashButton(): JSX.Element {
const [showConfirmDialog, setShowConfirmDialog] = useState(false);
const { automation } = useSelect(
const { workflow } = useSelect(
(select) => ({
automation: select(storeName).getAutomationData(),
workflow: select(storeName).getWorkflowData(),
}),
[],
);
@ -21,8 +20,8 @@ export function TrashButton(): JSX.Element {
<>
<ConfirmDialog
isOpen={showConfirmDialog}
title={__('Delete automation', 'mailpoet')}
confirmButtonText={__('Yes, delete', 'mailpoet')}
title="Delete workflow"
confirmButtonText="Yes, delete"
onConfirm={async () => {
trash(() => {
setShowConfirmDialog(false);
@ -31,12 +30,7 @@ export function TrashButton(): JSX.Element {
onCancel={() => setShowConfirmDialog(false)}
__experimentalHideHeader={false}
>
{sprintf(
__('You are about to delete the automation "%s".', 'mailpoet'),
automation.name,
)}
<br />
{__(' This will stop it for all subscribers immediately.', 'mailpoet')}
You are about to delete the {workflow.name} workflow.
</ConfirmDialog>
<Button
@ -44,7 +38,7 @@ export function TrashButton(): JSX.Element {
isDestructive
onClick={() => setShowConfirmDialog(true)}
>
{__('Move to Trash', 'mailpoet')}
Move to Trash
</Button>
</>
);

View File

@ -1,9 +0,0 @@
import { __ } from '@wordpress/i18n';
export function EmptyAutomation(): JSX.Element {
return (
<div className="mailpoet-automation-editor-empty-automation">
{__('No automation data.', 'mailpoet')}
</div>
);
}

View File

@ -1,40 +0,0 @@
import { useSelect } from '@wordpress/data';
import { _x } from '@wordpress/i18n';
import { storeName } from '../../store';
import { Statistics as BaseStatistics } from '../../../components/statistics';
export function Statistics(): JSX.Element {
const { automation } = useSelect(
(select) => ({
automation: select(storeName).getAutomationData(),
}),
[],
);
return (
<div className="mailpoet-automation-editor-stats">
<BaseStatistics
items={[
{
key: 'entered',
// translators: Total number of subscribers who entered an automation
label: _x('Total Entered', 'automation stats', 'mailpoet'),
value: automation.stats.totals.entered,
},
{
key: 'processing',
// translators: Total number of subscribers who are being processed in an automation
label: _x('Total Processing', 'automation stats', 'mailpoet'),
value: automation.stats.totals.in_progress,
},
{
key: 'exited',
// translators: Total number of subscribers who exited an automation, no matter the result
label: _x('Total Exited', 'automation stats', 'mailpoet'),
value: automation.stats.totals.exited,
},
]}
/>
</div>
);
}

View File

@ -1,68 +0,0 @@
import { useState, Fragment } from 'react';
import { DropdownMenu } from '@wordpress/components';
import { moreVertical, trash } from '@wordpress/icons';
import { __ } from '@wordpress/i18n';
import { Hooks } from 'wp-js-hooks';
import { PremiumModal } from 'common/premium_modal';
import { Step as StepData } from './types';
import { StepMoreControlsType } from '../../../types/filters';
type Props = {
step: StepData;
};
export function StepMoreMenu({ step }: Props): JSX.Element {
const [showModal, setShowModal] = useState(false);
const moreControls: StepMoreControlsType = Hooks.applyFilters(
'mailpoet.automation.step.more-controls',
{
delete: {
key: 'delete',
control: {
title: __('Delete step', 'mailpoet'),
icon: trash,
onClick: () => setShowModal(true),
},
slot: () => {
if (!showModal) {
return false;
}
return (
<PremiumModal
onRequestClose={() => {
setShowModal(false);
}}
tracking={{
utm_medium: 'upsell_modal',
utm_campaign: 'remove_automation_step',
}}
>
{__('You cannot remove a step from the automation.', 'mailpoet')}
</PremiumModal>
);
},
},
},
step,
);
const slots = Object.values(moreControls).filter(
(item) => item.slot !== undefined,
);
const controls = Object.values(moreControls).map((item) => item.control);
return (
<div className="mailpoet-automation-step-more-menu">
{slots.map(({ key, slot }) => (
<Fragment key={key}>{slot()}</Fragment>
))}
<DropdownMenu
label={__('More', 'mailpoet')}
icon={moreVertical}
popoverProps={{ position: 'bottom right' }}
toggleProps={{ isSmall: true }}
controls={Object.values(controls)}
/>
</div>
);
}

View File

@ -1,16 +1,16 @@
import { ComponentProps, ComponentType, Ref } from 'react';
import {
__experimentalText as Text,
Button,
Dropdown as WpDropdown,
Button,
VisuallyHidden,
__experimentalText as Text,
} from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useRef } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { chevronDown } from '@wordpress/icons';
import { storeName } from '../../store';
import { AutomationStatus } from '../../../listing/automation';
import { WorkflowStatus } from '../../../listing/workflow';
// See: https://github.com/WordPress/gutenberg/blob/eff0cab2b3181c004dbd15398e570ecec28a3726/packages/edit-site/src/components/header/document-actions/index.js
@ -21,11 +21,11 @@ const Dropdown: ComponentType<
}
> = WpDropdown;
function DocumentActions({ children }): JSX.Element {
const { automationName, automationStatus, showIconLabels } = useSelect(
export function DocumentActions({ children }): JSX.Element {
const { workflowName, workflowStatus, showIconLabels } = useSelect(
(select) => ({
automationName: select(storeName).getAutomationData().name,
automationStatus: select(storeName).getAutomationData().status,
workflowName: select(storeName).getWorkflowData().name,
workflowStatus: select(storeName).getWorkflowData().status,
showIconLabels: select(storeName).isFeatureActive('showIconLabels'),
}),
[],
@ -36,9 +36,9 @@ function DocumentActions({ children }): JSX.Element {
const titleRef = useRef();
let chipClass = 'mailpoet-automation-editor-chip-gray';
if (automationStatus === AutomationStatus.ACTIVE) {
if (workflowStatus === WorkflowStatus.ACTIVE) {
chipClass = 'mailpoet-automation-editor-chip-success';
} else if (automationStatus === AutomationStatus.DEACTIVATING) {
} else if (workflowStatus === WorkflowStatus.INACTIVE) {
chipClass = 'mailpoet-automation-editor-chip-danger';
}
@ -64,21 +64,19 @@ function DocumentActions({ children }): JSX.Element {
as="h1"
>
<VisuallyHidden as="span">
{__('Editing automation:', 'mailpoet')}
{__('Editing workflow: ')}
</VisuallyHidden>
{automationName}
{workflowName}
</Text>
<Text
size="body"
className={`edit-site-document-actions__secondary-item ${chipClass}`}
>
{automationStatus === AutomationStatus.ACTIVE &&
__('Active', 'mailpoet')}
{automationStatus === AutomationStatus.DEACTIVATING &&
__('Deactivating', 'mailpoet')}
{automationStatus === AutomationStatus.DRAFT &&
__('Draft', 'mailpoet')}
{workflowStatus === WorkflowStatus.ACTIVE && __('Active')}
{workflowStatus === WorkflowStatus.INACTIVE &&
__('Inactive')}
{workflowStatus === WorkflowStatus.DRAFT && __('Draft')}
</Text>
</a>
<Button
@ -87,9 +85,9 @@ function DocumentActions({ children }): JSX.Element {
aria-expanded={isOpen}
aria-haspopup="true"
onClick={onToggle}
label={__('Change automation name', 'mailpoet')}
label={__('Change workflow name')}
>
{showIconLabels && __('Rename', 'mailpoet')}
{showIconLabels && __('Rename')}
</Button>
</>
)}
@ -101,6 +99,3 @@ function DocumentActions({ children }): JSX.Element {
</div>
);
}
DocumentActions.displayName = 'DocumentActions';
export { DocumentActions };

Some files were not shown because too many files have changed in this diff Show More