ab_admin 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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