From 7b67b852132870af8ebe30e6b5e99f9a1f372a97 Mon Sep 17 00:00:00 2001 From: Zita Nemeckova Date: Wed, 17 Jan 2018 17:11:12 +0100 Subject: [PATCH 01/14] Add wrapper for widget in Dashboard --- .../javascripts/components/widget-chart.js | 25 +---- .../javascripts/components/widget-menu.js | 15 +-- .../javascripts/components/widget-report.js | 15 +-- .../javascripts/components/widget-rss.js | 15 +-- .../javascripts/components/widget-wrapper.js | 94 +++++++++++++++++++ app/views/dashboard/_widget.html.haml | 35 +++---- 6 files changed, 120 insertions(+), 79 deletions(-) create mode 100644 app/assets/javascripts/components/widget-wrapper.js diff --git a/app/assets/javascripts/components/widget-chart.js b/app/assets/javascripts/components/widget-chart.js index 0e0b07cbd8d..dd9c39f08ef 100644 --- a/app/assets/javascripts/components/widget-chart.js +++ b/app/assets/javascripts/components/widget-chart.js @@ -1,29 +1,15 @@ ManageIQ.angular.app.component('widgetChart', { bindings: { widgetId: '@', + widgetModel: '<', }, controllerAs: 'vm', controller: ['$http', 'miqService', '$sce', function($http, miqService, $sce) { var vm = this; - vm.widgetChartModel = {}; - this.$onInit = function() { - $http.get('/dashboard/widget_chart_data/' + vm.widgetId) - .then(vm.getData) - .catch(miqService.handleFailure); - vm.div_id = "dd_w" + vm.widgetId + "_box"; - }; - - vm.getData = function(response) { - vm.widgetChartModel.state = response.data.state; - if (response.data.content !== null) { - vm.widgetChartModel.content = $sce.trustAsHtml(response.data.content); - } - }; }], template: [ - '
', - '
', + '
', '
', ' ', ' ', @@ -32,7 +18,7 @@ ManageIQ.angular.app.component('widgetChart', { __('No chart data found.'), ' ', '
', - '
', + '
', '
', ' ', ' ', @@ -44,10 +30,9 @@ ManageIQ.angular.app.component('widgetChart', { __('Invalid chart data. Try regenerating the widgets.'), '

', '
', - '
', - '
', + '
', + '
', '
', '
', - '
', ].join("\n"), }); diff --git a/app/assets/javascripts/components/widget-menu.js b/app/assets/javascripts/components/widget-menu.js index 38d1bc36eaa..8d5495e78d9 100644 --- a/app/assets/javascripts/components/widget-menu.js +++ b/app/assets/javascripts/components/widget-menu.js @@ -1,31 +1,23 @@ ManageIQ.angular.app.component('widgetMenu', { bindings: { widgetId: '@', + widgetModel: '<', }, controllerAs: 'vm', controller: ['$http', 'miqService', function($http, miqService) { var vm = this; - vm.widgetMenuModel = {shortcuts: []}; vm.shortcutsMissing = function() { - return vm.widgetMenuModel.shortcuts.length === 0; - }; - - this.$onInit = function() { - $http.get('/dashboard/widget_menu_data/' + vm.widgetId) - .then(function(response) { vm.widgetMenuModel = response.data; }) - .catch(miqService.handleFailure); - vm.div_id = 'dd_w' + vm.widgetId + '_box'; + return vm.widgetModel.shortcuts.length === 0; }; }], template: [ - '
', ' ', ' ', '
', __('No shortcuts are authorized for this user, contact your Administrator'), '
', - ' ', + ' ', ' ', ' ', '
', ' ', '{{shortcut.description}}', @@ -34,6 +26,5 @@ ManageIQ.angular.app.component('widgetMenu', { '
', - '
', ].join("\n"), }); diff --git a/app/assets/javascripts/components/widget-report.js b/app/assets/javascripts/components/widget-report.js index 0cb9874be87..f0a71d8cfbc 100644 --- a/app/assets/javascripts/components/widget-report.js +++ b/app/assets/javascripts/components/widget-report.js @@ -1,25 +1,17 @@ ManageIQ.angular.app.component('widgetReport', { bindings: { widgetId: '@', + widgetModel: '<', }, controllerAs: 'vm', controller: ['$http', 'miqService', '$sce', function($http, miqService, $sce) { var vm = this; - vm.widgetReportModel = {}; - - this.$onInit = function() { - $http.get('/dashboard/widget_report_data/' + vm.widgetId) - .then(function(response) { vm.widgetReportModel.content = $sce.trustAsHtml(response.data.content);}) - .catch(miqService.handleFailure); - vm.div_id = "dd_w" + vm.widgetId + "_box"; - }; vm.contentPresent = function() { - return vm.widgetReportModel.content !== undefined; + return vm.widgetModel && vm.widgetModel.content !== undefined; }; }], template: [ - '
', '
', '
', ' ', @@ -30,10 +22,9 @@ ManageIQ.angular.app.component('widgetReport', { '
', '
', '
', - '
', + '
', '
', '
', - '
', ].join("\n"), }); diff --git a/app/assets/javascripts/components/widget-rss.js b/app/assets/javascripts/components/widget-rss.js index a5cb45cdf39..0216b7786d7 100644 --- a/app/assets/javascripts/components/widget-rss.js +++ b/app/assets/javascripts/components/widget-rss.js @@ -1,25 +1,17 @@ ManageIQ.angular.app.component('widgetRss', { bindings: { widgetId: '@', + widgetModel: '<', }, controllerAs: 'vm', controller: ['$http', 'miqService', '$sce', function($http, miqService, $sce) { var vm = this; - vm.widgetRssModel = {}; - - this.$onInit = function() { - $http.get('/dashboard/widget_rss_data/' + vm.widgetId) - .then(function(response) { vm.widgetRssModel.content = $sce.trustAsHtml(response.data.content); }) - .catch(miqService.handleFailure); - vm.div_id = "dd_w" + vm.widgetId + "_box"; - }; vm.contentPresent = function() { - return vm.widgetRssModel.content !== undefined; + return vm.widgetModel && vm.widgetModel.content !== undefined; }; }], template: [ - '
', '
', '
', ' ', @@ -30,9 +22,8 @@ ManageIQ.angular.app.component('widgetRss', { '
', '
', '
', - '
', + '
', '
', '
', - '
', ].join("\n"), }); diff --git a/app/assets/javascripts/components/widget-wrapper.js b/app/assets/javascripts/components/widget-wrapper.js new file mode 100644 index 00000000000..36400e57f4a --- /dev/null +++ b/app/assets/javascripts/components/widget-wrapper.js @@ -0,0 +1,94 @@ +ManageIQ.angular.app.component('widgetWrapper', { + bindings: { + widgetId: '@', + widgetType: '@', + widgetButtons: '@', + widgetBlank: '@', + widgetTitle: '@', + widgetLastRun: '@', + widgetNextRun: '@', + }, + controllerAs: 'vm', + controller: ['$http', 'miqService', '$sce', function($http, miqService, $sce) { + var vm = this; + + this.$onInit = function() { + vm.divId = "w_" + vm.widgetId; + vm.innerDivId = 'dd_w' + vm.widgetId + '_box'; + if (vm.widgetBlank == 'false') { + $http.get(vm.widgetUrl()) + .then(function(response) { + vm.widgetModel = response.data; + // if there's html make it passable + if (vm.widgetModel.content) { + vm.widgetModel.content = $sce.trustAsHtml(vm.widgetModel.content); + }; + }) + .catch(miqService.handleFailure); + }; + }; + + vm.widgetUrl = function() { + switch(vm.widgetType){ + case 'menu': + return '/dashboard/widget_menu_data/' + vm.widgetId; + case 'report': + return '/dashboard/widget_report_data/' + vm.widgetId; + case 'chart': + return '/dashboard/widget_chart_data/' + vm.widgetId; + case 'rss': + return '/dashboard/widget_rss_data/' + vm.widgetId; + default: + console.log('Something happened. You can see: ', vm.widgetType); + }; + }; + + }], + template: [ + '
', + '
', + '
', + '
', + ' ', + ' ', + '

', + "{{vm.widgetTitle}}", + '

', + '
', + '
', + '
', + '
', + '
', + '
', + ' ', + '
', + '

', + __('No data found.'), + '

', + '

', + __('If this widget is new or has just been added to your dashboard, the data is being generated and should be available soon.'), + '

', + '
', + '
', + '
', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + '
', + ' ', + '
', + '
', + '
', + ].join("\n"), +}); diff --git a/app/views/dashboard/_widget.html.haml b/app/views/dashboard/_widget.html.haml index 2dc16d3f8c1..62c092694e0 100644 --- a/app/views/dashboard/_widget.html.haml +++ b/app/views/dashboard/_widget.html.haml @@ -1,25 +1,14 @@ --# Parameters: --# widget MiqWidget object -%div{:id => "w_#{presenter.widget.id}"} - .card-pf.card-pf-view - .card-pf-body - .card-pf-heading-kebab - %dropdown-menu{"widget-id" => presenter.widget.id, "buttons-data" => presenter.widget_buttons} - %h2.card-pf-title.sortable-handle{:style => "cursor:move"} - = h(presenter.widget.title) - - - if presenter.widget.content_type == "menu" - %widget-menu{:id => presenter.widget.id, "widget-id" => presenter.widget.id} - - elsif presenter.widget.contents_for_user(current_user).blank? - = render :partial => 'widget_blank', :locals => {:widget => presenter.widget} - - elsif presenter.widget.content_type == "report" - %widget-report{:id => presenter.widget.id, "widget-id" => presenter.widget.id} - - elsif presenter.widget.content_type == "chart" - %widget-chart{:id => presenter.widget.id, "widget-id" => presenter.widget.id} - - elsif presenter.widget.content_type == "rss" - %widget-rss{:id => presenter.widget.id, "widget-id" => presenter.widget.id} - - unless presenter.widget.content_type == "menu" - = render :partial => 'widget_footer', :locals => {:widget => presenter.widget} +%div{:id => "ww_#{presenter.widget.id}"} + - last_run_on = presenter.widget.last_run_on_for_user(current_user) + - next_run_on = presenter.widget.next_run_on + - widget_blank = presenter.widget.content_type == 'menu' ? false : presenter.widget.contents_for_user(current_user).blank? + %widget-wrapper{"widget-id" => presenter.widget.id, + "widget-type" => presenter.widget.content_type, + "widget-buttons" => presenter.widget_buttons, + "widget_blank" => widget_blank, + "widget-last-run" => last_run_on ? format_timezone(last_run_on, session[:user_tz], "widget_footer") : _('Never'), + "widget-next-run" => next_run_on ? format_timezone(next_run_on, session[:user_tz], "widget_footer") : _('Unknown'), + "widget-title" => presenter.widget.title} :javascript - miq_bootstrap("#w_#{presenter.widget.id}"); + miq_bootstrap("#ww_#{presenter.widget.id}"); From 30ad6a25ca850adf3ef787405ddc7f8e7abfcc7a Mon Sep 17 00:00:00 2001 From: Zita Nemeckova Date: Tue, 23 Jan 2018 09:43:21 +0100 Subject: [PATCH 02/14] Remove no longer used views --- app/views/dashboard/_widget_blank.html.haml | 10 ---------- app/views/dashboard/_widget_footer.html.haml | 17 ----------------- 2 files changed, 27 deletions(-) delete mode 100644 app/views/dashboard/_widget_blank.html.haml delete mode 100644 app/views/dashboard/_widget_footer.html.haml diff --git a/app/views/dashboard/_widget_blank.html.haml b/app/views/dashboard/_widget_blank.html.haml deleted file mode 100644 index 2ef84b0ea97..00000000000 --- a/app/views/dashboard/_widget_blank.html.haml +++ /dev/null @@ -1,10 +0,0 @@ --# - Parameters: - widget -- MiqWidget object -.mc{:id => "dd_w#{widget.id}_box", -:style => "#{@sb[:dashboards][@sb[:active_db]][:minimized].include?(widget.id) ? 'display: none;' : ''}"} - .blank-slate-pf{:style => "padding: 10px"} - .blank-slate-pf-icon - %i.fa.fa-cog - %h1= _('No data found.') - %p= _('If this widget is new or has just been added to your dashboard, the data is being generated and should be available soon.') diff --git a/app/views/dashboard/_widget_footer.html.haml b/app/views/dashboard/_widget_footer.html.haml deleted file mode 100644 index df198451858..00000000000 --- a/app/views/dashboard/_widget_footer.html.haml +++ /dev/null @@ -1,17 +0,0 @@ --# - Parameters: - widget -- MiqWidget object -.card-pf-footer - = _('Updated') - - last_run_on = widget.last_run_on_for_user(current_user) - - if last_run_on - = format_timezone(last_run_on, session[:user_tz], "widget_footer") - - else - = _('Never') -   |   - = _('Next') - - next_run_on = widget.next_run_on - - if next_run_on - = format_timezone(next_run_on, session[:user_tz], "widget_footer") - - else - = _('Unknown') From 13109eb6da4aac5abb454e541cd9106f3b6b390c Mon Sep 17 00:00:00 2001 From: Zita Nemeckova Date: Tue, 23 Jan 2018 11:23:17 +0100 Subject: [PATCH 03/14] Add spinner when no data is loaded yet --- app/assets/javascripts/components/widget-wrapper.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/javascripts/components/widget-wrapper.js b/app/assets/javascripts/components/widget-wrapper.js index 36400e57f4a..6ad2c34ce43 100644 --- a/app/assets/javascripts/components/widget-wrapper.js +++ b/app/assets/javascripts/components/widget-wrapper.js @@ -56,6 +56,7 @@ ManageIQ.angular.app.component('widgetWrapper', { ' ', '
', '
', + ' ', '
', '
', '
', From 079414c9987c405b94b0e411a501148c1a78dbe7 Mon Sep 17 00:00:00 2001 From: Zita Nemeckova Date: Wed, 7 Feb 2018 13:40:35 +0100 Subject: [PATCH 04/14] Add error option and styling of spinner --- .../javascripts/components/widget-wrapper.js | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/components/widget-wrapper.js b/app/assets/javascripts/components/widget-wrapper.js index 6ad2c34ce43..bf30aa8e1a2 100644 --- a/app/assets/javascripts/components/widget-wrapper.js +++ b/app/assets/javascripts/components/widget-wrapper.js @@ -24,7 +24,10 @@ ManageIQ.angular.app.component('widgetWrapper', { vm.widgetModel.content = $sce.trustAsHtml(vm.widgetModel.content); }; }) - .catch(miqService.handleFailure); + .catch(function(){ + vm.error = true; + miqService.handleFailure; + }); }; }; @@ -39,7 +42,7 @@ ManageIQ.angular.app.component('widgetWrapper', { case 'rss': return '/dashboard/widget_rss_data/' + vm.widgetId; default: - console.log('Something happened. You can see: ', vm.widgetType); + console.log('Something went wrong. There is no support for widget type of ', vm.widgetType); }; }; @@ -56,7 +59,23 @@ ManageIQ.angular.app.component('widgetWrapper', { ' ', '
', '
', - ' ', + '
', + '
', + '
', + ' ', + '
', + '

', + __('There was an error during '), + '

', + '
', + '
', + '
', + '
', + '
', + ' ', + '
', + '
', + '
', '
', '
', '
', From dcf173ddeb786477174ff6671d8463ce19464433 Mon Sep 17 00:00:00 2001 From: Zita Nemeckova Date: Wed, 7 Feb 2018 14:37:28 +0100 Subject: [PATCH 05/14] Move specific parts of widget-wrapper to components --- .../javascripts/components/widget-chart.js | 4 -- .../javascripts/components/widget-empty.js | 15 ++++++ .../javascripts/components/widget-error.js | 12 +++++ .../javascripts/components/widget-footer.js | 16 ++++++ .../javascripts/components/widget-menu.js | 28 +++++----- .../javascripts/components/widget-report.js | 26 +++++---- .../javascripts/components/widget-rss.js | 5 +- .../javascripts/components/widget-spinner.js | 9 ++++ .../javascripts/components/widget-wrapper.js | 54 ++++--------------- 9 files changed, 90 insertions(+), 79 deletions(-) create mode 100644 app/assets/javascripts/components/widget-empty.js create mode 100644 app/assets/javascripts/components/widget-error.js create mode 100644 app/assets/javascripts/components/widget-footer.js create mode 100644 app/assets/javascripts/components/widget-spinner.js diff --git a/app/assets/javascripts/components/widget-chart.js b/app/assets/javascripts/components/widget-chart.js index dd9c39f08ef..4b022a7b46f 100644 --- a/app/assets/javascripts/components/widget-chart.js +++ b/app/assets/javascripts/components/widget-chart.js @@ -4,10 +4,6 @@ ManageIQ.angular.app.component('widgetChart', { widgetModel: '<', }, controllerAs: 'vm', - controller: ['$http', 'miqService', '$sce', function($http, miqService, $sce) { - var vm = this; - - }], template: [ '
', '
', diff --git a/app/assets/javascripts/components/widget-empty.js b/app/assets/javascripts/components/widget-empty.js new file mode 100644 index 00000000000..1d85802315e --- /dev/null +++ b/app/assets/javascripts/components/widget-empty.js @@ -0,0 +1,15 @@ +ManageIQ.angular.app.component('widgetEmpty', { + template: [ + '
', + '
', + ' ', + '
', + '

', + __('No data found.'), + '

', + '

', + __('If this widget is new or has just been added to your dashboard, the data is being generated and should be available soon.'), + '

', + '
', + ].join("\n"), +}); diff --git a/app/assets/javascripts/components/widget-error.js b/app/assets/javascripts/components/widget-error.js new file mode 100644 index 00000000000..5ca595e6710 --- /dev/null +++ b/app/assets/javascripts/components/widget-error.js @@ -0,0 +1,12 @@ +ManageIQ.angular.app.component('widgetError', { + template: [ + '
', + '
', + ' ', + '
', + '

', + __('Error: Request for data failed.'), + '

', + '
', + ].join("\n"), +}); diff --git a/app/assets/javascripts/components/widget-footer.js b/app/assets/javascripts/components/widget-footer.js new file mode 100644 index 00000000000..de6a8fa965e --- /dev/null +++ b/app/assets/javascripts/components/widget-footer.js @@ -0,0 +1,16 @@ +ManageIQ.angular.app.component('widgetFooter', { + bindings: { + widgetLastRun: '@', + widgetNextRun: '@', + }, + controllerAs: 'vm', + template: [ + '', + ].join("\n"), +}); diff --git a/app/assets/javascripts/components/widget-menu.js b/app/assets/javascripts/components/widget-menu.js index 8d5495e78d9..090d8669f8c 100644 --- a/app/assets/javascripts/components/widget-menu.js +++ b/app/assets/javascripts/components/widget-menu.js @@ -4,27 +4,27 @@ ManageIQ.angular.app.component('widgetMenu', { widgetModel: '<', }, controllerAs: 'vm', - controller: ['$http', 'miqService', function($http, miqService) { + controller: function() { var vm = this; vm.shortcutsMissing = function() { return vm.widgetModel.shortcuts.length === 0; }; - }], + }, template: [ - ' ', - ' ', - '
', + '
', + ' ', + '
', __('No shortcuts are authorized for this user, contact your Administrator'), - '
', - ' ', - ' ', + ' ', - ' ', - ' ', - '
', - ' ', + ' ', + '
', + ' ', '{{shortcut.description}}', - ' ', - '
', + ' ', + ' ', + ' ', + ' ', + '', ].join("\n"), }); diff --git a/app/assets/javascripts/components/widget-report.js b/app/assets/javascripts/components/widget-report.js index f0a71d8cfbc..94152440d91 100644 --- a/app/assets/javascripts/components/widget-report.js +++ b/app/assets/javascripts/components/widget-report.js @@ -4,27 +4,25 @@ ManageIQ.angular.app.component('widgetReport', { widgetModel: '<', }, controllerAs: 'vm', - controller: ['$http', 'miqService', '$sce', function($http, miqService, $sce) { + controller: function() { var vm = this; - vm.contentPresent = function() { return vm.widgetModel && vm.widgetModel.content !== undefined; }; - }], + }, template: [ - '
', - '
', - ' ', - ' ', - '

', + '
', + '
', + ' ', + ' ', + '

', __('No report data found.'), - '

', - '
', + '

', '
', - '
', - '
', - '
', + '
', + '
', + '
', '
', - + '
', ].join("\n"), }); diff --git a/app/assets/javascripts/components/widget-rss.js b/app/assets/javascripts/components/widget-rss.js index 0216b7786d7..a96c9aa73fb 100644 --- a/app/assets/javascripts/components/widget-rss.js +++ b/app/assets/javascripts/components/widget-rss.js @@ -4,13 +4,12 @@ ManageIQ.angular.app.component('widgetRss', { widgetModel: '<', }, controllerAs: 'vm', - controller: ['$http', 'miqService', '$sce', function($http, miqService, $sce) { + controller: function() { var vm = this; - vm.contentPresent = function() { return vm.widgetModel && vm.widgetModel.content !== undefined; }; - }], + }, template: [ '
', '
', diff --git a/app/assets/javascripts/components/widget-spinner.js b/app/assets/javascripts/components/widget-spinner.js new file mode 100644 index 00000000000..9ba8a04ed46 --- /dev/null +++ b/app/assets/javascripts/components/widget-spinner.js @@ -0,0 +1,9 @@ +ManageIQ.angular.app.component('widgetSpinner', { + template: [ + '
', + '
', + ' ', + '
', + '
', + ].join("\n"), +}); diff --git a/app/assets/javascripts/components/widget-wrapper.js b/app/assets/javascripts/components/widget-wrapper.js index bf30aa8e1a2..52a472c4a3a 100644 --- a/app/assets/javascripts/components/widget-wrapper.js +++ b/app/assets/javascripts/components/widget-wrapper.js @@ -15,24 +15,24 @@ ManageIQ.angular.app.component('widgetWrapper', { this.$onInit = function() { vm.divId = "w_" + vm.widgetId; vm.innerDivId = 'dd_w' + vm.widgetId + '_box'; - if (vm.widgetBlank == 'false') { + if (vm.widgetBlank === 'false') { $http.get(vm.widgetUrl()) .then(function(response) { vm.widgetModel = response.data; // if there's html make it passable if (vm.widgetModel.content) { vm.widgetModel.content = $sce.trustAsHtml(vm.widgetModel.content); - }; + } }) - .catch(function(){ + .catch(function() { vm.error = true; miqService.handleFailure; }); - }; + } }; vm.widgetUrl = function() { - switch(vm.widgetType){ + switch (vm.widgetType) { case 'menu': return '/dashboard/widget_menu_data/' + vm.widgetId; case 'report': @@ -43,9 +43,8 @@ ManageIQ.angular.app.component('widgetWrapper', { return '/dashboard/widget_rss_data/' + vm.widgetId; default: console.log('Something went wrong. There is no support for widget type of ', vm.widgetType); - }; + } }; - }], template: [ '
', @@ -59,37 +58,10 @@ ManageIQ.angular.app.component('widgetWrapper', { ' ', '
', '
', - '
', - '
', - '
', - ' ', - '
', - '

', - __('There was an error during '), - '

', - '
', - '
', - '
', - '
', - '
', - ' ', - '
', - '
', - '
', + ' ', + ' ', '
', - '
', - '
', - '
', - ' ', - '
', - '

', - __('No data found.'), - '

', - '

', - __('If this widget is new or has just been added to your dashboard, the data is being generated and should be available soon.'), - '

', - '
', - '
', + ' ', '
', ' ', ' ', @@ -100,13 +72,7 @@ ManageIQ.angular.app.component('widgetWrapper', { ' ', ' ', '
', - ' ', + ' ', '
', '
', '
', From 95d2657f57ac121b586951e03dd16ed527da757e Mon Sep 17 00:00:00 2001 From: Zita Nemeckova Date: Wed, 14 Feb 2018 15:43:20 +0100 Subject: [PATCH 06/14] Minor fixes and specs --- .../javascripts/components/widget-rss.js | 20 ++++---- .../javascripts/components/widget-wrapper.js | 15 ++++-- app/views/dashboard/_widget.html.haml | 6 +-- .../dashboards/widget-empty_spec.js | 27 +++++++++++ .../dashboards/widget-wrapper_spec.js | 48 +++++++++++++++++++ 5 files changed, 98 insertions(+), 18 deletions(-) create mode 100644 spec/javascripts/components/dashboards/widget-empty_spec.js create mode 100644 spec/javascripts/components/dashboards/widget-wrapper_spec.js diff --git a/app/assets/javascripts/components/widget-rss.js b/app/assets/javascripts/components/widget-rss.js index a96c9aa73fb..cd6dd6e3acb 100644 --- a/app/assets/javascripts/components/widget-rss.js +++ b/app/assets/javascripts/components/widget-rss.js @@ -11,18 +11,18 @@ ManageIQ.angular.app.component('widgetRss', { }; }, template: [ - '
', - '
', - ' ', - ' ', - '

', + '
', + '
', + ' ', + ' ', + '

', __('No RSS Feed data found'), - '

', - '
', + '

', '
', - '
', - '
', - '
', + '
', + '
', + '
', '
', + '
', ].join("\n"), }); diff --git a/app/assets/javascripts/components/widget-wrapper.js b/app/assets/javascripts/components/widget-wrapper.js index 52a472c4a3a..b2ff9fc1828 100644 --- a/app/assets/javascripts/components/widget-wrapper.js +++ b/app/assets/javascripts/components/widget-wrapper.js @@ -12,6 +12,9 @@ ManageIQ.angular.app.component('widgetWrapper', { controller: ['$http', 'miqService', '$sce', function($http, miqService, $sce) { var vm = this; + var deferred = miqDeferred(); + vm.promise = deferred.promise; + this.$onInit = function() { vm.divId = "w_" + vm.widgetId; vm.innerDivId = 'dd_w' + vm.widgetId + '_box'; @@ -23,10 +26,12 @@ ManageIQ.angular.app.component('widgetWrapper', { if (vm.widgetModel.content) { vm.widgetModel.content = $sce.trustAsHtml(vm.widgetModel.content); } + deferred.resolve(); }) - .catch(function() { + .catch(function(e) { vm.error = true; - miqService.handleFailure; + miqService.handleFailure(e); + deferred.reject(); }); } }; @@ -47,7 +52,7 @@ ManageIQ.angular.app.component('widgetWrapper', { }; }], template: [ - '
', + '
', '
', '
', '
', @@ -58,8 +63,8 @@ ManageIQ.angular.app.component('widgetWrapper', { ' ', '
', '
', - ' ', - ' ', + ' ', + ' ', '
', ' ', '
', diff --git a/app/views/dashboard/_widget.html.haml b/app/views/dashboard/_widget.html.haml index 62c092694e0..486bac58d9d 100644 --- a/app/views/dashboard/_widget.html.haml +++ b/app/views/dashboard/_widget.html.haml @@ -1,14 +1,14 @@ -%div{:id => "ww_#{presenter.widget.id}"} +%div{:id => "w_#{presenter.widget.id}"} - last_run_on = presenter.widget.last_run_on_for_user(current_user) - next_run_on = presenter.widget.next_run_on - widget_blank = presenter.widget.content_type == 'menu' ? false : presenter.widget.contents_for_user(current_user).blank? %widget-wrapper{"widget-id" => presenter.widget.id, "widget-type" => presenter.widget.content_type, "widget-buttons" => presenter.widget_buttons, - "widget_blank" => widget_blank, + "widget-blank" => widget_blank, "widget-last-run" => last_run_on ? format_timezone(last_run_on, session[:user_tz], "widget_footer") : _('Never'), "widget-next-run" => next_run_on ? format_timezone(next_run_on, session[:user_tz], "widget_footer") : _('Unknown'), "widget-title" => presenter.widget.title} :javascript - miq_bootstrap("#ww_#{presenter.widget.id}"); + miq_bootstrap("#w_#{presenter.widget.id}"); diff --git a/spec/javascripts/components/dashboards/widget-empty_spec.js b/spec/javascripts/components/dashboards/widget-empty_spec.js new file mode 100644 index 00000000000..763aacf76d9 --- /dev/null +++ b/spec/javascripts/components/dashboards/widget-empty_spec.js @@ -0,0 +1,27 @@ +describe('widget-empty', function() { + var $scope, element, $compile; + beforeEach(module('ManageIQ')); + beforeEach(inject(function(_$compile_, $rootScope, $templateCache) { + // FIXME: templateRequest is using $http to get the template, but angular-mocks prevents it + $templateCache.put('/static/dropdown-menu.html.haml', '
'); + $scope = $rootScope; + $scope.miqButtonClicked = function(){}; + $scope.validForm = true; + $compile = _$compile_; + })); + it('is rendered in widget-wrapper if widget-blank is set to true', function(done) { + element = angular.element( + '
' + + '' + + '
' + ); + element = $compile(element)($scope); + $scope.$digest(); + setTimeout(function(){ + var widget = element.find("widget-empty"); + expect(widget.length).not.toBe(0); + done(); + }); + }); +} +); diff --git a/spec/javascripts/components/dashboards/widget-wrapper_spec.js b/spec/javascripts/components/dashboards/widget-wrapper_spec.js new file mode 100644 index 00000000000..d40d784e634 --- /dev/null +++ b/spec/javascripts/components/dashboards/widget-wrapper_spec.js @@ -0,0 +1,48 @@ +describe('widget-wrapper', function() { + var $scope, element, $compile; + var widgetTypes = ['chart', 'menu', 'report', 'rss']; + + beforeEach(module('ManageIQ')); + + beforeEach(inject(function(_$compile_, $rootScope, $templateCache, $http) { + // FIXME: templateRequest is using $http to get the template, but angular-mocks prevents it + $templateCache.put('/static/dropdown-menu.html.haml', '
'); + + $scope = $rootScope; + + $compile = _$compile_; + spyOn($http, 'get').and.callFake(function(){ + return Promise.resolve({ + data: { + content: "
", + minimized: false, + shortcuts: [], + }, + status: 200, + statusText: 'OK', + }); + }); + })); + + widgetTypes.forEach(function (widget) { + it('renders widget-' + widget + ' when widget-type is ' + widget, function(done) { + debugger; + element = angular.element( + '
' + + ' ' + + '
' + ); + element = $compile(element)($scope); + $scope.$digest(); + + var $ctrl = element.find('widget-wrapper > div').scope().vm; + $ctrl.promise.catch(function () {}).then(function(){ + $scope.$digest(); + + var widgetElement = element.find("widget-" + widget); + expect(widgetElement.length).toBe(1); + done(); + }); + }); + }); +}); From c661b8af761c4f4dd62aa100db3d6460a8f2cd68 Mon Sep 17 00:00:00 2001 From: Zita Nemeckova Date: Thu, 15 Feb 2018 13:02:14 +0100 Subject: [PATCH 07/14] Specs --- .../spec/dashboards/widget-empty.test.js | 35 +++++++++++++++++++ .../spec/dashboards/widget-wrapper.test.js | 0 .../dashboards/widget-empty_spec.js | 27 -------------- 3 files changed, 35 insertions(+), 27 deletions(-) create mode 100644 app/javascript/spec/dashboards/widget-empty.test.js rename spec/javascripts/components/dashboards/widget-wrapper_spec.js => app/javascript/spec/dashboards/widget-wrapper.test.js (100%) delete mode 100644 spec/javascripts/components/dashboards/widget-empty_spec.js diff --git a/app/javascript/spec/dashboards/widget-empty.test.js b/app/javascript/spec/dashboards/widget-empty.test.js new file mode 100644 index 00000000000..50b170582c9 --- /dev/null +++ b/app/javascript/spec/dashboards/widget-empty.test.js @@ -0,0 +1,35 @@ +import * as angular from 'angular'; +import 'angular-mocks'; + +describe('widget-empty', function() { + var $scope, element, $compile; + console.log(angular.mock); + + beforeEach(() => { + angular.mock.module('ManageIQ'); + }); + + beforeEach(angular.mock.inject(function(_$compile_, $rootScope, $templateCache) { + // FIXME: templateRequest is using $http to get the template, but angular-mocks prevents it + $templateCache.put('/static/dropdown-menu.html.haml', '
'); + $scope = $rootScope; + $scope.miqButtonClicked = function(){}; + $scope.validForm = true; + $compile = _$compile_; + })); + it('is rendered in widget-wrapper if widget-blank is set to true', function(done) { + element = angular.element( + '
' + + '' + + '
' + ); + element = $compile(element)($scope); + $scope.$digest(); + setTimeout(function(){ + var widget = element.find("widget-empty"); + expect(widget.length).not.toBe(0); + done(); + }); + }); +} +); diff --git a/spec/javascripts/components/dashboards/widget-wrapper_spec.js b/app/javascript/spec/dashboards/widget-wrapper.test.js similarity index 100% rename from spec/javascripts/components/dashboards/widget-wrapper_spec.js rename to app/javascript/spec/dashboards/widget-wrapper.test.js diff --git a/spec/javascripts/components/dashboards/widget-empty_spec.js b/spec/javascripts/components/dashboards/widget-empty_spec.js deleted file mode 100644 index 763aacf76d9..00000000000 --- a/spec/javascripts/components/dashboards/widget-empty_spec.js +++ /dev/null @@ -1,27 +0,0 @@ -describe('widget-empty', function() { - var $scope, element, $compile; - beforeEach(module('ManageIQ')); - beforeEach(inject(function(_$compile_, $rootScope, $templateCache) { - // FIXME: templateRequest is using $http to get the template, but angular-mocks prevents it - $templateCache.put('/static/dropdown-menu.html.haml', '
'); - $scope = $rootScope; - $scope.miqButtonClicked = function(){}; - $scope.validForm = true; - $compile = _$compile_; - })); - it('is rendered in widget-wrapper if widget-blank is set to true', function(done) { - element = angular.element( - '
' + - '' + - '
' - ); - element = $compile(element)($scope); - $scope.$digest(); - setTimeout(function(){ - var widget = element.find("widget-empty"); - expect(widget.length).not.toBe(0); - done(); - }); - }); -} -); From fe2ef47e10be183326c6e51be3f4fa46b5d962a0 Mon Sep 17 00:00:00 2001 From: Martin Hradil Date: Thu, 15 Feb 2018 12:42:04 +0000 Subject: [PATCH 08/14] Widget-* specs - make them work in jest :) just needed to include/mock all the dependencies and not use jquery selectors --- .../spec/dashboards/widget-empty.test.js | 51 ++++++++++--- .../spec/dashboards/widget-wrapper.test.js | 71 +++++++++++++++---- 2 files changed, 101 insertions(+), 21 deletions(-) diff --git a/app/javascript/spec/dashboards/widget-empty.test.js b/app/javascript/spec/dashboards/widget-empty.test.js index 50b170582c9..aa786326f47 100644 --- a/app/javascript/spec/dashboards/widget-empty.test.js +++ b/app/javascript/spec/dashboards/widget-empty.test.js @@ -1,21 +1,54 @@ -import * as angular from 'angular'; -import 'angular-mocks'; +require('angular'); +require('angular-mocks'); +const module = window.module; +const inject = window.inject; -describe('widget-empty', function() { - var $scope, element, $compile; - console.log(angular.mock); +window.ManageIQ = { + angular: { + app: angular.module('ManageIQ', []), + }, +}; +window.__ = (x) => x; - beforeEach(() => { - angular.mock.module('ManageIQ'); - }); +// FIXME: app/assets/javascripts/services/ +ManageIQ.angular.app.service('miqService', function() { + this.handleFailure = () => null; +}); + +// FIXME: miq_application.js +window.miqDeferred = () => { + var deferred = {}; + + deferred.promise = new Promise(function(resolve, reject) { + deferred.resolve = resolve; + deferred.reject = reject; + }); - beforeEach(angular.mock.inject(function(_$compile_, $rootScope, $templateCache) { + return deferred; +}; + +require('../../../assets/javascripts/components/widget-chart'); +require('../../../assets/javascripts/components/widget-empty'); +require('../../../assets/javascripts/components/widget-error'); +require('../../../assets/javascripts/components/widget-footer'); +require('../../../assets/javascripts/components/widget-menu'); +require('../../../assets/javascripts/components/widget-report'); +require('../../../assets/javascripts/components/widget-rss'); +require('../../../assets/javascripts/components/widget-spinner'); +require('../../../assets/javascripts/components/widget-wrapper'); + + +describe('widget-empty', function() { + var $scope, element, $compile; + beforeEach(module('ManageIQ')); + beforeEach(inject(function(_$compile_, $rootScope, $templateCache) { // FIXME: templateRequest is using $http to get the template, but angular-mocks prevents it $templateCache.put('/static/dropdown-menu.html.haml', '
'); $scope = $rootScope; $scope.miqButtonClicked = function(){}; $scope.validForm = true; $compile = _$compile_; + })); it('is rendered in widget-wrapper if widget-blank is set to true', function(done) { element = angular.element( diff --git a/app/javascript/spec/dashboards/widget-wrapper.test.js b/app/javascript/spec/dashboards/widget-wrapper.test.js index d40d784e634..5ebc4d1ddf0 100644 --- a/app/javascript/spec/dashboards/widget-wrapper.test.js +++ b/app/javascript/spec/dashboards/widget-wrapper.test.js @@ -1,3 +1,43 @@ +require('angular'); +require('angular-mocks'); +const module = window.module; +const inject = window.inject; + +window.ManageIQ = { + angular: { + app: angular.module('ManageIQ', []), + }, +}; +window.__ = (x) => x; + +// FIXME: app/assets/javascripts/services/ +ManageIQ.angular.app.service('miqService', function() { + this.handleFailure = () => null; +}); + +// FIXME: miq_application.js +window.miqDeferred = () => { + var deferred = {}; + + deferred.promise = new Promise(function(resolve, reject) { + deferred.resolve = resolve; + deferred.reject = reject; + }); + + return deferred; +}; + +require('../../../assets/javascripts/components/widget-chart'); +require('../../../assets/javascripts/components/widget-empty'); +require('../../../assets/javascripts/components/widget-error'); +require('../../../assets/javascripts/components/widget-footer'); +require('../../../assets/javascripts/components/widget-menu'); +require('../../../assets/javascripts/components/widget-report'); +require('../../../assets/javascripts/components/widget-rss'); +require('../../../assets/javascripts/components/widget-spinner'); +require('../../../assets/javascripts/components/widget-wrapper'); + + describe('widget-wrapper', function() { var $scope, element, $compile; var widgetTypes = ['chart', 'menu', 'report', 'rss']; @@ -11,22 +51,29 @@ describe('widget-wrapper', function() { $scope = $rootScope; $compile = _$compile_; - spyOn($http, 'get').and.callFake(function(){ - return Promise.resolve({ - data: { - content: "
", - minimized: false, - shortcuts: [], - }, - status: 200, - statusText: 'OK', - }); + spyOn($http, 'get').and.callFake(function(url) { + if (url === '/static/dropdown-menu.html.haml') { + return Promise.resolve({ + data: "
", + status: 200, + statusText: 'OK', + }); + } else { + return Promise.resolve({ + data: { + content: "
", + minimized: false, + shortcuts: [], + }, + status: 200, + statusText: 'OK', + }); + } }); })); widgetTypes.forEach(function (widget) { it('renders widget-' + widget + ' when widget-type is ' + widget, function(done) { - debugger; element = angular.element( '
' + ' ' + @@ -35,7 +82,7 @@ describe('widget-wrapper', function() { element = $compile(element)($scope); $scope.$digest(); - var $ctrl = element.find('widget-wrapper > div').scope().vm; + var $ctrl = element.find('widget-wrapper').find('div').scope().vm; $ctrl.promise.catch(function () {}).then(function(){ $scope.$digest(); From 1c0af0e374860a1b7012e95ec789314d50407702 Mon Sep 17 00:00:00 2001 From: Martin Hradil Date: Thu, 15 Feb 2018 12:45:36 +0000 Subject: [PATCH 09/14] minor fixes --- app/javascript/spec/dashboards/widget-empty.test.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/javascript/spec/dashboards/widget-empty.test.js b/app/javascript/spec/dashboards/widget-empty.test.js index aa786326f47..589b6133306 100644 --- a/app/javascript/spec/dashboards/widget-empty.test.js +++ b/app/javascript/spec/dashboards/widget-empty.test.js @@ -40,16 +40,17 @@ require('../../../assets/javascripts/components/widget-wrapper'); describe('widget-empty', function() { var $scope, element, $compile; + beforeEach(module('ManageIQ')); beforeEach(inject(function(_$compile_, $rootScope, $templateCache) { // FIXME: templateRequest is using $http to get the template, but angular-mocks prevents it $templateCache.put('/static/dropdown-menu.html.haml', '
'); $scope = $rootScope; - $scope.miqButtonClicked = function(){}; + $scope.miqButtonClicked = function() {}; $scope.validForm = true; $compile = _$compile_; - })); + it('is rendered in widget-wrapper if widget-blank is set to true', function(done) { element = angular.element( '' + @@ -57,10 +58,13 @@ describe('widget-empty', function() { '' ); element = $compile(element)($scope); + $scope.$digest(); - setTimeout(function(){ + + setTimeout(function() { var widget = element.find("widget-empty"); - expect(widget.length).not.toBe(0); + expect(widget.length).toBe(1); + done(); }); }); From e4540c0b655e74f0d378a20a7a070a3075c9f481 Mon Sep 17 00:00:00 2001 From: Martin Hradil Date: Thu, 15 Feb 2018 13:04:04 +0000 Subject: [PATCH 10/14] dashboard specs - common mocks and includes to a shared file --- app/javascript/spec/dashboards/mocks.js | 40 +++++++++++++++++++ .../spec/dashboards/widget-empty.test.js | 40 +------------------ .../spec/dashboards/widget-wrapper.test.js | 40 +------------------ 3 files changed, 42 insertions(+), 78 deletions(-) create mode 100644 app/javascript/spec/dashboards/mocks.js diff --git a/app/javascript/spec/dashboards/mocks.js b/app/javascript/spec/dashboards/mocks.js new file mode 100644 index 00000000000..0300a71e278 --- /dev/null +++ b/app/javascript/spec/dashboards/mocks.js @@ -0,0 +1,40 @@ +require('angular'); +require('angular-mocks'); +const module = window.module; +const inject = window.inject; + +window.ManageIQ = { + angular: { + app: angular.module('ManageIQ', []), + }, +}; +window.__ = (x) => x; + +// FIXME: app/assets/javascripts/services/ +ManageIQ.angular.app.service('miqService', function() { + this.handleFailure = () => null; +}); + +// FIXME: miq_application.js +window.miqDeferred = () => { + var deferred = {}; + + deferred.promise = new Promise(function(resolve, reject) { + deferred.resolve = resolve; + deferred.reject = reject; + }); + + return deferred; +}; + +require('../../../assets/javascripts/components/widget-chart'); +require('../../../assets/javascripts/components/widget-empty'); +require('../../../assets/javascripts/components/widget-error'); +require('../../../assets/javascripts/components/widget-footer'); +require('../../../assets/javascripts/components/widget-menu'); +require('../../../assets/javascripts/components/widget-report'); +require('../../../assets/javascripts/components/widget-rss'); +require('../../../assets/javascripts/components/widget-spinner'); +require('../../../assets/javascripts/components/widget-wrapper'); + +export { module, inject }; diff --git a/app/javascript/spec/dashboards/widget-empty.test.js b/app/javascript/spec/dashboards/widget-empty.test.js index 589b6133306..c6daad7fbaa 100644 --- a/app/javascript/spec/dashboards/widget-empty.test.js +++ b/app/javascript/spec/dashboards/widget-empty.test.js @@ -1,42 +1,4 @@ -require('angular'); -require('angular-mocks'); -const module = window.module; -const inject = window.inject; - -window.ManageIQ = { - angular: { - app: angular.module('ManageIQ', []), - }, -}; -window.__ = (x) => x; - -// FIXME: app/assets/javascripts/services/ -ManageIQ.angular.app.service('miqService', function() { - this.handleFailure = () => null; -}); - -// FIXME: miq_application.js -window.miqDeferred = () => { - var deferred = {}; - - deferred.promise = new Promise(function(resolve, reject) { - deferred.resolve = resolve; - deferred.reject = reject; - }); - - return deferred; -}; - -require('../../../assets/javascripts/components/widget-chart'); -require('../../../assets/javascripts/components/widget-empty'); -require('../../../assets/javascripts/components/widget-error'); -require('../../../assets/javascripts/components/widget-footer'); -require('../../../assets/javascripts/components/widget-menu'); -require('../../../assets/javascripts/components/widget-report'); -require('../../../assets/javascripts/components/widget-rss'); -require('../../../assets/javascripts/components/widget-spinner'); -require('../../../assets/javascripts/components/widget-wrapper'); - +import { module, inject } from './mocks'; describe('widget-empty', function() { var $scope, element, $compile; diff --git a/app/javascript/spec/dashboards/widget-wrapper.test.js b/app/javascript/spec/dashboards/widget-wrapper.test.js index 5ebc4d1ddf0..c428231734d 100644 --- a/app/javascript/spec/dashboards/widget-wrapper.test.js +++ b/app/javascript/spec/dashboards/widget-wrapper.test.js @@ -1,42 +1,4 @@ -require('angular'); -require('angular-mocks'); -const module = window.module; -const inject = window.inject; - -window.ManageIQ = { - angular: { - app: angular.module('ManageIQ', []), - }, -}; -window.__ = (x) => x; - -// FIXME: app/assets/javascripts/services/ -ManageIQ.angular.app.service('miqService', function() { - this.handleFailure = () => null; -}); - -// FIXME: miq_application.js -window.miqDeferred = () => { - var deferred = {}; - - deferred.promise = new Promise(function(resolve, reject) { - deferred.resolve = resolve; - deferred.reject = reject; - }); - - return deferred; -}; - -require('../../../assets/javascripts/components/widget-chart'); -require('../../../assets/javascripts/components/widget-empty'); -require('../../../assets/javascripts/components/widget-error'); -require('../../../assets/javascripts/components/widget-footer'); -require('../../../assets/javascripts/components/widget-menu'); -require('../../../assets/javascripts/components/widget-report'); -require('../../../assets/javascripts/components/widget-rss'); -require('../../../assets/javascripts/components/widget-spinner'); -require('../../../assets/javascripts/components/widget-wrapper'); - +import { module, inject } from './mocks'; describe('widget-wrapper', function() { var $scope, element, $compile; From 42aac7f01a343d62a2ac71792f8d8a1458195fac Mon Sep 17 00:00:00 2001 From: Zita Nemeckova Date: Mon, 19 Feb 2018 12:51:45 +0100 Subject: [PATCH 11/14] Fixes linter errors --- app/javascript/spec/dashboards/mocks.js | 4 ++-- .../spec/dashboards/widget-empty.test.js | 16 ++++++++------- .../spec/dashboards/widget-wrapper.test.js | 20 ++++++++++--------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/app/javascript/spec/dashboards/mocks.js b/app/javascript/spec/dashboards/mocks.js index 0300a71e278..83e5a3e0ac8 100644 --- a/app/javascript/spec/dashboards/mocks.js +++ b/app/javascript/spec/dashboards/mocks.js @@ -11,7 +11,7 @@ window.ManageIQ = { window.__ = (x) => x; // FIXME: app/assets/javascripts/services/ -ManageIQ.angular.app.service('miqService', function() { +ManageIQ.angular.app.service('miqService', function () { this.handleFailure = () => null; }); @@ -19,7 +19,7 @@ ManageIQ.angular.app.service('miqService', function() { window.miqDeferred = () => { var deferred = {}; - deferred.promise = new Promise(function(resolve, reject) { + deferred.promise = new Promise(function (resolve, reject) { deferred.resolve = resolve; deferred.reject = reject; }); diff --git a/app/javascript/spec/dashboards/widget-empty.test.js b/app/javascript/spec/dashboards/widget-empty.test.js index c6daad7fbaa..ef0e372e670 100644 --- a/app/javascript/spec/dashboards/widget-empty.test.js +++ b/app/javascript/spec/dashboards/widget-empty.test.js @@ -1,19 +1,21 @@ import { module, inject } from './mocks'; -describe('widget-empty', function() { - var $scope, element, $compile; +describe('widget-empty', function () { + let $scope; + let element; + let $compile; beforeEach(module('ManageIQ')); - beforeEach(inject(function(_$compile_, $rootScope, $templateCache) { + beforeEach(inject(function (_$compile_, $rootScope, $templateCache) { // FIXME: templateRequest is using $http to get the template, but angular-mocks prevents it $templateCache.put('/static/dropdown-menu.html.haml', '
'); $scope = $rootScope; - $scope.miqButtonClicked = function() {}; + $scope.miqButtonClicked = function () {}; $scope.validForm = true; $compile = _$compile_; })); - it('is rendered in widget-wrapper if widget-blank is set to true', function(done) { + it('is rendered in widget-wrapper if widget-blank is set to true', function (done) { element = angular.element( '
' + '' + @@ -23,8 +25,8 @@ describe('widget-empty', function() { $scope.$digest(); - setTimeout(function() { - var widget = element.find("widget-empty"); + setTimeout(function () { + const widget = element.find("widget-empty"); expect(widget.length).toBe(1); done(); diff --git a/app/javascript/spec/dashboards/widget-wrapper.test.js b/app/javascript/spec/dashboards/widget-wrapper.test.js index c428231734d..86982f24940 100644 --- a/app/javascript/spec/dashboards/widget-wrapper.test.js +++ b/app/javascript/spec/dashboards/widget-wrapper.test.js @@ -1,19 +1,21 @@ import { module, inject } from './mocks'; -describe('widget-wrapper', function() { - var $scope, element, $compile; - var widgetTypes = ['chart', 'menu', 'report', 'rss']; +describe('widget-wrapper', function () { + let $scope; + let element; + let $compile; + const widgetTypes = ['chart', 'menu', 'report', 'rss']; beforeEach(module('ManageIQ')); - beforeEach(inject(function(_$compile_, $rootScope, $templateCache, $http) { + beforeEach(inject(function (_$compile_, $rootScope, $templateCache, $http) { // FIXME: templateRequest is using $http to get the template, but angular-mocks prevents it $templateCache.put('/static/dropdown-menu.html.haml', '
'); $scope = $rootScope; $compile = _$compile_; - spyOn($http, 'get').and.callFake(function(url) { + spyOn($http, 'get').and.callFake(function (url) { if (url === '/static/dropdown-menu.html.haml') { return Promise.resolve({ data: "
", @@ -35,7 +37,7 @@ describe('widget-wrapper', function() { })); widgetTypes.forEach(function (widget) { - it('renders widget-' + widget + ' when widget-type is ' + widget, function(done) { + it(`renders widget-${widget} when widget-type is ${widget}`, function (done) { element = angular.element( '' + ' ' + @@ -44,11 +46,11 @@ describe('widget-wrapper', function() { element = $compile(element)($scope); $scope.$digest(); - var $ctrl = element.find('widget-wrapper').find('div').scope().vm; - $ctrl.promise.catch(function () {}).then(function(){ + const $ctrl = element.find('widget-wrapper').find('div').scope().vm; + $ctrl.promise.catch(function () {}).then(function () { $scope.$digest(); - var widgetElement = element.find("widget-" + widget); + const widgetElement = element.find("widget-".concat(widget)); expect(widgetElement.length).toBe(1); done(); }); From e3dddf561936efa14471935068f4d9869534fc8d Mon Sep 17 00:00:00 2001 From: Zita Nemeckova Date: Mon, 12 Mar 2018 15:05:47 +0100 Subject: [PATCH 12/14] Fix according to review Use ng-class, ng-attr-, ng-class, ng-href Move urls from switch to object (pretty) --- .../javascripts/components/widget-footer.js | 4 ++-- .../javascripts/components/widget-menu.js | 4 ++-- .../javascripts/components/widget-spinner.js | 2 +- .../javascripts/components/widget-wrapper.js | 24 +++++++++---------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app/assets/javascripts/components/widget-footer.js b/app/assets/javascripts/components/widget-footer.js index de6a8fa965e..f8ee56ae00f 100644 --- a/app/assets/javascripts/components/widget-footer.js +++ b/app/assets/javascripts/components/widget-footer.js @@ -7,10 +7,10 @@ ManageIQ.angular.app.component('widgetFooter', { template: [ '', ].join("\n"), }); diff --git a/app/assets/javascripts/components/widget-menu.js b/app/assets/javascripts/components/widget-menu.js index 090d8669f8c..d2a466b7cf8 100644 --- a/app/assets/javascripts/components/widget-menu.js +++ b/app/assets/javascripts/components/widget-menu.js @@ -17,9 +17,9 @@ ManageIQ.angular.app.component('widgetMenu', { '
', __('No shortcuts are authorized for this user, contact your Administrator'), '
', - ' ', + ' ', ' ', - ' ', + ' ', '{{shortcut.description}}', ' ', ' ', diff --git a/app/assets/javascripts/components/widget-spinner.js b/app/assets/javascripts/components/widget-spinner.js index 9ba8a04ed46..f21cd7d228f 100644 --- a/app/assets/javascripts/components/widget-spinner.js +++ b/app/assets/javascripts/components/widget-spinner.js @@ -2,7 +2,7 @@ ManageIQ.angular.app.component('widgetSpinner', { template: [ '
', '
', - ' ', + ' ', '
', '
', ].join("\n"), diff --git a/app/assets/javascripts/components/widget-wrapper.js b/app/assets/javascripts/components/widget-wrapper.js index b2ff9fc1828..322406f10b0 100644 --- a/app/assets/javascripts/components/widget-wrapper.js +++ b/app/assets/javascripts/components/widget-wrapper.js @@ -12,6 +12,13 @@ ManageIQ.angular.app.component('widgetWrapper', { controller: ['$http', 'miqService', '$sce', function($http, miqService, $sce) { var vm = this; + var widgetTypeUrl = { + menu: '/dashboard/widget_menu_data/', + report: '/dashboard/widget_report_data/', + chart: '/dashboard/widget_chart_data/', + rss: '/dashboard/widget_rss_data/', + }; + var deferred = miqDeferred(); vm.promise = deferred.promise; @@ -37,17 +44,10 @@ ManageIQ.angular.app.component('widgetWrapper', { }; vm.widgetUrl = function() { - switch (vm.widgetType) { - case 'menu': - return '/dashboard/widget_menu_data/' + vm.widgetId; - case 'report': - return '/dashboard/widget_report_data/' + vm.widgetId; - case 'chart': - return '/dashboard/widget_chart_data/' + vm.widgetId; - case 'rss': - return '/dashboard/widget_rss_data/' + vm.widgetId; - default: - console.log('Something went wrong. There is no support for widget type of ', vm.widgetType); + if (widgetTypeUrl.hasOwnProperty(vm.widgetType)) { + return [widgetTypeUrl[vm.widgetType], vm.widgetId].join('/'); + } else { + console.log('Something went wrong. There is no support for widget type of ', vm.widgetType); } }; }], @@ -65,7 +65,7 @@ ManageIQ.angular.app.component('widgetWrapper', { '
', ' ', ' ', - '
', + '
', ' ', '
', ' ', From 67cd442286b4384e607934883f892fa3e2a402bf Mon Sep 17 00:00:00 2001 From: Zita Nemeckova Date: Wed, 14 Mar 2018 11:16:57 +0100 Subject: [PATCH 13/14] Fix failing jest spec Mock missing setupVerticalNavigation function from PatternFly --- app/javascript/spec/dashboards/mocks.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/javascript/spec/dashboards/mocks.js b/app/javascript/spec/dashboards/mocks.js index 83e5a3e0ac8..33a0f26d328 100644 --- a/app/javascript/spec/dashboards/mocks.js +++ b/app/javascript/spec/dashboards/mocks.js @@ -27,6 +27,9 @@ window.miqDeferred = () => { return deferred; }; +// FIXME: don't mock PF functions +$.fn.setupVerticalNavigation = function() {}; + require('../../../assets/javascripts/components/widget-chart'); require('../../../assets/javascripts/components/widget-empty'); require('../../../assets/javascripts/components/widget-error'); From 0c949183f3f9a3eb59e59f5da3c22b87e1f1cbaf Mon Sep 17 00:00:00 2001 From: Zita Nemeckova Date: Thu, 12 Apr 2018 16:41:29 +0200 Subject: [PATCH 14/14] Fix widget_footer Replace one partial call with widget-footer component, move lightbox-panel on same level as notification-app, move last_run and next_run to helper(no duplication of code) and fix same id warnings --- app/helpers/dashboard_helper.rb | 8 ++++++++ app/views/dashboard/_widget.html.haml | 11 +++++------ app/views/dashboard/_zoomed_chart.html.haml | 5 ++++- app/views/layouts/_header.html.haml | 5 ++--- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb index 149f145ccc9..7fb04ae3373 100644 --- a/app/helpers/dashboard_helper.rb +++ b/app/helpers/dashboard_helper.rb @@ -3,4 +3,12 @@ def ext_auth?(auth_option = nil) return false unless ::Settings.authentication.mode == 'httpd' auth_option ? ::Settings.authentication[auth_option] : true end + + def last_next_run(widget) + last_run_on = widget.last_run_on_for_user(current_user) + next_run_on = widget.next_run_on + last_run = last_run_on ? format_timezone(last_run_on, session[:user_tz], "widget_footer") : _('Never') + next_run = next_run_on ? format_timezone(next_run_on, session[:user_tz], "widget_footer") : _('Unknown') + [last_run, next_run] + end end diff --git a/app/views/dashboard/_widget.html.haml b/app/views/dashboard/_widget.html.haml index 486bac58d9d..0921e5d80ac 100644 --- a/app/views/dashboard/_widget.html.haml +++ b/app/views/dashboard/_widget.html.haml @@ -1,14 +1,13 @@ -%div{:id => "w_#{presenter.widget.id}"} - - last_run_on = presenter.widget.last_run_on_for_user(current_user) - - next_run_on = presenter.widget.next_run_on +%div{:id => "ww_#{presenter.widget.id}"} + - last_run, next_run = last_next_run(presenter.widget) - widget_blank = presenter.widget.content_type == 'menu' ? false : presenter.widget.contents_for_user(current_user).blank? %widget-wrapper{"widget-id" => presenter.widget.id, "widget-type" => presenter.widget.content_type, "widget-buttons" => presenter.widget_buttons, "widget-blank" => widget_blank, - "widget-last-run" => last_run_on ? format_timezone(last_run_on, session[:user_tz], "widget_footer") : _('Never'), - "widget-next-run" => next_run_on ? format_timezone(next_run_on, session[:user_tz], "widget_footer") : _('Unknown'), + "widget-last-run" => last_run, + "widget-next-run" => next_run, "widget-title" => presenter.widget.title} :javascript - miq_bootstrap("#w_#{presenter.widget.id}"); + miq_bootstrap("#ww_#{presenter.widget.id}"); diff --git a/app/views/dashboard/_zoomed_chart.html.haml b/app/views/dashboard/_zoomed_chart.html.haml index 7c3c657e8f7..ea4e8a92df2 100644 --- a/app/views/dashboard/_zoomed_chart.html.haml +++ b/app/views/dashboard/_zoomed_chart.html.haml @@ -1,6 +1,7 @@ -# Parameters: widget -- MiqWidget object +- last_run, next_run = last_next_run(widget) #zoomed_chart_div .card-pf .card-pf-heading @@ -11,4 +12,6 @@ %i.fa.fa-close.pull-right .card-pf-body = chart_remote('dashboard', :id => 'my_chart', :zoomed => true) - = render :partial => 'widget_footer', :locals => {:widget => widget} + %widget-footer{:id => "zoomed_chart_footer_#{widget.id}", 'widget-last-run' => last_run, 'widget-next-run' => next_run} +:javascript + miq_bootstrap("#zoomed_chart_footer_#{widget.id}"); diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index ac4878edc09..c89ff7de2b8 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -31,12 +31,11 @@ = _(menu_item.name) = render :partial => "layouts/user_options" - - = render :partial => "layouts/spinner" - = render :partial => "layouts/lightbox_panel" = render :partial => "layouts/notifications_drawer" = render :partial => "layouts/toast_list" += render :partial => "layouts/spinner" += render :partial => "layouts/lightbox_panel" :javascript miq_bootstrap('#notification-app', 'miq.notifications');