From 745390dcd55133b2c1b19d0176fea6daf9c6e76e Mon Sep 17 00:00:00 2001 From: Kristina Lim Date: Sun, 8 Jul 2018 16:40:43 +0800 Subject: [PATCH 1/9] Wrap rows in customer index with TBODY tag --- app/views/admin/customers/index.html.haml | 43 ++++++++++++----------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/app/views/admin/customers/index.html.haml b/app/views/admin/customers/index.html.haml index 9a269b5a99..8e42bf830a 100644 --- a/app/views/admin/customers/index.html.haml +++ b/app/views/admin/customers/index.html.haml @@ -72,27 +72,28 @@ %th.actions Ask?  %input{ :type => 'checkbox', 'ng-model' => "confirmDelete" } - %tr.customer{ 'ng-repeat' => "customer in filteredCustomers = ( customers | filter:quickSearch | orderBy:predicate:reverse ) | limitTo:customerLimit track by customer.id", 'ng-class-even' => "'even'", 'ng-class-odd' => "'odd'", :id => "c_{{customer.id}}" } - -# %td.bulk - -# %input{ :type => "checkbox", :name => 'bulk', 'ng-model' => 'customer.checked' } - %td.email{ 'ng-show' => 'columns.email.visible'} - %span{ 'ng-bind' => '::customer.email' } - %span.guest-label{ 'ng-show' => 'customer.user_id == null' }= t('.guest_label') - %td.name{ 'ng-show' => 'columns.name.visible'} - %input{ type: 'text', name: 'name', ng: { model: 'customer.name' }, 'obj-for-update' => 'customer', 'attr-for-update' => 'name'} - %td.code{ 'ng-show' => 'columns.code.visible' } - %input{ type: 'text', name: 'code', ng: {model: 'customer.code', change: 'checkForDuplicateCodes()'}, "obj-for-update" => "customer", "attr-for-update" => "code" } - %i.icon-warning-sign{ ng: {if: 'duplicate'} } - = t('.duplicate_code') - %td.tags{ 'ng-show' => 'columns.tags.visible' } - .tag_watcher{ 'obj-for-update' => "customer", "attr-for-update" => "tag_list"} - %tags_with_translation{ object: 'customer', 'find-tags' => 'findTags(query)' } - %td.bill_address{ 'ng-show' => 'columns.bill_address.visible' } - %a{ id: 'bill-address-link', href: 'javascript:void(0)', "ng-bind" => "customer.bill_address ? customer.bill_address.address1 : '#{t('admin.customers.index.edit')}' | limitTo: 15", 'edit-address-dialog' => true } - %td.ship_address{ 'ng-show' => 'columns.ship_address.visible' } - %a{ id: 'ship-address-link', href: 'javascript:void(0)', "ng-bind" => "customer.ship_address ? customer.ship_address.address1 : '#{t('admin.customers.index.edit')}' | limitTo: 15", 'edit-address-dialog' => true } - %td.actions - %a{ 'ng-click' => "deleteCustomer(customer)", :class => "delete-customer icon-trash no-text" } + %tbody + %tr.customer{ 'ng-repeat' => "customer in filteredCustomers = ( customers | filter:quickSearch | orderBy:predicate:reverse ) | limitTo:customerLimit track by customer.id", 'ng-class-even' => "'even'", 'ng-class-odd' => "'odd'", :id => "c_{{customer.id}}" } + -# %td.bulk + -# %input{ :type => "checkbox", :name => 'bulk', 'ng-model' => 'customer.checked' } + %td.email{ 'ng-show' => 'columns.email.visible'} + %span{ 'ng-bind' => '::customer.email' } + %span.guest-label{ 'ng-show' => 'customer.user_id == null' }= t('.guest_label') + %td.name{ 'ng-show' => 'columns.name.visible'} + %input{ type: 'text', name: 'name', ng: { model: 'customer.name' }, 'obj-for-update' => 'customer', 'attr-for-update' => 'name'} + %td.code{ 'ng-show' => 'columns.code.visible' } + %input{ type: 'text', name: 'code', ng: {model: 'customer.code', change: 'checkForDuplicateCodes()'}, "obj-for-update" => "customer", "attr-for-update" => "code" } + %i.icon-warning-sign{ ng: {if: 'duplicate'} } + = t('.duplicate_code') + %td.tags{ 'ng-show' => 'columns.tags.visible' } + .tag_watcher{ 'obj-for-update' => "customer", "attr-for-update" => "tag_list"} + %tags_with_translation{ object: 'customer', 'find-tags' => 'findTags(query)' } + %td.bill_address{ 'ng-show' => 'columns.bill_address.visible' } + %a{ id: 'bill-address-link', href: 'javascript:void(0)', "ng-bind" => "customer.bill_address ? customer.bill_address.address1 : '#{t('admin.customers.index.edit')}' | limitTo: 15", 'edit-address-dialog' => true } + %td.ship_address{ 'ng-show' => 'columns.ship_address.visible' } + %a{ id: 'ship-address-link', href: 'javascript:void(0)', "ng-bind" => "customer.ship_address ? customer.ship_address.address1 : '#{t('admin.customers.index.edit')}' | limitTo: 15", 'edit-address-dialog' => true } + %td.actions + %a{ 'ng-click' => "deleteCustomer(customer)", :class => "delete-customer icon-trash no-text" } -# %show-more.text-center{ data: "filteredCustomers", limit: "customerLimit", increment: "20" } %div.text-center{ ng: { show: "filteredCustomers.length > customerLimit" } } From 9f09861d8b72f00af3baecf0e94fa55bb9fbfb6d Mon Sep 17 00:00:00 2001 From: Kristina Lim Date: Sun, 8 Jul 2018 17:32:16 +0800 Subject: [PATCH 2/9] Change sorting to be done in ascending order first Currently, we always toggle "reverse" when triggering a sort. If "reverse" is initially set to false, triggering a sort for the first time then toggles this to true. The effect is that, the first time that sorting is done, the rows are sorted in reverse order. This is not intuitive - they should be sorted in ascending order first. --- .../admin/index_utils/controllers/columns_controller.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/admin/index_utils/controllers/columns_controller.js.coffee b/app/assets/javascripts/admin/index_utils/controllers/columns_controller.js.coffee index 39556983b3..b51b26d633 100644 --- a/app/assets/javascripts/admin/index_utils/controllers/columns_controller.js.coffee +++ b/app/assets/javascripts/admin/index_utils/controllers/columns_controller.js.coffee @@ -1,4 +1,4 @@ angular.module("admin.indexUtils").controller "ColumnsCtrl", ($scope, Columns) -> $scope.columns = Columns.columns $scope.predicate = "" - $scope.reverse = false + $scope.reverse = true From 822b2c929af05db5e6c815f92870d805be9c0034 Mon Sep 17 00:00:00 2001 From: Kristina Lim Date: Thu, 5 Jul 2018 18:15:33 +0800 Subject: [PATCH 3/9] Fix frontend sorting in "Customers" index The scope for customersCtrl did not have access to the sorting preferences stored in the nested ColumnsCtrl scope. To address this, the page has been changed to use a new set of sorting preferences declared in the customersCtrl scope itself. Also, these sorting preferences are now stored in an object. This enables the parent scope to see changes to the sorting preferences which are done via the nested ColumnsCtrl scope, The "Bulk Order Management" page is also affected by the same scoping issue. Once this page is fixed, we can remove remnants of the sorting preferences initialized in ColumnsCtrl. --- .../controllers/customers_controller.js.coffee | 3 +++ app/views/admin/customers/index.html.haml | 8 ++++---- spec/features/admin/customers_spec.rb | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/admin/customers/controllers/customers_controller.js.coffee b/app/assets/javascripts/admin/customers/controllers/customers_controller.js.coffee index d4ba6383d8..ada3eb2b0e 100644 --- a/app/assets/javascripts/admin/customers/controllers/customers_controller.js.coffee +++ b/app/assets/javascripts/admin/customers/controllers/customers_controller.js.coffee @@ -6,6 +6,9 @@ angular.module("admin.customers").controller "customersCtrl", ($scope, $q, $filt $scope.customerLimit = 20 $scope.customers = Customers.all $scope.columns = Columns.columns + $scope.sorting = + predicate: "" + reverse: true $scope.confirmRefresh = (event) -> event.preventDefault() unless pendingChanges.unsavedCount() == 0 || confirm(t("unsaved_changes_warning")) diff --git a/app/views/admin/customers/index.html.haml b/app/views/admin/customers/index.html.haml index 8e42bf830a..035e0c1570 100644 --- a/app/views/admin/customers/index.html.haml +++ b/app/views/admin/customers/index.html.haml @@ -61,11 +61,11 @@ -# %th.bulk -# %input{ :type => "checkbox", :name => 'toggle_bulk', 'ng-click' => 'toggleAllCheckboxes()', 'ng-checked' => "allBoxesChecked()" } %th.email{ 'ng-show' => 'columns.email.visible' } - %a{ :href => '', 'ng-click' => "predicate = 'customer.email'; reverse = !reverse" }=t('admin.email') + %a{ :href => '', 'ng-click' => "sorting.predicate = 'customer.email'; sorting.reverse = !sorting.reverse" }=t('admin.email') %th.name{ 'ng-show' => 'columns.name.visible' } - %a{ :href => '', 'ng-click' => "predicate = 'customer.name'; reverse = !reverse" }=t('admin.name') + %a{ :href => '', 'ng-click' => "sorting.predicate = 'customer.name'; sorting.reverse = !sorting.reverse" }=t('admin.name') %th.code{ 'ng-show' => 'columns.code.visible' } - %a{ :href => '', 'ng-click' => "predicate = 'customer.code'; reverse = !reverse" }=t('admin.customers.index.code') + %a{ :href => '', 'ng-click' => "sorting.predicate = 'customer.code'; sorting.reverse = !sorting.reverse" }=t('admin.customers.index.code') %th.tags{ 'ng-show' => 'columns.tags.visible' }=t('admin.tags') %th.bill_address{ 'ng-show' => 'columns.bill_address.visible' }=t('admin.customers.index.bill_address') %th.ship_address{ 'ng-show' => 'columns.ship_address.visible' }=t('admin.customers.index.ship_address') @@ -73,7 +73,7 @@ Ask?  %input{ :type => 'checkbox', 'ng-model' => "confirmDelete" } %tbody - %tr.customer{ 'ng-repeat' => "customer in filteredCustomers = ( customers | filter:quickSearch | orderBy:predicate:reverse ) | limitTo:customerLimit track by customer.id", 'ng-class-even' => "'even'", 'ng-class-odd' => "'odd'", :id => "c_{{customer.id}}" } + %tr.customer{ 'ng-repeat' => "customer in filteredCustomers = ( customers | filter:quickSearch | orderBy: sorting.predicate:sorting.reverse ) | limitTo:customerLimit track by customer.id", 'ng-class-even' => "'even'", 'ng-class-odd' => "'odd'", :id => "c_{{customer.id}}" } -# %td.bulk -# %input{ :type => "checkbox", :name => 'bulk', 'ng-model' => 'customer.checked' } %td.email{ 'ng-show' => 'columns.email.visible'} diff --git a/spec/features/admin/customers_spec.rb b/spec/features/admin/customers_spec.rb index cfbbd9e0e5..14c85d3504 100644 --- a/spec/features/admin/customers_spec.rb +++ b/spec/features/admin/customers_spec.rb @@ -48,6 +48,21 @@ feature 'Customers' do expect(page).to have_selector "tr#c_#{customer2.id}" fill_in "quick_search", with: "" + # Sorting when the header of a sortable column is clicked + customer_emails = [customer1.email, customer2.email].sort + within "#customers thead" do + click_on "Email" + end + expect(page).to have_selector("#customers .customer:nth-child(1) .email", text: customer_emails[0]) + expect(page).to have_selector("#customers .customer:nth-child(2) .email", text: customer_emails[1]) + + # Then sorting in reverse when the header is clicked again + within "#customers thead" do + click_on "Email" + end + expect(page).to have_selector("#customers .customer:nth-child(1) .email", text: customer_emails[1]) + expect(page).to have_selector("#customers .customer:nth-child(2) .email", text: customer_emails[0]) + # Toggling columns expect(page).to have_selector "th.email" expect(page).to have_content customer1.email From 2bba72c5a95193200684bdad351c04590e039703 Mon Sep 17 00:00:00 2001 From: Kristina Lim Date: Fri, 6 Jul 2018 17:26:02 +0800 Subject: [PATCH 4/9] Fix frontend sorting in "Bulk Order Management" --- .../line_items_controller.js.coffee | 3 ++ .../admin/orders/bulk_management.html.haml | 20 +++++------ .../admin/bulk_order_management_spec.rb | 34 +++++++++++++++++++ 3 files changed, 47 insertions(+), 10 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 29b0d4c4db..4ddee58c48 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 @@ -10,6 +10,9 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $scope.selectedUnitsVariant = {} $scope.sharedResource = false $scope.columns = Columns.columns + $scope.sorting = + predicate: "" + reverse: true $scope.confirmRefresh = -> LineItems.allSaved() || confirm(t("unsaved_changes_warning")) diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index 9efb7b4e28..b3474b99c3 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -118,31 +118,31 @@ %th.bulk %input{ :type => "checkbox", :name => 'toggle_bulk', 'ng-click' => 'toggleAllCheckboxes()', 'ng-checked' => "allBoxesChecked()" } %th.order_no{ 'ng-show' => 'columns.order_no.visible' } - %a{ :href => '', 'ng-click' => "predicate = 'order.number'; reverse = !reverse" } + %a{ :href => '', 'ng-click' => "sorting.predicate = 'order.number'; sorting.reverse = !sorting.reverse" } = t("admin.orders.bulk_management.order_no") %th.full_name{ 'ng-show' => 'columns.full_name.visible' } - %a{ :href => '', 'ng-click' => "predicate = 'order.full_name'; reverse = !reverse" } + %a{ :href => '', 'ng-click' => "sorting.predicate = 'order.full_name'; sorting.reverse = !sorting.reverse" } = t("admin.name") %th.email{ 'ng-show' => 'columns.email.visible' } - %a{ :href => '', 'ng-click' => "predicate = 'order.email'; reverse = !reverse" } + %a{ :href => '', 'ng-click' => "sorting.predicate = 'order.email'; sorting.reverse = !sorting.reverse" } = t("admin.email") %th.phone{ 'ng-show' => 'columns.phone.visible' } - %a{ :href => '', 'ng-click' => "predicate = 'order.phone'; reverse = !reverse" } + %a{ :href => '', 'ng-click' => "sorting.predicate = 'order.phone'; sorting.reverse = !sorting.reverse" } = t("admin.phone") %th.date{ 'ng-show' => 'columns.order_date.visible' } - %a{ :href => '', 'ng-click' => "predicate = 'order.completed_at'; reverse = !reverse" } + %a{ :href => '', 'ng-click' => "sorting.predicate = 'order.completed_at'; sorting.reverse = !sorting.reverse" } = t("admin.orders.bulk_management.order_date") %th.producer{ 'ng-show' => 'columns.producer.visible' } - %a{ :href => '', 'ng-click' => "predicate = 'supplier.name'; reverse = !reverse" } + %a{ :href => '', 'ng-click' => "sorting.predicate = 'supplier.name'; sorting.reverse = !sorting.reverse" } = t("admin.producer") %th.order_cycle{ 'ng-show' => 'columns.order_cycle.visible' } - %a{ :href => '', 'ng-click' => "predicate = 'order.order_cycle.name'; reverse = !reverse" } + %a{ :href => '', 'ng-click' => "sorting.predicate = 'order.order_cycle.name'; sorting.reverse = !sorting.reverse" } = t("admin.order_cycle") %th.hub{ 'ng-show' => 'columns.hub.visible' } - %a{ :href => '', 'ng-click' => "predicate = 'order.distributor.name'; reverse = !reverse" } + %a{ :href => '', 'ng-click' => "sorting.predicate = 'order.distributor.name'; sorting.reverse = !sorting.reverse" } = t("admin.shop") %th.variant{ 'ng-show' => 'columns.variant.visible' } - %a{ :href => '', 'ng-click' => "predicate = 'units_variant.full_name'; reverse = !reverse" } + %a{ :href => '', 'ng-click' => "sorting.predicate = 'units_variant.full_name'; sorting.reverse = !sorting.reverse" } = t("admin.orders.bulk_management.product_unit") %th.quantity{ 'ng-show' => 'columns.quantity.visible' } = t("admin.quantity") @@ -157,7 +157,7 @@ = t("admin.orders.bulk_management.ask") %input{ :type => 'checkbox', 'ng-model' => "confirmDelete" } - %tr.line_item{ 'ng-repeat' => "line_item in filteredLineItems = ( lineItems | filter:quickSearch | selectFilter:supplierFilter:distributorFilter:orderCycleFilter | variantFilter:selectedUnitsProduct:selectedUnitsVariant:sharedResource | orderBy:predicate:reverse )", 'ng-class-even' => "'even'", 'ng-class-odd' => "'odd'", :id => "li_{{line_item.id}}" } + %tr.line_item{ 'ng-repeat' => "line_item in filteredLineItems = ( lineItems | filter:quickSearch | selectFilter:supplierFilter:distributorFilter:orderCycleFilter | variantFilter:selectedUnitsProduct:selectedUnitsVariant:sharedResource | orderBy:sorting.predicate:sorting.reverse )", 'ng-class-even' => "'even'", 'ng-class-odd' => "'odd'", :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/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index 81b2845e04..f028776121 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -82,6 +82,40 @@ feature %q{ expect(page).to have_selector "td.max", text: li2.max_quantity.to_s, :visible => true end end + + describe "sorting of line items" do + let!(:o1) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now) } + let!(:o2) { create(:order_with_distributor, state: 'complete', completed_at: Time.zone.now) } + let!(:li1) { create(:line_item, order: o1) } + let!(:li2) { create(:line_item, order: o2) } + + before do + visit spree.admin_bulk_order_management_path + end + + it "sorts by customer name when the customer name header is clicked" do + customer_names = [o1.name, o2.name].sort + + within "#listing_orders thead" do + click_on "Name" + end + + expect(page).to have_selector("#listing_orders .line_item:nth-child(1) .full_name", text: customer_names[0]) + expect(page).to have_selector("#listing_orders .line_item:nth-child(2) .full_name", text: customer_names[1]) + end + + it "sorts by customer name in reverse when the customer name header is clicked twice" do + customer_names = [o1.name, o2.name].sort.reverse + + within "#listing_orders thead" do + click_on "Name" + click_on "Name" + end + + expect(page).to have_selector("#listing_orders .line_item:nth-child(1) .full_name", text: customer_names[1]) + expect(page).to have_selector("#listing_orders .line_item:nth-child(2) .full_name", text: customer_names[0]) + end + end end context "altering line item properties" do From 8b6b694244bb31ab53ecbbe2f4b8c4c0f9561f23 Mon Sep 17 00:00:00 2001 From: Kristina Lim Date: Fri, 6 Jul 2018 17:26:54 +0800 Subject: [PATCH 5/9] Remove unused sorting preferences in ColumnsCtrl --- .../admin/index_utils/controllers/columns_controller.js.coffee | 2 -- .../index_utils/controllers/columns_controller_spec.js.coffee | 2 -- 2 files changed, 4 deletions(-) diff --git a/app/assets/javascripts/admin/index_utils/controllers/columns_controller.js.coffee b/app/assets/javascripts/admin/index_utils/controllers/columns_controller.js.coffee index b51b26d633..9ee04a4f19 100644 --- a/app/assets/javascripts/admin/index_utils/controllers/columns_controller.js.coffee +++ b/app/assets/javascripts/admin/index_utils/controllers/columns_controller.js.coffee @@ -1,4 +1,2 @@ angular.module("admin.indexUtils").controller "ColumnsCtrl", ($scope, Columns) -> $scope.columns = Columns.columns - $scope.predicate = "" - $scope.reverse = true diff --git a/spec/javascripts/unit/admin/index_utils/controllers/columns_controller_spec.js.coffee b/spec/javascripts/unit/admin/index_utils/controllers/columns_controller_spec.js.coffee index 5fd79e71bf..5e01fdcc35 100644 --- a/spec/javascripts/unit/admin/index_utils/controllers/columns_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/index_utils/controllers/columns_controller_spec.js.coffee @@ -13,5 +13,3 @@ describe "ColumnsCtrl", -> it "initialises data", -> expect(scope.columns).toEqual Columns.columns - expect(scope.predicate).toEqual "" - expect(scope.reverse).toEqual false From 55d0b1dfc539bc4a66b7ad0ebc321f7b08d0cddc Mon Sep 17 00:00:00 2001 From: Kristina Lim Date: Thu, 19 Jul 2018 03:36:57 +0800 Subject: [PATCH 6/9] Generalize sorting through SortOptions service --- .../controllers/customers_controller.js.coffee | 6 ++---- .../index_utils/services/sort_options.js.coffee | 4 ++++ .../controllers/line_items_controller.js.coffee | 6 ++---- .../services/sort_options_spec.js.coffee | 15 +++++++++++++++ 4 files changed, 23 insertions(+), 8 deletions(-) create mode 100644 app/assets/javascripts/admin/index_utils/services/sort_options.js.coffee create mode 100644 spec/javascripts/unit/admin/index_utils/services/sort_options_spec.js.coffee diff --git a/app/assets/javascripts/admin/customers/controllers/customers_controller.js.coffee b/app/assets/javascripts/admin/customers/controllers/customers_controller.js.coffee index ada3eb2b0e..c8967780dc 100644 --- a/app/assets/javascripts/admin/customers/controllers/customers_controller.js.coffee +++ b/app/assets/javascripts/admin/customers/controllers/customers_controller.js.coffee @@ -1,4 +1,4 @@ -angular.module("admin.customers").controller "customersCtrl", ($scope, $q, $filter, Customers, TagRuleResource, CurrentShop, RequestMonitor, Columns, pendingChanges, shops, availableCountries) -> +angular.module("admin.customers").controller "customersCtrl", ($scope, $q, $filter, Customers, TagRuleResource, CurrentShop, RequestMonitor, Columns, SortOptions, pendingChanges, shops, availableCountries) -> $scope.shops = shops $scope.availableCountries = availableCountries $scope.RequestMonitor = RequestMonitor @@ -6,9 +6,7 @@ angular.module("admin.customers").controller "customersCtrl", ($scope, $q, $filt $scope.customerLimit = 20 $scope.customers = Customers.all $scope.columns = Columns.columns - $scope.sorting = - predicate: "" - reverse: true + $scope.sorting = SortOptions $scope.confirmRefresh = (event) -> event.preventDefault() unless pendingChanges.unsavedCount() == 0 || confirm(t("unsaved_changes_warning")) diff --git a/app/assets/javascripts/admin/index_utils/services/sort_options.js.coffee b/app/assets/javascripts/admin/index_utils/services/sort_options.js.coffee new file mode 100644 index 0000000000..5c3f38fef4 --- /dev/null +++ b/app/assets/javascripts/admin/index_utils/services/sort_options.js.coffee @@ -0,0 +1,4 @@ +angular.module("admin.indexUtils").factory 'SortOptions', -> + new class SortOptions + predicate: "" + reverse: true 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 4ddee58c48..ecc567c7cc 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 @@ -1,4 +1,4 @@ -angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $http, $q, StatusMessage, Columns, Dereferencer, Orders, LineItems, Enterprises, OrderCycles, VariantUnitManager, RequestMonitor) -> +angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $http, $q, StatusMessage, Columns, SortOptions, Dereferencer, Orders, LineItems, Enterprises, OrderCycles, VariantUnitManager, RequestMonitor) -> $scope.initialized = false $scope.RequestMonitor = RequestMonitor $scope.filteredLineItems = [] @@ -10,9 +10,7 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $scope.selectedUnitsVariant = {} $scope.sharedResource = false $scope.columns = Columns.columns - $scope.sorting = - predicate: "" - reverse: true + $scope.sorting = SortOptions $scope.confirmRefresh = -> LineItems.allSaved() || confirm(t("unsaved_changes_warning")) diff --git a/spec/javascripts/unit/admin/index_utils/services/sort_options_spec.js.coffee b/spec/javascripts/unit/admin/index_utils/services/sort_options_spec.js.coffee new file mode 100644 index 0000000000..90fd34cf02 --- /dev/null +++ b/spec/javascripts/unit/admin/index_utils/services/sort_options_spec.js.coffee @@ -0,0 +1,15 @@ +describe "SortOptions service", -> + SortOptions = null + + beforeEach -> + module 'admin.indexUtils' + inject (_SortOptions_) -> + SortOptions = _SortOptions_ + + describe "initialising predicate", -> + it "sets predicate to blank", -> + expect(SortOptions.predicate).toEqual "" + + describe "initialising reverse", -> + it "sets reverse to true", -> + expect(SortOptions.reverse).toBe true From 5179f7fd636867d442e667eb8bfc75dad416d73f Mon Sep 17 00:00:00 2001 From: Kristina Lim Date: Fri, 20 Jul 2018 09:25:55 +0800 Subject: [PATCH 7/9] Move logic for toggling by column into SortOptions --- .../services/sort_options.js.coffee | 4 ++++ app/views/admin/customers/index.html.haml | 6 +++--- .../admin/orders/bulk_management.html.haml | 18 +++++++++--------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/admin/index_utils/services/sort_options.js.coffee b/app/assets/javascripts/admin/index_utils/services/sort_options.js.coffee index 5c3f38fef4..770a09ac84 100644 --- a/app/assets/javascripts/admin/index_utils/services/sort_options.js.coffee +++ b/app/assets/javascripts/admin/index_utils/services/sort_options.js.coffee @@ -2,3 +2,7 @@ angular.module("admin.indexUtils").factory 'SortOptions', -> new class SortOptions predicate: "" reverse: true + + toggle: (predicate) -> + @predicate = predicate + @reverse = !@reverse diff --git a/app/views/admin/customers/index.html.haml b/app/views/admin/customers/index.html.haml index 035e0c1570..0a1fb012dc 100644 --- a/app/views/admin/customers/index.html.haml +++ b/app/views/admin/customers/index.html.haml @@ -61,11 +61,11 @@ -# %th.bulk -# %input{ :type => "checkbox", :name => 'toggle_bulk', 'ng-click' => 'toggleAllCheckboxes()', 'ng-checked' => "allBoxesChecked()" } %th.email{ 'ng-show' => 'columns.email.visible' } - %a{ :href => '', 'ng-click' => "sorting.predicate = 'customer.email'; sorting.reverse = !sorting.reverse" }=t('admin.email') + %a{ :href => '', 'ng-click' => "sorting.toggle('customer.email')" }=t('admin.email') %th.name{ 'ng-show' => 'columns.name.visible' } - %a{ :href => '', 'ng-click' => "sorting.predicate = 'customer.name'; sorting.reverse = !sorting.reverse" }=t('admin.name') + %a{ :href => '', 'ng-click' => "sorting.toggle('customer.name')" }=t('admin.name') %th.code{ 'ng-show' => 'columns.code.visible' } - %a{ :href => '', 'ng-click' => "sorting.predicate = 'customer.code'; sorting.reverse = !sorting.reverse" }=t('admin.customers.index.code') + %a{ :href => '', 'ng-click' => "sorting.toggle('customer.code')" }=t('admin.customers.index.code') %th.tags{ 'ng-show' => 'columns.tags.visible' }=t('admin.tags') %th.bill_address{ 'ng-show' => 'columns.bill_address.visible' }=t('admin.customers.index.bill_address') %th.ship_address{ 'ng-show' => 'columns.ship_address.visible' }=t('admin.customers.index.ship_address') diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index b3474b99c3..50aa10634f 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -118,31 +118,31 @@ %th.bulk %input{ :type => "checkbox", :name => 'toggle_bulk', 'ng-click' => 'toggleAllCheckboxes()', 'ng-checked' => "allBoxesChecked()" } %th.order_no{ 'ng-show' => 'columns.order_no.visible' } - %a{ :href => '', 'ng-click' => "sorting.predicate = 'order.number'; sorting.reverse = !sorting.reverse" } + %a{ :href => '', 'ng-click' => "sorting.toggle('order.number')" } = t("admin.orders.bulk_management.order_no") %th.full_name{ 'ng-show' => 'columns.full_name.visible' } - %a{ :href => '', 'ng-click' => "sorting.predicate = 'order.full_name'; sorting.reverse = !sorting.reverse" } + %a{ :href => '', 'ng-click' => "sorting.toggle('order.full_name')" } = t("admin.name") %th.email{ 'ng-show' => 'columns.email.visible' } - %a{ :href => '', 'ng-click' => "sorting.predicate = 'order.email'; sorting.reverse = !sorting.reverse" } + %a{ :href => '', 'ng-click' => "sorting.toggle('order.email')" } = t("admin.email") %th.phone{ 'ng-show' => 'columns.phone.visible' } - %a{ :href => '', 'ng-click' => "sorting.predicate = 'order.phone'; sorting.reverse = !sorting.reverse" } + %a{ :href => '', 'ng-click' => "sorting.toggle('order.phone')" } = t("admin.phone") %th.date{ 'ng-show' => 'columns.order_date.visible' } - %a{ :href => '', 'ng-click' => "sorting.predicate = 'order.completed_at'; sorting.reverse = !sorting.reverse" } + %a{ :href => '', 'ng-click' => "sorting.toggle('order.completed_at')" } = t("admin.orders.bulk_management.order_date") %th.producer{ 'ng-show' => 'columns.producer.visible' } - %a{ :href => '', 'ng-click' => "sorting.predicate = 'supplier.name'; sorting.reverse = !sorting.reverse" } + %a{ :href => '', 'ng-click' => "sorting.toggle('supplier.name')" } = t("admin.producer") %th.order_cycle{ 'ng-show' => 'columns.order_cycle.visible' } - %a{ :href => '', 'ng-click' => "sorting.predicate = 'order.order_cycle.name'; sorting.reverse = !sorting.reverse" } + %a{ :href => '', 'ng-click' => "sorting.toggle('order.order_cycle.name')" } = t("admin.order_cycle") %th.hub{ 'ng-show' => 'columns.hub.visible' } - %a{ :href => '', 'ng-click' => "sorting.predicate = 'order.distributor.name'; sorting.reverse = !sorting.reverse" } + %a{ :href => '', 'ng-click' => "sorting.toggle('order.distributor.name')" } = t("admin.shop") %th.variant{ 'ng-show' => 'columns.variant.visible' } - %a{ :href => '', 'ng-click' => "sorting.predicate = 'units_variant.full_name'; sorting.reverse = !sorting.reverse" } + %a{ :href => '', 'ng-click' => "sorting.toggle('units_variant.full_name')" } = t("admin.orders.bulk_management.product_unit") %th.quantity{ 'ng-show' => 'columns.quantity.visible' } = t("admin.quantity") From 47608525c64a5b45db8c7041f0543a3ecd372e47 Mon Sep 17 00:00:00 2001 From: Kristina Lim Date: Fri, 20 Jul 2018 09:27:16 +0800 Subject: [PATCH 8/9] Reset reverse when clicking another column to sort --- .../services/sort_options.js.coffee | 2 +- .../services/sort_options_spec.js.coffee | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/admin/index_utils/services/sort_options.js.coffee b/app/assets/javascripts/admin/index_utils/services/sort_options.js.coffee index 770a09ac84..36f1bc4d4d 100644 --- a/app/assets/javascripts/admin/index_utils/services/sort_options.js.coffee +++ b/app/assets/javascripts/admin/index_utils/services/sort_options.js.coffee @@ -4,5 +4,5 @@ angular.module("admin.indexUtils").factory 'SortOptions', -> reverse: true toggle: (predicate) -> + @reverse = (@predicate == predicate) && !@reverse @predicate = predicate - @reverse = !@reverse diff --git a/spec/javascripts/unit/admin/index_utils/services/sort_options_spec.js.coffee b/spec/javascripts/unit/admin/index_utils/services/sort_options_spec.js.coffee index 90fd34cf02..6c4b068bc4 100644 --- a/spec/javascripts/unit/admin/index_utils/services/sort_options_spec.js.coffee +++ b/spec/javascripts/unit/admin/index_utils/services/sort_options_spec.js.coffee @@ -13,3 +13,32 @@ describe "SortOptions service", -> describe "initialising reverse", -> it "sets reverse to true", -> expect(SortOptions.reverse).toBe true + + describe "sorting by a column", -> + describe "when selecting Column A once", -> + it "sorts by Column A", -> + SortOptions.toggle("column.a") + expect(SortOptions.predicate).toEqual "column.a" + expect(SortOptions.reverse).toBe false + + describe "when selecting Column A twice", -> + it "sorts by Column A in reverse order", -> + SortOptions.toggle("column.a") + SortOptions.toggle("column.a") + expect(SortOptions.predicate).toEqual "column.a" + expect(SortOptions.reverse).toBe true + + describe "when selecting Column A once then selecting Column B once", -> + it "sorts by Column B", -> + SortOptions.toggle("column.a") + SortOptions.toggle("column.b") + expect(SortOptions.predicate).toEqual "column.b" + expect(SortOptions.reverse).toBe false + + describe "when selecting Column A twice then selecting Column B once", -> + it "sorts by Column B in reverse order", -> + SortOptions.toggle("column.a") + SortOptions.toggle("column.a") + SortOptions.toggle("column.b") + expect(SortOptions.predicate).toEqual "column.b" + expect(SortOptions.reverse).toBe false From 89ac558f3786c05a51529e1ca378ffa20bc7808d Mon Sep 17 00:00:00 2001 From: Kristina Lim Date: Fri, 20 Jul 2018 11:45:07 +0800 Subject: [PATCH 9/9] Fix wrong sort predicates in customer index --- app/views/admin/customers/index.html.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/admin/customers/index.html.haml b/app/views/admin/customers/index.html.haml index 0a1fb012dc..6477357d63 100644 --- a/app/views/admin/customers/index.html.haml +++ b/app/views/admin/customers/index.html.haml @@ -61,11 +61,11 @@ -# %th.bulk -# %input{ :type => "checkbox", :name => 'toggle_bulk', 'ng-click' => 'toggleAllCheckboxes()', 'ng-checked' => "allBoxesChecked()" } %th.email{ 'ng-show' => 'columns.email.visible' } - %a{ :href => '', 'ng-click' => "sorting.toggle('customer.email')" }=t('admin.email') + %a{ :href => '', 'ng-click' => "sorting.toggle('email')" }=t('admin.email') %th.name{ 'ng-show' => 'columns.name.visible' } - %a{ :href => '', 'ng-click' => "sorting.toggle('customer.name')" }=t('admin.name') + %a{ :href => '', 'ng-click' => "sorting.toggle('name')" }=t('admin.name') %th.code{ 'ng-show' => 'columns.code.visible' } - %a{ :href => '', 'ng-click' => "sorting.toggle('customer.code')" }=t('admin.customers.index.code') + %a{ :href => '', 'ng-click' => "sorting.toggle('code')" }=t('admin.customers.index.code') %th.tags{ 'ng-show' => 'columns.tags.visible' }=t('admin.tags') %th.bill_address{ 'ng-show' => 'columns.bill_address.visible' }=t('admin.customers.index.bill_address') %th.ship_address{ 'ng-show' => 'columns.ship_address.visible' }=t('admin.customers.index.ship_address')