Skip to content

Commit 18af8dc

Browse files
committed
Build a single form for the event rule configuration
1 parent e3ccb69 commit 18af8dc

22 files changed

+2421
-637
lines changed

application/controllers/EventRuleController.php

Lines changed: 162 additions & 103 deletions
Large diffs are not rendered by default.

application/controllers/EventRulesController.php

Lines changed: 95 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,23 @@
44

55
namespace Icinga\Module\Notifications\Controllers;
66

7-
use Icinga\Exception\ProgrammingError;
87
use Icinga\Module\Notifications\Common\Database;
9-
use Icinga\Module\Notifications\Common\Links;
10-
use Icinga\Module\Notifications\Forms\EventRuleForm;
11-
use Icinga\Module\Notifications\Forms\SaveEventRuleForm;
12-
use Icinga\Module\Notifications\Model\ObjectExtraTag;
8+
use Icinga\Module\Notifications\Forms\EventRuleConfigForm;
139
use Icinga\Module\Notifications\Model\Rule;
1410
use Icinga\Module\Notifications\Web\Control\SearchBar\ObjectSuggestions;
1511
use Icinga\Module\Notifications\Widget\EventRuleConfig;
1612
use Icinga\Module\Notifications\Widget\ItemList\EventRuleList;
1713
use Icinga\Web\Notification;
1814
use Icinga\Web\Session;
15+
use ipl\Html\Attributes;
1916
use ipl\Html\Form;
17+
use ipl\Html\FormElement\SubmitButtonElement;
2018
use ipl\Html\Html;
19+
use ipl\Html\HtmlElement;
2120
use ipl\Stdlib\Filter;
2221
use ipl\Web\Compat\CompatController;
2322
use ipl\Web\Compat\SearchControls;
24-
use ipl\Web\Control\LimitControl;
2523
use ipl\Web\Control\SearchEditor;
26-
use ipl\Web\Control\SortControl;
2724
use ipl\Web\Filter\QueryString;
2825
use ipl\Web\Url;
2926
use ipl\Web\Widget\ButtonLink;
@@ -88,7 +85,7 @@ public function indexAction(): void
8885
$this->addContent(
8986
(new ButtonLink(
9087
t('New Event Rule'),
91-
Url::fromPath('notifications/event-rule/edit', ['id' => -1, 'clearCache' => true]),
88+
Url::fromPath('notifications/event-rule/edit', ['id' => -1]),
9289
'plus'
9390
))->openInModal()
9491
->addAttributes(['class' => 'new-event-rule'])
@@ -110,19 +107,56 @@ public function addAction(): void
110107
$this->getTabs()->setRefreshUrl(Url::fromPath('notifications/event-rules/add'));
111108

112109
$this->controls->addAttributes(['class' => 'event-rule-detail']);
110+
/** @var string $ruleId */
111+
$ruleId = $this->params->getRequired('id');
113112

114-
if ($this->params->has('use_cache') || $this->getServerRequest()->getMethod() !== 'GET') {
115-
$cache = $this->sessionNamespace->get(-1, []);
116-
} else {
117-
$this->sessionNamespace->delete(-1);
113+
$params = $this->params->toArray(false);
114+
/** @var array<string, mixed>|null $config */
115+
$config = $this->sessionNamespace->get($ruleId);
118116

119-
$cache = [];
117+
if ($config === null) {
118+
/** @var array<string, mixed> $config */
119+
$config = $params;
120120
}
121121

122-
$eventRuleConfig = new EventRuleConfig(Url::fromPath('notifications/event-rules/add-search-editor'), $cache);
122+
$eventRuleConfigSubmitButton = (new SubmitButtonElement(
123+
'save',
124+
[
125+
'label' => t('Add Event Rule'),
126+
'form' => 'event-rule-config-form',
127+
'formnovalidate' => true
128+
]
129+
))->setWrapper(new HtmlElement('div', Attributes::create(['class' => ['icinga-controls', 'save-config']])));
130+
131+
$eventRuleConfig = (new EventRuleConfigForm(
132+
$config,
133+
Url::fromPath(
134+
'notifications/event-rules/search-editor',
135+
['id' => $ruleId]
136+
)
137+
))
138+
->registerElement($eventRuleConfigSubmitButton)
139+
->populate($config);
140+
141+
$eventRuleConfig
142+
->on(Form::ON_SENT, function (Form $form) use ($config) {
143+
$config = array_merge($config, $form->getValues());
144+
$this->sessionNamespace->set('-1', $config);
145+
})
146+
->on(Form::ON_SUCCESS, function (EventRuleConfigForm $form) use ($config) {
147+
/** @var string $ruleId */
148+
$ruleId = $config['id'];
149+
/** @var string $ruleName */
150+
$ruleName = $config['name'];
151+
$form->addOrUpdateRule($ruleId, $config);
152+
$this->sessionNamespace->delete($ruleId);
153+
Notification::success(sprintf(t('Successfully add event rule %s'), $ruleName));
154+
$this->redirectNow('__CLOSE__');
155+
})
156+
->handleRequest($this->getServerRequest());
123157

124158
$eventRuleForm = Html::tag('div', ['class' => 'event-rule-form'], [
125-
Html::tag('h2', $eventRuleConfig->getConfig()['name'] ?? ''),
159+
Html::tag('h2', $config['name'] ?? ''),
126160
(new Link(
127161
new Icon('edit'),
128162
Url::fromPath('notifications/event-rule/edit', [
@@ -132,42 +166,8 @@ public function addAction(): void
132166
))->openInModal()
133167
]);
134168

135-
$saveForm = (new SaveEventRuleForm())
136-
->on(SaveEventRuleForm::ON_SUCCESS, function ($saveForm) use ($eventRuleConfig) {
137-
if (! $eventRuleConfig->isValid()) {
138-
$eventRuleConfig->addAttributes(['class' => 'invalid']);
139-
return;
140-
}
141-
142-
$id = $saveForm->addRule($this->sessionNamespace->get(-1));
143-
144-
Notification::success($this->translate('Successfully added rule.'));
145-
$this->sendExtraUpdates(['#col1']);
146-
$this->redirectNow(Links::eventRule($id));
147-
})->handleRequest($this->getServerRequest());
148-
149-
$eventRuleConfig->on(EventRuleConfig::ON_CHANGE, function ($eventRuleConfig) {
150-
$this->sessionNamespace->set(-1, $eventRuleConfig->getConfig());
151-
152-
$this->redirectNow(Url::fromPath('notifications/event-rules/add', ['use_cache' => true]));
153-
});
154-
155-
foreach ($eventRuleConfig->getForms() as $f) {
156-
$f->handleRequest($this->getServerRequest());
157-
158-
if (! $f->hasBeenSent()) {
159-
// Force validation of populated values in case we display an unsaved rule
160-
$f->validatePartial();
161-
}
162-
}
163-
164-
$eventRuleFormAndSave = Html::tag('div', ['class' => 'event-rule-and-save-forms']);
165-
$eventRuleFormAndSave->add([
166-
$eventRuleForm,
167-
$saveForm
168-
]);
169-
170-
$this->addControl($eventRuleFormAndSave);
169+
$this->addControl($eventRuleForm);
170+
$this->addControl($eventRuleConfigSubmitButton);
171171
$this->addContent($eventRuleConfig);
172172
}
173173

@@ -181,47 +181,70 @@ public function completeAction(): void
181181

182182
public function searchEditorAction(): void
183183
{
184-
$editor = $this->createSearchEditor(
185-
Rule::on(Database::get()),
186-
[
187-
LimitControl::DEFAULT_LIMIT_PARAM,
188-
SortControl::DEFAULT_SORT_PARAM,
189-
]
190-
);
184+
/** @var string $ruleId */
185+
$ruleId = $this->params->shiftRequired('id');
191186

192-
$this->getDocument()->add($editor);
193-
$this->setTitle($this->translate('Adjust Filter'));
194-
}
187+
/** @var array<string, mixed>|null $eventRule */
188+
$eventRule = $this->sessionNamespace->get($ruleId);
195189

196-
public function addSearchEditorAction(): void
197-
{
198-
$cache = $this->sessionNamespace->get(-1);
190+
if ($eventRule === null) {
191+
$eventRule = ['id' => '-1'];
192+
}
199193

200-
$editor = EventRuleConfig::createSearchEditor()
201-
->setQueryString($cache['object_filter'] ?? '');
194+
$editor = new SearchEditor();
202195

203-
$editor->on(SearchEditor::ON_SUCCESS, function (SearchEditor $form) {
204-
$cache = $this->sessionNamespace->get(-1);
205-
$cache['object_filter'] = EventRuleConfig::createFilterString($form->getFilter());
196+
/** @var string $objectFilter */
197+
$objectFilter = $eventRule['object_filter'] ?? '';
198+
$editor->setQueryString($objectFilter);
199+
$editor->setAction(Url::fromRequest()->getAbsoluteUrl());
200+
$editor->setSuggestionUrl(Url::fromPath(
201+
"notifications/event-rule/complete",
202+
['_disableLayout' => true, 'showCompact' => true, 'id' => Url::fromRequest()->getParams()->get('id')]
203+
));
206204

207-
$this->sessionNamespace->set(-1, $cache);
205+
$editor->on(SearchEditor::ON_SUCCESS, function (SearchEditor $form) use ($ruleId, $eventRule) {
206+
$filter = self::createFilterString($form->getFilter());
207+
$eventRule['object_filter'] = $filter;
208208

209+
$this->sessionNamespace->set($ruleId, $eventRule);
209210
$this->getResponse()
210211
->setHeader('X-Icinga-Container', '_self')
211212
->redirectAndExit(
212213
Url::fromPath(
213214
'notifications/event-rules/add',
214-
['use_cache' => true]
215+
['id' => $ruleId]
215216
)
216217
);
217218
});
218219

219220
$editor->handleRequest($this->getServerRequest());
220221

221-
$this->getDocument()->addHtml($editor);
222+
$this->getDocument()->add($editor);
222223
$this->setTitle($this->translate('Adjust Filter'));
223224
}
224225

226+
/**
227+
* Create filter string from the given filter rule
228+
*
229+
* @param Filter\Rule $filters
230+
*
231+
* @return string
232+
*/
233+
public static function createFilterString(Filter\Rule $filters): string
234+
{
235+
if ($filters instanceof Filter\Chain) {
236+
foreach ($filters as $filter) {
237+
self::createFilterString($filter);
238+
}
239+
} elseif ($filters instanceof Filter\Condition && empty($filters->getValue())) {
240+
$filters->setValue(true);
241+
}
242+
243+
$filterStr = QueryString::render($filters);
244+
245+
return ! empty($filterStr) ? $filterStr : '';
246+
}
247+
225248
/**
226249
* Get the filter created from query string parameters
227250
*

0 commit comments

Comments
 (0)