active_scaffold 4.1.6 → 4.2.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 (182) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.rdoc +27 -0
  3. data/README.md +6 -5
  4. data/app/assets/javascripts/jquery/active_scaffold.js +98 -47
  5. data/app/assets/javascripts/jquery/tiny_mce_bridge.js +15 -2
  6. data/app/assets/stylesheets/active_scaffold_images.scss +6 -0
  7. data/app/assets/stylesheets/{active_scaffold_layout.css → active_scaffold_layout.scss} +104 -4
  8. data/app/assets/stylesheets/tiny_mce_bridge.scss +11 -0
  9. data/app/views/active_scaffold_overrides/_base_form.html.erb +3 -2
  10. data/app/views/active_scaffold_overrides/_field_search.html.erb +2 -2
  11. data/app/views/active_scaffold_overrides/_form.html.erb +14 -4
  12. data/app/views/active_scaffold_overrides/_form_association.html.erb +1 -1
  13. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +5 -11
  14. data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +1 -1
  15. data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +1 -3
  16. data/app/views/active_scaffold_overrides/_new_record.js.erb +3 -1
  17. data/app/views/active_scaffold_overrides/_refresh_list.js.erb +1 -1
  18. data/app/views/active_scaffold_overrides/_render_field.js.erb +67 -36
  19. data/app/views/active_scaffold_overrides/_update_field_on_create.js.erb +41 -6
  20. data/app/views/active_scaffold_overrides/action_links_menu.js.erb +1 -0
  21. data/config/locales/de.yml +9 -0
  22. data/config/locales/en.yml +11 -0
  23. data/config/locales/es.yml +8 -0
  24. data/config/locales/fr.yml +8 -0
  25. data/config/locales/hu.yml +8 -0
  26. data/config/locales/ja.yml +8 -0
  27. data/config/locales/ru.yml +8 -0
  28. data/lib/active_scaffold/actions/common_search.rb +2 -0
  29. data/lib/active_scaffold/actions/core.rb +47 -23
  30. data/lib/active_scaffold/actions/create.rb +2 -0
  31. data/lib/active_scaffold/actions/delete.rb +6 -0
  32. data/lib/active_scaffold/actions/field_search.rb +36 -11
  33. data/lib/active_scaffold/actions/list.rb +26 -8
  34. data/lib/active_scaffold/actions/mark.rb +6 -0
  35. data/lib/active_scaffold/actions/nested.rb +2 -0
  36. data/lib/active_scaffold/actions/search.rb +7 -0
  37. data/lib/active_scaffold/actions/show.rb +6 -0
  38. data/lib/active_scaffold/actions/subform.rb +2 -0
  39. data/lib/active_scaffold/actions/update.rb +8 -1
  40. data/lib/active_scaffold/active_record_permissions.rb +3 -3
  41. data/lib/active_scaffold/attribute_params.rb +35 -17
  42. data/lib/active_scaffold/bridges/active_storage/active_storage_bridge.rb +2 -0
  43. data/lib/active_scaffold/bridges/active_storage/active_storage_helpers.rb +10 -9
  44. data/lib/active_scaffold/bridges/active_storage/form_ui.rb +10 -3
  45. data/lib/active_scaffold/bridges/active_storage/list_ui.rb +2 -0
  46. data/lib/active_scaffold/bridges/active_storage.rb +2 -0
  47. data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +2 -0
  48. data/lib/active_scaffold/bridges/ancestry.rb +2 -0
  49. data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +2 -0
  50. data/lib/active_scaffold/bridges/bitfields/list_ui.rb +2 -0
  51. data/lib/active_scaffold/bridges/bitfields.rb +2 -0
  52. data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +9 -6
  53. data/lib/active_scaffold/bridges/cancan.rb +2 -0
  54. data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +2 -0
  55. data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge_helpers.rb +2 -0
  56. data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +3 -1
  57. data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +2 -0
  58. data/lib/active_scaffold/bridges/carrierwave.rb +2 -0
  59. data/lib/active_scaffold/bridges/chosen/helpers.rb +13 -4
  60. data/lib/active_scaffold/bridges/chosen.rb +2 -0
  61. data/lib/active_scaffold/bridges/country_select/country_select_bridge_helper.rb +2 -0
  62. data/lib/active_scaffold/bridges/country_select.rb +2 -0
  63. data/lib/active_scaffold/bridges/date_picker/ext.rb +6 -0
  64. data/lib/active_scaffold/bridges/date_picker/helper.rb +7 -3
  65. data/lib/active_scaffold/bridges/date_picker.rb +2 -0
  66. data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge.rb +2 -0
  67. data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge_helpers.rb +2 -0
  68. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +3 -1
  69. data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +2 -0
  70. data/lib/active_scaffold/bridges/dragonfly.rb +2 -0
  71. data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +2 -0
  72. data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +10 -9
  73. data/lib/active_scaffold/bridges/file_column/form_ui.rb +2 -0
  74. data/lib/active_scaffold/bridges/file_column/list_ui.rb +2 -0
  75. data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +2 -0
  76. data/lib/active_scaffold/bridges/file_column/test/mock_model.rb +2 -0
  77. data/lib/active_scaffold/bridges/file_column.rb +2 -0
  78. data/lib/active_scaffold/bridges/logical_query_parser/tokens_grammar.rb +65 -0
  79. data/lib/active_scaffold/bridges/logical_query_parser/tokens_grammar.treetop +31 -0
  80. data/lib/active_scaffold/bridges/logical_query_parser.rb +9 -0
  81. data/lib/active_scaffold/bridges/paper_trail/actions.rb +2 -0
  82. data/lib/active_scaffold/bridges/paper_trail/config.rb +2 -0
  83. data/lib/active_scaffold/bridges/paper_trail/helper.rb +2 -0
  84. data/lib/active_scaffold/bridges/paper_trail/paper_trail_bridge.rb +2 -0
  85. data/lib/active_scaffold/bridges/paper_trail.rb +2 -0
  86. data/lib/active_scaffold/bridges/paperclip/form_ui.rb +3 -1
  87. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +2 -0
  88. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +2 -0
  89. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge_helpers.rb +12 -12
  90. data/lib/active_scaffold/bridges/paperclip.rb +2 -0
  91. data/lib/active_scaffold/bridges/record_select/helpers.rb +19 -11
  92. data/lib/active_scaffold/bridges/record_select.rb +2 -0
  93. data/lib/active_scaffold/bridges/semantic_attributes/column.rb +2 -0
  94. data/lib/active_scaffold/bridges/semantic_attributes.rb +2 -0
  95. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +3 -1
  96. data/lib/active_scaffold/bridges/tiny_mce.rb +6 -0
  97. data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +2 -0
  98. data/lib/active_scaffold/bridges/usa_state_select.rb +2 -0
  99. data/lib/active_scaffold/bridges.rb +2 -0
  100. data/lib/active_scaffold/config/base.rb +12 -7
  101. data/lib/active_scaffold/config/core.rb +26 -23
  102. data/lib/active_scaffold/config/create.rb +2 -0
  103. data/lib/active_scaffold/config/delete.rb +2 -0
  104. data/lib/active_scaffold/config/field_search.rb +2 -0
  105. data/lib/active_scaffold/config/form.rb +11 -1
  106. data/lib/active_scaffold/config/list.rb +7 -7
  107. data/lib/active_scaffold/config/mark.rb +2 -0
  108. data/lib/active_scaffold/config/nested.rb +28 -0
  109. data/lib/active_scaffold/config/search.rb +2 -0
  110. data/lib/active_scaffold/config/show.rb +2 -0
  111. data/lib/active_scaffold/config/subform.rb +2 -0
  112. data/lib/active_scaffold/config/update.rb +3 -1
  113. data/lib/active_scaffold/configurable.rb +4 -2
  114. data/lib/active_scaffold/constraints.rb +2 -0
  115. data/lib/active_scaffold/core.rb +14 -4
  116. data/lib/active_scaffold/data_structures/action_columns.rb +3 -1
  117. data/lib/active_scaffold/data_structures/action_link.rb +10 -0
  118. data/lib/active_scaffold/data_structures/action_link_separator.rb +2 -0
  119. data/lib/active_scaffold/data_structures/action_links.rb +32 -21
  120. data/lib/active_scaffold/data_structures/actions.rb +4 -2
  121. data/lib/active_scaffold/data_structures/association/abstract.rb +4 -2
  122. data/lib/active_scaffold/data_structures/association/active_mongoid.rb +4 -2
  123. data/lib/active_scaffold/data_structures/association/active_record.rb +3 -9
  124. data/lib/active_scaffold/data_structures/association/mongoid.rb +4 -2
  125. data/lib/active_scaffold/data_structures/association.rb +2 -0
  126. data/lib/active_scaffold/data_structures/bridge.rb +3 -1
  127. data/lib/active_scaffold/data_structures/column.rb +37 -3
  128. data/lib/active_scaffold/data_structures/columns.rb +4 -2
  129. data/lib/active_scaffold/data_structures/filter.rb +3 -3
  130. data/lib/active_scaffold/data_structures/filter_option.rb +2 -0
  131. data/lib/active_scaffold/data_structures/filters.rb +3 -3
  132. data/lib/active_scaffold/data_structures/nested_info.rb +4 -2
  133. data/lib/active_scaffold/data_structures/set.rb +8 -10
  134. data/lib/active_scaffold/data_structures/sorting.rb +5 -7
  135. data/lib/active_scaffold/engine.rb +3 -4
  136. data/lib/active_scaffold/extensions/action_controller_rendering.rb +2 -0
  137. data/lib/active_scaffold/extensions/action_controller_rescueing.rb +2 -0
  138. data/lib/active_scaffold/extensions/action_view_rendering.rb +2 -0
  139. data/lib/active_scaffold/extensions/connection_adapter.rb +2 -0
  140. data/lib/active_scaffold/extensions/ice_nine.rb +2 -0
  141. data/lib/active_scaffold/extensions/localize.rb +2 -0
  142. data/lib/active_scaffold/extensions/name_option_for_datetime.rb +2 -0
  143. data/lib/active_scaffold/extensions/paginator_extensions.rb +3 -1
  144. data/lib/active_scaffold/extensions/routing_mapper.rb +2 -0
  145. data/lib/active_scaffold/extensions/to_label.rb +2 -0
  146. data/lib/active_scaffold/extensions/unsaved_associated.rb +10 -8
  147. data/lib/active_scaffold/extensions/unsaved_record.rb +2 -0
  148. data/lib/active_scaffold/finder.rb +57 -18
  149. data/lib/active_scaffold/helpers/action_link_helpers.rb +112 -37
  150. data/lib/active_scaffold/helpers/association_helpers.rb +4 -2
  151. data/lib/active_scaffold/helpers/controller_helpers.rb +2 -0
  152. data/lib/active_scaffold/helpers/filter_helpers.rb +11 -3
  153. data/lib/active_scaffold/helpers/form_column_helpers.rb +98 -71
  154. data/lib/active_scaffold/helpers/human_condition_helpers.rb +2 -0
  155. data/lib/active_scaffold/helpers/id_helpers.rb +2 -0
  156. data/lib/active_scaffold/helpers/list_column_helpers.rb +9 -5
  157. data/lib/active_scaffold/helpers/pagination_helpers.rb +3 -1
  158. data/lib/active_scaffold/helpers/search_column_helpers.rb +19 -9
  159. data/lib/active_scaffold/helpers/show_column_helpers.rb +4 -2
  160. data/lib/active_scaffold/helpers/tabs_helpers.rb +5 -3
  161. data/lib/active_scaffold/helpers/view_helpers.rb +3 -3
  162. data/lib/active_scaffold/marked_model.rb +6 -5
  163. data/lib/active_scaffold/orm_checks.rb +2 -0
  164. data/lib/active_scaffold/paginator.rb +4 -1
  165. data/lib/active_scaffold/registry.rb +2 -0
  166. data/lib/active_scaffold/responds_to_parent.rb +2 -0
  167. data/lib/active_scaffold/tableless.rb +23 -13
  168. data/lib/active_scaffold/version.rb +4 -2
  169. data/lib/active_scaffold.rb +10 -2
  170. data/lib/generators/active_scaffold/controller/USAGE +19 -0
  171. data/lib/generators/active_scaffold/controller/controller_generator.rb +29 -0
  172. data/lib/generators/active_scaffold/install/USAGE +2 -0
  173. data/lib/generators/active_scaffold/{install_generator.rb → install/install_generator.rb} +10 -6
  174. data/lib/generators/active_scaffold/resource/USAGE +29 -0
  175. data/lib/generators/active_scaffold/resource/resource_generator.rb +30 -0
  176. data/lib/tasks/brakeman.rake +2 -0
  177. data/shoulda_macros/macros.rb +2 -0
  178. metadata +19 -11
  179. data/lib/generators/active_scaffold/controller_generator.rb +0 -49
  180. data/lib/generators/active_scaffold/resource_generator.rb +0 -56
  181. /data/lib/generators/{templates → active_scaffold/controller/templates}/controller.rb +0 -0
  182. /data/lib/generators/{templates → active_scaffold/controller/templates}/helper.rb +0 -0
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::Config
2
4
  # to fix the ckeditor bridge problem inherit from full class name
3
5
  class Core < ActiveScaffold::Config::Base
4
6
  include ActiveScaffold::OrmChecks
7
+
5
8
  # global level configuration
6
9
  # --------------------------
7
10
 
@@ -24,6 +27,10 @@ module ActiveScaffold::Config
24
27
  cattr_accessor :cache_action_link_urls, instance_accessor: false
25
28
  @@cache_action_link_urls = true
26
29
 
30
+ # enable caching of action links
31
+ cattr_accessor :cache_action_links, instance_accessor: false
32
+ @@cache_action_links = true
33
+
27
34
  # enable caching of association options
28
35
  cattr_accessor :cache_association_options, instance_accessor: false
29
36
  @@cache_association_options = true
@@ -36,18 +43,14 @@ module ActiveScaffold::Config
36
43
  cattr_accessor :store_user_settings, instance_accessor: false
37
44
  @@store_user_settings = true
38
45
 
39
- # lets you disable the DHTML history
40
- cattr_writer :dhtml_history, instance_accessor: false
41
-
42
- def self.dhtml_history?
43
- @@dhtml_history ? true : false
44
- end
45
- @@dhtml_history = true
46
-
47
46
  # action links are used by actions to tie together. you can use them, too! this is a collection of ActiveScaffold::DataStructures::ActionLink objects.
48
47
  cattr_reader :action_links, instance_reader: false
49
48
  @@action_links = ActiveScaffold::DataStructures::ActionLinks.new
50
49
 
50
+ # modules to include after all ActiveScaffold modules are included, to include generic customizations in all controllers
51
+ cattr_reader :custom_modules, instance_reader: false
52
+ @@custom_modules = []
53
+
51
54
  # access to the permissions configuration.
52
55
  # configuration options include:
53
56
  # * current_user_method - what method on the controller returns the current user. default: :current_user
@@ -116,9 +119,16 @@ module ActiveScaffold::Config
116
119
  # lets you override the global ActiveScaffold theme for a specific controller
117
120
  attr_accessor :theme
118
121
 
122
+ # modules to include after all ActiveScaffold modules are included, to include generic customizations in some controllers
123
+ # These modules are included after the modules in global custom_modules setting.
124
+ attr_reader :custom_modules
125
+
119
126
  # enable caching of action link urls
120
127
  attr_accessor :cache_action_link_urls
121
128
 
129
+ # enable caching of action links
130
+ attr_accessor :cache_action_links
131
+
122
132
  # enable caching of association options
123
133
  attr_accessor :cache_association_options
124
134
 
@@ -161,6 +171,7 @@ module ActiveScaffold::Config
161
171
  def initialize(model_id) # rubocop:disable Lint/MissingSuper
162
172
  # model_id is the only absolutely required configuration value. it is also not publicly accessible.
163
173
  @model_id = model_id
174
+ @custom_modules = []
164
175
  setup_user_setting_key
165
176
 
166
177
  # inherit the actions list directly from the global level
@@ -182,6 +193,7 @@ module ActiveScaffold::Config
182
193
 
183
194
  @theme = self.class.theme
184
195
  @cache_action_link_urls = self.class.cache_action_link_urls
196
+ @cache_action_links = self.class.cache_action_links
185
197
  @cache_association_options = self.class.cache_association_options
186
198
  @conditional_get_support = self.class.conditional_get_support
187
199
  @store_user_settings = self.class.store_user_settings
@@ -197,7 +209,7 @@ module ActiveScaffold::Config
197
209
  def _cache_lazy_values
198
210
  action_links.collection # ensure the collection group exist although it's empty
199
211
  action_links.member # ensure the collection group exist although it's empty
200
- if cache_action_link_urls
212
+ if cache_action_link_urls || cache_action_links
201
213
  action_links.each(&:name_to_cache)
202
214
  list.filters.each { |filter| filter.each(&:name_to_cache) } if actions.include?(:list)
203
215
  end
@@ -249,7 +261,7 @@ module ActiveScaffold::Config
249
261
 
250
262
  underscored_name = action_name.to_s.underscore.to_sym
251
263
  unless @actions.include? underscored_name
252
- raise "#{action_name.to_s.camelcase} is not enabled. Please enable it or remove any references in your configuration (e.g. config.#{underscored_name}.columns = [...])."
264
+ raise ArgumentError, "#{action_name.to_s.camelcase} is not enabled. Please enable it or remove any references in your configuration (e.g. config.#{underscored_name}.columns = [...])."
253
265
  end
254
266
 
255
267
  @action_configs ||= {}
@@ -309,8 +321,9 @@ module ActiveScaffold::Config
309
321
 
310
322
  class UserSettings < Base::UserSettings
311
323
  include ActiveScaffold::Configurable
312
- user_attr :cache_action_link_urls, :cache_association_options, :conditional_get_support,
313
- :timestamped_messages, :highlight_messages
324
+
325
+ user_attr :cache_action_link_urls, :cache_action_links, :cache_association_options,
326
+ :conditional_get_support, :timestamped_messages, :highlight_messages
314
327
  attr_writer :label
315
328
 
316
329
  def label(options = {})
@@ -337,17 +350,7 @@ module ActiveScaffold::Config
337
350
  @columns ||= UserColumns.new(@conf.columns)
338
351
  end
339
352
 
340
- def action_links
341
- @conf.action_links
342
- end
343
-
344
- def model
345
- @conf.model # for performance, called many times, so we avoid method_missing
346
- end
347
-
348
- def actions
349
- @conf.actions # for performance, called many times, so we avoid method_missing
350
- end
353
+ delegate :action_links, :model, :actions, to: :@conf
351
354
  end
352
355
 
353
356
  class UserColumns
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::Config
2
4
  class Create < ActiveScaffold::Config::Form
3
5
  self.crud_type = :create
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::Config
2
4
  class Delete < Base
3
5
  self.crud_type = :delete
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::Config
2
4
  class FieldSearch < Base
3
5
  self.crud_type = :read
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::Config
2
4
  class Form < Base
3
5
  def initialize(core_config)
@@ -6,6 +8,7 @@ module ActiveScaffold::Config
6
8
  @refresh_list = self.class.refresh_list
7
9
  @persistent = self.class.persistent
8
10
  @floating_footer = self.class.floating_footer
11
+ @field_descriptions = self.class.field_descriptions
9
12
 
10
13
  # no global setting here because multipart should only be set for specific forms
11
14
  @multipart = false
@@ -28,6 +31,10 @@ module ActiveScaffold::Config
28
31
  class_attribute :floating_footer, instance_accessor: false
29
32
  @@floating_footer = false
30
33
 
34
+ # whether field descriptions are visible always, on hover or click (:show, :hover, :click, default to :show)
35
+ class_attribute :field_descriptions, instance_accessor: false
36
+ @@field_descriptions = :show
37
+
31
38
  # instance-level configuration
32
39
  # ----------------------------
33
40
 
@@ -49,6 +56,9 @@ module ActiveScaffold::Config
49
56
  # whether footer should float when form is too long to fit in the screen, so footer is always available while scrolling
50
57
  attr_accessor :floating_footer
51
58
 
59
+ # whether field descriptions are visible always, on hover or click (:show, :hover, :click, default to :show)
60
+ attr_accessor :field_descriptions
61
+
52
62
  columns_accessor :columns do
53
63
  columns.exclude :created_on, :created_at, :updated_on, :updated_at, :as_marked
54
64
  columns.exclude(*@core.columns.filter_map { |c| c.name if c.association&.polymorphic? })
@@ -62,7 +72,7 @@ module ActiveScaffold::Config
62
72
  end
63
73
 
64
74
  UserSettings.class_eval do
65
- user_attr :persistent, :refresh_list, :show_unauthorized_columns, :floating_footer
75
+ user_attr :persistent, :refresh_list, :show_unauthorized_columns, :floating_footer, :field_descriptions
66
76
 
67
77
  attr_writer :multipart
68
78
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::Config
2
4
  class List < Base
3
5
  self.crud_type = :read
@@ -199,8 +201,8 @@ module ActiveScaffold::Config
199
201
  # the label for this List action. used for the header.
200
202
  attr_writer :label
201
203
 
202
- def label
203
- @label ? as_(@label, count: 2) : @core.label(count: 2)
204
+ def label(core: @core)
205
+ @label ? as_(@label, count: 2) : core.label(count: 2)
204
206
  end
205
207
 
206
208
  attr_writer :no_entries_message, :filtered_message, :always_show_search
@@ -244,7 +246,7 @@ module ActiveScaffold::Config
244
246
  attr_writer :hide_nested_column
245
247
 
246
248
  def hide_nested_column
247
- @hide_nested_column.nil? ? true : @hide_nested_column
249
+ @hide_nested_column.nil? || @hide_nested_column
248
250
  end
249
251
 
250
252
  # wrap normal cells (not inplace editable columns or with link) with a tag
@@ -274,7 +276,7 @@ module ActiveScaffold::Config
274
276
 
275
277
  # This label has already been localized.
276
278
  def label
277
- self['label'] || embedded_label || @label || @conf.label
279
+ self['label'] || embedded_label || @label || @conf.label(core: core)
278
280
  end
279
281
 
280
282
  def embedded_label
@@ -339,9 +341,7 @@ module ActiveScaffold::Config
339
341
  @_sorting
340
342
  end
341
343
 
342
- def count_includes
343
- @conf.count_includes
344
- end
344
+ delegate :count_includes, to: :@conf
345
345
 
346
346
  protected
347
347
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::Config
2
4
  class Mark < Base
3
5
  self.crud_type = :read
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::Config
2
4
  class Nested < Base
3
5
  self.crud_type = :read
@@ -41,8 +43,34 @@ module ActiveScaffold::Config
41
43
  action_link
42
44
  end
43
45
 
46
+ # Add a nested ActionLink to new action
47
+ def add_new_link(attribute, options = {})
48
+ column = @core.columns[attribute.to_sym]
49
+ raise ArgumentError, "unknown column #{attribute}" if column.nil?
50
+ raise ArgumentError, "column #{attribute} is not an association" if column.association.nil?
51
+
52
+ model =
53
+ if column.association.polymorphic?
54
+ column.label
55
+ else
56
+ column.association.klass.model_name.human(count: 1)
57
+ end
58
+ options.reverse_merge!(
59
+ security_method: :nested_authorized?,
60
+ label: as_(:add_model, model: model),
61
+ action: 'new',
62
+ refresh_on_close: false,
63
+ parameters: {parent_controller: @core.controller_path}
64
+ )
65
+ action_group = options.delete(:action_group) || self.action_group
66
+ action_link = @core.link_for_association(column, options)
67
+ @core.action_links.add_to_group(action_link, action_group) unless action_link.nil?
68
+ action_link
69
+ end
70
+
44
71
  def add_scoped_link(named_scope, options = {})
45
72
  action_link = @core.link_for_association_as_scope(named_scope.to_sym, options)
73
+ action_group = options.delete(:action_group) || self.action_group
46
74
  @core.action_links.add_to_group(action_link, action_group) unless action_link.nil?
47
75
  end
48
76
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::Config
2
4
  class Search < Base
3
5
  self.crud_type = :read
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::Config
2
4
  class Show < Base
3
5
  self.crud_type = :read
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::Config
2
4
  class Subform < Base
3
5
  def initialize(core_config)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::Config
2
4
  class Update < ActiveScaffold::Config::Form
3
5
  self.crud_type = :update
@@ -35,7 +37,7 @@ module ActiveScaffold::Config
35
37
  attr_writer :hide_nested_column
36
38
 
37
39
  def hide_nested_column
38
- @hide_nested_column.nil? ? true : @hide_nested_column
40
+ @hide_nested_column.nil? || @hide_nested_column
39
41
  end
40
42
 
41
43
  UserSettings.class_eval do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold
2
4
  # Exposes a +configure+ method that accepts a block and runs all contents of the block in two contexts,
3
5
  # as opposed to the normal one. First, everything gets evaluated as part of the object including Configurable.
@@ -16,9 +18,9 @@ module ActiveScaffold
16
18
  ret
17
19
  end
18
20
 
19
- def method_missing(name, *args)
21
+ def method_missing(name, *)
20
22
  if @configuration_binding&.respond_to?(name, true) # rubocop:disable Lint/RedundantSafeNavigation
21
- @configuration_binding.send(name, *args)
23
+ @configuration_binding.send(name, *)
22
24
  else
23
25
  super
24
26
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold
2
4
  module Constraints
3
5
  def self.included(base)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold
2
4
  module Core
3
5
  def self.included(base)
@@ -37,6 +39,7 @@ module ActiveScaffold
37
39
  module ClassMethods
38
40
  def active_scaffold(model_id = nil, &block)
39
41
  extend Prefixes
42
+
40
43
  # initialize bridges here
41
44
  ActiveScaffold::Bridges.run_all
42
45
 
@@ -56,6 +59,8 @@ module ActiveScaffold
56
59
  instance_eval(&callback)
57
60
  elsif active_scaffold_config.respond_to?(callback)
58
61
  active_scaffold_config.send(callback)
62
+ elsif respond_to?(callback)
63
+ send(callback)
59
64
  end
60
65
  end
61
66
 
@@ -72,6 +77,7 @@ module ActiveScaffold
72
77
  end
73
78
  active_scaffold_config.actions.each do |mod|
74
79
  include "ActiveScaffold::Actions::#{mod.to_s.camelize}".constantize
80
+
75
81
  mod_conf = active_scaffold_config.send(mod)
76
82
  active_scaffold_config._setup_action(mod)
77
83
  next unless mod_conf.respond_to?(:link) && (link = mod_conf.link)
@@ -87,6 +93,8 @@ module ActiveScaffold
87
93
  end
88
94
  end
89
95
  _add_sti_create_links if active_scaffold_config.add_sti_create_links?
96
+ ActiveScaffold::Config::Core.custom_modules.each { |mod| include mod }
97
+ active_scaffold_config.custom_modules.each { |mod| include mod }
90
98
  active_scaffold_config._cache_lazy_values
91
99
  active_scaffold_config.deep_freeze!
92
100
  end
@@ -110,7 +118,7 @@ module ActiveScaffold
110
118
 
111
119
  active_scaffold_config.action_links.collection.delete('new')
112
120
  active_scaffold_config.sti_children.each do |child|
113
- new_sti_link = Marshal.load(Marshal.dump(new_action_link)) # deep clone
121
+ new_sti_link = new_action_link.deep_dup
114
122
  new_sti_link.label = as_(:create_model, model: child.to_s.camelize.constantize.model_name.human)
115
123
  new_sti_link.parameters = {parent_sti: controller_path}
116
124
  new_sti_link.controller = proc { active_scaffold_controller_for(child.to_s.camelize.constantize).controller_path }
@@ -153,7 +161,7 @@ module ActiveScaffold
153
161
  options[:parameters] ||= {}
154
162
  options[:parameters].reverse_merge! association: column.association.name
155
163
  if column.association.collection?
156
- ActiveScaffold::DataStructures::ActionLink.new('index', options.merge(refresh_on_close: true))
164
+ ActiveScaffold::DataStructures::ActionLink.new('index', options.reverse_merge(refresh_on_close: true))
157
165
  else
158
166
  actions = controller.active_scaffold_config.actions unless controller == :polymorph
159
167
  actions ||= %i[create update show]
@@ -178,7 +186,7 @@ module ActiveScaffold
178
186
  as_path = File.realpath File.join(ActiveScaffold::Config::Core.plugin_directory, 'app', 'views')
179
187
  index = view_paths.find_index { |p| p.to_s == as_path }
180
188
  if index
181
- self.view_paths = view_paths[0..index - 1] + Array(path) + view_paths[index..]
189
+ self.view_paths = view_paths[0..(index - 1)] + Array(path) + view_paths[index..]
182
190
  else
183
191
  append_view_path path
184
192
  end
@@ -214,7 +222,9 @@ module ActiveScaffold
214
222
  return self if uses_active_scaffold? && klass == active_scaffold_config.model
215
223
 
216
224
  # noinspection RubyArgCount
217
- ActiveScaffold::Core.active_scaffold_controller_for(klass, "#{to_s.deconstantize}::")
225
+ ActiveScaffold::Registry.cache :as_controller, klass do
226
+ ActiveScaffold::Core.active_scaffold_controller_for(klass, "#{to_s.deconstantize}::")
227
+ end
218
228
  end
219
229
 
220
230
  def uses_active_scaffold?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::DataStructures
2
4
  # A set of columns. These structures can be nested for organization.
3
5
  class ActionColumns < ActiveScaffold::DataStructures::Set
@@ -86,7 +88,7 @@ module ActiveScaffold::DataStructures
86
88
  yield item
87
89
  end
88
90
  else
89
- next if skip_column?(item, options)
91
+ next if !options[:skip_authorization] && skip_column?(item, options)
90
92
 
91
93
  yield columns[item] || ActiveScaffold::DataStructures::Column.new(item.to_sym, columns.active_record_class)
92
94
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::DataStructures
2
4
  class ActionLink
3
5
  NO_OPTIONS = {}.freeze
@@ -39,6 +41,14 @@ module ActiveScaffold::DataStructures
39
41
  self.html_options = html_options.clone if action_link.instance_variable_get(:@html_options)
40
42
  end
41
43
 
44
+ def deep_dup
45
+ link = dup
46
+ instance_variables.each do |var|
47
+ link.instance_variable_set(var, link.instance_variable_get(var).deep_dup)
48
+ end
49
+ link
50
+ end
51
+
42
52
  # the weight for this link in the action links collection, it will be used to sort the collection
43
53
  attr_accessor :weight
44
54
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::DataStructures
2
4
  class ActionLinkSeparator
3
5
  def initialize(weight)
@@ -1,15 +1,30 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::DataStructures
2
4
  class ActionLinks
3
5
  include Enumerable
4
- attr_accessor :default_type
5
6
 
6
- def initialize(name = :root)
7
+ COLLECTION_CLICK_MENU_LINK = ActionLink.new(:index, position: false, type: :member, toggle: false, parameters: {action_links: '--ACTION-LINKS--', id: nil}) # member so it's cached
8
+ MEMBER_CLICK_MENU_LINK = ActionLink.new(:index, position: false, type: :member, toggle: false, parameters: {action_links: '--ACTION-LINKS--'})
9
+
10
+ attr_accessor :default_type, :weight, :css_class
11
+ attr_writer :click_menu, :label
12
+ attr_reader :name, :path
13
+
14
+ def initialize(name = :root, parent_path = nil)
7
15
  @set = []
8
16
  @name = name
9
17
  @css_class = name.to_s.downcase
10
18
  @weight = 0
19
+ @path = [parent_path, name].compact.join('.') unless name == :root
11
20
  end
12
21
 
22
+ def click_menu?
23
+ @click_menu
24
+ end
25
+
26
+ alias name_to_cache path
27
+
13
28
  # adds an ActionLink, creating one from the arguments if need be
14
29
  def add(action, options = {})
15
30
  link =
@@ -126,29 +141,26 @@ module ActiveScaffold::DataStructures
126
141
  @set
127
142
  end
128
143
 
129
- def empty?
130
- @set.empty?
131
- end
144
+ delegate :empty?, to: :@set
132
145
 
133
146
  def subgroup(name, label = nil)
147
+ name = name.to_sym
134
148
  group = self if name == self.name
135
149
  group ||= @set.find do |item|
136
150
  name == item.name if item.is_a?(ActiveScaffold::DataStructures::ActionLinks)
137
151
  end
138
152
 
139
153
  if group.nil?
140
- raise "Can't add new subgroup '#{name}', links are frozen" if frozen?
154
+ raise FrozenError, "Can't add new subgroup '#{name}', links are frozen" if frozen?
141
155
 
142
- group = ActiveScaffold::DataStructures::ActionLinks.new(name)
156
+ group = ActiveScaffold::DataStructures::ActionLinks.new(name, path)
143
157
  group.label = label || name
144
- group.default_type = self.name == :root ? (name.to_sym if %w[member collection].include?(name.to_s)) : default_type
158
+ group.default_type = self.name == :root ? (name if %i[member collection].include?(name)) : default_type
145
159
  add_to_set group
146
160
  end
147
161
  group
148
162
  end
149
163
 
150
- attr_writer :label
151
-
152
164
  def label(record)
153
165
  case @label
154
166
  when Symbol
@@ -164,23 +176,22 @@ module ActiveScaffold::DataStructures
164
176
  return super if name.match?(/[=!?]$/)
165
177
  return subgroup(name.to_sym, args.first, &) if frozen?
166
178
 
167
- class_eval <<-METHOD, __FILE__, __LINE__ + 1
168
- def #{name}(label = nil) # def group_name(label = nil)
169
- @#{name} ||= subgroup(:'#{name}', label) # @group_name ||= subgroup(:'group_name', label)
170
- yield @#{name} if block_given? # yield @group_name if block_given?
171
- @#{name} # @group_name
172
- end # end
173
- METHOD
179
+ define_singleton_method name do |label = nil|
180
+ value = instance_variable_get("@#{name}")
181
+ unless value
182
+ value = subgroup(name.to_sym, label)
183
+ instance_variable_set("@#{name}", value)
184
+ end
185
+ yield value if block_given?
186
+ value
187
+ end
174
188
  send(name, args.first, &)
175
189
  end
176
190
 
177
191
  def respond_to_missing?(name, *)
178
- name !~ /[!?]$/
192
+ name !~ /[=!?]$/
179
193
  end
180
194
 
181
- attr_reader :name
182
- attr_accessor :weight, :css_class
183
-
184
195
  protected
185
196
 
186
197
  # called during clone or dup. makes the clone/dup deeper.
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ActiveScaffold::DataStructures::Actions
2
4
  include Enumerable
3
5
 
4
- def initialize(*args)
6
+ def initialize(*)
5
7
  @set = []
6
- add(*args)
8
+ add(*)
7
9
  end
8
10
 
9
11
  def exclude(*args)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::DataStructures::Association
2
4
  class Abstract
3
5
  def initialize(association)
@@ -24,11 +26,11 @@ module ActiveScaffold::DataStructures::Association
24
26
  @association.macro == :belongs_to
25
27
  end
26
28
 
27
- def has_one? # rubocop:disable Naming/PredicateName
29
+ def has_one? # rubocop:disable Naming/PredicatePrefix
28
30
  @association.macro == :has_one
29
31
  end
30
32
 
31
- def has_many? # rubocop:disable Naming/PredicateName
33
+ def has_many? # rubocop:disable Naming/PredicatePrefix
32
34
  @association.macro == :has_many
33
35
  end
34
36
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::DataStructures::Association
2
4
  class ActiveMongoid < Mongoid
3
5
  def self.reflect_on_all_associations(klass)
@@ -26,11 +28,11 @@ module ActiveScaffold::DataStructures::Association
26
28
  %i[belongs_to_record belongs_to_document].include?(@association.macro)
27
29
  end
28
30
 
29
- def has_one? # rubocop:disable Naming/PredicateName
31
+ def has_one? # rubocop:disable Naming/PredicatePrefix
30
32
  %i[has_one_record has_one_document].include?(@association.macro)
31
33
  end
32
34
 
33
- def has_many? # rubocop:disable Naming/PredicateName
35
+ def has_many? # rubocop:disable Naming/PredicatePrefix
34
36
  %i[has_many_records has_many_documents].include?(@association.macro)
35
37
  end
36
38
 
@@ -1,19 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::DataStructures::Association
2
4
  class ActiveRecord < Abstract
3
5
  def self.reflect_on_all_associations(klass)
4
6
  klass.reflect_on_all_associations
5
7
  end
6
8
 
7
- delegate :collection?, :polymorphic?, :association_primary_key, :foreign_type, :table_name, to: :@association
9
+ delegate :collection?, :polymorphic?, :association_primary_key, :foreign_type, :table_name, :nested?, :scope, to: :@association
8
10
 
9
11
  def through?
10
12
  @association.options[:through].present?
11
13
  end
12
14
 
13
- def nested?
14
- @association.nested?
15
- end
16
-
17
15
  def readonly?
18
16
  scope_values[:readonly]
19
17
  end
@@ -26,10 +24,6 @@ module ActiveScaffold::DataStructures::Association
26
24
  @association.source_reflection if through?
27
25
  end
28
26
 
29
- def scope
30
- @association.scope
31
- end
32
-
33
27
  def inverse_klass
34
28
  @association.active_record
35
29
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveScaffold::DataStructures::Association
2
4
  class Mongoid < Abstract
3
5
  delegate :inverse_klass, :as, :dependent, :inverse, to: :@association
@@ -7,11 +9,11 @@ module ActiveScaffold::DataStructures::Association
7
9
  defined?(::Mongoid::Association) ? macro_mapping?(:belongs_to) : super
8
10
  end
9
11
 
10
- def has_one? # rubocop:disable Naming/PredicateName
12
+ def has_one? # rubocop:disable Naming/PredicatePrefix
11
13
  defined?(::Mongoid::Association) ? macro_mapping?(:has_one) : super
12
14
  end
13
15
 
14
- def has_many? # rubocop:disable Naming/PredicateName
16
+ def has_many? # rubocop:disable Naming/PredicatePrefix
15
17
  defined?(::Mongoid::Association) ? macro_mapping?(:has_many) : super
16
18
  end
17
19