Apply prettier

This commit is contained in:
David Remer
2023-06-19 08:20:55 +03:00
committed by Aschepikov
parent c03a3becc4
commit 8b1d51fcd6
7 changed files with 305 additions and 184 deletions

View File

@@ -8,7 +8,7 @@ import { select, useSelect } from '@wordpress/data';
import { MailPoet } from '../../../../../../mailpoet'; import { MailPoet } from '../../../../../../mailpoet';
import { OverviewSection, storeName } from '../../store'; import { OverviewSection, storeName } from '../../store';
import { locale } from '../../../../../config'; import { locale } from '../../../../../config';
import {formattedPrice} from "../../formatter"; import { formattedPrice } from '../../formatter';
function getEmailPercentage( function getEmailPercentage(
type: 'opened' | 'clicked', type: 'opened' | 'clicked',
@@ -120,7 +120,9 @@ export function Overview(): JSX.Element | null {
key="overview-revenue" key="overview-revenue"
label={__('Revenue', 'mailpoet')} label={__('Revenue', 'mailpoet')}
delta={getWooCommerceDelta('revenue').toFixed(2) as unknown as number} delta={getWooCommerceDelta('revenue').toFixed(2) as unknown as number}
value={formattedPrice(overview.data !== undefined ? overview.data.revenue.current : 0)} value={formattedPrice(
overview.data !== undefined ? overview.data.revenue.current : 0,
)}
/>, />,
); );
} }

View File

@@ -1,23 +1,37 @@
type CellProps = { type CellProps = {
value: number | string | JSX.Element value: number | string | JSX.Element;
subValue?: number | string; subValue?: number | string;
badge?: string; badge?: string;
badgeType?: string; badgeType?: string;
className?: string; className?: string;
} };
export function Cell({value, subValue, badge, badgeType, className}: CellProps): JSX.Element { export function Cell({
value,
const badgeElement = badge ? <span className="mailpoet-analytics-badge">{badge}</span> : null subValue,
const mainElement = <div className={`mailpoet-analytics-main-value ${className??''} ${badgeType??''}`}> badge,
badgeType,
className,
}: CellProps): JSX.Element {
const badgeElement = badge ? (
<span className="mailpoet-analytics-badge">{badge}</span>
) : null;
const mainElement = (
<div
className={`mailpoet-analytics-main-value ${className ?? ''} ${
badgeType ?? ''
}`}
>
{badgeElement} {badgeElement}
{value} {value}
</div> </div>
);
return ( return (
<div className="mailpoet-automation-analytics-emails-table-cell"> <div className="mailpoet-automation-analytics-emails-table-cell">
{mainElement} {mainElement}
<p className="mailpoet-automation-analytics-table-subvalue">{subValue}&nbsp;</p> <p className="mailpoet-automation-analytics-table-subvalue">
{subValue}&nbsp;
</p>
</div> </div>
) );
} }

View File

@@ -1,10 +1,10 @@
import {TableCard} from "@woocommerce/components/build"; import { useEffect, useState } from 'react';
import {useSelect} from "@wordpress/data"; import { TableCard } from '@woocommerce/components/build';
import {EmailStats, OverviewSection, storeName} from "../../../store"; import { useSelect } from '@wordpress/data';
import {__} from "@wordpress/i18n"; import { __ } from '@wordpress/i18n';
import {useEffect, useState} from "react"; import { calculateSummary } from './summary';
import {calculateSummary} from "./summary"; import { transformEmailsToRows } from './rows';
import {transformEmailsToRows} from "./rows"; import { EmailStats, OverviewSection, storeName } from '../../../store';
const headers = [ const headers = [
{ {
@@ -15,41 +15,41 @@ const headers = [
key: 'sent', key: 'sent',
label: __('Sent', 'mailpoet'), label: __('Sent', 'mailpoet'),
isLeftAligned: false, isLeftAligned: false,
isNumeric: true isNumeric: true,
}, },
{ {
key: 'opened', key: 'opened',
label: __('Opened', 'mailpoet'), label: __('Opened', 'mailpoet'),
isLeftAligned: false, isLeftAligned: false,
isNumeric: true isNumeric: true,
}, },
{ {
key: 'clicked', key: 'clicked',
label: __('Clicked', 'mailpoet'), label: __('Clicked', 'mailpoet'),
isLeftAligned: false, isLeftAligned: false,
isNumeric: true isNumeric: true,
}, },
{ {
key: 'orders', key: 'orders',
label: __('Orders', 'mailpoet'), label: __('Orders', 'mailpoet'),
isLeftAligned: false, isLeftAligned: false,
isNumeric: true isNumeric: true,
}, },
{ {
key: 'revenue', key: 'revenue',
label: __('Revenue', 'mailpoet'), label: __('Revenue', 'mailpoet'),
isLeftAligned: false, isLeftAligned: false,
isNumeric: true isNumeric: true,
}, },
{ {
key: 'unsubscribed', key: 'unsubscribed',
label: __('Unsubscribed', 'mailpoet'), label: __('Unsubscribed', 'mailpoet'),
isLeftAligned: false, isLeftAligned: false,
isNumeric: true isNumeric: true,
}, },
{ {
key: 'actions', key: 'actions',
label: '' label: '',
}, },
]; ];
@@ -58,41 +58,64 @@ export function Emails(): JSX.Element {
overview: s(storeName).getSection('overview'), overview: s(storeName).getSection('overview'),
})) as { overview: OverviewSection }; })) as { overview: OverviewSection };
const [visibleEmails, setVisibleEmails] = useState<EmailStats[] | undefined>(undefined); const [visibleEmails, setVisibleEmails] = useState<EmailStats[] | undefined>(
undefined,
);
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const [rowsPerPage, setRowsPerPage] = useState(5); const [rowsPerPage, setRowsPerPage] = useState(25);
//const [rowsPerPage, setRowsPerPage] = useState(25); useEffect(() => {
useEffect( setVisibleEmails(
() => { overview.data !== undefined
setVisibleEmails(overview.data !== undefined ? Object.values(overview.data.emails).splice((currentPage-1)*rowsPerPage, rowsPerPage): undefined) ? Object.values(overview.data.emails).splice(
}, [overview.data] (currentPage - 1) * rowsPerPage,
rowsPerPage,
) )
: undefined,
);
}, [overview.data, currentPage, rowsPerPage]);
const rows = visibleEmails !== undefined ? transformEmailsToRows(visibleEmails) : []; const rows =
visibleEmails !== undefined ? transformEmailsToRows(visibleEmails) : [];
const summary = calculateSummary(visibleEmails ?? []); const summary = calculateSummary(visibleEmails ?? []);
return <TableCard return (
<TableCard
title="" title=""
caption="" caption=""
onQueryChange={ (type:string) => (param) => { onQueryChange={(type: string) => (param: number) => {
if (type === 'paged') { if (type === 'paged') {
setCurrentPage(param); setCurrentPage(param);
setVisibleEmails(overview.data !== undefined ? Object.values(overview.data.emails).splice((param-1)*rowsPerPage, rowsPerPage): undefined) setVisibleEmails(
overview.data !== undefined
? Object.values(overview.data.emails).splice(
(param - 1) * rowsPerPage,
rowsPerPage,
)
: undefined,
);
} else if (type === 'per_page') { } else if (type === 'per_page') {
setCurrentPage(1); setCurrentPage(1);
setRowsPerPage(param); setRowsPerPage(param);
setVisibleEmails(overview.data !== undefined ? Object.values(overview.data.emails).splice(0, param): undefined) setVisibleEmails(
} overview.data !== undefined
} ? Object.values(overview.data.emails).splice(0, param)
: undefined,
);
} }
}}
query={{ paged: currentPage, sort: { key: 'email', direction: 'asc' } }} query={{ paged: currentPage, sort: { key: 'email', direction: 'asc' } }}
rows={rows} rows={rows}
headers={headers} headers={headers}
showMenu={false} showMenu={false}
rowsPerPage={rowsPerPage} rowsPerPage={rowsPerPage}
onRowClick={() => {}} onRowClick={() => {}}
totalRows={ overview.data !== undefined ? Object.values(overview.data.emails).length : 0 } totalRows={
overview.data !== undefined
? Object.values(overview.data.emails).length
: 0
}
summary={summary} summary={summary}
isLoading={overview.data === undefined} isLoading={overview.data === undefined}
/> />
);
} }

View File

@@ -1,118 +1,170 @@
import {Tooltip} from "@wordpress/components"; import { Tooltip } from '@wordpress/components';
import {__, sprintf} from "@wordpress/i18n"; import { __, sprintf } from '@wordpress/i18n';
import {EmailStats} from "../../../store"; import { EmailStats } from '../../../store';
import {Actions} from "./actions"; import { Actions } from './actions';
import {locale} from "../../../../../../config"; import { locale } from '../../../../../../config';
import {Cell} from "./cell"; import { Cell } from './cell';
import {formattedPrice} from "../../../formatter"; import { formattedPrice } from '../../../formatter';
const percentageFormatter = Intl.NumberFormat(locale.toString(), { style: 'percent', maximumFractionDigits: 2 }); const percentageFormatter = Intl.NumberFormat(locale.toString(), {
style: 'percent',
maximumFractionDigits: 2,
});
function calculatePercentage(value: number, base: number, canBeNegative = false) : number { function calculatePercentage(
value: number,
base: number,
canBeNegative = false,
): number {
if (base === 0) { if (base === 0) {
return 0; return 0;
} }
const percentage = (value * 100) / base; const percentage = (value * 100) / base;
return (canBeNegative) ? percentage - 100 : percentage; return canBeNegative ? percentage - 100 : percentage;
} }
function percentageBadgeCalculation(percentage:number) : {badge: string, badgeType: string} { function percentageBadgeCalculation(percentage: number): {
badge: string;
badgeType: string;
} {
if (percentage > 3) { if (percentage > 3) {
return {badge: __('Excellent', 'mailpoet'), badgeType: 'mailpoet-analytics-badge-success'} return {
badge: __('Excellent', 'mailpoet'),
badgeType: 'mailpoet-analytics-badge-success',
};
} }
if (percentage > 1) { if (percentage > 1) {
return {badge: __('Good', 'mailpoet'), badgeType: 'mailpoet-analytics-badge-success'} return {
badge: __('Good', 'mailpoet'),
badgeType: 'mailpoet-analytics-badge-success',
};
} }
return {badge: __('Average', 'mailpoet'), badgeType: 'mailpoet-analytics-badge-warning'} return {
badge: __('Average', 'mailpoet'),
badgeType: 'mailpoet-analytics-badge-warning',
};
} }
export function transformEmailsToRows(emails: EmailStats[]) { export function transformEmailsToRows(emails: EmailStats[]) {
const openOrders = () => { const openOrders = () => {
const tab: HTMLButtonElement | null = document.querySelector('.mailpoet-analytics-tab-orders'); const tab: HTMLButtonElement | null = document.querySelector(
'.mailpoet-analytics-tab-orders',
);
tab?.click(); tab?.click();
} };
return emails.map((email) => { return emails.map((email) => {
// Shows the percentage of clicked emails compared to the number of sent emails // Shows the percentage of clicked emails compared to the number of sent emails
const clickedPercentage = calculatePercentage(email.clicked.current, email.sent.current); const clickedPercentage = calculatePercentage(
email.clicked.current,
email.sent.current,
);
const clickedBadge = percentageBadgeCalculation(clickedPercentage); const clickedBadge = percentageBadgeCalculation(clickedPercentage);
return [ return [
{ {
display: <Cell display: (
className='mailpoet-automation-analytics-email-name' <Cell
className="mailpoet-automation-analytics-email-name"
value={email.name} value={email.name}
// translator: %d is the order number of the email, first email, second email, etc. // translator: %d is the order number of the email, first email, second email, etc.
subValue={sprintf(__('Email %d', 'mailpoet'), email.order)} subValue={sprintf(__('Email %d', 'mailpoet'), email.order)}
/>, />
value: email.name ),
value: email.name,
}, },
{ {
display: <Cell display: (
value={<Tooltip text={__('View sending status', 'mailpoet')}><a href={`?page=mailpoet-newsletters#/sending-status/${email.id}`}>{email.sent.current}</a></Tooltip>} <Cell
value={
<Tooltip text={__('View sending status', 'mailpoet')}>
<a
href={`?page=mailpoet-newsletters#/sending-status/${email.id}`}
>
{email.sent.current}
</a>
</Tooltip>
}
subValue={ subValue={
// Shows the percentage of sent emails compared to the previous email // Shows the percentage of sent emails compared to the previous email
percentageFormatter.format(calculatePercentage(email.sent.current, email.sent.previous, true)/100) percentageFormatter.format(
calculatePercentage(
email.sent.current,
email.sent.previous,
true,
) / 100,
)
} }
/>, />
value: email.sent.current ),
value: email.sent.current,
}, },
{ {
display: <Cell display: (
<Cell
value={email.opened.current} value={email.opened.current}
subValue={ subValue={
// Shows the percentage of opened emails compared to the number of sent emails // Shows the percentage of opened emails compared to the number of sent emails
percentageFormatter.format(calculatePercentage(email.opened.current, email.sent.current)/100) percentageFormatter.format(
calculatePercentage(email.opened.current, email.sent.current) /
100,
)
} }
/>, />
value: email.opened.current ),
value: email.opened.current,
}, },
{ {
display: <Cell display: (
<Cell
value={email.clicked.current} value={email.clicked.current}
className={ email.sent.current > 0 ? 'mailpoet-automation-analytics-email-clicked' : '' } className={
email.sent.current > 0
? 'mailpoet-automation-analytics-email-clicked'
: ''
}
subValue={percentageFormatter.format(clickedPercentage / 100)} subValue={percentageFormatter.format(clickedPercentage / 100)}
badge={email.sent.current > 0 ? clickedBadge.badge : undefined} badge={email.sent.current > 0 ? clickedBadge.badge : undefined}
badgeType={email.sent.current > 0 ? clickedBadge.badgeType : undefined} badgeType={
/>, email.sent.current > 0 ? clickedBadge.badgeType : undefined
value: email.clicked.current }
/>
),
value: email.clicked.current,
}, },
{ {
display: <Cell display: (
<Cell
value={ value={
<Tooltip text={__('View orders', 'mailpoet')}> <Tooltip text={__('View orders', 'mailpoet')}>
<a href="#" onClick={ <a
(e) => { href="#"
onClick={(e) => {
e.preventDefault(); e.preventDefault();
openOrders() openOrders();
} }}
}>{ >
email.orders.current {email.orders.current}
}
</a> </a>
</Tooltip>} </Tooltip>
/>, }
value: email.orders.current />
),
value: email.orders.current,
}, },
{ {
display: <Cell display: <Cell value={formattedPrice(email.revenue.current)} />,
value={formattedPrice(email.revenue.current)} value: email.revenue.current,
/>,
value: email.revenue.current
}, },
{ {
display: <Cell display: <Cell value={email.unsubscribed.current} />,
value={email.unsubscribed.current} value: email.unsubscribed.current,
/>,
value: email.unsubscribed.current
}, },
{ {
display: <Actions id={email.id} previewUrl={email.previewUrl} />, display: <Actions id={email.id} previewUrl={email.previewUrl} />,
value: null value: null,
}, },
] ];
}) });
} }

View File

@@ -1,13 +1,14 @@
import {__} from "@wordpress/i18n"; import { __ } from '@wordpress/i18n';
import {locale} from "../../../../../../config"; import { locale } from '../../../../../../config';
import {EmailStats} from "../../../store"; import { EmailStats } from '../../../store';
import {formattedPrice} from "../../../formatter"; import { formattedPrice } from '../../../formatter';
export function calculateSummary(rows: EmailStats[]) { export function calculateSummary(rows: EmailStats[]) {
if (rows.length === 0) { if (rows.length === 0) {
return []; return [];
} }
const data = rows.reduce((acc, row) => { const data = rows.reduce(
(acc, row) => {
acc.sent += row.sent.current; acc.sent += row.sent.current;
acc.opened += row.opened.current; acc.opened += row.opened.current;
acc.clicked += row.clicked.current; acc.clicked += row.clicked.current;
@@ -15,22 +16,49 @@ export function calculateSummary(rows:EmailStats[]) {
acc.unsubscribed += row.unsubscribed.current; acc.unsubscribed += row.unsubscribed.current;
acc.revenue += row.revenue.current; acc.revenue += row.revenue.current;
return acc; return acc;
}, { },
{
sent: 0, sent: 0,
opened: 0, opened: 0,
clicked: 0, clicked: 0,
orders: 0, orders: 0,
unsubscribed: 0, unsubscribed: 0,
revenue: 0, revenue: 0,
}); },
);
const summary = [ const summary = [
{ label: __('sent', 'mailpoet'), value: Intl.NumberFormat(locale.toString(), { notation: 'compact' }).format(data.sent) }, {
{ label: __('opened', 'mailpoet'), value: Intl.NumberFormat(locale.toString(), { notation: 'compact' }).format(data.opened) }, label: __('sent', 'mailpoet'),
{ label: __('clicked', 'mailpoet'), value: Intl.NumberFormat(locale.toString(), { notation: 'compact' }).format(data.clicked) }, value: Intl.NumberFormat(locale.toString(), {
{ label: __('orders', 'mailpoet'), value: Intl.NumberFormat(locale.toString(), { notation: 'compact' }).format(data.orders) }, notation: 'compact',
}).format(data.sent),
},
{
label: __('opened', 'mailpoet'),
value: Intl.NumberFormat(locale.toString(), {
notation: 'compact',
}).format(data.opened),
},
{
label: __('clicked', 'mailpoet'),
value: Intl.NumberFormat(locale.toString(), {
notation: 'compact',
}).format(data.clicked),
},
{
label: __('orders', 'mailpoet'),
value: Intl.NumberFormat(locale.toString(), {
notation: 'compact',
}).format(data.orders),
},
{ label: __('revenue', 'mailpoet'), value: formattedPrice(data.revenue) }, { label: __('revenue', 'mailpoet'), value: formattedPrice(data.revenue) },
{ label: __('unsubscribed', 'mailpoet'), value: Intl.NumberFormat(locale.toString(), { notation: 'compact' }).format(data.unsubscribed) }, {
label: __('unsubscribed', 'mailpoet'),
value: Intl.NumberFormat(locale.toString(), {
notation: 'compact',
}).format(data.unsubscribed),
},
]; ];
return summary; return summary;

View File

@@ -1,5 +1,5 @@
import CurrencyFactory from "@woocommerce/currency/build"; import CurrencyFactory from '@woocommerce/currency/build';
import {MailPoet} from "../../../../../mailpoet"; import { MailPoet } from '../../../../../mailpoet';
export function formattedPrice(price: number): string { export function formattedPrice(price: number): string {
const storeCurrency = CurrencyFactory(MailPoet.WooCommerceStoreConfig); const storeCurrency = CurrencyFactory(MailPoet.WooCommerceStoreConfig);

View File

@@ -82,7 +82,8 @@ declare module '@woocommerce/blocks-checkout' {
function registerCheckoutBlock(options: CheckoutBlockOptions): void; function registerCheckoutBlock(options: CheckoutBlockOptions): void;
} }
type WooCommerceStoreConfig = { type WooCommerceStoreConfig =
| {
precision: number | string | null; precision: number | string | null;
decimalSeparator: string; decimalSeparator: string;
thousandSeparator: string; thousandSeparator: string;
@@ -90,7 +91,8 @@ type WooCommerceStoreConfig = {
symbol: string; symbol: string;
symbolPosition: 'left' | 'right' | 'left_space' | 'right_space'; symbolPosition: 'left' | 'right' | 'left_space' | 'right_space';
priceFormat?: string; priceFormat?: string;
} | undefined }
| undefined;
interface Window { interface Window {
ajaxurl: string; ajaxurl: string;