Add ModulePage

refs #7163
This commit is contained in:
Johannes Meyer 2014-10-24 17:10:17 +02:00
parent 851682cf18
commit 2f83976f50
6 changed files with 301 additions and 5 deletions

View File

@ -0,0 +1,142 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Setup;
use InvalidArgumentException;
use Icinga\Application\Icinga;
use Icinga\Web\Form;
use Icinga\Web\Session;
use Icinga\Web\Request;
class ModulePage extends Form
{
protected $session;
protected $wizards;
protected $modules;
protected $modulePaths;
/**
* Initialize this page
*/
public function init()
{
$this->setName('setup_modules');
$this->setViewScript('form/setup-modules.phtml');
$this->session = Session::getSession()->getNamespace(get_class($this));
}
public function setModulePaths(array $availableDirs)
{
$this->modulePaths = $availableDirs;
}
public function handleRequest(Request $request = null)
{
if ($this->wasSent($this->getRequestData($request))) {
if (($newModule = $request->getPost('module')) !== null) {
$this->setCurrentModule($newModule);
$this->getResponse()->redirectAndExit($this->getRedirectUrl());
} else {
// The user submitted this form but with the parent wizard's navigation
// buttons so it's now up to the parent wizard to handle the request..
}
} else {
$wizard = $this->getCurrentWizard();
$wizardPage = $wizard->getForm();
if (false === $wizard->isFinished() || $wizardPage->wasSent($wizardPage->getRequestData($request))) {
$wizard->handleRequest($request);
} elseif ($wizard->isFinished()) {
$wizards = $this->getWizards();
$newModule = null;
foreach ($wizards as $moduleName => $moduleWizard) {
if (false === $moduleWizard->isFinished()) {
$newModule = $moduleName;
}
}
if ($newModule === null) {
// In case all module wizards were completed just pick the first one again
reset($wizards);
$newModule = key($wizards);
}
$this->setCurrentModule($newModule);
}
}
}
public function clearSession()
{
$this->session->clear();
foreach ($this->getWizards() as $wizard) {
$wizard->clearSession();
}
}
public function setCurrentModule($moduleName)
{
if (false === array_key_exists($moduleName, $this->getWizards())) {
throw new InvalidArgumentException(sprintf('Module "%s" does not provide a setup wizard', $moduleName));
}
$this->session->currentModule = $moduleName;
}
public function getCurrentModule()
{
$moduleName = $this->session->get('currentModule');
if ($moduleName === null) {
$moduleName = key($this->getWizards());
$this->setCurrentModule($moduleName);
}
return $moduleName;
}
public function getCurrentWizard()
{
$wizards = $this->getWizards();
return $wizards[$this->getCurrentModule()];
}
public function getModules()
{
if ($this->modules !== null) {
return $this->modules;
} else {
$this->modules = array();
}
$moduleManager = Icinga::app()->getModuleManager();
$moduleManager->detectInstalledModules($this->modulePaths);
foreach ($moduleManager->listInstalledModules() as $moduleName) {
$this->modules[] = $moduleManager->loadModule($moduleName)->getModule($moduleName);
}
return $this->modules;
}
public function getWizards()
{
if ($this->wizards !== null) {
return $this->wizards;
} else {
$this->wizards = array();
}
foreach ($this->getModules() as $module) {
if ($module->providesSetupWizard()) {
$this->wizards[$module->getName()] = $module->getSetupWizard();
}
}
return $this->wizards;
}
}

View File

@ -0,0 +1,47 @@
<?php
use Icinga\Web\Wizard;
?>
<div class="module-menu">
<p><?= t('The following modules are available for installation using a web-based wizard as well. To install a module, just complete it\'s wizard and advance to the summary!'); ?></p>
<p><?= t('You can freely switch to a module\'s wizard by clicking it\'s name below. The wizard you are currently looking at is written in bold. A small tick is shown on the right once a wizard has been completed.'); ?></p>
<form name="<?= $form->getName(); ?>" enctype="<?= $form->getEncType(); ?>" method="<?= $form->getMethod(); ?>">
<?= $form->getElement($form->getTokenElementName()); ?>
<?= $form->getElement($form->getUidElementName()); ?>
<ul>
<?php $allFinished = true; ?>
<?php foreach ($form->getModules() as $module): ?>
<?php if ($module->providesSetupWizard()): ?>
<li>
<?php $isActive = $module->getName() === $form->getCurrentModule(); ?>
<button type="submit" name="module" value="<?= $module->getName(); ?>">
<?= $isActive ? '<strong>' : '' ?><?= $module->getTitle(); ?><?= $isActive ? '</strong>' : '' ?>
</button>
<?php if ($module->getSetupWizard()->isFinished()): ?>
<?= $this->icon('acknowledgement.png', t('Completed', 'setup.modules.wizard.state')); ?>
<?php else: ?>
<?php $allFinished = false; ?>
<?php endif ?>
</li>
<?php endif ?>
<?php endforeach ?>
</ul>
</form>
<?php if ($allFinished): ?>
<p class="all-completed"><?= t('You\'ve completed all module wizards!'); ?></p>
<?php else: ?>
<p style="font-size: 80%;"><?= t('Note that you can skip a specific module by just not completing it\'s wizard.'); ?></p>
<?php endif ?>
</div>
<div class="module-wizard">
<?= $form->getCurrentWizard()->getForm()->render(); ?>
</div>
<form name="<?= $form->getName(); ?>" enctype="<?= $form->getEncType(); ?>" method="<?= $form->getMethod(); ?>">
<?= $form->getElement($form->getTokenElementName()); ?>
<?= $form->getElement($form->getUidElementName()); ?>
<div class="buttons">
<?= $form->getElement(Wizard::BTN_PREV); ?>
<?= $form->getElement(Wizard::BTN_NEXT); ?>
</div>
</form>

View File

@ -2,7 +2,7 @@
$pages = $wizard->getPages();
$finished = isset($success);
$configPages = array_slice($pages, 2, count($pages) - 3, true);
$configPages = array_slice($pages, 2, count($pages) - 4, true);
$currentPos = array_search($wizard->getCurrentPage(), $pages, true);
list($configPagesLeft, $configPagesRight) = array_chunk($configPages, count($configPages) / 2, true);
@ -41,7 +41,7 @@ $maxProgress = @max(array_keys(array_filter(
<td class="right"><div class="line right<?= $stateClass; ?>"></div></td>
</tr></tbody></table>
</div>
<div class="step" style="width: 60%;">
<div class="step" style="width: 50%;">
<h1><?= t('Configuration', 'setup.progress'); ?></h1>
<table><tbody><tr>
<td class="left">
@ -92,6 +92,17 @@ $maxProgress = @max(array_keys(array_filter(
</td>
</tr></tbody></table>
</div>
<div class="step" style="width: 10%;">
<h1><?= t('Modules', 'setup.progress'); ?></h1>
<?php $stateClass = $finished || $currentPos > count($pages) - 2 ? ' complete' : (
$maxProgress > count($pages) - 2 ? ' visited' : ($currentPos === count($pages) - 2 ? ' active' : '')
); ?>
<table><tbody><tr>
<td class="left"><div class="line left<?= $stateClass; ?>"></div></td>
<td class="middle"><div class="bubble<?= $stateClass; ?>"></div></td>
<td class="right"><div class="line right<?= $stateClass; ?>"></div></td>
</tr></tbody></table>
</div>
<div class="step" style="width: 10%;">
<h1><?= t('Summary', 'setup.progress'); ?></h1>
<?php $stateClass = $finished ? ' complete' : ($currentPos === count($pages) - 1 ? ' active' : ''); ?>

View File

@ -5,6 +5,7 @@
namespace Icinga\Application;
use PDOException;
use Icinga\Form\Setup\ModulePage;
use Icinga\Form\Setup\WelcomePage;
use Icinga\Form\Setup\SummaryPage;
use Icinga\Form\Setup\DbResourcePage;
@ -72,6 +73,7 @@ class WebSetup extends Wizard implements SetupWizard
$this->addPage(new AdminAccountPage());
$this->addPage(new GeneralConfigPage());
$this->addPage(new DatabaseCreationPage());
$this->addPage(new ModulePage());
$this->addPage(new SummaryPage());
}
@ -140,6 +142,16 @@ class WebSetup extends Wizard implements SetupWizard
unset($pageData['setup_admin_account']);
unset($pageData['setup_authentication_backend']);
}
} elseif ($page->getName() === 'setup_modules') {
$configData = $this->getPageData('setup_general_config');
$page->setModulePaths(explode(':', $configData['global_modulePath']));
$page->handleRequest($request);
} elseif ($page->getName() === 'setup_general_config' && $this->getDirection() === static::FORWARD) {
$configData = $this->getPageData($page->getName());
if ($configData !== null && $request->getPost('global_modulePath') !== $configData['global_modulePath']) {
// Drop the ModulePage's session and all associated wizard sessions once the module path changes
$this->getPage('setup_modules')->clearSession();
}
}
}
@ -221,6 +233,15 @@ class WebSetup extends Wizard implements SetupWizard
}
}
/**
* @see Wizard::clearSession()
*/
public function clearSession()
{
parent::clearSession();
$this->getPage('setup_modules')->clearSession();
}
/**
* @see SetupWizard::getInstaller()
*/
@ -295,6 +316,12 @@ class WebSetup extends Wizard implements SetupWizard
);
}
foreach ($this->getPage('setup_modules')->getWizards() as $wizard) {
if ($wizard->isFinished()) {
$installer->addSteps($wizard->getInstaller()->getSteps());
}
}
return $installer;
}
@ -415,6 +442,10 @@ class WebSetup extends Wizard implements SetupWizard
)
);
foreach ($this->getPage('setup_modules')->getWizards() as $wizard) {
$requirements->merge($wizard->getRequirements()->allOptional());
}
return $requirements;
}

View File

@ -18,6 +18,7 @@ $this->provideConfigTab('security', array(
'title' => 'Security',
'url' => 'config/security'
));
$this->provideSetupWizard('Icinga\Module\Monitoring\Setup');
/*
* Available Search Urls

View File

@ -123,7 +123,7 @@
border: 1px dotted black;
}
&:hover, &:focus {
&:hover, &:focus, &:active {
background-color: #333;
&[disabled="1"] {
@ -136,7 +136,7 @@
color: #fffafa;
background: #aaa;
&:hover, &:focus {
&:hover, &:focus, &:active {
background: #888;
}
}
@ -305,3 +305,67 @@
border: 1px solid lightgrey;
}
}
#setup {
div.module-wizard {
width: auto;
padding: 1em;
overflow: hidden;
border-radius: 1em;
background-color: #f4f4f4;
div.buttons button[type=submit] {
padding: 0.5em;
line-height: 0.5em;
background-color: #888;
&:hover, &:focus, &:active {
background-color: #666;
}
}
}
div.module-menu {
width: 25%;
float: right;
margin-left: 1.5em;
p {
margin-top: 0;
&.all-completed {
.conspicuous-state-notification;
text-align: center;
font-size: 90%;
background-color: @colorOk;
}
}
ul {
padding-left: 1.2em;
button {
margin: 0 0 0.8em;
padding: 0;
color: black;
border: none;
outline: none;
font-size: 90%;
background-color: inherit;
&:hover {
color: #666;
cursor: pointer;
}
&:focus, &:active {
color: #666;
}
}
img {
margin: 0 0.5em 0.2em;
}
}
}
}