From c5471fc25c07f6e6e8ccb8f2c0859f852f6f4937 Mon Sep 17 00:00:00 2001 From: Guido Oliveira Date: Sun, 30 May 2021 17:24:00 -0300 Subject: [PATCH 1/4] enable ordering shopfront by producer id --- app/models/enterprise.rb | 2 ++ .../api/admin/enterprise_serializer.rb | 5 ++-- .../permitted_attributes/enterprise.rb | 3 ++- app/services/products_renderer.rb | 6 ++++- .../form/_shop_preferences.html.haml | 22 ++++++++++++++--- config/locales/en.yml | 3 +++ spec/models/enterprise_spec.rb | 2 ++ spec/services/products_renderer_spec.rb | 24 +++++++++++++++---- 8 files changed, 56 insertions(+), 11 deletions(-) diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 1b4697c57e..90bd877562 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -9,8 +9,10 @@ class Enterprise < ApplicationRecord preference :shopfront_message, :text, default: "" preference :shopfront_closed_message, :text, default: "" preference :shopfront_taxon_order, :string, default: "" + preference :shopfront_producer_order, :string, default: "" preference :shopfront_order_cycle_order, :string, default: "orders_close_at" preference :show_customer_names_to_suppliers, :boolean, default: false + preference :shopfront_product_sorting_method, :string, default: "by_category" # Allow hubs to restrict visible variants to only those in their inventory preference :product_selection_from_inventory_only, :boolean, default: false diff --git a/app/serializers/api/admin/enterprise_serializer.rb b/app/serializers/api/admin/enterprise_serializer.rb index 4d8ee6aa93..cc2a962f7e 100644 --- a/app/serializers/api/admin/enterprise_serializer.rb +++ b/app/serializers/api/admin/enterprise_serializer.rb @@ -7,8 +7,9 @@ module Api :payment_method_ids, :shipping_method_ids, :producer_profile_only, :long_description, :preferred_product_selection_from_inventory_only, :preferred_shopfront_message, :preferred_shopfront_closed_message, - :preferred_shopfront_taxon_order, :preferred_shopfront_order_cycle_order, - :preferred_show_customer_names_to_suppliers, :owner, :contact, :users, :tag_groups, + :preferred_shopfront_taxon_order, :preferred_shopfront_producer_order, + :preferred_shopfront_order_cycle_order, :preferred_show_customer_names_to_suppliers, + :preferred_shopfront_product_sorting_method, :owner, :contact, :users, :tag_groups, :default_tag_group, :require_login, :allow_guest_orders, :allow_order_changes, :logo, :promo_image, :terms_and_conditions, :terms_and_conditions_file_name, :terms_and_conditions_updated_at diff --git a/app/services/permitted_attributes/enterprise.rb b/app/services/permitted_attributes/enterprise.rb index 0989511d69..a3f688c64d 100644 --- a/app/services/permitted_attributes/enterprise.rb +++ b/app/services/permitted_attributes/enterprise.rb @@ -30,7 +30,8 @@ module PermittedAttributes :abn, :acn, :charges_sales_tax, :display_invoice_logo, :invoice_text, :preferred_product_selection_from_inventory_only, :preferred_shopfront_message, :preferred_shopfront_closed_message, :preferred_shopfront_taxon_order, - :preferred_shopfront_order_cycle_order, :preferred_show_customer_names_to_suppliers + :preferred_shopfront_producer_order, :preferred_shopfront_order_cycle_order, + :preferred_show_customer_names_to_suppliers, :preferred_shopfront_product_sorting_method, ] end end diff --git a/app/services/products_renderer.rb b/app/services/products_renderer.rb index 963330dba8..40048f83aa 100644 --- a/app/services/products_renderer.rb +++ b/app/services/products_renderer.rb @@ -60,7 +60,11 @@ class ProductsRenderer end def taxon_order - if distributor.preferred_shopfront_taxon_order.present? + if distributor.preferred_shopfront_product_sorting_method == "by_producer" + # todo: replace with preferred_shopfront_producer_order like for category + # todo: order per producer or category alphabetically if no perferred order is present? + "spree_products.supplier_id, spree_products.id" + elsif distributor.preferred_shopfront_product_sorting_method == "by_category" && distributor.preferred_shopfront_taxon_order.present? distributor .preferred_shopfront_taxon_order .split(",").map { |id| "spree_products.primary_taxon_id=#{id} DESC" } diff --git a/app/views/admin/enterprises/form/_shop_preferences.html.haml b/app/views/admin/enterprises/form/_shop_preferences.html.haml index a04b09508f..9408969b3b 100644 --- a/app/views/admin/enterprises/form/_shop_preferences.html.haml +++ b/app/views/admin/enterprises/form/_shop_preferences.html.haml @@ -12,13 +12,29 @@ %text-angular{'ng-model' => 'Enterprise.preferred_shopfront_closed_message', 'id' => 'enterprise_preferred_shopfront_closed_message', 'name' => 'enterprise[preferred_shopfront_closed_message]', 'class' => 'text-angular textangular-strip', 'ta-paste' => "stripFormatting($html)", "textangular-links-target-blank" => true, 'ta-toolbar' => "[['h1','h2','h3','h4','p'],['bold','italics','underline','clear'],['insertLink']]", 'placeholder' => t('.shopfront_closed_message_placeholder')} + .row - .three.columns.alpha - = f.label "enterprise_preferred_shopfront_taxon_order", t('.shopfront_category_ordering') + .text-normal + = t('.display_ordering_in_shopfront') %br = t('.shopfront_category_ordering_note') +.row + .three.columns.alpha + = radio_button :enterprise, :preferred_shopfront_product_sorting_method, :by_category, { 'ng-model' => 'Enterprise.preferred_shopfront_product_sorting_method' } + = label :enterprise, :preferred_shopfront_product_sorting_method_by_category, t('.shopfront_sort_by_category') .eight.columns.omega - %textarea.fullwidth{ id: 'enterprise_preferred_shopfront_taxon_order', name: 'enterprise[preferred_shopfront_taxon_order]', rows: 6, 'ng-model' => 'Enterprise.preferred_shopfront_taxon_order', 'ofn-taxon-autocomplete' => '', 'multiple-selection' => 'true', placeholder: 'Category' } + %textarea.fullwidth{ id: 'enterprise_preferred_shopfront_taxon_order', name: 'enterprise[preferred_shopfront_taxon_order]', rows: 6, + 'ofn-taxon-autocomplete' => '', 'multiple-selection' => 'true', placeholder: 'Category', + ng: { model: 'Enterprise.preferred_shopfront_taxon_order', readonly: "Enterprise.preferred_shopfront_product_sorting_method != 'by_category'" }} +.row + .three.columns.alpha + = radio_button :enterprise, :preferred_shopfront_product_sorting_method, :by_producer, { 'ng-model' => 'Enterprise.preferred_shopfront_product_sorting_method' } + = label :enterprise, :preferred_shopfront_product_sorting_method_by_producer, t('.shopfront_sort_by_producer') + -# todo: create directive to support producer selector below + -# .eight.columns.omega + -# %textarea.fullwidth{ id: 'enterprise_preferred_shopfront_producer_order', name: 'enterprise[preferred_shopfront_producer_order]', rows: 6, + -# 'ofn-producer-autocomplete' => '', 'multiple-selection' => 'true', placeholder: 'Producer', + -# ng: { model: 'Enterprise.preferred_shopfront_producer_order', readonly: "Enterprise.preferred_shopfront_product_sorting_method != 'by_producer'" }} .row .three.columns.alpha diff --git a/config/locales/en.yml b/config/locales/en.yml index a1934c45c0..a168994374 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -875,6 +875,9 @@ en: shopfront_category_ordering_note: "(top to bottom)" open_date: "Open Date" close_date: "Close Date" + display_ordering_in_shopfront: "Display ordering in shopfront:" + shopfront_sort_by_category: "By category" + shopfront_sort_by_producer: "By producer" social: twitter_placeholder: "eg. @the_prof" instagram_placeholder: "eg. the_prof" diff --git a/spec/models/enterprise_spec.rb b/spec/models/enterprise_spec.rb index b4bfc76c0e..9b1e8b6a4a 100644 --- a/spec/models/enterprise_spec.rb +++ b/spec/models/enterprise_spec.rb @@ -187,6 +187,8 @@ describe Enterprise do expect(enterprise).to be_invalid end end + + # todo: describe "preferred_shopfront_producer_order" end describe "callbacks" do diff --git a/spec/services/products_renderer_spec.rb b/spec/services/products_renderer_spec.rb index 3794da31c7..789c0bbc4c 100644 --- a/spec/services/products_renderer_spec.rb +++ b/spec/services/products_renderer_spec.rb @@ -12,10 +12,12 @@ describe ProductsRenderer do describe "sorting" do let(:t1) { create(:taxon) } let(:t2) { create(:taxon) } - let!(:p1) { create(:product, name: "abc", primary_taxon_id: t2.id) } - let!(:p2) { create(:product, name: "def", primary_taxon_id: t1.id) } - let!(:p3) { create(:product, name: "ghi", primary_taxon_id: t2.id) } - let!(:p4) { create(:product, name: "jkl", primary_taxon_id: t1.id) } + let(:s1) { create(:supplier_enterprise) } + let(:s2) { create(:supplier_enterprise) } + let!(:p1) { create(:product, name: "abc", primary_taxon_id: t2.id, supplier_id: s1.id) } + let!(:p2) { create(:product, name: "def", primary_taxon_id: t1.id, supplier_id: s2.id) } + let!(:p3) { create(:product, name: "ghi", primary_taxon_id: t2.id, supplier_id: s1.id) } + let!(:p4) { create(:product, name: "jkl", primary_taxon_id: t1.id, supplier_id: s2.id) } before do exchange.variants << p1.variants.first @@ -30,6 +32,20 @@ describe ProductsRenderer do expect(products).to eq([p2, p4, p1, p3]) end + it "sorts products by producer id" do # todo: remove this temporary test + allow(distributor).to receive(:preferred_shopfront_product_sorting_method) { "by_producer" } + puts(distributor.preferred_shopfront_product_sorting_method) + products = products_renderer.send(:products) + expect(products).to eq([p1, p3, p2, p4]) + end + + # todo: it "sorts products by the distributor's preferred producer list" do + # allow(distributor).to receive(:preferred_shopfront_product_sorting_method) { "by_producer" } + # allow(distributor).to receive(:preferred_shopfront_producer_order) { "#{s2.id},#{s1.id}" } + # products = products_renderer.send(:products) + # expect(products).to eq([p2, p4, p1, p3]) + # end + it "alphabetizes products by name when taxon list is not set" do allow(distributor).to receive(:preferred_shopfront_taxon_order) { "" } products = products_renderer.send(:products) From baca89c5753903e62e55996c71059562f6000e47 Mon Sep 17 00:00:00 2001 From: Guido Oliveira Date: Thu, 3 Jun 2021 11:01:00 -0300 Subject: [PATCH 2/4] allow select producers for ordering --- .../enterprise_controller.js.coffee | 6 +++- .../producer_autocomplete.js.coffee | 30 ++++++++++++++++ .../resources/services/enterprises.js.coffee | 13 ++++++- .../directives/taxon_autocomplete.js.coffee | 6 ++-- app/assets/stylesheets/admin/disabled.scss | 4 +++ app/models/enterprise.rb | 7 ++++ app/services/products_renderer.rb | 9 ++--- .../form/_shop_preferences.html.haml | 9 +++-- spec/models/enterprise_spec.rb | 35 ++++++++++++++++++- spec/services/products_renderer_spec.rb | 13 ++----- 10 files changed, 107 insertions(+), 25 deletions(-) create mode 100644 app/assets/javascripts/admin/enterprises/directives/producer_autocomplete.js.coffee diff --git a/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee b/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee index 51c38d0a3f..ac1c2e45e2 100644 --- a/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee +++ b/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee @@ -1,12 +1,14 @@ angular.module("admin.enterprises") - .controller "enterpriseCtrl", ($scope, $http, $window, NavigationCheck, enterprise, Enterprises, EnterprisePaymentMethods, EnterpriseShippingMethods, SideMenu, StatusMessage) -> + .controller "enterpriseCtrl", ($scope, $http, $window, NavigationCheck, enterprise, Enterprises, EnterprisePaymentMethods, EnterpriseShippingMethods, SideMenu, StatusMessage, RequestMonitor) -> $scope.Enterprise = enterprise + $scope.Enterprises = Enterprises $scope.PaymentMethods = EnterprisePaymentMethods.paymentMethods $scope.ShippingMethods = EnterpriseShippingMethods.shippingMethods $scope.navClear = NavigationCheck.clear $scope.menu = SideMenu $scope.newManager = { id: null, email: (t('add_manager')) } $scope.StatusMessage = StatusMessage + $scope.RequestMonitor = RequestMonitor $scope.$watch 'enterprise_form.$dirty', (newValue) -> StatusMessage.display 'notice', t('admin.unsaved_changes') if newValue @@ -90,3 +92,5 @@ angular.module("admin.enterprises") $scope.translation = (key) -> t('js.admin.enterprises.form.images.' + key) + + RequestMonitor.load $scope.suppliers = Enterprises.index(action: "visible", ams_prefix: "basic", "q[is_primary_producer_eq]": "true") diff --git a/app/assets/javascripts/admin/enterprises/directives/producer_autocomplete.js.coffee b/app/assets/javascripts/admin/enterprises/directives/producer_autocomplete.js.coffee new file mode 100644 index 0000000000..181b781903 --- /dev/null +++ b/app/assets/javascripts/admin/enterprises/directives/producer_autocomplete.js.coffee @@ -0,0 +1,30 @@ +angular.module("admin.enterprises").directive "ofnProducerAutocomplete", (Enterprises, $sanitize) -> + scope: true + link: (scope,element,attrs) -> + multiple = scope.$eval attrs.multipleSelection + placeholder = attrs.placeholder + initialSelection = scope.$eval attrs.ngModel + suppliers = scope.suppliers + + setTimeout -> + element.select2 + placeholder: placeholder + multiple: multiple + initSelection: (element, callback) -> + if multiple + callback Enterprises.findByIDs(initialSelection) + else + callback Enterprises.findByID(initialSelection) + query: (query) -> + query.callback { results: Enterprises.findByTerm(suppliers, query.term) } + formatResult: (producer) -> + $sanitize(producer.name) + formatSelection: (producer) -> + producer.name + + #Allows drag and drop + if multiple + element.select2("container").find("ul.select2-choices").sortable + containment: 'parent' + start: -> element.select2("onSortStart") + update: -> element.select2("onSortEnd") diff --git a/app/assets/javascripts/admin/resources/services/enterprises.js.coffee b/app/assets/javascripts/admin/resources/services/enterprises.js.coffee index 7a51e52367..7adb4c33f7 100644 --- a/app/assets/javascripts/admin/resources/services/enterprises.js.coffee +++ b/app/assets/javascripts/admin/resources/services/enterprises.js.coffee @@ -1,4 +1,4 @@ -angular.module("admin.resources").factory 'Enterprises', ($q, EnterpriseResource) -> +angular.module("admin.resources").factory 'Enterprises', ($q, $filter, EnterpriseResource) -> new class Enterprises byID: {} pristineByID: {} @@ -50,6 +50,17 @@ angular.module("admin.resources").factory 'Enterprises', ($q, EnterpriseResource )) deferred.promise + findByID: (id) -> + @byID[id] + + # For finding multiple Enterprises represented by comma delimited string + findByIDs: (ids) -> + @byID[id] for id in ids.split(",") when @byID[id] + + findByTerm: (enterprises, term) -> + $filter('filter')(enterprises, term) + + removeLogo: performActionOnEnterpriseResource(EnterpriseResource.removeLogo) removePromoImage: performActionOnEnterpriseResource(EnterpriseResource.removePromoImage) removeTermsAndConditions: performActionOnEnterpriseResource(EnterpriseResource.removeTermsAndConditions) diff --git a/app/assets/javascripts/admin/taxons/directives/taxon_autocomplete.js.coffee b/app/assets/javascripts/admin/taxons/directives/taxon_autocomplete.js.coffee index b1eac64569..2c28be9c69 100644 --- a/app/assets/javascripts/admin/taxons/directives/taxon_autocomplete.js.coffee +++ b/app/assets/javascripts/admin/taxons/directives/taxon_autocomplete.js.coffee @@ -4,7 +4,7 @@ angular.module("admin.taxons").directive "ofnTaxonAutocomplete", (Taxons, $sanit link: (scope,element,attrs) -> multiple = scope.$eval attrs.multipleSelection placeholder = attrs.placeholder - initalSelection = scope.$eval attrs.ngModel + initialSelection = scope.$eval attrs.ngModel setTimeout -> element.select2 @@ -12,9 +12,9 @@ angular.module("admin.taxons").directive "ofnTaxonAutocomplete", (Taxons, $sanit multiple: multiple initSelection: (element, callback) -> if multiple - callback Taxons.findByIDs(initalSelection) + callback Taxons.findByIDs(initialSelection) else - callback Taxons.findByID(initalSelection) + callback Taxons.findByID(initialSelection) query: (query) -> query.callback { results: Taxons.findByTerm(query.term) } formatResult: (taxon) -> diff --git a/app/assets/stylesheets/admin/disabled.scss b/app/assets/stylesheets/admin/disabled.scss index 75f82686a8..5555e30d4e 100644 --- a/app/assets/stylesheets/admin/disabled.scss +++ b/app/assets/stylesheets/admin/disabled.scss @@ -16,4 +16,8 @@ input[type='button'], input[type='submit'] { .select2-choice > .select2-chosen { color: #a1a1a1; } + + .select2-search-choice { + background-color: #c3c3c3 !important; + } } diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 90bd877562..99cd8f262e 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -98,6 +98,7 @@ class Enterprise < ApplicationRecord validates :owner, presence: true validates :permalink, uniqueness: true, presence: true validate :shopfront_taxons + validate :shopfront_producers validate :enforce_ownership_limit, if: lambda { owner_id_changed? && !owner_id.nil? } before_validation :initialize_permalink, if: lambda { permalink.nil? } @@ -461,6 +462,12 @@ class Enterprise < ApplicationRecord end end + def shopfront_producers + unless preferred_shopfront_producer_order =~ /\A((\d+,)*\d+)?\z/ + errors.add(:shopfront_category_ordering, "must contain a list of producers.") + end + end + def restore_permalink # If the permalink has errors, reset it to it's original value, so we can update the form self.permalink = permalink_was if permalink_changed? && errors[:permalink].present? diff --git a/app/services/products_renderer.rb b/app/services/products_renderer.rb index 40048f83aa..1f276937eb 100644 --- a/app/services/products_renderer.rb +++ b/app/services/products_renderer.rb @@ -60,10 +60,11 @@ class ProductsRenderer end def taxon_order - if distributor.preferred_shopfront_product_sorting_method == "by_producer" - # todo: replace with preferred_shopfront_producer_order like for category - # todo: order per producer or category alphabetically if no perferred order is present? - "spree_products.supplier_id, spree_products.id" + if distributor.preferred_shopfront_product_sorting_method == "by_producer" && distributor.preferred_shopfront_producer_order.present? + distributor + .preferred_shopfront_producer_order + .split(",").map { |id| "spree_products.supplier_id=#{id} DESC" } + .join(", ") + ", spree_products.name ASC, spree_products.id ASC" elsif distributor.preferred_shopfront_product_sorting_method == "by_category" && distributor.preferred_shopfront_taxon_order.present? distributor .preferred_shopfront_taxon_order diff --git a/app/views/admin/enterprises/form/_shop_preferences.html.haml b/app/views/admin/enterprises/form/_shop_preferences.html.haml index 9408969b3b..75be67e194 100644 --- a/app/views/admin/enterprises/form/_shop_preferences.html.haml +++ b/app/views/admin/enterprises/form/_shop_preferences.html.haml @@ -30,11 +30,10 @@ .three.columns.alpha = radio_button :enterprise, :preferred_shopfront_product_sorting_method, :by_producer, { 'ng-model' => 'Enterprise.preferred_shopfront_product_sorting_method' } = label :enterprise, :preferred_shopfront_product_sorting_method_by_producer, t('.shopfront_sort_by_producer') - -# todo: create directive to support producer selector below - -# .eight.columns.omega - -# %textarea.fullwidth{ id: 'enterprise_preferred_shopfront_producer_order', name: 'enterprise[preferred_shopfront_producer_order]', rows: 6, - -# 'ofn-producer-autocomplete' => '', 'multiple-selection' => 'true', placeholder: 'Producer', - -# ng: { model: 'Enterprise.preferred_shopfront_producer_order', readonly: "Enterprise.preferred_shopfront_product_sorting_method != 'by_producer'" }} + .eight.columns.omega + %textarea.fullwidth{ id: 'enterprise_preferred_shopfront_producer_order', name: 'enterprise[preferred_shopfront_producer_order]', rows: 6, + 'ofn-producer-autocomplete' => '', 'multiple-selection' => 'true', placeholder: 'Producer', + ng: { model: 'Enterprise.preferred_shopfront_producer_order', readonly: "Enterprise.preferred_shopfront_product_sorting_method != 'by_producer'" }} .row .three.columns.alpha diff --git a/spec/models/enterprise_spec.rb b/spec/models/enterprise_spec.rb index 9b1e8b6a4a..30735154c6 100644 --- a/spec/models/enterprise_spec.rb +++ b/spec/models/enterprise_spec.rb @@ -188,7 +188,40 @@ describe Enterprise do end end - # todo: describe "preferred_shopfront_producer_order" + describe "preferred_shopfront_producer_order" do + it "empty strings are valid" do + enterprise = build(:enterprise, preferred_shopfront_producer_order: "") + expect(enterprise).to be_valid + end + + it "a single integer is valid" do + enterprise = build(:enterprise, preferred_shopfront_producer_order: "11") + expect(enterprise).to be_valid + end + + it "comma delimited integers are valid" do + enterprise = build(:enterprise, preferred_shopfront_producer_order: "1,2,3") + expect(enterprise).to be_valid + enterprise = build(:enterprise, preferred_shopfront_producer_order: "1,22,333") + expect(enterprise).to be_valid + end + + it "commas at the beginning and end are disallowed" do + enterprise = build(:enterprise, preferred_shopfront_producer_order: ",1,2,3") + expect(enterprise).to be_invalid + enterprise = build(:enterprise, preferred_shopfront_producer_order: "1,2,3,") + expect(enterprise).to be_invalid + end + + it "any other characters are invalid" do + enterprise = build(:enterprise, preferred_shopfront_producer_order: "a1,2,3") + expect(enterprise).to be_invalid + enterprise = build(:enterprise, preferred_shopfront_producer_order: ".1,2,3") + expect(enterprise).to be_invalid + enterprise = build(:enterprise, preferred_shopfront_producer_order: " 1,2,3") + expect(enterprise).to be_invalid + end + end end describe "callbacks" do diff --git a/spec/services/products_renderer_spec.rb b/spec/services/products_renderer_spec.rb index 789c0bbc4c..34692978dc 100644 --- a/spec/services/products_renderer_spec.rb +++ b/spec/services/products_renderer_spec.rb @@ -32,20 +32,13 @@ describe ProductsRenderer do expect(products).to eq([p2, p4, p1, p3]) end - it "sorts products by producer id" do # todo: remove this temporary test + it "sorts products by the distributor's preferred producer list" do allow(distributor).to receive(:preferred_shopfront_product_sorting_method) { "by_producer" } - puts(distributor.preferred_shopfront_product_sorting_method) + allow(distributor).to receive(:preferred_shopfront_producer_order) { "#{s2.id},#{s1.id}" } products = products_renderer.send(:products) - expect(products).to eq([p1, p3, p2, p4]) + expect(products).to eq([p2, p4, p1, p3]) end - # todo: it "sorts products by the distributor's preferred producer list" do - # allow(distributor).to receive(:preferred_shopfront_product_sorting_method) { "by_producer" } - # allow(distributor).to receive(:preferred_shopfront_producer_order) { "#{s2.id},#{s1.id}" } - # products = products_renderer.send(:products) - # expect(products).to eq([p2, p4, p1, p3]) - # end - it "alphabetizes products by name when taxon list is not set" do allow(distributor).to receive(:preferred_shopfront_taxon_order) { "" } products = products_renderer.send(:products) From 92031120e3250ea108447269e7fabdf7b7ffa82f Mon Sep 17 00:00:00 2001 From: Guido Oliveira Date: Sun, 6 Jun 2021 15:32:09 -0300 Subject: [PATCH 3/4] Create service for select2 autocomplete --- .../producer_autocomplete.js.coffee | 31 ++++++------------- .../directives/taxon_autocomplete.js.coffee | 31 ++++++------------- .../services/autocomplete_select2.js.coffee | 31 +++++++++++++++++++ app/assets/stylesheets/admin/disabled.scss | 8 +++-- app/services/products_renderer.rb | 4 +-- 5 files changed, 56 insertions(+), 49 deletions(-) create mode 100644 app/assets/javascripts/admin/utils/services/autocomplete_select2.js.coffee diff --git a/app/assets/javascripts/admin/enterprises/directives/producer_autocomplete.js.coffee b/app/assets/javascripts/admin/enterprises/directives/producer_autocomplete.js.coffee index 181b781903..e955be0a9d 100644 --- a/app/assets/javascripts/admin/enterprises/directives/producer_autocomplete.js.coffee +++ b/app/assets/javascripts/admin/enterprises/directives/producer_autocomplete.js.coffee @@ -1,4 +1,4 @@ -angular.module("admin.enterprises").directive "ofnProducerAutocomplete", (Enterprises, $sanitize) -> +angular.module("admin.enterprises").directive "ofnProducerAutocomplete", (Enterprises, AutocompleteSelect2) -> scope: true link: (scope,element,attrs) -> multiple = scope.$eval attrs.multipleSelection @@ -7,24 +7,11 @@ angular.module("admin.enterprises").directive "ofnProducerAutocomplete", (Enterp suppliers = scope.suppliers setTimeout -> - element.select2 - placeholder: placeholder - multiple: multiple - initSelection: (element, callback) -> - if multiple - callback Enterprises.findByIDs(initialSelection) - else - callback Enterprises.findByID(initialSelection) - query: (query) -> - query.callback { results: Enterprises.findByTerm(suppliers, query.term) } - formatResult: (producer) -> - $sanitize(producer.name) - formatSelection: (producer) -> - producer.name - - #Allows drag and drop - if multiple - element.select2("container").find("ul.select2-choices").sortable - containment: 'parent' - start: -> element.select2("onSortStart") - update: -> element.select2("onSortEnd") + AutocompleteSelect2.autocomplete( + multiple, + placeholder, + element, + (-> Enterprises.findByID(initialSelection)), + (-> Enterprises.findByIDs(initialSelection)), + ((term) -> Enterprises.findByTerm(suppliers, term)) + ) diff --git a/app/assets/javascripts/admin/taxons/directives/taxon_autocomplete.js.coffee b/app/assets/javascripts/admin/taxons/directives/taxon_autocomplete.js.coffee index 2c28be9c69..31f5a54cb6 100644 --- a/app/assets/javascripts/admin/taxons/directives/taxon_autocomplete.js.coffee +++ b/app/assets/javascripts/admin/taxons/directives/taxon_autocomplete.js.coffee @@ -1,4 +1,4 @@ -angular.module("admin.taxons").directive "ofnTaxonAutocomplete", (Taxons, $sanitize) -> +angular.module("admin.taxons").directive "ofnTaxonAutocomplete", (Taxons, AutocompleteSelect2) -> # Adapted from Spree's existing taxon autocompletion scope: true link: (scope,element,attrs) -> @@ -7,24 +7,11 @@ angular.module("admin.taxons").directive "ofnTaxonAutocomplete", (Taxons, $sanit initialSelection = scope.$eval attrs.ngModel setTimeout -> - element.select2 - placeholder: placeholder - multiple: multiple - initSelection: (element, callback) -> - if multiple - callback Taxons.findByIDs(initialSelection) - else - callback Taxons.findByID(initialSelection) - query: (query) -> - query.callback { results: Taxons.findByTerm(query.term) } - formatResult: (taxon) -> - $sanitize(taxon.name) - formatSelection: (taxon) -> - taxon.name - - #Allows drag and drop - if multiple - element.select2("container").find("ul.select2-choices").sortable - containment: 'parent' - start: -> element.select2("onSortStart") - update: -> element.select2("onSortEnd") + AutocompleteSelect2.autocomplete( + multiple, + placeholder, + element, + (-> Taxons.findByID(initialSelection)), + (-> Taxons.findByIDs(initialSelection)), + ((term) -> Taxons.findByTerm(term)) + ) diff --git a/app/assets/javascripts/admin/utils/services/autocomplete_select2.js.coffee b/app/assets/javascripts/admin/utils/services/autocomplete_select2.js.coffee new file mode 100644 index 0000000000..a17eee843a --- /dev/null +++ b/app/assets/javascripts/admin/utils/services/autocomplete_select2.js.coffee @@ -0,0 +1,31 @@ +angular.module("admin.utils").factory 'AutocompleteSelect2', ($sanitize) -> + scope: true + autocomplete: ( + multiple, + placeholder, + element, + findByID, + findByIDs, + findByTerm + ) -> + element.select2 + placeholder: placeholder + multiple: multiple + initSelection: (element, callback) -> + if multiple + callback findByIDs() + else + callback findByID() + query: (query) -> + query.callback { results: findByTerm(query.term) } + formatResult: (item) -> + $sanitize(item.name) + formatSelection: (item) -> + item.name + + #Allows drag and drop + if multiple + element.select2("container").find("ul.select2-choices").sortable + containment: 'parent' + start: -> element.select2("onSortStart") + update: -> element.select2("onSortEnd") diff --git a/app/assets/stylesheets/admin/disabled.scss b/app/assets/stylesheets/admin/disabled.scss index 5555e30d4e..e78c23e5c5 100644 --- a/app/assets/stylesheets/admin/disabled.scss +++ b/app/assets/stylesheets/admin/disabled.scss @@ -1,11 +1,13 @@ +$disabled-background: #c3c3c3; + label.disabled { - color: #c3c3c3; + color: $disabled-background; pointer-events: none; } input[type='button'], input[type='submit'] { &:disabled { - background-color: #c3c3c3; + background-color: $disabled-background; color: #ffffff; } } @@ -18,6 +20,6 @@ input[type='button'], input[type='submit'] { } .select2-search-choice { - background-color: #c3c3c3 !important; + background-color: $disabled-background !important; } } diff --git a/app/services/products_renderer.rb b/app/services/products_renderer.rb index 1f276937eb..8b7e621f80 100644 --- a/app/services/products_renderer.rb +++ b/app/services/products_renderer.rb @@ -32,7 +32,7 @@ class ProductsRenderer @products ||= begin results = distributed_products. products_relation. - order(Arel.sql(taxon_order)) + order(Arel.sql(products_order)) filter_and_paginate(results). each { |product| product_scoper.scope(product) } # Scope results with variant_overrides @@ -59,7 +59,7 @@ class ProductsRenderer OrderCycleDistributedProducts.new(distributor, order_cycle, customer) end - def taxon_order + def products_order if distributor.preferred_shopfront_product_sorting_method == "by_producer" && distributor.preferred_shopfront_producer_order.present? distributor .preferred_shopfront_producer_order From 0f2fd47ca0fa65303c1f33c7bd72d294451325d6 Mon Sep 17 00:00:00 2001 From: Guido Oliveira Date: Wed, 9 Jun 2021 16:13:54 -0300 Subject: [PATCH 4/4] Fix supplier loader issue in enterprise controller --- .../enterprise_controller.js.coffee | 3 ++- .../producer_autocomplete.js.coffee | 19 ++++++++++--------- app/assets/stylesheets/admin/disabled.scss | 4 ++-- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee b/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee index ac1c2e45e2..4ea40560ea 100644 --- a/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee +++ b/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee @@ -93,4 +93,5 @@ angular.module("admin.enterprises") $scope.translation = (key) -> t('js.admin.enterprises.form.images.' + key) - RequestMonitor.load $scope.suppliers = Enterprises.index(action: "visible", ams_prefix: "basic", "q[is_primary_producer_eq]": "true") + $scope.loadSuppliers = -> + RequestMonitor.load $scope.suppliers = Enterprises.index(action: "visible", ams_prefix: "basic", "q[is_primary_producer_eq]": "true") diff --git a/app/assets/javascripts/admin/enterprises/directives/producer_autocomplete.js.coffee b/app/assets/javascripts/admin/enterprises/directives/producer_autocomplete.js.coffee index e955be0a9d..68c8c64f6b 100644 --- a/app/assets/javascripts/admin/enterprises/directives/producer_autocomplete.js.coffee +++ b/app/assets/javascripts/admin/enterprises/directives/producer_autocomplete.js.coffee @@ -1,17 +1,18 @@ angular.module("admin.enterprises").directive "ofnProducerAutocomplete", (Enterprises, AutocompleteSelect2) -> scope: true link: (scope,element,attrs) -> + scope.loadSuppliers() if !scope.suppliers multiple = scope.$eval attrs.multipleSelection placeholder = attrs.placeholder initialSelection = scope.$eval attrs.ngModel - suppliers = scope.suppliers setTimeout -> - AutocompleteSelect2.autocomplete( - multiple, - placeholder, - element, - (-> Enterprises.findByID(initialSelection)), - (-> Enterprises.findByIDs(initialSelection)), - ((term) -> Enterprises.findByTerm(suppliers, term)) - ) + scope.suppliers.$promise.then (data) -> + AutocompleteSelect2.autocomplete( + multiple, + placeholder, + element, + (-> Enterprises.findByID(initialSelection)), + (-> Enterprises.findByIDs(initialSelection)), + ((term) -> Enterprises.findByTerm(scope.suppliers, term)) + ) diff --git a/app/assets/stylesheets/admin/disabled.scss b/app/assets/stylesheets/admin/disabled.scss index e78c23e5c5..d7c7805036 100644 --- a/app/assets/stylesheets/admin/disabled.scss +++ b/app/assets/stylesheets/admin/disabled.scss @@ -19,7 +19,7 @@ input[type='button'], input[type='submit'] { color: #a1a1a1; } - .select2-search-choice { - background-color: $disabled-background !important; + &.select2-container-multi .select2-choices .select2-search-choice { + background-color: $disabled-background; } }