semantic-administrate 0.1.0 → 0.1.1

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/administrate/application_controller.rb +21 -2
  3. data/app/controllers/concerns/administrate/punditize.rb +36 -0
  4. data/app/views/administrate/application/_collection.html.erb +10 -7
  5. data/app/views/administrate/application/_form.html.erb +5 -2
  6. data/app/views/administrate/application/edit.html.erb +3 -3
  7. data/app/views/administrate/application/index.html.erb +5 -2
  8. data/app/views/administrate/application/new.html.erb +6 -1
  9. data/app/views/administrate/application/show.html.erb +3 -3
  10. data/app/views/fields/has_many/_index.html.erb +1 -1
  11. data/config/locales/administrate.ar.yml +6 -4
  12. data/config/locales/administrate.bs.yml +6 -4
  13. data/config/locales/administrate.ca.yml +6 -4
  14. data/config/locales/administrate.da.yml +6 -4
  15. data/config/locales/administrate.de.yml +8 -6
  16. data/config/locales/administrate.en.yml +6 -4
  17. data/config/locales/administrate.es.yml +6 -4
  18. data/config/locales/administrate.fr.yml +6 -4
  19. data/config/locales/administrate.it.yml +6 -4
  20. data/config/locales/administrate.ja.yml +6 -4
  21. data/config/locales/administrate.ko.yml +6 -4
  22. data/config/locales/administrate.nl.yml +6 -4
  23. data/config/locales/administrate.pl.yml +6 -4
  24. data/config/locales/administrate.pt-BR.yml +6 -4
  25. data/config/locales/administrate.pt.yml +6 -4
  26. data/config/locales/administrate.ru.yml +6 -4
  27. data/config/locales/administrate.sv.yml +6 -4
  28. data/config/locales/administrate.uk.yml +6 -4
  29. data/config/locales/administrate.vi.yml +6 -4
  30. data/config/locales/administrate.zh-CN.yml +6 -4
  31. data/config/locales/administrate.zh-TW.yml +6 -4
  32. data/docs/authorization.md +69 -0
  33. data/docs/customizing_dashboards.md +18 -7
  34. data/docs/getting_started.md +42 -0
  35. data/lib/administrate/field/base.rb +1 -1
  36. data/lib/administrate/field/belongs_to.rb +1 -1
  37. data/lib/administrate/field/date_time.rb +13 -2
  38. data/lib/administrate/field/deferred.rb +3 -2
  39. data/lib/administrate/field/has_many.rb +2 -2
  40. data/lib/administrate/field/has_one.rb +16 -8
  41. data/lib/administrate/field/polymorphic.rb +1 -1
  42. data/lib/administrate/order.rb +38 -5
  43. data/lib/administrate/search.rb +1 -1
  44. data/lib/administrate/version.rb +1 -1
  45. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f9f5acea640f6f28faed41c71a9c0f08cf6dee72
4
- data.tar.gz: 94c28f34c197ac05d1482b17ddd7b3bee39a5fb6
3
+ metadata.gz: 2123d47601bf83f82794fe639a592c0be68130e8
4
+ data.tar.gz: 4f57f44bea647c725247c42fb9f18e21825ff7bc
5
5
  SHA512:
6
- metadata.gz: 9ececb0e5c2f750c26750c2ea01feac0519dfdefbfc24988480e5e821e92d5818cbdf7e1d527a63499eed709c422d58bddeca5bc072c9039d11c527f57230a2d
7
- data.tar.gz: c624e8334a33ac55996d2a9ef1891c95734a49680b9f69acd590a2612ab128713a66b1c629715a15a8fed027c15355560b094b550c02a5563cba900ea798e364
6
+ metadata.gz: c52c71169aed4dad7ea08c9f1873bdefa22e0b14a9dd6940cac3aa56f42dd29472744c9ec82f23bc7c2d908d44ed7e95b262900a331384c2b38200d12c144c64
7
+ data.tar.gz: be36d780bdd94b43d132468d6498f68e40dcff40e3d8642744c8f77886083559fa0f05f570cbe4a19a0b008b3796e3e7e880f6bedba1d8d0040036f28ffe7028
@@ -27,8 +27,10 @@ module Administrate
27
27
  end
28
28
 
29
29
  def new
30
+ resource = resource_class.new
31
+ authorize_resource(resource)
30
32
  render locals: {
31
- page: Administrate::Page::Form.new(dashboard, resource_class.new),
33
+ page: Administrate::Page::Form.new(dashboard, resource),
32
34
  }
33
35
  end
34
36
 
@@ -40,6 +42,7 @@ module Administrate
40
42
 
41
43
  def create
42
44
  resource = resource_class.new(resource_params)
45
+ authorize_resource(resource)
43
46
 
44
47
  if resource.save
45
48
  redirect_to(
@@ -103,7 +106,9 @@ module Administrate
103
106
  end
104
107
 
105
108
  def requested_resource
106
- @_requested_resource ||= find_resource(params[:id])
109
+ @_requested_resource ||= find_resource(params[:id]).tap do |resource|
110
+ authorize_resource(resource)
111
+ end
107
112
  end
108
113
 
109
114
  def find_resource(param)
@@ -158,5 +163,19 @@ module Administrate
158
163
  dashboard.collection_attributes
159
164
  ).any? { |_name, attribute| attribute.searchable? }
160
165
  end
166
+
167
+ def show_action?(action, resource)
168
+ true
169
+ end
170
+ helper_method :show_action?
171
+
172
+ def new_resource
173
+ resource_class.new
174
+ end
175
+ helper_method :new_resource
176
+
177
+ def authorize_resource(resource)
178
+ resource
179
+ end
161
180
  end
162
181
  end
@@ -0,0 +1,36 @@
1
+ if Object.const_defined?("Pundit")
2
+ module Administrate
3
+ module Punditize
4
+ extend ActiveSupport::Concern
5
+ include Pundit
6
+
7
+ included do
8
+ def scoped_resource
9
+ policy_scope_admin super
10
+ end
11
+
12
+ def authorize_resource(resource)
13
+ authorize resource
14
+ end
15
+
16
+ def show_action?(action, resource)
17
+ Pundit.policy!(pundit_user, resource).send("#{action}?".to_sym)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ # Like the policy_scope method in stock Pundit, but allows the 'resolve'
24
+ # to be overridden by 'resolve_admin' for a different index scope in Admin
25
+ # controllers.
26
+ def policy_scope_admin(scope)
27
+ ps = Pundit::PolicyFinder.new(scope).scope!.new(pundit_user, scope)
28
+ if ps.respond_to? :resolve_admin
29
+ ps.resolve_admin
30
+ else
31
+ ps.resolve
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -63,11 +63,13 @@ to display a collection of resources in an HTML table.
63
63
  >
64
64
  <% collection_presenter.attributes_for(resource).each do |attribute| %>
65
65
  <td class="cell-data cell-data--<%= attribute.html_class %>">
66
- <a href="<%= polymorphic_path([namespace, resource]) -%>"
67
- class="action-show"
68
- >
69
- <%= render_field attribute %>
70
- </a>
66
+ <% if show_action? :show, resource -%>
67
+ <a href="<%= polymorphic_path([namespace, resource]) -%>"
68
+ class="action-show"
69
+ >
70
+ <%= render_field attribute %>
71
+ </a>
72
+ <% end -%>
71
73
  </td>
72
74
  <% end %>
73
75
 
@@ -75,7 +77,8 @@ to display a collection of resources in an HTML table.
75
77
  <td><%= link_to(
76
78
  t("administrate.actions.edit"),
77
79
  [:edit, namespace, resource],
78
- ) %></td>
80
+ class: "action-edit",
81
+ ) if show_action? :edit, resource%></td>
79
82
  <% end %>
80
83
 
81
84
  <% if valid_action? :destroy, collection_presenter.resource_name %>
@@ -84,7 +87,7 @@ to display a collection of resources in an HTML table.
84
87
  [namespace, resource],
85
88
  method: :delete,
86
89
  data: { confirm: t("administrate.actions.confirm") }
87
- ) %></td>
90
+ ) if show_action? :destroy, resource %></td>
88
91
  <% end %>
89
92
  </tr>
90
93
  <% end %>
@@ -18,8 +18,11 @@ and renders all form fields for a resource's editable attributes.
18
18
  <% if page.resource.errors.any? %>
19
19
  <div id="error_explanation">
20
20
  <h2>
21
- <%= pluralize(page.resource.errors.count, "error") %>
22
- prohibited this <%= page.resource_name %> from being saved:
21
+ <%= t(
22
+ "administrate.form.errors",
23
+ pluralized_errors: pluralize(page.resource.errors.count, t("administrate.form.error")),
24
+ resource_name: display_resource_name(page.resource_name)
25
+ ) %>
23
26
  </h2>
24
27
 
25
28
  <ul>
@@ -15,7 +15,7 @@ It displays a header, and renders the `_form` partial to do the heavy lifting.
15
15
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Form
16
16
  %>
17
17
 
18
- <% content_for(:title) { "#{t("administrate.actions.edit")} #{page.page_title}" } %>
18
+ <% content_for(:title) { t("administrate.actions.edit_resource", name: page.page_title) } %>
19
19
 
20
20
  <header class="main-content__header" role="banner">
21
21
  <h1 class="main-content__page-title">
@@ -24,10 +24,10 @@ It displays a header, and renders the `_form` partial to do the heavy lifting.
24
24
 
25
25
  <div>
26
26
  <%= link_to(
27
- "#{t("administrate.actions.show")} #{page.page_title}",
27
+ t("administrate.actions.show_resource", name: page.page_title),
28
28
  [namespace, page.resource],
29
29
  class: "button",
30
- ) if valid_action? :show %>
30
+ ) if valid_action?(:show) && show_action?(:show, page.resource) %>
31
31
  </div>
32
32
  </header>
33
33
 
@@ -44,10 +44,13 @@ It renders the `_table` partial to display details about the resources.
44
44
 
45
45
  <div class="main-content__navs">
46
46
  <%= link_to(
47
- "#{t("administrate.actions.new")} #{page.resource_name.titleize.downcase}",
47
+ t(
48
+ "administrate.actions.new_resource",
49
+ name: page.resource_name.titleize.downcase
50
+ ),
48
51
  [:new, namespace, page.resource_path],
49
52
  class: "button",
50
- ) if valid_action? :new %>
53
+ ) if valid_action?(:new) && show_action?(:new, new_resource) %>
51
54
  </div>
52
55
  </header>
53
56
 
@@ -15,7 +15,12 @@ to do the heavy lifting.
15
15
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Form
16
16
  %>
17
17
 
18
- <% content_for(:title) { "#{t("administrate.actions.new")} #{page.resource_name.titleize}" } %>
18
+ <% content_for(:title) do %>
19
+ <%= t(
20
+ "administrate.actions.new_resource",
21
+ name: display_resource_name(page.resource_name).titleize
22
+ ) %>
23
+ <% end %>
19
24
 
20
25
  <header class="main-content__header" role="banner">
21
26
  <h1 class="main-content__page-title">
@@ -16,7 +16,7 @@ as well as a link to its edit page.
16
16
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Show
17
17
  %>
18
18
 
19
- <% content_for(:title) { "#{t("administrate.actions.show")} #{page.page_title}" } %>
19
+ <% content_for(:title) { t("administrate.actions.show_resource", name: page.page_title) } %>
20
20
 
21
21
  <header class="main-content__header" role="banner">
22
22
  <h1 class="main-content__page-title">
@@ -25,10 +25,10 @@ as well as a link to its edit page.
25
25
 
26
26
  <div>
27
27
  <%= link_to(
28
- "#{t("administrate.actions.edit")} #{page.page_title}",
28
+ t("administrate.actions.edit_resource", name: page.page_title),
29
29
  [:edit, namespace, page.resource],
30
30
  class: "button",
31
- ) if valid_action? :edit %>
31
+ ) if valid_action?(:edit) && show_action?(:edit, page.resource) %>
32
32
  </div>
33
33
  </header>
34
34
 
@@ -16,4 +16,4 @@ as a count of how many objects are associated through the relationship.
16
16
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/HasMany
17
17
  %>
18
18
 
19
- <%= pluralize(field.data.size, field.attribute.to_s.humanize.downcase) %>
19
+ <%= pluralize(field.data.size, field.attribute.to_s.humanize.downcase.singularize) %>
@@ -5,8 +5,9 @@ ar:
5
5
  confirm: "هل أنت متأكد ؟"
6
6
  destroy: "حذف"
7
7
  edit: "تعديل"
8
- show: "إظهار"
9
- new: "جديد"
8
+ edit_resource: "تعديل %{name}"
9
+ show_resource: "إظهار %{name}"
10
+ new_resource: "جديد %{name}"
10
11
  back: "الى الخلف"
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ ar:
19
20
  has_many:
20
21
  more: إظهار %{count} من %{total_count}
21
22
  none: "لا يوجد"
22
- has_one:
23
- not_supported: "غير مدعمه \"HasOne\" هذه العلاقه"
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: مسح البحث
26
28
  label: بحث %{resource}
@@ -4,8 +4,9 @@ bs:
4
4
  confirm: Jeste li sigurni?
5
5
  destroy: Izbrisati
6
6
  edit: Izmjena
7
- show: Pregled
8
- new: Novi
7
+ edit_resource: Izmjena %{name}
8
+ show_resource: Pregled %{name}
9
+ new_resource: Novi %{name}
9
10
  back: Nazad
10
11
  controller:
11
12
  create:
@@ -18,8 +19,9 @@ bs:
18
19
  has_many:
19
20
  more: Prikazuje %{count} od %{total_count}
20
21
  none: Niko
21
- has_one:
22
- not_supported: Asocijacije HasOne još nije podržana. Žao nam je!
22
+ form:
23
+ error: error
24
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
23
25
  search:
24
26
  clear: Izbriši pretraživanje
25
27
  label: Pretraga %{resource}
@@ -5,8 +5,9 @@ ca:
5
5
  confirm: Estàs segur?
6
6
  destroy: Destruir
7
7
  edit: Editar
8
- show: Mostrar
9
- new: Nou
8
+ edit_resource: Edita %{name}
9
+ show_resource: Mostra %{name}
10
+ new_resource: Nou %{name}
10
11
  back: Tornar
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ ca:
19
20
  has_many:
20
21
  more: Mostrant %{count} de %{total_count}
21
22
  none: Cap
22
- has_one:
23
- not_supported: Els formularis amb relacions "HasOne" no estàn suportats.
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} han impedit que %{resource_name} es guardés amb èxit:"
24
26
  search:
25
27
  clear: Esborrar la cerca
26
28
  label: Cerca %{resource}
@@ -5,8 +5,9 @@ da:
5
5
  confirm: Er du sikker?
6
6
  destroy: Slet
7
7
  edit: Rediger
8
- show: Vis
9
- new: Ny
8
+ edit_resource: Rediger %{name}
9
+ show_resource: Vis %{name}
10
+ new_resource: Ny %{name}
10
11
  back: Tilbage
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ da:
19
20
  has_many:
20
21
  more: "Viser %{count} af %{total_count}"
21
22
  none: Ingen
22
- has_one:
23
- not_supported: "Formularer med has_one associationer er ikke understøttede."
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: Ryd søgning
26
28
  label: Søg %{resource}
@@ -5,8 +5,9 @@ de:
5
5
  confirm: Sind Sie sicher?
6
6
  destroy: Löschen
7
7
  edit: Editieren
8
- show: Anzeigen
9
- new: Neu
8
+ edit_resource: "%{name} editieren"
9
+ show_resource: "%{name} anzeigen"
10
+ new_resource: "%{name} erstellen"
10
11
  back: Zurück
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ de:
19
20
  has_many:
20
21
  more: "%{count} von %{total_count}"
21
22
  none: Keine
22
- has_one:
23
- not_supported: HasOne Beziehungen werden nicht unterstützt.
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} haben das Speichern dieses %{resource_name} verhindert:"
24
26
  search:
25
- clear: Saubere Suche
26
- label: Suche %{resource}
27
+ clear: Suche zurücksetzen
28
+ label: "%{resource} durchsuchen"
@@ -5,8 +5,9 @@ en:
5
5
  confirm: Are you sure?
6
6
  destroy: Destroy
7
7
  edit: Edit
8
- show: Show
9
- new: New
8
+ edit_resource: Edit %{name}
9
+ show_resource: Show %{name}
10
+ new_resource: New %{name}
10
11
  back: Back
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ en:
19
20
  has_many:
20
21
  more: Showing %{count} of %{total_count}
21
22
  none: None
22
- has_one:
23
- not_supported: HasOne relationship forms are not supported.
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: Clear search
26
28
  label: Search %{resource}
@@ -5,8 +5,9 @@ es:
5
5
  confirm: ¿Estás seguro?
6
6
  destroy: Destruir
7
7
  edit: Editar
8
- show: Mostrar
9
- new: Nuevo
8
+ edit_resource: Editar %{name}
9
+ show_resource: Mostrar %{name}
10
+ new_resource: Nuevo %{name}
10
11
  back: Volver
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ es:
19
20
  has_many:
20
21
  more: Mostrando %{count} de %{total_count}
21
22
  none: Ninguno
22
- has_one:
23
- not_supported: Los formularios con relaciones HasOne no están soportados.
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: Borrar búsqueda
26
28
  label: Buscar %{resource}
@@ -5,8 +5,9 @@ fr:
5
5
  confirm: Êtes-vous sûr ?
6
6
  destroy: Supprimer
7
7
  edit: Modifier
8
- show: Détails
9
- new: Création
8
+ edit_resource: Modifier %{name}
9
+ show_resource: Détails %{name}
10
+ new_resource: Création %{name}
10
11
  back: Précédent
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ fr:
19
20
  has_many:
20
21
  more: "%{count} sur %{total_count}"
21
22
  none: Aucun
22
- has_one:
23
- not_supported: Les relations HasOne dans les formulaires ne sont pas supportées.
23
+ form:
24
+ error: erreur
25
+ errors: "%{pluralized_errors} ont empêchés %{resource_name} d'être sauvergardé :"
24
26
  search:
25
27
  clear: Effacer la recherche
26
28
  label: Chercher %{resource}
@@ -5,8 +5,9 @@ it:
5
5
  confirm: Sei sicuro?
6
6
  destroy: Elimina
7
7
  edit: Modifica
8
- show: Visualizza
9
- new: Nuovo
8
+ edit_resource: Modifica %{name}
9
+ show_resource: Visualizza %{name}
10
+ new_resource: Nuovo %{name}
10
11
  back: Indietro
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ it:
19
20
  has_many:
20
21
  more: Visualizzo %{count} di %{total_count}
21
22
  none: Nessuno
22
- has_one:
23
- not_supported: Associazioni HasOne non ancora supportate. Spiacenti!
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: Cancella ricerca
26
28
  label: Ricerca %{resource}
@@ -5,8 +5,9 @@ ja:
5
5
  confirm: 本当によろしいですか?
6
6
  destroy: 削除
7
7
  edit: 編集
8
- show: 参照
9
- new: 新規
8
+ edit_resource: 編集 %{name}
9
+ show_resource: 参照 %{name}
10
+ new_resource: 新規 %{name}
10
11
  back: 戻る
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ ja:
19
20
  has_many:
20
21
  more: "%{total_count} 件中 %{count} 件表示"
21
22
  none: データがありません
22
- has_one:
23
- not_supported: フォームでは「1:1」の関連をサポートしていません。
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: 検索をクリアする
26
28
  label: サーチ %{resource}
@@ -5,8 +5,9 @@ ko:
5
5
  confirm: 괜찮습니까?
6
6
  destroy: 삭제
7
7
  edit: 편집
8
- show: 보여주기
9
- new: 새로운
8
+ edit_resource: 편집 %{name}
9
+ show_resource: 보여주기 %{name}
10
+ new_resource: 새로운 %{name}
10
11
  back: 뒤로
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ ko:
19
20
  has_many:
20
21
  more: "%{total_count} 개 중에서 %{count} 개"
21
22
  none: 없음
22
- has_one:
23
- not_supported: 일대일 관계에 대한 양식은 제공되지 않습니다.
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: 검색 초기화
26
28
  label: "%{resource} 검색"
@@ -5,8 +5,9 @@ nl:
5
5
  confirm: Weet u het zeker?
6
6
  destroy: Verwijder
7
7
  edit: Bewerk
8
- show: Toon
9
- new: Nieuw
8
+ edit_resource: Bewerk %{name}
9
+ show_resource: Toon %{name}
10
+ new_resource: Nieuw %{name}
10
11
  back: Terug
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ nl:
19
20
  has_many:
20
21
  more: Resultaat %{count} van %{total_count}
21
22
  none: Geen
22
- has_one:
23
- not_supported: HasOne relaties formulieren worden niet ondersteund.
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: CDuidelijke zoek
26
28
  label: Zoeken %{resource}
@@ -5,8 +5,9 @@ pl:
5
5
  confirm: Czy jesteś pewien?
6
6
  destroy: Usuń
7
7
  edit: Edytuj
8
- show: Wyświetl
9
- new: Nowy
8
+ edit_resource: Edytuj %{name}
9
+ show_resource: Wyświetl %{name}
10
+ new_resource: Nowy %{name}
10
11
  back: Wstecz
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ pl:
19
20
  has_many:
20
21
  more: Wyświetlanie %{count} z %{total_count}
21
22
  none: Brak
22
- has_one:
23
- not_supported: Relacje jeden-do-jednego nie są obsługiwane.
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: Wyczyść wyszukiwanie
26
28
  label: Szukanie %{resource}
@@ -6,8 +6,9 @@ pt-BR:
6
6
  confirm: Você tem certeza?
7
7
  destroy: Deletar
8
8
  edit: Editar
9
- show: Visualizar
10
- new: Criar
9
+ edit_resource: Editar %{name}
10
+ show_resource: Visualizar %{name}
11
+ new_resource: Criar %{name}
11
12
  back: Voltar
12
13
  controller:
13
14
  create:
@@ -20,8 +21,9 @@ pt-BR:
20
21
  has_many:
21
22
  more: "Exibindo %{count} de %{total_count}"
22
23
  none: Nenhum
23
- has_one:
24
- not_supported: Relações um para muitos nos formulários não são suportadas.
24
+ form:
25
+ error: error
26
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
25
27
  search:
26
28
  clear: Limpar pesquisa
27
29
  label: Pesquisa %{resource}
@@ -6,8 +6,9 @@ pt:
6
6
  confirm: Tem certeza?
7
7
  destroy: Remover
8
8
  edit: Editar
9
- show: Visualizar
10
- new: Novo
9
+ edit_resource: Editar %{name}
10
+ show_resource: Visualizar %{name}
11
+ new_resource: Novo %{name}
11
12
  back: Voltar atrás
12
13
  controller:
13
14
  create:
@@ -20,8 +21,9 @@ pt:
20
21
  has_many:
21
22
  more: "Mostrando %{count} de %{total_count}"
22
23
  none: Nenhum
23
- has_one:
24
- not_supported: Relações um para muitos nos formulários não são suportadas.
24
+ form:
25
+ error: error
26
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
25
27
  search:
26
28
  clear: Limpar pesquisa
27
29
  label: Pesquisa %{resource}
@@ -5,8 +5,9 @@ ru:
5
5
  confirm: Вы уверены?
6
6
  destroy: Удалить
7
7
  edit: Редактировать
8
- show: Показать
9
- new: Новый
8
+ edit_resource: Редактировать %{name}
9
+ show_resource: Показать %{name}
10
+ new_resource: Новый %{name}
10
11
  back: Вернуться назад
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ ru:
19
20
  has_many:
20
21
  more: "%{count} из %{total_count}"
21
22
  none: Нет
22
- has_one:
23
- not_supported: HasOne отношения в формах не поддерживаются.
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: Очистить поиск
26
28
  label: Поиск %{resource}
@@ -5,8 +5,9 @@ sv:
5
5
  confirm: Är du säker?
6
6
  destroy: Ta bort
7
7
  edit: Ändra
8
- show: Visa
9
- new: Ny
8
+ edit_resource: Ändra %{name}
9
+ show_resource: Visa %{name}
10
+ new_resource: Ny %{name}
10
11
  back: Tillbaka
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ sv:
19
20
  has_many:
20
21
  more: "%{count} av %{total_count}"
21
22
  none: Inga
22
- has_one:
23
- not_supported: Formulär med HasOne relationer stöds inte.
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: Rensa sökningen
26
28
  label: Sök %{resource}
@@ -5,8 +5,9 @@ uk:
5
5
  confirm: Ви впевнені?
6
6
  destroy: Видалити
7
7
  edit: Редагувати
8
- show: Показати
9
- new: Новий
8
+ edit_resource: Редагувати %{name}
9
+ show_resource: Показати %{name}
10
+ new_resource: Новий %{name}
10
11
  back: Назад
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ uk:
19
20
  has_many:
20
21
  more: "%{count} із %{total_count}"
21
22
  none: Немає
22
- has_one:
23
- not_supported: HasOne відношення у формах не підтримуються.
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: Очистити пошук
26
28
  label: пошук %{resource}
@@ -5,8 +5,9 @@ vi:
5
5
  confirm: Bạn có chắc không?
6
6
  destroy: Xóa
7
7
  edit: Sửa
8
- show: Xem
9
- new: Mới
8
+ edit_resource: Sửa %{name}
9
+ show_resource: Xem %{name}
10
+ new_resource: Mới %{name}
10
11
  back: Trở lại
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ vi:
19
20
  has_many:
20
21
  more: "%{count} trên %{total_count}"
21
22
  none: Không
22
- has_one:
23
- not_supported: Quan hệ HasOne chưa được hỗ trợ.
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: Tìm kiếm rõ ràng
26
28
  label: Tìm kiếm %{resource}
@@ -5,8 +5,9 @@ zh-CN:
5
5
  confirm: 确定?
6
6
  destroy: 删除
7
7
  edit: 编辑
8
- show: 查看
9
- new: 新建
8
+ edit_resource: 编辑 %{name}
9
+ show_resource: 查看 %{name}
10
+ new_resource: 新建 %{name}
10
11
  back: 返回
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ zh-CN:
19
20
  has_many:
20
21
  more: 显示所有 %{total_count} 中 %{count} 条
21
22
  none: 无
22
- has_one:
23
- not_supported: HasOne 关系暂不支持.
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: 清除搜索
26
28
  label: 搜索 %{resource}
@@ -5,8 +5,9 @@ zh-TW:
5
5
  confirm: 確定?
6
6
  destroy: 刪除
7
7
  edit: 編輯
8
- show: 檢視
9
- new: 新增
8
+ edit_resource: 編輯 %{name}
9
+ show_resource: 檢視 %{name}
10
+ new_resource: 新增 %{name}
10
11
  back: 返回
11
12
  controller:
12
13
  create:
@@ -19,8 +20,9 @@ zh-TW:
19
20
  has_many:
20
21
  more: 顯示 %{total_count} 筆中的 %{count} 筆資料
21
22
  none: 無
22
- has_one:
23
- not_supported: 表單尚未支援 HasOne 關聯。
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
26
  search:
25
27
  clear: 清除搜索
26
28
  label: 搜索 %{resource}
@@ -0,0 +1,69 @@
1
+ # Authorization
2
+
3
+ The default configuration of Administrate is "authenticate-only" - once a
4
+ user is authenticated, that user has access to every action of every object.
5
+
6
+ You can add more fine-grained authorization by overriding methods in the
7
+ controller.
8
+
9
+ ## Using Pundit
10
+
11
+ If your app already uses [Pundit](https://github.com/elabs/pundit) for
12
+ authorization, you just need to add one line to your
13
+ `Admin::ApplicationController`:
14
+
15
+ ```ruby
16
+ include Administrate::Punditize
17
+ ```
18
+
19
+ This will use all the policies from your main app to determine if the
20
+ current user is able to view a given record or perform a given action.
21
+
22
+ ### Further limiting scope
23
+
24
+ You may want to limit the scope for a given user beyond what they
25
+ technically have access to see in the main app. For example, a user may
26
+ have all public records in their scope, but you want to only show *their*
27
+ records in the admin interface to reduce confusion.
28
+
29
+ In this case, you can add an additional `resolve_admin` to your policy's
30
+ scope and Administrate will use this instead of the `resolve` method.
31
+
32
+ For example:
33
+
34
+ ```ruby
35
+ class PostPolicy < ApplicationPolicy
36
+ class Scope < Scope
37
+ def resolve
38
+ scope.all
39
+ end
40
+
41
+ def resolve_admin
42
+ scope.where(owner: user)
43
+ end
44
+ end
45
+ end
46
+ ```
47
+
48
+ ## Authorization without Pundit
49
+
50
+ If you use a different authorization library, or you want to roll your own,
51
+ you just need to override a few methods in your controllers or
52
+ `Admin::ApplicationController`. For example:
53
+
54
+ ```ruby
55
+ # Limit the scope of the given resource
56
+ def scoped_resource
57
+ super.where(user: current_user)
58
+ end
59
+
60
+ # Raise an exception if the user is not permitted to access this resource
61
+ def authorize_resource(resource)
62
+ raise "Erg!" unless show_action?(params[:action], resource)
63
+ end
64
+
65
+ # Hide links to actions if the user is not allowed to do them
66
+ def show_action?(action, resource)
67
+ current_user.can? action, resource
68
+ end
69
+ ```
@@ -72,7 +72,13 @@ which are specified through the `.with_options` class method:
72
72
 
73
73
  **Field::BelongsTo**
74
74
 
75
- `:order` - order of the dropdown menu, can be ordered by more than one column `"name, email DESC"`
75
+ `:order` - Specifies the order of the dropdown menu, can be ordered by more
76
+ than one column. e.g.: `"name, email DESC"`.
77
+
78
+ `:primary_key` - Specifies object's primary_key. Defaults to `:id`.
79
+
80
+ `:foreign_key` - Specifies the name of the foreign key directly.
81
+ Defaults to `:#{attribute}_id`.
76
82
 
77
83
  **Field::HasMany**
78
84
 
@@ -87,12 +93,6 @@ which are specified through the `.with_options` class method:
87
93
 
88
94
  `:foreign_key` - Specifies the name of the foreign key directly. Defaults to `:#{attribute}_id`
89
95
 
90
- **Field::BelongsTo**
91
-
92
- `:primary_key` - Specifies object's primary_key. Defaults to `:id`.
93
-
94
- `:foreign_key` - Specifies the name of the foreign key directly. Defaults to `:#{attribute}_id`
95
-
96
96
  **Field::Number**
97
97
 
98
98
  `:decimals` - Set the number of decimals to display. Defaults to `0`.
@@ -124,6 +124,17 @@ Or, to display a distance in kilometers:
124
124
  `:classes` - Specify a list of classes whose objects will be used to populate select boxes for editing this polymorphic field.
125
125
  Default is `[]`.
126
126
 
127
+ `:order` - What to sort the association by in the form select.
128
+ Default is `nil`.
129
+
130
+ **Field::DateTime**
131
+
132
+ `:format` - Specify what format, using `strftime` you would like `DateTime`
133
+ objects to display as.
134
+
135
+ `:timezone` - Specify which timezone `Date` and `DateTime` objects are based
136
+ in.
137
+
127
138
  **Field::Select**
128
139
 
129
140
  `:collection` - Specify the array or range to select from. Defaults to `[]`.
@@ -73,6 +73,48 @@ namespace :admin do
73
73
  end
74
74
  ```
75
75
 
76
+ ## Keep Dashboards Updated as Model Attributes Change
77
+
78
+ If you've installed Administrate and generated dashboards and _then_
79
+ subsequently added attributes to your models you'll need to manually add
80
+ these additions (or removals) to your dashboards.
81
+
82
+ Example:
83
+
84
+ ```ruby
85
+ # app/dashboards/your_model_dashboard.rb
86
+
87
+ ATTRIBUTE_TYPES = {
88
+ # ...
89
+ the_new_attribute: Field::String,
90
+ # ...
91
+ }.freeze
92
+
93
+ SHOW_PAGE_ATTRIBUTES = [
94
+ # ...
95
+ :the_new_attribute,
96
+ # ...
97
+ ].freeze
98
+
99
+ FORM_ATTRIBUTES = [
100
+ # ...
101
+ :the_new_attribute,
102
+ # ...
103
+ ].freeze
104
+
105
+ COLLECTION_ATTRIBUTES = [
106
+ # ...
107
+ :the_new_attribute, # if you want it on the index, also.
108
+ # ...
109
+ ].freeze
110
+ ```
111
+
112
+ It's recommended that you make this change at the same time as you add the
113
+ attribute to the model.
114
+
115
+ The alternative way to handle this is to re-run `rails g administrate:install` and
116
+ carefully pick through the diffs. This latter method is probably more cumbersome.
117
+
76
118
  ## Rails API
77
119
 
78
120
  Since Rails 5.0, we've been able to have API only applications. Yet, sometimes
@@ -24,7 +24,7 @@ module Administrate
24
24
  @options = options
25
25
  end
26
26
 
27
- def self.permitted_attribute(attr)
27
+ def self.permitted_attribute(attr, _options = nil)
28
28
  attr
29
29
  end
30
30
 
@@ -3,7 +3,7 @@ require_relative "associative"
3
3
  module Administrate
4
4
  module Field
5
5
  class BelongsTo < Associative
6
- def self.permitted_attribute(attr)
6
+ def self.permitted_attribute(attr, _options = nil)
7
7
  :"#{attr}_id"
8
8
  end
9
9
 
@@ -4,11 +4,18 @@ module Administrate
4
4
  module Field
5
5
  class DateTime < Base
6
6
  def date
7
- I18n.localize(data.to_date, format: format)
7
+ I18n.localize(
8
+ data.in_time_zone(timezone).to_date,
9
+ format: format,
10
+ )
8
11
  end
9
12
 
10
13
  def datetime
11
- I18n.localize(data, format: format, default: data)
14
+ I18n.localize(
15
+ data.in_time_zone(timezone),
16
+ format: format,
17
+ default: data,
18
+ )
12
19
  end
13
20
 
14
21
  private
@@ -16,6 +23,10 @@ module Administrate
16
23
  def format
17
24
  options.fetch(:format, :default)
18
25
  end
26
+
27
+ def timezone
28
+ options.fetch(:timezone, "UTC")
29
+ end
19
30
  end
20
31
  end
21
32
  end
@@ -25,8 +25,9 @@ module Administrate
25
25
  options.fetch(:searchable, deferred_class.searchable?)
26
26
  end
27
27
 
28
- def permitted_attribute(attr)
29
- options.fetch(:foreign_key, deferred_class.permitted_attribute(attr))
28
+ def permitted_attribute(attr, _options = nil)
29
+ options.fetch(:foreign_key,
30
+ deferred_class.permitted_attribute(attr, options))
30
31
  end
31
32
 
32
33
  delegate :html_class, to: :deferred_class
@@ -7,8 +7,8 @@ module Administrate
7
7
  class HasMany < Associative
8
8
  DEFAULT_LIMIT = 5
9
9
 
10
- def self.permitted_attribute(attribute)
11
- { "#{attribute.to_s.singularize}_ids".to_sym => [] }
10
+ def self.permitted_attribute(attr, _options = nil)
11
+ { "#{attr.to_s.singularize}_ids".to_sym => [] }
12
12
  end
13
13
 
14
14
  def associated_collection
@@ -3,25 +3,33 @@ require_relative "associative"
3
3
  module Administrate
4
4
  module Field
5
5
  class HasOne < Associative
6
- def initialize(attribute, data, page, options = {})
7
- resolver = Administrate::ResourceResolver.new("admin/#{attribute}")
8
- @nested_form = Administrate::Page::Form.new(
6
+ def nested_form
7
+ @nested_form ||= Administrate::Page::Form.new(
9
8
  resolver.dashboard_class.new,
10
9
  data || resolver.resource_class.new,
11
10
  )
12
-
13
- super
14
11
  end
15
12
 
16
- def self.permitted_attribute(attr)
13
+ def self.permitted_attribute(attr, options = nil)
14
+ associated_class_name =
15
+ if options
16
+ options.fetch(:class_name, attr.to_s.singularize.camelcase)
17
+ else
18
+ attr
19
+ end
17
20
  related_dashboard_attributes =
18
- Administrate::ResourceResolver.new("admin/#{attr}").
21
+ Administrate::ResourceResolver.new("admin/#{associated_class_name}").
19
22
  dashboard_class.new.permitted_attributes + [:id]
20
23
 
21
24
  { "#{attr}_attributes": related_dashboard_attributes }
22
25
  end
23
26
 
24
- attr_reader :nested_form
27
+ private
28
+
29
+ def resolver
30
+ @resolver ||=
31
+ Administrate::ResourceResolver.new("admin/#{associated_class_name}")
32
+ end
25
33
  end
26
34
  end
27
35
  end
@@ -11,7 +11,7 @@ module Administrate
11
11
  end
12
12
  end
13
13
 
14
- def self.permitted_attribute(attr)
14
+ def self.permitted_attribute(attr, _options = nil)
15
15
  { attr => %i{type value} }
16
16
  end
17
17
 
@@ -6,11 +6,13 @@ module Administrate
6
6
  end
7
7
 
8
8
  def apply(relation)
9
- if relation.columns_hash.keys.include?(attribute.to_s)
10
- relation.order("#{attribute} #{direction}")
11
- else
12
- relation
13
- end
9
+ return order_by_association(relation) unless
10
+ reflect_association(relation).nil?
11
+
12
+ return relation.reorder("#{attribute} #{direction}") if
13
+ relation.columns_hash.keys.include?(attribute.to_s)
14
+
15
+ relation
14
16
  end
15
17
 
16
18
  def ordered_by?(attr)
@@ -41,5 +43,36 @@ module Administrate
41
43
  def opposite_direction
42
44
  direction.to_sym == :asc ? :desc : :asc
43
45
  end
46
+
47
+ def order_by_association(relation)
48
+ return order_by_count(relation) if has_many_attribute?(relation)
49
+
50
+ return order_by_id(relation) if belongs_to_attribute?(relation)
51
+
52
+ relation
53
+ end
54
+
55
+ def order_by_count(relation)
56
+ relation.
57
+ left_joins(attribute.to_sym).
58
+ group(:id).
59
+ reorder("COUNT(#{attribute}.id) #{direction}")
60
+ end
61
+
62
+ def order_by_id(relation)
63
+ relation.reorder("#{attribute}_id #{direction}")
64
+ end
65
+
66
+ def has_many_attribute?(relation)
67
+ reflect_association(relation).macro == :has_many
68
+ end
69
+
70
+ def belongs_to_attribute?(relation)
71
+ reflect_association(relation).macro == :belongs_to
72
+ end
73
+
74
+ def reflect_association(relation)
75
+ relation.klass.reflect_on_association(attribute.to_s)
76
+ end
44
77
  end
45
78
  end
@@ -24,7 +24,7 @@ module Administrate
24
24
  table_name = ActiveRecord::Base.connection.
25
25
  quote_table_name(@scoped_resource.table_name)
26
26
  attr_name = ActiveRecord::Base.connection.quote_column_name(attr)
27
- "lower(#{table_name}.#{attr_name}) LIKE ?"
27
+ "LOWER(TEXT(#{table_name}.#{attr_name})) LIKE ?"
28
28
  end.join(" OR ")
29
29
  end
30
30
 
@@ -1,3 +1,3 @@
1
1
  module Administrate
2
- VERSION = "0.1.0".freeze
2
+ VERSION = "0.1.1".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: semantic-administrate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Charlton
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-11-22 00:00:00.000000000 Z
12
+ date: 2018-02-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -224,6 +224,7 @@ files:
224
224
  - app/assets/stylesheets/administrate/vendor/semantic-ui.scss
225
225
  - app/assets/stylesheets/docs.scss
226
226
  - app/controllers/administrate/application_controller.rb
227
+ - app/controllers/concerns/administrate/punditize.rb
227
228
  - app/helpers/administrate/application_helper.rb
228
229
  - app/views/administrate/application/_collection.html.erb
229
230
  - app/views/administrate/application/_flashes.html.erb
@@ -300,6 +301,7 @@ files:
300
301
  - config/unicorn.rb
301
302
  - docs/adding_custom_field_types.md
302
303
  - docs/authentication.md
304
+ - docs/authorization.md
303
305
  - docs/customizing_attribute_partials.md
304
306
  - docs/customizing_controller_actions.md
305
307
  - docs/customizing_dashboards.md