spree_backend 4.3.0.rc1 → 4.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (271) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +222 -0
  3. data/.codeclimate.yml +36 -0
  4. data/.editorconfig +22 -0
  5. data/.eslintignore +7 -0
  6. data/.eslintrc.cjs +29 -0
  7. data/.gem_release.yml +4 -0
  8. data/.github/CONTRIBUTING.md +1 -0
  9. data/.github/ISSUE_TEMPLATE/bug_report.md +47 -0
  10. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  11. data/.github/ISSUE_TEMPLATE.md +39 -0
  12. data/.github/dependabot.yml +7 -0
  13. data/.github/workflows/spelling_lint.yml +34 -0
  14. data/.gitignore +63 -0
  15. data/.rubocop.yml +197 -0
  16. data/.solargraph.yml +20 -0
  17. data/.stylelintignore +4 -0
  18. data/.stylelintrc +6 -0
  19. data/CODE_OF_CONDUCT.md +22 -0
  20. data/Gemfile +59 -3
  21. data/README.md +123 -0
  22. data/SECURITY.md +1 -0
  23. data/app/assets/config/spree_backend_manifest.js +1 -1
  24. data/app/assets/images/backend-cloud-arrow-up.svg +4 -0
  25. data/app/assets/images/backend-eye-open.svg +1 -1
  26. data/app/assets/images/backend-file-earmark-font.svg +4 -0
  27. data/app/assets/images/backend-file-earmark-image.svg +4 -0
  28. data/app/assets/images/backend-file-earmark-music.svg +4 -0
  29. data/app/assets/images/backend-file-earmark-pdf.svg +4 -0
  30. data/app/assets/images/backend-file-earmark-play.svg +4 -0
  31. data/app/assets/images/backend-file-earmark-spreadsheet.svg +3 -0
  32. data/app/assets/images/backend-file-earmark-zip.svg +4 -0
  33. data/app/assets/images/backend-file-earmark.svg +3 -0
  34. data/app/assets/images/backend-hdd.svg +4 -0
  35. data/app/assets/images/backend-link.svg +4 -0
  36. data/app/assets/images/backend-view.svg +1 -1
  37. data/app/assets/images/noimage/backend-missing-image.svg +4 -0
  38. data/app/assets/javascripts/spree/backend/adjustments.js +5 -5
  39. data/app/assets/javascripts/spree/backend/admin.js +4 -6
  40. data/app/assets/javascripts/spree/backend/calculator.js +1 -1
  41. data/app/assets/javascripts/spree/backend/checkouts/edit.js +1 -1
  42. data/app/assets/javascripts/spree/backend/cms/links.es6 +1 -1
  43. data/app/assets/javascripts/spree/backend/cms/live_preview.es6 +1 -1
  44. data/app/assets/javascripts/spree/backend/cms/page.es6 +22 -40
  45. data/app/assets/javascripts/spree/backend/cms/section.es6 +1 -1
  46. data/app/assets/javascripts/spree/backend/gateway.js +1 -1
  47. data/app/assets/javascripts/spree/backend/general_settings.js +1 -1
  48. data/app/assets/javascripts/spree/backend/global/_index.js +3 -1
  49. data/app/assets/javascripts/spree/backend/global/alerts.es6 +1 -1
  50. data/app/assets/javascripts/spree/backend/global/animate_css.es6 +19 -0
  51. data/app/assets/javascripts/spree/backend/global/fetch_request_utility.es6 +114 -0
  52. data/app/assets/javascripts/spree/backend/global/flatpickr.es6 +2 -1
  53. data/app/assets/javascripts/spree/backend/global/info_alert.es6 +1 -1
  54. data/app/assets/javascripts/spree/backend/global/radio_panel_toggle.es6 +1 -1
  55. data/app/assets/javascripts/spree/backend/global/ransack.es6 +7 -5
  56. data/app/assets/javascripts/spree/backend/global/responsive_menus.es6 +1 -1
  57. data/app/assets/javascripts/spree/backend/global/select2_autocomplete.es6 +80 -91
  58. data/app/assets/javascripts/spree/backend/global/select2_populate.es6 +39 -13
  59. data/app/assets/javascripts/spree/backend/global/side_scroll_indication.es6 +2 -2
  60. data/app/assets/javascripts/spree/backend/global/sortable.es6 +1 -1
  61. data/app/assets/javascripts/spree/backend/global/tinymce.es6 +4 -3
  62. data/app/assets/javascripts/spree/backend/line_items.js +7 -9
  63. data/app/assets/javascripts/spree/backend/line_items_on_order_edit.js +23 -28
  64. data/app/assets/javascripts/spree/backend/menus/_index.es6 +0 -1
  65. data/app/assets/javascripts/spree/backend/menus/menu_item.es6 +1 -1
  66. data/app/assets/javascripts/spree/backend/multi_currency.js +2 -2
  67. data/app/assets/javascripts/spree/backend/option_type_autocomplete.js +7 -1
  68. data/app/assets/javascripts/spree/backend/orders/edit.js +1 -1
  69. data/app/assets/javascripts/spree/backend/payments/edit.js +32 -22
  70. data/app/assets/javascripts/spree/backend/payments/new.js +1 -1
  71. data/app/assets/javascripts/spree/backend/product_picker.js +16 -25
  72. data/app/assets/javascripts/spree/backend/progress.js +5 -3
  73. data/app/assets/javascripts/spree/backend/promotions.js +3 -1
  74. data/app/assets/javascripts/spree/backend/returns/expedited_exchanges_warning.js +1 -1
  75. data/app/assets/javascripts/spree/backend/returns/return_item_selection.js +1 -1
  76. data/app/assets/javascripts/spree/backend/shipments.js +80 -79
  77. data/app/assets/javascripts/spree/backend/spree-select2.js +1 -1
  78. data/app/assets/javascripts/spree/backend/states.js +1 -1
  79. data/app/assets/javascripts/spree/backend/stock_location.js +1 -1
  80. data/app/assets/javascripts/spree/backend/stock_management.js +1 -1
  81. data/app/assets/javascripts/spree/backend/stock_movement.js +58 -13
  82. data/app/assets/javascripts/spree/backend/stock_transfer.js +62 -32
  83. data/app/assets/javascripts/spree/backend/taxon_autocomplete.js +14 -7
  84. data/app/assets/javascripts/spree/backend/taxons.js +17 -14
  85. data/app/assets/javascripts/spree/backend/user_picker.js +1 -1
  86. data/app/assets/javascripts/spree/backend/users/edit.js +1 -1
  87. data/app/assets/javascripts/spree/backend/variant_autocomplete.js +19 -11
  88. data/app/assets/javascripts/spree/backend/variant_management.js +1 -1
  89. data/app/assets/javascripts/spree/backend/zone.js +1 -1
  90. data/app/assets/javascripts/spree/backend.js +13 -33
  91. data/app/assets/javascripts/spree.js +2 -9
  92. data/app/assets/stylesheets/spree/backend/components/_main.scss +8 -0
  93. data/app/assets/stylesheets/spree/backend/plugins/_nav_x.scss +1 -1
  94. data/app/assets/stylesheets/spree/backend/plugins/_select2_custom.scss +1 -1
  95. data/app/assets/stylesheets/spree/backend/shared/_base.scss +52 -0
  96. data/app/assets/stylesheets/spree/backend/shared/_forms.scss +1 -1
  97. data/app/assets/stylesheets/spree/backend/shared/_sortable_tree.scss +62 -0
  98. data/app/assets/stylesheets/spree/backend/spree_admin.css.scss +3 -0
  99. data/app/assets/stylesheets/spree/backend/views/_digitals.scss +33 -0
  100. data/app/assets/stylesheets/spree/backend/views/{prototypes.scss → _prototypes.scss} +0 -0
  101. data/app/assets/stylesheets/spree/backend/views/_taxonomies.scss +3 -0
  102. data/app/controllers/spree/admin/base_controller.rb +4 -13
  103. data/app/controllers/spree/admin/digitals_controller.rb +33 -0
  104. data/app/controllers/spree/admin/general_settings_controller.rb +0 -5
  105. data/app/controllers/spree/admin/images_controller.rb +25 -8
  106. data/app/controllers/spree/admin/oauth_applications_controller.rb +17 -0
  107. data/app/controllers/spree/admin/orders/customer_details_controller.rb +2 -2
  108. data/app/controllers/spree/admin/orders_controller.rb +11 -3
  109. data/app/controllers/spree/admin/payment_methods_controller.rb +4 -4
  110. data/app/controllers/spree/admin/payments_controller.rb +1 -1
  111. data/app/controllers/spree/admin/products_controller.rb +5 -3
  112. data/app/controllers/spree/admin/promotions_controller.rb +1 -1
  113. data/app/controllers/spree/admin/properties_controller.rb +1 -1
  114. data/app/controllers/spree/admin/resource_controller.rb +17 -15
  115. data/app/controllers/spree/admin/return_index_controller.rb +1 -1
  116. data/app/controllers/spree/admin/stock_transfers_controller.rb +2 -2
  117. data/app/controllers/spree/admin/store_credits_controller.rb +2 -2
  118. data/app/controllers/spree/admin/stores_controller.rb +2 -2
  119. data/app/controllers/spree/admin/taxons_controller.rb +23 -38
  120. data/app/controllers/spree/admin/users_controller.rb +6 -19
  121. data/app/controllers/spree/admin/variants_controller.rb +1 -2
  122. data/app/controllers/spree/admin/webhooks_subscribers_controller.rb +48 -0
  123. data/app/helpers/spree/admin/base_helper.rb +27 -9
  124. data/app/helpers/spree/admin/digital_helper.rb +28 -0
  125. data/app/helpers/spree/admin/menu_helper.rb +0 -21
  126. data/app/helpers/spree/admin/navigation_helper.rb +19 -9
  127. data/app/helpers/spree/admin/sortable_tree_helper.rb +31 -0
  128. data/app/helpers/spree/admin/stores_helper.rb +1 -1
  129. data/app/helpers/spree/admin/webhooks_subscribers_helper.rb +31 -0
  130. data/app/javascript/spree/dashboard/controllers/clipboard_controller.js +12 -0
  131. data/app/javascript/spree/dashboard/controllers/password_toggle_controller.js +14 -0
  132. data/app/javascript/spree/dashboard/controllers/sortable_tree_controller.js +55 -0
  133. data/app/javascript/spree/dashboard/controllers/spree_controller.js +25 -0
  134. data/app/javascript/spree/dashboard/controllers/upload_button_controller.js +13 -0
  135. data/app/javascript/spree/dashboard/controllers/webhooks_subscriber_events_controller.js +19 -0
  136. data/app/javascript/spree/dashboard/index.js +49 -0
  137. data/app/{assets/javascripts/spree/backend/global/bootstrap.es6 → javascript/spree/dashboard/utilities/bootstrap.js} +6 -2
  138. data/app/javascript/spree/dashboard/utilities/request_utility.js +54 -0
  139. data/app/models/spree/backend_configuration.rb +11 -0
  140. data/app/views/spree/admin/adjustments/_form.html.erb +2 -2
  141. data/app/views/spree/admin/adjustments/index.html.erb +1 -0
  142. data/app/views/spree/admin/cms_pages/_form.html.erb +8 -8
  143. data/app/views/spree/admin/cms_pages/edit.html.erb +1 -6
  144. data/app/views/spree/admin/cms_sections/_form.html.erb +2 -2
  145. data/app/views/spree/admin/cms_sections/types/_featured_article.html.erb +6 -6
  146. data/app/views/spree/admin/cms_sections/types/_hero_image.html.erb +9 -10
  147. data/app/views/spree/admin/cms_sections/types/_image_gallery.html.erb +24 -27
  148. data/app/views/spree/admin/cms_sections/types/_rich_text_content.html.erb +1 -1
  149. data/app/views/spree/admin/cms_sections/types/_side_by_side_images.html.erb +14 -14
  150. data/app/views/spree/admin/countries/_form.html.erb +4 -4
  151. data/app/views/spree/admin/customer_returns/new.html.erb +1 -1
  152. data/app/views/spree/admin/digitals/_form.html.erb +35 -0
  153. data/app/views/spree/admin/digitals/index.html.erb +25 -0
  154. data/app/views/spree/admin/general_settings/edit.html.erb +1 -22
  155. data/app/views/spree/admin/images/index.html.erb +3 -1
  156. data/app/views/spree/admin/menu_items/_form.html.erb +6 -6
  157. data/app/views/spree/admin/menus/_form.html.erb +3 -3
  158. data/app/views/spree/admin/menus/edit.html.erb +18 -18
  159. data/app/views/spree/admin/oauth_applications/_form.html.erb +22 -0
  160. data/app/views/spree/admin/oauth_applications/create.turbo_stream.erb +38 -0
  161. data/app/views/spree/admin/oauth_applications/edit.html.erb +13 -0
  162. data/app/views/spree/admin/oauth_applications/index.html.erb +51 -0
  163. data/app/views/spree/admin/oauth_applications/new.html.erb +15 -0
  164. data/app/views/spree/admin/option_types/_form.html.erb +3 -3
  165. data/app/views/spree/admin/option_types/_option_value_fields.html.erb +2 -2
  166. data/app/views/spree/admin/orders/_channel_form.html.erb +1 -1
  167. data/app/views/spree/admin/orders/_form.html.erb +1 -0
  168. data/app/views/spree/admin/orders/_line_items.html.erb +1 -1
  169. data/app/views/spree/admin/orders/_line_items_edit_form.html.erb +1 -0
  170. data/app/views/spree/admin/orders/_order_actions.html.erb +6 -0
  171. data/app/views/spree/admin/orders/_search.html.erb +151 -0
  172. data/app/views/spree/admin/orders/_shipment_manifest.html.erb +1 -1
  173. data/app/views/spree/admin/orders/index.html.erb +2 -151
  174. data/app/views/spree/admin/payment_methods/_form.html.erb +2 -2
  175. data/app/views/spree/admin/payments/_list.html.erb +1 -1
  176. data/app/views/spree/admin/products/_autocomplete.js.erb +6 -2
  177. data/app/views/spree/admin/products/_form.html.erb +32 -21
  178. data/app/views/spree/admin/products/index.html.erb +3 -1
  179. data/app/views/spree/admin/products/new.html.erb +6 -6
  180. data/app/views/spree/admin/promotion_actions/create.js.erb +1 -1
  181. data/app/views/spree/admin/promotion_categories/_form.html.erb +2 -2
  182. data/app/views/spree/admin/promotions/_form.html.erb +5 -5
  183. data/app/views/spree/admin/properties/_form.html.erb +3 -3
  184. data/app/views/spree/admin/properties/index.html.erb +10 -0
  185. data/app/views/spree/admin/prototypes/_form.html.erb +4 -4
  186. data/app/views/spree/admin/refunds/new.html.erb +2 -2
  187. data/app/views/spree/admin/reimbursement_types/_form.html.erb +2 -2
  188. data/app/views/spree/admin/return_authorizations/_form.html.erb +3 -3
  189. data/app/views/spree/admin/roles/_form.html.erb +1 -1
  190. data/app/views/spree/admin/shared/_account_nav.html.erb +3 -3
  191. data/app/views/spree/admin/shared/_address_form.html.erb +4 -4
  192. data/app/views/spree/admin/shared/_head.html.erb +4 -8
  193. data/app/views/spree/admin/shared/_main_menu.html.erb +12 -0
  194. data/app/views/spree/admin/shared/_new_resource_links.html.erb +1 -1
  195. data/app/views/spree/admin/shared/_product_tabs.html.erb +8 -0
  196. data/app/views/spree/admin/shared/_version.html.erb +1 -1
  197. data/app/views/spree/admin/shared/cms/_spree_product.html.erb +24 -11
  198. data/app/views/spree/admin/shared/cms/_spree_taxon.html.erb +24 -11
  199. data/app/views/spree/admin/shared/linkables/_spree_cms_page.erb +3 -8
  200. data/app/views/spree/admin/shared/linkables/_spree_product.html.erb +2 -2
  201. data/app/views/spree/admin/shared/linkables/_spree_taxon.html.erb +2 -2
  202. data/app/views/spree/admin/shared/linkables/_url.html.erb +1 -1
  203. data/app/views/spree/admin/shared/named_types/_form.html.erb +1 -1
  204. data/app/views/spree/admin/{menus/nested_menu_items/_item_bar.html.erb → shared/sortable_tree/_menu.html.erb} +10 -7
  205. data/app/views/spree/admin/shared/sortable_tree/_taxonomy.html.erb +34 -0
  206. data/app/views/spree/admin/shared/sub_menu/_apps.html.erb +3 -0
  207. data/app/views/spree/admin/shared/sub_menu/_integrations.html.erb +3 -0
  208. data/app/views/spree/admin/shipping_categories/_form.html.erb +1 -1
  209. data/app/views/spree/admin/shipping_methods/_form.html.erb +8 -8
  210. data/app/views/spree/admin/states/_form.html.erb +2 -2
  211. data/app/views/spree/admin/stock_locations/_form.html.erb +2 -2
  212. data/app/views/spree/admin/stock_movements/_form.html.erb +3 -3
  213. data/app/views/spree/admin/store_credit_categories/_form.html.erb +1 -1
  214. data/app/views/spree/admin/store_credits/_form.html.erb +4 -4
  215. data/app/views/spree/admin/stores/_form.html.erb +280 -227
  216. data/app/views/spree/admin/tax_categories/_form.html.erb +4 -4
  217. data/app/views/spree/admin/tax_rates/_form.html.erb +4 -3
  218. data/app/views/spree/admin/taxonomies/_form.html.erb +2 -2
  219. data/app/views/spree/admin/taxonomies/edit.html.erb +34 -29
  220. data/app/views/spree/admin/taxons/_form.html.erb +101 -57
  221. data/app/views/spree/admin/taxons/edit.html.erb +6 -3
  222. data/app/views/spree/admin/taxons/index.html.erb +1 -1
  223. data/app/views/spree/admin/taxons/new.html.erb +16 -0
  224. data/app/views/spree/admin/users/_form.html.erb +3 -3
  225. data/app/views/spree/admin/users/_lifetime_stats.html.erb +16 -4
  226. data/app/views/spree/admin/users/edit.html.erb +0 -40
  227. data/app/views/spree/admin/users/items.html.erb +1 -1
  228. data/app/views/spree/admin/variants/_autocomplete.js.erb +11 -7
  229. data/app/views/spree/admin/variants/_autocomplete_line_items_stock.js.erb +2 -2
  230. data/app/views/spree/admin/variants/_autocomplete_stock.js.erb +6 -6
  231. data/app/views/spree/admin/variants/_split.js.erb +1 -1
  232. data/app/views/spree/admin/variants/index.html.erb +4 -1
  233. data/app/views/spree/admin/webhooks_subscribers/_form.html.erb +101 -0
  234. data/app/views/spree/admin/webhooks_subscribers/edit.html.erb +13 -0
  235. data/app/views/spree/admin/webhooks_subscribers/index.html.erb +47 -0
  236. data/app/views/spree/admin/webhooks_subscribers/new.html.erb +13 -0
  237. data/app/views/spree/admin/webhooks_subscribers/show.html.erb +59 -0
  238. data/app/views/spree/admin/zones/_country_members.html.erb +1 -1
  239. data/app/views/spree/admin/zones/_form.html.erb +2 -2
  240. data/app/views/spree/admin/zones/_state_members.html.erb +1 -1
  241. data/app/views/spree/layouts/admin.html.erb +1 -11
  242. data/codespell.txt +8 -0
  243. data/config/locales/en.yml +273 -0
  244. data/config/routes.rb +6 -2
  245. data/lib/generators/spree/backend/install/install_generator.rb +4 -2
  246. data/lib/generators/spree/backend/install/templates/app/javascript/spree-dashboard.js +7 -0
  247. data/lib/spree/backend/engine.rb +2 -1
  248. data/lib/spree/backend/testing_support/capybara_utils.rb +53 -0
  249. data/lib/spree/backend/testing_support/flash.rb +38 -0
  250. data/lib/spree/backend/testing_support/flatpickr_capybara.rb +126 -0
  251. data/lib/spree/backend/version.rb +9 -0
  252. data/lib/spree/backend.rb +2 -1
  253. data/lib/spree_backend.rb +17 -0
  254. data/license.md +13 -0
  255. data/package.json +46 -0
  256. data/rollup.config.js +41 -0
  257. data/spree_backend.gemspec +18 -17
  258. data/vendor/assets/javascripts/purify.js +1 -1
  259. data/vendor/assets/stylesheets/animate.css +2 -4
  260. data/yarn.lock +959 -0
  261. metadata +120 -37
  262. data/app/assets/javascripts/spree/backend/menus/menu.es6 +0 -58
  263. data/app/assets/javascripts/spree/backend/taxon_permalink_preview.js +0 -11
  264. data/app/assets/javascripts/spree/backend/taxon_tree_menu.js +0 -35
  265. data/app/assets/javascripts/spree/backend/taxonomy.js +0 -178
  266. data/app/views/spree/admin/taxonomies/_js_head.html.erb +0 -7
  267. data/vendor/assets/javascripts/jquery.jstree/jquery.jstree.js +0 -4564
  268. data/vendor/assets/javascripts/js.cookie.js +0 -163
  269. data/vendor/assets/javascripts/modernizr.js +0 -3
  270. data/vendor/assets/stylesheets/jquery.jstree/themes/spree/style.scss +0 -230
  271. data/vendor/assets/stylesheets/jquery.jstree/themes/spree/throbber.gif +0 -0
@@ -1,4 +1,4 @@
1
- document.addEventListener('DOMContentLoaded', function() {
1
+ document.addEventListener("spree:load", function() {
2
2
  const pageVisabilityAttribute = document.querySelectorAll('[data-cms-page-id]')
3
3
  const pageTypeSelector = document.getElementById('cms_page_type')
4
4
  const el = document.getElementById('cmsPagesectionsArea')
@@ -32,32 +32,24 @@ function handleTogglePageVisibility(obj) {
32
32
  let checkedState = null
33
33
  if (obj.checked) checkedState = true
34
34
 
35
- const pageId = parseInt(obj.dataset.cmsPageId, 10)
35
+ const pageId = obj.dataset.cmsPageId
36
36
 
37
37
  const data = {
38
38
  cms_page: {
39
39
  visible: checkedState
40
40
  }
41
41
  }
42
+ const requestData = {
43
+ uri: Spree.routes.pages_api_v2 + `/${pageId}`,
44
+ method: 'PATCH',
45
+ dataBody: data,
46
+ }
47
+ spreeFetchRequest(requestData, handleToggleSuccess)
42
48
 
43
- fetch(Spree.routes.pages_api_v2 + `/${pageId}`, {
44
- method: 'PATCH',
45
- headers: {
46
- Authorization: 'Bearer ' + OAUTH_TOKEN,
47
- 'Content-Type': 'application/json'
48
- },
49
- body: JSON.stringify(data)
50
- })
51
- .then(response => {
52
- if (response.ok) {
53
- reloadPreview()
54
- toggleVisibilityState(obj)
55
- } else {
56
- // eslint-disable-next-line no-undef
57
- spreeHandleApiRequestError(response)
58
- }
59
- })
60
- .catch(err => { console.error(err) })
49
+ function handleToggleSuccess() {
50
+ toggleVisibilityState(obj)
51
+ reloadPreview()
52
+ }
61
53
  }
62
54
 
63
55
  function toggleVisibilityState(obj) {
@@ -83,28 +75,18 @@ function reloadPreview() {
83
75
  }
84
76
 
85
77
  function handleSectionReposition(evt) {
78
+ const sectionId = evt.item.dataset.sectionId
86
79
  const data = {
87
- section_id: parseInt(evt.item.dataset.sectionId, 10),
88
- new_position_idx: parseInt(evt.newIndex, 10)
80
+ cms_section: {
81
+ position: parseInt(evt.newIndex, 10) + 1
82
+ }
89
83
  }
90
-
91
- fetch(Spree.routes.sections_api_v2 + '/reposition', {
92
- method: 'PATCH',
93
- headers: {
94
- Authorization: 'Bearer ' + OAUTH_TOKEN,
95
- 'Content-Type': 'application/json'
96
- },
97
- body: JSON.stringify(data)
98
- })
99
- .then(response => {
100
- if (response.ok) {
101
- reloadPreview()
102
- } else {
103
- // eslint-disable-next-line no-undef
104
- spreeHandleApiRequestError(response.status)
105
- }
106
- })
107
- .catch(err => { console.error(err) })
84
+ const requestData = {
85
+ uri: `${Spree.routes.sections_api_v2}/${sectionId}`,
86
+ method: 'PATCH',
87
+ dataBody: data,
88
+ }
89
+ spreeFetchRequest(requestData, reloadPreview)
108
90
  }
109
91
 
110
92
  function updateCmsPageType() {
@@ -1,4 +1,4 @@
1
- document.addEventListener('DOMContentLoaded', function() {
1
+ document.addEventListener("spree:load", function() {
2
2
  const sectionKindSelector = $('#cms_section_type').select2()
3
3
  const layoutSwitcher = $('#cms_section_layout_style').select2()
4
4
 
@@ -1,4 +1,4 @@
1
- $(function () {
1
+ document.addEventListener("spree:load", function() {
2
2
  var originalGtwyType = $('#gtwy-type').prop('value')
3
3
  $('div#gateway-settings-warning').hide()
4
4
  $('#gtwy-type').change(function () {
@@ -1,5 +1,5 @@
1
1
  /* global show_flash */
2
- $(function () {
2
+ document.addEventListener("spree:load", function() {
3
3
  $('[data-hook=general_settings_clear_cache] #clear_cache').click(function () {
4
4
  if (confirm(Spree.translations.are_you_sure)) {
5
5
  $.ajax({
@@ -1,5 +1,6 @@
1
1
  //= require spree/backend/global/alerts
2
- //= require spree/backend/global/bootstrap
2
+ //= require spree/backend/global/animate_css
3
+ //= require spree/backend/global/fetch_request_utility
3
4
  //= require spree/backend/global/flatpickr
4
5
  //= require spree/backend/global/ransack
5
6
  //= require spree/backend/global/info_alert
@@ -9,3 +10,4 @@
9
10
  //= require spree/backend/global/select2_populate
10
11
  //= require spree/backend/global/sortable
11
12
  //= require spree/backend/global/side_scroll_indication
13
+ //= require spree/backend/global/tinymce
@@ -1,6 +1,6 @@
1
1
  /* global Swal */
2
2
 
3
- document.addEventListener('DOMContentLoaded', function() {
3
+ document.addEventListener("spree:load", function() {
4
4
  const alertEl = document.querySelectorAll('[data-alert-type]')
5
5
 
6
6
  if (!alertEl) return
@@ -0,0 +1,19 @@
1
+ /* eslint-disable no-unused-vars */
2
+
3
+ //
4
+ // Handle clearing out of animation styles from complete animation.
5
+ const animateCSS = (element, animation, speed, prefix = 'animate__') =>
6
+ new Promise((resolve) => {
7
+ const animationName = `${prefix}${animation}`
8
+ const node = document.querySelector(element)
9
+
10
+ node.classList.add(`${prefix}animated`, animationName, prefix + speed)
11
+
12
+ function handleAnimationEnd(event) {
13
+ event.stopPropagation()
14
+ node.classList.remove(`${prefix}animated`, animationName)
15
+ resolve('Animation ended')
16
+ }
17
+
18
+ node.addEventListener('animationend', handleAnimationEnd, { once: true })
19
+ })
@@ -0,0 +1,114 @@
1
+ /* eslint-disable no-undef */
2
+ /* eslint-disable no-unused-vars */
3
+
4
+ //
5
+ // Shows the progress bar on fech requests
6
+ const showProgressIndicator = () => {
7
+ Turbo.navigator.delegate.adapter.progressBar.setValue(0)
8
+ Turbo.navigator.delegate.adapter.progressBar.show()
9
+ }
10
+
11
+ //
12
+ // Hides the progress bar on fech requests
13
+ const hideProgressIndicator = () => {
14
+ Turbo.navigator.delegate.adapter.progressBar.setValue(1)
15
+ Turbo.navigator.delegate.adapter.progressBar.hide()
16
+ }
17
+
18
+ //
19
+ // Handles the fetch request response.
20
+ // If the response has content it is returned, else if the response is a 204 no-content,
21
+ // the resolved text is returned.
22
+ const spreeHandleFetchRequestResponse = function(response) {
23
+ hideProgressIndicator()
24
+
25
+ if (response.status === 204) {
26
+ return response.text()
27
+ } else {
28
+ return response.json()
29
+ }
30
+ }
31
+
32
+ //
33
+ // Handles fech request errors by triggering the appropriate flash alert type and displaying
34
+ // the response message.
35
+ const spreeHandleFetchRequestError = function(data) {
36
+ if (data.error != null) {
37
+ show_flash('error', data.error)
38
+ } else if (data.message != null) {
39
+ show_flash('success', data.message)
40
+ } else if (data.exception != null) {
41
+ show_flash('info', data.exception)
42
+ } else if (data.detail != null) {
43
+ show_flash('info', data.detail)
44
+ }
45
+ }
46
+
47
+ //
48
+ // Reloads the window.
49
+ const spreeWindowReload = function() {
50
+ window.location.reload()
51
+ }
52
+
53
+ //
54
+ // SPREE FECTCH REQUEST
55
+ // Pass a json object containing your fetch request details and settings, you can also send a second optional
56
+ // argument, this second argument is your success response handler, and lastly a third argument that carries
57
+ // through a target element to the response method if needed, the second and third arguments are optional.
58
+ // When using spreeFetchRequest() the loading... progress bar, flash notice and errors are all handled for you.
59
+ //
60
+ // EXAMPLE SENDING A POST REQUEST TO CREATE A NEW SHIPMENT:
61
+ // const data = {
62
+ // order_id: 'H8213728798',
63
+ // variant_id: 2,
64
+ // quantity: 4,
65
+ // stock_location_id: 1
66
+ // }
67
+ //
68
+ // const requestData = {
69
+ // // request details
70
+ // uri: Spree.routes.shipments_api_v2,
71
+ // method: 'POST',
72
+ // dataBody: data,
73
+ //
74
+ // // Optional Settings
75
+ // // disableProgressIndicator: true, Allows you to disable the progress loader bar if needed.
76
+ // // formatDataBody: false If you have pre-formatted data, pass this option to stop the function performing the default stringify.
77
+ // }
78
+ // spreeFetchRequest(requestData, someCallbackFunction, this)
79
+ //
80
+ const spreeFetchRequest = function(requstData, success = null, target = null) {
81
+ if (!requstData.disableProgressIndicator === true) showProgressIndicator()
82
+
83
+ let requestDataBody
84
+
85
+ const requestUri = requstData.uri || null
86
+ const requestMethod = requstData.method || 'GET'
87
+ const requestContentType = requstData.ContentType || 'application/json'
88
+
89
+ if (requstData.formatDataBody === false) {
90
+ requestDataBody = requstData.dataBody
91
+ } else {
92
+ requestDataBody = JSON.stringify(requstData.dataBody) || null
93
+ }
94
+
95
+ if (requestUri == null) return
96
+
97
+ fetch(requestUri, {
98
+ method: requestMethod,
99
+ headers: {
100
+ 'Authorization': 'Bearer ' + OAUTH_TOKEN,
101
+ 'Content-Type': requestContentType
102
+ },
103
+ body: requestDataBody
104
+ })
105
+ .then((response) => spreeHandleFetchRequestResponse(response)
106
+ .then((data) => {
107
+ if (response.ok) {
108
+ if (success != null) success(data, target)
109
+ } else {
110
+ spreeHandleFetchRequestError(data)
111
+ }
112
+ }))
113
+ .catch(err => console.log(err))
114
+ }
@@ -1,4 +1,4 @@
1
- document.addEventListener('DOMContentLoaded', function() {
1
+ document.addEventListener("spree:load", function() {
2
2
  flatpickr.setDefaults({
3
3
  altInput: true,
4
4
  time_24hr: true,
@@ -20,3 +20,4 @@ document.addEventListener('DOMContentLoaded', function() {
20
20
 
21
21
  flatpickr('.datepicker', {})
22
22
  })
23
+
@@ -1,5 +1,5 @@
1
1
  /* global Swal */
2
- document.addEventListener('DOMContentLoaded', function() {
2
+ document.addEventListener("spree:load", function() {
3
3
  const infoToggle = document.querySelectorAll('[data-show-info]')
4
4
 
5
5
  infoToggle.forEach(function(infoElem) {
@@ -2,7 +2,7 @@
2
2
  radioControlsVisibilityOfElement:
3
3
  Apply to individual radio button that makes another element visible when checked
4
4
  **/
5
- document.addEventListener('DOMContentLoaded', function() {
5
+ document.addEventListener("spree:load", function() {
6
6
  $.fn.radioControlsVisibilityOfElement = function(dependentElementSelector) {
7
7
  if (!this.get(0)) { return }
8
8
  var showValue = this.get(0).value
@@ -1,4 +1,4 @@
1
- document.addEventListener('DOMContentLoaded', function() {
1
+ document.addEventListener("spree:load", function() {
2
2
  const QuickSearchInput = document.getElementById('quick_search')
3
3
 
4
4
  if (QuickSearchInput) {
@@ -80,7 +80,7 @@ document.addEventListener('DOMContentLoaded', function() {
80
80
  }
81
81
  })
82
82
 
83
- // per page dropdown
83
+ // per page drop-down
84
84
  // preserves all selected filters / queries supplied by user
85
85
  // changes only per_page value
86
86
  $('.js-per-page-select').change(function() {
@@ -92,16 +92,18 @@ document.addEventListener('DOMContentLoaded', function() {
92
92
  } else {
93
93
  url += '?per_page=' + value
94
94
  }
95
- window.location = url
95
+ Turbo.visit(url)
96
96
  })
97
97
 
98
98
  // injects per_page settings to all available search forms
99
99
  // so when user changes some filters / queries per_page is preserved
100
- $(document).ready(function() {
100
+ document.addEventListener("spree:load", function() {
101
101
  var perPageDropdown = $('.js-per-page-select:first')
102
102
  if (perPageDropdown.length) {
103
103
  var perPageValue = perPageDropdown.val().toString()
104
- var perPageInput = '<input type="hidden" name="per_page" value=' + perPageValue + ' />'
104
+ var perPageInput = '<input class="hidden_per_page_input" type="hidden" name="per_page" value=' + perPageValue + ' />'
105
+
106
+ $('.hidden_per_page_input').remove()
105
107
  $('#table-filter form').append(perPageInput)
106
108
  }
107
109
  })
@@ -1,4 +1,4 @@
1
- document.addEventListener('DOMContentLoaded', function() {
1
+ document.addEventListener("spree:load", function() {
2
2
  var body = $('body')
3
3
  var modalBackdrop = $('#multi-backdrop')
4
4
 
@@ -1,49 +1,39 @@
1
1
  // SELECT2 AUTOCOMPLETE JS
2
- // This JavaScript file allows Spree developers to set up Select2 autocomplete search
3
- // using the API v2 by simply adding data attributes to a select element with the class: 'select2autocomplete'
4
- // as shown here: <select class="select2autocomplete"></select>.
2
+ // The JavaScript in this file allows Spree developers to set up Select2 autocomplete search
3
+ // using the API v2 by simply adding data attributes to a select element.
5
4
 
6
5
  // REQUIRED ATTRIBUTES
7
- // You must provide a URL for the API V2, use the format shown below.
8
- // See the backend.js file for other API V2 URL's.
9
- //
10
- // Example:
6
+ // You must provide a URL for the API V2, use the format shown below. See backend.js for other API V2 URL's.
7
+ // REQUIRED:
11
8
  // data-autocomplete-url-value="products_api_v2"
12
9
 
13
- // OPTIONAL ATTRIBUTES
14
- // These optional attributes have sensible defaults, you many not need to use them in many cases,
15
- // but they do provide a powerful toolkit to refine your autocomplete search as required.
16
- //
17
- // Examples:
18
- // data-autocomplete-placeholder-value="Seach Pages" <- Sets the placeholder | DEFAULT is: 'Search'
19
- // data-autocomplete-clear-value="boolean" <- Allow select2 to be cleared | DEFAULT is: false (no clear button)
20
- // data-autocomplete-multiple-value="boolean" <- Multiple or Single select | DEFAULT is: false (single)
21
- // data-autocomplete-return-attr-value="pretty_name" <- Return Attribute. | DEFAULT is: 'name'
22
- // data-autocomplete-min-input-value="4" <- Minimum input for search | DEFAULT is: 3
23
- // data-autocomplete-search-query-value="title_i_cont" <- Custom search query | DEFAULT is: 'name_i_cont'
24
- // data-autocomplete-custom-return-id-value="permalink" <- Return a custom attribute rather than the ID | DEFAULT: returns id
10
+ // OPTIONAL:
11
+ // data-autocomplete-placeholder-value="Search Pages" <- Sets the placeholder | DEFAULT is: 'Search'.
12
+ // data-autocomplete-clear-value=boolean <- Allow select2 to be cleared | DEFAULT is: false (no clear button).
13
+ // data-autocomplete-multiple-value=boolean <- Multiple or Single select | DEFAULT is: false (single).
14
+ // data-autocomplete-return-attr-value="pretty_name" <- Return Attribute. | DEFAULT is: 'name'.
15
+ // data-autocomplete-min-input-value="4" <- Minimum input for search | DEFAULT is: 3.
16
+ // data-autocomplete-search-query-value="title_i_cont" <- Custom search query | DEFAULT is: 'name_i_cont'.
17
+ // data-autocomplete-custom-return-id-value="permalink" <- Return a custom attribute | DEFAULT: returns id.
18
+ // data-autocomplete-debug-mode-value=boolean <- Turn on console login of data returned by the request.
25
19
  //
26
- // SECOND HARD CODED FILTER - (OPTIONAL)
27
- // Use a second hard coded search filter param and term if you require a little more curation
28
- // than just all results returning, an example of this in use can be seen in the menu_item search for Pages,
29
- // here we only want to retuen Pages that have linkable slugs, not homepages, and so we filter those using the
30
- // data attributes shown below.
31
- //
32
- // Examples:
33
- // data-autocomplete-additional-query-value="type_not_eq" <- Additional hard coded query | DEFAULT: null (not used)
34
- // data-autocomplete-additional-term-value="Spree::Cms::Pages::Homepage" <- Additional hard coded term | DEFAULT: null (not used)
20
+ // Add your own custom URL params to the request as needed
21
+ // EXAMPLE:
22
+ // data-autocomplete-additional-url-params-value="filter[type_not_eq]=Spree::Cms::Pages::Homepage"
35
23
 
36
- document.addEventListener('DOMContentLoaded', function() {
37
- const select2Autocompletes = document.querySelectorAll('select.select2autocomplete')
38
- select2Autocompletes.forEach(element => buildParamsFromDataAttrs(element))
24
+ document.addEventListener("spree:load", function() {
25
+ loadAutoCompleteParams()
39
26
  })
40
27
 
41
- function buildParamsFromDataAttrs (element) {
28
+ // eslint-disable-next-line no-unused-vars
29
+ function loadAutoCompleteParams() {
30
+ const select2Autocompletes = document.querySelectorAll('select[data-autocomplete-url-value]')
31
+ select2Autocompletes.forEach(element => buildParamsFromDataAttrs(element))
32
+ }
33
+
34
+ function buildParamsFromDataAttrs(element) {
42
35
  $(element).select2Autocomplete({
43
- // Required Attributes
44
36
  apiUrl: Spree.routes[element.dataset.autocompleteUrlValue],
45
-
46
- // Optional Attributes
47
37
  placeholder: element.dataset.autocompletePlaceholderValue,
48
38
  allow_clear: element.dataset.autocompleteClearValue,
49
39
  multiple: element.dataset.autocompleteMultipleValue,
@@ -51,19 +41,17 @@ function buildParamsFromDataAttrs (element) {
51
41
  minimum_input: element.dataset.autocompleteMinInputValue,
52
42
  search_query: element.dataset.autocompleteSearchQueryValue,
53
43
  custom_return_id: element.dataset.autocompleteCustomReturnIdValue,
54
-
55
- // Hard coded additional filter for those edge cases.
56
- additional_query: element.dataset.autocompleteAdditionalQueryValue,
57
- additional_term: element.dataset.autocompleteAdditionalTermValue
44
+ additional_url_params: element.dataset.autocompleteAdditionalUrlParamsValue,
45
+ debug_mode: element.dataset.autocompleteDebugModeValue
58
46
  })
59
47
  }
60
48
 
61
- // Can also be called directly as javastript.
62
49
  $.fn.select2Autocomplete = function(params) {
63
- // Required params
64
- const apiUrl = params.apiUrl || null
50
+ let apiUrl = null
51
+ let returnedFields
65
52
 
66
- // Optional Params
53
+ const resourcePlural = params.apiUrl.match(/([^/]*)\/*$/)[1]
54
+ const resourceSingular = resourcePlural.slice(0, -1)
67
55
  const select2placeHolder = params.placeholder || Spree.translations.search
68
56
  const select2Multiple = params.multiple || false
69
57
  const select2allowClear = params.allow_clear || false
@@ -71,19 +59,42 @@ $.fn.select2Autocomplete = function(params) {
71
59
  const minimumInput = params.minimum_input || 3
72
60
  const searchQuery = params.search_query || 'name_i_cont'
73
61
  const customReturnId = params.custom_return_id || null
74
- const additionalQuery = params.additional_query || null
75
- const additionalTerm = params.additional_term || null
62
+ const additionalUrlParams = params.additional_url_params || null
63
+ const DebugMode = params.debug_mode || null
76
64
 
65
+ //
66
+ // Set up a clean URL for sparseFields
67
+ if (customReturnId == null) {
68
+ returnedFields = returnAttribute
69
+ } else {
70
+ returnedFields = `${returnAttribute},${customReturnId}`
71
+ }
72
+ const sparseFields = `fields[${resourceSingular}]=${returnedFields}`
73
+
74
+ //
75
+ // Set up a clean URL for Additional URL Params
76
+ if (additionalUrlParams != null) {
77
+ // URL + Additional URL Params + Sparse Fields
78
+ apiUrl = `${params.apiUrl}?${additionalUrlParams}&${sparseFields}`
79
+ } else {
80
+ // URL + Sparse Fields (the default response for a normal Select2)
81
+ apiUrl = `${params.apiUrl}?${sparseFields}`
82
+ }
83
+
84
+ if (DebugMode != null) console.log('Request URL:' + apiUrl)
85
+
86
+ //
87
+ // Format the returned values.
77
88
  function formatList(values) {
78
89
  if (customReturnId) {
79
- return values.map(function (obj) {
90
+ return values.map(function(obj) {
80
91
  return {
81
92
  id: obj.attributes[customReturnId],
82
93
  text: obj.attributes[returnAttribute]
83
94
  }
84
95
  })
85
96
  } else {
86
- return values.map(function (obj) {
97
+ return values.map(function(obj) {
87
98
  return {
88
99
  id: obj.id,
89
100
  text: obj.attributes[returnAttribute]
@@ -92,52 +103,30 @@ $.fn.select2Autocomplete = function(params) {
92
103
  }
93
104
  }
94
105
 
95
- if (additionalQuery == null && additionalTerm == null) {
96
- this.select2({
97
- multiple: select2Multiple,
98
- allowClear: select2allowClear,
99
- placeholder: select2placeHolder,
100
- minimumInputLength: minimumInput,
101
- ajax: {
102
- url: apiUrl,
103
- headers: Spree.apiV2Authentication(),
104
- data: function (params) {
105
- return {
106
- filter: {
107
- [searchQuery]: params.term
108
- }
109
- }
110
- },
111
- processResults: function(json) {
112
- return {
113
- results: formatList(json.data)
106
+ //
107
+ // Set-up Select2 and make AJAX request.
108
+ this.select2({
109
+ multiple: select2Multiple,
110
+ allowClear: select2allowClear,
111
+ placeholder: select2placeHolder,
112
+ minimumInputLength: minimumInput,
113
+ ajax: {
114
+ url: apiUrl,
115
+ headers: Spree.apiV2Authentication(),
116
+ data: function(params) {
117
+ return {
118
+ filter: {
119
+ [searchQuery]: params.term
114
120
  }
115
121
  }
116
- }
117
- })
118
- } else {
119
- this.select2({
120
- multiple: select2Multiple,
121
- allowClear: select2allowClear,
122
- placeholder: select2placeHolder,
123
- minimumInputLength: minimumInput,
124
- ajax: {
125
- url: apiUrl,
126
- headers: Spree.apiV2Authentication(),
127
- data: function (params) {
128
- return {
129
- filter: {
130
- [searchQuery]: params.term,
131
- [additionalQuery]: additionalTerm
132
- }
133
- }
134
- },
135
- processResults: function(json) {
136
- return {
137
- results: formatList(json.data)
138
- }
122
+ },
123
+ processResults: function(json) {
124
+ if (DebugMode != null) console.log(json)
125
+
126
+ return {
127
+ results: formatList(json.data)
139
128
  }
140
129
  }
141
- })
142
- }
130
+ }
131
+ })
143
132
  }
@@ -1,11 +1,9 @@
1
1
  /**
2
2
  populateSelectOptionsFromApi(params)
3
+ Allows you to easily fetch data from API (Platform v2) and populate an empty <select> with <option> tags, including a selected <option> tag.
3
4
 
4
- Allows you to easily fetch data from API (Platfrom v2)
5
- and populate an empty <select> with <option> tags,
6
- including a selected <option> tag.
7
-
8
- ## EXAMPLE USE CASE called from ERB view file:
5
+ ## EXAMPLE A
6
+ # Populating a list of all taxons including a selected item
9
7
 
10
8
  populateSelectOptionsFromApi({
11
9
  targetElement: '#mySelectElement',
@@ -16,6 +14,24 @@
16
14
  selectedOption: <%= @menu_item.linked_resource_id %>
17
15
  <% end %>
18
16
  })
17
+
18
+ ## EXAMPLE B
19
+ # Populating a single selected item using filter and returning an attribute other than the ID
20
+
21
+ <% if resource.link_one.present? %>
22
+ <script>
23
+ populateSelectOptionsFromApi({
24
+ targetElement: "#<%= save_to %>Select2",
25
+ apiUrl: Spree.routes.taxons_api_v2 + "?filter[permalink_matches]=<%= resource.send(save_to) %>",
26
+ returnValueFromAttributes: 'permalink',
27
+ returnOptionText: 'pretty_name',
28
+
29
+ <% if resource.send(save_to) %>
30
+ selectedOption: "<%= resource.send(save_to) %>"
31
+ <% end %>
32
+ })
33
+ </script>
34
+ <% end %>
19
35
  **/
20
36
 
21
37
  // eslint-disable-next-line no-unused-vars
@@ -32,30 +48,40 @@ const handleErrors = function(response) {
32
48
  const createRequest = function(params, succeed, fail) {
33
49
  const targetElement = params.targetElement
34
50
  const apiUrl = params.apiUrl
35
- const returnAttribute = params.returnAttribute
51
+ const returnOptionText = params.returnOptionText
52
+ const returnValueFromAttributes = params.returnValueFromAttributes || null
36
53
  const selectedOption = params.selectedOption
37
54
  const selectEl = document.querySelector(targetElement)
38
55
 
39
56
  fetch(apiUrl, { headers: Spree.apiV2Authentication() })
40
57
  .then((response) => handleErrors(response))
41
- .then((json) => succeed(json.data, returnAttribute, selectEl, selectedOption))
58
+ .then((json) => succeed(json.data, returnValueFromAttributes, returnOptionText, selectEl, selectedOption))
42
59
  .catch((error) => fail(error, selectEl))
43
60
  }
44
61
 
45
- const updateSelectSuccess = function(parsedData, returnAttribute, selectEl, selectedOption) {
62
+ const updateSelectSuccess = function(parsedData, returnValueFromAttributes, returnOptionText, selectEl, selectedOption) {
63
+ const selectedOpt = selectEl.querySelector('option[selected]')
64
+
46
65
  parsedData.forEach((object) => {
47
66
  const optionEl = document.createElement('option')
48
- optionEl.value = object.id
49
- optionEl.innerHTML = object.attributes[returnAttribute]
50
67
 
51
- if (parseInt(selectedOption, 10) === parseInt(object.id, 10)) optionEl.selected = true
68
+ if (returnValueFromAttributes == null) {
69
+ optionEl.value = object.id
70
+ if (selectedOption === object.id) optionEl.selected = true
71
+ } else {
72
+ optionEl.value = object.attributes[returnValueFromAttributes]
73
+ if (selectedOpt.value === object.attributes[returnValueFromAttributes]) {
74
+ selectedOpt.remove()
75
+
76
+ optionEl.setAttribute('selected', 'selected')
77
+ }
78
+ }
52
79
 
80
+ optionEl.innerHTML = object.attributes[returnOptionText]
53
81
  selectEl.appendChild(optionEl)
54
82
  })
55
83
  }
56
84
 
57
85
  const updateSelectError = function(error, selectEl) {
58
- selectEl.disabled = true
59
-
60
86
  console.log(error)
61
87
  }