hot-glue 0.5.4 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4770a6dafa96c7d17e2104d7349caf126a7922c660b3055b29c6a7eab6e7d851
4
- data.tar.gz: cd730bb99e9d9dad8ca5ee22a504a9e91ace01123ce900e11c7ccffae3e26630
3
+ metadata.gz: 61b8c21f0bf630a68d9861b8bb70141ce7fe0da0a0f1ae71c3bb4e69da6b081d
4
+ data.tar.gz: 865d633fe279b4db0b2927801c82ec6de1ab630b4ffb7d24ffc539dfbb56d44d
5
5
  SHA512:
6
- metadata.gz: 5f59544515a51f85e494bd7a1ec7ee4586ab761919554f53ad751b845906e412a5cd80f65e1447183d79246e295abbb1fe468814ef572cd93888970603aafb7a
7
- data.tar.gz: 045115777e9399ddffd06f9b400d44cc1d5e230579ea9d2017213cf74ae786efe2ae42d52639dbc60b496d0628f8a955c0d03807cd7262203de1961e0ecf87c8
6
+ metadata.gz: 26901af291d1db0f028b14e320ed6c66908c90d94777c559bdba508c4e111b651357531f9fffc468cc419fbe16dda1d9bb6b86777c6e8f840631c4dfb7239e3d
7
+ data.tar.gz: 69775a6b4a31b142e1683c2017d2b85c1fda1f7350bb4b954948a0b06bfbb990578bed98c0eedce1534e10ad78aa44b87d27deecf027f017184aa731319c62cb
data/.gitignore CHANGED
@@ -16,11 +16,18 @@ Gemfile.lock
16
16
 
17
17
  db/*.sqlite3
18
18
 
19
- spec/dummy/app/views/
20
- spec/dummy/app/controllers/
21
- spec/dummy/specs/
19
+ dummy/app/views/
20
+ dummy/app/controllers/
21
+ dummy/specs/
22
+
23
+ dummy/node_modules/
24
+ dummy/log/
25
+ dummy/Gemfile.lock
26
+ dummy/config/hot_glue.yml
22
27
 
23
- spec/dummy/node_modules/
24
- spec/dummy/log/
25
28
 
26
29
  coverage/
30
+
31
+
32
+ spec/dummy/
33
+ dummy/spec/system/
data/README.md CHANGED
@@ -29,10 +29,10 @@ How is it different than Rails scaffolding?
29
29
 
30
30
  Although inspired by the Rails scaffold generators (built-in to Rails), Hot Glue does something similiar but has made opinionated decisions that deviate from the normal Rails scaffold:
31
31
 
32
- 1. The Hot Glue scaffolds are complete packages and pre-optimized for 'edit-in-place.' (the Rails scaffolds still generate views that make you flip between pages to do create/update operations)
33
- 2. Hot Glue does not create your models along with your scaffolding. Instead, create them first using `rails model new`
34
- 3. Hot Glue *reads* the fields on your database and the relationships defined on your models, so unlike the Rails scaffolding you must do that step before building your scaffolding.
35
- 4. Hot Glue has many more features for building layouts quickly, like choosing which fields to include or exclude and how to lay them out on the page, for stiching together related objects (nesting and child portals), and more.
32
+ 1. The Hot Glue scaffolds are complete packages and pre-optimized for 'edit-in-place.' (the Rails scaffolds still generates views that make you flip between pages to do create/update operations)
33
+ 2. Hot Glue does not create your models along with your scaffolding. Instead, create them first using `rails generate model X`
34
+ 3. Hot Glue *reads* the fields on your database *and* the relationships defined on your models. Unlike the Rails scaffolding you must add relationships and migration your DB before building your scaffolding.
35
+ 4. Hot Glue has many more features for building layouts quickly, like choosing which fields to include or exclude and how to lay them out on the page, for stitching together related objects (nesting and child portals), and more.
36
36
 
37
37
  Other than the opinionated differences and additional features, Hot Glue produces code that is fundamentally very similiar and works consistent with the Rails 7 ways of working.
38
38
 
@@ -138,7 +138,7 @@ sed -i '' -e 's/, html: { method: :post })/, html: { method: :post, "data-turbo"
138
138
  git add . && git commit -m 'devise view fixes' &&
139
139
  rails generate model User name:string &&
140
140
  rails generate devise User && git add . && git commit -m "adds Users model with devise" &&
141
- rails db:migrate &&
141
+ && ./bin/setup && rails db:migrate &&
142
142
  git add . && git commit -m "schema file"
143
143
  ```
144
144
 
@@ -568,17 +568,25 @@ Please note that this example would produce non-functional code, so you would ne
568
568
 
569
569
  Hawk a foreign key that is not the object's owner to within a specified scope.
570
570
 
571
- Assuming a Pet belong_to a :human, when building an Appointments scaffold, you can hawk the `pet_id` to the current human's pets. (Whoever is the authentication object.)
571
+ Assuming a Pet belong_to a :human, when building an Appointments scaffold,
572
+ you can hawk the `pet_id` to the current human's pets. (Whoever is the authentication object.)
572
573
 
574
+ The hawk has two forms: a short-form (`--hawk=key`) and long form (`--hawk=key{scope})
575
+
576
+ The short form looks like this. It presumes there is a 'pets' association from `current_user`
573
577
  `--hawk=pet_id`
574
578
 
579
+ (The long form equivalent of this would be `--hawk=pet_id{current_user.pets}`)
580
+
575
581
  This is covered in [Example #3 in the Hot Glue Tutorial](https://jfb.teachable.com/courses/hot-glue-in-depth-tutorial/lectures/38584014)
576
582
 
577
- To hawk to a scope that is not the currently authenticated user, use curly braces `{...}` to specify the scope.
583
+ To hawk to a scope that is not the currently authenticated user, use the long form with `{...}`
584
+ to specify the scope. Be sure to note to add the association name itself, like `users`:
578
585
 
579
- `--hawk=user_id{current_user.family}`
586
+ `--hawk=user_id{current_user.family.users}`
580
587
 
581
- This would hawk the Appointment's `user_id` key to any users who are within the scope of the current_user's family.
588
+ This would hawk the Appointment's `user_id` key to any users who are within the scope of the
589
+ current_user's has_many association (so, for any other "my" family, would be `current_user.family.users`).
582
590
 
583
591
  This is covered in [Example #4 in the Hot Glue Tutorial](https://jfb.teachable.com/courses/hot-glue-in-depth-tutorial/lectures/38787505)
584
592
 
@@ -905,6 +913,39 @@ Child portals have the headings omitted automatically (there is a heading identi
905
913
 
906
914
  # VERSION HISTORY
907
915
 
916
+ #### 2023-01-02 - v0.5.6
917
+ - Changes the long-form of the hawk specifier to require you to use the has_many of the relationship you are hawking (previously, it was assumed). See Hawk for details
918
+ - Adds "Regenerate me" comment to top of all generated controllers
919
+ - Change behavior of pluralization. Now, you can use an `inflections.rb` file and non-standard pluralization will be respected.
920
+
921
+
922
+ #### 2022-12-27 - v0.5.5
923
+
924
+ - Experimental support for Tailwind. Note I was not able to get Tailwind actually working in my app, and I'm not sure about how to think about the many flavors of Tailwind (all of which seem to be paid?). If anyone can lend a hand, the objects are now cleanly refactored so that the CSS logic is separated.
925
+
926
+ - Support for UUIDs. Database UUIDs are treated as foreign keys and behave like integers ending with _id (they are treated as foreign keys whether or not they end with _id where as integers are treated as foreign keys only if they end with _id)
927
+
928
+ - At the namespace level, you can now have a file called `_nav.html.erb` like this example for a two-tab bootstrap nav (you'll need to create this file manually).
929
+ - Here, our two tabs are called "Domains" and "Widgets"
930
+
931
+ ```
932
+ <ul class="nav nav-tabs">
933
+ <li class="nav-item">
934
+ <%= link_to "Domains", domains_path, class: "nav-link #{'active' if nav == 'domains'}" %>
935
+ </li>
936
+ <li class="nav-item">
937
+ <%= link_to "Widgets", widgets_path, class: "nav-link #{'active' if nav == 'widget'}" %>
938
+ </li>
939
+ </ul>
940
+ ```
941
+
942
+ If the file is present, Hot Glue will automatically add this to the top of, for example, the "domains" index page:
943
+
944
+ ```
945
+ <%= render partial: "owner/nav", locals: {nav: "domains"} %>
946
+ ```
947
+ Use this to build a Bootstrap nav that correctly turns each tab active when navigated to.
948
+
908
949
  #### 2022-11-27 - v0.5.4 - new flag --with-turbo-streams will append callbacks after_update_commit and after_destroy_commit to the MODEL you are building with to use turbo to target the scaffolding being built and programmatically update it
909
950
 
910
951
  Adds `--with-turbo-streams`. Use `--with-turbo-streams` to create hot (live reload) interfaces. See docs above.
@@ -78,9 +78,9 @@ module HotGlue
78
78
  @hawk_alarm = ""
79
79
  hawk_schema.each do |hawk_key,hawk_definition|
80
80
  hawk_root = hawk_definition[0]
81
- hawk_scope = hawk_definition[1]
81
+ # hawk_scope = hawk_definition[1]
82
82
  begin
83
- eval("hawk_root.#{hawk_scope}").find(modified_params[hawk_key.to_s])
83
+ eval("hawk_root").find(modified_params[hawk_key.to_s])
84
84
  rescue ActiveRecord::RecordNotFound => e
85
85
  @hawk_alarm << "You aren't allowed to set #{hawk_key.to_s} to #{modified_params[hawk_key.to_s]}. "
86
86
  modified_params.tap { |hs| hs.delete(hawk_key.to_s) }
@@ -1,5 +1,5 @@
1
1
  require 'rails/generators/erb/scaffold/scaffold_generator'
2
- require_relative './helpers'
2
+
3
3
  require 'ffaker'
4
4
 
5
5
  module HotGlue
@@ -15,15 +15,15 @@ module HotGlue
15
15
 
16
16
  def initialize(*args) #:nodoc:
17
17
  super
18
- @layout = options['layout'] || "hotglue"
18
+ layout = options['layout'] || "hotglue"
19
19
  @theme = options['theme']
20
- if @layout == "hotglue" && options['theme'].nil?
20
+ if layout == "hotglue" && options['theme'].nil?
21
21
  puts "You have selected to install Hot Glue without a theme. You can either use the --layout=bootstrap to install NO HOT GLUE THEME, or to use a Hot Glue theme please choose: like_boostrap, like_menlo_park, like_cupertino, like_mountain_view, dark_knight"
22
22
  return
23
23
  end
24
24
 
25
- if @layout == 'boostrap'
26
- puts "IMPORTANT: You have selected to install Hot Glue with Bootstrap layout (legacy). Be sure to always use ``--layout=bootstrap` when building your scaffold. No Hot Glue theme will be installed at this time.` "
25
+ if layout == 'boostrap'
26
+ puts "IMPORTANT: You have selected to install Hot Glue with Bootstrap layout.` "
27
27
  end
28
28
 
29
29
 
@@ -56,7 +56,7 @@ module HotGlue
56
56
 
57
57
 
58
58
  begin
59
- rails_helper_contents = File.read("spec/rails_helper.rb")
59
+ rails_helper_contents = File.read("#{'spec/dummy/' if Rails.env.test?}spec/rails_helper.rb")
60
60
  if !rails_helper_contents.include?("Capybara.default_driver =")
61
61
  rails_helper_contents << "\nCapybara.default_driver = :selenium_chrome_headless "
62
62
  puts " HOTGLUE --> added to spec/rails_helper.rb: `Capybara.default_driver = :selenium_chrome_headless` "
@@ -66,14 +66,14 @@ module HotGlue
66
66
  rails_helper_contents.gsub!("RSpec.configure do |config|", "RSpec.configure do |config| \n
67
67
  config.include FactoryBot::Syntax::Methods
68
68
  ")
69
- puts " HOTGLUE --> added to spec/rails_helper.rb: `config.include FactoryBot::Syntax::Methods` "
69
+ puts " HOTGLUE --> added to #{'spec/dummy/' if Rails.env.test?}spec/rails_helper.rb: `config.include FactoryBot::Syntax::Methods` "
70
70
  end
71
71
 
72
72
  if ! rails_helper_contents.include?("require 'support/capybara_login.rb'")
73
73
  rails_helper_contents.gsub!("require 'rspec/rails'","require 'rspec/rails' \nrequire 'support/capybara_login.rb'")
74
74
  puts " HOTGLUE --> added to spec/rails_helper.rb: `require 'support/capybara_login.rb'` "
75
75
  end
76
- File.write("spec/rails_helper.rb", rails_helper_contents)
76
+ File.write("#{'spec/dummy/' if Rails.env.test?}spec/rails_helper.rb", rails_helper_contents)
77
77
 
78
78
  rescue StandardError => e
79
79
  puts "WARNING: error writing to spec/rails_helper --- #{e.message}"
@@ -96,7 +96,7 @@ module HotGlue
96
96
 
97
97
 
98
98
  begin
99
- if @layout == "hotglue"
99
+ if layout == "hotglue"
100
100
  theme_location = "themes/hotglue_scaffold_#{@theme}.scss"
101
101
  theme_file = "hotglue_scaffold_#{@theme}.scss"
102
102
 
@@ -119,8 +119,8 @@ module HotGlue
119
119
 
120
120
 
121
121
  begin
122
- if !File.exists?("config/hot_glue.yml")
123
- yaml = {layout: @layout,
122
+ if !File.exists?("#{'spec/dummy/' if Rails.env.test?}config/hot_glue.yml")
123
+ yaml = {layout: layout,
124
124
  markup: @markup}.to_yaml
125
125
  File.write("#{'spec/dummy/' if Rails.env.test?}config/hot_glue.yml", yaml)
126
126
 
@@ -131,11 +131,11 @@ module HotGlue
131
131
 
132
132
 
133
133
  begin
134
- if !File.exists?("spec/support/capybara_login.rb")
134
+ if !File.exists?("#{'spec/dummy/' if Rails.env.test?}spec/support/capybara_login.rb")
135
135
  copy_file "capybara_login.rb", "#{'spec/dummy/' if Rails.env.test?}spec/support/capybara_login.rb"
136
136
  end
137
137
  rescue StandardError => e
138
- puts "WARNING: error writing to spec/support/capybara_login.rb --- #{e.message}"
138
+ puts "WARNING: error writing to #{Rails.env.test? ? 'spec/dummmy/' : ''}spec/support/capybara_login.rb --- #{e.message}"
139
139
  end
140
140
  end
141
141
  end
@@ -8,15 +8,18 @@ module HotGlue
8
8
  :buttons_width, :columns,
9
9
  :smart_layout, :specified_grouping_mode
10
10
 
11
- def initialize(params)
12
- @include_setting = params[:include_setting]
13
- @downnest_object = params[:downnest_object]
14
-
15
- @buttons_width = params[:buttons_width]
11
+ def initialize(include_setting: nil,
12
+ downnest_object: nil,
13
+ buttons_width: nil,
14
+ smart_layout: nil,
15
+ columns: nil)
16
+ @include_setting = include_setting
17
+ @downnest_object = downnest_object
18
+ @buttons_width = buttons_width
19
+ @columns = columns
20
+ @smart_layout = smart_layout
16
21
 
17
22
  @no_buttons = @buttons_width == 0
18
- @columns = params[:columns]
19
- @smart_layout = params[:smart_layout]
20
23
  @specified_grouping_mode = include_setting.include?(":")
21
24
  end
22
25
 
@@ -132,4 +135,4 @@ module HotGlue
132
135
 
133
136
  end
134
137
  end
135
- end
138
+ end
@@ -0,0 +1,31 @@
1
+ module LayoutStrategy
2
+ class Base
3
+ attr_accessor :builder
4
+ def initialize(scaffold_builder)
5
+ @builder = scaffold_builder
6
+ end
7
+
8
+ def button_classes; ""; end
9
+ def button_column_style; "" ; end
10
+ def button_style ; ""; end
11
+ def column_headings_col_style; "" ; end
12
+ def column_width; ""; end
13
+ def column_classes_for_line_fields; ""; end
14
+ def column_classes_for_form_fields; ""; end
15
+ def column_classes_for_column_headings; ""; end
16
+ def col_width; 100; end
17
+ def container_name; ""; end
18
+ def downnest_style ; ""; end
19
+ def downnest_column_style ; "" ; end
20
+ def each_col
21
+ return col_width if builder.columns.count == 0
22
+ (col_width/(builder.columns.count)).to_i
23
+ end
24
+ def list_classes; ""; end
25
+ def row_classes; ""; end
26
+ def row_heading_classes; ""; end
27
+ def page_begin; '<div> '; end
28
+ def page_end ; '</div> '; end
29
+ def style_with_flex_basis(x); "" ; end
30
+ end
31
+ end
@@ -0,0 +1,41 @@
1
+ class LayoutStrategy::Bootstrap < LayoutStrategy::Base
2
+ def button_classes
3
+ " " + column_classes_for_line_fields
4
+ end
5
+
6
+ def column_classes_for_form_fields
7
+ "col-md-#{builder.layout_object[:columns][:size_each]}"
8
+ end
9
+
10
+ def column_classes_for_column_headings
11
+ column_classes_for_line_fields
12
+ end
13
+
14
+ def container_name
15
+ "container-fluid"
16
+ end
17
+
18
+ def column_classes_for_line_fields
19
+ "col-sm-#{builder.layout_object[:columns][:size_each]}"
20
+ end
21
+
22
+ def column_width
23
+ builder.layout_object[:columns][:size_each]
24
+ end
25
+
26
+ def downnest_portal_column_width(downnest)
27
+ "col-sm-#{ builder.layout_object[:portals][downnest][:size] }"
28
+ end
29
+
30
+ def page_begin
31
+ '<div class="row"> <div class="col-md-12">'
32
+ end
33
+
34
+ def row_classes
35
+ "row"
36
+ end
37
+
38
+ def page_end
39
+ '</div> </div>'
40
+ end
41
+ end
@@ -0,0 +1,82 @@
1
+ class LayoutStrategy::HotGlue < LayoutStrategy::Base
2
+ def button_column_style
3
+ 'style="flex-basis: 150px'
4
+ end
5
+
6
+ def button_style
7
+ 'style="flex-basis: ' + (100 - (column_width * builder.columns.count)).floor.to_s + '%;"'
8
+ end
9
+
10
+ def column_width
11
+ each_col * builder.columns.count
12
+ end
13
+
14
+ def column_headings_col_style
15
+ " style='flex-basis: #{column_width}%'"
16
+ end
17
+
18
+ def container_name
19
+ "scaffold-container"
20
+ end
21
+
22
+ def downnest_column_style
23
+ 'style="flex-basis: ' + each_downnest_width.to_s + '%;'
24
+ end
25
+
26
+ def downnest_style
27
+ 'style="flex-basis: ' + each_downnest_width.to_s + '%"'
28
+ end
29
+
30
+ def each_downnest_width
31
+ builder.downnest_children.count == 1 ? 33 : (53/builder.downnest_children.count).floor
32
+ end
33
+
34
+ def list_classes
35
+ "scaffold-list"
36
+ end
37
+
38
+ def row_classes
39
+ "scaffold-row"
40
+ end
41
+
42
+ def column_classes_for_form_fields
43
+ "scaffold-cell"
44
+ end
45
+
46
+ def row_heading_classes
47
+ "scaffold-heading-row"
48
+ end
49
+ def column_classes_for_line_fields
50
+ "scaffold-cell"
51
+ end
52
+
53
+ def column_classes_for_column_headings
54
+ "scaffold-cell"
55
+ end
56
+
57
+ def col_width
58
+ downnest_size = case (builder.downnest_children.count)
59
+ when 0
60
+ downnest_size = 0
61
+ when 1
62
+ downnest_size = 40
63
+
64
+ else
65
+ downnest_size = 60
66
+
67
+ end
68
+ 100 - downnest_size - 5
69
+ end
70
+
71
+ def page_begin
72
+ '<div class=" scaffold-index-<%= plural %>">'
73
+ end
74
+
75
+ def page_end
76
+ '</div>'
77
+ end
78
+
79
+ def style_with_flex_basis(perc_width)
80
+ " style='flex-basis: #{perc_width}%'"
81
+ end
82
+ end
@@ -0,0 +1,28 @@
1
+
2
+
3
+ class LayoutStrategy::Tailwind < LayoutStrategy::Base
4
+ def button_classes; ""; end
5
+ def button_column_style; "" ; end
6
+ def button_style ; ""; end
7
+ def column_headings_col_style; "" ; end
8
+ def column_width; ""; end
9
+ def column_classes_for_line_fields; ""; end
10
+ def column_classes_for_form_fields; ""; end
11
+ def column_classes_for_column_headings; ""; end
12
+ def col_width; 100; end
13
+ def container_name; ""; end
14
+ def downnest_style ; ""; end
15
+ def downnest_column_style ; "" ; end
16
+ def each_col
17
+ return col_width if builder.columns.count == 0
18
+ (col_width/(builder.columns.count)).to_i
19
+ end
20
+
21
+ def list_classes; "overflow-x-auto w-full"; end
22
+ def row_classes; "grid grid-cols-4 gap-x-16 py-5 px-4 text-sm text-gray-700 border-b border-gray-200 dark:border-gray-700"; end
23
+ def row_heading_classes; "grid grid-cols-4 gap-x-16 p-4 text-sm font-medium text-gray-900 bg-gray-100 border-t border-b border-gray-200 dark:bg-gray-800 dark:border-gray-700 dark:text-white"; end
24
+ def page_begin; '<div class="overflow-hidden min-w-max"> '; end
25
+ def page_end ; '</div> '; end
26
+ def style_with_flex_basis(x); "" ; end
27
+
28
+ end
@@ -1,7 +1,7 @@
1
1
  module HotGlue
2
2
  class TemplateBase
3
- def initialize()
3
+ def initialize(layout_strategy: )
4
+ @layout_strategy = layout_strategy
4
5
  end
5
-
6
6
  end
7
- end
7
+ end