b4um_generators 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +28 -0
  4. data/CHANGELOG.md +5 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.de.md +821 -0
  7. data/README.md +815 -0
  8. data/Rakefile +12 -0
  9. data/b4um_generators.gemspec +30 -0
  10. data/bin/console +11 -0
  11. data/bin/setup +8 -0
  12. data/lib/b4um_generators/version.rb +5 -0
  13. data/lib/b4um_generators.rb +8 -0
  14. data/lib/generators/b4um/bento/bento_generator.rb +81 -0
  15. data/lib/generators/b4um/bento/templates/_alternating.html.erb.tt +15 -0
  16. data/lib/generators/b4um/bento/templates/_bento.html.erb.tt +26 -0
  17. data/lib/generators/b4um/bento/templates/_grid.html.erb.tt +13 -0
  18. data/lib/generators/b4um/bento/templates/_list.html.erb.tt +15 -0
  19. data/lib/generators/b4um/comments/comments_generator.rb +259 -0
  20. data/lib/generators/b4um/comments/templates/_comments.html.erb.tt +63 -0
  21. data/lib/generators/b4um/comments/templates/comment.rb.tt +5 -0
  22. data/lib/generators/b4um/comments/templates/comments_controller.rb.tt +45 -0
  23. data/lib/generators/b4um/comments/templates/create_comments.rb.tt +14 -0
  24. data/lib/generators/b4um/controller/controller_generator.rb +397 -0
  25. data/lib/generators/b4um/help/help_generator.rb +755 -0
  26. data/lib/generators/b4um/infinite_scroll/infinite_scroll_generator.rb +199 -0
  27. data/lib/generators/b4um/infinite_scroll/templates/infinite_scroll_controller.js +61 -0
  28. data/lib/generators/b4um/install/install_generator.rb +492 -0
  29. data/lib/generators/b4um/install/templates/_cookie_consent.html.erb +27 -0
  30. data/lib/generators/b4um/install/templates/_footer.html.erb +17 -0
  31. data/lib/generators/b4um/install/templates/_hero.html.erb +33 -0
  32. data/lib/generators/b4um/install/templates/_navigation.html.erb +31 -0
  33. data/lib/generators/b4um/install/templates/_sitemap.html.erb +48 -0
  34. data/lib/generators/b4um/install/templates/_theme_switcher.html.erb +57 -0
  35. data/lib/generators/b4um/install/templates/b4um/badges.css +43 -0
  36. data/lib/generators/b4um/install/templates/b4um/base.css +42 -0
  37. data/lib/generators/b4um/install/templates/b4um/callouts.css +58 -0
  38. data/lib/generators/b4um/install/templates/b4um/cards.css +401 -0
  39. data/lib/generators/b4um/install/templates/b4um/comments.css +52 -0
  40. data/lib/generators/b4um/install/templates/b4um/cookie-consent.css +83 -0
  41. data/lib/generators/b4um/install/templates/b4um/empty-state.css +26 -0
  42. data/lib/generators/b4um/install/templates/b4um/flash.css +86 -0
  43. data/lib/generators/b4um/install/templates/b4um/footer.css +338 -0
  44. data/lib/generators/b4um/install/templates/b4um/forms.css +924 -0
  45. data/lib/generators/b4um/install/templates/b4um/hero.css +149 -0
  46. data/lib/generators/b4um/install/templates/b4um/layout.css +166 -0
  47. data/lib/generators/b4um/install/templates/b4um/lightbox.css +268 -0
  48. data/lib/generators/b4um/install/templates/b4um/navigation.css +257 -0
  49. data/lib/generators/b4um/install/templates/b4um/pagination.css +85 -0
  50. data/lib/generators/b4um/install/templates/b4um/resources.css +121 -0
  51. data/lib/generators/b4um/install/templates/b4um/search.css +41 -0
  52. data/lib/generators/b4um/install/templates/b4um/tables.css +67 -0
  53. data/lib/generators/b4um/install/templates/b4um/theme-switcher.css +178 -0
  54. data/lib/generators/b4um/install/templates/b4um/theme.css +132 -0
  55. data/lib/generators/b4um/install/templates/b4um.css +20 -0
  56. data/lib/generators/b4um/install/templates/b4um.yml +12 -0
  57. data/lib/generators/b4um/install/templates/b4um_helper.rb +27 -0
  58. data/lib/generators/b4um/install/templates/cookie_consent_controller.js +76 -0
  59. data/lib/generators/b4um/install/templates/dismissible_controller.js +7 -0
  60. data/lib/generators/b4um/install/templates/image_lightbox_controller.js +414 -0
  61. data/lib/generators/b4um/install/templates/image_preview_controller.js +85 -0
  62. data/lib/generators/b4um/install/templates/navigation_controller.js +25 -0
  63. data/lib/generators/b4um/install/templates/navigation_helper.rb +26 -0
  64. data/lib/generators/b4um/install/templates/sitemap_controller.js +35 -0
  65. data/lib/generators/b4um/install/templates/theme_controller.js +122 -0
  66. data/lib/generators/b4um/pagination/pagination_generator.rb +179 -0
  67. data/lib/generators/b4um/pagination/templates/_pagination.html.erb.tt +48 -0
  68. data/lib/generators/b4um/pagination/templates/pagination.rb +36 -0
  69. data/lib/generators/b4um/scaffold/scaffold_generator.rb +333 -0
  70. data/lib/generators/b4um/scaffold/templates/_bento.html.erb.tt +26 -0
  71. data/lib/generators/b4um/scaffold/templates/_form.html.erb.tt +218 -0
  72. data/lib/generators/b4um/scaffold/templates/_resource.html.erb.tt +144 -0
  73. data/lib/generators/b4um/scaffold/templates/_table.html.erb.tt +40 -0
  74. data/lib/generators/b4um/scaffold/templates/edit.html.erb.tt +21 -0
  75. data/lib/generators/b4um/scaffold/templates/index.html.erb.tt +24 -0
  76. data/lib/generators/b4um/scaffold/templates/new.html.erb.tt +17 -0
  77. data/lib/generators/b4um/scaffold/templates/show.html.erb.tt +31 -0
  78. data/lib/generators/b4um/search/search_generator.rb +165 -0
  79. data/lib/generators/b4um/search/templates/search.rb +34 -0
  80. data/lib/generators/b4um/search/templates/search_form.html.erb.tt +15 -0
  81. data/lib/generators/b4um/table/table_generator.rb +63 -0
  82. data/lib/generators/b4um/table/templates/_table.html.erb.tt +40 -0
  83. data/lib/generators/b4um/trix/templates/b4um_rich_text_helper.rb +58 -0
  84. data/lib/generators/b4um/trix/templates/b4um_trix.js +551 -0
  85. data/lib/generators/b4um/trix/trix_generator.rb +383 -0
  86. data/sig/b4um_generators.rbs +4 -0
  87. metadata +148 -0
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+
5
+ module B4um
6
+ module Generators
7
+ class InfiniteScrollGenerator < Rails::Generators::NamedBase
8
+ source_root File.expand_path(
9
+ "../pagination/templates",
10
+ __dir__
11
+ )
12
+
13
+ class_option :per_page,
14
+ type: :numeric,
15
+ default: 20,
16
+ desc: "Number of records loaded per page"
17
+
18
+ class << self
19
+ def desc(_description = nil)
20
+ "Adds B4UM infinite scroll to an existing resource."
21
+ end
22
+ end
23
+
24
+ def validate_per_page
25
+ return if options[:per_page].positive?
26
+
27
+ raise Thor::Error, "--per-page must be greater than 0"
28
+ end
29
+
30
+ def validate_model
31
+ return if File.exist?(File.join(destination_root, model_path))
32
+
33
+ raise Thor::Error, "Model not found: #{model_path}"
34
+ end
35
+
36
+ def validate_controller
37
+ return if File.exist?(
38
+ File.join(destination_root, controller_path)
39
+ )
40
+
41
+ raise Thor::Error, "Controller not found: #{controller_path}"
42
+ end
43
+
44
+ def validate_index_view
45
+ return if File.exist?(
46
+ File.join(destination_root, index_view_path)
47
+ )
48
+
49
+ raise Thor::Error, "Index view not found: #{index_view_path}"
50
+ end
51
+
52
+ def create_pagination_concern
53
+ template(
54
+ "pagination.rb",
55
+ "app/controllers/concerns/b4um_pagination.rb"
56
+ )
57
+ end
58
+
59
+ def create_infinite_scroll_controller
60
+ copy_file(
61
+ File.expand_path(
62
+ "templates/infinite_scroll_controller.js",
63
+ __dir__
64
+ ),
65
+ "app/javascript/controllers/infinite_scroll_controller.js"
66
+ )
67
+ end
68
+
69
+ def update_controller
70
+ controller_content = File.read(
71
+ File.join(destination_root, controller_path)
72
+ )
73
+
74
+ unless controller_content.include?("include B4umPagination")
75
+ inject_into_class(
76
+ controller_path,
77
+ "#{class_name.pluralize}Controller",
78
+ " include B4umPagination\n\n"
79
+ )
80
+
81
+ controller_content = File.read(
82
+ File.join(destination_root, controller_path)
83
+ )
84
+ end
85
+
86
+ return if controller_content.include?(paginated_collection)
87
+
88
+ if controller_content.match?(search_pattern)
89
+ paginate_existing_search
90
+ return
91
+ end
92
+
93
+ paginate_plain_collection(controller_content)
94
+ end
95
+
96
+ def update_index_view
97
+ gsub_file(
98
+ index_view_path,
99
+ %r{\n*<%=\s*render\s+"shared/pagination",\s*pagination:\s*@pagination\s*%>\n*},
100
+ "\n"
101
+ )
102
+
103
+ index_content = File.read(
104
+ File.join(destination_root, index_view_path)
105
+ )
106
+
107
+ return if index_content.include?(
108
+ 'data-controller="infinite-scroll"'
109
+ )
110
+
111
+ append_to_file(
112
+ index_view_path,
113
+ <<~ERB
114
+
115
+ <div
116
+ data-controller="infinite-scroll"
117
+ data-infinite-scroll-container-value="#{plural_table_name}"
118
+ data-infinite-scroll-next-url-value="<%= url_for(request.query_parameters.merge(page: @pagination.next_page)) if @pagination.next_page %>"
119
+ ></div>
120
+ ERB
121
+ )
122
+ end
123
+
124
+ private
125
+
126
+ def paginated_collection
127
+ "@#{plural_table_name}, @pagination = b4um_paginate("
128
+ end
129
+
130
+ def search_pattern
131
+ /
132
+ @#{Regexp.escape(plural_table_name)}\s*=\s*
133
+ b4um_search\(\s*
134
+ #{Regexp.escape(class_name)}\.all,\s*
135
+ params\[:q\]\s*
136
+ \)
137
+ /x
138
+ end
139
+
140
+ def paginate_existing_search
141
+ gsub_file(
142
+ controller_path,
143
+ search_pattern,
144
+ [
145
+ "@#{plural_table_name}, @pagination = b4um_paginate(",
146
+ " b4um_search(",
147
+ " #{class_name}.all,",
148
+ " params[:q]",
149
+ " ),",
150
+ " per_page: #{options[:per_page]}",
151
+ " )"
152
+ ].join("\n")
153
+ )
154
+ end
155
+
156
+ def paginate_plain_collection(controller_content)
157
+ old_index = "@#{plural_table_name} = #{class_name}.all"
158
+
159
+ unless controller_content.include?(old_index)
160
+ raise Thor::Error,
161
+ "Could not find the index collection in app/controllers/#{plural_table_name}_controller.rb"
162
+ end
163
+
164
+ gsub_file(
165
+ controller_path,
166
+ old_index,
167
+ [
168
+ "@#{plural_table_name}, @pagination = b4um_paginate(",
169
+ " #{class_name}.all,",
170
+ " per_page: #{options[:per_page]}",
171
+ " )"
172
+ ].join("\n")
173
+ )
174
+ end
175
+
176
+ def model_path
177
+ File.join(
178
+ "app/models",
179
+ "#{file_name}.rb"
180
+ )
181
+ end
182
+
183
+ def controller_path
184
+ File.join(
185
+ "app/controllers",
186
+ "#{file_name.pluralize}_controller.rb"
187
+ )
188
+ end
189
+
190
+ def index_view_path
191
+ File.join(
192
+ "app/views",
193
+ file_name.pluralize,
194
+ "index.html.erb"
195
+ )
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,61 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+
3
+ export default class extends Controller {
4
+ static values = {
5
+ nextUrl: String,
6
+ container: String
7
+ }
8
+
9
+ connect() {
10
+ this.observer = new IntersectionObserver((entries) => {
11
+ if (entries.some((entry) => entry.isIntersecting)) {
12
+ this.loadMore()
13
+ }
14
+ })
15
+
16
+ this.observer.observe(this.element)
17
+ }
18
+
19
+ disconnect() {
20
+ this.observer?.disconnect()
21
+ }
22
+
23
+ async loadMore() {
24
+ if (!this.hasNextUrlValue || this.loading) return
25
+
26
+ this.loading = true
27
+
28
+ try {
29
+ const response = await fetch(this.nextUrlValue, {
30
+ headers: {
31
+ Accept: 'text/html'
32
+ }
33
+ })
34
+
35
+ if (!response.ok) return
36
+
37
+ const html = await response.text()
38
+
39
+ const nextDocument = new DOMParser().parseFromString(html, 'text/html')
40
+
41
+ const nextGrid = nextDocument.querySelector(`#${this.containerValue}`)
42
+
43
+ const currentGrid = document.getElementById(this.containerValue)
44
+
45
+ if (!currentGrid || !nextGrid) return
46
+
47
+ currentGrid.insertAdjacentHTML('beforeend', nextGrid.innerHTML)
48
+
49
+ const nextSentinel = nextDocument.querySelector('[data-controller="infinite-scroll"]')
50
+
51
+ if (nextSentinel?.dataset.infiniteScrollNextUrlValue) {
52
+ this.nextUrlValue = nextSentinel.dataset.infiniteScrollNextUrlValue
53
+ } else {
54
+ this.observer.disconnect()
55
+ this.element.remove()
56
+ }
57
+ } finally {
58
+ this.loading = false
59
+ }
60
+ }
61
+ }