Implement modules self provided search configuration

refs #6495
This commit is contained in:
Alexander Fuhr 2014-09-04 16:31:10 +02:00
parent 6739034a14
commit 1eacde0233
9 changed files with 175 additions and 54 deletions

View File

@ -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()
{
}
}

View File

@ -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()) {
?>
<div id="menu" data-base-target="_main">
<? if (SearchDashboard::load('dummy')->getPane('search')->hasComponents()): ?>
<form action="<?= $this->href('search') ?>" method="get" role="search">
<input type="text" name="q" class="search autofocus" placeholder="<?= $this->translate('Search...') ?>" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" />
</form>
<? endif; ?>
<?= new MenuRenderer(Menu::load(), Url::fromRequest()->without('renderLayout')->getRelativeUrl()); ?>
</div>

View File

@ -1,12 +1,8 @@
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content">
<h1><?= $this->translate("I'm ready to search, waiting for your input") ?></h1>
<p><strong><?= $this->translate('Hint') ?>: </strong><?= $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.'
) ?></p>
</div>

View File

@ -1,5 +1,5 @@
<div class="controls">
<?= $this->tabs ?>
<?= $this->dashboard->getTabs() ?>
</div>
<div class="content dashboard">

View File

@ -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
*

View File

@ -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
*

View File

@ -0,0 +1,101 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Web\Widget;
use Icinga\Application\Icinga;
use Icinga\Application\Modules\Module;
use Icinga\Web\Url;
use Icinga\Web\Widget\Dashboard\Pane;
use Zend_Controller_Action_Exception as ActionError;
/**
* Class SearchDashboard display multiple search views on a single search page
*
* @package Icinga\Web\Widget
*/
class SearchDashboard extends Dashboard
{
const SEARCH_PANE = 'search';
/**
* All searchUrls provided by Modules
*
* @var array
*/
protected $searchUrls = array();
/**
* Load all available search dashlets from modules
*
* @param $searchQuery
* @return Dashboard|SearchDashboard
*/
public static function load($searchQuery)
{
/** @var $dashboard SearchDashboard */
$dashboard = new static('searchDashboard');
$dashboard->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))
);
}
}
}
}

View File

@ -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(

View File

@ -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
*/