Calendar et2 bugs:

- Fix drag to re-order calendars
- Keep order in planner view
This commit is contained in:
Nathan Gray 2015-08-11 22:30:50 +00:00
parent c770021acb
commit 57ab5dc678
6 changed files with 161 additions and 49 deletions

View File

@ -840,7 +840,7 @@ class calendar_ui
{ {
if(is_int($event[$field])) if(is_int($event[$field]))
{ {
$event[$field] = egw_time::to($event[$field],'Y-m-d\TH:i:s').'Z'; $event[$field] = egw_time::to($event[$field], egw_time::ET2);
} }
} }
} }

View File

@ -240,7 +240,7 @@ class calendar_uiviews extends calendar_ui
$GLOBALS['egw_info']['flags']['params']['manual'] = array('page' => 'ManualCalendar'.ucfirst($this->view)); $GLOBALS['egw_info']['flags']['params']['manual'] = array('page' => 'ManualCalendar'.ucfirst($this->view));
// Sidebox & iframe for old views // Sidebox & iframe for old views
if(in_array($this->view,array('year','planner')) && $_GET['view']) if(in_array($this->view,array('year')) && $_GET['view'])
{ {
$GLOBALS['egw_info']['flags']['nonavbar'] = true; $GLOBALS['egw_info']['flags']['nonavbar'] = true;
$this->manage_states($_GET); $this->manage_states($_GET);
@ -269,11 +269,11 @@ class calendar_uiviews extends calendar_ui
if (egw_json_request::isJSONRequest())// && strpos($_GET['menuaction'], 'calendar_uiforms') === false) if (egw_json_request::isJSONRequest())// && strpos($_GET['menuaction'], 'calendar_uiforms') === false)
{ {
$states = array(); $states = array();
foreach(array('date','cat_id','filter','owner','view') as $state) foreach(array('date','cat_id','filter','owner','view','sortby') as $state)
{ {
if($this->$state) $states[$state] = $this->$state; if($this->$state) $states[$state] = $this->$state;
} }
$states['date'] = egw_time::to($states['date'],'Y-m-d\TH:i:s').'Z'; $states['date'] = egw_time::to($states['date'],egw_time::ET2);
$response = egw_json_response::get(); $response = egw_json_response::get();
$response->apply('app.calendar.set_state', array($states)); $response->apply('app.calendar.set_state', array($states));
} }

View File

@ -124,7 +124,6 @@ app.classes.calendar = AppJS.extend(
var egw_fw = egw_getFramework(); var egw_fw = egw_getFramework();
sidebox= $j('#favorite_sidebox_'+this.appname,egw_fw.sidemenuDiv); sidebox= $j('#favorite_sidebox_'+this.appname,egw_fw.sidemenuDiv);
} }
this._init_sidebox(sidebox);
var content = this.et2.getArrayMgr('content'); var content = this.et2.getArrayMgr('content');
@ -268,22 +267,36 @@ app.classes.calendar = AppJS.extend(
*/ */
linkHandler: function(_url) linkHandler: function(_url)
{ {
if (_url.match('menuaction=calendar.calendar_uiviews.index')) if (_url.match('menuaction=calendar\.calendar_uiviews\.'))
{ {
var state = this.getState(); var view = _url.match(/calendar_uiviews\.([^&?]+)/);
if (state.view == 'listview') view = view && view.length > 1 ? view[1] : null;
{
return _url.replace(/menuaction=[^&]+/, 'menuaction=calendar.calendar_uilist.listview&ajax=true'); // Get query
} var q = {};
else if (this.sidebox_et2 && typeof app.classes.calendar.views[state.view] == 'undefined') _url.split('?')[1].split('&').forEach(function(i){
q[i.split('=')[0]]=i.split('=')[1];
});
delete q.ajax;
delete q.menuaction;
if((!view || view == 'index') && q.view) view = q.view;
if (this.sidebox_et2 && typeof app.classes.calendar.views[view] == 'undefined')
{ {
this.sidebox_et2.getWidgetById('iframe').set_src(_url); this.sidebox_et2.getWidgetById('iframe').set_src(_url);
return true; return true;
} }
// Known AJAX view, but not loaded // Known AJAX view
else if(app.classes.calendar.views[state.view]) else if(app.classes.calendar.views[view])
{ {
return _url + '&ajax=true'; if(typeof app.classes.calendar.views[view].etemplates[0] == 'string')
{
return _url + '&ajax=true';
}
// Already loaded, we'll just apply any variables to our current state
var set = jQuery.extend({view: view},q);
this.update_state(set);
return true;
} }
} }
else if (_url.indexOf('menuaction=calendar.calendar_') >= 0) else if (_url.indexOf('menuaction=calendar.calendar_') >= 0)
@ -329,13 +342,12 @@ app.classes.calendar = AppJS.extend(
create: function () create: function ()
{ {
var $sortItem = jQuery(this); var $sortItem = jQuery(this);
}, },
start: function (event, ui) start: function (event, ui)
{ {
$j('.calendar_calTimeGrid',ui.helper).css('position', 'absolute'); $j('.calendar_calTimeGrid',ui.helper).css('position', 'absolute');
// Put owners into row IDs // Put owners into row IDs
app.classes.calendar.views[state.view].etemplates[0].widgetContainer.iterateOver(function(widget) { app.classes.calendar.views[app.calendar.state.view].etemplates[0].widgetContainer.iterateOver(function(widget) {
widget.div.parents('tr').attr('data-owner',widget.options.owner); widget.div.parents('tr').attr('data-owner',widget.options.owner);
},this,et2_calendar_timegrid); },this,et2_calendar_timegrid);
}, },
@ -344,6 +356,7 @@ app.classes.calendar = AppJS.extend(
}, },
update: function () update: function ()
{ {
var state = app.calendar.getState();
if (state && typeof state.owner !== 'undefined') if (state && typeof state.owner !== 'undefined')
{ {
var sortedArr = sortable.sortable('toArray', {attribute:"data-owner"}); var sortedArr = sortable.sortable('toArray', {attribute:"data-owner"});
@ -1370,10 +1383,14 @@ app.classes.calendar = AppJS.extend(
var view = app.classes.calendar.views[state.state.view]; var view = app.classes.calendar.views[state.state.view];
// Sanitize owner so it's always an array // Sanitize owner so it's always an array
if(state.state.owner === null)
{
state.state.owner = undefined;
}
switch(typeof state.state.owner) switch(typeof state.state.owner)
{ {
case 'undefined': case 'undefined':
state.state.owner = this.egw.user('account_id'); state.state.owner = [this.egw.user('account_id')];
break; break;
case 'string': case 'string':
state.state.owner = state.state.owner.split(','); state.state.owner = state.state.owner.split(',');
@ -2022,6 +2039,45 @@ app.classes.calendar = AppJS.extend(
} }
}, },
/**
* Initializes actions and handlers on sidebox (delete)
* Extended from parent to automatically add change handlers for resource
* menu items.
*
* @param {jQuery} sidebox jQuery of DOM node
*/
_init_sidebox: function(sidebox)
{
if( this._super.apply(this, arguments) )
{
sidebox.parentsUntil('#calendar_sidebox_content')
.find('.egw_fw_ui_category_content').not(sidebox.parent())
.on('change.sidebox', 'select:not(.et2_selectbox),input', this, function(event) {
var state = {};
// Here we look for things like owner: ['r1,r2'] and change them
// to owner: ['r1','r2']
state[this.name.replace('[]','')] = $j(this).val();
for(var key in state)
{
if(state[key] && typeof state[key].length !== 'undefined')
{
for(var sub_key in state[key])
{
if(typeof state[key][sub_key] == 'string' && state[key][sub_key].indexOf(',') !== -1)
{
var explode_me = state[key][sub_key];
delete state[key][sub_key];
jQuery.extend(state[key], explode_me.split(','));
}
}
}
}
app.calendar.update_state(state);
});
}
},
/** /**
* The sidebox filters use some non-standard and not-exposed options. They * The sidebox filters use some non-standard and not-exposed options. They
* are set up here. * are set up here.
@ -2220,7 +2276,8 @@ jQuery.extend(app.classes.calendar,{
} }
// If the owner is not set, 0, or the current user, don't bother adding it // If the owner is not set, 0, or the current user, don't bother adding it
var _owner = (owner && owner.toString() != '0' && owner !== (app.calendar.state.owner.toString()||'')) ? owner.toString() : ''; var state_owner = app.calendar ? app.calendar.state.owner.toString() || '' : '';
var _owner = (owner && owner.toString() != '0' && owner !== state_owner) ? owner.toString() : '';
if(_owner == egw.user('account_id')) if(_owner == egw.user('account_id'))
{ {
_owner = ''; _owner = '';

View File

@ -495,7 +495,8 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM],
// Go over the widget & add links - this is where we decide which actions are // Go over the widget & add links - this is where we decide which actions are
// 'allowed' for this widget at this time // 'allowed' for this widget at this time
var action_links = this._get_action_links(actions); var action_links = this._get_action_links(actions);
this._parent._parent._init_links_dnd(widget_object.manager,action_links); action_links.push('egw_link_drag');
action_links.push('egw_link_drop');
widget_object.updateActionLinks(action_links); widget_object.updateActionLinks(action_links);
}, },

View File

@ -295,7 +295,7 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
}, },
// Labels for the rows // Labels for the rows
row_labels: function() { row_labels: function() {
var labels = {}; var labels = [];
var accounts = egw.accounts(); var accounts = egw.accounts();
for(var i = 0; i < this.options.owner.length; i++) for(var i = 0; i < this.options.owner.length; i++)
{ {
@ -307,25 +307,41 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
} }
if (isNaN(user)) // resources if (isNaN(user)) // resources
{ {
labels[user] = egw.link_title('resources',user.match(/\d+/)[0],function(name) {this[user] = name;},labels); var planner = this;
var label = egw.link_title('resources',user.match(/\d+/)[0],function(name) {
for(var j = 0; j < labels.length; j++)
{
if(labels[j].id == this)
{
labels[j].label = name;
break;
}
}
var row = planner.getWidgetById(this);
if(row && row.set_label)
{
row.set_label(name);
}
},user);
labels.push({id: user, label: label});
} }
else if (user < 0) // groups else if (user < 0) // groups
{ {
egw.accountData(user,'account_fullname',true,function(result) { egw.accountData(user,'account_fullname',true,function(result) {
for(var id in result) for(var id in result)
{ {
this[id] = result[id]; this.push({id: id, label: result[id]});
} }
},labels); },labels);
} }
else // users else // users
{ {
user = parseInt(user) user = parseInt(user)
for(var i = 0; i < accounts.length; i++) for(var j = 0; j < accounts.length; j++)
{ {
if(accounts[i].value === user) if(accounts[j].value === user)
{ {
labels[user] = accounts[i].label; labels.push({id: user, label: accounts[j].label});
break; break;
} }
} }
@ -358,14 +374,23 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
for(var user in event.participants) for(var user in event.participants)
{ {
var participant = event.participants[user]; var participant = event.participants[user];
if(participant && typeof labels[user] !== 'undefined' && status_to_show.indexOf(participant.substr(0,1)) >= 0 || var label_index = false;
for(var i = 0; i < labels.length; i++)
{
if(labels[i].id == user)
{
label_index = i;
break;
}
}
if(participant && label_index !== false && status_to_show.indexOf(participant.substr(0,1)) >= 0 ||
this.options.filter === 'owner' && event.owner === user) this.options.filter === 'owner' && event.owner === user)
{ {
if(typeof rows[user] === 'undefined') if(typeof rows[label_index] === 'undefined')
{ {
rows[user] = []; rows[label_index] = [];
} }
rows[user].push(event); rows[label_index].push(event);
} }
} }
}, },
@ -383,12 +408,12 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
this.headers.append(this._header_day_of_month()); this.headers.append(this._header_day_of_month());
}, },
row_labels: function() { row_labels: function() {
var labels = {}; var labels = [];
var d = new Date(this.options.start_date); var d = new Date(this.options.start_date);
d = new Date(d.valueOf() + d.getTimezoneOffset() * 60 * 1000); d = new Date(d.valueOf() + d.getTimezoneOffset() * 60 * 1000);
for(var i = 0; i < 12; i++) for(var i = 0; i < 12; i++)
{ {
labels[d.getUTCFullYear() +'-'+d.getUTCMonth()] = egw.lang(date('F',d))+' '+d.getUTCFullYear(); labels.push({id: d.getUTCFullYear() +'-'+d.getUTCMonth(), label:egw.lang(date('F',d))+' '+d.getUTCFullYear()});
d.setUTCMonth(d.getUTCMonth()+1); d.setUTCMonth(d.getUTCMonth()+1);
} }
return labels; return labels;
@ -396,11 +421,20 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
group: function(labels, rows,event) { group: function(labels, rows,event) {
var start = new Date(event.start); var start = new Date(event.start);
var key = start.getUTCFullYear() +'-'+start.getUTCMonth(); var key = start.getUTCFullYear() +'-'+start.getUTCMonth();
if(typeof rows[key] === 'undefined') var label_index = false;
for(var i = 0; i < labels.length; i++)
{ {
rows[key] = []; if(labels[i].id == key)
{
label_index = i;
break;
}
} }
rows[key].push(event); if(typeof rows[label_index] === 'undefined')
{
rows[label_index] = [];
}
rows[label_index].push(event);
// end in a different month? // end in a different month?
var end = new Date(event.end); var end = new Date(event.end);
@ -415,7 +449,15 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
month = 1; month = 1;
} }
key = sprintf('%04d-%02d',year,month); key = sprintf('%04d-%02d',year,month);
rows[key].push(event); for(var i = 0; i < labels.length; i++)
{
if(labels[i].id == key)
{
label_index = i;
break;
}
}
rows[label_index].push(event);
} }
}, },
// Draw a single row, but split up the dates // Draw a single row, but split up the dates
@ -452,17 +494,22 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
} }
}, },
row_labels: function() { row_labels: function() {
return {'': egw.lang('none')}; return [{id:'',label: egw.lang('none')}];
}, },
group: function(labels, rows, event) { group: function(labels, rows, event) {
if(typeof rows[event.category] === 'undefined') var label_index = false;
for(var i = 0; i < labels.length; i++)
{ {
rows[event.category] = []; if(labels[i].id == event.category)
{
label_index = i;
break;
}
} }
rows[event.category].push(event); if(label_index === false)
if(typeof labels[event.category] === 'undefined')
{ {
labels[event.category] = ''; label_index = labels.length;
labels.push({id: event.category, label: ''});
var im = this.getInstanceManager(); var im = this.getInstanceManager();
// Fake it to use the cache / call // Fake it to use the cache / call
var categories = et2_selectbox.cat_options({ var categories = et2_selectbox.cat_options({
@ -473,10 +520,15 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
{ {
if(parseInt(categories[i].value) === parseInt(event.category)) if(parseInt(categories[i].value) === parseInt(event.category))
{ {
labels[event.category] = categories[i].label; labels[labels.length-1].label = categories[i].label;
} }
} }
} }
if(typeof rows[label_index] === 'undefined')
{
rows[label_index] = [];
}
rows[label_index].push(event);
}, },
draw_row: function(sort_key, label, events) { draw_row: function(sort_key, label, events) {
return this._drawRow(sort_key, label,events,this.options.start_date, this.options.end_date); return this._drawRow(sort_key, label,events,this.options.start_date, this.options.end_date);
@ -603,7 +655,7 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
// Draw the rows // Draw the rows
for(var key in labels) for(var key in labels)
{ {
grouper.draw_row.call(this,key, labels[key], events[key] || []); grouper.draw_row.call(this,labels[key].id, labels[key].label, events[key] || []);
} }
}, },
@ -1198,7 +1250,8 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
return null; return null;
},true); },true);
} }
if(actionLinks.indexOf(drag_action.id) < 0) // The planner itself is not draggable, the action is there for the children
if(false && actionLinks.indexOf(drag_action.id) < 0)
{ {
actionLinks.push(drag_action.id); actionLinks.push(drag_action.id);
} }

View File

@ -646,12 +646,11 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
// This binds into the egw action system. Most user interactions (drag to move, resize) // This binds into the egw action system. Most user interactions (drag to move, resize)
// are handled internally using jQuery directly. // are handled internally using jQuery directly.
var widget_object = parent.getObjectById(this.id); var widget_object = this._actionObject || parent.getObjectById(this.id);
var aoi = new et2_action_object_impl(this,this.getDOMNode()); var aoi = new et2_action_object_impl(this,this.getDOMNode());
aoi.doTriggerEvent = function(_event, _data) { aoi.doTriggerEvent = function(_event, _data) {
// Determine target node // Determine target node
debugger;
var event = _data.event || false; var event = _data.event || false;
if(!event) return; if(!event) return;
if(_data.ui.draggable.hasClass('rowNoEdit')) return; if(_data.ui.draggable.hasClass('rowNoEdit')) return;
@ -719,6 +718,7 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
{ {
widget_object.setAOI(aoi); widget_object.setAOI(aoi);
} }
this._actionObject = widget_object;
// Delete all old objects // Delete all old objects
widget_object.clear(); widget_object.clear();
@ -731,7 +731,6 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
this._init_links_dnd(widget_object.manager, action_links); this._init_links_dnd(widget_object.manager, action_links);
widget_object.updateActionLinks(action_links); widget_object.updateActionLinks(action_links);
this._actionObject = widget_object;
}, },
/** /**
@ -843,7 +842,9 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
return null; return null;
},true); },true);
} }
if(actionLinks.indexOf(drag_action.id) < 0) // The timegrid itself is not draggable, so don't add a link.
// The action is there for the children (events) to use
if(false && actionLinks.indexOf(drag_action.id) < 0)
{ {
actionLinks.push(drag_action.id); actionLinks.push(drag_action.id);
} }