diff --git a/app/assets/javascripts/admin/index_utils/directives/obj_for_update.js.coffee b/app/assets/javascripts/admin/index_utils/directives/obj_for_update.js.coffee index 18c800ce7f..3ed4e6c98f 100644 --- a/app/assets/javascripts/admin/index_utils/directives/obj_for_update.js.coffee +++ b/app/assets/javascripts/admin/index_utils/directives/obj_for_update.js.coffee @@ -11,14 +11,8 @@ angular.module("admin.indexUtils").directive "objForUpdate", (switchClass, pendi pendingChanges.remove(scope.object().id, scope.attr) scope.clear() else - change = - object: scope.object() - type: scope.type - attr: scope.attr - value: if value? then value else "" - scope: scope scope.pending() - pendingChanges.add(scope.object().id, scope.attr, change) + addPendingChange(scope.attr, value ? "") scope.reset = (value) -> scope.savedValue = value @@ -34,3 +28,33 @@ angular.module("admin.indexUtils").directive "objForUpdate", (switchClass, pendi scope.clear = -> switchClass( element, "", ["update-pending", "update-error", "update-success"], false ) + + # When a list of customer is filtered and we removed the "filtered value" from a customer, we + # want to make sure the customer is updated. IE. filtering by tag, and removing said tag. + # Deleting the "filtered value" from a customer will remove the customer entry, thus + # removing "objForUpdate" directive from the active scope. That means $watch won't pick up + # the attribute changed. + # To ensure the customer is still updated, we check on the $destroy event to see if + # the attribute has changed, if so we queue up the change. + scope.$on '$destroy', (value) -> + # No update + return if scope.object()[scope.attr] is scope.savedValue + + # For some reason the code attribute is removed from the object when cleared, so we add + # an emptyvalue so it gets updated properly + if scope.attr is "code" and scope.object()[scope.attr] is undefined + scope.object()["code"] = "" + + # Queuing up change + addPendingChange(scope.attr, scope.object()[scope.attr]) + + # private + + addPendingChange = (attr, value) -> + change = + object: scope.object() + type: scope.type + attr: attr + value: value + scope: scope + pendingChanges.add(scope.object().id, attr, change) diff --git a/app/views/admin/customers/index.html.haml b/app/views/admin/customers/index.html.haml index 3bacae5a4e..e0e2aaf02c 100644 --- a/app/views/admin/customers/index.html.haml +++ b/app/views/admin/customers/index.html.haml @@ -39,16 +39,15 @@ %h1 = t :loading_customers - .row{ :class => "sixteen columns alpha", 'ng-show' => '!RequestMonitor.loading && filteredCustomers.length == 0'} - %h1#no_results - =t :no_customers_found - - .row.margin-bottom-50{ ng: { show: "!RequestMonitor.loading && filteredCustomers.length > 0" } } + .row.margin-bottom-50{ ng: { show: "!RequestMonitor.loading" } } %form{ name: "customers_form" } + %h1#no_results{ 'ng-show' => '!RequestMonitor.loading && filteredCustomers.length == 0' } + =t :no_customers_found + %save-bar{ dirty: "customers_form.$dirty", persist: "false" } %input.red{ type: "button", value: t(:save_changes), ng: { click: "submitAll(customers_form)" } } - %table.index#customers + %table.index#customers{ 'ng-show' => '!RequestMonitor.loading && filteredCustomers.length > 0' } %col.email{ width: "20%", 'ng-show' => 'columns.email.visible' } %col.first_name{ width: "20%", 'ng-show' => 'columns.first_name.visible' } %col.last_name{ width: "20%", 'ng-show' => 'columns.last_name.visible' } diff --git a/spec/system/admin/customers_spec.rb b/spec/system/admin/customers_spec.rb index fc7172697b..f0c278b0fc 100644 --- a/spec/system/admin/customers_spec.rb +++ b/spec/system/admin/customers_spec.rb @@ -35,10 +35,11 @@ describe 'Customers' do it "passes the smoke test" do # Prompts for a hub for a list of my managed enterprises - expect(page) - .to have_select2 "shop_id", with_options: [managed_distributor1.name, - managed_distributor2.name], - without_options: [unmanaged_distributor.name] + expect(page).to have_select2( + "shop_id", + with_options: [managed_distributor1.name, managed_distributor2.name], + without_options: [unmanaged_distributor.name] + ) select2_select managed_distributor2.name, from: "shop_id" @@ -185,6 +186,77 @@ describe 'Customers' do end end + describe "filtering" do + before do + customer4.update enterprise: managed_distributor1 + end + + context "when filtering by code" do + before do + customer4.update code: 12_345 + + select2_select managed_distributor1.name, from: "shop_id" + + fill_in "quick_search", with: customer4.code + end + + it "displays only customer matching the code" do + expect(page).to have_content(customer4.email) + expect(page).not_to have_content(customer1.email) + expect(page).not_to have_content(customer2.email) + end + + context "when updating code" do + it "allows user to save changes" do + fill_in "code", with: "" + + expect(page).not_to have_content("12345") + expect(page).to have_content 'You have unsaved changes' + + click_button "Save Changes" + + # changes are saved in the database + expect(customer4.reload.code).to eq(nil) + end + end + end + + context "when filtering by tag" do + before do + # Add test_tag to customer4 + select2_select managed_distributor1.name, from: "shop_id" + within "tr#c_#{customer4.id}" do + find(:css, "tags-input .tags input").set "test_tag\n" + end + click_button "Save Changes" + + # Reload the page + visit admin_customers_path + select2_select managed_distributor1.name, from: "shop_id" + fill_in "quick_search", with: "test_tag" + end + + it "displays only customer matching the tag" do + expect(page).to have_content(customer4.email) + expect(page).not_to have_content(customer1.email) + expect(page).not_to have_content(customer2.email) + end + + context "when removing tag" do + it "allows user to save changes" do + find("tags-input li.tag-item a.remove-button").click + + expect(page).to have_content("No customers found") + expect(page).to have_content 'You have unsaved changes' + + click_button "Save Changes" + + expect(customer4.reload.tag_list).to be_empty + end + end + end + end + it "allows updating of attributes" do select2_select managed_distributor1.name, from: "shop_id"