spree_admin 5.0.0.rc1 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/spree/admin/components/_bulk_panel.scss +11 -1
  3. data/app/assets/stylesheets/spree/admin/components/_cards.scss +3 -4
  4. data/app/assets/stylesheets/spree/admin/components/_dropdowns.scss +1 -1
  5. data/app/assets/stylesheets/spree/admin/components/_main.scss +22 -5
  6. data/app/assets/stylesheets/spree/admin/components/_modals.scss +1 -1
  7. data/app/assets/stylesheets/spree/admin/global/_variables.scss +8 -2
  8. data/app/assets/stylesheets/spree/admin/shared/_base.scss +12 -1
  9. data/app/controllers/spree/admin/dashboard_controller.rb +4 -1
  10. data/app/controllers/spree/admin/products_controller.rb +1 -8
  11. data/app/controllers/spree/admin/storefront_controller.rb +1 -1
  12. data/app/controllers/spree/admin/translations_controller.rb +1 -1
  13. data/app/helpers/spree/admin/base_helper.rb +69 -63
  14. data/app/helpers/spree/admin/bulk_operations_helper.rb +86 -0
  15. data/app/helpers/spree/admin/modal_helper.rb +29 -0
  16. data/app/helpers/spree/admin/navigation_helper.rb +89 -11
  17. data/app/helpers/spree/admin/orders_helper.rb +0 -19
  18. data/app/helpers/spree/admin/stores_helper.rb +8 -36
  19. data/app/helpers/spree/admin/webhooks_subscribers_helper.rb +1 -1
  20. data/app/javascript/spree/admin/controllers/variants_form_controller.js +10 -3
  21. data/app/views/active_storage/_upload_form.html.erb +4 -8
  22. data/app/views/layouts/spree/admin.html.erb +4 -0
  23. data/app/views/spree/admin/assets/edit.html.erb +3 -8
  24. data/app/views/spree/admin/coupon_codes/index.html.erb +4 -6
  25. data/app/views/spree/admin/custom_domains/_custom_domains.html.erb +1 -1
  26. data/app/views/spree/admin/custom_domains/index.html.erb +1 -1
  27. data/app/views/spree/admin/customer_returns/index.html.erb +4 -17
  28. data/app/views/spree/admin/dashboard/_setup_progress.html.erb +4 -2
  29. data/app/views/spree/admin/dashboard/_sidebar.html.erb +2 -0
  30. data/app/views/spree/admin/dashboard/_top_products.html.erb +34 -24
  31. data/app/views/spree/admin/dashboard/analytics.html.erb +3 -1
  32. data/app/views/spree/admin/dashboard/show.html.erb +4 -8
  33. data/app/views/spree/admin/digital_assets/_table.html.erb +1 -1
  34. data/app/views/spree/admin/digital_assets/edit.html.erb +3 -11
  35. data/app/views/spree/admin/digital_assets/new.html.erb +3 -11
  36. data/app/views/spree/admin/exports/index.html.erb +22 -24
  37. data/app/views/spree/admin/exports/new.html.erb +3 -9
  38. data/app/views/spree/admin/line_items/new.html.erb +2 -5
  39. data/app/views/spree/admin/oauth_applications/index.html.erb +57 -58
  40. data/app/views/spree/admin/option_types/_filter.html.erb +1 -1
  41. data/app/views/spree/admin/option_types/index.html.erb +7 -11
  42. data/app/views/spree/admin/orders/_customer_summary.html.erb +0 -2
  43. data/app/views/spree/admin/orders/_filters.html.erb +3 -8
  44. data/app/views/spree/admin/orders/_header.html.erb +2 -0
  45. data/app/views/spree/admin/orders/_list.html.erb +2 -4
  46. data/app/views/spree/admin/orders/_summary.html.erb +1 -1
  47. data/app/views/spree/admin/orders/billing_address/create.turbo_stream.erb +3 -6
  48. data/app/views/spree/admin/orders/billing_address/edit.html.erb +3 -6
  49. data/app/views/spree/admin/orders/billing_address/new.html.erb +3 -6
  50. data/app/views/spree/admin/orders/billing_address/update.turbo_stream.erb +3 -6
  51. data/app/views/spree/admin/orders/contact_information/edit.html.erb +3 -6
  52. data/app/views/spree/admin/orders/customer_returns/edit.html.erb +1 -10
  53. data/app/views/spree/admin/orders/edit.html.erb +3 -5
  54. data/app/views/spree/admin/orders/index.html.erb +1 -1
  55. data/app/views/spree/admin/orders/return_authorizations/_form.html.erb +1 -1
  56. data/app/views/spree/admin/orders/return_authorizations/show.html.erb +45 -43
  57. data/app/views/spree/admin/orders/shipping_address/create.turbo_stream.erb +3 -6
  58. data/app/views/spree/admin/orders/shipping_address/edit.html.erb +3 -6
  59. data/app/views/spree/admin/orders/shipping_address/new.html.erb +3 -6
  60. data/app/views/spree/admin/orders/shipping_address/update.turbo_stream.erb +3 -6
  61. data/app/views/spree/admin/pages/_filters.html.erb +1 -1
  62. data/app/views/spree/admin/pages/edit.html.erb +2 -5
  63. data/app/views/spree/admin/pages/index.html.erb +4 -4
  64. data/app/views/spree/admin/payment_methods/index.html.erb +10 -8
  65. data/app/views/spree/admin/post_categories/index.html.erb +4 -6
  66. data/app/views/spree/admin/posts/_filters.html.erb +2 -7
  67. data/app/views/spree/admin/posts/_post.html.erb +1 -11
  68. data/app/views/spree/admin/posts/index.html.erb +5 -9
  69. data/app/views/spree/admin/products/_bulk_operations.html.erb +59 -94
  70. data/app/views/spree/admin/products/_filters.html.erb +13 -8
  71. data/app/views/spree/admin/products/_form.html.erb +3 -3
  72. data/app/views/spree/admin/products/_list.html.erb +2 -10
  73. data/app/views/spree/admin/products/_product.html.erb +1 -4
  74. data/app/views/spree/admin/products/bulk_modal.html.erb +3 -8
  75. data/app/views/spree/admin/products/edit.html.erb +3 -0
  76. data/app/views/spree/admin/products/form/_variants.html.erb +1 -0
  77. data/app/views/spree/admin/products/index.html.erb +5 -5
  78. data/app/views/spree/admin/promotion_actions/new.html.erb +7 -12
  79. data/app/views/spree/admin/promotion_rules/new.html.erb +7 -12
  80. data/app/views/spree/admin/promotions/_filters.html.erb +27 -0
  81. data/app/views/spree/admin/promotions/index.html.erb +7 -35
  82. data/app/views/spree/admin/properties/index.html.erb +10 -9
  83. data/app/views/spree/admin/refund_reasons/index.html.erb +37 -35
  84. data/app/views/spree/admin/refunds/edit.html.erb +3 -8
  85. data/app/views/spree/admin/reimbursement_types/index.html.erb +42 -40
  86. data/app/views/spree/admin/reports/_report.html.erb +1 -1
  87. data/app/views/spree/admin/return_authorization_reasons/index.html.erb +41 -41
  88. data/app/views/spree/admin/return_authorizations/_filters.html.erb +1 -1
  89. data/app/views/spree/admin/return_authorizations/_list.html.erb +1 -10
  90. data/app/views/spree/admin/return_authorizations/index.html.erb +1 -1
  91. data/app/views/spree/admin/roles/_form.html.erb +1 -1
  92. data/app/views/spree/admin/roles/index.html.erb +26 -24
  93. data/app/views/spree/admin/shared/_bulk_modal.html.erb +6 -7
  94. data/app/views/spree/admin/shared/_developers_nav.html.erb +2 -2
  95. data/app/views/spree/admin/shared/_filter_submit.html.erb +6 -0
  96. data/app/views/spree/admin/shared/_head.html.erb +3 -1
  97. data/app/views/spree/admin/shared/_modal.html.erb +2 -8
  98. data/app/views/spree/admin/shared/_multi_product_picker.html.erb +2 -4
  99. data/app/views/spree/admin/shared/_no_resource_found.html.erb +1 -1
  100. data/app/views/spree/admin/shared/_posts_tabs.html.erb +2 -2
  101. data/app/views/spree/admin/shared/_product_image.html.erb +1 -10
  102. data/app/views/spree/admin/shared/_refunds.html.erb +1 -1
  103. data/app/views/spree/admin/shared/_returns_and_refunds_nav.html.erb +3 -3
  104. data/app/views/spree/admin/shared/_shipping_nav.html.erb +2 -2
  105. data/app/views/spree/admin/shared/_stock_nav.html.erb +2 -2
  106. data/app/views/spree/admin/shared/_tax_nav.html.erb +2 -2
  107. data/app/views/spree/admin/shared/_user.html.erb +2 -2
  108. data/app/views/spree/admin/shared/_user_dropdown.html.erb +2 -2
  109. data/app/views/spree/admin/shared/sidebar/_orders_nav.html.erb +19 -29
  110. data/app/views/spree/admin/shared/sidebar/_products_nav.html.erb +6 -25
  111. data/app/views/spree/admin/shared/sidebar/_returns_nav.html.erb +8 -15
  112. data/app/views/spree/admin/shared/sidebar/_store_dropdown.html.erb +36 -7
  113. data/app/views/spree/admin/shared/sidebar/_store_nav.html.erb +28 -52
  114. data/app/views/spree/admin/shared/sidebar/_storefront_nav.html.erb +19 -26
  115. data/app/views/spree/admin/shared/sortable_tree/_taxonomy.html.erb +3 -23
  116. data/app/views/spree/admin/shipping_categories/index.html.erb +28 -26
  117. data/app/views/spree/admin/shipping_methods/_actions.html.erb +1 -1
  118. data/app/views/spree/admin/shipping_methods/index.html.erb +23 -21
  119. data/app/views/spree/admin/stock_items/_filters.html.erb +2 -7
  120. data/app/views/spree/admin/stock_items/index.html.erb +5 -8
  121. data/app/views/spree/admin/stock_locations/_stock_location.html.erb +16 -13
  122. data/app/views/spree/admin/stock_locations/index.html.erb +24 -21
  123. data/app/views/spree/admin/stock_transfers/_filters.html.erb +1 -1
  124. data/app/views/spree/admin/stock_transfers/_new_variant_modal.html.erb +3 -5
  125. data/app/views/spree/admin/stock_transfers/index.html.erb +6 -6
  126. data/app/views/spree/admin/store_credit_categories/_form.html.erb +1 -1
  127. data/app/views/spree/admin/store_credit_categories/edit.html.erb +6 -4
  128. data/app/views/spree/admin/store_credit_categories/index.html.erb +28 -24
  129. data/app/views/spree/admin/store_credits/index.html.erb +2 -2
  130. data/app/views/spree/admin/storefront/edit.html.erb +7 -9
  131. data/app/views/spree/admin/stores/form/_basic.html.erb +2 -2
  132. data/app/views/spree/admin/stores/form/_policies.html.erb +1 -1
  133. data/app/views/spree/admin/stores/new.html.erb +8 -6
  134. data/app/views/spree/admin/tax_categories/index.html.erb +24 -22
  135. data/app/views/spree/admin/tax_rates/index.html.erb +26 -24
  136. data/app/views/spree/admin/taxonomies/index.html.erb +4 -4
  137. data/app/views/spree/admin/taxonomies/show.html.erb +2 -2
  138. data/app/views/spree/admin/themes/_theme_preview_image.html.erb +1 -10
  139. data/app/views/spree/admin/themes/index.html.erb +2 -2
  140. data/app/views/spree/admin/translations/_translations_unavailable.html.erb +6 -8
  141. data/app/views/spree/admin/users/_filters.html.erb +2 -7
  142. data/app/views/spree/admin/users/_tabs.html.erb +4 -4
  143. data/app/views/spree/admin/users/_user.html.erb +1 -4
  144. data/app/views/spree/admin/users/bulk_modal.html.erb +3 -8
  145. data/app/views/spree/admin/users/index.html.erb +25 -58
  146. data/app/views/spree/admin/variants/_variant.html.erb +8 -2
  147. data/app/views/spree/admin/variants/form/_media_asset.html.erb +1 -7
  148. data/app/views/spree/admin/variants/form/_pricing.html.erb +5 -4
  149. data/app/views/spree/admin/webhooks_subscribers/_form.html.erb +1 -1
  150. data/app/views/spree/admin/webhooks_subscribers/index.html.erb +25 -22
  151. data/app/views/spree/admin/webhooks_subscribers/show.html.erb +3 -3
  152. data/app/views/spree/admin/zones/index.html.erb +34 -32
  153. data/config/locales/en.yml +1 -46
  154. data/lib/spree/admin/engine.rb +50 -0
  155. metadata +13 -14
  156. data/app/views/spree/admin/orders/_extra_filters.html.erb +0 -0
  157. data/app/views/spree/admin/products/_empty_list.html.erb +0 -1
  158. data/app/views/spree/admin/products/form/_extra_filters.html.erb +0 -0
  159. data/app/views/spree/admin/products/form/_extra_form.html.erb +0 -0
  160. data/app/views/spree/admin/products/form/_extra_form_sidebar.erb +0 -0
  161. data/app/views/spree/admin/stores/form/_custom.html.erb +0 -0
@@ -1,8 +1,22 @@
1
1
  module Spree
2
2
  module Admin
3
3
  module NavigationHelper
4
+ # Creates a navigation item with optional icon
5
+ # @param [String, SafeBuffer] label The text or HTML to use as the link content
6
+ # @param [String] url The URL for the link
7
+ # @param [String, nil] icon Optional icon name to prepend to the label
8
+ # @param [Boolean, nil] active Whether the link should be marked as active
9
+ # @return [SafeBuffer] The navigation item HTML
10
+ def nav_item(label, url, icon: nil, active: nil)
11
+ content_tag :li, class: 'nav-item', role: 'presentation' do
12
+ label = icon(icon) + label if icon.present?
13
+ active_link_to label, url, class: 'nav-link', active: active
14
+ end
15
+ end
16
+
4
17
  # the per_page_dropdown is used on index pages like orders, products, promotions etc.
5
18
  # this method generates the select_tag
19
+ # @return [String]
6
20
  def per_page_dropdown
7
21
  per_page_default = if @products
8
22
  Spree::Admin::RuntimeConfig.admin_products_per_page
@@ -35,6 +49,8 @@ module Spree
35
49
 
36
50
  # helper method to create proper url to apply per page ing
37
51
  # fixes https://github.com/spree/spree/issues/6888
52
+ # @param per_page [Integer] the number of items per page
53
+ # @return [Hash] the params to apply per page
38
54
  def per_page_dropdown_params(per_page)
39
55
  args = params.permit!.to_h.clone
40
56
  args.delete(:page)
@@ -43,6 +59,12 @@ module Spree
43
59
  args
44
60
  end
45
61
 
62
+ # render a button link to edit a resource
63
+ # if the current user doesn't have permission to update the resource, the button will not be rendered
64
+ # @param resource [Spree::Product, Spree::User, Spree::Order] the resource to edit
65
+ # @param options [Hash] the options for the link
66
+ # @option options [String] :url the url to edit the resource (optional)
67
+ # @return [String] the link to edit the resource
46
68
  def link_to_edit(resource, options = {})
47
69
  url = options[:url] || edit_object_url(resource)
48
70
  options[:data] ||= {}
@@ -51,6 +73,12 @@ module Spree
51
73
  link_to_with_icon('pencil', Spree.t(:edit), url, options) if can?(:update, resource)
52
74
  end
53
75
 
76
+ # render a button to delete a resource with a confirmation modal
77
+ # if the current user doesn't have permission to destroy the resource, the button will not be rendered
78
+ # @param resource [Spree::Product, Spree::User, Spree::Order] the resource to delete
79
+ # @param options [Hash] the options for the link
80
+ # @option options [String] :url the url to delete the resource (optional)
81
+ # @return [String] the link to delete the resource
54
82
  def link_to_delete(resource, options = {})
55
83
  url = options[:url] || object_url(resource)
56
84
  name = options[:name] || Spree.t('actions.destroy')
@@ -68,6 +96,12 @@ module Spree
68
96
  end
69
97
  end
70
98
 
99
+ # renders a link with an icon
100
+ # @param icon_name [String] the name of the icon, eg: 'pencil', see: https://tabler.io/icons
101
+ # @param text [String] the text of the link
102
+ # @param url [String] the url of the link
103
+ # @param options [Hash] the options for the link
104
+ # @return [String] the link with the icon
71
105
  def link_to_with_icon(icon_name, text, url, options = {})
72
106
  options[:class] ||= (options[:class].to_s + " with-tip").strip
73
107
  options[:title] ||= text if options[:no_text]
@@ -82,6 +116,12 @@ module Spree
82
116
  link_to(text.html_safe, url, options)
83
117
  end
84
118
 
119
+ # renders an active link with an icon, using the active_link_to method from https://github.com/comfy/active_link_to gem
120
+ # @param icon_name [String] the name of the icon, eg: 'pencil', see: https://tabler.io/icons
121
+ # @param text [String] the text of the link
122
+ # @param url [String] the url of the link
123
+ # @param options [Hash] the options for the link
124
+ # @return [String] the active link with the icon
85
125
  def active_link_to_with_icon(icon_name, text, url, options = {})
86
126
  options[:class] = (options[:class].to_s + " with-tip").strip
87
127
  options[:title] = text if options[:no_text]
@@ -96,7 +136,13 @@ module Spree
96
136
  active_link_to(text.html_safe, url, options)
97
137
  end
98
138
 
139
+ # renders a button with an icon (optional)
99
140
  # Override: Add disable_with option to prevent multiple request on consecutive clicks
141
+ # @param text [String] the text of the button
142
+ # @param icon_name [String] the name of the icon, eg: 'pencil', see: https://tabler.io/icons
143
+ # @param button_type [String] the type of the button, eg: 'submit', 'button'
144
+ # @param options [Hash] the options for the button
145
+ # @return [String] the button with the icon
100
146
  def button(text, icon_name = nil, button_type = 'submit', options = {})
101
147
  if icon_name
102
148
  text = "#{icon(icon_name, class: "icon icon-#{icon_name}")} #{text}"
@@ -115,6 +161,8 @@ module Spree
115
161
  end
116
162
 
117
163
  def button_link_to(text, url, html_options = {})
164
+ Spree::Deprecation.warn("button_link_to is deprecated. Use standard link_to instead.")
165
+
118
166
  if html_options[:method] &&
119
167
  !html_options[:method].to_s.casecmp('get').zero? &&
120
168
  !html_options[:remote]
@@ -136,6 +184,10 @@ module Spree
136
184
  end
137
185
  end
138
186
 
187
+ # renders a badge (active/inactive)
188
+ # @param condition [Boolean] the condition to check
189
+ # @param options [Hash] the options for the badge
190
+ # @return [String] the badge with the icon
139
191
  def active_badge(condition, options = {})
140
192
  label = options[:label]
141
193
  label ||= condition ? Spree.t(:say_yes) : Spree.t(:say_no)
@@ -148,6 +200,11 @@ module Spree
148
200
  end
149
201
  end
150
202
 
203
+ # renders a back button to the previous page
204
+ # @param default_url [String] the default url to go back to
205
+ # @param object [Spree::Product, Spree::User, Spree::Order] the object list to go back to
206
+ # @param label [String] the label of the back button (optional)
207
+ # @return [String] the back button
151
208
  def page_header_back_button(default_url, object = nil, label = nil)
152
209
  url = default_url
153
210
 
@@ -162,20 +219,15 @@ module Spree
162
219
  end
163
220
  end
164
221
 
165
- def nav_pill_list_item(resource, url: nil, label: Spree.t(resource), active: nil, link_class: 'nav-link')
166
- url = spree.send("admin_#{resource.to_s.pluralize}_path") if url.nil?
167
- active = request.url.starts_with?(url) || request.fullpath.starts_with?(url) || controller_name == resource.to_s if active.nil?
168
- link_class = "#{link_class} active" if active
169
-
170
- content_tag :li, class: 'nav-item', role: 'presentation' do
171
- link_to label, url, role: 'tab', 'aria-controls': 'pills-general', class: link_class, 'aria-selected': active
172
- end
173
- end
174
-
222
+ # renders an external link with an icon (eg. spree documentation website)
223
+ # @param label [String] the label of the link
224
+ # @param url [String] the url of the link
225
+ # @param opts [Hash] the options for the link
226
+ # @return [String] the external link with the icon
175
227
  def external_link_to(label, url, opts = {}, &block)
176
228
  opts[:target] ||= :blank
177
229
  opts[:rel] ||= :nofollow
178
- opts[:class] ||= "d-inline-flex align-items-center text-blue"
230
+ opts[:class] ||= "d-inline-flex align-items-center text-blue text-decoration-none"
179
231
 
180
232
  if block_given?
181
233
  link_to url, opts, &block
@@ -186,6 +238,32 @@ module Spree
186
238
  end
187
239
  end
188
240
 
241
+ # renders a link to preview a resource on the storefront using the spree_storefront_resource_url helper
242
+ # @param resource [Spree::Product, Spree::Post] the resource to preview
243
+ # @param options [Hash] the options for the link
244
+ # @return [String] the link to preview the resource
245
+ def external_page_preview_link(resource, options = {})
246
+ resource_name = options[:name] || resource.class.name.demodulize
247
+
248
+ url = if [Spree::Product, Spree::Post].include?(resource.class)
249
+ spree_storefront_resource_url(resource, preview_id: resource.id)
250
+ else
251
+ spree_storefront_resource_url(resource)
252
+ end
253
+
254
+ link_to_with_icon(
255
+ 'eye',
256
+ Spree.t('admin.utilities.preview', name: resource_name),
257
+ url,
258
+ class: 'text-left dropdown-item', id: "adminPreview#{resource_name}", target: :blank, data: { turbo: false }
259
+ )
260
+ end
261
+
262
+ # renders a help bubble with an icon
263
+ # @param text [String] the text of the help bubble
264
+ # @param placement [String] the placement of the help bubble
265
+ # @param css [String] the css class of the help bubble
266
+ # @return [String] the help bubble with the icon
189
267
  def help_bubble(text = '', placement = 'bottom', css: nil)
190
268
  css ||= 'text-muted'
191
269
  content_tag :small, icon('info-square-rounded', class: css), data: { placement: placement }, class: "with-tip #{css}", title: text
@@ -69,25 +69,6 @@ module Spree
69
69
  end
70
70
  end
71
71
 
72
- # Renders all the extension partials that may have been specified in the extensions
73
- def event_links(order, events)
74
- links = []
75
- events.each do |event|
76
- next unless order.send("can_#{event}?")
77
-
78
- label = Spree.t(event, scope: 'admin.order.events', default: Spree.t(event))
79
- links << button_link_to(
80
- label.capitalize,
81
- [event.to_sym, :admin, order],
82
- method: :put,
83
- icon: event.to_s + '.svg',
84
- data: { turbo_confirm: Spree.t(:order_sure_want_to, event: label) },
85
- class: 'btn-light'
86
- )
87
- end
88
- safe_join(links, ''.html_safe)
89
- end
90
-
91
72
  def line_item_shipment_price(line_item, quantity)
92
73
  Spree::Money.new(line_item.price * quantity, currency: line_item.currency)
93
74
  end
@@ -1,6 +1,8 @@
1
1
  module Spree
2
2
  module Admin
3
3
  module StoresHelper
4
+ include Spree::ImagesHelper
5
+
4
6
  def available_stores
5
7
  @available_stores ||= Spree::Store.accessible_by(current_ability)
6
8
  end
@@ -18,31 +20,9 @@ module Spree
18
20
 
19
21
  Rails.cache.fetch(["#{store.cache_key_with_version}/admin_icon", opts.to_param]) do
20
22
  if store.logo&.attached? && store.logo&.variable?
21
- image_tag(
22
- main_app.cdn_image_url(
23
- store.logo.variant(
24
- spree_image_variant_options(
25
- resize_to_fill: [opts[:width] * 2, opts[:height] * 2]
26
- )
27
- )
28
- ),
29
- class: opts[:class],
30
- width: opts[:width],
31
- height: opts[:height]
32
- )
23
+ spree_image_tag(store.logo, class: opts[:class], width: opts[:width], height: opts[:height])
33
24
  elsif store.favicon_image&.attached? && store.favicon_image&.variable?
34
- image_tag(
35
- main_app.cdn_image_url(
36
- store.favicon_image.variant(
37
- spree_image_variant_options(
38
- resize_to_fill: [opts[:width] * 2, opts[:height] * 2]
39
- )
40
- )
41
- ),
42
- class: opts[:class],
43
- width: opts[:width],
44
- height: opts[:height]
45
- )
25
+ spree_image_tag(store.favicon_image, class: opts[:class], width: opts[:width], height: opts[:height])
46
26
  else
47
27
  first_letter_icon(store.name, opts)
48
28
  end
@@ -65,20 +45,12 @@ module Spree
65
45
  opts.merge!(options)
66
46
 
67
47
  if store.is_a?(Spree::Store) && store.logo&.attached? && store.logo&.variable?
68
- image_tag(
69
- main_app.cdn_image_url(
70
- store.logo.variant(
71
- spree_image_variant_options(
72
- resize_to_fill: [opts[:width] * 2, opts[:height] * 2]
73
- )
74
- )
75
- ),
76
- opts
77
- )
48
+ spree_image_tag(store.logo, class: opts[:class], width: opts[:width], height: opts[:height])
78
49
  else
79
50
  initials = store.name.split.map(&:first).join.upcase
80
- image_tag("https://eu.ui-avatars.com/api/?name=#{initials}&background=random", width: opts[:height], height: opts[:height],
81
- class: 'rounded with-tip', title: store.name)
51
+ content_tag(:div, initials, class: "avatar rounded with-tip bg-light",
52
+ style: "width: #{opts[:height]}px; height: #{opts[:height]}px;",
53
+ title: store.name)
82
54
  end
83
55
  end
84
56
  end
@@ -5,7 +5,7 @@ module Spree
5
5
  content_tag :div, class: 'col-xs-12 col-sm-6 col-md-4 col-lg-4 form-group' do
6
6
  content_tag :div, class: 'custom-control custom-switch' do
7
7
  (form.check_box resource_name, event_checkbox_opts(resource_name), true, nil) + ' ' +
8
- form.label(resource_name, Spree.t("admin.webhooks_subscribers.#{resource_name.to_s.pluralize}"), class: 'custom-control-label')
8
+ form.label(resource_name, Spree.t("#{resource_name.to_s.pluralize}"), class: 'custom-control-label')
9
9
  end
10
10
  end
11
11
  end
@@ -36,7 +36,8 @@ export default class extends CheckboxSelectAll {
36
36
  variantIds: Object,
37
37
  currentStockLocationId: String,
38
38
  stockLocations: Array,
39
- optionValuesSelectOptions: Array
39
+ optionValuesSelectOptions: Array,
40
+ locale: String
40
41
  }
41
42
 
42
43
  connect() {
@@ -403,7 +404,7 @@ export default class extends CheckboxSelectAll {
403
404
  pricesVariation.delete(null)
404
405
 
405
406
  if (pricesVariation.size === 0) {
406
- parentPriceEl.value = this.priceForVariant(variantName, currency).amount
407
+ parentPriceEl.value = this.priceForVariant(variantName, currency).amount?.toLocaleString(this.localeValue) || ''
407
408
  parentPriceEl.placeholder = ''
408
409
  return
409
410
  }
@@ -586,6 +587,12 @@ export default class extends CheckboxSelectAll {
586
587
  }
587
588
 
588
589
  keys.forEach((key) => {
590
+ const idInput = document.createElement('input')
591
+ idInput.type = 'hidden'
592
+ idInput.name = `product[variants_attributes][${i}][options][][id]`
593
+ idInput.value = Object.entries(this.optionsValue).find((option) => option[1].name === key)?.[0]
594
+ inputs.push(idInput)
595
+
589
596
  const nameInput = document.createElement('input')
590
597
  nameInput.type = 'hidden'
591
598
  nameInput.name = `product[variants_attributes][${i}][options][][name]`
@@ -668,7 +675,7 @@ export default class extends CheckboxSelectAll {
668
675
  }
669
676
 
670
677
  const existingPrice = this.priceForVariant(internalName, currency)
671
- priceInput.value = existingPrice.amount
678
+ priceInput.value = existingPrice.amount?.toLocaleString(this.localeValue) || ''
672
679
  currencyInput.value = currency
673
680
  if (existingPrice.id) {
674
681
  idInput.value = existingPrice.id
@@ -18,14 +18,10 @@
18
18
  data-action="click->active-storage-upload#open"
19
19
  >
20
20
  <% if form.object.send(field_name).attached? && form.object.send(field_name).variable? %>
21
- <%= image_tag(
22
- main_app.cdn_image_url(
23
- form.object.send(field_name).variant(
24
- spree_image_variant_options(
25
- resize_to_fill: [width, (crop ? height : nil)]
26
- )
27
- )
28
- ),
21
+ <%= spree_image_tag(
22
+ form.object.send(field_name),
23
+ width: width,
24
+ height: height,
29
25
  class: 'img-fluid rounded-lg',
30
26
  data: { active_storage_upload_target: 'thumb' },
31
27
  loading: :lazy
@@ -6,6 +6,8 @@
6
6
  </head>
7
7
 
8
8
  <body class="admin min-vh-100 <%= controller_name %> <%= action_name %>">
9
+ <%= render_admin_partials(:body_start_partials) %>
10
+
9
11
  <%= render "spree/admin/shared/header" %>
10
12
  <%= render "spree/admin/shared/sidebar" %>
11
13
  <main id="content">
@@ -17,5 +19,7 @@
17
19
  </main>
18
20
  <%= render "spree/admin/shared/modal" %>
19
21
  <%= render "spree/admin/shared/alerts" %>
22
+
23
+ <%= render_admin_partials(:body_end_partials) %>
20
24
  </body>
21
25
  </html>
@@ -1,11 +1,6 @@
1
1
  <%= turbo_frame_tag :dialog_modal_lg do %>
2
- <div class="modal-content" >
3
- <div class="modal-header">
4
- <h5 class="modal-title" id="exampleModalLabel">
5
- <%= Spree.t(:edit) %> <%= Spree.t(:image) %>
6
- </h5>
7
- <button type="button" class="btn-close" data-dismiss="modal" aria-label="<%= Spree.t(:close) %>" />
8
- </div>
2
+ <div class="modal-content">
3
+ <%= modal_header(Spree.t(:edit) + ' ' + Spree.t(:image)) %>
9
4
  <%= form_with model: @asset, url: spree.admin_asset_path(@asset), method: :put, scope: :asset do |f| %>
10
5
  <div class="modal-body pb-0" data-turbo-permanent id="asset-<%= @asset.key.parameterize %>">
11
6
  <%= render 'active_storage/upload_form', form: f, field_name: :attachment, width: 200, height: 200, can_delete: false %>
@@ -16,7 +11,7 @@
16
11
  <%= f.text_area :alt, rows: 4, class: 'form-control' %>
17
12
  </div>
18
13
  </div>
19
- <div class="modal-footer d-flex justify-content-between">
14
+ <div class="modal-footer">
20
15
  <%= turbo_save_button_tag %>
21
16
  <%= link_to Spree.t('actions.destroy'), object_url(@asset),
22
17
  data: { turbo_method: :delete, turbo_confirm: Spree.t(:are_you_sure_delete), turbo_frame: '_top' },
@@ -2,8 +2,8 @@
2
2
 
3
3
  <div class="row">
4
4
  <div class="col-12 col-lg-8">
5
- <div class="card-lg p-0">
6
- <%= search_form_for [:admin, @promotion, @search], class: "filter-wrap border-bottom" do |f| %>
5
+ <div class="card-lg">
6
+ <%= search_form_for [:admin, @promotion, @search], class: "filter-wrap" do |f| %>
7
7
  <div class="d-flex flex-column flex-lg-row gap-2">
8
8
  <%= render 'spree/admin/shared/filters_search_bar', param: :code_eq %>
9
9
 
@@ -54,13 +54,11 @@
54
54
  </tbody>
55
55
  </table>
56
56
  <% else %>
57
- <div class="text-muted p-5 d-flex align-items-center w-100 justify-content-center">
58
- <%= Spree.t(:no_resource_found, resource: plural_resource_name(Spree::CouponCode)) %>
59
- </div>
57
+ <%= render 'spree/admin/shared/no_resource_found', new_object_url: nil %>
60
58
  <% end %>
61
59
  </div>
62
60
 
63
- <%= render 'spree/admin/shared/index_table_options', collection: @coupon_codes, simple: true if @coupon_codes.any? %>
61
+ <%= render 'spree/admin/shared/index_table_options', collection: @coupon_codes if @coupon_codes.any? %>
64
62
  </div>
65
63
  </div>
66
64
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  <% unless entri_enabled? %>
10
10
  <th>Default</th>
11
- <th class="actions"></th>
11
+ <th></th>
12
12
  <% end %>
13
13
  </tr>
14
14
  </thead>
@@ -5,7 +5,7 @@
5
5
  <%= Spree.t(:domains) %>
6
6
  <% end %>
7
7
 
8
- <div class="card-lg">
8
+ <div class="card-lg p-4">
9
9
  <h5 class="mb-3">Internal URL</h5>
10
10
  <div class="row mb-4">
11
11
  <div class="col-lg-4">
@@ -5,9 +5,9 @@
5
5
  <% content_for :page_title do %>
6
6
  <%= Spree.t(:customer_returns) %>
7
7
  <% end %>
8
- <div class="card-lg p-0">
9
8
 
10
- <%= search_form_for [:admin, @search], url: spree.admin_customer_returns_path, class: "filter-wrap border-bottom", data: {controller: "filters reveal", reveal_hidden_class: "d-none"} do |f| %>
9
+ <div class="card-lg">
10
+ <%= search_form_for [:admin, @search], url: spree.admin_customer_returns_path, class: "filter-wrap", data: {controller: "filters reveal", reveal_hidden_class: "d-none"} do |f| %>
11
11
  <%= render "spree/admin/shared/filters_search_bar",
12
12
  param: :number_cont,
13
13
  label: Spree.t(:number) %>
@@ -37,21 +37,8 @@
37
37
  </tbody>
38
38
  </table>
39
39
  </div>
40
+ <%= render 'spree/admin/shared/index_table_options', collection: @collection %>
40
41
  <% else %>
41
- <div
42
- class="
43
- text-muted p-5 d-flex align-items-center w-100 justify-content-center
44
- "
45
- >
46
- <%= Spree.t(
47
- :no_resource_found,
48
- resource: plural_resource_name(Spree::CustomerReturn),
49
- ) %>
50
- </div>
42
+ <%= render 'spree/admin/shared/no_resource_found', new_object_url: nil %>
51
43
  <% end %>
52
-
53
- <%= render partial: "spree/admin/shared/index_table_options",
54
- locals: {
55
- collection: @collection,
56
- } %>
57
44
  </div>
@@ -2,12 +2,14 @@
2
2
  <div class="card-body">
3
3
  <div class="mb-3">
4
4
  Your overall setup progress
5
- <span class="float-right badge badge-<%= current_store.setup_completed? ? 'success' : 'light' %>">
5
+ <span class="float-right badge badge-<%= current_store.setup_completed? ? 'success' : 'info' %>">
6
6
  <% if current_store.setup_completed? %>
7
7
  <%= icon('check', class: 'text-success') %>
8
8
  <% end %>
9
9
 
10
- <%= current_store.setup_tasks_done %> of <%= current_store.setup_tasks_total %> steps done
10
+ <span>
11
+ <strong><%= current_store.setup_tasks_done %></strong> of <%= current_store.setup_tasks_total %> steps done
12
+ </span>
11
13
  </span>
12
14
  </div>
13
15
  <div class="progress">
@@ -0,0 +1,2 @@
1
+ <%= render 'updater' %>
2
+ <%= render 'store_preview' %>
@@ -32,40 +32,50 @@
32
32
  </tr>
33
33
  </thead>
34
34
  <tbody>
35
- <% @top_products.each do |list_item| %>
36
- <% product = list_item[:product] %>
37
- <tr>
38
- <% cache_unless @vendor, spree_base_cache_scope.call(product) do %>
39
- <td>
40
- <%= link_to spree.edit_admin_product_path(product), class: 'd-flex align-items-center font-weight-bold', data: { 'turbo-frame': '_top' } do %>
41
- <div class="mr-3">
42
- <%= render 'spree/admin/shared/product_image', object: product %>
43
- </div>
44
- <%= product.name %>
35
+ <% if @top_products.any? %>
36
+ <% @top_products.each do |list_item| %>
37
+ <% product = list_item[:product] %>
38
+ <tr>
39
+ <% cache_unless @vendor, spree_base_cache_scope.call(product) do %>
40
+ <td>
41
+ <%= link_to spree.edit_admin_product_path(product), class: 'd-flex align-items-center font-weight-bold', data: { 'turbo-frame': '_top' } do %>
42
+ <div class="mr-3">
43
+ <%= render 'spree/admin/shared/product_image', object: product %>
44
+ </div>
45
+ <%= product.name %>
46
+ <% end %>
47
+ </td>
48
+ <% if enterprise_edition? && defined?(vendor_logo_link) && !@vendor %>
49
+ <td>
50
+ <%= vendor_logo_link(product.vendor) if product.vendor.present? %>
51
+ </td>
45
52
  <% end %>
46
- </td>
47
- <% if enterprise_edition? && defined?(vendor_logo_link) && !@vendor %>
48
53
  <td>
49
- <%= vendor_logo_link(product.vendor) if product.vendor.present? %>
54
+ <%= display_admin_price(product) %>
50
55
  </td>
51
56
  <% end %>
52
- <td>
53
- <%= display_admin_price(product) %>
57
+ <td class="text-center">
58
+ <%= list_item[:quantity] %>
54
59
  </td>
55
- <% end %>
56
- <td class="text-center">
57
- <%= list_item[:quantity] %>
58
- </td>
59
- <td class="text-right">
60
- <%= list_item[:amount] %>
60
+ <td class="text-right">
61
+ <%= list_item[:amount] %>
62
+ </td>
63
+ </tr>
64
+ <% end %>
65
+ <% else %>
66
+ <tr>
67
+ <td colspan="5" class="text-center text-muted py-5">
68
+ <%= Spree.t(:no_resource_found, resource: Spree::Product.name.demodulize.underscore.humanize) %>
61
69
  </td>
62
70
  </tr>
63
71
  <% end %>
64
72
  </tbody>
65
73
  </table>
66
74
  </div>
67
- <p class="text-center mt-0 border-top py-2 mb-0">
68
- <%= link_to Spree.t('admin.dashboard.view_report'), report_link, class: 'm-2 w-50 btn btn-light mt-2', data: { turbo_frame: '_top' } %>
69
- </p>
75
+ <% if @top_products.any? %>
76
+ <p class="text-center mt-0 border-top py-2 mb-0">
77
+ <%= link_to Spree.t('admin.dashboard.view_report'), report_link, class: 'm-2 w-50 btn btn-light mt-2', data: { turbo_frame: '_top' } %>
78
+ </p>
79
+ <% end %>
70
80
  </div>
71
81
  </div>
@@ -113,6 +113,8 @@
113
113
  </div>
114
114
  </div>
115
115
 
116
- <%= render 'top_products' if @top_products.present? %>
116
+ <%= render 'top_products' if @top_products %>
117
117
  <%= render 'visits' if @visits %>
118
+
119
+ <%= render_admin_partials(:dashboard_analytics_partials) %>
118
120
  <% end %>
@@ -17,17 +17,13 @@
17
17
  <%= render 'spree/admin/shared/calendar_range_picker',
18
18
  date_from_value: params[:date_from] || 1.month.ago.beginning_of_month,
19
19
  date_to_value: params[:date_to] || 1.month.ago.end_of_month,
20
- css_classes: "btn btn-sm border hover-light d-inline-flex align-items-center h-100 dropdown-toggle" %>
20
+ css_classes: "btn btn-sm border rounded-lg hover-light d-inline-flex align-items-center h-100 dropdown-toggle" %>
21
21
  <% end %>
22
22
  </div>
23
23
  <%= render 'analytics' %>
24
24
  </div>
25
25
  <div class="col-lg-4">
26
- <% if defined?(current_vendor) && current_vendor %>
27
- <%= render 'spree/admin/shared/vendor_faq' %>
28
- <% else %>
29
- <%= render 'updater' %>
30
- <%= render 'store_preview' %>
31
- <%= render 'vendors' if defined?(Spree::Vendor) %>
32
- <% end %>
26
+ <%= render 'sidebar' %>
27
+ <%= render_admin_partials(:dashboard_sidebar_partials) %>
28
+ </div>
33
29
  </div>
@@ -6,7 +6,7 @@
6
6
  <% end %>
7
7
  <th><%= Spree.t(:name) %></th>
8
8
  <th><%= Spree.t(:size) %></th>
9
- <th class="actions"></th>
9
+ <th></th>
10
10
  </tr>
11
11
  </thead>
12
12
  <tbody>
@@ -1,20 +1,12 @@
1
1
  <%= turbo_frame_tag :dialog_modal do %>
2
2
  <%= form_for :digital_asset, url: spree.admin_product_digital_asset_path(@product, @digital_asset), method: :put do |f| %>
3
3
  <div class="modal-content">
4
- <div class="modal-header">
5
- <h5 class="modal-title" id="exampleModalLabel"><%= @digital_asset.attachment.filename %></h5>
6
- <button
7
- type="button"
8
- class="btn-close"
9
- data-dismiss="modal"
10
- aria-label="<%= Spree.t(:close) %>"
11
- />
12
- </div>
4
+ <%= modal_header(@digital_asset.attachment.filename) %>
13
5
  <div class="modal-body">
14
6
  <%= render "spree/admin/digital_assets/form", f: f %>
15
7
  </div>
16
- <div class="modal-footer d-flex justify-content-between">
17
- <button type="button" class="btn btn-light" data-dismiss="modal"><%= Spree.t("actions.discard") %></button>
8
+ <div class="modal-footer">
9
+ <%= modal_discard_button %>
18
10
  <%= turbo_save_button_tag Spree.t("actions.save"), data: { turbo_frame: :_top } %>
19
11
  </div>
20
12
  </div>