administrate 0.20.1 → 1.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +9 -9
- data/app/assets/builds/administrate/application.css +2542 -0
- data/app/assets/builds/administrate/application.css.map +1 -0
- data/app/assets/builds/administrate/application.js +22169 -0
- data/app/assets/builds/administrate/application.js.map +7 -0
- data/app/assets/builds/administrate-internal/docs.css +89 -0
- data/app/assets/builds/administrate-internal/docs.css.map +1 -0
- data/app/assets/config/administrate_manifest.js +2 -0
- data/app/assets/javascripts/administrate/add_jquery.js +4 -0
- data/app/assets/javascripts/administrate/application.js +8 -4
- data/app/assets/javascripts/administrate/controllers/application.js +9 -0
- data/app/assets/javascripts/administrate/controllers/index.js +7 -0
- data/app/assets/javascripts/administrate/controllers/select_controller.js +8 -0
- data/app/assets/javascripts/administrate/{components/table.js → controllers/table_controller.js} +9 -9
- data/app/assets/stylesheets/administrate/application.scss +3 -3
- data/app/assets/stylesheets/administrate/base/_forms.scss +4 -4
- data/app/assets/stylesheets/administrate/base/_layout.scss +5 -0
- data/app/assets/stylesheets/administrate/base/_tables.scss +1 -1
- data/app/assets/stylesheets/administrate/base/_typography.scss +12 -1
- data/app/assets/stylesheets/administrate/components/_attributes.scss +1 -0
- data/app/assets/stylesheets/administrate/components/_buttons.scss +12 -12
- data/app/assets/stylesheets/administrate/components/_cells.scss +19 -19
- data/app/assets/stylesheets/administrate/components/_field-unit.scss +3 -3
- data/app/assets/stylesheets/administrate/components/_main-content.scss +1 -1
- data/app/assets/stylesheets/administrate/components/_navigation.scss +3 -3
- data/app/assets/stylesheets/administrate/components/_search.scss +11 -11
- data/app/assets/stylesheets/administrate/library/_variables.scss +7 -3
- data/app/assets/stylesheets/administrate/reset/_normalize.scss +7 -1
- data/app/controllers/administrate/application_controller.rb +20 -19
- data/app/controllers/concerns/administrate/punditize.rb +5 -5
- data/app/helpers/administrate/application_helper.rb +4 -4
- data/app/views/administrate/application/_collection.html.erb +1 -1
- data/app/views/administrate/application/_collection_item_actions.html.erb +3 -3
- data/app/views/administrate/application/_index_header.html.erb +4 -0
- data/app/views/administrate/application/_javascript.html.erb +1 -1
- data/app/views/administrate/application/edit.html.erb +15 -3
- data/app/views/administrate/application/index.html.erb +19 -11
- data/app/views/administrate/application/new.html.erb +15 -3
- data/app/views/administrate/application/show.html.erb +35 -23
- data/app/views/fields/belongs_to/_form.html.erb +3 -2
- data/app/views/fields/has_many/_form.html.erb +1 -1
- data/app/views/fields/polymorphic/_form.html.erb +1 -1
- data/app/views/fields/rich_text/_form.html.erb +6 -0
- data/app/views/fields/rich_text/_index.html.erb +18 -0
- data/app/views/fields/rich_text/_show.html.erb +18 -0
- data/app/views/fields/select/_form.html.erb +2 -1
- data/app/views/fields/text/_form.html.erb +1 -1
- data/app/views/layouts/administrate/application.html.erb +1 -2
- data/docs/customizing_dashboards.md +138 -4
- data/docs/customizing_page_views.md +25 -0
- data/lib/administrate/base_dashboard.rb +6 -5
- data/lib/administrate/engine.rb +7 -6
- data/lib/administrate/field/associative.rb +5 -1
- data/lib/administrate/field/base.rb +21 -3
- data/lib/administrate/field/belongs_to.rb +7 -2
- data/lib/administrate/field/date.rb +1 -1
- data/lib/administrate/field/date_time.rb +2 -2
- data/lib/administrate/field/deferred.rb +10 -2
- data/lib/administrate/field/has_many.rb +5 -5
- data/lib/administrate/field/has_one.rb +10 -6
- data/lib/administrate/field/number.rb +2 -2
- data/lib/administrate/field/polymorphic.rb +3 -3
- data/lib/administrate/field/rich_text.rb +21 -0
- data/lib/administrate/field/select.rb +4 -0
- data/lib/administrate/generator_helpers.rb +1 -1
- data/lib/administrate/namespace/resource.rb +1 -1
- data/lib/administrate/order.rb +30 -26
- data/lib/administrate/page/base.rb +2 -7
- data/lib/administrate/page/collection.rb +2 -2
- data/lib/administrate/page/form.rb +1 -1
- data/lib/administrate/page/show.rb +1 -1
- data/lib/administrate/resource_resolver.rb +1 -1
- data/lib/administrate/search.rb +6 -7
- data/lib/administrate/version.rb +1 -1
- data/lib/administrate/view_generator.rb +3 -3
- data/lib/administrate.rb +18 -18
- data/lib/generators/administrate/dashboard/dashboard_generator.rb +12 -9
- data/lib/generators/administrate/field/field_generator.rb +2 -2
- data/lib/generators/administrate/install/install_generator.rb +2 -2
- data/lib/generators/administrate/routes/routes_generator.rb +5 -5
- data/lib/generators/administrate/views/field_generator.rb +2 -2
- data/lib/generators/administrate/views/index_generator.rb +1 -0
- data/lib/generators/administrate/views/layout_generator.rb +1 -1
- metadata +20 -53
- data/app/assets/javascripts/administrate/components/associative.js +0 -5
- data/app/assets/javascripts/administrate/components/select.js +0 -3
- data/app/assets/stylesheets/administrate/utilities/_text-color.scss +0 -3
- data/lib/generators/administrate/assets/assets_generator.rb +0 -12
- data/lib/generators/administrate/assets/javascripts_generator.rb +0 -17
- data/lib/generators/administrate/assets/stylesheets_generator.rb +0 -17
- /data/app/assets/stylesheets/{docs.scss → administrate-internal/docs.scss} +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
module Administrate
|
2
2
|
module Punditize
|
3
|
-
if Object.const_defined?(
|
3
|
+
if Object.const_defined?(:Pundit)
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
if Pundit.const_defined?(:Authorization)
|
@@ -28,7 +28,7 @@ module Administrate
|
|
28
28
|
def authorized_action?(resource, action)
|
29
29
|
namespaced_resource = policy_namespace + [resource]
|
30
30
|
policy = Pundit.policy!(pundit_user, namespaced_resource)
|
31
|
-
policy.send("#{action}?"
|
31
|
+
policy.send(:"#{action}?")
|
32
32
|
end
|
33
33
|
|
34
34
|
def policy_scope!(user, scope)
|
@@ -38,13 +38,13 @@ module Administrate
|
|
38
38
|
policy_scope = policy_scope_class.new(user, pundit_model(scope))
|
39
39
|
rescue ArgumentError
|
40
40
|
raise(Pundit::InvalidConstructorError,
|
41
|
-
|
41
|
+
"Invalid #<#{policy_scope_class}> constructor is called")
|
42
42
|
end
|
43
43
|
|
44
44
|
if policy_scope.respond_to? :resolve_admin
|
45
45
|
Administrate.deprecator.warn(
|
46
|
-
"Pundit policy scope `resolve_admin` method is deprecated. "
|
47
|
-
"Please use a namespaced pundit policy instead."
|
46
|
+
"Pundit policy scope `resolve_admin` method is deprecated. " \
|
47
|
+
"Please use a namespaced pundit policy instead."
|
48
48
|
)
|
49
49
|
policy_scope.resolve_admin
|
50
50
|
else
|
@@ -50,7 +50,7 @@ module Administrate
|
|
50
50
|
def display_resource_name(resource_name, opts = {})
|
51
51
|
dashboard_from_resource(resource_name).resource_name(
|
52
52
|
count: opts[:singular] ? SINGULAR_COUNT : PLURAL_MANY_COUNT,
|
53
|
-
default: default_resource_name(resource_name, opts)
|
53
|
+
default: default_resource_name(resource_name, opts)
|
54
54
|
)
|
55
55
|
end
|
56
56
|
|
@@ -65,14 +65,14 @@ module Administrate
|
|
65
65
|
def resource_index_route(resource_name)
|
66
66
|
url_for(
|
67
67
|
action: "index",
|
68
|
-
controller: "/#{namespace}/#{resource_name}"
|
68
|
+
controller: "/#{namespace}/#{resource_name}"
|
69
69
|
)
|
70
70
|
end
|
71
71
|
|
72
72
|
def sanitized_order_params(page, current_field_name)
|
73
73
|
collection_names = page.item_associations + [current_field_name]
|
74
74
|
association_params = collection_names.map do |assoc_name|
|
75
|
-
{
|
75
|
+
{assoc_name => %i[order direction page per_page]}
|
76
76
|
end
|
77
77
|
params.permit(:search, :id, :_page, :per_page, association_params)
|
78
78
|
end
|
@@ -87,7 +87,7 @@ module Administrate
|
|
87
87
|
|
88
88
|
def default_resource_name(name, opts = {})
|
89
89
|
resource_name = (opts[:singular] ? name.to_s : name.to_s.pluralize)
|
90
|
-
resource_name.
|
90
|
+
resource_name.tr("/", "_").titleize
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
@@ -18,7 +18,7 @@ to display a collection of resources in an HTML table.
|
|
18
18
|
[1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection
|
19
19
|
%>
|
20
20
|
|
21
|
-
<table aria-labelledby="<%= table_title %>">
|
21
|
+
<table aria-labelledby="<%= table_title %>" data-controller="table" data-action="click->table#visitDataUrl keydown->table#visitDataUrl">
|
22
22
|
<thead>
|
23
23
|
<tr>
|
24
24
|
<% collection_presenter.attribute_types.each do |attr_name, attr_type| %>
|
@@ -7,11 +7,11 @@
|
|
7
7
|
<% end %>
|
8
8
|
|
9
9
|
<% if existing_action?(collection_presenter.resource_name, :destroy) %>
|
10
|
-
<td><%=
|
10
|
+
<td><%= button_to(
|
11
11
|
t("administrate.actions.destroy"),
|
12
12
|
[namespace, resource],
|
13
|
-
class: "
|
13
|
+
class: "link link--danger",
|
14
14
|
method: :delete,
|
15
|
-
data: {
|
15
|
+
data: { turbo_confirm: t("administrate.actions.confirm") }
|
16
16
|
) if accessible_action?(resource, :destroy) %></td>
|
17
17
|
<% end %>
|
@@ -7,6 +7,8 @@
|
|
7
7
|
<%= content_for(:title) %>
|
8
8
|
</h1>
|
9
9
|
|
10
|
+
<%= content_for(:header_middle) %>
|
11
|
+
|
10
12
|
<% if show_search_bar %>
|
11
13
|
<%= render(
|
12
14
|
"search",
|
@@ -25,4 +27,6 @@
|
|
25
27
|
class: "button",
|
26
28
|
) if accessible_action?(new_resource, :new) %>
|
27
29
|
</div>
|
30
|
+
|
31
|
+
<%= content_for(:header_last) %>
|
28
32
|
</header>
|
@@ -8,7 +8,7 @@ by providing a `content_for(:javascript)` block.
|
|
8
8
|
%>
|
9
9
|
|
10
10
|
<% Administrate::Engine.javascripts.each do |js_path| %>
|
11
|
-
<%= javascript_include_tag js_path %>
|
11
|
+
<%= javascript_include_tag js_path, "data-turbo-track": "reload", defer: true %>
|
12
12
|
<% end %>
|
13
13
|
|
14
14
|
<%= yield :javascript %>
|
@@ -22,6 +22,8 @@ It displays a header, and renders the `_form` partial to do the heavy lifting.
|
|
22
22
|
<%= content_for(:title) %>
|
23
23
|
</h1>
|
24
24
|
|
25
|
+
<%= content_for(:header_middle) %>
|
26
|
+
|
25
27
|
<div>
|
26
28
|
<%= link_to(
|
27
29
|
t("administrate.actions.show_resource", name: page.page_title),
|
@@ -29,8 +31,18 @@ It displays a header, and renders the `_form` partial to do the heavy lifting.
|
|
29
31
|
class: "button",
|
30
32
|
) if accessible_action?(page.resource, :show) %>
|
31
33
|
</div>
|
34
|
+
|
35
|
+
<%= content_for(:header_last) %>
|
32
36
|
</header>
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
|
38
|
+
<%= content_for(:before_main) %>
|
39
|
+
|
40
|
+
<% if content_for?(:main) %>
|
41
|
+
<%= content_for(:main) %>
|
42
|
+
<% else %>
|
43
|
+
<section class="main-content__body">
|
44
|
+
<%= render "form", page: page %>
|
45
|
+
</section>
|
46
|
+
<% end %>
|
47
|
+
|
48
|
+
<%= content_for(:after_main) %>
|
@@ -32,15 +32,23 @@ It renders the `_table` partial to display details about the resources.
|
|
32
32
|
)
|
33
33
|
%>
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
35
|
+
<%= content_for(:before_main) %>
|
36
|
+
|
37
|
+
<% if content_for?(:main) %>
|
38
|
+
<%= content_for(:main) %>
|
39
|
+
<% else %>
|
40
|
+
<section class="main-content__body main-content__body--flush">
|
41
|
+
<%= render(
|
42
|
+
"collection",
|
43
|
+
collection_presenter: page,
|
44
|
+
collection_field_name: resource_name,
|
45
|
+
page: page,
|
46
|
+
resources: resources,
|
47
|
+
table_title: "page-title"
|
48
|
+
) %>
|
49
|
+
|
50
|
+
<%= render("pagination", resources: resources) %>
|
51
|
+
</section>
|
52
|
+
<% end %>
|
44
53
|
|
45
|
-
|
46
|
-
</section>
|
54
|
+
<%= content_for(:after_main) %>
|
@@ -27,11 +27,23 @@ to do the heavy lifting.
|
|
27
27
|
<%= content_for(:title) %>
|
28
28
|
</h1>
|
29
29
|
|
30
|
+
<%= content_for(:header_middle) %>
|
31
|
+
|
30
32
|
<div>
|
31
33
|
<%= link_to t("administrate.actions.back"), :back, class: "button" %>
|
32
34
|
</div>
|
35
|
+
|
36
|
+
<%= content_for(:header_last) %>
|
33
37
|
</header>
|
34
38
|
|
35
|
-
|
36
|
-
|
37
|
-
|
39
|
+
<%= content_for(:before_main) %>
|
40
|
+
|
41
|
+
<% if content_for?(:main) %>
|
42
|
+
<%= content_for(:main) %>
|
43
|
+
<% else %>
|
44
|
+
<section class="main-content__body">
|
45
|
+
<%= render "form", page: page %>
|
46
|
+
</section>
|
47
|
+
<% end %>
|
48
|
+
|
49
|
+
<%= content_for(:after_main) %>
|
@@ -23,6 +23,8 @@ as well as a link to its edit page.
|
|
23
23
|
<%= content_for(:title) %>
|
24
24
|
</h1>
|
25
25
|
|
26
|
+
<%= content_for(:header_middle) %>
|
27
|
+
|
26
28
|
<div>
|
27
29
|
<%= link_to(
|
28
30
|
t("administrate.actions.edit_resource", name: page.page_title),
|
@@ -30,36 +32,46 @@ as well as a link to its edit page.
|
|
30
32
|
class: "button",
|
31
33
|
) if accessible_action?(page.resource, :edit) %>
|
32
34
|
|
33
|
-
<%=
|
35
|
+
<%= button_to(
|
34
36
|
t("administrate.actions.destroy"),
|
35
37
|
[namespace, page.resource],
|
36
38
|
class: "button button--danger",
|
37
39
|
method: :delete,
|
38
|
-
data: {
|
40
|
+
data: { turbo_confirm: t("administrate.actions.confirm") }
|
39
41
|
) if accessible_action?(page.resource, :destroy) %>
|
40
42
|
</div>
|
43
|
+
|
44
|
+
<%= content_for(:header_last) %>
|
41
45
|
</header>
|
42
46
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
<%= content_for(:before_main) %>
|
48
|
+
|
49
|
+
<% if content_for?(:main) %>
|
50
|
+
<%= content_for(:main) %>
|
51
|
+
<% else %>
|
52
|
+
<section class="main-content__body">
|
53
|
+
<dl>
|
54
|
+
<% page.attributes.each do |title, attributes| %>
|
55
|
+
<fieldset class="<%= "field-unit--nested" if title.present? %>">
|
56
|
+
<% if title.present? %>
|
57
|
+
<legend><%= t "helpers.label.#{page.resource_name}.#{title}", default: title %></legend>
|
58
|
+
<% end %>
|
59
|
+
|
60
|
+
<% attributes.each do |attribute| %>
|
61
|
+
<dt class="attribute-label" id="<%= attribute.name %>">
|
62
|
+
<%= t(
|
63
|
+
"helpers.label.#{resource_name}.#{attribute.name}",
|
64
|
+
default: page.resource.class.human_attribute_name(attribute.name),
|
65
|
+
) %>
|
66
|
+
</dt>
|
50
67
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
68
|
+
<dd class="attribute-data attribute-data--<%=attribute.html_class%>"
|
69
|
+
><%= render_field attribute, page: page %></dd>
|
70
|
+
<% end %>
|
71
|
+
</fieldset>
|
72
|
+
<% end %>
|
73
|
+
</dl>
|
74
|
+
</section>
|
75
|
+
<% end %>
|
58
76
|
|
59
|
-
|
60
|
-
><%= render_field attribute, page: page %></dd>
|
61
|
-
<% end %>
|
62
|
-
</fieldset>
|
63
|
-
<% end %>
|
64
|
-
</dl>
|
65
|
-
</section>
|
77
|
+
<%= content_for(:after_main) %>
|
@@ -17,10 +17,11 @@ that displays all possible records to associate with.
|
|
17
17
|
%>
|
18
18
|
|
19
19
|
<div class="field-unit__label">
|
20
|
-
<%= f.label field.permitted_attribute %>
|
20
|
+
<%= f.label field.attribute, for: "#{f.object_name}_#{field.permitted_attribute}" %>
|
21
21
|
</div>
|
22
22
|
<div class="field-unit__field">
|
23
23
|
<%= f.select(field.permitted_attribute,
|
24
24
|
options_for_select(field.associated_resource_options, field.selected_option),
|
25
|
-
include_blank: field.include_blank_option
|
25
|
+
{include_blank: field.include_blank_option},
|
26
|
+
data: {controller: field.html_controller}) %>
|
26
27
|
</div>
|
@@ -23,7 +23,7 @@ and is augmented with [Selectize].
|
|
23
23
|
<%= f.label field.attribute, for: "#{f.object_name}_#{field.attribute_key}" %>
|
24
24
|
</div>
|
25
25
|
<div class="field-unit__field">
|
26
|
-
<%= f.select(field.attribute_key, nil, {}, multiple: true) do %>
|
26
|
+
<%= f.select(field.attribute_key, nil, {}, multiple: true, data: {controller: field.html_controller}) do %>
|
27
27
|
<%= options_for_select(field.associated_resource_options, field.selected_options) %>
|
28
28
|
<% end %>
|
29
29
|
</div>
|
@@ -22,7 +22,7 @@ This partial renders an input element for polymorphic relationships.
|
|
22
22
|
|
23
23
|
<div class="field-unit__field">
|
24
24
|
<%= pf.hidden_field(:type, value: field.class.name) %>
|
25
|
-
<%= pf.select(:value) do %>
|
25
|
+
<%= pf.select(:value, {}, data: {controller: field.html_controller}) do %>
|
26
26
|
<%= grouped_options_for_select(field.associated_resource_grouped_options, field.selected_global_id, prompt: true) %>
|
27
27
|
<% end %>
|
28
28
|
</div>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<%#
|
2
|
+
# RichText Index Partial
|
3
|
+
|
4
|
+
This partial renders a rich_text attribute
|
5
|
+
to be displayed on a resource's index page.
|
6
|
+
|
7
|
+
By default, the attribute is rendered as a plain text truncated string.
|
8
|
+
|
9
|
+
## Local variables:
|
10
|
+
|
11
|
+
- `field`:
|
12
|
+
An instance of [Administrate::Field::RichText][1].
|
13
|
+
A wrapper around the RichText pulled from the database.
|
14
|
+
|
15
|
+
[1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/RichText
|
16
|
+
%>
|
17
|
+
|
18
|
+
<%= field.truncate %>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<%#
|
2
|
+
# RichText Show Partial
|
3
|
+
|
4
|
+
This partial renders a rich_text attribute,
|
5
|
+
to be displayed on a resource's show page.
|
6
|
+
|
7
|
+
By default, the attribute is rendered as HTML.
|
8
|
+
|
9
|
+
## Local variables:
|
10
|
+
|
11
|
+
- `field`:
|
12
|
+
An instance of [Administrate::Field::RichText][1].
|
13
|
+
A wrapper around the RichText object pulled from the database.
|
14
|
+
|
15
|
+
[1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/RichText
|
16
|
+
%>
|
17
|
+
|
18
|
+
<%= field.data %>
|
@@ -18,5 +18,5 @@ This partial renders a textarea element for a text attribute.
|
|
18
18
|
<%= f.label field.attribute %>
|
19
19
|
</div>
|
20
20
|
<div class="field-unit__field">
|
21
|
-
<%= f.text_area field.attribute %>
|
21
|
+
<%= f.text_area field.attribute, field.options.fetch(:input_options, {}) %>
|
22
22
|
</div>
|
@@ -24,6 +24,7 @@ By default, it renders:
|
|
24
24
|
<%= render "stylesheet" %>
|
25
25
|
<%= csrf_meta_tags %>
|
26
26
|
<%= csp_meta_tag if defined?(csp_meta_tag) %>
|
27
|
+
<%= render "javascript" %>
|
27
28
|
</head>
|
28
29
|
<body>
|
29
30
|
<%= render "icons" %>
|
@@ -36,7 +37,5 @@ By default, it renders:
|
|
36
37
|
<%= yield %>
|
37
38
|
</main>
|
38
39
|
</div>
|
39
|
-
|
40
|
-
<%= render "javascript" %>
|
41
40
|
</body>
|
42
41
|
</html>
|
@@ -82,7 +82,8 @@ the table views and in the dropdown menu on the record forms.
|
|
82
82
|
You can set multiple columns as well with direction. E.g.: `"name, email DESC"`.
|
83
83
|
|
84
84
|
`:scope` - Specifies a custom scope inside a callable. Useful for preloading.
|
85
|
-
Example: `.with_options(scope: -> { MyModel.includes(:rel).limit(5) })`
|
85
|
+
Example #1: `.with_options(scope: -> { MyModel.includes(:rel).limit(5) })`
|
86
|
+
Example #2: `.with_options(scope: -> (field) { field.resource.my_models.includes(:rel).limit(5) })`
|
86
87
|
|
87
88
|
`:include_blank` - Specifies if the select element to be rendered should include
|
88
89
|
blank option. Default is `true`.
|
@@ -113,7 +114,7 @@ association `belongs_to :country`, from your model.
|
|
113
114
|
|
114
115
|
**Field::HasMany**
|
115
116
|
|
116
|
-
`:collection_attributes` - Set the columns to display in the show view.
|
117
|
+
`:collection_attributes` - Set the columns to display in the show view.
|
117
118
|
Default is COLLECTION_ATTRIBUTES in dashboard.
|
118
119
|
|
119
120
|
`:limit` - The number of resources (paginated) to display in the show view. To disable pagination,
|
@@ -144,14 +145,14 @@ Default is `false`.
|
|
144
145
|
For example:
|
145
146
|
|
146
147
|
```ruby
|
147
|
-
|
148
|
+
city: Field::HasOne.with_options(
|
148
149
|
searchable: true,
|
149
150
|
searchable_fields: ['name'],
|
150
151
|
)
|
151
152
|
```
|
152
153
|
|
153
154
|
with this, you will be able to search through the column `name` from the
|
154
|
-
association `
|
155
|
+
association `has_one :city`, from your model.
|
155
156
|
|
156
157
|
`:class_name` (deprecated) - Specifies the name of the associated class.
|
157
158
|
|
@@ -266,6 +267,9 @@ Default is `false`.
|
|
266
267
|
`:truncate` - Set the number of characters to display in the index view.
|
267
268
|
Defaults to `50`.
|
268
269
|
|
270
|
+
`:input_options` - Options to customize the text area in form view.
|
271
|
+
Example: `.with_options(input_options: { rows: 20 })`
|
272
|
+
|
269
273
|
**Field::Url**
|
270
274
|
|
271
275
|
`:searchable` - Specify if the attribute should be considered when searching.
|
@@ -436,3 +440,133 @@ en:
|
|
436
440
|
```
|
437
441
|
|
438
442
|
If not defined (see `SHOW_PAGE_ATTRIBUTES` above), Administrate will default to the given strings.
|
443
|
+
|
444
|
+
## Virtual Attributes
|
445
|
+
|
446
|
+
For all field types, you can use the `getter` option to change where the data is retrieved from or to set the data directly.
|
447
|
+
|
448
|
+
By using this, you can define an attribute in `ATTRIBUTE_TYPES` that doesn’t exist in the model, and use it for various purposes.
|
449
|
+
|
450
|
+
### Attribute Aliases
|
451
|
+
|
452
|
+
You can create an alias for an attribute. For example:
|
453
|
+
|
454
|
+
```ruby
|
455
|
+
ATTRIBUTE_TYPES = {
|
456
|
+
shipped_at: Field::DateTime,
|
457
|
+
shipped_on: Field::Date.with_options(
|
458
|
+
getter: :shipped_at
|
459
|
+
)
|
460
|
+
}
|
461
|
+
COLLECTION_ATTRIBUTES = [
|
462
|
+
:shipped_on
|
463
|
+
}
|
464
|
+
SHOW_PAGE_ATTRIBUTES = [
|
465
|
+
:shipped_at
|
466
|
+
}
|
467
|
+
```
|
468
|
+
|
469
|
+
In this example, a virtual attribute `shipped_on` based on the value of `shipped_at` is defined as a `Date` type and used for display on the index page (this can help save table cell space).
|
470
|
+
|
471
|
+
### Decorated Attributes
|
472
|
+
|
473
|
+
You can also use this to decorate data. For example:
|
474
|
+
|
475
|
+
```ruby
|
476
|
+
ATTRIBUTE_TYPES = {
|
477
|
+
price: Field::Number,
|
478
|
+
price_including_tax: Field::Number.with_options(
|
479
|
+
getter: -> (field) {
|
480
|
+
field.resource.price * 1.1 if field.resource.price.present?
|
481
|
+
}
|
482
|
+
)
|
483
|
+
}
|
484
|
+
```
|
485
|
+
|
486
|
+
### Composite Attributes
|
487
|
+
|
488
|
+
You can dynamically create a virtual attribute by combining multiple attributes for display. For example:
|
489
|
+
|
490
|
+
```ruby
|
491
|
+
ATTRIBUTE_TYPES = {
|
492
|
+
first_name: Field::String,
|
493
|
+
last_name: Field::String,
|
494
|
+
full_name: Field::String.with_options(
|
495
|
+
getter: -> (field) {
|
496
|
+
[
|
497
|
+
field.resource.first_name,
|
498
|
+
field.resource.last_name
|
499
|
+
].compact_blank.join(' ')
|
500
|
+
}
|
501
|
+
)
|
502
|
+
}
|
503
|
+
```
|
504
|
+
|
505
|
+
## Virtual Fields
|
506
|
+
|
507
|
+
Custom fields can also be defined using virtual fields.
|
508
|
+
|
509
|
+
```ruby
|
510
|
+
ATTRIBUTE_TYPES = {
|
511
|
+
id: Field::Number,
|
512
|
+
receipt: Field::ReceiptLink
|
513
|
+
}
|
514
|
+
```
|
515
|
+
|
516
|
+
```ruby
|
517
|
+
module Administrate
|
518
|
+
module Field
|
519
|
+
class ReceiptLink < Base
|
520
|
+
def data
|
521
|
+
resource.id
|
522
|
+
end
|
523
|
+
|
524
|
+
def filename
|
525
|
+
"receipt-#{data}.pdf"
|
526
|
+
end
|
527
|
+
|
528
|
+
def url
|
529
|
+
"/files/receipts/#{filename}"
|
530
|
+
end
|
531
|
+
end
|
532
|
+
end
|
533
|
+
end
|
534
|
+
```
|
535
|
+
|
536
|
+
```erb
|
537
|
+
<%= link_to field.filename, field.url %>
|
538
|
+
```
|
539
|
+
|
540
|
+
### Custom Actions via Virtual Field
|
541
|
+
|
542
|
+
By creating custom fields that are not dependent on specific attributes, you can insert custom views into any screen.
|
543
|
+
For example, you can add custom buttons like this:
|
544
|
+
|
545
|
+
```ruby
|
546
|
+
ATTRIBUTE_TYPES = {
|
547
|
+
id: Field::Number,
|
548
|
+
custom_index_actions: Field::CustomActionButtons,
|
549
|
+
custom_show_actions: Field::CustomActionButtons,
|
550
|
+
}
|
551
|
+
```
|
552
|
+
|
553
|
+
```ruby
|
554
|
+
module Administrate
|
555
|
+
module Field
|
556
|
+
class CustomActionButtons < Base
|
557
|
+
def data
|
558
|
+
resource.id
|
559
|
+
end
|
560
|
+
end
|
561
|
+
end
|
562
|
+
end
|
563
|
+
```
|
564
|
+
|
565
|
+
```erb
|
566
|
+
<%# app/views/fields/custom_action_buttons/_index.html.erb %>
|
567
|
+
<% if field.data.present? %>
|
568
|
+
<%= button_to "some action 1", [:some_action_1, namespace, field.resource] %>
|
569
|
+
<%= button_to "some action 2", [:some_action_2, namespace, field.resource] %>
|
570
|
+
<%= button_to "some action 3", [:some_action_3, namespace, field.resource] %>
|
571
|
+
<% end %>
|
572
|
+
```
|
@@ -94,3 +94,28 @@ rails generate administrate:views:layout
|
|
94
94
|
# It only generates the sidebar partial
|
95
95
|
# -> app/views/admin/application/_navigation.html.erb
|
96
96
|
```
|
97
|
+
|
98
|
+
## Customizing for a specific layout
|
99
|
+
|
100
|
+
You can use several hook points to add elements to specific layouts or specific pages:
|
101
|
+
|
102
|
+
* header_middle
|
103
|
+
* header_last
|
104
|
+
* before_main
|
105
|
+
* main
|
106
|
+
* after_main
|
107
|
+
|
108
|
+
For example, you can add a button in the middle of the header as follows:
|
109
|
+
|
110
|
+
```eruby
|
111
|
+
<%# app/views/admin/customers/_index_header.html.erb %>
|
112
|
+
|
113
|
+
<% content_for(:header_middle) do %>
|
114
|
+
<div>
|
115
|
+
You are logged in as <em><%= pundit_user.name %></em>.
|
116
|
+
<%= link_to("Become the Admin", become_admin_customer_path("admin")) unless pundit_user.admin? %>
|
117
|
+
</div>
|
118
|
+
<% end %>
|
119
|
+
|
120
|
+
<%= render template: 'administrate/application/_index_header', locals: local_assigns %>
|
121
|
+
```
|
@@ -7,6 +7,7 @@ require "administrate/field/has_many"
|
|
7
7
|
require "administrate/field/has_one"
|
8
8
|
require "administrate/field/number"
|
9
9
|
require "administrate/field/polymorphic"
|
10
|
+
require "administrate/field/rich_text"
|
10
11
|
require "administrate/field/select"
|
11
12
|
require "administrate/field/string"
|
12
13
|
require "administrate/field/text"
|
@@ -79,7 +80,7 @@ module Administrate
|
|
79
80
|
attribute_types[attr].permitted_attribute(
|
80
81
|
attr,
|
81
82
|
resource_class: self.class.model,
|
82
|
-
action: action
|
83
|
+
action: action
|
83
84
|
)
|
84
85
|
end.uniq
|
85
86
|
end
|
@@ -118,10 +119,10 @@ module Administrate
|
|
118
119
|
|
119
120
|
def item_associations
|
120
121
|
attributes = if show_page_attributes.is_a?(Hash)
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
122
|
+
show_page_attributes.values.flatten
|
123
|
+
else
|
124
|
+
show_page_attributes
|
125
|
+
end
|
125
126
|
attribute_associated attributes
|
126
127
|
end
|
127
128
|
|