diff --git a/app/controllers/admin/products_v3_controller.rb b/app/controllers/admin/products_v3_controller.rb index 667706aeba..168fa001d0 100644 --- a/app/controllers/admin/products_v3_controller.rb +++ b/app/controllers/admin/products_v3_controller.rb @@ -7,7 +7,7 @@ module Admin def index fetch_products - render "index", locals: { producers:, categories:, flash: } + render "index", locals: { producers:, categories:, tax_category_options:, flash: } end def bulk_update @@ -59,6 +59,10 @@ module Admin Spree::Taxon.order(:name).map { |c| [c.name, c.id] } end + def tax_category_options + Spree::TaxCategory.order(:name).pluck(:name, :id) + end + def fetch_products product_query = OpenFoodNetwork::Permissions.new(spree_current_user) .editable_products.merge(product_scope).ransack(ransack_query).result diff --git a/app/views/admin/products_v3/_content.html.haml b/app/views/admin/products_v3/_content.html.haml index 1b50fa3f10..0a9459abae 100644 --- a/app/views/admin/products_v3/_content.html.haml +++ b/app/views/admin/products_v3/_content.html.haml @@ -15,7 +15,7 @@ .container.results .sixteen.columns = render partial: 'sort', locals: { pagy: pagy, search_term: search_term, producer_id: producer_id, category_id: category_id } - = render partial: 'table', locals: { products:, producer_options:, category_options: } + = render partial: 'table', locals: { products:, producer_options:, category_options:, tax_category_options: } - if pagy.present? && pagy.pages > 1 = render partial: 'admin/shared/stimulus_pagination', locals: { pagy: pagy } - else diff --git a/app/views/admin/products_v3/_table.html.haml b/app/views/admin/products_v3/_table.html.haml index b95c9f5187..4c0538e43c 100644 --- a/app/views/admin/products_v3/_table.html.haml +++ b/app/views/admin/products_v3/_table.html.haml @@ -72,12 +72,12 @@ - product.variants.each_with_index do |variant, variant_index| = form.fields_for("products][#{product_index}][variants_attributes][", variant, index: variant_index) do |variant_form| %tr.condensed{ 'data-controller': "variant" } - = render partial: 'variant_row', locals: { variant:, f: variant_form, producer_options:, category_options: } + = render partial: 'variant_row', locals: { variant:, f: variant_form, producer_options:, category_options:, tax_category_options: } = form.fields_for("products][#{product_index}][variants_attributes][NEW_RECORD", product.variants.build) do |new_variant_form| %template{ 'data-nested-form-target': "template" } %tr.condensed{ 'data-controller': "variant" } - = render partial: 'variant_row', locals: { variant: new_variant_form.object, f: new_variant_form, producer_options:, category_options: } + = render partial: 'variant_row', locals: { variant: new_variant_form.object, f: new_variant_form, producer_options:, category_options:, tax_category_options: } %tr{ 'data-nested-form-target': "target" } %tr.condensed diff --git a/app/views/admin/products_v3/_variant_row.html.haml b/app/views/admin/products_v3/_variant_row.html.haml index 9e19c693ed..2a243025ee 100644 --- a/app/views/admin/products_v3/_variant_row.html.haml +++ b/app/views/admin/products_v3/_variant_row.html.haml @@ -42,11 +42,12 @@ - if producer_options.many? %td.align-left -# empty producer name -%td.align-left +%td.field.naked_inputs = f.select :primary_taxon_id, options_for_select(category_options, variant.primary_taxon_id), {}, data: { "controller": "tom-select", 'tom-select-placeholder-value': t('admin.products_v3.filters.search_for_categories')} -%td.align-left - .content= (variant.tax_category_id ? variant.tax_category&.name : t('.none_tax_category')) # TODO: convert to dropdown +%td.field.naked_inputs + = f.select :tax_category_id, options_for_select(tax_category_options, variant.tax_category_id), {include_blank: t('.none_tax_category')}, + data: { "controller": "tom-select", 'tom-select-placeholder-value': t('.search_for_tax_categories')} %td.align-left -# empty %td.align-right diff --git a/app/views/admin/products_v3/index.html.haml b/app/views/admin/products_v3/index.html.haml index 4200cd0176..5087feddc2 100644 --- a/app/views/admin/products_v3/index.html.haml +++ b/app/views/admin/products_v3/index.html.haml @@ -15,7 +15,7 @@ = render partial: "content", locals: { products: @products, pagy: @pagy, search_term: @search_term, producer_options: producers, producer_id: @producer_id, category_options: categories, category_id: @category_id, - flashes: flash } + tax_category_options:, flashes: flash } - %w[product variant].each do |object_type| = render partial: 'delete_modal', locals: { object_type: } #modal-component diff --git a/app/webpacker/controllers/bulk_form_controller.js b/app/webpacker/controllers/bulk_form_controller.js index 602f7c0127..54a8a812df 100644 --- a/app/webpacker/controllers/bulk_form_controller.js +++ b/app/webpacker/controllers/bulk_form_controller.js @@ -135,10 +135,17 @@ export default class BulkFormController extends Controller { if (element.type == "checkbox") { return element.defaultChecked !== undefined && element.checked != element.defaultChecked; } else if (element.type == "select-one") { + // (weird) Behavior of select element's include_blank option in Rails: + // If a select field has include_blank option selected (its value will be ''), + // its respective option doesn't have the selected attribute + // but selectedOptions have that option present const defaultSelected = Array.from(element.options).find((opt) => opt.hasAttribute("selected"), ); - return element.selectedOptions[0] != defaultSelected; + const selectedOption = element.selectedOptions[0]; + const areBothBlank = selectedOption.value === '' && defaultSelected === undefined + + return !areBothBlank && selectedOption !== defaultSelected; } else { return element.defaultValue !== undefined && element.value != element.defaultValue; } diff --git a/config/locales/en.yml b/config/locales/en.yml index 1fe516fee8..f17baa2601 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -910,6 +910,7 @@ en: error: Unable to delete the variant variant_row: none_tax_category: None + search_for_tax_categories: "Search for tax categories" product_import: title: Product Import file_not_found: File not found or could not be opened