diff --git a/application/controllers/MigrateController.php b/application/controllers/MigrateController.php index 899f1f8fe..014c3328e 100644 --- a/application/controllers/MigrateController.php +++ b/application/controllers/MigrateController.php @@ -7,12 +7,15 @@ use Exception; use GuzzleHttp\Psr7\ServerRequest; use Icinga\Application\Hook; +use Icinga\Application\Icinga; use Icinga\Exception\IcingaException; use Icinga\Module\Icingadb\Compat\UrlMigrator; use Icinga\Module\Icingadb\Forms\SetAsBackendForm; use Icinga\Module\Icingadb\Hook\IcingadbSupportHook; use Icinga\Module\Icingadb\Web\Controller; use ipl\Html\HtmlString; +use ipl\Stdlib\Filter; +use ipl\Web\Filter\QueryString; use ipl\Web\Url; class MigrateController extends Controller @@ -65,6 +68,55 @@ public function monitoringUrlAction() $response->sendResponse(); } + public function searchUrlAction() + { + $this->assertHttpMethod('post'); + if (! $this->getRequest()->isApiRequest()) { + $this->httpBadRequest('No API request'); + } + + if ( + ! preg_match('/([^;]*);?/', $this->getRequest()->getHeader('Content-Type'), $matches) + || $matches[1] !== 'application/json' + ) { + $this->httpBadRequest('No JSON content'); + } + + $traverseFilter = function ($filter) use (&$traverseFilter) { + if ($filter instanceof Filter\Chain) { + foreach ($filter as $child) { + $newChild = $traverseFilter($child); + if ($newChild !== null) { + $filter->replace($child, $newChild); + } + } + } elseif ($filter instanceof Filter\Equal) { + if (strpos($filter->getValue(), '*') !== false) { + return Filter::like($filter->getColumn(), $filter->getValue()); + } + } elseif ($filter instanceof Filter\Unequal) { + if (strpos($filter->getValue(), '*') !== false) { + return Filter::unlike($filter->getColumn(), $filter->getValue()); + } + } + }; + + $urls = $this->getRequest()->getPost(); + + $result = []; + foreach ($urls as $urlString) { + $url = Url::fromPath($urlString); + $filter = QueryString::parse($url->getQueryString()); + $filter = $traverseFilter($filter) ?? $filter; + $result[] = $url->setQueryString(QueryString::render($filter))->getAbsoluteUrl(); + } + + $response = $this->getResponse()->json(); + $response->setSuccessData($result); + + $response->sendResponse(); + } + public function checkboxStateAction() { $this->assertHttpMethod('get'); @@ -98,7 +150,10 @@ public function backendSupportAction() } $moduleSupportStates = []; - if ($this->Auth()->hasPermission('module/monitoring')) { + if ( + Icinga::app()->getModuleManager()->hasEnabled('monitoring') + && $this->Auth()->hasPermission('module/monitoring') + ) { $supportList = []; foreach (Hook::all('Icingadb/IcingadbSupport') as $hook) { /** @var IcingadbSupportHook $hook */ diff --git a/configuration.php b/configuration.php index 416d37f78..2c83acc1c 100644 --- a/configuration.php +++ b/configuration.php @@ -565,9 +565,5 @@ $this->provideJsFile('action-list.js'); $this->provideJsFile('loadmore.js'); - - $mg = Icinga::app()->getModuleManager(); - if ($mg->hasEnabled('monitoring')) { - $this->provideJsFile('migrate.js'); - } + $this->provideJsFile('migrate.js'); } diff --git a/library/Icingadb/Common/StateBadges.php b/library/Icingadb/Common/StateBadges.php index 2cb5cc8da..a4e58dbe5 100644 --- a/library/Icingadb/Common/StateBadges.php +++ b/library/Icingadb/Common/StateBadges.php @@ -4,7 +4,6 @@ namespace Icinga\Module\Icingadb\Common; -use Icinga\Data\Filter\Filter; use Icinga\Module\Icingadb\Widget\StateBadge; use ipl\Html\BaseHtmlElement; use ipl\Html\Html; @@ -116,7 +115,9 @@ public function createLink($content, array $params = null): Link } if ($this->hasBaseFilter()) { - $url->addFilter(Filter::fromQueryString(QueryString::render($this->getBaseFilter()))); + $urlParams = $url->getParams()->toArray(false); + $url->setQueryString(QueryString::render($this->getBaseFilter())) + ->addParams($urlParams); } return new Link($content, $url); diff --git a/library/Icingadb/Widget/Detail/HostStatistics.php b/library/Icingadb/Widget/Detail/HostStatistics.php index 110eed2d5..18b0f400c 100644 --- a/library/Icingadb/Widget/Detail/HostStatistics.php +++ b/library/Icingadb/Widget/Detail/HostStatistics.php @@ -5,7 +5,6 @@ namespace Icinga\Module\Icingadb\Widget\Detail; use Icinga\Chart\Donut; -use Icinga\Data\Filter\Filter; use Icinga\Module\Icingadb\Common\Links; use Icinga\Module\Icingadb\Widget\HostStateBadges; use ipl\Html\ValidHtml; @@ -38,7 +37,7 @@ protected function createTotal(): ValidHtml { $url = Links::hosts(); if ($this->hasBaseFilter()) { - $url->addFilter(Filter::fromQueryString(QueryString::render($this->getBaseFilter()))); + $url->setQueryString(QueryString::render($this->getBaseFilter())); } return new Link( diff --git a/library/Icingadb/Widget/Detail/ServiceStatistics.php b/library/Icingadb/Widget/Detail/ServiceStatistics.php index 6b6ed9d22..9f0cbdf67 100644 --- a/library/Icingadb/Widget/Detail/ServiceStatistics.php +++ b/library/Icingadb/Widget/Detail/ServiceStatistics.php @@ -5,7 +5,6 @@ namespace Icinga\Module\Icingadb\Widget\Detail; use Icinga\Chart\Donut; -use Icinga\Data\Filter\Filter; use Icinga\Module\Icingadb\Common\Links; use Icinga\Module\Icingadb\Widget\ServiceStateBadges; use ipl\Html\ValidHtml; @@ -42,7 +41,7 @@ protected function createTotal(): ValidHtml { $url = Links::services(); if ($this->hasBaseFilter()) { - $url->addFilter(Filter::fromQueryString(QueryString::render($this->getBaseFilter()))); + $url->setQueryString(QueryString::render($this->getBaseFilter())); } return new Link( diff --git a/library/Icingadb/Widget/HostSummaryDonut.php b/library/Icingadb/Widget/HostSummaryDonut.php index 19f7984f3..79521129f 100644 --- a/library/Icingadb/Widget/HostSummaryDonut.php +++ b/library/Icingadb/Widget/HostSummaryDonut.php @@ -5,7 +5,6 @@ namespace Icinga\Module\Icingadb\Widget; use Icinga\Chart\Donut; -use Icinga\Data\Filter\Filter; use Icinga\Module\Icingadb\Common\BaseFilter; use Icinga\Module\Icingadb\Common\Links; use Icinga\Module\Icingadb\Model\HoststateSummary; @@ -42,9 +41,7 @@ protected function assembleBody(BaseHtmlElement $body) ->addSlice($this->summary->hosts_unreachable_unhandled, ['class' => 'slice-state-unreachable']) ->addSlice($this->summary->hosts_pending, ['class' => 'slice-state-pending']) ->setLabelBig($this->summary->hosts_down_unhandled) - ->setLabelBigUrl(Links::hosts()->addFilter( - Filter::fromQueryString(QueryString::render($this->getBaseFilter())) - )->addParams([ + ->setLabelBigUrl(Links::hosts()->setQueryString(QueryString::render($this->getBaseFilter()))->addParams([ 'host.state.soft_state' => 1, 'host.state.is_handled' => 'n', 'sort' => 'host.state.last_state_change' diff --git a/library/Icingadb/Widget/ServiceSummaryDonut.php b/library/Icingadb/Widget/ServiceSummaryDonut.php index 8141f86b8..4cb861feb 100644 --- a/library/Icingadb/Widget/ServiceSummaryDonut.php +++ b/library/Icingadb/Widget/ServiceSummaryDonut.php @@ -5,7 +5,6 @@ namespace Icinga\Module\Icingadb\Widget; use Icinga\Chart\Donut; -use Icinga\Data\Filter\Filter; use Icinga\Module\Icingadb\Common\BaseFilter; use Icinga\Module\Icingadb\Common\Links; use Icinga\Module\Icingadb\Model\ServicestateSummary; @@ -44,9 +43,7 @@ protected function assembleBody(BaseHtmlElement $body) ->addSlice($this->summary->services_unknown_unhandled, ['class' => 'slice-state-unknown']) ->addSlice($this->summary->services_pending, ['class' => 'slice-state-pending']) ->setLabelBig($this->summary->services_critical_unhandled) - ->setLabelBigUrl(Links::services()->addFilter( - Filter::fromQueryString(QueryString::render($this->getBaseFilter())) - )->addParams([ + ->setLabelBigUrl(Links::services()->setQueryString(QueryString::render($this->getBaseFilter()))->addParams([ 'service.state.soft_state' => 2, 'service.state.is_handled' => 'n', 'sort' => 'service.state.last_state_change' diff --git a/public/css/widget/migrate-popup.less b/public/css/widget/migrate-popup.less index f7adb22f6..8f9586b95 100644 --- a/public/css/widget/migrate-popup.less +++ b/public/css/widget/migrate-popup.less @@ -76,6 +76,9 @@ } .suggestion-area { + display: flex; + flex-direction: column-reverse; + padding: .75em; flex-grow: 1; pointer-events: auto; @@ -90,12 +93,19 @@ } p { + display: none; margin-bottom: .5em; color: @text-color-light; } + form ~ .monitoring-migration-hint, + .search-migration-suggestions:not(:empty) + .search-migration-hint, + .monitoring-migration-suggestions:not(:empty) + .monitoring-migration-hint { + display: block; + } + & > button.close { - float: right; + margin-left: auto; margin-top: 1em; &:hover { @@ -105,7 +115,7 @@ ul { padding: 0; - margin: .5em 0 0; + margin: 0; list-style-type: none; } @@ -116,6 +126,10 @@ &:last-of-type { margin-bottom: 0; } + + &:first-of-type { + margin-top: 0; + } } li { @@ -143,7 +157,6 @@ } form { - margin-top: 0.5em; width: 100%; .control-group { @@ -159,5 +172,10 @@ } } } + + .search-migration-suggestions:not(:empty) ~ form, + .search-migration-suggestions:not(:empty) ~ .monitoring-migration-suggestions:not(:empty) { + margin-bottom: .5em; + } } } diff --git a/public/js/migrate.js b/public/js/migrate.js index 9984d3a3b..5a00dbee1 100644 --- a/public/js/migrate.js +++ b/public/js/migrate.js @@ -11,9 +11,11 @@ const POPUP_HTML = '
Preview this in Icinga DB
\n' + - 'Miss some results? Try the link(s) below
\n' + + 'Preview this in Icinga DB
\n' + '