administrate 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
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: