hot-glue 0.5.17 → 0.5.19.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +10 -2
- data/.github/workflows/test_suite.yml +46 -0
- data/Gemfile.lock +1 -1
- data/README.md +64 -17
- data/app/helpers/hot_glue/controller_helper.rb +42 -30
- data/config/hot_glue.yml +2 -2
- data/lib/generators/hot_glue/field_factory.rb +3 -1
- data/lib/generators/hot_glue/fields/association_field.rb +3 -1
- data/lib/generators/hot_glue/fields/attachment_field.rb +3 -1
- data/lib/generators/hot_glue/fields/boolean_field.rb +40 -7
- data/lib/generators/hot_glue/fields/date_field.rb +1 -1
- data/lib/generators/hot_glue/fields/date_time_field.rb +6 -6
- data/lib/generators/hot_glue/fields/field.rb +27 -1
- data/lib/generators/hot_glue/fields/time_field.rb +12 -4
- data/lib/generators/hot_glue/layout/builder.rb +9 -3
- data/lib/generators/hot_glue/layout_strategy/base.rb +3 -0
- data/lib/generators/hot_glue/layout_strategy/bootstrap.rb +12 -0
- data/lib/generators/hot_glue/markup_templates/erb.rb +5 -1
- data/lib/generators/hot_glue/scaffold_generator.rb +41 -7
- data/lib/generators/hot_glue/templates/controller.rb.erb +18 -5
- data/lib/generators/hot_glue/templates/system_spec.rb.erb +10 -26
- data/lib/hotglue/version.rb +1 -1
- metadata +3 -3
- data/.github/workflows/test.yml +0 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86497d64d197f64d4df68804b0cfcb02f5541c64d98932cdb723e1b19b4aa76b
|
4
|
+
data.tar.gz: 7e6161cee21f3a4e5968d450cb44ade8fcb4b7c6e15d3c466ffa47527c979ec7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d0788389d37a0a477793bbce0a57c29141061d35e3d4bb26e56affa15ec446f4eba1e6b545c316118eba231c1c3e9d51d1c68dcc62dea2990cedd4dbcd59ca1
|
7
|
+
data.tar.gz: d2036061122d60696b6cc24bd3085aeee5525f531d950f40ea569e9f54d229a0cca6cdaf573f0da5a73aab3e3743857155d7b54ce83c47aa74e83fd74aa93731
|
data/.circleci/config.yml
CHANGED
@@ -3,7 +3,7 @@ version: 2.1
|
|
3
3
|
|
4
4
|
orbs:
|
5
5
|
ruby: circleci/ruby@1.0
|
6
|
-
browser-tools: circleci/browser-tools@1.4.
|
6
|
+
browser-tools: circleci/browser-tools@1.4.4
|
7
7
|
|
8
8
|
jobs:
|
9
9
|
build:
|
@@ -47,7 +47,15 @@ jobs:
|
|
47
47
|
RAILS_ENV: test
|
48
48
|
|
49
49
|
steps:
|
50
|
-
-
|
50
|
+
- run: sudo apt-get update
|
51
|
+
- browser-tools/install-browser-tools:
|
52
|
+
chrome-version: 116.0.5845.96 # TODO: remove when chromedriver downloads are fixed
|
53
|
+
replace-existing-chrome: true
|
54
|
+
- browser-tools/install-chrome:
|
55
|
+
# TODO remove following line when fixed https://github.com/CircleCI-Public/browser-tools-orb/issues/90
|
56
|
+
chrome-version: 116.0.5845.96
|
57
|
+
replace-existing: true
|
58
|
+
|
51
59
|
- browser-tools/install-chromedriver
|
52
60
|
- checkout
|
53
61
|
- ruby/install-deps
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub. They are
|
2
|
+
# provided by a third-party and are governed by separate terms of service,
|
3
|
+
# privacy policy, and support documentation.
|
4
|
+
#
|
5
|
+
# This workflow will install a prebuilt Ruby version, install dependencies, and
|
6
|
+
# run tests and linters.
|
7
|
+
name: "Test Suite"
|
8
|
+
on:
|
9
|
+
push:
|
10
|
+
branches: [ "main" ]
|
11
|
+
pull_request:
|
12
|
+
branches: [ "main" ]
|
13
|
+
jobs:
|
14
|
+
test:
|
15
|
+
runs-on: ubuntu-latest
|
16
|
+
services:
|
17
|
+
postgres:
|
18
|
+
image: postgres:11-alpine
|
19
|
+
ports:
|
20
|
+
- "5432:5432"
|
21
|
+
env:
|
22
|
+
POSTGRES_DB: rails_test
|
23
|
+
POSTGRES_USER: rails
|
24
|
+
POSTGRES_PASSWORD: password
|
25
|
+
chrome:
|
26
|
+
image: selenium/standalone-chrome:latest
|
27
|
+
ports:
|
28
|
+
- 4444:4444
|
29
|
+
env:
|
30
|
+
RAILS_ENV: test
|
31
|
+
DATABASE_URL: "postgres://rails:password@localhost:5432/rails_test"
|
32
|
+
|
33
|
+
|
34
|
+
steps:
|
35
|
+
- name: Checkout code
|
36
|
+
uses: actions/checkout@v3
|
37
|
+
- name: Install Ruby and gems
|
38
|
+
uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0
|
39
|
+
with:
|
40
|
+
bundler-cache: true
|
41
|
+
|
42
|
+
- name: internal tests
|
43
|
+
run: bundle exec rspec
|
44
|
+
- name: system tests
|
45
|
+
run: script/test
|
46
|
+
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -672,9 +672,8 @@ here, even though `paid_at` is a datetime field, it will display as-if it is a b
|
|
672
672
|
label or the falsy label depending on if `paid_at` is or is not null in the database.
|
673
673
|
For all fields except booleans, this affects only the viewable output —
|
674
674
|
what you see on the list page and on the edit page for show-only fields.
|
675
|
-
For booleans, it affects those outputs as well as the normal
|
676
|
-
|
677
|
-
|
675
|
+
For booleans shown as radio buttons, it affects those outputs as well as the normal view output.
|
676
|
+
For booleans shown as checkboxes or switches, it affects only the view output as the truthy and falsy labels are not displays in editbale view.
|
678
677
|
|
679
678
|
You will need to separately specify them as show-only if you want them to be non-editable.
|
680
679
|
|
@@ -1159,13 +1158,13 @@ factory = AgentFactory.new(find_or_create_by_email: agent_company_params[:__look
|
|
1159
1158
|
params: modified_params)
|
1160
1159
|
```
|
1161
1160
|
|
1162
|
-
Here the new AgentFactory will
|
1161
|
+
Here the new AgentFactory will receive any variables by keyword argument, and since you're specifying the calling code here, Hot Glue does not dictate your factory's setup.
|
1163
1162
|
However, two special variables are in scope which you can use in your calling code.
|
1164
1163
|
|
1165
1164
|
`*_params` (where * is the name of the thing you are building)
|
1166
|
-
`modified_params`
|
1165
|
+
`modified_params`
|
1167
1166
|
|
1168
|
-
Either one must be
|
1167
|
+
Either one must be received by your factory for your factory to create data based off the inputted data.
|
1169
1168
|
|
1170
1169
|
Rememebr, `*_params` has the input params passed only the through the sanitizer, and modified_params has it passed through the timezone aware mechanism and other Hot Glue-specific defaults.
|
1171
1170
|
|
@@ -1179,14 +1178,14 @@ Always:
|
|
1179
1178
|
Don't include this last line in your factory code.
|
1180
1179
|
|
1181
1180
|
## Nav Templates
|
1182
|
-
At the namespace level, you can have a file called `_nav.html.erb` to create tabbed bootstrap nav
|
1181
|
+
At the namespace level, you can have a file called `_nav.html.erb` to create tabbed bootstrap nav
|
1183
1182
|
|
1184
|
-
To create the
|
1183
|
+
To create the file for the first time (at each namespace), start by running
|
1185
1184
|
```
|
1186
1185
|
bin/rails generate hot_glue:nav_template --namespace=xyz
|
1187
|
-
|
1188
1186
|
```
|
1189
|
-
|
1187
|
+
|
1188
|
+
This will append the file `_nav.html.erb` to the views folder at `views/xyz`. To begin, this file contains only the following:
|
1190
1189
|
|
1191
1190
|
```
|
1192
1191
|
<ul class='nav nav-tabs'>
|
@@ -1195,19 +1194,18 @@ this will append the file `_nav.html.erb` to the views folder at `views/xyz`
|
|
1195
1194
|
|
1196
1195
|
Once the file is present, any further builds in this namespace will:
|
1197
1196
|
|
1198
|
-
1) Append to
|
1199
|
-
2)
|
1197
|
+
1) Append to this `_nav.html.erb` file, adding a tab for the new built scaffold
|
1198
|
+
2) On the list view of the scaffold being built, it will include a render to the _nav partial, passing the name of the currently-viewed thing as the local variable `nav` (this is how the nav template knows which tab to make active).
|
1200
1199
|
```
|
1201
1200
|
<%= render partial: "owner/nav", locals: {nav: "things"} %>
|
1202
1201
|
```
|
1203
|
-
(
|
1202
|
+
(In this example `owner/` is the namespace and `things` is the name of the scaffold being built)
|
1204
1203
|
|
1205
1204
|
## Automatic Base Controller
|
1206
1205
|
|
1207
|
-
|
1208
|
-
|
1209
|
-
The created controller will always have this base controller as its subclass. You are encouraged to implement functionality common to the *namespace* (shared between the controllers in the namespace) using this technique.
|
1206
|
+
Hot Glue will copy a file named `base_controller.rb` to the same folder where it tries to create any controller (so to the namespace), unless such a file exists there already.
|
1210
1207
|
|
1208
|
+
The created controller will always have this base controller as its subclass. You are encouraged to implement functionality common to all the controllers in the *namespace* in the base class. For example, authorizing your user to access that part of the app.
|
1211
1209
|
|
1212
1210
|
## Special Table Labels
|
1213
1211
|
|
@@ -1300,11 +1298,60 @@ end
|
|
1300
1298
|
|
1301
1299
|
```
|
1302
1300
|
|
1301
|
+
# VERSION HISTORY
|
1302
|
+
|
1303
|
+
#### 2023-09-02 - v0.5.19
|
1304
|
+
|
1305
|
+
Given a table generated with this schema:
|
1306
|
+
```
|
1307
|
+
rails generate model Thing abc:boolean dfg:boolean hij:boolean klm_at:datetime
|
1308
|
+
```
|
1309
|
+
|
1310
|
+
• You can now use new flag `--display-as` to determine how the booleans will be displayed: checkbox, radio, or switch
|
1303
1311
|
|
1312
|
+
rails generate hot_glue:scaffold Thing --include=abc,dfg,hij,klm_at --god --modify='klm_at{yes|no}' --display-as='abc{checkbox},dfg{radio},hij{switch}'
|
1304
1313
|
|
1314
|
+
You may specify a default `default_boolean_display` in `config/hot_glue.yml`, like so:
|
1315
|
+
:default_boolean_display: 'radio'
|
1305
1316
|
|
1317
|
+
(The options are checkbox, radio, or switch.)
|
1318
|
+
If none is given and no default is specified, legacy display behavior will be used (radio buttons)
|
1319
|
+
|
1320
|
+
![Screenshot 2023-08-22 at 7 40 44 PM](https://github.com/hot-glue-for-rails/hot-glue/assets/59002/ba076cb0-fa40-4b68-a1a0-cab496670e00)
|
1321
|
+
|
1322
|
+
You still use the `--modify` flag to determine the truthy and falsy labels, which are also used as the truth and false when a boolean is displays as radio button, as shown in the `klm_at` field above. (switches and checkboxes simply display with the field label and do not use the truthy and falsy labels)
|
1323
|
+
|
1324
|
+
|
1325
|
+
|
1326
|
+
#### 2023-09-01 - v0.5.18
|
1327
|
+
- there three ways Hot Glue deals with Datetime fields:
|
1328
|
+
-
|
1329
|
+
- (1) with current users who have `timezone` method (field or method)
|
1330
|
+
- (2) without current user timezone and no global timezone set for your app
|
1331
|
+
- (3) without current user timezone and global timezone set for your app
|
1332
|
+
|
1333
|
+
- For #1, previously this method returned a time zone offset (integer). After v0.5.18, the preferred return value is a Timezone string, but legacy implementation returning offset values will continue to work.
|
1334
|
+
Your user objects should have a field called `timezone` which should be a string.
|
1335
|
+
- Note that daylight savings time is accounted for in this implementation.
|
1336
|
+
|
1337
|
+
- For #2 (your user does not have a timezone field and you _have not_ set the timezone globally), all datetimes will display in UTC timezone.
|
1338
|
+
|
1339
|
+
- For #3 (your user does not have a timezone field but you _have_ set the timezone globally), your datetimes will display in the Rails-specified timezone.
|
1340
|
+
|
1341
|
+
- be sure to configure in `config/application.rb` this:
|
1342
|
+
```
|
1343
|
+
config.time_zone = 'Eastern Time (US & Canada)'
|
1344
|
+
```
|
1345
|
+
This should be your business's default timezone.
|
1346
|
+
|
1347
|
+
|
1348
|
+
(#93)
|
1349
|
+
fixes variables be more clear if they are TimeZone objects (https://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html) or are UTC offset (integers -/+ from UTC)
|
1350
|
+
- fixes spec assertions for DateTime and Time fields
|
1351
|
+
- removes randomness causing race conditions in the datetime object specs
|
1352
|
+
**- fixes issue where setting bootstrap-column-width was not preferred if… (#88)**
|
1353
|
+
- fixes flash notice output
|
1306
1354
|
|
1307
|
-
# VERSION HISTORY
|
1308
1355
|
|
1309
1356
|
#### 2023-08-18 - v0.5.17
|
1310
1357
|
|
@@ -5,10 +5,11 @@ module HotGlue
|
|
5
5
|
(tz >= 0 ? "+" : "-") + sprintf('%02d',tz.abs) + ":00"
|
6
6
|
end
|
7
7
|
|
8
|
-
def datetime_field_localized(form_object, field_name, value, label
|
8
|
+
def datetime_field_localized(form_object, field_name, value, label )
|
9
|
+
current_timezone
|
9
10
|
form_object.text_field(field_name, class: 'form-control',
|
10
11
|
type: 'datetime-local',
|
11
|
-
value: date_to_current_timezone(value,
|
12
|
+
value: date_to_current_timezone(value, current_timezone)) + timezonize(current_timezone)
|
12
13
|
end
|
13
14
|
|
14
15
|
|
@@ -18,53 +19,65 @@ module HotGlue
|
|
18
19
|
value: value )
|
19
20
|
end
|
20
21
|
|
21
|
-
def time_field_localized(form_object, field_name, value, label
|
22
|
+
def time_field_localized(form_object, field_name, value, label )
|
23
|
+
current_timezone
|
22
24
|
form_object.text_field(field_name, class: 'form-control',
|
23
25
|
type: 'time',
|
24
|
-
value:
|
26
|
+
value: value && value.strftime("%H:%M"))
|
25
27
|
|
26
28
|
end
|
27
29
|
|
28
30
|
def current_timezone
|
31
|
+
# returns a TimeZone (https://apidock.com/rails/TimeZone) object
|
29
32
|
if defined?(current_user)
|
30
33
|
if current_user.try(:timezone)
|
31
|
-
|
34
|
+
current_user.timezone
|
35
|
+
|
36
|
+
# Time.now.in_time_zone(current_user.timezone.to_i).zone
|
32
37
|
else
|
33
|
-
|
38
|
+
Rails.application.config.time_zone
|
39
|
+
# Time.zone.name
|
34
40
|
end
|
35
41
|
else
|
36
|
-
|
42
|
+
Rails.application.config.time_zone
|
43
|
+
# Time.zone.name
|
37
44
|
end
|
38
45
|
end
|
39
46
|
|
40
47
|
def date_to_current_timezone(date, timezone = nil)
|
41
|
-
#
|
42
|
-
|
43
|
-
if
|
44
|
-
|
48
|
+
# used for displaying when in EDIT mode
|
49
|
+
# (this format is how the browser expectes to receive the value='' of the input field)
|
50
|
+
if date.nil?
|
51
|
+
return nil
|
52
|
+
else
|
53
|
+
return date.in_time_zone(timezone).strftime("%Y-%m-%dT%H:%M")
|
45
54
|
end
|
46
|
-
|
47
|
-
return nil if date.nil?
|
48
|
-
|
49
|
-
return date.in_time_zone(timezone).strftime("%Y-%m-%dT%H:%M")
|
50
|
-
# begin
|
51
|
-
#
|
52
|
-
# rescue
|
53
|
-
# return nil
|
54
|
-
# end
|
55
55
|
end
|
56
56
|
|
57
|
-
def modify_date_inputs_on_params(modified_params, current_user_object = nil)
|
58
|
-
|
59
|
-
use_timezone = (current_user_object.try(:timezone)) || Time.now.strftime("%z")
|
57
|
+
def modify_date_inputs_on_params(modified_params, current_user_object = nil, field_list = nil)
|
58
|
+
use_offset = (current_user_object.try(:timezone)) || server_timezone_offset
|
60
59
|
|
61
60
|
modified_params = modified_params.tap do |params|
|
62
61
|
params.keys.each{|k|
|
63
|
-
if k.ends_with?("_at") || k.ends_with?("_date")
|
64
62
|
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
if field_list.nil? # legacy pre v0.5.18 behavior
|
64
|
+
include_me = k.ends_with?("_at") || k.ends_with?("_date")
|
65
|
+
else
|
66
|
+
include_me = field_list.include?(k.to_sym)
|
67
|
+
end
|
68
|
+
if include_me
|
69
|
+
if use_offset != 0
|
70
|
+
puts "changing #{params[k]}"
|
71
|
+
|
72
|
+
if use_offset.is_a? String
|
73
|
+
puts "parsing #{use_offset}"
|
74
|
+
zone = DateTime.now.in_time_zone(use_offset).zone
|
75
|
+
params[k] = DateTime.parse(params[k].gsub("T", " ") + " #{zone}")
|
76
|
+
else
|
77
|
+
puts "parsing #{use_offset}"
|
78
|
+
params[k] = DateTime.strptime("#{params[k]} #{use_offset}", '%Y-%m-%dT%H:%M %z').new_offset(0)
|
79
|
+
end
|
80
|
+
puts "changed #{params[k]}"
|
68
81
|
|
69
82
|
end
|
70
83
|
end
|
@@ -73,7 +86,6 @@ module HotGlue
|
|
73
86
|
modified_params
|
74
87
|
end
|
75
88
|
|
76
|
-
|
77
89
|
def hawk_params(hawk_schema, modified_params)
|
78
90
|
@hawk_alarm = ""
|
79
91
|
hawk_schema.each do |hawk_key,hawk_definition|
|
@@ -94,8 +106,8 @@ module HotGlue
|
|
94
106
|
|
95
107
|
private
|
96
108
|
|
97
|
-
def
|
98
|
-
Time.now.strftime("%z").to_i/100
|
109
|
+
def server_timezone_offset # returns integer of hours to add/subtract from UTC
|
110
|
+
Time.now.in_time_zone(Rails.application.config.time_zone).strftime("%z").to_i/100
|
99
111
|
end
|
100
112
|
end
|
101
113
|
end
|
data/config/hot_glue.yml
CHANGED
@@ -58,6 +58,8 @@ 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
|
-
modify: generator.modify[name.to_sym] || nil
|
61
|
+
modify: generator.modify[name.to_sym] || nil,
|
62
|
+
display_as: generator.display_as[name.to_sym] || nil,
|
63
|
+
default_boolean_display: generator.default_boolean_display)
|
62
64
|
end
|
63
65
|
end
|
@@ -5,7 +5,9 @@ class AssociationField < Field
|
|
5
5
|
|
6
6
|
attr_accessor :assoc_name, :assoc_class, :assoc
|
7
7
|
|
8
|
-
def initialize(
|
8
|
+
def initialize(alt_lookups: , class_name: , default_boolean_display:, display_as: ,
|
9
|
+
name: , singular: ,
|
10
|
+
update_show_only: ,
|
9
11
|
hawk_keys: , auth: , sample_file_path:, ownership_field: ,
|
10
12
|
attachment_data: nil , layout_strategy: , form_placeholder_labels: nil,
|
11
13
|
form_labels_position:, modify: )
|
@@ -1,6 +1,8 @@
|
|
1
1
|
class AttachmentField < Field
|
2
2
|
attr_accessor :attachment_data
|
3
|
-
def initialize(name:, class_name:, alt_lookups:,
|
3
|
+
def initialize(name:, class_name:, alt_lookups:, default_boolean_display: ,
|
4
|
+
display_as:,
|
5
|
+
singular:, update_show_only:, hawk_keys:, auth:,
|
4
6
|
sample_file_path: nil, attachment_data:, ownership_field:, layout_strategy: ,
|
5
7
|
form_placeholder_labels: , form_labels_position:, modify: )
|
6
8
|
super
|
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
class BooleanField < Field
|
2
3
|
def spec_setup_and_change_act(which_partial = nil)
|
3
4
|
" new_#{name} = 1 \n" +
|
@@ -15,15 +16,43 @@ class BooleanField < Field
|
|
15
16
|
def spec_list_view_assertion
|
16
17
|
["expect(page).to have_content(#{singular}#{1}.#{name} ? 'YES' : 'NO')"].join("\n ")
|
17
18
|
end
|
18
|
-
|
19
|
-
|
19
|
+
|
20
|
+
def label_for
|
21
|
+
"#{singular}_#{name}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def radio_button_display
|
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" +
|
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"
|
29
|
+
end
|
30
|
+
|
31
|
+
def checkbox_display
|
32
|
+
"<%= f.check_box(:#{name}, class: '#{@layout_strategy.form_checkbox_input_class}', id: '#{singular}_#{name}', checked: #{singular}.#{name}) %>\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
def switch_display
|
36
|
+
"<%= f.check_box(:#{name}, class: '#{@layout_strategy.form_checkbox_input_class}', role: 'switch', id: '#{singular}_#{name}', checked: #{singular}.#{name}) %>\n"
|
37
|
+
end
|
38
|
+
|
39
|
+
def form_field_display
|
40
|
+
if display_boolean_as.nil?
|
41
|
+
byebug
|
42
|
+
end
|
43
|
+
"<div class='#{@layout_strategy.form_checkbox_wrapper_class} #{'form-switch' if display_boolean_as == 'switch'}'>\n" +
|
44
|
+
(if display_boolean_as == 'radio'
|
45
|
+
radio_button_display
|
46
|
+
elsif display_boolean_as == 'checkbox'
|
47
|
+
checkbox_display
|
48
|
+
elsif display_boolean_as == 'switch'
|
49
|
+
switch_display
|
50
|
+
end) + "</div> \n"
|
51
|
+
end
|
52
|
+
|
20
53
|
def form_field_output
|
21
54
|
(form_labels_position == 'before' ? " <br />" : "") +
|
22
|
-
|
23
|
-
" <%= f.label(:#{name}, value: '#{modify_binary? && modify[:binary][:falsy] || 'No'}', for: '#{singular}_#{name}_0') %>\n" +
|
24
|
-
" <br /> <%= f.radio_button(:#{name}, '1', checked: #{singular}.#{name} ? 'checked' : '') %>\n" +
|
25
|
-
" <%= f.label(:#{name}, value: '#{modify_binary? && modify[:binary][:truthy] || 'Yes'}', for: '#{singular}_#{name}_1') %>\n" +
|
26
|
-
(form_labels_position == 'after' ? " <br />" : "")
|
55
|
+
form_field_display + (form_labels_position == 'after' ? " <br />" : "")
|
27
56
|
end
|
28
57
|
|
29
58
|
def line_field_output
|
@@ -45,4 +74,8 @@ class BooleanField < Field
|
|
45
74
|
<% end %>"
|
46
75
|
end
|
47
76
|
end
|
77
|
+
|
78
|
+
def label_class
|
79
|
+
super + " form-check-label"
|
80
|
+
end
|
48
81
|
end
|
@@ -10,7 +10,7 @@ class DateField < Field
|
|
10
10
|
|
11
11
|
|
12
12
|
def form_field_output
|
13
|
-
"<%= date_field_localized(f, :#{name}, #{singular}.#{name}, '#{ name.to_s.humanize }'
|
13
|
+
"<%= date_field_localized(f, :#{name}, #{singular}.#{name}, '#{ name.to_s.humanize }') %>"
|
14
14
|
end
|
15
15
|
|
16
16
|
def line_field_output
|
@@ -4,21 +4,21 @@ class DateTimeField < Field
|
|
4
4
|
end
|
5
5
|
|
6
6
|
def spec_setup_and_change_act(which_partial = nil)
|
7
|
-
" " + "new_#{name} = DateTime.current +
|
7
|
+
" " + "new_#{name} = DateTime.current + 1.year \n" +
|
8
8
|
' ' + "find(\"[name='#{testing_name}[#{ name.to_s }]']\").fill_in(with: new_#{name.to_s})"
|
9
9
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def spec_make_assertion
|
13
13
|
if !modify_binary?
|
14
|
-
"expect(page).to have_content(new_#{name}.in_time_zone(
|
14
|
+
"expect(page).to have_content(new_#{name}.in_time_zone(testing_timezone).strftime('%m/%d/%Y @ %l:%M %p %Z').gsub(' ', ' '))"
|
15
15
|
else
|
16
16
|
"expect(page).to have_content('#{modify[:binary][:truthy]}'"
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
def spec_setup_let_arg
|
21
|
-
"#{name}: DateTime.current +
|
21
|
+
"#{name}: DateTime.current + 1.day"
|
22
22
|
end
|
23
23
|
|
24
24
|
def spec_list_view_assertion
|
@@ -30,11 +30,11 @@ class DateTimeField < Field
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def spec_list_view_natural_assertion
|
33
|
-
"expect(page).to have_content(#{singular}#{1}.#{name}.in_time_zone(
|
33
|
+
"expect(page).to have_content(#{singular}#{1}.#{name}.in_time_zone(testing_timezone).strftime('%m/%d/%Y @ %l:%M %p %Z').gsub(' ', ' '))"
|
34
34
|
end
|
35
35
|
|
36
36
|
def form_field_output
|
37
|
-
"<%= datetime_field_localized(f, :#{name}, #{singular}.#{name}, '#{ name.to_s.humanize }'
|
37
|
+
"<%= datetime_field_localized(f, :#{name}, #{singular}.#{name}, '#{ name.to_s.humanize }') %>"
|
38
38
|
end
|
39
39
|
|
40
40
|
def line_field_output
|
@@ -42,7 +42,7 @@ class DateTimeField < Field
|
|
42
42
|
modified_display_output
|
43
43
|
else
|
44
44
|
"<% unless #{singular}.#{name}.nil? %>
|
45
|
-
<%= #{singular}.#{name}.in_time_zone(current_timezone).strftime('%m/%d/%Y @ %l:%M %p ')
|
45
|
+
<%= #{singular}.#{name}.in_time_zone(current_timezone).strftime('%m/%d/%Y @ %l:%M %p %Z') %>
|
46
46
|
<% else %>
|
47
47
|
<span class='alert-danger'>MISSING</span>
|
48
48
|
<% end %>"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Field
|
2
2
|
attr_accessor :assoc_model, :assoc_name, :assoc_class, :associations, :alt_lookups, :auth,
|
3
|
-
:assoc_label, :class_name,
|
3
|
+
:assoc_label, :class_name, :default_boolean_display, :display_as, :form_placeholder_labels, :form_labels_position,
|
4
4
|
:hawk_keys, :layout_strategy, :limit, :modify, :name, :object, :sample_file_path,
|
5
5
|
:singular_class, :singular, :sql_type, :ownership_field,
|
6
6
|
:update_show_only
|
@@ -10,6 +10,8 @@ class Field
|
|
10
10
|
alt_lookups: ,
|
11
11
|
attachment_data: nil,
|
12
12
|
class_name: ,
|
13
|
+
default_boolean_display: ,
|
14
|
+
display_as: ,
|
13
15
|
form_labels_position:,
|
14
16
|
form_placeholder_labels: ,
|
15
17
|
hawk_keys: nil,
|
@@ -34,6 +36,9 @@ class Field
|
|
34
36
|
@ownership_field = ownership_field
|
35
37
|
@form_labels_position = form_labels_position
|
36
38
|
@modify = modify
|
39
|
+
@display_as = display_as
|
40
|
+
|
41
|
+
@default_boolean_display = default_boolean_display
|
37
42
|
|
38
43
|
# TODO: remove knowledge of subclasses from Field
|
39
44
|
unless self.class == AttachmentField
|
@@ -132,4 +137,25 @@ class Field
|
|
132
137
|
def modify_binary? # safe
|
133
138
|
!!(modify && modify[:binary])
|
134
139
|
end
|
140
|
+
|
141
|
+
def display_boolean_as
|
142
|
+
|
143
|
+
if ! @default_boolean_display
|
144
|
+
@default_boolean_display = "radio"
|
145
|
+
end
|
146
|
+
|
147
|
+
if display_as
|
148
|
+
return display_as[:boolean] || "radio"
|
149
|
+
else
|
150
|
+
return @default_boolean_display
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def label_class
|
155
|
+
"text-muted small form-text"
|
156
|
+
end
|
157
|
+
|
158
|
+
def label_for
|
159
|
+
|
160
|
+
end
|
135
161
|
end
|
@@ -5,22 +5,30 @@ class TimeField < Field
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def form_field_output
|
8
|
-
"<%= time_field_localized(f, :#{name}, #{singular}.#{name}, '#{ name.to_s.humanize }'
|
8
|
+
"<%= time_field_localized(f, :#{name}, #{singular}.#{name}, '#{ name.to_s.humanize }') %>"
|
9
9
|
end
|
10
10
|
|
11
11
|
def line_field_output
|
12
12
|
"<% unless #{singular}.#{name}.nil? %>
|
13
|
-
<%= #{singular}.#{name}.in_time_zone(current_timezone).strftime('%l:%M %p ')
|
13
|
+
<%= #{singular}.#{name}.in_time_zone(current_timezone).strftime('%l:%M %p ') %>
|
14
14
|
<% else %>
|
15
15
|
<span class='alert-danger'>MISSING</span>
|
16
16
|
<% end %>"
|
17
17
|
end
|
18
18
|
|
19
|
+
def spec_setup_and_change_act(which_partial = nil)
|
20
|
+
" new_#{name} = Time.current + 5.seconds \n" +
|
21
|
+
' ' + "find(\"[name='#{testing_name}[#{ name.to_s }]']\").fill_in(with: new_#{name.to_s})"
|
22
|
+
|
23
|
+
end
|
24
|
+
|
19
25
|
def spec_make_assertion
|
20
|
-
"
|
26
|
+
"expect(page).to have_content(new_#{name}.strftime('%l:%M %p').strip)"
|
21
27
|
end
|
22
28
|
|
23
29
|
def spec_list_view_assertion
|
24
|
-
"
|
30
|
+
# "expect(page).to have_content(#{singular}#{1}.#{name})"
|
25
31
|
end
|
32
|
+
|
33
|
+
|
26
34
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module HotGlue
|
4
4
|
module Layout
|
5
5
|
class Builder
|
6
|
+
include DefaultConfigLoader
|
6
7
|
attr_reader :include_setting,
|
7
8
|
:downnest_object,
|
8
9
|
:buttons_width, :columns,
|
@@ -11,12 +12,13 @@ module HotGlue
|
|
11
12
|
|
12
13
|
def initialize(generator: ,
|
13
14
|
include_setting: ,
|
14
|
-
buttons_width:
|
15
|
+
buttons_width: )
|
15
16
|
|
16
17
|
|
17
18
|
@generator = generator
|
18
19
|
|
19
20
|
@modify = generator.modify
|
21
|
+
@display_as = generator.display_as
|
20
22
|
@columns = generator.columns
|
21
23
|
@smart_layout = generator.smart_layout
|
22
24
|
@stacked_downnesting = generator.stacked_downnesting || false
|
@@ -27,8 +29,11 @@ module HotGlue
|
|
27
29
|
|
28
30
|
@no_buttons = @buttons_width == 0
|
29
31
|
@specified_grouping_mode = include_setting.include?(":")
|
30
|
-
@bootstrap_column_width = generator.bootstrap_column_width
|
32
|
+
@bootstrap_column_width = generator.bootstrap_column_width.to_i
|
31
33
|
@big_edit = generator.big_edit
|
34
|
+
|
35
|
+
@default_boolean_display = get_default_from_config(key: :default_boolean_display)
|
36
|
+
|
32
37
|
end
|
33
38
|
|
34
39
|
def construct
|
@@ -41,7 +46,8 @@ module HotGlue
|
|
41
46
|
|
42
47
|
},
|
43
48
|
buttons: { size: @buttons_width},
|
44
|
-
modify: @modify
|
49
|
+
modify: @modify,
|
50
|
+
display_as: @display_as
|
45
51
|
}
|
46
52
|
|
47
53
|
# downnest_object.each do |child, size|
|
@@ -30,5 +30,8 @@ module LayoutStrategy
|
|
30
30
|
def page_begin; '<div> '; end
|
31
31
|
def page_end ; '</div> '; end
|
32
32
|
def style_with_flex_basis(x); "" ; end
|
33
|
+
def form_checkbox_input_class; ""; end
|
34
|
+
def form_checkbox_label_class; ""; end
|
35
|
+
def form_checkbox_wrapper_class; ""; end
|
33
36
|
end
|
34
37
|
end
|
@@ -56,4 +56,16 @@ class LayoutStrategy::Bootstrap < LayoutStrategy::Base
|
|
56
56
|
def page_end
|
57
57
|
'</div> </div>'
|
58
58
|
end
|
59
|
+
|
60
|
+
def form_checkbox_input_class
|
61
|
+
"form-check-input"
|
62
|
+
end
|
63
|
+
|
64
|
+
def form_checkbox_wrapper_class
|
65
|
+
"form-check"
|
66
|
+
end
|
67
|
+
|
68
|
+
def form_checkbox_label_class
|
69
|
+
"form-check-label"
|
70
|
+
end
|
59
71
|
end
|
@@ -87,7 +87,11 @@ module HotGlue
|
|
87
87
|
|
88
88
|
field_error_name = columns_map[col].field_error_name
|
89
89
|
|
90
|
-
|
90
|
+
|
91
|
+
label_class = columns_map[col].label_class
|
92
|
+
label_for = columns_map[col].label_for
|
93
|
+
|
94
|
+
the_label = "\n<label class='#{label_class}' for='#{label_for}'>#{col.to_s.humanize}</label>"
|
91
95
|
show_only_open = ""
|
92
96
|
show_only_close = ""
|
93
97
|
|
@@ -17,7 +17,8 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
17
17
|
|
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
22
|
:nest_with, :path, :plural, :sample_file_path, :show_only_data, :singular,
|
22
23
|
:singular_class, :smart_layout, :stacked_downnesting, :update_show_only, :ownership_field,
|
23
24
|
:layout_strategy, :form_placeholder_labels, :form_labels_position
|
@@ -79,6 +80,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
79
80
|
class_option :bootstrap_column_width, default: nil # must be nil to detect if user has not passed
|
80
81
|
class_option :button_icons, default: nil
|
81
82
|
class_option :modify, default: {}
|
83
|
+
class_option :display_as, default: {}
|
82
84
|
|
83
85
|
def initialize(*meta_args)
|
84
86
|
super
|
@@ -115,8 +117,12 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
115
117
|
|
116
118
|
@markup = get_default_from_config(key: :markup)
|
117
119
|
@sample_file_path = get_default_from_config(key: :sample_file_path)
|
118
|
-
@bootstrap_column_width ||=
|
120
|
+
@bootstrap_column_width ||= options['bootstrap_column_width'] ||
|
121
|
+
get_default_from_config(key: :bootstrap_column_width) || 2
|
119
122
|
|
123
|
+
|
124
|
+
|
125
|
+
@default_boolean_display = get_default_from_config(key: :default_boolean_display)
|
120
126
|
if options['layout']
|
121
127
|
layout = options['layout']
|
122
128
|
else
|
@@ -154,6 +160,8 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
154
160
|
@controller_build_folder_singular = singular
|
155
161
|
|
156
162
|
@auth = options['auth'] || "current_user"
|
163
|
+
|
164
|
+
@god = options['god'] || options['gd'] || false
|
157
165
|
@auth_identifier = options['auth_identifier'] || (!@god && @auth.gsub("current_", "")) || nil
|
158
166
|
|
159
167
|
if options['nest']
|
@@ -208,6 +216,19 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
208
216
|
end
|
209
217
|
end
|
210
218
|
end
|
219
|
+
|
220
|
+
@display_as = {}
|
221
|
+
if !options['display_as'].empty?
|
222
|
+
display_input = options['display_as'].split(",")
|
223
|
+
|
224
|
+
display_input.each do |setting|
|
225
|
+
setting =~ /(.*){(.*)}/
|
226
|
+
key, lookup_as = $1, $2
|
227
|
+
@display_as[key.to_sym] = {boolean: $2}
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
|
211
232
|
@update_show_only = []
|
212
233
|
if !options['update_show_only'].empty?
|
213
234
|
@update_show_only += options['update_show_only'].split(",").collect(&:to_sym)
|
@@ -256,7 +277,6 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
256
277
|
raise HotGlue::Error, "You passed '#{@inline_list_labels}' as the setting for --inline-list-labels but the only allowed options are before, after, and omit (default)"
|
257
278
|
end
|
258
279
|
|
259
|
-
@god = options['god'] || options['gd'] || false
|
260
280
|
@specs_only = options['specs_only'] || false
|
261
281
|
|
262
282
|
@no_specs = options['no_specs'] || false
|
@@ -292,7 +312,6 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
292
312
|
if @god
|
293
313
|
@auth = nil
|
294
314
|
end
|
295
|
-
|
296
315
|
# when in self auth, the object is the same as the authenticated object
|
297
316
|
|
298
317
|
if @auth && auth_identifier == @singular
|
@@ -645,9 +664,7 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
645
664
|
end
|
646
665
|
end
|
647
666
|
|
648
|
-
|
649
|
-
"authenticate_" + @auth_identifier.split(".")[0] + "!"
|
650
|
-
end
|
667
|
+
|
651
668
|
|
652
669
|
def formats
|
653
670
|
[format]
|
@@ -818,6 +835,14 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
818
835
|
nested_set: @nested_set)
|
819
836
|
end
|
820
837
|
|
838
|
+
def datetime_fields_list
|
839
|
+
@columns.select do |col|
|
840
|
+
if @the_object.columns_hash[col.to_s]
|
841
|
+
@the_object.columns_hash[col.to_s].type == :datetime
|
842
|
+
end
|
843
|
+
end
|
844
|
+
end
|
845
|
+
|
821
846
|
def form_path_new_helper
|
822
847
|
HotGlue.optionalized_ternary(namespace: @namespace,
|
823
848
|
target: @controller_build_folder,
|
@@ -951,6 +976,15 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
|
|
951
976
|
@auth
|
952
977
|
end
|
953
978
|
|
979
|
+
def current_user_object
|
980
|
+
default_current_user = options['auth'] || "current_user"
|
981
|
+
if eval("defined?(#{default_current_user})")
|
982
|
+
default_current_user
|
983
|
+
else
|
984
|
+
"nil"
|
985
|
+
end
|
986
|
+
end
|
987
|
+
|
954
988
|
def no_devise_installed
|
955
989
|
!Gem::Specification.sort_by { |g| [g.name.downcase, g.version] }.group_by { |g| g.name }['devise']
|
956
990
|
end
|
@@ -5,7 +5,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
5
5
|
helper :hot_glue
|
6
6
|
include HotGlue::ControllerHelper
|
7
7
|
|
8
|
-
<% unless @
|
8
|
+
<% unless @god %>before_action :<%= "authenticate_" + @auth_identifier.split(".")[0] + "!" %><% end %><% if any_nested? %>
|
9
9
|
<% nest_chain = [] %> <% @nested_set.each { |arg|
|
10
10
|
|
11
11
|
if auth_identifier == arg[:singular]
|
@@ -86,8 +86,16 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
86
86
|
<% if @alt_lookups.any? %><%= @alt_lookups.collect{|key, data|
|
87
87
|
" #{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"
|
88
88
|
}.join("/n") %><% end %> <% merge_lookups = @alt_lookups.collect{|key, data| "#{key.gsub("_id", "")}: #{key.gsub("_id", "")}" }.join(",") %>
|
89
|
-
modified_params = modify_date_inputs_on_params(<%= singular_name %>_params.dup<%= controller_update_params_tap_away_alt_lookups
|
90
|
-
modified_params =
|
89
|
+
modified_params = modify_date_inputs_on_params(<%= singular_name %>_params.dup<%= controller_update_params_tap_away_alt_lookups %>, <%= current_user_object %>, <%= datetime_fields_list %>) <% if @object_owner_sym && eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %>
|
90
|
+
modified_params = modified_params.merge(<%= @object_owner_sym %>: <%= @object_owner_eval %>) <% elsif @object_owner_optional && any_nested? %>
|
91
|
+
modified_params = modified_params.merge(<%= @object_owner_name %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {}) <% elsif !@object_owner_eval.empty? %>
|
92
|
+
modified_params = modified_params.merge(<%= @object_owner_eval %>) <% end %><% if !merge_lookups.empty? %>
|
93
|
+
modified_params = modified_params.merge(<%= merge_lookups %>)
|
94
|
+
<% end %>
|
95
|
+
|
96
|
+
<% if @hawk_keys.any? %>
|
97
|
+
modified_params = hawk_params({<%= hawk_to_ruby %>}, modified_params)<% end %>
|
98
|
+
<%= controller_attachment_orig_filename_pickup_syntax %>
|
91
99
|
<%= creation_syntax %>
|
92
100
|
|
93
101
|
if @<%= singular_name %>.save
|
@@ -112,7 +120,12 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
112
120
|
}.join("\n") %><% end %> <% merge_lookups = @alt_lookups.filter{|key,d| ! @update_show_only.include?(key.to_sym) }.collect{|key, data| "#{key.gsub("_id", "")}: #{key.gsub("_id", "")}" }.join(",") %>
|
113
121
|
<% @magic_buttons.each { |button| %>@<%= singular_name %>.<%= button %>! if <%= singular_name %>_params[:__<%= button %>]
|
114
122
|
<% } %>
|
115
|
-
modified_params = modify_date_inputs_on_params(<%= singular_name %>_params.dup<% if @object_owner_sym && eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection
|
123
|
+
modified_params = modify_date_inputs_on_params(<%= singular_name %>_params.dup<%= controller_update_params_tap_away_alt_lookups %>, <%= current_user_object %>, <%= datetime_fields_list %>) <% if @object_owner_sym && eval("#{class_name}.reflect_on_association(:#{@object_owner_sym})").class == ActiveRecord::Reflection::BelongsToReflection %>
|
124
|
+
modified_params = modified_params.merge(<%= @object_owner_sym %>: <%= @object_owner_eval %>) <% elsif @object_owner_optional && any_nested? %>
|
125
|
+
modified_params = modified_params.merge(<%= @object_owner_name %> ? {<%= @object_owner_sym %>: <%= @object_owner_eval %>} : {}) <% elsif !@object_owner_eval.empty? %>
|
126
|
+
modified_params = modified_params.merge(<%= @object_owner_eval %>) <% end %><% if !merge_lookups.empty? %>
|
127
|
+
modified_params = modified_params.merge(<%= merge_lookups %>)
|
128
|
+
<% end %>
|
116
129
|
|
117
130
|
<% if @hawk_keys.any? %> modified_params = hawk_params({<%= hawk_to_ruby %>}, modified_params)<% end %>
|
118
131
|
<% if @alt_lookups.any? %><%= @alt_lookups.collect{|key, data|
|
@@ -125,7 +138,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
|
|
125
138
|
}.join("/n") %><% end %><%= controller_attachment_orig_filename_pickup_syntax %>
|
126
139
|
if @<%= singular_name %>.update(modified_params)
|
127
140
|
<% if @display_list_after_update %> load_all_<%= plural %><% end %>
|
128
|
-
flash[:notice] = "#{flash[:notice]} Saved
|
141
|
+
flash[:notice] = "#{flash[:notice]} Saved #{@<%= singular %>.<%= display_class %>}"
|
129
142
|
flash[:alert] = @hawk_alarm if @hawk_alarm
|
130
143
|
render :update
|
131
144
|
else
|
@@ -19,8 +19,8 @@ describe 'interaction for <%= controller_class_name %>' do
|
|
19
19
|
before do
|
20
20
|
login_as(<%= @auth %>)
|
21
21
|
end <% end %> <% if any_datetime_fields? %>
|
22
|
-
let(:
|
23
|
-
|
22
|
+
let(:testing_timezone) {
|
23
|
+
Rails.application.config.time_zone
|
24
24
|
}<% end %>
|
25
25
|
describe "index" do
|
26
26
|
it "should show me the list" do
|
@@ -59,30 +59,14 @@ describe 'interaction for <%= controller_class_name %>' do
|
|
59
59
|
<%= capybara_make_updates(:update) %>
|
60
60
|
click_button "Save"
|
61
61
|
within("turbo-frame#<%= @namespace %>__#{dom_id(<%= singular %>1)} ") do
|
62
|
-
<%=
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
elsif type == :boolean
|
71
|
-
' expect(page).to have_content(new_' + col.to_s + ' ? "YES" : "NO")'
|
72
|
-
|
73
|
-
elsif type == :enum && eval("#{singular_class}.respond_to?(:#{col}_labels)")
|
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))"
|
81
|
-
else
|
82
|
-
" expect(page).to have_content(new_#{col.to_s})"
|
83
|
-
end
|
84
|
-
}.compact.join("\n")
|
85
|
-
%>
|
62
|
+
<%= " " + @columns_map.map{ |col, col_object|
|
63
|
+
if @attachments.keys.collect(&:to_sym).include?(col)
|
64
|
+
elsif @show_only.include?(col)
|
65
|
+
else
|
66
|
+
col_object.spec_make_assertion
|
67
|
+
end
|
68
|
+
}.compact.join("\n ")
|
69
|
+
%>
|
86
70
|
end
|
87
71
|
end
|
88
72
|
end <% end %>
|
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.19.1
|
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-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -61,7 +61,7 @@ extra_rdoc_files: []
|
|
61
61
|
files:
|
62
62
|
- ".circleci/config.yml"
|
63
63
|
- ".github/FUNDING.yml"
|
64
|
-
- ".github/workflows/
|
64
|
+
- ".github/workflows/test_suite.yml"
|
65
65
|
- ".gitignore"
|
66
66
|
- ".ruby-version"
|
67
67
|
- ".travis.yml"
|
data/.github/workflows/test.yml
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
name: Test
|
2
|
-
on: [ push, pull_request ]
|
3
|
-
|
4
|
-
jobs:
|
5
|
-
internal_tests:
|
6
|
-
services:
|
7
|
-
# Label used to access the service container
|
8
|
-
postgres:
|
9
|
-
# Docker Hub image
|
10
|
-
image: postgres
|
11
|
-
# Provide the password for postgres
|
12
|
-
env:
|
13
|
-
POSTGRES_USER: postgres
|
14
|
-
POSTGRES_PASSWORD: postgres
|
15
|
-
POSTGRES_DB: test_database_name
|
16
|
-
ports:
|
17
|
-
- 5432:5432
|
18
|
-
# Set health checks to wait until postgres has started
|
19
|
-
options: >-
|
20
|
-
--health-cmd pg_isready
|
21
|
-
--health-interval 10s
|
22
|
-
--health-timeout 5s
|
23
|
-
--health-retries 5
|
24
|
-
runs-on: ubuntu-latest
|
25
|
-
steps:
|
26
|
-
- uses: actions/checkout@v3
|
27
|
-
- name: Set up Ruby
|
28
|
-
uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0
|
29
|
-
with:
|
30
|
-
# Not needed with a .ruby-version file
|
31
|
-
# runs 'bundle install' and caches installed gems automatically
|
32
|
-
bundler-cache: true
|
33
|
-
- name: bundle install
|
34
|
-
run: cd dummy && bundle install && cd ..
|
35
|
-
|
36
|
-
- name: run tests
|
37
|
-
env:
|
38
|
-
RUBYOPT: "-W:no-deprecated -W:no-experimental" # Suppress Rails 6 deprecation warnings for ruby 2.7
|
39
|
-
RAILS_ENV: "test"
|
40
|
-
DATABASE_URL: "postgres://postgres:postgres@localhost:5432/test_database_name"
|
41
|
-
|
42
|
-
run: |
|
43
|
-
cd dummy && bin/setup && cd ..
|
44
|
-
bundle install
|
45
|
-
bundle exec rspec --fail-fast --backtrace
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|