From 6d26240d6dddfb0b32b59df0cb1845ac91cc1179 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannis=20Mo=C3=9Fhammer?= Date: Wed, 11 Sep 2013 17:19:18 +0200 Subject: [PATCH] Add Main detail state to url, renderhelper, container tests - The ActionController is now able to render a seperate detail view - All list scripts select the currently active row from the detail view with the 'active' class - Autosubmit is now again attached to the onchange attribute (to prevent issues when js can't load correctly) - Logout is now recognized and causes a page refresh (will be made more generic) - Add history mock for testing url changes - Update all grids to implement the app/mainDetailGrid component refs #4611 --- application/layouts/scripts/body.phtml | 25 +- application/layouts/scripts/inline.phtml | 3 - application/layouts/scripts/layout.phtml | 9 +- .../layouts/scripts/parts/navigation.phtml | 2 +- .../layouts/scripts/parts/topbar.phtml | 3 +- application/views/helpers/MainDetail.php | 69 +++++ .../Web/Controller/ActionController.php | 55 +++- library/Icinga/Web/Form.php | 24 +- .../controllers/ListController.php | 7 +- .../controllers/ShowController.php | 5 +- .../views/scripts/list/downtimes.phtml | 188 +++++++------- .../views/scripts/list/hosts.phtml | 148 +++++------ .../views/scripts/list/notifications.phtml | 59 +++-- .../views/scripts/list/services.phtml | 237 +++++++++--------- .../views/scripts/show/header.phtml | 8 +- .../views/scripts/show/service.phtml | 43 ++-- .../test/icinga/components/containerTest.js | 155 ++++++++++++ test/js/testlib/historymock.js | 59 +++++ 18 files changed, 723 insertions(+), 376 deletions(-) create mode 100644 application/views/helpers/MainDetail.php create mode 100644 test/js/test/icinga/components/containerTest.js create mode 100644 test/js/testlib/historymock.js diff --git a/application/layouts/scripts/body.phtml b/application/layouts/scripts/body.phtml index 908108689..b4a9fcafc 100755 --- a/application/layouts/scripts/body.phtml +++ b/application/layouts/scripts/body.phtml @@ -7,21 +7,18 @@
-
- render('inline.phtml') ?> -
- - + mainDetail($this->render('inline.phtml'), $this->layout()->detailContent); ?>
+
- - -
-
- Icinga 2 Web © 2013 Icinga Team +
+
+ +
+
+ Icinga 2 Web © 2013 Icinga Team +
+
-
- +
\ No newline at end of file diff --git a/application/layouts/scripts/inline.phtml b/application/layouts/scripts/inline.phtml index 1157e8ca9..8f6e18169 100644 --- a/application/layouts/scripts/inline.phtml +++ b/application/layouts/scripts/inline.phtml @@ -1,4 +1 @@ -layout()->moduleStart ?> layout()->content ?> -layout()->benchmark ?> -layout()->moduleEnd ?> diff --git a/application/layouts/scripts/layout.phtml b/application/layouts/scripts/layout.phtml index 35a366e20..533b42fd8 100755 --- a/application/layouts/scripts/layout.phtml +++ b/application/layouts/scripts/layout.phtml @@ -17,11 +17,11 @@ - + diff --git a/application/layouts/scripts/parts/navigation.phtml b/application/layouts/scripts/parts/navigation.phtml index d9901a5ba..78e873fb8 100755 --- a/application/layouts/scripts/parts/navigation.phtml +++ b/application/layouts/scripts/parts/navigation.phtml @@ -6,7 +6,7 @@ $currentKey = isset($this->navkey) ? $this->navkey : $url; $item = $this->navigation->keys("menu"); ?> auth()->isAuthenticated()): ?> -
\ No newline at end of file diff --git a/modules/monitoring/application/views/scripts/list/hosts.phtml b/modules/monitoring/application/views/scripts/list/hosts.phtml index 2bbb72135..d7cef24b1 100644 --- a/modules/monitoring/application/views/scripts/list/hosts.phtml +++ b/modules/monitoring/application/views/scripts/list/hosts.phtml @@ -5,105 +5,87 @@ $hosts = $this->hosts->paginate(); $viewHelper = $this->getHelper('MonitoringState'); ?> -sortControl->render($this); ?> -paginationControl($hosts, null, null, array('preserve' => $this->preserve)); ?> +
- + sortControl->render($this); ?> + paginationControl($hosts, null, null, array('preserve' => $this->preserve)); ?> - +
+ - + - - - + + - - - + + href('monitoring/show/host', array('host' => $host->host_name)); ?> + activeRowHref === $hostLink) ? 'class="active"' : ''; ?> > + + + + - host_in_downtime): ?> - - {{IN_DOWNTIME_ICON}} - - + - - - - + + +
StatusStatus Host Output
-
- host_icon_image) : ?> - - -
-
+ +
+
-
-
- host_handled && $host->host_state > 0): ?> - - {{UNHANDLED_ICON}} + + host_icon_image) : ?> + + +
+
+
+ host_handled && $host->host_state > 0): ?> + + {{UNHANDLED_ICON}} + + + + host_acknowledged && !$host->host_in_downtime): ?> + + {{ACKNOWLEDGED_ICON}} + + + + host_is_flapping): ?> + + {{FLAPPING_ICON}} + + +
+
+ host_last_comment !== null): ?> + + {{COMMENT_ICON}} - host_acknowledged && !$host->host_in_downtime): ?> - - {{ACKNOWLEDGED_ICON}} + + host_name ?>
+ host_address ?>
+ + host_action_url != ""): ?> + Action - host_is_flapping): ?> - - {{FLAPPING_ICON}} - + host_notes_url != ""): ?> + Notes - host_notifications_enabled): ?> - - {{NOTIFICATIONS_DISABLED_ICON}} - - +
+ escape(substr(strip_tags($host->host_output), 0, 10000)); ?> + -
- monitoringState($host, 'host')); ?> -
Since  - timeSince($host->host_last_state_change); ?> - host_state_type == 0): ?> - - {{SOFTSTATE_ICON}} - - -
-
-
- host_last_comment !== null): ?> - - {{COMMENT_ICON}} - - +
+ paginationControl($hosts, null, null, array('preserve' => $this->preserve)); ?> - - host_name ?>
- host_address ?> -
- - host_action_url != ""): ?> - Action - - - host_notes_url != ""): ?> - Notes - - - - - - escape(substr(strip_tags($host->host_output), 0, 10000)); ?> - - - - - - +
diff --git a/modules/monitoring/application/views/scripts/list/notifications.phtml b/modules/monitoring/application/views/scripts/list/notifications.phtml index b10316b0d..eb1629818 100644 --- a/modules/monitoring/application/views/scripts/list/notifications.phtml +++ b/modules/monitoring/application/views/scripts/list/notifications.phtml @@ -3,29 +3,41 @@ getHelper('MonitoringProperties'); ?> +
+ sortControl->render($this); ?> + notifications->paginate(); + ?> -sortControl->render($this); ?> -notifications->paginate(); -echo $this->paginationControl($notifications, null, null, array('preserve' => $this->preserve)); -?> - - - - - - - - - - - - - - - - - @@ -103,12 +103,12 @@ if (!$this->compact) { diff --git a/modules/monitoring/application/views/scripts/show/service.phtml b/modules/monitoring/application/views/scripts/show/service.phtml index 08be70a2b..f56b0e23d 100644 --- a/modules/monitoring/application/views/scripts/show/service.phtml +++ b/modules/monitoring/application/views/scripts/show/service.phtml @@ -25,22 +25,22 @@ $this->partial( ?> preview_image ?> -
-
+
+
Plugin output
-
+
pluginOutput($this->service->service_output); ?> pluginOutput($this->service->service_long_output); ?>
-
-
+
+
{{CHECK_ICON}} Check Command
-
+
service->service_check_command, 2); echo array_shift($explodedCommand); @@ -49,16 +49,18 @@ $this->partial(
-
-
+
+
{{GROUP_ICON}} Groups and Contacts
+
{{SERVICEGROUP_ICON}} Servicegroups: render('show/components/contacts.phtml') ?> +
render('show/components/comments.phtml'); ?> @@ -68,40 +70,39 @@ $this->partial( render('show/components/customvars.phtml'); ?> service->service_perfdata): ?> -
- -
+
+
Perfdata
-
+
perfdata($this->service->service_perfdata); ?>
-
-
+
+
Flags
-
+
render('show/components/flags.phtml'); ?>
-
-
+
+
Properties
-
+
render('show/components/properties.phtml'); ?>
-
-
+
+
{{COMMAND_ICON}} Commands
-
+
monitoringCommands($this->service, 'full'); ?>
\ No newline at end of file diff --git a/test/js/test/icinga/components/containerTest.js b/test/js/test/icinga/components/containerTest.js new file mode 100644 index 000000000..85cd9dba3 --- /dev/null +++ b/test/js/test/icinga/components/containerTest.js @@ -0,0 +1,155 @@ +/*global requireNew:false, describe: false, it:false */ + +/** + * {{LICENSE_HEADER}} + * {{LICENSE_HEADER}} + */ + +/** + * The assertion framework + * + * @type {should} + */ +var should = require('should'); + +/** + * RequireJS mocks for dynamically loading modules + * + * @type {requiremock} + */ +var rjsmock = require('requiremock.js'); + +/** + * URIjs object for easier URL manipulation + * + * @type {URIjs} + */ +var URI = require('URIjs'); + +// Setup required globals for this test +GLOBAL.document = $('body'); +GLOBAL.History = require('historymock.js'); +GLOBAL.Modernizr = { + history: true +}; + +/** + * Workaround as jQuery.contains doesn't work with the nodejs jQuery library on some test systems + * + * @returns {boolean} + */ +jQuery.contains = function() { + 'use strict'; + return true; +}; + +/** + * Create a basic dom only containing a main and detail container + * + */ +var createDOM = function() { + 'use strict'; + + document.empty(); + document.append( + $('
').attr('id', 'icingamain') + ).append( + $('
').attr('id', 'icingadetail') + ); +}; + +$.ajax = function(obj) { + obj.success("
"); + +}; +/** + * Test case + * + */ +describe('The container component', function() { + 'use strict'; + + /** + * Test dom selectors and instance creation + */ + it('should provide access to the main and detail component', function() { + requireNew('icinga/components/container.js'); + createDOM(); + var Container = rjsmock.getDefine(); + should.exist(Container.getMainContainer().containerDom, 'Assert that the main container has an DOM attached'); + should.exist(Container.getDetailContainer().containerDom, 'Assert that the detail container has an DOM attached'); + Container.getMainContainer().containerDom[0].should.equal( + $('#icingamain')[0], 'Assert the DOM of the main container being #icingamain'); + Container.getDetailContainer().containerDom[0].should.equal( + $('#icingadetail')[0], 'Assert the DOM of the detail container being #icingadetail'); + }); + + /** + * Test dynamic Url update + */ + it('should automatically update its part of the URL if assigning a new URL', function() { + rjsmock.registerDependencies({ + 'URIjs/URI' : URI + }); + requireNew('icinga/components/container.js'); + createDOM(); + var Container = rjsmock.getDefine(); + Container.getMainContainer().updateContainerHref('/some/other/url?test'); + Container.getMainContainer().containerDom.attr('data-icinga-href').should.equal('/some/other/url?test'); + + window.location.href.should.equal( + '/some/other/url?test', + 'Assert the main container updating the url correctly'); + + Container.getDetailContainer().updateContainerHref('/some/detail/url?test'); + Container.getDetailContainer().containerDom.attr('data-icinga-href').should.equal('/some/detail/url?test'); + window.location.href.should.equal( + '/some/other/url?test&detail=' + encodeURIComponent('/some/detail/url?test'), + 'Assert the detail container only updating the "detail" portion of the URL' + ); + + Container.getMainContainer().updateContainerHref('/some/other2/url?test=test'); + Container.getMainContainer().containerDom.attr('data-icinga-href').should.equal('/some/other2/url?test=test'); + window.location.href.should.equal( + '/some/other2/url?test=test&detail=' + encodeURIComponent('/some/detail/url?test'), + 'Assert the main container keeping the detail portion untouched if being assigned a new URL' + ); + }); + + /** + * Test synchronization with Url + */ + it('should be able to sync correctly with the current url if the URL changed', function() { + rjsmock.registerDependencies({ + 'URIjs/URI' : URI, + 'icinga/componentLoader' : { + load: function() {} + } + }); + requireNew('icinga/components/container.js'); + createDOM(); + + var Container = rjsmock.getDefine(); + var containerModified = false; + + Container.getMainContainer().updateContainerHref('/my/test/url?test=1'); + Container.getMainContainer().registerOnUpdate(function() { + containerModified = true; + }); + + window.setWindowUrl('/my/test/url?test=2'); + Container.getMainContainer().syncWithCurrentUrl(); + Container.getMainContainer().containerDom.attr('data-icinga-href').should.equal('/my/test/url?test=2'); + containerModified.should.equal(true); + containerModified = false; + + Container.getMainContainer().syncWithCurrentUrl(); + // URL hasn't changed, so this should not return true + containerModified.should.equal(false); + + window.setWindowUrl('/my/test/url?test=2&detail=test'); + Container.getMainContainer().syncWithCurrentUrl(); + // URL is not modified for main container, so this should not return true + containerModified.should.equal(false); + }); +}); diff --git a/test/js/testlib/historymock.js b/test/js/testlib/historymock.js new file mode 100644 index 000000000..bbefd6467 --- /dev/null +++ b/test/js/testlib/historymock.js @@ -0,0 +1,59 @@ +/** + * {{LICENSE_HEADER}} + * {{LICENSE_HEADER}} + */ + +var URI = require('URIjs'); + +(function() { + GLOBAL.window = { + location: { + href: 'http://localhost/icinga2-web/testcase', + pathname: '/icinga2-web/testcase', + query: '', + hash: '', + host: 'localhost', + protocol: 'http' + } + }; + "use strict"; + + var states = []; + + + window.setWindowUrl = function(url) { + var url = URI(url); + window.location.protocol = url.protocol(); + window.location.pathname = url.pathname(); + window.location.query = url.query(); + window.location.search = url.search(); + window.location.hash = url.hash(); + window.location.href = url.href(); + }; + + /** + * Mock for the History API + * + * @type {{pushState: Function, popState: Function, replaceState: Function, clear: Function}} + */ + module.exports = { + pushState: function(state, title, url) { + window.setWindowUrl(url); + states.push(arguments); + }, + popState: function() { + return states.pop(); + }, + replaceState: function(state, title, url) { + states.pop(); + window.setWindowUrl(url); + states.push(arguments); + }, + clearState: function() { + states = []; + }, + getState: function() { + return states; + } + }; +})(); \ No newline at end of file
HostServiceTypeTimeContactNotification CommandInformation
+ paginationControl($notifications, null, null, array('preserve' => $this->preserve)); ?> + + + + + + + + + + + + + + + service_description)) { + $detailLink = $this->href('monitoring/show/host', array('host' => $notification->host_name)); + } else { + $detailLink = $this->href('monitoring/show/host', array( + 'host' => $notification->host_name, + 'service' => $notification->service_description + ) + ); + } + ?> + activeRowHref === $detailLink) ? 'class="active"' : ''; ?>> + @@ -56,3 +69,5 @@ echo $this->paginationControl($notifications, null, null, array('preserve' => $t
HostServiceTypeTimeContactNotification CommandInformation
+ host_name ?> @@ -37,6 +49,7 @@ echo $this->paginationControl($notifications, null, null, array('preserve' => $t ) ); ?>"> service_description) ? '' : $notification->service_description; ?> + getNotificationType($notification); ?>
+ + \ No newline at end of file diff --git a/modules/monitoring/application/views/scripts/list/services.phtml b/modules/monitoring/application/views/scripts/list/services.phtml index a300dee7a..ccb501d10 100644 --- a/modules/monitoring/application/views/scripts/list/services.phtml +++ b/modules/monitoring/application/views/scripts/list/services.phtml @@ -4,131 +4,134 @@ $paginator = $services->paginate(); $viewHelper = $this->getHelper('MonitoringState'); ?> +
-sortControl->render($this); ?> -paginationControl($paginator, null, null, array('preserve' => $this->preserve)) ?> + sortControl->render($this); ?> + paginationControl($paginator, null, null, array('preserve' => $this->preserve)) ?> - - - - - - - - - - - - fetchAll() as $service): ?> - - - - - - + + + + + + + +
StatusServiceHostOutput
-
- service_icon_image) : ?> - - -
-
-
- service_handled && $service->service_state > 0): ?> - - {{UNHANDLED_ICON}} - - - - service_acknowledged && !$service->service_in_downtime): ?> - - {{ACKNOWLEDGED_ICON}} - - - - service_is_flapping): ?> - - {{FLAPPING_ICON}} - - - - service_notifications_enabled): ?> - - {{NOTIFICATIONS_DISABLED_ICON}} - - - - service_in_downtime): ?> - - {{IN_DOWNTIME_ICON}} - - - -
-
-
- monitoringState($service, 'service')); ?> -
Since  - timeSince($service->service_last_state_change); ?> - - service_state_type == 0): ?> - - {{SOFTSTATE_ICON}} - - + + + + + + + + + + + + fetchAll() as $service): ?> + href('monitoring/show/service',array( + 'host' => $service->host_name, + 'service' => $service->service_description + ) + ); + $hostLink = $this->href('monitoring/show/host',array( + 'host' => $service->host_name, + ) + ); + ?> + activeRowHref === $serviceLink) ? 'class="active"' : ''; ?>> + + + - - service_notes_url != ""): ?> - Notes - - + + service_notes_url != ""): ?> + Notes + - - - - -
StatusServiceHostOutput
+ +
+ service_icon_image) : ?> + +
- -
+
+ service_handled && $service->service_state > 0): ?> + + {{UNHANDLED_ICON}} + + + + service_acknowledged && !$service->service_in_downtime): ?> + + {{ACKNOWLEDGED_ICON}} + + + + service_is_flapping): ?> + + {{FLAPPING_ICON}} + + + + service_notifications_enabled): ?> + + {{NOTIFICATIONS_DISABLED_ICON}} + + + + service_in_downtime): ?> + + {{IN_DOWNTIME_ICON}} + + + +
+
- service_last_comment !== null): ?> - - {{COMMENT_ICON}} - - - - service_display_name; ?> - -
+
+
+ monitoringState($service, 'service')); ?> +
Since  + timeSince($service->service_last_state_change); ?> - service_action_url != ""): ?> - Action - + service_state_type == 0): ?> + + {{SOFTSTATE_ICON}} + + +
+
+
+ service_last_comment !== null): ?> + + {{COMMENT_ICON}} + + + + service_display_name; ?> + +
-
- - host_name; ?> - + service_action_url != ""): ?> + Action + -
- (monitoringState($service, 'host')); ?>) -
- - host_address ?> - -
- escape(substr(strip_tags($service->service_output), 0, 10000)); ?> -
+
+ + host_name; ?> + + +
+ (monitoringState($service, 'host')); ?>) +
+ + host_address ?> + +
+ escape(substr(strip_tags($service->service_output), 0, 10000)); ?> +
+
\ No newline at end of file diff --git a/modules/monitoring/application/views/scripts/show/header.phtml b/modules/monitoring/application/views/scripts/show/header.phtml index 03d2328f0..91141018e 100644 --- a/modules/monitoring/application/views/scripts/show/header.phtml +++ b/modules/monitoring/application/views/scripts/show/header.phtml @@ -65,11 +65,11 @@ if (!$this->compact) {
host->host_action_url): ?> {{EXTERNAL_LINK_ICON}} - Host actions + Host actions host->host_notes_url): ?> {{EXTERNAL_LINK_ICON}} - Host notes + Host notes
service->service_action_url): ?> {{EXTERNAL_LINK_ICON}} - Service actions + Service actions service->service_notes_url): ?> {{EXTERNAL_LINK_ICON}} - Service notes + Service notes