Merge branch 'master' into feature/improve-autologin-setup-8274

This commit is contained in:
Johannes Meyer 2015-01-28 18:01:15 +01:00
commit 3a983e8859
43 changed files with 174 additions and 106 deletions

View File

@ -1,4 +1,4 @@
<div class="controls">
<div class="controls" data-base-target="_main">
<?= $tabs; ?>
</div>
<div class="content" data-base-target="_next">

View File

@ -1,4 +1,4 @@
<div class="controls">
<div class="controls" data-base-target="_main">
<?= $this->tabs->render($this); ?>
</div>

View File

@ -1,35 +0,0 @@
<div class="controls">
<?= $this->tabs->render($this); ?>
</div>
<div class="content">
<?php $errors = $this->form->getErrorMessages(); ?>
<?php if (isset($this->messageBox)): ?>
<?= $this->messageBox->render() ?>
<?php endif ?>
<?php if ($this->successMessage): ?>
<div>
<i class="icinga-icon-success"></i>
<strong><?= $this->escape($this->successMessage); ?></strong>
</div>
<?php endif; ?>
<?php if (!empty($errors)) : ?>
<div>
<h4>Errors occured when trying to save the project.</h4>
<p>
The following errors occured when trying to save the configuration:
</p>
<ul>
<?php foreach($errors as $error): ?>
<li><?= $this->escape($error) ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<?= $this->form ?>
</div>

View File

@ -1,4 +1,4 @@
<div class="controls">
<div class="controls" data-base-target="_right">
<?= $this->tabs ?>
<h1><?= $this->escape($module->getTitle()) ?></h1>
</div>

View File

@ -1,4 +1,4 @@
<div class="controls">
<div class="controls" data-base-target="_main">
<?= $tabs; ?>
</div>
<div class="content" data-base-target="_next">

View File

@ -1,4 +1,4 @@
<div class="controls">
<div class="controls" data-base-target="_main">
<?= $tabs ?>
<h1><?= $this->translate('Roles') ?></h1>
</div>

View File

@ -8,6 +8,11 @@ use Icinga\Data\Filter\Filter;
/**
* Interface for filtering a result set
*
* @deprecated(EL): addFilter and applyFilter do the same in all usages.
* addFilter could be replaced w/ getFilter()->add(). We must no require classes implementing this interface to
* implement redundant methods over and over again. This interface must be moved to the namespace Icinga\Data\Filter.
* It lacks documentation.
*/
interface Filterable
{

View File

@ -38,15 +38,17 @@ class LessCompiler
/**
* Create a new instance
*
* @param string $basePath Provide web base path optional
*/
public function __construct()
public function __construct($basePath = null)
{
require_once 'lessphp/lessc.inc.php';
$this->lessc = new lessc();
$this->lessc->setVariables(
array(
'baseurl' => '\'' . Zend_Controller_Front::getInstance()->getBaseUrl(). '\''
'baseurl' => '\'' . $basePath. '\''
)
);
}

View File

@ -11,7 +11,7 @@ use Icinga\Web\LessCompiler;
class StyleSheet
{
protected static $lessFiles = array(
'../application/fonts/fontello-ifont/css/ifont-embedded.css',
'fonts/fontello-ifont/css/ifont-embedded.less',
'css/vendor/tipsy.css',
'css/icinga/defaults.less',
'css/icinga/layout-colors.less',
@ -96,7 +96,8 @@ class StyleSheet
$cache->send($cacheFile);
return;
}
$less = new LessCompiler();
$less = new LessCompiler(dirname($_SERVER['PHP_SELF']));
foreach ($lessFiles as $file) {
$less->addFile($file);
}

View File

@ -218,6 +218,25 @@ EOT;
return $this;
}
/**
* Remove a tab
*
* @param string $name
*
* @return self
*/
public function remove($name)
{
if ($this->has($name)) {
unset($this->tabs[$name]);
if (($dropdownIndex = array_search($name, $this->dropdownTabs)) !== false) {
array_splice($this->dropdownTabs, $dropdownIndex, 2);
}
}
return $this;
}
/**
* Add a tab to the dropdown on the right side of the tab-bar.
*

View File

@ -26,20 +26,15 @@ class Monitoring_HostController extends MonitoredObjectController
public function init()
{
$host = new Host($this->backend, $this->params->get('host'));
$this->applyRestriction('monitoring/hosts/filter', $host);
if ($host->fetch() === false) {
throw new Zend_Controller_Action_Exception($this->translate('Host not found'));
}
$this->object = $host;
$this->createTabs();
}
/**
* Show a host
*/
public function showAction()
{
$this->getTabs()->activate('host');
parent::showAction();
}
/**

View File

@ -131,6 +131,8 @@ class Monitoring_ListController extends Controller
$this->filterQuery($query);
$this->applyRestriction('monitoring/hosts/filter', $query);
$this->setupSortControl(array(
'host_severity' => $this->translate('Severity'),
'host_state' => $this->translate('Current State'),
@ -218,6 +220,9 @@ class Monitoring_ListController extends Controller
$query = $this->backend->select()->from('serviceStatus', $columns);
$this->filterQuery($query);
$this->applyRestriction('monitoring/services/filter', $query);
$this->setupSortControl(array(
'service_severity' => $this->translate('Service Severity'),
'service_state' => $this->translate('Current Service State'),
@ -661,22 +666,10 @@ class Monitoring_ListController extends Controller
if ($sort = $this->params->get('sort')) {
$query->order($sort, $this->params->get('dir'));
}
$this->applyRestrictions($query);
$this->handleFormatRequest($query);
return $query;
}
/**
* Apply current user's `monitoring/filter' restrictions on the given data view
*/
protected function applyRestrictions($query)
{
foreach ($this->getRestrictions('monitoring/filter') as $restriction) {
// TODO: $query->applyFilter(Filter::fromQueryString());
}
return $query;
}
protected function extraColumns()
{
$columns = preg_split(

View File

@ -26,20 +26,15 @@ class Monitoring_ServiceController extends MonitoredObjectController
public function init()
{
$service = new Service($this->backend, $this->params->get('host'), $this->params->get('service'));
$this->applyRestriction('monitoring/services/filter', $service);
if ($service->fetch() === false) {
throw new Zend_Controller_Action_Exception($this->translate('Service not found'));
}
$this->object = $service;
$this->createTabs();
}
/**
* Show a service
*/
public function showAction()
{
$this->getTabs()->activate('service');
parent::showAction();
}
/**

View File

@ -1,4 +1,4 @@
<div class="controls">
<div class="controls" data-base-target="_right">
<?= $tabs; ?>
<h1><?= $this->translate('Monitoring Backends') ?></h1>
</div>

View File

@ -1,4 +1,4 @@
<div class="controls">
<div class="controls" data-base-target="_right">
<?= $this->tabs ?>
</div>
<div class="content">

View File

@ -1,5 +1,5 @@
<div class="controls">
<?= $this->tabs->showOnlyCloseButton() ?>
<?= $this->tabs->remove('dashboard') ?>
</div>
<div class="content">
<h1><?= $title ?> <?= /** @var \Icinga\Module\Monitoring\Forms\Command\CommandForm $form */ $this->icon('help', $form->getHelp()) ?></h1>

View File

@ -35,7 +35,7 @@ if ($object->acknowledged): ?>
);
}
?>
<a href="<?= $ackLink ?>">
<a href="<?= $ackLink ?>" data-base-target="_self">
<?= $this->icon('ok') ?> <?= $this->translate('Acknowledge') ?>
</a>
<?php } else {

View File

@ -39,7 +39,7 @@ if ($object->getType() === $object::TYPE_HOST) {
);
}
?>
<a href="<?= $reschedule ?>">
<a href="<?= $reschedule ?>" data-base-target="_self">
<?= $this->icon('reschedule') ?>
<?= $this->translate('Reschedule') ?>
</a>

View File

@ -21,7 +21,7 @@ $command = array_shift($parts);
array('host' => $object->getHost()->getName(), 'service' => $object->getName())
);
} ?>
<a href="<?= $processCheckResult ?>">
<a href="<?= $processCheckResult ?>" data-base-target="_self">
<?= $this->icon('reply') ?>
<?= $this->translate('Process check result') ?>
</a>

View File

@ -15,7 +15,7 @@
);
}
?>
<a href="<?= $addCommentLink ?>">
<a href="<?= $addCommentLink ?>" data-base-target="_self">
<?= $this->icon('comment') ?>
<?= $this->translate('Add comment') ?>
</a>

View File

@ -15,7 +15,7 @@
);
}
?>
<a href="<?= $scheduleDowntimeLink ?>">
<a href="<?= $scheduleDowntimeLink ?>" data-base-target="_self">
<?= $this->icon('plug') ?>
<?= $this->translate('Schedule downtime') ?>
</a>

View File

@ -56,8 +56,13 @@ $this->providePermission(
);
$this->provideRestriction(
'monitoring/filter',
$this->translate('Restrict views to the hosts and services that match the filter')
'monitoring/hosts/filter',
$this->translate('Restrict hosts view to the hosts that match the filter')
);
$this->provideRestriction(
'monitoring/services/filter',
$this->translate('Restrict services view to the services that match the filter')
);
$this->provideConfigTab('backends', array(

View File

@ -145,7 +145,7 @@ class MonitoringBackend implements Selectable, Queryable, ConnectionInterface
$this->type = lcfirst(substr($class, 0, -7));
} else {
throw new ProgrammingError(
'%s is not a valid monitoring backend class name',
'%s is not a valid monitoring backend class name',
$class
);
}
@ -251,7 +251,7 @@ class MonitoringBackend implements Selectable, Queryable, ConnectionInterface
* @param string $name
* @param array $columns
*
* @return DataView
* @return \Icinga\Module\Monitoring\DataView\DataView
*/
public function from($name, array $columns = null)
{

View File

@ -4,9 +4,11 @@
namespace Icinga\Module\Monitoring;
use Icinga\Data\Filter\Filter;
use Icinga\Data\Filterable;
use Icinga\File\Csv;
use Icinga\Web\Controller\ModuleActionController;
use Icinga\Web\Url;
use Icinga\File\Csv;
/**
* Base class for all monitoring action controller
@ -60,5 +62,21 @@ class Controller extends ModuleActionController
exit;
}
}
/**
* Apply a restriction on the given data view
*
* @param string $restriction The name of restriction
* @param Filterable $filterable The filterable to restrict
*
* @return Filterable The filterable
*/
protected function applyRestriction($restriction, Filterable $view)
{
foreach ($this->getRestrictions($restriction) as $filter) {
$view->applyFilter(Filter::fromQueryString($filter));
}
return $view;
}
}

View File

@ -355,12 +355,21 @@ abstract class DataView implements Browsable, Countable, Filterable, Sortable
return $this;
}
/**
* @deprecated(EL): Only use DataView::applyFilter() for applying filter because all other functions are missing
* column validation. Filter::matchAny() for the IdoQuery (or the DbQuery or the SimpleQuery I didn't have a look)
* is required for the filter to work properly.
*/
public function setFilter(Filter $filter)
{
$this->query->setFilter($filter);
return $this;
}
/**
* @deprecated(EL): Only use DataView::applyFilter() for applying filter because all other functions are missing
* column validation.
*/
public function addFilter(Filter $filter)
{
$this->query->addFilter(clone($filter));

View File

@ -7,13 +7,15 @@ namespace Icinga\Module\Monitoring\Object;
use InvalidArgumentException;
use Icinga\Application\Config;
use Icinga\Exception\InvalidPropertyException;
use Icinga\Data\Filter\Filter;
use Icinga\Data\Filterable;
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
use Icinga\Web\UrlParams;
/**
* A monitored Icinga object, i.e. host or service
*/
abstract class MonitoredObject
abstract class MonitoredObject implements Filterable
{
/**
* Type host
@ -116,6 +118,13 @@ abstract class MonitoredObject
*/
protected $stats;
/**
* Filter
*
* @type Filter
*/
protected $filter;
/**
* Create a monitored object, i.e. host or service
*
@ -133,6 +142,35 @@ abstract class MonitoredObject
*/
abstract protected function getDataView();
public function applyFilter(Filter $filter)
{
$this->getFilter()->addFilter($filter);
return $this;
}
public function setFilter(Filter $filter)
{
// Left out on purpose. Interface is deprecated.
}
public function getFilter()
{
if ($this->filter === null) {
$this->filter = Filter::matchAny();
}
return $this->filter;
}
public function addFilter(Filter $filter)
{
// Left out on purpose. Interface is deprecated.
}
public function where($condition, $value = null)
{
// Left out on purpose. Interface is deprecated.
}
/**
* Fetch the object's properties
*
@ -140,7 +178,7 @@ abstract class MonitoredObject
*/
public function fetch()
{
$this->properties = $this->getDataView()->getQuery()->fetchRow();
$this->properties = $this->getDataView()->applyFilter($this->getFilter())->getQuery()->fetchRow();
if ($this->properties === false) {
return false;
}

View File

@ -1,8 +1,8 @@
@font-face {
font-family: 'ifont';
src: url('../font/ifont.eot?75097146');
src: url('../font/ifont.eot?75097146#iefix') format('embedded-opentype'),
url('../font/ifont.svg?75097146#ifont') format('svg');
src: url('@{baseurl}/fonts/fontello-ifont/font/ifont.eot?75097146');
src: url('@{baseurl}/fonts/fontello-ifont/font/ifont.eot?75097146#iefix') format('embedded-opentype'),
url('@{baseurl}/fonts/fontello-ifont/ifont.svg?75097146#ifont') format('svg');
font-weight: normal;
font-style: normal;
}

View File

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -0,0 +1,6 @@
# fontello-ifont has been moved
The font directory has been moved to the public structure because of Internet Explorer version 8 compatibility. The
common way for browsers is to include the binary embeded font type in the javascript. IE8 falls back and include one of
the provided font sources. Therefore it is important to have the font files available public and exported by the
HTTP server.

View File

@ -130,23 +130,26 @@
}
setTimeout(function () {
if (! $li.is('li:hover')) {
return;
}
if ($li.hasClass('active')) {
return;
}
try {
if (!$li.is('li:hover')) {
return;
}
if ($li.hasClass('active')) {
return;
}
} catch(e) { /* Bypass because if IE8 */ }
$li.siblings().each(function () {
var $sibling = $(this);
if ($sibling.is('li:hover')) {
return;
}
try {
if ($sibling.is('li:hover')) {
return;
}
} catch(e) { /* Bypass because if IE8 */ };
if ($sibling.hasClass('hover')) {
$sibling.removeClass('hover');
}
});
self.hoverElement($li);
}, delay);
};
@ -161,9 +164,11 @@
}
setTimeout(function () {
if ($li.is('li:hover') || $sidebar.is('sidebar:hover') ) {
return;
}
try {
if ($li.is('li:hover') || $sidebar.is('sidebar:hover')) {
return;
}
} catch(e) { /* Bypass because if IE8 */ };
$li.removeClass('hover');
$('#layout').removeClass('hoveredmenu');
}, 500);
@ -183,9 +188,11 @@
self = event.data.self;
setTimeout(function () {
// TODO: make this behave well together with keyboard navigation
if (! $li.is('li:hover') /*&& ! $li.find('a:focus')*/) {
$li.removeClass('hover');
}
try {
if (!$li.is('li:hover') /*&& ! $li.find('a:focus')*/) {
$li.removeClass('hover');
}
} catch(e) { /* Bypass because if IE8 */ }
}, 300);
};
Icinga.Behaviors.Navigation = Navigation;

View File

@ -482,6 +482,16 @@
targetId = 'col1';
$target = $('#' + targetId);
self.icinga.ui.layout1col();
} else if (targetId === '_right') {
// Ensure that the content is displayed in the rightmost column
$target = $el.closest('.container');
if ($target.attr('id') === 'col1') {
// As it's not possible to detect what's preceding the current state in the
// history stack this just simulates _main in case the respective element
// is not part of the rightmost column
$target = $('#col1');
self.icinga.ui.layout1col();
}
} else {
$target = $('#' + targetId);
}