Add engagement score into segment list
[MAILPOET-3533]
This commit is contained in:
@ -5,10 +5,12 @@ import classNames from 'classnames';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import Listing from 'listing/listing.jsx';
|
import Listing from 'listing/listing.jsx';
|
||||||
|
import { ListingsEngagementScore } from '../subscribers/listings_engagement_score';
|
||||||
|
|
||||||
const isWPUsersSegment = (segment) => segment.type === 'wp_users';
|
const isWPUsersSegment = (segment) => segment.type === 'wp_users';
|
||||||
const isWooCommerceCustomersSegment = (segment) => segment.type === 'woocommerce_users';
|
const isWooCommerceCustomersSegment = (segment) => segment.type === 'woocommerce_users';
|
||||||
const isSpecialSegment = (segmt) => isWPUsersSegment(segmt) || isWooCommerceCustomersSegment(segmt);
|
const isSpecialSegment = (segmt) => isWPUsersSegment(segmt) || isWooCommerceCustomersSegment(segmt);
|
||||||
|
const mailpoetTrackingEnabled = (!!(window.mailpoet_tracking_enabled));
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
@ -20,6 +22,11 @@ const columns = [
|
|||||||
name: 'description',
|
name: 'description',
|
||||||
label: MailPoet.I18n.t('description'),
|
label: MailPoet.I18n.t('description'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'average_subscriber_score',
|
||||||
|
label: MailPoet.I18n.t('averageScore'),
|
||||||
|
display: mailpoetTrackingEnabled,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'subscribed',
|
name: 'subscribed',
|
||||||
label: MailPoet.I18n.t('subscribed'),
|
label: MailPoet.I18n.t('subscribed'),
|
||||||
@ -263,6 +270,16 @@ class SegmentList extends React.Component {
|
|||||||
<td data-colname={MailPoet.I18n.t('description')}>
|
<td data-colname={MailPoet.I18n.t('description')}>
|
||||||
<abbr>{ segment.description }</abbr>
|
<abbr>{ segment.description }</abbr>
|
||||||
</td>
|
</td>
|
||||||
|
{ (mailpoetTrackingEnabled === true) ? (
|
||||||
|
<td className="column mailpoet-listing-stats-column" data-colname={MailPoet.I18n.t('averageScore')}>
|
||||||
|
<div className="mailpoet-listing-stats">
|
||||||
|
<ListingsEngagementScore
|
||||||
|
id={segment.id}
|
||||||
|
engagementScore={segment.average_engagement_score}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
) : null }
|
||||||
<td className="mailpoet-hide-on-mobile" data-colname={MailPoet.I18n.t('subscribed')}>
|
<td className="mailpoet-hide-on-mobile" data-colname={MailPoet.I18n.t('subscribed')}>
|
||||||
<abbr>{ subscribed.toLocaleString() }</abbr>
|
<abbr>{ subscribed.toLocaleString() }</abbr>
|
||||||
</td>
|
</td>
|
||||||
|
@ -32,6 +32,7 @@ class SegmentsResponseBuilder {
|
|||||||
'created_at' => $segment->getCreatedAt()->format(self::DATE_FORMAT),
|
'created_at' => $segment->getCreatedAt()->format(self::DATE_FORMAT),
|
||||||
'updated_at' => $segment->getUpdatedAt()->format(self::DATE_FORMAT),
|
'updated_at' => $segment->getUpdatedAt()->format(self::DATE_FORMAT),
|
||||||
'deleted_at' => ($deletedAt = $segment->getDeletedAt()) ? $deletedAt->format(self::DATE_FORMAT) : null,
|
'deleted_at' => ($deletedAt = $segment->getDeletedAt()) ? $deletedAt->format(self::DATE_FORMAT) : null,
|
||||||
|
'average_engagement_score' => $segment->getAverageEngagementScore(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ use MailPoet\Listing\PageLimit;
|
|||||||
use MailPoet\Models\Newsletter;
|
use MailPoet\Models\Newsletter;
|
||||||
use MailPoet\Segments\SegmentDependencyValidator;
|
use MailPoet\Segments\SegmentDependencyValidator;
|
||||||
use MailPoet\Services\Bridge;
|
use MailPoet\Services\Bridge;
|
||||||
|
use MailPoet\Settings\SettingsController;
|
||||||
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
|
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
|
||||||
use MailPoet\WooCommerce\Helper as WooCommerceHelper;
|
use MailPoet\WooCommerce\Helper as WooCommerceHelper;
|
||||||
use MailPoet\WP\AutocompletePostListLoader as WPPostListLoader;
|
use MailPoet\WP\AutocompletePostListLoader as WPPostListLoader;
|
||||||
@ -36,6 +37,9 @@ class Segments {
|
|||||||
/** @var WPPostListLoader */
|
/** @var WPPostListLoader */
|
||||||
private $wpPostListLoader;
|
private $wpPostListLoader;
|
||||||
|
|
||||||
|
/** @var SettingsController */
|
||||||
|
private $settings;
|
||||||
|
|
||||||
/** @var SegmentDependencyValidator */
|
/** @var SegmentDependencyValidator */
|
||||||
private $segmentDependencyValidator;
|
private $segmentDependencyValidator;
|
||||||
|
|
||||||
@ -47,6 +51,7 @@ class Segments {
|
|||||||
WooCommerceHelper $woocommerceHelper,
|
WooCommerceHelper $woocommerceHelper,
|
||||||
WPPostListLoader $wpPostListLoader,
|
WPPostListLoader $wpPostListLoader,
|
||||||
SubscribersFeature $subscribersFeature,
|
SubscribersFeature $subscribersFeature,
|
||||||
|
SettingsController $settings,
|
||||||
SegmentDependencyValidator $segmentDependencyValidator
|
SegmentDependencyValidator $segmentDependencyValidator
|
||||||
) {
|
) {
|
||||||
$this->pageRenderer = $pageRenderer;
|
$this->pageRenderer = $pageRenderer;
|
||||||
@ -56,6 +61,7 @@ class Segments {
|
|||||||
$this->wp = $wp;
|
$this->wp = $wp;
|
||||||
$this->woocommerceHelper = $woocommerceHelper;
|
$this->woocommerceHelper = $woocommerceHelper;
|
||||||
$this->wpPostListLoader = $wpPostListLoader;
|
$this->wpPostListLoader = $wpPostListLoader;
|
||||||
|
$this->settings = $settings;
|
||||||
$this->segmentDependencyValidator = $segmentDependencyValidator;
|
$this->segmentDependencyValidator = $segmentDependencyValidator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +108,7 @@ class Segments {
|
|||||||
);
|
);
|
||||||
$wooCurrencySymbol = $this->woocommerceHelper->isWooCommerceActive() ? $this->woocommerceHelper->getWoocommerceCurrencySymbol() : '';
|
$wooCurrencySymbol = $this->woocommerceHelper->isWooCommerceActive() ? $this->woocommerceHelper->getWoocommerceCurrencySymbol() : '';
|
||||||
$data['woocommerce_currency_symbol'] = html_entity_decode($wooCurrencySymbol);
|
$data['woocommerce_currency_symbol'] = html_entity_decode($wooCurrencySymbol);
|
||||||
|
$data['tracking_enabled'] = $this->settings->get('tracking.enabled');
|
||||||
|
|
||||||
$this->pageRenderer->displayPage('segments.html', $data);
|
$this->pageRenderer->displayPage('segments.html', $data);
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,18 @@ class SegmentEntity {
|
|||||||
*/
|
*/
|
||||||
private $dynamicFilters;
|
private $dynamicFilters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="float", nullable=true)
|
||||||
|
* @var float|null
|
||||||
|
*/
|
||||||
|
private $averageEngagementScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="datetimetz", nullable=true)
|
||||||
|
* @var \DateTimeInterface|null
|
||||||
|
*/
|
||||||
|
private $averageEngagementScoreUpdatedAt;
|
||||||
|
|
||||||
public function __construct(string $name, string $type, string $description) {
|
public function __construct(string $name, string $type, string $description) {
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
@ -122,4 +134,20 @@ class SegmentEntity {
|
|||||||
public function isStatic(): bool {
|
public function isStatic(): bool {
|
||||||
return in_array($this->getType(), [self::TYPE_DEFAULT, self::TYPE_WP_USERS, self::TYPE_WC_USERS], true);
|
return in_array($this->getType(), [self::TYPE_DEFAULT, self::TYPE_WP_USERS, self::TYPE_WC_USERS], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getAverageEngagementScore(): ?float {
|
||||||
|
return $this->averageEngagementScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setAverageEngagementScore(?float $averageEngagementScore): void {
|
||||||
|
$this->averageEngagementScore = $averageEngagementScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAverageEngagementScoreUpdatedAt(): ?\DateTimeInterface {
|
||||||
|
return $this->averageEngagementScoreUpdatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setAverageEngagementScoreUpdatedAt(?\DateTimeInterface $averageEngagementScoreUpdatedAt): void {
|
||||||
|
$this->averageEngagementScoreUpdatedAt = $averageEngagementScoreUpdatedAt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ class SegmentListingRepository extends ListingRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function applySelectClause(QueryBuilder $queryBuilder) {
|
protected function applySelectClause(QueryBuilder $queryBuilder) {
|
||||||
$queryBuilder->select("PARTIAL s.{id,name,type,description,createdAt,updatedAt,deletedAt}");
|
$queryBuilder->select("PARTIAL s.{id,name,type,description,createdAt,updatedAt,deletedAt,averageEngagementScore}");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function applyFromClause(QueryBuilder $queryBuilder) {
|
protected function applyFromClause(QueryBuilder $queryBuilder) {
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
var mailpoet_can_use_woocommerce_subscriptions = <%= json_encode(can_use_woocommerce_subscriptions) %>;
|
var mailpoet_can_use_woocommerce_subscriptions = <%= json_encode(can_use_woocommerce_subscriptions) %>;
|
||||||
var mailpoet_woocommerce_currency_symbol = <%= json_encode(woocommerce_currency_symbol) %>;
|
var mailpoet_woocommerce_currency_symbol = <%= json_encode(woocommerce_currency_symbol) %>;
|
||||||
var mailpoet_woocommerce_countries = <%= json_encode(woocommerce_countries) %>;
|
var mailpoet_woocommerce_countries = <%= json_encode(woocommerce_countries) %>;
|
||||||
|
var mailpoet_tracking_enabled = <%= json_encode(tracking_enabled) %>;
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<% endblock %>
|
<% endblock %>
|
||||||
@ -85,6 +86,7 @@
|
|||||||
'save': __('Save'),
|
'save': __('Save'),
|
||||||
'trashAndDisable': __('Trash and disable'),
|
'trashAndDisable': __('Trash and disable'),
|
||||||
'restoreAndEnable': __('Restore and enable'),
|
'restoreAndEnable': __('Restore and enable'),
|
||||||
|
'averageScore': __('Average Score'),
|
||||||
|
|
||||||
'previousPage': __('Previous page'),
|
'previousPage': __('Previous page'),
|
||||||
'firstPage': __('First page'),
|
'firstPage': __('First page'),
|
||||||
@ -195,5 +197,18 @@
|
|||||||
'dynamicSegmentSizeIsCalculated': __('Calculating segment size…'),
|
'dynamicSegmentSizeIsCalculated': __('Calculating segment size…'),
|
||||||
'dynamicSegmentSizeCalculatingTimeout': __('Segment size calculation has timed out. You can still save the segment.'),
|
'dynamicSegmentSizeCalculatingTimeout': __('Segment size calculation has timed out. You can still save the segment.'),
|
||||||
'dynamicSegmentSize': __('This segment has %$1d subscribers.'),
|
'dynamicSegmentSize': __('This segment has %$1d subscribers.'),
|
||||||
|
|
||||||
|
'unknownBadgeName': __('Unknown'),
|
||||||
|
'unknownBadgeTooltip': __('Not enough data.'),
|
||||||
|
'tooltipUnknown': __('Fewer than 3 emails sent'),
|
||||||
|
'excellentBadgeName': __('Excellent'),
|
||||||
|
'excellentBadgeTooltip': __('Congrats!'),
|
||||||
|
'tooltipExcellent': __('Above 50%'),
|
||||||
|
'goodBadgeName': __('Good'),
|
||||||
|
'goodBadgeTooltip': __('Good stuff.'),
|
||||||
|
'tooltipGood': __('between 20 and 50%'),
|
||||||
|
'averageBadgeName': __('Low'),
|
||||||
|
'averageBadgeTooltip': __('Something to improve.'),
|
||||||
|
'tooltipAverage': __('between 0 and 20%'),
|
||||||
}) %>
|
}) %>
|
||||||
<% endblock %>
|
<% endblock %>
|
||||||
|
Reference in New Issue
Block a user