semantic-administrate 0.1.0 → 0.1.1

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