mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-23 00:13:35 +01:00
Calendar et2 conversion work in progress.
- Slightly more efficient event positioning
This commit is contained in:
parent
a5b36d48e0
commit
4562b53b1b
@ -492,7 +492,7 @@ app.classes.calendar = AppJS.extend(
|
||||
egw().json(
|
||||
'calendar.calendar_uiforms.ajax_moveEvent',
|
||||
[widget.id, widget.options.value.owner, widget.options.value.start, widget.options.value.owner, widget.options.value.duration]
|
||||
).sendRequest();
|
||||
).sendRequest(true);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -290,69 +290,41 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
// Remove all events
|
||||
while(this._children.length)
|
||||
{
|
||||
this._children[this._children.length-1].free();
|
||||
var node = this._children[this._children.length-1];
|
||||
this.removeChild(node);
|
||||
node.free();
|
||||
}
|
||||
var events = _events || this.getArrayMgr('content').getEntry(this.options.date) || [];
|
||||
|
||||
// Sort events into minimally-overlapping columns
|
||||
var columns = this._spread_events(events);
|
||||
|
||||
for(var c = 0; c < columns.length; c++)
|
||||
for(var c = 0; c < events.length; c++)
|
||||
{
|
||||
// Calculate horizontal positioning
|
||||
var left = Math.ceil(5 + (1.5 * 100 / (this.options.width || 100)));
|
||||
var width = 98 - left;
|
||||
if (columns.length !== 1)
|
||||
{
|
||||
width = !c ? 70 : 50;
|
||||
left += c * (100.0-left) / columns.length;
|
||||
}
|
||||
if (left + width > 100.0) width = 98.0 - left;
|
||||
|
||||
var whole_day_counter = 0;
|
||||
|
||||
for(var i = 0; i < columns[c].length; i++)
|
||||
{
|
||||
// Calculate vertical positioning
|
||||
var top = 0;
|
||||
var height = 0;
|
||||
if(columns[c][i].whole_day_on_top)
|
||||
{
|
||||
top = ((this.title.height()/this.div.height())*100) + this.display_settings.rowHeight*whole_day_counter++;
|
||||
height = this.display_settings.rowHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
top = this._time_to_position(columns[c][i].start_m,whole_day_counter);
|
||||
height = this._time_to_position(columns[c][i].end_m,whole_day_counter)-top;
|
||||
}
|
||||
|
||||
// Create event
|
||||
var event = et2_createWidget('calendar-event',{id:columns[c][i].app_id||columns[c][i].id},this);
|
||||
var event = et2_createWidget('calendar-event',{
|
||||
id:events[c].app_id||events[c].id,
|
||||
value: events[c]
|
||||
},this);
|
||||
if(this.isInTree())
|
||||
{
|
||||
event.doLoadingFinished();
|
||||
}
|
||||
event.set_value(columns[c][i]);
|
||||
|
||||
// Copy actions set in parent
|
||||
event._link_actions(this._parent._parent.options.actions||{});
|
||||
|
||||
// Position the event
|
||||
event.div.css('top', top+'%');
|
||||
event.div.css('height', height+'%');
|
||||
event.div.css('left', left.toFixed(1)+'%');
|
||||
event.div.css('width', width.toFixed(1)+'%');
|
||||
}
|
||||
}
|
||||
|
||||
// Seperate loop so column sorting finds all children in the right place
|
||||
for(var c = 0; c < events.length; c++)
|
||||
{
|
||||
this._children[c].set_value(events[c]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sort a day's events into minimally overlapping columns
|
||||
*
|
||||
* @param {Object[]} events
|
||||
* @returns {Array[]} Events sorted into columns
|
||||
*/
|
||||
_spread_events: function(events)
|
||||
_spread_events: function()
|
||||
{
|
||||
var day_start = this.date.valueOf() / 1000;
|
||||
var dst_check = new Date(this.date);
|
||||
@ -367,9 +339,11 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
}
|
||||
|
||||
var eventCols = [], col_ends = [];
|
||||
for(var i = 0; i < events.length; i++)
|
||||
for(var i = 0; i < this._children.length; i++)
|
||||
{
|
||||
var event = events[i];
|
||||
var event = this._children[i].options.value || false;
|
||||
if(!event) continue;
|
||||
|
||||
var c = 0;
|
||||
event['multiday'] = false;
|
||||
if(typeof event.start !== 'object')
|
||||
@ -407,11 +381,70 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
{
|
||||
eventCols[c] = [];
|
||||
}
|
||||
eventCols[c].push(event);
|
||||
eventCols[c].push(this._children[i]);
|
||||
}
|
||||
return eventCols;
|
||||
},
|
||||
|
||||
/**
|
||||
* Position the event according to it's time and how this widget is laid
|
||||
* out.
|
||||
*
|
||||
* @param {undefined|Object|et2_calendar_event} event
|
||||
*/
|
||||
position_event: function(event)
|
||||
{
|
||||
// Sort events into minimally-overlapping columns
|
||||
var columns = this._spread_events();
|
||||
|
||||
for(var c = 0; c < columns.length; c++)
|
||||
{
|
||||
// Calculate horizontal positioning
|
||||
var left = Math.ceil(5 + (1.5 * 100 / (this.options.width || 100)));
|
||||
var width = 98 - left;
|
||||
if (columns.length !== 1)
|
||||
{
|
||||
width = !c ? 70 : 50;
|
||||
left += c * (100.0-left) / columns.length;
|
||||
}
|
||||
if (left + width > 100.0) width = 98.0 - left;
|
||||
|
||||
var whole_day_counter = 0;
|
||||
|
||||
for(var i = 0; (columns[c].indexOf(event) >= 0 || !event) && i < columns[c].length; i++)
|
||||
{
|
||||
// Calculate vertical positioning
|
||||
var top = 0;
|
||||
var height = 0;
|
||||
if(columns[c][i].options.value.whole_day_on_top)
|
||||
{
|
||||
top = ((this.title.height()/this.div.height())*100) + this.display_settings.rowHeight*whole_day_counter++;
|
||||
height = this.display_settings.rowHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
top = this._time_to_position(columns[c][i].options.value.start_m,whole_day_counter);
|
||||
height = this._time_to_position(columns[c][i].options.value.end_m,whole_day_counter)-top;
|
||||
}
|
||||
|
||||
// Position the event
|
||||
if(event && columns[c].indexOf(event) >= 0 || !event)
|
||||
{
|
||||
columns[c][i].div.css('top', top+'%');
|
||||
columns[c][i].div.css('height', height+'%');
|
||||
columns[c][i].div.css('left', left.toFixed(1)+'%');
|
||||
columns[c][i].div.css('width', width.toFixed(1)+'%');
|
||||
|
||||
}
|
||||
}
|
||||
// Only wanted to position this event, leave the other columns alone
|
||||
if(event && columns[c].indexOf(event) >= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculates the vertical position based on the time
|
||||
*
|
||||
|
@ -25,6 +25,10 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
{
|
||||
|
||||
attributes: {
|
||||
"value": {
|
||||
type: "any",
|
||||
default: et2_no_init
|
||||
},
|
||||
"onclick": {
|
||||
"description": "JS code which is executed when the element is clicked. " +
|
||||
"If no handler is provided, or the handler returns true and the event is not read-only, the " +
|
||||
@ -76,8 +80,11 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
// Unregister, or we'll continue to be notified...
|
||||
if(this.options.value)
|
||||
{
|
||||
var old_app_id = this.options.value.app_id ? this.options.value.app_id : this.options.value.id + (this.options.value.recur_type ? ':'+this.options.value.recur_date : '');
|
||||
egw.dataUnregisterUID('calendar::'+old_app_id,false,this);
|
||||
}
|
||||
},
|
||||
|
||||
set_value: function(_value) {
|
||||
@ -93,30 +100,13 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
var app_id = this.options.value.app_id ? this.options.value.app_id : this.options.value.id + (this.options.value.recur_type ? ':'+this.options.value.recur_date : '');
|
||||
egw.dataRegisterUID('calendar::'+app_id, function(event) {
|
||||
// Copy to avoid changes, which may cause nm problems
|
||||
event = jQuery.extend({},event);
|
||||
var list = [event];
|
||||
// Let parent format any missing data
|
||||
this._parent._spread_events(list);
|
||||
this.options.value = jQuery.extend({},event);
|
||||
|
||||
// Calculate vertical positioning
|
||||
// TODO: Maybe move this somewhere common between here & parent?
|
||||
var top = 0;
|
||||
var height = 0;
|
||||
if(event.whole_day_on_top)
|
||||
{
|
||||
top = ((this._parent.title.height()/this._parent.div.height())*100) + this._parent.display_settings.rowHeight;
|
||||
height = this._parent.display_settings.rowHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
top = this._parent._time_to_position(event.start_m,0);
|
||||
height = this._parent._time_to_position(event.end_m,0)-top;
|
||||
}
|
||||
// Let parent position
|
||||
this._parent.position_event(this);
|
||||
|
||||
this._update(this.options.value);
|
||||
|
||||
// Position the event - horizontal is controlled by parent
|
||||
this.div.css('top', top+'%');
|
||||
this.div.css('height', height+'%');
|
||||
this._update(event);
|
||||
},this,this.getInstanceManager().execId,this.id);
|
||||
|
||||
|
||||
@ -304,16 +294,18 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
icons.push('<img src="'+this.egw().image('recur','calendar')+'" title="'+this.egw().lang('recurring event')+'"/>');
|
||||
}
|
||||
// icons for single user, multiple users or group(s) and resources
|
||||
var single = '<img src="'+this.egw().image('single','calendar')+'" title="'+'"/>';
|
||||
var multiple = '<img src="'+this.egw().image('users','calendar')+'" title="'+'"/>';
|
||||
for(var uid in this.options.value['participants'])
|
||||
{
|
||||
if(Object.keys(this.options.value.participants).length == 1 && !isNaN(uid))
|
||||
{
|
||||
icons.push('<img src="'+this.egw().image('single','calendar')+'" title="'+'"/>');
|
||||
icons.push(single);
|
||||
break;
|
||||
}
|
||||
if(!isNaN(uid))
|
||||
if(!isNaN(uid) && icons.indexOf(multiple) === -1)
|
||||
{
|
||||
icons.push('<img src="'+this.egw().image('users','calendar')+'" title="'+'"/>');
|
||||
icons.push(multiple);
|
||||
}
|
||||
/*
|
||||
* TODO: resource icons
|
||||
|
@ -171,9 +171,9 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
*
|
||||
* If event information is not provided, it will be pulled from the content array.
|
||||
*
|
||||
* @param {Object[]} [_events] Array of event information, one per event.
|
||||
* @param {Object[]} [events] Array of event information, one per event.
|
||||
*/
|
||||
_update_events: function(_events)
|
||||
_update_events: function(events)
|
||||
{
|
||||
// Remove all events
|
||||
while(this._children.length)
|
||||
@ -182,7 +182,38 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
this.removeChild(this._children[this._children.length-1]);
|
||||
}
|
||||
|
||||
var rows = this._spread_events(_events);
|
||||
for(var c = 0; c < events.length; c++)
|
||||
{
|
||||
// Create event
|
||||
var event = et2_createWidget('calendar-event',{
|
||||
id:events[c].app_id||events[c].id,
|
||||
value: events[c]
|
||||
},this);
|
||||
if(this.isInTree())
|
||||
{
|
||||
event.doLoadingFinished();
|
||||
}
|
||||
|
||||
// Copy actions set in parent
|
||||
event._link_actions(this._parent._parent.options.actions||{});
|
||||
}
|
||||
|
||||
// Seperate loop so column sorting finds all children in the right place
|
||||
for(var c = 0; c < events.length; c++)
|
||||
{
|
||||
this._children[c].set_value(events[c]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Position the event according to it's time and how this widget is laid
|
||||
* out.
|
||||
*
|
||||
* @param {undefined|Object|et2_calendar_event} event
|
||||
*/
|
||||
position_event: function(event)
|
||||
{
|
||||
var rows = this._spread_events();
|
||||
var row = $j('<div class="calendar_plannerEventRowWidget"></div>').appendTo(this.rows);
|
||||
var height = rows.length * (parseInt(window.getComputedStyle(row[0]).getPropertyValue("height")) || 20);
|
||||
row.remove();
|
||||
@ -192,31 +223,17 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
// Calculate vertical positioning
|
||||
var top = c * (100.0 / rows.length);
|
||||
|
||||
for(var i = 0; i < rows[c].length; i++)
|
||||
for(var i = 0; (rows[c].indexOf(event) >=0 || !event) && i < rows[c].length; i++)
|
||||
{
|
||||
// Calculate horizontal positioning
|
||||
var left = this._time_to_position(rows[c][i].start);
|
||||
var width = this._time_to_position(rows[c][i].end)-left;
|
||||
|
||||
// Create event
|
||||
var event = et2_createWidget('calendar-event',{
|
||||
id:rows[c][i].app_id||rows[c][i].id,
|
||||
class: 'calendar_plannerEvent'
|
||||
},this);
|
||||
if(this.isInTree())
|
||||
{
|
||||
event.doLoadingFinished();
|
||||
}
|
||||
event.set_value(rows[c][i]);
|
||||
|
||||
// TODO
|
||||
event._link_actions(this._parent.options.actions||{});
|
||||
var left = this._time_to_position(rows[c][i].options.value.start);
|
||||
var width = this._time_to_position(rows[c][i].options.value.end)-left;
|
||||
|
||||
// Position the event
|
||||
event.div.css('top', top+'%');
|
||||
event.div.css('height', (100/rows.length)+'%');
|
||||
event.div.css('left', left.toFixed(1)+'%');
|
||||
event.div.css('width', width.toFixed(1)+'%');
|
||||
rows[c][i].div.css('top', top+'%');
|
||||
rows[c][i].div.css('height', (100/rows.length)+'%');
|
||||
rows[c][i].div.css('left', left.toFixed(1)+'%');
|
||||
rows[c][i].div.css('width', width.toFixed(1)+'%');
|
||||
}
|
||||
}
|
||||
if(height)
|
||||
@ -228,10 +245,9 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
/**
|
||||
* Sort a day's events into non-overlapping rows
|
||||
*
|
||||
* @param {Object[]} events
|
||||
* @returns {Array[]} Events sorted into rows
|
||||
*/
|
||||
_spread_events: function(events)
|
||||
_spread_events: function()
|
||||
{
|
||||
// sorting the events in non-overlapping rows
|
||||
var rows = [];
|
||||
@ -240,9 +256,9 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
var start = this.options.start_date;
|
||||
var end = this.options.end_date;
|
||||
|
||||
for(var n = 0; n < events.length; n++)
|
||||
for(var n = 0; n < this._children.length; n++)
|
||||
{
|
||||
var event = events[n];
|
||||
var event = this._children[n].options.value || false;
|
||||
if(typeof event.start !== 'object')
|
||||
{
|
||||
this.date_helper.set_value(event.start);
|
||||
@ -282,11 +298,11 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
}
|
||||
}
|
||||
|
||||
var event_start = new Date(events[n].start).valueOf();
|
||||
var event_start = new Date(event.start).valueOf();
|
||||
for(var row = 0; row_end[row] > event_start; ++row); // find a "free" row (no other event)
|
||||
if(typeof rows[row] === 'undefined') rows[row] = [];
|
||||
rows[row].push(events[n]);
|
||||
row_end[row] = new Date(events[n]['end']).valueOf();
|
||||
rows[row].push(this._children[n]);
|
||||
row_end[row] = new Date(event['end']).valueOf();
|
||||
}
|
||||
return rows;
|
||||
},
|
||||
|
@ -245,7 +245,8 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
|
||||
|
||||
if(event_widget)
|
||||
{
|
||||
event_widget.options.value.end_m = event_widget.options.value.duration = e.data.duration;
|
||||
event_widget.options.value.end_m = eT;
|
||||
event_widget.options.value.duration = e.data.duration;
|
||||
}
|
||||
$j(this).trigger(e);
|
||||
|
||||
@ -253,7 +254,10 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
|
||||
$j(this).resizable('destroy');
|
||||
}
|
||||
// Clear the helper, re-draw
|
||||
event_widget.set_value(event_widget.options.value);
|
||||
if(event_widget)
|
||||
{
|
||||
event_widget._parent.position_event(event_widget);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -517,6 +521,7 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
|
||||
|
||||
// Create / update day widgets with dates and data, if available
|
||||
// TODO: need data doesn't take category & other filters into account
|
||||
// Currently always loading new data, which causes multiple unneeded redraws
|
||||
var need_data = true;
|
||||
for(var i = 0; i < this.day_list.length; i++)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user