From 8658b1a74324001389cb1565f74133da72a45d31 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Fri, 17 Feb 2023 11:28:30 +0100 Subject: [PATCH 1/5] Remove quick filter that search only on displayed line items + remove specs as well --- .../line_items_controller.js.coffee | 1 - .../admin/orders/bulk_management.html.haml | 4 +- .../admin/bulk_order_management_spec.rb | 65 ------------------- 3 files changed, 1 insertion(+), 69 deletions(-) diff --git a/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee b/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee index d2dc108464..1932043f7d 100644 --- a/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee +++ b/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee @@ -26,7 +26,6 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $scope.distributorFilter = '' $scope.supplierFilter = '' $scope.orderCycleFilter = '' - $scope.quickSearch = '' $scope.startDate = undefined $scope.endDate = undefined event = new CustomEvent('flatpickr:clear') diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index 2c3090a17c..354e7c09af 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -97,8 +97,6 @@ .clear %div{ ng: { hide: 'RequestMonitor.loading || line_items.length == 0' }, style: "display: flex; justify-content: flex-start; column-gap: 10px; margin-bottom: 15px" } - %div{ style: "flex-grow: 1" } - %input.fullwidth{ :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } -# This -20px is a hack to make the dropdowns align properly %div{ style: "margin-right: -20px;" } = render 'admin/shared/bulk_actions_dropdown' @@ -162,7 +160,7 @@ = "#{t('admin.price')} (#{Spree::Money.currency_symbol})" %th.actions - %tr.line_item{ ng: { repeat: "line_item in filteredLineItems = ( line_items | filter:quickSearch | variantFilter:selectedUnitsProduct:selectedUnitsVariant:sharedResource | orderBy:sorting.predicate:sorting.reverse )", 'class-even' => "'even'", 'class-odd' => "'odd'", attr: { id: "li_{{line_item.id}}" } } } + %tr.line_item{ ng: { repeat: "line_item in filteredLineItems = ( line_items | variantFilter:selectedUnitsProduct:selectedUnitsVariant:sharedResource | orderBy:sorting.predicate:sorting.reverse )", 'class-even' => "'even'", 'class-odd' => "'odd'", attr: { id: "li_{{line_item.id}}" } } } %td.bulk %input{ :type => "checkbox", :name => 'bulk', 'ng-model' => 'line_item.checked', 'ignore-dirty' => true } %td.order_no{ 'ng-show' => 'columns.order_no.visible' } {{ line_item.order.number }} diff --git a/spec/system/admin/bulk_order_management_spec.rb b/spec/system/admin/bulk_order_management_spec.rb index d7547a126d..5b34876861 100644 --- a/spec/system/admin/bulk_order_management_spec.rb +++ b/spec/system/admin/bulk_order_management_spec.rb @@ -602,38 +602,6 @@ describe ' end end - context "using quick search" do - let!(:o1) { - create(:order_with_distributor, state: 'complete', shipment_state: 'ready', - completed_at: Time.zone.now ) - } - let!(:o2) { - create(:order_with_distributor, state: 'complete', shipment_state: 'ready', - completed_at: Time.zone.now ) - } - let!(:o3) { - create(:order_with_distributor, state: 'complete', shipment_state: 'ready', - completed_at: Time.zone.now ) - } - let!(:li1) { create(:line_item_with_shipment, order: o1 ) } - let!(:li2) { create(:line_item_with_shipment, order: o2 ) } - let!(:li3) { create(:line_item_with_shipment, order: o3 ) } - - before :each do - visit_bulk_order_management - end - - it "filters line items based on their attributes and the contents of the quick search input" do - expect(page).to have_selector "tr#li_#{li1.id}" - expect(page).to have_selector "tr#li_#{li2.id}" - expect(page).to have_selector "tr#li_#{li3.id}" - fill_in "quick_search", with: o1.email - expect(page).to have_selector "tr#li_#{li1.id}" - expect(page).to have_no_selector "tr#li_#{li2.id}" - expect(page).to have_no_selector "tr#li_#{li3.id}" - end - end - context "using date restriction controls" do let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', @@ -793,39 +761,6 @@ describe ' end.to have_enqueued_mail(Spree::OrderMailer, :cancel_email) end end - - context "when a filter has been applied" do - it "only toggles checkboxes which are in filteredLineItems" do - fill_in "quick_search", with: o1.number - expect(page).to have_no_selector "tr#li_#{li2.id}" - check "toggle_bulk" - fill_in "quick_search", with: '' - wait_until { request_monitor_finished 'LineItemsCtrl' } - expect(find("tr#li_#{li1.id} input[type='checkbox'][name='bulk']").checked?).to be true - expect(find("tr#li_#{li2.id} input[type='checkbox'][name='bulk']").checked?).to be false - expect(find("input[type='checkbox'][name='toggle_bulk']").checked?).to be false - end - - it "only applies the delete action to filteredLineItems" do - check "toggle_bulk" - fill_in "quick_search", with: o1.number - expect(page).to have_no_selector "tr#li_#{li2.id}" - - find("div#bulk-actions-dropdown").click - find("div#bulk-actions-dropdown div.menu_item", text: "Delete Selected" ).click - - within ".modal" do - click_on("OK") - end - - expect(page).to have_no_selector "tr#li_#{li1.id}" - expect(page).to have_selector "#quick_search" - fill_in "quick_search", with: '' - wait_until { request_monitor_finished 'LineItemsCtrl' } - expect(page).to have_selector "tr#li_#{li2.id}" - expect(page).to have_no_selector "tr#li_#{li1.id}" - end - end end context "using action buttons" do From ebd5d706c25d5b431f5d02bb7f234b8410d352cf Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Fri, 17 Feb 2023 11:38:12 +0100 Subject: [PATCH 2/5] Add search input Actually this only search for `order_email` or `order_number` or `product_name` or `supplier_name` + Improve display by reduce each columns width --- .../controllers/line_items_controller.js.coffee | 2 ++ .../spree/admin/orders/bulk_management.html.haml | 14 ++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee b/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee index 1932043f7d..d411c81440 100644 --- a/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee +++ b/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee @@ -26,6 +26,7 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $scope.distributorFilter = '' $scope.supplierFilter = '' $scope.orderCycleFilter = '' + $scope.query = '' $scope.startDate = undefined $scope.endDate = undefined event = new CustomEvent('flatpickr:clear') @@ -59,6 +60,7 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, [formattedStartDate, formattedEndDate] = $scope.formatDates($scope.startDate, $scope.endDate) RequestMonitor.load LineItems.index( + "q[variant_product_supplier_name_or_order_email_or_order_number_or_product_name_cont]": $scope.query, "q[order_state_not_eq]": "canceled", "q[order_shipment_state_not_eq]": "shipped", "q[order_completed_at_not_null]": "true", diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index 354e7c09af..3ca93cfc81 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -18,22 +18,28 @@ %input.red{ type: "button", value: "Save Changes", ng: { click: "submit()", disabled: "!bulk_order_form.$dirty" } } %legend{ align: 'center'}= t(:search) %div{ :class => "sixteen columns alpha" } - .filter_select{ :class => "four columns" } + .quick_search.three.columns.alpha + %label{ for: 'quick_filter' } + %br + %input.quick-search.fullwidth{ ng: {model: 'query'}, name: "quick_filter", type: 'text', placeholder: t('admin.quick_search'), "ng-keypress" => "$event.keyCode === 13 && fetchResults()" } + .one.columns +   + .filter_select{ :class => "three columns" } %label{ :for => 'supplier_filter' } = t("admin.producer") %br %input#supplier_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'suppliers', placeholder: "#{t(:all)}", blank: "{ id: '', name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'supplierFilter' } } - .filter_select{ :class => "four columns" } + .filter_select{ :class => "three columns" } %label{ :for => 'distributor_filter' } = t("admin.shop") %br %input#distributor_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'distributors', placeholder: "#{t(:all)}", blank: "{ id: '', name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'distributorFilter' } } - .filter_select{ :class => "four columns" } + .filter_select{ :class => "three columns" } %label{ :for => 'order_cycle_filter' } = t("admin.order_cycle") %br %input#order_cycle_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'orderCycles', placeholder: "#{t(:all)}", blank: "{ id: '', name: '#{t(:all)}' }", on: { selecting: "confirmRefresh" }, ng: { model: 'orderCycleFilter' } } - .date_filter{class: "four columns"} + .date_filter{class: "three columns"} %label = t("date_range") %br From 8ad532c41a598b84a99c5116ad919cf160a36994 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Tue, 28 Feb 2023 17:16:25 +0100 Subject: [PATCH 3/5] Can search `bill_address:phone, firstname, lastname` and `distributor:name` --- .../line_items/controllers/line_items_controller.js.coffee | 2 +- app/models/enterprise.rb | 2 +- app/models/spree/address.rb | 2 +- app/models/spree/order.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee b/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee index d411c81440..1157e571b1 100644 --- a/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee +++ b/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee @@ -60,7 +60,7 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, [formattedStartDate, formattedEndDate] = $scope.formatDates($scope.startDate, $scope.endDate) RequestMonitor.load LineItems.index( - "q[variant_product_supplier_name_or_order_email_or_order_number_or_product_name_cont]": $scope.query, + "q[order_distributor_name_or_order_bill_address_phone_or_order_bill_address_firstname_or_order_bill_address_lastname_or_variant_product_supplier_name_or_order_email_or_order_number_or_product_name_cont]": $scope.query, "q[order_state_not_eq]": "canceled", "q[order_shipment_state_not_eq]": "shipped", "q[order_completed_at_not_null]": "true", diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 20f0aba26d..5efc7ea1cf 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -17,7 +17,7 @@ class Enterprise < ApplicationRecord }.freeze VALID_INSTAGRAM_REGEX = %r{\A[a-zA-Z0-9._]{1,30}([^/-]*)\z} - searchable_attributes :sells, :is_primary_producer + searchable_attributes :sells, :is_primary_producer, :name searchable_associations :properties searchable_scopes :is_primary_producer, :is_distributor, :is_hub, :activated, :visible, :ready_for_checkout, :not_ready_for_checkout diff --git a/app/models/spree/address.rb b/app/models/spree/address.rb index c40cb05a28..998cb0ec4f 100644 --- a/app/models/spree/address.rb +++ b/app/models/spree/address.rb @@ -4,7 +4,7 @@ module Spree class Address < ApplicationRecord include AddressDisplay - searchable_attributes :firstname, :lastname + searchable_attributes :firstname, :lastname, :phone searchable_associations :country, :state belongs_to :country, class_name: "Spree::Country" diff --git a/app/models/spree/order.rb b/app/models/spree/order.rb index e696b872e9..5032b9d650 100644 --- a/app/models/spree/order.rb +++ b/app/models/spree/order.rb @@ -14,7 +14,7 @@ module Spree searchable_attributes :number, :state, :shipment_state, :payment_state, :distributor_id, :order_cycle_id, :email, :total, :customer_id - searchable_associations :shipping_method, :bill_address + searchable_associations :shipping_method, :bill_address, :distributor searchable_scopes :complete, :incomplete checkout_flow do From 50bc48c96f6eed347241dbb046e62f6995f1c343 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Tue, 28 Feb 2023 17:37:24 +0100 Subject: [PATCH 4/5] Introduce some specs around searching in BOM --- .../admin/bulk_order_management_spec.rb | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/spec/system/admin/bulk_order_management_spec.rb b/spec/system/admin/bulk_order_management_spec.rb index 5b34876861..506e1c9de6 100644 --- a/spec/system/admin/bulk_order_management_spec.rb +++ b/spec/system/admin/bulk_order_management_spec.rb @@ -127,6 +127,81 @@ describe ' end end + context "searching" do + let!(:a1) { create(:address, phone: "1234567890", firstname: "Willy", lastname: "Wonka") } + let!(:o1) { + create(:order_with_distributor, state: 'complete', shipment_state: 'ready', + completed_at: Time.zone.now, bill_address: a1) + } + let!(:o2) { + create(:order_with_distributor, state: 'complete', shipment_state: 'ready', + completed_at: Time.zone.now ) + } + let!(:s1) { create(:supplier_enterprise) } + let!(:s2) { create(:supplier_enterprise) } + let!(:li1) { create(:line_item_with_shipment, order: o1, product: create(:product, supplier: s1)) } + let!(:li2) { create(:line_item_with_shipment, order: o2, product: create(:product, supplier: s2)) } + let!(:li3) { create(:line_item_with_shipment, order: o2, product: create(:product, supplier: s2)) } + + before :each do + visit_bulk_order_management + end + + it "by product name" do + fill_in "quick_filter", with: li1.product.name + page.find('.filter-actions .button.icon-search').click + + expect_line_items_results [li1], [li2, li3] + end + + it "by supplier name" do + fill_in "quick_filter", with: li1.product.supplier.name + page.find('.filter-actions .button.icon-search').click + + expect_line_items_results [li1], [li2, li3] + end + + it "by email" do + fill_in "quick_filter", with: o1.email + page.find('.filter-actions .button.icon-search').click + + expect_line_items_results [li1], [li2, li3] + end + + it "by order number" do + fill_in "quick_filter", with: o1.number + page.find('.filter-actions .button.icon-search').click + + expect_line_items_results [li1], [li2, li3] + end + + it "by phone number" do + fill_in "quick_filter", with: o1.bill_address.phone + page.find('.filter-actions .button.icon-search').click + + expect_line_items_results [li1], [li2, li3] + end + + it "by distributor name" do + fill_in "quick_filter", with: o1.distributor.name + page.find('.filter-actions .button.icon-search').click + + expect_line_items_results [li1], [li2, li3] + end + + it "by customer name" do + fill_in "quick_filter", with: o1.bill_address.firstname + page.find('.filter-actions .button.icon-search').click + + expect_line_items_results [li1], [li2, li3] + + fill_in "quick_filter", with: o1.bill_address.lastname + page.find('.filter-actions .button.icon-search').click + + expect_line_items_results [li1], [li2, li3] + end + end + context "displaying individual columns" do let!(:o1) { create(:order_with_distributor, state: 'complete', shipment_state: 'ready', completed_at: Time.zone.now, @@ -1004,4 +1079,14 @@ describe ' expect(page).to have_selector "tr#li_#{li1.id}" expect(page).to have_selector "tr#li_#{li2.id}" end + + def expect_line_items_results(line_items, excluded_line_items) + expect(page).to have_text "Loading orders" + line_items.each do |li| + expect(page).to have_selector "tr#li_#{li.id}" + end + excluded_line_items.each do |li| + expect(page).to have_no_selector "tr#li_#{li.id}" + end + end end From ac739108a24218f60d001048cd788624905c8814 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Mon, 6 Mar 2023 11:31:36 +0100 Subject: [PATCH 5/5] Improve readability by generating search string for ransack --- .../controllers/line_items_controller.js.coffee | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee b/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee index 1157e571b1..3bf5c469d5 100644 --- a/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee +++ b/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee @@ -17,7 +17,14 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, ] $scope.page = 1 $scope.per_page = $scope.per_page_options[0].id - + searchThrough = ["order_distributor_name", + "order_bill_address_phone", + "order_bill_address_firstname", + "order_bill_address_lastname", + "variant_product_supplier_name", + "order_email", + "order_number", + "product_name"].join("_or_") + "_cont" $scope.confirmRefresh = -> LineItems.allSaved() || confirm(t("unsaved_changes_warning")) @@ -60,7 +67,7 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, [formattedStartDate, formattedEndDate] = $scope.formatDates($scope.startDate, $scope.endDate) RequestMonitor.load LineItems.index( - "q[order_distributor_name_or_order_bill_address_phone_or_order_bill_address_firstname_or_order_bill_address_lastname_or_variant_product_supplier_name_or_order_email_or_order_number_or_product_name_cont]": $scope.query, + "q[#{searchThrough}]": $scope.query, "q[order_state_not_eq]": "canceled", "q[order_shipment_state_not_eq]": "shipped", "q[order_completed_at_not_null]": "true",