diff --git a/application/controllers/SearchController.php b/application/controllers/SearchController.php
index f2bf1ceac..c90e930a9 100644
--- a/application/controllers/SearchController.php
+++ b/application/controllers/SearchController.php
@@ -3,9 +3,8 @@
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Web\Controller\ActionController;
-use Icinga\Application\Icinga;
use Icinga\Web\Widget;
-use Icinga\Web\Url;
+use Icinga\Web\Widget\SearchDashboard;
/**
* Search controller
@@ -14,47 +13,13 @@ class SearchController extends ActionController
{
public function indexAction()
{
- $search = $this->_request->getParam('q');
- if (! $search) {
- $this->view->tabs = Widget::create('tabs')->add(
- 'search',
- array(
- 'title' => $this->translate('Search'),
- 'url' => '/search',
- )
- )->activate('search');
- $this->render('hint');
- return;
- }
- $dashboard = Widget::create('dashboard')->createPane($this->translate('Search'));
- $pane = $dashboard->getPane($this->translate('Search'));
- $suffix = strlen($search) ? ': ' . rtrim($search, '*') . '*' : '';
- $pane->addComponent(
- $this->translate('Hosts') . $suffix,
- Url::fromPath('monitoring/list/hosts', array(
- 'host_name' => $search . '*',
- 'sort' => 'host_severity',
- 'limit' => 10,
- )
- ));
- $pane->addComponent(
- $this->translate('Services') . $suffix,
- Url::fromPath('monitoring/list/services', array(
- 'service_description' => $search . '*',
- 'sort' => 'service_severity',
- 'limit' => 10,
- )
- ));
- $pane->addComponent('Hostgroups' . $suffix, Url::fromPath('monitoring/list/hostgroups', array(
- 'hostgroup' => $search . '*',
- 'limit' => 10,
- )));
- $pane->addComponent('Servicegroups' . $suffix, Url::fromPath('monitoring/list/servicegroups', array(
- 'servicegroup' => $search . '*',
- 'limit' => 10,
- )));
- $dashboard->activate($this->translate('Search'));
- $this->view->dashboard = $dashboard;
- $this->view->tabs = $dashboard->getTabs();
+ $this->view->dashboard = SearchDashboard::load($this->params->get('q'));
+
+ // NOTE: This renders the dashboard twice. Remove this once we can catch exceptions thrown in view scripts.
+ $this->view->dashboard->render();
+ }
+
+ public function hintAction()
+ {
}
}
diff --git a/application/layouts/scripts/parts/navigation.phtml b/application/layouts/scripts/parts/navigation.phtml
index 019fba767..2f4335d89 100644
--- a/application/layouts/scripts/parts/navigation.phtml
+++ b/application/layouts/scripts/parts/navigation.phtml
@@ -3,6 +3,7 @@
use Icinga\Web\Url;
use Icinga\Web\Menu;
use Icinga\Web\MenuRenderer;
+use Icinga\Web\Widget\SearchDashboard;
// Don't render a menu for unauthenticated users unless menu is auth aware
if (! $this->auth()->isAuthenticated()) {
@@ -11,8 +12,10 @@ if (! $this->auth()->isAuthenticated()) {
?>
diff --git a/application/views/scripts/search/hint.phtml b/application/views/scripts/search/hint.phtml
index 91a85e9fe..d54c0b24f 100644
--- a/application/views/scripts/search/hint.phtml
+++ b/application/views/scripts/search/hint.phtml
@@ -1,12 +1,8 @@
-
-= $this->tabs ?>
-
-
= $this->translate("I'm ready to search, waiting for your input") ?>
= $this->translate('Hint') ?>: = $this->translate(
'Please use the asterisk (*) as a placeholder for wildcard searches.'
- . " For convenience I'll always add a wildcard after the last character"
- . ' you typed.'
+ . " For convenience I'll always add a wildcard in front and after your"
+ . ' search string.'
) ?>
diff --git a/application/views/scripts/search/index.phtml b/application/views/scripts/search/index.phtml
index 52dc7a14c..321597e70 100644
--- a/application/views/scripts/search/index.phtml
+++ b/application/views/scripts/search/index.phtml
@@ -1,5 +1,5 @@
-= $this->tabs ?>
+= $this->dashboard->getTabs() ?>
diff --git a/library/Icinga/Application/Modules/Module.php b/library/Icinga/Application/Modules/Module.php
index d0bf451ee..c0c6b1f6f 100644
--- a/library/Icinga/Application/Modules/Module.php
+++ b/library/Icinga/Application/Modules/Module.php
@@ -163,6 +163,31 @@ class Module
*/
protected $paneItems = array();
+ /**
+ * @var array
+ */
+ protected $searchUrls = array();
+
+ /**
+ * @param string $title
+ * @param string $url
+ */
+ public function provideSearchUrl($title, $url)
+ {
+ $searchUrl = (object) array(
+ 'title' => $title,
+ 'url' => $url
+ );
+
+ $this->searchUrls[] = $searchUrl;
+ }
+
+ public function getSearchUrls()
+ {
+ $this->launchConfigScript();
+ return $this->searchUrls;
+ }
+
/**
* Get all Menu Items
*
diff --git a/library/Icinga/Web/Widget/Dashboard/Pane.php b/library/Icinga/Web/Widget/Dashboard/Pane.php
index 45bd9c558..8c1e66bad 100644
--- a/library/Icinga/Web/Widget/Dashboard/Pane.php
+++ b/library/Icinga/Web/Widget/Dashboard/Pane.php
@@ -135,6 +135,24 @@ class Pane extends AbstractWidget
return $this;
}
+ /**
+ * Removes all or a given list of components from this pane
+ *
+ * @param array $components Optional list of component titles
+ * @return Pane $this
+ */
+ public function removeComponents(array $components = null)
+ {
+ if ($components === null) {
+ $this->components = array();
+ } else {
+ foreach ($components as $component) {
+ $this->removeComponent($component);
+ }
+ }
+ return $this;
+ }
+
/**
* Return all components added at this pane
*
diff --git a/library/Icinga/Web/Widget/SearchDashboard.php b/library/Icinga/Web/Widget/SearchDashboard.php
new file mode 100644
index 000000000..a97de06e5
--- /dev/null
+++ b/library/Icinga/Web/Widget/SearchDashboard.php
@@ -0,0 +1,101 @@
+loadSearchDashlets($searchQuery);
+ return $dashboard;
+ }
+
+ /**
+ * Renders the output
+ *
+ * @return string
+ * @throws \Zend_Controller_Action_Exception
+ */
+ public function render()
+ {
+ if (!$this->getPane(self::SEARCH_PANE)->hasComponents()) {
+ throw new ActionError('Site not found', 404);
+ }
+ return parent::render();
+ }
+
+ /**
+ * Loads search dashlets
+ *
+ * @param string $searchString
+ */
+ protected function loadSearchDashlets($searchString)
+ {
+ $pane = $this->createPane(self::SEARCH_PANE)->getPane(self::SEARCH_PANE)->setTitle(t('Search'));
+ $this->activate(self::SEARCH_PANE);
+
+ $manager = Icinga::app()->getModuleManager();
+
+ foreach ($manager->getLoadedModules() as $module) {
+ $this->addSearchDashletsFromModule($searchString, $module, $pane);
+ }
+
+ if ($searchString === '' && $pane->hasComponents()) {
+ $pane->removeComponents();
+ $pane->add('Ready to search', 'search/hint');
+ return;
+ }
+ }
+
+ /**
+ * Add available search dashlets to the pane
+ *
+ * @param string $searchString
+ * @param Module $module
+ * @param Pane $pane
+ */
+ protected function addSearchDashletsFromModule($searchString, $module, $pane)
+ {
+ $searchUrls = $module->getSearchUrls();
+
+ if (! empty($searchUrls)) {
+ $this->searchUrls[] = $module->getSearchUrls();
+ foreach ($searchUrls as $search) {
+ $pane->addComponent(
+ $search->title . ': ' . $searchString,
+ Url::fromPath($search->url, array('q' => $searchString))
+ );
+ }
+ }
+ }
+}
diff --git a/modules/monitoring/application/controllers/ListController.php b/modules/monitoring/application/controllers/ListController.php
index 047b4ab35..b167c5e43 100644
--- a/modules/monitoring/application/controllers/ListController.php
+++ b/modules/monitoring/application/controllers/ListController.php
@@ -55,10 +55,9 @@ class Monitoring_ListController extends Controller
$url->addParams(array($k => $v));
return $url;
}
-
} else {
$q = $url->shift('q');
- if ($q) {
+ if ($q !== null) {
$action = $this->_request->getActionName();
switch($action) {
case 'services':
@@ -68,7 +67,7 @@ class Monitoring_ListController extends Controller
$this->params->remove('q')->set('host_name', '*' . $q . '*');
break;
case 'hostgroups':
- $this->params->remove('q')->set('hostgroups', '*' . $q . '*');
+ $this->params->remove('q')->set('hostgroup', '*' . $q . '*');
break;
case 'servicegroups':
$this->params->remove('q')->set('servicegroup', '*' . $q . '*');
@@ -413,6 +412,9 @@ class Monitoring_ListController extends Controller
public function servicegroupsAction()
{
+ if ($url = $this->hasBetterUrl()) {
+ return $this->redirectNow($url);
+ }
$this->addTitleTab('servicegroups');
$this->setAutorefreshInterval(12);
$query = $this->backend->select()->from('groupsummary', array(
@@ -441,6 +443,9 @@ class Monitoring_ListController extends Controller
public function hostgroupsAction()
{
+ if ($url = $this->hasBetterUrl()) {
+ return $this->redirectNow($url);
+ }
$this->addTitleTab('hostgroups');
$this->setAutorefreshInterval(12);
$query = $this->backend->select()->from('groupsummary', array(
diff --git a/modules/monitoring/configuration.php b/modules/monitoring/configuration.php
index 412581d24..fc0688e89 100644
--- a/modules/monitoring/configuration.php
+++ b/modules/monitoring/configuration.php
@@ -19,6 +19,14 @@ $this->provideConfigTab('security', array(
'url' => 'config/security'
));
+/*
+ * Available Search Urls
+ */
+$this->provideSearchUrl($this->translate('Hosts'), 'monitoring/list/hosts?sort=host_severity&limit=10');
+$this->provideSearchUrl($this->translate('Services'), 'monitoring/list/services?sort=service_severity&limit=10');
+$this->provideSearchUrl($this->translate('Hostgroups'), 'monitoring/list/hostgroups?limit=10');
+$this->provideSearchUrl($this->translate('Servicegroups'), 'monitoring/list/servicegroups?limit=10');
+
/*
* Problems Section
*/