rolemodel-rails 0.26.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 (251) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +161 -0
  4. data/Rakefile +6 -0
  5. data/lib/generators/rolemodel/README.md +29 -0
  6. data/lib/generators/rolemodel/USAGE +5 -0
  7. data/lib/generators/rolemodel/all_generator.rb +29 -0
  8. data/lib/generators/rolemodel/base_generator.rb +14 -0
  9. data/lib/generators/rolemodel/editors/README.md +9 -0
  10. data/lib/generators/rolemodel/editors/USAGE +9 -0
  11. data/lib/generators/rolemodel/editors/editors_generator.rb +30 -0
  12. data/lib/generators/rolemodel/editors/vscode_helpers.rb +22 -0
  13. data/lib/generators/rolemodel/github/README.md +23 -0
  14. data/lib/generators/rolemodel/github/USAGE +9 -0
  15. data/lib/generators/rolemodel/github/github_generator.rb +43 -0
  16. data/lib/generators/rolemodel/good_job/README.md +13 -0
  17. data/lib/generators/rolemodel/good_job/USAGE +5 -0
  18. data/lib/generators/rolemodel/good_job/good_job_generator.rb +73 -0
  19. data/lib/generators/rolemodel/good_job/templates/config/initializers/active_job.rb +17 -0
  20. data/lib/generators/rolemodel/good_job/templates/config/initializers/good_job.rb +24 -0
  21. data/lib/generators/rolemodel/heroku/README.md +8 -0
  22. data/lib/generators/rolemodel/heroku/USAGE +9 -0
  23. data/lib/generators/rolemodel/heroku/heroku_generator.rb +52 -0
  24. data/lib/generators/rolemodel/heroku/templates/Procfile +2 -0
  25. data/lib/generators/rolemodel/heroku/templates/app.json.tt +30 -0
  26. data/lib/generators/rolemodel/kaminari/README.md +14 -0
  27. data/lib/generators/rolemodel/kaminari/USAGE +5 -0
  28. data/lib/generators/rolemodel/kaminari/kaminari_generator.rb +17 -0
  29. data/lib/generators/rolemodel/kaminari/templates/app/views/kaminari/_first_page.html.slim +9 -0
  30. data/lib/generators/rolemodel/kaminari/templates/app/views/kaminari/_gap.html.slim +8 -0
  31. data/lib/generators/rolemodel/kaminari/templates/app/views/kaminari/_last_page.html.slim +9 -0
  32. data/lib/generators/rolemodel/kaminari/templates/app/views/kaminari/_next_page.html.slim +12 -0
  33. data/lib/generators/rolemodel/kaminari/templates/app/views/kaminari/_page.html.slim +10 -0
  34. data/lib/generators/rolemodel/kaminari/templates/app/views/kaminari/_paginator.html.slim +19 -0
  35. data/lib/generators/rolemodel/kaminari/templates/app/views/kaminari/_prev_page.html.slim +12 -0
  36. data/lib/generators/rolemodel/linters/README.md +32 -0
  37. data/lib/generators/rolemodel/linters/USAGE +5 -0
  38. data/lib/generators/rolemodel/linters/all_generator.rb +14 -0
  39. data/lib/generators/rolemodel/linters/eslint/README.md +5 -0
  40. data/lib/generators/rolemodel/linters/eslint/USAGE +8 -0
  41. data/lib/generators/rolemodel/linters/eslint/eslint_generator.rb +33 -0
  42. data/lib/generators/rolemodel/linters/eslint/templates/eslint.config.js +92 -0
  43. data/lib/generators/rolemodel/linters/rubocop/README.md +7 -0
  44. data/lib/generators/rolemodel/linters/rubocop/USAGE +9 -0
  45. data/lib/generators/rolemodel/linters/rubocop/rubocop_generator.rb +23 -0
  46. data/lib/generators/rolemodel/linters/rubocop/templates/lib/cops/form_error_response.rb +54 -0
  47. data/lib/generators/rolemodel/linters/rubocop/templates/lib/cops/no_chrome_tag.rb +45 -0
  48. data/lib/generators/rolemodel/lograge/README.md +10 -0
  49. data/lib/generators/rolemodel/lograge/USAGE +8 -0
  50. data/lib/generators/rolemodel/lograge/lograge_generator.rb +15 -0
  51. data/lib/generators/rolemodel/lograge/templates/config/initializers/lograge.rb +16 -0
  52. data/lib/generators/rolemodel/mailers/README.md +13 -0
  53. data/lib/generators/rolemodel/mailers/USAGE +22 -0
  54. data/lib/generators/rolemodel/mailers/mailers_generator.rb +99 -0
  55. data/lib/generators/rolemodel/mailers/templates/app/assets/stylesheets/mailer.scss +61 -0
  56. data/lib/generators/rolemodel/mailers/templates/app/mailers/example_mailer.rb +8 -0
  57. data/lib/generators/rolemodel/mailers/templates/app/mailers/staging_mailer_interceptor.rb +9 -0
  58. data/lib/generators/rolemodel/mailers/templates/app/views/example_mailer/example_email.html.slim +16 -0
  59. data/lib/generators/rolemodel/mailers/templates/app/views/layouts/mailer.html.slim +16 -0
  60. data/lib/generators/rolemodel/mailers/templates/config/initializers/premailer_rails.rb +15 -0
  61. data/lib/generators/rolemodel/mailers/templates/public/logo.png +0 -0
  62. data/lib/generators/rolemodel/mailers/templates/spec/mailers/previews/example_mailer_preview.rb +6 -0
  63. data/lib/generators/rolemodel/optics/README.md +8 -0
  64. data/lib/generators/rolemodel/optics/USAGE +5 -0
  65. data/lib/generators/rolemodel/optics/all_generator.rb +12 -0
  66. data/lib/generators/rolemodel/optics/base/README.md +9 -0
  67. data/lib/generators/rolemodel/optics/base/USAGE +5 -0
  68. data/lib/generators/rolemodel/optics/base/base_generator.rb +21 -0
  69. data/lib/generators/rolemodel/optics/icons/README.md +7 -0
  70. data/lib/generators/rolemodel/optics/icons/USAGE +8 -0
  71. data/lib/generators/rolemodel/optics/icons/icons_generator.rb +48 -0
  72. data/lib/generators/rolemodel/optics/icons/templates/app/helpers/icon_helper.rb.tt +24 -0
  73. data/lib/generators/rolemodel/optics/icons/templates/app/icon_builders/custom_icon_builder.rb +53 -0
  74. data/lib/generators/rolemodel/optics/icons/templates/app/icon_builders/feather_icon_builder.rb +22 -0
  75. data/lib/generators/rolemodel/optics/icons/templates/app/icon_builders/icon_builder.rb +73 -0
  76. data/lib/generators/rolemodel/optics/icons/templates/app/icon_builders/lucide_icon_builder.rb +22 -0
  77. data/lib/generators/rolemodel/optics/icons/templates/app/icon_builders/material_icon_builder.rb +31 -0
  78. data/lib/generators/rolemodel/optics/icons/templates/app/icon_builders/phosphor_icon_builder.rb +27 -0
  79. data/lib/generators/rolemodel/optics/icons/templates/app/icon_builders/tabler_icon_builder.rb +22 -0
  80. data/lib/generators/rolemodel/react/README.md +12 -0
  81. data/lib/generators/rolemodel/react/USAGE +5 -0
  82. data/lib/generators/rolemodel/react/react_generator.rb +36 -0
  83. data/lib/generators/rolemodel/react/templates/app/helpers/react_helper.rb +11 -0
  84. data/lib/generators/rolemodel/react/templates/app/javascript/components/HelloReact.jsx +14 -0
  85. data/lib/generators/rolemodel/react/templates/app/javascript/controllers/react_controller.js +24 -0
  86. data/lib/generators/rolemodel/readme/README.md +9 -0
  87. data/lib/generators/rolemodel/readme/USAGE +8 -0
  88. data/lib/generators/rolemodel/readme/readme_generator.rb +11 -0
  89. data/lib/generators/rolemodel/readme/templates/README.md.erb +116 -0
  90. data/lib/generators/rolemodel/replace_content_helper.rb +29 -0
  91. data/lib/generators/rolemodel/saas/README.md +7 -0
  92. data/lib/generators/rolemodel/saas/USAGE +5 -0
  93. data/lib/generators/rolemodel/saas/all_generator.rb +15 -0
  94. data/lib/generators/rolemodel/saas/devise/README.md +24 -0
  95. data/lib/generators/rolemodel/saas/devise/USAGE +25 -0
  96. data/lib/generators/rolemodel/saas/devise/devise_generator.rb +172 -0
  97. data/lib/generators/rolemodel/saas/devise/templates/app/assets/stylesheets/login.css +30 -0
  98. data/lib/generators/rolemodel/saas/devise/templates/app/controllers/admin/users_controller.rb +34 -0
  99. data/lib/generators/rolemodel/saas/devise/templates/app/controllers/application_controller.rb +11 -0
  100. data/lib/generators/rolemodel/saas/devise/templates/app/controllers/users/invitations_controller.rb +77 -0
  101. data/lib/generators/rolemodel/saas/devise/templates/app/controllers/users/omniauth_callbacks_controller.rb +30 -0
  102. data/lib/generators/rolemodel/saas/devise/templates/app/controllers/users/registrations_controller.rb +80 -0
  103. data/lib/generators/rolemodel/saas/devise/templates/app/views/admin/users/edit.html.slim +10 -0
  104. data/lib/generators/rolemodel/saas/devise/templates/app/views/admin/users/index.html.slim +27 -0
  105. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/confirmations/new.html.slim +11 -0
  106. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/invitations/edit.html.slim +13 -0
  107. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/invitations/new.html.slim +14 -0
  108. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/mailer/confirmation_instructions.html.slim +3 -0
  109. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/mailer/email_changed.html.slim +5 -0
  110. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/mailer/invitation_instructions.html.slim +11 -0
  111. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/mailer/invitation_instructions.text.slim +6 -0
  112. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/mailer/password_change.html.slim +2 -0
  113. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/mailer/reset_password_instructions.html.slim +5 -0
  114. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/mailer/unlock_instructions.html.slim +4 -0
  115. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/passwords/edit.html.slim +13 -0
  116. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/passwords/new.html.slim +11 -0
  117. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/registrations/edit.html.slim +34 -0
  118. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/registrations/new.html.slim +17 -0
  119. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/sessions/new.html.slim +14 -0
  120. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/shared/_error_messages.html.slim +9 -0
  121. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/shared/_links.html.slim +14 -0
  122. data/lib/generators/rolemodel/saas/devise/templates/app/views/devise/unlocks/new.html.slim +11 -0
  123. data/lib/generators/rolemodel/saas/devise/templates/config/locales/devise.en.yml +151 -0
  124. data/lib/generators/rolemodel/saas/devise/templates/config/locales/devise_invitable.en.yml +31 -0
  125. data/lib/generators/rolemodel/saas/devise/templates/spec/factories/organizations.rb +9 -0
  126. data/lib/generators/rolemodel/saas/devise/templates/spec/factories/users.rb +33 -0
  127. data/lib/generators/rolemodel/saas/devise/templates/spec/mailers/previews/devise_mailer_preview.rb +36 -0
  128. data/lib/generators/rolemodel/saas/devise/templates/spec/models/user_spec.rb +29 -0
  129. data/lib/generators/rolemodel/saas/devise/templates/spec/support/devise.rb +8 -0
  130. data/lib/generators/rolemodel/saas/devise/templates/spec/system/users_spec.rb +128 -0
  131. data/lib/generators/rolemodel/semaphore/README.md +15 -0
  132. data/lib/generators/rolemodel/semaphore/USAGE +11 -0
  133. data/lib/generators/rolemodel/semaphore/semaphore_generator.rb +25 -0
  134. data/lib/generators/rolemodel/semaphore/templates/heroku-deployment-commands.sh +3 -0
  135. data/lib/generators/rolemodel/semaphore/templates/production-deploy.yml.erb +17 -0
  136. data/lib/generators/rolemodel/semaphore/templates/semaphore.yml.erb +145 -0
  137. data/lib/generators/rolemodel/semaphore/templates/staging-deploy.yml.erb +17 -0
  138. data/lib/generators/rolemodel/simple_form/README.md +10 -0
  139. data/lib/generators/rolemodel/simple_form/USAGE +11 -0
  140. data/lib/generators/rolemodel/simple_form/simple_form_generator.rb +20 -0
  141. data/lib/generators/rolemodel/simple_form/templates/app/inputs/collection_check_boxes_input.rb +7 -0
  142. data/lib/generators/rolemodel/simple_form/templates/app/inputs/collection_select_input.rb +7 -0
  143. data/lib/generators/rolemodel/simple_form/templates/app/inputs/grouped_collection_select_input.rb +7 -0
  144. data/lib/generators/rolemodel/simple_form/templates/app/inputs/segmented_control_input.rb +48 -0
  145. data/lib/generators/rolemodel/simple_form/templates/app/inputs/switch_checkbox_input.rb +39 -0
  146. data/lib/generators/rolemodel/simple_form/templates/app/inputs/tailored_select_input.rb +75 -0
  147. data/lib/generators/rolemodel/simple_form/templates/config/initializers/simple_form.rb +207 -0
  148. data/lib/generators/rolemodel/simple_form/templates/config/locales/simple_form.en.yml +31 -0
  149. data/lib/generators/rolemodel/simple_form/templates/lib/templates/slim/scaffold/_form.html.slim.tt +12 -0
  150. data/lib/generators/rolemodel/slim/README.md +9 -0
  151. data/lib/generators/rolemodel/slim/USAGE +5 -0
  152. data/lib/generators/rolemodel/slim/slim_generator.rb +24 -0
  153. data/lib/generators/rolemodel/slim/templates/app/views/application/_head.html.slim.tt +13 -0
  154. data/lib/generators/rolemodel/slim/templates/app/views/layouts/application.html.slim.tt +6 -0
  155. data/lib/generators/rolemodel/slim/templates/lib/templates/slim/scaffold/edit.html.slim.tt +15 -0
  156. data/lib/generators/rolemodel/slim/templates/lib/templates/slim/scaffold/index.html.slim.tt +13 -0
  157. data/lib/generators/rolemodel/slim/templates/lib/templates/slim/scaffold/new.html.slim.tt +13 -0
  158. data/lib/generators/rolemodel/slim/templates/lib/templates/slim/scaffold/partial.html.slim.tt +10 -0
  159. data/lib/generators/rolemodel/slim/templates/lib/templates/slim/scaffold/show.html.slim.tt +33 -0
  160. data/lib/generators/rolemodel/soft_destroyable/README.md +8 -0
  161. data/lib/generators/rolemodel/soft_destroyable/USAGE +9 -0
  162. data/lib/generators/rolemodel/soft_destroyable/soft_destroyable_generator.rb +13 -0
  163. data/lib/generators/rolemodel/soft_destroyable/templates/soft_destroyable.rb +82 -0
  164. data/lib/generators/rolemodel/soft_destroyable/templates/soft_destroyable_behavior.rb +166 -0
  165. data/lib/generators/rolemodel/source_map/README.md +13 -0
  166. data/lib/generators/rolemodel/source_map/USAGE +9 -0
  167. data/lib/generators/rolemodel/source_map/source_map_generator.rb +22 -0
  168. data/lib/generators/rolemodel/source_map/templates/lib/middleware/rolemodel/source_map.rb +45 -0
  169. data/lib/generators/rolemodel/source_map/templates/lib/tasks/assets.rake +43 -0
  170. data/lib/generators/rolemodel/tailored_select/README.md +7 -0
  171. data/lib/generators/rolemodel/tailored_select/USAGE +5 -0
  172. data/lib/generators/rolemodel/tailored_select/tailored_select_generator.rb +13 -0
  173. data/lib/generators/rolemodel/testing/README.md +11 -0
  174. data/lib/generators/rolemodel/testing/USAGE +5 -0
  175. data/lib/generators/rolemodel/testing/all_generator.rb +17 -0
  176. data/lib/generators/rolemodel/testing/factory_bot/README.md +18 -0
  177. data/lib/generators/rolemodel/testing/factory_bot/USAGE +8 -0
  178. data/lib/generators/rolemodel/testing/factory_bot/factory_bot_generator.rb +20 -0
  179. data/lib/generators/rolemodel/testing/factory_bot/templates/support/factory_bot.rb +3 -0
  180. data/lib/generators/rolemodel/testing/jasmine_playwright/README.md +9 -0
  181. data/lib/generators/rolemodel/testing/jasmine_playwright/jasmine_playwright_generator.rb +52 -0
  182. data/lib/generators/rolemodel/testing/jasmine_playwright/templates/jp-runner.config.mjs +5 -0
  183. data/lib/generators/rolemodel/testing/jasmine_playwright/templates/spec/javascript/browser/example_spec.js +15 -0
  184. data/lib/generators/rolemodel/testing/jasmine_playwright/templates/spec/javascript/browser/setupTests.js +3 -0
  185. data/lib/generators/rolemodel/testing/jasmine_playwright/templates/support/react.mjs +26 -0
  186. data/lib/generators/rolemodel/testing/parallel_tests/README.md +53 -0
  187. data/lib/generators/rolemodel/testing/parallel_tests/USAGE +12 -0
  188. data/lib/generators/rolemodel/testing/parallel_tests/parallel_tests_generator.rb +42 -0
  189. data/lib/generators/rolemodel/testing/rspec/README.md +46 -0
  190. data/lib/generators/rolemodel/testing/rspec/USAGE +14 -0
  191. data/lib/generators/rolemodel/testing/rspec/rspec_generator.rb +46 -0
  192. data/lib/generators/rolemodel/testing/rspec/templates/rails_helper.rb +72 -0
  193. data/lib/generators/rolemodel/testing/rspec/templates/spec_helper.rb +97 -0
  194. data/lib/generators/rolemodel/testing/rspec/templates/support/capybara_drivers.rb +51 -0
  195. data/lib/generators/rolemodel/testing/rspec/templates/support/capybara_testid.rb +5 -0
  196. data/lib/generators/rolemodel/testing/rspec/templates/support/helpers/action_cable_helper.rb +5 -0
  197. data/lib/generators/rolemodel/testing/rspec/templates/support/helpers/capybara_helper.rb +72 -0
  198. data/lib/generators/rolemodel/testing/rspec/templates/support/helpers/playwright_helper.rb +85 -0
  199. data/lib/generators/rolemodel/testing/rspec/templates/support/helpers/select_helper.rb +33 -0
  200. data/lib/generators/rolemodel/testing/rspec/templates/support/helpers/test_element_helper.rb +11 -0
  201. data/lib/generators/rolemodel/testing/rspec/templates/support/helpers.rb +12 -0
  202. data/lib/generators/rolemodel/testing/test_prof/README.md +5 -0
  203. data/lib/generators/rolemodel/testing/test_prof/USAGE +5 -0
  204. data/lib/generators/rolemodel/testing/test_prof/test_prof_generator.rb +14 -0
  205. data/lib/generators/rolemodel/testing/vitest/README.md +5 -0
  206. data/lib/generators/rolemodel/testing/vitest/USAGE +5 -0
  207. data/lib/generators/rolemodel/testing/vitest/templates/spec/javascript/example.spec.js +12 -0
  208. data/lib/generators/rolemodel/testing/vitest/templates/spec/javascript/test-setup.js +1 -0
  209. data/lib/generators/rolemodel/testing/vitest/templates/vitest.config.js +23 -0
  210. data/lib/generators/rolemodel/testing/vitest/vitest_generator.rb +38 -0
  211. data/lib/generators/rolemodel/ui_components/README.md +9 -0
  212. data/lib/generators/rolemodel/ui_components/USAGE +5 -0
  213. data/lib/generators/rolemodel/ui_components/all_generator.rb +15 -0
  214. data/lib/generators/rolemodel/ui_components/flash/README.md +10 -0
  215. data/lib/generators/rolemodel/ui_components/flash/USAGE +9 -0
  216. data/lib/generators/rolemodel/ui_components/flash/flash_generator.rb +22 -0
  217. data/lib/generators/rolemodel/ui_components/flash/templates/app/views/application/_flash.html.slim +6 -0
  218. data/lib/generators/rolemodel/ui_components/flash/templates/spec/support/matchers/flash_matchers.rb +19 -0
  219. data/lib/generators/rolemodel/ui_components/modals/README.md +119 -0
  220. data/lib/generators/rolemodel/ui_components/modals/USAGE +8 -0
  221. data/lib/generators/rolemodel/ui_components/modals/modals_generator.rb +74 -0
  222. data/lib/generators/rolemodel/ui_components/modals/templates/app/helpers/turbo_frame_link_helper.rb +20 -0
  223. data/lib/generators/rolemodel/ui_components/modals/templates/app/javascript/controllers/morph_controller.js +23 -0
  224. data/lib/generators/rolemodel/ui_components/modals/templates/app/javascript/controllers/toggle_controller.js +55 -0
  225. data/lib/generators/rolemodel/ui_components/modals/templates/app/javascript/initializers/before_morph_handler.js +21 -0
  226. data/lib/generators/rolemodel/ui_components/modals/templates/app/javascript/initializers/frame_missing_handler.js +12 -0
  227. data/lib/generators/rolemodel/ui_components/modals/templates/app/javascript/initializers/turbo_confirm.js +3 -0
  228. data/lib/generators/rolemodel/ui_components/modals/templates/app/views/application/_confirm.html.slim +12 -0
  229. data/lib/generators/rolemodel/ui_components/modals/templates/app/views/layouts/modal.html.slim.tt +26 -0
  230. data/lib/generators/rolemodel/ui_components/modals/templates/app/views/layouts/panel.html.slim.tt +21 -0
  231. data/lib/generators/rolemodel/ui_components/navbar/README.md +11 -0
  232. data/lib/generators/rolemodel/ui_components/navbar/USAGE +10 -0
  233. data/lib/generators/rolemodel/ui_components/navbar/navbar_generator.rb +54 -0
  234. data/lib/generators/rolemodel/ui_components/navbar/templates/app/assets/stylesheets/components/shoelace/index.scss +2 -0
  235. data/lib/generators/rolemodel/ui_components/navbar/templates/app/javascript/lib/shoelace.js +9 -0
  236. data/lib/generators/rolemodel/ui_components/navbar/templates/app/views/layouts/_navbar.html.slim +29 -0
  237. data/lib/generators/rolemodel/webpack/README.md +8 -0
  238. data/lib/generators/rolemodel/webpack/USAGE +5 -0
  239. data/lib/generators/rolemodel/webpack/templates/app/assets/stylesheets/application.scss +5 -0
  240. data/lib/generators/rolemodel/webpack/templates/app/javascript/initializers/honeybadger.js +26 -0
  241. data/lib/generators/rolemodel/webpack/templates/postcss.config.cjs +14 -0
  242. data/lib/generators/rolemodel/webpack/templates/webpack.config.js +104 -0
  243. data/lib/generators/rolemodel/webpack/webpack_generator.rb +76 -0
  244. data/lib/generators/templates/generator/%filename%.rb.tt +11 -0
  245. data/lib/generators/templates/generator/README.md.tt +11 -0
  246. data/lib/generators/templates/generator/USAGE.tt +5 -0
  247. data/lib/generators/templates/generator_spec/%filename%_spec.rb.tt +5 -0
  248. data/lib/rolemodel/engine.rb +9 -0
  249. data/lib/rolemodel/version.rb +5 -0
  250. data/lib/rolemodel-rails.rb +7 -0
  251. metadata +416 -0
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Sets up React for Rails
3
+
4
+ Example:
5
+ rails generate rolemodel:react
@@ -0,0 +1,36 @@
1
+ module Rolemodel
2
+ class ReactGenerator < BaseGenerator
3
+ source_root File.expand_path('templates', __dir__)
4
+
5
+ def add_npm_packages
6
+ @add_react = yes?('Would you like to add react?')
7
+
8
+ if @add_react
9
+ run 'yarn add react react-dom'
10
+ end
11
+ end
12
+
13
+ def add_files
14
+ if @add_react
15
+ say 'Copying files'
16
+
17
+ template 'app/helpers/react_helper.rb', 'app/helpers/react_helper.rb'
18
+
19
+ template 'app/javascript/components/HelloReact.jsx', 'app/javascript/components/HelloReact.jsx'
20
+ template 'app/javascript/controllers/react_controller.js', 'app/javascript/controllers/react_controller.js'
21
+ end
22
+ end
23
+
24
+ def import_react_controller
25
+ if @add_react
26
+ say 'Importing react_controller.js'
27
+
28
+ append_to_file 'app/javascript/controllers/index.js', <<~JS
29
+
30
+ import ReactController from './react_controller.js'
31
+ application.register('react', ReactController)
32
+ JS
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,11 @@
1
+ module ReactHelper
2
+ def react_component(component_name, props = {})
3
+ tag.div(
4
+ data: {
5
+ controller: 'react',
6
+ component: component_name,
7
+ props: props.to_json
8
+ }
9
+ )
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ import React from 'react'
2
+
3
+ // To display React components in your view, import them into the react_controller.js Stimulus
4
+ // controller and then use the react_component view helper to mount them in your Rails view:
5
+ //
6
+ // = react_component 'HelloReact', currentTime: Time.now
7
+
8
+ export default function HelloReact({ currentTime }) {
9
+ return (
10
+ <div>
11
+ Hello! The current time is {currentTime}
12
+ </div>
13
+ )
14
+ }
@@ -0,0 +1,24 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+ import React from 'react'
3
+ import { createRoot } from 'react-dom/client'
4
+
5
+ import HelloReact from '../components/HelloReact.jsx'
6
+
7
+ const registeredComponents = {
8
+ HelloReact
9
+ }
10
+
11
+ export default class extends Controller {
12
+ connect() {
13
+ const componentName = this.element.dataset.component
14
+ const component = registeredComponents[componentName]
15
+
16
+ if (component) {
17
+ const root = createRoot(this.element)
18
+ const props = JSON.parse(this.element.dataset.props)
19
+ root.render(React.createElement(component, props))
20
+ } else {
21
+ throw new Error('Unrecognized React component name!')
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,9 @@
1
+ # README Generator
2
+
3
+ ## What you get
4
+
5
+ ### README Template
6
+
7
+ When you create a project in Github it will use the Markdown file as a [README](./templates/README.md.erb) for the repository.
8
+
9
+ Make sure to review the README and add other items your team finds necessary.
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Sets up our standard README for a project
3
+
4
+ Example:
5
+ rails generate rolemodel:readme
6
+
7
+ This will create:
8
+ /README.md
@@ -0,0 +1,11 @@
1
+ module Rolemodel
2
+ class ReadmeGenerator < BaseGenerator
3
+ source_root File.expand_path('templates', __dir__)
4
+
5
+ def install_readme
6
+ @project_name = Rails.application.class.try(:parent_name) || Rails.application.class.module_parent_name
7
+ @project = @project_name.underscore
8
+ template 'README.md.erb', 'README.md'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,116 @@
1
+ # Overview
2
+ ## Name and aliases
3
+ The project is named "<%= @project_name %>". Some will refer to it as "<alias1>" or "<alias2>".
4
+
5
+ ## Purpose
6
+ The system is designed to solve the problem of ... Users had the problem, but this system resolves it by ...
7
+
8
+ ## Technologies
9
+ ### Chosen
10
+ * Ruby on Rails
11
+ * Postgres
12
+ * nginx
13
+ * puma
14
+
15
+ ### Tried and rejected
16
+ * Node.js - Not enough internal experience.
17
+ * Mongo - Needed to use a relational database for reporting.
18
+ * Websphere - Cost
19
+ * webrick - Application servers are using newer technology now.
20
+
21
+ ## Technology relationships
22
+ <insert image here>
23
+
24
+ ## Supported browsers
25
+ The customer states that only Chrome will be used.
26
+
27
+ # How to set up the project
28
+ ## External tool installation
29
+ \```
30
+ brew update --system
31
+ brew upgrade ruby-build
32
+ git clone http://github.com/RoleModel/<%= @project %>
33
+ cd <%= @project %>
34
+ rbenv install
35
+ gem install bundler
36
+ bundle install
37
+ \```
38
+
39
+ ## How to run locally
40
+ `rails s`
41
+
42
+ ## How to run tests
43
+ `rake`
44
+
45
+ ## Editor plugins
46
+ * Rubocop linter
47
+
48
+ ## Troubleshooting information
49
+ * [App Status Page](http://app.<applicationname>.com/_ping) will give you information about what is running.
50
+ * Alternatively, you can ssh in and check that the application server and web server are both running.
51
+
52
+ # Testing Strategy
53
+ ## Testing approach
54
+ ### System tests
55
+ Due to the nature of this application, End User tests are...
56
+
57
+ ### Unit tests
58
+ Due to the nature of this application, unit tests are prominent and handle most of the confidence building and documentation needs of the system below the user interface.
59
+
60
+ ### Other tests
61
+ At this point, no other tests are being employed.
62
+ However, one might consider performance tests or other categories and describe the reasons here
63
+
64
+ ## Testing tools
65
+ Which tools are we using?
66
+
67
+ ## Continuous integration
68
+ No CI has been set up yet (though we recommend Sempahore in most cases). When you set it up, tell what you need to know here
69
+
70
+ # Branching strategy
71
+ To begin a new feature run, `git checkout -b <branchname>`.
72
+ When finished with the feature and the code has been reviewed, the commits should be squashed before merging. See [RoleModel Best Practices](https://github.com/RoleModel/BestPractices) for more information.
73
+
74
+ # List of background processes
75
+ * Nightly database backup and export
76
+ * Monthly invoicing on last business day of the month
77
+
78
+ # Links to:
79
+ ## [Git repo](http://github.com/RoleModel/<%= @project %>)
80
+ ## [Task management system](http://trello.com)
81
+ ## [Staging](http://staging.<applicationname>.com)
82
+ ## [Production](http://app.<applicationname>.com)
83
+ ## External services
84
+ * [HoneyBadger](http://honeybadger.io)
85
+ * [Skylight](http://skylight.io)
86
+ * [SendGrid](http://sendgrid.com/RoleModel)
87
+ * [Heroku](http://herokuapp.com)
88
+
89
+ ## [CI](http://semaphoreci.com/RoleModel)
90
+ ## [Core project presentation](http://docs.google.com)
91
+ ## [List of contributors](http://github.com/RoleModel)
92
+ ## [Change log](file://./docs/change_log.md)
93
+
94
+ # Deployment
95
+ ## Strategy/process/commands
96
+ `master` is always deployed to production. The `staging` branch is deployed to staging.
97
+ \```
98
+ git checkout master
99
+ git tag 2016-05-16 # <date> YYYY-MM-DD
100
+ git push --tags
101
+ \```
102
+ Deployment is done with [Ansible](http://ansible.com).
103
+ `ansible <command goes here>`
104
+
105
+ ## Description of host(s), DNS, certificate authority
106
+ The application is deployed to Heroku. They are also hosting the DNS. We certificate was received from [Let's Encrypt](https://letsencrypt.org/).
107
+
108
+ ## ssh information
109
+ `ssh user@hostname.com`
110
+
111
+ # Customer contacts
112
+ * Joe Johnson - 919-555-1212
113
+ * Larry Anderson - 919-555-1213
114
+
115
+ # Copyright & licensing
116
+ Copyright (c) 2019 Closed Source @CompanyName
@@ -0,0 +1,29 @@
1
+ module Rolemodel
2
+ module ReplaceContentHelper
3
+ private
4
+
5
+ def replace_content(relative_path, &block)
6
+ source = File.expand_path(relative_path.to_s, destination_root)
7
+ content = File.exist?(source) ? File.open(source) { it.binmode.read } : ''
8
+
9
+ remove_file relative_path
10
+ create_file relative_path, yield(content)
11
+ end
12
+
13
+ def modify_json_file(relative_path, &block)
14
+ replace_content(relative_path) do |content|
15
+ hash = JSON.parse(content.presence || '{}')
16
+ yield(hash)
17
+ JSON.pretty_generate(hash) + "\n"
18
+ end
19
+ end
20
+
21
+ def add_package_json_script(command_name, command)
22
+ modify_json_file('package.json') do |hash|
23
+ hash['scripts'] ||= {}
24
+ hash['scripts'][command_name] = command
25
+ hash
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ # SaaS Generator
2
+
3
+ [USAGE](./USAGE)
4
+
5
+ ## What you get
6
+
7
+ * [Devise](./devise)
@@ -0,0 +1,5 @@
1
+ Description:
2
+ runs all the SaaS generators
3
+
4
+ Example:
5
+ rails generate rolemodel:saas:all
@@ -0,0 +1,15 @@
1
+ module Rolemodel
2
+ module Saas
3
+ class AllGenerator < BaseGenerator
4
+ source_root File.expand_path('templates', __dir__)
5
+
6
+ def run_all_the_generators
7
+ # no guaranteed order to this list with Dir.glob
8
+ Dir.glob(Pathname(File.expand_path('.', __dir__)).join('*', '*generator.rb')).each do |generator|
9
+ name = File.basename(generator, '_generator.rb')
10
+ generate "rolemodel:saas:#{name}"
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ # Devise Generator
2
+
3
+ Depends on devise and devise_invitable generators
4
+ Depends on [RSpec Generator](../../testing/rspec)
5
+ Depends on slim
6
+
7
+ ## What you get
8
+
9
+ Installs [devise](https://github.com/heartcombo/devise)
10
+ Installs [devise_invitable](https://github.com/scambra/devise_invitable)
11
+
12
+ ### Models
13
+ * Adds User model
14
+ * Add Organization model (if needed)
15
+
16
+ ### Views
17
+ * Current user
18
+ * Sign up, sign in, sign out
19
+ * Add user profile page
20
+ * Invitation page (if requested)
21
+
22
+ ### Tests
23
+ * Devise test helpers
24
+ * User system test
@@ -0,0 +1,25 @@
1
+ Description:
2
+ installs and configures Devise
3
+
4
+ Example:
5
+ rails generate rolemodel:saas:devise
6
+
7
+ This will create:
8
+ app/controllers/application_controller.rb
9
+ app/controllers/users
10
+ app/models/organization.rb
11
+ app/models/user.rb
12
+ app/views/devise
13
+ config/initializers/devise.rb
14
+ spec/support/devise.rb
15
+ spec/system/users_spec.rb
16
+ spec/factories/organizations.rb
17
+ spec/factories/users.rb
18
+ spec/mailers/previews/devise_mailer_preview.rb
19
+
20
+ This will modify:
21
+ config/environments/development.rb
22
+ config/environments/production.rb
23
+ config/routes.rb
24
+ app/models/user.rb
25
+ db/seeds.rb
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rolemodel
4
+ module Saas
5
+ class DeviseGenerator < BaseGenerator
6
+ source_root File.expand_path('templates', __dir__)
7
+
8
+ def add_organization
9
+ generate :model, 'organization name:string' unless File.exist?(Rails.root.join('app/models/organization.rb'))
10
+ inject_into_file 'app/models/organization.rb', " has_many :users, inverse_of: :organization\n",
11
+ after: "ApplicationRecord\n"
12
+ end
13
+
14
+ def install_devise
15
+ # Devise tries to install bcrypt, but it fails because the bundle command
16
+ # is run using the wrong platform causing the native extension to fail.
17
+ # Using clean env fixes this.
18
+ bundle_command 'add devise'
19
+
20
+ generate 'devise:install'
21
+ generate :devise, 'user first_name:string last_name:string'
22
+ generate :migration,
23
+ 'add_organization_and_role_to_users organization_id:bigint:index role:string super_admin:boolean'
24
+ file_name = Dir.glob(Rails.root.join('db/migrate', '*_add_organization_and_role_to_users.rb')).last
25
+ gsub_file file_name, /:role, :string$/, ":role, :string, default: 'user', null: false"
26
+ gsub_file file_name, /:super_admin, :boolean$/, ':super_admin, :boolean, default: false, null: false'
27
+ end
28
+
29
+ def add_invitable
30
+ @add_invitations = yes?('Would you like to add user invitations?')
31
+ return unless @add_invitations
32
+
33
+ bundle_command 'add devise_invitable'
34
+
35
+ generate 'devise_invitable:install'
36
+ generate :devise_invitable, 'user'
37
+ end
38
+
39
+ def add_routes
40
+ route_info = ", controllers: {\n"
41
+ route_info += " invitations: 'users/invitations',\n" if @add_invitations
42
+ route_info += " registrations: 'users/registrations',\n"
43
+ route_info += ' }'
44
+ inject_into_file 'config/routes.rb', route_info, after: /devise_for :users$/
45
+
46
+ route_info = "namespace :admin do\n"
47
+ if @add_invitations
48
+ route_info += " resources :users do\n"
49
+ route_info += " post :reinvite, on: :member\n"
50
+ route_info += " end\n"
51
+ else
52
+ route_info += " resources :users\n"
53
+ end
54
+ route_info += 'end'
55
+ route route_info
56
+
57
+ route 'root to: "admin/users#index"' unless File.readlines('config/routes.rb').grep(/root\sto/).any?
58
+ end
59
+
60
+ def add_modified_files
61
+ copy_file 'app/controllers/application_controller.rb'
62
+ if @add_invitations
63
+ copy_file 'app/controllers/users/invitations_controller.rb'
64
+ directory 'app/views/devise/invitations'
65
+ copy_file 'app/views/devise/mailer/invitation_instructions.html.slim'
66
+ copy_file 'app/views/devise/mailer/invitation_instructions.text.slim'
67
+ copy_file 'config/locales/devise_invitable.en.yml'
68
+ end
69
+ template 'app/controllers/admin/users_controller.rb'
70
+ copy_file 'app/controllers/users/registrations_controller.rb'
71
+ directory 'app/views/admin'
72
+ directory 'app/views/devise', exclude_pattern: /invitation/
73
+ copy_file 'config/locales/devise.en.yml'
74
+ copy_file 'spec/support/devise.rb'
75
+ copy_file 'spec/system/users_spec.rb'
76
+ copy_file 'spec/factories/organizations.rb'
77
+ copy_file 'spec/factories/users.rb'
78
+ copy_file 'spec/models/user_spec.rb'
79
+ end
80
+
81
+ def modify_existing_files
82
+ unless File.exist?(Rails.root.join('config/initializers/premailer_rails.rb'))
83
+ inject_into_file 'config/environments/development.rb',
84
+ after: "config.action_mailer.perform_caching = false\n" do
85
+ optimize_indentation <<~'RUBY', 2
86
+
87
+ # Default mailing host suggested by Devise installation instructions
88
+ config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
89
+ RUBY
90
+ end
91
+ end
92
+
93
+ inject_into_file 'config/environments/production.rb', after: "config.action_mailer.perform_caching = false\n" do
94
+ optimize_indentation <<~'RUBY', 2
95
+
96
+ # Tell Devise about your host, so it can send password reset emails
97
+ if ENV['REVIEW_APP'] == 'true' && ENV['HEROKU_APP_NAME'].present?
98
+ config.action_mailer.default_url_options = { host: "https://#{ENV['HEROKU_APP_NAME']}.herokuapp.com" }
99
+ else
100
+ config.action_mailer.default_url_options = { host: ENV['PRODUCTION_HOST'] }
101
+ end
102
+ RUBY
103
+ end
104
+
105
+ # Update Devise email_regexp to something more useful
106
+ gsub_file 'config/initializers/devise.rb', '/\A[^@\s]+@[^@\s]+\z/',
107
+ '/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i'
108
+ # Turn Devise validate_on_invite on by default
109
+ if @add_invitations
110
+ gsub_file 'config/initializers/devise.rb', '# config.validate_on_invite = true',
111
+ 'config.validate_on_invite = true'
112
+ end
113
+
114
+ inject_into_file 'app/models/user.rb', after: /devise\s+:.*\n.*\n/ do
115
+ optimize_indentation <<~'RUBY', 2
116
+
117
+ enum :role, { user: 'user', admin: 'admin' }
118
+
119
+ belongs_to :organization, inverse_of: :users
120
+ accepts_nested_attributes_for :organization
121
+
122
+ validates :first_name, :last_name, :role, presence: true
123
+ delegate :name, to: :organization, prefix: true
124
+ RUBY
125
+ end
126
+
127
+ inject_into_file 'db/seeds.rb', after: "Examples:\n" do
128
+ <<~'RUBY'
129
+ if Rails.env.development?
130
+ puts 'Creating the default user environment...'
131
+
132
+ organization = Organization.create!(
133
+ name: 'RoleModel Software'
134
+ )
135
+
136
+ User.create!(
137
+ first_name: 'Support',
138
+ last_name: 'Admin',
139
+ organization: organization,
140
+ super_admin: true,
141
+ role: User.roles[:admin],
142
+ email: 'user@example.com',
143
+ password: 'password',
144
+ password_confirmation: 'password'
145
+ )
146
+ end
147
+ RUBY
148
+ end
149
+ end
150
+
151
+ def define_devise_mailer_layout
152
+ gsub_file 'config/initializers/devise.rb', "# config.parent_mailer = 'ActionMailer::Base'",
153
+ "config.parent_mailer = 'ApplicationMailer'"
154
+ end
155
+
156
+ def add_devise_mailer_preview
157
+ copy_file 'spec/mailers/previews/devise_mailer_preview.rb'
158
+ end
159
+
160
+ def add_login_styles
161
+ say 'importing login stylesheet', :green
162
+ copy_file 'app/assets/stylesheets/login.css'
163
+
164
+ return unless File.exist?(File.join(destination_root, 'app/assets/stylesheets/application.scss'))
165
+
166
+ append_to_file 'app/assets/stylesheets/application.scss', <<~SCSS
167
+ @import 'login';
168
+ SCSS
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,30 @@
1
+ .app__login {
2
+ margin: calc(2 * var(--op-space-4x-large)) auto auto;
3
+ padding-inline: var(--op-space-large);
4
+ width: 100%;
5
+ max-width: calc(116 * var(--op-size-unit));
6
+ }
7
+
8
+ /* This could also be its own card variant */
9
+ .card--login {
10
+ .card__header {
11
+ display: flex;
12
+ justify-content: center;
13
+ }
14
+
15
+ .card__header img {
16
+ width: calc(23 * var(--op-size-unit));
17
+ }
18
+
19
+ .card__body {
20
+ padding-block: 0;
21
+ }
22
+
23
+ .card__footer {
24
+ display: flex;
25
+ justify-content: space-between;
26
+ align-items: center;
27
+ flex-wrap: wrap;
28
+ gap: var(--op-space-x-small);
29
+ }
30
+ }
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Admin
4
+ class UsersController < ApplicationController
5
+ def index
6
+ @users = User.all
7
+ end
8
+
9
+ def edit
10
+ @user = User.find(params[:id])
11
+ end
12
+
13
+ def update
14
+ @user = User.find(params[:id])
15
+ if @user.update(user_params)
16
+ redirect_to admin_users_url, notice: 'User was updated successfully'
17
+ else
18
+ render :edit
19
+ end
20
+ end
21
+ <%- if @add_invitations %>
22
+ def reinvite
23
+ @user = User.find(params[:id])
24
+ @user.invite! current_user
25
+ redirect_to admin_users_url, notice: 'Invitation email sent'
26
+ end
27
+ <%- end %>
28
+ private
29
+
30
+ def user_params
31
+ params.require(:user).permit(:email, :first_name, :last_name)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationController < ActionController::Base
4
+ before_action :authenticate_user!
5
+
6
+ private
7
+
8
+ def current_organization
9
+ current_user.try(:organization)
10
+ end
11
+ end