hot-glue 0.5.11 → 0.5.14

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 +4 -4
  2. data/.github/workflows/test.yml +17 -2
  3. data/README.md +78 -7
  4. data/lib/generators/hot_glue/default_config_loader.rb +12 -0
  5. data/lib/generators/hot_glue/field_factory.rb +2 -0
  6. data/lib/generators/hot_glue/fields/association_field.rb +1 -1
  7. data/lib/generators/hot_glue/fields/attachment_field.rb +27 -0
  8. data/lib/generators/hot_glue/fields/date_time_field.rb +3 -2
  9. data/lib/generators/hot_glue/fields/enum_field.rb +2 -2
  10. data/lib/generators/hot_glue/fields/field.rb +2 -2
  11. data/lib/generators/hot_glue/fields/integer_field.rb +1 -1
  12. data/lib/generators/hot_glue/fields/uuid_field.rb +1 -2
  13. data/lib/generators/hot_glue/flash_notices_install_generator.rb +20 -0
  14. data/lib/generators/hot_glue/hot_glue.rb +5 -0
  15. data/lib/generators/hot_glue/install_generator.rb +2 -7
  16. data/lib/generators/hot_glue/layout/builder.rb +38 -55
  17. data/lib/generators/hot_glue/markup_templates/erb.rb +9 -15
  18. data/lib/generators/hot_glue/scaffold_generator.rb +971 -1008
  19. data/lib/generators/hot_glue/templates/controller.rb.erb +5 -4
  20. data/lib/generators/hot_glue/templates/erb/_edit.erb +12 -0
  21. data/lib/generators/hot_glue/templates/erb/_flash_notices.erb +12 -8
  22. data/lib/generators/hot_glue/templates/erb/_list.erb +1 -2
  23. data/lib/generators/hot_glue/templates/erb/_show.erb +2 -2
  24. data/lib/generators/hot_glue/templates/erb/create.turbo_stream.erb +3 -4
  25. data/lib/generators/hot_glue/templates/erb/destroy.turbo_stream.erb +7 -1
  26. data/lib/generators/hot_glue/templates/erb/edit.erb +34 -16
  27. data/lib/generators/hot_glue/templates/erb/update.turbo_stream.erb +3 -6
  28. data/lib/generators/hot_glue/templates/system_spec.rb.erb +1 -1
  29. data/lib/hot-glue.rb +81 -0
  30. data/lib/hotglue/version.rb +1 -1
  31. data/script/test +2 -4
  32. metadata +6 -18
  33. data/lib/generators/hot_glue/templates/erb/_errors.erb +0 -11
  34. data/lib/generators/hot_glue/templates/haml/_errors.haml +0 -6
  35. data/lib/generators/hot_glue/templates/haml/_flash_notices.haml +0 -8
  36. data/lib/generators/hot_glue/templates/haml/_form.haml +0 -5
  37. data/lib/generators/hot_glue/templates/haml/_line.haml +0 -6
  38. data/lib/generators/hot_glue/templates/haml/_list.haml +0 -15
  39. data/lib/generators/hot_glue/templates/haml/_new_button.haml +0 -2
  40. data/lib/generators/hot_glue/templates/haml/_new_form.haml +0 -7
  41. data/lib/generators/hot_glue/templates/haml/_show.haml +0 -7
  42. data/lib/generators/hot_glue/templates/haml/create.turbo_stream.haml +0 -14
  43. data/lib/generators/hot_glue/templates/haml/destroy.turbo_stream.haml +0 -2
  44. data/lib/generators/hot_glue/templates/haml/edit.haml +0 -19
  45. data/lib/generators/hot_glue/templates/haml/edit.turbo_stream.haml +0 -4
  46. data/lib/generators/hot_glue/templates/haml/index.haml +0 -8
  47. data/lib/generators/hot_glue/templates/haml/new.haml +0 -1
  48. data/lib/generators/hot_glue/templates/haml/update.turbo_stream.haml +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dfaa7e5a93bb7693f4f0bd452e3bd76463b30fe05145eadd5cb7e999dcdaf2a5
4
- data.tar.gz: 908e35fb0d8657743c214773a11dccbdf8ee3312ee264b35538c1f4c262364f0
3
+ metadata.gz: c93b089a5dfd19941c88d9b330f0305dee83315bf7b8a6af436321dad842ac0b
4
+ data.tar.gz: cf17d5a487fdf1ae4230647923b42d344465bf1e81a06eb6eef0caa75282eb2c
5
5
  SHA512:
6
- metadata.gz: 16ac78ed4e0dc3bb92d5aad3e47063e2907915c2ce4a9ede816c9835b52875c3b7598471ee9a63de10a04e6e4bcb1c00e86a9d751c0b0d570d93f2bad8a2ee0a
7
- data.tar.gz: 968ef8a60a992ddb90906a0d2cf2a47df01d786fb4a040bad01bb89e1c0f8d0d0720f91035205d3ed35f11726e0c4d22db91f77b8ce97d5e3e1c799ae99bf929
6
+ metadata.gz: f9c6f8fdd02d3cd09e7c9e6a46a5a82c7125475b18f11fafa1cc3c609c4e7376c7c2cfcbc3a18483bd2027a69adfff859b62fa5d2405dabf371f4086247b240d
7
+ data.tar.gz: 51b3736cb2715e6387a13a98a4fe12bf450eee827679d80a6079d3b62546d31db234c4a818e03e801f07881ebd45da289b34b7c61dd5821d25db8084c8de6a61
@@ -2,7 +2,7 @@ name: Test
2
2
  on: [ push, pull_request ]
3
3
 
4
4
  jobs:
5
- build:
5
+ internal_tests:
6
6
  runs-on: ubuntu-latest
7
7
  steps:
8
8
  - uses: actions/checkout@v3
@@ -12,4 +12,19 @@ jobs:
12
12
  # Not needed with a .ruby-version file
13
13
  # runs 'bundle install' and caches installed gems automatically
14
14
  bundler-cache: true
15
- - run: script/test
15
+ - run: bundle install
16
+ - run: bundle exec rspec
17
+
18
+
19
+ system_tests:
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@v3
23
+ - name: Set up Ruby
24
+ uses: ruby/setup-ruby@v1
25
+ with:
26
+ # Not needed with a .ruby-version file
27
+ # runs 'bundle install' and caches installed gems automatically
28
+ bundler-cache: true
29
+ - run: bundle install
30
+ - run: bundle exec script/test
data/README.md CHANGED
@@ -750,6 +750,10 @@ end
750
750
 
751
751
  ```
752
752
 
753
+ ### `--button-icons` (default is no icons)
754
+ You can specify this either as builder flag or as a config setting (in `config/hot_glue.yml`)
755
+ Use `font-awesome` for Font Awesome or `none` for no icons.
756
+
753
757
 
754
758
  ### `--specs-only`
755
759
 
@@ -783,6 +787,8 @@ Omits delete button & destroy action.
783
787
 
784
788
  If you do not want inline editing of your list items but instead want to fall back to full page style behavior for your edit views, use `--big-edit`. Turbo still handles the page interactions, but the user is taken to a full-screen edit page instead of an edit-in-place interaction.
785
789
 
790
+ When using `--big-edit`, any downnested portals will be displayed on the edit page instead of on the list page.
791
+
786
792
  ### `--display-list-after-update`
787
793
 
788
794
  After an update-in-place normally only the edit view is swapped out for the show view of the record you just edited.
@@ -903,9 +909,6 @@ Use `before` to make the labels come before or `after` to make them come after.
903
909
  Omits the heading of column names that appears above the 1st row of data.
904
910
 
905
911
 
906
-
907
-
908
-
909
912
  ## Special Features
910
913
 
911
914
  ### `--attachments`
@@ -1121,9 +1124,29 @@ Thus, your factory object must have a method of the same name as the factory bei
1121
1124
  For example, assuming the example from above, we are going to do the lookup ourselves inside of our own `AgentFactory` object.)
1122
1125
 
1123
1126
  ```
1124
- agent_factory = AgentFactory.new(find_or_create_by_email: agent_company_params[:__lookup_email])
1127
+ factory = AgentFactory.new(find_or_create_by_email: agent_company_params[:__lookup_email],
1128
+ params: modified_params)
1125
1129
  ```
1126
1130
 
1131
+ Here the new AgentFactory will recieve any variables by keyword argument, and since you're specifying the calling code here, Hot Glue does not dictate your factory's setup.
1132
+ However, two special variables are in scope which you can use in your calling code.
1133
+
1134
+ `*_params` (where * is the name of the thing you are building)
1135
+ `modified_params` a variable that has been transmogrified for the timezone aware input
1136
+
1137
+ Either one must be recieved by your factory for your factory to create data based off the inputted data.
1138
+
1139
+ Rememebr, `*_params` has the input params passed only the through the sanitizer, and modified_params has it passed through the timezone aware mechanism and other Hot Glue-specific defaults.
1140
+
1141
+ Always:
1142
+ • In your factory calling code, assign the variable `factory = ` (do not use a different variable name),
1143
+ • Write a factory object with a `new` method that received the paramters you are specifying in your calling code,
1144
+ • Be sure your factory has an _instance method_ a method with the **same name** of the built object, which hot glue will call next:
1145
+
1146
+ `@agent = factory.agent`
1147
+
1148
+ Don't include this last line in your factory code.
1149
+
1127
1150
 
1128
1151
 
1129
1152
  ## Automatic Base Controller
@@ -1206,10 +1229,60 @@ def self.status_labels
1206
1229
 
1207
1230
  Now, your labels will show up on the front-end as defined in the `_labels` ("Is currently pending", etc) instead of the database-values.
1208
1231
 
1232
+ ### Validation Magic
1233
+
1234
+ Use ActiveRecord validations or hooks to validate your data. Hot Glue will automatically display the errors in the UI.
1235
+
1236
+ TO prevent a record from being destroyed, use a syntax like this:
1237
+
1238
+ ```
1239
+ before_destroy :check_if_allowed_to_destroy
1240
+
1241
+ def check_if_allowed_to_destroy
1242
+ if (some_condition)
1243
+ self.errors.add(:base, "Cannot delete")
1244
+ raise ActiveRecord::RecordNotDestroyed("Cannot delete because of some condition")
1245
+ end
1246
+ end
1247
+
1248
+ ```
1249
+
1250
+
1251
+
1252
+
1209
1253
 
1210
1254
  # VERSION HISTORY
1211
- #### 2023-04-19 - renamed previous version to v0.5.11
1212
1255
 
1256
+ #### TBR
1257
+ - When using big edit, updating a child will now re-render the parent EDIT record automatically.
1258
+
1259
+ For example
1260
+ `rails generate hot_glue:scafold LineItem --nested=invioce`
1261
+
1262
+ Whenever the line item is created, updated, or destroyed, the parent invoice record gets (edit action) re-rendered automatically. This happens for the big edit screen of the invoice.
1263
+
1264
+ #### 2023-05-14 - v0.5.14 Delete message flash notice and new flash notice partial
1265
+
1266
+ - This changes to how flash_notices work.
1267
+ - After you upgrade to 0.5.14 from a prior version, please re-install the global flash notice
1268
+ - template with:
1269
+
1270
+ `rails generate hot_glue:flash_notices_install`
1271
+
1272
+ The newer template will work with old Hot Glue scaffold (generated prior to 0.5.14) and new scaffold moving forward.
1273
+
1274
+ If you miss this step, your old Hot Glue flash notices template will not show the model error messages (but will continue to show the global alert & notice messages)
1275
+
1276
+ - The destroy action on controllers now produces an "alert" message for successful deletion.
1277
+
1278
+ #### 2023-04-24 - v0.5.12
1279
+ - adds new option for `bootstrap_column_width` (default is 2) to specify the number of bootstrap columns a visual column should take up
1280
+ - You can specify this as a builder option (`--bootstrap-column-width`)
1281
+ or in your `config/hot_glue.yml` file. Passing option will override config setting
1282
+ - Adds new option for `button_icons` (default to "font-awesome"); use `none` to have no button icons
1283
+ - When using big edit with downnested portals, the downnested portals now display on the edit page instead of the list page.
1284
+
1285
+ #### 2023-04-19 - renamed previous version to v0.5.11
1213
1286
 
1214
1287
  #### 2023-04-08 - v0.5.9.2
1215
1288
  • This begins a refactor of the field knowledge into properly abstracted Field objects
@@ -1218,8 +1291,6 @@ Now, your labels will show up on the front-end as defined in the `_labels` ("Is
1218
1291
  #### - v0.5.9.1
1219
1292
  • Fixed issue with ownership fields coming through as associations.
1220
1293
 
1221
-
1222
-
1223
1294
  #### 2023-03-17 - v0.5.9
1224
1295
  - Attachments! You can use Hot Glue to seamlessly create an image, file, or video attachment. Please see the docs in new flag `--atachments` under the "Special Features" section
1225
1296
 
@@ -0,0 +1,12 @@
1
+ module DefaultConfigLoader
2
+
3
+
4
+ def default_configs
5
+ @yaml_from_config ||= YAML.load(File.read("config/hot_glue.yml"))
6
+ end
7
+
8
+
9
+ def get_default_from_config(key: )
10
+ default_configs[key]
11
+ end
12
+ end
@@ -45,6 +45,7 @@ class FieldFactory
45
45
  end
46
46
  @class_name = class_name
47
47
 
48
+
48
49
  @field = field_class.new(name: name,
49
50
  hawk_keys: generator.hawk_keys,
50
51
  auth: generator.auth,
@@ -52,6 +53,7 @@ class FieldFactory
52
53
  alt_lookups: generator.alt_lookups,
53
54
  singular: generator.singular,
54
55
  update_show_only: generator.update_show_only,
56
+ attachment_data: generator.attachments[name.to_sym],
55
57
  sample_file_path: generator.sample_file_path)
56
58
  end
57
59
  end
@@ -4,7 +4,7 @@ require_relative './field.rb'
4
4
  class AssociationField < Field
5
5
 
6
6
  def initialize(name: , class_name: , alt_lookups: , singular: , update_show_only: ,
7
- hawk_keys: , auth: , sample_file_path: )
7
+ hawk_keys: , auth: , sample_file_path:, attachment_data: nil )
8
8
  super
9
9
  assoc_model = eval("#{class_name}.reflect_on_association(:#{assoc})")
10
10
 
@@ -1,4 +1,11 @@
1
1
  class AttachmentField < Field
2
+ attr_accessor :attachment_data
3
+ def initialize(name:, class_name:, alt_lookups:, singular:, update_show_only:, hawk_keys:, auth:,
4
+ sample_file_path: nil, attachment_data: )
5
+ super
6
+ @attachment_data = attachment_data
7
+ end
8
+
2
9
  def spec_setup_let_arg
3
10
  nil
4
11
  end
@@ -6,4 +13,24 @@ class AttachmentField < Field
6
13
  def spec_setup_and_change_act(which_partial = nil)
7
14
  " attach_file(\"#{singular}[#{name.to_s}]\", \"#{sample_file_path}\")"
8
15
  end
16
+
17
+ def thumbnail
18
+ attachment_data[:thumbnail]
19
+ end
20
+
21
+ def form_field_output
22
+ direct = attachment_data[:direct_upload]
23
+ dropzone = attachment_data[:dropzone]
24
+ field_result = (thumbnail ? "<%= #{singular}.#{name}.attached? ? image_tag(#{singular}.#{name}.variant(:#{thumbnail})) : '' %>" : "") +
25
+ "<br />\n" + (update_show_only.include?(name) ? "" : "<%= f.file_field :#{name} #{', direct_upload: true ' if direct}#{', "data-dropzone-target": "input"' if dropzone}%>")
26
+
27
+ if dropzone
28
+ 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>"
29
+ end
30
+ return field_result
31
+ end
32
+
33
+ def field_error_name
34
+ name
35
+ end
9
36
  end
@@ -10,7 +10,8 @@ class DateTimeField < Field
10
10
  end
11
11
 
12
12
  def spec_make_assertion
13
- super
13
+
14
+ "expect(page).to have_content(new_#{name}.in_time_zone(current_timezone).strftime('%m/%d/%Y @ %l:%M %p ') + timezonize(current_timezone))"
14
15
  end
15
16
 
16
17
  def spec_setup_let_arg
@@ -18,6 +19,6 @@ class DateTimeField < Field
18
19
  end
19
20
 
20
21
  def spec_list_view_assertion
21
- " " + ["expect(page).to have_content(#{singular}#{1}.#{name}.in_time_zone(current_timezone).strftime('%m/%d/%Y @ %l:%M %p ').gsub(' ', ' ') + timezonize(current_timezone) )"].join("\n ")
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) )"
22
23
  end
23
24
  end
@@ -19,9 +19,9 @@ class EnumField < Field
19
19
 
20
20
  def spec_list_view_assertion
21
21
  if(eval("#{singular_class}.respond_to?(:#{name}_labels)"))
22
- " " + "expect(page).to have_content(#{singular_class}.#{name}_labels[#{singular}#{1}.#{name}])"
22
+ "expect(page).to have_content(#{singular_class}.#{name}_labels[#{singular}#{1}.#{name}])"
23
23
  else
24
- " " + "expect(page).to have_content(#{singular}1.#{name})"
24
+ "expect(page).to have_content(#{singular}1.#{name})"
25
25
  end
26
26
  end
27
27
  end
@@ -6,7 +6,7 @@ class Field
6
6
  attr_accessor :hawk_keys, :auth, :sample_file_path
7
7
 
8
8
  def initialize(name: , class_name: , alt_lookups: , singular: , update_show_only: ,
9
- hawk_keys: , auth: , sample_file_path: nil)
9
+ hawk_keys: , auth: , sample_file_path: nil, attachment_data: nil )
10
10
  @name = name
11
11
  @alt_lookups = alt_lookups
12
12
  @singular = singular
@@ -42,7 +42,7 @@ class Field
42
42
  end
43
43
 
44
44
  def spec_list_view_assertion
45
- " " + ["expect(page).to have_content(#{singular}#{1}.#{name})"].join("\n ")
45
+ "expect(page).to have_content(#{singular}#{1}.#{name})"
46
46
  end
47
47
 
48
48
  def spec_related_column_lets
@@ -21,6 +21,6 @@ class IntegerField < Field
21
21
  end
22
22
 
23
23
  def spec_list_view_assertion
24
- " " + ["expect(page).to have_content(#{singular}#{1}.#{name})"].join("\n ")
24
+ "expect(page).to have_content(#{singular}#{1}.#{name})"
25
25
  end
26
26
  end
@@ -6,7 +6,6 @@ class UUIDField < Field
6
6
  def spec_list_view_assertion
7
7
  assoc_name = name.to_s.gsub('_id','')
8
8
  association = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
9
- " " + ["expect(page).to have_content(#{singular}#{1}.#{assoc_name}.#{HotGlue.derrive_reference_name(association.class_name)})"].join("\n ")
10
-
9
+ "expect(page).to have_content(#{singular}#{1}.#{assoc_name}.#{HotGlue.derrive_reference_name(association.class_name)})"
11
10
  end
12
11
  end
@@ -0,0 +1,20 @@
1
+ module HotGlue
2
+ class FlashNoticesInstallGenerator < Rails::Generators::Base
3
+ source_root File.expand_path('templates', __dir__)
4
+
5
+ def filepath_prefix
6
+ # todo: inject the context
7
+ 'spec/dummy/' if Rails.env.test?
8
+ end
9
+
10
+
11
+ def initialize(*args) #:nodoc:
12
+ super
13
+ copy_file "erb/_flash_notices.erb", "#{'spec/dummy/' if Rails.env.test?}app/views/layouts/_flash_notices.erb"
14
+
15
+ end
16
+ end
17
+ end
18
+
19
+
20
+
@@ -0,0 +1,5 @@
1
+
2
+
3
+ module HotGlue
4
+
5
+ end
@@ -27,13 +27,8 @@ module HotGlue
27
27
  end
28
28
 
29
29
 
30
- @markup = options['markup']
31
- if @markup == "haml"
32
- copy_file "haml/_flash_notices.haml", "#{'spec/dummy/' if Rails.env.test?}app/views/layouts/_flash_notices.haml"
33
- elsif @markup == "erb"
34
- copy_file "erb/_flash_notices.erb", "#{'spec/dummy/' if Rails.env.test?}app/views/layouts/_flash_notices.erb"
35
-
36
- end
30
+ @markup = options['markup'] || "erb"
31
+ copy_file "erb/_flash_notices.erb", "#{'spec/dummy/' if Rails.env.test?}app/views/layouts/_flash_notices.erb"
37
32
 
38
33
  begin
39
34
  if Rails.version.split(".")[0].to_i == 6
@@ -6,29 +6,34 @@ module HotGlue
6
6
  attr_reader :include_setting,
7
7
  :downnest_object,
8
8
  :buttons_width, :columns,
9
- :smart_layout, :specified_grouping_mode, :stacked_downnesting
10
-
11
- def initialize(include_setting: nil,
12
- downnest_object: nil,
13
- buttons_width: nil,
14
- smart_layout: nil,
15
- columns: nil,
16
- stacked_downnesting: false)
9
+ :smart_layout, :specified_grouping_mode,
10
+ :stacked_downnesting, :bootstrap_column_width
11
+
12
+ def initialize(generator: ,
13
+ include_setting: ,
14
+ buttons_width: )
15
+
16
+
17
+ @generator = generator
18
+
19
+ @columns = generator.columns
20
+ @smart_layout = generator.smart_layout
21
+ @stacked_downnesting = generator.stacked_downnesting || false
22
+ @downnest_object = generator.downnest_object
23
+
17
24
  @include_setting = include_setting
18
- @downnest_object = downnest_object
19
25
  @buttons_width = buttons_width
20
- @columns = columns
21
- @smart_layout = smart_layout
22
26
 
23
27
  @no_buttons = @buttons_width == 0
24
28
  @specified_grouping_mode = include_setting.include?(":")
25
- @stacked_downnesting = stacked_downnesting
29
+ @bootstrap_column_width = generator.bootstrap_column_width
30
+ @big_edit = generator.big_edit
26
31
  end
27
32
 
28
33
  def construct
29
34
  layout_object = {
30
35
  columns: {
31
- size_each: smart_layout ? 2 : (specified_grouping_mode ? nil : 1),
36
+ size_each: smart_layout ? bootstrap_column_width : (specified_grouping_mode ? nil : 1),
32
37
  container: [] # array of arrays
33
38
  },
34
39
  portals: {
@@ -41,33 +46,29 @@ module HotGlue
41
46
  # layout_object[:portals][child] = {size: size}
42
47
  # end
43
48
 
44
- # smart layout: 2 columns per field; 4 column for EACH downnested portals, 2 column for buttons
45
- how_many_downnest = downnest_object.size
46
-
47
49
  bootstrap_columns = (12 - @buttons_width )
48
50
 
49
- if(!stacked_downnesting)
50
- bootstrap_columns = bootstrap_columns - (downnest_object.collect{|k,v| v}.sum)
51
- else
52
- bootstrap_columns = bootstrap_columns - 4
53
- end
51
+ unless @big_edit
52
+ # how_many_downnest = downnest_object.size
53
+ if(!stacked_downnesting)
54
+ bootstrap_columns = bootstrap_columns - (downnest_object.collect{|k,v| v}.sum)
55
+ else
56
+ bootstrap_columns = bootstrap_columns - 4
57
+ end
54
58
 
55
- available_columns = (bootstrap_columns / 2).floor # bascially turns the 12-column grid into a 6-column grid
59
+ # downnest_children_width = []
60
+ downnest_object.each do |child, size|
61
+ layout_object[:portals][child] = {size: size}
62
+ end
63
+ end
64
+ available_columns = (bootstrap_columns / bootstrap_column_width).floor
56
65
 
66
+ # when set to 2, turns the 12-column grid into a 6-column grid
57
67
  if available_columns < 0
58
- raise "Cannot build layout with #{how_many_downnest} downnested portals"
59
- end
60
- #
61
- # if !stacked_downnesting
62
- #
63
- # else
64
- #
65
- # end
66
- downnest_children_width = []
67
- downnest_object.each do |child, size|
68
- layout_object[:portals][child] = {size: size}
68
+ raise "Cannot build layout -- too few columns"
69
69
  end
70
70
 
71
+ # smart layout: bootstrap_column_width columns per field; 4 column for EACH downnested portals, 2 column for buttons
71
72
  if smart_layout
72
73
  # automatic control
73
74
  #
@@ -86,20 +87,20 @@ module HotGlue
86
87
 
87
88
  else
88
89
  layout_object[:columns][:container] = (0..available_columns-1).collect { |x|
89
- [ columns[x]]
90
+ [ columns[x] ]
90
91
  }
91
92
  layout_object[:columns][:container] = (0..available_columns-1).collect { |x| [columns[x]] }
92
93
  layout_object[:columns][:container].reject!{|x| x == [nil]}
93
- layout_object[:columns][:size_each] = 2
94
+ layout_object[:columns][:size_each] = bootstrap_column_width
94
95
  end
95
96
  elsif ! specified_grouping_mode
96
97
  # not smart and no specified grouping
97
- layout_object[:columns][:button_columns] = 2
98
+ layout_object[:columns][:button_columns] = bootstrap_column_width
98
99
 
99
100
  layout_object[:columns][:container] = columns.collect{|col| [col]}
100
101
 
101
102
  else # specified grouping mode -- the builder is given control
102
- layout_object[:columns][:button_columns] = 2
103
+ layout_object[:columns][:button_columns] = bootstrap_column_width
103
104
 
104
105
  (0..available_columns-1).each do |int|
105
106
  layout_object[:columns][:container][int] = []
@@ -124,24 +125,6 @@ module HotGlue
124
125
  end
125
126
  end
126
127
 
127
- # TODO: do I want this code that expands the downnest portal
128
- # maybe refactor into a setting on the --downnest flag itself somehow
129
- # if layout_object[:columns][:container].size < available_columns
130
- # available = available_columns - layout_object[:columns][:container].size
131
- # downnest_child_count = 0
132
- #
133
- # while(available > 0)
134
- # if (downnest_child_count <= downnest_children.size-1)
135
- # layout_object[:portals][downnest_children[downnest_child_count]][:size] = layout_object[:portals][downnest_children[downnest_child_count]][:size] + 2
136
- # else
137
- # # leave as-is
138
- # end
139
- # downnest_child_count = downnest_child_count + 1
140
- # available = available - 1
141
- # end
142
- # # give some space back to the downnest
143
- # end
144
-
145
128
  puts "*** constructed smart layout columns #{layout_object.inspect}"
146
129
  layout_object
147
130
  end
@@ -8,20 +8,22 @@ module HotGlue
8
8
  :inline_list_labels, :layout_object,
9
9
  :columns, :col_identifier, :singular,
10
10
  :form_placeholder_labels, :hawk_keys, :update_show_only,
11
- :alt_lookups, :attachments, :show_only
11
+ :alt_lookups, :attachments, :show_only, :columns_map
12
12
 
13
13
 
14
- def initialize(singular:, singular_class: ,
14
+ def initialize(singular:, singular_class: ,
15
15
  layout_strategy: , magic_buttons: ,
16
16
  small_buttons: , show_only: ,
17
17
  ownership_field: , form_labels_position: ,
18
18
  inline_list_labels: ,
19
19
  form_placeholder_labels:, hawk_keys:,
20
- update_show_only:, alt_lookups: , attachments: )
20
+ update_show_only:, alt_lookups: , attachments: , columns_map: )
21
21
 
22
22
  @singular = singular
23
23
  @singular_class = singular_class
24
24
 
25
+ @columns_map = columns_map
26
+
25
27
  @magic_buttons = magic_buttons
26
28
  @small_buttons = small_buttons
27
29
  @layout_strategy = layout_strategy
@@ -60,7 +62,7 @@ module HotGlue
60
62
 
61
63
  columns = layout_object[:columns][:container]
62
64
  result = columns.map{ |column|
63
- "<div class='#{col_identifier}' heading--#{singular}--#{column.join("-")} " + col_style + ">" +
65
+ "<div class='#{col_identifier} heading--#{singular}--#{column.join("-")}' " + col_style + ">" +
64
66
  column.map(&:to_s).map{|col_name| "#{col_name.humanize}"}.join("<br />") + "</div>"
65
67
  }.join("\n")
66
68
  return result
@@ -80,17 +82,9 @@ module HotGlue
80
82
  " <div class='#{column_classes} cell--#{singular}--#{column.join("-")}' >" +
81
83
  column.map { |col|
82
84
  if attachments.keys.include?(col)
83
- this_attachment = attachments[col]
84
- thumbnail = this_attachment[:thumbnail]
85
- direct = this_attachment[:direct_upload]
86
- dropzone = this_attachment[:dropzone]
87
- field_result = (this_attachment[:thumbnail] ? "<%= #{singular}.#{col}.attached? ? image_tag(#{singular}.#{col}.variant(:#{thumbnail})) : '' %>" : "") +
88
- "<br />\n" + (update_show_only.include?(col) ? "" : "<%= f.file_field :#{col} #{', direct_upload: true ' if direct}#{', "data-dropzone-target": "input"' if dropzone}%>")
89
-
90
- if dropzone
91
- 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>"
92
- end
93
- field_error_name = col
85
+
86
+ field_result = columns_map[col].form_field_output
87
+ field_error_name = columns_map[col].field_error_name
94
88
  else
95
89
 
96
90
  type = eval("#{singular_class}.columns_hash['#{col}']").type