custom_table 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +210 -0
  3. data/Rakefile +8 -0
  4. data/app/assets/config/custom_table_manifest.js +1 -0
  5. data/app/assets/stylesheets/custom_table/application.scss +1 -0
  6. data/app/assets/stylesheets/custom_table/table.scss +89 -0
  7. data/app/controllers/concerns/custom_table_concern.rb +118 -0
  8. data/app/controllers/custom_table/application_controller.rb +4 -0
  9. data/app/controllers/custom_table/settings_controller.rb +86 -0
  10. data/app/helpers/custom_table/application_helper.rb +483 -0
  11. data/app/helpers/custom_table/fieldset_helper.rb +90 -0
  12. data/app/helpers/custom_table/icons_helper.rb +42 -0
  13. data/app/inputs/date_picker_input.rb +52 -0
  14. data/app/javascript/controllers/batch_actions_controller.js +53 -0
  15. data/app/javascript/controllers/table_controller.js +109 -0
  16. data/app/jobs/custom_table/application_job.rb +4 -0
  17. data/app/mailers/custom_table/application_mailer.rb +6 -0
  18. data/app/models/concerns/custom_table_settings.rb +42 -0
  19. data/app/models/custom_table/application_record.rb +5 -0
  20. data/app/views/custom_table/_download.haml +19 -0
  21. data/app/views/custom_table/_field.haml +8 -0
  22. data/app/views/custom_table/_field_plain.haml +1 -0
  23. data/app/views/custom_table/_fieldset.haml +2 -0
  24. data/app/views/custom_table/_filter.html.haml +104 -0
  25. data/app/views/custom_table/_settings.html.haml +57 -0
  26. data/app/views/custom_table/_table.html.haml +261 -0
  27. data/app/views/custom_table/_table.xlsx.axlsx +76 -0
  28. data/app/views/custom_table/_table_fe.xlsx.fast_excel +141 -0
  29. data/app/views/custom_table/_table_row.html.haml +72 -0
  30. data/app/views/custom_table/_table_row_data.html.haml +26 -0
  31. data/app/views/custom_table/settings/destroy.html.haml +4 -0
  32. data/app/views/custom_table/settings/edit.html.haml +2 -0
  33. data/app/views/custom_table/settings/update.html.haml +4 -0
  34. data/app/views/layouts/custom_table/application.html.erb +15 -0
  35. data/config/initializers/simple_form_bootstrap.rb +468 -0
  36. data/config/locales/en.yml +18 -0
  37. data/config/locales/ru.yml +18 -0
  38. data/config/routes.rb +5 -0
  39. data/lib/custom_table/configuration.rb +10 -0
  40. data/lib/custom_table/engine.rb +12 -0
  41. data/lib/custom_table/version.rb +3 -0
  42. data/lib/custom_table.rb +14 -0
  43. data/lib/generators/custom_table/USAGE +8 -0
  44. data/lib/generators/custom_table/custom_table_generator.rb +16 -0
  45. data/lib/generators/custom_table/templates/initializer.rb +3 -0
  46. data/lib/generators/custom_table/templates/migration.rb +5 -0
  47. data/lib/tasks/custom_table_tasks.rake +4 -0
  48. metadata +300 -0
@@ -0,0 +1,261 @@
1
+ - model_class = local_assigns[:model_class].presence || collection.model
2
+ - global_model_name = model_class.model_name.singular
3
+ - fields_totals = {}
4
+ - variant = local_assigns[:variant]
5
+ - if local_assigns[:tree] && local_assigns[:paginate]
6
+ %p.text-danger Tree mode is incompartible with pagination
7
+
8
+ - if collection.respond_to?(:model)
9
+ - customization = custom_table_user_customization_for(collection.model, variant)
10
+ - per_page = params[:per] || customization&.dig(:per_page).presence || 25
11
+ - collection = collection.page(params[:page]).per(per_page) if local_assigns[:paginate]
12
+ - collection = collection.without_count if !local_assigns[:last_page] # Disable Last Page for performance
13
+
14
+ - local_assigns[:fields] = params[:fields].split(",").map { |x| x.to_sym } if local_assigns[:fields].nil? && !params[:fields].blank?
15
+ - local_assigns[:skip_actions] = true if local_assigns[:skip_actions].nil? && params[:skip_actions].to_s=="true"
16
+
17
+ - fields = custom_table_fields_for(model_class, variant: variant, predefined_fields: local_assigns[:fields])
18
+
19
+ - fields = fields.except(*local_assigns[:skip_fields]) if !local_assigns[:skip_fields].nil?
20
+
21
+ %div.table-wrapper{data: {controller: "batch-actions"}}
22
+
23
+ - if local_assigns[:batch_actions]
24
+ = self.send(local_assigns[:batch_actions])
25
+
26
+ %table{class: ["search-fields", "custom-table", "table", "table-hover", "table-sm", model_class.model_name.plural], data: {controller: "table toggle"}}
27
+ %thead.sticky
28
+ - if local_assigns[:quick_filter]
29
+ %tr
30
+ %td{colspan: "100%"}
31
+ .input-group.input-group-sm
32
+ .input-group-text
33
+ = custom_table_search_icon
34
+ %input.form-control-sm.form-control{type: "text", data: {action: "table#search"}, placeholder: t("custom_table.quick_search")}
35
+
36
+
37
+ %tr
38
+
39
+ - if local_assigns[:tree]
40
+ %th{style: "width: 15px;"}
41
+
42
+ - if local_assigns[:with_select]
43
+ %th.checkbox-col
44
+ = check_box_tag "check-all", "", true, data: {"toggle-target": "toggler", "action": "toggle#toggle batch-actions#refresh"}
45
+ - if local_assigns[:with_index]
46
+ %th= "#"
47
+ - fields.each do |field, defs|
48
+ - next if defs[:table] == false
49
+ - cls = [field.to_s]
50
+ - defs[:amount] = true if defs[:amount].nil? && !model_class.columns_hash[field.to_s].nil? && [:float, :decimal, :integer].include?(model_class.columns_hash[field.to_s].type) && !model_class.defined_enums.has_key?(field.to_s)
51
+ - cls += ["text-end"] if defs[:amount]
52
+ %th{class: cls}
53
+ - if !defs[:sort].nil? && !@q.nil?
54
+ - defs[:sort] = {} if defs[:sort]===true
55
+ - sort_field = defs[:sort][:field].blank? ? field : defs[:sort][:field]
56
+ - sort_order = defs[:sort][:default_order].blank? ? :asc : defs[:sort][:default_order]
57
+ - if !@q.nil?
58
+ = sort_link @q, sort_field, default_order: sort_order, data: {sort: "custom-table-sort-#{sort_field}-#{sort_order}"} do
59
+ = defs[:label].nil? ? model_class.human_attribute_name(field) : defs[:label]
60
+ - else
61
+ = defs[:label].nil? ? model_class.human_attribute_name(field) : defs[:label]
62
+
63
+ - if !local_assigns[:skip_actions]
64
+ %th.text-end
65
+
66
+ %tbody
67
+
68
+ - position = 0
69
+
70
+ - if local_assigns[:tree]
71
+
72
+ - if collection.length > 0
73
+
74
+ - grouped_collection = collection.group_by{|i| i.parent_id}
75
+
76
+ - if !grouped_collection[nil].nil?
77
+
78
+ - grouped_collection[nil].each do |parent_item|
79
+
80
+ - childs = grouped_collection[parent_item.id] || []
81
+
82
+ = render "custom_table/table_row", local_assigns.merge({item: parent_item, fields: fields, position: position, fields_totals: fields_totals, has_children: (childs.length > 0)})
83
+ - position+=1
84
+
85
+ - childs.each do |item|
86
+ - position+=1
87
+ = render "custom_table/table_row", local_assigns.merge({item: item, fields: fields, position: position, fields_totals: fields_totals})
88
+
89
+ - elsif local_assigns[:group_by]
90
+
91
+ - if collection.length > 0
92
+
93
+ - grouped_collection = collection.group_by{|i| self.send(local_assigns[:group_by], i)}
94
+
95
+ -# - (grouped_collection[nil] || []).each do |ungrouped_items|
96
+ -# - ungrouped_items.each do |item|
97
+ -# - position+=1
98
+ -# = render "custom_table/table_row", local_assigns.merge({item: item, fields: fields, position: position, fields_totals: fields_totals})
99
+
100
+ -# - abort Hash[grouped_collection.sort_by{|k,v| k.to_s}].inspect
101
+
102
+ - group_id = 0
103
+
104
+ - Hash[grouped_collection.sort_by{|k,v| k.to_s}].each do |group, items|
105
+
106
+ - if !group.nil?
107
+
108
+ - group_id += 1
109
+
110
+ -# Calculating group totals
111
+ - group_fields_totals = {}
112
+
113
+ - items.each do |item|
114
+ - custom_table_fields_totals(fields: fields, item: item, totals: local_assigns[:totals], variant: variant, fields_totals: group_fields_totals)
115
+ %tr
116
+ - shown = false
117
+ - fields.each do |field, defs|
118
+ - next if defs[:table] == false
119
+ - if !group_fields_totals[field].nil?
120
+ %th{class: [field.to_s, "text-end"]}
121
+ = amount_color group_fields_totals[field]
122
+ - else
123
+ %th{class: [field.to_s, "text-start"]}
124
+ - if !shown
125
+ = tree_opener(group_id, true, local_assigns[:expanded])
126
+ = group
127
+ - shown = true
128
+ - if !local_assigns[:skip_actions]
129
+ %th.text-end
130
+
131
+ - items.each do |item|
132
+ - position+=1
133
+ = render "custom_table/table_row", local_assigns.merge({item: item, fields: fields, position: position, fields_totals: fields_totals, grouped_by_id: group_id})
134
+
135
+ - else
136
+
137
+ - collection.each do |item|
138
+
139
+ - position+=1
140
+
141
+ = render "custom_table/table_row", local_assigns.merge({item: item, fields: fields, position: position, fields_totals: fields_totals})
142
+
143
+ -# - model_name = item.model_name.singular # Allows to show different class models in one table!
144
+ -# -# = render partial: "custom_tables/table_row", locals: local_assigns.merge(item: item, position: position, fields: fields, fields_totals: fields_totals)
145
+ -# - row_class = local_assigns[:row_class] || "#{model_name}_row_class"
146
+ -# %tr{id: dom_id(item, "row"), :class => (self.send(row_class, item) rescue "")}
147
+
148
+ -# - if local_assigns[:with_select]
149
+ -# %td.checkbox-col
150
+ -# = self.send(local_assigns[:with_select], item, position)
151
+
152
+ -# - if local_assigns[:with_index]
153
+ -# %td
154
+ -# = position
155
+
156
+ -# - fields.each do |field, defs|
157
+ -# - next if defs[:table] == false
158
+ -# - td_classes = [field.to_s]
159
+ -# - td_classes += ["text-end"] if defs[:amount]
160
+ -# - td_classes += ["text-nowrap"] if defs[:nowrap]
161
+ -# - td_classes += ["amount"] if defs[:amount]
162
+
163
+ -# %td{class: td_classes, id: dom_id(item, field)}
164
+ -# - v = field_value_for(item, field, definitions: defs, variant: variant)
165
+
166
+ -# - if totals.has_key?(field) && totals[field].nil? # Auto-counting
167
+ -# - fields_totals[field] = 0 if fields_totals[field].nil?
168
+ -# - fields_totals[field] += raw_field_value_for(item, field, definitions: defs, variant: variant).to_f rescue 0
169
+
170
+ -# - if defs[:editable]
171
+
172
+ -# = editable item, field do
173
+ -# - if defs[:link_to_show] == true && custom_table_has_show_route?(item) && can?(:show, item)
174
+ -# -# = link_to v, url_for(controller: controller_name, action: "show", id: item.to_param)
175
+ -# = link_to v, [namespace, item], data: {turbo: false}
176
+ -# - else
177
+ -# = v
178
+ -# - else
179
+ -# - if defs[:link_to_show] == true && custom_table_has_show_route?(item) && can?(:show, item)
180
+ -# -# = link_to v, url_for(controller: controller_name, action: "show", id: item.to_param)
181
+ -# = link_to v, [namespace, item], data: {turbo: false}
182
+ -# - else
183
+ -# = v
184
+
185
+ -# - if !local_assigns[:skip_actions]
186
+
187
+ -# %td.text-end.actions
188
+ -# - if !local_assigns[:actions].nil?
189
+ -# = self.send(local_assigns[:actions], item)
190
+ -# - elsif !variant.nil? && self.class.method_defined?("#{variant}_#{model_name}_custom_table_actions")
191
+ -# = self.send("#{variant}_#{model_name}_custom_table_actions", item)
192
+ -# - elsif self.class.method_defined?("#{model_name}_custom_table_actions")
193
+ -# = self.send("#{model_name}_custom_table_actions", item)
194
+ -# - if local_assigns[:skip_default_actions].nil?
195
+ -# - if (!custom_table_has_show_route?(item) || local_assigns[:force_edit_button]) && can?(:update, item)
196
+ -# = custom_table_edit_button [:edit, namespace, local_assigns[:parent], item], id: "edit_#{item.model_name.singular}_#{item.id}", modal: local_assigns[:modal_edit]
197
+ -# - if can? :destroy, item
198
+ -# - if (Rails.application.routes.recognize_path(url_for([namespace, local_assigns[:parent], item]), :method => :delete) rescue false)
199
+ -# = custom_table_delete_button [namespace, local_assigns[:parent], item], id: "destroy_#{item.model_name.singular}_#{item.id}"
200
+
201
+ - if local_assigns.has_key?(:extra) && !extra.nil?
202
+ - extra.each do |er|
203
+ %tr
204
+ - fields.each do |field, defs|
205
+ - next if defs[:table] == false
206
+ %td{class: [field.to_s]}
207
+ = er[field]
208
+ %td
209
+
210
+ - if collection.length == 0
211
+ %tr.warning.text-center
212
+ %th{:colspan=>"100%"}= t("custom_table.no_records_found")
213
+ - else
214
+
215
+ - found_totals = custom_table_totals(collection, fields, local_assigns[:totals], fields_totals)
216
+
217
+ - if !found_totals.empty?
218
+
219
+ %tr.totals{data: {"table-target": "move"}}
220
+ - if local_assigns[:tree]
221
+ %th
222
+
223
+ - if local_assigns[:with_index]
224
+ %th
225
+
226
+ - if local_assigns[:with_select]
227
+ %th
228
+
229
+ - fields.each do |field, defs|
230
+ - next if defs[:table] == false
231
+ %th{class: [field.to_s, "text-end"]}
232
+ - if !found_totals[field].nil?
233
+ - if found_totals[field].is_a?(Numeric)
234
+ = amount_color found_totals[field]
235
+ - else
236
+ = found_totals[field]
237
+ %th.text-end
238
+
239
+ - if collection.respond_to? :total_pages
240
+ .custom-table-pagination.overflow-hidden
241
+ -# - if turbo_frame_request?
242
+ -# - if !collection.last_page?
243
+ -# = link_to_next_page collection, raw(t('views.pagination.next'))
244
+ -# - else
245
+
246
+ - begin
247
+ - if collection.total_count > 25
248
+ %nav.float-end.ms-2
249
+ %ul.pagination
250
+ - [25, 50, 100].each do |p|
251
+ %li.page-item{class: (collection.limit_value.to_i == p) ? "active" : ""}
252
+ = link_to p, url_for(params.permit!.merge({per: p})), class: "page-link"
253
+
254
+ = paginate(collection, theme: 'bootstrap-5')
255
+ - rescue
256
+ = link_to_prev_page collection, t("views.pagination.previous").html_safe, class: "btn btn-outline-primary"
257
+ = link_to_next_page collection, t("views.pagination.next").html_safe, class: "btn btn-outline-primary"
258
+
259
+ -# - "TODO: Remove with param"
260
+ -# - if false && turbo_frame_request? && params[:q].present?
261
+ -# = link_to t("show_all"), url_for(q: params[:q]), data: {turbo: false}, class: "text-right"
@@ -0,0 +1,76 @@
1
+ global_model_name = collection.model.model_name.singular
2
+
3
+ sheet.add_row []
4
+
5
+ if local_assigns[:fields].nil?
6
+ fields = custom_table_fields_definition_for(collection.model)
7
+ else
8
+ d = custom_table_fields_definition_for(collection.model)
9
+ fields = {}
10
+ local_assigns[:fields].each do |f|
11
+ found = d.find {|k, v| k == f }
12
+ fields[f] = found[1] if !found.nil?
13
+ end
14
+ end
15
+
16
+ if defined?(style)
17
+ unless defined?(aligned_style)
18
+ aligned_style = style.add_style alignment: { horizontal: :left }
19
+ end
20
+ unless defined?(date_style)
21
+ date_style = style.add_style(format_code: 'dd.mm.yyyy', alignment: { horizontal: :left })
22
+ end
23
+
24
+ unless defined?(head_style)
25
+ head_style = s.add_style b: true, alignment: { horizontal: :left }
26
+ end
27
+ end
28
+
29
+ head = []
30
+ fields.each do |field, defs|
31
+ next if defs[:table] == false
32
+
33
+ head.push defs[:label].nil? ? collection.model.human_attribute_name(field) : defs[:label]
34
+ end
35
+
36
+ if defined?(extra_head)
37
+ head += extra_head.call
38
+ end
39
+
40
+ sheet.add_row(head, style: head_style)
41
+
42
+ collection.except(:limit, :offset).find_each do |item|
43
+ row_def = []
44
+ row = []
45
+ style_def = []
46
+
47
+ model_name = item.model_name.singular # Allows to show different class models in one table!
48
+
49
+ fields.each do |field, defs|
50
+ next if defs[:table] == false
51
+
52
+ value = raw_field_value_for(item, field)
53
+ val_def = nil
54
+ val_style = aligned_style
55
+
56
+ if [Date, ActiveSupport::TimeWithZone].include?(value.class)
57
+ value = value.to_date
58
+ val_def = :date
59
+ val_style = date_style if defined?(date_style)
60
+ end
61
+
62
+ if [String].include?(value.class)
63
+ val_def = :string
64
+ end
65
+
66
+ row.push value
67
+ row_def.push val_def
68
+ style_def.push val_style
69
+ end
70
+
71
+ if defined?(extra_cols)
72
+ row += extra_cols.call(item)
73
+ end
74
+
75
+ sheet.add_row(row, style: aligned_style, types: row_def)
76
+ end
@@ -0,0 +1,141 @@
1
+ global_model_name = collection.model.model_name.singular
2
+
3
+ if local_assigns[:fields].nil?
4
+ if params[:all_fields].to_s == "true"
5
+ fields = custom_table_fields_definition_for(collection.model, local_assigns[:variant])
6
+ else
7
+ fields = custom_table_fields_for(collection.model, variant: local_assigns[:variant], predefined_fields: local_assigns[:fields])
8
+ end
9
+ else
10
+ fields = custom_table_fields_list_to_definitions(collection.model, fields)
11
+ end
12
+
13
+ data_start_row = sheet.last_row_number+1
14
+ data_end_row = collection.length + data_start_row + 3
15
+
16
+ if !local_assigns[:totals].nil?
17
+ data_start_row+=1
18
+ total_vals = []
19
+ total_format = workbook.number_format("#,##0.00").set(bold: true, align: {h: :right, v: :center})
20
+
21
+ i = 0
22
+ fields.each do |field, defs|
23
+ if totals.has_key?(field)
24
+ if total_vals.compact.length == 0 && total_vals.length > 0
25
+ total_vals[-1] = "Total:"
26
+ end
27
+ col = ("A".."Z").to_a[i]
28
+ if totals[field] == nil
29
+ total_vals.push FastExcel::Formula.new("SUM(#{col}#{data_start_row+2}:#{col}#{data_end_row})")
30
+ else
31
+ total_vals.push totals[field]
32
+ end
33
+ else
34
+ total_vals.push nil
35
+ end
36
+ i+=1
37
+ end
38
+ # abort total_vals.inspect
39
+ sheet.append_row(total_vals, total_format)
40
+ sheet.set_row(sheet.last_row_number, 20, nil)
41
+
42
+ end
43
+
44
+
45
+ head = []
46
+ head_formats = []
47
+
48
+ fields.each do |field, defs|
49
+ next if defs[:table] == false
50
+ head.push defs[:label].nil? ? collection.model.human_attribute_name(field) : defs[:label]
51
+
52
+ if local_assigns[:head_format].nil?
53
+ head_format = workbook.bold_format
54
+ else
55
+ head_format = sheet.workbook.add_format(local_assigns[:head_format])
56
+ end
57
+
58
+ if !local_assigns[:column_formats].nil? && !local_assigns[:column_formats][field.to_sym].nil?
59
+ head_format.set(local_assigns[:column_formats][field.to_sym])
60
+ end
61
+ head_formats.push(head_format)
62
+ end
63
+
64
+ fields.keys.each_with_index do |key, i|
65
+ w = 15
66
+ sheet.set_column(i, i, w)
67
+ end
68
+
69
+ if defined?(extra_head)
70
+ head += extra_head.call
71
+ end
72
+
73
+ # sheet.set_row(row_num = 1, 15, )
74
+ sheet.append_row(head, head_formats)
75
+
76
+ column_formats = {}
77
+
78
+ iterator = "find_each" if local_assigns[:iterator].nil?
79
+
80
+ collection.except(:limit, :offset).send(iterator) do |item|
81
+
82
+ row = []
83
+ formats = []
84
+
85
+ model_name = item.model_name.singular # Allows to show different class models in one table!
86
+
87
+ fields.each do |field, defs|
88
+ next if defs[:table] == false
89
+
90
+ value = raw_field_value_for(item, field)
91
+
92
+ if column_formats[field].nil?
93
+
94
+ if item.class.columns_hash[field.to_s] && item.class.columns_hash[field.to_s].type == :boolean
95
+ # Boolean
96
+ column_formats[field] = local_assigns[:generic_data_format]
97
+ elsif (defs[:type] == :date) || (item.class.columns_hash[field.to_s] && [:date, :datetime].include?(item.class.columns_hash[field.to_s].type))
98
+ value = value.to_date if !value.nil?
99
+ column_formats[field] = workbook.number_format("[$-409]dd/mm/yy;@").set(align: { h: :center })
100
+ elsif item.class.columns_hash[field.to_s] && [:integer, :float, :decimal].include?(item.class.columns_hash[field.to_s].type)
101
+ column_formats[field] = workbook.number_format("#,##0.00") if (defs[:amount]!=false)
102
+ elsif [Date, ActiveSupport::TimeWithZone].include?(value.class)
103
+ value = value.to_date if !value.nil?
104
+ column_formats[field] = workbook.number_format("[$-409]dd/mm/yy;@").set(align: { h: :center })
105
+ elsif defs[:amount] || value.is_a?(Numeric)
106
+ column_formats[field] = workbook.number_format("#,##0.00")
107
+ else
108
+ column_formats[field] = local_assigns[:generic_data_format]
109
+ end
110
+
111
+ if !local_assigns[:column_formats].nil? && !local_assigns[:column_formats][field.to_sym].nil?
112
+ column_formats[field].set(local_assigns[:column_formats][field.to_sym])
113
+ end
114
+
115
+ # abort value.inspect if field.to_s == "credit"
116
+
117
+ end
118
+
119
+ formats.push column_formats[field]
120
+ row.push value
121
+ end
122
+
123
+ if defined?(extra_cols)
124
+ row += extra_cols.call(item)
125
+ end
126
+
127
+ sheet.append_row(row, formats)
128
+ end
129
+
130
+ ef = workbook.add_format(top: :medium)
131
+ row = []
132
+ fields.each do |field, defs|
133
+ next if defs[:table] == false
134
+ row.push nil
135
+ end
136
+ sheet.append_row(row, ef)
137
+
138
+
139
+ if local_assigns[:autofilter]
140
+ sheet.autofilter(data_start_row, 0, sheet.last_row_number, fields.length-1)
141
+ end
@@ -0,0 +1,72 @@
1
+ - variant = local_assigns[:variant]
2
+ - model_name = item.model_name.singular # Allows to show different class models in one table!
3
+ -# = render partial: "custom_tables/table_row", locals: local_assigns.merge(item: item, position: position, fields: fields, fields_totals: fields_totals)
4
+ - row_class_helper = local_assigns[:row_class] || "#{model_name}_row_class"
5
+ - row_class = [(self.send(row_class_helper, item) rescue "")]
6
+
7
+ - row_class += ["child-of-#{item.parent_id}", (local_assigns[:expanded] ? "" : "d-none")] if local_assigns[:tree] && !item.parent_id.nil?
8
+ - row_class += ["child-of-#{local_assigns[:grouped_by_id]}", (local_assigns[:expanded] ? "" : "d-none")] if local_assigns[:grouped_by_id]
9
+
10
+ %tr{id: dom_id(item, "row"), :class => row_class}
11
+
12
+ - if local_assigns[:tree]
13
+ %td
14
+ - if item.parent_id.nil?
15
+ - if local_assigns[:has_children]
16
+ = tree_opener(item.id, local_assigns[:has_children], local_assigns[:expanded])
17
+ - else
18
+ = custom_table_icon(custom_table_tree_child_icon_class)
19
+
20
+ - if local_assigns[:with_select]
21
+ %td.checkbox-col
22
+ - if local_assigns[:with_select].to_s == "true"
23
+ = check_box_tag "#{item.model_name.plural}[]", item.id, (!params[item.model_name.plural.to_sym].blank?) && (params[item.model_name.plural.to_sym].include?(item.id.to_s)), data: {"toggle-target": "checkbox", "batch-actions-target": "checkbox", "action": "toggle#recalculateToggler batch-actions#refresh"}
24
+ - else
25
+ = self.send(local_assigns[:with_select], item, position)
26
+
27
+ - if local_assigns[:with_index]
28
+ %td
29
+ = position
30
+
31
+ - custom_table_fields_totals(fields: fields, item: item, totals: local_assigns[:totals], variant: variant, fields_totals: fields_totals)
32
+
33
+ - fields.each do |field, defs|
34
+ - next if defs[:table] == false
35
+ - td_classes = [field.to_s]
36
+ - td_classes += ["text-end"] if defs[:amount]
37
+ - td_classes += ["text-nowrap"] if defs[:nowrap]
38
+ - td_classes += ["amount"] if defs[:amount]
39
+
40
+ %td{class: td_classes, id: dom_id(item, field)}
41
+ - v = field_value_for(item, field, definitions: defs, variant: variant)
42
+
43
+ - if defs[:editable]
44
+
45
+ = editable item, field do
46
+ - if defs[:link_to_show] == true && custom_table_has_show_route?(item) && can?(:show, item)
47
+ -# = link_to v, url_for(controller: controller_name, action: "show", id: item.to_param)
48
+ = link_to v, [namespace, item], data: {turbo: false}
49
+ - else
50
+ = v
51
+ - else
52
+ - if defs[:link_to_show] == true && custom_table_has_show_route?(item) && can?(:show, item)
53
+ -# = link_to v, url_for(controller: controller_name, action: "show", id: item.to_param)
54
+ = link_to v, [namespace, item], data: {turbo: false}
55
+ - else
56
+ = v
57
+
58
+ - if !local_assigns[:skip_actions]
59
+
60
+ %td.text-end.actions
61
+ - if !local_assigns[:actions].nil?
62
+ = self.send(local_assigns[:actions], item)
63
+ - elsif !variant.nil? && self.class.method_defined?("#{variant}_#{model_name}_custom_table_actions")
64
+ = self.send("#{variant}_#{model_name}_custom_table_actions", item)
65
+ - elsif self.class.method_defined?("#{model_name}_custom_table_actions")
66
+ = self.send("#{model_name}_custom_table_actions", item)
67
+ - if local_assigns[:skip_default_actions].nil?
68
+ - if (!custom_table_has_show_route?(item) || local_assigns[:force_edit_button]) && can?(:update, item)
69
+ = custom_table_edit_button [:edit, namespace, local_assigns[:parent], item], id: "edit_#{item.model_name.singular}_#{item.id}", modal: local_assigns[:modal_edit]
70
+ - if can? :destroy, item
71
+ - if (Rails.application.routes.recognize_path(url_for([namespace, local_assigns[:parent], item]), :method => :delete) rescue false)
72
+ = custom_table_delete_button [namespace, local_assigns[:parent], item], id: "destroy_#{item.model_name.singular}_#{item.id}"
@@ -0,0 +1,26 @@
1
+ - model_class = item.class
2
+ - fields = custom_table_fields_for(model_class, use_all_fields: true, variant: local_assigns[:variant], predefined_fields: local_assigns[:fields])
3
+ - model_name = item.model_name.singular # Allows to show different class models in one table!
4
+
5
+ - fields.each do |field, defs|
6
+ - next if defs[:table] == false
7
+
8
+ = turbo_stream.update dom_id(item, field) do
9
+ - v = field_value_for(item, field, definitions: defs)
10
+
11
+ - if defs[:link_to_show] == true && custom_table_has_show_route?(item)
12
+ -# = link_to v, url_for(controller: controller_name, action: "show", id: item.to_param)
13
+ = link_to v, [namespace, item]
14
+ - else
15
+ = v
16
+
17
+ -# %td.text-end.actions
18
+ -# - if !local_assigns[:actions].nil?
19
+ -# = self.send(local_assigns[:actions], item)
20
+ -# - elsif self.class.method_defined?("#{model_name}_custom_table_actions")
21
+ -# = self.send("#{model_name}_custom_table_actions", item)
22
+ -# - if local_assigns[:skip_default_actions].nil?
23
+ -# - if (!has_show_route?(item) || local_assigns[:force_edit_button]) && can?(:update, item)
24
+ -# = edit_button [:edit, namespace, local_assigns[:parent], item], id: "edit_#{item.model_name.singular}_#{item.id}"
25
+ -# - if can? :destroy, item
26
+ -# = delete_button [namespace, local_assigns[:parent], item], id: "destroy_#{item.model_name.singular}_#{item.id}", data: turbo_frame_request? ? {} : {}
@@ -0,0 +1,4 @@
1
+ = turbo_frame_tag "custom-table-settings" do
2
+ %p= t("custom_table.customization_saved")
3
+ :javascript
4
+ window.location.reload();
@@ -0,0 +1,2 @@
1
+ = turbo_frame_tag "remote-modal" do
2
+ = custom_table_settings @search_model, @variant
@@ -0,0 +1,4 @@
1
+ = turbo_frame_tag "custom-table-settings" do
2
+ %p= t("custom_table.customization_saved")
3
+ :javascript
4
+ window.location.reload();
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Custom table</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "custom_table/application", media: "all" %>
9
+ </head>
10
+ <body>
11
+
12
+ <%= yield %>
13
+
14
+ </body>
15
+ </html>