From 4161e2e1ac97c654b5d5c7536f65ac9d7d0587a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Busqu=C3=A9?= Date: Mon, 21 Aug 2023 12:18:05 +0200 Subject: [PATCH] Extract product status component We'll need the same logic in the product forms, so we need to extract it to a component. Ref. #5329 --- .../solidus_admin/products/index/component.rb | 13 ++------ .../products/index/component.yml | 3 -- .../products/status/component.rb | 32 +++++++++++++++++++ .../products/status/component.yml | 3 ++ .../products/status/component_preview.rb | 30 +++++++++++++++++ .../component_preview/overview.html.erb | 16 ++++++++++ .../products/status/component_spec.rb | 27 ++++++++++++++++ 7 files changed, 111 insertions(+), 13 deletions(-) create mode 100644 admin/app/components/solidus_admin/products/status/component.rb create mode 100644 admin/app/components/solidus_admin/products/status/component.yml create mode 100644 admin/spec/components/previews/solidus_admin/products/status/component_preview.rb create mode 100644 admin/spec/components/previews/solidus_admin/products/status/component_preview/overview.html.erb create mode 100644 admin/spec/components/solidus_admin/products/status/component_spec.rb diff --git a/admin/app/components/solidus_admin/products/index/component.rb b/admin/app/components/solidus_admin/products/index/component.rb index a8c472aa3af..fe0b9fa281c 100644 --- a/admin/app/components/solidus_admin/products/index/component.rb +++ b/admin/app/components/solidus_admin/products/index/component.rb @@ -3,14 +3,13 @@ class SolidusAdmin::Products::Index::Component < SolidusAdmin::BaseComponent def initialize( page:, - badge_component: component('ui/badge'), + status_component: component('products/status'), table_component: component('ui/table'), pagination_component: component('ui/table/pagination'), button_component: component("ui/button") ) @page = page - - @badge_component = badge_component + @status_component = status_component @table_component = table_component @button_component = button_component @pagination_component = pagination_component @@ -100,13 +99,7 @@ def name_column def status_column { header: :status, - data: ->(product) do - if product.available? - @badge_component.new(name: t('.status.available'), color: :green) - else - @badge_component.new(name: t('.status.discontinued'), color: :red) - end - end + data: ->(product) { @status_component.new(product: product) } } end diff --git a/admin/app/components/solidus_admin/products/index/component.yml b/admin/app/components/solidus_admin/products/index/component.yml index b347ff0d31f..bf8f0359fcf 100644 --- a/admin/app/components/solidus_admin/products/index/component.yml +++ b/admin/app/components/solidus_admin/products/index/component.yml @@ -1,9 +1,6 @@ en: product_image: 'Image' add_product: 'Add Product' - status: - available: 'Available' - discontinued: 'Discontinued' stock: infinity: '∞' in_stock: '%{on_hand} in stock' diff --git a/admin/app/components/solidus_admin/products/status/component.rb b/admin/app/components/solidus_admin/products/status/component.rb new file mode 100644 index 00000000000..d21e844f011 --- /dev/null +++ b/admin/app/components/solidus_admin/products/status/component.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +class SolidusAdmin::Products::Status::Component < SolidusAdmin::BaseComponent + COLORS = { + available: :green, + discontinued: :red + }.freeze + + # @param product [Spree::Product] + def initialize(product:, badge_component: component('ui/badge')) + @product = product + @badge_component = badge_component + end + + def call + render @badge_component.new( + name: t(".#{status}"), + color: COLORS.fetch(status) + ) + end + + # @return [Symbol] + # :available when the product is available + # :discontinued when the product is not available + def status + if @product.available? + :available + else + :discontinued + end + end +end diff --git a/admin/app/components/solidus_admin/products/status/component.yml b/admin/app/components/solidus_admin/products/status/component.yml new file mode 100644 index 00000000000..c0f10400804 --- /dev/null +++ b/admin/app/components/solidus_admin/products/status/component.yml @@ -0,0 +1,3 @@ +en: + available: 'Available' + discontinued: 'Discontinued' diff --git a/admin/spec/components/previews/solidus_admin/products/status/component_preview.rb b/admin/spec/components/previews/solidus_admin/products/status/component_preview.rb new file mode 100644 index 00000000000..0d60429a087 --- /dev/null +++ b/admin/spec/components/previews/solidus_admin/products/status/component_preview.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +# @component "products/status" +class SolidusAdmin::Products::Status::ComponentPreview < ViewComponent::Preview + include SolidusAdmin::Preview + + def overview + render_with_template(locals: + { + definitions: { + available: available_component, + discontinued: discontinued_component + } + }) + end + + private + + def available_component + current_component.new( + product: Spree::Product.new(available_on: Time.current) + ) + end + + def discontinued_component + current_component.new( + product: Spree::Product.new(available_on: nil) + ) + end +end diff --git a/admin/spec/components/previews/solidus_admin/products/status/component_preview/overview.html.erb b/admin/spec/components/previews/solidus_admin/products/status/component_preview/overview.html.erb new file mode 100644 index 00000000000..ee9120ee41e --- /dev/null +++ b/admin/spec/components/previews/solidus_admin/products/status/component_preview/overview.html.erb @@ -0,0 +1,16 @@ + + + + <% definitions.each_key do |status| %> + + <% end %> + + + + + <% definitions.each_value do |component| %> + + <% end %> + + +
<%= status.to_s.humanize %>
<%= render component %>
diff --git a/admin/spec/components/solidus_admin/products/status/component_spec.rb b/admin/spec/components/solidus_admin/products/status/component_spec.rb new file mode 100644 index 00000000000..b0cf11c8929 --- /dev/null +++ b/admin/spec/components/solidus_admin/products/status/component_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe SolidusAdmin::Products::Status::Component, type: :component do + it "renders the overview preview" do + render_preview(:overview) + end + + describe "#status" do + it "returns :available when the product is available" do + product = Spree::Product.new(available_on: Time.current) + + component = described_class.new(product: product) + + expect(component.status).to eq(:available) + end + + it "returns :discontinued when the product is not available" do + product = Spree::Product.new(available_on: nil) + + component = described_class.new(product: product) + + expect(component.status).to eq(:discontinued) + end + end +end