Skip to content

Commit

Permalink
Merge pull request solidusio#5829 from MadelineCollier/admin-rma-reas…
Browse files Browse the repository at this point in the history
…ons-create-update

[Admin] Introduce RMA reasons creation & modification capability
  • Loading branch information
MadelineCollier authored Aug 19, 2024
2 parents 5d82826 + 10eb257 commit b766363
Show file tree
Hide file tree
Showing 12 changed files with 411 additions and 11 deletions.
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) %>
12 changes: 12 additions & 0 deletions admin/app/components/solidus_admin/return_reasons/new/component.rb
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."
94 changes: 87 additions & 7 deletions admin/app/controllers/solidus_admin/return_reasons_controller.rb
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

0 comments on commit b766363

Please sign in to comment.