[pkg-nagios-changes] [Git][nagios-team/icingadb-web][upstream] New upstream version 1.0.2

Bas Couwenberg (@sebastic) gitlab at salsa.debian.org
Sat Nov 5 06:00:46 GMT 2022



Bas Couwenberg pushed to branch upstream at Debian Nagios Maintainer Group / icingadb-web


Commits:
5a821163 by Bas Couwenberg at 2022-11-05T06:50:48+01:00
New upstream version 1.0.2
- - - - -


27 changed files:

- AUTHORS
- CHANGELOG.md
- application/controllers/CommentController.php
- application/controllers/EventController.php
- application/forms/RedisConfigForm.php
- library/Icingadb/Command/Transport/ApiCommandTransport.php
- library/Icingadb/Common/Database.php
- library/Icingadb/Common/SearchControls.php
- + library/Icingadb/Common/TicketLinks.php
- library/Icingadb/Util/PluginOutput.php
- library/Icingadb/Widget/Detail/CommentDetail.php
- library/Icingadb/Widget/Detail/DowntimeDetail.php
- library/Icingadb/Widget/Detail/EventDetail.php
- library/Icingadb/Widget/Detail/ObjectDetail.php
- library/Icingadb/Widget/ItemList/BaseCommentListItem.php
- library/Icingadb/Widget/ItemList/BaseDowntimeListItem.php
- library/Icingadb/Widget/ItemList/BaseHistoryListItem.php
- library/Icingadb/Widget/ItemList/BaseNotificationListItem.php
- library/Icingadb/Widget/ItemList/CommentList.php
- library/Icingadb/Widget/ItemList/DowntimeList.php
- library/Icingadb/Widget/ItemList/HistoryList.php
- library/Icingadb/Widget/ItemList/HostListItemDetailed.php
- library/Icingadb/Widget/ItemList/ServiceListItemDetailed.php
- module.info
- public/css/common.less
- public/css/widget/quick-actions.less
- public/js/action-list.js


Changes:

=====================================
AUTHORS
=====================================
@@ -6,6 +6,7 @@ Johannes Meyer <johannes.meyer at icinga.com>
 Loei Petrus Marogi <LoeiPetrus.Marogi at netways.de>
 Marius Hein <marius.hein at icinga.com>
 Noah Hilverling <noah.hilverling at icinga.com>
+Patrick Dolinic <patrick.dolinic at netways.de>
 Ravi Kumar Kempapura Srinivasa <ravi.srinivasa at icinga.com>
 Sukhwinder Dhillon <sukhwinder.dhillon at icinga.com>
 VerboEse <verboEse at users.noreply.github.com>


=====================================
CHANGELOG.md
=====================================
@@ -3,6 +3,17 @@
 Please make sure to always read our [Upgrading](https://icinga.com/docs/icinga-db-web/latest/doc/05-Upgrading/)
 documentation before switching to a new version.
 
+## 1.0.2 (2022-11-04)
+
+You can find all issues related to this release on the respective [Milestone](https://github.com/Icinga/icingadb-web/milestone/4?closed=1).
+
+Notable fixes in this release are that the *GenericTTS* module is now supported and that the legacy integration
+of modules with no official support for Icinga DB Web is working again, even if the *monitoring* module is disabled.
+Action and Note URLs, which disappeared with v1.0.1, are also visible again.
+
+Some enhancements also found their way in this release. They include improved compatibility with Icinga DB's
+asynchronous behavior and its migration tool included in the v1.1 release.
+
 ## 1.0.1 (2022-09-08)
 
 Here are Fixes: https://github.com/Icinga/icingadb-web/milestone/3?closed=1


=====================================
application/controllers/CommentController.php
=====================================
@@ -55,7 +55,7 @@ class CommentController extends Controller
             ->setCaptionDisabled()
             ->setNoSubjectLink());
 
-        $this->addContent(new CommentDetail($this->comment));
+        $this->addContent((new CommentDetail($this->comment))->setTicketLinkEnabled());
 
         $this->setAutorefreshInterval(10);
     }


=====================================
application/controllers/EventController.php
=====================================
@@ -66,6 +66,6 @@ class EventController extends Controller
             ->setCaptionDisabled()
             ->setNoSubjectLink()
             ->setDetailActionsDisabled());
-        $this->addContent(new EventDetail($this->event));
+        $this->addContent((new EventDetail($this->event))->setTicketLinkEnabled());
     }
 }


=====================================
application/forms/RedisConfigForm.php
=====================================
@@ -399,28 +399,50 @@ class RedisConfigForm extends ConfigForm
         if (! empty($redis1Port)) {
             $redis1Section['port'] = $redis1Port;
             $this->getElement('redis1_port')->setValue(null);
+        } else {
+            $redis1Section['port'] = null;
         }
+
         if (! empty($redis1Password)) {
             $redis1Section['password'] = $redis1Password;
             $this->getElement('redis1_password')->setValue(null);
+        } else {
+            $redis1Section['password'] = null;
+        }
+
+        if (! array_filter($redis1Section->toArray())) {
+            $connectionConfig->removeSection('redis1');
         }
 
         $redis2Host = $this->getValue('redis2_host');
         $redis2Port = $this->getValue('redis2_port');
+        $redis2Password = $this->getValue('redis2_password');
         $redis2Section = $connectionConfig->getSection('redis2');
         if (! empty($redis2Host)) {
             $redis2Section['host'] = $redis2Host;
             $this->getElement('redis2_host')->setValue(null);
             $connectionConfig->setSection('redis2', $redis2Section);
+        } else {
+            $redis2Section['host'] = null;
         }
+
         if (! empty($redis2Port)) {
             $redis2Section['port'] = $redis2Port;
             $this->getElement('redis2_port')->setValue(null);
             $connectionConfig->setSection('redis2', $redis2Section);
+        } else {
+            $redis2Section['port'] = null;
         }
+
         if (! empty($redis2Password)) {
             $redis2Section['password'] = $redis2Password;
             $this->getElement('redis2_password')->setValue(null);
+        } else {
+            $redis2Section['password'] = null;
+        }
+
+        if (! array_filter($redis2Section->toArray())) {
+            $connectionConfig->removeSection('redis2');
         }
 
         $connectionConfig->saveIni();


=====================================
library/Icingadb/Command/Transport/ApiCommandTransport.php
=====================================
@@ -311,7 +311,7 @@ class ApiCommandTransport implements CommandTransportInterface
     public function probe()
     {
         try {
-            $response = (new Client())
+            $response = (new Client(['timeout' => 15]))
                 ->get($this->getUriFor(''), [
                     'auth'          => [$this->getUsername(), $this->getPassword()],
                     'headers'       => ['Accept' => 'application/json'],


=====================================
library/Icingadb/Common/Database.php
=====================================
@@ -34,11 +34,11 @@ trait Database
                 AppConfig::module('icingadb')->get('icingadb', 'resource')
             ));
 
-            $config->options = [
-                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
-                PDO::MYSQL_ATTR_INIT_COMMAND => "SET SESSION SQL_MODE='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE"
-                    . ",ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'"
-            ];
+            $config->options = [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ];
+            if ($config->db === 'mysql') {
+                $config->options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET SESSION SQL_MODE='STRICT_TRANS_TABLES"
+                    . ",NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'";
+            }
 
             $this->db = new Connection($config);
 


=====================================
library/Icingadb/Common/SearchControls.php
=====================================
@@ -35,7 +35,10 @@ trait SearchControls
     {
         $searchBar = $this->webCreateSearchBar($query, ...$params);
 
-        Html::tag('div', ['class' => 'filter'])->wrap($searchBar);
+        if (($wrapper = $searchBar->getWrapper()) && ! $wrapper->getWrapper()) {
+            // TODO: Remove this once ipl-web v0.7.0 is required
+            $searchBar->addWrapper(Html::tag('div', ['class' => 'search-controls']));
+        }
 
         return $searchBar;
     }


=====================================
library/Icingadb/Common/TicketLinks.php
=====================================
@@ -0,0 +1,56 @@
+<?php
+
+/* Icinga DB Web | (c) 2022 Icinga GmbH | GPLv2 */
+
+namespace Icinga\Module\Icingadb\Common;
+
+use Icinga\Application\Hook;
+
+trait TicketLinks
+{
+    /** @var bool */
+    protected $ticketLinkEnabled = false;
+
+    /**
+     * Set whether list items should render host and service links
+     *
+     * @param bool $state
+     *
+     * @return $this
+     */
+    public function setTicketLinkEnabled(bool $state = true): self
+    {
+        $this->ticketLinkEnabled = $state;
+
+        return $this;
+    }
+
+    /**
+     * Get whether list items should render host and service links
+     *
+     * @return bool
+     */
+    public function getTicketLinkEnabled(): bool
+    {
+        return $this->ticketLinkEnabled;
+    }
+
+    /**
+     * Get whether list items should render host and service links
+     *
+     * @return string
+     */
+    public function createTicketLinks($text): string
+    {
+        if (Hook::has('ticket')) {
+            $tickets = Hook::first('ticket');
+        }
+
+        if ($this->getTicketLinkEnabled() && isset($tickets)) {
+            /** @var \Icinga\Application\Hook\TicketHook $tickets */
+            return $tickets->createLinks($text);
+        }
+
+        return $text;
+    }
+}


=====================================
library/Icingadb/Util/PluginOutput.php
=====================================
@@ -82,6 +82,11 @@ class PluginOutput extends HtmlString
     public function isHtml(): bool
     {
         if ($this->isHtml === null) {
+            if (empty($this->getContent())) {
+                // "Nothing" can't be HTML
+                return false;
+            }
+
             throw new LogicException('Output not rendered yet');
         }
 


=====================================
library/Icingadb/Widget/Detail/CommentDetail.php
=====================================
@@ -7,9 +7,12 @@ namespace Icinga\Module\Icingadb\Widget\Detail;
 use Icinga\Date\DateFormatter;
 use Icinga\Module\Icingadb\Common\Auth;
 use Icinga\Module\Icingadb\Common\Links;
+use Icinga\Module\Icingadb\Common\TicketLinks;
 use Icinga\Module\Icingadb\Model\Comment;
 use Icinga\Module\Icingadb\Widget\MarkdownText;
 use Icinga\Module\Icingadb\Forms\Command\Object\DeleteCommentForm;
+use ipl\Stdlib\Filter;
+use ipl\Web\Filter\QueryString;
 use ipl\Web\Widget\HorizontalKeyValue;
 use ipl\Web\Widget\StateBall;
 use ipl\Web\Widget\TimeUntil;
@@ -19,6 +22,7 @@ use ipl\Html\Html;
 class CommentDetail extends BaseHtmlElement
 {
     use Auth;
+    use TicketLinks;
 
     protected $comment;
 
@@ -35,7 +39,7 @@ class CommentDetail extends BaseHtmlElement
     {
         return [
             Html::tag('h2', t('Comment')),
-            new MarkdownText($this->comment->text)
+            new MarkdownText($this->createTicketLinks($this->comment->text))
         ];
     }
 
@@ -106,7 +110,7 @@ class CommentDetail extends BaseHtmlElement
         }
 
         $action = Links::commentsDelete();
-        $action->setParam('name', $this->comment->name);
+        $action->setQueryString(QueryString::render(Filter::equal('name', $this->comment->name)));
 
         return (new DeleteCommentForm())
             ->setObjects([$this->comment])


=====================================
library/Icingadb/Widget/Detail/DowntimeDetail.php
=====================================
@@ -54,7 +54,7 @@ class DowntimeDetail extends BaseHtmlElement
     protected function createCancelDowntimeForm()
     {
         $action = Links::downtimesDelete();
-        $action->setParam('name', $this->downtime->name);
+        $action->setQueryString(QueryString::render(Filter::equal('name', $this->downtime->name)));
 
         return (new DeleteDowntimeForm())
             ->setObjects([$this->downtime])


=====================================
library/Icingadb/Widget/Detail/EventDetail.php
=====================================
@@ -12,6 +12,7 @@ use Icinga\Module\Icingadb\Common\Database;
 use Icinga\Module\Icingadb\Common\HostLink;
 use Icinga\Module\Icingadb\Common\HostStates;
 use Icinga\Module\Icingadb\Common\Links;
+use Icinga\Module\Icingadb\Common\TicketLinks;
 use Icinga\Module\Icingadb\Hook\ExtensionHook\ObjectDetailExtensionHook;
 use Icinga\Module\Icingadb\Widget\MarkdownText;
 use Icinga\Module\Icingadb\Common\ServiceLink;
@@ -47,6 +48,7 @@ class EventDetail extends BaseHtmlElement
     use Database;
     use HostLink;
     use ServiceLink;
+    use TicketLinks;
 
     protected $tag = 'div';
 
@@ -68,18 +70,24 @@ class EventDetail extends BaseHtmlElement
             ? $this->event->host->checkcommand_name
             : $this->event->service->checkcommand_name;
         if (isset($commandName)) {
+            if (empty($notification->text)) {
+                $notificationText = new EmptyState(t('Output unavailable.'));
+            } else {
+                $notificationText = new PluginOutputContainer(
+                    (new PluginOutput($notification->text))
+                        ->setCommandName($notification->object_type === 'host'
+                            ? $this->event->host->checkcommand_name
+                            : $this->event->service->checkcommand_name)
+                );
+            }
+
             $pluginOutput = [
                 HtmlElement::create('h2', null, $notification->author ? t('Comment') : t('Plugin Output')),
                 HtmlElement::create('div', [
                     'id'    => 'check-output-' . $commandName,
                     'class' => 'collapsible',
                     'data-visible-height' => 100
-                ], new PluginOutputContainer(
-                    (new PluginOutput($notification->text))
-                        ->setCommandName($notification->object_type === 'host'
-                            ? $this->event->host->checkcommand_name
-                            : $this->event->service->checkcommand_name)
-                ))
+                ], $notificationText)
             ];
         } else {
             $pluginOutput[] = new EmptyState(t('Waiting for Icinga DB to synchronize the config.'));
@@ -171,16 +179,22 @@ class EventDetail extends BaseHtmlElement
             ? $this->event->host->checkcommand_name
             : $this->event->service->checkcommand_name;
         if (isset($commandName)) {
+            if (empty($stateChange->output) && empty($stateChange->long_output)) {
+                $commandOutput = new EmptyState(t('Output unavailable.'));
+            } else {
+                $commandOutput = new PluginOutputContainer(
+                    (new PluginOutput($stateChange->output . "\n" . $stateChange->long_output))
+                        ->setCommandName($commandName)
+                );
+            }
+
             $pluginOutput = [
                 new HtmlElement('h2', null, Text::create(t('Plugin Output'))),
                 HtmlElement::create('div', [
                     'id'    => 'check-output-' . $commandName,
                     'class' => 'collapsible',
                     'data-visible-height' => 100
-                ], new PluginOutputContainer(
-                    (new PluginOutput($stateChange->output . "\n" . $stateChange->long_output))
-                        ->setCommandName($commandName)
-                ))
+                ], $commandOutput)
             ];
         } else {
             $pluginOutput[] = new EmptyState(t('Waiting for Icinga DB to synchronize the config.'));
@@ -253,7 +267,7 @@ class EventDetail extends BaseHtmlElement
     {
         $commentInfo = [
             new HtmlElement('h2', null, Text::create(t('Comment'))),
-            new MarkdownText($downtime->comment)
+            new MarkdownText($this->createTicketLinks($downtime->comment))
         ];
 
         $eventInfo = [new HtmlElement('h2', null, Text::create(t('Event Info')))];
@@ -352,7 +366,7 @@ class EventDetail extends BaseHtmlElement
     {
         $commentInfo = [
             new HtmlElement('h2', null, Text::create(t('Comment'))),
-            new MarkdownText($comment->comment)
+            new MarkdownText($this->createTicketLinks($comment->comment))
         ];
 
         $eventInfo = [new HtmlElement('h2', null, Text::create(t('Event Info')))];
@@ -464,7 +478,7 @@ class EventDetail extends BaseHtmlElement
         if ($acknowledgement->comment) {
             $commentInfo = [
                 new HtmlElement('h2', null, Text::create(t('Comment'))),
-                new MarkdownText($acknowledgement->comment)
+                new MarkdownText($this->createTicketLinks($acknowledgement->comment))
             ];
         } elseif (! isset($acknowledgement->author)) {
             $commentInfo[] = new EmptyState(t('This acknowledgement was set before Icinga DB history recording'));
@@ -519,7 +533,7 @@ class EventDetail extends BaseHtmlElement
             } else {
                 $expired = false;
                 if ($acknowledgement->expire_time) {
-                    $now = (new DateTime())->setTimezone(new DateTimeZone(DateTimeZone::UTC));
+                    $now = (new DateTime())->setTimezone(new DateTimeZone('UTC'));
                     $expiresOn = clone $now;
                     $expiresOn->setTimestamp($acknowledgement->expire_time);
                     if ($now <= $expiresOn) {


=====================================
library/Icingadb/Widget/Detail/ObjectDetail.php
=====================================
@@ -10,7 +10,6 @@ use Icinga\Application\Hook;
 use Icinga\Application\Hook\GrapherHook;
 use Icinga\Application\Icinga;
 use Icinga\Application\Logger;
-use Icinga\Application\Modules\Module;
 use Icinga\Date\DateFormatter;
 use Icinga\Exception\IcingaException;
 use Icinga\Module\Icingadb\Common\Auth;
@@ -132,7 +131,7 @@ class ObjectDetail extends BaseHtmlElement
             $item->setObject($this->object);
         }
 
-        foreach ($this->object->action_url->action_url ?? [] as $url) {
+        foreach ($this->object->action_url->first()->action_url ?? [] as $url) {
             $url = $this->expandMacros($url, $this->object);
             $navigation->addItem(
                 Html::wantHtml([
@@ -160,7 +159,7 @@ class ObjectDetail extends BaseHtmlElement
             }
         }
 
-        if (Module::exists('monitoring')) {
+        if (Icinga::app()->getModuleManager()->hasInstalled('monitoring')) {
             foreach (Hook::all('Monitoring\\' . ucfirst($this->objectType) . 'Actions') as $hook) {
                 $moduleName = ClassLoader::extractModuleName(get_class($hook));
                 if (! isset($nativeExtensionProviders[$moduleName])) {
@@ -216,7 +215,7 @@ class ObjectDetail extends BaseHtmlElement
         $content = [Html::tag('h2', t('Comments'))];
 
         if ($comments->hasResult()) {
-            $content[] = (new CommentList($comments))->setObjectLinkDisabled();
+            $content[] = (new CommentList($comments))->setObjectLinkDisabled()->setTicketLinkEnabled();
             $content[] = (new ShowMore($comments, $link))->setBaseTarget('_next');
         } else {
             $content[] = new EmptyState(t('No comments created.'));
@@ -267,7 +266,7 @@ class ObjectDetail extends BaseHtmlElement
         $content = [Html::tag('h2', t('Downtimes'))];
 
         if ($downtimes->hasResult()) {
-            $content[] = (new DowntimeList($downtimes))->setObjectLinkDisabled();
+            $content[] = (new DowntimeList($downtimes))->setObjectLinkDisabled()->setTicketLinkEnabled();
             $content[] = (new ShowMore($downtimes, $link))->setBaseTarget('_next');
         } else {
             $content[] = new EmptyState(t('No downtimes scheduled.'));
@@ -320,7 +319,7 @@ class ObjectDetail extends BaseHtmlElement
         $navigation = new Navigation();
         $notes = trim($this->object->notes);
 
-        foreach ($this->object->notes_url->notes_url ?? [] as $url) {
+        foreach ($this->object->notes_url->first()->notes_url ?? [] as $url) {
             $url = $this->expandMacros($url, $this->object);
             $navigation->addItem(
                 Html::wantHtml([
@@ -446,7 +445,7 @@ class ObjectDetail extends BaseHtmlElement
             }
         }
 
-        if (! Module::exists('monitoring')) {
+        if (! Icinga::app()->getModuleManager()->hasInstalled('monitoring')) {
             return $extensions;
         }
 


=====================================
library/Icingadb/Widget/ItemList/BaseCommentListItem.php
=====================================
@@ -4,6 +4,7 @@
 
 namespace Icinga\Module\Icingadb\Widget\ItemList;
 
+use Icinga\Module\Icingadb\Common\TicketLinks;
 use ipl\Html\Html;
 use Icinga\Module\Icingadb\Common\HostLink;
 use Icinga\Module\Icingadb\Common\Icons;
@@ -37,10 +38,12 @@ abstract class BaseCommentListItem extends BaseListItem
     use ServiceLink;
     use NoSubjectLink;
     use ObjectLinkDisabled;
+    use TicketLinks;
 
     protected function assembleCaption(BaseHtmlElement $caption)
     {
-        $markdownLine = new MarkdownLine($this->item->text);
+        $markdownLine = new MarkdownLine($this->createTicketLinks($this->item->text));
+
         $caption->getAttributes()->add($markdownLine->getAttributes());
         $caption->addFrom($markdownLine);
     }
@@ -119,6 +122,7 @@ abstract class BaseCommentListItem extends BaseListItem
 
     protected function init()
     {
+        $this->setTicketLinkEnabled($this->list->getTicketLinkEnabled());
         $this->list->addDetailFilterAttribute($this, Filter::equal('name', $this->item->name));
         $this->list->addMultiselectFilterAttribute($this, Filter::equal('name', $this->item->name));
         $this->setObjectLinkDisabled($this->list->getObjectLinkDisabled());


=====================================
library/Icingadb/Widget/ItemList/BaseDowntimeListItem.php
=====================================
@@ -12,6 +12,7 @@ use Icinga\Module\Icingadb\Common\Links;
 use Icinga\Module\Icingadb\Common\NoSubjectLink;
 use Icinga\Module\Icingadb\Common\ObjectLinkDisabled;
 use Icinga\Module\Icingadb\Common\ServiceLink;
+use Icinga\Module\Icingadb\Common\TicketLinks;
 use Icinga\Module\Icingadb\Model\Downtime;
 use Icinga\Module\Icingadb\Widget\MarkdownLine;
 use ipl\Html\BaseHtmlElement;
@@ -35,6 +36,7 @@ abstract class BaseDowntimeListItem extends BaseListItem
     use ServiceLink;
     use NoSubjectLink;
     use ObjectLinkDisabled;
+    use TicketLinks;
 
     /** @var int Current Time */
     protected $currentTime;
@@ -75,6 +77,7 @@ abstract class BaseDowntimeListItem extends BaseListItem
         $this->list->addMultiselectFilterAttribute($this, Filter::equal('name', $this->item->name));
         $this->setObjectLinkDisabled($this->list->getObjectLinkDisabled());
         $this->setNoSubjectLink($this->list->getNoSubjectLink());
+        $this->setTicketLinkEnabled($this->list->getTicketLinkEnabled());
 
         if ($this->item->is_in_effect) {
             $this->getAttributes()->add('class', 'in-effect');
@@ -106,7 +109,7 @@ abstract class BaseDowntimeListItem extends BaseListItem
 
     protected function assembleCaption(BaseHtmlElement $caption)
     {
-        $markdownLine = new MarkdownLine($this->item->comment);
+        $markdownLine = new MarkdownLine($this->createTicketLinks($this->item->comment));
         $caption->getAttributes()->add($markdownLine->getAttributes());
         $caption->addHtml(
             new HtmlElement(


=====================================
library/Icingadb/Widget/ItemList/BaseHistoryListItem.php
=====================================
@@ -9,6 +9,7 @@ use Icinga\Module\Icingadb\Common\HostLink;
 use Icinga\Module\Icingadb\Common\HostStates;
 use Icinga\Module\Icingadb\Common\Icons;
 use Icinga\Module\Icingadb\Common\Links;
+use Icinga\Module\Icingadb\Common\TicketLinks;
 use Icinga\Module\Icingadb\Widget\EmptyState;
 use Icinga\Module\Icingadb\Widget\MarkdownLine;
 use Icinga\Module\Icingadb\Common\NoSubjectLink;
@@ -34,6 +35,7 @@ abstract class BaseHistoryListItem extends BaseListItem
     use HostLink;
     use NoSubjectLink;
     use ServiceLink;
+    use TicketLinks;
 
     /** @var History */
     protected $item;
@@ -44,6 +46,7 @@ abstract class BaseHistoryListItem extends BaseListItem
     protected function init()
     {
         $this->setNoSubjectLink($this->list->getNoSubjectLink());
+        $this->setTicketLinkEnabled($this->list->getTicketLinkEnabled());
         $this->list->addDetailFilterAttribute($this, Filter::equal('id', bin2hex($this->item->id)));
     }
 
@@ -54,7 +57,7 @@ abstract class BaseHistoryListItem extends BaseListItem
         switch ($this->item->event_type) {
             case 'comment_add':
             case 'comment_remove':
-                $markdownLine = new MarkdownLine($this->item->comment->comment);
+                $markdownLine = new MarkdownLine($this->createTicketLinks($this->item->comment->comment));
                 $caption->getAttributes()->add($markdownLine->getAttributes());
                 $caption->add([
                     new Icon(Icons::USER),
@@ -65,7 +68,7 @@ abstract class BaseHistoryListItem extends BaseListItem
                 break;
             case 'downtime_end':
             case 'downtime_start':
-                $markdownLine = new MarkdownLine($this->item->downtime->comment);
+                $markdownLine = new MarkdownLine($this->createTicketLinks($this->item->downtime->comment));
                 $caption->getAttributes()->add($markdownLine->getAttributes());
                 $caption->add([
                     new Icon(Icons::USER),
@@ -106,7 +109,7 @@ abstract class BaseHistoryListItem extends BaseListItem
                         t('This acknowledgement was set before Icinga DB history recording')
                     ));
                 } else {
-                    $markdownLine = new MarkdownLine($this->item->acknowledgement->comment);
+                    $markdownLine = new MarkdownLine($this->createTicketLinks($this->item->acknowledgement->comment));
                     $caption->getAttributes()->add($markdownLine->getAttributes());
                     $caption->add([
                         new Icon(Icons::USER),
@@ -129,10 +132,14 @@ abstract class BaseHistoryListItem extends BaseListItem
                         ? $this->item->host->checkcommand_name
                         : $this->item->service->checkcommand_name;
                     if (isset($commandName)) {
-                        $caption->addHtml(new PluginOutputContainer(
-                            (new PluginOutput($this->item->notification->text))
-                                ->setCommandName($commandName)
-                        ));
+                        if (empty($this->item->notification->text)) {
+                            $caption->addHtml(new EmptyState(t('Output unavailable.')));
+                        } else {
+                            $caption->addHtml(new PluginOutputContainer(
+                                (new PluginOutput($this->item->notification->text))
+                                    ->setCommandName($commandName)
+                            ));
+                        }
                     } else {
                         $caption->addHtml(new EmptyState(t('Waiting for Icinga DB to synchronize the config.')));
                     }
@@ -144,10 +151,14 @@ abstract class BaseHistoryListItem extends BaseListItem
                     ? $this->item->host->checkcommand_name
                     : $this->item->service->checkcommand_name;
                 if (isset($commandName)) {
-                    $caption->addHtml(new PluginOutputContainer(
-                        (new PluginOutput($this->item->state->output))
-                            ->setCommandName($commandName)
-                    ));
+                    if (empty($this->item->state->output)) {
+                        $caption->addHtml(new EmptyState(t('Output unavailable.')));
+                    } else {
+                        $caption->addHtml(new PluginOutputContainer(
+                            (new PluginOutput($this->item->state->output))
+                                ->setCommandName($commandName)
+                        ));
+                    }
                 } else {
                     $caption->addHtml(new EmptyState(t('Waiting for Icinga DB to synchronize the config.')));
                 }


=====================================
library/Icingadb/Widget/ItemList/BaseNotificationListItem.php
=====================================
@@ -82,10 +82,14 @@ abstract class BaseNotificationListItem extends BaseListItem
                 ? $this->item->host->checkcommand_name
                 : $this->item->service->checkcommand_name;
             if (isset($commandName)) {
-                $caption->addHtml(new PluginOutputContainer(
-                    (new PluginOutput($this->item->text))
-                        ->setCommandName($commandName)
-                ));
+                if (empty($this->item->text)) {
+                    $caption->addHtml(new EmptyState(t('Output unavailable.')));
+                } else {
+                    $caption->addHtml(new PluginOutputContainer(
+                        (new PluginOutput($this->item->text))
+                            ->setCommandName($commandName)
+                    ));
+                }
             } else {
                 $caption->addHtml(new EmptyState(t('Waiting for Icinga DB to synchronize the config.')));
             }


=====================================
library/Icingadb/Widget/ItemList/CommentList.php
=====================================
@@ -8,6 +8,7 @@ use Icinga\Module\Icingadb\Common\CaptionDisabled;
 use Icinga\Module\Icingadb\Common\Links;
 use Icinga\Module\Icingadb\Common\NoSubjectLink;
 use Icinga\Module\Icingadb\Common\ObjectLinkDisabled;
+use Icinga\Module\Icingadb\Common\TicketLinks;
 use Icinga\Module\Icingadb\Common\ViewMode;
 use Icinga\Module\Icingadb\Common\BaseItemList;
 use ipl\Web\Url;
@@ -18,6 +19,7 @@ class CommentList extends BaseItemList
     use NoSubjectLink;
     use ObjectLinkDisabled;
     use ViewMode;
+    use TicketLinks;
 
     protected $defaultAttributes = ['class' => 'comment-list'];
 


=====================================
library/Icingadb/Widget/ItemList/DowntimeList.php
=====================================
@@ -9,6 +9,7 @@ use Icinga\Module\Icingadb\Common\CaptionDisabled;
 use Icinga\Module\Icingadb\Common\Links;
 use Icinga\Module\Icingadb\Common\NoSubjectLink;
 use Icinga\Module\Icingadb\Common\ObjectLinkDisabled;
+use Icinga\Module\Icingadb\Common\TicketLinks;
 use Icinga\Module\Icingadb\Common\ViewMode;
 use ipl\Web\Url;
 
@@ -18,6 +19,7 @@ class DowntimeList extends BaseItemList
     use NoSubjectLink;
     use ObjectLinkDisabled;
     use ViewMode;
+    use TicketLinks;
 
     protected $defaultAttributes = ['class' => 'downtime-list'];
 


=====================================
library/Icingadb/Widget/ItemList/HistoryList.php
=====================================
@@ -7,6 +7,7 @@ namespace Icinga\Module\Icingadb\Widget\ItemList;
 use Icinga\Module\Icingadb\Common\CaptionDisabled;
 use Icinga\Module\Icingadb\Common\LoadMore;
 use Icinga\Module\Icingadb\Common\NoSubjectLink;
+use Icinga\Module\Icingadb\Common\TicketLinks;
 use Icinga\Module\Icingadb\Common\ViewMode;
 use Icinga\Module\Icingadb\Common\BaseItemList;
 use ipl\Orm\ResultSet;
@@ -18,6 +19,7 @@ class HistoryList extends BaseItemList
     use NoSubjectLink;
     use ViewMode;
     use LoadMore;
+    use TicketLinks;
 
     protected $defaultAttributes = ['class' => 'history-list'];
 


=====================================
library/Icingadb/Widget/ItemList/HostListItemDetailed.php
=====================================
@@ -31,7 +31,7 @@ class HostListItemDetailed extends BaseHostListItem
     {
         $statusIcons = new HtmlElement('div', Attributes::create(['class' => 'status-icons']));
 
-        if ($this->item->state->last_comment_id !== null) {
+        if ($this->item->state->last_comment->host_id === $this->item->id) {
             $comment = $this->item->state->last_comment;
             $comment->host = $this->item;
             $comment = (new CommentList([$comment]))


=====================================
library/Icingadb/Widget/ItemList/ServiceListItemDetailed.php
=====================================
@@ -31,7 +31,7 @@ class ServiceListItemDetailed extends BaseServiceListItem
     {
         $statusIcons = new HtmlElement('div', Attributes::create(['class' => 'status-icons']));
 
-        if ($this->item->state->last_comment_id !== null) {
+        if ($this->item->state->last_comment->service_id === $this->item->id) {
             $comment = $this->item->state->last_comment;
             $comment->service = $this->item;
             $comment = (new CommentList([$comment]))


=====================================
module.info
=====================================
@@ -1,5 +1,5 @@
 Module: icingadb
-Version: 1.0.1
+Version: 1.0.2
 Requires:
   Libraries: icinga-php-library (>=0.10.0), icinga-php-thirdparty (>=0.11.0)
 Description: Icinga DB Web


=====================================
public/css/common.less
=====================================
@@ -28,10 +28,6 @@
   color: @gray-semilight;
 }
 
-.pagination-control {
-  float: none;
-}
-
 div.show-more {
   .clearfix();
   float: right;
@@ -104,19 +100,6 @@ div.show-more {
     background-color: @gray-lighter;
   }
 
-  .filter {
-    display: flex;
-    min-width: 100%;
-
-    .search-bar {
-      flex: 1 1 auto;
-    }
-  }
-
-  .pagination-control {
-    float: left;
-  }
-
   .limit-control,
   .view-mode-switcher,
   .sort-control {
@@ -148,46 +131,63 @@ div.show-more {
     }
   }
 
-  .control-button {
+  .search-controls .continue-with {
+    margin-right: -.5em;
     margin-left: .5em;
   }
 
-  .continue-with,
-  .search-editor-opener {
-    &:last-child {
-      margin-right: -.5em;
-    }
+  .show-more {
+    margin-top: .25em;
   }
 
-  .search-suggestions {
-    margin-bottom: 2.5em;
+  .notice {
+    display: none;
   }
 
-  .sort-control {
-    display: flex;
-    justify-content: flex-end;
+  // TODO: Remove once ipl-web v0.7.0 is required
+  &:not(.default-layout) {
+    .pagination-control {
+      float: left;
+    }
+
+    .sort-control {
+      display: flex;
+      justify-content: flex-end;
+
+      :not(.form-element) > label {
+        margin-right: 0;
+      }
 
-    // Icinga Web 2 override
-    label {
-      margin-right: 0;
+      .control-button {
+        margin: 0;
+      }
     }
 
-    // Icinga Web 2 override
-    .spinner {
-      height: 100%;
+    > :not(:only-child) {
+      margin-bottom: 0.5em;
     }
 
-    .control-button {
-      margin: 0;
+    .search-suggestions {
+      margin-bottom: 2.5em;
     }
-  }
 
-  .show-more {
-    margin-top: .25em;
-  }
+    .search-controls {
+      clear: both;
+      display: flex;
+      min-width: 100%;
 
-  .notice {
-    display: none;
+      .search-bar {
+        flex: 1 1 auto;
+
+        & ~ .control-button:last-child {
+          margin-right: -.5em;
+        }
+
+        & ~ .control-button {
+          margin-left: .5em;
+        }
+      }
+    }
   }
 }
 


=====================================
public/css/widget/quick-actions.less
=====================================
@@ -28,6 +28,7 @@
   }
 }
 
+.controls:not(.default-layout) > .quick-actions:last-child,
 .controls > .quick-actions:last-child {
   margin-bottom: 0;
 }


=====================================
public/js/action-list.js
=====================================
@@ -35,7 +35,7 @@
         var $item = $target.closest('[data-action-item]');
         var $list = $item.closest('.action-list');
 
-        if ($target.is('a') && ! $target.is('.subject')) {
+        if ($target.is('a') && (! $target.is('.subject') || event.ctrlKey || event.metaKey)) {
             return true;
         }
 



View it on GitLab: https://salsa.debian.org/nagios-team/icingadb-web/-/commit/5a821163c49218ef8c17f5d4ace249b16be21e03

-- 
View it on GitLab: https://salsa.debian.org/nagios-team/icingadb-web/-/commit/5a821163c49218ef8c17f5d4ace249b16be21e03
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-nagios-changes/attachments/20221105/5c13c4e9/attachment-0001.htm>


More information about the pkg-nagios-changes mailing list