diff --git a/backend/app/helpers/spree/admin/navigation_helper.rb b/backend/app/helpers/spree/admin/navigation_helper.rb index 2145902dbb0..b50a08bf67d 100644 --- a/backend/app/helpers/spree/admin/navigation_helper.rb +++ b/backend/app/helpers/spree/admin/navigation_helper.rb @@ -42,18 +42,22 @@ def admin_page_title # Make an admin tab that covers one or more resources supplied by symbols # Option hash may follow. Valid options are # * :label to override link text, otherwise based on the first resource name (translated) - # * :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. # * :match_path can also be a callable that takes a request and determines whether the menu item is selected for the request. - def tab(*args, &_block) - options = { label: args.first.to_s } + def tab(*args, &block) + block_content = capture(&block) if block_given? - if args.last.is_a?(Hash) - options = options.merge(args.pop) + options = args.pop if args.last.is_a?(Hash) + + if args.any? + warn "[DEPRECATION] Passing resources to #{self.class.name} is deprecated. Please pass a label instead." + end + + if options.key?(:route) + warn "[DEPRECATION] Passing a route to #{self.class.name} is deprecated. Please pass a url instead." end - options[:route] ||= "admin_#{args.first}" - destination_url = options[:url] || spree.send("#{options[:route]}_path") + destination_url = options[:url] || spree.send("admin_#{options[:label]}_path") label = t(options[:label], scope: [:spree, :admin, :tab]) css_classes = [] @@ -65,22 +69,12 @@ def tab(*args, &_block) link = link_to(label, destination_url) end - selected = if options[:match_path].is_a? Regexp - request.fullpath =~ options[:match_path] - elsif options[:match_path].respond_to?(:call) - options[:match_path].call(request) - elsif options[:match_path] - request.fullpath.starts_with?("#{spree.admin_path}#{options[:match_path]}") - else - request.fullpath.starts_with?(destination_url) || - args.include?(controller.controller_name.to_sym) - end - css_classes << 'selected' if selected + css_classes << 'selected' if options[:selected] if options[:css_class] css_classes << options[:css_class] end - content_tag('li', link + (yield if block_given?), class: css_classes.join(' ') ) + content_tag('li', link + block_content.to_s, class: css_classes.join(' ') ) end def link_to_clone(resource, options = {}) diff --git a/backend/app/views/spree/admin/shared/_order_submenu.html.erb b/backend/app/views/spree/admin/shared/_order_submenu.html.erb deleted file mode 100644 index 7f0741ad57c..00000000000 --- a/backend/app/views/spree/admin/shared/_order_submenu.html.erb +++ /dev/null @@ -1,63 +0,0 @@ - diff --git a/backend/app/views/spree/admin/shared/_product_sub_menu.html.erb b/backend/app/views/spree/admin/shared/_product_sub_menu.html.erb deleted file mode 100644 index dd44c97eeda..00000000000 --- a/backend/app/views/spree/admin/shared/_product_sub_menu.html.erb +++ /dev/null @@ -1,17 +0,0 @@ -
diff --git a/backend/app/views/spree/admin/shared/_promotion_sub_menu.html.erb b/backend/app/views/spree/admin/shared/_promotion_sub_menu.html.erb deleted file mode 100644 index 1c45767fc35..00000000000 --- a/backend/app/views/spree/admin/shared/_promotion_sub_menu.html.erb +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/backend/app/views/spree/admin/shared/_settings_sub_menu.html.erb b/backend/app/views/spree/admin/shared/_settings_sub_menu.html.erb deleted file mode 100644 index b7180af6265..00000000000 --- a/backend/app/views/spree/admin/shared/_settings_sub_menu.html.erb +++ /dev/null @@ -1,26 +0,0 @@ - diff --git a/backend/app/views/spree/admin/shared/_tabs.html.erb b/backend/app/views/spree/admin/shared/_tabs.html.erb index 60e84498c7e..16f5afb9e06 100644 --- a/backend/app/views/spree/admin/shared/_tabs.html.erb +++ b/backend/app/views/spree/admin/shared/_tabs.html.erb @@ -1,15 +1,23 @@ -<% Spree::Backend::Config.menu_items.sort_by { |item| item.position || Float::INFINITY }.each do |menu_item| %> - <% if instance_exec(&menu_item.condition) %> - <%= - tab( - *menu_item.sections, - icon: menu_item.icon, - label: menu_item.label, - url: menu_item.url.is_a?(Symbol) ? spree.public_send(menu_item.url) : menu_item.url, - match_path: menu_item.match_path, - ) do - %> - <%- render partial: menu_item.partial if menu_item.partial %> +<% Spree::Backend::Config.menu_items.sort_by { |item| item.position || Float::INFINITY }.select { instance_exec(&_1.condition) }.each do |menu_item| %> + <%= tab( + icon: menu_item.icon, + label: menu_item.label, + url: menu_item.url, + selected: menu_item.selected?(request), + ) do %> + <% if menu_item.partial %> + <%- render partial: menu_item.partial %> + <% elsif menu_item.children.present? %> + <%- end %> <% end %> <% end %> diff --git a/backend/lib/spree/backend_configuration.rb b/backend/lib/spree/backend_configuration.rb index b9e14fcb26b..52291dd06e6 100644 --- a/backend/lib/spree/backend_configuration.rb +++ b/backend/lib/spree/backend_configuration.rb @@ -32,29 +32,19 @@ def theme_path(user_theme = nil) } } - ORDER_TABS ||= [:orders, :payments, :creditcard_payments, - :shipments, :credit_cards, :return_authorizations, - :customer_returns, :adjustments, :customer_details] - PRODUCT_TABS ||= [:products, :option_types, :properties, - :variants, :product_properties, :taxonomies, - :taxons] - CONFIGURATION_TABS ||= [:stores, :tax_categories, - :tax_rates, :zones, - :payment_methods, :shipping_methods, - :shipping_categories, :stock_locations, - :refund_reasons, :reimbursement_types, - :return_reasons, :adjustment_reasons, - :store_credit_reasons] - PROMOTION_TABS ||= [:promotions, :promotion_categories] - STOCK_TABS ||= [:stock_items] - USER_TABS ||= [:users, :store_credits] + autoload :ORDER_TABS, 'spree/backend_configuration/deprecated_tab_constants' + autoload :PRODUCT_TABS, 'spree/backend_configuration/deprecated_tab_constants' + autoload :CONFIGURATION_TABS, 'spree/backend_configuration/deprecated_tab_constants' + autoload :PROMOTION_TABS, 'spree/backend_configuration/deprecated_tab_constants' + autoload :STOCK_TABS, 'spree/backend_configuration/deprecated_tab_constants' + autoload :USER_TABS, 'spree/backend_configuration/deprecated_tab_constants' # Items can be added to the menu by using code like the following: # # Spree::Backend::Config.configure do |config| # config.menu_items << config.class::MenuItem.new( - # [:section], - # 'icon-name', + # label: :section, + # icon: 'icon-name', # url: 'https://solidus.io/' # ) # end @@ -75,45 +65,78 @@ def theme_path(user_theme = nil) def menu_items @menu_items ||= [ MenuItem.new( - ORDER_TABS, - 'shopping-cart', + label: :orders, + icon: admin_updated_navbar ? 'ri-inbox-line' : 'shopping-cart', condition: -> { can?(:admin, Spree::Order) }, position: 0 ), MenuItem.new( - PRODUCT_TABS, - 'th-large', + label: :products, + icon: admin_updated_navbar ? 'ri-price-tag-3-line' : 'th-large', condition: -> { can?(:admin, Spree::Product) }, - partial: 'spree/admin/shared/product_sub_menu', - position: 1 + position: 1, + children: [ + MenuItem.new( + label: :products, + condition: -> { can? :admin, Spree::Product }, + match_path: '/products', + ), + MenuItem.new( + label: :option_types, + condition: -> { can? :admin, Spree::OptionType }, + match_path: '/option_types', + ), + MenuItem.new( + label: :properties, + condition: -> { can? :admin, Spree::Property }, + ), + MenuItem.new( + label: :taxonomies, + condition: -> { can? :admin, Spree::Taxonomy }, + ), + MenuItem.new( + url: :admin_taxons_path, + condition: -> { can? :admin, Spree::Taxon }, + label: :display_order, + match_path: '/taxons', + ), + ], ), MenuItem.new( - PROMOTION_TABS, - 'bullhorn', - partial: 'spree/admin/shared/promotion_sub_menu', + label: :promotions, + icon: admin_updated_navbar ? 'ri-megaphone-line' : 'bullhorn', + children: [ + MenuItem.new( + label: :promotions, + condition: -> { can?(:admin, Spree::Promotion) }, + ), + MenuItem.new( + label: :promotion_categories, + condition: -> { can?(:admin, Spree::PromotionCategory) }, + ), + ], condition: -> { can?(:admin, Spree::Promotion) }, url: :admin_promotions_path, - position: 2 + position: 2, ), MenuItem.new( - STOCK_TABS, - 'cubes', - condition: -> { can?(:admin, Spree::StockItem) }, label: :stock, + icon: admin_updated_navbar ? 'ri-stack-line' : 'cubes', + condition: -> { can?(:admin, Spree::StockItem) }, url: :admin_stock_items_path, match_path: '/stock_items', - position: 3 + position: 3, ), MenuItem.new( - USER_TABS, - 'user', + label: :users, + icon: admin_updated_navbar ? 'ri-user-line' : 'user', condition: -> { Spree.user_class && can?(:admin, Spree.user_class) }, url: :admin_users_path, - position: 4 + position: 4, ), MenuItem.new( - CONFIGURATION_TABS, - 'wrench', + label: :settings, + icon: admin_updated_navbar ? 'ri-settings-line' : 'wrench', condition: -> { can?(:admin, Spree::Store) || can?(:admin, Spree::AdjustmentReason) || @@ -128,10 +151,50 @@ def menu_items can?(:admin, Spree::ReturnReason) || can?(:admin, Spree::Zone) }, - label: :settings, - partial: 'spree/admin/shared/settings_sub_menu', url: :admin_stores_path, - position: 5 + position: 5, + children: [ + MenuItem.new( + label: :stores, + condition: -> { can? :admin, Spree::Store }, + url: :admin_stores_path, + ), + MenuItem.new( + label: :payment_methods, + condition: -> { can? :admin, Spree::PaymentMethod }, + url: :admin_payment_methods_path, + ), + + MenuItem.new( + label: :taxes, + condition: -> { can?(:admin, Spree::TaxCategory) || can?(:admin, Spree::TaxRate) }, + url: :admin_tax_categories_path, + match_path: %r(tax_categories|tax_rates), + ), + MenuItem.new( + label: :checkout, + condition: -> { + can?(:admin, Spree::RefundReason) || + can?(:admin, Spree::ReimbursementType) || + can?(:show, Spree::ReturnReason) || + can?(:show, Spree::AdjustmentReason) + }, + url: :admin_refund_reasons_path, + match_path: %r(refund_reasons|reimbursement_types|return_reasons|adjustment_reasons|store_credit_reasons) + ), + MenuItem.new( + label: :shipping, + condition: -> { can?(:admin, Spree::ShippingMethod) || + can?(:admin, Spree::ShippingCategory) || can?(:admin, Spree::StockLocation) }, + url: :admin_shipping_methods_path, + match_path: %r(shipping_methods|shipping_categories|stock_locations), + ), + MenuItem.new( + label: :zones, + condition: -> { can?(:admin, Spree::Zone) }, + url: :admin_zones_path, + ), + ], ) ] end diff --git a/backend/lib/spree/backend_configuration/deprecated_tab_constants.rb b/backend/lib/spree/backend_configuration/deprecated_tab_constants.rb new file mode 100644 index 00000000000..5efbed17278 --- /dev/null +++ b/backend/lib/spree/backend_configuration/deprecated_tab_constants.rb @@ -0,0 +1,30 @@ +warn "DEPRECATION WARNING: Spree::BackendConfiguration::*_TABS is deprecated and will be removed in Spree 5.0. Please use Spree::BackendConfiguration::MenuItem(children:) instead." + +Spree::BackendConfiguration::ORDER_TABS ||= [ + :orders, :payments, :creditcard_payments, + :shipments, :credit_cards, :return_authorizations, + :customer_returns, :adjustments, :customer_details +] +Spree::BackendConfiguration::PRODUCT_TABS ||= [ + :products, :option_types, :properties, + :variants, :product_properties, :taxonomies, + :taxons +] +Spree::BackendConfiguration::CONFIGURATION_TABS ||= [ + :stores, :tax_categories, + :tax_rates, :zones, + :payment_methods, :shipping_methods, + :shipping_categories, :stock_locations, + :refund_reasons, :reimbursement_types, + :return_reasons, :adjustment_reasons, + :store_credit_reasons +] +Spree::BackendConfiguration::PROMOTION_TABS ||= [ + :promotions, :promotion_categories +] +Spree::BackendConfiguration::STOCK_TABS ||= [ + :stock_items +] +Spree::BackendConfiguration::USER_TABS ||= [ + :users, :store_credits +] diff --git a/backend/lib/spree/backend_configuration/menu_item.rb b/backend/lib/spree/backend_configuration/menu_item.rb index d257f43b8c1..8d0b850bb5f 100644 --- a/backend/lib/spree/backend_configuration/menu_item.rb +++ b/backend/lib/spree/backend_configuration/menu_item.rb @@ -4,12 +4,12 @@ module Spree class BackendConfiguration < Preferences::Configuration # An item which should be drawn in the admin menu class MenuItem - attr_reader :icon, :label, :partial, :condition, :sections, :match_path + attr_reader :icon, :label, :partial, :children, :condition, :sections, :match_path attr_accessor :position # @param sections [Array