Skip to content

Commit

Permalink
Convert Menu Features Tree to use TreeBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
hayesr committed Jan 12, 2017
1 parent a470992 commit 2f476e2
Show file tree
Hide file tree
Showing 13 changed files with 593 additions and 78 deletions.
17 changes: 12 additions & 5 deletions app/controllers/ops_controller/ops_rbac.rb
Original file line number Diff line number Diff line change
Expand Up @@ -958,13 +958,20 @@ def rbac_group_right_tree(selected)
def rbac_role_get_details(id)
@edit = nil
@record = @role = MiqUserRole.find_by_id(from_cid(id))
@role_features = @role.feature_identifiers.sort
@features_tree = rbac_build_features_tree
@rbac_menu_tree = build_rbac_menu_tree
end

def rbac_build_features_tree
def build_rbac_menu_tree
@role = @sb[:typ] == "copy" ? @record.dup : @record if @role.nil? # if on edit screen use @record
TreeBuilder.convert_bs_tree(OpsController::RbacTree.build(@role, @role_features, !@edit.nil?)).to_json

TreeBuilderOpsRbacMenu.new(
"features_tree",
"features",
@sb,
true,
role: @role,
editable: @edit.present?
)
end

# Set form variables for role edit
Expand Down Expand Up @@ -1166,7 +1173,7 @@ def rbac_role_set_form_vars
@edit[:current] = copy_hash(@edit[:new])

@role_features = @record.feature_identifiers.sort
@features_tree = rbac_build_features_tree
@rbac_menu_tree = build_rbac_menu_tree
end

# Get array of total set of features from the children of selected features
Expand Down
10 changes: 10 additions & 0 deletions app/presenters/menu/item.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
module Menu
Item = Struct.new(:id, :name, :feature, :rbac_feature, :href, :type) do
extend ActiveModel::Naming

def self.base_class
Menu::Item
end

def self.base_model
model_name
end

def initialize(an_id, a_name, features, rbac_feature, href, type = :default)
super
@parent = nil
Expand Down
20 changes: 15 additions & 5 deletions app/presenters/menu/manager.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
module Menu
class Manager
include Enumerable
include Singleton

class << self
extend Forwardable

delegate %i(menu item_in_section? item section section_id_string_to_symbol each) => :instance
delegate %i(
menu
item_in_section?
item section
section_id_string_to_symbol
each
map
detect
select
) => :instance
end

def each
@menu.map { |section| yield section }
end

private
Expand Down Expand Up @@ -39,10 +53,6 @@ def item_in_section?(item_id, section_id)
@id_to_section[section_id].contains_item_id?(item_id)
end

def each
@menu.each { |section| yield section }
end

def initialize
load_default_items
load_custom_items
Expand Down
16 changes: 15 additions & 1 deletion app/presenters/menu/section.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
module Menu
Section = Struct.new(:id, :name, :icon, :items, :placement, :before, :type, :href) do
extend ActiveModel::Naming

def self.base_class
Menu::Section
end

def self.base_model
model_name
end

def initialize(an_id, name, icon, *args)
super
self.items ||= []
Expand All @@ -17,7 +27,7 @@ def features
end

def features_recursive
Array(items).collect { |el| el.try(:feature) || el.try(:features) }.flatten.compact
Array(items).flat_map { |el| el.try(:feature) || el.try(:features) }.compact
end

def visible?
Expand Down Expand Up @@ -84,5 +94,9 @@ def parent_path(acc = [])
acc << id
@parent.present? ? @parent.parent_path(acc) : acc
end

def load_children?
true
end
end
end
8 changes: 7 additions & 1 deletion app/presenters/tree_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,15 @@ def x_build_node(object, pid, options)
node = x_build_single_node(object, pid, options)

# Process the node's children
load_children = if object.kind_of?(Struct)
object.respond_to?(:load_children?) && object.load_children?
else
object[:load_children]
end

node[:expand] = Array(@tree_state.x_tree(@name)[:open_nodes]).include?(node[:key]) || !!options[:open_all] || node[:expand]
if ancestry_kids ||
object[:load_children] ||
load_children ||
node[:expand] ||
@options[:lazy] == false

Expand Down
183 changes: 183 additions & 0 deletions app/presenters/tree_builder_ops_rbac_menu.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
class TreeBuilderOpsRbacMenu < TreeBuilder
include CompressedIds

has_kids_for Menu::Section, [:x_get_tree_section_kids]
has_kids_for Menu::Item, [:x_get_tree_item_kids]
has_kids_for MiqProductFeature, [:x_get_tree_feature_kids]

attr_reader :role, :features, :editable, :root_counter

def initialize(name, type, sandbox, build, role:, editable: false)
@role = role
@editable = editable
@features = @role.miq_product_features.order(:identifier).pluck(:identifier)

@root_counter = []

super(name, type, sandbox, build)
end

private

def filtered_menus
menus = Menu::Manager.map do |section|
next if section.id == :cons && !Settings.product.consumption
next if section.name.nil?
next unless Vmdb::PermissionStores.instance.can?(section.id)

section
end

menus
end

def set_locals_for_render
locals = {
:checkboxes => true,
:three_checks => true,
:check_url => "/ops/rbac_role_field_changed/"
}

if editable
locals[:oncheck] = "miqOnCheckHandler"
end

super.merge!(locals)
end

def x_get_tree_roots(count_only = false, _options)
top_nodes = filtered_menus
top_nodes << MiqProductFeature.find_by_identifier("all_vm_rules")

count_only_or_objects(count_only, top_nodes)
end

def x_get_tree_hash_kids(parent, count_only = false)
count_only_or_objects(count_only, parent[:data][:kids])
end

def x_get_tree_section_kids(parent, count_only = false)
kids = parent.items.select do |item|
if item.kind_of? Menu::Item
item.feature.present? && MiqProductFeature.feature_exists?(item.feature)
else
true
end
end

count_only_or_objects(count_only, kids)
end

# FIXME: This is inefficient, but done to use MiqProductFeature objects rather than hashes
def x_get_tree_item_kids(parent, count_only = false)
if parent_feature = all_features.find_by(:identifier => parent.feature)
details = MiqProductFeature.features[parent.feature]

kids = parent_feature.children.where(:hidden => [false, nil]).sort_by do |c|
details[:children].index(c.identifier)
end

count_only_or_objects(count_only, kids)
else
[]
end
end

def x_get_tree_feature_kids(parent, count_only = false)
count_only_or_objects(count_only, parent.children)
end

def tree_init_options(_tree_name)
{
:lazy => false,
:add_root => true,
:role => role,
:features => features,
:editable => editable,
:node_id_prefix => node_id_prefix
}
end

def root_options
root_node
end

def root_node
@root_node ||= {
:key => root_key,
:title => root_title,
:tooltip => root_tooltip,
:expand => true,
:cfmeNoClick => true,
:select => root_select_state,
:checkable => editable
}
end

def root_details
@root_details ||= MiqProductFeature.feature_details(root_feature)
end

def root_tooltip
_(root_details[:description]) || _(root_details[:name])
end

def root_title
_(root_details[:name])
end

def root_key
"#{node_id_prefix}__#{root_feature}"
end

def root_select_state
features.include?(root_feature) || select_state_from_counter
end

def select_state_from_counter
return false if root_counter.empty?
return true if root_counter.all?{ |n| n }
return 'undefined' if root_counter.any? { |n| n || n == 'undefined' }

false
end

def node_id_prefix
role.id ? to_cid(role.id) : "new"
end

def root_feature
@root_feature ||= MiqProductFeature.feature_root
end

def all_vm_options
text = _("Access Rules for all Virtual Machines")
checked = features.include?("all_vm_rules") || root_select_state

{
:key => "#{node_id_prefix}___tab_all_vm_rules",
:title => text,
:tooltip => text,
:select => checked
}
end

def all_features
@all_features ||= MiqProductFeature.where(:hidden => [false, nil]).load
end

def add_to_root_counter(node)
root_counter << node[:select]
end

def override(node, object, pid, options)
case object
when Menu::Section
add_to_root_counter(node)
when MiqProductFeature
if object.identifier == "all_vm_rules"
node.merge!(all_vm_options)
end
end
end
end
3 changes: 2 additions & 1 deletion app/presenters/tree_node/hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ class Hash < Node

set_attribute(:hide_checkbox) { @object.key?(:hideCheckbox) && @object[:hideCheckbox] ? true : nil }

set_attribute(:selected) { @object.key?(:select) && @object[:select] ? true : nil }
# set_attribute(:selected) { @object.key?(:select) && @object[:select] ? true : nil }
set_attribute(:selected) { @object[:select] if @object.key?(:select) }

set_attribute(:klass) { @object.key?(:addClass) ? @object[:addClass] : nil }

Expand Down
Loading

0 comments on commit 2f476e2

Please sign in to comment.