administrate 0.17.0 → 0.19.0

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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +0 -2
  3. data/app/assets/javascripts/administrate/application.js +0 -2
  4. data/app/assets/javascripts/administrate/components/select.js +3 -0
  5. data/app/assets/stylesheets/administrate/application.scss +0 -1
  6. data/app/assets/stylesheets/administrate/base/_forms.scss +1 -1
  7. data/app/assets/stylesheets/administrate/components/_buttons.scss +9 -0
  8. data/app/assets/stylesheets/administrate/components/_flashes.scss +2 -2
  9. data/app/assets/stylesheets/administrate/library/_variables.scss +1 -1
  10. data/app/controllers/administrate/application_controller.rb +84 -17
  11. data/app/controllers/concerns/administrate/punditize.rb +41 -13
  12. data/app/helpers/administrate/application_helper.rb +24 -6
  13. data/app/views/administrate/application/_collection.html.erb +5 -6
  14. data/app/views/administrate/application/_collection_header_actions.html.erb +2 -2
  15. data/app/views/administrate/application/_collection_item_actions.html.erb +4 -4
  16. data/app/views/administrate/application/_index_header.html.erb +2 -2
  17. data/app/views/administrate/application/_navigation.html.erb +2 -2
  18. data/app/views/administrate/application/_pagination.html.erb +1 -0
  19. data/app/views/administrate/application/edit.html.erb +2 -2
  20. data/app/views/administrate/application/index.html.erb +1 -1
  21. data/app/views/administrate/application/new.html.erb +1 -1
  22. data/app/views/administrate/application/show.html.erb +10 -2
  23. data/app/views/fields/belongs_to/_index.html.erb +1 -1
  24. data/app/views/fields/belongs_to/_show.html.erb +1 -1
  25. data/app/views/fields/date/_form.html.erb +1 -3
  26. data/app/views/fields/date_time/_form.html.erb +1 -3
  27. data/app/views/fields/has_many/_index.html.erb +1 -1
  28. data/app/views/fields/has_many/_show.html.erb +2 -1
  29. data/app/views/fields/has_one/_form.html.erb +1 -1
  30. data/app/views/fields/has_one/_index.html.erb +2 -1
  31. data/app/views/fields/has_one/_show.html.erb +3 -2
  32. data/app/views/fields/polymorphic/_index.html.erb +2 -1
  33. data/app/views/fields/polymorphic/_show.html.erb +1 -1
  34. data/app/views/fields/select/_form.html.erb +5 -18
  35. data/app/views/fields/time/_form.html.erb +2 -3
  36. data/app/views/fields/url/_index.html.erb +1 -1
  37. data/app/views/fields/url/_show.html.erb +1 -1
  38. data/app/views/layouts/administrate/application.html.erb +1 -1
  39. data/config/locales/administrate.de.yml +2 -2
  40. data/config/locales/administrate.ja.yml +5 -5
  41. data/config/locales/administrate.sl.yml +30 -0
  42. data/docs/adding_controllers_without_related_model.md +2 -2
  43. data/docs/authorization.md +43 -20
  44. data/docs/customizing_controller_actions.md +11 -6
  45. data/docs/customizing_dashboards.md +33 -8
  46. data/docs/getting_started.md +1 -1
  47. data/docs/guides/customising_search.md +149 -0
  48. data/docs/guides/hiding_dashboards_from_sidebar.md +4 -2
  49. data/docs/guides/scoping_has_many_relations.md +27 -0
  50. data/docs/guides.md +3 -1
  51. data/lib/administrate/base_dashboard.rb +23 -2
  52. data/lib/administrate/engine.rb +2 -2
  53. data/lib/administrate/field/associative.rb +18 -8
  54. data/lib/administrate/field/base.rb +4 -0
  55. data/lib/administrate/field/belongs_to.rb +9 -2
  56. data/lib/administrate/field/deferred.rb +4 -0
  57. data/lib/administrate/field/has_many.rb +15 -5
  58. data/lib/administrate/field/has_one.rb +4 -0
  59. data/lib/administrate/field/polymorphic.rb +2 -1
  60. data/lib/administrate/field/select.rb +19 -9
  61. data/lib/administrate/field/url.rb +4 -0
  62. data/lib/administrate/not_authorized_error.rb +20 -0
  63. data/lib/administrate/order.rb +68 -13
  64. data/lib/administrate/page/base.rb +4 -0
  65. data/lib/administrate/page/form.rb +0 -7
  66. data/lib/administrate/resource_resolver.rb +2 -1
  67. data/lib/administrate/search.rb +1 -1
  68. data/lib/administrate/version.rb +1 -1
  69. data/lib/administrate/view_generator.rb +6 -1
  70. data/lib/administrate.rb +18 -0
  71. data/lib/generators/administrate/dashboard/dashboard_generator.rb +20 -2
  72. data/lib/generators/administrate/dashboard/templates/controller.rb.erb +2 -2
  73. data/lib/generators/administrate/install/install_generator.rb +6 -1
  74. data/lib/generators/administrate/routes/routes_generator.rb +11 -2
  75. data/lib/generators/administrate/test_record.rb +21 -0
  76. metadata +10 -35
  77. data/app/assets/javascripts/administrate/components/date_time_picker.js +0 -14
  78. data/config/i18n-tasks.yml +0 -18
  79. data/config/routes.rb +0 -2
  80. data/config/unicorn.rb +0 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a099c28c8a74491759229e6fe82de763f25b9ff59473d5c70b00d38675e3498
4
- data.tar.gz: c24140b9e1bc63eb9ecd5f38cd0cfd3d3c0f125a81370df1dd6663af66121baa
3
+ metadata.gz: a94bb51af4fa730f84d042f402122cc3073894e67494309dab4621b5f39b36fa
4
+ data.tar.gz: 57e7d78f316c635be65735e5c4220bd4e8d777c29c1d92741ab2520998080cde
5
5
  SHA512:
6
- metadata.gz: 8ada94532afa210a359eece24f042fdb7de549cdb6bb94507c044f85df7b26cfbd5855202de2016255d635d2448dcba303d91eac4dc41c896f30e52f95073345
7
- data.tar.gz: 98e115c8c3acfe7dc5cab3a3055b5f06dfa5661f9d2eb135c528b474cbe36e6fb51b36a8c88489860a9fda200758ce37f4d60375705f0e0234af4dc2805e75ff
6
+ metadata.gz: 4d7b0a4b21404d16b48a5545e57202b73b3d782e23a5b26b5ed9e52ab3a66069717e23b1e099727eba9ff99315ba757d8ad0b739895a56775fbb5f3f8279df29
7
+ data.tar.gz: 07cc800c0c7cca79231ac047d10120ef63ec1c7d95aa5dccac9c7b1b5a99cafaccc2c31165c7350920721e622063190b0f804fb05d1e436c518511639802d4bd
data/Rakefile CHANGED
@@ -28,5 +28,3 @@ if defined? RSpec
28
28
  t.verbose = false
29
29
  end
30
30
  end
31
-
32
- task default: "bundler:audit"
@@ -1,6 +1,4 @@
1
1
  //= require jquery
2
2
  //= require jquery_ujs
3
3
  //= require selectize
4
- //= require moment
5
- //= require datetime_picker
6
4
  //= require_tree .
@@ -0,0 +1,3 @@
1
+ $(function() {
2
+ $('.field-unit--select select').selectize({});
3
+ });
@@ -3,7 +3,6 @@
3
3
  @import "reset/normalize";
4
4
 
5
5
  @import "selectize";
6
- @import "datetime_picker";
7
6
 
8
7
  @import "library/clearfix";
9
8
  @import "library/data-label";
@@ -85,7 +85,7 @@ textarea {
85
85
  [type="checkbox"],
86
86
  [type="radio"] {
87
87
  display: inline;
88
- margin-right: $small-spacing / 2;
88
+ margin-right: $small-spacing * 0.5;
89
89
  }
90
90
 
91
91
  [type="file"] {
@@ -49,6 +49,15 @@ input[type="submit"],
49
49
  color: $blue;
50
50
  }
51
51
 
52
+ .button--danger {
53
+ background-color: $red;
54
+
55
+ &:hover {
56
+ background-color: mix($black, $red, 20%);
57
+ color: $white;
58
+ }
59
+ }
60
+
52
61
  .button--nav {
53
62
  margin-bottom: $base-spacing;
54
63
  }
@@ -3,8 +3,8 @@
3
3
  background-color: $color;
4
4
  color: mix($black, $color, 60%);
5
5
  display: block;
6
- margin-bottom: $base-spacing / 2;
7
- padding: $base-spacing / 2;
6
+ margin-bottom: $base-spacing * 0.5;
7
+ padding: $base-spacing * 0.5;
8
8
  text-align: center;
9
9
 
10
10
  a {
@@ -14,7 +14,7 @@ $heading-line-height: 1.2 !default;
14
14
  // Other Sizes
15
15
  $base-border-radius: 4px !default;
16
16
  $base-spacing: $base-line-height * 1em !default;
17
- $small-spacing: $base-spacing / 2 !default;
17
+ $small-spacing: $base-spacing * 0.5 !default;
18
18
 
19
19
  // Colors
20
20
  $white: #fff !default;
@@ -5,12 +5,10 @@ module Administrate
5
5
  def index
6
6
  authorize_resource(resource_class)
7
7
  search_term = params[:search].to_s.strip
8
- resources = Administrate::Search.new(scoped_resource,
9
- dashboard,
10
- search_term).run
8
+ resources = filter_resources(scoped_resource, search_term: search_term)
11
9
  resources = apply_collection_includes(resources)
12
10
  resources = order.apply(resources)
13
- resources = resources.page(params[:_page]).per(records_per_page)
11
+ resources = paginate_resources(resources)
14
12
  page = Administrate::Page::Collection.new(dashboard, order: order)
15
13
 
16
14
  render locals: {
@@ -42,7 +40,7 @@ module Administrate
42
40
  end
43
41
 
44
42
  def create
45
- resource = resource_class.new(resource_params)
43
+ resource = new_resource(resource_params)
46
44
  authorize_resource(resource)
47
45
 
48
46
  if resource.save
@@ -81,6 +79,14 @@ module Administrate
81
79
 
82
80
  private
83
81
 
82
+ def filter_resources(resources, search_term:)
83
+ Administrate::Search.new(
84
+ resources,
85
+ dashboard,
86
+ search_term,
87
+ ).run
88
+ end
89
+
84
90
  def after_resource_destroyed_path(_requested_resource)
85
91
  { action: :index }
86
92
  end
@@ -99,15 +105,30 @@ module Administrate
99
105
  resource_name.to_s.pluralize == underscore_resource ? :active : :inactive
100
106
  end
101
107
 
102
- helper_method :valid_action?
103
- def valid_action?(name, resource = resource_class)
104
- !!routes.detect do |controller, action|
105
- controller == resource.to_s.underscore.pluralize && action == name.to_s
106
- end
108
+ # Whether the named action route exists for the resource class.
109
+ #
110
+ # @param resource [Class, String, Symbol] A class of resources, or the name
111
+ # of a class of resources.
112
+ # @param action_name [String, Symbol] The name of an action that might be
113
+ # possible to perform on a resource or resource class.
114
+ # @return [Boolean] `true` if a route exists for the resource class and the
115
+ # action. `false` otherwise.
116
+ def existing_action?(resource, action_name)
117
+ routes.include?([resource.to_s.underscore.pluralize, action_name.to_s])
118
+ end
119
+ helper_method :existing_action?
120
+
121
+ # @deprecated Use {#existing_action} instead. Note that, in
122
+ # {#existing_action}, the order of parameters is reversed and
123
+ # there is no default value for the `resource` parameter.
124
+ def valid_action?(action_name, resource = resource_class)
125
+ Administrate.warn_of_deprecated_authorization_method(__method__)
126
+ existing_action?(resource, action_name)
107
127
  end
128
+ helper_method :valid_action?
108
129
 
109
130
  def routes
110
- @routes ||= Namespace.new(namespace).routes
131
+ @routes ||= Namespace.new(namespace).routes.to_set
111
132
  end
112
133
 
113
134
  def records_per_page
@@ -115,7 +136,23 @@ module Administrate
115
136
  end
116
137
 
117
138
  def order
118
- @order ||= Administrate::Order.new(sorting_attribute, sorting_direction)
139
+ @order ||= Administrate::Order.new(
140
+ sorting_attribute,
141
+ sorting_direction,
142
+ association_attribute: order_by_field(
143
+ dashboard_attribute(sorting_attribute),
144
+ ),
145
+ )
146
+ end
147
+
148
+ def order_by_field(dashboard)
149
+ return unless dashboard.try(:options)
150
+
151
+ dashboard.options.fetch(:order, nil)
152
+ end
153
+
154
+ def dashboard_attribute(attribute)
155
+ dashboard.attribute_types[attribute.to_sym] if attribute
119
156
  end
120
157
 
121
158
  def sorting_attribute
@@ -164,7 +201,7 @@ module Administrate
164
201
 
165
202
  def resource_params
166
203
  params.require(resource_class.model_name.param_key).
167
- permit(dashboard.permitted_attributes).
204
+ permit(dashboard.permitted_attributes(action_name)).
168
205
  transform_values { |v| read_param_value(v) }
169
206
  end
170
207
 
@@ -177,6 +214,8 @@ module Administrate
177
214
  end
178
215
  elsif data.is_a?(ActionController::Parameters)
179
216
  data.transform_values { |v| read_param_value(v) }
217
+ elsif data.is_a?(String) && data.blank?
218
+ nil
180
219
  else
181
220
  data
182
221
  end
@@ -206,18 +245,46 @@ module Administrate
206
245
  ).any? { |_name, attribute| attribute.searchable? }
207
246
  end
208
247
 
209
- def show_action?(_action, _resource)
248
+ # Whether the current user is authorized to perform the named action on the
249
+ # resource.
250
+ #
251
+ # @param _resource [ActiveRecord::Base, Class, String, Symbol] The
252
+ # temptative target of the action, or the name of its class.
253
+ # @param _action_name [String, Symbol] The name of an action that might be
254
+ # possible to perform on a resource or resource class.
255
+ # @return [Boolean] `true` if the current user is authorized to perform the
256
+ # action on the resource. `false` otherwise.
257
+ def authorized_action?(_resource, _action_name)
210
258
  true
211
259
  end
260
+ helper_method :authorized_action?
261
+
262
+ # @deprecated Use {#authorized_action} instead. Note that the order of
263
+ # parameters is reversed in {#authorized_action}.
264
+ def show_action?(action, resource)
265
+ Administrate.warn_of_deprecated_authorization_method(__method__)
266
+ authorized_action?(resource, action)
267
+ end
212
268
  helper_method :show_action?
213
269
 
214
- def new_resource
215
- resource_class.new
270
+ def new_resource(params = {})
271
+ resource_class.new(params)
216
272
  end
217
273
  helper_method :new_resource
218
274
 
219
275
  def authorize_resource(resource)
220
- resource
276
+ if authorized_action?(resource, action_name)
277
+ resource
278
+ else
279
+ raise Administrate::NotAuthorizedError.new(
280
+ action: action_name,
281
+ resource: resource,
282
+ )
283
+ end
284
+ end
285
+
286
+ def paginate_resources(resources)
287
+ resources.page(params[:_page]).per(records_per_page)
221
288
  end
222
289
  end
223
290
  end
@@ -2,35 +2,63 @@ module Administrate
2
2
  module Punditize
3
3
  if Object.const_defined?("Pundit")
4
4
  extend ActiveSupport::Concern
5
- include Pundit
5
+
6
+ if Pundit.const_defined?(:Authorization)
7
+ include Pundit::Authorization
8
+ else
9
+ include Pundit
10
+ end
6
11
 
7
12
  included do
13
+ private
14
+
15
+ def policy_namespace
16
+ []
17
+ end
18
+
8
19
  def scoped_resource
9
- policy_scope_admin super
20
+ namespaced_scope = policy_namespace + [super]
21
+ policy_scope!(pundit_user, namespaced_scope)
10
22
  end
11
23
 
12
24
  def authorize_resource(resource)
13
- authorize resource
25
+ namespaced_resource = policy_namespace + [resource]
26
+ authorize namespaced_resource
14
27
  end
15
28
 
16
- def show_action?(action, resource)
17
- Pundit.policy!(pundit_user, resource).send("#{action}?".to_sym)
29
+ def authorized_action?(resource, action)
30
+ namespaced_resource = policy_namespace + [resource]
31
+ policy = Pundit.policy!(pundit_user, namespaced_resource)
32
+ policy.send("#{action}?".to_sym)
18
33
  end
19
34
  end
20
35
 
21
36
  private
22
37
 
23
- # Like the policy_scope method in stock Pundit, but allows the 'resolve'
24
- # to be overridden by 'resolve_admin' for a different index scope in Admin
25
- # controllers.
26
- def policy_scope_admin(scope)
27
- ps = Pundit::PolicyFinder.new(scope).scope!.new(pundit_user, scope)
28
- if ps.respond_to? :resolve_admin
29
- ps.resolve_admin
38
+ def policy_scope!(user, scope)
39
+ policy_scope_class = Pundit::PolicyFinder.new(scope).scope!
40
+
41
+ begin
42
+ policy_scope = policy_scope_class.new(user, pundit_model(scope))
43
+ rescue ArgumentError
44
+ raise(Pundit::InvalidConstructorError,
45
+ "Invalid #<#{policy_scope_class}> constructor is called")
46
+ end
47
+
48
+ if policy_scope.respond_to? :resolve_admin
49
+ ActiveSupport::Deprecation.warn(
50
+ "Pundit policy scope `resolve_admin` method is deprecated. " +
51
+ "Please use a namespaced pundit policy instead.",
52
+ )
53
+ policy_scope.resolve_admin
30
54
  else
31
- ps.resolve
55
+ policy_scope.resolve
32
56
  end
33
57
  end
58
+
59
+ def pundit_model(record)
60
+ record.is_a?(Array) ? record.last : record
61
+ end
34
62
  end
35
63
  end
36
64
  end
@@ -4,11 +4,7 @@ module Administrate
4
4
  SINGULAR_COUNT = 1
5
5
 
6
6
  def application_title
7
- if Rails::VERSION::MAJOR <= 5
8
- Rails.application.class.parent_name.titlecase
9
- else
10
- Rails.application.class.module_parent_name.titlecase
11
- end
7
+ Rails.application.class.module_parent_name.titlecase
12
8
  end
13
9
 
14
10
  def render_field(field, locals = {})
@@ -29,6 +25,28 @@ module Administrate
29
25
  dashboard.try(:model) || resource_name.to_sym
30
26
  end
31
27
 
28
+ # Unification of
29
+ # {Administrate::ApplicationController#existing_action? existing_action?}
30
+ # and
31
+ # {Administrate::ApplicationController#authorized_action?
32
+ # authorized_action?}
33
+ #
34
+ # @param target [ActiveRecord::Base, Class, Symbol, String] A resource,
35
+ # a class of resources, or the name of a class of resources.
36
+ # @param action_name [String, Symbol] The name of an action that might be
37
+ # possible to perform on a resource or resource class.
38
+ # @return [Boolean] Whether the action both (a) exists for the record class,
39
+ # and (b) the current user is authorized to perform it on the record
40
+ # instance or class.
41
+ def accessible_action?(target, action_name)
42
+ target = target.to_sym if target.is_a?(String)
43
+ target_class_or_class_name =
44
+ target.is_a?(ActiveRecord::Base) ? target.class : target
45
+
46
+ existing_action?(target_class_or_class_name, action_name) &&
47
+ authorized_action?(target, action_name)
48
+ end
49
+
32
50
  def display_resource_name(resource_name, opts = {})
33
51
  dashboard_from_resource(resource_name).resource_name(
34
52
  count: opts[:singular] ? SINGULAR_COUNT : PLURAL_MANY_COUNT,
@@ -52,7 +70,7 @@ module Administrate
52
70
  end
53
71
 
54
72
  def sanitized_order_params(page, current_field_name)
55
- collection_names = page.item_includes + [current_field_name]
73
+ collection_names = page.item_associations + [current_field_name]
56
74
  association_params = collection_names.map do |assoc_name|
57
75
  { assoc_name => %i[order direction page per_page] }
58
76
  end
@@ -25,17 +25,16 @@ to display a collection of resources in an HTML table.
25
25
  <th class="cell-label
26
26
  cell-label--<%= attr_type.html_class %>
27
27
  cell-label--<%= collection_presenter.ordered_html_class(attr_name) %>
28
- cell-label--<%= "#{resource_name}_#{attr_name}" %>"
28
+ cell-label--<%= "#{collection_presenter.resource_name}_#{attr_name}" %>"
29
29
  scope="col"
30
- role="columnheader"
31
30
  aria-sort="<%= sort_order(collection_presenter.ordered_html_class(attr_name)) %>">
32
31
  <%= link_to(sanitized_order_params(page, collection_field_name).merge(
33
32
  collection_presenter.order_params_for(attr_name, key: collection_field_name)
34
33
  )) do %>
35
34
  <%= t(
36
35
  "helpers.label.#{collection_presenter.resource_name}.#{attr_name}",
37
- default: resource_class.human_attribute_name(attr_name),
38
- ).titleize %>
36
+ default: resource_class.human_attribute_name(attr_name).titleize,
37
+ ) %>
39
38
  <% if collection_presenter.ordered_by?(attr_name) %>
40
39
  <span class="cell-label__sort-indicator cell-label__sort-indicator--<%= collection_presenter.ordered_html_class(attr_name) %>">
41
40
  <svg aria-hidden="true">
@@ -59,13 +58,13 @@ to display a collection of resources in an HTML table.
59
58
  <tbody>
60
59
  <% resources.each do |resource| %>
61
60
  <tr class="js-table-row"
62
- <% if show_action? :show, resource %>
61
+ <% if accessible_action?(resource, :show) %>
63
62
  <%= %(tabindex=0 role=link data-url=#{polymorphic_path([namespace, resource])}) %>
64
63
  <% end %>
65
64
  >
66
65
  <% collection_presenter.attributes_for(resource).each do |attribute| %>
67
66
  <td class="cell-data cell-data--<%= attribute.html_class %>">
68
- <% if show_action? :show, resource -%>
67
+ <% if accessible_action?(resource, :show) -%>
69
68
  <a href="<%= polymorphic_path([namespace, resource]) -%>"
70
69
  tabindex="-1"
71
70
  class="action-show"
@@ -1,4 +1,4 @@
1
- <% [valid_action?(:edit, collection_presenter.resource_name),
2
- valid_action?(:destroy, collection_presenter.resource_name)].count(true).times do %>
1
+ <% [existing_action?(collection_presenter.resource_name, :edit),
2
+ existing_action?(collection_presenter.resource_name, :destroy)].count(true).times do %>
3
3
  <th scope="col"></th>
4
4
  <% end %>
@@ -1,17 +1,17 @@
1
- <% if valid_action?(:edit, collection_presenter.resource_name) %>
1
+ <% if existing_action?(collection_presenter.resource_name, :edit) %>
2
2
  <td><%= link_to(
3
3
  t("administrate.actions.edit"),
4
4
  [:edit, namespace, resource],
5
5
  class: "action-edit",
6
- ) if show_action?(:edit, resource) %></td>
6
+ ) if accessible_action?(resource, :edit) %></td>
7
7
  <% end %>
8
8
 
9
- <% if valid_action?(:destroy, collection_presenter.resource_name) %>
9
+ <% if existing_action?(collection_presenter.resource_name, :destroy) %>
10
10
  <td><%= link_to(
11
11
  t("administrate.actions.destroy"),
12
12
  [namespace, resource],
13
13
  class: "text-color-red",
14
14
  method: :delete,
15
15
  data: { confirm: t("administrate.actions.confirm") }
16
- ) if show_action?(:destroy, resource) %></td>
16
+ ) if accessible_action?(resource, :destroy) %></td>
17
17
  <% end %>
@@ -2,7 +2,7 @@
2
2
  <%= display_resource_name(page.resource_name) %>
3
3
  <% end %>
4
4
 
5
- <header class="main-content__header" role="banner">
5
+ <header class="main-content__header">
6
6
  <h1 class="main-content__page-title" id="page-title">
7
7
  <%= content_for(:title) %>
8
8
  </h1>
@@ -23,6 +23,6 @@
23
23
  ),
24
24
  [:new, namespace, page.resource_path.to_sym],
25
25
  class: "button",
26
- ) if valid_action?(:new) && show_action?(:new, new_resource) %>
26
+ ) if accessible_action?(new_resource, :new) %>
27
27
  </div>
28
28
  </header>
@@ -7,7 +7,7 @@ for all resources in the admin dashboard,
7
7
  as defined by the routes in the `admin/` namespace
8
8
  %>
9
9
 
10
- <nav class="navigation" role="navigation">
10
+ <nav class="navigation">
11
11
  <%= link_to(t("administrate.navigation.back_to_app"), root_url, class: "button button--alt button--nav") if defined?(root_url) %>
12
12
 
13
13
  <% Administrate::Namespace.new(namespace).resources_with_index_route.each do |resource| %>
@@ -15,6 +15,6 @@ as defined by the routes in the `admin/` namespace
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) && show_action?(:index, model_from_resource(resource)) %>
18
+ ) if accessible_action?(model_from_resource(resource), :index) %>
19
19
  <% end %>
20
20
  </nav>
@@ -0,0 +1 @@
1
+ <%= paginate resources, param_name: local_assigns.fetch(:param_name, "_page") %>
@@ -17,7 +17,7 @@ It displays a header, and renders the `_form` partial to do the heavy lifting.
17
17
 
18
18
  <% content_for(:title) { t("administrate.actions.edit_resource", name: page.page_title) } %>
19
19
 
20
- <header class="main-content__header" role="banner">
20
+ <header class="main-content__header">
21
21
  <h1 class="main-content__page-title">
22
22
  <%= content_for(:title) %>
23
23
  </h1>
@@ -27,7 +27,7 @@ It displays a header, and renders the `_form` partial to do the heavy lifting.
27
27
  t("administrate.actions.show_resource", name: page.page_title),
28
28
  [namespace, page.resource],
29
29
  class: "button",
30
- ) if valid_action?(:show) && show_action?(:show, page.resource) %>
30
+ ) if accessible_action?(page.resource, :show) %>
31
31
  </div>
32
32
  </header>
33
33
 
@@ -42,5 +42,5 @@ It renders the `_table` partial to display details about the resources.
42
42
  table_title: "page-title"
43
43
  ) %>
44
44
 
45
- <%= paginate resources, param_name: '_page' %>
45
+ <%= render("pagination", resources: resources) %>
46
46
  </section>
@@ -22,7 +22,7 @@ to do the heavy lifting.
22
22
  ) %>
23
23
  <% end %>
24
24
 
25
- <header class="main-content__header" role="banner">
25
+ <header class="main-content__header">
26
26
  <h1 class="main-content__page-title">
27
27
  <%= content_for(:title) %>
28
28
  </h1>
@@ -18,7 +18,7 @@ as well as a link to its edit page.
18
18
 
19
19
  <% content_for(:title) { t("administrate.actions.show_resource", name: page.page_title) } %>
20
20
 
21
- <header class="main-content__header" role="banner">
21
+ <header class="main-content__header">
22
22
  <h1 class="main-content__page-title">
23
23
  <%= content_for(:title) %>
24
24
  </h1>
@@ -28,7 +28,15 @@ as well as a link to its edit page.
28
28
  t("administrate.actions.edit_resource", name: page.page_title),
29
29
  [:edit, namespace, page.resource],
30
30
  class: "button",
31
- ) if valid_action?(:edit) && show_action?(:edit, page.resource) %>
31
+ ) if accessible_action?(page.resource, :edit) %>
32
+
33
+ <%= link_to(
34
+ t("administrate.actions.destroy"),
35
+ [namespace, page.resource],
36
+ class: "button button--danger",
37
+ method: :delete,
38
+ data: { confirm: t("administrate.actions.confirm") }
39
+ ) if accessible_action?(page.resource, :destroy) %>
32
40
  </div>
33
41
  </header>
34
42
 
@@ -16,7 +16,7 @@ By default, the relationship is rendered as a link to the associated object.
16
16
  %>
17
17
 
18
18
  <% if field.data %>
19
- <% if valid_action?(:show, field.associated_class) && show_action?(:show, field.associated_class) %>
19
+ <% if accessible_action?(field.data, :show) %>
20
20
  <%= link_to(
21
21
  field.display_associated_resource,
22
22
  [namespace, field.data],
@@ -16,7 +16,7 @@ By default, the relationship is rendered as a link to the associated object.
16
16
  %>
17
17
 
18
18
  <% if field.data %>
19
- <% if valid_action?(:show, field.associated_class) && show_action?(:show, field.associated_class) %>
19
+ <% if accessible_action?(field.data, :show) %>
20
20
  <%= link_to(
21
21
  field.display_associated_resource,
22
22
  [namespace, field.data],
@@ -2,7 +2,6 @@
2
2
  # Date Form Partial
3
3
 
4
4
  This partial renders an input element for a date attribute.
5
- By default, the input is a text field that is augmented with [DateTimePicker].
6
5
 
7
6
  ## Local variables:
8
7
 
@@ -13,12 +12,11 @@ By default, the input is a text field that is augmented with [DateTimePicker].
13
12
  A wrapper around the Date value pulled from the database.
14
13
 
15
14
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/Date
16
- [DateTimePicker]: https://github.com/Eonasdan/bootstrap-datetimepicker
17
15
  %>
18
16
 
19
17
  <div class="field-unit__label">
20
18
  <%= f.label field.attribute %>
21
19
  </div>
22
20
  <div class="field-unit__field">
23
- <%= f.text_field field.attribute, data: { type: 'date' } %>
21
+ <%= f.date_field field.attribute %>
24
22
  </div>
@@ -2,7 +2,6 @@
2
2
  # DateTime Form Partial
3
3
 
4
4
  This partial renders an input element for a datetime attribute.
5
- By default, the input is a text field that is augmented with [DateTimePicker].
6
5
 
7
6
  ## Local variables:
8
7
 
@@ -13,12 +12,11 @@ By default, the input is a text field that is augmented with [DateTimePicker].
13
12
  A wrapper around the DateTime value pulled from the database.
14
13
 
15
14
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/DateTime
16
- [DateTimePicker]: https://github.com/Eonasdan/bootstrap-datetimepicker
17
15
  %>
18
16
 
19
17
  <div class="field-unit__label">
20
18
  <%= f.label field.attribute %>
21
19
  </div>
22
20
  <div class="field-unit__field">
23
- <%= f.text_field field.attribute, data: { type: 'datetime' } %>
21
+ <%= f.datetime_local_field field.attribute, step: 1 %>
24
22
  </div>
@@ -16,4 +16,4 @@ as a count of how many objects are associated through the relationship.
16
16
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/HasMany
17
17
  %>
18
18
 
19
- <%= pluralize(field.data.size, field.attribute.to_s.humanize.downcase.singularize) %>
19
+ <%= pluralize(field.data.size, t("activerecord.models.#{field.attribute.to_s.singularize}", default: field.attribute.to_s.humanize.downcase.singularize, count: field.data.size)) %>
@@ -28,9 +28,10 @@ from the associated resource class's dashboard.
28
28
  page: page,
29
29
  resources: field.resources(page_number, order),
30
30
  table_title: field.name,
31
+ resource_class: field.associated_class,
31
32
  ) %>
32
33
  <% if field.more_than_limit? %>
33
- <%= paginate field.resources(page_number), param_name: "#{field.name}[page]" %>
34
+ <%= render("pagination", resources: field.resources(page_number), param_name: "#{field.name}[page]") %>
34
35
  <% end %>
35
36
 
36
37
  <% else %>
@@ -18,7 +18,7 @@ The form will be rendered as nested_from to parent relationship.
18
18
 
19
19
  <%= f.fields_for field.attribute, field.data || field.nested_form.resource.class.new do |has_one_f| %>
20
20
  <fieldset class="field-unit--nested">
21
- <legend><%= t "helpers.label.#{f.object_name}.#{field.nested_form.resource_name}", default: field.nested_form.resource_name.titleize %></legend>
21
+ <legend><%= t "helpers.label.#{f.object_name}.#{field.name}", default: field.name.titleize %></legend>
22
22
  <% field.nested_form.attributes.each do |attribute| -%>
23
23
  <div class="field-unit field-unit--<%= attribute.html_class %>">
24
24
  <%= render_field attribute, f: has_one_f %>