express_admin 1.6.3 → 1.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/components/express_admin/command_button.rb +39 -36
- data/app/components/express_admin/command_button_list.rb +25 -21
- data/app/components/express_admin/definition_list.rb +54 -50
- data/app/components/express_admin/definition_table.rb +16 -12
- data/app/components/express_admin/icon.rb +13 -8
- data/app/components/express_admin/icon_link.rb +42 -37
- data/app/components/express_admin/layout_component.rb +4 -0
- data/app/components/express_admin/layout_components/h_box.rb +5 -1
- data/app/components/express_admin/layout_components/pane.rb +24 -19
- data/app/components/express_admin/layout_components/sidebar_region.rb +5 -1
- data/app/components/express_admin/layout_components/v_box.rb +5 -1
- data/app/components/express_admin/main_region.rb +5 -1
- data/app/components/express_admin/page_header.rb +15 -11
- data/app/components/express_admin/smart_form.rb +106 -102
- data/app/components/express_admin/smart_table.rb +177 -165
- data/app/helpers/express_admin/admin_helper.rb +8 -0
- data/lib/express_admin/version.rb +1 -1
- data/test/dummy/db/test.sqlite3 +0 -0
- data/vendor/gems/express_templates/Gemfile.lock +7 -1
- data/vendor/gems/express_templates/express_templates-0.11.2.gem +0 -0
- data/vendor/gems/express_templates/express_templates.gemspec +2 -0
- data/vendor/gems/express_templates/lib/express_templates/components/all.rb +17 -15
- data/vendor/gems/express_templates/lib/express_templates/components/forms.rb +1 -0
- data/vendor/gems/express_templates/lib/express_templates/components/forms/country_select.rb +23 -0
- data/vendor/gems/express_templates/lib/express_templates/components/tree_for.rb +72 -70
- data/vendor/gems/express_templates/lib/express_templates/template/handler.rb +3 -2
- data/vendor/gems/express_templates/lib/express_templates/version.rb +1 -1
- data/vendor/gems/express_templates/test/components/forms/country_select_test.rb +34 -0
- data/vendor/gems/express_templates/test/dummy/log/test.log +654 -0
- data/vendor/gems/express_templates/test/test_helper.rb +1 -1
- metadata +5 -4
- data/vendor/gems/express_templates/express_templates-0.11.0.gem +0 -0
- data/vendor/gems/express_templates/express_templates-0.11.1.gem +0 -0
@@ -1,17 +1,21 @@
|
|
1
1
|
module ExpressAdmin
|
2
|
-
|
2
|
+
module Components
|
3
|
+
module Presenters
|
4
|
+
class PageHeader < ExpressTemplates::Components::Base
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
contains -> {
|
7
|
+
if content_for?(:page_header)
|
8
|
+
h1 {
|
9
|
+
content_for(:page_header)
|
10
|
+
}
|
11
|
+
end
|
12
|
+
if content_for?(:page_header_lead)
|
13
|
+
para(class: 'lead') {
|
14
|
+
content_for(:page_header_lead)
|
15
|
+
}
|
16
|
+
end
|
8
17
|
}
|
9
18
|
end
|
10
|
-
|
11
|
-
para(class: 'lead') {
|
12
|
-
content_for(:page_header_lead)
|
13
|
-
}
|
14
|
-
end
|
15
|
-
}
|
19
|
+
end
|
16
20
|
end
|
17
21
|
end
|
@@ -1,121 +1,125 @@
|
|
1
1
|
require 'rails/generators/generated_attribute'
|
2
2
|
|
3
3
|
module ExpressAdmin
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
filter_by_name(editable_attributes).each do |attrib|
|
22
|
-
form_field_for(attrib)
|
23
|
-
end
|
24
|
-
filter_by_name(has_many_through_associations).each do |assoc|
|
25
|
-
select_collection(assoc.name, nil, nil, class: 'select2')
|
26
|
-
end
|
27
|
-
if show_timestamps?
|
28
|
-
filter_by_name(timestamp_attributes).each do |timestamp|
|
29
|
-
div {
|
30
|
-
label {
|
31
|
-
"#{timestamp.name.titleize}: #{resource.try(timestamp.name.to_sym)}"
|
32
|
-
}
|
4
|
+
module Components
|
5
|
+
module Forms
|
6
|
+
class SmartForm < ExpressTemplates::Components::Forms::ExpressForm
|
7
|
+
TIMESTAMPS = %w(updated_at created_at)
|
8
|
+
|
9
|
+
has_option :virtual, 'Override the list of virtual attributes of the resource to be displayed', type: :array,
|
10
|
+
values: -> (*) { resource_class.respond_to?(:virtual_attributes) ? resource_class.virtual_attributes : [] }
|
11
|
+
has_option :exclude, 'Attributes not to be included in the form', type: :array
|
12
|
+
has_option :only, 'Respects the order the attributes are listed in', type: :array
|
13
|
+
has_option :show_timestamps, 'Set to true to show timestamps as labels'
|
14
|
+
|
15
|
+
contains {
|
16
|
+
# TODO: taken from express_form. should be inherited?
|
17
|
+
div(style: 'display:none') {
|
18
|
+
add_child helpers.utf8_enforcer_tag
|
19
|
+
add_child helpers.send(:method_tag, resource.persisted? ? :put : :post)
|
20
|
+
helpers.send(:token_tag)
|
33
21
|
}
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
22
|
+
|
23
|
+
filter_by_name(editable_attributes).each do |attrib|
|
24
|
+
form_field_for(attrib)
|
25
|
+
end
|
26
|
+
filter_by_name(has_many_through_associations).each do |assoc|
|
27
|
+
select_collection(assoc.name, nil, nil, class: 'select2')
|
28
|
+
end
|
29
|
+
if show_timestamps?
|
30
|
+
filter_by_name(timestamp_attributes).each do |timestamp|
|
31
|
+
div {
|
32
|
+
label {
|
33
|
+
"#{timestamp.name.titleize}: #{resource.try(timestamp.name.to_sym)}"
|
34
|
+
}
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
submit(class: 'button')
|
39
|
+
}
|
40
|
+
|
41
|
+
|
42
|
+
def form_field_for(attrib)
|
43
|
+
field_type_substitutions = {'text_area' => 'textarea',
|
44
|
+
'datetime_select' => 'datetime',
|
45
|
+
'check_box' => 'checkbox'}
|
46
|
+
field_type = attrib.field_type.to_s.sub(/_field$/,'')
|
47
|
+
field_type = "password" if attrib.name.match(/password/)
|
48
|
+
if relation = attrib.name.match(/(\w+)_id$/).try(:[], 1)
|
49
|
+
# TODO: should allow select2 override
|
50
|
+
select(attrib.name.to_sym, options: config["#{relation}_collection".to_sym], select2: true)
|
57
51
|
else
|
58
|
-
|
52
|
+
if field_type == 'text_area'
|
53
|
+
if attrib.name == 'definition'
|
54
|
+
# TODO allow other fields aside from layout.definition
|
55
|
+
base_styles = "position: relative; height: 300px;"
|
56
|
+
target = [attributes[:class].to_a.last, attrib.name].join("_")
|
57
|
+
textarea attrib.name.to_sym, rows: 10, class: "hide", hidden: true
|
58
|
+
content_tag(:div, '', id: "ace_#{attrib.name}", class: "ace-input", style: base_styles, data: { target: target })
|
59
|
+
else
|
60
|
+
textarea attrib.name.to_sym, rows: 10
|
61
|
+
end
|
62
|
+
else
|
63
|
+
self.send((field_type_substitutions[field_type] || field_type), attrib.name.to_sym)
|
64
|
+
end
|
59
65
|
end
|
60
|
-
else
|
61
|
-
self.send((field_type_substitutions[field_type] || field_type), attrib.name.to_sym)
|
62
66
|
end
|
63
|
-
end
|
64
|
-
end
|
65
67
|
|
66
|
-
|
68
|
+
protected
|
67
69
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
70
|
+
def resource_attributes
|
71
|
+
super.map do |attrib|
|
72
|
+
field_definition = [attrib.name, attrib.type] # index not important here for now
|
73
|
+
Rails::Generators::GeneratedAttribute.parse(field_definition.join(":"))
|
74
|
+
end
|
75
|
+
end
|
74
76
|
|
75
|
-
|
76
|
-
|
77
|
-
|
77
|
+
def editable_attributes
|
78
|
+
non_timestamp_attributes + virtual_attributes
|
79
|
+
end
|
78
80
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
def virtual_attributes
|
82
|
+
(config[:virtual]||[]).map do |attrib_name|
|
83
|
+
Rails::Generators::GeneratedAttribute.parse("#{attrib_name}:string")
|
84
|
+
end
|
85
|
+
end
|
84
86
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
87
|
+
def excluded_attributes
|
88
|
+
excl = [:id]
|
89
|
+
excl += config[:exclude] if config[:exclude]
|
90
|
+
excl
|
91
|
+
end
|
90
92
|
|
91
|
-
|
92
|
-
|
93
|
-
|
93
|
+
def timestamp_attributes
|
94
|
+
resource_attributes.select {|attrib| TIMESTAMPS.include?(attrib.name) }
|
95
|
+
end
|
94
96
|
|
95
|
-
|
96
|
-
|
97
|
-
|
97
|
+
def show_timestamps?
|
98
|
+
!!config[:show_timestamps]
|
99
|
+
end
|
98
100
|
|
99
|
-
|
100
|
-
|
101
|
-
|
101
|
+
def non_timestamp_attributes
|
102
|
+
resource_attributes.reject {|attrib| TIMESTAMPS.include?(attrib.name) }
|
103
|
+
end
|
102
104
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
105
|
+
def has_many_through_associations
|
106
|
+
resource_class.reflect_on_all_associations(:has_many).select do |assoc|
|
107
|
+
assoc.options.keys.include?(:through)
|
108
|
+
end
|
109
|
+
end
|
108
110
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
111
|
+
def filter_by_name(attribs)
|
112
|
+
if config[:only]
|
113
|
+
# if using :only, we respect the order
|
114
|
+
config[:only].map do |only|
|
115
|
+
attribs.detect {|attrib| only.to_s.eql?(attrib.name)} || nil
|
116
|
+
end.compact
|
117
|
+
else
|
118
|
+
attribs
|
119
|
+
end.reject {|attrib| (excluded_attributes).map(&:to_s).include? attrib.name }
|
120
|
+
end
|
119
121
|
|
122
|
+
end
|
123
|
+
end
|
120
124
|
end
|
121
|
-
end
|
125
|
+
end
|
@@ -1,192 +1,204 @@
|
|
1
1
|
module ExpressAdmin
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
column
|
2
|
+
module Components
|
3
|
+
module Presenters
|
4
|
+
class SmartTable < ExpressTemplates::Components::Configurable
|
5
|
+
include ExpressTemplates::Components::Capabilities::Resourceful
|
6
|
+
|
7
|
+
tag :table
|
8
|
+
|
9
|
+
MAX_COLS_TO_SHOW_IDX = 5
|
10
|
+
|
11
|
+
attr :columns
|
12
|
+
|
13
|
+
has_option :scrollable, 'Set to true if the table should be scrollable', type: :boolean, default: false
|
14
|
+
has_option :show_actions, 'Set to true if table has actions for each row'
|
15
|
+
has_option :row_class, 'Add a class to each table row'
|
16
|
+
|
17
|
+
column_defs = {}
|
18
|
+
column_defs[:array] = {description: "List of fields to include in the table as columns",
|
19
|
+
options: -> { resource.columns.map(&:name)} }
|
20
|
+
column_defs[:hash] = {description: "Hash of column names (titles) and how to calculate the cell values."}
|
21
|
+
|
22
|
+
has_option :columns, 'Specify the columns. May provide as a hash with values used to provide cell values as a proc.',
|
23
|
+
type: [:array, :hash],
|
24
|
+
values: -> (*) {
|
25
|
+
options = resource_class.columns.map(&:name)
|
26
|
+
resource_class.columns.map(&:name).each do |name|
|
27
|
+
options << if name.match(/(\w+)_at$/)
|
28
|
+
"#{name}_in_words"
|
29
|
+
else
|
30
|
+
"#{name}_link"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
options = options + resource_class.instance_methods.grep(/_count$/).map(&:to_s)
|
34
|
+
}
|
35
|
+
|
36
|
+
contains -> {
|
37
|
+
thead {
|
38
|
+
tr {
|
39
|
+
display_columns.each do |column|
|
40
|
+
th(class: column.name) {
|
41
|
+
column.title
|
42
|
+
}
|
43
|
+
end
|
44
|
+
actions_header if should_show_actions?
|
45
|
+
hidden_columns_header_indicator if columns_hidden?
|
40
46
|
}
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
47
|
+
}
|
48
|
+
tbody {
|
49
|
+
stored_member_assigns = assigns[collection_member_name.to_sym]
|
50
|
+
collection.each do |item|
|
51
|
+
assigns[collection_member_name.to_sym] = item
|
52
|
+
tr(id: row_id(item), class: row_class(item)) {
|
53
|
+
display_columns.each do |column|
|
54
|
+
td(class: column.name) {
|
55
|
+
cell_value(item, column.accessor)
|
56
|
+
}
|
57
|
+
end
|
58
|
+
actions_column(item) if should_show_actions?
|
59
|
+
hidden_column_cell if columns_hidden?
|
54
60
|
}
|
55
|
-
|
56
|
-
|
57
|
-
hidden_column_cell if columns_hidden?
|
61
|
+
assigns[collection_member_name.to_sym] = stored_member_assigns
|
62
|
+
end ; nil
|
58
63
|
}
|
59
|
-
assigns[collection_member_name.to_sym] = stored_member_assigns
|
60
|
-
end ; nil
|
61
|
-
}
|
62
|
-
|
63
|
-
scroll_table if !!config[:scrollable]
|
64
|
-
}
|
65
|
-
|
66
|
-
before_build -> {
|
67
|
-
_initialize_columns
|
68
|
-
add_class 'table striped'
|
69
|
-
}
|
70
|
-
|
71
|
-
def scroll_table
|
72
|
-
script {
|
73
|
-
%Q($('\##{config[:id]}').scrollTableBody())
|
74
|
-
}
|
75
|
-
end
|
76
64
|
|
77
|
-
|
78
|
-
|
79
|
-
end
|
65
|
+
scroll_table if !!config[:scrollable]
|
66
|
+
}
|
80
67
|
|
81
|
-
|
82
|
-
|
83
|
-
|
68
|
+
before_build -> {
|
69
|
+
_initialize_columns
|
70
|
+
add_class 'table striped'
|
71
|
+
}
|
84
72
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
else
|
91
|
-
false
|
92
|
-
end
|
93
|
-
end
|
73
|
+
def scroll_table
|
74
|
+
script {
|
75
|
+
%Q($('\##{config[:id]}').scrollTableBody())
|
76
|
+
}
|
77
|
+
end
|
94
78
|
|
95
|
-
|
96
|
-
|
97
|
-
if should_show_delete?(item)
|
98
|
-
link_to 'Delete', resource_path(item), method: :delete, data: {confirm: 'Are you sure?'}, class: 'button small secondary'
|
79
|
+
def actions_header
|
80
|
+
th(class: 'actions') { 'Actions' }
|
99
81
|
end
|
100
|
-
}
|
101
|
-
end
|
102
82
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
else
|
107
|
-
item.eql?(resource) ? 'current' : ''
|
108
|
-
end
|
109
|
-
end
|
83
|
+
def should_show_actions?
|
84
|
+
!!config[:show_actions]
|
85
|
+
end
|
110
86
|
|
111
|
-
|
112
|
-
|
113
|
-
|
87
|
+
def should_show_delete?(item)
|
88
|
+
if item.respond_to?(:can_delete?) && item.can_delete?
|
89
|
+
true
|
90
|
+
elsif !item.respond_to?(:can_delete?)
|
91
|
+
true
|
92
|
+
else
|
93
|
+
false
|
94
|
+
end
|
95
|
+
end
|
114
96
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
elsif attrib = accessor.to_s.match(/(\w+)_link$/).try(:[], 1)
|
123
|
-
# TODO: only works with non-namespaced routes
|
124
|
-
helpers.link_to item.send(attrib), resource_path(item)
|
125
|
-
elsif attrib = accessor.to_s.match(/(\w+)_in_words/).try(:[], 1)
|
126
|
-
item.send(attrib) ? (helpers.time_ago_in_words(item.send(attrib))+' ago') : 'never'
|
127
|
-
else
|
128
|
-
if relation_name = accessor.to_s.match(/(.*)_id$/).try(:[], 1)
|
129
|
-
reflection = resource_class.reflect_on_association(relation_name.to_sym)
|
130
|
-
end
|
97
|
+
def actions_column(item)
|
98
|
+
td {
|
99
|
+
if should_show_delete?(item)
|
100
|
+
link_to 'Delete', resource_path(item), method: :delete, data: {confirm: 'Are you sure?'}, class: 'button small secondary'
|
101
|
+
end
|
102
|
+
}
|
103
|
+
end
|
131
104
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
current_arbre_element.add_child value
|
140
|
-
end
|
105
|
+
def row_class(item)
|
106
|
+
if config[:row_class].try(:respond_to?, :call)
|
107
|
+
config[:row_class].call(item)
|
108
|
+
else
|
109
|
+
item.eql?(resource) ? 'current' : ''
|
110
|
+
end
|
111
|
+
end
|
141
112
|
|
142
|
-
|
143
|
-
|
144
|
-
|
113
|
+
def row_id(item)
|
114
|
+
"#{collection_member_name}:#{item.to_param}"
|
115
|
+
end
|
145
116
|
|
146
|
-
|
147
|
-
|
148
|
-
|
117
|
+
def cell_value(item, accessor)
|
118
|
+
value = if accessor.respond_to?(:call)
|
119
|
+
begin
|
120
|
+
accessor.call(item).try(:html_safe)
|
121
|
+
rescue
|
122
|
+
'Error: '+$!.to_s
|
123
|
+
end
|
124
|
+
elsif attrib = accessor.to_s.match(/(\w+)_link$/).try(:[], 1)
|
125
|
+
# TODO: only works with non-namespaced routes
|
126
|
+
helpers.link_to item.send(attrib), resource_path(item)
|
127
|
+
elsif attrib = accessor.to_s.match(/(\w+)_in_words/).try(:[], 1)
|
128
|
+
if item.send(attrib)
|
129
|
+
if item.send(attrib) < DateTime.now
|
130
|
+
"#{helpers.time_ago_in_words(item.send(attrib))} ago"
|
131
|
+
else
|
132
|
+
helpers.time_ago_in_words(item.send(attrib))
|
133
|
+
end
|
134
|
+
else
|
135
|
+
'never'
|
136
|
+
end
|
137
|
+
else
|
138
|
+
if relation_name = accessor.to_s.match(/(.*)_id$/).try(:[], 1)
|
139
|
+
reflection = resource_class.reflect_on_association(relation_name.to_sym)
|
140
|
+
end
|
141
|
+
|
142
|
+
if reflection
|
143
|
+
relation = item.send(relation_name)
|
144
|
+
relation.try(:name) || relation.to_s
|
145
|
+
else
|
146
|
+
item.send(accessor)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
current_arbre_element.add_child value
|
150
|
+
end
|
149
151
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
@name = accessor.kind_of?(Symbol) ? accessor.to_s.underscore : title.titleize.gsub(/\s+/,'').underscore
|
154
|
-
@accessor = accessor
|
155
|
-
@title = title || @name.titleize
|
156
|
-
end
|
157
|
-
end
|
152
|
+
def display_columns
|
153
|
+
specified_columns? ? @columns : @columns.slice(1..MAX_COLS_TO_SHOW_IDX)
|
154
|
+
end
|
158
155
|
|
159
|
-
|
160
|
-
|
161
|
-
|
156
|
+
def columns_hidden?
|
157
|
+
!specified_columns? && columns.size > MAX_COLS_TO_SHOW_IDX+1
|
158
|
+
end
|
162
159
|
|
163
|
-
|
164
|
-
|
165
|
-
|
160
|
+
class Column
|
161
|
+
attr :name, :title, :accessor
|
162
|
+
def initialize(accessor, title = nil)
|
163
|
+
@name = accessor.kind_of?(Symbol) ? accessor.to_s.underscore : title.titleize.gsub(/\s+/,'').underscore
|
164
|
+
@accessor = accessor
|
165
|
+
@title = title || @name.titleize
|
166
|
+
end
|
167
|
+
end
|
166
168
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
}
|
171
|
-
end
|
169
|
+
def specified_columns?
|
170
|
+
!!specified_columns
|
171
|
+
end
|
172
172
|
|
173
|
-
|
174
|
-
|
175
|
-
|
173
|
+
def specified_columns
|
174
|
+
config[:columns]
|
175
|
+
end
|
176
176
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
177
|
+
def hidden_columns_header_indicator
|
178
|
+
th(class: 'more-columns-indicator') {
|
179
|
+
"..."
|
180
|
+
}
|
181
|
+
end
|
182
182
|
|
183
|
-
|
184
|
-
|
183
|
+
def hidden_column_cell
|
184
|
+
td(class: 'more-columns-indicator')
|
185
|
+
end
|
185
186
|
|
186
|
-
|
187
|
-
|
187
|
+
private
|
188
|
+
def _initialize_columns
|
189
|
+
@columns =
|
190
|
+
if specified_columns.kind_of?(Array)
|
191
|
+
specified_columns.map { |name| Column.new(name) }
|
192
|
+
|
193
|
+
elsif specified_columns.kind_of?(Hash)
|
194
|
+
specified_columns.map { |title, accessor| Column.new(accessor, title) }
|
195
|
+
|
196
|
+
else
|
197
|
+
resource_attributes.map { |column| Column.new(column.name.to_sym) }
|
198
|
+
end
|
188
199
|
end
|
189
|
-
end
|
190
200
|
|
201
|
+
end
|
202
|
+
end
|
191
203
|
end
|
192
204
|
end
|