ab_admin 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/app/assets/javascripts/ab_admin/components/admin_assets.js.coffee +1 -1
  4. data/app/assets/javascripts/ab_admin/components/locator.js.coffee +2 -0
  5. data/app/assets/javascripts/ab_admin/components/select2_bridge.js.coffee +8 -7
  6. data/app/assets/javascripts/ab_admin/core/confirmation.js.coffee +1 -1
  7. data/app/assets/javascripts/ab_admin/core/init.js.coffee +6 -5
  8. data/app/assets/javascripts/ab_admin/core/utils.js.coffee +2 -2
  9. data/app/assets/stylesheets/ab_admin/{application.css.scss → application.scss} +0 -0
  10. data/app/assets/stylesheets/ab_admin/{bootstrap_and_overrides.css.scss → bootstrap_and_overrides.scss} +0 -0
  11. data/app/assets/stylesheets/ab_admin/components/{_admin_comments.css.scss → _admin_comments.scss} +0 -0
  12. data/app/assets/stylesheets/ab_admin/components/{_base.css.scss → _base.scss} +0 -0
  13. data/app/assets/stylesheets/ab_admin/components/{_colored_tabs.css.scss → _colored_tabs.scss} +0 -0
  14. data/app/assets/stylesheets/ab_admin/components/{_columns_hider.css.scss → _columns_hider.scss} +0 -0
  15. data/app/assets/stylesheets/ab_admin/components/{_form.css.scss → _form.scss} +0 -0
  16. data/app/assets/stylesheets/ab_admin/components/{_geo_input.css.scss → _geo_input.scss} +0 -0
  17. data/app/assets/stylesheets/ab_admin/components/{_grid_view.css.scss → _grid_view.scss} +0 -0
  18. data/app/assets/stylesheets/ab_admin/components/{_locale_tabs.css.scss → _locale_tabs.scss} +0 -0
  19. data/app/assets/stylesheets/ab_admin/components/{_navigation.css.scss → _navigation.scss} +0 -0
  20. data/app/assets/stylesheets/ab_admin/components/{_perms.css.scss → _perms.scss} +0 -0
  21. data/app/assets/stylesheets/ab_admin/components/{_table_view.css.scss → _table_view.scss} +0 -0
  22. data/app/assets/stylesheets/ab_admin/components/{_translations.css.scss → _translations.scss} +0 -0
  23. data/app/assets/stylesheets/ab_admin/components/{_tree_view.css.scss → _tree_view.scss} +0 -0
  24. data/app/assets/stylesheets/ab_admin/components/{_view_layout.css.scss → _view_layout.scss} +0 -0
  25. data/app/assets/stylesheets/ab_admin/{devise.css.scss → devise.scss} +0 -0
  26. data/app/assets/stylesheets/ab_admin/{fileupload.css.scss → fileupload.scss} +0 -0
  27. data/app/assets/stylesheets/ab_admin/{main.css.scss → main.scss} +0 -0
  28. data/app/controllers/admin/base_controller.rb +26 -11
  29. data/app/views/admin/admin_comments/_comment.html.slim +1 -1
  30. data/app/views/admin/base/_search_layout.html.slim +5 -6
  31. data/app/views/admin/base/index.html.slim +9 -10
  32. data/app/views/admin/fileupload/_container.html.slim +2 -1
  33. data/app/views/admin/locators/edit.html.slim +2 -2
  34. data/app/views/admin/locators/show.html.slim +2 -2
  35. data/app/views/admin/manager/_table.html.slim +2 -2
  36. data/app/views/admin/settings/_form.html.slim +3 -2
  37. data/app/views/admin/shared/_content_actions.html.slim +1 -1
  38. data/app/views/admin/shared/_flash.js.erb +2 -2
  39. data/config/routes.rb +13 -13
  40. data/lib/ab_admin.rb +13 -0
  41. data/lib/ab_admin/abstract_resource.rb +0 -4
  42. data/lib/ab_admin/concerns/admin_addition.rb +5 -1
  43. data/lib/ab_admin/concerns/has_tracking.rb +1 -1
  44. data/lib/ab_admin/concerns/utilities.rb +2 -1
  45. data/lib/ab_admin/devise.rb +0 -2
  46. data/lib/ab_admin/engine.rb +0 -1
  47. data/lib/ab_admin/hooks.rb +1 -1
  48. data/lib/ab_admin/hooks/globalize_locale_suffix_accessors.rb +29 -2
  49. data/lib/ab_admin/i18n_tools/model_translator.rb +1 -1
  50. data/lib/ab_admin/menu/group.rb +10 -1
  51. data/lib/ab_admin/menu/item.rb +5 -4
  52. data/lib/ab_admin/models/asset.rb +2 -1
  53. data/lib/ab_admin/models/settings.rb +24 -22
  54. data/lib/ab_admin/models/user.rb +8 -4
  55. data/lib/ab_admin/utils.rb +4 -4
  56. data/lib/ab_admin/utils/logger.rb +1 -1
  57. data/lib/ab_admin/version.rb +1 -1
  58. data/lib/ab_admin/views/admin_helpers.rb +4 -0
  59. data/lib/ab_admin/views/admin_navigation_helpers.rb +1 -0
  60. data/lib/ab_admin/views/inputs/ckeditor_input.rb +1 -1
  61. data/lib/ab_admin/views/inputs/color_input.rb +1 -1
  62. data/lib/ab_admin/views/inputs/date_time_picker_input.rb +1 -3
  63. data/lib/ab_admin/views/inputs/editor_input.rb +1 -1
  64. data/lib/ab_admin/views/inputs/token_input.rb +1 -3
  65. data/lib/ab_admin/views/inputs/uploader_input.rb +2 -2
  66. data/lib/ab_admin/views/search_form_builder.rb +23 -12
  67. data/lib/generators/ab_admin/install/install_generator.rb +0 -2
  68. data/lib/generators/ab_admin/install/templates/config/ab_admin.rb.erb +3 -5
  69. data/lib/generators/ab_admin/install/templates/config/nginx.conf +2 -1
  70. data/lib/generators/template.rb +2 -6
  71. metadata +29 -31
  72. data/lib/generators/ab_admin/install/templates/config/unicorn/production.rb +0 -49
  73. data/lib/generators/ab_admin/install/templates/script/unicorn.sh +0 -75
@@ -24,7 +24,7 @@ module AbAdmin
24
24
 
25
25
  module ClassMethods
26
26
  def tracking_enabled?
27
- tracking_enabled && Activity.tracking_enabled
27
+ tracking_enabled && Track.tracking_enabled
28
28
  end
29
29
  end
30
30
  end
@@ -20,7 +20,7 @@ module AbAdmin
20
20
  def full_truncate(with_destroy=true)
21
21
  destroy_all if with_destroy
22
22
  truncate!
23
- const_get(:Translation).truncate! if respond_to?(:translates?) && translates?
23
+ const_get(:Translation).truncate! if try!(:translates?)
24
24
  end
25
25
 
26
26
  def all_ids
@@ -90,6 +90,7 @@ module AbAdmin
90
90
  end
91
91
 
92
92
  def all_columns_names
93
+ ActiveSupport::Deprecation.warn('#all_columns_names is deprecated without replacement')
93
94
  if translates?
94
95
  column_names + all_translated_attribute_names + translated_attribute_names.map(&:to_s)
95
96
  else
@@ -2,7 +2,6 @@ require 'devise'
2
2
 
3
3
  module AbAdmin
4
4
  module Devise
5
-
6
5
  def self.config
7
6
  {
8
7
  controllers: {
@@ -35,6 +34,5 @@ module AbAdmin
35
34
  class PasswordsController < ::Devise::PasswordsController
36
35
  include ::AbAdmin::Devise::Controller
37
36
  end
38
-
39
37
  end
40
38
  end
@@ -30,7 +30,6 @@ module AbAdmin
30
30
  ActionController::Base.helper AbAdmin::Views::AdminNavigationHelpers
31
31
  ActionController::Base.helper AbAdmin::Views::ManagerHelpers
32
32
  end
33
-
34
33
  end
35
34
  end
36
35
  end
@@ -1,7 +1,7 @@
1
1
  #
2
2
  # ***** IMPORTANT *****
3
3
  #
4
- # This file contains some monkeypatching staff and is not required by default.
4
+ # This file requires hook files with some monkeypatching staff and it is not required by default.
5
5
  # Please, read code and comments before usage.
6
6
  #
7
7
  Dir["#{File.dirname(__FILE__)}/hooks/*.rb"].sort.each do |path|
@@ -1,14 +1,20 @@
1
1
  # add accessors with locale suffix like `title_en`, `title_de`
2
2
  Globalize::ActiveRecord::ClassMethods.module_eval do
3
3
  def define_translations_reader_with_locale_suffix(name)
4
+ translation_attributes = class_variable_defined?(:@@translation_attributes) ? class_variable_get(:@@translation_attributes) : []
5
+
4
6
  define_translations_reader_without_locale_suffix(name)
5
7
 
6
8
  Globalize.available_locales.each do |locale|
7
- define_method :"#{name}_#{locale}" do
9
+ method_name = "#{name}_#{locale}"
10
+ define_method method_name.to_sym do
8
11
  read_attribute(name, {locale: locale})
9
12
  end
13
+ translation_attributes.push(method_name)
10
14
  end
15
+ class_variable_set(:@@translation_attributes, translation_attributes)
11
16
  end
17
+
12
18
  alias_method_chain :define_translations_reader, :locale_suffix
13
19
 
14
20
  def define_translations_writer_with_locale_suffix(name)
@@ -16,12 +22,33 @@ Globalize::ActiveRecord::ClassMethods.module_eval do
16
22
 
17
23
  Globalize.available_locales.each do |locale|
18
24
  define_method :"#{name}_#{locale}=" do |value|
19
- changed_attributes[:"#{name}_#{locale}"] = value unless value == read_attribute(name, {locale: locale})
25
+ changed_attributes
26
+ @changed_attributes[:"#{name}_#{locale}"] = value unless value == read_attribute(name, {locale: locale})
20
27
  write_attribute(name, value, {locale: locale})
21
28
  end
22
29
  end
23
30
  end
31
+
24
32
  alias_method_chain :define_translations_writer, :locale_suffix
25
33
  end
26
34
 
35
+ Globalize::ActiveRecord::InstanceMethods.module_eval do
36
+ private
37
+
38
+ # Filters translation attributes from the attribute names.
39
+ def attributes_for_update(attribute_names)
40
+ filter_translation_attributes(super)
41
+ end
42
+
43
+ # Filters translation attributes from the attribute names.
44
+ def attributes_for_create(attribute_names)
45
+ filter_translation_attributes(super)
46
+ end
47
+
48
+ def filter_translation_attributes(attributes)
49
+ translation_attributes = self.class.class_variable_get(:@@translation_attributes)
50
+ attributes.delete_if { |attr| translation_attributes.include? attr }
51
+ end
52
+ end
53
+
27
54
  Globalize::ActiveRecord::Translation.attr_accessible :locale
@@ -26,7 +26,7 @@ module AbAdmin
26
26
  }
27
27
  @models_i18n_hash[locale]['activerecord']['models'][model.model_name.i18n_key.to_s]= model_i18n
28
28
  attributes = model.columns.map(&:name)
29
- attributes.concat(model.translated_attribute_names.map(&:to_s)) if model.translates?
29
+ attributes.concat(model.translated_attribute_names.map(&:to_s)) if model.try!(:translates?)
30
30
  attributes.reject! { |el| IGNORE_COLUMNS.include?(el) }
31
31
  h[model.model_name.i18n_key.to_s] = attributes.each_with_object({}) do |attr, o|
32
32
  o[attr] = ha(model, attr, locale).presence || attr
@@ -14,11 +14,20 @@ module AbAdmin
14
14
 
15
15
  <<-HTML.html_safe
16
16
  <li class="dropdown">
17
- <a class="dropdown-toggle" href="#{@options[:url] || '#'}" >#{@title}<b class="caret"></b></a>
17
+ <a class="dropdown-toggle" href="#{@options[:url] || '#'}" >#{title(template)}<b class="caret"></b></a>
18
18
  <ul class="dropdown-menu">#{render_nested(template)}</ul>
19
19
  <li>
20
20
  HTML
21
21
  end
22
+
23
+ private
24
+
25
+ def title(template)
26
+ return @title unless @options[:badge]
27
+ badge = call_method_or_proc_on(template, @options[:badge])
28
+ return @title if !badge || badge == 0
29
+ "#{@title}&nbsp;<span class='badge badge-#{@options[:badge_type] || 'important'}'>#{badge}</span>".html_safe
30
+ end
22
31
  end
23
32
  end
24
33
  end
@@ -24,10 +24,11 @@ module AbAdmin
24
24
  private
25
25
 
26
26
  def title(template)
27
- return @title unless @options[:badge_counter]
28
- badge_counter = call_method_or_proc_on(template, @options[:badge_counter])
29
- return @title if !badge_counter || badge_counter.zero?
30
- "#{@title}&nbsp;<span class='badge badge-#{@options[:badge_type] || 'important'}'>#{badge_counter}</span>".html_safe
27
+ ActiveSupport::Deprecation.warn('Menu item :badge_counter option is deprecated, use :badge instead') if @options[:badge_counter]
28
+ return @title unless @options[:badge]
29
+ badge = call_method_or_proc_on(template, @options[:badge])
30
+ return @title if !badge || badge == 0
31
+ "#{@title}&nbsp;<span class='badge badge-#{@options[:badge_type] || 'important'}'>#{badge}</span>".html_safe
31
32
  end
32
33
  end
33
34
  end
@@ -48,7 +48,8 @@ module AbAdmin
48
48
  end
49
49
 
50
50
  def thumb_url
51
- data.url(self.thumb_size) if image?
51
+ return unless image?
52
+ data.versions[thumb_size] ? data.url(thumb_size) : data.url
52
53
  end
53
54
 
54
55
  def format_created_at
@@ -27,17 +27,28 @@ module AbAdmin
27
27
 
28
28
  def initialize
29
29
  @data = {}
30
- @editable_path = find_editable_path
31
30
  @paths = find_paths
32
31
  end
33
32
 
34
- def find_editable_path
35
- path = editable_paths.detect { |path| File.exists?(path) }
36
- path or raise("Create settings file for editing: #{editable_paths.join(' or ')}")
33
+ def editable
34
+ return {} unless editable_path
35
+ YAML.load_file(editable_path) rescue {}
37
36
  end
38
37
 
39
- def find_paths
40
- base_paths.dup.unshift(@editable_path).find_all { |path| File.exists?(path) }
38
+ def save(raw_config)
39
+ config = {}
40
+ raw_config.each do |root_key, root_value|
41
+ if root_value.is_a?(Hash)
42
+ config[root_key] ||= {}
43
+ root_value.each do |key, value|
44
+ config[root_key][key] = typecast_value(value)
45
+ end
46
+ else
47
+ config[root_key] = typecast_value(root_value)
48
+ end
49
+ end
50
+ return unless editable_path
51
+ File.open(editable_path, 'w') { |file| file.write config.to_yaml } and self.class.load_config
41
52
  end
42
53
 
43
54
  def all
@@ -47,26 +58,17 @@ module AbAdmin
47
58
  @data
48
59
  end
49
60
 
50
- def editable
51
- YAML.load_file(@editable_path) rescue {}
61
+ private
62
+
63
+ def editable_path
64
+ @editable_path ||= editable_paths.detect { |path| File.exists?(path) }
52
65
  end
53
66
 
54
- def save(raw_config)
55
- conf = {}
56
- raw_config.each do |root_key, root_value|
57
- if root_value.is_a?(Hash)
58
- conf[root_key] ||= {}
59
- root_value.each do |key, value|
60
- conf[root_key][key] = case_value(value)
61
- end
62
- else
63
- conf[root_key] = case_value(root_value)
64
- end
65
- end
66
- File.open(@editable_path, 'w') { |file| file.write conf.to_yaml } and self.class.load_config
67
+ def find_paths
68
+ base_paths.dup.unshift(editable_path).compact.find_all { |path| File.exists?(path) }
67
69
  end
68
70
 
69
- def case_value(value)
71
+ def typecast_value(value)
70
72
  if %w(true false).include?(value) || value.to_s.is_number?
71
73
  YAML::load(value)
72
74
  else
@@ -47,10 +47,6 @@ module AbAdmin
47
47
  raw_password
48
48
  end
49
49
 
50
- def moderator?
51
- has_role?(:admin) || has_role?(:moderator)
52
- end
53
-
54
50
  def admin_access?
55
51
  moderator?
56
52
  end
@@ -59,6 +55,14 @@ module AbAdmin
59
55
  has_role?(:default)
60
56
  end
61
57
 
58
+ def redactor?
59
+ has_role?(:redactor)
60
+ end
61
+
62
+ def moderator?
63
+ has_role?(:admin) || has_role?(:moderator)
64
+ end
65
+
62
66
  def admin?
63
67
  has_role?(:admin)
64
68
  end
@@ -59,7 +59,7 @@ module AbAdmin
59
59
  # normalized to: "<p>div content</p><p>p content</p>"
60
60
  def normalize_html(raw_html, options = {}, &block)
61
61
  @@sanitizer ||= Sanitizer.new(options)
62
- @@sanitizer.normalize_html(raw_html, &block)
62
+ @@sanitizer.normalize_html(raw_html, options[:sanitize] || {}, &block)
63
63
  end
64
64
 
65
65
  def url_helpers
@@ -93,10 +93,10 @@ module AbAdmin
93
93
  @options = options
94
94
  end
95
95
 
96
- def normalize_html(raw_html)
96
+ def normalize_html(raw_html, options = {})
97
97
  return '' if raw_html.blank?
98
98
  cleaned_html = raw_html.gsub(CLEAN_HTML_COMMENTS_REGEXP, '')#.gsub(CLEAN_LINE_BREAKS_REGEXP, '<br/>')
99
- html = sanitize(cleaned_html, @options[:sanitize] || {})
99
+ html = sanitize(cleaned_html, options || {})
100
100
  doc = Nokogiri::HTML.fragment(html)
101
101
  #doc.xpath('comment()').each { |c| c.remove }
102
102
  yield doc if block_given?
@@ -142,7 +142,7 @@ module AbAdmin
142
142
  end
143
143
 
144
144
  def friendly_token(n=10)
145
- SecureRandom.base64(16).tr('+/=', 'xyz').first(n)
145
+ SecureRandom.base64(n * 2).tr('+/=', 'xyz').first(n)
146
146
  end
147
147
  end
148
148
  end
@@ -6,7 +6,7 @@ module AbAdmin
6
6
  def exception(e, options={})
7
7
  message = "#{e.message} #{"DATA:#{options[:data].inspect}" if options && options[:data]}"
8
8
  backtrace = e.backtrace.map { |l| "#{' ' * 2}#{l}" }.join("\n")
9
- error("#{message}\n#{backtrace}\n\n")
9
+ error("#{e.class} #{message}\n#{backtrace}\n\n")
10
10
  end
11
11
 
12
12
  def reopen
@@ -1,3 +1,3 @@
1
1
  module AbAdmin
2
- VERSION = '0.5.0'
2
+ VERSION = '0.6.0'
3
3
  end
@@ -133,6 +133,10 @@ module AbAdmin
133
133
  image_tag_if(item.send(assoc).try(:url, size))
134
134
  end
135
135
 
136
+ def per_page_variants
137
+ AbAdmin.per_page_variants.map{|variant| [variant, max_per_page].min }.uniq
138
+ end
139
+
136
140
  # input_set 'title', legend_class: 'do_sort', label_class: 'label-info' do
137
141
  def input_set(title, options={}, &block)
138
142
  options.reverse_merge!(class: "inputs well well-small clearfix #{options.delete(:legend_class) || 'do_sort'}", id: options.delete(:legend_id))
@@ -10,6 +10,7 @@ module AbAdmin
10
10
  options[:html][:class] ||= 'pjax-form'
11
11
  options[:builder] ||= ::AbAdmin::Views::SearchFormBuilder
12
12
  options[:method] ||= :get
13
+ options[:as] ||= 'q'
13
14
  form_for([:admin, object].flatten, *(args << options), &block)
14
15
  end
15
16
 
@@ -2,7 +2,7 @@ module AbAdmin
2
2
  module Views
3
3
  module Inputs
4
4
  class CkeditorInput < ::SimpleForm::Inputs::Base
5
- def input
5
+ def input(wrapper_options=nil)
6
6
  unless @builder.template.instance_variable_get(:@ckeditor_init)
7
7
  @builder.template.concat @builder.template.javascript_include_tag('/javascripts/ckeditor/init')
8
8
  @builder.template.instance_variable_set(:@ckeditor_init, true)
@@ -2,7 +2,7 @@ module AbAdmin
2
2
  module Views
3
3
  module Inputs
4
4
  class ColorInput < ::SimpleForm::Inputs::Base
5
- def input
5
+ def input(wrapper_options=nil)
6
6
  value = @builder.object[attribute_name].to_s.sub(/^#|/, '#')
7
7
  name = "#{@builder.object_name}[#{attribute_name}]"
8
8
  @builder.template.tag(:input, input_html_options.merge(type: 'color', name: name, value: value))
@@ -2,8 +2,7 @@ module AbAdmin
2
2
  module Views
3
3
  module Inputs
4
4
  class DateTimePickerInput < ::SimpleForm::Inputs::Base
5
-
6
- def input
5
+ def input(wrapper_options=nil)
7
6
  input_html_options[:value] ||= formated_value
8
7
  input_html_classes << input_type
9
8
  @builder.text_field(attribute_name, input_html_options)
@@ -38,7 +37,6 @@ module AbAdmin
38
37
  "#{attribute_name}_4i"
39
38
  end
40
39
  end
41
-
42
40
  end
43
41
  end
44
42
  end
@@ -2,7 +2,7 @@ module AbAdmin
2
2
  module Views
3
3
  module Inputs
4
4
  class EditorInput < ::SimpleForm::Inputs::TextInput
5
- def input
5
+ def input(wrapper_options=nil)
6
6
  input_html_options[:class] = "#{Array(input_html_options[:class]).join(' ')} do_wysihtml5"
7
7
  super
8
8
  end
@@ -2,14 +2,12 @@ module AbAdmin
2
2
  module Views
3
3
  module Inputs
4
4
  class TokenInput < ::SimpleForm::Inputs::StringInput
5
-
6
- def input
5
+ def input(wrapper_options=nil)
7
6
  attr = options.delete(:assoc) || attribute_name.to_s.sub(/^token_|_id$/, '')
8
7
  token_data = object.token_data(attr.to_sym, options.extract!(:geo_order, :c, :sortable))
9
8
  input_html_options.reverse_deep_merge!(token_data)
10
9
  super
11
10
  end
12
-
13
11
  end
14
12
  end
15
13
  end
@@ -11,17 +11,17 @@ module AbAdmin
11
11
  file_type: 'image',
12
12
  container_id: "#{attribute_name}_#{object.fileupload_guid}",
13
13
  multiple: @assoc.collection?,
14
- extensions: @assoc.klass.ext_list,
15
14
  max_size: @assoc.klass.try(:max_size),
16
15
  error: @builder.error(attribute_name)
17
16
  }
18
17
  @options.reverse_merge!(defaults)
18
+ @options[:extensions] = @assoc.klass.ext_list if @assoc.klass.ext_list
19
19
  @options[:sortable] = @options[:multiple] unless @options.has_key?(:sortable)
20
20
  @options[:asset_template] ||= @options[:file_type]
21
21
  @options[:container_class] = container_class
22
22
  end
23
23
 
24
- def input
24
+ def input(wrapper_options=nil)
25
25
  title = options[:title] || object.class.han(attribute_name)
26
26
  template.capture do
27
27
  if @options[:unwrapped]
@@ -8,7 +8,7 @@ module AbAdmin
8
8
  def input(attr, options={})
9
9
  field_type = field_type(attr, options)
10
10
  content_tag :div, class: "clearfix #{field_type} #{options[:wrapper_class]}" do
11
- send("#{field_type}_field", attr, options)
11
+ public_send("#{field_type}_field", attr, options)
12
12
  end
13
13
  end
14
14
 
@@ -89,18 +89,14 @@ module AbAdmin
89
89
  end
90
90
 
91
91
  def presence_field(attr, options={})
92
- content_tag(:div, class: 'pull-left') do
93
- content_tag(:label, class: 'checkbox inline') do
94
- param = "#{attr}_present"
95
- check_box_tag("q[#{param}]", 1, params[:q][param].to_i == 1, class: 'inline', id: "q_#{attr}") + I18n.t('simple_form.yes')
96
- end +
97
- content_tag(:label, class: 'checkbox inline') do
98
- param = "#{attr}_null"
99
- check_box_tag("q[#{param}]", 1, params[:q][param].to_i == 1, class: 'inline') + I18n.t('simple_form.no')
100
- end
101
- end + label(attr, options[:label], class: 'right-label')
92
+ yes_no_field(attr, {yes: %w(present 1), no: %w(present 0)}, options)
102
93
  end
103
94
 
95
+ def null_field(attr, options={})
96
+ yes_no_field(attr, {yes: %w(null 0), no: %w(null 1)}, options)
97
+ end
98
+
99
+
104
100
  def hidden_field(attr, options={})
105
101
  hidden_field_tag("q[#{attr}_eq]", options[:value], options)
106
102
  end
@@ -119,7 +115,7 @@ module AbAdmin
119
115
  if input_type
120
116
  return :select if options[:collection]
121
117
  return :string if input_type == :text
122
- elsif @object.klass.translates? && @object.klass.translated?(attr)
118
+ elsif @object.klass.try!(:translates?) && @object.klass.translated?(attr)
123
119
  options[:value_attr] = "translations_#{attr}"
124
120
  return :string
125
121
  elsif assoc = @object.klass.reflect_on_association(attr.to_sym)
@@ -137,6 +133,21 @@ module AbAdmin
137
133
  input_type or raise "No available input type for #{attr}"
138
134
  end
139
135
  end
136
+
137
+ private
138
+
139
+ def yes_no_field(attr, predicates, options={})
140
+ content_tag(:div, class: 'pull-left') do
141
+ content_tag(:label, class: 'checkbox inline') do
142
+ param = "#{attr}_#{predicates[:yes][0]}"
143
+ check_box_tag("q[#{param}]", predicates[:yes][1], params[:q][param] == predicates[:yes][1], class: 'inline', id: "q_#{attr}") + I18n.t('simple_form.yes')
144
+ end +
145
+ content_tag(:label, class: 'checkbox inline') do
146
+ param = "#{attr}_#{predicates[:no][0]}"
147
+ check_box_tag("q[#{param}]", predicates[:no][1], params[:q][param] == predicates[:no][1], class: 'inline') + I18n.t('simple_form.no')
148
+ end
149
+ end + label(attr, options[:label], class: 'right-label')
150
+ end
140
151
  end
141
152
  end
142
153
  end