hot-glue 0.5.8 → 0.5.9.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +5 -2
- data/Gemfile +1 -1
- data/README.md +267 -149
- data/app/helpers/hot_glue/controller_helper.rb +9 -6
- data/config/hot_glue.yml +2 -0
- data/lib/generators/hot_glue/direct_upload_install_generator.rb +48 -0
- data/lib/generators/hot_glue/dropzone_install_generator.rb +42 -0
- data/lib/generators/hot_glue/field_factory.rb +57 -0
- data/lib/generators/hot_glue/fields/association_field.rb +76 -0
- data/lib/generators/hot_glue/fields/attachment_field.rb +9 -0
- data/lib/generators/hot_glue/fields/boolean_field.rb +18 -0
- data/lib/generators/hot_glue/fields/date_field.rb +10 -0
- data/lib/generators/hot_glue/fields/date_time_field.rb +23 -0
- data/lib/generators/hot_glue/fields/enum_field.rb +27 -0
- data/lib/generators/hot_glue/fields/field.rb +51 -0
- data/lib/generators/hot_glue/fields/float_field.rb +11 -0
- data/lib/generators/hot_glue/fields/integer_field.rb +26 -0
- data/lib/generators/hot_glue/fields/string_field.rb +33 -0
- data/lib/generators/hot_glue/fields/text_field.rb +14 -0
- data/lib/generators/hot_glue/fields/time_field.rb +6 -0
- data/lib/generators/hot_glue/fields/uuid_field.rb +12 -0
- data/lib/generators/hot_glue/layout/builder.rb +15 -6
- data/lib/generators/hot_glue/layout_strategy/base.rb +2 -0
- data/lib/generators/hot_glue/layout_strategy/bootstrap.rb +4 -0
- data/lib/generators/hot_glue/markup_templates/erb.rb +158 -117
- data/lib/generators/hot_glue/scaffold_generator.rb +296 -306
- data/lib/generators/hot_glue/templates/computer_code.jpg +0 -0
- data/lib/generators/hot_glue/templates/controller.rb.erb +15 -9
- data/lib/generators/hot_glue/templates/erb/_list.erb +19 -6
- data/lib/generators/hot_glue/templates/erb/_show.erb +6 -4
- data/lib/generators/hot_glue/templates/javascript/dropzone_controller.js +191 -0
- data/lib/generators/hot_glue/templates/system_spec.rb.erb +32 -111
- data/lib/hotglue/version.rb +1 -1
- data/script/clean_generated_code +1 -1
- metadata +22 -4
Binary file
|
@@ -41,20 +41,25 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
41
41
|
<% else %>
|
42
42
|
@<%= @nested_set[0][:singular] %> ||= <%= root_object %>.find(params[:<%= @nested_set[0][:singular] %>_id])<%= " if params.include?(:#{@nested_set[0][:singular]}_id)" if @nested_set[0][:optional] %> <% end %>
|
43
43
|
end
|
44
|
-
<% end %><% if any_nested? %><% nest_chain = [@nested_set[0][:singular]];
|
45
|
-
<%
|
44
|
+
<% end %><% if any_nested? %><% nest_chain = [@nested_set[0][:singular]]; %>
|
45
|
+
<% for index in 1..(@nested_set.count - 1) do
|
46
46
|
arg = @nested_set[index]
|
47
|
+
|
47
48
|
last_arg = (index == 0 ? nil : @nested_set[index-1])
|
48
49
|
|
49
50
|
this_scope = "#{nest_chain.last}.#{arg[:plural]}"
|
50
|
-
nest_chain << arg %>
|
51
|
-
<% unless @nested_set[0][:singular] == arg[:singular] %>
|
51
|
+
nest_chain << arg[:singular] %>
|
52
52
|
def <%= arg[:singular] %>
|
53
|
-
@<%=
|
53
|
+
@<%= arg[:singular] %> ||= (<%= this_scope; %>.find(params[:<%= arg[:singular] %>_id]) <%= " if params.include?(:#{last_arg[:singular]}_id)" if last_arg && @god && last_arg[:optional] %>)
|
54
54
|
<% if @god && last_arg && (last_arg[:optional] ) %>@<%= arg[:singular] %> ||= (<%= collect_objects[index-1] %>.find(params[:<%= arg[:singular] %>_id]) if params.include?(:<%= arg[:singular] %>_id) ) <% end %>
|
55
|
-
end<% end %><% end
|
55
|
+
end<% end %><% end %>
|
56
|
+
<% if !@self_auth %>
|
56
57
|
def load_<%= singular_name %>
|
57
|
-
|
58
|
+
<% if @nested_set[0] && @nested_set[0][:optional] %>if params.include?(:<%= @nested_set.last[:singular] %>_id)
|
59
|
+
@<%= singular_name %> = <%= object_scope.gsub("@",'') %>.find(params[:id])
|
60
|
+
else
|
61
|
+
<% end %>@<%= singular_name %> = <%= object_scope %>.find(params[:id])<% if @nested_set[0] && @nested_set[0][:optional] %>
|
62
|
+
end<% end %>
|
58
63
|
end
|
59
64
|
<% else %>
|
60
65
|
def load_<%= singular_name %>
|
@@ -83,8 +88,9 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
83
88
|
" #{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"
|
84
89
|
}.join("/n") %><% end %> <% merge_lookups = @alt_lookups.collect{|key, data| "#{key.gsub("_id", "")}: #{key.gsub("_id", "")}" }.join(",") %>
|
85
90
|
modified_params = modify_date_inputs_on_params(<%= singular_name %>_params.dup<%= controller_update_params_tap_away_alt_lookups %><% if @object_owner_sym && eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %>.merge!(<% if @object_owner_optional && any_nested? %><%= @object_owner_name %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {}<% else %><%= @object_owner_sym %>: <%= @object_owner_eval %><% end %>)<% end %>)<%= ".merge(#{merge_lookups})" if !merge_lookups.empty? %><% if @hawk_keys.any? %>
|
86
|
-
modified_params = hawk_params({<%= hawk_to_ruby %>}, modified_params)<% end %>
|
91
|
+
modified_params = hawk_params({<%= hawk_to_ruby %>}, modified_params)<% end %><%= controller_attachment_orig_filename_pickup_syntax %>
|
87
92
|
<%= creation_syntax %>
|
93
|
+
|
88
94
|
if @<%= singular_name %>.save
|
89
95
|
flash[:notice] = "Successfully created #{@<%= singular %>.<%= display_class %>}"
|
90
96
|
load_all_<%= plural %>
|
@@ -116,7 +122,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
116
122
|
}.join("/n") %><% end %><% if (@update_alt_lookups).any? %>
|
117
123
|
<%= @update_alt_lookups.collect{|key, data|
|
118
124
|
" @#{ singular_name }.#{key.gsub("_id", "")} = #{key.gsub("_id", "")}"
|
119
|
-
}.join("/n") %><% end %>
|
125
|
+
}.join("/n") %><% end %><%= controller_attachment_orig_filename_pickup_syntax %>
|
120
126
|
if @<%= singular_name %>.update(modified_params)
|
121
127
|
<% if @display_list_after_update %> load_all_<%= plural %><% end %>
|
122
128
|
flash[:notice] = (flash[:notice] || "") << "Saved #{@<%= singular %>.<%= display_class %>}"
|
@@ -12,15 +12,28 @@
|
|
12
12
|
<% unless @no_list_heading %>
|
13
13
|
<div class="<%= @layout_strategy.row_classes %> <%= @layout_strategy.row_heading_classes %>">
|
14
14
|
<%= list_column_headings %>
|
15
|
+
|
15
16
|
<% if @downnest_object.any? %>
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
<
|
20
|
-
|
21
|
-
|
17
|
+
<% if !@stacked_downnesting %>
|
18
|
+
<%= @layout_strategy.downnest_column_style %>
|
19
|
+
<% @downnest_object.each do |downnest,i| %>
|
20
|
+
<div class=" scaffold-col-heading <%= @layout_strategy.downnest_portal_column_width(downnest) %> <%= @layout_strategy.downnest_column_style %>">
|
21
|
+
<strong>
|
22
|
+
<%= downnest.titleize %>
|
23
|
+
</strong>
|
24
|
+
</div>
|
25
|
+
<% end %>
|
26
|
+
<% else %>
|
27
|
+
<div class=" scaffold-col-heading <%= @layout_strategy.downnest_portal_stacked_column_width %> <%= @layout_strategy.downnest_column_style %>">
|
28
|
+
<%= @layout_strategy.downnest_column_style %>
|
29
|
+
<% @downnest_object.each do |downnest,i| %>
|
30
|
+
<strong>
|
31
|
+
<%= downnest.titleize %>
|
32
|
+
</strong>
|
33
|
+
<% end %>
|
22
34
|
</div>
|
23
35
|
<% end %>
|
36
|
+
|
24
37
|
<% end %>
|
25
38
|
|
26
39
|
<div class=' scaffold-col-heading scaffold-col-heading-buttons <%= @layout_strategy.column_classes_for_column_headings %>' <%= @layout_strategy.button_column_style %>>
|
@@ -1,16 +1,17 @@
|
|
1
1
|
<%= all_line_fields %>
|
2
2
|
|
3
|
+
|
4
|
+
|
3
5
|
<% if @downnest_children.any? %>
|
4
6
|
<% each_downnest_width = @downnest_children.count == 1 ? 33 : (53/@downnest_children.count).floor %>
|
5
|
-
|
7
|
+
<% if @stacked_downnesting %><div class="<%= @layout_strategy.downnest_portal_stacked_column_width %> scaffold-downnest" ><% end %>
|
6
8
|
<% @downnest_object.each do |downnest, size| %>
|
7
|
-
|
8
9
|
<% downnest_object = eval("#{singular_class}.reflect_on_association(:#{downnest})") %>
|
9
10
|
<% if downnest_object.nil?; raise "no relationship for downnested portal `#{downnest}` found on `#{singular_class}`; please check relationship for has_many :#{downnest}"; end; %>
|
10
11
|
<% downnest_class = downnest_object.class_name %>
|
11
12
|
<% downnest_object_name = eval("#{downnest_class}.table_name") %>
|
12
13
|
<% downnest_style = @layout_strategy.downnest_style %>
|
13
|
-
|
14
|
+
<% if !@stacked_downnesting %><div class="<%= @layout_strategy.downnest_portal_column_width(downnest) %> scaffold-downnest" <%= downnest_style %> ><% end %>
|
14
15
|
<\%= render partial: "<%= namespace_with_trailing_dash %><%= downnest_object_name %>/list", locals: {
|
15
16
|
<%= @singular %>: <%= @singular %>,
|
16
17
|
<%= downnest_object_name %>: <%= @singular %>.<%= downnest %>
|
@@ -18,8 +19,9 @@
|
|
18
19
|
.merge({nested_for: "<% if @nested_set.any? %>#{nested_for + "__" if defined?(nested_for)}<% end %><%= @singular %>-#{<%= @singular %>.id}"})
|
19
20
|
<%= @nested_set.collect{|arg| ".merge(defined?(#{arg[:singular]}) ? {#{arg[:singular]}: #{arg[:singular]}} : {} )"}.join("\n") %>
|
20
21
|
\%>
|
21
|
-
|
22
|
+
<% if !@stacked_downnesting %></div><% end %>
|
22
23
|
<% end %>
|
24
|
+
<% if @stacked_downnesting %></div><% end %>
|
23
25
|
<% end %>
|
24
26
|
|
25
27
|
<%= @layout_strategy.button_style %>
|
@@ -0,0 +1,191 @@
|
|
1
|
+
import Dropzone from "dropzone";
|
2
|
+
import { Controller } from "@hotwired/stimulus"
|
3
|
+
import { DirectUpload } from "@rails/activestorage";
|
4
|
+
|
5
|
+
export default class extends Controller {
|
6
|
+
static targets = ["input"];
|
7
|
+
|
8
|
+
connect() {
|
9
|
+
this.dropZone = this.createDropZone(this);
|
10
|
+
this.hideFileInput();
|
11
|
+
this.bindEvents();
|
12
|
+
Dropzone.autoDiscover = false; // necessary quirk for Dropzone error in console
|
13
|
+
}
|
14
|
+
|
15
|
+
// helpers
|
16
|
+
getMetaValue(name) {
|
17
|
+
const element = this.findElement(document.head, `meta[name="${name}"]`);
|
18
|
+
if (element) {
|
19
|
+
return element.getAttribute("content");
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
findElement(root, selector) {
|
24
|
+
if (typeof root == "string") {
|
25
|
+
selector = root;
|
26
|
+
root = document;
|
27
|
+
}
|
28
|
+
return root.querySelector(selector);
|
29
|
+
}
|
30
|
+
|
31
|
+
toArray(value) {
|
32
|
+
if (Array.isArray(value)) {
|
33
|
+
return value;
|
34
|
+
} else if (Array.from) {
|
35
|
+
return Array.from(value);
|
36
|
+
} else {
|
37
|
+
return [].slice.call(value);
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
|
42
|
+
hideFileInput() {
|
43
|
+
this.inputTarget.disabled = true;
|
44
|
+
this.inputTarget.style.display = "none";
|
45
|
+
}
|
46
|
+
|
47
|
+
bindEvents() {
|
48
|
+
this.dropZone.on("addedfile", file => {
|
49
|
+
setTimeout(() => {
|
50
|
+
if (file.accepted) {
|
51
|
+
const duc = new DirectUploadProcessor(this, this.url(), file)
|
52
|
+
duc.start();
|
53
|
+
}
|
54
|
+
}, 500);
|
55
|
+
});
|
56
|
+
|
57
|
+
this.dropZone.on("removedfile", file => {
|
58
|
+
if(file.controller) {
|
59
|
+
file.controller.hiddenInput.parentNode.removeChild(file.controller.hiddenInput);
|
60
|
+
}
|
61
|
+
});
|
62
|
+
|
63
|
+
this.dropZone.on("canceled", file => {
|
64
|
+
file.controller && file.controller.xhr.abort();
|
65
|
+
});
|
66
|
+
}
|
67
|
+
|
68
|
+
url() {
|
69
|
+
return this.inputTarget.getAttribute("data-direct-upload-url");
|
70
|
+
}
|
71
|
+
|
72
|
+
createDropZone() {
|
73
|
+
|
74
|
+
return new Dropzone(this.element, {
|
75
|
+
url: this.url(),
|
76
|
+
headers: this.headers,
|
77
|
+
maxFiles: this.maxFiles,
|
78
|
+
maxFilesize: this.maxFileSize,
|
79
|
+
acceptedFiles: this.acceptedFiles,
|
80
|
+
addRemoveLinks: this.addRemoveLinks,
|
81
|
+
autoQueue: false
|
82
|
+
});
|
83
|
+
}
|
84
|
+
|
85
|
+
get headers() {
|
86
|
+
return { "X-CSRF-Token": this.getMetaValue("csrf-token") };
|
87
|
+
}
|
88
|
+
|
89
|
+
get maxFiles() {
|
90
|
+
return this.data.get("maxFiles") || 1;
|
91
|
+
}
|
92
|
+
|
93
|
+
get maxFileSize() {
|
94
|
+
return this.data.get("maxFileSize") || 256;
|
95
|
+
}
|
96
|
+
|
97
|
+
get acceptedFiles() {
|
98
|
+
return this.data.get("acceptedFiles");
|
99
|
+
}
|
100
|
+
|
101
|
+
get addRemoveLinks() {
|
102
|
+
return this.data.get("addRemoveLinks") || true;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
class DirectUploadProcessor {
|
107
|
+
constructor(source, url, file) {
|
108
|
+
this.directUpload = createDirectUpload(file, url, this);
|
109
|
+
this.source = source;
|
110
|
+
this.file = file;
|
111
|
+
this.url = url;
|
112
|
+
}
|
113
|
+
|
114
|
+
insertAfter(el, referenceNode) {
|
115
|
+
return referenceNode.parentNode.insertBefore(el, referenceNode.nextSibling);
|
116
|
+
}
|
117
|
+
|
118
|
+
start() {
|
119
|
+
this.file.controller = this;
|
120
|
+
this.hiddenInput = this.createHiddenInput();
|
121
|
+
this.directUpload.create((error, attributes) => {
|
122
|
+
if (error) {
|
123
|
+
|
124
|
+
this.hiddenInput.remove();
|
125
|
+
this.emitDropzoneError(error);
|
126
|
+
} else {
|
127
|
+
this.hiddenInput.value = attributes.signed_id;
|
128
|
+
this.emitDropzoneSuccess();
|
129
|
+
}
|
130
|
+
});
|
131
|
+
}
|
132
|
+
|
133
|
+
createHiddenInput() {
|
134
|
+
const input = document.createElement("input");
|
135
|
+
input.type = "hidden";
|
136
|
+
input.name = this.source.inputTarget.name;
|
137
|
+
this.insertAfter(input, this.source.inputTarget);
|
138
|
+
return input;
|
139
|
+
}
|
140
|
+
|
141
|
+
directUploadWillStoreFileWithXHR(xhr) {
|
142
|
+
this.bindProgressEvent(xhr);
|
143
|
+
this.emitDropzoneUploading();
|
144
|
+
}
|
145
|
+
|
146
|
+
bindProgressEvent(xhr) {
|
147
|
+
this.xhr = xhr;
|
148
|
+
this.xhr.upload.addEventListener("progress", event =>
|
149
|
+
this.uploadRequestDidProgress(event)
|
150
|
+
);
|
151
|
+
}
|
152
|
+
|
153
|
+
findElement(root, selector) {
|
154
|
+
if (typeof root == "string") {
|
155
|
+
selector = root;
|
156
|
+
root = document;
|
157
|
+
}
|
158
|
+
return root.querySelector(selector);
|
159
|
+
}
|
160
|
+
|
161
|
+
uploadRequestDidProgress(event) {
|
162
|
+
const element = this.source.element;
|
163
|
+
const progress = (event.loaded / event.total) * 100;
|
164
|
+
this.findElement(
|
165
|
+
this.file.previewTemplate,
|
166
|
+
".dz-upload"
|
167
|
+
).style.width = `${progress}%`;
|
168
|
+
}
|
169
|
+
|
170
|
+
emitDropzoneUploading() {
|
171
|
+
this.file.status = Dropzone.UPLOADING;
|
172
|
+
this.source.dropZone.emit("processing", this.file);
|
173
|
+
}
|
174
|
+
|
175
|
+
emitDropzoneError(error) {
|
176
|
+
this.file.status = Dropzone.ERROR;
|
177
|
+
this.source.dropZone.emit("error", this.file, error);
|
178
|
+
this.source.dropZone.emit("complete", this.file);
|
179
|
+
}
|
180
|
+
|
181
|
+
emitDropzoneSuccess() {
|
182
|
+
this.file.status = Dropzone.SUCCESS;
|
183
|
+
this.source.dropZone.emit("success", this.file);
|
184
|
+
this.source.dropZone.emit("complete", this.file);
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
function createDirectUpload(file, url, controller) {
|
189
|
+
return new DirectUpload(file, url, controller);
|
190
|
+
}
|
191
|
+
|
@@ -1,93 +1,31 @@
|
|
1
|
-
|
1
|
+
<% item1_addOns = ""
|
2
|
+
if (eval(@singular_class).instance_methods.include?(display_class.to_s))
|
3
|
+
item1_addOns << "#{display_class}: FFaker::Name.name"
|
4
|
+
end
|
5
|
+
item1_addOns << ", " + @columns_map.collect{|col, col_object|
|
6
|
+
col_object.spec_setup_let_arg
|
7
|
+
}.compact.join(", ")
|
8
|
+
%>require 'rails_helper'
|
2
9
|
|
3
10
|
describe 'interaction for <%= controller_class_name %>' do
|
4
11
|
include HotGlue::ControllerHelper
|
5
12
|
include ActionView::RecordIdentifier
|
6
13
|
|
7
14
|
<%= @existing_content %>
|
8
|
-
<% unless @god %>let(:<%= @auth %>) {create(:<%= @auth.gsub('current_', '') %>)}<%end%>
|
15
|
+
<% unless @god %>let(:<%= @auth %>) {create(:<%= @auth.gsub('current_', '') %>)}<% end %>
|
9
16
|
<%= spec_related_column_lets %>
|
10
|
-
|
11
|
-
if (eval(@singular_class).instance_methods.include?(display_class.to_s))
|
12
|
-
item1_addOns << "#{display_class}: FFaker::Name.name"
|
13
|
-
end
|
14
|
-
|
15
|
-
item1_addOns << ", " + @columns.map { |col|
|
16
|
-
type = eval("#{singular_class}.columns_hash['#{col}']").type
|
17
|
-
case type
|
18
|
-
when :string
|
19
|
-
faker_string =
|
20
|
-
if col.to_s.include?('email')
|
21
|
-
"#{col}: FFaker::Internet.email"
|
22
|
-
elsif col.to_s.include?('domain')
|
23
|
-
"#{col}: FFaker::Internet.domain_name"
|
24
|
-
elsif col.to_s.include?('ip_address') || col.to_s.ends_with?('_ip')
|
25
|
-
"#{col}: FFaker::Internet.ip_v4_address"
|
26
|
-
else
|
27
|
-
"#{col}: FFaker::Movie.title"
|
28
|
-
end
|
29
|
-
when :text
|
30
|
-
"#{col}: FFaker::Lorem.paragraphs(10).join(" ")"
|
31
|
-
|
32
|
-
when :float
|
33
|
-
"#{col}: rand(1)*10000"
|
34
|
-
when :boolean
|
35
|
-
"#{col}: !!rand(2).floor"
|
36
|
-
when :time
|
37
|
-
"#{col}: Time.current + rand(5000).seconds"
|
38
|
-
when :date
|
39
|
-
"#{col}: Date.current + rand(50).days"
|
40
|
-
when :datetime
|
41
|
-
"#{col}: DateTime.current + rand(1000).seconds"
|
42
|
-
when :integer
|
43
|
-
if col.to_s.ends_with?("_id")
|
44
|
-
"#{col.to_s.gsub('_id','')}: #{col.to_s.gsub('_id','')}1"
|
45
|
-
else
|
46
|
-
"#{col}: rand(100)"
|
47
|
-
end
|
48
|
-
when :uuid
|
49
|
-
"#{col.to_s.gsub('_id','')}: #{col.to_s.gsub('_id','')}1"
|
50
|
-
end
|
51
|
-
}.compact.join(", ")
|
52
|
-
%>let!(:<%= singular %>1) {create(:<%= singular %><%= object_parent_mapping_as_argument_for_specs %> <%= item1_addOns %> )}
|
17
|
+
let!(:<%= singular %>1) {create(:<%= singular %><%= object_parent_mapping_as_argument_for_specs %> <%= item1_addOns %> )}
|
53
18
|
<%= objest_nest_factory_setup %> <% unless @god || @existing_content.include?("login_as")%>
|
54
19
|
before do
|
55
20
|
login_as(<%= @auth %>)
|
56
|
-
end <% end %>
|
57
|
-
|
21
|
+
end <% end %> <% if any_datetime_fields? %>
|
22
|
+
let(:current_timezone) {
|
23
|
+
<%= @auth_identifier %>.try(:timezone) || Time.now.strftime("%z").to_i/100
|
24
|
+
}<% end %>
|
58
25
|
describe "index" do
|
59
26
|
it "should show me the list" do
|
60
27
|
visit <%= path_helper_plural %>
|
61
|
-
<%=
|
62
|
-
@columns.map { |col|
|
63
|
-
type = eval("#{singular_class}.columns_hash['#{col}']").type
|
64
|
-
|
65
|
-
case type
|
66
|
-
when :datetime
|
67
|
-
" " + ["expect(page).to have_content(#{singular}#{1}.#{col}.in_time_zone(current_timezone).strftime('%m/%d/%Y @ %l:%M %p ').gsub(' ', ' ') + timezonize(current_timezone) )"].join("\n ")
|
68
|
-
when :integer
|
69
|
-
if !col.ends_with?("_id")
|
70
|
-
" " + ["expect(page).to have_content(#{singular}#{1}.#{col})"].join("\n ")
|
71
|
-
end
|
72
|
-
when :uuid
|
73
|
-
assoc_name = col.to_s.gsub('_id','')
|
74
|
-
association = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
|
75
|
-
" " + ["expect(page).to have_content(#{singular}#{1}.#{assoc_name}.#{HotGlue.derrive_reference_name(association.class_name)})"].join("\n ")
|
76
|
-
when :enum
|
77
|
-
if(eval("#{singular_class}.respond_to?(:#{col}_labels)"))
|
78
|
-
" " + "expect(page).to have_content(#{singular_class}.#{col}_labels[#{singular}#{1}.#{col}])"
|
79
|
-
else
|
80
|
-
" " + "expect(page).to have_content(new_#{col})"
|
81
|
-
end
|
82
|
-
|
83
|
-
when :boolean
|
84
|
-
" " + ["expect(page).to have_content(#{singular}#{1}.#{col} ? 'YES' : 'NO')"].join("\n ")
|
85
|
-
else
|
86
|
-
" " + ["expect(page).to have_content(#{singular}#{1}.#{col})"].join("\n ")
|
87
|
-
end
|
88
|
-
|
89
|
-
}.join("\n")
|
90
|
-
%>
|
28
|
+
<%= @columns_map.collect{|col, col_object| col_object.spec_list_view_assertion } %>
|
91
29
|
end
|
92
30
|
end
|
93
31
|
|
@@ -96,40 +34,17 @@ describe 'interaction for <%= controller_class_name %>' do
|
|
96
34
|
visit <%= path_helper_plural %>
|
97
35
|
click_link "<%= @new_button_label %>"
|
98
36
|
expect(page).to have_selector(:xpath, './/h3[contains(., "<%= @new_button_label %>")]')
|
99
|
-
<%=
|
37
|
+
<%= capybara_make_updates(:create) %>
|
100
38
|
click_button "Save"
|
101
39
|
expect(page).to have_content("Successfully created")
|
102
|
-
<%=" " +
|
103
|
-
|
104
|
-
(@columns - @show_only).map { |col|
|
105
|
-
type = eval("#{singular_class}.columns_hash['#{col}']").type
|
106
|
-
|
107
|
-
case type
|
108
|
-
when :datetime
|
109
|
-
# " expect(page).to have_content(#{col}.in_time_zone(current_timezone).strftime('%m/%d/%Y') + \" @ \" +
|
110
|
-
# new_#{col}.in_time_zone(current_timezone).strftime('%l').strip + \":\" +
|
111
|
-
# new_#{col}.in_time_zone(current_timezone).strftime('%M %p').strip + \" \" +
|
112
|
-
# timezonize(current_timezone))"
|
113
|
-
when :integer
|
114
|
-
if col.to_s.ends_with?("_id")
|
115
|
-
# shoould the assoication be on here
|
116
|
-
else
|
117
|
-
"expect(page).to have_content(new_#{col})"
|
118
|
-
end
|
119
40
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
end
|
128
|
-
else
|
129
|
-
"expect(page).to have_content(new_#{col})"
|
130
|
-
end
|
131
|
-
|
132
|
-
}.compact.join("\n ")
|
41
|
+
<%=" " + @columns_map.map{ |col, col_object|
|
42
|
+
if @attachments.keys.collect(&:to_sym).include?(col)
|
43
|
+
elsif @show_only.include?(col)
|
44
|
+
else
|
45
|
+
col_object.spec_make_assertion
|
46
|
+
end
|
47
|
+
}.compact.join("\n ")
|
133
48
|
%>
|
134
49
|
end
|
135
50
|
end<% end %>
|
@@ -141,10 +56,10 @@ describe 'interaction for <%= controller_class_name %>' do
|
|
141
56
|
find("a.edit-<%= singular %>-button[href='/<%= namespace_with_slash %><%= plural %>/#{<%= singular %>1.id}/edit']").click
|
142
57
|
|
143
58
|
expect(page).to have_content("Editing #{<%= singular %>1.<%= @display_class %>.squish || "(no name)"}")
|
144
|
-
<%=
|
59
|
+
<%= capybara_make_updates(:update) %>
|
145
60
|
click_button "Save"
|
146
61
|
within("turbo-frame#<%= @namespace %>__#{dom_id(<%= singular %>1)} ") do
|
147
|
-
<%= (@columns - @show_only).map { |col|
|
62
|
+
<%= ((@columns - @attachments.keys.collect(&:to_sym)) - (@show_only+@update_show_only)).map { |col|
|
148
63
|
type = eval("#{singular_class}.columns_hash['#{col}']").type
|
149
64
|
|
150
65
|
if type == :uuid || (type == :integer && col.to_s.ends_with?("_id"))
|
@@ -157,8 +72,14 @@ describe 'interaction for <%= controller_class_name %>' do
|
|
157
72
|
|
158
73
|
elsif type == :enum && eval("#{singular_class}.respond_to?(:#{col}_labels)")
|
159
74
|
" expect(page).to have_content(#{singular_class}.#{col}_labels[new_#{col}])"
|
75
|
+
elsif type == :string && eval("#{singular_class}.respond_to?(:devise_modules)") &&
|
76
|
+
#devise confirmable makes email updates go into unconfirmed_email
|
77
|
+
eval("#{singular_class}.devise_modules.include?(:confirmable)") && col.to_s == "email"
|
78
|
+
" expect(page).to have_content(#{ singular }1.#{col.to_s})"
|
79
|
+
elsif type == :datetime
|
80
|
+
" expect(page).to have_content(new_#{col.to_s}.in_time_zone(current_timezone).strftime('%m/%d/%Y @ %l:%M %p ') + timezonize(current_timezone))"
|
160
81
|
else
|
161
|
-
|
82
|
+
" expect(page).to have_content(new_#{col.to_s})"
|
162
83
|
end
|
163
84
|
}.compact.join("\n")
|
164
85
|
%>
|
data/lib/hotglue/version.rb
CHANGED
data/script/clean_generated_code
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.9.2
|
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-04-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -75,6 +75,22 @@ files:
|
|
75
75
|
- config/database.yml
|
76
76
|
- config/hot_glue.yml
|
77
77
|
- db/schema.rb
|
78
|
+
- lib/generators/hot_glue/direct_upload_install_generator.rb
|
79
|
+
- lib/generators/hot_glue/dropzone_install_generator.rb
|
80
|
+
- lib/generators/hot_glue/field_factory.rb
|
81
|
+
- lib/generators/hot_glue/fields/association_field.rb
|
82
|
+
- lib/generators/hot_glue/fields/attachment_field.rb
|
83
|
+
- lib/generators/hot_glue/fields/boolean_field.rb
|
84
|
+
- lib/generators/hot_glue/fields/date_field.rb
|
85
|
+
- lib/generators/hot_glue/fields/date_time_field.rb
|
86
|
+
- lib/generators/hot_glue/fields/enum_field.rb
|
87
|
+
- lib/generators/hot_glue/fields/field.rb
|
88
|
+
- lib/generators/hot_glue/fields/float_field.rb
|
89
|
+
- lib/generators/hot_glue/fields/integer_field.rb
|
90
|
+
- lib/generators/hot_glue/fields/string_field.rb
|
91
|
+
- lib/generators/hot_glue/fields/text_field.rb
|
92
|
+
- lib/generators/hot_glue/fields/time_field.rb
|
93
|
+
- lib/generators/hot_glue/fields/uuid_field.rb
|
78
94
|
- lib/generators/hot_glue/install_generator.rb
|
79
95
|
- lib/generators/hot_glue/layout/builder.rb
|
80
96
|
- lib/generators/hot_glue/layout_strategy/base.rb
|
@@ -86,6 +102,7 @@ files:
|
|
86
102
|
- lib/generators/hot_glue/scaffold_generator.rb
|
87
103
|
- lib/generators/hot_glue/templates/base_controller.rb.erb
|
88
104
|
- lib/generators/hot_glue/templates/capybara_login.rb
|
105
|
+
- lib/generators/hot_glue/templates/computer_code.jpg
|
89
106
|
- lib/generators/hot_glue/templates/controller.rb.erb
|
90
107
|
- lib/generators/hot_glue/templates/erb/_errors.erb
|
91
108
|
- lib/generators/hot_glue/templates/erb/_flash_notices.erb
|
@@ -117,6 +134,7 @@ files:
|
|
117
134
|
- lib/generators/hot_glue/templates/haml/index.haml
|
118
135
|
- lib/generators/hot_glue/templates/haml/new.haml
|
119
136
|
- lib/generators/hot_glue/templates/haml/update.turbo_stream.haml
|
137
|
+
- lib/generators/hot_glue/templates/javascript/dropzone_controller.js
|
120
138
|
- lib/generators/hot_glue/templates/system_spec.rb.erb
|
121
139
|
- lib/generators/hot_glue/templates/themes/hotglue_scaffold_dark_knight.scss
|
122
140
|
- lib/generators/hot_glue/templates/themes/hotglue_scaffold_like_bootstrap.scss
|
@@ -131,9 +149,9 @@ homepage: https://heliosdev.shop/p/hot-glue?utm_source=rubygems.org&utm_campaign
|
|
131
149
|
licenses:
|
132
150
|
- Nonstandard
|
133
151
|
metadata:
|
134
|
-
source_code_uri: https://github.com/
|
152
|
+
source_code_uri: https://github.com/hot-glue-for-rails/hot-glue
|
135
153
|
homepage: https://heliosdev.shop/hot-glue
|
136
|
-
funding: https://
|
154
|
+
funding: https://school.jasonfleetwoodboldt.com/8188
|
137
155
|
post_install_message: |
|
138
156
|
---------------------------------------------
|
139
157
|
Welcome to Hot Glue - A Scaffold Building Companion for Hotwire + Turbo-Rails
|