hot-glue 0.5.7 → 0.5.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +1 -1
- data/.gitignore +2 -1
- data/Gemfile +1 -1
- data/LICENSE +12 -5
- data/README.md +323 -143
- data/app/helpers/hot_glue/controller_helper.rb +9 -6
- data/lib/generators/hot_glue/direct_upload_install_generator.rb +47 -0
- data/lib/generators/hot_glue/dropzone_install_generator.rb +39 -0
- data/lib/generators/hot_glue/layout/builder.rb +15 -7
- data/lib/generators/hot_glue/layout_strategy/base.rb +2 -0
- data/lib/generators/hot_glue/layout_strategy/bootstrap.rb +16 -3
- data/lib/generators/hot_glue/markup_templates/erb.rb +186 -127
- data/lib/generators/hot_glue/scaffold_generator.rb +269 -142
- data/lib/generators/hot_glue/templates/controller.rb.erb +19 -11
- data/lib/generators/hot_glue/templates/erb/_list.erb +19 -6
- data/lib/generators/hot_glue/templates/erb/_show.erb +6 -4
- data/lib/generators/hot_glue/templates/javascript/dropzone_controller.js +191 -0
- data/lib/generators/hot_glue/templates/system_spec.rb.erb +31 -13
- data/lib/hotglue/version.rb +1 -1
- data/script/clean_generated_code +1 -1
- metadata +7 -4
@@ -3,13 +3,41 @@ module HotGlue
|
|
3
3
|
|
4
4
|
attr_accessor :path, :singular, :singular_class,
|
5
5
|
:magic_buttons, :small_buttons,
|
6
|
-
:show_only, :
|
6
|
+
:show_only, :layout_strategy, :perc_width,
|
7
7
|
:ownership_field, :form_labels_position,
|
8
|
-
:inline_list_labels,
|
9
|
-
:columns,
|
10
|
-
:form_placeholder_labels, :hawk_keys
|
11
|
-
|
12
|
-
|
8
|
+
:inline_list_labels, :layout_object,
|
9
|
+
:columns, :col_identifier, :singular,
|
10
|
+
:form_placeholder_labels, :hawk_keys, :update_show_only,
|
11
|
+
:alt_lookups, :attachments, :show_only
|
12
|
+
|
13
|
+
|
14
|
+
def initialize(singular:, singular_class: ,
|
15
|
+
layout_strategy: , magic_buttons: ,
|
16
|
+
small_buttons: , show_only: ,
|
17
|
+
ownership_field: , form_labels_position: ,
|
18
|
+
inline_list_labels: ,
|
19
|
+
form_placeholder_labels:, hawk_keys:,
|
20
|
+
update_show_only:, alt_lookups: , attachments: )
|
21
|
+
|
22
|
+
@singular = singular
|
23
|
+
@singular_class = singular_class
|
24
|
+
|
25
|
+
@magic_buttons = magic_buttons
|
26
|
+
@small_buttons = small_buttons
|
27
|
+
@layout_strategy = layout_strategy
|
28
|
+
@show_only = show_only
|
29
|
+
@ownership_field = ownership_field
|
30
|
+
|
31
|
+
@form_labels_position = form_labels_position
|
32
|
+
|
33
|
+
@inline_list_labels = inline_list_labels
|
34
|
+
@singular = singular
|
35
|
+
@form_placeholder_labels = form_placeholder_labels
|
36
|
+
@hawk_keys = hawk_keys
|
37
|
+
@update_show_only = update_show_only
|
38
|
+
@alt_lookups = alt_lookups
|
39
|
+
@attachments = attachments
|
40
|
+
end
|
13
41
|
|
14
42
|
def add_spaces_each_line(text, num_spaces)
|
15
43
|
add_spaces = " " * num_spaces
|
@@ -18,89 +46,110 @@ module HotGlue
|
|
18
46
|
|
19
47
|
def magic_button_output(path:, singular:, magic_buttons:, small_buttons: )
|
20
48
|
magic_buttons.collect{ |button_name|
|
21
|
-
"<%= form_with model: #{singular}, url: #{path}, html: {style: 'display: inline', data: {\"turbo-confirm\": 'Are you sure you want to #{button_name} this #{singular}?'}} do |f| %>
|
22
|
-
|
23
|
-
|
24
|
-
|
49
|
+
"<%= form_with model: #{singular}, url: #{path}, html: {style: 'display: inline', data: {\"turbo-confirm\": 'Are you sure you want to #{button_name} this #{singular}?'}} do |f| %>" +
|
50
|
+
"<%= f.hidden_field :__#{button_name}, value: \"__#{button_name}\" %>" +
|
51
|
+
"<%= f.submit '#{button_name.titleize}'.html_safe, disabled: (#{singular}.respond_to?(:#{button_name}able?) && ! #{singular}.#{button_name}able? ), class: '#{singular}-button #{@layout_strategy.button_applied_classes} #{@layout_strategy.magic_button_classes}' %>" +
|
52
|
+
"<% end %>"
|
25
53
|
}.join("\n")
|
26
54
|
end
|
27
55
|
|
28
|
-
def list_column_headings(
|
29
|
-
|
30
|
-
|
31
|
-
@col_identifier = args[0][:col_identifier]
|
32
|
-
|
56
|
+
def list_column_headings(layout_object: ,
|
57
|
+
col_identifier: ,
|
58
|
+
column_width:, singular: )
|
33
59
|
col_style = @layout_strategy.column_headings_col_style
|
34
60
|
|
61
|
+
columns = layout_object[:columns][:container]
|
35
62
|
result = columns.map{ |column|
|
36
|
-
"<div class='#{col_identifier}'
|
63
|
+
"<div class='#{col_identifier}' heading--#{singular}--#{column.join("-")} " + col_style + ">" +
|
64
|
+
column.map(&:to_s).map{|col_name| "#{col_name.humanize}"}.join("<br />") + "</div>"
|
37
65
|
}.join("\n")
|
38
66
|
return result
|
39
67
|
end
|
40
68
|
|
41
69
|
|
42
70
|
################################################################
|
43
|
-
|
44
71
|
# THE FORM
|
72
|
+
################################################################
|
45
73
|
|
46
|
-
def all_form_fields(*args)
|
47
|
-
|
48
|
-
@columns = args[0][:columns]
|
49
|
-
@show_only = args[0][:show_only]
|
50
74
|
|
51
|
-
|
52
|
-
@ownership_field = args[0][:ownership_field]
|
53
|
-
@form_labels_position = args[0][:form_labels_position]
|
54
|
-
@form_placeholder_labels = args[0][:form_placeholder_labels]
|
55
|
-
@hawk_keys = args[0][:hawk_keys]
|
56
|
-
@singular = args[0][:singular]
|
75
|
+
def all_form_fields(layout_strategy: , layout_object: )
|
57
76
|
|
58
|
-
@
|
77
|
+
# @show_only = args[0][:show_only]
|
78
|
+
#
|
79
|
+
# @singular_class = args[0][:singular_class]
|
80
|
+
# @ownership_field = args[0][:ownership_field]
|
81
|
+
# @form_labels_position = args[0][:form_labels_position]
|
82
|
+
# @form_placeholder_labels = args[0][:form_placeholder_labels]
|
83
|
+
# @hawk_keys = args[0][:hawk_keys]
|
84
|
+
# @singular = args[0][:singular]
|
85
|
+
# attachments = args[0][:attachments]
|
86
|
+
#
|
87
|
+
# @alt_lookups = args[0][:alt_lookups]
|
88
|
+
#
|
89
|
+
# column_classes = args[0][:col_identifier]
|
90
|
+
# update_show_only = args[0][:update_show_only] || []
|
91
|
+
# singular = @singular
|
59
92
|
|
60
|
-
column_classes =
|
61
|
-
|
62
|
-
singular = @singular
|
93
|
+
column_classes = layout_strategy.column_classes_for_form_fields
|
94
|
+
columns = layout_object[:columns][:container]
|
63
95
|
|
64
96
|
result = columns.map{ |column|
|
65
|
-
" <div class='#{column_classes}' >" +
|
97
|
+
" <div class='#{column_classes} cell--#{singular}--#{column.join("-")}' >" +
|
66
98
|
column.map { |col|
|
67
|
-
|
68
|
-
|
69
|
-
|
99
|
+
if attachments.keys.include?(col)
|
100
|
+
this_attachment = attachments[col]
|
101
|
+
thumbnail = this_attachment[:thumbnail]
|
102
|
+
direct = this_attachment[:direct_upload]
|
103
|
+
dropzone = this_attachment[:dropzone]
|
104
|
+
field_result = (this_attachment[:thumbnail] ? "<%= #{singular}.#{col}.attached? ? image_tag(#{singular}.#{col}.variant(:#{thumbnail})) : '' %>" : "") +
|
105
|
+
"<br />\n" + (update_show_only.include?(col) ? "" : "<%= f.file_field :#{col} #{', direct_upload: true ' if direct}#{', "data-dropzone-target": "input"' if dropzone}%>")
|
106
|
+
|
107
|
+
if dropzone
|
108
|
+
field_result = "<div class=\"dropzone dropzone-default dz-clickable\" data-controller=\"dropzone\" data-dropzone-max-file-size=\"2\" data-dropzone-max-files=\"1\">\n "+ field_result + "\n</div>"
|
109
|
+
end
|
110
|
+
field_error_name = col
|
111
|
+
else
|
70
112
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
113
|
+
type = eval("#{singular_class}.columns_hash['#{col}']").type
|
114
|
+
limit = eval("#{singular_class}.columns_hash['#{col}']").limit
|
115
|
+
sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
|
116
|
+
|
117
|
+
field_result =
|
118
|
+
if show_only.include?(col.to_sym)
|
119
|
+
show_only_result(type: type, col: col, singular: singular)
|
120
|
+
else
|
121
|
+
case type
|
122
|
+
when :integer
|
123
|
+
integer_result(col)
|
124
|
+
when :uuid
|
125
|
+
association_result(col)
|
126
|
+
when :string
|
127
|
+
string_result(col, sql_type, limit)
|
128
|
+
when :text
|
129
|
+
text_result(col, sql_type, limit)
|
130
|
+
when :float
|
131
|
+
field_output(col, nil, 5, column_classes)
|
132
|
+
when :datetime
|
133
|
+
"<%= datetime_field_localized(f, :#{col}, #{singular}.#{col}, '#{ col.to_s.humanize }', #{@auth ? @auth+'.timezone' : 'nil'}) %>"
|
134
|
+
when :date
|
135
|
+
"<%= date_field_localized(f, :#{col}, #{singular}.#{col}, '#{ col.to_s.humanize }', #{@auth ? @auth+'.timezone' : 'nil'}) %>"
|
136
|
+
when :time
|
137
|
+
"<%= time_field_localized(f, :#{col}, #{singular}.#{col}, '#{ col.to_s.humanize }', #{@auth ? @auth+'.timezone' : 'nil'}) %>"
|
138
|
+
when :boolean
|
139
|
+
boolean_result(col)
|
140
|
+
when :enum
|
141
|
+
enum_result(col)
|
142
|
+
end
|
96
143
|
end
|
144
|
+
|
145
|
+
if (type == :integer) && col.to_s.ends_with?("_id")
|
146
|
+
field_error_name = col.to_s.gsub("_id","")
|
147
|
+
else
|
148
|
+
field_error_name = col
|
97
149
|
end
|
98
150
|
|
99
|
-
if (type == :integer) && col.to_s.ends_with?("_id")
|
100
|
-
field_error_name = col.to_s.gsub("_id","")
|
101
|
-
else
|
102
|
-
field_error_name = col
|
103
151
|
end
|
152
|
+
the_label = "\n<label class='small form-text text-muted'>#{col.to_s.humanize}</label>"
|
104
153
|
show_only_open = ""
|
105
154
|
show_only_close = ""
|
106
155
|
if update_show_only.include?(col)
|
@@ -108,14 +157,13 @@ module HotGlue
|
|
108
157
|
show_only_result(type: type, col: col, singular: singular) + "<% else %>"
|
109
158
|
show_only_close = "<% end %>"
|
110
159
|
end
|
111
|
-
|
160
|
+
|
112
161
|
add_spaces_each_line( "\n <span class='<%= \"alert-danger\" if #{singular}.errors.details.keys.include?(:#{field_error_name}) %>' #{'style="display: inherit;"'} >\n" +
|
113
|
-
add_spaces_each_line( (
|
114
|
-
|
115
|
-
|
162
|
+
add_spaces_each_line( (form_labels_position == 'before' ? the_label : "") +
|
163
|
+
show_only_open + field_result + show_only_close +
|
164
|
+
(form_labels_position == 'after' ? the_label : "") , 4) +
|
116
165
|
"\n </span>\n <br />", 2)
|
117
166
|
|
118
|
-
|
119
167
|
}.join("") + "\n </div>"
|
120
168
|
}.join("\n")
|
121
169
|
return result
|
@@ -177,10 +225,9 @@ module HotGlue
|
|
177
225
|
is_owner = col == ownership_field
|
178
226
|
assoc_class_name = assoc.class_name.to_s
|
179
227
|
display_column = HotGlue.derrive_reference_name(assoc_class_name)
|
180
|
-
|
181
228
|
if @hawk_keys[assoc.foreign_key.to_sym]
|
182
229
|
hawk_definition = @hawk_keys[assoc.foreign_key.to_sym]
|
183
|
-
hawked_association = hawk_definition.join(".")
|
230
|
+
hawked_association = hawk_definition[:bind_to].join(".")
|
184
231
|
else
|
185
232
|
hawked_association = "#{assoc.class_name}.all"
|
186
233
|
end
|
@@ -223,12 +270,13 @@ module HotGlue
|
|
223
270
|
end
|
224
271
|
|
225
272
|
def boolean_result(col)
|
226
|
-
" <br />" +
|
273
|
+
(form_labels_position == 'before' ? " <br />" : "") +
|
227
274
|
" <%= f.radio_button(:#{col}, '0', checked: #{singular}.#{col} ? '' : 'checked') %>\n" +
|
228
275
|
" <%= f.label(:#{col}, value: 'No', for: '#{singular}_#{col}_0') %>\n" +
|
229
276
|
" <%= f.radio_button(:#{col}, '1', checked: #{singular}.#{col} ? 'checked' : '') %>\n" +
|
230
277
|
" <%= f.label(:#{col}, value: 'Yes', for: '#{singular}_#{col}_1') %>\n" +
|
231
|
-
|
278
|
+
(form_labels_position == 'after' ? " <br />" : "")
|
279
|
+
|
232
280
|
end
|
233
281
|
|
234
282
|
def enum_result(col)
|
@@ -257,32 +305,42 @@ module HotGlue
|
|
257
305
|
################################################################
|
258
306
|
|
259
307
|
|
260
|
-
def all_line_fields(
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
@
|
266
|
-
@col_identifier = @layout_strategy.column_classes_for_line_fields
|
308
|
+
def all_line_fields(layout_strategy:,
|
309
|
+
layout_object: ,
|
310
|
+
perc_width:,
|
311
|
+
col_identifier: nil)
|
312
|
+
|
313
|
+
@col_identifier = layout_strategy.column_classes_for_line_fields
|
267
314
|
|
268
|
-
|
315
|
+
inline_list_labels = @inline_list_labels || 'omit'
|
316
|
+
columns = layout_object[:columns][:container]
|
269
317
|
|
270
318
|
columns_count = columns.count + 1
|
271
|
-
perc_width = (
|
319
|
+
perc_width = (perc_width).floor
|
272
320
|
|
273
|
-
style_with_flex_basis =
|
321
|
+
style_with_flex_basis = layout_strategy.style_with_flex_basis(perc_width)
|
274
322
|
|
275
323
|
result = columns.map{ |column|
|
276
|
-
"<div class='#{col_identifier}'#{style_with_flex_basis}>" +
|
277
|
-
|
278
324
|
|
325
|
+
"<div class='#{col_identifier} #{singular}--#{column.join("-")}'#{style_with_flex_basis}> " +
|
279
326
|
column.map { |col|
|
280
|
-
|
281
|
-
|
282
|
-
|
327
|
+
if eval("#{singular_class}.columns_hash['#{col}']").nil? && !attachments.keys.include?(col)
|
328
|
+
raise "Can't find column '#{col}' on #{singular_class}, are you sure that is the column name?"
|
329
|
+
end
|
330
|
+
|
331
|
+
if attachments.keys.include?(col)
|
332
|
+
this_attachment = attachments[col]
|
333
|
+
thumbnail = this_attachment[:thumbnail]
|
334
|
+
|
335
|
+
field_output = (this_attachment[:thumbnail] ? "<%= #{singular}.#{col}.attached? ? image_tag(#{singular}.#{col}.variant(:#{thumbnail})) : '' %>" : "")
|
283
336
|
|
284
|
-
|
285
|
-
|
337
|
+
else
|
338
|
+
type = eval("#{singular_class}.columns_hash['#{col}']").type
|
339
|
+
limit = eval("#{singular_class}.columns_hash['#{col}']").limit
|
340
|
+
sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
|
341
|
+
|
342
|
+
field_output =
|
343
|
+
case type
|
286
344
|
when :integer
|
287
345
|
# look for a belongs_to on this object
|
288
346
|
if col.ends_with?("_id")
|
@@ -304,48 +362,48 @@ module HotGlue
|
|
304
362
|
"<%= #{singular}.#{col}%>"
|
305
363
|
end
|
306
364
|
|
307
|
-
|
308
|
-
|
309
|
-
|
365
|
+
when :uuid
|
366
|
+
assoc_name = col.to_s.gsub("_id","")
|
367
|
+
assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
|
310
368
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
369
|
+
if assoc.nil?
|
370
|
+
exit_message = "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
|
371
|
+
puts exit_message
|
372
|
+
exit
|
373
|
+
# raise(HotGlue::Error,exit_message)
|
374
|
+
end
|
317
375
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
376
|
+
display_column = HotGlue.derrive_reference_name(assoc.class_name.to_s)
|
377
|
+
"<%= #{singular}.#{assoc.name.to_s}.try(:#{display_column}) || '<span class=\"content alert-danger\">MISSING</span>'.html_safe %>"
|
378
|
+
|
379
|
+
when :float
|
380
|
+
width = (limit && limit < 40) ? limit : (40)
|
381
|
+
"<%= #{singular}.#{col}%>"
|
382
|
+
when :string
|
383
|
+
width = (limit && limit < 40) ? limit : (40)
|
384
|
+
"<%= #{singular}.#{col} %>"
|
385
|
+
when :text
|
386
|
+
"<%= #{singular}.#{col} %>"
|
387
|
+
when :datetime
|
388
|
+
"<% unless #{singular}.#{col}.nil? %>
|
331
389
|
<%= #{singular}.#{col}.in_time_zone(current_timezone).strftime('%m/%d/%Y @ %l:%M %p ') + timezonize(current_timezone) %>
|
332
390
|
<% else %>
|
333
391
|
<span class='alert-danger'>MISSING</span>
|
334
392
|
<% end %>"
|
335
|
-
|
336
|
-
|
393
|
+
when :date
|
394
|
+
"<% unless #{singular}.#{col}.nil? %>
|
337
395
|
<%= #{singular}.#{col} %>
|
338
396
|
<% else %>
|
339
397
|
<span class='alert-danger'>MISSING</span>
|
340
398
|
<% end %>"
|
341
|
-
|
342
|
-
|
399
|
+
when :time
|
400
|
+
"<% unless #{singular}.#{col}.nil? %>
|
343
401
|
<%= #{singular}.#{col}.in_time_zone(current_timezone).strftime('%l:%M %p ') + timezonize(current_timezone) %>
|
344
402
|
<% else %>
|
345
403
|
<span class='alert-danger'>MISSING</span>
|
346
404
|
<% end %>"
|
347
|
-
|
348
|
-
|
405
|
+
when :boolean
|
406
|
+
"
|
349
407
|
<% if #{singular}.#{col}.nil? %>
|
350
408
|
<span class='alert-danger'>MISSING</span>
|
351
409
|
<% elsif #{singular}.#{col} %>
|
@@ -355,15 +413,15 @@ module HotGlue
|
|
355
413
|
<% end %>
|
356
414
|
|
357
415
|
"
|
358
|
-
|
359
|
-
|
416
|
+
when :enum
|
417
|
+
enum_type = eval("#{singular_class}.columns.select{|x| x.name == '#{col}'}[0].sql_type")
|
360
418
|
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
419
|
+
if eval("defined? #{singular_class}.#{enum_type}_labels") == "method"
|
420
|
+
enum_definer = "#{singular_class}.#{enum_type}_labels"
|
421
|
+
else
|
422
|
+
enum_definer = "#{singular_class}.defined_enums['#{enum_type}']"
|
423
|
+
end
|
424
|
+
"
|
367
425
|
<% if #{singular}.#{col}.nil? %>
|
368
426
|
<span class='alert-danger'>MISSING</span>
|
369
427
|
<% else %>
|
@@ -371,7 +429,8 @@ module HotGlue
|
|
371
429
|
<% end %>
|
372
430
|
|
373
431
|
"
|
374
|
-
|
432
|
+
end #end of switch
|
433
|
+
end
|
375
434
|
|
376
435
|
label = "<br/><label class='small form-text text-muted'>#{col.to_s.humanize}</label>"
|
377
436
|
|