Skip to content

Commit

Permalink
Merge pull request #5517 from solidusio/elia/admin/promotions
Browse files Browse the repository at this point in the history
[admin] Add a `promotions/index` component
  • Loading branch information
elia authored Nov 28, 2023
2 parents 733eba1 + b2b3213 commit c74eafa
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<%= page do %>
<%= page_header do %>
<%= page_header_title title %>
<%= page_header_actions do %>
<%= render component("ui/button").new(
tag: :a,
text: t('.add'),
href: spree.new_admin_promotion_path,
icon: "add-line",
) %>
<% end %>
<% end %>

<%= render component('ui/table').new(
id: stimulus_id,
data: {
class: Spree::Promotion,
rows: @page.records,
url: ->(promotion) { spree.admin_promotion_path(promotion) },
prev: prev_page_path,
next: next_page_path,
columns: columns,
batch_actions: batch_actions,
},
search: {
name: :q,
value: params[:q],
url: solidus_admin.promotions_path,
searchbar_key: :name_or_codes_value_or_path_or_description_cont,
filters: filters,
scopes: scopes,
},
) %>
<% end %>
97 changes: 97 additions & 0 deletions admin/app/components/solidus_admin/promotions/index/component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# frozen_string_literal: true

class SolidusAdmin::Promotions::Index::Component < SolidusAdmin::BaseComponent
include SolidusAdmin::Layout::PageHelpers

def initialize(page:)
@page = page
end

def title
Spree::Promotion.model_name.human.pluralize
end

def prev_page_path
solidus_admin.url_for(**request.params, page: @page.number - 1, only_path: true) unless @page.first?
end

def next_page_path
solidus_admin.url_for(**request.params, page: @page.next_param, only_path: true) unless @page.last?
end

def batch_actions
[
{
display_name: t('.batch_actions.delete'),
action: solidus_admin.promotions_path,
method: :delete,
icon: 'delete-bin-7-line',
},
]
end

def filters
[
{
presentation: Spree::PromotionCategory.model_name.human.pluralize,
attribute: "promotion_category_id",
predicate: "in",
options: Spree::PromotionCategory.pluck(:name, :id)
}
]
end

def scopes
[
{ name: :active, label: t('.scopes.active'), default: true },
{ name: :draft, label: t('.scopes.draft') },
{ name: :future, label: t('.scopes.future') },
{ name: :expired, label: t('.scopes.expired') },
{ name: :all, label: t('.scopes.all') },
]
end

def columns
[
{
header: :name,
data: ->(promotion) do
content_tag :div, promotion.name
end
},
{
header: :code,
data: ->(promotion) do
count = promotion.codes.count
(count == 1) ? promotion.codes.pick(:value) : t('spree.number_of_codes', count: count)
end
},
{
header: :status,
data: ->(promotion) do
if promotion.active?
render component('ui/badge').new(name: t('.status.active'), color: :green)
else
render component('ui/badge').new(name: t('.status.inactive'), color: :graphite_light)
end
end
},
{
header: :usage_limit,
data: ->(promotion) { promotion.usage_limit || icon_tag('infinity-line') }
},
{
header: :uses,
data: ->(promotion) { promotion.usage_count }
},
{
header: :starts_at,
data: ->(promotion) { promotion.starts_at ? l(promotion.starts_at, format: :long) : icon_tag('infinity-line') }
},
{
header: :expires_at,
data: ->(promotion) { promotion.expires_at ? l(promotion.expires_at, format: :long) : icon_tag('infinity-line') }
},
]
end
end
14 changes: 14 additions & 0 deletions admin/app/components/solidus_admin/promotions/index/component.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
en:
promotion_image: 'Image'
add: 'Add Promotion'
batch_actions:
delete: 'Delete'
scopes:
active: Active
draft: Draft
future: Future
expired: Expired
all: All
status:
active: Active
inactive: Inactive
46 changes: 46 additions & 0 deletions admin/app/controllers/solidus_admin/promotions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# frozen_string_literal: true

module SolidusAdmin
class PromotionsController < SolidusAdmin::BaseController
include SolidusAdmin::ControllerHelpers::Search

search_scope(:active, default: true, &:active)
search_scope(:draft) { _1.where.not(id: _1.has_actions.select(:id)) }
search_scope(:future) { _1.has_actions.where(starts_at: Time.current..) }
search_scope(:expired) { _1.has_actions.where(expires_at: ..Time.current) }
search_scope(:all)

def index
promotions = apply_search_to(
Spree::Promotion.order(id: :desc),
param: :q,
)

set_page_and_extract_portion_from(promotions)

respond_to do |format|
format.html { render component('promotions/index').new(page: @page) }
end
end

def destroy
@promotions = Spree::Promotion.where(id: params[:id])

Spree::Promotion.transaction { @promotions.destroy_all }

flash[:notice] = t('.success')
redirect_back_or_to promotions_path, status: :see_other
end

private

def load_promotion
@promotion = Spree::Promotion.find_by!(number: params[:id])
authorize! action_name, @promotion
end

def promotion_params
params.require(:promotion).permit(:user_id, permitted_promotion_attributes)
end
end
end
6 changes: 6 additions & 0 deletions admin/config/locales/promotions.en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
en:
solidus_admin:
promotions:
title: "Promotions"
destroy:
success: "Promotions were successfully removed."
6 changes: 6 additions & 0 deletions admin/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,10 @@
delete :destroy
end
end

resources :promotions, only: [:index] do
collection do
delete :destroy
end
end
end
36 changes: 36 additions & 0 deletions admin/spec/features/promotions_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

require 'spec_helper'

describe "Promotions", :js, type: :feature do
before { sign_in create(:admin_user, email: '[email protected]') }

it "lists promotions and allows deleting them" do
create(:promotion, :with_action, name: "My active Promotion")
create(:promotion, name: "My draft Promotion")
create(:promotion, :with_action, name: "My expired Promotion", expires_at: 1.day.ago)
create(:promotion, :with_action, name: "My future Promotion", starts_at: 1.day.from_now)

visit "/admin/promotions"
expect(page).to have_content("My active Promotion")
click_on "Draft"
expect(page).to have_content("My draft Promotion", wait: 30)
click_on "Future"
expect(page).to have_content("My future Promotion", wait: 30)
click_on "Expired"
expect(page).to have_content("My expired Promotion", wait: 30)
click_on "All"
expect(page).to have_content("My active Promotion", wait: 30)
expect(page).to have_content("My draft Promotion")
expect(page).to have_content("My future Promotion")
expect(page).to have_content("My expired Promotion")

expect(page).to be_axe_clean

select_row("My active Promotion")
click_on "Delete"
expect(page).to have_content("Promotions were successfully removed.")
expect(page).not_to have_content("My active Promotion")
expect(Spree::Promotion.count).to eq(3)
end
end

0 comments on commit c74eafa

Please sign in to comment.