From b329aed0f2966da4e11c8dd5b0f59ffb9414c2e2 Mon Sep 17 00:00:00 2001 From: Rob H Date: Fri, 21 Mar 2014 13:00:12 +1100 Subject: [PATCH] BOM: Can toggle columns, and interface rearrange --- .../admin/bulk_order_management.js.coffee | 19 ++++ .../admin/bulk_product_update.js.coffee | 15 --- .../admin/shared_directives.js.coffee | 23 ++++- .../admin/orders/bulk_management.html.haml | 95 ++++++++++--------- .../admin/bulk_order_management_spec.rb | 66 +++++++++++++ 5 files changed, 155 insertions(+), 63 deletions(-) diff --git a/app/assets/javascripts/admin/bulk_order_management.js.coffee b/app/assets/javascripts/admin/bulk_order_management.js.coffee index 33a4c2552d..918711f415 100644 --- a/app/assets/javascripts/admin/bulk_order_management.js.coffee +++ b/app/assets/javascripts/admin/bulk_order_management.js.coffee @@ -122,6 +122,20 @@ orderManagementModule.controller "AdminOrderMgmtCtrl", [ $scope.selectedUnitsVariant = {}; $scope.predicate = "" $scope.reverse = false + $scope.optionTabs = + filters: { title: "Filter Line Items", visible: false } + column_toggle: { title: "Toggle Columns", visible: false } + $scope.columns = + #order_no: { name: "Order No.", visible: false } + full_name: { name: "Name", visible: true } + #email: { name: "Email", visible: false } + #phone: { name: "Phone", visible: false } + order_date: { name: "Order Date", visible: true } + producer: { name: "Producer", visible: true } + #hub: { name: "Hub", visible: false } + variant: { name: "Variant", visible: true } + quantity: { name: "Quantity", visible: true } + max: { name: "Max", visible: true } $scope.initialise = (spree_api_key) -> $scope.initialiseVariables() @@ -261,6 +275,11 @@ orderManagementModule.controller "AdminOrderMgmtCtrl", [ $scope.unitsVariantSelected = -> angular.equals($scope.selectedUnitsVariant,{}) + + $scope.shiftTab = (tab) -> + $scope.visibleTab.visible = false unless $scope.visibleTab == tab || $scope.visibleTab == undefined + tab.visible = !tab.visible + $scope.visibleTab = tab ] orderManagementModule.filter "selectFilter", [ diff --git a/app/assets/javascripts/admin/bulk_product_update.js.coffee b/app/assets/javascripts/admin/bulk_product_update.js.coffee index 97116f673b..a1c1e09f7a 100644 --- a/app/assets/javascripts/admin/bulk_product_update.js.coffee +++ b/app/assets/javascripts/admin/bulk_product_update.js.coffee @@ -65,21 +65,6 @@ productEditModule.directive "ofnToggleVariants", -> element.removeClass "icon-chevron-right" element.addClass "icon-chevron-down" - - -productEditModule.directive "ofnToggleColumn", -> - link: (scope, element, attrs) -> - element.addClass "unselected" unless scope.column.visible - element.click "click", -> - scope.$apply -> - if scope.column.visible - scope.column.visible = false - element.addClass "unselected" - else - scope.column.visible = true - element.removeClass "unselected" - - productEditModule.controller "AdminProductEditCtrl", [ "$scope", "$timeout", "$http", "dataFetcher" ($scope, $timeout, $http, dataFetcher) -> diff --git a/app/assets/javascripts/admin/shared_directives.js.coffee b/app/assets/javascripts/admin/shared_directives.js.coffee index 95eeb30a75..e498482709 100644 --- a/app/assets/javascripts/admin/shared_directives.js.coffee +++ b/app/assets/javascripts/admin/shared_directives.js.coffee @@ -15,4 +15,25 @@ sharedDirectivesModule.directive "datetimepicker", [ # Fires ngModel.$parsers ngModel.$setViewValue dateText ) -] \ No newline at end of file +] + +sharedDirectivesModule.directive "ofnSelect2MinSearch", [ + -> + return ( + link: (scope, element, attrs) -> + element.select2 + minimumResultsForSearch: attrs.ofnSelect2MinSearch + ) +] + +sharedDirectivesModule.directive "ofnToggleColumn", -> + link: (scope, element, attrs) -> + element.addClass "unselected" unless scope.column.visible + element.click "click", -> + scope.$apply -> + if scope.column.visible + scope.column.visible = false + element.addClass "unselected" + else + scope.column.visible = true + element.removeClass "unselected" \ No newline at end of file diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index 54c0b813ad..f407c4a129 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -6,41 +6,36 @@ %div{ 'ng-app' => 'ofn.bulk_order_management', 'ng-controller' => 'AdminOrderMgmtCtrl', 'ng-init' => "initialise('#{@spree_api_key}');loading=true;" } %div{ 'ng-show' => '!spree_api_key_ok' } {{ api_error_msg }} - .filter_selects{ :class => "three columns alpha" } - .filter_select{ :class => "three columns alpha" } - %label{ :for => 'supplier_filter' }Producer - %br - %select.select2{ :class => "three columns alpha", :id => 'supplier_filter', 'ng-model' => 'supplierFilter', 'ng-options' => 's.name for s in suppliers' } - .filter_select{ :class => "three columns alpha" } - %label{ :for => 'distributor_filter' }Hub - %br - %select.select2{ :class => "three columns alpha", :id => 'distributor_filter', 'ng-model' => 'distributorFilter', 'ng-options' => 'd.name for d in distributors'} - .filter_select{ :class => "three columns alpha" } - %label{ :for => 'order_cycle_filter' }Order Cycle - %br - %select.select2{ :class => "three columns alpha", :id => 'order_cycle_filter', 'ng-model' => 'orderCycleFilter', 'ng-options' => 'oc.name for oc in orderCycles'} - .date_filters{ :class => "three columns alpha" } - .date_filter{ :class => "three columns alpha" } - %label{ :for => 'start_date_filter' }Start Date - %br - %input{ :class => "three columns alpha", :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datetimepicker' => "startDate", 'ofn-confirm-change' => "startDate" } - .date_filter{ :class => "three columns alpha" } - %label{ :for => 'end_date_filter' }End Date - %br - %input{ :class => "three columns alpha", :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datetimepicker' => "endDate", 'ofn-confirm-change' => "endDate" } - .quick_search{ :class => "three columns alpha"} - %label{ :for => 'quick_search' }Quick Search - %br - %input{ :class => "three columns alpha", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } - .bulk_actions{ :class => "three columns alpha" } - %div{ :class => "three columns alpha" } - %label{ :for => 'bulk_actions' }Bulk Action - %br - %select.select2{ :class => "three columns alpha", :id => 'bulk_actions', 'ng-model' => 'selectedBulkAction', 'ng-options' => 'a as a.name for a in bulkActions' } - %div{ :class => "three columns alpha" } - %label{ :for => 'bulk_execute' } - %br - %input{ :class => "three columns alpha", :value => "Run", :type => "button", :id => 'bulk_execute', 'ng-click' => 'selectedBulkAction.callback()' } + .option_tab_titles{ :class => "nine columns alpha" } + %h6{ :class => "three columns alpha", 'ng-repeat' => "tab in optionTabs", "ng-click" => "shiftTab(tab)", "ng-class" => "tab.visible && 'selected' || !tab.visible && 'unselected'"} + {{ tab.title }} + .filters{ :class => "nine columns alpha", 'ng-show' => 'optionTabs.filters.visible' } + .row{ :class => "six columns alpha" } + .date_filter{ :class => "three columns alpha" } + %label{ :for => 'start_date_filter' }Start Date + %br + %input{ :class => "three columns alpha", :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datetimepicker' => "startDate", 'ofn-confirm-change' => "startDate" } + .date_filter{ :class => "three columns alpha" } + %label{ :for => 'end_date_filter' }End Date + %br + %input{ :class => "three columns alpha", :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datetimepicker' => "endDate", 'ofn-confirm-change' => "endDate" } + .row{ :class => "nine columns alpha" } + .filter_select{ :class => "three columns alpha" } + %label{ :for => 'supplier_filter' }Producer + %br + %select{ :class => "three columns alpha", :id => 'supplier_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'supplierFilter', 'ng-options' => 's.name for s in suppliers' } + .filter_select{ :class => "three columns alpha" } + %label{ :for => 'distributor_filter' }Hub + %br + %select{ :class => "three columns alpha", :id => 'distributor_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'distributorFilter', 'ng-options' => 'd.name for d in distributors'} + .filter_select{ :class => "three columns alpha" } + %label{ :for => 'order_cycle_filter' }Order Cycle + %br + %select{ :class => "three columns alpha", :id => 'order_cycle_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'orderCycleFilter', 'ng-options' => 'oc.name for oc in orderCycles'} + .column_toggle{ :class => "nine columns alpha", "ng-show" => 'optionTabs.column_toggle.visible' } + %ul.column-list{ :class => "nine columns alpha" } + %li.column-list-item{ :class => "three columns alpha", 'ofn-toggle-column' => 'column', 'ng-repeat' => 'column in columns' } + {{ column.name }} %div#group_buy_calculation{ :class => "seven columns alpha", 'ng-hide' => 'unitsVariantSelected()' } %div{ :class => "seven columns alpha" } %h6{ :class => "five columns alpha" } {{ selectedUnitsVariant.unit_text }} @@ -67,35 +62,41 @@ %div{ :class => "sixteen columns alpha", 'ng-show' => '!loading && lineItems.length == 0'} %h4{ :style => 'color:red;' } No matching line items found. %div{ 'ng-hide' => 'loading || lineItems.length == 0' } + .controls{ :class => "sixteen columns alpha", :style => "margin-bottom: 15px;" } + %input{ :class => "three columns alpha", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } + %div{ :class => "three columns alpha" } + %select{ :class => "three columns alpha", :id => 'bulk_actions', 'ofn-select2-min-search' => 10, 'ng-model' => 'selectedBulkAction', 'ng-options' => 'a as a.name for a in bulkActions' } + %div{ :class => "three columns alpha" } + %input{ :class => "three columns alpha", :value => "Run", :type => "button", :id => 'bulk_execute', 'ng-click' => 'selectedBulkAction.callback()' } %table.index#listing_orders.bulk %thead %tr %th.bulk %input{ :type => "checkbox", :name => 'toggle_bulk', 'ng-click' => 'toggleAllCheckboxes()', 'ng-checked' => "allBoxesChecked()" } - %th.full_name + %th.full_name{ 'ng-show' => 'columns.full_name.visible' } %a{ :href => '', 'ng-click' => "predicate = 'order.full_name'; reverse = !reverse" } Name - %th.date + %th.date{ 'ng-show' => 'columns.order_date.visible' } %a{ :href => '', 'ng-click' => "predicate = 'order.completed_at'; reverse = !reverse" } Order Date - %th.producer + %th.producer{ 'ng-show' => 'columns.producer.visible' } %a{ :href => '', 'ng-click' => "predicate = 'supplier.name'; reverse = !reverse" } Producer - %th.variant + %th.variant{ 'ng-show' => 'columns.variant.visible' } %a{ :href => '', 'ng-click' => "predicate = 'units_variant.unit_text'; reverse = !reverse" } Product: Unit - %th.quantity Quantity - %th.max Max + %th.quantity{ 'ng-show' => 'columns.quantity.visible' } Quantity + %th.max{ 'ng-show' => 'columns.max.visible' } Max %th.actions Ask?  %input{ :type => 'checkbox', 'ng-model' => "confirmDelete" } %tr.line_item{ 'ng-repeat' => "line_item in filteredLineItems = ( lineItems | filter:quickSearch | selectFilter:supplierFilter:distributorFilter:orderCycleFilter:selectedUnitsVariant | orderBy:predicate: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' } - %td.full_name {{ line_item.order.full_name }} - %td.date {{ line_item.order.completed_at }} - %td.producer {{ line_item.supplier.name }} - %td.variant + %td.full_name{ 'ng-show' => 'columns.full_name.visible' } {{ line_item.order.full_name }} + %td.date{ 'ng-show' => 'columns.order_date.visible' } {{ line_item.order.completed_at }} + %td.producer{ 'ng-show' => 'columns.producer.visible' } {{ line_item.supplier.name }} + %td.variant{ 'ng-show' => 'columns.variant.visible' } %a{ 'ng-click' => "setSelectedUnitsVariant(line_item.units_variant)" } {{ line_item.units_variant.unit_text }} - %td.quantity + %td.quantity{ 'ng-show' => 'columns.quantity.visible' } %input{ :type => 'number', :name => 'quantity', 'ng-model' => "line_item.quantity", 'ofn-line-item-upd-attr' => "quantity" } - %td.max {{ line_item.max }} + %td.max{ 'ng-show' => 'columns.max.visible' } {{ line_item.max }} %td.actions %a{ 'ng-click' => "deleteLineItem(line_item)", :class => "delete-line-item icon-trash no-text" } %input{ :type => "button", 'value' => 'Update', 'ng-click' => 'pendingChanges.submitAll()' } \ No newline at end of file diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index 1f44877cc7..eb02ec06cd 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -158,6 +158,68 @@ feature %q{ login_to_admin_section end + let!(:o1) { FactoryGirl.create(:order, state: 'complete', completed_at: Time.now ) } + let!(:li1) { FactoryGirl.create(:line_item, order: o1, :quantity => 5 ) } + + context "using tabs to hide and display page controls" do + it "shows a column display toggle button, which shows a list of columns when clicked" do + visit '/admin/orders/bulk_management' + + page.should have_selector "div.column_toggle", :visible => false + + page.should have_selector "div.option_tab_titles h6.unselected", :text => "Toggle Columns" + first("div.option_tab_titles h6", :text => "Toggle Columns").click + + page.should have_selector "div.option_tab_titles h6.selected", :text => "Toggle Columns" + page.should have_selector "div.column_toggle", :visible => true + page.should have_selector "li.column-list-item", text: "Producer" + + page.should have_selector "div.filters", :visible => false + + page.should have_selector "div.option_tab_titles h6.unselected", :text => "Filter Line Items" + first("div.option_tab_titles h6", :text => "Filter Line Items").click + + page.should have_selector "div.option_tab_titles h6.unselected", :text => "Toggle Columns" + page.should have_selector "div.option_tab_titles h6.selected", :text => "Filter Line Items" + page.should have_selector "div.filters", :visible => true + page.should have_selector "li.column-list-item", text: "Producer" + + first("div.option_tab_titles h6", :text => "Filter Line Items").click + + page.should have_selector "div.option_tab_titles h6.unselected", :text => "Filter Line Items" + page.should have_selector "div.option_tab_titles h6.unselected", :text => "Toggle Columns" + page.should have_selector "div.filters", :visible => false + page.should have_selector "div.column_toggle", :visible => false + end + end + + context "using column display toggle" do + it "shows a column display toggle button, which shows a list of columns when clicked" do + visit '/admin/orders/bulk_management' + + first("div.option_tab_titles h6", :text => "Toggle Columns").click + + page.should have_selector "th", :text => "NAME" + page.should have_selector "th", :text => "ORDER DATE" + page.should have_selector "th", :text => "PRODUCER" + page.should have_selector "th", :text => "PRODUCT: UNIT" + page.should have_selector "th", :text => "QUANTITY" + page.should have_selector "th", :text => "MAX" + + page.should have_selector "div.option_tab_titles h6", :text => "Toggle Columns" + + page.should have_selector "div ul.column-list li.column-list-item", text: "Producer" + first("li.column-list-item", text: "Producer").click + + page.should_not have_selector "th", :text => "PRODUCER" + page.should have_selector "th", :text => "NAME" + page.should have_selector "th", :text => "ORDER DATE" + page.should have_selector "th", :text => "PRODUCT: UNIT" + page.should have_selector "th", :text => "QUANTITY" + page.should have_selector "th", :text => "MAX" + end + end + context "using drop down seletors" do let!(:oc1) { FactoryGirl.create(:order_cycle) } let!(:oc2) { FactoryGirl.create(:order_cycle) } @@ -301,6 +363,7 @@ feature %q{ end it "displays only line items whose orders meet the date restriction criteria, when changed" do + first("div.option_tab_titles h6", :text => "Filter Line Items").click fill_in "start_date_filter", :with => (Date.today - 9).strftime("%F %T") page.should have_selector "tr#li_#{li1.id}", visible: true page.should have_selector "tr#li_#{li2.id}", visible: true @@ -318,6 +381,7 @@ feature %q{ li2_quantity_column.fill_in "quantity", :with => li2.quantity + 1 page.should_not have_button "IGNORE" page.should_not have_button "SAVE" + first("div.option_tab_titles h6", :text => "Filter Line Items").click fill_in "start_date_filter", :with => (Date.today - 9).strftime("%F %T") page.should have_button "IGNORE" page.should have_button "SAVE" @@ -327,6 +391,7 @@ feature %q{ within("tr#li_#{li2.id} td.quantity") do page.fill_in "quantity", :with => (li2.quantity + 1).to_s end + first("div.option_tab_titles h6", :text => "Filter Line Items").click fill_in "start_date_filter", :with => (Date.today - 9).strftime("%F %T") click_button "SAVE" page.should_not have_selector "input[name='quantity'].update-pending" @@ -339,6 +404,7 @@ feature %q{ within("tr#li_#{li2.id} td.quantity") do page.fill_in "quantity", :with => (li2.quantity + 1).to_s end + first("div.option_tab_titles h6", :text => "Filter Line Items").click fill_in "start_date_filter", :with => (Date.today - 9).strftime("%F %T") click_button "IGNORE" page.should_not have_selector "input[name='quantity'].update-pending"