mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Merge pull request #9526 from jibees/6730-use-a-date-range-picker
Admin, List of Orders & Orders Bulk Management pages: use a date range picker
This commit is contained in:
@@ -22,24 +22,6 @@
|
||||
//= require angular-rails-templates
|
||||
//= require lodash.underscore.js
|
||||
|
||||
// datetimepicker (fil, nb)
|
||||
//= require flatpickr/dist/flatpickr.min
|
||||
//= require flatpickr/dist/l10n/ar
|
||||
//= require flatpickr/dist/l10n/cat
|
||||
//= require flatpickr/dist/l10n/cy
|
||||
//= require flatpickr/dist/l10n/de
|
||||
//= require flatpickr/dist/l10n/es
|
||||
//= require flatpickr/dist/l10n/fr
|
||||
//= require flatpickr/dist/l10n/it
|
||||
//= require flatpickr/dist/l10n/nl
|
||||
//= require flatpickr/dist/l10n/pl
|
||||
//= require flatpickr/dist/l10n/pt
|
||||
//= require flatpickr/dist/l10n/ru
|
||||
//= require flatpickr/dist/l10n/sv
|
||||
//= require flatpickr/dist/l10n/tr
|
||||
//= require shortcut-buttons-flatpickr/dist/shortcut-buttons-flatpickr.min
|
||||
//= require flatpickr/dist/plugins/labelPlugin/labelPlugin
|
||||
|
||||
// spree
|
||||
//= require admin/spree/spree
|
||||
//= require admin/spree/spree-select2
|
||||
|
||||
@@ -25,6 +25,10 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
$scope.resetFilters()
|
||||
$scope.refreshData()
|
||||
|
||||
$scope.$watchCollection "[startDate, endDate]", (newValues, oldValues) ->
|
||||
if newValues != oldValues
|
||||
$scope.refreshData()
|
||||
|
||||
$scope.refreshData = ->
|
||||
unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == ''
|
||||
$scope.setOrderCycleDateRange()
|
||||
|
||||
@@ -1,21 +1,4 @@
|
||||
angular.module('admin.orderCycles', ['ngTagsInput', 'admin.indexUtils', 'admin.enterprises'])
|
||||
.directive 'datetimepicker', ($timeout, $parse) ->
|
||||
require: "ngModel"
|
||||
link: (scope, element, attrs, ngModel) ->
|
||||
$timeout ->
|
||||
fp = flatpickr(element, Object.assign({},
|
||||
window.FLATPICKR_DATETIME_DEFAULT, {
|
||||
onOpen: (selectedDates, dateStr, instance) ->
|
||||
instance.setDate(ngModel.$modelValue)
|
||||
instance.input.dispatchEvent(new Event('focus', { bubbles: true }));
|
||||
}));
|
||||
fp.minuteElement.addEventListener "keyup", (e) ->
|
||||
if !isNaN(event.target.value)
|
||||
fp.setDate(fp.selectedDates[0].setMinutes(e.target.value), true)
|
||||
fp.hourElement.addEventListener "keyup", (e) ->
|
||||
if !isNaN(event.target.value)
|
||||
fp.setDate(fp.selectedDates[0].setHours(e.target.value), true)
|
||||
|
||||
.directive 'ofnOnChange', ->
|
||||
(scope, element, attrs) ->
|
||||
element.bind 'change', ->
|
||||
|
||||
@@ -29,6 +29,8 @@ angular.module("admin.orders").controller "ordersCtrl", ($scope, $timeout, Reque
|
||||
$scope.q = {
|
||||
completed_at_not_null: true
|
||||
}
|
||||
e = new CustomEvent("flatpickr_clear");
|
||||
window.dispatchEvent(e)
|
||||
|
||||
$scope.clearFilters = () ->
|
||||
KeyValueMapStore.clearKeyValueMap()
|
||||
|
||||
@@ -1,70 +1,4 @@
|
||||
$(document).ready(function() {
|
||||
var onClickButtons = function(index, fp) {
|
||||
var date;
|
||||
// Memorize index used for the 'Close' button
|
||||
// (currently it has index of 1)
|
||||
var closeButtonIndex = 1;
|
||||
switch (index) {
|
||||
case 0:
|
||||
date = new Date();
|
||||
break;
|
||||
case closeButtonIndex:
|
||||
fp.close();
|
||||
break;
|
||||
}
|
||||
// Set the date unless clicked button was the 'Close' one
|
||||
if (index != closeButtonIndex) {
|
||||
fp.setDate(date, true);
|
||||
}
|
||||
}
|
||||
window.FLATPICKR_DATE_DEFAULT = {
|
||||
altInput: true,
|
||||
altFormat: Spree.translations.flatpickr_date_format,
|
||||
dateFormat: "Y-m-d",
|
||||
locale: I18n.base_locale,
|
||||
plugins: [
|
||||
ShortcutButtonsPlugin({
|
||||
button: [
|
||||
{
|
||||
label: Spree.translations.today
|
||||
},
|
||||
{
|
||||
label: Spree.translations.close
|
||||
}
|
||||
],
|
||||
label: "or",
|
||||
onClick: onClickButtons
|
||||
}),
|
||||
labelPlugin({})
|
||||
]
|
||||
}
|
||||
window.FLATPICKR_DATETIME_DEFAULT = Object.assign(
|
||||
{},
|
||||
window.FLATPICKR_DATE_DEFAULT,
|
||||
{
|
||||
altInput: true,
|
||||
altFormat: Spree.translations.flatpickr_datetime_format,
|
||||
dateFormat: "Y-m-d H:i",
|
||||
enableTime: true,
|
||||
time_24hr: true,
|
||||
plugins: [
|
||||
ShortcutButtonsPlugin({
|
||||
button: [
|
||||
{
|
||||
label: Spree.translations.now
|
||||
},
|
||||
{
|
||||
label: Spree.translations.close
|
||||
}
|
||||
],
|
||||
label: "or",
|
||||
onClick: onClickButtons
|
||||
}),
|
||||
labelPlugin({})
|
||||
]
|
||||
}
|
||||
);
|
||||
flatpickr(".datetimepicker", window.FLATPICKR_DATETIME_DEFAULT);
|
||||
$('a.close').click(function(event){
|
||||
event.preventDefault();
|
||||
$(this).parent().slideUp(250);
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
angular.module("admin.utils").directive "datepicker", ($window, $timeout) ->
|
||||
require: "ngModel"
|
||||
link: (scope, element, attrs, ngModel) ->
|
||||
$timeout ->
|
||||
flapickrInstance = flatpickr(element, Object.assign(
|
||||
{},
|
||||
$window.FLATPICKR_DATE_DEFAULT, {
|
||||
onOpen: (selectedDates, dateStr, instance) ->
|
||||
instance.setDate(ngModel.$modelValue)
|
||||
}
|
||||
));
|
||||
ngModel.$render = () ->
|
||||
newValue = ngModel.$viewValue;
|
||||
flapickrInstance?.setDate(newValue)
|
||||
@@ -11,7 +11,7 @@
|
||||
= f.label :orders_open_at, t('.orders_open')
|
||||
.omega.six.columns.fullwidth_inputs
|
||||
- if viewing_as_coordinator_of?(@order_cycle)
|
||||
= f.text_field :orders_open_at, 'datetimepicker' => 'order_cycle.orders_open_at', 'ng-model' => 'order_cycle.orders_open_at', 'ng-if' => 'loaded()', 'change-warning' => 'order_cycle', class: "datetimepicker"
|
||||
= f.text_field :orders_open_at, data: { controller: "flatpickr", "flatpickr-enable-time-value": true }, 'ng-model' => 'order_cycle.orders_open_at', 'ng-if' => 'loaded()', 'change-warning' => 'order_cycle', class: "datetimepicker"
|
||||
- else
|
||||
{{ order_cycle.orders_open_at }}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
= f.label :orders_close, t('.orders_close')
|
||||
.six.columns.omega.fullwidth_inputs
|
||||
- if viewing_as_coordinator_of?(@order_cycle)
|
||||
= f.text_field :orders_close_at, 'datetimepicker' => 'order_cycle.orders_close_at', 'ng-model' => 'order_cycle.orders_close_at', 'ng-if' => 'loaded()', 'change-warning' => 'order_cycle', class: "datetimepicker"
|
||||
= f.text_field :orders_close_at, data: { controller: "flatpickr", "flatpickr-enable-time-value": true }, 'ng-model' => 'order_cycle.orders_close_at', 'ng-if' => 'loaded()', 'change-warning' => 'order_cycle', class: "datetimepicker"
|
||||
- else
|
||||
{{ order_cycle.orders_close_at }}
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
{{ schedule.name + ($last ? '' : ',') }}
|
||||
%span{ ng: { show: 'orderCycle.schedules.length == 0'}} None
|
||||
%td.orders_open_at{ ng: { show: 'columns.open.visible' } }
|
||||
%input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_open_at', name: 'oc{{::orderCycle.id}}[orders_open_at]', type: 'text', ng: { if: 'orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_open_at' }, datetimepicker: 'orderCycle.orders_open_at', 'change-warning' => 'orderCycle' }
|
||||
%input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_open_at', name: 'oc{{::orderCycle.id}}[orders_open_at]', type: 'text', ng: { if: 'orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_open_at' }, data: { controller: "flatpickr", "flatpickr-enable-time-value": true }, 'change-warning' => 'orderCycle' }
|
||||
%input{ id: 'oc{{::orderCycle.id}}_orders_open_at', name: 'oc{{::orderCycle.id}}[orders_open_at]', type: 'text', ng: { if: '!orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_open_at'}, disabled: true }
|
||||
%td.orders_close_at{ ng: { show: 'columns.close.visible' } }
|
||||
%input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_close_at', name: 'oc{{::orderCycle.id}}[orders_close_at]', type: 'text', ng: { if: 'orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_close_at' }, datetimepicker: 'orderCycle.orders_close_at', 'change-warning' => 'orderCycle' }
|
||||
%input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_close_at', name: 'oc{{::orderCycle.id}}[orders_close_at]', type: 'text', ng: { if: 'orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_close_at' }, data: { controller: "flatpickr", "flatpickr-enable-time-value": true }, 'change-warning' => 'orderCycle' }
|
||||
%input{ id: 'oc{{::orderCycle.id}}_orders_close_at', name: 'oc{{::orderCycle.id}}[orders_close_at]', type: 'text', ng: { if: '!orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_close_at'}, disabled: true }
|
||||
|
||||
- unless simple_index
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
.row.date-range-filter
|
||||
.alpha.two.columns= label_tag nil, t(:date_range)
|
||||
.omega.fourteen.columns
|
||||
= f.text_field "#{field}_gt", :class => 'datetimepicker datepicker-from', :placeholder => t(:start)
|
||||
= f.text_field "#{field}_gt", :class => 'datetimepicker datepicker-from', :placeholder => t(:start), data: { controller: "flatpickr", "flatpickr-enable-time-value": true }
|
||||
%span.range-divider
|
||||
%i.icon-arrow-right
|
||||
= f.text_field "#{field}_lt", :class => 'datetimepicker datepicker-to', :placeholder => t(:stop)
|
||||
= f.text_field "#{field}_lt", :class => 'datetimepicker datepicker-to', :placeholder => t(:stop), data: { controller: "flatpickr", "flatpickr-enable-time-value": true }
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
.fourteen.columns.omega= number_field_tag :initial_invoice_number, params[:initial_invoice_number]
|
||||
.row
|
||||
.two.columns.alpha= label_tag :invoice_date, t(:invoice_date)
|
||||
.fourteen.columns.omega= text_field_tag :invoice_date, params[:invoice_date], class: 'datetimepicker'
|
||||
.fourteen.columns.omega= text_field_tag :invoice_date, params[:invoice_date], class: 'datetimepicker', data: { controller: "flatpickr", "flatpickr-enable-time-value": true }
|
||||
.row
|
||||
.two.columns.alpha= label_tag :due_date, t(:due_date)
|
||||
.fourteen.columns.omega= text_field_tag :due_date, params[:due_date], class: 'datetimepicker'
|
||||
.fourteen.columns.omega= text_field_tag :due_date, params[:due_date], class: 'datetimepicker', data: { controller: "flatpickr", "flatpickr-enable-time-value": true }
|
||||
.row
|
||||
.two.columns.alpha= label_tag :account_code, t(:account_code)
|
||||
.fourteen.columns.omega= text_field_tag :account_code, params[:account_code]
|
||||
|
||||
@@ -34,11 +34,11 @@
|
||||
.row
|
||||
.seven.columns.alpha.field
|
||||
%label{ for: 'begins_at'}= t('admin.begins_at')
|
||||
%input.fullwidth#begins_at{ name: 'begins_at', type: 'text', placeholder: "#{t('.begins_at_placeholder')}", datepicker: 'subscription.begins_at', required: true, ng: { model: 'subscription.begins_at' } }
|
||||
%input.fullwidth#begins_at{ name: 'begins_at', type: 'text', placeholder: "#{t('.begins_at_placeholder')}", data: { controller: "flatpickr" }, required: true, ng: { model: 'subscription.begins_at' } }
|
||||
.error{ ng: { show: 'subscription_form.$submitted && subscription_details_form.begins_at.$error.required' } }= t(:error_required)
|
||||
.error{ ng: { repeat: 'error in errors.begins_at', show: 'subscription_details_form.begins_at.$pristine' } } {{ error }}
|
||||
.two.columns
|
||||
.seven.columns.omega.field
|
||||
%label{ for: 'ends_at'}= t('admin.ends_at')
|
||||
%input.fullwidth#ends_at{ name: 'ends_at', type: 'text', placeholder: "#{t('.ends_at_placeholder')}", datepicker: 'subscription.begins_at', ng: { model: 'subscription.ends_at' } }
|
||||
%input.fullwidth#ends_at{ name: 'ends_at', type: 'text', placeholder: "#{t('.ends_at_placeholder')}", data: { controller: "flatpickr" }, ng: { model: 'subscription.ends_at' } }
|
||||
.error{ ng: { repeat: 'error in errors.ends_at', show: 'subscription_details_form.ends_at.$pristine' } } {{ error }}
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
.field-block.alpha.four.columns
|
||||
.date-range-filter.field
|
||||
= label_tag nil, t(:date_range)
|
||||
.date-range-fields
|
||||
= text_field_tag "q[completed_at_gteq]", nil, class: 'datepicker', datepicker: 'q.completed_at_gteq', 'ng-model' => 'q.completed_at_gteq', :placeholder => t(:start)
|
||||
%span.range-divider
|
||||
%i.icon-arrow-right
|
||||
= text_field_tag "q[completed_at_lteq]", nil, class: 'datepicker', datepicker: 'q.completed_at_lteq', 'ng-model' => 'q.completed_at_lteq', :placeholder => t(:stop)
|
||||
.date-range-fields{ data: { controller: "flatpickr", "flatpickr-mode-value": "range", "flatpickr-default-date": "{{ [q.completed_at_gteq, q.completed_at_lteq] }}" } }
|
||||
= text_field_tag nil, nil, class: "datepicker", data: { "flatpickr-target": "instance", action: "flatpickr_clear@window->flatpickr#clear" }
|
||||
= text_field_tag "q[completed_at_gteq]", nil, "ng-model": "q.completed_at_gteq", data: { "flatpickr-target": "start" }, style: "display: none"
|
||||
= text_field_tag "q[completed_at_lteq]", nil, "ng-model": "q.completed_at_lteq", data: { "flatpickr-target": "end" }, style: "display: none"
|
||||
.field
|
||||
= label_tag nil, t(:status)
|
||||
%select2-watch-ng-model{'ng-model': 'q.state_eq'}
|
||||
|
||||
@@ -17,16 +17,14 @@
|
||||
%input.red{ type: "button", value: "Save Changes", ng: { click: "submit()", disabled: "!bulk_order_form.$dirty" } }
|
||||
|
||||
.filters{ :class => "sixteen columns alpha" }
|
||||
.date_filter{ :class => "two columns alpha" }
|
||||
%label{ :for => 'start_date_filter' }
|
||||
= t("admin.start_date")
|
||||
.date_filter{class: "four columns"}
|
||||
%label
|
||||
= t("date_range")
|
||||
%br
|
||||
%input.fullwidth.datepicker{ :type => "text", :id => 'start_date_filter', 'ng-model' => 'startDate', 'datepicker' => "startDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()', 'ng-model-options' => '{ debounce: 1000 }' }
|
||||
.date_filter{ :class => "two columns" }
|
||||
%label{ :for => 'end_date_filter' }
|
||||
= t("admin.end_date")
|
||||
%br
|
||||
%input.fullwidth.datepicker{ :type => "text", :id => 'end_date_filter', 'ng-model' => 'endDate', 'datepicker' => "endDate", 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()', 'ng-model-options' => '{ debounce: 1000 }' }
|
||||
%div{ data: { controller: "flatpickr", "flatpickr-mode-value": "range", "flatpickr-default-date": "{{ [startDate, endDate] }}" } }
|
||||
%input.datepicker.fullwidth{ class: "datepicker", data: { "flatpickr-target": "instance" } }
|
||||
%input{ type: "text", id: 'start_date_filter', 'ng-model': "startDate", data: { "flatpickr-target": "start" }, style: "display: none;", "confirm-change": "confirmRefresh()" }
|
||||
%input{ type: "text", id: 'end_date_filter', 'ng-model': "endDate", data: { "flatpickr-target": "end" }, style: "display: none;", "confirm-change": "confirmRefresh()"}
|
||||
.one.column
|
||||
.filter_select{ :class => "three columns" }
|
||||
%label{ :for => 'supplier_filter' }
|
||||
|
||||
121
app/webpacker/controllers/flatpickr_controller.js
Normal file
121
app/webpacker/controllers/flatpickr_controller.js
Normal file
@@ -0,0 +1,121 @@
|
||||
// import Flatpickr
|
||||
import Flatpickr from "stimulus-flatpickr";
|
||||
import { ar } from "flatpickr/dist/l10n/ar";
|
||||
import { cat } from "flatpickr/dist/l10n/cat";
|
||||
import { cy } from "flatpickr/dist/l10n/cy";
|
||||
import { de } from "flatpickr/dist/l10n/de";
|
||||
import { fr } from "flatpickr/dist/l10n/fr";
|
||||
import { it } from "flatpickr/dist/l10n/it";
|
||||
import { nl } from "flatpickr/dist/l10n/nl";
|
||||
import { pl } from "flatpickr/dist/l10n/pl";
|
||||
import { pt } from "flatpickr/dist/l10n/pt";
|
||||
import { ru } from "flatpickr/dist/l10n/ru";
|
||||
import { sv } from "flatpickr/dist/l10n/sv";
|
||||
import { tr } from "flatpickr/dist/l10n/tr";
|
||||
import { en } from "flatpickr/dist/l10n/default.js";
|
||||
import ShortcutButtonsPlugin from "shortcut-buttons-flatpickr";
|
||||
import labelPlugin from "flatpickr/dist/plugins/labelPlugin/labelPlugin";
|
||||
|
||||
export default class extends Flatpickr {
|
||||
static values = { enableTime: Boolean, mode: String };
|
||||
static targets = ["start", "end"];
|
||||
locales = {
|
||||
ar: ar,
|
||||
cat: cat,
|
||||
cy: cy,
|
||||
de: de,
|
||||
fr: fr,
|
||||
it: it,
|
||||
nl: nl,
|
||||
pl: pl,
|
||||
pt: pt,
|
||||
ru: ru,
|
||||
sv: sv,
|
||||
tr: tr,
|
||||
en: en,
|
||||
};
|
||||
|
||||
initialize() {
|
||||
const datetimepicker = this.enableTimeValue == true;
|
||||
const mode = this.modeValue == "range" ? "range" : "single";
|
||||
// sets your language (you can also set some global setting for all time pickers)
|
||||
this.config = {
|
||||
altInput: true,
|
||||
altFormat: datetimepicker
|
||||
? Spree.translations.flatpickr_datetime_format
|
||||
: Spree.translations.flatpickr_date_format,
|
||||
dateFormat: datetimepicker ? "Y-m-d H:i" : "Y-m-d",
|
||||
enableTime: datetimepicker,
|
||||
time_24hr: datetimepicker,
|
||||
locale: I18n.base_locale,
|
||||
plugins: this.plugins(mode, datetimepicker),
|
||||
mode,
|
||||
};
|
||||
}
|
||||
|
||||
clear(e) {
|
||||
this.fp.setDate(null);
|
||||
}
|
||||
|
||||
open() {
|
||||
this.fp.element.dispatchEvent(new Event("focus"));
|
||||
}
|
||||
|
||||
change(selectedDates, dateStr, instance) {
|
||||
if (this.hasStartTarget && this.hasEndTarget && this.modeValue == "range") {
|
||||
this.startTarget.value = selectedDates[0]
|
||||
? this.fp.formatDate(selectedDates[0], this.config.dateFormat)
|
||||
: "";
|
||||
this.endTarget.value = selectedDates[1]
|
||||
? this.fp.formatDate(selectedDates[1], this.config.dateFormat)
|
||||
: "";
|
||||
// Also, send event to be sure that ng-model is well updated
|
||||
// Send event only if range il valid, ie. start and end are not empty
|
||||
if (this.startTarget.value && this.endTarget.value) {
|
||||
this.startTarget.dispatchEvent(new Event("change"));
|
||||
this.endTarget.dispatchEvent(new Event("change"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
// Send a change event to the input element to trigger the ng-change
|
||||
this.hasEndTarget && this.endTarget.dispatchEvent(new Event("change"));
|
||||
}
|
||||
|
||||
// private
|
||||
|
||||
plugins = (mode, datetimepicker) => {
|
||||
const buttons = [{ label: Spree.translations.close }];
|
||||
if (mode == "single") {
|
||||
buttons.unshift({
|
||||
label: datetimepicker
|
||||
? Spree.translations.now
|
||||
: Spree.translations.today,
|
||||
});
|
||||
}
|
||||
return [
|
||||
ShortcutButtonsPlugin({
|
||||
button: buttons,
|
||||
onClick: this.onClickButtons,
|
||||
}),
|
||||
labelPlugin({}),
|
||||
];
|
||||
};
|
||||
|
||||
onClickButtons = (index, fp) => {
|
||||
// Memorize index used for the 'Close' and 'Today|Now' buttons
|
||||
// it has index of 1 in case of single mode (ie. can set Today or Now date)
|
||||
// it has index of 0 in case of range mode (no Today or Now button)
|
||||
const closeButtonIndex = this.modeValue == "range" ? 0 : 1;
|
||||
const todayButtonIndex = this.modeValue == "range" ? null : 0;
|
||||
switch (index) {
|
||||
case todayButtonIndex:
|
||||
fp.setDate(new Date(), true);
|
||||
break;
|
||||
case closeButtonIndex:
|
||||
fp.close();
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,15 +1,5 @@
|
||||
// scss-lint:disable QualifyingElement
|
||||
|
||||
.date-range-filter {
|
||||
.range-divider {
|
||||
padding: 0;
|
||||
margin-left: 5px;
|
||||
}
|
||||
input.datepicker {
|
||||
width: 96px !important;
|
||||
}
|
||||
}
|
||||
|
||||
input.datetimepicker {
|
||||
min-width: 12.9em;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
"select2": "^4.0.13",
|
||||
"shortcut-buttons-flatpickr": "^0.4.0",
|
||||
"stimulus": "^3.0.1",
|
||||
"stimulus-flatpickr": "^1.4.0",
|
||||
"tom-select": "^2.0.0",
|
||||
"webpack": "~4",
|
||||
"webpack-cli": "~3"
|
||||
|
||||
@@ -8,8 +8,15 @@ module Features
|
||||
end
|
||||
end
|
||||
|
||||
def select_date_from_datepicker(date)
|
||||
navigate_datepicker_to_month date
|
||||
def select_dates_from_daterangepicker(from, to)
|
||||
# Once the datepicker is open,
|
||||
# it simply consist to select the 'from' date and then the 'to' date
|
||||
select_date_from_datepicker(from)
|
||||
select_date_from_datepicker(to, from)
|
||||
end
|
||||
|
||||
def select_date_from_datepicker(date, reference_date = Time.zone.today)
|
||||
navigate_datepicker_to_month(date, reference_date)
|
||||
find('.flatpickr-calendar.open .flatpickr-days .flatpickr-day:not(.prevMonthDay)',
|
||||
text: date.strftime("%e").to_s.strip, exact_text: true, match: :first).click
|
||||
end
|
||||
@@ -22,7 +29,7 @@ module Features
|
||||
find(".flatpickr-calendar.open .flatpickr-minute").set datetime.strftime("%M").to_s.strip
|
||||
end
|
||||
|
||||
def navigate_datepicker_to_month(date, reference_date = Time.zone.today)
|
||||
def navigate_datepicker_to_month(date, reference_date)
|
||||
month_and_year = date.strftime("%-m %Y")
|
||||
|
||||
until datepicker_month_and_year == month_and_year.upcase
|
||||
|
||||
@@ -534,7 +534,7 @@ describe '
|
||||
}
|
||||
let!(:o2) {
|
||||
create(:order_with_distributor, state: 'complete', shipment_state: 'ready',
|
||||
completed_at: Time.zone.today - 7.days)
|
||||
completed_at: Time.zone.today - 6.days)
|
||||
}
|
||||
let!(:o3) {
|
||||
create(:order_with_distributor, state: 'complete', shipment_state: 'ready',
|
||||
@@ -542,12 +542,13 @@ describe '
|
||||
}
|
||||
let!(:o4) {
|
||||
create(:order_with_distributor, state: 'complete', shipment_state: 'ready',
|
||||
completed_at: Time.zone.now.end_of_day + 1.second)
|
||||
completed_at: Time.zone.now.end_of_day + 1.day)
|
||||
}
|
||||
let!(:li1) { create(:line_item_with_shipment, order: o1, quantity: 1 ) }
|
||||
let!(:li2) { create(:line_item_with_shipment, order: o2, quantity: 2 ) }
|
||||
let!(:li3) { create(:line_item_with_shipment, order: o3, quantity: 3 ) }
|
||||
let!(:li4) { create(:line_item_with_shipment, order: o4, quantity: 4 ) }
|
||||
let(:today) { Time.zone.today }
|
||||
|
||||
before :each do
|
||||
visit_bulk_order_management
|
||||
@@ -555,10 +556,8 @@ describe '
|
||||
|
||||
it "displays date fields for filtering orders, with default values set" do
|
||||
# use Date.current since Date.today is without timezone
|
||||
today = Time.zone.today
|
||||
one_week_ago = today.prev_day(7).strftime("%F")
|
||||
expect(page).to have_field "start_date_filter", with: one_week_ago
|
||||
expect(page).to have_field "end_date_filter", with: today.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" do
|
||||
@@ -569,16 +568,20 @@ describe '
|
||||
end
|
||||
|
||||
it "displays only line items whose orders meet the date restriction criteria, when changed" do
|
||||
find('#start_date_filter').click
|
||||
select_date_from_datepicker Time.zone.today - 8.days
|
||||
from = today - 8.days
|
||||
to = today + 1.day
|
||||
|
||||
find("input.datepicker").click
|
||||
select_dates_from_daterangepicker(from, today)
|
||||
expect(page).to have_text 'Loading orders'
|
||||
|
||||
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}"
|
||||
|
||||
find('#end_date_filter').click
|
||||
select_date_from_datepicker Time.zone.today + 1.day
|
||||
find("input.datepicker").click
|
||||
select_dates_from_daterangepicker(from, to)
|
||||
|
||||
expect(page).to have_selector "tr#li_#{li1.id}"
|
||||
expect(page).to have_selector "tr#li_#{li2.id}"
|
||||
@@ -596,8 +599,8 @@ describe '
|
||||
it "shows a dialog and ignores changes when confirm dialog is accepted" do
|
||||
page.driver.accept_modal :confirm,
|
||||
text: "Unsaved changes exist and will be lost if you continue." do
|
||||
find('#start_date_filter').click
|
||||
select_date_from_datepicker Time.zone.today - 9.days
|
||||
find("input.datepicker").click
|
||||
select_dates_from_daterangepicker(today - 9.days, today)
|
||||
end
|
||||
expect(page).to have_no_selector "#save-bar"
|
||||
within("tr#li_#{li2.id} td.quantity") do
|
||||
@@ -608,8 +611,8 @@ describe '
|
||||
it "shows a dialog and keeps changes when confirm dialog is rejected" do
|
||||
page.driver.dismiss_modal :confirm,
|
||||
text: "Unsaved changes exist and will be lost if you continue." do
|
||||
find('#start_date_filter').click
|
||||
select_date_from_datepicker Time.zone.today - 9.days
|
||||
find("input.datepicker").click
|
||||
select_dates_from_daterangepicker(today - 9.days, today)
|
||||
end
|
||||
expect(page).to have_selector "#save-bar"
|
||||
within("tr#li_#{li2.id} td.quantity") do
|
||||
|
||||
@@ -700,6 +700,7 @@ describe '
|
||||
datetime = Time.zone.at(Time.zone.local(2040, 10, 17, 0o6, 0o0, 0o0))
|
||||
input = find(".flatpickr-calendar.open .flatpickr-minute")
|
||||
input.send_keys datetime.strftime("%M").to_s.strip
|
||||
input.send_keys :enter
|
||||
expect(page).to have_content "You have unsaved changes"
|
||||
end
|
||||
|
||||
|
||||
@@ -90,10 +90,8 @@ describe '
|
||||
it "filter by complete date" do
|
||||
login_as_admin_and_visit 'admin/orders'
|
||||
|
||||
find('#q_completed_at_gteq').click
|
||||
select_date_from_datepicker order3.completed_at.yesterday
|
||||
find('#q_completed_at_lteq').click
|
||||
select_date_from_datepicker order4.completed_at.tomorrow
|
||||
find("input.datepicker").click
|
||||
select_dates_from_daterangepicker(order3.completed_at.yesterday, order4.completed_at.tomorrow)
|
||||
|
||||
page.find('.filter-actions .button.icon-search').click
|
||||
|
||||
@@ -218,7 +216,7 @@ describe '
|
||||
end
|
||||
end
|
||||
|
||||
context "save the filter params" do
|
||||
context "save the filter params", js: true do
|
||||
let!(:shipping_method) { create(:shipping_method, name: "UPS Ground") }
|
||||
let!(:user) { create(:user, email: 'an@email.com') }
|
||||
let!(:order) do
|
||||
@@ -246,10 +244,8 @@ describe '
|
||||
fill_in "Email", with: user.email
|
||||
fill_in "First name begins with", with: "J"
|
||||
fill_in "Last name begins with", with: "D"
|
||||
find('#q_completed_at_gteq').click
|
||||
select_date_from_datepicker Time.zone.at(1.week.ago)
|
||||
find('#q_completed_at_lteq').click
|
||||
select_date_from_datepicker Time.zone.now.tomorrow
|
||||
find("input.datepicker").click
|
||||
select_dates_from_daterangepicker(Time.zone.at(1.week.ago), Time.zone.now.tomorrow)
|
||||
|
||||
page.find('a.icon-search').click
|
||||
end
|
||||
@@ -267,8 +263,7 @@ describe '
|
||||
expect(find_field("Email").value).to eq user.email
|
||||
expect(find_field("First name begins with").value).to eq "J"
|
||||
expect(find_field("Last name begins with").value).to eq "D"
|
||||
expect(find("#q_completed_at_gteq").value).to eq 1.week.ago.strftime("%Y-%m-%d")
|
||||
expect(find("#q_completed_at_lteq").value).to eq Time.zone.now.tomorrow.strftime("%Y-%m-%d")
|
||||
expect(find("input.datepicker").value).to eq "#{1.week.ago.strftime('%Y-%m-%d')} to #{Time.zone.now.tomorrow.strftime('%Y-%m-%d')}"
|
||||
end
|
||||
|
||||
it "and clear filters" do
|
||||
@@ -282,8 +277,7 @@ describe '
|
||||
expect(find_field("Email").value).to be_empty
|
||||
expect(find_field("First name begins with").value).to be_empty
|
||||
expect(find_field("Last name begins with").value).to be_empty
|
||||
expect(find("#q_completed_at_gteq").value).to be_empty
|
||||
expect(find("#q_completed_at_lteq").value).to be_empty
|
||||
expect(find("input.datepicker").value).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11605,6 +11605,11 @@ static-extend@^0.1.1:
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
||||
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
|
||||
|
||||
stimulus-flatpickr@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/stimulus-flatpickr/-/stimulus-flatpickr-1.4.0.tgz#a41071a3e69cfc50b7eaaacf356fc0ab1ab0543c"
|
||||
integrity sha512-rcC/c9+E+f5W2kOjaaLShtf3i+p95ACqt+oGzSAgeuZh2YeIN8gW4EWO7h0STBLzSVPl6BjIfPWP7upMPavIVQ==
|
||||
|
||||
stimulus@^3.0.1:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/stimulus/-/stimulus-3.1.0.tgz#225298f1936f96b0eafa883b8b304266427912c3"
|
||||
|
||||
Reference in New Issue
Block a user