UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

203 lines (163 loc) • 5.41 kB
"use strict"; var dateUtils = require("../../core/utils/date"), days = [0, 1, 2, 3, 4, 5, 6]; function getWeekendDays(workdays) { return days.filter(function (day) { return !workdays.some(function (workDay) { return workDay === day; }); }); } function getNextDayIndex(dayIndex) { return (dayIndex + 1) % 7; } function dayBetweenWeekend(weekend, day) { var start = weekend.start, end = weekend.end; while (start !== end) { if (start === day) { return true; } start = getNextDayIndex(start); } return false; } function getDaysDistance(day, end) { var length = 0; while (day !== end) { day = getNextDayIndex(day); length++; } return length; } function separateBreak(scaleBreak, day) { var result = [], dayEnd = new Date(day); dayEnd.setDate(day.getDate() + 1); if (day > scaleBreak.from) { result.push({ from: scaleBreak.from, to: day }); } if (dayEnd < scaleBreak.to) { result.push({ from: dayEnd, to: scaleBreak.to }); } return result; } function getWeekEndDayIndices(workDays) { var indices = getWeekendDays(workDays); if (indices.length < 7) { while (getNextDayIndex(indices[indices.length - 1]) === indices[0]) { indices.unshift(indices.pop()); } } return indices; } function generateDateBreaksForWeekend(min, max, weekendDayIndices) { var day = min.getDate(), breaks = [], weekends = weekendDayIndices.reduce(function (obj, day) { var currentWeekEnd = obj[1]; if (currentWeekEnd.start === undefined) { currentWeekEnd = { start: day, end: getNextDayIndex(day) }; obj[0].push(currentWeekEnd); return [obj[0], currentWeekEnd]; } else if (currentWeekEnd.end === day) { currentWeekEnd.end = getNextDayIndex(day); return obj; } currentWeekEnd = { start: day, end: getNextDayIndex(day) }; obj[0].push(currentWeekEnd); return [obj[0], currentWeekEnd]; }, [[], {}]); weekends[0].forEach(function (weekend) { var currentDate = new Date(min); currentDate = dateUtils.trimTime(currentDate); while (currentDate < max) { day = currentDate.getDay(); var date = currentDate.getDate(); if (dayBetweenWeekend(weekend, day)) { var from = new Date(currentDate), to; currentDate.setDate(date + getDaysDistance(day, weekend.end)); to = new Date(currentDate); breaks.push({ from: from, to: to }); } currentDate.setDate(currentDate.getDate() + 1); } }); return breaks; } function excludeWorkDaysFromWeekEndBreaks(breaks, exactWorkDays) { var result = breaks.slice(), i, processWorkDay = function processWorkDay(workday) { workday = dateUtils.trimTime(new Date(workday)); if (result[i].from <= workday && result[i].to > workday) { var separatedBreak = separateBreak(result[i], workday); if (separatedBreak.length === 2) { result.splice(i, 1, separatedBreak[0], separatedBreak[1]); } else if (separatedBreak.length === 1) { result.splice(i, 1, separatedBreak[0]); } else { result.splice(i, 1); } } }; for (i = 0; i < result.length; i++) { exactWorkDays.forEach(processWorkDay); } return result; } function generateBreaksForHolidays(min, max, holidays, weekendDayIndices) { var day, dayInWeekend = function dayInWeekend(dayIndex) { return dayIndex === day; }, adjustedMin = dateUtils.trimTime(min), adjustedMax = dateUtils.trimTime(max); adjustedMax.setDate(max.getDate() + 1); return holidays.reduce(function (breaks, holiday) { var holidayStart, holidayEnd; holiday = new Date(holiday); day = holiday.getDay(); if (!weekendDayIndices.some(dayInWeekend) && holiday >= adjustedMin && holiday <= adjustedMax) { holidayStart = dateUtils.trimTime(holiday); holidayEnd = new Date(holidayStart); holidayEnd.setDate(holidayStart.getDate() + 1); breaks.push({ from: holidayStart, to: holidayEnd }); } return breaks; }, []); } function calculateGaps(breaks) { return breaks.map(function (b) { return { from: b.from, to: b.to, gapSize: dateUtils.convertMillisecondsToDateUnits(b.to - b.from) }; }); } exports.generateDateBreaks = function (min, max, workWeek, singleWorkdays, holidays) { var weekendDayIndices = getWeekEndDayIndices(workWeek), breaks = generateDateBreaksForWeekend(min, max, weekendDayIndices); breaks.push.apply(breaks, generateBreaksForHolidays(min, max, holidays || [], weekendDayIndices)); return calculateGaps(excludeWorkDaysFromWeekEndBreaks(breaks, singleWorkdays || [])); };