Compare commits

...

779 Commits

Author SHA1 Message Date
af13db4921 Release 4.5.0 2023-01-17 09:36:50 +02:00
339068c086 Set isBusy state for OptionButton
[MAILPOET-4918]
2023-01-16 14:15:23 +01:00
dad40e262f Set isBusy state for FromScratch buttons
[MAILPOET-4918]
2023-01-16 14:15:23 +01:00
0bbd65ac61 Sanitize segment data when persisty via public API
[MAILPOET-4942]
2023-01-16 13:59:30 +01:00
1a7b7d1936 Escape segment name for usage in html select
[MAILPOET-4942]
2023-01-16 13:59:30 +01:00
2bbaa246d7 Sanitize name and description of segment when saving
[MAILPOET-4942]
2023-01-16 13:59:30 +01:00
296ec54c3e Add function preparing error response
[MAILPOET-4639]
2023-01-16 13:46:07 +01:00
579de1cc86 Reduce the count of constants
[MAILPOET-4639]
2023-01-16 13:46:07 +01:00
da88250fe1 Update integration tests
[MAILPOET-4639]
2023-01-16 13:46:07 +01:00
ad831316ab Remove unused constants
[MAILPOET-4639]
2023-01-16 13:46:07 +01:00
2e97cb6924 Fix tests after last changes
[MAILPOET-4639]
2023-01-16 13:46:07 +01:00
c79787c677 Extract domain creation error messages from bridge to strings
As a part of those changes I tried to unify the array key with error messages.
[MAILPOET-4639]
2023-01-16 13:46:07 +01:00
07954dd968 Extract domain verification error messages from bridge to strings
As a part of those changes I tried to unify the array key with error messages.
[MAILPOET-4639]
2023-01-16 13:46:07 +01:00
2ace6da75b Extract email authorization error messages from bridge to strings
As a part of those changes I tried to unify the array key with error messages.
[MAILPOET-4639]
2023-01-16 13:46:07 +01:00
982568445b Extract sending error messages from bridge to strings
The original error is stored under a new key for easier handling an error state.
[MAILPOET-4639]
2023-01-16 13:46:07 +01:00
a53e446583 Add request cache to TranslationUpdater
WP may call the action we hook into more times during one request.
This commit adds simple caching to prevent multiple requests.
[MAILPOET-4909]
2023-01-12 14:08:31 +01:00
b033d7d92f Add error logging when fetching language packs info
[MAILPOET-4909]
2023-01-12 14:08:31 +01:00
1190d61ca3 Update mailpoet_shortcodes tinyMce extension to work with v6
[MAILPOET-4963]
2023-01-11 14:19:03 +01:00
7da5cc847f Make completed tasks in task list not interact-able
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
2778244faf Use nicer name for property that indicates complete task
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
3789379084 Add error boundaries to the homepage app
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
72e3c87190 Add basic acceptance test for the homepage task list
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
38640e65e4 Add complete state task titles and additional task contents
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
e0718f11ea Add message when task list is complete
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
eb7cc97ca2 Add styles for task list heading
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
24d3c0b13b Display WooCommerce import task based on customers count
We use the same logic in WooCommerce setup page
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
ec0b1d4de8 Highlight current task in task list on homepage
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
56c90ef452 Add styles and links for homepage task list
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
5f0ac0ec7e Render simple task list items with state info
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
8c767af5c6 Store homepage task list was dismissed to DB
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
b0e8263e2f Hide the task list and store the state in the store
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
be592dbf9b Add an empty wordpress/data store to homepage
We plan to add more dynamic sections to the homepage so I want to set up and use the
store from the beginning.
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
3679320483 Add dummy hide list button
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
51ab4523f8 Add basic task list component for homepage
[MAILPOET-4826]
2023-01-11 11:30:10 +01:00
60abe14c7a Remove text-domain rule from shared-ruleset
[MAILPOET-4913]
2023-01-11 07:46:57 +02:00
f58b5e61b0 Use new ruleset for free plugin
[MAILPOET-4913]
2023-01-11 07:46:57 +02:00
dbb972ec3f Create ruleset for free and premium and a shared ruleset
[MAILPOET-4913]
2023-01-11 07:46:57 +02:00
1930410754 Release 4.4.0 2023-01-10 15:45:22 +01:00
539df2a994 Switch to @wordpress/i18n and clean up
MAILPOET-4798
2023-01-10 15:23:50 +01:00
ad41ef2f5e Add FAQ accordion and contents
MAILPOET-4798
2023-01-10 15:23:50 +01:00
7ed0a92eda Add padding class to header and footer
MAILPOET-4798
2023-01-10 15:23:50 +01:00
9471314917 Add Landingpage Faq component and text
MAILPOET-4798
2023-01-10 15:23:50 +01:00
69440ec2a6 Add migration with a fix for inconsistent MailerLog data
[MAILPOET-4940]
2023-01-09 20:01:47 +01:00
0bbdf4b47f Add error log when pausing sending due an error
[MAILPOET-4940]
2023-01-09 20:01:47 +01:00
f11aca925f Do not attempt to send a confirmation email when sending is paused
When sending is paused due to some MSS configuration error the confirmation
email error may cause that the important error from MSS gets overwritten
event reset in case the mail is accidentally sent.
[MAILPOET-4940]
2023-01-09 20:01:47 +01:00
e4029a607a Adopt logging test to warning instead of error
[MAILPOET-4639]
2023-01-09 15:23:48 +01:00
eb53973799 Remove logEntity cleanup
[MAILPOET-4639]
2023-01-09 15:23:48 +01:00
aab8281af0 Remove request data from logged context
[MAILPOET-4639]
2023-01-09 15:23:48 +01:00
3df00548ab Change logged error to warning
[MAILPOET-4639]
2023-01-09 15:23:48 +01:00
ada346f4ef Add logging to php error log
[MAILPOET-4104]
2023-01-09 15:23:48 +01:00
b3691a4625 Detach invalid entity
[MAILPOET-4104]
2023-01-09 15:23:48 +01:00
e02b631172 Add log entities cleanup
[MAILPOET-4104]
2023-01-09 15:23:48 +01:00
2200411455 Add test case for logged error
[MAILPOET-4104]
2023-01-09 15:23:48 +01:00
b0ab2f404f Add logging errors to the log table
[MAILPOET-4104]
2023-01-09 15:23:48 +01:00
4195428643 Add API topic
[MAILPOET-4104]
2023-01-09 15:23:48 +01:00
1692c9bef5 Fix typo in strings
MAILPOET-4797
2023-01-09 14:38:09 +01:00
cb25cf2944 Handle redirect to welcome wizard with named function
MAILPOET-4797
2023-01-09 14:38:09 +01:00
794c5ce2d5 Extract landing page content into Header and Footer components
MAILPOET-4797
2023-01-09 14:38:09 +01:00
974d2d5a59 Add welcome_wizard_url variable
MAILPOET-4797
2023-01-09 14:38:09 +01:00
2ebcad1468 Exclude Notices from landingpage
MAILPOET-4797
2023-01-09 14:38:09 +01:00
671c7eed7d Add React landingpage component
MAILPOET-4797
2023-01-09 14:38:09 +01:00
72de76fe9b Fix multi site tests 2023-01-09 10:49:24 +01:00
53cc357632 Fix step info being rendered inside inserter popover
[MAILPOET-4922]
2023-01-06 18:31:36 +01:00
47d3472fef Fix acceptance tests error and add acceptance test for landing page
MAILPOET-4795
2023-01-06 18:29:46 +01:00
05c5b46089 Redirect to landingpage when welcome wizard is not filled
MAILPOET-4795
2023-01-06 18:29:46 +01:00
f85bd8622f Add comment explaining the usage of the method
MAILPOET-4795
2023-01-06 18:29:46 +01:00
503cf61c0f Do not redirect when activated with bulk activation mode
MAILPOET-4795
2023-01-06 18:29:46 +01:00
d9eca55189 Redirect to Landing page after plugin activation
MAILPOET-4795
2023-01-06 18:29:46 +01:00
e850eaa90c Add Landing page and hide behind feature flag
MAILPOET-4795
2023-01-06 18:29:46 +01:00
478eab61e4 Add Landingpage feature flag
MAILPOET-4795
2023-01-06 18:29:46 +01:00
ea53728799 Add period at the end of delay action description
[MAILPOET-4928]
2023-01-06 18:26:30 +01:00
914d0d37c0 Add periods at the end of automation action descriptions
[MAILPOET-4928]
2023-01-06 18:26:30 +01:00
c1aae2c192 Update usage of settings inside tinymce callbacks
Settings are now accesable via this.options.get
[MAILPOET-4213]
2023-01-04 14:46:59 +01:00
03cdcb30f8 Add missing tinymce DOM model
[MAILPOET-4213]
2023-01-04 14:46:59 +01:00
a462e72b30 Update name of the used plugin from formatselect to blocks
In v6 formatselect is renamed to blocks
[MAILPOET-4213]
2023-01-04 14:46:59 +01:00
83db3db90d Remove explicit addition of paste plugin as it's added to core
[MAILPOET-4213]
2023-01-04 14:46:59 +01:00
9495a40900 Convert TextEditorBehavior.js to TS
[MAILPOET-4213]
2023-01-04 14:46:59 +01:00
dbc2c9c240 Update tinymce package
[MAILPOET-4213]
2023-01-04 14:46:59 +01:00
d6bd1a5527 Release 4.3.1 2023-01-03 13:58:02 -06:00
c5cd863f15 Use database() value for column existing detection
[MAILPOET-4916]
2023-01-02 14:37:33 +01:00
8ef1bfaf24 Add acceptance test for homepage basic functionality
[MAILPOET-4825]
2023-01-02 14:13:53 +01:00
abac8d7147 Move MailerError notice component to notices namespace
[MAILPOET-4825]
2023-01-02 14:13:53 +01:00
367bcaf233 Refactor MailerError notice props to camel case
[MAILPOET-4825]
2023-01-02 14:13:53 +01:00
fdbb9428d9 Refactor MailerError notice to Typescript
[MAILPOET-4825]
2023-01-02 14:13:53 +01:00
bd047a0108 Automatically hide MailerError notice after resuming sending
[MAILPOET-4825]
2023-01-02 14:13:53 +01:00
05202d572f Add Mailer Error notice to homepage
This commit reuses the MailerError component to render important errors related to issues in sending.

I needed to slightly modify the MailerError notice component to be able to render as inline notice.
When rendered as non-inline WordPress JS code grabbed it and moved in DOM breaking all callbacks.
[MAILPOET-4825]
2023-01-02 14:13:53 +01:00
a698e416ad Allow all permanent notices on all pages except the wizard page
[MAILPOET-4825]
2023-01-02 14:13:53 +01:00
1efc417f82 Add TransactionalEmailsProposeOptInNotice on homepage
[MAILPOET-4825]
2023-01-02 14:13:53 +01:00
4dc31bbdb0 Add InvalidMssKeyNotice to homepage
[MAILPOET-4825]
2023-01-02 14:13:53 +01:00
12dc727fda Refactor SubscribersLimitNotice to TS
[MAILPOET-4825]
2023-01-02 14:13:53 +01:00
6602103d0f Add email volume limit notice
[MAILPOET-4825]
2023-01-02 14:13:53 +01:00
f3e8fb8ae2 Add subscribers limit notice to homepage
[MAILPOET-4825]
2023-01-02 14:13:53 +01:00
a205d4d7f4 Add basic support for dynamic notices
[MAILPOET-4825]
2023-01-02 14:13:53 +01:00
1783ca6e42 Add basic top bar with beamer at homepage
[MAILPOET-4825]
2023-01-02 14:13:53 +01:00
6555833fb6 Add test case for scheduled tasks
[MAILPOET-3995]
2023-01-02 12:07:24 +01:00
ce3b9b2b7b Remove redundant variables
[MAILPOET-3995]
2023-01-02 12:07:24 +01:00
1a653c5676 Add small code style improvements
[MAILPOET-3995]
2023-01-02 12:07:24 +01:00
85a8d8aedb Move more specific conditions into private methods
[MAILPOET-3995]
2023-01-02 12:07:24 +01:00
5c453fcd54 Add list of simple workers
To avoid code repetition I added a const with a list of simple workers that was used in a loop.
[MAILPOET-3995]
2023-01-02 12:07:24 +01:00
ec9adf8a6c Add missing test cases
[MAILPOET-3995]
2023-01-02 12:07:24 +01:00
b5064ca46f Remove old model from WordPressTest
[MAILPOET-3995]
2023-01-02 12:07:24 +01:00
84b97ead76 Make parameter scheduledAt optional
[MAILPOET-3995]
2023-01-02 12:07:24 +01:00
4e578238f7 Improve code style in WordPressTest
[MAILPOET-3995]
2023-01-02 12:07:24 +01:00
bb6d6137aa Stop checking if website is on HTTPS for 1-click-unsubscribe
[MAILPOET-4859]
2022-12-29 11:18:25 +01:00
74c7728e3a Fix issue with passing too few params to tested class 2022-12-28 20:02:36 +03:00
e13113e38b Fix condition for pausing sending when confirmation emails fail
[MAILPOET-4736]
2022-12-28 14:25:56 +01:00
68db0dbefe Don't process soft sending errors via MailerLog in confirmation mailer
Soft errors are usually related to the particular email address. We don't want to
pause sending due soft errors.
[MAILPOET-4736]
2022-12-28 14:25:56 +01:00
e015302a94 Update the confirmation email error message
[MAILPOET-4736]
2022-12-28 14:25:56 +01:00
20fcf23f8f Add processing of sending errors to the confirmation mailer
[MAILPOET-4736]
2022-12-28 14:25:56 +01:00
11beebf74d Add MailerLog method for handling transactional emails errors
The new method allows processing sending errors that happen when sending from other places of plugin
then from the Sending Queue worker.
After three failed attempts it pauses the sending and admin user will see an notice.
[MAILPOET-4736]
2022-12-28 14:25:56 +01:00
5a53406d33 Show error in form if confirmation email fails
[MAILPOET-4736]
2022-12-28 14:25:56 +01:00
ee83e4d748 Refactor SubscriberActions:subscribe to return status of confirmation email
We need to pass the error or success info about the confirmation email
in order to be able to be able to display the error message.
[MAILPOET-4736]
2022-12-28 14:25:56 +01:00
970db8f0d8 Prevent undefined function request_filesystem_credentials error
The function request_filesystem_credentials was not loaded when
running translation update during regular page load.
This commit ensures the function is loaded.
[MAILPOET-4902]
2022-12-28 13:24:47 +01:00
71828f9f6e Fix WC Checkout test by stoping to toggle removed setting
Starting from wc@7.2 the WC Blocks compatible version's
Checkout block doesn't offer the option to enable/disable
creating checkout on checkout, and this is only controllled
via the WC settings page

[MAILPOET-4925]
2022-12-23 10:28:35 +01:00
0525dd0f56 Update cerdic/css-tidy to version 2.0.3 to remove PHP 8.2 warnings
PHP 8.2 deprecates dynamic properties. The version of the Composer package cerdic/css-tidy that we are using relies on dynamic properties and thus MailPoet is generating a few deprecation warnings when running with PHP 8.2. Updating cerdic/css-tidy to the latest version remove those warnings as this was already fixed by the package maintainers.

[MAILPOET-4857]
2022-12-21 10:50:05 +01:00
e3ba525195 Unify inheritance with other processors
[MAILPOET-4735]
2022-12-21 10:07:35 +01:00
1eed55cbce Indicate optional processors
[MAILPOET-4735]
2022-12-21 10:07:35 +01:00
fd1331e602 Add plugins version to logs
[MAILPOET-4735]
2022-12-21 10:07:35 +01:00
02b82c04f3 Release 4.3.0 2022-12-20 16:25:45 +01:00
ad5ef6ebbc Fix ESLint errors after rebasing PR
Use async/await for promisses. Similar to what was discussed here: https://github.com/mailpoet/mailpoet/pull/4603#discussion_r1048950706

This is the ESLint error that started happening after the rebase:

```
mailpoet/assets/js/src/wizard/woocommerce_controller.tsx
  71:11  error  Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator  @typescript-eslint/no-floating-promises
```

[MAILPOET-4815]
2022-12-19 21:37:42 +01:00
3c5bc5b384 Fix issue in wizard.tsx with using Route.render
Route.render expects other types than the one coming out of
withBoundary, replacing it with Route.component fixes the
typing issue

[MAILPOET-4815]
2022-12-19 21:37:42 +01:00
f229df0383 Replace void with async/await based on input from PR reviewer
See https://github.com/mailpoet/mailpoet/pull/4603#discussion_r1048950706

[MAILPOET-4815]
2022-12-19 21:37:42 +01:00
9092f892d0 Refactor webpack_admin_index.jsx to TypeScript
[MAILPOET-4815]
2022-12-19 21:37:42 +01:00
9c3fb0856f Refactor wizard.jsx to TypeScript
[MAILPOET-4815]
2022-12-19 21:37:42 +01:00
2a8c665e12 Refactor welcome_wizard_controller.jsx to TypeScript
[MAILPOET-4815]
2022-12-19 21:37:42 +01:00
9b1942ce48 Refactor sender_step.jsx to TypeScript
[MAILPOET-4815]
2022-12-19 21:37:42 +01:00
932b4532f0 Change ReinstallFromScratch test now that the Welcome Wizard is mandatory
This commit updates the ReinstallFromScratch test now that the logic for
displaying the Welcome Wizard changed in
afba41ad27b8b72e892892fe386b48b5a6f59b9b. Before just loading the wizard
once was enough to dismiss it, now it is necessary to complete it. In
this commit, an utility function was created and it is used to dismiss
the wizard twice in the modified test.

[MAILPOET-4815]
2022-12-19 21:37:42 +01:00
6533a1444d Display submenu entries only after the Welcome Wizard is completed
[MAILPOET-4815]
2022-12-19 21:37:42 +01:00
05a109dcf4 Force users to complete the Welcome Wizard
This commit changes the behavior of the Welcome Wizard. Up until now,
the wizard would load once and users could opt to complete or skip it.
Now it is mandatory for the users to complete the wizard. Before we
saved the setting "version" the first time the first step of the wizard
was loaded and now we saved it when the wizard is completed.

[MAILPOET-4815]
2022-12-19 21:37:42 +01:00
5b5b7856c6 Use DI container to get an instance of Menu to simplify MenuTest
By using the DI container to get an instance of Menu we simplify
MenuTest and avoid the need to change MenuTest::getMenu() every time the
signature of the constructor of the Menu class changes, which will
happen in a subsequent commit.

[MAILPOET-4815]
2022-12-19 21:37:42 +01:00
4ceb508218 Fix typo 2022-12-19 21:37:42 +01:00
3afc7dc140 Change button in the first step of the welcome wizard
This commit changes the button "Finish later" of the first step of the
welcome wizard to "Skip this step". Both the label and the functionality
of the button changed.

[MAILPOET-4815]
2022-12-19 21:37:42 +01:00
1c1058667b Change copy of the first step of the welcome wizard
[MAILPOET-4815]
2022-12-19 21:37:42 +01:00
129aed2ae9 Add minimal error boundary to Automation app
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
f8c7adf5a6 Add error boundary to common components
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
6346d39507 Add erro boundary to newsletter app
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
1b76f3b862 Add error boundary to form editor app
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
40c140a631 Add error boundary to wizard app
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
7fd11d4fb5 Add error boundary to subscriber import/export app
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
7fa694314b Add error boundary to logs namespace
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
080e385b02 Add error boundary to experimental_features.jsx
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
7c0b625793 Add error boundaries to logs.tsx
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
f0b858b1f8 Add error boundery to underlying components in forms/forms.jsx
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
b218663e7e Add error boundary to segments/segments.jsx
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
d8ea29423d Add error boundary to newsletters_editor/initialize.jsx
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
ff038a1c56 Wrap inner components of newsletters.jsx in erro boundary
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
588e8fca6b Use withBoundary HOC in subscribers.jsx
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
8d9f23d5f8 Define error boundary and relevant HOC
[MAILPOET-4706]
2022-12-19 17:02:00 +01:00
ea4637c740 Add the possibility to skip hooks when subscribing to segments
[PREMIUM-214]
2022-12-19 12:04:28 +01:00
c0e56a4f92 Expose checkbox control
[PREMIUM-214]
2022-12-19 12:04:28 +01:00
53a4722e91 Add remove-from-list step placeholder
[PREMIUM-214]
2022-12-19 12:04:28 +01:00
d175870adf Add add-to-list step placeholder
[PREMIUM-214]
2022-12-19 12:04:28 +01:00
a64229f688 Fix automation template variables being loaded too late
[PREMIUM-214]
2022-12-19 12:04:28 +01:00
cd69e1e7b9 Refactor woocommerce_controller.jsx to TypeScript
[MAILPOET-4817]
2022-12-17 13:16:30 +01:00
321db0b004 Refactor woo_commerce_step.jsx to TypeScript
While renaming the file, I also opted to remove the underscore in
between "woo" and "commerce" as it is more common to spell "woocommerce"
without the underscore in file names and we already have at least
woocommerce_controller.jsx.

[MAILPOET-4817]
2022-12-17 13:16:30 +01:00
aaf01475b0 Simplify code to redirect to next step based on review feedback
See https://github.com/mailpoet/mailpoet/pull/4605#discussion_r1044404486

[MAILPOET-4817]
2022-12-17 13:16:30 +01:00
1cd38a396e Add parent container to the list of options in the WooCommerce step
This parent container is needed so that the last-child CSS pseudo
selector that was added in #4602 works to remove the horizontal line
from the last .mailpoet-wizard-woocommerce-option.

[MAILPOET-4817]
2022-12-17 13:16:30 +01:00
1f1c9dd077 Update copy of the Woo step of the Welcome Wizard
[MAILPOET-4817]
2022-12-17 13:16:30 +01:00
0da6d84309 Welcome Wizard: invert the order of the Woo and MSS steps
Now the Woo step comes first and then the MSS step which is always the
last step.

[MAILPOET-4817]
2022-12-17 13:16:30 +01:00
3a05598166 Improve comparison stability in test
[MAILPOET-4886]
2022-12-16 15:39:43 +01:00
5035d64298 Update the layout of the horizontal lines in the second step of the Welcome Wizard
In the second step of the wizard, it was necessary to add a <div> as a
container for all of the options, so that we could use the CSS
pseudo-class `last-child` to remove the horizontal line from the last
option.

[MAILPOET-4816]
2022-12-16 14:54:46 +01:00
56f6d20244 Update copy of the title of the second step of the Welcome Wizard
[MAILPOET-4816]
2022-12-16 14:54:46 +01:00
650d730c3f Fix lowercased captcha on built-in CAPTCHA buttons
[MAILPOET-4915]
2022-12-16 14:27:49 +01:00
decaa0f636 Fix typos
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
c2b9e33b79 Show error background in FormTokenField
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
34347f241d Add RemoveTag action stub
[PREMIUM-216]
2022-12-16 14:11:34 +01:00
5802f2132d Use badRequest method instead of throwing an InvalidState exception
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
8e502e5f50 Rename save method to create
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
0187f0cede change date keys
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
8457aa7e2b Remove ToDo comments
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
67156b7c6f Expose wordpress/components/spinner
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
f9250b66a9 Export wordpress/data-controls
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
1fcdccaa33 Expost json api endpoint
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
5b93b88f46 Add Tags endpoint
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
cbd41cd1be Remove unnecessary styles
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
95a8943b7e Use span instead of paragraph
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
dd363370f6 Remove white space
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
1027a6a676 Move FormTokenField to editor components
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
0fd93b0ff9 Show Upsell and LockedBadge
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
bfade87b62 Add Badge with locked symbol
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
26d9030544 Expose PanelBody via @wordpress/components
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
5688a0daea Rename filter to mailpoet.automation.register_step_type
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
92996ac781 Make mailpoet_tags available globally
[MAILPOET-4423]
2022-12-16 14:11:34 +01:00
1f471782ab Add Action stub 'Add Tag'
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
320459eaab Add filter mailpoet.register_step_type
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
e65b2cce02 Expose components for premium
[PREMIUM-213]
2022-12-16 14:11:34 +01:00
520ee981d3 Fix autosaving when activation link is missing
MAILPOET-4649
2022-12-15 18:15:01 +01:00
f100ef72da Add tracking and reporting information
MAILPOET-4649
2022-12-15 18:15:01 +01:00
146e1c871f Remove preview button
The preview button is a nice addition to the confirmation email template, but it's currently not part of the Jira ticket spec.

MAILPOET-4649
2022-12-15 18:15:01 +01:00
669367c9c6 Update texts and fix editor saving template with missing activation link
MAILPOET-4649
2022-12-15 18:15:01 +01:00
77d62c431a Fix coding style issues
MAILPOET-4649
2022-12-15 18:15:01 +01:00
4a5fc507ca Add tests for ConfirmationEmailCustomizer
MAILPOET-4649
2022-12-15 18:15:01 +01:00
06f59dd320 Update JS tests
MAILPOET-4649
2022-12-15 18:15:01 +01:00
4367f44449 Add support for confirmation email in newsletter editor
MAILPOET-4649
2022-12-15 18:15:01 +01:00
856e0f69d3 Add text contents and data required for confirmation email editor
MAILPOET-4649
2022-12-15 18:15:01 +01:00
c4bd2acd84 Update tests
MAILPOET-4649
2022-12-15 18:15:01 +01:00
210c240aab Update ConfirmationEmailMailer to support custom confirmation email created with the email editor from template
Setup confirmation email customizer in ConfirmationEmailMailer and trigger confirmation email template creation when visual subscription confirmation emails is enabled from settings

MAILPOET-4649
2022-12-15 18:15:01 +01:00
d19f5dc732 Add ConfirmationEmailCustomizer class and confirmation email template
MAILPOET-4649
2022-12-15 18:15:01 +01:00
6541c20466 Hide both “Email subject” and “Email content” when ConfirmationEmailCustomizer is enabled
MAILPOET-4649
2022-12-15 18:15:01 +01:00
3952484848 Add openEmailCustomizer action used by the ConfirmationEmailCustomizer component
MAILPOET-4649
2022-12-15 18:15:01 +01:00
7d918604c3 Add ConfirmationEmailCustomizer component and setup types
MAILPOET-4649
2022-12-15 18:15:01 +01:00
ffaf5b88b6 Configure integration tests oldest to use MYISAM and MySQL 5.5
[MAILPOET-4832]
2022-12-14 12:00:49 +01:00
eca4a9e923 Add integration test to ensure correct unique varchar indexes
[MAILPOET-4832]
2022-12-14 12:00:49 +01:00
1cee4e67e8 Print DB tables with engine and collation on test env star
[MAILPOET-4832]
2022-12-14 12:00:49 +01:00
b1c35b60d8 Configure acceptance tests oldest to use MYISAM db engine
[MAILPOET-4832]
2022-12-14 12:00:49 +01:00
1e5cfb4eaf Switch acceptance tests oldest to MYSQL 5.5
[MAILPOET-4832]
2022-12-14 12:00:49 +01:00
5e5956420f Release 4.2.0 2022-12-13 13:34:21 +01:00
78446d174a Fix quotes in a queries processed by $wpdb
These queries failed when ANSI_QUOTES mode is enabled
[MAILPOET-4887]
2022-12-12 13:59:09 +01:00
917d64a3e3 Print sql_mode when starting test environment
[MAILPOET-4887]
2022-12-12 13:59:09 +01:00
a3d51b2b08 Add ANSI and ONLY_FULL_GROUP_BY to sql_mode for tests environment
The default modes shipped with the mysql or mariaDB docker containers are
STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
In this commit I added ANSI, ONLY_FULL_GROUP_BY so that we are sure that we don't break compatibility with those modes
[MAILPOET-4887]
2022-12-12 13:59:09 +01:00
3ffbd6e236 Add ANSI and ONLY_FULL_GROUP_BY to sql_mode for dev environment
The default modes shipped with the mysql or mariaDB docker containers are
STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
in this commit I added ANSI, ONLY_FULL_GROUP_BY so that we are sure that we don't break compatibility with those modes
[MAILPOET-4887]
2022-12-12 13:59:09 +01:00
9753331d52 Improve sql_mode replace code to support both ANSI and ANSI_QUOTES
[MAILPOET-4887]
2022-12-12 13:59:09 +01:00
b266edb8e7 Make initial migration ANSI_QUOTES compatible
We run the initial migrations via dbDelta which internally uses
$wpdb. ANSI_QUOTES is not on the list of WPDB's incompatible modes
(767bdad516/wp-includes/class-wpdb.php (L648-L655))
So we need to make sure SQL queries we run through wpdb are ANSI_QUOTES compatible.
This commit makes initial migrations compatible with the ANSI_QUETES mode.
[MAILPOET-4887]
2022-12-12 13:59:09 +01:00
f1899055b8 Drop StepType from mailpoet.automation.step.more-controls filter
[MAILPOET-4889]
2022-12-12 12:23:52 +01:00
c3f0a36665 Make it possible to display the MP logo without a link
[MAILPOET-4819]
2022-12-08 13:30:12 +01:00
88efb1f3d1 Move logo to the top bar in the welcome wizard
[MAILPOET-4819]
2022-12-08 13:30:12 +01:00
146f5881f7 Adjustments to the layout of the welcome wizard layout
[MAILPOET-4819]
2022-12-08 13:30:12 +01:00
3279fb1154 Move regexes out of KeyActivation to avoid rerunning them in every render
[MAILPOET-4749]
2022-12-08 11:00:09 +01:00
5f5efbe876 Change title and description of the key activation settings tab
This commit changes the text of the title and the description of the key
activation settings tab to hopefully make it more clear the meaning of the
key and what they should do if they don't have one or if they are unsure
where they can get their key.

[MAILPOET-4749]
2022-12-08 11:00:09 +01:00
12afcfb656 Improve readability
[MAILPOET-3487]
2022-12-07 11:53:48 +01:00
0aac9e9d60 Test language switches in newsletters
[MAILPOET-3487]
2022-12-07 11:53:48 +01:00
4e3b1527cd If no translation for the current language exists, return 'en'
[MAILPOET-3487]
2022-12-07 11:53:48 +01:00
b27dcdd40a Use new language function in twig email templates
[MAILPOET-3487]
2022-12-07 11:53:48 +01:00
7b584dd482 Add language function to twig
[MAILPOET-3487]
2022-12-07 11:53:48 +01:00
5e71d94b62 Use website language for newsletters
[MAILPOET-3487]
2022-12-07 11:53:48 +01:00
8bb4338627 Inject WPFunctions
[MAILPOET-3487]
2022-12-07 11:53:48 +01:00
4bcd4a2cf2 Add single const to expose shortcodes for unsubscribe link
[MAILPOET-4862]
2022-12-07 10:52:07 +01:00
ea7971cb3b Translate the shortcode for instance unsubscribe link
The [link:subscription_instant_unsubscribe_url] shown on
stats page was not translated

[MAILPOET-4862]
2022-12-07 10:52:07 +01:00
9036b210a0 Add test for click stat recording for 1-click
[MAILPOET-4862]
2022-12-07 10:52:07 +01:00
f337ac388b Fix wrong assertions in PagesTest
[MAILPOET-4862]
2022-12-07 10:52:07 +01:00
b0ae21ec60 Record click stat for 1-click unsubscribe
[MAILPOET-4862]
2022-12-07 10:52:07 +01:00
7d11eeeddd Add triggering of the actionScheduler
[MAILPOET-4899]
2022-12-07 07:42:03 +01:00
4577ca5476 Fix tests
[MAILPOET-3982]
2022-12-06 14:17:49 +01:00
846794b60d Improve Cron error message
This commit gives more context to the maximum execution limit error

[MAILPOET-3982]
2022-12-06 14:17:49 +01:00
5757af95aa Release 4.1.1 2022-12-06 13:04:01 +01:00
b8c3b38652 Skip SwitchingLanguagesCest on release branch
The test would fail because the translations packs are not ready
at the time when we prepare the release.
[MAILPOET-4863]
2022-12-05 12:02:15 +01:00
3d21e4f35e Increase retries when waiting for languages update to be available
[MAILPOET-4863]
2022-12-05 12:02:15 +01:00
73ce89d051 Mention both forms and emails when describing 3rd-party libraries and Google Fonts
[MAILPOET-4888]
2022-12-05 11:59:48 +01:00
49d9dd666b Fix coding styles issues in DisableMailFunctionNotice
[MAILPOET-4760]
2022-12-05 11:59:16 +01:00
53dda33c02 Update method and constant name
MAILPOET-4760
2022-12-05 10:25:28 +01:00
9b9f61bf13 Only queue test mail for sending when the mailpoet sending method is updated
MAILPOET-4760
2022-12-05 10:25:28 +01:00
651e2d3c56 Update tests and refactor method name
MAILPOET-4760
2022-12-05 10:25:28 +01:00
0bd627d3b1 Add support for checking misconfiguration of the PHP mail function
Some hosts do perform intentional misconfiguration of the mail function, causing it not to work.

When the mail function is misconfigured, we can still access and execute the mail function from within the codebase, but we get an error.

There’s no accurate way to know the PHP mail function is misconfigured. Unless we execute the function with all the proper parameters and check the exception error message against this error `Could not instantiate mail function.`

MAILPOET-4760
2022-12-05 10:25:28 +01:00
99d0eede80 Add tests for DisabledMailFunctionNotice
MAILPOET-4760
2022-12-05 10:25:28 +01:00
d09b4ca409 Add check for mail function and display notice if disabled
MAILPOET-4760
2022-12-05 10:25:28 +01:00
caa76983e4 Ensure action scheduler jobs are done
[MAILPOET-4864]
2022-12-02 14:58:48 +01:00
7b6bbb0bc3 Remove unnecessary integration test job for woo
After the release of HPOS we no longer need to install the special Woo build and
that caused that integration_test_woocommerce job and integration_test_woo_cot_off job
have completely same configuration.
This commit removes one of those job.
[MAILPOET-4880]
2022-12-01 12:20:42 -03:00
cdf7c81a94 Remove unnecessary acceptance_tests_woo_cot_off job
The same set of tests run within acceptance_tests_base_and_woo_cot_off job
[MAILPOET-4880]
2022-12-01 12:20:42 -03:00
86812c5259 Rename acceptance test job to contain info about HPOS configuration
[MAILPOET-4880]
2022-12-01 12:20:42 -03:00
657302b720 Simplify <Tags> component and add wrapper components
[MAILPOET-4628]
2022-12-01 13:36:18 +01:00
172b5215d2 Fix strict types definition spacing
[MAILPOET-4879]
2022-11-30 12:39:19 +01:00
52a9d9f76c Remove redundant name from package.json 2022-11-30 12:30:52 +01:00
8eb7a48d3e Fix display of Text option in the editor sidebar
[MAILPOET-4808]
2022-11-30 12:30:52 +01:00
a8bceffc9c Add forgotten strict_types to Homepage page class
[MAILPOET-4824]
2022-11-30 11:42:41 +01:00
2c728c793a Redirect to main page instead of emails page from logo and after reinstall
[MAILPOET-4824]
2022-11-30 11:42:41 +01:00
8d974d8147 Add mainPageSlug to MailPoet module
In some places we hardcode emails page as the main page.
This property is meant to be used in places where we want to link
to main plugin page so that the links change when homepage is active
[MAILPOET-4824]
2022-11-30 11:42:41 +01:00
8fbc5c270a Place home at the first position in submenu
[MAILPOET-4824]
2022-11-30 11:42:41 +01:00
92dc5921df Set main page to homepage in case the feature is active
[MAILPOET-4824]
2022-11-30 11:42:41 +01:00
3c3ce37720 Temporarily add static property for MAIN_PAGE_SLUG
We need to be able to change it when homepage feature is active.
When we remove the feature flag will switch back to using constant.
Note I also kept the constant in case a third party plugin uses it.
[MAILPOET-4824]
2022-11-30 11:42:41 +01:00
f369e399ed Distinguish main page and emails page
There are some cases where we link or redirect to main page but
actually we want to redirect to emails page. It happens that currently they are
the same page, but we need to distinguish these cases for the future when
we switch the main page to new homepage.
[MAILPOET-4824]
2022-11-30 11:42:41 +01:00
01aa1e1e52 Refactor page slugs into constants
[MAILPOET-4824]
2022-11-30 11:42:41 +01:00
2bbc1b7063 Add homepage page and submenu item hidden behind feature flag
[MAILPOET-4824]
2022-11-30 11:42:41 +01:00
04b8a0ed73 Add feature flag for homepage
[MAILPOET-4824]
2022-11-30 11:42:41 +01:00
761f7c6537 Prevent issues if other plugins define WC function
It's possible that other plugins might define wc_get_page_id, so it's
more important to know that WC is installed/active than to know if the
function itself exists.

For good measure I'm including a cast to int even though the WC version
of the function always returns an integer. This is probably unnecessary
but it protects us from the possibility of the WC version of the
function returning something other than an integer in the future.

[MAILPOET-4834]
2022-11-30 11:03:40 +01:00
723dc2c9d3 Fix type errors in tests
[MAILPOET-2688]
2022-11-29 15:04:09 +01:00
d66fbb1c20 Fix confirmed IP value in tests
[MAILPOET-2688]
2022-11-29 15:04:09 +01:00
c2107b8d59 Enable strict types rule for all files
[MAILPOET-2688]
2022-11-29 15:04:09 +01:00
926620e8f8 Ignore strict types rule in all existing files that don't have it
[MAILPOET-2688]
2022-11-29 15:04:09 +01:00
82aeb89854 Use strict types in tests
[MAILPOET-2688]
2022-11-29 15:04:09 +01:00
c67c58709b Unify spacing of declare statements
[MAILPOET-2688]
2022-11-29 15:04:09 +01:00
75b5958a53 Release 4.1.0 2022-11-29 13:56:02 +01:00
bba5101669 Replace switching groups' tab by a new function
[MAILPOET-4861]
2022-11-29 10:58:11 +01:00
b9c5dddbaf Try switch group multiple times
[MAILPOET-4861]
2022-11-29 10:58:11 +01:00
0566b3f5fa Fix remaining code style issues
[MAILPOET-4850]
2022-11-28 22:24:54 +01:00
ac4adac1ab Fix test class name
[MAILPOET-4850]
2022-11-28 22:24:54 +01:00
33a9097719 Fix trim(null) issue
[MAILPOET-4850]
2022-11-28 22:54:13 +03:00
08c74cdf8b Fix SlevomatCodingStandard.Namespaces.UnusedUses.MismatchingCaseSensitivity
[MAILPOET-4850]
2022-11-28 22:54:13 +03:00
8c5222d850 Fix WordPress.Security.ValidatedSanitizedInput.InputNotSanitized and related errors
[MAILPOET-4850]
2022-11-28 22:54:13 +03:00
08c76a46af Fix Squiz.Classes.ClassFileName.NoMatch and related errors
[MAILPOET-4850]
2022-11-28 22:54:13 +03:00
3d24cb1deb Fix Generic.Classes.DuplicateClassName.Found
[MAILPOET-4850]
2022-11-28 22:54:13 +03:00
a151f93be1 Fix Generic.CodeAnalysis.JumbledIncrementer.Found
[MAILPOET-4850]
2022-11-28 22:54:13 +03:00
bce6a06c15 Fix Sniffs.ControlSignature.Found
[MAILPOET-4850]
2022-11-28 22:54:13 +03:00
10a6e387f3 Fix Squiz.Scope.MethodScope.Missing
[MAILPOET-4850]
2022-11-28 22:54:13 +03:00
b6a37f274c Fix Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
[MAILPOET-4850]
2022-11-28 22:54:13 +03:00
2cdbc68643 Fix Squiz.Classes.ValidClassName.NotCamelCaps
[MAILPOET-4850]
2022-11-28 22:54:13 +03:00
7db40b27b5 Fix errors automatically with phpcbf
[MAILPOET-4850]
2022-11-28 22:54:13 +03:00
b1760ff676 Add MinimalPluginStandard to lint-staged command
[MAILPOET-4850]
2022-11-28 22:54:13 +03:00
293eef2c78 Add MinimalPluginStandard to Robofile
./do qa:minimal-plugin-standard will not execute the MinimalPluginStandard phpcs sniffs
./do qa:php has been extended to include the sniffs as well

[MAILPOET-4850]
2022-11-28 22:54:13 +03:00
299c6b779e Remove MinimalPluginStandard from ruleset
[MAILPOET-4850]
2022-11-28 22:54:13 +03:00
842f435976 Add default value for method to StatisticsUnsubscribeEntity
When entity is created the default value is not set and it may causes
failures when it is not set additionally.
This commit sets default value and also defines a constant for the default value.
[PREMIUM-211]
2022-11-28 18:21:52 +01:00
11faf925cc Refactor time assertions in AutomaticEmailTest to use assert with delta
Carbon:setTestNow was not working because we are instantiating the new Carbon instance with value.
This commit updates all DateTime assertions to use the new assertEqualDateTimes method
[MAILPOET-4867]
2022-11-28 14:19:30 +01:00
1295aa21cc Skip congratulatory email if we know it will fail
[MAILPOET-4641]
2022-11-28 14:12:50 +01:00
84cd137c76 Don't switch to MSS when activating key without sending
[MAILPOET-4641]
2022-11-28 14:12:50 +01:00
37067dff67 Add state to MSS key check response
[MAILPOET-4641]
2022-11-28 14:12:50 +01:00
c7f850e1ba Declare strict types
[MAILPOET-4842]
2022-11-28 13:03:06 +01:00
b25f2cd5f4 Enable a Trigger to activate a second automation
[MAILPOET-4842]
2022-11-28 13:03:06 +01:00
af95080b67 Add test for TriggerHandler
[MAILPOET-4842]
2022-11-28 13:03:06 +01:00
6b8c35d5fe Fix Manage Sender Domain modal hides underneath Preview newsletter modal
MAILPOET-4812
2022-11-28 12:14:52 +01:00
a35e0dced4 Accept null opt-in values for in Woo Blocks integration
[MAILPOET-4804]
2022-11-28 11:51:27 +01:00
c6259eb185 Create acceptance test container upfront with one retry
This is and attempt to fix random issue with
Error response from daemon: Conflict. The container name "/wordpress_X" is already in use
[MAILPOET-4851]
2022-11-28 09:14:56 +01:00
670017b342 Update nesbot/carbon to the latest version
This is needed for MailPoet to work well with the upcoming PHP 8.2.

nesbot/carbon versions previous to 2.62.1 could cause issues when used
with PHP 8.2, see this PR for more information:
https://github.com/briannesbitt/Carbon/pull/2663

Without this update MailPoet users will see the following fatal error
when using PHP 8.2:

```
TypeError
MailPoetVendor\Carbon\Carbon::setLastErrors(): Argument #1 ($lastErrors) must be of type array, bool given, called in /srv/www/mp/public_html/wp-content/plugins/mailpoet/vendor-prefixed/nesbot/carbon/src/Carbon/Traits/Creator.php on line 567
```

[MAILPOET-4838]
2022-11-26 09:38:05 +01:00
ce7b210da9 Bump tested up to
[MAILPOET-4841]
2022-11-26 09:09:00 +01:00
1a2d8b8d40 Add saving nicename for created WP users
[MAILPOET-4841]
2022-11-26 09:09:00 +01:00
fe2df00a8c Use the latest WP version as default for acceptance tests
[MAILPOET-4841]
2022-11-26 09:09:00 +01:00
20577d974f Replace custom createSubscriber method with common factory method
[MAILPOET-4860]
2022-11-25 17:17:48 +01:00
7369465a3a Add subscribers cleanup to stats notification worker test
The test creates subscribers and there was not cleanup so this was increasing
probability of conflict in subscribers email.
[MAILPOET-4860]
2022-11-25 17:17:48 +01:00
5769fa45f5 Use helper methods for method column migration
This fixes issues with MailPoet in multiple schemas on the same MySQL instance as well
as simplifies the code. The migration was also renamed to a newer date. Additionally, the
edit of the initial MailPoet migration was reverted as this is not needed.

[MAILPOET-4733]
2022-11-25 14:51:57 +01:00
193b4cbf98 Set missing unsubscribe method for failing tests
[MAILPOET-4733]
2022-11-25 14:51:57 +01:00
461df1a560 Adjust strict_types & method typehint based on PR feedback
[MAILPOET-4733]
2022-11-25 14:51:57 +01:00
d5f78680eb Add integration test for unsubscibe properties
[MAILPOET-4733]
2022-11-25 14:51:57 +01:00
96dde7107b Expose unsubscribe analytics properperties
[MAILPOET-4733]
2022-11-25 14:51:57 +01:00
3e756bfadd Add test to assert correct unsubscription method is saved
[MAILPOET-4733]
2022-11-25 14:51:57 +01:00
82c755200e Augment track persister test with method as meta
[MAILPOET-4733]
2022-11-25 14:51:57 +01:00
735d33d05b Add method of tracking when tracking unsubscriptions
[MAILPOET-4733]
2022-11-25 14:51:57 +01:00
90c8e5b2c9 Introduce method column to statistics_unsubscribes table
[MAILPOET-4733]
2022-11-25 14:51:57 +01:00
cd1f06b116 Forbid assert() in code base
[MAILPOET-4258]
2022-11-25 14:32:34 +01:00
173f347431 Fix assert in Helper
[MAILPOET-4258]
2022-11-25 14:32:34 +01:00
353d3389cd Fix assert in data factories
[MAILPOET-4258]
2022-11-25 14:32:34 +01:00
fe364978a1 Fix usage of assert in acceptance tests
[MAILPOET-4258]
2022-11-25 14:32:34 +01:00
cd512bbb01 Fix instanceOf assertions in unit tests
[MAILPOET-4258]
2022-11-25 14:32:34 +01:00
f5193df721 Fix not null assertions in integration tests
[MAILPOET-4258]
2022-11-25 14:32:34 +01:00
25b5d24867 Fix is_array assertion in integration tests
[MAILPOET-4258]
2022-11-25 14:32:34 +01:00
1d99ff0943 Fix all is_string assertions in integration tests
[MAILPOET-4258]
2022-11-25 14:32:34 +01:00
99d6d96b05 Fix all is_numeric asserts in integration tests
[MAILPOET-4258]
2022-11-25 14:32:34 +01:00
6ddfe2c605 Remove ignores no longer needed
[MAILPOET-4258]
2022-11-25 14:32:34 +01:00
d2ec7bba42 Replace instance_of asserts in integration tests
[MAILPOET-4258]
2022-11-25 14:32:34 +01:00
2557171953 Fix assert() in lib
[MAILPOET-4258]
2022-11-25 14:32:34 +01:00
0d7e45ea03 Fix filename that is removed by fix-monolog.php
The following error is being thrown when running composer commands:

```
> php fix-monolog.php
rm: cannot remove 'mailpoet/mailpoet/prefixer/../vendor-prefixed/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php': No such file or directory
```

This is happening because in commit 9b71a7804c
we updated Monolog from v1 to v2. v2 renamed the file ElasticSearchHandler.php
to ElasticsearchHandler.php (see
4c7795d310).
Note that search is not spelled with a capital S anymore. We didn’t update
fix-monolog.php to reflect this change.

This commit updates fix-monolog.php to use the new file name and to remove
the error.

[MAILPOET-4856]
2022-11-25 13:47:24 +01:00
e677169a51 Update Mysql image for integration and acceptance tests
[MAILPOET-4851]
2022-11-25 13:37:08 +01:00
e268eac378 Add healthcheck for mysql service in the test environment
This is replacement for custom wait scripts and also should ensure
that DB is ready before starting the wordpress serive container,
which was missing the check.
[MAILPOET-4851]
2022-11-25 13:37:08 +01:00
375f2b13c5 Try select option in select 2 multiple times
[MAILPOET-4555]
2022-11-25 13:21:42 +01:00
34406a2f72 Fix flaky WooCommercePurchaseTest
[MAILPOET-4854]
2022-11-25 13:10:30 +01:00
cc658bcc3d Split one big test case into three smaller
[MAILPOET-4846]
2022-11-25 13:04:46 +01:00
973aefe7ae Hide black Friday notice in acceptance tests
[MAILPOET-4846]
2022-11-25 13:04:46 +01:00
34e91251e8 Add waiting on clickable trash button
[MAILPOET-4846]
2022-11-25 13:04:46 +01:00
882402645d Do not wrap automations beta badge, make it a bit smaller
[MAILPOET-4840]
2022-11-25 09:55:11 +01:00
d9d4dccc09 Make instruction on how to test with different PHP versions more generic
This commit just updates the README file so that it doesn't mention
specific PHP versions. This way we don't have to update it every time we
add a new version to the dev environment.

[MAILPOET-4855]
2022-11-25 09:33:39 +01:00
9d2fcccbf5 Add option to run the dev env with PHP 8.2RC6
[MAILPOET-4855]
2022-11-25 09:33:39 +01:00
c4fdd881e6 Retry language updates if they are not scheduled yet
[MAILPOET-4849]
2022-11-24 16:58:18 +01:00
83f7eee8ae Early return to make the migration idempotent
[MAILPOET-4852]
2022-11-24 16:04:29 +01:00
dc1f63d8bb Rename segments migration to be executed again
[MAILPOET-4852]
2022-11-24 16:04:29 +01:00
3e2425abd8 Rewrite segments migration to use helper methods, Doctrine DBAL, and lower number of queries
[MAILPOET-4852]
2022-11-24 16:04:29 +01:00
65e78c7990 Add helper to determine whether a column exists
[MAILPOET-4852]
2022-11-24 16:04:29 +01:00
2bdc5d3683 Add helper to get current table name
[MAILPOET-4852]
2022-11-24 16:04:29 +01:00
1de276378f Use different container names for different parallel runs
[MAILPOET-4851]
2022-11-24 15:48:43 +01:00
cc76fe77f0 Ensure that docker caching on CircleCi is disabled
[MAILPOET-4851]
2022-11-24 13:29:20 +01:00
c8636aac6f Update selenium and chrome image
[MAILPOET-4848]
2022-11-24 10:34:59 +01:00
a09f41143e Update codeception, webdriver and lucatume/browser
[MAILPOET-4848]
2022-11-24 10:34:59 +01:00
8b29694446 Compare scheduledAt with delta 2022-11-24 10:06:59 +01:00
5e0e89408c Test CaptchaFormRenderer
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
86076547c3 Raise aria-live level
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
b1bbabe14d early return when no audioCaptcha element was found
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
f5c678ec2d Initialize session when no ID exists
[MAILPOET-4514]
2022-11-24 09:20:39 +01:00
223625bd9b Use constant for endpoint
[MAILPOET-4514]
2022-11-24 09:20:39 +01:00
fbd7cf8cc7 Use SubscriberEntity instead of the Model
[MAILPOET-4514]
2022-11-24 09:20:39 +01:00
26c7e4d1cc Use null instead of empty string
[MAILPOET-4514]
2022-11-24 09:20:39 +01:00
4832771185 Refactor the captcha system
The current Captcha class has a lot of responsibilities. It renders the captcha
image, can check if a certain captcha type is a Google captcha, if a captcha is
required for a certain email. The SubscriberSubscribeController is not only in
charge of "controlling" the subscription process but also validates, whether a
captcha is correct or not. This architecture made it difficult to extend the
functionality and introduce the audio captcha feature.

Therefore this commit refactors the captcha architecture and tries to seperate
the different concerns into several classes and objects. Validation is now done
by validators.

The CaptchaPhrase now is in charge of keeping the captcha phrase consistent
between the image and the new audio, so that you can renew the captcha and both
captchas are in sync.

[MAILPOET-4514]
2022-11-24 09:20:39 +01:00
7fb8d64628 Rename CaptchaRenderer to CaptchaFormRenderer
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
36fed3bbf8 Enable output of audio captcha when image captcha has not yet been generated
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
8ab738b315 Use classes instead of ids for captcha elements
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
b84b9606e9 Remove type residual from audio captcha url building
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
aa68b7e148 Bust caching when building the audio captcha url
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
ca44339512 Fix typo in button cursor property
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
91f5376dfc Apply prettier
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
d51ef70db6 Add audio assets
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
c164268c20 Change file name to lower case
and codestyle
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
4c7c94c75d Update JavaScript for captcha audio player
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
ccf141b279 Add button icons
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
e42808f22d Update Captcha UI to add audio button
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
75a4b2c538 Add Captcha Audio endpoint to Router
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
f1d64c0572 Add Captcha styles
[MAILPOET-4203]
2022-11-24 09:20:39 +01:00
25c57bf9fe Fix flaky acceptance test for tag filter
[MAILPOET-4844]
2022-11-23 16:38:49 +01:00
079c90dbba Add acceptance test for switching languages
[MAILPOET-4147]
2022-11-23 12:50:32 +01:00
0fc342ee4c Release 4.0.1 2022-11-22 13:57:46 +01:00
7570c9fa0e Make automations Beta badge smaller
[MAILPOET-4836]
2022-11-22 09:23:57 +01:00
7642c4da4f Update machine executor images
[MAILPOET-4833]
2022-11-21 16:06:58 -03:00
dce13e5b8e Update sentence, add full stop.
MAILPOET-4669
2022-11-21 15:21:29 +01:00
8b922681b6 Use boolean instead of integer for displayInManageSubscriptionPage column
MAILPOET-4669
2022-11-21 15:21:29 +01:00
bd33cdbc24 Add new migration file for DisplayInManageSubscriptionPage column
MAILPOET-4669
2022-11-21 15:21:29 +01:00
bc04ad2528 Enable default checked state for standard lists checkbox
MAILPOET-4669
2022-11-21 15:21:29 +01:00
c54a5213b3 Update tests
MAILPOET-4669
2022-11-21 15:21:29 +01:00
07cf0cd79b Remove list management from settings page
MAILPOET-4669
2022-11-21 15:21:29 +01:00
e64dc1669f Add support for segment displayInManageSubscriptionPage on Subscription management page
MAILPOET-4669
2022-11-21 15:21:29 +01:00
48181994d8 Handle saving and loading list page. Add support for showInManageSubscriptionPage checkbox input
MAILPOET-4669
2022-11-21 15:21:29 +01:00
31c2915075 Add showInManageSubscriptionPage checkbox to edit list page
MAILPOET-4669
2022-11-21 15:21:29 +01:00
67f05ecfe2 Prefix forgotten Twig call in generated template code
[MAILPOET-4718]
2022-11-21 12:47:19 +01:00
c121c60e8c Fix condition for the running status
[MAILPOET-4664]
2022-11-21 12:45:28 +01:00
110859508e Fix tasks order on the status page
[MAILPOET-4664]
2022-11-21 12:45:28 +01:00
efd3377ecd Fix count of tasks on the status page
[MAILPOET-4664]
2022-11-21 12:45:28 +01:00
a7c1d8431d Update tests for [subscriber:count] shortcode
MAILPOET-4527
2022-11-21 12:36:12 +01:00
127f3e6363 Fix [subscriber:count] counts only subscribed subscribers
MAILPOET-4527
2022-11-21 12:36:12 +01:00
6bec12c762 Use helper function to create migration tables
[MAILPOET-4835]
2022-11-21 12:15:10 +01:00
d1df2d4f42 Add a helper function to create new table
[MAILPOET-4835]
2022-11-21 12:15:10 +01:00
5598f0af19 Fixing small typo
Automatoin should be automation
2022-11-21 11:23:01 +01:00
8dd80ce0f2 Fix the circle rerun command output
[PREMIUM-207]
2022-11-18 16:05:18 +01:00
e45510e064 Add rerunning premium workflow into the prepare command
[PREMIUM-207]
2022-11-18 16:05:18 +01:00
bfafff132a Make the project parameter optional
[PREMIUM-207]
2022-11-18 16:05:18 +01:00
d6748fe979 Add command for rerunning circle workflow
[PREMIUM-207]
2022-11-18 16:05:18 +01:00
2169522818 Add methods for rerunning Circle workflow
[PREMIUM-207]
2022-11-18 16:05:18 +01:00
06cfa3fc60 Shorten test and run action-scheduler group
[MAILPOET-4746]
2022-11-17 22:25:52 +01:00
f9e507eb15 Use latest WooCommerce version for Woo HPOS related tests
Before WooCommerce 7.1.0 was released, we were defining a specific
version of Woo that included HPOS to be used when running HPOS related
tests. Now that 7.1.0 was released and since we started using it by
default in bd51822b961a6f8ad10d3454cde912917acac0b6, we don't need to
specify a different Woo version for the HPOS tests.

[MAILPOET-4801]
2022-11-17 14:55:38 +01:00
90332a23b3 Use latest WooCommerce version in the CircleCI jobs
[MAILPOET-4801]
2022-11-17 14:55:38 +01:00
a82a810269 Update form templates to include privacy page link (if found)
MAILPOET-4651
2022-11-16 16:51:12 +01:00
5a378b3c5f Add replacePrivacyLinkTags method for Form Template
MAILPOET-4651
2022-11-16 16:51:12 +01:00
49a2df3dbb Release 4.0.0 2022-11-16 09:43:17 +01:00
dee5ff38f5 Fix error when sending a preview email with MSS
With HTTPS and "$oneClickUnsubscribeUrl = false", we were sending "false" instead of an actual URL.

[MAILPOET-4813]
2022-11-15 15:05:03 +01:00
70aefb421b Clear error when rerunning migration
[MAILPOET-4811]
2022-11-14 20:12:35 +03:00
764e1a1bf0 Rename "Not active" state to "Draft" on automations listing page
[MAILPOET-4810]
2022-11-14 19:51:34 +03:00
b140011f92 Update minimal version check for WooCommerceCheckoutBlockCest
Since we support the Woo Blocks integration only for versions from 8.0.0
we need to update minimal version check code for acceptance test.
[MAILPOET-4668]
2022-11-14 17:20:43 +01:00
b48c9e437e Update plugins in tests for feature and trunk branches
[MAILPOET-4668]
2022-11-14 17:20:43 +01:00
f34efb4d6f Update acceptance test oldest job configuration
[MAILPOET-4668]
2022-11-14 17:20:43 +01:00
324c03e8b9 Print WordPress version when starting test environment
[MAILPOET-4668]
2022-11-14 17:20:43 +01:00
e718101425 Upgrade minimum required WordPress version to 5.8
[MAILPOET-4668]
2022-11-14 17:20:43 +01:00
080ce50fea Open automations Beacon links in a new tab instead of HelpScout Beacon
[MAILPOET-4809]
2022-11-14 18:53:20 +03:00
1b9eb223b0 Load templates late
[MAILPOET-4788]
2022-11-14 12:35:29 +02:00
ea2fa794ac Limit varchar length to 191 to avoid unique/primary key issues
[MAILPOET-4788]
2022-11-14 12:35:29 +02:00
c46c61a923 Simplify and optimize automation stats
[MAILPOET-4788]
2022-11-14 12:35:29 +02:00
1136431551 Use $wpdb->prepare() for automation stats
[MAILPOET-4788]
2022-11-14 12:35:29 +02:00
957be23212 Improve query formatting
[MAILPOET-4788]
2022-11-14 12:35:29 +02:00
91a88b3e91 Rename alias "w" to "a"
[MAILPOET-4788]
2022-11-14 12:35:29 +02:00
7c5d239267 Fix and unify cleanup in automation tests
[MAILPOET-4788]
2022-11-14 12:35:29 +02:00
c748b80447 Fix timestamp column problems with some MySQL versions and some SQL modes
[MAILPOET-4788]
2022-11-14 12:35:29 +02:00
725e0ecb00 Remove automation feature flag
[MAILPOET-4788]
2022-11-14 12:35:29 +02:00
eb71dd8a68 Remove automation testing buttons and hooks
[MAILPOET-4788]
2022-11-14 12:35:29 +02:00
ce1687cf97 Replace custom mutation hook with a @wordpress/api-fetch based one
[MAILPOET-4788]
2022-11-14 12:35:29 +02:00
2e328b6d7f Move temporary automation migrator to a new migration
[MAILPOET-4788]
2022-11-14 12:35:29 +02:00
8489e63d34 Delete automation testing system endpoints
[MAILPOET-4788]
2022-11-14 12:35:29 +02:00
f8c17730fc Update tracking campaign
[MAILPOET-4712]
2022-11-14 11:22:57 +01:00
93e43eee7a Update sales banner for Black Friday 2022
[MAILPOET-4712]
2022-11-14 11:22:57 +01:00
9063dc3079 Remove duplicities in naming
[MAILPOET-4793]
2022-11-14 12:14:35 +02:00
9d55d3f134 Use "automation" instead of "workflow"
[MAILPOET-4793]
2022-11-14 12:14:35 +02:00
d199c3768a Show Bounced and Unsubscribed badge for minimum of 100 newsletter sent
The reason is that at low volumes the percentages can be misleading. E.g. if you send 20 emails and 1 hard bounces - that’s a hard bounce rate of 5%.

The percentage is very high, but a single hard bounce doesn’t really mean anything, so to avoid confusion I’d hide the badge altogether for low volumes.

MAILPOET-4688
2022-11-14 10:47:04 +01:00
0e0c2447d9 Fix issue with badge stats
We were using MailPoet.Num.toLocaleFixed which returns a string locale of the number. This can cause issues with some locales e.g some locale returns 2,3 instead of 2.3

MAILPOET-4688
2022-11-14 10:47:04 +01:00
99dfb3d24b Add formatForStats method for Unsubscribed and Bounced Stats
MAILPOET-4688
2022-11-14 10:47:04 +01:00
c4366e009b Fix crashing page due to newsletter not found error
MAILPOET-4688
2022-11-14 10:47:04 +01:00
1d31202607 Add badge for Unsubscribe, bounced and opened stat to the Advanced email statistics page
MAILPOET-4688
2022-11-14 10:47:04 +01:00
78d25ffb69 Add Stats Badge for opened rate on email listing
MAILPOET-4688
2022-11-14 10:47:04 +01:00
b710682c66 Replace average with critical badge on email listing for opened and clicked stats
MAILPOET-4688
2022-11-14 10:47:04 +01:00
52c6b94315 Add support for critical tag in newsletter badge
MAILPOET-4688
2022-11-14 10:47:04 +01:00
fd6b49e598 Add type TagVariant for variant strings
MAILPOET-4688
2022-11-14 10:47:04 +01:00
df2982454e Add support for Critical Tag and critical tag color
MAILPOET-4688
2022-11-14 10:47:04 +01:00
8a19fd906f Update test to check for distinct one-click urls in bulk
[MAILPOET-4703]
2022-11-11 09:21:30 +01:00
99198e5c2d Fix MailPoet\WP\Functions newly added method name
[MAILPOET-4703]
2022-11-11 09:21:30 +01:00
9204f37560 Remove redundant injection
[MAILPOET-4703]
2022-11-11 09:21:30 +01:00
765aa6efab Augment tests to acknowledge oneclick unsubscribe url
[MAILPOET-4703]
2022-11-11 09:21:30 +01:00
50b613365f Make sure one-click unsubscribe url won't redirect internally
[MAILPOET-4703]
2022-11-11 09:21:30 +01:00
4fe8d10d6c Update tests for Subscription and pass the new argument
[MAILPOET-4703]
2022-11-11 09:21:30 +01:00
162dab790d Implement 1-click unsubscribe strategy for post requests
[MAILPOET-4703]
2022-11-11 09:21:30 +01:00
6e8c9731d8 Define new isSiteUsingHttps method for WP_Functions
[MAILPOET-4703]
2022-11-11 09:21:30 +01:00
235552f91d Define Request utility class with isPost method
[MAILPOET-4703]
2022-11-11 09:21:30 +01:00
4ee08c296b Fix unknown storage engine 'InnoDB' error
[MAILPOET-4802]
2022-11-10 12:59:24 +01:00
bda979ec4f Fix trash error when workflow status is draft
[MAILPOET-4792]
2022-11-09 19:58:44 +03:00
78f10f064e Fix clicking on no longer existing text
[MAILPOET-4796]
2022-11-09 15:58:36 +01:00
eca4a68fec Revert broken test fix
Reverts: https://github.com/mailpoet/mailpoet/pull/4511

[MAILPOET-4796]
2022-11-09 15:58:36 +01:00
9daa5d58c7 Adjust tests to new templates
[MAILPOET-4745]
2022-11-09 15:24:50 +03:00
6cc232fbad Make premium badge mailpoet orange
[MAILPOET-4745]
2022-11-09 15:24:50 +03:00
6a07bd44ff Improve 'Coming soon' styles
[MAILPOET-4745]
2022-11-09 15:24:50 +03:00
63cd326191 Update template descriptions
[MAILPOET-4745]
2022-11-09 15:24:50 +03:00
40b15b0eb1 Lower the grid size for the badge
[MAILPOET-4745]
2022-11-09 15:24:50 +03:00
3825e9cb11 Fix test
[MAILPOET-4745]
2022-11-09 15:24:50 +03:00
7db2942140 Show PremiumModal for premium templates
[MAILPOET-4745]
2022-11-09 15:24:50 +03:00
3a5d28f24a Export const premiumValidAndActive
[MAILPOET-4745]
2022-11-09 15:24:50 +03:00
d02c63844d Add badges to template items
[MAILPOET-4745]
2022-11-09 15:24:50 +03:00
c3045dba07 Add type to WorkflowTemplate definition
[MAILPOET-4745]
2022-11-09 15:24:50 +03:00
c239566e1e Add premium and coming-soon template stubs
[MAILPOET-4745]
2022-11-09 15:24:50 +03:00
dfdc8cfd09 Add WorkflowTemplate types
[MAILPOET-4745]
2022-11-09 15:24:50 +03:00
4977b7ffa2 Add free templates
[MAILPOET-4745]
2022-11-09 15:24:50 +03:00
8e69299a6a Adjust naming and use wp wrapper I/O of direct usage
[MAILPOET-4702]
2022-11-09 12:36:44 +01:00
903bcbb92e Update tests and adapt to the new unsubscribe key structure
[MAILPOET-4702]
2022-11-09 12:36:44 +01:00
8d6492ac8c Adjust constructor injections of instantiators of MailPoet
[MAILPOET-4702]
2022-11-09 12:36:44 +01:00
c39ae1fe1f Adjust the unsubscribe key to use the new structure
[MAILPOET-4702]
2022-11-09 12:36:44 +01:00
e3539b06a2 Define URL utility method to check if url is using https
[MAILPOET-4702]
2022-11-09 12:36:44 +01:00
d34a265ac2 Prevent leaving unsaved automation
[MAILPOET-4776]
2022-11-09 13:42:56 +03:00
9a72e361b1 Fix plugin activtion for the smtp plugin
[MAILPOET-4785]
2022-11-09 12:59:29 +03:00
a520e4bd93 Run full activation of user account on multisite
[MAILPOET-4785]
2022-11-09 12:59:29 +03:00
9ab6ebbe0d Use always SMTP to send wp_mail
[MAILPOET-4785]
2022-11-09 12:59:29 +03:00
6a3cfd05e7 Update CircleCI to wait for Woo jobs to complete before starting build_release_zip
In [MAILPOET-4572] we added new CircleCI jobs to run WooCommerce tests in
different scenarios. But we forgot to add those jobs to the list of jobs
that need to finish before starting the build_release_zip job.

This can be problematic as we don’t want the build_release_zip to start
before all the test jobs have finished and, even worst, we don’t want it
to run if one of the test jobs failed.

This commit adds the following jobs to the list of jobs that are
required to finish before running build_release_zip:

- 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_off
- acceptance_tests_woo_cot_no_sync

[MAILPOET-4791]
2022-11-09 09:07:21 +01:00
f825e535e3 Save next step in trigger handler
[MAILPOET-4787]
2022-11-08 22:55:57 +02:00
a2c5420d7f Save updated at timestamp in workflow runs
[MAILPOET-4787]
2022-11-08 22:55:57 +02:00
c6d3573652 Save next step ID to workflow runs
[MAILPOET-4787]
2022-11-08 22:55:57 +02:00
e41bcd0d02 Manage ActivationPanel in store and close when sidebar opens
[MAILPOET-4769]
2022-11-08 23:31:36 +03:00
f805907954 Release 3.103.1 2022-11-08 17:35:04 +01:00
d970efc0da Reduce size of a database field to avoid error in some MySQL versions
This commit reduces the size of the `name` field from varchar(255) to
varchar(191) to avoid the following fatal error in some MySQL versions:

```
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
```

See the ticket descriptions and the links in it for more information.

[MAILPOET-4790]
2022-11-08 12:27:01 -03:00
c0ce5944dc Use short table aliases
[MAILPOET-4778]
2022-11-08 16:17:34 +02:00
467f354eb1 Do not skip workflow trigger queries when trigger keys are empty
[MAILPOET-4778]
2022-11-08 16:17:34 +02:00
3f016b45f9 Don't escape table names when not needed
[MAILPOET-4778]
2022-11-08 16:17:34 +02:00
679f74e498 Unify query error checking
[MAILPOET-4778]
2022-11-08 16:17:34 +02:00
08b314e0b4 Unify table variable naming
[MAILPOET-4778]
2022-11-08 16:17:34 +02:00
cc5959805b Use "workflow_triggers" table instead of an inline JSON
[MAILPOET-4778]
2022-11-08 16:17:34 +02:00
407f3d1609 Hide duplicate workflow button
[MAILPOET-4786]
2022-11-08 16:48:35 +03:00
503df3584c Track errors
[MAILPOET-4756]
2022-11-08 16:41:47 +03:00
fa9510f0c1 Add getStepById method
[MAILPOET-4756]
2022-11-08 16:41:47 +03:00
cc92df4e7f Track Automations > Listing viewed event
[MAILPOET-4756]
2022-11-08 16:41:47 +03:00
d76c5d32f2 Track Workflow deactivated
[MAILPOET-4756]
2022-11-08 16:41:47 +03:00
c6198cba4c Track Workflow activated
[MAILPOET-4756]
2022-11-08 16:41:47 +03:00
e29dd4286e Track template selected
[MAILPOET-4756]
2022-11-08 16:41:47 +03:00
98c1c33341 Release 3.103.0 2022-11-08 10:33:23 -03:00
78cc8743d5 Skip tests that are failing to unblock a release preparation
Those two tests that are failing are related to the automation feature
which is not yet available to the users. So skipping them should be
safe.

[MAILPOET-4784]
2022-11-07 23:42:16 +03:00
89e75b3828 Make test passable for both multi-side and single 2022-11-07 15:16:44 -03:00
982d104ba0 Fix the issue in test dot instead plus [MAILPOET-4782]
[MAILPOET-4782]
2022-11-07 15:16:44 -03:00
2ce4461c63 Fix acceptance test UserRegistrationTriggered [MAILPOET-4782]
[MAILPOET-4782](https://mailpoet.atlassian.net/browse/MAILPOET-4782)
2022-11-07 15:16:44 -03:00
146a55b921 Improve stability of SchedulerTest by adding 1s delta to time comparisons
[MAILPOET-4780]
2022-11-07 19:15:43 +01:00
7e883d3e5b Rename method from checkForNullOrUndefined to isNullOrUndefined
MAILPOET-4681
2022-11-07 14:17:50 +01:00
7896efcd6c Enforce user selection for welcome wizard privacy and data sharing
We are making the two buttons mandatory. Users have to select either yes or no before they can proceed with the welcome wizard

MAILPOET-4681
2022-11-07 14:17:50 +01:00
a1ef87ef78 Remove later phrase from options
MAILPOET-4658
2022-11-07 12:42:58 +01:00
d058f1741f Add after text for immediately option on the post notification create screen.
MAILPOET-4658
2022-11-07 12:42:58 +01:00
ff0852fa39 Update after delay text
MAILPOET-4658
2022-11-07 12:42:58 +01:00
5f07b68b07 Update post notification emails
Remove select frequency subheader and add "after publishing a post" to immediately text

MAILPOET-4658
2022-11-07 12:42:58 +01:00
0c2934a556 Update Post notifications email setup
Add "When to send this post notification email" text to the page

MAILPOET-4658
2022-11-07 12:42:58 +01:00
885b51a6cf Update PurchasedInCategory and PurchasedProduct
Add "after purchase" text to the page

MAILPOET-4658
2022-11-07 12:42:58 +01:00
6cb5ceca21 Update First purchase automatic emails
Add "When to send this email" and "after first purchase" texts to the page

MAILPOET-4658
2022-11-07 12:42:58 +01:00
9a14ddb57c Fire mailpoet_segment_subscribed only when subscriber status changed
[MAILPOET-4773]
2022-11-07 04:41:47 -06:00
5c6f32488a Remove old hook
[MAILPOET-4773]
2022-11-07 04:41:47 -06:00
4ec8f27d36 Delete schema if necessary
[MAILPOET-4773]
2022-11-07 04:41:47 -06:00
9554727370 Fire mailpoet_segment_subscribed when user registers and is subscribed
When no confirmation mail gets send, the user is subscribed immediately. In this case
we need to fire the mailpoet_segment_subscribed action, so the trigger can listen to this
event.

[MAILPOET-4773]
2022-11-07 04:41:47 -06:00
394f9abd67 Make sure, we have a fresh subscriber from the database
[MAILPOET-4773]
2022-11-07 04:41:47 -06:00
6ee45f0f54 Add method to retrieve subsccriber
[MAILPOET-4773]
2022-11-07 04:41:47 -06:00
2e9ae1ed0b Add info about subscribe in registration from setting
[MAILPOET-4772]
2022-11-07 04:41:47 -06:00
74b12bd2d9 Change trigger to mailpoet_segment_subscribed
We should listen to mailpoet_segment_subscribed to start the trigger.
This means the subscriber is confirmed. And it removes the fatal error
which was produced by not finding the $segment during signup.

[MAILPOET-4772]
[MAILPOET-4773]
2022-11-07 04:41:47 -06:00
279adcfbcf Test user registration triggers automation
[MAILPOET-4773]
2022-11-07 04:41:47 -06:00
64d655857b Explicitly declare compatibility with Woo High Performance Order Tables
This was done following the instructions published by the WooCommerce
team: pcShBQ-oY-p2

[MAILPOET-4726]
2022-11-07 10:42:38 +01:00
b2b5f3c22a Add Woo tags "WC requires at least" and "WC tested up to"
As discussed in this P2 post (pcNwfB-1lW-p2), we will start using the
Woo tags "WC requires at least" and "WC tested up to". The "WC tested up
to" tag is required by WooCommerce for extensions to explicitly declare
compatibility with Woo High Performance Order Tables (pcShBQ-oY-p2). The
"WC requires at least" is not currently used by WooCommerce, but it
helps us make more explicit which versions of Woo MailPoet currently
supports.

[MAILPOET-4726]
2022-11-07 10:42:38 +01:00
588f3a9feb Use "reply to" from settings only when they are different than "from" settings
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
8c676b773d Fix hook type
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
c76a0adb5e Move validation rules for active workflows below structural rules
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
848fc51070 Run full workflow validation for all non-draft statuses
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
af1e09f46f Remove "inactive" status for now, use "draft" instead
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
f1abfe557a Use undefined for no value in GA campaign field
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
aa52ca804e Expose send email create step filter
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
273551fa36 Add type for a step creation callback
[MAILPOET-4757]x
2022-11-07 11:17:36 +02:00
17898b243a Use default reply to values when no previous values are set
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
81ed12d454 Use previous reply to values when toggled off and on
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
2f78c99381 Fix reply-to panel empty value handling
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
480c7d25e0 Delete step args when they are set to "undefined"
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
c1a6c5a215 Force sidebar remount to avoid different steps mixing their data
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
8fadc87036 Enable delay in minutes
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
5176566882 Remove debug info from step panel
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
b52b9990da Improve workflow name rendering in listing
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
8796599d89 Automatically open sidebar panels when their fields contain errors
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
9808245d30 Set errors object also for non-step errors to propagate correct state
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
12f2d1730f Do not enforce workflow content for non-active workflows
[MAILPOET-4757]
2022-11-07 11:17:36 +02:00
dac8c1e2f3 Improve assertEqualDateTimes helper interface
Make sure that both dates parameters have to be passed into the method.
[MAILPOET-4723]
2022-11-07 10:10:17 +01:00
a3e1f8d8c6 Fix flaky AbandonedCartTest
Fix the flaky DateTime comparisons test by allowing 1 second delta
[MAILPOET-4723]
2022-11-07 10:10:17 +01:00
2c28449b58 Add helper method for comparing DateTimeInterface objects
This commit adds a method to the integration tester that allows
comparing two DateTimeInterface objects and specify tolerated delta.
It also allows passing null and assert the DateTimeInterface internally.
This is because often our entities have return type DateTimeInterface|null
So with the internal checks we don't have to make those instance of checks
each time we pass date from entity into the method.
Note: I was not able to use $this->assertInstanceOf because PHPStan was not accepting that
and still complained.
[MAILPOET-4723]
2022-11-07 10:10:17 +01:00
43197bf859 Use 24-hour format in migration timestamps
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
bd34c4e7ec Ignore index.php in migrations directory
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
511b8ad7ff Retry timed out and failed migrations
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
a60562254c Temporarily fix reinstall test wiping out automation tables
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
96368cbd3f Move one-time migrations from populator to the new initial migration
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
e384e7dea3 Merge inactive subscribers frequency test into the new initial migration test
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
86fbcd3a57 Annotate types for PHPStan rather than using baseline files
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
9730fb9272 Move the old dbDelta-based migrator to a migration
This will ensure it runs once and from there, it will continue using the new migrations.

[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
a3f2ee8bbb Implement CLI output logging when running migrations
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
a177b3b8da Add the possibility to use a logger in migrator
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
f369fdfa4a Add ./do migrations:new command to generate migration files
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
80a6e78d48 Allow underscored naming in lib/Migrations
This is to allow readable naming of migration files and classes, such as "Migration_20221023_040819".
2022-11-07 10:05:42 +01:00
f65821256c Run migrations on activation
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
dd10389c55 Implement WP CLI command to show migrations info
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
3dd6ef3da7 Implement WP CLI command to run migrations
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
036d0a29ae Implement full migration running logic
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
d199e0b77e Add migrator service with ability to resolve status of all migrations
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
17ab79aa6f Add store method to list all migrations
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
b10cd32449 Add runner to execute a migration and save its status
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
f9001c1826 Add store methods to start, complete, and fail a migration
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
31050394b9 Add a store with a method to create migrations table when it doesn't exist
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
e9970f3cc8 Implement loading existing migration classes from the filesystem
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
516c460ace Add repository with the ability to create new migration classes
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
03d80290e6 Add a migration template that will be used to generate new migrations
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
d65b567858 Add abstract migration class with access to connection, entity manager, and the DI container
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
0d10f4b1dd Enable mocking non-object properties in test service overrides
[MAILPOET-4466]
2022-11-07 10:05:42 +01:00
610d0204eb Add link to email statistics page
[MAILPOET-4777]
2022-11-07 10:25:21 +02:00
545a4adc66 Fix typo
[MAILPOET-4744]
2022-11-07 02:22:21 -06:00
38d8a1cd00 Wrap updateingActiveWorkflowNotPossible in useEffect
[MAILPOET-4744]
2022-11-07 02:22:21 -06:00
53201c7422 Rename imported select
[MAILPOET4744]
2022-11-07 02:22:21 -06:00
6f447e8a93 Show snackbar message on boot when updating not possible
[MAILPOET-4744]
2022-11-07 02:22:21 -06:00
368a400fea Allow updating an active workflow when no user is in progress
[MAILPOET-4744]
2022-11-07 02:22:21 -06:00
902eeccea1 Block updating workflows with active runs in the backend
[MAILPOET-4744]
2022-11-07 02:22:21 -06:00
c8cf00a151 Add delay to tooltips
[MAILPOET-4744]
2022-11-07 02:22:21 -06:00
f41423e6a2 Add period at the end of the sentence
[MAILPOET-4744]
2022-11-07 02:22:21 -06:00
774485d5f2 Deactivate 'update/activate' buttons when status is active/deactivting
[MAILPOET-4744]
2022-11-07 02:22:21 -06:00
8f4d62b080 Hide search on Listing page
[MAILPOET-4779]
2022-11-07 02:14:40 -06:00
8003a3e97f Do only trigger when segment is of type default
[MAILPOET-4771]
2022-11-05 07:40:43 +01:00
cf572985a7 Add test to ensure WC checkout only triggers one flow
[MAILPOET-4771]
2022-11-05 07:40:43 +01:00
c4966a9cc1 Prevent flakiness when comparing time in NewsletterTest
When comparing the sentAt and processedAt dates there might be one second difference.
This may happen also in the application, because they are updated by separate queries.

This commit fixes the flakiness by comparing timestamps with delta 1 second instead of comparing date time strings.
[MAILPOET-4710]
2022-11-04 12:14:36 -03:00
c6e6b13731 Run Woo HPOS tests in all branches
This commit reverts 4256a18b82 so that the
Woo HPOS tests are executed in all branches instead of just trunk and
the Woo HPOS related branches.

[MAILPOET-4648]
2022-11-04 14:17:28 +01:00
975041d211 Stop allowing Woo HPOS tests to fail
This commit basically reverts all the changes from
5d8ccb96b4 to stop allowing Woo HPOS
related tests to fail on the CircleCI builds now that all the issues
were fixed and all tests should pass.

[MAILPOET-4648]
2022-11-04 14:17:28 +01:00
ea16472ab1 Use Codeception\TestInterface::getName() instead of Codeception\TestInterface::getMetadata()
This commit changes the code to use $event->getTest()->getName() instead
of $event->getTest()->getMetadata()->getName() to get the name of the
current test. This was necessary because the latter was returning null
for integration tests while the former works both for acceptance and
integration tests. I did not investigate why Codeception behaves this
way due to lack of time, there is a chance that this is a bug in
Codeception.

Since $event->getTest() returns an instance of TestInterface and this
class does not define getName() (but the call works probably due to some
magic method), it was necessary to edit phpstan.neon to skip a PHPStan
error.

[MAILPOET-4765]
2022-11-04 12:43:48 +01:00
713b0255f7 Add WooCommerce Subscriptions tests to $allowedToSkipList list
We skip those tests in some cenarios because WooCommerce Subscriptions
does not support Woo HPOS yet. When the code to skip them was added, we
forgot to add those tests to the list of tests that are allowed to skip
even in the trunk and release branches. This is done now in this commit.

[MAILPOET-4765]
2022-11-04 12:43:48 +01:00
2aa63bbb8e Fix typo
[MAILPOET-4765]
2022-11-04 12:43:48 +01:00
f6708d9526 Change the system that is used to prevent skipped tests
This commit changes the system that is used to prevent skipped tests
when CircleCI executes the integration tests against the trunk
and release branches. After this commit, the integration tests will use
the same system that is used by the acceptance tests. Besides
consolidating everything into a single system, this change is necessary
because we will need to know the name of the tests as we want to allow
some integration tests to be skipped in some circumstances, and this was
not possible with the old system.

[MAILPOET-4765]
2022-11-04 12:43:48 +01:00
65b56271d4 Update Woo HPOS build in test to the latest version
The latest version is 7.1.0-rc.2. Since this build is available on
WP.org, this commit also removes the custom code that we had to download
builds from GitHub. We can now use \RoboFile::downloadWooCommerceZip()
to download builds to test Woo HPOS.

[MAILPOET-4704]
2022-11-04 10:39:59 +01:00
c9c35d591b Update URLs in email templates
[MAILPOET-4758]
2022-11-04 10:51:23 +02:00
e9cfcb51ba Add missing strings
[MAILPOET-4758]
2022-11-04 10:51:23 +02:00
dc5e5b4f8b Use "automation" instead of "workflow" in user-facing strings
[MAILPOET-4758]
2022-11-04 10:51:23 +02:00
ccb5369c57 Use https everywhere for www.mailpoet.com
[MAILPOET-4758]
2022-11-04 10:51:23 +02:00
bfe3ff17af Fix translation strings
[MAILPOET-4758]
2022-11-04 10:51:23 +02:00
756b0587bc Return an empty string for footer when on automation page
[MAILPOET-4755]
2022-11-04 06:26:21 +02:00
af3d08ff36 Add method to detect automation pages
[MAILPOET-4755]
2022-11-04 06:26:21 +02:00
a91913e633 Make 'Give feedback' translateable
[MAILPOET-4755]
2022-11-04 06:26:21 +02:00
736d8a8b12 Add 'Give feedback' beacon ID to automation pages
[MAILPOET-4755]
2022-11-04 06:26:21 +02:00
9b5bdb2206 Release 3.102.1 2022-11-03 22:49:42 +03:00
3ad606a767 Revert "Change the system that is used to prevent skipped tests"
This reverts commit 363ee93c25.
2022-11-03 12:29:48 -03:00
e0cab11293 Revert "Fix typo"
This reverts commit da110bed80.
2022-11-03 12:29:48 -03:00
bffafdcd33 Revert "Add WooCommerce Subscriptions tests to $allowedToSkipList list"
This reverts commit 6b4d2409cc.
2022-11-03 12:29:48 -03:00
6dfeb7a100 Prevent enabling Woo Blocks integration for older versions
Version 8.0.0 was shipped with WooCommerce 6.8.0 which is the oldest currently supported Woo version.
[MAILPOET-4774]
2022-11-03 15:16:43 +01:00
a6431678ed Remove backward compatibility for Woo Blocks ExtendRestApi
The new ExtendSchema was introduced in WCBlocks 7.2 which are way older
then we currently want to support.
[MAILPOET-4774]
2022-11-03 15:16:43 +01:00
cdcdfb135c Update php-stubs/woocommerce-stubs to the latest version
[MAILPOET-4774]
2022-11-03 15:16:43 +01:00
7821c5767b Use current namespace for Woo store API checkout schema class
The new namespace is supported from WooCommerce 6.4.0 so we don't need
to support the old namespace any more.
Some users reported issues with BC class aliases provided by Woo.
[MAILPOET-4774]
2022-11-03 15:16:43 +01:00
6a5b7adc16 Prefix polyfilled normalizer functions
[MAILPOET-4770]
2022-11-03 12:39:24 +01:00
e58de01950 Improve mobile behavior of hero image
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
ae6e790879 Adjust hight of hero picture to align with blue button
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
d21b2fe21d Ensure same width of template buttons
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
6b8e8988b8 Keep template button columns aligned on top
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
0db495eb1d Use DropdownMenu in OptionButton component
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
6ad315b8de Add mailpoet-automation-section-content to define a max-width for section content
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
945ff65358 Use cdn url for automation assets
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
e0458ca444 Sort use statements alphabetically
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
5bd639e0be Add automation listing header
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
c78a050d86 Reduce nesting in CSS
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
e37a824d86 Hide notices on onboarding screen
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
fe4d78992f Let image go below build-your-own list on mobile
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
1c380933e1 Adjust layout of build-your-own list
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
a8c3465133 Add space between options menu and options button
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
edbfb957b1 Ensure there is space between template items and enable wrap
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
161b8d8f34 Reduce right padding of sections by 20px
Those 20px to the border are already in the double usage of the .wrap class in the DOM

[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
96d9347cff Move automation image assets directory
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
dfb7133dbb Use images with a better quality
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
a264b00200 Simplify full-width definition
The values to define fullwidth are derived from #wpcontent and .wrap
The div.wrap exists actually twice in our templates, so those values
needed to be multiplied by 2.

[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
100a301476 Ensure template items are of same height
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
35c3ebfb20 Add Non-breaking space
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
e3db69282d Rephrase to 'Explore essentials'
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
45999f98b2 align template-list items layout
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
6f5c39e97c Add missing period
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
4644f3fe08 Adjust automation test to new UI
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
d951ebd351 Add different sections for welcome screen
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
a7bc4e7c70 Add <OptionButton> component
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
a08553c9bc Add path the image assets
[MAILPOET-4536]
2022-11-03 11:56:21 +01:00
8161b83ded Add check on list type when deleting list
[MAILPOET-4752]
2022-11-02 14:05:39 +01:00
ad46d05c6b Add check on list type
[MAILPOET-4752]
2022-11-02 14:05:39 +01:00
f231f3dc6d Fix type error for list update
[MAILPOET-4752]
2022-11-02 14:05:39 +01:00
933b947f45 Add deleteList documentation
[MAILPOET-4752]
2022-11-02 14:05:39 +01:00
f6a5e0117c Add deleteList test cases
[MAILPOET-4752]
2022-11-02 14:05:39 +01:00
56c79dd66a Add API method deleteList
[MAILPOET-4752]
2022-11-02 14:05:39 +01:00
25ba667cb1 Move segment id validation to private method
[MAILPOET-4752]
2022-11-02 14:05:39 +01:00
1ac9c86a66 Add updateList documentation
[MAILPOET-4752]
2022-11-02 14:05:39 +01:00
94a2e54c1e Add test cases for updateList
[MAILPOET-4752]
2022-11-02 14:05:39 +01:00
fbf4c853c1 Add new API method updateList
[MAILPOET-4752]
2022-11-02 14:05:39 +01:00
5fba25d823 Fix the exception message
[MAILPOET-4752]
2022-11-02 14:05:39 +01:00
18efc02921 Move list validation to a private method
We move the segment's name validation to a private method to avoid code repetition.
[MAILPOET-4752]
2022-11-02 14:05:39 +01:00
bdd803c517 Support text wrap in forms submit button
MAILPOET-4638
2022-11-02 11:33:44 +01:00
382e232538 Add CSS class form-editor-sidebar-heading back to component
MAILPOET-4650
2022-11-02 11:24:57 +01:00
a2cddc761c Make the labels in form editor consistent
MAILPOET-4650
2022-11-02 11:24:57 +01:00
6b4d2409cc Add WooCommerce Subscriptions tests to $allowedToSkipList list
We skip those tests in some cenarios because WooCommerce Subscriptions
does not support Woo HPOS yet. When the code to skip them was added, we
forgot to add those tests to the list of tests that are allowed to skip
even in the trunk and release branches. This is done now in this commit.

[MAILPOET-4765]
2022-11-02 10:27:34 +01:00
da110bed80 Fix typo
[MAILPOET-4765]
2022-11-02 10:27:34 +01:00
363ee93c25 Change the system that is used to prevent skipped tests
This commit changes the system that is used to prevent skipped tests
when CircleCI executes the integration tests against the trunk
and release branches. After this commit, the integration tests will use
the same system that is used by the acceptance tests. Besides
consolidating everything into a single system, this change is necessary
because we will need to know the name of the tests as we want to allow
some integration tests to be skipped in some circumstances, and this was
not possible with the old system.

[MAILPOET-4765]
2022-11-02 10:27:34 +01:00
db0024dc58 Specify return types for each filter
[MAILPOET-4674]
2022-11-01 15:56:28 +01:00
1b59b95f52 Use controls property of DropdownMenu
[MAILPOET-4674]
2022-11-01 15:56:28 +01:00
2d0673a864 Export @wordpress/icons
[MAILPOET-4674]
2022-11-01 15:56:28 +01:00
9f4b0d0ca1 Add filter so the more menu can be extended by third party
* Removes deprecated mailpoet.automation.workflow.delete_step_callback filter
* Adds mailpoet.automation.workflow.step.more-controls filter

[MAILPOET-4674]
2022-11-01 15:56:28 +01:00
97c1712fa6 Expose MenuItem and ConfirmDialog
[MAILPOET-4674]
2022-11-01 15:56:28 +01:00
455e3fbb90 Fix issue of site-url in none-lowercase failing validation
When validating the MSS/Premium keys sending a none-lowercase
site-url would cause the bridge to correctly validating

[MAILPOET-4754]
2022-11-01 15:00:07 +01:00
3c718e3f68 Update ViewInBrowserRenderer, Fix tracking config error
MAILPOET-4599
2022-11-01 14:59:28 +01:00
63e797ba37 Add more tests for new site shortcodes
MAILPOET-4599
2022-11-01 14:59:28 +01:00
48340872f8 Update acceptance tests for confirmation email
MAILPOET-4599
2022-11-01 14:59:28 +01:00
1b5d85d41a Render the current site title for [site:title] on signup confirmation page description
MAILPOET-4599
2022-11-01 14:59:28 +01:00
0595852d5a Update subscription confirmation email subject
Allow shortcode processing in subject

MAILPOET-4599
2022-11-01 14:59:28 +01:00
448e89d062 Update tests for confirmation emails
MAILPOET-4599
2022-11-01 14:59:28 +01:00
f92ee90e9b Add support for [site:title] and [site:homepage_link]
These will add support for these two shortcodes in the Shortcode engine

MAILPOET-4599
2022-11-01 14:59:28 +01:00
80f22c5b50 Process confirmation email content with newsletter shortcode engine
MAILPOET-4599
2022-11-01 14:59:28 +01:00
4b74d66529 Update subscription confirmation email content description
MAILPOET-4599
2022-11-01 14:59:28 +01:00
ca72e11d9a Update default subscription confirmation email content
MAILPOET-4599
2022-11-01 14:59:28 +01:00
5a0ec403f6 Update test cases to reflect change in method location
MAILPOET-4663
2022-11-01 14:58:47 +01:00
b6e7e39fb0 Rename method and move wcGetPageId to Woo helper class
MAILPOET-4663
2022-11-01 14:58:47 +01:00
8c24d59f43 Add tests for form display on Woo Shop listing page
MAILPOET-4663
2022-11-01 14:58:47 +01:00
5ed0c3fb2d Allow form display on Woo Shop listing page
The WooCommerce Shop page is a special kind of page. It’s basically a post archive.

The Shop page is a placeholder for a post type archive for products. It may render differently than other pages in your install.
https://woocommerce.com/document/woocommerce-pages/#section-4

It doesn’t have any content and WooCommerce core team is also removing the the-content filter from the Shop listing page hence why we are unable to hook into the the-content filter we use for other parts of the codebase

MAILPOET-4663
2022-11-01 14:58:47 +01:00
2151118183 Release 3.102.0 2022-11-01 16:53:44 +03:00
4c65374a0c Add some POT file headers that we've been using
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
32cf2084b8 Unify quotes in strings
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
9dc834e14a Pass translated automation strings to our @wordpress/i18n
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
3db11c443d Use WP-native translation system for marketing optin block
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
421549d6ee Make all automation strings in PHP translatable, improve context/comments
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
a7277f3437 Add context and translators comments where needed
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
4d56911230 Make all automation strings translatable
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
0f23dea7fc Don't add hash of JS bundles to their filenames, use plugin version parameter instead
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
742e3e85e9 Load translations for automation scripts using wp_set_script_translations()
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
6eeb5bb1bf Load all automation scripts using wp_enqueue_script()
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
01eb59a295 Keep only the part of the old makepot logic that is required for HTML and HBS files
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
8ddd42ea4c Generate translations after JS assets are built
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
eb80adc2ed Extract translations from PHP and JS/TS files using WP CLI
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
3103ef11d5 Use old translation extraction logic only for HTML and HBS files
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
a1ead743fa Complete translation directory exclusion list, make it more readable
[MAILPOET-4611]
2022-10-31 10:03:45 +01:00
c8d0291e41 Fix acceptance test flakyness for allowSubscribeInComments 2022-10-28 13:42:09 +01:00
bd44d77973 Fix acceptance test failure for woocommerce setup wizard 2022-10-28 13:42:09 +01:00
f872ab1819 Update expectation for confirmation emails on multisite
MAILPOET-4667
2022-10-28 13:42:09 +01:00
55371ce7ee Reset fetchingPreviewLink and disable button while link is fetched
[MAILPOET-4631]
2022-10-27 10:43:53 -05:00
ba45d23307 Fetch preview link when user clicks on preview
[MAILPOET-4631]
2022-10-27 10:43:53 -05:00
f660bd9bd7 Add Email Preview link
[MAILPOET-4631]
2022-10-27 10:43:53 -05:00
1332fb89e4 Update acceptance tests for confirmation page
MAILPOET-4667
2022-10-27 13:42:50 +02:00
dc5254721e Update the confirmation page title
Show website title instead of list names

MAILPOET-4667
2022-10-27 13:42:50 +02:00
918a4d7c74 Refresh the sending queue entity when fetching it from the old model
By moving the refresh code into the method used for getting sending queue entity for the old model object
we want to make our code better protected from working with inconsistent sending queue data.
[MAILPOET-4750]
2022-10-27 12:08:31 +02:00
ec29c8fb49 Change order of saving sending task related data
In case we save the task and and queue saving fails the sending may be triggered with incorrect data in the queue.
Since the scheduled task is used for controlling sending state lets save it as last so that we are sure all related
data are up to date before saving the task.
[MAILPOET-4750]
2022-10-27 12:08:31 +02:00
43922a7c27 Notify about subscriber changes in WP and Woo synchronizations
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
76b1166269 Add methods for batch changes
Because sometimes can be difficult to get updated and created subscribers, I decided to create methods that doesn't need subscriber ids.
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
12c0605f92 Fix variable name typo
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
0bbf1b96d5 Add notifications about imported subscribers
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
b716b427a7 Fix UTC time for changes
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
c1ac9f7922 Add test case on notifications during shutdown
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
3dd872e211 Add SubscriberListener integration test
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
a09a9cdcbf Add typecast to batch methods
Because functions can return ids as a string, the typecast is necessary to avoid type errors.
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
2d835cdec1 Add new action hooks for multiple changes
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
28b91ed994 Notify about subscriber changes in repository
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
1e147c9dd5 Add notify actions for multiple subscribers
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
6f89b47b30 Store time of change in SubscriberChangesNotifier
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
8d5c07a317 Add notifying about deleted subscribers
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
9ff72b4d4c Add SubscriberListener for notification about changes
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
4fe5219b89 Add notifying about changes to the shutdown hook
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
2dab7fdb0c Add new service for handling subscriber changes
This new service should store all changes and notify about them at the end of the HTTP request.
[MAILPOET-4727]
2022-10-27 09:31:40 +02:00
5075982cd3 Rename validateArray to validateSchemaArray and specify the format in doc comment
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
1a58166a0b Improve error message for the case when no email has been designed yet.
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
ca0681b1a7 Use alert icon from Figma
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
540b34c63f Validate multiple properties
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
c8565b1197 Add validateArray method
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
75906820e5 Reset recent changes in Validator
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
2cacb5809d Avoid iteration
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
900faa2a71 order error cases
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
c140eea734 Adjust DelayActionTest to new error format
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
5201c359d3 Adjust SendEmailActionTest to new error format
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
4e1b1b3c27 Ensure at least one trigger is present and triggers are followed by actions
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
8af01c3bcb Use Rest API error codes and map them to error messages
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
d94dabb8d6 Style error messages and fields
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
63b1f1670b Render error fields and messages in steps
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
2d050b0ea5 Update StepError type to conform with new API response
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
686f702ec9 Add errors per field in Response data
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
5754302154 Add all errors from WordPress to the \ValidationException
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
e2ede3e568 use withError to build error message
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
f95824dea0 Add withError() method to exceptions
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
650a8704cd Show saved message when workflow is saved
[MAILPOET-4700]
2022-10-26 12:51:16 +02:00
cd37f92592 PR feedback: add the default value back
[MAILPOET-4521]
2022-10-26 12:28:22 +02:00
6bf201b45e Remove propTypes and defaultProps from AuthorizeSenderEmailModal
Removing the defaultProps is safe since the defaulted prop
is mandatory by TS

[MAILPOET-4521]
2022-10-26 12:28:22 +02:00
e178d6519c Remove propTypes from StylesSettingsPanel
[MAILPOET-4521]
2022-10-26 12:28:22 +02:00
97d4a8e4f8 Remove propTypes definition for InputStylesSettings
[MAILPOET-4521]
2022-10-26 12:28:22 +02:00
e5ce252587 Remove propTypes from FormFieldTokenField
[MAILPOET-4521]
2022-10-26 12:28:22 +02:00
b7cae6dac4 Remove propTypes & defaultProps from authorize_sender_domain_modal
Safe removal of defaultProps since the defauleted prop is
mandatory by TS and always set by users

[MAILPOET-4521]
2022-10-26 12:28:22 +02:00
07d3b753b8 Remove babel-plugin-typescript-to-proptypes package
[MAILPOET-4521]
2022-10-26 12:28:22 +02:00
72ef0909f5 Stop executing workers when execution limit is reached
When execution limit is reached it makes no sense to continue and
execute additional workers or log the execution limit exception as an error.
[MAILPOET-4725]
2022-10-26 10:13:05 +02:00
a5473bf882 Use proper logger name for logging cron errors
[MAILPOET-4725]
2022-10-26 10:13:05 +02:00
c4e7ea4c8e Use addFilter instead of addAction
[MAILPOET-4728]
2022-10-25 12:04:44 -05:00
ce462f1643 Close correct HTML element type
[MAILPOET-4728]
2022-10-25 12:04:44 -05:00
91936aff92 Rename Automation to Automations in Menu
[MAILPOET-4728]
2022-10-25 12:04:44 -05:00
57858bbe9a Move Automation menu item between Emails and Forms
[MAILPOET-4728]
2022-10-25 12:04:44 -05:00
42d9b1241e Make menu strings translateable and use esc_html__() for menu titles
[MAILPOET-4728]
2022-10-25 12:04:44 -05:00
fc4a5315df Add beta badge
[MAILPOET-4728]
2022-10-25 12:04:44 -05:00
e771bd53da Release 3.101.1 2022-10-25 15:42:37 +02:00
291f46d732 Fix spacing in docs 2022-10-25 13:13:47 +01:00
e236d3312c Fix listId typo 2022-10-25 13:15:28 +02:00
794090291a Update getSubscribers filter arguments
Filter arguments 'list_id' and 'min_updated_at' do not work. These arguments currently only work with lowerCamelCase.
2022-10-25 13:15:28 +02:00
380eec1ed6 Add prop types for deactivation modals
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
7c283b7fda Use " for quotation marks
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
916080fa5a Reset step runners to not interfer with other tests
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
c10f80457d Use new getCountForWorkflow for performance
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
9773408c8b Add getCountForWorkflow method to return how many runs exist for specific status
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
5ba5426281 truncate entries of WorkflowRunLogStorage
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
098aebfaf9 Add truncate() method to WorkflowRunLogStorage
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
75d79f19cc Add information that deleting a workflow deletes also the workflow runs
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
1b70e6d494 Ensure workflows are active
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
2c57251bae Revert e8cfb2565
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
9bdb32c073 Verify deactivating workflow gets inactive after last workflow run
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
b74890137a Set a deactivating Workflow to inactive once all runs are completed
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
57548b579f Add method to fetch all runs of a workflow
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
7aa1a5f4ba Enable setStatus to handle multiple WorkflowRuns at the same time
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
d60e399a3b Alter buttons depending on workflow state, use DeactivateImmediatelyModal
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
da34614b5c Add new DeactivateImmediatelyModal
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
a0d330fded Deactivate workflow on button click depending on selected status
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
f766661f8c Show Deactivating state in header
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
82ddce42df Use WorkflowStatus enum for valid status values in Workflow type
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
bfe95676c3 Add switch to decide which deactivation state we want to set the workflow to
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
789bb0b396 Use workflow status constants
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
2620ef0b57 Do not handle workflow runs when workflow status is not active/deactivating
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
627962570e Add new workflow status 'deactivating'
[MAILPOET-4731]
2022-10-25 12:46:07 +02:00
1854 changed files with 22425 additions and 14000 deletions

View File

@ -71,13 +71,6 @@ 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:
@ -186,10 +179,10 @@ jobs:
- run:
name: Download additional WP Plugins for tests
command: |
./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
./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
- run:
name: Dump tests ENV variables for acceptance tests
command: |
@ -318,7 +311,8 @@ jobs:
parallelism: 20
working_directory: /home/circleci/mailpoet/mailpoet
machine:
image: ubuntu-2204:2022.07.1
image: ubuntu-2204:2022.10.2
docker_layer_caching: false
parameters:
multisite:
type: integer
@ -329,7 +323,7 @@ jobs:
mysql_command:
type: string
default: ''
mysql_image_version:
mysql_image:
type: string
default: ''
codeception_image_version:
@ -356,12 +350,9 @@ jobs:
enable_cot_sync:
type: integer
default: 0
allow_fail:
type: integer
default: 0
environment:
MYSQL_COMMAND: << parameters.mysql_command >>
MYSQL_IMAGE_VERSION: << parameters.mysql_image_version >>
MYSQL_IMAGE: << parameters.mysql_image >>
CODECEPTION_IMAGE_VERSION: << parameters.codeception_image_version >>
WORDPRESS_IMAGE_VERSION: << parameters.wordpress_image_version >>
steps:
@ -421,6 +412,12 @@ 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: |
@ -434,9 +431,6 @@ 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} \
@ -444,18 +438,13 @@ jobs:
-e ENABLE_COT=<< parameters.enable_cot >> \
-e ENABLE_COT_SYNC=<< parameters.enable_cot_sync >> \
codeception_acceptance "${args[@]}"
- 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
- 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:
@ -494,9 +483,12 @@ jobs:
integration_tests:
working_directory: /home/circleci/mailpoet/mailpoet
machine:
image: ubuntu-2204:2022.07.1
image: ubuntu-2204:2022.10.2
docker_layer_caching: false
environment:
CODECEPTION_IMAGE_VERSION: << parameters.codeception_image_version >>
MYSQL_COMMAND: << parameters.mysql_command >>
MYSQL_IMAGE: << parameters.mysql_image >>
parameters:
codeception_image_version:
type: string
@ -519,12 +511,12 @@ jobs:
multisite:
type: integer
default: 0
woo_core_version:
mysql_command:
type: string
default: ''
mysql_image:
type: string
default: ''
allow_fail:
type: integer
default: 0
steps:
- attach_workspace:
at: /home/circleci
@ -532,14 +524,6 @@ 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: |
@ -558,9 +542,6 @@ 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} \
@ -653,7 +634,7 @@ workflows:
- build
- acceptance_tests:
<<: *slack-fail-post-step
name: acceptance_tests
name: acceptance_tests_base_and_woo_cot_off
requires:
- unit_tests
- static_analysis_php8
@ -661,13 +642,10 @@ 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
@ -675,24 +653,10 @@ 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
@ -705,20 +669,8 @@ 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
@ -727,12 +679,9 @@ 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
@ -741,9 +690,7 @@ 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
@ -779,10 +726,14 @@ workflows:
<<: *slack-fail-post-step
requires:
- build
- acceptance_tests
- acceptance_tests_base_and_woo_cot_off
- 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:
@ -807,14 +758,14 @@ workflows:
- acceptance_tests:
<<: *slack-fail-post-step
name: acceptance_oldest
woo_core_version: 6.2.2
woo_core_version: 6.8.0
woo_subscriptions_version: 4.3.0
woo_memberships_version: 1.21.0
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
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
requires:
- build
- unit_tests:
@ -837,6 +788,8 @@ 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,23 +126,24 @@ 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 PHP 7.4 or PHP 8.0
## 🚥 Testing with different PHP versions
To switch the environment to PHP 7.4/8.0:
To switch the environment to a different PHP version:
1. Configure the `wordpress` service in `docker-compose.override.yml` to build from the php74 Dockerfile:
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):
```yaml
wordpress:
build:
context: .
dockerfile: dev/php74/Dockerfile # OR dev/php80/Dockerfile
dockerfile: dev/{PHP_VERSION}/Dockerfile
```
2. Run `docker-compose build wordpress`.
3. Start the stack with `./do start`.
3. Run `docker-compose build wordpress`.
4. Start the stack with `./do start`.
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,
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,
and start the stack using `./do start`.
## ✅ TODO

46
dev/php82/Dockerfile Normal file
View File

@ -0,0 +1,46 @@
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,6 +28,7 @@ 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)
@ -38,6 +39,7 @@ 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

@ -0,0 +1,27 @@
[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` |
| 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 |
| 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 |

View File

@ -0,0 +1,39 @@
[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,6 +15,7 @@ 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,7 +5,6 @@
"@babel/preset-env"
],
"plugins": [
"babel-plugin-typescript-to-proptypes",
[
"@babel/plugin-transform-runtime",
{

View File

@ -1,4 +1,4 @@
<?php
<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
// phpcs:disable PSR1.Classes.ClassDeclaration
// phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
@ -117,11 +117,45 @@ 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')
->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();
// 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();
}
public function translationsGetPotFileFromBuild() {
@ -351,6 +385,25 @@ 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']);
@ -372,6 +425,9 @@ class RoboFile extends \Robo\Tasks {
$collection->addCode(function() {
return $this->qaCodeSniffer([]);
});
$collection->addCode(function() {
return $this->qaMinimalPluginStandard([]);
});
return $collection->run();
}
@ -448,7 +504,56 @@ class RoboFile extends \Robo\Tasks {
'./tasks/code_sniffer/vendor/bin/phpcs',
'--extensions=php',
$severityFlag,
'--standard=tasks/code_sniffer/MailPoet',
'--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',
'-s',
]);
@ -746,6 +851,9 @@ 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);
})
@ -1063,6 +1171,18 @@ 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);
@ -1087,20 +1207,10 @@ 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([]));

BIN
mailpoet/assets/audio/0.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/1.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/2.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/3.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/4.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/5.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/6.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/7.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/8.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/9.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/a.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/b.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/c.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/d.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/e.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/f.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/g.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/h.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/i.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/j.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/k.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/l.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/m.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/n.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/o.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/p.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/q.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/r.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/s.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/t.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/u.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/v.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/w.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/x.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/y.mp3 Normal file

Binary file not shown.

BIN
mailpoet/assets/audio/z.mp3 Normal file

Binary file not shown.

View File

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

View File

@ -1,14 +1,14 @@
.mailpoet-automation-editor-workflow {
.mailpoet-automation-editor-automation {
background: #fbfbfb;
flex-grow: 1;
}
.mailpoet-automation-editor-workflow-wrapper {
.mailpoet-automation-editor-automation-wrapper {
display: grid;
padding: 50px 20px;
}
.mailpoet-automation-editor-workflow-end {
.mailpoet-automation-editor-automation-end {
background: #8c8f94;
border-radius: 999999px;
fill: white;

View File

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

View File

@ -30,3 +30,32 @@
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

@ -6,6 +6,12 @@
}
}
.mailpoet-automation-is-onboarding {
.notice {
display: none;
}
}
.mailpoet-automation-listing-heading {
margin-bottom: 16px;
}
@ -15,6 +21,21 @@
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-filter-tab-panel {
background-color: #fff;
border: 1px solid #dcdcde;

View File

@ -0,0 +1,201 @@
@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

@ -0,0 +1,33 @@
.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

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

View File

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

View File

@ -0,0 +1,126 @@
$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,3 +122,21 @@ 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

@ -0,0 +1,91 @@
#mailpoet_landingpage_container {
$content-padding: 32px 65px;
.mailpoet-content-center {
text-align: center;
}
.mailpoet-content-padding {
padding: $content-padding;
}
.landing-header {
padding: $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;
}
}
}
.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;
}
}
.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,6 +119,10 @@
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,6 +22,12 @@
}
}
#mailpoet-wizard-container {
.mailpoet-top-bar {
left: 0;
}
}
.mailpoet-wizard-logo {
margin-bottom: 100px;
text-align: center;
@ -35,6 +41,7 @@
align-items: center;
display: flex;
justify-content: center;
margin-top: 8px;
@include respond-to(medium-screen) {
flex-direction: column;
@ -42,7 +49,7 @@
}
.mailpoet-wizard-step-illustration {
margin-right: $grid-gap;
margin-right: $grid-gap-xl;
max-width: $grid-column;
text-align: center;
width: 100%;
@ -63,12 +70,16 @@
}
.mailpoet-wizard-step-content {
max-width: $grid-column-small + $grid-gap + $grid-column;
max-width: 480px;
width: 100%;
@include respond-to(medium-screen) {
max-width: $grid-column;
}
.mailpoet-button {
height: 36px;
}
}
.mailpoet-wizard-label {
@ -111,12 +122,16 @@
.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,6 +63,11 @@ $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

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

View File

@ -112,3 +112,11 @@
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,6 +41,15 @@
}
}
.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,7 +29,6 @@ $beamer-dot-size: 8px;
}
.mailpoet-top-bar-logo {
cursor: pointer;
position: relative;
top: 2px;
z-index: 1;
@ -39,6 +38,10 @@ $beamer-dot-size: 8px;
max-width: 100%;
}
}
a.mailpoet-top-bar-logo {
cursor: pointer;
}
}
.mailpoet-top-bar-logo-desktop {

View File

@ -11,17 +11,17 @@
@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-workflow';
@import './components-automation-editor/empty-automation';
@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';

View File

@ -13,18 +13,34 @@ 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: block;
display: grid;
grid-template-rows: 40px auto auto;
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;
@ -37,12 +53,15 @@ 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;
@ -54,7 +73,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;
@ -71,4 +90,27 @@ 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

@ -4,11 +4,14 @@
// 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';

View File

@ -0,0 +1,16 @@
@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';
// Components
// Actual UI components.
@import 'components-homepage/_layout';
@import 'components-homepage/_task-list';

View File

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

View File

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

View File

@ -69,6 +69,7 @@ $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
@ -78,3 +79,9 @@ $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: #f5f5f5;

View File

@ -0,0 +1,5 @@
<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>

After

Width:  |  Height:  |  Size: 565 B

View File

@ -0,0 +1 @@
<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>

After

Width:  |  Height:  |  Size: 587 B

View File

@ -0,0 +1 @@
<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>

After

Width:  |  Height:  |  Size: 355 B

View File

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

View File

@ -1,94 +1,70 @@
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 { plusIcon } from 'common/button/icon/plus';
import { Button, Flex, Popover, SlotFillProvider } from '@wordpress/components';
import { Popover, SlotFillProvider } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { initializeApi, useMutation } from './api';
import { initializeApi } from './api';
import { registerTranslations } from './i18n';
import { createStore, storeName } from './listing/store';
import { AutomationListing } from './listing';
import { AutomationListing, AutomationListingHeader } from './listing';
import { registerApiErrorHandler } from './listing/api-error-handler';
import { Notices } from './listing/components/notices';
import { WorkflowListingNotices } from './listing/workflow-listing-notices';
import { Onboarding } from './onboarding';
import {
CreateEmptyWorkflowButton,
CreateWorkflowFromTemplateButton,
} from './testing';
import { BuildYourOwnSection, HeroSection, TemplatesSection } from './sections';
import { MailPoet } from '../mailpoet';
function Content(): JSX.Element {
const count = useSelect((select) => select(storeName).getWorkflowCount());
return count > 0 ? <AutomationListing /> : <Onboarding />;
}
const trackOpenEvent = () => {
MailPoet.trackEvent('Automations > Listing viewed');
};
function Workflows(): JSX.Element {
function Content(): JSX.Element {
const [isBooting, setIsBooting] = useState(true);
const count = useSelect((select) => select(storeName).getAutomationCount());
useEffect(() => {
if (!isBooting || count === 0) {
return;
}
trackOpenEvent();
setIsBooting(false);
}, [isBooting, count]);
const content =
count > 0 ? (
<>
<AutomationListingHeader />
<AutomationListing />
</>
) : (
<HeroSection />
);
// 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 (
<>
<TopBarWithBeamer />
<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>
<Notices />
<Content />
{content}
<TemplatesSection />
<BuildYourOwnSection />
</>
);
}
function RecreateSchemaButton(): JSX.Element {
const [createSchema, { loading, error }] = useMutation('system/database', {
method: 'POST',
});
function Automations(): JSX.Element {
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>
<>
<TopBarWithBeamer />
<Notices />
<Content />
</>
);
}
@ -96,26 +72,8 @@ function App(): JSX.Element {
return (
<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>
<Popover.Slot />
</div>
<Automations />
<Popover.Slot />
</BrowserRouter>
</SlotFillProvider>
);
@ -126,6 +84,7 @@ window.addEventListener('DOMContentLoaded', () => {
const root = document.getElementById('mailpoet_automation');
if (root) {
registerTranslations();
registerApiErrorHandler();
initializeApi();
ReactDOM.render(<App />, root);

View File

@ -0,0 +1,64 @@
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

@ -4,9 +4,9 @@ declare global {
root: string;
nonce: string;
};
mailpoet_workflow_count: number;
mailpoet_automation_count: number;
}
}
export const api = window.mailpoet_automation_api;
export const workflowCount = window.mailpoet_workflow_count;
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_workflow_not_valid') {
if (code === 'mailpoet_automation_not_valid') {
dispatch(storeName).setErrors({ steps: errorObject.data.errors });
return undefined;
}
@ -30,6 +30,7 @@ export const registerApiErrorHandler = (): void =>
message ?? __('An unknown error occurred.', 'mailpoet'),
{ explicitDismiss: true },
);
dispatch(storeName).setErrors({ steps: [] });
return undefined;
}

View File

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

View File

@ -1,7 +1,7 @@
import { useContext } from 'react';
import { __unstableCompositeItem as CompositeItem } from '@wordpress/components';
import { Icon, plus } from '@wordpress/icons';
import { WorkflowCompositeContext } from './context';
import { AutomationCompositeContext } from './context';
type Props = {
onClick?: (element: HTMLButtonElement) => void;
@ -9,7 +9,7 @@ type Props = {
};
export function AddStepButton({ onClick, previousStepId }: Props): JSX.Element {
const compositeState = useContext(WorkflowCompositeContext);
const compositeState = useContext(AutomationCompositeContext);
return (
<CompositeItem
state={compositeState}

View File

@ -3,7 +3,7 @@ import { __unstableCompositeItem as CompositeItem } from '@wordpress/components'
import { Icon, plus } from '@wordpress/icons';
import { __ } from '@wordpress/i18n';
import { useDispatch } from '@wordpress/data';
import { WorkflowCompositeContext } from './context';
import { AutomationCompositeContext } from './context';
import { Step } from './types';
import { storeName } from '../../store';
@ -12,14 +12,14 @@ type Props = {
};
export function AddTrigger({ step }: Props): JSX.Element {
const compositeState = useContext(WorkflowCompositeContext);
const compositeState = useContext(AutomationCompositeContext);
const { setInserterPopover } = useDispatch(storeName);
return (
<CompositeItem
state={compositeState}
role="treeitem"
className="mailpoet-automation-workflow-add-trigger"
className="mailpoet-automation-add-trigger"
data-previous-step-id={step.id}
focusable
onClick={(event) => {

View File

@ -1,5 +1,5 @@
import { __unstableUseCompositeState as useCompositeState } from '@wordpress/components';
import { createContext } from '@wordpress/element';
export const WorkflowCompositeContext =
export const AutomationCompositeContext =
createContext<ReturnType<typeof useCompositeState>>(undefined);

View File

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

View File

@ -7,8 +7,8 @@ import { useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { Icon, check } from '@wordpress/icons';
import { Hooks } from 'wp-js-hooks';
import { WorkflowCompositeContext } from './context';
import { EmptyWorkflow } from './empty-workflow';
import { AutomationCompositeContext } from './context';
import { EmptyAutomation } from './empty-automation';
import { Separator } from './separator';
import { Step } from './step';
import { Step as StepData } from './types';
@ -16,11 +16,15 @@ import { InserterPopover } from '../inserter-popover';
import { storeName } from '../../store';
import { AddTrigger } from './add-trigger';
import { Statistics } from './statistics';
import {
RenderStepSeparatorType,
RenderStepType,
} from '../../../types/filters';
export function Workflow(): JSX.Element {
const { workflowData, selectedStep } = useSelect(
export function Automation(): JSX.Element {
const { automationData, selectedStep } = useSelect(
(select) => ({
workflowData: select(storeName).getWorkflowData(),
automationData: select(storeName).getAutomationData(),
selectedStep: select(storeName).getSelectedStep(),
}),
[],
@ -32,9 +36,9 @@ export function Workflow(): JSX.Element {
shift: true,
});
const stepMap = workflowData?.steps ?? undefined;
const stepMap = automationData?.steps ?? undefined;
// serialize steps (for now, we support only one trigger and linear workflows)
// serialize steps (for now, we support only one trigger and linear automations)
const steps = useMemo(() => {
const stepArray = [stepMap.root];
@ -50,9 +54,9 @@ export function Workflow(): JSX.Element {
}, [stepMap]);
const renderStep = useMemo(
() =>
(): RenderStepType =>
Hooks.applyFilters(
'mailpoet.automation.workflow.render_step',
'mailpoet.automation.render_step',
(stepData: StepData) =>
stepData.type === 'root' ? (
<AddTrigger step={stepData} />
@ -67,9 +71,9 @@ export function Workflow(): JSX.Element {
);
const renderSeparator = useMemo(
() =>
(): RenderStepSeparatorType =>
Hooks.applyFilters(
'mailpoet.automation.workflow.render_step_separator',
'mailpoet.automation.render_step_separator',
(previousStepData: StepData) => (
<Separator previousStepId={previousStepData.id} />
),
@ -77,20 +81,20 @@ export function Workflow(): JSX.Element {
[],
);
if (!workflowData) {
return <EmptyWorkflow />;
if (!automationData) {
return <EmptyAutomation />;
}
return (
<WorkflowCompositeContext.Provider value={compositeState}>
<AutomationCompositeContext.Provider value={compositeState}>
<Composite
state={compositeState}
role="tree"
aria-label={__('Workflow', 'mailpoet')}
aria-label={__('Automation', 'mailpoet')}
aria-orientation="vertical"
className="mailpoet-automation-editor-workflow"
className="mailpoet-automation-editor-automation"
>
<div className="mailpoet-automation-editor-workflow-wrapper">
<div className="mailpoet-automation-editor-automation-wrapper">
<Statistics />
{stepMap.root.next_steps.length === 0 ? (
<>
@ -115,13 +119,13 @@ export function Workflow(): JSX.Element {
</Fragment>
))}
<Icon
className="mailpoet-automation-editor-workflow-end"
className="mailpoet-automation-editor-automation-end"
icon={check}
/>
<div />
</div>
<InserterPopover />
</Composite>
</WorkflowCompositeContext.Provider>
</AutomationCompositeContext.Provider>
);
}

View File

@ -0,0 +1,40 @@
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

@ -0,0 +1,68 @@
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

@ -3,8 +3,8 @@ import { useContext } from 'react';
import { __unstableCompositeItem as CompositeItem } from '@wordpress/components';
import { useDispatch, useRegistry, useSelect } from '@wordpress/data';
import { blockMeta } from '@wordpress/icons';
import { __ } from '@wordpress/i18n';
import { WorkflowCompositeContext } from './context';
import { __, _x } from '@wordpress/i18n';
import { AutomationCompositeContext } from './context';
import { StepMoreMenu } from './step-more-menu';
import { Step as StepData } from './types';
import { Chip } from '../chip';
@ -48,7 +48,7 @@ export function Step({ step, isSelected }: Props): JSX.Element {
[step],
);
const { openSidebar, selectStep } = useDispatch(storeName);
const compositeState = useContext(WorkflowCompositeContext);
const compositeState = useContext(AutomationCompositeContext);
const { batch } = useRegistry();
const compositeItemId = `step-${step.id}`;
@ -90,7 +90,7 @@ export function Step({ step, isSelected }: Props): JSX.Element {
>
{step.type !== 'trigger'
? stepTypeData.title
: __('Trigger', 'mailpoet')}
: _x('Trigger', 'noun', 'mailpoet')}
</label>
<div className="mailpoet-automation-editor-step-subtitle">
{step.type !== 'trigger'

View File

@ -1,3 +1,5 @@
import { AutomationStatus } from '../../../listing/automation';
export type NextStep = {
id: string;
};
@ -10,10 +12,10 @@ export type Step = {
next_steps: NextStep[];
};
export type Workflow = {
export type Automation = {
id: number;
name: string;
status: 'active' | 'inactive' | 'draft' | 'trash';
status: AutomationStatus;
created_at: string;
updated_at: string;
activated_at: string;

View File

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

View File

@ -9,10 +9,11 @@ import {
import { useDispatch, useSelect } from '@wordpress/data';
import { createContext } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { ErrorBoundary } from 'common';
import { Chip } from '../chip';
import { ColoredIcon } from '../icons';
import {
StepError as StepErrorType,
StepErrors as StepErrorType,
stepSidebarKey,
storeName,
} from '../../store';
@ -35,17 +36,17 @@ type StepErrorProps = {
function StepError({ stepId }: StepErrorProps): JSX.Element {
const compositeState = useContext(ErrorsCompositeContext);
const { steps, workflowData } = useSelect(
const { steps, automationData } = useSelect(
(select) => ({
steps: select(storeName).getSteps(),
workflowData: select(storeName).getWorkflowData(),
automationData: select(storeName).getAutomationData(),
}),
[],
);
const { openSidebar, selectStep } = useDispatch(storeName);
const stepData = workflowData.steps[stepId];
const stepData = automationData.steps[stepId];
const step = steps.find(({ key }) => key === stepData.key);
return (
@ -70,6 +71,8 @@ function StepError({ stepId }: StepErrorProps): JSX.Element {
);
}
StepError.displayName = 'StepError';
export function Errors(): JSX.Element | null {
const [showPopover, setShowPopover] = useState(false);
@ -78,10 +81,10 @@ export function Errors(): JSX.Element | null {
shift: true,
});
const { errors, workflowData } = useSelect(
const { errors, automationData } = useSelect(
(select) => ({
errors: select(storeName).getErrors(),
workflowData: select(storeName).getWorkflowData(),
automationData: select(storeName).getAutomationData(),
}),
[],
);
@ -93,18 +96,18 @@ export function Errors(): JSX.Element | null {
}
const visited = new Map<string, StepErrorType | undefined>();
const ids = workflowData.steps.root.next_steps.map(({ id }) => id);
const ids = automationData.steps.root.next_steps.map(({ id }) => id);
while (ids.length > 0) {
const id = ids.shift();
if (!visited.has(id)) {
visited.set(id, errors.steps[id]);
workflowData.steps[id]?.next_steps?.forEach((step) =>
automationData.steps[id]?.next_steps?.forEach((step) =>
ids.push(step.id),
);
}
}
return [...visited.values()].filter((error) => !!error);
}, [errors, workflowData]);
}, [errors, automationData]);
// automatically open the popover when errors appear
const hasErrors = stepErrors.length > 0;
@ -151,15 +154,20 @@ export function Errors(): JSX.Element | null {
<Composite
state={compositeState}
role="list"
aria-label={__('Workflow errors', 'mailpoet')}
aria-label={__('Automation errors', 'mailpoet')}
className="mailpoet-automation-errors"
>
<div className="mailpoet-automation-errors-header">
{__('The following steps are not fully set:', 'mailpoet')}
{
// translators: Label for a list of automation steps that are incomplete or have errors
__('The following steps are not fully set:', 'mailpoet')
}
</div>
{stepErrors.map((error) => (
<StepError key={error.step_id} stepId={error.step_id} />
))}
<ErrorBoundary>
{stepErrors.map((error) => (
<StepError key={error.step_id} stepId={error.step_id} />
))}
</ErrorBoundary>
</Composite>
</ErrorsCompositeContext.Provider>
</Popover>

View File

@ -1,51 +1,113 @@
import { useState } from 'react';
import { Button, NavigableMenu, TextControl } from '@wordpress/components';
import {
Button,
NavigableMenu,
TextControl,
Tooltip,
} from '@wordpress/components';
import { dispatch, useDispatch, useSelect } from '@wordpress/data';
import { PinnedItems } from '@wordpress/interface';
import { __ } from '@wordpress/i18n';
import { ErrorBoundary } from 'common';
import { DocumentActions } from './document_actions';
import { Errors } from './errors';
import { InserterToggle } from './inserter_toggle';
import { MoreMenu } from './more_menu';
import { storeName } from '../../store';
import { WorkflowStatus } from '../../../listing/workflow';
import { DeactivateModal } from '../modals/deactivate-modal';
import { AutomationStatus } from '../../../listing/automation';
import {
DeactivateImmediatelyModal,
DeactivateModal,
} from '../modals/deactivate-modal';
// See:
// https://github.com/WordPress/gutenberg/blob/9601a33e30ba41bac98579c8d822af63dd961488/packages/edit-post/src/components/header/index.js
// https://github.com/WordPress/gutenberg/blob/0ee78b1bbe9c6f3e6df99f3b967132fa12bef77d/packages/edit-site/src/components/header/index.js
function ActivateButton({ onClick }): JSX.Element {
const { errors } = useSelect(
function ActivateButton({ label }): JSX.Element {
const { errors, isDeactivating } = useSelect(
(select) => ({
errors: select(storeName).getErrors(),
isDeactivating:
select(storeName).getAutomationData().status ===
AutomationStatus.DEACTIVATING,
}),
[],
);
const { openActivationPanel } = useDispatch(storeName);
return (
const button = (
<Button
variant="primary"
className="editor-post-publish-button"
onClick={onClick}
disabled={!!errors}
onClick={openActivationPanel}
disabled={isDeactivating || !!errors}
>
{__('Activate', 'mailpoet')}
{label}
</Button>
);
if (isDeactivating) {
return (
<Tooltip
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// The following error seems to be a mismatch. It claims the 'delay' prop does not exist, but it does.
delay={0}
text={__(
'Editing an active automation is temporarily unavailable. We are working on introducing this functionality.',
'mailpoet',
)}
>
{button}
</Tooltip>
);
}
return button;
}
function UpdateButton(): JSX.Element {
const { save } = useDispatch(storeName);
const { automation } = useSelect(
(select) => ({
automation: select(storeName).getAutomationData(),
}),
[],
);
if (automation.stats.totals.in_progress === 0) {
return (
<Button
variant="primary"
className="editor-post-publish-button"
onClick={save}
>
{__('Update', 'mailpoet')}
</Button>
);
}
return (
<Button
variant="primary"
className="editor-post-publish-button"
onClick={save}
<Tooltip
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// The following error seems to be a mismatch. It claims the 'delay' prop does not exist, but it does.
delay={0}
text={__(
'Editing an active automation is temporarily unavailable. We are working on introducing this functionality.',
'mailpoet',
)}
>
{__('Update', 'mailpoet')}
</Button>
<Button
variant="primary"
className="editor-post-publish-button"
onClick={save}
disabled
>
{__('Update', 'mailpoet')}
</Button>
</Tooltip>
);
}
@ -65,7 +127,7 @@ function DeactivateButton(): JSX.Element {
const { hasUsersInProgress } = useSelect(
(select) => ({
hasUsersInProgress:
select(storeName).getWorkflowData().stats.totals.in_progress > 0,
select(storeName).getAutomationData().stats.totals.in_progress > 0,
}),
[],
);
@ -99,20 +161,56 @@ function DeactivateButton(): JSX.Element {
);
}
function DeactivateNowButton(): JSX.Element {
const [showDeactivateModal, setShowDeactivateModal] = useState(false);
const [isBusy, setIsBusy] = useState(false);
const { hasUsersInProgress } = useSelect(
(select) => ({
hasUsersInProgress:
select(storeName).getAutomationData().stats.totals.in_progress > 0,
}),
[],
);
const deactivateOrShowModal = () => {
if (hasUsersInProgress) {
setShowDeactivateModal(true);
return;
}
setIsBusy(true);
void dispatch(storeName).deactivate();
};
return (
<>
{showDeactivateModal && (
<DeactivateImmediatelyModal
onClose={() => {
setShowDeactivateModal(false);
}}
/>
)}
<Button
isBusy={isBusy}
variant="tertiary"
onClick={deactivateOrShowModal}
>
{__('Deactivate now', 'mailpoet')}
</Button>
</>
);
}
type Props = {
showInserterToggle: boolean;
toggleActivatePanel: () => void;
};
export function Header({
showInserterToggle,
toggleActivatePanel,
}: Props): JSX.Element {
const { setWorkflowName } = useDispatch(storeName);
const { workflowName, workflowStatus } = useSelect(
export function Header({ showInserterToggle }: Props): JSX.Element {
const { setAutomationName } = useDispatch(storeName);
const { automationName, automationStatus } = useSelect(
(select) => ({
workflowName: select(storeName).getWorkflowData().name,
workflowStatus: select(storeName).getWorkflowData().status,
automationName: select(storeName).getAutomationData().name,
automationStatus: select(storeName).getAutomationData().status,
}),
[],
);
@ -130,40 +228,50 @@ export function Header({
</div>
<div className="edit-site-header_center">
<DocumentActions>
{() => (
<div className="mailpoet-automation-editor-dropdown-name-edit">
<div className="mailpoet-automation-editor-dropdown-name-edit-title">
{__('Automation name', 'mailpoet')}
<ErrorBoundary>
<DocumentActions>
{() => (
<div className="mailpoet-automation-editor-dropdown-name-edit">
<div className="mailpoet-automation-editor-dropdown-name-edit-title">
{__('Automation name', 'mailpoet')}
</div>
<TextControl
value={automationName}
onChange={(newName) => setAutomationName(newName)}
help={__(
`Give the automation a name that indicates its purpose. E.g. "Abandoned cart recovery"`,
'mailpoet',
)}
/>
</div>
<TextControl
value={workflowName}
onChange={(newName) => setWorkflowName(newName)}
help={__(
`Give the automation a name that indicates its purpose. E.g. "Abandoned cart recovery"`,
'mailpoet',
)}
/>
</div>
)}
</DocumentActions>
)}
</DocumentActions>
</ErrorBoundary>
</div>
<div className="edit-site-header_end">
<div className="edit-site-header__actions">
<Errors />
{workflowStatus !== WorkflowStatus.ACTIVE && (
<ErrorBoundary>
<Errors />
</ErrorBoundary>
{automationStatus === AutomationStatus.DRAFT && (
<>
<SaveDraftButton />
<ActivateButton onClick={toggleActivatePanel} />
<ActivateButton label={__('Activate', 'mailpoet')} />
</>
)}
{workflowStatus === WorkflowStatus.ACTIVE && (
{automationStatus === AutomationStatus.ACTIVE && (
<>
<DeactivateButton />
<UpdateButton />
</>
)}
{automationStatus === AutomationStatus.DEACTIVATING && (
<>
<DeactivateNowButton />
<ActivateButton label={__('Update & Activate', 'mailpoet')} />
</>
)}
<PinnedItems.Slot scope={storeName} />
<MoreMenu />
</div>

View File

@ -1,6 +1,6 @@
import { Button, ToolbarItem } from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
import { __, _x } from '@wordpress/i18n';
import { __ } from '@wordpress/i18n';
import { plus } from '@wordpress/icons';
import { storeName } from '../../store';
@ -28,13 +28,11 @@ export function InserterToggle(): JSX.Element {
onMouseDown={(event) => event.preventDefault()}
onClick={toggleInserterSidebar}
icon={plus}
label={_x(
'Toggle step inserter',
'Generic label for step inserter button',
)}
label={__('Toggle step inserter', 'mailpoet')}
showTooltip={!showIconLabels}
>
{showIconLabels && (!isInserterOpened ? __('Add') : __('Close'))}
{showIconLabels &&
(!isInserterOpened ? __('Add', 'mailpoet') : __('Close', 'mailpoet'))}
</ToolbarItem>
);
}

View File

@ -20,14 +20,14 @@ export function MoreMenu(): JSX.Element {
>
{() => (
<>
<MenuGroup label={_x('View', 'noun')}>
<MenuGroup label={_x('View', 'noun', 'mailpoet')}>
<PreferenceToggleMenuItem
scope={storeName}
name="fullscreenMode"
label={__('Fullscreen mode')}
info={__('Work without distraction')}
messageActivated={__('Fullscreen mode activated')}
messageDeactivated={__('Fullscreen mode deactivated')}
label={__('Fullscreen mode', 'mailpoet')}
info={__('Work without distraction', 'mailpoet')}
messageActivated={__('Fullscreen mode activated', 'mailpoet')}
messageDeactivated={__('Fullscreen mode deactivated', 'mailpoet')}
shortcut={displayShortcut.secondary('f')}
/>
</MenuGroup>

View File

@ -0,0 +1,2 @@
export * from './panel';
export * from './form-token-field';

View File

@ -13,7 +13,10 @@ export const InserterListboxGroup = forwardRef<HTMLDivElement, Props>(
useEffect(() => {
if (shouldSpeak) {
speak(__('Use left and right arrow keys to move through blocks'));
speak(
// translators: Moving through automation step list using keyboard
__('Use left and right arrow keys to move through steps', 'mailpoet'),
);
}
}, [shouldSpeak]);

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