spree_admin 5.0.0 → 5.0.2

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 (140) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/spree/admin/components/_alerts.scss +6 -3
  3. data/app/assets/stylesheets/spree/admin/components/_bulk_panel.scss +11 -1
  4. data/app/assets/stylesheets/spree/admin/components/_cards.scss +3 -4
  5. data/app/assets/stylesheets/spree/admin/components/_dropdowns.scss +1 -1
  6. data/app/assets/stylesheets/spree/admin/components/_main.scss +8 -1
  7. data/app/assets/stylesheets/spree/admin/components/_modals.scss +1 -1
  8. data/app/assets/stylesheets/spree/admin/global/_variables.scss +12 -6
  9. data/app/assets/stylesheets/spree/admin/shared/_base.scss +3 -5
  10. data/app/controllers/spree/admin/posts_controller.rb +6 -0
  11. data/app/controllers/spree/admin/products_controller.rb +7 -8
  12. data/app/controllers/spree/admin/storefront_controller.rb +1 -1
  13. data/app/controllers/spree/admin/translations_controller.rb +1 -1
  14. data/app/controllers/spree/admin/users_controller.rb +1 -1
  15. data/app/helpers/spree/admin/base_helper.rb +49 -57
  16. data/app/helpers/spree/admin/bulk_operations_helper.rb +86 -0
  17. data/app/helpers/spree/admin/modal_helper.rb +29 -0
  18. data/app/helpers/spree/admin/navigation_helper.rb +76 -1
  19. data/app/helpers/spree/admin/orders_helper.rb +0 -19
  20. data/app/helpers/spree/admin/stores_helper.rb +5 -34
  21. data/app/javascript/spree/admin/controllers/slug_form_controller.js +0 -3
  22. data/app/javascript/spree/admin/controllers/variants_form_controller.js +6 -0
  23. data/app/javascript/spree/admin/helpers/bootstrap.js +3 -3
  24. data/app/views/active_storage/_upload_form.html.erb +4 -8
  25. data/app/views/spree/admin/assets/edit.html.erb +3 -8
  26. data/app/views/spree/admin/coupon_codes/index.html.erb +4 -6
  27. data/app/views/spree/admin/custom_domains/_custom_domains.html.erb +1 -1
  28. data/app/views/spree/admin/custom_domains/index.html.erb +1 -1
  29. data/app/views/spree/admin/customer_returns/index.html.erb +4 -17
  30. data/app/views/spree/admin/dashboard/_setup_progress.html.erb +4 -2
  31. data/app/views/spree/admin/dashboard/show.html.erb +1 -1
  32. data/app/views/spree/admin/digital_assets/_table.html.erb +1 -1
  33. data/app/views/spree/admin/digital_assets/edit.html.erb +3 -11
  34. data/app/views/spree/admin/digital_assets/new.html.erb +3 -11
  35. data/app/views/spree/admin/errors/forbidden.html.erb +13 -0
  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/_filters.html.erb +2 -7
  43. data/app/views/spree/admin/orders/_list.html.erb +2 -4
  44. data/app/views/spree/admin/orders/billing_address/create.turbo_stream.erb +3 -6
  45. data/app/views/spree/admin/orders/billing_address/edit.html.erb +3 -6
  46. data/app/views/spree/admin/orders/billing_address/new.html.erb +3 -6
  47. data/app/views/spree/admin/orders/billing_address/update.turbo_stream.erb +3 -6
  48. data/app/views/spree/admin/orders/contact_information/edit.html.erb +3 -6
  49. data/app/views/spree/admin/orders/customer_returns/edit.html.erb +1 -10
  50. data/app/views/spree/admin/orders/index.html.erb +1 -1
  51. data/app/views/spree/admin/orders/return_authorizations/_form.html.erb +1 -1
  52. data/app/views/spree/admin/orders/return_authorizations/show.html.erb +45 -43
  53. data/app/views/spree/admin/orders/shipping_address/create.turbo_stream.erb +3 -6
  54. data/app/views/spree/admin/orders/shipping_address/edit.html.erb +3 -6
  55. data/app/views/spree/admin/orders/shipping_address/new.html.erb +3 -6
  56. data/app/views/spree/admin/orders/shipping_address/update.turbo_stream.erb +3 -6
  57. data/app/views/spree/admin/pages/_filters.html.erb +1 -1
  58. data/app/views/spree/admin/pages/_page.html.erb +26 -0
  59. data/app/views/spree/admin/pages/edit.html.erb +2 -5
  60. data/app/views/spree/admin/pages/index.html.erb +9 -7
  61. data/app/views/spree/admin/payment_methods/index.html.erb +10 -8
  62. data/app/views/spree/admin/post_categories/_post_category.html.erb +5 -2
  63. data/app/views/spree/admin/post_categories/index.html.erb +6 -7
  64. data/app/views/spree/admin/posts/_filters.html.erb +4 -9
  65. data/app/views/spree/admin/posts/_form.html.erb +2 -2
  66. data/app/views/spree/admin/posts/_post.html.erb +1 -11
  67. data/app/views/spree/admin/posts/index.html.erb +7 -11
  68. data/app/views/spree/admin/products/_bulk_operations.html.erb +59 -94
  69. data/app/views/spree/admin/products/_filters.html.erb +12 -7
  70. data/app/views/spree/admin/products/_list.html.erb +2 -10
  71. data/app/views/spree/admin/products/_product.html.erb +1 -4
  72. data/app/views/spree/admin/products/bulk_modal.html.erb +3 -8
  73. data/app/views/spree/admin/products/index.html.erb +5 -5
  74. data/app/views/spree/admin/promotion_actions/new.html.erb +7 -12
  75. data/app/views/spree/admin/promotion_rules/new.html.erb +7 -12
  76. data/app/views/spree/admin/promotions/_filters.html.erb +27 -0
  77. data/app/views/spree/admin/promotions/index.html.erb +7 -35
  78. data/app/views/spree/admin/properties/index.html.erb +10 -9
  79. data/app/views/spree/admin/refund_reasons/index.html.erb +37 -35
  80. data/app/views/spree/admin/refunds/edit.html.erb +3 -8
  81. data/app/views/spree/admin/reimbursement_types/index.html.erb +42 -40
  82. data/app/views/spree/admin/reports/_report.html.erb +1 -1
  83. data/app/views/spree/admin/return_authorization_reasons/index.html.erb +41 -41
  84. data/app/views/spree/admin/return_authorizations/_filters.html.erb +1 -1
  85. data/app/views/spree/admin/return_authorizations/_list.html.erb +1 -10
  86. data/app/views/spree/admin/return_authorizations/index.html.erb +1 -1
  87. data/app/views/spree/admin/roles/_form.html.erb +1 -1
  88. data/app/views/spree/admin/roles/index.html.erb +26 -24
  89. data/app/views/spree/admin/shared/_bulk_modal.html.erb +6 -7
  90. data/app/views/spree/admin/shared/_filter_submit.html.erb +6 -0
  91. data/app/views/spree/admin/shared/_modal.html.erb +2 -8
  92. data/app/views/spree/admin/shared/_multi_product_picker.html.erb +2 -4
  93. data/app/views/spree/admin/shared/_no_resource_found.html.erb +1 -1
  94. data/app/views/spree/admin/shared/_product_image.html.erb +1 -10
  95. data/app/views/spree/admin/shared/_refunds.html.erb +1 -1
  96. data/app/views/spree/admin/shared/sidebar/_orders_nav.html.erb +1 -1
  97. data/app/views/spree/admin/shared/sidebar/_store_dropdown.html.erb +36 -7
  98. data/app/views/spree/admin/shared/sidebar/_store_nav.html.erb +4 -0
  99. data/app/views/spree/admin/shared/sortable_tree/_taxonomy.html.erb +3 -23
  100. data/app/views/spree/admin/shipping_categories/index.html.erb +28 -26
  101. data/app/views/spree/admin/shipping_methods/_actions.html.erb +1 -1
  102. data/app/views/spree/admin/shipping_methods/index.html.erb +23 -21
  103. data/app/views/spree/admin/stock_items/_filters.html.erb +2 -7
  104. data/app/views/spree/admin/stock_items/index.html.erb +5 -8
  105. data/app/views/spree/admin/stock_locations/_stock_location.html.erb +16 -13
  106. data/app/views/spree/admin/stock_locations/index.html.erb +24 -21
  107. data/app/views/spree/admin/stock_transfers/_filters.html.erb +1 -1
  108. data/app/views/spree/admin/stock_transfers/_new_variant_modal.html.erb +3 -5
  109. data/app/views/spree/admin/stock_transfers/index.html.erb +6 -6
  110. data/app/views/spree/admin/store_credit_categories/_form.html.erb +1 -1
  111. data/app/views/spree/admin/store_credit_categories/edit.html.erb +6 -4
  112. data/app/views/spree/admin/store_credit_categories/index.html.erb +28 -24
  113. data/app/views/spree/admin/store_credits/index.html.erb +2 -2
  114. data/app/views/spree/admin/storefront/edit.html.erb +7 -9
  115. data/app/views/spree/admin/stores/form/_policies.html.erb +1 -1
  116. data/app/views/spree/admin/stores/new.html.erb +9 -6
  117. data/app/views/spree/admin/tax_categories/index.html.erb +24 -22
  118. data/app/views/spree/admin/tax_rates/index.html.erb +26 -24
  119. data/app/views/spree/admin/taxonomies/index.html.erb +4 -4
  120. data/app/views/spree/admin/taxonomies/show.html.erb +2 -2
  121. data/app/views/spree/admin/themes/_theme_preview_image.html.erb +1 -10
  122. data/app/views/spree/admin/themes/index.html.erb +2 -2
  123. data/app/views/spree/admin/translations/_translations_unavailable.html.erb +6 -8
  124. data/app/views/spree/admin/users/_filters.html.erb +2 -7
  125. data/app/views/spree/admin/users/_lifetime_stats.html.erb +1 -1
  126. data/app/views/spree/admin/users/_tabs.html.erb +4 -4
  127. data/app/views/spree/admin/users/_user.html.erb +1 -4
  128. data/app/views/spree/admin/users/bulk_modal.html.erb +3 -8
  129. data/app/views/spree/admin/users/index.html.erb +25 -58
  130. data/app/views/spree/admin/variants/form/_media_asset.html.erb +1 -7
  131. data/app/views/spree/admin/variants/form/_pricing.html.erb +1 -1
  132. data/app/views/spree/admin/webhooks_subscribers/_form.html.erb +1 -1
  133. data/app/views/spree/admin/webhooks_subscribers/index.html.erb +25 -22
  134. data/app/views/spree/admin/webhooks_subscribers/show.html.erb +3 -3
  135. data/app/views/spree/admin/zones/index.html.erb +34 -32
  136. data/config/initializers/chartkick.rb +1 -1
  137. data/config/locales/en.yml +3 -7
  138. metadata +14 -10
  139. data/app/views/spree/admin/pages/_page.erb +0 -8
  140. data/app/views/spree/admin/products/_empty_list.html.erb +0 -1
@@ -16,6 +16,7 @@ module Spree
16
16
 
17
17
  # the per_page_dropdown is used on index pages like orders, products, promotions etc.
18
18
  # this method generates the select_tag
19
+ # @return [String]
19
20
  def per_page_dropdown
20
21
  per_page_default = if @products
21
22
  Spree::Admin::RuntimeConfig.admin_products_per_page
@@ -48,6 +49,8 @@ module Spree
48
49
 
49
50
  # helper method to create proper url to apply per page ing
50
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
51
54
  def per_page_dropdown_params(per_page)
52
55
  args = params.permit!.to_h.clone
53
56
  args.delete(:page)
@@ -56,6 +59,12 @@ module Spree
56
59
  args
57
60
  end
58
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
59
68
  def link_to_edit(resource, options = {})
60
69
  url = options[:url] || edit_object_url(resource)
61
70
  options[:data] ||= {}
@@ -64,6 +73,12 @@ module Spree
64
73
  link_to_with_icon('pencil', Spree.t(:edit), url, options) if can?(:update, resource)
65
74
  end
66
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
67
82
  def link_to_delete(resource, options = {})
68
83
  url = options[:url] || object_url(resource)
69
84
  name = options[:name] || Spree.t('actions.destroy')
@@ -81,6 +96,12 @@ module Spree
81
96
  end
82
97
  end
83
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
84
105
  def link_to_with_icon(icon_name, text, url, options = {})
85
106
  options[:class] ||= (options[:class].to_s + " with-tip").strip
86
107
  options[:title] ||= text if options[:no_text]
@@ -95,6 +116,12 @@ module Spree
95
116
  link_to(text.html_safe, url, options)
96
117
  end
97
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
98
125
  def active_link_to_with_icon(icon_name, text, url, options = {})
99
126
  options[:class] = (options[:class].to_s + " with-tip").strip
100
127
  options[:title] = text if options[:no_text]
@@ -109,7 +136,13 @@ module Spree
109
136
  active_link_to(text.html_safe, url, options)
110
137
  end
111
138
 
139
+ # renders a button with an icon (optional)
112
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
113
146
  def button(text, icon_name = nil, button_type = 'submit', options = {})
114
147
  if icon_name
115
148
  text = "#{icon(icon_name, class: "icon icon-#{icon_name}")} #{text}"
@@ -128,6 +161,8 @@ module Spree
128
161
  end
129
162
 
130
163
  def button_link_to(text, url, html_options = {})
164
+ Spree::Deprecation.warn("button_link_to is deprecated. Use standard link_to instead.")
165
+
131
166
  if html_options[:method] &&
132
167
  !html_options[:method].to_s.casecmp('get').zero? &&
133
168
  !html_options[:remote]
@@ -149,6 +184,10 @@ module Spree
149
184
  end
150
185
  end
151
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
152
191
  def active_badge(condition, options = {})
153
192
  label = options[:label]
154
193
  label ||= condition ? Spree.t(:say_yes) : Spree.t(:say_no)
@@ -161,6 +200,11 @@ module Spree
161
200
  end
162
201
  end
163
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
164
208
  def page_header_back_button(default_url, object = nil, label = nil)
165
209
  url = default_url
166
210
 
@@ -175,10 +219,15 @@ module Spree
175
219
  end
176
220
  end
177
221
 
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
178
227
  def external_link_to(label, url, opts = {}, &block)
179
228
  opts[:target] ||= :blank
180
229
  opts[:rel] ||= :nofollow
181
- opts[:class] ||= "d-inline-flex align-items-center text-blue"
230
+ opts[:class] ||= "d-inline-flex align-items-center text-blue text-decoration-none"
182
231
 
183
232
  if block_given?
184
233
  link_to url, opts, &block
@@ -189,6 +238,32 @@ module Spree
189
238
  end
190
239
  end
191
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
192
267
  def help_bubble(text = '', placement = 'bottom', css: nil)
193
268
  css ||= 'text-muted'
194
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,16 +45,7 @@ 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
51
  content_tag(:div, initials, class: "avatar rounded with-tip bg-light",
@@ -10,8 +10,5 @@ export default class extends Controller {
10
10
  const name = this.nameTarget.value
11
11
  const url = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)+/g, '')
12
12
  this.urlTarget.value = url
13
-
14
- // TODO: do ajax call and check if url is available
15
- // if not, append a number to the end to make it unique
16
13
  }
17
14
  }
@@ -587,6 +587,12 @@ export default class extends CheckboxSelectAll {
587
587
  }
588
588
 
589
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
+
590
596
  const nameInput = document.createElement('input')
591
597
  nameInput.type = 'hidden'
592
598
  nameInput.name = `product[variants_attributes][${i}][options][][name]`
@@ -4,11 +4,11 @@ import { lockScroll, unlockScroll } from 'spree/core/helpers/scroll_lock'
4
4
 
5
5
 
6
6
  const initTooltips = () => {
7
- $('.with-tip').each(function() {
7
+ $('.with-tip, .trix-button').each(function() {
8
8
  $(this).tooltip()
9
9
  })
10
10
 
11
- $('.with-tip').on('show.bs.tooltip', function(event) {
11
+ $('.with-tip, .trix-button').on('show.bs.tooltip', function(event) {
12
12
  if (('ontouchstart' in window)) {
13
13
  event.preventDefault()
14
14
  }
@@ -16,7 +16,7 @@ const initTooltips = () => {
16
16
  }
17
17
 
18
18
  const removeTooltips = () => {
19
- $('.with-tip').each(function() {
19
+ $('.with-tip, .trix-button').each(function() {
20
20
  $(this).tooltip('dispose')
21
21
  })
22
22
  }
@@ -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
@@ -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">
@@ -17,7 +17,7 @@
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' %>
@@ -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>
@@ -1,20 +1,12 @@
1
1
  <%= turbo_frame_tag :dialog_modal do %>
2
2
  <%= form_for :digital_asset, url: spree.admin_product_digital_assets_path(@product) do |f| %>
3
3
  <div class="modal-content">
4
- <div class="modal-header">
5
- <h5 class="modal-title" id="exampleModalLabel"><%= Spree.t(:new_digital_asset) %></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(Spree.t(:new_digital_asset)) %>
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>
@@ -0,0 +1,13 @@
1
+ <%= content_for :title do %>
2
+ <%= Spree.t(:forbidden) %>
3
+ <% end %>
4
+
5
+ <%= content_for :page_title do %>
6
+ <%= Spree.t(:forbidden) %>
7
+ <% end %>
8
+
9
+ <p class="text-danger">
10
+ <%= Spree.t(:forbidden_message) %>
11
+ </p>
12
+
13
+ <%= link_to Spree.t('admin.back_to_dashboard'), spree.admin_dashboard_path, class: 'btn btn-primary' %>
@@ -1,30 +1,28 @@
1
1
  <%= render 'spree/admin/shared/audit_nav' %>
2
2
 
3
- <% if @collection.present? %>
4
- <div class="table-responsive card-lg p-0">
5
- <table class="table">
6
- <thead class="text-muted">
7
- <tr>
8
- <th><%= Spree.t(:number) %></th>
9
- <th class="text-center"><%= Spree.t(:kind) %></th>
10
- <th class="text-center"><%= Spree.t(:status) %></th>
11
- <th><%= Spree.t(:user) %></th>
12
- <th><%= Spree.t(:filename) %></th>
13
- <th><%= Spree.t(:date) %></th>
14
- <th><%= Spree.t(:size) %></th>
15
- <th class="text-center"><%= Spree.t(:download) %></th>
16
- </tr>
17
- </thead>
3
+ <div class="card-lg">
4
+ <% if @collection.any? %>
5
+ <div class="table-responsive">
6
+ <table class="table">
7
+ <thead class="text-muted">
8
+ <tr>
9
+ <th><%= Spree.t(:number) %></th>
10
+ <th class="text-center"><%= Spree.t(:kind) %></th>
11
+ <th class="text-center"><%= Spree.t(:status) %></th>
12
+ <th><%= Spree.t(:user) %></th>
13
+ <th><%= Spree.t(:filename) %></th>
14
+ <th><%= Spree.t(:date) %></th>
15
+ <th><%= Spree.t(:size) %></th>
16
+ <th class="text-center"><%= Spree.t(:download) %></th>
17
+ </tr>
18
+ </thead>
18
19
  <tbody>
19
- <%= render partial: 'export', collection: @exports, cached: true %>
20
+ <%= render partial: 'export', collection: @collection, cached: true %>
20
21
  </tbody>
21
22
  </table>
23
+ <%= render 'spree/admin/shared/index_table_options', collection: @collection %>
22
24
  </div>
23
- </div>
24
- <% else %>
25
- <div class="text-muted p-5 d-flex align-items-center w-100 justify-content-center">
26
- <%= Spree.t(:no_resource_found, resource: plural_resource_name(model_class)) %>
27
- </div>
28
- <% end %>
29
-
30
- <%= render 'spree/admin/shared/index_table_options', collection: @imports, simple: true if @imports.present? %>
25
+ <% else %>
26
+ <%= render 'spree/admin/shared/no_resource_found', new_object_url: nil %>
27
+ <% end %>
28
+ </div>
@@ -3,13 +3,7 @@
3
3
  <%= f.hidden_field :type %>
4
4
  <%= f.hidden_field :search_params %>
5
5
  <div class="modal-content">
6
- <div class="modal-header">
7
- <h5 class="modal-title" id="exampleModalLabel">
8
- <%= Spree.t(:export) %>
9
- <%= plural_resource_name(@export.model_class) %>
10
- </h5>
11
- <button type="button" class="btn-close" data-dismiss="modal" aria-label="<%= Spree.t(:close) %>" />
12
- </div>
6
+ <%= modal_header(Spree.t(:export) + ' ' + plural_resource_name(@export.model_class)) %>
13
7
  <div class="modal-body">
14
8
  <%= render 'spree/admin/shared/error_messages', target: @export %>
15
9
  <div class="custom-control custom-radio">
@@ -33,8 +27,8 @@
33
27
  <% end %>
34
28
  </div>
35
29
  </div>
36
- <div class="modal-footer d-flex justify-content-between">
37
- <button type="button" class="btn btn-light" data-dismiss="modal"><%= Spree.t('actions.discard') %></button>
30
+ <div class="modal-footer">
31
+ <%= modal_discard_button %>
38
32
  <%= turbo_save_button_tag Spree.t(:export), class: 'btn btn-primary' %>
39
33
  </div>
40
34
  </div>
@@ -1,9 +1,6 @@
1
1
  <%= turbo_frame_tag :dialog_modal do %>
2
2
  <div class="modal-content" data-controller="search-picker">
3
- <div class="modal-header">
4
- <h5 class="modal-title" id="exampleModalLabel"><%= Spree.t(:add_variant) %></h5>
5
- <button type="button" class="btn-close" data-dismiss="modal" aria-label="<%= Spree.t(:close) %>" />
6
- </div>
3
+ <%= modal_header(Spree.t(:add_variant)) %>
7
4
  <div class="modal-body border-bottom">
8
5
  <%= form_with url: spree.admin_variants_search_path, method: :post, data: { controller: 'auto-submit', turbo_frame: '_top' } do |form| %>
9
6
  <%= form.hidden_field :omit_ids, value: @order.variant_ids.join(',') %>
@@ -20,7 +17,7 @@
20
17
  </p>
21
18
  </div>
22
19
  </div>
23
- <div class="modal-footer d-flex justify-content-between border-top">
20
+ <div class="modal-footer border-top">
24
21
  <div class="d-flex gap-2 m-0 align-items-center">
25
22
  <%= form.label :quantity, Spree.t(:quantity), class: "mb-0" %>
26
23
  <%= form.number_field :quantity, class: "form-control", min: 1 %>