hot-glue 0.5.22 → 0.5.24
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -3
- data/README.md +125 -6
- data/lib/generators/hot_glue/field_factory.rb +1 -1
- data/lib/generators/hot_glue/fields/association_field.rb +1 -1
- data/lib/generators/hot_glue/fields/attachment_field.rb +12 -2
- data/lib/generators/hot_glue/fields/boolean_field.rb +4 -4
- data/lib/generators/hot_glue/fields/enum_field.rb +33 -11
- data/lib/generators/hot_glue/fields/field.rb +18 -13
- data/lib/generators/hot_glue/fields/text_field.rb +1 -1
- data/lib/generators/hot_glue/layout/builder.rb +2 -2
- data/lib/generators/hot_glue/markup_templates/erb.rb +7 -5
- data/lib/generators/hot_glue/scaffold_generator.rb +21 -11
- data/lib/generators/hot_glue/templates/controller.rb.erb +3 -2
- data/lib/generators/hot_glue/templates/system_spec.rb.erb +14 -3
- data/lib/hotglue/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: badba8cc091a29c8613194fa379cce1d7cdd720a1ae3627630a069afb5b4c352
|
4
|
+
data.tar.gz: d0e5cd8a96ae546596eabc865f1dc4979f0a528b82ffd19bdfdddf6dc92fe3f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94ae4da0d2644a6b6311f5b81da1f864ae90d4a69c133b4a3259ad53f0221ed10bfedfe4964dc7ceb04d65e2d6ef28c420af6b5489bae4ec22bb7989f6b0249a
|
7
|
+
data.tar.gz: 9e0f23257368d5836f4a95c4f116f2d70057f063cce7ff14acecee0c2e7f62fd921e752d13fec73d073aa40ba6f89709a9efbb92a0c0f2bd823324a897cf93dd
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
hot-glue (0.5.
|
4
|
+
hot-glue (0.5.24)
|
5
5
|
ffaker (~> 2.16)
|
6
6
|
kaminari (~> 1.2)
|
7
7
|
rails (> 5.1)
|
@@ -139,14 +139,14 @@ 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.
|
142
|
+
net-imap (0.4.0)
|
143
143
|
date
|
144
144
|
net-protocol
|
145
145
|
net-pop (0.1.2)
|
146
146
|
net-protocol
|
147
147
|
net-protocol (0.2.1)
|
148
148
|
timeout
|
149
|
-
net-smtp (0.
|
149
|
+
net-smtp (0.4.0)
|
150
150
|
net-protocol
|
151
151
|
nio4r (2.5.8)
|
152
152
|
nokogiri (1.13.9)
|
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
|
-
|
667
|
+
Notice that each modifiers can be used with specific field types.
|
668
668
|
|
669
|
-
| modifier
|
670
|
-
|
671
|
-
| $
|
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" |
|
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.
|
@@ -1402,8 +1405,124 @@ end
|
|
1402
1405
|
|
1403
1406
|
```
|
1404
1407
|
|
1408
|
+
|
1409
|
+
### TinyMCE
|
1410
|
+
1. `bundle add tinymce-rails` to add it to your Gemfile
|
1411
|
+
|
1412
|
+
2. Add this inside of your `<head>` tag (at the bottom is fine)
|
1413
|
+
```
|
1414
|
+
<%= tinymce_assets %>
|
1415
|
+
```
|
1416
|
+
3. Then, also inside of your `<head>` tag, add this:
|
1417
|
+
```
|
1418
|
+
<script>
|
1419
|
+
TinyMCERails.configuration.default = {
|
1420
|
+
selector: "textarea.tinymce",
|
1421
|
+
cache_suffix: "?v=6.7.0",
|
1422
|
+
menubar: "insert view format table tools",
|
1423
|
+
toolbar: ["bold italic | link | undo redo | forecolor backcolor | bullist numlist outdent indent | table | uploadimage | code"],
|
1424
|
+
plugins: "table,fullscreen,image,code,searchreplace,wordcount,visualblocks,visualchars,link,charmap,directionality,nonbreaking,media,advlist,autolink,lists",
|
1425
|
+
images_upload_url: "/uploader/image"
|
1426
|
+
};
|
1427
|
+
|
1428
|
+
</script>
|
1429
|
+
```
|
1430
|
+
|
1431
|
+
Then to `application.js` add
|
1432
|
+
|
1433
|
+
```
|
1434
|
+
import "./tinymce_init"
|
1435
|
+
|
1436
|
+
```
|
1437
|
+
|
1438
|
+
create a file `tinymce_init.js` with this content
|
1439
|
+
|
1440
|
+
```
|
1441
|
+
const reinitTiny = () => {
|
1442
|
+
tinymce.init({
|
1443
|
+
selector: 'textarea.tinymce', // Add the appropriate selector for your textareas
|
1444
|
+
// Other TinyMCE configuration options
|
1445
|
+
});
|
1446
|
+
}
|
1447
|
+
|
1448
|
+
window.addEventListener('turbo:before-fetch-response', () => {
|
1449
|
+
tinymce.remove();
|
1450
|
+
tinymce.init({selector:'textarea.tinymce'});
|
1451
|
+
})
|
1452
|
+
|
1453
|
+
window.addEventListener('turbo:frame-render', reinitTiny)
|
1454
|
+
window.addEventListener('turbo:render', reinitTiny)
|
1455
|
+
```
|
1456
|
+
|
1457
|
+
Once you have completed this setup, you can now use `--modify` with the modifier `tinymce`.
|
1458
|
+
|
1459
|
+
For example, to display the field `my_story` on the object `Thing`, you'd generate with:
|
1460
|
+
|
1461
|
+
```
|
1462
|
+
bin/rails generate Thing --include=my_story --modify='my_story{tinymce}'
|
1463
|
+
```
|
1464
|
+
|
1405
1465
|
# VERSION HISTORY
|
1406
1466
|
|
1467
|
+
#### 2023-10-07 - v0.5.24
|
1468
|
+
|
1469
|
+
- TinyMCE implementation. See 'TinyMCE' above.
|
1470
|
+
Note: I plan to also implement ActionText as an alternative in the future. 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.
|
1471
|
+
- Spec Savestart code: In the behavior specs, there is a code marker (start & end) where you can insert custom code that gets saved between
|
1472
|
+
build. The start code maker has changed from `#HOTGLUE-SAVESTART` to `# HOTGLUE-SAVESTART`
|
1473
|
+
and the end code marker has changed from `#HOTGLUE-END` to `# HOTGLUE-END`. This now conforms to Rubocop.
|
1474
|
+
Be sure to do find & replace in your existing projects to keep your custom code.
|
1475
|
+
- Fix for specs for attachment fields. If you have attachments fields, you must have a sample file at `spec/fixtures/glass_button.png`
|
1476
|
+
- Pundit now correctly protects the `index` action (authorize was missing before)
|
1477
|
+
|
1478
|
+
#### 2023-10-01 - v0.5.23
|
1479
|
+
|
1480
|
+
- You can now use the modify flag on enum type fields to display a partial with the same name of that enum type.
|
1481
|
+
|
1482
|
+
`--modify=status{partials}`
|
1483
|
+
|
1484
|
+
Here, `status` is an enum field on your table; you must use the exact string `partials` when using this feature.
|
1485
|
+
|
1486
|
+
You're telling Hot Glue to build scaffold that will display the `status` enum field as a partial.
|
1487
|
+
|
1488
|
+
It will look for a partial in the same build directory, whose name matches to the value of the enum. You will need to create a partial _for each enum option_ that you have defined.
|
1489
|
+
|
1490
|
+
Remember when defining enums Rails will patch methods on your objects with the name of the enum types, so you must avoid namespace collisions with existing Ruby or Rails methods that are common to all objects -- like, for example, `new`.
|
1491
|
+
|
1492
|
+
- Before this feature, enums always rendered like this on the show page:
|
1493
|
+
`<%= domain.status %>`
|
1494
|
+
(or, if you use custom labels:)
|
1495
|
+
`<%= Domain.status_labels(domain.status)`
|
1496
|
+
|
1497
|
+
- After, you if you use the `--modify` flag and modify the enum to 'partials', your show output will render:
|
1498
|
+
```
|
1499
|
+
<%= render partial: thing.status, locals: {thing: thing} %>
|
1500
|
+
```
|
1501
|
+
(In this example `Thing` is the name of the model being built.)
|
1502
|
+
|
1503
|
+
Your form will also render the partial, but after the collection_select used to create the drop-down.
|
1504
|
+
(This implementation has the draw-back that there is no immediate switch between the partials when changing the drop-down)
|
1505
|
+
|
1506
|
+
Assuming your Thing enum is defined like so:
|
1507
|
+
```
|
1508
|
+
enum :status {abc: 'abc', dfg: 'dfg', hgk: 'hgk'}
|
1509
|
+
```
|
1510
|
+
|
1511
|
+
You then would create three partials in the `things` directory. Make sure to create a partial for each defined enum, or else your app will crash when it tries to render a record with that enum.
|
1512
|
+
```
|
1513
|
+
_abc.html.erb
|
1514
|
+
_dfg.html.erb
|
1515
|
+
_hgk.html.erb
|
1516
|
+
```
|
1517
|
+
|
1518
|
+
If your enum is on the show-only list, then the drop-down does not appear (but the partial is rendered).
|
1519
|
+
|
1520
|
+
Proof-of-concept can be found here:
|
1521
|
+
https://github.com/hot-glue-for-rails/HGEnumWithPartials1
|
1522
|
+
|
1523
|
+
Remember to see the section marked 'A Note About Enums' for more about working with Rails 7 enums.
|
1524
|
+
|
1525
|
+
|
1407
1526
|
#### 2023-09-20- v0.5.22
|
1408
1527
|
- adds back magic button tap-away params in the controller
|
1409
1528
|
- changes creation of flash[:notice] in update method
|
@@ -58,7 +58,7 @@ class FieldFactory
|
|
58
58
|
update_show_only: generator.update_show_only,
|
59
59
|
attachment_data: generator.attachments[name.to_sym],
|
60
60
|
sample_file_path: generator.sample_file_path,
|
61
|
-
|
61
|
+
modify_as: generator.modify_as[name.to_sym] || nil,
|
62
62
|
display_as: generator.display_as[name.to_sym] || nil,
|
63
63
|
default_boolean_display: generator.default_boolean_display)
|
64
64
|
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:,
|
13
|
+
form_labels_position:, modify_as: )
|
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:,
|
7
|
+
form_placeholder_labels: , form_labels_position:, modify_as: )
|
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
|
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? &&
|
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? &&
|
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
|
-
#{
|
63
|
+
#{modify_as[:binary][:truthy]}
|
64
64
|
<% else %>
|
65
|
-
#{
|
65
|
+
#{modify_as[:binary][:falsy]}
|
66
66
|
<% end %>"
|
67
67
|
else
|
68
68
|
"<% if #{singular}.#{name}.nil? %>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class EnumField < Field
|
2
2
|
def spec_setup_and_change_act(which_partial = nil)
|
3
3
|
# what is the enum name
|
4
|
-
" list_of_#{enum_type} = #{class_name}.defined_enums['#{
|
4
|
+
" list_of_#{enum_type} = #{class_name}.defined_enums['#{name}'].keys \n" +
|
5
5
|
" " + "new_#{name} = list_of_#{enum_type}[rand(list_of_#{enum_type}.length)].to_s \n" +
|
6
6
|
' find("select[name=\'' + singular + '[' + name + ']\'] option[value=\'#{new_' + name + '}\']").select_option'
|
7
7
|
end
|
@@ -32,13 +32,19 @@ class EnumField < Field
|
|
32
32
|
|
33
33
|
def form_field_output
|
34
34
|
enum_type = eval("#{class_name}.columns.select{|x| x.name == '#{name}'}[0].sql_type")
|
35
|
-
|
36
35
|
if eval("defined? #{class_name}.#{enum_type}_labels") == "method"
|
37
36
|
enum_definer = "#{class_name}.#{enum_type}_labels"
|
38
37
|
else
|
39
|
-
enum_definer = "#{class_name}.defined_enums['#{
|
38
|
+
enum_definer = "#{class_name}.defined_enums['#{name}']"
|
39
|
+
end
|
40
|
+
|
41
|
+
res = "<%= f.collection_select(:#{name}, enum_to_collection_select(#{enum_definer}), :key, :value, {selected: #{singular}.#{name} }, class: 'form-control') %>"
|
42
|
+
|
43
|
+
|
44
|
+
if modify_as && modify_as[:enum] == :partials
|
45
|
+
res << partial_render
|
40
46
|
end
|
41
|
-
|
47
|
+
res
|
42
48
|
end
|
43
49
|
|
44
50
|
def line_field_output
|
@@ -47,14 +53,30 @@ class EnumField < Field
|
|
47
53
|
if eval("defined? #{class_name}.#{enum_type}_labels") == "method"
|
48
54
|
enum_definer = "#{class_name}.#{enum_type}_labels"
|
49
55
|
else
|
50
|
-
enum_definer = "#{class_name}.defined_enums['#{
|
56
|
+
enum_definer = "#{class_name}.defined_enums['#{name}']"
|
51
57
|
end
|
52
|
-
|
58
|
+
|
59
|
+
res = "
|
53
60
|
<% if #{singular}.#{name}.nil? %>
|
54
|
-
<span class='alert-danger'>
|
55
|
-
<% else %>
|
56
|
-
|
57
|
-
|
58
|
-
|
61
|
+
<span class='alert-danger'>Missing #{name}</span>
|
62
|
+
<% else %>"
|
63
|
+
|
64
|
+
if modify_as && modify_as[:enum] == :partials
|
65
|
+
res << partial_render
|
66
|
+
else
|
67
|
+
res << "<%= #{enum_definer}[#{singular}.#{name}.to_sym] %>"
|
68
|
+
end
|
69
|
+
|
70
|
+
res << "<% end %>"
|
71
|
+
res
|
72
|
+
end
|
73
|
+
|
74
|
+
def partial_render
|
75
|
+
"<% if #{singular}.#{name} %><%= render partial: #{singular}.#{name}, locals: { #{singular}: #{singular} } %><% end %>"
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
def form_show_only_output
|
80
|
+
viewable_output
|
59
81
|
end
|
60
82
|
end
|
@@ -1,7 +1,8 @@
|
|
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,
|
4
|
-
:
|
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,
|
5
6
|
:singular_class, :singular, :sql_type, :ownership_field,
|
6
7
|
:update_show_only
|
7
8
|
|
@@ -16,7 +17,7 @@ class Field
|
|
16
17
|
form_placeholder_labels: ,
|
17
18
|
hawk_keys: nil,
|
18
19
|
layout_strategy: ,
|
19
|
-
|
20
|
+
modify_as: , #note non-standard naming as to avoid collision with Ruby reserved word modify
|
20
21
|
name: ,
|
21
22
|
ownership_field: ,
|
22
23
|
sample_file_path: nil,
|
@@ -35,7 +36,7 @@ class Field
|
|
35
36
|
@form_placeholder_labels = form_placeholder_labels
|
36
37
|
@ownership_field = ownership_field
|
37
38
|
@form_labels_position = form_labels_position
|
38
|
-
@
|
39
|
+
@modify_as = modify_as
|
39
40
|
@display_as = display_as
|
40
41
|
|
41
42
|
@default_boolean_display = default_boolean_display
|
@@ -72,7 +73,7 @@ class Field
|
|
72
73
|
if !modify_binary?
|
73
74
|
"expect(page).to have_content(new_#{name})"
|
74
75
|
else
|
75
|
-
"expect(page).to have_content('#{
|
76
|
+
"expect(page).to have_content('#{modify_as[:binary][:truthy]}'"
|
76
77
|
end
|
77
78
|
end
|
78
79
|
|
@@ -87,7 +88,7 @@ class Field
|
|
87
88
|
|
88
89
|
def spec_list_view_assertion
|
89
90
|
if modify_binary?
|
90
|
-
"expect(page).to have_content('#{
|
91
|
+
"expect(page).to have_content('#{modify_as[:binary][:truthy]}'"
|
91
92
|
else
|
92
93
|
spec_list_view_natural_assertion
|
93
94
|
end
|
@@ -107,7 +108,7 @@ class Field
|
|
107
108
|
end
|
108
109
|
|
109
110
|
def viewable_output
|
110
|
-
if
|
111
|
+
if modify_as
|
111
112
|
modified_display_output
|
112
113
|
else
|
113
114
|
"<%= #{singular}.#{name} %>"
|
@@ -115,10 +116,14 @@ class Field
|
|
115
116
|
end
|
116
117
|
|
117
118
|
def modified_display_output
|
118
|
-
if
|
119
|
+
if modify_as[:cast] && modify_as[:cast] == "$"
|
119
120
|
"<%= number_to_currency(#{singular}.#{name}) %>"
|
120
|
-
elsif
|
121
|
-
"<%= #{singular}.#{name} ? '#{
|
121
|
+
elsif modify_as[:binary]
|
122
|
+
"<%= #{singular}.#{name} ? '#{modify_as[:binary][:truthy]}' : '#{modify_as[:binary][:falsy]}' %>"
|
123
|
+
elsif modify_as[:tinymce]
|
124
|
+
|
125
|
+
elsif modify_as[:enum]
|
126
|
+
"<%= render partial: #{singular}.#{name}, locals: {#{singular}: #{singular}} %>"
|
122
127
|
end
|
123
128
|
end
|
124
129
|
|
@@ -126,16 +131,16 @@ class Field
|
|
126
131
|
" <%= 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"
|
127
132
|
end
|
128
133
|
|
129
|
-
def text_area_output(field_length )
|
134
|
+
def text_area_output(field_length, extra_classes: "")
|
130
135
|
lines = field_length % 40
|
131
136
|
if lines > 5
|
132
137
|
lines = 5
|
133
138
|
end
|
134
|
-
"<%= f.text_area :#{name}, class: 'form-control', autocomplete: 'off', cols: 40, rows: '#{lines}'" + ( form_placeholder_labels ? ", placeholder: '#{name.to_s.humanize}'" : "") + " %>"
|
139
|
+
"<%= f.text_area :#{name}, class: 'form-control#{extra_classes}', autocomplete: 'off', cols: 40, rows: '#{lines}'" + ( form_placeholder_labels ? ", placeholder: '#{name.to_s.humanize}'" : "") + " %>"
|
135
140
|
end
|
136
141
|
|
137
142
|
def modify_binary? # safe
|
138
|
-
!!(
|
143
|
+
!!(modify_as && modify_as[:binary])
|
139
144
|
end
|
140
145
|
|
141
146
|
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
|
-
@
|
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
|
-
|
49
|
+
modify_as: @modify_as,
|
50
50
|
display_as: @display_as
|
51
51
|
}
|
52
52
|
|
@@ -97,18 +97,20 @@ module HotGlue
|
|
97
97
|
elsif update_show_only.include?(col) && !@pundit
|
98
98
|
"<% if action_name == 'edit' %>" + columns_map[col].form_show_only_output + "<% else %>" + columns_map[col].form_field_output + "<% end %>"
|
99
99
|
elsif update_show_only.include?(col) && @pundit && eval("defined? #{singular_class}Policy") && eval("#{singular_class}Policy").instance_methods.include?("#{col}_able?".to_sym)
|
100
|
-
"<% if action_name == '
|
100
|
+
"<% if action_name == 'new' && policy(@#{singular}).#{col}_able? %>" + columns_map[col].form_field_output + "<% else %>" + columns_map[col].form_show_only_output + "<% end %>"
|
101
101
|
|
102
102
|
# show only on the update action overrides any pundit policy
|
103
103
|
elsif @pundit && eval("defined? #{singular_class}Policy") && eval("#{singular_class}Policy").instance_methods.include?("#{col}_able?".to_sym)
|
104
104
|
"<% if policy(@#{singular}).#{col}_able? %>" + columns_map[col].form_field_output + "<% else %>" + columns_map[col].form_show_only_output + "<% end %>"
|
105
105
|
else
|
106
106
|
columns_map[col].form_field_output
|
107
|
-
|
107
|
+
end
|
108
|
+
# byebug
|
109
|
+
@tinymce_stimulus_controller = (columns_map[col].modify_as == {tinymce: 1} ? "data-controller='tiny-mce' " : "")
|
108
110
|
|
109
|
-
add_spaces_each_line( "\n <span class='<%= \"alert-danger\" if #{singular}.errors.details.keys.include?(:#{field_error_name}) %>' #{'style="display: inherit;"'} >\n" +
|
110
|
-
add_spaces_each_line( (form_labels_position == 'before' ? the_label : "") +
|
111
|
-
+ field_result +
|
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" +
|
112
|
+
add_spaces_each_line( (form_labels_position == 'before' ? the_label || "" : "") +
|
113
|
+
+ " <br />\n" + field_result +
|
112
114
|
(form_labels_position == 'after' ? the_label : "") , 4) +
|
113
115
|
"\n </span>\n <br />", 2)
|
114
116
|
|
@@ -18,7 +18,8 @@ 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,
|
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
25
|
:layout_strategy, :form_placeholder_labels, :form_labels_position, :pundit
|
@@ -204,18 +205,25 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
204
205
|
puts "show only field #{@show_only}}"
|
205
206
|
end
|
206
207
|
|
207
|
-
@
|
208
|
+
@modify_as = {}
|
208
209
|
if !options['modify'].empty?
|
210
|
+
|
209
211
|
modify_input = options['modify'].split(",")
|
210
212
|
modify_input.each do |setting|
|
211
213
|
setting =~ /(.*){(.*)}/
|
212
214
|
key, lookup_as = $1, $2
|
213
215
|
|
214
216
|
if ["$"].include?($2)
|
215
|
-
@
|
217
|
+
@modify_as[key.to_sym] = {cast: $2}
|
216
218
|
elsif $2.include?("|")
|
217
219
|
binary = $2.split("|")
|
218
|
-
@
|
220
|
+
@modify_as[key.to_sym] = {binary: {truthy: binary[0], falsy: binary[1]}}
|
221
|
+
elsif $2 == "partial"
|
222
|
+
@modify_as[key.to_sym] = {enum: :partials}
|
223
|
+
elsif $2 == "tinymce"
|
224
|
+
@modify_as[key.to_sym] = {tinymce: 1}
|
225
|
+
else
|
226
|
+
raise "unknown modification direction #{$2}"
|
219
227
|
end
|
220
228
|
end
|
221
229
|
end
|
@@ -709,17 +717,19 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
709
717
|
if File.exist?(dest_file)
|
710
718
|
existing_file = File.open(dest_file)
|
711
719
|
existing_content = existing_file.read
|
712
|
-
if existing_content =~ /\#HOTGLUE-SAVESTART/
|
713
|
-
if existing_content !~ /\#HOTGLUE-END/
|
714
|
-
raise "Your file at #{dest_file} contains a #HOTGLUE-SAVESTART marker without #HOTGLUE-END"
|
720
|
+
if existing_content =~ /\# HOTGLUE-SAVESTART/
|
721
|
+
if existing_content !~ /\# HOTGLUE-END/
|
722
|
+
raise "Your file at #{dest_file} contains a # HOTGLUE-SAVESTART marker without # HOTGLUE-END"
|
715
723
|
end
|
716
|
-
@existing_content = existing_content[(existing_content =~ /\#HOTGLUE-SAVESTART/)..(existing_content =~ /\#HOTGLUE-END/) - 1]
|
717
|
-
@existing_content << "#HOTGLUE-END"
|
724
|
+
@existing_content = existing_content[(existing_content =~ /\# HOTGLUE-SAVESTART/)..(existing_content =~ /\# HOTGLUE-END/) - 1]
|
725
|
+
@existing_content << "# HOTGLUE-END"
|
718
726
|
|
727
|
+
else
|
728
|
+
@existing_content = " # HOTGLUE-SAVESTART\n # HOTGLUE-END"
|
719
729
|
end
|
720
730
|
existing_file.rewind
|
721
731
|
else
|
722
|
-
@existing_content = " #HOTGLUE-SAVESTART\n #HOTGLUE-END"
|
732
|
+
@existing_content = " # HOTGLUE-SAVESTART\n # HOTGLUE-END"
|
723
733
|
end
|
724
734
|
|
725
735
|
template "system_spec.rb.erb", dest_file
|
@@ -763,7 +773,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
763
773
|
end
|
764
774
|
|
765
775
|
def regenerate_me_code
|
766
|
-
"rails generate hot_glue:scaffold #{ @meta_args[0][0] } #{@meta_args[1].collect { |x| x.gsub(/\s*=\s*([\S\s]+)/, '=\'\1\'') }.join(" ")}"
|
776
|
+
"bin/rails generate hot_glue:scaffold #{ @meta_args[0][0] } #{@meta_args[1].collect { |x| x.gsub(/\s*=\s*([\S\s]+)/, '=\'\1\'') }.join(" ")}"
|
767
777
|
end
|
768
778
|
|
769
779
|
def object_parent_mapping_as_argument_for_specs
|
@@ -79,7 +79,8 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
79
79
|
def index
|
80
80
|
load_all_<%= plural %><% if @pundit %>
|
81
81
|
rescue Pundit::NotAuthorizedError
|
82
|
-
flash[:alert] = "You are not authorized to perform this action."
|
82
|
+
flash[:alert] = "You are not authorized to perform this action."
|
83
|
+
render "layouts/error"<% end %>
|
83
84
|
end
|
84
85
|
|
85
86
|
<% if create_action %> def new<% if @object_owner_sym %>
|
@@ -142,7 +143,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
142
143
|
end
|
143
144
|
|
144
145
|
<% end %><% if @build_update_action %> def update
|
145
|
-
flash[:notice] =
|
146
|
+
flash[:notice] = +''
|
146
147
|
flash[:alert] = nil
|
147
148
|
<% if @alt_lookups.filter{|key,d| ! @update_show_only.include?(key.to_sym) }.any? %><%= @alt_lookups.filter{|key,d| ! @update_show_only.include?(key.to_sym) }.collect{|key, data|
|
148
149
|
" #{data[:assoc].downcase} = #{data[:assoc]}.#{data[:with_create] ? "find_or_create_by" : "find_by"}(#{data[:lookup_as]}: #{ singular_name }_params[:__lookup_#{data[:lookup_as]}])\n"
|
@@ -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) {
|
17
|
+
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
|
+
}
|
18
29
|
<%= objest_nest_factory_setup %> <% unless @god || (@existing_content && @existing_content.include?("login_as")) %>
|
19
30
|
before do
|
20
31
|
login_as(<%= @auth %>)
|
data/lib/hotglue/version.rb
CHANGED
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.
|
4
|
+
version: 0.5.24
|
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-
|
11
|
+
date: 2023-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|