icingaweb2-module-businessp.../library/Businessprocess/Renderer/TreeRenderer.php

314 lines
10 KiB
PHP
Raw Normal View History

<?php
namespace Icinga\Module\Businessprocess\Renderer;
2019-01-22 05:44:05 -05:00
use Icinga\Date\DateFormatter;
2017-01-11 08:04:45 -05:00
use Icinga\Module\Businessprocess\BpConfig;
use Icinga\Module\Businessprocess\BpNode;
use Icinga\Module\Businessprocess\ImportedNode;
use Icinga\Module\Businessprocess\Node;
use Icinga\Module\Businessprocess\Web\Component\StateBall;
use Icinga\Module\Businessprocess\Web\Form\CsrfToken;
use ipl\Html\BaseHtmlElement;
use ipl\Html\Html;
class TreeRenderer extends Renderer
{
/**
* @inheritdoc
*/
public function render()
{
2017-01-11 08:33:35 -05:00
$bp = $this->config;
2019-01-22 05:44:05 -05:00
$htmlId = $bp->getHtmlId();
$tree = Html::tag(
'ul',
[
2019-01-22 05:44:05 -05:00
'id' => $htmlId,
'class' => ['bp', 'sortable', $this->wantsRootNodes() ? '' : 'process'],
'data-sortable-disabled' => $this->isLocked() ? 'true' : 'false',
'data-sortable-data-id-attr' => 'id',
'data-sortable-direction' => 'vertical',
'data-sortable-group' => json_encode([
2019-01-22 05:44:05 -05:00
'name' => $this->wantsRootNodes() ? 'root' : $htmlId,
'put' => 'function:rowPutAllowed'
]),
'data-sortable-invert-swap' => 'true',
2019-01-22 05:44:05 -05:00
'data-is-root-config' => $this->wantsRootNodes() ? 'true' : 'false',
'data-csrf-token' => CsrfToken::generate()
],
$this->renderBp($bp)
);
if ($this->wantsRootNodes()) {
$tree->getAttributes()->add(
'data-action-url',
$this->getUrl()->setParams(['config' => $bp->getName()])->getAbsoluteUrl()
);
} else {
$nodeName = $this->parent instanceof ImportedNode
? $this->parent->getNodeName()
: $this->parent->getName();
$tree->getAttributes()
->add('data-node-name', $nodeName)
->add('data-action-url', $this->getUrl()
->setParams([
'config' => $this->parent->getBpConfig()->getName(),
'node' => $nodeName
])
->getAbsoluteUrl());
}
$this->add($tree);
return parent::render();
}
/**
2017-01-11 08:04:45 -05:00
* @param BpConfig $bp
* @return string
*/
2017-01-11 08:04:45 -05:00
public function renderBp(BpConfig $bp)
{
$html = array();
if ($this->wantsRootNodes()) {
$nodes = $bp->getChildren();
} else {
$nodes = $this->parent->getChildren();
}
foreach ($nodes as $name => $node) {
if ($node instanceof BpNode) {
$html[] = $this->renderNode($bp, $node);
} else {
$html[] = $this->renderChild($bp, $node);
}
}
return $html;
}
protected function getStateClassNames(Node $node)
{
$state = strtolower($node->getStateName());
if ($node->isMissing()) {
return array('missing');
} elseif ($state === 'ok') {
if ($node->hasMissingChildren()) {
return array('ok', 'missing-children');
} else {
return array('ok');
}
} else {
return array('problem', $state);
}
}
/**
* @param Node $node
2019-01-22 05:44:05 -05:00
* @param array $path
* @return BaseHtmlElement[]
*/
2019-01-22 05:44:05 -05:00
public function getNodeIcons(Node $node, array $path = null)
{
2019-01-22 05:44:05 -05:00
$icons = [];
if (empty($path) && $node instanceof BpNode) {
2019-01-22 05:44:05 -05:00
$icons[] = Html::tag('i', ['class' => 'icon icon-sitemap']);
} else {
$icons[] = $node->getIcon();
}
$icons[] = (new StateBall(strtolower($node->getStateName())))->addAttributes([
'title' => sprintf(
'%s %s',
$node->getStateName(),
DateFormatter::timeSince($node->getLastStateChange())
)
]);
if ($node->isInDowntime()) {
$icons[] = Html::tag('i', ['class' => 'icon icon-moon']);
}
if ($node->isAcknowledged()) {
$icons[] = Html::tag('i', ['class' => 'icon icon-ok']);
}
return $icons;
}
/**
2017-01-11 08:04:45 -05:00
* @param BpConfig $bp
* @param Node $node
* @param array $path
*
* @return string
*/
2017-01-11 08:04:45 -05:00
public function renderNode(BpConfig $bp, Node $node, $path = array())
{
2019-01-16 07:38:30 -05:00
$htmlId = $this->getId($node, $path);
2019-01-22 05:44:05 -05:00
$li = Html::tag(
'li',
[
2019-01-16 07:38:30 -05:00
'id' => $htmlId,
'class' => ['bp', 'movable', $node->getObjectClassName()],
'data-node-name' => $node->getName()
]
);
2019-01-22 05:44:05 -05:00
$attributes = $li->getAttributes();
$attributes->add('class', $this->getStateClassNames($node));
if ($node->isHandled()) {
$attributes->add('class', 'handled');
}
if ($node instanceof BpNode) {
$attributes->add('class', 'operator');
} else {
$attributes->add('class', 'node');
}
2019-01-22 05:44:05 -05:00
$div = Html::tag('div');
$li->add($div);
2019-01-22 05:44:05 -05:00
$div->add($node->getLink());
$div->add($this->getNodeIcons($node, $path));
2019-01-22 05:44:05 -05:00
$div->add(Html::tag('span', null, $node->getAlias()));
2019-01-22 05:44:05 -05:00
if ($node instanceof BpNode) {
$div->add(Html::tag('span', ['class' => 'op'], $node->operatorHtml()));
}
if ($node instanceof BpNode && $node->hasInfoUrl()) {
$div->add($this->createInfoAction($node));
}
if (! $this->isLocked() && $node->getBpConfig()->getName() === $this->getBusinessProcess()->getName()) {
2019-01-22 05:44:05 -05:00
$div->add($this->getActionIcons($bp, $node));
}
2019-01-22 05:44:05 -05:00
$ul = Html::tag('ul', [
'class' => ['bp', 'sortable'],
2019-02-14 09:32:51 -05:00
'data-sortable-disabled' => (
$this->isLocked() || $node->getBpConfig()->getName() !== $this->getBusinessProcess()->getName()
) ? 'true' : 'false',
2019-01-22 05:44:05 -05:00
'data-sortable-invert-swap' => 'true',
'data-sortable-data-id-attr' => 'id',
'data-sortable-draggable' => '.movable',
'data-sortable-direction' => 'vertical',
'data-sortable-group' => json_encode([
2019-01-16 07:38:30 -05:00
'name' => $htmlId, // Unique, so that the function below is the only deciding factor
'put' => 'function:rowPutAllowed'
]),
'data-csrf-token' => CsrfToken::generate(),
'data-action-url' => $this->getUrl()
->setParams([
'config' => $node->getBpConfig()->getName(),
'node' => $node instanceof ImportedNode
? $node->getNodeName()
2019-02-21 05:32:32 -05:00
: $node->getName()
])
->getAbsoluteUrl()
]);
2019-01-22 05:44:05 -05:00
$li->add($ul);
$path[] = $node->getIdentifier();
foreach ($node->getChildren() as $name => $child) {
if ($child instanceof BpNode) {
2019-01-22 05:44:05 -05:00
$ul->add($this->renderNode($bp, $child, $path));
} else {
2019-01-22 05:44:05 -05:00
$ul->add($this->renderChild($bp, $child, $path));
}
}
2019-01-22 05:44:05 -05:00
return $li;
}
protected function renderChild($bp, Node $node, $path = null)
{
$li = Html::tag('li', [
'class' => 'movable',
'id' => $this->getId($node, $path ?: []),
2019-02-21 05:32:32 -05:00
'data-node-name' => $node->getName()
]);
2019-01-22 05:44:05 -05:00
$li->add($this->getNodeIcons($node, $path));
$link = $node->getLink();
$link->getAttributes()->set('data-base-target', '_next');
2019-01-22 05:44:05 -05:00
$li->add($link);
if (! $this->isLocked() && $node->getBpConfig()->getName() === $this->getBusinessProcess()->getName()) {
2019-01-22 05:44:05 -05:00
$li->add($this->getActionIcons($bp, $node));
}
return $li;
}
2017-01-11 08:04:45 -05:00
protected function getActionIcons(BpConfig $bp, Node $node)
{
if ($node instanceof BpNode) {
if ($bp->getMetadata()->canModify()) {
return [$this->createEditAction($bp, $node), $this->renderAddNewNode($node)];
} else {
return '';
}
} else {
return $this->createSimulationAction($bp, $node);
}
}
2017-01-11 08:04:45 -05:00
protected function createEditAction(BpConfig $bp, BpNode $node)
{
return $this->actionIcon(
2019-01-22 05:44:05 -05:00
'edit',
$this->getUrl()->with(array(
'action' => 'edit',
'editnode' => $node->getName()
)),
mt('businessprocess', 'Modify this node')
);
}
2017-01-11 08:04:45 -05:00
protected function createSimulationAction(BpConfig $bp, Node $node)
{
return $this->actionIcon(
'magic',
2016-11-30 08:35:13 -05:00
$this->getUrl()->with(array(
//'config' => $bp->getName(),
'action' => 'simulation',
'simulationnode' => $node->getName()
)),
mt('businessprocess', 'Simulate a specific state')
);
}
protected function createInfoAction(BpNode $node)
{
$url = $node->getInfoUrl();
return $this->actionIcon(
'help',
$url,
sprintf('%s: %s', mt('businessprocess', 'More information'), $url)
);
}
protected function actionIcon($icon, $url, $title)
{
return Html::tag(
'a',
[
'href' => $url,
'title' => $title,
2019-01-22 05:44:05 -05:00
'class' => 'action-link'
],
Html::tag('i', ['class' => 'icon icon-' . $icon])
);
}
2016-11-29 10:58:03 -05:00
protected function renderAddNewNode($parent)
{
return $this->actionIcon(
'plus',
$this->getUrl()
->with('action', 'add')
->with('node', $parent->getName()),
mt('businessprocess', 'Add a new business process node')
2016-11-29 10:58:03 -05:00
);
}
}