Skip to content

Commit 13e4fae

Browse files
authored
Merge pull request #6270 from chaimann/admin-product-form-improvements
[Admin] Product form improvements
2 parents 0106345 + b4b15bb commit 13e4fae

File tree

5 files changed

+86
-35
lines changed

5 files changed

+86
-35
lines changed

admin/app/components/solidus_admin/products/show/component.html.erb

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@
2626
<%= form_for @product, url: solidus_admin.product_path(@product), html: { id: form_id } do |f| %>
2727
<%= page_with_sidebar do %>
2828
<%= page_with_sidebar_main do %>
29-
<%= render component('ui/panel').new do %>
29+
<%= render component("ui/panel").new do %>
3030
<%= render component("ui/forms/field").text_field(f, :name) %>
3131
<%= render component("ui/forms/field").text_field(f, :slug) %>
3232
<%= render component("ui/forms/field").text_area(f, :description) %>
3333
<% end %>
3434

35-
<%= render component('ui/panel').new(title: 'SEO') do %>
35+
<%= render component("ui/panel").new(title: t(".seo")) do %>
3636
<%= render component("ui/forms/field").text_field(f, :meta_title) %>
3737
<%= render component("ui/forms/field").text_field(f, :meta_description) %>
3838
<%= render component("ui/forms/field").text_area(f, :meta_keywords) %>
@@ -41,25 +41,25 @@
4141
f,
4242
:condition,
4343
condition_options,
44-
include_blank: t('spree.unset'),
44+
include_blank: t("spree.unset"),
4545
) %>
4646
<% end %>
47-
<%= render component('ui/panel').new(title: "Media") do |panel| %>
47+
<%= render component("ui/panel").new(title: t(".media")) do |panel| %>
4848
<% panel.with_action(
4949
name: t(".manage_images"),
5050
href: spree.admin_product_images_path(@product)
5151
) %>
5252
<% end %>
5353

54-
<%= render component('ui/panel').new(title: 'Pricing') do %>
54+
<%= render component("ui/panel").new(title: t(".pricing")) do %>
5555
<%= render component("ui/forms/field").text_field(f, :price) %>
5656
<div class="flex gap-4 justify-items-stretch">
5757
<%= render component("ui/forms/field").text_field(f, :cost_price) %>
5858
<%= render component("ui/forms/field").text_field(f, :cost_currency) %>
5959
</div>
6060
<% end %>
6161

62-
<%= render component('ui/panel').new(title: 'Stock') do |panel| %>
62+
<%= render component("ui/panel").new(title: t(".stock")) do |panel| %>
6363
<%= render component("ui/forms/field").text_field(f, :sku) %>
6464

6565
<% panel.with_action(
@@ -68,25 +68,22 @@
6868
) %>
6969
<% end %>
7070

71-
<%= render component('ui/panel').new(title: 'Shipping') do %>
71+
<%= render component("ui/panel").new(title: t(".shipping")) do %>
7272
<%= render component("ui/forms/field").select(
7373
f,
7474
:shipping_category_id,
7575
[[t(".none"), nil]] + Spree::ShippingCategory.order(:name).pluck(:name, :id),
76-
tip: t(".hints.shipping_category_html"),
76+
tip: t(".hints.shipping_category_html")
7777
) %>
7878
<%= render component("ui/forms/field").select(
7979
f,
8080
:tax_category_id,
8181
[[t(".none"), nil]] + Spree::TaxCategory.order(:name).pluck(:name, :id),
82-
tip: t(
83-
".hints.tax_category_html",
84-
default_tax_category: Spree::TaxCategory.default&.name
85-
),
82+
tip: t(".hints.tax_category_html")
8683
) %>
8784
<% end %>
8885

89-
<%= render component('ui/panel').new(title: "Options") do %>
86+
<%= render component("ui/panel").new(title: t(".options")) do %>
9087
<%= render component("ui/forms/field").select(
9188
f,
9289
:option_type_ids,
@@ -96,7 +93,7 @@
9693
) %>
9794
<% end %>
9895

99-
<%= render component('ui/panel').new(title: "Specifications") do |panel| %>
96+
<%= render component("ui/panel").new(title: t(".specifications")) do |panel| %>
10097
<% panel.with_action(
10198
name: t(".manage_properties"),
10299
href: spree.admin_product_product_properties_path(@product)
@@ -105,18 +102,18 @@
105102
<% end %>
106103

107104
<%= page_with_sidebar_aside do %>
108-
<%= render component('ui/panel').new(title: "Publishing") do %>
105+
<%= render component("ui/panel").new(title: t(".publishing")) do %>
109106
<%= render component("ui/forms/field").text_field(
110107
f,
111108
:available_on,
112-
hint: t(".available_on_html"),
109+
hint: t(".hints.available_on_html"),
113110
type: :date,
114111
value: f.object.available_on&.to_date
115112
) %>
116113
<%= render component("ui/forms/field").text_field(
117114
f,
118115
:discontinue_on,
119-
hint: t(".discontinue_on_html"),
116+
hint: t(".hints.discontinue_on_html"),
120117
type: :date,
121118
value: f.object.discontinue_on&.to_date
122119
) %>
@@ -130,7 +127,7 @@
130127
</label>
131128
<% end %>
132129

133-
<%= render component('ui/panel').new(title: "Product organization") do %>
130+
<%= render component("ui/panel").new(title: t(".product_organization")) do %>
134131
<%= render component("ui/forms/field").select(
135132
f,
136133
:taxon_ids,

admin/app/components/solidus_admin/products/show/component.yml

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,23 @@ en:
44
duplicate: "Duplicate"
55
view: "View online"
66
delete: "Delete"
7-
none: "None"
7+
delete_confirmation: "Are you sure you want to delete this product?"
88
manage_images: "Manage images"
99
manage_properties: "Manage product specifications"
1010
manage_stock: "Manage stock"
11-
delete_confirmation: "Are you sure you want to delete this product?"
12-
available_on_html: 'Product availability starts from the set date.<br> Empty date indicates no availability.'
13-
discontinue_on_html: 'Product availability ends from the set date.<br> Empty date indicates continuous availability.'
11+
media: "Media"
12+
none: "None"
13+
options: "Options"
14+
pricing: "Pricing"
15+
product_organization: "Product organization"
16+
publishing: "Publishing"
17+
seo: "SEO"
18+
stock: "Stock"
19+
shipping: "Shipping"
20+
specifications: "Specifications"
1421
hints:
15-
promotionable_html: Promotions can apply to this product
16-
shipping_category_html: Manage Shipping in Settings
17-
tax_category_html: Manage Taxes in Settings
22+
available_on_html: "Product availability starts from the set date.<br> Empty date indicates no availability."
23+
discontinue_on_html: "Product availability ends from the set date.<br> Empty date indicates continuous availability."
24+
promotionable_html: "Promotions can apply to this product"
25+
shipping_category_html: "Manage Shipping in Settings"
26+
tax_category_html: "Manage Taxes in Settings"

admin/app/components/solidus_admin/ui/panel/component.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def initialize(title: nil, title_hint: nil)
3232
def render_section(wide: false, high: false, **args, &block)
3333
tag.section(**args, class: "
3434
border-gray-100 border-t w-full first-of-type:border-t-0
35+
flex flex-col gap-6
3536
#{'px-6' unless wide}
3637
#{'py-4' unless high}
3738
#{args[:class]}

admin/app/controllers/solidus_admin/products_controller.rb

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ class ProductsController < SolidusAdmin::BaseController
1111
search_scope(:in_stock) { _1.where(id: Spree::Variant.in_stock.distinct.select(:product_id)) }
1212
search_scope(:out_of_stock) { _1.where.not(id: Spree::Variant.in_stock.distinct.select(:product_id)) }
1313

14-
before_action :split_params, only: [:update]
15-
1614
def index
1715
products = apply_search_to(
1816
Spree::Product.includes(:master, :variants),
@@ -44,7 +42,7 @@ def show
4442
def update
4543
@product = Spree::Product.friendly.find(params[:id])
4644

47-
if @product.update(params.require(:product).permit!)
45+
if @product.update(product_params)
4846
flash[:success] = t('spree.successfully_updated', resource: [
4947
Spree::Product.model_name.human,
5048
@product.name.inspect,
@@ -101,13 +99,12 @@ def activate
10199
redirect_to products_path, status: :see_other
102100
end
103101

104-
def split_params
105-
if params[:product][:taxon_ids].present?
106-
params[:product][:taxon_ids] = params[:product][:taxon_ids].split(',')
107-
end
108-
if params[:product][:option_type_ids].present?
109-
params[:product][:option_type_ids] = params[:product][:option_type_ids].split(',')
110-
end
102+
private
103+
104+
def product_params
105+
params.require(:product).permit(:name, :slug, :description, :meta_title, :meta_description, :meta_keywords, :gtin,
106+
:condition, :price, :cost_price, :cost_currency, :sku, :shipping_category_id, :tax_category_id,
107+
:available_on, :discontinue_on, :promotionable, option_type_ids: [], taxon_ids: [])
111108
end
112109
end
113110
end
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# frozen_string_literal: true
2+
3+
require "spec_helper"
4+
5+
RSpec.describe "SolidusAdmin::PropertiesController", type: :request do
6+
let(:admin_user) { create(:admin_user) }
7+
8+
before do
9+
allow_any_instance_of(SolidusAdmin::BaseController).to receive(:spree_current_user).and_return(admin_user)
10+
end
11+
12+
describe "PATCH #update" do
13+
let(:product) { create(:product) }
14+
let(:params) do
15+
{
16+
name: "T-Shirt",
17+
description: "Nice T-Shirt",
18+
slug: "nice-t-shirt",
19+
meta_title: "Nice T-Shirt",
20+
meta_description: "It is a really nice T-Shirt",
21+
meta_keywords: "tshirt, tee",
22+
gtin: "12345",
23+
condition: "new",
24+
price: 100,
25+
cost_price: 100,
26+
cost_currency: "USD",
27+
sku: "T123",
28+
shipping_category_id: create(:shipping_category).id,
29+
tax_category_id: create(:tax_category).id,
30+
available_on: "2025-05-28".to_date,
31+
discontinue_on: "2026-01-06".to_date,
32+
promotionable: true,
33+
option_type_ids: [create(:option_type).id, create(:option_type).id],
34+
taxon_ids: [create(:taxon).id, create(:taxon).id],
35+
}
36+
end
37+
38+
it "updates product" do
39+
patch solidus_admin.product_path(product), params: { product: params }
40+
expect(response).to have_http_status(:see_other)
41+
expect(product.reload).to have_attributes(params.except(Spree::Product::MASTER_ATTRIBUTES))
42+
%i[gtin condition price cost_price cost_currency sku].each do |attr|
43+
expect(product.public_send(attr)).to eq(params[attr])
44+
end
45+
end
46+
end
47+
end

0 commit comments

Comments
 (0)