custom_table 0.1.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 (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>