andrewroth_activeadmin 0.3.4 → 0.3.4.1

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 (201) hide show
  1. data/CHANGELOG.md +159 -3
  2. data/CONTRIBUTING.md +113 -0
  3. data/LICENSE +1 -1
  4. data/README.rdoc +19 -20
  5. data/activeadmin.gemspec +3 -1
  6. data/app/assets/javascripts/active_admin/application.js +9 -0
  7. data/app/assets/javascripts/active_admin/base.js +4 -12
  8. data/app/assets/stylesheets/active_admin/_base.css.scss +16 -340
  9. data/app/assets/stylesheets/active_admin/_forms.css.scss +13 -7
  10. data/app/assets/stylesheets/active_admin/_header.css.scss +23 -4
  11. data/app/assets/stylesheets/active_admin/components/_blank_slates.scss +31 -0
  12. data/app/assets/stylesheets/active_admin/components/_breadcrumbs.scss +20 -0
  13. data/app/assets/stylesheets/active_admin/components/_buttons.scss +12 -0
  14. data/app/assets/stylesheets/active_admin/components/_flash_messages.css.scss +2 -0
  15. data/app/assets/stylesheets/active_admin/components/_grid.scss +9 -0
  16. data/app/assets/stylesheets/active_admin/components/_links.scss +5 -0
  17. data/app/assets/stylesheets/active_admin/components/_pagination.scss +34 -0
  18. data/app/assets/stylesheets/active_admin/components/_panels.scss +6 -0
  19. data/app/assets/stylesheets/active_admin/components/_scopes.scss +10 -0
  20. data/app/assets/stylesheets/active_admin/components/_status_tags.scss +12 -0
  21. data/app/assets/stylesheets/active_admin/components/_table_tools.css.scss +101 -0
  22. data/app/assets/stylesheets/active_admin/mixins/_all.css.scss +2 -1
  23. data/app/assets/stylesheets/active_admin/mixins/_buttons.css.scss +50 -13
  24. data/app/assets/stylesheets/active_admin/mixins/_gradients.css.scss +9 -1
  25. data/app/assets/stylesheets/active_admin/mixins/_sections.css.scss +7 -5
  26. data/app/assets/stylesheets/active_admin/mixins/_shadows.css.scss +1 -0
  27. data/app/assets/stylesheets/active_admin/mixins/_typography.scss +3 -0
  28. data/app/assets/stylesheets/active_admin/mixins/_variables.css.scss +1 -0
  29. data/app/assets/stylesheets/active_admin/pages/_dashboard.scss +5 -0
  30. data/app/assets/stylesheets/active_admin/pages/_logged_out.scss +44 -0
  31. data/app/assets/stylesheets/active_admin/structure/_footer.scss +14 -0
  32. data/app/assets/stylesheets/active_admin/structure/_main_structure.scss +26 -0
  33. data/app/assets/stylesheets/active_admin/structure/_title_bar.scss +44 -0
  34. data/app/views/active_admin/devise/passwords/edit.html.erb +1 -1
  35. data/app/views/active_admin/devise/passwords/new.html.erb +1 -1
  36. data/app/views/active_admin/devise/sessions/new.html.erb +1 -1
  37. data/app/views/active_admin/devise/shared/_links.erb +1 -1
  38. data/app/views/active_admin/devise/unlocks/new.html.erb +1 -1
  39. data/app/views/active_admin/page/index.html.arb +1 -0
  40. data/app/views/layouts/active_admin_logged_out.html.erb +2 -2
  41. data/cucumber.yml +3 -2
  42. data/docs/1-general-configuration.md +46 -10
  43. data/docs/6-show-screens.md +7 -0
  44. data/docs/8-custom-actions.md +12 -2
  45. data/docs/9-custom-pages.md +84 -0
  46. data/features/belongs_to.feature +27 -0
  47. data/features/comments/commenting.feature +3 -2
  48. data/features/dashboard.feature +18 -0
  49. data/features/development_reloading.feature +19 -0
  50. data/features/index/filter_with_check_boxes.feature +25 -0
  51. data/features/index/index_as_table.feature +14 -0
  52. data/features/index/index_scopes.feature +42 -0
  53. data/features/index/pagination.feature +19 -1
  54. data/features/menu.feature +22 -2
  55. data/features/registering_assets.feature +2 -2
  56. data/features/registering_pages.feature +66 -0
  57. data/features/specifying_actions.feature +5 -0
  58. data/features/step_definitions/action_item_steps.rb +2 -6
  59. data/features/step_definitions/action_link_steps.rb +7 -0
  60. data/features/step_definitions/additional_web_steps.rb +8 -0
  61. data/features/step_definitions/asset_steps.rb +5 -1
  62. data/features/step_definitions/breadcrumb_steps.rb +5 -0
  63. data/features/step_definitions/configuration_steps.rb +56 -8
  64. data/features/step_definitions/dashboard_steps.rb +5 -1
  65. data/features/step_definitions/factory_steps.rb +9 -2
  66. data/features/step_definitions/flash_steps.rb +9 -1
  67. data/features/step_definitions/index_scope_steps.rb +16 -4
  68. data/features/step_definitions/member_link_steps.rb +7 -0
  69. data/features/step_definitions/site_title_steps.rb +15 -0
  70. data/features/support/paths.rb +6 -0
  71. data/features/users/logging_out.feature +11 -0
  72. data/lib/active_admin.rb +25 -10
  73. data/lib/active_admin/application.rb +63 -20
  74. data/lib/active_admin/arbre/html/element.rb +10 -0
  75. data/lib/active_admin/asset_registration.rb +15 -2
  76. data/lib/active_admin/base_controller.rb +61 -0
  77. data/lib/active_admin/{resource_controller → base_controller}/menu.rb +1 -1
  78. data/lib/active_admin/comments.rb +48 -54
  79. data/lib/active_admin/comments/comment.rb +13 -2
  80. data/lib/active_admin/comments/namespace_helper.rb +1 -1
  81. data/lib/active_admin/comments/views/active_admin_comments.rb +7 -3
  82. data/lib/active_admin/dashboards.rb +4 -0
  83. data/lib/active_admin/dashboards/dashboard_controller.rb +20 -4
  84. data/lib/active_admin/dsl.rb +6 -159
  85. data/lib/active_admin/event.rb +5 -3
  86. data/lib/active_admin/filter_form_builder.rb +53 -0
  87. data/lib/active_admin/form_builder.rb +25 -19
  88. data/lib/active_admin/inputs.rb +14 -0
  89. data/lib/active_admin/inputs/datepicker_input.rb +11 -0
  90. data/lib/active_admin/inputs/filter_base.rb +46 -0
  91. data/lib/active_admin/inputs/filter_check_boxes_input.rb +40 -0
  92. data/lib/active_admin/inputs/filter_date_range_input.rb +34 -0
  93. data/lib/active_admin/inputs/filter_numeric_input.rb +55 -0
  94. data/lib/active_admin/inputs/filter_select_input.rb +23 -0
  95. data/lib/active_admin/inputs/filter_string_input.rb +22 -0
  96. data/lib/active_admin/locales/ca.yml +44 -0
  97. data/lib/active_admin/locales/cs.yml +14 -10
  98. data/lib/active_admin/locales/de.yml +43 -0
  99. data/lib/active_admin/locales/en.yml +5 -0
  100. data/lib/active_admin/locales/hr.yml +40 -0
  101. data/lib/active_admin/locales/ko.yml +40 -0
  102. data/lib/active_admin/locales/lv.yml +43 -0
  103. data/lib/active_admin/locales/nl.yml +40 -0
  104. data/lib/active_admin/locales/no-NB.yml +40 -0
  105. data/lib/active_admin/locales/pl.yml +7 -1
  106. data/lib/active_admin/locales/pt-BR.yml +6 -2
  107. data/lib/active_admin/namespace.rb +48 -33
  108. data/lib/active_admin/page.rb +54 -0
  109. data/lib/active_admin/page_controller.rb +15 -0
  110. data/lib/active_admin/page_dsl.rb +21 -0
  111. data/lib/active_admin/page_presenter.rb +30 -0
  112. data/lib/active_admin/resource.rb +38 -44
  113. data/lib/active_admin/resource/action_items.rb +5 -0
  114. data/lib/active_admin/resource/belongs_to.rb +4 -2
  115. data/lib/active_admin/resource/controllers.rb +35 -0
  116. data/lib/active_admin/resource/menu.rb +1 -2
  117. data/lib/active_admin/resource/naming.rb +43 -31
  118. data/lib/active_admin/resource/page_presenters.rb +28 -0
  119. data/lib/active_admin/resource/scopes.rb +16 -3
  120. data/lib/active_admin/resource/sidebars.rb +4 -0
  121. data/lib/active_admin/resource_collection.rb +88 -0
  122. data/lib/active_admin/resource_controller.rb +18 -54
  123. data/lib/active_admin/resource_controller/action_builder.rb +1 -1
  124. data/lib/active_admin/resource_controller/actions.rb +1 -1
  125. data/lib/active_admin/resource_controller/callbacks.rb +1 -1
  126. data/lib/active_admin/resource_controller/collection.rb +8 -4
  127. data/lib/active_admin/resource_controller/filters.rb +1 -1
  128. data/lib/active_admin/resource_controller/resource_class_methods.rb +24 -0
  129. data/lib/active_admin/resource_controller/scoping.rb +1 -1
  130. data/lib/active_admin/resource_controller/sidebars.rb +1 -1
  131. data/lib/active_admin/resource_dsl.rb +157 -0
  132. data/lib/active_admin/router.rb +21 -14
  133. data/lib/active_admin/scope.rb +15 -3
  134. data/lib/active_admin/version.rb +1 -1
  135. data/lib/active_admin/view_factory.rb +4 -3
  136. data/lib/active_admin/view_helpers/auto_link_helper.rb +1 -10
  137. data/lib/active_admin/view_helpers/breadcrumb_helper.rb +25 -21
  138. data/lib/active_admin/view_helpers/filter_form_helper.rb +0 -150
  139. data/lib/active_admin/views/components/attributes_table.rb +1 -1
  140. data/lib/active_admin/views/components/paginated_collection.rb +42 -13
  141. data/lib/active_admin/views/components/scopes.rb +17 -17
  142. data/lib/active_admin/views/components/status_tag.rb +6 -5
  143. data/lib/active_admin/views/components/table_for.rb +6 -2
  144. data/lib/active_admin/views/header_renderer.rb +31 -12
  145. data/lib/active_admin/views/index_as_block.rb +2 -2
  146. data/lib/active_admin/views/index_as_blog.rb +3 -3
  147. data/lib/active_admin/views/index_as_grid.rb +4 -4
  148. data/lib/active_admin/views/index_as_table.rb +13 -6
  149. data/lib/active_admin/views/pages/base.rb +4 -4
  150. data/lib/active_admin/views/pages/form.rb +49 -0
  151. data/lib/active_admin/views/pages/index.rb +18 -6
  152. data/lib/active_admin/views/pages/page.rb +24 -0
  153. data/lib/active_admin/views/pages/show.rb +1 -1
  154. data/lib/generators/active_admin/assets/assets_generator.rb +19 -1
  155. data/lib/generators/active_admin/install/templates/active_admin.rb.erb +38 -12
  156. data/lib/generators/active_admin/install/templates/dashboards.rb +6 -0
  157. data/spec/spec_helper.rb +4 -0
  158. data/spec/support/rails_template.rb +11 -0
  159. data/spec/support/templates/cucumber_with_reloading.rb +5 -0
  160. data/spec/unit/active_admin_spec.rb +8 -0
  161. data/spec/unit/application_spec.rb +48 -2
  162. data/spec/unit/arbre/html/element_finder_methods_spec.rb +58 -2
  163. data/spec/unit/asset_registration_spec.rb +9 -3
  164. data/spec/unit/auto_link_spec.rb +2 -2
  165. data/spec/unit/base_controller_shared_examples.rb +28 -0
  166. data/spec/unit/base_controller_spec.rb +8 -0
  167. data/spec/unit/belongs_to_spec.rb +30 -33
  168. data/spec/unit/comments_spec.rb +45 -15
  169. data/spec/unit/config_shared_examples.rb +108 -0
  170. data/spec/unit/dashboard_controller_spec.rb +44 -0
  171. data/spec/unit/event_spec.rb +6 -0
  172. data/spec/unit/filter_form_builder_spec.rb +9 -0
  173. data/spec/unit/form_builder_spec.rb +8 -14
  174. data/spec/unit/namespace/register_page_spec.rb +102 -0
  175. data/spec/unit/namespace/register_resource_spec.rb +188 -0
  176. data/spec/unit/namespace_spec.rb +11 -183
  177. data/spec/unit/page_controller_spec.rb +8 -0
  178. data/spec/unit/page_spec.rb +60 -0
  179. data/spec/unit/resource/menu_spec.rb +1 -51
  180. data/spec/unit/resource/naming_spec.rb +24 -19
  181. data/spec/unit/resource/page_presenters_spec.rb +32 -0
  182. data/spec/unit/resource/scopes_spec.rb +13 -0
  183. data/spec/unit/resource_collection_spec.rb +101 -0
  184. data/spec/unit/resource_controller_spec.rb +40 -32
  185. data/spec/unit/{registration_spec.rb → resource_registration_spec.rb} +0 -0
  186. data/spec/unit/resource_spec.rb +8 -24
  187. data/spec/unit/routing_spec.rb +50 -1
  188. data/spec/unit/scope_spec.rb +18 -4
  189. data/spec/unit/views/components/paginated_collection_spec.rb +150 -0
  190. data/spec/unit/views/components/status_tag_spec.rb +9 -0
  191. data/tasks/test.rake +43 -27
  192. metadata +140 -31
  193. data/app/assets/javascripts/active_admin/vendor.js +0 -382
  194. data/lib/active_admin/comments/configuration.rb +0 -18
  195. data/lib/active_admin/page_config.rb +0 -15
  196. data/lib/active_admin/resource_controller/form.rb +0 -42
  197. data/lib/active_admin/resource_controller/page_configurations.rb +0 -53
  198. data/lib/active_admin/views/pages/edit.rb +0 -28
  199. data/lib/active_admin/views/pages/new.rb +0 -28
  200. data/lib/generators/active_admin/assets/templates/3.0/active_admin.js +0 -427
  201. data/spec/integration/belongs_to_spec.rb +0 -42
@@ -28,27 +28,33 @@ module ActiveAdmin
28
28
 
29
29
  # Now define the routes for each resource
30
30
  router.instance_exec(@application.namespaces) do |namespaces|
31
- resources = namespaces.values.collect{|n| n.resources.values }.flatten
31
+ resources = namespaces.values.collect{|n| n.resources.resources }.flatten
32
32
  resources.each do |config|
33
33
 
34
34
  # Define the block the will get eval'd within the namespace
35
35
  route_definition_block = Proc.new do
36
- resources config.underscored_resource_name.pluralize do
37
-
38
- # Define any member actions
39
- member do
40
- config.member_actions.each do |action|
41
- # eg: get :comment
42
- send(action.http_verb, action.name)
36
+ case config
37
+ when Resource
38
+ resources config.underscored_resource_name.pluralize do
39
+ # Define any member actions
40
+ member do
41
+ config.member_actions.each do |action|
42
+ # eg: get :comment
43
+ send(action.http_verb, action.name)
44
+ end
43
45
  end
44
- end
45
46
 
46
- # Define any collection actions
47
- collection do
48
- config.collection_actions.each do |action|
49
- send(action.http_verb, action.name)
47
+ # Define any collection actions
48
+ collection do
49
+ config.collection_actions.each do |action|
50
+ send(action.http_verb, action.name)
51
+ end
50
52
  end
51
53
  end
54
+ when Page
55
+ match "/#{config.underscored_resource_name}" => "#{config.underscored_resource_name}#index"
56
+ else
57
+ raise "Unsupported config class: #{config.class}"
52
58
  end
53
59
  end
54
60
 
@@ -60,7 +66,8 @@ module ActiveAdmin
60
66
  instance_eval &routes_for_belongs_to if config.belongs_to_config.optional?
61
67
 
62
68
  # Make the nested belongs_to routes
63
- resources config.belongs_to_config.target.underscored_resource_name.pluralize do
69
+ # :only is set to nothing so that we don't clobber any existing routes on the resource
70
+ resources config.belongs_to_config.target.underscored_resource_name.pluralize, :only => [] do
64
71
  instance_eval &routes_for_belongs_to
65
72
  end
66
73
  end
@@ -1,7 +1,7 @@
1
1
  module ActiveAdmin
2
2
  class Scope
3
3
 
4
- attr_reader :name, :scope_method, :id, :scope_block
4
+ attr_reader :name, :scope_method, :id, :scope_block, :display_if_block
5
5
 
6
6
  # Create a Scope
7
7
  #
@@ -13,11 +13,14 @@ module ActiveAdmin
13
13
  # Scope.new('Published', :public)
14
14
  # # => Scope with name 'Published' and scope method :public
15
15
  #
16
+ # Scope.new('Published', :public, :if => proc { current_admin_user.can?( :manage, active_admin_config.resource_class ) } ) { |articles| articles.where(:published => true) }
17
+ # # => Scope with name 'Published' and scope method :public, optionally displaying the scope per the :if block, using a block
18
+ #
16
19
  # Scope.new('Published') { |articles| articles.where(:published => true) }
17
20
  # # => Scope with name 'Published' using a block to scope
18
21
  #
19
- def initialize(name, method = nil, &block)
20
- @name = name.to_s.titleize
22
+ def initialize(name, method = nil, options = {}, &block)
23
+ @name = name.is_a?( String ) ? name : name.to_s.titleize
21
24
  @scope_method = method
22
25
  # Scope ':all' means no scoping
23
26
  @scope_method ||= name.to_sym unless name.to_sym == :all
@@ -26,6 +29,15 @@ module ActiveAdmin
26
29
  @scope_method = nil
27
30
  @scope_block = block
28
31
  end
32
+
33
+ @display_if_block = options[:if]
29
34
  end
35
+
36
+ # Returns the display if block. If the block was not explicitly defined
37
+ # a default block always returning true will be returned.
38
+ def display_if_block
39
+ @display_if_block || proc{ true }
40
+ end
41
+
30
42
  end
31
43
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveAdmin
2
- VERSION = '0.3.4'
2
+ VERSION = '0.3.4.1'
3
3
  end
@@ -15,9 +15,10 @@ module ActiveAdmin
15
15
  register :dashboard_page => ActiveAdmin::Views::Pages::Dashboard,
16
16
  :index_page => ActiveAdmin::Views::Pages::Index,
17
17
  :show_page => ActiveAdmin::Views::Pages::Show,
18
- :new_page => ActiveAdmin::Views::Pages::New,
19
- :edit_page => ActiveAdmin::Views::Pages::Edit,
20
- :layout => ActiveAdmin::Views::Pages::Layout
18
+ :new_page => ActiveAdmin::Views::Pages::Form,
19
+ :edit_page => ActiveAdmin::Views::Pages::Form,
20
+ :layout => ActiveAdmin::Views::Pages::Layout,
21
+ :page => ActiveAdmin::Views::Pages::Page
21
22
 
22
23
  end
23
24
  end
@@ -24,19 +24,10 @@ module ActiveAdmin
24
24
 
25
25
  # Returns the ActiveAdmin::Resource instance for a class
26
26
  def active_admin_resource_for(klass)
27
+ return nil unless respond_to?(:active_admin_namespace)
27
28
  active_admin_namespace.resource_for(klass)
28
29
  end
29
30
 
30
- # Returns the current Active Admin namespace
31
- def active_admin_namespace
32
- if respond_to?(:active_admin_config) && active_admin_config
33
- active_admin_config.namespace
34
- else
35
- # Return a default namespace if none exists
36
- active_admin_application.find_or_create_namespace(active_admin_application.default_namespace)
37
- end
38
- end
39
-
40
31
  end
41
32
  end
42
33
  end
@@ -2,27 +2,31 @@ module ActiveAdmin
2
2
  module ViewHelpers
3
3
  module BreadcrumbHelper
4
4
 
5
- # Returns an array of links to use in a breadcrumb
6
- def breadcrumb_links(path = nil)
7
- path ||= request.fullpath
8
- parts = path.gsub(/^\//, '').split('/')
9
- parts.pop unless %w{ create update }.include?(params[:action])
10
- crumbs = []
11
- parts.each_with_index do |part, index|
12
- name = ""
13
- if part =~ /^\d/ && parent = parts[index - 1]
14
- begin
15
- parent_class = parent.singularize.camelcase.constantize
16
- obj = parent_class.find(part.to_i)
17
- name = obj.display_name if obj.respond_to?(:display_name)
18
- rescue
19
- end
20
- end
21
- name = part.titlecase if name == ""
22
- crumbs << link_to(name, "/" + parts[0..index].join('/'))
23
- end
24
- crumbs
25
- end
5
+ # Returns an array of links to use in a breadcrumb
6
+ def breadcrumb_links(path = nil)
7
+ path ||= request.fullpath
8
+ parts = path.gsub(/^\//, '').split('/')
9
+ parts.pop unless %w{ create update }.include?(params[:action])
10
+ crumbs = []
11
+ parts.each_with_index do |part, index|
12
+ name = ""
13
+ if part =~ /^\d/ && parent = parts[index - 1]
14
+ begin
15
+ parent_class = parent.singularize.camelcase.constantize
16
+ obj = parent_class.find(part.to_i)
17
+ name = obj.display_name if obj.respond_to?(:display_name)
18
+ rescue
19
+ end
20
+ end
21
+ name = part.titlecase if name == ""
22
+ begin
23
+ crumbs << link_to( I18n.translate!("activerecord.models.#{part.singularize}", :count => 2), "/" + parts[0..index].join('/'))
24
+ rescue I18n::MissingTranslationData
25
+ crumbs << link_to( name, "/" + parts[0..index].join('/'))
26
+ end
27
+ end
28
+ crumbs
29
+ end
26
30
 
27
31
  end
28
32
  end
@@ -33,154 +33,4 @@ module ActiveAdmin
33
33
  end
34
34
  end
35
35
 
36
- # This form builder defines methods to build filter forms such
37
- # as the one found in the sidebar of the index page of a standard resource.
38
- class FilterFormBuilder < FormBuilder
39
-
40
- def filter(method, options = {})
41
- return "" if method.nil? || method == ""
42
- options[:as] ||= default_filter_type(method)
43
- return "" unless options[:as]
44
- field_type = options.delete(:as)
45
- options[:label] ||= default_filter_label(method)
46
- content = with_new_form_buffer do
47
- send("filter_#{field_type}_input", method, options)
48
- end
49
- @form_buffers.last << template.content_tag(:div, content, :class => "filter_form_field filter_#{field_type}")
50
- end
51
-
52
- protected
53
-
54
- def filter_string_input(method, options = {})
55
- field_name = "#{method}_contains"
56
-
57
- [ label(field_name, I18n.t('active_admin.search_field', :field => options[:label])),
58
- text_field(field_name)
59
- ].join("\n").html_safe
60
- end
61
-
62
- def filter_date_range_input(method, options = {})
63
- gt_field_name = "#{method}_gte"
64
- lt_field_name = "#{method}_lte"
65
-
66
- [ label(gt_field_name, options[:label]),
67
- filter_date_text_field(gt_field_name),
68
- template.content_tag(:span, "-", :class => "seperator"),
69
- filter_date_text_field(lt_field_name)
70
- ].join("\n").html_safe
71
- end
72
-
73
- def filter_date_text_field(method)
74
- current_value = @object.send(method)
75
- text_field(method, :size => 12, :class => "datepicker", :max => 10, :value => current_value.respond_to?(:strftime) ? current_value.strftime("%Y-%m-%d") : "")
76
- end
77
-
78
- def filter_numeric_input(method, options = {})
79
- filters = numeric_filters_for_method(method, options.delete(:filters) || default_numeric_filters)
80
- current_filter = current_numeric_scope(filters)
81
- filter_select = @template.select_tag '', @template.options_for_select(filters, current_filter),
82
- :onchange => "document.getElementById('#{method}_numeric').name = 'q[' + this.value + ']';"
83
- filter_input = text_field current_filter, :size => 10, :id => "#{method}_numeric"
84
-
85
- [ label(method, options[:label]),
86
- filter_select,
87
- " ",
88
- filter_input
89
- ].join("\n").html_safe
90
- end
91
-
92
- def numeric_filters_for_method(method, filters)
93
- filters.collect{|scope| [scope[0], [method,scope[1]].join("_") ] }
94
- end
95
-
96
- # Returns the scope for which we are currently searching. If no search is available
97
- # it returns the first scope
98
- def current_numeric_scope(filters)
99
- filters[1..-1].inject(filters.first){|a,b| object.send(b[1].to_sym) ? b : a }[1]
100
- end
101
-
102
- def default_numeric_filters
103
- [[I18n.t('active_admin.equal_to'), 'eq'], [I18n.t('active_admin.greater_than'), 'gt'], [I18n.t('active_admin.less_than'), 'lt']]
104
- end
105
-
106
- def filter_select_input(method, options = {})
107
- association_name = method.to_s.gsub(/_id$/, '').to_sym
108
- input_name = (generate_association_input_name(method).to_s + "_eq").to_sym
109
- collection = find_collection_for_column(association_name, options)
110
-
111
- [ label(input_name, options[:label]),
112
- select(input_name, collection, options.merge(:include_blank => I18n.t('active_admin.any')))
113
- ].join("\n").html_safe
114
- end
115
-
116
- def filter_check_boxes_input(method, options = {})
117
- input_name = (generate_association_input_name(method).to_s + "_in").to_sym
118
- collection = find_collection_for_column(method, options)
119
- selected_values = @object.send(input_name) || []
120
- checkboxes = template.content_tag :div, :class => "check_boxes_wrapper" do
121
- collection.map do |c|
122
- label = c.is_a?(Array) ? c.first : c
123
- value = c.is_a?(Array) ? c.last : c
124
- "<label><input type=\"checkbox\" name=\"q[#{input_name}][]\" value=\"#{value}\" #{selected_values.include?(value) ? "checked" : ""}/> #{label}</label>"
125
- end.join("\n").html_safe
126
- end
127
-
128
- [ label(input_name, options[:label]),
129
- checkboxes
130
- ].join("\n").html_safe
131
- end
132
-
133
- # Override the standard finder to accept a proc
134
- def find_collection_for_column(method, options = {})
135
- options = options.dup
136
- case options[:collection]
137
- when Proc
138
- options[:collection] = options[:collection].call
139
- end
140
- super(method, options)
141
- end
142
-
143
- # Returns the default filter type for a given attribute
144
- def default_filter_type(method)
145
- if column = column_for(method)
146
- case column.type
147
- when :date, :datetime
148
- return :date_range
149
- when :string, :text
150
- return :string
151
- when :integer
152
- return :select if reflection_for(method.to_s.gsub('_id','').to_sym)
153
- return :numeric
154
- when :float, :decimal
155
- return :numeric
156
- end
157
- end
158
-
159
- if reflection = reflection_for(method)
160
- return :select if reflection.macro == :belongs_to && !reflection.options[:polymorphic]
161
- end
162
- end
163
-
164
- # Returns the default label for a given attribute
165
- # Will use ActiveModel I18n if possible
166
- def default_filter_label(method)
167
- if @object.base.respond_to?(:human_attribute_name)
168
- @object.base.human_attribute_name(method)
169
- else
170
- method.to_s.titlecase
171
- end
172
- end
173
-
174
- # Returns the column for an attribute on the object being searched
175
- # if it exists. Otherwise returns nil
176
- def column_for(method)
177
- @object.base.columns_hash[method.to_s] if @object.base.respond_to?(:columns_hash)
178
- end
179
-
180
- # Returns the association reflection for the method if it exists
181
- def reflection_for(method)
182
- @object.base.reflect_on_association(method) if @object.base.respond_to?(:reflect_on_association)
183
- end
184
-
185
- end
186
36
  end
@@ -45,7 +45,7 @@ module ActiveAdmin
45
45
  def content_for(attr_or_proc)
46
46
  value = case attr_or_proc
47
47
  when Proc
48
- attr_or_proc.call
48
+ attr_or_proc.call(@record)
49
49
  else
50
50
  content_for_attribute(attr_or_proc)
51
51
  end
@@ -23,6 +23,7 @@ module ActiveAdmin
23
23
  class PaginatedCollection < ActiveAdmin::Component
24
24
  builder_method :paginated_collection
25
25
 
26
+ attr_reader :collection
26
27
 
27
28
  # Builds a new paginated collection component
28
29
  #
@@ -30,12 +31,21 @@ module ActiveAdmin
30
31
  # @param [Hash] options These options will be passed on to the page_entries_info
31
32
  # method.
32
33
  # Useful keys:
33
- # :entry_name - The name to display for this resource collection
34
+ # :entry_name - The name to display for this resource collection
35
+ # :param_name - Parameter name for page number in the links (:page by default)
36
+ # :download_links - Set to false to skip download format links
34
37
  def build(collection, options = {})
35
38
  @collection = collection
36
- div(page_entries_info(options).html_safe, :class => "pagination_information")
39
+ @param_name = options.delete(:param_name)
40
+ @download_links = options.delete(:download_links)
41
+
42
+ unless collection.respond_to?(:num_pages)
43
+ raise(StandardError, "Collection is not a paginated scope. Set collection.page(params[:page]).per(10) before calling :paginated_collection.")
44
+ end
45
+
46
+
37
47
  @contents = div(:class => "paginated_collection_contents")
38
- build_pagination_with_formats
48
+ build_pagination_with_formats(options)
39
49
  @built = true
40
50
  end
41
51
 
@@ -50,15 +60,19 @@ module ActiveAdmin
50
60
 
51
61
  protected
52
62
 
53
- def build_pagination_with_formats
63
+ def build_pagination_with_formats(options)
54
64
  div :id => "index_footer" do
55
- build_download_format_links
56
65
  build_pagination
66
+ div(page_entries_info(options).html_safe, :class => "pagination_information")
67
+ build_download_format_links unless @download_links == false
57
68
  end
58
69
  end
59
70
 
60
71
  def build_pagination
61
- text_node paginate(collection)
72
+ options = request.query_parameters.except(:commit, :format)
73
+ options[:param_name] = @param_name if @param_name
74
+
75
+ text_node paginate(collection, options.symbolize_keys)
62
76
  end
63
77
 
64
78
  # TODO: Refactor to new HTML DSL
@@ -66,24 +80,39 @@ module ActiveAdmin
66
80
  links = formats.collect do |format|
67
81
  link_to format.to_s.upcase, { :format => format}.merge(request.query_parameters.except(:commit, :format))
68
82
  end
69
- text_node [I18n.t('active_admin.download'), links].flatten.join("&nbsp;").html_safe
83
+ div :class => "download_links" do
84
+ text_node [I18n.t('active_admin.download'), links].flatten.join("&nbsp;").html_safe
85
+ end
70
86
  end
71
87
 
72
88
  # modified from will_paginate
73
89
  def page_entries_info(options = {})
74
- entry_name = options[:entry_name] ||
75
- (collection.empty?? 'entry' : collection.first.class.name.underscore.sub('_', ' '))
90
+ if options[:entry_name]
91
+ entry_name = options[:entry_name]
92
+ entries_name = options[:entries_name]
93
+ elsif collection.empty?
94
+ entry_name = I18n.translate("active_admin.pagination.entry", :count => 1, :default => 'entry')
95
+ entries_name = I18n.translate("active_admin.pagination.entry", :count => 2, :default => 'entries')
96
+ else
97
+ begin
98
+ entry_name = I18n.translate!("activerecord.models.#{collection.first.class.model_name.i18n_key}", :count => 1)
99
+ entries_name = I18n.translate!("activerecord.models.#{collection.first.class.model_name.i18n_key}", :count => collection.size)
100
+ rescue I18n::MissingTranslationData
101
+ entry_name = collection.first.class.name.underscore.sub('_', ' ')
102
+ end
103
+ end
104
+ entries_name = entry_name.pluralize unless entries_name
76
105
 
77
106
  if collection.num_pages < 2
78
107
  case collection.size
79
- when 0; I18n.t('active_admin.pagination.empty', :model => entry_name.pluralize)
108
+ when 0; I18n.t('active_admin.pagination.empty', :model => entries_name)
80
109
  when 1; I18n.t('active_admin.pagination.one', :model => entry_name)
81
- else; I18n.t('active_admin.pagination.one_page', :model => entry_name.pluralize, :n => collection.size)
110
+ else; I18n.t('active_admin.pagination.one_page', :model => entries_name, :n => collection.size)
82
111
  end
83
112
  else
84
- offset = collection.current_page * active_admin_application.default_per_page
113
+ offset = collection.current_page * collection.size
85
114
  total = collection.total_count
86
- I18n.t('active_admin.pagination.multiple', :model => entry_name.pluralize, :from => (offset - active_admin_application.default_per_page + 1), :to => offset > total ? total : offset, :total => total)
115
+ I18n.t('active_admin.pagination.multiple', :model => entries_name, :from => (offset - collection.size + 1), :to => offset > total ? total : offset, :total => total)
87
116
  end
88
117
  end
89
118