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 fcb7be17f0..5a37a3377d 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 @@ -9,38 +9,39 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $scope.sharedResource = false $scope.columns = Columns.columns $scope.sorting = SortOptions + $scope.pagination = Orders.pagination + $scope.per_page_options = [ + {id: 15, name: t('js.admin.orders.index.per_page', results: 15)}, + {id: 50, name: t('js.admin.orders.index.per_page', results: 50)}, + {id: 100, name: t('js.admin.orders.index.per_page', results: 100)} + ] + $scope.page = 1 + $scope.per_page = $scope.per_page_options[0].id + $scope.confirmRefresh = -> LineItems.allSaved() || confirm(t("unsaved_changes_warning")) - $scope.initStartAndEnDate = -> - $scope.startDate = moment().startOf('day').subtract(7, 'days').format('YYYY-MM-DD') - $scope.endDate = moment().startOf('day').format('YYYY-MM-DD') - $scope.resetFilters = -> $scope.distributorFilter = '' $scope.supplierFilter = '' $scope.orderCycleFilter = '' $scope.quickSearch = '' - $scope.initStartAndEnDate() - event = new CustomEvent('flatpickr:change', { - detail: { - startDate: $scope.startDate, - endDate: $scope.endDate - } - }) + $scope.startDate = undefined + $scope.endDate = undefined + event = new CustomEvent('flatpickr:clear') window.dispatchEvent(event) $scope.resetSelectFilters = -> $scope.resetFilters() $scope.refreshData() + $scope.fetchResults = -> + # creates indirection in order to factorize the code between orders and bulk orders + # used in app/views/admin/shared/_angular_per_page_controls.html.haml + $scope.refreshData() + $scope.refreshData = -> - $scope.formattedStartDate = moment($scope.startDate).format() - $scope.formattedEndDate = moment($scope.endDate).add(1,'day').format() - - return unless moment($scope.formattedStartDate).isValid() and moment($scope.formattedEndDate).isValid() - return "cancel" unless $scope.confirmRefresh() $scope.loadOrders() @@ -51,33 +52,24 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $scope.dereferenceLoadedData() - $scope.setOrderCycleDateRange = -> - start_date = OrderCycles.byID[$scope.orderCycleFilter].orders_open_at - end_date = OrderCycles.byID[$scope.orderCycleFilter].orders_close_at - format = "YYYY-MM-DD HH:mm:ss Z" - $scope.startDate = moment(start_date, format).format('YYYY-MM-DD') - $scope.endDate = moment(end_date, format).startOf('day').format('YYYY-MM-DD') - # throw a flatpickr:change event to change the date back in the datepicker - event = new CustomEvent('flatpickr:change', { - detail: { - startDate: $scope.startDate, - endDate: $scope.endDate - } - }) - window.dispatchEvent(event) - $scope.loadOrders = -> + [formattedStartDate, formattedEndDate] = $scope.formatDates($scope.startDate, $scope.endDate) + RequestMonitor.load $scope.orders = Orders.index( "q[state_not_eq]": "canceled", "q[shipment_state_not_eq]": "shipped", "q[completed_at_not_null]": "true", "q[distributor_id_eq]": $scope.distributorFilter, "q[order_cycle_id_eq]": $scope.orderCycleFilter, - "q[completed_at_gteq]": $scope.formattedStartDate, - "q[completed_at_lt]": $scope.formattedEndDate + "q[completed_at_gteq]": if formattedStartDate then formattedStartDate else undefined, + "q[completed_at_lt]": if formattedEndDate then formattedEndDate else undefined, + "page": $scope.page, + "per_page": $scope.per_page ) $scope.loadLineItems = -> + [formattedStartDate, formattedEndDate] = $scope.formatDates($scope.startDate, $scope.endDate) + RequestMonitor.load LineItems.index( "q[order_state_not_eq]": "canceled", "q[order_shipment_state_not_eq]": "shipped", @@ -85,10 +77,17 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, "q[order_distributor_id_eq]": $scope.distributorFilter, "q[variant_product_supplier_id_eq]": $scope.supplierFilter, "q[order_order_cycle_id_eq]": $scope.orderCycleFilter, - "q[order_completed_at_gteq]": $scope.formattedStartDate, - "q[order_completed_at_lt]": $scope.formattedEndDate + "q[order_completed_at_gteq]": if formattedStartDate then formattedStartDate else undefined, + "q[order_completed_at_lt]": if formattedEndDate then formattedEndDate else undefined, + "page": $scope.page, + "per_page": $scope.per_page ) + $scope.formatDates = (startDate, endDate) -> + formattedStartDate = moment(startDate).format('YYYY-MM-DD') if startDate + formattedEndDate = moment(endDate).add(1,'day').format('YYYY-MM-DD') if endDate + return [formattedStartDate, formattedEndDate] + $scope.loadAssociatedData = -> RequestMonitor.load $scope.distributors = Enterprises.index(action: "visible", ams_prefix: "basic", "q[sells_in][]": ["own", "any"]) RequestMonitor.load $scope.orderCycles = OrderCycles.index(ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{moment().subtract(90,'days').format()}") @@ -263,4 +262,8 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, lineItem.final_weight_volume = LineItems.pristineByID[lineItem.id].final_weight_volume * lineItem.quantity / LineItems.pristineByID[lineItem.id].quantity $scope.weightAdjustedPrice(lineItem) + $scope.changePage = (newPage) -> + $scope.page = newPage + $scope.refreshData() + $scope.resetSelectFilters() diff --git a/app/views/spree/admin/orders/_per_page_controls.html.haml b/app/views/admin/shared/_angular_per_page_controls.html.haml similarity index 100% rename from app/views/spree/admin/orders/_per_page_controls.html.haml rename to app/views/admin/shared/_angular_per_page_controls.html.haml diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index afbfdfc284..f00cc8af93 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -32,7 +32,7 @@ %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', change: "setOrderCycleDateRange()" } } + %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"} %label = t("date_range") @@ -94,14 +94,20 @@ = t("admin.orders.bulk_management.variants_without_unit_value") %hr.divider.sixteen.columns.alpha.omega + .clear - .controls.sixteen.columns.alpha.omega{ ng: { hide: 'RequestMonitor.loading || line_items.length == 0' } } - %div.three.columns.alpha + %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' } - %div.three.columns + -# This -20px is a hack to make the dropdowns align properly + %div{ style: "margin-right: -20px;" } = render 'admin/shared/bulk_actions_dropdown' - %div.ten.columns + %div %columns-dropdown{ action: "#{controller_name}_#{action_name}" } + %div{ style: "flex-grow: 1"} + %div{ style: "float: right;"} + = render partial: 'admin/shared/angular_per_page_controls', locals: { position: "right" } + %div.sixteen.columns.alpha#loading{ 'ng-if' => 'RequestMonitor.loading' } = render partial: "components/admin_spinner" @@ -184,4 +190,7 @@ %td.actions %a{ 'ng-click' => "deleteLineItem(line_item)", :class => "delete-line-item icon-trash no-text" } + %div{'ng-show' => "!RequestMonitor.loading && orders.length > 0" } + = render partial: 'admin/shared/angular_pagination' + = render 'spree/admin/shared/custom-confirm' diff --git a/app/views/spree/admin/orders/index.html.haml b/app/views/spree/admin/orders/index.html.haml index 4326c2065e..d744498fd8 100644 --- a/app/views/spree/admin/orders/index.html.haml +++ b/app/views/spree/admin/orders/index.html.haml @@ -40,7 +40,7 @@ %span.name{'ng-controller' => 'bulkCancelCtrl', 'ng-click' => 'cancelSelectedOrders()' } = t('.cancel_orders') - = render partial: 'per_page_controls', locals: { position: "right" } + = render partial: 'admin/shared/angular_per_page_controls', locals: { position: "right" } %table#listing_orders.index.responsive{width: "100%", 'ng-init' => 'initialise()', 'ng-show' => "!RequestMonitor.loading && orders.length > 0" } %colgroup diff --git a/app/webpacker/controllers/flatpickr_controller.js b/app/webpacker/controllers/flatpickr_controller.js index a588c25e68..c9294b0f1f 100644 --- a/app/webpacker/controllers/flatpickr_controller.js +++ b/app/webpacker/controllers/flatpickr_controller.js @@ -55,6 +55,7 @@ export default class extends Flatpickr { mode, }; window.addEventListener("flatpickr:change", this.onChangeEvent.bind(this)); + window.addEventListener("flatpickr:clear", this.clear.bind(this)); } clear(e) { diff --git a/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee b/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee index 9d496f6c26..74bbedb100 100644 --- a/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/line_items/controllers/line_items_controller_spec.js.coffee @@ -49,7 +49,7 @@ describe "LineItemsCtrl", -> return Promise.resolve() allSaved: jasmine.createSpy('allSaved').and.returnValue(true) - httpBackend.expectGET("/api/v0/orders.json?q%5Bcompleted_at_gteq%5D=SomeDate&q%5Bcompleted_at_lt%5D=SomeDate&q%5Bcompleted_at_not_null%5D=true&q%5Bdistributor_id_eq%5D=&q%5Border_cycle_id_eq%5D=&q%5Bshipment_state_not_eq%5D=shipped&q%5Bstate_not_eq%5D=canceled").respond {orders: [order], pagination: {page: 1, pages: 1, results: 1}} + httpBackend.expectGET("/api/v0/orders.json?page=1&per_page=15&q%5Bcompleted_at_not_null%5D=true&q%5Bdistributor_id_eq%5D=&q%5Border_cycle_id_eq%5D=&q%5Bshipment_state_not_eq%5D=shipped&q%5Bstate_not_eq%5D=canceled").respond {orders: [order], pagination: {page: 1, pages: 1, results: 1}} httpBackend.expectGET("/admin/enterprises/visible.json?ams_prefix=basic&q%5Bsells_in%5D%5B%5D=own&q%5Bsells_in%5D%5B%5D=any").respond [distributor] httpBackend.expectGET("/admin/order_cycles.json?ams_prefix=basic&as=distributor&q%5Borders_close_at_gt%5D=SomeDate").respond [orderCycle] httpBackend.expectGET("/admin/enterprises/visible.json?ams_prefix=basic&q%5Bis_primary_producer_eq%5D=true").respond [supplier] diff --git a/spec/system/admin/bulk_order_management_spec.rb b/spec/system/admin/bulk_order_management_spec.rb index 3893561e75..04fb1b7da8 100644 --- a/spec/system/admin/bulk_order_management_spec.rb +++ b/spec/system/admin/bulk_order_management_spec.rb @@ -466,38 +466,6 @@ describe ' page.find('.filter-actions .button.icon-search').click displays_default_orders end - - it "selecting an OC pre-selects the date range from that OC" do - displays_default_orders - click_on_select2 oc3.name, from: "order_cycle_filter" - expect(find("input.datepicker").value).to eq "#{oc3.orders_open_at.strftime('%F')} to #{oc3.orders_close_at.strftime('%F')}" - displays_default_orders - click_on_select2 oc1.name, from: "order_cycle_filter" - displays_default_orders - expect(find("input.datepicker").value).to eq "#{oc1.orders_open_at.strftime('%F')} to #{oc1.orders_close_at.strftime('%F')}" - # only filters results after clicking the 'Filter Results' button - displays_default_orders - page.find('.filter-actions .button.icon-search').click - expect(page).to have_selector "tr#li_#{li1.id}" - expect(page).to_not have_selector "tr#li_#{li2.id}" - # only filters results after clicking the 'Clear Filters' button resets to display the default results - page.find("#clear_filters_button").click - displays_default_orders - end - - xit "allows combining the order cycle and the pre-selected date with a custom date" do - # pending (#10192) - click_on_select2 oc3.name, from: "order_cycle_filter" - expect(find("input.datepicker").value).to eq "#{oc3.orders_open_at.strftime('%F')} to #{oc3.orders_close_at.strftime('%F')}" - page.find('.filter-actions .button.icon-search').click - expect(page).to have_selector "tr#li_#{li3.id}" - expect(page).to have_selector "tr#li_#{li4.id}" - find("input.datepicker").click # selecting a date range, within oc3 - select_dates_from_daterangepicker(o4.completed_at - 1.day, o4.completed_at + 1.day) - page.find('.filter-actions .button.icon-search').click - expect(page).to have_selector "tr#li_#{li4.id}" - expect(page).to_not have_selector "tr#li_#{li3.id}" - end end context "combination of filters" do @@ -625,17 +593,11 @@ describe ' visit_bulk_order_management end - it "displays date fields for filtering orders, with default values set" do - # use Date.current since Date.today is without timezone - one_week_ago = today.prev_day(7).strftime("%F") - expect(find("input.datepicker").value).to eq "#{one_week_ago} to #{today.strftime('%F')}" - end - - it "only loads line items whose orders meet the date restriction criteria", retry: 3 do - expect(page).to have_no_selector "tr#li_#{li1.id}" + it "loads all line items because no date restriction on first load" 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}" - expect(page).to have_no_selector "tr#li_#{li4.id}" + expect(page).to have_selector "tr#li_#{li4.id}" end it "displays only line items whose orders meet the date restriction criteria, when changed", retry: 3 do diff --git a/vendor/assets/stylesheets/select2.css.scss b/vendor/assets/stylesheets/select2.css.scss index ea1e45eb5f..1f8fd014bc 100644 --- a/vendor/assets/stylesheets/select2.css.scss +++ b/vendor/assets/stylesheets/select2.css.scss @@ -605,7 +605,6 @@ disabled look for disabled choices in the results dropdown @media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi) { .select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice .select2-arrow b { - background-image: url('../images/select2x2.png') !important; background-repeat: no-repeat !important; background-size: 60px 40px !important; }