administrate 0.14.0 → 0.15.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/administrate/components/associative.js +1 -0
  3. data/app/assets/stylesheets/administrate/components/_attributes.scss +3 -2
  4. data/app/assets/stylesheets/administrate/components/_field-unit.scss +4 -0
  5. data/app/assets/stylesheets/administrate/components/_main-content.scss +1 -0
  6. data/app/controllers/administrate/application_controller.rb +11 -11
  7. data/app/helpers/administrate/application_helper.rb +10 -23
  8. data/app/views/administrate/application/_collection.html.erb +1 -1
  9. data/app/views/administrate/application/_form.html.erb +1 -1
  10. data/app/views/administrate/application/index.html.erb +2 -2
  11. data/app/views/administrate/application/show.html.erb +1 -1
  12. data/app/views/fields/belongs_to/_form.html.erb +3 -3
  13. data/app/views/fields/has_one/_index.html.erb +1 -1
  14. data/app/views/fields/has_one/_show.html.erb +4 -4
  15. data/app/views/fields/number/_form.html.erb +1 -1
  16. data/app/views/fields/polymorphic/_show.html.erb +1 -1
  17. data/app/views/fields/select/_form.html.erb +2 -2
  18. data/app/views/fields/time/_index.html.erb +3 -1
  19. data/app/views/fields/time/_show.html.erb +3 -1
  20. data/app/views/layouts/administrate/application.html.erb +1 -0
  21. data/config/locales/administrate.fi.yml +30 -0
  22. data/config/locales/administrate.fr.yml +2 -2
  23. data/config/locales/administrate.nl.yml +4 -4
  24. data/config/locales/administrate.pt-BR.yml +2 -2
  25. data/config/locales/administrate.pt.yml +3 -3
  26. data/config/locales/administrate.tr.yml +30 -0
  27. data/config/unicorn.rb +8 -13
  28. data/docs/adding_controllers_without_related_model.md +18 -0
  29. data/docs/customizing_dashboards.md +32 -16
  30. data/docs/extending_administrate.md +27 -0
  31. data/docs/getting_started.md +27 -5
  32. data/docs/guides.md +5 -0
  33. data/docs/guides/hiding_dashboards_from_sidebar.md +19 -0
  34. data/lib/administrate.rb +19 -0
  35. data/lib/administrate/base_dashboard.rb +5 -2
  36. data/lib/administrate/engine.rb +7 -0
  37. data/lib/administrate/field/associative.rb +48 -4
  38. data/lib/administrate/field/base.rb +26 -0
  39. data/lib/administrate/field/belongs_to.rb +13 -3
  40. data/lib/administrate/field/deferred.rb +7 -3
  41. data/lib/administrate/field/has_many.rb +15 -2
  42. data/lib/administrate/field/has_one.rb +28 -8
  43. data/lib/administrate/field/number.rb +19 -2
  44. data/lib/administrate/field/polymorphic.rb +1 -1
  45. data/lib/administrate/order.rb +3 -1
  46. data/lib/administrate/resource_resolver.rb +1 -1
  47. data/lib/administrate/search.rb +11 -8
  48. data/lib/administrate/version.rb +1 -1
  49. data/lib/administrate/view_generator.rb +7 -1
  50. data/lib/generators/administrate/dashboard/dashboard_generator.rb +3 -10
  51. data/lib/generators/administrate/dashboard/templates/dashboard.rb.erb +3 -3
  52. data/lib/generators/administrate/install/install_generator.rb +37 -1
  53. data/lib/generators/administrate/routes/routes_generator.rb +3 -13
  54. data/lib/generators/administrate/views/views_generator.rb +5 -4
  55. metadata +15 -25
  56. data/docs/contributing.md +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e8120deb0ddc3a88302230382298ce39c25d60e4effca6336787016c46024d91
4
- data.tar.gz: ad6262c38fca6d8be885d8687db7b02444da05c751c8dcb25a71d7a292d43f05
3
+ metadata.gz: bb407c439ba3795c3161109f57d64a8e20db553d80f583c6d2a66bfe0f713cd7
4
+ data.tar.gz: 1691010813773e6ecc19b067adb4a610c6624f2ec2d8a03bb6414a683d5d83b0
5
5
  SHA512:
6
- metadata.gz: e6bfde68398c548cfe04665c21c5e44fd8f659c404ddfcb141c5b358396cb6d0ca1c087b459a322553ff9dfeb195f033d817829d7a84bc80024004f1390faf5c
7
- data.tar.gz: 794416e6cc50fadef9674c2fcb5316be67e7523d19c31431dfe3f80165a5355f3ce12019aad78681b6f5ede71797f3b3bab9b911236e8f3231bd0fcdacd15bc2
6
+ metadata.gz: 0fc7042ed3389b1cf87a4ba41681e310dc3678e790a5af0d3c3e3d64c213f50b5bf66409069159a18e784c9cdaf5e6d60e2d2614f4647b5ab0d8e0b4e2f6b70e
7
+ data.tar.gz: 1c8b66a38eca96f2002ccd8b253b4fc7abd082e7376111e2e1be399b870755ce29511982828760fd6a229f5571eb1ace83a9121fae2253db2653218ffbd237ce
@@ -1,4 +1,5 @@
1
1
  $(function() {
2
2
  $('.field-unit--belongs-to select').selectize({});
3
3
  $(".field-unit--has-many select").selectize({});
4
+ $('.field-unit--polymorphic select').selectize({});
4
5
  });
@@ -5,7 +5,7 @@
5
5
  margin-bottom: $base-spacing;
6
6
  margin-top: 0.25em;
7
7
  text-align: right;
8
- width: calc(15% - 1rem);
8
+ width: calc(20% - 1rem);
9
9
  }
10
10
 
11
11
  .preserve-whitespace {
@@ -17,7 +17,8 @@
17
17
  float: left;
18
18
  margin-bottom: $base-spacing;
19
19
  margin-left: 2rem;
20
- width: calc(85% - 1rem);
20
+ width: calc(80% - 1rem);
21
+ word-break: break-word;
21
22
  }
22
23
 
23
24
  .attribute--nested {
@@ -19,6 +19,10 @@
19
19
  margin-left: 2rem;
20
20
  max-width: 50rem;
21
21
  width: 100%;
22
+
23
+ .optgroup-header {
24
+ font-weight: $bold-font-weight;
25
+ }
22
26
  }
23
27
 
24
28
  .field-unit--nested {
@@ -5,6 +5,7 @@
5
5
  0 2px 2px rgba($black, 0.2);
6
6
  flex: 1 1 100%;
7
7
  padding-bottom: 10vh;
8
+ min-width: 800px;
8
9
  }
9
10
 
10
11
  .main-content__header,
@@ -3,13 +3,14 @@ module Administrate
3
3
  protect_from_forgery with: :exception
4
4
 
5
5
  def index
6
+ authorize_resource(resource_class)
6
7
  search_term = params[:search].to_s.strip
7
8
  resources = Administrate::Search.new(scoped_resource,
8
9
  dashboard_class,
9
10
  search_term).run
10
11
  resources = apply_collection_includes(resources)
11
12
  resources = order.apply(resources)
12
- resources = resources.page(params[:page]).per(records_per_page)
13
+ resources = resources.page(params[:_page]).per(records_per_page)
13
14
  page = Administrate::Page::Collection.new(dashboard, order: order)
14
15
 
15
16
  render locals: {
@@ -52,7 +53,7 @@ module Administrate
52
53
  else
53
54
  render :new, locals: {
54
55
  page: Administrate::Page::Form.new(dashboard, resource),
55
- }
56
+ }, status: :unprocessable_entity
56
57
  end
57
58
  end
58
59
 
@@ -65,7 +66,7 @@ module Administrate
65
66
  else
66
67
  render :edit, locals: {
67
68
  page: Administrate::Page::Form.new(dashboard, requested_resource),
68
- }
69
+ }, status: :unprocessable_entity
69
70
  end
70
71
  end
71
72
 
@@ -105,10 +106,7 @@ module Administrate
105
106
  end
106
107
 
107
108
  def sorting_attribute
108
- params.fetch(resource_name, {}).fetch(
109
- :order,
110
- default_sorting_attribute,
111
- )
109
+ sorting_params.fetch(:order) { default_sorting_attribute }
112
110
  end
113
111
 
114
112
  def default_sorting_attribute
@@ -116,16 +114,17 @@ module Administrate
116
114
  end
117
115
 
118
116
  def sorting_direction
119
- params.fetch(resource_name, {}).fetch(
120
- :direction,
121
- default_sorting_direction,
122
- )
117
+ sorting_params.fetch(:direction) { default_sorting_direction }
123
118
  end
124
119
 
125
120
  def default_sorting_direction
126
121
  nil
127
122
  end
128
123
 
124
+ def sorting_params
125
+ Hash.try_convert(request.query_parameters[resource_name]) || {}
126
+ end
127
+
129
128
  def dashboard
130
129
  @dashboard ||= dashboard_class.new
131
130
  end
@@ -174,6 +173,7 @@ module Administrate
174
173
  to: :resource_resolver
175
174
  helper_method :namespace
176
175
  helper_method :resource_name
176
+ helper_method :resource_class
177
177
 
178
178
  def resource_resolver
179
179
  @resource_resolver ||=
@@ -1,6 +1,7 @@
1
1
  module Administrate
2
2
  module ApplicationHelper
3
3
  PLURAL_MANY_COUNT = 2.1
4
+ SINGULAR_COUNT = 1
4
5
 
5
6
  def application_title
6
7
  if Rails::VERSION::MAJOR <= 5
@@ -16,22 +17,7 @@ module Administrate
16
17
  end
17
18
 
18
19
  def requireness(field)
19
- required_field?(field) ? "required" : "optional"
20
- end
21
-
22
- def required_field?(field)
23
- has_presence_validator?(field.resource.class, field.attribute)
24
- end
25
-
26
- def has_presence_validator?(resource_class, field_name)
27
- validators_on(resource_class, field_name).
28
- any? { |v| v.class == ActiveRecord::Validations::PresenceValidator }
29
- end
30
-
31
- def validators_on(resource_class, field_name)
32
- return [] unless resource_class.respond_to?(:validators_on)
33
-
34
- resource_class.validators_on(field_name)
20
+ field.required? ? "required" : "optional"
35
21
  end
36
22
 
37
23
  def dashboard_from_resource(resource_name)
@@ -43,10 +29,10 @@ module Administrate
43
29
  dashboard.try(:model) || resource_name.to_sym
44
30
  end
45
31
 
46
- def display_resource_name(resource_name)
32
+ def display_resource_name(resource_name, opts = {})
47
33
  dashboard_from_resource(resource_name).resource_name(
48
- count: PLURAL_MANY_COUNT,
49
- default: default_resource_name(resource_name),
34
+ count: opts[:singular] ? SINGULAR_COUNT : PLURAL_MANY_COUNT,
35
+ default: default_resource_name(resource_name, opts),
50
36
  )
51
37
  end
52
38
 
@@ -70,19 +56,20 @@ module Administrate
70
56
  association_params = collection_names.map do |assoc_name|
71
57
  { assoc_name => %i[order direction page per_page] }
72
58
  end
73
- params.permit(:search, :id, :page, :per_page, association_params)
59
+ params.permit(:search, :id, :_page, :per_page, association_params)
74
60
  end
75
61
 
76
62
  def clear_search_params
77
- params.except(:search, :page).permit(
63
+ params.except(:search, :_page).permit(
78
64
  :per_page, resource_name => %i[order direction]
79
65
  )
80
66
  end
81
67
 
82
68
  private
83
69
 
84
- def default_resource_name(resource_name)
85
- resource_name.to_s.pluralize.gsub("/", "_").titleize
70
+ def default_resource_name(name, opts = {})
71
+ resource_name = (opts[:singular] ? name.to_s : name.to_s.pluralize)
72
+ resource_name.gsub("/", "_").titleize
86
73
  end
87
74
  end
88
75
  end
@@ -33,7 +33,7 @@ to display a collection of resources in an HTML table.
33
33
  )) do %>
34
34
  <%= t(
35
35
  "helpers.label.#{collection_presenter.resource_name}.#{attr_name}",
36
- default: attr_name.to_s,
36
+ default: resource_class.human_attribute_name(attr_name),
37
37
  ).titleize %>
38
38
  <% if collection_presenter.ordered_by?(attr_name) %>
39
39
  <span class="cell-label__sort-indicator cell-label__sort-indicator--<%= collection_presenter.ordered_html_class(attr_name) %>">
@@ -21,7 +21,7 @@ and renders all form fields for a resource's editable attributes.
21
21
  <%= t(
22
22
  "administrate.form.errors",
23
23
  pluralized_errors: pluralize(page.resource.errors.count, t("administrate.form.error")),
24
- resource_name: display_resource_name(page.resource_name).singularize
24
+ resource_name: display_resource_name(page.resource_name, singular: true)
25
25
  ) %>
26
26
  </h2>
27
27
 
@@ -44,7 +44,7 @@ It renders the `_table` partial to display details about the resources.
44
44
  <%= link_to(
45
45
  t(
46
46
  "administrate.actions.new_resource",
47
- name: page.resource_name.titleize.downcase
47
+ name: display_resource_name(page.resource_name, singular: true).downcase
48
48
  ),
49
49
  [:new, namespace, page.resource_path],
50
50
  class: "button",
@@ -62,5 +62,5 @@ It renders the `_table` partial to display details about the resources.
62
62
  table_title: "page-title"
63
63
  ) %>
64
64
 
65
- <%= paginate resources %>
65
+ <%= paginate resources, param_name: '_page' %>
66
66
  </section>
@@ -38,7 +38,7 @@ as well as a link to its edit page.
38
38
  <dt class="attribute-label" id="<%= attribute.name %>">
39
39
  <%= t(
40
40
  "helpers.label.#{resource_name}.#{attribute.name}",
41
- default: attribute.name.titleize,
41
+ default: page.resource.class.human_attribute_name(attribute.name),
42
42
  ) %>
43
43
  </dt>
44
44
 
@@ -20,7 +20,7 @@ that displays all possible records to associate with.
20
20
  <%= f.label field.permitted_attribute %>
21
21
  </div>
22
22
  <div class="field-unit__field">
23
- <%= f.select(field.permitted_attribute) do %>
24
- <%= options_for_select(field.associated_resource_options, field.selected_option) %>
25
- <% end %>
23
+ <%= f.select(field.permitted_attribute,
24
+ options_for_select(field.associated_resource_options, field.selected_option),
25
+ include_blank: field.include_blank_option) %>
26
26
  </div>
@@ -15,7 +15,7 @@ By default, the relationship is rendered as a link to the associated object.
15
15
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/HasOne
16
16
  %>
17
17
 
18
- <% if field.data %>
18
+ <% if field.linkable? %>
19
19
  <%= link_to(
20
20
  field.display_associated_resource,
21
21
  [namespace, field.data],
@@ -4,7 +4,7 @@
4
4
  This partial renders a has_one relationship,
5
5
  to be displayed on a resource's show page.
6
6
 
7
- All fields of has_one relationship would be rendered
7
+ All show page attributes of has_one relationship would be rendered
8
8
 
9
9
  ## Local variables:
10
10
 
@@ -15,7 +15,7 @@ All fields of has_one relationship would be rendered
15
15
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/HasOne
16
16
  %>
17
17
 
18
- <% if field.data %>
18
+ <% if field.linkable? %>
19
19
  <fieldset class="attribute--nested">
20
20
  <legend>
21
21
  <%= link_to(
@@ -23,7 +23,7 @@ All fields of has_one relationship would be rendered
23
23
  [namespace, field.data],
24
24
  ) %>
25
25
  </legend>
26
- <% field.nested_form.attributes.each do |attribute| -%>
26
+ <% field.nested_show.attributes.each do |attribute| -%>
27
27
  <div>
28
28
  <dt class="attribute-label">
29
29
  <%= t(
@@ -32,7 +32,7 @@ All fields of has_one relationship would be rendered
32
32
  ) %>
33
33
  </dt>
34
34
  <dd class="attribute-data attribute-data--<%= attribute.html_class %>">
35
- <%= attribute.data %>
35
+ <%= render_field attribute, { page: page } %>
36
36
  </dd>
37
37
  </div>
38
38
  <% end -%>
@@ -19,5 +19,5 @@ By default, the input is a text field.
19
19
  <%= f.label field.attribute %>
20
20
  </div>
21
21
  <div class="field-unit__field">
22
- <%= f.text_field field.attribute %>
22
+ <%= f.number_field field.attribute, step: "any" %>
23
23
  </div>
@@ -17,7 +17,7 @@ By default, the relationship is rendered as a link to the associated object.
17
17
  %>
18
18
 
19
19
  <% if field.data %>
20
- <% if valid_action?(:show, field.attribute) %>
20
+ <% if valid_action?(:show, field.data.class) %>
21
21
  <%= link_to(
22
22
  field.display_associated_resource,
23
23
  [namespace, field.data],
@@ -26,7 +26,7 @@ to be displayed on a resource's edit form page.
26
26
  field.selectable_options,
27
27
  :last,
28
28
  :first,
29
- field.data.presence,
29
+ field.data,
30
30
  )
31
31
  ) %>
32
32
  <% else %>
@@ -36,7 +36,7 @@ to be displayed on a resource's edit form page.
36
36
  field.selectable_options,
37
37
  :to_s,
38
38
  :to_s,
39
- field.data.presence,
39
+ field.data,
40
40
  )
41
41
  ) %>
42
42
  <% end %>
@@ -14,4 +14,6 @@ By default, the attribute is rendered as a text tag.
14
14
 
15
15
  %>
16
16
 
17
- <%= field.data.strftime("%I:%M%p").to_s %>
17
+ <% if field.data %>
18
+ <%= field.data.strftime("%I:%M%p").to_s %>
19
+ <% end %>
@@ -14,4 +14,6 @@ By default, the attribute is rendered as a text tag.
14
14
 
15
15
  %>
16
16
 
17
- <%= field.data.strftime("%I:%M%p").to_s %>
17
+ <% if field.data %>
18
+ <%= field.data.strftime("%I:%M%p").to_s %>
19
+ <% end %>
@@ -23,6 +23,7 @@ By default, it renders:
23
23
  </title>
24
24
  <%= render "stylesheet" %>
25
25
  <%= csrf_meta_tags %>
26
+ <%= csp_meta_tag if defined?(csp_meta_tag) %>
26
27
  </head>
27
28
  <body>
28
29
  <%= render "icons" %>
@@ -0,0 +1,30 @@
1
+ ---
2
+ fi:
3
+ administrate:
4
+ actions:
5
+ confirm: Oletko varma?
6
+ destroy: Poista
7
+ edit: Muokkaa
8
+ edit_resource: Muokkaa %{name}
9
+ show_resource: Näytä %{name}
10
+ new_resource: Uusi %{name}
11
+ back: Takaisin
12
+ controller:
13
+ create:
14
+ success: "%{resource} luotiin onnistuneesti."
15
+ destroy:
16
+ success: "%{resource} poistettiin onnistuneesti."
17
+ update:
18
+ success: "%{resource} päivitettiin onnistuneesti."
19
+ fields:
20
+ has_many:
21
+ more: Näytetään %{count}/%{total_count}
22
+ none: Ei yhtään
23
+ form:
24
+ error: virhe
25
+ errors: "%{pluralized_errors} estivät tätä %{resource_name} tallentumasta:"
26
+ navigation:
27
+ back_to_app: Takaisin sovellukseen
28
+ search:
29
+ clear: Tyhjennä haku
30
+ label: Etsi %{resource}
@@ -2,7 +2,7 @@
2
2
  fr:
3
3
  administrate:
4
4
  actions:
5
- confirm: Êtes-vous sûr ?
5
+ confirm: Êtes-vous sûr(e) ?
6
6
  destroy: Supprimer
7
7
  edit: Modifier
8
8
  edit_resource: Modifier %{name}
@@ -22,7 +22,7 @@ fr:
22
22
  none: Aucun
23
23
  form:
24
24
  error: erreur
25
- errors: "%{pluralized_errors} ont empêchés %{resource_name} d'être sauvergardé :"
25
+ errors: "%{pluralized_errors} ont empêché %{resource_name} d'être sauvegardé(e) :"
26
26
  navigation:
27
27
  back_to_app: Retour à l'application
28
28
  search:
@@ -11,18 +11,18 @@ nl:
11
11
  back: Terug
12
12
  controller:
13
13
  create:
14
- success: "%{resource} was succesvol aangemaakt."
14
+ success: "%{resource} is succesvol aangemaakt."
15
15
  destroy:
16
- success: "%{resource} was succesvol verwijderd."
16
+ success: "%{resource} is succesvol verwijderd."
17
17
  update:
18
- success: "%{resource} was succesvol geupdated."
18
+ success: "%{resource} is succesvol geupdated."
19
19
  fields:
20
20
  has_many:
21
21
  more: Resultaat %{count} van %{total_count}
22
22
  none: Geen
23
23
  form:
24
24
  error: error
25
- errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
25
+ errors: "%{pluralized_errors} maakten het onmogelijk %{resource_name} op:"
26
26
  navigation:
27
27
  back_to_app: Terug naar app
28
28
  search: