Skip to content

Commit b10faf4

Browse files
Introduce Notification History tab in incident detail view
`ObjectSuggestions`: Apply base filter to suggest only current-incident-based suggestions.
1 parent 8702639 commit b10faf4

2 files changed

Lines changed: 143 additions & 1 deletion

File tree

application/controllers/IncidentController.php

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,42 @@
55

66
namespace Icinga\Module\Notifications\Controllers;
77

8+
use ipl\Web\Common\Controls;
9+
use ipl\Web\Compat\SearchControls;
810
use Icinga\Module\Notifications\Common\Auth;
911
use Icinga\Module\Notifications\Common\Database;
1012
use Icinga\Module\Notifications\Common\Links;
1113
use Icinga\Module\Notifications\Model\Contact;
1214
use Icinga\Module\Notifications\Model\Incident;
15+
use Icinga\Module\Notifications\Model\NotificationHistory;
16+
use Icinga\Module\Notifications\View\NotificationHistoryRenderer;
17+
use Icinga\Module\Notifications\Web\Control\SearchBar\ObjectSuggestions;
1318
use Icinga\Module\Notifications\Widget\Detail\IncidentDetail;
1419
use Icinga\Module\Notifications\Widget\Detail\IncidentQuickActions;
1520
use Icinga\Module\Notifications\Widget\Detail\ObjectHeader;
21+
use Icinga\Module\Notifications\Widget\ItemList\ObjectList;
1622
use ipl\Html\Attributes;
1723
use ipl\Html\Contract\Form;
1824
use ipl\Stdlib\Filter;
1925
use ipl\Web\Compat\CompatController;
26+
use ipl\Web\Control\LimitControl;
27+
use ipl\Web\Control\SortControl;
28+
use ipl\Web\Filter\QueryString;
29+
use ipl\Web\Layout\DetailedItemLayout;
30+
use ipl\Web\Layout\ItemLayout;
31+
use ipl\Web\Layout\MinimalItemLayout;
32+
use ipl\Web\Url;
2033

2134
class IncidentController extends CompatController
2235
{
2336
use Auth;
37+
use SearchControls;
38+
use Controls;
2439

2540
public function indexAction(): void
2641
{
27-
$this->addTitleTab(t('Incident'));
42+
$this->setTitle(t('Incident'));
43+
$this->setTitleTab($this->getRequest()->getActionName());
2844

2945
$id = $this->params->getRequired('id');
3046

@@ -63,4 +79,124 @@ public function indexAction(): void
6379

6480
$this->addContent(new IncidentDetail($incident));
6581
}
82+
83+
public function notificationHistoryAction(): void
84+
{
85+
$this->setTitle(t('Notification History'));
86+
$this->setTitleTab($this->getRequest()->getActionName());
87+
88+
$notificationHistory = NotificationHistory::on(Database::get())
89+
->with(['channel', 'contact', 'contactgroup', 'schedule'])
90+
->filter(Filter::equal('notification_history.incident_id', $this->params->shiftRequired('id')));
91+
$this->applyRestrictions($notificationHistory);
92+
93+
$limitControl = $this->createLimitControl();
94+
$sortControl = $this->createSortControl(
95+
$notificationHistory,
96+
[
97+
'notification_history.triggered_at desc' => t('Triggered At'),
98+
'notification_history.state, notification_history.triggered_at desc' => t('State')
99+
]
100+
);
101+
102+
$paginationControl = $this->createPaginationControl($notificationHistory);
103+
$viewModeSwitcher = $this->createViewModeSwitcher($this->params);
104+
105+
$searchBar = $this->createSearchBar(
106+
$notificationHistory,
107+
[
108+
$limitControl->getLimitParam(),
109+
$sortControl->getSortParam(),
110+
$viewModeSwitcher->getViewModeParam(),
111+
'id'
112+
]
113+
);
114+
115+
$this->applyViewModeLimit($limitControl, $paginationControl);
116+
$this->handleControls($this->getServerRequest());
117+
118+
if ($searchBar->hasBeenSent() && ! $searchBar->isValid()) {
119+
if ($searchBar->hasBeenSubmitted()) {
120+
$filter = QueryString::parse((string) $this->params);
121+
} else {
122+
$this->addControl($searchBar);
123+
$this->sendMultipartUpdate();
124+
return;
125+
}
126+
} else {
127+
$filter = $searchBar->getFilter();
128+
}
129+
130+
$notificationHistory->filter($filter);
131+
132+
$this->addControl($paginationControl);
133+
$this->addControl($sortControl);
134+
$this->addControl($limitControl);
135+
$this->addControl($viewModeSwitcher);
136+
$this->addControl($searchBar);
137+
138+
$this->addContent(
139+
(new ObjectList($notificationHistory, new NotificationHistoryRenderer()))
140+
->setItemLayoutClass(match ($viewModeSwitcher->getViewMode()) {
141+
'minimal' => MinimalItemLayout::class,
142+
'detailed' => DetailedItemLayout::class,
143+
'common' => ItemLayout::class
144+
})
145+
);
146+
147+
if (! $searchBar->hasBeenSubmitted() && $searchBar->hasBeenSent()) {
148+
$this->sendMultipartUpdate();
149+
}
150+
151+
$this->setAutorefreshInterval(10);
152+
}
153+
154+
public function completeAction(): void
155+
{
156+
$suggestions = (new ObjectSuggestions())
157+
->setModel(NotificationHistory::class)
158+
->setBaseFilter(
159+
Filter::equal('notification_history.incident_id', $this->params->getRequired('id'))
160+
)
161+
->forRequest($this->getServerRequest());
162+
163+
$this->getDocument()->addHtml($suggestions);
164+
}
165+
166+
public function searchEditorAction(): void
167+
{
168+
$preserveParams = [
169+
LimitControl::DEFAULT_LIMIT_PARAM,
170+
SortControl::DEFAULT_SORT_PARAM,
171+
'id'
172+
];
173+
174+
$editor = $this->createSearchEditor(
175+
NotificationHistory::on(Database::get()),
176+
Url::fromPath('notifications/incident/notification-history', ['id' => $this->params->getRequired('id')]),
177+
$preserveParams
178+
);
179+
$editor->setSuggestionUrl(
180+
Url::fromPath('notifications/incident/complete')
181+
->setParams(Url::fromRequest()->onlyWith($preserveParams)->getParams())
182+
);
183+
184+
$this->getDocument()->addHtml($editor);
185+
$this->setTitle($this->translate('Adjust Filter'));
186+
}
187+
188+
protected function setTitleTab(string $name): void
189+
{
190+
$id = $this->params->getRequired('id');
191+
$this->getTabs()
192+
->add('index', [
193+
'label' => $this->translate('Incident'),
194+
'url' => Links::incident($id)
195+
])
196+
->add('notification-history', [
197+
'label' => $this->translate('Notification History'),
198+
'url' => Url::fromPath('notifications/incident/notification-history', ['id' => $id])
199+
])
200+
->activate($name);
201+
}
66202
}

library/Notifications/Web/Control/SearchBar/ObjectSuggestions.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use ipl\Orm\Relation;
1919
use ipl\Orm\Relation\HasOne;
2020
use ipl\Orm\Resolver;
21+
use ipl\Stdlib\BaseFilter;
2122
use ipl\Stdlib\Filter;
2223
use ipl\Stdlib\Seq;
2324
use ipl\Web\Control\SearchBar\SearchException;
@@ -29,6 +30,7 @@
2930
class ObjectSuggestions extends Suggestions
3031
{
3132
use Auth;
33+
use BaseFilter;
3234

3335
protected ?Model $model = null;
3436

@@ -106,6 +108,10 @@ protected function fetchValueSuggestions(
106108
$query = $model::on(Database::get());
107109
$query->limit(static::DEFAULT_LIMIT);
108110

111+
if ($this->hasBaseFilter()) {
112+
$query->filter($this->getBaseFilter());
113+
}
114+
109115
if (str_contains($column, ' ')) {
110116
// $column may be a label
111117
/** @var string $path */

0 commit comments

Comments
 (0)