diff --git a/admin/app/components/solidus_admin/refund_reasons/index/component.rb b/admin/app/components/solidus_admin/refund_reasons/index/component.rb
index bff2aa644c1..6cbcfecada9 100644
--- a/admin/app/components/solidus_admin/refund_reasons/index/component.rb
+++ b/admin/app/components/solidus_admin/refund_reasons/index/component.rb
@@ -17,11 +17,15 @@ def row_url(refund_reason)
spree.edit_admin_refund_reason_path(refund_reason)
end
- def actions
+ def turbo_frames
+ %w[new_refund_reason_modal]
+ end
+
+ def page_actions
render component("ui/button").new(
tag: :a,
text: t('.add'),
- href: spree.new_admin_refund_reason_path,
+ href: solidus_admin.new_refund_reason_path, data: { turbo_frame: :new_refund_reason_modal },
icon: "add-line",
class: "align-self-end w-full",
)
diff --git a/admin/app/components/solidus_admin/refund_reasons/new/component.html.erb b/admin/app/components/solidus_admin/refund_reasons/new/component.html.erb
new file mode 100644
index 00000000000..ed82c770caf
--- /dev/null
+++ b/admin/app/components/solidus_admin/refund_reasons/new/component.html.erb
@@ -0,0 +1,27 @@
+<%= turbo_frame_tag :new_refund_reason_modal do %>
+ <%= render component("ui/modal").new(title: t(".title")) do |modal| %>
+ <%= form_for @refund_reason, url: solidus_admin.refund_reasons_path, html: { id: form_id } do |f| %>
+
+ <%= render component("ui/forms/field").text_field(f, :name, class: "required") %>
+ <%= render component("ui/forms/field").text_field(f, :code, class: "required") %>
+
+
+ <% modal.with_actions do %>
+
+ <%= render component("ui/button").new(form: form_id, type: :submit, text: t('.submit')) %>
+ <% end %>
+ <% end %>
+ <% end %>
+<% end %>
+
+<%= render component("refund_reasons/index").new(page: @page) %>
diff --git a/admin/app/components/solidus_admin/refund_reasons/new/component.rb b/admin/app/components/solidus_admin/refund_reasons/new/component.rb
new file mode 100644
index 00000000000..686fc0e9ade
--- /dev/null
+++ b/admin/app/components/solidus_admin/refund_reasons/new/component.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class SolidusAdmin::RefundReasons::New::Component < SolidusAdmin::BaseComponent
+ def initialize(page:, refund_reason:)
+ @page = page
+ @refund_reason = refund_reason
+ end
+
+ def form_id
+ dom_id(@refund_reason, "#{stimulus_id}_new_refund_reason_form")
+ end
+end
diff --git a/admin/app/components/solidus_admin/refund_reasons/new/component.yml b/admin/app/components/solidus_admin/refund_reasons/new/component.yml
new file mode 100644
index 00000000000..57c60c9c077
--- /dev/null
+++ b/admin/app/components/solidus_admin/refund_reasons/new/component.yml
@@ -0,0 +1,6 @@
+en:
+ title: "New Refund Reason"
+ cancel: "Cancel"
+ submit: "Add Refund Reason"
+ hints:
+ active: "When checked, this refund reason will be available for selection when refunding orders."
diff --git a/admin/app/controllers/solidus_admin/refund_reasons_controller.rb b/admin/app/controllers/solidus_admin/refund_reasons_controller.rb
index 55a78bbb1da..f88cee5f06a 100644
--- a/admin/app/controllers/solidus_admin/refund_reasons_controller.rb
+++ b/admin/app/controllers/solidus_admin/refund_reasons_controller.rb
@@ -5,18 +5,50 @@ class RefundReasonsController < SolidusAdmin::BaseController
include SolidusAdmin::ControllerHelpers::Search
def index
- refund_reasons = apply_search_to(
- Spree::RefundReason.unscoped.order(id: :desc),
- param: :q,
- )
-
- set_page_and_extract_portion_from(refund_reasons)
+ set_index_page
respond_to do |format|
format.html { render component('refund_reasons/index').new(page: @page) }
end
end
+ def new
+ @refund_reason = Spree::RefundReason.new
+
+ set_index_page
+
+ respond_to do |format|
+ format.html { render component('refund_reasons/new').new(page: @page, refund_reason: @refund_reason) }
+ end
+ end
+
+ def create
+ @refund_reason = Spree::RefundReason.new(refund_reason_params)
+
+ if @refund_reason.save
+ respond_to do |format|
+ flash[:notice] = t('.success')
+
+ format.html do
+ redirect_to solidus_admin.refund_reasons_path, status: :see_other
+ end
+
+ format.turbo_stream do
+ render turbo_stream: ''
+ end
+ end
+ else
+ set_index_page
+
+ respond_to do |format|
+ format.html do
+ page_component = component('refund_reasons/new').new(page: @page, refund_reason: @refund_reason)
+ render page_component, status: :unprocessable_entity
+ end
+ end
+ end
+ end
+
def destroy
@refund_reason = Spree::RefundReason.find_by!(id: params[:id])
@@ -34,7 +66,16 @@ def load_refund_reason
end
def refund_reason_params
- params.require(:refund_reason).permit(:refund_reason_id, permitted_refund_reason_attributes)
+ params.require(:refund_reason).permit(:name, :code, :active)
+ end
+
+ def set_index_page
+ refund_reasons = apply_search_to(
+ Spree::RefundReason.unscoped.order(id: :desc),
+ param: :q,
+ )
+
+ set_page_and_extract_portion_from(refund_reasons)
end
end
end
diff --git a/admin/config/locales/refund_reasons_.en.yml b/admin/config/locales/refund_reasons.en.yml
similarity index 66%
rename from admin/config/locales/refund_reasons_.en.yml
rename to admin/config/locales/refund_reasons.en.yml
index 26bfae7ee8e..5113e88772a 100644
--- a/admin/config/locales/refund_reasons_.en.yml
+++ b/admin/config/locales/refund_reasons.en.yml
@@ -4,3 +4,5 @@ en:
title: "Refund Reasons"
destroy:
success: "Refund Reasons were successfully removed."
+ create:
+ success: "Refund reason was successfully created."
diff --git a/admin/config/routes.rb b/admin/config/routes.rb
index 37003949356..b066458127a 100644
--- a/admin/config/routes.rb
+++ b/admin/config/routes.rb
@@ -60,7 +60,7 @@
admin_resources :stock_locations, only: [:index, :destroy]
admin_resources :stores, only: [:index, :destroy]
admin_resources :zones, only: [:index, :destroy]
- admin_resources :refund_reasons, only: [:index, :destroy]
+ admin_resources :refund_reasons, only: [:index, :new, :create, :destroy]
admin_resources :reimbursement_types, only: [:index]
admin_resources :return_reasons, only: [:index, :destroy]
admin_resources :adjustment_reasons, only: [:index, :destroy]
diff --git a/admin/spec/features/refund_reasons_spec.rb b/admin/spec/features/refund_reasons_spec.rb
index 551035387d1..1cc9307e331 100644
--- a/admin/spec/features/refund_reasons_spec.rb
+++ b/admin/spec/features/refund_reasons_spec.rb
@@ -19,4 +19,43 @@
expect(Spree::RefundReason.count).to eq(0)
expect(page).to be_axe_clean
end
+
+ context "when creating a new refund reason" do
+ let(:query) { "?page=1&q%5Bname_or_description_cont%5D=Ret" }
+
+ before do
+ visit "/admin/refund_reasons/#{query}"
+ click_on "Add new"
+ expect(page).to have_content("New Refund 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 refund reason, keeping page and q params" do
+ fill_in "Name", with: "Return process"
+
+ click_on "Add Refund Reason"
+
+ expect(page).to have_content("Refund reason was successfully created.")
+ expect(Spree::RefundReason.find_by(name: "Return process")).to be_present
+ expect(page.current_url).to include(query)
+ end
+ end
+
+ context "with invalid data" do
+ it "fails to create a new refund reason, keeping page and q params" do
+ click_on "Add Refund Reason"
+
+ expect(page).to have_content "can't be blank"
+ expect(page.current_url).to include(query)
+ end
+ end
+ end
end