semantic-administrate 0.1.1 → 0.10.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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/administrate/components/date_time_picker.js +5 -1
  3. data/app/controllers/administrate/application_controller.rb +20 -12
  4. data/app/helpers/administrate/application_helper.rb +9 -3
  5. data/app/views/administrate/application/_collection.html.erb +2 -3
  6. data/app/views/administrate/application/_flashes.html.erb +1 -1
  7. data/app/views/administrate/application/index.html.erb +2 -0
  8. data/app/views/administrate/application/show.html.erb +1 -1
  9. data/app/views/fields/belongs_to/_index.html.erb +1 -1
  10. data/app/views/fields/belongs_to/_show.html.erb +1 -1
  11. data/app/views/fields/date_time/_form.html.erb +1 -1
  12. data/app/views/fields/date_time/_index.html.erb +1 -1
  13. data/app/views/fields/has_many/_form.html.erb +2 -2
  14. data/app/views/fields/has_many/_show.html.erb +8 -5
  15. data/app/views/fields/has_one/_form.html.erb +1 -1
  16. data/app/views/fields/password/_form.html.erb +23 -0
  17. data/app/views/fields/password/_index.html.erb +18 -0
  18. data/app/views/fields/password/_show.html.erb +18 -0
  19. data/app/views/fields/polymorphic/_form.html.erb +0 -3
  20. data/app/views/fields/time/_form.html.erb +22 -0
  21. data/app/views/fields/time/_index.html.erb +17 -0
  22. data/app/views/fields/time/_show.html.erb +17 -0
  23. data/config/locales/administrate.al.yml +28 -0
  24. data/config/locales/administrate.id.yml +28 -0
  25. data/config/locales/administrate.ja.yml +2 -2
  26. data/config/locales/administrate.ru.yml +2 -2
  27. data/config/locales/administrate.zh-TW.yml +4 -4
  28. data/docs/customizing_dashboards.md +71 -5
  29. data/docs/customizing_page_views.md +5 -1
  30. data/lib/administrate/base_dashboard.rb +7 -1
  31. data/lib/administrate/field/associative.rb +4 -4
  32. data/lib/administrate/field/belongs_to.rb +3 -1
  33. data/lib/administrate/field/date_time.rb +1 -1
  34. data/lib/administrate/field/deferred.rb +4 -0
  35. data/lib/administrate/field/has_many.rb +15 -8
  36. data/lib/administrate/field/password.rb +25 -0
  37. data/lib/administrate/field/polymorphic.rb +1 -1
  38. data/lib/administrate/field/time.rb +8 -0
  39. data/lib/administrate/namespace.rb +1 -1
  40. data/lib/administrate/order.rb +3 -1
  41. data/lib/administrate/page/base.rb +4 -0
  42. data/lib/administrate/page/collection.rb +5 -1
  43. data/lib/administrate/search.rb +39 -5
  44. data/lib/administrate/version.rb +1 -1
  45. data/lib/generators/administrate/dashboard/dashboard_generator.rb +1 -1
  46. metadata +18 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2123d47601bf83f82794fe639a592c0be68130e8
4
- data.tar.gz: 4f57f44bea647c725247c42fb9f18e21825ff7bc
3
+ metadata.gz: b0ef87476dd9f2165cc5bb4bc0fc2fbf48f21600
4
+ data.tar.gz: 882284666a8830d2483fd92dbb9a2e1d31571dd7
5
5
  SHA512:
6
- metadata.gz: c52c71169aed4dad7ea08c9f1873bdefa22e0b14a9dd6940cac3aa56f42dd29472744c9ec82f23bc7c2d908d44ed7e95b262900a331384c2b38200d12c144c64
7
- data.tar.gz: be36d780bdd94b43d132468d6498f68e40dcff40e3d8642744c8f77886083559fa0f05f570cbe4a19a0b008b3796e3e7e880f6bedba1d8d0040036f28ffe7028
6
+ metadata.gz: f2007d097c22eaf8609641345735db8bac5b2ca475efe7fbe5aa862e7410d3ccf0f9c9ad5babf12e1eadf0397ad9868f98a219ef1ba84e7778316e5f049a8868
7
+ data.tar.gz: 3c915b462dac24879e61935eedc02bd0672f3d1db3d54c0e04b42b6a83a006d7541a3f5319ed26cc34f6f50d436abbd4cfb87fc6f230665f6999e639e0874a48
@@ -1,5 +1,9 @@
1
1
  $(function () {
2
- $(".datetimepicker").datetimepicker({
2
+ $('[data-type="time"]').datetimepicker({
3
+ debug: false,
4
+ format: "HH:mm:ss",
5
+ });
6
+ $('[data-type="datetime"]').datetimepicker({
3
7
  debug: false,
4
8
  format: "YYYY-MM-DD HH:mm:ss",
5
9
  });
@@ -7,7 +7,7 @@ module Administrate
7
7
  resources = Administrate::Search.new(scoped_resource,
8
8
  dashboard_class,
9
9
  search_term).run
10
- resources = resources.includes(*resource_includes) if resource_includes.any?
10
+ resources = apply_resource_includes(resources)
11
11
  resources = order.apply(resources)
12
12
  resources = resources.page(params[:page]).per(records_per_page)
13
13
  page = Administrate::Page::Collection.new(dashboard, order: order)
@@ -16,7 +16,7 @@ module Administrate
16
16
  resources: resources,
17
17
  search_term: search_term,
18
18
  page: page,
19
- show_search_bar: show_search_bar?
19
+ show_search_bar: show_search_bar?,
20
20
  }
21
21
  end
22
22
 
@@ -70,8 +70,11 @@ module Administrate
70
70
  end
71
71
 
72
72
  def destroy
73
- requested_resource.destroy
74
- flash[:notice] = translate_with_resource("destroy.success")
73
+ if requested_resource.destroy
74
+ flash[:notice] = translate_with_resource("destroy.success")
75
+ else
76
+ flash[:error] = requested_resource.errors.full_messages.join("<br/>")
77
+ end
75
78
  redirect_to action: :index
76
79
  end
77
80
 
@@ -98,15 +101,18 @@ module Administrate
98
101
  end
99
102
 
100
103
  def order
101
- @_order ||= Administrate::Order.new(params[:order], params[:direction])
104
+ @order ||= Administrate::Order.new(
105
+ params.fetch(resource_name, {}).fetch(:order, nil),
106
+ params.fetch(resource_name, {}).fetch(:direction, nil),
107
+ )
102
108
  end
103
109
 
104
110
  def dashboard
105
- @_dashboard ||= dashboard_class.new
111
+ @dashboard ||= dashboard_class.new
106
112
  end
107
113
 
108
114
  def requested_resource
109
- @_requested_resource ||= find_resource(params[:id]).tap do |resource|
115
+ @requested_resource ||= find_resource(params[:id]).tap do |resource|
110
116
  authorize_resource(resource)
111
117
  end
112
118
  end
@@ -119,8 +125,10 @@ module Administrate
119
125
  resource_class.default_scoped
120
126
  end
121
127
 
122
- def resource_includes
123
- dashboard.association_includes
128
+ def apply_resource_includes(relation)
129
+ resource_includes = dashboard.association_includes
130
+ return relation if resource_includes.empty?
131
+ relation.includes(*resource_includes)
124
132
  end
125
133
 
126
134
  def resource_params
@@ -147,7 +155,7 @@ module Administrate
147
155
  helper_method :resource_name
148
156
 
149
157
  def resource_resolver
150
- @_resource_resolver ||=
158
+ @resource_resolver ||=
151
159
  Administrate::ResourceResolver.new(controller_path)
152
160
  end
153
161
 
@@ -160,11 +168,11 @@ module Administrate
160
168
 
161
169
  def show_search_bar?
162
170
  dashboard.attribute_types_for(
163
- dashboard.collection_attributes
171
+ dashboard.all_attributes,
164
172
  ).any? { |_name, attribute| attribute.searchable? }
165
173
  end
166
174
 
167
- def show_action?(action, resource)
175
+ def show_action?(_action, _resource)
168
176
  true
169
177
  end
170
178
  helper_method :show_action?
@@ -40,12 +40,18 @@ module Administrate
40
40
  ActiveModel::Naming.route_key(class_from_resource(resource_name))
41
41
  end
42
42
 
43
- def sanitized_order_params
44
- params.permit(:search, :id, :order, :page, :per_page, :direction, :orders)
43
+ def sanitized_order_params(page, current_field_name)
44
+ collection_names = page.association_includes + [current_field_name]
45
+ association_params = collection_names.map do |assoc_name|
46
+ { assoc_name => %i[order direction page per_page] }
47
+ end
48
+ params.permit(:search, :id, :page, :per_page, association_params)
45
49
  end
46
50
 
47
51
  def clear_search_params
48
- params.except(:search, :page).permit(:order, :direction, :per_page)
52
+ params.except(:search, :page).permit(
53
+ :per_page, resource_name => %i[order direction]
54
+ )
49
55
  end
50
56
  end
51
57
  end
@@ -28,14 +28,13 @@ to display a collection of resources in an HTML table.
28
28
  scope="col"
29
29
  role="columnheader"
30
30
  aria-sort="<%= sort_order(collection_presenter.ordered_html_class(attr_name)) %>">
31
- <%= link_to(sanitized_order_params.merge(
32
- collection_presenter.order_params_for(attr_name)
31
+ <%= link_to(sanitized_order_params(page, collection_field_name).merge(
32
+ collection_presenter.order_params_for(attr_name, key: collection_field_name)
33
33
  )) do %>
34
34
  <%= t(
35
35
  "helpers.label.#{collection_presenter.resource_name}.#{attr_name}",
36
36
  default: attr_name.to_s,
37
37
  ).titleize %>
38
-
39
38
  <% if collection_presenter.ordered_by?(attr_name) %>
40
39
  <span class="cell-label__sort-indicator cell-label__sort-indicator--<%= collection_presenter.ordered_html_class(attr_name) %>">
41
40
  <svg aria-hidden="true">
@@ -14,7 +14,7 @@ This partial renders flash messages on every page.
14
14
  <% if flash.any? %>
15
15
  <div class="flashes">
16
16
  <% flash.each do |key, value| -%>
17
- <div class="flash flash-<%= key %>"><%= value %></div>
17
+ <div class="flash flash-<%= key %>"><%= value.html_safe %></div>
18
18
  <% end -%>
19
19
  </div>
20
20
  <% end %>
@@ -58,6 +58,8 @@ It renders the `_table` partial to display details about the resources.
58
58
  <%= render(
59
59
  "collection",
60
60
  collection_presenter: page,
61
+ collection_field_name: resource_name,
62
+ page: page,
61
63
  resources: resources,
62
64
  table_title: "page-title"
63
65
  ) %>
@@ -43,7 +43,7 @@ as well as a link to its edit page.
43
43
  </dt>
44
44
 
45
45
  <dd class="attribute-data attribute-data--<%=attribute.html_class%>"
46
- ><%= render_field attribute %></dd>
46
+ ><%= render_field attribute, page: page %></dd>
47
47
  <% end %>
48
48
  </dl>
49
49
  </section>
@@ -16,7 +16,7 @@ By default, the relationship is rendered as a link to the associated object.
16
16
  %>
17
17
 
18
18
  <% if field.data %>
19
- <% if valid_action?(:show, field.attribute) %>
19
+ <% if valid_action?(:show, field.associated_class) %>
20
20
  <%= link_to(
21
21
  field.display_associated_resource,
22
22
  [namespace, field.data],
@@ -16,7 +16,7 @@ By default, the relationship is rendered as a link to the associated object.
16
16
  %>
17
17
 
18
18
  <% if field.data %>
19
- <% if valid_action?(:show, field.attribute) %>
19
+ <% if valid_action?(:show, field.associated_class) %>
20
20
  <%= link_to(
21
21
  field.display_associated_resource,
22
22
  [namespace, field.data],
@@ -20,5 +20,5 @@ By default, the input is a text field that is augmented with [DateTimePicker].
20
20
  <%= f.label field.attribute %>
21
21
  </div>
22
22
  <div class="field-unit__field">
23
- <%= f.text_field field.attribute, class: "datetimepicker" %>
23
+ <%= f.text_field field.attribute, data: { type: 'datetime' } %>
24
24
  </div>
@@ -17,5 +17,5 @@ as a localized date & time string.
17
17
  %>
18
18
 
19
19
  <% if field.data %>
20
- <%= field.date %>
20
+ <%= field.datetime %>
21
21
  <% end %>
@@ -1,7 +1,7 @@
1
1
  <%#
2
2
  # HasMany Form Partial
3
3
 
4
- This partial renders an input element for belongs_to relationships.
4
+ This partial renders an input element for has_many relationships.
5
5
  By default, the input is a collection select box
6
6
  that displays all possible records to associate with.
7
7
  The collection select box supports multiple inputs,
@@ -20,7 +20,7 @@ and is augmented with [Selectize].
20
20
  %>
21
21
 
22
22
  <div class="field-unit__label">
23
- <%= f.label field.attribute_key, field.attribute %>
23
+ <%= f.label field.attribute, for: "#{f.object_name}_#{field.attribute_key}" %>
24
24
  </div>
25
25
  <div class="field-unit__field">
26
26
  <%= f.select(field.attribute_key, nil, {}, multiple: true) do %>
@@ -19,15 +19,18 @@ from the associated resource class's dashboard.
19
19
  %>
20
20
 
21
21
  <% if field.resources.any? %>
22
+ <% order = field.order_from_params(params.fetch(field.name, {})) %>
23
+ <% page_number = params.fetch(field.name, {}).fetch(:page, nil) %>
22
24
  <%= render(
23
25
  "collection",
24
- collection_presenter: field.associated_collection,
25
- resources: field.resources(params[field.name]),
26
- table_title: field.name
26
+ collection_presenter: field.associated_collection(order),
27
+ collection_field_name: field.name,
28
+ page: page,
29
+ resources: field.resources(page_number, order),
30
+ table_title: field.name,
27
31
  ) %>
28
-
29
32
  <% if field.more_than_limit? %>
30
- <%= paginate field.resources(params[field.name]), param_name: "#{field.name}" %>
33
+ <%= paginate field.resources(page_number), param_name: "#{field.name}[page]" %>
31
34
  <% end %>
32
35
 
33
36
  <% else %>
@@ -18,7 +18,7 @@ The form will be rendered as nested_from to parent relationship.
18
18
 
19
19
  <%= f.fields_for field.attribute, field.data || field.nested_form.resource.class.new do |has_one_f| %>
20
20
  <fieldset class="field-unit--nested">
21
- <legend><%= field.nested_form.resource_name.titleize %></legend>
21
+ <legend><%= t "helpers.label.#{f.object_name}.#{field.nested_form.resource_name}", default: field.nested_form.resource_name.titleize %></legend>
22
22
  <% field.nested_form.attributes.each do |attribute| -%>
23
23
  <div class="field-unit field-unit--<%= attribute.html_class %>">
24
24
  <%= render_field attribute, f: has_one_f %>
@@ -0,0 +1,23 @@
1
+ <%#
2
+ # Password Form Partial
3
+
4
+ This partial renders an input element for a password attribute.
5
+ By default, the input is a password field.
6
+
7
+ ## Local variables:
8
+
9
+ - `f`:
10
+ A Rails form generator, used to help create the appropriate input fields.
11
+ - `field`:
12
+ An instance of [Administrate::Field::Password][1].
13
+ A wrapper around the Password.
14
+
15
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/Password
16
+ %>
17
+
18
+ <div class="field-unit__label">
19
+ <%= f.label field.attribute %>
20
+ </div>
21
+ <div class="field-unit__field">
22
+ <%= f.password_field field.attribute, value: field.data %>
23
+ </div>
@@ -0,0 +1,18 @@
1
+ <%#
2
+ # Password Index Partial
3
+
4
+ This partial renders a password attribute
5
+ to be displayed on a resource's index page.
6
+
7
+ By default, the attribute is rendered as a truncated string.
8
+
9
+ ## Local variables:
10
+
11
+ - `field`:
12
+ An instance of [Administrate::Field::Password][1].
13
+ A wrapper around the Password.
14
+
15
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/Password
16
+ %>
17
+
18
+ <%= field.truncate %>
@@ -0,0 +1,18 @@
1
+ <%#
2
+ # Password Show Partial
3
+
4
+ This partial renders a password attribute,
5
+ to be displayed on a resource's show page.
6
+
7
+ By default, the attribute is rendered as an truncate string.
8
+
9
+ ## Local variables:
10
+
11
+ - `field`:
12
+ An instance of [Administrate::Field::Password][1].
13
+ A wrapper around the Password.
14
+
15
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/Password
16
+ %>
17
+
18
+ <%= field.truncate %>
@@ -3,9 +3,6 @@
3
3
 
4
4
  This partial renders an input element for polymorphic relationships.
5
5
 
6
- At the moment, polymorphic form fields are not supported,
7
- so this partial renders a message to that effect.
8
-
9
6
  ## Local variables:
10
7
 
11
8
  - `f`:
@@ -0,0 +1,22 @@
1
+ <%#
2
+ # Time Form Partial
3
+
4
+ This partial renders an input element for time attributes.
5
+ By default, the input is a select field for the time attributes.
6
+
7
+ ## Local variables:
8
+
9
+ - `f`:
10
+ A Rails form generator, used to help create the appropriate input fields.
11
+ - `field`:
12
+ An instance of [Administrate::Field::Time][1].
13
+ A wrapper around the tmie attributes pulled from the model.
14
+
15
+ %>
16
+
17
+ <div class="field-unit__label">
18
+ <%= f.label field.attribute %>
19
+ </div>
20
+ <div class="field-unit__field">
21
+ <%= f.text_field field.attribute, data: { type: 'time' } %>
22
+ </div>
@@ -0,0 +1,17 @@
1
+ <%#
2
+ # Time Index Partial
3
+
4
+ This partial renders an time attribute
5
+ to be displayed on a resource's index page.
6
+
7
+ By default, the attribute is rendered as a text tag.
8
+
9
+ ## Local variables:
10
+
11
+ - `field`:
12
+ An instance of [Administrate::Field::Time][1].
13
+ A wrapper around the time attributes pulled from the model.
14
+
15
+ %>
16
+
17
+ <%= field.data.strftime("%I:%M%p").to_s %>
@@ -0,0 +1,17 @@
1
+ <%#
2
+ # Time Show Partial
3
+
4
+ This partial renders an time attribute,
5
+ to be displayed on a resource's show page.
6
+
7
+ By default, the attribute is rendered as a text tag.
8
+
9
+ ## Local variables:
10
+
11
+ - `field`:
12
+ An instance of [Administrate::Field::Time][1].
13
+ A wrapper around the time attributes pulled from the model.
14
+
15
+ %>
16
+
17
+ <%= field.data.strftime("%I:%M%p").to_s %>
@@ -0,0 +1,28 @@
1
+ ---
2
+ al:
3
+ administrate:
4
+ actions:
5
+ confirm: A jeni te sigurtë?
6
+ destroy: Fshij
7
+ edit: Ndrysho
8
+ edit_resource: Ndrysho %{name}
9
+ show_resource: Trego %{name}
10
+ new_resource: Të re %{name}
11
+ back: Prapa
12
+ controller:
13
+ create:
14
+ success: "%{resource} është krijuar me sukses."
15
+ destroy:
16
+ success: "%{resource} është fshirë me sukses."
17
+ update:
18
+ success: "%{resource} është azhurnuar me sukses."
19
+ fields:
20
+ has_many:
21
+ more: Duke treguar %{count} nga %{total_count}
22
+ none: Asnjë
23
+ form:
24
+ error: gabim
25
+ errors: "%{pluralized_errors} nuk e lejoj %{resource_name} të ruhet:"
26
+ search:
27
+ clear: Pastro kërkimin
28
+ label: Kërko %{resource}
@@ -0,0 +1,28 @@
1
+ ---
2
+ id:
3
+ administrate:
4
+ actions:
5
+ confirm: Anda yakin?
6
+ destroy: Hapus
7
+ edit: Perbarui
8
+ edit_resource: Perbarui %{name}
9
+ show_resource: Tampilkan %{name}
10
+ new_resource: "%{name} baru"
11
+ back: Kembali
12
+ controller:
13
+ create:
14
+ success: "%{resource} telah berhasil dibuat."
15
+ destroy:
16
+ success: "%{resource} telah berhasil dihapus."
17
+ update:
18
+ success: "%{resource} telah berhasil diperbarui."
19
+ fields:
20
+ has_many:
21
+ more: Menampilkan %{count} dari %{total_count}
22
+ none: Kosong
23
+ form:
24
+ error: error
25
+ errors: "%{pluralized_errors} membuat %{resource_name} tidak bisa tersimpan:"
26
+ search:
27
+ clear: Kosongkan pencarian
28
+ label: Cari %{resource}
@@ -21,8 +21,8 @@ ja:
21
21
  more: "%{total_count} 件中 %{count} 件表示"
22
22
  none: データがありません
23
23
  form:
24
- error: error
25
- errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
+ error: エラー
25
+ errors: "%{pluralized_errors}のため%{resource_name}を保存できません。"
26
26
  search:
27
27
  clear: 検索をクリアする
28
28
  label: サーチ %{resource}
@@ -21,8 +21,8 @@ ru:
21
21
  more: "%{count} из %{total_count}"
22
22
  none: Нет
23
23
  form:
24
- error: error
25
- errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
+ error: Ошибка
25
+ errors: "При сохранении %{resource_name} произошли ошибки:"
26
26
  search:
27
27
  clear: Очистить поиск
28
28
  label: Поиск %{resource}
@@ -21,8 +21,8 @@ zh-TW:
21
21
  more: 顯示 %{total_count} 筆中的 %{count} 筆資料
22
22
  none: 無
23
23
  form:
24
- error: error
25
- errors: "%{pluralized_errors} prohibited this %{resource_name} from being saved:"
24
+ error: 錯誤
25
+ errors: "%{pluralized_errors} 導致此 %{resource_name} 不能被儲存:"
26
26
  search:
27
- clear: 清除搜索
28
- label: 搜索 %{resource}
27
+ clear: 清除搜尋
28
+ label: 搜尋 %{resource}
@@ -10,7 +10,7 @@ require "administrate/dashboard/base"
10
10
 
11
11
  class CustomerDashboard < Administrate::Dashboard::Base
12
12
  ATTRIBUTE_TYPES = {
13
- id: Field::Integer,
13
+ id: Field::Number,
14
14
  name: Field::String,
15
15
  email: Field::String,
16
16
  created_at: Field::DateTime,
@@ -62,6 +62,7 @@ specify, including:
62
62
  - `Field::Select`
63
63
  - `Field::String`
64
64
  - `Field::Text`
65
+ - `Field::Password`
65
66
 
66
67
  ## Customizing Fields
67
68
 
@@ -80,6 +81,30 @@ than one column. e.g.: `"name, email DESC"`.
80
81
  `:foreign_key` - Specifies the name of the foreign key directly.
81
82
  Defaults to `:#{attribute}_id`.
82
83
 
84
+ `:scope` - Specifies a custom scope inside a callable. Useful for preloading.
85
+ Example: `.with_options(scope: -> { MyModel.includes(:rel).limit(5) })`
86
+
87
+ `:class_name` - Specifies the name of the associated class.
88
+ Defaults to `:#{attribute}.to_s.singularize.camelcase`.
89
+
90
+ `:searchable` - Specify if the attribute should be considered when searching.
91
+ Default is `false`.
92
+
93
+ `searchable_field` - Specify which column to use on the search, only applies
94
+ if `searchable` is `true`
95
+
96
+ For example:
97
+
98
+ ```ruby
99
+ country: Field::BelongsTo.with_options(
100
+ searchable: true,
101
+ seachable_field: 'name',
102
+ )
103
+ ```
104
+
105
+ with this, you will be able to search through the column `name` from the
106
+ association `belongs_to :country`, from your model.
107
+
83
108
  **Field::HasMany**
84
109
 
85
110
  `:limit` - Set the number of resources to display in the show view. Default is
@@ -93,8 +118,38 @@ Defaults to `:#{attribute}_id`.
93
118
 
94
119
  `:foreign_key` - Specifies the name of the foreign key directly. Defaults to `:#{attribute}_id`
95
120
 
121
+ `:class_name` - Specifies the name of the associated class.
122
+ Defaults to `:#{attribute}.to_s.singularize.camelcase`.
123
+
124
+ **Field::HasOne**
125
+
126
+ `:class_name` - Specifies the name of the associated class.
127
+ Defaults to `:#{attribute}.to_s.singularize.camelcase`.
128
+
129
+ `:searchable` - Specify if the attribute should be considered when searching.
130
+ Default is `false`.
131
+
132
+ `searchable_field` - Specify which column to use on the search, only applies if
133
+ `searchable` is `true`
134
+
135
+ For example:
136
+
137
+ ```ruby
138
+ cities: Field::HasMany.with_options(
139
+ searchable: true,
140
+ searchable_field: 'name',
141
+ )
142
+ ```
143
+
144
+ with this, you will be able to search through the column `name` from the
145
+ association `has_many :cities`, from your model.
146
+
96
147
  **Field::Number**
97
148
 
149
+ `:searchable` - Specify if the attribute should be considered when searching.
150
+ Note that currently number fields are searched like text, which may yield
151
+ more results than expected. Default is `false`.
152
+
98
153
  `:decimals` - Set the number of decimals to display. Defaults to `0`.
99
154
 
100
155
  `:prefix` - Prefixes the number with a string. Defaults to `""`.
@@ -137,7 +192,7 @@ in.
137
192
 
138
193
  **Field::Select**
139
194
 
140
- `:collection` - Specify the array or range to select from. Defaults to `[]`.
195
+ `:collection` - Specify the array or range to select from. Defaults to `[]`.
141
196
 
142
197
  `:searchable` - Specify if the attribute should be considered when searching.
143
198
  Default is `true`.
@@ -158,6 +213,17 @@ Default is `false`.
158
213
  `:truncate` - Set the number of characters to display in the index view.
159
214
  Defaults to `50`.
160
215
 
216
+ **Field::Password**
217
+
218
+ `:searchable` - Specify if the attribute should be considered when searching.
219
+ Default is `false`.
220
+
221
+ `:truncate` - Set the number of characters to display in the views.
222
+ Defaults to `50`.
223
+
224
+ `:character` - Set the replace character.
225
+ Defaults to `•`.
226
+
161
227
  ### Defining Labels
162
228
 
163
229
  To change the user-facing label for an attribute,
@@ -180,11 +246,11 @@ Add this method to the dashboard for Users.
180
246
  Use whatever attribute or method you like.
181
247
  Example for *user*:
182
248
 
183
- ````ruby
249
+ ```ruby
184
250
  def display_resource(user)
185
251
  user.name
186
252
  end
187
- ````
253
+ ```
188
254
 
189
255
  [define your own]: /adding_custom_field_types
190
256
 
@@ -196,7 +262,7 @@ en:
196
262
  models:
197
263
  customer:
198
264
  one: Happy Customer
199
- others: Happy Customers
265
+ other: Happy Customers
200
266
  ```
201
267
 
202
268
  ## Customizing Actions
@@ -67,7 +67,7 @@ and will leave the show pages for other resources unchanged.
67
67
  ## Customizing layouts
68
68
 
69
69
  Many developers need to customize the layouts of their admin dashboard.
70
- It's so easy that pass in the "layout" key word to the view generators.
70
+ It's as easy as passing in the "layout" keyword to the view generators.
71
71
 
72
72
  ```bash
73
73
  rails generate administrate:views:layout
@@ -75,4 +75,8 @@ rails generate administrate:views:layout
75
75
  # -> app/views/admin/application/_navigation.html.erb
76
76
  # -> app/views/admin/application/_javascript.html.erb
77
77
  # -> app/views/admin/application/_flashes.html.erb
78
+
79
+ rails generate administrate:views:navigation
80
+ # It only generates the sidebar partial
81
+ # -> app/views/admin/application/_navigation.html.erb
78
82
  ```
@@ -9,6 +9,8 @@ require "administrate/field/polymorphic"
9
9
  require "administrate/field/select"
10
10
  require "administrate/field/string"
11
11
  require "administrate/field/text"
12
+ require "administrate/field/time"
13
+ require "administrate/field/password"
12
14
 
13
15
  module Administrate
14
16
  class BaseDashboard
@@ -30,6 +32,10 @@ module Administrate
30
32
  end
31
33
  end
32
34
 
35
+ def all_attributes
36
+ attribute_types.keys
37
+ end
38
+
33
39
  def form_attributes
34
40
  self.class::FORM_ATTRIBUTES
35
41
  end
@@ -59,7 +65,7 @@ module Administrate
59
65
  field = self.class::ATTRIBUTE_TYPES[key]
60
66
 
61
67
  next key if association_classes.include?(field)
62
- key if association_classes.include?(field.try :deferred_class)
68
+ key if association_classes.include?(field.try(:deferred_class))
63
69
  end.compact
64
70
  end
65
71
 
@@ -7,16 +7,16 @@ module Administrate
7
7
  associated_dashboard.display_resource(data)
8
8
  end
9
9
 
10
+ def associated_class
11
+ associated_class_name.constantize
12
+ end
13
+
10
14
  protected
11
15
 
12
16
  def associated_dashboard
13
17
  "#{associated_class_name}Dashboard".constantize.new
14
18
  end
15
19
 
16
- def associated_class
17
- associated_class_name.constantize
18
- end
19
-
20
20
  def associated_class_name
21
21
  options.fetch(:class_name, attribute.to_s.singularize.camelcase)
22
22
  end
@@ -24,8 +24,10 @@ module Administrate
24
24
  private
25
25
 
26
26
  def candidate_resources
27
+ scope = options[:scope] ? options[:scope].call : associated_class.all
28
+
27
29
  order = options.delete(:order)
28
- order ? associated_class.order(order) : associated_class.all
30
+ order ? scope.reorder(order) : scope
29
31
  end
30
32
 
31
33
  def display_candidate_resource(resource)
@@ -25,7 +25,7 @@ module Administrate
25
25
  end
26
26
 
27
27
  def timezone
28
- options.fetch(:timezone, "UTC")
28
+ options.fetch(:timezone, ::Time.zone.name || "UTC")
29
29
  end
30
30
  end
31
31
  end
@@ -25,6 +25,10 @@ module Administrate
25
25
  options.fetch(:searchable, deferred_class.searchable?)
26
26
  end
27
27
 
28
+ def searchable_field
29
+ options.fetch(:searchable_field)
30
+ end
31
+
28
32
  def permitted_attribute(attr, _options = nil)
29
33
  options.fetch(:foreign_key,
30
34
  deferred_class.permitted_attribute(attr, options))
@@ -11,8 +11,8 @@ module Administrate
11
11
  { "#{attr.to_s.singularize}_ids".to_sym => [] }
12
12
  end
13
13
 
14
- def associated_collection
15
- Administrate::Page::Collection.new(associated_dashboard)
14
+ def associated_collection(order = self.order)
15
+ Administrate::Page::Collection.new(associated_dashboard, order: order)
16
16
  end
17
17
 
18
18
  def attribute_key
@@ -39,7 +39,7 @@ module Administrate
39
39
  self.class.permitted_attribute(attribute)
40
40
  end
41
41
 
42
- def resources(page = 1)
42
+ def resources(page = 1, order = self.order)
43
43
  resources = order.apply(data).page(page).per(limit)
44
44
  includes.any? ? resources.includes(*includes) : resources
45
45
  end
@@ -49,7 +49,18 @@ module Administrate
49
49
  end
50
50
 
51
51
  def data
52
- @data ||= associated_class.none
52
+ @data ||= associated_class.none
53
+ end
54
+
55
+ def order_from_params(params)
56
+ Administrate::Order.new(
57
+ params.fetch(:order, sort_by),
58
+ params.fetch(:direction, direction),
59
+ )
60
+ end
61
+
62
+ def order
63
+ @order ||= Administrate::Order.new(sort_by, direction)
53
64
  end
54
65
 
55
66
  private
@@ -71,10 +82,6 @@ module Administrate
71
82
  associated_dashboard.display_resource(resource)
72
83
  end
73
84
 
74
- def order
75
- @_order ||= Administrate::Order.new(sort_by, direction)
76
- end
77
-
78
85
  def sort_by
79
86
  options[:sort_by]
80
87
  end
@@ -0,0 +1,25 @@
1
+ require_relative "base"
2
+
3
+ module Administrate
4
+ module Field
5
+ class Password < Field::Base
6
+ def self.searchable?
7
+ false
8
+ end
9
+
10
+ def truncate
11
+ data.to_s.gsub(/./, character)[0...truncation_length]
12
+ end
13
+
14
+ private
15
+
16
+ def truncation_length
17
+ options.fetch(:truncate, 50)
18
+ end
19
+
20
+ def character
21
+ options.fetch(:character, "•")
22
+ end
23
+ end
24
+ end
25
+ end
@@ -30,7 +30,7 @@ module Administrate
30
30
  end
31
31
 
32
32
  def classes
33
- options.fetch(:classes) || []
33
+ options.fetch(:classes, [])
34
34
  end
35
35
 
36
36
  private
@@ -0,0 +1,8 @@
1
+ require_relative "base"
2
+
3
+ module Administrate
4
+ module Field
5
+ class Time < Base
6
+ end
7
+ end
8
+ end
@@ -12,7 +12,7 @@ module Administrate
12
12
 
13
13
  def routes
14
14
  @routes ||= all_routes.select do |controller, _action|
15
- controller.starts_with?(namespace.to_s)
15
+ controller.starts_with?("#{namespace}/")
16
16
  end.map do |controller, action|
17
17
  [controller.gsub(/^#{namespace}\//, ""), action]
18
18
  end
@@ -9,7 +9,9 @@ module Administrate
9
9
  return order_by_association(relation) unless
10
10
  reflect_association(relation).nil?
11
11
 
12
- return relation.reorder("#{attribute} #{direction}") if
12
+ order = "#{relation.table_name}.#{attribute} #{direction}"
13
+
14
+ return relation.reorder(order) if
13
15
  relation.columns_hash.keys.include?(attribute.to_s)
14
16
 
15
17
  relation
@@ -15,6 +15,10 @@ module Administrate
15
15
  @resource_path ||= resource_name.gsub("/", "_")
16
16
  end
17
17
 
18
+ def association_includes
19
+ dashboard.try(:association_includes) || []
20
+ end
21
+
18
22
  protected
19
23
 
20
24
  def attribute_field(dashboard, resource, attribute_name, page)
@@ -21,7 +21,11 @@ module Administrate
21
21
  ordered_by?(attr) && order.direction
22
22
  end
23
23
 
24
- delegate :ordered_by?, :order_params_for, to: :order
24
+ delegate :ordered_by?, to: :order
25
+
26
+ def order_params_for(attr, key: resource_name)
27
+ { key => order.order_params_for(attr) }
28
+ end
25
29
 
26
30
  private
27
31
 
@@ -13,7 +13,7 @@ module Administrate
13
13
  if @term.blank?
14
14
  @scoped_resource.all
15
15
  else
16
- @scoped_resource.where(query, *search_terms)
16
+ @scoped_resource.joins(tables_to_join).where(query, *search_terms)
17
17
  end
18
18
  end
19
19
 
@@ -21,10 +21,10 @@ module Administrate
21
21
 
22
22
  def query
23
23
  search_attributes.map do |attr|
24
- table_name = ActiveRecord::Base.connection.
25
- quote_table_name(@scoped_resource.table_name)
26
- attr_name = ActiveRecord::Base.connection.quote_column_name(attr)
27
- "LOWER(TEXT(#{table_name}.#{attr_name})) LIKE ?"
24
+ table_name = query_table_name(attr)
25
+ attr_name = column_to_query(attr)
26
+
27
+ "LOWER(CAST(#{table_name}.#{attr_name} AS CHAR(256))) LIKE ?"
28
28
  end.join(" OR ")
29
29
  end
30
30
 
@@ -42,6 +42,40 @@ module Administrate
42
42
  @dashboard_class::ATTRIBUTE_TYPES
43
43
  end
44
44
 
45
+ def query_table_name(attr)
46
+ if association_search?(attr)
47
+ ActiveRecord::Base.connection.quote_table_name(attr.to_s.pluralize)
48
+ else
49
+ ActiveRecord::Base.connection.
50
+ quote_table_name(@scoped_resource.table_name)
51
+ end
52
+ end
53
+
54
+ def column_to_query(attr)
55
+ if association_search?(attr)
56
+ ActiveRecord::Base.connection.
57
+ quote_column_name(attribute_types[attr].searchable_field)
58
+ else
59
+ ActiveRecord::Base.connection.quote_column_name(attr)
60
+ end
61
+ end
62
+
63
+ def tables_to_join
64
+ attribute_types.keys.select do |attribute|
65
+ attribute_types[attribute].searchable? && association_search?(attribute)
66
+ end
67
+ end
68
+
69
+ def association_search?(attribute)
70
+ return unless attribute_types[attribute].respond_to?(:deferred_class)
71
+
72
+ [
73
+ Administrate::Field::BelongsTo,
74
+ Administrate::Field::HasMany,
75
+ Administrate::Field::HasOne,
76
+ ].include?(attribute_types[attribute].deferred_class)
77
+ end
78
+
45
79
  attr_reader :resolver, :term
46
80
  end
47
81
  end
@@ -1,3 +1,3 @@
1
1
  module Administrate
2
- VERSION = "0.1.1".freeze
2
+ VERSION = "0.10.0".freeze
3
3
  end
@@ -10,7 +10,7 @@ module Administrate
10
10
  enum: "Field::String",
11
11
  float: "Field::Number",
12
12
  integer: "Field::Number",
13
- time: "Field::DateTime",
13
+ time: "Field::Time",
14
14
  text: "Field::Text",
15
15
  string: "Field::String",
16
16
  }
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.1
4
+ version: 0.10.0
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: 2018-02-27 00:00:00.000000000 Z
12
+ date: 2018-08-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -20,7 +20,7 @@ dependencies:
20
20
  version: '4.2'
21
21
  - - "<"
22
22
  - !ruby/object:Gem::Version
23
- version: '5.2'
23
+ version: '6.0'
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
@@ -30,7 +30,7 @@ dependencies:
30
30
  version: '4.2'
31
31
  - - "<"
32
32
  - !ruby/object:Gem::Version
33
- version: '5.2'
33
+ version: '6.0'
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: actionview
36
36
  requirement: !ruby/object:Gem::Requirement
@@ -40,7 +40,7 @@ dependencies:
40
40
  version: '4.2'
41
41
  - - "<"
42
42
  - !ruby/object:Gem::Version
43
- version: '5.2'
43
+ version: '6.0'
44
44
  type: :runtime
45
45
  prerelease: false
46
46
  version_requirements: !ruby/object:Gem::Requirement
@@ -50,7 +50,7 @@ dependencies:
50
50
  version: '4.2'
51
51
  - - "<"
52
52
  - !ruby/object:Gem::Version
53
- version: '5.2'
53
+ version: '6.0'
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: activerecord
56
56
  requirement: !ruby/object:Gem::Requirement
@@ -60,7 +60,7 @@ dependencies:
60
60
  version: '4.2'
61
61
  - - "<"
62
62
  - !ruby/object:Gem::Version
63
- version: '5.2'
63
+ version: '6.0'
64
64
  type: :runtime
65
65
  prerelease: false
66
66
  version_requirements: !ruby/object:Gem::Requirement
@@ -70,7 +70,7 @@ dependencies:
70
70
  version: '4.2'
71
71
  - - "<"
72
72
  - !ruby/object:Gem::Version
73
- version: '5.2'
73
+ version: '6.0'
74
74
  - !ruby/object:Gem::Dependency
75
75
  name: autoprefixer-rails
76
76
  requirement: !ruby/object:Gem::Requirement
@@ -262,6 +262,9 @@ files:
262
262
  - app/views/fields/number/_form.html.erb
263
263
  - app/views/fields/number/_index.html.erb
264
264
  - app/views/fields/number/_show.html.erb
265
+ - app/views/fields/password/_form.html.erb
266
+ - app/views/fields/password/_index.html.erb
267
+ - app/views/fields/password/_show.html.erb
265
268
  - app/views/fields/polymorphic/_form.html.erb
266
269
  - app/views/fields/polymorphic/_index.html.erb
267
270
  - app/views/fields/polymorphic/_show.html.erb
@@ -274,8 +277,12 @@ files:
274
277
  - app/views/fields/text/_form.html.erb
275
278
  - app/views/fields/text/_index.html.erb
276
279
  - app/views/fields/text/_show.html.erb
280
+ - app/views/fields/time/_form.html.erb
281
+ - app/views/fields/time/_index.html.erb
282
+ - app/views/fields/time/_show.html.erb
277
283
  - app/views/layouts/administrate/application.html.erb
278
284
  - config/i18n-tasks.yml
285
+ - config/locales/administrate.al.yml
279
286
  - config/locales/administrate.ar.yml
280
287
  - config/locales/administrate.bs.yml
281
288
  - config/locales/administrate.ca.yml
@@ -284,6 +291,7 @@ files:
284
291
  - config/locales/administrate.en.yml
285
292
  - config/locales/administrate.es.yml
286
293
  - config/locales/administrate.fr.yml
294
+ - config/locales/administrate.id.yml
287
295
  - config/locales/administrate.it.yml
288
296
  - config/locales/administrate.ja.yml
289
297
  - config/locales/administrate.ko.yml
@@ -320,10 +328,12 @@ files:
320
328
  - lib/administrate/field/has_many.rb
321
329
  - lib/administrate/field/has_one.rb
322
330
  - lib/administrate/field/number.rb
331
+ - lib/administrate/field/password.rb
323
332
  - lib/administrate/field/polymorphic.rb
324
333
  - lib/administrate/field/select.rb
325
334
  - lib/administrate/field/string.rb
326
335
  - lib/administrate/field/text.rb
336
+ - lib/administrate/field/time.rb
327
337
  - lib/administrate/generator_helpers.rb
328
338
  - lib/administrate/namespace.rb
329
339
  - lib/administrate/namespace/resource.rb