mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-03 22:06:07 +00:00
Merge branch 'laura_and_will'
This commit is contained in:
@@ -4,6 +4,7 @@ Darkswarm.controller "HubsCtrl", ($scope, Hubs, Search, $document, $rootScope, H
|
||||
$scope.totalActive = FilterSelectorsService.totalActive
|
||||
$scope.clearAll = FilterSelectorsService.clearAll
|
||||
$scope.filterText = FilterSelectorsService.filterText
|
||||
$scope.FilterSelectorsService = FilterSelectorsService
|
||||
$scope.query = Search.search()
|
||||
|
||||
$scope.$watch "query", (query)->
|
||||
|
||||
@@ -3,6 +3,7 @@ Darkswarm.controller "ProducersCtrl", ($scope, Producers, $filter, FilterSelecto
|
||||
$scope.totalActive = FilterSelectorsService.totalActive
|
||||
$scope.clearAll = FilterSelectorsService.clearAll
|
||||
$scope.filterText = FilterSelectorsService.filterText
|
||||
$scope.FilterSelectorsService = FilterSelectorsService
|
||||
$scope.filtersActive = false
|
||||
$scope.activeTaxons = []
|
||||
$scope.query = Search.search()
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
Darkswarm.controller "ProductNodeCtrl", ($scope) ->
|
||||
|
||||
$scope.price = ->
|
||||
if $scope.product.variants.length > 0
|
||||
prices = (v.price for v in $scope.product.variants)
|
||||
Math.min.apply(null, prices)
|
||||
else
|
||||
$scope.product.price
|
||||
|
||||
Darkswarm.controller "ProductNodeCtrl", ($scope, $modal) ->
|
||||
$scope.enterprise = $scope.product.supplier # For the modal, so it's consistent
|
||||
$scope.hasVariants = $scope.product.variants.length > 0
|
||||
|
||||
$scope.triggerProductModal = ->
|
||||
$modal.open(templateUrl: "product_modal.html", scope: $scope)
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
Darkswarm.controller "ProductsCtrl", ($scope, $rootScope, Product, OrderCycle) ->
|
||||
Darkswarm.controller "ProductsCtrl", ($scope, $rootScope, Product, OrderCycle, FilterSelectorsService) ->
|
||||
$scope.Product = Product
|
||||
$scope.totalActive = FilterSelectorsService.totalActive
|
||||
$scope.clearAll = FilterSelectorsService.clearAll
|
||||
$scope.filterText = FilterSelectorsService.filterText
|
||||
$scope.FilterSelectorsService = FilterSelectorsService
|
||||
$scope.limit = 3
|
||||
$scope.ordering = {order: "name"}
|
||||
$scope.order_cycle = OrderCycle.order_cycle
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
Darkswarm.directive "productModal", ($modal)->
|
||||
restrict: 'E'
|
||||
replace: true
|
||||
template: "<a ng-transclude></a>"
|
||||
transclude: true
|
||||
link: (scope, elem, attrs, ctrl)->
|
||||
elem.on "click", =>
|
||||
scope.modalInstance = $modal.open(controller: ctrl, templateUrl: 'product_modal.html', scope: scope)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
Darkswarm.directive "shippingTypeSelector", (FilterSelectorsService)->
|
||||
restrict: 'E'
|
||||
replace: true
|
||||
templateUrl: 'shipping_type_selector.html'
|
||||
link: (scope, elem, attr)->
|
||||
scope.shippingTypes =
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
Darkswarm.directive "taxonSelector", (FilterSelectorsService)->
|
||||
restrict: 'E'
|
||||
replace: true
|
||||
scope:
|
||||
objects: "&"
|
||||
results: "="
|
||||
@@ -19,8 +20,12 @@ Darkswarm.directive "taxonSelector", (FilterSelectorsService)->
|
||||
taxons = {}
|
||||
selectors = []
|
||||
for object in scope.objects()
|
||||
for taxon in (object.taxons.concat object?.supplied_taxons)
|
||||
for taxon in object.taxons
|
||||
taxons[taxon.id] = taxon
|
||||
if object.supplied_taxons
|
||||
for taxon in object.supplied_taxons
|
||||
taxons[taxon.id] = taxon
|
||||
|
||||
for id, taxon of taxons
|
||||
if selector = selectors_by_id[id]
|
||||
selectors.push selector
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Darkswarm.factory 'Product', ($resource, Enterprises) ->
|
||||
new class Product
|
||||
Darkswarm.factory 'Product', ($resource, Enterprises, Dereferencer, Taxons) ->
|
||||
new class Products
|
||||
constructor: ->
|
||||
@update()
|
||||
|
||||
@@ -10,7 +10,8 @@ Darkswarm.factory 'Product', ($resource, Enterprises) ->
|
||||
|
||||
update: =>
|
||||
@loading = true
|
||||
@products = $resource("/shop/products").query =>
|
||||
@products = $resource("/shop/products").query (products)=>
|
||||
@extend()
|
||||
@dereference()
|
||||
@loading = false
|
||||
@
|
||||
@@ -18,3 +19,12 @@ Darkswarm.factory 'Product', ($resource, Enterprises) ->
|
||||
dereference: ->
|
||||
for product in @products
|
||||
product.supplier = Enterprises.enterprises_by_id[product.supplier.id]
|
||||
Dereferencer.dereference product.taxons, Taxons.taxons_by_id
|
||||
|
||||
extend: ->
|
||||
for product in @products
|
||||
if product.variants.length > 0
|
||||
prices = (v.price for v in product.variants)
|
||||
product.price = Math.min.apply(null, prices)
|
||||
|
||||
product.hasVariants = product.variants.length > 0
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
%ul.small-block-grid-2.large-block-grid-1
|
||||
%active-selector{"ng-repeat" => "(name, selector) in selectors"}
|
||||
%i{"ng-class" => "selector.icon"}
|
||||
{{ name | capitalize }}
|
||||
%active-selector{"ng-repeat" => "(name, selector) in selectors"}
|
||||
%i{"ng-class" => "selector.icon"}
|
||||
{{ name | capitalize }}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
%ul.small-block-grid-2.large-block-grid-5
|
||||
%active-selector{"ng-repeat" => "selector in selectors()"}
|
||||
%render-svg{path: "{{selector.taxon.icon}}"}
|
||||
%span {{ selector.taxon.name }}
|
||||
%active-selector{"ng-repeat" => "selector in selectors()"}
|
||||
%render-svg{path: "{{selector.taxon.icon}}"}
|
||||
%span {{ selector.taxon.name }}
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
@import mixins
|
||||
@import "compass/css3/user-interface"
|
||||
|
||||
|
||||
.no-results
|
||||
font-size: 1.875rem
|
||||
|
||||
.active_table
|
||||
margin: 2em 0em
|
||||
@include user-select(none)
|
||||
@@ -9,9 +13,7 @@
|
||||
display: block
|
||||
&:first-child
|
||||
cursor: pointer
|
||||
|
||||
.no-results
|
||||
font-size: 1.875rem
|
||||
padding: 1rem 0
|
||||
|
||||
.active_table .active_table_node
|
||||
display: block
|
||||
|
||||
@@ -11,17 +11,23 @@
|
||||
.row.filter-box:first-child
|
||||
border-top: 1px solid $clr-brick
|
||||
|
||||
products .filter-box
|
||||
background: #f7f7f7
|
||||
|
||||
.filter-box
|
||||
background: rgba(255,255,255,0.65)
|
||||
background: rgba(245,245,245,0.6)
|
||||
|
||||
.tdhead
|
||||
padding: 0.25rem 0.5rem
|
||||
margin-top: 0.9rem
|
||||
|
||||
// OVERRIDES
|
||||
[class*="block-grid-"]
|
||||
margin: 0 0 0.5rem 0
|
||||
[class*="block-grid-"] > li
|
||||
padding-bottom: 0.5rem !important
|
||||
|
||||
|
||||
li
|
||||
@include border-radius(12px)
|
||||
padding-top: 0.5rem
|
||||
@@ -45,6 +51,7 @@
|
||||
@include csstrans
|
||||
display: table
|
||||
table-layout: fixed
|
||||
text-transform: capitalize
|
||||
overflow: visible
|
||||
// width: 100%
|
||||
// height: 2rem
|
||||
|
||||
@@ -83,28 +83,35 @@
|
||||
filter: alpha(opacity = 50)
|
||||
opacity: .5
|
||||
|
||||
|
||||
.animate-repeat
|
||||
line-height: 40px
|
||||
list-style: none
|
||||
box-sizing: border-box
|
||||
border-color: rgba(153, 153, 153, 1)
|
||||
-webkit-transform: translateZ(0)
|
||||
transform: translateZ(0)
|
||||
&.ng-move, &.ng-enter, &.ng-leave
|
||||
-webkit-transition: all 1s linear
|
||||
transition: all 1s linear
|
||||
|
||||
&.ng-leave
|
||||
opacity: 1
|
||||
border-color: rgba(153, 153, 153, 1)
|
||||
//max-height: 200px
|
||||
&.ng-leave-active
|
||||
opacity: 0
|
||||
//max-height: 0px
|
||||
border-color: rgba(153, 153, 153, 0)
|
||||
|
||||
.animate-repeat.ng-move,
|
||||
.animate-repeat.ng-enter,
|
||||
.animate-repeat.ng-leave
|
||||
-webkit-transition: all linear 0.2s
|
||||
transition: all linear 0.2s
|
||||
&.ng-enter
|
||||
opacity: 0
|
||||
border-color: rgba(153, 153, 153, 0)
|
||||
//max-height: 0px
|
||||
&.ng-enter-active
|
||||
//max-height: 200px
|
||||
opacity: 1
|
||||
border-color: rgba(153, 153, 153, 1)
|
||||
|
||||
.animate-repeat.ng-leave.ng-leave-active,
|
||||
.animate-repeat.ng-move,
|
||||
.animate-repeat.ng-enter
|
||||
opacity: 0
|
||||
max-height: 0
|
||||
|
||||
.animate-repeat.ng-leave,
|
||||
.animate-repeat.ng-move.ng-move-active,
|
||||
.animate-repeat.ng-enter.ng-enter-active
|
||||
opacity: 1
|
||||
max-height: 40px
|
||||
&.ng-move
|
||||
&.ng-move-active
|
||||
|
||||
|
||||
.animate-show
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
box-shadow: 0
|
||||
padding: 0.75rem 1rem 0.35rem 1rem
|
||||
height: auto
|
||||
width: 100%
|
||||
margin-bottom: 0.5rem
|
||||
box-shadow: none
|
||||
color: $inputactv
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
|
||||
.darkswarm
|
||||
// #search
|
||||
@include placeholder(rgba(0,0,0,0.3), #999)
|
||||
@include placeholder(rgba(0,0,0,0.4), #777)
|
||||
|
||||
input#search
|
||||
@include big-input(rgba(0,0,0,0.2), #999, #000)
|
||||
@include big-input(rgba(0,0,0,0.3), #777, $clr-brick)
|
||||
@include big-input-static
|
||||
|
||||
color: #666
|
||||
@@ -115,7 +115,7 @@
|
||||
.columns
|
||||
padding-top: 1em
|
||||
padding-bottom: 1em
|
||||
line-height: 2.4em
|
||||
line-height: 1em
|
||||
|
||||
.row.summary, .row.variants
|
||||
margin-left: 0
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
line-height: 1
|
||||
margin-right: 0.5rem
|
||||
margin-bottom: 0.35rem
|
||||
text-transform: uppercase
|
||||
text-transform: capitalize
|
||||
font-weight: 300
|
||||
font-size: 0.875rem
|
||||
background: rgba(235,235,235,0.5)
|
||||
|
||||
@@ -7,13 +7,15 @@
|
||||
%h5.tdhead
|
||||
.light Filter by
|
||||
Type
|
||||
%taxon-selector{objects: "hubs | hubs:query",
|
||||
results: "activeTaxons"}
|
||||
%ul.small-block-grid-2.medium-block-grid-4.large-block-grid-5
|
||||
%taxon-selector{objects: "hubs | hubs:query",
|
||||
results: "activeTaxons"}
|
||||
.small-12.large-3.columns
|
||||
%h5.tdhead
|
||||
.light Filter by
|
||||
Delivery
|
||||
%shipping-type-selector{results: "shippingTypes"}
|
||||
%ul.small-block-grid-2.medium-block-grid-4.large-block-grid-2
|
||||
%shipping-type-selector{results: "shippingTypes"}
|
||||
.row.filter-box.animate-show{"ng-show" => "filtersActive && totalActive() > 0"}
|
||||
.small-12.columns
|
||||
%a.button.secondary.small.expand{"ng-click" => "clearAll()"}
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
%h5.tdhead
|
||||
.light Filter by
|
||||
Type
|
||||
%taxon-selector{objects: "Producers.visible | filterProducers:query",
|
||||
results: "activeTaxons"}
|
||||
%ul.small-block-grid-2.medium-block-grid-4.large-block-grid-6
|
||||
%taxon-selector{objects: "Producers.visible | filterProducers:query",
|
||||
results: "activeTaxons"}
|
||||
|
||||
.row.filter-box.animate-show{"ng-show" => "filtersActive && totalActive() > 0"}
|
||||
.small-12.columns
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
.row
|
||||
.small-12.columns
|
||||
%a.button.primary.tiny.filterbtn{{"ng-click" => "filtersActive = !filtersActive"}}
|
||||
%a.button.primary.tiny.filterbtn{"ng-click" => "filtersActive = !filtersActive",
|
||||
"ng-show" => "FilterSelectorsService.selectors.length > 0"}
|
||||
{{ filterText(filtersActive) }}
|
||||
%i.ofn-i_005-caret-down{"ng-show" => "!filtersActive"}
|
||||
%i.ofn-i_006-caret-up{"ng-show" => "filtersActive"}
|
||||
|
||||
%a.button.secondary.tiny.filterbtn.disabled{"ng-show" => "FilterSelectorsService.selectors.length == 0"}
|
||||
No filters
|
||||
|
||||
@@ -43,7 +43,7 @@ node :variants do |product|
|
||||
end
|
||||
|
||||
child :taxons => :taxons do |taxon|
|
||||
attributes :name
|
||||
attributes :id
|
||||
end
|
||||
|
||||
child :properties => :properties do |property|
|
||||
|
||||
18
app/views/shop/products/_filters.html.haml
Normal file
18
app/views/shop/products/_filters.html.haml
Normal file
@@ -0,0 +1,18 @@
|
||||
= render partial: 'shared/components/filter_controls'
|
||||
|
||||
.row.animate-show{"ng-show" => "filtersActive"}
|
||||
.small-12.columns
|
||||
.row.filter-box
|
||||
.small-12.columns
|
||||
%h5.tdhead
|
||||
.light Filter by
|
||||
Type
|
||||
%ul.small-block-grid-2.medium-block-grid-3.large-block-grid-4
|
||||
%taxon-selector{objects: "Product.products | products:query",
|
||||
results: "activeTaxons"}
|
||||
|
||||
.row.filter-box.animate-show{"ng-show" => "filtersActive && totalActive() > 0"}
|
||||
.small-12.columns
|
||||
%a.button.secondary.small.expand{"ng-click" => "clearAll()"}
|
||||
%i.ofn-i_009-close
|
||||
Clear all filters
|
||||
@@ -1,30 +1,42 @@
|
||||
%products.small-12.columns{"ng-controller" => "ProductsCtrl", "ng-show" => "order_cycle.order_cycle_id != null",
|
||||
"infinite-scroll" => "incrementLimit()", "infinite-scroll-distance" => "1"}
|
||||
|
||||
|
||||
= form_for :order, :url => populate_orders_path, html: {:class => "custom"} do
|
||||
.row
|
||||
.small-6.columns
|
||||
.small-12.medium-8.large-8.columns
|
||||
%input#search.text{"ng-model" => "query",
|
||||
placeholder: "Search products",
|
||||
"ng-debounce" => "150",
|
||||
placeholder: "Search by product or producer",
|
||||
"ng-debounce" => "100",
|
||||
"ofn-disable-enter" => true}
|
||||
.small-6.columns
|
||||
|
||||
= render partial: "shop/products/filters"
|
||||
|
||||
.small-12.medium-4.large-4.columns
|
||||
%input.button.primary.right{type: :submit, value: "Add to Cart"}
|
||||
|
||||
%div{bindonce: true}
|
||||
|
||||
%div.pad-top{bindonce: true}
|
||||
%product.animate-repeat{"ng-controller" => "ProductNodeCtrl",
|
||||
"ng-repeat" => "product in Product.products | products:query | orderBy:ordering.order"}
|
||||
"ng-repeat" => "product in filteredProducts = (Product.products | products:query | taxons:activeTaxons | orderBy:ordering.order) track by product.id "}
|
||||
%div
|
||||
= render partial: "shop/products/summary"
|
||||
%div{"bo-if" => "hasVariants"}
|
||||
%div{"bo-if" => "product.hasVariants"}
|
||||
= render partial: "shop/products/variants"
|
||||
.variants.row{"bo-if" => "!hasVariants"}
|
||||
.variants.row{"bo-if" => "!product.hasVariants"}
|
||||
= render partial: "shop/products/master"
|
||||
|
||||
%product{"ng-show" => "Product.loading"}
|
||||
.row.summary
|
||||
.small-12.columns.text-center
|
||||
Loading products
|
||||
|
||||
%div{"ng-show" => "filteredProducts.length == 0 && !Product.loading"}
|
||||
.row.summary
|
||||
.small-12.columns
|
||||
%p.no-results
|
||||
Sorry, no results found for
|
||||
%strong {{query}}.
|
||||
Try another search?
|
||||
.row
|
||||
.small-12.columns
|
||||
%input.button.primary.right.add_to_cart{type: :submit, value: "Add to Cart"}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
.row.summary
|
||||
.small-1.columns
|
||||
%product-modal
|
||||
%img{"bo-src" => "product.master.images[0].small_url"}
|
||||
%img{"bo-src" => "product.master.images[0].small_url", "ng-click" => "triggerProductModal()"}
|
||||
|
||||
.small-4.columns.summary-header
|
||||
%render-svg{path: "{{product.primary_taxon.icon}}"}
|
||||
%product-modal {{ product.name }}
|
||||
%a{"ng-click" => "triggerProductModal()"}{{ product.name }}
|
||||
|
||||
.small-5.columns
|
||||
%i.ofn-i_036-producers
|
||||
%producer-modal {{ enterprise.name }}
|
||||
|
||||
.small-2.columns.summary-price.text-right.price
|
||||
%span{"ng-if" => "hasVariants"}
|
||||
%span{"ng-if" => "product.hasVariants"}
|
||||
%em from
|
||||
{{ price() | currency }}
|
||||
{{ product.price | currency }}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.row.variants{bindonce: true,
|
||||
"ng-repeat" => "variant in product.variants"}
|
||||
"ng-repeat" => "variant in product.variants track by variant.id"}
|
||||
|
||||
.small-1.columns
|
||||
%i.ofn-i_056-bulk{"bo-if" => "product.group_buy"}
|
||||
|
||||
Reference in New Issue
Block a user