From 6bdc5d4438939a670a6b6406dc97252bdb9908ef Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Mon, 6 May 2019 01:26:15 +0100 Subject: [PATCH] Fix maps performance --- .../services/enterprise_modal.js.coffee | 9 +- app/controllers/api/enterprises_controller.rb | 6 + app/helpers/injection_helper.rb | 8 ++ .../enterprise_shopfront_list_serializer.rb | 52 +++++++ .../api/enterprise_shopfront_serializer.rb | 133 ++++++++++++++++++ .../api/enterprise_thin_serializer.rb | 21 +++ app/views/map/index.html.haml | 2 +- config/routes.rb | 4 + 8 files changed, 231 insertions(+), 4 deletions(-) create mode 100644 app/serializers/api/enterprise_shopfront_list_serializer.rb create mode 100644 app/serializers/api/enterprise_shopfront_serializer.rb create mode 100644 app/serializers/api/enterprise_thin_serializer.rb diff --git a/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee b/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee index ae43c85090..19361fe508 100644 --- a/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee +++ b/app/assets/javascripts/darkswarm/services/enterprise_modal.js.coffee @@ -1,9 +1,12 @@ -Darkswarm.factory "EnterpriseModal", ($modal, $rootScope)-> +Darkswarm.factory "EnterpriseModal", ($modal, $rootScope, $http)-> # Build a modal popup for an enterprise. new class EnterpriseModal open: (enterprise)-> scope = $rootScope.$new(true) # Spawn an isolate to contain the enterprise scope.embedded_layout = window.location.search.indexOf("embedded_shopfront=true") != -1 - scope.enterprise = enterprise - $modal.open(templateUrl: "enterprise_modal.html", scope: scope) + $http.get("/api/enterprises/" + enterprise.id + "/shopfront").success (data) -> + scope.enterprise = data + $modal.open(templateUrl: "enterprise_modal.html", scope: scope) + .error (data) -> + console.error(data) diff --git a/app/controllers/api/enterprises_controller.rb b/app/controllers/api/enterprises_controller.rb index c1f6fb3ce7..ca828f707a 100644 --- a/app/controllers/api/enterprises_controller.rb +++ b/app/controllers/api/enterprises_controller.rb @@ -47,6 +47,12 @@ module Api end end + def shopfront + enterprise = Enterprise.find_by_id(params[:id]) + + render text: Api::EnterpriseShopfrontSerializer.new(enterprise).to_json, status: :ok + end + private def override_owner diff --git a/app/helpers/injection_helper.rb b/app/helpers/injection_helper.rb index aaec90f0b8..60fc2bbde5 100644 --- a/app/helpers/injection_helper.rb +++ b/app/helpers/injection_helper.rb @@ -10,6 +10,14 @@ module InjectionHelper ) end + def inject_enterprise_shopfront_list + inject_json_ams( + 'enterprises', + Enterprise.activated.includes(address: :state).all, + Api::EnterpriseShopfrontListSerializer + ) + end + def inject_enterprise_and_relatives inject_json_ams "enterprises", current_distributor.relatives_including_self.activated.includes(address: :state).all, Api::EnterpriseSerializer, enterprise_injection_data end diff --git a/app/serializers/api/enterprise_shopfront_list_serializer.rb b/app/serializers/api/enterprise_shopfront_list_serializer.rb new file mode 100644 index 0000000000..30b5ed3590 --- /dev/null +++ b/app/serializers/api/enterprise_shopfront_list_serializer.rb @@ -0,0 +1,52 @@ +# Represents the minimum details of an Enterprise when all shopfronts are being listed +module Api + class EnterpriseShopfrontListSerializer < ActiveModel::Serializer + attributes :name, :id, :latitude, :longitude, :is_primary_producer, :is_distributor, + :visible, :path, :icon, :icon_font, :producer_icon_font + + has_one :address, serializer: Api::AddressSerializer + + def path + enterprise_shop_path(enterprise) + end + + def icon + icons = { + hub: "/assets/map_005-hub.svg", + hub_profile: "/assets/map_006-hub-profile.svg", + producer_hub: "/assets/map_005-hub.svg", + producer_shop: "/assets/map_003-producer-shop.svg", + producer: "/assets/map_001-producer-only.svg", + } + icons[enterprise.category] + end + + def icon_font + icon_fonts = { + hub: "ofn-i_063-hub", + hub_profile: "ofn-i_064-hub-reversed", + producer_hub: "ofn-i_063-hub", + producer_shop: "ofn-i_059-producer", + producer: "ofn-i_059-producer", + } + icon_fonts[enterprise.category] + end + + def producer_icon_font + icon_fonts = { + hub: "", + hub_profile: "", + producer_hub: "ofn-i_059-producer", + producer_shop: "ofn-i_059-producer", + producer: "ofn-i_059-producer", + } + icon_fonts[enterprise.category] + end + + private + + def enterprise + object + end + end +end diff --git a/app/serializers/api/enterprise_shopfront_serializer.rb b/app/serializers/api/enterprise_shopfront_serializer.rb new file mode 100644 index 0000000000..6b800ffcd7 --- /dev/null +++ b/app/serializers/api/enterprise_shopfront_serializer.rb @@ -0,0 +1,133 @@ +# Represents the properties of an Enterprise when viewing the details of listed shopfronts +module Api + class EnterpriseShopfrontSerializer < ActiveModel::Serializer + include SerializerHelper + + attributes :name, :id, :description, :latitude, :longitude, :long_description, :website, + :instagram, :linkedin, :twitter, :facebook, :is_primary_producer, :is_distributor, + :phone, :visible, :email_address, :hash, :logo, :promo_image, :path, :category, + :active, :producers, :orders_close_at, :hubs, :taxons, :supplied_taxons, :pickup, + :delivery + + has_one :address, serializer: Api::AddressSerializer + has_many :supplied_properties, serializer: Api::PropertySerializer + has_many :distributed_properties, serializer: Api::PropertySerializer + + def orders_close_at + OrderCycle.with_distributor(enterprise).soonest_closing.first.andand.orders_close_at + end + + def active + enterprise.ready_for_checkout? && OrderCycle.active.with_distributor(enterprise).exists? + end + + def pickup + shipping_types? :pickup + end + + def delivery + shipping_types? :delivery + end + + def email_address + enterprise.email_address.to_s.reverse + end + + def hash + enterprise.to_param + end + + def logo + enterprise.logo(:medium) if enterprise.logo? + end + + def promo_image + enterprise.promo_image(:large) if enterprise.promo_image? + end + + def path + enterprise_shop_path(enterprise) + end + + def producers + ActiveModel::ArraySerializer.new( + enterprise.suppliers, each_serializer: Api::EnterpriseThinSerializer + ) + end + + def hubs + ActiveModel::ArraySerializer.new( + enterprise.distributors, each_serializer: Api::EnterpriseThinSerializer + ) + end + + def taxons + ActiveModel::ArraySerializer.new( + enterprise.distributed_taxons, each_serializer: Api::TaxonSerializer + ) + end + + def supplied_taxons + ActiveModel::ArraySerializer.new( + enterprise.supplied_taxons, each_serializer: Api::TaxonSerializer + ) + end + + def supplied_properties + (product_properties + producer_properties).uniq do |property_object| + property_object.property.presentation + end + end + + def distributed_properties + (distributed_product_properties + distributed_producer_properties).uniq do |property_object| + property_object.property.presentation + end + end + + def distributed_product_properties + properties = Spree::Property.joins(products: { variants: { exchanges: :order_cycle } }) + .merge(Exchange.outgoing) + .merge(Exchange.to_enterprise(enterprise)) + .select('DISTINCT spree_properties.*') + + return properties.merge(OrderCycle.active) if active + properties + end + + def distributed_producer_properties + properties = Spree::Property.joins( + producer_properties: { + producer: { supplied_products: { variants: { exchanges: :order_cycle } } } + } + ) + .merge(Exchange.outgoing).merge(Exchange.to_enterprise(enterprise)) + .select('DISTINCT spree_properties.*') + + return properties.merge(OrderCycle.active) if active + properties + end + + private + + def product_properties + enterprise.supplied_products.flat_map(&:properties) + end + + def producer_properties + enterprise.properties + end + + def enterprise + object + end + + def shipping_types?(type) + require_shipping = type == :delivery ? 't' : 'f' + Spree::ShippingMethod. + joins(:distributor_shipping_methods). + where('distributors_shipping_methods.distributor_id = ?', enterprise.id). + where("spree_shipping_methods.require_ship_address = '#{require_shipping}'").exists? + end + end +end diff --git a/app/serializers/api/enterprise_thin_serializer.rb b/app/serializers/api/enterprise_thin_serializer.rb new file mode 100644 index 0000000000..cdc4d6b9eb --- /dev/null +++ b/app/serializers/api/enterprise_thin_serializer.rb @@ -0,0 +1,21 @@ +module Api + class EnterpriseThinSerializer < ActiveModel::Serializer + attributes :name, :id, :active, :path + + has_one :address, serializer: Api::AddressSerializer + + def active + enterprise.ready_for_checkout? && OrderCycle.active.with_distributor(enterprise).exists? + end + + def path + enterprise_shop_path(enterprise) + end + + private + + def enterprise + object + end + end +end diff --git a/app/views/map/index.html.haml b/app/views/map/index.html.haml index 75bb99f9d7..b66df8429f 100644 --- a/app/views/map/index.html.haml +++ b/app/views/map/index.html.haml @@ -1,7 +1,7 @@ - content_for(:title) do = t :label_map -= inject_enterprises += inject_enterprise_shopfront_list .map-container{"fill-vertical" => true} %map{"ng-controller" => "MapCtrl"} diff --git a/config/routes.rb b/config/routes.rb index 34d681fe11..f264d87144 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -96,6 +96,10 @@ Openfoodnetwork::Application.routes.draw do resource :logo, only: [:destroy] resource :promo_image, only: [:destroy] + + member do + get :shopfront + end end resources :order_cycles do