hot-glue 0.5.14 → 0.5.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +74 -0
  3. data/.github/workflows/test.yml +33 -14
  4. data/.gitignore +0 -2
  5. data/.ruby-version +1 -1
  6. data/Gemfile +4 -2
  7. data/Gemfile.lock +280 -0
  8. data/README.md +33 -4
  9. data/lib/generators/hot_glue/direct_upload_install_generator.rb +1 -1
  10. data/lib/generators/hot_glue/dropzone_install_generator.rb +1 -1
  11. data/lib/generators/hot_glue/field_factory.rb +6 -2
  12. data/lib/generators/hot_glue/fields/association_field.rb +73 -6
  13. data/lib/generators/hot_glue/fields/attachment_field.rb +7 -3
  14. data/lib/generators/hot_glue/fields/boolean_field.rb +31 -1
  15. data/lib/generators/hot_glue/fields/date_field.rb +13 -0
  16. data/lib/generators/hot_glue/fields/date_time_field.rb +30 -3
  17. data/lib/generators/hot_glue/fields/enum_field.rb +39 -6
  18. data/lib/generators/hot_glue/fields/field.rb +92 -8
  19. data/lib/generators/hot_glue/fields/float_field.rb +11 -0
  20. data/lib/generators/hot_glue/fields/integer_field.rb +4 -0
  21. data/lib/generators/hot_glue/fields/string_field.rb +17 -0
  22. data/lib/generators/hot_glue/fields/text_field.rb +17 -0
  23. data/lib/generators/hot_glue/fields/time_field.rb +20 -0
  24. data/lib/generators/hot_glue/fields/uuid_field.rb +1 -1
  25. data/lib/generators/hot_glue/flash_notices_install_generator.rb +1 -1
  26. data/lib/generators/hot_glue/install_generator.rb +15 -9
  27. data/lib/generators/hot_glue/layout/builder.rb +4 -2
  28. data/lib/generators/hot_glue/markup_templates/erb.rb +14 -279
  29. data/lib/generators/hot_glue/scaffold_generator.rb +133 -151
  30. data/lib/generators/hot_glue/templates/erb/_edit.erb +1 -1
  31. data/lib/hotglue/version.rb +1 -1
  32. data/script/test +9 -14
  33. metadata +5 -3
@@ -13,6 +13,36 @@ class BooleanField < Field
13
13
  end
14
14
 
15
15
  def spec_list_view_assertion
16
- " " + ["expect(page).to have_content(#{singular}#{1}.#{name} ? 'YES' : 'NO')"].join("\n ")
16
+ ["expect(page).to have_content(#{singular}#{1}.#{name} ? 'YES' : 'NO')"].join("\n ")
17
+ end
18
+
19
+
20
+ def form_field_output
21
+ (form_labels_position == 'before' ? " <br />" : "") +
22
+ " <%= f.radio_button(:#{name}, '0', checked: #{singular}.#{name} ? '' : 'checked') %>\n" +
23
+ " <%= f.label(:#{name}, value: '#{modify_binary? && modify[:binary][:falsy] || 'No'}', for: '#{singular}_#{name}_0') %>\n" +
24
+ " <br /> <%= f.radio_button(:#{name}, '1', checked: #{singular}.#{name} ? 'checked' : '') %>\n" +
25
+ " <%= f.label(:#{name}, value: '#{modify_binary? && modify[:binary][:truthy] || 'Yes'}', for: '#{singular}_#{name}_1') %>\n" +
26
+ (form_labels_position == 'after' ? " <br />" : "")
27
+ end
28
+
29
+ def line_field_output
30
+ if modify_binary?
31
+ "<% if #{singular}.#{name}.nil? %>
32
+ <span class='alert-danger'>MISSING</span>
33
+ <% elsif #{singular}.#{name} %>
34
+ #{modify[:binary][:truthy]}
35
+ <% else %>
36
+ #{modify[:binary][:falsy]}
37
+ <% end %>"
38
+ else
39
+ "<% if #{singular}.#{name}.nil? %>
40
+ <span class='alert-danger'>MISSING</span>
41
+ <% elsif #{singular}.#{name} %>
42
+ YES
43
+ <% else %>
44
+ NO
45
+ <% end %>"
46
+ end
17
47
  end
18
48
  end
@@ -7,4 +7,17 @@ class DateField < Field
7
7
  def spec_setup_let_arg
8
8
  "#{name}: Date.current + rand(50).days"
9
9
  end
10
+
11
+
12
+ def form_field_output
13
+ "<%= date_field_localized(f, :#{name}, #{singular}.#{name}, '#{ name.to_s.humanize }', #{auth ? auth+'.timezone' : 'nil'}) %>"
14
+ end
15
+
16
+ def line_field_output
17
+ "<% unless #{singular}.#{name}.nil? %>
18
+ <%= #{singular}.#{name} %>
19
+ <% else %>
20
+ <span class='alert-danger'>MISSING</span>
21
+ <% end %>"
22
+ end
10
23
  end
@@ -10,8 +10,11 @@ class DateTimeField < Field
10
10
  end
11
11
 
12
12
  def spec_make_assertion
13
-
14
- "expect(page).to have_content(new_#{name}.in_time_zone(current_timezone).strftime('%m/%d/%Y @ %l:%M %p ') + timezonize(current_timezone))"
13
+ if !modify_binary?
14
+ "expect(page).to have_content(new_#{name}.in_time_zone(current_timezone).strftime('%m/%d/%Y @ %l:%M %p ') + timezonize(current_timezone))"
15
+ else
16
+ "expect(page).to have_content('#{modify[:binary][:truthy]}'"
17
+ end
15
18
  end
16
19
 
17
20
  def spec_setup_let_arg
@@ -19,6 +22,30 @@ class DateTimeField < Field
19
22
  end
20
23
 
21
24
  def spec_list_view_assertion
22
- "expect(page).to have_content(#{singular}#{1}.#{name}.in_time_zone(current_timezone).strftime('%m/%d/%Y @ %l:%M %p ').gsub(' ', ' ') + timezonize(current_timezone) )"
25
+ if modify_binary?
26
+ "expect(page).to have_content('#{modify[:binary][:truthy]}')"
27
+ else
28
+ spec_list_view_natural_assertion
29
+ end
30
+ end
31
+
32
+ def spec_list_view_natural_assertion
33
+ "expect(page).to have_content(#{singular}#{1}.#{name}.in_time_zone(current_timezone).strftime('%m/%d/%Y @ %l:%M %p ').gsub(' ', ' ') + timezonize(current_timezone) )"
34
+ end
35
+
36
+ def form_field_output
37
+ "<%= datetime_field_localized(f, :#{name}, #{singular}.#{name}, '#{ name.to_s.humanize }', #{auth ? auth+'.timezone' : 'nil'}) %>"
38
+ end
39
+
40
+ def line_field_output
41
+ if modify_binary?
42
+ modified_display_output
43
+ else
44
+ "<% unless #{singular}.#{name}.nil? %>
45
+ <%= #{singular}.#{name}.in_time_zone(current_timezone).strftime('%m/%d/%Y @ %l:%M %p ') + timezonize(current_timezone) %>
46
+ <% else %>
47
+ <span class='alert-danger'>MISSING</span>
48
+ <% end %>"
49
+ end
23
50
  end
24
51
  end
@@ -1,12 +1,17 @@
1
1
  class EnumField < Field
2
2
  def spec_setup_and_change_act(which_partial = nil)
3
- " list_of_#{name.to_s} = #{singular_class}.defined_enums['#{name.to_s}'].keys \n" +
4
- " " + "new_#{name.to_s} = list_of_#{name.to_s}[rand(list_of_#{name.to_s}.length)].to_s \n" +
5
- ' find("select[name=\'' + singular + '[' + name.to_s + ']\'] option[value=\'#{new_' + name.to_s + '}\']").select_option'
3
+ # what is the enum name
4
+ " list_of_#{enum_type} = #{class_name}.defined_enums['#{enum_type}'].keys \n" +
5
+ " " + "new_#{name} = list_of_#{enum_type}[rand(list_of_#{enum_type}.length)].to_s \n" +
6
+ ' find("select[name=\'' + singular + '[' + name + ']\'] option[value=\'#{new_' + name + '}\']").select_option'
7
+ end
8
+
9
+ def enum_type
10
+ eval("#{class_name}.columns.select{|x| x.name == '#{name}'}[0].sql_type")
6
11
  end
7
12
 
8
13
  def spec_make_assertion
9
- if(eval("#{singular_class}.respond_to?(:#{name}_labels)"))
14
+ if(eval("#{class_name}.respond_to?(:#{name}_labels)"))
10
15
  "expect(page).to have_content(#{singular_class}.#{name}_labels[new_#{name}])"
11
16
  else
12
17
  "expect(page).to have_content(new_#{name})"
@@ -18,10 +23,38 @@ class EnumField < Field
18
23
  end
19
24
 
20
25
  def spec_list_view_assertion
21
- if(eval("#{singular_class}.respond_to?(:#{name}_labels)"))
22
- "expect(page).to have_content(#{singular_class}.#{name}_labels[#{singular}#{1}.#{name}])"
26
+ if(eval("#{class_name}.respond_to?(:#{name}_labels)"))
27
+ "expect(page).to have_content(#{class_name}.#{name}_labels[#{singular}#{1}.#{name}])"
23
28
  else
24
29
  "expect(page).to have_content(#{singular}1.#{name})"
25
30
  end
26
31
  end
32
+
33
+ def form_field_output
34
+ enum_type = eval("#{class_name}.columns.select{|x| x.name == '#{name}'}[0].sql_type")
35
+
36
+ if eval("defined? #{class_name}.#{enum_type}_labels") == "method"
37
+ enum_definer = "#{class_name}.#{enum_type}_labels"
38
+ else
39
+ enum_definer = "#{class_name}.defined_enums['#{enum_type}']"
40
+ end
41
+ return "<%= f.collection_select(:#{name}, enum_to_collection_select(#{enum_definer}), :key, :value, {selected: #{singular}.#{name} }, class: 'form-control') %>"
42
+ end
43
+
44
+ def line_field_output
45
+ enum_type = eval("#{class_name}.columns.select{|x| x.name == '#{name}'}[0].sql_type")
46
+
47
+ if eval("defined? #{class_name}.#{enum_type}_labels") == "method"
48
+ enum_definer = "#{class_name}.#{enum_type}_labels"
49
+ else
50
+ enum_definer = "#{class_name}.defined_enums['#{enum_type}']"
51
+ end
52
+ "
53
+ <% if #{singular}.#{name}.nil? %>
54
+ <span class='alert-danger'>MISSING</span>
55
+ <% else %>
56
+ <%= #{enum_definer}[#{singular}.#{name}.to_sym] %>
57
+ <% end %>
58
+ "
59
+ end
27
60
  end
@@ -1,13 +1,28 @@
1
1
  class Field
2
- attr_accessor :name, :object, :singular_class, :class_name, :singular,
2
+ attr_accessor :assoc_model, :assoc_name, :assoc_class, :associations, :alt_lookups, :auth,
3
+ :assoc_label, :class_name, :form_placeholder_labels, :form_labels_position,
4
+ :hawk_keys, :layout_strategy, :limit, :modify, :name, :object, :sample_file_path,
5
+ :singular_class, :singular, :sql_type, :ownership_field,
3
6
  :update_show_only
4
- attr_accessor :assoc_model, :assoc_name, :assoc_class, :associations, :alt_lookups, :assoc_label
5
7
 
6
- attr_accessor :hawk_keys, :auth, :sample_file_path
7
-
8
- def initialize(name: , class_name: , alt_lookups: , singular: , update_show_only: ,
9
- hawk_keys: , auth: , sample_file_path: nil, attachment_data: nil )
8
+ def initialize(
9
+ auth: ,
10
+ alt_lookups: ,
11
+ attachment_data: nil,
12
+ class_name: ,
13
+ form_labels_position:,
14
+ form_placeholder_labels: ,
15
+ hawk_keys: nil,
16
+ layout_strategy: ,
17
+ modify: ,
18
+ name: ,
19
+ ownership_field: ,
20
+ sample_file_path: nil,
21
+ singular: ,
22
+ update_show_only:
23
+ )
10
24
  @name = name
25
+ @layout_strategy = layout_strategy
11
26
  @alt_lookups = alt_lookups
12
27
  @singular = singular
13
28
  @class_name = class_name
@@ -15,12 +30,26 @@ class Field
15
30
  @hawk_keys = hawk_keys
16
31
  @auth = auth
17
32
  @sample_file_path = sample_file_path
33
+ @form_placeholder_labels = form_placeholder_labels
34
+ @ownership_field = ownership_field
35
+ @form_labels_position = form_labels_position
36
+ @modify = modify
37
+
38
+ # TODO: remove knowledge of subclasses from Field
39
+ unless self.class == AttachmentField
40
+ @sql_type = eval("#{class_name}.columns_hash['#{name}']").sql_type
41
+ @limit = eval("#{class_name}.columns_hash['#{name}']").limit
42
+ end
18
43
  end
19
44
 
20
45
  def getName
21
46
  @name
22
47
  end
23
48
 
49
+ def field_error_name
50
+ name
51
+ end
52
+
24
53
  def spec_random_data
25
54
 
26
55
  end
@@ -33,19 +62,74 @@ class Field
33
62
  ""
34
63
  end
35
64
 
65
+
36
66
  def spec_make_assertion
37
- "expect(page).to have_content(new_#{name})"
67
+ if !modify_binary?
68
+ "expect(page).to have_content(new_#{name})"
69
+ else
70
+ "expect(page).to have_content('#{modify[:binary][:truthy]}'"
71
+ end
38
72
  end
39
73
 
74
+
40
75
  def spec_setup_let_arg
41
76
 
42
77
  end
43
78
 
44
- def spec_list_view_assertion
79
+ def spec_list_view_natural_assertion
45
80
  "expect(page).to have_content(#{singular}#{1}.#{name})"
46
81
  end
47
82
 
83
+ def spec_list_view_assertion
84
+ if modify_binary?
85
+ "expect(page).to have_content('#{modify[:binary][:truthy]}'"
86
+ else
87
+ spec_list_view_natural_assertion
88
+ end
89
+ end
90
+
91
+
48
92
  def spec_related_column_lets
49
93
  ""
50
94
  end
95
+
96
+ def line_field_output
97
+ viewable_output
98
+ end
99
+
100
+ def form_show_only_output
101
+ viewable_output
102
+ end
103
+
104
+ def viewable_output
105
+ if modify
106
+ modified_display_output
107
+ else
108
+ "<%= #{singular}.#{name} %>"
109
+ end
110
+ end
111
+
112
+ def modified_display_output
113
+ if modify[:cast] && modify[:cast] == "$"
114
+ "<%= number_to_currency(#{singular}.#{name}) %>"
115
+ elsif modify[:binary]
116
+ "<%= #{singular}.#{name} ? '#{modify[:binary][:truthy]}' : '#{modify[:binary][:falsy]}' %>"
117
+ end
118
+ end
119
+
120
+ def field_output(type = nil, width )
121
+ " <%= f.text_field :#{name}, value: #{singular}.#{name}, autocomplete: 'off', size: #{width}, class: 'form-control', type: '#{type}'" + (form_placeholder_labels ? ", placeholder: '#{name.to_s.humanize}'" : "") + " %>\n " + "\n"
122
+ end
123
+
124
+ def text_area_output(field_length )
125
+ lines = field_length % 40
126
+ if lines > 5
127
+ lines = 5
128
+ end
129
+ "<%= f.text_area :#{name}, class: 'form-control', autocomplete: 'off', cols: 40, rows: '#{lines}'" + ( form_placeholder_labels ? ", placeholder: '#{name.to_s.humanize}'" : "") + " %>"
130
+ end
131
+
132
+ def modify_binary? # safe
133
+ !!(modify && modify[:binary])
134
+ end
51
135
  end
@@ -5,7 +5,18 @@ class FloatField < Field
5
5
 
6
6
  end
7
7
 
8
+
8
9
  def spec_setup_let_arg
9
10
  "#{name}: rand(1)*10000"
10
11
  end
12
+
13
+ def form_field_output
14
+ field_output(nil, 5)
15
+ end
16
+
17
+ # def line_field_output
18
+ # width = (limit && limit < 40) ? limit : (40)
19
+ #
20
+ # "<%= #{singular}.#{name} %>"
21
+ # end
11
22
  end
@@ -23,4 +23,8 @@ class IntegerField < Field
23
23
  def spec_list_view_assertion
24
24
  "expect(page).to have_content(#{singular}#{1}.#{name})"
25
25
  end
26
+
27
+ def form_field_output
28
+ " <%= f.text_field :#{name}, value: #{singular}.#{name}, autocomplete: 'off', size: 4, class: 'form-control', type: 'number'" + (form_placeholder_labels ? ", placeholder: '#{name.to_s.humanize}'" : "") + " %>\n " + "\n"
29
+ end
26
30
  end
@@ -30,4 +30,21 @@ class StringField < Field
30
30
  "#{name}: FFaker::Movie.title"
31
31
  end
32
32
  end
33
+
34
+ def form_field_output
35
+ if sql_type == "varchar" || sql_type == "character varying"
36
+ field_output(nil, limit || 40)
37
+ else
38
+ text_area_output( 65536)
39
+ end
40
+ end
41
+
42
+ # TODO: dry with text_field.rb
43
+ def text_result(col, sql_type, limit)
44
+ if sql_type == "varchar"
45
+ field_output( nil, limit)
46
+ else
47
+ text_area_output( 65536)
48
+ end
49
+ end
33
50
  end
@@ -11,4 +11,21 @@ class TextField < Field
11
11
  def spec_setup_let_arg
12
12
  "#{name}: FFaker::Lorem.paragraphs(10).join(" ")"
13
13
  end
14
+
15
+ def form_field_output
16
+ if sql_type == "varchar" || sql_type == "character varying"
17
+ field_output( nil, limit || 40)
18
+ else
19
+ text_area_output( 65536)
20
+ end
21
+ end
22
+
23
+ # TODO: dry with string_field.rb
24
+ def text_result( sql_type, limit)
25
+ if sql_type == "varchar"
26
+ field_output( nil, limit)
27
+ else
28
+ text_area_output( 65536)
29
+ end
30
+ end
14
31
  end
@@ -3,4 +3,24 @@ class TimeField < Field
3
3
  def spec_setup_let_arg
4
4
  "#{name}: Time.current + rand(5000).seconds"
5
5
  end
6
+
7
+ def form_field_output
8
+ "<%= time_field_localized(f, :#{name}, #{singular}.#{name}, '#{ name.to_s.humanize }', #{auth ? auth+'.timezone' : 'nil'}) %>"
9
+ end
10
+
11
+ def line_field_output
12
+ "<% unless #{singular}.#{name}.nil? %>
13
+ <%= #{singular}.#{name}.in_time_zone(current_timezone).strftime('%l:%M %p ') + timezonize(current_timezone) %>
14
+ <% else %>
15
+ <span class='alert-danger'>MISSING</span>
16
+ <% end %>"
17
+ end
18
+
19
+ def spec_make_assertion
20
+ "#expect(page).to have_content(new_#{name} .in_time_zone(current_timezone).strftime('%l:%M %p ') + timezonize(current_timezone))"
21
+ end
22
+
23
+ def spec_list_view_assertion
24
+ "#expect(page).to have_content(#{singular}#{1}.#{name})"
25
+ end
6
26
  end
@@ -1,4 +1,4 @@
1
- class UUIDField < Field
1
+ class UUIDField < AssociationField
2
2
  def spec_setup_let_arg
3
3
  "#{name.to_s.gsub('_id','')}: #{name.to_s.gsub('_id','')}1"
4
4
  end
@@ -4,7 +4,7 @@ module HotGlue
4
4
 
5
5
  def filepath_prefix
6
6
  # todo: inject the context
7
- 'spec/dummy/' if Rails.env.test?
7
+ 'spec/dummy/' if $INTERNAL_SPECS
8
8
  end
9
9
 
10
10
 
@@ -13,6 +13,12 @@ module HotGlue
13
13
 
14
14
 
15
15
 
16
+
17
+ def filepath_prefix
18
+ 'spec/dummy/' if $INTERNAL_SPECS
19
+ end
20
+
21
+
16
22
  def initialize(*args) #:nodoc:
17
23
  super
18
24
  layout = options['layout'] || "hotglue"
@@ -28,7 +34,7 @@ module HotGlue
28
34
 
29
35
 
30
36
  @markup = options['markup'] || "erb"
31
- copy_file "erb/_flash_notices.erb", "#{'spec/dummy/' if Rails.env.test?}app/views/layouts/_flash_notices.erb"
37
+ copy_file "erb/_flash_notices.erb", "#{filepath_prefix}app/views/layouts/_flash_notices.erb"
32
38
 
33
39
  begin
34
40
  if Rails.version.split(".")[0].to_i == 6
@@ -51,7 +57,7 @@ module HotGlue
51
57
 
52
58
 
53
59
  begin
54
- rails_helper_contents = File.read("#{'spec/dummy/' if Rails.env.test?}spec/rails_helper.rb")
60
+ rails_helper_contents = File.read("#{filepath_prefix}spec/rails_helper.rb")
55
61
  if !rails_helper_contents.include?("Capybara.default_driver =")
56
62
  rails_helper_contents << "\nCapybara.default_driver = :selenium_chrome_headless "
57
63
  puts " HOTGLUE --> added to spec/rails_helper.rb: `Capybara.default_driver = :selenium_chrome_headless` "
@@ -61,14 +67,14 @@ module HotGlue
61
67
  rails_helper_contents.gsub!("RSpec.configure do |config|", "RSpec.configure do |config| \n
62
68
  config.include FactoryBot::Syntax::Methods
63
69
  ")
64
- puts " HOTGLUE --> added to #{'spec/dummy/' if Rails.env.test?}spec/rails_helper.rb: `config.include FactoryBot::Syntax::Methods` "
70
+ puts " HOTGLUE --> added to #{filepath_prefix}spec/rails_helper.rb: `config.include FactoryBot::Syntax::Methods` "
65
71
  end
66
72
 
67
73
  if ! rails_helper_contents.include?("require 'support/capybara_login.rb'")
68
74
  rails_helper_contents.gsub!("require 'rspec/rails'","require 'rspec/rails' \nrequire 'support/capybara_login.rb'")
69
75
  puts " HOTGLUE --> added to spec/rails_helper.rb: `require 'support/capybara_login.rb'` "
70
76
  end
71
- File.write("#{'spec/dummy/' if Rails.env.test?}spec/rails_helper.rb", rails_helper_contents)
77
+ File.write("#{filepath_prefix}spec/rails_helper.rb", rails_helper_contents)
72
78
 
73
79
  rescue StandardError => e
74
80
  puts "WARNING: error writing to spec/rails_helper --- #{e.message}"
@@ -95,7 +101,7 @@ module HotGlue
95
101
  theme_location = "themes/hotglue_scaffold_#{@theme}.scss"
96
102
  theme_file = "hotglue_scaffold_#{@theme}.scss"
97
103
 
98
- copy_file theme_location, "#{'spec/dummy/' if Rails.env.test?}app/assets/stylesheets/#{theme_file}"
104
+ copy_file theme_location, "#{filepath_prefix}app/assets/stylesheets/#{theme_file}"
99
105
 
100
106
  application_scss = File.read("app/assets/stylesheets/application.scss")
101
107
 
@@ -114,10 +120,10 @@ module HotGlue
114
120
 
115
121
 
116
122
  begin
117
- if !File.exist?("#{'spec/dummy/' if Rails.env.test?}config/hot_glue.yml")
123
+ if !File.exist?("#{filepath_prefix}config/hot_glue.yml")
118
124
  yaml = {layout: layout,
119
125
  markup: @markup}.to_yaml
120
- File.write("#{'spec/dummy/' if Rails.env.test?}config/hot_glue.yml", yaml)
126
+ File.write("#{filepath_prefix}config/hot_glue.yml", yaml)
121
127
 
122
128
  end
123
129
  rescue StandardError => e
@@ -126,8 +132,8 @@ module HotGlue
126
132
 
127
133
 
128
134
  begin
129
- if !File.exist?("#{'spec/dummy/' if Rails.env.test?}spec/support/capybara_login.rb")
130
- copy_file "capybara_login.rb", "#{'spec/dummy/' if Rails.env.test?}spec/support/capybara_login.rb"
135
+ if !File.exist?("#{filepath_prefix}spec/support/capybara_login.rb")
136
+ copy_file "capybara_login.rb", "#{filepath_prefix}spec/support/capybara_login.rb"
131
137
  end
132
138
  rescue StandardError => e
133
139
  puts "WARNING: error writing to #{Rails.env.test? ? 'spec/dummmy/' : ''}spec/support/capybara_login.rb --- #{e.message}"
@@ -16,6 +16,7 @@ module HotGlue
16
16
 
17
17
  @generator = generator
18
18
 
19
+ @modify = generator.modify
19
20
  @columns = generator.columns
20
21
  @smart_layout = generator.smart_layout
21
22
  @stacked_downnesting = generator.stacked_downnesting || false
@@ -39,7 +40,8 @@ module HotGlue
39
40
  portals: {
40
41
 
41
42
  },
42
- buttons: { size: @buttons_width}
43
+ buttons: { size: @buttons_width},
44
+ modify: @modify
43
45
  }
44
46
 
45
47
  # downnest_object.each do |child, size|
@@ -68,7 +70,7 @@ module HotGlue
68
70
  raise "Cannot build layout -- too few columns"
69
71
  end
70
72
 
71
- # smart layout: bootstrap_column_width columns per field; 4 column for EACH downnested portals, 2 column for buttons
73
+ # smart layout: bootstrap_column_width columns per field; 4 column for EACH downnested portal, 2 column for buttons
72
74
  if smart_layout
73
75
  # automatic control
74
76
  #