diff --git a/application/controllers/ReportController.php b/application/controllers/ReportController.php index f10bab6e..09a23b5a 100644 --- a/application/controllers/ReportController.php +++ b/application/controllers/ReportController.php @@ -4,6 +4,7 @@ namespace Icinga\Module\Reporting\Controllers; +use Exception; use Icinga\Application\Hook; use Icinga\Module\Pdfexport\ProvidedHook\Pdfexport; use Icinga\Module\Reporting\Database; @@ -16,6 +17,7 @@ use Icinga\Module\Reporting\Web\Widget\CompatDropdown; use Icinga\Web\Notification; use ipl\Html\Error; +use ipl\Html\HtmlElement; use ipl\Stdlib\Filter; use ipl\Web\Url; use ipl\Web\Widget\ActionBar; @@ -50,15 +52,31 @@ public function indexAction() { $this->addTitleTab($this->report->getName()); + $this->controls->getAttributes()->add('class', 'default-layout'); $this->addControl($this->assembleActions()); + /** @var string $contentId */ + $contentId = $this->content->getAttributes()->get('id')->getValue(); + $this->sendExtraUpdates([ + $contentId => Url::fromPath('reporting/report/content', ['id' => $this->report->getId()]) + ]); + + // Will be replaced once the report content is rendered + $this->addContent(new HtmlElement('div')); + } + + public function contentAction(): void + { Environment::raiseExecutionTime(); Environment::raiseMemoryLimit(); + $this->view->compact = true; + $this->_helper->layout()->disableLayout(); + try { - $this->addContent($this->report->toHtml()); - } catch (\Exception $e) { - $this->addContent(Error::show($e)); + $this->getDocument()->addHtml($this->report->toHtml()); + } catch (Exception $e) { + $this->getDocument()->addHtml(Error::show($e)); } } @@ -89,8 +107,12 @@ public function cloneAction() ->setSubmitButtonLabel($this->translate('Clone Report')) ->setAction((string) Url::fromRequest()) ->populate($values) - ->on(ReportForm::ON_SUCCESS, function () { - $this->redirectNow('__CLOSE__'); + ->on(ReportForm::ON_SUCCESS, function (ReportForm $form) { + Notification::success($this->translate('Cloned report successfully')); + + $this->sendExtraUpdates(['#col1']); + + $this->redirectNow(Url::fromPath('reporting/report', ['id' => $form->getId()])); }) ->handleRequest($this->getServerRequest()); @@ -120,8 +142,19 @@ public function editAction() $form = ReportForm::fromId($this->report->getId()) ->setAction((string) Url::fromRequest()) ->populate($values) - ->on(ReportForm::ON_SUCCESS, function () { - $this->redirectNow('__CLOSE__'); + ->on(ReportForm::ON_SUCCESS, function (ReportForm $form) { + $pressedButton = $form->getPressedSubmitElement(); + if ($pressedButton && $pressedButton->getName() === 'remove') { + Notification::success($this->translate('Removed report successfully')); + + $this->switchToSingleColumnLayout(); + } else { + Notification::success($this->translate('Updated report successfully')); + + $this->closeModalAndRefreshRemainingViews( + Url::fromPath('reporting/report', ['id' => $this->report->getId()]) + ); + } }) ->handleRequest($this->getServerRequest()); @@ -139,7 +172,9 @@ public function sendAction() ->setReport($this->report) ->setAction((string) Url::fromRequest()) ->on(SendForm::ON_SUCCESS, function () { - $this->redirectNow("reporting/report?id={$this->report->getId()}"); + $this->closeModalAndRefreshRelatedView( + Url::fromPath('reporting/report', ['id' => $this->report->getId()]) + ); }) ->handleRequest($this->getServerRequest()); @@ -169,7 +204,9 @@ public function scheduleAction() Notification::success($this->translate('Created schedule successfully')); } - $this->redirectNow("reporting/report?id={$this->report->getId()}"); + $this->closeModalAndRefreshRelatedView( + Url::fromPath('reporting/report', ['id' => $this->report->getId()]) + ); }) ->handleRequest($this->getServerRequest()); @@ -259,56 +296,40 @@ protected function assembleActions() if ($this->hasPermission('reporting/reports')) { $actions->addHtml( - new ActionLink( + (new ActionLink( $this->translate('Modify'), Url::fromPath('reporting/report/edit', ['id' => $reportId]), - 'edit', - [ - 'data-icinga-modal' => true, - 'data-no-icinga-ajax' => true - ] - ) + 'edit' + ))->openInModal() ); $actions->addHtml( - new ActionLink( + (new ActionLink( $this->translate('Clone'), Url::fromPath('reporting/report/clone', ['id' => $reportId]), - 'clone', - [ - 'data-icinga-modal' => true, - 'data-no-icinga-ajax' => true - ] - ) + 'clone' + ))->openInModal() ); } if ($this->hasPermission('reporting/schedules')) { $actions->addHtml( - new ActionLink( + (new ActionLink( $this->translate('Schedule'), Url::fromPath('reporting/report/schedule', ['id' => $reportId]), - 'calendar-empty', - [ - 'data-icinga-modal' => true, - 'data-no-icinga-ajax' => true - ] - ) + 'calendar-empty' + ))->openInModal() ); } $actions ->add($download) ->addHtml( - new ActionLink( + (new ActionLink( $this->translate('Send'), Url::fromPath('reporting/report/send', ['id' => $reportId]), - 'forward', - [ - 'data-icinga-modal' => true, - 'data-no-icinga-ajax' => true - ] - ) + 'forward' + ))->openInModal() ); return $actions; diff --git a/application/controllers/ReportsController.php b/application/controllers/ReportsController.php index 74583b6d..b63714a9 100644 --- a/application/controllers/ReportsController.php +++ b/application/controllers/ReportsController.php @@ -11,11 +11,10 @@ use Icinga\Module\Reporting\Web\Controller; use Icinga\Module\Reporting\Web\Forms\ReportForm; use Icinga\Module\Reporting\Web\ReportsTimeframesAndTemplatesTabs; +use Icinga\Web\Notification; use ipl\Html\Html; use ipl\Web\Url; use ipl\Web\Widget\ButtonLink; -use ipl\Web\Widget\Icon; -use ipl\Web\Widget\Link; class ReportsController extends Controller { @@ -25,17 +24,16 @@ class ReportsController extends Controller public function indexAction() { $this->createTabs()->activate('reports'); + $this->getTabs()->getAttributes()->set('data-base-target', '_main'); if ($this->hasPermission('reporting/reports')) { - $this->addControl(new ButtonLink( - $this->translate('New Report'), - Url::fromPath('reporting/reports/new'), - 'plus', - [ - 'data-icinga-modal' => true, - 'data-no-icinga-ajax' => true - ] - )); + $this->addControl( + (new ButtonLink( + $this->translate('New Report'), + Url::fromPath('reporting/reports/new'), + 'plus' + ))->openInModal() + ); } $tableRows = []; @@ -65,16 +63,7 @@ public function indexAction() Html::tag('td', null, $report->timeframe->name), Html::tag('td', null, $report->ctime->format('Y-m-d H:i')), Html::tag('td', null, $report->mtime->format('Y-m-d H:i')), - Html::tag('td', ['class' => 'icon-col'], [ - new Link( - new Icon('edit'), - Url::fromPath('reporting/report/edit', ['id' => $report->id]), - [ - 'data-icinga-modal' => true, - 'data-no-icinga-ajax' => true - ] - ) - ]) + Html::tag('td', null, $report->mtime->format('Y-m-d H:i')) ]); } @@ -128,14 +117,27 @@ public function newAction() $form = (new ReportForm()) ->setAction((string) Url::fromRequest()) + ->setRenderCreateAndShowButton($class !== null) ->populate([ 'filter' => $this->params->shift('filter'), 'reportlet' => $class ]) - ->on(ReportForm::ON_SUCCESS, function () { - $this->getResponse()->setHeader('X-Icinga-Container', 'modal-content', true); - - $this->redirectNow('__CLOSE__'); + ->on(ReportForm::ON_SUCCESS, function (ReportForm $form) { + Notification::success($this->translate('Created report successfully')); + + $pressedButton = $form->getPressedSubmitElement(); + if ($pressedButton && $pressedButton->getName() !== 'create_show') { + $this->closeModalAndRefreshRelatedView(Url::fromPath('reporting/reports')); + } else { + $this->redirectNow( + Url::fromPath( + sprintf( + 'reporting/reports#!%s', + Url::fromPath('reporting/report', ['id' => $form->getId()])->getAbsoluteUrl() + ) + ) + ); + } }) ->handleRequest($this->getServerRequest()); diff --git a/application/controllers/TemplateController.php b/application/controllers/TemplateController.php index c37f4720..8d2c1cd1 100644 --- a/application/controllers/TemplateController.php +++ b/application/controllers/TemplateController.php @@ -13,16 +13,23 @@ use Icinga\Module\Reporting\Web\Forms\TemplateForm; use Icinga\Module\Reporting\Web\Widget\Template; use Icinga\Web\Notification; +use ipl\Html\Form; +use ipl\Html\ValidHtml; use ipl\Stdlib\Filter; use ipl\Web\Url; +use ipl\Web\Widget\ActionBar; +use ipl\Web\Widget\ActionLink; class TemplateController extends Controller { use Database; - public function indexAction() + /** @var Model\Template */ + protected $template; + + public function init() { - $this->createTabs()->activate('preview'); + parent::init(); /** @var Model\Template $template */ $template = Model\Template::on($this->getDb()) @@ -33,7 +40,17 @@ public function indexAction() throw new Exception('Template not found'); } - $template = Template::fromModel($template) + $this->template = $template; + } + + public function indexAction() + { + $this->addTitleTab($this->translate('Preview')); + + $this->controls->getAttributes()->add('class', 'default-layout'); + $this->addControl($this->createActionBars()); + + $template = Template::fromModel($this->template) ->setMacros([ 'date' => (new DateTime())->format('jS M, Y'), 'time_frame' => 'Time Frame', @@ -48,51 +65,40 @@ public function indexAction() public function editAction() { $this->assertPermission('reporting/templates'); + $this->addTitleTab($this->translate('Edit Template')); - $this->createTabs()->activate('edit'); - - /** @var Model\Template $template */ - $template = Model\Template::on($this->getDb()) - ->filter(Filter::equal('id', $this->params->getRequired('id'))) - ->first(); - - if ($template === false) { - throw new Exception('Template not found'); - } - - $template->settings = json_decode($template->settings, true); - - $form = TemplateForm::fromTemplate($template) + $form = TemplateForm::fromTemplate($this->template) ->setAction((string) Url::fromRequest()) - ->on(TemplateForm::ON_SUCCESS, function () { - Notification::success($this->translate('Updated template successfully')); - - $this->redirectNow('__CLOSE__'); + ->on(TemplateForm::ON_SUCCESS, function (Form $form) { + $pressedButton = $form->getPressedSubmitElement(); + if ($pressedButton && $pressedButton->getName() === 'remove') { + Notification::success($this->translate('Removed template successfully')); + + $this->switchToSingleColumnLayout(); + } else { + Notification::success($this->translate('Updated template successfully')); + + $this->closeModalAndRefreshRemainingViews( + Url::fromPath('reporting/template', ['id' => $this->template->id]) + ); + } }) ->handleRequest(ServerRequest::fromGlobals()); - $this->setTitle($this->translate('Edit template')); $this->addContent($form); } - protected function createTabs() + protected function createActionBars(): ValidHtml { - $tabs = $this->getTabs(); - - if ($this->hasPermission('reporting/templates')) { - $tabs->add('edit', [ - 'title' => $this->translate('Edit template'), - 'label' => $this->translate('Edit Template'), - 'url' => 'reporting/template/edit?id=' . $this->params->getRequired('id') - ]); - } - - $tabs->add('preview', [ - 'title' => $this->translate('Preview template'), - 'label' => $this->translate('Preview'), - 'url' => 'reporting/template?id=' . $this->params->getRequired('id') - ]); - - return $tabs; + $actions = new ActionBar(); + $actions->addHtml( + (new ActionLink( + $this->translate('Modify'), + Url::fromPath('reporting/template/edit', ['id' => $this->template->id]), + 'edit' + ))->openInModal() + ); + + return $actions; } } diff --git a/application/controllers/TemplatesController.php b/application/controllers/TemplatesController.php index d8faa988..cf1875ff 100644 --- a/application/controllers/TemplatesController.php +++ b/application/controllers/TemplatesController.php @@ -4,7 +4,6 @@ namespace Icinga\Module\Reporting\Controllers; -use GuzzleHttp\Psr7\ServerRequest; use Icinga\Module\Reporting\Database; use Icinga\Module\Reporting\Model; use Icinga\Module\Reporting\Web\Controller; @@ -28,15 +27,13 @@ public function indexAction() $canManage = $this->hasPermission('reporting/templates'); if ($canManage) { - $this->addControl(new ButtonLink( - $this->translate('New Template'), - Url::fromPath('reporting/templates/new'), - 'plus', - [ - 'data-icinga-modal' => true, - 'data-no-icinga-ajax' => true - ] - )); + $this->addControl( + (new ButtonLink( + $this->translate('New Template'), + Url::fromPath('reporting/templates/new'), + 'plus' + ))->openInModal() + ); } $templates = Model\Template::on($this->getDb()); @@ -58,20 +55,8 @@ public function indexAction() /** @var Model\Template $template */ foreach ($templates as $template) { - if ($canManage) { - $subjectLink = new Link( - $template->name, - Url::fromPath('reporting/template/edit', ['id' => $template->id]), - [ - 'data-icinga-modal' => true, - 'data-no-icinga-ajax' => true - ] - ); - } else { - // Preview URL - $subjectLink = new Link($template->name, Url::fromPath('reporting/template', ['id' => $template->id])); - } - + // Preview URL + $subjectLink = new Link($template->name, Url::fromPath('reporting/template', ['id' => $template->id])); $tableRows[] = Html::tag('tr', null, [ Html::tag('td', null, $subjectLink), Html::tag('td', null, $template->author), @@ -119,9 +104,7 @@ public function newAction() ->on(TemplateForm::ON_SUCCESS, function () { Notification::success($this->translate('Created template successfully')); - $this->getResponse()->setHeader('X-Icinga-Container', 'modal-content', true); - - $this->redirectNow('__CLOSE__'); + $this->closeModalAndRefreshRelatedView(Url::fromPath('reporting/templates')); }) ->handleRequest($this->getServerRequest()); diff --git a/application/controllers/TimeframeController.php b/application/controllers/TimeframeController.php index 60ee3c27..c2818451 100644 --- a/application/controllers/TimeframeController.php +++ b/application/controllers/TimeframeController.php @@ -10,6 +10,8 @@ use Icinga\Module\Reporting\Timeframe; use Icinga\Module\Reporting\Web\Controller; use Icinga\Module\Reporting\Web\Forms\TimeframeForm; +use Icinga\Web\Notification; +use ipl\Html\Form; use ipl\Web\Url; use ipl\Stdlib\Filter; @@ -48,10 +50,15 @@ public function editAction() $form = TimeframeForm::fromId($this->timeframe->getId()) ->setAction((string) Url::fromRequest()) ->populate($values) - ->on(TimeframeForm::ON_SUCCESS, function () { - $this->getResponse()->setHeader('X-Icinga-Container', 'modal-content', true); + ->on(TimeframeForm::ON_SUCCESS, function (Form $form) { + $pressedButton = $form->getPressedSubmitElement(); + if ($pressedButton && $pressedButton->getName() === 'remove') { + Notification::success($this->translate('Removed timeframe successfully')); + } else { + Notification::success($this->translate('Update timeframe successfully')); + } - $this->redirectNow('__CLOSE__'); + $this->switchToSingleColumnLayout(); })->handleRequest($this->getServerRequest()); $this->addContent($form); diff --git a/application/controllers/TimeframesController.php b/application/controllers/TimeframesController.php index 698f16c7..96a1b688 100644 --- a/application/controllers/TimeframesController.php +++ b/application/controllers/TimeframesController.php @@ -9,6 +9,7 @@ use Icinga\Module\Reporting\Web\Controller; use Icinga\Module\Reporting\Web\Forms\TimeframeForm; use Icinga\Module\Reporting\Web\ReportsTimeframesAndTemplatesTabs; +use Icinga\Web\Notification; use ipl\Html\Html; use ipl\Web\Url; use ipl\Web\Widget\ButtonLink; @@ -26,15 +27,13 @@ public function indexAction() $canManage = $this->hasPermission('reporting/timeframes'); if ($canManage) { - $this->addControl(new ButtonLink( - $this->translate('New Timeframe'), - Url::fromPath('reporting/timeframes/new'), - 'plus', - [ - 'data-icinga-modal' => true, - 'data-no-icinga-ajax' => true - ] - )); + $this->addControl( + (new ButtonLink( + $this->translate('New Timeframe'), + Url::fromPath('reporting/timeframes/new'), + 'plus' + ))->openInModal() + ); } $tableRows = []; @@ -58,18 +57,11 @@ public function indexAction() if ($canManage) { $subject = new Link( $timeframe->name, - Url::fromPath('reporting/timeframe/edit', ['id' => $timeframe->id]), - [ - 'data-icinga-modal' => true, - 'data-no-icinga-ajax' => true - ] + Url::fromPath('reporting/timeframe/edit', ['id' => $timeframe->id]) ); } - $tableRows[] = Html::tag('tr', [ - 'data-icinga-modal' => true, - 'data-no-icinga-ajax' => true - ], [ + $tableRows[] = Html::tag('tr', null, [ Html::tag('td', null, $subject), Html::tag('td', null, $timeframe->start), Html::tag('td', null, $timeframe->end), @@ -81,7 +73,10 @@ public function indexAction() if (! empty($tableRows)) { $table = Html::tag( 'table', - ['class' => 'common-table table-row-selectable'], + [ + 'class' => 'common-table table-row-selectable', + 'data-base-target' => '_next' + ], [ Html::tag( 'thead', @@ -116,9 +111,9 @@ public function newAction() $form = (new TimeframeForm()) ->setAction((string) Url::fromRequest()) ->on(TimeframeForm::ON_SUCCESS, function () { - $this->getResponse()->setHeader('X-Icinga-Container', 'modal-content', true); + Notification::success($this->translate('Created timeframe successfully')); - $this->redirectNow('__CLOSE__'); + $this->closeModalAndRefreshRelatedView(Url::fromPath('reporting/timeframes')); })->handleRequest($this->getServerRequest()); $this->addContent($form); diff --git a/library/Reporting/Model/Report.php b/library/Reporting/Model/Report.php index 4b12b75d..b466a603 100644 --- a/library/Reporting/Model/Report.php +++ b/library/Reporting/Model/Report.php @@ -4,11 +4,23 @@ namespace Icinga\Module\Reporting\Model; +use DateTime; use ipl\Orm\Behavior\MillisecondTimestamp; use ipl\Orm\Behaviors; use ipl\Orm\Model; use ipl\Orm\Relations; +/** + * A Report database model + * + * @property int $id Unique identifier of this model + * @property int $timeframe_id The timeframe id used by this report + * @property int $template_id The template id used by this report + * @property string $author The author of this report + * @property string $name The name of this report + * @property DateTime $ctime The creation time of this report + * @property DateTime $mtime Modify time of this report + */ class Report extends Model { public function getTableName() diff --git a/library/Reporting/Web/Forms/ReportForm.php b/library/Reporting/Web/Forms/ReportForm.php index 7b5926b8..1cd8ac40 100644 --- a/library/Reporting/Web/Forms/ReportForm.php +++ b/library/Reporting/Web/Forms/ReportForm.php @@ -23,6 +23,9 @@ class ReportForm extends CompatForm /** @var string Label to use for the submit button */ protected $submitButtonLabel; + /** @var bool Whether to render the create and show submit button (is only used from DB Web's object detail) */ + protected $renderCreateAndShowButton = false; + /** * Create a new form instance with the given report id * @@ -38,6 +41,11 @@ public static function fromId($id): self return $form; } + public function getId(): ?int + { + return $this->id; + } + /** * Set the label of the submit button * @@ -66,9 +74,27 @@ public function getSubmitButtonLabel(): string return $this->id === null ? $this->translate('Create Report') : $this->translate('Update Report'); } + /** + * Set whether the create and show submit button should be rendered + * + * @param bool $renderCreateAndShowButton + * + * @return $this + */ + public function setRenderCreateAndShowButton(bool $renderCreateAndShowButton): self + { + $this->renderCreateAndShowButton = $renderCreateAndShowButton; + + return $this; + } + public function hasBeenSubmitted(): bool { - return $this->hasBeenSent() && ($this->getPopulatedValue('submit') || $this->getPopulatedValue('remove')); + return $this->hasBeenSent() && ( + $this->getPopulatedValue('submit') + || $this->getPopulatedValue('create_show') + || $this->getPopulatedValue('remove') + ); } protected function assemble() @@ -153,6 +179,15 @@ protected function assemble() /** @var HtmlDocument $wrapper */ $wrapper = $this->getElement('submit')->getWrapper(); $wrapper->prepend($removeButton); + } elseif ($this->renderCreateAndShowButton) { + $createAndShow = $this->createElement('submit', 'create_show', [ + 'label' => $this->translate('Create and Show'), + ]); + $this->registerElement($createAndShow); + + /** @var HtmlDocument $wrapper */ + $wrapper = $this->getElement('submit')->getWrapper(); + $wrapper->prepend($createAndShow); } } @@ -223,5 +258,7 @@ public function onSuccess() } $db->commitTransaction(); + + $this->id = $reportId; } } diff --git a/library/Reporting/Web/Forms/TemplateForm.php b/library/Reporting/Web/Forms/TemplateForm.php index 407a0a0f..381564a5 100644 --- a/library/Reporting/Web/Forms/TemplateForm.php +++ b/library/Reporting/Web/Forms/TemplateForm.php @@ -8,6 +8,7 @@ use GuzzleHttp\Psr7\UploadedFile; use Icinga\Authentication\Auth; use Icinga\Module\Reporting\Database; +use Icinga\Util\Json; use ipl\Html\Contract\FormSubmitElement; use ipl\Html\Html; use ipl\Html\HtmlDocument; @@ -35,10 +36,13 @@ public static function fromTemplate($template): self { $form = new static(); + $template->settings = Json::decode($template->settings, true); $form->template = $template; if ($template->settings) { - $form->populate(array_filter($template->settings, function ($value) { + /** @var array $settings */ + $settings = $template->settings; + $form->populate(array_filter($settings, function ($value) { // Don't populate files return ! is_array($value); })); diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 6d9c15a6..d6823e9a 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -165,11 +165,6 @@ parameters: count: 1 path: application/controllers/ReportsController.php - - - message: "#^Cannot call method format\\(\\) on mixed\\.$#" - count: 2 - path: application/controllers/ReportsController.php - - message: "#^Method Icinga\\\\Module\\\\Reporting\\\\Controllers\\\\ReportsController\\:\\:indexAction\\(\\) has no return type specified\\.$#" count: 1 @@ -190,11 +185,6 @@ parameters: count: 1 path: application/controllers/ReportsController.php - - - message: "#^Method Icinga\\\\Module\\\\Reporting\\\\Controllers\\\\TemplateController\\:\\:createTabs\\(\\) has no return type specified\\.$#" - count: 1 - path: application/controllers/TemplateController.php - - message: "#^Method Icinga\\\\Module\\\\Reporting\\\\Controllers\\\\TemplateController\\:\\:editAction\\(\\) has no return type specified\\.$#" count: 1 @@ -215,14 +205,9 @@ parameters: count: 1 path: application/controllers/TemplateController.php - - - message: "#^Parameter \\#1 \\$json of function json_decode expects string, mixed given\\.$#" - count: 1 - path: application/controllers/TemplateController.php - - message: "#^Parameter \\#2 \\$value of static method ipl\\\\Stdlib\\\\Filter\\:\\:equal\\(\\) expects array\\|bool\\|float\\|int\\|string, mixed given\\.$#" - count: 2 + count: 1 path: application/controllers/TemplateController.php - @@ -685,21 +670,6 @@ parameters: count: 1 path: library/Reporting/Report.php - - - message: "#^Property Icinga\\\\Module\\\\Reporting\\\\Report\\:\\:\\$author \\(string\\) does not accept mixed\\.$#" - count: 1 - path: library/Reporting/Report.php - - - - message: "#^Property Icinga\\\\Module\\\\Reporting\\\\Report\\:\\:\\$id \\(int\\) does not accept mixed\\.$#" - count: 1 - path: library/Reporting/Report.php - - - - message: "#^Property Icinga\\\\Module\\\\Reporting\\\\Report\\:\\:\\$name \\(string\\) does not accept mixed\\.$#" - count: 1 - path: library/Reporting/Report.php - - message: "#^Method Icinga\\\\Module\\\\Reporting\\\\ReportData\\:\\:getAverages\\(\\) has no return type specified\\.$#" count: 1 diff --git a/phpstan.neon b/phpstan.neon index 16cac333..264c33dc 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -24,6 +24,8 @@ parameters: - '#Call to an undefined method Icinga\\Module\\Reporting\\RetryConnection::lastInsertId\(\)#' + - '#Call to an undefined method Zend_Controller_Action_HelperBroker::layout\(\)#' + universalObjectCratesClasses: - Icinga\Web\View - ipl\Orm\Model diff --git a/public/css/module.less b/public/css/module.less index b8175045..c4ad1bd6 100644 --- a/public/css/module.less +++ b/public/css/module.less @@ -1,5 +1,9 @@ // Icinga Reporting | (c) 2018 Icinga GmbH | GPLv2 +.content:focus { + outline: none; +} + .sla-column { border-radius: 0.5em; color: @text-color-on-icinga-blue; @@ -84,16 +88,20 @@ } } -.action-bar .dropdown:first-child:hover .dropdown-menu { - left: .25em; -} +.action-bar { + line-height: 2em; -.action-bar .dropdown:last-child:hover .dropdown-menu { - right: .25em; -} + .dropdown:first-child:hover .dropdown-menu { + left: .25em; + } + + .dropdown:last-child:hover .dropdown-menu { + right: .25em; + } -.action-bar > *:not(:last-child) { - margin-right: .5em; + > *:not(:last-child) { + margin-right: .5em; + } } /* Stuff that's missing in ipl <= 0.8 END */