commit
a44d17f0a6
|
@ -30,6 +30,7 @@
|
|||
use \Zend_Controller_Action_Exception as ActionException;
|
||||
use \Icinga\Web\Controller\ActionController;
|
||||
use \Icinga\Application\Icinga;
|
||||
use \Icinga\Application\Config as IcingaConfig;
|
||||
use \Icinga\Application\Logger;
|
||||
|
||||
class StaticController extends ActionController
|
||||
|
@ -72,12 +73,7 @@ class StaticController extends ActionController
|
|||
} else {
|
||||
$extension = 'fixme';
|
||||
}
|
||||
$hash = md5_file($filePath);
|
||||
if ($hash === $this->getRequest()->getHeader('If-None-Match')) {
|
||||
$this->getResponse()->setHttpResponseCode(304);
|
||||
return;
|
||||
}
|
||||
header('ETag: ' . $hash);
|
||||
|
||||
header('Content-Type: image/' . $extension);
|
||||
header('Cache-Control: max-age=3600');
|
||||
header('Last-Modified: ' . gmdate(
|
||||
|
@ -119,11 +115,15 @@ class StaticController extends ActionController
|
|||
echo '/** Module has no js files **/';
|
||||
return;
|
||||
}
|
||||
$hash = md5_file($filePath);
|
||||
$response = $this->getResponse();
|
||||
$response->setHeader('ETag', $hash);
|
||||
$response->setHeader('Content-Type', 'application/javascript');
|
||||
$response->setHeader('Cache-Control', 'max-age=3600', true);
|
||||
$response->setHeader('Content-Type', 'text/javascript');
|
||||
if (!IcingaConfig::app()->global->get('environment') == 'development') {
|
||||
$this->setCacheHeader(3600);
|
||||
} else {
|
||||
$response->setHeader('Pragma', 'no-cache', true);
|
||||
$response->setHeader('Cache-Control', 'max-age=-3600', true);
|
||||
|
||||
}
|
||||
$response->setHeader(
|
||||
'Last-Modified',
|
||||
gmdate(
|
||||
|
@ -132,15 +132,28 @@ class StaticController extends ActionController
|
|||
) . ' GMT'
|
||||
);
|
||||
|
||||
$hash = md5_file($filePath);
|
||||
|
||||
if ($hash === $this->getRequest()->getHeader('If-None-Match')) {
|
||||
$response->setHttpResponseCode(304);
|
||||
return;
|
||||
} else {
|
||||
readfile($filePath);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cache header for this respone
|
||||
*
|
||||
* @param integer $maxAge The maximum age to set
|
||||
*/
|
||||
private function setCacheHeader($maxAge)
|
||||
{
|
||||
$response = $this->getResponse();
|
||||
$response->setHeader('Cache-Control', 'max-age=3600', true);
|
||||
$response->setHeader('Pragma', 'cache', true);
|
||||
$response->setHeader(
|
||||
'Expires',
|
||||
gmdate(
|
||||
'D, d M Y H:i:s',
|
||||
time()+3600
|
||||
) . ' GMT',
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
|
|
@ -2,18 +2,26 @@
|
|||
<div class="row">
|
||||
|
||||
<!-- Only required for left/right tabs -->
|
||||
<div class="col-md-2">
|
||||
<div class="col-sm-12 col-xs-12 col-md-2 col-lg-2">
|
||||
<?php echo $this->render('parts/navigation.phtml') ?>
|
||||
</div>
|
||||
|
||||
<div class="col-md-10">
|
||||
<div id="icingamain" class="col-md-8">
|
||||
<div class="col-sm-12 col-xs-12 col-md-10 col-lg-10">
|
||||
<div id="icingamain" class="col-sm-12 col-xs-12 col-md-8 col-lg-8">
|
||||
<?= $this->render('inline.phtml') ?>
|
||||
</div>
|
||||
|
||||
<div id="icingadetail" class="col-md-2">
|
||||
<div id="icingadetail" class="hidden-sm hidden-xs col-md-4 col-lg-4">
|
||||
Details
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<!-- Make some space at the end of the page -->
|
||||
<div class="panel">
|
||||
<div class="panel-body text-center">
|
||||
Icinga 2 Web © 2013 Icinga Team
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -43,11 +43,11 @@
|
|||
<script src="./js/vendor/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script data-main="<?php echo $this->baseUrl('js/main.js')?>"
|
||||
src="<?php echo $this->baseUrl('js/vendor/require.js') ?>"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<?= $this->render('body.phtml') ?>
|
||||
<script data-main="<?php echo $this->baseUrl('js/main.js')?>"
|
||||
src="<?php echo $this->baseUrl('js/vendor/require.js') ?>"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -101,3 +101,22 @@ You can now either extend your Tabs object using the DashboardAction's `apply()`
|
|||
`extend()` method (which is more fluent):
|
||||
|
||||
$tabs->extend(new DashboardAction());
|
||||
|
||||
## The SortBox widget
|
||||
|
||||
The "SortBox" Widget allows you to create a generic sort input for sortable views.
|
||||
It automatically creates a form containing a select box with all sort options and a dropbox with the sort direction. It
|
||||
also handles automatic submission of sorting changes and draws an additional submit button when JavaScript is disabled.
|
||||
|
||||
The constructor takes an string for the component name ad an array containing the select options, where the key is
|
||||
the value to be submitted and the value is the label that will be shown. You then should call applyRequest in order to
|
||||
make sure the form is correctly populated when a request with a sort parameter is being made.
|
||||
|
||||
$this->view->sortControl = new SortBox(
|
||||
$this->getRequest()->getActionName(),
|
||||
$columns
|
||||
);
|
||||
$this->view->sortControl->applyRequest($this->getRequest());
|
||||
|
||||
|
||||
By default the sortBox uses the GET parameter 'sort' for the sorting key and 'dir' for the sorting direction
|
||||
|
|
|
@ -121,22 +121,11 @@ class Web extends ApplicationBootstrap
|
|||
*/
|
||||
private function setupRoute()
|
||||
{
|
||||
// TODO: Find a better solution
|
||||
$this->frontController->getRouter()->addRoute(
|
||||
'module_overview',
|
||||
new Zend_Controller_Router_Route(
|
||||
'js/modules/list.js',
|
||||
array(
|
||||
'controller' => 'static',
|
||||
'action' => 'modulelist',
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$this->frontController->getRouter()->addRoute(
|
||||
'module_javascript',
|
||||
new Zend_Controller_Router_Route(
|
||||
'js/modules/:module_name/:file',
|
||||
'js/components/:module_name/:file',
|
||||
array(
|
||||
'controller' => 'static',
|
||||
'action' => 'javascript'
|
||||
|
|
|
@ -328,7 +328,6 @@ namespace Icinga\Test {
|
|||
if ($token !== null) {
|
||||
$requestData[$form->getTokenElementName()] = $token;
|
||||
}
|
||||
|
||||
$request = $this->getRequest();
|
||||
$request->setMethod('POST');
|
||||
$request->setPost($requestData);
|
||||
|
@ -363,6 +362,7 @@ namespace Icinga\Test {
|
|||
|
||||
require_once self::$libDir . '/Web/Form/Decorator/ConditionalHidden.php';
|
||||
require_once self::$libDir . '/Web/Form/Decorator/HelpText.php';
|
||||
require_once self::$libDir . '/Web/Form/Decorator/BootstrapForm.php';
|
||||
|
||||
require_once self::$libDir . '/Web/Form/Validator/DateFormatValidator.php';
|
||||
require_once self::$libDir . '/Web/Form/Validator/TimeFormatValidator.php';
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
namespace Icinga\Web;
|
||||
|
||||
|
||||
use \Zend_Controller_Request_Abstract;
|
||||
use \Zend_Form;
|
||||
use \Zend_Config;
|
||||
|
@ -34,6 +35,7 @@ use \Zend_View_Interface;
|
|||
use \Icinga\Web\Form\Element\Note;
|
||||
use \Icinga\Exception\ProgrammingError;
|
||||
use \Icinga\Web\Form\Decorator\HelpText;
|
||||
use \Icinga\Web\Form\Decorator\BootstrapForm;
|
||||
use \Icinga\Web\Form\InvalidCSRFTokenException;
|
||||
use \Icinga\Application\Config as IcingaConfig;
|
||||
|
||||
|
@ -122,6 +124,13 @@ class Form extends Zend_Form
|
|||
*/
|
||||
private $last_note_id = 0;
|
||||
|
||||
/**
|
||||
* Decorator that replaces the DtDd Zend-Form default
|
||||
*
|
||||
* @var Form\Decorator\BootstrapFormDecorator
|
||||
*/
|
||||
private $formDecorator;
|
||||
|
||||
/**
|
||||
* Getter for the session ID
|
||||
*
|
||||
|
@ -554,4 +563,52 @@ class Form extends Zend_Form
|
|||
list ($seed, $token) = $this->generateCsrfToken($this->getSessionId());
|
||||
return sprintf('%s|%s', $seed, $token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new element
|
||||
*
|
||||
* Additionally, all DtDd tags will be removed and the Bootstrap compatible
|
||||
* BootstrapForm decorator will be added to the elements
|
||||
*
|
||||
*
|
||||
* @param string|Zend_Form_Element $element String element type, or an object of type Zend_Form_Element
|
||||
* @param string $name The name of the element to add if $element is a string
|
||||
* @param array $options The settings for the element if $element is a string
|
||||
*
|
||||
* @return Form
|
||||
* @see Zend_Form::addElement()
|
||||
*/
|
||||
public function addElement($element, $name = null, $options = null)
|
||||
{
|
||||
parent::addElement($element, $name, $options);
|
||||
$el = $name ? $this->getElement($name) : $element;
|
||||
if ($el) {
|
||||
$el->removeDecorator('HtmlTag');
|
||||
$el->removeDecorator('Label');
|
||||
$el->removeDecorator('DtDdWrapper');
|
||||
$el->addDecorator(new BootstrapForm());
|
||||
$el->setAttrib('class', $el->getAttrib('class') . ' form-control input-sm');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the default decorators
|
||||
*
|
||||
* @return Zend_Form
|
||||
*/
|
||||
public function loadDefaultDecorators()
|
||||
{
|
||||
if ($this->loadDefaultDecoratorsIsDisabled()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$decorators = $this->getDecorators();
|
||||
if (empty($decorators)) {
|
||||
$this->addDecorator('FormElements')
|
||||
->addDecorator('Form');
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Web\Form\Decorator;
|
||||
|
||||
use Zend_Form_Decorator_Abstract;
|
||||
|
||||
/**
|
||||
* Decorator that styles forms in the DOM Bootstrap wants for it's forms
|
||||
*
|
||||
* This component replaces the dt/dd wrapping of elements with the approach used by bootstrap.
|
||||
*
|
||||
* Labels are drawn for all elements, except hidden, button and submit elements. If you want a
|
||||
* placeholder for this elements, set the 'addLabelPlaceholder' property. This can be useful in
|
||||
* cases where you want to put inputs with and inputs without labels on the same line and don't
|
||||
* want buttons to 'jump'
|
||||
*/
|
||||
class BootstrapForm extends Zend_Form_Decorator_Abstract
|
||||
{
|
||||
/**
|
||||
* An array of elements that won't get a <label> dom added per default
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $noLabel = array(
|
||||
'Zend_Form_Element_Hidden',
|
||||
'Zend_Form_Element_Button',
|
||||
'Zend_Form_Element_Submit'
|
||||
);
|
||||
|
||||
/**
|
||||
* Return the DOM for the element label
|
||||
*
|
||||
* @param String $elementName The name of the element
|
||||
*
|
||||
* @return String The DOM for the form element's label
|
||||
*/
|
||||
public function getLabel($elementName)
|
||||
{
|
||||
$label = $this->getElement()->getLabel();
|
||||
if (!$label) {
|
||||
$label = ' ';
|
||||
}
|
||||
if (in_array($this->getElement()->getType(), self::$noLabel)
|
||||
&& !$this->getElement()->getAttrib('addLabelPlaceholder', false)) {
|
||||
$label = '';
|
||||
} else {
|
||||
if (in_array($this->getElement()->getType(), self::$noLabel)) {
|
||||
$label = ' ';
|
||||
}
|
||||
$label = '<label for="' . $elementName . '">' . $label . '</label>';
|
||||
}
|
||||
return $label;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render this element
|
||||
*
|
||||
* Renders as the following:
|
||||
* <div class="form-group">
|
||||
* $dtLabel
|
||||
* $dtElement
|
||||
* </div>
|
||||
*
|
||||
* @param String $content The content of the form element
|
||||
*
|
||||
* @return String The decorated form element
|
||||
*/
|
||||
public function render($content)
|
||||
{
|
||||
$el = $this->getElement();
|
||||
$elementName = $el->getName();
|
||||
$label = $this->getLabel($elementName);
|
||||
return '<div class="form-group" id="' . $elementName . '-element">'
|
||||
. $label
|
||||
. $content
|
||||
. '</div>';
|
||||
}
|
||||
}
|
|
@ -46,13 +46,15 @@ class HelpText extends Zend_Form_Decorator_Abstract
|
|||
public function render($content = '')
|
||||
{
|
||||
$attributes = $this->getElement()->getAttribs();
|
||||
|
||||
if (isset($attributes['helptext'])) {
|
||||
$content = '<div>'
|
||||
. $content
|
||||
. '<span class="helptext">'
|
||||
$visible = true;
|
||||
if (isset($attributes['condition'])) {
|
||||
$visible = $attributes['condition'] == '1';
|
||||
}
|
||||
if (isset($attributes['helptext']) && $visible) {
|
||||
$content = $content
|
||||
. '<p class="help-block">'
|
||||
. $attributes['helptext']
|
||||
. '</span></div><br/>';
|
||||
. '</p>';
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Web\Widget;
|
||||
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Web\Request;
|
||||
use Zend_View_Abstract;
|
||||
use Icinga\Web\Form\Decorator\ConditionalHidden;
|
||||
use Zend_Form_Element_Submit;
|
||||
|
||||
/**
|
||||
* Sortbox widget
|
||||
*
|
||||
* The "SortBox" Widget allows you to create a generic sort input for sortable views.
|
||||
* It automatically creates a form containing a select box with all sort options and a
|
||||
* dropbox with the sort direction. It also handles automatic submission of sorting changes and draws an additional
|
||||
* submit button when JavaScript is disabled.
|
||||
*
|
||||
* The constructor takes an string for the component name ad an array containing the select options, where the key is
|
||||
* the value to be submitted and the value is the label that will be shown. You then should call applyRequest in order
|
||||
* to make sure the form is correctly populated when a request with a sort parameter is being made.
|
||||
*
|
||||
* Example:
|
||||
* <pre><code>
|
||||
* $this->view->sortControl = new SortBox(
|
||||
* $this->getRequest()->getActionName(),
|
||||
* $columns
|
||||
* );
|
||||
* $this->view->sortControl->applyRequest($this->getRequest());
|
||||
* </code></pre>
|
||||
* By default the sortBox uses the GET parameter 'sort' for the sorting key and 'dir' for the sorting direction
|
||||
*
|
||||
*/
|
||||
class SortBox implements Widget
|
||||
{
|
||||
|
||||
/**
|
||||
* An array containing all sort columns with their associated labels
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $sortFields;
|
||||
|
||||
/**
|
||||
* The name of the form that will be created
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* A request object used for initial form population
|
||||
*
|
||||
* @var Icinga\Web\Request
|
||||
*/
|
||||
private $request;
|
||||
|
||||
/**
|
||||
* Create a SortBox with the entries from $sortFields
|
||||
*
|
||||
* @param string $name The name of the sort form
|
||||
* @param array $sortFields An array containing the columns and their labels to be displayed
|
||||
* in the sort select box
|
||||
*/
|
||||
public function __construct($name, array $sortFields)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->sortFields = $sortFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the parameters from the given request on this SortBox
|
||||
*
|
||||
* @param Request $request The request to use for populating the form
|
||||
*/
|
||||
public function applyRequest($request)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a submit button that is hidden via the ConditionalDecorator
|
||||
* in order to allow sorting changes to be submitted in a JavaScript-less environment
|
||||
*
|
||||
* @return Zend_Form_Element_Submit The submit button that is hidden by default
|
||||
* @see ConditionalDecorator
|
||||
*/
|
||||
private function createFallbackSubmitButton()
|
||||
{
|
||||
$manualSubmitButton = new Zend_Form_Element_Submit(
|
||||
array(
|
||||
'name' => 'submit_' . $this->name,
|
||||
'label' => 'Sort',
|
||||
'class' => 'btn btn-default',
|
||||
'condition' => 0,
|
||||
'value' => '{{SUBMIT_ICON}}'
|
||||
)
|
||||
);
|
||||
$manualSubmitButton->addDecorator(new ConditionalHidden());
|
||||
$manualSubmitButton->setAttrib('addLabelPlaceholder', true);
|
||||
return $manualSubmitButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders this widget via the given view and returns the
|
||||
* HTML as a string
|
||||
*
|
||||
* @param Zend_View_Abstract $view
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(Zend_View_Abstract $view)
|
||||
{
|
||||
$form = new Form();
|
||||
$form->setAttrib('class', 'form-inline');
|
||||
$form->setMethod('GET');
|
||||
$form->setTokenDisabled();
|
||||
$form->setName($this->name);
|
||||
$form->addElement(
|
||||
'select',
|
||||
'sort_' . $this->name,
|
||||
array(
|
||||
'name' => 'sort',
|
||||
'label' => 'Sort By',
|
||||
'multiOptions' => $this->sortFields
|
||||
)
|
||||
);
|
||||
$form->addElement(
|
||||
'select',
|
||||
'dir_' . $this->name,
|
||||
array(
|
||||
'name' => 'dir',
|
||||
'multiOptions' => array(
|
||||
'desc' => 'Desc',
|
||||
'asc' => 'Asc'
|
||||
)
|
||||
|
||||
)
|
||||
);
|
||||
|
||||
$form->enableAutoSubmit(array('sort_' . $this->name, 'dir_' . $this->name));
|
||||
$form->addElement($this->createFallbackSubmitButton());
|
||||
|
||||
if ($this->request) {
|
||||
$form->populate($this->request->getParams());
|
||||
}
|
||||
return $form->render($view);
|
||||
}
|
||||
}
|
|
@ -32,11 +32,11 @@ use \Icinga\Data\Db\Query;
|
|||
use \Icinga\File\Csv;
|
||||
use \Icinga\Web\Controller\ActionController;
|
||||
use \Icinga\Web\Hook;
|
||||
use \Icinga\Web\Widget\Tabextension\BasketAction;
|
||||
use \Icinga\Web\Widget\Tabextension\DashboardAction;
|
||||
use \Icinga\Web\Widget\Tabextension\OutputFormat;
|
||||
use \Icinga\Web\Widget\Tabs;
|
||||
use \Icinga\Module\Monitoring\Backend;
|
||||
use Icinga\Module\Monitoring\Backend;
|
||||
use \Icinga\Web\Widget\SortBox;
|
||||
|
||||
class Monitoring_ListController extends ActionController
|
||||
{
|
||||
|
@ -46,7 +46,6 @@ class Monitoring_ListController extends ActionController
|
|||
* @var Backend
|
||||
*/
|
||||
protected $backend;
|
||||
|
||||
/**
|
||||
* Set to a string containing the compact layout name to use when
|
||||
* 'compact' is set as the layout parameter, otherwise null
|
||||
|
@ -107,6 +106,14 @@ class Monitoring_ListController extends ActionController
|
|||
'host_last_comment'
|
||||
)
|
||||
);
|
||||
$this->setupSortControl(array(
|
||||
'host_last_check' => 'Last Host Check',
|
||||
'host_severity' => 'Host Severity',
|
||||
'host_state' => 'Current Host State',
|
||||
'host_name' => 'Host Name',
|
||||
'host_address' => 'Address',
|
||||
'host_state' => 'Hard State'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,13 +121,6 @@ class Monitoring_ListController extends ActionController
|
|||
*/
|
||||
public function servicesAction()
|
||||
{
|
||||
if ($this->_getParam('_statetype', 'soft') === 'soft') {
|
||||
$state_column = 'service_state';
|
||||
$state_change_column = 'service_last_state_change';
|
||||
} else {
|
||||
$state_column = 'service_hard_state';
|
||||
$state_change_column = 'service_last_hard_state_change';
|
||||
}
|
||||
$this->compactView = "services-compact";
|
||||
|
||||
$this->view->services = $this->query('status', array(
|
||||
|
@ -132,12 +132,12 @@ class Monitoring_ListController extends ActionController
|
|||
'host_handled',
|
||||
'service_description',
|
||||
'service_display_name',
|
||||
'service_state' => $state_column,
|
||||
'service_state' => 'service_state',
|
||||
'service_in_downtime',
|
||||
'service_acknowledged',
|
||||
'service_handled',
|
||||
'service_output',
|
||||
'service_last_state_change' => $state_change_column,
|
||||
'service_last_state_change' => 'service_last_state_change',
|
||||
'service_icon_image',
|
||||
'service_long_output',
|
||||
'service_is_flapping',
|
||||
|
@ -150,7 +150,19 @@ class Monitoring_ListController extends ActionController
|
|||
'service_notes_url',
|
||||
'service_last_comment'
|
||||
));
|
||||
$this->inheritCurrentSortColumn();
|
||||
|
||||
$this->setupSortControl(array(
|
||||
'service_last_check' => 'Last Service Check',
|
||||
'service_severity' => 'Severity',
|
||||
'service_state' => 'Current Service State',
|
||||
'service_description' => 'Service Name',
|
||||
'service_state_type' => 'Hard State',
|
||||
'host_severity' => 'Host Severity',
|
||||
'host_state' => 'Current Host State',
|
||||
'host_name' => 'Host Name',
|
||||
'host_address' => 'Host Address',
|
||||
'host_last_check' => 'Last Host Check'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,8 +170,8 @@ class Monitoring_ListController extends ActionController
|
|||
*/
|
||||
public function downtimesAction()
|
||||
{
|
||||
$query = $this->backend->select()
|
||||
->from('downtime',array(
|
||||
$this->setDefaultSortColumn('downtime_is_in_effect');
|
||||
$this->view->downtimes = $this->query('downtime', array(
|
||||
'host_name',
|
||||
'object_type',
|
||||
'service_description',
|
||||
|
@ -175,11 +187,21 @@ class Monitoring_ListController extends ActionController
|
|||
'downtime_triggered_by_id',
|
||||
'downtime_trigger_time'
|
||||
));
|
||||
if (!$this->_getParam('sort')) {
|
||||
$query->order('downtime_is_in_effect');
|
||||
}
|
||||
$this->view->downtimes = $query->applyRequest($this->_request);
|
||||
$this->inheritCurrentSortColumn();
|
||||
|
||||
$this->setupSortControl(array(
|
||||
'downtime_is_in_effect' => 'Is In Effect',
|
||||
'object_type' => 'Service/Host',
|
||||
'host_name' => 'Host Name',
|
||||
'service_description' => 'Service Name',
|
||||
'downtime_entry_time' => 'Entry Time',
|
||||
'downtime_author_name' => 'Author',
|
||||
'downtime_comment_data' => 'Comment',
|
||||
'downtime_scheduled_start_time' => 'Start',
|
||||
'downtime_scheduled_end_time' => 'End',
|
||||
'downtime_trigger_time' => 'Trigger Time',
|
||||
'downtime_internal_downtime_id' => 'Downtime ID',
|
||||
'downtime_duration' => 'Duration',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -187,6 +209,7 @@ class Monitoring_ListController extends ActionController
|
|||
*/
|
||||
public function notificationsAction()
|
||||
{
|
||||
$this->setDefaultSortColumn('notification_start_time', 'DESC');
|
||||
$this->view->notifications = $this->query(
|
||||
'notification',
|
||||
array(
|
||||
|
@ -200,11 +223,9 @@ class Monitoring_ListController extends ActionController
|
|||
'notification_command'
|
||||
)
|
||||
);
|
||||
if (!$this->_getParam('sort')) {
|
||||
$this->view->notifications->order('notification_start_time DESC');
|
||||
}
|
||||
|
||||
$this->inheritCurrentSortColumn();
|
||||
$this->setupSortControl(array(
|
||||
'notification_start_time' => 'Notification Start'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -263,6 +284,34 @@ class Monitoring_ListController extends ActionController
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default sort column for this action if none is provided
|
||||
*
|
||||
* @param string $column The column to use for sorting
|
||||
* @param string $dir The direction ('ASC' or 'DESC')
|
||||
*/
|
||||
private function setDefaultSortColumn($column, $dir = 'DESC')
|
||||
{
|
||||
|
||||
$this->setParam('sort', $this->getParam('sort', $column));
|
||||
$this->setParam('dir', $this->getParam('dir', $dir));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a sort control box at the 'sortControl' view parameter
|
||||
*
|
||||
* @param array $columns An array containing the sort columns, with the
|
||||
* submit value as the key and the value as the label
|
||||
*/
|
||||
private function setupSortControl(array $columns)
|
||||
{
|
||||
$this->view->sortControl = new SortBox(
|
||||
$this->getRequest()->getActionName(),
|
||||
$columns
|
||||
);
|
||||
$this->view->sortControl->applyRequest($this->getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all tabs for this controller
|
||||
*
|
||||
|
@ -273,18 +322,7 @@ class Monitoring_ListController extends ActionController
|
|||
|
||||
$tabs = $this->getTabs();
|
||||
$tabs->extend(new OutputFormat())
|
||||
->extend(new DashboardAction())
|
||||
->extend(new BasketAction());
|
||||
}
|
||||
|
||||
/**
|
||||
* Let the current response inherit the used sort column by applying it to the view property `sort`
|
||||
*/
|
||||
private function inheritCurrentSortColumn()
|
||||
{
|
||||
if ($this->_getParam('sort')) {
|
||||
$this->view->sort = $this->_getParam('sort');
|
||||
}
|
||||
->extend(new DashboardAction());
|
||||
}
|
||||
}
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
|
|
@ -61,7 +61,7 @@ class Monitoring_ShowController extends ActionController
|
|||
// TODO: Do not allow wildcards in names!
|
||||
if ($host !== null) {
|
||||
// TODO: $this->assertPermission('host/read', $host);
|
||||
if ($this->action_name !== 'host' && $service !== null && $service !== '*') {
|
||||
if ($this->getRequest()->getActionName() !== 'host' && $service !== null && $service !== '*') {
|
||||
// TODO: $this->assertPermission('service/read', $service);
|
||||
$object = Service::fetch($this->backend, $host, $service);
|
||||
} else {
|
||||
|
|
|
@ -16,41 +16,8 @@ function formatDateString($self,$dateString){
|
|||
$paginator = $downtimes->paginate();
|
||||
$downtimes = $downtimes->fetchAll();
|
||||
?>
|
||||
<form method="get" class="form-inline" action="<?= $this->href(
|
||||
'monitoring/list/downtimes?',
|
||||
array(
|
||||
'action' => 'downtimes'
|
||||
));
|
||||
?>">
|
||||
<label>Sort By</label>
|
||||
<br/>
|
||||
<?=
|
||||
$this->formSelect(
|
||||
'sort',
|
||||
$this->sort,
|
||||
array('class' => 'autosubmit'),
|
||||
array(
|
||||
'downtime_is_in_effect' => 'Is In Effect',
|
||||
'object_type' => 'Service/Host',
|
||||
'host_name' => 'Host Name',
|
||||
'service_description' => 'Service Name',
|
||||
'downtime_entry_time' => 'Entry Time',
|
||||
'downtime_author_name' => 'Author',
|
||||
'downtime_comment_data' => 'Comment',
|
||||
'downtime_scheduled_start_time' => 'Start',
|
||||
'downtime_scheduled_end_time' => 'End',
|
||||
'downtime_trigger_time' => 'Trigger Time',
|
||||
'downtime_internal_downtime_id' => 'Downtime ID',
|
||||
'downtime_duration' => 'Duration',
|
||||
)
|
||||
);
|
||||
?>
|
||||
<noscript>
|
||||
<button class="btn btn-small btn-default" >
|
||||
<i>{{REFRESH_ICON}}</i>
|
||||
</button>
|
||||
</noscript>
|
||||
</form>
|
||||
|
||||
<?= $this->sortControl->render($this); ?>
|
||||
<?=
|
||||
$this->paginationControl(
|
||||
$paginator,
|
||||
|
|
|
@ -5,31 +5,14 @@ $hosts = $this->hosts->paginate();
|
|||
$viewHelper = $this->getHelper('MonitoringState');
|
||||
?>
|
||||
|
||||
<form method="get" class="form-inline" action="<?= $this->href('monitoring/list/hosts', $this->hosts->getAppliedFilter()->toParams());?>">
|
||||
<label>Sort By</label>
|
||||
<?= $this->formSelect(
|
||||
'sort',
|
||||
$this->sort,
|
||||
array('class' => array('autosubmit')),
|
||||
array(
|
||||
'host_severity' => 'Severity',
|
||||
'host_last_state_change' => 'Last state change',
|
||||
'host_name' => 'Host',
|
||||
)
|
||||
); ?>
|
||||
<noscript>
|
||||
<button class="btn btn-small btn-default">
|
||||
<i>{{REFRESH_ICON}}</i>
|
||||
</button>
|
||||
</noscript>
|
||||
</form>
|
||||
<?= $this->sortControl->render($this); ?>
|
||||
<?= $this->paginationControl($hosts, null, null, array('preserve' => $this->preserve)); ?>
|
||||
|
||||
<table class="table table-condensed">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Status</th>
|
||||
<th colspan="3">Status</th>
|
||||
<th>Host</th>
|
||||
<th>Output</th>
|
||||
<th></th>
|
||||
|
|
|
@ -4,31 +4,7 @@
|
|||
$formatter = $this->getHelper('MonitoringProperties');
|
||||
?>
|
||||
|
||||
<form method="get" action="<?=
|
||||
$this->href(
|
||||
'monitoring/list/notifications',
|
||||
$this->notifications->getAppliedFilter()->toParams()
|
||||
);
|
||||
?>">
|
||||
<label>Sort By</label> <?=
|
||||
$this->formSelect(
|
||||
'sort',
|
||||
$this->sort,
|
||||
array(
|
||||
'class' => 'autosubmit'
|
||||
),
|
||||
array(
|
||||
'notification_start_time' => 'Time'
|
||||
)
|
||||
);
|
||||
?>
|
||||
<noscript>
|
||||
<button class="btn btn-small btn-default">
|
||||
{{REFRESH_ICON}}
|
||||
</button>
|
||||
</noscript>
|
||||
</form>
|
||||
|
||||
<?= $this->sortControl->render($this); ?>
|
||||
<?php
|
||||
$notifications = $this->notifications->paginate();
|
||||
echo $this->paginationControl($notifications, null, null, array('preserve' => $this->preserve));
|
||||
|
@ -50,9 +26,16 @@ echo $this->paginationControl($notifications, null, null, array('preserve' => $t
|
|||
<?php foreach ($notifications as $notification): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="<?= $this->href('monitoring/show/host', array('host' => $notification->host_name)); ?>">
|
||||
<?= $notification->host_name ?>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?= $this->href('monitoring/show/host', array(
|
||||
'host' => $notification->host_name,
|
||||
'service' => $notification->service_description
|
||||
)
|
||||
); ?>">
|
||||
<?= empty($notification->service_description) ? '' : $notification->service_description; ?>
|
||||
</td>
|
||||
<td><?= $formatter->getNotificationType($notification); ?>
|
||||
|
|
|
@ -6,41 +6,13 @@ $viewHelper = $this->getHelper('MonitoringState');
|
|||
$trimArea = $this->getHelper('Trim');
|
||||
?>
|
||||
|
||||
<?php if (empty($services)): ?>
|
||||
<div>
|
||||
Sorry, no services found for this search
|
||||
</div>
|
||||
<?php return; endif ?>
|
||||
|
||||
<form method="get" action="<?= $this->href('monitoring/list/services', $this->services->getAppliedFilter()->toParams()); ?>">
|
||||
<label>Sort By</label>
|
||||
<?= $this->formSelect(
|
||||
'sort',
|
||||
$this->sort,
|
||||
array('class' => 'autosubmit'),
|
||||
array(
|
||||
'service_severity' => 'Severity',
|
||||
'service_last_state_change' => 'Last state change',
|
||||
'service_last_time_unknown' => 'Last UNKNOWN',
|
||||
'service_last_time_critical' => 'Last CRITICAL',
|
||||
'service_last_time_warning' => 'Last WARNING',
|
||||
'service_last_time_ok' => 'Last OK',
|
||||
'service_description' => 'Service',
|
||||
)
|
||||
); ?>
|
||||
<noscript>
|
||||
<button class="btn btn-small btn-default">
|
||||
<i>ICON REFRESH</i>
|
||||
</button>
|
||||
</noscript>
|
||||
</form>
|
||||
|
||||
<?= $this->sortControl->render($this); ?>
|
||||
<?= $this->paginationControl($paginator, null, null, array('preserve' => $this->preserve)) ?>
|
||||
|
||||
<table class="table table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Status</th>
|
||||
<th colspan="3">Status</th>
|
||||
<th>Service</th>
|
||||
<th>Host</th>
|
||||
<th>Output</th>
|
||||
|
@ -115,8 +87,15 @@ $trimArea = $this->getHelper('Trim');
|
|||
<i>{{COMMENT_ICON}}</i>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
|
||||
<a href="<?= $this->href(
|
||||
'monitoring/show/service',
|
||||
array(
|
||||
'host' => $service->host_name,
|
||||
'service' => $service->service_description
|
||||
)
|
||||
); ?>">
|
||||
<b> <?= $service->service_display_name; ?></b>
|
||||
</a>
|
||||
<br/>
|
||||
|
||||
<?php if ($service->service_action_url != ""): ?>
|
||||
|
@ -130,7 +109,14 @@ $trimArea = $this->getHelper('Trim');
|
|||
</td>
|
||||
|
||||
<td title="<?= $viewHelper->getStateTitle($service, 'host'); ?>">
|
||||
<a href="<?= $this->href(
|
||||
'monitoring/show/host',
|
||||
array(
|
||||
'host' => $service->host_name,
|
||||
)
|
||||
); ?>">
|
||||
<?= $service->host_name; ?>
|
||||
</a>
|
||||
|
||||
<div>
|
||||
(<?= ucfirst($viewHelper->monitoringState($service, 'host')); ?>)
|
||||
|
|
|
@ -119,7 +119,7 @@ abstract class MonitoringControllerTest extends Zend_Test_PHPUnit_ControllerTest
|
|||
require_once('Data/Db/Connection.php');
|
||||
require_once('Data/Db/Query.php');
|
||||
require_once('Exception/ProgrammingError.php');
|
||||
|
||||
require_once('Web/Widget/SortBox.php');
|
||||
require_once('library/Monitoring/Backend/AbstractBackend.php');
|
||||
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ define(['jquery', 'logging', 'icinga/componentRegistry'], function ($, log, regi
|
|||
*/
|
||||
var loadComponent = function(cmpType, target, fin, err) {
|
||||
requirejs(
|
||||
['modules/' + cmpType],
|
||||
['components/' + cmpType],
|
||||
function (Cmp) {
|
||||
var cmp;
|
||||
try {
|
||||
|
|
|
@ -26,9 +26,22 @@
|
|||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/*global Icinga:false, document: false, define:false require:false base_url:false console:false, window:false */
|
||||
|
||||
|
||||
/**
|
||||
* Icinga Logger
|
||||
*
|
||||
* Allows platform independent logging of via logger.info, logger.warn, logger.error and logger.emergency
|
||||
*
|
||||
*/
|
||||
define(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Log a message to the console (if available), using the provided tag
|
||||
*
|
||||
* @param {String} tag The tag to use, error and emergency are logged as console.error
|
||||
* @param {String} logArgs The arguments to log
|
||||
*/
|
||||
function logTagged(tag, logArgs) {
|
||||
var now = new Date();
|
||||
var ms = now.getMilliseconds() + '';
|
||||
|
@ -42,11 +55,11 @@ define(function() {
|
|||
for (var el in logArgs) {
|
||||
args.push(logArgs[el]);
|
||||
}
|
||||
|
||||
try {
|
||||
if (console[tag]) {
|
||||
|
||||
console[tag].apply(console, logArgs);
|
||||
} else if (tag === 'emergency') {
|
||||
console.error.apply(console, logArgs);
|
||||
} else {
|
||||
console.log.apply(console, args);
|
||||
}
|
||||
|
@ -59,7 +72,11 @@ define(function() {
|
|||
if(!window.console) {
|
||||
window.console = { log: function() {} };
|
||||
}
|
||||
var features = {
|
||||
|
||||
/**
|
||||
* Callinterface for this module
|
||||
*/
|
||||
return {
|
||||
debug: function() {
|
||||
if (!window.ICINGA_DEBUG) {
|
||||
return;
|
||||
|
@ -77,6 +94,4 @@ define(function() {
|
|||
// TODO: log *emergency* errors to the backend
|
||||
}
|
||||
};
|
||||
|
||||
return features;
|
||||
});
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
requirejs.config({
|
||||
baseUrl: window.base_url + '/js',
|
||||
paths: {
|
||||
'baseUrl': window.base_url + '/js',
|
||||
'paths': {
|
||||
'jquery': 'vendor/jquery-1.8.3',
|
||||
'bootstrap': 'vendor/bootstrap/bootstrap.min',
|
||||
'history': 'vendor/history',
|
||||
'logging': 'icinga/util/logging',
|
||||
'datetimepicker': 'vendor/bootstrap/datetimepicker.min'
|
||||
},
|
||||
'shim': {
|
||||
'datetimepicker': {
|
||||
'exports': 'datetimepicker'
|
||||
},
|
||||
'jquery' : {
|
||||
exports: 'jquery'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ var rjsmock = require('requiremock.js');
|
|||
GLOBAL.document = $('body');
|
||||
var component;
|
||||
|
||||
|
||||
/**
|
||||
* Set up the test fixture
|
||||
*
|
||||
|
@ -28,28 +27,30 @@ var setUp = function(registry)
|
|||
/*
|
||||
* Available components
|
||||
*/
|
||||
'modules/app/component1': function(cmp) {
|
||||
'components/app/component1': function(cmp) {
|
||||
cmp.test = 'changed-by-component-1';
|
||||
this.type = function() {
|
||||
return "app/component1";
|
||||
};
|
||||
return this;
|
||||
},
|
||||
'modules/app/component2': function(cmp) {
|
||||
'components/app/component2': function(cmp) {
|
||||
cmp.test = 'changed-by-component-2';
|
||||
this.type = function() {
|
||||
return "app/component2";
|
||||
};
|
||||
return this;
|
||||
},
|
||||
'modules/module/component3': function(cmp) {
|
||||
'components/module/component3': function(cmp) {
|
||||
cmp.test = 'changed-by-component-3-from-module';
|
||||
this.type = function() {
|
||||
return "module/component3";
|
||||
};
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
$('body').empty();
|
||||
|
||||
requireNew('icinga/componentLoader.js');
|
||||
component = rjsmock.getDefine();
|
||||
};
|
||||
|
@ -72,7 +73,6 @@ describe('Component loader', function() {
|
|||
it('Component loaded with automatic id', function() {
|
||||
setUp();
|
||||
addComponent('app/component1');
|
||||
|
||||
component.load(function() {
|
||||
var cmpNode = $('#icinga-component-0');
|
||||
cmpNode.length.should.equal(1);
|
||||
|
|
|
@ -65,7 +65,7 @@ class GeneralFormTest extends BaseTestCase
|
|||
if ($child->hasAttributes() === false) {
|
||||
continue;
|
||||
}
|
||||
if (strpos($child->attributes->item(0)->value, $value) !== false) {
|
||||
if (strpos($child->attributes->getNamedItem('id')->value, $value . '-element') !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue