Calendar: Drag & drop working for planner by user view

This commit is contained in:
nathan 2024-07-23 14:41:17 -06:00
parent b2132c089d
commit ee8c491c77
2 changed files with 92 additions and 24 deletions

View File

@ -214,6 +214,11 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta
*/ */
onstart: function(event : InteractEvent) onstart: function(event : InteractEvent)
{ {
if(event.type == "resizestart")
{
event.target.removeAttribute("draggable");
}
egw.tooltipDestroy();
if(planner.drag_create.start) if(planner.drag_create.start)
{ {
// Abort drag to create, we're dragging to resize // Abort drag to create, we're dragging to resize
@ -358,6 +363,13 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta
{ {
// Cancel drag to create, we're dragging an existing event // Cancel drag to create, we're dragging an existing event
planner._drag_create_end(); planner._drag_create_end();
})
.on("dragend", () =>
{
this.div.removeClass(["drop-hover", "et2-dropzone"]);
// Remove helper
document.body.querySelectorAll(".calendar_d-n-d_helper").forEach(n => n.remove());
}); });
return true; return true;
} }
@ -1488,6 +1500,7 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta
aoi.doTriggerEvent = function(_event, _data) aoi.doTriggerEvent = function(_event, _data)
{ {
egw.tooltipDestroy();
// Determine target node // Determine target node
var event = _data.event || false; var event = _data.event || false;
@ -1506,17 +1519,26 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta
*/ */
if(event.type === 'drop') if(event.type === 'drop')
{ {
this.getWidget()._event_drop.call(jQuery('.calendar_d-n-d_timeCounter', _data.ui.draggable)[0], this.getWidget(), event, _data.ui); this.getWidget()._event_drop.call(_data.ui.draggable, this.getWidget(), event, _data.ui);
} }
var drag_listener = function(event) var drag_listener = function(event)
{ {
event.preventDefault();
const helper = document.body.querySelector(".calendar_d-n-d_helper");
if(helper)
{
helper.style.top = (event.clientY + 20) + "px";
helper.style.left = (event.clientX - (helper.clientWidth / 2)) + "px";
}
let style = getComputedStyle(_data.ui.helper); let style = getComputedStyle(_data.ui.helper);
aoi.getWidget()._drag_helper(jQuery('.calendar_d-n-d_timeCounter', _data.ui.draggable)[0], { aoi.getWidget()._drag_helper(helper, {
top: parseInt(style.top), top: Number.isNaN(style.top) ? event.clientY : parseInt(style.top),
left: event.clientX - jQuery(this).parent().offset().left left: event.clientX - jQuery(this).parent().offset().left
}, 0); }, 0);
}; };
var time = jQuery('.calendar_d-n-d_timeCounter', _data.ui.draggable); var time = jQuery('.calendar_d-n-d_timeCounter', _data.ui.helper);
switch(_event) switch(_event)
{ {
// Triggered once, when something is dragged into the timegrid's div // Triggered once, when something is dragged into the timegrid's div
@ -1527,6 +1549,11 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta
jQuery(_data.ui.draggable).on('dragend.et2_timegrid' + widget_object.id, function() jQuery(_data.ui.draggable).on('dragend.et2_timegrid' + widget_object.id, function()
{ {
jQuery(_data.ui.draggable).off('drag.et2_timegrid' + widget_object.id); jQuery(_data.ui.draggable).off('drag.et2_timegrid' + widget_object.id);
aoi.getWidget().div.removeClass(["drop-hover", "et2-dropzone"]);
// Remove helper
document.body.querySelectorAll(".calendar_d-n-d_helper").forEach(n => n.remove());
}); });
if(time.length) if(time.length)
{ {
@ -1535,7 +1562,7 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta
} }
else else
{ {
jQuery(_data.ui.draggable).prepend('<div class="calendar_d-n-d_timeCounter" data-count="1"><span></span></div>'); jQuery(_data.ui.helper).prepend('<div class="calendar_d-n-d_timeCounter" data-count="1"><span></span></div>');
} }
break; break;
@ -1639,6 +1666,24 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta
for(var i = 0; i < source.length; i++) for(var i = 0; i < source.length; i++)
{ {
if(!source[i].id) continue; if(!source[i].id) continue;
if(source[i].manager === dropped.manager)
{
// Find the planner, could have dropped on an event
let planner = dropped.iface.getWidget();
while(planner.getParent() && planner.instanceOf && !planner.instanceOf(et2_calendar_planner))
{
planner = planner.getParent();
}
if(planner && planner._drop_data)
{
planner._event_drop.call(source[i].iface.getDOMNode(), planner, null, action.ui);
}
planner._drop_data = false;
// Ok, stop.
return false;
}
id = source[i].id.split('::'); id = source[i].id.split('::');
links.push({app: id[0] == 'filemanager' ? 'link' : id[0], id: id[1]}); links.push({app: id[0] == 'filemanager' ? 'link' : id[0], id: id[1]});
} }
@ -1753,10 +1798,15 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta
{ {
// Create drag action that allows linking // Create drag action that allows linking
drag_action = mgr.addAction('drag', 'egw_link_drag', egw.lang('link'), 'link', function(action, selected) { drag_action = mgr.addAction('drag', 'egw_link_drag', egw.lang('link'), 'link', function(action, selected) {
// As we wanted to have a general defaul helper interface, we return null here and not using customize helper for links const helper = selected[0].iface.getWidget().getDOMNode().cloneNode();
// TODO: Need to decide if we need to create a customized helper interface for links anyway helper.classList.add("calendar_d-n-d_helper");
//return helper; let position = selected[0].iface.getDOMNode().getBoundingClientRect();
return null;
self._drag_helper(helper, position, position.height);
document.body.append(helper);
// System drag helper - empty span so we can update with the target time
return document.createElement("span");
},true); },true);
} }
// The planner itself is not draggable, the action is there for the children // The planner itself is not draggable, the action is there for the children
@ -1809,11 +1859,24 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta
*/ */
_drag_helper(element, position ,height) _drag_helper(element, position ,height)
{ {
if(!element)
{
return;
}
if(position.height)
{
element.style.height = position.height + "px";
}
let time = this._get_time_from_position(position.left, position.top); let time = this._get_time_from_position(position.left, position.top);
element.dropEnd = time; element.dropEnd = time;
if(time)
{
this._drop_data = {...element.dataset};
}
let formatted_time = formatTime(time); let formatted_time = formatTime(time);
element.innerHTML = '<div class="calendar_d-n-d_timeCounter"><span class="calendar_timeDemo" >'+formatted_time+'</span></div>'; element.innerHTML = '<div class="calendar_d-n-d_timeCounter"><span class="calendar_timeDemo" >'+formatted_time+'</span></div>';
element.querySelector('.calendar_d-n-d_timeCounter').dropEnd = time;
//jQuery(element).width(jQuery(helper).width()); //jQuery(element).width(jQuery(helper).width());
} }
@ -1833,6 +1896,7 @@ export class et2_calendar_planner extends et2_calendar_view implements et2_IDeta
if(typeof this.dropEnd != 'undefined' && this.dropEnd) if(typeof this.dropEnd != 'undefined' && this.dropEnd)
{ {
var drop_date = this.dropEnd.toJSON() || false; var drop_date = this.dropEnd.toJSON() || false;
this.dropEnd = undefined;
var event_data = planner._get_event_info(ui.draggable); var event_data = planner._get_event_info(ui.draggable);
var event_widget = planner.getWidgetById(event_data.widget_id); var event_widget = planner.getWidgetById(event_data.widget_id);

View File

@ -150,7 +150,7 @@ export class et2_calendar_planner_row extends et2_valueWidget implements et2_IRe
{ {
var event = event.iface.getWidget(); var event = event.iface.getWidget();
const row = target.iface.getWidget() || false; const row = target.iface.getWidget() || false;
if(event === row || !event || !row || if(event === row || !event || !row || !row.node ||
!event.options || !event.options.value.participants !event.options || !event.options.value.participants
) )
{ {
@ -162,7 +162,7 @@ export class et2_calendar_planner_row extends et2_valueWidget implements et2_IRe
for (let id in event.options.value.participants) for (let id in event.options.value.participants)
{ {
owner_match = owner_match || row.node.dataset.participants === '' + id; owner_match = owner_match || (row.node.dataset?.participants ?? false) === '' + id;
} }
const enabled = !owner_match && const enabled = !owner_match &&
@ -195,14 +195,18 @@ export class et2_calendar_planner_row extends et2_valueWidget implements et2_IRe
*/ */
if(event.type === 'drop' && widget_object.getActionLink('egw_link_drop').enabled) if(event.type === 'drop' && widget_object.getActionLink('egw_link_drop').enabled)
{ {
this.getWidget().getParent()._event_drop.call( const helper = document.body.querySelector(".calendar_d-n-d_helper");
jQuery('.calendar_d-n-d_timeCounter', _data.ui.draggable)[0], const planner = this.getWidget().getParent();
this.getWidget().getParent(), event, _data.ui, planner._event_drop.call(
helper,
planner, event, _data.ui,
this.getWidget() this.getWidget()
); );
planner._drop_data = false;
} }
const drag_listener = function(_event) const drag_listener = function(_event)
{ {
_event.preventDefault();
let position = {}; let position = {};
if(planner.options.group_by === 'month') if(planner.options.group_by === 'month')
{ {
@ -212,11 +216,10 @@ export class et2_calendar_planner_row extends et2_valueWidget implements et2_IRe
{ {
let style = getComputedStyle(_data.ui.helper); let style = getComputedStyle(_data.ui.helper);
position = { position = {
top: parseInt(style.top), top: parseInt(style.top || "0"),
left: _event.clientX - jQuery(this).parent().offset().left left: _event.clientX - jQuery(this).parent().offset().left
} }
} }
aoi.getWidget().getParent()._drag_helper(jQuery('.calendar_d-n-d_timeCounter', _data.ui.draggable)[0], position, 0);
var event = _data.ui.selected[0]; var event = _data.ui.selected[0];
if(!event || event.id && event.id.indexOf('calendar') !== 0) if(!event || event.id && event.id.indexOf('calendar') !== 0)
@ -232,17 +235,23 @@ export class et2_calendar_planner_row extends et2_valueWidget implements et2_IRe
); );
} }
}; };
const time = jQuery('.calendar_d-n-d_timeCounter', _data.ui.draggable); const time = jQuery('.calendar_d-n-d_timeCounter', _data.ui.helper);
switch(_event) switch(_event)
{ {
// Triggered once, when something is dragged into the timegrid's div // Triggered once, when something is dragged into the timegrid's div
case EGW_AI_DRAG_ENTER: case EGW_AI_DRAG_ENTER:
// Listen to the drag and update the helper with the time // Listen to the drag and update the helper with the time
// This part lets us drag between different timegrids // This part lets us drag between different timegrids
jQuery(_data.ui.draggable).on('drag.et2_timegrid_row' + widget_object.id, drag_listener); planner.div.on('dragover.et2_timegrid_row' + widget_object.id, drag_listener);
jQuery(_data.ui.draggable).on('dragend.et2_timegrid_row' + widget_object.id, function() planner.div.on('dragend.et2_timegrid_row' + widget_object.id, function()
{ {
jQuery(_data.ui.draggable).off('drag.et2_timegrid_row' + widget_object.id); jQuery(_data.ui.draggable).off('drag.et2_timegrid_row' + widget_object.id);
planner.div.removeClass(["drop-hover", "et2-dropzone"]);
// Remove helper
document.body.querySelectorAll(".calendar_d-n-d_helper").forEach(n => n.remove());
}); });
widget_object.iface.getWidget().div.addClass('drop-hover'); widget_object.iface.getWidget().div.addClass('drop-hover');
@ -265,11 +274,6 @@ export class et2_calendar_planner_row extends et2_valueWidget implements et2_IRe
// The out will trigger after the over, so we count // 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
{
jQuery(_data.ui.draggable).prepend('<div class="calendar_d-n-d_timeCounter" data-count="1"><span></span></div>');
}
break; break;