dry_crud 6.0.0 → 8.0.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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +2 -2
  3. data/README.rdoc +7 -6
  4. data/VERSION +1 -1
  5. data/app/assets/stylesheets/sample.scss +45 -24
  6. data/app/controllers/crud_controller.rb +24 -26
  7. data/app/controllers/dry_crud/generic_model.rb +6 -12
  8. data/app/controllers/dry_crud/nestable.rb +1 -4
  9. data/app/controllers/dry_crud/rememberable.rb +1 -4
  10. data/app/controllers/dry_crud/render_callbacks.rb +4 -12
  11. data/app/controllers/dry_crud/searchable.rb +3 -10
  12. data/app/controllers/dry_crud/sortable.rb +3 -10
  13. data/app/controllers/list_controller.rb +1 -3
  14. data/app/helpers/actions_helper.rb +13 -15
  15. data/app/helpers/dry_crud/form/builder.rb +56 -62
  16. data/app/helpers/dry_crud/form/control.rb +12 -19
  17. data/app/helpers/dry_crud/table/actions.rb +15 -20
  18. data/app/helpers/dry_crud/table/builder.rb +12 -15
  19. data/app/helpers/dry_crud/table/col.rb +5 -8
  20. data/app/helpers/dry_crud/table/sorting.rb +3 -6
  21. data/app/helpers/form_helper.rb +11 -15
  22. data/app/helpers/format_helper.rb +18 -20
  23. data/app/helpers/i18n_helper.rb +13 -15
  24. data/app/helpers/table_helper.rb +16 -19
  25. data/app/helpers/utility_helper.rb +12 -14
  26. data/app/views/crud/new.html.erb +1 -1
  27. data/app/views/crud/new.html.haml +1 -1
  28. data/app/views/layouts/application.html.erb +8 -6
  29. data/app/views/layouts/application.html.haml +6 -5
  30. data/app/views/list/_search.html.erb +1 -3
  31. data/app/views/list/_search.html.haml +1 -2
  32. data/app/views/shared/_error_messages.html.erb +2 -2
  33. data/lib/dry_crud/engine.rb +1 -3
  34. data/lib/dry_crud.rb +1 -1
  35. data/lib/generators/dry_crud/dry_crud_generator.rb +18 -18
  36. data/lib/generators/dry_crud/dry_crud_generator_base.rb +8 -8
  37. data/lib/generators/dry_crud/file_generator.rb +6 -6
  38. data/lib/generators/dry_crud/templates/config/initializers/field_error_proc.rb +1 -1
  39. data/lib/generators/dry_crud/templates/spec/controllers/crud_test_models_controller_spec.rb +122 -122
  40. data/lib/generators/dry_crud/templates/spec/helpers/dry_crud/form/builder_spec.rb +55 -60
  41. data/lib/generators/dry_crud/templates/spec/helpers/dry_crud/table/builder_spec.rb +24 -26
  42. data/lib/generators/dry_crud/templates/spec/helpers/form_helper_spec.rb +16 -18
  43. data/lib/generators/dry_crud/templates/spec/helpers/format_helper_spec.rb +90 -94
  44. data/lib/generators/dry_crud/templates/spec/helpers/i18n_helper_spec.rb +33 -34
  45. data/lib/generators/dry_crud/templates/spec/helpers/table_helper_spec.rb +59 -61
  46. data/lib/generators/dry_crud/templates/spec/helpers/utility_helper_spec.rb +20 -23
  47. data/lib/generators/dry_crud/templates/spec/support/crud_controller_examples.rb +66 -68
  48. data/lib/generators/dry_crud/templates/spec/support/crud_controller_test_helper.rb +11 -13
  49. data/lib/generators/dry_crud/templates/test/controllers/crud_test_models_controller_test.rb +63 -65
  50. data/lib/generators/dry_crud/templates/test/helpers/custom_assertions_test.rb +25 -27
  51. data/lib/generators/dry_crud/templates/test/helpers/dry_crud/form/builder_test.rb +74 -74
  52. data/lib/generators/dry_crud/templates/test/helpers/dry_crud/table/builder_test.rb +21 -21
  53. data/lib/generators/dry_crud/templates/test/helpers/form_helper_test.rb +21 -23
  54. data/lib/generators/dry_crud/templates/test/helpers/format_helper_test.rb +68 -70
  55. data/lib/generators/dry_crud/templates/test/helpers/i18n_helper_test.rb +26 -28
  56. data/lib/generators/dry_crud/templates/test/helpers/table_helper_test.rb +28 -30
  57. data/lib/generators/dry_crud/templates/test/helpers/utility_helper_test.rb +17 -19
  58. data/lib/generators/dry_crud/templates/test/support/crud_controller_test_helper.rb +13 -15
  59. data/lib/generators/dry_crud/templates/test/support/crud_test_helper.rb +15 -19
  60. data/lib/generators/dry_crud/templates/test/support/crud_test_model.rb +9 -14
  61. data/lib/generators/dry_crud/templates/test/support/crud_test_models_controller.rb +16 -20
  62. data/lib/generators/dry_crud/templates/test/support/custom_assertions.rb +8 -10
  63. metadata +9 -10
@@ -7,7 +7,6 @@
7
7
  # Furthermore, it remembers the last search and sort parameters after the
8
8
  # user returns from a displayed or edited entry.
9
9
  class ListController < ApplicationController
10
-
11
10
  include DryCrud::GenericModel
12
11
  prepend DryCrud::Nestable
13
12
  include DryCrud::RenderCallbacks
@@ -32,7 +31,7 @@ class ListController < ApplicationController
32
31
  # Helper method to access the entries to be displayed in the current index
33
32
  # page in an uniform way.
34
33
  def entries
35
- model_ivar_get(true) || model_ivar_set(list_entries)
34
+ model_ivar_get(plural: true) || model_ivar_set(list_entries)
36
35
  end
37
36
 
38
37
  # The base relation used to filter the entries.
@@ -48,5 +47,4 @@ class ListController < ApplicationController
48
47
  # Include these modules after the #list_entries method is defined.
49
48
  include DryCrud::Searchable
50
49
  include DryCrud::Sortable
51
-
52
50
  end
@@ -3,19 +3,18 @@
3
3
  # of action links, change the method #action_link, e.g. to generate a button.
4
4
  # The common crud actions show, edit, destroy, index and add are provided here.
5
5
  module ActionsHelper
6
-
7
6
  # A generic helper method to create action links.
8
7
  # These link could be styled to look like buttons, for example.
9
8
  def action_link(label, icon = nil, url = {}, html_options = {})
10
- add_css_class html_options, 'action btn btn-light'
9
+ add_css_class html_options, "action btn btn-light"
11
10
  link_to(icon ? action_icon(icon, label) : label,
12
11
  url, html_options)
13
12
  end
14
13
 
15
14
  # Outputs an icon for an action with an optional label.
16
15
  def action_icon(icon, label = nil)
17
- html = content_tag(:span, '', class: "icon icon-#{icon}")
18
- html << ' ' << label if label
16
+ html = tag.i("", class: "bi-#{icon}")
17
+ html << " " << label if label
19
18
  html
20
19
  end
21
20
 
@@ -23,40 +22,39 @@ module ActionsHelper
23
22
  # Uses the current +entry+ if no path is given.
24
23
  def show_action_link(path = nil)
25
24
  path ||= path_args(entry)
26
- action_link(ti('link.show'), 'zoom-in', path)
25
+ action_link(ti("link.show"), "zoom-in", path)
27
26
  end
28
27
 
29
28
  # Standard edit action to given path.
30
29
  # Uses the current +entry+ if no path is given.
31
30
  def edit_action_link(path = nil)
32
31
  path ||= path_args(entry)
33
- path = path.is_a?(String) ? path : edit_polymorphic_path(path)
34
- action_link(ti('link.edit'), 'pencil', path)
32
+ path = edit_polymorphic_path(path) unless path.is_a?(String)
33
+ action_link(ti("link.edit"), "pencil", path)
35
34
  end
36
35
 
37
36
  # Standard destroy action to the given path.
38
37
  # Uses the current +entry+ if no path is given.
39
38
  def destroy_action_link(path = nil)
40
39
  path ||= path_args(entry)
41
- action_link(ti('link.delete'), 'remove', path,
42
- data: { confirm: ti(:confirm_delete),
43
- method: :delete })
40
+ action_link(ti("link.delete"), "trash", path,
41
+ data: { 'turbo-confirm': ti(:confirm_delete),
42
+ 'turbo-method': :delete })
44
43
  end
45
44
 
46
45
  # Standard list action to the given path.
47
46
  # Uses the current +model_class+ if no path is given.
48
47
  def index_action_link(path = nil, url_options = { returning: true })
49
48
  path ||= path_args(model_class)
50
- path = path.is_a?(String) ? path : polymorphic_path(path, url_options)
51
- action_link(ti('link.list'), 'list', path)
49
+ path = polymorphic_path(path, url_options) unless path.is_a?(String)
50
+ action_link(ti("link.list"), "list", path)
52
51
  end
53
52
 
54
53
  # Standard add action to given path.
55
54
  # Uses the current +model_class+ if no path is given.
56
55
  def add_action_link(path = nil, url_options = {})
57
56
  path ||= path_args(model_class)
58
- path = path.is_a?(String) ? path : new_polymorphic_path(path, url_options)
59
- action_link(ti('link.add'), 'plus', path)
57
+ path = new_polymorphic_path(path, url_options) unless path.is_a?(String)
58
+ action_link(ti("link.add"), "plus", path)
60
59
  end
61
-
62
60
  end
@@ -1,6 +1,5 @@
1
1
  module DryCrud
2
2
  module Form
3
-
4
3
  # A form builder that automatically selects the corresponding input field
5
4
  # for ActiveRecord column types. Convenience methods for each column type
6
5
  # allow one to customize the different fields.
@@ -14,14 +13,13 @@ module DryCrud
14
13
  # See the Control class for how to customize the html rendered for a
15
14
  # single input field.
16
15
  class Builder < ActionView::Helpers::FormBuilder
17
-
18
16
  class_attribute :control_class
19
17
  self.control_class = Control
20
18
 
21
19
  attr_reader :template
22
20
 
23
21
  delegate :association, :column_type, :column_property, :captionize,
24
- :ti, :ta, :link_to, :content_tag, :safe_join, :capture,
22
+ :ti, :ta, :link_to, :tag, :safe_join, :capture,
25
23
  :add_css_class, :assoc_and_id_attr,
26
24
  to: :template
27
25
 
@@ -29,9 +27,8 @@ module DryCrud
29
27
 
30
28
  # Render multiple input controls together with a label for the given
31
29
  # attributes.
32
- def labeled_input_fields(*attrs)
33
- options = attrs.extract_options!
34
- safe_join(attrs) { |a| labeled_input_field(a, options.dup) }
30
+ def labeled_input_fields(*attrs, **options)
31
+ safe_join(attrs) { |a| labeled_input_field(a, **options.dup) }
35
32
  end
36
33
 
37
34
  # Render a corresponding input control and label for the given attribute.
@@ -45,8 +42,8 @@ module DryCrud
45
42
  # * <tt>:field_method</tt> - Different method to create the input field.
46
43
  #
47
44
  # Use additional html_options for the input element.
48
- def labeled_input_field(attr, html_options = {})
49
- control_class.new(self, attr, html_options).render_labeled
45
+ def labeled_input_field(attr, **html_options)
46
+ control_class.new(self, attr, **html_options).render_labeled
50
47
  end
51
48
 
52
49
  # Render a corresponding input control for the given attribute.
@@ -59,22 +56,22 @@ module DryCrud
59
56
  # * <tt>:field_method</tt> - Different method to create the input field.
60
57
  #
61
58
  # Use additional html_options for the input element.
62
- def input_field(attr, html_options = {})
63
- control_class.new(self, attr, html_options).render_content
59
+ def input_field(attr, **html_options)
60
+ control_class.new(self, attr, **html_options).render_content
64
61
  end
65
62
 
66
63
  # Render a standard string field with column contraints.
67
- def string_field(attr, html_options = {})
64
+ def string_field(attr, **html_options)
68
65
  html_options[:maxlength] ||= column_property(@object, attr, :limit)
69
- text_field(attr, html_options)
66
+ text_field(attr, **html_options)
70
67
  end
71
68
 
72
69
  # Render a boolean field.
73
- def boolean_field(attr, html_options = {})
74
- content_tag(:div, class: 'checkbox') do
75
- content_tag(:label) do
76
- detail = html_options.delete(:detail) || '&nbsp;'.html_safe
77
- safe_join([check_box(attr, html_options), ' ', detail])
70
+ def boolean_field(attr, **html_options)
71
+ tag.div(class: "checkbox") do
72
+ tag.label do
73
+ detail = html_options.delete(:detail) || "&nbsp;".html_safe
74
+ safe_join([ check_box(attr, html_options), " ", detail ])
78
75
  end
79
76
  end
80
77
  end
@@ -82,33 +79,33 @@ module DryCrud
82
79
  # Add form-control class to all input fields.
83
80
  %w[text_field password_field email_field
84
81
  number_field date_field time_field datetime_field].each do |method|
85
- define_method(method) do |attr, html_options = {}|
86
- add_css_class(html_options, 'form-control')
82
+ define_method(method) do |attr, **html_options|
83
+ add_css_class(html_options, "form-control")
87
84
  super(attr, html_options)
88
85
  end
89
86
  end
90
87
 
91
- def integer_field(attr, html_options = {})
88
+ def integer_field(attr, **html_options)
92
89
  html_options[:step] ||= 1
93
- number_field(attr, html_options)
90
+ number_field(attr, **html_options)
94
91
  end
95
92
 
96
- def float_field(attr, html_options = {})
97
- html_options[:step] ||= 'any'
98
- number_field(attr, html_options)
93
+ def float_field(attr, **html_options)
94
+ html_options[:step] ||= "any"
95
+ number_field(attr, **html_options)
99
96
  end
100
97
 
101
- def decimal_field(attr, html_options = {})
98
+ def decimal_field(attr, **html_options)
102
99
  html_options[:step] ||=
103
100
  (10**-column_property(object, attr, :scale)).to_f
104
- number_field(attr, html_options)
101
+ number_field(attr, **html_options)
105
102
  end
106
103
 
107
104
  # Customize the standard text area to have 5 rows by default.
108
- def text_area(attr, html_options = {})
109
- add_css_class(html_options, 'form-control')
105
+ def text_area(attr, **html_options)
106
+ add_css_class(html_options, "form-control")
110
107
  html_options[:rows] ||= 5
111
- super(attr, html_options)
108
+ super
112
109
  end
113
110
 
114
111
  # Render a select element for a :belongs_to association defined by attr.
@@ -116,13 +113,13 @@ module DryCrud
116
113
  # To pass a custom element list, specify the list with the :list key or
117
114
  # define an instance variable with the pluralized name of the
118
115
  # association.
119
- def belongs_to_field(attr, html_options = {})
120
- list = association_entries(attr, html_options).to_a
116
+ def belongs_to_field(attr, **html_options)
117
+ list = association_entries(attr, **html_options).to_a
121
118
  if list.present?
122
- add_css_class(html_options, 'form-control')
119
+ add_css_class(html_options, "form-control")
123
120
  collection_select(attr, list, :id, :to_s,
124
- select_options(attr, html_options),
125
- html_options)
121
+ select_options(attr, **html_options),
122
+ **html_options)
126
123
  else
127
124
  # rubocop:disable Rails/OutputSafety
128
125
  none = ta(:none_available, association(@object, attr)).html_safe
@@ -131,7 +128,7 @@ module DryCrud
131
128
  end
132
129
  end
133
130
 
134
- # rubocop:disable PredicateName
131
+ # rubocop:disable Naming/PredicateName
135
132
 
136
133
  # Render a multi select element for a :has_many or
137
134
  # :has_and_belongs_to_many association defined by attr.
@@ -139,63 +136,62 @@ module DryCrud
139
136
  # To pass a custom element list, specify the list with the :list key or
140
137
  # define an instance variable with the pluralized name of the
141
138
  # association.
142
- def has_many_field(attr, html_options = {})
139
+ def has_many_field(attr, **html_options)
143
140
  html_options[:multiple] = true
144
- add_css_class(html_options, 'multiselect')
145
- belongs_to_field(attr, html_options)
141
+ add_css_class(html_options, "multiselect")
142
+ belongs_to_field(attr, **html_options)
146
143
  end
147
- # rubocop:enable PredicateName
144
+ # rubocop:enable Naming/PredicateName
148
145
 
149
146
  ### VARIOUS FORM ELEMENTS
150
147
 
151
148
  # Render the error messages for the current form.
152
149
  def error_messages
153
- @template.render('shared/error_messages',
150
+ @template.render("shared/error_messages",
154
151
  errors: @object.errors,
155
152
  object: @object)
156
153
  end
157
154
 
158
155
  # Renders the given content with an addon.
159
156
  def with_addon(content, addon)
160
- content_tag(:div, class: 'input-group') do
161
- html = content_tag(:span, addon, class: 'input-group-text')
162
- content + content_tag(:div, html, class: 'input-group-append')
157
+ tag.div(class: "input-group") do
158
+ content + tag.span(addon, class: "input-group-text")
163
159
  end
164
160
  end
165
161
 
166
162
  # Renders a static text where otherwise form inputs appear.
167
163
  def static_text(text)
168
- content_tag(:p, text, class: 'form-control-static')
164
+ tag.p(text, class: "form-control-static")
169
165
  end
170
166
 
171
167
  # Generates a help block for fields
172
168
  def help_block(text)
173
- content_tag(:p, text, class: 'help-block')
169
+ tag.p(text, class: "help-block")
174
170
  end
175
171
 
176
172
  # Render a submit button and a cancel link for this form.
177
- def standard_actions(submit_label = ti('button.save'), cancel_url = nil)
178
- content_tag(:div, class: 'col-md-offset-2 col-md-8') do
179
- safe_join([submit_button(submit_label),
180
- cancel_link(cancel_url)],
181
- ' ')
173
+ def standard_actions(submit_label = ti("button.save"), cancel_url = nil)
174
+ tag.div(class: "col-md-offset-2 col-md-8") do
175
+ safe_join([ submit_button(submit_label),
176
+ cancel_link(cancel_url) ],
177
+ " ")
182
178
  end
183
179
  end
184
180
 
185
181
  # Render a standard submit button with the given label.
186
- def submit_button(label = ti('button.save'))
187
- button(label, class: 'btn btn-primary', data: { disable_with: label })
182
+ def submit_button(label = ti("button.save"))
183
+ button(label, class: "btn btn-primary", data: { disable_with: label })
188
184
  end
189
185
 
190
186
  # Render a cancel link pointing to the given url.
191
187
  def cancel_link(url = nil)
192
188
  url ||= cancel_url
193
- link_to(ti('button.cancel'), url, class: 'cancel')
189
+ link_to(ti("button.cancel"), url, class: "cancel")
194
190
  end
195
191
 
196
192
  # Depending if the given attribute must be present, return
197
193
  # only an initial selection prompt or a blank option, respectively.
198
- def select_options(attr, options = {})
194
+ def select_options(attr, **options)
199
195
  prompt = options.delete(:prompt)
200
196
  blank = options.delete(:include_blank)
201
197
  if options[:multiple]
@@ -239,7 +235,7 @@ module DryCrud
239
235
  options = content
240
236
  content = capture(&block)
241
237
  end
242
- control = control_class.new(self, attr, options)
238
+ control = control_class.new(self, attr, **options)
243
239
  control.render_labeled(content)
244
240
  end
245
241
 
@@ -267,19 +263,18 @@ module DryCrud
267
263
  # Checks if the passed name corresponds to a field method with a
268
264
  # 'labeled_' prefix.
269
265
  def labeled_field_method?(name)
270
- prefix = 'labeled_'
266
+ prefix = "labeled_"
271
267
  if name.to_s.start_with?(prefix)
272
- field_method = name.to_s[prefix.size..-1]
268
+ field_method = name.to_s[prefix.size..]
273
269
  field_method if respond_to?(field_method)
274
270
  end
275
271
  end
276
272
 
277
273
  # Renders the corresponding field together with a label, required mark
278
274
  # and an optional help block.
279
- def build_labeled_field(field_method, *args)
280
- options = args.extract_options!
275
+ def build_labeled_field(field_method, *args, **options)
281
276
  options[:field_method] = field_method
282
- control_class.new(self, *(args << options)).render_labeled
277
+ control_class.new(self, *args, **options).render_labeled
283
278
  end
284
279
 
285
280
  # Returns the list of association entries, either from options[:list] or
@@ -287,7 +282,7 @@ module DryCrud
287
282
  # Otherwise, if the association defines a #options_list or #list scope,
288
283
  # this is used to load the entries.
289
284
  # As a last resort, all entries from the association class are returned.
290
- def association_entries(attr, options)
285
+ def association_entries(attr, **options)
291
286
  list = options.delete(:list)
292
287
  unless list
293
288
  assoc = association(@object, attr)
@@ -324,7 +319,6 @@ module DryCrud
324
319
  options[:cancel_url_edit] || options[:cancel_url]
325
320
  end
326
321
  end
327
-
328
322
  end
329
323
  end
330
324
  end
@@ -1,18 +1,16 @@
1
1
  module DryCrud
2
2
  module Form
3
-
4
3
  # Internal class to handle the rendering of a single form control,
5
4
  # consisting of a label, input field, addon, help text or
6
5
  # required mark.
7
6
  class Control
8
-
9
7
  attr_reader :builder, :attr, :args, :options, :addon, :help
10
8
 
11
- delegate :content_tag, :object,
9
+ delegate :tag, :object, :add_css_class,
12
10
  to: :builder
13
11
 
14
12
  # Html displayed to mark an input as required.
15
- REQUIRED_MARK = '*'.freeze
13
+ REQUIRED_MARK = "*".freeze
16
14
 
17
15
  # Number of default input field span columns depending
18
16
  # on the #field_method.
@@ -39,10 +37,10 @@ module DryCrud
39
37
  # (The value for this option usually is 'required').
40
38
  #
41
39
  # All the other options will go to the field_method.
42
- def initialize(builder, attr, *args)
40
+ def initialize(builder, attr, *args, **options)
43
41
  @builder = builder
44
42
  @attr = attr
45
- @options = args.extract_options!
43
+ @options = options
46
44
  @args = args
47
45
 
48
46
  @addon = options.delete(:addon)
@@ -70,11 +68,9 @@ module DryCrud
70
68
 
71
69
  # Create the HTML markup for any labeled content.
72
70
  def labeled
73
- errors = errors? ? ' has-error' : ''
74
-
75
- content_tag(:div, class: "form-group#{errors}") do
76
- builder.label(attr, caption, class: 'col-md-2 control-label') +
77
- content_tag(:div, content, class: "col-md-#{span}")
71
+ tag.div(class: "row mb-3") do
72
+ builder.label(attr, caption, class: "col-md-2 col-form-label") +
73
+ tag.div(content, class: "col-md-#{span}")
78
74
  end
79
75
  end
80
76
 
@@ -100,8 +96,9 @@ module DryCrud
100
96
  # depending on the attribute.
101
97
  def input
102
98
  @input ||= begin
103
- options[:required] = 'required' if required
104
- builder.send(field_method, attr, *(args << options))
99
+ options[:required] = "required" if required
100
+ add_css_class(options, "is-invalid") if errors?
101
+ builder.send(field_method, attr, *args, **options)
105
102
  end
106
103
  end
107
104
 
@@ -137,7 +134,6 @@ module DryCrud
137
134
 
138
135
  # Defines the field method to use based on the attribute
139
136
  # type, association or name.
140
- # rubocop:disable PerceivedComplexity
141
137
  def detect_field_method
142
138
  if type == :text
143
139
  :text_area
@@ -145,9 +141,9 @@ module DryCrud
145
141
  :belongs_to_field
146
142
  elsif association_kind?(:has_and_belongs_to_many, :has_many)
147
143
  :has_many_field
148
- elsif attr.to_s.include?('password')
144
+ elsif attr.to_s.include?("password")
149
145
  :password_field
150
- elsif attr.to_s.include?('email')
146
+ elsif attr.to_s.include?("email")
151
147
  :email_field
152
148
  elsif builder.respond_to?(:"#{type}_field")
153
149
  :"#{type}_field"
@@ -155,7 +151,6 @@ module DryCrud
155
151
  :text_field
156
152
  end
157
153
  end
158
- # rubocop:enable PerceivedComplexity
159
154
 
160
155
  # The column type of the attribute.
161
156
  def type
@@ -173,8 +168,6 @@ module DryCrud
173
168
  false
174
169
  end
175
170
  end
176
-
177
171
  end
178
-
179
172
  end
180
173
  end
@@ -1,12 +1,10 @@
1
1
  module DryCrud
2
2
  module Table
3
-
4
3
  # Adds action columns to the table builder.
5
4
  # Predefined actions are available for show, edit and destroy.
6
5
  # Additionally, a special col type to define cells linked to the show page
7
6
  # of the row entry is provided.
8
7
  module Actions
9
-
10
8
  extend ActiveSupport::Concern
11
9
 
12
10
  included do
@@ -26,13 +24,13 @@ module DryCrud
26
24
  # Action column to show the row entry.
27
25
  # A block may be given to define the link path for the row entry.
28
26
  # If the block returns nil, no link is rendered.
29
- def show_action_col(html_options = {}, &block)
27
+ def show_action_col(**html_options, &block)
30
28
  action_col do |entry|
31
29
  path = action_path(entry, &block)
32
30
  if path
33
- table_action_link('zoom-in',
31
+ table_action_link("zoom-in",
34
32
  path,
35
- html_options.clone)
33
+ **html_options.clone)
36
34
  end
37
35
  end
38
36
  end
@@ -40,12 +38,12 @@ module DryCrud
40
38
  # Action column to edit the row entry.
41
39
  # A block may be given to define the link path for the row entry.
42
40
  # If the block returns nil, no link is rendered.
43
- def edit_action_col(html_options = {}, &block)
41
+ def edit_action_col(**html_options, &block)
44
42
  action_col do |entry|
45
43
  path = action_path(entry, &block)
46
44
  if path
47
- path = path.is_a?(String) ? path : edit_polymorphic_path(path)
48
- table_action_link('pencil', path, html_options.clone)
45
+ path = edit_polymorphic_path(path) unless path.is_a?(String)
46
+ table_action_link("pencil", path, **html_options.clone)
49
47
  end
50
48
  end
51
49
  end
@@ -53,16 +51,15 @@ module DryCrud
53
51
  # Action column to destroy the row entry.
54
52
  # A block may be given to define the link path for the row entry.
55
53
  # If the block returns nil, no link is rendered.
56
- def destroy_action_col(html_options = {}, &block)
54
+ def destroy_action_col(**html_options, &block)
57
55
  action_col do |entry|
58
56
  path = action_path(entry, &block)
59
57
  if path
60
- table_action_link('remove',
58
+ table_action_link("trash",
61
59
  path,
62
- html_options.merge(
63
- data: { confirm: ti(:confirm_delete),
64
- method: :delete }
65
- ))
60
+ **html_options,
61
+ data: { 'turbo-confirm': ti(:confirm_delete),
62
+ 'turbo-method': :delete })
66
63
  end
67
64
  end
68
65
  end
@@ -70,13 +67,13 @@ module DryCrud
70
67
  # Action column inside a table. No header.
71
68
  # The cell content should be defined in the passed block.
72
69
  def action_col(&block)
73
- col('', class: 'action', &block)
70
+ col("", class: "action", &block)
74
71
  end
75
72
 
76
73
  # Generic action link inside a table.
77
- def table_action_link(icon, url, html_options = {})
78
- add_css_class(html_options, "icon icon-#{icon}")
79
- link_to('', url, html_options)
74
+ def table_action_link(icon, url, **html_options)
75
+ add_css_class(html_options, "bi-#{icon}")
76
+ link_to("", url, html_options)
80
77
  end
81
78
 
82
79
  private
@@ -86,8 +83,6 @@ module DryCrud
86
83
  def action_path(entry)
87
84
  block_given? ? yield(entry) : path_args(entry)
88
85
  end
89
-
90
86
  end
91
-
92
87
  end
93
88
  end
@@ -1,6 +1,5 @@
1
1
  module DryCrud
2
2
  module Table
3
-
4
3
  # A simple helper to easily define tables listing several rows of the same
5
4
  # data type.
6
5
  #
@@ -10,17 +9,16 @@ module DryCrud
10
9
  # t.attrs :name, :city
11
10
  # end
12
11
  class Builder
13
-
14
12
  include Sorting
15
13
  include Actions
16
14
 
17
15
  attr_reader :entries, :cols, :options, :template
18
16
 
19
- delegate :content_tag, :format_attr, :column_type, :association, :dom_id,
17
+ delegate :tag, :format_attr, :column_type, :association, :dom_id,
20
18
  :captionize, :add_css_class, :content_tag_nested,
21
19
  to: :template
22
20
 
23
- def initialize(entries, template, options = {})
21
+ def initialize(entries, template, **options)
24
22
  @entries = entries
25
23
  @template = template
26
24
  @options = options
@@ -30,8 +28,8 @@ module DryCrud
30
28
  # Convenience method to directly generate a table. Renders a row for each
31
29
  # entry in entries. Takes a block that gets the table object as parameter
32
30
  # for configuration. Returns the generated html for the table.
33
- def self.table(entries, template, options = {})
34
- t = new(entries, template, options)
31
+ def self.table(entries, template, **options)
32
+ t = new(entries, template, **options)
35
33
  yield t
36
34
  t.to_html
37
35
  end
@@ -39,7 +37,7 @@ module DryCrud
39
37
  # Define a column for the table with the given header, the html_options
40
38
  # used for each td and a block rendering the contents of a cell for the
41
39
  # current entry. The columns appear in the order they are defined.
42
- def col(header = '', html_options = {}, &block)
40
+ def col(header = "", **html_options, &block)
43
41
  @cols << Col.new(header, html_options, @template, block)
44
42
  end
45
43
 
@@ -55,17 +53,17 @@ module DryCrud
55
53
  # Define a column for the given attribute and an optional header.
56
54
  # If no header is given, the attribute name is used. The cell will
57
55
  # contain the formatted attribute value for the current entry.
58
- def attr(attr, header = nil, html_options = {}, &block)
56
+ def attr(attr, header = nil, **html_options, &block)
59
57
  header ||= attr_header(attr)
60
58
  block ||= ->(e) { format_attr(e, attr) }
61
59
  add_css_class(html_options, align_class(attr))
62
- col(header, html_options, &block)
60
+ col(header, **html_options, &block)
63
61
  end
64
62
 
65
63
  # Renders the table as HTML.
66
64
  def to_html
67
- content_tag :table, options do
68
- content_tag(:thead, html_header) +
65
+ tag.table(**options) do
66
+ tag.thead(html_header) +
69
67
  content_tag_nested(:tbody, entries) { |e| html_row(e) }
70
68
  end
71
69
  end
@@ -76,9 +74,9 @@ module DryCrud
76
74
  entry = entries.present? ? entry_class.new : nil
77
75
  case column_type(entry, attr)
78
76
  when :integer, :float, :decimal
79
- 'right' unless association(entry, attr, :belongs_to)
77
+ "right" unless association(entry, attr, :belongs_to)
80
78
  when :boolean
81
- 'center'
79
+ "center"
82
80
  end
83
81
  end
84
82
 
@@ -98,7 +96,7 @@ module DryCrud
98
96
  def html_row(entry)
99
97
  attrs = {}
100
98
  attrs[:id] = dom_id(entry) if entry.respond_to?(:to_key)
101
- content_tag_nested(:tr, cols, attrs) { |c| c.html_cell(entry) }
99
+ content_tag_nested(:tr, cols, **attrs) { |c| c.html_cell(entry) }
102
100
  end
103
101
 
104
102
  # Determines the class of the table entries.
@@ -110,7 +108,6 @@ module DryCrud
110
108
  entries.first.class
111
109
  end
112
110
  end
113
-
114
111
  end
115
112
  end
116
113
  end