Skip to content

Commit 0d12e38

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

2 files changed

Lines changed: 128 additions & 1 deletion

File tree

application/controllers/IncidentController.php

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

66
namespace Icinga\Module\Notifications\Controllers;
77

8+
use ipl\Web\Compat\SearchControls;
89
use Icinga\Module\Notifications\Common\Auth;
910
use Icinga\Module\Notifications\Common\Database;
1011
use Icinga\Module\Notifications\Common\Links;
1112
use Icinga\Module\Notifications\Model\Contact;
1213
use Icinga\Module\Notifications\Model\Incident;
14+
use Icinga\Module\Notifications\Model\NotificationHistory;
15+
use Icinga\Module\Notifications\View\NotificationHistoryRenderer;
16+
use Icinga\Module\Notifications\Web\Control\SearchBar\ObjectSuggestions;
1317
use Icinga\Module\Notifications\Widget\Detail\IncidentDetail;
1418
use Icinga\Module\Notifications\Widget\Detail\IncidentQuickActions;
1519
use Icinga\Module\Notifications\Widget\Detail\ObjectHeader;
20+
use Icinga\Module\Notifications\Widget\ItemList\ObjectList;
1621
use ipl\Html\Attributes;
1722
use ipl\Html\Contract\Form;
1823
use ipl\Stdlib\Filter;
1924
use ipl\Web\Compat\CompatController;
25+
use ipl\Web\Control\LimitControl;
26+
use ipl\Web\Control\SortControl;
27+
use ipl\Web\Filter\QueryString;
28+
use ipl\Web\Url;
2029

2130
class IncidentController extends CompatController
2231
{
2332
use Auth;
33+
use SearchControls;
34+
35+
public function init(): void
36+
{
37+
$this->setTitleTab($this->getRequest()->getActionName());
38+
}
2439

2540
public function indexAction(): void
2641
{
27-
$this->addTitleTab(t('Incident'));
42+
$this->setTitle(t('Incident'));
2843

2944
$id = $this->params->getRequired('id');
3045

@@ -63,4 +78,110 @@ public function indexAction(): void
6378

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

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)