From 77524c633d92ff0664382b4d71fe2a05fac6794c Mon Sep 17 00:00:00 2001 From: PHAN QUANG LAM Date: Tue, 26 Oct 2021 06:41:30 +0900 Subject: [PATCH] Fix menu indicator on bulk order page --- app/helpers/spree/admin/navigation_helper.rb | 8 ++-- app/services/path_checker.rb | 21 ++++++++ .../admin/shared/_order_sub_menu.html.haml | 2 +- spec/services/path_checker_spec.rb | 48 +++++++++++++++++++ 4 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 app/services/path_checker.rb create mode 100644 spec/services/path_checker_spec.rb diff --git a/app/helpers/spree/admin/navigation_helper.rb b/app/helpers/spree/admin/navigation_helper.rb index c6ab8eac75..24c33e4996 100644 --- a/app/helpers/spree/admin/navigation_helper.rb +++ b/app/helpers/spree/admin/navigation_helper.rb @@ -9,6 +9,8 @@ module Spree # * :route to override automatically determining the default route # * :match_path as an alternative way to control when the tab is active, # /products would match /admin/products, /admin/products/5/variants etc. + # * :except_paths to reject subpaths that have their own menu, + # e.g. match_path = '/admin/orders', except_paths = ['/admin/orders/bulk_management'] def tab(*args) options = { label: args.first.to_s } if args.last.is_a?(Hash) @@ -36,9 +38,9 @@ module Spree end selected = if options[:match_path] - request. - fullpath. - starts_with?("#{main_app.root_path}admin#{options[:match_path]}") + PathChecker + .new(request.fullpath, self) + .active_path?(options[:match_path], options[:except_paths]) else args.include?(controller.controller_name.to_sym) end diff --git a/app/services/path_checker.rb b/app/services/path_checker.rb new file mode 100644 index 0000000000..d912160835 --- /dev/null +++ b/app/services/path_checker.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: false + +class PathChecker + def initialize(fullpath, view_context) + @fullpath = fullpath + @view_context = view_context + end + + def active_path?(match_path, except_paths = nil) + root_path = @view_context.main_app.root_path + active = @fullpath.starts_with?("#{root_path}admin#{match_path}") + return false unless active + return true if except_paths.blank? + + except_paths.each do |path| + return false if @fullpath.starts_with?("#{root_path}admin#{path}") + end + + true + end +end diff --git a/app/views/spree/admin/shared/_order_sub_menu.html.haml b/app/views/spree/admin/shared/_order_sub_menu.html.haml index ba9a15407b..978c77a560 100644 --- a/app/views/spree/admin/shared/_order_sub_menu.html.haml +++ b/app/views/spree/admin/shared/_order_sub_menu.html.haml @@ -1,6 +1,6 @@ - content_for :sub_menu do %ul#sub_nav.inline-menu - = tab :orders, :match_path => '/orders' + = tab :orders, match_path: '/orders', except_paths: ['/orders/bulk_management'] = tab :bulk_order_management, :match_path => '/orders/bulk_management' - if subscriptions_enabled? = tab :subscriptions, :match_path => '/subscriptions', url: main_app.admin_subscriptions_path diff --git a/spec/services/path_checker_spec.rb b/spec/services/path_checker_spec.rb new file mode 100644 index 0000000000..e0a4160e18 --- /dev/null +++ b/spec/services/path_checker_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe PathChecker do + describe "#active_path?" do + let(:view_context) { double("view context") } + + before do + allow(view_context).to receive_message_chain("main_app.root_path") { "/" } + end + + context "when fullpath starts with match_path and except_paths is blank" do + it "returns true" do + checker = described_class.new("/admin/products", view_context) + expect(checker.active_path?("/products")).to be true + expect(checker.active_path?("/products", nil)).to be true + expect(checker.active_path?("/products", [])).to be true + + checker = described_class.new("/admin/products/5/variants", view_context) + expect(checker.active_path?("/products")).to be true + expect(checker.active_path?("/products", nil)).to be true + expect(checker.active_path?("/products", [])).to be true + end + end + + context "when fullpath doesn't start with match_path" do + it "returns false" do + checker = described_class.new("/admin/products", view_context) + expect(checker.active_path?("/orders")).to be false + end + end + + context "when fullpath starts with match_path and doesn't start with any of except_paths" do + it "returns true" do + checker = described_class.new("/admin/products", view_context) + expect(checker.active_path?("/products", ["/orders/bulk_management"])).to be true + end + end + + context "when fullpath starts with match_path also with one of except_paths" do + it "returns false" do + checker = described_class.new("/admin/orders/bulk_management", view_context) + expect(checker.active_path?("/orders", ["/orders/bulk_management"])).to be false + end + end + end +end