diff --git a/.puppet/profiles/icingaweb2_dev/manifests/init.pp b/.puppet/profiles/icingaweb2_dev/manifests/init.pp index b8bea040f8..33f29df3b6 100644 --- a/.puppet/profiles/icingaweb2_dev/manifests/init.pp +++ b/.puppet/profiles/icingaweb2_dev/manifests/init.pp @@ -90,7 +90,7 @@ source => $name, } - icingaweb2::config::general { [ 'config', 'resources' ]: + icingaweb2::config::general { [ 'config', 'resources', 'roles' ]: source => $name, replace => false, } diff --git a/.puppet/profiles/icingaweb2_dev/templates/roles.ini.erb b/.puppet/profiles/icingaweb2_dev/templates/roles.ini.erb new file mode 100644 index 0000000000..98a885fd09 --- /dev/null +++ b/.puppet/profiles/icingaweb2_dev/templates/roles.ini.erb @@ -0,0 +1,3 @@ +[admins] +users = icingaadmin +permissions = * diff --git a/AUTHORS b/AUTHORS index 30365cbd03..8a0bc91d0c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,5 +1,6 @@ Alexander Fuhr Alexander Klimov +ayoubabid baufrecht Bernd Erk Boden Garman @@ -11,8 +12,9 @@ Goran Rakic Gunnar Beutner Jannis Moßhammer Johannes Meyer -Marius Hein +Louis Sautier Marcus Cobden +Marius Hein Markus Frosch Matthias Jentsch Michael Friedrich @@ -22,4 +24,3 @@ Sylph Lin Thomas Gelf Tom Ford Ulf Lange -ayoubabid diff --git a/application/controllers/ConfigController.php b/application/controllers/ConfigController.php index 9602396ed9..f7543cc032 100644 --- a/application/controllers/ConfigController.php +++ b/application/controllers/ConfigController.php @@ -121,7 +121,8 @@ public function modulesAction() // @TODO(el): This seems not natural to me. Module configuration should have its own controller. $this->view->tabs = Widget::create('tabs') ->add('modules', array( - 'title' => $this->translate('Modules'), + 'label' => $this->translate('Modules'), + 'title' => $this->translate('List intalled modules'), 'url' => 'config/modules' )) ->activate('modules'); @@ -134,22 +135,23 @@ public function modulesAction() public function moduleAction() { - $name = $this->getParam('name'); $app = Icinga::app(); $manager = $app->getModuleManager(); + $name = $this->getParam('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)); + $this->view->moduleData = $manager->select()->from('modules')->where('name', $name)->fetchRow(); + if ($manager->hasLoaded($name)) { + $module = $manager->getModule($name); + } else { + $module = new Module($app, $name, $manager->getModuleDir($name)); + } + $this->view->module = $module; + $this->view->tabs = $module->getConfigTabs()->activate('info'); } else { $this->view->module = false; + $this->view->tabs = null; } - $this->view->tabs = $module->getConfigTabs()->activate('info'); } /** @@ -162,7 +164,6 @@ public function moduleenableAction() $manager = Icinga::app()->getModuleManager(); try { $manager->enableModule($module); - $manager->loadModule($module); Notification::success(sprintf($this->translate('Module "%s" enabled'), $module)); $this->rerenderLayout()->reloadCss()->redirectNow('config/modules'); } catch (Exception $e) { @@ -215,6 +216,11 @@ public function createauthenticationbackendAction() { $this->assertPermission('system/config/authentication'); $form = new AuthenticationBackendConfigForm(); + $form->setTitle($this->translate('Create New Authentication Backend')); + $form->addDescription($this->translate( + 'Create a new backend for authenticating your users. This backend' + . ' will be added at the end of your authentication order.' + )); $form->setIniConfig(Config::app('authentication')); $form->setResourceConfig(ResourceFactory::getResourceConfigs()); $form->setRedirectUrl('config/authentication'); @@ -232,6 +238,7 @@ public function editauthenticationbackendAction() { $this->assertPermission('system/config/authentication'); $form = new AuthenticationBackendConfigForm(); + $form->setTitle($this->translate('Edit Backend')); $form->setIniConfig(Config::app('authentication')); $form->setResourceConfig(ResourceFactory::getResourceConfigs()); $form->setRedirectUrl('config/authentication'); @@ -271,6 +278,7 @@ public function removeauthenticationbackendAction() } } )); + $form->setTitle($this->translate('Remove Backend')); $form->setRedirectUrl('config/authentication'); $form->handleRequest(); @@ -296,6 +304,8 @@ public function createresourceAction() { $this->assertPermission('system/config/resources'); $form = new ResourceConfigForm(); + $form->setTitle($this->translate('Create A New Resource')); + $form->addDescription($this->translate('Resources are entities that provide data to Icinga Web 2.')); $form->setIniConfig(Config::app('resources')); $form->setRedirectUrl('config/resource'); $form->handleRequest(); @@ -311,6 +321,7 @@ public function editresourceAction() { $this->assertPermission('system/config/resources'); $form = new ResourceConfigForm(); + $form->setTitle($this->translate('Edit Existing Resource')); $form->setIniConfig(Config::app('resources')); $form->setRedirectUrl('config/resource'); $form->handleRequest(); @@ -345,6 +356,7 @@ public function removeresourceAction() } } )); + $form->setTitle($this->translate('Remove Existing Resource')); $form->setRedirectUrl('config/resource'); $form->handleRequest(); @@ -353,7 +365,7 @@ public function removeresourceAction() $authConfig = Config::app('authentication'); foreach ($authConfig as $backendName => $config) { if ($config->get('resource') === $resource) { - $form->addError(sprintf( + $form->addDescription(sprintf( $this->translate( 'The resource "%s" is currently in use by the authentication backend "%s". ' . 'Removing the resource can result in noone being able to log in any longer.' diff --git a/application/controllers/DashboardController.php b/application/controllers/DashboardController.php index 9e7b482a84..325556be00 100644 --- a/application/controllers/DashboardController.php +++ b/application/controllers/DashboardController.php @@ -66,6 +66,7 @@ public function newDashletAction() Notification::success(t('Dashlet created')); return true; }); + $form->setTitle($this->translate('Add Dashlet To Dashboard')); $form->setRedirectUrl('dashboard'); $form->handleRequest(); $this->view->form = $form; @@ -128,6 +129,7 @@ public function updateDashletAction() Notification::success(t('Dashlet updated')); return true; }); + $form->setTitle($this->translate('Edit Dashlet')); $form->setRedirectUrl('dashboard/settings'); $form->handleRequest(); $pane = $dashboard->getPane($this->getParam('pane')); @@ -176,6 +178,7 @@ public function removeDashletAction() } return false; }); + $form->setTitle($this->translate('Remove Dashlet From Dashboard')); $form->setRedirectUrl('dashboard/settings'); $form->handleRequest(); $this->view->pane = $pane; @@ -215,6 +218,7 @@ public function removePaneAction() } return false; }); + $form->setTitle($this->translate('Remove Dashboard')); $form->setRedirectUrl('dashboard/settings'); $form->handleRequest(); $this->view->pane = $pane; @@ -249,8 +253,9 @@ public function indexAction() $this->view->tabs->add( 'Add', array( - 'title' => '+', - 'url' => Url::fromPath('dashboard/new-dashlet') + 'label' => '+', + 'title' => 'Add a dashlet to an existing or new dashboard', + 'url' => Url::fromPath('dashboard/new-dashlet') ) ); $this->view->dashboard = $this->dashboard; diff --git a/application/controllers/RolesController.php b/application/controllers/RolesController.php index 6cbb4f7038..2b7b520c5c 100644 --- a/application/controllers/RolesController.php +++ b/application/controllers/RolesController.php @@ -86,6 +86,7 @@ public function newAction() } )); $role + ->setTitle($this->translate('New Role')) ->setSubmitLabel($this->translate('Create Role')) ->setIniConfig(Config::app('roles', true)) ->setRedirectUrl('roles') @@ -108,6 +109,7 @@ public function updateAction() ); } $role = new RoleForm(); + $role->setTitle(sprintf($this->translate('Update Role %s'), $name)); $role->setSubmitLabel($this->translate('Update Role')); try { $role @@ -138,7 +140,6 @@ public function updateAction() }) ->setRedirectUrl('roles') ->handleRequest(); - $this->view->name = $name; $this->view->form = $role; } @@ -183,10 +184,10 @@ public function removeAction() } )); $confirmation + ->setTitle(sprintf($this->translate('Remove Role %s'), $name)) ->setSubmitLabel($this->translate('Remove Role')) ->setRedirectUrl('roles') ->handleRequest(); - $this->view->name = $name; $this->view->form = $confirmation; } } diff --git a/application/fonts/fontello-ifont/LICENSE.txt b/application/fonts/fontello-ifont/LICENSE.txt index 29b99c574a..152fb787d1 100644 --- a/application/fonts/fontello-ifont/LICENSE.txt +++ b/application/fonts/fontello-ifont/LICENSE.txt @@ -37,3 +37,12 @@ Font license info Homepage: http://www.entypo.com +## Fontelico + + Copyright (C) 2012 by Fontello project + + Author: Crowdsourced, for Fontello project + License: SIL (http://scripts.sil.org/OFL) + Homepage: http://fontello.com + + diff --git a/application/fonts/fontello-ifont/config.json b/application/fonts/fontello-ifont/config.json index 6e2d2af3b9..e9a58cc1ab 100644 --- a/application/fonts/fontello-ifont/config.json +++ b/application/fonts/fontello-ifont/config.json @@ -6,6 +6,12 @@ "units_per_em": 1000, "ascent": 850, "glyphs": [ + { + "uid": "9bc2902722abb366a213a052ade360bc", + "css": "spin6", + "code": 59508, + "src": "fontelico" + }, { "uid": "9dd9e835aebe1060ba7190ad2b2ed951", "css": "search", diff --git a/application/fonts/fontello-ifont/css/ifont-codes.css b/application/fonts/fontello-ifont/css/ifont-codes.css index 7bd25fd38f..ed241ebe9a 100644 --- a/application/fonts/fontello-ifont/css/ifont-codes.css +++ b/application/fonts/fontello-ifont/css/ifont-codes.css @@ -114,4 +114,5 @@ .icon-chart-area:before { content: '\e870'; } /* '' */ .icon-chart-bar:before { content: '\e871'; } /* '' */ .icon-beaker:before { content: '\e872'; } /* '' */ -.icon-magic:before { content: '\e873'; } /* '' */ \ No newline at end of file +.icon-magic:before { content: '\e873'; } /* '' */ +.icon-spin6:before { content: '\e874'; } /* '' */ \ No newline at end of file diff --git a/application/fonts/fontello-ifont/css/ifont-embedded.css b/application/fonts/fontello-ifont/css/ifont-embedded.css index 92bcfdff94..e35b001b29 100644 --- a/application/fonts/fontello-ifont/css/ifont-embedded.css +++ b/application/fonts/fontello-ifont/css/ifont-embedded.css @@ -1,15 +1,15 @@ @font-face { font-family: 'ifont'; - src: url('../font/ifont.eot?75097146'); - src: url('../font/ifont.eot?75097146#iefix') format('embedded-opentype'), - url('../font/ifont.svg?75097146#ifont') format('svg'); + src: url('../font/ifont.eot?57837527'); + src: url('../font/ifont.eot?57837527#iefix') format('embedded-opentype'), + url('../font/ifont.svg?57837527#ifont') format('svg'); font-weight: normal; font-style: normal; } @font-face { font-family: 'ifont'; - src: url('data:application/octet-stream;base64,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') format('woff'), - url('data:application/octet-stream;base64,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BjYGFQ4BFS4BNx4BFxYHBgcGFxQGFgGtdMZycsboyG4GerwBEgEIAwECBAMRFRMKAQwEDAMBBwYEBAoFBgQBCAEGAQQEBAIEBgEGAggJBQQFBQMBCAwBBRwHAgIBCAEOAQIHCQMEBAEEAgMBBwoCBAUNBAIUDhMECAYBAgECBQkCARMJAgQGBQYKAwgEBwUDAgYJBAYBBQkEBQMDAgUEAQ4HCw8EEAMDAQgECAEIAwEIBAQEAwMEAgQSBQMMDAEDAwIMGRsDAwgFEwUDCwQNCwEEAgYECAQJBFEyBAUCBgUDARgKAQIHBQQDBAQEAQIBAQECCgcHEgQHCQQDCAQCDgEBAgIOAgQCAg8IAwQDAgMFAQQKCgEECAQFDAcCAwgDCQcWBgYFCAgQBBQKAQIEAgYDDgMEAQoFCBEKAgICAgEFAgQBCgIDDAMCCAECCAMBAwIHCwQBAgIIFAMICgECAQQCAwUCAQIBBAECAgQYAwkDAQEBAw0CDgQCAwEEAwUCBggEAgIBCAQEBwgFBwwEBAICAgYBBQQDAgMFBwQDAhIBBAICBQwCCQICCggFCQIIBAIKCQ0JaXJRAQwBDQEEAxUBAwUCAwICAQUMCAMEBQEKAQMBAQQIBAoBBwYCCgIEAQwBAQICBAsPAQIJCgEDC3TE6sR0dMTqxHT+3QEIAgYGAQQIAwULAQwCAgQMAQoHAgMEAgQBAgYMBQYDCgEGBAEBAgICAQMDAgEDCAQCBgIDAwQFBAYHBAYICgcEBQYFDAMBAgQCAQMMCQ4DBAUHCAUDEQIDDgcGDAMBAwkCBwoDBgEOBAoEAQIFAgIGCgQHBwcBCQUIBwgDAgcDAgQCBgIEBQoDAw4CBQEBAgUEBwIBCggPAQMCAgcEAw4DAgQDBwMGBAQBAS1PBAEIBAMEBg8KAgYEBQQFDgkUCwIBBhoCARcFBAYDBRQDAxAFAgEECAUIBAELFw4FDAICBAQMCA4EDgEKCxQHCAEFAw0CAQIBEgMKBAQJBQYCAwoDAgMFDAIQCRMDAwQEBgIECgcOAQUCBAEEAgIQBQ8FAgUDAgsCCAQEAgIEGA4JDgUJAQQGAQIDAQEBBAMGBwYFAg8KAQQBAgMBAgMIBRcEAggIAwQPAgoKBQECAwQLCQUCAgICBgIKBwYFBAQEAwEECgQGAQcCAQcGBQMEAQEBBQQC/g0VVQIC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aQBmAG8AbgB0AEcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAAcwB2AGcAMgB0AHQAZgAgAGYAcgBvAG0AIABGAG8AbgB0AGUAbABsAG8AIABwAHIAbwBqAGUAYwB0AC4AaAB0AHQAcAA6AC8ALwBmAG8AbgB0AGUAbABsAG8ALgBjAG8AbQAAAAACAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHUAAAECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BHwEgASEBIgEjASQBJQEmAScBKAEpASoBKwEsAS0BLgEvATABMQEyATMBNAE1ATYBNwE4ATkBOgE7ATwBPQE+AT8BQAFBAUIBQwFEAUUBRgFHAUgBSQFKAUsBTAFNAU4BTwFQAVEBUgFTAVQBVQFWAVcBWAFZAVoBWwFcAV0BXgFfAWABYQFiAWMBZAFlAWYBZwFoAWkBagFrAWwBbQFuAW8BcAFxAXIBcwF0AXUJZGFzaGJvYXJkBHVzZXIFdXNlcnMCb2sGY2FuY2VsBHBsdXMFbWludXMMZm9sZGVyLWVtcHR5CGRvd25sb2FkBnVwbG9hZANnaXQFY3ViZXMIZGF0YWJhc2UFZ2F1Z2UHc2l0ZW1hcAxzb3J0LW5hbWUtdXAOc29ydC1uYW1lLWRvd24JbWVnYXBob25lA2J1ZwV0YXNrcwZmaWx0ZXIDb2ZmBGJvb2sFcGFzdGUIc2Npc3NvcnMFZ2xvYmUFY2xvdWQFZmxhc2gIYmFyY2hhcnQIZG93bi1kaXIGdXAtZGlyCGxlZnQtZGlyCXJpZ2h0LWRpcglkb3duLW9wZW4KcmlnaHQtb3Blbgd1cC1vcGVuCWxlZnQtb3BlbgZ1cC1iaWcJcmlnaHQtYmlnCGxlZnQtYmlnCGRvd24tYmlnD3Jlc2l6ZS1mdWxsLWFsdAtyZXNpemUtZnVsbAxyZXNpemUtc21hbGwEbW92ZRFyZXNpemUtaG9yaXpvbnRhbA9yZXNpemUtdmVydGljYWwHem9vbS1pbgVibG9jawh6b29tLW91dAlsaWdodGJ1bGIFY2xvY2sJdm9sdW1lLXVwC3ZvbHVtZS1kb3duCnZvbHVtZS1vZmYEbXV0ZQNtaWMHZW5kdGltZQlzdGFydHRpbWUOY2FsZW5kYXItZW1wdHkIY2FsZW5kYXIGd3JlbmNoB3NsaWRlcnMIc2VydmljZXMHc2VydmljZQVwaG9uZQhmaWxlLXBkZglmaWxlLXdvcmQKZmlsZS1leGNlbAhkb2MtdGV4dAV0cmFzaA1jb21tZW50LWVtcHR5B2NvbW1lbnQEY2hhdApjaGF0LWVtcHR5BGJlbGwIYmVsbC1hbHQNYXR0ZW50aW9uLWFsdAVwcmludARlZGl0B2ZvcndhcmQFcmVwbHkJcmVwbHktYWxsA2V5ZQN0YWcEdGFncw1sb2NrLW9wZW4tYWx0CWxvY2stb3BlbgRsb2NrBGhvbWUEaW5mbwRoZWxwBnNlYXJjaAhmbGFwcGluZwZyZXdpbmQKY2hhcnQtbGluZQhiZWxsLW9mZg5iZWxsLW9mZi1lbXB0eQRwbHVnB2V5ZS1vZmYKcmVzY2hlZHVsZQJjdwRob3N0CXRodW1icy11cAt0aHVtYnMtZG93bgdzcGlubmVyBmF0dGFjaAhrZXlib2FyZARtZW51BHdpZmkEbW9vbgljaGFydC1waWUKY2hhcnQtYXJlYQljaGFydC1iYXIGYmVha2VyBW1hZ2ljAAAAAQAB//8ADwAAAAAAAAAAAAAAALAALCCwAFVYRVkgIEu4AA5RS7AGU1pYsDQbsChZYGYgilVYsAIlYbkIAAgAY2MjYhshIbAAWbAAQyNEsgABAENgQi2wASywIGBmLbACLCBkILDAULAEJlqyKAEKQ0VjRVJbWCEjIRuKWCCwUFBYIbBAWRsgsDhQWCGwOFlZILEBCkNFY0VhZLAoUFghsQEKQ0VjRSCwMFBYIbAwWRsgsMBQWCBmIIqKYSCwClBYYBsgsCBQWCGwCmAbILA2UFghsDZgG2BZWVkbsAErWVkjsABQWGVZWS2wAywgRSCwBCVhZCCwBUNQWLAFI0KwBiNCGyEhWbABYC2wBCwjISMhIGSxBWJCILAGI0KxAQpDRWOxAQpDsABgRWOwAyohILAGQyCKIIqwASuxMAUlsAQmUVhgUBthUllYI1khILBAU1iwASsbIbBAWSOwAFBYZVktsAUssAdDK7IAAgBDYEItsAYssAcjQiMgsAAjQmGwAmJmsAFjsAFgsAUqLbAHLCAgRSCwC0NjuAQAYiCwAFBYsEBgWWawAWNgRLABYC2wCCyyBwsAQ0VCKiGyAAEAQ2BCLbAJLLAAQyNEsgABAENgQi2wCiwgIEUgsAErI7AAQ7AEJWAgRYojYSBkILAgUFghsAAbsDBQWLAgG7BAWVkjsABQWGVZsAMlI2FERLABYC2wCywgIEUgsAErI7AAQ7AEJWAgRYojYSBksCRQWLAAG7BAWSOwAFBYZVmwAyUjYUREsAFgLbAMLCCwACNCsgsKA0VYIRsjIVkqIS2wDSyxAgJFsGRhRC2wDiywAWAgILAMQ0qwAFBYILAMI0JZsA1DSrAAUlggsA0jQlktsA8sILAQYmawAWMguAQAY4ojYbAOQ2AgimAgsA4jQiMtsBAsS1RYsQRkRFkksA1lI3gtsBEsS1FYS1NYsQRkRFkbIVkksBNlI3gtsBIssQAPQ1VYsQ8PQ7ABYUKwDytZsABDsAIlQrEMAiVCsQ0CJUKwARYjILADJVBYsQEAQ2CwBCVCioogiiNhsA4qISOwAWEgiiNhsA4qIRuxAQBDYLACJUKwAiVhsA4qIVmwDENHsA1DR2CwAmIgsABQWLBAYFlmsAFjILALQ2O4BABiILAAUFiwQGBZZrABY2CxAAATI0SwAUOwAD6yAQEBQ2BCLbATLACxAAJFVFiwDyNCIEWwCyNCsAojsABgQiBgsAFhtRAQAQAOAEJCimCxEgYrsHIrGyJZLbAULLEAEystsBUssQETKy2wFiyxAhMrLbAXLLEDEystsBgssQQTKy2wGSyxBRMrLbAaLLEGEystsBsssQcTKy2wHCyxCBMrLbAdLLEJEystsB4sALANK7EAAkVUWLAPI0IgRbALI0KwCiOwAGBCIGCwAWG1EBABAA4AQkKKYLESBiuwcisbIlktsB8ssQAeKy2wICyxAR4rLbAhLLECHistsCIssQMeKy2wIyyxBB4rLbAkLLEFHistsCUssQYeKy2wJiyxBx4rLbAnLLEIHistsCgssQkeKy2wKSwgPLABYC2wKiwgYLAQYCBDI7ABYEOwAiVhsAFgsCkqIS2wKyywKiuwKiotsCwsICBHICCwC0NjuAQAYiCwAFBYsEBgWWawAWNgI2E4IyCKVVggRyAgsAtDY7gEAGIgsABQWLBAYFlmsAFjYCNhOBshWS2wLSwAsQACRVRYsAEWsCwqsAEVMBsiWS2wLiwAsA0rsQACRVRYsAEWsCwqsAEVMBsiWS2wLywgNbABYC2wMCwAsAFFY7gEAGIgsABQWLBAYFlmsAFjsAErsAtDY7gEAGIgsABQWLBAYFlmsAFjsAErsAAWtAAAAAAARD4jOLEvARUqLbAxLCA8IEcgsAtDY7gEAGIgsABQWLBAYFlmsAFjYLAAQ2E4LbAyLC4XPC2wMywgPCBHILALQ2O4BABiILAAUFiwQGBZZrABY2CwAENhsAFDYzgtsDQssQIAFiUgLiBHsAAjQrACJUmKikcjRyNhIFhiGyFZsAEjQrIzAQEVFCotsDUssAAWsAQlsAQlRyNHI2GwCUMrZYouIyAgPIo4LbA2LLAAFrAEJbAEJSAuRyNHI2EgsAQjQrAJQysgsGBQWCCwQFFYswIgAyAbswImAxpZQkIjILAIQyCKI0cjRyNhI0ZgsARDsAJiILAAUFiwQGBZZrABY2AgsAErIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbACYiCwAFBYsEBgWWawAWNhIyAgsAQmI0ZhOBsjsAhDRrACJbAIQ0cjRyNhYCCwBEOwAmIgsABQWLBAYFlmsAFjYCMgsAErI7AEQ2CwASuwBSVhsAUlsAJiILAAUFiwQGBZZrABY7AEJmEgsAQlYGQjsAMlYGRQWCEbIyFZIyAgsAQmI0ZhOFktsDcssAAWICAgsAUmIC5HI0cjYSM8OC2wOCywABYgsAgjQiAgIEYjR7ABKyNhOC2wOSywABawAyWwAiVHI0cjYbAAVFguIDwjIRuwAiWwAiVHI0cjYSCwBSWwBCVHI0cjYbAGJbAFJUmwAiVhuQgACABjYyMgWGIbIVljuAQAYiCwAFBYsEBgWWawAWNgIy4jICA8ijgjIVktsDossAAWILAIQyAuRyNHI2EgYLAgYGawAmIgsABQWLBAYFlmsAFjIyAgPIo4LbA7LCMgLkawAiVGUlggPFkusSsBFCstsDwsIyAuRrACJUZQWCA8WS6xKwEUKy2wPSwjIC5GsAIlRlJYIDxZIyAuRrACJUZQWCA8WS6xKwEUKy2wPiywNSsjIC5GsAIlRlJYIDxZLrErARQrLbA/LLA2K4ogIDywBCNCijgjIC5GsAIlRlJYIDxZLrErARQrsARDLrArKy2wQCywABawBCWwBCYgLkcjRyNhsAlDKyMgPCAuIzixKwEUKy2wQSyxCAQlQrAAFrAEJbAEJSAuRyNHI2EgsAQjQrAJQysgsGBQWCCwQFFYswIgAyAbswImAxpZQkIjIEewBEOwAmIgsABQWLBAYFlmsAFjYCCwASsgiophILACQ2BkI7ADQ2FkUFiwAkNhG7ADQ2BZsAMlsAJiILAAUFiwQGBZZrABY2GwAiVGYTgjIDwjOBshICBGI0ewASsjYTghWbErARQrLbBCLLA1Ky6xKwEUKy2wQyywNishIyAgPLAEI0IjOLErARQrsARDLrArKy2wRCywABUgR7AAI0KyAAEBFRQTLrAxKi2wRSywABUgR7AAI0KyAAEBFRQTLrAxKi2wRiyxAAEUE7AyKi2wRyywNCotsEgssAAWRSMgLiBGiiNhOLErARQrLbBJLLAII0KwSCstsEossgAAQSstsEsssgABQSstsEwssgEAQSstsE0ssgEBQSstsE4ssgAAQistsE8ssgABQistsFAssgEAQistsFEssgEBQistsFIssgAAPistsFMssgABPistsFQssgEAPistsFUssgEBPistsFYssgAAQCstsFcssgABQCstsFgssgEAQCstsFkssgEBQCstsFossgAAQystsFsssgABQystsFwssgEAQystsF0ssgEBQystsF4ssgAAPystsF8ssgABPystsGAssgEAPystsGEssgEBPystsGIssDcrLrErARQrLbBjLLA3K7A7Ky2wZCywNyuwPCstsGUssAAWsDcrsD0rLbBmLLA4Ky6xKwEUKy2wZyywOCuwOystsGgssDgrsDwrLbBpLLA4K7A9Ky2waiywOSsusSsBFCstsGsssDkrsDsrLbBsLLA5K7A8Ky2wbSywOSuwPSstsG4ssDorLrErARQrLbBvLLA6K7A7Ky2wcCywOiuwPCstsHEssDorsD0rLbByLLMJBAIDRVghGyMhWUIrsAhlsAMkUHiwARUwLQBLuADIUlixAQGOWbABuQgACABjcLEABUKxAAAqsQAFQrEACCqxAAVCsQAIKrEABUK5AAAACSqxAAVCuQAAAAkqsQMARLEkAYhRWLBAiFixA2REsSYBiFFYugiAAAEEQIhjVFixAwBEWVlZWbEADCq4Af+FsASNsQIARAA=') format('truetype'); + src: url('data:application/octet-stream;base64,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') format('woff'), + url('data:application/octet-stream;base64,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BjYGFQ4BFS4BNx4BFxYHBgcGFxQGFgGtdMZycsboyG4GerwBEgEIAwECBAMRFRMKAQwEDAMBBwYEBAoFBgQBCAEGAQQEBAIEBgEGAggJBQQFBQMBCAwBBRwHAgIBCAEOAQIHCQMEBAEEAgMBBwoCBAUNBAIUDhMECAYBAgECBQkCARMJAgQGBQYKAwgEBwUDAgYJBAYBBQkEBQMDAgUEAQ4HCw8EEAMDAQgECAEIAwEIBAQEAwMEAgQSBQMMDAEDAwIMGRsDAwgFEwUDCwQNCwEEAgYECAQJBFEyBAUCBgUDARgKAQIHBQQDBAQEAQIBAQECCgcHEgQHCQQDCAQCDgEBAgIOAgQCAg8IAwQDAgMFAQQKCgEECAQFDAcCAwgDCQcWBgYFCAgQBBQKAQIEAgYDDgMEAQoFCBEKAgICAgEFAgQBCgIDDAMCCAECCAMBAwIHCwQBAgIIFAMICgECAQQCAwUCAQIBBAECAgQYAwkDAQEBAw0CDgQCAwEEAwUCBggEAgIBCAQEBwgFBwwEBAICAgYBBQQDAgMFBwQDAhIBBAICBQwCCQICCggFCQIIBAIKCQ0JaXJRAQwBDQEEAxUBAwUCAwICAQUMCAMEBQEKAQMBAQQIBAoBBwYCCgIEAQwBAQICBAsPAQIJCgEDC3TE6sR0dMTqxHT+3QEIAgYGAQQIAwULAQwCAgQMAQoHAgMEAgQBAgYMBQYDCgEGBAEBAgICAQMDAgEDCAQCBgIDAwQFBAYHBAYICgcEBQYFDAMBAgQCAQMMCQ4DBAUHCAUDEQIDDgcGDAMBAwkCBwoDBgEOBAoEAQIFAgIGCgQHBwcBCQUIBwgDAgcDAgQCBgIEBQoDAw4CBQEBAgUEBwIBCggPAQMCAgcEAw4DAgQDBwMGBAQBAS1PBAEIBAMEBg8KAgYEBQQFDgkUCwIBBhoCARcFBAYDBRQDAxAFAgEECAUIBAELFw4FDAICBAQMCA4EDgEKCxQHCAEFAw0CAQIBEgMKBAQJBQYCAwoDAgMFDAIQCRMDAwQEBgIECgcOAQUCBAEEAgIQBQ8FAgUDAgsCCAQEAgIEGA4JDgUJAQQGAQIDAQEBBAMGBwYFAg8KAQQBAgMBAgMIBRcEAggIAwQPAgoKBQECAwQLCQUCAgICBgIKBwYFBAQEAwEECgQGAQcCAQcGBQMEAQEBBQQC/g0VVQIC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KABDACkAIAAyADAAMQA1ACAAYgB5ACAAbwByAGkAZwBpAG4AYQBsACAAYQB1AHQAaABvAHIAcwAgAEAAIABmAG8AbgB0AGUAbABsAG8ALgBjAG8AbQBpAGYAbwBuAHQAUgBlAGcAdQBsAGEAcgBpAGYAbwBuAHQAaQBmAG8AbgB0AFYAZQByAHMAaQBvAG4AIAAxAC4AMABpAGYAbwBuAHQARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABzAHYAZwAyAHQAdABmACAAZgByAG8AbQAgAEYAbwBuAHQAZQBsAGwAbwAgAHAAcgBvAGoAZQBjAHQALgBoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAAAAAAIAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdgAAAQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE3ATgBOQE6ATsBPAE9AT4BPwFAAUEBQgFDAUQBRQFGAUcBSAFJAUoBSwFMAU0BTgFPAVABUQFSAVMBVAFVAVYBVwFYAVkBWgFbAVwBXQFeAV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFzAXQBdQF2CWRhc2hib2FyZAR1c2VyBXVzZXJzAm9rBmNhbmNlbARwbHVzBW1pbnVzDGZvbGRlci1lbXB0eQhkb3dubG9hZAZ1cGxvYWQDZ2l0BWN1YmVzCGRhdGFiYXNlBWdhdWdlB3NpdGVtYXAMc29ydC1uYW1lLXVwDnNvcnQtbmFtZS1kb3duCW1lZ2FwaG9uZQNidWcFdGFza3MGZmlsdGVyA29mZgRib29rBXBhc3RlCHNjaXNzb3JzBWdsb2JlBWNsb3VkBWZsYXNoCGJhcmNoYXJ0CGRvd24tZGlyBnVwLWRpcghsZWZ0LWRpcglyaWdodC1kaXIJZG93bi1vcGVuCnJpZ2h0LW9wZW4HdXAtb3BlbglsZWZ0LW9wZW4GdXAtYmlnCXJpZ2h0LWJpZwhsZWZ0LWJpZwhkb3duLWJpZw9yZXNpemUtZnVsbC1hbHQLcmVzaXplLWZ1bGwMcmVzaXplLXNtYWxsBG1vdmURcmVzaXplLWhvcml6b250YWwPcmVzaXplLXZlcnRpY2FsB3pvb20taW4FYmxvY2sIem9vbS1vdXQJbGlnaHRidWxiBWNsb2NrCXZvbHVtZS11cAt2b2x1bWUtZG93bgp2b2x1bWUtb2ZmBG11dGUDbWljB2VuZHRpbWUJc3RhcnR0aW1lDmNhbGVuZGFyLWVtcHR5CGNhbGVuZGFyBndyZW5jaAdzbGlkZXJzCHNlcnZpY2VzB3NlcnZpY2UFcGhvbmUIZmlsZS1wZGYJZmlsZS13b3JkCmZpbGUtZXhjZWwIZG9jLXRleHQFdHJhc2gNY29tbWVudC1lbXB0eQdjb21tZW50BGNoYXQKY2hhdC1lbXB0eQRiZWxsCGJlbGwtYWx0DWF0dGVudGlvbi1hbHQFcHJpbnQEZWRpdAdmb3J3YXJkBXJlcGx5CXJlcGx5LWFsbANleWUDdGFnBHRhZ3MNbG9jay1vcGVuLWFsdAlsb2NrLW9wZW4EbG9jawRob21lBGluZm8EaGVscAZzZWFyY2gIZmxhcHBpbmcGcmV3aW5kCmNoYXJ0LWxpbmUIYmVsbC1vZmYOYmVsbC1vZmYtZW1wdHkEcGx1ZwdleWUtb2ZmCnJlc2NoZWR1bGUCY3cEaG9zdAl0aHVtYnMtdXALdGh1bWJzLWRvd24Hc3Bpbm5lcgZhdHRhY2gIa2V5Ym9hcmQEbWVudQR3aWZpBG1vb24JY2hhcnQtcGllCmNoYXJ0LWFyZWEJY2hhcnQtYmFyBmJlYWtlcgVtYWdpYwVzcGluNgAAAAEAAf//AA8AAAAAAAAAAAAAAACwACwgsABVWEVZICBLuAAOUUuwBlNaWLA0G7AoWWBmIIpVWLACJWG5CAAIAGNjI2IbISGwAFmwAEMjRLIAAQBDYEItsAEssCBgZi2wAiwgZCCwwFCwBCZasigBCkNFY0VSW1ghIyEbilggsFBQWCGwQFkbILA4UFghsDhZWSCxAQpDRWNFYWSwKFBYIbEBCkNFY0UgsDBQWCGwMFkbILDAUFggZiCKimEgsApQWGAbILAgUFghsApgGyCwNlBYIbA2YBtgWVlZG7ABK1lZI7AAUFhlWVktsAMsIEUgsAQlYWQgsAVDUFiwBSNCsAYjQhshIVmwAWAtsAQsIyEjISBk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') format('truetype'); } /* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ /* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ @@ -17,7 +17,7 @@ @media screen and (-webkit-min-device-pixel-ratio:0) { @font-face { font-family: 'ifont'; - src: url('../font/ifont.svg?75097146#ifont') format('svg'); + src: url('../font/ifont.svg?57837527#ifont') format('svg'); } } */ @@ -168,3 +168,4 @@ .icon-chart-bar:before { content: '\e871'; } /* '' */ .icon-beaker:before { content: '\e872'; } /* '' */ .icon-magic:before { content: '\e873'; } /* '' */ +.icon-spin6:before { content: '\e874'; } /* '' */ \ No newline at end of file diff --git a/application/fonts/fontello-ifont/css/ifont-ie7-codes.css b/application/fonts/fontello-ifont/css/ifont-ie7-codes.css index 130f0e4147..1f3c433540 100644 --- a/application/fonts/fontello-ifont/css/ifont-ie7-codes.css +++ b/application/fonts/fontello-ifont/css/ifont-ie7-codes.css @@ -114,4 +114,5 @@ .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 = ' '); } \ No newline at end of file +.icon-magic { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } +.icon-spin6 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } \ No newline at end of file diff --git a/application/fonts/fontello-ifont/css/ifont-ie7.css b/application/fonts/fontello-ifont/css/ifont-ie7.css index 4e6ee83dd9..18b372d2bf 100644 --- a/application/fonts/fontello-ifont/css/ifont-ie7.css +++ b/application/fonts/fontello-ifont/css/ifont-ie7.css @@ -125,4 +125,5 @@ .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 = ' '); } \ No newline at end of file +.icon-magic { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } +.icon-spin6 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); } \ No newline at end of file diff --git a/application/fonts/fontello-ifont/css/ifont.css b/application/fonts/fontello-ifont/css/ifont.css index 546dffff11..80f91f8b2d 100644 --- a/application/fonts/fontello-ifont/css/ifont.css +++ b/application/fonts/fontello-ifont/css/ifont.css @@ -1,10 +1,10 @@ @font-face { font-family: 'ifont'; - 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'); + src: url('../font/ifont.eot?6491776'); + src: url('../font/ifont.eot?6491776#iefix') format('embedded-opentype'), + url('../font/ifont.woff?6491776') format('woff'), + url('../font/ifont.ttf?6491776') format('truetype'), + url('../font/ifont.svg?6491776#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?81587324#ifont') format('svg'); + src: url('../font/ifont.svg?6491776#ifont') format('svg'); } } */ @@ -165,4 +165,5 @@ .icon-chart-area:before { content: '\e870'; } /* '' */ .icon-chart-bar:before { content: '\e871'; } /* '' */ .icon-beaker:before { content: '\e872'; } /* '' */ -.icon-magic:before { content: '\e873'; } /* '' */ \ No newline at end of file +.icon-magic:before { content: '\e873'; } /* '' */ +.icon-spin6:before { content: '\e874'; } /* '' */ \ No newline at end of file diff --git a/application/fonts/fontello-ifont/demo.html b/application/fonts/fontello-ifont/demo.html index c9a06c6dcd..dff2d3250f 100644 --- a/application/fonts/fontello-ifont/demo.html +++ b/application/fonts/fontello-ifont/demo.html @@ -428,6 +428,9 @@

icon-beaker0xe872
icon-magic0xe873
+
+
icon-spin60xe874
+
diff --git a/application/forms/Authentication/LoginForm.php b/application/forms/Authentication/LoginForm.php index 43fd8823f2..d4f0e87457 100644 --- a/application/forms/Authentication/LoginForm.php +++ b/application/forms/Authentication/LoginForm.php @@ -16,6 +16,7 @@ class LoginForm extends Form */ public function init() { + $this->setRequiredCue(null); $this->setName('form_login'); $this->setSubmitLabel($this->translate('Login')); } diff --git a/application/forms/Config/Authentication/ExternalBackendForm.php b/application/forms/Config/Authentication/ExternalBackendForm.php index e256615969..86087eb662 100644 --- a/application/forms/Config/Authentication/ExternalBackendForm.php +++ b/application/forms/Config/Authentication/ExternalBackendForm.php @@ -53,7 +53,7 @@ public function createElements(array $formData) return @preg_match($value, '') !== false; }); $callbackValidator->setMessage( - $this->translate('"%value%" is not a valid regular expression'), + $this->translate('"%value%" is not a valid regular expression.'), Zend_Validate_Callback::INVALID_VALUE ); $this->addElement( @@ -62,9 +62,10 @@ public function createElements(array $formData) array( 'label' => $this->translate('Filter Pattern'), 'description' => $this->translate( - 'The regular expression to use to strip specific parts off from usernames.' - . ' Leave empty if you do not want to strip off anything' + 'The filter to use to strip specific parts off from usernames.' + . ' Leave empty if you do not want to strip off anything.' ), + 'requirement' => $this->translate('The filter pattern must be a valid regular expression.'), 'validators' => array($callbackValidator) ) ); diff --git a/application/forms/Config/General/LoggingConfigForm.php b/application/forms/Config/General/LoggingConfigForm.php index 1c4e090c4b..bd62f4490d 100644 --- a/application/forms/Config/General/LoggingConfigForm.php +++ b/application/forms/Config/General/LoggingConfigForm.php @@ -66,6 +66,7 @@ public function createElements(array $formData) 'description' => $this->translate( 'The name of the application by which to prefix syslog messages.' ), + 'requirement' => $this->translate('The application prefix must not contain whitespace.'), 'value' => 'icingaweb2', 'validators' => array( array( diff --git a/application/forms/Config/GeneralConfigForm.php b/application/forms/Config/GeneralConfigForm.php index b11b91208e..c3c771f978 100644 --- a/application/forms/Config/GeneralConfigForm.php +++ b/application/forms/Config/GeneralConfigForm.php @@ -20,6 +20,7 @@ public function init() { $this->setName('form_config_general'); $this->setSubmitLabel($this->translate('Save Changes')); + $this->setTitle($this->translate('General Configuration')); } /** diff --git a/application/forms/Config/Resource/FileResourceForm.php b/application/forms/Config/Resource/FileResourceForm.php index b1bb0c6aee..184a5c18a0 100644 --- a/application/forms/Config/Resource/FileResourceForm.php +++ b/application/forms/Config/Resource/FileResourceForm.php @@ -3,6 +3,7 @@ namespace Icinga\Forms\Config\Resource; +use Zend_Validate_Callback; use Icinga\Web\Form; /** @@ -42,13 +43,22 @@ public function createElements(array $formData) 'validators' => array('ReadablePathValidator') ) ); + $callbackValidator = new Zend_Validate_Callback(function ($value) { + return @preg_match($value, '') !== false; + }); + $callbackValidator->setMessage( + $this->translate('"%value%" is not a valid regular expression.'), + Zend_Validate_Callback::INVALID_VALUE + ); $this->addElement( 'text', 'fields', array( 'required' => true, 'label' => $this->translate('Pattern'), - 'description' => $this->translate('The regular expression by which to identify columns') + 'description' => $this->translate('The pattern by which to identify columns.'), + 'requirement' => $this->translate('The column pattern must be a valid regular expression.'), + 'validators' => array($callbackValidator) ) ); diff --git a/application/forms/Dashboard/DashletForm.php b/application/forms/Dashboard/DashletForm.php index 6a33a439be..59ae41582b 100644 --- a/application/forms/Dashboard/DashletForm.php +++ b/application/forms/Dashboard/DashletForm.php @@ -116,9 +116,9 @@ public function createElements(array $formData) 'checkbox', 'create_new_pane', array( + 'autosubmit' => true, 'required' => false, 'label' => $this->translate('New dashboard'), - 'class' => 'autosubmit', 'description' => $this->translate('Check this box if you want to add the dashlet to a new dashboard') ) ); diff --git a/application/forms/LdapDiscoveryForm.php b/application/forms/LdapDiscoveryForm.php index e05be6eaa0..3e129934d9 100644 --- a/application/forms/LdapDiscoveryForm.php +++ b/application/forms/LdapDiscoveryForm.php @@ -24,51 +24,11 @@ public function createElements(array $formData) 'text', 'domain', array( - 'required' => true, 'label' => $this->translate('Search Domain'), 'description' => $this->translate('Search this domain for records of available servers.'), ) ); - if (false) { - $this->addElement( - 'note', - 'additional_description', - array( - 'value' => $this->translate('No Ldap servers found on this domain.' - . ' You can try to specify host and port and try again, or just skip this step and ' - . 'configure the server manually.' - ) - ) - ); - $this->addElement( - 'text', - 'hostname', - array( - 'required' => false, - 'label' => $this->translate('Host'), - 'description' => $this->translate('IP or hostname to search.'), - ) - ); - - $this->addElement( - 'text', - 'port', - array( - 'required' => false, - 'label' => $this->translate('Port'), - 'description' => $this->translate('Port', 389), - ) - ); - } return $this; } - - public function isValid($data) - { - if (false === parent::isValid($data)) { - return false; - } - return true; - } } diff --git a/application/forms/PreferenceForm.php b/application/forms/PreferenceForm.php index 3ee1ebb38c..09aa6b6522 100644 --- a/application/forms/PreferenceForm.php +++ b/application/forms/PreferenceForm.php @@ -40,6 +40,7 @@ class PreferenceForm extends Form public function init() { $this->setName('form_config_preferences'); + $this->setTitle($this->translate('Preferences')); } /** diff --git a/application/layouts/scripts/body.phtml b/application/layouts/scripts/body.phtml index 03c0f5905b..78bb4f91de 100644 --- a/application/layouts/scripts/body.phtml +++ b/application/layouts/scripts/body.phtml @@ -29,7 +29,16 @@ if ($notifications->hasMessages()) { } ?> diff --git a/application/views/helpers/ProtectId.php b/application/views/helpers/ProtectId.php new file mode 100644 index 0000000000..8795a39330 --- /dev/null +++ b/application/views/helpers/ProtectId.php @@ -0,0 +1,12 @@ +getRequest()->protectId($id); + } +} diff --git a/application/views/scripts/authentication/login.phtml b/application/views/scripts/authentication/login.phtml index 4b1de39611..1bd7dc562e 100644 --- a/application/views/scripts/authentication/login.phtml +++ b/application/views/scripts/authentication/login.phtml @@ -18,7 +18,7 @@ '' ); ?>

-

icon('icon-info'); ?>translate( +

icon('info'); ?>translate( 'You\'re currently not authenticated using any of the web server\'s authentication mechanisms.' . ' Make sure you\'ll configure such, otherwise you\'ll not be able to login.' ); ?>

diff --git a/application/views/scripts/config/application.phtml b/application/views/scripts/config/application.phtml index 4255befc40..e9aa039f99 100644 --- a/application/views/scripts/config/application.phtml +++ b/application/views/scripts/config/application.phtml @@ -2,9 +2,6 @@ tabs->render($this); ?>
-

- translate('General Configuration'); ?> -

messageBox)): ?> messageBox->render() ?> diff --git a/application/views/scripts/config/authentication/create.phtml b/application/views/scripts/config/authentication/create.phtml index 48d1f00ed6..a53f51721a 100644 --- a/application/views/scripts/config/authentication/create.phtml +++ b/application/views/scripts/config/authentication/create.phtml @@ -2,15 +2,5 @@ tabs->showOnlyCloseButton() ?>
-

- translate('Create New Authentication Backend'); ?> -

-

- translate( - 'Create a new backend for authenticating your users. This backend will be added at the end of your authentication order.' - ); ?> -

-
- -
-
+ + \ No newline at end of file diff --git a/application/views/scripts/config/authentication/modify.phtml b/application/views/scripts/config/authentication/modify.phtml index ebc1937a7c..338d6807e4 100644 --- a/application/views/scripts/config/authentication/modify.phtml +++ b/application/views/scripts/config/authentication/modify.phtml @@ -2,10 +2,5 @@ tabs->showOnlyCloseButton() ?>
-

- translate('Edit Backend'); ?> -

-
- -
+
diff --git a/application/views/scripts/config/authentication/remove.phtml b/application/views/scripts/config/authentication/remove.phtml index 0a53af30cb..a53f51721a 100644 --- a/application/views/scripts/config/authentication/remove.phtml +++ b/application/views/scripts/config/authentication/remove.phtml @@ -2,10 +2,5 @@ tabs->showOnlyCloseButton() ?>
-

- translate('Remove Backend'); ?> -

-
- -
+
\ No newline at end of file diff --git a/application/views/scripts/config/authentication/reorder.phtml b/application/views/scripts/config/authentication/reorder.phtml index 4583a23b34..0386cdd5e1 100644 --- a/application/views/scripts/config/authentication/reorder.phtml +++ b/application/views/scripts/config/authentication/reorder.phtml @@ -2,7 +2,7 @@
-

+

translate('Authentication Configuration'); ?>

diff --git a/application/views/scripts/config/module.phtml b/application/views/scripts/config/module.phtml index 28fbeb39e8..9130bcc902 100644 --- a/application/views/scripts/config/module.phtml +++ b/application/views/scripts/config/module.phtml @@ -2,9 +2,6 @@ tabs ?>

-

- escape($module->getTitle()) ?> -

translate('There is no such module installed.') ?> @@ -14,6 +11,9 @@ $permissions = $module->getProvidedPermissions(); $state = $moduleData->enabled ? ($moduleData->loaded ? 'enabled' : 'failed') : 'disabled' ?> +

+ escape($module->getTitle()) ?> +

diff --git a/application/views/scripts/config/resource.phtml b/application/views/scripts/config/resource.phtml index 342320ab94..a8275912bb 100644 --- a/application/views/scripts/config/resource.phtml +++ b/application/views/scripts/config/resource.phtml @@ -42,7 +42,7 @@ 'config/removeresource', array('resource' => $name), array( - 'icon' => 'cancel', + 'icon' => 'trash', 'title' => sprintf($this->translate('Remove resource %s'), $name) ) ); ?> diff --git a/application/views/scripts/config/resource/create.phtml b/application/views/scripts/config/resource/create.phtml index 71d8c946e7..a53f51721a 100644 --- a/application/views/scripts/config/resource/create.phtml +++ b/application/views/scripts/config/resource/create.phtml @@ -2,11 +2,5 @@ tabs->showOnlyCloseButton() ?>
-

- translate('Create A New Resource'); ?> -

-

translate('Resources are entities that provide data to Icinga Web 2.'); ?>

-
- -
+
\ No newline at end of file diff --git a/application/views/scripts/config/resource/modify.phtml b/application/views/scripts/config/resource/modify.phtml index b7bd0a2f70..a53f51721a 100644 --- a/application/views/scripts/config/resource/modify.phtml +++ b/application/views/scripts/config/resource/modify.phtml @@ -2,10 +2,5 @@ tabs->showOnlyCloseButton() ?>
-

- translate('Edit Existing Resource'); ?> -

-
- -
+
\ No newline at end of file diff --git a/application/views/scripts/config/resource/remove.phtml b/application/views/scripts/config/resource/remove.phtml index 010f2d5d27..a53f51721a 100644 --- a/application/views/scripts/config/resource/remove.phtml +++ b/application/views/scripts/config/resource/remove.phtml @@ -2,10 +2,5 @@ tabs->showOnlyCloseButton() ?>
-

- translate('Remove Existing Resource'); ?> -

-
- -
+
\ No newline at end of file diff --git a/application/views/scripts/dashboard/new-dashlet.phtml b/application/views/scripts/dashboard/new-dashlet.phtml index 98b0554140..b265a253a6 100644 --- a/application/views/scripts/dashboard/new-dashlet.phtml +++ b/application/views/scripts/dashboard/new-dashlet.phtml @@ -2,6 +2,5 @@ tabs ?>
-

form; ?>
\ No newline at end of file diff --git a/application/views/scripts/dashboard/remove-dashlet.phtml b/application/views/scripts/dashboard/remove-dashlet.phtml index 4c842cf291..b265a253a6 100644 --- a/application/views/scripts/dashboard/remove-dashlet.phtml +++ b/application/views/scripts/dashboard/remove-dashlet.phtml @@ -1,14 +1,6 @@
tabs ?>
-
-

- -

- translate('Please confirm the removal'); ?>: - pane; ?>/dashlet; ?> -

- form; ?>
\ No newline at end of file diff --git a/application/views/scripts/dashboard/remove-pane.phtml b/application/views/scripts/dashboard/remove-pane.phtml index 45455d37d2..b265a253a6 100644 --- a/application/views/scripts/dashboard/remove-pane.phtml +++ b/application/views/scripts/dashboard/remove-pane.phtml @@ -1,14 +1,6 @@
tabs ?>
-
-

- -

- translate('Please confirm the removal of'); ?>: - pane; ?> -

- form; ?>
\ No newline at end of file diff --git a/application/views/scripts/dashboard/settings.phtml b/application/views/scripts/dashboard/settings.phtml index d1ed998d15..2c638c3181 100644 --- a/application/views/scripts/dashboard/settings.phtml +++ b/application/views/scripts/dashboard/settings.phtml @@ -28,7 +28,7 @@ 'dashboard/remove-pane', array('pane' => $pane->getName()), array( - 'icon' => 'cancel', + 'icon' => 'trash', 'title' => sprintf($this->translate('Remove pane %s'), $pane->getName()) ) ); ?> @@ -67,7 +67,7 @@ 'dashboard/remove-dashlet', array('pane' => $pane->getName(), 'dashlet' => $dashlet->getTitle()), array( - 'icon' => 'cancel', + 'icon' => 'trash', 'title' => sprintf($this->translate('Remove dashlet %s from pane %s'), $dashlet->getTitle(), $pane->getName()) ) ); ?> diff --git a/application/views/scripts/dashboard/update-dashlet.phtml b/application/views/scripts/dashboard/update-dashlet.phtml index e83c8b6c38..b265a253a6 100644 --- a/application/views/scripts/dashboard/update-dashlet.phtml +++ b/application/views/scripts/dashboard/update-dashlet.phtml @@ -1,8 +1,6 @@
tabs ?>
-
-

form; ?>
\ No newline at end of file diff --git a/application/views/scripts/form/reorder-authbackend.phtml b/application/views/scripts/form/reorder-authbackend.phtml index 02f62572d2..cd8001436e 100644 --- a/application/views/scripts/form/reorder-authbackend.phtml +++ b/application/views/scripts/form/reorder-authbackend.phtml @@ -1,4 +1,4 @@ - +
escape($this->translate('Name')) ?>
@@ -26,12 +26,12 @@ 'config/removeAuthenticationBackend', array('auth_backend' => $backendNames[$i]), array( - 'icon' => 'cancel', + 'icon' => 'trash', 'title' => sprintf($this->translate('Remove authentication backend %s'), $backendNames[$i]) ) ); ?> -
Backend + 0): ?> ', + $isForm + ? t('Push this button to update the form to reflect the changes that were made below') + : t('Push this button to update the form to reflect the change' + . ' that was made in the field on the left'), + $this->getView()->icon('cw') . t('Apply') + ); + } + + return $content; + } +} diff --git a/library/Icinga/Web/Form/Decorator/FormDescriptions.php b/library/Icinga/Web/Form/Decorator/FormDescriptions.php new file mode 100644 index 0000000000..c8ba16ead4 --- /dev/null +++ b/library/Icinga/Web/Form/Decorator/FormDescriptions.php @@ -0,0 +1,146 @@ +blacklist = array( + 'Zend_Form_Element_Hidden', + 'Zend_Form_Element_Submit', + 'Zend_Form_Element_Button', + 'Icinga\Web\Form\Element\Note', + 'Icinga\Web\Form\Element\Button', + 'Icinga\Web\Form\Element\CsrfCounterMeasure' + ); + } + + /** + * Render form descriptions + * + * @param string $content The html rendered so far + * + * @return string The updated html + */ + public function render($content = '') + { + $form = $this->getElement(); + if (! $form instanceof Form) { + return $content; + } + + $view = $form->getView(); + if ($view === null) { + return $content; + } + + $descriptions = $this->recurseForm($form, $entirelyRequired); + if ($entirelyRequired) { + $descriptions[] = $form->getView()->translate( + 'All fields are required and must be filled in to complete the form.' + ); + } elseif ($entirelyRequired === false) { + $descriptions[] = $form->getView()->translate(sprintf( + 'Required fields are marked with %s and must be filled in to complete the form.', + $form->getRequiredCue() + )); + } + + if (empty($descriptions)) { + return $content; + } + + $html = '
    '; + foreach ($descriptions as $description) { + if (is_array($description)) { + list($description, $properties) = $description; + $html .= 'propertiesToString($properties) . '>' . $view->escape($description) . ''; + } else { + $html .= '
  • ' . $view->escape($description) . '
  • '; + } + } + + switch ($this->getPlacement()) { + case self::APPEND: + return $content . $html . '
'; + case self::PREPEND: + return $html . '' . $content; + } + } + + /** + * Recurse the given form and return the descriptions for it and all of its subforms + * + * @param Form $form The form to recurse + * @param mixed $entirelyRequired Set by reference, true means all elements in the hierarchy are + * required, false only a partial subset and null none at all + * @param bool $elementsPassed Whether there were any elements passed during the recursion until now + * + * @return array + */ + protected function recurseForm(Form $form, & $entirelyRequired = null, $elementsPassed = false) + { + $requiredLabels = array(); + if ($form->getRequiredCue() !== null) { + $partiallyRequired = $partiallyOptional = false; + foreach ($form->getElements() as $element) { + if (! in_array($element->getType(), $this->blacklist)) { + if (! $element->isRequired()) { + $partiallyOptional = true; + if ($entirelyRequired) { + $entirelyRequired = false; + } + } else { + $partiallyRequired = true; + if (($label = $element->getDecorator('label')) !== false) { + $requiredLabels[] = $label; + } + } + } + } + + if (! $elementsPassed) { + $elementsPassed = $partiallyRequired || $partiallyOptional; + if ($entirelyRequired === null && $partiallyRequired) { + $entirelyRequired = ! $partiallyOptional; + } + } elseif ($entirelyRequired === null && $partiallyRequired) { + $entirelyRequired = false; + } + } + + $descriptions = array($form->getDescriptions()); + foreach ($form->getSubForms() as $subForm) { + $descriptions[] = $this->recurseForm($subForm, $entirelyRequired, $elementsPassed); + } + + if ($entirelyRequired) { + foreach ($requiredLabels as $label) { + $label->setRequiredSuffix(''); + } + } + + return call_user_func_array('array_merge', $descriptions); + } +} diff --git a/library/Icinga/Web/Form/Decorator/Help.php b/library/Icinga/Web/Form/Decorator/Help.php new file mode 100644 index 0000000000..152d548afd --- /dev/null +++ b/library/Icinga/Web/Form/Decorator/Help.php @@ -0,0 +1,110 @@ + should be created to describe the decorated form element + * + * @var bool + */ + protected $accessible = false; + + /** + * The id used to identify the description associated with the decorated form element + * + * @var string + */ + protected $descriptionId; + + /** + * Set whether a hidden should be created to describe the decorated form element + * + * @param bool $state + * + * @return Help + */ + public function setAccessible($state = true) + { + $this->accessible = (bool) $state; + return $this; + } + + /** + * Return the id used to identify the description associated with the decorated element + * + * @param Zend_Form_Element $element The element for which to generate a id + * + * @return string + */ + public function getDescriptionId(Zend_Form_Element $element = null) + { + if ($this->descriptionId === null) { + $element = $element ?: $this->getElement(); + $this->descriptionId = 'desc_' . $element->getId(); + } + + return $this->descriptionId; + } + + /** + * Return the current view + * + * @return View + */ + protected function getView() + { + return Icinga::app()->getViewRenderer()->view; + } + + /** + * Add a help icon to the left of an element + * + * @param string $content The html rendered so far + * + * @return string The updated html + */ + public function render($content = '') + { + $element = $this->getElement(); + $description = $element->getDescription(); + $requirement = $element->getAttrib('requirement'); + unset($element->requirement); + + $helpContent = ''; + if ($description || $requirement) { + if ($this->accessible) { + $helpContent = '' + . $description + . ($description && $requirement ? ' ' : '') + . $requirement + . ''; + } + + $helpContent = $this->getView()->icon( + 'help', + $description . ($description && $requirement ? ' ' : '') . $requirement, + array('aria-hidden' => $this->accessible ? 'true' : 'false') + ) . $helpContent; + } + + switch ($this->getPlacement()) { + case self::APPEND: + return $content . $helpContent; + case self::PREPEND: + return $helpContent . $content; + } + } +} diff --git a/library/Icinga/Web/Form/Decorator/NoScriptApply.php b/library/Icinga/Web/Form/Decorator/NoScriptApply.php deleted file mode 100644 index fbc96756b4..0000000000 --- a/library/Icinga/Web/Form/Decorator/NoScriptApply.php +++ /dev/null @@ -1,34 +0,0 @@ -'; - } - - return $content; - } -} diff --git a/library/Icinga/Web/Request.php b/library/Icinga/Web/Request.php index 4dd57df910..90551b33c5 100644 --- a/library/Icinga/Web/Request.php +++ b/library/Icinga/Web/Request.php @@ -18,6 +18,11 @@ class Request extends Zend_Controller_Request_Http */ private $user; + /** + * @var string + */ + private $uniqueId; + private $url; public function getUrl() @@ -47,4 +52,19 @@ public function getUser() { return $this->user; } + + /** + * Makes an ID unique to this request, to prevent id collisions in different containers + * + * Call this whenever an ID might show up multiple times in different containers. This function is useful + * for ensuring unique ids on sites, even if we combine the HTML of different requests into one site, + * while still being able to reference elements uniquely in the same request. + */ + public function protectId($id) + { + if (! isset($this->uniqueId)) { + $this->uniqueId = Window::generateId(); + } + return $id . '-' . $this->uniqueId; + } } diff --git a/library/Icinga/Web/StyleSheet.php b/library/Icinga/Web/StyleSheet.php index bff60b68a4..3f1e2b2a7c 100644 --- a/library/Icinga/Web/StyleSheet.php +++ b/library/Icinga/Web/StyleSheet.php @@ -13,6 +13,7 @@ class StyleSheet '../application/fonts/fontello-ifont/css/ifont-embedded.css', 'css/vendor/tipsy.css', 'css/icinga/defaults.less', + 'css/icinga/animation.less', 'css/icinga/layout-colors.less', 'css/icinga/layout-structure.less', 'css/icinga/menu.less', diff --git a/library/Icinga/Web/View/helpers/url.php b/library/Icinga/Web/View/helpers/url.php index 925a225f95..39e8de9518 100644 --- a/library/Icinga/Web/View/helpers/url.php +++ b/library/Icinga/Web/View/helpers/url.php @@ -53,11 +53,12 @@ $properties['alt'] = ''; } + $ariaHidden = array_key_exists('aria-hidden', $properties) ? $properties['aria-hidden'] : null; if (array_key_exists('title', $properties)) { - if (! array_key_exists('aria-label', $properties)) { + if (! array_key_exists('aria-label', $properties) && $ariaHidden !== 'true') { $properties['aria-label'] = $properties['title']; } - } elseif (! array_key_exists('aria-hidden', $properties)) { + } elseif ($ariaHidden === null) { $properties['aria-hidden'] = 'true'; } @@ -79,14 +80,15 @@ return $view->img('img/icons/' . $img, $properties); } + $ariaHidden = array_key_exists('aria-hidden', $properties) ? $properties['aria-hidden'] : null; if ($title !== null) { $properties['role'] = 'img'; $properties['title'] = $title; - if (! array_key_exists('aria-label', $properties)) { + if (! array_key_exists('aria-label', $properties) && $ariaHidden !== 'true') { $properties['aria-label'] = $title; } - } elseif (! array_key_exists('aria-hidden', $properties)) { + } elseif ($ariaHidden === null) { $properties['aria-hidden'] = 'true'; } diff --git a/library/Icinga/Web/Widget/AbstractWidget.php b/library/Icinga/Web/Widget/AbstractWidget.php index a1c1a244ee..e047d75120 100644 --- a/library/Icinga/Web/Widget/AbstractWidget.php +++ b/library/Icinga/Web/Widget/AbstractWidget.php @@ -26,7 +26,7 @@ abstract class AbstractWidget { /** * If you are going to access the current view with the view() function, - * it's instance is stored here for performance reasons. + * its instance is stored here for performance reasons. * * @var Zend_View_Abstract */ diff --git a/library/Icinga/Web/Widget/Dashboard.php b/library/Icinga/Web/Widget/Dashboard.php index 00d39cd71f..258c9cf2e7 100644 --- a/library/Icinga/Web/Widget/Dashboard.php +++ b/library/Icinga/Web/Widget/Dashboard.php @@ -18,7 +18,7 @@ * * The terminology is as follows: * - Dashlet: A single view showing a specific url - * - Pane: Aggregates one or more dashlets on one page, displays it's title as a tab + * - Pane: Aggregates one or more dashlets on one page, displays its title as a tab * - Dashboard: Shows all panes * */ @@ -347,7 +347,7 @@ public function render() } /** - * Activates the default pane of this dashboard and returns it's name + * Activates the default pane of this dashboard and returns its name * * @return mixed */ diff --git a/library/Icinga/Web/Widget/FilterEditor.php b/library/Icinga/Web/Widget/FilterEditor.php index 0a8de55867..8bcb9aa60e 100644 --- a/library/Icinga/Web/Widget/FilterEditor.php +++ b/library/Icinga/Web/Widget/FilterEditor.php @@ -310,7 +310,7 @@ protected function removeLink(Filter $filter) $this->preservedUrl()->with('removeFilter', $filter->getId()), null, array( - 'icon' => 'icon-cancel', + 'icon' => 'trash', 'title' => t('Remove this part of your filter') ) ); @@ -323,7 +323,7 @@ protected function addLink(Filter $filter) $this->preservedUrl()->with('addFilter', $filter->getId()), null, array( - 'icon' => 'icon-plus', + 'icon' => 'plus', 'title' => t('Add another filter') ) ); @@ -336,7 +336,7 @@ protected function stripLink(Filter $filter) $this->preservedUrl()->with('stripFilter', $filter->getId()), null, array( - 'icon' => 'icon-minus', + 'icon' => 'minus', 'title' => t('Strip this filter') ) ); @@ -349,7 +349,7 @@ protected function cancelLink() $this->preservedUrl()->without('addFilter'), null, array( - 'icon' => 'icon-cancel', + 'icon' => 'cancel', 'title' => t('Cancel this operation') ) ); diff --git a/library/Icinga/Web/Widget/Tab.php b/library/Icinga/Web/Widget/Tab.php index 94e2bc6783..c7fb30ff89 100644 --- a/library/Icinga/Web/Widget/Tab.php +++ b/library/Icinga/Web/Widget/Tab.php @@ -42,6 +42,11 @@ class Tab extends AbstractWidget */ private $title = ''; + /** + * The label displayed for this tab + * + * @var string + */ private $label = ''; /** @@ -118,11 +123,26 @@ public function getName() return $this->name; } + /** + * Set the tab label + * + * @param string $label + */ public function setLabel($label) { $this->label = $label; } + /** + * Get the tab label + * + * @return string + */ + public function getLabel() + { + return $this->label; + } + /** * @param mixed $title */ diff --git a/library/Icinga/Web/Widget/Tabs.php b/library/Icinga/Web/Widget/Tabs.php index 2027712377..4952d29b1a 100644 --- a/library/Icinga/Web/Widget/Tabs.php +++ b/library/Icinga/Web/Widget/Tabs.php @@ -4,6 +4,7 @@ namespace Icinga\Web\Widget; use Icinga\Exception\ProgrammingError; +use Icinga\Web\Url; use Icinga\Web\Widget\Tabextension\Tabextension; use Icinga\Application\Icinga; use Countable; @@ -23,6 +24,7 @@ class Tabs extends AbstractWidget implements Countable
    {TABS} {DROPDOWN} + {REFRESH} {CLOSE}
EOT; @@ -59,6 +61,18 @@ class Tabs extends AbstractWidget implements Countable EOT; + /** + * Template used for the refresh icon + * + * @var string + */ + private $refreshTpl = <<< 'EOT' +
  • + + + +
  • +EOT; /** * This is where single tabs added to this container will be stored @@ -193,7 +207,7 @@ public function get($name) * with tab properties or an instance of an existing Tab * * @param string $name The new tab name - * @param array|Tab $tab The tab itself of it's properties + * @param array|Tab $tab The tab itself of its properties * * @return self * @@ -218,7 +232,7 @@ public function add($name, $tab) * of an existing Tab * * @param string $name The new tab name - * @param array|Tab $tab The tab itself of it's properties + * @param array|Tab $tab The tab itself of its properties * * @return self */ @@ -265,7 +279,7 @@ public function addAsDropdown($name, $tab) } /** - * Render the dropdown area with it's tabs and return the resulting HTML + * Render the dropdown area with its tabs and return the resulting HTML * * @return mixed|string */ @@ -308,6 +322,43 @@ private function renderCloseTab() return $this->closeTpl; } + private function renderRefreshTab() + { + $url = Url::fromRequest()->without('renderLayout'); + $tab = $this->get($this->getActiveName()); + + if ($tab !== null) { + $label = $this->view()->escape( + $tab->getLabel() + ); + } + + if (! empty($label)) { + $caption = $label; + } else { + $caption = t('Content'); + } + + $label = t(sprintf('Refresh the %s', $caption)); + $title = $label; + + $tpl = str_replace( + array( + '{URL}', + '{TITLE}', + '{LABEL}' + ), + array( + $url, + $title, + $label + ), + $this->refreshTpl + ); + + return $tpl; + } + /** * Render to HTML * @@ -323,11 +374,13 @@ public function render() $drop = $this->renderDropdownTabs(); } $close = $this->closeTab ? $this->renderCloseTab() : ''; + $refresh = $this->renderRefreshTab(); return str_replace( array( '{TABS}', '{DROPDOWN}', + '{REFRESH}', '{CLOSE}', '{HEADER}' ), @@ -335,6 +388,7 @@ public function render() $tabs, $drop, $close, + $refresh, $this->renderHeader() ), $this->baseTpl diff --git a/modules/doc/application/controllers/StyleController.php b/modules/doc/application/controllers/StyleController.php index 8e21a62759..8661d024a4 100644 --- a/modules/doc/application/controllers/StyleController.php +++ b/modules/doc/application/controllers/StyleController.php @@ -24,14 +24,15 @@ protected function tabs() return Widget::create('tabs')->add( 'guide', array( - 'title' => $this->translate('Style Guide'), - 'url' => 'doc/style/guide' + 'label' => $this->translate('Style Guide'), + 'url' => 'doc/style/guide' ) )->add( 'font', array( - 'title' => $this->translate('Icons'), - 'url' => 'doc/style/font' + 'label' => $this->translate('Icons'), + 'title' => $this->translate('List all available icons'), + 'url' => 'doc/style/font' ) ); } diff --git a/modules/doc/module.info b/modules/doc/module.info index 1689fd9402..2c6f48ac95 100644 --- a/modules/doc/module.info +++ b/modules/doc/module.info @@ -1,4 +1,4 @@ Module: doc Version: 2.0.0 Description: Documentation module - Extracts, shows and exports documentation for Icinga Web 2 and it's modules. + Extracts, shows and exports documentation for Icinga Web 2 and its modules. diff --git a/modules/monitoring/application/controllers/ConfigController.php b/modules/monitoring/application/controllers/ConfigController.php index 7d4c07de08..2571b071e6 100644 --- a/modules/monitoring/application/controllers/ConfigController.php +++ b/modules/monitoring/application/controllers/ConfigController.php @@ -30,6 +30,7 @@ public function indexAction() public function editbackendAction() { $form = new BackendConfigForm(); + $form->setTitle($this->translate('Edit Existing Backend')); $form->setIniConfig($this->Config('backends')); $form->setResourceConfig(ResourceFactory::getResourceConfigs()); $form->setRedirectUrl('monitoring/config'); @@ -44,6 +45,7 @@ public function editbackendAction() public function createbackendAction() { $form = new BackendConfigForm(); + $form->setTitle($this->translate('Add New Backend')); $form->setIniConfig($this->Config('backends')); $form->setResourceConfig(ResourceFactory::getResourceConfigs()); $form->setRedirectUrl('monitoring/config'); @@ -72,12 +74,16 @@ public function removebackendAction() } if ($configForm->save()) { - Notification::success(sprintf(mt('monitoring', 'Backend "%s" successfully removed.'), $backendName)); + Notification::success(sprintf( + $this->translate('Backend "%s" successfully removed.'), + $backendName + )); } else { return false; } } )); + $form->setTitle($this->translate('Remove Existing Backend')); $form->setRedirectUrl('monitoring/config'); $form->handleRequest(); @@ -104,12 +110,31 @@ public function removeinstanceAction() } if ($configForm->save()) { - Notification::success(sprintf(mt('monitoring', 'Instance "%s" successfully removed.'), $instanceName)); + Notification::success(sprintf( + $this->translate('Instance "%s" successfully removed.'), + $instanceName + )); } else { return false; } } )); + $form->setTitle($this->translate('Remove Existing Instance')); + $form->addDescription($this->translate( + 'If you have still any environments or views referring to this instance, ' + . 'you won\'t be able to send commands anymore after deletion.' + )); + $form->addElement( + 'note', + 'question', + array( + 'value' => $this->translate('Are you sure you want to remove this instance?'), + 'decorators' => array( + 'ViewHelper', + array('HtmlTag', array('tag' => 'p')) + ) + ) + ); $form->setRedirectUrl('monitoring/config'); $form->handleRequest(); @@ -122,6 +147,7 @@ public function removeinstanceAction() public function editinstanceAction() { $form = new InstanceConfigForm(); + $form->setTitle($this->translate('Edit Existing Instance')); $form->setIniConfig($this->Config('instances')); $form->setRedirectUrl('monitoring/config'); $form->handleRequest(); @@ -135,6 +161,7 @@ public function editinstanceAction() public function createinstanceAction() { $form = new InstanceConfigForm(); + $form->setTitle($this->translate('Add New Instance')); $form->setIniConfig($this->Config('instances')); $form->setRedirectUrl('monitoring/config'); $form->handleRequest(); diff --git a/modules/monitoring/application/controllers/HostController.php b/modules/monitoring/application/controllers/HostController.php index 9cf3b26ab0..4a29750e3e 100644 --- a/modules/monitoring/application/controllers/HostController.php +++ b/modules/monitoring/application/controllers/HostController.php @@ -66,8 +66,9 @@ public function acknowledgeProblemAction() { $this->assertPermission('monitoring/command/acknowledge-problem'); - $this->view->title = $this->translate('Acknowledge Host Problem'); - $this->handleCommandForm(new AcknowledgeProblemCommandForm()); + $form = new AcknowledgeProblemCommandForm(); + $form->setTitle($this->translate('Acknowledge Host Problem')); + $this->handleCommandForm($form); } /** @@ -77,8 +78,9 @@ public function addCommentAction() { $this->assertPermission('monitoring/command/comment/add'); - $this->view->title = $this->translate('Add Host Comment'); - $this->handleCommandForm(new AddCommentCommandForm()); + $form = new AddCommentCommandForm(); + $form->setTitle($this->translate('Add Host Comment')); + $this->handleCommandForm($form); } /** @@ -88,8 +90,9 @@ public function rescheduleCheckAction() { $this->assertPermission('monitoring/command/schedule-check'); - $this->view->title = $this->translate('Reschedule Host Check'); - $this->handleCommandForm(new ScheduleHostCheckCommandForm()); + $form = new ScheduleHostCheckCommandForm(); + $form->setTitle($this->translate('Reschedule Host Check')); + $this->handleCommandForm($form); } /** @@ -99,8 +102,9 @@ public function scheduleDowntimeAction() { $this->assertPermission('monitoring/command/downtime/schedule'); - $this->view->title = $this->translate('Schedule Host Downtime'); - $this->handleCommandForm(new ScheduleHostDowntimeCommandForm()); + $form = new ScheduleHostDowntimeCommandForm(); + $form->setTitle($this->translate('Schedule Host Downtime')); + $this->handleCommandForm($form); } /** @@ -110,7 +114,8 @@ public function processCheckResultAction() { $this->assertPermission('monitoring/command/process-check-result'); - $this->view->title = $this->translate('Submit Passive Host Check Result'); - $this->handleCommandForm(new ProcessCheckResultCommandForm()); + $form = new ProcessCheckResultCommandForm(); + $form->setTitle($this->translate('Submit Passive Host Check Result')); + $this->handleCommandForm($form); } } diff --git a/modules/monitoring/application/controllers/HostsController.php b/modules/monitoring/application/controllers/HostsController.php index de1f063ac3..5dc72eeb05 100644 --- a/modules/monitoring/application/controllers/HostsController.php +++ b/modules/monitoring/application/controllers/HostsController.php @@ -175,8 +175,9 @@ public function acknowledgeProblemAction() { $this->assertPermission('monitoring/command/acknowledge-problem'); - $this->view->title = $this->translate('Acknowledge Host Problems'); - $this->handleCommandForm(new AcknowledgeProblemCommandForm()); + $form = new AcknowledgeProblemCommandForm(); + $form->setTitle($this->translate('Acknowledge Host Problems')); + $this->handleCommandForm($form); } /** @@ -186,8 +187,9 @@ public function rescheduleCheckAction() { $this->assertPermission('monitoring/command/schedule-check'); - $this->view->title = $this->translate('Reschedule Host Checks'); - $this->handleCommandForm(new ScheduleHostCheckCommandForm()); + $form = new ScheduleHostCheckCommandForm(); + $form->setTitle($this->translate('Reschedule Host Checks')); + $this->handleCommandForm($form); } /** @@ -197,8 +199,9 @@ public function scheduleDowntimeAction() { $this->assertPermission('monitoring/command/downtime/schedule'); - $this->view->title = $this->translate('Schedule Host Downtimes'); - $this->handleCommandForm(new ScheduleHostDowntimeCommandForm()); + $form = new ScheduleHostDowntimeCommandForm(); + $form->setTitle($this->translate('Schedule Host Downtimes')); + $this->handleCommandForm($form); } /** @@ -208,7 +211,8 @@ public function processCheckResultAction() { $this->assertPermission('monitoring/command/process-check-result'); - $this->view->title = $this->translate('Submit Passive Host Check Results'); - $this->handleCommandForm(new ProcessCheckResultCommandForm()); + $form = new ProcessCheckResultCommandForm(); + $form->setTitle($this->translate('Submit Passive Host Check Results')); + $this->handleCommandForm($form); } } diff --git a/modules/monitoring/application/controllers/ListController.php b/modules/monitoring/application/controllers/ListController.php index 3fb7828566..b1b96b4773 100644 --- a/modules/monitoring/application/controllers/ListController.php +++ b/modules/monitoring/application/controllers/ListController.php @@ -397,6 +397,7 @@ public function eventgridAction() $form->render(); $this->view->form = $form; + $this->params->remove('view'); $orientation = $this->params->shift('vertical', 0) ? 'vertical' : 'horizontal'; /* $orientationBox = new SelectBox( @@ -702,7 +703,7 @@ protected function extraColumns() private function setupSortControl(array $columns) { $this->view->sortControl = new SortBox( - $this->getRequest()->getActionName(), + 'sortbox-' . $this->getRequest()->getActionName(), $columns ); $this->view->sortControl->applyRequest($this->getRequest()); diff --git a/modules/monitoring/application/controllers/ServiceController.php b/modules/monitoring/application/controllers/ServiceController.php index 19906f5d2f..d717a8e1cd 100644 --- a/modules/monitoring/application/controllers/ServiceController.php +++ b/modules/monitoring/application/controllers/ServiceController.php @@ -43,8 +43,9 @@ public function acknowledgeProblemAction() { $this->assertPermission('monitoring/command/acknowledge-problem'); - $this->view->title = $this->translate('Acknowledge Service Problem'); - $this->handleCommandForm(new AcknowledgeProblemCommandForm()); + $form = new AcknowledgeProblemCommandForm(); + $form->setTitle($this->translate('Acknowledge Service Problem')); + $this->handleCommandForm($form); } /** @@ -54,8 +55,9 @@ public function addCommentAction() { $this->assertPermission('monitoring/command/comment/add'); - $this->view->title = $this->translate('Add Service Comment'); - $this->handleCommandForm(new AddCommentCommandForm()); + $form = new AddCommentCommandForm(); + $form->setTitle($this->translate('Add Service Comment')); + $this->handleCommandForm($form); } /** @@ -65,8 +67,9 @@ public function rescheduleCheckAction() { $this->assertPermission('monitoring/command/schedule-check'); - $this->view->title = $this->translate('Reschedule Service Check'); - $this->handleCommandForm(new ScheduleServiceCheckCommandForm()); + $form = new ScheduleServiceCheckCommandForm(); + $form->setTitle($this->translate('Reschedule Service Check')); + $this->handleCommandForm($form); } /** @@ -76,8 +79,9 @@ public function scheduleDowntimeAction() { $this->assertPermission('monitoring/command/downtime/schedule'); - $this->view->title = $this->translate('Schedule Service Downtime'); - $this->handleCommandForm(new ScheduleServiceDowntimeCommandForm()); + $form = new ScheduleServiceDowntimeCommandForm(); + $form->setTitle($this->translate('Schedule Service Downtime')); + $this->handleCommandForm($form); } /** @@ -87,7 +91,8 @@ public function processCheckResultAction() { $this->assertPermission('monitoring/command/process-check-result'); - $this->view->title = $this->translate('Submit Passive Service Check Result'); - $this->handleCommandForm(new ProcessCheckResultCommandForm()); + $form = new ProcessCheckResultCommandForm(); + $form->setTitle($this->translate('Submit Passive Service Check Result')); + $this->handleCommandForm($form); } } diff --git a/modules/monitoring/application/controllers/ServicesController.php b/modules/monitoring/application/controllers/ServicesController.php index a74b610742..1e907aab9a 100644 --- a/modules/monitoring/application/controllers/ServicesController.php +++ b/modules/monitoring/application/controllers/ServicesController.php @@ -224,8 +224,9 @@ public function acknowledgeProblemAction() { $this->assertPermission('monitoring/command/acknowledge-problem'); - $this->view->title = $this->translate('Acknowledge Service Problems'); - $this->handleCommandForm(new AcknowledgeProblemCommandForm()); + $form = new AcknowledgeProblemCommandForm(); + $form->setTitle($this->translate('Acknowledge Service Problems')); + $this->handleCommandForm($form); } /** @@ -235,8 +236,9 @@ public function rescheduleCheckAction() { $this->assertPermission('monitoring/command/schedule-check'); - $this->view->title = $this->translate('Reschedule Service Checks'); - $this->handleCommandForm(new ScheduleServiceCheckCommandForm()); + $form = new ScheduleServiceCheckCommandForm(); + $form->setTitle($this->translate('Reschedule Service Checks')); + $this->handleCommandForm($form); } /** @@ -246,8 +248,9 @@ public function scheduleDowntimeAction() { $this->assertPermission('monitoring/command/downtime/schedule'); - $this->view->title = $this->translate('Schedule Service Downtimes'); - $this->handleCommandForm(new ScheduleServiceDowntimeCommandForm()); + $form = new ScheduleServiceDowntimeCommandForm(); + $form->setTitle($this->translate('Schedule Service Downtimes')); + $this->handleCommandForm($form); } /** @@ -257,7 +260,8 @@ public function processCheckResultAction() { $this->assertPermission('monitoring/command/process-check-result'); - $this->view->title = $this->translate('Submit Passive Service Check Results'); - $this->handleCommandForm(new ProcessCheckResultCommandForm()); + $form = new ProcessCheckResultCommandForm(); + $form->setTitle($this->translate('Submit Passive Service Check Results')); + $this->handleCommandForm($form); } } diff --git a/modules/monitoring/application/forms/Command/CommandForm.php b/modules/monitoring/application/forms/Command/CommandForm.php index dae5df9632..41a46f1107 100644 --- a/modules/monitoring/application/forms/Command/CommandForm.php +++ b/modules/monitoring/application/forms/Command/CommandForm.php @@ -43,16 +43,6 @@ public function getBackend() return $this->backend; } - /** - * Get the command help description - * - * @return string|null - */ - public function getHelp() - { - return null; - } - /** * Get the transport used to send commands * diff --git a/modules/monitoring/application/forms/Command/Instance/DisableNotificationsExpireCommandForm.php b/modules/monitoring/application/forms/Command/Instance/DisableNotificationsExpireCommandForm.php index 96f7f80d38..e69b9ea112 100644 --- a/modules/monitoring/application/forms/Command/Instance/DisableNotificationsExpireCommandForm.php +++ b/modules/monitoring/application/forms/Command/Instance/DisableNotificationsExpireCommandForm.php @@ -20,18 +20,11 @@ class DisableNotificationsExpireCommandForm extends CommandForm */ public function init() { + $this->setRequiredCue(null); $this->setSubmitLabel($this->translate('Disable Notifications')); - } - - /** - * (non-PHPDoc) - * @see \Icinga\Module\Monitoring\Forms\Command\CommandForm::getHelp() For the method documentation. - */ - public function getHelp() - { - return $this->translate( + $this->addDescription($this->translate( 'This command is used to disable host and service notifications for a specific time.' - ); + )); } /** diff --git a/modules/monitoring/application/forms/Command/Instance/ToggleInstanceFeaturesCommandForm.php b/modules/monitoring/application/forms/Command/Instance/ToggleInstanceFeaturesCommandForm.php index 692ed6094c..ec58bb4b62 100644 --- a/modules/monitoring/application/forms/Command/Instance/ToggleInstanceFeaturesCommandForm.php +++ b/modules/monitoring/application/forms/Command/Instance/ToggleInstanceFeaturesCommandForm.php @@ -25,7 +25,10 @@ class ToggleInstanceFeaturesCommandForm extends CommandForm */ public function init() { + $this->setUseFormAutosubmit(); + $this->setTitle($this->translate('Feature Commands')); $this->setAttrib('class', 'inline instance-features'); + $this->loadDefaultDecorators()->getDecorator('description')->setTag('h2'); } /** diff --git a/modules/monitoring/application/forms/Command/Object/AcknowledgeProblemCommandForm.php b/modules/monitoring/application/forms/Command/Object/AcknowledgeProblemCommandForm.php index 6f12353630..ef6d626b37 100644 --- a/modules/monitoring/application/forms/Command/Object/AcknowledgeProblemCommandForm.php +++ b/modules/monitoring/application/forms/Command/Object/AcknowledgeProblemCommandForm.php @@ -14,27 +14,24 @@ class AcknowledgeProblemCommandForm extends ObjectsCommandForm { /** - * (non-PHPDoc) - * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. + * Initialize this form */ - public function getSubmitLabel() + public function init() { - return mtp( - 'monitoring', 'Acknowledge problem', 'Acknowledge problems', count($this->objects) - ); + $this->addDescription($this->translate( + 'This command is used to acknowledge host or service problems. When a problem is acknowledged,' + . ' future notifications about problems are temporarily disabled until the host or service' + . ' recovers.' + )); } /** * (non-PHPDoc) - * @see \Icinga\Module\Monitoring\Forms\Command\CommandForm::getHelp() For the method documentation. + * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. */ - public function getHelp() + public function getSubmitLabel() { - return $this->translate( - 'This command is used to acknowledge host or service problems. When a problem is acknowledged,' - . ' future notifications about problems are temporarily disabled until the host or service' - . ' recovers.' - ); + return $this->translatePlural('Acknowledge problem', 'Acknowledge problems', count($this->objects)); } /** @@ -156,8 +153,7 @@ public function onSuccess() } $this->getTransport($this->request)->send($ack); } - Notification::success(mtp( - 'monitoring', + Notification::success($this->translatePlural( 'Acknowledging problem..', 'Acknowledging problems..', count($this->objects) diff --git a/modules/monitoring/application/forms/Command/Object/AddCommentCommandForm.php b/modules/monitoring/application/forms/Command/Object/AddCommentCommandForm.php index eee6713972..d167061f9c 100644 --- a/modules/monitoring/application/forms/Command/Object/AddCommentCommandForm.php +++ b/modules/monitoring/application/forms/Command/Object/AddCommentCommandForm.php @@ -12,25 +12,20 @@ class AddCommentCommandForm extends ObjectsCommandForm { /** - * (non-PHPDoc) - * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. + * Initialize this form */ - public function getSubmitLabel() + public function init() { - return mtp( - 'monitoring', 'Add comment', 'Add comments', count($this->objects) - ); + $this->addDescription($this->translate('This command is used to add host or service comments.')); } /** * (non-PHPDoc) - * @see \Icinga\Module\Monitoring\Forms\Command\CommandForm::getHelp() For the method documentation. + * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. */ - public function getHelp() + public function getSubmitLabel() { - return $this->translate( - 'This command is used to add host or service comments.' - ); + return $this->translatePlural('Add comment', 'Add comments', count($this->objects)); } /** @@ -84,8 +79,7 @@ public function onSuccess() $comment->setPersistent($this->getElement('persistent')->isChecked()); $this->getTransport($this->request)->send($comment); } - Notification::success(mtp( - 'monitoring', + Notification::success($this->translatePlural( 'Adding comment..', 'Adding comments..', count($this->objects) diff --git a/modules/monitoring/application/forms/Command/Object/CheckNowCommandForm.php b/modules/monitoring/application/forms/Command/Object/CheckNowCommandForm.php index c272b4c30f..e5cf6b9e42 100644 --- a/modules/monitoring/application/forms/Command/Object/CheckNowCommandForm.php +++ b/modules/monitoring/application/forms/Command/Object/CheckNowCommandForm.php @@ -39,7 +39,7 @@ public function addSubmitButton() . $this->translate('Check now'), 'decorators' => array('ViewHelper'), 'escape' => false, - 'class' => 'link-like', + 'class' => 'link-like spinner', 'title' => $this->translate('Schedule the next active check to run immediately') ) ) diff --git a/modules/monitoring/application/forms/Command/Object/ProcessCheckResultCommandForm.php b/modules/monitoring/application/forms/Command/Object/ProcessCheckResultCommandForm.php index 1a357bdcee..ec80a539fb 100644 --- a/modules/monitoring/application/forms/Command/Object/ProcessCheckResultCommandForm.php +++ b/modules/monitoring/application/forms/Command/Object/ProcessCheckResultCommandForm.php @@ -12,24 +12,23 @@ class ProcessCheckResultCommandForm extends ObjectsCommandForm { /** - * (non-PHPDoc) - * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. + * Initialize this form */ - public function getSubmitLabel() + public function init() { - return mtp( - 'monitoring', 'Submit Passive Check Result', 'Submit Passive Check Results', count($this->objects) - ); + $this->addDescription($this->translate( + 'This command is used to submit passive host or service check results.' + )); } /** * (non-PHPDoc) - * @see \Icinga\Module\Monitoring\Forms\Command\CommandForm::getHelp() For the method documentation. + * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. */ - public function getHelp() + public function getSubmitLabel() { - return $this->translate( - 'This command is used to submit passive host or service check results.' + return $this->translatePlural( + 'Submit Passive Check Result', 'Submit Passive Check Results', count($this->objects) ); } @@ -108,8 +107,7 @@ public function onSuccess() $this->getTransport($this->request)->send($command); } - Notification::success(mtp( - 'monitoring', + Notification::success($this->translatePlural( 'Processing check result..', 'Processing check results..', count($this->objects) diff --git a/modules/monitoring/application/forms/Command/Object/ScheduleHostCheckCommandForm.php b/modules/monitoring/application/forms/Command/Object/ScheduleHostCheckCommandForm.php index 7789460e35..0fa748fc4e 100644 --- a/modules/monitoring/application/forms/Command/Object/ScheduleHostCheckCommandForm.php +++ b/modules/monitoring/application/forms/Command/Object/ScheduleHostCheckCommandForm.php @@ -47,8 +47,7 @@ public function onSuccess() ->setOfAllServices($this->getElement('all_services')->isChecked()); $this->scheduleCheck($check, $this->request); } - Notification::success(mtp( - 'monitoring', + Notification::success($this->translatePlural( 'Scheduling host check..', 'Scheduling host checks..', count($this->objects) diff --git a/modules/monitoring/application/forms/Command/Object/ScheduleHostDowntimeCommandForm.php b/modules/monitoring/application/forms/Command/Object/ScheduleHostDowntimeCommandForm.php index 6c7823dca0..c35cb5413b 100644 --- a/modules/monitoring/application/forms/Command/Object/ScheduleHostDowntimeCommandForm.php +++ b/modules/monitoring/application/forms/Command/Object/ScheduleHostDowntimeCommandForm.php @@ -7,7 +7,6 @@ use Icinga\Module\Monitoring\Command\Object\ScheduleHostDowntimeCommand; use Icinga\Module\Monitoring\Command\Object\ScheduleServiceDowntimeCommand; use Icinga\Web\Notification; -use Icinga\Web\Request; /** * Form for scheduling host downtimes @@ -83,8 +82,7 @@ public function onSuccess() $hostDowntime->setObject($object); $this->scheduleDowntime($hostDowntime, $this->request); } - Notification::success(mtp( - 'monitoring', + Notification::success($this->translatePlural( 'Scheduling host downtime..', 'Scheduling host downtimes..', count($this->objects) diff --git a/modules/monitoring/application/forms/Command/Object/ScheduleServiceCheckCommandForm.php b/modules/monitoring/application/forms/Command/Object/ScheduleServiceCheckCommandForm.php index e6686a9b87..f0f15559e1 100644 --- a/modules/monitoring/application/forms/Command/Object/ScheduleServiceCheckCommandForm.php +++ b/modules/monitoring/application/forms/Command/Object/ScheduleServiceCheckCommandForm.php @@ -15,26 +15,23 @@ class ScheduleServiceCheckCommandForm extends ObjectsCommandForm { /** - * (non-PHPDoc) - * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. + * Initialize this form */ - public function getSubmitLabel() + public function init() { - return mtp( - 'monitoring', 'Schedule check', 'Schedule checks', count($this->objects) - ); + $this->addDescription($this->translate( + 'This command is used to schedule the next check of hosts or services. Icinga will re-queue the' + . ' hosts or services to be checked at the time you specify.' + )); } /** * (non-PHPDoc) - * @see \Icinga\Module\Monitoring\Forms\Command\CommandForm::getHelp() For the method documentation. + * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. */ - public function getHelp() + public function getSubmitLabel() { - return $this->translate( - 'This command is used to schedule the next check of hosts or services. Icinga will re-queue the' - . ' hosts or services to be checked at the time you specify.' - ); + return $this->translatePlural('Schedule check', 'Schedule checks', count($this->objects)); } /** @@ -99,8 +96,7 @@ public function onSuccess() $check->setObject($object); $this->scheduleCheck($check, $this->request); } - Notification::success(mtp( - 'monitoring', + Notification::success($this->translatePlural( 'Scheduling service check..', 'Scheduling service checks..', count($this->objects) diff --git a/modules/monitoring/application/forms/Command/Object/ScheduleServiceDowntimeCommandForm.php b/modules/monitoring/application/forms/Command/Object/ScheduleServiceDowntimeCommandForm.php index 00487e1153..627138a888 100644 --- a/modules/monitoring/application/forms/Command/Object/ScheduleServiceDowntimeCommandForm.php +++ b/modules/monitoring/application/forms/Command/Object/ScheduleServiceDowntimeCommandForm.php @@ -25,29 +25,26 @@ class ScheduleServiceDowntimeCommandForm extends ObjectsCommandForm const FLEXIBLE = 'flexible'; /** - * (non-PHPDoc) - * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. + * Initialize this form */ - public function getSubmitLabel() + public function init() { - return mtp( - 'monitoring', 'Schedule downtime', 'Schedule downtimes', count($this->objects) - ); + $this->addDescription($this->translate( + 'This command is used to schedule host and service downtimes. During the specified downtime,' + . ' Icinga will not send notifications out about the hosts and services. When the scheduled' + . ' downtime expires, Icinga will send out notifications for the hosts and services as it' + . ' normally would. Scheduled downtimes are preserved across program shutdowns and' + . ' restarts.' + )); } /** * (non-PHPDoc) - * @see \Icinga\Module\Monitoring\Forms\Command\CommandForm::getHelp() For the method documentation. + * @see \Icinga\Web\Form::getSubmitLabel() For the method documentation. */ - public function getHelp() + public function getSubmitLabel() { - return $this->translate( - 'This command is used to schedule host and service downtimes. During the specified downtime,' - . ' Icinga will not send notifications out about the hosts and services. When the scheduled' - . ' downtime expires, Icinga will send out notifications for the hosts and services as it' - . ' normally would. Scheduled downtimes are preserved across program shutdowns and' - . ' restarts.' - ); + return $this->translatePlural('Schedule downtime', 'Schedule downtimes', count($this->objects)); } /** @@ -206,8 +203,7 @@ public function onSuccess() $downtime->setObject($object); $this->scheduleDowntime($downtime, $this->request); } - Notification::success(mtp( - 'monitoring', + Notification::success($this->translatePlural( 'Scheduling service downtime..', 'Scheduling service downtimes..', count($this->objects) diff --git a/modules/monitoring/application/forms/Command/Object/ToggleObjectFeaturesCommandForm.php b/modules/monitoring/application/forms/Command/Object/ToggleObjectFeaturesCommandForm.php index 5caacb5f8a..a6c20f6309 100644 --- a/modules/monitoring/application/forms/Command/Object/ToggleObjectFeaturesCommandForm.php +++ b/modules/monitoring/application/forms/Command/Object/ToggleObjectFeaturesCommandForm.php @@ -18,7 +18,10 @@ class ToggleObjectFeaturesCommandForm extends ObjectsCommandForm */ public function init() { + $this->setUseFormAutosubmit(); + $this->setTitle('Feature Commands'); $this->setAttrib('class', 'inline object-features'); + $this->loadDefaultDecorators()->getDecorator('description')->setTag('h4'); } /** diff --git a/modules/monitoring/application/forms/Setup/BackendPage.php b/modules/monitoring/application/forms/Setup/BackendPage.php index f2df42a1ff..077ca35947 100644 --- a/modules/monitoring/application/forms/Setup/BackendPage.php +++ b/modules/monitoring/application/forms/Setup/BackendPage.php @@ -11,31 +11,14 @@ class BackendPage extends Form public function init() { $this->setName('setup_monitoring_backend'); + $this->setTitle($this->translate('Monitoring Backend', 'setup.page.title')); + $this->addDescription($this->translate( + 'Please configure below how Icinga Web 2 should retrieve monitoring information.' + )); } public function createElements(array $formData) { - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('Monitoring Backend', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - $this->addElement( - 'note', - 'description', - array( - 'value' => $this->translate( - 'Please configure below how Icinga Web 2 should retrieve monitoring information.' - ) - ) - ); - $this->addElement( 'text', 'name', diff --git a/modules/monitoring/application/forms/Setup/IdoResourcePage.php b/modules/monitoring/application/forms/Setup/IdoResourcePage.php index dac7d041fe..f526013593 100644 --- a/modules/monitoring/application/forms/Setup/IdoResourcePage.php +++ b/modules/monitoring/application/forms/Setup/IdoResourcePage.php @@ -11,6 +11,10 @@ class IdoResourcePage extends Form public function init() { $this->setName('setup_monitoring_ido'); + $this->setTitle($this->translate('Monitoring IDO Resource', 'setup.page.title')); + $this->addDescription($this->translate( + 'Please fill out the connection details below to access the IDO database of your monitoring environment.' + )); } public function createElements(array $formData) @@ -23,27 +27,6 @@ public function createElements(array $formData) 'value' => 'db' ) ); - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('Monitoring IDO Resource', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - $this->addElement( - 'note', - 'description', - array( - 'value' => $this->translate( - 'Please fill out the connection details below to access' - . ' the IDO database of your monitoring environment.' - ) - ) - ); if (isset($formData['skip_validation']) && $formData['skip_validation']) { $this->addSkipValidationCheckbox(); diff --git a/modules/monitoring/application/forms/Setup/InstancePage.php b/modules/monitoring/application/forms/Setup/InstancePage.php index 54e4bbba6e..25525ffaf7 100644 --- a/modules/monitoring/application/forms/Setup/InstancePage.php +++ b/modules/monitoring/application/forms/Setup/InstancePage.php @@ -11,31 +11,14 @@ class InstancePage extends Form public function init() { $this->setName('setup_monitoring_instance'); + $this->setTitle($this->translate('Monitoring Instance', 'setup.page.title')); + $this->addDescription($this->translate( + 'Please define the settings specific to your monitoring instance below.' + )); } public function createElements(array $formData) { - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('Monitoring Instance', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - $this->addElement( - 'note', - 'description', - array( - 'value' => $this->translate( - 'Please define the settings specific to your monitoring instance below.' - ) - ) - ); - if (isset($formData['host'])) { $formData['type'] = 'remote'; // This is necessary as the type element gets ignored by Form::getValues() } diff --git a/modules/monitoring/application/forms/Setup/LivestatusResourcePage.php b/modules/monitoring/application/forms/Setup/LivestatusResourcePage.php index ca50980d6a..48b688218d 100644 --- a/modules/monitoring/application/forms/Setup/LivestatusResourcePage.php +++ b/modules/monitoring/application/forms/Setup/LivestatusResourcePage.php @@ -11,6 +11,11 @@ class LivestatusResourcePage extends Form public function init() { $this->setName('setup_monitoring_livestatus'); + $this->setTitle($this->translate('Monitoring Livestatus Resource', 'setup.page.title')); + $this->addDescription($this->translate( + 'Please fill out the connection details below to access the Livestatus' + . ' socket interface for your monitoring environment.' + )); } public function createElements(array $formData) @@ -23,27 +28,6 @@ public function createElements(array $formData) 'value' => 'livestatus' ) ); - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('Monitoring Livestatus Resource', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - $this->addElement( - 'note', - 'description', - array( - 'value' => $this->translate( - 'Please fill out the connection details below to access the Livestatus' - . ' socket interface for your monitoring environment.' - ) - ) - ); if (isset($formData['skip_validation']) && $formData['skip_validation']) { $this->addSkipValidationCheckbox(); diff --git a/modules/monitoring/application/forms/Setup/SecurityPage.php b/modules/monitoring/application/forms/Setup/SecurityPage.php index 1921c58f47..30eac67ab5 100644 --- a/modules/monitoring/application/forms/Setup/SecurityPage.php +++ b/modules/monitoring/application/forms/Setup/SecurityPage.php @@ -11,31 +11,14 @@ class SecurityPage extends Form public function init() { $this->setName('setup_monitoring_security'); + $this->setTitle($this->translate('Monitoring Security', 'setup.page.title')); + $this->addDescription($this->translate( + 'To protect your monitoring environment against prying eyes please fill out the settings below.' + )); } public function createElements(array $formData) { - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('Monitoring Security', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - $this->addElement( - 'note', - 'description', - array( - 'value' => $this->translate( - 'To protect your monitoring environment against prying eyes please fill out the settings below.' - ) - ) - ); - $securityConfigForm = new SecurityConfigForm(); $securityConfigForm->createElements($formData); $this->addElements($securityConfigForm->getElements()); diff --git a/modules/monitoring/application/views/scripts/config/createbackend.phtml b/modules/monitoring/application/views/scripts/config/createbackend.phtml index 10ee02541d..d2c7b6bdd9 100644 --- a/modules/monitoring/application/views/scripts/config/createbackend.phtml +++ b/modules/monitoring/application/views/scripts/config/createbackend.phtml @@ -1,5 +1,6 @@
    showOnlyCloseButton() ?>
    -

    translate('Add New Backend'); ?>

    - +
    + +
    \ No newline at end of file diff --git a/modules/monitoring/application/views/scripts/config/createinstance.phtml b/modules/monitoring/application/views/scripts/config/createinstance.phtml index 3515514df7..d2c7b6bdd9 100644 --- a/modules/monitoring/application/views/scripts/config/createinstance.phtml +++ b/modules/monitoring/application/views/scripts/config/createinstance.phtml @@ -1,5 +1,6 @@
    showOnlyCloseButton() ?>
    -

    translate('Add New Instance') ?>

    - +
    + +
    \ No newline at end of file diff --git a/modules/monitoring/application/views/scripts/config/editbackend.phtml b/modules/monitoring/application/views/scripts/config/editbackend.phtml index 630cb83f29..d2c7b6bdd9 100644 --- a/modules/monitoring/application/views/scripts/config/editbackend.phtml +++ b/modules/monitoring/application/views/scripts/config/editbackend.phtml @@ -1,5 +1,6 @@
    showOnlyCloseButton() ?>
    -

    translate('Edit Existing Backend') ?>

    - +
    + +
    \ No newline at end of file diff --git a/modules/monitoring/application/views/scripts/config/editinstance.phtml b/modules/monitoring/application/views/scripts/config/editinstance.phtml index 2c91ee6562..d2c7b6bdd9 100644 --- a/modules/monitoring/application/views/scripts/config/editinstance.phtml +++ b/modules/monitoring/application/views/scripts/config/editinstance.phtml @@ -1,5 +1,6 @@
    showOnlyCloseButton() ?>
    -

    translate('Edit Existing Instance'); ?>

    - +
    + +
    \ No newline at end of file diff --git a/modules/monitoring/application/views/scripts/config/index.phtml b/modules/monitoring/application/views/scripts/config/index.phtml index 634da957c0..201a09dae9 100644 --- a/modules/monitoring/application/views/scripts/config/index.phtml +++ b/modules/monitoring/application/views/scripts/config/index.phtml @@ -38,7 +38,7 @@ '/monitoring/config/removebackend', array('backend' => $backendName), array( - 'icon' => 'cancel', + 'icon' => 'trash', 'title' => sprintf($this->translate('Remove monitoring backend %s'), $backendName) ) ); ?> @@ -82,7 +82,7 @@ '/monitoring/config/removeinstance', array('instance' => $instanceName), array( - 'icon' => 'cancel', + 'icon' => 'trash', 'title' => sprintf($this->translate('Remove monitoring instance %s'), $instanceName) ) ); ?> diff --git a/modules/monitoring/application/views/scripts/config/removebackend.phtml b/modules/monitoring/application/views/scripts/config/removebackend.phtml index d297f615b8..d2c7b6bdd9 100644 --- a/modules/monitoring/application/views/scripts/config/removebackend.phtml +++ b/modules/monitoring/application/views/scripts/config/removebackend.phtml @@ -1,5 +1,6 @@
    showOnlyCloseButton() ?>
    -

    translate('Remove Existing Backend') ?>

    - +
    + +
    \ No newline at end of file diff --git a/modules/monitoring/application/views/scripts/config/removeinstance.phtml b/modules/monitoring/application/views/scripts/config/removeinstance.phtml index eee29fb026..d2c7b6bdd9 100644 --- a/modules/monitoring/application/views/scripts/config/removeinstance.phtml +++ b/modules/monitoring/application/views/scripts/config/removeinstance.phtml @@ -1,7 +1,6 @@
    showOnlyCloseButton() ?>
    -

    translate('Remove Existing Instance'); ?>

    -

    translate('Are you sure you want to remove this instance?'); ?>

    -

    translate('If you have still any environments or views referring to this instance, you won\'t be able to send commands anymore after deletion.'); ?>

    - +
    + +
    \ No newline at end of file diff --git a/modules/monitoring/application/views/scripts/partials/command/object-command-form.phtml b/modules/monitoring/application/views/scripts/partials/command/object-command-form.phtml index 7f4314cbf1..dbcf0bc033 100644 --- a/modules/monitoring/application/views/scripts/partials/command/object-command-form.phtml +++ b/modules/monitoring/application/views/scripts/partials/command/object-command-form.phtml @@ -7,7 +7,6 @@
    -
    -

    icon('help', $form->getHelp()); ?>

    - +
    +
    \ No newline at end of file diff --git a/modules/monitoring/application/views/scripts/partials/command/objects-command-form.phtml b/modules/monitoring/application/views/scripts/partials/command/objects-command-form.phtml index da58fc9cba..d387202c27 100644 --- a/modules/monitoring/application/views/scripts/partials/command/objects-command-form.phtml +++ b/modules/monitoring/application/views/scripts/partials/command/objects-command-form.phtml @@ -5,7 +5,7 @@ render('partials/host/objects-header.phtml'); ?>
    -
    +
    @@ -27,6 +27,5 @@

    -

    icon('help', $form->getHelp()) ?>

    - +
    diff --git a/modules/monitoring/application/views/scripts/process/disable-notifications.phtml b/modules/monitoring/application/views/scripts/process/disable-notifications.phtml index 2fb3c6c6e3..9b9a2b133a 100644 --- a/modules/monitoring/application/views/scripts/process/disable-notifications.phtml +++ b/modules/monitoring/application/views/scripts/process/disable-notifications.phtml @@ -2,7 +2,7 @@ tabs->showOnlyCloseButton() ?>
    -

    icon('help', $form->getHelp()) ?>

    +

    notifications_enabled === false): ?>
    translate('Host and service notifications are already disabled.') ?> @@ -13,6 +13,6 @@
    - +
    diff --git a/modules/monitoring/application/views/scripts/process/info.phtml b/modules/monitoring/application/views/scripts/process/info.phtml index 639b5ebc0d..b881641e6d 100644 --- a/modules/monitoring/application/views/scripts/process/info.phtml +++ b/modules/monitoring/application/views/scripts/process/info.phtml @@ -16,10 +16,7 @@ $cp = $this->checkPerformance()->create($this->checkperformance);
    -

    - translate('Feature Commands') ?> -

    - toggleFeaturesForm ?> + toggleFeaturesForm; ?>
    diff --git a/modules/monitoring/application/views/scripts/show/components/acknowledgement.phtml b/modules/monitoring/application/views/scripts/show/components/acknowledgement.phtml index 22a3721516..7c50a48823 100644 --- a/modules/monitoring/application/views/scripts/show/components/acknowledgement.phtml +++ b/modules/monitoring/application/views/scripts/show/components/acknowledgement.phtml @@ -40,8 +40,9 @@ if ($object->acknowledged): ?> $ackLink, null, array( - 'icon' => 'ok', - 'title' => $this->translate( + 'icon' => 'ok', + 'data-base-target' => '_self', + 'title' => $this->translate( 'Acknowledge this problem, suppress all future notifications for it and tag it as being handled' ) ) diff --git a/modules/monitoring/public/css/module.less b/modules/monitoring/public/css/module.less index 26cd5bc381..6c205cd045 100644 --- a/modules/monitoring/public/css/module.less +++ b/modules/monitoring/public/css/module.less @@ -160,6 +160,20 @@ form.instance-features span.description, form.object-features span.description { display: inline; } +.boxview div.box form.instance-features div.header { + border-bottom: 1px solid #d9d9d9; + margin-bottom: 0.5em; + + h2 { + border: 0; + padding-bottom: 0; + } +} + +table.avp form.object-features div.header h4 { + margin: 0; +} + table.avp .customvar ul { list-style-type: none; margin: 0; @@ -190,7 +204,7 @@ div.selection-info { vertical-align: middle; } -h1.command-title { +.object-command form h1, .objects-command form h1 { border: none; } @@ -202,4 +216,4 @@ hr.command-separator { .sort-box { float: right; margin-right: 1em; -} \ No newline at end of file +} diff --git a/modules/setup/application/forms/AdminAccountPage.php b/modules/setup/application/forms/AdminAccountPage.php index 485baa64f0..da9e90a145 100644 --- a/modules/setup/application/forms/AdminAccountPage.php +++ b/modules/setup/application/forms/AdminAccountPage.php @@ -192,31 +192,6 @@ public function createElements(array $formData) ) ); } - - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('Administration', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - $this->addElement( - 'note', - 'description', - array( - 'value' => tp( - 'Now it\'s time to configure your first administrative account for Icinga Web 2.' - . ' Please follow the instructions below:', - 'Now it\'s time to configure your first administrative account for Icinga Web 2.' - . ' Below are several options you can choose from. Select one and follow its instructions:', - count($choices) - ) - ) - ); } /** diff --git a/modules/setup/application/forms/AuthBackendPage.php b/modules/setup/application/forms/AuthBackendPage.php index 0f07d31be1..0ec1de30fc 100644 --- a/modules/setup/application/forms/AuthBackendPage.php +++ b/modules/setup/application/forms/AuthBackendPage.php @@ -27,6 +27,7 @@ class AuthBackendPage extends Form public function init() { $this->setName('setup_authentication_backend'); + $this->setTitle($this->translate('Authentication Backend', 'setup.page.title')); } /** @@ -57,54 +58,33 @@ public function getResourceConfig() */ public function createElements(array $formData) { - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('Authentication Backend', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - - if ($this->config['type'] === 'db') { - $note = $this->translate( - 'As you\'ve chosen to use a database for authentication all you need ' - . 'to do now is defining a name for your first authentication backend.' - ); - } elseif ($this->config['type'] === 'ldap') { - $note = $this->translate( - 'Before you are able to authenticate using the LDAP connection defined earlier you need to' - . ' provide some more information so that Icinga Web 2 is able to locate account details.' - ); - } else { // if ($this->config['type'] === 'external' - $note = $this->translate( - 'You\'ve chosen to authenticate using a web server\'s mechanism so it may be necessary' - . ' to adjust usernames before any permissions, restrictions, etc. are being applied.' - ); - } - - $this->addElement( - 'note', - 'description', - array('value' => $note) - ); - if (isset($formData['skip_validation']) && $formData['skip_validation']) { $this->addSkipValidationCheckbox(); } if ($this->config['type'] === 'db') { + $this->setRequiredCue(null); $backendForm = new DbBackendForm(); + $backendForm->setRequiredCue(null); $backendForm->createElements($formData)->removeElement('resource'); + $this->addDescription($this->translate( + 'As you\'ve chosen to use a database for authentication all you need ' + . 'to do now is defining a name for your first authentication backend.' + )); } elseif ($this->config['type'] === 'ldap') { $backendForm = new LdapBackendForm(); $backendForm->createElements($formData)->removeElement('resource'); + $this->addDescription($this->translate( + 'Before you are able to authenticate using the LDAP connection defined earlier you need to' + . ' provide some more information so that Icinga Web 2 is able to locate account details.' + )); } else { // $this->config['type'] === 'external' $backendForm = new ExternalBackendForm(); $backendForm->createElements($formData); + $this->addDescription($this->translate( + 'You\'ve chosen to authenticate using a web server\'s mechanism so it may be necessary' + . ' to adjust usernames before any permissions, restrictions, etc. are being applied.' + )); } $this->addElements($backendForm->getElements()); @@ -143,7 +123,7 @@ protected function addSkipValidationCheckbox() 'checkbox', 'skip_validation', array( - 'order' => 2, + 'order' => 0, 'ignore' => true, 'required' => true, 'label' => $this->translate('Skip Validation'), diff --git a/modules/setup/application/forms/AuthenticationPage.php b/modules/setup/application/forms/AuthenticationPage.php index d7c26d4607..4f455de1e8 100644 --- a/modules/setup/application/forms/AuthenticationPage.php +++ b/modules/setup/application/forms/AuthenticationPage.php @@ -16,7 +16,13 @@ class AuthenticationPage extends Form */ public function init() { + $this->setRequiredCue(null); $this->setName('setup_authentication_type'); + $this->setTitle($this->translate('Authentication', 'setup.page.title')); + $this->addDescription($this->translate( + 'Please choose how you want to authenticate when accessing Icinga Web 2.' + . ' Configuring backend specific details follows in a later step.' + )); } /** @@ -24,50 +30,14 @@ public function init() */ public function createElements(array $formData) { - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('Authentication', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - if (isset($formData['type']) && $formData['type'] === 'external' && !isset($_SERVER['REMOTE_USER'])) { - $this->addElement( - 'note', - 'external_note', - array( - 'value' => '' . $this->translate( - 'You\'re currently not authenticated using any of the web server\'s authentication ' - . 'mechanisms. Make sure you\'ll configure such, otherwise you\'ll not be able to ' - . 'log into Icinga Web 2.' - ), - 'decorators' => array( - 'ViewHelper', - array( - 'HtmlTag', - array('tag' => 'p', 'class' => 'info-box') - ) - ) - ) - ); + $this->addDescription($this->translate( + 'You\'re currently not authenticated using any of the web server\'s authentication ' + . 'mechanisms. Make sure you\'ll configure such, otherwise you\'ll not be able to ' + . 'log into Icinga Web 2.' + )); } - $this->addElement( - 'note', - 'description', - array( - 'value' => $this->translate( - 'Please choose how you want to authenticate when accessing Icinga Web 2.' - . ' Configuring backend specific details follows in a later step.' - ) - ) - ); - $backendTypes = array(); if (Platform::hasMysqlSupport() || Platform::hasPostgresqlSupport()) { $backendTypes['db'] = $this->translate('Database'); diff --git a/modules/setup/application/forms/DatabaseCreationPage.php b/modules/setup/application/forms/DatabaseCreationPage.php index 81e9dcc624..9f4ed35a1e 100644 --- a/modules/setup/application/forms/DatabaseCreationPage.php +++ b/modules/setup/application/forms/DatabaseCreationPage.php @@ -39,6 +39,13 @@ class DatabaseCreationPage extends Form public function init() { $this->setName('setup_database_creation'); + $this->setTitle($this->translate('Database Setup', 'setup.page.title')); + $this->addDescription($this->translate( + 'It seems that either the database you defined earlier does not yet exist and cannot be created' + . ' using the provided access credentials, the database does not have the required schema to be' + . ' operated by Icinga Web 2 or the provided access credentials do not have the sufficient ' + . 'permissions to access the database. Please provide appropriate access credentials to solve this.' + )); } /** @@ -85,30 +92,6 @@ public function setDatabaseUsagePrivileges(array $privileges) */ public function createElements(array $formData) { - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('Database Setup', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - $this->addElement( - 'note', - 'description', - array( - 'value' => $this->translate( - 'It seems that either the database you defined earlier does not yet exist and cannot be created' - . ' using the provided access credentials, the database does not have the required schema to be' - . ' operated by Icinga Web 2 or the provided access credentials do not have the sufficient ' - . 'permissions to access the database. Please provide appropriate access credentials to solve this.' - ) - ) - ); - $skipValidation = isset($formData['skip_validation']) && $formData['skip_validation']; $this->addElement( 'text', @@ -213,7 +196,7 @@ protected function addSkipValidationCheckbox() 'checkbox', 'skip_validation', array( - 'order' => 2, + 'order' => 0, 'required' => true, 'label' => $this->translate('Skip Validation'), 'description' => $this->translate( diff --git a/modules/setup/application/forms/DbResourcePage.php b/modules/setup/application/forms/DbResourcePage.php index df5fd9c9a5..8844ced4c7 100644 --- a/modules/setup/application/forms/DbResourcePage.php +++ b/modules/setup/application/forms/DbResourcePage.php @@ -19,6 +19,11 @@ class DbResourcePage extends Form public function init() { $this->setName('setup_db_resource'); + $this->setTitle($this->translate('Database Resource', 'setup.page.title')); + $this->addDescription($this->translate( + 'Now please configure your database resource. Note that the database itself does not need to' + . ' exist at this time as it is going to be created once the wizard is about to be finished.' + )); } /** @@ -34,27 +39,6 @@ public function createElements(array $formData) 'value' => 'db' ) ); - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('Database Resource', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - $this->addElement( - 'note', - 'description', - array( - 'value' => $this->translate( - 'Now please configure your database resource. Note that the database itself does not need to' - . ' exist at this time as it is going to be created once the wizard is about to be finished.' - ) - ) - ); if (isset($formData['skip_validation']) && $formData['skip_validation']) { $this->addSkipValidationCheckbox(); diff --git a/modules/setup/application/forms/GeneralConfigPage.php b/modules/setup/application/forms/GeneralConfigPage.php index 3dc4eecf14..c50d772938 100644 --- a/modules/setup/application/forms/GeneralConfigPage.php +++ b/modules/setup/application/forms/GeneralConfigPage.php @@ -17,6 +17,10 @@ class GeneralConfigPage extends Form public function init() { $this->setName('setup_general_config'); + $this->setTitle($this->translate('Application Configuration', 'setup.page.title')); + $this->addDescription($this->translate( + 'Now please adjust all application and logging related configuration options to fit your needs.' + )); } /** @@ -24,27 +28,6 @@ public function init() */ public function createElements(array $formData) { - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('Application Configuration', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - $this->addElement( - 'note', - 'description', - array( - 'value' => $this->translate( - 'Now please adjust all application and logging related configuration options to fit your needs.' - ) - ) - ); - $loggingForm = new LoggingConfigForm(); $this->addElements($loggingForm->createElements($formData)->getElements()); } diff --git a/modules/setup/application/forms/LdapDiscoveryConfirmPage.php b/modules/setup/application/forms/LdapDiscoveryConfirmPage.php index 6a09d9fee8..3635fc358d 100644 --- a/modules/setup/application/forms/LdapDiscoveryConfirmPage.php +++ b/modules/setup/application/forms/LdapDiscoveryConfirmPage.php @@ -37,6 +37,7 @@ class LdapDiscoveryConfirmPage extends Form public function init() { $this->setName('setup_ldap_discovery_confirm'); + $this->setTitle($this->translate('LDAP Discovery Results', 'setup.page.title')); } /** @@ -77,27 +78,10 @@ public function createElements(array $formData) $html = str_replace('{user_attribute}', $backend['user_name_attribute'], $html); $html = str_replace('{user_class}', $backend['user_class'], $html); - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('LDAP Discovery Results', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - $this->addElement( - 'note', - 'description', - array( - 'value' => sprintf( - $this->translate('The following directory service has been found on domain "%s":'), - $this->config['domain'] - ) - ) - ); + $this->addDescription(sprintf( + $this->translate('The following directory service has been found on domain "%s".'), + $this->config['domain'] + )); $this->addElement( 'note', diff --git a/modules/setup/application/forms/LdapDiscoveryPage.php b/modules/setup/application/forms/LdapDiscoveryPage.php index addc405458..1b8a85c77d 100644 --- a/modules/setup/application/forms/LdapDiscoveryPage.php +++ b/modules/setup/application/forms/LdapDiscoveryPage.php @@ -3,7 +3,9 @@ namespace Icinga\Module\Setup\Forms; +use Zend_Validate_NotEmpty; use Icinga\Web\Form; +use Icinga\Web\Form\ErrorLabeller; use Icinga\Forms\LdapDiscoveryForm; use Icinga\Protocol\Ldap\Discovery; use Icinga\Module\Setup\Forms\LdapDiscoveryConfirmPage; @@ -24,6 +26,11 @@ class LdapDiscoveryPage extends Form public function init() { $this->setName('setup_ldap_discovery'); + $this->setTitle($this->translate('LDAP Discovery', 'setup.page.title')); + $this->addDescription($this->translate( + 'You can use this page to discover LDAP or ActiveDirectory servers ' . + ' for authentication. If you don\' want to execute a discovery, just skip this step.' + )); } /** @@ -31,39 +38,13 @@ public function init() */ public function createElements(array $formData) { - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('LDAP Discovery', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - $this->addElement( - 'note', - 'description', - array( - 'value' => $this->translate( - 'You can use this page to discover LDAP or ActiveDirectory servers ' . - ' for authentication. If you don\' want to execute a discovery, just skip this step.' - ) - ) - ); - $discoveryForm = new LdapDiscoveryForm(); $this->addElements($discoveryForm->createElements($formData)->getElements()); - $this->getElement('domain')->setRequired( - isset($formData['skip_validation']) === false || ! $formData['skip_validation'] - ); $this->addElement( 'checkbox', 'skip_validation', array( - 'required' => true, 'label' => $this->translate('Skip'), 'description' => $this->translate('Do not discover LDAP servers and enter all settings manually.') ) @@ -82,19 +63,24 @@ public function isValid($data) if (false === parent::isValid($data)) { return false; } - if ($data['skip_validation']) { + if (isset($data['skip_validation']) && $data['skip_validation']) { return true; } - if (isset($data['domain'])) { + if (isset($data['domain']) && $data['domain']) { $this->discovery = Discovery::discoverDomain($data['domain']); if ($this->discovery->isSuccess()) { return true; } + + $this->addError( + sprintf($this->translate('Could not find any LDAP servers on the domain "%s".'), $data['domain']) + ); + } else { + $labeller = new ErrorLabeller(array('element' => $this->getElement('domain'))); + $this->getElement('domain')->addError($labeller->translate(Zend_Validate_NotEmpty::IS_EMPTY)); } - $this->addError( - sprintf($this->translate('Could not find any LDAP servers on the domain "%s".'), $data['domain']) - ); + return false; } diff --git a/modules/setup/application/forms/LdapResourcePage.php b/modules/setup/application/forms/LdapResourcePage.php index 8374c8efa5..e7342185eb 100644 --- a/modules/setup/application/forms/LdapResourcePage.php +++ b/modules/setup/application/forms/LdapResourcePage.php @@ -17,6 +17,11 @@ class LdapResourcePage extends Form public function init() { $this->setName('setup_ldap_resource'); + $this->setTitle($this->translate('LDAP Resource', 'setup.page.title')); + $this->addDescription($this->translate( + 'Now please configure your AD/LDAP resource. This will later ' + . 'be used to authenticate users logging in to Icinga Web 2.' + )); } /** @@ -32,27 +37,6 @@ public function createElements(array $formData) 'value' => 'ldap' ) ); - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('LDAP Resource', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - $this->addElement( - 'note', - 'description', - array( - 'value' => $this->translate( - 'Now please configure your AD/LDAP resource. This will later ' - . 'be used to authenticate users logging in to Icinga Web 2.' - ) - ) - ); if (isset($formData['skip_validation']) && $formData['skip_validation']) { $this->addSkipValidationCheckbox(); diff --git a/modules/setup/application/forms/PreferencesPage.php b/modules/setup/application/forms/PreferencesPage.php index 3e91fc4280..fdd5844cf1 100644 --- a/modules/setup/application/forms/PreferencesPage.php +++ b/modules/setup/application/forms/PreferencesPage.php @@ -16,24 +16,10 @@ class PreferencesPage extends Form */ public function init() { + $this->setRequiredCue(null); $this->setName('setup_preferences_type'); - } - - /** - * Pre-select "db" as preference backend and add a hint to the select element - * - * @return self - */ - public function showDatabaseNote() - { - $this->getElement('store') - ->setValue('db') - ->setDescription( - $this->translate( - 'Note that choosing "Database" causes Icinga Web 2 to use the same database as for authentication.' - ) - ); - return $this; + $this->setTitle($this->translate('Preferences', 'setup.page.title')); + $this->addDescription($this->translate('Please choose how Icinga Web 2 should store user preferences.')); } /** @@ -41,25 +27,6 @@ public function showDatabaseNote() */ public function createElements(array $formData) { - $this->addElement( - 'note', - 'title', - array( - 'value' => $this->translate('Preferences', 'setup.page.title'), - 'decorators' => array( - 'ViewHelper', - array('HtmlTag', array('tag' => 'h2')) - ) - ) - ); - $this->addElement( - 'note', - 'description', - array( - 'value' => $this->translate('Please choose how Icinga Web 2 should store user preferences.') - ) - ); - $storageTypes = array(); $storageTypes['ini'] = $this->translate('File System (INI Files)'); if (Platform::hasMysqlSupport() || Platform::hasPostgresqlSupport()) { diff --git a/modules/setup/application/forms/WelcomePage.php b/modules/setup/application/forms/WelcomePage.php index 7f2e00ef26..bc4c40b9fe 100644 --- a/modules/setup/application/forms/WelcomePage.php +++ b/modules/setup/application/forms/WelcomePage.php @@ -17,6 +17,7 @@ class WelcomePage extends Form */ public function init() { + $this->setRequiredCue(null); $this->setName('setup_welcome'); $this->setViewScript('form/setup-welcome.phtml'); } diff --git a/modules/setup/application/views/scripts/form/setup-admin-account.phtml b/modules/setup/application/views/scripts/form/setup-admin-account.phtml index b069bb371b..77220017c3 100644 --- a/modules/setup/application/views/scripts/form/setup-admin-account.phtml +++ b/modules/setup/application/views/scripts/form/setup-admin-account.phtml @@ -7,17 +7,25 @@ $showRadioBoxes = strpos(strtolower(get_class($radioElem)), 'radio') !== false; ?> +

    translate('Administration', 'setup.page.title'); ?>

    +
      +
    • translatePlural( + 'Now it\'s time to configure your first administrative account for Icinga Web 2. Please follow the instructions below:', + 'Now it\'s time to configure your first administrative account for Icinga Web 2. Below are several options you can choose from. Select one and follow its instructions:', + $showRadioBoxes ? count($radioElem->getMultiOptions()) : 1 + ); ?>
    • +
    getElement('title'); ?> getElement('description'); ?> getElement('by_name')) !== null): ?>
    - + setAttrib('data-related-radiobtn', 'by_name') : $byNameElem; ?>
    @@ -27,12 +35,12 @@ $showRadioBoxes = strpos(strtolower(get_class($radioElem)), 'radio') !== false; getElement('existing_user')) !== null): ?>
    - + setAttrib('data-related-radiobtn', 'existing_user') : $existingUserElem; ?>
    @@ -42,14 +50,14 @@ $showRadioBoxes = strpos(strtolower(get_class($radioElem)), 'radio') !== false; getElement('new_user')) !== null): ?>
    - + setAttrib('data-related-radiobtn', 'new_user') : $newUserElem; ?> getElement('new_user_password'); ?> getElement('new_user_2ndpass'); ?>
    diff --git a/modules/setup/application/views/scripts/form/setup-welcome.phtml b/modules/setup/application/views/scripts/form/setup-welcome.phtml index d4bc1c3d72..1b37f60f00 100644 --- a/modules/setup/application/views/scripts/form/setup-welcome.phtml +++ b/modules/setup/application/views/scripts/form/setup-welcome.phtml @@ -5,6 +5,7 @@ use Icinga\Application\Config; use Icinga\Application\Platform; use Icinga\Web\Wizard; +$phpUser = Platform::getPhpUser(); $configDir = Icinga::app()->getConfigDir(); $setupTokenPath = rtrim($configDir, '/') . '/setup.token'; $cliPath = realpath(Icinga::app()->getApplicationDir() . '/../bin/icingacli'); @@ -41,10 +42,15 @@ $cliPath = realpath(Icinga::app()->getApplicationDir() . '/../bin/icingacli'); 'To run this wizard a user needs to authenticate using a token which is usually' . ' provided to him by an administrator who\'d followed the instructions below.' ); ?>

    -

    translate('In any case, make sure that a group called "icingaweb2" exists:'); ?>

    -
    - groupadd icingaweb2; -
    +

    translate('In any case, make sure that all of the following applies to your environment:'); ?>

    +
      +
    • translate('A system group called "icingaweb2" exists'); ?>
    • + +
    • translate('The user "%s" is a member of the system group "icingaweb2"'), $phpUser); ?>
    • + +
    • translate('Your webserver\'s user is a member of the system group "icingaweb2"'); ?>
    • + +

    translate('If you\'ve got the IcingaCLI installed you can do the following:'); ?>

    setup config directory --group icingaweb2; @@ -52,7 +58,7 @@ $cliPath = realpath(Icinga::app()->getApplicationDir() . '/../bin/icingacli');

    translate('In case the IcingaCLI is missing you can create the token manually:'); ?>

    - su -c "mkdir -m 2770 ; chgrp icingaweb2 ; head -c 12 /dev/urandom | base64 | tee ; chmod 0660 ;"; + su translate(''); ?> -c "mkdir -m 2770 ; chgrp icingaweb2 ; head -c 12 /dev/urandom | base64 | tee ; chmod 0660 ;";

    translate('Please see the %s for an extensive description on how to access and use this wizard.'), diff --git a/modules/setup/library/Setup/WebWizard.php b/modules/setup/library/Setup/WebWizard.php index 6158d9bd0a..59404efd64 100644 --- a/modules/setup/library/Setup/WebWizard.php +++ b/modules/setup/library/Setup/WebWizard.php @@ -119,7 +119,11 @@ public function setupPage(Form $page, Request $request) } elseif ($page->getName() === 'setup_preferences_type') { $authData = $this->getPageData('setup_authentication_type'); if ($authData['type'] === 'db') { - $page->create()->showDatabaseNote(); + $page->create()->getElement('store')->setValue('db'); + $page->addDescription(mt( + 'setup', + 'Note that choosing "Database" causes Icinga Web 2 to use the same database as for authentication.' + )); } } elseif ($page->getName() === 'setup_authentication_backend') { $authData = $this->getPageData('setup_authentication_type'); diff --git a/modules/setup/library/Setup/Webserver/Nginx.php b/modules/setup/library/Setup/Webserver/Nginx.php index 780a3184ea..524b90ebf1 100644 --- a/modules/setup/library/Setup/Webserver/Nginx.php +++ b/modules/setup/library/Setup/Webserver/Nginx.php @@ -25,6 +25,7 @@ protected function getTemplate() include fastcgi_params; fastcgi_param SCRIPT_FILENAME {documentRoot}/index.php; fastcgi_param ICINGAWEB_CONFIGDIR {configDir}; + fastcgi_param REMOTE_USER $remote_user; } location ~ ^{urlPath}(.+)? { diff --git a/modules/test/module.info b/modules/test/module.info index 6463151565..ed6adc1f25 100644 --- a/modules/test/module.info +++ b/modules/test/module.info @@ -2,4 +2,4 @@ Module: test Version: 2.0.0~alpha4 Description: Translation module This module allows developers to run (unit) tests against Icinga Web 2 and - any of it's modules. Usually you do not need to enable this. + any of its modules. Usually you do not need to enable this. diff --git a/modules/translation/application/clicommands/CompileCommand.php b/modules/translation/application/clicommands/CompileCommand.php index 4f08b28448..0367691750 100644 --- a/modules/translation/application/clicommands/CompileCommand.php +++ b/modules/translation/application/clicommands/CompileCommand.php @@ -15,7 +15,7 @@ * Domains are the global one 'icinga' and all available and enabled modules * identified by their name. * - * Once a PO-file is compiled it's content is used by Icinga Web 2 to display + * Once a PO-file is compiled its content is used by Icinga Web 2 to display * messages in the configured language. */ class CompileCommand extends TranslationCommand diff --git a/modules/translation/doc/translation.md b/modules/translation/doc/translation.md index 55dc415ad2..308eae6a8a 100644 --- a/modules/translation/doc/translation.md +++ b/modules/translation/doc/translation.md @@ -109,7 +109,7 @@ When you are done, just save your new settings. To work with Icinga Web 2 .po files, you can open for e.g. the german icinga.po file which is located under `application/locale/de_DE/LC_MESSAGES/icinga.po`, as shown below, you will get then a full list of all available -translation strings for the core application. Each module names it's translation files `%module_name%.po`. For a +translation strings for the core application. Each module names its translation files `%module_name%.po`. For a module called __yourmodule__ the .po translation file will be named `yourmodule.po`. @@ -196,4 +196,4 @@ The last step is to compile the __yourmodule.po__ to the __yourmodule.mo__: icingacli translation compile module development ll_CC At this moment, everywhere in the module where the `Dummy` should be translated, it would returns the translated -string `Attrappe`. \ No newline at end of file +string `Attrappe`. diff --git a/modules/translation/module.info b/modules/translation/module.info index 9934ec931a..ebe121ebc3 100644 --- a/modules/translation/module.info +++ b/modules/translation/module.info @@ -2,6 +2,6 @@ Module: translation Version: 2.0.0~alpha4 Description: Translation module This module allows developers and translators to translate Icinga Web 2 and - it's modules for multiple languages. You do not need this module to run an + its modules for multiple languages. You do not need this module to run an internationalized web frontend. This is only for people who want to contribute translations or translate just their own moduls. diff --git a/packages/debian/control b/packages/debian/control index 560b2ef651..73d0b57a3d 100644 --- a/packages/debian/control +++ b/packages/debian/control @@ -24,7 +24,7 @@ Package: icingaweb-module-doc Architecture: any Depends: icingaweb-common Description: Icingaweb documentation module - This module renders documentation for Icingaweb and it's modules + This module renders documentation for Icingaweb and its modules Package: icingaweb-module-monitoring Architecture: any @@ -42,7 +42,7 @@ Package: icingaweb-module-test Architecture: any Depends: icingacli Description: Icingaweb test module - Use this module to run unit tests against Icingaweb or any of it's modules + Use this module to run unit tests against Icingaweb or any of its modules Package: icingaweb-module-translation Architecture: any @@ -54,7 +54,7 @@ Package: icingacli Architecture: any Depends: icingaweb-common, php5-cli (>= 5.3.2) Description: Icinga CLI tool - The Icinga CLI allows one to access it's Icinga monitoring + The Icinga CLI allows one to access its Icinga monitoring system from a terminal. . The CLI is based on the Icinga PHP libraries diff --git a/public/css/icinga/animation.less b/public/css/icinga/animation.less new file mode 100644 index 0000000000..928cdf526a --- /dev/null +++ b/public/css/icinga/animation.less @@ -0,0 +1,82 @@ +.animate(@animate) { + -moz-animation: @animate; + -o-animation: @animate; + -webkit-animation: @animate; + animation: @animate; +} + +@-moz-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@-webkit-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@-o-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@-ms-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} \ No newline at end of file diff --git a/public/css/icinga/forms.less b/public/css/icinga/forms.less index b0468234ac..41525a4c74 100644 --- a/public/css/icinga/forms.less +++ b/public/css/icinga/forms.less @@ -126,10 +126,10 @@ input.link-like:hover, button.link-like:focus { .non-list-like-list { list-style-type: none; margin: 0; - padding: 0; + padding: 0.5em 0.5em 0; li { - margin: 0.5em; + padding-bottom: 0.5em; } } @@ -146,12 +146,16 @@ form div.element ul.errors { form ul.form-errors { .non-list-like-list; - display: inline-block; margin-bottom: 1em; background-color: @colorCritical; ul.errors { .non-list-like-list; + padding: 0; + + li:last-child { + padding-bottom: 0; + } } li { @@ -190,38 +194,43 @@ form .description { display: block; } -form label.has-feedback:after { - content: '\e85b'; - font-family: "ifont"; - font-style: normal; - font-weight: normal; - speak: none; +select.grant-permissions { + height: 20em; + width: auto; +} - text-decoration: inherit; - width: 1em; - margin-right: .2em; - text-align: center; - /* opacity: .8; */ +label ~ input, label ~ select { + margin-left: 1.6em; +} - /* For safety - reset parent styles, that can break glyph codes*/ - font-variant: normal; - text-transform: none; +label + i ~ input, label + i ~ select { + margin-left: 0; +} - /* fix buttons height, for twitter bootstrap */ - line-height: 1em; +button.noscript-apply { + margin-left: 0.5em; +} - /* Animation center compensation - margins should be symmetric */ - /* remove if not needed */ - margin-left: .2em; +html.no-js i.autosubmit-warning { + .sr-only; +} - /* you can be more comfortable with increased icons size */ - /* font-size: 120%; */ +form ul.descriptions { + .info-box; + padding: 0.5em 0.5em 0 1.8em; - /* Uncomment for 3D effect */ - /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ -} + li { + padding-bottom: 0.5em; -select.grant-permissions { - height: 20em; - width: auto; + &:only-child { + margin-left: -1.3em; + list-style-type: none; + } + } } + +form > div.header { + h1, h2, h3, h4, h5, h6 { + display: inline-block; + } +} \ No newline at end of file diff --git a/public/css/icinga/login.less b/public/css/icinga/login.less index 0211fdc353..5bc21d940a 100644 --- a/public/css/icinga/login.less +++ b/public/css/icinga/login.less @@ -79,9 +79,10 @@ form input { width: 18em; padding: 0.5em; - background: #ddd; - color: #333; + background: #ddd; + color: #333; border: 1px solid #ddd; + margin-left: 0; } form input:focus { diff --git a/public/css/icinga/main-content.less b/public/css/icinga/main-content.less index 74f9e1a6d2..32054e2425 100644 --- a/public/css/icinga/main-content.less +++ b/public/css/icinga/main-content.less @@ -206,5 +206,5 @@ table.benchmark { .info-box { padding: 0.5em; border: 1px solid lightgrey; - background-color: infobackground; + background-color: #fbfcc5; } diff --git a/public/css/icinga/setup.less b/public/css/icinga/setup.less index d7217e1afa..66b08417e2 100644 --- a/public/css/icinga/setup.less +++ b/public/css/icinga/setup.less @@ -222,10 +222,6 @@ } } -#setup_authentication_type p.info-box em { - text-decoration: underline; -} - #setup_ldap_discovery_confirm table { margin: 1em 0; border-collapse: separate; @@ -440,6 +436,7 @@ input[type=checkbox] { height: 10em; float: right; + margin: 0; } } diff --git a/public/css/icinga/tabs.less b/public/css/icinga/tabs.less index e776469e03..d9161f6722 100644 --- a/public/css/icinga/tabs.less +++ b/public/css/icinga/tabs.less @@ -136,3 +136,15 @@ ul.tabs img.icon { a.close-tab { display: none; } + +.spinner > i { + line-height: 1; +} + +.spinner.active > i { + .animate(spin 2s infinite linear); + &:before { + // icon-spin6 + content: '\e874'; + } +} diff --git a/public/css/icinga/widgets.less b/public/css/icinga/widgets.less index 1da6b7bfbd..45701a6975 100644 --- a/public/css/icinga/widgets.less +++ b/public/css/icinga/widgets.less @@ -230,29 +230,29 @@ li li .badge-container { background-color: @colorInvalid; } -#menu > ul > li.active > .badge-container { +#menu nav > ul > li.active > .badge-container { display: none; } -#menu > ul > li.hover > .badge-container { +#menu nav > ul > li.hover > .badge-container { display: none; } -#menu > ul > li.active > ul > li .badge-container { +#menu nav > ul > li.active > ul > li .badge-container { position: relative; top: -0.5em; } -#menu > ul > li.hover > ul > li > a { +#menu nav > ul > li.hover > ul > li > a { width: 12.5em; } -#menu > ul > li.hover > ul > li .badge-container { +#menu nav > ul > li.hover > ul > li .badge-container { position: relative; top: -0.5em; } -#menu > ul > li.hover > ul > li { +#menu nav > ul > li.hover > ul > li { // prevent floating badges from resizing list items in webkit //max-height: 2em; } diff --git a/public/font/ifont.eot b/public/font/ifont.eot index 22e4b3011f..d249dc858a 100644 Binary files a/public/font/ifont.eot and b/public/font/ifont.eot differ diff --git a/public/font/ifont.svg b/public/font/ifont.svg index ae7e08c46a..e712cc6d67 100644 --- a/public/font/ifont.svg +++ b/public/font/ifont.svg @@ -1,7 +1,7 @@ -Copyright (C) 2014 by original authors @ fontello.com +Copyright (C) 2015 by original authors @ fontello.com @@ -122,6 +122,7 @@ + \ No newline at end of file diff --git a/public/font/ifont.ttf b/public/font/ifont.ttf index 931b3d1571..e222d9669d 100644 Binary files a/public/font/ifont.ttf and b/public/font/ifont.ttf differ diff --git a/public/font/ifont.woff b/public/font/ifont.woff index 36c96a9676..9cde04cd0c 100644 Binary files a/public/font/ifont.woff and b/public/font/ifont.woff differ diff --git a/public/js/icinga/events.js b/public/js/icinga/events.js index 39a2a3de4e..c7674a63d0 100644 --- a/public/js/icinga/events.js +++ b/public/js/icinga/events.js @@ -125,6 +125,10 @@ $(document).on('change', 'form select.autosubmit', { self: this }, this.autoSubmitForm); $(document).on('change', 'form input.autosubmit', { self: this }, this.autoSubmitForm); + // Automatically check a radio button once a specific input is focused + $(document).on('focus', 'form select[data-related-radiobtn]', { self: this }, this.autoCheckRadioButton); + $(document).on('focus', 'form input[data-related-radiobtn]', { self: this }, this.autoCheckRadioButton); + $(document).on('keyup', '#menu input.search', {self: this}, this.autoSubmitSearch); $(document).on('click', '.tree .handle', { self: this }, this.treeNodeToggle); @@ -163,6 +167,15 @@ icinga.ui.fixControls(); }, + autoCheckRadioButton: function (event) { + var $input = $(event.currentTarget); + var $radio = $('#' + $input.attr('data-related-radiobtn')); + if ($radio.length) { + $radio.prop('checked', true); + } + return true; + }, + autoSubmitSearch: function(event) { var self = event.data.self; if ($('#menu input.search').val() === self.searchValue) { @@ -226,9 +239,14 @@ event.stopPropagation(); event.preventDefault(); + // activate spinner indicator + if ($button.hasClass('spinner')) { + $button.addClass('active'); + } + icinga.logger.debug('Submitting form: ' + method + ' ' + url, method); - $target = self.getLinkTargetFor($form); + $target = self.getLinkTargetFor($button); if (method === 'GET') { var dataObj = $form.serializeObject(); @@ -438,6 +456,11 @@ return; } + // activate spinner indicator + if ($a.hasClass('spinner')) { + $a.addClass('active'); + } + // If link has hash tag... if (href.match(/#/)) { if (href === '#') { @@ -548,8 +571,10 @@ $(document).off('click', 'table.action tr[href]', this.rowSelected); $(document).off('click', 'table.action tr a', this.rowSelected); $(document).off('submit', 'form', this.submitForm); - $(document).off('click', 'button', this.submitForm); $(document).off('change', 'form select.autosubmit', this.submitForm); + $(document).off('change', 'form input.autosubmit', this.submitForm); + $(document).off('focus', 'form select[data-related-radiobtn]', this.autoCheckRadioButton); + $(document).off('focus', 'form input[data-related-radiobtn]', this.autoCheckRadioButton); }, destroy: function() { diff --git a/test/php/application/forms/Config/Authentication/DbBackendFormTest.php b/test/php/application/forms/Config/Authentication/DbBackendFormTest.php index 2dc7fb5a0b..b7d1ea3c11 100644 --- a/test/php/application/forms/Config/Authentication/DbBackendFormTest.php +++ b/test/php/application/forms/Config/Authentication/DbBackendFormTest.php @@ -31,7 +31,10 @@ public function testValidBackendIsValid() ->shouldReceive('count') ->andReturn(2); - $form = new DbBackendForm(); + $form = Mockery::mock('Icinga\Forms\Config\Authentication\DbBackendForm[getView]'); + $form->shouldReceive('getView->escape') + ->with(Mockery::type('string')) + ->andReturnUsing(function ($s) { return $s; }); $form->setTokenDisabled(); $form->setResources(array('test_db_backend')); $form->populate(array('resource' => 'test_db_backend')); @@ -53,7 +56,10 @@ public function testInvalidBackendIsNotValid() ->shouldReceive('count') ->andReturn(0); - $form = new DbBackendForm(); + $form = Mockery::mock('Icinga\Forms\Config\Authentication\DbBackendForm[getView]'); + $form->shouldReceive('getView->escape') + ->with(Mockery::type('string')) + ->andReturnUsing(function ($s) { return $s; }); $form->setTokenDisabled(); $form->setResources(array('test_db_backend')); $form->populate(array('resource' => 'test_db_backend')); diff --git a/test/php/application/forms/Config/Authentication/LdapBackendFormTest.php b/test/php/application/forms/Config/Authentication/LdapBackendFormTest.php index 561d61b1c9..d31033ba94 100644 --- a/test/php/application/forms/Config/Authentication/LdapBackendFormTest.php +++ b/test/php/application/forms/Config/Authentication/LdapBackendFormTest.php @@ -31,7 +31,10 @@ public function testValidBackendIsValid() Mockery::mock('overload:Icinga\Authentication\Backend\LdapUserBackend') ->shouldReceive('assertAuthenticationPossible')->andReturnNull(); - $form = new LdapBackendForm(); + $form = Mockery::mock('Icinga\Forms\Config\Authentication\LdapBackendForm[getView]'); + $form->shouldReceive('getView->escape') + ->with(Mockery::type('string')) + ->andReturnUsing(function ($s) { return $s; }); $form->setTokenDisabled(); $form->setResources(array('test_ldap_backend')); $form->populate(array('resource' => 'test_ldap_backend')); @@ -52,7 +55,10 @@ public function testInvalidBackendIsNotValid() Mockery::mock('overload:Icinga\Authentication\Backend\LdapUserBackend') ->shouldReceive('assertAuthenticationPossible')->andThrow(new AuthenticationException); - $form = new LdapBackendForm(); + $form = Mockery::mock('Icinga\Forms\Config\Authentication\LdapBackendForm[getView]'); + $form->shouldReceive('getView->escape') + ->with(Mockery::type('string')) + ->andReturnUsing(function ($s) { return $s; }); $form->setTokenDisabled(); $form->setResources(array('test_ldap_backend')); $form->populate(array('resource' => 'test_ldap_backend')); diff --git a/test/php/application/forms/Config/Resource/LdapResourceFormTest.php b/test/php/application/forms/Config/Resource/LdapResourceFormTest.php index f6d823046e..d074f1b3b6 100644 --- a/test/php/application/forms/Config/Resource/LdapResourceFormTest.php +++ b/test/php/application/forms/Config/Resource/LdapResourceFormTest.php @@ -29,7 +29,10 @@ public function testValidLdapResourceIsValid() Mockery::mock()->shouldReceive('testCredentials')->once()->andReturn(true)->getMock() ); - $form = new LdapResourceForm(); + $form = Mockery::mock('Icinga\Forms\Config\Resource\LdapResourceForm[getView]'); + $form->shouldReceive('getView->escape') + ->with(Mockery::type('string')) + ->andReturnUsing(function ($s) { return $s; }); $form->setTokenDisabled(); $this->assertTrue( @@ -48,7 +51,10 @@ public function testInvalidLdapResourceIsNotValid() Mockery::mock()->shouldReceive('testCredentials')->once()->andThrow('\Exception')->getMock() ); - $form = new LdapResourceForm(); + $form = Mockery::mock('Icinga\Forms\Config\Resource\LdapResourceForm[getView]'); + $form->shouldReceive('getView->escape') + ->with(Mockery::type('string')) + ->andReturnUsing(function ($s) { return $s; }); $form->setTokenDisabled(); $this->assertFalse( diff --git a/test/php/library/Icinga/File/Ini/IniWriterTest.php b/test/php/library/Icinga/File/Ini/IniWriterTest.php index 56f7fbf3f6..4dc94a63a8 100644 --- a/test/php/library/Icinga/File/Ini/IniWriterTest.php +++ b/test/php/library/Icinga/File/Ini/IniWriterTest.php @@ -726,7 +726,7 @@ public function testWhetherCommentsOnSectionPropertyLinesArePreserved() } /** - * Write a INI-configuration string to a temporary file and return it's path + * Write a INI-configuration string to a temporary file and return its path * * @param string $config The config string to write * diff --git a/test/php/library/Icinga/Protocol/Ldap/ConnectionTest.php b/test/php/library/Icinga/Protocol/Ldap/ConnectionTest.php new file mode 100644 index 0000000000..1820047030 --- /dev/null +++ b/test/php/library/Icinga/Protocol/Ldap/ConnectionTest.php @@ -0,0 +1,258 @@ +getAttributesMock; + } + + function ldap_start_tls() + { + global $self; + $self->startTlsCalled = true; + } + + function ldap_set_option($ds, $option, $value) + { + global $self; + $self->activatedOptions[$option] = $value; + return true; + } + + function ldap_set($ds, $option) + { + global $self; + $self->activatedOptions[] = $option; + } + + function ldap_control_paged_result() + { + global $self; + $self->pagedResultsCalled = true; + return true; + } + + function ldap_control_paged_result_response() + { + return true; + } + + function ldap_get_dn() + { + return NULL; + } + + function ldap_free_result() + { + return NULL; + } + } + + private function node(&$element, $name) + { + $element['count']++; + $element[$name] = array('count' => 0); + $element[] = $name; + } + + private function addEntry(&$element, $name, $entry) + { + $element[$name]['count']++; + $element[$name][] = $entry; + } + + private function mockQuery() + { + return Mockery::mock('overload:Icinga\Protocol\Ldap\Query') + ->shouldReceive(array( + 'from' => Mockery::self(), + 'create' => array('count' => 1), + 'listFields' => array('count' => 1), + 'getLimit' => 1, + 'hasOffset' => false, + 'hasBase' => false, + 'getSortColumns' => array(), + 'getUsePagedResults' => true + )); + } + + private function connectionFetchAll() + { + $this->mockQuery(); + $this->connection->connect(); + $this->connection->fetchAll(Mockery::self()); + } + + public function setUp() + { + $this->pagedResultsCalled = false; + $this->startTlsCalled = false; + $this->activatedOptions = array(); + + $this->mockLdapFunctions(); + + $config = new ConfigObject( + array( + 'hostname' => 'localhost', + 'root_dn' => 'dc=example,dc=com', + 'bind_dn' => 'cn=user,ou=users,dc=example,dc=com', + 'bind_pw' => '***' + ) + ); + $this->connection = new Connection($config); + + $caps = array('count' => 0); + $this->node($caps, 'defaultNamingContext'); + $this->node($caps, 'namingContexts'); + $this->node($caps, 'supportedCapabilities'); + $this->node($caps, 'supportedControl'); + $this->node($caps, 'supportedLDAPVersion'); + $this->node($caps, 'supportedExtension'); + $this->getAttributesMock = $caps; + } + + public function testUsePageControlWhenAnnounced() + { + if (version_compare(PHP_VERSION, '5.4.0') < 0) { + $this->markTestSkipped('Page control needs at least PHP_VERSION 5.4.0'); + } + + $this->addEntry($this->getAttributesMock, 'supportedControl', Capability::LDAP_PAGED_RESULT_OID_STRING); + $this->connectionFetchAll(); + + // see ticket #7993 + $this->assertEquals(true, $this->pagedResultsCalled, "Use paged result when capability is present."); + } + + public function testDontUsePagecontrolWhenNotAnnounced() + { + if (version_compare(PHP_VERSION, '5.4.0') < 0) { + $this->markTestSkipped('Page control needs at least PHP_VERSION 5.4.0'); + } + $this->connectionFetchAll(); + + // see ticket #8490 + $this->assertEquals(false, $this->pagedResultsCalled, "Don't use paged result when capability is not announced."); + } + + public function testUseLdapV2WhenAnnounced() + { + // TODO: Test turned off, see other TODO in Ldap/Connection. + $this->markTestSkipped('LdapV2 currently turned off.'); + + $this->addEntry($this->getAttributesMock, 'supportedLDAPVersion', 2); + $this->connectionFetchAll(); + + $this->assertArrayHasKey(LDAP_OPT_PROTOCOL_VERSION, $this->activatedOptions, "LDAP version must be set"); + $this->assertEquals($this->activatedOptions[LDAP_OPT_PROTOCOL_VERSION], 2); + } + + public function testUseLdapV3WhenAnnounced() + { + $this->addEntry($this->getAttributesMock, 'supportedLDAPVersion', 3); + $this->connectionFetchAll(); + + $this->assertArrayHasKey(LDAP_OPT_PROTOCOL_VERSION, $this->activatedOptions, "LDAP version must be set"); + $this->assertEquals($this->activatedOptions[LDAP_OPT_PROTOCOL_VERSION], 3, "LDAPv3 must be active"); + } + + public function testDefaultSettings() + { + $this->connectionFetchAll(); + + $this->assertArrayHasKey(LDAP_OPT_PROTOCOL_VERSION, $this->activatedOptions, "LDAP version must be set"); + $this->assertEquals($this->activatedOptions[LDAP_OPT_PROTOCOL_VERSION], 3, "LDAPv3 must be active"); + + $this->assertArrayHasKey(LDAP_OPT_REFERRALS, $this->activatedOptions, "Following referrals must be turned off"); + $this->assertEquals($this->activatedOptions[LDAP_OPT_REFERRALS], 0, "Following referrals must be turned off"); + } + + + public function testActiveDirectoryDiscovery() + { + $this->addEntry($this->getAttributesMock, 'supportedCapabilities', Capability::LDAP_CAP_ACTIVE_DIRECTORY_OID); + $this->connectionFetchAll(); + + $this->assertEquals(true, $this->connection->getCapabilities()->hasAdOid(), + "Server with LDAP_CAP_ACTIVE_DIRECTORY_OID must be recognized as Active Directory."); + } + + public function testDefaultNamingContext() + { + $this->addEntry($this->getAttributesMock, 'defaultNamingContext', 'dn=default,dn=contex'); + $this->connectionFetchAll(); + + $this->assertEquals('dn=default,dn=contex', $this->connection->getCapabilities()->getDefaultNamingContext(), + 'Default naming context must be correctly recognized.'); + } + + public function testDefaultNamingContextFallback() + { + $this->addEntry($this->getAttributesMock, 'namingContexts', 'dn=some,dn=other,dn=context'); + $this->addEntry($this->getAttributesMock, 'namingContexts', 'dn=default,dn=context'); + $this->connectionFetchAll(); + + $this->assertEquals('dn=some,dn=other,dn=context', $this->connection->getCapabilities()->getDefaultNamingContext(), + 'If defaultNamingContext is missing, the connection must fallback to first namingContext.'); + } +}