spree_admin 5.0.3 → 5.1.0.beta

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 (268) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/login_sidebar_background.png +0 -0
  3. data/app/assets/stylesheets/spree/admin/components/_bulk_panel.scss +8 -1
  4. data/app/assets/stylesheets/spree/admin/components/_buttons.scss +12 -20
  5. data/app/assets/stylesheets/spree/admin/components/_cards.scss +9 -3
  6. data/app/assets/stylesheets/spree/admin/components/_dropdowns.scss +13 -40
  7. data/app/assets/stylesheets/spree/admin/components/_filters.scss +32 -3
  8. data/app/assets/stylesheets/spree/admin/components/_main.scss +107 -31
  9. data/app/assets/stylesheets/spree/admin/components/_media_form.scss +21 -9
  10. data/app/assets/stylesheets/spree/admin/components/_modals.scss +4 -3
  11. data/app/assets/stylesheets/spree/admin/components/_navbar.scss +5 -9
  12. data/app/assets/stylesheets/spree/admin/components/_navigation.scss +0 -1
  13. data/app/assets/stylesheets/spree/admin/components/_sortable_tree.scss +6 -2
  14. data/app/assets/stylesheets/spree/admin/components/_tables.scss +35 -5
  15. data/app/assets/stylesheets/spree/admin/global/_variables.scss +37 -17
  16. data/app/assets/stylesheets/spree/admin/plugins/tom-select.bootstrap4.scss +5 -4
  17. data/app/assets/stylesheets/spree/admin/shared/_base.scss +50 -17
  18. data/app/assets/stylesheets/spree/admin/shared/_forms.scss +6 -2
  19. data/app/assets/stylesheets/spree/admin/views/_page_builder.scss +30 -21
  20. data/app/controllers/concerns/spree/admin/breadcrumb_concern.rb +22 -0
  21. data/app/controllers/concerns/spree/admin/preferences_concern.rb +22 -0
  22. data/app/controllers/concerns/spree/admin/products_breadcrumb_concern.rb +22 -0
  23. data/app/controllers/concerns/spree/admin/promotions_breadcrumb_concern.rb +23 -0
  24. data/app/controllers/concerns/spree/admin/storefront_breadcrumb_concern.rb +12 -0
  25. data/app/controllers/spree/admin/addresses_controller.rb +4 -0
  26. data/app/controllers/spree/admin/admin_users_controller.rb +112 -0
  27. data/app/controllers/spree/admin/assets_controller.rb +7 -9
  28. data/app/controllers/spree/admin/base_controller.rb +21 -10
  29. data/app/controllers/spree/admin/checkouts_controller.rb +4 -0
  30. data/app/controllers/spree/admin/classifications_controller.rb +4 -0
  31. data/app/controllers/spree/admin/coupon_codes_controller.rb +2 -0
  32. data/app/controllers/spree/admin/custom_domains_controller.rb +6 -0
  33. data/app/controllers/spree/admin/customer_returns_controller.rb +4 -0
  34. data/app/controllers/spree/admin/dashboard_controller.rb +19 -14
  35. data/app/controllers/spree/admin/digital_assets_controller.rb +8 -0
  36. data/app/controllers/spree/admin/exports_controller.rb +6 -2
  37. data/app/controllers/spree/admin/integrations_controller.rb +61 -0
  38. data/app/controllers/spree/admin/invitations_controller.rb +128 -0
  39. data/app/controllers/spree/admin/line_items_controller.rb +4 -0
  40. data/app/controllers/spree/admin/oauth_applications_controller.rb +6 -0
  41. data/app/controllers/spree/admin/option_types_controller.rb +15 -0
  42. data/app/controllers/spree/admin/option_values_controller.rb +4 -0
  43. data/app/controllers/spree/admin/orders/return_authorizations_controller.rb +4 -0
  44. data/app/controllers/spree/admin/orders_controller.rb +11 -0
  45. data/app/controllers/spree/admin/page_blocks_controller.rb +3 -2
  46. data/app/controllers/spree/admin/page_links_controller.rb +9 -0
  47. data/app/controllers/spree/admin/page_sections_controller.rb +13 -4
  48. data/app/controllers/spree/admin/pages_controller.rb +7 -0
  49. data/app/controllers/spree/admin/payment_methods_controller.rb +23 -12
  50. data/app/controllers/spree/admin/post_categories_controller.rb +3 -0
  51. data/app/controllers/spree/admin/posts_controller.rb +11 -0
  52. data/app/controllers/spree/admin/products_controller.rb +11 -8
  53. data/app/controllers/spree/admin/promotion_actions_controller.rb +10 -2
  54. data/app/controllers/spree/admin/promotion_rules_controller.rb +10 -2
  55. data/app/controllers/spree/admin/promotions_controller.rb +6 -0
  56. data/app/controllers/spree/admin/properties_controller.rb +15 -0
  57. data/app/controllers/spree/admin/refund_reasons_controller.rb +7 -0
  58. data/app/controllers/spree/admin/refunds_controller.rb +4 -0
  59. data/app/controllers/spree/admin/reimbursement_types_controller.rb +7 -0
  60. data/app/controllers/spree/admin/reimbursements_controller.rb +4 -0
  61. data/app/controllers/spree/admin/reports_controller.rb +12 -2
  62. data/app/controllers/spree/admin/resource_controller.rb +1 -1
  63. data/app/controllers/spree/admin/return_authorization_reasons_controller.rb +7 -0
  64. data/app/controllers/spree/admin/return_authorizations_controller.rb +4 -0
  65. data/app/controllers/spree/admin/return_items_controller.rb +6 -0
  66. data/app/controllers/spree/admin/role_users_controller.rb +36 -0
  67. data/app/controllers/spree/admin/roles_controller.rb +8 -0
  68. data/app/controllers/spree/admin/shipments_controller.rb +2 -2
  69. data/app/controllers/spree/admin/shipping_categories_controller.rb +7 -0
  70. data/app/controllers/spree/admin/shipping_methods_controller.rb +6 -0
  71. data/app/controllers/spree/admin/stock_items_controller.rb +13 -0
  72. data/app/controllers/spree/admin/stock_locations_controller.rb +7 -0
  73. data/app/controllers/spree/admin/stock_transfers_controller.rb +14 -2
  74. data/app/controllers/spree/admin/store_credit_categories_controller.rb +5 -0
  75. data/app/controllers/spree/admin/store_credits_controller.rb +4 -0
  76. data/app/controllers/spree/admin/storefront_controller.rb +3 -0
  77. data/app/controllers/spree/admin/stores_controller.rb +17 -2
  78. data/app/controllers/spree/admin/tax_categories_controller.rb +7 -0
  79. data/app/controllers/spree/admin/tax_rates_controller.rb +6 -0
  80. data/app/controllers/spree/admin/taxonomies_controller.rb +15 -0
  81. data/app/controllers/spree/admin/taxons_controller.rb +24 -1
  82. data/app/controllers/spree/admin/themes_controller.rb +7 -0
  83. data/app/controllers/spree/admin/translations_controller.rb +9 -1
  84. data/app/controllers/spree/admin/user_passwords_controller.rb +22 -0
  85. data/app/controllers/spree/admin/user_sessions_controller.rb +23 -0
  86. data/app/controllers/spree/admin/users_controller.rb +11 -2
  87. data/app/controllers/spree/admin/variants_controller.rb +13 -0
  88. data/app/controllers/spree/admin/webhooks_subscribers_controller.rb +34 -12
  89. data/app/controllers/spree/admin/zones_controller.rb +5 -0
  90. data/app/helpers/spree/admin/base_helper.rb +33 -32
  91. data/app/helpers/spree/admin/bulk_operations_helper.rb +8 -2
  92. data/app/helpers/spree/admin/modal_helper.rb +1 -1
  93. data/app/helpers/spree/admin/navigation_helper.rb +12 -6
  94. data/app/helpers/spree/admin/posts_helper.rb +1 -1
  95. data/app/helpers/spree/admin/session_assets_helper.rb +1 -1
  96. data/app/helpers/spree/admin/stores_helper.rb +1 -18
  97. data/app/helpers/spree/admin/tags_helper.rb +2 -2
  98. data/app/javascript/spree/admin/application.js +2 -2
  99. data/app/javascript/spree/admin/controllers/asset_uploader_controller.js +3 -2
  100. data/app/javascript/spree/admin/controllers/variants_form_controller.js +3 -2
  101. data/app/javascript/spree/admin/helpers/bootstrap.js +3 -3
  102. data/app/javascript/spree/admin/helpers/trix/video_embed.js +2 -2
  103. data/app/views/active_storage/_upload_form.html.erb +1 -1
  104. data/app/views/layouts/spree/minimal.html.erb +22 -0
  105. data/app/views/spree/admin/admin_users/_admin_user.html.erb +19 -0
  106. data/app/views/spree/admin/admin_users/_audit_log.html.erb +5 -0
  107. data/app/views/spree/admin/admin_users/_form.html.erb +12 -0
  108. data/app/views/spree/admin/admin_users/edit.html.erb +35 -0
  109. data/app/views/spree/admin/admin_users/index.html.erb +18 -0
  110. data/app/views/spree/admin/admin_users/new.html.erb +21 -0
  111. data/app/views/spree/admin/admin_users/show.html.erb +113 -0
  112. data/app/views/spree/admin/coupon_codes/index.html.erb +6 -6
  113. data/app/views/spree/admin/custom_domains/_custom_domains.html.erb +1 -1
  114. data/app/views/spree/admin/customer_returns/index.html.erb +1 -1
  115. data/app/views/spree/admin/dashboard/_store_preview.html.erb +1 -1
  116. data/app/views/spree/admin/dashboard/_top_products.html.erb +5 -3
  117. data/app/views/spree/admin/digital_assets/_table.html.erb +1 -1
  118. data/app/views/spree/admin/digital_assets/index.html.erb +0 -1
  119. data/app/views/spree/admin/exports/index.html.erb +1 -1
  120. data/app/views/spree/admin/integrations/_integration.html.erb +36 -0
  121. data/app/views/spree/admin/integrations/edit.html.erb +11 -0
  122. data/app/views/spree/admin/integrations/index.html.erb +23 -0
  123. data/app/views/spree/admin/integrations/new.html.erb +14 -0
  124. data/app/views/spree/admin/invitations/_invitation.html.erb +52 -0
  125. data/app/views/spree/admin/invitations/create.turbo_stream.erb +4 -0
  126. data/app/views/spree/admin/invitations/index.html.erb +21 -0
  127. data/app/views/spree/admin/invitations/new.html.erb +32 -0
  128. data/app/views/spree/admin/invitations/show.html.erb +9 -0
  129. data/app/views/spree/admin/line_items/new.html.erb +2 -2
  130. data/app/views/spree/admin/oauth_applications/index.html.erb +1 -1
  131. data/app/views/spree/admin/option_types/edit.html.erb +1 -1
  132. data/app/views/spree/admin/option_types/index.html.erb +1 -1
  133. data/app/views/spree/admin/orders/_customer.html.erb +1 -2
  134. data/app/views/spree/admin/orders/_filters.html.erb +28 -22
  135. data/app/views/spree/admin/orders/_list.html.erb +1 -1
  136. data/app/views/spree/admin/orders/_refunds.html.erb +1 -1
  137. data/app/views/spree/admin/orders/_shipment.html.erb +1 -1
  138. data/app/views/spree/admin/orders/_summary.html.erb +1 -1
  139. data/app/views/spree/admin/orders/_table_filter_dropdown.html.erb +2 -2
  140. data/app/views/spree/admin/orders/customer_returns/_customer_return.html.erb +1 -1
  141. data/app/views/spree/admin/orders/customer_returns/_return_item_decision.html.erb +1 -1
  142. data/app/views/spree/admin/orders/return_authorizations/_form.html.erb +1 -1
  143. data/app/views/spree/admin/orders/return_authorizations/show.html.erb +2 -2
  144. data/app/views/spree/admin/page_blocks/_form_tab_buttons.html.erb +5 -7
  145. data/app/views/spree/admin/page_blocks/edit.html.erb +3 -5
  146. data/app/views/spree/admin/page_blocks/forms/_image.html.erb +9 -0
  147. data/app/views/spree/admin/page_builder/_add_block.html.erb +1 -1
  148. data/app/views/spree/admin/page_builder/_header.html.erb +35 -28
  149. data/app/views/spree/admin/page_builder/_pages_dropdown.html.erb +15 -21
  150. data/app/views/spree/admin/page_builder/_sidebar.html.erb +1 -1
  151. data/app/views/spree/admin/page_builder/_sidebar_block.html.erb +11 -10
  152. data/app/views/spree/admin/page_builder/_sidebar_sections_toolbar.html.erb +152 -39
  153. data/app/views/spree/admin/page_links/_list.html.erb +2 -2
  154. data/app/views/spree/admin/page_links/edit.html.erb +2 -4
  155. data/app/views/spree/admin/page_sections/_form_tab_buttons.html.erb +6 -10
  156. data/app/views/spree/admin/page_sections/new.html.erb +1 -1
  157. data/app/views/spree/admin/pages/edit.html.erb +2 -2
  158. data/app/views/spree/admin/payment_methods/_form.html.erb +1 -1
  159. data/app/views/spree/admin/payment_methods/index.html.erb +16 -15
  160. data/app/views/spree/admin/payments/_payment.html.erb +1 -1
  161. data/app/views/spree/admin/post_categories/index.html.erb +1 -1
  162. data/app/views/spree/admin/posts/index.html.erb +1 -1
  163. data/app/views/spree/admin/products/_bulk_operations.html.erb +1 -1
  164. data/app/views/spree/admin/products/_filters.html.erb +2 -5
  165. data/app/views/spree/admin/products/_list.html.erb +1 -1
  166. data/app/views/spree/admin/products/_table_filter_dropdown.html.erb +2 -2
  167. data/app/views/spree/admin/products/form/_categorization.html.erb +34 -30
  168. data/app/views/spree/admin/products/form/_variants.html.erb +1 -0
  169. data/app/views/spree/admin/promotion_actions/_promotion_action.html.erb +1 -1
  170. data/app/views/spree/admin/promotion_rules/_promotion_rule.html.erb +1 -1
  171. data/app/views/spree/admin/promotions/_filters.html.erb +2 -6
  172. data/app/views/spree/admin/promotions/_header.html.erb +1 -3
  173. data/app/views/spree/admin/promotions/_sidebar.html.erb +18 -0
  174. data/app/views/spree/admin/promotions/_table_filter_dropdown.html.erb +2 -2
  175. data/app/views/spree/admin/promotions/index.html.erb +1 -1
  176. data/app/views/spree/admin/properties/edit.html.erb +1 -1
  177. data/app/views/spree/admin/properties/index.html.erb +1 -1
  178. data/app/views/spree/admin/refund_reasons/index.html.erb +1 -1
  179. data/app/views/spree/admin/reimbursement_types/index.html.erb +1 -1
  180. data/app/views/spree/admin/reimbursements/edit.html.erb +2 -2
  181. data/app/views/spree/admin/reimbursements/show.html.erb +1 -1
  182. data/app/views/spree/admin/reports/_report.html.erb +1 -1
  183. data/app/views/spree/admin/return_authorization_reasons/index.html.erb +1 -1
  184. data/app/views/spree/admin/return_authorizations/_filters.html.erb +2 -2
  185. data/app/views/spree/admin/return_authorizations/_list.html.erb +1 -1
  186. data/app/views/spree/admin/roles/edit.html.erb +6 -4
  187. data/app/views/spree/admin/roles/index.html.erb +11 -7
  188. data/app/views/spree/admin/shared/_alerts.html.erb +1 -1
  189. data/app/views/spree/admin/shared/_breadcrumbs.html.erb +13 -0
  190. data/app/views/spree/admin/shared/_calendar_range_picker.html.erb +1 -1
  191. data/app/views/spree/admin/shared/_content_header.html.erb +3 -3
  192. data/app/views/spree/admin/shared/_filters_button.html.erb +1 -1
  193. data/app/views/spree/admin/shared/_filters_search_bar.html.erb +1 -1
  194. data/app/views/spree/admin/shared/_head.html.erb +10 -1
  195. data/app/views/spree/admin/shared/_header.html.erb +26 -17
  196. data/app/views/spree/admin/shared/_index_table_options.html.erb +1 -1
  197. data/app/views/spree/admin/shared/_multi_product_picker.html.erb +1 -1
  198. data/app/views/spree/admin/shared/_new_item_dropdown.html.erb +32 -0
  199. data/app/views/spree/admin/shared/_no_resource_found.html.erb +6 -3
  200. data/app/views/spree/admin/shared/_offcanvas_nav.html.erb +1 -14
  201. data/app/views/spree/admin/shared/_refunds.html.erb +1 -1
  202. data/app/views/spree/admin/shared/_sidebar.html.erb +0 -8
  203. data/app/views/spree/admin/shared/_tax_nav.html.erb +1 -0
  204. data/app/views/spree/admin/shared/_team_nav.html.erb +13 -0
  205. data/app/views/spree/admin/shared/_user_dropdown.html.erb +25 -20
  206. data/app/views/spree/admin/shared/devise/_links.html.erb +18 -0
  207. data/app/views/spree/admin/shared/sidebar/_enterprise_edition_notice.html.erb +7 -5
  208. data/app/views/spree/admin/shared/sidebar/_integrations_nav.html.erb +5 -7
  209. data/app/views/spree/admin/shared/sidebar/_orders_nav.html.erb +2 -2
  210. data/app/views/spree/admin/shared/sidebar/_products_nav.html.erb +2 -2
  211. data/app/views/spree/admin/shared/sidebar/_promotions_nav.html.erb +17 -0
  212. data/app/views/spree/admin/shared/sidebar/_returns_nav.html.erb +1 -1
  213. data/app/views/spree/admin/shared/sidebar/_store_dropdown.html.erb +33 -75
  214. data/app/views/spree/admin/shared/sidebar/_store_nav.html.erb +17 -36
  215. data/app/views/spree/admin/shared/sidebar/_storefront_nav.html.erb +6 -2
  216. data/app/views/spree/admin/shared/sidebar/_vendors_nav.html.erb +9 -7
  217. data/app/views/spree/admin/shared/sortable_tree/_taxonomy.html.erb +1 -1
  218. data/app/views/spree/admin/shipping_categories/index.html.erb +1 -1
  219. data/app/views/spree/admin/shipping_methods/_form.html.erb +7 -134
  220. data/app/views/spree/admin/shipping_methods/form/_display.html.erb +25 -0
  221. data/app/views/spree/admin/shipping_methods/form/_estimated_transit_business_days.html.erb +23 -0
  222. data/app/views/spree/admin/shipping_methods/form/_shipping_categories.html.erb +21 -0
  223. data/app/views/spree/admin/shipping_methods/form/_tax_category.html.erb +16 -0
  224. data/app/views/spree/admin/shipping_methods/form/_tracking_url.html.erb +18 -0
  225. data/app/views/spree/admin/shipping_methods/form/_zones.html.erb +26 -0
  226. data/app/views/spree/admin/shipping_methods/index.html.erb +1 -1
  227. data/app/views/spree/admin/stock_items/index.html.erb +1 -1
  228. data/app/views/spree/admin/stock_locations/_stock_location.html.erb +5 -3
  229. data/app/views/spree/admin/stock_locations/index.html.erb +4 -2
  230. data/app/views/spree/admin/stock_transfers/index.html.erb +1 -1
  231. data/app/views/spree/admin/store_credit_categories/index.html.erb +1 -1
  232. data/app/views/spree/admin/store_credits/_list.html.erb +1 -1
  233. data/app/views/spree/admin/stores/edit_emails.html.erb +1 -1
  234. data/app/views/spree/admin/stores/form/_basic.html.erb +1 -1
  235. data/app/views/spree/admin/stores/form/_emails.html.erb +1 -1
  236. data/app/views/spree/admin/tax_categories/index.html.erb +1 -1
  237. data/app/views/spree/admin/tax_rates/index.html.erb +1 -1
  238. data/app/views/spree/admin/taxonomies/index.html.erb +1 -1
  239. data/app/views/spree/admin/themes/_theme.html.erb +6 -4
  240. data/app/views/spree/admin/themes/_theme_preview_image.html.erb +6 -4
  241. data/app/views/spree/admin/themes/index.html.erb +1 -1
  242. data/app/views/spree/admin/translations/edit.html.erb +1 -1
  243. data/app/views/spree/admin/user_passwords/edit.html.erb +21 -0
  244. data/app/views/spree/admin/user_passwords/new.html.erb +12 -0
  245. data/app/views/spree/admin/user_sessions/new.html.erb +16 -0
  246. data/app/views/spree/admin/users/_form.html.erb +10 -8
  247. data/app/views/spree/admin/users/_user.html.erb +4 -4
  248. data/app/views/spree/admin/users/index.html.erb +4 -4
  249. data/app/views/spree/admin/users/new.html.erb +1 -1
  250. data/app/views/spree/admin/variants/_search_result.html.erb +1 -1
  251. data/app/views/spree/admin/variants/form/_media.html.erb +1 -0
  252. data/app/views/spree/admin/variants/form/_media_asset.html.erb +1 -1
  253. data/app/views/spree/admin/webhooks_subscribers/_form.html.erb +37 -19
  254. data/app/views/spree/admin/webhooks_subscribers/_webhooks_subscriber.html.erb +12 -6
  255. data/app/views/spree/admin/webhooks_subscribers/edit.html.erb +2 -2
  256. data/app/views/spree/admin/webhooks_subscribers/index.html.erb +1 -1
  257. data/app/views/spree/admin/webhooks_subscribers/show.html.erb +58 -47
  258. data/app/views/spree/admin/zones/_form.html.erb +11 -15
  259. data/app/views/spree/admin/zones/index.html.erb +1 -1
  260. data/config/importmap.rb +2 -2
  261. data/config/locales/en.yml +3 -0
  262. data/config/routes.rb +13 -1
  263. data/lib/spree/admin/engine.rb +11 -1
  264. data/lib/spree/admin.rb +1 -0
  265. data/vendor/javascript/bootstrap--dist--js--bootstrap.bundle.min.js.js +4 -4
  266. data/vendor/javascript/dompurify.js +24 -24
  267. metadata +65 -9
  268. data/app/javascript/spree/admin/controllers/webhook_subscriber_events_controller.js +0 -19
@@ -1,6 +1,8 @@
1
1
  module Spree
2
2
  module Admin
3
3
  class BaseController < Spree::BaseController
4
+ include Spree::Admin::BreadcrumbConcern
5
+
4
6
  layout :choose_layout
5
7
 
6
8
  helper 'spree/base'
@@ -8,6 +10,7 @@ module Spree
8
10
  helper 'spree/locale'
9
11
  helper 'spree/currency'
10
12
  helper 'spree/addresses'
13
+ helper 'spree/integrations'
11
14
 
12
15
  before_action :authorize_admin
13
16
 
@@ -33,20 +36,24 @@ module Spree
33
36
  redirect_to spree.admin_forbidden_path, allow_other_host: true
34
37
  else
35
38
  store_location
36
- if defined?(spree_admin_login_path)
37
- redirect_to spree_admin_login_path, allow_other_host: true
38
- elsif respond_to?(:spree_login_path)
39
- redirect_to spree_login_path, allow_other_host: true
40
- elsif spree.respond_to?(:root_path)
41
- redirect_to spree.root_path, allow_other_host: true
42
- else
43
- redirect_to main_app.respond_to?(:root_path) ? main_app.root_path : '/'
44
- end
39
+ try_to_redirect_to_login_path
40
+ end
41
+ end
42
+
43
+ def try_to_redirect_to_login_path
44
+ if defined?(spree_admin_login_path)
45
+ redirect_to spree_admin_login_path, allow_other_host: true
46
+ elsif respond_to?(:spree_login_path)
47
+ redirect_to spree_login_path, allow_other_host: true
48
+ elsif spree.respond_to?(:root_path)
49
+ redirect_to spree.root_path, allow_other_host: true
50
+ else
51
+ redirect_to main_app.respond_to?(:root_path) ? main_app.root_path : '/'
45
52
  end
46
53
  end
47
54
 
48
55
  def try_spree_current_user
49
- if Spree.admin_user_class
56
+ if Spree.admin_user_class && Spree.admin_user_class != Spree.user_class
50
57
  send("current_#{Spree.admin_user_class.model_name.singular_route_key}")
51
58
  else
52
59
  # use Spree::Core::ControllerHelpers::Auth#try_spree_current_user
@@ -54,6 +61,10 @@ module Spree
54
61
  end
55
62
  end
56
63
 
64
+ def store_location_session_key
65
+ "#{Spree.admin_user_class.model_name.singular_route_key.to_sym}_return_to"
66
+ end
67
+
57
68
  def flash_message_for(object, event_sym)
58
69
  if object.is_a?(ActiveRecord::Relation)
59
70
  resource_desc = object.model.model_name.human.pluralize
@@ -5,6 +5,10 @@ module Spree
5
5
 
6
6
  before_action :load_user, only: [:index]
7
7
 
8
+ add_breadcrumb Spree.t(:orders), :admin_orders_path
9
+ add_breadcrumb Spree.t(:draft_orders), :admin_checkouts_path
10
+ add_breadcrumb_icon 'inbox'
11
+
8
12
  def index
9
13
  params[:q] ||= {}
10
14
  params[:q][:s] ||= 'created_at desc'
@@ -69,6 +69,10 @@ module Spree
69
69
 
70
70
  sort_orders.fetch(sort_order.to_s, 'manual')
71
71
  end
72
+
73
+ def permitted_resource_params
74
+ params.require(:classification).permit(Spree::PermittedAttributes.classification_attributes)
75
+ end
72
76
  end
73
77
  end
74
78
  end
@@ -3,6 +3,8 @@ module Spree
3
3
  class CouponCodesController < ResourceController
4
4
  belongs_to 'spree/promotion', find_by: :id
5
5
 
6
+ include PromotionsBreadcrumbConcern
7
+
6
8
  def collection
7
9
  return @collection if @collection.present?
8
10
 
@@ -1,6 +1,8 @@
1
1
  module Spree
2
2
  module Admin
3
3
  class CustomDomainsController < ResourceController
4
+ add_breadcrumb Spree.t(:domains), :admin_custom_domains_path
5
+
4
6
  protected
5
7
 
6
8
  def collection_url
@@ -14,6 +16,10 @@ module Spree
14
16
  def location_after_save
15
17
  spree.admin_custom_domains_path
16
18
  end
19
+
20
+ def permitted_resource_params
21
+ params.require(:custom_domain).permit(Spree::PermittedAttributes.custom_domain_attributes)
22
+ end
17
23
  end
18
24
  end
19
25
  end
@@ -1,6 +1,10 @@
1
1
  module Spree
2
2
  module Admin
3
3
  class CustomerReturnsController < ResourceController
4
+ add_breadcrumb_icon 'receipt-refund'
5
+ add_breadcrumb Spree.t(:returns), :admin_customer_returns_path
6
+ add_breadcrumb Spree.t(:customer_returns), :admin_customer_returns_path
7
+
4
8
  def index; end
5
9
 
6
10
  private
@@ -7,9 +7,15 @@ module Spree
7
7
  before_action :load_vendor
8
8
  before_action :clear_return_to, only: %i[show]
9
9
 
10
- def show; end
10
+ def show
11
+ @breadcrumb_icon = 'home'
12
+ add_breadcrumb Spree.t(:home), spree.admin_dashboard_path
13
+ end
11
14
 
12
- def getting_started; end
15
+ def getting_started
16
+ @breadcrumb_icon = 'map'
17
+ add_breadcrumb Spree.t('admin.getting_started'), spree.admin_getting_started_path
18
+ end
13
19
 
14
20
  def analytics
15
21
  @orders_scope = current_store.orders.complete.where(currency: params[:analytics_currency])
@@ -111,9 +117,11 @@ module Spree
111
117
  @audience_growth_rate = calc_growth_rate(@audience_total, previous_audience_total)
112
118
 
113
119
  @audience = if same_day?
114
- @audience_scope.group_by_hour(:created_at, range: analytics_time_range, time_zone: current_store.preferred_timezone, default_value: 0)
120
+ @audience_scope.group_by_hour(:created_at, range: analytics_time_range, time_zone: current_store.preferred_timezone,
121
+ default_value: 0)
115
122
  else
116
- @audience_scope.group_by_day(:created_at, range: analytics_time_range, time_zone: current_store.preferred_timezone, default_value: 0)
123
+ @audience_scope.group_by_day(:created_at, range: analytics_time_range, time_zone: current_store.preferred_timezone,
124
+ default_value: 0)
117
125
  end
118
126
 
119
127
  return unless defined?(Ahoy)
@@ -123,25 +131,22 @@ module Spree
123
131
  previous_visits_total = Ahoy::Visit.where(started_at: previous_analytics_time_range).count
124
132
  @visits_growth_rate = calc_growth_rate(@visits_total, previous_visits_total)
125
133
 
126
- @visits_scope = Ahoy::Visit.where(started_at: analytics_time_range)
127
- @visits_total = @visits_scope.count
128
- previous_visits_total = Ahoy::Visit.where(started_at: previous_analytics_time_range).count
129
- @visits_growth_rate = calc_growth_rate(@visits_total, previous_visits_total)
130
-
131
134
  @visits = if same_day?
132
- @visits_scope.group_by_hour(:started_at, range: analytics_time_range, time_zone: current_store.preferred_timezone, default_value: 0)
135
+ @visits_scope.group_by_hour(:started_at, range: analytics_time_range, time_zone: current_store.preferred_timezone,
136
+ default_value: 0)
133
137
  else
134
- @visits_scope.group_by_day(:started_at, range: analytics_time_range, time_zone: current_store.preferred_timezone, default_value: 0)
138
+ @visits_scope.group_by_day(:started_at, range: analytics_time_range, time_zone: current_store.preferred_timezone,
139
+ default_value: 0)
135
140
  end
136
141
 
137
- @top_landing_pages = @visits_scope.where.not(landing_page_title: [nil, '']).top(:landing_page_title, 10)
142
+ @top_landing_pages = @visits_scope.where.not(landing_page: [nil, '']).top(:landing_page, 10)
138
143
  @top_referrers = @visits_scope.where.not(referring_domain: current_store.custom_domains.pluck(:url) << current_store.url).top(
139
144
  :referring_domain, 10
140
145
  )
141
146
  @top_locations = @visits_scope.top(:country, 10)
142
147
  @top_devices = @visits_scope.group(:device_type).count.transform_keys do |device|
143
- device.nil? ? 'N/A' : device
144
- end.map { |series| [series.first, (series.second.to_f / @visits_scope.count) * 100] }
148
+ device.nil? ? 'N/A' : device
149
+ end.map { |series| [series.first, (series.second.to_f / @visits_scope.count) * 100] }
145
150
  end
146
151
  end
147
152
  end
@@ -3,6 +3,10 @@ module Spree
3
3
  class DigitalAssetsController < ResourceController
4
4
  belongs_to 'spree/product', find_by: :slug
5
5
 
6
+ include ProductsBreadcrumbConcern
7
+
8
+ before_action :add_breadcrumbs
9
+
6
10
  private
7
11
 
8
12
  def model_class
@@ -40,6 +44,10 @@ module Spree
40
44
  def permitted_resource_params
41
45
  params.require(:digital_asset).permit(permitted_digital_attributes)
42
46
  end
47
+
48
+ def add_breadcrumbs
49
+ add_breadcrumb Spree.t(:digital_assets), spree.admin_product_digital_assets_path(@product)
50
+ end
43
51
  end
44
52
  end
45
53
  end
@@ -40,8 +40,12 @@ module Spree
40
40
  end
41
41
 
42
42
  def assign_params
43
- @object.type = params.dig(:export, :type) if Spree::Export.available_types.map(&:to_s).include?(params.dig(:export, :type))
44
- @object.search_params = params.dig(:export, :search_params)
43
+ @object.type = permitted_resource_params[:type] if Spree::Export.available_types.map(&:to_s).include?(permitted_resource_params[:type])
44
+ @object.search_params = permitted_resource_params[:search_params]
45
+ end
46
+
47
+ def permitted_resource_params
48
+ params.require(:export).permit(permitted_export_attributes)
45
49
  end
46
50
  end
47
51
  end
@@ -0,0 +1,61 @@
1
+ module Spree
2
+ module Admin
3
+ class IntegrationsController < ResourceController
4
+ include Spree::Admin::PreferencesConcern
5
+
6
+ prepend_before_action :require_integration_type, only: %i[new create]
7
+ prepend_before_action :prevent_from_creating_more_integrations, only: %i[new create]
8
+
9
+ before_action -> { clear_empty_password_preferences(:integration) }, only: :update
10
+
11
+ before_action :check_if_can_connect, only: %i[create update]
12
+
13
+ add_breadcrumb Spree.t(:integrations), :admin_integrations_path
14
+ add_breadcrumb_icon 'plug-connected'
15
+
16
+ private
17
+
18
+ def allowed_integration_types
19
+ @allowed_integration_types ||= Rails.application.config.spree.integrations.map { |klass| [klass.to_s, klass] }.to_h
20
+ end
21
+
22
+ def require_integration_type
23
+ redirect_to spree.admin_integrations_path unless params.dig(:integration, :type).present?
24
+ end
25
+
26
+ def prevent_from_creating_more_integrations
27
+ type = params.dig(:integration, :type)
28
+
29
+ if allowed_integration_types.key?(type) && allowed_integration_types[type].for_store(current_store).exists?
30
+ redirect_to spree.admin_integrations_path
31
+ end
32
+ end
33
+
34
+ def build_resource
35
+ return unless params[:integration].present?
36
+
37
+ type = params[:integration].delete(:type)
38
+
39
+ if allowed_integration_types.key?(type)
40
+ @object = allowed_integration_types[type].new
41
+ else
42
+ flash[:error] = Spree.t('admin.integrations.invalid_integration_type')
43
+ redirect_to spree.admin_integrations_path
44
+ end
45
+ end
46
+
47
+ def check_if_can_connect
48
+ @integration.attributes = permitted_resource_params
49
+
50
+ unless @integration.can_connect?
51
+ @integration.errors.add(:base, :unable_to_connect, error_message: @integration.connection_error_message)
52
+ render action == :create ? :new : :edit, status: :unprocessable_entity
53
+ end
54
+ end
55
+
56
+ def permitted_resource_params
57
+ params.require(:integration).permit(*permitted_integration_attributes + @object.preferences.keys.map { |key| "preferred_#{key}" })
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,128 @@
1
+ module Spree
2
+ module Admin
3
+ class InvitationsController < BaseController
4
+ skip_before_action :authorize_admin, only: [:show, :accept]
5
+
6
+ add_breadcrumb Spree.t(:users), :admin_admin_users_path
7
+ add_breadcrumb Spree.t(:invitations), :admin_invitations_path
8
+
9
+ before_action :load_parent, except: [:show]
10
+ before_action :load_invitation, only: [:destroy]
11
+ before_action :load_roles, only: [:new, :create]
12
+
13
+ layout :choose_layout
14
+
15
+ # GET /admin/invitations
16
+ def index
17
+ params[:q] ||= {}
18
+ params[:q][:s] ||= 'created_at desc'
19
+ @search = scope.includes(:inviter, :role).ransack(params[:q])
20
+ @collection = @search.result
21
+ end
22
+
23
+ # GET /admin/invitations/new
24
+ def new
25
+ authorize! :create, Spree::Invitation
26
+ authorize! :manage, @parent
27
+
28
+ @invitation = Spree::Invitation.new
29
+ @invitation.resource = @parent
30
+ @invitation.inviter = try_spree_current_user
31
+ end
32
+
33
+ # POST /admin/invitations
34
+ def create
35
+ authorize! :create, Spree::Invitation
36
+ authorize! :manage, @parent
37
+
38
+ @invitation = Spree::Invitation.new(permitted_params)
39
+ @invitation.resource = @parent
40
+ @invitation.inviter = try_spree_current_user
41
+
42
+ if @invitation.save
43
+ respond_to do |format|
44
+ format.html { redirect_to spree.admin_invitations_path, notice: flash_message_for(@invitation, :successfully_created) }
45
+ format.turbo_stream
46
+ end
47
+ else
48
+ render :new, status: :unprocessable_entity
49
+ end
50
+ end
51
+
52
+ # GET /admin/invitations/:id?token=:token
53
+ def show
54
+ @invitation = Spree::Invitation.pending.not_expired.find_by!(id: params[:id], token: params[:token])
55
+ @parent = @invitation.resource
56
+
57
+ if try_spree_current_user.present?
58
+ unless @invitation.invitee == try_spree_current_user
59
+ raise ActiveRecord::RecordNotFound
60
+ end
61
+ elsif @invitation.invitee.present?
62
+ store_location
63
+ try_to_redirect_to_login_path
64
+ else
65
+ redirect_to spree.new_admin_admin_user_path(token: @invitation.token), status: :see_other
66
+ end
67
+ rescue ActiveRecord::RecordNotFound
68
+ redirect_to spree.root_path, alert: Spree.t('invalid_or_expired_invitation')
69
+ nil
70
+ end
71
+
72
+ # PUT /admin/invitations/:id/accept
73
+ def accept
74
+ @invitation = try_spree_current_user.invitations.pending.not_expired.find(params[:id])
75
+
76
+ authorize! :accept, @invitation
77
+
78
+ @invitation.accept!
79
+ redirect_to spree.admin_path, notice: Spree.t('invitation_accepted')
80
+ end
81
+
82
+ # PUT /admin/invitations/:id/resend
83
+ def resend
84
+ @invitation = scope.find(params[:id])
85
+ @invitation.resend!
86
+ redirect_back fallback_location: spree.admin_invitations_path, notice: Spree.t('invitation_resent')
87
+ end
88
+
89
+ # DELETE /admin/invitations/:id
90
+ def destroy
91
+ authorize! :destroy, @invitation
92
+
93
+ @invitation.destroy
94
+ redirect_back fallback_location: spree.admin_invitations_path, notice: flash_message_for(@invitation, :successfully_removed)
95
+ end
96
+
97
+ private
98
+
99
+ def load_invitation
100
+ @invitation = scope.find(params[:id])
101
+ end
102
+
103
+ def load_parent
104
+ @parent = current_store
105
+ end
106
+
107
+ def scope
108
+ Spree::Invitation.accessible_by(current_ability).where(resource: @parent)
109
+ end
110
+
111
+ def load_roles
112
+ @roles = Spree::Role.accessible_by(current_ability)
113
+ end
114
+
115
+ def permitted_params
116
+ params.require(:invitation).permit(Spree::PermittedAttributes.invitation_attributes)
117
+ end
118
+
119
+ def choose_layout
120
+ action_name == 'show' ? 'spree/minimal' : 'spree/admin'
121
+ end
122
+
123
+ def model_class
124
+ Spree::Invitation
125
+ end
126
+ end
127
+ end
128
+ end
@@ -116,6 +116,10 @@ module Spree
116
116
  model_class.new
117
117
  end
118
118
  end
119
+
120
+ def permitted_resource_params
121
+ params.require(:line_item).permit(permitted_line_item_attributes)
122
+ end
119
123
  end
120
124
  end
121
125
  end
@@ -3,6 +3,8 @@ module Spree
3
3
  class OauthApplicationsController < ResourceController
4
4
  before_action :set_default_scopes, only: [:new, :edit]
5
5
 
6
+ add_breadcrumb Spree.t(:developers), :admin_oauth_applications_path
7
+
6
8
  private
7
9
 
8
10
  def collection
@@ -22,6 +24,10 @@ module Spree
22
24
  def set_default_scopes
23
25
  @object.scopes = 'admin' if @object.scopes.blank?
24
26
  end
27
+
28
+ def permitted_resource_params
29
+ params.require(:oauth_application).permit(:name, :scopes)
30
+ end
25
31
  end
26
32
  end
27
33
  end
@@ -3,6 +3,11 @@ module Spree
3
3
  class OptionTypesController < ResourceController
4
4
  before_action :setup_new_option_value, only: :edit
5
5
 
6
+ include ProductsBreadcrumbConcern
7
+ add_breadcrumb Spree.t(:options), :admin_option_types_path
8
+
9
+ before_action :add_breadcrumbs
10
+
6
11
  private
7
12
 
8
13
  def collection
@@ -18,6 +23,16 @@ module Spree
18
23
  def setup_new_option_value
19
24
  @option_type.option_values.build if @option_type.option_values.empty?
20
25
  end
26
+
27
+ def add_breadcrumbs
28
+ if @option_type.present? && @option_type.persisted?
29
+ add_breadcrumb @option_type.presentation, spree.edit_admin_option_type_path(@option_type)
30
+ end
31
+ end
32
+
33
+ def permitted_resource_params
34
+ params.require(:option_type).permit(permitted_option_type_attributes)
35
+ end
21
36
  end
22
37
  end
23
38
  end
@@ -16,6 +16,10 @@ module Spree
16
16
  def location_after_save
17
17
  spree.edit_admin_option_type_path(@parent)
18
18
  end
19
+
20
+ def permitted_resource_params
21
+ params.require(:option_value).permit(permitted_option_value_attributes)
22
+ end
19
23
  end
20
24
  end
21
25
  end
@@ -84,6 +84,10 @@ module Spree
84
84
  def model_class
85
85
  Spree::ReturnAuthorization
86
86
  end
87
+
88
+ def permitted_resource_params
89
+ params.require(:return_authorization).permit(permitted_return_authorization_attributes)
90
+ end
87
91
  end
88
92
  end
89
93
  end
@@ -11,12 +11,23 @@ module Spree
11
11
 
12
12
  helper_method :model_class
13
13
 
14
+ add_breadcrumb Spree.t(:orders), :admin_orders_path
15
+ add_breadcrumb_icon 'inbox'
16
+
14
17
  def create
15
18
  @order = Spree::Order.create(created_by: try_spree_current_user, store: current_store)
16
19
 
17
20
  redirect_to spree.edit_admin_order_path(@order)
18
21
  end
19
22
 
23
+ def edit
24
+ unless @order.completed?
25
+ add_breadcrumb Spree.t(:draft_orders), :admin_checkouts_path
26
+ end
27
+
28
+ add_breadcrumb @order.number, spree.edit_admin_order_path(@order)
29
+ end
30
+
20
31
  def index
21
32
  params[:q] ||= {}
22
33
  params[:q][:s] ||= 'completed_at desc'
@@ -27,9 +27,10 @@ module Spree
27
27
 
28
28
  def create
29
29
  page_block_type = params.dig(:page_block, :type)
30
+ allowed_type = allowed_types.find { |type| type.to_s == page_block_type }
30
31
 
31
- if allowed_types.map(&:to_s).include?(page_block_type) && page_block_type.safe_constantize.present?
32
- @page_block = page_block_type.constantize.new
32
+ if allowed_type
33
+ @page_block = allowed_type.new
33
34
  @page_block.section = @page_section
34
35
  @page_block.save!
35
36
  end
@@ -38,6 +38,15 @@ module Spree
38
38
  @page_link.linkable_type ||= @parent.default_linkable_type
39
39
  @page_link.linkable ||= @parent.default_linkable_resource
40
40
  end
41
+
42
+ # for create action we don't pass the page_link at all
43
+ def permitted_resource_params
44
+ if params[:page_link].present?
45
+ params.require(:page_link).permit(permitted_page_link_attributes)
46
+ else
47
+ {}
48
+ end
49
+ end
41
50
  end
42
51
  end
43
52
  end
@@ -9,10 +9,15 @@ module Spree
9
9
  page_section_type = params.dig(:page_section, :type)
10
10
  allowed_types = available_page_section_types.map(&:to_s)
11
11
 
12
- if allowed_types.include?(page_section_type) && page_section_type.safe_constantize.present?
13
- @page_section = page_section_type.constantize.new(permitted_resource_params)
14
- @page_section.pageable = @pageable
15
- @page_section.save!
12
+ if allowed_types.include?(page_section_type)
13
+ # Find the actual class from our allowed types rather than using constantize
14
+ section_class = available_page_section_types.find { |type| type.to_s == page_section_type }
15
+
16
+ if section_class
17
+ @page_section = section_class.new(permitted_resource_params)
18
+ @page_section.pageable = @pageable
19
+ @page_section.save!
20
+ end
16
21
  end
17
22
  end
18
23
 
@@ -64,6 +69,10 @@ module Spree
64
69
  []
65
70
  end
66
71
  end
72
+
73
+ def permitted_resource_params
74
+ params.require(:page_section).permit(permitted_page_section_attributes + @object.preferences.keys.map { |key| "preferred_#{key}" })
75
+ end
67
76
  end
68
77
  end
69
78
  end
@@ -6,6 +6,9 @@ module Spree
6
6
  destroy.after :remove_preview_from_session
7
7
  create.after :remove_preview_from_session
8
8
 
9
+ include StorefrontBreadcrumbConcern
10
+ add_breadcrumb Spree.t(:pages), :admin_pages_path
11
+
9
12
  private
10
13
 
11
14
  def remove_preview_from_session
@@ -35,6 +38,10 @@ module Spree
35
38
  @search = @collection.ransack(params[:q])
36
39
  @collection = @search.result.page(params[:page]).per(params[:per_page])
37
40
  end
41
+
42
+ def permitted_resource_params
43
+ params.require(:page).permit(permitted_page_attributes)
44
+ end
38
45
  end
39
46
  end
40
47
  end
@@ -1,13 +1,25 @@
1
1
  module Spree
2
2
  module Admin
3
3
  class PaymentMethodsController < ResourceController
4
+ include Spree::Admin::PreferencesConcern
5
+ add_breadcrumb Spree.t(:payment_methods), :admin_payment_methods_path
6
+
4
7
  prepend_before_action :require_payment_type, only: [:new, :create]
5
- before_action :clear_empty_password_preferences, only: :update
8
+ before_action -> { clear_empty_password_preferences(:payment_method) }, only: :update
9
+ before_action :set_breadcrumb, only: :edit
6
10
 
7
11
  private
8
12
 
9
13
  def build_resource
10
- @object = params[:payment_method].delete(:type).constantize.new if params[:payment_method].present?
14
+ if params[:payment_method].present?
15
+ payment_type = params[:payment_method].delete(:type)
16
+ # Find the actual class from our allowed types rather than using constantize
17
+ payment_class = allowed_payment_types.find { |type| type.to_s == payment_type }
18
+
19
+ if payment_class
20
+ @object = payment_class.new
21
+ end
22
+ end
11
23
  end
12
24
 
13
25
  def collection
@@ -28,17 +40,16 @@ module Spree
28
40
  redirect_to spree.admin_payment_methods_path unless params.dig(:payment_method, :type).present?
29
41
  end
30
42
 
31
- def clear_empty_password_preferences
32
- if params[:payment_method].present?
33
- password_preferences = @object.preferences_of_type(:password)
34
- password_preferences.each do |preference|
35
- preference_key = "preferred_#{preference}"
43
+ def set_breadcrumb
44
+ add_breadcrumb @payment_method.name, spree.edit_admin_payment_method_path(@payment_method)
45
+ end
36
46
 
37
- if params.dig(:payment_method, preference_key).blank? && @object.preferences[preference].present?
38
- params[:payment_method].delete(preference_key)
39
- end
40
- end
41
- end
47
+ def allowed_payment_types
48
+ Rails.application.config.spree.payment_methods
49
+ end
50
+
51
+ def permitted_resource_params
52
+ params.require(:payment_method).permit(permitted_payment_method_attributes + @object.preferences.keys.map { |key| "preferred_#{key}" })
42
53
  end
43
54
  end
44
55
  end