Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,44 @@
) %>
<% end %>

<%= render component("ui/panel").new(title: t(".options")) do %>
<%= f.select(:option_type_ids, option_type_options, multiple: true) %>
<%= render component("ui/panel").new(title: t(".options")) do |panel| %>
<% if @product.product_option_types.present? %>
<% panel.with_section do %>
<div class="flex flex-col gap-4" data-controller="sortable" data-sortable-handle-value=".handle">
<% @product.product_option_types.includes(option_type: :option_values).order(:position).each do |product_option| %>
<div class="flex gap-2 justify-between" data-sortable-url=<%= solidus_admin.move_product_option_type_path(product_option) %>>
<div class="flex gap-2">
<div class="flex items-center">
<%= render component("ui/icon").new(name: "draggable", class: "w-6 h-6 cursor-grab handle fill-gray-500") %>
</div>
<div class="flex flex-col gap-2">
<span class="font-semibold text-sm"><%= product_option.option_type.name %>:<%= product_option.option_type.presentation %></span>
<div class="flex gap-2 flex-wrap">
<% product_option.option_type.option_values.each do |value| %>
<%= render component("ui/badge").new(name: "#{value.name}:#{value.presentation}") %>
<% end %>
</div>
</div>
</div>
<div class="flex items-center">
<%= render component("ui/button").new(tag: :a, href: spree.edit_admin_option_type_path(product_option.option_type), scheme: :secondary, text: t(".edit")) %>
</div>
</div>
<% end %>
</div>
<% end %>
<% end %>

<div class="flex gap-4 justify-between items-end">
<%= hidden_field_tag "#{f.object_name}[option_type_ids][]", nil %>
<%= f.select(:option_type_ids, option_type_options, multiple: true) %>
<%= render component("ui/button").new(type: :submit, text: t(".save")) %>
</div>

<% panel.with_action(
name: t(".manage_options"),
href: solidus_admin.option_types_path
) %>
<% end %>

<%= render component("ui/panel").new(title: t(".specifications")) do |panel| %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def taxon_options

def option_type_options
@option_type_options ||= Spree::OptionType.order(:presentation).pluck(:presentation, :name, :id).map do
["#{_1} (#{_2})", _3]
["#{_2}:#{_1}", _3]
end
end

Expand Down
20 changes: 12 additions & 8 deletions admin/app/components/solidus_admin/products/show/component.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
en:
duplicate: "Duplicate"
view: "View online"
back: "Back"
delete: "Delete"
delete_confirmation: "Are you sure you want to delete this product?"
duplicate: "Duplicate"
edit: "Edit"
hints:
available_on_html: "Product availability starts from the set date.<br> Empty date indicates no availability."
discontinue_on_html: "Product availability ends from the set date.<br> Empty date indicates continuous availability."
promotionable_html: "Promotions can apply to this product"
shipping_category_html: "Manage Shipping in Settings"
tax_category_html: "Manage Taxes in Settings"
manage_images: "Manage images"
manage_options: "Manage option types"
manage_properties: "Manage product specifications"
manage_stock: "Manage stock"
media: "Media"
Expand All @@ -12,13 +20,9 @@ en:
pricing: "Pricing"
product_organization: "Product organization"
publishing: "Publishing"
save: "Save"
seo: "SEO"
stock: "Stock"
shipping: "Shipping"
specifications: "Specifications"
hints:
available_on_html: "Product availability starts from the set date.<br> Empty date indicates no availability."
discontinue_on_html: "Product availability ends from the set date.<br> Empty date indicates continuous availability."
promotionable_html: "Promotions can apply to this product"
shipping_category_html: "Manage Shipping in Settings"
tax_category_html: "Manage Taxes in Settings"
view: "View online"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

class SolidusAdmin::ProductOptionTypesController < SolidusAdmin::BaseController
include SolidusAdmin::Moveable
end
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,7 @@ def update
@product = Spree::Product.friendly.find(params[:id])

if @product.update(product_params)
flash[:notice] = t('spree.successfully_updated', resource: [
Spree::Product.model_name.human,
@product.name.inspect,
].join(' '))

flash[:success] = t('.success')
redirect_to action: :show, status: :see_other
else
flash.now[:error] = @product.errors.full_messages.join(", ")
Expand Down
2 changes: 2 additions & 0 deletions admin/config/locales/products.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ en:
success: "Products were successfully discontinued."
activate:
success: "Products were successfully activated."
update:
success: "Product was successfully updated."
1 change: 1 addition & 0 deletions admin/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,5 @@
admin_resources :roles, except: [:show]
admin_resources :adjustment_reasons, except: [:show]
admin_resources :store_credit_reasons, except: [:show]
admin_resources :product_option_types, only: [], sortable: true
end
12 changes: 12 additions & 0 deletions admin/lib/solidus_admin/testing_support/feature_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ def select_row(text)
end
end

def panel(title:)
find("section", text: title).find(:xpath, "..")
end

# Select options from a "solidus-select" field
#
# @param value [String, Array<String>] which option(s) to select
Expand All @@ -52,6 +56,14 @@ def solidus_select(value, from:)
end
end

def solidus_unselect(value, from:)
input = find_field(from, visible: :all)
Array.wrap(value).each do |val|
item = input.sibling("div", text: val)
item.find("a").click
end
end

def checkbox(locator)
find(:checkbox, locator)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
RSpec.shared_examples_for "features: sortable" do
let(:factory_attrs) { {} }
let(:scope) { "body" }
let(:handle) { nil }

before do
create(factory, displayed_attribute => "First", position: 1, **factory_attrs)
Expand All @@ -35,7 +36,10 @@
expect(find("[data-controller='sortable']").all(:xpath, "./*").last).to have_text("Second")

rows = find("[data-controller='sortable']").all(:xpath, "./*")
rows[1].drag_to rows[0]
target = rows[0]
source = rows[1]
source = source.find(handle) if handle
source.drag_to target

expect(find("[data-controller='sortable']").all(:xpath, "./*").first).to have_text("Second")
expect(find("[data-controller='sortable']").all(:xpath, "./*").last).to have_text("First")
Expand Down
78 changes: 78 additions & 0 deletions admin/spec/features/product_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require 'spec_helper'
require "solidus_admin/testing_support/shared_examples/moveable"

describe "Product", type: :feature do
before do
Expand Down Expand Up @@ -52,4 +53,81 @@
expect(page).to have_content("Name can't be blank")
expect(page).to be_axe_clean
end

describe "option types", :js do
before do
create(:option_type, name: "clothing-size", presentation: "Size").tap do |option_type|
option_type.option_values << [
create(:option_value, name: "S", presentation: "Small"),
create(:option_value, name: "M", presentation: "Medium")
]
end

create(:option_type, name: "clothing-color", presentation: "Color").tap do |option_type|
option_type.option_values << [
create(:option_value, name: "brown", presentation: "Brown"),
create(:option_value, name: "red", presentation: "Red")
]
end
end

let!(:product) { create(:product, name: "Just a product", slug: 'just-a-prod', price: 19.99) }

it "updates option types" do
visit "/admin/products/just-a-prod"
solidus_select(%w[clothing-size:Size clothing-color:Color], from: "Option Types")
options_panel = panel(title: "Options")
# for some reason capybara on circle ci does not register a form submit when clicking "Save" within options panel,
# so we have to resort to Save button in the header
within("header") { click_on "Save" }

expect(options_panel).to have_content("clothing-size:Size")
expect(options_panel).to have_content("S:Small")
expect(options_panel).to have_content("M:Medium")
expect(options_panel).to have_content("clothing-color:Color")
expect(options_panel).to have_content("brown:Brown")
expect(options_panel).to have_content("red:Red")

solidus_unselect(%w[clothing-size:Size clothing-color:Color], from: "Option Types")
within(options_panel) { click_on "Save" }

expect(options_panel).not_to have_content("clothing-size:Size")
expect(options_panel).not_to have_content("S:Small")
expect(options_panel).not_to have_content("M:Medium")
expect(options_panel).not_to have_content("clothing-color:Color")
expect(options_panel).not_to have_content("brown:Brown")
expect(options_panel).not_to have_content("red:Red")
end

context "clicking on Edit" do
# skipping test until updated option types UI is merged
# https://github.com/solidusio/solidus/pull/6236
xit "leads to option type edit page" do

Check warning on line 105 in admin/spec/features/product_spec.rb

View workflow job for this annotation

GitHub Actions / solidus_admin / Rails 7.2, Ruby 3.3, postgres, activestorage

Product option types clicking on Edit leads to option type edit page Skipped: Temporarily skipped with xit

Check warning on line 105 in admin/spec/features/product_spec.rb

View workflow job for this annotation

GitHub Actions / solidus_admin / Rails 7.1, Ruby 3.2, mysql, activestorage

Product option types clicking on Edit leads to option type edit page Skipped: Temporarily skipped with xit

Check warning on line 105 in admin/spec/features/product_spec.rb

View workflow job for this annotation

GitHub Actions / solidus_admin / Rails 7.0, Ruby 3.1, postgres, paperclip

Product option types clicking on Edit leads to option type edit page Skipped: Temporarily skipped with xit

Check warning on line 105 in admin/spec/features/product_spec.rb

View workflow job for this annotation

GitHub Actions / solidus_admin / Rails 8.0, Ruby 3.4, sqlite, activestorage

Product option types clicking on Edit leads to option type edit page Skipped: Temporarily skipped with xit
option_type = create(:option_type)
product.option_types << option_type
visit "/admin/products/just-a-prod"

within(panel(title: "Options")) { click_on "Edit" }
expect(page).to have_current_path("/admin/option_types/#{option_type.id}/edit")
end
end

context "clicking on Manage option types" do
it "leads to option types index page" do
visit "/admin/products/just-a-prod"

within(panel(title: "Options")) { click_on "Manage option types" }
expect(page).to have_current_path("/admin/option_types")
end
end

it_behaves_like "features: sortable" do
let(:product) { create(:product) }
let(:factory) { :option_type }
let(:factory_attrs) { { products: [product] } }
let(:displayed_attribute) { :name }
let(:handle) { ".handle" }
let(:path) { solidus_admin.product_path(product) }
end
end
end
11 changes: 11 additions & 0 deletions admin/spec/requests/solidus_admin/product_option_types_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

require "spec_helper"
require "solidus_admin/testing_support/shared_examples/moveable"

RSpec.describe "SolidusAdmin::ProductOptionTypesController", type: :request do
it_behaves_like "requests: moveable" do
let(:factory) { :product_option_type }
let(:request_path) { solidus_admin.move_product_option_type_path(record, format: :js) }
end
end
2 changes: 1 addition & 1 deletion admin/spec/requests/solidus_admin/products_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

require "spec_helper"

RSpec.describe "SolidusAdmin::PropertiesController", type: :request do
RSpec.describe "SolidusAdmin::ProductsController", type: :request do
let(:admin_user) { create(:admin_user) }

before do
Expand Down
1 change: 1 addition & 0 deletions core/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ en:
meta_title: Meta Title
name: Name
on_hand: On Hand
option_type_ids: Option Types
price: Master Price
primary_taxon: Primary Taxon
primary_taxon_id: Primary Taxon
Expand Down
Loading