From 57e66c247aecd77b3a94abf26f36e2a9e402f982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannis=20Mo=C3=9Fhammer?= Date: Tue, 3 Sep 2013 18:43:17 +0200 Subject: [PATCH 1/6] Add sort widget, change js path from module to app, small style fixes refs #4601 --- application/controllers/StaticController.php | 49 +++--- application/layouts/scripts/body.phtml | 16 +- application/layouts/scripts/layout.phtml | 6 +- doc/widgets.md | 19 +++ library/Icinga/Application/Web.php | 13 +- library/Icinga/Web/Form.php | 57 +++++++ .../Form/Decorator/BoostrapFormDecorator.php | 105 +++++++++++++ .../Icinga/Web/Form/Decorator/HelpText.php | 14 +- .../controllers/ListController.php | 140 +++++++++++------- .../views/scripts/list/downtimes.phtml | 37 +---- .../views/scripts/list/hosts.phtml | 19 +-- .../views/scripts/list/notifications.phtml | 26 +--- .../views/scripts/list/services.phtml | 32 +--- public/js/icinga/componentLoader.js | 2 +- public/js/icinga/util/logging.js | 29 +++- public/js/main.js | 12 +- test/js/test/icinga/componentTest.js | 12 +- 17 files changed, 370 insertions(+), 218 deletions(-) create mode 100644 library/Icinga/Web/Form/Decorator/BoostrapFormDecorator.php diff --git a/application/controllers/StaticController.php b/application/controllers/StaticController.php index 2cc35e546..ba2837fdb 100644 --- a/application/controllers/StaticController.php +++ b/application/controllers/StaticController.php @@ -30,6 +30,7 @@ use \Zend_Controller_Action_Exception as ActionException; use \Icinga\Web\Controller\ActionController; use \Icinga\Application\Icinga; +use \Icinga\Application\Config as IcingaConfig; use \Icinga\Application\Logger; class StaticController extends ActionController @@ -72,12 +73,7 @@ class StaticController extends ActionController } else { $extension = 'fixme'; } - $hash = md5_file($filePath); - if ($hash === $this->getRequest()->getHeader('If-None-Match')) { - $this->getResponse()->setHttpResponseCode(304); - return; - } - header('ETag: ' . $hash); + header('Content-Type: image/' . $extension); header('Cache-Control: max-age=3600'); header('Last-Modified: ' . gmdate( @@ -119,11 +115,15 @@ class StaticController extends ActionController echo '/** Module has no js files **/'; return; } - $hash = md5_file($filePath); $response = $this->getResponse(); - $response->setHeader('ETag', $hash); - $response->setHeader('Content-Type', 'application/javascript'); - $response->setHeader('Cache-Control', 'max-age=3600', true); + $response->setHeader('Content-Type', 'text/javascript'); + if (!IcingaConfig::app()->global->get('environment') == 'development') { + $this->setCacheHeader(3600); + } else { + $response->setHeader('Pragma', 'no-cache', true); + $response->setHeader('Cache-Control', 'max-age=-3600', true); + + } $response->setHeader( 'Last-Modified', gmdate( @@ -132,15 +132,28 @@ class StaticController extends ActionController ) . ' GMT' ); - $hash = md5_file($filePath); - - if ($hash === $this->getRequest()->getHeader('If-None-Match')) { - $response->setHttpResponseCode(304); - return; - } else { - readfile($filePath); - } + readfile($filePath); return; } + + /** + * Set cache header for this resspone + * + * @param integer $maxAge The maximum age to set + */ + private function setCacheHeader($maxAge) + { + $response = $this->getResponse(); + $response->setHeader('Cache-Control', 'max-age=3600', true); + $response->setHeader('Pragma', 'cache', true); + $response->setHeader( + 'Expires', + gmdate( + 'D, d M Y H:i:s', + time()+3600 + ) . ' GMT', + true + ); + } } // @codingStandardsIgnoreEnd diff --git a/application/layouts/scripts/body.phtml b/application/layouts/scripts/body.phtml index bd2abae46..388572f16 100755 --- a/application/layouts/scripts/body.phtml +++ b/application/layouts/scripts/body.phtml @@ -2,18 +2,26 @@
-
+
render('parts/navigation.phtml') ?>
-
-
+
+
render('inline.phtml') ?>
-
+
+
+ + +
+
+ Icinga2-Web © 2013 Icinga Team +
+
diff --git a/application/layouts/scripts/layout.phtml b/application/layouts/scripts/layout.phtml index 02798122a..35a366e20 100755 --- a/application/layouts/scripts/layout.phtml +++ b/application/layouts/scripts/layout.phtml @@ -43,11 +43,11 @@ - - render('body.phtml') ?> + + diff --git a/doc/widgets.md b/doc/widgets.md index 336cce58c..bab71c170 100644 --- a/doc/widgets.md +++ b/doc/widgets.md @@ -101,3 +101,22 @@ You can now either extend your Tabs object using the DashboardAction's `apply()` `extend()` method (which is more fluent): $tabs->extend(new DashboardAction()); + +## The SortBox widget + +The "SortBox" Widget allows you to create a generic sort input for sortable views. +It automatically creates a form containing a select box with all sort options and a dropbox with the sort direction. It +also handles automatic submission of sorting changes and draws an additional submit button when JavaScript is disabled. + +The constructor takes an string for the component name ad an array containing the select options, where the key is +the value to be submitted and the value is the label that will be shown. You then should call applyRequest in order to +make sure the form is correctly populated when a request with a sort parameter is being made. + + $this->view->sortControl = new SortBox( + $this->getRequest()->getActionName(), + $columns + ); + $this->view->sortControl->applyRequest($this->getRequest()); + + +By default the sortBox uses the GET parameter 'sort' for the sorting key and 'dir' for the sorting direction diff --git a/library/Icinga/Application/Web.php b/library/Icinga/Application/Web.php index af4f542d8..a1b5647e4 100644 --- a/library/Icinga/Application/Web.php +++ b/library/Icinga/Application/Web.php @@ -121,22 +121,11 @@ class Web extends ApplicationBootstrap */ private function setupRoute() { - // TODO: Find a better solution - $this->frontController->getRouter()->addRoute( - 'module_overview', - new Zend_Controller_Router_Route( - 'js/modules/list.js', - array( - 'controller' => 'static', - 'action' => 'modulelist', - ) - ) - ); $this->frontController->getRouter()->addRoute( 'module_javascript', new Zend_Controller_Router_Route( - 'js/modules/:module_name/:file', + 'js/components/:module_name/:file', array( 'controller' => 'static', 'action' => 'javascript' diff --git a/library/Icinga/Web/Form.php b/library/Icinga/Web/Form.php index 0fe83dc30..1fc0de71c 100644 --- a/library/Icinga/Web/Form.php +++ b/library/Icinga/Web/Form.php @@ -25,6 +25,7 @@ namespace Icinga\Web; + use \Zend_Controller_Request_Abstract; use \Zend_Form; use \Zend_Config; @@ -34,6 +35,7 @@ use \Zend_View_Interface; use \Icinga\Web\Form\Element\Note; use \Icinga\Exception\ProgrammingError; use \Icinga\Web\Form\Decorator\HelpText; +use \Icinga\Web\Form\Decorator\BoostrapFormDecorator; use \Icinga\Web\Form\InvalidCSRFTokenException; use \Icinga\Application\Config as IcingaConfig; @@ -122,6 +124,13 @@ class Form extends Zend_Form */ private $last_note_id = 0; + /** + * Decorator that replaces the DtDd Zend-Form default + * + * @var Form\Decorator\BoostrapFormDecorator + */ + private $formDecorator; + /** * Getter for the session ID * @@ -554,4 +563,52 @@ class Form extends Zend_Form list ($seed, $token) = $this->generateCsrfToken($this->getSessionId()); return sprintf('%s|%s', $seed, $token); } + + /** + * Add a new element + * + * Additionally, all DtDd tags will be removed and the Boostrap compatible + * BoostrapFormDecorator will be added to the forms + * + * + * @param string|\Zend_Form_Element $element The element or elementtype to add + * @param string $name The name of the element to add if $element is a string + * @param array $options The settings for the element if $element is a string + * + * @return Form + * @see Zend_Form + */ + public function addElement($element, $name = null, $options = null) + { + parent::addElement($element, $name, $options); + $el = $name ? $this->getElement($name) : $element; + if ($el) { + $el->removeDecorator('HtmlTag'); + $el->removeDecorator('Label'); + $el->removeDecorator('DtDdWrapper'); + $el->addDecorator(new BoostrapFormDecorator()); + $el->setAttrib('class', $el->getAttrib('class') . ' form-control input-sm'); + } + + return $this; + } + + /** + * Load the default decorators + * + * @return Zend_Form + */ + public function loadDefaultDecorators() + { + if ($this->loadDefaultDecoratorsIsDisabled()) { + return $this; + } + + $decorators = $this->getDecorators(); + if (empty($decorators)) { + $this->addDecorator('FormElements') + ->addDecorator('Form'); + } + return $this; + } } diff --git a/library/Icinga/Web/Form/Decorator/BoostrapFormDecorator.php b/library/Icinga/Web/Form/Decorator/BoostrapFormDecorator.php new file mode 100644 index 000000000..d47a3e058 --- /dev/null +++ b/library/Icinga/Web/Form/Decorator/BoostrapFormDecorator.php @@ -0,0 +1,105 @@ + + * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2 + * @author Icinga Development Team + */ +// {{{ICINGA_LICENSE_HEADER}}} + +namespace Icinga\Web\Form\Decorator; + +use Zend_Form_Decorator_Abstract; + + /** + * Decorator that styles forms in the DOM boostrap wants for it's forms + * + * This component replaces the dt/dd wrapping of elements with the approach used by bootstrap. + * + * Labels are drawn for all elements, except hidden, button and submit elements. If you want a + * placeholder for this elements, set the 'addLabelPlaceholder' property. This can be useful in + * cases where you want to put inputs with and inputs without labels on the same line and don't + * want buttons to 'jump' + */ +class BoostrapFormDecorator extends Zend_Form_Decorator_Abstract +{ + /** + * An array of elements that won't get a