mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-30 06:31:16 +00:00
Replace bulk buy inputs with add-remove-buttons
This commit is contained in:
@@ -4,7 +4,7 @@ Darkswarm.directive "shopVariant", ->
|
||||
templateUrl: 'shop_variant.html'
|
||||
scope:
|
||||
variant: '='
|
||||
controller: ($scope, Cart) ->
|
||||
controller: ($scope, $modal, Cart) ->
|
||||
$scope.$watchGroup [
|
||||
'variant.line_item.quantity',
|
||||
'variant.line_item.max_quantity'
|
||||
@@ -13,9 +13,33 @@ Darkswarm.directive "shopVariant", ->
|
||||
Cart.adjust($scope.variant.line_item)
|
||||
|
||||
$scope.add = (quantity) ->
|
||||
$scope.variant.line_item.quantity += quantity
|
||||
item = $scope.variant.line_item
|
||||
item.quantity += quantity
|
||||
if $scope.variant.product.group_buy
|
||||
if item.quantity < 1 || item.max_quantity < item.quantity
|
||||
item.max_quantity = item.quantity
|
||||
|
||||
$scope.addMax = (quantity) ->
|
||||
item = $scope.variant.line_item
|
||||
item.max_quantity += quantity
|
||||
if item.max_quantity < item.quantity
|
||||
item.quantity = item.max_quantity
|
||||
|
||||
$scope.canAdd = (quantity) ->
|
||||
wantedQuantity = $scope.variant.line_item.quantity + quantity
|
||||
$scope.quantityValid(wantedQuantity)
|
||||
|
||||
$scope.canAddMax = (quantity) ->
|
||||
variant = $scope.variant
|
||||
wantedQuantity = variant.line_item.quantity + quantity
|
||||
variant.on_demand || wantedQuantity <= variant.on_hand
|
||||
wantedQuantity = variant.line_item.max_quantity + quantity
|
||||
$scope.quantityValid(wantedQuantity) && variant.line_item.quantity > 0
|
||||
|
||||
$scope.quantityValid = (quantity) ->
|
||||
variant = $scope.variant
|
||||
minimum = 0
|
||||
maximum = variant.on_demand && Infinity || variant.on_hand
|
||||
quantity >= minimum && quantity <= maximum
|
||||
|
||||
$scope.addBulk = (quantity) ->
|
||||
$scope.add(quantity)
|
||||
$modal.open(templateUrl: "bulk_buy_modal.html", scope: $scope)
|
||||
|
||||
34
app/assets/javascripts/templates/bulk_buy_modal.html.haml
Normal file
34
app/assets/javascripts/templates/bulk_buy_modal.html.haml
Normal file
@@ -0,0 +1,34 @@
|
||||
.row
|
||||
.columns.small-12
|
||||
%h3{"ng-bind" => "::variant.extended_name"}
|
||||
|
||||
.row.variant-bulk-buy-price-summary
|
||||
.columns.small-6
|
||||
.variant-unit {{ ::variant.unit_to_display }}
|
||||
.columns.small-6
|
||||
{{ variant.line_item.total_price | localizeCurrency }}
|
||||
|
||||
.row
|
||||
.columns.small-6
|
||||
.variant-bulk-buy-quantity-label
|
||||
Min quantity
|
||||
%div
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "add(-1)", disabled: "!canAdd(-1)"}}>
|
||||
{{ "js.shop_variant_no_group_buy.decrement" | t }}
|
||||
%span.bulk-buy.variant-quantity>
|
||||
{{ variant.line_item.quantity }}
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "add(1)", disabled: "!canAdd(1)"}}
|
||||
{{ "js.shop_variant_no_group_buy.increment" | t }}
|
||||
.columns.small-6
|
||||
.variant-bulk-buy-quantity-label
|
||||
Max quantity
|
||||
%div
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "addMax(-1)", disabled: "!canAddMax(-1)"}}>
|
||||
{{ "js.shop_variant_no_group_buy.decrement" | t }}
|
||||
%span.bulk-buy.variant-quantity>
|
||||
{{ variant.line_item.max_quantity }}
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "addMax(1)", disabled: "!canAddMax(1)"}}
|
||||
{{ "js.shop_variant_no_group_buy.increment" | t }}
|
||||
|
||||
|
||||
%ng-include{src: "'partials/close.html'"}
|
||||
@@ -1,28 +1,17 @@
|
||||
.small-5.medium-3.large-3.columns.text-right{"ng-if" => "::variant.product.group_buy"}
|
||||
|
||||
%span.bulk-input-container
|
||||
%span.bulk-input
|
||||
%input.bulk.first{type: :number,
|
||||
value: nil,
|
||||
integer: true,
|
||||
min: 0,
|
||||
"ng-model" => "variant.line_item.quantity",
|
||||
placeholder: "{{::'shop_variant_quantity_min' | t}}",
|
||||
"ofn-disable-scroll" => true,
|
||||
"ng-debounce" => "500",
|
||||
onwheel: "this.blur()",
|
||||
"ofn-on-hand" => "{{variant.on_demand && 9999 || variant.on_hand }}",
|
||||
name: "variants[{{::variant.id}}]", id: "variants_{{::variant.id}}"}
|
||||
%span.bulk-input
|
||||
%input.bulk.second{type: :number,
|
||||
"ng-disabled" => "!variant.line_item.quantity",
|
||||
integer: true,
|
||||
min: 0,
|
||||
"ng-model" => "variant.line_item.max_quantity",
|
||||
placeholder: "{{::'shop_variant_quantity_max' | t}}",
|
||||
"ofn-disable-scroll" => true,
|
||||
"ng-debounce" => "500",
|
||||
onwheel: "this.blur()",
|
||||
min: "{{variant.line_item.quantity}}",
|
||||
name: "variant_attributes[{{::variant.id}}][max_quantity]",
|
||||
id: "variants_{{::variant.id}}_max"}
|
||||
%button.add-variant{type: "button", ng: {if: "!variant.line_item.quantity", click: "addBulk(1)", disabled: "!canAdd(1)"}}
|
||||
{{ "js.shop_variant_no_group_buy.add" | t }}
|
||||
%button.bulk-buy.variant-quantity{type: "button", ng: {if: "variant.line_item.quantity", click: "addBulk(0)"}}>
|
||||
{{ variant.line_item.quantity }}
|
||||
%button.bulk-buy.variant-quantity{type: "button", ng: {if: "variant.line_item.quantity", click: "addBulk(0)"}}
|
||||
{{ variant.line_item.max_quantity || "-" }}
|
||||
%br
|
||||
.variant-quantity-display{ng: {class: "{visible: variant.line_item.quantity}"}}
|
||||
{{ "js.shop_variant_no_group_buy.in_cart" | t:{quantity: ''} }}
|
||||
%input{type: :hidden,
|
||||
name: "variants[{{::variant.id}}]",
|
||||
ng: {model: "variant.line_item.quantity"}}
|
||||
%input{type: :hidden,
|
||||
name: "variants[{{::variant.id}}]",
|
||||
ng: {model: "variant.line_item.max_quantity"}}
|
||||
|
||||
@@ -6,47 +6,6 @@
|
||||
.darkswarm {
|
||||
// #search
|
||||
@include placeholder(rgba(0, 0, 0, 0.4), #777);
|
||||
|
||||
// ordering
|
||||
product {
|
||||
// BULK
|
||||
|
||||
input.bulk {
|
||||
width: 5rem;
|
||||
|
||||
@include breakpoint(desktop) {
|
||||
width: 4rem;
|
||||
}
|
||||
|
||||
@include breakpoint(tablet) {
|
||||
width: 3.5rem;
|
||||
}
|
||||
|
||||
@include breakpoint(mobile) {
|
||||
width: 2.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
input.bulk.first {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
input.bulk.second {
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.bulk-input-container {
|
||||
float: right;
|
||||
|
||||
@include breakpoint(phablet) {
|
||||
float: left !important;
|
||||
}
|
||||
|
||||
.bulk-input {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Components to add variants to cart and change quanities
|
||||
@@ -106,3 +65,29 @@ button.variant-quantity {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
button.bulk-buy.variant-quantity {
|
||||
background-color: transparent;
|
||||
border: .1em solid $grey-200;
|
||||
color: inherit;
|
||||
}
|
||||
button.bulk-buy-add.variant-quantity {
|
||||
width: 2.5rem
|
||||
}
|
||||
span.bulk-buy.variant-quantity {
|
||||
border: .1em solid $grey-200;
|
||||
height: 2.5rem;
|
||||
display: inline-block;
|
||||
min-width: 3em;
|
||||
padding: .5em;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
}
|
||||
.variant-bulk-buy-price-summary {
|
||||
color: $disabled-med;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.variant-bulk-buy-quantity-label {
|
||||
font-size: 0.875rem;
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
|
||||
@@ -243,20 +243,24 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
it "should save group buy data to the cart and display it on shopfront reload" do
|
||||
# -- Quantity
|
||||
click_add_bulk_to_cart variant, 6
|
||||
close_modal
|
||||
expect(page).to have_in_cart product.name
|
||||
toggle_cart
|
||||
|
||||
expect(order.reload.line_items.first.quantity).to eq(6)
|
||||
|
||||
# -- Max quantity
|
||||
click_add_bulk_max_to_cart variant, 7
|
||||
open_bulk_quantity_modal(variant)
|
||||
click_add_bulk_max_to_cart variant, 1
|
||||
|
||||
expect(order.reload.line_items.first.max_quantity).to eq(7)
|
||||
|
||||
# -- Reload
|
||||
visit shop_path
|
||||
expect(page).to have_field "variants[#{variant.id}]", with: 6
|
||||
expect(page).to have_field "variant_attributes[#{variant.id}][max_quantity]", with: 7
|
||||
within_variant(variant) do
|
||||
expect(page).to have_selector "button.bulk-buy:nth-of-type(1)", text: "6"
|
||||
expect(page).to have_selector "button.bulk-buy:nth-last-of-type(1)", text: "7"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -372,12 +376,14 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
|
||||
# -- Page updates
|
||||
# Update amount in cart
|
||||
expect(page).to have_field "variant_attributes[#{variant.id}][max_quantity]", with: '0', disabled: true
|
||||
within_variant(variant) do
|
||||
expect(page).to have_button "Add", disabled: true
|
||||
expect(page).to have_no_content "in cart"
|
||||
end
|
||||
|
||||
# Update amount available in product list
|
||||
# If amount falls to zero, variant should be greyed out and input disabled
|
||||
# If amount falls to zero, variant should be greyed out
|
||||
expect(page).to have_selector "#variant-#{variant.id}.out-of-stock"
|
||||
expect(page).to have_selector "#variants_#{variant.id}_max[disabled='disabled']"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -400,7 +406,7 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
|
||||
it "does not update max_quantity" do
|
||||
click_add_bulk_to_cart variant, 2
|
||||
click_add_bulk_max_to_cart variant, 3
|
||||
click_add_bulk_max_to_cart variant, 1
|
||||
close_modal
|
||||
|
||||
variant.update! on_hand: 1
|
||||
@@ -412,8 +418,10 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
expect(page).to have_content "#{product.name} - #{variant.unit_to_display} now only has 1 remaining"
|
||||
end
|
||||
|
||||
expect(page).to have_field "variants[#{variant.id}]", with: '1'
|
||||
expect(page).to have_field "variant_attributes[#{variant.id}][max_quantity]", with: '3'
|
||||
within_variant(variant) do
|
||||
expect(page).to have_selector "button.bulk-buy:nth-of-type(1)", text: "1"
|
||||
expect(page).to have_selector "button.bulk-buy:nth-last-of-type(1)", text: "3"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,12 +6,6 @@ module ShopWorkflow
|
||||
end
|
||||
|
||||
def wait_for_cart
|
||||
# Wait for debounce
|
||||
#
|
||||
# The auto-submit on these specific form elements (add to cart) now has a small built-in
|
||||
# waiting period before submitting the data...
|
||||
sleep 0.6
|
||||
|
||||
within find_body do
|
||||
# We ignore visibility in case the cart dropdown is not open.
|
||||
within '.cart-sidebar', visible: false do
|
||||
@@ -67,18 +61,21 @@ module ShopWorkflow
|
||||
|
||||
def click_add_bulk_to_cart(variant = nil, quantity = 1)
|
||||
within_variant(variant) do
|
||||
input = page.find("input")
|
||||
new_quantity = input.value.to_i + quantity
|
||||
fill_in input[:name], with: new_quantity
|
||||
click_button "Add"
|
||||
end
|
||||
within(".reveal-modal") do
|
||||
(quantity - 1).times do
|
||||
first(:button, "+").click
|
||||
end
|
||||
end
|
||||
wait_for_cart
|
||||
end
|
||||
|
||||
def click_add_bulk_max_to_cart(variant = nil, quantity = 1)
|
||||
within_variant(variant) do
|
||||
input = page.find(:field, "variant_attributes[#{variant.id}][max_quantity]")
|
||||
new_quantity = input.value.to_i + quantity
|
||||
fill_in input[:name], with: new_quantity
|
||||
within(".reveal-modal") do
|
||||
quantity.times do
|
||||
page.all("button", text: "+").last.click
|
||||
end
|
||||
end
|
||||
wait_for_cart
|
||||
end
|
||||
@@ -91,6 +88,12 @@ module ShopWorkflow
|
||||
end
|
||||
end
|
||||
|
||||
def open_bulk_quantity_modal(variant)
|
||||
within_variant(variant) do
|
||||
page.first("button.bulk-buy").click
|
||||
end
|
||||
end
|
||||
|
||||
def toggle_accordion(name)
|
||||
find("dd a", text: name).click
|
||||
end
|
||||
|
||||
@@ -54,6 +54,10 @@ module UIComponentHelper
|
||||
end
|
||||
end
|
||||
|
||||
def close_modal
|
||||
find("a.close-reveal-modal").click
|
||||
end
|
||||
|
||||
def have_reset_password
|
||||
have_content "An email with instructions on resetting your password has been sent!"
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user