From 2f83976f500f694c796057d0e4f70264cd710210 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Fri, 24 Oct 2014 17:10:17 +0200 Subject: [PATCH] Add ModulePage refs #7163 --- application/forms/Setup/ModulePage.php | 142 ++++++++++++++++++ .../views/scripts/form/setup-modules.phtml | 47 ++++++ application/views/scripts/setup/index.phtml | 15 +- library/Icinga/Application/WebSetup.php | 31 ++++ modules/monitoring/configuration.php | 1 + public/css/icinga/setup.less | 70 ++++++++- 6 files changed, 301 insertions(+), 5 deletions(-) create mode 100644 application/forms/Setup/ModulePage.php create mode 100644 application/views/scripts/form/setup-modules.phtml diff --git a/application/forms/Setup/ModulePage.php b/application/forms/Setup/ModulePage.php new file mode 100644 index 000000000..9d0e6d145 --- /dev/null +++ b/application/forms/Setup/ModulePage.php @@ -0,0 +1,142 @@ +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; + } +} diff --git a/application/views/scripts/form/setup-modules.phtml b/application/views/scripts/form/setup-modules.phtml new file mode 100644 index 000000000..291d7d2ea --- /dev/null +++ b/application/views/scripts/form/setup-modules.phtml @@ -0,0 +1,47 @@ + +
+

+

+
+ getElement($form->getTokenElementName()); ?> + getElement($form->getUidElementName()); ?> +
    + + getModules() as $module): ?> + providesSetupWizard()): ?> +
  • + getName() === $form->getCurrentModule(); ?> + + getSetupWizard()->isFinished()): ?> + icon('acknowledgement.png', t('Completed', 'setup.modules.wizard.state')); ?> + + + +
  • + + +
+
+ +

+ +

+ +
+
+ getCurrentWizard()->getForm()->render(); ?> +
+
+ getElement($form->getTokenElementName()); ?> + getElement($form->getUidElementName()); ?> +
+ getElement(Wizard::BTN_PREV); ?> + getElement(Wizard::BTN_NEXT); ?> +
+
\ No newline at end of file diff --git a/application/views/scripts/setup/index.phtml b/application/views/scripts/setup/index.phtml index 396f05ea5..ac6d7a8f4 100644 --- a/application/views/scripts/setup/index.phtml +++ b/application/views/scripts/setup/index.phtml @@ -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(
-
+

@@ -92,6 +92,17 @@ $maxProgress = @max(array_keys(array_filter(
+
+

+ count($pages) - 2 ? ' complete' : ( + $maxProgress > count($pages) - 2 ? ' visited' : ($currentPos === count($pages) - 2 ? ' active' : '') + ); ?> + + + + +
+

diff --git a/library/Icinga/Application/WebSetup.php b/library/Icinga/Application/WebSetup.php index e04ac0db5..c14526296 100644 --- a/library/Icinga/Application/WebSetup.php +++ b/library/Icinga/Application/WebSetup.php @@ -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; } diff --git a/modules/monitoring/configuration.php b/modules/monitoring/configuration.php index edcd37a24..693cb8e9e 100644 --- a/modules/monitoring/configuration.php +++ b/modules/monitoring/configuration.php @@ -18,6 +18,7 @@ $this->provideConfigTab('security', array( 'title' => 'Security', 'url' => 'config/security' )); +$this->provideSetupWizard('Icinga\Module\Monitoring\Setup'); /* * Available Search Urls diff --git a/public/css/icinga/setup.less b/public/css/icinga/setup.less index 353e31502..9a3857b05 100644 --- a/public/css/icinga/setup.less +++ b/public/css/icinga/setup.less @@ -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; } } @@ -304,4 +304,68 @@ background-color: #eee; border: 1px solid lightgrey; } -} \ No newline at end of file +} + +#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; + } + } + } +}