Permalink
Browse files

Merge branch 'master' of git://github.com/sferik/rails_admin

Conflicts:
	app/views/rails_admin/main/_form_filtering_multiselect.html.haml
	lib/rails_admin/config/fields/types/has_many_association.rb
  • Loading branch information...
pehlert committed Apr 18, 2013
2 parents e746e7f + b8465f7 commit e596b6b89244b65fc68f314492b29019f2d9a205

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -68,3 +68,10 @@ $(document).on 'rails_admin.dom_ready', ->
$(this).siblings('.control-group').hide()
$(".table").tooltip selector: "th[rel=tooltip]"
+
+$(document).on 'click', '#fields_to_export label input#check_all', () ->
+ elems = $('#fields_to_export label input')
+ if $('#fields_to_export label input#check_all').is ':checked'
+ $(elems).prop('checked', true)
+ else
+ $(elems).prop('checked',false)
@@ -47,7 +47,8 @@ body.rails_admin {
.controls .nav {
margin-bottom:5px;
}
- .remove_nested_fields {
+ .remove_nested_fields,
+ .remove_nested_one_fields {
position:absolute;
}
margin:0px;
@@ -62,7 +62,7 @@ def get_sort_hash(model_config)
"#{abstract_model.table_name}.#{params[:sort]}"
elsif field.sortable == false # use default sort, asked field is not sortable
"#{abstract_model.table_name}.#{model_config.list.sort_by}"
- elsif field.sortable.is_a?(String) && field.sortable.include?('.') # just provide sortable, don't do anything smart
+ elsif (field.sortable.is_a?(String) || field.sortable.is_a?(Symbol)) && field.sortable.to_s.include?('.') # just provide sortable, don't do anything smart
field.sortable
elsif field.sortable.is_a?(Hash) # just join sortable hash, don't do anything smart
"#{field.sortable.keys.first}.#{field.sortable.values.first}"
@@ -79,9 +79,10 @@ def navigation nodes_stack, nodes, level=0
model_param = node.abstract_model.to_param
url = url_for(:action => :index, :controller => 'rails_admin/main', :model_name => model_param)
level_class = " nav-level-#{level}" if level > 0
+ nav_icon = node.navigation_icon ? %{<i class="#{node.navigation_icon}"></i>}.html_safe : ''
li = content_tag :li, "data-model"=>model_param do
- link_to node.label_plural, url, :class => "pjax#{level_class}"
+ link_to nav_icon + node.label_plural, url, :class => "pjax#{level_class}"
end
li + navigation(nodes_stack, nodes_stack.select{ |n| n.parent.to_s == node.abstract_model.model_name}, level+1)
end.join.html_safe
@@ -41,7 +41,7 @@
- selected_ids = (hdv = field.html_default_value).nil? ? selected_ids : hdv
= form.select field.method_name, collection, { :selected => selected_ids, :object => form.object }, field.html_attributes.reverse_merge({:data => { :filteringmultiselect => true, :options => js_data.to_json }, :multiple => true})
-- if authorized?(:new, config.abstract_model) && !field.parent_readonly
+- if authorized?(:new, config.abstract_model) && !field.parent_readonly && field.inline_add
- path_hash = { :model_name => config.abstract_model.to_param, :modal => true }
- path_hash.merge!({ :associations => { field.inverse_of => (form.object.persisted? ? form.object.id : 'new') } }) if field.inverse_of
= link_to "<i class=\"icon-plus icon-white\"></i> ".html_safe + wording_for(:link, :new, config.abstract_model), '#', :data => { :link => new_path(path_hash) }, :class => "create btn btn-info", :style => 'margin-left:10px'
@@ -28,10 +28,10 @@
- selected_id = (hdv = field.html_default_value).nil? ? selected_id : hdv
= form.select field.method_name, collection, { :selected => selected_id, :include_blank => true }, field.html_attributes.reverse_merge({ :data => { :filteringselect => true, :options => js_data.to_json }, :placeholder => t('admin.misc.search') })
-- if authorized? :new, config.abstract_model
+- if authorized?(:new, config.abstract_model) && field.inline_add
- path_hash = { :model_name => config.abstract_model.to_param, :modal => true }
- path_hash.merge!({ :associations => { field.inverse_of => (form.object.persisted? ? form.object.id : 'new') } }) if field.inverse_of
= link_to "<i class=\"icon-plus icon-white\"></i> ".html_safe + wording_for(:link, :new, config.abstract_model), '#', :data => { :link => new_path(path_hash) }, :class => "btn btn-info create", :style => 'margin-left:10px'
-- if edit_url.present?
+- if edit_url.present? && field.inline_edit
= link_to "<i class=\"icon-pencil icon-white\"></i> ".html_safe + wording_for(:link, :edit, config.abstract_model), '#', :data => { :link => edit_url }, :class => "btn btn-info update #{field.value.nil? && 'disabled'}", :style => 'margin-left:10px'
@@ -2,7 +2,7 @@
.btn-group
%a.btn.btn-info.toggler{:'data-toggle' => "button", :'data-target' => "#{form.jquery_namespace(field)} > .tab-content, #{form.jquery_namespace(field)} > .controls > .nav", :class => (field.active? ? 'active' : '')}
%i.icon-white
- - unless field.nested_form[:update_only]
+ - unless field.nested_form[:update_only] || !field.inline_add
= form.link_to_add "<i class=\"icon-plus icon-white\"></i> #{wording_for(:link, :new, field.associated_model_config.abstract_model)}".html_safe, field.name, { :class => 'btn btn-info' }
= form.errors_for(field)
= form.help_for(field)
@@ -4,7 +4,12 @@
= form_tag export_path(params.merge(:all => true)), :method => 'post', :class => 'form-horizontal denser' do
%input{:name => "send_data", :type => "hidden", :value => "true"}/
- %fieldset
+ %fieldset{:id => 'fields_to_export'}
+ %div.control-group
+ %div.controls
+ %label.checkbox{:for => 'check_all'}
+ = 'Select All Fields'
+ = check_box_tag 'all', 'all', true, { :id => 'check_all' }
%legend
%i.icon-chevron-down
= t('admin.export.select')
@@ -107,6 +107,10 @@ def embedded?
false
end
+ def cyclic?
+ false
+ end
+
def adapter_supports_joins?
true
end
@@ -6,7 +6,7 @@ module RailsAdmin
module Adapters
module Mongoid
STRING_TYPE_COLUMN_NAMES = [:name, :title, :subject]
- DISABLED_COLUMN_TYPES = ['Range']
+ DISABLED_COLUMN_TYPES = ['Range', 'Moped::BSON::Binary']
ObjectId = (::Mongoid::VERSION >= '3' ? ::Moped::BSON::ObjectId : ::BSON::ObjectId)
def new(params = {})
@@ -105,6 +105,10 @@ def embedded?
@embedded ||= !!model.associations.values.find{|a| a.macro.to_sym == :embedded_in }
end
+ def cyclic?
+ @cyclic ||= !!model.cyclic?
+ end
+
def object_id_from_string(str)
ObjectId.from_string(str)
end
@@ -327,7 +331,7 @@ def association_foreign_inverse_of_lookup(association)
def association_nested_attributes_options_lookup(association)
nested = model.nested_attributes_options.try { |o| o[association.name.to_sym] }
- if !nested && [:embeds_one, :embeds_many].include?(association.macro.to_sym)
+ if !nested && [:embeds_one, :embeds_many].include?(association.macro.to_sym) && !association.cyclic
raise <<-MSG.gsub(/^\s+/, '')
Embbeded association without accepts_nested_attributes_for can't be handled by RailsAdmin,
because embedded model doesn't have top-level access.
@@ -426,10 +430,14 @@ def perform_search_on_associated_collection(field_name, conditions)
def sort_by(options, scope)
return scope unless options[:sort]
- field_name, collection_name = options[:sort].to_s.split('.').reverse
- if collection_name && collection_name != table_name
- # sorting by associated model column is not supported, so just ignore
- return scope
+ case options[:sort]
+ when String
+ field_name, collection_name = options[:sort].split('.').reverse
+ if collection_name && collection_name != table_name
+ raise "sorting by associated model column is not supported in Non-Relational databases"
+ end
+ when Symbol
+ field_name = options[:sort].to_s
end
if options[:sort_reverse]
scope.asc field_name
@@ -315,7 +315,7 @@ def reset_model(model)
# @see RailsAdmin::Config::Hideable
def visible_models(bindings)
- models.map{|m| m.with(bindings) }.select{|m| m.visible? && bindings[:controller].authorized?(:index, m.abstract_model) && !m.abstract_model.embedded?}.sort do |a, b|
+ models.map{|m| m.with(bindings) }.select{|m| m.visible? && bindings[:controller].authorized?(:index, m.abstract_model) && (!m.abstract_model.embedded? || m.abstract_model.cyclic?)}.sort do |a, b|
(weight_order = a.weight <=> b.weight) == 0 ? a.label.downcase <=> b.label.downcase : weight_order
end
end
@@ -215,10 +215,28 @@ def virtual?
def editable?
return false if @properties && @properties[:read_only]
- active_model_attr_accessible = !bindings[:object].class.active_authorizer[bindings[:view].controller.send(:_attr_accessible_role)].deny?(self.method_name)
+ role = bindings[:view].controller.send(:_attr_accessible_role)
+ active_model_attr_accessible = !bindings[:object].class.active_authorizer[role].deny?(self.method_name)
+
return true if active_model_attr_accessible
if RailsAdmin::Config.yell_for_non_accessible_fields
- Rails.logger.debug "\n\n[RailsAdmin] Please add 'attr_accessible :#{self.method_name}' in your '#{bindings[:object].class}' model definition if you want to make it editable.\nYou can also explicitely mark this field as read-only: \n\nconfig.model #{bindings[:object].class} do\n field :#{self.name} do\n read_only true\n end\nend\n\nAdd 'config.yell_for_non_accessible_fields = false' in your 'rails_admin.rb' initializer if you do not want to see these warnings\n\n"
+ accessible = "attr_accessible :#{self.method_name}#{role == :default ? '' : ", :as => :#{role}"}"
+
+ Rails.logger.debug <<-MESSAGE.strip_heredoc
+
+
+ [RailsAdmin] Please add '#{accessible}' in your '#{bindings[:object].class}' model definition if you want to make it editable.
+ You can also explicitely mark this field as read-only:
+
+ config.model #{bindings[:object].class} do
+ field :#{self.name} do
+ read_only true
+ end
+ end
+
+ Add 'config.yell_for_non_accessible_fields = false' in your 'rails_admin.rb' initializer if you do not want to see these warnings
+
+ MESSAGE
end
false
end
@@ -23,6 +23,14 @@ class BelongsToAssociation < RailsAdmin::Config::Fields::Association
nested_form ? :form_nested_one : :form_filtering_select
end
+ register_instance_option :inline_add do
+ true
+ end
+
+ register_instance_option :inline_edit do
+ true
+ end
+
def selected_id
bindings[:object].send(foreign_key)
end
@@ -22,6 +22,10 @@ class HasManyAssociation < RailsAdmin::Config::Fields::Association
self.associated_model_config.excluded?
end
+ register_instance_option :inline_add do
+ true
+ end
+
def method_name
nested_form ? "#{super}_attributes".to_sym : "#{super.to_s.singularize}_ids".to_sym # name_ids
end
@@ -17,6 +17,15 @@ class HasOneAssociation < RailsAdmin::Config::Fields::Association
(o = value) && o.send(associated_model_config.object_label_method)
end
+ register_instance_option :inline_add do
+ true
+ end
+
+ register_instance_option :inline_edit do
+ true
+ end
+
+
def editable?
(nested_form || abstract_model.model.new.respond_to?("#{self.name}_id=")) && super
end
@@ -13,7 +13,9 @@ class Serialized < RailsAdmin::Config::Fields::Types::Text
end
def parse_input(params)
- params[name] = (params[name].blank? ? nil : YAML.safe_load(params[name])) if params[name].is_a?(::String)
+ if params[name].is_a?(::String)
+ params[name] = (params[name].blank? ? nil : (YAML.safe_load(params[name]) || nil))
+ end
end
end
end
@@ -82,6 +82,10 @@ def pluralize(count)
@navigation_label ||= (parent_module = abstract_model.model.parent) != Object ? parent_module.to_s : nil
end
+ register_instance_option :navigation_icon do
+ nil
+ end
+
# Act as a proxy for the base section configuration that actually
# store the configurations.
def method_missing(m, *args, &block)
@@ -2,7 +2,7 @@ module RailsAdmin
class Version
MAJOR = 0 unless defined? MAJOR
MINOR = 4 unless defined? MINOR
- PATCH = 5 unless defined? PATCH
+ PATCH = 7 unless defined? PATCH
PRE = nil unless defined? PRE
class << self
@@ -38,6 +38,24 @@
end
describe "#get_sort_hash" do
+ context "options sortable is a hash" do
+ before do
+ RailsAdmin.config('Player') do
+ configure :team do
+ sortable do
+ :'team.name'
+ end
+ end
+ end
+ end
+
+ it "returns the option with no changes" do
+ controller.params = { :sort => "team", :model_name =>"players" }
+ expect(controller.send(:get_sort_hash, RailsAdmin.config(Player))).to eq({:sort=>:"team.name", :sort_reverse=>true})
+ end
+ end
+
+
it "works with belongs_to associations with label method virtual" do
controller.params = { :sort => "parent_category", :model_name =>"categories" }
expect(controller.send(:get_sort_hash, RailsAdmin.config(Category))).to eq({:sort=>"categories.parent_category_id", :sort_reverse=>true})
@@ -11,6 +11,7 @@ class FieldTest
field :big_decimal_field, :type => BigDecimal
field :boolean_field, :type => Boolean
field :bson_object_id_field, :type => RailsAdmin::Adapters::Mongoid::ObjectId
+ field :bson_binary_field, :type => Moped::BSON::Binary
field :date_field, :type => Date
field :datetime_field, :type => DateTime
field :time_with_zone_field, :type => ActiveSupport::TimeWithZone
@@ -30,7 +31,7 @@ class FieldTest
field :protected_field, :type => String
has_mongoid_attached_file :paperclip_asset, :styles => { :thumb => "100x100>" }
- basic_accessible_fields = [:comment_attributes, :nested_field_tests_attributes, :embed_attributes, :embeds_attributes, :dragonfly_asset, :remove_dragonfly_asset, :retained_dragonfly_asset, :carrierwave_asset, :carrierwave_asset_cache, :remove_carrierwave_asset, :paperclip_asset, :delete_paperclip_asset, :comment_id, :name, :array_field, :big_decimal_field, :boolean_field, :bson_object_id_field, :date_field, :datetime_field, :time_with_zone_field, :default_field, :float_field, :hash_field, :integer_field, :object_field, :range_field, :string_field, :symbol_field, :text_field, :time_field, :created_at, :updated_at, :format]
+ basic_accessible_fields = [:comment_attributes, :nested_field_tests_attributes, :embed_attributes, :embeds_attributes, :dragonfly_asset, :remove_dragonfly_asset, :retained_dragonfly_asset, :carrierwave_asset, :carrierwave_asset_cache, :remove_carrierwave_asset, :paperclip_asset, :delete_paperclip_asset, :comment_id, :name, :array_field, :big_decimal_field, :boolean_field, :bson_object_id_field, :bson_binary_field, :date_field, :datetime_field, :time_with_zone_field, :default_field, :float_field, :hash_field, :integer_field, :object_field, :range_field, :string_field, :symbol_field, :text_field, :time_field, :created_at, :updated_at, :format]
attr_accessible *basic_accessible_fields
attr_accessible *(basic_accessible_fields + [:restricted_field, {:as => :custom_role}])
attr_accessible *(basic_accessible_fields + [:protected_field, {:as => :extra_safe_role}])
@@ -593,6 +593,79 @@ class HelpTest < Tableless
expect(find("#team_division_id_field .help-block")).to have_content("Optional")
expect(find("#team_name_field .help-block")).to have_content("Required")
end
+
+ it "can hide the add button on an associated field" do
+ RailsAdmin.config Player do
+ edit do
+ field :team do
+ inline_add false
+ end
+ field :draft do
+ inline_add false
+ end
+ field :comments do
+ inline_add false
+ end
+ end
+ end
+ visit new_path(:model_name => "player")
+ should have_no_selector('a', :text => 'Add a new Team')
+ should have_no_selector('a', :text => 'Add a new Draft')
+ should have_no_selector('a', :text => 'Add a new Comment')
+ end
+
+ it "can show the add button on an associated field" do
+ RailsAdmin.config Player do
+ edit do
+ field :team do
+ inline_add true
+ end
+ field :draft do
+ inline_add true
+ end
+ field :comments do
+ inline_add true
+ end
+ end
+ end
+ visit new_path(:model_name => "player")
+ should have_selector('a', :text => 'Add a new Team')
+ should have_selector('a', :text => 'Add a new Draft')
+ should have_selector('a', :text => 'Add a new Comment')
+ end
+
+ it "can hide the edit button on an associated field" do
+ RailsAdmin.config Player do
+ edit do
+ field :team do
+ inline_edit false
+ end
+ field :draft do
+ inline_edit false
+ end
+ end
+ end
+ visit new_path(:model_name => "player")
+ should have_no_selector('a', :text => 'Edit this Team')
+ should have_no_selector('a', :text => 'Edit this Draft')
+ end
+
+ it "can show the edit button on an associated field" do
+ RailsAdmin.config Player do
+ edit do
+ field :team do
+ inline_edit true
+ end
+ field :draft do
+ inline_edit true
+ end
+ end
+ end
+ visit new_path(:model_name => "player")
+ should have_selector('a', :text => 'Edit this Team')
+ should have_selector('a', :text => 'Edit this Draft')
+ end
+
end
describe "bindings" do
@@ -1023,4 +1096,5 @@ def color_enum
should have_selector(".color_type input")
end
end
+
end
Oops, something went wrong.

0 comments on commit e596b6b

Please sign in to comment.