plutonium 0.10.3 → 0.11.1

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 (185) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -2
  3. data/app/assets/application.js.bk +31419 -0
  4. data/app/assets/plutonium-original.png +0 -0
  5. data/app/assets/plutonium-white.png +0 -0
  6. data/app/assets/plutonium.css +1 -0
  7. data/app/assets/plutonium.ico +0 -0
  8. data/app/assets/plutonium.js +12416 -0
  9. data/app/assets/plutonium.js.map +7 -0
  10. data/app/assets/plutonium.min.js +39 -0
  11. data/app/assets/plutonium.min.js.map +7 -0
  12. data/app/assets/plutonium.png +0 -0
  13. data/app/views/application/_flash_alerts.html.erb +2 -2
  14. data/app/views/application/_resource_header.html.erb +261 -697
  15. data/app/views/application/_resource_sidebar.html.erb +14 -12
  16. data/app/views/components/action_button/action_button_component.rb +3 -3
  17. data/app/views/components/attributes.rb +184 -0
  18. data/app/views/components/base.rb +19 -40
  19. data/app/views/components/block/block_component.html.erb +1 -1
  20. data/app/views/components/block/block_component.rb +11 -7
  21. data/app/views/components/breadcrumbs/breadcrumbs_component.rb +3 -3
  22. data/app/views/components/button/button_component.html.erb +2 -2
  23. data/app/views/components/button/button_component.rb +10 -5
  24. data/app/views/components/dyna_frame_content/dyna_frame_content_component.html.erb +1 -0
  25. data/app/views/components/dyna_frame_content/dyna_frame_content_component.rb +3 -3
  26. data/app/views/components/dyna_frame_host/dyna_frame_host_component.html.erb +1 -2
  27. data/app/views/components/dyna_frame_host/dyna_frame_host_component.rb +12 -5
  28. data/app/views/components/empty_card/empty_card_component.rb +3 -3
  29. data/app/views/components/form/form_builder.rb +1 -1
  30. data/app/views/components/form/form_component.rb +3 -3
  31. data/app/views/components/has_many_panel/has_many_panel_component.html.erb +25 -0
  32. data/app/views/components/has_many_panel/has_many_panel_component.rb +16 -0
  33. data/app/views/components/header/header_component.rb +3 -3
  34. data/app/views/components/interactive_action_form/interactive_action_form_component.rb +3 -3
  35. data/app/views/components/nav_grid_menu/nav_grid_menu_component.html.erb +24 -0
  36. data/app/views/components/nav_grid_menu/nav_grid_menu_component.rb +23 -0
  37. data/app/views/components/nav_grid_menu_item/nav_grid_menu_item_component.html.erb +4 -0
  38. data/app/views/components/nav_grid_menu_item/nav_grid_menu_item_component.rb +20 -0
  39. data/app/views/components/nav_user/nav_user_component.html.erb +50 -0
  40. data/app/views/components/nav_user/nav_user_component.rb +32 -0
  41. data/app/views/components/nav_user_link/nav_user_link_component.html.erb +7 -0
  42. data/app/views/components/nav_user_link/nav_user_link_component.rb +23 -0
  43. data/app/views/components/nav_user_section/nav_user_section_component.html.erb +7 -0
  44. data/app/views/components/nav_user_section/nav_user_section_component.rb +18 -0
  45. data/app/views/components/nested_resource_form_fields/nested_resource_form_fields_component.html.erb +1 -3
  46. data/app/views/components/nested_resource_form_fields/nested_resource_form_fields_component.rb +11 -5
  47. data/app/views/components/pagination/pagination_component.html.erb +1 -1
  48. data/app/views/components/pagination/pagination_component.rb +10 -7
  49. data/app/views/components/panel/panel_component.html.erb +13 -6
  50. data/app/views/components/panel/panel_component.rb +11 -5
  51. data/app/views/components/resource_header/resource_header_component.html.erb +83 -0
  52. data/app/views/components/resource_header/resource_header_component.rb +30 -0
  53. data/app/views/components/resource_layout/resource_layout_component.html.erb +49 -0
  54. data/app/views/components/resource_layout/resource_layout_component.rb +41 -0
  55. data/app/views/components/sidebar/sidebar_component.html.erb +3 -33
  56. data/app/views/components/sidebar/sidebar_component.rb +3 -3
  57. data/app/views/components/sidebar_menu/sidebar_menu_component.html.erb +4 -2
  58. data/app/views/components/sidebar_menu/sidebar_menu_component.rb +10 -6
  59. data/app/views/components/sidebar_menu_item/sidebar_menu_item_component.html.erb +63 -71
  60. data/app/views/components/sidebar_menu_item/sidebar_menu_item_component.rb +27 -8
  61. data/app/views/components/skeleton/table/table_component.html.erb +1 -1
  62. data/app/views/components/skeleton/table/table_component.rb +3 -3
  63. data/app/views/components/table/table_component.html.erb +40 -89
  64. data/app/views/components/table/table_component.rb +124 -28
  65. data/app/views/components/table_search_input/table_search_input_component.html.erb +1 -1
  66. data/app/views/components/table_search_input/table_search_input_component.rb +11 -6
  67. data/app/views/components/table_toolbar/table_toolbar_component.html.erb +1 -1
  68. data/app/views/components/table_toolbar/table_toolbar_component.rb +11 -3
  69. data/app/views/components/toolbar/toolbar_component.html.erb +2 -2
  70. data/app/views/components/toolbar/toolbar_component.rb +16 -8
  71. data/app/views/layouts/resource.html.erb +12 -45
  72. data/app/views/layouts/rodauth.html.erb +20 -36
  73. data/app/views/resource/_interactive_resource_action_form.html.erb +1 -1
  74. data/app/views/resource/_resource_details.html.erb +8 -5
  75. data/app/views/resource/_resource_table.html.erb +70 -1
  76. data/app/views/resource/interactive_resource_collection_action.html.erb +1 -0
  77. data/app/views/resource/interactive_resource_record_action.html.erb +1 -0
  78. data/app/views/resource/interactive_resource_recordless_action.html.erb +1 -0
  79. data/app/views/resource/new.html.erb +1 -0
  80. data/config/initializers/simple_form.rb +22 -2
  81. data/esbuild.config.js +35 -31
  82. data/lib/generators/pu/core/assets/assets_generator.rb +44 -0
  83. data/lib/generators/pu/core/assets/templates/tailwind.config.js +18 -0
  84. data/lib/generators/pu/core/install/install_generator.rb +4 -1
  85. data/lib/generators/pu/gem/dotenv/templates/config/initializers/001_ensure_required_env.rb +6 -0
  86. data/lib/generators/pu/gen/component/component_generator.rb +13 -10
  87. data/lib/generators/pu/gen/component/templates/component.html.erb.tt +1 -1
  88. data/lib/generators/pu/gen/component/templates/component.rb.tt +10 -4
  89. data/lib/generators/pu/pkg/app/app_generator.rb +4 -4
  90. data/lib/generators/pu/pkg/app/templates/app/controllers/concerns/controller.rb.tt +28 -0
  91. data/lib/generators/pu/pkg/app/templates/app/controllers/controller.rb.tt +5 -0
  92. data/lib/generators/pu/pkg/app/templates/app/controllers/dashboard_controller.rb.tt +1 -1
  93. data/lib/generators/pu/res/conn/conn_generator.rb +4 -4
  94. data/lib/generators/pu/res/conn/templates/app/controllers/resource_controller.rb.tt +1 -1
  95. data/lib/generators/pu/res/model/model_generator.rb +3 -3
  96. data/lib/generators/pu/res/scaffold/templates/policy.rb.tt +6 -0
  97. data/lib/generators/pu/service/sidekiq/sidekiq_generator.rb +0 -5
  98. data/lib/generators/pu/service/sidekiq/templates/app/sidekiq/sidekiq_job.rb +0 -2
  99. data/lib/plutonium/config.rb +2 -14
  100. data/lib/plutonium/core/associations/renderers/basic_renderer.rb +28 -0
  101. data/lib/plutonium/core/associations/renderers/factory.rb +36 -0
  102. data/lib/plutonium/core/associations/renderers/has_many_renderer.rb +16 -0
  103. data/lib/plutonium/core/autodiscovery/association_renderer_discoverer.rb +31 -0
  104. data/lib/plutonium/core/controllers/authorizable.rb +13 -17
  105. data/lib/plutonium/core/controllers/base.rb +3 -7
  106. data/lib/plutonium/core/controllers/presentable.rb +6 -1
  107. data/lib/plutonium/core/definers/association_renderer_definer.rb +33 -0
  108. data/lib/plutonium/core/fields/inputs/checkbox_input.rb +13 -0
  109. data/lib/plutonium/core/fields/inputs/factory.rb +1 -0
  110. data/lib/plutonium/core/fields/inputs/polymorphic_belongs_to_association_input.rb +1 -1
  111. data/lib/plutonium/core/ui/detail.rb +1 -0
  112. data/lib/plutonium/helpers/application_helper.rb +8 -9
  113. data/lib/plutonium/helpers/assets_helper.rb +41 -0
  114. data/lib/plutonium/helpers/display_helper.rb +13 -0
  115. data/lib/plutonium/helpers/form_helper.rb +1 -1
  116. data/lib/plutonium/helpers.rb +1 -0
  117. data/lib/plutonium/icons.rb +12 -5
  118. data/lib/plutonium/pkg/app.rb +10 -0
  119. data/lib/plutonium/pundit/context.rb +18 -0
  120. data/lib/plutonium/pundit/policy_finder.rb +25 -0
  121. data/lib/plutonium/railtie.rb +26 -8
  122. data/lib/plutonium/reloader.rb +18 -7
  123. data/lib/plutonium/resource/controller.rb +4 -0
  124. data/lib/plutonium/resource/policy.rb +69 -47
  125. data/lib/plutonium/resource/presenter.rb +1 -0
  126. data/lib/plutonium/resource/query_object.rb +139 -130
  127. data/lib/plutonium/rodauth/controller_methods.rb +7 -3
  128. data/lib/plutonium/version.rb +1 -1
  129. data/lib/plutonium.rb +9 -57
  130. data/package-lock.json +782 -17
  131. data/package.json +31 -8
  132. data/postcss.config.js +17 -7
  133. data/src/.npmignore +2 -0
  134. data/src/js/controllers/color_mode_controller.js +41 -0
  135. data/src/js/controllers/frame_navigator_controller.js +99 -0
  136. data/src/js/controllers/has_many_panel_controller.js +8 -0
  137. data/src/js/controllers/nav_grid_menu_controller.js +8 -0
  138. data/src/js/controllers/nav_grid_menu_item_controller.js +8 -0
  139. data/{app/views/components/tab_bar/tab_bar_controller.js → src/js/controllers/nav_user_controller.js} +2 -2
  140. data/src/js/controllers/nav_user_link_controller.js +8 -0
  141. data/src/js/controllers/nav_user_section_controller.js +8 -0
  142. data/src/js/controllers/register_controllers.js +45 -0
  143. data/{app/assets/javascripts → src/js}/controllers/resource_dismiss_controller.js +2 -0
  144. data/{app/assets/javascripts → src/js}/controllers/resource_drop_down_controller.js +2 -0
  145. data/src/js/controllers/resource_header_controller.js +8 -0
  146. data/src/js/controllers/resource_layout_controller.js +8 -0
  147. data/src/js/controllers/sidebar_menu_controller.js +8 -0
  148. data/src/js/controllers/sidebar_menu_item_controller.js +8 -0
  149. data/src/js/core.js +4 -0
  150. data/{app/assets/javascripts/plutonium-app.js → src/js/plutonium.js} +1 -1
  151. data/{app/assets/javascripts → src/js}/turbo/turbo_debug.js +2 -4
  152. data/tailwind.config.js +85 -84
  153. metadata +73 -39
  154. data/app/assets/build/plutonium.js +0 -5122
  155. data/app/assets/javascripts/controllers/index.js +0 -34
  156. data/app/assets/javascripts/plutonium.js +0 -1
  157. data/app/views/application/_color_modes.html.erb +0 -57
  158. data/app/views/components/tab_bar/tab_bar_component.html.erb +0 -11
  159. data/app/views/components/tab_bar/tab_bar_component.rb +0 -9
  160. data/app/views/resource/_nav_user.html.erb +0 -4
  161. data/app/views/resource/_tab_menu.html.erb +0 -13
  162. data/css.manifest +0 -3
  163. data/js.manifest +0 -4
  164. data/lib/generators/pu/pkg/app/templates/app/controllers/app_controller.rb.tt +0 -5
  165. data/lib/generators/pu/pkg/app/templates/app/controllers/package_controller.rb.tt +0 -26
  166. data/public/plutonium-assets/application.css +0 -25086
  167. data/public/plutonium-assets/plutonium-app-36KN5FVJ.js +0 -6
  168. data/public/plutonium-assets/plutonium-app-36KN5FVJ.js.map +0 -7
  169. data/public/plutonium-assets/plutonium-app-6WILQCTT.js +0 -39
  170. data/public/plutonium-assets/plutonium-app-6WILQCTT.js.map +0 -7
  171. data/public/plutonium-assets/plutonium.2d4f0c333cd000051d3b.css +0 -3424
  172. data/public/plutonium-assets/plutonium.50232e35b5495f5ad90d.css +0 -3415
  173. data/public/plutonium-assets/plutonium.8bee7a8482988b0360e3.css +0 -3420
  174. /data/{app/assets/build → lib/generators/pu/core/assets/templates}/.keep +0 -0
  175. /data/{app/assets/stylesheets → src/css}/plutonium.css +0 -0
  176. /data/{app/views/components/form → src/js/controllers}/form_controller.js +0 -0
  177. /data/{app/views/components/interactive_action_form → src/js/controllers}/interactive_action_form_controller.js +0 -0
  178. /data/{app/views/components/nested_resource_form_fields → src/js/controllers}/nested_resource_form_fields_controller.js +0 -0
  179. /data/{app/views/components/table → src/js/controllers}/table_controller.js +0 -0
  180. /data/{app/views/components/table_search_input → src/js/controllers}/table_search_input_controller.js +0 -0
  181. /data/{app/views/components/table_toolbar → src/js/controllers}/table_toolbar_controller.js +0 -0
  182. /data/{app/views/components/toolbar → src/js/controllers}/toolbar_controller.js +0 -0
  183. /data/{app/assets/javascripts → src/js}/turbo/index.js +0 -0
  184. /data/{app/assets/javascripts → src/js}/turbo/turbo_actions.js +0 -0
  185. /data/{app/assets/javascripts → src/js}/turbo/turbo_frame_monkey_patch.js +0 -0
@@ -1,49 +1,16 @@
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">
7
- <meta name="turbo-cache-control" content="no-cache">
8
- <meta name="turbo-refresh-method" content="morph">
9
- <meta name="turbo-refresh-scroll" content="preserve">
10
- <%= Plutonium::Config.favicon_tag.call self %>
11
- <%= csrf_meta_tags %>
12
- <%= csp_meta_tag %>
13
- <%= yield(:meta) %>
1
+ <%= render_component :resource_layout, lang: "en",
2
+ page_title: make_page_title(@page_title) do |layout| %>
3
+ <% layout.with_favicon do %>
4
+ <%= resource_favicon_tag %>
5
+ <% end %>
14
6
 
15
- <link rel="preconnect" href="https://fonts.googleapis.com">
16
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
17
- <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">
7
+ <% layout.with_header do %>
8
+ <%= render("resource_header", sidebar_toggle: true) %>
9
+ <% end %>
18
10
 
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 %>
29
-
30
- <%= yield(:head) %>
31
- </head>
32
- <body class="antialiased bg-gray-50 dark:bg-gray-900">
33
- <%= render("resource_header") %>
11
+ <% layout.with_sidebar do %>
34
12
  <%= 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
-
42
-
43
- <!--
44
-
45
- <%= modal_frame_tag do %>
46
- <%= yield(:modal) %>
47
- <% end %>
13
+ <% end %>
48
14
 
49
- -->
15
+ <%= yield %>
16
+ <% end %>
@@ -1,36 +1,20 @@
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">
7
- <meta name="turbo-cache-control" content="no-cache">
8
- <meta name="turbo-refresh-method" content="morph">
9
- <meta name="turbo-refresh-scroll" content="preserve">
10
- <%= csrf_meta_tags %>
11
- <%= csp_meta_tag %>
12
- <link rel="preconnect" href="https://fonts.googleapis.com">
13
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
14
- <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
- <%= render "flash" %>
21
- <p class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white">
22
- <img class="w-16 h-16 mr-2" src="<%= Plutonium.logo_link %>" alt="logo">
23
- <%= application_name %>
24
- </p>
25
- <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">
26
- <div class="w-full p-6 space-y-4 md:space-y-6 sm:p-8">
27
- <%= yield %>
28
- </div>
29
- </div>
30
- <div class="mt-4 flex items-center font-medium text-blue-600 dark:text-blue-500 hover:underline">
31
- <%= Plutonium::Icons.render "outline/home" %>
32
- <%= link_to "Home", root_path, class: "font-medium text-blue-600 dark:text-blue-500" %>
33
- </div>
34
- </main>
35
- </body>
36
- </html>
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
+ <% layout.with_favicon do %>
5
+ <%= resource_favicon_tag %>
6
+ <% end %>
7
+
8
+ <p class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white">
9
+ <%= resource_logo_tag classname: "w-24 h-24 mr-2" %>
10
+ </p>
11
+ <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">
12
+ <div class="w-full p-6 space-y-4 md:space-y-6 sm:p-8">
13
+ <%= yield %>
14
+ </div>
15
+ </div>
16
+ <div class="mt-4 flex items-center font-medium text-blue-600 dark:text-blue-500 hover:underline">
17
+ <%= render_icon "outline/home" %>
18
+ <%= link_to "Home", root_path, class: "font-medium text-blue-600 dark:text-blue-500" %>
19
+ </div>
20
+ <% 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 %>
@@ -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,44 @@
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
+
39
+ environment "config.plutonium.assets.stylesheet = \"application\""
40
+ environment "config.plutonium.assets.script = \"application\""
41
+ end
42
+ end
43
+ end
44
+ 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
+ }
@@ -29,8 +29,11 @@ module Pu
29
29
  end
30
30
 
31
31
  def setup_app
32
- directory "config"
32
+ # directory "config"
33
33
  directory "app"
34
+
35
+ environment "# config.plutonium.assets.favicon = \"favicon.ico\""
36
+ environment "# config.plutonium.assets.logo = \"logo.png\""
34
37
  end
35
38
 
36
39
  def install_required_gems
@@ -1,6 +1,12 @@
1
+ return if ENV["SECRET_KEY_BASE_DUMMY"].present?
2
+
1
3
  # Add required env vars to this list
2
4
  required_env_vars = %w[]
3
5
 
6
+ if Rails.env.production?
7
+ required_env_vars += %w[RAILS_MASTER_KEY DATABASE_URL]
8
+ end
9
+
4
10
  # Add additional env vars here
5
11
 
6
12
  # Check required env vars
@@ -20,10 +20,9 @@ module Pu
20
20
  template "component.html.erb", "#{component_path}.html.erb"
21
21
  template "controller.js", controller_path
22
22
 
23
- controllers_index_file = File.join __dir__, "../../../../../app/assets/javascripts/controllers/index.js"
23
+ controllers_index_file = File.join __dir__, "../../../../../src/js/controllers/register_controllers.js"
24
24
  insert_into_file controllers_index_file, controller_import, after: /.*Import controllers here*\n/
25
25
  insert_into_file controllers_index_file, controller_registration, after: /.*Register controllers here*\n/
26
- insert_into_file controllers_index_file, controller_export, after: /.*Export controllers here*\n/
27
26
  end
28
27
 
29
28
  protected
@@ -45,7 +44,7 @@ module Pu
45
44
  end
46
45
 
47
46
  def component_namespace
48
- ["Plutonium::Ui", component_module].compact.join "::"
47
+ ["PlutoniumUi", component_module].compact.join "::"
49
48
  end
50
49
 
51
50
  def component_reference
@@ -68,8 +67,16 @@ module Pu
68
67
  [component_module, component_name].compact.join("::").gsub("::", "__").underscore
69
68
  end
70
69
 
70
+ def controller_filename
71
+ "#{[component_module, component_name].compact.join("::").underscore}_controller.js"
72
+ end
73
+
74
+ def controllers_dir
75
+ File.join "src", "js", "controllers"
76
+ end
77
+
71
78
  def controller_path
72
- "#{component_base_path}_controller.js"
79
+ File.join controllers_dir, controller_filename
73
80
  end
74
81
 
75
82
  def controller_identifier
@@ -77,20 +84,16 @@ module Pu
77
84
  end
78
85
 
79
86
  def controller_reference
80
- [component_module, "#{component_name}Controller"].compact.join("::").gsub("::", "_")
87
+ [component_module, "#{component_name}Controller"].compact.join("")
81
88
  end
82
89
 
83
90
  def controller_import
84
- "import #{controller_reference} from \"../../../../#{controller_path}\"\n"
91
+ "import #{controller_reference} from \"./#{controller_filename}\"\n"
85
92
  end
86
93
 
87
94
  def controller_registration
88
95
  " application.register(\"#{controller_identifier}\", #{controller_reference})\n"
89
96
  end
90
-
91
- def controller_export
92
- "export { #{controller_reference} }\n"
93
- end
94
97
  end
95
98
  end
96
99
  end
@@ -1,3 +1,3 @@
1
- <div data-controller="<%= controller_identifier %>" <%%= render_component_attributes %>>
1
+ <div <%%= attributes_html %>>
2
2
  <%%= content %>
3
3
  </div>
@@ -1,8 +1,14 @@
1
1
  module <%= component_namespace %>
2
- class <%= component_classname %> < Plutonium::Ui::Base
3
- # def base_classname
4
- # "base classnames here"
5
- # end
2
+ class <%= component_classname %> < PlutoniumUi::Base
3
+ private
4
+
5
+ def base_attributes
6
+ # base attributes go here
7
+ {
8
+ classname: "<%= controller_identifier %>",
9
+ controller: "<%= controller_identifier %>"
10
+ }
11
+ end
6
12
  end
7
13
  end
8
14
 
@@ -28,10 +28,10 @@ module Pu
28
28
  template "lib/engine.rb", "packages/#{package_namespace}/lib/engine.rb"
29
29
  template "config/routes.rb", "packages/#{package_namespace}/config/routes.rb"
30
30
 
31
- template "app/controllers/package_controller.rb",
32
- "packages/#{package_namespace}/app/controllers/#{package_namespace}/#{package_namespace}_controller.rb"
33
- template "app/controllers/app_controller.rb",
34
- "packages/#{package_namespace}/app/controllers/#{package_namespace}/app_controller.rb"
31
+ template "app/controllers/concerns/controller.rb",
32
+ "packages/#{package_namespace}/app/controllers/#{package_namespace}/concerns/controller.rb"
33
+ template "app/controllers/controller.rb",
34
+ "packages/#{package_namespace}/app/controllers/#{package_namespace}/controller.rb"
35
35
 
36
36
  template "app/controllers/dashboard_controller.rb",
37
37
  "packages/#{package_namespace}/app/controllers/#{package_namespace}/dashboard_controller.rb"
@@ -0,0 +1,28 @@
1
+ module <%= package_name %>
2
+ module Concerns
3
+ module Controller
4
+ extend ActiveSupport::Concern
5
+ include Plutonium::Application::Controller
6
+ <%- if rodauth_account.present? -%>
7
+ include Plutonium::Auth.rodauth(:<%= rodauth_account %>)
8
+ <%- elsif public_access? -%>
9
+ include Plutonium::Auth::Public
10
+ <%- end -%>
11
+ # add concerns above.
12
+
13
+ included do
14
+ boot <%= package_name %>
15
+ <%- if bring_your_own_auth? -%>
16
+
17
+ helper_method :current_user
18
+ <%- end -%>
19
+ end
20
+ <%- if bring_your_own_auth? -%>
21
+
22
+ def current_user
23
+ raise NotImplementedError, "#{self.class}#current_user must return a non nil value"
24
+ end
25
+ <%- end -%>
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ module <%= package_name %>
2
+ class Controller < ::ApplicationController
3
+ include <%= package_name %>::Concerns::Controller
4
+ end
5
+ end
@@ -1,5 +1,5 @@
1
1
  module <%= package_name %>
2
- class DashboardController < AppController
2
+ class DashboardController < Controller
3
3
  def index
4
4
  end
5
5
  end