diff --git a/library/Businessprocess/BpNode.php b/library/Businessprocess/BpNode.php index 643af1b..1575b34 100644 --- a/library/Businessprocess/BpNode.php +++ b/library/Businessprocess/BpNode.php @@ -116,8 +116,10 @@ class BpNode extends Node $name ); } + $this->children[$name] = $node; $this->childNames[] = $name; + $this->reorderChildren(); $node->addParent($this); return $this; } @@ -425,13 +427,9 @@ class BpNode extends Node public function setChildNames($names) { - if (! $this->getBpConfig()->getMetadata()->isManuallyOrdered()) { - natcasesort($names); - $names = array_values($names); - } - $this->childNames = $names; $this->children = null; + $this->reorderChildren(); return $this; } @@ -449,12 +447,8 @@ class BpNode extends Node public function getChildren($filter = null) { if ($this->children === null) { - $this->children = array(); - if (! $this->getBpConfig()->getMetadata()->isManuallyOrdered()) { - $childNames = $this->getChildNames(); - natcasesort($childNames); - $this->childNames = array_values($childNames); - } + $this->children = []; + $this->reorderChildren(); foreach ($this->getChildNames() as $name) { $this->children[$name] = $this->getBpConfig()->getNode($name); $this->children[$name]->addParent($this); @@ -464,6 +458,29 @@ class BpNode extends Node return $this->children; } + /** + * Reorder this node's children, in case manual order is not applied + */ + protected function reorderChildren() + { + if ($this->getBpConfig()->getMetadata()->isManuallyOrdered()) { + return; + } + + $childNames = $this->getChildNames(); + natcasesort($childNames); + $this->childNames = array_values($childNames); + + if (! empty($this->children)) { + $children = []; + foreach ($this->childNames as $name) { + $children[$name] = $this->children[$name]; + } + + $this->children = $children; + } + } + /** * return BpNode[] */ diff --git a/library/Businessprocess/Renderer/Renderer.php b/library/Businessprocess/Renderer/Renderer.php index ebbe05f..5d613d7 100644 --- a/library/Businessprocess/Renderer/Renderer.php +++ b/library/Businessprocess/Renderer/Renderer.php @@ -5,6 +5,7 @@ namespace Icinga\Module\Businessprocess\Renderer; use Icinga\Exception\ProgrammingError; use Icinga\Module\Businessprocess\BpNode; use Icinga\Module\Businessprocess\BpConfig; +use Icinga\Module\Businessprocess\ImportedNode; use Icinga\Module\Businessprocess\Node; use Icinga\Module\Businessprocess\Web\Url; use ipl\Html\BaseHtmlElement; @@ -196,6 +197,36 @@ abstract class Renderer extends HtmlDocument return $classes; } + /** + * Return the url to the given node's source configuration + * + * @param BpNode $node + * + * @return Url + */ + public function getSourceUrl(BpNode $node) + { + if ($node instanceof ImportedNode) { + $name = $node->getNodeName(); + $paths = $node->getBpConfig()->getBpNode($name)->getPaths(); + } else { + $name = $node->getName(); + $paths = $node->getPaths(); + } + + $url = $this->getUrl()->setParams([ + 'config' => $node->getBpConfig()->getName(), + 'node' => $name + ]); + // This depends on the fact that the node's root path is the last element in $paths + $url->getParams()->addValues('path', array_slice(array_pop($paths), 0, -1)); + if (! $this->isLocked()) { + $url->getParams()->add('unlocked', true); + } + + return $url; + } + /** * @param Node $node * @param $path diff --git a/library/Businessprocess/Renderer/TileRenderer/NodeTile.php b/library/Businessprocess/Renderer/TileRenderer/NodeTile.php index 108f84b..40216ea 100644 --- a/library/Businessprocess/Renderer/TileRenderer/NodeTile.php +++ b/library/Businessprocess/Renderer/TileRenderer/NodeTile.php @@ -197,6 +197,20 @@ class NodeTile extends BaseHtmlElement ], Html::tag('i', ['class' => 'icon icon-sitemap']) )); + if ($node->getBpConfig()->getName() !== $this->renderer->getBusinessProcess()->getName()) { + $this->actions()->add(Html::tag( + 'a', + [ + 'data-base-target' => '_next', + 'href' => $this->renderer->getSourceUrl($node)->getAbsoluteUrl(), + 'title' => mt( + 'businessprocess', + 'Show this process as part of its original configuration' + ) + ], + Html::tag('i', ['class' => 'icon icon-forward']) + )); + } $url = $node->getInfoUrl(); @@ -279,6 +293,7 @@ class NodeTile extends BaseHtmlElement } if (! $this->renderer->getBusinessProcess()->getMetadata()->canModify() + || $this->node->getBpConfig()->getName() !== $this->renderer->getBusinessProcess()->getName() || $this->node->getName() === '__unbound__' ) { return; diff --git a/library/Businessprocess/Renderer/TreeRenderer.php b/library/Businessprocess/Renderer/TreeRenderer.php index d0726fa..7fc5199 100644 --- a/library/Businessprocess/Renderer/TreeRenderer.php +++ b/library/Businessprocess/Renderer/TreeRenderer.php @@ -147,7 +147,9 @@ class TreeRenderer extends Renderer [ 'id' => $htmlId, 'class' => ['bp', 'movable', $node->getObjectClassName()], - 'data-node-name' => $node->getName() + 'data-node-name' => $node instanceof ImportedNode + ? $node->getNodeName() + : $node->getName() ] ); $attributes = $li->getAttributes(); @@ -180,6 +182,12 @@ class TreeRenderer extends Renderer $differentConfig = $node->getBpConfig()->getName() !== $this->getBusinessProcess()->getName(); if (! $this->isLocked() && !$differentConfig) { $div->add($this->getActionIcons($bp, $node)); + } elseif ($differentConfig) { + $div->add($this->actionIcon( + 'forward', + $this->getSourceUrl($node)->addParams(['mode' => 'tree'])->getAbsoluteUrl(), + mt('businessprocess', 'Show this process as part of its original configuration') + )->addAttributes(['data-base-target' => '_next'])); } $ul = Html::tag('ul', [