administrate 0.13.0 → 0.17.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 (101) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/administrate/components/associative.js +5 -0
  3. data/app/assets/stylesheets/administrate/base/_tables.scss +3 -0
  4. data/app/assets/stylesheets/administrate/components/_attributes.scss +3 -2
  5. data/app/assets/stylesheets/administrate/components/_buttons.scss +3 -0
  6. data/app/assets/stylesheets/administrate/components/_field-unit.scss +4 -0
  7. data/app/assets/stylesheets/administrate/components/_flashes.scss +0 -8
  8. data/app/assets/stylesheets/administrate/components/_main-content.scss +1 -0
  9. data/app/assets/stylesheets/administrate/library/_variables.scss +10 -8
  10. data/app/controllers/administrate/application_controller.rb +47 -13
  11. data/app/helpers/administrate/application_helper.rb +27 -28
  12. data/app/views/administrate/application/_collection.html.erb +24 -26
  13. data/app/views/administrate/application/_collection_header_actions.html.erb +4 -0
  14. data/app/views/administrate/application/_collection_item_actions.html.erb +17 -0
  15. data/app/views/administrate/application/_flashes.html.erb +1 -0
  16. data/app/views/administrate/application/_form.html.erb +2 -2
  17. data/app/views/administrate/application/_icons.html.erb +1 -1
  18. data/app/views/administrate/application/_index_header.html.erb +28 -0
  19. data/app/views/administrate/application/_navigation.html.erb +4 -4
  20. data/app/views/administrate/application/index.html.erb +9 -29
  21. data/app/views/administrate/application/show.html.erb +1 -1
  22. data/app/views/fields/belongs_to/_form.html.erb +3 -3
  23. data/app/views/fields/belongs_to/_index.html.erb +1 -1
  24. data/app/views/fields/belongs_to/_show.html.erb +1 -1
  25. data/app/views/fields/has_one/_index.html.erb +1 -1
  26. data/app/views/fields/has_one/_show.html.erb +4 -4
  27. data/app/views/fields/number/_form.html.erb +1 -1
  28. data/app/views/fields/polymorphic/_show.html.erb +1 -1
  29. data/app/views/fields/select/_form.html.erb +23 -9
  30. data/app/views/fields/time/_form.html.erb +3 -2
  31. data/app/views/fields/time/_index.html.erb +3 -1
  32. data/app/views/fields/time/_show.html.erb +3 -1
  33. data/app/views/fields/url/_index.html.erb +1 -1
  34. data/app/views/fields/url/_show.html.erb +1 -1
  35. data/app/views/layouts/administrate/application.html.erb +1 -0
  36. data/config/locales/administrate.ar.yml +2 -0
  37. data/config/locales/administrate.bs.yml +2 -0
  38. data/config/locales/administrate.ca.yml +2 -0
  39. data/config/locales/administrate.da.yml +2 -0
  40. data/config/locales/administrate.de.yml +2 -0
  41. data/config/locales/administrate.en.yml +2 -0
  42. data/config/locales/administrate.es.yml +2 -0
  43. data/config/locales/administrate.fi.yml +30 -0
  44. data/config/locales/administrate.fr.yml +4 -2
  45. data/config/locales/administrate.id.yml +2 -0
  46. data/config/locales/administrate.it.yml +2 -0
  47. data/config/locales/administrate.ja.yml +2 -0
  48. data/config/locales/administrate.ko.yml +2 -0
  49. data/config/locales/administrate.nl.yml +7 -5
  50. data/config/locales/administrate.pl.yml +2 -0
  51. data/config/locales/administrate.pt-BR.yml +4 -2
  52. data/config/locales/administrate.pt.yml +4 -2
  53. data/config/locales/administrate.ru.yml +2 -0
  54. data/config/locales/{administrate.al.yml → administrate.sq.yml} +3 -1
  55. data/config/locales/administrate.sv.yml +2 -0
  56. data/config/locales/administrate.tr.yml +30 -0
  57. data/config/locales/administrate.uk.yml +2 -0
  58. data/config/locales/administrate.vi.yml +2 -0
  59. data/config/locales/administrate.zh-CN.yml +2 -0
  60. data/config/locales/administrate.zh-TW.yml +2 -0
  61. data/config/unicorn.rb +8 -13
  62. data/docs/adding_controllers_without_related_model.md +52 -0
  63. data/docs/customizing_controller_actions.md +32 -0
  64. data/docs/customizing_dashboards.md +81 -23
  65. data/docs/customizing_page_views.md +15 -3
  66. data/docs/extending_administrate.md +27 -0
  67. data/docs/getting_started.md +27 -5
  68. data/docs/guides/hiding_dashboards_from_sidebar.md +19 -0
  69. data/docs/guides.md +5 -0
  70. data/lib/administrate/base_dashboard.rb +34 -12
  71. data/lib/administrate/custom_dashboard.rb +15 -0
  72. data/lib/administrate/engine.rb +7 -0
  73. data/lib/administrate/field/associative.rb +49 -5
  74. data/lib/administrate/field/base.rb +30 -0
  75. data/lib/administrate/field/belongs_to.rb +13 -3
  76. data/lib/administrate/field/deferred.rb +22 -3
  77. data/lib/administrate/field/has_many.rb +15 -2
  78. data/lib/administrate/field/has_one.rb +28 -8
  79. data/lib/administrate/field/number.rb +19 -2
  80. data/lib/administrate/field/polymorphic.rb +2 -2
  81. data/lib/administrate/field/select.rb +10 -1
  82. data/lib/administrate/field/time.rb +11 -0
  83. data/lib/administrate/namespace.rb +5 -1
  84. data/lib/administrate/order.rb +3 -1
  85. data/lib/administrate/page/base.rb +1 -1
  86. data/lib/administrate/page/form.rb +10 -3
  87. data/lib/administrate/resource_resolver.rb +2 -2
  88. data/lib/administrate/search.rb +47 -36
  89. data/lib/administrate/version.rb +1 -1
  90. data/lib/administrate/view_generator.rb +7 -1
  91. data/lib/administrate.rb +19 -0
  92. data/lib/generators/administrate/dashboard/dashboard_generator.rb +18 -14
  93. data/lib/generators/administrate/dashboard/templates/controller.rb.erb +2 -2
  94. data/lib/generators/administrate/dashboard/templates/dashboard.rb.erb +3 -3
  95. data/lib/generators/administrate/install/install_generator.rb +37 -1
  96. data/lib/generators/administrate/install/templates/application_controller.rb.erb +1 -1
  97. data/lib/generators/administrate/routes/routes_generator.rb +3 -13
  98. data/lib/generators/administrate/views/views_generator.rb +5 -4
  99. metadata +25 -44
  100. data/app/assets/javascripts/administrate/components/has_many_form.js +0 -3
  101. data/docs/contributing.md +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a347d47197b8258a2233e4bed126e17faf34cedf8b87ca21ad61283c7f5b8dcf
4
- data.tar.gz: 2a63e64339323c68e2daae8df8c48a50c2a85aa25cfded6a14899a275e523573
3
+ metadata.gz: 6a099c28c8a74491759229e6fe82de763f25b9ff59473d5c70b00d38675e3498
4
+ data.tar.gz: c24140b9e1bc63eb9ecd5f38cd0cfd3d3c0f125a81370df1dd6663af66121baa
5
5
  SHA512:
6
- metadata.gz: e8e751c67ebafc99997f82646120be75a79f021e6a78ea207b1a393e38438abd2c9fe00596a9772514d86e9b079984b6dd110eaef6541517dbf369b27acce590
7
- data.tar.gz: ad12aac58cee58d0eb620c0b60627f07bfddaa7853e6c518b0a2cbe4d219c61d64a41b761d7a958bf8b65c4003ecca74b572245ae1db54e2616aafe4420e494c
6
+ metadata.gz: 8ada94532afa210a359eece24f042fdb7de549cdb6bb94507c044f85df7b26cfbd5855202de2016255d635d2448dcba303d91eac4dc41c896f30e52f95073345
7
+ data.tar.gz: 98e115c8c3acfe7dc5cab3a3055b5f06dfa5661f9d2eb135c528b474cbe36e6fb51b36a8c88489860a9fda200758ce37f4d60375705f0e0234af4dc2805e75ff
@@ -0,0 +1,5 @@
1
+ $(function() {
2
+ $('.field-unit--belongs-to select').selectize({});
3
+ $(".field-unit--has-many select").selectize({});
4
+ $('.field-unit--polymorphic select').selectize({});
5
+ });
@@ -21,6 +21,9 @@ tr {
21
21
  tbody tr {
22
22
  &:hover {
23
23
  background-color: $base-background-color;
24
+ }
25
+
26
+ [role=link] {
24
27
  cursor: pointer;
25
28
  }
26
29
 
@@ -5,7 +5,7 @@
5
5
  margin-bottom: $base-spacing;
6
6
  margin-top: 0.25em;
7
7
  text-align: right;
8
- width: calc(15% - 1rem);
8
+ width: calc(20% - 1rem);
9
9
  }
10
10
 
11
11
  .preserve-whitespace {
@@ -17,7 +17,8 @@
17
17
  float: left;
18
18
  margin-bottom: $base-spacing;
19
19
  margin-left: 2rem;
20
- width: calc(85% - 1rem);
20
+ width: calc(80% - 1rem);
21
+ word-break: break-word;
21
22
  }
22
23
 
23
24
  .attribute--nested {
@@ -47,5 +47,8 @@ input[type="submit"],
47
47
  border: $base-border;
48
48
  border-color: $blue;
49
49
  color: $blue;
50
+ }
51
+
52
+ .button--nav {
50
53
  margin-bottom: $base-spacing;
51
54
  }
@@ -19,6 +19,10 @@
19
19
  margin-left: 2rem;
20
20
  max-width: 50rem;
21
21
  width: 100%;
22
+
23
+ .optgroup-header {
24
+ font-weight: $bold-font-weight;
25
+ }
22
26
  }
23
27
 
24
28
  .field-unit--nested {
@@ -1,11 +1,3 @@
1
- $base-spacing: 1.5em !default;
2
- $flashes: (
3
- "alert": #fff6bf,
4
- "error": #fbe3e4,
5
- "notice": #e5edf8,
6
- "success": #e6efc2,
7
- ) !default;
8
-
9
1
  @each $flash-type, $color in $flashes {
10
2
  .flash-#{$flash-type} {
11
3
  background-color: $color;
@@ -5,6 +5,7 @@
5
5
  0 2px 2px rgba($black, 0.2);
6
6
  flex: 1 1 100%;
7
7
  padding-bottom: 10vh;
8
+ min-width: 800px;
8
9
  }
9
10
 
10
11
  .main-content__header,
@@ -22,8 +22,10 @@ $black: #000 !default;
22
22
 
23
23
  $blue: #1976d2 !default;
24
24
  $red: #d32f2f !default;
25
- $light-yellow: #f0cd66 !default;
26
- $light-green: #4ab471 !default;
25
+ $light-yellow: #fff6bf !default;
26
+ $light-red: #fbe3e4 !default;
27
+ $light-green: #e6efc2 !default;
28
+ $light-blue: #e5edf8 !default;
27
29
 
28
30
  $grey-0: #f6f7f7 !default;
29
31
  $grey-1: #dfe0e1 !default;
@@ -47,12 +49,12 @@ $focus-outline: $focus-outline-width solid $focus-outline-color;
47
49
  $focus-outline-offset: 1px;
48
50
 
49
51
  // Flash Colors
50
- $flash-colors: (
51
- alert: $light-yellow,
52
- error: $red,
53
- notice: mix($white, $blue, 50%),
54
- success: $light-green
55
- );
52
+ $flashes: (
53
+ "alert": $light-yellow,
54
+ "error": $light-red,
55
+ "notice": $light-blue,
56
+ "success": $light-green
57
+ ) !default;
56
58
 
57
59
  // Border
58
60
  $base-border-color: $grey-1 !default;
@@ -3,13 +3,14 @@ module Administrate
3
3
  protect_from_forgery with: :exception
4
4
 
5
5
  def index
6
+ authorize_resource(resource_class)
6
7
  search_term = params[:search].to_s.strip
7
8
  resources = Administrate::Search.new(scoped_resource,
8
- dashboard_class,
9
+ dashboard,
9
10
  search_term).run
10
11
  resources = apply_collection_includes(resources)
11
12
  resources = order.apply(resources)
12
- resources = resources.page(params[:page]).per(records_per_page)
13
+ resources = resources.page(params[:_page]).per(records_per_page)
13
14
  page = Administrate::Page::Collection.new(dashboard, order: order)
14
15
 
15
16
  render locals: {
@@ -27,7 +28,7 @@ module Administrate
27
28
  end
28
29
 
29
30
  def new
30
- resource = resource_class.new
31
+ resource = new_resource
31
32
  authorize_resource(resource)
32
33
  render locals: {
33
34
  page: Administrate::Page::Form.new(dashboard, resource),
@@ -46,26 +47,26 @@ module Administrate
46
47
 
47
48
  if resource.save
48
49
  redirect_to(
49
- [namespace, resource],
50
+ after_resource_created_path(resource),
50
51
  notice: translate_with_resource("create.success"),
51
52
  )
52
53
  else
53
54
  render :new, locals: {
54
55
  page: Administrate::Page::Form.new(dashboard, resource),
55
- }
56
+ }, status: :unprocessable_entity
56
57
  end
57
58
  end
58
59
 
59
60
  def update
60
61
  if requested_resource.update(resource_params)
61
62
  redirect_to(
62
- [namespace, requested_resource],
63
+ after_resource_updated_path(requested_resource),
63
64
  notice: translate_with_resource("update.success"),
64
65
  )
65
66
  else
66
67
  render :edit, locals: {
67
68
  page: Administrate::Page::Form.new(dashboard, requested_resource),
68
- }
69
+ }, status: :unprocessable_entity
69
70
  end
70
71
  end
71
72
 
@@ -75,14 +76,27 @@ module Administrate
75
76
  else
76
77
  flash[:error] = requested_resource.errors.full_messages.join("<br/>")
77
78
  end
78
- redirect_to action: :index
79
+ redirect_to after_resource_destroyed_path(requested_resource)
79
80
  end
80
81
 
81
82
  private
82
83
 
84
+ def after_resource_destroyed_path(_requested_resource)
85
+ { action: :index }
86
+ end
87
+
88
+ def after_resource_created_path(requested_resource)
89
+ [namespace, requested_resource]
90
+ end
91
+
92
+ def after_resource_updated_path(requested_resource)
93
+ [namespace, requested_resource]
94
+ end
95
+
83
96
  helper_method :nav_link_state
84
97
  def nav_link_state(resource)
85
- resource_name.to_s.pluralize == resource.to_s ? :active : :inactive
98
+ underscore_resource = resource.to_s.split("/").join("__")
99
+ resource_name.to_s.pluralize == underscore_resource ? :active : :inactive
86
100
  end
87
101
 
88
102
  helper_method :valid_action?
@@ -101,10 +115,27 @@ module Administrate
101
115
  end
102
116
 
103
117
  def order
104
- @order ||= Administrate::Order.new(
105
- params.fetch(resource_name, {}).fetch(:order, nil),
106
- params.fetch(resource_name, {}).fetch(:direction, nil),
107
- )
118
+ @order ||= Administrate::Order.new(sorting_attribute, sorting_direction)
119
+ end
120
+
121
+ def sorting_attribute
122
+ sorting_params.fetch(:order) { default_sorting_attribute }
123
+ end
124
+
125
+ def default_sorting_attribute
126
+ nil
127
+ end
128
+
129
+ def sorting_direction
130
+ sorting_params.fetch(:direction) { default_sorting_direction }
131
+ end
132
+
133
+ def default_sorting_direction
134
+ nil
135
+ end
136
+
137
+ def sorting_params
138
+ Hash.try_convert(request.query_parameters[resource_name]) || {}
108
139
  end
109
140
 
110
141
  def dashboard
@@ -144,6 +175,8 @@ module Administrate
144
175
  else
145
176
  raise "Unrecognised param data: #{data.inspect}"
146
177
  end
178
+ elsif data.is_a?(ActionController::Parameters)
179
+ data.transform_values { |v| read_param_value(v) }
147
180
  else
148
181
  data
149
182
  end
@@ -153,6 +186,7 @@ module Administrate
153
186
  to: :resource_resolver
154
187
  helper_method :namespace
155
188
  helper_method :resource_name
189
+ helper_method :resource_class
156
190
 
157
191
  def resource_resolver
158
192
  @resource_resolver ||=
@@ -1,6 +1,7 @@
1
1
  module Administrate
2
2
  module ApplicationHelper
3
3
  PLURAL_MANY_COUNT = 2.1
4
+ SINGULAR_COUNT = 1
4
5
 
5
6
  def application_title
6
7
  if Rails::VERSION::MAJOR <= 5
@@ -11,40 +12,28 @@ module Administrate
11
12
  end
12
13
 
13
14
  def render_field(field, locals = {})
14
- locals.merge!(field: field)
15
+ locals[:field] = field
15
16
  render locals: locals, partial: field.to_partial_path
16
17
  end
17
18
 
18
19
  def requireness(field)
19
- required_field?(field) ? "required" : "optional"
20
+ field.required? ? "required" : "optional"
20
21
  end
21
22
 
22
- def required_field?(field)
23
- has_presence_validator?(field.resource.class, field.attribute)
23
+ def dashboard_from_resource(resource_name)
24
+ "#{resource_name.to_s.singularize}_dashboard".classify.constantize
24
25
  end
25
26
 
26
- def has_presence_validator?(resource_class, field_name)
27
- validators_on(resource_class, field_name).
28
- any? { |v| v.class == ActiveRecord::Validations::PresenceValidator }
27
+ def model_from_resource(resource_name)
28
+ dashboard = dashboard_from_resource(resource_name)
29
+ dashboard.try(:model) || resource_name.to_sym
29
30
  end
30
31
 
31
- def validators_on(resource_class, field_name)
32
- return [] unless resource_class.respond_to?(:validators_on)
33
-
34
- resource_class.validators_on(field_name)
35
- end
36
-
37
- def class_from_resource(resource_name)
38
- resource_name.to_s.classify.constantize
39
- end
40
-
41
- def display_resource_name(resource_name)
42
- class_from_resource(resource_name).
43
- model_name.
44
- human(
45
- count: PLURAL_MANY_COUNT,
46
- default: resource_name.to_s.pluralize.titleize,
47
- )
32
+ def display_resource_name(resource_name, opts = {})
33
+ dashboard_from_resource(resource_name).resource_name(
34
+ count: opts[:singular] ? SINGULAR_COUNT : PLURAL_MANY_COUNT,
35
+ default: default_resource_name(resource_name, opts),
36
+ )
48
37
  end
49
38
 
50
39
  def sort_order(order)
@@ -55,8 +44,11 @@ module Administrate
55
44
  end
56
45
  end
57
46
 
58
- def resource_index_route_key(resource_name)
59
- ActiveModel::Naming.route_key(class_from_resource(resource_name))
47
+ def resource_index_route(resource_name)
48
+ url_for(
49
+ action: "index",
50
+ controller: "/#{namespace}/#{resource_name}",
51
+ )
60
52
  end
61
53
 
62
54
  def sanitized_order_params(page, current_field_name)
@@ -64,13 +56,20 @@ module Administrate
64
56
  association_params = collection_names.map do |assoc_name|
65
57
  { assoc_name => %i[order direction page per_page] }
66
58
  end
67
- params.permit(:search, :id, :page, :per_page, association_params)
59
+ params.permit(:search, :id, :_page, :per_page, association_params)
68
60
  end
69
61
 
70
62
  def clear_search_params
71
- params.except(:search, :page).permit(
63
+ params.except(:search, :_page).permit(
72
64
  :per_page, resource_name => %i[order direction]
73
65
  )
74
66
  end
67
+
68
+ private
69
+
70
+ def default_resource_name(name, opts = {})
71
+ resource_name = (opts[:singular] ? name.to_s : name.to_s.pluralize)
72
+ resource_name.gsub("/", "_").titleize
73
+ end
75
74
  end
76
75
  end
@@ -24,7 +24,8 @@ to display a collection of resources in an HTML table.
24
24
  <% collection_presenter.attribute_types.each do |attr_name, attr_type| %>
25
25
  <th class="cell-label
26
26
  cell-label--<%= attr_type.html_class %>
27
- cell-label--<%= collection_presenter.ordered_html_class(attr_name) %>"
27
+ cell-label--<%= collection_presenter.ordered_html_class(attr_name) %>
28
+ cell-label--<%= "#{resource_name}_#{attr_name}" %>"
28
29
  scope="col"
29
30
  role="columnheader"
30
31
  aria-sort="<%= sort_order(collection_presenter.ordered_html_class(attr_name)) %>">
@@ -33,7 +34,7 @@ to display a collection of resources in an HTML table.
33
34
  )) do %>
34
35
  <%= t(
35
36
  "helpers.label.#{collection_presenter.resource_name}.#{attr_name}",
36
- default: attr_name.to_s,
37
+ default: resource_class.human_attribute_name(attr_name),
37
38
  ).titleize %>
38
39
  <% if collection_presenter.ordered_by?(attr_name) %>
39
40
  <span class="cell-label__sort-indicator cell-label__sort-indicator--<%= collection_presenter.ordered_html_class(attr_name) %>">
@@ -45,50 +46,47 @@ to display a collection of resources in an HTML table.
45
46
  <% end %>
46
47
  </th>
47
48
  <% end %>
48
- <% [valid_action?(:edit, collection_presenter.resource_name),
49
- valid_action?(:destroy, collection_presenter.resource_name)].count(true).times do %>
50
- <th scope="col"></th>
51
- <% end %>
49
+ <%= render(
50
+ "collection_header_actions",
51
+ collection_presenter: collection_presenter,
52
+ page: page,
53
+ resources: resources,
54
+ table_title: "page-title"
55
+ ) %>
52
56
  </tr>
53
57
  </thead>
54
58
 
55
59
  <tbody>
56
60
  <% resources.each do |resource| %>
57
61
  <tr class="js-table-row"
58
- tabindex="0"
59
- <% if valid_action? :show, collection_presenter.resource_name %>
60
- <%= %(role=link data-url=#{polymorphic_path([namespace, resource])}) %>
62
+ <% if show_action? :show, resource %>
63
+ <%= %(tabindex=0 role=link data-url=#{polymorphic_path([namespace, resource])}) %>
61
64
  <% end %>
62
65
  >
63
66
  <% collection_presenter.attributes_for(resource).each do |attribute| %>
64
67
  <td class="cell-data cell-data--<%= attribute.html_class %>">
65
68
  <% if show_action? :show, resource -%>
66
69
  <a href="<%= polymorphic_path([namespace, resource]) -%>"
70
+ tabindex="-1"
67
71
  class="action-show"
68
72
  >
69
73
  <%= render_field attribute %>
70
74
  </a>
75
+ <% else %>
76
+ <%= render_field attribute %>
71
77
  <% end -%>
72
78
  </td>
73
79
  <% end %>
74
80
 
75
- <% if valid_action? :edit, collection_presenter.resource_name %>
76
- <td><%= link_to(
77
- t("administrate.actions.edit"),
78
- [:edit, namespace, resource],
79
- class: "action-edit",
80
- ) if show_action? :edit, resource%></td>
81
- <% end %>
82
-
83
- <% if valid_action? :destroy, collection_presenter.resource_name %>
84
- <td><%= link_to(
85
- t("administrate.actions.destroy"),
86
- [namespace, resource],
87
- class: "text-color-red",
88
- method: :delete,
89
- data: { confirm: t("administrate.actions.confirm") }
90
- ) if show_action? :destroy, resource %></td>
91
- <% end %>
81
+ <%= render(
82
+ "collection_item_actions",
83
+ collection_presenter: collection_presenter,
84
+ collection_field_name: collection_field_name,
85
+ page: page,
86
+ namespace: namespace,
87
+ resource: resource,
88
+ table_title: "page-title"
89
+ ) %>
92
90
  </tr>
93
91
  <% end %>
94
92
  </tbody>
@@ -0,0 +1,4 @@
1
+ <% [valid_action?(:edit, collection_presenter.resource_name),
2
+ valid_action?(:destroy, collection_presenter.resource_name)].count(true).times do %>
3
+ <th scope="col"></th>
4
+ <% end %>
@@ -0,0 +1,17 @@
1
+ <% if valid_action?(:edit, collection_presenter.resource_name) %>
2
+ <td><%= link_to(
3
+ t("administrate.actions.edit"),
4
+ [:edit, namespace, resource],
5
+ class: "action-edit",
6
+ ) if show_action?(:edit, resource) %></td>
7
+ <% end %>
8
+
9
+ <% if valid_action?(:destroy, collection_presenter.resource_name) %>
10
+ <td><%= link_to(
11
+ t("administrate.actions.destroy"),
12
+ [namespace, resource],
13
+ class: "text-color-red",
14
+ method: :delete,
15
+ data: { confirm: t("administrate.actions.confirm") }
16
+ ) if show_action?(:destroy, resource) %></td>
17
+ <% end %>
@@ -14,6 +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
+ <% next unless value.respond_to?(:html_safe) %>
17
18
  <div class="flash flash-<%= key %>"><%= value.html_safe %></div>
18
19
  <% end -%>
19
20
  </div>
@@ -21,7 +21,7 @@ and renders all form fields for a resource's editable attributes.
21
21
  <%= t(
22
22
  "administrate.form.errors",
23
23
  pluralized_errors: pluralize(page.resource.errors.count, t("administrate.form.error")),
24
- resource_name: display_resource_name(page.resource_name)
24
+ resource_name: display_resource_name(page.resource_name, singular: true)
25
25
  ) %>
26
26
  </h2>
27
27
 
@@ -33,7 +33,7 @@ and renders all form fields for a resource's editable attributes.
33
33
  </div>
34
34
  <% end %>
35
35
 
36
- <% page.attributes.each do |attribute| -%>
36
+ <% page.attributes(controller.action_name).each do |attribute| -%>
37
37
  <div class="field-unit field-unit--<%= attribute.html_class %> field-unit--<%= requireness(attribute) %>">
38
38
  <%= render_field attribute, f: f %>
39
39
  </div>
@@ -1,4 +1,4 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
1
+ <svg hidden xmlns="http://www.w3.org/2000/svg">
2
2
  <symbol id="icon-cancel" viewBox="0 0 48 48">
3
3
  <path fill-rule="evenodd" d="M24 19.757l-8.485-8.485c-.784-.783-2.047-.782-2.827 0l-1.417 1.416c-.777.777-.78 2.046.002 2.827L19.757 24l-8.485 8.485c-.783.784-.782 2.047 0 2.827l1.416 1.417c.777.777 2.046.78 2.827-.002L24 28.243l8.485 8.485c.784.783 2.047.782 2.827 0l1.417-1.416c.777-.777.78-2.046-.002-2.827L28.243 24l8.485-8.485c.783-.784.782-2.047 0-2.827l-1.416-1.417c-.777-.777-2.046-.78-2.827.002L24 19.757zM24 47c12.703 0 23-10.297 23-23S36.703 1 24 1 1 11.297 1 24s10.297 23 23 23z" />
4
4
  </symbol>
@@ -0,0 +1,28 @@
1
+ <% content_for(:title) do %>
2
+ <%= display_resource_name(page.resource_name) %>
3
+ <% end %>
4
+
5
+ <header class="main-content__header" role="banner">
6
+ <h1 class="main-content__page-title" id="page-title">
7
+ <%= content_for(:title) %>
8
+ </h1>
9
+
10
+ <% if show_search_bar %>
11
+ <%= render(
12
+ "search",
13
+ search_term: search_term,
14
+ resource_name: display_resource_name(page.resource_name)
15
+ ) %>
16
+ <% end %>
17
+
18
+ <div>
19
+ <%= link_to(
20
+ t(
21
+ "administrate.actions.new_resource",
22
+ name: display_resource_name(page.resource_name, singular: true).downcase
23
+ ),
24
+ [:new, namespace, page.resource_path.to_sym],
25
+ class: "button",
26
+ ) if valid_action?(:new) && show_action?(:new, new_resource) %>
27
+ </div>
28
+ </header>
@@ -8,13 +8,13 @@ as defined by the routes in the `admin/` namespace
8
8
  %>
9
9
 
10
10
  <nav class="navigation" role="navigation">
11
- <%= link_to "Back to app", root_url, class: "button button--alt" %>
11
+ <%= link_to(t("administrate.navigation.back_to_app"), root_url, class: "button button--alt button--nav") if defined?(root_url) %>
12
12
 
13
- <% Administrate::Namespace.new(namespace).resources.each do |resource| %>
13
+ <% Administrate::Namespace.new(namespace).resources_with_index_route.each do |resource| %>
14
14
  <%= link_to(
15
15
  display_resource_name(resource),
16
- [namespace, resource_index_route_key(resource)],
16
+ resource_index_route(resource),
17
17
  class: "navigation__link navigation__link--#{nav_link_state(resource)}"
18
- ) if valid_action? :index, resource %>
18
+ ) if valid_action?(:index, resource) && show_action?(:index, model_from_resource(resource)) %>
19
19
  <% end %>
20
20
  </nav>
@@ -23,34 +23,14 @@ It renders the `_table` partial to display details about the resources.
23
23
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection
24
24
  %>
25
25
 
26
- <% content_for(:title) do %>
27
- <%= display_resource_name(page.resource_name) %>
28
- <% end %>
29
-
30
- <header class="main-content__header" role="banner">
31
- <h1 class="main-content__page-title" id="page-title">
32
- <%= content_for(:title) %>
33
- </h1>
34
-
35
- <% if show_search_bar %>
36
- <%= render(
37
- "search",
38
- search_term: search_term,
39
- resource_name: display_resource_name(page.resource_name)
40
- ) %>
41
- <% end %>
42
-
43
- <div>
44
- <%= link_to(
45
- t(
46
- "administrate.actions.new_resource",
47
- name: page.resource_name.titleize.downcase
48
- ),
49
- [:new, namespace, page.resource_path],
50
- class: "button",
51
- ) if valid_action?(:new) && show_action?(:new, new_resource) %>
52
- </div>
53
- </header>
26
+ <%=
27
+ render("index_header",
28
+ resources: resources,
29
+ search_term: search_term,
30
+ page: page,
31
+ show_search_bar: show_search_bar,
32
+ )
33
+ %>
54
34
 
55
35
  <section class="main-content__body main-content__body--flush">
56
36
  <%= render(
@@ -62,5 +42,5 @@ It renders the `_table` partial to display details about the resources.
62
42
  table_title: "page-title"
63
43
  ) %>
64
44
 
65
- <%= paginate resources %>
45
+ <%= paginate resources, param_name: '_page' %>
66
46
  </section>
@@ -38,7 +38,7 @@ as well as a link to its edit page.
38
38
  <dt class="attribute-label" id="<%= attribute.name %>">
39
39
  <%= t(
40
40
  "helpers.label.#{resource_name}.#{attribute.name}",
41
- default: attribute.name.titleize,
41
+ default: page.resource.class.human_attribute_name(attribute.name),
42
42
  ) %>
43
43
  </dt>
44
44
 
@@ -20,7 +20,7 @@ that displays all possible records to associate with.
20
20
  <%= f.label field.permitted_attribute %>
21
21
  </div>
22
22
  <div class="field-unit__field">
23
- <%= f.select(field.permitted_attribute) do %>
24
- <%= options_for_select(field.associated_resource_options, field.selected_option) %>
25
- <% end %>
23
+ <%= f.select(field.permitted_attribute,
24
+ options_for_select(field.associated_resource_options, field.selected_option),
25
+ include_blank: field.include_blank_option) %>
26
26
  </div>
@@ -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.associated_class) %>
19
+ <% if valid_action?(:show, field.associated_class) && show_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.associated_class) %>
19
+ <% if valid_action?(:show, field.associated_class) && show_action?(:show, field.associated_class) %>
20
20
  <%= link_to(
21
21
  field.display_associated_resource,
22
22
  [namespace, field.data],
@@ -15,7 +15,7 @@ By default, the relationship is rendered as a link to the associated object.
15
15
  [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/HasOne
16
16
  %>
17
17
 
18
- <% if field.data %>
18
+ <% if field.linkable? %>
19
19
  <%= link_to(
20
20
  field.display_associated_resource,
21
21
  [namespace, field.data],