plutonium 0.10.2 → 0.11.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 (228) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/Rakefile +1 -2
  4. data/app/assets/application.js.bk +31419 -0
  5. data/app/assets/plutonium-logo-original.png +0 -0
  6. data/app/assets/plutonium-logo-white.png +0 -0
  7. data/app/assets/plutonium-logo.png +0 -0
  8. data/app/assets/plutonium.css +1 -0
  9. data/app/assets/plutonium.ico +0 -0
  10. data/app/assets/plutonium.js +12416 -0
  11. data/app/assets/plutonium.js.map +7 -0
  12. data/app/assets/plutonium.min.js +39 -0
  13. data/app/assets/plutonium.min.js.map +7 -0
  14. data/app/views/application/_flash_alerts.html.erb +5 -2
  15. data/app/views/application/_flash_toasts.html.erb +2 -0
  16. data/app/views/application/_resource_header.html.erb +263 -697
  17. data/app/views/application/_resource_sidebar.html.erb +14 -12
  18. data/app/views/components/action_button/action_button_component.rb +3 -3
  19. data/app/views/components/attributes.rb +184 -0
  20. data/app/views/components/base.rb +19 -40
  21. data/app/views/components/block/block_component.html.erb +1 -1
  22. data/app/views/components/block/block_component.rb +11 -7
  23. data/app/views/components/breadcrumbs/breadcrumbs_component.rb +3 -3
  24. data/app/views/components/button/button_component.html.erb +2 -2
  25. data/app/views/components/button/button_component.rb +10 -5
  26. data/app/views/components/dyna_frame_content/dyna_frame_content_component.html.erb +1 -0
  27. data/app/views/components/dyna_frame_content/dyna_frame_content_component.rb +3 -3
  28. data/app/views/components/dyna_frame_host/dyna_frame_host_component.html.erb +1 -2
  29. data/app/views/components/dyna_frame_host/dyna_frame_host_component.rb +12 -5
  30. data/app/views/components/empty_card/empty_card_component.rb +3 -3
  31. data/app/views/components/form/form_builder.rb +1 -1
  32. data/app/views/components/form/form_component.rb +3 -3
  33. data/app/views/components/has_many_panel/has_many_panel_component.html.erb +25 -0
  34. data/app/views/components/has_many_panel/has_many_panel_component.rb +16 -0
  35. data/app/views/components/header/header_component.rb +3 -3
  36. data/app/views/components/interactive_action_form/interactive_action_form_component.rb +3 -3
  37. data/app/views/components/nav_grid_menu/nav_grid_menu_component.html.erb +24 -0
  38. data/app/views/components/nav_grid_menu/nav_grid_menu_component.rb +23 -0
  39. data/app/views/components/nav_grid_menu_item/nav_grid_menu_item_component.html.erb +4 -0
  40. data/app/views/components/nav_grid_menu_item/nav_grid_menu_item_component.rb +20 -0
  41. data/app/views/components/nav_user/nav_user_component.html.erb +50 -0
  42. data/app/views/components/nav_user/nav_user_component.rb +32 -0
  43. data/app/views/components/nav_user_link/nav_user_link_component.html.erb +7 -0
  44. data/app/views/components/nav_user_link/nav_user_link_component.rb +23 -0
  45. data/app/views/components/nav_user_section/nav_user_section_component.html.erb +7 -0
  46. data/app/views/components/nav_user_section/nav_user_section_component.rb +18 -0
  47. data/app/views/components/nested_resource_form_fields/nested_resource_form_fields_component.html.erb +1 -3
  48. data/app/views/components/nested_resource_form_fields/nested_resource_form_fields_component.rb +11 -5
  49. data/app/views/components/pagination/pagination_component.html.erb +1 -1
  50. data/app/views/components/pagination/pagination_component.rb +10 -7
  51. data/app/views/components/panel/panel_component.html.erb +13 -6
  52. data/app/views/components/panel/panel_component.rb +11 -5
  53. data/app/views/components/resource_header/resource_header_component.html.erb +81 -0
  54. data/app/views/components/resource_header/resource_header_component.rb +20 -0
  55. data/app/views/components/resource_layout/resource_layout_component.html.erb +32 -0
  56. data/app/views/components/resource_layout/resource_layout_component.rb +39 -0
  57. data/app/views/components/sidebar/sidebar_component.html.erb +3 -33
  58. data/app/views/components/sidebar/sidebar_component.rb +3 -3
  59. data/app/views/components/sidebar_menu/sidebar_menu_component.html.erb +4 -2
  60. data/app/views/components/sidebar_menu/sidebar_menu_component.rb +10 -6
  61. data/app/views/components/sidebar_menu_item/sidebar_menu_item_component.html.erb +63 -71
  62. data/app/views/components/sidebar_menu_item/sidebar_menu_item_component.rb +27 -8
  63. data/app/views/components/skeleton/table/table_component.html.erb +1 -1
  64. data/app/views/components/skeleton/table/table_component.rb +3 -3
  65. data/app/views/components/table/table_component.html.erb +40 -89
  66. data/app/views/components/table/table_component.rb +124 -28
  67. data/app/views/components/table_search_input/table_search_input_component.html.erb +1 -1
  68. data/app/views/components/table_search_input/table_search_input_component.rb +11 -6
  69. data/app/views/components/table_toolbar/table_toolbar_component.html.erb +1 -1
  70. data/app/views/components/table_toolbar/table_toolbar_component.rb +11 -3
  71. data/app/views/components/toolbar/toolbar_component.html.erb +2 -2
  72. data/app/views/components/toolbar/toolbar_component.rb +16 -8
  73. data/app/views/layouts/resource.html copy.erb +2 -2
  74. data/app/views/layouts/resource.html.erb +21 -37
  75. data/app/views/layouts/rodauth.html.erb +32 -25
  76. data/app/views/resource/_interactive_resource_action_form.html.erb +1 -1
  77. data/app/views/resource/_resource_details.html.erb +8 -5
  78. data/app/views/resource/_resource_table.html.erb +70 -1
  79. data/app/views/resource/interactive_resource_collection_action.html.erb +1 -0
  80. data/app/views/resource/interactive_resource_record_action.html.erb +1 -0
  81. data/app/views/resource/interactive_resource_recordless_action.html.erb +1 -0
  82. data/app/views/resource/new.html.erb +1 -0
  83. data/app/views/rodauth/add_recovery_codes.html.erb +8 -7
  84. data/app/views/rodauth/otp_auth.html.erb +1 -1
  85. data/app/views/rodauth/otp_setup.html.erb +10 -8
  86. data/config/initializers/simple_form.rb +22 -2
  87. data/esbuild.config.js +35 -31
  88. data/lib/generators/pu/core/assets/assets_generator.rb +41 -0
  89. data/lib/generators/pu/core/assets/templates/tailwind.config.js +18 -0
  90. data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +3 -0
  91. data/lib/generators/pu/core/ruby/ruby_generator.rb +30 -0
  92. data/lib/generators/pu/core/ruby/templates/.keep +0 -0
  93. data/lib/generators/pu/docker/install/install_generator.rb +35 -0
  94. data/lib/generators/pu/docker/install/templates/.keep +0 -0
  95. data/lib/generators/pu/docker/install/templates/Dockerfile.dev.tt +30 -0
  96. data/lib/generators/pu/docker/install/templates/Dockerfile.tt +75 -0
  97. data/lib/generators/pu/docker/install/templates/bin/console +3 -0
  98. data/lib/generators/pu/docker/install/templates/bin/restart +3 -0
  99. data/lib/generators/pu/docker/install/templates/bin/shell +3 -0
  100. data/lib/generators/pu/docker/install/templates/docker-compose.yml +29 -0
  101. data/lib/generators/pu/gem/dotenv/dotenv_generator.rb +32 -0
  102. data/lib/generators/pu/gem/dotenv/templates/.env +6 -0
  103. data/lib/generators/pu/gem/dotenv/templates/.env.local +5 -0
  104. data/lib/generators/pu/gem/dotenv/templates/.env.local.template +5 -0
  105. data/lib/generators/pu/gem/dotenv/templates/.env.template +6 -0
  106. data/lib/generators/pu/gem/dotenv/templates/.keep +0 -0
  107. data/lib/generators/pu/gem/dotenv/templates/config/initializers/001_ensure_required_env.rb +21 -0
  108. data/lib/generators/pu/gem/redis/redis_generator.rb +22 -0
  109. data/lib/generators/pu/gem/redis/templates/.keep +0 -0
  110. data/lib/generators/pu/gen/component/component_generator.rb +13 -10
  111. data/lib/generators/pu/gen/component/templates/component.html.erb.tt +1 -1
  112. data/lib/generators/pu/gen/component/templates/component.rb.tt +10 -4
  113. data/lib/generators/pu/lib/plutonium_generators/concerns/actions.rb +154 -32
  114. data/lib/generators/pu/lib/plutonium_generators/generator.rb +6 -6
  115. data/lib/generators/pu/lib/plutonium_generators/installer.rb +1 -1
  116. data/lib/generators/pu/pkg/app/app_generator.rb +4 -4
  117. data/lib/generators/pu/pkg/app/templates/app/controllers/concerns/controller.rb.tt +28 -0
  118. data/lib/generators/pu/pkg/app/templates/app/controllers/controller.rb.tt +5 -0
  119. data/lib/generators/pu/pkg/app/templates/app/controllers/dashboard_controller.rb.tt +1 -1
  120. data/lib/generators/pu/res/conn/conn_generator.rb +4 -4
  121. data/lib/generators/pu/res/conn/templates/app/controllers/resource_controller.rb.tt +1 -1
  122. data/lib/generators/pu/res/model/model_generator.rb +3 -3
  123. data/lib/generators/pu/res/scaffold/templates/policy.rb.tt +6 -0
  124. data/lib/generators/pu/rodauth/account_generator.rb +10 -10
  125. data/lib/generators/pu/rodauth/install_generator.rb +9 -2
  126. data/lib/generators/pu/rodauth/migration/sequel/audit_logging.erb +2 -2
  127. data/lib/generators/pu/rodauth/migration_generator.rb +1 -1
  128. data/lib/generators/pu/rodauth/templates/app/{misc → rodauth}/account_rodauth_plugin.rb.tt +2 -2
  129. data/lib/generators/pu/rodauth/templates/app/{misc → rodauth}/rodauth_plugin.rb.tt +0 -3
  130. data/lib/generators/pu/rodauth/templates/db/migrate/install_rodauth.rb.tt +5 -0
  131. data/lib/generators/pu/service/postgres/postgres_generator.rb +61 -0
  132. data/lib/generators/pu/service/postgres/templates/.keep +0 -0
  133. data/lib/generators/pu/service/postgres/templates/bin/initdb.d/create-multiple-postgresql-databases.sh +22 -0
  134. data/lib/generators/pu/service/postgres/templates/database.yml.tt +93 -0
  135. data/lib/generators/pu/service/sidekiq/sidekiq_generator.rb +57 -0
  136. data/lib/generators/pu/service/sidekiq/templates/.keep +0 -0
  137. data/lib/generators/pu/service/sidekiq/templates/app/sidekiq/sidekiq_job.rb +3 -0
  138. data/lib/generators/pu/service/sidekiq/templates/config/initializers/sidekiq.rb +53 -0
  139. data/lib/generators/pu/service/sidekiq/templates/config/sidekiq.yml +6 -0
  140. data/lib/plutonium/config.rb +2 -9
  141. data/lib/plutonium/core/associations/renderers/basic_renderer.rb +28 -0
  142. data/lib/plutonium/core/associations/renderers/factory.rb +36 -0
  143. data/lib/plutonium/core/associations/renderers/has_many_renderer.rb +16 -0
  144. data/lib/plutonium/core/autodiscovery/association_renderer_discoverer.rb +31 -0
  145. data/lib/plutonium/core/controllers/authorizable.rb +13 -17
  146. data/lib/plutonium/core/controllers/base.rb +3 -7
  147. data/lib/plutonium/core/controllers/entity_scoping.rb +3 -3
  148. data/lib/plutonium/core/controllers/presentable.rb +6 -1
  149. data/lib/plutonium/core/definers/association_renderer_definer.rb +33 -0
  150. data/lib/plutonium/core/fields/inputs/checkbox_input.rb +13 -0
  151. data/lib/plutonium/core/fields/inputs/factory.rb +1 -0
  152. data/lib/plutonium/core/fields/inputs/polymorphic_belongs_to_association_input.rb +1 -1
  153. data/lib/plutonium/core/ui/detail.rb +1 -0
  154. data/lib/plutonium/helpers/application_helper.rb +8 -9
  155. data/lib/plutonium/helpers/assets_helper.rb +33 -0
  156. data/lib/plutonium/helpers/display_helper.rb +13 -0
  157. data/lib/plutonium/helpers/form_helper.rb +1 -1
  158. data/lib/plutonium/helpers.rb +1 -0
  159. data/lib/plutonium/icons.rb +12 -5
  160. data/lib/plutonium/pkg/app.rb +10 -0
  161. data/lib/plutonium/pundit/context.rb +18 -0
  162. data/lib/plutonium/pundit/policy_finder.rb +25 -0
  163. data/lib/plutonium/railtie.rb +24 -8
  164. data/lib/plutonium/reloader.rb +18 -7
  165. data/lib/plutonium/resource/controller.rb +5 -0
  166. data/lib/plutonium/resource/policy.rb +69 -47
  167. data/lib/plutonium/resource/presenter.rb +1 -0
  168. data/lib/plutonium/resource/query_object.rb +139 -130
  169. data/lib/plutonium/rodauth/controller_methods.rb +7 -3
  170. data/lib/plutonium/version.rb +1 -1
  171. data/lib/plutonium.rb +10 -54
  172. data/lib/tasks/create_rodauth_admin.rake +16 -0
  173. data/package-lock.json +782 -17
  174. data/package.json +31 -8
  175. data/postcss.config.js +17 -7
  176. data/src/.npmignore +2 -0
  177. data/src/js/controllers/color_mode_controller.js +41 -0
  178. data/src/js/controllers/frame_navigator_controller.js +99 -0
  179. data/src/js/controllers/has_many_panel_controller.js +8 -0
  180. data/src/js/controllers/nav_grid_menu_controller.js +8 -0
  181. data/src/js/controllers/nav_grid_menu_item_controller.js +8 -0
  182. data/{app/views/components/tab_bar/tab_bar_controller.js → src/js/controllers/nav_user_controller.js} +2 -2
  183. data/src/js/controllers/nav_user_link_controller.js +8 -0
  184. data/src/js/controllers/nav_user_section_controller.js +8 -0
  185. data/src/js/controllers/register_controllers.js +45 -0
  186. data/{app/assets/javascripts → src/js}/controllers/resource_dismiss_controller.js +2 -0
  187. data/{app/assets/javascripts → src/js}/controllers/resource_drop_down_controller.js +2 -0
  188. data/src/js/controllers/resource_header_controller.js +8 -0
  189. data/src/js/controllers/resource_layout_controller.js +8 -0
  190. data/src/js/controllers/sidebar_menu_controller.js +8 -0
  191. data/src/js/controllers/sidebar_menu_item_controller.js +8 -0
  192. data/src/js/core.js +4 -0
  193. data/{app/assets/javascripts/plutonium-app.js → src/js/plutonium.js} +1 -1
  194. data/{app/assets/javascripts → src/js}/turbo/turbo_debug.js +2 -4
  195. data/tailwind.config.js +85 -84
  196. metadata +106 -41
  197. data/app/assets/build/plutonium.js +0 -5122
  198. data/app/assets/javascripts/controllers/index.js +0 -34
  199. data/app/assets/javascripts/plutonium.js +0 -1
  200. data/app/views/application/_color_modes.html.erb +0 -57
  201. data/app/views/components/tab_bar/tab_bar_component.html.erb +0 -11
  202. data/app/views/components/tab_bar/tab_bar_component.rb +0 -9
  203. data/app/views/resource/_nav_user.html.erb +0 -4
  204. data/app/views/resource/_tab_menu.html.erb +0 -13
  205. data/css.manifest +0 -3
  206. data/js.manifest +0 -4
  207. data/lib/generators/pu/pkg/app/templates/app/controllers/app_controller.rb.tt +0 -5
  208. data/lib/generators/pu/pkg/app/templates/app/controllers/package_controller.rb.tt +0 -26
  209. data/public/plutonium-assets/application.css +0 -25086
  210. data/public/plutonium-assets/plutonium-app-36KN5FVJ.js +0 -6
  211. data/public/plutonium-assets/plutonium-app-36KN5FVJ.js.map +0 -7
  212. data/public/plutonium-assets/plutonium-app-6WILQCTT.js +0 -39
  213. data/public/plutonium-assets/plutonium-app-6WILQCTT.js.map +0 -7
  214. data/public/plutonium-assets/plutonium.2d4f0c333cd000051d3b.css +0 -3424
  215. data/public/plutonium-assets/plutonium.50232e35b5495f5ad90d.css +0 -3415
  216. /data/{app/assets/build → lib/generators/pu/core/assets/templates}/.keep +0 -0
  217. /data/lib/generators/pu/rodauth/templates/app/{misc → rodauth}/rodauth_app.rb.tt +0 -0
  218. /data/{app/assets/stylesheets → src/css}/plutonium.css +0 -0
  219. /data/{app/views/components/form → src/js/controllers}/form_controller.js +0 -0
  220. /data/{app/views/components/interactive_action_form → src/js/controllers}/interactive_action_form_controller.js +0 -0
  221. /data/{app/views/components/nested_resource_form_fields → src/js/controllers}/nested_resource_form_fields_controller.js +0 -0
  222. /data/{app/views/components/table → src/js/controllers}/table_controller.js +0 -0
  223. /data/{app/views/components/table_search_input → src/js/controllers}/table_search_input_controller.js +0 -0
  224. /data/{app/views/components/table_toolbar → src/js/controllers}/table_toolbar_controller.js +0 -0
  225. /data/{app/views/components/toolbar → src/js/controllers}/toolbar_controller.js +0 -0
  226. /data/{app/assets/javascripts → src/js}/turbo/index.js +0 -0
  227. /data/{app/assets/javascripts → src/js}/turbo/turbo_actions.js +0 -0
  228. /data/{app/assets/javascripts → src/js}/turbo/turbo_frame_monkey_patch.js +0 -0
@@ -1,49 +1,33 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <title><%= page_title @page_title %></title>
5
- <meta charset="utf-8">
6
- <meta name="viewport" content="width=device-width,initial-scale=1">
1
+ <%= render_component :resource_layout, page_title: make_page_title(@page_title), lang: "en" do |layout| %>
2
+
3
+ <% layout.with_meta do %>
7
4
  <meta name="turbo-cache-control" content="no-cache">
8
5
  <meta name="turbo-refresh-method" content="morph">
9
6
  <meta name="turbo-refresh-scroll" content="preserve">
10
- <link rel="icon" type="image/x-icon" href="<%= Plutonium.favicon_link %>">
11
- <%= csrf_meta_tags %>
12
- <%= csp_meta_tag %>
13
- <%= yield(:meta) %>
7
+ <% end %>
8
+
9
+ <% layout.with_favicon do %>
10
+ <%= favicon_link_tag "plutonium.ico" %>
11
+ <% end %>
14
12
 
13
+ <% layout.with_fonts do %>
15
14
  <link rel="preconnect" href="https://fonts.googleapis.com">
16
15
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
17
16
  <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap" rel="stylesheet">
17
+ <% end %>
18
18
 
19
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.snow.min.css" integrity="sha512-/FHUK/LsH78K9XTqsR9hbzr21J8B8RwHR/r8Jv9fzry6NVAOVIGFKQCNINsbhK7a1xubVu2r5QZcz2T9cKpubw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
20
- <script src="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.min.js" integrity="sha512-P2W2rr8ikUPfa31PLBo5bcBQrsa+TNj8jiKadtaIrHQGMo6hQM6RdPjQYxlNguwHz8AwSQ28VkBK6kHBLgd/8g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
21
-
22
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/slim-select/2.6.0/slimselect.min.css" integrity="sha512-GvqWM4KWH8mbgWIyvwdH8HgjUbyZTXrCq0sjGij9fDNiXz3vJoy3jCcAaWNekH2rJe4hXVWCJKN+bEW8V7AAEQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
23
- <script src="https://cdnjs.cloudflare.com/ajax/libs/slim-select/2.6.0/slimselect.min.js" integrity="sha512-0E8oaoA2v32h26IycsmRDShtQ8kMgD91zWVBxdIvUCjU3xBw81PV61QBsBqNQpWkp/zYJZip8Ag3ifmzz1wCKQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
24
-
25
- <%= yield(:assets) %>
26
-
27
- <%== Plutonium::Config.stylesheet_tag.call self %>
28
- <%== Plutonium::Config.script_tag.call self %>
19
+ <% layout.with_assets do %>
20
+ <%= plutonium_stylesheet_tag %>
21
+ <%= plutonium_script_tag %>
22
+ <% end %>
29
23
 
30
- <%= yield(:head) %>
31
- </head>
32
- <body class="antialiased bg-gray-50 dark:bg-gray-900">
24
+ <% layout.with_header do %>
33
25
  <%= render("resource_header") %>
34
- <%= render("resource_sidebar") %>
35
- <main class="p-4 lg:ml-64 h-auto pt-20">
36
- <%= render "flash" %>
37
- <%= yield %>
38
- </main>
39
- </body>
40
- </html>
41
-
26
+ <% end %>
42
27
 
43
- <!--
44
-
45
- <%= modal_frame_tag do %>
46
- <%= yield(:modal) %>
47
- <% end %>
28
+ <% layout.with_sidebar do %>
29
+ <%= render("resource_sidebar") %>
30
+ <% end %>
48
31
 
49
- -->
32
+ <%= yield %>
33
+ <% end %>
@@ -1,31 +1,38 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <title><%= @page_title %></title>
5
- <meta charset="utf-8">
6
- <meta name="viewport" content="width=device-width,initial-scale=1">
1
+ <%= render_component :resource_layout, page_title: @page_title,
2
+ lang: "en",
3
+ main_classname: "flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0" do |layout| %>
4
+
5
+ <% layout.with_meta do %>
7
6
  <meta name="turbo-cache-control" content="no-cache">
8
7
  <meta name="turbo-refresh-method" content="morph">
9
8
  <meta name="turbo-refresh-scroll" content="preserve">
10
- <%= csrf_meta_tags %>
11
- <%= csp_meta_tag %>
9
+ <% end %>
10
+
11
+ <% layout.with_favicon do %>
12
+ <%= favicon_link_tag "plutonium.ico" %>
13
+ <% end %>
14
+
15
+ <% layout.with_fonts do %>
12
16
  <link rel="preconnect" href="https://fonts.googleapis.com">
13
17
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
14
18
  <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap" rel="stylesheet">
15
- <%== Plutonium::Config.stylesheet_tag.call self %>
16
- <%== Plutonium::Config.script_tag.call self %>
17
- </head>
18
- <body class="antialiased bg-gray-50 dark:bg-gray-900">
19
- <main div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0">
20
- <p class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white">
21
- <img class="w-16 h-16 mr-2" src="<%= Plutonium.logo_link %>" alt="logo">
22
- <%= application_name %>
23
- </p>
24
- <div class="w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700">
25
- <div class="p-6 space-y-4 md:space-y-6 sm:p-8">
26
- <%= yield %>
27
- </div>
28
- </div>
29
- </main>
30
- </body>
31
- </html>
19
+ <% end %>
20
+
21
+ <% layout.with_assets do %>
22
+ <%= plutonium_stylesheet_tag %>
23
+ <%= plutonium_script_tag %>
24
+ <% end %>
25
+
26
+ <p class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white">
27
+ <%= logo_tag classname: "w-24 h-24 mr-2" %>
28
+ </p>
29
+ <div class="w-full max-w-md bg-white rounded-lg shadow dark:border md:mt-0 xl:p-0 dark:bg-gray-800 dark:border-gray-700">
30
+ <div class="w-full p-6 space-y-4 md:space-y-6 sm:p-8">
31
+ <%= yield %>
32
+ </div>
33
+ </div>
34
+ <div class="mt-4 flex items-center font-medium text-blue-600 dark:text-blue-500 hover:underline">
35
+ <%= Plutonium::Icons.render "outline/home" %>
36
+ <%= link_to "Home", root_path, class: "font-medium text-blue-600 dark:text-blue-500" %>
37
+ </div>
38
+ <% end %>
@@ -2,7 +2,7 @@
2
2
 
3
3
  <% if current_turbo_frame == 'modal' %>
4
4
  <%= turbo_frame_tag "modal" do %>
5
- <div class="modal " tabindex="-1" data-controller="modal">
5
+ <div class="modal" tabindex="-1" data-controller="modal">
6
6
  <div class="modal-dialog modal-dialog-scrollable modal-lg">
7
7
  <%= resource_form_for @interaction, as: :interaction,
8
8
  method: :post,
@@ -5,22 +5,25 @@
5
5
  actions: details.actions.record_actions.permitted_for(policy(details.record))
6
6
  %>
7
7
 
8
-
9
8
  <%= render_component :block, rounded: :all do %>
10
-
11
9
  <div class="p-4">
12
10
  <dl class="divide-y divide-gray-100">
13
- <% details.fields.each do |name, field| %>
11
+ <% details.fields.each do |name, renderer| %>
14
12
  <div class="py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
15
13
  <dt class="text-sm font-medium leading-6 text-gray-900 dark:text-gray-300">
16
- <%= field.label %>
14
+ <%= renderer.label %>
17
15
  </dt>
18
16
  <dd class="mt-1 text-sm leading-6 text-gray-700 dark:text-gray-200 sm:col-span-2 sm:mt-0">
19
- <%= field.render self, details.record %>
17
+ <%= renderer.render self, details.record %>
20
18
  </dd>
21
19
  </div>
22
20
  <% end %>
23
21
  </dl>
24
22
  </div>
23
+ <% end %>
25
24
 
25
+ <% if present_associations? %>
26
+ <% details.associations.each do |name, renderer| %>
27
+ <%= renderer.render self, details.record %>
28
+ <% end %>
26
29
  <% end %>
@@ -8,8 +8,77 @@
8
8
  fields = collection.fields
9
9
  pager = collection.pager
10
10
  collection_actions = @collection.actions.collection_actions.permitted_for(current_policy)
11
+ table_rounding = search_object.scope_definitions.present? ? :bottom : :all
11
12
  -%>
12
13
 
13
14
  <%= render_component :table_toolbar, resource_class:, search_object:, actions: collection_actions %>
14
15
 
15
- <%= render_component :table, resource_class:, resources:, record_actions:, search_object:, fields:, pager: %>
16
+ <% if search_object.scope_definitions.present? %>
17
+ <%
18
+ name = name.to_s
19
+ current_scope = resource_query_params[:scope]
20
+ %>
21
+ <%= render_component :block, rounded: :top do %>
22
+ <ul class="text-sm font-medium flex flex-wrap -mb-px">
23
+ <li class="me-2">
24
+ <% if current_scope.blank? %>
25
+ <a class="inline-block p-4 text-primary-600 border-b-2 border-primary-600 rounded-t-lg active dark:text-primary-500 dark:border-primary-500" aria-current="page" href="?<%= search_object.build_url(scope: nil) %>">All</a>
26
+ <% else %>
27
+ <a class="inline-block p-4 border-b-2 border-transparent rounded-t-lg hover:text-gray-600 hover:border-gray-300 dark:hover:text-gray-300 dark:text-gray-500" href="<%= search_object.build_url(scope: nil) %>">All</a>
28
+ <% end %>
29
+ </li>
30
+
31
+ <% search_object.scope_definitions.each do |name, definition| %>
32
+ <li class="me-2">
33
+ <% if name == current_scope %>
34
+ <a class="inline-block p-4 text-primary-600 border-b-2 border-primary-600 rounded-t-lg active dark:text-primary-500 dark:border-primary-500" aria-current="page" href="?<%= search_object.build_url(scope: name) %>"><%= name.humanize %></a>
35
+ <% else %>
36
+ <a class="inline-block p-4 border-b-2 border-transparent rounded-t-lg hover:text-gray-600 hover:border-gray-300 dark:hover:text-gray-300 dark:text-gray-500" href="<%= search_object.build_url(scope: name) %>"><%= name.humanize %></a>
37
+ <% end %>
38
+ </li>
39
+ <% end %>
40
+ </ul>
41
+ <% end %>
42
+ <% end %>
43
+
44
+ <%= render_component :block, id: "resource-table-container",
45
+ scroll: :x,
46
+ rounded: table_rounding,
47
+ data: {
48
+ controller:"scroll-preserver",
49
+ action: "scroll->scroll-preserver#scrolled"
50
+ } do %>
51
+ <% unless resources.any? %>
52
+ <%# empty card %>
53
+ <div class="col-12">
54
+ <%=
55
+ render_component :empty_card, message: "No #{resource_name_plural(resource_class).downcase} match your query" do
56
+ if current_policy.create?
57
+ render_component :button, label: "Create #{resource_name(resource_class)}",
58
+ to: resource_url_for(resource_class, action: :new),
59
+ color: :primary
60
+ end
61
+ end
62
+ %>
63
+ </div>
64
+ <% else %>
65
+ <%# table %>
66
+ <%= render_component :table, rows: resources do |table| %>
67
+ <% table.with_actions do |resource| %>
68
+ <% record_actions.permitted_for(policy(resource)).values.each do |action| %>
69
+ <%= table_action_button resource, action %>
70
+ <% end %>
71
+ <% end %>
72
+
73
+ <% fields.each do |name, field| %>
74
+ <% table.column(name:, label: field.label, search_object: search_object) do |resource| %>
75
+ <%= field.render self, resource %>
76
+ <% end %>
77
+ <% end %>
78
+ <% end %>
79
+ <%# pagination %>
80
+ <% if pager.present? %>
81
+ <%= render_component :pagination, pager: pager %>
82
+ <% end %>
83
+ <% end %>
84
+ <% end %>
@@ -1,4 +1,5 @@
1
1
  <%= render_component :breadcrumbs, resource_class:, parent: current_parent, resource: resource_record %>
2
+
2
3
  <%= render_component :dyna_frame_content do %>
3
4
  <%= render "interactive_resource_action_form", interactive_action: current_interactive_action %>
4
5
  <% end %>
@@ -1,4 +1,5 @@
1
1
  <%= render_component :breadcrumbs, resource_class:, parent: current_parent, resource: resource_record %>
2
+
2
3
  <%= render_component :dyna_frame_content do %>
3
4
  <%= render "interactive_resource_action_form", interactive_action: current_interactive_action %>
4
5
  <% end %>
@@ -1,4 +1,5 @@
1
1
  <%= render_component :breadcrumbs, resource_class:, parent: current_parent, resource: resource_record %>
2
+
2
3
  <%= render_component :dyna_frame_content do %>
3
4
  <%= render "interactive_resource_action_form", interactive_action: current_interactive_action %>
4
5
  <% end %>
@@ -1,4 +1,5 @@
1
1
  <%= render_component :breadcrumbs, resource_class:, parent: current_parent, resource: @form.record %>
2
+
2
3
  <%= render_component :dyna_frame_content do %>
3
4
  <%= render "resource_form", form: @form %>
4
5
  <% end %>
@@ -1,16 +1,17 @@
1
1
  <div>
2
- <% if rodauth.recovery_codes.any? %>
3
- <div class="text-sm px-4 py-3 bg-white rounded-lg border shadow-lg grid grid-cols-2 gap-y-2 gap-x-4 dark:bg-gray-900 dark:text-gray-200">
2
+ <h4 class="text-2xl font-bold dark:text-white mb-4">Recovery Codes</h4>
3
+
4
+ <div class="mb-4 text-sm grid grid-cols-1 gap-y-2 gap-x-4 dark:bg-gray-900 dark:text-gray-200">
5
+ <% if rodauth.recovery_codes.any? %>
4
6
  <% rodauth.recovery_codes.each do |code| %>
5
7
  <div class="font-mono"><%= code %></div>
6
8
  <% end %>
7
- </div>
8
- <% end %>
9
+ <% else %>
10
+ <div class="font-mono">You have no recovery codes</div>
11
+ <% end %>
12
+ </div>
9
13
 
10
14
  <% if rodauth.can_add_recovery_codes? %>
11
- <div class="text-2xl font-medium mt-6 mb-4">
12
- <%== rodauth.add_recovery_codes_heading %>
13
- </div>
14
15
  <%= render template: "rodauth/recovery_codes", layout: false %>
15
16
  <% end %>
16
17
  </div>
@@ -1,7 +1,7 @@
1
1
  <%= form_with url: rodauth.otp_auth_path, method: :post, data: { turbo: false }, class: "w-full max-w-sm" do |form| %>
2
2
  <div class="mb-6">
3
3
  <%= form.label "otp-auth-code", rodauth.otp_auth_label, class: "block text-sm font-semibold" %>
4
- <%= form.text_field rodauth.otp_auth_param, value: "", id: "otp-auth-code", autocomplete: "off", inputmode: "numeric", required: true, class: "mt-2 text-sm w-1/2 px-3 py-2 border rounded-md dark:bg-gray-900 dark:text-gray-100 dark:focus:bg-gray-800 #{rodauth.field_error(rodauth.otp_auth_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }", aria: ({ invalid: true, describedby: "otp-auth-code_error_message" } if rodauth.field_error(rodauth.otp_auth_param)) %>
4
+ <%= form.text_field rodauth.otp_auth_param, value: "", id: "otp-auth-code", autocomplete: "off", inputmode: "numeric", required: true, class: "mt-2 text-sm w-full px-3 py-2 border rounded-md dark:bg-gray-900 dark:text-gray-100 dark:focus:bg-gray-800 #{rodauth.field_error(rodauth.otp_auth_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }", aria: ({ invalid: true, describedby: "otp-auth-code_error_message" } if rodauth.field_error(rodauth.otp_auth_param)) %>
5
5
  <%= content_tag(:span, rodauth.field_error(rodauth.otp_auth_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "otp-auth-code_error_message") if rodauth.field_error(rodauth.otp_auth_param) %>
6
6
  </div>
7
7
 
@@ -2,8 +2,10 @@
2
2
  <%= form.hidden_field rodauth.otp_setup_param, value: rodauth.otp_user_key, id: "otp-key" %>
3
3
  <%= form.hidden_field rodauth.otp_setup_raw_param, value: rodauth.otp_key, id: "otp-hmac-secret" if rodauth.otp_keys_use_hmac? %>
4
4
 
5
- <div class="mb-6 w-48">
6
- <%== rodauth.otp_qr_code %>
5
+ <div class="mb-6 flex items-center justify-center">
6
+ <div class="w-48">
7
+ <%== rodauth.otp_qr_code %>
8
+ </div>
7
9
  </div>
8
10
 
9
11
  <dl class="mb-6 text-sm">
@@ -14,6 +16,12 @@
14
16
  <dd><%= rodauth.otp_provisioning_uri %></dd>
15
17
  </dl>
16
18
 
19
+ <div class="mb-6">
20
+ <%= form.label "otp-auth-code", rodauth.otp_auth_label, class: "block text-sm font-semibold" %>
21
+ <%= form.text_field rodauth.otp_auth_param, value: "", id: "otp-auth-code", autocomplete: "off", inputmode: "numeric", required: true, class: "mt-2 text-sm w-full px-3 py-2 border rounded-md dark:bg-gray-900 dark:text-gray-100 dark:focus:bg-gray-800 #{rodauth.field_error(rodauth.otp_auth_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }" , aria: ({ invalid: true, describedby: "otp-auth-code_error_message" } if rodauth.field_error(rodauth.otp_auth_param)) %>
22
+ <%= content_tag(:span, rodauth.field_error(rodauth.otp_auth_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "otp-auth-code_error_message") if rodauth.field_error(rodauth.otp_auth_param) %>
23
+ </div>
24
+
17
25
  <% if rodauth.two_factor_modifications_require_password? %>
18
26
  <div class="mb-6">
19
27
  <%= form.label "password", rodauth.password_label, class: "block text-sm font-semibold" %>
@@ -22,11 +30,5 @@
22
30
  </div>
23
31
  <% end %>
24
32
 
25
- <div class="mb-6">
26
- <%= form.label "otp-auth-code", rodauth.otp_auth_label, class: "block text-sm font-semibold" %>
27
- <%= form.text_field rodauth.otp_auth_param, value: "", id: "otp-auth-code", autocomplete: "off", inputmode: "numeric", required: true, class: "mt-2 text-sm w-1/2 px-3 py-2 border rounded-md dark:bg-gray-900 dark:text-gray-100 dark:focus:bg-gray-800 #{rodauth.field_error(rodauth.otp_auth_param) ? "border-red-600 focus:ring-red-600 focus:border-red-600 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 dark:border-gray-700 dark:focus:border-emerald-400 dark:focus:ring-emerald-400" }", aria: ({ invalid: true, describedby: "otp-auth-code_error_message" } if rodauth.field_error(rodauth.otp_auth_param)) %>
28
- <%= content_tag(:span, rodauth.field_error(rodauth.otp_auth_param), class: "block mt-1 text-red-600 text-xs dark:text-red-400", id: "otp-auth-code_error_message") if rodauth.field_error(rodauth.otp_auth_param) %>
29
- </div>
30
-
31
33
  <%= form.submit rodauth.otp_setup_button, class: "w-full px-8 py-3 cursor-pointer font-semibold text-sm rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-600 dark:bg-emerald-400 dark:hover:bg-emerald-500 dark:text-gray-900 dark:focus:ring-emerald-400 dark:focus:ring-offset-current" %>
32
34
  <% end %>
@@ -21,7 +21,7 @@ SimpleForm.setup do |config|
21
21
  b.use :label, class: "md:w-1/6 mt-2 text-sm font-medium"
22
22
 
23
23
  b.wrapper tag: :div, html: {class: "md:w-5/6 w-full"} do |ba|
24
- ba.use :input, class: "w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-primary-500 focus:border-primary-500 font-medium text-sm dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white ",
24
+ ba.use :input, class: "w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-primary-500 focus:border-primary-500 font-medium text-sm dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white",
25
25
  error_class: "bg-red-50 border border-red-500 text-red-900 placeholder-red-700 rounded-lg focus:ring-red-500 dark:bg-gray-700 focus:border-red-500 dark:text-red-500 dark:placeholder-red-500 dark:border-red-500",
26
26
  valid_class: "bg-green-50 border border-green-500 text-green-900 dark:text-green-400 placeholder-green-700 dark:placeholder-green-500 rounded-lg focus:ring-green-500 focus:border-green-500 dark:bg-gray-700 dark:border-green-500"
27
27
  ba.use :full_error, wrap_with: {tag: "p", class: "mt-2 text-sm text-red-600 dark:text-red-500"}
@@ -43,7 +43,7 @@ SimpleForm.setup do |config|
43
43
 
44
44
  b.wrapper tag: :div, html: {class: "md:w-5/6 w-full"} do |ba|
45
45
  ba.wrapper tag: :div, html: {class: "flex gap-2 flex-col md:flex-row items-center"} do |bc|
46
- bc.use :input, class: "w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-primary-500 focus:border-primary-500 font-medium text-sm dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white ",
46
+ bc.use :input, class: "w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-primary-500 focus:border-primary-500 font-medium text-sm dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white",
47
47
  error_class: "bg-red-50 border border-red-500 text-red-900 placeholder-red-700 rounded-lg focus:ring-red-500 dark:bg-gray-700 focus:border-red-500 dark:text-red-500 dark:placeholder-red-500 dark:border-red-500",
48
48
  valid_class: "bg-green-50 border border-green-500 text-green-900 dark:text-green-400 placeholder-green-700 dark:placeholder-green-500 rounded-lg focus:ring-green-500 focus:border-green-500 dark:bg-gray-700 dark:border-green-500"
49
49
  end
@@ -51,4 +51,24 @@ SimpleForm.setup do |config|
51
51
  ba.use :hint, wrap_with: {tag: "p", class: "mt-2 text-sm text-gray-500 dark:text-gray-200"}
52
52
  end
53
53
  end
54
+
55
+ config.wrappers :resource_checkbox, class: "flex flex-col md:flex-row items-start space-y-2 md:space-y-0 md:space-x-2 mb-4" do |b|
56
+ b.use :html5
57
+ b.use :placeholder
58
+ b.use :maxlength
59
+ b.use :minlength
60
+ b.optional :pattern
61
+ b.use :min_max
62
+ b.optional :readonly
63
+
64
+ b.use :label, class: "md:w-1/6 mt-2 text-sm font-medium"
65
+
66
+ b.wrapper tag: :div, html: {class: "md:w-5/6 w-full"} do |ba|
67
+ ba.use :input, class: "w-4 h-4 text-primary-600 bg-gray-100 border-gray-300 rounded focus:ring-primary-500 focus:ring-2 dark:bg-gray-700 dark:border-gray-600",
68
+ error_class: "bg-red-50 border border-red-500 text-red-900 placeholder-red-700 rounded focus:ring-red-500 dark:bg-gray-700 focus:border-red-500 dark:text-red-500 dark:placeholder-red-500 dark:border-red-500",
69
+ valid_class: "bg-green-50 border border-green-500 text-green-900 dark:text-green-400 placeholder-green-700 dark:placeholder-green-500 rounded focus:ring-green-500 focus:border-green-500 dark:bg-gray-700 dark:border-green-500"
70
+ ba.use :full_error, wrap_with: {tag: "p", class: "mt-2 text-sm text-red-600 dark:text-red-500"}
71
+ ba.use :hint, wrap_with: {tag: "p", class: "mt-2 text-sm text-gray-500 dark:text-gray-200"}
72
+ end
73
+ end
54
74
  end
data/esbuild.config.js CHANGED
@@ -1,44 +1,48 @@
1
- const esbuild = require('esbuild');
2
- const manifestPlugin = require('esbuild-plugin-manifest')
1
+ import { context as _context, build as _build } from 'esbuild';
2
+ import manifestPlugin from 'esbuild-plugin-manifest';
3
3
 
4
4
 
5
- if (process.argv.includes("--prod")) {
6
- esbuild.build({
7
- outdir: "public/plutonium-assets",
5
+ if (process.argv.includes("--dev")) {
6
+ _context({
7
+ outdir: "src/build",
8
8
  entryPoints: [
9
- "app/assets/javascripts/plutonium-app.js"
9
+ "src/js/plutonium.js"
10
10
  ],
11
11
  plugins: [
12
12
  manifestPlugin({
13
- filename: `${__dirname}/js.manifest`,
13
+ filename: `js.manifest`,
14
14
  shortNames: true,
15
15
  })
16
16
  ],
17
- minify: true,
18
- sourcemap: true,
19
17
  bundle: true,
20
- })
21
-
22
- esbuild.build({
23
- outdir: "app/assets/build",
24
- entryPoints: [
25
- "app/assets/javascripts/plutonium.js"
26
- ],
27
- bundle: true,
28
- })
18
+ }).then((context) => context.watch().catch((e) => console.error(e.message)))
29
19
  }
30
20
  else {
31
- esbuild.context({
32
- outdir: "public/plutonium-assets/build",
33
- entryPoints: [
34
- "app/assets/javascripts/plutonium-app.js"
35
- ],
36
- plugins: [
37
- manifestPlugin({
38
- filename: `${__dirname}/js.dev.manifest`,
39
- shortNames: true,
40
- })
41
- ],
42
- bundle: true,
43
- }).then((context) => context.watch().catch((e) => console.error(e.message)))
21
+ function build(minify) {
22
+ const outExtension = minify ? { '.js': '.min.js' } : { '.js': '.js' }
23
+ _build({
24
+ outdir: "src/dist/js",
25
+ entryPoints: [
26
+ "src/js/plutonium.js",
27
+ ],
28
+ minify,
29
+ sourcemap: true,
30
+ bundle: true,
31
+ outExtension
32
+ }).catch(() => process.exit(1));
33
+
34
+ _build({
35
+ outdir: "app/assets",
36
+ entryPoints: [
37
+ "src/js/plutonium.js"
38
+ ],
39
+ minify,
40
+ sourcemap: true,
41
+ bundle: true,
42
+ outExtension
43
+ }).catch(() => process.exit(1));
44
+ }
45
+
46
+ build(true)
47
+ build(false)
44
48
  }
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../lib/plutonium_generators"
4
+
5
+ module Pu
6
+ module Core
7
+ class AssetsGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Setup plutonium assets"
13
+
14
+ def start
15
+ install_dependencies
16
+ copy_tailwind_config
17
+ configure_application
18
+ rescue => e
19
+ exception "#{self.class} failed:", e
20
+ end
21
+
22
+ private
23
+
24
+ def copy_tailwind_config
25
+ copy_file "tailwind.config.js"
26
+ end
27
+
28
+ def install_dependencies
29
+ `yarn add @radioactive-labs/plutonium`
30
+ end
31
+
32
+ def configure_application
33
+ insert_into_file "app/javascript/controllers/index.js", <<~EOT
34
+
35
+ import { registerControllers } from "@radioactive-labs/plutonium"
36
+ registerControllers(application)
37
+ EOT
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ const { execSync } = require('child_process');
2
+ const plutoniumGemPath = execSync("bundle show plutonium").toString().trim();
3
+ const plutoniumTailwindConfig = require(`${plutoniumGemPath}/tailwind.config.js`)
4
+
5
+ module.exports = {
6
+ darkMode: plutoniumTailwindConfig.darkMode,
7
+ plugins: [
8
+ // add plugins here
9
+ ].concat(plutoniumTailwindConfig.plugins),
10
+ theme: plutoniumTailwindConfig.theme,
11
+ content: [
12
+ `${__dirname}/app/views/**/*.html.erb`,
13
+ `${__dirname}/app/helpers/**/*.rb`,
14
+ `${__dirname}/app/assets/stylesheets/**/*.css`,
15
+ `${__dirname}/app/javascript/**/*.js`,
16
+ `${__dirname}/packages/**/app/views/**/*.html.erb`,
17
+ ].concat(plutoniumTailwindConfig.content),
18
+ }
@@ -1 +1,4 @@
1
1
  # Configure plutonium
2
+
3
+ # # set a custom global logo
4
+ # Plutonium::Config.logo = "custom-logo.png"
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../lib/plutonium_generators"
4
+
5
+ module Pu
6
+ module Core
7
+ class RubyGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Set ruby version for project"
13
+ class_option :version, type: :string, desc: "Ruby version", default: "3.3.0"
14
+
15
+ def start
16
+ set_ruby_version! version
17
+ say "Ruby version set to #{version}"
18
+ say "Run `bundle install` to update your dependencies"
19
+ rescue => e
20
+ exception "#{self.class} failed:", e
21
+ end
22
+
23
+ private
24
+
25
+ def version
26
+ options[:version]
27
+ end
28
+ end
29
+ end
30
+ end
File without changes
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../lib/plutonium_generators"
4
+
5
+ module Pu
6
+ module Docker
7
+ class InstallGenerator < Rails::Generators::Base
8
+ include PlutoniumGenerators::Generator
9
+
10
+ source_root File.expand_path("templates", __dir__)
11
+
12
+ desc "Set up docker for project"
13
+
14
+ def start
15
+ in_root do
16
+ template "Dockerfile", force: true
17
+ template "Dockerfile.dev", force: true
18
+ template "docker-compose.yml", force: true
19
+ proc_file :web, "env RUBY_DEBUG_OPEN=true bin/rails server -b '0.0.0.0'", env: :dev
20
+ bin_directory
21
+ gitignore ".volumes"
22
+ dockerignore ".volumes"
23
+ end
24
+ rescue => e
25
+ exception "#{self.class} failed:", e
26
+ end
27
+
28
+ private
29
+
30
+ def ruby_version
31
+ @ruby_version ||= File.read(".ruby-version").strip
32
+ end
33
+ end
34
+ end
35
+ end
File without changes