UNPKG

@oveasoft/planning

Version:

An AngularJS planning component

196 lines (176 loc) 7.43 kB
import template from './ovaPlanningDay.template.html'; import moment from 'moment'; import { Slot } from '../classes/slot.class'; import { MomentHelper } from '../classes/moment.helper'; import angular from 'angular'; import _ from 'lodash'; import './ovaPlanningDay.scss'; /** * @name OvaPlanningDayComponent * @class OvaPlanningDayComponent * @module day * @description Represent a day of the planning. */ class OvaPlanningDayComponent { /** * @constructor * @property {moment.Moment|String} date The moment object or a string of a date. * @property {Array} data Data to be sorted in slots. */ constructor () { this.slots = []; /** * Build a moment object. * @private */ this._buildDate = () => { if (moment(this.date).isValid()) { this.date = moment(this.date); } else { throw new Error(`[ova-planning] Trying to build a day from an invalid date parameter ${this.date} (${typeof date}).`); } }; /** * Build slots. * @private */ this._buildSlots = () => { _.each(this.ovaPlanning.config.slot, (slotRanges, index) => { let start = slotRanges[0]; let end = slotRanges[1]; let currentSlot = MomentHelper.buildSlot(this.date, start); let lastSlot = MomentHelper.buildSlot(this.date, end); /** * Build breaking slots if config.showPause = true */ if (this.ovaPlanning.config.showPause && index > 0) { this._buildBreakSlot(currentSlot, index); } while (currentSlot.isBefore(lastSlot)) { let actualSlot = moment(currentSlot); let nextSlot = moment(currentSlot.add(this.ovaPlanning.config.slotInterval, 'minutes')); let targetSlot = nextSlot.isAfter(lastSlot) ? lastSlot : nextSlot; let slot = new Slot(actualSlot, targetSlot, [], 'slot'); this._dataToSlot(slot); this.slots.push(slot); } }); /** * Build waiting slots. */ this.waitingSlot = new Slot(moment(this.date).hour(0), moment(this.date).hour(1), [], 'slot waiting'); this._missPlacedAppointment(); this.slots.push(this.waitingSlot); }; this._buildBreakSlot = (currentSlot, index) => { let previousMaxHour = this.ovaPlanning.config.slot[index - 1][1]; let previousSlot = MomentHelper.buildSlot(this.date, previousMaxHour); this.slots.push(new Slot(previousSlot, moment(currentSlot), [], 'break')); }; /** * Put data in the rights slots. * We must iterate through each slot of this day and find the between. * example: 8:14 must go in 8:00's slot because 8:14 > 8:00 AND 8:14 < 8:15. * @param {Slot} slot * @private */ this._dataToSlot = (slot) => { if (this.data) { _.each(this.data, appointment => { _.set(appointment, this.ovaPlanning.config.datePath, moment(_.get(appointment, this.ovaPlanning.config.datePath))); // _.get(appointment, this.ovaPlanning.config.datePath) = _.get(appointment, this.ovaPlanning.config.datePath) instanceof moment ? _.get(appointment, this.ovaPlanning.config.datePath) : moment(_.get(appointment, this.ovaPlanning.config.datePath)); if (_.get(appointment, this.ovaPlanning.config.datePath) instanceof moment) { if (_.get(appointment, this.ovaPlanning.config.datePath).isSame(this.date, 'day')) { this._placeAppointment(appointment, slot); } } else { throw new Error(`[ova-planning] ${_.get(appointment, this.ovaPlanning.config.datePath)} is not an instance of moment.`); } }); } }; /** * Place the appointment without slot. * @private */ this._missPlacedAppointment = () => { let missplacedAppointment = _.filter(this.data, appointment => { let isBetween = null; _.each(this.ovaPlanning.config.slot, ranges => { let start = ranges[0]; let end = ranges[1]; let startSlot = MomentHelper.buildSlot(this.date, start); let endSlot = MomentHelper.buildSlot(this.date, end); isBetween = _.get(appointment, this.ovaPlanning.config.datePath).isBetween(startSlot, endSlot, null, '[)'); if (isBetween) { return false; } }); return !isBetween; }); _.each(missplacedAppointment, appointment => { if (_.get(appointment, this.ovaPlanning.config.datePath) instanceof moment && _.get(appointment, this.ovaPlanning.config.datePath).isSame(this.date, 'day')) { this.ovaPlanning.pushToInformations(appointment, 'missplaced'); // appointment._isPlaced = false; this.waitingSlot.data.push(appointment); } }); }; /** * Place an appointment in a slot. * @param appointment * @param {Slot} slot * @private */ this._placeAppointment = (appointment, slot) => { if (slot.start instanceof moment && slot.state === 'slot') { if (this._appointmentFitInSlot(slot, appointment)) { this.ovaPlanning.pushToInformations(appointment, 'placed'); // appointment._isPlaced = true; slot.data.push(appointment); } } }; /** * Check if the appointment date is between the slot start and end. * @param {Object} slot * @param {Object} appointment * @private */ this._appointmentFitInSlot = (slot, appointment) => { return _.get(appointment, this.ovaPlanning.config.datePath).isSameOrAfter(slot.start) && _.get(appointment, this.ovaPlanning.config.datePath).isBefore(slot.end); }; } /** * Event */ $onInit () { this.ovaPlanning.Debugger.output(`Day ${this.date.day()} $onInit`); this.theme = `theme-${this.ovaPlanning.config.theme}`; this.oldData = angular.copy(this.data); this._buildDate(); this._buildSlots(); } $doCheck () { if (!angular.equals(this.data, this.oldData)) { this.ovaPlanning.Debugger.output(`Data for day ${this.date.day()} has changed.`); this.slots = []; this._buildSlots(); this.oldData = angular.copy(this.data); } } slotClicked (slot) { this.ovaPlanning.config.selectSlot(slot); } } export default { controller: OvaPlanningDayComponent, template, require: { ovaPlanning: '^ovaPlanning' }, bindings: { date: '<?', data: '=' } };