administrate 0.20.1 → 1.0.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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +9 -9
  3. data/app/assets/builds/administrate/application.css +2614 -0
  4. data/app/assets/builds/administrate/application.css.map +1 -0
  5. data/app/assets/builds/administrate/application.js +31661 -0
  6. data/app/assets/builds/administrate/application.js.map +7 -0
  7. data/app/assets/builds/administrate-internal/docs.css +102 -0
  8. data/app/assets/builds/administrate-internal/docs.css.map +1 -0
  9. data/app/assets/config/administrate_manifest.js +2 -0
  10. data/app/assets/javascripts/administrate/add_jquery.js +4 -0
  11. data/app/assets/javascripts/administrate/application.js +9 -4
  12. data/app/assets/javascripts/administrate/controllers/application.js +9 -0
  13. data/app/assets/javascripts/administrate/controllers/index.js +9 -0
  14. data/app/assets/javascripts/administrate/controllers/select_controller.js +25 -0
  15. data/app/assets/javascripts/administrate/{components/table.js → controllers/table_controller.js} +9 -9
  16. data/app/assets/javascripts/administrate/controllers/tooltip_controller.js +24 -0
  17. data/app/assets/javascripts/administrate/vendor/css-anchor-positioning.js +9310 -0
  18. data/app/assets/stylesheets/administrate/application.scss +3 -3
  19. data/app/assets/stylesheets/administrate/base/_forms.scss +4 -4
  20. data/app/assets/stylesheets/administrate/base/_layout.scss +5 -0
  21. data/app/assets/stylesheets/administrate/base/_tables.scss +1 -1
  22. data/app/assets/stylesheets/administrate/base/_typography.scss +15 -1
  23. data/app/assets/stylesheets/administrate/components/_attributes.scss +1 -0
  24. data/app/assets/stylesheets/administrate/components/_buttons.scss +37 -12
  25. data/app/assets/stylesheets/administrate/components/_cells.scss +26 -19
  26. data/app/assets/stylesheets/administrate/components/_field-unit.scss +3 -3
  27. data/app/assets/stylesheets/administrate/components/_main-content.scss +1 -1
  28. data/app/assets/stylesheets/administrate/components/_navigation.scss +3 -3
  29. data/app/assets/stylesheets/administrate/components/_search.scss +55 -14
  30. data/app/assets/stylesheets/administrate/library/_variables.scss +7 -3
  31. data/app/assets/stylesheets/administrate/reset/_normalize.scss +7 -1
  32. data/app/assets/stylesheets/{docs.scss → administrate-internal/docs.scss} +25 -23
  33. data/app/controllers/administrate/application_controller.rb +27 -39
  34. data/app/controllers/concerns/administrate/punditize.rb +4 -12
  35. data/app/helpers/administrate/application_helper.rb +13 -5
  36. data/app/views/administrate/application/_collection.html.erb +30 -20
  37. data/app/views/administrate/application/_collection_header_actions.html.erb +1 -1
  38. data/app/views/administrate/application/_collection_item_actions.html.erb +4 -4
  39. data/app/views/administrate/application/_form.html.erb +1 -1
  40. data/app/views/administrate/application/_icons.html.erb +14 -6
  41. data/app/views/administrate/application/_index_header.html.erb +23 -0
  42. data/app/views/administrate/application/_javascript.html.erb +1 -1
  43. data/app/views/administrate/application/edit.html.erb +15 -3
  44. data/app/views/administrate/application/index.html.erb +20 -11
  45. data/app/views/administrate/application/new.html.erb +16 -4
  46. data/app/views/administrate/application/show.html.erb +35 -23
  47. data/app/views/fields/belongs_to/_form.html.erb +3 -2
  48. data/app/views/fields/has_many/_form.html.erb +2 -2
  49. data/app/views/fields/has_one/_form.html.erb +6 -0
  50. data/app/views/fields/polymorphic/_form.html.erb +1 -1
  51. data/app/views/fields/rich_text/_form.html.erb +22 -0
  52. data/app/views/fields/rich_text/_index.html.erb +18 -0
  53. data/app/views/fields/rich_text/_show.html.erb +18 -0
  54. data/app/views/fields/select/_form.html.erb +2 -1
  55. data/app/views/fields/text/_form.html.erb +1 -1
  56. data/app/views/layouts/administrate/application.html.erb +1 -2
  57. data/docs/customizing_dashboards.md +214 -11
  58. data/docs/customizing_page_views.md +47 -0
  59. data/docs/guides/scoping_has_many_relations.md +2 -2
  60. data/docs/guides/switching_templates_with_view_variants.md +45 -0
  61. data/docs/guides.md +1 -0
  62. data/docs/migrating-to-v1.md +34 -0
  63. data/lib/administrate/base_dashboard.rb +6 -11
  64. data/lib/administrate/engine.rb +7 -6
  65. data/lib/administrate/field/associative.rb +8 -23
  66. data/lib/administrate/field/base.rb +40 -5
  67. data/lib/administrate/field/belongs_to.rb +8 -8
  68. data/lib/administrate/field/date.rb +6 -2
  69. data/lib/administrate/field/date_time.rb +3 -4
  70. data/lib/administrate/field/deferred.rb +14 -18
  71. data/lib/administrate/field/has_many.rb +25 -6
  72. data/lib/administrate/field/has_one.rb +11 -15
  73. data/lib/administrate/field/number.rb +2 -2
  74. data/lib/administrate/field/password.rb +4 -0
  75. data/lib/administrate/field/polymorphic.rb +4 -4
  76. data/lib/administrate/field/rich_text.rb +21 -0
  77. data/lib/administrate/field/select.rb +4 -0
  78. data/lib/administrate/field/time.rb +5 -4
  79. data/lib/administrate/generator_helpers.rb +1 -1
  80. data/lib/administrate/namespace/resource.rb +1 -1
  81. data/lib/administrate/namespace.rb +10 -10
  82. data/lib/administrate/order.rb +37 -33
  83. data/lib/administrate/page/base.rb +2 -7
  84. data/lib/administrate/page/collection.rb +2 -2
  85. data/lib/administrate/page/form.rb +1 -1
  86. data/lib/administrate/page/show.rb +1 -1
  87. data/lib/administrate/resource_resolver.rb +1 -1
  88. data/lib/administrate/search.rb +14 -16
  89. data/lib/administrate/version.rb +1 -1
  90. data/lib/administrate/view_generator.rb +4 -3
  91. data/lib/administrate.rb +0 -38
  92. data/lib/generators/administrate/dashboard/dashboard_generator.rb +12 -9
  93. data/lib/generators/administrate/field/field_generator.rb +2 -2
  94. data/lib/generators/administrate/install/install_generator.rb +3 -2
  95. data/lib/generators/administrate/routes/routes_generator.rb +6 -5
  96. data/lib/generators/administrate/views/field_generator.rb +2 -2
  97. data/lib/generators/administrate/views/index_generator.rb +5 -0
  98. data/lib/generators/administrate/views/layout_generator.rb +1 -1
  99. metadata +35 -76
  100. data/app/assets/javascripts/administrate/components/associative.js +0 -5
  101. data/app/assets/javascripts/administrate/components/select.js +0 -3
  102. data/app/assets/stylesheets/administrate/utilities/_text-color.scss +0 -3
  103. data/lib/generators/administrate/assets/assets_generator.rb +0 -12
  104. data/lib/generators/administrate/assets/javascripts_generator.rb +0 -17
  105. data/lib/generators/administrate/assets/stylesheets_generator.rb +0 -17
@@ -10,18 +10,20 @@ module Administrate
10
10
  resources = order.apply(resources)
11
11
  resources = paginate_resources(resources)
12
12
  page = Administrate::Page::Collection.new(dashboard, order: order)
13
+ filters = Administrate::Search.new(scoped_resource, dashboard, search_term).valid_filters
13
14
 
14
15
  render locals: {
15
16
  resources: resources,
16
17
  search_term: search_term,
17
18
  page: page,
18
19
  show_search_bar: show_search_bar?,
20
+ filters: filters
19
21
  }
20
22
  end
21
23
 
22
24
  def show
23
25
  render locals: {
24
- page: Administrate::Page::Show.new(dashboard, requested_resource),
26
+ page: Administrate::Page::Show.new(dashboard, requested_resource)
25
27
  }
26
28
  end
27
29
 
@@ -29,13 +31,13 @@ module Administrate
29
31
  resource = new_resource
30
32
  authorize_resource(resource)
31
33
  render locals: {
32
- page: Administrate::Page::Form.new(dashboard, resource),
34
+ page: Administrate::Page::Form.new(dashboard, resource)
33
35
  }
34
36
  end
35
37
 
36
38
  def edit
37
39
  render locals: {
38
- page: Administrate::Page::Form.new(dashboard, requested_resource),
40
+ page: Administrate::Page::Form.new(dashboard, requested_resource)
39
41
  }
40
42
  end
41
43
 
@@ -47,11 +49,11 @@ module Administrate
47
49
  yield(resource) if block_given?
48
50
  redirect_to(
49
51
  after_resource_created_path(resource),
50
- notice: translate_with_resource("create.success"),
52
+ notice: translate_with_resource("create.success")
51
53
  )
52
54
  else
53
55
  render :new, locals: {
54
- page: Administrate::Page::Form.new(dashboard, resource),
56
+ page: Administrate::Page::Form.new(dashboard, resource)
55
57
  }, status: :unprocessable_entity
56
58
  end
57
59
  end
@@ -61,10 +63,11 @@ module Administrate
61
63
  redirect_to(
62
64
  after_resource_updated_path(requested_resource),
63
65
  notice: translate_with_resource("update.success"),
66
+ status: :see_other
64
67
  )
65
68
  else
66
69
  render :edit, locals: {
67
- page: Administrate::Page::Form.new(dashboard, requested_resource),
70
+ page: Administrate::Page::Form.new(dashboard, requested_resource)
68
71
  }, status: :unprocessable_entity
69
72
  end
70
73
  end
@@ -75,7 +78,7 @@ module Administrate
75
78
  else
76
79
  flash[:error] = requested_resource.errors.full_messages.join("<br/>")
77
80
  end
78
- redirect_to after_resource_destroyed_path(requested_resource)
81
+ redirect_to after_resource_destroyed_path(requested_resource), status: :see_other
79
82
  end
80
83
 
81
84
  private
@@ -84,12 +87,12 @@ module Administrate
84
87
  Administrate::Search.new(
85
88
  resources,
86
89
  dashboard,
87
- search_term,
90
+ search_term
88
91
  ).run
89
92
  end
90
93
 
91
94
  def after_resource_destroyed_path(_requested_resource)
92
- { action: :index }
95
+ {action: :index}
93
96
  end
94
97
 
95
98
  def after_resource_created_path(requested_resource)
@@ -103,7 +106,7 @@ module Administrate
103
106
  helper_method :nav_link_state
104
107
  def nav_link_state(resource)
105
108
  underscore_resource = resource.to_s.split("/").join("__")
106
- resource_name.to_s.pluralize == underscore_resource ? :active : :inactive
109
+ (resource_name.to_s.pluralize == underscore_resource) ? :active : :inactive
107
110
  end
108
111
 
109
112
  # Whether the named action route exists for the resource class.
@@ -119,15 +122,6 @@ module Administrate
119
122
  end
120
123
  helper_method :existing_action?
121
124
 
122
- # @deprecated Use {#existing_action} instead. Note that, in
123
- # {#existing_action}, the order of parameters is reversed and
124
- # there is no default value for the `resource` parameter.
125
- def valid_action?(action_name, resource = resource_class)
126
- Administrate.warn_of_deprecated_authorization_method(__method__)
127
- existing_action?(resource, action_name)
128
- end
129
- helper_method :valid_action?
130
-
131
125
  def routes
132
126
  @routes ||= Namespace.new(namespace).routes.to_set
133
127
  end
@@ -140,16 +134,18 @@ module Administrate
140
134
  @order ||= Administrate::Order.new(
141
135
  sorting_attribute,
142
136
  sorting_direction,
143
- association_attribute: order_by_field(
144
- dashboard_attribute(sorting_attribute),
145
- ),
137
+ sorting_column: sorting_column(
138
+ dashboard_attribute(sorting_attribute)
139
+ )
146
140
  )
147
141
  end
148
142
 
149
- def order_by_field(dashboard)
150
- return unless dashboard.try(:options)
143
+ def sorting_column(dashboard_attribute)
144
+ return unless dashboard_attribute.try(:options)
151
145
 
152
- dashboard.options.fetch(:order, nil)
146
+ dashboard_attribute.options.fetch(:sorting_column) {
147
+ dashboard_attribute.options.fetch(:order, nil)
148
+ }
153
149
  end
154
150
 
155
151
  def dashboard_attribute(attribute)
@@ -201,9 +197,9 @@ module Administrate
201
197
  end
202
198
 
203
199
  def resource_params
204
- params.require(resource_class.model_name.param_key).
205
- permit(dashboard.permitted_attributes(action_name)).
206
- transform_values { |v| read_param_value(v) }
200
+ params.require(resource_class.model_name.param_key)
201
+ .permit(dashboard.permitted_attributes(action_name))
202
+ .transform_values { |v| read_param_value(v) }
207
203
  end
208
204
 
209
205
  def read_param_value(data)
@@ -236,13 +232,13 @@ module Administrate
236
232
  def translate_with_resource(key)
237
233
  t(
238
234
  "administrate.controller.#{key}",
239
- resource: resource_resolver.resource_title,
235
+ resource: resource_resolver.resource_title
240
236
  )
241
237
  end
242
238
 
243
239
  def show_search_bar?
244
240
  dashboard.attribute_types_for(
245
- dashboard.all_attributes,
241
+ dashboard.all_attributes
246
242
  ).any? { |_name, attribute| attribute.searchable? }
247
243
  end
248
244
 
@@ -260,14 +256,6 @@ module Administrate
260
256
  end
261
257
  helper_method :authorized_action?
262
258
 
263
- # @deprecated Use {#authorized_action} instead. Note that the order of
264
- # parameters is reversed in {#authorized_action}.
265
- def show_action?(action, resource)
266
- Administrate.warn_of_deprecated_authorization_method(__method__)
267
- authorized_action?(resource, action)
268
- end
269
- helper_method :show_action?
270
-
271
259
  def new_resource(params = {})
272
260
  resource_class.new(params)
273
261
  end
@@ -279,7 +267,7 @@ module Administrate
279
267
  else
280
268
  raise Administrate::NotAuthorizedError.new(
281
269
  action: action_name,
282
- resource: resource,
270
+ resource: resource
283
271
  )
284
272
  end
285
273
  end
@@ -1,6 +1,6 @@
1
1
  module Administrate
2
2
  module Punditize
3
- if Object.const_defined?("Pundit")
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}?".to_sym)
31
+ policy.send(:"#{action}?")
32
32
  end
33
33
 
34
34
  def policy_scope!(user, scope)
@@ -38,18 +38,10 @@ module Administrate
38
38
  policy_scope = policy_scope_class.new(user, pundit_model(scope))
39
39
  rescue ArgumentError
40
40
  raise(Pundit::InvalidConstructorError,
41
- "Invalid #<#{policy_scope_class}> constructor is called")
41
+ "Invalid #<#{policy_scope_class}> constructor is called")
42
42
  end
43
43
 
44
- if policy_scope.respond_to? :resolve_admin
45
- Administrate.deprecator.warn(
46
- "Pundit policy scope `resolve_admin` method is deprecated. " +
47
- "Please use a namespaced pundit policy instead.",
48
- )
49
- policy_scope.resolve_admin
50
- else
51
- policy_scope.resolve
52
- end
44
+ policy_scope.resolve
53
45
  end
54
46
 
55
47
  def pundit_model(record)
@@ -9,7 +9,15 @@ module Administrate
9
9
 
10
10
  def render_field(field, locals = {})
11
11
  locals[:field] = field
12
- render locals: locals, partial: field.to_partial_path
12
+ if (prefix = find_partial_prefix(field))
13
+ render locals: locals, partial: "#{prefix}/#{field.page}"
14
+ end
15
+ end
16
+
17
+ def find_partial_prefix(field)
18
+ field.partial_prefixes.detect do |prefix|
19
+ lookup_context.template_exists?(field.page, [prefix], true)
20
+ end
13
21
  end
14
22
 
15
23
  def requireness(field)
@@ -50,7 +58,7 @@ module Administrate
50
58
  def display_resource_name(resource_name, opts = {})
51
59
  dashboard_from_resource(resource_name).resource_name(
52
60
  count: opts[:singular] ? SINGULAR_COUNT : PLURAL_MANY_COUNT,
53
- default: default_resource_name(resource_name, opts),
61
+ default: default_resource_name(resource_name, opts)
54
62
  )
55
63
  end
56
64
 
@@ -65,14 +73,14 @@ module Administrate
65
73
  def resource_index_route(resource_name)
66
74
  url_for(
67
75
  action: "index",
68
- controller: "/#{namespace}/#{resource_name}",
76
+ controller: "/#{namespace}/#{resource_name}"
69
77
  )
70
78
  end
71
79
 
72
80
  def sanitized_order_params(page, current_field_name)
73
81
  collection_names = page.item_associations + [current_field_name]
74
82
  association_params = collection_names.map do |assoc_name|
75
- { assoc_name => %i[order direction page per_page] }
83
+ {assoc_name => %i[order direction page per_page]}
76
84
  end
77
85
  params.permit(:search, :id, :_page, :per_page, association_params)
78
86
  end
@@ -87,7 +95,7 @@ module Administrate
87
95
 
88
96
  def default_resource_name(name, opts = {})
89
97
  resource_name = (opts[:singular] ? name.to_s : name.to_s.pluralize)
90
- resource_name.gsub("/", "_").titleize
98
+ resource_name.tr("/", "_").titleize
91
99
  end
92
100
  end
93
101
  end
@@ -18,30 +18,40 @@ 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| %>
25
25
  <th class="cell-label
26
- cell-label--<%= attr_type.html_class %>
27
- cell-label--<%= collection_presenter.ordered_html_class(attr_name) %>
28
- cell-label--<%= "#{collection_presenter.resource_name}_#{attr_name}" %>"
29
- scope="col"
30
- aria-sort="<%= sort_order(collection_presenter.ordered_html_class(attr_name)) %>">
31
- <%= link_to(sanitized_order_params(page, collection_field_name).merge(
32
- collection_presenter.order_params_for(attr_name, key: collection_field_name)
33
- )) do %>
34
- <%= t(
35
- "helpers.label.#{collection_presenter.resource_name}.#{attr_name}",
36
- default: resource_class.human_attribute_name(attr_name).titleize,
37
- ) %>
38
- <% if collection_presenter.ordered_by?(attr_name) %>
39
- <span class="cell-label__sort-indicator cell-label__sort-indicator--<%= collection_presenter.ordered_html_class(attr_name) %>">
40
- <svg aria-hidden="true">
41
- <use xlink:href="#icon-up-caret" />
42
- </svg>
43
- </span>
26
+ cell-label--<%= attr_type.html_class %>
27
+ cell-label--<%= collection_presenter.ordered_html_class(attr_name) %>
28
+ cell-label--<%= "#{collection_presenter.resource_name}_#{attr_name}" %>"
29
+ scope="col"
30
+ <% if attr_type.sortable? %>
31
+ aria-sort="<%= sort_order(collection_presenter.ordered_html_class(attr_name)) %>"
32
+ <% end %>
33
+ >
34
+ <% if attr_type.sortable? %>
35
+ <%= link_to(params: sanitized_order_params(page, collection_field_name).merge(
36
+ collection_presenter.order_params_for(attr_name, key: collection_field_name)
37
+ )) do %>
38
+ <%= t(
39
+ "helpers.label.#{collection_presenter.resource_name}.#{attr_name}",
40
+ default: resource_class.human_attribute_name(attr_name).titleize,
41
+ ) %>
42
+ <% if collection_presenter.ordered_by?(attr_name) %>
43
+ <span class="cell-label__sort-indicator cell-label__sort-indicator--<%= collection_presenter.ordered_html_class(attr_name) %>">
44
+ <svg aria-hidden="true">
45
+ <use xlink:href="#icon-up-caret" />
46
+ </svg>
47
+ </span>
48
+ <% end %>
44
49
  <% end %>
50
+ <% else %>
51
+ <%= t(
52
+ "helpers.label.#{collection_presenter.resource_name}.#{attr_name}",
53
+ default: resource_class.human_attribute_name(attr_name).titleize,
54
+ ) %>
45
55
  <% end %>
46
56
  </th>
47
57
  <% end %>
@@ -59,7 +69,7 @@ to display a collection of resources in an HTML table.
59
69
  <% resources.each do |resource| %>
60
70
  <tr class="js-table-row"
61
71
  <% if accessible_action?(resource, :show) %>
62
- <%= %(tabindex=0 role=link data-url=#{polymorphic_path([namespace, resource])}) %>
72
+ <%= %(tabindex=0 data-url=#{polymorphic_path([namespace, resource])}) %>
63
73
  <% end %>
64
74
  >
65
75
  <% collection_presenter.attributes_for(resource).each do |attribute| %>
@@ -1,4 +1,4 @@
1
1
  <% [existing_action?(collection_presenter.resource_name, :edit),
2
2
  existing_action?(collection_presenter.resource_name, :destroy)].count(true).times do %>
3
- <th scope="col"></th>
3
+ <th scope="col" class="cell-label--action-button"></th>
4
4
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <% if existing_action?(collection_presenter.resource_name, :edit) %>
2
- <td><%= link_to(
2
+ <td class="cell-label--action-button"><%= link_to(
3
3
  t("administrate.actions.edit"),
4
4
  [:edit, namespace, resource],
5
5
  class: "action-edit",
@@ -7,11 +7,11 @@
7
7
  <% end %>
8
8
 
9
9
  <% if existing_action?(collection_presenter.resource_name, :destroy) %>
10
- <td><%= link_to(
10
+ <td class="cell-label--action-button"><%= button_to(
11
11
  t("administrate.actions.destroy"),
12
12
  [namespace, resource],
13
- class: "text-color-red",
13
+ class: "link link--danger",
14
14
  method: :delete,
15
- data: { confirm: t("administrate.actions.confirm") }
15
+ data: { turbo_confirm: t("administrate.actions.confirm") }
16
16
  ) if accessible_action?(resource, :destroy) %></td>
17
17
  <% end %>
@@ -14,7 +14,7 @@ and renders all form fields for a resource's editable attributes.
14
14
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Form
15
15
  %>
16
16
 
17
- <%= form_for([namespace, page.resource], html: { class: "form" }) do |f| %>
17
+ <%= form_with(model: page.resource, url: [namespace, page.resource], scope: page.resource, local: true, class: "form") do |f| %>
18
18
  <% if page.resource.errors.any? %>
19
19
  <div id="error_explanation">
20
20
  <h2>
@@ -1,13 +1,21 @@
1
1
  <svg hidden xmlns="http://www.w3.org/2000/svg">
2
- <symbol id="icon-cancel" viewBox="0 0 48 48">
3
- <path fill-rule="evenodd" d="M24 19.757l-8.485-8.485c-.784-.783-2.047-.782-2.827 0l-1.417 1.416c-.777.777-.78 2.046.002 2.827L19.757 24l-8.485 8.485c-.783.784-.782 2.047 0 2.827l1.416 1.417c.777.777 2.046.78 2.827-.002L24 28.243l8.485 8.485c.784.783 2.047.782 2.827 0l1.417-1.416c.777-.777.78-2.046-.002-2.827L28.243 24l8.485-8.485c.783-.784.782-2.047 0-2.827l-1.416-1.417c-.777-.777-2.046-.78-2.827.002L24 19.757zM24 47c12.703 0 23-10.297 23-23S36.703 1 24 1 1 11.297 1 24s10.297 23 23 23z" />
2
+ <symbol id="icon-cancel" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
3
+ <circle cx="12" cy="12" r="10"></circle>
4
+ <line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line>
4
5
  </symbol>
5
6
 
6
- <symbol id="icon-eyeglass" viewBox="0 0 48 48">
7
- <path d="M27.885 32.515c-2.864 1.966-6.333 3.116-10.07 3.116C7.976 35.63 0 27.656 0 17.817 0 7.976 7.976 0 17.816 0S35.63 7.976 35.63 17.816c0 3.736-1.15 7.205-3.115 10.07l14.53 14.53c1.278 1.277 1.275 3.352 0 4.628-1.28 1.278-3.353 1.278-4.63 0l-14.53-14.53zm-10.07-3.736c6.056 0 10.964-4.91 10.964-10.964 0-6.055-4.91-10.964-10.964-10.964-6.055 0-10.964 4.91-10.964 10.964 0 6.055 4.91 10.963 10.964 10.963z" />
7
+ <symbol id="icon-eyeglass" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
8
+ <circle cx="11" cy="11" r="8"></circle>
9
+ <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
8
10
  </symbol>
9
11
 
10
- <symbol id="icon-up-caret" viewBox="0 0 48 48">
11
- <path d="M2.988 33.02c-1.66 0-1.943-.81-.618-1.824l20-15.28c.878-.672 2.31-.67 3.188 0l20.075 15.288c1.316 1.003 1.048 1.816-.62 1.816H2.987z" />
12
+ <symbol id="icon-up-caret" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
13
+ <polyline points="18 15 12 9 6 15"></polyline>
12
14
  </symbol>
15
+
16
+ <symbol id="icon-question-mark" viewBox="0 0 24 24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
17
+ <circle cx="12" cy="12" r="10"></circle>
18
+ <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
19
+ <line x1="12" y1="17" x2="12.01" y2="17"></line>
20
+ <symbol>
13
21
  </svg>
@@ -7,12 +7,33 @@
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",
13
15
  search_term: search_term,
14
16
  resource_name: display_resource_name(page.resource_name)
15
17
  ) %>
18
+
19
+ <% if filters.any? %>
20
+ <div data-controller="tooltip">
21
+ <button data-tooltip-target="tooltip" popovertarget="search-tooltip" class="button--tooltip search__tooltip">
22
+ <svg role="img">
23
+ <use xlink:href="#icon-question-mark" />
24
+ </svg>
25
+ </button>
26
+
27
+ <div data-tooltip-target="popover" popover id="search-tooltip" role="tooltip" class="search__tooltip-popover search__tooltip-popover-positioning">
28
+ <p><strong>Use filters to refine your search</strong></p>
29
+ <ul>
30
+ <% filters.keys.each do |filter_key| %>
31
+ <li><%= filter_key %>:<span class="search__tooltip-popover-value">&lt;value&gt;</span></li>
32
+ <% end %>
33
+ </ul>
34
+ </div>
35
+ </div>
36
+ <% end %>
16
37
  <% end %>
17
38
 
18
39
  <div>
@@ -25,4 +46,6 @@
25
46
  class: "button",
26
47
  ) if accessible_action?(new_resource, :new) %>
27
48
  </div>
49
+
50
+ <%= content_for(:header_last) %>
28
51
  </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
- <section class="main-content__body">
35
- <%= render "form", page: page %>
36
- </section>
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) %>
@@ -29,18 +29,27 @@ It renders the `_table` partial to display details about the resources.
29
29
  search_term: search_term,
30
30
  page: page,
31
31
  show_search_bar: show_search_bar,
32
+ filters: filters,
32
33
  )
33
34
  %>
34
35
 
35
- <section class="main-content__body main-content__body--flush">
36
- <%= render(
37
- "collection",
38
- collection_presenter: page,
39
- collection_field_name: resource_name,
40
- page: page,
41
- resources: resources,
42
- table_title: "page-title"
43
- ) %>
36
+ <%= content_for(:before_main) %>
37
+
38
+ <% if content_for?(:main) %>
39
+ <%= content_for(:main) %>
40
+ <% else %>
41
+ <section class="main-content__body main-content__body--flush">
42
+ <%= render(
43
+ "collection",
44
+ collection_presenter: page,
45
+ collection_field_name: resource_name,
46
+ page: page,
47
+ resources: resources,
48
+ table_title: "page-title"
49
+ ) %>
50
+
51
+ <%= render("pagination", resources: resources) %>
52
+ </section>
53
+ <% end %>
44
54
 
45
- <%= render("pagination", resources: resources) %>
46
- </section>
55
+ <%= content_for(:after_main) %>
@@ -18,7 +18,7 @@ to do the heavy lifting.
18
18
  <% content_for(:title) do %>
19
19
  <%= t(
20
20
  "administrate.actions.new_resource",
21
- name: display_resource_name(page.resource_name).titleize
21
+ name: display_resource_name(page.resource_name, singular: true)
22
22
  ) %>
23
23
  <% end %>
24
24
 
@@ -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
- <section class="main-content__body">
36
- <%= render "form", page: page %>
37
- </section>
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
- <%= link_to(
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: { confirm: t("administrate.actions.confirm") }
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
- <section class="main-content__body">
44
- <dl>
45
- <% page.attributes.each do |title, attributes| %>
46
- <fieldset class="<%= "field-unit--nested" if title.present? %>">
47
- <% if title.present? %>
48
- <legend><%= t "helpers.label.#{page.resource_name}.#{title}", default: title %></legend>
49
- <% end %>
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
- <% attributes.each do |attribute| %>
52
- <dt class="attribute-label" id="<%= attribute.name %>">
53
- <%= t(
54
- "helpers.label.#{resource_name}.#{attribute.name}",
55
- default: page.resource.class.human_attribute_name(attribute.name),
56
- ) %>
57
- </dt>
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
- <dd class="attribute-data attribute-data--<%=attribute.html_class%>"
60
- ><%= render_field attribute, page: page %></dd>
61
- <% end %>
62
- </fieldset>
63
- <% end %>
64
- </dl>
65
- </section>
77
+ <%= content_for(:after_main) %>