hot-glue 0.5.11 → 0.5.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +17 -2
- data/README.md +13 -6
- data/lib/generators/hot_glue/default_config_loader.rb +12 -0
- data/lib/generators/hot_glue/field_factory.rb +2 -0
- data/lib/generators/hot_glue/fields/association_field.rb +1 -1
- data/lib/generators/hot_glue/fields/attachment_field.rb +27 -0
- data/lib/generators/hot_glue/fields/field.rb +1 -1
- data/lib/generators/hot_glue/hot_glue.rb +5 -0
- data/lib/generators/hot_glue/layout/builder.rb +38 -55
- data/lib/generators/hot_glue/markup_templates/erb.rb +9 -15
- data/lib/generators/hot_glue/scaffold_generator.rb +953 -1010
- data/lib/generators/hot_glue/templates/erb/_list.erb +1 -2
- data/lib/generators/hot_glue/templates/erb/_show.erb +1 -1
- data/lib/generators/hot_glue/templates/erb/edit.erb +35 -6
- data/lib/hot-glue.rb +78 -0
- data/lib/hotglue/version.rb +1 -1
- data/script/test +2 -4
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 78d37c6eaf1dbce758ad70869c5a8b18f799b5ebabfebf242fa7e5641c672cd2
|
|
4
|
+
data.tar.gz: 38b18ddbe9505ec0123c403a944d563c9b91720d9a03deb7e89c8202ae406574
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c8562d221489ae715a8848cec74b28259bbf51d06d90df8968cfeb1a7a36d2c20968fc596f8e89ad49bbce4533bcc0bab425d84ec43fdaf511fd785e22b590b3
|
|
7
|
+
data.tar.gz: fd79db54f85333e4652b9e5444b720eb5525275fd7e071eb27bce4105bd6ca0f475bf921fb216f4389e1f4522bc148d7c9306efdfd707f466a4d826477c5a146
|
data/.github/workflows/test.yml
CHANGED
|
@@ -2,7 +2,7 @@ name: Test
|
|
|
2
2
|
on: [ push, pull_request ]
|
|
3
3
|
|
|
4
4
|
jobs:
|
|
5
|
-
|
|
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:
|
|
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`
|
|
@@ -1208,8 +1211,14 @@ Now, your labels will show up on the front-end as defined in the `_labels` ("Is
|
|
|
1208
1211
|
|
|
1209
1212
|
|
|
1210
1213
|
# VERSION HISTORY
|
|
1211
|
-
#### 2023-04-
|
|
1214
|
+
#### 2023-04-24 - v0.5.12
|
|
1215
|
+
- adds new option for `bootstrap_column_width` (default is 2) to specify the number of bootstrap columns a visual column should take up
|
|
1216
|
+
- You can specify this as a builder option (`--bootstrap-column-width`)
|
|
1217
|
+
or in your `config/hot_glue.yml` file. Passing option will override config setting
|
|
1218
|
+
- Adds new option for `button_icons` (default to "font-awesome"); use `none` to have no button icons
|
|
1219
|
+
- When using big edit with downnested portals, the downnested portals now display on the edit page instead of the list page.
|
|
1212
1220
|
|
|
1221
|
+
#### 2023-04-19 - renamed previous version to v0.5.11
|
|
1213
1222
|
|
|
1214
1223
|
#### 2023-04-08 - v0.5.9.2
|
|
1215
1224
|
• This begins a refactor of the field knowledge into properly abstracted Field objects
|
|
@@ -1218,8 +1227,6 @@ Now, your labels will show up on the front-end as defined in the `_labels` ("Is
|
|
|
1218
1227
|
#### - v0.5.9.1
|
|
1219
1228
|
• Fixed issue with ownership fields coming through as associations.
|
|
1220
1229
|
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
1230
|
#### 2023-03-17 - v0.5.9
|
|
1224
1231
|
- 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
1232
|
|
|
@@ -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
|
|
@@ -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
|
|
@@ -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,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
@
|
|
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 ?
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
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
|
|
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] =
|
|
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] =
|
|
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] =
|
|
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
|
-
|
|
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}
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|