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]))
{
$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));
// 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;
$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)
{
$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;
}
$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->apply('app.calendar.set_state', array($states));
}

View File

@ -124,7 +124,6 @@ app.classes.calendar = AppJS.extend(
var egw_fw = egw_getFramework();
sidebox= $j('#favorite_sidebox_'+this.appname,egw_fw.sidemenuDiv);
}
this._init_sidebox(sidebox);
var content = this.et2.getArrayMgr('content');
@ -268,22 +267,36 @@ app.classes.calendar = AppJS.extend(
*/
linkHandler: function(_url)
{
if (_url.match('menuaction=calendar.calendar_uiviews.index'))
if (_url.match('menuaction=calendar\.calendar_uiviews\.'))
{
var state = this.getState();
if (state.view == 'listview')
{
return _url.replace(/menuaction=[^&]+/, 'menuaction=calendar.calendar_uilist.listview&ajax=true');
}
else if (this.sidebox_et2 && typeof app.classes.calendar.views[state.view] == 'undefined')
var view = _url.match(/calendar_uiviews\.([^&?]+)/);
view = view && view.length > 1 ? view[1] : null;
// Get query
var q = {};
_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);
return true;
}
// Known AJAX view, but not loaded
else if(app.classes.calendar.views[state.view])
// Known AJAX 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)
@ -329,13 +342,12 @@ app.classes.calendar = AppJS.extend(
create: function ()
{
var $sortItem = jQuery(this);
},
start: function (event, ui)
{
$j('.calendar_calTimeGrid',ui.helper).css('position', 'absolute');
// 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);
},this,et2_calendar_timegrid);
},
@ -344,6 +356,7 @@ app.classes.calendar = AppJS.extend(
},
update: function ()
{
var state = app.calendar.getState();
if (state && typeof state.owner !== 'undefined')
{
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];
// Sanitize owner so it's always an array
if(state.state.owner === null)
{
state.state.owner = undefined;
}
switch(typeof state.state.owner)
{
case 'undefined':
state.state.owner = this.egw.user('account_id');
state.state.owner = [this.egw.user('account_id')];
break;
case 'string':
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
* 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
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'))
{
_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
// 'allowed' for this widget at this time
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);
},

View File

@ -295,7 +295,7 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
},
// Labels for the rows
row_labels: function() {
var labels = {};
var labels = [];
var accounts = egw.accounts();
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
{
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
{
egw.accountData(user,'account_fullname',true,function(result) {
for(var id in result)
{
this[id] = result[id];
this.push({id: id, label: result[id]});
}
},labels);
}
else // users
{
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;
}
}
@ -358,14 +374,23 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
for(var user in event.participants)
{
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)
{
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());
},
row_labels: function() {
var labels = {};
var labels = [];
var d = new Date(this.options.start_date);
d = new Date(d.valueOf() + d.getTimezoneOffset() * 60 * 1000);
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);
}
return labels;
@ -396,11 +421,20 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
group: function(labels, rows,event) {
var start = new Date(event.start);
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?
var end = new Date(event.end);
@ -415,7 +449,15 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
month = 1;
}
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
@ -452,17 +494,22 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
}
},
row_labels: function() {
return {'': egw.lang('none')};
return [{id:'',label: egw.lang('none')}];
},
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(typeof labels[event.category] === 'undefined')
if(label_index === false)
{
labels[event.category] = '';
label_index = labels.length;
labels.push({id: event.category, label: ''});
var im = this.getInstanceManager();
// Fake it to use the cache / call
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))
{
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) {
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
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;
},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);
}

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)
// 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());
aoi.doTriggerEvent = function(_event, _data) {
// Determine target node
debugger;
var event = _data.event || false;
if(!event) 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);
}
this._actionObject = widget_object;
// Delete all old objects
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);
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;
},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);
}