mirror of
https://github.com/Icinga/icingaweb2-module-businessprocess.git
synced 2026-02-17 01:41:44 -05:00
Merge pull request #305 from Icinga/fix/redesign-state-badge-widget
Redesign state badge widget on tiles
This commit is contained in:
commit
5ccc13c862
6 changed files with 118 additions and 100 deletions
|
|
@ -6,6 +6,9 @@ Requirements
|
||||||
|
|
||||||
* Icinga Web 2 (>= 2.9)
|
* Icinga Web 2 (>= 2.9)
|
||||||
* PHP (>= 7.2)
|
* PHP (>= 7.2)
|
||||||
|
* Icinga Web 2 libraries:
|
||||||
|
* [Icinga PHP Library (ipl)](https://github.com/Icinga/icinga-php-library) (>= 0.8)
|
||||||
|
* [Icinga PHP Thirdparty](https://github.com/Icinga/icinga-php-thirdparty) (>= 0.11)
|
||||||
* Icinga Web 2 modules:
|
* Icinga Web 2 modules:
|
||||||
* The `monitoring` or `icingadb` module needs to be configured and enabled.
|
* The `monitoring` or `icingadb` module needs to be configured and enabled.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,15 +30,15 @@ class BpNode extends Node
|
||||||
protected $stateOverrides = [];
|
protected $stateOverrides = [];
|
||||||
|
|
||||||
protected static $emptyStateSummary = array(
|
protected static $emptyStateSummary = array(
|
||||||
'OK' => 0,
|
'CRITICAL' => 0,
|
||||||
'WARNING' => 0,
|
'CRITICAL-HANDLED' => 0,
|
||||||
'CRITICAL' => 0,
|
'WARNING' => 0,
|
||||||
'UNKNOWN' => 0,
|
'WARNING-HANDLED' => 0,
|
||||||
'PENDING' => 0,
|
'UNKNOWN' => 0,
|
||||||
'UP' => 0,
|
'UNKNOWN-HANDLED' => 0,
|
||||||
'DOWN' => 0,
|
'OK' => 0,
|
||||||
'UNREACHABLE' => 0,
|
'PENDING' => 0,
|
||||||
'MISSING' => 0,
|
'MISSING' => 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
protected static $sortStateInversionMap = array(
|
protected static $sortStateInversionMap = array(
|
||||||
|
|
@ -65,16 +65,27 @@ class BpNode extends Node
|
||||||
$this->counters = self::$emptyStateSummary;
|
$this->counters = self::$emptyStateSummary;
|
||||||
|
|
||||||
foreach ($this->getChildren() as $child) {
|
foreach ($this->getChildren() as $child) {
|
||||||
if ($child instanceof BpNode) {
|
if ($child->isMissing()) {
|
||||||
$counters = $child->getStateSummary();
|
|
||||||
foreach ($counters as $k => $v) {
|
|
||||||
$this->counters[$k] += $v;
|
|
||||||
}
|
|
||||||
} elseif ($child->isMissing()) {
|
|
||||||
$this->counters['MISSING']++;
|
$this->counters['MISSING']++;
|
||||||
} else {
|
} else {
|
||||||
$state = $child->getStateName($this->getChildState($child));
|
$state = $child->getStateName($this->getChildState($child));
|
||||||
$this->counters[$state]++;
|
if ($child->isHandled() && ($state !== 'UP' && $state !== 'OK')) {
|
||||||
|
$state = $state . '-HANDLED';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($state === 'DOWN') {
|
||||||
|
$this->counters['CRITICAL']++;
|
||||||
|
} elseif ($state === 'DOWN-HANDLED') {
|
||||||
|
$this->counters['CRITICAL-HANDLED']++;
|
||||||
|
} elseif ($state === 'UNREACHABLE') {
|
||||||
|
$this->counters['UNKNOWN']++;
|
||||||
|
} elseif ($state === 'UNREACHABLE-HANDLED') {
|
||||||
|
$this->counters['UNKNOWN-HANDLED']++;
|
||||||
|
} elseif ($state === 'UP') {
|
||||||
|
$this->counters['OK']++;
|
||||||
|
} else {
|
||||||
|
$this->counters[$state]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ use Icinga\Module\Businessprocess\Web\Url;
|
||||||
use ipl\Html\BaseHtmlElement;
|
use ipl\Html\BaseHtmlElement;
|
||||||
use ipl\Html\Html;
|
use ipl\Html\Html;
|
||||||
use ipl\Html\HtmlDocument;
|
use ipl\Html\HtmlDocument;
|
||||||
|
use ipl\Web\Widget\StateBadge;
|
||||||
|
|
||||||
abstract class Renderer extends HtmlDocument
|
abstract class Renderer extends HtmlDocument
|
||||||
{
|
{
|
||||||
|
|
@ -135,34 +136,31 @@ abstract class Renderer extends HtmlDocument
|
||||||
* @param $summary
|
* @param $summary
|
||||||
* @return BaseHtmlElement
|
* @return BaseHtmlElement
|
||||||
*/
|
*/
|
||||||
public function renderStateBadges($summary)
|
public function renderStateBadges($summary, $totalChildren)
|
||||||
{
|
{
|
||||||
$elements = [];
|
$elements = [];
|
||||||
|
|
||||||
foreach ($summary as $state => $cnt) {
|
$itemCount = Html::tag(
|
||||||
if ($cnt === 0
|
'span',
|
||||||
|| $state === 'OK'
|
[
|
||||||
|| $state === 'UP'
|
'class' => [
|
||||||
) {
|
'item-count',
|
||||||
continue;
|
]
|
||||||
}
|
],
|
||||||
|
sprintf(mtp('businessprocess', '%u Child', '%u Children', $totalChildren), $totalChildren)
|
||||||
|
);
|
||||||
|
|
||||||
$elements[] = Html::tag(
|
$elements[] = array_filter([
|
||||||
'span',
|
$this->createBadgeGroup($summary, 'CRITICAL'),
|
||||||
[
|
$this->createBadgeGroup($summary, 'UNKNOWN'),
|
||||||
'class' => [
|
$this->createBadgeGroup($summary, 'WARNING'),
|
||||||
'badge',
|
$this->createBadge($summary, 'MISSING'),
|
||||||
'badge-' . strtolower($state)
|
$this->createBadge($summary, 'PENDING')
|
||||||
],
|
]);
|
||||||
// TODO: We should translate this in this module
|
|
||||||
'title' => mt('monitoring', $state)
|
|
||||||
],
|
|
||||||
$cnt
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($elements)) {
|
if (!empty($elements)) {
|
||||||
$container = Html::tag('div', ['class' => 'badges']);
|
$container = Html::tag('ul', ['class' => 'state-badges']);
|
||||||
|
$container->add($itemCount);
|
||||||
foreach ($elements as $element) {
|
foreach ($elements as $element) {
|
||||||
$container->add($element);
|
$container->add($element);
|
||||||
}
|
}
|
||||||
|
|
@ -172,6 +170,33 @@ abstract class Renderer extends HtmlDocument
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function createBadge($summary, $state)
|
||||||
|
{
|
||||||
|
if ($summary[$state] !== 0) {
|
||||||
|
return Html::tag('li', new StateBadge($summary[$state], strtolower($state)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createBadgeGroup($summary, $state)
|
||||||
|
{
|
||||||
|
$content = [];
|
||||||
|
if ($summary[$state] !== 0) {
|
||||||
|
$content[] = Html::tag('li', new StateBadge($summary[$state], strtolower($state)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($summary[$state . '-HANDLED'] !== 0) {
|
||||||
|
$content[] = Html::tag('li', new StateBadge($summary[$state . '-HANDLED'], strtolower($state), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($content)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Html::tag('li', Html::tag('ul', $content));
|
||||||
|
}
|
||||||
|
|
||||||
public function getNodeClasses(Node $node)
|
public function getNodeClasses(Node $node)
|
||||||
{
|
{
|
||||||
if ($node->isMissing()) {
|
if ($node->isMissing()) {
|
||||||
|
|
|
||||||
|
|
@ -129,24 +129,7 @@ class NodeTile extends BaseHtmlElement
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($node instanceof BpNode && !$renderer->isBreadcrumb()) {
|
if ($node instanceof BpNode && !$renderer->isBreadcrumb()) {
|
||||||
$this->add(Html::tag(
|
$this->add($renderer->renderStateBadges($node->getStateSummary(), $node->countChildren()));
|
||||||
'p',
|
|
||||||
['class' => 'children-count'],
|
|
||||||
$node->hasChildren()
|
|
||||||
? Html::tag(
|
|
||||||
'span',
|
|
||||||
null,
|
|
||||||
sprintf('%u %s', $node->countChildren(), mtp(
|
|
||||||
'businessprocess',
|
|
||||||
'Child',
|
|
||||||
'Children',
|
|
||||||
$node->countChildren(),
|
|
||||||
'businessprocess.nodes'
|
|
||||||
))
|
|
||||||
)
|
|
||||||
: null
|
|
||||||
));
|
|
||||||
$this->add($renderer->renderStateBadges($node->getStateSummary()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::render();
|
return parent::render();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
Name: Businessprocess
|
Name: Businessprocess
|
||||||
Version: 2.3.1
|
Version: 2.3.1
|
||||||
Depends: monitoring (>= 2.4.1), icingadb (>= 1.0.0), ipl (>= 0.5.0)
|
Requires:
|
||||||
|
Libraries: icinga-php-library (>=0.8.0), icinga-php-thirdparty (>=0.11.0)
|
||||||
|
Modules: monitoring (>=2.4.1), icingadb (>= 1.0.0)
|
||||||
Description: A Business Process viewer and modeler
|
Description: A Business Process viewer and modeler
|
||||||
Provides a web-based process modeler for. It integrates as a module into
|
Provides a web-based process modeler for. It integrates as a module into
|
||||||
Icinga Web 2 and provides a plugin check command for Icinga. Tile and tree
|
Icinga Web 2 and provides a plugin check command for Icinga. Tile and tree
|
||||||
|
|
|
||||||
|
|
@ -330,19 +330,6 @@ ul.bp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge {
|
|
||||||
margin-top: 0.25em;
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: 0px 0px 5px @gray-light;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-tile,
|
.dashboard-tile,
|
||||||
|
|
@ -376,35 +363,49 @@ ul.bp {
|
||||||
}
|
}
|
||||||
/** END Dashboard **/
|
/** END Dashboard **/
|
||||||
|
|
||||||
/** BEGIN Badges **/
|
// State summary badges
|
||||||
.badges {
|
.state-badges {
|
||||||
background-color: fade(@body-bg-color, 50%);
|
.state-badges();
|
||||||
border-radius: 0.45em;
|
|
||||||
display: block;
|
|
||||||
padding: 0.3em 0.4em;
|
|
||||||
|
|
||||||
.badge {
|
&.state-badges li > ul > li:last-child {
|
||||||
border: 1px solid @body-bg-color;
|
margin-left: 0;
|
||||||
margin: 0;
|
}
|
||||||
|
|
||||||
|
li > ul > li:first-child:not(:last-child) .state-badge {
|
||||||
|
border-right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
div.bp .badges {
|
// Node children count
|
||||||
|
.item-count {
|
||||||
|
font-size: 1em;
|
||||||
|
text-align: center;
|
||||||
|
color: @text-color-inverted;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.bp .state-badges {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td > a > .state-badges {
|
||||||
|
|
||||||
td > a > .badges {
|
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge-critical, .badge-down { background: @color-critical; }
|
.state-badge {
|
||||||
.badge-unknown, .badge-unreachable { background: @color-unknown; }
|
font-size: .8em;
|
||||||
.badge-warning { background: @color-warning }
|
border: 1px solid @body-bg-color;
|
||||||
.badge-pending { background: @color-pending }
|
|
||||||
.badge-missing { background: @gray-semilight; color: @text-color-on-icinga-blue; }
|
&.state-missing {
|
||||||
|
background: @gray-semilight;
|
||||||
|
color: @text-color-on-icinga-blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.state-critical.handled, &.state-down.handled { background: @color-critical-handled; opacity: 1; }
|
||||||
|
&.state-unknown.handled { background-color: @color-unknown-handled; opacity: 1; }
|
||||||
|
&.state-warning.handled { background: @color-warning-handled; opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
/** END Badges **/
|
/** END Badges **/
|
||||||
|
|
||||||
/** BEGIN Tiles **/
|
/** BEGIN Tiles **/
|
||||||
|
|
@ -431,7 +432,11 @@ td > a > .badges {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.badges {
|
.item-count {
|
||||||
|
margin-right: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.state-badges {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
|
@ -457,17 +462,6 @@ td > a > .badges {
|
||||||
padding: 1em 1em 0;
|
padding: 1em 1em 0;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
|
||||||
& + p.children-count {
|
|
||||||
margin: 0;
|
|
||||||
font-size: .5em;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: .8em;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue