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

[Admin] Introduce RMA reasons creation & modification capability #5829

Merged
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
@@ -0,0 +1,26 @@
<%= turbo_frame_tag :edit_return_reason_modal do %>
<%= render component("ui/modal").new(title: t(".title")) do |modal| %>
<%= form_for @return_reason, url: solidus_admin.return_reason_path(@return_reason), html: { id: form_id } do |f| %>
<div class="flex flex-col gap-6 pb-4">
<%= render component("ui/forms/field").text_field(f, :name, class: "required") %>
<label class="flex gap-2 items-center">
<%= hidden_field_tag "#{f.object_name}[active]", "0" %>
<%= render component("ui/forms/checkbox").new(
name: "#{f.object_name}[active]",
value: "1",
checked: f.object.active
) %>
<span class="font-semibold text-xs ml-2"><%= Spree::ReturnReason.human_attribute_name :active %></span>
<%= render component("ui/toggletip").new(text: t(".hints.active")) %>
</label>
</div>
<% modal.with_actions do %>
<form method="dialog">
<%= render component("ui/button").new(scheme: :secondary, text: t('.cancel')) %>
</form>
<%= render component("ui/button").new(form: form_id, type: :submit, text: t('.submit')) %>
<% end %>
<% end %>
<% end %>
<% end %>
<%= render component("return_reasons/index").new(page: @page) %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

class SolidusAdmin::ReturnReasons::Edit::Component < SolidusAdmin::BaseComponent
def initialize(page:, return_reason:)
@page = page
@return_reason = return_reason
end

def form_id
dom_id(@return_reason, "#{stimulus_id}_edit_return_reason_form")
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Add your component translations here.
# Use the translation in the example in your template with `t(".hello")`.
en:
title: "Edit Return Reason"
cancel: "Cancel"
submit: "Update Return Reason"
hints:
active: "When checked, this return reason will be available for selection when returning orders."
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,25 @@ def search_key
end

def row_url(return_reason)
spree.edit_admin_return_reason_path(return_reason)
spree.edit_admin_return_reason_path(return_reason, _turbo_frame: :edit_return_reason_modal)
end

def turbo_frames
%w[
new_return_reason_modal
edit_return_reason_modal
]
end

def page_actions
render component("ui/button").new(
tag: :a,
text: t('.add'),
href: solidus_admin.new_return_reason_path,
data: { turbo_frame: :new_return_reason_modal },
icon: "add-line",
class: "align-self-end w-full",
)
end

def batch_actions
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<%= turbo_frame_tag :new_return_reason_modal do %>
<%= render component("ui/modal").new(title: t(".title")) do |modal| %>
<%= form_for @return_reason, url: solidus_admin.return_reasons_path, html: { id: form_id } do |f| %>
<div class="flex flex-col gap-6 pb-4">
<%= render component("ui/forms/field").text_field(f, :name, class: "required") %>
<label class="flex gap-2 items-center">
<%= hidden_field_tag "#{f.object_name}[active]", "0" %>
<%= render component("ui/forms/checkbox").new(
name: "#{f.object_name}[active]",
value: "1",
checked: f.object.active
) %>
<span class="font-semibold text-xs ml-2"><%= Spree::ReturnReason.human_attribute_name :active %></span>
<%= render component("ui/toggletip").new(text: t(".hints.active")) %>
</label>
</div>
<% modal.with_actions do %>
<form method="dialog">
<%= render component("ui/button").new(scheme: :secondary, text: t('.cancel')) %>
</form>
<%= render component("ui/button").new(form: form_id, type: :submit, text: t('.submit')) %>
<% end %>
<% end %>
<% end %>
<% end %>

<%= render component("return_reasons/index").new(page: @page) %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

class SolidusAdmin::ReturnReasons::New::Component < SolidusAdmin::BaseComponent
def initialize(page:, return_reason:)
@page = page
@return_reason = return_reason
end

def form_id
dom_id(@return_reason, "#{stimulus_id}_new_return_reason_form")
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Add your component translations here.
# Use the translation in the example in your template with `t(".hello")`.
en:
title: "New Return Reason"
cancel: "Cancel"
submit: "Add Return Reason"
hints:
active: "When checked, this return reason will be available for selection when returning orders."
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,86 @@ module SolidusAdmin
class ReturnReasonsController < SolidusAdmin::BaseController
include SolidusAdmin::ControllerHelpers::Search

def index
return_reasons = apply_search_to(
Spree::ReturnReason.unscoped.order(id: :desc),
param: :q,
)
before_action :find_return_reason, only: %i[edit update]

set_page_and_extract_portion_from(return_reasons)
def index
set_index_page

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

def new
@return_reason = Spree::ReturnReason.new

set_index_page

respond_to do |format|
format.html { render component('return_reasons/new').new(page: @page, return_reason: @return_reason) }
end
end

def create
@return_reason = Spree::ReturnReason.new(return_reason_params)

if @return_reason.save
respond_to do |format|
flash[:notice] = t('.success')

format.html do
redirect_to solidus_admin.return_reasons_path, status: :see_other
end

format.turbo_stream do
render turbo_stream: '<turbo-stream action="refresh" />'
end
end
else
set_index_page

respond_to do |format|
format.html do
page_component = component('return_reasons/new').new(page: @page, return_reason: @return_reason)
render page_component, status: :unprocessable_entity
end
end
end
end

def edit
set_index_page

respond_to do |format|
format.html { render component('return_reasons/edit').new(page: @page, return_reason: @return_reason) }
end
end

def update
if @return_reason.update(return_reason_params)
respond_to do |format|
flash[:notice] = t('.success')

format.html do
redirect_to solidus_admin.return_reasons_path, status: :see_other
end

format.turbo_stream do
render turbo_stream: '<turbo-stream action="refresh" />'
end
end
else
set_index_page

respond_to do |format|
format.html do
page_component = component('return_reasons/edit').new(page: @page, return_reason: @return_reason)
render page_component, status: :unprocessable_entity
end
end
end
end

def destroy
@return_reason = Spree::ReturnReason.find_by!(id: params[:id])

Expand All @@ -28,8 +95,21 @@ def destroy

private

def find_return_reason
@return_reason = Spree::ReturnReason.find(params[:id])
end

def set_index_page
return_reasons = apply_search_to(
Spree::ReturnReason.unscoped.order(id: :desc),
param: :q,
)

set_page_and_extract_portion_from(return_reasons)
end

def return_reason_params
params.require(:return_reason).permit(:return_reason_id, permitted_return_reason_attributes)
params.require(:return_reason).permit(:name, :active)
end
end
end
6 changes: 5 additions & 1 deletion admin/config/locales/return_reasons.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,8 @@ en:
return_reasons:
title: "Return Reasons"
destroy:
success: "Return Reasons were successfully removed."
success: "Return reasons were successfully removed."
create:
success: "Return reason was successfully created."
update:
success: "Return reason was successfully updated."
2 changes: 1 addition & 1 deletion admin/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
admin_resources :zones, only: [:index, :destroy]
admin_resources :refund_reasons, except: [:show]
admin_resources :reimbursement_types, only: [:index]
admin_resources :return_reasons, only: [:index, :destroy]
admin_resources :return_reasons, except: [:show]
admin_resources :adjustment_reasons, except: [:show]
admin_resources :store_credit_reasons, except: [:show]
end
75 changes: 74 additions & 1 deletion admin/spec/features/return_reasons_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,82 @@

select_row("Default-return-reason")
click_on "Delete"
expect(page).to have_content("Return Reasons were successfully removed.")
expect(page).to have_content("Return reasons were successfully removed.")
expect(page).not_to have_content("Default-return-reason")
expect(Spree::ReturnReason.count).to eq(0)
expect(page).to be_axe_clean
end

context "when creating a new return reason" do
let(:query) { "?page=1&q%5Bname_cont%5D=new" }

before do
visit "/admin/return_reasons#{query}"
click_on "Add new"
expect(page).to have_content("New Return Reason")
expect(page).to be_axe_clean
end

it "opens a modal" do
expect(page).to have_selector("dialog")
within("dialog") { click_on "Cancel" }
expect(page).not_to have_selector("dialog")
expect(page.current_url).to include(query)
end

context "with valid data" do
it "successfully creates a new return reason, keeping page and q params" do
fill_in "Name", with: "New Reason"
page.uncheck "return_reason[active]"

click_on "Add Return Reason"

expect(page).to have_content("Return reason was successfully created.")
expect(Spree::ReturnReason.find_by(name: "New Reason")).to be_present
expect(Spree::ReturnReason.find_by(name: "New Reason").active).to be_falsey
expect(page.current_url).to include(query)
end
end

context "with invalid data" do
it "fails to create a new return reason, keeping page and q params" do
click_on "Add Return Reason"

expect(page).to have_content("can't be blank")
expect(page.current_url).to include(query)
end
end
end

context "when editing an existing return reason" do
let(:query) { "?page=1&q%5Bname_cont%5D=reason" }

before do
Spree::ReturnReason.create(name: "Good Reason")
visit "/admin/return_reasons#{query}"
find_row("Good Reason").click
expect(page).to have_content("Edit Return Reason")
expect(page).to be_axe_clean
end

it "opens a modal" do
expect(page).to have_selector("dialog")
within("dialog") { click_on "Cancel" }
expect(page).not_to have_selector("dialog")
expect(page.current_url).to include(query)
end

it "successfully updates the existing return reason" do
fill_in "Name", with: "Better Reason"
page.uncheck "return_reason[active]"

click_on "Update Return Reason"
expect(page).to have_content("Return reason was successfully updated.")
expect(page).to have_content("Better Reason")
expect(page).not_to have_content("Good Reason")
expect(Spree::ReturnReason.find_by(name: "Better Reason")).to be_present
expect(Spree::ReturnReason.find_by(name: "Better Reason").active).to be_falsey
expect(page.current_url).to include(query)
end
end
end
Loading
Loading