Skip to content

Commit

Permalink
Merge pull request #5433 from solidusio/elia/admin/product-components
Browse files Browse the repository at this point in the history
Extract a `products/stock` component
  • Loading branch information
elia authored Oct 13, 2023
2 parents 3c74c9a + 595b072 commit 0e4424c
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 80 deletions.
19 changes: 2 additions & 17 deletions admin/app/components/solidus_admin/products/index/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,29 +96,14 @@ def name_column
def status_column
{
header: :status,
data: ->(product) { component('products/status').new(product: product) }
data: ->(product) { component('products/status').from_product(product) }
}
end

def stock_column
{
header: :stock,
data: ->(product) do
stock_info =
case (on_hand = product.total_on_hand)
when Float::INFINITY
content_tag :span, t('.stock.in_stock', on_hand: t('.stock.infinity')), class: 'text-forest'
when 1..Float::INFINITY
content_tag :span, t('.stock.in_stock', on_hand: on_hand), class: 'text-forest'
else
content_tag :span, t('.stock.in_stock', on_hand: on_hand), class: 'text-red-500'
end

variant_info =
t('.for_variants', count: product.variants.count)

content_tag :div, safe_join([stock_info, variant_info], ' ')
end
data: ->(product) { component('products/stock').from_product(product) }
}
end

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
en:
product_image: 'Image'
add_product: 'Add Product'
stock:
infinity: ''
in_stock: '%{on_hand} in stock'
for_variants: 'for %{count} variants'
batch_actions:
delete: 'Delete'
discontinue: 'Discontinue'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
) %>
<h1 class="flex items-center gap-2">
<span class="body-title"><%= @product.name %></span>
<%= render component("products/status").new(product: @product) %>
<%= render component("products/status").from_product(@product) %>
</h1>

<div class="ml-auto flex gap-2 items-center">
Expand Down
26 changes: 9 additions & 17 deletions admin/app/components/solidus_admin/products/status/component.rb
Original file line number Diff line number Diff line change
@@ -1,31 +1,23 @@
# frozen_string_literal: true

class SolidusAdmin::Products::Status::Component < SolidusAdmin::BaseComponent
COLORS = {
STATUSES = {
available: :green,
discontinued: :red
}.freeze

# @param product [Spree::Product]
def initialize(product:)
@product = product
def self.from_product(product)
new(status: product.available? ? :available : :discontinued)
end

def initialize(status:)
@status = status
end

def call
render component('ui/badge').new(
name: t(".#{status}"),
color: COLORS.fetch(status)
name: t(".#{@status}"),
color: STATUSES.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
31 changes: 31 additions & 0 deletions admin/app/components/solidus_admin/products/stock/component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

class SolidusAdmin::Products::Stock::Component < SolidusAdmin::BaseComponent
def self.from_product(product)
new(
on_hand: product.total_on_hand,
variants_count: product.variants.count,
)
end

def initialize(on_hand:, variants_count:)
@on_hand = on_hand
@variants_count = variants_count
end

def call
stock_info =
case @on_hand
when Float::INFINITY
tag.span t('.stock.in_stock', on_hand: t('.stock.infinity')), class: 'text-forest'
when 1..Float::INFINITY
tag.span t('.stock.in_stock', on_hand: @on_hand), class: 'text-forest'
else
tag.span t('.stock.in_stock', on_hand: @on_hand), class: 'text-red-500'
end

variant_info = t('.for_variants', count: @variants_count)

tag.div safe_join([stock_info, variant_info], ' ')
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
en:
stock:
infinity: ''
in_stock: '%{on_hand} in stock'
for_variants: 'for %{count} variants'
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,6 @@ 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)
)
render_with_template
end
end
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
<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>
<div class="mb-8">
<h6 class="text-gray-500 mb-3 mt-0">
Available
</h6>

<%= render current_component.new(status: :available) %>
</div>

<div class="mb-8">
<h6 class="text-gray-500 mb-3 mt-0">
Discontinued
</h6>

<%= render current_component.new(status: :discontinued) %>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

# @component "products/stock"
class SolidusAdmin::Products::Stock::ComponentPreview < ViewComponent::Preview
include SolidusAdmin::Preview

def overview
render_with_template
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<div class="mb-8">
<h6 class="text-gray-500 mb-3 mt-0">
In Stock
</h6>

<%= render current_component.new(on_hand: 32, variants_count: 12) %>
</div>

<div class="mb-8">
<h6 class="text-gray-500 mb-3 mt-0">
Infinite stock
</h6>

<%= render current_component.new(on_hand: Float::INFINITY, variants_count: 12) %>
</div>

<div class="mb-8">
<h6 class="text-gray-500 mb-3 mt-0">
Out of stock
</h6>

<%= render current_component.new(on_hand: 0, variants_count: 12) %>
</div>

<div class="mb-8">
<h6 class="text-gray-500 mb-3 mt-0">
Negative stock
</h6>

<%= render current_component.new(on_hand: -10, variants_count: 12) %>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@
it "returns :available when the product is available" do
product = Spree::Product.new(available_on: Time.current)

component = described_class.new(product: product)
render_inline described_class.from_product(product)

expect(component.status).to eq(:available)
expect(rendered_content).to have_text("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)
render_inline described_class.from_product(product)

expect(component.status).to eq(:discontinued)
expect(rendered_content).to have_text("Discontinued")
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

require "spec_helper"

RSpec.describe SolidusAdmin::Products::Stock::Component, type: :component do
it "renders the overview preview" do
render_preview(:overview)
end
end

0 comments on commit 0e4424c

Please sign in to comment.