Add sending queue status to help page
[MAILPOET-1459]
This commit is contained in:
@ -13,7 +13,7 @@ function renderStatusTableRow(title, value) {
|
|||||||
const CronStatus = (props) => {
|
const CronStatus = (props) => {
|
||||||
const status = props.status_data;
|
const status = props.status_data;
|
||||||
const activeStatusMapping = {
|
const activeStatusMapping = {
|
||||||
active: MailPoet.I18n.t('cronRunning'),
|
active: MailPoet.I18n.t('running'),
|
||||||
inactive: MailPoet.I18n.t('cronWaiting'),
|
inactive: MailPoet.I18n.t('cronWaiting'),
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
@ -41,7 +41,7 @@ const CronStatus = (props) => {
|
|||||||
MailPoet.I18n.t('lastRunCompleted'),
|
MailPoet.I18n.t('lastRunCompleted'),
|
||||||
status.run_completed_at ? MailPoet.Date.full(status.run_completed_at * 1000) : MailPoet.I18n.t('unknown'))
|
status.run_completed_at ? MailPoet.Date.full(status.run_completed_at * 1000) : MailPoet.I18n.t('unknown'))
|
||||||
}
|
}
|
||||||
{renderStatusTableRow(MailPoet.I18n.t('lastSeenError'), status.last_error || '-')}
|
{renderStatusTableRow(MailPoet.I18n.t('lastSeenError'), status.last_error || MailPoet.I18n.t('none'))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
91
assets/js/src/help/queue_status.jsx
Normal file
91
assets/js/src/help/queue_status.jsx
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import MailPoet from 'mailpoet';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
function renderStatusTableRow(title, value) {
|
||||||
|
return (
|
||||||
|
<tr>
|
||||||
|
<td className={'row-title'}>{ title }</td><td>{ value }</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QueueStatus = (props) => {
|
||||||
|
const status = props.status_data;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>{MailPoet.I18n.t('systemStatusQueueTitle')}</h2>
|
||||||
|
<table className={'widefat fixed'} style={{ maxWidth: '400px' }}>
|
||||||
|
<tbody>
|
||||||
|
{renderStatusTableRow(
|
||||||
|
MailPoet.I18n.t('status'),
|
||||||
|
status.status === 'paused' ? MailPoet.I18n.t('paused') : MailPoet.I18n.t('running'))
|
||||||
|
}
|
||||||
|
{renderStatusTableRow(
|
||||||
|
MailPoet.I18n.t('startedAt'),
|
||||||
|
status.started ? MailPoet.Date.full(status.started * 1000) : MailPoet.I18n.t('unknown'))
|
||||||
|
}
|
||||||
|
{renderStatusTableRow(
|
||||||
|
MailPoet.I18n.t('sentEmails'),
|
||||||
|
status.sent || 0)
|
||||||
|
}
|
||||||
|
{renderStatusTableRow(
|
||||||
|
MailPoet.I18n.t('retryAttempts'),
|
||||||
|
status.retry_attempt || MailPoet.I18n.t('none'))
|
||||||
|
}
|
||||||
|
{renderStatusTableRow(
|
||||||
|
MailPoet.I18n.t('retryAt'),
|
||||||
|
status.retry_at ? MailPoet.Date.full(status.retry_at * 1000) : MailPoet.I18n.t('none'))
|
||||||
|
}
|
||||||
|
{renderStatusTableRow(
|
||||||
|
MailPoet.I18n.t('error'),
|
||||||
|
status.error || MailPoet.I18n.t('none'))
|
||||||
|
}
|
||||||
|
{renderStatusTableRow(
|
||||||
|
MailPoet.I18n.t('totalCompletedTasks'),
|
||||||
|
status.tasksStatusCounts.completed)
|
||||||
|
}
|
||||||
|
{renderStatusTableRow(
|
||||||
|
MailPoet.I18n.t('totalRunningTasks'),
|
||||||
|
status.tasksStatusCounts.running)
|
||||||
|
}
|
||||||
|
{renderStatusTableRow(
|
||||||
|
MailPoet.I18n.t('totalPausedTasks'),
|
||||||
|
status.tasksStatusCounts.paused)
|
||||||
|
}
|
||||||
|
{renderStatusTableRow(
|
||||||
|
MailPoet.I18n.t('totalScheduledTasks'),
|
||||||
|
status.tasksStatusCounts.scheduled)
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
QueueStatus.propTypes = {
|
||||||
|
status_data: React.PropTypes.shape({
|
||||||
|
status: React.PropTypes.string,
|
||||||
|
started: React.PropTypes.number,
|
||||||
|
sent: React.PropTypes.number,
|
||||||
|
retry_attempt: React.PropTypes.number,
|
||||||
|
retry_at: React.PropTypes.number,
|
||||||
|
tasksStatusCounts: React.PropTypes.shape({
|
||||||
|
completed: React.PropTypes.number.isRequired,
|
||||||
|
running: React.PropTypes.number.isRequired,
|
||||||
|
paused: React.PropTypes.number.isRequired,
|
||||||
|
scheduled: React.PropTypes.number.isRequired,
|
||||||
|
}).isRequired,
|
||||||
|
}).isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
QueueStatus.defaultProps = {
|
||||||
|
status_data: {
|
||||||
|
status: null,
|
||||||
|
started: null,
|
||||||
|
sent: null,
|
||||||
|
retry_attempt: null,
|
||||||
|
retry_at: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = QueueStatus;
|
@ -2,6 +2,7 @@ import MailPoet from 'mailpoet';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactStringReplace from 'react-string-replace';
|
import ReactStringReplace from 'react-string-replace';
|
||||||
import CronStatus from './cron_status.jsx';
|
import CronStatus from './cron_status.jsx';
|
||||||
|
import QueueStatus from './queue_status.jsx';
|
||||||
import Tabs from './tabs.jsx';
|
import Tabs from './tabs.jsx';
|
||||||
|
|
||||||
function renderStatusMessage(status, error, link) {
|
function renderStatusMessage(status, error, link) {
|
||||||
@ -67,6 +68,7 @@ function SystemStatus() {
|
|||||||
{renderCronSection(systemStatusData)}
|
{renderCronSection(systemStatusData)}
|
||||||
{renderMSSSection(systemStatusData)}
|
{renderMSSSection(systemStatusData)}
|
||||||
<CronStatus status_data={systemStatusData.cronStatus} />
|
<CronStatus status_data={systemStatusData.cronStatus} />
|
||||||
|
<QueueStatus status_data={systemStatusData.queueStatus} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,10 @@ use MailPoet\Form\Block;
|
|||||||
use MailPoet\Form\Renderer as FormRenderer;
|
use MailPoet\Form\Renderer as FormRenderer;
|
||||||
use MailPoet\Helpscout\Beacon;
|
use MailPoet\Helpscout\Beacon;
|
||||||
use MailPoet\Listing;
|
use MailPoet\Listing;
|
||||||
|
use MailPoet\Mailer\MailerLog;
|
||||||
use MailPoet\Models\CustomField;
|
use MailPoet\Models\CustomField;
|
||||||
use MailPoet\Models\Form;
|
use MailPoet\Models\Form;
|
||||||
|
use MailPoet\Models\ScheduledTask;
|
||||||
use MailPoet\Models\Segment;
|
use MailPoet\Models\Segment;
|
||||||
use MailPoet\Models\Setting;
|
use MailPoet\Models\Setting;
|
||||||
use MailPoet\Models\Subscriber;
|
use MailPoet\Models\Subscriber;
|
||||||
@ -20,6 +22,7 @@ use MailPoet\Services\Bridge;
|
|||||||
use MailPoet\Settings\Hosts;
|
use MailPoet\Settings\Hosts;
|
||||||
use MailPoet\Settings\Pages;
|
use MailPoet\Settings\Pages;
|
||||||
use MailPoet\Subscribers\ImportExport\ImportExportFactory;
|
use MailPoet\Subscribers\ImportExport\ImportExportFactory;
|
||||||
|
use MailPoet\Tasks\State;
|
||||||
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
|
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
|
||||||
use MailPoet\Util\License\License;
|
use MailPoet\Util\License\License;
|
||||||
use MailPoet\WP\DateTime;
|
use MailPoet\WP\DateTime;
|
||||||
@ -447,6 +450,7 @@ class Menu {
|
|||||||
|
|
||||||
|
|
||||||
function help() {
|
function help() {
|
||||||
|
$tasks_state = new State();
|
||||||
$system_info_data = Beacon::getData();
|
$system_info_data = Beacon::getData();
|
||||||
$system_status_data = [
|
$system_status_data = [
|
||||||
'cron' => [
|
'cron' => [
|
||||||
@ -459,8 +463,10 @@ class Menu {
|
|||||||
false
|
false
|
||||||
],
|
],
|
||||||
'cronStatus' => CronHelper::getDaemon(),
|
'cronStatus' => CronHelper::getDaemon(),
|
||||||
|
'queueStatus' => MailerLog::getMailerLog(),
|
||||||
];
|
];
|
||||||
$system_status_data['cronStatus']['accessible'] = CronHelper::isDaemonAccessible();
|
$system_status_data['cronStatus']['accessible'] = CronHelper::isDaemonAccessible();
|
||||||
|
$system_status_data['queueStatus']['tasksStatusCounts'] = $tasks_state->getCountsPerStatus();
|
||||||
$this->displayPage(
|
$this->displayPage(
|
||||||
'help.html',
|
'help.html',
|
||||||
array(
|
array(
|
||||||
|
@ -11,6 +11,7 @@ class ScheduledTask extends Model {
|
|||||||
const STATUS_COMPLETED = 'completed';
|
const STATUS_COMPLETED = 'completed';
|
||||||
const STATUS_SCHEDULED = 'scheduled';
|
const STATUS_SCHEDULED = 'scheduled';
|
||||||
const STATUS_PAUSED = 'paused';
|
const STATUS_PAUSED = 'paused';
|
||||||
|
const VIRTUAL_STATUS_RUNNING = 'running'; // For historical reasons this is stored as null in DB
|
||||||
const PRIORITY_HIGH = 1;
|
const PRIORITY_HIGH = 1;
|
||||||
const PRIORITY_MEDIUM = 5;
|
const PRIORITY_MEDIUM = 5;
|
||||||
const PRIORITY_LOW = 10;
|
const PRIORITY_LOW = 10;
|
||||||
|
35
lib/Tasks/State.php
Normal file
35
lib/Tasks/State.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace MailPoet\Tasks;
|
||||||
|
|
||||||
|
|
||||||
|
use MailPoet\Models\ScheduledTask;
|
||||||
|
|
||||||
|
class State
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function getCountsPerStatus() {
|
||||||
|
$stats = [
|
||||||
|
ScheduledTask::STATUS_COMPLETED => 0,
|
||||||
|
ScheduledTask::STATUS_PAUSED => 0,
|
||||||
|
ScheduledTask::STATUS_SCHEDULED => 0,
|
||||||
|
ScheduledTask::VIRTUAL_STATUS_RUNNING => 0,
|
||||||
|
];
|
||||||
|
$counts = ScheduledTask::rawQuery(
|
||||||
|
"SELECT COUNT(*) as value, status
|
||||||
|
FROM `" . ScheduledTask::$_table . "`
|
||||||
|
WHERE deleted_at IS NULL AND `type` = 'sending'
|
||||||
|
GROUP BY status;"
|
||||||
|
)->findMany();
|
||||||
|
foreach($counts as $count) {
|
||||||
|
if($count->status === null) {
|
||||||
|
$stats[ScheduledTask::VIRTUAL_STATUS_RUNNING] = (int)$count->value;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$stats[$count->status] = (int)$count->value;
|
||||||
|
}
|
||||||
|
return $stats;
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,7 @@
|
|||||||
'systemInfoIntro': __('The information below is useful when you need to get in touch with our support. Just copy all the text below and paste it into a message to us.'),
|
'systemInfoIntro': __('The information below is useful when you need to get in touch with our support. Just copy all the text below and paste it into a message to us.'),
|
||||||
'systemInfoDataError': __('Sorry, there was an error, please try again later.'),
|
'systemInfoDataError': __('Sorry, there was an error, please try again later.'),
|
||||||
'systemStatusCronStatusTitle': __('Cron'),
|
'systemStatusCronStatusTitle': __('Cron'),
|
||||||
|
'systemStatusQueueTitle': __('Sending Queue'),
|
||||||
'lastUpdated': __('Last updated'),
|
'lastUpdated': __('Last updated'),
|
||||||
'lastRunStarted': __('Last run started'),
|
'lastRunStarted': __('Last run started'),
|
||||||
'lastRunCompleted': __('Last run completed'),
|
'lastRunCompleted': __('Last run completed'),
|
||||||
@ -43,8 +44,18 @@
|
|||||||
'status': __('Status'),
|
'status': __('Status'),
|
||||||
'yes': __('yes'),
|
'yes': __('yes'),
|
||||||
'no': __('no'),
|
'no': __('no'),
|
||||||
'cronRunning': __('running'),
|
'none': __('none'),
|
||||||
|
'running': __('running'),
|
||||||
'cronWaiting': __('waiting for the next run'),
|
'cronWaiting': __('waiting for the next run'),
|
||||||
|
'startedAt': __('Started at'),
|
||||||
|
'sentEmails': __('Sent emails'),
|
||||||
|
'retryAttempt': __('Retry attempt'),
|
||||||
|
'retryAt': __('Retry at'),
|
||||||
|
'error': __('Error'),
|
||||||
|
'totalCompletedTasks': __('Total completed tasks'),
|
||||||
|
'totalScheduledTasks': __('Total scheduled tasks'),
|
||||||
|
'totalRunningTasks': __('Total running tasks'),
|
||||||
|
'totalPausedTasks': __('Total paused tasks'),
|
||||||
}) %>
|
}) %>
|
||||||
<% endblock %>
|
<% endblock %>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user