diff --git a/calendar/js/et2_widget_event.ts b/calendar/js/et2_widget_event.ts index 5f9065bcf2..e8489d27c4 100644 --- a/calendar/js/et2_widget_event.ts +++ b/calendar/js/et2_widget_event.ts @@ -26,7 +26,7 @@ import {egw} from "../../api/js/jsapi/egw_global"; import {et2_selectbox} from "../../api/js/etemplate/et2_widget_selectbox"; import {et2_container} from "../../api/js/etemplate/et2_core_baseWidget"; import {Et2Dialog} from "../../api/js/etemplate/Et2Dialog/Et2Dialog"; -import {formatTime} from "../../api/js/etemplate/Et2Date/Et2Date"; +import {formatDate, formatTime} from "../../api/js/etemplate/Et2Date/Et2Date"; import {ColorTranslator} from "colortranslator"; /** @@ -1085,26 +1085,26 @@ export class et2_calendar_event extends et2_valueWidget implements et2_IDetached */ _copy_parent_actions() { - // Copy actions set in parent - if (!this.options.readonly && !this.getParent().options.readonly) + // Copy actions set in parent + if(!this.options.readonly && this.getParent() && !this.getParent().options.readonly) + { + let action_parent : et2_widget = this; + while(action_parent != null && !action_parent.options.actions && + !(action_parent instanceof et2_container) + ) { - let action_parent: et2_widget = this; - while (action_parent != null && !action_parent.options.actions && - !(action_parent instanceof et2_container) - ) - { - action_parent = action_parent.getParent(); - } - try - { - this._link_actions(action_parent.options.actions || {}); - this._need_actions_linked = false; - } - catch (e) - { - // something went wrong, but keep quiet about it - } + action_parent = action_parent.getParent(); } + try + { + this._link_actions(action_parent.options.actions || {}); + this._need_actions_linked = false; + } + catch(e) + { + // something went wrong, but keep quiet about it + } + } } /** @@ -1404,37 +1404,37 @@ export class et2_calendar_event extends et2_valueWidget implements et2_IDetached // we try to catch the exception and in this case retrieve the egw object from current window. try { - egw = this.egw ? (typeof this.egw == 'function' ? this.egw() : this.egw) : window.opener && typeof window.opener.egw != 'undefined' ? window.opener.egw('calendar') : window.egw('calendar'); + egw = this.egw ? (typeof this.egw == 'function' ? this.egw() : this.egw) : window.opener && typeof window.opener.egw != 'undefined' ? window.opener.egw('calendar') : window.egw('calendar'); } - catch (e) + catch(e) { - egw = window.egw('calendar'); + egw = window.egw('calendar'); } - const that = this; + const that = this; - if (typeof instance_date == 'string') - { - instance_date = new Date(instance_date); - } + if(typeof instance_date == 'string') + { + instance_date = new Date(instance_date); + } - // Check for modifying a series that started before today - const tempDate = new Date(); - const today = new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate(), tempDate.getHours(), -tempDate.getTimezoneOffset(), tempDate.getSeconds()); - const termination_date = instance_date < today ? egw.lang('today') : date(egw.preference('dateformat'), instance_date); + // Check for modifying a series that started before today + const tempDate = new Date(); + const today = new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate(), tempDate.getHours(), -tempDate.getTimezoneOffset(), tempDate.getSeconds()); + const termination_date = instance_date < today ? egw.lang('today') : formatDate(instance_date); - if (parseInt(event_data.recur_type)) - { - Et2Dialog.show_dialog( - function(button_id) - { - callback.call(that, button_id, event_data); - }, - (!event_data.is_private ? event_data['title'] : egw.lang('private')) + "\n" + - egw.lang("Do you really want to change the start of this series? If you do, the original series will be terminated as of %1 and a new series for the future reflecting your changes will be created.", termination_date), - "This event is part of a series", {}, Et2Dialog.BUTTONS_OK_CANCEL, Et2Dialog.WARNING_MESSAGE - ); - } + if(parseInt(event_data.recur_type)) + { + Et2Dialog.show_dialog( + function(button_id) + { + callback.call(that, button_id, event_data); + }, + (!event_data.is_private ? event_data['title'] : egw.lang('private')) + "\n" + + egw.lang("Do you really want to change the start of this series? If you do, the original series will be terminated as of %1 and a new series for the future reflecting your changes will be created.", termination_date), + "This event is part of a series", {}, Et2Dialog.BUTTONS_OK_CANCEL, Et2Dialog.WARNING_MESSAGE + ); + } } public static drag_helper(event, ui) diff --git a/calendar/js/et2_widget_planner.ts b/calendar/js/et2_widget_planner.ts index dff70fc825..dbf73baf75 100644 --- a/calendar/js/et2_widget_planner.ts +++ b/calendar/js/et2_widget_planner.ts @@ -23,7 +23,11 @@ import {et2_calendar_event} from "./et2_widget_event"; import {et2_calendar_planner_row} from "./et2_widget_planner_row"; import {egw} from "../../api/js/jsapi/egw_global"; import {egw_getObjectManager, egwActionObject} from "../../api/js/egw_action/egw_action.js"; -import {EGW_AI_DRAG_OVER, EGW_AO_FLAG_IS_CONTAINER} from "../../api/js/egw_action/egw_action_constants.js"; +import { + EGW_AI_DRAG_ENTER, + EGW_AI_DRAG_OUT, + EGW_AO_FLAG_IS_CONTAINER +} from "../../api/js/egw_action/egw_action_constants.js"; import {et2_IDetachedDOM, et2_IPrint, et2_IResizeable} from "../../api/js/etemplate/et2_core_interfaces"; import {et2_compileLegacyJS} from "../../api/js/etemplate/et2_core_legacyJSFunctions"; import {et2_no_init} from "../../api/js/etemplate/et2_core_common"; @@ -343,18 +347,9 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta this._link_actions(this.options.actions || this.getParent().options.actions || []); // Customize and override some draggable settings - this.div.on('dragcreate','.calendar_calEvent', function(event, ui) { - jQuery(this).draggable('option','cancel','.rowNoEdit'); - // Act like you clicked the header, makes it easier to position - jQuery(this).draggable('option','cursorAt', {top: 5, left: 5}); - }) - .on('dragstart', '.calendar_calEvent', function(event,ui) { - jQuery('.calendar_calEvent',ui.helper).width(jQuery(this).width()) - .height(jQuery(this).outerHeight()) - .css('top', '').css('left','') - .appendTo(ui.helper); - ui.helper.width(jQuery(this).width()); - + this.div + .on('dragstart', '.calendar_calEvent', function(event) + { // Cancel drag to create, we're dragging an existing event planner._drag_create_end(); }); @@ -1447,12 +1442,19 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta widget_object.getActionLink('egw_link_drop').enabled = !enabled; }; - aoi.doTriggerEvent = function(_event, _data) { + aoi.doTriggerEvent = function(_event, _data) + { // Determine target node var event = _data.event || false; - if(!event) return; - if(_data.ui.draggable.hasClass('rowNoEdit')) return; + if(!event) + { + return; + } + if(_data.ui.draggable.classList.contains('rowNoEdit')) + { + return; + } /* We have to handle the drop in the normal event stream instead of waiting @@ -1460,33 +1462,36 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta */ if(event.type === 'drop') { - this.getWidget()._event_drop.call(jQuery('.calendar_d-n-d_timeCounter',_data.ui.helper)[0],this.getWidget(),event, _data.ui); + this.getWidget()._event_drop.call(jQuery('.calendar_d-n-d_timeCounter', _data.ui.draggable)[0], this.getWidget(), event, _data.ui); } - var drag_listener = function(event, ui) { - aoi.getWidget()._drag_helper(jQuery('.calendar_d-n-d_timeCounter',ui.helper)[0],{ - top:ui.position.top, - left: ui.position.left - jQuery(this).parent().offset().left - },0); + var drag_listener = function(event) + { + let style = getComputedStyle(_data.ui.helper); + aoi.getWidget()._drag_helper(jQuery('.calendar_d-n-d_timeCounter', _data.ui.draggable)[0], { + top: parseInt(style.top), + left: event.clientX - jQuery(this).parent().offset().left + }, 0); }; - var time = jQuery('.calendar_d-n-d_timeCounter',_data.ui.helper); + var time = jQuery('.calendar_d-n-d_timeCounter', _data.ui.draggable); switch(_event) { // Triggered once, when something is dragged into the timegrid's div - case EGW_AI_DRAG_OVER: + case EGW_AI_DRAG_ENTER: // Listen to the drag and update the helper with the time // This part lets us drag between different timegrids - _data.ui.draggable.on('drag.et2_timegrid'+widget_object.id, drag_listener); - _data.ui.draggable.on('dragend.et2_timegrid'+widget_object.id, function() { - _data.ui.draggable.off('drag.et2_timegrid' + widget_object.id); + jQuery(_data.ui.draggable).on('drag.et2_timegrid' + widget_object.id, drag_listener); + jQuery(_data.ui.draggable).on('dragend.et2_timegrid' + widget_object.id, function() + { + jQuery(_data.ui.draggable).off('drag.et2_timegrid' + widget_object.id); }); if(time.length) { // The out will trigger after the over, so we count - time.data('count',time.data('count')+1); + time.data('count', time.data('count') + 1); } else { - _data.ui.helper.prepend('
'); + jQuery(_data.ui.draggable).prepend('
'); } break; @@ -1494,7 +1499,7 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta // Triggered once, when something is dragged out of the timegrid case EGW_AI_DRAG_OUT: // Stop listening - _data.ui.draggable.off('drag.et2_timegrid'+widget_object.id); + jQuery(_data.ui.draggable).off('drag.et2_timegrid' + widget_object.id); // Remove any highlighted time squares jQuery('[data-date]',this.doGetDOMNode()).removeClass("ui-state-active"); @@ -1781,9 +1786,9 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta var e = new jQuery.Event('change'); e.originalEvent = event; e.data = {start: 0}; - if (typeof this.dropEnd != 'undefined') + if(typeof this.dropEnd != 'undefined' && this.dropEnd) { - var drop_date = this.dropEnd.toJSON() ||false; + var drop_date = this.dropEnd.toJSON() || false; var event_data = planner._get_event_info(ui.draggable); var event_widget = planner.getWidgetById(event_data.widget_id); @@ -1792,9 +1797,9 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta event_widget.options.value.start = event_widget._parent.date_helper(drop_date); // Leave the helper there until the update is done - var loading = ui.helper.clone().appendTo(ui.helper.parent()); + var loading = event_data.event_node; // and add a loading icon so user knows something is happening - jQuery('.calendar_timeDemo',loading).after('
'); + jQuery('.calendar_calEventHeader', event_widget.div).addClass('loading'); event_widget.recur_prompt(function(button_id) { if(button_id === 'cancel' || !button_id) return; diff --git a/calendar/js/et2_widget_planner_row.ts b/calendar/js/et2_widget_planner_row.ts index 8c5264e3e9..c48ea0dcbd 100644 --- a/calendar/js/et2_widget_planner_row.ts +++ b/calendar/js/et2_widget_planner_row.ts @@ -21,7 +21,7 @@ import {ClassWithAttributes} from "../../api/js/etemplate/et2_core_inheritance"; import {et2_action_object_impl} from "../../api/js/etemplate/et2_core_DOMWidget"; import {et2_calendar_planner} from "./et2_widget_planner"; import {egw_getObjectManager, egwActionObject} from "../../api/js/egw_action/egw_action.js"; -import {EGW_AI_DRAG_OUT, EGW_AI_DRAG_OVER} from "../../api/js/egw_action/egw_action_constants.js"; +import {EGW_AI_DRAG_ENTER, EGW_AI_DRAG_OUT} from "../../api/js/egw_action/egw_action_constants.js"; import {et2_IResizeable} from "../../api/js/etemplate/et2_core_interfaces"; import {egw} from "../../api/js/jsapi/egw_global"; import {et2_calendar_view} from "./et2_widget_view"; @@ -176,12 +176,19 @@ export class et2_calendar_planner_row extends et2_valueWidget implements et2_IRe widget_object.getActionLink('egw_link_drop').enabled = !enabled; }; - aoi.doTriggerEvent = function(_event, _data) { + aoi.doTriggerEvent = function(_event, _data) + { // Determine target node var event = _data.event || false; - if(!event) return; - if(_data.ui.draggable.hasClass('rowNoEdit')) return; + if(!event) + { + return; + } + if(_data.ui.draggable.classList.contains('rowNoEdit')) + { + return; + } /* We have to handle the drop in the normal event stream instead of waiting for the egwAction system so we can get the helper, and destination @@ -189,27 +196,29 @@ export class et2_calendar_planner_row extends et2_valueWidget implements et2_IRe if(event.type === 'drop' && widget_object.getActionLink('egw_link_drop').enabled) { this.getWidget().getParent()._event_drop.call( - jQuery('.calendar_d-n-d_timeCounter',_data.ui.helper)[0], + jQuery('.calendar_d-n-d_timeCounter', _data.ui.draggable)[0], this.getWidget().getParent(), event, _data.ui, this.getWidget() ); } - const drag_listener = function (_event, ui) + const drag_listener = function(_event) { + let position = {}; if(planner.options.group_by === 'month') { - var position = {left: _event.clientX, top: _event.clientY}; + position = {left: _event.clientX, top: _event.clientY}; } else { - var position = {top: ui.position.top, left: ui.position.left - jQuery(this).parent().offset().left}; + let style = getComputedStyle(_data.ui.helper); + position = { + top: parseInt(style.top), + left: _event.clientX - jQuery(this).parent().offset().left + } } - aoi.getWidget().getParent()._drag_helper( - jQuery('.calendar_d-n-d_timeCounter', ui.helper)[0], - position, 0 - ); + aoi.getWidget().getParent()._drag_helper(jQuery('.calendar_d-n-d_timeCounter', _data.ui.draggable)[0], position, 0); - let event = _data.ui.draggable.data('selected')[0]; + var event = _data.ui.selected[0]; if(!event || event.id && event.id.indexOf('calendar') !== 0) { event = false; @@ -223,21 +232,22 @@ export class et2_calendar_planner_row extends et2_valueWidget implements et2_IRe ); } }; - const time = jQuery('.calendar_d-n-d_timeCounter', _data.ui.helper); + const time = jQuery('.calendar_d-n-d_timeCounter', _data.ui.draggable); switch(_event) { // Triggered once, when something is dragged into the timegrid's div - case EGW_AI_DRAG_OVER: + case EGW_AI_DRAG_ENTER: // Listen to the drag and update the helper with the time // This part lets us drag between different timegrids - _data.ui.draggable.on('drag.et2_timegrid_row'+widget_object.id, drag_listener); - _data.ui.draggable.on('dragend.et2_timegrid_row'+widget_object.id, function() { - _data.ui.draggable.off('drag.et2_timegrid_row' + widget_object.id); + jQuery(_data.ui.draggable).on('drag.et2_timegrid_row' + widget_object.id, drag_listener); + jQuery(_data.ui.draggable).on('dragend.et2_timegrid_row' + widget_object.id, function() + { + jQuery(_data.ui.draggable).off('drag.et2_timegrid_row' + widget_object.id); }); widget_object.iface.getWidget().div.addClass('drop-hover'); // Disable invite / change actions for same calendar or already participant - var event = _data.ui.draggable.data('selected')[0]; + let event = _data.ui.selected[0]; if(!event || event.id && event.id.indexOf('calendar') !== 0) { event = false; @@ -257,7 +267,7 @@ export class et2_calendar_planner_row extends et2_valueWidget implements et2_IRe } else { - _data.ui.helper.prepend('
'); + jQuery(_data.ui.draggable).prepend('
'); } @@ -266,7 +276,7 @@ export class et2_calendar_planner_row extends et2_valueWidget implements et2_IRe // Triggered once, when something is dragged out of the timegrid case EGW_AI_DRAG_OUT: // Stop listening - _data.ui.draggable.off('drag.et2_timegrid_row'+widget_object.id); + jQuery(_data.ui.draggable).off('drag.et2_timegrid_row' + widget_object.id); // Remove highlight widget_object.iface.getWidget().div.removeClass('drop-hover'); diff --git a/calendar/js/et2_widget_timegrid.ts b/calendar/js/et2_widget_timegrid.ts index f71738ec37..246294dfe1 100644 --- a/calendar/js/et2_widget_timegrid.ts +++ b/calendar/js/et2_widget_timegrid.ts @@ -26,7 +26,7 @@ import {et2_calendar_event} from "./et2_widget_event"; import {egw_getObjectManager, egwActionObject} from "../../api/js/egw_action/egw_action.js"; import {et2_compileLegacyJS} from "../../api/js/etemplate/et2_core_legacyJSFunctions"; import {Et2Dialog} from "../../api/js/etemplate/Et2Dialog/Et2Dialog"; -import {EGW_AI_DRAG_OUT, EGW_AI_DRAG_OVER} from "../../api/js/egw_action/egw_action_constants.js"; +import {EGW_AI_DRAG_ENTER, EGW_AI_DRAG_OUT} from "../../api/js/egw_action/egw_action_constants.js"; import {formatDate, formatTime, parseTime} from "../../api/js/etemplate/Et2Date/Et2Date"; import interact from "@interactjs/interactjs/index"; import type {InteractEvent} from "@interactjs/core/InteractEvent"; @@ -356,14 +356,7 @@ export class et2_calendar_timegrid extends et2_calendar_view implements et2_IDet // Customize and override some draggable settings this.div - .on('dragcreate', '.calendar_calEvent', function(event, ui) - { - jQuery(this).draggable('option', 'cancel', '.rowNoEdit'); - // Act like you clicked the header, makes it easier to position - // but put it to the side (-5) so we can still do the hover - jQuery(this).draggable('option', 'cursorAt', {top: 5, left: -5}); - }) - .on('dragstart', '.calendar_calEvent', function(event, ui) + .on('dragstart', '.calendar_calEvent', function(event) { // Cancel drag to create, we're dragging an existing event timegrid.drag_create.start = null; @@ -539,7 +532,6 @@ export class et2_calendar_timegrid extends et2_calendar_view implements et2_IDet [event_data.app_id, target_date || false, duration], function() { - debugger; loading.remove(); } ).sendRequest(true); @@ -1297,14 +1289,12 @@ export class et2_calendar_timegrid extends et2_calendar_view implements et2_IDet var helper = jQuery('.calendar_d-n-d_timeCounter', _data.ui.helper)[0]; if(helper && helper.dropEnd && helper.dropEnd.length >= 1) { - if(typeof this.dropEnd !== 'undefined' && this.dropEnd.length >= 1) - { - dropEnd = helper.dropEnd[0].dataset || false; - } + dropEnd = helper.dropEnd[0].dataset || this.dropEnd } this.getWidget()._event_drop.call(jQuery('.calendar_d-n-d_timeCounter', _data.ui.helper)[0], this.getWidget(), event, _data.ui, dropEnd); } - var drag_listener = function(_event, ui) { + var drag_listener = function(_event) + { aoi.getWidget()._drag_helper(jQuery('.calendar_d-n-d_timeCounter', _data.ui.helper)[0], _data.ui.helper[0], 0); if(aoi.getWidget().daily_owner) { @@ -1319,15 +1309,7 @@ export class et2_calendar_timegrid extends et2_calendar_view implements et2_IDet switch(_event) { // Triggered once, when something is dragged into the timegrid's div - case EGW_AI_DRAG_OVER: - // Listen to the drag and update the helper with the time - // This part lets us drag between different timegrids - jQuery(_data.ui.draggable).on('drag.et2_timegrid' + widget_object.id, drag_listener); - jQuery(_data.ui.draggable).on('dragend.et2_timegrid' + widget_object.id, function() - { - jQuery(_data.ui.draggable).off('drag.et2_timegrid' + widget_object.id); - }); - + case EGW_AI_DRAG_ENTER: // Remove formatting for out-of-view events (full day non-blocking) jQuery('.calendar_calEventHeader', _data.ui.helper).css('top', ''); jQuery('.calendar_calEventBody', _data.ui.helper).css('padding-top', ''); @@ -1369,12 +1351,19 @@ export class et2_calendar_timegrid extends et2_calendar_view implements et2_IDet timegrid.scrolling.scrollTop(timegrid._top_time); // Out triggers after the over, count to not accidentally remove - time.data('count',time.data('count')-1); + time.data('count', time.data('count') - 1); if(time.length && time.data('count') <= 0) { time.remove(); } break; + default: + // It never came in? + if(!time.length) + { + jQuery(_data.ui.helper).prepend('
'); + } + drag_listener(event); } }; @@ -1541,7 +1530,7 @@ export class et2_calendar_timegrid extends et2_calendar_view implements et2_IDet } // Leave the helper there until the update is done - var loading = action.ui.helper.clone(true).appendTo(jQuery('body')); + var loading = action.ui.draggable; // and add a loading icon so user knows something is happening if(jQuery('.calendar_timeDemo',loading).length == 0) diff --git a/calendar/templates/default/app.css b/calendar/templates/default/app.css index 8050407b7a..fca5a543a5 100644 --- a/calendar/templates/default/app.css +++ b/calendar/templates/default/app.css @@ -815,6 +815,8 @@ Hide subsequent headers in week view with non-consolidated owners opacity: 0.85; -moz-opacity: 0.85; + box-sizing: border-box; + touch-action:none; /* set via inline style on runtime: * top: depending on startime @@ -1212,6 +1214,7 @@ Hide subsequent headers in week view with non-consolidated owners height: 100%; border-left: 1px solid silver; margin-left: -1px; + z-index: 1; } .calendar_plannerGrid > .calendar_plannerScale, .calendar_plannerGrid > .calendar_plannerScaleDay { @@ -1242,6 +1245,7 @@ Hide subsequent headers in week view with non-consolidated owners left: 0px; width: 100%; min-height: 20px; + z-index: 2; } .calendar_plannerRowWidget:not(:first-child) { border-top: 1px solid silver; diff --git a/calendar/templates/mobile/app.css b/calendar/templates/mobile/app.css index 8049aa303c..1b03e2e13c 100644 --- a/calendar/templates/mobile/app.css +++ b/calendar/templates/mobile/app.css @@ -810,6 +810,8 @@ Hide subsequent headers in week view with non-consolidated owners transition: none !important; opacity: 0.85; -moz-opacity: 0.85; + box-sizing: border-box; + touch-action: none; /* set via inline style on runtime: * top: depending on startime * height: depending on length @@ -1182,6 +1184,7 @@ Hide subsequent headers in week view with non-consolidated owners height: 100%; border-left: 1px solid silver; margin-left: -1px; + z-index: 1; } .calendar_plannerGrid > .calendar_plannerScale, .calendar_plannerGrid > .calendar_plannerScaleDay { @@ -1213,6 +1216,7 @@ Hide subsequent headers in week view with non-consolidated owners left: 0px; width: 100%; min-height: 20px; + z-index: 2; } .calendar_plannerRowWidget:not(:first-child) { border-top: 1px solid silver; @@ -2989,4 +2993,3 @@ div#calendar-container div.calendar table tbody tr.rowhilite td { color: #707070; } } -/*# sourceMappingURL=app.css.map */ \ No newline at end of file diff --git a/calendar/templates/pixelegg/app.css b/calendar/templates/pixelegg/app.css index 1209c1b1ff..f5034f7a74 100755 --- a/calendar/templates/pixelegg/app.css +++ b/calendar/templates/pixelegg/app.css @@ -798,6 +798,8 @@ Hide subsequent headers in week view with non-consolidated owners transition: none !important; opacity: 0.85; -moz-opacity: 0.85; + box-sizing: border-box; + touch-action: none; /* set via inline style on runtime: * top: depending on startime * height: depending on length @@ -1170,6 +1172,7 @@ Hide subsequent headers in week view with non-consolidated owners height: 100%; border-left: 1px solid silver; margin-left: -1px; + z-index: 1; } .calendar_plannerGrid > .calendar_plannerScale, .calendar_plannerGrid > .calendar_plannerScaleDay { @@ -1201,6 +1204,7 @@ Hide subsequent headers in week view with non-consolidated owners left: 0px; width: 100%; min-height: 20px; + z-index: 2; } .calendar_plannerRowWidget:not(:first-child) { border-top: 1px solid silver;