diff --git a/application/controllers/EventRuleController.php b/application/controllers/EventRuleController.php index fee84617c..d41958c41 100644 --- a/application/controllers/EventRuleController.php +++ b/application/controllers/EventRuleController.php @@ -7,13 +7,13 @@ use Icinga\Module\Notifications\Common\Auth; use Icinga\Module\Notifications\Common\Database; use Icinga\Module\Notifications\Common\Links; +use Icinga\Module\Notifications\Forms\EventRuleConfigElements\EventRuleConfigFilter; use Icinga\Module\Notifications\Forms\EventRuleConfigForm; use Icinga\Module\Notifications\Forms\EventRuleForm; use Icinga\Module\Notifications\Model\Incident; use Icinga\Module\Notifications\Model\Rule; use Icinga\Module\Notifications\Web\Control\SearchBar\ExtraTagSuggestions; use Icinga\Web\Notification; -use Icinga\Web\Session; use ipl\Html\Attributes; use ipl\Html\Form; use ipl\Html\FormElement\SubmitButtonElement; @@ -31,92 +31,53 @@ class EventRuleController extends CompatController { use Auth; - /** @var Session\SessionNamespace */ - private $sessionNamespace; - /** @var ?string Event rule config filter */ protected $filter; - public function init() - { - $this->sessionNamespace = Session::getSession()->getNamespace('notifications'); - } - public function indexAction(): void { $this->assertPermission('notifications/config/event-rule'); - $this->sessionNamespace->delete('-1'); + $this->addContent(Html::tag('div', ['class' => 'container', 'id' => 'dummy'])); $this->addTitleTab(t('Event Rule')); $this->controls->addAttributes(['class' => 'event-rule-detail']); /** @var string $ruleId */ $ruleId = $this->params->getRequired('id'); - /** @var array|null $configValues */ - $configValues = $this->sessionNamespace->get($ruleId); $this->controls->addAttributes(['class' => 'event-rule-detail']); $disableSave = false; - if ($configValues === null) { - $configValues = $this->fromDb((int) $ruleId); - $disableSave = true; + $configValues = $this->fromDb((int) $ruleId); + /** @var array $configFilter */ + $configFilter = $this->getRequest()->get('config-filter'); + if ($this->getRequest()->has('searchbar')) { + $configValues['object_filter'] = $this->getRequest()->get('searchbar'); + } elseif ($configFilter !== null) { + if (isset($configFilter['show-searchbar']) && $configFilter['show-searchbar'] === '0') { + $configValues['object_filter'] = ''; + } } $eventRuleConfig = (new EventRuleConfigForm( $configValues, Url::fromPath( 'notifications/event-rule/search-editor', - ['id' => $ruleId] + ['id' => $ruleId, 'object_filter' => $configValues['object_filter']] ) ))->populate($configValues); $eventRuleConfig ->on(Form::ON_SUCCESS, function (EventRuleConfigForm $form) use ($ruleId, $configValues) { $form->addOrUpdateRule($ruleId, $configValues); - $this->sessionNamespace->delete($ruleId); Notification::success((sprintf(t('Successfully saved event rule %s'), $configValues['name']))); $this->redirectNow(Links::eventRule((int) $ruleId)); }) ->on(EventRuleConfigForm::ON_DELETE, function (EventRuleConfigForm $form) use ($ruleId, $configValues) { $form->removeRule((int) $ruleId); - $this->sessionNamespace->delete($ruleId); Notification::success(sprintf(t('Successfully deleted event rule %s'), $configValues['name'])); $this->redirectNow('__CLOSE__'); }) - ->on(EventRuleConfigForm::ON_DISCARD, function () use ($ruleId, $configValues) { - $this->sessionNamespace->delete($ruleId); - Notification::success( - sprintf( - t('Successfully discarded changes to event rule %s'), - $configValues['name'] - ) - ); - $this->redirectNow(Links::eventRule((int) $ruleId)); - }) - ->on(EventRuleConfigForm::ON_CHANGE, function (EventRuleConfigForm $form) use ($ruleId, $configValues) { - $configValues = array_merge($configValues, $form->getValues()); - $configValues['rule_escalation'] = $form->getValues()['rule_escalation']; - $this->sessionNamespace->set($ruleId, $configValues); - }) ->handleRequest($this->getServerRequest()); - /** @var array $cache */ - $cache = $this->sessionNamespace->get($ruleId); - $discardChangesButton = null; - if ($cache !== null) { - $this->addContent(Html::tag('div', ['class' => 'cache-notice'], t('There are unsaved changes.'))); - $discardChangesButton = (new SubmitButtonElement( - 'discard_changes', - [ - 'label' => t('Discard Changes'), - 'form' => 'event-rule-config-form', - 'class' => 'btn-discard-changes', - 'formnovalidate' => true, - ] - )); - $disableSave = false; - } - - $buttonsWrapper = new HtmlElement('div', Attributes::create(['class' => ['icinga-controls', 'save-config']])); $eventRuleConfigSubmitButton = (new SubmitButtonElement( 'save', @@ -137,7 +98,7 @@ public function indexAction(): void )); $buttonsWrapper->add( - [$eventRuleConfigSubmitButton, $discardChangesButton, $deleteButton] + [$eventRuleConfigSubmitButton, $deleteButton] ); if ($ruleId > 0) { @@ -150,7 +111,7 @@ public function indexAction(): void } } - $eventRuleForm = Html::tag('div', ['class' => 'event-rule-form'], [ + $eventRuleForm = Html::tag('div', ['class' => 'event-rule-form', 'id' => 'event-rule-form'], [ Html::tag('h2', $configValues['name'] ?? ''), (new Link( new Icon('edit'), @@ -166,6 +127,49 @@ public function indexAction(): void $this->addContent($eventRuleConfig); } + public function ruleAction(): void + { + /** @var int $ruleId */ + $ruleId = $this->params->getRequired('id'); + $query = Rule::on(Database::get()) + ->withoutColumns('timeperiod_id') + ->filter(Filter::equal('id', $ruleId)); + + $rule = $query->first(); + + $this->getDocument()->add([ + Html::tag('h2', $rule->name ?? ''), + (new Link( + new Icon('edit'), + Url::fromPath('notifications/event-rule/edit', [ + 'id' => $ruleId + ]), + ['class' => 'control-button'] + ))->openInModal() + ]); + } + + public function configFilterAction(): void + { + $ruleId = $this->params->getRequired('id'); + /** @var string $objectFilter */ + $objectFilter = $this->params->get('object_filter', ''); + $eventRuleFilterFieldset = (new EventRuleConfigFilter('config-filter')) + ->setObjectFilter($objectFilter) + ->setSearchEditorUrl( + Url::fromPath( + 'notifications/event-rule/search-editor', + ['id' => $ruleId, 'object_filter' => $objectFilter] + ) + ); + + if ($objectFilter === '') { + $eventRuleFilterFieldset->getAttributes()->add('class', 'empty-filter'); + } + + $this->getDocument()->add($eventRuleFilterFieldset); + } + /** * Create config from db * @@ -237,38 +241,35 @@ public function searchEditorAction(): void { /** @var string $ruleId */ $ruleId = $this->params->shiftRequired('id'); - - $eventRule = $this->sessionNamespace->get($ruleId); - - if ($eventRule === null) { - $eventRule = $this->fromDb((int) $ruleId); - } - $editor = new SearchEditor(); /** @var string $objectFilter */ - $objectFilter = $eventRule['object_filter'] ?? ''; + $objectFilter = $this->params->shift('object_filter', ''); $editor->setQueryString($objectFilter); $editor->setAction(Url::fromRequest()->getAbsoluteUrl()); $editor->setSuggestionUrl( Url::fromPath( "notifications/event-rule/complete", - ['_disableLayout' => true, 'showCompact' => true, 'id' => Url::fromRequest()->getParams()->get('id')] + ['_disableLayout' => true, 'showCompact' => true, 'id' => $ruleId] ) ); - $editor->on(SearchEditor::ON_SUCCESS, function (SearchEditor $form) use ($ruleId, $eventRule) { + $editor->on(SearchEditor::ON_SUCCESS, function (SearchEditor $form) use ($ruleId) { $filter = self::createFilterString($form->getFilter()); - $eventRule['object_filter'] = $filter; - $this->sessionNamespace->set($ruleId, $eventRule); - $this->getResponse() - ->setHeader('X-Icinga-Container', '_self') - ->redirectAndExit( - Url::fromPath( - 'notifications/event-rule', - ['id' => $ruleId] + $this->sendExtraUpdates( + [ + '#config-filter' => Url::fromPath( + 'notifications/event-rule/config-filter', + [ + 'id' => $ruleId, + 'object_filter' => $filter + ] ) - ); + ] + ); + $this->getResponse() + ->setHeader('X-Icinga-Container', 'dummy') + ->redirectAndExit('__CLOSE__'); }); $editor->handleRequest($this->getServerRequest()); @@ -303,14 +304,11 @@ public function editAction(): void { /** @var string $ruleId */ $ruleId = $this->params->getRequired('id'); - /** @var array|null $config */ - $config = $this->sessionNamespace->get($ruleId); - if ($config === null) { - if ($ruleId === '-1') { - $config = ['id' => $ruleId]; - } else { - $config = $this->fromDb((int) $ruleId); - } + if ($ruleId === '-1') { + $config = ['id' => $ruleId]; + } else { + /** @var array $config */ + $config = $this->fromDb((int) $ruleId); } $eventRuleForm = (new EventRuleForm()) @@ -332,14 +330,23 @@ public function editAction(): void if ($ruleId === '-1') { $redirectUrl = Url::fromPath('notifications/event-rules/add', $params); + $this->getResponse()->setHeader('X-Icinga-Container', 'col2'); + $this->redirectNow($redirectUrl); } else { - $redirectUrl = Url::fromPath('notifications/event-rule', $params); - $this->sendExtraUpdates(['#col1']); + Database::get()->update('rule', [ + 'name' => $config['name'], + 'is_active' => $config['is_active'] ?? 'n' + ], ['id = ?' => $ruleId]); + $this->sendExtraUpdates([ + '#event-rule-form' => Url::fromPath( + 'notifications/event-rule/rule', + ['id' => $ruleId] + )->getAbsoluteUrl() + ]); + + $this->getResponse()->setHeader('X-Icinga-Container', 'dummy') + ->redirectAndExit('__CLOSE__'); } - - $this->sessionNamespace->set($ruleId, $config); - $this->getResponse()->setHeader('X-Icinga-Container', 'col2'); - $this->redirectNow($redirectUrl); })->handleRequest($this->getServerRequest()); if ($ruleId === '-1') { diff --git a/application/controllers/EventRulesController.php b/application/controllers/EventRulesController.php index 6fecaab40..dcb912190 100644 --- a/application/controllers/EventRulesController.php +++ b/application/controllers/EventRulesController.php @@ -5,6 +5,7 @@ namespace Icinga\Module\Notifications\Controllers; use Icinga\Module\Notifications\Common\Database; +use Icinga\Module\Notifications\Forms\EventRuleConfigElements\EventRuleConfigFilter; use Icinga\Module\Notifications\Forms\EventRuleConfigForm; use Icinga\Module\Notifications\Model\Rule; use Icinga\Module\Notifications\Web\Control\SearchBar\ObjectSuggestions; @@ -105,6 +106,7 @@ public function addAction(): void { $this->addTitleTab(t('Add Event Rule')); $this->getTabs()->setRefreshUrl(Url::fromPath('notifications/event-rules/add')); + $this->addContent(Html::tag('div', ['class' => 'container', 'id' => 'dummy'])); $this->controls->addAttributes(['class' => 'event-rule-detail']); /** @var string $ruleId */ @@ -119,6 +121,16 @@ public function addAction(): void $config = $params; } + /** @var array $configFilter */ + $configFilter = $this->getRequest()->get('config-filter'); + if ($this->getRequest()->has('searchbar')) { + $config['object_filter'] = $this->getRequest()->get('searchbar'); + } elseif ($configFilter !== null) { + if (isset($configFilter['show-searchbar']) && $configFilter['show-searchbar'] === '0') { + $config['object_filter'] = ''; + } + } + $eventRuleConfigSubmitButton = (new SubmitButtonElement( 'save', [ @@ -132,7 +144,7 @@ public function addAction(): void $config, Url::fromPath( 'notifications/event-rules/search-editor', - ['id' => $ruleId] + ['id' => $ruleId, 'object_filter' => $config['object_filter'] ?? ''] ) )) ->registerElement($eventRuleConfigSubmitButton) @@ -157,13 +169,20 @@ public function addAction(): void $eventRuleForm = Html::tag('div', ['class' => 'event-rule-form'], [ Html::tag('h2', $config['name'] ?? ''), - (new Link( - new Icon('edit'), - Url::fromPath('notifications/event-rule/edit', [ - 'id' => -1 - ]), - ['class' => 'control-button'] - ))->openInModal() + Html::tag( + 'div', + [ + 'class' => 'not-allowed', + 'title' => $this->translate('Cannot edit event rule until it is saved to database') + ], + (new Link( + new Icon('edit'), + Url::fromPath('notifications/event-rule/edit', [ + 'id' => -1 + ]), + ['class' => ['control-button', 'disabled']] + ))->openInModal() + ) ]); $this->addControl($eventRuleForm); @@ -171,6 +190,27 @@ public function addAction(): void $this->addContent($eventRuleConfig); } + public function configFilterAction(): void + { + $ruleId = $this->params->getRequired('id'); + /** @var string $objectFilter */ + $objectFilter = $this->params->get('object_filter', ''); + $eventRuleFilterFieldset = (new EventRuleConfigFilter('config-filter')) + ->setObjectFilter($objectFilter) + ->setSearchEditorUrl( + Url::fromPath( + 'notifications/event-rule/search-editor', + ['id' => $ruleId, 'object_filter' => $objectFilter] + ) + ); + + if ($objectFilter === '') { + $eventRuleFilterFieldset->getAttributes()->add('class', 'empty-filter'); + } + + $this->getDocument()->add($eventRuleFilterFieldset); + } + public function completeAction(): void { $suggestions = new ObjectSuggestions(); @@ -184,17 +224,10 @@ public function searchEditorAction(): void /** @var string $ruleId */ $ruleId = $this->params->shiftRequired('id'); - /** @var array|null $eventRule */ - $eventRule = $this->sessionNamespace->get($ruleId); - - if ($eventRule === null) { - $eventRule = ['id' => '-1']; - } - + /** @var string $objectFilter */ + $objectFilter = $this->params->shift('object_filter', ''); $editor = new SearchEditor(); - /** @var string $objectFilter */ - $objectFilter = $eventRule['object_filter'] ?? ''; $editor->setQueryString($objectFilter); $editor->setAction(Url::fromRequest()->getAbsoluteUrl()); $editor->setSuggestionUrl( @@ -204,19 +237,22 @@ public function searchEditorAction(): void ) ); - $editor->on(SearchEditor::ON_SUCCESS, function (SearchEditor $form) use ($ruleId, $eventRule) { + $editor->on(SearchEditor::ON_SUCCESS, function (SearchEditor $form) use ($ruleId) { $filter = self::createFilterString($form->getFilter()); - $eventRule['object_filter'] = $filter; - - $this->sessionNamespace->set($ruleId, $eventRule); - $this->getResponse() - ->setHeader('X-Icinga-Container', '_self') - ->redirectAndExit( - Url::fromPath( - 'notifications/event-rules/add', - ['id' => $ruleId] + $this->sendExtraUpdates( + [ + '#config-filter' => Url::fromPath( + 'notifications/event-rules/config-filter', + [ + 'id' => $ruleId, + 'object_filter' => $filter + ] ) - ); + ] + ); + $this->getResponse() + ->setHeader('X-Icinga-Container', 'dummy') + ->redirectAndExit('__CLOSE__'); }); $editor->handleRequest($this->getServerRequest()); diff --git a/application/forms/EventRuleConfigForm.php b/application/forms/EventRuleConfigForm.php index 84cf98dc8..7daf43045 100644 --- a/application/forms/EventRuleConfigForm.php +++ b/application/forms/EventRuleConfigForm.php @@ -248,7 +248,7 @@ protected function assemble(): void ['class' => 'filter-wrapper'], [ Html::tag('li', (new FlowLine())->getRightArrow()), - Html::tag('li', $configFilter), + Html::tag('li', ['id' => 'config-filter'], $configFilter), Html::tag('li', (new FlowLine())->getHorizontalLine()) ] ) diff --git a/public/css/detail/event-rule-detail.less b/public/css/detail/event-rule-detail.less index 0e3c83e1b..dcc68a8b0 100644 --- a/public/css/detail/event-rule-detail.less +++ b/public/css/detail/event-rule-detail.less @@ -38,6 +38,14 @@ width: 25em; } } + + .control-button.disabled { + pointer-events: none; + } + + .not-allowed { + cursor: not-allowed; + } } .save-config {