spree_admin 5.4.1 → 5.4.3

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 (28) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/spree/admin/bulk_operations_controller.rb +4 -0
  3. data/app/controllers/spree/admin/imports_controller.rb +1 -1
  4. data/app/controllers/spree/admin/invitations_controller.rb +1 -2
  5. data/app/controllers/spree/admin/option_types_controller.rb +16 -3
  6. data/app/controllers/spree/admin/resource_controller.rb +11 -2
  7. data/app/controllers/spree/admin/states_controller.rb +13 -0
  8. data/app/controllers/spree/admin/zones_controller.rb +0 -1
  9. data/app/helpers/spree/admin/table_helper.rb +7 -1
  10. data/app/javascript/spree/admin/application.js +2 -0
  11. data/app/javascript/spree/admin/controllers/zone_state_select_controller.js +31 -0
  12. data/app/subscribers/spree/admin/import_row_subscriber.rb +1 -0
  13. data/app/subscribers/spree/admin/import_subscriber.rb +25 -11
  14. data/app/views/spree/admin/gift_cards/_form.html.erb +1 -1
  15. data/app/views/spree/admin/imports/_loader.html.erb +5 -0
  16. data/app/views/spree/admin/imports/show.html.erb +14 -0
  17. data/app/views/spree/admin/invitations/expired.html.erb +4 -0
  18. data/app/views/spree/admin/option_types/_form.html.erb +37 -2
  19. data/app/views/spree/admin/orders/_line_item.html.erb +3 -3
  20. data/app/views/spree/admin/orders/_shipment.html.erb +1 -1
  21. data/app/views/spree/admin/shared/_user_dropdown.html.erb +1 -1
  22. data/app/views/spree/admin/zones/_state_members.html.erb +14 -4
  23. data/config/initializers/spree_admin_tables.rb +2 -2
  24. data/config/locales/en.yml +3 -1
  25. data/config/routes.rb +10 -1
  26. data/lib/spree/admin/runtime_configuration.rb +1 -0
  27. data/lib/spree/admin/tailwind_helper.rb +1 -1
  28. metadata +9 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 26df0b31a098e6532b1f1ce9a0d9c93e5775eabfdb0aae25d97ddc2cad9817f7
4
- data.tar.gz: d9a8d58ad5854ae05313f113ad57530aaa1a7b70d75bb4d19c20f7fc0904a71b
3
+ metadata.gz: 9a5af2b78a13b13f570093bfe92c6d6c6b3ade67ec72e294fbf0f1ffd9c121d6
4
+ data.tar.gz: 6dfa405d89717625d66b270fe16f7343bb8ec532f8ba673ee856361eb3682e92
5
5
  SHA512:
6
- metadata.gz: 142a56b2d97a37fd72ec7230a0d35bc83a3ea1e56b31c36c536a1e33a5714c1148c4e69d6e779348fa10cef3f8157e0e14909641a9472419c95bd09da52bd48d
7
- data.tar.gz: f29b088464374c13ae4bbc77a549f15524cd6661fedc3ac6e3d3f484c3dba47b91bd1e0d643031ddf953c156949f7fdf54ed889cc026096ca701df6b9e6db0e3
6
+ metadata.gz: 9172a34304882f931b1bf56502ffd09121ca3497d8e3b24b5520dc03cf6cebf5a70c6e284615098dc4c70462f153aa204899911f152902e75317b5130760222d
7
+ data.tar.gz: 91f7065af97ecddea447d6add3cd60ab8d36ceb6590ced8ca3e74bbe65a26eeded78625209b38e5b5ad9f26e43605bdc05fb594664f0d1aad1fbe51af22f17b9
@@ -29,6 +29,10 @@ module Spree
29
29
  table = Spree.admin.tables.get(table_key)
30
30
  table.find_bulk_action(key.to_sym)
31
31
  end
32
+
33
+ def authorize_admin
34
+ params[:kind] == 'set_active' ? authorize!(:bulk_activate, Spree::Product) : super
35
+ end
32
36
  end
33
37
  end
34
38
  end
@@ -14,7 +14,7 @@ module Spree
14
14
  if @object.status == 'mapping'
15
15
  @mappings = @object.mappings
16
16
  @mappings_options = @object.unmapped_file_columns.map { |file_column| [file_column, file_column] }
17
- else
17
+ elsif !@object.large_import?
18
18
  @rows = @object.rows.processed.includes(:item)
19
19
  end
20
20
  end
@@ -63,8 +63,7 @@ module Spree
63
63
  redirect_to spree.new_admin_admin_user_path(token: @invitation.token), status: :see_other
64
64
  end
65
65
  rescue ActiveRecord::RecordNotFound
66
- redirect_to spree.root_path, alert: Spree.t('invalid_or_expired_invitation')
67
- nil
66
+ render :expired, status: :not_found
68
67
  end
69
68
 
70
69
  # PUT /admin/invitations/:id/accept
@@ -1,7 +1,7 @@
1
1
  module Spree
2
2
  module Admin
3
3
  class OptionTypesController < ResourceController
4
- before_action :setup_new_option_value, only: :edit
4
+ before_action :setup_option_values, only: [:edit, :new]
5
5
 
6
6
  include ProductsBreadcrumbConcern
7
7
  add_breadcrumb Spree.t(:options), :admin_option_types_path
@@ -10,8 +10,21 @@ module Spree
10
10
 
11
11
  private
12
12
 
13
- def setup_new_option_value
14
- @option_type.option_values.build if @option_type.option_values.empty?
13
+ def setup_option_values
14
+ per_page = Spree::Admin::RuntimeConfig.admin_option_values_per_page
15
+ @option_values_page = [params[:option_values_page].to_i, 1].max
16
+ @option_values_total = @option_type.option_values.count
17
+
18
+ if @option_values_total == 0
19
+ @option_type.option_values.build
20
+ @option_values = @option_type.option_values
21
+ @option_values_pages = 1
22
+ else
23
+ @option_values = @option_type.option_values.order(:position)
24
+ .offset((@option_values_page - 1) * per_page)
25
+ .limit(per_page)
26
+ @option_values_pages = (@option_values_total.to_f / per_page).ceil
27
+ end
15
28
  end
16
29
 
17
30
  def add_breadcrumbs
@@ -279,8 +279,7 @@ class Spree::Admin::ResourceController < Spree::Admin::BaseController
279
279
 
280
280
  params[:q][:s] ||= collection_default_sort if collection_default_sort.present?
281
281
 
282
- date_range_params = %i[created_at_gt created_at_lt updated_at_gt updated_at_lt]
283
- date_range_params.each do |param|
282
+ %i[created_at_gt updated_at_gt].each do |param|
284
283
  if params[:q][param].present?
285
284
  params[:q][param] = begin
286
285
  params[:q][param].to_date&.in_time_zone(current_timezone)&.beginning_of_day
@@ -290,6 +289,16 @@ class Spree::Admin::ResourceController < Spree::Admin::BaseController
290
289
  end
291
290
  end
292
291
 
292
+ %i[created_at_lt updated_at_lt].each do |param|
293
+ if params[:q][param].present?
294
+ params[:q][param] = begin
295
+ params[:q][param].to_date&.in_time_zone(current_timezone)&.end_of_day
296
+ rescue StandardError
297
+ ''
298
+ end
299
+ end
300
+ end
301
+
293
302
  params[:q]
294
303
  end
295
304
 
@@ -0,0 +1,13 @@
1
+ module Spree
2
+ module Admin
3
+ class StatesController < ResourceController
4
+ belongs_to 'spree/country', find_by: :id
5
+
6
+ def select_options
7
+ states = @country.states.accessible_by(current_ability).order(:name)
8
+
9
+ render json: states.to_tom_select_json
10
+ end
11
+ end
12
+ end
13
+ end
@@ -23,7 +23,6 @@ module Spree
23
23
  current_store.default_country
24
24
  end
25
25
  @countries = Country.order(:name)
26
- @states = @selected_country&.states&.order(:name) || Spree::State.none
27
26
  @zones = Zone.order(:name)
28
27
  end
29
28
 
@@ -79,7 +79,13 @@ module Spree
79
79
  def render_money_column(value, column)
80
80
  return empty_column_placeholder if value.blank?
81
81
 
82
- value.respond_to?(:display_amount) ? value.display_amount : Spree::Money.new(value, currency: current_currency).to_html
82
+ if value.respond_to?(:display_amount)
83
+ value.display_amount
84
+ elsif value.is_a?(Spree::Money)
85
+ value.to_html
86
+ else
87
+ Spree::Money.new(value, currency: current_currency).to_html
88
+ end
83
89
  end
84
90
 
85
91
  # Render date column
@@ -92,6 +92,7 @@ import TooltipController from 'spree/admin/controllers/tooltip_controller'
92
92
  import TurboSubmitButtonController from 'spree/admin/controllers/turbo_submit_button_controller'
93
93
  import UnitSystemController from 'spree/admin/controllers/unit_system_controller'
94
94
  import VariantsFormController from 'spree/admin/controllers/variants_form_controller'
95
+ import ZoneStateSelectController from 'spree/admin/controllers/zone_state_select_controller'
95
96
  import BulkEditorController from 'spree/admin/controllers/bulk_editor_controller'
96
97
  import AddressAutocompleteController from 'spree/core/controllers/address_autocomplete_controller'
97
98
  import AddressFormController from 'spree/core/controllers/address_form_controller'
@@ -166,6 +167,7 @@ application.register('turbo-submit-button', TurboSubmitButtonController)
166
167
  application.register('textarea-autogrow', TextareaAutogrow)
167
168
  application.register('unit-system', UnitSystemController)
168
169
  application.register('variants-form', VariantsFormController)
170
+ application.register('zone-state-select', ZoneStateSelectController)
169
171
  application.register('bulk-editor', BulkEditorController)
170
172
 
171
173
  LocalTime.start()
@@ -0,0 +1,31 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+ import { get } from '@rails/request.js'
3
+
4
+ export default class extends Controller {
5
+ static values = {
6
+ url: String
7
+ }
8
+
9
+ static targets = ["statesSelect"]
10
+
11
+ async countryChanged(event) {
12
+ const countryId = event.target.value
13
+ const statesInput = this.statesSelectTarget.querySelector('select')
14
+ if (!statesInput || !statesInput.tomselect) return
15
+
16
+ const tomSelect = statesInput.tomselect
17
+ tomSelect.clear()
18
+ tomSelect.clearOptions()
19
+
20
+ if (!countryId) return
21
+
22
+ const url = this.urlValue.replace(':country_id', countryId)
23
+ const response = await get(url, { contentType: 'application/json' })
24
+
25
+ if (response.ok) {
26
+ const states = await response.json
27
+ states.forEach(state => tomSelect.addOption(state))
28
+ tomSelect.refreshOptions(false)
29
+ }
30
+ }
31
+ }
@@ -23,6 +23,7 @@ module Spree
23
23
 
24
24
  import_row = Spree::ImportRow.find_by_prefix_id(import_row_id)
25
25
  return unless import_row
26
+ return if import_row.import.large_import?
26
27
 
27
28
  add_row_to_import_view(import_row)
28
29
  update_footer_in_import_view(import_row)
@@ -4,24 +4,17 @@ module Spree
4
4
  module Admin
5
5
  # Handles Import events for the admin interface.
6
6
  #
7
- # This subscriber listens to import.completed event and handles:
8
- # - Updating the loader in the import view (Turbo Streams)
9
- #
10
- # We use async: false because the UI update should happen immediately
11
- # after the import completes.
7
+ # We use async: false because the UI updates should happen immediately.
12
8
  #
13
9
  class ImportSubscriber < Spree::Subscriber
14
- subscribes_to 'import.completed', async: false
10
+ subscribes_to 'import.completed', 'import.progress', async: false
15
11
 
16
12
  on 'import.completed', :update_loader_in_import_view
13
+ on 'import.progress', :update_footer_in_import_view
17
14
 
18
15
  def update_loader_in_import_view(event)
19
- import_id = event.payload['id']
20
- return unless import_id
21
-
22
- import = Spree::Import.find_by_prefix_id(import_id)
16
+ import = find_import(event)
23
17
  return unless import
24
- return unless import.respond_to?(:broadcast_update_to)
25
18
 
26
19
  import.broadcast_update_to(
27
20
  "import_#{import.id}_loader",
@@ -30,6 +23,27 @@ module Spree
30
23
  locals: { import: import }
31
24
  )
32
25
  end
26
+
27
+ def update_footer_in_import_view(event)
28
+ import = find_import(event)
29
+ return unless import
30
+
31
+ import.broadcast_replace_to(
32
+ "import_#{import.id}_footer",
33
+ target: 'footer',
34
+ partial: 'spree/admin/imports/footer',
35
+ locals: { import: import }
36
+ )
37
+ end
38
+
39
+ private
40
+
41
+ def find_import(event)
42
+ import_id = event.payload['id']
43
+ return unless import_id
44
+
45
+ Spree::Import.find_by_prefix_id(import_id)
46
+ end
33
47
  end
34
48
  end
35
49
  end
@@ -1,7 +1,7 @@
1
1
  <div class="card mb-6">
2
2
  <div class="card-body">
3
3
  <% unless f.object.persisted? %>
4
- <%= f.spree_text_field :code, required: true, help_bubble: Spree.t('admin.gift_cards.code_help_text'), autofocus: true %>
4
+ <%= f.spree_text_field :code, help_bubble: Spree.t('admin.gift_cards.code_help_text'), autofocus: true %>
5
5
  <% end %>
6
6
 
7
7
  <%= f.spree_money_field :amount, currency: f.object.currency, required: true %>
@@ -2,6 +2,11 @@
2
2
  <div class="flex justify-center items-center my-12 flex-col pb-12">
3
3
  <%= icon('check', class: 'text-green-700', style: 'font-size: 4rem;') %>
4
4
  <p class="text-green-700 mb-3"><%= Spree.t('admin.imports.import_done') %>!</p>
5
+ <% if import.large_import? %>
6
+ <p class="text-gray-600 mb-3">
7
+ <%= Spree.t('admin.imports.large_import_summary', completed: import.rows.completed.count, failed: import.rows.failed.count) %>
8
+ </p>
9
+ <% end %>
5
10
  <%= link_to_with_icon 'arrow-back-up', Spree.t('admin.back_to_dashboard'), spree.admin_path, class: 'btn btn-light mb-12' %>
6
11
  </div>
7
12
  <% else %>
@@ -25,6 +25,20 @@
25
25
  </div>
26
26
 
27
27
  <%= render 'spree/admin/imports/mapping_footer', import: @import %>
28
+ <% elsif @import.large_import? %>
29
+ <%= turbo_stream_from "import_#{@import.id}_footer" %>
30
+ <%= turbo_stream_from "import_#{@import.id}_loader" %>
31
+
32
+ <div class="p-6 text-center text-gray-600 my-8">
33
+ <p class="mb-2"><%= Spree.t('admin.imports.large_import_message', count: @import.rows_count) %></p>
34
+ <p><%= Spree.t('admin.imports.large_import_background_note') %></p>
35
+ </div>
36
+
37
+ <div id="loader" data-controller="auto-scroll">
38
+ <%= render 'spree/admin/imports/loader', import: @import %>
39
+ </div>
40
+
41
+ <%= render 'spree/admin/imports/footer', import: @import %>
28
42
  <% else %>
29
43
  <%= turbo_stream_from "import_#{@import.id}_rows" %>
30
44
  <%= turbo_stream_from "import_#{@import.id}_footer" %>
@@ -0,0 +1,4 @@
1
+ <div class="text-center">
2
+ <h1 class="text-2xl font-semibold mb-2"><%= Spree.t('invitation_expired.heading') %></h1>
3
+ <p class="text-gray-500"><%= Spree.t('invitation_expired.body') %></p>
4
+ </div>
@@ -36,6 +36,11 @@
36
36
  <div class="card mb-6">
37
37
  <div class="card-header flex justify-between items-center">
38
38
  <h5 class="card-title"><%= Spree.t(:option_values) %></h5>
39
+ <% if @option_values_total > 0 %>
40
+ <span class="text-sm text-gray-500">
41
+ <%= @option_values_total %> <%= 'value'.pluralize(@option_values_total) %>
42
+ </span>
43
+ <% end %>
39
44
  </div>
40
45
  <div class="card-body p-0">
41
46
  <div class="table-responsive">
@@ -50,8 +55,7 @@
50
55
  </tr>
51
56
  </thead>
52
57
  <tbody id="option_values" data-controller="sortable" data-sortable-handle-value=".move-handle" data-sortable-resource-name-value="option_value" data-sortable-response-kind-value="turbo-stream">
53
- <% @option_type.option_values.build if @option_type.option_values.empty? %>
54
- <%= f.fields_for :option_values do |option_value_form| %>
58
+ <%= f.fields_for :option_values, @option_values do |option_value_form| %>
55
59
  <%= render partial: 'option_value_fields', locals: { f: option_value_form, option_type: @option_type } %>
56
60
  <% end %>
57
61
 
@@ -69,5 +73,36 @@
69
73
  </tbody>
70
74
  </table>
71
75
  </div>
76
+ <% if @option_values_pages > 1 %>
77
+ <div class="flex items-center justify-between p-3 border-t">
78
+ <span class="text-sm text-gray-500">
79
+ <% per_page = Spree::Admin::RuntimeConfig.admin_option_values_per_page %>
80
+ Showing <%= (@option_values_page - 1) * per_page + 1 %>-<%= [@option_values_page * per_page, @option_values_total].min %> of <%= @option_values_total %>
81
+ </span>
82
+ <div class="flex gap-1.5">
83
+ <% if @option_values_page > 1 %>
84
+ <%= link_to icon('chevron-left', class: 'text-gray-900 mr-0'),
85
+ spree.edit_admin_option_type_path(@option_type, option_values_page: @option_values_page - 1),
86
+ class: "btn btn-light p-2",
87
+ 'aria-label': 'Previous page' %>
88
+ <% else %>
89
+ <button class="btn btn-light p-2 cursor-not-allowed opacity-50" disabled>
90
+ <%= icon('chevron-left', class: 'text-gray-900 mr-0') %>
91
+ </button>
92
+ <% end %>
93
+
94
+ <% if @option_values_page < @option_values_pages %>
95
+ <%= link_to icon('chevron-right', class: 'text-gray-900 mr-0'),
96
+ spree.edit_admin_option_type_path(@option_type, option_values_page: @option_values_page + 1),
97
+ class: "btn btn-light p-2",
98
+ 'aria-label': 'Next page' %>
99
+ <% else %>
100
+ <button class="btn btn-light p-2 cursor-not-allowed opacity-50" disabled>
101
+ <%= icon('chevron-right', class: 'text-gray-900 mr-0') %>
102
+ </button>
103
+ <% end %>
104
+ </div>
105
+ </div>
106
+ <% end %>
72
107
  </div>
73
108
  </div>
@@ -30,12 +30,12 @@
30
30
  <%= dropdown_menu do %>
31
31
  <%= link_to_with_icon "edit",
32
32
  Spree.t(:edit),
33
- spree.edit_admin_order_line_item_path(@order, line_item),
33
+ spree.edit_admin_order_line_item_path(line_item.order, line_item),
34
34
  class: "dropdown-item" %>
35
35
  <% if line_item.digital_links.any? %>
36
36
  <%= link_to_with_icon "refresh",
37
37
  Spree.t("admin.reset_digital_link_download_limits"),
38
- spree.reset_digital_links_limit_admin_order_line_item_path(@order, line_item),
38
+ spree.reset_digital_links_limit_admin_order_line_item_path(line_item.order, line_item),
39
39
  data: {
40
40
  turbo_method: :post,
41
41
  turbo_confirm: Spree.t(:are_you_sure),
@@ -46,7 +46,7 @@
46
46
 
47
47
  <% if can?(:destroy, line_item) %>
48
48
  <div class="dropdown-divider"></div>
49
- <%= link_to_with_icon "trash", Spree.t('actions.destroy'), spree.admin_order_line_item_path(@order, line_item), data: { turbo_method: :delete, turbo_frame: '_top', turbo_confirm: Spree.t(:are_you_sure )}, class: 'dropdown-item text-red-600 hover:bg-red-100' %>
49
+ <%= link_to_with_icon "trash", Spree.t('actions.destroy'), spree.admin_order_line_item_path(line_item.order, line_item), data: { turbo_method: :delete, turbo_frame: '_top', turbo_confirm: Spree.t(:are_you_sure )}, class: 'dropdown-item text-red-600 hover:bg-red-100' %>
50
50
  <% end %>
51
51
  <% end %>
52
52
  <% end %>
@@ -87,7 +87,7 @@
87
87
  <% if can_ship?(shipment) %>
88
88
  <div class="card-footer flex justify-end border-t bg-gray-25">
89
89
  <% if shipment.tracked? %>
90
- <%= link_to_with_icon 'send.svg', Spree.t(:ship), spree.ship_admin_order_shipment_path(order, shipment), class: 'ml-auto btn btn-primary mb-0', data: {turbo_method: :post, turbo_confirm: Spree.t(:are_you_sure)} %>
90
+ <%= link_to_with_icon 'send.svg', Spree.t(:ship), spree.ship_admin_order_shipment_path(order, shipment), class: 'ml-auto btn btn-primary mb-0', data: {turbo_method: :post, turbo_confirm: Spree.t(:are_you_sure), turbo_frame: '_top'} %>
91
91
  <% elsif !shipment.digital? %>
92
92
  <span class="ship ml-auto btn btn-primary disabled mb-0" data-controller="tooltip" data-tooltip-placement-value="left">
93
93
  <%= icon 'send' %>
@@ -38,7 +38,7 @@
38
38
  <%= Spree.t(:support) %>
39
39
  </h6>
40
40
  <%= link_to_with_icon 'book', Spree.t('admin.documentation'), 'https://spreecommerce.org/docs', class: 'dropdown-item', target: '_blank' %>
41
- <%= link_to_with_icon 'brand-slack', Spree.t('admin.slack'), 'https://slack.spreecommerce.org/', class: 'dropdown-item', target: '_blank' %>
41
+ <%= link_to_with_icon 'brand-discord', 'Discord', 'https://discord.spreecommerce.org/', class: 'dropdown-item', target: '_blank' %>
42
42
  <%= link_to_with_icon 'message', Spree.t(:contact_us), 'https://spreecommerce.org/contact/', class: 'dropdown-item', target: '_blank' %>
43
43
  <% end %>
44
44
 
@@ -1,4 +1,4 @@
1
- <div id="state_members">
1
+ <div id="state_members" data-controller="zone-state-select" data-zone-state-select-url-value="<%= spree.select_options_admin_country_states_path(':country_id') %>">
2
2
  <div class="card mb-6">
3
3
  <div class="card-header">
4
4
  <h5 class="card-title">
@@ -9,12 +9,22 @@
9
9
  <div class="card-body">
10
10
  <div class="form-group">
11
11
  <%= label_tag :states_country_id, Spree.t(:country) %>
12
- <%= tom_select_tag :states_country_id, class: 'w-full', options: Spree::Country.joins(:states).to_tom_select_json, active_option: @selected_country&.id, select_data: {action: "auto-submit#submit"} %>
12
+ <%= tom_select_tag :states_country_id,
13
+ class: 'w-full',
14
+ options: Spree::Country.joins(:states).distinct.to_tom_select_json,
15
+ active_option: @selected_country&.id,
16
+ select_data: {action: "change->zone-state-select#countryChanged"}
17
+ %>
13
18
  </div>
14
19
 
15
- <div class="form-group">
20
+ <div class="form-group" data-zone-state-select-target="statesSelect">
16
21
  <%= zone_form.label :state_ids, Spree.t(:states) %>
17
- <%= tom_select_tag 'zone[state_ids]', multiple: true, class: 'w-full', options: @states.to_tom_select_json, active_option: @zone.state_ids %>
22
+ <%= tom_select_tag 'zone[state_ids]',
23
+ multiple: true,
24
+ class: 'w-full',
25
+ url: @selected_country ? spree.select_options_admin_country_states_path(@selected_country) : nil,
26
+ active_option: @zone.state_ids
27
+ %>
18
28
  </div>
19
29
  </div>
20
30
  </div>
@@ -135,7 +135,7 @@ Rails.application.config.after_initialize do
135
135
  action_path: ->(view_context) { view_context.spree.bulk_status_update_admin_products_path(status: 'active') },
136
136
  body: 'admin.bulk_ops.products.body.set_active',
137
137
  position: 10,
138
- condition: -> { can?(:activate, Spree::Product) }
138
+ condition: -> { can?(:bulk_activate, Spree::Product) }
139
139
 
140
140
  Spree.admin.tables.products.add_bulk_action :set_draft,
141
141
  label: 'admin.bulk_ops.products.title.set_draft',
@@ -462,7 +462,7 @@ Rails.application.config.after_initialize do
462
462
  position: 30,
463
463
  ransack_attribute: 'addresses_country_name',
464
464
  operators: %i[eq],
465
- search_url: ->(view_context) { view_context.spree.admin_countries_select_options_path(format: :json) },
465
+ search_url: ->(view_context) { view_context.spree.select_options_admin_countries_path(format: :json) },
466
466
  partial: 'spree/admin/tables/columns/user_location'
467
467
 
468
468
  # Number of orders
@@ -136,6 +136,9 @@ en:
136
136
  all_required_columns_mapped: Good job, all required columns are mapped!
137
137
  field_required: Field required
138
138
  import_done: All done!
139
+ large_import_background_note: You can close this page — the import will continue in the background.
140
+ large_import_message: This import contains %{count} rows and is too large to display individually.
141
+ large_import_summary: "%{completed} completed, %{failed} failed"
139
142
  mapping_required: This field is required
140
143
  please_map_all_required_fields: Please map all the required fields to continue.
141
144
  waiting_for_file_to_be_processed: Waiting for file to be processed...
@@ -294,7 +297,6 @@ en:
294
297
  shipment_transfer:
295
298
  wrong_destination: Wrong destination
296
299
  show_json: Show JSON
297
- slack: Slack
298
300
  stock_transfers:
299
301
  add_products_tip: You need to select a destination location first
300
302
  store_credit:
data/config/routes.rb CHANGED
@@ -62,9 +62,18 @@ Spree::Core::Engine.add_routes do
62
62
  end
63
63
  get '/taxons/select_options' => 'taxons#select_options', as: :taxons_select_options, defaults: { format: :json }
64
64
  get '/tags/select_options' => 'tags#select_options', as: :tags_select_options, defaults: { format: :json }
65
- get '/countries/select_options' => 'countries#select_options', as: :countries_select_options, defaults: { format: :json }
66
65
  get '/users/select_options' => 'users#select_options', as: :users_select_options, defaults: { format: :json }
67
66
  get '/stock_locations/select_options' => 'stock_locations#select_options', as: :stock_locations_select_options, defaults: { format: :json }
67
+ resources :countries, only: [] do
68
+ collection do
69
+ get :select_options, defaults: { format: :json }
70
+ end
71
+ resources :states, only: [] do
72
+ collection do
73
+ get :select_options, defaults: { format: :json }
74
+ end
75
+ end
76
+ end
68
77
 
69
78
  # media library
70
79
  resources :assets, only: [:create, :edit, :update, :destroy] do
@@ -11,6 +11,7 @@ module Spree
11
11
  preference :admin_records_per_page, :integer, default: DEFAULT_PER_PAGE
12
12
  preference :admin_products_per_page, :integer, default: DEFAULT_PER_PAGE
13
13
  preference :admin_orders_per_page, :integer, default: DEFAULT_PER_PAGE
14
+ preference :admin_option_values_per_page, :integer, default: 50
14
15
 
15
16
  preference :include_application_importmap, :boolean, default: false
16
17
  preference :legacy_sidebar_navigation, :boolean, default: false
@@ -43,7 +43,7 @@ module Spree
43
43
 
44
44
  def spree_engines
45
45
  Rails::Engine.subclasses.select do |engine|
46
- engine.name&.start_with?("Spree::")
46
+ engine.name&.start_with?("Spree")
47
47
  end
48
48
  end
49
49
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.4.1
4
+ version: 5.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vendo Connect Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-14 00:00:00.000000000 Z
11
+ date: 2026-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spree
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 5.4.1
19
+ version: 5.4.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 5.4.1
26
+ version: 5.4.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: active_link_to
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -220,20 +220,6 @@ dependencies:
220
220
  - - "~>"
221
221
  - !ruby/object:Gem::Version
222
222
  version: 6.8.5
223
- - !ruby/object:Gem::Dependency
224
- name: pagy
225
- requirement: !ruby/object:Gem::Requirement
226
- requirements:
227
- - - "~>"
228
- - !ruby/object:Gem::Version
229
- version: '43.0'
230
- type: :runtime
231
- prerelease: false
232
- version_requirements: !ruby/object:Gem::Requirement
233
- requirements:
234
- - - "~>"
235
- - !ruby/object:Gem::Version
236
- version: '43.0'
237
223
  - !ruby/object:Gem::Dependency
238
224
  name: ruby-oembed
239
225
  requirement: !ruby/object:Gem::Requirement
@@ -378,6 +364,7 @@ files:
378
364
  - app/controllers/spree/admin/shipments_controller.rb
379
365
  - app/controllers/spree/admin/shipping_categories_controller.rb
380
366
  - app/controllers/spree/admin/shipping_methods_controller.rb
367
+ - app/controllers/spree/admin/states_controller.rb
381
368
  - app/controllers/spree/admin/stock_items_controller.rb
382
369
  - app/controllers/spree/admin/stock_locations_controller.rb
383
370
  - app/controllers/spree/admin/stock_movements_controller.rb
@@ -493,6 +480,7 @@ files:
493
480
  - app/javascript/spree/admin/controllers/turbo_submit_button_controller.js
494
481
  - app/javascript/spree/admin/controllers/unit_system_controller.js
495
482
  - app/javascript/spree/admin/controllers/variants_form_controller.js
483
+ - app/javascript/spree/admin/controllers/zone_state_select_controller.js
496
484
  - app/javascript/spree/admin/helpers/index.js
497
485
  - app/javascript/spree/admin/helpers/tinymce.js
498
486
  - app/javascript/spree/admin/helpers/trix/video_embed.js
@@ -635,6 +623,7 @@ files:
635
623
  - app/views/spree/admin/integrations/new.html.erb
636
624
  - app/views/spree/admin/invitations/_invitation.html.erb
637
625
  - app/views/spree/admin/invitations/create.turbo_stream.erb
626
+ - app/views/spree/admin/invitations/expired.html.erb
638
627
  - app/views/spree/admin/invitations/index.html.erb
639
628
  - app/views/spree/admin/invitations/new.html.erb
640
629
  - app/views/spree/admin/invitations/show.html.erb
@@ -1175,9 +1164,9 @@ licenses:
1175
1164
  - BSD-3-Clause
1176
1165
  metadata:
1177
1166
  bug_tracker_uri: https://github.com/spree/spree/issues
1178
- changelog_uri: https://github.com/spree/spree/releases/tag/v5.4.1
1167
+ changelog_uri: https://github.com/spree/spree/releases/tag/v5.4.3
1179
1168
  documentation_uri: https://docs.spreecommerce.org/
1180
- source_code_uri: https://github.com/spree/spree/tree/v5.4.1
1169
+ source_code_uri: https://github.com/spree/spree/tree/v5.4.3
1181
1170
  post_install_message:
1182
1171
  rdoc_options: []
1183
1172
  require_paths: