Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
sukhwinder33445 committed Aug 4, 2023
1 parent c2e06ac commit 11b706d
Show file tree
Hide file tree
Showing 6 changed files with 284 additions and 10 deletions.
29 changes: 29 additions & 0 deletions application/controllers/NodeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace Icinga\Module\Businessprocess\Controllers;

use GuzzleHttp\Psr7\ServerRequest;
use Icinga\Application\Modules\Module;
use Icinga\Module\Businessprocess\Forms\AddNodeToProcessForm;
use Icinga\Module\Businessprocess\ProvidedHook\Icingadb\IcingadbSupport;
use Icinga\Module\Businessprocess\Renderer\Breadcrumb;
use Icinga\Module\Businessprocess\Renderer\TileRenderer;
Expand All @@ -11,6 +13,8 @@
use Icinga\Module\Businessprocess\State\MonitoringState;
use Icinga\Module\Businessprocess\Web\Controller;
use Icinga\Module\Businessprocess\Web\Url;
use ipl\Web\Url as iplUrl;
use ipl\Web\Widget\ButtonLink;

class NodeController extends Controller
{
Expand Down Expand Up @@ -108,5 +112,30 @@ public function impactAction()
if ($content->isEmpty()) {
$content->add($this->translate('No impact detected. Is this node part of a business process?'));
}

$content->add(
(new ButtonLink(t('Add to process'), iplUrl::fromPath('businessprocess/node/add', ['name' => $name])))
->setAttribute('data-base-target', '_self')
);
}

public function addAction(): void
{
$this->controls()->add(
$this->singleTab($this->translate('Add Node'))
);

$objectName = $this->params->getRequired('name');

$this->addTitle(sprintf(t('Add %s to process'), $objectName));

$form = (new AddNodeToProcessForm())
->populate(['config' => $this->params->get('config')])
->setStorage($this->storage())
->setNodeName($objectName)
->setSession($this->session())
->handleRequest(ServerRequest::fromGlobals());

$this->content()->add($form);
}
}
166 changes: 166 additions & 0 deletions application/forms/AddNodeToProcessForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<?php

namespace Icinga\Module\Businessprocess\Forms;

use Exception;
use Icinga\Application\Icinga;
use Icinga\Exception\ConfigurationError;
use Icinga\Module\Businessprocess\BpConfig;
use Icinga\Module\Businessprocess\Exception\ModificationError;
use Icinga\Module\Businessprocess\Modification\ProcessChanges;
use Icinga\Module\Businessprocess\Renderer\TreeRenderer;
use Icinga\Module\Businessprocess\Storage\Storage;
use Icinga\Module\Businessprocess\Web\Url;
use Icinga\Web\Session;
use ipl\Html\Form;
use ipl\Html\FormDecorator\DdDtDecorator;
use ipl\I18n\Translation;
use ipl\Web\Common\CsrfCounterMeasure;

class AddNodeToProcessForm extends Form
{
use Translation;
use CsrfCounterMeasure;

/** @var ?Storage */
protected $storage;

/** @var ?Session\SessionNamespace */
protected $session;

/** @var ?string */
protected $nodeName;

/** @var BpConfig */
protected $bpConfig;

protected $changes;

/**
* Set the storage
*
* @param Storage $storage
*
* @return $this
*/
public function setStorage(Storage $storage): self
{
$this->storage = $storage;

return $this;
}

/**
* Set the session
*
* @param Session\SessionNamespace $session
*
* @return $this
*/
public function setSession(Session\SessionNamespace $session): self
{
$this->session = $session;

return $this;
}

public function setBpConfig(BpConfig $config)
{
$this->bpConfig = $config;

return $this;
}

public function setNodeName(string $nodeName): self
{
$this->nodeName = $nodeName;

return $this;
}

public function getNodeName(): ?string
{
return $this->nodeName;
}

protected function assemble()
{
$this->createCsrfCounterMeasure(Session::getSession()->getId());
$this->setDefaultElementDecorator(new DdDtDecorator());

$this->addElement('select', 'config', [
'label' => $this->translate('File Name'),
'required' => true,
'class' => 'autosubmit',
'options' => array_merge(
['' => $this->translate('Please choose')],
$this->storage->listProcesses()
),
'disabledOptions' => [''],
'description' => $this->translate('Choose a configuration file')
]);

$newParentNode = null;
$configName = $this->getValue('config');
if ($configName !== null) {
try {
$this->setBpConfig($this->storage->loadProcess($configName));
$parent = $this->bpConfig->createBp('Unbound');
$changes = ProcessChanges::construct($this->bpConfig, $this->session);
$changes->addChildrenToNode($this->getNodeName(), $parent);
$newParentNode = $this->getPopulatedValue('parent');
$newParentNode = $newParentNode ? $this->bpConfig->getNode($newParentNode) : null;
if ($newParentNode && ! $this->bpConfig->hasNode($this->getNodeName())) {
$changes->addChildrenToNode($this->getNodeName(), $newParentNode);
}

if ($this->getPopulatedValue('from') !== null) {
if (! $this->bpConfig->getMetadata()->isManuallyOrdered()) {
$changes->applyManualOrder();
}


try {
$changes->moveNode(
$this->bpConfig->getNode($this->getNodeName()),
$this->getPopulatedValue('from'),
$this->getPopulatedValue('to'),
$this->getPopulatedValue('parent')
);
} catch (Exception $e) {
throw new Exception($e->getMessage());
/*$this->notifyError($e->getMessage());
Icinga::app()->getResponse()
// Web 2's JS forces a content update for non-200s. Our own JS
// can't prevent this, hence we're not making this a 400 :(
//->setHttpResponseCode(400)
->setHeader('X-Icinga-Container', 'ignore')
->sendResponse();
exit;*/
}
}
// Trigger session destruction to make sure it get's stored.
unset($changes);
} catch (Exception $e) {
throw new ConfigurationError(
'Config file %s.conf is invalid, please choose another one',
$configName
);
}

$tree = (new TreeRenderer($this->bpConfig))
->setUrl(Url::fromRequest())
->setExtraChild(! $newParentNode ? $this->getNodeName() : null)
->unlock();

$this->add($tree);

$this->addElement('submit', 'submit');
}
}

protected function onSuccess()
{

}
}
65 changes: 58 additions & 7 deletions library/Businessprocess/Renderer/TreeRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class TreeRenderer extends Renderer
{
const NEW_COLLAPSIBLE_IMPLEMENTATION_SINCE = '2.11.2';

/** @var ?string */
protected $extraChild;

public function assemble()
{
$bp = $this->config;
Expand All @@ -32,9 +35,11 @@ public function assemble()
'data-sortable-disabled' => $this->isLocked() ? 'true' : 'false',
'data-sortable-data-id-attr' => 'id',
'data-sortable-direction' => 'vertical',
'data-sortable-sort' => $this->hasExtraChild() ? 'false' : 'true',
'data-sortable-group' => json_encode([
'name' => $this->wantsRootNodes() ? 'root' : $htmlId,
'put' => 'function:rowPutAllowed'
'put' => 'function:rowPutAllowed',
'pull' => ! $this->hasExtraChild()
]),
'data-sortable-invert-swap' => 'true',
'data-csrf-token' => CsrfToken::generate()
Expand Down Expand Up @@ -76,6 +81,20 @@ public function renderBp(BpConfig $bp)
$html = array();
if ($this->wantsRootNodes()) {
$nodes = $bp->getChildren();
if ($this->hasExtraChild()) {
$objectToAdd = $this->getExtraChild();
$parts = explode(';', $objectToAdd);
if ($parts[1] === 'Hoststatus') {
$bp->createHost($parts[0]);
} else {
$bp->createService($parts[0], $parts[1]);
}

$parent = $bp->createBp('Unbound');
$parent->addChild($bp->getNode($objectToAdd));

$html[] = $this->renderNode($bp, $parent, true);
}
} else {
$nodes = $this->parent->getChildren();
}
Expand Down Expand Up @@ -172,11 +191,12 @@ public function getOverriddenState($fakeState, Node $node)
/**
* @param BpConfig $bp
* @param Node $node
* @param bool $isFakeNode
* @param array $path
*
* @return string
*/
public function renderNode(BpConfig $bp, Node $node, $path = array())
public function renderNode(BpConfig $bp, Node $node, bool $isFakeNode = false, $path = array())
{
$htmlId = $this->getId($node, $path);
$li = Html::tag(
Expand Down Expand Up @@ -216,7 +236,7 @@ public function renderNode(BpConfig $bp, Node $node, $path = array())

$summary->add(Html::tag('span', null, $node->getAlias()));

if ($node instanceof BpNode) {
if ( ! $isFakeNode && $node instanceof BpNode) {
$summary->add(Html::tag('span', ['class' => 'op'], $node->operatorHtml()));
}

Expand All @@ -225,7 +245,7 @@ public function renderNode(BpConfig $bp, Node $node, $path = array())
}

$differentConfig = $node->getBpConfig()->getName() !== $this->getBusinessProcess()->getName();
if (! $this->isLocked() && !$differentConfig) {
if (! $this->isLocked() && ! $this->hasExtraChild() && ! $differentConfig) {
$summary->add($this->getActionIcons($bp, $node));
} elseif ($differentConfig) {
$summary->add($this->actionIcon(
Expand All @@ -242,9 +262,11 @@ public function renderNode(BpConfig $bp, Node $node, $path = array())
'data-sortable-data-id-attr' => 'id',
'data-sortable-draggable' => '.movable',
'data-sortable-direction' => 'vertical',
'data-sortable-sort' => $this->hasExtraChild() ? 'false' : 'true',
'data-sortable-group' => json_encode([
'name' => $htmlId, // Unique, so that the function below is the only deciding factor
'put' => 'function:rowPutAllowed'
'put' => ! $isFakeNode ? 'function:rowPutAllowed' : false,
'pull' => $this->hasExtraChild() ? 'function:rowPullAllowed' : true,
]),
'data-csrf-token' => CsrfToken::generate(),
'data-action-url' => $this->getUrl()
Expand All @@ -260,7 +282,7 @@ public function renderNode(BpConfig $bp, Node $node, $path = array())
$path[] = $differentConfig ? $node->getIdentifier() : $node->getName();
foreach ($node->getChildren() as $name => $child) {
if ($child instanceof BpNode) {
$ul->add($this->renderNode($bp, $child, $path));
$ul->add($this->renderNode($bp, $child, false, $path));
} else {
$ul->add($this->renderChild($bp, $node, $child, $path));
}
Expand All @@ -281,6 +303,14 @@ protected function renderChild($bp, BpNode $parent, Node $node, $path = null)
'data-node-name' => $node->getName()
]);

if ($this->hasExtraChild()) {
if ($node->getName() === $this->getExtraChild()) {
$li->addAttributes(['class' => 'new-child']);
} else {
$li->addAttributes(['class' => 'unhighlight']);
}
}

$li->add($this->getNodeIcons($node, $path, $parent));

$link = $node->getLink();
Expand All @@ -291,7 +321,11 @@ protected function renderChild($bp, BpNode $parent, Node $node, $path = null)
$li->add($this->getOverriddenState($overriddenState, $node));
}

if (! $this->isLocked() && $node->getBpConfig()->getName() === $this->getBusinessProcess()->getName()) {
if (
! $this->isLocked()
&& ! $this->hasExtraChild()
&& $node->getBpConfig()->getName() === $this->getBusinessProcess()->getName()
) {
$li->add($this->getActionIcons($bp, $node));
}

Expand Down Expand Up @@ -369,4 +403,21 @@ protected function renderAddNewNode($parent)
mt('businessprocess', 'Add a new business process node')
);
}

public function setExtraChild(?string $extraChild): self
{
$this->extraChild = $extraChild;

return $this;
}

public function getExtraChild(): ?string
{
return $this->extraChild;
}

public function hasExtraChild(): bool
{
return $this->extraChild !== null;
}
}
4 changes: 4 additions & 0 deletions public/css/module.less
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ form a {
color: @icinga-blue;
}

form li.unhighlight a {
color: @gray;
}

div.bp {
margin-bottom: 4px;
}
Expand Down
12 changes: 9 additions & 3 deletions public/js/behavior/sortable.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,15 @@
}
});

if (typeof options.group !== 'undefined' && typeof options.group.put === 'string' && options.group.put.substring(0, 9) === 'function:') {
var module = icinga.module($el.closest('.icinga-module').data('icingaModule'));
options.group.put = module.object[options.group.put.substr(9)];
if (typeof options.group !== 'undefined') {
let module = icinga.module($el.closest('.icinga-module').data('icingaModule'));
if (typeof options.group.put === 'string' && options.group.put.substring(0, 9) === 'function:') {
options.group.put = module.object[options.group.put.substr(9)];
}

if (typeof options.group.pull === 'string' && options.group.pull.substring(0, 9) === 'function:') {
options.group.pull = module.object[options.group.pull.substr(9)];
}
}

$(this).sortable(options);
Expand Down
Loading

0 comments on commit 11b706d

Please sign in to comment.