diff --git a/assets/js/src/common/print_boolean.jsx b/assets/js/src/common/print_boolean.jsx
new file mode 100644
index 0000000000..fd4956b77a
--- /dev/null
+++ b/assets/js/src/common/print_boolean.jsx
@@ -0,0 +1,26 @@
+import React from 'react';
+import MailPoet from 'mailpoet';
+
+const PrintBoolean = props => (
+
+ {(props.children === true && props.truthy) ||
+ (props.children === false && props.falsy) ||
+ (props.unknown)}
+
+);
+
+PrintBoolean.propTypes = {
+ truthy: React.PropTypes.string,
+ falsy: React.PropTypes.string,
+ unknown: React.PropTypes.string,
+ children: React.PropTypes.bool,
+};
+
+PrintBoolean.defaultProps = {
+ truthy: MailPoet.I18n.t('yes'),
+ falsy: MailPoet.I18n.t('no'),
+ unknown: MailPoet.I18n.t('unknown'),
+ children: null,
+};
+
+module.exports = PrintBoolean;
diff --git a/assets/js/src/help/cron_status.jsx b/assets/js/src/help/cron_status.jsx
new file mode 100644
index 0000000000..80b268ab74
--- /dev/null
+++ b/assets/js/src/help/cron_status.jsx
@@ -0,0 +1,71 @@
+import MailPoet from 'mailpoet';
+import React from 'react';
+import PrintBoolean from 'common/print_boolean.jsx';
+
+function renderStatusTableRow(title, value) {
+ return (
+
+ { title } | { value } |
+
+ );
+}
+
+const CronStatus = (props) => {
+ const status = props.status_data;
+ const activeStatusMapping = {
+ active: MailPoet.I18n.t('cronRunning'),
+ inactive: MailPoet.I18n.t('cronWaiting'),
+ };
+ return (
+
+
{MailPoet.I18n.t('systemStatusCronStatusTitle')}
+
+
+ {renderStatusTableRow(
+ MailPoet.I18n.t('accessible'),
+ {status.accessible})
+ }
+ {renderStatusTableRow(
+ MailPoet.I18n.t('status'),
+ activeStatusMapping[status.status] ? activeStatusMapping[status.status] : MailPoet.I18n.t('unknown'))
+ }
+ {renderStatusTableRow(
+ MailPoet.I18n.t('lastUpdated'),
+ status.updated_at ? MailPoet.Date.full(status.updated_at * 1000) : MailPoet.I18n.t('unknown'))
+ }
+ {renderStatusTableRow(
+ MailPoet.I18n.t('lastRunStarted'),
+ status.run_accessed_at ? MailPoet.Date.full(status.run_started_at * 1000) : MailPoet.I18n.t('unknown'))
+ }
+ {renderStatusTableRow(
+ MailPoet.I18n.t('lastRunCompleted'),
+ status.run_completed_at ? MailPoet.Date.full(status.run_completed_at * 1000) : MailPoet.I18n.t('unknown'))
+ }
+ {renderStatusTableRow(MailPoet.I18n.t('lastSeenError'), status.last_error || '-')}
+
+
+
+ );
+};
+
+CronStatus.propTypes = {
+ status_data: React.PropTypes.shape({
+ accessible: React.PropTypes.bool,
+ status: React.PropTypes.string,
+ updated_at: React.PropTypes.number,
+ run_accessed_at: React.PropTypes.number,
+ run_completed_at: React.PropTypes.number,
+ }).isRequired,
+};
+
+CronStatus.defaultProps = {
+ status_data: {
+ accessible: null,
+ status: null,
+ updated_at: null,
+ run_accessed_at: null,
+ run_completed_at: null,
+ },
+};
+
+module.exports = CronStatus;
diff --git a/assets/js/src/help/system_status.jsx b/assets/js/src/help/system_status.jsx
index f4750aba56..7eb7f7b8cc 100644
--- a/assets/js/src/help/system_status.jsx
+++ b/assets/js/src/help/system_status.jsx
@@ -1,6 +1,7 @@
import MailPoet from 'mailpoet';
import React from 'react';
import ReactStringReplace from 'react-string-replace';
+import CronStatus from './cron_status.jsx';
import Tabs from './tabs.jsx';
function renderStatusMessage(status, error, link) {
@@ -65,6 +66,7 @@ function SystemStatus() {
{renderCronSection(systemStatusData)}
{renderMSSSection(systemStatusData)}
+
);
}
diff --git a/lib/Config/Menu.php b/lib/Config/Menu.php
index fd2afa4b25..97f168d3f7 100644
--- a/lib/Config/Menu.php
+++ b/lib/Config/Menu.php
@@ -448,17 +448,19 @@ class Menu {
function help() {
$system_info_data = Beacon::getData();
- $system_status_data = array(
- 'cron' => array(
+ $system_status_data = [
+ 'cron' => [
'url' => CronHelper::getCronUrl(CronDaemon::ACTION_PING),
'isReachable' => CronHelper::pingDaemon(true)
- ),
- 'mss' => array(
+ ],
+ 'mss' => [
'enabled' => (Bridge::isMPSendingServiceEnabled()) ?
- array('isReachable' => Bridge::pingBridge()) :
+ ['isReachable' => Bridge::pingBridge()] :
false
- )
- );
+ ],
+ 'cronStatus' => CronHelper::getDaemon(),
+ ];
+ $system_status_data['cronStatus']['accessible'] = CronHelper::isDaemonAccessible();
$this->displayPage(
'help.html',
array(
diff --git a/views/help.html b/views/help.html
index 9f509a3e23..1d9c7b9f2f 100644
--- a/views/help.html
+++ b/views/help.html
@@ -33,6 +33,18 @@
'knowledgeBaseButton': __('Visit our Knowledge Base for more articles'),
'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.'),
+ 'systemStatusCronStatusTitle': __('Cron'),
+ 'lastUpdated': __('Last updated'),
+ 'lastRunStarted': __('Last run started'),
+ 'lastRunCompleted': __('Last run completed'),
+ 'lastSeenError': __('Last seen error'),
+ 'unknown': __('unknown'),
+ 'accessible': __('Accessible'),
+ 'status': __('Status'),
+ 'yes': __('yes'),
+ 'no': __('no'),
+ 'cronRunning': __('running'),
+ 'cronWaiting': __('waiting for the next run'),
}) %>
<% endblock %>