activeadmin 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activeadmin might be problematic. Click here for more details.
- data/CHANGELOG.md +46 -0
- data/Gemfile +1 -0
- data/README.rdoc +1 -1
- data/activeadmin.gemspec +1 -1
- data/app/assets/stylesheets/active_admin/_base.css.scss +2 -1
- data/app/assets/stylesheets/active_admin/components/_columns.scss +3 -0
- data/app/assets/stylesheets/active_admin/mixins/_sections.css.scss +1 -1
- data/app/views/active_admin/devise/sessions/new.html.erb +1 -1
- data/docs/2-resource-customization.md +13 -0
- data/docs/3-index-pages.md +23 -0
- data/docs/3-index-pages/index-as-grid.md +2 -2
- data/docs/7-sidebars.md +7 -0
- data/docs/8-custom-actions.md +6 -0
- data/features/action_item.feature +73 -0
- data/features/index/filters.feature +55 -22
- data/features/index/index_parameters.feature +12 -0
- data/features/index/index_scope_to.feature +29 -0
- data/features/index/index_scopes.feature +13 -0
- data/features/index/pagination.feature +14 -5
- data/features/sidebar_sections.feature +45 -0
- data/features/step_definitions/action_item_steps.rb +4 -0
- data/features/step_definitions/factory_steps.rb +3 -2
- data/features/step_definitions/filter_steps.rb +17 -0
- data/features/step_definitions/format_steps.rb +4 -0
- data/features/step_definitions/index_scope_steps.rb +5 -0
- data/lib/active_admin/arbre/html/tag.rb +9 -1
- data/lib/active_admin/helpers/optional_display.rb +13 -3
- data/lib/active_admin/locales/da.yml +15 -0
- data/lib/active_admin/locales/es.yml +18 -2
- data/lib/active_admin/locales/he_il.yml +45 -0
- data/lib/active_admin/menu_item.rb +0 -21
- data/lib/active_admin/page.rb +9 -0
- data/lib/active_admin/page_controller.rb +4 -0
- data/lib/active_admin/page_dsl.rb +7 -0
- data/lib/active_admin/reloader.rb +0 -1
- data/lib/active_admin/resource.rb +6 -0
- data/lib/active_admin/resource/action_items.rb +2 -2
- data/lib/active_admin/resource/pagination.rb +19 -0
- data/lib/active_admin/resource/sidebars.rb +2 -2
- data/lib/active_admin/resource_controller/callbacks.rb +13 -1
- data/lib/active_admin/resource_controller/collection.rb +17 -10
- data/lib/active_admin/router.rb +3 -0
- data/lib/active_admin/version.rb +1 -1
- data/lib/active_admin/views/components/columns.rb +115 -12
- data/lib/active_admin/views/components/scopes.rb +4 -4
- data/lib/active_admin/views/index_as_table.rb +14 -2
- data/lib/active_admin/views/pages/base.rb +2 -2
- data/lib/active_admin/views/pages/index.rb +25 -13
- data/lib/active_admin/views/tabbed_navigation.rb +14 -2
- data/spec/unit/menu_item_spec.rb +0 -14
- data/spec/unit/namespace/register_resource_spec.rb +1 -1
- data/spec/unit/resource/pagination_spec.rb +38 -0
- data/spec/unit/resource_controller/collection_spec.rb +1 -1
- data/spec/unit/views/components/columns_spec.rb +61 -4
- data/spec/unit/views/tabbed_navigation_spec.rb +2 -2
- metadata +20 -11
- data/features/index/filter_with_check_boxes.feature +0 -25
@@ -6,10 +6,6 @@ module ActiveAdmin
|
|
6
6
|
module Collection
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
|
-
included do
|
10
|
-
before_filter :setup_pagination_for_csv
|
11
|
-
end
|
12
|
-
|
13
9
|
module BaseCollection
|
14
10
|
protected
|
15
11
|
|
@@ -50,7 +46,8 @@ module ActiveAdmin
|
|
50
46
|
column = $1
|
51
47
|
order = $2
|
52
48
|
table = active_admin_config.resource_table_name
|
53
|
-
table_column = (column =~ /\./) ? column :
|
49
|
+
table_column = (column =~ /\./) ? column :
|
50
|
+
"#{table}.#{active_admin_config.resource_quoted_column_name(column)}"
|
54
51
|
|
55
52
|
chain.order("#{table_column} #{order}")
|
56
53
|
else
|
@@ -118,13 +115,23 @@ module ActiveAdmin
|
|
118
115
|
paginate(super)
|
119
116
|
end
|
120
117
|
|
121
|
-
|
122
|
-
|
123
|
-
@per_page = 10_000 if request.format == 'text/csv'
|
118
|
+
def paginate(chain)
|
119
|
+
chain.send(Kaminari.config.page_method_name, params[:page]).per(per_page)
|
124
120
|
end
|
125
121
|
|
126
|
-
def
|
127
|
-
|
122
|
+
def per_page
|
123
|
+
return max_csv_records if request.format == 'text/csv'
|
124
|
+
return max_per_page if active_admin_config.paginate == false
|
125
|
+
|
126
|
+
@per_page || active_admin_config.per_page
|
127
|
+
end
|
128
|
+
|
129
|
+
def max_csv_records
|
130
|
+
10_000
|
131
|
+
end
|
132
|
+
|
133
|
+
def max_per_page
|
134
|
+
10_000
|
128
135
|
end
|
129
136
|
end
|
130
137
|
|
data/lib/active_admin/router.rb
CHANGED
@@ -53,6 +53,9 @@ module ActiveAdmin
|
|
53
53
|
end
|
54
54
|
when Page
|
55
55
|
match "/#{config.underscored_resource_name}" => "#{config.underscored_resource_name}#index"
|
56
|
+
config.page_actions.each do |action|
|
57
|
+
match "/#{config.underscored_resource_name}/#{action.name}" => "#{config.underscored_resource_name}##{action.name}", :via => action.http_verb
|
58
|
+
end
|
56
59
|
else
|
57
60
|
raise "Unsupported config class: #{config.class}"
|
58
61
|
end
|
data/lib/active_admin/version.rb
CHANGED
@@ -1,9 +1,70 @@
|
|
1
1
|
module ActiveAdmin
|
2
2
|
module Views
|
3
3
|
|
4
|
+
# = Columns Component
|
5
|
+
#
|
6
|
+
# The Columns component allows you draw content into scalable columns. All
|
7
|
+
# you need to do is define the number of columns and the component will
|
8
|
+
# take care of the rest.
|
9
|
+
#
|
10
|
+
# == Simple Columns
|
11
|
+
#
|
12
|
+
# To display columns, use the #columns method. Within the block, call the
|
13
|
+
# #column method to create a new column.
|
14
|
+
#
|
15
|
+
# To createa a two column layout:
|
16
|
+
#
|
17
|
+
# colums do
|
18
|
+
# column do
|
19
|
+
# span "Column # 1
|
20
|
+
# end
|
21
|
+
# column do
|
22
|
+
# span "Column # 2
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
#
|
27
|
+
# == Multiple Span Columns
|
28
|
+
#
|
29
|
+
# To make a column span multiple, pass the :span option to the column method:
|
30
|
+
#
|
31
|
+
# colums do
|
32
|
+
# column :span => 2 do
|
33
|
+
# span "Column # 1
|
34
|
+
# end
|
35
|
+
# column do
|
36
|
+
# span "Column # 2
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# By default, each column spans 1 column. So the above layout would have 2 columns,
|
41
|
+
# the first being 2 time bigger than the second.
|
42
|
+
#
|
43
|
+
#
|
44
|
+
# == Max and Mix Column Sizes
|
45
|
+
#
|
46
|
+
# Active Admin is a fluid width layout, which means that columns are all defined
|
47
|
+
# using percentages. Sometimes this can cause issues if you don't want a column
|
48
|
+
# to shrink or expand past a certain point.
|
49
|
+
#
|
50
|
+
# To overcome this, columns include a :max_width and :min_width option.
|
51
|
+
#
|
52
|
+
# colums do
|
53
|
+
# column :max_width => "200px", :min_width => "100px" do
|
54
|
+
# span "Column # 1
|
55
|
+
# end
|
56
|
+
# column do
|
57
|
+
# span "Column # 2
|
58
|
+
# end
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# Now the first column will not grow bigger than 200px and will not shrink smaller
|
62
|
+
# than 100px.
|
4
63
|
class Columns < ActiveAdmin::Component
|
5
64
|
builder_method :columns
|
6
65
|
|
66
|
+
|
67
|
+
# For documentation, please take a look at Column#build
|
7
68
|
def column(*args, &block)
|
8
69
|
insert_tag Column, *args, &block
|
9
70
|
end
|
@@ -14,34 +75,76 @@ module ActiveAdmin
|
|
14
75
|
calculate_columns!
|
15
76
|
end
|
16
77
|
|
17
|
-
def to_s
|
18
|
-
super.to_s + "<div style=\"clear:both;\"></div>".html_safe
|
19
|
-
end
|
20
|
-
|
21
78
|
protected
|
22
79
|
|
80
|
+
# Override the closing tag to include a clear
|
81
|
+
def closing_tag
|
82
|
+
"<div style=\"clear:both;\"></div>" + super
|
83
|
+
end
|
84
|
+
|
23
85
|
def margin_size
|
24
86
|
2
|
25
87
|
end
|
26
88
|
|
89
|
+
# Calculate our columns sizes and margins
|
27
90
|
def calculate_columns!
|
28
|
-
|
29
|
-
|
30
|
-
margins_width = margin_size * (count - 1)
|
31
|
-
column_width = (100.00 - margins_width) / count
|
91
|
+
span_count = columns_span_count
|
92
|
+
columns_count = children.size
|
32
93
|
|
33
|
-
|
34
|
-
column_width =
|
94
|
+
all_margins_width = margin_size * (span_count - 1)
|
95
|
+
column_width = (100.00 - all_margins_width) / span_count
|
35
96
|
|
36
97
|
children.each_with_index do |col, i|
|
37
|
-
|
38
|
-
col.
|
98
|
+
is_last_column = i == (columns_count - 1)
|
99
|
+
col.set_column_styles(column_width, margin_size, is_last_column)
|
39
100
|
end
|
40
101
|
end
|
41
102
|
|
103
|
+
def columns_span_count
|
104
|
+
count = 0
|
105
|
+
children.each {|column| count += column.span_size }
|
106
|
+
|
107
|
+
count
|
108
|
+
end
|
109
|
+
|
42
110
|
end
|
43
111
|
|
44
112
|
class Column < ActiveAdmin::Component
|
113
|
+
|
114
|
+
attr_accessor :span_size, :max_width, :min_width
|
115
|
+
|
116
|
+
# @param [Hash] options An options hash for the column
|
117
|
+
#
|
118
|
+
# @options options [Integer] :span The columns this column should span
|
119
|
+
def build(options = {})
|
120
|
+
options = options.dup
|
121
|
+
@span_size = options.delete(:span) || 1
|
122
|
+
@max_width = options.delete(:max_width)
|
123
|
+
@min_width = options.delete(:min_width)
|
124
|
+
|
125
|
+
super(options)
|
126
|
+
end
|
127
|
+
|
128
|
+
def set_column_styles(column_width, margin_width, is_last_column = false)
|
129
|
+
column_with_span_width = (span_size * column_width) + ((span_size - 1) * margin_width)
|
130
|
+
|
131
|
+
styles = []
|
132
|
+
|
133
|
+
styles << "width: #{column_with_span_width}%;"
|
134
|
+
|
135
|
+
if max_width
|
136
|
+
styles << "max-width: #{max_width};"
|
137
|
+
end
|
138
|
+
|
139
|
+
if min_width
|
140
|
+
styles << "min-width: #{min_width};"
|
141
|
+
end
|
142
|
+
|
143
|
+
styles << "margin-right: #{margin_width}%;" unless is_last_column
|
144
|
+
|
145
|
+
set_attribute :style, styles.join(" ")
|
146
|
+
end
|
147
|
+
|
45
148
|
end
|
46
149
|
end
|
47
150
|
end
|
@@ -16,17 +16,17 @@ module ActiveAdmin
|
|
16
16
|
'ul'
|
17
17
|
end
|
18
18
|
|
19
|
-
def build(scopes)
|
19
|
+
def build(scopes, options = {})
|
20
20
|
unless current_filter_search_empty?
|
21
21
|
scopes.each do |scope|
|
22
|
-
build_scope(scope) if call_method_or_proc_on(self, scope.display_if_block)
|
22
|
+
build_scope(scope, options) if call_method_or_proc_on(self, scope.display_if_block)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
protected
|
28
28
|
|
29
|
-
def build_scope(scope)
|
29
|
+
def build_scope(scope, options)
|
30
30
|
li :class => classes_for_scope(scope) do
|
31
31
|
begin
|
32
32
|
scope_name = I18n.t!("active_admin.scopes.#{scope.id}")
|
@@ -38,7 +38,7 @@ module ActiveAdmin
|
|
38
38
|
text_node scope_name
|
39
39
|
span :class => 'count' do
|
40
40
|
"(" + get_scope_count(scope).to_s + ")"
|
41
|
-
end
|
41
|
+
end if options[:scope_count]
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
@@ -97,11 +97,13 @@ module ActiveAdmin
|
|
97
97
|
:id => active_admin_config.plural_underscored_resource_name,
|
98
98
|
:sortable => true,
|
99
99
|
:class => "index_table",
|
100
|
-
:i18n => active_admin_config.resource_class
|
100
|
+
:i18n => active_admin_config.resource_class,
|
101
|
+
:paginator => page_presenter[:paginator] != false
|
101
102
|
}
|
102
103
|
|
103
104
|
table_for collection, table_options do |t|
|
104
|
-
|
105
|
+
table_config_block = page_presenter.block || default_table
|
106
|
+
instance_exec(t, &table_config_block)
|
105
107
|
end
|
106
108
|
end
|
107
109
|
|
@@ -109,6 +111,16 @@ module ActiveAdmin
|
|
109
111
|
insert_tag IndexTableFor, *args, &block
|
110
112
|
end
|
111
113
|
|
114
|
+
def default_table
|
115
|
+
proc do
|
116
|
+
id_column
|
117
|
+
resource_class.content_columns.each do |col|
|
118
|
+
column col.name.to_sym
|
119
|
+
end
|
120
|
+
default_actions
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
112
124
|
#
|
113
125
|
# Extend the default ActiveAdmin::Views::TableFor with some
|
114
126
|
# methods for quickly displaying items on the index page
|
@@ -87,7 +87,7 @@ module ActiveAdmin
|
|
87
87
|
|
88
88
|
def build_action_items
|
89
89
|
if active_admin_config && active_admin_config.action_items?
|
90
|
-
items = active_admin_config.action_items_for(params[:action])
|
90
|
+
items = active_admin_config.action_items_for(params[:action], self)
|
91
91
|
insert_tag view_factory.action_items, items
|
92
92
|
end
|
93
93
|
end
|
@@ -135,7 +135,7 @@ module ActiveAdmin
|
|
135
135
|
# Returns the sidebar sections to render for the current action
|
136
136
|
def sidebar_sections_for_action
|
137
137
|
if active_admin_config && active_admin_config.sidebar_sections?
|
138
|
-
active_admin_config.sidebar_sections_for(params[:action])
|
138
|
+
active_admin_config.sidebar_sections_for(params[:action], self)
|
139
139
|
else
|
140
140
|
[]
|
141
141
|
end
|
@@ -17,7 +17,7 @@ module ActiveAdmin
|
|
17
17
|
def main_content
|
18
18
|
build_scopes
|
19
19
|
|
20
|
-
if
|
20
|
+
if items_in_collection?
|
21
21
|
render_index
|
22
22
|
else
|
23
23
|
if params[:q]
|
@@ -29,8 +29,18 @@ module ActiveAdmin
|
|
29
29
|
end
|
30
30
|
|
31
31
|
protected
|
32
|
-
|
33
|
-
|
32
|
+
|
33
|
+
def items_in_collection?
|
34
|
+
# Remove the order clause before limiting to 1. This ensures that
|
35
|
+
# any referenced columns in the order will not try to be accessed.
|
36
|
+
#
|
37
|
+
# When we call #exists?, the query's select statement is changed to "1".
|
38
|
+
#
|
39
|
+
# If we don't reorder, there may be some columns referenced in the order
|
40
|
+
# clause that requires the original select.
|
41
|
+
collection.reorder("").limit(1).exists?
|
42
|
+
end
|
43
|
+
|
34
44
|
# TODO: Refactor to new HTML DSL
|
35
45
|
def build_download_format_links(formats = [:csv, :xml, :json])
|
36
46
|
links = formats.collect do |format|
|
@@ -41,8 +51,12 @@ module ActiveAdmin
|
|
41
51
|
|
42
52
|
def build_scopes
|
43
53
|
if active_admin_config.scopes.any?
|
54
|
+
scope_options = {
|
55
|
+
:scope_count => config[:scope_count].nil? ? true : config[:scope_count]
|
56
|
+
}
|
57
|
+
|
44
58
|
div :class => "table_tools" do
|
45
|
-
scopes_renderer active_admin_config.scopes
|
59
|
+
scopes_renderer active_admin_config.scopes, scope_options
|
46
60
|
end
|
47
61
|
end
|
48
62
|
end
|
@@ -50,13 +64,7 @@ module ActiveAdmin
|
|
50
64
|
# Creates a default configuration for the resource class. This is a table
|
51
65
|
# with each column displayed as well as all the default actions
|
52
66
|
def default_index_config
|
53
|
-
@default_index_config ||= ::ActiveAdmin::PagePresenter.new(:as => :table)
|
54
|
-
id_column
|
55
|
-
resource_class.content_columns.each do |col|
|
56
|
-
column col.name.to_sym
|
57
|
-
end
|
58
|
-
default_actions
|
59
|
-
end
|
67
|
+
@default_index_config ||= ::ActiveAdmin::PagePresenter.new(:as => :table)
|
60
68
|
end
|
61
69
|
|
62
70
|
# Returns the actual class for renderering the main content on the index
|
@@ -87,9 +95,13 @@ module ActiveAdmin
|
|
87
95
|
|
88
96
|
def render_index
|
89
97
|
renderer_class = find_index_renderer_class(config[:as])
|
98
|
+
paginator = config[:paginator].nil? ? true : config[:paginator]
|
99
|
+
download_links = config[:download_links].nil? ? true : config[:download_links]
|
90
100
|
|
91
|
-
paginated_collection(collection, :entry_name
|
92
|
-
:entries_name
|
101
|
+
paginated_collection(collection, :entry_name => active_admin_config.resource_name,
|
102
|
+
:entries_name => active_admin_config.plural_resource_name,
|
103
|
+
:download_links => download_links,
|
104
|
+
:paginator => paginator) do
|
93
105
|
div :class => 'index_content' do
|
94
106
|
insert_tag(renderer_class, config, collection)
|
95
107
|
end
|
@@ -42,17 +42,29 @@ module ActiveAdmin
|
|
42
42
|
def build_menu_item(item)
|
43
43
|
li :id => item.dom_id do |li_element|
|
44
44
|
li_element.add_class "current" if current?(item)
|
45
|
+
link_path = url_for_menu_item(item)
|
45
46
|
|
46
47
|
if item.children.any?
|
47
48
|
li_element.add_class "has_nested"
|
48
|
-
text_node link_to(item.name,
|
49
|
+
text_node link_to(item.name, link_path)
|
49
50
|
render_nested_menu(item)
|
50
51
|
else
|
51
|
-
link_to item.name,
|
52
|
+
link_to item.name, link_path
|
52
53
|
end
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
57
|
+
def url_for_menu_item(menu_item)
|
58
|
+
case menu_item.url
|
59
|
+
when Symbol
|
60
|
+
send(menu_item.url)
|
61
|
+
when nil
|
62
|
+
"#"
|
63
|
+
else
|
64
|
+
menu_item.url
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
56
68
|
def render_nested_menu(item)
|
57
69
|
ul do
|
58
70
|
displayable_items(item.children).each do |child|
|
data/spec/unit/menu_item_spec.rb
CHANGED
@@ -35,20 +35,6 @@ module ActiveAdmin
|
|
35
35
|
item.display_if_block.call(self).should == true
|
36
36
|
end
|
37
37
|
|
38
|
-
describe "url generation and caching" do
|
39
|
-
it "should generate a url if it is a symbol" do
|
40
|
-
item = MenuItem.new("Posts", :admin_posts_path)
|
41
|
-
MenuItem.should_receive(:generate_url).with(:admin_posts_path).
|
42
|
-
and_return("/admin/posts")
|
43
|
-
|
44
|
-
item.url.should == "/admin/posts"
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should generate a url if it is a string" do
|
48
|
-
MenuItem.new("Posts", "/admin/posts").url.should == "/admin/posts"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
38
|
context "with no children" do
|
53
39
|
it "should be empty" do
|
54
40
|
item = MenuItem.new("Blog", "/admin/blog")
|
@@ -22,7 +22,7 @@ describe ActiveAdmin::Namespace, "registering a resource" do
|
|
22
22
|
it "should create a menu item" do
|
23
23
|
namespace.load_menu!
|
24
24
|
namespace.menu["Categories"].should be_an_instance_of(ActiveAdmin::MenuItem)
|
25
|
-
namespace.menu["Categories"].url.should ==
|
25
|
+
namespace.menu["Categories"].url.should == :admin_categories_path
|
26
26
|
end
|
27
27
|
end # context "with no configuration"
|
28
28
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ActiveAdmin
|
4
|
+
describe Resource, "Pagination" do
|
5
|
+
|
6
|
+
before { load_defaults! }
|
7
|
+
|
8
|
+
let(:application){ ActiveAdmin::Application.new }
|
9
|
+
let(:namespace){ Namespace.new(application, :admin) }
|
10
|
+
|
11
|
+
def config(options = {})
|
12
|
+
@config ||= Resource.new(namespace, Category, options)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#paginate" do
|
16
|
+
it "should default to true" do
|
17
|
+
config.paginate.should == true
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should be settable to false" do
|
21
|
+
config.paginate = false
|
22
|
+
config.paginate.should == false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#per_page" do
|
27
|
+
it "should default to namespace.default_per_page" do
|
28
|
+
namespace.should_receive(:default_per_page).and_return(5)
|
29
|
+
config.per_page.should == 5
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should be settable" do
|
33
|
+
config.per_page = 5
|
34
|
+
config.per_page.should == 5
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|