spree_backend 4.6.2 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +20 -101
- data/.codeclimate.yml +1 -1
- data/.rubocop.yml +5 -2
- data/Gemfile +10 -14
- data/app/assets/javascripts/spree/backend/global/tinymce.es6 +2 -2
- data/app/assets/javascripts/spree/backend/stock_transfer.js +1 -1
- data/app/controllers/spree/admin/products_controller.rb +22 -0
- data/app/helpers/spree/admin/navigation_helper.rb +77 -11
- data/app/helpers/spree/admin/orders_helper.rb +0 -18
- data/app/models/spree/admin/actions/action.rb +48 -0
- data/app/models/spree/admin/actions/action_builder.rb +79 -0
- data/app/models/spree/admin/actions/action_style.rb +11 -0
- data/app/models/spree/admin/actions/adjustments_default_actions_builder.rb +28 -0
- data/app/models/spree/admin/actions/images_default_actions_builder.rb +29 -0
- data/app/models/spree/admin/actions/order_default_actions_builder.rb +92 -0
- data/app/models/spree/admin/actions/orders_default_actions_builder.rb +29 -0
- data/app/models/spree/admin/actions/payments_default_actions_builder.rb +33 -0
- data/app/models/spree/admin/actions/product_properties_default_actions_builder.rb +42 -0
- data/app/models/spree/admin/actions/products_default_actions_builder.rb +29 -0
- data/app/models/spree/admin/actions/root.rb +15 -0
- data/app/models/spree/admin/actions/store_credits_default_actions_builder.rb +28 -0
- data/app/models/spree/admin/actions/user_default_actions_builder.rb +29 -0
- data/app/models/spree/admin/actions/users_default_actions_builder.rb +29 -0
- data/app/models/spree/admin/actions/variants_default_actions_builder.rb +30 -0
- data/app/models/spree/admin/item_manager.rb +50 -0
- data/app/models/spree/admin/main_menu/default_configuration_builder.rb +263 -0
- data/app/models/spree/admin/main_menu/item.rb +30 -0
- data/app/models/spree/admin/main_menu/item_builder.rb +37 -0
- data/app/models/spree/admin/main_menu/root.rb +17 -0
- data/app/models/spree/admin/main_menu/section.rb +31 -0
- data/app/models/spree/admin/main_menu/section_builder.rb +36 -0
- data/app/models/spree/admin/permission_checks.rb +50 -0
- data/app/models/spree/admin/tabs/order_default_tabs_builder.rb +147 -0
- data/app/models/spree/admin/tabs/product_default_tabs_builder.rb +144 -0
- data/app/models/spree/admin/tabs/root.rb +15 -0
- data/app/models/spree/admin/tabs/tab.rb +38 -0
- data/app/models/spree/admin/tabs/tab_builder.rb +63 -0
- data/app/models/spree/admin/tabs/user_default_tabs_builder.rb +77 -0
- data/app/views/spree/admin/adjustments/index.html.erb +9 -1
- data/app/views/spree/admin/cms_sections/types/_image_gallery.html.erb +27 -33
- data/app/views/spree/admin/cms_sections/types/_side_by_side_images.html.erb +18 -22
- data/app/views/spree/admin/images/index.html.erb +12 -3
- data/app/views/spree/admin/orders/_order_actions.html.erb +10 -15
- data/app/views/spree/admin/orders/index.html.erb +11 -6
- data/app/views/spree/admin/payments/index.html.erb +9 -4
- data/app/views/spree/admin/prices/index.html.erb +12 -2
- data/app/views/spree/admin/product_properties/index.html.erb +13 -13
- data/app/views/spree/admin/products/_add_stock_form.html.erb +12 -1
- data/app/views/spree/admin/products/edit.html.erb +12 -1
- data/app/views/spree/admin/products/index.html.erb +11 -2
- data/app/views/spree/admin/shared/_main_menu.html.erb +19 -77
- data/app/views/spree/admin/shared/_order_tabs.html.erb +10 -83
- data/app/views/spree/admin/shared/_product_tabs.html.erb +12 -64
- data/app/views/spree/admin/store_credits/index.html.erb +9 -1
- data/app/views/spree/admin/users/_tabs.html.erb +11 -30
- data/app/views/spree/admin/users/_user_page_actions.html.erb +9 -1
- data/app/views/spree/admin/users/index.html.erb +11 -2
- data/app/views/spree/admin/variants/index.html.erb +12 -2
- data/app/views/spree/admin/webhooks_subscribers/index.html.erb +0 -11
- data/config/locales/en.yml +6 -4
- data/lib/spree/backend/configuration.rb +0 -17
- data/lib/spree/backend/engine.rb +28 -1
- data/lib/spree/backend/version.rb +1 -1
- data/spree_backend.gemspec +2 -2
- data/yarn.lock +58 -22
- metadata +36 -17
- data/app/views/spree/admin/shared/sub_menu/_apps.html.erb +0 -3
- data/app/views/spree/admin/shared/sub_menu/_configuration.html.erb +0 -19
- data/app/views/spree/admin/shared/sub_menu/_content.html.erb +0 -4
- data/app/views/spree/admin/shared/sub_menu/_integrations.html.erb +0 -5
- data/app/views/spree/admin/shared/sub_menu/_orders.html.erb +0 -5
- data/app/views/spree/admin/shared/sub_menu/_organizations.html.erb +0 -3
- data/app/views/spree/admin/shared/sub_menu/_product.html.erb +0 -8
- data/app/views/spree/admin/shared/sub_menu/_promotion.html.erb +0 -4
- data/app/views/spree/admin/shared/sub_menu/_returns.html.erb +0 -4
- data/app/views/spree/admin/shared/sub_menu/_stock.html.erb +0 -4
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
module Actions
|
|
4
|
+
class ImagesDefaultActionsBuilder
|
|
5
|
+
include Spree::Core::Engine.routes.url_helpers
|
|
6
|
+
|
|
7
|
+
def build
|
|
8
|
+
root = Root.new
|
|
9
|
+
add_new_image_action(root)
|
|
10
|
+
root
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def add_new_image_action(root)
|
|
16
|
+
action =
|
|
17
|
+
ActionBuilder.new('new_image', ->(resource) { new_admin_product_image_path(resource) }).
|
|
18
|
+
with_icon_key('add.svg').
|
|
19
|
+
with_style(::Spree::Admin::Actions::ActionStyle::PRIMARY).
|
|
20
|
+
with_id('new_image_link').
|
|
21
|
+
with_create_ability_check(::Spree::Image).
|
|
22
|
+
build
|
|
23
|
+
|
|
24
|
+
root.add(action)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
module Actions
|
|
4
|
+
class OrderDefaultActionsBuilder
|
|
5
|
+
include Spree::Core::Engine.routes.url_helpers
|
|
6
|
+
|
|
7
|
+
def build
|
|
8
|
+
root = Root.new
|
|
9
|
+
add_approve_action(root)
|
|
10
|
+
add_cancel_action(root)
|
|
11
|
+
add_resume_action(root)
|
|
12
|
+
add_resend_action(root)
|
|
13
|
+
add_reset_download_links_action(root)
|
|
14
|
+
root
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def add_approve_action(root)
|
|
20
|
+
action =
|
|
21
|
+
ActionBuilder.new('approve', ->(resource) { approve_admin_order_path(resource) }).
|
|
22
|
+
with_icon_key('approve.svg').
|
|
23
|
+
with_label_translation_key('admin.order.events.approve').
|
|
24
|
+
with_method(:put).
|
|
25
|
+
with_data_attributes({ confirm: Spree.t(:order_sure_want_to, event: :approve) }).
|
|
26
|
+
with_state_change_check('approve').
|
|
27
|
+
with_fire_ability_check.
|
|
28
|
+
build
|
|
29
|
+
|
|
30
|
+
root.add(action)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def add_cancel_action(root)
|
|
34
|
+
action =
|
|
35
|
+
ActionBuilder.new('cancel', ->(resource) { cancel_admin_order_path(resource) }).
|
|
36
|
+
with_icon_key('cancel.svg').
|
|
37
|
+
with_label_translation_key('admin.order.events.cancel').
|
|
38
|
+
with_method(:put).
|
|
39
|
+
with_data_attributes({ confirm: Spree.t(:order_sure_want_to, event: :cancel) }).
|
|
40
|
+
with_state_change_check('cancel').
|
|
41
|
+
with_fire_ability_check.
|
|
42
|
+
build
|
|
43
|
+
|
|
44
|
+
root.add(action)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def add_resume_action(root)
|
|
48
|
+
action =
|
|
49
|
+
ActionBuilder.new('resume', ->(resource) { resume_admin_order_path(resource) }).
|
|
50
|
+
with_icon_key('resume.svg').
|
|
51
|
+
with_label_translation_key('admin.order.events.resume').
|
|
52
|
+
with_method(:put).
|
|
53
|
+
with_data_attributes({ confirm: Spree.t(:order_sure_want_to, event: :resume) }).
|
|
54
|
+
with_state_change_check('resume').
|
|
55
|
+
with_fire_ability_check.
|
|
56
|
+
build
|
|
57
|
+
|
|
58
|
+
root.add(action)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def add_resend_action(root)
|
|
62
|
+
action =
|
|
63
|
+
ActionBuilder.new('resend', ->(resource) { resend_admin_order_path(resource) }).
|
|
64
|
+
with_icon_key('envelope.svg').
|
|
65
|
+
with_label_translation_key('admin.order.events.resend').
|
|
66
|
+
with_method(:post).
|
|
67
|
+
with_style(::Spree::Admin::Actions::ActionStyle::SECONDARY).
|
|
68
|
+
with_resend_ability_check.
|
|
69
|
+
build
|
|
70
|
+
|
|
71
|
+
root.add(action)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def add_reset_download_links_action(root)
|
|
75
|
+
action =
|
|
76
|
+
ActionBuilder.new('reset_download_links', ->(resource) { reset_digitals_admin_order_path(resource) }).
|
|
77
|
+
with_icon_key('hdd.svg').
|
|
78
|
+
with_label_translation_key('admin.digitals.reset_download_links').
|
|
79
|
+
with_method(:put).
|
|
80
|
+
with_availability_check(
|
|
81
|
+
lambda do |ability, resource|
|
|
82
|
+
ability.can?(:update, resource) && resource.some_digital?
|
|
83
|
+
end
|
|
84
|
+
).
|
|
85
|
+
build
|
|
86
|
+
|
|
87
|
+
root.add(action)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
module Actions
|
|
4
|
+
class OrdersDefaultActionsBuilder
|
|
5
|
+
include Spree::Core::Engine.routes.url_helpers
|
|
6
|
+
|
|
7
|
+
def build
|
|
8
|
+
root = Root.new
|
|
9
|
+
add_new_order_action(root)
|
|
10
|
+
root
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def add_new_order_action(root)
|
|
16
|
+
action =
|
|
17
|
+
ActionBuilder.new('new_order', new_admin_order_path).
|
|
18
|
+
with_icon_key('add.svg').
|
|
19
|
+
with_id('admin_new_order').
|
|
20
|
+
with_style(::Spree::Admin::Actions::ActionStyle::PRIMARY).
|
|
21
|
+
with_create_ability_check(::Spree::Order).
|
|
22
|
+
build
|
|
23
|
+
|
|
24
|
+
root.add(action)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
module Actions
|
|
4
|
+
class PaymentsDefaultActionsBuilder
|
|
5
|
+
include Spree::Core::Engine.routes.url_helpers
|
|
6
|
+
|
|
7
|
+
def build
|
|
8
|
+
root = Root.new
|
|
9
|
+
add_new_payment_action(root)
|
|
10
|
+
root
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def add_new_payment_action(root)
|
|
16
|
+
action =
|
|
17
|
+
ActionBuilder.new('new_payment', ->(resource) { new_admin_order_payment_path(resource) }).
|
|
18
|
+
with_icon_key('add.svg').
|
|
19
|
+
with_style(::Spree::Admin::Actions::ActionStyle::PRIMARY).
|
|
20
|
+
with_id('new_payment_section').
|
|
21
|
+
with_availability_check(
|
|
22
|
+
lambda do |ability, resource|
|
|
23
|
+
ability.can?(:create, ::Spree::Payment) && resource.outstanding_balance?
|
|
24
|
+
end
|
|
25
|
+
).
|
|
26
|
+
build
|
|
27
|
+
|
|
28
|
+
root.add(action)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
module Actions
|
|
4
|
+
class ProductPropertiesDefaultActionsBuilder
|
|
5
|
+
include Spree::Core::Engine.routes.url_helpers
|
|
6
|
+
|
|
7
|
+
def build
|
|
8
|
+
root = Root.new
|
|
9
|
+
add_select_from_prototype_action(root)
|
|
10
|
+
add_add_product_properties_action(root)
|
|
11
|
+
root
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def add_select_from_prototype_action(root)
|
|
17
|
+
action =
|
|
18
|
+
ActionBuilder.new('select_from_prototype', available_admin_prototypes_path).
|
|
19
|
+
with_icon_key('list.svg').
|
|
20
|
+
with_classes('js-new-ptype-link').
|
|
21
|
+
with_data_attributes({ update: 'prototypes', remote: true }).
|
|
22
|
+
build
|
|
23
|
+
|
|
24
|
+
root.add(action)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def add_add_product_properties_action(root)
|
|
28
|
+
action =
|
|
29
|
+
ActionBuilder.new('add_product_properties', 'javascript:;').
|
|
30
|
+
with_icon_key('add.svg').
|
|
31
|
+
with_style(::Spree::Admin::Actions::ActionStyle::PRIMARY).
|
|
32
|
+
with_classes('spree_add_fields').
|
|
33
|
+
with_data_attributes({ target: 'tbody#sortVert' }).
|
|
34
|
+
with_create_ability_check(::Spree::ProductProperty).
|
|
35
|
+
build
|
|
36
|
+
|
|
37
|
+
root.add(action)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
module Actions
|
|
4
|
+
class ProductsDefaultActionsBuilder
|
|
5
|
+
include Spree::Core::Engine.routes.url_helpers
|
|
6
|
+
|
|
7
|
+
def build
|
|
8
|
+
root = Root.new
|
|
9
|
+
add_new_product_action(root)
|
|
10
|
+
root
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def add_new_product_action(root)
|
|
16
|
+
action =
|
|
17
|
+
ActionBuilder.new('new_product', new_admin_product_path).
|
|
18
|
+
with_icon_key('add.svg').
|
|
19
|
+
with_style(::Spree::Admin::Actions::ActionStyle::PRIMARY).
|
|
20
|
+
with_id('admin_new_product').
|
|
21
|
+
with_create_ability_check(::Spree::Product).
|
|
22
|
+
build
|
|
23
|
+
|
|
24
|
+
root.add(action)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
module Actions
|
|
4
|
+
class StoreCreditsDefaultActionsBuilder
|
|
5
|
+
include Spree::Core::Engine.routes.url_helpers
|
|
6
|
+
|
|
7
|
+
def build
|
|
8
|
+
root = Root.new
|
|
9
|
+
add_add_store_credit_action(root)
|
|
10
|
+
root
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def add_add_store_credit_action(root)
|
|
16
|
+
action =
|
|
17
|
+
ActionBuilder.new('add_store_credit', ->(resource) { new_admin_user_store_credit_path(resource) }).
|
|
18
|
+
with_icon_key('add.svg').
|
|
19
|
+
with_style(::Spree::Admin::Actions::ActionStyle::PRIMARY).
|
|
20
|
+
with_create_ability_check(::Spree::StoreCredit).
|
|
21
|
+
build
|
|
22
|
+
|
|
23
|
+
root.add(action)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
module Actions
|
|
4
|
+
class UserDefaultActionsBuilder
|
|
5
|
+
include Spree::Core::Engine.routes.url_helpers
|
|
6
|
+
|
|
7
|
+
def build
|
|
8
|
+
root = Root.new
|
|
9
|
+
add_new_order_action(root)
|
|
10
|
+
root
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def add_new_order_action(root)
|
|
16
|
+
action =
|
|
17
|
+
ActionBuilder.new('create_new_order', ->(resource) { new_admin_order_path(user_id: resource.id) }).
|
|
18
|
+
with_icon_key('add.svg').
|
|
19
|
+
with_style(::Spree::Admin::Actions::ActionStyle::PRIMARY).
|
|
20
|
+
with_method(:post).
|
|
21
|
+
with_create_ability_check(Spree::Order).
|
|
22
|
+
build
|
|
23
|
+
|
|
24
|
+
root.add(action)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
module Actions
|
|
4
|
+
class UsersDefaultActionsBuilder
|
|
5
|
+
include Spree::Core::Engine.routes.url_helpers
|
|
6
|
+
|
|
7
|
+
def build
|
|
8
|
+
root = Root.new
|
|
9
|
+
add_new_user_action(root)
|
|
10
|
+
root
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def add_new_user_action(root)
|
|
16
|
+
action =
|
|
17
|
+
ActionBuilder.new('new_user', new_admin_user_path).
|
|
18
|
+
with_icon_key('add.svg').
|
|
19
|
+
with_style(::Spree::Admin::Actions::ActionStyle::PRIMARY).
|
|
20
|
+
with_id('admin_new_user_link').
|
|
21
|
+
with_create_ability_check(::Spree.user_class).
|
|
22
|
+
build
|
|
23
|
+
|
|
24
|
+
root.add(action)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
module Actions
|
|
4
|
+
class VariantsDefaultActionsBuilder
|
|
5
|
+
include Spree::Core::Engine.routes.url_helpers
|
|
6
|
+
|
|
7
|
+
def build
|
|
8
|
+
root = Root.new
|
|
9
|
+
add_new_variant_action(root)
|
|
10
|
+
root
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def add_new_variant_action(root)
|
|
16
|
+
action =
|
|
17
|
+
ActionBuilder.new('new_variant', ->(resource) { new_admin_product_variant_path(resource) }).
|
|
18
|
+
with_icon_key('add.svg').
|
|
19
|
+
with_style(::Spree::Admin::Actions::ActionStyle::PRIMARY).
|
|
20
|
+
with_id('new_var_link').
|
|
21
|
+
with_data_attributes({ update: 'new_variant' }).
|
|
22
|
+
with_create_ability_check(::Spree::Variant).
|
|
23
|
+
build
|
|
24
|
+
|
|
25
|
+
root.add(action)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
module ItemManager
|
|
4
|
+
def add(item)
|
|
5
|
+
raise KeyError, "Item with key #{item.key} already exists" if index_for_key(item.key)
|
|
6
|
+
|
|
7
|
+
@items << item
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def child_with_key?(key)
|
|
11
|
+
index_for_key(key).present?
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def remove(item_key)
|
|
15
|
+
item_index = index_for_key!(item_key)
|
|
16
|
+
|
|
17
|
+
@items.delete_at(item_index)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def item_for_key(key)
|
|
21
|
+
@items.find { |e| e.key == key }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def insert_before(item_key, item_to_add)
|
|
25
|
+
item_index = index_for_key!(item_key)
|
|
26
|
+
|
|
27
|
+
@items.insert(item_index, item_to_add)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def insert_after(item_key, item_to_add)
|
|
31
|
+
item_index = index_for_key!(item_key)
|
|
32
|
+
|
|
33
|
+
@items.insert(item_index + 1, item_to_add)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def index_for_key(key)
|
|
39
|
+
@items.index { |e| e.key == key }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def index_for_key!(key)
|
|
43
|
+
item_index = index_for_key(key)
|
|
44
|
+
raise KeyError, "Item not found for key #{key}" unless item_index
|
|
45
|
+
|
|
46
|
+
item_index
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|