From 649aea45de6a0cbcb3f912ddaf0bef29582b2085 Mon Sep 17 00:00:00 2001 From: Loic Date: Wed, 10 Apr 2024 12:57:02 +0200 Subject: [PATCH 1/3] Create a shipping category via new admin UI --- .../shipping_categories/index/component.rb | 14 +++++ .../new/component.html.erb | 17 ++++++ .../shipping_categories/new/component.rb | 12 ++++ .../shipping_categories/new/component.yml | 6 ++ .../shipping_categories_controller.rb | 57 ++++++++++++++++--- .../config/locales/shipping_categories.en.yml | 2 + admin/config/routes.rb | 2 +- .../spec/features/shipping_categories_spec.rb | 39 +++++++++++++ 8 files changed, 141 insertions(+), 8 deletions(-) create mode 100644 admin/app/components/solidus_admin/shipping_categories/new/component.html.erb create mode 100644 admin/app/components/solidus_admin/shipping_categories/new/component.rb create mode 100644 admin/app/components/solidus_admin/shipping_categories/new/component.yml diff --git a/admin/app/components/solidus_admin/shipping_categories/index/component.rb b/admin/app/components/solidus_admin/shipping_categories/index/component.rb index d5bf779136b..33a09f4cd2f 100644 --- a/admin/app/components/solidus_admin/shipping_categories/index/component.rb +++ b/admin/app/components/solidus_admin/shipping_categories/index/component.rb @@ -15,6 +15,20 @@ def actions ) end + def page_actions + render component("ui/button").new( + tag: :a, + text: t('.add'), + href: solidus_admin.new_shipping_category_path, data: { turbo_frame: :new_shipping_category_modal }, + icon: "add-line", + class: "align-self-end w-full", + ) + end + + def turbo_frames + %w[new_shipping_category_modal] + end + def row_url(shipping_category) spree.edit_admin_shipping_category_path(shipping_category) end diff --git a/admin/app/components/solidus_admin/shipping_categories/new/component.html.erb b/admin/app/components/solidus_admin/shipping_categories/new/component.html.erb new file mode 100644 index 00000000000..e3cf3a75937 --- /dev/null +++ b/admin/app/components/solidus_admin/shipping_categories/new/component.html.erb @@ -0,0 +1,17 @@ +<%= turbo_frame_tag :new_shipping_category_modal do %> + <%= render component("ui/modal").new(title: t(".title")) do |modal| %> + <%= form_for @shipping_category, url: solidus_admin.shipping_categories_path(page: params[:page], q: params[:q]), html: { id: form_id } do |f| %> +
+ <%= render component("ui/forms/field").text_field(f, :name) %> +
+ <% modal.with_actions do %> +
+ <%= render component("ui/button").new(scheme: :secondary, text: t('.cancel')) %> +
+ <%= render component("ui/button").new(form: form_id, type: :submit, text: t('.submit')) %> + <% end %> + <% end %> + <% end %> +<% end %> + +<%= render component("shipping_categories/index").new(page: @page) %> diff --git a/admin/app/components/solidus_admin/shipping_categories/new/component.rb b/admin/app/components/solidus_admin/shipping_categories/new/component.rb new file mode 100644 index 00000000000..ec46b93ae3d --- /dev/null +++ b/admin/app/components/solidus_admin/shipping_categories/new/component.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class SolidusAdmin::ShippingCategories::New::Component < SolidusAdmin::ShippingCategories::Index::Component + def initialize(page:, shipping_category:) + @page = page + @shipping_category = shipping_category + end + + def form_id + dom_id(@shipping_category, "#{stimulus_id}_new_shipping_category_form") + end +end diff --git a/admin/app/components/solidus_admin/shipping_categories/new/component.yml b/admin/app/components/solidus_admin/shipping_categories/new/component.yml new file mode 100644 index 00000000000..f4b77159807 --- /dev/null +++ b/admin/app/components/solidus_admin/shipping_categories/new/component.yml @@ -0,0 +1,6 @@ +# Add your component translations here. +# Use the translation in the example in your template with `t(".hello")`. +en: + title: "New Shipping Category" + cancel: "Cancel" + submit: "Add Shipping Category" diff --git a/admin/app/controllers/solidus_admin/shipping_categories_controller.rb b/admin/app/controllers/solidus_admin/shipping_categories_controller.rb index 7e77234c58b..a27bf31313e 100644 --- a/admin/app/controllers/solidus_admin/shipping_categories_controller.rb +++ b/admin/app/controllers/solidus_admin/shipping_categories_controller.rb @@ -4,13 +4,47 @@ module SolidusAdmin class ShippingCategoriesController < SolidusAdmin::BaseController include SolidusAdmin::ControllerHelpers::Search - def index - shipping_categories = apply_search_to( - Spree::ShippingCategory.order(id: :desc), - param: :q, - ) + def new + @shipping_category = Spree::ShippingCategory.new - set_page_and_extract_portion_from(shipping_categories) + set_index_page + + respond_to do |format| + format.html { render component('shipping_categories/new').new(page: @page, shipping_category: @shipping_category) } + end + end + + def create + @shipping_category = Spree::ShippingCategory.new(shipping_category_params) + + if @shipping_category.save + respond_to do |format| + flash[:notice] = t('.success') + + format.html do + redirect_to solidus_admin.shipping_categories_path, status: :see_other + end + + format.turbo_stream do + # we need to explicitly write the refresh tag for now. + # See https://github.com/hotwired/turbo-rails/issues/579 + render turbo_stream: '' + end + end + else + set_index_page + + respond_to do |format| + format.html do + page_component = component('shipping_categories/new').new(page: @page, shipping_category: @shipping_category) + render page_component, status: :unprocessable_entity + end + end + end + end + + def index + set_index_page respond_to do |format| format.html { render component('shipping_categories/index').new(page: @page) } @@ -34,7 +68,16 @@ def load_shipping_category end def shipping_category_params - params.require(:shipping_category).permit(:shipping_category_id, permitted_shipping_category_attributes) + params.require(:shipping_category).permit(:name) + end + + def set_index_page + shipping_categories = apply_search_to( + Spree::ShippingCategory.order(id: :desc), + param: :q, + ) + + set_page_and_extract_portion_from(shipping_categories) end end end diff --git a/admin/config/locales/shipping_categories.en.yml b/admin/config/locales/shipping_categories.en.yml index 69ab216dac5..7bcc3dd54e1 100644 --- a/admin/config/locales/shipping_categories.en.yml +++ b/admin/config/locales/shipping_categories.en.yml @@ -4,3 +4,5 @@ en: title: "Shipping Categories" destroy: success: "Shipping categories were successfully removed." + create: + success: "Shipping category was successfully created." diff --git a/admin/config/routes.rb b/admin/config/routes.rb index 37003949356..28a740117cb 100644 --- a/admin/config/routes.rb +++ b/admin/config/routes.rb @@ -56,7 +56,7 @@ admin_resources :payment_methods, only: [:index, :destroy], sortable: true admin_resources :stock_items, only: [:index, :edit, :update] admin_resources :shipping_methods, only: [:index, :destroy] - admin_resources :shipping_categories, only: [:index, :destroy] + admin_resources :shipping_categories, only: [:new, :index, :create, :destroy] admin_resources :stock_locations, only: [:index, :destroy] admin_resources :stores, only: [:index, :destroy] admin_resources :zones, only: [:index, :destroy] diff --git a/admin/spec/features/shipping_categories_spec.rb b/admin/spec/features/shipping_categories_spec.rb index e3d02c4a0d9..56b374c55bb 100644 --- a/admin/spec/features/shipping_categories_spec.rb +++ b/admin/spec/features/shipping_categories_spec.rb @@ -19,4 +19,43 @@ expect(Spree::ShippingCategory.count).to eq(0) expect(page).to be_axe_clean end + + context "when creating a new shipping category" do + let(:query) { "?page=1&q%5Bname_or_description_cont%5D=What" } + + before do + visit "/admin/shipping_categories#{query}" + click_on "Add new" + expect(page).to have_content("New Shipping Category") + 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 shipping category, keeping page and q params" do + fill_in "Name", with: "Whatever" + + click_on "Add Shipping Category" + + expect(page).to have_content("Shipping category was successfully created.") + expect(Spree::ShippingCategory.find_by(name: "Whatever")).to be_present + expect(page.current_url).to include(query) + end + end + + context "with invalid data" do + it "fails to create a new shipping category, keeping page and q params" do + click_on "Add Shipping Category" + + expect(page).to have_content "can't be blank" + expect(page.current_url).to include(query) + end + end + end end From 5cc263b65546b720eb07174e3fe8dad3a2f1a5c2 Mon Sep 17 00:00:00 2001 From: Loic Date: Wed, 10 Apr 2024 12:58:51 +0200 Subject: [PATCH 2/3] capability to search shipping category in admin Now that new admin allow for searching them, we had to allow name attrribute to be searchable via ransack --- .../solidus_admin/shipping_categories/index/component.rb | 2 +- core/app/models/spree/shipping_category.rb | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/admin/app/components/solidus_admin/shipping_categories/index/component.rb b/admin/app/components/solidus_admin/shipping_categories/index/component.rb index 33a09f4cd2f..d15fee49d9c 100644 --- a/admin/app/components/solidus_admin/shipping_categories/index/component.rb +++ b/admin/app/components/solidus_admin/shipping_categories/index/component.rb @@ -34,7 +34,7 @@ def row_url(shipping_category) end def search_key - :name_or_description_cont + :name_cont end def search_url diff --git a/core/app/models/spree/shipping_category.rb b/core/app/models/spree/shipping_category.rb index eca822d9554..8d5da64979f 100644 --- a/core/app/models/spree/shipping_category.rb +++ b/core/app/models/spree/shipping_category.rb @@ -2,6 +2,8 @@ module Spree class ShippingCategory < Spree::Base + self.allowed_ransackable_attributes = %w[name] + validates :name, presence: true has_many :products, inverse_of: :shipping_category has_many :shipping_method_categories, inverse_of: :shipping_category From 47177cb9eded31e3df848be2a89c9d9758aac63b Mon Sep 17 00:00:00 2001 From: Loic Date: Fri, 12 Apr 2024 15:23:49 +0200 Subject: [PATCH 3/3] Update a shipping category in new admin UI --- .../edit/component.html.erb | 16 ++++++++ .../shipping_categories/edit/component.rb | 12 ++++++ .../shipping_categories/edit/component.yml | 6 +++ .../shipping_categories/index/component.rb | 7 +++- .../shipping_categories_controller.rb | 39 +++++++++++++++++++ .../config/locales/shipping_categories.en.yml | 3 ++ admin/config/routes.rb | 2 +- .../spec/features/shipping_categories_spec.rb | 19 +++++++++ 8 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 admin/app/components/solidus_admin/shipping_categories/edit/component.html.erb create mode 100644 admin/app/components/solidus_admin/shipping_categories/edit/component.rb create mode 100644 admin/app/components/solidus_admin/shipping_categories/edit/component.yml diff --git a/admin/app/components/solidus_admin/shipping_categories/edit/component.html.erb b/admin/app/components/solidus_admin/shipping_categories/edit/component.html.erb new file mode 100644 index 00000000000..2afd4813ee1 --- /dev/null +++ b/admin/app/components/solidus_admin/shipping_categories/edit/component.html.erb @@ -0,0 +1,16 @@ +<%= turbo_frame_tag :edit_shipping_category_modal do %> + <%= render component("ui/modal").new(title: t(".title")) do |modal| %> + <%= form_for @shipping_category, url: solidus_admin.shipping_category_path(@shipping_category), html: { id: form_id } do |f| %> +
+ <%= render component("ui/forms/field").text_field(f, :name) %> +
+ <% modal.with_actions do %> +
+ <%= render component("ui/button").new(scheme: :secondary, text: t('.cancel')) %> +
+ <%= render component("ui/button").new(form: form_id, type: :submit, text: t('.submit')) %> + <% end %> + <% end %> + <% end %> +<% end %> +<%= render component("shipping_categories/index").new(page: @page) %> \ No newline at end of file diff --git a/admin/app/components/solidus_admin/shipping_categories/edit/component.rb b/admin/app/components/solidus_admin/shipping_categories/edit/component.rb new file mode 100644 index 00000000000..62f8b8f1b59 --- /dev/null +++ b/admin/app/components/solidus_admin/shipping_categories/edit/component.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class SolidusAdmin::ShippingCategories::Edit::Component < SolidusAdmin::ShippingCategories::Index::Component + def initialize(page:, shipping_category:) + @page = page + @shipping_category = shipping_category + end + + def form_id + dom_id(@shipping_category, "#{stimulus_id}_edit_shipping_category_form") + end +end \ No newline at end of file diff --git a/admin/app/components/solidus_admin/shipping_categories/edit/component.yml b/admin/app/components/solidus_admin/shipping_categories/edit/component.yml new file mode 100644 index 00000000000..d61ed4ed0c0 --- /dev/null +++ b/admin/app/components/solidus_admin/shipping_categories/edit/component.yml @@ -0,0 +1,6 @@ +# Add your component translations here. +# Use the translation in the example in your template with `t(".hello")`. +en: + title: "Edit Shipping Category" + cancel: "Cancel" + submit: "Update Shipping Category" \ No newline at end of file diff --git a/admin/app/components/solidus_admin/shipping_categories/index/component.rb b/admin/app/components/solidus_admin/shipping_categories/index/component.rb index d15fee49d9c..37b6b148257 100644 --- a/admin/app/components/solidus_admin/shipping_categories/index/component.rb +++ b/admin/app/components/solidus_admin/shipping_categories/index/component.rb @@ -26,11 +26,14 @@ def page_actions end def turbo_frames - %w[new_shipping_category_modal] + %w[ + new_shipping_category_modal + edit_shipping_category_modal + ] end def row_url(shipping_category) - spree.edit_admin_shipping_category_path(shipping_category) + spree.edit_admin_shipping_category_path(shipping_category, _turbo_frame: :edit_shipping_category_modal) end def search_key diff --git a/admin/app/controllers/solidus_admin/shipping_categories_controller.rb b/admin/app/controllers/solidus_admin/shipping_categories_controller.rb index a27bf31313e..400482ab822 100644 --- a/admin/app/controllers/solidus_admin/shipping_categories_controller.rb +++ b/admin/app/controllers/solidus_admin/shipping_categories_controller.rb @@ -4,6 +4,8 @@ module SolidusAdmin class ShippingCategoriesController < SolidusAdmin::BaseController include SolidusAdmin::ControllerHelpers::Search + before_action :find_shipping_category, only: %i[edit update] + def new @shipping_category = Spree::ShippingCategory.new @@ -43,6 +45,39 @@ def create end end + def edit + set_index_page + + respond_to do |format| + format.html { render component('shipping_categories/edit').new(page: @page, shipping_category: @shipping_category) } + end + end + + def update + if @shipping_category.update(shipping_category_params) + respond_to do |format| + flash[:notice] = t('.success') + + format.html do + redirect_to solidus_admin.shipping_categories_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('shipping_categories/edit').new(page: @page, shipping_category: @shipping_category) + render page_component, status: :unprocessable_entity + end + end + end + end + def index set_index_page @@ -67,6 +102,10 @@ def load_shipping_category authorize! action_name, @shipping_category end + def find_shipping_category + @shipping_category = Spree::ShippingCategory.find(params[:id]) + end + def shipping_category_params params.require(:shipping_category).permit(:name) end diff --git a/admin/config/locales/shipping_categories.en.yml b/admin/config/locales/shipping_categories.en.yml index 7bcc3dd54e1..677230e6607 100644 --- a/admin/config/locales/shipping_categories.en.yml +++ b/admin/config/locales/shipping_categories.en.yml @@ -6,3 +6,6 @@ en: success: "Shipping categories were successfully removed." create: success: "Shipping category was successfully created." + update: + success: "Shipping category was successfully updated." + diff --git a/admin/config/routes.rb b/admin/config/routes.rb index 28a740117cb..8f0d9bfee77 100644 --- a/admin/config/routes.rb +++ b/admin/config/routes.rb @@ -56,7 +56,7 @@ admin_resources :payment_methods, only: [:index, :destroy], sortable: true admin_resources :stock_items, only: [:index, :edit, :update] admin_resources :shipping_methods, only: [:index, :destroy] - admin_resources :shipping_categories, only: [:new, :index, :create, :destroy] + admin_resources :shipping_categories, except: [:show] admin_resources :stock_locations, only: [:index, :destroy] admin_resources :stores, only: [:index, :destroy] admin_resources :zones, only: [:index, :destroy] diff --git a/admin/spec/features/shipping_categories_spec.rb b/admin/spec/features/shipping_categories_spec.rb index 56b374c55bb..d2ab165ad98 100644 --- a/admin/spec/features/shipping_categories_spec.rb +++ b/admin/spec/features/shipping_categories_spec.rb @@ -20,6 +20,25 @@ expect(page).to be_axe_clean end + context "edition" do + before do + Spree::ShippingCategory.create(name: "a shipping category") + end + + it "allows to edit a shipping category" do + visit "/admin/shipping_categories" + find_row("a shipping category").click() + + expect(page).to have_content("Edit Shipping Category") + + fill_in "Name", with: "a new name" + + click_on "Update Shipping Category" + expect(page).to have_content("Shipping category was successfully updated.") + expect(Spree::ShippingCategory.find_by(name: "a new name")).to be_present + end + end + context "when creating a new shipping category" do let(:query) { "?page=1&q%5Bname_or_description_cont%5D=What" }