Skip to content

Commit

Permalink
fixes #6150 - users need taxonomy added on "all Users"
Browse files Browse the repository at this point in the history
With this commit, if "All users" is ticked then
locations and organizations are added to users. On edit user page,
you can not edit this taxonomy as they are disabled with tooltip
"Select all option enabled for this taxonomy".
  • Loading branch information
kgaikwad committed Jan 25, 2017
1 parent 2e81c25 commit f7e8950
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 45 deletions.
56 changes: 30 additions & 26 deletions app/assets/javascripts/jquery.multi-select.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,48 @@ function multiSelectOnLoad(){

function multiSelectToolTips(){
$('select[multiple]').each(function(i,item){
var mismatches = $(item).attr('data-mismatches');
var inheriteds = $(item).attr('data-inheriteds');
var descendants = $(item).attr('data-descendants');
var useds = $(item).attr('data-useds');
var msid = '#ms-'+item.id;
var mismatches = $(item).attr('data-mismatches'),
inheriteds = $(item).attr('data-inheriteds'),
descendants = $(item).attr('data-descendants'),
useds = $(item).attr('data-useds'),
usedall = $(item).attr('data-usedall'),
msid = '#ms-'+item.id;
// it an <li> items match multiple tooltips, then only the first tooltip will show
if (!(usedall == null || usedall == 'undefined')) {
addTooltipForElements(msid, usedall,
[{class_to_find_li: 'selection', clname: 'selected_taxonomy', label: "Select all option enabled for this taxonomy", position: 'right'}]);
}
if (!(mismatches == null || mismatches == 'undefined')) {
var missing_ids = $.parseJSON(mismatches);
$.each(missing_ids, function(index,missing_id){
opt_id = sanitize(missing_id+'');
$(msid).find('li#'+opt_id+'-selectable').addClass('delete').tooltip({container: 'body', title: __("Select this since it belongs to a host"), placement: "left"});
})
addTooltipForElements(msid, mismatches,
[{class_to_find_li: 'selectable', clname: 'delete', label: "Select this since it belongs to a host", position: 'left'}]);
}
if (!(useds == null || descendants == 'useds')) {
var used_ids = $.parseJSON(useds);
$.each(used_ids, function(index,used_id){
opt_id = sanitize(used_id+'');
$(msid).find('li#'+opt_id+'-selection').addClass('used_by_hosts').tooltip({container: 'body', title: __("This is used by a host"), placement: "right"});
})
addTooltipForElements(msid, useds,
[{class_to_find_li: 'selection', clname: 'used_by_hosts', label: "This is used by a host", position: 'right'}]);
}
if (!(inheriteds == null || inheriteds == 'undefined')) {
var inherited_ids = $.parseJSON(inheriteds);
$.each(inherited_ids, function(index,inherited_id){
opt_id = sanitize(inherited_id+'');
$(msid).find('li#'+opt_id+'-selection').addClass('inherited').tooltip({container: 'body', title: __("This is inherited from parent"), placement: "right"});
})
addTooltipForElements(msid, inheriteds,
[{class_to_find_li: 'selection', clname: 'inherited', label: "This is inherited from parent", position: 'right'}]);
}
if (!(descendants == null || descendants == 'undefined')) {
var descendant_ids = $.parseJSON(descendants);
$.each(descendant_ids, function(index,descendant_id){
opt_id = sanitize(descendant_id+'');
$(msid).find('li#'+opt_id+'-selection').addClass('descendants').tooltip({container: 'body', title: __("Parent is already selected"), placement: "right"});
$(msid).find('li#'+opt_id+'-selectable').addClass('descendants').tooltip({container: 'body', title: __("Parent is already selected"), placement: "left"});
})
addTooltipForElements(msid, descendants,
[{class_to_find_li: 'selection', clname: 'descendants', label: 'Parent is already selected', position: 'right'},
{class_to_find_li: 'selectable', clname: 'descendants', label: 'Parent is already selected', position: 'left'}]);
}
})
}

function addTooltipForElements(msid, json_ids, tooltips_with_options) {
var ids = $.parseJSON(json_ids);
$.each(ids, function(index, id){
opt_id = sanitize(id+'');
$.each(tooltips_with_options, function(tooltip_index, tooltip_opts) {
$(msid).find('li#'+opt_id+'-' + tooltip_opts.class_to_find_li).addClass(tooltip_opts.clname).tooltip(
{container: 'body', title: __(tooltip_opts.label), placement: tooltip_opts.position});
});
});
}

// function below is copy/paste from source of multi-select-rails gem
// it takes the option value and returns a value used in css id
function sanitize(value){
Expand Down
6 changes: 6 additions & 0 deletions app/assets/javascripts/taxonomy_edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ $(function(){
$(":checkbox").each(function(i,item){
ignore_checked(item);
})
$('form').on('submit', function() {
$('select.without_select2').prop('disabled', false);
$('.ms-selection li.ms-elem-selection').removeClass('disabled');
});

})

function ignore_checked(item){
var current_select = $(item).closest('.tab-pane').find('select');

if ($(item).is(':checked')) {
current_select.attr('disabled', 'disabled');
current_select.find("option").prop('selected', true);
} else {
current_select.removeAttr('disabled');
}
Expand Down
22 changes: 9 additions & 13 deletions app/helpers/form_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,9 @@ def multiple_checkboxes(f, attr, klass, associations, options = {}, html_options
# add hidden field for options[:disabled]
def multiple_selects(f, attr, associations, selected_ids, options = {}, html_options = {})
options.merge!(:size => "col-md-10")
case attr
when :organizations
klass = Organization
when :locations
klass = Location
else
klass = nil
klass = nil
if [:organizations, :locations].include?(attr)
klass = attr.to_s.classify.constantize
end
authorized = AssociationAuthorizer.authorized_associations(associations.reorder(nil), klass).all

Expand All @@ -75,12 +71,12 @@ def multiple_selects(f, attr, associations, selected_ids, options = {}, html_opt
field(f, attr, options) do
attr_ids = (attr.to_s.singularize+"_ids").to_sym
hidden_fields = ''
html_options["data-useds"] ||= "[]"
JSON.parse(html_options["data-useds"]).each do |disabled_value|
hidden_fields += f.hidden_field(attr_ids, :multiple => true, :value => disabled_value, :id=>'')
end
unauthorized.each do |unauthorized_value|
hidden_fields += f.hidden_field(attr_ids, :multiple => true, :value => unauthorized_value, :id=>'')
html_options["data-useds"] ||= '[]'
html_options["data-usedall"] ||= '[]'
[JSON.parse(html_options["data-useds"]), JSON.parse(html_options["data-usedall"]), unauthorized].each do |optns|
optns.each do |value|
hidden_fields += f.hidden_field(attr_ids, :multiple => true, :value => value, :id=>'')
end
end
hidden_fields + f.collection_select(attr_ids, authorized.sort_by { |a| a.to_s },
:id, :to_label, options.merge(:selected => selected_ids),
Expand Down
12 changes: 10 additions & 2 deletions app/models/concerns/taxonomix.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,20 @@ def used_organization_ids
used_taxonomy_ids(:organization_id)
end

def enabled_select_all_location_ids
Location.enabled_select_all_taxonomies(self.class.to_s).map(&:id)
end

def enabled_select_all_organization_ids
Organization.enabled_select_all_taxonomies(self.class.to_s).map(&:id)
end

def used_or_selected_location_ids
(location_ids + used_location_ids).uniq
(location_ids + used_location_ids + enabled_select_all_location_ids).uniq
end

def used_or_selected_organization_ids
(organization_ids + used_organization_ids).uniq
(organization_ids + used_organization_ids + enabled_select_all_organization_ids).uniq
end

def children_of_selected_location_ids
Expand Down
2 changes: 2 additions & 0 deletions app/models/taxonomy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ def self.inherited(child)
end
}

scope :enabled_select_all_taxonomies, ->(taxable_type){where("ignore_types LIKE ?", "%#{[taxable_type].to_yaml}%") }

def self.locations_enabled
enabled?(:location)
end
Expand Down
14 changes: 14 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def self.name_format

after_create :welcome_mail
after_create :set_default_widgets
after_initialize :add_select_all_taxonomies

scoped_search :on => :login, :complete_value => :true
scoped_search :on => :firstname, :complete_value => :true
Expand Down Expand Up @@ -506,6 +507,19 @@ def verify_current_password
end
end

# assign all taxonomies for which ignore_type includes 'User' resource
def add_select_all_taxonomies
if self.new_record?
[Organization, Location].each do |taxonomy_class|
objs = taxonomy_class.enabled_select_all_taxonomies('User').to_a
meth_name = taxonomy_class.name.underscore.pluralize
existing_objs = self.send(meth_name)
objs.concat(existing_objs).uniq!
self.send("#{meth_name}=", objs)
end
end
end

protected

def name_used_in_a_usergroup
Expand Down
10 changes: 6 additions & 4 deletions app/views/taxonomies/_loc_org_tabs.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
<% if show_location_tab? %>
<div class="tab-pane" id="locations">
<%= location_selects f, obj.used_or_selected_location_ids,
{:disabled => obj.used_location_ids }.merge!(select_options),
{:disabled => obj.used_location_ids.concat(obj.enabled_select_all_location_ids)}.merge!(select_options),
{'data-descendants' => obj.children_of_selected_location_ids.to_json,
'data-useds' => obj.used_location_ids.to_json }.merge!(html_options[:location]) %>
'data-useds' => obj.used_location_ids.to_json,
'data-usedall' => obj.enabled_select_all_location_ids.to_json }.merge!(html_options[:location]) %>
<% if SETTINGS[:locations_enabled] && (obj.kind_of? User) %>
<%= select_f f, :default_location_id, (obj.admin? ? Location.all : obj.locations), :id, :title,
{ :include_blank => true }, { :label => _('Default on login') } %>
Expand All @@ -19,9 +20,10 @@
<% if show_organization_tab? %>
<div class="tab-pane" id="organizations">
<%= organization_selects f, obj.used_or_selected_organization_ids,
{:disabled => obj.used_organization_ids }.merge!(select_options),
{:disabled => obj.used_organization_ids.concat(obj.enabled_select_all_organization_ids)}.merge!(select_options),
{'data-descendants' => obj.children_of_selected_organization_ids.to_json,
'data-useds' => obj.used_organization_ids.to_json }.merge!(html_options[:organization]) %>
'data-useds' => obj.used_organization_ids.to_json,
'data-usedall' => obj.enabled_select_all_organization_ids.to_json }.merge!(html_options[:organization]) %>
<% if SETTINGS[:organizations_enabled] && (obj.kind_of? User) %>
<%= select_f f, :default_organization_id,(obj.admin? ? Organization.all : obj.organizations), :id, :title,
{ :include_blank => true }, { :label => _('Default on login') } %>
Expand Down
9 changes: 9 additions & 0 deletions db/migrate/20161212121640_update_taxonomies_with_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class UpdateTaxonomiesWithUsers < ActiveRecord::Migration
def up
say "This Migration will take time for updating organization & location records with all users for which ignore_types includes 'User' resource."
Rake::Task['taxonomy:update_taxonomy'].invoke
end

def down
end
end
20 changes: 20 additions & 0 deletions lib/tasks/taxonomy.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace :taxonomy do
desc <<-END_DESC
This task will update organization & location records with all users for which ignore_types includes 'User' resource.
END_DESC
task :update_taxonomy => :environment do
users = User.all
orgs_with_user_ignore_types = Organization.enabled_select_all_taxonomies('User')
orgs_with_user_ignore_types.each do |org|
org.users = users
success = org.save
puts "Failed to save Organization #{org.id}- #{org.errors.full_messages.inspect}" unless success
end
locations_with_user_ignore_types = Location.enabled_select_all_taxonomies('User')
locations_with_user_ignore_types.each do |loc|
loc.users = users
success = loc.save
puts "Failed to save Location #{loc.id}- #{loc.errors.full_messages.inspect}" unless success
end
end
end
8 changes: 8 additions & 0 deletions test/models/taxonomix_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -283,4 +283,12 @@ def setup
assert_empty used_organizations
assert_equal used_organizations.count, 0
end

test "#enabled_select_all_organization_ids should return organizations for which 'Select All' option is checked for a resource." do
FactoryGirl.create(:organization, :ignore_types => [ 'User' ])
user = FactoryGirl.create(:user, :id => 20)
select_all_enabled_organizations = user.enabled_select_all_organization_ids
assert_not select_all_enabled_organizations.empty?
assert_equal select_all_enabled_organizations.count, 1
end
end

0 comments on commit f7e8950

Please sign in to comment.