config/modules: show metadata, improve usability

Well... I didn't want to commit this before creating single-button
forms for enabling/disabling modules. However part of this accidentally
made it through, so let's finish it.

Still some work to do, but it already looks far better like this.

refs 
This commit is contained in:
Thomas Gelf 2014-06-21 02:27:27 +02:00
parent 747083d322
commit 78193137f0
6 changed files with 74 additions and 43 deletions
application
controllers
views/scripts/config
library/Icinga/Data/DataArray
public/js/icinga

View File

@ -27,23 +27,24 @@
*/ */
// {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}}
use \Icinga\Web\Controller\BaseConfigController; use Icinga\Web\Controller\BaseConfigController;
use \Icinga\Web\Widget\Tab; use Icinga\Web\Widget\Tab;
use \Icinga\Web\Widget\AlertMessageBox; use Icinga\Web\Widget\AlertMessageBox;
use Icinga\Web\Notification; use Icinga\Web\Notification;
use Icinga\Application\Modules\Module; use Icinga\Application\Modules\Module;
use \Icinga\Web\Url; use Icinga\Web\Url;
use \Icinga\Application\Icinga; use Icinga\Web\Widget;
use \Icinga\Application\Config as IcingaConfig; use Icinga\Application\Icinga;
use \Icinga\Data\ResourceFactory; use Icinga\Application\Config as IcingaConfig;
use \Icinga\Form\Config\GeneralForm; use Icinga\Data\ResourceFactory;
use \Icinga\Form\Config\Authentication\ReorderForm; use Icinga\Form\Config\GeneralForm;
use \Icinga\Form\Config\Authentication\LdapBackendForm; use Icinga\Form\Config\Authentication\ReorderForm;
use \Icinga\Form\Config\Authentication\DbBackendForm; use Icinga\Form\Config\Authentication\LdapBackendForm;
use \Icinga\Form\Config\ResourceForm; use Icinga\Form\Config\Authentication\DbBackendForm;
use \Icinga\Form\Config\LoggingForm; use Icinga\Form\Config\ResourceForm;
use \Icinga\Form\Config\ConfirmRemovalForm; use Icinga\Form\Config\LoggingForm;
use \Icinga\Config\PreservingIniWriter; use Icinga\Form\Config\ConfirmRemovalForm;
use Icinga\Config\PreservingIniWriter;
/** /**
@ -158,8 +159,7 @@ class ConfigController extends BaseConfigController
$this->view->modules = Icinga::app()->getModuleManager()->select() $this->view->modules = Icinga::app()->getModuleManager()->select()
->from('modules') ->from('modules')
->order('enabled', 'desc') ->order('enabled', 'desc')
->order('name'); ->order('name')->paginate();
$this->render('module/overview');
} }
public function moduleAction() public function moduleAction()
@ -168,11 +168,17 @@ class ConfigController extends BaseConfigController
$app = Icinga::app(); $app = Icinga::app();
$manager = $app->getModuleManager(); $manager = $app->getModuleManager();
if ($manager->hasInstalled($name)) { if ($manager->hasInstalled($name)) {
$this->view->moduleData = Icinga::app()->getModuleManager()->select()
->from('modules')->where('name', $name)->fetchRow();
$module = new Module($app, $name, $manager->getModuleDir($name)); $module = new Module($app, $name, $manager->getModuleDir($name));
$this->view->module = $module; $this->view->module = $module;
} else { } else {
$this->view->module = false; $this->view->module = false;
} }
$this->view->tabs = Widget::create('tabs')->add('info', array(
'url' => Url::fromRequest(),
'title' => 'Module info'
))->activate('info');
} }
/** /**
@ -186,7 +192,10 @@ class ConfigController extends BaseConfigController
$manager->enableModule($module); $manager->enableModule($module);
$manager->loadModule($module); $manager->loadModule($module);
Notification::success('Module "' . $module . '" enabled'); Notification::success('Module "' . $module . '" enabled');
$this->redirectNow('config/modules_render=layout&_reload=css'); $this->redirectNow(Url::fromPath('config/modules', array(
'_render' => 'layout',
'_reload' => 'css'
)));
return; return;
} catch (Exception $e) { } catch (Exception $e) {
$this->view->exceptionMesssage = $e->getMessage(); $this->view->exceptionMesssage = $e->getMessage();
@ -206,7 +215,10 @@ class ConfigController extends BaseConfigController
try { try {
$manager->disableModule($module); $manager->disableModule($module);
Notification::success('Module "' . $module . '" disabled'); Notification::success('Module "' . $module . '" disabled');
$this->redirectNow('config/modules?_render=layout&_reload=css'); $this->redirectNow(Url::fromPath('config/modules', array(
'_render' => 'layout',
'_reload' => 'css'
)));
return; return;
} catch (Exception $e) { } catch (Exception $e) {
$this->view->exceptionMessage = $e->getMessage(); $this->view->exceptionMessage = $e->getMessage();

View File

@ -9,6 +9,7 @@
$dependencies = $module->getDependencies(); $dependencies = $module->getDependencies();
$restrictions = $module->getProvidedRestrictions(); $restrictions = $module->getProvidedRestrictions();
$permissions = $module->getProvidedPermissions(); $permissions = $module->getProvidedPermissions();
$state = $moduleData->enabled ? ($moduleData->loaded ? 'enabled' : 'failed') : 'disabled'
?> ?>
<h1><?= $this->escape($module->getTitle()) ?></h1> <h1><?= $this->escape($module->getTitle()) ?></h1>
@ -17,6 +18,19 @@ $permissions = $module->getProvidedPermissions();
<th><?= $this->escape('Name') ?></th> <th><?= $this->escape('Name') ?></th>
<td><?= $this->escape($module->getName()) ?></td> <td><?= $this->escape($module->getName()) ?></td>
</tr> </tr>
<tr>
<th><?= $this->translate('State') ?></th>
<td><?= $state ?><?php if ($state === 'enabled'): ?>
<?= $this->qlink('disable', 'config/moduledisable', array(
'name' => $module->getName()
)) ?>
<?php endif ?>
<?php if ($state === 'disabled'): ?>
<?= $this->qlink('enable', 'config/moduleenable', array(
'name' => $module->getName()
)) ?>
<?php endif ?>
</td>
<tr> <tr>
<th><?= $this->escape('Version') ?></th> <th><?= $this->escape('Version') ?></th>
<td><?= $this->escape($module->getVersion()) ?></td></tr> <td><?= $this->escape($module->getVersion()) ?></td></tr>

View File

@ -1,25 +1,10 @@
<?php
use Icinga\Web\Url;
$this->modules->limit(10);
$modules = $this->modules->paginate();
?>
<div class="controls"> <div class="controls">
<?= $this->tabs->render($this); ?> <?= $this->tabs ?>
<h1>Installed Modules</h1>
<?= $this->paginationControl($modules) ?>
</div> </div>
<div class="content"> <div class="content">
<h3>Installed Modules</h3>
<?php if (isset($this->messageBox)): ?>
<?= $this->messageBox->render() ?>
<?php endif ?>
<?= $this->paginationControl($modules, null, null, array(
'preserve' => $this->preserve
));
?>
<table class="action" data-base-target="_next"> <table class="action" data-base-target="_next">
<tbody> <tbody>
<?php foreach ($modules as $module): ?> <?php foreach ($modules as $module): ?>
@ -30,9 +15,12 @@ $modules = $this->modules->paginate();
<?php else: ?> <?php else: ?>
<?= $this->icon('remove.png', 'Module is disabled') ?> <?= $this->icon('remove.png', 'Module is disabled') ?>
<? endif ?> <? endif ?>
<a href="<?= $this->url('config/module/', array('name' => $module->name)) ?>"><?= $this->escape($module->name); ?></a> <a href="<?= $this->url(
(<?= 'config/module/',
$module->enabled ? ($module->loaded ? 'enabled' : 'failed') : 'disabled' ?>) array('name' => $module->name)
) ?>"><?= $this->escape($module->name); ?></a> (<?=
$module->enabled ? ($module->loaded ? 'enabled' : 'failed') : 'disabled'
?>)
</td> </td>
</tr> </tr>
<? endforeach ?> <? endforeach ?>

View File

@ -57,6 +57,15 @@ class ArrayDatasource implements Selectable
return $result; return $result;
} }
public function fetchRow(SimpleQuery $query)
{
$result = $this->getResult($query);
if (empty($result)) {
return false;
}
return $result[0];
}
public function fetchAll(SimpleQuery $query) public function fetchAll(SimpleQuery $query)
{ {
return $this->getResult($query); return $this->getResult($query);

View File

@ -71,7 +71,6 @@
icinga.logger.debug('Pushing current state to history'); icinga.logger.debug('Pushing current state to history');
var url = ''; var url = '';
var blacklist = ['_render', '_reload'];
// We only store URLs of containers sitting directly under #main: // We only store URLs of containers sitting directly under #main:
$('#main > .container').each(function (idx, container) { $('#main > .container').each(function (idx, container) {
@ -90,7 +89,7 @@
// Did we find any URL? Then push it! // Did we find any URL? Then push it!
if (url !== '') { if (url !== '') {
window.history.pushState({icinga: true}, null, url); window.history.pushState({icinga: true}, null, this.cleanupUrl(url));
} }
}, },
@ -99,7 +98,13 @@
if (!this.enabled) { if (!this.enabled) {
return; return;
} }
window.history.pushState({icinga: true}, null, url); window.history.pushState({icinga: true}, null, this.cleanupUrl(url));
},
cleanupUrl: function(url) {
url = url.replace(/_render=[a-z0-9]+&/, '').replace(/&_render=[a-z0-9]+/, '').replace(/\?_render=[a-z0-9]+$/, '');
url = url.replace(/_reload=[a-z0-9]+&/, '').replace(/&_reload=[a-z0-9]+/, '').replace(/\?_reload=[a-z0-9]+$/, '');
return url;
}, },
/** /**

View File

@ -343,6 +343,9 @@
delete this.requests[req.$target.attr('id')]; delete this.requests[req.$target.attr('id')];
req.$target = $('#' + target); req.$target = $('#' + target);
// We assume target === 'layout' right now. This might not be correct
this.icinga.ui.layout1col();
newBody = true; newBody = true;
} }