mirror of
https://github.com/itflow-org/itflow
synced 2026-09-08 07:45:11 +00:00
Update Font, Migrated away from JQUERY dependent libs: toastr to bootstrap5 toasts, daterangepicker to flatpickr, select2 to Tom Select, InputMask to IMask
This commit is contained in:
@@ -1,108 +1,183 @@
|
||||
(function ($, window) {
|
||||
"use strict";
|
||||
/**
|
||||
* Date range filter.
|
||||
*
|
||||
* Rebuilt on Flatpickr, replacing daterangepicker (jQuery) and moment.
|
||||
*
|
||||
* Flatpickr has no preset-ranges feature, so the nine presets daterangepicker
|
||||
* gave us for free are built here as a panel injected into the calendar via
|
||||
* the onReady hook. Behaviour is unchanged: picking a preset writes its canned
|
||||
* value and clears dtf/dtt; picking a custom range writes 'custom' plus both
|
||||
* dates; either way the form auto-submits.
|
||||
*
|
||||
* Date maths is plain Date - weeks start Monday, matching the old isoWeek.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
$(function () {
|
||||
var $input = $('#dateFilter');
|
||||
if (!$input.length) return; // nothing to initialize
|
||||
var ALL_TIME_START = '1970-01-01';
|
||||
var ALL_TIME_END = '2099-12-31';
|
||||
|
||||
var $canned = $('#canned_date');
|
||||
var $dtf = $('#dtf');
|
||||
var $dtt = $('#dtt');
|
||||
|
||||
// Default to "All Time" if nothing provided
|
||||
var hasValues =
|
||||
($dtf.val() && $dtt.val()) ||
|
||||
($canned.val() && $canned.val() !== '');
|
||||
|
||||
if (!hasValues) {
|
||||
$canned.val('alltime');
|
||||
$dtf.val('1970-01-01');
|
||||
$dtt.val('2099-12-31');
|
||||
function ymd(d) {
|
||||
var m = String(d.getMonth() + 1).padStart(2, '0');
|
||||
var day = String(d.getDate()).padStart(2, '0');
|
||||
return d.getFullYear() + '-' + m + '-' + day;
|
||||
}
|
||||
|
||||
var initialStart = moment($dtf.val(), "YYYY-MM-DD");
|
||||
var initialEnd = moment($dtt.val(), "YYYY-MM-DD");
|
||||
|
||||
function setDisplay(start, end, label) {
|
||||
// Special display for All Time
|
||||
if (
|
||||
label === 'All Time' ||
|
||||
(start.format('YYYY-MM-DD') === '1970-01-01' &&
|
||||
end.format('YYYY-MM-DD') === '2099-12-31')
|
||||
) {
|
||||
$input.val('All Time');
|
||||
} else {
|
||||
$input.val(start.format('YYYY-MM-DD') + " — " + end.format('YYYY-MM-DD'));
|
||||
}
|
||||
function parseYmd(s) {
|
||||
var parts = String(s || '').split('-');
|
||||
if (parts.length !== 3) {
|
||||
return null;
|
||||
}
|
||||
var d = new Date(Number(parts[0]), Number(parts[1]) - 1, Number(parts[2]));
|
||||
return isNaN(d.getTime()) ? null : d;
|
||||
}
|
||||
|
||||
var cannedMap = {
|
||||
"Today": "today",
|
||||
"Yesterday": "yesterday",
|
||||
"This Week": "thisweek",
|
||||
"Last Week": "lastweek",
|
||||
"This Month": "thismonth",
|
||||
"Last Month": "lastmonth",
|
||||
"This Year": "thisyear",
|
||||
"Last Year": "lastyear",
|
||||
"All Time": "alltime"
|
||||
};
|
||||
function addDays(d, n) {
|
||||
var c = new Date(d.getTime());
|
||||
c.setDate(c.getDate() + n);
|
||||
return c;
|
||||
}
|
||||
|
||||
$input.daterangepicker({
|
||||
startDate: initialStart,
|
||||
endDate: initialEnd,
|
||||
autoUpdateInput: true,
|
||||
opens: 'left',
|
||||
locale: {
|
||||
format: 'YYYY-MM-DD',
|
||||
firstDay: 1
|
||||
},
|
||||
ranges: {
|
||||
'Today': [moment(), moment()],
|
||||
'Yesterday': [moment().subtract(1, 'day'), moment().subtract(1, 'day')],
|
||||
'This Week': [moment().startOf('isoWeek'), moment()],
|
||||
'Last Week': [
|
||||
moment().subtract(1, 'week').startOf('isoWeek'),
|
||||
moment().subtract(1, 'week').endOf('isoWeek')
|
||||
],
|
||||
'This Month': [moment().startOf('month'), moment()],
|
||||
'Last Month': [
|
||||
moment().subtract(1, 'month').startOf('month'),
|
||||
moment().subtract(1, 'month').endOf('month')
|
||||
],
|
||||
'This Year': [moment().startOf('year'), moment()],
|
||||
'Last Year': [
|
||||
moment().subtract(1, 'year').startOf('year'),
|
||||
moment().subtract(1, 'year').endOf('year')
|
||||
],
|
||||
'All Time': [
|
||||
moment('1970-01-01', 'YYYY-MM-DD'),
|
||||
moment('2099-12-31', 'YYYY-MM-DD')
|
||||
]
|
||||
}
|
||||
}, setDisplay);
|
||||
/** Monday-based start of week, matching moment's isoWeek. */
|
||||
function startOfWeek(d) {
|
||||
var c = new Date(d.getTime());
|
||||
var dow = (c.getDay() + 6) % 7;
|
||||
return addDays(c, -dow);
|
||||
}
|
||||
|
||||
// Show initial label
|
||||
setDisplay(initialStart, initialEnd);
|
||||
function buildRanges() {
|
||||
var now = new Date();
|
||||
var lastWeekStart = addDays(startOfWeek(now), -7);
|
||||
|
||||
$input.on('apply.daterangepicker', function (ev, picker) {
|
||||
var label = picker.chosenLabel || '';
|
||||
var canned = cannedMap[label];
|
||||
return [
|
||||
{ label: 'Today', canned: 'today', start: now, end: now },
|
||||
{ label: 'Yesterday', canned: 'yesterday',
|
||||
start: addDays(now, -1), end: addDays(now, -1) },
|
||||
{ label: 'This Week', canned: 'thisweek',
|
||||
start: startOfWeek(now), end: now },
|
||||
{ label: 'Last Week', canned: 'lastweek',
|
||||
start: lastWeekStart, end: addDays(lastWeekStart, 6) },
|
||||
{ label: 'This Month', canned: 'thismonth',
|
||||
start: new Date(now.getFullYear(), now.getMonth(), 1), end: now },
|
||||
{ label: 'Last Month', canned: 'lastmonth',
|
||||
start: new Date(now.getFullYear(), now.getMonth() - 1, 1),
|
||||
end: new Date(now.getFullYear(), now.getMonth(), 0) },
|
||||
{ label: 'This Year', canned: 'thisyear',
|
||||
start: new Date(now.getFullYear(), 0, 1), end: now },
|
||||
{ label: 'Last Year', canned: 'lastyear',
|
||||
start: new Date(now.getFullYear() - 1, 0, 1),
|
||||
end: new Date(now.getFullYear() - 1, 11, 31) },
|
||||
{ label: 'All Time', canned: 'alltime',
|
||||
start: parseYmd(ALL_TIME_START), end: parseYmd(ALL_TIME_END) }
|
||||
];
|
||||
}
|
||||
|
||||
if (canned) {
|
||||
$canned.val(canned);
|
||||
$dtf.val('');
|
||||
$dtt.val('');
|
||||
} else {
|
||||
$canned.val('custom');
|
||||
$dtf.val(picker.startDate.format('YYYY-MM-DD'));
|
||||
$dtt.val(picker.endDate.format('YYYY-MM-DD'));
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var input = document.getElementById('dateFilter');
|
||||
if (!input || input._flatpickr) {
|
||||
return;
|
||||
}
|
||||
|
||||
setDisplay(picker.startDate, picker.endDate, label);
|
||||
var canned = document.getElementById('canned_date');
|
||||
var dtf = document.getElementById('dtf');
|
||||
var dtt = document.getElementById('dtt');
|
||||
if (!canned || !dtf || !dtt) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Auto-submit form
|
||||
this.form.submit();
|
||||
// Default to All Time when the page arrives with nothing set
|
||||
if (!((dtf.value && dtt.value) || canned.value)) {
|
||||
canned.value = 'alltime';
|
||||
dtf.value = ALL_TIME_START;
|
||||
dtt.value = ALL_TIME_END;
|
||||
}
|
||||
|
||||
var ranges = buildRanges();
|
||||
var submitting = false;
|
||||
var presetClicked = false;
|
||||
|
||||
function setDisplay(start, end, label) {
|
||||
if (label === 'All Time' ||
|
||||
(ymd(start) === ALL_TIME_START && ymd(end) === ALL_TIME_END)) {
|
||||
input.value = 'All Time';
|
||||
} else {
|
||||
input.value = ymd(start) + ' \u2014 ' + ymd(end);
|
||||
}
|
||||
}
|
||||
|
||||
function apply(start, end, range) {
|
||||
if (submitting) {
|
||||
return;
|
||||
}
|
||||
submitting = true;
|
||||
if (range) {
|
||||
canned.value = range.canned;
|
||||
dtf.value = '';
|
||||
dtt.value = '';
|
||||
} else {
|
||||
canned.value = 'custom';
|
||||
dtf.value = ymd(start);
|
||||
dtt.value = ymd(end);
|
||||
}
|
||||
setDisplay(start, end, range ? range.label : undefined);
|
||||
if (input.form) {
|
||||
input.form.submit();
|
||||
}
|
||||
}
|
||||
|
||||
var initialStart = parseYmd(dtf.value) || parseYmd(ALL_TIME_START);
|
||||
var initialEnd = parseYmd(dtt.value) || parseYmd(ALL_TIME_END);
|
||||
var initialKey = ymd(initialStart) + '|' + ymd(initialEnd);
|
||||
|
||||
flatpickr(input, {
|
||||
mode: 'range',
|
||||
dateFormat: 'Y-m-d',
|
||||
defaultDate: [initialStart, initialEnd],
|
||||
locale: { firstDayOfWeek: 1 },
|
||||
allowInput: false,
|
||||
onReady: function (selectedDates, dateStr, instance) {
|
||||
// The preset panel daterangepicker used to provide
|
||||
var panel = document.createElement('div');
|
||||
panel.className = 'itflow-fp-ranges';
|
||||
ranges.forEach(function (r) {
|
||||
var btn = document.createElement('button');
|
||||
btn.type = 'button';
|
||||
btn.className = 'itflow-fp-range';
|
||||
btn.textContent = r.label;
|
||||
btn.addEventListener('click', function () {
|
||||
// close() fires onClose synchronously - flag it first
|
||||
// or onClose applies the stale range as a custom one
|
||||
presetClicked = true;
|
||||
instance.close();
|
||||
apply(r.start, r.end, r);
|
||||
});
|
||||
panel.appendChild(btn);
|
||||
});
|
||||
instance.calendarContainer.classList.add('itflow-fp-with-ranges');
|
||||
instance.calendarContainer.appendChild(panel);
|
||||
},
|
||||
onClose: function (selectedDates, dateStr, instance) {
|
||||
// A preset closed the calendar itself; its handler applies.
|
||||
if (presetClicked) {
|
||||
presetClicked = false;
|
||||
return;
|
||||
}
|
||||
// Abandoned half-selection - put the box back how it was.
|
||||
if (selectedDates.length !== 2) {
|
||||
instance.setDate([initialStart, initialEnd], false);
|
||||
setDisplay(initialStart, initialEnd);
|
||||
return;
|
||||
}
|
||||
// Dismissed without actually changing the range - daterangepicker
|
||||
// only applied on its Apply button, so don't resubmit here.
|
||||
if (ymd(selectedDates[0]) + '|' + ymd(selectedDates[1]) === initialKey) {
|
||||
setDisplay(initialStart, initialEnd);
|
||||
return;
|
||||
}
|
||||
apply(selectedDates[0], selectedDates[1], null);
|
||||
}
|
||||
});
|
||||
|
||||
setDisplay(initialStart, initialEnd);
|
||||
});
|
||||
});
|
||||
})(jQuery, window);
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user