hot-glue 0.5.11 → 0.5.12
Sign up to get free protection for your applications and to get access to all the features.
- 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
|