Merge branch 'master' into feature/security-gui-5647

This commit is contained in:
Eric Lippmann 2014-11-19 14:13:26 +01:00
commit a2818bd937
97 changed files with 2476 additions and 1429 deletions

View File

@ -2,16 +2,17 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Application\Config;
use Icinga\Application\Logger;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\IcingaException;
use Icinga\Exception\NotReadableError;
use Icinga\File\Ini\IniWriter;
use Icinga\Forms\Dashboard\AddUrlForm;
use Icinga\Exception\ProgrammingError;
use Icinga\Forms\ConfirmRemovalForm;
use Icinga\Forms\Dashboard\ComponentForm;
use Icinga\Web\Form;
use Icinga\Web\Notification;
use Icinga\Web\Controller\ActionController;
use Icinga\Web\Request;
use Icinga\Web\Url;
use Icinga\Web\Widget\Dashboard;
use Icinga\Web\Widget\Tabextension\DashboardSettings;
/**
* Handle creation, removal and displaying of dashboards, panes and components
@ -21,92 +22,203 @@ use Icinga\Web\Widget\Dashboard;
class DashboardController extends ActionController
{
/**
* Default configuration
* @var Dashboard;
*/
const DEFAULT_CONFIG = 'dashboard/dashboard';
/**
* Retrieve a dashboard from the provided config
*
* @param string $config The config to read the dashboard from, or 'dashboard/dashboard' if none is given
*
* @return \Icinga\Web\Widget\Dashboard
*/
private function getDashboard($config = self::DEFAULT_CONFIG)
private $dashboard;
public function init()
{
$dashboard = new Dashboard();
try {
$dashboardConfig = Config::app($config);
if ($dashboardConfig->isEmpty()) {
return null;
}
$dashboard->readConfig($dashboardConfig);
} catch (NotReadableError $e) {
Logger::error(new IcingaException('Cannot load dashboard configuration. An exception was thrown:', $e));
return null;
}
return $dashboard;
$this->dashboard = new Dashboard();
$this->dashboard->setUser($this->getRequest()->getUser());
$this->dashboard->load();
}
/**
* Remove a component from the pane identified by the 'pane' parameter
*/
public function removecomponentAction()
public function newComponentAction()
{
$pane = $this->_getParam('pane');
$dashboard = $this->getDashboard();
try {
$dashboard->removeComponent(
$pane,
$this->_getParam('component')
)->store();
$this->redirectNow(Url::fromPath('dashboard', array('pane' => $pane)));
} catch (ConfigurationError $exc ) {
$this->_helper->viewRenderer('show_configuration');
$this->view->exceptionMessage = $exc->getMessage();
$this->view->iniConfigurationString = $dashboard->toIni();
$form = new ComponentForm();
$this->createTabs();
$dashboard = $this->dashboard;
$form->setDashboard($dashboard);
if ($this->_request->getParam('url')) {
$params = $this->_request->getParams();
$params['url'] = rawurldecode($this->_request->getParam('url'));
$form->populate($params);
}
$action = $this;
$form->setOnSuccess(function (Form $form) use ($dashboard, $action) {
try {
$pane = $dashboard->getPane($form->getValue('pane'));
} catch (ProgrammingError $e) {
$pane = new Dashboard\Pane($form->getValue('pane'));
$pane->setUserWidget();
$dashboard->addPane($pane);
}
$component = new Dashboard\Component($form->getValue('component'), $form->getValue('url'), $pane);
$component->setUserWidget();
$pane->addComponent($component);
try {
$dashboard->write();
} catch (\Zend_Config_Exception $e) {
$action->view->error = $e;
$action->view->config = $dashboard->createWriter();
$action->render('error');
return false;
}
Notification::success(t('Component created'));
return true;
});
$form->setRedirectUrl('dashboard');
$form->handleRequest();
$this->view->form = $form;
}
/**
* Display the form for adding new components or add the new component if submitted
*/
public function addurlAction()
public function updateComponentAction()
{
$this->getTabs()->add(
'addurl',
array(
'title' => 'Add Dashboard URL',
'url' => Url::fromRequest()
)
)->activate('addurl');
$form = new AddUrlForm();
$request = $this->getRequest();
if ($request->isPost()) {
if ($form->isValid($request->getPost()) && $form->isSubmitted()) {
$dashboard = $this->getDashboard();
$dashboard->setComponentUrl(
$form->getValue('pane'),
$form->getValue('component'),
ltrim($form->getValue('url'), '/')
);
$configFile = Config::app('dashboard/dashboard')->getConfigFile();
if ($this->writeConfiguration(Config::fromArray($dashboard->toArray()), $configFile)) {
$this->redirectNow(Url::fromPath('dashboard', array('pane' => $form->getValue('pane'))));
} else {
$this->render('showConfiguration');
return;
}
}
} else {
$form->create()->setDefault('url', htmlspecialchars_decode($request->getParam('url', '')));
$this->createTabs();
$dashboard = $this->dashboard;
$form = new ComponentForm();
$form->setDashboard($dashboard);
$form->setSubmitLabel(t('Update Component'));
if (! $this->_request->getParam('pane')) {
throw new Zend_Controller_Action_Exception(
'Missing parameter "pane"',
400
);
}
if (! $this->_request->getParam('component')) {
throw new Zend_Controller_Action_Exception(
'Missing parameter "component"',
400
);
}
$action = $this;
$form->setOnSuccess(function (Form $form) use ($dashboard, $action) {
try {
$pane = $dashboard->getPane($form->getValue('pane'));
} catch (ProgrammingError $e) {
$pane = new Dashboard\Pane($form->getValue('pane'));
$pane->setUserWidget();
$dashboard->addPane($pane);
}
try {
$component = $pane->getComponent($form->getValue('component'));
$component->setUrl($form->getValue('url'));
} catch (ProgrammingError $e) {
$component = new Dashboard\Component($form->getValue('component'), $form->getValue('url'), $pane);
$pane->addComponent($component);
}
$component->setUserWidget();
// Rename component
if ($form->getValue('org_component') && $form->getValue('org_component') !== $component->getTitle()) {
$pane->removeComponent($form->getValue('org_component'));
}
// Move
if ($form->getValue('org_pane') && $form->getValue('org_pane') !== $pane->getTitle()) {
$oldPane = $dashboard->getPane($form->getValue('org_pane'));
$oldPane->removeComponent($component->getTitle());
}
try {
$dashboard->write();
} catch (\Zend_Config_Exception $e) {
$action->view->error = $e;
$action->view->config = $dashboard->createWriter();
$action->render('error');
return false;
}
Notification::success(t('Component updated'));
return true;
});
$form->setRedirectUrl('dashboard/settings');
$form->handleRequest();
$pane = $dashboard->getPane($this->getParam('pane'));
$component = $pane->getComponent($this->getParam('component'));
$form->load($component);
$this->view->form = $form;
}
public function removeComponentAction()
{
$form = new ConfirmRemovalForm();
$this->createTabs();
$dashboard = $this->dashboard;
if (! $this->_request->getParam('pane')) {
throw new Zend_Controller_Action_Exception(
'Missing parameter "pane"',
400
);
}
if (! $this->_request->getParam('component')) {
throw new Zend_Controller_Action_Exception(
'Missing parameter "component"',
400
);
}
$pane = $this->_request->getParam('pane');
$component = $this->_request->getParam('component');
$action = $this;
$form->setOnSuccess(function (Form $form) use ($dashboard, $component, $pane, $action) {
try {
$pane = $dashboard->getPane($pane);
$pane->removeComponent($component);
$dashboard->write();
Notification::success(t('Component has been removed from') . ' ' . $pane->getTitle());
return true;
} catch (\Zend_Config_Exception $e) {
$action->view->error = $e;
$action->view->config = $dashboard->createWriter();
$action->render('error');
return false;
} catch (ProgrammingError $e) {
Notification::error($e->getMessage());
return false;
}
return false;
});
$form->setRedirectUrl('dashboard/settings');
$form->handleRequest();
$this->view->pane = $pane;
$this->view->component = $component;
$this->view->form = $form;
}
public function removePaneAction()
{
$form = new ConfirmRemovalForm();
$this->createTabs();
$dashboard = $this->dashboard;
if (! $this->_request->getParam('pane')) {
throw new Zend_Controller_Action_Exception(
'Missing parameter "pane"',
400
);
}
$pane = $this->_request->getParam('pane');
$action = $this;
$form->setOnSuccess(function (Form $form) use ($dashboard, $pane, $action) {
try {
$pane = $dashboard->getPane($pane);
$dashboard->removePane($pane->getTitle());
$dashboard->write();
Notification::success(t('Pane has been removed') . ': ' . $pane->getTitle());
return true;
} catch (\Zend_Config_Exception $e) {
$action->view->error = $e;
$action->view->config = $dashboard->createWriter();
$action->render('error');
return false;
} catch (ProgrammingError $e) {
Notification::error($e->getMessage());
return false;
}
return false;
});
$form->setRedirectUrl('dashboard/settings');
$form->handleRequest();
$this->view->pane = $pane;
$this->view->form = $form;
}
/**
* Display the dashboard with the pane set in the 'pane' request parameter
*
@ -115,61 +227,49 @@ class DashboardController extends ActionController
*/
public function indexAction()
{
$dashboard = Dashboard::load();
if (! $dashboard->hasPanes()) {
$this->createTabs();
if (! $this->dashboard->hasPanes()) {
$this->view->title = 'Dashboard';
} else {
if ($this->_getParam('pane')) {
$pane = $this->_getParam('pane');
$dashboard->activate($pane);
$this->dashboard->activate($pane);
}
$this->view->configPath = Config::resolvePath(self::DEFAULT_CONFIG);
if ($dashboard === null) {
if ($this->dashboard === null) {
$this->view->title = 'Dashboard';
} else {
$this->view->title = $dashboard->getActivePane()->getTitle() . ' :: Dashboard';
$this->view->tabs = $dashboard->getTabs();
/* Temporarily removed
$this->view->title = $this->dashboard->getActivePane()->getTitle() . ' :: Dashboard';
if ($this->hasParam('remove')) {
$this->dashboard->getActivePane()->removeComponent($this->getParam('remove'));
$this->dashboard->write();
$this->redirectNow(URL::fromRequest()->remove('remove'));
}
$this->view->tabs->add(
'Add',
array(
'title' => '+',
'url' => Url::fromPath('dashboard/addurl')
'url' => Url::fromPath('dashboard/new-component')
)
);
*/
$this->view->dashboard = $dashboard;
$this->view->dashboard = $this->dashboard;
}
}
}
/**
* Store the given configuration as INI file
*
* @param Config $config The configuration to store
* @param string $target The path where to store the configuration
*
* @return bool Whether the configuartion has been successfully stored
* Setting dialog
*/
protected function writeConfiguration(Config $config, $target)
public function settingsAction()
{
$writer = new IniWriter(array('config' => $config, 'filename' => $target));
$this->createTabs();
$this->view->dashboard = $this->dashboard;
}
try {
$writer->write();
} catch (Exception $e) {
Logger::error(new ConfiguationError("Cannot write dashboard to $target", 0, $e));
$this->view->configString = $writer->render();
$this->view->errorMessage = $e->getMessage();
$this->view->filePath = $target;
return false;
}
return true;
/**
* Create tab aggregation
*/
private function createTabs()
{
$this->view->tabs = $this->dashboard->getTabs()->extend(new DashboardSettings());
}
}

View File

@ -48,6 +48,12 @@
"code": 59481,
"src": "fontawesome"
},
{
"uid": "0d6ab6194c0eddda2b8c9cedf2ab248e",
"css": "attach",
"code": 59498,
"src": "fontawesome"
},
{
"uid": "c1f1975c885aa9f3dad7810c53b82074",
"css": "lock",
@ -144,6 +150,12 @@
"code": 59470,
"src": "fontawesome"
},
{
"uid": "ecb97add13804c190456025e43ec003b",
"css": "keyboard",
"code": 59499,
"src": "fontawesome"
},
{
"uid": "85528017f1e6053b2253785c31047f44",
"css": "comment",
@ -234,15 +246,21 @@
"code": 59457,
"src": "fontawesome"
},
{
"uid": "559647a6f430b3aeadbecd67194451dd",
"css": "menu",
"code": 59500,
"src": "fontawesome"
},
{
"uid": "e99461abfef3923546da8d745372c995",
"css": "conf",
"css": "service",
"code": 59456,
"src": "fontawesome"
},
{
"uid": "98687378abd1faf8f6af97c254eb6cd6",
"css": "conf-alt",
"css": "services",
"code": 59455,
"src": "fontawesome"
},
@ -452,10 +470,16 @@
},
{
"uid": "d407a4707f719b042ed2ad28d2619d7e",
"css": "service",
"css": "barchart",
"code": 59420,
"src": "fontawesome"
},
{
"uid": "cd4bfdae4dc89b175ff49330ce29611a",
"css": "wifi",
"code": 59501,
"src": "fontawesome"
},
{
"uid": "500fc1f109021e4b1de4deda2f7ed399",
"css": "host",
@ -480,6 +504,12 @@
"code": 59419,
"src": "fontawesome"
},
{
"uid": "567e3e257f2cc8fba2c12bf691c9f2d8",
"css": "moon",
"code": 59502,
"src": "fontawesome"
},
{
"uid": "8772331a9fec983cdb5d72902a6f9e0e",
"css": "scissors",
@ -504,6 +534,24 @@
"code": 59414,
"src": "fontawesome"
},
{
"uid": "266d5d9adf15a61800477a5acf9a4462",
"css": "chart-bar",
"code": 59505,
"src": "fontawesome"
},
{
"uid": "7d1ca956f4181a023de4b9efbed92524",
"css": "chart-area",
"code": 59504,
"src": "fontawesome"
},
{
"uid": "554ee96588a6c9ee632624cd051fe6fc",
"css": "chart-pie",
"code": 59503,
"src": "fontawesome"
},
{
"uid": "ea2d9a8c51ca42b38ef0d2a07f16d9a7",
"css": "chart-line",
@ -534,6 +582,18 @@
"code": 59412,
"src": "fontawesome"
},
{
"uid": "0f444c61b0d2c9966016d7ddb12f5837",
"css": "beaker",
"code": 59506,
"src": "fontawesome"
},
{
"uid": "ff70f7b3228702e0d590e60ed3b90bea",
"css": "magic",
"code": 59507,
"src": "fontawesome"
},
{
"uid": "3ed68ae14e9cde775121954242a412b2",
"css": "sort-name-up",
@ -558,6 +618,12 @@
"code": 59406,
"src": "fontawesome"
},
{
"uid": "cda0cdcfd38f5f1d9255e722dad42012",
"css": "spinner",
"code": 59497,
"src": "fontawesome"
},
{
"uid": "af95ef0ddda80a78828c62d386506433",
"css": "cubes",

View File

@ -27,7 +27,7 @@
.icon-globe:before { content: '\e819'; } /* '' */
.icon-cloud:before { content: '\e81a'; } /* '' */
.icon-flash:before { content: '\e81b'; } /* '' */
.icon-service:before { content: '\e81c'; } /* '' */
.icon-barchart:before { content: '\e81c'; } /* '' */
.icon-down-dir:before { content: '\e81d'; } /* '' */
.icon-up-dir:before { content: '\e81e'; } /* '' */
.icon-left-dir:before { content: '\e81f'; } /* '' */
@ -62,8 +62,8 @@
.icon-calendar:before { content: '\e83c'; } /* '' */
.icon-wrench:before { content: '\e83d'; } /* '' */
.icon-sliders:before { content: '\e83e'; } /* '' */
.icon-conf-alt:before { content: '\e83f'; } /* '' */
.icon-conf:before { content: '\e840'; } /* '' */
.icon-services:before { content: '\e83f'; } /* '' */
.icon-service:before { content: '\e840'; } /* '' */
.icon-phone:before { content: '\e841'; } /* '' */
.icon-file-pdf:before { content: '\e842'; } /* '' */
.icon-file-word:before { content: '\e843'; } /* '' */
@ -103,4 +103,15 @@
.icon-cw:before { content: '\e865'; } /* '' */
.icon-host:before { content: '\e866'; } /* '' */
.icon-thumbs-up:before { content: '\e867'; } /* '' */
.icon-thumbs-down:before { content: '\e868'; } /* '' */
.icon-thumbs-down:before { content: '\e868'; } /* '' */
.icon-spinner:before { content: '\e869'; } /* '' */
.icon-attach:before { content: '\e86a'; } /* '' */
.icon-keyboard:before { content: '\e86b'; } /* '' */
.icon-menu:before { content: '\e86c'; } /* '' */
.icon-wifi:before { content: '\e86d'; } /* '' */
.icon-moon:before { content: '\e86e'; } /* '' */
.icon-chart-pie:before { content: '\e86f'; } /* '' */
.icon-chart-area:before { content: '\e870'; } /* '' */
.icon-chart-bar:before { content: '\e871'; } /* '' */
.icon-beaker:before { content: '\e872'; } /* '' */
.icon-magic:before { content: '\e873'; } /* '' */

View File

@ -27,7 +27,7 @@
.icon-globe { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-cloud { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-flash { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-service { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-barchart { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-down-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-up-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-left-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
@ -62,8 +62,8 @@
.icon-calendar { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-wrench { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-sliders { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-conf-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-conf { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-services { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-service { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-phone { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-file-pdf { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-file-word { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
@ -103,4 +103,15 @@
.icon-cw { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-host { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-thumbs-up { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-thumbs-down { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-thumbs-down { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-spinner { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-attach { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-keyboard { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-menu { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-wifi { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-moon { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-chart-pie { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-chart-area { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-chart-bar { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-beaker { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-magic { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }

View File

@ -38,7 +38,7 @@
.icon-globe { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-cloud { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-flash { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-service { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-barchart { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-down-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-up-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-left-dir { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
@ -73,8 +73,8 @@
.icon-calendar { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-wrench { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-sliders { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-conf-alt { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-conf { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-services { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-service { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-phone { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-file-pdf { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-file-word { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
@ -114,4 +114,15 @@
.icon-cw { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-host { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-thumbs-up { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-thumbs-down { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-thumbs-down { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-spinner { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-attach { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-keyboard { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-menu { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-wifi { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-moon { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-chart-pie { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-chart-area { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-chart-bar { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-beaker { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
.icon-magic { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }

View File

@ -1,10 +1,10 @@
@font-face {
font-family: 'ifont';
src: url('../font/ifont.eot?81676749');
src: url('../font/ifont.eot?81676749#iefix') format('embedded-opentype'),
url('../font/ifont.woff?81676749') format('woff'),
url('../font/ifont.ttf?81676749') format('truetype'),
url('../font/ifont.svg?81676749#ifont') format('svg');
src: url('../font/ifont.eot?81587324');
src: url('../font/ifont.eot?81587324#iefix') format('embedded-opentype'),
url('../font/ifont.woff?81587324') format('woff'),
url('../font/ifont.ttf?81587324') format('truetype'),
url('../font/ifont.svg?81587324#ifont') format('svg');
font-weight: normal;
font-style: normal;
}
@ -14,7 +14,7 @@
@media screen and (-webkit-min-device-pixel-ratio:0) {
@font-face {
font-family: 'ifont';
src: url('../font/ifont.svg?81676749#ifont') format('svg');
src: url('../font/ifont.svg?81587324#ifont') format('svg');
}
}
*/
@ -78,7 +78,7 @@
.icon-globe:before { content: '\e819'; } /* '' */
.icon-cloud:before { content: '\e81a'; } /* '' */
.icon-flash:before { content: '\e81b'; } /* '' */
.icon-service:before { content: '\e81c'; } /* '' */
.icon-barchart:before { content: '\e81c'; } /* '' */
.icon-down-dir:before { content: '\e81d'; } /* '' */
.icon-up-dir:before { content: '\e81e'; } /* '' */
.icon-left-dir:before { content: '\e81f'; } /* '' */
@ -113,8 +113,8 @@
.icon-calendar:before { content: '\e83c'; } /* '' */
.icon-wrench:before { content: '\e83d'; } /* '' */
.icon-sliders:before { content: '\e83e'; } /* '' */
.icon-conf-alt:before { content: '\e83f'; } /* '' */
.icon-conf:before { content: '\e840'; } /* '' */
.icon-services:before { content: '\e83f'; } /* '' */
.icon-service:before { content: '\e840'; } /* '' */
.icon-phone:before { content: '\e841'; } /* '' */
.icon-file-pdf:before { content: '\e842'; } /* '' */
.icon-file-word:before { content: '\e843'; } /* '' */
@ -154,4 +154,15 @@
.icon-cw:before { content: '\e865'; } /* '' */
.icon-host:before { content: '\e866'; } /* '' */
.icon-thumbs-up:before { content: '\e867'; } /* '' */
.icon-thumbs-down:before { content: '\e868'; } /* '' */
.icon-thumbs-down:before { content: '\e868'; } /* '' */
.icon-spinner:before { content: '\e869'; } /* '' */
.icon-attach:before { content: '\e86a'; } /* '' */
.icon-keyboard:before { content: '\e86b'; } /* '' */
.icon-menu:before { content: '\e86c'; } /* '' */
.icon-wifi:before { content: '\e86d'; } /* '' */
.icon-moon:before { content: '\e86e'; } /* '' */
.icon-chart-pie:before { content: '\e86f'; } /* '' */
.icon-chart-area:before { content: '\e870'; } /* '' */
.icon-chart-bar:before { content: '\e871'; } /* '' */
.icon-beaker:before { content: '\e872'; } /* '' */
.icon-magic:before { content: '\e873'; } /* '' */

View File

@ -297,7 +297,7 @@ body {
<div title="Code: 0xe81b" class="the-icons span3"><i class="icon-flash"></i> <span class="i-name">icon-flash</span><span class="i-code">0xe81b</span></div>
</div>
<div class="row">
<div title="Code: 0xe81c" class="the-icons span3"><i class="icon-service"></i> <span class="i-name">icon-service</span><span class="i-code">0xe81c</span></div>
<div title="Code: 0xe81c" class="the-icons span3"><i class="icon-barchart"></i> <span class="i-name">icon-barchart</span><span class="i-code">0xe81c</span></div>
<div title="Code: 0xe81d" class="the-icons span3"><i class="icon-down-dir"></i> <span class="i-name">icon-down-dir</span><span class="i-code">0xe81d</span></div>
<div title="Code: 0xe81e" class="the-icons span3"><i class="icon-up-dir"></i> <span class="i-name">icon-up-dir</span><span class="i-code">0xe81e</span></div>
<div title="Code: 0xe81f" class="the-icons span3"><i class="icon-left-dir"></i> <span class="i-name">icon-left-dir</span><span class="i-code">0xe81f</span></div>
@ -348,10 +348,10 @@ body {
<div title="Code: 0xe83c" class="the-icons span3"><i class="icon-calendar"></i> <span class="i-name">icon-calendar</span><span class="i-code">0xe83c</span></div>
<div title="Code: 0xe83d" class="the-icons span3"><i class="icon-wrench"></i> <span class="i-name">icon-wrench</span><span class="i-code">0xe83d</span></div>
<div title="Code: 0xe83e" class="the-icons span3"><i class="icon-sliders"></i> <span class="i-name">icon-sliders</span><span class="i-code">0xe83e</span></div>
<div title="Code: 0xe83f" class="the-icons span3"><i class="icon-conf-alt"></i> <span class="i-name">icon-conf-alt</span><span class="i-code">0xe83f</span></div>
<div title="Code: 0xe83f" class="the-icons span3"><i class="icon-services"></i> <span class="i-name">icon-services</span><span class="i-code">0xe83f</span></div>
</div>
<div class="row">
<div title="Code: 0xe840" class="the-icons span3"><i class="icon-conf"></i> <span class="i-name">icon-conf</span><span class="i-code">0xe840</span></div>
<div title="Code: 0xe840" class="the-icons span3"><i class="icon-service"></i> <span class="i-name">icon-service</span><span class="i-code">0xe840</span></div>
<div title="Code: 0xe841" class="the-icons span3"><i class="icon-phone"></i> <span class="i-name">icon-phone</span><span class="i-code">0xe841</span></div>
<div title="Code: 0xe842" class="the-icons span3"><i class="icon-file-pdf"></i> <span class="i-name">icon-file-pdf</span><span class="i-code">0xe842</span></div>
<div title="Code: 0xe843" class="the-icons span3"><i class="icon-file-word"></i> <span class="i-name">icon-file-word</span><span class="i-code">0xe843</span></div>
@ -412,6 +412,21 @@ body {
</div>
<div class="row">
<div title="Code: 0xe868" class="the-icons span3"><i class="icon-thumbs-down"></i> <span class="i-name">icon-thumbs-down</span><span class="i-code">0xe868</span></div>
<div title="Code: 0xe869" class="the-icons span3"><i class="icon-spinner"></i> <span class="i-name">icon-spinner</span><span class="i-code">0xe869</span></div>
<div title="Code: 0xe86a" class="the-icons span3"><i class="icon-attach"></i> <span class="i-name">icon-attach</span><span class="i-code">0xe86a</span></div>
<div title="Code: 0xe86b" class="the-icons span3"><i class="icon-keyboard"></i> <span class="i-name">icon-keyboard</span><span class="i-code">0xe86b</span></div>
</div>
<div class="row">
<div title="Code: 0xe86c" class="the-icons span3"><i class="icon-menu"></i> <span class="i-name">icon-menu</span><span class="i-code">0xe86c</span></div>
<div title="Code: 0xe86d" class="the-icons span3"><i class="icon-wifi"></i> <span class="i-name">icon-wifi</span><span class="i-code">0xe86d</span></div>
<div title="Code: 0xe86e" class="the-icons span3"><i class="icon-moon"></i> <span class="i-name">icon-moon</span><span class="i-code">0xe86e</span></div>
<div title="Code: 0xe86f" class="the-icons span3"><i class="icon-chart-pie"></i> <span class="i-name">icon-chart-pie</span><span class="i-code">0xe86f</span></div>
</div>
<div class="row">
<div title="Code: 0xe870" class="the-icons span3"><i class="icon-chart-area"></i> <span class="i-name">icon-chart-area</span><span class="i-code">0xe870</span></div>
<div title="Code: 0xe871" class="the-icons span3"><i class="icon-chart-bar"></i> <span class="i-name">icon-chart-bar</span><span class="i-code">0xe871</span></div>
<div title="Code: 0xe872" class="the-icons span3"><i class="icon-beaker"></i> <span class="i-name">icon-beaker</span><span class="i-code">0xe872</span></div>
<div title="Code: 0xe873" class="the-icons span3"><i class="icon-magic"></i> <span class="i-name">icon-magic</span><span class="i-code">0xe873</span></div>
</div>
</div>
<div class="container footer">Generated by <a href="http://fontello.com">fontello.com</a></div>

View File

@ -34,7 +34,7 @@
<glyph glyph-name="globe" unicode="&#xe819;" d="m429 779q116 0 215-58t156-156 57-215-57-215-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58z m152-291q-1-1-5-5t-7-6q1 0 2 3t3 6 2 4q3 4 12 8 8 4 29 7 19 5 29-6-1 1 5 7t8 7q2 1 8 2t9 5l1 12q-7-1-10 4t-3 12q0-2-4-5 0 4-2 5t-7-1-5-1q-5 2-8 5t-5 9-2 8q-1 3-5 6t-5 6q-1 1-2 3t-2 4-2 3-3 1-4-3-4-5-2-3q-2 1-4 1t-2-1-3-2-3-2q-1-1-4-1t-5-1q8 3-1 6-5 2-9 1 5 3 5 7t-5 8h3q-1 2-5 5t-10 4-7 4q-5 3-19 5t-18 0q-3-3-3-5t2-8 2-7q1-4-3-7t-3-7q0-4 7-9t6-12q-2-4-9-9t-9-6q-3-5-1-11t6-9q1-1 1-2t-2-3-3-2-4-2l-1-1q-7-3-12 3t-7 15q-4 14-9 17-13 4-17-1-2 7-22 15-14 5-33 2 4 0 0 8-4 9-10 7 1 3 2 10t0 7q2 7 7 13 1 1 4 5t5 7 1 4q19-3 28 6 2 2 6 9t6 10q5 3 8 3t8-3 8-3q8-1 8 6t-4 11q7 0 2 10-3 4-5 5-6 2-15-3-4-2 2-4-1 0-6-6t-9-10-9 3q0 0-3 7t-5 8q-5 0-9-9 1 5-6 9t-14 4q11 7-4 15-4 3-12 3t-11-2q-2-4-3-7t3-4 6-3 6-2 5-2q8-6 5-8-1 0-5-2t-6-2-4-3q-2-2 0-7t-1-8q-3 3-5 10t-4 9q4-5-14-4l-5 1q-3 0-9-1t-12-1-7 5q-3 4 0 11 0 2 2 1-2 2-6 5t-6 5q-25-8-52-23 3 0 6 1 3 1 8 3t5 4q19 7 24 3l3 3q7-9 11-14-4 3-17 1-11-4-12-7 4-7 2-10-2 2-6 6t-8 6-8 3q-9 0-13-1-81-45-131-124 4-4 7-4 2-1 3-5t1-6 6 1q5-4 2-10 1 0 25-15 10-10 11-12 2-6-5-10-1 1-5 5t-5 2q-2-3 0-10t6-7q-4 0-5-9t-2-20 0-13l1-1q-2-6 3-19t12-11q-7-1 11-24 3-4 4-5 2-1 7-4t9-6 5-5q2-3 6-13t8-13q-2-3 5-11t6-13q-1 0-2-1t-1 0q2-4 9-8t8-7q1-2 1-6t2-6 4-1q2 11-13 34-8 14-9 17-2 2-4 8t-2 8q1 0 3 0t5-2 4-3 1-1q-1-4 1-10t7-10 10-11 6-7q4-4 8-11t0-8q5 0 11-5t10-11q3-5 4-15t3-13q1-4 5-8t7-5l9-5t7-3q3-2 10-6t12-7q6-2 9-2t8 1 8 2q8 1 16-8t12-12q20-10 30-6-1 0 1-4t4-9 5-8 3-5q3-3 10-8t10-8q4 2 4 5-1-5 4-11t10-6q8 2 8 18-17-9-27 10 0 0-2 3t-2 5-1 4 0 5 2 1q5 0 6 2t-1 7-2 8q-1 4-6 11t-7 8q-3-5-9-4t-9 5q0-1-1-3t-1-4q-7 0-8 0 1 2 1 10t2 13q1 2 3 6t5 9 2 7-3 5-9 1q-11 0-15-11-1-2-2-6t-2-6-5-4q-4-2-14-1t-13 3q-8 4-13 16t-5 20q0 6 1 15t2 14-3 14q2 1 5 5t5 6q2 1 3 1t2 0 3 1 1 3q0 1-2 2-2 1-2 1 4-1 16 1t15-1q9-6 12 1 0 1-1 6t0 7q3-15 16-5 2-1 9-3t9-2q2-1 4-3t3-3 3 0 5 4q5-8 7-13 6-23 10-25 4-2 6-1t3 5 0 8-1 7l-1 4v11l0 4q-8 2-10 7t0 10 9 10q0 1 4 2t9 4 7 4q12 11 8 20 4 0 6 5 0 0-2 2t-5 2-2 2q5 2 1 8 3 2 4 7t4 5q5-7 12-1 4 5 1 9 2 4 11 6t10 5q4-1 5 1t0 7 2 7q2 2 8 5t8 2l9 7q2 2 0 2 10-1 18 6 5 6-4 11 2 3-2 5t-8 3q2 1 7 1t5 1q9 5-4 9-9 2-24-7z m-90-490q114 21 195 106-1 2-7 2t-7 2q-10 4-13 5 1 4-1 7t-5 5-7 5-6 4q-1 1-4 3t-4 3-4 2-5 2-5-1l-2-1q-2 0-3-1t-3-2-2-1 0-2q-12 10-20 13-3 0-7 3t-5 4-6 0-6-4q-3-2-4-8t-1-7q-4 3 0 10t1 10q-1 3-6 2t-6-2-7-5-5-3-4-3-5-5q-2-2-4-6t-2-7q-1 3-7 4t-5 3q1-5 2-19t3-22q4-17-7-26-15-14-16-23-2-12 7-14 0-4-5-12t-4-12q0-3 2-9z" horiz-adv-x="857.1" />
<glyph glyph-name="cloud" unicode="&#xe81a;" d="m1071 207q0-89-62-151t-152-63h-607q-103 0-177 73t-73 177q0 74 40 135t104 91q-1 15-1 24 0 118 84 202t202 84q88 0 159-50t105-128q39 35 93 35 59 0 101-42t42-101q0-42-23-77 72-17 119-75t46-134z" horiz-adv-x="1071.4" />
<glyph glyph-name="flash" unicode="&#xe81b;" d="m494 534q10-11 4-24l-302-646q-7-14-23-14-2 0-8 1-9 3-14 11t-3 16l110 451-226-56q-2-1-7-1-10 0-17 7-10 8-7 21l112 461q2 8 9 13t15 5h183q11 0 18-7t7-17q0-4-2-10l-96-258 221 54q5 2 7 2 11 0 19-9z" horiz-adv-x="500" />
<glyph glyph-name="service" unicode="&#xe81c;" d="m143 46v-107q0-8-5-13t-13-5h-107q-8 0-13 5t-5 13v107q0 8 5 13t13 5h107q8 0 13-5t5-13z m214 72v-179q0-8-5-13t-13-5h-107q-8 0-13 5t-5 13v179q0 8 5 13t13 5h107q8 0 13-5t5-13z m214 143v-322q0-8-5-13t-12-5h-108q-7 0-12 5t-5 13v322q0 8 5 13t12 5h108q7 0 12-5t5-13z m215 214v-536q0-8-5-13t-13-5h-107q-8 0-13 5t-5 13v536q0 8 5 13t13 5h107q8 0 13-5t5-13z m214 286v-822q0-8-5-13t-13-5h-107q-8 0-13 5t-5 13v822q0 8 5 13t13 5h107q8 0 13-5t5-13z" horiz-adv-x="1000" />
<glyph glyph-name="barchart" unicode="&#xe81c;" d="m143 46v-107q0-8-5-13t-13-5h-107q-8 0-13 5t-5 13v107q0 8 5 13t13 5h107q8 0 13-5t5-13z m214 72v-179q0-8-5-13t-13-5h-107q-8 0-13 5t-5 13v179q0 8 5 13t13 5h107q8 0 13-5t5-13z m214 143v-322q0-8-5-13t-12-5h-108q-7 0-12 5t-5 13v322q0 8 5 13t12 5h108q7 0 12-5t5-13z m215 214v-536q0-8-5-13t-13-5h-107q-8 0-13 5t-5 13v536q0 8 5 13t13 5h107q8 0 13-5t5-13z m214 286v-822q0-8-5-13t-13-5h-107q-8 0-13 5t-5 13v822q0 8 5 13t13 5h107q8 0 13-5t5-13z" horiz-adv-x="1000" />
<glyph glyph-name="down-dir" unicode="&#xe81d;" d="m571 457q0-14-10-25l-250-250q-11-11-25-11t-25 11l-250 250q-11 11-11 25t11 25 25 11h500q14 0 25-11t10-25z" horiz-adv-x="571.4" />
<glyph glyph-name="up-dir" unicode="&#xe81e;" d="m571 171q0-14-10-25t-25-10h-500q-15 0-25 10t-11 25 11 26l250 250q10 10 25 10t25-10l250-250q10-11 10-26z" horiz-adv-x="571.4" />
<glyph glyph-name="left-dir" unicode="&#xe81f;" d="m357 600v-500q0-14-10-25t-26-11-25 11l-250 250q-10 11-10 25t10 25l250 250q11 11 25 11t26-11 10-25z" horiz-adv-x="357.1" />
@ -69,8 +69,8 @@
<glyph glyph-name="calendar" unicode="&#xe83c;" d="m71-79h161v161h-161v-161z m197 0h178v161h-178v-161z m-197 197h161v178h-161v-178z m197 0h178v178h-178v-178z m-197 214h161v161h-161v-161z m411-411h179v161h-179v-161z m-214 411h178v161h-178v-161z m428-411h161v161h-161v-161z m-214 197h179v178h-179v-178z m-196 482v161q0 7-6 12t-12 6h-36q-7 0-12-6t-6-12v-161q0-7 6-13t12-5h36q7 0 12 5t6 13z m410-482h161v178h-161v-178z m-214 214h179v161h-179v-161z m214 0h161v161h-161v-161z m18 268v161q0 7-5 12t-13 6h-35q-8 0-13-6t-5-12v-161q0-7 5-13t13-5h35q8 0 13 5t5 13z m215 36v-715q0-29-22-50t-50-21h-786q-29 0-50 21t-21 50v715q0 29 21 50t50 21h72v54q0 36 26 63t63 26h36q37 0 63-26t26-63v-54h214v54q0 36 27 63t63 26h35q37 0 63-26t27-63v-54h71q29 0 50-21t22-50z" horiz-adv-x="928.6" />
<glyph glyph-name="wrench" unicode="&#xe83d;" d="m214 29q0 14-10 25t-25 10-26-10-10-25 10-26 26-10 25 10 10 26z m360 234l-381-381q-21-20-50-20-29 0-51 20l-59 61q-21 20-21 50 0 29 21 51l380 380q22-55 64-97t97-64z m353 243q0-22-12-59-27-75-92-122t-144-46q-104 0-177 73t-73 177 73 176 177 74q32 0 67-10t60-26q9-6 9-15t-9-16l-163-94v-125l108-60q2 2 44 27t75 45 40 20q8 0 13-5t4-14z" horiz-adv-x="928.6" />
<glyph glyph-name="sliders" unicode="&#xe83e;" d="m196 64v-71h-196v71h196z m197 72q14 0 25-11t11-25v-143q0-14-11-25t-25-11h-143q-14 0-25 11t-11 25v143q0 15 11 25t25 11h143z m89 214v-71h-482v71h482z m-357 286v-72h-125v72h125z m732-572v-71h-411v71h411z m-536 643q15 0 26-10t10-26v-142q0-15-10-26t-26-10h-142q-15 0-26 10t-10 26v142q0 15 10 26t26 10h142z m358-286q14 0 25-10t10-25v-143q0-15-10-25t-25-11h-143q-15 0-25 11t-11 25v143q0 14 11 25t25 10h143z m178-71v-71h-125v71h125z m0 286v-72h-482v72h482z" horiz-adv-x="857.1" />
<glyph glyph-name="conf-alt" unicode="&#xe83f;" d="m500 350q0 59-42 101t-101 42-101-42-42-101 42-101 101-42 101 42 42 101z m429-286q0 29-22 51t-50 21-50-21-21-51q0-29 21-50t50-21 51 21 21 50z m0 572q0 29-22 50t-50 21-50-21-21-50q0-30 21-51t50-21 51 21 21 51z m-215-235v-103q0-6-4-11t-9-6l-86-14q-6-19-18-42 19-27 50-64 4-6 4-11 0-7-4-11-13-17-46-50t-44-33q-6 0-11 4l-64 50q-21-11-43-17-6-60-13-87-4-13-17-13h-104q-6 0-11 4t-5 10l-13 85q-19 6-42 18l-66-50q-4-4-11-4-6 0-12 4-80 75-80 90 0 5 4 10 5 8 23 30t26 34q-13 24-20 46l-85 13q-5 1-9 5t-4 11v103q0 6 4 11t9 6l86 14q7 19 18 42-19 27-50 64-4 6-4 11 0 7 4 11 12 17 46 50t44 33q6 0 12-4l64-50q19 10 43 18 6 60 13 86 3 13 16 13h104q6 0 11-4t6-10l13-85q19-6 41-17l66 49q5 4 11 4 7 0 12-4 81-75 81-90 0-5-4-10-7-9-24-30t-25-34q13-27 19-46l85-12q5-2 9-6t4-11z m357-298v-78q0-9-83-17-6-15-16-29 28-63 28-77 0-2-2-4-68-40-69-40-5 0-26 27t-29 37q-11-1-17-1t-17 1q-7-11-29-37t-25-27q-1 0-69 40-3 2-3 4 0 14 29 77-10 14-17 29-83 8-83 17v78q0 9 83 18 7 16 17 29-29 63-29 77 0 2 3 4 2 1 19 11t33 19 17 9q4 0 25-26t29-38q12 1 17 1t17-1q28 40 51 63l4 1q2 0 69-39 2-2 2-4 0-14-28-77 9-13 16-29 83-9 83-18z m0 572v-78q0-9-83-18-6-15-16-29 28-63 28-77 0-2-2-4-68-39-69-39-5 0-26 26t-29 38q-11-1-17-1t-17 1q-7-12-29-38t-25-26q-1 0-69 39-3 2-3 4 0 14 29 77-10 14-17 29-83 9-83 18v78q0 9 83 17 7 16 17 29-29 63-29 77 0 2 3 4 2 1 19 11t33 19 17 9q4 0 25-26t29-38q12 2 17 2t17-2q28 40 51 63l4 1q2 0 69-39 2-2 2-4 0-14-28-77 9-13 16-29 83-8 83-17z" horiz-adv-x="1071.4" />
<glyph glyph-name="conf" unicode="&#xe840;" d="m571 350q0 59-41 101t-101 42-101-42-42-101 42-101 101-42 101 42 41 101z m286 61v-124q0-7-4-13t-11-7l-104-16q-10-30-21-51 19-27 59-77 6-6 6-13t-5-13q-15-21-55-61t-53-39q-7 0-14 5l-77 60q-25-13-51-21-9-76-16-104-4-16-20-16h-124q-8 0-14 5t-6 12l-16 103q-27 9-50 21l-79-60q-6-5-14-5-8 0-14 6-70 64-92 94-4 5-4 13 0 6 5 12 8 12 28 37t30 40q-15 28-23 55l-102 15q-7 1-11 7t-5 13v124q0 7 5 13t10 7l104 16q8 25 22 51-23 32-60 77-6 7-6 14 0 5 5 12 15 20 55 60t53 40q7 0 15-5l77-60q24 13 50 21 9 76 17 104 3 15 20 15h124q7 0 13-4t7-12l15-103q28-9 50-21l80 60q5 5 13 5 7 0 14-5 72-67 92-95 4-5 4-13 0-6-4-12-9-12-29-38t-30-39q14-28 23-55l102-15q7-1 12-7t4-13z" horiz-adv-x="857.1" />
<glyph glyph-name="services" unicode="&#xe83f;" d="m500 350q0 59-42 101t-101 42-101-42-42-101 42-101 101-42 101 42 42 101z m429-286q0 29-22 51t-50 21-50-21-21-51q0-29 21-50t50-21 51 21 21 50z m0 572q0 29-22 50t-50 21-50-21-21-50q0-30 21-51t50-21 51 21 21 51z m-215-235v-103q0-6-4-11t-9-6l-86-14q-6-19-18-42 19-27 50-64 4-6 4-11 0-7-4-11-13-17-46-50t-44-33q-6 0-11 4l-64 50q-21-11-43-17-6-60-13-87-4-13-17-13h-104q-6 0-11 4t-5 10l-13 85q-19 6-42 18l-66-50q-4-4-11-4-6 0-12 4-80 75-80 90 0 5 4 10 5 8 23 30t26 34q-13 24-20 46l-85 13q-5 1-9 5t-4 11v103q0 6 4 11t9 6l86 14q7 19 18 42-19 27-50 64-4 6-4 11 0 7 4 11 12 17 46 50t44 33q6 0 12-4l64-50q19 10 43 18 6 60 13 86 3 13 16 13h104q6 0 11-4t6-10l13-85q19-6 41-17l66 49q5 4 11 4 7 0 12-4 81-75 81-90 0-5-4-10-7-9-24-30t-25-34q13-27 19-46l85-12q5-2 9-6t4-11z m357-298v-78q0-9-83-17-6-15-16-29 28-63 28-77 0-2-2-4-68-40-69-40-5 0-26 27t-29 37q-11-1-17-1t-17 1q-7-11-29-37t-25-27q-1 0-69 40-3 2-3 4 0 14 29 77-10 14-17 29-83 8-83 17v78q0 9 83 18 7 16 17 29-29 63-29 77 0 2 3 4 2 1 19 11t33 19 17 9q4 0 25-26t29-38q12 1 17 1t17-1q28 40 51 63l4 1q2 0 69-39 2-2 2-4 0-14-28-77 9-13 16-29 83-9 83-18z m0 572v-78q0-9-83-18-6-15-16-29 28-63 28-77 0-2-2-4-68-39-69-39-5 0-26 26t-29 38q-11-1-17-1t-17 1q-7-12-29-38t-25-26q-1 0-69 39-3 2-3 4 0 14 29 77-10 14-17 29-83 9-83 18v78q0 9 83 17 7 16 17 29-29 63-29 77 0 2 3 4 2 1 19 11t33 19 17 9q4 0 25-26t29-38q12 2 17 2t17-2q28 40 51 63l4 1q2 0 69-39 2-2 2-4 0-14-28-77 9-13 16-29 83-8 83-17z" horiz-adv-x="1071.4" />
<glyph glyph-name="service" unicode="&#xe840;" d="m571 350q0 59-41 101t-101 42-101-42-42-101 42-101 101-42 101 42 41 101z m286 61v-124q0-7-4-13t-11-7l-104-16q-10-30-21-51 19-27 59-77 6-6 6-13t-5-13q-15-21-55-61t-53-39q-7 0-14 5l-77 60q-25-13-51-21-9-76-16-104-4-16-20-16h-124q-8 0-14 5t-6 12l-16 103q-27 9-50 21l-79-60q-6-5-14-5-8 0-14 6-70 64-92 94-4 5-4 13 0 6 5 12 8 12 28 37t30 40q-15 28-23 55l-102 15q-7 1-11 7t-5 13v124q0 7 5 13t10 7l104 16q8 25 22 51-23 32-60 77-6 7-6 14 0 5 5 12 15 20 55 60t53 40q7 0 15-5l77-60q24 13 50 21 9 76 17 104 3 15 20 15h124q7 0 13-4t7-12l15-103q28-9 50-21l80 60q5 5 13 5 7 0 14-5 72-67 92-95 4-5 4-13 0-6-4-12-9-12-29-38t-30-39q14-28 23-55l102-15q7-1 12-7t4-13z" horiz-adv-x="857.1" />
<glyph glyph-name="phone" unicode="&#xe841;" d="m786 158q0-15-6-39t-12-38q-11-28-68-60-52-28-103-28-16 0-30 2t-32 7-26 8-31 11-28 10q-54 20-97 47-72 44-148 120t-120 148q-27 43-46 97-2 5-10 28t-12 31-8 26-7 32-2 29q0 52 29 104 31 56 59 68 14 6 38 12t39 6q8 0 12-2 10-3 30-43 6-10 16-30t20-35 17-30q2-2 10-14t12-20 4-16q0-11-16-28t-35-30-34-30-16-25q0-5 3-13t4-11 8-14 7-10q42-77 97-132t131-97q1 0 10-6t14-8 11-5 13-2q10 0 25 15t30 35 31 35 28 16q7 0 15-4t20-12 14-10q14-8 30-17t35-20 31-17q39-19 42-29 2-4 2-12z" horiz-adv-x="785.7" />
<glyph glyph-name="file-pdf" unicode="&#xe842;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-287 331q18-14 47-31 33 4 65 4 82 0 99-27 9-13 1-29 0-1-1-1l-1-2v0q-3-21-39-21-27 0-65 11t-72 29q-123-13-219-46-85-146-135-146-8 0-15 4l-14 6q0 1-3 3-6 6-4 20 5 23 32 51t73 54q8 5 13-3 1-1 1-2 29 47 60 110 38 76 58 146-13 46-17 89t4 71q6 22 23 22h12q13 0 20-8 10-12 5-38-1-3-2-4 0-2 0-5v-17q-1-68-8-107 31-91 82-133z m-322-229q30 13 77 88-29-22-49-47t-28-41z m223 513q-9-23-2-73 1 4 4 24 0 2 4 24 1 3 3 5-1 0-1 1t0 1-1 1q0 12-7 20 0-1 0-1v-2z m-70-368q76 30 159 45-1 0-7 5t-9 8q-43 37-71 98-15-48-47-110-16-31-25-46z m361 8q-14 14-78 14 42-16 69-16 8 0 10 1 0 0-1 1z" horiz-adv-x="857.1" />
<glyph glyph-name="file-word" unicode="&#xe843;" d="m819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 16-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 15t-16 38v233h-429v-858h715z m-656 500v-59h39l92-369h88l72 271q4 11 5 25 1 9 1 14h3l1-14q1-1 2-11t3-14l72-271h89l91 369h39v59h-167v-59h50l-55-245q-3-11-4-25l-1-12h-3l-1 12q-1 2-2 11t-3 14l-81 304h-63l-81-304q-1-5-2-13t-2-12l-2-12h-2l-2 12q-1 14-4 25l-55 245h50v59h-167z" horiz-adv-x="857.1" />
@ -111,6 +111,17 @@
<glyph glyph-name="host" unicode="&#xe866;" d="m232 136q-37 0-63 26t-26 63v393q0 37 26 63t63 26h607q37 0 63-26t27-63v-393q0-37-27-63t-63-26h-607z m-18 482v-393q0-7 6-13t12-5h607q8 0 13 5t5 13v393q0 7-5 12t-13 6h-607q-7 0-12-6t-6-12z m768-518h89v-54q0-22-26-37t-63-16h-893q-36 0-63 16t-26 37v54h982z m-402-54q9 0 9 9t-9 9h-89q-9 0-9-9t9-9h89z" horiz-adv-x="1071.4" />
<glyph glyph-name="thumbs-up" unicode="&#xe867;" d="m143 100q0 15-11 25t-25 11-25-11-11-25 11-25 25-11 25 11 11 25z m643 321q0 29-22 50t-50 22h-196q0 32 27 89t26 89q0 55-17 81t-72 27q-14-15-21-48t-17-70-33-61q-13-13-43-51-2-3-13-17t-18-22-19-24-22-25-22-19-22-16-20-5h-18v-357h18q7 0 18-1t18-4 21-6 20-7 20-7 16-5q118-41 191-41h67q107 0 107 93 0 15-2 31 16 9 26 30t10 41-10 38q29 28 29 67 0 13-5 31t-14 26q18 1 30 26t12 45z m71 1q0-50-27-91 5-18 5-38 0-43-21-81 1-12 1-24 0-56-33-99 0-78-48-123t-126-45h-72q-54 0-106 13t-121 36q-65 23-77 23h-161q-29 0-50 21t-21 50v357q0 30 21 51t50 21h153q20 13 77 86 32 42 60 72 13 14 19 47t17 71 35 60q22 21 50 21 47 0 84-18t57-57 20-104q0-51-27-107h98q58 0 101-42t42-100z" horiz-adv-x="857.1" />
<glyph glyph-name="thumbs-down" unicode="&#xe868;" d="m143 600q0 15-11 25t-25 11-25-11-11-25 11-25 25-11 25 11 11 25z m643-321q0 19-12 45t-30 26q8 10 14 27t5 30q0 39-29 67 10 18 10 38t-10 41-26 30q2 16 2 31 0 47-27 70t-76 23h-71q-73 0-191-41-3-1-16-6t-20-7-20-6-21-6-18-4-18-1h-18v-358h18q9 0 20-5t22-15 22-19 22-25 19-24 18-23 13-16q30-38 43-51 23-24 33-61t17-70 21-48q54 0 72 27t17 81q0 32-26 89t-27 89h196q28 0 50 22t22 49z m71-1q0-57-42-100t-101-42h-98q27-55 27-107 0-66-20-104-19-39-57-57t-84-18q-28 0-50 21-19 18-30 45t-14 51-10 47-17 36q-27 28-60 71-57 73-77 86h-153q-29 0-50 21t-21 51v357q0 29 21 50t50 21h161q12 0 77 22 72 25 125 37t111 13h63q78 0 126-45t48-120v-3q33-43 33-99 0-13-1-24 21-38 21-81 0-20-5-38 27-41 27-91z" horiz-adv-x="857.1" />
<glyph glyph-name="spinner" unicode="&#xe869;" d="m277 100q0-33-24-57t-57-23q-33 0-56 23t-24 57 24 57 56 23q33 0 57-23t24-57z m241-107q0-30-21-51t-51-21-50 21-21 51 21 50 50 21 51-21 21-50z m-339 357q0-37-27-63t-63-26-63 26-26 63 26 63 63 26 63-26 27-63z m580-250q0-26-18-44t-45-18-44 18-18 44 18 44 44 19 45-19 18-44z m-464 500q0-41-29-69t-70-29-69 29-29 69 29 69 69 29 70-29 29-69z m259 107q0-45-32-76t-76-31-75 31-32 76 32 76 75 31 76-31 32-76z m303-357q0-22-15-38t-38-16-38 16-16 38 16 38 38 16 38-16 15-38z m-116 250q0-18-13-32t-32-13-31 13-13 32 13 31 31 14 32-14 13-31z" horiz-adv-x="875" />
<glyph glyph-name="attach" unicode="&#xe86a;" d="m783 77q0-65-44-109t-109-44q-75 0-131 55l-434 434q-63 64-63 151 0 88 62 150t150 62q88 0 152-63l338-338q5-5 5-12 0-9-17-26t-26-17q-7 0-13 5l-338 339q-44 43-101 43-59 0-100-42t-40-101q0-58 42-101l433-433q35-35 81-35 36 0 59 23t24 59q0 46-36 81l-324 324q-14 14-33 14-16 0-27-11t-11-27q0-18 14-33l229-228q6-6 6-13 0-9-18-26t-26-17q-7 0-12 5l-229 229q-35 34-35 83 0 46 32 78t77 32q49 0 83-36l325-324q55-54 55-131z" horiz-adv-x="785.7" />
<glyph glyph-name="keyboard" unicode="&#xe86b;" d="m214 198v-53q0-9-9-9h-53q-9 0-9 9v53q0 9 9 9h53q9 0 9-9z m72 143v-53q0-9-9-9h-125q-9 0-9 9v53q0 9 9 9h125q9 0 9-9z m-72 143v-54q0-9-9-9h-53q-9 0-9 9v54q0 9 9 9h53q9 0 9-9z m572-286v-53q0-9-9-9h-482q-9 0-9 9v53q0 9 9 9h482q9 0 9-9z m-357 143v-53q0-9-9-9h-54q-9 0-9 9v53q0 9 9 9h54q9 0 9-9z m-72 143v-54q0-9-9-9h-53q-9 0-9 9v54q0 9 9 9h53q9 0 9-9z m214-143v-53q0-9-8-9h-54q-9 0-9 9v53q0 9 9 9h54q8 0 8-9z m-71 143v-54q0-9-9-9h-53q-9 0-9 9v54q0 9 9 9h53q9 0 9-9z m214-143v-53q0-9-9-9h-53q-9 0-9 9v53q0 9 9 9h53q9 0 9-9z m215-143v-53q0-9-9-9h-54q-9 0-9 9v53q0 9 9 9h54q9 0 9-9z m-286 286v-54q0-9-9-9h-54q-9 0-9 9v54q0 9 9 9h54q9 0 9-9z m143 0v-54q0-9-9-9h-54q-9 0-9 9v54q0 9 9 9h54q9 0 9-9z m143 0v-196q0-9-9-9h-125q-9 0-9 9v53q0 9 9 9h62v134q0 9 9 9h54q9 0 9-9z m71-420v500h-929v-500h929z m71 500v-500q0-29-21-50t-50-21h-929q-29 0-50 21t-21 50v500q0 30 21 51t50 21h929q30 0 50-21t21-51z" horiz-adv-x="1071.4" />
<glyph glyph-name="menu" unicode="&#xe86c;" d="m857 100v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 25t25 11h785q15 0 26-11t10-25z m0 286v-72q0-14-10-25t-26-10h-785q-15 0-25 10t-11 25v72q0 14 11 25t25 10h785q15 0 26-10t10-25z m0 285v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 26t25 10h785q15 0 26-10t10-26z" horiz-adv-x="857.1" />
<glyph glyph-name="wifi" unicode="&#xe86d;" d="m571 0q-11 0-51 41t-41 52q0 18 35 30t57 13 58-13 35-30q0-11-41-52t-52-41z m151 151q-1 0-22 14t-57 28-72 14-71-14-57-28-22-14q-10 0-52 42t-43 52q0 7 6 13 44 43 109 67t130 25 130-25 110-67q5-6 5-13 0-10-42-52t-52-42z m152 152q-6 0-12 5-76 58-141 86t-150 27q-47 0-95-12t-83-29-63-35-44-30-18-12q-9 0-51 42t-42 52q0 7 6 12 73 74 178 115t212 40 212-40 179-115q6-5 6-12 0-10-42-52t-52-42z m152 151q-6 0-13 5-100 88-207 132t-235 45-234-45-207-132q-7-5-13-5-9 0-51 42t-43 52q0 7 6 13 104 104 248 161t294 56 295-56 248-161q5-6 5-13 0-10-42-52t-51-42z" horiz-adv-x="1142.9" />
<glyph glyph-name="moon" unicode="&#xe86e;" d="m704 123q-30-5-61-5-102 0-188 50t-137 137-50 188q0 107 58 199-112-33-183-128t-72-214q0-73 29-139t76-113 114-77 139-28q80 0 152 34t123 96z m114 47q-53-113-159-181t-230-68q-87 0-167 34t-136 92-92 137-34 166q0 85 32 163t87 135 132 92 161 38q25 1 34-22 10-23-8-40-48-43-73-101t-26-122q0-83 41-152t111-111 152-41q66 0 127 29 23 10 40-7 8-8 10-19t-2-22z" horiz-adv-x="857.1" />
<glyph glyph-name="chart-pie" unicode="&#xe86f;" d="m429 353l304-304q-59-61-138-94t-166-34q-117 0-216 58t-155 156-58 215 58 215 155 156 216 58v-426z m104-3h431q0-88-33-167t-94-138z m396 71h-429v429q117 0 215-57t156-156 58-216z" horiz-adv-x="1000" />
<glyph glyph-name="chart-area" unicode="&#xe870;" d="m1143-7v-72h-1143v858h71v-786h1072z m-214 571l142-500h-928v322l250 321 321-321z" horiz-adv-x="1142.9" />
<glyph glyph-name="chart-bar" unicode="&#xe871;" d="m357 350v-286h-143v286h143z m214 286v-572h-142v572h142z m572-643v-72h-1143v858h71v-786h1072z m-357 500v-429h-143v429h143z m214 214v-643h-143v643h143z" horiz-adv-x="1142.9" />
<glyph glyph-name="beaker" unicode="&#xe872;" d="m852 42q31-50 12-85t-78-36h-643q-59 0-79 36t12 85l281 442v223h-36q-14 0-25 11t-10 25 10 25 25 11h286q15 0 25-11t11-25-11-25-25-11h-36v-223z m-435 405l-151-240h397l-152 240-11 17v243h-71v-243z" horiz-adv-x="928.6" />
<glyph glyph-name="magic" unicode="&#xe873;" d="m664 526l164 163-60 60-164-164z m249 163q0-15-10-25l-717-718q-10-10-25-10t-25 10l-111 111q-10 10-10 25t10 25l718 718q10 10 25 10t25-10l110-111q10-10 10-25z m-753 106l54-16-54-17-17-55-17 55-55 17 55 16 17 55z m195-90l109-34-109-33-34-109-33 109-109 33 109 34 33 109z m519-267l55-17-55-16-17-55-17 55-54 16 54 17 17 55z m-357 357l54-16-54-17-17-55-17 55-54 17 54 16 17 55z" horiz-adv-x="928.6" />
</font>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

View File

@ -32,7 +32,7 @@ class LoginForm extends Form
array(
'required' => true,
'label' => t('Username'),
'placeholder' => t(''),
'placeholder' => t('Please enter your username...'),
'class' => false === isset($formData['username']) ? 'autofocus' : ''
)
);
@ -42,7 +42,7 @@ class LoginForm extends Form
array(
'required' => true,
'label' => t('Password'),
'placeholder' => t(''),
'placeholder' => t('...and your password'),
'class' => isset($formData['username']) ? 'autofocus' : ''
)
);

View File

@ -1,116 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Forms\Dashboard;
use Icinga\Application\Config;
use Icinga\Web\Widget\Dashboard;
use Icinga\Web\Form;
/**
* Form to add an url a dashboard pane
*/
class AddUrlForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_dashboard_addurl');
$this->setSubmitLabel(t('Add To Dashboard'));
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'url',
array(
'required' => true,
'label' => t('Url'),
'helptext' => t('The url being loaded in the dashlet')
)
);
$paneSelectionValues = $this->getDashboardPaneSelectionValues();
if (empty($paneSelectionValues) ||
((isset($formData['create_new_pane']) && $formData['create_new_pane'] != false) &&
(false === isset($formData['use_existing_dashboard']) || $formData['use_existing_dashboard'] != true))
) {
$this->addElement(
'text',
'pane',
array(
'required' => true,
'label' => t("The New Pane's Title"),
'style' => 'display: inline-block'
)
);
$this->addElement( // Prevent the button from being displayed again on validation errors
'hidden',
'create_new_pane',
array(
'value' => 1
)
);
if (false === empty($paneSelectionValues)) {
$this->addElement(
'submit',
'use_existing_dashboard',
array(
'ignore' => true,
'label' => t('Use An Existing Pane'),
'style' => 'display: inline-block'
)
);
}
} else {
$this->addElement(
'select',
'pane',
array(
'required' => true,
'label' => t('Pane'),
'style' => 'display: inline-block;',
'multiOptions' => $paneSelectionValues
)
);
$this->addElement(
'submit',
'create_new_pane',
array(
'ignore' => true,
'label' => t('Create A New Pane'),
'style' => 'display: inline-block'
)
);
}
$this->addElement(
'text',
'component',
array(
'required' => true,
'label' => t('Title'),
'helptext' => t('The title for the dashlet')
)
);
}
/**
* Return the names and titles of the available dashboard panes as key-value array
*
* @return array
*/
protected function getDashboardPaneSelectionValues()
{
$dashboard = new Dashboard();
$dashboard->readConfig(Config::app('dashboard/dashboard'));
return $dashboard->getPaneKeyTitleArray();
}
}

View File

@ -0,0 +1,193 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Forms\Dashboard;
use Icinga\Web\Widget\Dashboard;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Web\Widget\Dashboard\Component;
/**
* Form to add an url a dashboard pane
*/
class ComponentForm extends Form
{
/**
* @var Dashboard
*/
private $dashboard;
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_dashboard_addurl');
if (! $this->getSubmitLabel()) {
$this->setSubmitLabel(t('Add To Dashboard'));
}
}
/**
* Build AddUrl form elements
*
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$groupElements = array();
$panes = array();
if ($this->dashboard) {
$panes = $this->dashboard->getPaneKeyTitleArray();
}
$this->addElement(
'hidden',
'org_pane',
array(
'required' => false
)
);
$this->addElement(
'hidden',
'org_component',
array(
'required' => false
)
);
$this->addElement(
'text',
'url',
array(
'required' => true,
'label' => t('Url'),
'description' =>
t('Enter url being loaded in the dashlet. You can paste the full URL, including filters.')
)
);
$this->addElement(
'text',
'component',
array(
'required' => true,
'label' => t('Dashlet Title'),
'description' => t('Enter a title for the dashlet.')
)
);
if (empty($panes) ||
((isset($formData['create_new_pane']) && $formData['create_new_pane'] != false) &&
(false === isset($formData['use_existing_dashboard']) || $formData['use_existing_dashboard'] != true))
) {
$groupElements[] = $this->createElement(
'text',
'pane',
array(
'required' => true,
'label' => t("New Pane Title"),
'description' =>
t('Enter a title for the new pane.')
)
);
$groupElements[] = $this->createElement( // Prevent the button from being displayed again on validation errors
'hidden',
'create_new_pane',
array(
'value' => 1
)
);
if (false === empty($panes)) {
$buttonExistingPane = $this->createElement(
'submit',
'use_existing_dashboard',
array(
'ignore' => true,
'label' => t('Use An Existing Pane'),
'description' =>
t('Click on the button to add the dashlet to an existing pane on your dashboard.')
)
);
$buttonExistingPane->removeDecorator('Label');
$groupElements[] = $buttonExistingPane;
}
} else {
$groupElements[] = $this->createElement(
'select',
'pane',
array(
'required' => true,
'label' => t('Pane'),
'multiOptions' => $panes,
'description' =>
t('Select a pane you want to add the dashlet.')
)
);
$buttonNewPane = $this->createElement(
'submit',
'create_new_pane',
array(
'ignore' => true,
'label' => t('Create A New Pane'),
'description' =>
t('Click on the button if you want to add the dashlet to a new pane on the dashboard.')
)
);
$buttonNewPane->removeDecorator('Label');
$groupElements[] = $buttonNewPane;
}
$this->addDisplayGroup(
$groupElements,
'pane_group',
array(
'legend' => t('Pane'),
'description' => t(
'Decide if you want add the dashlet to an existing pane'
. ' or create a new pane. Have a look on the button below.'
),
'decorators' => array(
'FormElements',
array('HtmlTag', array('tag' => 'div', 'class' => 'control-group')),
array(
'Description',
array('tag' => 'span', 'class' => 'description', 'placement' => 'prepend')
),
'Fieldset'
)
)
);
}
/**
* @param \Icinga\Web\Widget\Dashboard $dashboard
*/
public function setDashboard(Dashboard $dashboard)
{
$this->dashboard = $dashboard;
}
/**
* @return \Icinga\Web\Widget\Dashboard
*/
public function getDashboard()
{
return $this->dashboard;
}
/**
* @param Component $component
*/
public function load(Component $component)
{
$this->populate(array(
'pane' => $component->getPane()->getName(),
'org_pane' => $component->getPane()->getName(),
'component' => $component->getTitle(),
'org_component' => $component->getTitle(),
'url' => $component->getUrl()
));
}
}

View File

@ -5,6 +5,7 @@
</div>
</div>
<div class="form" data-base-target="layout">
<h1>Welcome to Icinga Web 2</h1>
<?php
/* TODO: remove this as soon as notifications and forms are ready */
if (isset($this->errorInfo)): ?>

View File

@ -22,7 +22,7 @@
</td>
<td style="text-align: center">
<a href="<?= $this->href('config/removeresource', array('resource' => $name)); ?>">
<?= $this->icon('minus'); ?>
<?= $this->icon('cancel'); ?>
</a>
</td>
</tr>

View File

@ -3,10 +3,6 @@
</div>
<div class="content">
<h1><?= $this->escape($this->translate('This feature is deactivated at the moment.')); ?></h1>
<p>
<?=
$this->escape($this->translate('Please have a little patience, we are hard working on it, take a look at icingaweb2 issues.'));
?>
</p>
<h1><?= t('Add URL to Dashboard'); ?></h1>
<?= $this->form; ?>
</div>

View File

@ -0,0 +1,13 @@
<div class="content">
<h1><?= t('Could not persist dashboard'); ?></h1>
<p>
<?= t('Please copy the following dashboard snippet to '); ?>
<strong><?= $this->config->getFilename(); ?>;</strong>.
<br>
<?= t('Make sure that the webserver can write to this file.'); ?>
</p>
<pre><?= (string) $this->config->render(); ?></pre>
<hr>
<h2><?= t('Error details') ?></h2>
<p><?= $this->error->getMessage(); ?></p>
</div>

View File

@ -8,9 +8,11 @@
<?php else: ?>
<div class="content">
<h1><?= $this->escape($this->translate('Welcome to Icinga Web!')) ?></h1>
<p><?= sprintf(
$this->escape($this->translate('Currently there is no dashlet available. This might change once you enabled some of the available %s.')),
$this->qlink($this->translate('modules'), 'config/modules')
) ?></p>
<p>
<?= sprintf(
$this->escape($this->translate('Currently there is no dashlet available. This might change once you enabled some of the available %s.')),
$this->qlink($this->translate('modules'), 'config/modules')
) ?>
</p>
</div>
<?php endif ?>

View File

@ -0,0 +1,7 @@
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content">
<h1><?= t('Add Component To Dashboard'); ?></h1>
<?= $this->form; ?>
</div>

View File

@ -0,0 +1,14 @@
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content">
<h1><?= t('Remove Component From Dashboard'); ?></h1>
<p>
<?= $this->translate('Please confirm the removal'); ?>:
<?= $this->pane; ?>/<?= $this->component; ?>
</p>
<?= $this->form; ?>
</div>

View File

@ -0,0 +1,14 @@
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content">
<h1><?= t('Remove Pane'); ?></h1>
<p>
<?= $this->translate('Please confirm the removal of'); ?>:
<?= $this->pane; ?>
</p>
<?= $this->form; ?>
</div>

View File

@ -0,0 +1,62 @@
<?php
?>
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content">
<h1><?= t('Dashboard Settings'); ?></h1>
<table class="avp" data-base-target="_next">
<thead>
<tr>
<th>
<strong><?= t('Component Name') ?></strong>
</th>
<th>
<strong><?= t('Url') ?></strong>
</th>
</tr>
</thead>
<tbody>
<?php foreach ($this->dashboard->getPanes() as $pane): ?>
<tr style="background-color: #f1f1f1;">
<th colspan="2" style="text-align: left; padding: 0.5em;">
<?= $pane->getName(); ?>
</th>
<th>
<a href="<?= $this->href('dashboard/remove-pane', array('pane' => $pane->getName())); ?>">
<?= $this->icon('cancel'); ?>
</a>
</th>
</tr>
<?php $components = $pane->getComponents(); ?>
<?php if(empty($components)): ?>
<tr>
<td colspan="3">
<?= $this->translate('No compoments added to dashboard') ?>.
</td>
</tr>
<?php else: ?>
<?php foreach ($components as $component): ?>
<?php if ($component->getDisabled() === true) continue; ?>
<tr>
<td>
<a href="<?= $this->href('dashboard/update-component', array('pane' => $pane->getName(), 'component' => $component->getTitle())); ?>">
<?= $component->getTitle(); ?>
</a>
</td>
<td>
<a href="<?= $this->href($component->getUrl()); ?>"><?= $component->getUrl(); ?></a>
</td>
<td>
<a href="<?= $this->href('dashboard/remove-component', array('pane' => $pane->getName(), 'component' => $component->getTitle())); ?>">
<?= $this->icon('cancel'); ?>
</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
<?php endforeach; ?>
</tbody>
</table>
</div>

View File

@ -1,28 +0,0 @@
<br/>
<div class="alert alert-error">
<h4><i>{{WARNING_ICON}}</i>Saving Dashboard Failed</h4>
<br/>
<p>
Your dashboard couldn't be stored (error: "<?= $this->exceptionMessage; ?>"). This could have one or more
of the following reasons:
</p>
<ul>
<li>You don't have permissions to write to the dashboard file</li>
<li>Something went wrong while writing the file</li>
<li>There's an application error preventing you from persisting the configuration</li>
</ul>
</div>
<p>
Details can be seen in your application log (if you don't have access to this file, call your administrator in this case).
<br/>
In case you can access the configuration file (config/dashboard/dashboard.ini) by yourself, you can open it and
insert the config manually:
</p>
<p>
<pre>
<code>
<?= $this->escape($this->iniConfigurationString); ?>
</code>
</pre>
</p>

View File

@ -0,0 +1,8 @@
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content">
<h1><?= t('Edit Component'); ?></h1>
<?= $this->form; ?>
</div>

View File

@ -16,7 +16,7 @@
</td>
<td>
<a href="<?= $this->href('config/removeAuthenticationBackend', array('auth_backend' => $backendNames[$i])); ?>">
<?= $this->icon('minus', $this->translate('Remove')); ?>
<?= $this->icon('cancel', $this->translate('Remove')); ?>
</a>
</td>
<td>

View File

@ -231,4 +231,14 @@ class IniWriter extends Zend_Config_Writer_FileAbstract
return $combinations;
}
/**
* Getter for filename
*
* @return string
*/
public function getFilename()
{
return $this->_filename;
}
}

View File

@ -213,7 +213,7 @@ class Menu implements RecursiveIterator
));
$section = $this->add(t('System'), array(
'icon' => 'conf-alt',
'icon' => 'wrench',
'priority' => 200
));
$section->add(t('Configuration'), array(

View File

@ -11,6 +11,8 @@ use Icinga\Web\LessCompiler;
class StyleSheet
{
protected static $lessFiles = array(
'../application/fonts/fontello-ifont/css/ifont-embedded.css',
'css/vendor/tipsy.css',
'css/icinga/defaults.less',
'css/icinga/layout-colors.less',
'css/icinga/layout-structure.less',
@ -24,9 +26,7 @@ class StyleSheet
'css/icinga/pagination.less',
'css/icinga/monitoring-colors.less',
'css/icinga/selection-toolbar.less',
'css/icinga/login.less',
'../application/fonts/fontanello-ifont/css/ifont-embedded.css',
'css/vendor/tipsy.css'
'css/icinga/login.less'
);
public static function compileForPdf()

View File

@ -6,8 +6,13 @@ namespace Icinga\Web\Widget;
use Icinga\Application\Icinga;
use Icinga\Application\Config;
use Icinga\Data\ConfigObject;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\NotReadableError;
use Icinga\Exception\ProgrammingError;
use Icinga\Exception\SystemPermissionException;
use Icinga\File\Ini\IniWriter;
use Icinga\User;
use Icinga\Web\Widget\Dashboard\Pane;
use Icinga\Web\Widget\Dashboard\Component as DashboardComponent;
use Icinga\Web\Url;
@ -23,13 +28,6 @@ use Icinga\Web\Url;
*/
class Dashboard extends AbstractWidget
{
/**
* The configuration containing information about this dashboard
*
* @var Config;
*/
private $config;
/**
* An array containing all panes of this dashboard
*
@ -51,6 +49,11 @@ class Dashboard extends AbstractWidget
*/
private $tabParam = 'pane';
/**
* @var User
*/
private $user;
/**
* Set the given tab name as active.
*
@ -67,30 +70,136 @@ class Dashboard extends AbstractWidget
*
* @return self
*/
public static function load()
public function load()
{
/** @var $dashboard Dashboard */
$dashboard = new static('dashboard');
$manager = Icinga::app()->getModuleManager();
foreach ($manager->getLoadedModules() as $module) {
/** @var $module \Icinga\Application\Modules\Module */
$dashboard->mergePanes($module->getPaneItems());
$this->mergePanes($module->getPaneItems());
}
return $dashboard;
if ($this->user !== null) {
$this->loadUserDashboards();
}
return $this;
}
/**
* Create a writer object
*
* @return IniWriter
*/
public function createWriter()
{
$configFile = $this->getConfigFile();
$output = array();
foreach ($this->panes as $pane) {
if ($pane->isUserWidget() === true) {
$output[$pane->getName()] = $pane->toArray();
}
foreach ($pane->getComponents() as $component) {
if ($component->isUserWidget() === true) {
$output[$pane->getName() . '.' . $component->getTitle()] = $component->toArray();
}
}
}
$co = new ConfigObject($output);
$config = new Config($co);
return new IniWriter(array('config' => $config, 'filename' => $configFile));
}
/**
* Write user specific dashboards to disk
*/
public function write()
{
$this->createWriter()->write();
}
/**
* @return bool
*/
private function loadUserDashboards()
{
try {
$config = Config::fromIni($this->getConfigFile());
} catch (NotReadableError $e) {
return;
}
if (! count($config)) {
return false;
}
$panes = array();
$components = array();
foreach ($config as $key => $part) {
if (strpos($key, '.') === false) {
if ($this->hasPane($part->title)) {
$panes[$key] = $this->getPane($part->title);
} else {
$panes[$key] = new Pane($key);
$panes[$key]->setTitle($part->title);
}
$panes[$key]->setUserWidget();
if ((bool) $part->get('disabled', false) === true) {
$panes[$key]->setDisabled();
}
} else {
list($paneName, $componentName) = explode('.', $key, 2);
$part->pane = $paneName;
$part->component = $componentName;
$components[] = $part;
}
}
foreach ($components as $componentData) {
$pane = null;
if (array_key_exists($componentData->pane, $panes) === true) {
$pane = $panes[$componentData->pane];
} elseif (array_key_exists($componentData->pane, $this->panes) === true) {
$pane = $this->panes[$componentData->pane];
} else {
continue;
}
$component = new DashboardComponent(
$componentData->title,
$componentData->url,
$pane
);
if ((bool) $componentData->get('disabled', false) === true) {
$component->setDisabled(true);
}
$component->setUserWidget();
$pane->addComponent($component);
}
$this->mergePanes($panes);
return true;
}
/**
* Merge panes with existing panes
*
* @param array $panes
* @return $this
* @param array $panes
*
* @return $this
*/
public function mergePanes(array $panes)
{
/** @var $pane Pane */
foreach ($panes as $pane) {
if (array_key_exists($pane->getName(), $this->panes)) {
if ($pane->getDisabled()) {
if ($this->hasPane($pane->getTitle()) === true) {
$this->removePane($pane->getTitle());
}
continue;
}
if ($this->hasPane($pane->getTitle()) === true) {
/** @var $current Pane */
$current = $this->panes[$pane->getName()];
$current->addComponents($pane->getComponents());
@ -109,7 +218,7 @@ class Dashboard extends AbstractWidget
*/
public function getTabs()
{
$url = Url::fromRequest()->getUrlWithout($this->tabParam);
$url = Url::fromPath('dashboard')->getUrlWithout($this->tabParam);
if ($this->tabs === null) {
$this->tabs = new Tabs();
@ -137,20 +246,6 @@ class Dashboard extends AbstractWidget
return $this->panes;
}
/**
* Populate this dashboard via the given configuration file
*
* @param Config $config The configuration file to populate this dashboard with
*
* @return self
*/
public function readConfig(Config $config)
{
$this->config = $config;
$this->panes = array();
$this->loadConfigPanes();
return $this;
}
/**
* Creates a new empty pane with the given title
@ -168,34 +263,6 @@ class Dashboard extends AbstractWidget
return $this;
}
/**
* Update or adds a new component with the given url to a pane
*
* @TODO: Should only allow component objects to be added directly as soon as we store more information
*
* @param string $pane The pane to add the component to
* @param Component|string $component The component to add or the title of the newly created component
* @param string|null $url The url to use for the component
*
* @return self
*/
public function setComponentUrl($pane, $component, $url)
{
if ($component === null && strpos($pane, '.')) {
list($pane, $component) = preg_split('~\.~', $pane, 2);
}
if (!isset($this->panes[$pane])) {
$this->createPane($pane);
}
$pane = $this->getPane($pane);
if ($pane->hasComponent($component)) {
$pane->getComponent($component)->setUrl($url);
} else {
$pane->addComponent($component, $url);
}
return $this;
}
/**
* Checks if the current dashboard has any panes
*
@ -207,49 +274,14 @@ class Dashboard extends AbstractWidget
}
/**
* Check if this dashboard has a specific pane
* Check if a panel exist
*
* @param $pane string The name of the pane
* @return bool
* @param string $pane
* @return bool
*/
public function hasPane($pane)
{
return array_key_exists($pane, $this->panes);
}
/**
* Remove a component $component from the given pane
*
* @param string $pane The pane to remove the component from
* @param Component|string $component The component to remove or it's name
*
* @return self
*/
public function removeComponent($pane, $component)
{
if ($component === null && strpos($pane, '.')) {
list($pane, $component) = preg_split('~\.~', $pane, 2);
}
$pane = $this->getPane($pane);
if ($pane !== null) {
$pane->removeComponent($component);
}
return $this;
}
/**
* Return an array with pane name=>title format used for comboboxes
*
* @return array
*/
public function getPaneKeyTitleArray()
{
$list = array();
foreach ($this->panes as $name => $pane) {
$list[$name] = $pane->getTitle();
}
return $list;
return $pane && array_key_exists($pane, $this->panes);
}
/**
@ -265,6 +297,21 @@ class Dashboard extends AbstractWidget
return $this;
}
public function removePane($title)
{
if ($this->hasPane($title) === true) {
$pane = $this->getPane($title);
if ($pane->isUserWidget() === true) {
unset($this->panes[$pane->getName()]);
} else {
$pane->setDisabled();
$pane->setUserWidget();
}
} else {
throw new ProgrammingError('Pane not found: ' . $title);
}
}
/**
* Return the pane with the provided name
*
@ -284,6 +331,20 @@ class Dashboard extends AbstractWidget
return $this->panes[$name];
}
/**
* Return an array with pane name=>title format used for comboboxes
*
* @return array
*/
public function getPaneKeyTitleArray()
{
$list = array();
foreach ($this->panes as $name => $pane) {
$list[$name] = $pane->getTitle();
}
return $list;
}
/**
* @see Icinga\Web\Widget::render
*/
@ -292,6 +353,7 @@ class Dashboard extends AbstractWidget
if (empty($this->panes)) {
return '';
}
return $this->determineActivePane()->render();
}
@ -319,7 +381,10 @@ class Dashboard extends AbstractWidget
/**
* Determine the active pane either by the selected tab or the current request
*
* @return Pane The currently active pane
* @throws \Icinga\Exception\ConfigurationError
* @throws \Icinga\Exception\ProgrammingError
*
* @return Pane The currently active pane
*/
public function determineActivePane()
{
@ -346,34 +411,55 @@ class Dashboard extends AbstractWidget
}
/**
* Return this dashboard's structure as array
* Setter for user object
*
* @return array
* @param User $user
*/
public function toArray()
public function setUser(User $user)
{
$array = array();
foreach ($this->panes as $pane) {
$array += $pane->toArray();
}
return $array;
$this->user = $user;
}
/**
* Load all config panes from @see Dashboard::$config
* Getter for user object
*
* @return User
*/
private function loadConfigPanes()
public function getUser()
{
foreach ($this->config as $key => $item) {
if (false === strstr($key, '.')) {
$this->addPane(Pane::fromIni($key, $item));
} else {
list($paneName, $title) = explode('.', $key, 2);
$pane = $this->getPane($paneName);
$pane->addComponent(DashboardComponent::fromIni($title, $item, $pane));
return $this->user;
}
/**
* Get config file
*
* @return string
*/
public function getConfigFile()
{
if ($this->user === null) {
return '';
}
$baseDir = '/var/lib/icingaweb';
if (! file_exists($baseDir)) {
throw new NotReadableError('Could not read: ' . $baseDir);
}
$userDir = $baseDir . '/' . $this->user->getUsername();
if (! file_exists($userDir)) {
$success = @mkdir($userDir);
if (!$success) {
throw new SystemPermissionException('Could not create: ' . $userDir);
}
}
if (! file_exists($userDir)) {
throw new NotReadableError('Could not read: ' . $userDir);
}
return $userDir . '/dashboard.ini';
}
}

View File

@ -17,7 +17,7 @@ use Icinga\Exception\IcingaException;
* This is the element displaying a specific view in icinga2web
*
*/
class Component extends AbstractWidget
class Component extends UserWidget
{
/**
* The url of this Component
@ -53,7 +53,7 @@ class Component extends AbstractWidget
private $template =<<<'EOD'
<div class="container" data-icinga-url="{URL}">
<h1>{REMOVE}<a href="{FULL_URL}" data-base-target="col1">{TITLE}</a></h1>
<h1><a href="{FULL_URL}" data-base-target="col1">{TITLE}</a></h1>
<noscript>
<iframe src="{IFRAME_URL}" style="height:100%; width:99%" frameborder="no"></iframe>
</noscript>
@ -93,6 +93,14 @@ EOD;
return $this->title;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* Retrieve the components url
*
@ -147,7 +155,13 @@ EOD;
*/
public function toArray()
{
$array = array('url' => $this->url->getPath());
$array = array(
'url' => $this->url->getPath(),
'title' => $this->getTitle()
);
if ($this->getDisabled() === true) {
$array['disabled'] = 1;
}
foreach ($this->url->getParams()->toArray() as $param) {
$array[$param[0]] = $param[1];
}
@ -169,13 +183,23 @@ EOD;
$iframeUrl = clone($url);
$iframeUrl->setParam('isIframe');
$html = str_replace('{URL}', $url, $this->template);
$html = str_replace('{IFRAME_URL}', $iframeUrl, $html);
$html = str_replace('{FULL_URL}', $url->getUrlWithout(array('view', 'limit')), $html);
$html = str_replace('{REMOVE_BTN}', $this->getRemoveForm($view), $html);
$html = str_replace('{TITLE}', $view->escape($this->getTitle()), $html);
$html = str_replace('{REMOVE}', $this->getRemoveForm(), $html);
return $html;
$searchTokens = array(
'{URL}',
'{IFRAME_URL}',
'{FULL_URL}',
'{TITLE}',
'{REMOVE}'
);
$replaceTokens = array(
$url,
$iframeUrl,
$url->getUrlWithout(array('view', 'limit')),
$view->escape($this->getTitle()),
$this->getRemoveLink()
);
return str_replace($searchTokens, $replaceTokens, $this->template);
}
/**
@ -183,32 +207,16 @@ EOD;
*
* @return string The html representation of the form
*/
protected function getRemoveForm()
protected function getRemoveLink()
{
// TODO: temporarily disabled, should point to a form asking for confirmal
return '';
$removeUrl = Url::fromPath(
'/dashboard/removecomponent',
array(
'pane' => $this->pane->getName(),
'component' => $this->getTitle()
)
return sprintf(
'<a data-base-target="main" href="%s">%s</a>',
Url::fromPath('dashboard/remove-component', array(
'component' => $this->getTitle(),
'pane' => $this->pane->getTitle()
)),
t('Remove')
);
$form = new Form();
$form->setMethod('POST');
$form->setAttrib('class', 'inline');
$form->setAction($removeUrl);
$form->addElement(
new Zend_Form_Element_Button(
'remove_pane_btn',
array(
'class'=> 'link-like pull-right',
'type' => 'submit',
'label' => 'x'
)
)
);
return $form;
}
/**
@ -231,4 +239,20 @@ EOD;
$cmp = new Component($title, Url::fromPath($url, $parameters), $pane);
return $cmp;
}
/**
* @param \Icinga\Web\Widget\Dashboard\Pane $pane
*/
public function setPane(Panel $pane)
{
$this->pane = $pane;
}
/**
* @return \Icinga\Web\Widget\Dashboard\Pane
*/
public function getPane()
{
return $this->pane;
}
}

View File

@ -12,7 +12,7 @@ use Icinga\Exception\ConfigurationError;
/**
* A pane, displaying different Dashboard components
*/
class Pane extends AbstractWidget
class Pane extends UserWidget
{
/**
* The name of this pane, as defined in the ini file
@ -36,6 +36,13 @@ class Pane extends AbstractWidget
*/
private $components = array();
/**
* Disabled flag of a pane
*
* @var bool
*/
private $disabled;
/**
* Create a new pane
*
@ -130,7 +137,15 @@ class Pane extends AbstractWidget
public function removeComponent($title)
{
if ($this->hasComponent($title)) {
unset($this->components[$title]);
$component = $this->getComponent($title);
if ($component->isUserWidget() === true) {
unset($this->components[$title]);
} else {
$component->setDisabled(true);
$component->setUserWidget();
}
} else {
throw new ProgrammingError('Component does not exist: ' . $title);
}
return $this;
}
@ -168,7 +183,13 @@ class Pane extends AbstractWidget
*/
public function render()
{
return implode("\n", $this->components) . "\n";
$components = array_filter(
$this->components,
function ($e) {
return ! $e->getDisabled();
}
);
return implode("\n", $components) . "\n";
}
/**
@ -241,12 +262,15 @@ class Pane extends AbstractWidget
*/
public function toArray()
{
$array = array($this->getName() => array('title' => $this->getTitle()));
foreach ($this->components as $title => $component) {
$array[$this->getName() . ".$title"] = $component->toArray();
$pane = array(
'title' => $this->getTitle(),
);
if ($this->getDisabled() === true) {
$pane['disabled'] = 1;
}
return $array;
return $pane;
}
/**
@ -265,4 +289,26 @@ class Pane extends AbstractWidget
}
return $pane;
}
/**
* Setter for disabled
*
* @param boolean $disabled
*/
public function setDisabled($disabled = true)
{
$this->disabled = (bool) $disabled;
}
/**
* Getter for disabled
*
* @return boolean
*/
public function getDisabled()
{
return $this->disabled;
}
}

View File

@ -0,0 +1,37 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Web\Widget\Dashboard;
use Icinga\Web\Widget\AbstractWidget;
abstract class UserWidget extends AbstractWidget
{
/**
* Flag if widget is created by an user
*
* @var bool
*/
protected $userWidget = false;
/**
* Set the user widget flag
*
* @param boolean $userWidget
*/
public function setUserWidget($userWidget = true)
{
$this->userWidget = (bool) $userWidget;
}
/**
* Getter for user widget flag
*
* @return boolean
*/
public function isUserWidget()
{
return $this->userWidget;
}
}

View File

@ -218,7 +218,12 @@ class FilterEditor extends AbstractWidget
if ($strip) {
$redirect = $this->url();
$filter->replaceById($strip, $filter->getById($strip . '-1'));
$subId = $strip . '-1';
if ($filter->getId() === $strip) {
$filter = $filter->getById($strip . '-1');
} else {
$filter->replaceById($strip, $filter->getById($strip . '-1'));
}
$redirect->setQueryString($filter->toQueryString())->getParams()->add('modifyFilter');
$this->redirectNow($redirect->addParams($preserve));
}
@ -341,7 +346,7 @@ class FilterEditor extends AbstractWidget
protected function renderFilter($filter, $level = 0)
{
if ($level === 0 && $filter->isChain() && $filter->isEmpty()) {
return '<ul class="datafilter"><li style="background-color: #ffb">' . $this->renderNewFilter() . '</li></ul>';
return '<ul class="datafilter"><li class="active">' . $this->renderNewFilter() . '</li></ul>';
}
if ($filter instanceof FilterChain) {
@ -398,7 +403,7 @@ class FilterEditor extends AbstractWidget
. $this->text($filter)
. $this->removeLink($filter)
. $this->addLink($filter)
. '</li><li style="background-color: #ffb">'
. '</li><li class="active">'
. $this->renderNewFilter() .$this->cancelLink()
. '</li></ul>'
;
@ -585,7 +590,7 @@ class FilterEditor extends AbstractWidget
} else {
$parent = $filter->getById($addTo);
$f = Filter::expression($add['column'], $add['sign'], $add['value']);
if ($add['operator']) {
if (isset($add['operator'])) {
switch($add['operator']) {
case 'AND':
if ($parent->isExpression()) {
@ -665,7 +670,7 @@ class FilterEditor extends AbstractWidget
. '<form action="'
. Url::fromRequest()
. '" class="filterEditor" method="POST">'
. '<ul class="tree"><li>'
. '<ul class="tree widgetFilter"><li>'
. $this->renderFilter($this->filter)
. '</li></ul>'
. '<div style="float: right">'

View File

@ -26,7 +26,7 @@ class DashboardAction implements Tabextension
array(
'icon' => 'dashboard',
'title' => 'Add To Dashboard',
'url' => Url::fromPath('dashboard/addurl'),
'url' => Url::fromPath('dashboard/new-component'),
'urlParams' => array(
'url' => rawurlencode(Url::fromRequest()->getRelativeUrl())
)

View File

@ -0,0 +1,40 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Web\Widget\Tabextension;
use Icinga\Web\Url;
use Icinga\Web\Widget\Tabs;
/**
* Dashboard settings
*/
class DashboardSettings implements Tabextension
{
/**
* Apply this tabextension to the provided tabs
*
* @param Tabs $tabs The tabbar to modify
*/
public function apply(Tabs $tabs)
{
$tabs->addAsDropdown(
'dashboard_add',
array(
'icon' => 'img/icons/dashboard.png',
'title' => t('Add To Dashboard'),
'url' => Url::fromPath('dashboard/new-component')
)
);
$tabs->addAsDropdown(
'dashboard_settings',
array(
'icon' => 'img/icons/dashboard.png',
'title' => t('Settings'),
'url' => Url::fromPath('dashboard/settings')
)
);
}
}

View File

@ -6,16 +6,32 @@ use Icinga\Web\Widget;
class Doc_StyleController extends Controller
{
public function guideAction()
{
$this->view->tabs = $this->tabs()->activate('guide');
}
public function fontAction()
{
$this->view->tabs = Widget::create('tabs')->add(
$this->view->tabs = $this->tabs()->activate('font');
$confFile = Icinga::app()->getApplicationDir('fonts/fontello-ifont/config.json');
$this->view->font = json_decode(file_get_contents($confFile));
}
protected function tabs()
{
return Widget::create('tabs')->add(
'guide',
array(
'title' => $this->translate('Style Guide'),
'url' => 'doc/style/guide'
)
)->add(
'fonts',
array(
'title' => $this->translate('Icons'),
'url' => 'doc/style/font'
)
)->activate('fonts');
$confFile = Icinga::app()->getApplicationDir('fonts/fontanello-ifont/config.json');
$this->view->font = json_decode(file_get_contents($confFile));
);
}
}

View File

@ -0,0 +1,13 @@
<div class="controls">
<?= $this->tabs ?>
<h1>Style Guide</h1>
</div>
<div class="content">
<h1>H1 - header</h1>
<h2>H2 - header</h2>
<h3>H3 - header</h3>
<h4>H4 - header</h4>
<h5>H5 - header</h5>
<h6>H6 - header</h6>
</div>

View File

@ -18,6 +18,6 @@ $section->add('Module documentations', array(
'url' => 'doc/module',
));
$section->add($this->translate('Developer - Style'), array(
'url' => 'doc/style/font',
'url' => 'doc/style/guide',
'priority' => 200,
));

View File

@ -1,11 +1,3 @@
// W3C Recommendation <http://www.w3.org/TR/CSS21/sample.html> (except h4)
h1 { font-size: 2em !important; }
h2 { font-size: 1.5em !important; }
h3 { font-size: 1.17em !important; }
h4 { font-size: 1em !important; }
h5 { font-size: .83em !important; }
h6 { font-size: .75em !important; }
div.chapter {
padding-left: 5px;
}

View File

@ -64,7 +64,7 @@ class Monitoring_AlertsummaryController extends Controller
*/
public function indexAction()
{
$this->addTitleTab('alertsummary');
$this->addTitleTab('alertsummary', t('Alert Summary'));
$this->view->intervalBox = $this->createIntervalBox();
$this->view->recentAlerts = $this->createRecentAlerts();
$this->view->interval = $this->getInterval();
@ -433,7 +433,7 @@ class Monitoring_AlertsummaryController extends Controller
$gridChart->drawBars(
array(
'label' => $this->translate('Notifications'),
'color' => 'blue',
'color' => '#049baf',
'data' => $notifications,
'showPoints' => true
)
@ -442,7 +442,7 @@ class Monitoring_AlertsummaryController extends Controller
$gridChart->drawLines(
array(
'label' => $this->translate('Avg (min)'),
'color' => 'orange',
'color' => '#ffaa44',
'data' => $dAvg,
'showPoints' => true
)
@ -451,7 +451,7 @@ class Monitoring_AlertsummaryController extends Controller
$gridChart->drawLines(
array(
'label' => $this->translate('Max (min)'),
'color' => 'red',
'color' => '#ff5566',
'data' => $dMax,
'showPoints' => true
)
@ -478,7 +478,7 @@ class Monitoring_AlertsummaryController extends Controller
$gridChart->drawBars(
array(
'label' => $this->translate('Notifications'),
'color' => 'green',
'color' => '#049baf',
'data' => $this->notificationData,
'showPoints' => true
)
@ -487,7 +487,7 @@ class Monitoring_AlertsummaryController extends Controller
$gridChart->drawLines(
array(
'label' => $this->translate('Defects'),
'color' => 'red',
'color' => '#ff5566',
'data' => $this->problemData,
'showPoints' => true
)

View File

@ -396,7 +396,8 @@ class Monitoring_ListController extends Controller
array('day', $form->getValue('state'))
);
$this->params->remove(array('objecttype', 'from', 'to', 'state', 'btn_submit'));
$this->filterQuery($query);
$this->view->filter = Filter::fromQuerystring((string) $this->params);
$query->applyFilter($this->view->filter);
$this->view->summary = $query->getQuery()->fetchAll();
$this->view->column = $form->getValue('state');
// $this->view->orientationBox = $orientationBox;
@ -490,7 +491,16 @@ class Monitoring_ListController extends Controller
'services_critical_unhandled',
'services_warning_handled',
'services_warning_unhandled',
'services_pending'
'services_pending',
'services_ok_last_state_change',
'services_pending_last_state_change',
'services_warning_last_state_change_handled',
'services_critical_last_state_change_handled',
'services_unknown_last_state_change_handled',
'services_warning_last_state_change_unhandled',
'services_critical_last_state_change_unhandled',
'services_unknown_last_state_change_unhandled',
'services_total'
));
$this->filterQuery($query);
$this->view->servicegroups = $query->paginate();
@ -521,7 +531,16 @@ class Monitoring_ListController extends Controller
'services_critical_unhandled',
'services_warning_handled',
'services_warning_unhandled',
'services_pending'
'services_pending',
'services_ok_last_state_change',
'services_pending_last_state_change',
'services_warning_last_state_change_handled',
'services_critical_last_state_change_handled',
'services_unknown_last_state_change_handled',
'services_warning_last_state_change_unhandled',
'services_critical_last_state_change_unhandled',
'services_unknown_last_state_change_unhandled',
'services_total'
));
$this->filterQuery($query);
$this->view->hostgroups = $query->paginate();
@ -537,6 +556,24 @@ class Monitoring_ListController extends Controller
}
$this->addTitleTab('eventhistory', $this->translate('Event Overview'));
$form = new EventOverviewForm();
$form->handleRequest($this->getRequest());
$this->view->form = $form;
if ($this->getRequest()->isPost() && !$this->getParam('modifyFilter')) {
// update filter string
$filters = $form->getFilter();
$url = $this->_request->getUrl();
$url->setQueryString($filters->toQueryString());
if ($this->getParam('sort') !== null) {
$url->setParam('sort', $this->getParam('sort'));
}
if ($this->getParam('dir') !== null) {
$url->setParam('dir', $this->getParam('dir'));
}
return $this->redirectNow($url);
}
$query = $this->backend->select()->from('eventHistory', array(
'host_name',
'service_description',
@ -550,6 +587,9 @@ class Monitoring_ListController extends Controller
'host',
'service'
));
if ($this->getParam('state')) {
$query->applyFilter(Filter::expression('state', '=', $this->getParam('state')));
}
$this->setupSortControl(array(
'timestamp' => 'Occurence'
@ -587,8 +627,8 @@ class Monitoring_ListController extends Controller
{
$editor = Widget::create('filterEditor')
->setQuery($query)
->preserveParams('limit', 'sort', 'dir', 'format', 'view', 'backend')
->ignoreParams('page', 'objecttype', 'from', 'to', 'state', 'btn_submit')
->preserveParams('limit', 'sort', 'dir', 'format', 'view', 'backend', 'renderLayout', 'stateType', 'addColumns')
->ignoreParams('page', 'objecttype', 'from', 'to', 'btn_submit')
->handleRequest($this->getRequest());
$query->applyFilter($editor->getFilter());

View File

@ -23,16 +23,9 @@ class Monitoring_ProcessController extends Controller
->add(
'info',
array(
'title' => $this->translate('Process Info'),
'title' => $this->translate('Monitoring Health'),
'url' =>'monitoring/process/info'
)
)
->add(
'performance',
array(
'title' => $this->translate('Performance Info'),
'url' => 'monitoring/process/performance'
)
);
}
@ -41,7 +34,7 @@ class Monitoring_ProcessController extends Controller
*/
public function infoAction()
{
$this->view->title = $this->translate('Process Info');
$this->view->title = $this->translate('Monitoring Health');
$this->getTabs()->activate('info');
$this->setAutorefreshInterval(10);
$this->view->backendName = $this->backend->getName();
@ -80,6 +73,14 @@ class Monitoring_ProcessController extends Controller
->load($programStatus)
->handleRequest();
$this->view->toggleFeaturesForm = $toggleFeaturesForm;
$this->view->runtimevariables = (object) $this->backend->select()
->from('runtimevariables', array('varname', 'varvalue'))
->getQuery()->fetchPairs();
$this->view->checkperformance = $this->backend->select()
->from('runtimesummary')
->getQuery()->fetchAll();
}
/**
@ -111,6 +112,9 @@ class Monitoring_ProcessController extends Controller
}
}
/**
* @todo should be dropped later
*/
public function performanceAction()
{
$this->getTabs()->activate('performance');

View File

@ -222,7 +222,7 @@ class Monitoring_ShowController extends Controller
'services',
array(
'title' => 'Services',
'icon' => 'service',
'icon' => 'services',
'url' => 'monitoring/show/services',
'urlParams' => $params,
)

View File

@ -28,8 +28,6 @@ class CheckNowCommandForm extends ObjectsCommandForm
*/
public function addSubmitButton()
{
$iconUrl = $this->getView()->href('img/icons/refresh_petrol.png');
$this->addElements(array(
array(
'button',
@ -38,7 +36,7 @@ class CheckNowCommandForm extends ObjectsCommandForm
'ignore' => true,
'type' => 'submit',
'value' => mt('monitoring', 'Check now'),
'label' => '<img src="' . $iconUrl . '"> ' . mt('monitoring', 'Check now'),
'label' => '<i class="icon-reschedule"></i> ' . mt('monitoring', 'Check now'),
'decorators' => array('ViewHelper'),
'escape' => false,
'class' => 'link-like'

View File

@ -237,18 +237,28 @@ class BackendConfigForm extends ConfigForm
)
);
$resourceName = (isset($formData['resource'])) ? $formData['resource'] : $this->getValue('resource');
if ($resourceElement) {
$resourceElement->getDecorator('Description')->setEscape(false);
$link = sprintf(
'<a href="%s" data-base-target="_main">%s</a>',
$this->getView()->href('/icingaweb/config/editresource', array('resource' => $resourceName)),
mt('monitoring', 'Show resource configuration')
);
$resourceElement->setDescription($resourceElement->getDescription() . ' (' . $link . ')');
if (empty($formData)) {
$options = $resourceElement->options;
$resourceName = array_shift($options);
} else {
$resourceName = (isset($formData['resource'])) ? $formData['resource'] : $this->getValue('resource');
}
$this->addElement($resourceElement);
if ($resourceElement) {
$this->addElement(
'note',
'resource_note',
array(
'value' => sprintf(
'<a href="%s" data-base-target="_main">%s</a>',
$this->getView()->href('/icingaweb/config/editresource', array('resource' => $resourceName)),
mt('monitoring', 'Show resource configuration')
),
'escape' => false
)
);
}
}
}

View File

@ -0,0 +1,160 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Monitoring\Forms;
use Icinga\Data\Filter\FilterNot;
use Icinga\Web\Url;
use \Zend_Form;
use Icinga\Web\Form;
use Icinga\Data\Filter\Filter;
/**
* Configure the filter for the event overview
*/
class EventOverviewForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_event_overview');
$this->setDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'div', 'class' => 'hbox')),
'Form'
));
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$decorators = array(
array('Label', array('class' => 'optional')),
'ViewHelper',
array('HtmlTag', array('tag' => 'div', 'class' => 'hbox-item optionbox')),
);
$url = Url::fromRequest()->getAbsoluteUrl();
$this->addElement(
'checkbox',
'statechange',
array(
'label' => t('State Changes'),
'class' => 'autosubmit',
'decorators' => $decorators,
'value' => strpos($url, $this->stateChangeFilter()->toQueryString()) === false ? 0 : 1
)
);
$this->addElement(
'checkbox',
'downtime',
array(
'label' => t('Downtimes'),
'class' => 'autosubmit',
'decorators' => $decorators,
'value' => strpos($url, $this->downtimeFilter()->toQueryString()) === false ? 0 : 1
)
);
$this->addElement(
'checkbox',
'comment',
array(
'label' => t('Comments'),
'class' => 'autosubmit',
'decorators' => $decorators,
'value' => strpos($url, $this->commentFilter()->toQueryString()) === false ? 0 : 1
)
);
$this->addElement(
'checkbox',
'notification',
array(
'label' => t('Notifications'),
'class' => 'autosubmit',
'decorators' => $decorators,
'value' => strpos($url, $this->notificationFilter()->toQueryString()) === false ? 0 : 1
)
);
$this->addElement(
'checkbox',
'flapping',
array(
'label' => t('Flapping'),
'class' => 'autosubmit',
'decorators' => $decorators,
'value' => strpos($url, $this->flappingFilter()->toQueryString()) === false ? 0 : 1
)
);
}
/**
* Return the corresponding filter-object
*
* @returns Filter
*/
public function getFilter()
{
$filters = array();
if ($this->getValue('statechange', 1)) {
$filters[] = $this->stateChangeFilter();
}
if ($this->getValue('comment', 1)) {
$filters[] = $this->commentFilter();
}
if ($this->getValue('notification', 1)) {
$filters[] = $this->notificationFilter();
}
if ($this->getValue('downtime', 1)) {
$filters[] = $this->downtimeFilter();
}
if ($this->getValue('flapping', 1)) {
$filters[] = $this->flappingFilter();
}
return Filter::matchAny($filters);
}
public function stateChangeFilter()
{
return Filter::matchAny(
Filter::expression('type', '=', 'hard_state'),
Filter::expression('type', '=', 'soft_state')
);
}
public function commentFilter()
{
return Filter::matchAny(
Filter::expression('type', '=', 'comment'),
Filter::expression('type', '=', 'comment_deleted'),
Filter::expression('type', '=', 'dt_comment'),
Filter::expression('type', '=', 'dt_comment_deleted'),
Filter::expression('type', '=', 'ack')
);
}
public function notificationFilter()
{
return Filter::expression('type', '=', 'notify');
}
public function downtimeFilter()
{
return Filter::matchAny(
Filter::expression('type', '=', 'downtime_start'),
Filter::expression('type', '=', 'downtime_end')
);
}
public function flappingFilter()
{
return Filter::matchAny(
Filter::expression('type', '=', 'flapping'),
Filter::expression('type', '=', 'flapping_deleted')
);
}
}

View File

@ -11,19 +11,19 @@ $helper = $this->getHelper('MonitoringState');
</div>
<div class="content alertsummary">
<h1><?= $this->translate('Alert summary'); ?></h1>
<!-- <h1><?= $this->translate('Alert summary'); ?></h1> -->
<div class="alertsummary-flex-container">
<div class="alertsummary-flex">
<h2><?= $this->translate('Notifications and problems'); ?></h2>
<div>
<div class="hbox">
<div class="hbox-item">
<h2><?= $this->translate('Notifications and Problems'); ?></h2>
<div style="width: 400px; height: 400px;">
<?= $defectChart->render(); ?>
</div>
</div>
<div class="alertsummary-flex">
<h2><?= $this->translate('Time to reaction (Ack, Recover)'); ?></h2>
<div>
<div class="hbox-item">
<h2><?= $this->translate('Time to Reaction (Ack, Recover)'); ?></h2>
<div style="width: 400px; height: 400px;">
<?= $healingChart->render(); ?>
</div>
</div>
@ -56,7 +56,7 @@ $helper = $this->getHelper('MonitoringState');
</div>
<?php if ($this->recentAlerts): ?>
<h2><?= $this->translate('Top 5 recent alerts'); ?></h2>
<h1><?= $this->translate('Top 5 Recent Alerts'); ?></h1>
<div class="alertsummary-flex-container">
<div class="alertsummary-flex">
@ -69,7 +69,7 @@ $helper = $this->getHelper('MonitoringState');
</div>
<?php endif; ?>
<h2><?= $this->translate('History'); ?></h2>
<h1><?= $this->translate('History'); ?></h1>
<div class="alertsummary-flex-container">
<div class="alertsummary-flex">
<?= $this->partial('list/notifications.phtml', array(

View File

@ -7,7 +7,7 @@
<thead>
<tr>
<th><?= $this->icon('host') ?> Host</th>
<th><?= $this->icon('service') ?> Service</th>
<th><?= $this->icon('conf') ?> Service</th>
</tr>
</thead>
<tbody>

View File

@ -28,7 +28,7 @@
</td>
<td>
<a href="<?= $this->href('/monitoring/config/removebackend', array('backend' => $backendName)); ?>">
<?= $this->icon('minus'); ?>
<?= $this->icon('cancel'); ?>
</a>
</td>
</tr>
@ -60,7 +60,7 @@
</td>
<td>
<a href="<?= $this->href('/monitoring/config/removeinstance', array('instance' => $instanceName)); ?>">
<?= $this->icon('minus'); ?>
<?= $this->icon('cancel'); ?>
</a>
</td>
</tr>

View File

@ -50,7 +50,7 @@
</td>
<td>
<?php if ($comment->objecttype === 'service'): ?>
<?= $this->icon('service'); ?> <a href="<?= $this->href('monitoring/service/show', array(
<?= $this->icon('conf'); ?> <a href="<?= $this->href('monitoring/service/show', array(
'host' => $comment->host,
'service' => $comment->service,
)); ?>">

View File

@ -6,9 +6,9 @@ $selfUrl = 'monitoring/list/hosts';
$currentUrl = Url::fromRequest()->getRelativeUrl();
?>
<h3 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : '' ?>>
<h1 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : '' ?>>
<?= $this->qlink(sprintf($this->translate('%s hosts:'), $this->stats->hosts_total), $selfUrl); ?>
<span class="badges">
<?php if($this->stats->hosts_up): ?>
<span class="state ok<?= $currentUrl === Url::fromPath($selfUrl, array('host_state' => 0))->getRelativeUrl() ? ' active' : '' ?>">
<?= $this->qlink(
@ -80,4 +80,5 @@ $currentUrl = Url::fromRequest()->getRelativeUrl();
) ?>
</span>
<?php endif; ?>
</h3>
</span>
</h1>

View File

@ -1,6 +1,6 @@
<?php
$helpMessage = $this->translate('Press and hold the Ctrl key while clicking on rows to select multiple rows or press and hold the Shift key to select a range of rows.', 'multiselection');
?>
<div class="selection-info">
<span class="selection-info-count">0</span> <?= $this->translate('row(s) selected', 'multiselection') ?> <?= $this->icon('help', $helpMessage) ?>
<div class="selection-info" title="<?= $this->escape($helpMessage) ?>">
<span class="selection-info-count">0</span> <?= $this->translate('row(s) selected', 'multiselection') ?>
</div>

View File

@ -4,8 +4,9 @@ use Icinga\Web\Url;
$selfUrl = 'monitoring/list/services';
$currentUrl = Url::fromRequest()->getRelativeUrl();
?><h3 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : '' ?>>
?><h1 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : '' ?>>
<?= $this->qlink(sprintf($this->translate('%s services:'), $this->stats->services_total), $selfUrl) ?>
<span class="badges">
<?php if ($this->stats->services_ok): ?>
<span class="state ok<?= $currentUrl === Url::fromPath($selfUrl, array('service_state' => 0))->getRelativeUrl() ? ' active' : '' ?>"><?= $this->qlink(
$this->stats->services_ok,
@ -79,5 +80,6 @@ foreach (array(2 => 'critical', 3 => 'unknown', 1 => 'warning') as $stateId => $
array('title' => sprintf($this->translate('Services with state %s'), strtoupper($this->translate('pending'))))
) ?></span>
<?php endif ?>
</h3>
</span>
</h1>

View File

@ -4,9 +4,16 @@
<div style="margin: 1em" class="dontprint">
<?= $this->translate('Sort by'); ?> <?= $this->sortControl->render($this); ?>
</div>
<?= $this->widget('limiter', array('url' => $this->url, 'max' => $this->history->count())); ?>
<?= $this->paginationControl($history, null, null, array('preserve' => $this->preserve)); ?>
</div>
<br> <br>
<?= $form ?>
<div class="content">
<?= $this->filterEditor ?>
</div>
<?php endif ?>
<div class="content">

View File

@ -1,266 +1,253 @@
<?php if (!$this->compact): ?>
<div class="controls">
<?= $this->tabs ?>
</div>
<?php endif ?>
<?php if ($this->compact): ?>
<div class="content">
<div class="boxview" data-base-target="_next">
<?php
if (count($hostgroups) === 0) {
echo mt('monitoring', 'No host groups matching the filter');
}
?>
<?php foreach($hostgroups as $h): ?>
<div class="box hostgroup">
<h2>
<a href="<?= $this->href('monitoring/list/services', array('hostgroup' => $h->hostgroup)); ?>">
<?= $h->hostgroup; ?>
</a>
</h2>
<div class="box contents">
<table>
<thead>
<tr>
<th><?= $this->translate('Hosts'); ?></th>
<th><?= $this->translate('Services'); ?></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<?php if ($h->hosts_down_handled || $h->hosts_down_unhandled): ?>
<!-- Hosts DOWN -->
<div class="box entry state_down <?= $h->hosts_down_unhandled ? '' : 'handled'; ?>">
<?php if ($h->hosts_down_unhandled): ?>
<a href="<?= $this->href(
'monitoring/list/hosts',
array(
'host_state' => 1,
'host_unhandled' => 1,
'hostgroup' => $h->hostgroup
)
); ?>" title="<?= $this->translate('Hosts DOWN Unhandled') ?>">
<?= $h->hosts_down_unhandled; ?> <?= $this->translate('DOWN', 'icinga.state') ?>
</a>
<?php endif ?>
<?php if ($h->hosts_down_handled): ?>
<a href="<?= $this->href(
'monitoring/list/hosts',
array(
'host_state' => 1,
'host_handled' => 1,
'hostgroup' => $h->hostgroup
)
); ?>" title="<?= $this->translate('Hosts DOWN Handled') ?>">
<?= $h->hosts_down_handled . ' ' . ($h->hosts_down_unhandled ? $this->translate('Acknowledged') : $this->translate('DOWN', 'icinga.state')); ?>
</a>
<?php endif ?>
</div>
<!-- End of Hosts DOWN -->
<?php endif ?>
<?php if ($h->hosts_unreachable_handled || $h->hosts_unreachable_unhandled): ?>
<!-- Hosts UNREACHABLE -->
<div class="box entry state_unreachable <?= $h->hosts_unreachable_unhandled ? '' : 'handled'; ?>">
<?php if ($h->hosts_unreachable_unhandled): ?>
<a href="<?= $this->href(
'monitoring/list/hosts',
array(
'host_state' => 2,
'host_unhandled' => 1,
'hostgroup' => $h->hostgroup
)
); ?>" title="<?= $this->translate('Hosts UNREACHABLE Unhandled') ?>">
<?= $h->hosts_unreachable_unhandled; ?> <?= $this->translate('UNREACHABLE', 'icinga.state') ?>
</a>
<?php endif ?>
<?php if ($h->hosts_unreachable_handled): ?>
<a href="<?= $this->href(
'monitoring/list/hosts',
array(
'host_state' => 2,
'host_handled' => 1,
'hostgroup' => $h->hostgroup
)
); ?>" title="<?= $this->translate('Hosts UNREACHABLE Handled') ?>">
<?= $h->hosts_unreachable_handled . ' ' . ($h->hosts_unreachable_unhandled ? $this->translate('Acknowledged') : $this->translate('UNREACHABLE', 'icinga.state')) ?>
</a>
<?php endif ?>
</div>
<!-- End of Hosts UNREACHABLE -->
<?php endif ?>
<?php if ($h->hosts_up): ?>
<!-- Hosts UP -->
<div class="box entry state_up">
<a href="<?= $this->href(
'monitoring/list/hosts',
array(
'host_state' => 0,
'hostgroup' => $h->hostgroup
)
); ?>" title="<?= $this->translate('Hosts UP') ?>">
<?= $h->hosts_up; ?> <?= $this->translate('UP', 'icinga.state') ?>
</a>
</div>
<!-- End of Hosts UP -->
<?php endif ?>
<?php if ($h->hosts_pending): ?>
<!-- Hosts PENDING -->
<div class="box entry state_pending">
<a href="<?= $this->href(
'monitoring/list/hosts',
array(
'host_state' => 99,
'hostgroup' => $h->hostgroup
)
); ?>" title="<?= $this->translate('Hosts PENDING') ?>">
<?= $h->hosts_pending; ?> <?= $this->translate('PENDING', 'icinga.state') ?>
</a>
</div>
<!-- End of Hosts PENDING -->
<?php endif ?>
</td>
<td>
<?php if ($h->services_critical_handled || $h->services_critical_unhandled): ?>
<!-- Services CRITICAL -->
<div class="box entry state_critical <?= $h->services_critical_unhandled ? '' : 'handled'; ?>">
<?php if ($h->services_critical_unhandled): ?>
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 2,
'service_acknowledged' => 0,
'service_in_downtime' => 0,
'host_problem' => 0,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services CRITICAL Unhandled') ?>">
<?= $h->services_critical_unhandled; ?> <?= $this->translate('CRITICAL', 'icinga.state') ?>
</a>
<?php endif ?>
<?php if ($h->services_critical_handled): ?>
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 2,
'service_handled' => 1,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services CRITICAL Handled') ?>">
<?= $h->services_critical_handled . ' ' . ($h->services_critical_unhandled ? $this->translate('Acknowledged') : $this->translate('CRITICAL', 'icinga.state')); ?>
</a>
<?php endif ?>
</div>
<!-- End of Services CRITICAL -->
<?php endif ?>
<?php if ($h->services_warning_handled || $h->services_warning_unhandled): ?>
<!-- Services WARNING -->
<div class="box entry state_warning <?= $h->services_warning_unhandled ? '' : 'handled'; ?>">
<?php if ($h->services_warning_unhandled): ?>
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 1,
'service_acknowledged' => 0,
'service_in_downtime' => 0,
'host_problem' => 0,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services WARNING Unhandled') ?>">
<?= $h->services_warning_unhandled; ?> <?= $this->translate('WARNING', 'icinga.state') ?>
</a>
<?php endif ?>
<?php if ($h->services_warning_handled): ?>
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 1,
'service_handled' => 1,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services WARNING Handled') ?>">
<?= $h->services_warning_handled . ' ' . ($h->services_warning_unhandled ? $this->translate('Acknowledged') : $this->translate('WARNING', 'icinga.state')); ?>
</a>
<?php endif ?>
</div>
<!-- End of Services WARNING -->
<?php endif ?>
<?php if ($h->services_unknown_handled || $h->services_unknown_unhandled): ?>
<!-- Services UNKNOWN -->
<div class="box entry state_unknown <?= $h->services_unknown_unhandled ? '' : 'handled'; ?>">
<?php if ($h->services_unknown_unhandled): ?>
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 3,
'service_acknowledged' => 0,
'service_in_downtime' => 0,
'host_problem' => 0,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services UNKNOWN Unhandled') ?>">
<?= $h->services_unknown_unhandled; ?> <?= $this->translate('UNKNOWN', 'icinga.state') ?>
</a>
<?php endif ?>
<?php if ($h->services_unknown_handled): ?>
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 3,
'service_handled' => 1,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services UNKNOWN Handled') ?>">
<?= $h->services_unknown_handled . ' ' . ($h->services_unknown_unhandled ? $this->translate('Acknowledged') : $this->translate('UNKNOWN', 'icinga.state')); ?>
</a>
<?php endif ?>
</div>
<!-- End of Services UNKNOWN -->
<?php endif ?>
<?php if ($h->services_ok): ?>
<!-- Services OK -->
<div class="box entry state_ok">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 0,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services OK') ?>">
<?= $h->services_ok; ?> <?= $this->translate('OK', 'icinga.state') ?>
</a>
</div>
<!-- End of Services OK -->
<?php endif ?>
<?php if ($h->services_pending): ?>
<!-- Services PENDING -->
<div class="box entry state_pending">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 99,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services PENDING') ?>">
<?= $h->services_pending; ?> <?= $this->translate('PENDING', 'icinga.state') ?>
</a>
</div>
<!-- End of Services PENDING -->
<?php endif ?>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<?php endforeach ?>
</div>
<?php else: ?>
<div class="controls">
<?= $this->tabs ?>
<?= $this->widget('limiter')->setMaxLimit(count($hostgroups)); ?>
<?= $this->paginationControl($hostgroups, null, null, array('preserve' => $this->preserve)); ?>
</div>
<div class="content">
<?= $this->filterEditor; ?>
<?php endif ?>
<?php
if (count($hostgroups) === 0) {
echo $this->translate('No host groups matching the filter');
echo '</div>';
return;
}
?>
<table class="groupview" data-base-target="_next">
<thead>
<th style="text-align: left;"><?= $this->translate('Last Problem'); ?></th>
<th style="text-align: left;"><?= $this->translate('Host Group'); ?></th>
<th><?= $this->translate('Total Services'); ?></th>
<th colspan="5"><?= $this->translate('Service States'); ?></th>
</thead>
<tbody>
<?php foreach ($hostgroups as $h): ?>
<tr href="<?= $this->href('monitoring/list/services', array('hostgroup' => $h->hostgroup)); ?>">
<?php if ($h->services_critical_last_state_change_unhandled): ?>
<td class="state change critical">
<strong><?= $this->translate('CRITICAL'); ?></strong>
<br>
<?= $this->prefixedTimeSince($h->services_critical_last_state_change_unhandled); ?>
</td>
<?php elseif ($h->services_unknown_last_state_change_unhandled): ?>
<td class="state change unknown">
<strong><?= $this->translate('UNKNOWN'); ?></strong>
<br>
<?= $this->prefixedTimeSince($h->services_unknown_last_state_change_unhandled); ?>
</td>
<?php elseif ($h->services_warning_last_state_change_unhandled): ?>
<td class="state change warning">
<strong><?= $this->translate('WARNING'); ?></strong>
<br>
<?= $this->prefixedTimeSince($h->services_warning_last_state_change_unhandled); ?>
</td>
<?php elseif ($h->services_critical_last_state_change_handled): ?>
<td class="state change critical handled">
<strong><?= $this->translate('CRITICAL'); ?></strong>
<br>
<?= $this->prefixedTimeSince($h->services_critical_last_state_change_handled); ?>
</td>
<?php elseif ($h->services_unknown_last_state_change_handled): ?>
<td class="state change unknown handled">
<strong><?= $this->translate('UNKNOWN'); ?></strong>
<br>
<?= $this->prefixedTimeSince($h->services_unknown_last_state_change_handled); ?>
</td>
<?php elseif ($h->services_warning_last_state_change_handled): ?>
<td class="state change warning handled">
<strong><?= $this->translate('WARNING'); ?></strong>
<br>
<?= $this->prefixedTimeSince($h->services_warning_last_state_change_handled); ?>
</td>
<?php elseif ($h->services_ok_last_state_change): ?>
<td class="state change ok">
<strong><?= $this->translate('OK'); ?></strong>
<br>
<?= $this->prefixedTimeSince($h->services_ok_last_state_change); ?>
</td>
<?php else: ?>
<td class="state change pending">
<strong><?= $this->translate('PENDING'); ?></strong>
<br>
<?= $this->prefixedTimeSince($h->services_pending_last_state_change); ?>
</td>
<?php endif ?>
<td>
<a href="<?= $this->href('monitoring/list/services', array('hostgroup' => $h->hostgroup)); ?>">
<?= $h->hostgroup; ?>
</a>
</td>
<td class="services-total">
<?= $h->services_total; ?>
</td>
<td class="state">
<?php if ($h->services_ok): ?>
<span class="state ok">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 0,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services OK'); ?>">
<?= $h->services_ok; ?>
</a>
</span>
<?php else: ?>
<span class="no-state">
-
</span>
<?php endif ?>
</td>
<td class="state">
<?php if ($h->services_critical_unhandled): ?>
<span class="state critical">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 2,
'service_acknowledged' => 0,
'service_in_downtime' => 0,
'host_problem' => 0,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services CRITICAL Unhandled'); ?>">
<?= $h->services_critical_unhandled; ?>
</a>
<?php endif ?>
<?php if ($h->services_critical_handled): ?>
<span class="state critical handled">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 2,
'service_handled' => 1,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services CRITICAL Handled'); ?>">
<?= $h->services_critical_handled; ?>
</a>
</span>
<?php endif ?>
<?php if ($h->services_critical_unhandled): ?>
</span>
<?php endif ?>
<?php if (! $h->services_critical_unhandled && !$h->services_critical_handled): ?>
<span class="no-state">
-
</span>
<?php endif ?>
</td>
<td class="state">
<?php if ($h->services_unknown_unhandled): ?>
<span class="state unknown">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 3,
'service_acknowledged' => 0,
'service_in_downtime' => 0,
'host_problem' => 0,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services UNKNOWN Unhandled'); ?>">
<?= $h->services_unknown_unhandled; ?>
</a>
<?php endif ?>
<?php if ($h->services_unknown_handled): ?>
<span class="state unknown handled">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 3,
'service_handled' => 1,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services UNKNOWN Handled'); ?>">
<?= $h->services_unknown_handled; ?>
</a>
</span>
<?php endif ?>
<?php if ($h->services_unknown_unhandled): ?>
</span>
<?php endif ?>
<?php if (! $h->services_unknown_unhandled && !$h->services_unknown_handled): ?>
<span class="no-state">
-
</span>
<?php endif ?>
</td>
<td class="state">
<?php if ($h->services_warning_unhandled): ?>
<span class="state warning">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 1,
'service_acknowledged' => 0,
'service_in_downtime' => 0,
'host_problem' => 0,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services WARNING Unhandled'); ?>">
<?= $h->services_warning_unhandled; ?>
</a>
<?php endif ?>
<?php if ($h->services_warning_handled): ?>
<span class="state warning handled">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 1,
'service_handled' => 1,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services WARNING Handled'); ?>">
<?= $h->services_warning_handled; ?>
</a>
</span>
<?php endif ?>
<?php if ($h->services_warning_unhandled): ?>
</span>
<?php endif ?>
<?php if (! $h->services_warning_unhandled && !$h->services_warning_handled): ?>
<span class="no-state">
-
</span>
<?php endif ?>
</td>
<td class="state">
<?php if ($h->services_pending): ?>
<span class="state pending">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 99,
'hostgroup' => $h->hostgroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services PENDING'); ?>">
<?= $h->services_pending; ?>
</a>
</span>
<?php else: ?>
<span class="no-state">
-
</span>
<?php endif ?>
</td>
</tr>
<?php endforeach ?>
</tbody>
</table>
</div>

View File

@ -7,6 +7,7 @@ if ($this->compact): ?>
<div class="controls">
<?= $this->tabs ?>
<div style="margin: 1em;" class="dontprint">
<?= $this->render('list/components/selectioninfo.phtml') ?>
<?= $this->render('list/components/hostssummary.phtml') ?>
<?= $this->translate('Sort by') ?> <?= $this->sortControl->render($this) ?>
</div>
@ -14,7 +15,6 @@ if ($this->compact): ?>
<?= $this->widget('limiter')->setMaxLimit($this->hosts->count()) ?>
<?= $this->paginationControl($hosts, null, null, array('preserve' => $this->preserve)) ?>
<?= $this->selectionToolbar('multi', $this->href('monitoring/hosts/show?' . $this->filter->toQueryString())) ?>
<?= $this->render('list/components/selectioninfo.phtml') ?>
</div>
<div class="content">
@ -46,7 +46,7 @@ if ($hosts->count() === 0) {
$icons = array();
if (! $host->host_handled && $host->host_state > 0){
$icons[] = $this->icon('flash', $this->translate('Unhandled'));
$icons[] = $this->icon('attention-alt', $this->translate('Unhandled'));
}
if ($host->host_acknowledged) {

View File

@ -1,269 +1,253 @@
<?php if (!$this->compact): ?>
<div class="controls">
<?= $this->tabs ?>
</div>
<?php endif ?>
<?php if ($this->compact): ?>
<div class="content">
<div class="boxview" data-base-target="_next">
<?php
if (count($servicegroups) === 0) {
echo mt('monitoring', 'No service groups matching the filter');
}
?>
<?php foreach($servicegroups as $servicegroup): ?>
<div class="box servicegroup">
<h2>
<a href="<?= $this->href(
'monitoring/list/services',
array('servicegroup' => $servicegroup->servicegroup)
); ?>">
<?= $servicegroup->servicegroup; ?>
</a>
</h2>
<div class="box contents">
<table>
<thead>
<tr>
<th><?= $this->translate('Hosts'); ?></th>
<th><?= $this->translate('Services'); ?></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<?php if ($servicegroup->hosts_down_handled || $servicegroup->hosts_down_unhandled): ?>
<!-- Hosts DOWN -->
<div class="box entry state_down <?= $servicegroup->hosts_down_unhandled ? '' : 'handled'; ?>">
<?php if ($servicegroup->hosts_down_unhandled): ?>
<a href="<?= $this->href(
'monitoring/list/hosts',
array(
'host_state' => 1,
'host_unhandled' => 1,
'servicegroup' => $servicegroup->servicegroup
)
); ?>" title="<?= $this->translate('Hosts DOWN Unhandled') ?>">
<?= $servicegroup->hosts_down_unhandled; ?> <?= $this->translate('DOWN', 'icinga.state') ?>
</a>
<?php endif ?>
<?php if ($servicegroup->hosts_down_handled): ?>
<a href="<?= $this->href(
'monitoring/list/hosts',
array(
'host_state' => 1,
'host_handled' => 1,
'servicegroup' => $servicegroup->servicegroup
)
); ?>" title="<?= $this->translate('Hosts DOWN Handled') ?>">
<?= $servicegroup->hosts_down_handled . ' ' . ($servicegroup->hosts_down_unhandled ? $this->translate('Acknowledged') : 'DOWN'); ?>
</a>
<?php endif ?>
</div>
<!-- End of Hosts DOWN -->
<?php endif ?>
<?php if ($servicegroup->hosts_unreachable_handled || $servicegroup->hosts_unreachable_unhandled): ?>
<!-- Hosts UNREACHABLE -->
<div class="box entry state_unreachable <?= $servicegroup->hosts_unreachable_unhandled ? '' : 'handled'; ?>">
<?php if ($servicegroup->hosts_unreachable_unhandled): ?>
<a href="<?= $this->href(
'monitoring/list/hosts',
array(
'host_state' => 2,
'host_unhandled' => 1,
'servicegroup' => $servicegroup->servicegroup
)
); ?>" title="<?= $this->translate('Hosts UNREACHABLE Unhandled') ?>">
<?= $servicegroup->hosts_unreachable_unhandled; ?> <?= $this->translate('UNREACHABLE', 'icinga.state') ?>
</a>
<?php endif ?>
<?php if ($servicegroup->hosts_unreachable_handled): ?>
<a href="<?= $this->href(
'monitoring/list/hosts',
array(
'host_state' => 2,
'host_handled' => 1,
'servicegroup' => $servicegroup->servicegroup
)
); ?>" title="<?= $this->translate('Hosts UNREACHABLE Handled') ?>">
<?= $servicegroup->hosts_unreachable_handled . ' ' . ($servicegroup->hosts_unreachable_unhandled ? $this->translate('Acknowledged') : 'UNREACHABLE'); ?>
</a>
<?php endif ?>
</div>
<!-- End of Hosts UNREACHABLE -->
<?php endif ?>
<?php if ($servicegroup->hosts_up): ?>
<!-- Hosts UP -->
<div class="box entry state_up">
<a href="<?= $this->href(
'monitoring/list/hosts',
array(
'host_state' => 0,
'servicegroup' => $servicegroup->servicegroup
)
); ?>" title="<?= $this->translate('Hosts UP') ?>">
<?= $servicegroup->hosts_up; ?> <?= $this->translate('UP', 'icinga.state') ?>
</a>
</div>
<!-- End of Hosts UP -->
<?php endif ?>
<?php if ($servicegroup->hosts_pending): ?>
<!-- Hosts PENDING -->
<div class="box entry state_pending">
<a href="<?= $this->href(
'monitoring/list/hosts',
array(
'host_state' => 99,
'servicegroup' => $servicegroup->servicegroup
)
); ?>" title="<?= $this->translate('Hosts PENDING') ?>">
<?= $servicegroup->hosts_pending; ?> <?= $this->translate('PENDING', 'icinga.state') ?>
</a>
</div>
<!-- End of Hosts PENDING -->
<?php endif ?>
</td>
<td>
<?php if ($servicegroup->services_critical_handled || $servicegroup->services_critical_unhandled): ?>
<!-- Services CRITICAL -->
<div class="box entry state_critical <?= $servicegroup->services_critical_unhandled ? '' : 'handled'; ?>">
<?php if ($servicegroup->services_critical_unhandled): ?>
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 2,
'service_acknowledged' => 0,
'service_in_downtime' => 0,
'host_problem' => 0,
'servicegroup' => $servicegroup->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services CRITICAL Unhandled') ?>">
<?= $servicegroup->services_critical_unhandled; ?> <?= $this->translate('CRITICAL', 'icinga.state') ?>
</a>
<?php endif ?>
<?php if ($servicegroup->services_critical_handled): ?>
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 2,
'service_handled' => 1,
'servicegroup' => $servicegroup->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services CRITICAL Handled') ?>">
<?= $servicegroup->services_critical_handled . ' ' . ($servicegroup->services_critical_unhandled ? $this->translate('Acknowledged') : 'CRITICAL'); ?>
</a>
<?php endif ?>
</div>
<!-- End of Services CRITICAL -->
<?php endif ?>
<?php if ($servicegroup->services_warning_handled || $servicegroup->services_warning_unhandled): ?>
<!-- Services WARNING -->
<div class="box entry state_warning <?= $servicegroup->services_warning_unhandled ? '' : 'handled'; ?>">
<?php if ($servicegroup->services_warning_unhandled): ?>
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 1,
'service_acknowledged' => 0,
'service_in_downtime' => 0,
'host_problem' => 0,
'servicegroup' => $servicegroup->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services WARNING Unhandled') ?>">
<?= $servicegroup->services_warning_unhandled; ?> <?= $this->translate('WARNING', 'icinga.state') ?>
</a>
<?php endif ?>
<?php if ($servicegroup->services_warning_handled): ?>
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 1,
'service_handled' => 1,
'servicegroup' => $servicegroup->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services WARNING Handled') ?>">
<?= $servicegroup->services_warning_handled . ' ' . ($servicegroup->services_warning_unhandled ? $this->translate('Acknowledged') : 'WARNING'); ?>
</a>
<?php endif ?>
</div>
<!-- End of Services WARNING -->
<?php endif ?>
<?php if ($servicegroup->services_unknown_handled || $servicegroup->services_unknown_unhandled): ?>
<!-- Services UNKNOWN -->
<div class="box entry state_unknown <?= $servicegroup->services_unknown_unhandled ? '' : 'handled'; ?>">
<?php if ($servicegroup->services_unknown_unhandled): ?>
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 3,
'service_acknowledged' => 0,
'service_in_downtime' => 0,
'host_problem' => 0,
'servicegroup' => $servicegroup->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services UNKNOWN Unhandled') ?>">
<?= $servicegroup->services_unknown_unhandled; ?> <?= $this->translate('UNKNOWN', 'icinga.state') ?>
</a>
<?php endif ?>
<?php if ($servicegroup->services_unknown_handled): ?>
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 3,
'service_handled' => 1,
'servicegroup' => $servicegroup->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services UNKNOWN Handled') ?>">
<?= $servicegroup->services_unknown_handled . ' ' . ($servicegroup->services_unknown_unhandled ? $this->translate('Acknowledged') : 'UNKNOWN'); ?>
</a>
<?php endif ?>
</div>
<!-- End of Services UNKNOWN -->
<?php endif ?>
<?php if ($servicegroup->services_ok): ?>
<!-- Services OK -->
<div class="box entry state_ok">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 0,
'servicegroup' => $servicegroup->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services OK') ?>">
<?= $servicegroup->services_ok; ?> <?= $this->translate('OK', 'icinga.state') ?>
</a>
</div>
<!-- End of Services OK -->
<?php endif ?>
<?php if ($servicegroup->services_pending): ?>
<!-- Services PENDING -->
<div class="box entry state_pending">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 99,
'servicegroup' => $servicegroup->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services PENDING') ?>">
<?= $servicegroup->services_pending; ?> <?= $this->translate('PENDING', 'icinga.state') ?>
</a>
</div>
<!-- End of Services PENDING -->
<?php endif ?>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<div class="controls">
<?= $this->tabs ?>
<?= $this->widget('limiter')->setMaxLimit(count($servicegroups)); ?>
<?= $this->paginationControl($servicegroups, null, null, array('preserve' => $this->preserve)); ?>
</div>
<div class="content">
<?= $this->filterEditor; ?>
<?php endif ?>
<?php
if (count($servicegroups) === 0) {
echo $this->translate('No service groups matching the filter');
echo '</div>';
return;
}
?>
<table class="groupview" data-base-target="_next">
<thead>
<th style="text-align: left;"><?= $this->translate('Last Problem'); ?></th>
<th style="text-align: left;"><?= $this->translate('Service Group'); ?></th>
<th><?= $this->translate('Total Services'); ?></th>
<th colspan="5"><?= $this->translate('Service States'); ?></th>
</thead>
<tbody>
<?php foreach ($servicegroups as $s): ?>
<tr href="<?= $this->href('monitoring/list/services', array('servicegroup' => $s->servicegroup)); ?>">
<?php if ($s->services_critical_last_state_change_unhandled): ?>
<td class="state change critical">
<strong><?= $this->translate('CRITICAL'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_critical_last_state_change_unhandled); ?>
</td>
<?php elseif ($s->services_unknown_last_state_change_unhandled): ?>
<td class="state change unknown">
<strong><?= $this->translate('UNKNOWN'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_unknown_last_state_change_unhandled); ?>
</td>
<?php elseif ($s->services_warning_last_state_change_unhandled): ?>
<td class="state change warning">
<strong><?= $this->translate('WARNING'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_warning_last_state_change_unhandled); ?>
</td>
<?php elseif ($s->services_critical_last_state_change_handled): ?>
<td class="state change critical handled">
<strong><?= $this->translate('CRITICAL'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_critical_last_state_change_handled); ?>
</td>
<?php elseif ($s->services_unknown_last_state_change_handled): ?>
<td class="state change unknown handled">
<strong><?= $this->translate('UNKNOWN'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_unknown_last_state_change_handled); ?>
</td>
<?php elseif ($s->services_warning_last_state_change_handled): ?>
<td class="state change warning handled">
<strong><?= $this->translate('WARNING'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_warning_last_state_change_handled); ?>
</td>
<?php elseif ($s->services_ok_last_state_change): ?>
<td class="state change ok">
<strong><?= $this->translate('OK'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_ok_last_state_change); ?>
</td>
<?php else: ?>
<td class="state change pending">
<strong><?= $this->translate('PENDING'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_pending_last_state_change); ?>
</td>
<?php endif ?>
<td>
<a href="<?= $this->href('monitoring/list/services', array('servicegroup' => $s->servicegroup)); ?>">
<?= $s->servicegroup; ?>
</a>
</td>
<td class="services-total">
<?= $s->services_total; ?>
</td>
<td class="state">
<?php if ($s->services_ok): ?>
<span class="state ok">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 0,
'servicegroup' => $s->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services OK'); ?>">
<?= $s->services_ok; ?>
</a>
</span>
<?php else: ?>
<span class="no-state">
-
</span>
<?php endif ?>
</td>
<td class="state">
<?php if ($s->services_critical_unhandled): ?>
<span class="state critical">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 2,
'service_acknowledged' => 0,
'service_in_downtime' => 0,
'host_problem' => 0,
'servicegroup' => $s->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services CRITICAL Unhandled'); ?>">
<?= $s->services_critical_unhandled; ?>
</a>
<?php endif ?>
<?php if ($s->services_critical_handled): ?>
<span class="state critical handled">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 2,
'service_handled' => 1,
'servicegroup' => $s->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services CRITICAL Handled'); ?>">
<?= $s->services_critical_handled; ?>
</a>
</span>
<?php endif ?>
<?php if ($s->services_critical_unhandled): ?>
</span>
<?php endif ?>
<?php if (! $s->services_critical_unhandled && !$s->services_critical_handled): ?>
<span class="no-state">
-
</span>
<?php endif ?>
</td>
<td class="state">
<?php if ($s->services_unknown_unhandled): ?>
<span class="state unknown">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 3,
'service_acknowledged' => 0,
'service_in_downtime' => 0,
'host_problem' => 0,
'servicegroup' => $s->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services UNKNOWN Unhandled'); ?>">
<?= $s->services_unknown_unhandled; ?>
</a>
<?php endif ?>
<?php if ($s->services_unknown_handled): ?>
<span class="state unknown handled">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 3,
'service_handled' => 1,
'servicegroup' => $s->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services UNKNOWN Handled'); ?>">
<?= $s->services_unknown_handled; ?>
</a>
</span>
<?php endif ?>
<?php if ($s->services_unknown_unhandled): ?>
</span>
<?php endif ?>
<?php if (! $s->services_unknown_unhandled && !$s->services_unknown_handled): ?>
<span class="no-state">
-
</span>
<?php endif ?>
</td>
<td class="state">
<?php if ($s->services_warning_unhandled): ?>
<span class="state warning">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 1,
'service_acknowledged' => 0,
'service_in_downtime' => 0,
'host_problem' => 0,
'servicegroup' => $s->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services WARNING Unhandled'); ?>">
<?= $s->services_warning_unhandled; ?>
</a>
<?php endif ?>
<?php if ($s->services_warning_handled): ?>
<span class="state warning handled">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 1,
'service_handled' => 1,
'servicegroup' => $s->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services WARNING Handled'); ?>">
<?= $s->services_warning_handled; ?>
</a>
</span>
<?php endif ?>
<?php if ($s->services_warning_unhandled): ?>
</span>
<?php endif ?>
<?php if (! $s->services_warning_unhandled && !$s->services_warning_handled): ?>
<span class="no-state">
-
</span>
<?php endif ?>
</td>
<td class="state">
<?php if ($s->services_pending): ?>
<span class="state pending">
<a href="<?= $this->href(
'monitoring/list/services',
array(
'service_state' => 99,
'servicegroup' => $s->servicegroup,
'sort' => 'service_severity'
)
); ?>" title="<?= $this->translate('Services PENDING'); ?>">
<?= $s->services_pending; ?>
</a>
</span>
<?php else: ?>
<span class="no-state">
-
</span>
<?php endif ?>
</td>
</tr>
<?php endforeach ?>
</tbody>
</table>
</div>

View File

@ -7,6 +7,7 @@ if (!$this->compact): ?>
<div class="controls">
<?= $this->tabs ?>
<div style="margin: 1em;" class="dontprint">
<?= $this->render('list/components/selectioninfo.phtml') ?>
<?= $this->render('list/components/servicesummary.phtml') ?>
<div style="float: right">
<?= $this->translate('Sort by') ?> <?= $this->sortControl ?>
@ -18,10 +19,6 @@ if (!$this->compact): ?>
<?= $this->widget('limiter')->setCurrentPageCount($this->services->count()) ?>
<?= $this->paginationControl($services, null, null, array('preserve' => $this->preserve)) ?>
<?php endif ?>
<!--
<?= $this->selectionToolbar('multi', $this->href('monitoring/services/show?' . $this->filterEditor->getFilter()->toQueryString())) ?>
<?= $this->render('list/components/selectioninfo.phtml') ?>
-->
</div>
<div class="content">
@ -71,7 +68,7 @@ foreach ($services as $service):
<?= $this->perfdata($service->service_perfdata, true, true) ?>
<?php if (!$service->service_handled && $service->service_state > 0): ?>
<?= $this->icon('flash', $this->translate('Unhandled')) ?>
<?= $this->icon('attention-alt', $this->translate('Unhandled')) ?>
<?php endif ?>
<?php if ($service->service_acknowledged && !$service->service_in_downtime): ?>

View File

@ -6,7 +6,7 @@ $objectName = $this->is_service ? 'Services' : 'Hosts';
<th><a href=<?= count($comments) ?> <?= $this->translate('Comments') ?></th>
<td>
<a href="<?= $this->href('monitoring/command/removecomment', $this->target) ?>"><?=
$this->icon('minus')
$this->icon('cancel')
?> <?= $this->translate('Remove Comments') ?></a><br />
<a href="<?= $this->href('monitoring/command/delaynotifications', $this->target); ?>"><?=
$this->icon('bell-off-empty')

View File

@ -7,7 +7,7 @@ $objectName = $this->is_service ? 'Services' : 'Hosts';
<th><?= count($downtimes) ?> Downtimes</th>
<td>
<a href="<?=$this->href('monitoring/command/removedowntime', $this->target); ?>"><?=
$this->icon('minus') ?>Remove Downtimes</a><br />
$this->icon('cancel') ?>Remove Downtimes</a><br />
<a title="Schedule downtimes for all selected <?= $objectName ?>" href="<?=
$this->href('monitoring/command/scheduledowntime', $this->target) ?>"><?=
$this->icon('plug')

View File

@ -45,7 +45,7 @@ $this->target = array(
</tr>
</table>
<h2><?=$this->icon('service')?> Service Actions</h2>
<h2><?=$this->icon('conf')?> Service Actions</h2>
<table class="avp newsection">
<tbody>

View File

@ -7,7 +7,7 @@
<thead>
<tr>
<th><?= $this->icon('host') ?> <?= $this->translate('Host') ?></th>
<th><?= $this->icon('service') ?> <?= $this->translate('Service') ?></th>
<th><?= $this->icon('conf') ?> <?= $this->translate('Service') ?></th>
</tr>
</thead>
<tbody>

View File

@ -1,55 +1,171 @@
<?php
$rv = $this->runtimeVariables()->create($this->runtimevariables);
$cp = $this->checkPerformance()->create($this->checkperformance);
?>
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content processinfo">
<?php if ((bool) $this->programStatus->is_currently_running === true): ?>
<div class="backend-running">
<?= sprintf(
$this->translate('%s has been up and running with PID %d since %s'),
$this->backendName,
$this->programStatus->process_id,
$this->timeSince($this->programStatus->program_start_time)) ?>
<div class="boxview">
<div class="box left">
<h2><?= $this->translate('Feature Commands') ?></h2>
<?= $this->toggleFeaturesForm ?>
</div>
<div class="box left">
<h2><?= $this->translate('Process Info') ?></h2>
<table class="avp">
<tbody>
<tr>
<th><?= $this->translate('Program Start Time') ?></th>
<td><?= $this->dateFormat()->formatDateTime($this->programStatus->program_start_time) ?></td>
</tr>
<tr>
<th><?= $this->translate('Last Status Update'); ?></th>
<td><?= $this->timeSince($this->programStatus->status_update_time) ?> ago</td>
</tr>
<tr>
<th><?= $this->translate('Last External Command Check'); ?></th>
<td><?= $this->timeSince($this->programStatus->last_command_check) ?> ago</td>
</tr>
<tr>
<th><?= $this->translate('Last Log File Rotation'); ?></th>
<td><?= $this->programStatus->last_log_rotation
? $this->timeSince($this->programStatus->last_log_rotation)
: $this->translate('N/A') ?></td>
</tr>
<tr>
<th><?= $this->translate('Global Service Event Handler'); ?></th>
<td><?= $this->programStatus->global_service_event_handler
? $this->programStatus->global_service_event_handler
: $this->translate('N/A'); ?></td>
</tr>
<tr>
<th><?= $this->translate('Global Host Event Handler'); ?></th>
<td><?= $this->programStatus->global_host_event_handler
? $this->programStatus->global_host_event_handler
: $this->translate('N/A'); ?></td>
</tr>
</tbody>
</table>
<?php if ((bool) $this->programStatus->is_currently_running === true): ?>
<div class="backend-running">
<?= sprintf(
$this->translate('%s has been up and running with PID %d since %s'),
$this->backendName,
$this->programStatus->process_id,
$this->timeSince($this->programStatus->program_start_time)) ?>
</div>
<?php else: ?>
<div class="backend-not-running">
<?= sprintf($this->translate('%s is not running'), $this->backendName) ?>
</div>
<?php endif ?>
</div>
<div class="box left">
<h2><?= $this->translate('Performance Info') ?></h2>
<h3><?= $this->translate('Object summaries') ?></h3>
<table class="avp">
<thead>
<tr>
<th></th>
<th><?= $this->translate('overall') ?></th>
<th><?= $this->translate('scheduled') ?></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<strong><?= $this->translate('Hosts') ?></strong>
</td>
<td>
<?= $rv->total_hosts; ?>
</td>
<td>
<?= $rv->total_scheduled_hosts; ?>
</td>
</tr>
<tr>
<td>
<strong><?= $this->translate('Services') ?></strong>
</td>
<td>
<?= $rv->total_services; ?>
</td>
<td>
<?= $rv->total_scheduled_services; ?>
</td>
</tr>
<tr>
<td>
<strong><?= $this->translate('Average services per host') ?></strong>
</td>
<td>
<?= sprintf('%.2f', $rv->average_services_per_host); ?>
</td>
<td>
<?= sprintf('%.2f', $rv->average_scheduled_services_per_host); ?>
</td>
</tr>
</tbody>
</table>
<h3><?= $this->translate('Active checks') ?></h3>
<table class="avp">
<thead>
<tr>
<th></th>
<th></th>
<th><?= $this->translate('Latency') ?></th>
<th><?= $this->translate('Execution time') ?></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<strong><?= $this->translate('Host Checks') ?></strong>
</td>
<td><?= $cp->host_active_count; ?></td>
<td><?= sprintf('%.3f', $cp->host_active_latency_avg); ?>s</td>
<td><?= sprintf('%.3f', $cp->host_active_execution_avg); ?>s</td>
</tr>
<tr>
<td>
<strong><?= $this->translate('Service Checks') ?></strong>
</td>
<td><?= $cp->service_active_count; ?></td>
<td><?= sprintf('%.3f', $cp->service_active_latency_avg); ?>s</td>
<td><?= sprintf('%.3f', $cp->service_active_execution_avg); ?>s</td>
</tr>
</tbody>
</table>
<h3><?= $this->translate('Passive checks') ?></h3>
<table class="avp">
<tbody>
<tr>
<td>
<strong><?= $this->translate('Host Checks') ?></strong>
</td>
<td><?= $cp->host_passive_count; ?></td>
</tr>
<tr>
<td>
<strong><?= $this->translate('Service Checks') ?></strong>
</td>
<td><?= $cp->service_passive_count; ?></td>
</tr>
</tbody>
</table>
</div>
</div>
<?php else: ?>
<div class="backend-not-running">
<?= sprintf($this->translate('%s is not running'), $this->backendName) ?>
</div>
<?php endif ?>
<table class="avp">
<tbody>
<tr>
<th><?= $this->translate('Program Start Time') ?></th>
<td><?= $this->dateFormat()->formatDateTime($this->programStatus->program_start_time) ?></td>
</tr>
<tr>
<th><?= $this->translate('Last Status Update'); ?></th>
<td><?= $this->timeSince($this->programStatus->status_update_time) ?> ago</td>
</tr>
<tr>
<th><?= $this->translate('Last External Command Check'); ?></th>
<td><?= $this->timeSince($this->programStatus->last_command_check) ?> ago</td>
</tr>
<tr>
<th><?= $this->translate('Last Log File Rotation'); ?></th>
<td><?= $this->programStatus->last_log_rotation
? $this->timeSince($this->programStatus->last_log_rotation)
: $this->translate('N/A') ?></td>
</tr>
<tr>
<th><?= $this->translate('Global Service Event Handler'); ?></th>
<td><?= $this->programStatus->global_service_event_handler
? $this->programStatus->global_service_event_handler
: $this->translate('N/A'); ?></td>
</tr>
<tr>
<th><?= $this->translate('Global Host Event Handler'); ?></th>
<td><?= $this->programStatus->global_host_event_handler
? $this->programStatus->global_host_event_handler
: $this->translate('N/A'); ?></td>
</tr>
</tbody>
</table>
<hr>
<?= $this->toggleFeaturesForm ?>
</div>

View File

@ -5,13 +5,13 @@ $selfUrl = Url::fromPath('monitoring/show/services', array('host' => $this->obje
$currentUrl = Url::fromRequest()->without('limit')->getRelativeUrl();
?>
<h3 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : '' ?>>
<h1 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : '' ?>>
<?php if ($object->stats->services_total > 0): ?>
<?= $this->qlink(sprintf($this->translate('%s configured services:'), $object->stats->services_total), $selfUrl) ?>
<?php else: ?>
<?= $this->translate('No services configured on this host'); ?>
<?php endif; ?>
<span class="badges">
<?php if ($object->stats->services_ok > 0): ?>
<span class="state ok<?= $currentUrl === $selfUrl->with('service_state', 0)->getRelativeUrl() ? ' active' : '' ?>"><?= $this->qlink(
$object->stats->services_ok,
@ -84,5 +84,6 @@ foreach (array(2 => 'critical', 3 => 'unknown', 1 => 'warning') as $stateId => $
array('title' => sprintf($this->translate('Services with state %s'), strtoupper($this->translate('pending'))))
) ?></span>
<?php endif ?>
</h3>
</span>
</h1>

View File

@ -1,2 +1,5 @@
<div class="pluginoutput">
<h4>Pluginoutput</h4>
<?= $this->pluginOutput($object->output) ?>
<?= $this->pluginOutput($object->long_output) ?>
</div>

View File

@ -12,7 +12,7 @@ foreach ($object->servicegroups as $name => $alias) {
printf(
"<tr><th>%s</th><td>%s %s</td></tr>\n",
$this->translate('Servicegroups'),
$this->icon('service'),
$this->icon('services'),
implode(', ', $list)
);

View File

@ -23,7 +23,7 @@ $obj->passive_checks_enabled =
$i = array();
if (! $obj->handled && $obj->state > 0) {
$i[] = $this->icon('flash', $this->translate('Unhandled'));
$i[] = $this->icon('attention-alt', $this->translate('Unhandled'));
}
if ($obj->acknowledged && ! $obj->in_downtime) {

View File

@ -85,17 +85,17 @@ function contactsLink($match, $view) {
$msg = $this->escape($event->output);
break;
case 'hard_state':
$icon = $isService ? 'service' : 'host';
$msg = '[ ' . $event->attempt . '/' . $event->max_attempts . ' ] ' . $this->escape($event->output);
$stateClass = (
$isService
? strtolower($this->util()->getServiceStateName($event->state))
: strtolower($this->util()->getHostStateName($event->state))
);
$icon = 'attention-alt';
$title = strtoupper($stateClass); // TODO: Should be translatable!
break;
case 'soft_state':
$icon = 'softstate';
$icon = 'spinner';
$msg = '[ ' . $event->attempt . '/' . $event->max_attempts . ' ] ' . $this->escape($event->output);
$stateClass = (
$isService

View File

@ -2,4 +2,4 @@
<?= $this->render('show/components/header.phtml') ?>
<?= $this->render('show/components/hostservicesummary.phtml') ?>
</div>
<?= preg_replace('~<table data-base-target="_next"~', '<table data-base-target="_self"', $services) /* TODO: find an elegant solution for this */ ?>
<?= $services ?>

View File

@ -124,7 +124,7 @@ $section->add($this->translate('Timeline'))->setUrl('monitoring/timeline');
* Reporting Section
*/
$section = $this->menuSection($this->translate('Reporting'), array(
'icon' => 'chart-line',
'icon' => 'barchart',
'priority' => 100
));
@ -136,14 +136,10 @@ $section->add($this->translate('Alert Summary'), array(
* System Section
*/
$section = $this->menuSection($this->translate('System'));
$section->add($this->translate('Process Info'), array(
$section->add($this->translate('Monitoring Health'), array(
'url' => 'monitoring/process/info',
'priority' => 120
));
$section->add($this->translate('Performance Info'), array(
'url' => 'monitoring/process/performance',
'priority' => 130
));
/*
* Dashboard

View File

@ -24,6 +24,7 @@ class GroupSummaryQuery extends IdoQuery
'hostgroup' => 'hostgroup'
),
'servicestatussummary' => array(
'services_total' => 'SUM(CASE WHEN object_type = \'service\' THEN 1 ELSE 0 END)',
'services_ok' => 'SUM(CASE WHEN object_type = \'service\' AND state = 0 THEN 1 ELSE 0 END)',
'services_pending' => 'SUM(CASE WHEN object_type = \'service\' AND state = 99 THEN 1 ELSE 0 END)',
'services_warning' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 THEN 1 ELSE 0 END)',
@ -35,6 +36,14 @@ class GroupSummaryQuery extends IdoQuery
'services_warning_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 AND acknowledged + in_downtime + host_state = 0 THEN 1 ELSE 0 END)',
'services_critical_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 AND acknowledged + in_downtime + host_state = 0 THEN 1 ELSE 0 END)',
'services_unknown_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 AND acknowledged + in_downtime + host_state = 0 THEN 1 ELSE 0 END)',
'services_ok_last_state_change' => 'MAX(CASE WHEN object_type = \'service\' AND state = 0 THEN state_change ELSE 0 END)',
'services_pending_last_state_change' => 'MAX(CASE WHEN object_type = \'service\' AND state = 99 THEN state_change ELSE 0 END)',
'services_warning_last_state_change_handled' => 'MAX(CASE WHEN object_type = \'service\' AND state = 1 AND acknowledged + in_downtime + host_state > 0 THEN state_change ELSE 0 END)',
'services_critical_last_state_change_handled' => 'MAX(CASE WHEN object_type = \'service\' AND state = 2 AND acknowledged + in_downtime + host_state > 0 THEN state_change ELSE 0 END)',
'services_unknown_last_state_change_handled' => 'MAX(CASE WHEN object_type = \'service\' AND state = 3 AND acknowledged + in_downtime + host_state > 0 THEN state_change ELSE 0 END)',
'services_warning_last_state_change_unhandled' => 'MAX(CASE WHEN object_type = \'service\' AND state = 1 AND acknowledged + in_downtime + host_state = 0 THEN state_change ELSE 0 END)',
'services_critical_last_state_change_unhandled' => 'MAX(CASE WHEN object_type = \'service\' AND state = 2 AND acknowledged + in_downtime + host_state = 0 THEN state_change ELSE 0 END)',
'services_unknown_last_state_change_unhandled' => 'MAX(CASE WHEN object_type = \'service\' AND state = 3 AND acknowledged + in_downtime + host_state = 0 THEN state_change ELSE 0 END)',
'servicegroup' => 'servicegroup'
)
);
@ -57,7 +66,8 @@ class GroupSummaryQuery extends IdoQuery
$columns + array(
'state' => 'host_state',
'acknowledged' => 'host_acknowledged',
'in_downtime' => 'host_in_downtime'
'in_downtime' => 'host_in_downtime',
'state_change' => 'host_last_state_change'
)
);
if (in_array('servicegroup', $this->desiredColumns)) {
@ -68,7 +78,8 @@ class GroupSummaryQuery extends IdoQuery
$columns + array(
'state' => 'service_state',
'acknowledged' => 'service_acknowledged',
'in_downtime' => 'service_in_downtime'
'in_downtime' => 'service_in_downtime',
'state_change' => 'service_last_state_change'
)
);

View File

@ -207,7 +207,7 @@ abstract class MonitoredObjectController extends Controller
'services',
array(
'title' => 'Services',
'icon' => 'service',
'icon' => 'services',
'url' => 'monitoring/show/services',
'urlParams' => $params
)

View File

@ -1,6 +1,18 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
h1 {
font-size: 1em;
}
h2 {
font-size: 1em;
}
h3 {
font-size: 1em;
}
table.action.comments td p, table.action.downtimes td p {
margin: 0;
font-size: 0.8em;
@ -20,16 +32,21 @@ p.pluginoutput {
white-space: pre-wrap;
}
pre.pluginoutput {
font-family: Courier;
background: #eee;
font-size: 0.7em;
div.pluginoutput {
border-right: solid 5px @colorPetrol;
overflow: auto;
white-space: pre-wrap;
margin: 0em;
padding: 1em;
margin-bottom: 0.5em;
color: black;
margin-bottom: 1em;
padding: 0.2em;
}
div.pluginoutput h4 {
font-size: 0.875em;
margin: 0em;
}
div.pluginoutput pre{
white-space: pre-wrap;
}
table.objecthistory td {
@ -75,36 +92,32 @@ div.contacts div.notification-periods {
margin-top: 0.5em;
}
h3.tinystatesummary {
line-height: 2em;
font-size: 0.95em;
margin-right: 1em;
border-bottom: 2px solid @colorPetrol;
h1.tinystatesummary .badges {
display: inline-block;
margin-bottom: 4px;
margin-left: 1em;
}
h3.tinystatesummary a {
color: inherit;
text-decoration: none;
padding: 1px 3px;
h1.tinystatesummary .state > a {
color: white;
font-size: 0.8em;
padding: 2px 5px;
}
h3.tinystatesummary a:hover {
text-decoration: underline;
h1.tinystatesummary .state.handled a {
}
/* State badges */
span.state {
font-size: 1em;
font-weight: 700;
font-weight: bold;
color: white;
font-weight: bold;
padding: 1px 2px;
margin-right: 5px;
}
span.state.active {
border: 2px solid white;
border: 2px solid #555;
}
span.state span.state {
@ -156,5 +169,24 @@ table.avp .customvar ul {
}
div.selection-info {
padding-top:1em;
padding-top: 0.4em;
float: right;
cursor: help;
font-size: 0.8em;
}
.optionbox {
margin-left: 0em;
margin-right: 3em;
}
.optionbox label {
max-width: 6.5em;
text-align: left;
vertical-align: middle;
margin-right: 0em;
}
.optionbox input {
vertical-align: middle;
}

View File

@ -0,0 +1,38 @@
Alias /icingaweb "/usr/share/icingaweb/public"
<Directory "/usr/share/icingaweb/public">
Options SymLinksIfOwnerMatch
AllowOverride None
<IfModule mod_authz_core.c>
# Apache 2.4
<RequireAll>
Require all granted
</RequireAll>
</IfModule>
<IfModule !mod_authz_core.c>
# Apache 2.2
Order allow,deny
Allow from all
</IfModule>
SetEnv ICINGAWEB_CONFIGDIR "/etc/icingaweb"
EnableSendfile Off
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /icingaweb/
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
</IfModule>
<IfModule !mod_rewrite.c>
DirectoryIndex error_norewrite.html
ErrorDocument 404 /error_norewrite.html
</IfModule>
</Directory>

View File

@ -1,6 +1,6 @@
#!/usr/bin/php
<?php
define('ICINGAWEB_APPDIR', '/usr/share/icingaweb/application');
require_once 'Icinga/Application/Cli.php';
Icinga\Application\Cli::start()->dispatch();
require_once '/usr/share/php/Icinga/Application/Cli.php';
Icinga\Application\Cli::start('/usr/share/icingaweb')->dispatch();

View File

@ -1,19 +0,0 @@
Alias /icingaweb "/usr/share/icingaweb/public"
<Directory "/usr/share/icingaweb/public">
Options SymLinksIfOwnerMatch
AllowOverride None
Order allow,deny
Allow from all
# SetEnv ICINGAWEB_CONFIGDIR /etc/icingaweb
RewriteEngine on
RewriteBase /icingaweb/
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
</Directory>

View File

@ -1,6 +1,3 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
define('ICINGAWEB_APPDIR', dirname(__DIR__) . '/application');
require_once 'Icinga/Application/webrouter.php';
require_once '/usr/share/php/Icinga/Application/webrouter.php';

View File

@ -1,32 +0,0 @@
Alias /icingaweb "/usr/share/icingaweb2/public"
<Directory "/usr/share/icingaweb2/public">
Options SymLinksIfOwnerMatch
AllowOverride None
<IfModule mod_authz_core.c>
# Apache 2.4
<RequireAll>
Require all granted
</RequireAll>
</IfModule>
<IfModule !mod_authz_core.c>
# Apache 2.2
Order allow,deny
Allow from all
</IfModule>
SetEnv ICINGAWEB_CONFIGDIR /etc/icingaweb2
EnableSendfile Off
RewriteEngine on
RewriteBase /icingaweb/
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
</Directory>

View File

@ -1,6 +0,0 @@
[autologin]
backend = autologin
[internal_db_authentication]
backend = db
resource = internal_db

View File

@ -1,8 +0,0 @@
[localdb]
type = ido
resource = "ido"
[locallive]
disabled = "1"
type = livestatus
resource = livestatus

View File

@ -1,2 +0,0 @@
[icinga]
path = "/var/run/icinga2/cmd/icinga2.cmd"

View File

@ -1,28 +0,0 @@
[internal_db]
type = db
db = mysql
host = localhost
port = 3306
password = icingaweb
username = icingaweb
dbname = icingaweb
[ido]
type = db
db = mysql
host = localhost
port = 3306
password = icinga
username = icinga
dbname = icinga
[livestatus]
type = livestatus
socket = /var/run/icinga2/cmd/livestatus
[logfile]
type = file
filename = "/var/log/icingaweb2/icingaweb2.log"
fields = "/^(?<datetime>[0-9]{4}(-[0-9]{2}){2}T[0-9]{2}(:[0-9]{2}){2}(\\+[0-9]{2}:[0-9]{2})?) - (?<loglevel>[A-Za-z]+) - (?<message>.*)$/"
; format: PCRE
;

View File

@ -1,6 +0,0 @@
#!/usr/bin/php
<?php
use Icinga\Application\Cli;
require_once '/usr/share/icingaweb2/library/Icinga/Application/Cli.php';
Cli::start()->dispatch();

View File

@ -49,6 +49,52 @@ a:hover {
text-decoration: underline;
}
/* W3C Recommendation <http://www.w3.org/TR/CSS21/sample.html> (except h4) */
h1 {
font-size: 2em;
color: @colorTextDefault;
border-bottom: 2px solid @colorPetrol;
}
h2 {
font-size: 1.5em;
color: @colorPetrol;
}
h3 {
font-size: 1.17em;
color: @colorTextDefault;
border-bottom: 1px solid @colorPetrol;
}
h4 {
font-size: 1em;
color: @colorPetrol;
}
h5 {
font-size: .83em;
border-bottom: 1px solid @colorPetrol;
}
h6 {
font-size: .75em;
color: @colorPetrol;
}
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
text-decoration: none;
color: inherit;
}
h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover {
text-decoration: underline;
}
button {
font-family: inherit;
}
#fontsize-calc {
display: none;
width: 1000em;

View File

@ -124,12 +124,6 @@ html {
z-index: 100;
}
.controls h1 {
font-size: 1.5em;
margin-bottom: 0.2em;
border-bottom: 1px solid black;
}
.container .fake-controls {
padding: 0;
}
@ -152,13 +146,6 @@ html {
margin-left: 1%;
}
.dashboard > div.container h1, .container .content h1, .container .controls h1, .content h3 {
line-height: 2em;
font-size: 1em;
color: @colorTextDefault;
border-bottom: 2px solid @colorPetrol;
}
.content h3 {
font-size: 0.9em;
}
@ -167,24 +154,10 @@ html {
margin-left: 1em;
}
.container .controls h1 {
margin-left: 1em;
margin-right: 1em;
}
.container .controls .pagination {
margin-left: 1.2em;
}
.dashboard > div.container h1 a {
text-decoration: none;
color: inherit;
}
.dashboard > div.container h1 a:hover {
text-decoration: underline;
}
.content {
padding: 1em;
}

View File

@ -39,18 +39,17 @@
.form {
position: absolute;
font-size: 0.9em;
top: 50%;
top: 45%;
left: 0;
bottom: 0;
right: 0;
}
.form h1 {
text-align: left;
text-align: center;
font-size: 1.5em;
margin-left: auto;
margin-right: auto;
width: 12em;
margin-left: 2.3em;
border: none;
color: @colorTextDefault;
}
@ -75,7 +74,7 @@
form {
margin-left: auto;
margin-right: auto;
width: 40em;
width: 35em;
}
form input {
@ -108,9 +107,10 @@
}
.footer {
margin-top: 2em;
margin-top: 7em;
font-size: 0.9em;
text-align: center;
text-align: center;
margin-left: 5em;
}
div.config-note {

View File

@ -170,6 +170,35 @@ table.benchmark {
width: 96%;
}
.dashboard h1 {
font-size: 1em;
}
.dashboard h2 {
font-size: 1em;
}
.dashboard h3 {
font-size: 1em;
}
.dashboard table.benchmark {
font-size: 0.9em;
}
.left {
text-align: left !important;
}
.controls a {
color: inherit;
}
/* controls have no padding as of tabs */
.controls > h1 {
margin-right: 1em;
}
[class^="icon-"]:before, [class*=" icon-"]:before {
text-decoration: none;
}

View File

@ -194,8 +194,12 @@ tr.state.handled td.state {
}
/* HOVER colors */
tr[href]:hover {
color: black;
background-color: #eee;
}
tr[href]:hover, tr.state[href]:hover td.state {
tr.state[href]:hover td.state {
color: white;
background-color: #eee;
}
@ -311,6 +315,13 @@ a.critical {
.boxview div.box h2:first-child > a:hover {
}
.boxview div.box h3 {
line-height: 1.5em;
font-size: 0.9em;
color: #555;
border-bottom: 1px solid #d9d9d9;
}
/* Box body of contents */
.boxview div.box.contents {
padding: 0.2em;
@ -810,9 +821,125 @@ div.timeline {
/* End of monitoring timeline styles */
.controls {
font-size: 0.9em;
}
.controls a {
color: black;
/* Monitoring groupsummary styles */
table.groupview {
width: 100%;
margin-top: 1em;
border-collapse: separate;
border-spacing: 0.1em;
thead th {
font-size: 0.9em;
}
tbody {
tr {
&:hover {
color: #333;
}
a {
color: #333;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
td.services-total {
width: 10%;
text-align: center;
}
td.state {
width: 10%;
color: white;
text-align: center;
&.change {
width: 10%;
white-space: nowrap;
padding: 0.3em 0.5em 0.3em 0.5em;
strong {
font-size: 0.8em;
}
span.timesince {
font-size: 0.8em;
}
}
&.ok {
color: #333;
border-left-style: solid;
border-left-width: 1.5em;
border-color: @colorOk;
}
&.pending {
color: #333;
border-left-style: solid;
border-left-width: 1.5em;
border-color: @colorPending;
}
&.warning {
background-color: @colorWarning;
&.handled {
background-color: inherit;
color: #333;
border-left-style: solid;
border-left-width: 1.5em;
border-color: @colorWarningHandled;
}
}
&.unknown {
background-color: @colorUnknown;
&.handled {
color: #333;
background-color: inherit;
border-left-style: solid;
border-left-width: 1.5em;
border-color: @colorUnknownHandled;
}
}
&.critical {
background-color: @colorCritical;
&.handled {
color: #333;
background-color: inherit;
border-left-style: solid;
border-left-width: 1.5em;
border-color: @colorCriticalHandled;
}
}
span {
&.no-state {
color: #333;
}
&.state {
&.handled {
margin-right: 2px;
}
a {
color: white;
}
}
}
}
}
}
/* End of monitoring groupsummary styles */

View File

@ -251,3 +251,7 @@ li li .badge {
.badge-pending {
background-color: @colorUnknown;
}
.widgetFilter li.active {
background-color: #eee;
}

View File

@ -131,7 +131,8 @@ class DashboardTest extends BaseTestCase
*/
public function testLoadPaneItemsProvidedByEnabledModules()
{
$dashboard = Dashboard::load();
$dashboard = new Dashboard();
$dashboard->load();
$this->assertCount(
1,
@ -270,71 +271,15 @@ class DashboardTest extends BaseTestCase
$component2 = new Component('test2', 'test2', $pane);
$pane->addComponent($component2);
$dashboard->removeComponent('test1', 'test');
$dashboard->getPane('test1')->removeComponent('test');
$result = $dashboard->getPane('test1')->hasComponent('test');
$this->assertFalse(
$this->assertTrue(
$result,
'Dashboard::removeComponent() could not remove component from the pane'
);
}
/**
* @depends testWhetherGetPaneReturnsAPaneByName
*/
public function testWhetherRemoveComponentRemovesComponentByConcatenation()
{
$dashboard = new Dashboard();
$dashboard->createPane('test1');
$pane = $dashboard->getPane('test1');
$component = new Component('test', 'test', $pane);
$pane->addComponent($component);
$component2 = new Component('test2', 'test2', $pane);
$pane->addComponent($component2);
$dashboard->removeComponent('test1.test', null);
$result = $dashboard->getPane('test1')->hasComponent('test');
$this->assertFalse(
$result,
'Dashboard::removeComponent() could not remove component from the pane'
);
}
/**
* @depends testWhetherGetPaneReturnsAPaneByName
*/
public function testWhetherToArrayReturnsDashboardStructureAsArray()
{
$dashboard = new Dashboard();
$dashboard->createPane('test1');
$pane = $dashboard->getPane('test1');
$component = new Component('test', 'test', $pane);
$pane->addComponent($component);
$result = $dashboard->toArray();
$expected = array(
'test1' => array(
'title' => 'test1'
),
'test1.test' => array(
'url' => 'test'
)
);
$this->assertEquals(
$expected,
$result,
'Dashboard::toArray() could not return valid expectation'
);
}
/**
* @depends testWhetherGetPaneReturnsAPaneByName
*/
@ -346,7 +291,7 @@ class DashboardTest extends BaseTestCase
$component = new Component('test', 'test', $pane);
$pane->addComponent($component);
$dashboard->setComponentUrl('test1', 'test', 'new');
$dashboard->getPane('test1')->getComponent('test')->setUrl('new');
$this->assertEquals(
'new',
@ -355,48 +300,6 @@ class DashboardTest extends BaseTestCase
);
}
/**
* @depends testWhetherGetPaneReturnsAPaneByName
*/
public function testWhetherSetComponentUrlUpdatesTheComponentUrlConcatenation()
{
$dashboard = new Dashboard();
$dashboard->createPane('test1');
$pane = $dashboard->getPane('test1');
$component = new Component('test', 'test', $pane);
$pane->addComponent($component);
$dashboard->setComponentUrl('test1.test', null, 'new');
$this->assertEquals(
'new',
$component->getUrl()->getPath(),
'Dashboard::setComponentUrl() could not return valid expectation'
);
}
/**
* @depends testWhetherGetPaneReturnsAPaneByName
*/
public function testWhetherSetComponentUrlUpdatesTheComponentUrlNotExistentPane()
{
$dashboard = new Dashboard();
$dashboard->createPane('test1');
$pane = $dashboard->getPane('test1');
$component = new Component('test', 'test', $pane);
$pane->addComponent($component);
$dashboard->setComponentUrl('test3.test', null, 'new');
$result = $dashboard->getPane('test3')->getComponent('test');
$this->assertEquals(
'new',
$result->getUrl()->getPath(),
'Dashboard::setComponentUrl() could not return valid expectation'
);
}
/**
* @expectedException \Icinga\Exception\ConfigurationError
*/