diff --git a/app/assets/javascripts/controllers/tree_view_controller.js b/app/assets/javascripts/controllers/tree_view_controller.js index 72fe4a1a7a6..5986dc792cc 100644 --- a/app/assets/javascripts/controllers/tree_view_controller.js +++ b/app/assets/javascripts/controllers/tree_view_controller.js @@ -2,34 +2,49 @@ (function() { var CONTROLLER_NAME = 'treeViewController'; - var TreeViewController = function($http) { + var TreeViewController = function($http, $scope) { var vm = this; vm.$http = $http; + vm.$scope = $scope; vm.selectedNodes = {}; - }; + vm.data = {}; - TreeViewController.prototype.initSelected = function(tree, node) { - this.selectedNodes[tree] = this.selectedNodes[tree] || { key: node }; - }; + ManageIQ.angular.rxSubject.subscribe(function(payload) { + if (payload.reloadTrees && _.isObject(payload.reloadTrees) && Object.keys(payload.reloadTrees).length > 0) { + _.forEach(payload.reloadTrees, function(value, key) { + vm.data[key] = value; + }); + vm.$scope.$apply(); + } + }); - TreeViewController.prototype.lazyLoad = function(node, name, url) { - var vm = this; - return new Promise(function(resolve) { - vm.$http.post(url, { - id: node.key, - tree: name, - mode: 'all', - }).then(function(response) { - resolve(response.data); + vm.initSelected = function(tree, node) { + vm.selectedNodes[tree] = vm.selectedNodes[tree] || { key: node }; + }; + + vm.initData = function(tree, data, selected) { + vm.data[tree] = vm.data[tree] || data; + vm.selectedNodes[tree] = vm.selectedNodes[tree] || { key: selected }; + }; + + vm.lazyLoad = function(node, name, url) { + return new Promise(function(resolve) { + vm.$http.post(url, { + id: node.key, + tree: name, + mode: 'all', + }).then(function(response) { + resolve(response.data); + }); }); - }); - }; + }; - TreeViewController.prototype.nodeSelect = function(node, path) { - var url = path + '?id=' + encodeURIComponent(node.key.split('__')[0]); - miqJqueryRequest(url, {beforeSend: true}); + vm.nodeSelect = function(node, path) { + var url = path + '?id=' + encodeURIComponent(node.key.split('__')[0]); + miqJqueryRequest(url, {beforeSend: true}); + }; }; - TreeViewController.$inject = ['$http']; + TreeViewController.$inject = ['$http', '$scope']; window.miqHttpInject(angular.module('ManageIQ.treeView')).controller(CONTROLLER_NAME, TreeViewController); })(); diff --git a/app/assets/javascripts/miq_explorer.js b/app/assets/javascripts/miq_explorer.js index 10e4b0888ca..3efe390a744 100644 --- a/app/assets/javascripts/miq_explorer.js +++ b/app/assets/javascripts/miq_explorer.js @@ -107,6 +107,12 @@ ManageIQ.explorer.updatePartials = function(data) { } }; +ManageIQ.explorer.reloadTrees = function(data) { + if (_.isObject(data.reloadTrees)) { + sendDataWithRx({reloadTrees: data.reloadTrees}); + } +}; + ManageIQ.explorer.spinnerOff = function(data) { if (data.spinnerOff) { miqSparkle(false); @@ -197,6 +203,8 @@ ManageIQ.explorer.processReplaceRightCell = function(data) { ManageIQ.explorer.replacePartials(data); + ManageIQ.explorer.reloadTrees(data); + if (_.isObject(data.buildCalendar)) { ManageIQ.explorer.buildCalendar(data.buildCalendar); } if (data.initDashboard) { miqInitDashboardCols(); } diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 724a834fadf..4af72c8d1a2 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -2220,20 +2220,10 @@ def controller_for_common_methods end end - def replace_trees_by_presenter(presenter, trees) - trees.each_pair do |name, tree| + def reload_trees_by_presenter(presenter, trees) + trees.each_pair do |_, tree| next unless tree.present? - - presenter.replace( - "#{name}_tree_div", - render_to_string( - :partial => 'shared/tree', - :locals => { - :tree => tree, - :name => tree.name.to_s - } - ) - ) + presenter.reload_tree(tree.name, tree.locals_for_render[:bs_tree]) end end diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb index 248acaab5cf..3cc65d284dd 100644 --- a/app/controllers/catalog_controller.rb +++ b/app/controllers/catalog_controller.rb @@ -1967,7 +1967,7 @@ def replace_right_cell(options = {}) :active_tree => x_active_tree, :add_nodes => add_nodes ) - replace_trees_by_presenter(presenter, trees) + reload_trees_by_presenter(presenter, trees) if @sb[:buttons_node] if action == "group_reorder" diff --git a/app/controllers/chargeback_controller.rb b/app/controllers/chargeback_controller.rb index e645011650c..9284b43b3eb 100644 --- a/app/controllers/chargeback_controller.rb +++ b/app/controllers/chargeback_controller.rb @@ -838,7 +838,7 @@ def replace_right_cell(options = {}) presenter = ExplorerPresenter.new( :active_tree => x_active_tree, ) - replace_trees_by_presenter(presenter, :cb_rates => cb_rates_build_tree) if replace_trees.include?(:cb_rates) + reload_trees_by_presenter(presenter, :cb_rates => cb_rates_build_tree) if replace_trees.include?(:cb_rates) # FIXME # if params[:action].ends_with?("_delete") diff --git a/app/controllers/miq_ae_class_controller.rb b/app/controllers/miq_ae_class_controller.rb index 28c7ac04f10..cc75c3ef509 100644 --- a/app/controllers/miq_ae_class_controller.rb +++ b/app/controllers/miq_ae_class_controller.rb @@ -280,7 +280,7 @@ def replace_right_cell(options = {}) :add_nodes => add_nodes, ) - replace_trees_by_presenter(presenter, :ae => build_ae_tree) unless replace_trees.blank? + reload_trees_by_presenter(presenter, :ae => build_ae_tree) unless replace_trees.blank? if @sb[:action] == "miq_ae_field_seq" presenter.update(:class_fields_div, r[:partial => "fields_seq_form"]) diff --git a/app/controllers/miq_ae_customization_controller.rb b/app/controllers/miq_ae_customization_controller.rb index 60f032f289a..8af32184039 100644 --- a/app/controllers/miq_ae_customization_controller.rb +++ b/app/controllers/miq_ae_customization_controller.rb @@ -248,7 +248,7 @@ def replace_right_cell(options = {}) @explorer = true presenter = ExplorerPresenter.new(:active_tree => x_active_tree) - replace_trees_by_presenter(presenter, trees) + reload_trees_by_presenter(presenter, trees) presenter[:osf_node] = x_node unless @in_a_form if ['dialog_edit', 'dialog_copy'].include?(params[:pressed]) diff --git a/app/controllers/miq_policy_controller.rb b/app/controllers/miq_policy_controller.rb index 1ad2157df3c..f9717df6a81 100644 --- a/app/controllers/miq_policy_controller.rb +++ b/app/controllers/miq_policy_controller.rb @@ -522,7 +522,7 @@ def replace_right_cell(options = {}) raise _("unknown tree in replace_trees: %{name}") % {name => name} end end - replace_trees_by_presenter(presenter, trees) + reload_trees_by_presenter(presenter, trees) if params[:action].ends_with?('_delete') && !x_node.starts_with?('p') && diff --git a/app/controllers/mixins/manager_controller_mixin.rb b/app/controllers/mixins/manager_controller_mixin.rb index 07a789a1e25..9bd8e95129f 100644 --- a/app/controllers/mixins/manager_controller_mixin.rb +++ b/app/controllers/mixins/manager_controller_mixin.rb @@ -310,7 +310,7 @@ def replace_right_cell(options = {}) update_partials(record_showing, presenter) replace_search_box(presenter) handle_bottom_cell(presenter) - replace_trees_by_presenter(presenter, trees) + reload_trees_by_presenter(presenter, trees) rebuild_toolbars(record_showing, presenter) presenter[:right_cell_text] = @right_cell_text presenter[:osf_node] = x_node # Open, select, and focus on this node diff --git a/app/controllers/ops_controller.rb b/app/controllers/ops_controller.rb index 2bb1517dceb..9e406066512 100644 --- a/app/controllers/ops_controller.rb +++ b/app/controllers/ops_controller.rb @@ -774,7 +774,7 @@ def replace_explorer_trees(replace_trees, presenter) trees[:diagnostics] = diagnostics_build_tree if replace_trees.include?(:diagnostics) trees[:vmdb] = db_build_tree if replace_trees.include?(:vmdb) end - replace_trees_by_presenter(presenter, trees) + reload_trees_by_presenter(presenter, trees) end # Build the audit object when a profile is saved diff --git a/app/controllers/pxe_controller.rb b/app/controllers/pxe_controller.rb index 7f977de5aab..5aa2b8d7f48 100644 --- a/app/controllers/pxe_controller.rb +++ b/app/controllers/pxe_controller.rb @@ -117,7 +117,7 @@ def replace_right_cell(options = {}) c_tb = build_toolbar(center_toolbar_filename) unless @in_a_form h_tb = build_toolbar('x_history_tb') - replace_trees_by_presenter(presenter, trees) + reload_trees_by_presenter(presenter, trees) # Rebuild the toolbars presenter.reload_toolbars(:history => h_tb) diff --git a/app/controllers/report_controller.rb b/app/controllers/report_controller.rb index 373a8da8021..a297fa11230 100644 --- a/app/controllers/report_controller.rb +++ b/app/controllers/report_controller.rb @@ -690,7 +690,7 @@ def replace_right_cell(options = {}) # :replace_trees key can be an array of tr v_tb = build_toolbar("report_view_tb") if @report && [:reports_tree, :savedreports_tree].include?(x_active_tree) end - replace_trees_by_presenter(presenter, trees) + reload_trees_by_presenter(presenter, trees) presenter[:osf_node] = x_node # Open, select, and focus on this node session[:changed] = (@edit[:new] != @edit[:current]) if @edit && @edit[:current] # to get save/reset buttons to highlight when something is changed diff --git a/app/controllers/service_controller.rb b/app/controllers/service_controller.rb index f6bfd5126d2..7da1a24ef3f 100644 --- a/app/controllers/service_controller.rb +++ b/app/controllers/service_controller.rb @@ -326,7 +326,7 @@ def replace_right_cell(options = {}) ) if Array(replace_trees).include?(:svcs) - replace_trees_by_presenter(presenter, :svcs => build_svcs_tree) + reload_trees_by_presenter(presenter, :svcs => build_svcs_tree) end # Replace right cell divs diff --git a/app/controllers/storage_controller.rb b/app/controllers/storage_controller.rb index 79ee4672ddb..b6d96423c14 100644 --- a/app/controllers/storage_controller.rb +++ b/app/controllers/storage_controller.rb @@ -396,7 +396,7 @@ def replace_right_cell(options = {}) update_partials(record_showing, presenter) replace_search_box(presenter) handle_bottom_cell(presenter) - replace_trees_by_presenter(presenter, trees) + reload_trees_by_presenter(presenter, trees) rebuild_toolbars(record_showing, presenter) case x_active_tree when :storage_tree diff --git a/app/presenters/explorer_presenter.rb b/app/presenters/explorer_presenter.rb index 24baec668d2..059f648a333 100644 --- a/app/presenters/explorer_presenter.rb +++ b/app/presenters/explorer_presenter.rb @@ -68,6 +68,7 @@ def initialize(options = {}) :element_updates => {}, :replace_partials => {}, :reload_toolbars => {}, + :reload_trees => {}, :exp => {}, :osf_node => '', :show_miq_buttons => false, @@ -141,6 +142,10 @@ def reload_toolbars(toolbars) self end + def reload_tree(name, data) + @options[:reload_trees][name] = data + end + def replace(div_name, content) @options[:replace_partials][div_name] = content self @@ -246,6 +251,7 @@ def for_render_default data[:updatePartials] = @options[:update_partials] # Replace content of given DOM element (element stays). data[:updateElements] = @options[:element_updates] # Update element in the DOM with given options data[:replacePartials] = @options[:replace_partials] # Replace given DOM element (and it's children) (element goes away). + data[:reloadTrees] = @options[:reload_trees] # Replace the data attribute of the given TreeViewComponent data[:buildCalendar] = format_calendar_dates(@options[:build_calendar]) data[:initDashboard] = !! @options[:init_dashboard] data[:ajaxUrl] = ajax_action_url(@options[:ajax_action]) if @options[:ajax_action] diff --git a/app/views/layouts/listnav/_explorer.html.haml b/app/views/layouts/listnav/_explorer.html.haml index 27cba95620b..246da4a1993 100644 --- a/app/views/layouts/listnav/_explorer.html.haml +++ b/app/views/layouts/listnav/_explorer.html.haml @@ -7,9 +7,9 @@ -# Set the first tree to be rendered if there is a mismatch with the name/type - tree = @trees.find(-> { @trees.first }) { |t| t.type == accord[:name].to_sym } %miq-tree-view{:name => tree.name, - :data => tree.locals_for_render[:bs_tree], + :data => "vm.data['#{tree.name}']", :reselect => tree.locals_for_render[:allow_reselect], - "ng-init" => "vm.initSelected('#{tree.name}', '#{tree.locals_for_render[:select_node]}')", + "ng-init" => "vm.initData('#{tree.name}', '#{tree.locals_for_render[:bs_tree]}', '#{tree.locals_for_render[:select_node]}')", 'on-select' => "vm.nodeSelect(node, '/#{request.parameters[:controller]}/tree_select')", 'selected' => "vm.selectedNodes['#{tree.name}']", 'lazy-load' => "(vm.lazyLoad(node, '#{tree.name}', '/#{request.parameters[:controller]}/tree_autoload'))"} diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 86778682173..d840fbcf7be 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -300,16 +300,17 @@ end end - describe "#replace_trees_by_presenter" do + describe "#reload_trees_by_presenter" do let(:tree_1) { double(:name => 'tree_1') } let(:tree_2) { double(:name => 'tree_2') } let(:trees) { {'tree_1' => tree_1, 'tree_2' => tree_2, 'tree_3' => nil} } let(:presenter) { double(:presenter) } it "calls render and passes data to presenter for each pair w/ value" do - expect(controller).to receive(:render_to_string).with(any_args).twice - expect(presenter).to receive(:replace).with(any_args).twice - controller.send(:replace_trees_by_presenter, presenter, trees) + allow(tree_1).to receive(:locals_for_render).and_return(:bs_tree => {}) + allow(tree_2).to receive(:locals_for_render).and_return(:bs_tree => {}) + expect(presenter).to receive(:reload_tree).with(any_args).twice + controller.send(:reload_trees_by_presenter, presenter, trees) end end end diff --git a/spec/controllers/miq_ae_class_controller_spec.rb b/spec/controllers/miq_ae_class_controller_spec.rb index 147032e9128..6f3afafe619 100644 --- a/spec/controllers/miq_ae_class_controller_spec.rb +++ b/spec/controllers/miq_ae_class_controller_spec.rb @@ -97,7 +97,7 @@ :trees => {:ae_tree => {:active_node => node}}) controller.instance_variable_set(:@_params, :button => "reset", :id => cls1.id) allow(controller).to receive(:open_parent_nodes) - expect(controller).to_not receive(:replace_trees_by_presenter) + expect(controller).to_not receive(:reload_trees_by_presenter) expect(controller).to receive(:render) controller.send(:copy_objects) expect(controller.send(:flash_errors?)).not_to be_truthy diff --git a/spec/controllers/miq_policy_controller_spec.rb b/spec/controllers/miq_policy_controller_spec.rb index 8d8c4419af8..3080f8ab8ae 100644 --- a/spec/controllers/miq_policy_controller_spec.rb +++ b/spec/controllers/miq_policy_controller_spec.rb @@ -200,14 +200,14 @@ end describe '#replace_right_cell' do - it 'should replace policy_tree_div when replace_trees contains :policy' do + it 'should reload policy tree when reload_trees contains :policy_tree' do allow(controller).to receive(:params).and_return(:action => 'whatever') controller.instance_eval { @sb = {:active_tree => :policy_tree} } allow(controller).to receive(:render).and_return(nil) presenter = ExplorerPresenter.new(:active_tree => :policy_tree) controller.send(:replace_right_cell, :nodetype => 'root', :replace_trees => [:policy], :presenter => presenter) - expect(presenter[:replace_partials]).to have_key('policy_tree_div') + expect(presenter[:reload_trees]).to have_key(:policy_tree) end it 'should not hide center toolbar while doing searches' do