spree_admin 5.2.0.rc3 → 5.2.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/app/assets/stylesheets/spree/admin/application.scss +1 -1
- data/app/assets/stylesheets/spree/admin/components/_dropdowns.scss +2 -0
- data/app/assets/stylesheets/spree/admin/components/_main.scss +2 -233
- data/app/assets/stylesheets/spree/admin/components/_sidebar.scss +693 -0
- data/app/assets/stylesheets/spree/admin/global/_variables.scss +1 -0
- data/app/assets/stylesheets/spree/admin/shared/_base.scss +7 -1
- data/app/assets/stylesheets/spree/admin/views/_dashboard.scss +14 -0
- data/app/controllers/spree/admin/integrations_controller.rb +1 -1
- data/app/controllers/spree/admin/metafields_controller.rb +1 -1
- data/app/controllers/spree/admin/page_blocks_controller.rb +1 -1
- data/app/controllers/spree/admin/payment_methods_controller.rb +1 -1
- data/app/controllers/spree/admin/promotion_actions_controller.rb +1 -1
- data/app/controllers/spree/admin/promotion_rules_controller.rb +1 -1
- data/app/controllers/spree/admin/promotions_controller.rb +1 -1
- data/app/controllers/spree/admin/reports_controller.rb +1 -1
- data/app/controllers/spree/admin/taxons_controller.rb +1 -1
- data/app/controllers/spree/admin/translations_controller.rb +1 -1
- data/app/helpers/spree/admin/base_helper.rb +1 -1
- data/app/helpers/spree/admin/drawer_helper.rb +6 -6
- data/app/helpers/spree/admin/dropdown_helper.rb +10 -2
- data/app/helpers/spree/admin/modal_helper.rb +2 -0
- data/app/helpers/spree/admin/navigation_helper.rb +46 -3
- data/app/helpers/spree/admin/orders_filters_helper.rb +1 -0
- data/app/helpers/spree/admin/promotion_actions_helper.rb +1 -1
- data/app/helpers/spree/admin/promotion_rules_helper.rb +1 -1
- data/app/helpers/spree/admin/translations_helper.rb +1 -1
- data/app/javascript/spree/admin/application.js +2 -1
- data/app/javascript/spree/admin/controllers/dropdown_controller.js +85 -14
- data/app/javascript/spree/admin/controllers/sidebar_controller.js +231 -0
- data/app/javascript/spree/admin/controllers/tooltip_controller.js +84 -31
- data/app/models/spree/admin/form_builder.rb +74 -16
- data/app/models/spree/admin/navigation/builder.rb +82 -0
- data/app/models/spree/admin/navigation/item.rb +177 -0
- data/app/models/spree/admin/navigation.rb +193 -0
- data/app/views/layouts/spree/admin.html.erb +1 -1
- data/app/views/spree/admin/assets/edit.html.erb +1 -1
- data/app/views/spree/admin/custom_domains/_form.html.erb +2 -14
- data/app/views/spree/admin/gift_cards/_filters.html.erb +26 -18
- data/app/views/spree/admin/gift_cards/index.html.erb +1 -1
- data/app/views/spree/admin/orders/_customer.html.erb +2 -2
- data/app/views/spree/admin/orders/_filters.html.erb +34 -25
- data/app/views/spree/admin/orders/_table_filter_dropdown.html.erb +1 -1
- data/app/views/spree/admin/page_blocks/forms/_image.html.erb +2 -5
- data/app/views/spree/admin/page_links/_form.html.erb +4 -13
- data/app/views/spree/admin/page_sections/forms/_header.html.erb +0 -2
- data/app/views/spree/admin/payments/_payment.html.erb +7 -0
- data/app/views/spree/admin/posts/_form.html.erb +1 -4
- data/app/views/spree/admin/posts/filters.html.erb +18 -8
- data/app/views/spree/admin/products/_bulk_operations.html.erb +1 -1
- data/app/views/spree/admin/products/_filters.html.erb +17 -6
- data/app/views/spree/admin/products/_table_filter_dropdown.html.erb +1 -1
- data/app/views/spree/admin/profile/edit.html.erb +9 -61
- data/app/views/spree/admin/promotions/_filters.html.erb +23 -13
- data/app/views/spree/admin/promotions/_table_filter_dropdown.html.erb +1 -1
- data/app/views/spree/admin/promotions/form/_settings.html.erb +2 -13
- data/app/views/spree/admin/refunds/_form.html.erb +1 -9
- data/app/views/spree/admin/return_authorizations/filters.html.erb +1 -1
- data/app/views/spree/admin/shared/_audit_nav.html.erb +2 -0
- data/app/views/spree/admin/shared/_calendar_range_picker.html.erb +2 -2
- data/app/views/spree/admin/shared/_content_header.html.erb +1 -1
- data/app/views/spree/admin/shared/_developers_nav.html.erb +2 -4
- data/app/views/spree/admin/shared/_header.html.erb +5 -7
- data/app/views/spree/admin/shared/_navigation.html.erb +5 -0
- data/app/views/spree/admin/shared/_navigation_item.html.erb +64 -0
- data/app/views/spree/admin/shared/_new_item_dropdown.html.erb +1 -1
- data/app/views/spree/admin/shared/_page_section_image.html.erb +2 -5
- data/app/views/spree/admin/shared/_page_section_logo.html.erb +1 -1
- data/app/views/spree/admin/shared/_returns_and_refunds_nav.html.erb +2 -3
- data/app/views/spree/admin/shared/_shipping_nav.html.erb +3 -2
- data/app/views/spree/admin/shared/_sidebar.html.erb +33 -7
- data/app/views/spree/admin/shared/_stock_nav.html.erb +6 -3
- data/app/views/spree/admin/shared/_tax_nav.html.erb +1 -2
- data/app/views/spree/admin/shared/_team_nav.html.erb +2 -3
- data/app/views/spree/admin/shared/_user_dropdown.html.erb +26 -17
- data/app/views/spree/admin/shared/sidebar/_customers_nav.html.erb +7 -0
- data/app/views/spree/admin/shared/sidebar/_orders_nav.html.erb +22 -2
- data/app/views/spree/admin/shared/sidebar/_products_nav.html.erb +21 -0
- data/app/views/spree/admin/shared/sidebar/_promotions_nav.html.erb +8 -0
- data/app/views/spree/admin/shared/sidebar/_returns_nav.html.erb +12 -0
- data/app/views/spree/admin/shared/sidebar/_store_dropdown.html.erb +3 -1
- data/app/views/spree/admin/shared/sidebar/_store_nav.html.erb +15 -1
- data/app/views/spree/admin/shared/sidebar/_storefront_nav.html.erb +25 -3
- data/app/views/spree/admin/shared/sortable_tree/_taxonomy.html.erb +1 -1
- data/app/views/spree/admin/stock_items/_filters.html.erb +18 -8
- data/app/views/spree/admin/stock_locations/_table_row.html.erb +1 -1
- data/app/views/spree/admin/stock_transfers/_filters.html.erb +19 -9
- data/app/views/spree/admin/storefront/edit.html.erb +2 -14
- data/app/views/spree/admin/stores/form/_basic.html.erb +2 -8
- data/app/views/spree/admin/stores/form/_emails.html.erb +1 -1
- data/app/views/spree/admin/tax_rates/_form.html.erb +1 -10
- data/app/views/spree/admin/taxons/_form.html.erb +2 -9
- data/app/views/spree/admin/themes/_theme.html.erb +1 -1
- data/app/views/spree/admin/translations/translation_rows/_permalink_field_row.html.erb +1 -12
- data/app/views/spree/admin/users/_filters.html.erb +23 -13
- data/config/initializers/spree_admin_navigation.rb +510 -0
- data/config/locales/en.yml +4 -0
- data/lib/generators/spree/admin/scaffold/templates/controller.rb.tt +3 -1
- data/lib/generators/spree/admin/scaffold/templates/views/_table_row.html.erb.tt +8 -6
- data/lib/spree/admin/engine.rb +64 -2
- data/lib/spree/admin/runtime_configuration.rb +1 -0
- data/lib/spree/admin.rb +20 -0
- metadata +17 -15
- data/app/assets/stylesheets/spree/admin/components/_offcanvas.scss +0 -26
- data/app/javascript/spree/admin/helpers/canvas.js +0 -29
- data/app/views/spree/admin/shared/_offcanvas_nav.html.erb +0 -12
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
# Default Admin Navigation Configuration
|
|
2
|
+
# This file defines the default sidebar and settings navigation for Spree Admin
|
|
3
|
+
|
|
4
|
+
Rails.application.config.after_initialize do
|
|
5
|
+
# ===============================================
|
|
6
|
+
# Sidebar Navigation
|
|
7
|
+
# ===============================================
|
|
8
|
+
sidebar_nav = Spree.admin.navigation.sidebar
|
|
9
|
+
|
|
10
|
+
# Getting Started (onboarding)
|
|
11
|
+
sidebar_nav.add :getting_started,
|
|
12
|
+
label: 'admin.getting_started',
|
|
13
|
+
url: :admin_getting_started_path,
|
|
14
|
+
icon: 'map',
|
|
15
|
+
position: 5,
|
|
16
|
+
if: -> { current_store && can?(:manage, current_store) && !current_store.setup_completed? },
|
|
17
|
+
badge: -> { "#{current_store.setup_tasks_done}/#{current_store.setup_tasks_total}" },
|
|
18
|
+
badge_class: 'badge-info',
|
|
19
|
+
active: -> { controller_name == 'dashboard' && action_name == 'getting_started' }
|
|
20
|
+
|
|
21
|
+
# Dashboard / Home
|
|
22
|
+
sidebar_nav.add :home,
|
|
23
|
+
label: :home,
|
|
24
|
+
url: :admin_path,
|
|
25
|
+
icon: 'home',
|
|
26
|
+
position: 10,
|
|
27
|
+
active: -> { controller_name == 'dashboard' && action_name == 'show' }
|
|
28
|
+
|
|
29
|
+
# Orders with submenu
|
|
30
|
+
sidebar_nav.add :orders,
|
|
31
|
+
label: :orders,
|
|
32
|
+
url: :admin_orders_path,
|
|
33
|
+
icon: 'inbox',
|
|
34
|
+
position: 20,
|
|
35
|
+
if: -> { can?(:manage, Spree::Order) },
|
|
36
|
+
badge: -> {
|
|
37
|
+
# Evaluated in view context with access to helper methods
|
|
38
|
+
ready_to_ship_orders_count if ready_to_ship_orders_count&.positive?
|
|
39
|
+
} do |orders|
|
|
40
|
+
# Orders to Fulfill submenu
|
|
41
|
+
orders.add :orders_to_fulfill,
|
|
42
|
+
label: 'admin.orders.orders_to_fulfill',
|
|
43
|
+
url: -> { spree.admin_orders_path(q: {shipment_state_not_in: [:shipped, :canceled]}) },
|
|
44
|
+
position: 10,
|
|
45
|
+
active: -> { controller_name == 'orders' && params.dig(:q, :shipment_state_not_in).present? },
|
|
46
|
+
if: -> {
|
|
47
|
+
ready_to_ship_orders_count&.positive?
|
|
48
|
+
},
|
|
49
|
+
badge: -> {
|
|
50
|
+
ready_to_ship_orders_count if ready_to_ship_orders_count&.positive?
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# Draft Orders
|
|
54
|
+
orders.add :draft_orders,
|
|
55
|
+
label: :draft_orders,
|
|
56
|
+
url: :admin_checkouts_path,
|
|
57
|
+
position: 20,
|
|
58
|
+
active: -> { controller_name == 'checkouts' || (@order.present? && !@order.completed?) },
|
|
59
|
+
if: -> { can?(:manage, :checkouts) }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Returns with submenu
|
|
63
|
+
sidebar_nav.add :returns,
|
|
64
|
+
label: :returns,
|
|
65
|
+
url: :admin_customer_returns_path,
|
|
66
|
+
icon: 'receipt-refund',
|
|
67
|
+
position: 25,
|
|
68
|
+
if: -> { can?(:manage, Spree::CustomerReturn) || can?(:manage, Spree::ReturnAuthorization) } do |returns|
|
|
69
|
+
# Return Authorizations
|
|
70
|
+
returns.add :return_authorizations,
|
|
71
|
+
label: :return_authorizations,
|
|
72
|
+
url: :admin_return_authorizations_path,
|
|
73
|
+
position: 10,
|
|
74
|
+
if: -> { can?(:manage, Spree::ReturnAuthorization) }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Products with submenu
|
|
78
|
+
sidebar_nav.add :products,
|
|
79
|
+
label: :products,
|
|
80
|
+
url: :admin_products_path,
|
|
81
|
+
icon: 'package',
|
|
82
|
+
position: 30,
|
|
83
|
+
if: -> { can?(:manage, Spree::Product) } do |products|
|
|
84
|
+
# Stock
|
|
85
|
+
products.add :stock,
|
|
86
|
+
label: :stock,
|
|
87
|
+
url: :admin_stock_items_path,
|
|
88
|
+
position: 10,
|
|
89
|
+
active: -> { %w[stock_items stock_transfers].include?(controller_name) },
|
|
90
|
+
if: -> { can?(:manage, Spree::StockItem) || can?(:manage, Spree::StockTransfer) }
|
|
91
|
+
|
|
92
|
+
# Taxonomies
|
|
93
|
+
products.add :taxonomies,
|
|
94
|
+
label: :taxonomies,
|
|
95
|
+
url: :admin_taxonomies_path,
|
|
96
|
+
position: 20,
|
|
97
|
+
active: -> { %w[taxonomies taxons].include?(controller_name) },
|
|
98
|
+
if: -> { can?(:manage, Spree::Taxonomy) && can?(:manage, Spree::Taxon) }
|
|
99
|
+
|
|
100
|
+
# Options
|
|
101
|
+
products.add :options,
|
|
102
|
+
label: :options,
|
|
103
|
+
url: :admin_option_types_path,
|
|
104
|
+
position: 30,
|
|
105
|
+
active: -> { %w[option_types option_values].include?(controller_name) },
|
|
106
|
+
if: -> { can?(:manage, Spree::OptionType) }
|
|
107
|
+
|
|
108
|
+
# Properties
|
|
109
|
+
products.add :properties,
|
|
110
|
+
label: :properties,
|
|
111
|
+
url: :admin_properties_path,
|
|
112
|
+
position: 40,
|
|
113
|
+
if: -> { can?(:manage, Spree::Property) && Spree::Config.product_properties_enabled }
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Vendors (Enterprise Edition)
|
|
117
|
+
sidebar_nav.add :vendors,
|
|
118
|
+
label: :vendors,
|
|
119
|
+
url: 'https://spreecommerce.org/marketplace-ecommerce/',
|
|
120
|
+
icon: 'heart-handshake',
|
|
121
|
+
position: 35,
|
|
122
|
+
if: -> { can?(:manage, current_store) && !defined?(SpreeEnterprise) },
|
|
123
|
+
badge: 'Enterprise',
|
|
124
|
+
tooltip: 'Multi-Vendor Marketplace is available in the Enterprise Edition',
|
|
125
|
+
target: '_blank'
|
|
126
|
+
|
|
127
|
+
# Customers with submenu
|
|
128
|
+
sidebar_nav.add :customers,
|
|
129
|
+
label: :customers,
|
|
130
|
+
url: :admin_users_path,
|
|
131
|
+
icon: 'users',
|
|
132
|
+
position: 40,
|
|
133
|
+
if: -> { can?(:manage, Spree.user_class) } do |customers|
|
|
134
|
+
# Newsletter Subscribers
|
|
135
|
+
customers.add :newsletter_subscribers,
|
|
136
|
+
label: :newsletter_subscribers,
|
|
137
|
+
url: :admin_newsletter_subscribers_path,
|
|
138
|
+
position: 10
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Promotions with submenu
|
|
142
|
+
sidebar_nav.add :promotions,
|
|
143
|
+
label: :promotions,
|
|
144
|
+
url: :admin_promotions_path,
|
|
145
|
+
icon: 'discount',
|
|
146
|
+
position: 50,
|
|
147
|
+
if: -> { can?(:manage, Spree::Promotion) } do |promotions|
|
|
148
|
+
# Gift Cards
|
|
149
|
+
promotions.add :gift_cards,
|
|
150
|
+
label: :gift_cards,
|
|
151
|
+
url: :admin_gift_cards_path,
|
|
152
|
+
position: 10,
|
|
153
|
+
active: -> { %w[gift_cards gift_card_batches].include?(controller_name) }
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Reports
|
|
157
|
+
sidebar_nav.add :reports,
|
|
158
|
+
label: :reports,
|
|
159
|
+
url: :admin_reports_path,
|
|
160
|
+
icon: 'chart-bar',
|
|
161
|
+
position: 60,
|
|
162
|
+
if: -> { can?(:manage, Spree::Report) }
|
|
163
|
+
|
|
164
|
+
# Storefront with submenu
|
|
165
|
+
sidebar_nav.add :storefront,
|
|
166
|
+
label: 'admin.storefront',
|
|
167
|
+
url: :admin_themes_path,
|
|
168
|
+
icon: 'building-store',
|
|
169
|
+
position: 70,
|
|
170
|
+
if: -> { can?(:manage, Spree::Theme) } do |storefront|
|
|
171
|
+
|
|
172
|
+
# Pages
|
|
173
|
+
storefront.add :pages,
|
|
174
|
+
label: :pages,
|
|
175
|
+
url: :admin_pages_path,
|
|
176
|
+
position: 20,
|
|
177
|
+
if: -> { can?(:manage, Spree::Page) }
|
|
178
|
+
|
|
179
|
+
# Posts (Blog)
|
|
180
|
+
storefront.add :posts,
|
|
181
|
+
label: :posts,
|
|
182
|
+
url: :admin_posts_path,
|
|
183
|
+
position: 30,
|
|
184
|
+
active: -> { %w[posts post_categories].include?(controller_name) },
|
|
185
|
+
if: -> { can?(:manage, Spree::Post) }
|
|
186
|
+
|
|
187
|
+
# Storefront Settings
|
|
188
|
+
storefront.add :storefront_settings,
|
|
189
|
+
label: :settings,
|
|
190
|
+
url: :edit_admin_storefront_path,
|
|
191
|
+
position: 40,
|
|
192
|
+
if: -> { can?(:manage, current_store) }
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Integrations
|
|
196
|
+
sidebar_nav.add :integrations,
|
|
197
|
+
label: :integrations,
|
|
198
|
+
url: :admin_integrations_path,
|
|
199
|
+
icon: 'plug-connected',
|
|
200
|
+
position: 80,
|
|
201
|
+
if: -> { can?(:manage, Spree::Integration) }
|
|
202
|
+
|
|
203
|
+
# Section divider before settings
|
|
204
|
+
sidebar_nav.add :settings_section,
|
|
205
|
+
section_label: 'Settings',
|
|
206
|
+
position: 90
|
|
207
|
+
|
|
208
|
+
# Settings (bottom of sidebar)
|
|
209
|
+
sidebar_nav.add :settings,
|
|
210
|
+
label: :settings,
|
|
211
|
+
url: -> { spree.edit_admin_store_path(section: 'general-settings') },
|
|
212
|
+
icon: 'settings',
|
|
213
|
+
position: 100,
|
|
214
|
+
if: -> { can?(:manage, current_store) }
|
|
215
|
+
|
|
216
|
+
# Admin Users (bottom of sidebar)
|
|
217
|
+
sidebar_nav.add :admin_users,
|
|
218
|
+
label: :users,
|
|
219
|
+
url: :admin_admin_users_path,
|
|
220
|
+
icon: 'users',
|
|
221
|
+
position: 110,
|
|
222
|
+
if: -> { can?(:manage, Spree.admin_user_class) }
|
|
223
|
+
|
|
224
|
+
# ===============================================
|
|
225
|
+
# Settings Navigation
|
|
226
|
+
# ===============================================
|
|
227
|
+
settings_nav = Spree.admin.navigation.settings
|
|
228
|
+
|
|
229
|
+
# Store Details
|
|
230
|
+
settings_nav.add :general_settings,
|
|
231
|
+
label: :store_details,
|
|
232
|
+
url: -> { spree.edit_admin_store_path(section: 'general-settings') },
|
|
233
|
+
icon: 'building-store',
|
|
234
|
+
position: 10,
|
|
235
|
+
active: -> { controller_name == 'stores' && params[:section] == 'general-settings' },
|
|
236
|
+
if: -> { can?(:manage, current_store) }
|
|
237
|
+
|
|
238
|
+
# Admin Users
|
|
239
|
+
settings_nav.add :users,
|
|
240
|
+
label: :users,
|
|
241
|
+
url: :admin_admin_users_path,
|
|
242
|
+
icon: 'users',
|
|
243
|
+
position: 20,
|
|
244
|
+
active: -> { %w[admin_users invitations roles].include?(controller_name) },
|
|
245
|
+
if: -> { can?(:manage, Spree.admin_user_class) }
|
|
246
|
+
|
|
247
|
+
# Emails
|
|
248
|
+
settings_nav.add :emails,
|
|
249
|
+
label: :emails,
|
|
250
|
+
url: -> { spree.edit_admin_store_path(section: 'emails') },
|
|
251
|
+
icon: 'send',
|
|
252
|
+
position: 30,
|
|
253
|
+
active: -> { controller_name == 'stores' && params[:section] == 'emails' },
|
|
254
|
+
if: -> { can?(:manage, current_store) }
|
|
255
|
+
|
|
256
|
+
# Policies
|
|
257
|
+
settings_nav.add :policies,
|
|
258
|
+
label: :policies,
|
|
259
|
+
url: :admin_policies_path,
|
|
260
|
+
icon: 'list-check',
|
|
261
|
+
position: 40,
|
|
262
|
+
active: -> { controller_name == 'policies' },
|
|
263
|
+
if: -> { can?(:manage, Spree::Policy) }
|
|
264
|
+
|
|
265
|
+
# Checkout
|
|
266
|
+
settings_nav.add :checkout,
|
|
267
|
+
label: :checkout,
|
|
268
|
+
url: -> { spree.edit_admin_store_path(section: 'checkout') },
|
|
269
|
+
icon: 'shopping-cart',
|
|
270
|
+
position: 50,
|
|
271
|
+
active: -> { controller_name == 'stores' && params[:section] == 'checkout' },
|
|
272
|
+
if: -> { can?(:manage, current_store) }
|
|
273
|
+
|
|
274
|
+
# Domains
|
|
275
|
+
settings_nav.add :domains,
|
|
276
|
+
label: :domains,
|
|
277
|
+
url: :admin_custom_domains_path,
|
|
278
|
+
icon: 'world-www',
|
|
279
|
+
position: 60,
|
|
280
|
+
active: -> { controller_name == 'custom_domains' },
|
|
281
|
+
if: -> { can?(:manage, Spree::CustomDomain) }
|
|
282
|
+
|
|
283
|
+
# Payment Methods
|
|
284
|
+
settings_nav.add :payment_methods,
|
|
285
|
+
label: :payments,
|
|
286
|
+
url: :admin_payment_methods_path,
|
|
287
|
+
icon: 'credit-card',
|
|
288
|
+
position: 70,
|
|
289
|
+
active: -> { controller_name == 'payment_methods' },
|
|
290
|
+
if: -> { can?(:manage, Spree::PaymentMethod) }
|
|
291
|
+
|
|
292
|
+
# Zones
|
|
293
|
+
settings_nav.add :zones,
|
|
294
|
+
label: :zones,
|
|
295
|
+
url: :admin_zones_path,
|
|
296
|
+
icon: 'world',
|
|
297
|
+
position: 80,
|
|
298
|
+
active: -> { %w[zones countries states].include?(controller_name) },
|
|
299
|
+
if: -> { can?(:manage, Spree::Zone) }
|
|
300
|
+
|
|
301
|
+
# Shipping Methods
|
|
302
|
+
settings_nav.add :shipping_methods,
|
|
303
|
+
label: :shipping,
|
|
304
|
+
url: :admin_shipping_methods_path,
|
|
305
|
+
icon: 'truck',
|
|
306
|
+
position: 90,
|
|
307
|
+
active: -> { %w[shipping_methods shipping_categories].include?(controller_name) },
|
|
308
|
+
if: -> { can?(:manage, Spree::ShippingMethod) }
|
|
309
|
+
|
|
310
|
+
# Tax Settings
|
|
311
|
+
settings_nav.add :tax_rates,
|
|
312
|
+
label: :tax,
|
|
313
|
+
url: :admin_tax_rates_path,
|
|
314
|
+
icon: 'receipt-tax',
|
|
315
|
+
position: 100,
|
|
316
|
+
active: -> { %w[tax_rates tax_categories stripe_tax_registrations].include?(controller_name) },
|
|
317
|
+
if: -> { can?(:manage, Spree::TaxRate) }
|
|
318
|
+
|
|
319
|
+
# Returns
|
|
320
|
+
settings_nav.add :return_settings,
|
|
321
|
+
label: :returns,
|
|
322
|
+
url: :admin_return_authorization_reasons_path,
|
|
323
|
+
icon: 'receipt-refund',
|
|
324
|
+
position: 110,
|
|
325
|
+
active: -> { %w[refund_reasons reimbursement_types return_authorization_reasons].include?(controller_name) },
|
|
326
|
+
if: -> { can?(:manage, Spree::ReturnAuthorizationReason) }
|
|
327
|
+
|
|
328
|
+
# Stock Locations
|
|
329
|
+
settings_nav.add :stock_locations,
|
|
330
|
+
label: :stock_locations,
|
|
331
|
+
url: :admin_stock_locations_path,
|
|
332
|
+
icon: 'map-pin',
|
|
333
|
+
position: 120,
|
|
334
|
+
active: -> { controller_name == 'stock_locations' },
|
|
335
|
+
if: -> { can?(:manage, Spree::StockLocation) }
|
|
336
|
+
|
|
337
|
+
# Metafield Definitions
|
|
338
|
+
settings_nav.add :metafield_definitions,
|
|
339
|
+
label: :metafield_definitions,
|
|
340
|
+
url: :admin_metafield_definitions_path,
|
|
341
|
+
icon: 'list-details',
|
|
342
|
+
position: 130,
|
|
343
|
+
active: -> { controller_name == 'metafield_definitions' },
|
|
344
|
+
if: -> { can?(:manage, Spree::MetafieldDefinition) }
|
|
345
|
+
|
|
346
|
+
# Audit Log
|
|
347
|
+
settings_nav.add :audits,
|
|
348
|
+
label: 'admin.audit_log',
|
|
349
|
+
url: :admin_audits_path,
|
|
350
|
+
icon: 'history',
|
|
351
|
+
position: 140,
|
|
352
|
+
active: -> { %w[audits exports imports].include?(controller_name) },
|
|
353
|
+
if: -> {
|
|
354
|
+
# Only show if audits feature exists
|
|
355
|
+
can?(:manage, current_store) &&
|
|
356
|
+
Spree::Core::Engine.routes.url_helpers.respond_to?(:admin_audits_path)
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
# Developers
|
|
360
|
+
settings_nav.add :developers,
|
|
361
|
+
label: :developers,
|
|
362
|
+
url: :admin_oauth_applications_path,
|
|
363
|
+
icon: 'terminal',
|
|
364
|
+
position: 150,
|
|
365
|
+
active: -> { %w[oauth_applications webhooks_subscribers].include?(controller_name) },
|
|
366
|
+
if: -> { can?(:manage, Spree::OauthApplication) }
|
|
367
|
+
|
|
368
|
+
# Edit Profile
|
|
369
|
+
settings_nav.add :edit_profile,
|
|
370
|
+
label: 'admin.edit_profile',
|
|
371
|
+
url: :edit_admin_profile_path,
|
|
372
|
+
icon: 'user-scan',
|
|
373
|
+
position: 200,
|
|
374
|
+
active: -> { controller_name == 'profiles' && action_name == 'edit' }
|
|
375
|
+
|
|
376
|
+
# ===============================================
|
|
377
|
+
# Page Tab Navigations
|
|
378
|
+
# ===============================================
|
|
379
|
+
|
|
380
|
+
# Tax Tab Navigation
|
|
381
|
+
tax_tabs_nav = Spree.admin.navigation.tax_tabs
|
|
382
|
+
|
|
383
|
+
tax_tabs_nav.add :tax_rates,
|
|
384
|
+
label: :tax_rates,
|
|
385
|
+
url: :admin_tax_rates_path,
|
|
386
|
+
position: 10,
|
|
387
|
+
if: -> { can?(:manage, Spree::TaxRate) }
|
|
388
|
+
|
|
389
|
+
tax_tabs_nav.add :tax_categories,
|
|
390
|
+
label: :tax_categories,
|
|
391
|
+
url: :admin_tax_categories_path,
|
|
392
|
+
position: 20,
|
|
393
|
+
if: -> { can?(:manage, Spree::TaxCategory) }
|
|
394
|
+
|
|
395
|
+
# Shipping Tab Navigation
|
|
396
|
+
shipping_tabs_nav = Spree.admin.navigation.shipping_tabs
|
|
397
|
+
|
|
398
|
+
shipping_tabs_nav.add :shipping_methods,
|
|
399
|
+
label: :shipping_methods,
|
|
400
|
+
url: :admin_shipping_methods_path,
|
|
401
|
+
position: 10,
|
|
402
|
+
active: -> { controller_name == 'shipping_methods' && action_name == 'index' },
|
|
403
|
+
if: -> { can?(:manage, Spree::ShippingMethod) }
|
|
404
|
+
|
|
405
|
+
shipping_tabs_nav.add :shipping_categories,
|
|
406
|
+
label: :shipping_categories,
|
|
407
|
+
url: :admin_shipping_categories_path,
|
|
408
|
+
position: 20,
|
|
409
|
+
if: -> { can?(:manage, Spree::ShippingCategory) }
|
|
410
|
+
|
|
411
|
+
# Team Tab Navigation
|
|
412
|
+
team_tabs_nav = Spree.admin.navigation.team_tabs
|
|
413
|
+
|
|
414
|
+
team_tabs_nav.add :admin_users,
|
|
415
|
+
label: :users,
|
|
416
|
+
url: :admin_admin_users_path,
|
|
417
|
+
position: 10,
|
|
418
|
+
if: -> { can?(:manage, Spree.admin_user_class) }
|
|
419
|
+
|
|
420
|
+
team_tabs_nav.add :invitations,
|
|
421
|
+
label: :invitations,
|
|
422
|
+
url: :admin_invitations_path,
|
|
423
|
+
position: 20,
|
|
424
|
+
if: -> { can?(:manage, Spree::Invitation) }
|
|
425
|
+
|
|
426
|
+
team_tabs_nav.add :roles,
|
|
427
|
+
label: :roles,
|
|
428
|
+
url: :admin_roles_path,
|
|
429
|
+
position: 30,
|
|
430
|
+
if: -> { can?(:manage, Spree::Role) }
|
|
431
|
+
|
|
432
|
+
# Stock Tab Navigation
|
|
433
|
+
stock_tabs_nav = Spree.admin.navigation.stock_tabs
|
|
434
|
+
|
|
435
|
+
stock_tabs_nav.add :stock_items,
|
|
436
|
+
label: :stock_items,
|
|
437
|
+
url: :admin_stock_items_path,
|
|
438
|
+
position: 10,
|
|
439
|
+
active: -> { controller_name == 'stock_items' },
|
|
440
|
+
if: -> { can?(:manage, Spree::StockItem) }
|
|
441
|
+
|
|
442
|
+
stock_tabs_nav.add :stock_transfers,
|
|
443
|
+
label: :stock_transfers,
|
|
444
|
+
url: :admin_stock_transfers_path,
|
|
445
|
+
position: 20,
|
|
446
|
+
active: -> { controller_name == 'stock_transfers' },
|
|
447
|
+
if: -> { can?(:manage, Spree::StockTransfer) }
|
|
448
|
+
|
|
449
|
+
# Returns and Refunds Tab Navigation
|
|
450
|
+
returns_tabs_nav = Spree.admin.navigation.returns_tabs
|
|
451
|
+
|
|
452
|
+
returns_tabs_nav.add :return_authorization_reasons,
|
|
453
|
+
label: :return_authorization_reasons,
|
|
454
|
+
url: :admin_return_authorization_reasons_path,
|
|
455
|
+
position: 10,
|
|
456
|
+
if: -> { can?(:manage, Spree::ReturnAuthorizationReason) }
|
|
457
|
+
|
|
458
|
+
returns_tabs_nav.add :refund_reasons,
|
|
459
|
+
label: :refund_reasons,
|
|
460
|
+
url: :admin_refund_reasons_path,
|
|
461
|
+
position: 20,
|
|
462
|
+
if: -> { can?(:manage, Spree::RefundReason) }
|
|
463
|
+
|
|
464
|
+
returns_tabs_nav.add :reimbursement_types,
|
|
465
|
+
label: :reimbursement_types,
|
|
466
|
+
url: :admin_reimbursement_types_path,
|
|
467
|
+
position: 30,
|
|
468
|
+
if: -> { can?(:manage, Spree::ReimbursementType) }
|
|
469
|
+
|
|
470
|
+
# Developers Tab Navigation
|
|
471
|
+
developers_tabs_nav = Spree.admin.navigation.developers_tabs
|
|
472
|
+
|
|
473
|
+
developers_tabs_nav.add :api_keys,
|
|
474
|
+
label: :api_keys,
|
|
475
|
+
url: :admin_oauth_applications_path,
|
|
476
|
+
position: 10,
|
|
477
|
+
active: -> { controller_name == 'oauth_applications' },
|
|
478
|
+
if: -> { can?(:manage, Spree::OauthApplication) }
|
|
479
|
+
|
|
480
|
+
developers_tabs_nav.add :webhooks,
|
|
481
|
+
label: :webhooks,
|
|
482
|
+
url: :admin_webhooks_subscribers_path,
|
|
483
|
+
position: 20,
|
|
484
|
+
active: -> { controller_name == 'webhooks_subscribers' },
|
|
485
|
+
if: -> { can?(:manage, Spree::Webhooks::Subscriber) }
|
|
486
|
+
|
|
487
|
+
# Audit Tab Navigation
|
|
488
|
+
audit_tabs_nav = Spree.admin.navigation.audit_tabs
|
|
489
|
+
|
|
490
|
+
audit_tabs_nav.add :audit_log,
|
|
491
|
+
label: 'admin.audit_log',
|
|
492
|
+
url: :admin_audits_path,
|
|
493
|
+
position: 10,
|
|
494
|
+
active: -> { controller_name == 'audits' },
|
|
495
|
+
if: -> { can?(:manage, current_store) }
|
|
496
|
+
|
|
497
|
+
audit_tabs_nav.add :exports,
|
|
498
|
+
label: :exports,
|
|
499
|
+
url: :admin_exports_path,
|
|
500
|
+
position: 20,
|
|
501
|
+
active: -> { controller_name == 'exports' },
|
|
502
|
+
if: -> { can?(:manage, Spree::Export) }
|
|
503
|
+
|
|
504
|
+
audit_tabs_nav.add :imports,
|
|
505
|
+
label: :imports,
|
|
506
|
+
url: :admin_imports_path,
|
|
507
|
+
position: 30,
|
|
508
|
+
active: -> { controller_name == 'imports' },
|
|
509
|
+
if: -> { can?(:manage, Spree::Import) }
|
|
510
|
+
end
|
data/config/locales/en.yml
CHANGED
|
@@ -48,6 +48,7 @@ en:
|
|
|
48
48
|
special_instructions:
|
|
49
49
|
description: Allow customers to add special instructions to their order.
|
|
50
50
|
label: Display the special instructions field
|
|
51
|
+
close_sidebar: Close sidebar
|
|
51
52
|
copied: Copied!
|
|
52
53
|
copy_payment_link: Copy Payment Link
|
|
53
54
|
copy_to_clipboard: Copy to clipboard
|
|
@@ -75,6 +76,7 @@ en:
|
|
|
75
76
|
edit_theme: Edit theme
|
|
76
77
|
errors: Errors
|
|
77
78
|
execution_time: Execution Time
|
|
79
|
+
expand_sidebar: Expand sidebar
|
|
78
80
|
export_all: Export all records (can be slow for large datasets)
|
|
79
81
|
export_coupons: Export coupons as CSV file
|
|
80
82
|
export_created: Your export was started. You will receive an email with a download link when it is ready!
|
|
@@ -298,6 +300,8 @@ en:
|
|
|
298
300
|
compare_at_price_description: This price is used to show marked down price on the product page.
|
|
299
301
|
stock_locations_link: To add more stock locations please go to <a href="%{link}">Stock Locations</a>
|
|
300
302
|
total_inventory_html: 'Total inventory at %{stock_location} location: %{count} available'
|
|
303
|
+
vendors:
|
|
304
|
+
enterprise_feature: Multi-Vendor Marketplace is available in the Enterprise Edition
|
|
301
305
|
webhooks_subscribers:
|
|
302
306
|
all_events: All Events
|
|
303
307
|
new_webhooks_subscriber: New Webhooks Subscriber
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
<tr id="<%%= spree_dom_id <%= @singular_name %> %>" class="cursor-pointer" data-controller="row-link">
|
|
2
|
-
<td data-action="click->row-link#openLink" class="w-70"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
<td data-action="click->row-link#openLink" class="w-70">
|
|
3
|
+
<%%= <%= @singular_name %>.name %>
|
|
4
|
+
</td>
|
|
5
|
+
<td data-action="click->row-link#openLink" class="w-20">
|
|
6
|
+
<%%= spree_date(<%= @singular_name %>.created_at) %>
|
|
7
|
+
</td>
|
|
8
|
+
<td class="actions w-10">
|
|
9
|
+
<%%= link_to_edit(<%= @singular_name %>, data: { row_link_target: :link, turbo_frame: '_top' }) if can? :edit, <%= @singular_name %> %>
|
|
8
10
|
</td>
|
|
9
11
|
</tr>
|
data/lib/spree/admin/engine.rb
CHANGED
|
@@ -125,9 +125,59 @@ module Spree
|
|
|
125
125
|
:webhooks_subscribers_header_partials,
|
|
126
126
|
:vendors_nav_partials,
|
|
127
127
|
:zones_actions_partials,
|
|
128
|
-
:zones_header_partials
|
|
128
|
+
:zones_header_partials,
|
|
129
|
+
:navigation
|
|
129
130
|
)
|
|
130
131
|
|
|
132
|
+
class NavigationEnvironment
|
|
133
|
+
def initialize
|
|
134
|
+
@contexts = {}
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Register a new navigation context
|
|
138
|
+
# @param name [Symbol] The name of the navigation context
|
|
139
|
+
# @return [Spree::Admin::Navigation] The navigation instance
|
|
140
|
+
def register_context(name)
|
|
141
|
+
name = name.to_sym
|
|
142
|
+
@contexts[name] ||= Spree::Admin::Navigation.new(name)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Get a registered navigation context
|
|
146
|
+
# @param name [Symbol] The name of the navigation context
|
|
147
|
+
# @return [Spree::Admin::Navigation] The navigation instance
|
|
148
|
+
# @raise [NoMethodError] if the context hasn't been registered
|
|
149
|
+
def get_context(name)
|
|
150
|
+
name = name.to_sym
|
|
151
|
+
@contexts[name] || raise(NoMethodError, "Navigation context '#{name}' has not been registered. Use Spree.admin.navigation.register_context(:#{name}) first.")
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# List all registered contexts
|
|
155
|
+
# @return [Array<Symbol>] Array of registered context names
|
|
156
|
+
def contexts
|
|
157
|
+
@contexts.keys
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Check if a context exists
|
|
161
|
+
# @param name [Symbol] The context name to check
|
|
162
|
+
# @return [Boolean] true if the context is registered
|
|
163
|
+
def context?(name)
|
|
164
|
+
@contexts.key?(name.to_sym)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Define accessor methods for predefined and custom contexts
|
|
168
|
+
def method_missing(method_name, *args)
|
|
169
|
+
if method_name.to_s.end_with?('=')
|
|
170
|
+
super
|
|
171
|
+
else
|
|
172
|
+
get_context(method_name)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
177
|
+
method_name.to_s.end_with?('=') ? false : context?(method_name)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
131
181
|
# accessible via Rails.application.config.spree_admin
|
|
132
182
|
initializer 'spree.admin.environment', before: :load_config_initializers do |app|
|
|
133
183
|
app.config.spree_admin = Environment.new
|
|
@@ -182,12 +232,24 @@ module Spree
|
|
|
182
232
|
end
|
|
183
233
|
end
|
|
184
234
|
|
|
185
|
-
config.after_initialize do
|
|
235
|
+
config.after_initialize do |app|
|
|
186
236
|
Environment.new.tap do |env|
|
|
187
237
|
env.members.each do |key|
|
|
188
238
|
Rails.application.config.spree_admin.send("#{key}=", [])
|
|
189
239
|
end
|
|
190
240
|
end
|
|
241
|
+
|
|
242
|
+
# Register predefined navigation contexts
|
|
243
|
+
app.config.spree_admin.navigation = NavigationEnvironment.new
|
|
244
|
+
app.config.spree_admin.navigation.register_context(:sidebar)
|
|
245
|
+
app.config.spree_admin.navigation.register_context(:settings)
|
|
246
|
+
app.config.spree_admin.navigation.register_context(:tax_tabs)
|
|
247
|
+
app.config.spree_admin.navigation.register_context(:shipping_tabs)
|
|
248
|
+
app.config.spree_admin.navigation.register_context(:team_tabs)
|
|
249
|
+
app.config.spree_admin.navigation.register_context(:stock_tabs)
|
|
250
|
+
app.config.spree_admin.navigation.register_context(:returns_tabs)
|
|
251
|
+
app.config.spree_admin.navigation.register_context(:developers_tabs)
|
|
252
|
+
app.config.spree_admin.navigation.register_context(:audit_tabs)
|
|
191
253
|
end
|
|
192
254
|
end
|
|
193
255
|
end
|
|
@@ -12,6 +12,7 @@ module Spree
|
|
|
12
12
|
preference :admin_orders_per_page, :integer, default: Kaminari.config.default_per_page
|
|
13
13
|
|
|
14
14
|
preference :include_application_importmap, :boolean, default: false
|
|
15
|
+
preference :legacy_sidebar_navigation, :boolean, default: false
|
|
15
16
|
end
|
|
16
17
|
end
|
|
17
18
|
end
|
data/lib/spree/admin.rb
CHANGED
|
@@ -18,5 +18,25 @@ require 'inline_svg'
|
|
|
18
18
|
require 'spree/admin/action_callbacks'
|
|
19
19
|
require 'spree/admin/callbacks'
|
|
20
20
|
require 'spree/admin/engine'
|
|
21
|
+
require 'spree/core/partials'
|
|
21
22
|
|
|
22
23
|
require 'tinymce-rails'
|
|
24
|
+
|
|
25
|
+
module Spree
|
|
26
|
+
def self.admin
|
|
27
|
+
@admin ||= AdminConfig.new
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class AdminConfig
|
|
31
|
+
def partials
|
|
32
|
+
@partials ||= Spree::Core::Partials.new(
|
|
33
|
+
Rails.application.config.spree_admin,
|
|
34
|
+
Spree::Admin::Engine::Environment
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def navigation
|
|
39
|
+
Rails.application.config.spree_admin.navigation
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|