solidus_admin 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (285) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.json +7 -0
  3. data/README.md +1 -1
  4. data/Rakefile +26 -0
  5. data/app/assets/builds/.keep +0 -0
  6. data/app/assets/builds/solidus_admin/tailwind.css +2799 -0
  7. data/app/assets/config/solidus_admin_manifest.js +1 -0
  8. data/app/assets/stylesheets/solidus_admin/application.tailwind.css +4 -0
  9. data/app/assets/stylesheets/solidus_admin/dark.css +12 -0
  10. data/app/assets/stylesheets/solidus_admin/dimmed.css +11 -0
  11. data/app/components/solidus_admin/adjustment_reasons/index/component.html.erb +32 -0
  12. data/app/components/solidus_admin/adjustment_reasons/index/component.rb +53 -0
  13. data/app/components/solidus_admin/adjustment_reasons/index/component.yml +4 -0
  14. data/app/components/solidus_admin/layout/feedback/component.html.erb +15 -0
  15. data/app/components/solidus_admin/layout/feedback/component.rb +4 -0
  16. data/app/components/solidus_admin/layout/feedback/component.yml +3 -0
  17. data/app/components/solidus_admin/layout/navigation/account/component.html.erb +74 -0
  18. data/app/components/solidus_admin/layout/navigation/account/component.js +16 -0
  19. data/app/components/solidus_admin/layout/navigation/account/component.rb +36 -0
  20. data/app/components/solidus_admin/{sidebar → layout/navigation}/component.html.erb +9 -9
  21. data/app/components/solidus_admin/layout/navigation/component.rb +26 -0
  22. data/app/components/solidus_admin/{sidebar → layout/navigation}/item/component.html.erb +5 -5
  23. data/app/components/solidus_admin/{sidebar → layout/navigation}/item/component.rb +2 -2
  24. data/app/components/solidus_admin/layout/page_helpers.rb +55 -0
  25. data/app/components/solidus_admin/{skip_link → layout/skip_link}/component.rb +2 -4
  26. data/app/components/solidus_admin/option_types/index/component.html.erb +30 -0
  27. data/app/components/solidus_admin/option_types/index/component.rb +57 -0
  28. data/app/components/solidus_admin/option_types/index/component.yml +4 -0
  29. data/app/components/solidus_admin/orders/cart/component.html.erb +77 -0
  30. data/app/components/solidus_admin/orders/cart/component.js +37 -0
  31. data/app/components/solidus_admin/orders/cart/component.rb +7 -0
  32. data/app/components/solidus_admin/orders/cart/component.yml +3 -0
  33. data/app/components/solidus_admin/orders/cart/result/component.html.erb +26 -0
  34. data/app/components/solidus_admin/orders/cart/result/component.rb +11 -0
  35. data/app/components/solidus_admin/orders/index/component.html.erb +26 -22
  36. data/app/components/solidus_admin/orders/index/component.rb +80 -16
  37. data/app/components/solidus_admin/orders/index/component.yml +10 -3
  38. data/app/components/solidus_admin/orders/show/address/component.html.erb +67 -0
  39. data/app/components/solidus_admin/orders/show/address/component.js +9 -0
  40. data/app/components/solidus_admin/orders/show/address/component.rb +53 -0
  41. data/app/components/solidus_admin/orders/show/address/component.yml +14 -0
  42. data/app/components/solidus_admin/orders/show/component.html.erb +76 -0
  43. data/app/components/solidus_admin/orders/show/component.js +7 -0
  44. data/app/components/solidus_admin/orders/show/component.rb +40 -0
  45. data/app/components/solidus_admin/orders/show/component.yml +21 -0
  46. data/app/components/solidus_admin/orders/show/customer_search/component.html.erb +14 -0
  47. data/app/components/solidus_admin/orders/show/customer_search/component.js +14 -0
  48. data/app/components/solidus_admin/orders/show/customer_search/component.rb +7 -0
  49. data/app/components/solidus_admin/orders/show/customer_search/component.yml +2 -0
  50. data/app/components/solidus_admin/orders/show/customer_search/result/component.html.erb +17 -0
  51. data/app/components/solidus_admin/orders/show/customer_search/result/component.rb +11 -0
  52. data/app/components/solidus_admin/orders/show/email/component.html.erb +18 -0
  53. data/app/components/solidus_admin/orders/show/email/component.rb +15 -0
  54. data/app/components/solidus_admin/orders/show/email/component.yml +8 -0
  55. data/app/components/solidus_admin/orders/show/summary/component.html.erb +14 -0
  56. data/app/components/solidus_admin/orders/show/summary/component.rb +7 -0
  57. data/app/components/solidus_admin/orders/show/summary/component.yml +8 -0
  58. data/app/components/solidus_admin/payment_methods/index/component.html.erb +38 -0
  59. data/app/components/solidus_admin/payment_methods/index/component.rb +93 -0
  60. data/app/components/solidus_admin/payment_methods/index/component.yml +15 -0
  61. data/app/components/solidus_admin/products/index/component.html.erb +26 -22
  62. data/app/components/solidus_admin/products/index/component.rb +36 -36
  63. data/app/components/solidus_admin/products/index/component.yml +9 -6
  64. data/app/components/solidus_admin/products/show/component.html.erb +32 -38
  65. data/app/components/solidus_admin/products/show/component.rb +2 -0
  66. data/app/components/solidus_admin/products/show/component.yml +5 -5
  67. data/app/components/solidus_admin/products/status/component.rb +20 -18
  68. data/app/components/solidus_admin/products/status/component.yml +1 -0
  69. data/app/components/solidus_admin/products/stock/component.rb +38 -0
  70. data/app/components/solidus_admin/products/stock/component.yml +5 -0
  71. data/app/components/solidus_admin/promotion_categories/index/component.html.erb +26 -0
  72. data/app/components/solidus_admin/promotion_categories/index/component.rb +57 -0
  73. data/app/components/solidus_admin/promotion_categories/index/component.yml +4 -0
  74. data/app/components/solidus_admin/promotions/index/component.html.erb +34 -0
  75. data/app/components/solidus_admin/promotions/index/component.rb +97 -0
  76. data/app/components/solidus_admin/promotions/index/component.yml +14 -0
  77. data/app/components/solidus_admin/properties/index/component.html.erb +34 -0
  78. data/app/components/solidus_admin/properties/index/component.rb +65 -0
  79. data/app/components/solidus_admin/properties/index/component.yml +4 -0
  80. data/app/components/solidus_admin/refund_reasons/index/component.html.erb +31 -0
  81. data/app/components/solidus_admin/refund_reasons/index/component.rb +53 -0
  82. data/app/components/solidus_admin/refund_reasons/index/component.yml +4 -0
  83. data/app/components/solidus_admin/refunds_and_returns/component.html.erb +26 -0
  84. data/app/components/solidus_admin/refunds_and_returns/component.rb +20 -0
  85. data/app/components/solidus_admin/refunds_and_returns/component.yml +3 -0
  86. data/app/components/solidus_admin/reimbursement_types/index/component.html.erb +22 -0
  87. data/app/components/solidus_admin/reimbursement_types/index/component.rb +45 -0
  88. data/app/components/solidus_admin/reimbursement_types/index/component.yml +4 -0
  89. data/app/components/solidus_admin/return_reasons/index/component.html.erb +31 -0
  90. data/app/components/solidus_admin/return_reasons/index/component.rb +52 -0
  91. data/app/components/solidus_admin/return_reasons/index/component.yml +4 -0
  92. data/app/components/solidus_admin/shipping/component.html.erb +30 -0
  93. data/app/components/solidus_admin/shipping/component.rb +18 -0
  94. data/app/components/solidus_admin/shipping/component.yml +3 -0
  95. data/app/components/solidus_admin/shipping_categories/index/component.html.erb +32 -0
  96. data/app/components/solidus_admin/shipping_categories/index/component.rb +46 -0
  97. data/app/components/solidus_admin/shipping_categories/index/component.yml +4 -0
  98. data/app/components/solidus_admin/shipping_methods/index/component.html.erb +32 -0
  99. data/app/components/solidus_admin/shipping_methods/index/component.rb +61 -0
  100. data/app/components/solidus_admin/shipping_methods/index/component.yml +4 -0
  101. data/app/components/solidus_admin/stock_items/edit/component.html.erb +89 -0
  102. data/app/components/solidus_admin/stock_items/edit/component.js +17 -0
  103. data/app/components/solidus_admin/stock_items/edit/component.rb +23 -0
  104. data/app/components/solidus_admin/stock_items/edit/component.yml +10 -0
  105. data/app/components/solidus_admin/stock_items/index/component.html.erb +26 -0
  106. data/app/components/solidus_admin/stock_items/index/component.rb +180 -0
  107. data/app/components/solidus_admin/stock_items/index/component.yml +10 -0
  108. data/app/components/solidus_admin/stock_locations/index/component.html.erb +32 -0
  109. data/app/components/solidus_admin/stock_locations/index/component.rb +81 -0
  110. data/app/components/solidus_admin/stock_locations/index/component.yml +6 -0
  111. data/app/components/solidus_admin/store_credit_reasons/index/component.html.erb +31 -0
  112. data/app/components/solidus_admin/store_credit_reasons/index/component.rb +52 -0
  113. data/app/components/solidus_admin/store_credit_reasons/index/component.yml +4 -0
  114. data/app/components/solidus_admin/stores/index/component.html.erb +34 -0
  115. data/app/components/solidus_admin/stores/index/component.rb +59 -0
  116. data/app/components/solidus_admin/stores/index/component.yml +4 -0
  117. data/app/components/solidus_admin/tax_categories/index/component.html.erb +32 -0
  118. data/app/components/solidus_admin/tax_categories/index/component.rb +58 -0
  119. data/app/components/solidus_admin/tax_categories/index/component.yml +6 -0
  120. data/app/components/solidus_admin/tax_rates/index/component.html.erb +32 -0
  121. data/app/components/solidus_admin/tax_rates/index/component.rb +84 -0
  122. data/app/components/solidus_admin/tax_rates/index/component.yml +4 -0
  123. data/app/components/solidus_admin/taxes/component.html.erb +24 -0
  124. data/app/components/solidus_admin/taxes/component.rb +25 -0
  125. data/app/components/solidus_admin/taxes/component.yml +3 -0
  126. data/app/components/solidus_admin/taxonomies/index/component.html.erb +28 -0
  127. data/app/components/solidus_admin/taxonomies/index/component.rb +47 -0
  128. data/app/components/solidus_admin/taxonomies/index/component.yml +4 -0
  129. data/app/components/solidus_admin/ui/badge/component.rb +18 -8
  130. data/app/components/solidus_admin/ui/badge/component.yml +3 -0
  131. data/app/components/solidus_admin/ui/button/component.rb +32 -32
  132. data/app/components/solidus_admin/ui/details_list/component.html.erb +10 -0
  133. data/app/components/solidus_admin/ui/details_list/component.rb +7 -0
  134. data/app/components/solidus_admin/ui/dropdown/component.html.erb +50 -0
  135. data/app/components/solidus_admin/ui/dropdown/component.js +16 -0
  136. data/app/components/solidus_admin/ui/dropdown/component.rb +28 -0
  137. data/app/components/solidus_admin/ui/dropdown/component.yml +2 -0
  138. data/app/components/solidus_admin/ui/forms/address/component.html.erb +36 -0
  139. data/app/components/solidus_admin/ui/forms/address/component.js +34 -0
  140. data/app/components/solidus_admin/ui/forms/address/component.rb +14 -0
  141. data/app/components/solidus_admin/ui/forms/field/component.html.erb +5 -4
  142. data/app/components/solidus_admin/ui/forms/field/component.rb +53 -15
  143. data/app/components/solidus_admin/ui/forms/input/component.rb +11 -5
  144. data/app/components/solidus_admin/ui/forms/search/component.html.erb +52 -0
  145. data/app/components/solidus_admin/ui/forms/search/component.js +116 -0
  146. data/app/components/solidus_admin/ui/forms/search/component.rb +8 -0
  147. data/app/components/solidus_admin/ui/forms/search/component.yml +4 -0
  148. data/app/components/solidus_admin/ui/forms/search/result/component.rb +12 -0
  149. data/app/components/solidus_admin/ui/forms/search_field/component.html.erb +20 -0
  150. data/app/{javascript/solidus_admin/controllers/hello_controller.js → components/solidus_admin/ui/forms/search_field/component.js} +4 -2
  151. data/app/components/solidus_admin/ui/forms/search_field/component.rb +10 -0
  152. data/app/components/solidus_admin/ui/forms/search_field/component.yml +2 -0
  153. data/app/components/solidus_admin/ui/forms/switch/component.rb +27 -31
  154. data/app/components/solidus_admin/ui/forms/switch_field/component.html.erb +20 -0
  155. data/app/components/solidus_admin/ui/forms/switch_field/component.rb +11 -0
  156. data/app/components/solidus_admin/ui/icon/component.rb +4 -0
  157. data/app/components/solidus_admin/ui/modal/component.html.erb +37 -0
  158. data/app/components/solidus_admin/ui/modal/component.rb +12 -0
  159. data/app/components/solidus_admin/ui/modal/component.yml +2 -0
  160. data/app/components/solidus_admin/ui/panel/component.html.erb +26 -12
  161. data/app/components/solidus_admin/ui/panel/component.rb +17 -0
  162. data/app/components/solidus_admin/ui/panel/component.yml +1 -3
  163. data/app/components/solidus_admin/ui/resource_item/component.html.erb +10 -0
  164. data/app/components/solidus_admin/ui/resource_item/component.rb +9 -0
  165. data/app/components/solidus_admin/ui/tab/component.rb +9 -8
  166. data/app/components/solidus_admin/ui/table/component.html.erb +146 -135
  167. data/app/components/solidus_admin/ui/table/component.js +56 -17
  168. data/app/components/solidus_admin/ui/table/component.rb +94 -70
  169. data/app/components/solidus_admin/ui/table/component.yml +0 -1
  170. data/app/components/solidus_admin/ui/table/ransack_filter/component.html.erb +72 -0
  171. data/app/components/solidus_admin/ui/table/ransack_filter/component.js +73 -0
  172. data/app/components/solidus_admin/ui/table/ransack_filter/component.rb +68 -0
  173. data/app/components/solidus_admin/ui/table/ransack_filter/component.yml +3 -0
  174. data/app/components/solidus_admin/ui/table/toolbar/component.rb +21 -0
  175. data/app/components/solidus_admin/ui/thumbnail/component.rb +46 -0
  176. data/app/components/solidus_admin/ui/toast/component.html.erb +9 -5
  177. data/app/components/solidus_admin/ui/toast/component.js +9 -6
  178. data/app/components/solidus_admin/ui/toast/component.rb +2 -2
  179. data/app/components/solidus_admin/ui/toggletip/component.html.erb +14 -10
  180. data/app/components/solidus_admin/ui/toggletip/component.js +22 -4
  181. data/app/components/solidus_admin/ui/toggletip/component.rb +8 -85
  182. data/app/components/solidus_admin/users/index/component.html.erb +34 -0
  183. data/app/components/solidus_admin/users/index/component.rb +89 -0
  184. data/app/components/solidus_admin/users/index/component.yml +18 -0
  185. data/app/components/solidus_admin/zones/index/component.html.erb +35 -0
  186. data/app/components/solidus_admin/zones/index/component.rb +55 -0
  187. data/app/components/solidus_admin/zones/index/component.yml +4 -0
  188. data/app/controllers/solidus_admin/addresses_controller.rb +92 -0
  189. data/app/controllers/solidus_admin/adjustment_reasons_controller.rb +40 -0
  190. data/app/controllers/solidus_admin/base_controller.rb +1 -0
  191. data/app/controllers/solidus_admin/controller_helpers/authorization.rb +5 -1
  192. data/app/controllers/solidus_admin/controller_helpers/locale.rb +2 -2
  193. data/app/controllers/solidus_admin/controller_helpers/search.rb +48 -0
  194. data/app/controllers/solidus_admin/controller_helpers/theme.rb +30 -0
  195. data/app/controllers/solidus_admin/countries_controller.rb +12 -0
  196. data/app/controllers/solidus_admin/customers_controller.rb +29 -0
  197. data/app/controllers/solidus_admin/line_items_controller.rb +45 -0
  198. data/app/controllers/solidus_admin/option_types_controller.rb +46 -0
  199. data/app/controllers/solidus_admin/orders_controller.rb +104 -7
  200. data/app/controllers/solidus_admin/payment_methods_controller.rb +52 -0
  201. data/app/controllers/solidus_admin/products_controller.rb +26 -17
  202. data/app/controllers/solidus_admin/promotion_categories_controller.rb +38 -0
  203. data/app/controllers/solidus_admin/promotions_controller.rb +46 -0
  204. data/app/controllers/solidus_admin/properties_controller.rb +33 -0
  205. data/app/controllers/solidus_admin/refund_reasons_controller.rb +40 -0
  206. data/app/controllers/solidus_admin/reimbursement_types_controller.rb +31 -0
  207. data/app/controllers/solidus_admin/return_reasons_controller.rb +40 -0
  208. data/app/controllers/solidus_admin/shipping_categories_controller.rb +40 -0
  209. data/app/controllers/solidus_admin/shipping_methods_controller.rb +40 -0
  210. data/app/controllers/solidus_admin/stock_items_controller.rb +67 -0
  211. data/app/controllers/solidus_admin/stock_locations_controller.rb +40 -0
  212. data/app/controllers/solidus_admin/store_credit_reasons_controller.rb +40 -0
  213. data/app/controllers/solidus_admin/stores_controller.rb +40 -0
  214. data/app/controllers/solidus_admin/tax_categories_controller.rb +40 -0
  215. data/app/controllers/solidus_admin/tax_rates_controller.rb +40 -0
  216. data/app/controllers/solidus_admin/taxonomies_controller.rb +46 -0
  217. data/app/controllers/solidus_admin/users_controller.rb +50 -0
  218. data/app/controllers/solidus_admin/zones_controller.rb +40 -0
  219. data/app/javascript/solidus_admin/controllers/components.js +3 -1
  220. data/app/javascript/solidus_admin/controllers/confirm_controller.js +21 -0
  221. data/app/javascript/solidus_admin/controllers/details_click_outside_controller.js +12 -0
  222. data/app/javascript/solidus_admin/controllers/readonly_when_submitting_controller.js +17 -0
  223. data/app/javascript/solidus_admin/controllers/sortable_controller.js +33 -0
  224. data/app/views/layouts/solidus_admin/application.html.erb +16 -10
  225. data/app/views/layouts/solidus_admin/preview.html.erb +0 -1
  226. data/app/views/solidus_admin/base/unauthorized.html.erb +4 -0
  227. data/config/importmap.rb +2 -0
  228. data/config/initializers/view_component.rb +20 -0
  229. data/config/locales/adjustment_reasons.en.yml +6 -0
  230. data/config/locales/customers.en.yml +7 -0
  231. data/config/locales/errors.en.yml +7 -0
  232. data/config/locales/line_items.en.yml +9 -0
  233. data/config/locales/{main_nav.en.yml → menu_item.en.yml} +8 -2
  234. data/config/locales/option_types.en.yml +6 -0
  235. data/config/locales/orders.en.yml +9 -0
  236. data/config/locales/payment_methods.en.yml +6 -0
  237. data/config/locales/promotion_categories.en.yml +6 -0
  238. data/config/locales/promotions.en.yml +6 -0
  239. data/config/locales/properties.en.yml +6 -0
  240. data/config/locales/refund_reasons_.en.yml +6 -0
  241. data/config/locales/reimbursement_types.en.yml +4 -0
  242. data/config/locales/return_reasons.en.yml +6 -0
  243. data/config/locales/shipping_categories.en.yml +6 -0
  244. data/config/locales/shipping_methods.en.yml +6 -0
  245. data/config/locales/stock_items.en.yml +4 -0
  246. data/config/locales/stock_locations.en.yml +6 -0
  247. data/config/locales/store_credit_reasons.en.yml +6 -0
  248. data/config/locales/stores.en.yml +6 -0
  249. data/config/locales/tax_categories.en.yml +6 -0
  250. data/config/locales/tax_rates.en.yml +6 -0
  251. data/config/locales/taxonomies.en.yml +6 -0
  252. data/config/locales/users.en.yml +6 -0
  253. data/config/locales/zones.en.yml +6 -0
  254. data/config/routes.rb +50 -3
  255. data/config/tailwind.config.js +119 -0
  256. data/docs/{customizing_main_navigation.md → customizing_menu_items.md} +2 -2
  257. data/docs/customizing_tailwindcss.md +57 -0
  258. data/docs/customizing_view_components.md +17 -38
  259. data/lib/generators/solidus_admin/install/install_generator.rb +13 -4
  260. data/lib/generators/solidus_admin/install/templates/config/initializers/{solidus_admin.rb → solidus_admin.rb.tt} +10 -14
  261. data/lib/solidus_admin/admin_resources.rb +23 -0
  262. data/lib/solidus_admin/configuration.rb +93 -67
  263. data/lib/solidus_admin/install_tailwindcss.rb +102 -0
  264. data/lib/solidus_admin/{main_nav_item.rb → menu_item.rb} +2 -2
  265. data/lib/solidus_admin/version.rb +1 -1
  266. data/lib/solidus_admin.rb +1 -2
  267. data/lib/tasks/tailwind.rake +10 -0
  268. data/solidus_admin.gemspec +3 -4
  269. metadata +228 -48
  270. data/app/assets/stylesheets/solidus_admin/application.tailwind.css.erb +0 -35
  271. data/app/components/solidus_admin/feedback/component.html.erb +0 -11
  272. data/app/components/solidus_admin/feedback/component.rb +0 -4
  273. data/app/components/solidus_admin/feedback/component.yml +0 -5
  274. data/app/components/solidus_admin/sidebar/account_nav/component.html.erb +0 -67
  275. data/app/components/solidus_admin/sidebar/account_nav/component.rb +0 -15
  276. data/app/components/solidus_admin/sidebar/component.rb +0 -21
  277. data/app/components/solidus_admin/ui/panel/component.js +0 -14
  278. data/config/solidus_admin/tailwind.config.js.erb +0 -95
  279. data/docs/customizing_tailwind.md +0 -78
  280. data/lib/solidus_admin/tailwindcss.rb +0 -58
  281. data/lib/tasks/tailwindcss.rake +0 -55
  282. /data/app/components/solidus_admin/{sidebar/account_nav → layout/navigation/account}/component.yml +0 -0
  283. /data/app/components/solidus_admin/{sidebar → layout/navigation}/component.js +0 -0
  284. /data/app/components/solidus_admin/{sidebar → layout/navigation}/component.yml +0 -0
  285. /data/app/components/solidus_admin/{skip_link → layout/skip_link}/component.yml +0 -0
@@ -3,168 +3,179 @@
3
3
  rounded-lg
4
4
  border
5
5
  border-gray-100
6
- overflow-hidden
7
6
  "
8
7
  data-controller="<%= stimulus_id %>"
9
8
  data-<%= stimulus_id %>-selected-row-class="bg-gray-15"
9
+ data-<%= stimulus_id %>-mode-value="<%= initial_mode %>"
10
+ data-<%= stimulus_id %>-sortable-value="<%= should_enable_sortable? %>"
11
+ data-action="
12
+ <%= component("ui/table/ransack_filter").stimulus_id %>:search-><%= stimulus_id %>#search
13
+ <%= component("ui/table/ransack_filter").stimulus_id %>:showSearch-><%= stimulus_id %>#showSearch
14
+ "
10
15
  >
11
- <% toolbar_classes = "h-14 p-2 bg-white border-b border-gray-100 justify-start items-center gap-2 visible:flex hidden:hidden" %>
16
+ <% if @search %>
17
+ <div role="search">
18
+ <%= render component("ui/table/toolbar").new("data-#{stimulus_id}-target": "searchToolbar", hidden: initial_mode != "search") do %>
19
+ <%= form_with(
20
+ url: @search.url,
21
+ method: :get,
22
+ html: {
23
+ id: search_form_id,
24
+ class: 'flex-grow',
25
+ "data-turbo-action": "replace",
26
+ "data-#{stimulus_id}-target": "searchForm",
27
+ "data-action": "input->#{stimulus_id}#search change->#{stimulus_id}#search",
28
+ },
29
+ ) do |form| %>
30
+ <%= hidden_field_tag @search.scope_param_name, @search.current_scope.name if @search.scopes.present? %>
31
+ <%= render component('ui/forms/search_field').new(
32
+ name: @search.searchbar_param_name,
33
+ value: @search.value[@search.searchbar_key],
34
+ placeholder: t('.search_placeholder', resources: @data.plural_name),
35
+ "aria-label": t('.search_placeholder', resources: @data.plural_name),
36
+ "data-#{stimulus_id}-target": "searchField",
37
+ "data-turbo-permanent": "true",
38
+ id: "#{stimulus_id}-search-field-#{@id}",
39
+ ) %>
40
+ <% end %>
12
41
 
13
- <div role="search">
14
- <div class="<%= toolbar_classes %>" data-<%= stimulus_id %>-target="searchToolbar">
15
- <%= form_with(
16
- url: @search_url,
17
- method: :get,
18
- html: {
19
- id: search_form_id,
20
- class: 'flex-grow',
21
- "data-turbo-frame": table_frame_id,
22
- "data-turbo-action": "replace",
23
- "data-#{stimulus_id}-target": "searchForm",
24
- "data-action": "reset->#{stimulus_id}#search",
25
- },
26
- ) do |form| %>
27
- <label class="items-center gap-1 p-0 inline-flex w-full justify-start relative">
28
- <%= render component("ui/icon").new(name: 'search-line', class: "w-[1.4em] h-[1.4em] fill-gray-500 absolute ml-3") %>
29
- <input
30
- name="q[<%= @search_key %>]"
31
- value="<%= params.dig(:q, @search_key) %>"
32
- type="search"
33
- placeholder="<%= t('.search_placeholder', resources: resource_plural_name) %>"
34
- class="peer w-full placeholder:text-gray-400 py-1.5 px-10 bg-white rounded border border-gray-300 search-cancel:appearance-none"
35
- data-<%= stimulus_id %>-target="searchField"
36
- data-action="<%= stimulus_id %>#search"
37
- aria-label="<%= t('.search_placeholder', resources: resource_plural_name) %>"
38
- >
39
- <button
40
- class="absolute right-0 mr-3 peer-placeholder-shown:hidden"
41
- data-action="<%= stimulus_id %>#clearSearch"
42
- aria-label="<%= t('.clear') %>"
43
- >
44
- <%= render component("ui/icon").new(name: 'close-circle-fill', class: "w-[1.4em] h-[1.4em] fill-gray-500") %>
45
- </button>
46
- </label>
42
+ <% if @search.scopes.any? %>
43
+ <div class="ml-4">
44
+ <%= render component("ui/button").new(
45
+ text: t('.cancel'),
46
+ scheme: :ghost,
47
+ "data-action": "#{stimulus_id}#resetSearchAndFilters",
48
+ ) %>
49
+ </div>
50
+ <% end %>
47
51
  <% end %>
48
52
 
49
- <div class="ml-4">
50
- <%= render component("ui/button").new(
51
- text: t('.cancel'),
52
- scheme: :ghost,
53
- "data-action": "#{stimulus_id}#cancelSearch",
54
- ) %>
55
- </div>
56
- </div>
57
-
58
- <% if @filters.any? %>
59
- <div class="<%= toolbar_classes %>" data-<%= stimulus_id %>-target="filterToolbar">
60
- <div class="font-semibold text-gray-700 text-sm px-2"><%= t('.refine_search') %>:</div>
61
- <% @filters.each do |filter| %>
62
- <label class="flex gap-2 px-2">
63
- <%= render component('ui/forms/checkbox').new(
64
- name: filter[:name],
65
- value: filter[:value],
66
- size: :s,
67
- form: search_form_id,
68
- 'data-action': "#{stimulus_id}#search",
69
- ) %>
70
- <span class="text-gray-700 leading-none text-sm self-center"><%= filter[:label] %></span>
71
- </label>
53
+ <% if @search.filters.any? %>
54
+ <%= render component("ui/table/toolbar").new("data-#{stimulus_id}-target": "filterToolbar", hidden: initial_mode != "search", class: "flex-wrap") do %>
55
+ <% @search.filters.each_with_index do |filter, index| %>
56
+ <%= render_ransack_filter_dropdown(filter, index) %>
57
+ <% end %>
72
58
  <% end %>
73
- </div>
74
- <% end %>
59
+ <% end %>
75
60
 
76
- <div class="<%= toolbar_classes %>" data-<%= stimulus_id %>-target="scopesToolbar">
77
- <div class="flex-grow">
78
- <%= render component("ui/tab").new(text: "All", current: true, href: "") %>
79
- </div>
61
+ <% if @search.scopes.any? %>
62
+ <%= render component("ui/table/toolbar").new("data-#{stimulus_id}-target": "scopesToolbar", hidden: initial_mode != "scopes") do %>
63
+ <div class="flex-grow">
64
+ <%= form_with(url: @search.url, method: :get) do %>
65
+ <% @search.scopes.each do |scope| %>
66
+ <%= render component("ui/tab").new(
67
+ tag: :button,
68
+ type: :submit,
69
+ text: scope.label,
70
+ current: scope == @search.current_scope,
71
+ name: @search.scope_param_name,
72
+ value: scope.name,
73
+ ) %>
74
+ <% end %>
75
+ <% end %>
76
+ </div>
80
77
 
81
- <%= render component("ui/button").new(
82
- 'aria-label': t('.filter'),
83
- icon: "filter-3-line",
84
- scheme: :secondary,
85
- "data-action": "#{stimulus_id}#showSearch",
86
- ) %>
78
+ <%= render component("ui/button").new(
79
+ 'aria-label': t('.filter'),
80
+ icon: "filter-3-line",
81
+ scheme: :secondary,
82
+ "data-action": "#{stimulus_id}#showSearch",
83
+ ) %>
84
+ <% end %>
85
+ <% end %>
87
86
  </div>
88
- </div>
87
+ <% end %>
89
88
 
90
- <div class="<%= toolbar_classes %>" data-<%= stimulus_id %>-target="batchToolbar" role="toolbar" aria-label="<%= t(".batch_actions") %>">
89
+ <%= render component("ui/table/toolbar").new("data-#{stimulus_id}-target": "batchToolbar", role: "toolbar", "aria-label": t(".batch_actions"), hidden: true) do %>
91
90
  <%= form_tag '', id: batch_actions_form_id %>
92
- <% @batch_actions.each do |batch_action| %>
91
+ <% @data.batch_actions.each do |batch_action| %>
93
92
  <%= render_batch_action_button(batch_action) %>
94
93
  <% end %>
95
- </div>
94
+ <% end %>
95
+
96
+ <table class="table-fixed w-full border-collapse">
97
+ <colgroup>
98
+ <% @data.columns.each do |column| %>
99
+ <col <%= tag.attributes(**column.col) if column.col %>">
100
+ <% end %>
101
+ </colgroup>
96
102
 
97
- <%= turbo_frame_tag table_frame_id, target: "_top" do %>
98
- <table class="table-fixed w-full border-collapse">
99
- <colgroup>
100
- <% @columns.each do |column| %>
101
- <col class="<%= column.class_name %>">
103
+ <thead
104
+ class="bg-gray-15 text-gray-700 text-left text-small"
105
+ data-<%= stimulus_id %>-target="defaultHeader"
106
+ >
107
+ <tr>
108
+ <% @data.columns.each do |column| %>
109
+ <%= render_header_cell(column.header) %>
102
110
  <% end %>
103
- </colgroup>
111
+ </tr>
112
+ </thead>
104
113
 
114
+ <% if @data.batch_actions %>
105
115
  <thead
106
- class="bg-gray-15 text-gray-700 text-left text-small"
107
- data-<%= stimulus_id %>-target="defaultHeader"
116
+ data-<%= stimulus_id %>-target="batchHeader"
117
+ class="bg-white color-black text-xs leading-none text-left"
118
+ hidden
108
119
  >
109
120
  <tr>
110
- <% @columns.each do |column| %>
111
- <%= render_header_cell(column.header) %>
112
- <% end %>
121
+ <%= render_header_cell(selectable_column.header) %>
122
+ <%= render_header_cell(content_tag(:div, safe_join([
123
+ content_tag(:span, "0", "data-#{stimulus_id}-target": "selectedRowsCount"),
124
+ " #{t('.rows_selected')}.",
125
+ ])), colspan: @data.columns.count - 1) %>
113
126
  </tr>
114
127
  </thead>
128
+ <% end %>
115
129
 
116
- <% if @batch_actions %>
117
- <thead
118
- data-<%= stimulus_id %>-target="batchHeader"
119
- class="bg-white color-black text-xs leading-none text-left"
120
- hidden
130
+ <tbody
131
+ class="bg-white text-3.5 line-[150%] text-black"
132
+ data-<%= stimulus_id %>-target="tableBody"
133
+ <%= "data-controller=sortable" if should_enable_sortable? %>
134
+ <%= "data-sortable-param-value=#{@sortable.param}" if @sortable&.param %>
135
+ <%= "data-sortable-handle-value=#{@sortable.handle}" if @sortable&.handle %>
136
+ <%= "data-sortable-animation-value=#{@sortable.animation}" if @sortable&.animation %>
137
+ >
138
+ <% @data.rows.each do |row| %>
139
+ <tr
140
+ class="border-b border-gray-100 last:border-0 hover:bg-gray-50 cursor-pointer <%= 'bg-gray-15 text-gray-700' if @data.fade&.call(row) %>"
141
+ <% if @data.url %>
142
+ data-action="click-><%= stimulus_id %>#rowClicked"
143
+ data-<%= stimulus_id %>-url-param="<%= @data.url.call(row) %>"
144
+ <%= "data-sortable-url=#{@sortable.url.call(row)}" if @sortable&.url %>
145
+ <% end %>
121
146
  >
122
- <tr>
123
- <%= render_header_cell(selectable_column.header) %>
124
- <%= render_header_cell(content_tag(:div, safe_join([
125
- content_tag(:span, "0", "data-#{stimulus_id}-target": "selectedRowsCount"),
126
- " #{t('.rows_selected')}.",
127
- ])), colspan: @columns.count - 1) %>
128
- </div>
129
- </thead>
147
+ <% @data.columns.each do |column| %>
148
+ <%= render_data_cell(column, row) %>
149
+ <% end %>
150
+ </tr>
130
151
  <% end %>
131
152
 
132
- <tbody class="bg-white text-3.5 line-[150%] text-black">
133
- <% @rows.each do |row| %>
134
- <tr class="<%= row_class_for(row) %>">
135
- <% @columns.each do |column| %>
136
- <%= render_data_cell(column.data, row) %>
137
- <% end %>
138
- </tr>
139
- <% end %>
140
-
141
- <% if @rows.empty? && @model_class %>
142
- <tr>
143
- <td
144
- colspan="<%= @columns.size %>"
145
- class="text-center py-4 text-3.5 line-[150%] text-black bg-white"
146
- >
147
- <%= t('.no_resources_found', resources: resource_plural_name) %>
148
- </td>
149
- </tr>
150
- <% end %>
151
- </tbody>
152
-
153
- <% if @prev_page_link || @next_page_link %>
154
- <tfoot>
155
- <tr>
156
- <td colspan="<%= @columns.size %>" class="py-4 bg-white">
157
- <div class="flex justify-center">
158
- <%= render component('ui/table/pagination').new(
159
- prev_link: @prev_page_link,
160
- next_link: @next_page_link
161
- ) %>
162
- </div>
163
- </td>
164
- </tr>
165
- </tfoot>
153
+ <% if @data.rows.empty? && @data.plural_name %>
154
+ <tr>
155
+ <td
156
+ colspan="<%= @data.columns.size %>"
157
+ class="text-center py-4 text-3.5 line-[150%] text-black bg-white rounded-b-lg"
158
+ >
159
+ <%= t('.no_resources_found', resources: @data.plural_name) %>
160
+ </td>
161
+ </tr>
166
162
  <% end %>
163
+ </tbody>
167
164
 
168
- </table>
169
- <% end %>
165
+ <% if @data.prev || @data.next %>
166
+ <tfoot>
167
+ <tr>
168
+ <td colspan="<%= @data.columns.size %>" class="py-4 bg-white rounded-b-lg border-t border-gray-100">
169
+ <div class="flex justify-center">
170
+ <%= render component('ui/table/pagination').new(
171
+ prev_link: @data.prev,
172
+ next_link: @data.next
173
+ ) %>
174
+ </div>
175
+ </td>
176
+ </tr>
177
+ </tfoot>
178
+ <% end %>
179
+
180
+ </table>
170
181
  </div>
@@ -13,12 +13,14 @@ export default class extends Controller {
13
13
  "filterToolbar",
14
14
  "defaultHeader",
15
15
  "batchHeader",
16
+ "tableBody",
16
17
  "selectedRowsCount",
17
18
  ]
18
19
 
19
20
  static classes = ["selectedRow"]
20
21
  static values = {
21
22
  mode: { type: String, default: "scopes" },
23
+ sortable: { type: Boolean, default: false },
22
24
  }
23
25
 
24
26
  initialize() {
@@ -29,16 +31,22 @@ export default class extends Controller {
29
31
  this.search = debounce(this.search.bind(this), 200)
30
32
  }
31
33
 
32
- connect() {
33
- if (this.searchFieldTarget.value !== "") this.modeValue = "search"
34
+ // Determine if sortable should be enabled
35
+ modeValueChanged() {
36
+ const shouldSetSortable = this.sortableValue && this.modeValue !== "batch" && this.modeValue !== "search"
34
37
 
35
- this.render()
38
+ if (shouldSetSortable) {
39
+ this.tableBodyTarget.setAttribute('data-controller', 'sortable')
40
+ } else {
41
+ this.tableBodyTarget.removeAttribute('data-controller')
42
+ }
36
43
  }
37
44
 
38
- showSearch(event) {
45
+ showSearch({ detail: { avoidFocus } }) {
39
46
  this.modeValue = "search"
40
47
  this.render()
41
- this.searchFieldTarget.focus()
48
+
49
+ if (!avoidFocus) this.searchFieldTarget.focus()
42
50
  }
43
51
 
44
52
  search() {
@@ -50,32 +58,38 @@ export default class extends Controller {
50
58
  this.search()
51
59
  }
52
60
 
53
- cancelSearch() {
54
- this.clearSearch()
61
+ resetSearchAndFilters() {
62
+ if (this.hasFilterToolbarTarget) {
63
+ this.filterToolbarTarget.querySelectorAll('fieldset').forEach(fieldset => fieldset.disabled = true)
64
+ }
55
65
 
56
- this.modeValue = "scopes"
57
- this.render()
66
+ this.searchFieldTarget.disabled = true
67
+ this.searchFormTarget.submit()
58
68
  }
59
69
 
60
70
  selectRow(event) {
61
71
  if (this.checkboxTargets.some((checkbox) => checkbox.checked)) {
62
72
  this.modeValue = "batch"
63
- } else if (this.searchFieldTarget.value !== '') {
73
+ } else if (this.hasSearchFieldTarget && (this.searchFieldTarget.value !== '')) {
64
74
  this.modeValue = "search"
65
- } else {
75
+ } else if (this.hasScopesToolbarTarget) {
66
76
  this.modeValue = "scopes"
77
+ } else {
78
+ this.modeValue = "search"
67
79
  }
68
80
 
69
81
  this.render()
70
82
  }
71
83
 
72
84
  selectAllRows(event) {
73
- if (this.modeValue = event.target.checked) {
85
+ if (event.target.checked) {
74
86
  this.modeValue = "batch"
75
- } else if (this.searchFieldTarget.value !== '') {
87
+ } else if (this.hasSearchFieldTarget && (this.searchFieldTarget.value !== '')) {
76
88
  this.modeValue = "search"
77
- } else {
89
+ } else if (this.hasScopesToolbarTarget) {
78
90
  this.modeValue = "scopes"
91
+ } else {
92
+ this.modeValue = "search"
79
93
  }
80
94
 
81
95
  this.checkboxTargets.forEach((checkbox) => (checkbox.checked = event.target.checked))
@@ -83,10 +97,32 @@ export default class extends Controller {
83
97
  this.render()
84
98
  }
85
99
 
100
+ rowClicked(event) {
101
+ // If the user clicked on a link, button, input or summary, skip the row url visit
102
+ if (event.target.closest("td").contains(event.target.closest("a,select,textarea,button,input,summary"))) return
103
+
104
+ if (this.modeValue === "batch") {
105
+ this.toggleCheckbox(event.currentTarget)
106
+ } else {
107
+ window.Turbo.visit(event.params.url)
108
+ }
109
+ }
110
+
111
+ toggleCheckbox(row) {
112
+ const checkbox = this.checkboxTargets.find(selection => row.contains(selection))
113
+
114
+ if (checkbox) {
115
+ checkbox.checked = !checkbox.checked
116
+ this.selectRow()
117
+ }
118
+ }
119
+
86
120
  render() {
87
121
  const selectedRows = this.checkboxTargets.filter((checkbox) => checkbox.checked)
88
122
 
89
- this.searchToolbarTarget.toggleAttribute("hidden", this.modeValue !== "search")
123
+ if (this.hasSearchFieldTarget) {
124
+ this.searchToolbarTarget.toggleAttribute("hidden", this.modeValue !== "search")
125
+ }
90
126
 
91
127
  if (this.hasFilterToolbarTarget) {
92
128
  this.filterToolbarTarget.toggleAttribute("hidden", this.modeValue !== "search")
@@ -96,7 +132,9 @@ export default class extends Controller {
96
132
  this.batchHeaderTarget.toggleAttribute("hidden", this.modeValue !== "batch")
97
133
  this.defaultHeaderTarget.toggleAttribute("hidden", this.modeValue === "batch")
98
134
 
99
- this.scopesToolbarTarget.toggleAttribute("hidden", this.modeValue !== "scopes")
135
+ if (this.hasScopesToolbarTarget) {
136
+ this.scopesToolbarTarget.toggleAttribute("hidden", this.modeValue !== "scopes")
137
+ }
100
138
 
101
139
  // Update the rows background color
102
140
  this.checkboxTargets.filter((checkbox) =>
@@ -111,7 +149,8 @@ export default class extends Controller {
111
149
  checkbox.indeterminate = false
112
150
  checkbox.checked = false
113
151
 
114
- if (selectedRows.length === this.checkboxTargets.length) checkbox.checked = true
152
+ if (this.checkboxTargets.length > 0 && selectedRows.length === this.checkboxTargets.length)
153
+ checkbox.checked = true
115
154
  else if (selectedRows.length > 0) checkbox.indeterminate = true
116
155
  })
117
156
  }
@@ -1,62 +1,67 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class SolidusAdmin::UI::Table::Component < SolidusAdmin::BaseComponent
4
- # @param id [String] A unique identifier for the table component.
5
- # @param model_class [ActiveModel::Translation] The model class used for translations.
6
- # @param rows [Array] The collection of objects that will be passed to columns for display.
7
- # @param fade_row_proc [Proc, nil] A proc determining if a row should have a faded appearance.
8
- # @param search_key [Symbol] The key for searching.
9
- # @param search_url [String] The base URL for searching.
10
- #
11
- # @param columns [Array<Hash>] The array of column definitions.
12
- # @option columns [Symbol|Proc|#to_s] :header The column header.
13
- # @option columns [Symbol|Proc|#to_s] :data The data accessor for the column.
14
- # @option columns [String] :class_name (optional) The class name for the column.
15
- #
16
- # @param batch_actions [Array<Hash>] The array of batch action definitions.
17
- # @option batch_actions [String] :display_name The batch action display name.
18
- # @option batch_actions [String] :icon The batch action icon.
19
- # @option batch_actions [String] :action The batch action path.
20
- # @option batch_actions [String] :method The batch action HTTP method for the provided path.
21
- #
22
- #
23
- # @param filters [Array<Hash>] The array of filter definitions.
24
- # @option filters [String] :name The filter's name.
25
- # @option filters [Any] :value The filter's value.
26
- # @option filters [String] :label The filter's label.
27
- #
28
- # @param prev_page_link [String, nil] The link to the previous page.
29
- # @param next_page_link [String, nil] The link to the next page.
30
- def initialize(
31
- id:,
32
- model_class:,
33
- rows:,
34
- search_key:,
35
- search_url:,
36
- fade_row_proc: nil,
37
- columns: [],
38
- batch_actions: [],
39
- filters: [],
40
- prev_page_link: nil,
41
- next_page_link: nil
42
- )
43
- @columns = columns.map { Column.new(**_1) }
44
- @batch_actions = batch_actions.map { BatchAction.new(**_1) }
45
- @filters = filters.map { Filter.new(**_1) }
46
- @id = id
47
- @model_class = model_class
48
- @rows = rows
49
- @fade_row_proc = fade_row_proc
50
- @search_key = search_key
51
- @search_url = search_url
52
- @prev_page_link = prev_page_link
53
- @next_page_link = next_page_link
54
-
55
- @columns.unshift selectable_column if batch_actions.present?
4
+ BatchAction = Struct.new(:display_name, :icon, :action, :method, keyword_init: true) # rubocop:disable Lint/StructNewOverride
5
+ Column = Struct.new(:header, :data, :col, :wrap, keyword_init: true)
6
+ Filter = Struct.new(:presentation, :combinator, :attribute, :predicate, :options, keyword_init: true)
7
+ Scope = Struct.new(:name, :label, :default, keyword_init: true)
8
+ Sortable = Struct.new(:url, :param, :animation, :handle, keyword_init: true)
9
+ private_constant :BatchAction, :Column, :Filter, :Scope, :Sortable
10
+
11
+ class Data < Struct.new(:rows, :class, :url, :prev, :next, :columns, :fade, :batch_actions, keyword_init: true) # rubocop:disable Lint/StructNewOverride,Style/StructInheritance
12
+ def initialize(**args)
13
+ super
14
+
15
+ self.columns = columns.map do |column|
16
+ column.is_a?(Symbol) ? Column.new(wrap: false, header: column, data: column) : Column.new(wrap: false, **column)
17
+ end
18
+ self.batch_actions = batch_actions.to_a.map { |action| BatchAction.new(**action) }
19
+ end
20
+
21
+ def plural_name
22
+ self[:class].model_name.human.pluralize if self[:class]
23
+ end
56
24
  end
57
25
 
58
- def resource_plural_name
59
- @model_class.model_name.human.pluralize
26
+ class Search < Struct.new(:name, :value, :url, :searchbar_key, :scopes, :filters, keyword_init: true) # rubocop:disable Style/StructInheritance
27
+ def initialize(**args)
28
+ super
29
+
30
+ self.filters = filters.to_a.map { |filter| Filter.new(**filter) }
31
+ self.scopes = scopes.to_a.map { |scope| Scope.new(**scope) }
32
+ end
33
+
34
+ def current_scope
35
+ scopes.find { |scope| scope.name.to_s == value[:scope].presence } || default_scope
36
+ end
37
+
38
+ def default_scope
39
+ scopes.find(&:default)
40
+ end
41
+
42
+ def on_default_scope?
43
+ current_scope == default_scope
44
+ end
45
+
46
+ def scope_param_name
47
+ "#{name}[scope]"
48
+ end
49
+
50
+ def searchbar_param_name
51
+ "#{name}[#{searchbar_key}]"
52
+ end
53
+
54
+ def value
55
+ super || {}
56
+ end
57
+ end
58
+
59
+ def initialize(id:, data:, search: nil, sortable: nil)
60
+ @id = id
61
+ @data = Data.new(**data)
62
+ @data.columns.unshift selectable_column if @data.batch_actions.present?
63
+ @search = Search.new(**search) if search
64
+ @sortable = Sortable.new(**sortable) if sortable
60
65
  end
61
66
 
62
67
  def selectable_column
@@ -79,7 +84,7 @@ class SolidusAdmin::UI::Table::Component < SolidusAdmin::BaseComponent
79
84
  "aria-label": t('.select_row'),
80
85
  )
81
86
  },
82
- class_name: 'w-[52px]',
87
+ col: { class: 'w-[52px]' },
83
88
  )
84
89
  end
85
90
 
@@ -87,10 +92,6 @@ class SolidusAdmin::UI::Table::Component < SolidusAdmin::BaseComponent
87
92
  @batch_actions_form_id ||= "#{stimulus_id}--batch-actions-#{@id}"
88
93
  end
89
94
 
90
- def table_frame_id
91
- @table_frame_id ||= "#{stimulus_id}--table-frame-#{@id}"
92
- end
93
-
94
95
  def search_form_id
95
96
  @search_form_id ||= "#{stimulus_id}--search-form-#{@id}"
96
97
  end
@@ -112,9 +113,22 @@ class SolidusAdmin::UI::Table::Component < SolidusAdmin::BaseComponent
112
113
  )
113
114
  end
114
115
 
116
+ def render_ransack_filter_dropdown(filter, index)
117
+ render component("ui/table/ransack_filter").new(
118
+ presentation: filter.presentation,
119
+ search_param: @search.name,
120
+ combinator: filter.combinator,
121
+ attribute: filter.attribute,
122
+ predicate: filter.predicate,
123
+ options: filter.options,
124
+ form: search_form_id,
125
+ index: index,
126
+ )
127
+ end
128
+
115
129
  def render_header_cell(cell, **attrs)
116
130
  cell = cell.call if cell.respond_to?(:call)
117
- cell = @model_class.human_attribute_name(cell) if cell.is_a?(Symbol)
131
+ cell = @data[:class].human_attribute_name(cell) if cell.is_a?(Symbol)
118
132
  cell = cell.render_in(self) if cell.respond_to?(:render_in)
119
133
 
120
134
  content_tag(:th, cell, class: %{
@@ -128,23 +142,33 @@ class SolidusAdmin::UI::Table::Component < SolidusAdmin::BaseComponent
128
142
  }, **attrs)
129
143
  end
130
144
 
131
- def render_data_cell(cell, data)
145
+ def render_data_cell(column, data)
146
+ cell = column.data
132
147
  cell = cell.call(data) if cell.respond_to?(:call)
133
148
  cell = data.public_send(cell) if cell.is_a?(Symbol)
134
149
  cell = cell.render_in(self) if cell.respond_to?(:render_in)
150
+ cell = tag.div(cell, class: "flex items-center gap-1.5 justify-start overflow-x-hidden") if column.wrap
135
151
 
136
- content_tag(:td, content_tag(:div, cell, class: "flex items-center gap-1.5"), class: "py-2 px-4 h-10 vertical-align-middle leading-none")
152
+ tag.td(cell, class: "
153
+ py-2 px-4 h-10 vertical-align-middle leading-none
154
+ [tr:last-child_&:first-child]:rounded-bl-lg [tr:last-child_&:last-child]:rounded-br-lg
155
+ ")
137
156
  end
138
157
 
139
- def row_class_for(row)
140
- classes = ['border-b', 'border-gray-100']
141
- classes << ['bg-gray-15', 'text-gray-700'] if @fade_row_proc&.call(row)
158
+ def current_scope_name
159
+ @search.current_scope.name
160
+ end
142
161
 
143
- classes.join(' ')
162
+ def initial_mode
163
+ @initial_mode ||=
164
+ if @search && (@search.value[@search.searchbar_key] || @search.scopes.none?)
165
+ "search"
166
+ else
167
+ "scopes"
168
+ end
144
169
  end
145
170
 
146
- Column = Struct.new(:header, :data, :class_name, keyword_init: true)
147
- BatchAction = Struct.new(:display_name, :icon, :action, :method, keyword_init: true) # rubocop:disable Lint/StructNewOverride
148
- Filter = Struct.new(:name, :value, :label, keyword_init: true)
149
- private_constant :Column, :BatchAction, :Filter
171
+ def should_enable_sortable?
172
+ @sortable && @search&.on_default_scope?
173
+ end
150
174
  end