-
+
= t('Resource Configuration'); ?>
-
-
+
= t('Create New Resource'); ?>
@@ -24,7 +13,7 @@
= $this->icon('plus'); ?> = $this->translate('Create A New Resource'); ?>
-
+
= t('Edit Existing Resources'); ?>
diff --git a/application/views/scripts/config/resource/create.phtml b/application/views/scripts/config/resource/create.phtml
index c70bd4779..71d8c946e 100644
--- a/application/views/scripts/config/resource/create.phtml
+++ b/application/views/scripts/config/resource/create.phtml
@@ -2,7 +2,7 @@
= $this->tabs->showOnlyCloseButton() ?>
-
+
= $this->translate('Create A New Resource'); ?>
= $this->translate('Resources are entities that provide data to Icinga Web 2.'); ?>
diff --git a/application/views/scripts/config/resource/modify.phtml b/application/views/scripts/config/resource/modify.phtml
index 48255261b..b7bd0a2f7 100644
--- a/application/views/scripts/config/resource/modify.phtml
+++ b/application/views/scripts/config/resource/modify.phtml
@@ -2,7 +2,7 @@
= $this->tabs->showOnlyCloseButton() ?>
-
+
= $this->translate('Edit Existing Resource'); ?>
diff --git a/application/views/scripts/config/resource/remove.phtml b/application/views/scripts/config/resource/remove.phtml
index ad5ed59cb..010f2d5d2 100644
--- a/application/views/scripts/config/resource/remove.phtml
+++ b/application/views/scripts/config/resource/remove.phtml
@@ -2,7 +2,7 @@
= $this->tabs->showOnlyCloseButton() ?>
-
+
= $this->translate('Remove Existing Resource'); ?>
diff --git a/application/views/scripts/preference/index.phtml b/application/views/scripts/preference/index.phtml
index 163381531..fc19a1e10 100644
--- a/application/views/scripts/preference/index.phtml
+++ b/application/views/scripts/preference/index.phtml
@@ -1,7 +1,7 @@
= $tabs; ?>
-
+
= $this->translate('Preferences'); ?>
= $form; ?>
\ No newline at end of file
diff --git a/application/views/scripts/roles/index.phtml b/application/views/scripts/roles/index.phtml
index 0dcd75691..fa1297396 100644
--- a/application/views/scripts/roles/index.phtml
+++ b/application/views/scripts/roles/index.phtml
@@ -1,8 +1,10 @@
= $tabs ?>
-
= $this->translate('Roles') ?>
+
+ = $this->translate('Roles') ?>
+
isEmpty()): ?>
= $this->translate('No roles found.') ?>
@@ -66,6 +68,9 @@
+
+ = $this->translate('Create New Role'); ?>
+
= $this->translate('Create a New Role') ?>
diff --git a/application/views/scripts/roles/new.phtml b/application/views/scripts/roles/new.phtml
index 4c21c6f6b..d18ada1a5 100644
--- a/application/views/scripts/roles/new.phtml
+++ b/application/views/scripts/roles/new.phtml
@@ -1,7 +1,9 @@
= $tabs->showOnlyCloseButton() ?>
-
= $this->translate('New Role') ?>
+
+ = $this->translate('New Role') ?>
+
= $form ?>
diff --git a/application/views/scripts/roles/remove.phtml b/application/views/scripts/roles/remove.phtml
index 4abff566a..432c3602d 100644
--- a/application/views/scripts/roles/remove.phtml
+++ b/application/views/scripts/roles/remove.phtml
@@ -1,7 +1,9 @@
= $tabs->showOnlyCloseButton() ?>
-
= sprintf($this->translate('Remove Role %s'), $name) ?>
+
+ = sprintf($this->translate('Remove Role %s'), $name) ?>
+
= $form ?>
diff --git a/application/views/scripts/roles/update.phtml b/application/views/scripts/roles/update.phtml
index f48f1ca69..32ab7d018 100644
--- a/application/views/scripts/roles/update.phtml
+++ b/application/views/scripts/roles/update.phtml
@@ -1,7 +1,9 @@
= $tabs->showOnlyCloseButton() ?>
-
= sprintf($this->translate('Update Role %s'), $name) ?>
+
+ = sprintf($this->translate('Update Role %s'), $name) ?>
+
= $form ?>
diff --git a/library/Icinga/Chart/Chart.php b/library/Icinga/Chart/Chart.php
index 13b0114e6..842bb56e8 100644
--- a/library/Icinga/Chart/Chart.php
+++ b/library/Icinga/Chart/Chart.php
@@ -38,11 +38,25 @@ abstract class Chart implements Drawable
*/
protected $palette;
+ /**
+ * The title of this chart, used for providing accessibility features
+ *
+ * @var string
+ */
+ public $title;
+
+ /**
+ * The description for this chart, mandatory for providing accessibility features
+ *
+ * @var string
+ */
+ public $description;
+
/**
* Create a new chart object and create internal objects
*
* If you want to extend this class use the init() method as an extension point,
- * as this will be called at the end o fthe construct call
+ * as this will be called at the end of the construct call
*/
public function __construct()
{
@@ -86,7 +100,6 @@ abstract class Chart implements Drawable
}
/**
- *
* Render this graph and return the created SVG
*
* @return string The SVG created by the SvgRenderer
@@ -105,6 +118,11 @@ abstract class Chart implements Drawable
$this->renderer->setXAspectRatioAlignment(SVGRenderer::X_ASPECT_RATIO_MIN);
$this->renderer->setYAspectRatioAlignment(SVGRenderer::Y_ASPECT_RATIO_MIN);
}
+
+ $this->renderer->setAriaDescription($this->description);
+ $this->renderer->setAriaTitle($this->title);
+ $this->renderer->getCanvas()->setAriaRole('presentation');
+
$this->renderer->getCanvas()->addElement($this);
return $this->renderer->render();
}
diff --git a/library/Icinga/Chart/Graph/BarGraph.php b/library/Icinga/Chart/Graph/BarGraph.php
index 2d20f8f22..dacc12878 100644
--- a/library/Icinga/Chart/Graph/BarGraph.php
+++ b/library/Icinga/Chart/Graph/BarGraph.php
@@ -65,7 +65,13 @@ class BarGraph extends Styleable implements Drawable
) {
$this->order = $order;
$this->dataSet = $dataSet;
+
$this->tooltips = $tooltips;
+ foreach ($this->tooltips as $value) {
+ $ts[] = $value;
+ }
+ $this->tooltips = $ts;
+
$this->graphs = $graphs;
}
diff --git a/library/Icinga/Chart/Graph/LineGraph.php b/library/Icinga/Chart/Graph/LineGraph.php
index 630223968..7b831d625 100644
--- a/library/Icinga/Chart/Graph/LineGraph.php
+++ b/library/Icinga/Chart/Graph/LineGraph.php
@@ -38,6 +38,13 @@ class LineGraph extends Styleable implements Drawable
*/
private $isDiscrete = false;
+ /**
+ * The tooltips
+ *
+ * @var
+ */
+ private $tooltips;
+
/**
* The default stroke width
* @var int
@@ -56,10 +63,22 @@ class LineGraph extends Styleable implements Drawable
*
* @param array $dataset An array of [x, y] arrays to display
*/
- public function __construct(array $dataset)
- {
+ public function __construct(
+ array $dataset,
+ array &$graphs,
+ $order,
+ array $tooltips = null
+ ) {
usort($dataset, array($this, 'sortByX'));
$this->dataset = $dataset;
+ $this->graphs = $graphs;
+
+ $this->tooltips = $tooltips;
+ foreach ($this->tooltips as $value) {
+ $ts[] = $value;
+ }
+ $this->tooltips = $ts;
+ $this->order = $order;
}
/**
@@ -142,14 +161,41 @@ class LineGraph extends Styleable implements Drawable
$path->setAdditionalStyle('clip-path: url(#clip);');
$path->setId($this->id);
$group = $path->toSvg($ctx);
- if ($this->showDataPoints === true) {
- foreach ($this->dataset as $point) {
- $dot = new Circle($point[0], $point[1], $this->dotWith);
- $dot->setFill($this->strokeColor);
- $group->appendChild($dot->toSvg($ctx));
+ foreach ($this->dataset as $x => $point) {
+
+ if ($this->showDataPoints === true) {
+ $dot = new Circle($point[0], $point[1], $this->dotWith);
+ $dot->setFill($this->strokeColor);
+ $group->appendChild($dot->toSvg($ctx));
+ }
+
+ // Draw invisible circle for tooltip hovering
+ $invisible = new Circle($point[0], $point[1], 20);
+ $invisible->setFill($this->strokeColor);
+ $invisible->setAdditionalStyle('opacity: 0.0;');
+ $invisible->setAttribute('class', 'chart-data');
+ if (isset($this->tooltips[$x])) {
+ $data = array(
+ 'label' => isset($this->graphs[$this->order]['label']) ?
+ strtolower($this->graphs[$this->order]['label']) : '',
+ 'color' => isset($this->graphs[$this->order]['color']) ?
+ strtolower($this->graphs[$this->order]['color']) : '#fff'
+ );
+ $format = isset($this->graphs[$this->order]['tooltip'])
+ ? $this->graphs[$this->order]['tooltip'] : null;
+ $invisible->setAttribute(
+ 'title',
+ $this->tooltips[$x]->renderNoHtml($this->order, $data, $format)
+ );
+ $invisible->setAttribute(
+ 'data-title-rich',
+ $this->tooltips[$x]->render($this->order, $data, $format)
+ );
+ }
+ $group->appendChild($invisible->toSvg($ctx));
}
- }
+
return $group;
}
}
diff --git a/library/Icinga/Chart/Graph/Tooltip.php b/library/Icinga/Chart/Graph/Tooltip.php
index 5fa5c3608..8b2efa613 100644
--- a/library/Icinga/Chart/Graph/Tooltip.php
+++ b/library/Icinga/Chart/Graph/Tooltip.php
@@ -66,7 +66,7 @@ class Tooltip
*/
public function __construct (
$data = array(),
- $format = '
{title} {value} of {sum} {label}'
+ $format = '
{title}: {value} {label}'
) {
$this->data = array_merge($this->data, $data);
$this->defaultFormat = $format;
diff --git a/library/Icinga/Chart/GridChart.php b/library/Icinga/Chart/GridChart.php
index 7f2794282..9f867ac66 100644
--- a/library/Icinga/Chart/GridChart.php
+++ b/library/Icinga/Chart/GridChart.php
@@ -84,6 +84,13 @@ class GridChart extends Chart
*/
private $tooltips = array();
+ public function __construct()
+ {
+ $this->title = t('Grid Chart');
+ $this->description = t('Contains data in a bar or line chart.');
+ parent::__construct();
+ }
+
/**
* Check if the current dataset has the proper structure for this chart.
*
@@ -395,7 +402,12 @@ class GridChart extends Chart
);
break;
case self::TYPE_LINE:
- $graphObj = new LineGraph($axis->transform($graph['data']));
+ $graphObj = new LineGraph(
+ $axis->transform($graph['data']),
+ $graphs,
+ $dataset,
+ $this->tooltips
+ );
break;
default:
continue;
diff --git a/library/Icinga/Chart/PieChart.php b/library/Icinga/Chart/PieChart.php
index 33ce32927..6b19969c8 100644
--- a/library/Icinga/Chart/PieChart.php
+++ b/library/Icinga/Chart/PieChart.php
@@ -50,6 +50,13 @@ class PieChart extends Chart
*/
private $noCaption = false;
+ public function __construct()
+ {
+ $this->title = t('Pie Chart');
+ $this->description = t('Contains data in a pie chart.');
+ parent::__construct();
+ }
+
/**
* Test if the given pies have the correct format
*
diff --git a/library/Icinga/Chart/Primitive/Canvas.php b/library/Icinga/Chart/Primitive/Canvas.php
index c5617fa35..88e247f02 100644
--- a/library/Icinga/Chart/Primitive/Canvas.php
+++ b/library/Icinga/Chart/Primitive/Canvas.php
@@ -43,6 +43,13 @@ class Canvas implements Drawable
*/
private $rect;
+ /**
+ * The aria role used to describe this canvas' purpose in the accessibility tree
+ *
+ * @var string
+ */
+ private $ariaRole;
+
/**
* Create this canvas
*
@@ -111,6 +118,23 @@ class Canvas implements Drawable
$innerContainer->appendChild($child->toSvg($ctx));
}
+ if (isset($this->ariaRole)) {
+ $outer->setAttribute('role', $this->ariaRole);
+ }
return $outer;
}
+
+ /**
+ * Set the aria role used to determine the meaning of this canvas in the accessibility tree
+ *
+ * The role 'presentation' will indicate that the purpose of this canvas is entirely decorative, while the role
+ * 'img' will indicate that the canvas contains an image, with a possible title or a description. For other
+ * possible roles, see http://www.w3.org/TR/wai-aria/roles
+ *
+ * @param $role string The aria role to set
+ */
+ public function setAriaRole($role)
+ {
+ $this->ariaRole = $role;
+ }
}
diff --git a/library/Icinga/Chart/SVGRenderer.php b/library/Icinga/Chart/SVGRenderer.php
index 5cc223388..98eaa86d6 100644
--- a/library/Icinga/Chart/SVGRenderer.php
+++ b/library/Icinga/Chart/SVGRenderer.php
@@ -48,6 +48,27 @@ class SVGRenderer
*/
private $svg;
+ /**
+ * The description of this SVG, useful for screen readers
+ *
+ * @var string
+ */
+ private $ariaDescription;
+
+ /**
+ * The title of this SVG, useful for screen readers
+ *
+ * @var string
+ */
+ private $ariaTitle;
+
+ /**
+ * The aria role used by this svg element
+ *
+ * @var string
+ */
+ private $ariaRole = 'img';
+
/**
* The root layer for all elements
*
@@ -126,6 +147,7 @@ class SVGRenderer
$svg = $this->document->createElement('svg');
$svg->setAttribute('xmlns', 'http://www.w3.org/2000/svg');
$svg->setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+ $svg->setAttribute('role', $this->ariaRole);
$svg->setAttribute('width', '100%');
$svg->setAttribute('height', '100%');
$svg->setAttribute(
@@ -150,6 +172,42 @@ class SVGRenderer
return $svg;
}
+ /**
+ * Add aria title and description
+ *
+ * Adds an aria title and desc element to the given SVG node, which are used to describe this SVG by accessibility
+ * tools such as screen readers.
+ *
+ * @param DOMNode $svg The SVG DOMNode to which the aria attributes should be attached
+ * @param $title The title text
+ * @param $description The description text
+ */
+ private function addAriaDescription (DOMNode $svg, $titleText, $descriptionText)
+ {
+ $doc = $svg->ownerDocument;
+
+ $titleId = $descId = '';
+ if (isset ($this->ariaTitle)) {
+ $titleId = 'aria-title-' . $this->stripNonAlphanumeric($titleText);
+ $title = $doc->createElement('title');
+ $title->setAttribute('id', $titleId);
+
+ $title->appendChild($doc->createTextNode($titleText));
+ $svg->appendChild($title);
+ }
+
+ if (isset ($this->ariaDescription)) {
+ $descId = 'aria-desc-' . $this->stripNonAlphanumeric($descriptionText);
+ $desc = $doc->createElement('desc');
+ $desc->setAttribute('id', $descId);
+
+ $desc->appendChild($doc->createTextNode($descriptionText));
+ $svg->appendChild($desc);
+ }
+
+ $svg->setAttribute('aria-labelledby', join(' ', array($titleId, $descId)));
+ }
+
/**
* Initialises the XML-document, SVG-element and this figure's root canvas
*
@@ -172,6 +230,7 @@ class SVGRenderer
{
$this->createRootDocument();
$ctx = $this->createRenderContext();
+ $this->addAriaDescription($this->svg, $this->ariaTitle, $this->ariaDescription);
$this->svg->appendChild($this->rootCanvas->toSvg($ctx));
$this->document->formatOutput = true;
return $this->document->saveXML();
@@ -232,4 +291,40 @@ class SVGRenderer
{
$this->yAspectRatio = $alignment;
}
+
+ /**
+ * Set the aria description, that is used as a title for this SVG in screen readers
+ *
+ * @param $text
+ */
+ public function setAriaTitle($text)
+ {
+ $this->ariaTitle = $text;
+ }
+
+ /**
+ * Set the aria description, that is used to describe this SVG in screen readers
+ *
+ * @param $text
+ */
+ public function setAriaDescription($text)
+ {
+ $this->ariaDescription = $text;
+ }
+
+ /**
+ * Set the aria role, that is used to describe the purpose of this SVG in screen readers
+ *
+ * @param $text
+ */
+ public function setAriaRole($text)
+ {
+ $this->ariaRole = $text;
+ }
+
+
+ private function stripNonAlphanumeric($str)
+ {
+ return preg_replace('/[^A-Za-z]+/', '', $str);
+ }
}
diff --git a/library/Icinga/Web/Widget/Chart/InlinePie.php b/library/Icinga/Web/Widget/Chart/InlinePie.php
index 341322714..0bddc906d 100644
--- a/library/Icinga/Web/Widget/Chart/InlinePie.php
+++ b/library/Icinga/Web/Widget/Chart/InlinePie.php
@@ -44,7 +44,6 @@ EOD;
EOD;
-
/**
* @var Url
*/
diff --git a/library/Icinga/Web/Widget/Dashboard/Dashlet.php b/library/Icinga/Web/Widget/Dashboard/Dashlet.php
index cbb4bec33..614caf845 100644
--- a/library/Icinga/Web/Widget/Dashboard/Dashlet.php
+++ b/library/Icinga/Web/Widget/Dashboard/Dashlet.php
@@ -6,7 +6,6 @@ namespace Icinga\Web\Widget\Dashboard;
use Zend_Form_Element_Button;
use Icinga\Web\Form;
use Icinga\Web\Url;
-use Icinga\Web\Widget\AbstractWidget;
use Icinga\Data\ConfigObject;
use Icinga\Exception\IcingaException;
@@ -54,7 +53,12 @@ class Dashlet extends UserWidget
EOD;
@@ -184,7 +188,8 @@ EOD;
'{IFRAME_URL}',
'{FULL_URL}',
'{TOOLTIP}',
- '{TITLE}'
+ '{TITLE}',
+ '{TITLE_PREFIX}'
);
$replaceTokens = array(
@@ -192,7 +197,8 @@ EOD;
$iframeUrl,
$url->getUrlWithout(array('view', 'limit')),
sprintf($view->translate('Show %s', 'dashboard.dashlet.tooltip'), $view->escape($this->getTitle())),
- $view->escape($this->getTitle())
+ $view->escape($this->getTitle()),
+ $view->translate('Dashlet') . ': '
);
return str_replace($searchTokens, $replaceTokens, $this->template);
diff --git a/library/Icinga/Web/Widget/FilterEditor.php b/library/Icinga/Web/Widget/FilterEditor.php
index 16136a62a..21dd0f04a 100644
--- a/library/Icinga/Web/Widget/FilterEditor.php
+++ b/library/Icinga/Web/Widget/FilterEditor.php
@@ -678,20 +678,28 @@ class FilterEditor extends AbstractWidget
public function render()
{
if (! $this->preservedUrl()->getParam('modifyFilter')) {
- return $this->renderSearch() . $this->shorten($this->filter, 50);
+ $filterEditor = $this->renderSearch() . $this->shorten($this->filter, 50);
+ } else {
+ $filterEditor = $this->renderSearch()
+ . '
';
}
- return $this->renderSearch()
- . '
';
+
+ return sprintf(
+ '
'
+ . '
%s
%s',
+ t('Filters'),
+ $filterEditor
+ );
}
protected function shorten($string, $length)
diff --git a/library/Icinga/Web/Widget/SortBox.php b/library/Icinga/Web/Widget/SortBox.php
index 18ed95b86..a1728db4f 100644
--- a/library/Icinga/Web/Widget/SortBox.php
+++ b/library/Icinga/Web/Widget/SortBox.php
@@ -133,6 +133,13 @@ class SortBox extends AbstractWidget
if ($this->request) {
$form->populate($this->request->getParams());
}
- return $form;
+
+ return sprintf(
+ '
'
+ . '
%s
%s%s',
+ t('Sort Criteria'),
+ t('Sort by'),
+ (string) $form
+ );
}
}
diff --git a/library/Icinga/Web/Widget/Tabs.php b/library/Icinga/Web/Widget/Tabs.php
index 56bd3404c..202771237 100644
--- a/library/Icinga/Web/Widget/Tabs.php
+++ b/library/Icinga/Web/Widget/Tabs.php
@@ -19,6 +19,7 @@ class Tabs extends AbstractWidget implements Countable
* @var string
*/
private $baseTpl = <<< 'EOT'
+{HEADER}
{TABS}
{DROPDOWN}
@@ -26,6 +27,13 @@ class Tabs extends AbstractWidget implements Countable
EOT;
+ /**
+ * Template used for the header
+ *
+ * @type string
+ */
+ private $headerTpl = '
{TITLE}
';
+
/**
* Template used for the tabs dropdown
*
@@ -87,6 +95,13 @@ EOT;
*/
private $closeTab = true;
+ /**
+ * Title of the tab navigation
+ *
+ * @type string
+ */
+ private $title;
+
/**
* Set whether the current tab is closable
*/
@@ -309,11 +324,21 @@ EOT;
}
$close = $this->closeTab ? $this->renderCloseTab() : '';
- $html = $this->baseTpl;
- $html = str_replace('{TABS}', $tabs, $html);
- $html = str_replace('{DROPDOWN}', $drop, $html);
- $html = str_replace('{CLOSE}', $close, $html);
- return $html;
+ return str_replace(
+ array(
+ '{TABS}',
+ '{DROPDOWN}',
+ '{CLOSE}',
+ '{HEADER}'
+ ),
+ array(
+ $tabs,
+ $drop,
+ $close,
+ $this->renderHeader()
+ ),
+ $this->baseTpl
+ );
}
public function __toString()
@@ -372,4 +397,30 @@ EOT;
$tabextension->apply($this);
return $this;
}
+
+ /**
+ * Set the title of the tab navigation
+ *
+ * @param string $title
+ * @return self
+ */
+ public function setTitle($title)
+ {
+ $this->title = $title;
+ return $this;
+ }
+
+ /**
+ * Render the title into the header template
+ *
+ * @return string
+ */
+ public function renderHeader()
+ {
+ if (! $this->title) {
+ return '';
+ }
+
+ return str_replace('{TITLE}', $this->title, $this->headerTpl);
+ }
}
diff --git a/modules/monitoring/application/controllers/AlertsummaryController.php b/modules/monitoring/application/controllers/AlertsummaryController.php
index 3490da9b4..cc1d75193 100644
--- a/modules/monitoring/application/controllers/AlertsummaryController.php
+++ b/modules/monitoring/application/controllers/AlertsummaryController.php
@@ -44,7 +44,7 @@ class Monitoring_AlertsummaryController extends Controller
'label' => $this->translate('Alert Summary'),
'url' => Url::fromRequest()
)
- )->activate('alertsummary');
+ )->activate('alertsummary')->setTitle($this->translate('Alertsummary Navigation'));
$this->view->title = $this->translate('Alert Summary');
$this->view->intervalBox = $this->createIntervalBox();
@@ -324,6 +324,8 @@ class Monitoring_AlertsummaryController extends Controller
public function createHealingChart()
{
$gridChart = new GridChart();
+ $gridChart->title = t('Healing Chart');
+ $gridChart->description = t('Notifications and average reaction time per hour.');
$gridChart->alignTopLeft();
$gridChart->setAxisLabel($this->createPeriodDescription(), mt('monitoring', 'Notifications'))
@@ -427,7 +429,8 @@ class Monitoring_AlertsummaryController extends Controller
'label' => $this->translate('Notifications'),
'color' => '#07C0D9',
'data' => $notifications,
- 'showPoints' => true
+ 'showPoints' => true,
+ 'tooltip' => '
{title}: {value} {label}'
)
);
@@ -436,7 +439,8 @@ class Monitoring_AlertsummaryController extends Controller
'label' => $this->translate('Avg (min)'),
'color' => '#ffaa44',
'data' => $dAvg,
- 'showPoints' => true
+ 'showPoints' => true,
+ 'tooltip' => t('
{title}: {value}m min. reaction time')
)
);
@@ -445,7 +449,8 @@ class Monitoring_AlertsummaryController extends Controller
'label' => $this->translate('Max (min)'),
'color' => '#ff5566',
'data' => $dMax,
- 'showPoints' => true
+ 'showPoints' => true,
+ 'tooltip' => t('
{title}: {value}m max. reaction time')
)
);
@@ -460,6 +465,8 @@ class Monitoring_AlertsummaryController extends Controller
public function createDefectImage()
{
$gridChart = new GridChart();
+ $gridChart->title = t('Defect Chart');
+ $gridChart->description = t('Notifications and defects per hour');
$gridChart->alignTopLeft();
$gridChart->setAxisLabel($this->createPeriodDescription(), mt('monitoring', 'Notifications'))
@@ -472,7 +479,8 @@ class Monitoring_AlertsummaryController extends Controller
'label' => $this->translate('Notifications'),
'color' => '#07C0D9',
'data' => $this->notificationData,
- 'showPoints' => true
+ 'showPoints' => true,
+ 'tooltip' => '
{title}: {value} {label}'
)
);
@@ -481,7 +489,8 @@ class Monitoring_AlertsummaryController extends Controller
'label' => $this->translate('Defects'),
'color' => '#ff5566',
'data' => $this->problemData,
- 'showPoints' => true
+ 'showPoints' => true,
+ 'tooltip' => '
{title}: {value} {label}'
)
);
diff --git a/modules/monitoring/application/controllers/ChartController.php b/modules/monitoring/application/controllers/ChartController.php
index b01702c04..f19d3f458 100644
--- a/modules/monitoring/application/controllers/ChartController.php
+++ b/modules/monitoring/application/controllers/ChartController.php
@@ -236,6 +236,9 @@ class Monitoring_ChartController extends Controller
$unknownBars[] = array($servicegroup->servicegroup, $servicegroup->services_unknown_unhandled);
}
$this->view->chart = new GridChart();
+ $this->view->chart->title = t('Service Group Chart');
+ $this->view->chart->description = t('Contains service states for each service group.');
+
$this->view->chart->alignTopLeft();
$this->view->chart->setAxisLabel('', mt('monitoring', 'Services'))
->setXAxis(new StaticAxis())
@@ -292,6 +295,9 @@ class Monitoring_ChartController extends Controller
}
$tooltip = mt('monitoring', '
{title}: {value} of {sum} hosts are {label}');
$this->view->chart = new GridChart();
+ $this->view->chart->title = t('Host Group Chart');
+ $this->view->chart->description = t('Contains host states of each service group.');
+
$this->view->chart->alignTopLeft();
$this->view->chart->setAxisLabel('', mt('monitoring', 'Hosts'))
->setXAxis(new StaticAxis())
diff --git a/modules/monitoring/application/controllers/ListController.php b/modules/monitoring/application/controllers/ListController.php
index e43d64f1d..3fb782856 100644
--- a/modules/monitoring/application/controllers/ListController.php
+++ b/modules/monitoring/application/controllers/ListController.php
@@ -726,6 +726,7 @@ class Monitoring_ListController extends Controller
private function createTabs()
{
$tabs = $this->getTabs();
+ $tabs->setTitle($this->translate('Monitoring Navigation'));
if (in_array($this->_request->getActionName(), array(
'hosts',
'services',
diff --git a/modules/monitoring/application/controllers/ProcessController.php b/modules/monitoring/application/controllers/ProcessController.php
index b20bd7576..efca3d520 100644
--- a/modules/monitoring/application/controllers/ProcessController.php
+++ b/modules/monitoring/application/controllers/ProcessController.php
@@ -29,7 +29,7 @@ class Monitoring_ProcessController extends Controller
'label' => $this->translate('Monitoring Health'),
'url' =>'monitoring/process/info'
)
- );
+ )->setTitle($this->translate('Process Information'));
}
/**
diff --git a/modules/monitoring/application/controllers/TimelineController.php b/modules/monitoring/application/controllers/TimelineController.php
index f1ef32592..4abe53c4b 100644
--- a/modules/monitoring/application/controllers/TimelineController.php
+++ b/modules/monitoring/application/controllers/TimelineController.php
@@ -22,7 +22,7 @@ class Monitoring_TimelineController extends Controller
'label' => $this->translate('Timeline'),
'url' => Url::fromRequest()
)
- )->activate('timeline');
+ )->activate('timeline')->setTitle($this->translate('Timeline Navigation'));
$this->view->title = $this->translate('Timeline');
// TODO: filter for hard_states (precedence adjustments necessary!)
diff --git a/modules/monitoring/application/forms/Config/BackendConfigForm.php b/modules/monitoring/application/forms/Config/BackendConfigForm.php
index 3014974a3..62e3858a9 100644
--- a/modules/monitoring/application/forms/Config/BackendConfigForm.php
+++ b/modules/monitoring/application/forms/Config/BackendConfigForm.php
@@ -43,8 +43,11 @@ class BackendConfigForm extends ConfigForm
{
$resources = array();
foreach ($resourceConfig as $name => $resource) {
- if ($resource->type === 'db' || $resource->type === 'livestatus') {
- $resources[$resource->type === 'db' ? 'ido' : 'livestatus'][$name] = $name;
+// if ($resource->type === 'db' || $resource->type === 'livestatus') {
+// $resources[$resource->type === 'db' ? 'ido' : 'livestatus'][$name] = $name;
+// }
+ if ($resource->type === 'db') {
+ $resources['ido'][$name] = $name;
}
}
@@ -183,13 +186,19 @@ class BackendConfigForm extends ConfigForm
{
$resourceType = isset($formData['type']) ? $formData['type'] : key($this->resources);
+ if ($resourceType === 'livestatus') {
+ throw new ConfigurationError(
+ 'We\'ve disabled livestatus support for now because it\'s not feature complete yet'
+ );
+ }
+
$resourceTypes = array();
if ($resourceType === 'ido' || array_key_exists('ido', $this->resources)) {
$resourceTypes['ido'] = 'IDO Backend';
}
- if ($resourceType === 'livestatus' || array_key_exists('livestatus', $this->resources)) {
- $resourceTypes['livestatus'] = 'Livestatus';
- }
+// if ($resourceType === 'livestatus' || array_key_exists('livestatus', $this->resources)) {
+// $resourceTypes['livestatus'] = 'Livestatus';
+// }
$this->addElement(
'checkbox',
diff --git a/modules/monitoring/application/forms/Setup/BackendPage.php b/modules/monitoring/application/forms/Setup/BackendPage.php
index d8d4c7fd0..f2df42a1f 100644
--- a/modules/monitoring/application/forms/Setup/BackendPage.php
+++ b/modules/monitoring/application/forms/Setup/BackendPage.php
@@ -51,7 +51,7 @@ class BackendPage extends Form
if (Platform::hasMysqlSupport() || Platform::hasPostgresqlSupport()) {
$resourceTypes['ido'] = 'IDO';
}
- $resourceTypes['livestatus'] = 'Livestatus';
+ // $resourceTypes['livestatus'] = 'Livestatus';
$this->addElement(
'select',
diff --git a/modules/monitoring/application/views/scripts/alertsummary/index.phtml b/modules/monitoring/application/views/scripts/alertsummary/index.phtml
index dbfff6433..3281f3ec8 100644
--- a/modules/monitoring/application/views/scripts/alertsummary/index.phtml
+++ b/modules/monitoring/application/views/scripts/alertsummary/index.phtml
@@ -1,6 +1,9 @@
= $this->tabs ?>
+
+ = $this->translate('Filters'); ?>
+
= $intervalBox; ?>
= $this->widget('limiter') ?>
@@ -8,25 +11,33 @@
-
+
+ = $this->translate('Alert summary'); ?>
+
-
= $this->translate('Notifications and Problems'); ?>
+
+ = $this->translate('Notifications and Problems'); ?>
+
= $defectChart->render(); ?>
-
= $this->translate('Time to Reaction (Ack, Recover)'); ?>
+
+ = $this->translate('Time to Reaction (Ack, Recover)'); ?>
+
= $healingChart->render(); ?>
-
= $this->translate('Trend'); ?>
+
+ = $this->translate('Trend'); ?>
+
@@ -53,7 +64,9 @@
recentAlerts): ?>
-
= $this->translate('Top 5 Recent Alerts'); ?>
+
+ = $this->translate('Top 5 Recent Alerts'); ?>
+
@@ -66,7 +79,9 @@
-
= $this->translate('History'); ?>
+
+ = $this->translate('History'); ?>
+
= $this->partial('list/notifications.phtml', array(
diff --git a/modules/monitoring/application/views/scripts/host/show.phtml b/modules/monitoring/application/views/scripts/host/show.phtml
index 867692301..f490c25f9 100644
--- a/modules/monitoring/application/views/scripts/host/show.phtml
+++ b/modules/monitoring/application/views/scripts/host/show.phtml
@@ -3,6 +3,7 @@
= $this->render('partials/host/servicesummary.phtml') ?>
+
= $this->translate('Host Detail Information') ?>
= $this->render('show/components/output.phtml') ?>
= $this->render('show/components/grapher.phtml') ?>
diff --git a/modules/monitoring/application/views/scripts/list/comments.phtml b/modules/monitoring/application/views/scripts/list/comments.phtml
index 6f49bf4a8..d41399984 100644
--- a/modules/monitoring/application/views/scripts/list/comments.phtml
+++ b/modules/monitoring/application/views/scripts/list/comments.phtml
@@ -1,15 +1,14 @@
compact): ?>
-
- = $this->tabs->render($this); ?>
-
- = $this->translate('Sort by'); ?> = $this->sortControl->render($this); ?>
-
- = $this->widget('limiter', array('url' => $this->url, 'max' => $comments->count())); ?>
- = $this->paginationControl($comments, null, null, array('preserve' => $this->preserve)); ?>
-
+
+ = $this->tabs ?>
+ = $this->sortControl ?>
+ = $this->widget('limiter', array('url' => $this->url, 'max' => $comments->count())); ?>
+ = $this->paginationControl($comments, null, null, array('preserve' => $this->preserve)); ?>
+
+
= $this->translate('Comments') ?>
= $this->translate('No comments matching the filter'); ?>
diff --git a/modules/monitoring/application/views/scripts/list/contactgroups.phtml b/modules/monitoring/application/views/scripts/list/contactgroups.phtml
index a44b388b7..b00e78031 100644
--- a/modules/monitoring/application/views/scripts/list/contactgroups.phtml
+++ b/modules/monitoring/application/views/scripts/list/contactgroups.phtml
@@ -4,6 +4,9 @@
+
+ = $this->translate('Contact Groups'); ?>
+
- = $this->tabs ?>
-
- = $this->sortControl->render($this); ?>
+compact): ?>
+
+ = $this->tabs ?>
+ = $this->sortControl ?>
+ = $this->widget('limiter', array('url' => $this->url, 'max' => $contacts->count())); ?>
+ = $this->paginationControl($contacts, null, null, array('preserve' => $this->preserve)); ?>
- = $this->paginationControl($contacts, null, null, array('preserve' => $this->preserve)); ?>
-
+
+
= $this->translate('Contacts') ?>
translate('No contacts matching the filter');
diff --git a/modules/monitoring/application/views/scripts/list/downtimes.phtml b/modules/monitoring/application/views/scripts/list/downtimes.phtml
index 1fbaa713f..5ad554f99 100644
--- a/modules/monitoring/application/views/scripts/list/downtimes.phtml
+++ b/modules/monitoring/application/views/scripts/list/downtimes.phtml
@@ -4,23 +4,17 @@ use Icinga\Module\Monitoring\Object\Host;
use Icinga\Module\Monitoring\Object\Service;
?>
-
compact): ?>
-
- = $this->tabs->render($this); ?>
-
- = $this->translate('Sort by'); ?> = $this->sortControl->render($this); ?>
- filterEditor): ?>
- = $this->filterPreview ?>
-
-
- = $this->widget('limiter', array('url' => $this->url, 'max' => $downtimes->count())); ?>
- = $this->paginationControl($downtimes, null, null, array('preserve' => $this->preserve)); ?>
-
+
+ = $this->tabs ?>
+ = $this->sortControl ?>
+ = $this->widget('limiter', array('url' => $this->url, 'max' => $downtimes->count())); ?>
+ = $this->paginationControl($downtimes, null, null, array('preserve' => $this->preserve)); ?>
+
-
= $this->filterEditor ?>
+
= $this->translate('Downtimes'); ?>
= $this->translate('No active downtimes'); ?>
diff --git a/modules/monitoring/application/views/scripts/list/eventgrid.phtml b/modules/monitoring/application/views/scripts/list/eventgrid.phtml
index 1af75caf9..6bf0b800b 100644
--- a/modules/monitoring/application/views/scripts/list/eventgrid.phtml
+++ b/modules/monitoring/application/views/scripts/list/eventgrid.phtml
@@ -2,18 +2,21 @@
use Icinga\Data\Filter\Filter;
use Icinga\Web\Widget\Chart\HistoryColorGrid;
?>
-
-
- if (! $compact): ?>
+
= $this->tabs->render($this); ?>
+
+ = $this->translate('Filters'); ?>
+
= $form ?>
- endif; ?>
-
-
+
+
= $this->translate('Event Grid'); ?>
+
+
+
-
compact): ?>
= $this->tabs ?>
-
-
- = $this->translate('Sort by') ?> = $this->sortControl ?>
-
-
-
+ = $this->sortControl ?>
= $this->widget('limiter', array('url' => $this->url, 'max' => $this->history->count())); ?>
= $this->paginationControl($history, null, null, array('preserve' => $this->preserve)); ?>
-
-
-
-= $this->filterEditor ?>
+ = $this->filterEditor ?>
+
= $this->translate('Event History') ?>
+
+
+
+
+
= $this->translate('No history events matching the filter') ?>
diff --git a/modules/monitoring/application/views/scripts/list/hostgroups.phtml b/modules/monitoring/application/views/scripts/list/hostgroups.phtml
index c702197b2..c8f5b2de2 100644
--- a/modules/monitoring/application/views/scripts/list/hostgroups.phtml
+++ b/modules/monitoring/application/views/scripts/list/hostgroups.phtml
@@ -3,14 +3,13 @@
= $this->tabs ?>
-
- = $this->translate('Sort by'); ?> = $this->sortControl->render($this); ?>
-
+ = $this->sortControl->render($this); ?>
= $this->widget('limiter')->setMaxLimit(count($hostgroups)); ?>
= $this->paginationControl($hostgroups, null, null, array('preserve' => $this->preserve)); ?>
= $this->filterEditor; ?>
+
= $this->translate('Host Groups') ?>
compact): ?>
= $this->render('list/components/selectioninfo.phtml') ?>
= $this->render('list/components/hostssummary.phtml') ?>
- = $this->translate('Sort by') ?> = $this->sortControl->render($this) ?>
-
+= $this->sortControl->render($this) ?>
= $this->widget('limiter')->setMaxLimit($this->hosts->count()) ?>
= $this->paginationControl($hosts, null, null, array('preserve' => $this->preserve)) ?>
= $this->selectionToolbar('multi', $this->href('monitoring/hosts/show?' . $this->filter->toQueryString())) ?>
@@ -19,6 +18,7 @@ if ($this->compact): ?>
= $this->filterEditor ?>
+
= $this->translate('Hosts') ?>
count() === 0) {
return;
}
?>
-
-
compact): ?>
= $this->tabs ?>
-
- = $this->translate('Sort by') ?> = $this->sortControl->render($this) ?>
-
+ = $this->sortControl->render($this) ?>
= $this->widget('limiter') ?>
= $this->paginationControl($notifications, null, null, array('preserve' => $this->preserve)) ?>
-
-
+
= $this->translate('Notifications'); ?>
+
+
+
= $this->translate('No notifications matching the filter') ?>
diff --git a/modules/monitoring/application/views/scripts/list/servicegrid.phtml b/modules/monitoring/application/views/scripts/list/servicegrid.phtml
index a102c36eb..d4b5a4074 100644
--- a/modules/monitoring/application/views/scripts/list/servicegrid.phtml
+++ b/modules/monitoring/application/views/scripts/list/servicegrid.phtml
@@ -6,12 +6,11 @@ use Icinga\Module\Monitoring\Object\Service;
compact): ?>
= $this->tabs; ?>
-
- = $this->translate('Sort by'); ?> = $this->sortControl; ?>
-
+ = $this->sortControl; ?>
+
= $this->translate('Service Grid') ?>
= $this->tabs ?>
-
- = $this->translate('Sort by'); ?> = $this->sortControl->render($this); ?>
-
+ = $this->sortControl->render($this); ?>
= $this->widget('limiter')->setMaxLimit(count($servicegroups)); ?>
= $this->paginationControl($servicegroups, null, null, array('preserve' => $this->preserve)); ?>
= $this->filterEditor; ?>
+
= $this->translate('Service Groups') ?>
compact): ?>
= $this->render('list/components/selectioninfo.phtml') ?>
= $this->render('list/components/servicesummary.phtml') ?>
-
-= $this->translate('Sort by') ?> = $this->sortControl ?>
-
+= $this->sortControl ?>
limit === 0): ?>
= $this->widget('limiter') ?>
@@ -24,6 +22,7 @@ if (!$this->compact): ?>
= $this->filterEditor ?>
+
= $this->translate('Services') ?>
diff --git a/modules/monitoring/application/views/scripts/partials/host/objects-header.phtml b/modules/monitoring/application/views/scripts/partials/host/objects-header.phtml
index f5edd0213..f892df6f4 100644
--- a/modules/monitoring/application/views/scripts/partials/host/objects-header.phtml
+++ b/modules/monitoring/application/views/scripts/partials/host/objects-header.phtml
@@ -3,7 +3,9 @@
0): ?>
- = sprintf($this->translatePlural('Host (%u)', 'Hosts (%u)', $hostCount), $hostCount); ?>
+
+ = sprintf($this->translatePlural('Host (%u)', 'Hosts (%u)', $hostCount), $hostCount); ?>
+
= $hostStatesPieChart; ?>
diff --git a/modules/monitoring/application/views/scripts/partials/service/objects-header.phtml b/modules/monitoring/application/views/scripts/partials/service/objects-header.phtml
index 1ac27b934..6389d992f 100644
--- a/modules/monitoring/application/views/scripts/partials/service/objects-header.phtml
+++ b/modules/monitoring/application/views/scripts/partials/service/objects-header.phtml
@@ -4,7 +4,9 @@
0): ?>
- = sprintf($this->translatePlural('Service (%u)', 'Services (%u)', $serviceCount), $serviceCount); ?>
+
+ = sprintf($this->translatePlural('Service (%u)', 'Services (%u)', $serviceCount), $serviceCount); ?>
+
= $serviceStatesPieChart; ?>
diff --git a/modules/monitoring/application/views/scripts/process/info.phtml b/modules/monitoring/application/views/scripts/process/info.phtml
index 92bb6cb63..639b5ebc0 100644
--- a/modules/monitoring/application/views/scripts/process/info.phtml
+++ b/modules/monitoring/application/views/scripts/process/info.phtml
@@ -9,15 +9,23 @@ $cp = $this->checkPerformance()->create($this->checkperformance);
+
+ = $this->translate('Monitoring Health'); ?>
+
+
-
= $this->translate('Feature Commands') ?>
+
+ = $this->translate('Feature Commands') ?>
+
= $this->toggleFeaturesForm ?>
-
= $this->translate('Process Info') ?>
+
+ = $this->translate('Process Info') ?>
+
@@ -68,9 +76,13 @@ $cp = $this->checkPerformance()->create($this->checkperformance);
-
= $this->translate('Performance Info') ?>
+
-
= $this->translate('Object summaries') ?>
+
+ = $this->translate('Object summaries') ?>
+
@@ -118,7 +130,9 @@ $cp = $this->checkPerformance()->create($this->checkperformance);
-
= $this->translate('Active checks') ?>
+
+ = $this->translate('Active checks') ?>
+
@@ -148,7 +162,9 @@ $cp = $this->checkPerformance()->create($this->checkperformance);
-
= $this->translate('Passive checks') ?>
+
+ = $this->translate('Passive checks') ?>
+
diff --git a/modules/monitoring/application/views/scripts/tactical/index.phtml b/modules/monitoring/application/views/scripts/tactical/index.phtml
index 3882b27b3..897ef9776 100644
--- a/modules/monitoring/application/views/scripts/tactical/index.phtml
+++ b/modules/monitoring/application/views/scripts/tactical/index.phtml
@@ -4,6 +4,7 @@
+
= $this->translate('Tactical Overview') ?>
statusSummary->hosts_down || $this->statusSummary->hosts_unreachable): ?>
= $this->render('tactical/components/problem_hosts.phtml'); ?>
diff --git a/modules/monitoring/application/views/scripts/timeline/index.phtml b/modules/monitoring/application/views/scripts/timeline/index.phtml
index 6557b4a28..a9b5666f6 100644
--- a/modules/monitoring/application/views/scripts/timeline/index.phtml
+++ b/modules/monitoring/application/views/scripts/timeline/index.phtml
@@ -10,6 +10,9 @@ $firstRow = !$beingExtended;
= $this->tabs ?>
+
+ = $this->translate('Filters') ?>
+
= $intervalBox; ?>
@@ -22,6 +25,7 @@ $firstRow = !$beingExtended;
+
= $this->translate('Timeline'); ?>
diff --git a/modules/monitoring/public/css/module.less b/modules/monitoring/public/css/module.less
index 387df892b..26cd5bc38 100644
--- a/modules/monitoring/public/css/module.less
+++ b/modules/monitoring/public/css/module.less
@@ -198,3 +198,8 @@ hr.command-separator {
border: none;
border-bottom: 2px solid @colorPetrol;
}
+
+.sort-box {
+ float: right;
+ margin-right: 1em;
+}
\ No newline at end of file
diff --git a/public/css/icinga/menu.less b/public/css/icinga/menu.less
index c33c6670c..3c733db6e 100644
--- a/public/css/icinga/menu.less
+++ b/public/css/icinga/menu.less
@@ -270,7 +270,7 @@ a:focus {
/* Accessibility Skip Links */
.skip-links {
- position: absolute;
+ position: relative;
opacity: 1;
ul {
list-style-type: none;
@@ -286,7 +286,6 @@ a:focus {
left: -999em;
box-sizing: content-box;
width: 10.4em !important;
- top: 0em;
text-align: left !important;
padding: 0.8em;
background-color: white;
@@ -301,5 +300,8 @@ a:focus {
}
}
.skip-links-inline {
- margin-top: -3.5em;
+ ul > li > a {
+ width: 14em !important;
+ top: -3em;
+ }
}
diff --git a/public/js/icinga/behavior/tooltip.js b/public/js/icinga/behavior/tooltip.js
index b08b1f3c1..c9a64257f 100644
--- a/public/js/icinga/behavior/tooltip.js
+++ b/public/js/icinga/behavior/tooltip.js
@@ -27,7 +27,7 @@
var $el = $(this);
$el.attr('title', $el.data('title-rich') || $el.attr('title'));
});
- $('svg rect.chart-data[title]', el).tipsy({ gravity: 'se', html: true });
+ $('svg .chart-data', el).tipsy({ gravity: 'se', html: true });
$('.historycolorgrid a[title]', el).tipsy({ gravity: 's', offset: 2 });
$('img.icon[title]', el).tipsy({ gravity: $.fn.tipsy.autoNS, offset: 2 });
$('[title]', el).tipsy({ gravity: $.fn.tipsy.autoNS, delayIn: 500 });
diff --git a/public/js/icinga/events.js b/public/js/icinga/events.js
index 098aaa88f..39a2a3de4 100644
--- a/public/js/icinga/events.js
+++ b/public/js/icinga/events.js
@@ -337,21 +337,29 @@
handleAnchor: function(query) {
var $element = $(query);
if ($element.length > 0) {
- // Try to find the first header. It is more pleasant to users
- // to select the header instead a container
- var $header = $element.find(':header:first');
- if ($header.length > 0) {
- $element = $header;
- } else {
- var $input = $element.find(':header:first');
- if ($input.length > 0) {
- $element = $input
- }
+ // TODO(mh): Some elements are missing to place the right focus
+ // This is a fixed workarround until all header took place
+
+ var $item = $element.find(':header:first').nextUntil(':header:first').next();
+ if ($item.length > 0) {
+ $element = $item;
}
+
+ /*
+ var focusQueries = ['h1:first', ':header:first', ':input:first'];
+ $.each(focusQueries, function(index,q) {
+ var $item = $element.find(q);
+ if ($item.length > 0) {
+ $element = $item;
+ return false;
+ }
+ });
+ */
+
// If we want to focus an element which has no tabindex
// add one that we can focus is
if ($element.prop('tabindex') < 0) {
- $element.prop('tabindex', 0);
+ $element.prop('tabindex', '-1');
}
$element.focus();
}