mirror of
https://github.com/Icinga/icingaweb2-module-businessprocess.git
synced 2026-02-01 07:59:26 -05:00
Businessprocess/Renderer: prepare new renderers
This commit is contained in:
parent
1f43d2c71c
commit
fbd6aef886
4 changed files with 451 additions and 0 deletions
226
library/Businessprocess/Renderer/Renderer.php
Normal file
226
library/Businessprocess/Renderer/Renderer.php
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Renderer;
|
||||
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\BusinessProcess;
|
||||
use Icinga\Module\Businessprocess\Html\Container;
|
||||
use Icinga\Module\Businessprocess\Html\Element;
|
||||
use Icinga\Module\Businessprocess\Html\Html;
|
||||
use Icinga\Module\Businessprocess\Node;
|
||||
use Icinga\Module\Businessprocess\Renderer\TileRenderer\NodeTile;
|
||||
use Icinga\Module\Businessprocess\Web\Url;
|
||||
use Icinga\Web\View;
|
||||
|
||||
abstract class Renderer extends Html
|
||||
{
|
||||
/** @var View */
|
||||
protected $view;
|
||||
|
||||
/** @var BusinessProcess */
|
||||
protected $bp;
|
||||
|
||||
/** @var BpNode */
|
||||
protected $parent;
|
||||
|
||||
/** @var bool Administrative actions are hidden unless unlocked */
|
||||
protected $locked = true;
|
||||
|
||||
/** @var Url */
|
||||
protected $baseUrl;
|
||||
|
||||
/** @var array */
|
||||
protected $path = array();
|
||||
|
||||
/**
|
||||
* Renderer constructor.
|
||||
*
|
||||
* @param View $view
|
||||
* @param BusinessProcess $bp
|
||||
* @param BpNode|null $parent
|
||||
*/
|
||||
public function __construct(View $view, BusinessProcess $bp, BpNode $parent = null)
|
||||
{
|
||||
$this->bp = $bp;
|
||||
$this->parent = $parent;
|
||||
$this->view = $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BusinessProcess
|
||||
*/
|
||||
public function getBusinessProcess()
|
||||
{
|
||||
return $this->bp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this will render all root nodes
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function wantsRootNodes()
|
||||
{
|
||||
return $this->parent === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this will only render parts of given config
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function rendersSubNode()
|
||||
{
|
||||
return $this->parent !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BpNode[]
|
||||
*/
|
||||
public function getParentNodes()
|
||||
{
|
||||
if ($this->wantsRootNodes()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return $this->parent->getParents();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $summary
|
||||
* @return Container
|
||||
*/
|
||||
public function renderStateBadges($summary)
|
||||
{
|
||||
$container = Container::create(
|
||||
array('class' => 'badges')
|
||||
)/* ->renderIfEmpty(false) */;
|
||||
|
||||
foreach ($summary as $state => $cnt) {
|
||||
if ($cnt === 0
|
||||
|| $state === 'OK'
|
||||
|| $state === 'UP'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$container->addContent(
|
||||
Element::create(
|
||||
'span',
|
||||
array(
|
||||
'class' => array(
|
||||
'badge',
|
||||
'badge-' . strtolower($state)
|
||||
),
|
||||
// TODO: We should translate this in this module
|
||||
'title' => mt('monitoring', $state)
|
||||
)
|
||||
)->setContent($cnt)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
public function getNodeClasses(Node $node)
|
||||
{
|
||||
$classes = array(
|
||||
strtolower($node->getStateName())
|
||||
);
|
||||
|
||||
if ($node->isHandled()) {
|
||||
$classes[] = 'handled';
|
||||
}
|
||||
|
||||
if ($node instanceof BpNode) {
|
||||
$classes[] = 'process-node';
|
||||
} else {
|
||||
$classes[] = 'monitored-node';
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
public function setPath(array $path)
|
||||
{
|
||||
$this->path = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function getMyPath()
|
||||
{
|
||||
$path = $this->getPath();
|
||||
if ($this->rendersSubNode()) {
|
||||
$path[] = (string) $this->parent;
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Url $url
|
||||
* @return $this
|
||||
*/
|
||||
public function setBaseUrl(Url $url)
|
||||
{
|
||||
$this->baseUrl = $url->without(array('config', 'node', 'path'));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Url
|
||||
* @throws ProgrammingError
|
||||
*/
|
||||
public function getBaseUrl()
|
||||
{
|
||||
if ($this->baseUrl === null) {
|
||||
throw new ProgrammingError('Renderer has no baseUrl');
|
||||
}
|
||||
|
||||
return clone($this->baseUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isLocked()
|
||||
{
|
||||
return $this->locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function lock()
|
||||
{
|
||||
$this->locked = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function unlock()
|
||||
{
|
||||
$this->locked = false;
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* Just to be on the safe side
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
unset($this->parent);
|
||||
unset($this->bp);
|
||||
unset($this->view);
|
||||
}
|
||||
}
|
||||
125
library/Businessprocess/Renderer/TileRenderer.php
Normal file
125
library/Businessprocess/Renderer/TileRenderer.php
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Renderer;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\Html\Container;
|
||||
use Icinga\Module\Businessprocess\Html\Element;
|
||||
use Icinga\Module\Businessprocess\Html\Link;
|
||||
use Icinga\Module\Businessprocess\Renderer\TileRenderer\AddNewTile;
|
||||
use Icinga\Module\Businessprocess\Renderer\TileRenderer\NodeTile;
|
||||
|
||||
class TileRenderer extends Renderer
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$bp = $this->bp;
|
||||
$nodesDiv = Container::create(
|
||||
array(
|
||||
'class' => array(
|
||||
'tiles',
|
||||
$this->howMany()
|
||||
),
|
||||
'data-base-target' => '_main',
|
||||
)
|
||||
);
|
||||
|
||||
if ($this->wantsRootNodes()) {
|
||||
$nodes = $bp->getChildren();
|
||||
} else {
|
||||
$nodes = $this->parent->getChildren();
|
||||
}
|
||||
|
||||
if (! $this->isLocked()) {
|
||||
$this->add(new AddNewTile($this));
|
||||
}
|
||||
|
||||
foreach ($nodes as $name => $node) {
|
||||
$this->add(new NodeTile($this, $name, $node));
|
||||
}
|
||||
|
||||
$nodesDiv->addContent($this->getContent());
|
||||
$this->setContent($this->renderBreadCrumb())
|
||||
->addContent($nodesDiv);
|
||||
|
||||
return parent::render();
|
||||
}
|
||||
|
||||
public function renderBreadCrumb()
|
||||
{
|
||||
$breadcrumb = Element::create('ul', array('class' => 'breadcrumb'));
|
||||
$breadcrumb = Element::create( 'ul', array(
|
||||
'class' => 'breadcrumb',
|
||||
'data-base-target' => '_main'
|
||||
));
|
||||
|
||||
|
||||
$breadcrumb->add(Element::create('li')->add(
|
||||
Link::create('Process', $this->getBaseUrl()))
|
||||
);
|
||||
$bp = $this->bp;
|
||||
$path = $this->getMyPath();
|
||||
$max = 20;
|
||||
$chosen = array();
|
||||
for ($i = 1; $i <= $max; $i++) {
|
||||
if (! empty($path)) {
|
||||
$chosen[] = array_pop($path);
|
||||
}
|
||||
}
|
||||
$chosen = array_reverse($chosen);
|
||||
$consumed = array();
|
||||
while ($parent = array_shift($chosen)) {
|
||||
$breadcrumb->add($this->renderParent($bp->getNode($parent), $consumed));
|
||||
$consumed[] = $parent;
|
||||
}
|
||||
|
||||
return $breadcrumb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BpNode $parent
|
||||
*/
|
||||
public function renderParent(BpNode $parent, $path)
|
||||
{
|
||||
$p = new NodeTile($this, (string) $parent, $parent, $path);
|
||||
$p->attributes()->add('class', $this->getNodeClasses($parent));
|
||||
$p->setTag('li');
|
||||
return $p;
|
||||
// $p->attributes()->add('class', 'parent');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDefaultAttributes()
|
||||
{
|
||||
return array(
|
||||
'class' => 'tiles aaaa' . $this->howMany()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A CSS class giving a rough indication of how many nodes we have
|
||||
*
|
||||
* This is used to show larger tiles when there are few and smaller
|
||||
* ones if there are many.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function howMany()
|
||||
{
|
||||
$count = $this->bp->countChildren();
|
||||
$howMany = 'normal';
|
||||
|
||||
if ($count < 20) {
|
||||
$howMany = 'few';
|
||||
} elseif ($count > 50) {
|
||||
$howMany = 'many';
|
||||
}
|
||||
|
||||
return $howMany;
|
||||
}
|
||||
}
|
||||
47
library/Businessprocess/Renderer/TileRenderer/AddNewTile.php
Normal file
47
library/Businessprocess/Renderer/TileRenderer/AddNewTile.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Renderer\TileRenderer;
|
||||
|
||||
use Icinga\Module\Businessprocess\BusinessProcess;
|
||||
use Icinga\Module\Businessprocess\Html\BaseElement;
|
||||
use Icinga\Module\Businessprocess\Html\Link;
|
||||
use Icinga\Module\Businessprocess\Renderer\Renderer;
|
||||
use Icinga\Module\Businessprocess\Web\Url;
|
||||
|
||||
class AddNewTile extends BaseElement
|
||||
{
|
||||
protected $tag = 'div';
|
||||
|
||||
protected $node;
|
||||
|
||||
protected $defaultAttributes = array('class' => 'addnew');
|
||||
|
||||
public function __construct(Renderer $renderer)
|
||||
{
|
||||
$bp = $renderer->getBusinessProcess();
|
||||
$path = $renderer->getMyPath();
|
||||
|
||||
$params = array(
|
||||
'config' => $bp->getName()
|
||||
);
|
||||
|
||||
// Workaround for array issues
|
||||
$url = Url::fromPath('businessprocess/process/create');
|
||||
$p = $url->getParams();
|
||||
$p->mergeValues($params);
|
||||
if (! empty($path)) {
|
||||
$p->addValues('path', $path);
|
||||
}
|
||||
|
||||
$this->add(
|
||||
Link::create(
|
||||
$this->translate('Add'),
|
||||
$url,
|
||||
null,
|
||||
array(
|
||||
'title' => $this->translate('Add a new business process node')
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
53
library/Businessprocess/Renderer/TileRenderer/NodeTile.php
Normal file
53
library/Businessprocess/Renderer/TileRenderer/NodeTile.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Renderer\TileRenderer;
|
||||
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\Html\BaseElement;
|
||||
use Icinga\Module\Businessprocess\Html\Link;
|
||||
use Icinga\Module\Businessprocess\ImportedNode;
|
||||
use Icinga\Module\Businessprocess\MonitoredNode;
|
||||
use Icinga\Module\Businessprocess\Node;
|
||||
use Icinga\Module\Businessprocess\Renderer\TileRenderer;
|
||||
|
||||
class NodeTile extends BaseElement
|
||||
{
|
||||
protected $tag = 'div';
|
||||
|
||||
public function __construct(TileRenderer $renderer, $name, Node $node, $path = null)
|
||||
{
|
||||
$attributes = $this->attributes();
|
||||
$attributes->add('class', $renderer->getNodeClasses($node));
|
||||
$attributes->add('id', 'bp-' . (string) $node);
|
||||
|
||||
if ($node instanceof MonitoredNode) {
|
||||
$attributes->add('data-base-target', '_next');
|
||||
$url = $node->getUrl();
|
||||
} else {
|
||||
$bp = $renderer->getBusinessProcess();
|
||||
$params = array(
|
||||
'config' => $node instanceof ImportedNode ?
|
||||
$node->getConfigName() :
|
||||
$bp->getName()
|
||||
);
|
||||
|
||||
if ($name !== null) {
|
||||
$params['node'] = $name;
|
||||
}
|
||||
|
||||
$url = $renderer->getBaseUrl();
|
||||
$p = $url->getParams();
|
||||
$p->mergeValues($params);
|
||||
if (! empty($path)) {
|
||||
$p->addValues('path', $path);
|
||||
}
|
||||
}
|
||||
|
||||
$link = Link::create($node->getAlias(), $url);
|
||||
|
||||
$this->add($link);
|
||||
if ($node instanceof BpNode) {
|
||||
$link->addContent($renderer->renderStateBadges($node->getStateSummary()));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue