TreeRenderer: Restructure node layout

This commit is contained in:
Johannes Meyer 2019-01-22 11:44:05 +01:00
parent bb62fe7048
commit d880291c02
3 changed files with 52 additions and 65 deletions

View file

@ -386,7 +386,9 @@ abstract class Node
public function getLink() public function getLink()
{ {
return Html::tag('a', ['href' => '#'], $this->getAlias()); return Html::tag('a', ['href' => '#', 'class' => 'toggle'], Html::tag('i', [
'class' => 'icon icon-down-dir'
]));
} }
public function getIcon() public function getIcon()

View file

@ -298,22 +298,6 @@ abstract class Renderer extends HtmlDocument
return $this->isBreadcrumb; return $this->isBreadcrumb;
} }
public function timeSince($time, $timeOnly = false)
{
if (! $time) {
return HtmlString::create('');
}
return Html::tag(
'span',
[
'class' => ['relative-time', 'time-since'],
'title' => DateFormatter::formatDateTime($time)
],
DateFormatter::timeSince($time, $timeOnly)
);
}
protected function createUnboundParent(BpConfig $bp) protected function createUnboundParent(BpConfig $bp)
{ {
return $bp->getNode('__unbound__'); return $bp->getNode('__unbound__');

View file

@ -2,12 +2,14 @@
namespace Icinga\Module\Businessprocess\Renderer; namespace Icinga\Module\Businessprocess\Renderer;
use Icinga\Date\DateFormatter;
use Icinga\Module\Businessprocess\BpNode; use Icinga\Module\Businessprocess\BpNode;
use Icinga\Module\Businessprocess\BpConfig; use Icinga\Module\Businessprocess\BpConfig;
use Icinga\Module\Businessprocess\Node; use Icinga\Module\Businessprocess\Node;
use Icinga\Module\Businessprocess\Web\Form\CsrfToken; use Icinga\Module\Businessprocess\Web\Form\CsrfToken;
use ipl\Html\BaseHtmlElement; use ipl\Html\BaseHtmlElement;
use ipl\Html\Html; use ipl\Html\Html;
use ipl\Web\Widget\StateBall;
class TreeRenderer extends Renderer class TreeRenderer extends Renderer
{ {
@ -17,19 +19,21 @@ class TreeRenderer extends Renderer
public function render() public function render()
{ {
$bp = $this->config; $bp = $this->config;
$htmlId = $bp->getHtmlId();
$this->add(Html::tag( $this->add(Html::tag(
'ul', 'ul',
[ [
'id' => $bp->getHtmlId(), 'id' => $htmlId,
'class' => ['tree', 'sortable'], 'class' => ['bp', 'sortable'],
'data-sortable-disabled' => $this->isLocked() ? 'true' : 'false', 'data-sortable-disabled' => $this->isLocked() ? 'true' : 'false',
'data-sortable-data-id-attr' => 'id', 'data-sortable-data-id-attr' => 'id',
'data-sortable-direction' => 'vertical', 'data-sortable-direction' => 'vertical',
'data-sortable-group' => json_encode([ 'data-sortable-group' => json_encode([
'name' => 'root', 'name' => $this->wantsRootNodes() ? 'root' : $htmlId,
'put' => 'function:rowPutAllowed' 'put' => 'function:rowPutAllowed'
]), ]),
'data-sortable-invert-swap' => 'true', 'data-sortable-invert-swap' => 'true',
'data-is-root-config' => $this->wantsRootNodes() ? 'true' : 'false',
'data-csrf-token' => CsrfToken::generate(), 'data-csrf-token' => CsrfToken::generate(),
'data-action-url' => $this->getUrl()->getAbsoluteUrl() 'data-action-url' => $this->getUrl()->getAbsoluteUrl()
], ],
@ -92,11 +96,24 @@ class TreeRenderer extends Renderer
/** /**
* @param Node $node * @param Node $node
* @param array $path
* @return BaseHtmlElement[] * @return BaseHtmlElement[]
*/ */
public function getNodeIcons(Node $node) public function getNodeIcons(Node $node, array $path = null)
{ {
$icons = array(); $icons = [];
if (empty($path)) {
$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()) { if ($node->isInDowntime()) {
$icons[] = Html::tag('i', ['class' => 'icon icon-moon']); $icons[] = Html::tag('i', ['class' => 'icon icon-moon']);
} }
@ -116,7 +133,7 @@ class TreeRenderer extends Renderer
public function renderNode(BpConfig $bp, Node $node, $path = array()) public function renderNode(BpConfig $bp, Node $node, $path = array())
{ {
$htmlId = $this->getId($node, $path); $htmlId = $this->getId($node, $path);
$table = Html::tag( $li = Html::tag(
'li', 'li',
[ [
'id' => $htmlId, 'id' => $htmlId,
@ -124,7 +141,7 @@ class TreeRenderer extends Renderer
'data-node-name' => $node->getName() 'data-node-name' => $node->getName()
] ]
); );
$attributes = $table->getAttributes(); $attributes = $li->getAttributes();
$attributes->add('class', $this->getStateClassNames($node)); $attributes->add('class', $this->getStateClassNames($node));
if ($node->isHandled()) { if ($node->isHandled()) {
$attributes->add('class', 'handled'); $attributes->add('class', 'handled');
@ -135,41 +152,30 @@ class TreeRenderer extends Renderer
$attributes->add('class', 'node'); $attributes->add('class', 'node');
} }
if ($node instanceof BpNode) { $div = Html::tag('div');
$table->add(Html::tag('span', ['class' => 'op'], $node->operatorHtml())); $li->add($div);
}
$td = Html::tag('div'); $div->add($node->getLink());
$table->add($td); $div->add($this->getNodeIcons($node, $path));
if ($node instanceof BpNode && $node->hasInfoUrl()) { if ($node instanceof BpNode && $node->hasInfoUrl()) {
$td->add($this->createInfoAction($node)); $div->add($this->createInfoAction($node));
}
$div->add(Html::tag('span', null, $node->getAlias()));
if ($node instanceof BpNode) {
$div->add(Html::tag('span', ['class' => 'op'], $node->operatorHtml()));
} }
if (! $this->isLocked()) { if (! $this->isLocked()) {
$td->add($this->getActionIcons($bp, $node)); $div->add($this->getActionIcons($bp, $node));
} }
$link = $node->getLink(); $ul = Html::tag('ul', [
$link->getAttributes()->set('data-base-target', '_next'); 'class' => ['bp', 'sortable'],
$link->add($this->getNodeIcons($node));
if ($node->hasChildren()) {
$link->add($this->renderStateBadges($node->getStateSummary()));
}
if ($time = $node->getLastStateChange()) {
$since = $this->timeSince($time)->prepend(
sprintf(' (%s ', $node->getStateName())
)->add(')');
$link->add($since);
}
$td->add($link);
$tbody = Html::tag('ul', [
'class' => 'sortable',
'data-sortable-disabled' => $this->isLocked() ? 'true' : 'false', 'data-sortable-disabled' => $this->isLocked() ? 'true' : 'false',
'data-sortable-invert-swap' => 'true',
'data-sortable-data-id-attr' => 'id', 'data-sortable-data-id-attr' => 'id',
'data-sortable-draggable' => '.movable', 'data-sortable-draggable' => '.movable',
'data-sortable-direction' => 'vertical', 'data-sortable-direction' => 'vertical',
@ -182,18 +188,18 @@ class TreeRenderer extends Renderer
->overwriteParams(['node' => (string) $node]) ->overwriteParams(['node' => (string) $node])
->getAbsoluteUrl() ->getAbsoluteUrl()
]); ]);
$table->add($tbody); $li->add($ul);
$path[] = (string) $node; $path[] = (string) $node;
foreach ($node->getChildren() as $name => $child) { foreach ($node->getChildren() as $name => $child) {
if ($child instanceof BpNode) { if ($child instanceof BpNode) {
$tbody->add($this->renderNode($bp, $child, $path)); $ul->add($this->renderNode($bp, $child, $path));
} else { } else {
$tbody->add($this->renderChild($bp, $child, $path)); $ul->add($this->renderChild($bp, $child, $path));
} }
} }
return $table; return $li;
} }
protected function renderChild($bp, Node $node, $path = null) protected function renderChild($bp, Node $node, $path = null)
@ -204,19 +210,14 @@ class TreeRenderer extends Renderer
'data-node-name' => (string) $node 'data-node-name' => (string) $node
]); ]);
if (! $this->isLocked()) { $li->add($this->getNodeIcons($node, $path));
$li->add($this->getActionIcons($bp, $node));
}
$link = $node->getLink(); $link = $node->getLink();
$link->getAttributes()->set('data-base-target', '_next'); $link->getAttributes()->set('data-base-target', '_next');
$link->add($this->getNodeIcons($node)); $li->add($link);
if ($time = $node->getLastStateChange()) { if (! $this->isLocked()) {
$since = $this->timeSince($time)->prepend( $li->add($this->getActionIcons($bp, $node));
sprintf(' (%s ', $node->getStateName())
)->add(')');
$link->add($since);
} }
return $li; return $li;
@ -238,7 +239,7 @@ class TreeRenderer extends Renderer
protected function createEditAction(BpConfig $bp, BpNode $node) protected function createEditAction(BpConfig $bp, BpNode $node)
{ {
return $this->actionIcon( return $this->actionIcon(
'wrench', 'edit',
$this->getUrl()->with(array( $this->getUrl()->with(array(
'action' => 'edit', 'action' => 'edit',
'editnode' => $node->getName() 'editnode' => $node->getName()
@ -277,7 +278,7 @@ class TreeRenderer extends Renderer
[ [
'href' => $url, 'href' => $url,
'title' => $title, 'title' => $title,
'style' => 'float: right' 'class' => 'action-link'
], ],
Html::tag('i', ['class' => 'icon icon-' . $icon]) Html::tag('i', ['class' => 'icon icon-' . $icon])
); );