Skip to content

Commit

Permalink
Merge pull request #4345 from Matt-Yorkley/shopfront_pagination
Browse files Browse the repository at this point in the history
Shopfront pagination
  • Loading branch information
luisramos0 authored Oct 21, 2019
2 parents c9e2315 + 7b0c55e commit 02c0b89
Show file tree
Hide file tree
Showing 91 changed files with 980 additions and 2,476 deletions.
7 changes: 0 additions & 7 deletions .rubocop_manual_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ Metrics/LineLength:
- lib/open_food_network/payments_report.rb
- lib/open_food_network/permalink_generator.rb
- lib/open_food_network/products_cache.rb
- lib/open_food_network/products_renderer.rb
- lib/open_food_network/reports/bulk_coop_allocation_report.rb
- lib/open_food_network/reports/line_items.rb
- lib/open_food_network/sales_tax_report.rb
Expand Down Expand Up @@ -249,13 +248,10 @@ Metrics/LineLength:
- spec/helpers/order_cycles_helper_spec.rb
- spec/helpers/spree/admin/base_helper_spec.rb
- spec/jobs/confirm_order_job_spec.rb
- spec/jobs/products_cache_integrity_checker_job_spec.rb
- spec/jobs/refresh_products_cache_job_spec.rb
- spec/jobs/subscription_confirm_job_spec.rb
- spec/jobs/subscription_placement_job_spec.rb
- spec/lib/open_food_network/address_finder_spec.rb
- spec/lib/open_food_network/bulk_coop_report_spec.rb
- spec/lib/open_food_network/cached_products_renderer_spec.rb
- spec/lib/open_food_network/customers_report_spec.rb
- spec/lib/open_food_network/enterprise_fee_applicator_spec.rb
- spec/lib/open_food_network/enterprise_fee_calculator_spec.rb
Expand All @@ -272,7 +268,6 @@ Metrics/LineLength:
- spec/lib/open_food_network/permissions_spec.rb
- spec/lib/open_food_network/products_and_inventory_report_spec.rb
- spec/lib/open_food_network/products_cache_spec.rb
- spec/lib/open_food_network/products_renderer_spec.rb
- spec/lib/open_food_network/proxy_order_syncer_spec.rb
- spec/lib/open_food_network/scope_variant_to_hub_spec.rb
- spec/lib/open_food_network/subscription_payment_updater_spec.rb
Expand Down Expand Up @@ -615,7 +610,6 @@ Metrics/MethodLength:
- lib/open_food_network/payments_report.rb
- lib/open_food_network/permissions.rb
- lib/open_food_network/products_and_inventory_report.rb
- lib/open_food_network/products_renderer.rb
- lib/open_food_network/rack_request_blocker.rb
- lib/open_food_network/reports/bulk_coop_allocation_report.rb
- lib/open_food_network/reports/bulk_coop_supplier_report.rb
Expand Down Expand Up @@ -670,7 +664,6 @@ Metrics/ModuleLength:
- spec/controllers/api/orders_controller_spec.rb
- spec/controllers/spree/api/products_controller_spec.rb
- spec/lib/open_food_network/address_finder_spec.rb
- spec/lib/open_food_network/cached_products_renderer_spec.rb
- spec/lib/open_food_network/customers_report_spec.rb
- spec/lib/open_food_network/enterprise_fee_calculator_spec.rb
- spec/lib/open_food_network/option_value_namer_spec.rb
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
Darkswarm.controller "OrderCycleCtrl", ($scope, $timeout, OrderCycle) ->
Darkswarm.controller "OrderCycleCtrl", ($scope, $rootScope, $timeout, OrderCycle) ->
$scope.order_cycle = OrderCycle.order_cycle
$scope.OrderCycle = OrderCycle

# Timeout forces this to be evaluated after everything is loaded
# This is a hack. We should probably write our own "popover" directive
# That takes an expression instead of a trigger, and binds to that
$timeout =>
$rootScope.$broadcast 'orderCycleSelected'
if !$scope.OrderCycle.selected()
$("#order_cycle_id").trigger("openTrigger")


Darkswarm.controller "OrderCycleChangeCtrl", ($scope, $timeout, OrderCycle, Products, Variants, Cart, ChangeableOrdersAlert) ->
Darkswarm.controller "OrderCycleChangeCtrl", ($scope, $rootScope, $timeout, OrderCycle, Products, Variants, Cart, ChangeableOrdersAlert) ->
# Track previous order cycle id for use with revertOrderCycle()
$scope.previous_order_cycle_id = OrderCycle.order_cycle.order_cycle_id
$scope.$watch 'order_cycle.order_cycle_id', (newValue, oldValue)->
Expand All @@ -32,3 +33,4 @@ Darkswarm.controller "OrderCycleChangeCtrl", ($scope, $timeout, OrderCycle, Prod
Products.update()
Cart.reloadFinalisedLineItems()
ChangeableOrdersAlert.reload()
$rootScope.$broadcast 'orderCycleSelected'
Original file line number Diff line number Diff line change
@@ -1,41 +1,65 @@
Darkswarm.controller "ProductsCtrl", ($scope, $filter, $rootScope, Products, OrderCycle, FilterSelectorsService, Cart, Taxons, Properties) ->
Darkswarm.controller "ProductsCtrl", ($scope, $filter, $rootScope, Products, OrderCycle, OrderCycleResource, FilterSelectorsService, Cart, Dereferencer, Taxons, Properties, currentHub, $timeout) ->
$scope.Products = Products
$scope.Cart = Cart
$scope.query = ""
$scope.taxonSelectors = FilterSelectorsService.createSelectors()
$scope.propertySelectors = FilterSelectorsService.createSelectors()
$scope.filtersActive = true
$scope.limit = 10
$scope.page = 1
$scope.per_page = 10
$scope.order_cycle = OrderCycle.order_cycle
# $scope.infiniteDisabled = true

# All of this logic basically just replicates the functionality filtering an ng-repeat
# except that it allows us to filter a separate list before rendering, meaning that
# we can get much better performance when applying filters by resetting the limit on the
# number of products being rendered each time a filter is changed.

$scope.$watch "Products.loading", (newValue, oldValue) ->
$scope.updateFilteredProducts()
$scope.$broadcast("loadFilterSelectors") if !newValue

$scope.incrementLimit = ->
if $scope.limit < Products.products.length
$scope.limit += 10
$scope.updateVisibleProducts()

$scope.$watch 'query', -> $scope.updateFilteredProducts()
$scope.$watchCollection 'activeTaxons', -> $scope.updateFilteredProducts()
$scope.$watchCollection 'activeProperties', -> $scope.updateFilteredProducts()

$scope.updateFilteredProducts = ->
$scope.limit = 10
f1 = $filter('products')(Products.products, $scope.query)
f2 = $filter('taxons')(f1, $scope.activeTaxons)
$scope.filteredProducts = $filter('properties')(f2, $scope.activeProperties)
$scope.updateVisibleProducts()

$scope.updateVisibleProducts = ->
$scope.visibleProducts = $filter('limitTo')($scope.filteredProducts, $scope.limit)
$scope.supplied_taxons = null
$scope.supplied_properties = null

$rootScope.$on "orderCycleSelected", ->
$scope.update_filters()
$scope.clearAll()

$scope.update_filters = ->
order_cycle_id = OrderCycle.order_cycle.order_cycle_id

return unless order_cycle_id

params = {
id: order_cycle_id,
distributor: currentHub.id
}
OrderCycleResource.taxons params, (data)=>
$scope.supplied_taxons = {}
data.map( (taxon) ->
$scope.supplied_taxons[taxon.id] = Taxons.taxons_by_id[taxon.id]
)
OrderCycleResource.properties params, (data)=>
$scope.supplied_properties = {}
data.map( (property) ->
$scope.supplied_properties[property.id] = Properties.properties_by_id[property.id]
)

$scope.loadMore = ->
if ($scope.page * $scope.per_page) <= Products.products.length
$scope.loadMoreProducts()

$scope.$watch 'query', (newValue, oldValue) -> $scope.loadProducts() if newValue != oldValue
$scope.$watchCollection 'activeTaxons', (newValue, oldValue) -> $scope.loadProducts() if newValue != oldValue
$scope.$watchCollection 'activeProperties', (newValue, oldValue) -> $scope.loadProducts() if newValue != oldValue

$scope.loadProducts = ->
$scope.page = 1
Products.update($scope.queryParams())

$scope.loadMoreProducts = ->
Products.update($scope.queryParams($scope.page + 1), true)
$scope.page += 1

$scope.queryParams = (page = null) ->
{
id: $scope.order_cycle.order_cycle_id,
page: page || $scope.page,
per_page: $scope.per_page,
'q[name_or_meta_keywords_or_supplier_name_cont]': $scope.query,
'q[properties_id_or_supplier_properties_id_in_any][]': $scope.activeProperties,
'q[primary_taxon_id_in_any][]': $scope.activeTaxons
}

$scope.searchKeypress = (e)->
code = e.keyCode || e.which
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Darkswarm.factory 'OrderCycleResource', ($resource) ->
$resource('/api/order_cycles/:id', {}, {
'products':
method: 'GET'
isArray: true
url: '/api/order_cycles/:id/products'
params:
id: '@id'
'taxons':
method: 'GET'
isArray: true
url: '/api/order_cycles/:id/taxons'
params:
id: '@id'
'properties':
method: 'GET'
isArray: true
url: '/api/order_cycles/:id/properties'
params:
id: '@id'
})
30 changes: 19 additions & 11 deletions app/assets/javascripts/darkswarm/services/products.js.coffee
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
Darkswarm.factory 'Products', ($resource, Shopfront, Dereferencer, Taxons, Properties, Cart, Variants) ->
Darkswarm.factory 'Products', (OrderCycleResource, OrderCycle, Shopfront, currentHub, Dereferencer, Taxons, Properties, Cart, Variants) ->
new class Products
constructor: ->
@update()

# TODO: don't need to scope this into object
# Already on object as far as controller scope is concerned
products: null
products: []
fetched_products: []
loading: true

update: =>
update: (params = {}, load_more = false) =>
@loading = true
@products = []
$resource("/shop/products").query (products)=>
@products = products
order_cycle_id = OrderCycle.order_cycle.order_cycle_id

if order_cycle_id == undefined
@loading = false
return

params['id'] = order_cycle_id
params['distributor'] = currentHub.id

OrderCycleResource.products params, (data)=>
@products = [] unless load_more
@fetched_products = data
@extend()
@dereference()
@registerVariants()
@products = @products.concat(@fetched_products)
@loading = false

extend: ->
for product in @products
for product in @fetched_products
if product.variants?.length > 0
prices = (v.price for v in product.variants)
product.price = Math.min.apply(null, prices)
Expand All @@ -30,7 +38,7 @@ Darkswarm.factory 'Products', ($resource, Shopfront, Dereferencer, Taxons, Prope
product.largeImage = product.images[0]?.large_url if product.images

dereference: ->
for product in @products
for product in @fetched_products
product.supplier = Shopfront.producers_by_id[product.supplier.id]
Dereferencer.dereference product.taxons, Taxons.taxons_by_id

Expand All @@ -40,7 +48,7 @@ Darkswarm.factory 'Products', ($resource, Shopfront, Dereferencer, Taxons, Prope
# May return different objects! If the variant has already been registered
# by another service, we fetch those
registerVariants: ->
for product in @products
for product in @fetched_products
if product.variants
product.variant_names = ""
product.variants = for variant in product.variants
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/templates/shop_variant.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
.small-4.medium-2.large-2.columns.variant-price
.table-cell.price
%i.ofn-i_009-close
{{ ::variant.price_with_fees | localizeCurrency }}
{{ variant.price_with_fees | localizeCurrency }}
-# Now in a template in app/assets/javascripts/templates !
%price-breakdown{"price-breakdown" => "_", variant: "variant",
Expand Down
27 changes: 0 additions & 27 deletions app/controllers/admin/cache_settings_controller.rb

This file was deleted.

88 changes: 88 additions & 0 deletions app/controllers/api/order_cycles_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
module Api
class OrderCyclesController < BaseController
include EnterprisesHelper
respond_to :json

skip_authorization_check

def products
products = ProductsRenderer.new(
distributor,
order_cycle,
customer,
search_params
).products_json

render json: products
rescue ProductsRenderer::NoProducts
render status: :not_found, json: ''
end

def taxons
taxons = Spree::Taxon.
joins(:products).
where(spree_products: { id: distributed_products }).
select('DISTINCT spree_taxons.*')

render json: ActiveModel::ArraySerializer.new(taxons, each_serializer: Api::TaxonSerializer)
end

def properties
render json: ActiveModel::ArraySerializer.new(
product_properties | producer_properties, each_serializer: Api::PropertySerializer
)
end

private

def product_properties
Spree::Property.
joins(:products).
where(spree_products: { id: distributed_products }).
select('DISTINCT spree_properties.*')
end

def producer_properties
producers = Enterprise.
joins(:supplied_products).
where(spree_products: { id: distributed_products })

Spree::Property.
joins(:producer_properties).
where(producer_properties: { producer_id: producers }).
select('DISTINCT spree_properties.*')
end

def search_params
permitted_search_params = params.slice :q, :page, :per_page

if permitted_search_params.key? :q
permitted_search_params[:q].slice!(*permitted_ransack_params)
end

permitted_search_params
end

def permitted_ransack_params
[:name_or_meta_keywords_or_supplier_name_cont,
:properties_id_or_supplier_properties_id_in_any,
:primary_taxon_id_in_any]
end

def distributor
Enterprise.find_by_id(params[:distributor])
end

def order_cycle
OrderCycle.find_by_id(params[:id])
end

def customer
@current_api_user.andand.customer_of(distributor) || nil
end

def distributed_products
OrderCycleDistributedProducts.new(distributor, order_cycle, customer).products_relation
end
end
end
Loading

0 comments on commit 02c0b89

Please sign in to comment.