spree_admin 5.0.0.rc1 → 5.0.1
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/components/_bulk_panel.scss +11 -1
- data/app/assets/stylesheets/spree/admin/components/_cards.scss +3 -4
- data/app/assets/stylesheets/spree/admin/components/_dropdowns.scss +1 -1
- data/app/assets/stylesheets/spree/admin/components/_main.scss +22 -5
- data/app/assets/stylesheets/spree/admin/components/_modals.scss +1 -1
- data/app/assets/stylesheets/spree/admin/global/_variables.scss +8 -2
- data/app/assets/stylesheets/spree/admin/shared/_base.scss +12 -1
- data/app/controllers/spree/admin/dashboard_controller.rb +4 -1
- data/app/controllers/spree/admin/products_controller.rb +1 -8
- data/app/controllers/spree/admin/storefront_controller.rb +1 -1
- data/app/controllers/spree/admin/translations_controller.rb +1 -1
- data/app/helpers/spree/admin/base_helper.rb +69 -63
- data/app/helpers/spree/admin/bulk_operations_helper.rb +86 -0
- data/app/helpers/spree/admin/modal_helper.rb +29 -0
- data/app/helpers/spree/admin/navigation_helper.rb +89 -11
- data/app/helpers/spree/admin/orders_helper.rb +0 -19
- data/app/helpers/spree/admin/stores_helper.rb +8 -36
- data/app/helpers/spree/admin/webhooks_subscribers_helper.rb +1 -1
- data/app/javascript/spree/admin/controllers/variants_form_controller.js +10 -3
- data/app/views/active_storage/_upload_form.html.erb +4 -8
- data/app/views/layouts/spree/admin.html.erb +4 -0
- data/app/views/spree/admin/assets/edit.html.erb +3 -8
- data/app/views/spree/admin/coupon_codes/index.html.erb +4 -6
- data/app/views/spree/admin/custom_domains/_custom_domains.html.erb +1 -1
- data/app/views/spree/admin/custom_domains/index.html.erb +1 -1
- data/app/views/spree/admin/customer_returns/index.html.erb +4 -17
- data/app/views/spree/admin/dashboard/_setup_progress.html.erb +4 -2
- data/app/views/spree/admin/dashboard/_sidebar.html.erb +2 -0
- data/app/views/spree/admin/dashboard/_top_products.html.erb +34 -24
- data/app/views/spree/admin/dashboard/analytics.html.erb +3 -1
- data/app/views/spree/admin/dashboard/show.html.erb +4 -8
- data/app/views/spree/admin/digital_assets/_table.html.erb +1 -1
- data/app/views/spree/admin/digital_assets/edit.html.erb +3 -11
- data/app/views/spree/admin/digital_assets/new.html.erb +3 -11
- data/app/views/spree/admin/exports/index.html.erb +22 -24
- data/app/views/spree/admin/exports/new.html.erb +3 -9
- data/app/views/spree/admin/line_items/new.html.erb +2 -5
- data/app/views/spree/admin/oauth_applications/index.html.erb +57 -58
- data/app/views/spree/admin/option_types/_filter.html.erb +1 -1
- data/app/views/spree/admin/option_types/index.html.erb +7 -11
- data/app/views/spree/admin/orders/_customer_summary.html.erb +0 -2
- data/app/views/spree/admin/orders/_filters.html.erb +3 -8
- data/app/views/spree/admin/orders/_header.html.erb +2 -0
- data/app/views/spree/admin/orders/_list.html.erb +2 -4
- data/app/views/spree/admin/orders/_summary.html.erb +1 -1
- data/app/views/spree/admin/orders/billing_address/create.turbo_stream.erb +3 -6
- data/app/views/spree/admin/orders/billing_address/edit.html.erb +3 -6
- data/app/views/spree/admin/orders/billing_address/new.html.erb +3 -6
- data/app/views/spree/admin/orders/billing_address/update.turbo_stream.erb +3 -6
- data/app/views/spree/admin/orders/contact_information/edit.html.erb +3 -6
- data/app/views/spree/admin/orders/customer_returns/edit.html.erb +1 -10
- data/app/views/spree/admin/orders/edit.html.erb +3 -5
- data/app/views/spree/admin/orders/index.html.erb +1 -1
- data/app/views/spree/admin/orders/return_authorizations/_form.html.erb +1 -1
- data/app/views/spree/admin/orders/return_authorizations/show.html.erb +45 -43
- data/app/views/spree/admin/orders/shipping_address/create.turbo_stream.erb +3 -6
- data/app/views/spree/admin/orders/shipping_address/edit.html.erb +3 -6
- data/app/views/spree/admin/orders/shipping_address/new.html.erb +3 -6
- data/app/views/spree/admin/orders/shipping_address/update.turbo_stream.erb +3 -6
- data/app/views/spree/admin/pages/_filters.html.erb +1 -1
- data/app/views/spree/admin/pages/edit.html.erb +2 -5
- data/app/views/spree/admin/pages/index.html.erb +4 -4
- data/app/views/spree/admin/payment_methods/index.html.erb +10 -8
- data/app/views/spree/admin/post_categories/index.html.erb +4 -6
- data/app/views/spree/admin/posts/_filters.html.erb +2 -7
- data/app/views/spree/admin/posts/_post.html.erb +1 -11
- data/app/views/spree/admin/posts/index.html.erb +5 -9
- data/app/views/spree/admin/products/_bulk_operations.html.erb +59 -94
- data/app/views/spree/admin/products/_filters.html.erb +13 -8
- data/app/views/spree/admin/products/_form.html.erb +3 -3
- data/app/views/spree/admin/products/_list.html.erb +2 -10
- data/app/views/spree/admin/products/_product.html.erb +1 -4
- data/app/views/spree/admin/products/bulk_modal.html.erb +3 -8
- data/app/views/spree/admin/products/edit.html.erb +3 -0
- data/app/views/spree/admin/products/form/_variants.html.erb +1 -0
- data/app/views/spree/admin/products/index.html.erb +5 -5
- data/app/views/spree/admin/promotion_actions/new.html.erb +7 -12
- data/app/views/spree/admin/promotion_rules/new.html.erb +7 -12
- data/app/views/spree/admin/promotions/_filters.html.erb +27 -0
- data/app/views/spree/admin/promotions/index.html.erb +7 -35
- data/app/views/spree/admin/properties/index.html.erb +10 -9
- data/app/views/spree/admin/refund_reasons/index.html.erb +37 -35
- data/app/views/spree/admin/refunds/edit.html.erb +3 -8
- data/app/views/spree/admin/reimbursement_types/index.html.erb +42 -40
- data/app/views/spree/admin/reports/_report.html.erb +1 -1
- data/app/views/spree/admin/return_authorization_reasons/index.html.erb +41 -41
- data/app/views/spree/admin/return_authorizations/_filters.html.erb +1 -1
- data/app/views/spree/admin/return_authorizations/_list.html.erb +1 -10
- data/app/views/spree/admin/return_authorizations/index.html.erb +1 -1
- data/app/views/spree/admin/roles/_form.html.erb +1 -1
- data/app/views/spree/admin/roles/index.html.erb +26 -24
- data/app/views/spree/admin/shared/_bulk_modal.html.erb +6 -7
- data/app/views/spree/admin/shared/_developers_nav.html.erb +2 -2
- data/app/views/spree/admin/shared/_filter_submit.html.erb +6 -0
- data/app/views/spree/admin/shared/_head.html.erb +3 -1
- data/app/views/spree/admin/shared/_modal.html.erb +2 -8
- data/app/views/spree/admin/shared/_multi_product_picker.html.erb +2 -4
- data/app/views/spree/admin/shared/_no_resource_found.html.erb +1 -1
- data/app/views/spree/admin/shared/_posts_tabs.html.erb +2 -2
- data/app/views/spree/admin/shared/_product_image.html.erb +1 -10
- data/app/views/spree/admin/shared/_refunds.html.erb +1 -1
- data/app/views/spree/admin/shared/_returns_and_refunds_nav.html.erb +3 -3
- data/app/views/spree/admin/shared/_shipping_nav.html.erb +2 -2
- data/app/views/spree/admin/shared/_stock_nav.html.erb +2 -2
- data/app/views/spree/admin/shared/_tax_nav.html.erb +2 -2
- data/app/views/spree/admin/shared/_user.html.erb +2 -2
- data/app/views/spree/admin/shared/_user_dropdown.html.erb +2 -2
- data/app/views/spree/admin/shared/sidebar/_orders_nav.html.erb +19 -29
- data/app/views/spree/admin/shared/sidebar/_products_nav.html.erb +6 -25
- data/app/views/spree/admin/shared/sidebar/_returns_nav.html.erb +8 -15
- data/app/views/spree/admin/shared/sidebar/_store_dropdown.html.erb +36 -7
- data/app/views/spree/admin/shared/sidebar/_store_nav.html.erb +28 -52
- data/app/views/spree/admin/shared/sidebar/_storefront_nav.html.erb +19 -26
- data/app/views/spree/admin/shared/sortable_tree/_taxonomy.html.erb +3 -23
- data/app/views/spree/admin/shipping_categories/index.html.erb +28 -26
- data/app/views/spree/admin/shipping_methods/_actions.html.erb +1 -1
- data/app/views/spree/admin/shipping_methods/index.html.erb +23 -21
- data/app/views/spree/admin/stock_items/_filters.html.erb +2 -7
- data/app/views/spree/admin/stock_items/index.html.erb +5 -8
- data/app/views/spree/admin/stock_locations/_stock_location.html.erb +16 -13
- data/app/views/spree/admin/stock_locations/index.html.erb +24 -21
- data/app/views/spree/admin/stock_transfers/_filters.html.erb +1 -1
- data/app/views/spree/admin/stock_transfers/_new_variant_modal.html.erb +3 -5
- data/app/views/spree/admin/stock_transfers/index.html.erb +6 -6
- data/app/views/spree/admin/store_credit_categories/_form.html.erb +1 -1
- data/app/views/spree/admin/store_credit_categories/edit.html.erb +6 -4
- data/app/views/spree/admin/store_credit_categories/index.html.erb +28 -24
- data/app/views/spree/admin/store_credits/index.html.erb +2 -2
- data/app/views/spree/admin/storefront/edit.html.erb +7 -9
- data/app/views/spree/admin/stores/form/_basic.html.erb +2 -2
- data/app/views/spree/admin/stores/form/_policies.html.erb +1 -1
- data/app/views/spree/admin/stores/new.html.erb +8 -6
- data/app/views/spree/admin/tax_categories/index.html.erb +24 -22
- data/app/views/spree/admin/tax_rates/index.html.erb +26 -24
- data/app/views/spree/admin/taxonomies/index.html.erb +4 -4
- data/app/views/spree/admin/taxonomies/show.html.erb +2 -2
- data/app/views/spree/admin/themes/_theme_preview_image.html.erb +1 -10
- data/app/views/spree/admin/themes/index.html.erb +2 -2
- data/app/views/spree/admin/translations/_translations_unavailable.html.erb +6 -8
- data/app/views/spree/admin/users/_filters.html.erb +2 -7
- data/app/views/spree/admin/users/_tabs.html.erb +4 -4
- data/app/views/spree/admin/users/_user.html.erb +1 -4
- data/app/views/spree/admin/users/bulk_modal.html.erb +3 -8
- data/app/views/spree/admin/users/index.html.erb +25 -58
- data/app/views/spree/admin/variants/_variant.html.erb +8 -2
- data/app/views/spree/admin/variants/form/_media_asset.html.erb +1 -7
- data/app/views/spree/admin/variants/form/_pricing.html.erb +5 -4
- data/app/views/spree/admin/webhooks_subscribers/_form.html.erb +1 -1
- data/app/views/spree/admin/webhooks_subscribers/index.html.erb +25 -22
- data/app/views/spree/admin/webhooks_subscribers/show.html.erb +3 -3
- data/app/views/spree/admin/zones/index.html.erb +34 -32
- data/config/locales/en.yml +1 -46
- data/lib/spree/admin/engine.rb +50 -0
- metadata +13 -14
- data/app/views/spree/admin/orders/_extra_filters.html.erb +0 -0
- data/app/views/spree/admin/products/_empty_list.html.erb +0 -1
- data/app/views/spree/admin/products/form/_extra_filters.html.erb +0 -0
- data/app/views/spree/admin/products/form/_extra_form.html.erb +0 -0
- data/app/views/spree/admin/products/form/_extra_form_sidebar.erb +0 -0
- data/app/views/spree/admin/stores/form/_custom.html.erb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d55b4e39523cee4652dddb953445f27d15190d2cff8e40d3f012329c3e3612ec
|
4
|
+
data.tar.gz: e919c13188d0b35f8c17afaa52fd6e26ea2eae5713e2f5c7d2abb81ea7b7cb9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f7534f9a249beb83294f14d274920f12d7eb55504951365b0511e1efd980040a4811ffb9261af1aaf8074a60afb564176aa654c321bf771da211f629862e1281
|
7
|
+
data.tar.gz: 50b9265c84d615cade73af58b1af47ff41c043394ac10f9475d1a5cfdaf1398cf3bd274be2880264d846ad15e0ff9701e7b883cf1839b99eef34e198779db873
|
@@ -5,6 +5,9 @@
|
|
5
5
|
background-color: $white;
|
6
6
|
padding: 0.5rem;
|
7
7
|
box-shadow: $dropdown-box-shadow;
|
8
|
+
animation: bounceInUp;
|
9
|
+
animation-duration: 0.5s;
|
10
|
+
gap: 0.75rem;
|
8
11
|
}
|
9
12
|
|
10
13
|
#bulk-panel {
|
@@ -28,4 +31,11 @@
|
|
28
31
|
left: 16.66666667%;
|
29
32
|
width: 83.33333333%;
|
30
33
|
}
|
31
|
-
}
|
34
|
+
}
|
35
|
+
|
36
|
+
.bulk-operations-counter {
|
37
|
+
display: inline-flex;
|
38
|
+
align-items: center;
|
39
|
+
justify-content: center;
|
40
|
+
gap: 0.25rem;
|
41
|
+
}
|
@@ -60,12 +60,11 @@
|
|
60
60
|
}
|
61
61
|
|
62
62
|
.card-lg {
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
margin-bottom: 1rem;
|
64
|
+
background-color: $white;
|
66
65
|
border-radius: $border-radius-lg;
|
67
66
|
border: 1px solid $card-border-color;
|
68
|
-
padding:
|
67
|
+
padding: 0;
|
69
68
|
}
|
70
69
|
|
71
70
|
.card-text {
|
@@ -26,7 +26,6 @@
|
|
26
26
|
box-shadow: $dropdown-box-shadow;
|
27
27
|
|
28
28
|
.dropdown-item, .dropdown-header {
|
29
|
-
margin-bottom: 0.25rem;
|
30
29
|
padding-left: $input-btn-padding-x;
|
31
30
|
padding-right: $input-btn-padding-x;
|
32
31
|
padding-top: $input-btn-padding-y;
|
@@ -34,6 +33,7 @@
|
|
34
33
|
}
|
35
34
|
|
36
35
|
.dropdown-item {
|
36
|
+
margin-bottom: 0.25rem;
|
37
37
|
border-radius: $border-radius;
|
38
38
|
display: flex;
|
39
39
|
align-items: center;
|
@@ -54,26 +54,35 @@ turbo-frame[loading] .spinner-border, turbo-frame[busy] .spinner-border {
|
|
54
54
|
border-radius: $border-radius;
|
55
55
|
display: flex;
|
56
56
|
align-items: center;
|
57
|
-
padding-left: 0.
|
58
|
-
padding-right: 0.
|
57
|
+
padding-left: 0.35rem;
|
58
|
+
padding-right: 0.35rem;
|
59
59
|
padding-top: 0.35rem;
|
60
60
|
padding-bottom: 0.35rem;
|
61
61
|
|
62
62
|
.ti {
|
63
63
|
font-size: 1rem;
|
64
64
|
margin-right: 0.5rem;
|
65
|
+
border-radius: $border-radius-sm;
|
66
|
+
padding: 0.2rem 0.2rem;
|
65
67
|
}
|
66
68
|
|
67
69
|
&:hover {
|
68
|
-
background-color: $gray-
|
70
|
+
background-color: $gray-50;
|
69
71
|
}
|
70
72
|
&.active {
|
71
73
|
color: theme-color('primary');
|
72
|
-
background-color: $
|
74
|
+
background-color: $white;
|
75
|
+
box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.05) 0px 1px 2px -1px, rgba(0, 0, 0, 0.02) 0px 2px 4px 0px;
|
73
76
|
font-weight: 500;
|
77
|
+
|
78
|
+
.ti {
|
79
|
+
background-color: theme-color('primary');
|
80
|
+
color: $white;
|
81
|
+
box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.05) 0px 1px 2px -1px, rgba(0, 0, 0, 0.02) 0px 2px 4px 0px;
|
82
|
+
}
|
74
83
|
}
|
75
84
|
|
76
|
-
.badge {
|
85
|
+
.badge:not(.badge-info) {
|
77
86
|
@extend .badge-light;
|
78
87
|
}
|
79
88
|
}
|
@@ -96,6 +105,7 @@ turbo-frame[loading] .spinner-border, turbo-frame[busy] .spinner-border {
|
|
96
105
|
&.active, &:active, &:focus {
|
97
106
|
font-weight: 600;
|
98
107
|
background-color: transparent !important;
|
108
|
+
box-shadow: none;
|
99
109
|
}
|
100
110
|
}
|
101
111
|
}
|
@@ -146,3 +156,10 @@ turbo-frame[loading] .spinner-border, turbo-frame[busy] .spinner-border {
|
|
146
156
|
top: 0.5rem;
|
147
157
|
}
|
148
158
|
}
|
159
|
+
|
160
|
+
.documentation-link-container {
|
161
|
+
font-size: $font-size-sm;
|
162
|
+
text-align: center;
|
163
|
+
margin-top: 2rem;
|
164
|
+
color: $gray-400;
|
165
|
+
}
|
@@ -21,13 +21,16 @@ $black: #000000 !default;
|
|
21
21
|
$blue: #0077ff !default;
|
22
22
|
$white: #FFFFFF !default;
|
23
23
|
|
24
|
+
$action: #f1faff !default;
|
25
|
+
$action-border: #e2ecff !default;
|
26
|
+
|
24
27
|
$theme-colors: (
|
25
28
|
"white": $white,
|
26
29
|
"black": $black,
|
27
30
|
"primary": $primary,
|
28
31
|
"secondary": rgba($blue, 0.1),
|
29
|
-
"action":
|
30
|
-
"action-border":
|
32
|
+
"action": $action,
|
33
|
+
"action-border": $action-border,
|
31
34
|
"active": $gray-25,
|
32
35
|
"partial": #E2E8F0,
|
33
36
|
"warning": #ffe17d,
|
@@ -67,6 +70,9 @@ $border-color: $gray-100 !default;
|
|
67
70
|
$input-border-color: $gray-100 !default;
|
68
71
|
$list-group-border-color: $border-color !default;
|
69
72
|
$list-group-hover-bg: $gray-25 !default;
|
73
|
+
$list-group-active-bg: $action !default;
|
74
|
+
$list-group-active-border-color: $action-border !default;
|
75
|
+
|
70
76
|
$thumbnail-border-color: $gray-100 !default;
|
71
77
|
$hr-border-color: $border-color !default;
|
72
78
|
$table-border-color: $gray-50 !default;
|
@@ -671,4 +671,15 @@ div.uppy-Root {
|
|
671
671
|
|
672
672
|
.tooltip-inner {
|
673
673
|
box-shadow: $dropdown-box-shadow;
|
674
|
-
}
|
674
|
+
}
|
675
|
+
|
676
|
+
.avatar {
|
677
|
+
border-radius: 50%;
|
678
|
+
background-color: $gray-200;
|
679
|
+
color: $gray-500;
|
680
|
+
font-size: 1rem;
|
681
|
+
font-weight: 500;
|
682
|
+
display: flex;
|
683
|
+
align-items: center;
|
684
|
+
justify-content: center;
|
685
|
+
}
|
@@ -83,7 +83,10 @@ module Spree
|
|
83
83
|
|
84
84
|
product_ids = line_items_grouped.map(&:variant_product_id).uniq.compact
|
85
85
|
|
86
|
-
|
86
|
+
if product_ids.empty?
|
87
|
+
@top_products = []
|
88
|
+
return
|
89
|
+
end
|
87
90
|
|
88
91
|
products = current_store.products.with_deleted.includes(:master, :variants).where(id: product_ids)
|
89
92
|
|
@@ -68,10 +68,7 @@ module Spree
|
|
68
68
|
# update the product again
|
69
69
|
@product.slug = @product.slug_was if @product.slug.blank?
|
70
70
|
invoke_callbacks(:update, :fails)
|
71
|
-
|
72
|
-
format.html { render :edit, status: :unprocessable_entity }
|
73
|
-
format.turbo_stream
|
74
|
-
end
|
71
|
+
render :edit, status: :unprocessable_entity
|
75
72
|
end
|
76
73
|
end
|
77
74
|
|
@@ -294,10 +291,6 @@ module Spree
|
|
294
291
|
|
295
292
|
private
|
296
293
|
|
297
|
-
def update_turbo_stream_enabled?
|
298
|
-
true
|
299
|
-
end
|
300
|
-
|
301
294
|
def variant_stock_includes
|
302
295
|
[:images, { stock_items: :stock_location, option_values: :option_type }]
|
303
296
|
end
|
@@ -26,7 +26,7 @@ module Spree
|
|
26
26
|
:meta_description, :meta_title, :meta_keywords, :seo_robots,
|
27
27
|
:facebook, :twitter, :instagram, :linkedin, :youtube, :tiktok, :pinterest,
|
28
28
|
:storefront_custom_code_head, :storefront_custom_code_body_start,
|
29
|
-
:storefront_custom_code_body_end
|
29
|
+
:storefront_custom_code_body_end, :storefront_password
|
30
30
|
)
|
31
31
|
end
|
32
32
|
|
@@ -66,7 +66,7 @@ module Spree
|
|
66
66
|
@back_path = spree.edit_admin_taxonomy_path(@resource)
|
67
67
|
when Spree::Store
|
68
68
|
@resource_name = @resource.name
|
69
|
-
@back_path = spree.edit_admin_store_path(
|
69
|
+
@back_path = spree.edit_admin_store_path(section: "general-settings")
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
@@ -3,6 +3,12 @@ module Spree
|
|
3
3
|
module BaseHelper
|
4
4
|
include Spree::ImagesHelper
|
5
5
|
|
6
|
+
def render_admin_partials(section, options = {})
|
7
|
+
Rails.application.config.spree_admin.send(section).map do |partial|
|
8
|
+
render partial, options
|
9
|
+
end.join.html_safe
|
10
|
+
end
|
11
|
+
|
6
12
|
def enterprise_edition?
|
7
13
|
defined?(Vendo)
|
8
14
|
end
|
@@ -15,37 +21,64 @@ module Spree
|
|
15
21
|
@spree_update_available ||= !Rails.env.test? && spree_updater.update_available?
|
16
22
|
end
|
17
23
|
|
24
|
+
# check if the current controller is a settings controller
|
25
|
+
# this is used to display different sidebar navigation for settings pages
|
26
|
+
# @return [Boolean]
|
18
27
|
def settings_active?
|
19
|
-
%w[stores zones shipping_methods oauth_applications
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
28
|
+
@settings_active || %w[stores zones shipping_methods oauth_applications
|
29
|
+
payment_methods refund_reasons reimbursement_types
|
30
|
+
shipping_categories store_credit_categories
|
31
|
+
syncs tax_categories tax_rates webhooks accounts
|
32
|
+
custom_domains audits exports imports return_authorization_reasons
|
33
|
+
documents stripe_tax_registrations members subscriptions stock_locations webhooks_subscribers].include?(controller_name)
|
25
34
|
end
|
26
35
|
|
36
|
+
# @return [Array<String>] the available countries for checkout
|
27
37
|
def available_countries_iso
|
28
38
|
@available_countries_iso ||= current_store.countries_available_for_checkout.pluck(:iso)
|
29
39
|
end
|
30
40
|
|
31
|
-
|
41
|
+
# render an avatar for a user
|
42
|
+
# if user doesn't have an avatar, the user's initials will be displayed on a rounded background
|
43
|
+
# @param user [Spree::User] the user to render the avatar for
|
44
|
+
# @param options [Hash] the options for the avatar
|
45
|
+
# @option options [Integer] :width the width of the avatar, default: 128
|
46
|
+
# @option options [Integer] :height the height of the avatar, default: 128
|
47
|
+
# @option options [String] :class the CSS class(es) of the avatar, default: 'avatar'
|
48
|
+
# @return [String] the avatar
|
49
|
+
def render_avatar(user, options = {})
|
32
50
|
return unless user.present?
|
33
51
|
|
52
|
+
options[:width] ||= 128
|
53
|
+
options[:height] ||= 128
|
54
|
+
options[:class] ||= 'avatar'
|
55
|
+
|
34
56
|
if user.respond_to?(:avatar) && user.avatar.attached? && user.avatar.variable?
|
35
|
-
|
36
|
-
user.avatar
|
57
|
+
spree_image_tag(
|
58
|
+
user.avatar,
|
59
|
+
width: options[:width],
|
60
|
+
height: options[:height],
|
61
|
+
class: options[:class],
|
62
|
+
style: "width: #{options[:width]}px; height: #{options[:height]}px;"
|
37
63
|
)
|
38
64
|
else
|
39
|
-
|
65
|
+
content_tag(:div, user.name&.initials, class: options[:class], style: "width: #{options[:width]}px; height: #{options[:height]}px;")
|
40
66
|
end
|
41
67
|
end
|
42
68
|
|
69
|
+
# returns the available display on options, eg backend, frontend, both
|
70
|
+
# @return [Array<Array<String, String>>] the available display on options
|
43
71
|
def display_on_options
|
44
72
|
Spree::DisplayOn::DISPLAY.map do |display_on|
|
45
73
|
[Spree.t("admin.display_on_options.#{display_on}"), display_on]
|
46
74
|
end
|
47
75
|
end
|
48
76
|
|
77
|
+
# render an error message for a form field
|
78
|
+
# @param object [Spree::Model] the object to render the error message for
|
79
|
+
# @param method [String] the method to render the error message for
|
80
|
+
# @param options [Hash] the options for the error message
|
81
|
+
# @return [String] the error message
|
49
82
|
def error_message_on(object, method, _options = {})
|
50
83
|
object = convert_to_model(object)
|
51
84
|
obj = object.respond_to?(:errors) ? object : instance_variable_get("@#{object}")
|
@@ -58,6 +91,10 @@ module Spree
|
|
58
91
|
end
|
59
92
|
end
|
60
93
|
|
94
|
+
# render an icon, using the tabler icons library
|
95
|
+
# @param icon_name [String] the name of the icon, eg: 'pencil', see: https://tabler.io/icons
|
96
|
+
# @param options [Hash] the options for the icon
|
97
|
+
# @return [String] the icon
|
61
98
|
def icon(icon_name, options = {})
|
62
99
|
if icon_name.ends_with?('.svg')
|
63
100
|
icon_name = File.basename(icon_name, File.extname(icon_name))
|
@@ -77,42 +114,19 @@ module Spree
|
|
77
114
|
content_tag :i, nil, class: "ti ti-#{icon_name} #{options[:class]}", style: styles
|
78
115
|
end
|
79
116
|
|
117
|
+
# returns the flag emoji for a country
|
118
|
+
# @param iso [String] the ISO code of the country
|
119
|
+
# @return [String] the flag emoji
|
80
120
|
def flag_emoji(iso)
|
81
121
|
::Country.new(iso).emoji_flag
|
82
122
|
end
|
83
123
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
current_store.supported_currencies.split(',')
|
91
|
-
),
|
92
|
-
class: 'custom-select',
|
93
|
-
disabled: current_store.supported_currencies.split(',').count == 1
|
94
|
-
)
|
95
|
-
end
|
96
|
-
|
97
|
-
case options[:type]
|
98
|
-
when :integer
|
99
|
-
number_field_tag(name, value, preference_field_options(options))
|
100
|
-
when :decimal
|
101
|
-
number_field_tag(name, value, preference_field_options(options))
|
102
|
-
when :boolean
|
103
|
-
hidden_field_tag(name, 0, id: "#{name}_hidden") +
|
104
|
-
check_box_tag(name, 1, value, preference_field_options(options))
|
105
|
-
when :string
|
106
|
-
text_field_tag(name, value, preference_field_options(options))
|
107
|
-
when :password
|
108
|
-
password_field_tag(name, value, preference_field_options(options))
|
109
|
-
when :text
|
110
|
-
text_area_tag(name, value, preference_field_options(options))
|
111
|
-
else
|
112
|
-
text_field_tag(name, value, preference_field_options(options))
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
124
|
+
# render a form field for a preference, according to the type of the preference (number, decimal, boolean, string, password, text)
|
125
|
+
# see https://spreecommerce.org/docs/developer/customization/model-preferences
|
126
|
+
# @param form [ActionView::Helpers::FormBuilder] the form builder
|
127
|
+
# @param field [String] the name of the field
|
128
|
+
# @param options [Hash] the options for the field
|
129
|
+
# @return [String] the preference field
|
116
130
|
def preference_field_for(form, field, options)
|
117
131
|
case options[:type]
|
118
132
|
when :integer
|
@@ -132,6 +146,11 @@ module Spree
|
|
132
146
|
end
|
133
147
|
end
|
134
148
|
|
149
|
+
# returns the options for a preference field, according to the type of the preference (number, decimal, boolean, string, password, text)
|
150
|
+
# @param options [Hash] the options for the field
|
151
|
+
# @option options [Symbol] :type the type of the preference, eg. :integer, :decimal, :boolean, :string, :password, :text
|
152
|
+
# @option options [Boolean] :disabled whether the field is disabled
|
153
|
+
# @return [Hash] the options for the field
|
135
154
|
def preference_field_options(options)
|
136
155
|
field_options = case options[:type]
|
137
156
|
when :integer
|
@@ -177,6 +196,10 @@ module Spree
|
|
177
196
|
size: options[:size])
|
178
197
|
end
|
179
198
|
|
199
|
+
# renders all the preference fields for an object
|
200
|
+
# @param object [Spree::TaxRate, Spree::Calculator, Spree::PaymentMethod, Spree::ShippingMethod, Spree::Store] the object to render the preference fields for
|
201
|
+
# @param form [ActionView::Helpers::FormBuilder] the form builder
|
202
|
+
# @return [String] the preference fields
|
180
203
|
def preference_fields(object, form)
|
181
204
|
return unless object.respond_to?(:preferences)
|
182
205
|
|
@@ -213,31 +236,14 @@ module Spree
|
|
213
236
|
dom_id(record, 'spree')
|
214
237
|
end
|
215
238
|
|
239
|
+
# renders a red dot with a * to indicate that a field is required
|
240
|
+
# @return [String] the required span tag
|
216
241
|
def required_span_tag
|
217
242
|
content_tag(:span, ' *', class: 'required font-weight-bold text-danger')
|
218
243
|
end
|
219
244
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
url = if [Spree::Product, Spree::Post].include?(resource.class)
|
224
|
-
spree_storefront_resource_url(resource, preview_id: resource.id)
|
225
|
-
else
|
226
|
-
spree_storefront_resource_url(resource)
|
227
|
-
end
|
228
|
-
|
229
|
-
link_to_with_icon(
|
230
|
-
'eye',
|
231
|
-
Spree.t('admin.utilities.preview', name: resource_name),
|
232
|
-
url,
|
233
|
-
class: 'text-left dropdown-item', id: "adminPreview#{resource_name}", target: :blank, data: { turbo: false }
|
234
|
-
)
|
235
|
-
end
|
236
|
-
|
237
|
-
def path_from_url(url)
|
238
|
-
url.to_s.gsub('https://', '').gsub('http://', '')
|
239
|
-
end
|
240
|
-
|
245
|
+
# returns the allowed file types for upload, according to the active storage configuration
|
246
|
+
# @return [Array<String>] the allowed file types for upload, eg. ['image/png', 'image/jpeg', 'image/gif', 'image/webp']
|
241
247
|
def allowed_file_types_for_upload
|
242
248
|
Rails.application.config.active_storage.web_image_content_types
|
243
249
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Spree
|
2
|
+
module Admin
|
3
|
+
module BulkOperationsHelper
|
4
|
+
# render a checkbox to select all items for bulk operations
|
5
|
+
# @return [String]
|
6
|
+
def bulk_operations_select_all_checkbox
|
7
|
+
content_tag :div, class: "custom-control custom-checkbox ml-1" do
|
8
|
+
check_box_tag(
|
9
|
+
nil,
|
10
|
+
nil,
|
11
|
+
false,
|
12
|
+
id: "checkAllMasterCheckbox",
|
13
|
+
class: "custom-control-input",
|
14
|
+
data: { bulk_operation_target: "checkboxAll" }
|
15
|
+
) +
|
16
|
+
content_tag(:label, content_tag(:span, ""), class: "custom-control-label", for: "checkAllMasterCheckbox")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# render a checkbox to select an item for bulk operations
|
21
|
+
# @param object [Spree::Product, Spree::User, Spree::Order]
|
22
|
+
# @return [String]
|
23
|
+
def bulk_operations_checkbox(object)
|
24
|
+
content_tag :div, class: "custom-control custom-checkbox ml-1" do
|
25
|
+
check_box_tag(
|
26
|
+
"ids[]",
|
27
|
+
object.id,
|
28
|
+
false,
|
29
|
+
class: "custom-control-input",
|
30
|
+
id: "ids_#{object.id}",
|
31
|
+
data: { bulk_operation_target: "checkbox" }
|
32
|
+
) +
|
33
|
+
content_tag(:label, content_tag(:span, ""), class: "custom-control-label", for: "ids_#{object.id}")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# render a link to perform a bulk action
|
38
|
+
# @param text [String] the text of the link
|
39
|
+
# @param path [String] the path of the link
|
40
|
+
# @param options [Hash] the options of the link
|
41
|
+
# @option options [String] :icon the icon of the link
|
42
|
+
# @option options [String] :url the url to perform the bulk action to be set for the form in bulk modal
|
43
|
+
# @option options [String] :class the class of the link
|
44
|
+
# @option options [String] :data the data of the link
|
45
|
+
# @return [String]
|
46
|
+
def bulk_action_link(text, path, options = {})
|
47
|
+
options[:data] ||= {}
|
48
|
+
options[:data][:action] ||= 'click->bulk-operation#setBulkAction'
|
49
|
+
options[:data][:turbo_frame] ||= :bulk_modal
|
50
|
+
options[:data][:url] ||= options[:url]
|
51
|
+
options[:class] ||= 'btn btn-light'
|
52
|
+
|
53
|
+
if options[:icon]
|
54
|
+
text = icon(options[:icon]) + ' ' + text
|
55
|
+
end
|
56
|
+
|
57
|
+
content_tag :span, data: { toggle: 'modal', target: '#bulk-modal' } do
|
58
|
+
link_to text, path, options
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# render a close button for the bulk modal
|
63
|
+
def bulk_operations_close_button
|
64
|
+
button_tag(
|
65
|
+
'',
|
66
|
+
type: 'button',
|
67
|
+
class: 'btn-close',
|
68
|
+
data: {
|
69
|
+
dismiss: 'modal',
|
70
|
+
aria_label: Spree.t(:close),
|
71
|
+
action: 'bulk-operation#cancel'
|
72
|
+
}
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
# render a counter for the bulk operations
|
77
|
+
# @return [String]
|
78
|
+
def bulk_operations_counter
|
79
|
+
content_tag(:span, class: 'bulk-operations-counter ml-1') do
|
80
|
+
content_tag(:strong, '', data: { bulk_operation_target: 'counter' }) +
|
81
|
+
Spree.t("admin.selected")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Spree
|
2
|
+
module Admin
|
3
|
+
module ModalHelper
|
4
|
+
# render a header for the modal
|
5
|
+
# @param title [String, Proc] the title of the modal
|
6
|
+
# @return [String]
|
7
|
+
def modal_header(title)
|
8
|
+
title = capture(&title) if block_given?
|
9
|
+
content_tag(:div, class: 'modal-header') do
|
10
|
+
content_tag(:h5, title, class: 'modal-title') + modal_close_button
|
11
|
+
end.html_safe
|
12
|
+
end
|
13
|
+
|
14
|
+
# render a close button for the modal
|
15
|
+
# @return [String]
|
16
|
+
def modal_close_button
|
17
|
+
button_tag('', type: 'button', class: 'btn-close', data: { dismiss: 'modal', aria_label: Spree.t(:close) }).html_safe
|
18
|
+
end
|
19
|
+
|
20
|
+
# render a discard button for the modal
|
21
|
+
# @return [String]
|
22
|
+
def modal_discard_button
|
23
|
+
button_tag(type: 'button', class: 'btn btn-light', data: { dismiss: 'modal' }) do
|
24
|
+
Spree.t('actions.discard')
|
25
|
+
end.html_safe
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|