Use new @wordpress/data types in dynamic segments

[MAILPOET-5102]
This commit is contained in:
Rostislav Wolny
2023-03-08 17:27:48 +01:00
committed by Aschepikov
parent 5890b74598
commit a8916a2b78
29 changed files with 315 additions and 311 deletions

View File

@@ -5,6 +5,7 @@ import { MailPoet } from 'mailpoet';
import { Select } from 'common/form/select/select';
import { WordpressRoleFormItem } from '../../types';
import { store } from '../../store/store';
export function validateCheckbox(item: WordpressRoleFormItem): boolean {
return item.value === '1' || item.value === '0';
@@ -16,14 +17,12 @@ type Props = {
export function Checkbox({ filterIndex }: Props): JSX.Element {
const segment: WordpressRoleFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const { updateSegmentFilterFromEvent, updateSegmentFilter } = useDispatch(
'mailpoet-dynamic-segments-form',
);
const { updateSegmentFilterFromEvent, updateSegmentFilter } =
useDispatch(store);
useEffect(() => {
if (segment.value !== '1' && segment.value !== '0') {

View File

@@ -9,6 +9,7 @@ import { Grid } from 'common/grid';
import { Datepicker } from 'common/datepicker/datepicker';
import { WordpressRoleFormItem, OnFilterChange } from '../../types';
import { store } from '../../store/store';
interface ComponentProps {
onChange: OnFilterChange;
@@ -228,12 +229,11 @@ export function CustomFieldDate({
filterIndex,
}: Props): JSX.Element {
const segment: WordpressRoleFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const { updateSegmentFilter } = useDispatch('mailpoet-dynamic-segments-form');
const { updateSegmentFilter } = useDispatch(store);
useEffect(() => {
if (segment.date_type !== customField.params.date_type) {

View File

@@ -9,6 +9,7 @@ import {
SelectOption,
WindowCustomFields,
} from '../../types';
import { store } from '../../store/store';
interface ParamsType {
values?: {
@@ -26,15 +27,14 @@ type Props = {
export function RadioSelect({ filterIndex }: Props): JSX.Element {
const segment: WordpressRoleFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const { updateSegmentFilter } = useDispatch('mailpoet-dynamic-segments-form');
const { updateSegmentFilter } = useDispatch(store);
const customFieldsList: WindowCustomFields = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getCustomFieldsList(),
(select) => select(store).getCustomFieldsList(),
[],
);
const customField = find(

View File

@@ -7,6 +7,7 @@ import { Input } from 'common/form/input/input';
import { Grid } from 'common/grid';
import { WordpressRoleFormItem } from '../../types';
import { store } from '../../store/store';
export function validateText(item: WordpressRoleFormItem): boolean {
return (
@@ -26,14 +27,12 @@ type Props = {
export function Text({ filterIndex }: Props): JSX.Element {
const segment: WordpressRoleFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const { updateSegmentFilterFromEvent, updateSegmentFilter } = useDispatch(
'mailpoet-dynamic-segments-form',
);
const { updateSegmentFilterFromEvent, updateSegmentFilter } =
useDispatch(store);
useEffect(() => {
if (segment.operator === undefined) {

View File

@@ -1,50 +1,16 @@
import { MailPoet } from 'mailpoet';
import { useSelect } from '@wordpress/data';
import {
EmailActionTypes,
EmailFormItem,
SegmentTypes,
WordpressRoleFormItem,
} from '../types';
import { store } from '../store/store';
import { EmailOpenStatisticsFields } from './email_statistics_opens';
import { EmailClickStatisticsFields } from './email_statistics_clicks';
import { EmailOpensAbsoluteCountFields } from './email_opens_absolute_count';
export const EmailSegmentOptions = [
{
value: EmailActionTypes.OPENS_ABSOLUTE_COUNT,
label: MailPoet.I18n.t('emailActionOpensAbsoluteCount'),
group: SegmentTypes.Email,
},
{
value: EmailActionTypes.MACHINE_OPENS_ABSOLUTE_COUNT,
label: MailPoet.I18n.t('emailActionMachineOpensAbsoluteCount'),
group: SegmentTypes.Email,
},
{
value: EmailActionTypes.OPENED,
label: MailPoet.I18n.t('emailActionOpened'),
group: SegmentTypes.Email,
},
{
value: EmailActionTypes.MACHINE_OPENED,
label: MailPoet.I18n.t('emailActionMachineOpened'),
group: SegmentTypes.Email,
},
{
value: EmailActionTypes.CLICKED,
label: MailPoet.I18n.t('emailActionClicked'),
group: SegmentTypes.Email,
},
{
value: EmailActionTypes.CLICKED_ANY,
label: MailPoet.I18n.t('emailActionClickedAnyEmail'),
group: SegmentTypes.Email,
},
];
export function validateEmail(formItems: EmailFormItem): boolean {
// check if the action has the right type
if (!Object.values(EmailActionTypes).some((v) => v === formItems.action))
@@ -87,8 +53,7 @@ type Props = {
export function EmailFields({ filterIndex }: Props): JSX.Element {
const segment: WordpressRoleFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);

View File

@@ -7,6 +7,7 @@ import { Input } from 'common/form/input/input';
import { MailPoet } from 'mailpoet';
import { EmailFormItem } from '../types';
import { store } from '../store/store';
function replaceElementsInDaysSentence(
fn: (value) => JSX.Element,
@@ -32,14 +33,12 @@ export function EmailOpensAbsoluteCountFields({
filterIndex,
}: Props): JSX.Element {
const segment: EmailFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } = useDispatch(
'mailpoet-dynamic-segments-form',
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } =
useDispatch(store);
useEffect(() => {
if (segment.operator === undefined) {
void updateSegmentFilter({ operator: 'more' }, filterIndex);

View File

@@ -0,0 +1,35 @@
import { EmailActionTypes, SegmentTypes } from 'segments/dynamic/types';
import { MailPoet } from 'mailpoet';
export const EmailSegmentOptions = [
{
value: EmailActionTypes.OPENS_ABSOLUTE_COUNT,
label: MailPoet.I18n.t('emailActionOpensAbsoluteCount'),
group: SegmentTypes.Email,
},
{
value: EmailActionTypes.MACHINE_OPENS_ABSOLUTE_COUNT,
label: MailPoet.I18n.t('emailActionMachineOpensAbsoluteCount'),
group: SegmentTypes.Email,
},
{
value: EmailActionTypes.OPENED,
label: MailPoet.I18n.t('emailActionOpened'),
group: SegmentTypes.Email,
},
{
value: EmailActionTypes.MACHINE_OPENED,
label: MailPoet.I18n.t('emailActionMachineOpened'),
group: SegmentTypes.Email,
},
{
value: EmailActionTypes.CLICKED,
label: MailPoet.I18n.t('emailActionClicked'),
group: SegmentTypes.Email,
},
{
value: EmailActionTypes.CLICKED_ANY,
label: MailPoet.I18n.t('emailActionClickedAnyEmail'),
group: SegmentTypes.Email,
},
];

View File

@@ -13,6 +13,7 @@ import {
SelectOption,
WindowNewslettersList,
} from '../types';
import { store } from '../store/store';
const shouldDisplayLinks = (itemNewsletterId?: string): boolean =>
!!itemNewsletterId;
@@ -25,17 +26,15 @@ export function EmailClickStatisticsFields({
filterIndex,
}: Props): JSX.Element {
const segment: EmailFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } = useDispatch(
'mailpoet-dynamic-segments-form',
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } =
useDispatch(store);
const newslettersList: WindowNewslettersList = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getNewslettersList(),
(select) => select(store).getNewslettersList(),
[],
);

View File

@@ -13,6 +13,7 @@ import {
SelectOption,
WindowNewslettersList,
} from '../types';
import { store } from '../store/store';
type Props = {
filterIndex: number;
@@ -20,17 +21,15 @@ type Props = {
export function EmailOpenStatisticsFields({ filterIndex }: Props): JSX.Element {
const segment: EmailFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } = useDispatch(
'mailpoet-dynamic-segments-form',
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } =
useDispatch(store);
const newslettersList: WindowNewslettersList = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getNewslettersList(),
(select) => select(store).getNewslettersList(),
[],
);

View File

@@ -1,11 +1,7 @@
import { MailPoet } from 'mailpoet';
import { useSelect } from '@wordpress/data';
import {
SegmentTypes,
WordpressRoleFormItem,
SubscriberActionTypes,
} from '../types';
import { WordpressRoleFormItem, SubscriberActionTypes } from '../types';
import { store } from '../store/store';
import { WordpressRoleFields } from './subscriber_wordpress_role';
import {
SubscriberScoreFields,
@@ -69,39 +65,6 @@ export function validateSubscriber(formItems: WordpressRoleFormItem): boolean {
return false;
}
export const SubscriberSegmentOptions = [
{
value: SubscriberActionTypes.MAILPOET_CUSTOM_FIELD,
label: MailPoet.I18n.t('mailpoetCustomField'),
group: SegmentTypes.WordPressRole,
},
{
value: SubscriberActionTypes.SUBSCRIBER_SCORE,
label: MailPoet.I18n.t('subscriberScore'),
group: SegmentTypes.WordPressRole,
},
{
value: SubscriberActionTypes.SUBSCRIBED_DATE,
label: MailPoet.I18n.t('subscribedDate'),
group: SegmentTypes.WordPressRole,
},
{
value: SubscriberActionTypes.SUBSCRIBED_TO_LIST,
label: MailPoet.I18n.t('subscribedToList'),
group: SegmentTypes.WordPressRole,
},
{
value: SubscriberActionTypes.SUBSCRIBER_TAG,
label: MailPoet.I18n.t('subscriberTag'),
group: SegmentTypes.WordPressRole,
},
{
value: SubscriberActionTypes.WORDPRESS_ROLE,
label: MailPoet.I18n.t('segmentsSubscriber'),
group: SegmentTypes.WordPressRole,
},
];
const componentsMap = {
[SubscriberActionTypes.WORDPRESS_ROLE]: WordpressRoleFields,
[SubscriberActionTypes.SUBSCRIBER_SCORE]: SubscriberScoreFields,
@@ -117,8 +80,7 @@ type Props = {
export function SubscriberFields({ filterIndex }: Props): JSX.Element {
const segment: WordpressRoleFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);

View File

@@ -14,6 +14,7 @@ import {
SelectOption,
WindowCustomFields,
} from '../types';
import { store } from '../store/store';
enum CustomFieldsTypes {
DATE = 'date',
@@ -58,15 +59,14 @@ type Props = {
export function MailPoetCustomFields({ filterIndex }: Props): JSX.Element {
const segment: WordpressRoleFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const { updateSegmentFilter } = useDispatch('mailpoet-dynamic-segments-form');
const { updateSegmentFilter } = useDispatch(store);
const customFieldsList: WindowCustomFields = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getCustomFieldsList(),
(select) => select(store).getCustomFieldsList(),
[],
);
const selectedCustomField = find(

View File

@@ -0,0 +1,35 @@
import { SegmentTypes, SubscriberActionTypes } from 'segments/dynamic/types';
import { MailPoet } from 'mailpoet';
export const SubscriberSegmentOptions = [
{
value: SubscriberActionTypes.MAILPOET_CUSTOM_FIELD,
label: MailPoet.I18n.t('mailpoetCustomField'),
group: SegmentTypes.WordPressRole,
},
{
value: SubscriberActionTypes.SUBSCRIBER_SCORE,
label: MailPoet.I18n.t('subscriberScore'),
group: SegmentTypes.WordPressRole,
},
{
value: SubscriberActionTypes.SUBSCRIBED_DATE,
label: MailPoet.I18n.t('subscribedDate'),
group: SegmentTypes.WordPressRole,
},
{
value: SubscriberActionTypes.SUBSCRIBED_TO_LIST,
label: MailPoet.I18n.t('subscribedToList'),
group: SegmentTypes.WordPressRole,
},
{
value: SubscriberActionTypes.SUBSCRIBER_TAG,
label: MailPoet.I18n.t('subscriberTag'),
group: SegmentTypes.WordPressRole,
},
{
value: SubscriberActionTypes.WORDPRESS_ROLE,
label: MailPoet.I18n.t('segmentsSubscriber'),
group: SegmentTypes.WordPressRole,
},
];

View File

@@ -7,6 +7,7 @@ import { Grid } from 'common/grid';
import { Input } from 'common/form/input/input';
import { WordpressRoleFormItem } from '../types';
import { store } from '../store/store';
export enum SubscriberScoreOperator {
HIGHER_THAN = 'higherThan',
@@ -67,14 +68,12 @@ function replaceSubscriberScoreSentence(
export function SubscriberScoreFields({ filterIndex }: Props): JSX.Element {
const segment: WordpressRoleFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } = useDispatch(
'mailpoet-dynamic-segments-form',
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } =
useDispatch(store);
useEffect(() => {
if (

View File

@@ -9,6 +9,7 @@ import { Grid } from 'common/grid';
import { Input } from 'common/form/input/input';
import { WordpressRoleFormItem } from '../types';
import { store } from '../store/store';
export enum SubscribedDateOperator {
BEFORE = 'before',
@@ -54,14 +55,12 @@ type Props = {
export function SubscribedDateFields({ filterIndex }: Props): JSX.Element {
const segment: WordpressRoleFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } = useDispatch(
'mailpoet-dynamic-segments-form',
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } =
useDispatch(store);
useEffect(() => {
if (

View File

@@ -13,6 +13,7 @@ import {
StaticSegment,
WordpressRoleFormItem,
} from '../types';
import { store } from '../store/store';
export function validateSubscribedToList(
formItems: WordpressRoleFormItem,
@@ -32,19 +33,16 @@ type Props = {
export function SubscribedToList({ filterIndex }: Props): JSX.Element {
const segment: WordpressRoleFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const staticSegmentsList: StaticSegment[] = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getStaticSegmentsList(),
(select) => select(store).getStaticSegmentsList(),
[],
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } = useDispatch(
'mailpoet-dynamic-segments-form',
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } =
useDispatch(store);
useEffect(() => {
if (

View File

@@ -14,6 +14,7 @@ import {
AnyValueTypes,
SubscriberActionTypes,
} from '../types';
import { store } from '../store/store';
type Props = {
filterIndex: number;
@@ -21,14 +22,12 @@ type Props = {
export function WordpressRoleFields({ filterIndex }: Props): JSX.Element {
const segment: WordpressRoleFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } = useDispatch(
'mailpoet-dynamic-segments-form',
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } =
useDispatch(store);
useEffect(() => {
if (
@@ -42,7 +41,7 @@ export function WordpressRoleFields({ filterIndex }: Props): JSX.Element {
}, [updateSegmentFilter, segment, filterIndex]);
const wordpressRoles: WindowEditableRoles = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getWordpressRoles(),
(select) => select(store).getWordpressRoles(),
[],
);
const options = wordpressRoles.map((currentValue) => ({

View File

@@ -9,54 +9,17 @@ import { Grid } from 'common/grid';
import { Input } from 'common/form/input/input';
import {
AnyValueTypes,
SegmentTypes,
SelectOption,
WindowProductCategories,
WindowProducts,
WindowWooCommerceCountries,
WooCommerceFormItem,
} from '../types';
enum WooCommerceActionTypes {
NUMBER_OF_ORDERS = 'numberOfOrders',
PURCHASED_CATEGORY = 'purchasedCategory',
PURCHASED_PRODUCT = 'purchasedProduct',
TOTAL_SPENT = 'totalSpent',
CUSTOMER_IN_COUNTRY = 'customerInCountry',
}
export const WooCommerceOptions = [
{
value: WooCommerceActionTypes.CUSTOMER_IN_COUNTRY,
label: MailPoet.I18n.t('wooCustomerInCountry'),
group: SegmentTypes.WooCommerce,
},
{
value: WooCommerceActionTypes.NUMBER_OF_ORDERS,
label: MailPoet.I18n.t('wooNumberOfOrders'),
group: SegmentTypes.WooCommerce,
},
{
value: WooCommerceActionTypes.PURCHASED_CATEGORY,
label: MailPoet.I18n.t('wooPurchasedCategory'),
group: SegmentTypes.WooCommerce,
},
{
value: WooCommerceActionTypes.PURCHASED_PRODUCT,
label: MailPoet.I18n.t('wooPurchasedProduct'),
group: SegmentTypes.WooCommerce,
},
{
value: WooCommerceActionTypes.TOTAL_SPENT,
label: MailPoet.I18n.t('wooTotalSpent'),
group: SegmentTypes.WooCommerce,
},
];
const actionTypesWithDefaultTypeAny: Array<string> = [
WooCommerceActionTypes.PURCHASED_PRODUCT,
WooCommerceActionTypes.PURCHASED_CATEGORY,
];
import { store } from '../store/store';
import {
WooCommerceActionTypes,
actionTypesWithDefaultTypeAny,
} from './woocommerce_options';
export function validateWooCommerce(formItems: WooCommerceFormItem): boolean {
if (
@@ -121,31 +84,27 @@ export const WooCommerceFields: FunctionComponent<Props> = ({
filterIndex,
}) => {
const segment: WooCommerceFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } = useDispatch(
'mailpoet-dynamic-segments-form',
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } =
useDispatch(store);
const productCategories: WindowProductCategories = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getProductCategories(),
(select) => select(store).getProductCategories(),
[],
);
const woocommerceCountries: WindowWooCommerceCountries = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getWooCommerceCountries(),
(select) => select(store).getWooCommerceCountries(),
[],
);
const products: WindowProducts = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getProducts(),
(select) => select(store).getProducts(),
[],
);
const wooCurrencySymbol: string = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getWooCommerceCurrencySymbol(),
(select) => select(store).getWooCommerceCurrencySymbol(),
[],
);
const productOptions = products.map((product) => ({

View File

@@ -9,23 +9,12 @@ import { Grid } from 'common/grid';
import {
AnyValueTypes,
SegmentTypes,
SelectOption,
WindowMembershipPlans,
WooCommerceMembershipFormItem,
} from '../types';
enum WooCommerceMembershipsActionTypes {
MEMBER_OF = 'isMemberOf',
}
export const WooCommerceMembershipOptions = [
{
value: WooCommerceMembershipsActionTypes.MEMBER_OF,
label: MailPoet.I18n.t('segmentsActiveMembership'),
group: SegmentTypes.WooCommerceMembership,
},
];
import { store } from '../store/store';
import { WooCommerceMembershipsActionTypes } from './woocommerce_options';
export function validateWooCommerceMembership(
formItem: WooCommerceMembershipFormItem,
@@ -49,17 +38,15 @@ export function WooCommerceMembershipFields({
filterIndex,
}: Props): JSX.Element {
const segment: WooCommerceMembershipFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } = useDispatch(
'mailpoet-dynamic-segments-form',
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } =
useDispatch(store);
const membershipPlans: WindowMembershipPlans = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getMembershipPlans(),
(select) => select(store).getMembershipPlans(),
[],
);
const planOptions = membershipPlans.map((plan) => ({

View File

@@ -0,0 +1,70 @@
import { MailPoet } from 'mailpoet';
import { SegmentTypes } from 'segments/dynamic/types';
// WooCommerce
export enum WooCommerceActionTypes {
NUMBER_OF_ORDERS = 'numberOfOrders',
PURCHASED_CATEGORY = 'purchasedCategory',
PURCHASED_PRODUCT = 'purchasedProduct',
TOTAL_SPENT = 'totalSpent',
CUSTOMER_IN_COUNTRY = 'customerInCountry',
}
export const WooCommerceOptions = [
{
value: WooCommerceActionTypes.CUSTOMER_IN_COUNTRY,
label: MailPoet.I18n.t('wooCustomerInCountry'),
group: SegmentTypes.WooCommerce,
},
{
value: WooCommerceActionTypes.NUMBER_OF_ORDERS,
label: MailPoet.I18n.t('wooNumberOfOrders'),
group: SegmentTypes.WooCommerce,
},
{
value: WooCommerceActionTypes.PURCHASED_CATEGORY,
label: MailPoet.I18n.t('wooPurchasedCategory'),
group: SegmentTypes.WooCommerce,
},
{
value: WooCommerceActionTypes.PURCHASED_PRODUCT,
label: MailPoet.I18n.t('wooPurchasedProduct'),
group: SegmentTypes.WooCommerce,
},
{
value: WooCommerceActionTypes.TOTAL_SPENT,
label: MailPoet.I18n.t('wooTotalSpent'),
group: SegmentTypes.WooCommerce,
},
];
export const actionTypesWithDefaultTypeAny: Array<string> = [
WooCommerceActionTypes.PURCHASED_PRODUCT,
WooCommerceActionTypes.PURCHASED_CATEGORY,
];
// WooCommerce Memberships
export enum WooCommerceMembershipsActionTypes {
MEMBER_OF = 'isMemberOf',
}
export const WooCommerceMembershipOptions = [
{
value: WooCommerceMembershipsActionTypes.MEMBER_OF,
label: MailPoet.I18n.t('segmentsActiveMembership'),
group: SegmentTypes.WooCommerceMembership,
},
];
// WooCommerce Subscriptions
export enum WooCommerceSubscriptionsActionTypes {
ACTIVE_SUBSCRIPTIONS = 'hasActiveSubscription',
}
export const WooCommerceSubscriptionOptions = [
{
value: WooCommerceSubscriptionsActionTypes.ACTIVE_SUBSCRIPTIONS,
label: MailPoet.I18n.t('segmentsActiveSubscription'),
group: SegmentTypes.WooCommerceSubscription,
},
];

View File

@@ -9,23 +9,12 @@ import { Grid } from 'common/grid';
import {
AnyValueTypes,
SegmentTypes,
SelectOption,
WindowSubscriptionProducts,
WooCommerceSubscriptionFormItem,
} from '../types';
enum WooCommerceSubscriptionsActionTypes {
ACTIVE_SUBSCRIPTIONS = 'hasActiveSubscription',
}
export const WooCommerceSubscriptionOptions = [
{
value: WooCommerceSubscriptionsActionTypes.ACTIVE_SUBSCRIPTIONS,
label: MailPoet.I18n.t('segmentsActiveSubscription'),
group: SegmentTypes.WooCommerceSubscription,
},
];
import { store } from '../store/store';
import { WooCommerceSubscriptionsActionTypes } from './woocommerce_options';
export function validateWooCommerceSubscription(
formItem: WooCommerceSubscriptionFormItem,
@@ -50,18 +39,15 @@ export function WooCommerceSubscriptionFields({
filterIndex,
}: Props): JSX.Element {
const segment: WooCommerceSubscriptionFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } = useDispatch(
'mailpoet-dynamic-segments-form',
);
const { updateSegmentFilter, updateSegmentFilterFromEvent } =
useDispatch(store);
const subscriptionProducts: WindowSubscriptionProducts = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSubscriptionProducts(),
(select) => select(store).getSubscriptionProducts(),
[],
);
const productOptions = subscriptionProducts.map((product) => ({

View File

@@ -8,14 +8,14 @@ import { Heading } from 'common/typography/heading/heading';
import { HideScreenOptions } from 'common/hide_screen_options/hide_screen_options';
import { Form } from './form';
import { createStore } from './store/store';
import { createStore, store } from './store/store';
export function Editor(): JSX.Element {
const match = useRouteMatch<{ id: string }>();
createStore();
const { pageLoaded } = useDispatch('mailpoet-dynamic-segments-form');
const { pageLoaded } = useDispatch(store);
useEffect(() => {
void pageLoaded(match.params.id);

View File

@@ -4,18 +4,19 @@ import { useDispatch, useSelect } from '@wordpress/data';
import { Hooks } from 'wp-js-hooks';
import { MailPoet } from 'mailpoet';
import { Button } from 'common/button/button';
import { plusIcon } from 'common/button/icon/plus';
import { Heading } from 'common/typography/heading/heading';
import { Input } from 'common/form/input/input';
import { ReactSelect } from 'common/form/react_select/react_select';
import { Textarea } from 'common/form/textarea/textarea';
import { Grid } from 'common/grid';
import { APIErrorsNotice } from 'notices/api_errors_notice';
import { SubscribersCounter } from './subscribers_counter';
import { FormFilterFields } from './form_filter_fields';
import { isFormValid } from './validator';
import { plusIcon } from '../../common/button/icon/plus';
import { APIErrorsNotice } from '../../notices/api_errors_notice';
import { PrivacyProtectionNotice } from './privacy_protection_notice';
import { DynamicSegmentsPremiumBanner } from './premium_banner';
import { store } from './store/store';
import {
FilterRow,
@@ -44,36 +45,28 @@ const FilterAfter = Hooks.applyFilters(
export function Form({ segmentId }: Props): JSX.Element {
const segment: Segment = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getSegment(),
(select) => select(store).getSegment(),
[],
);
const segmentFilters: GroupFilterValue[] = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getAvailableFilters(),
(select) => select(store).getAvailableFilters(),
[],
);
const filterRows: FilterRow[] = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').findFiltersValueForSegment(
segment,
),
(select) => select(store).findFiltersValueForSegment(segment),
[segment],
);
const subscriberCount: SubscriberCount = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getSubscriberCount(),
(select) => select(store).getSubscriberCount(),
[],
);
const errors: string[] = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getErrors(),
[],
);
const errors: string[] = useSelect((select) => select(store).getErrors(), []);
const { updateSegment, updateSegmentFilter, handleSave } = useDispatch(
'mailpoet-dynamic-segments-form',
);
const { updateSegment, updateSegmentFilter, handleSave } = useDispatch(store);
const [premiumBannerVisible, setPremiumBannerVisible] = useState(false);
const showPremiumBanner = (): void => {

View File

@@ -7,6 +7,7 @@ import { SubscriberFields } from './dynamic_segments_filters/subscriber';
import { WooCommerceFields } from './dynamic_segments_filters/woocommerce';
import { WooCommerceMembershipFields } from './dynamic_segments_filters/woocommerce_membership';
import { WooCommerceSubscriptionFields } from './dynamic_segments_filters/woocommerce_subscription';
import { store } from './store/store';
const filterFieldsMap = {
[SegmentTypes.Email]: EmailFields,
@@ -22,8 +23,7 @@ type Props = {
export function FormFilterFields({ filterIndex }: Props): JSX.Element {
const filter: WordpressRoleFormItem = useSelect(
(select) =>
select('mailpoet-dynamic-segments-form').getSegmentFilter(filterIndex),
(select) => select(store).getSegmentFilter(filterIndex),
[filterIndex],
);

View File

@@ -2,10 +2,11 @@ import { MailPoet } from 'mailpoet';
import { useSelect } from '@wordpress/data';
import { EmailActionTypes, Segment } from './types';
import { store } from './store/store';
function PrivacyProtectionNotice(): JSX.Element {
const segment: Segment = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getSegment(),
(select) => select(store).getSegment(),
[],
);

View File

@@ -1,6 +1,10 @@
import { ChangeEvent } from 'react';
import { select } from '@wordpress/data';
import { MailPoet } from 'mailpoet';
import {
ReduxStoreConfig,
StoreDescriptor,
} from '@wordpress/data/build-types/types';
import {
Actions,
@@ -8,9 +12,16 @@ import {
SetSegmentActionType,
SetErrorsActionType,
SetSegmentFilerActionType,
StateType,
SubscriberCount,
SetSubscriberCountActionType,
} from '../types';
import * as selectors from './selectors';
// workaround to avoid import cycles
const store = { name: 'mailpoet-dynamic-segments-form' } as StoreDescriptor<
ReduxStoreConfig<StateType, null, typeof selectors>
>;
export function setSegment(segment: AnyFormItem): SetSegmentActionType {
return {
@@ -116,7 +127,7 @@ export function* handleSave(segmentId?: number): Generator<{
type: string;
segment?: AnyFormItem;
}> {
const segment = select('mailpoet-dynamic-segments-form').getSegment();
const segment = select(store).getSegment();
yield setErrors([]);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore -- I don't know how to configure typescript to understand this

View File

@@ -1,11 +1,13 @@
import { MailPoet } from 'mailpoet';
import { GroupFilterValue } from '../types';
import { EmailSegmentOptions } from '../dynamic_segments_filters/email';
import { SubscriberSegmentOptions } from '../dynamic_segments_filters/subscriber';
import { WooCommerceOptions } from '../dynamic_segments_filters/woocommerce';
import { WooCommerceMembershipOptions } from '../dynamic_segments_filters/woocommerce_membership';
import { WooCommerceSubscriptionOptions } from '../dynamic_segments_filters/woocommerce_subscription';
import { EmailSegmentOptions } from '../dynamic_segments_filters/email_options';
import { SubscriberSegmentOptions } from '../dynamic_segments_filters/subscriber_opitions';
import {
WooCommerceOptions,
WooCommerceMembershipOptions,
WooCommerceSubscriptionOptions,
} from '../dynamic_segments_filters/woocommerce_options';
export function getAvailableFilters(
canUseWooSubscriptions: boolean,

View File

@@ -0,0 +1,44 @@
import {
SegmentConnectTypes,
SegmentFormDataWindow,
SegmentTypes,
StateType,
SubscriberActionTypes,
} from 'segments/dynamic/types';
import { getAvailableFilters } from 'segments/dynamic/store/all_available_filters';
declare let window: SegmentFormDataWindow;
export const getInitialState = (): StateType => ({
products: window.mailpoet_products,
staticSegmentsList: window.mailpoet_static_segments_list,
membershipPlans: window.mailpoet_membership_plans,
subscriptionProducts: window.mailpoet_subscription_products,
productCategories: window.mailpoet_product_categories,
newslettersList: window.mailpoet_newsletters_list,
wordpressRoles: window.wordpress_editable_roles_list,
canUseWooMemberships: window.mailpoet_can_use_woocommerce_memberships,
canUseWooSubscriptions: window.mailpoet_can_use_woocommerce_subscriptions,
wooCurrencySymbol: window.mailpoet_woocommerce_currency_symbol,
wooCountries: window.mailpoet_woocommerce_countries,
customFieldsList: window.mailpoet_custom_fields,
tags: window.mailpoet_tags,
segment: {
filters_connect: SegmentConnectTypes.AND,
filters: [
{
segmentType: SegmentTypes.WordPressRole,
action: SubscriberActionTypes.WORDPRESS_ROLE,
},
],
},
subscriberCount: {
loading: false,
},
errors: [],
allAvailableFilters: getAvailableFilters(
window.mailpoet_can_use_woocommerce_subscriptions,
window.mailpoet_can_use_woocommerce_memberships,
),
});

View File

@@ -2,58 +2,16 @@
* The store is implemented using @wordpress/data module
* @see https://developer.wordpress.org/block-editor/packages/packages-data/
*/
import { registerStore } from '@wordpress/data';
import { createReduxStore, register } from '@wordpress/data';
import * as selectors from './selectors';
import { createReducer } from './reducer';
import * as actions from './actions';
import * as controls from './controls';
import { getInitialState } from './initial_state';
import {
StateType,
SegmentFormDataWindow,
SegmentTypes,
SegmentConnectTypes,
SubscriberActionTypes,
} from '../types';
import { getAvailableFilters } from './all_available_filters';
declare let window: SegmentFormDataWindow;
const STORE = 'mailpoet-dynamic-segments-form';
export const createStore = (): void => {
const defaultState: StateType = {
products: window.mailpoet_products,
staticSegmentsList: window.mailpoet_static_segments_list,
membershipPlans: window.mailpoet_membership_plans,
subscriptionProducts: window.mailpoet_subscription_products,
productCategories: window.mailpoet_product_categories,
newslettersList: window.mailpoet_newsletters_list,
wordpressRoles: window.wordpress_editable_roles_list,
canUseWooMemberships: window.mailpoet_can_use_woocommerce_memberships,
canUseWooSubscriptions: window.mailpoet_can_use_woocommerce_subscriptions,
wooCurrencySymbol: window.mailpoet_woocommerce_currency_symbol,
wooCountries: window.mailpoet_woocommerce_countries,
customFieldsList: window.mailpoet_custom_fields,
tags: window.mailpoet_tags,
segment: {
filters_connect: SegmentConnectTypes.AND,
filters: [
{
segmentType: SegmentTypes.WordPressRole,
action: SubscriberActionTypes.WORDPRESS_ROLE,
},
],
},
subscriberCount: {
loading: false,
},
errors: [],
allAvailableFilters: getAvailableFilters(
window.mailpoet_can_use_woocommerce_subscriptions,
window.mailpoet_can_use_woocommerce_memberships,
),
};
const storeName = 'mailpoet-dynamic-segments-form';
export const createStore = () => {
const defaultState = getInitialState();
const config = {
selectors,
actions,
@@ -62,5 +20,12 @@ export const createStore = (): void => {
resolvers: {},
};
registerStore(STORE, config);
const store = createReduxStore(storeName, config);
register(store);
return store;
};
export const store: ReturnType<typeof createStore> = {
name: storeName,
instantiate: (registry) => createStore().instantiate(registry),
};

View File

@@ -6,21 +6,20 @@ import { isFormValid } from './validator';
import { loadCount } from './subscribers_calculator';
import { Segment, SubscriberCount } from './types';
import { store } from './store/store';
function SubscribersCounter(): JSX.Element {
const segment: Segment = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getSegment(),
(select) => select(store).getSegment(),
[],
);
const subscribersCount: SubscriberCount = useSelect(
(select) => select('mailpoet-dynamic-segments-form').getSubscriberCount(),
(select) => select(store).getSubscriberCount(),
[],
);
const { updateSubscriberCount } = useDispatch(
'mailpoet-dynamic-segments-form',
);
const { updateSubscriberCount } = useDispatch(store);
const serializedSegment = JSON.stringify(segment);
const latestRequestIdRef = useRef(1);