hot-glue 0.5.23.1 → 0.5.25

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bdb39b06854037640b63ad674ce2785fcdbb5ea7947b9bf62483b8bc81f24aed
4
- data.tar.gz: d64d081e67e29d893849950568ba70bbdaccb057da5d2ade725ea26e74040664
3
+ metadata.gz: 9c2b46bf01f0742356ab56ad4cd139534becbe919b8e38ac8d166f8ca1c1c47c
4
+ data.tar.gz: b697f19f9928249d693632ff040f7ebb97ddf396fd8fb8d74b60f3abfe3a6bca
5
5
  SHA512:
6
- metadata.gz: f09eb212dc5f40325cccb88273088e3fd8ab096fbccf42f4c99d4bb9fb8964efde375be68e9b927fadd5b077d846d8b208b149030b93cabe4348d76a0ad4758d
7
- data.tar.gz: 2dc1598871b44d6199011e2b36e6ed8c88c4a2564c249e363130cda931dfb5cef5c4900dade36182ec68216da12ca52f51b941db02056c2ee6d9abb8e68bacf8
6
+ metadata.gz: 9ad16ec01f21d5ac9013cbbc0ee2e364cce4deec8ff52544d34438c641a4009d763ff953e70813d2f4b5e5b35904959ca49b5fea50dc8187c254c0bc0a19850c
7
+ data.tar.gz: f7cbb297d36077486c6983b0dfebee09b32871b316f28fe215f3578df5054445f337d372e13b55d84f44f30a6e4e0de776df14cb3137a4ec12c8e481ed38abba
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hot-glue (0.5.23.1)
4
+ hot-glue (0.5.25)
5
5
  ffaker (~> 2.16)
6
6
  kaminari (~> 1.2)
7
7
  rails (> 5.1)
@@ -139,7 +139,7 @@ GEM
139
139
  mini_mime (1.1.2)
140
140
  mini_portile2 (2.8.4)
141
141
  minitest (5.16.3)
142
- net-imap (0.3.7)
142
+ net-imap (0.4.1)
143
143
  date
144
144
  net-protocol
145
145
  net-pop (0.1.2)
data/README.md CHANGED
@@ -664,13 +664,16 @@ For booleans shown as checkboxes or switches, it affects only the view output as
664
664
 
665
665
  You will need to separately specify them as show-only if you want them to be non-editable.
666
666
 
667
- The available modifiers are:
667
+ Notice that each modifiers can be used with specific field types.
668
668
 
669
- | modifier | what it does | can be used on | | |
670
- |---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------|---|---|
671
- | $ | wraps output in `number_to_currency()` | float, integer | | |
672
- | truthy label\|falsy label | specify a binary switch with a pipe (\|) character if the value is truthy, it will display as "truthy label" if the value is falsy, it will display as "falsy label" | boolean, datetime, date, time | | |
673
- | | | | | |
669
+ | user modifier | what it does | Field types | | |
670
+ |-------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------|---|---|
671
+ | $ | wraps output in `number_to_currency()` | floats and integers | | |
672
+ | (truthy label)\|(falsy label) | specify a binary switch with a pipe (\|) character if the value is truthy, it will display as "truthy label" if the value is falsy, it will display as "falsy label" | booleans, datetimes, dates, times | | |
673
+ | partials | applies to enums only, you must have a partial whose name matches each enum type | enums only | | |
674
+ | tinymce | applies to text fields only, be sure to setup TineMCE globally | text fields only | | |
675
+
676
+ Except for "(truthy label)" and "(falsy label)" which represent the labels you should specify separated by the pipe character (|), use the modifier exactly as shown.
674
677
 
675
678
  ### `--pundit`
676
679
  If you enable Pundit, your controllers will look for a Policy that matches the name of the thing being built.
@@ -891,10 +894,15 @@ Produces ONLY the controller spec file, nothing else.
891
894
  Produces all the files except the spec file.
892
895
 
893
896
 
894
- ### `--no-paginate`
897
+ ### `--no-paginate` (default: false)
895
898
 
896
899
  Omits pagination. (All list views have pagination by default.)
897
900
 
901
+ ### `--paginate-per-page-selector` (default: false)
902
+
903
+ Show a small drop-down below the list to let the user choose 10, 25, or 100 results per page.
904
+
905
+
898
906
  ### `--no-list`
899
907
 
900
908
  Omits list action. Only makes sense to use this if want to create a view where you only want the create button or to navigate to the update screen alternative ways. (The new/create still appears, as well the edit, update & destroy actions are still created even though there is no natural way to navigate to them.)
@@ -1402,8 +1410,99 @@ end
1402
1410
 
1403
1411
  ```
1404
1412
 
1413
+
1414
+ ### TinyMCE
1415
+ 1. `bundle add tinymce-rails` to add it to your Gemfile
1416
+
1417
+ 2. Add this inside of your `<head>` tag (at the bottom is fine)
1418
+ ```
1419
+ <%= tinymce_assets %>
1420
+ ```
1421
+ 3. Then, also inside of your `<head>` tag, add this:
1422
+ ```
1423
+ <script>
1424
+ TinyMCERails.configuration.default = {
1425
+ selector: "textarea.tinymce",
1426
+ cache_suffix: "?v=6.7.0",
1427
+ menubar: "insert view format table tools",
1428
+ toolbar: ["bold italic | link | undo redo | forecolor backcolor | bullist numlist outdent indent | table | uploadimage | code"],
1429
+ plugins: "table,fullscreen,image,code,searchreplace,wordcount,visualblocks,visualchars,link,charmap,directionality,nonbreaking,media,advlist,autolink,lists",
1430
+ images_upload_url: "/uploader/image"
1431
+ };
1432
+
1433
+ </script>
1434
+ ```
1435
+
1436
+ Then to `application.js` add
1437
+
1438
+ ```
1439
+ import "./tinymce_init"
1440
+
1441
+ ```
1442
+
1443
+ create a file `tinymce_init.js` with this content
1444
+
1445
+ ```
1446
+ const reinitTiny = () => {
1447
+ tinymce.init({
1448
+ selector: 'textarea.tinymce', // Add the appropriate selector for your textareas
1449
+ // Other TinyMCE configuration options
1450
+ });
1451
+ }
1452
+
1453
+ window.addEventListener('turbo:before-fetch-response', () => {
1454
+ tinymce.remove();
1455
+ tinymce.init({selector:'textarea.tinymce'});
1456
+ })
1457
+
1458
+ window.addEventListener('turbo:frame-render', reinitTiny)
1459
+ window.addEventListener('turbo:render', reinitTiny)
1460
+ ```
1461
+
1462
+ Once you have completed this setup, you can now use `--modify` with the modifier `tinymce`.
1463
+
1464
+ For example, to display the field `my_story` on the object `Thing`, you'd generate with:
1465
+
1466
+ ```
1467
+ bin/rails generate Thing --include=my_story --modify='my_story{tinymce}'
1468
+ ```
1469
+
1405
1470
  # VERSION HISTORY
1406
1471
 
1472
+ #### 2023-10-16 - v0.5.25
1473
+
1474
+ - Fixes scoping on Pundit-built controllers; even when using pundit we should still wrap to the current build's own ownership scope (#132
1475
+ - don't write to the nav file if we're building a nested controller (#134)
1476
+ - adds system specs for self-auth feature
1477
+ - Pagination Fixes:
1478
+
1479
+ A new flag `--paginate-per-page-selector` (default false) will allow you to show a small drop-down to let the user choose 10, 25, or 100 results per page.
1480
+
1481
+ To get pagination to work, choose either #1 OR #2 below. #1 will replace the templates in app/views/kaminari so don't do that if you have modified them since first generating them out of Kaminari.
1482
+
1483
+ 1. Replace the kaminari gem with my fork and regenerate your templates
1484
+ bundle remove kaminari
1485
+ bundle add kaminari --git="https://github.com/jasonfb/kaminari.git" --branch="master"
1486
+ bundle install
1487
+ rm -rf app/views/kaminari
1488
+ rails g kaminari:config
1489
+
1490
+
1491
+ 2. Go into app/views/kaminari/ and modify each template in this folder by adding ` 'data-turbo-action': 'advance'` to all of the links (which mostly appear in this code as the `link_to_unless` helper-- add the parameter onto the end of the calls to those helpers.)
1492
+
1493
+
1494
+
1495
+ #### 2023-10-07 - v0.5.24
1496
+
1497
+ - TinyMCE implementation. See 'TinyMCE' above.
1498
+ Note: I also plan to implement ActionText as an alternative. However, because TinyMCE is implemented with a `text` field type an ActionText is implemented with a Rails-specific `rich_text` field type, the two mechanisms will be incompatible with one another. TinyMCE has an annoying drawback in how it works with Turbo refreshes (not very consistently), and style of loading Javascript is discordant with Rails moving forward. So I am leaving this implementation as experimental.
1499
+ - Spec Savestart code: In the behavior specs, there is a code marker (start & end) where you can insert custom code that gets saved between
1500
+ build. The start code maker has changed from `#HOTGLUE-SAVESTART` to `# HOTGLUE-SAVESTART`
1501
+ and the end code marker has changed from `#HOTGLUE-END` to `# HOTGLUE-END`. This now conforms to Rubocop.
1502
+ Be sure to do find & replace in your existing projects to keep your custom code.
1503
+ - Fix for specs for attachment fields. If you have attachments fields, you must have a sample file at `spec/fixtures/glass_button.png`
1504
+ - Pundit now correctly protects the `index` action (authorize was missing before)
1505
+
1407
1506
  #### 2023-10-01 - v0.5.23
1408
1507
 
1409
1508
  - You can now use the modify flag on enum type fields to display a partial with the same name of that enum type.
@@ -1897,7 +1996,5 @@ To run only the internal specs, use
1897
1996
 
1898
1997
  `rspec spec`
1899
1998
 
1900
- Internal Test coverage as of 2023-02-10 (v0.5.7)
1901
-
1902
- <img width="1202" alt="Screen Shot 2023-02-10 at 4 43 59 PM" src="https://user-images.githubusercontent.com/59002/218204736-5740505b-1ec8-456f-b0fb-9c359f6f7037.png">
1903
-
1999
+ Internal Test coverage as of 2023-10-15 (v0.5.24)
2000
+ All Files ( 86.29% covered at 75.64 hits/line )
@@ -55,10 +55,11 @@ class FieldFactory
55
55
  class_name: generator.singular_class,
56
56
  alt_lookups: generator.alt_lookups,
57
57
  singular: generator.singular,
58
+ self_auth: generator.self_auth,
58
59
  update_show_only: generator.update_show_only,
59
60
  attachment_data: generator.attachments[name.to_sym],
60
61
  sample_file_path: generator.sample_file_path,
61
- modify: generator.modify[name.to_sym] || nil,
62
+ modify_as: generator.modify_as[name.to_sym] || nil,
62
63
  display_as: generator.display_as[name.to_sym] || nil,
63
64
  default_boolean_display: generator.default_boolean_display)
64
65
  end
@@ -10,7 +10,7 @@ class AssociationField < Field
10
10
  update_show_only: ,
11
11
  hawk_keys: , auth: , sample_file_path:, ownership_field: ,
12
12
  attachment_data: nil , layout_strategy: , form_placeholder_labels: nil,
13
- form_labels_position:, modify: )
13
+ form_labels_position:, modify_as: , self_auth: )
14
14
  super
15
15
 
16
16
  @assoc_model = eval("#{class_name}.reflect_on_association(:#{assoc})")
@@ -4,7 +4,7 @@ class AttachmentField < Field
4
4
  display_as:,
5
5
  singular:, update_show_only:, hawk_keys:, auth:,
6
6
  sample_file_path: nil, attachment_data:, ownership_field:, layout_strategy: ,
7
- form_placeholder_labels: , form_labels_position:, modify: )
7
+ form_placeholder_labels: , form_labels_position:, modify_as:, self_auth: )
8
8
  super
9
9
 
10
10
  @attachment_data = attachment_data
@@ -14,7 +14,17 @@ class AttachmentField < Field
14
14
  nil
15
15
  end
16
16
 
17
- def spec_setup_and_change_act(which_partial = nil)
17
+ def spec_list_view_natural_assertion
18
+ "within('div.#{singular}--#{name}') do
19
+ img = page.find('img')
20
+ expect(img['src']).to end_with('glass_button.png')
21
+ end"
22
+
23
+ # "expect(page).to have_content(#{singular}#{1}.#{name})"
24
+ end
25
+
26
+
27
+ def spec_setup_and_change_act(which_partial = nil)
18
28
  " attach_file(\"#{singular}[#{name.to_s}]\", \"#{sample_file_path}\")"
19
29
  end
20
30
 
@@ -23,9 +23,9 @@ class BooleanField < Field
23
23
 
24
24
  def radio_button_display
25
25
  " <%= f.radio_button(:#{name}, '0', checked: #{singular}.#{name} ? '' : 'checked', class: '#{@layout_strategy.form_checkbox_input_class}') %>\n" +
26
- " <%= f.label(:#{name}, value: '#{modify_binary? && modify[:binary][:falsy] || 'No'}', for: '#{singular}_#{name}_0') %>\n" +
26
+ " <%= f.label(:#{name}, value: '#{modify_binary? && modify_as[:binary][:falsy] || 'No'}', for: '#{singular}_#{name}_0') %>\n" +
27
27
  " <br /> <%= f.radio_button(:#{name}, '1', checked: #{singular}.#{name} ? 'checked' : '' , class: '#{@layout_strategy.form_checkbox_input_class}') %>\n" +
28
- " <%= f.label(:#{name}, value: '#{modify_binary? && modify[:binary][:truthy] || 'Yes'}', for: '#{singular}_#{name}_1') %>\n"
28
+ " <%= f.label(:#{name}, value: '#{modify_binary? && modify_as[:binary][:truthy] || 'Yes'}', for: '#{singular}_#{name}_1') %>\n"
29
29
  end
30
30
 
31
31
  def checkbox_display
@@ -60,9 +60,9 @@ class BooleanField < Field
60
60
  "<% if #{singular}.#{name}.nil? %>
61
61
  <span class='alert-danger'>MISSING</span>
62
62
  <% elsif #{singular}.#{name} %>
63
- #{modify[:binary][:truthy]}
63
+ #{modify_as[:binary][:truthy]}
64
64
  <% else %>
65
- #{modify[:binary][:falsy]}
65
+ #{modify_as[:binary][:falsy]}
66
66
  <% end %>"
67
67
  else
68
68
  "<% if #{singular}.#{name}.nil? %>
@@ -41,7 +41,7 @@ class EnumField < Field
41
41
  res = "<%= f.collection_select(:#{name}, enum_to_collection_select(#{enum_definer}), :key, :value, {selected: #{singular}.#{name} }, class: 'form-control') %>"
42
42
 
43
43
 
44
- if modify && modify[:enum] == :partials
44
+ if modify_as && modify_as[:enum] == :partials
45
45
  res << partial_render
46
46
  end
47
47
  res
@@ -61,7 +61,7 @@ class EnumField < Field
61
61
  <span class='alert-danger'>Missing #{name}</span>
62
62
  <% else %>"
63
63
 
64
- if modify && modify[:enum] == :partials
64
+ if modify_as && modify_as[:enum] == :partials
65
65
  res << partial_render
66
66
  else
67
67
  res << "<%= #{enum_definer}[#{singular}.#{name}.to_sym] %>"
@@ -1,7 +1,9 @@
1
1
  class Field
2
2
  attr_accessor :assoc_model, :assoc_name, :assoc_class, :associations, :alt_lookups, :auth,
3
- :assoc_label, :class_name, :default_boolean_display, :display_as, :form_placeholder_labels, :form_labels_position,
4
- :hawk_keys, :layout_strategy, :limit, :modify, :name, :object, :sample_file_path,
3
+ :assoc_label, :class_name, :default_boolean_display, :display_as, :form_placeholder_labels,
4
+ :form_labels_position,
5
+ :hawk_keys, :layout_strategy, :limit, :modify_as, :name, :object, :sample_file_path,
6
+ :self_auth,
5
7
  :singular_class, :singular, :sql_type, :ownership_field,
6
8
  :update_show_only
7
9
 
@@ -16,12 +18,13 @@ class Field
16
18
  form_placeholder_labels: ,
17
19
  hawk_keys: nil,
18
20
  layout_strategy: ,
19
- modify: ,
21
+ modify_as: , #note non-standard naming as to avoid collision with Ruby reserved word modify
20
22
  name: ,
21
23
  ownership_field: ,
22
24
  sample_file_path: nil,
23
25
  singular: ,
24
- update_show_only:
26
+ update_show_only:,
27
+ self_auth:
25
28
  )
26
29
  @name = name
27
30
  @layout_strategy = layout_strategy
@@ -35,9 +38,10 @@ class Field
35
38
  @form_placeholder_labels = form_placeholder_labels
36
39
  @ownership_field = ownership_field
37
40
  @form_labels_position = form_labels_position
38
- @modify = modify
41
+ @modify_as = modify_as
39
42
  @display_as = display_as
40
43
 
44
+ @self_auth = self_auth
41
45
  @default_boolean_display = default_boolean_display
42
46
 
43
47
  # TODO: remove knowledge of subclasses from Field
@@ -72,7 +76,7 @@ class Field
72
76
  if !modify_binary?
73
77
  "expect(page).to have_content(new_#{name})"
74
78
  else
75
- "expect(page).to have_content('#{modify[:binary][:truthy]}'"
79
+ "expect(page).to have_content('#{modify_as[:binary][:truthy]}'"
76
80
  end
77
81
  end
78
82
 
@@ -82,12 +86,16 @@ class Field
82
86
  end
83
87
 
84
88
  def spec_list_view_natural_assertion
85
- "expect(page).to have_content(#{singular}#{1}.#{name})"
89
+ if !self_auth
90
+ "expect(page).to have_content(#{singular}#{1}.#{name})"
91
+ else
92
+ "expect(page).to have_content(current_#{singular}.#{name})"
93
+ end
86
94
  end
87
95
 
88
96
  def spec_list_view_assertion
89
97
  if modify_binary?
90
- "expect(page).to have_content('#{modify[:binary][:truthy]}'"
98
+ "expect(page).to have_content('#{modify_as[:binary][:truthy]}'"
91
99
  else
92
100
  spec_list_view_natural_assertion
93
101
  end
@@ -107,7 +115,7 @@ class Field
107
115
  end
108
116
 
109
117
  def viewable_output
110
- if modify
118
+ if modify_as
111
119
  modified_display_output
112
120
  else
113
121
  "<%= #{singular}.#{name} %>"
@@ -115,11 +123,13 @@ class Field
115
123
  end
116
124
 
117
125
  def modified_display_output
118
- if modify[:cast] && modify[:cast] == "$"
126
+ if modify_as[:cast] && modify_as[:cast] == "$"
119
127
  "<%= number_to_currency(#{singular}.#{name}) %>"
120
- elsif modify[:binary]
121
- "<%= #{singular}.#{name} ? '#{modify[:binary][:truthy]}' : '#{modify[:binary][:falsy]}' %>"
122
- elsif modify[:enum]
128
+ elsif modify_as[:binary]
129
+ "<%= #{singular}.#{name} ? '#{modify_as[:binary][:truthy]}' : '#{modify_as[:binary][:falsy]}' %>"
130
+ elsif modify_as[:tinymce]
131
+
132
+ elsif modify_as[:enum]
123
133
  "<%= render partial: #{singular}.#{name}, locals: {#{singular}: #{singular}} %>"
124
134
  end
125
135
  end
@@ -128,16 +138,16 @@ class Field
128
138
  " <%= 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"
129
139
  end
130
140
 
131
- def text_area_output(field_length )
141
+ def text_area_output(field_length, extra_classes: "")
132
142
  lines = field_length % 40
133
143
  if lines > 5
134
144
  lines = 5
135
145
  end
136
- "<%= f.text_area :#{name}, class: 'form-control', autocomplete: 'off', cols: 40, rows: '#{lines}'" + ( form_placeholder_labels ? ", placeholder: '#{name.to_s.humanize}'" : "") + " %>"
146
+ "<%= f.text_area :#{name}, class: 'form-control#{extra_classes}', autocomplete: 'off', cols: 40, rows: '#{lines}'" + ( form_placeholder_labels ? ", placeholder: '#{name.to_s.humanize}'" : "") + " %>"
137
147
  end
138
148
 
139
149
  def modify_binary? # safe
140
- !!(modify && modify[:binary])
150
+ !!(modify_as && modify_as[:binary])
141
151
  end
142
152
 
143
153
  def display_boolean_as
@@ -16,7 +16,7 @@ class TextField < Field
16
16
  if sql_type == "varchar" || sql_type == "character varying"
17
17
  field_output( nil, limit || 40)
18
18
  else
19
- text_area_output( 65536)
19
+ text_area_output( 65536, extra_classes: (modify_as == {tinymce: 1} ? " tinymce" : "" ))
20
20
  end
21
21
  end
22
22
 
@@ -17,7 +17,7 @@ module HotGlue
17
17
 
18
18
  @generator = generator
19
19
 
20
- @modify = generator.modify
20
+ @modify_as = generator.modify_as
21
21
  @display_as = generator.display_as
22
22
  @columns = generator.columns
23
23
  @smart_layout = generator.smart_layout
@@ -46,7 +46,7 @@ module HotGlue
46
46
 
47
47
  },
48
48
  buttons: { size: @buttons_width},
49
- modify: @modify,
49
+ modify_as: @modify_as,
50
50
  display_as: @display_as
51
51
  }
52
52
 
@@ -105,7 +105,10 @@ module HotGlue
105
105
  else
106
106
  columns_map[col].form_field_output
107
107
  end
108
- add_spaces_each_line( "\n <span class='<%= \"alert-danger\" if #{singular}.errors.details.keys.include?(:#{field_error_name}) %>' #{'style="display: inherit;"'} >\n" +
108
+ # byebug
109
+ @tinymce_stimulus_controller = (columns_map[col].modify_as == {tinymce: 1} ? "data-controller='tiny-mce' " : "")
110
+
111
+ add_spaces_each_line( "\n <span #{@tinymce_stimulus_controller}class='<%= \"alert-danger\" if #{singular}.errors.details.keys.include?(:#{field_error_name}) %>' #{'style="display: inherit;"'} >\n" +
109
112
  add_spaces_each_line( (form_labels_position == 'before' ? the_label || "" : "") +
110
113
  + " <br />\n" + field_result +
111
114
  (form_labels_position == 'after' ? the_label : "") , 4) +
@@ -18,10 +18,12 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
18
18
  source_root File.expand_path('templates', __dir__)
19
19
  attr_accessor :alt_lookups, :attachments, :auth, :big_edit, :button_icons, :bootstrap_column_width, :columns,
20
20
  :default_boolean_display,
21
- :display_as, :downnest_children, :downnest_object, :hawk_keys, :layout_object, :modify,
21
+ :display_as, :downnest_children, :downnest_object, :hawk_keys, :layout_object,
22
+ :modify_as,
22
23
  :nest_with, :path, :plural, :sample_file_path, :show_only_data, :singular,
23
24
  :singular_class, :smart_layout, :stacked_downnesting, :update_show_only, :ownership_field,
24
- :layout_strategy, :form_placeholder_labels, :form_labels_position, :pundit
25
+ :layout_strategy, :form_placeholder_labels, :form_labels_position, :pundit,
26
+ :self_auth
25
27
 
26
28
  class_option :singular, type: :string, default: nil
27
29
  class_option :plural, type: :string, default: nil
@@ -46,6 +48,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
46
48
  class_option :no_controller, type: :boolean, default: false
47
49
  class_option :no_list, type: :boolean, default: false
48
50
  class_option :no_paginate, type: :boolean, default: false
51
+ class_option :paginate_per_page_selector, type: :boolean, default: false
49
52
  class_option :big_edit, type: :boolean, default: false
50
53
  class_option :show_only, type: :string, default: ""
51
54
  class_option :update_show_only, type: :string, default: ""
@@ -204,7 +207,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
204
207
  puts "show only field #{@show_only}}"
205
208
  end
206
209
 
207
- @modify = {}
210
+ @modify_as = {}
208
211
  if !options['modify'].empty?
209
212
 
210
213
  modify_input = options['modify'].split(",")
@@ -213,13 +216,14 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
213
216
  key, lookup_as = $1, $2
214
217
 
215
218
  if ["$"].include?($2)
216
- @modify[key.to_sym] = {cast: $2}
219
+ @modify_as[key.to_sym] = {cast: $2}
217
220
  elsif $2.include?("|")
218
221
  binary = $2.split("|")
219
- @modify[key.to_sym] = {binary: {truthy: binary[0], falsy: binary[1]}}
222
+ @modify_as[key.to_sym] = {binary: {truthy: binary[0], falsy: binary[1]}}
220
223
  elsif $2 == "partial"
221
- @modify[key.to_sym] = {enum: :partials}
222
-
224
+ @modify_as[key.to_sym] = {enum: :partials}
225
+ elsif $2 == "tinymce"
226
+ @modify_as[key.to_sym] = {tinymce: 1}
223
227
  else
224
228
  raise "unknown modification direction #{$2}"
225
229
  end
@@ -293,6 +297,8 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
293
297
 
294
298
  @no_create = options['no_create'] || false
295
299
  @no_paginate = options['no_paginate'] || false
300
+ @paginate_per_page_selector = options['paginate_per_page_selector']
301
+
296
302
  @big_edit = options['big_edit']
297
303
 
298
304
  @no_edit = options['no_edit'] || false
@@ -715,17 +721,19 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
715
721
  if File.exist?(dest_file)
716
722
  existing_file = File.open(dest_file)
717
723
  existing_content = existing_file.read
718
- if existing_content =~ /\#HOTGLUE-SAVESTART/
719
- if existing_content !~ /\#HOTGLUE-END/
720
- raise "Your file at #{dest_file} contains a #HOTGLUE-SAVESTART marker without #HOTGLUE-END"
724
+ if existing_content =~ /\# HOTGLUE-SAVESTART/
725
+ if existing_content !~ /\# HOTGLUE-END/
726
+ raise "Your file at #{dest_file} contains a # HOTGLUE-SAVESTART marker without # HOTGLUE-END"
721
727
  end
722
- @existing_content = existing_content[(existing_content =~ /\#HOTGLUE-SAVESTART/)..(existing_content =~ /\#HOTGLUE-END/) - 1]
723
- @existing_content << "#HOTGLUE-END"
728
+ @existing_content = existing_content[(existing_content =~ /\# HOTGLUE-SAVESTART/)..(existing_content =~ /\# HOTGLUE-END/) - 1]
729
+ @existing_content << "# HOTGLUE-END"
724
730
 
731
+ else
732
+ @existing_content = " # HOTGLUE-SAVESTART\n # HOTGLUE-END"
725
733
  end
726
734
  existing_file.rewind
727
735
  else
728
- @existing_content = " #HOTGLUE-SAVESTART\n #HOTGLUE-END"
736
+ @existing_content = " # HOTGLUE-SAVESTART\n # HOTGLUE-END"
729
737
  end
730
738
 
731
739
  template "system_spec.rb.erb", dest_file
@@ -744,6 +752,14 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
744
752
  singular_class.gsub("::", "_").underscore
745
753
  end
746
754
 
755
+ def factory_testing_name
756
+ if !@self_auth
757
+ "#{singular}1"
758
+ else
759
+ "current_#{singular}"
760
+ end
761
+ end
762
+
747
763
  def spec_related_column_lets
748
764
  @columns_map.collect { |col, col_object|
749
765
  col_object.spec_related_column_lets
@@ -769,7 +785,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
769
785
  end
770
786
 
771
787
  def regenerate_me_code
772
- "rails generate hot_glue:scaffold #{ @meta_args[0][0] } #{@meta_args[1].collect { |x| x.gsub(/\s*=\s*([\S\s]+)/, '=\'\1\'') }.join(" ")}"
788
+ "bin/rails generate hot_glue:scaffold #{ @meta_args[0][0] } #{@meta_args[1].collect { |x| x.gsub(/\s*=\s*([\S\s]+)/, '=\'\1\'') }.join(" ")}"
773
789
  end
774
790
 
775
791
  def object_parent_mapping_as_argument_for_specs
@@ -1089,7 +1105,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
1089
1105
  def insert_into_nav_template
1090
1106
  # how does this get called(?)
1091
1107
  nav_file = "#{Rails.root}/app/views/#{namespace_with_trailing_dash}_nav.html.#{@markup}"
1092
- if include_nav_template
1108
+ if include_nav_template && @nested_set.none?
1093
1109
  append_text = " <li class='nav-item'>
1094
1110
  <%= link_to '#{@list_label_heading}', #{path_helper_plural}, class: \"nav-link \#{'active' if nav == '#{plural_name}'}\" %>
1095
1111
  </li>"
@@ -66,20 +66,24 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
66
66
  def load_<%= singular_name %>
67
67
  @<%= singular_name %> = (<%= auth_object.gsub("@",'') %><%= " if params.include?(:#{@nested_set[0][:singular]}_id)" if @nested_set.any? && @nested_set[0][:optional] %>)<% if @nested_set.any? && @nested_set[0][:optional] %> || <%= class_name %>.find(params[:id])<% end %>
68
68
  end<% end %>
69
+ <% if @paginate_per_page_selector %>def per
70
+ params[:per] || 10
71
+ end
69
72
 
70
- def load_all_<%= plural %><% if @pundit %>
71
- @<%= plural_name %> = policy_scope(<%= class_name %>).page(params[:page])<%= n_plus_one_includes %>
73
+ <% end %>def load_all_<%= plural %><% if @pundit %>
74
+ @<%= plural_name %> = policy_scope(<%= object_scope %>).page(params[:page])<%= n_plus_one_includes %><%= ".per(per)" if @paginate_per_page_selector %>
72
75
  authorize @<%= plural_name %>.all<% else %> <% if !@self_auth %>
73
- @<%= plural_name %> = <%= object_scope.gsub("@",'') %>.page(params[:page])<%= n_plus_one_includes %><%= " if params.include?(:#{ @nested_set.last[:singular]}_id)" if @nested_set.any? && @nested_set[0] && @nested_set[0][:optional] %><% if @nested_set[0] && @nested_set[0][:optional] %>
76
+ @<%= plural_name %> = <%= object_scope.gsub("@",'') %><%= n_plus_one_includes %>.page(params[:page])<%= ".per(per)" if @paginate_per_page_selector %><%= " if params.include?(:#{ @nested_set.last[:singular]}_id)" if @nested_set.any? && @nested_set[0] && @nested_set[0][:optional] %><% if @nested_set[0] && @nested_set[0][:optional] %>
74
77
  @<%= plural_name %> = <%= class_name %>.all<% end %><% else %>
75
- @<%= plural_name %> = <%= class_name %>.where(id: <%= auth_object.gsub("@",'') %>.id)<%= n_plus_one_includes %><% end %>
78
+ @<%= plural_name %> = <%= class_name %>.where(id: <%= auth_object.gsub("@",'') %>.id)<%= n_plus_one_includes %>.page(params[:page])<%= ".per(per)" if @paginate_per_page_selector %><% end %>
76
79
  <% end %>
77
80
  end
78
81
 
79
82
  def index
80
83
  load_all_<%= plural %><% if @pundit %>
81
84
  rescue Pundit::NotAuthorizedError
82
- flash[:alert] = "You are not authorized to perform this action."<% end %>
85
+ flash[:alert] = "You are not authorized to perform this action."
86
+ render "layouts/error"<% end %>
83
87
  end
84
88
 
85
89
  <% if create_action %> def new<% if @object_owner_sym %>
@@ -155,7 +159,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
155
159
  <% end %>
156
160
  modified_params = modify_date_inputs_on_params(<% if @update_show_only %>update_<% end %><%= singular_name %>_params.dup<%= controller_update_params_tap_away_alt_lookups %><%= controller_update_params_tap_away_magic_buttons %>, <%= current_user_object %>, <%= datetime_fields_list %>) <% if @object_owner_sym && eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %>
157
161
  modified_params = modified_params.merge(<%= @object_owner_sym %>: <%= @object_owner_eval %>) <% elsif @object_owner_optional && any_nested? %>
158
- modified_params = modified_params.merge(<%= @object_owner_name %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {}) <% elsif !@object_owner_eval.empty? %>
162
+ modified_params = modified_params.merge(<%= @object_owner_name %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {}) <% elsif ! @object_owner_eval.empty? && !@self_auth%>
159
163
  modified_params = modified_params.merge(<%= @object_owner_eval %>) <% end %><% if !merge_lookups.empty? %>
160
164
  modified_params = modified_params.merge(<%= merge_lookups %>)
161
165
  <% end %>
@@ -51,6 +51,12 @@
51
51
  <%= @nested_set.collect{|arg| " .merge(defined?(#{arg[:singular]}) ? {#{arg[:singular]}: #{arg[:singular]}} : {})"}.join("\n") %>
52
52
  %>
53
53
  <\% end %>
54
+ <% if @paginate_per_page_selector %>
55
+ <\%= form_with url: things_path, method: :get do |f| %>
56
+ Show per page
57
+ <\%= f.collection_select "per", [10, 25, 100], :to_s, :to_s, {prompt: true, selected: params[:per]}, {onChange: "this.form.submit();"} %>
58
+ <\% end %>
59
+ <% end %>
54
60
  <%= @no_paginate ? "" : paginate %>
55
61
  <% end %>
56
62
  </div>
@@ -2,9 +2,9 @@
2
2
  if (eval(@singular_class).instance_methods.include?(display_class.to_s))
3
3
  item1_addOns << "#{display_class}: FFaker::Name.name"
4
4
  end
5
- item1_addOns << ", " + @columns_map.collect{|col, col_object|
5
+ item1_addOns << ", \n " + @columns_map.collect{|col, col_object|
6
6
  col_object.spec_setup_let_arg
7
- }.compact.join(", ")
7
+ }.compact.join(", \n ")
8
8
  %>require 'rails_helper'
9
9
 
10
10
  describe 'interaction for <%= controller_class_name %>' do
@@ -14,7 +14,18 @@ describe 'interaction for <%= controller_class_name %>' do
14
14
  <%= @existing_content %>
15
15
  <% unless @god %>let(:<%= @auth %>) {create(:<%= @auth.gsub('current_', '') %>)}<% end %>
16
16
  <%= spec_related_column_lets %>
17
- let!(:<%= singular %>1) {create(:<%= singular %><%= object_parent_mapping_as_argument_for_specs %> <%= item1_addOns %> )}
17
+ <% unless @self_auth %> let!(:<%= singular %>1) {
18
+ <%= singular %> = create(:<%= singular %><%= object_parent_mapping_as_argument_for_specs %> <%= item1_addOns %> )
19
+ <%= @attachments.collect{ |attachment|
20
+ " #{singular}.#{ attachment[0].to_s }.attach(
21
+ io: File.open('spec/fixtures/glass_button.png'),
22
+ filename: 'glass_button.png',
23
+ content_type: 'image/png')"
24
+ }.join("\n")
25
+ %>
26
+ <%=singular%>.save!
27
+ <%=singular%>
28
+ }<% end %>
18
29
  <%= objest_nest_factory_setup %> <% unless @god || (@existing_content && @existing_content.include?("login_as")) %>
19
30
  before do
20
31
  login_as(<%= @auth %>)
@@ -53,25 +64,25 @@ describe 'interaction for <%= controller_class_name %>' do
53
64
  describe "edit & update" do
54
65
  it "should return an editable form" do
55
66
  visit <%= path_helper_plural %>
56
- find("a.edit-<%= singular %>-button[href='/<%= namespace_with_slash %><%= plural %>/#{<%= singular %>1.id}/edit']").click
67
+ find("a.edit-<%= singular %>-button[href='/<%= namespace_with_slash %><%= plural %>/#{<%= factory_testing_name %>.id}/edit']").click
57
68
 
58
- expect(page).to have_content("Editing #{<%= singular %>1.<%= @display_class %>.squish || "(no name)"}")
69
+ expect(page).to have_content("Editing #{<%= factory_testing_name %>.<%= @display_class %>.squish || "(no name)"}")
59
70
  <%= capybara_make_updates(:update) %>
60
71
  click_button "Save"
61
- within("turbo-frame#<%= @namespace %>__#{dom_id(<%= singular %>1)} ") do
72
+ within("turbo-frame#<%= @namespace %>__#{dom_id(<%= factory_testing_name %>)} ") do
62
73
  <%= " " + @columns_map.map{ |col, col_object|
63
74
  if @attachments.keys.collect(&:to_sym).include?(col)
64
75
  elsif @show_only.include?(col)
65
76
  else
66
77
  col_object.spec_make_assertion
67
78
  end
68
- }.compact.join("\n ")
79
+ }.compact.join("\n ")
69
80
  %>
70
81
  end
71
82
  end
72
- end <% end %>
83
+ end <% end %><% if destroy_action %>
73
84
 
74
- <% unless @no_delete %> describe "destroy" do
85
+ describe "destroy" do
75
86
  it "should destroy" do
76
87
  visit <%= path_helper_plural %>
77
88
  accept_alert do
@@ -1,5 +1,5 @@
1
1
  module HotGlue
2
2
  class Version
3
- CURRENT = '0.5.23.1'
3
+ CURRENT = '0.5.25'
4
4
  end
5
5
  end
data/script/test CHANGED
@@ -30,7 +30,9 @@ bin/rails generate hot_glue:scaffold Pet --gd
30
30
 
31
31
  bin/rails generate hot_glue:scaffold Human --gd
32
32
 
33
- #rails generate hot_glue:scaffold User --no-create --self-auth
33
+ bin/rails generate hot_glue:scaffold User --no-create --self-auth
34
+
35
+
34
36
  #rails generate hot_glue:scaffold Jkl --gd
35
37
  #rails generate hot_glue:scaffold Appointment --hawk=pets --gd
36
38
  #rails generate hot_glue:scaffold Family --gd
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hot-glue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.23.1
4
+ version: 0.5.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Fleetwood-Boldt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-01 00:00:00.000000000 Z
11
+ date: 2023-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -143,7 +143,7 @@ licenses:
143
143
  metadata:
144
144
  source_code_uri: https://github.com/hot-glue-for-rails/hot-glue
145
145
  homepage: https://heliosdev.shop/hot-glue
146
- funding: https://school.jasonfleetwoodboldt.com/8188
146
+ funding: https://school.jfbcodes.com/8188
147
147
  post_install_message: |
148
148
  ---------------------------------------------
149
149
  Welcome to Hot Glue - A Scaffold Building Companion for Hotwire + Turbo-Rails