Skip to content

Commit

Permalink
Extract product status component
Browse files Browse the repository at this point in the history
We'll need the same logic in the product forms, so we need to extract it
to a component.

Ref. #5329
  • Loading branch information
waiting-for-dev authored and elia committed Sep 29, 2023
1 parent 636dd04 commit 4161e2e
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 13 deletions.
13 changes: 3 additions & 10 deletions admin/app/components/solidus_admin/products/index/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
@@ -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'
Expand Down
32 changes: 32 additions & 0 deletions admin/app/components/solidus_admin/products/status/component.rb
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
en:
available: 'Available'
discontinued: 'Discontinued'
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<table>
<thead>
<tr>
<% definitions.each_key do |status| %>
<th class="px-3 py-1 text-gray-500 text-center"><%= status.to_s.humanize %></th>
<% end %>
</tr>
</thead>
<tbody>
<tr>
<% definitions.each_value do |component| %>
<th class="px-3 py-1"><%= render component %></th>
<% end %>
</tr>
</tbody>
</table>
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 4161e2e

Please sign in to comment.