Skip to content

Commit

Permalink
Merge pull request #2100 from skateman/explorer-tree-reload
Browse files Browse the repository at this point in the history
Reload listnav explorer trees from explorers using RxJS
  • Loading branch information
martinpovolny committed Sep 8, 2017
2 parents 13ab389 + 9f67c25 commit 2b10d1a
Show file tree
Hide file tree
Showing 19 changed files with 73 additions and 53 deletions.
55 changes: 35 additions & 20 deletions app/assets/javascripts/controllers/tree_view_controller.js
Expand Up @@ -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);
})();
8 changes: 8 additions & 0 deletions app/assets/javascripts/miq_explorer.js
Expand Up @@ -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);
Expand Down Expand Up @@ -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(); }
Expand Down
16 changes: 3 additions & 13 deletions app/controllers/application_controller.rb
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/catalog_controller.rb
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/chargeback_controller.rb
Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/miq_ae_class_controller.rb
Expand Up @@ -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"])
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/miq_ae_customization_controller.rb
Expand Up @@ -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])
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/miq_policy_controller.rb
Expand Up @@ -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') &&
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/mixins/manager_controller_mixin.rb
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/ops_controller.rb
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/pxe_controller.rb
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/report_controller.rb
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/service_controller.rb
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/storage_controller.rb
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions app/presenters/explorer_presenter.rb
Expand Up @@ -68,6 +68,7 @@ def initialize(options = {})
:element_updates => {},
:replace_partials => {},
:reload_toolbars => {},
:reload_trees => {},
:exp => {},
:osf_node => '',
:show_miq_buttons => false,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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]
Expand Down
4 changes: 2 additions & 2 deletions app/views/layouts/listnav/_explorer.html.haml
Expand Up @@ -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'))"}
Expand Down
9 changes: 5 additions & 4 deletions spec/controllers/application_controller_spec.rb
Expand Up @@ -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
2 changes: 1 addition & 1 deletion spec/controllers/miq_ae_class_controller_spec.rb
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions spec/controllers/miq_policy_controller_spec.rb
Expand Up @@ -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
Expand Down

0 comments on commit 2b10d1a

Please sign in to comment.