Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Promotions index improvements #79

Merged
merged 15 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def collection
return @collection if @collection

params[:q] ||= HashWithIndifferentAccess.new
params[:q][:s] ||= "id desc"
params[:q][:s] ||= "updated_at desc"

@collection = super
@search = @collection.ransack(params[:q])
Expand Down
2 changes: 1 addition & 1 deletion app/models/solidus_friendly_promotions/promotion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def self.ordered_lanes
end

self.allowed_ransackable_associations = ["codes"]
self.allowed_ransackable_attributes = %w[name path promotion_category_id]
self.allowed_ransackable_attributes = %w[name customer_label path promotion_category_id lane updated_at]
self.allowed_ransackable_scopes = %i[active]

# All orders that have been discounted using this promotion
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<table class="index">
<thead>
<tr>
<th><%= sort_link @search, :name %></th>
<th><%= SolidusFriendlyPromotions::Promotion.human_attribute_name(:code) %></th>
<th><%= SolidusFriendlyPromotions::Promotion.human_attribute_name(:status) %></th>
<th><%= SolidusFriendlyPromotions::Promotion.human_attribute_name(:usage) %></th>
<th><%= sort_link @search, :starts_at %></th>
<th><%= sort_link @search, :expires_at %></th>
<th><%= SolidusFriendlyPromotions::Promotion.human_attribute_name(:lane) %></th>
<th><%= sort_link @search, :updated_at %></th>
<th class="actions"></th>
</tr>
</thead>
<tbody>
<% promotions.each do |promotion| %>
<tr id="<%= spree_dom_id promotion %>">
<td><%= promotion.name %></td>
<td>
<%= (promotion.codes.size == 1) ? promotion.codes.pluck(:value).first : t('solidus_friendly_promotions.number_of_codes', count: promotion.codes.size) %>
</td>
<td>
<span class="pill pill-<%= promotion.active? ? 'active' : 'inactive' %>">
<%= t(admin_promotion_status(promotion), scope: 'solidus_friendly_promotions.admin.promotion_status') %>
</span>
</td>
<td>
<% if promotion.usage_limit.nil? %>
<%= promotion.discounted_orders.exists? ? t(:say_yes, scope: :spree) : t(:say_no, scope: :spree) %>
<% else %>
<%= promotion.usage_count %> / <%= promotion.usage_limit %>
<% end %>
<td>
<%= l(promotion.starts_at, format: :short) if promotion.starts_at %>
</td>
<td>
<%= l(promotion.expires_at, format: :short) if promotion.expires_at %>
</td>
<td>
<%= SolidusFriendlyPromotions::Promotion.human_enum_name(:lane, promotion.lane) %>
</td>
<td>
<%= l(promotion.updated_at, format: :short) %>
</td>
<td class="actions">
<% if can?(:edit, promotion) %>
<%= link_to_edit promotion, no_text: true %>
<% end %>
<% if can?(:destroy, promotion) %>
<%= link_to_delete promotion, no_text: true %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<% content_for :table_filter_title do %>
<%= t('spree.search') %>
<% end %>

<% content_for :table_filter do %>
<div data-hook="admin_promotions_index_search">
<%= search_form_for [:admin, search] do |f| %>
<div class="row">
<div class="col-4">
<div class="field">
<%= label_tag :q_name_cont, SolidusFriendlyPromotions::Promotion.human_attribute_name(:name) %>
<%= f.text_field :name_cont, tabindex: 1 %>
</div>
</div>

<div class="col-4">
<div class="field">
<%= label_tag :q_customer_label_cont, SolidusFriendlyPromotions::Promotion.human_attribute_name(:customer_label) %>
<%= f.text_field :customer_label_cont, tabindex: 1 %>
</div>
</div>

<div class="col-2">
<div class="field">
<%= label_tag :q_codes_value_cont, SolidusFriendlyPromotions::Promotion.human_attribute_name(:code) %>
<%= f.text_field :codes_value_cont, tabindex: 1 %>
</div>
</div>

<div class="col-2">
<div class="field">
<%= label_tag :q_path_cont, SolidusFriendlyPromotions::Promotion.human_attribute_name(:path) %>
<%= f.text_field :path_cont, tabindex: 1 %>
</div>
</div>

<div class="col-2">
<div class="date-range-filter field">
<%= label_tag :q_active, SolidusFriendlyPromotions::Promotion.human_attribute_name(:active) %>
<%= f.text_field :active, value: params[:q][:active],
class: 'datepicker datepicker-from fullwidth',
data: { :'enable-time' => true, :'default-hour' => 0 } %>
</div>
</div>

<div class="col-2">
<div class="field">
<%= label_tag :q_promotion_category_id_eq, SolidusFriendlyPromotions::PromotionCategory.model_name.human %><br>
<%= f.collection_select(:promotion_category_id_eq, @promotion_categories, :id, :name, { include_blank: t(:all, scope: :spree) }, { class: 'custom-select fullwidth' }) %>
</div>
</div>

<div class="col-2">
<div class="field">
<%= label_tag :q_lane_eq, SolidusFriendlyPromotions::Promotion.human_attribute_name(:lane) %><br>
<%= f.select(:lane_eq, SolidusFriendlyPromotions::Promotion.lane_options, { include_blank: t(:all, scope: :spree) }, { class: 'custom-select fullwidth' }) %>
</div>
</div>

</div>

<div class="actions filter-actions">
<div data-hook="admin_promotions_index_search_buttons">
<%= button_tag t('spree.filter_results'), class: 'btn btn-primary' %>
</div>
</div>
<% end %>
</div>
<% end %>
105 changes: 2 additions & 103 deletions app/views/solidus_friendly_promotions/admin/promotions/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,113 +8,12 @@
<% end %>
<% end %>

<% content_for :table_filter_title do %>
<%= t('spree.search') %>
<% end %>

<% content_for :table_filter do %>
<div data-hook="admin_promotions_index_search">
<%= search_form_for [:admin, @search] do |f| %>
<div class="row">
<div class="col-4">
<div class="field">
<%= label_tag :q_name_cont, SolidusFriendlyPromotions::Promotion.human_attribute_name(:name) %>
<%= f.text_field :name_cont, tabindex: 1 %>
</div>
</div>

<div class="col-2">
<div class="field">
<%= label_tag :q_codes_value_cont, SolidusFriendlyPromotions::Promotion.human_attribute_name(:code) %>
<%= f.text_field :codes_value_cont, tabindex: 1 %>
</div>
</div>

<div class="col-2">
<div class="field">
<%= label_tag :q_path_cont, SolidusFriendlyPromotions::Promotion.human_attribute_name(:path) %>
<%= f.text_field :path_cont, tabindex: 1 %>
</div>
</div>

<div class="col-2">
<div class="field">
<%= label_tag :q_promotion_category_id_eq, SolidusFriendlyPromotions::PromotionCategory.model_name.human %><br>
<%= f.collection_select(:promotion_category_id_eq, @promotion_categories, :id, :name, { include_blank: t('solidus_friendly_promotions.match_choices.all') }, { class: 'custom-select fullwidth' }) %>
</div>
</div>

<div class="col-2">
<div class="field">
<%= label_tag :active, SolidusFriendlyPromotions::Promotion.human_attribute_name(:active) %><br>
<%= f.check_box :active, label: false, as: :boolean, checked_value: true %>
</div>
</div>
</div>

<div class="clearfix"></div>

<div class="actions filter-actions">
<div data-hook="admin_promotions_index_search_buttons">
<%= button_tag t('spree.filter_results'), class: 'btn btn-primary' %>
</div>
</div>
<% end %>
</div>
<% end %>
<%= render "table_filter", search: @search %>

<%= paginate @promotions, theme: "solidus_admin" %>

<% if @promotions.length > 0 %>
<table class="index">
<thead>
<tr>
<th><%= SolidusFriendlyPromotions::Promotion.human_attribute_name(:name) %></th>
<th><%= SolidusFriendlyPromotions::Promotion.human_attribute_name(:code) %></th>
<th><%= SolidusFriendlyPromotions::Promotion.human_attribute_name(:status) %></th>
<th><%= SolidusFriendlyPromotions::Promotion.human_attribute_name(:usage_limit) %></th>
<th><%= SolidusFriendlyPromotions::Promotion.human_attribute_name(:uses) %></th>
<th><%= SolidusFriendlyPromotions::Promotion.human_attribute_name(:starts_at) %></th>
<th><%= SolidusFriendlyPromotions::Promotion.human_attribute_name(:expires_at) %></th>
<th class="actions"></th>
</tr>
</thead>
<tbody>
<% @promotions.each do |promotion| %>
<tr id="<%= spree_dom_id promotion %>">
<td><%= promotion.name %></td>
<td>
<%= (promotion.codes.size == 1) ? promotion.codes.pluck(:value).first : t('solidus_friendly_promotions.number_of_codes', count: promotion.codes.size) %>
</td>
<td>
<span class="pill pill-<%= promotion.active? ? 'active' : 'inactive' %>">
<%= t(admin_promotion_status(promotion), scope: 'solidus_friendly_promotions.admin.promotion_status') %>
</span>
</td>
<td>
<%= promotion.usage_limit.nil? ? "∞" : promotion.usage_limit %>
</td>
<td>
<%= promotion.usage_count %>
</td>
<td>
<%= promotion.starts_at.to_fs(:long) if promotion.starts_at %>
</td>
<td>
<%= promotion.expires_at.to_fs(:long) if promotion.expires_at %>
</td>
<td class="actions">
<% if can?(:edit, promotion) %>
<%= link_to_edit promotion, no_text: true %>
<% end %>
<% if can?(:destroy, promotion) %>
<%= link_to_delete promotion, no_text: true %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= render "table", promotions: @promotions %>
<% else %>
<div class="no-objects-found">
<%= render 'spree/admin/shared/no_objects_found',
Expand Down
3 changes: 2 additions & 1 deletion config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ en:
new_promotion: New Promotion
new_promotion_category: New Promotion Category
new_promotion_code_batch: New Promotion Code Batch
number_of_codes: Number of codes
number_of_codes: "%{count} codes"
legacy_promotions: Legacy Promotions
no_rules_added: No Rules Added
promotion_successfully_created: Promotion has been successfully created!
Expand Down Expand Up @@ -191,6 +191,7 @@ en:
solidus_friendly_promotions/promotion:
active: Active
customer_label: Customer-facing label
usage: Usage
lanes:
pre: Pre
default: Default
Expand Down
1 change: 1 addition & 0 deletions lib/solidus_friendly_promotions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require "turbo-rails"
require "importmap-rails"
require "stimulus-rails"
require "ransack-enum"
require "solidus_friendly_promotions/nested_class_set"
require "solidus_friendly_promotions/configuration"
require "solidus_friendly_promotions/version"
Expand Down
1 change: 1 addition & 0 deletions solidus_friendly_promotions.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
spec.add_dependency "turbo-rails", "~> 1.4"
spec.add_dependency "stimulus-rails", "~> 1.2"
spec.add_dependency "importmap-rails", "~> 1.2"
spec.add_dependency "ransack-enum", "~> 1.0"
spec.add_development_dependency "rspec-activemodel-mocks", "~> 1.0"
spec.add_development_dependency "shoulda-matchers", "~> 5.3"
spec.add_development_dependency "solidus_dev_support", "~> 2.6"
Expand Down
35 changes: 28 additions & 7 deletions spec/system/solidus_friendly_promotions/admin/promotions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@

describe "#index" do
let!(:promotion1) do
create(:friendly_promotion, :with_adjustable_action, name: "name1", code: "code1", path: "path1")
create(:friendly_promotion, :with_adjustable_action, name: "name1", code: "code1", path: "path1", lane: "pre", updated_at: 2.days.ago)
end
let!(:promotion2) do
create(:friendly_promotion, :with_adjustable_action, name: "name2", code: "code2", path: "path2")
create(:friendly_promotion, :with_adjustable_action, name: "name2", code: "code2", path: "path2", lane: "default", updated_at: 10.days.ago)
end
let!(:promotion3) do
create(
:friendly_promotion,
:with_adjustable_action,
lane: "post",
name: "name3",
code: "code3",
path: "path3",
updated_at: 5.days.ago,
expires_at: Date.yesterday
)
end
Expand All @@ -39,11 +41,11 @@
)
end

context "search" do
describe "search" do
it "pages results" do
visit solidus_friendly_promotions.admin_promotions_path(per_page: "1")
expect(page).to have_content(promotion3.name)
expect(page).not_to have_content(promotion1.name)
expect(page).to have_content(promotion1.name)
expect(page).not_to have_content(promotion3.name)
end

it "filters by name" do
Expand All @@ -64,12 +66,31 @@
expect(page).not_to have_content(promotion2.name)
end

it "filters by active" do
visit solidus_friendly_promotions.admin_promotions_path(q: {active: true})
it "filters by active date" do
visit solidus_friendly_promotions.admin_promotions_path(q: {active: Time.current})
expect(page).to have_content(promotion1.name)
expect(page).to have_content(promotion2.name)
expect(page).not_to have_content(promotion3.name)
end

it "filters by active the day before yesterday" do
visit solidus_friendly_promotions.admin_promotions_path(q: {active: 2.days.ago})
expect(page).to have_content(promotion1.name)
expect(page).to have_content(promotion2.name)
expect(page).to have_content(promotion3.name)
end

it "filters by lane" do
visit solidus_friendly_promotions.admin_promotions_path(q: {lane_eq: :pre})
expect(page).to have_content(promotion1.name)
expect(page).not_to have_content(promotion2.name)
expect(page).not_to have_content(promotion3.name)
end

it "sorts by updated_at by default" do
visit solidus_friendly_promotions.admin_promotions_path
expect(page.text).to match(/.*name1.*name3.*name2.*/m)
end
end
end

Expand Down