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
@@ -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>
@@ -16,14 +16,14 @@ and is augmented with [Selectize].
16
16
  Contains helper methods for displaying a collection select box.
17
17
 
18
18
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/HasMany
19
- [Selectize]: http://brianreavis.github.io/selectize.js
19
+ [Selectize]: https://github.com/selectize/selectize.js
20
20
  %>
21
21
 
22
22
  <div class="field-unit__label">
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>
@@ -30,6 +30,12 @@ The form will be rendered as nested_from to parent relationship.
30
30
  <div class="field-unit field-unit--<%= attribute.html_class %>">
31
31
  <%= render_field attribute, f: has_one_f %>
32
32
  </div>
33
+ <% hint_key = "administrate.field_hints.#{field.name}.#{attribute.name}" %>
34
+ <% if I18n.exists?(hint_key) -%>
35
+ <div class="field-unit__hint">
36
+ <%= I18n.t(hint_key) %>
37
+ </div>
38
+ <% end -%>
33
39
  <% end %>
34
40
  </fieldset>
35
41
 
@@ -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, nil, {}, 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,22 @@
1
+ <%#
2
+ # Rich Text Form Partial
3
+
4
+ This partial renders a trix-editor element for ActionText::RichText attributes.
5
+
6
+ ## Local variables:
7
+
8
+ - `f`:
9
+ A Rails form generator, used to help create the appropriate trix-editor fields.
10
+ - `field`:
11
+ An instance of [Administrate::Field::RichText][1].
12
+ A wrapper around the tmie attributes pulled from the model.
13
+
14
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/RichText
15
+ %>
16
+
17
+ <div class="field-unit__label">
18
+ <%= f.label field.attribute %>
19
+ </div>
20
+ <div class="field-unit__field">
21
+ <%= f.rich_text_area(field.attribute) %>
22
+ </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 %>
@@ -26,7 +26,8 @@ to be displayed on a resource's edit form page.
26
26
  field.selectable_options,
27
27
  field.data,
28
28
  ),
29
- include_blank: field.include_blank_option
29
+ {include_blank: field.include_blank_option},
30
+ data: {controller: field.html_controller}
30
31
  )
31
32
  %>
32
33
  </div>
@@ -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`.
@@ -105,15 +106,18 @@ For example:
105
106
  with this, you will be able to search through the column `name` from the
106
107
  association `belongs_to :country`, from your model.
107
108
 
108
- `:primary_key` (deprecated) - Specifies the association's primary_key.
109
+ `:sortable` - Specifies if sorting should be enabled in the table views.
110
+ Default is `true`.
109
111
 
110
- `:foreign_key` (deprecated) - Specifies the name of the foreign key directly.
112
+ `:sorting_column` - Specifies the column of the associated model to be used for sorting in the table views and dropdown menu.
113
+ If `sorting_column` is omitted and `order` is specified, the value of `order` will be used.
114
+ If neither is specified, sorting will be done using the foreign key.
111
115
 
112
- `:class_name` (deprecated) - Specifies the name of the associated class.
116
+ `:class_name` - Specifies the name of the associated class.
113
117
 
114
118
  **Field::HasMany**
115
119
 
116
- `:collection_attributes` - Set the columns to display in the show view.
120
+ `:collection_attributes` - Set the columns to display in the show view.
117
121
  Default is COLLECTION_ATTRIBUTES in dashboard.
118
122
 
119
123
  `:limit` - The number of resources (paginated) to display in the show view. To disable pagination,
@@ -123,11 +127,15 @@ set this to `0` or `false`. Default is `5`.
123
127
 
124
128
  `:direction` - What direction the sort should be in, `:asc` (default) or `:desc`.
125
129
 
126
- `:primary_key` (deprecated) - Specifies object's primary_key.
130
+ `:sortable` - Specifies if sorting should be enabled in the table views.
131
+ Default is `true`.
127
132
 
128
- `:foreign_key` (deprecated) - Specifies the name of the foreign key directly.
133
+ `:sorting_column` - Specifies the column of the associated model to be used for sorting in the dropdown menu.
134
+ If `sorting_column` is omitted and `sort_by` is specified, the value of `sort_by` will be used.
135
+ If neither is specified, sorting will be done using the foreign key.
136
+ For `HasMany` associations, sorting is based on the count, so this option is not referenced in the table views.
129
137
 
130
- `:class_name` (deprecated) - Specifies the name of the associated class.
138
+ `:class_name` - Specifies the name of the associated class.
131
139
 
132
140
  **Field::HasOne**
133
141
 
@@ -144,16 +152,23 @@ Default is `false`.
144
152
  For example:
145
153
 
146
154
  ```ruby
147
- cities: Field::HasMany.with_options(
155
+ city: Field::HasOne.with_options(
148
156
  searchable: true,
149
157
  searchable_fields: ['name'],
150
158
  )
151
159
  ```
152
160
 
153
161
  with this, you will be able to search through the column `name` from the
154
- association `has_many :cities`, from your model.
162
+ association `has_one :city`, from your model.
155
163
 
156
- `:class_name` (deprecated) - Specifies the name of the associated class.
164
+ `:sortable` - Specifies if sorting should be enabled in the table views.
165
+ Default is `true`.
166
+
167
+ `:sorting_column` - Specifies the column of the associated model to be used for sorting in the table views and dropdown menu.
168
+ If `sorting_column` is omitted and `order` is specified, the value of `order` will be used.
169
+ If neither is specified, sorting will be done using the foreign key.
170
+
171
+ `:class_name` - Specifies the name of the associated class.
157
172
 
158
173
  **Field::Number**
159
174
 
@@ -161,6 +176,13 @@ association `has_many :cities`, from your model.
161
176
  Note that currently number fields are searched like text, which may yield
162
177
  more results than expected. Default is `false`.
163
178
 
179
+ `:sortable` - Specifies if sorting should be enabled in the table views.
180
+ Default is `true`.
181
+
182
+ `:sorting_column` - Specifies the column to be used for sorting in the table view.
183
+ By default, the column itself is used, but when used as a virtual column,
184
+ a custom sorting column can be specified.
185
+
164
186
  `:decimals` - Set the number of decimals to display. Defaults to `0`.
165
187
 
166
188
  `:prefix` - Prefixes the number with a string. Defaults to `""`.
@@ -209,8 +231,18 @@ Default is `[]`.
209
231
  `:order` - What to sort the association by in the form select.
210
232
  Default is `nil`.
211
233
 
234
+ `:sortable` - Specifies if sorting should be enabled in the table views.
235
+ Default is `true`.
236
+
212
237
  **Field::DateTime**
213
238
 
239
+ `:sortable` - Specifies if sorting should be enabled in the table views.
240
+ Default is `true`.
241
+
242
+ `:sorting_column` - Specifies the column to be used for sorting in the table view.
243
+ By default, the column itself is used, but when used as a virtual column,
244
+ a custom sorting column can be specified.
245
+
214
246
  `:format` - Specify what format, using `strftime` you would like `DateTime`
215
247
  objects to display as.
216
248
 
@@ -219,6 +251,13 @@ in.
219
251
 
220
252
  **Field::Date**
221
253
 
254
+ `:sortable` - Specifies if sorting should be enabled in the table views.
255
+ Default is `true`.
256
+
257
+ `:sorting_column` - Specifies the column to be used for sorting in the table view.
258
+ By default, the column itself is used, but when used as a virtual column,
259
+ a custom sorting column can be specified.
260
+
222
261
  `:format` - Specify what format, using `strftime` you would like `Date`
223
262
  objects to display as.
224
263
 
@@ -248,6 +287,13 @@ If no collection is provided and no enum can be detected, the list of options wi
248
287
  `:searchable` - Specify if the attribute should be considered when searching.
249
288
  Default is `true`.
250
289
 
290
+ `:sortable` - Specifies if sorting should be enabled in the table views.
291
+ Default is `true`.
292
+
293
+ `:sorting_column` - Specifies the column to be used for sorting in the table view.
294
+ By default, the column itself is used, but when used as a virtual column,
295
+ a custom sorting column can be specified.
296
+
251
297
  `:include_blank` - Similar to [the option of the same name accepted by Rails helpers](https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html). If provided, a "blank" option will be added first to the list of options, with the value of `include_blank` as label.
252
298
 
253
299
  **Field::String**
@@ -255,6 +301,13 @@ Default is `true`.
255
301
  `:searchable` - Specify if the attribute should be considered when searching.
256
302
  Default is `true`.
257
303
 
304
+ `:sortable` - Specifies if sorting should be enabled in the table views.
305
+ Default is `true`.
306
+
307
+ `:sorting_column` - Specifies the column to be used for sorting in the table view.
308
+ By default, the column itself is used, but when used as a virtual column,
309
+ a custom sorting column can be specified.
310
+
258
311
  `:truncate` - Set the number of characters to display in the index view.
259
312
  Defaults to `50`.
260
313
 
@@ -263,14 +316,31 @@ Defaults to `50`.
263
316
  `:searchable` - Specify if the attribute should be considered when searching.
264
317
  Default is `false`.
265
318
 
319
+ `:sortable` - Specifies if sorting should be enabled in the table views.
320
+ Default is `true`.
321
+
322
+ `:sorting_column` - Specifies the column to be used for sorting in the table view.
323
+ By default, the column itself is used, but when used as a virtual column,
324
+ a custom sorting column can be specified.
325
+
266
326
  `:truncate` - Set the number of characters to display in the index view.
267
327
  Defaults to `50`.
268
328
 
329
+ `:input_options` - Options to customize the text area in form view.
330
+ Example: `.with_options(input_options: { rows: 20 })`
331
+
269
332
  **Field::Url**
270
333
 
271
334
  `:searchable` - Specify if the attribute should be considered when searching.
272
335
  Default is `true`.
273
336
 
337
+ `:sortable` - Specifies if sorting should be enabled in the table views.
338
+ Default is `true`.
339
+
340
+ `:sorting_column` - Specifies the column to be used for sorting in the table view.
341
+ By default, the column itself is used, but when used as a virtual column,
342
+ a custom sorting column can be specified.
343
+
274
344
  `:truncate` - Set the number of characters to display in the index view.
275
345
  Defaults to `50`.
276
346
 
@@ -282,6 +352,9 @@ Defaults is `{}`.
282
352
  `:searchable` - Specify if the attribute should be considered when searching.
283
353
  Default is `false`.
284
354
 
355
+ `:sortable` - Specifies if sorting should be enabled in the table views.
356
+ Default is `false`.
357
+
285
358
  `:truncate` - Set the number of characters to display in the views.
286
359
  Defaults to `50`.
287
360
 
@@ -436,3 +509,133 @@ en:
436
509
  ```
437
510
 
438
511
  If not defined (see `SHOW_PAGE_ATTRIBUTES` above), Administrate will default to the given strings.
512
+
513
+ ## Virtual Attributes
514
+
515
+ For all field types, you can use the `getter` option to change where the data is retrieved from or to set the data directly.
516
+
517
+ By using this, you can define an attribute in `ATTRIBUTE_TYPES` that doesn’t exist in the model, and use it for various purposes.
518
+
519
+ ### Attribute Aliases
520
+
521
+ You can create an alias for an attribute. For example:
522
+
523
+ ```ruby
524
+ ATTRIBUTE_TYPES = {
525
+ shipped_at: Field::DateTime,
526
+ shipped_on: Field::Date.with_options(
527
+ getter: :shipped_at
528
+ )
529
+ }
530
+ COLLECTION_ATTRIBUTES = [
531
+ :shipped_on
532
+ }
533
+ SHOW_PAGE_ATTRIBUTES = [
534
+ :shipped_at
535
+ }
536
+ ```
537
+
538
+ 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).
539
+
540
+ ### Decorated Attributes
541
+
542
+ You can also use this to decorate data. For example:
543
+
544
+ ```ruby
545
+ ATTRIBUTE_TYPES = {
546
+ price: Field::Number,
547
+ price_including_tax: Field::Number.with_options(
548
+ getter: -> (field) {
549
+ field.resource.price * 1.1 if field.resource.price.present?
550
+ }
551
+ )
552
+ }
553
+ ```
554
+
555
+ ### Composite Attributes
556
+
557
+ You can dynamically create a virtual attribute by combining multiple attributes for display. For example:
558
+
559
+ ```ruby
560
+ ATTRIBUTE_TYPES = {
561
+ first_name: Field::String,
562
+ last_name: Field::String,
563
+ full_name: Field::String.with_options(
564
+ getter: -> (field) {
565
+ [
566
+ field.resource.first_name,
567
+ field.resource.last_name
568
+ ].compact_blank.join(' ')
569
+ }
570
+ )
571
+ }
572
+ ```
573
+
574
+ ## Virtual Fields
575
+
576
+ Custom fields can also be defined using virtual fields.
577
+
578
+ ```ruby
579
+ ATTRIBUTE_TYPES = {
580
+ id: Field::Number,
581
+ receipt: Field::ReceiptLink
582
+ }
583
+ ```
584
+
585
+ ```ruby
586
+ module Administrate
587
+ module Field
588
+ class ReceiptLink < Base
589
+ def data
590
+ resource.id
591
+ end
592
+
593
+ def filename
594
+ "receipt-#{data}.pdf"
595
+ end
596
+
597
+ def url
598
+ "/files/receipts/#{filename}"
599
+ end
600
+ end
601
+ end
602
+ end
603
+ ```
604
+
605
+ ```erb
606
+ <%= link_to field.filename, field.url %>
607
+ ```
608
+
609
+ ### Custom Actions via Virtual Field
610
+
611
+ By creating custom fields that are not dependent on specific attributes, you can insert custom views into any screen.
612
+ For example, you can add custom buttons like this:
613
+
614
+ ```ruby
615
+ ATTRIBUTE_TYPES = {
616
+ id: Field::Number,
617
+ custom_index_actions: Field::CustomActionButtons,
618
+ custom_show_actions: Field::CustomActionButtons,
619
+ }
620
+ ```
621
+
622
+ ```ruby
623
+ module Administrate
624
+ module Field
625
+ class CustomActionButtons < Base
626
+ def data
627
+ resource.id
628
+ end
629
+ end
630
+ end
631
+ end
632
+ ```
633
+
634
+ ```erb
635
+ <%# app/views/fields/custom_action_buttons/_index.html.erb %>
636
+ <% if field.data.present? %>
637
+ <%= button_to "some action 1", [:some_action_1, namespace, field.resource] %>
638
+ <%= button_to "some action 2", [:some_action_2, namespace, field.resource] %>
639
+ <%= button_to "some action 3", [:some_action_3, namespace, field.resource] %>
640
+ <% end %>
641
+ ```
@@ -94,3 +94,50 @@ 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
+ ```
122
+
123
+ ## Adding custom CSS and JS
124
+
125
+ You can add custom CSS and JS to Administrate. Put the files in the
126
+ appropriate folders (typically under `assets`) and point Administrate to them
127
+ using the following API, preferably in an initializer. For example, if your
128
+ files are called `admin.css` and `admin.js`:
129
+
130
+ ```
131
+ /// config/initializers/administrate.rb
132
+ Administrate::Engine.add_stylesheet("admin")
133
+ Administrate::Engine.add_javascript("admin")
134
+ ```
135
+
136
+ Then make sure to list them in your manifest file (Rails will helpfully remind
137
+ you of this step if you miss it):
138
+
139
+ ```
140
+ /// app/assets/config/manifest.js
141
+ //= link admin.css
142
+ //= link admin.js
143
+ ```
@@ -18,10 +18,10 @@ Since ActiveRecord infers the class name from the first argument, the new `has_m
18
18
 
19
19
  ## Add new relationship to dashboard
20
20
 
21
- Your new scoped relation can be used in the dashboard just like the original `HasMany`. Notice the new field needs to specifiy the class name as an option like you did in the model.
21
+ Your new scoped relation can be used in the dashboard just like the original `HasMany`.
22
22
 
23
23
  ```ruby
24
24
  ATTRIBUTE_TYPES = {
25
25
  orders: Field::HasMany,
26
- processed_orders: Field::HasMany.with_options(class_name: 'Order')
26
+ processed_orders: Field::HasMany
27
27
  ```
@@ -0,0 +1,45 @@
1
+ ---
2
+ title: Switching templates with view variants
3
+ ---
4
+
5
+ You can switch to different templates using Rails' support for [view
6
+ variants][], which can be used to override the template used inside the
7
+ controller.
8
+
9
+ By setting the `request.variant` option to any value (in this case, `:admin`)
10
+ at any point in any controller, you can add a new variant to Rails' template
11
+ lookup tree (in this case, `.html+admin.erb`).
12
+
13
+ For example, to add a button to become the admin to view certain functionality:
14
+
15
+ ```ruby
16
+ class CustomersController < Admin::ApplicationController
17
+ before_action :with_variant, only: %i[index]
18
+
19
+ private
20
+
21
+ def with_variant
22
+ if @current_user.admin?
23
+ request.variant = :admin
24
+ end
25
+ end
26
+ end
27
+ ```
28
+
29
+ ```erb
30
+ <!-- app/views/admin/customers/_index_header.html.erb -->
31
+ <p class="identity__banner">
32
+ You are logged in as <em><%= pundit_user.name %></em>.
33
+ <%= link_to("Become the Admin", become_admin_customer_path("admin"),
34
+ class: "identity__become-action")%>
35
+ </p>
36
+ ```
37
+
38
+ ```erb
39
+ <!-- app/views/admin/customers/_index_header.html+admin.erb -->
40
+ <p class="identity__banner identity__banner--admin">
41
+ You are logged in as <em><%= pundit_user.name %></em>.
42
+ </p>
43
+ ```
44
+
45
+ [view variants]: https://guides.rubyonrails.org/layouts_and_rendering.html#the-variants-option
data/docs/guides.md CHANGED
@@ -5,3 +5,4 @@ title: Guides
5
5
  - [Hiding Dashboards from the Sidebar](./guides/hiding_dashboards_from_sidebar)
6
6
  - [Customising the search](./guides/customising_search)
7
7
  - [Scoping HasMany Relations](./guides/scoping_has_many_relations.md)
8
+ - [Switching templates with view variants](./guides/switching_templates_with_view_variants.md)
@@ -0,0 +1,34 @@
1
+ ---
2
+ title: Migrating to v1
3
+ ---
4
+
5
+ In the release of v1.0.0, we [began bundling assets in the gem itself][2397].
6
+ In the future, this should mean that any changes made to assets (coming
7
+ from you or from Administrate updates) should not have an effect on you.
8
+ However, this is quite a big change and so you might find some problems.
9
+
10
+ As with most upgrades, if you're upgrading between versions with changes to the
11
+ templates, and if you've customised them, you may need to apply recent changes.
12
+ You can see those which changed in the [CHANGELOG][].
13
+
14
+ This applies to both modified files in `app/views/admin` and `app/views/fields`
15
+ if you have your own Field classes defined. A good way is to use the same
16
+ command to generate the view as for the earlier version:
17
+ `rails generate administrate:views:ACTION MyModel`
18
+ noting the changes and re-applying the modifications
19
+
20
+ [2397]: https://github.com/thoughtbot/administrate/pull/2397
21
+ [CHANGELOG]: https://github.com/thoughtbot/administrate/blob/main/CHANGELOG.md
22
+
23
+ ## Reported issues
24
+
25
+ ### Removal of the `sprockets-rails` transitive dependency
26
+
27
+ [Issue][2514]
28
+
29
+ Previously, Administrate depended on [`sprockets-rails`][], if you have a
30
+ dependency which requires this, you may now need to add a direct dependency on
31
+ your application.
32
+
33
+ [2514]: https://github.com/thoughtbot/administrate/issues/2514
34
+ [`sprockets-rails`]: https://rubygems.org/gems/sprockets-rails
@@ -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
@@ -110,18 +111,12 @@ module Administrate
110
111
  attribute_includes(collection_attributes)
111
112
  end
112
113
 
113
- def item_includes
114
- # Deprecated, internal usage has moved to #item_associations
115
- Administrate.warn_of_deprecated_method(self.class, :item_includes)
116
- attribute_includes(show_page_attributes)
117
- end
118
-
119
114
  def item_associations
120
115
  attributes = if show_page_attributes.is_a?(Hash)
121
- show_page_attributes.values.flatten
122
- else
123
- show_page_attributes
124
- end
116
+ show_page_attributes.values.flatten
117
+ else
118
+ show_page_attributes
119
+ end
125
120
  attribute_associated attributes
126
121
  end
127
122