administrate 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/administrate/components/{has_many_form.js → associative.js} +1 -0
- data/app/assets/stylesheets/administrate/base/_tables.scss +3 -0
- data/app/assets/stylesheets/administrate/components/_flashes.scss +0 -8
- data/app/assets/stylesheets/administrate/library/_variables.scss +10 -8
- data/app/controllers/administrate/application_controller.rb +25 -4
- data/app/helpers/administrate/application_helper.rb +23 -11
- data/app/views/administrate/application/_collection.html.erb +5 -3
- data/app/views/administrate/application/_form.html.erb +1 -1
- data/app/views/administrate/application/_navigation.html.erb +4 -4
- data/app/views/fields/select/_form.html.erb +21 -9
- data/app/views/fields/time/_form.html.erb +3 -2
- data/config/locales/administrate.ar.yml +2 -0
- data/config/locales/administrate.bs.yml +2 -0
- data/config/locales/administrate.ca.yml +2 -0
- data/config/locales/administrate.da.yml +2 -0
- data/config/locales/administrate.de.yml +2 -0
- data/config/locales/administrate.en.yml +2 -0
- data/config/locales/administrate.es.yml +2 -0
- data/config/locales/administrate.fr.yml +2 -0
- data/config/locales/administrate.id.yml +2 -0
- data/config/locales/administrate.it.yml +2 -0
- data/config/locales/administrate.ja.yml +2 -0
- data/config/locales/administrate.ko.yml +2 -0
- data/config/locales/administrate.nl.yml +3 -1
- data/config/locales/administrate.pl.yml +2 -0
- data/config/locales/administrate.pt-BR.yml +2 -0
- data/config/locales/administrate.pt.yml +2 -0
- data/config/locales/administrate.ru.yml +2 -0
- data/config/locales/{administrate.al.yml → administrate.sq.yml} +3 -1
- data/config/locales/administrate.sv.yml +2 -0
- data/config/locales/administrate.uk.yml +2 -0
- data/config/locales/administrate.vi.yml +2 -0
- data/config/locales/administrate.zh-CN.yml +2 -0
- data/config/locales/administrate.zh-TW.yml +2 -0
- data/docs/adding_controllers_without_related_model.md +36 -0
- data/docs/customizing_controller_actions.md +14 -0
- data/docs/customizing_dashboards.md +6 -5
- data/docs/customizing_page_views.md +15 -3
- data/lib/administrate/base_dashboard.rb +13 -8
- data/lib/administrate/custom_dashboard.rb +15 -0
- data/lib/administrate/field/associative.rb +1 -1
- data/lib/administrate/field/base.rb +4 -0
- data/lib/administrate/field/deferred.rb +15 -0
- data/lib/administrate/field/polymorphic.rb +1 -1
- data/lib/administrate/field/select.rb +6 -1
- data/lib/administrate/namespace.rb +4 -0
- data/lib/administrate/page/base.rb +1 -1
- data/lib/administrate/page/form.rb +1 -1
- data/lib/administrate/search.rb +22 -18
- data/lib/administrate/version.rb +1 -1
- data/lib/generators/administrate/dashboard/dashboard_generator.rb +14 -3
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8120deb0ddc3a88302230382298ce39c25d60e4effca6336787016c46024d91
|
4
|
+
data.tar.gz: ad6262c38fca6d8be885d8687db7b02444da05c751c8dcb25a71d7a292d43f05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6bfde68398c548cfe04665c21c5e44fd8f659c404ddfcb141c5b358396cb6d0ca1c087b459a322553ff9dfeb195f033d817829d7a84bc80024004f1390faf5c
|
7
|
+
data.tar.gz: 794416e6cc50fadef9674c2fcb5316be67e7523d19c31431dfe3f80165a5355f3ce12019aad78681b6f5ede71797f3b3bab9b911236e8f3231bd0fcdacd15bc2
|
@@ -22,8 +22,10 @@ $black: #000 !default;
|
|
22
22
|
|
23
23
|
$blue: #1976d2 !default;
|
24
24
|
$red: #d32f2f !default;
|
25
|
-
$light-yellow: #
|
26
|
-
$light-
|
25
|
+
$light-yellow: #fff6bf !default;
|
26
|
+
$light-red: #fbe3e4 !default;
|
27
|
+
$light-green: #e6efc2 !default;
|
28
|
+
$light-blue: #e5edf8 !default;
|
27
29
|
|
28
30
|
$grey-0: #f6f7f7 !default;
|
29
31
|
$grey-1: #dfe0e1 !default;
|
@@ -47,12 +49,12 @@ $focus-outline: $focus-outline-width solid $focus-outline-color;
|
|
47
49
|
$focus-outline-offset: 1px;
|
48
50
|
|
49
51
|
// Flash Colors
|
50
|
-
$
|
51
|
-
alert: $light-yellow,
|
52
|
-
error: $red,
|
53
|
-
notice:
|
54
|
-
success: $light-green
|
55
|
-
);
|
52
|
+
$flashes: (
|
53
|
+
"alert": $light-yellow,
|
54
|
+
"error": $light-red,
|
55
|
+
"notice": $light-blue,
|
56
|
+
"success": $light-green
|
57
|
+
) !default;
|
56
58
|
|
57
59
|
// Border
|
58
60
|
$base-border-color: $grey-1 !default;
|
@@ -27,7 +27,7 @@ module Administrate
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def new
|
30
|
-
resource =
|
30
|
+
resource = new_resource
|
31
31
|
authorize_resource(resource)
|
32
32
|
render locals: {
|
33
33
|
page: Administrate::Page::Form.new(dashboard, resource),
|
@@ -101,12 +101,31 @@ module Administrate
|
|
101
101
|
end
|
102
102
|
|
103
103
|
def order
|
104
|
-
@order ||= Administrate::Order.new(
|
105
|
-
|
106
|
-
|
104
|
+
@order ||= Administrate::Order.new(sorting_attribute, sorting_direction)
|
105
|
+
end
|
106
|
+
|
107
|
+
def sorting_attribute
|
108
|
+
params.fetch(resource_name, {}).fetch(
|
109
|
+
:order,
|
110
|
+
default_sorting_attribute,
|
107
111
|
)
|
108
112
|
end
|
109
113
|
|
114
|
+
def default_sorting_attribute
|
115
|
+
nil
|
116
|
+
end
|
117
|
+
|
118
|
+
def sorting_direction
|
119
|
+
params.fetch(resource_name, {}).fetch(
|
120
|
+
:direction,
|
121
|
+
default_sorting_direction,
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
def default_sorting_direction
|
126
|
+
nil
|
127
|
+
end
|
128
|
+
|
110
129
|
def dashboard
|
111
130
|
@dashboard ||= dashboard_class.new
|
112
131
|
end
|
@@ -144,6 +163,8 @@ module Administrate
|
|
144
163
|
else
|
145
164
|
raise "Unrecognised param data: #{data.inspect}"
|
146
165
|
end
|
166
|
+
elsif data.is_a?(ActionController::Parameters)
|
167
|
+
data.transform_values { |v| read_param_value(v) }
|
147
168
|
else
|
148
169
|
data
|
149
170
|
end
|
@@ -11,7 +11,7 @@ module Administrate
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def render_field(field, locals = {})
|
14
|
-
locals
|
14
|
+
locals[:field] = field
|
15
15
|
render locals: locals, partial: field.to_partial_path
|
16
16
|
end
|
17
17
|
|
@@ -34,17 +34,20 @@ module Administrate
|
|
34
34
|
resource_class.validators_on(field_name)
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
38
|
-
resource_name.to_s.classify.constantize
|
37
|
+
def dashboard_from_resource(resource_name)
|
38
|
+
"#{resource_name.to_s.singularize}_dashboard".classify.constantize
|
39
|
+
end
|
40
|
+
|
41
|
+
def model_from_resource(resource_name)
|
42
|
+
dashboard = dashboard_from_resource(resource_name)
|
43
|
+
dashboard.try(:model) || resource_name.to_sym
|
39
44
|
end
|
40
45
|
|
41
46
|
def display_resource_name(resource_name)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
default: resource_name.to_s.pluralize.titleize,
|
47
|
-
)
|
47
|
+
dashboard_from_resource(resource_name).resource_name(
|
48
|
+
count: PLURAL_MANY_COUNT,
|
49
|
+
default: default_resource_name(resource_name),
|
50
|
+
)
|
48
51
|
end
|
49
52
|
|
50
53
|
def sort_order(order)
|
@@ -55,8 +58,11 @@ module Administrate
|
|
55
58
|
end
|
56
59
|
end
|
57
60
|
|
58
|
-
def
|
59
|
-
|
61
|
+
def resource_index_route(resource_name)
|
62
|
+
url_for(
|
63
|
+
action: "index",
|
64
|
+
controller: "/#{namespace}/#{resource_name}",
|
65
|
+
)
|
60
66
|
end
|
61
67
|
|
62
68
|
def sanitized_order_params(page, current_field_name)
|
@@ -72,5 +78,11 @@ module Administrate
|
|
72
78
|
:per_page, resource_name => %i[order direction]
|
73
79
|
)
|
74
80
|
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def default_resource_name(resource_name)
|
85
|
+
resource_name.to_s.pluralize.gsub("/", "_").titleize
|
86
|
+
end
|
75
87
|
end
|
76
88
|
end
|
@@ -55,19 +55,21 @@ to display a collection of resources in an HTML table.
|
|
55
55
|
<tbody>
|
56
56
|
<% resources.each do |resource| %>
|
57
57
|
<tr class="js-table-row"
|
58
|
-
|
59
|
-
|
60
|
-
<%= %(role=link data-url=#{polymorphic_path([namespace, resource])}) %>
|
58
|
+
<% if show_action? :show, resource %>
|
59
|
+
<%= %(tabindex=0 role=link data-url=#{polymorphic_path([namespace, resource])}) %>
|
61
60
|
<% end %>
|
62
61
|
>
|
63
62
|
<% collection_presenter.attributes_for(resource).each do |attribute| %>
|
64
63
|
<td class="cell-data cell-data--<%= attribute.html_class %>">
|
65
64
|
<% if show_action? :show, resource -%>
|
66
65
|
<a href="<%= polymorphic_path([namespace, resource]) -%>"
|
66
|
+
tabindex="-1"
|
67
67
|
class="action-show"
|
68
68
|
>
|
69
69
|
<%= render_field attribute %>
|
70
70
|
</a>
|
71
|
+
<% else %>
|
72
|
+
<%= render_field attribute %>
|
71
73
|
<% end -%>
|
72
74
|
</td>
|
73
75
|
<% end %>
|
@@ -21,7 +21,7 @@ and renders all form fields for a resource's editable attributes.
|
|
21
21
|
<%= t(
|
22
22
|
"administrate.form.errors",
|
23
23
|
pluralized_errors: pluralize(page.resource.errors.count, t("administrate.form.error")),
|
24
|
-
resource_name: display_resource_name(page.resource_name)
|
24
|
+
resource_name: display_resource_name(page.resource_name).singularize
|
25
25
|
) %>
|
26
26
|
</h2>
|
27
27
|
|
@@ -8,13 +8,13 @@ as defined by the routes in the `admin/` namespace
|
|
8
8
|
%>
|
9
9
|
|
10
10
|
<nav class="navigation" role="navigation">
|
11
|
-
<%= link_to
|
11
|
+
<%= link_to(t("administrate.navigation.back_to_app"), root_url, class: "button button--alt") if defined?(root_url) %>
|
12
12
|
|
13
|
-
<% Administrate::Namespace.new(namespace).
|
13
|
+
<% Administrate::Namespace.new(namespace).resources_with_index_route.each do |resource| %>
|
14
14
|
<%= link_to(
|
15
15
|
display_resource_name(resource),
|
16
|
-
|
16
|
+
resource_index_route(resource),
|
17
17
|
class: "navigation__link navigation__link--#{nav_link_state(resource)}"
|
18
|
-
) if valid_action? :index, resource
|
18
|
+
) if valid_action?(:index, resource) && show_action?(:index, model_from_resource(resource)) %>
|
19
19
|
<% end %>
|
20
20
|
</nav>
|
@@ -19,13 +19,25 @@ to be displayed on a resource's edit form page.
|
|
19
19
|
<%= f.label field.attribute %>
|
20
20
|
</div>
|
21
21
|
<div class="field-unit__field">
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
22
|
+
<% if field.selectable_options.first&.is_a?(Array) %>
|
23
|
+
<%= f.select(
|
24
|
+
field.attribute,
|
25
|
+
options_from_collection_for_select(
|
26
|
+
field.selectable_options,
|
27
|
+
:last,
|
28
|
+
:first,
|
29
|
+
field.data.presence,
|
30
|
+
)
|
31
|
+
) %>
|
32
|
+
<% else %>
|
33
|
+
<%= f.select(
|
34
|
+
field.attribute,
|
35
|
+
options_from_collection_for_select(
|
36
|
+
field.selectable_options,
|
37
|
+
:to_s,
|
38
|
+
:to_s,
|
39
|
+
field.data.presence,
|
40
|
+
)
|
41
|
+
) %>
|
42
|
+
<% end %>
|
31
43
|
</div>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# Time Form Partial
|
3
3
|
|
4
4
|
This partial renders an input element for time attributes.
|
5
|
-
By default, the input is a
|
5
|
+
By default, the input is a text field that is augmented with [DateTimePicker].
|
6
6
|
|
7
7
|
## Local variables:
|
8
8
|
|
@@ -12,11 +12,12 @@ By default, the input is a select field for the time attributes.
|
|
12
12
|
An instance of [Administrate::Field::Time][1].
|
13
13
|
A wrapper around the tmie attributes pulled from the model.
|
14
14
|
|
15
|
+
[DateTimePicker]: https://github.com/Eonasdan/bootstrap-datetimepicker
|
15
16
|
%>
|
16
17
|
|
17
18
|
<div class="field-unit__label">
|
18
19
|
<%= f.label field.attribute %>
|
19
20
|
</div>
|
20
21
|
<div class="field-unit__field">
|
21
|
-
<%= f.text_field field.attribute, data: { type: 'time' } %>
|
22
|
+
<%= f.text_field field.attribute, data: { type: 'time' }, value: field.data&.strftime("%H:%M:%S") %>
|
22
23
|
</div>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
---
|
2
|
-
|
2
|
+
sq:
|
3
3
|
administrate:
|
4
4
|
actions:
|
5
5
|
confirm: A jeni te sigurtë?
|
@@ -23,6 +23,8 @@ al:
|
|
23
23
|
form:
|
24
24
|
error: gabim
|
25
25
|
errors: "%{pluralized_errors} nuk e lejoj %{resource_name} të ruhet:"
|
26
|
+
navigation:
|
27
|
+
back_to_app: Kthehu tek aplikacioni
|
26
28
|
search:
|
27
29
|
clear: Pastro kërkimin
|
28
30
|
label: Kërko %{resource}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Adding Controllers without a related Model
|
2
|
+
|
3
|
+
Sometimes you may want to add a custom controller that has no resource
|
4
|
+
related to it (for example for a statistics page).
|
5
|
+
|
6
|
+
To do that, you must define an `index` route, as only controllers with index
|
7
|
+
routes are displayed in the sidebar and then add a custom dashboard:
|
8
|
+
|
9
|
+
```erb
|
10
|
+
# app/views/admin/stats/index.html.erb
|
11
|
+
|
12
|
+
<div style="padding: 20px">
|
13
|
+
<h1>Stats</h1>
|
14
|
+
<br>
|
15
|
+
<p><b>Total Customers:</b> <%= @stats[:customer_count] %></h1>
|
16
|
+
<br>
|
17
|
+
<p><b>Total Orders:</b> <%= @stats[:order_count] %></h1>
|
18
|
+
</div>
|
19
|
+
```
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
# app/dashboards/stat_dashboard.rb
|
23
|
+
require "administrate/custom_dashboard"
|
24
|
+
|
25
|
+
class StatDashboard < Administrate::CustomDashboard
|
26
|
+
resource "Stats" # used by administrate in the views
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
# config/routes.rb
|
32
|
+
namespace :admin do
|
33
|
+
# ...
|
34
|
+
resources :stats, only: [:index]
|
35
|
+
end
|
36
|
+
```
|
@@ -56,3 +56,17 @@ end
|
|
56
56
|
```
|
57
57
|
|
58
58
|
Action is one of `new`, `edit`, `show`, `destroy`.
|
59
|
+
|
60
|
+
## Customizing Default Sorting
|
61
|
+
|
62
|
+
To set the default sorting on the index action you could override `default_sorting_attribute` or `default_sorting_direction` in your dashboard controller like this:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
def default_sorting_attribute
|
66
|
+
:age
|
67
|
+
end
|
68
|
+
|
69
|
+
def default_sorting_direction
|
70
|
+
:desc
|
71
|
+
end
|
72
|
+
```
|
@@ -93,7 +93,7 @@ Defaults to `:#{attribute}.to_s.singularize.camelcase`.
|
|
93
93
|
`:searchable` - Specify if the attribute should be considered when searching.
|
94
94
|
Default is `false`.
|
95
95
|
|
96
|
-
`
|
96
|
+
`searchable_fields` - Specify which columns to use on the search, only applies
|
97
97
|
if `searchable` is `true`
|
98
98
|
|
99
99
|
For example:
|
@@ -101,7 +101,7 @@ For example:
|
|
101
101
|
```ruby
|
102
102
|
country: Field::BelongsTo.with_options(
|
103
103
|
searchable: true,
|
104
|
-
|
104
|
+
searchable_fields: ['name'],
|
105
105
|
)
|
106
106
|
```
|
107
107
|
|
@@ -132,7 +132,7 @@ Defaults to `:#{attribute}.to_s.singularize.camelcase`.
|
|
132
132
|
`:searchable` - Specify if the attribute should be considered when searching.
|
133
133
|
Default is `false`.
|
134
134
|
|
135
|
-
`
|
135
|
+
`searchable_fields` - Specify which columns to use on the search, only applies if
|
136
136
|
`searchable` is `true`
|
137
137
|
|
138
138
|
For example:
|
@@ -140,7 +140,7 @@ For example:
|
|
140
140
|
```ruby
|
141
141
|
cities: Field::HasMany.with_options(
|
142
142
|
searchable: true,
|
143
|
-
|
143
|
+
searchable_fields: ['name'],
|
144
144
|
)
|
145
145
|
```
|
146
146
|
|
@@ -200,7 +200,8 @@ objects to display as.
|
|
200
200
|
|
201
201
|
**Field::Select**
|
202
202
|
|
203
|
-
`:collection` - Specify the
|
203
|
+
`:collection` - Specify the options shown on the select field. It accept either
|
204
|
+
an array or an object responding to `:call`. Defaults to `[]`.
|
204
205
|
|
205
206
|
`:searchable` - Specify if the attribute should be considered when searching.
|
206
207
|
Default is `true`.
|
@@ -2,12 +2,24 @@
|
|
2
2
|
title: Customizing page views
|
3
3
|
---
|
4
4
|
|
5
|
-
|
6
|
-
you can
|
5
|
+
You can provide replacements for any of Administrate's templates.
|
6
|
+
This way you can change the appearance of any page or element of
|
7
|
+
the interface.
|
8
|
+
|
9
|
+
In general, you can override any of the views under Administrate's
|
10
|
+
[/app/views][1].
|
11
|
+
For example, say that you want to customize the template used for flash
|
12
|
+
messages. You can provide your own as
|
13
|
+
`/app/views/administrate/application/_flashes.html.erb`, and it will replace
|
14
|
+
Administrate's own.
|
15
|
+
|
16
|
+
Figuring out which views are available and where can be repetitive. You can
|
17
|
+
spare yourself some effort by using the built-in view generators.
|
18
|
+
|
19
|
+
[1]: https://github.com/thoughtbot/administrate/tree/master/app/views
|
7
20
|
|
8
21
|
## Customizing for all resources
|
9
22
|
|
10
|
-
The easiest way to get started is by using the built-in generators.
|
11
23
|
In order to change the appearance of views for all resource types,
|
12
24
|
call the generators with no arguments.
|
13
25
|
|
@@ -18,6 +18,18 @@ module Administrate
|
|
18
18
|
class BaseDashboard
|
19
19
|
include Administrate
|
20
20
|
|
21
|
+
DASHBOARD_SUFFIX = "Dashboard".freeze
|
22
|
+
|
23
|
+
class << self
|
24
|
+
def model
|
25
|
+
to_s.chomp(DASHBOARD_SUFFIX).classify.constantize
|
26
|
+
end
|
27
|
+
|
28
|
+
def resource_name(opts)
|
29
|
+
model.model_name.human(opts)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
21
33
|
def attribute_types
|
22
34
|
self.class::ATTRIBUTE_TYPES
|
23
35
|
end
|
@@ -74,18 +86,11 @@ module Administrate
|
|
74
86
|
"Attribute #{attr} could not be found in #{self.class}::ATTRIBUTE_TYPES"
|
75
87
|
end
|
76
88
|
|
77
|
-
def association_classes
|
78
|
-
@association_classes ||=
|
79
|
-
ObjectSpace.each_object(Class).
|
80
|
-
select { |klass| klass < Administrate::Field::Associative }
|
81
|
-
end
|
82
|
-
|
83
89
|
def attribute_includes(attributes)
|
84
90
|
attributes.map do |key|
|
85
91
|
field = self.class::ATTRIBUTE_TYPES[key]
|
86
92
|
|
87
|
-
|
88
|
-
key if association_classes.include?(field.try(:deferred_class))
|
93
|
+
key if field.associative?
|
89
94
|
end.compact
|
90
95
|
end
|
91
96
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Administrate
|
2
|
+
class CustomDashboard
|
3
|
+
include Administrate
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def resource_name(_opts)
|
7
|
+
named_resource.pluralize.titleize
|
8
|
+
end
|
9
|
+
|
10
|
+
def resource(resource_name)
|
11
|
+
define_singleton_method(:named_resource) { resource_name }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -21,14 +21,29 @@ module Administrate
|
|
21
21
|
options == other.options
|
22
22
|
end
|
23
23
|
|
24
|
+
def associative?
|
25
|
+
deferred_class.associative?
|
26
|
+
end
|
27
|
+
|
24
28
|
def searchable?
|
25
29
|
options.fetch(:searchable, deferred_class.searchable?)
|
26
30
|
end
|
27
31
|
|
28
32
|
def searchable_field
|
33
|
+
ActiveSupport::Deprecation.warn(
|
34
|
+
"searchable_field is deprecated, use searchable_fields instead",
|
35
|
+
)
|
29
36
|
options.fetch(:searchable_field)
|
30
37
|
end
|
31
38
|
|
39
|
+
def searchable_fields
|
40
|
+
if options.key?(:searchable_field)
|
41
|
+
[searchable_field]
|
42
|
+
else
|
43
|
+
options.fetch(:searchable_fields)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
32
47
|
def permitted_attribute(attr, _options = nil)
|
33
48
|
options.fetch(:foreign_key,
|
34
49
|
deferred_class.permitted_attribute(attr, options))
|
@@ -14,7 +14,12 @@ module Administrate
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def collection
|
17
|
-
|
17
|
+
values = options.fetch(:collection, [])
|
18
|
+
if values.respond_to? :call
|
19
|
+
return values.arity.positive? ? values.call(self) : values.call
|
20
|
+
end
|
21
|
+
|
22
|
+
@collection ||= values
|
18
23
|
end
|
19
24
|
end
|
20
25
|
end
|
data/lib/administrate/search.rb
CHANGED
@@ -81,14 +81,24 @@ module Administrate
|
|
81
81
|
def query_template
|
82
82
|
search_attributes.map do |attr|
|
83
83
|
table_name = query_table_name(attr)
|
84
|
-
|
85
|
-
|
86
|
-
|
84
|
+
searchable_fields(attr).map do |field|
|
85
|
+
attr_name = column_to_query(field)
|
86
|
+
"LOWER(CAST(#{table_name}.#{attr_name} AS CHAR(256))) LIKE ?"
|
87
|
+
end.join(" OR ")
|
87
88
|
end.join(" OR ")
|
88
89
|
end
|
89
90
|
|
91
|
+
def searchable_fields(attr)
|
92
|
+
return [attr] unless association_search?(attr)
|
93
|
+
|
94
|
+
attribute_types[attr].searchable_fields
|
95
|
+
end
|
96
|
+
|
90
97
|
def query_values
|
91
|
-
|
98
|
+
fields_count = search_attributes.sum do |attr|
|
99
|
+
searchable_fields(attr).count
|
100
|
+
end
|
101
|
+
["%#{term.mb_chars.downcase}%"] * fields_count
|
92
102
|
end
|
93
103
|
|
94
104
|
def search_attributes
|
@@ -117,7 +127,12 @@ module Administrate
|
|
117
127
|
|
118
128
|
def query_table_name(attr)
|
119
129
|
if association_search?(attr)
|
120
|
-
|
130
|
+
provided_class_name = attribute_types[attr].options[:class_name]
|
131
|
+
if provided_class_name
|
132
|
+
provided_class_name.constantize.table_name
|
133
|
+
else
|
134
|
+
ActiveRecord::Base.connection.quote_table_name(attr.to_s.pluralize)
|
135
|
+
end
|
121
136
|
else
|
122
137
|
ActiveRecord::Base.connection.
|
123
138
|
quote_table_name(@scoped_resource.table_name)
|
@@ -125,12 +140,7 @@ module Administrate
|
|
125
140
|
end
|
126
141
|
|
127
142
|
def column_to_query(attr)
|
128
|
-
|
129
|
-
ActiveRecord::Base.connection.
|
130
|
-
quote_column_name(attribute_types[attr].searchable_field)
|
131
|
-
else
|
132
|
-
ActiveRecord::Base.connection.quote_column_name(attr)
|
133
|
-
end
|
143
|
+
ActiveRecord::Base.connection.quote_column_name(attr)
|
134
144
|
end
|
135
145
|
|
136
146
|
def tables_to_join
|
@@ -140,13 +150,7 @@ module Administrate
|
|
140
150
|
end
|
141
151
|
|
142
152
|
def association_search?(attribute)
|
143
|
-
|
144
|
-
|
145
|
-
[
|
146
|
-
Administrate::Field::BelongsTo,
|
147
|
-
Administrate::Field::HasMany,
|
148
|
-
Administrate::Field::HasOne,
|
149
|
-
].include?(attribute_types[attribute].deferred_class)
|
153
|
+
attribute_types[attribute].associative?
|
150
154
|
end
|
151
155
|
|
152
156
|
def term
|
data/lib/administrate/version.rb
CHANGED
@@ -7,7 +7,7 @@ module Administrate
|
|
7
7
|
boolean: "Field::Boolean",
|
8
8
|
date: "Field::Date",
|
9
9
|
datetime: "Field::DateTime",
|
10
|
-
enum: "Field::
|
10
|
+
enum: "Field::Select",
|
11
11
|
float: "Field::Number",
|
12
12
|
integer: "Field::Number",
|
13
13
|
time: "Field::Time",
|
@@ -16,7 +16,9 @@ module Administrate
|
|
16
16
|
}
|
17
17
|
|
18
18
|
ATTRIBUTE_OPTIONS_MAPPING = {
|
19
|
-
|
19
|
+
# procs must be defined in one line!
|
20
|
+
enum: { searchable: false,
|
21
|
+
collection: ->(field) { field.resource.class.send(field.attribute.to_s.pluralize).keys } },
|
20
22
|
float: { decimals: 2 },
|
21
23
|
}
|
22
24
|
|
@@ -136,7 +138,16 @@ module Administrate
|
|
136
138
|
end
|
137
139
|
|
138
140
|
def inspect_hash_as_ruby(hash)
|
139
|
-
hash.map
|
141
|
+
hash.map do |key, value|
|
142
|
+
v_str = value.respond_to?(:call) ? proc_string(value) : value.inspect
|
143
|
+
"#{key}: #{v_str}"
|
144
|
+
end.join(", ")
|
145
|
+
end
|
146
|
+
|
147
|
+
def proc_string(value)
|
148
|
+
source = value.source_location
|
149
|
+
proc_string = IO.readlines(source.first)[source.second - 1]
|
150
|
+
proc_string[/->[^}]*} | (lambda|proc).*end/x]
|
140
151
|
end
|
141
152
|
end
|
142
153
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: administrate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Charlton
|
8
8
|
- Grayson Wright
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-07-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -187,8 +187,8 @@ extra_rdoc_files: []
|
|
187
187
|
files:
|
188
188
|
- Rakefile
|
189
189
|
- app/assets/javascripts/administrate/application.js
|
190
|
+
- app/assets/javascripts/administrate/components/associative.js
|
190
191
|
- app/assets/javascripts/administrate/components/date_time_picker.js
|
191
|
-
- app/assets/javascripts/administrate/components/has_many_form.js
|
192
192
|
- app/assets/javascripts/administrate/components/table.js
|
193
193
|
- app/assets/stylesheets/administrate/application.scss
|
194
194
|
- app/assets/stylesheets/administrate/base/_forms.scss
|
@@ -275,7 +275,6 @@ files:
|
|
275
275
|
- app/views/fields/url/_show.html.erb
|
276
276
|
- app/views/layouts/administrate/application.html.erb
|
277
277
|
- config/i18n-tasks.yml
|
278
|
-
- config/locales/administrate.al.yml
|
279
278
|
- config/locales/administrate.ar.yml
|
280
279
|
- config/locales/administrate.bs.yml
|
281
280
|
- config/locales/administrate.ca.yml
|
@@ -293,6 +292,7 @@ files:
|
|
293
292
|
- config/locales/administrate.pt-BR.yml
|
294
293
|
- config/locales/administrate.pt.yml
|
295
294
|
- config/locales/administrate.ru.yml
|
295
|
+
- config/locales/administrate.sq.yml
|
296
296
|
- config/locales/administrate.sv.yml
|
297
297
|
- config/locales/administrate.uk.yml
|
298
298
|
- config/locales/administrate.vi.yml
|
@@ -300,6 +300,7 @@ files:
|
|
300
300
|
- config/locales/administrate.zh-TW.yml
|
301
301
|
- config/routes.rb
|
302
302
|
- config/unicorn.rb
|
303
|
+
- docs/adding_controllers_without_related_model.md
|
303
304
|
- docs/adding_custom_field_types.md
|
304
305
|
- docs/authentication.md
|
305
306
|
- docs/authorization.md
|
@@ -312,6 +313,7 @@ files:
|
|
312
313
|
- docs/rails_api.md
|
313
314
|
- lib/administrate.rb
|
314
315
|
- lib/administrate/base_dashboard.rb
|
316
|
+
- lib/administrate/custom_dashboard.rb
|
315
317
|
- lib/administrate/engine.rb
|
316
318
|
- lib/administrate/field/associative.rb
|
317
319
|
- lib/administrate/field/base.rb
|
@@ -374,7 +376,7 @@ homepage: https://administrate-prototype.herokuapp.com/
|
|
374
376
|
licenses:
|
375
377
|
- MIT
|
376
378
|
metadata: {}
|
377
|
-
post_install_message:
|
379
|
+
post_install_message:
|
378
380
|
rdoc_options: []
|
379
381
|
require_paths:
|
380
382
|
- lib
|
@@ -390,7 +392,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
390
392
|
version: '0'
|
391
393
|
requirements: []
|
392
394
|
rubygems_version: 3.0.3
|
393
|
-
signing_key:
|
395
|
+
signing_key:
|
394
396
|
specification_version: 4
|
395
397
|
summary: A Rails engine for creating super-flexible admin dashboards
|
396
398
|
test_files: []
|