/* ---------------------------------------------------------------------------- * Easy!Appointments - Online Appointment Scheduler * * @package EasyAppointments * @author A.Tselegidis * @copyright Copyright (c) Alex Tselegidis * @license https://opensource.org/licenses/GPL-3.0 - GPLv3 * @link https://easyappointments.org * @since v1.5.0 * ---------------------------------------------------------------------------- */ /** * Working plan exceptions modal component. * * This module implements the working plan exceptions modal functionality. */ App.Components.WorkingPlanExceptionsModal = (function () { const $modal = $('#working-plan-exceptions-modal'); const $date = $('#working-plan-exceptions-date'); const $start = $('#working-plan-exceptions-start'); const $end = $('#working-plan-exceptions-end'); const $breaks = $('#working-plan-exceptions-breaks'); const $save = $('#working-plan-exceptions-save'); const $addBreak = $('.working-plan-exceptions-add-break'); const $isNonWorkingDay = $('#working-plan-exceptions-is-non-working-day'); const moment = window.moment; let deferred = null; let enableSubmit = false; let enableCancel = false; /** * Reset the modal fields back to the original empty state. */ function resetModal() { $addBreak.prop('disabled', false); $date.val(''); $start.val(''); $end.val(''); $breaks.find('tbody').html(renderNoBreaksRow()); $isNonWorkingDay.prop('checked', false); toggleFieldsByNonWorkingDay(false); } /** * Render a single table row as a placeholder to empty breaks table. */ function renderNoBreaksRow() { return $(` ${lang('no_breaks')} `); } /** * Toggle the state of the fields depending on the non-working day checkbox value. * * @param {Boolean} isNonWorkingDay */ function toggleFieldsByNonWorkingDay(isNonWorkingDay) { $start.prop('disabled', isNonWorkingDay).toggleClass('text-decoration-line-through', isNonWorkingDay); $end.prop('disabled', isNonWorkingDay).toggleClass('text-decoration-line-through', isNonWorkingDay); $addBreak.prop('disabled', isNonWorkingDay); $breaks.find('button').prop('disabled', isNonWorkingDay); $breaks.toggleClass('text-decoration-line-through', isNonWorkingDay); } /** * Validate the modal form fields and return false if the validation fails. * * @returns {Boolean} */ function validate() { $modal.find('.is-invalid').removeClass('is-invalid'); const date = $date[0]._flatpickr.selectedDates[0]; if (!date) { $date.addClass('is-invalid'); } const start = $start[0]._flatpickr.selectedDates[0]; if (!start) { $start.addClass('is-invalid'); } const end = $end[0]._flatpickr.selectedDates[0]; if (!end) { $end.addClass('is-invalid'); } return !$modal.find('.is-invalid').length; } /** * Event: On Modal "Hidden" * * This event is used to automatically reset the modal back to the original state. */ function onModalHidden() { resetModal(); } /** * Serialize the entered break entries. * * @returns {Array} */ function getBreaks() { const breaks = []; $breaks .find('tbody tr') .not('.no-breaks-row') .each((index, tr) => { const $tr = $(tr); if ($tr.find('input:text').length) { return true; } const start = $tr.find('.working-plan-exceptions-break-start').text(); const end = $tr.find('.working-plan-exceptions-break-end').text(); breaks.push({ start: moment(start, vars('time_format') === 'regular' ? 'h:mm a' : 'HH:mm').format('HH:mm'), end: moment(end, vars('time_format') === 'regular' ? 'h:mm a' : 'HH:mm').format('HH:mm'), }); }); // Sort breaks increasingly by hour within day breaks.sort((break1, break2) => { // We can do a direct string comparison since we have time based on 24 hours clock. return break1.start.localeCompare(break2.start); }); return breaks; } /** * Event: On Save "Click" * * Serialize the entire working plan exception and resolved the promise so that external code can save it. */ function onSaveClick() { if (!deferred) { return; } if (!validate()) { return; } const date = moment($date[0]._flatpickr.selectedDates[0]).format('YYYY-MM-DD'); const isNonWorkingDay = $isNonWorkingDay.prop('checked'); const workingPlanException = isNonWorkingDay ? null : { start: moment($start[0]._flatpickr.selectedDates[0]).format('HH:mm'), end: moment($end[0]._flatpickr.selectedDates[0]).format('HH:mm'), breaks: getBreaks(), }; deferred.resolve(date, workingPlanException); $modal.modal('hide'); resetModal(); } /** * Enable the inline-editable table cell functionality for the provided target element.. * * @param {jQuery} $target */ function editableTimeCell($target) { $target.editable( (value) => { // Do not return the value because the user needs to press the "Save" button. return value; }, { event: 'edit', height: '30px', submit: $('