administrate 0.8.1 → 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 (140) hide show
  1. checksums.yaml +5 -5
  2. data/app/assets/javascripts/administrate/components/associative.js +5 -0
  3. data/app/assets/javascripts/administrate/components/date_time_picker.js +10 -2
  4. data/app/assets/javascripts/administrate/components/table.js +1 -1
  5. data/app/assets/stylesheets/administrate/base/_tables.scss +3 -0
  6. data/app/assets/stylesheets/administrate/base/_typography.scss +1 -1
  7. data/app/assets/stylesheets/administrate/components/_attributes.scss +4 -3
  8. data/app/assets/stylesheets/administrate/components/_buttons.scss +11 -0
  9. data/app/assets/stylesheets/administrate/components/_cells.scss +3 -5
  10. data/app/assets/stylesheets/administrate/components/_field-unit.scss +17 -4
  11. data/app/assets/stylesheets/administrate/components/_flashes.scss +0 -8
  12. data/app/assets/stylesheets/administrate/components/_main-content.scss +1 -0
  13. data/app/assets/stylesheets/administrate/components/_navigation.scss +2 -3
  14. data/app/assets/stylesheets/administrate/library/_variables.scss +10 -8
  15. data/app/assets/stylesheets/docs.scss +1 -0
  16. data/app/controllers/administrate/application_controller.rb +95 -21
  17. data/app/controllers/concerns/administrate/punditize.rb +36 -0
  18. data/app/helpers/administrate/application_helper.rb +51 -14
  19. data/app/views/administrate/application/_collection.html.erb +32 -33
  20. data/app/views/administrate/application/_collection_header_actions.html.erb +4 -0
  21. data/app/views/administrate/application/_collection_item_actions.html.erb +17 -0
  22. data/app/views/administrate/application/_flashes.html.erb +2 -1
  23. data/app/views/administrate/application/_form.html.erb +7 -4
  24. data/app/views/administrate/application/{_icons.erb → _icons.html.erb} +1 -1
  25. data/app/views/administrate/application/_index_header.html.erb +28 -0
  26. data/app/views/administrate/application/_navigation.html.erb +5 -3
  27. data/app/views/administrate/application/edit.html.erb +3 -3
  28. data/app/views/administrate/application/index.html.erb +11 -26
  29. data/app/views/administrate/application/new.html.erb +6 -1
  30. data/app/views/administrate/application/show.html.erb +5 -5
  31. data/app/views/fields/belongs_to/_form.html.erb +3 -3
  32. data/app/views/fields/belongs_to/_index.html.erb +1 -1
  33. data/app/views/fields/belongs_to/_show.html.erb +1 -1
  34. data/app/views/fields/date/_form.html.erb +24 -0
  35. data/app/views/fields/date/_index.html.erb +21 -0
  36. data/app/views/fields/date/_show.html.erb +21 -0
  37. data/app/views/fields/date_time/_form.html.erb +1 -1
  38. data/app/views/fields/date_time/_index.html.erb +1 -1
  39. data/app/views/fields/has_many/_form.html.erb +2 -2
  40. data/app/views/fields/has_many/_index.html.erb +1 -1
  41. data/app/views/fields/has_many/_show.html.erb +8 -5
  42. data/app/views/fields/has_one/_form.html.erb +1 -1
  43. data/app/views/fields/has_one/_index.html.erb +1 -1
  44. data/app/views/fields/has_one/_show.html.erb +4 -4
  45. data/app/views/fields/number/_form.html.erb +1 -1
  46. data/app/views/fields/password/_form.html.erb +23 -0
  47. data/app/views/fields/password/_index.html.erb +18 -0
  48. data/app/views/fields/password/_show.html.erb +18 -0
  49. data/app/views/fields/polymorphic/_form.html.erb +11 -9
  50. data/app/views/fields/polymorphic/_show.html.erb +8 -4
  51. data/app/views/fields/select/_form.html.erb +24 -10
  52. data/app/views/fields/string/_show.html.erb +2 -2
  53. data/app/views/fields/text/_show.html.erb +2 -3
  54. data/app/views/fields/time/_form.html.erb +23 -0
  55. data/app/views/fields/time/_index.html.erb +19 -0
  56. data/app/views/fields/time/_show.html.erb +19 -0
  57. data/app/views/fields/url/_form.html.erb +23 -0
  58. data/app/views/fields/url/_index.html.erb +20 -0
  59. data/app/views/fields/url/_show.html.erb +20 -0
  60. data/app/views/layouts/administrate/application.html.erb +2 -1
  61. data/config/locales/administrate.ar.yml +8 -6
  62. data/config/locales/administrate.bs.yml +29 -0
  63. data/config/locales/administrate.ca.yml +30 -0
  64. data/config/locales/administrate.da.yml +8 -6
  65. data/config/locales/administrate.de.yml +10 -8
  66. data/config/locales/administrate.en.yml +8 -6
  67. data/config/locales/administrate.es.yml +8 -6
  68. data/config/locales/administrate.fi.yml +30 -0
  69. data/config/locales/administrate.fr.yml +9 -7
  70. data/config/locales/administrate.id.yml +30 -0
  71. data/config/locales/administrate.it.yml +8 -6
  72. data/config/locales/administrate.ja.yml +8 -6
  73. data/config/locales/administrate.ko.yml +13 -11
  74. data/config/locales/administrate.nl.yml +12 -10
  75. data/config/locales/administrate.pl.yml +8 -6
  76. data/config/locales/administrate.pt-BR.yml +8 -6
  77. data/config/locales/administrate.pt.yml +8 -6
  78. data/config/locales/administrate.ru.yml +8 -6
  79. data/config/locales/administrate.sq.yml +30 -0
  80. data/config/locales/administrate.sv.yml +8 -6
  81. data/config/locales/administrate.tr.yml +30 -0
  82. data/config/locales/administrate.uk.yml +8 -6
  83. data/config/locales/administrate.vi.yml +8 -6
  84. data/config/locales/administrate.zh-CN.yml +8 -6
  85. data/config/locales/administrate.zh-TW.yml +10 -8
  86. data/config/unicorn.rb +8 -13
  87. data/docs/adding_controllers_without_related_model.md +52 -0
  88. data/docs/adding_custom_field_types.md +3 -1
  89. data/docs/authentication.md +3 -1
  90. data/docs/authorization.md +71 -0
  91. data/docs/customizing_attribute_partials.md +24 -2
  92. data/docs/customizing_controller_actions.md +50 -2
  93. data/docs/customizing_dashboards.md +210 -9
  94. data/docs/customizing_page_views.md +23 -5
  95. data/docs/extending_administrate.md +27 -0
  96. data/docs/getting_started.md +89 -15
  97. data/docs/guides/hiding_dashboards_from_sidebar.md +19 -0
  98. data/docs/guides.md +5 -0
  99. data/docs/rails_api.md +45 -0
  100. data/lib/administrate/base_dashboard.rb +53 -11
  101. data/lib/administrate/custom_dashboard.rb +15 -0
  102. data/lib/administrate/engine.rb +8 -1
  103. data/lib/administrate/field/associative.rb +55 -7
  104. data/lib/administrate/field/base.rb +35 -9
  105. data/lib/administrate/field/belongs_to.rb +18 -5
  106. data/lib/administrate/field/date.rb +20 -0
  107. data/lib/administrate/field/date_time.rb +13 -2
  108. data/lib/administrate/field/deferred.rb +29 -5
  109. data/lib/administrate/field/has_many.rb +32 -12
  110. data/lib/administrate/field/has_one.rb +39 -11
  111. data/lib/administrate/field/number.rb +19 -2
  112. data/lib/administrate/field/password.rb +25 -0
  113. data/lib/administrate/field/polymorphic.rb +42 -4
  114. data/lib/administrate/field/select.rb +10 -1
  115. data/lib/administrate/field/time.rb +19 -0
  116. data/lib/administrate/field/url.rb +21 -0
  117. data/lib/administrate/namespace.rb +6 -2
  118. data/lib/administrate/order.rb +52 -7
  119. data/lib/administrate/page/base.rb +9 -3
  120. data/lib/administrate/page/collection.rb +5 -1
  121. data/lib/administrate/page/form.rb +10 -3
  122. data/lib/administrate/resource_resolver.rb +4 -4
  123. data/lib/administrate/search.rb +138 -16
  124. data/lib/administrate/version.rb +1 -1
  125. data/lib/administrate/view_generator.rb +9 -3
  126. data/lib/administrate.rb +19 -0
  127. data/lib/generators/administrate/dashboard/USAGE +1 -1
  128. data/lib/generators/administrate/dashboard/dashboard_generator.rb +29 -17
  129. data/lib/generators/administrate/dashboard/templates/controller.rb.erb +35 -10
  130. data/lib/generators/administrate/dashboard/templates/dashboard.rb.erb +18 -6
  131. data/lib/generators/administrate/install/install_generator.rb +50 -7
  132. data/lib/generators/administrate/install/templates/{application_controller.rb → application_controller.rb.erb} +4 -4
  133. data/lib/generators/administrate/routes/routes_generator.rb +26 -26
  134. data/lib/generators/administrate/routes/templates/routes.rb.erb +1 -1
  135. data/lib/generators/administrate/views/field_generator.rb +19 -5
  136. data/lib/generators/administrate/views/layout_generator.rb +1 -0
  137. data/lib/generators/administrate/views/views_generator.rb +5 -4
  138. metadata +52 -53
  139. data/app/assets/javascripts/administrate/components/has_many_form.js +0 -3
  140. data/config/secrets.yml +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: bbf40650e2f1b5fef6121aed98256dfc8225bb12
4
- data.tar.gz: ec4394132d9e3b0f5117b95e26dcbc8d3fca3bea
2
+ SHA256:
3
+ metadata.gz: 6a099c28c8a74491759229e6fe82de763f25b9ff59473d5c70b00d38675e3498
4
+ data.tar.gz: c24140b9e1bc63eb9ecd5f38cd0cfd3d3c0f125a81370df1dd6663af66121baa
5
5
  SHA512:
6
- metadata.gz: 9e9014f2e04d659e1ca3d8e7fdb3b54f55097bfb8911279baf03f5114db200d4de3cc4a1b0fe745d70e033aa790e43e50a1f5b7f708897623cfeff75b156204b
7
- data.tar.gz: 23896d95877e97096300d8412b9a5ff9332aceb3f9aabee06cd297f6641a01bfe6a0e86b2b6c48cd55f047decb0d77935e21874bba5459a118cde5051a28adee
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
+ });
@@ -1,6 +1,14 @@
1
1
  $(function () {
2
- $(".datetimepicker").datetimepicker({
2
+ $('[data-type="time"]').datetimepicker({
3
3
  debug: false,
4
- format: "YYYY-MM-DD HH:mm:ss",
4
+ format: 'HH:mm:ss',
5
+ });
6
+ $('[data-type="datetime"]').datetimepicker({
7
+ debug: false,
8
+ format: 'YYYY-MM-DD HH:mm:ss',
9
+ });
10
+ $('[data-type="date"]').datetimepicker({
11
+ debug: false,
12
+ format: 'YYYY-MM-DD',
5
13
  });
6
14
  });
@@ -13,7 +13,7 @@ $(function() {
13
13
  var dataUrl = $(event.target).closest("tr").data("url");
14
14
  var selection = window.getSelection().toString();
15
15
  if (selection.length === 0 && dataUrl) {
16
- window.location = dataUrl;
16
+ window.location = window.location.protocol + '//' + window.location.host + dataUrl;
17
17
  }
18
18
  }
19
19
  };
@@ -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
 
@@ -23,7 +23,7 @@ p {
23
23
 
24
24
  a {
25
25
  color: $action-color;
26
- text-decoration-skip: ink;
26
+ text-decoration-skip-ink: auto;
27
27
  transition: color $base-duration $base-timing;
28
28
 
29
29
  &:hover {
@@ -3,9 +3,9 @@
3
3
  clear: left;
4
4
  float: left;
5
5
  margin-bottom: $base-spacing;
6
- margin-top: 0;
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 {
@@ -41,3 +41,14 @@ input[type="submit"],
41
41
  }
42
42
  }
43
43
  }
44
+
45
+ .button--alt {
46
+ background-color: transparent;
47
+ border: $base-border;
48
+ border-color: $blue;
49
+ color: $blue;
50
+ }
51
+
52
+ .button--nav {
53
+ margin-bottom: $base-spacing;
54
+ }
@@ -1,5 +1,5 @@
1
1
  .cell-label {
2
- position: relative;
2
+ padding-top: 0.15em;
3
3
 
4
4
  &:hover {
5
5
  a {
@@ -26,10 +26,8 @@
26
26
  }
27
27
 
28
28
  .cell-label__sort-indicator {
29
- display: inline-block;
30
- overflow: hidden;
31
- position: absolute;
32
- right: 0;
29
+ float: right;
30
+ margin-left: 5px;
33
31
 
34
32
  svg {
35
33
  fill: $hint-grey;
@@ -17,20 +17,33 @@
17
17
  .field-unit__field {
18
18
  float: left;
19
19
  margin-left: 2rem;
20
- width: 45%;
20
+ max-width: 50rem;
21
+ width: 100%;
22
+
23
+ .optgroup-header {
24
+ font-weight: $bold-font-weight;
25
+ }
21
26
  }
22
27
 
23
28
  .field-unit--nested {
24
29
  border: $base-border;
25
30
  margin-left: 7.5%;
31
+ max-width: 60rem;
26
32
  padding: $small-spacing;
27
- width: 50%;
33
+ width: 100%;
28
34
 
29
35
  .field-unit__field {
30
- width: calc(75% - 1rem);
36
+ width: 100%;
31
37
  }
32
38
 
33
39
  .field-unit__label {
34
- width: calc(25% - 1rem);
40
+ width: 10rem;
41
+ }
42
+ }
43
+
44
+ .field-unit--required {
45
+ label::after {
46
+ color: $red;
47
+ content: " *";
35
48
  }
36
49
  }
@@ -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,
@@ -2,9 +2,8 @@ $_navigation-link-padding: 0.6em;
2
2
 
3
3
  .navigation {
4
4
  flex: 1 0 10rem;
5
- padding-bottom: $base-spacing;
6
- padding-right: calc(#{$base-spacing} - #{$_navigation-link-padding});
7
- padding-top: $base-spacing;
5
+ padding: $base-spacing;
6
+ padding-left: 0;
8
7
  }
9
8
 
10
9
  .navigation__link {
@@ -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;
@@ -80,6 +80,7 @@ code {
80
80
  padding-left: 1rem;
81
81
 
82
82
  .hljs-string { color: $code-green; }
83
+ .hljs-subst { color: $code-white; }
83
84
  .hljs-constant { color: $code-blue; }
84
85
  .hljs-symbol { color: $code-red; }
85
86
  .hljs-keyword { color: $code-yellow; }
@@ -3,20 +3,21 @@ 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
- resources = resources.includes(*resource_includes) if resource_includes.any?
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: {
16
17
  resources: resources,
17
18
  search_term: search_term,
18
19
  page: page,
19
- show_search_bar: show_search_bar?
20
+ show_search_bar: show_search_bar?,
20
21
  }
21
22
  end
22
23
 
@@ -27,8 +28,10 @@ module Administrate
27
28
  end
28
29
 
29
30
  def new
31
+ resource = new_resource
32
+ authorize_resource(resource)
30
33
  render locals: {
31
- page: Administrate::Page::Form.new(dashboard, resource_class.new),
34
+ page: Administrate::Page::Form.new(dashboard, resource),
32
35
  }
33
36
  end
34
37
 
@@ -40,43 +43,60 @@ module Administrate
40
43
 
41
44
  def create
42
45
  resource = resource_class.new(resource_params)
46
+ authorize_resource(resource)
43
47
 
44
48
  if resource.save
45
49
  redirect_to(
46
- [namespace, resource],
50
+ after_resource_created_path(resource),
47
51
  notice: translate_with_resource("create.success"),
48
52
  )
49
53
  else
50
54
  render :new, locals: {
51
55
  page: Administrate::Page::Form.new(dashboard, resource),
52
- }
56
+ }, status: :unprocessable_entity
53
57
  end
54
58
  end
55
59
 
56
60
  def update
57
61
  if requested_resource.update(resource_params)
58
62
  redirect_to(
59
- [namespace, requested_resource],
63
+ after_resource_updated_path(requested_resource),
60
64
  notice: translate_with_resource("update.success"),
61
65
  )
62
66
  else
63
67
  render :edit, locals: {
64
68
  page: Administrate::Page::Form.new(dashboard, requested_resource),
65
- }
69
+ }, status: :unprocessable_entity
66
70
  end
67
71
  end
68
72
 
69
73
  def destroy
70
- requested_resource.destroy
71
- flash[:notice] = translate_with_resource("destroy.success")
72
- redirect_to action: :index
74
+ if requested_resource.destroy
75
+ flash[:notice] = translate_with_resource("destroy.success")
76
+ else
77
+ flash[:error] = requested_resource.errors.full_messages.join("<br/>")
78
+ end
79
+ redirect_to after_resource_destroyed_path(requested_resource)
73
80
  end
74
81
 
75
82
  private
76
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
+
77
96
  helper_method :nav_link_state
78
97
  def nav_link_state(resource)
79
- 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
80
100
  end
81
101
 
82
102
  helper_method :valid_action?
@@ -95,15 +115,37 @@ module Administrate
95
115
  end
96
116
 
97
117
  def order
98
- @_order ||= Administrate::Order.new(params[:order], params[:direction])
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]) || {}
99
139
  end
100
140
 
101
141
  def dashboard
102
- @_dashboard ||= dashboard_class.new
142
+ @dashboard ||= dashboard_class.new
103
143
  end
104
144
 
105
145
  def requested_resource
106
- @_requested_resource ||= find_resource(params[:id])
146
+ @requested_resource ||= find_resource(params[:id]).tap do |resource|
147
+ authorize_resource(resource)
148
+ end
107
149
  end
108
150
 
109
151
  def find_resource(param)
@@ -114,22 +156,40 @@ module Administrate
114
156
  resource_class.default_scoped
115
157
  end
116
158
 
117
- def resource_includes
118
- dashboard.association_includes
159
+ def apply_collection_includes(relation)
160
+ resource_includes = dashboard.collection_includes
161
+ return relation if resource_includes.empty?
162
+ relation.includes(*resource_includes)
119
163
  end
120
164
 
121
165
  def resource_params
122
166
  params.require(resource_class.model_name.param_key).
123
- permit(dashboard.permitted_attributes)
167
+ permit(dashboard.permitted_attributes).
168
+ transform_values { |v| read_param_value(v) }
169
+ end
170
+
171
+ def read_param_value(data)
172
+ if data.is_a?(ActionController::Parameters) && data[:type]
173
+ if data[:type] == Administrate::Field::Polymorphic.to_s
174
+ GlobalID::Locator.locate(data[:value])
175
+ else
176
+ raise "Unrecognised param data: #{data.inspect}"
177
+ end
178
+ elsif data.is_a?(ActionController::Parameters)
179
+ data.transform_values { |v| read_param_value(v) }
180
+ else
181
+ data
182
+ end
124
183
  end
125
184
 
126
185
  delegate :dashboard_class, :resource_class, :resource_name, :namespace,
127
186
  to: :resource_resolver
128
187
  helper_method :namespace
129
188
  helper_method :resource_name
189
+ helper_method :resource_class
130
190
 
131
191
  def resource_resolver
132
- @_resource_resolver ||=
192
+ @resource_resolver ||=
133
193
  Administrate::ResourceResolver.new(controller_path)
134
194
  end
135
195
 
@@ -142,8 +202,22 @@ module Administrate
142
202
 
143
203
  def show_search_bar?
144
204
  dashboard.attribute_types_for(
145
- dashboard.collection_attributes
205
+ dashboard.all_attributes,
146
206
  ).any? { |_name, attribute| attribute.searchable? }
147
207
  end
208
+
209
+ def show_action?(_action, _resource)
210
+ true
211
+ end
212
+ helper_method :show_action?
213
+
214
+ def new_resource
215
+ resource_class.new
216
+ end
217
+ helper_method :new_resource
218
+
219
+ def authorize_resource(resource)
220
+ resource
221
+ end
148
222
  end
149
223
  end
@@ -0,0 +1,36 @@
1
+ module Administrate
2
+ module Punditize
3
+ if Object.const_defined?("Pundit")
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
@@ -1,22 +1,39 @@
1
1
  module Administrate
2
2
  module ApplicationHelper
3
3
  PLURAL_MANY_COUNT = 2.1
4
+ SINGULAR_COUNT = 1
5
+
6
+ def application_title
7
+ if Rails::VERSION::MAJOR <= 5
8
+ Rails.application.class.parent_name.titlecase
9
+ else
10
+ Rails.application.class.module_parent_name.titlecase
11
+ end
12
+ end
4
13
 
5
14
  def render_field(field, locals = {})
6
- locals.merge!(field: field)
15
+ locals[:field] = field
7
16
  render locals: locals, partial: field.to_partial_path
8
17
  end
9
18
 
10
- def display_resource_name(resource_name)
11
- resource_name.
12
- to_s.
13
- classify.
14
- constantize.
15
- model_name.
16
- human(
17
- count: PLURAL_MANY_COUNT,
18
- default: resource_name.to_s.pluralize.titleize,
19
- )
19
+ def requireness(field)
20
+ field.required? ? "required" : "optional"
21
+ end
22
+
23
+ def dashboard_from_resource(resource_name)
24
+ "#{resource_name.to_s.singularize}_dashboard".classify.constantize
25
+ end
26
+
27
+ def model_from_resource(resource_name)
28
+ dashboard = dashboard_from_resource(resource_name)
29
+ dashboard.try(:model) || resource_name.to_sym
30
+ end
31
+
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
+ )
20
37
  end
21
38
 
22
39
  def sort_order(order)
@@ -27,12 +44,32 @@ module Administrate
27
44
  end
28
45
  end
29
46
 
30
- def sanitized_order_params
31
- params.permit(:search, :id, :order, :page, :per_page, :direction, :orders)
47
+ def resource_index_route(resource_name)
48
+ url_for(
49
+ action: "index",
50
+ controller: "/#{namespace}/#{resource_name}",
51
+ )
52
+ end
53
+
54
+ def sanitized_order_params(page, current_field_name)
55
+ collection_names = page.item_includes + [current_field_name]
56
+ association_params = collection_names.map do |assoc_name|
57
+ { assoc_name => %i[order direction page per_page] }
58
+ end
59
+ params.permit(:search, :id, :_page, :per_page, association_params)
32
60
  end
33
61
 
34
62
  def clear_search_params
35
- params.except(:search, :page).permit(:order, :direction, :per_page)
63
+ params.except(:search, :_page).permit(
64
+ :per_page, resource_name => %i[order direction]
65
+ )
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
36
73
  end
37
74
  end
38
75
  end