diff --git a/app/helpers/spree/admin/navigation_helper.rb b/app/helpers/spree/admin/navigation_helper.rb index 0060742ff6..53451567ce 100644 --- a/app/helpers/spree/admin/navigation_helper.rb +++ b/app/helpers/spree/admin/navigation_helper.rb @@ -1,5 +1,6 @@ module Spree module Admin + # rubocop:disable Metrics/ModuleLength module NavigationHelper # Makes an admin navigation tab (
  • tag) that links to a routing resource under /admin. # The arguments should be a list of symbolized controller names that will cause this tab to @@ -320,6 +321,63 @@ def user_tabs def product_tabs Rails.application.config.spree_backend.tabs[:product] end + + def orders_actions + Rails.application.config.spree_backend.actions[:orders] + end + + def order_actions + Rails.application.config.spree_backend.actions[:order] + end + + def users_actions + Rails.application.config.spree_backend.actions[:users] + end + + def user_actions + Rails.application.config.spree_backend.actions[:user] + end + + def products_actions + Rails.application.config.spree_backend.actions[:products] + end + + def product_actions + Rails.application.config.spree_backend.actions[:product] + end + + def images_actions + Rails.application.config.spree_backend.actions[:images] + end + + def prices_actions + Rails.application.config.spree_backend.actions[:prices] + end + + def store_credits_actions + Rails.application.config.spree_backend.actions[:store_credits] + end + + def adjustments_actions + Rails.application.config.spree_backend.actions[:adjustments] + end + + def payments_actions + Rails.application.config.spree_backend.actions[:payments] + end + + def stock_actions + Rails.application.config.spree_backend.actions[:stock] + end + + def variants_actions + Rails.application.config.spree_backend.actions[:variants] + end + + def product_properties_actions + Rails.application.config.spree_backend.actions[:product_properties] + end + # rubocop:enable Metrics/ModuleLength end end end diff --git a/app/helpers/spree/admin/orders_helper.rb b/app/helpers/spree/admin/orders_helper.rb index 16d73289a8..a262778bec 100644 --- a/app/helpers/spree/admin/orders_helper.rb +++ b/app/helpers/spree/admin/orders_helper.rb @@ -2,24 +2,6 @@ module Spree module Admin module OrdersHelper # Renders all the extension partials that may have been specified in the extensions - def event_links(order, events) - links = [] - events.each do |event| - next unless order.send("can_#{event}?") - - label = Spree.t(event, scope: 'admin.order.events', default: Spree.t(event)) - links << button_link_to( - label.capitalize, - [event.to_sym, :admin, order], - method: :put, - icon: event.to_s + '.svg', - data: { confirm: Spree.t(:order_sure_want_to, event: label) }, - class: 'btn-light' - ) - end - safe_join(links, ''.html_safe) - end - def line_item_shipment_price(line_item, quantity) Spree::Money.new(line_item.price * quantity, currency: line_item.currency) end diff --git a/app/models/spree/admin/actions/action.rb b/app/models/spree/admin/actions/action.rb new file mode 100644 index 0000000000..312884a662 --- /dev/null +++ b/app/models/spree/admin/actions/action.rb @@ -0,0 +1,35 @@ +module Spree + module Admin + module Actions + class Action + attr_reader :icon_name, :key, :classes, :text, :method, :id, :target, :data + + def initialize(config) + @icon_name = config[:icon_name] + @key = config[:key] + @url = config[:url] + @classes = config[:classes] + @availability_checks = config[:availability_checks] + @text = config[:text] + @method = config[:method] + @id = config[:id] + @translation_options = config[:translation_options] + @target = config[:target] + @data = config[:data] + end + + def available?(current_ability, resource = nil) + return true if @availability_checks.empty? + + result = @availability_checks.map { |check| check.call(current_ability, resource) } + + result.all?(true) + end + + def url(resource = nil) + @url.is_a?(Proc) ? @url.call(resource) : @url + end + end + end + end +end diff --git a/app/models/spree/admin/actions/action_builder.rb b/app/models/spree/admin/actions/action_builder.rb new file mode 100644 index 0000000000..1c896e8657 --- /dev/null +++ b/app/models/spree/admin/actions/action_builder.rb @@ -0,0 +1,48 @@ +module Spree + module Admin + module Actions + class ActionBuilder + include ::Spree::Admin::PermissionChecks + + def initialize(config) + @icon_name = config[:icon_name] + @key = config[:key] + @url = config[:url] + @classes = config[:classes] + @availability_checks = [] + @method = config[:method] + @id = config[:id] + @translation_options = config[:translation_options] + @target = config[:target] + @data = config[:data] + end + + def build + Action.new(build_config) + end + + private + + def build_config + { + icon_name: @icon_name, + key: @key, + url: @url, + classes: @classes, + availability_checks: @availability_checks, + text: text(@key, @translation_options), + method: @method, + id: @id, + translation_options: @translation_options, + target: @target, + data: @data + } + end + + def text(text, options) + options.present? ? ::Spree.t(text, options) : ::Spree.t(text) + end + end + end + end +end diff --git a/app/models/spree/admin/actions/adjustments_default_actions_builder.rb b/app/models/spree/admin/actions/adjustments_default_actions_builder.rb new file mode 100644 index 0000000000..328b5529e6 --- /dev/null +++ b/app/models/spree/admin/actions/adjustments_default_actions_builder.rb @@ -0,0 +1,35 @@ +module Spree + module Admin + module Actions + class AdjustmentsDefaultActionsBuilder + include Spree::Core::Engine.routes.url_helpers + + def build + root = Root.new + add_new_adjustment_action(root) + root + end + + private + + def add_new_adjustment_action(root) + action = + ActionBuilder.new(new_adjustment_config). + with_create_ability_check(::Spree::Adjustment). + build + + root.add(action) + end + + def new_adjustment_config + { + icon_name: 'add.svg', + key: :new_adjustment, + url: ->(resource) { new_admin_order_adjustment_path(resource) }, + classes: 'btn-success' + } + end + end + end + end +end diff --git a/app/models/spree/admin/actions/images_default_actions_builder.rb b/app/models/spree/admin/actions/images_default_actions_builder.rb new file mode 100644 index 0000000000..2e6b5d8964 --- /dev/null +++ b/app/models/spree/admin/actions/images_default_actions_builder.rb @@ -0,0 +1,36 @@ +module Spree + module Admin + module Actions + class ImagesDefaultActionsBuilder + include Spree::Core::Engine.routes.url_helpers + + def build + root = Root.new + add_new_image_action(root) + root + end + + private + + def add_new_image_action(root) + action = + ActionBuilder.new(new_image_config). + with_create_ability_check(::Spree::Image). + build + + root.add(action) + end + + def new_image_config + { + icon_name: 'add.svg', + key: :new_image, + url: ->(resource) { new_admin_product_image_path(resource) }, + classes: 'btn-success', + id: 'new_image_link' + } + end + end + end + end +end diff --git a/app/models/spree/admin/actions/order_default_actions_builder.rb b/app/models/spree/admin/actions/order_default_actions_builder.rb new file mode 100644 index 0000000000..6f0300fcac --- /dev/null +++ b/app/models/spree/admin/actions/order_default_actions_builder.rb @@ -0,0 +1,138 @@ +module Spree + module Admin + module Actions + class OrderDefaultActionsBuilder + include Spree::Core::Engine.routes.url_helpers + + def build + root = Root.new + add_approve_action(root) + add_cancel_action(root) + add_resume_action(root) + add_resend_action(root) + add_reset_download_links_action(root) + root + end + + private + + def add_approve_action(root) + action = + ActionBuilder.new(approve_config). + with_state_change_check('approve'). + with_fire_ability_check. + build + + root.add(action) + end + + def approve_config + { + icon_name: 'approve.svg', + key: :approve, + url: ->(resource) { approve_admin_order_path(resource) }, + classes: 'btn-light', + method: :put, + translation_options: { + scope: 'admin.order.events' + }, + data: { confirm: Spree.t(:order_sure_want_to, event: :approve) } + } + end + + def add_cancel_action(root) + action = + ActionBuilder.new(cancel_config). + with_state_change_check('cancel'). + with_fire_ability_check. + build + + root.add(action) + end + + def cancel_config + { + icon_name: 'cancel.svg', + key: :cancel, + url: ->(resource) { cancel_admin_order_path(resource) }, + classes: 'btn-light', + method: :put, + translation_options: { + scope: 'admin.order.events' + }, + data: { confirm: Spree.t(:order_sure_want_to, event: :cancel) } + } + end + + def add_resume_action(root) + action = + ActionBuilder.new(resume_config). + with_state_change_check('resume'). + with_fire_ability_check. + build + + root.add(action) + end + + def resume_config + { + icon_name: 'resume.svg', + key: :resume, + url: ->(resource) { resume_admin_order_path(resource) }, + classes: 'btn-light', + method: :put, + translation_options: { + scope: 'admin.order.events' + }, + data: { confirm: Spree.t(:order_sure_want_to, event: :resume) } + } + end + + def add_resend_action(root) + action = + ActionBuilder.new(resend_config). + with_resend_ability_check. + build + + root.add(action) + end + + def resend_config + { + icon_name: 'envelope.svg', + key: :resend, + url: ->(resource) { resend_admin_order_path(resource) }, + classes: 'btn-secondary', + method: :post, + translation_options: { + scope: 'admin.order.events', + default: ::Spree.t(:resend) + } + } + end + + def add_reset_download_links_action(root) + action = + ActionBuilder.new(reset_download_links_config). + with_availability_check( + lambda do |ability, resource| + ability.can?(:update, resource) && resource.some_digital? + end + ). + build + + root.add(action) + end + + def reset_download_links_config + { + icon_name: 'hdd.svg', + key: 'admin.digitals.reset_download_links', + url: ->(resource) { reset_digitals_admin_order_path(resource) }, + method: :put + } + end + end + end + end +end diff --git a/app/models/spree/admin/actions/orders_default_actions_builder.rb b/app/models/spree/admin/actions/orders_default_actions_builder.rb new file mode 100644 index 0000000000..c0a41c9e07 --- /dev/null +++ b/app/models/spree/admin/actions/orders_default_actions_builder.rb @@ -0,0 +1,36 @@ +module Spree + module Admin + module Actions + class OrdersDefaultActionsBuilder + include Spree::Core::Engine.routes.url_helpers + + def build + root = Root.new + add_new_order_action(root) + root + end + + private + + def add_new_order_action(root) + action = + ActionBuilder.new(new_order_config). + with_create_ability_check(::Spree::Order). + build + + root.add(action) + end + + def new_order_config + { + icon_name: 'add.svg', + key: :new_order, + url: new_admin_order_path, + classes: 'btn-success', + id: 'admin_new_order' + } + end + end + end + end +end diff --git a/app/models/spree/admin/actions/payments_default_actions_builder.rb b/app/models/spree/admin/actions/payments_default_actions_builder.rb new file mode 100644 index 0000000000..77e27b0f48 --- /dev/null +++ b/app/models/spree/admin/actions/payments_default_actions_builder.rb @@ -0,0 +1,40 @@ +module Spree + module Admin + module Actions + class PaymentsDefaultActionsBuilder + include Spree::Core::Engine.routes.url_helpers + + def build + root = Root.new + add_new_payment_action(root) + root + end + + private + + def add_new_payment_action(root) + action = + ActionBuilder.new(new_payment_config). + with_availability_check( + lambda do |ability, resource| + ability.can?(:create, ::Spree::Payment) && resource.outstanding_balance? + end + ). + build + + root.add(action) + end + + def new_payment_config + { + icon_name: 'add.svg', + key: :new_payment, + url: ->(resource) { new_admin_order_payment_path(resource) }, + classes: 'btn-success', + id: 'new_payment_section' + } + end + end + end + end +end diff --git a/app/models/spree/admin/actions/product_preview_action_builder.rb b/app/models/spree/admin/actions/product_preview_action_builder.rb new file mode 100644 index 0000000000..68f54b2d0e --- /dev/null +++ b/app/models/spree/admin/actions/product_preview_action_builder.rb @@ -0,0 +1,40 @@ +module Spree + module Admin + module Actions + class ProductPreviewActionBuilder + include Spree::Core::Engine.routes.url_helpers + + def build + root = Root.new + add_external_preview_action(root) + root + end + + private + + def add_external_preview_action(root) + action = + ActionBuilder.new(external_preview_config). + build + + root.add(action) + end + + def external_preview_config + { + icon_name: 'view.svg', + key: 'admin.utilities.preview', + url: ->(resource) { product_path(resource) }, + classes: 'btn-light', + id: 'adminPreviewProduct', + translation_options: { + name: :product + }, + target: :blank, + data: { turbo: false } + } + end + end + end + end +end diff --git a/app/models/spree/admin/actions/product_properties_default_actions_builder.rb b/app/models/spree/admin/actions/product_properties_default_actions_builder.rb new file mode 100644 index 0000000000..459ecc9bea --- /dev/null +++ b/app/models/spree/admin/actions/product_properties_default_actions_builder.rb @@ -0,0 +1,55 @@ +module Spree + module Admin + module Actions + class ProductPropertiesDefaultActionsBuilder + include Spree::Core::Engine.routes.url_helpers + + def build + root = Root.new + add_select_from_prototype_action(root) + add_add_product_properties_action(root) + root + end + + private + + def add_select_from_prototype_action(root) + action = + ActionBuilder.new(select_from_prototype_config). + build + + root.add(action) + end + + def select_from_prototype_config + { + icon_name: 'list.svg', + key: :select_from_prototype, + url: available_admin_prototypes_path, + classes: 'btn-light js-new-ptype-link', + data: { update: 'prototypes', remote: true } + } + end + + def add_add_product_properties_action(root) + action = + ActionBuilder.new(add_product_properties_config). + with_create_ability_check(::Spree::ProductProperty). + build + + root.add(action) + end + + def add_product_properties_config + { + icon_name: 'add.svg', + key: :add_product_properties, + url: 'javascript:;', + classes: 'btn-success spree_add_fields', + data: { target: 'tbody#sortVert' } + } + end + end + end + end +end diff --git a/app/models/spree/admin/actions/products_default_actions_builder.rb b/app/models/spree/admin/actions/products_default_actions_builder.rb new file mode 100644 index 0000000000..738c870655 --- /dev/null +++ b/app/models/spree/admin/actions/products_default_actions_builder.rb @@ -0,0 +1,36 @@ +module Spree + module Admin + module Actions + class ProductsDefaultActionsBuilder + include Spree::Core::Engine.routes.url_helpers + + def build + root = Root.new + add_new_product_action(root) + root + end + + private + + def add_new_product_action(root) + action = + ActionBuilder.new(new_product_config). + with_create_ability_check(::Spree::Product). + build + + root.add(action) + end + + def new_product_config + { + icon_name: 'add.svg', + key: :new_product, + url: new_admin_product_path, + classes: 'btn-success', + id: 'admin_new_product' + } + end + end + end + end +end diff --git a/app/models/spree/admin/actions/root.rb b/app/models/spree/admin/actions/root.rb new file mode 100644 index 0000000000..44af8ea45f --- /dev/null +++ b/app/models/spree/admin/actions/root.rb @@ -0,0 +1,15 @@ +module Spree + module Admin + module Actions + class Root + include ::Spree::Admin::ItemManager + + attr_reader :items + + def initialize + @items = [] + end + end + end + end +end diff --git a/app/models/spree/admin/actions/store_credits_default_actions_builder.rb b/app/models/spree/admin/actions/store_credits_default_actions_builder.rb new file mode 100644 index 0000000000..b6780104bf --- /dev/null +++ b/app/models/spree/admin/actions/store_credits_default_actions_builder.rb @@ -0,0 +1,35 @@ +module Spree + module Admin + module Actions + class StoreCreditsDefaultActionsBuilder + include Spree::Core::Engine.routes.url_helpers + + def build + root = Root.new + add_add_store_credit_action(root) + root + end + + private + + def add_add_store_credit_action(root) + action = + ActionBuilder.new(add_store_credit_config). + with_create_ability_check(::Spree::StoreCredit). + build + + root.add(action) + end + + def add_store_credit_config + { + icon_name: 'add.svg', + key: :add_store_credit, + url: ->(resource) { new_admin_user_store_credit_path(resource) }, + classes: 'btn-success' + } + end + end + end + end +end diff --git a/app/models/spree/admin/actions/user_default_actions_builder.rb b/app/models/spree/admin/actions/user_default_actions_builder.rb new file mode 100644 index 0000000000..030e38e39f --- /dev/null +++ b/app/models/spree/admin/actions/user_default_actions_builder.rb @@ -0,0 +1,36 @@ +module Spree + module Admin + module Actions + class UserDefaultActionsBuilder + include Spree::Core::Engine.routes.url_helpers + + def build + root = Root.new + add_new_order_action(root) + root + end + + private + + def add_new_order_action(root) + action = + ActionBuilder.new(new_order_config). + with_create_ability_check(Spree::Order). + build + + root.add(action) + end + + def new_order_config + { + icon_name: 'add.svg', + key: :create_new_order, + url: ->(resource) { new_admin_order_path(user_id: resource.id) }, + classes: 'btn-success', + method: :post + } + end + end + end + end +end diff --git a/app/models/spree/admin/actions/users_default_actions_builder.rb b/app/models/spree/admin/actions/users_default_actions_builder.rb new file mode 100644 index 0000000000..5676bf35dc --- /dev/null +++ b/app/models/spree/admin/actions/users_default_actions_builder.rb @@ -0,0 +1,36 @@ +module Spree + module Admin + module Actions + class UsersDefaultActionsBuilder + include Spree::Core::Engine.routes.url_helpers + + def build + root = Root.new + add_new_user_action(root) + root + end + + private + + def add_new_user_action(root) + action = + ActionBuilder.new(new_user_config). + with_create_ability_check(::Spree.user_class). + build + + root.add(action) + end + + def new_user_config + { + icon_name: 'add.svg', + key: :new_user, + url: new_admin_user_path, + classes: 'btn-success', + id: 'admin_new_user_link' + } + end + end + end + end +end diff --git a/app/models/spree/admin/actions/variants_default_actions_builder.rb b/app/models/spree/admin/actions/variants_default_actions_builder.rb new file mode 100644 index 0000000000..4cc2a98984 --- /dev/null +++ b/app/models/spree/admin/actions/variants_default_actions_builder.rb @@ -0,0 +1,37 @@ +module Spree + module Admin + module Actions + class VariantsDefaultActionsBuilder + include Spree::Core::Engine.routes.url_helpers + + def build + root = Root.new + add_new_variant_action(root) + root + end + + private + + def add_new_variant_action(root) + action = + ActionBuilder.new(new_variant_config). + with_create_ability_check(::Spree::Variant). + build + + root.add(action) + end + + def new_variant_config + { + icon_name: 'add.svg', + key: :new_variant, + url: ->(resource) { new_admin_product_variant_path(resource) }, + classes: 'btn-success', + id: 'new_var_link', + data: { update: 'new_variant' } + } + end + end + end + end +end diff --git a/app/models/spree/admin/main_menu/item.rb b/app/models/spree/admin/main_menu/item.rb index 74f22036cc..363a244eff 100644 --- a/app/models/spree/admin/main_menu/item.rb +++ b/app/models/spree/admin/main_menu/item.rb @@ -4,19 +4,21 @@ module MainMenu class Item attr_reader :key, :label_translation_key, :icon_key, :url, :match_path - def initialize(key, label_translation_key, url, icon_key, availability_check, match_path) # rubocop:disable Metrics/ParameterLists + def initialize(key, label_translation_key, url, icon_key, availability_checks, match_path) # rubocop:disable Metrics/ParameterLists @key = key @label_translation_key = label_translation_key @url = url @icon_key = icon_key - @availability_check = availability_check + @availability_checks = availability_checks @match_path = match_path end - def available?(current_ability, current_store) - return true unless @availability_check.present? + def available?(current_ability, resource) + return true if @availability_checks.empty? - @availability_check.call(current_ability, current_store) + result = @availability_checks.map { |check| check.call(current_ability, resource) } + + result.all?(true) end def children? diff --git a/app/models/spree/admin/main_menu/item_builder.rb b/app/models/spree/admin/main_menu/item_builder.rb index d3ed00c0ba..627b369474 100644 --- a/app/models/spree/admin/main_menu/item_builder.rb +++ b/app/models/spree/admin/main_menu/item_builder.rb @@ -5,12 +5,12 @@ class ItemBuilder include ::Spree::Admin::PermissionChecks def initialize(key, url) - @key = key + @key = key @label_translation_key = key - @url = url - @icon_key = nil - @availability_check = nil - @match_path = nil + @url = url + @icon_key = nil + @availability_checks = [] + @match_path = nil end def with_label_translation_key(key) @@ -29,7 +29,7 @@ def with_match_path(match_path) end def build - Item.new(@key, @label_translation_key, @url, @icon_key, @availability_check, @match_path) + Item.new(@key, @label_translation_key, @url, @icon_key, @availability_checks, @match_path) end end end diff --git a/app/models/spree/admin/main_menu/root.rb b/app/models/spree/admin/main_menu/root.rb index 188521a511..2509f676f2 100644 --- a/app/models/spree/admin/main_menu/root.rb +++ b/app/models/spree/admin/main_menu/root.rb @@ -5,7 +5,7 @@ class Root < Section attr_reader :items def initialize - super('root', 'root', nil, nil, []) + super('root', 'root', nil, [], []) end def add_to_section(section_key, item) diff --git a/app/models/spree/admin/main_menu/section.rb b/app/models/spree/admin/main_menu/section.rb index 7146556fdf..274eb67017 100644 --- a/app/models/spree/admin/main_menu/section.rb +++ b/app/models/spree/admin/main_menu/section.rb @@ -6,18 +6,20 @@ class Section attr_reader :key, :label_translation_key, :icon_key, :items - def initialize(key, label_translation_key, icon_key, availability_check, items) + def initialize(key, label_translation_key, icon_key, availability_checks, items) @key = key @label_translation_key = label_translation_key @icon_key = icon_key - @availability_check = availability_check + @availability_checks = availability_checks @items = items end - def available?(current_ability, current_store) - return true unless @availability_check.present? + def available?(current_ability, resource) + return true if @availability_checks.empty? - @availability_check.call(current_ability, current_store) + result = @availability_checks.map { |check| check.call(current_ability, resource) } + + result.all?(true) end def children? diff --git a/app/models/spree/admin/main_menu/section_builder.rb b/app/models/spree/admin/main_menu/section_builder.rb index d3864a2eb7..de5ab94b02 100644 --- a/app/models/spree/admin/main_menu/section_builder.rb +++ b/app/models/spree/admin/main_menu/section_builder.rb @@ -5,11 +5,11 @@ class SectionBuilder include ::Spree::Admin::PermissionChecks def initialize(key, icon_key) - @key = key + @key = key @label_translation_key = key - @icon_key = icon_key - @availability_check = nil - @items = [] + @icon_key = icon_key + @availability_checks = [] + @items = [] end def with_label_translation_key(key) @@ -28,7 +28,7 @@ def with_items(items) end def build - Section.new(@key, @label_translation_key, @icon_key, @availability_check, @items) + Section.new(@key, @label_translation_key, @icon_key, @availability_checks, @items) end end end diff --git a/app/models/spree/admin/permission_checks.rb b/app/models/spree/admin/permission_checks.rb index 475e27096f..afdb76f716 100644 --- a/app/models/spree/admin/permission_checks.rb +++ b/app/models/spree/admin/permission_checks.rb @@ -2,27 +2,47 @@ module Spree module Admin module PermissionChecks def with_availability_check(availability_check) - @availability_check = availability_check + @availability_checks << availability_check self end def with_manage_ability_check(*classes) - @availability_check = ->(ability, _current) { classes.any? { |c| ability.can?(:manage, c) } } + @availability_checks << ->(ability, _current) { classes.any? { |c| ability.can?(:manage, c) } } self end def with_admin_ability_check(*classes) - @availability_check = ->(ability, _current) { classes.any? { |c| ability.can?(:admin, c) } } + @availability_checks << ->(ability, _current) { classes.any? { |c| ability.can?(:admin, c) } } self end def with_index_ability_check(*classes) - @availability_check = ->(ability, _current) { classes.any? { |c| ability.can?(:index, c) } } + @availability_checks << ->(ability, _current) { classes.any? { |c| ability.can?(:index, c) } } + self + end + + def with_create_ability_check(*classes) + @availability_checks << ->(ability, _current) { classes.any? { |c| ability.can?(:create, c) } } self end def with_update_ability_check - @availability_check = ->(ability, resource) { ability.can?(:update, resource) } + @availability_checks << ->(ability, resource) { ability.can?(:update, resource) } + self + end + + def with_resend_ability_check + @availability_checks << ->(ability, resource) { ability.can?(:resend, resource) } + self + end + + def with_fire_ability_check + @availability_checks << ->(ability, resource) { ability.can?(:fire, resource) } + self + end + + def with_state_change_check(event) + @availability_checks << ->(_ability, resource) { resource.send("can_#{event}?") } self end end diff --git a/app/models/spree/admin/tabs/tab.rb b/app/models/spree/admin/tabs/tab.rb index b44ee61c31..8081ddd424 100644 --- a/app/models/spree/admin/tabs/tab.rb +++ b/app/models/spree/admin/tabs/tab.rb @@ -9,7 +9,7 @@ def initialize(config) @key = config[:key] @url = config[:url] @partial_name = config[:partial_name] - @availability_check = config[:availability_check] + @availability_checks = config[:availability_checks] @active_check = config[:active_check] @completed_check = config[:completed_check] @text = config[:text] @@ -18,9 +18,11 @@ def initialize(config) end def available?(current_ability, resource) - return true unless @availability_check.present? + return true if @availability_checks.empty? - @availability_check.call(current_ability, resource) + result = @availability_checks.map { |check| check.call(current_ability, resource) } + + result.all?(true) end def url(resource = nil) diff --git a/app/models/spree/admin/tabs/tab_builder.rb b/app/models/spree/admin/tabs/tab_builder.rb index 86d8c99b19..a01927cb88 100644 --- a/app/models/spree/admin/tabs/tab_builder.rb +++ b/app/models/spree/admin/tabs/tab_builder.rb @@ -7,13 +7,13 @@ class TabBuilder include DataHook def initialize(config) - @icon_name = config[:icon_name] - @key = config[:key] - @url = config[:url] - @partial_name = config[:partial_name] - @availability_check = nil - @active_check = nil - @completed_check = nil + @icon_name = config[:icon_name] + @key = config[:key] + @url = config[:url] + @partial_name = config[:partial_name] + @availability_checks = [] + @active_check = nil + @completed_check = nil end def build @@ -28,7 +28,7 @@ def build_config key: @key, url: @url, partial_name: @partial_name, - availability_check: @availability_check, + availability_checks: @availability_checks, active_check: @active_check, completed_check: @completed_check, text: text, diff --git a/app/views/spree/admin/adjustments/index.html.erb b/app/views/spree/admin/adjustments/index.html.erb index 8e3b29e298..9510d7a802 100644 --- a/app/views/spree/admin/adjustments/index.html.erb +++ b/app/views/spree/admin/adjustments/index.html.erb @@ -1,7 +1,15 @@ <%= render partial: 'spree/admin/shared/order_tabs', locals: { current: :adjustments} %> <% content_for :page_actions do %> - <%= button_link_to(Spree.t(:new_adjustment), new_admin_order_adjustment_url(@order), class: "btn-success", icon: 'add.svg') if can? :create, Spree::Adjustment %> + <% adjustments_actions.items.each do |action| %> + <% next unless action.available?(current_ability) %> + <%= button_link_to( + action.text, + action.url(@order), + class: action.classes, + icon: action.icon_name + ) %> + <% end %> <% end %> <% if @adjustments.present? %> diff --git a/app/views/spree/admin/images/index.html.erb b/app/views/spree/admin/images/index.html.erb index 9a259735a1..55b1fa4a55 100644 --- a/app/views/spree/admin/images/index.html.erb +++ b/app/views/spree/admin/images/index.html.erb @@ -1,9 +1,18 @@ <%= render partial: 'spree/admin/shared/product_tabs', locals: { current: :images } %> <% content_for :page_actions do %> - <%= yield :page_actions %> - <%= external_page_preview_link(@product) %> - <%= button_link_to(Spree.t(:new_image), spree.new_admin_product_image_url(@product), { class: "btn-success", icon: 'add.svg', id: 'new_image_link' }) if can? :create, Spree::Image %> + <% images_actions.items.each do |action| %> + <% next unless action.available?(current_ability) %> + <%= button_link_to( + action.text, + action.url(@product), + class: action.classes, + icon: action.icon_name, + id: action.id, + target: action.target, + data: action.data + ) %> + <% end %> <% end %> <% has_variants = @product.has_variants? %> diff --git a/app/views/spree/admin/orders/_order_actions.html.erb b/app/views/spree/admin/orders/_order_actions.html.erb index 96a74099f2..5d8de2c326 100644 --- a/app/views/spree/admin/orders/_order_actions.html.erb +++ b/app/views/spree/admin/orders/_order_actions.html.erb @@ -1,18 +1,13 @@ <% content_for :page_actions do %> - <% if can?(:fire, order) %> - <%= event_links(order, events) %> - <% end %> - <% if can?(:resend, order) %> - <%= button_link_to Spree.t(:resend, scope: 'admin.order.events', default: Spree.t(:resend)), - resend_admin_order_url(order), - method: :post, - icon: 'envelope.svg', class: 'btn-secondary' %> - <% end %> - - <% if (can? :update, @order) && @order.some_digital? %> - <%= button_link_to Spree.t('admin.digitals.reset_download_links'), - reset_digitals_admin_order_url(@order), - method: :put, - icon: 'hdd.svg' %> + <% order_actions.items.each do |action| %> + <% next unless action.available?(current_ability, order) %> + <%= button_link_to( + action.text, + action.url(order), + class: action.classes, + icon: action.icon_name, + method: action.method, + data: action.data + ) %> <% end %> <% end %> diff --git a/app/views/spree/admin/orders/index.html.erb b/app/views/spree/admin/orders/index.html.erb index 151c79827f..3366403203 100644 --- a/app/views/spree/admin/orders/index.html.erb +++ b/app/views/spree/admin/orders/index.html.erb @@ -3,12 +3,17 @@ <% end %> <% content_for :page_actions do %> - <%= button_link_to Spree.t(:new_order), - new_admin_order_url, - class: "btn-success", - icon: 'add.svg', - id: 'admin_new_order' %> -<% end if can? :create, Spree::Order %> + <% orders_actions.items.each do |action| %> + <% next unless action.available?(current_ability) %> + <%= button_link_to( + action.text, + action.url, + class: action.classes, + icon: action.icon_name, + id: action.id + ) %> + <% end %> +<% end %> <% content_for :page_tabs do %>