Single day, multiple owner now shows in a single row

Also start of some refactoring to reduce the same code in multiple places
This commit is contained in:
Nathan Gray 2015-12-28 22:21:47 +00:00
parent bcea893927
commit d9f09e1333
5 changed files with 294 additions and 245 deletions

View File

@ -1824,7 +1824,7 @@ app.classes.calendar = AppJS.extend(
{
case 'day':
case 'day4':
grid_count = state.state.owner.length >= parseInt(this.egw.preference('day_consolidate','calendar')) ? 1 : state.state.owner.length;
grid_count = 1
break;
case 'week':
grid_count = state.state.owner.length >= parseInt(this.egw.preference('week_consolidate','calendar')) ? 1 : state.state.owner.length;
@ -1900,7 +1900,7 @@ app.classes.calendar = AppJS.extend(
{
widget.set_show_weekend(view.show_weekend(state.state));
}
},this, et2_valueWidget);
},this, et2_calendar_view);
// Granularity needs to be done seperately
grid.iterateOver(function(widget) {
@ -1908,7 +1908,7 @@ app.classes.calendar = AppJS.extend(
{
widget.set_granularity(view.granularity(state.state));
}
},this, et2_valueWidget);
},this, et2_calendar_view);
}
}
else
@ -1931,11 +1931,24 @@ app.classes.calendar = AppJS.extend(
{
widget['set_'+updater](value);
}
}, this, et2_valueWidget);
}, this, et2_calendar_view);
}
}
}
var value = [{start_date: state.state.first, end_date: state.state.last}];
// Single day with multiple owners still needs owners split
if(state.state.view == 'day' && state.state.owner.length < parseInt(this.egw.preference('day_consolidate','calendar')))
{
value = [];
for(var i = 0; i < state.state.owner.length; i++)
{
value.push({
start_date: state.state.first,
end_date: state.state.last,
owner: state.state.owner[i]
});
}
}
this._need_data(value,state.state);
}
// Include first & last dates in state, mostly for server side processing
@ -1946,7 +1959,6 @@ app.classes.calendar = AppJS.extend(
for(var i = 0; i < view.etemplates.length; i++)
{
$j(view.etemplates[i].DOMContainer).show();
view.etemplates[i].resize();
}
// Toggle todos
if(state.state.view == 'day' || this.state.view == 'day')
@ -2343,7 +2355,8 @@ app.classes.calendar = AppJS.extend(
* Take the date range(s) in the value and decide if we need to fetch data
* for the date ranges, or if they're already cached fill them in.
*
* @param {
* @param {Object} value
* @param {Object} state
*/
_need_data: function(value, state)
{
@ -2522,7 +2535,7 @@ app.classes.calendar = AppJS.extend(
}
} catch(e) {debugger;}
}
app.calendar.state_update_in_progress = in_progress;
}
}

View File

@ -227,12 +227,16 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM],
sprintf("%02d",this._parent.date_helper.get_date());
// Set label
// Add timezone offset back in, or formatDate will lose those hours
var formatDate = new Date(this.date.valueOf() + this.date.getTimezoneOffset() * 60 * 1000);
var date_string = this._parent._children.length === 1 ?
app.calendar.date.long_date(formatDate,false, false, true) :
jQuery.datepicker.formatDate('DD dd',formatDate);
this.title.text(date_string)
if(!this.options.label)
{
// Add timezone offset back in, or formatDate will lose those hours
var formatDate = new Date(this.date.valueOf() + this.date.getTimezoneOffset() * 60 * 1000);
var date_string = this._parent._children.length === 1 ?
app.calendar.date.long_date(formatDate,false, false, true) :
jQuery.datepicker.formatDate('DD dd',formatDate);
this.title.text(date_string);
}
this.title
.attr("data-date", new_date);
this.header
.attr('data-date',new_date)
@ -294,7 +298,8 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM],
egw.dataUnregisterUID(app.classes.calendar._daywise_cache_id(this.options.date,this.options.owner),false,this);
this.options.owner = _owner;
this.div.attr('data-sortable-id', this.options.owner);
this.title
.attr("data-owner", this.options.owner);
// Register for updates on events for this day
egw.dataRegisterUID(
@ -328,6 +333,10 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM],
this._update_events(events);
},
set_label: function(label) {
this.options.label = label;
this.title.text(label);
},
set_left: function(left) {
// Maybe?
window.setTimeout(jQuery.proxy(function() {

View File

@ -12,7 +12,7 @@
"use strict";
/*egw:uses
/etemplate/js/et2_core_valueWidget;
/calendar/js/et2_widget_view.js;
/calendar/js/et2_widget_planner_row.js;
/calendar/js/et2_widget_event.js;
*/
@ -24,31 +24,17 @@
* @augments et2_valueWidget
* @class
*/
var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizeable],
var et2_calendar_planner = et2_calendar_view.extend([et2_IDetachedDOM, et2_IResizeable],
{
createNamespace: true,
attributes: {
start_date: {
name: "Start date",
type: "any"
},
end_date: {
name: "End date",
type: "any"
},
group_by: {
name: "Group by",
type: "string", // or category ID
default: "0",
description: "Display planner by 'user', 'month', or the given category"
},
owner: {
name: "Owner",
type: "any", // Integer, or array of integers
default: 0,
description: "Account ID number of the calendar owner, if not the current user"
},
filter: {
name: "Filter",
type: "string",
@ -103,10 +89,6 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
this.vertical_bar = $j(document.createElement("div"))
.addClass('verticalBar')
.appendTo(this.div);
// Used for its date calculations
this.date_helper = et2_createWidget('date-time',{},null);
this.date_helper.loadingFinished();
this.value = [];
@ -128,10 +110,6 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
egw.dataUnregisterUID(this.registeredCallbacks[i],false,this);
}
// date_helper has no parent, so we must explicitly remove it
this.date_helper.destroy();
this.date_helper = null;
// Stop the invalidate timer
if(this.update_timer)
{
@ -1631,76 +1609,6 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
}
},
/**
* Change the start date
*
* @param {string|number|Date} new_date New starting date
* @returns {undefined}
*/
set_start_date: function(new_date)
{
if(!new_date || new_date === null)
{
throw new Error('Invalid start date. ' + new_date.toString());
}
// Use date widget's existing functions to deal
if(typeof new_date === "object" || typeof new_date === "string" && new_date.length > 8)
{
this.date_helper.set_value(new_date);
}
else if(typeof new_date === "string")
{
this.date_helper.set_year(new_date.substring(0,4));
this.date_helper.set_month(new_date.substring(4,6));
this.date_helper.set_date(new_date.substring(6,8));
}
var old_date = this.options.start_date;
this.options.start_date = new Date(this.date_helper.getValue());
if(old_date !== this.options.start_date && this.isAttached())
{
this.invalidate(true);
}
},
/**
* Change the end date
*
* @param {string|number|Date} new_date New end date
* @returns {undefined}
*/
set_end_date: function(new_date)
{
if(!new_date || new_date === null)
{
throw new Error('Invalid end date. ' + new_date.toString());
}
// Use date widget's existing functions to deal
if(typeof new_date === "object" || typeof new_date === "string" && new_date.length > 8)
{
this.date_helper.set_value(new_date);
}
else if(typeof new_date === "string")
{
this.date_helper.set_year(new_date.substring(0,4));
this.date_helper.set_month(new_date.substring(4,6));
this.date_helper.set_date(new_date.substring(6,8));
}
this.date_helper.set_hours(23);
this.date_helper.set_minutes(59);
this.date_helper.date.setSeconds(59);
var old_date = this.options.end_date;
this.options.end_date = new Date(this.date_helper.getValue());
if(old_date !== this.options.end_date && this.isAttached())
{
this.invalidate(true);
}
},
/**
* Change how the planner is grouped
*
@ -1722,37 +1630,6 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
}
},
/**
* Set which users to display when filtering, and for rows when grouping by user.
*
* @param {number|number[]} _owner Account ID
*/
set_owner: function(_owner)
{
var old = this.options.owner;
if(!jQuery.isArray(_owner))
{
if(typeof _owner === "string")
{
_owner = _owner.split(',');
}
else
{
_owner = [_owner];
}
}
else
{
_owner = jQuery.extend([],_owner);
}
this.options.owner = _owner;
if(old !== this.options.owner && this.isAttached())
{
this.invalidate(true);
}
},
/**
* Call change handler, if set
*/

View File

@ -12,7 +12,7 @@
"use strict";
/*egw:uses
/etemplate/js/et2_core_valueWidget;
/calendar/js/et2_widget_view.js;
/calendar/js/et2_widget_daycol.js;
/calendar/js/et2_widget_event.js;
*/
@ -24,19 +24,11 @@
*
* @augments et2_DOMWidget
*/
var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizeable],
var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IResizeable],
{
createNamespace: true,
attributes: {
start_date: {
name: "Start date",
type: "any"
},
end_date: {
name: "End date",
type: "any"
},
value: {
type: "any",
description: "An array of events, indexed by date (Ymd format)."
@ -65,13 +57,6 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
default: parseInt(egw.preference('interval','calendar')) || 30,
description: "How many minutes per row"
},
owner: {
name: "Owner",
type: "any", // Integer, or array of integers
default: 0,
description: "Account ID number of the calendar owner, if not the current user"
},
"onchange": {
"name": "onchange",
"type": "js",
@ -118,10 +103,6 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
.addClass("calendar_calDayCols")
.appendTo(this.scrolling);
// Used for its date calculations
this.date_helper = et2_createWidget('date',{},null);
this.date_helper.loadingFinished();
// Used for owners
this.owner = et2_createWidget('select-account_ro',{},this);
@ -166,10 +147,6 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
this.scrolling = null;
this._labelContainer = null;
// date_helper has no parent, so we must explicitly remove it
this.date_helper.destroy();
this.date_helper = null;
// Stop the invalidate timer
if(this.update_timer)
{
@ -510,7 +487,7 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
* The whole grid is not regenerated because times aren't expected to change,
* just the days.
*
* @param {boolean} trigger=false Trigger an event once things are done.
* @param {boolean} [trigger=false] Trigger an event once things are done.
* Waiting until invalidate completes prevents 2 updates when changing the date range.
* @returns {undefined}
*/
@ -740,21 +717,25 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
{
this.day_list = this._calculate_day_list(this.options.start_date, this.options.end_date, this.options.show_weekend);
}
var day_width = ( this.days.width()/this.day_list.length);
// For a single day, we show each owner in their own daycol
var daily_owner = this.day_list.length === 1 && this.options.owner.length < parseInt(egw.preference('day_consolidate','calendar'));
var daycols_needed = daily_owner ? this.options.owner.length : this.day_list.length;
var day_width = ( Math.min( $j(this.getInstanceManager().DOMContainer).width(),this.days.width())/daycols_needed);
if(!day_width || !this.day_list)
{
// Hidden on another tab, or no days for some reason
var dim = egw.getHiddenDimensions(this.days, false);
day_width = ( dim.w /Math.max(this.day_list.length,1));
day_width = ( dim.w /Math.max(daycols_needed,1));
}
// Create any needed widgets - otherwise, we'll just recycle
// Add any needed day widgets (now showing more days)
var add_index = 0;
var before = true;
while(this.day_list.length > this.day_widgets.length)
while(daycols_needed > this.day_widgets.length)
{
var existing_index = this.day_widgets[add_index] ? this.day_list.indexOf(this.day_widgets[add_index].options.date) : -1;
var existing_index = this.day_widgets[add_index] && !daily_owner ? this.day_list.indexOf(this.day_widgets[add_index].options.date) : -1;
before = existing_index > add_index;
var day = et2_createWidget('calendar-daycol',{
@ -779,16 +760,19 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
// Remove any extra day widgets (now showing less)
var delete_index = this.day_widgets.length - 1;
before = false;
while(this.day_widgets.length > this.day_list.length)
while(this.day_widgets.length > daycols_needed)
{
// If we're going down to an existing one, just keep it for cool CSS animation
while(this.day_list.indexOf(this.day_widgets[delete_index].options.date) > -1)
while(delete_index > 1 && this.day_list.indexOf(this.day_widgets[delete_index].options.date) > -1)
{
delete_index--;
before = true;
}
if(delete_index < 0) delete_index = 0;
// Wait until any animations or other timeouts are done
window.setTimeout(jQuery.proxy(function() {
this.div.hide();
this.header.hide();
this.free();
},this.day_widgets[delete_index]),1000);
@ -801,16 +785,27 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
}
// Create / update day widgets with dates and data
for(var i = 0; i < this.day_list.length; i++)
for(var i = 0; i < this.day_widgets.length; i++)
{
day = this.day_widgets[i];
// Position
day.set_left((day_width * i) + 'px');
day.set_date(this.day_list[i], this.value[this.day_list[i]] || false);
day.set_owner(this.options.owner);
day.set_id(this.day_list[i]);
if(daily_owner)
{
day.set_date(this.day_list[0], false);
day.set_owner(this.options.owner[i]);
day.set_id(this.day_list[0]+'-'+this.options.owner[i]);
day.set_label(this._get_owner_name(this.options.owner[i]));
}
else
{
// Go back to self-calculated date
day.set_label('');
day.set_date(this.day_list[i], this.value[this.day_list[i]] || false);
day.set_owner(this.options.owner);
day.set_id(this.day_list[i]);
}
day.set_width(day_width + 'px');
}
@ -1233,73 +1228,6 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
this.day_list = [];
},
/**
* Change the start date
*
* @param {string|number|Date} new_date New starting date
* @returns {undefined}
*/
set_start_date: function(new_date)
{
if(!new_date || new_date === null)
{
throw exception('Invalid start date. ' + new_date.toString());
}
// Use date widget's existing functions to deal
if(typeof new_date === "object" || typeof new_date === "string" && new_date.length > 8)
{
this.date_helper.set_value(new_date);
}
else if(typeof new_date === "string")
{
this.date_helper.set_year(new_date.substring(0,4));
this.date_helper.set_month(new_date.substring(4,6));
this.date_helper.set_date(new_date.substring(6,8));
}
var old_date = this.options.start_date;
this.options.start_date = this.date_helper.getValue();
if(old_date !== this.options.start_date && this.isAttached())
{
this.invalidate(true);
}
},
/**
* Change the end date
*
* @param {string|number|Date} new_date New end date
* @returns {undefined}
*/
set_end_date: function(new_date)
{
if(!new_date || new_date === null)
{
throw exception('Invalid end date. ' + new_date.toString());
}
// Use date widget's existing functions to deal
if(typeof new_date === "object" || typeof new_date === "string" && new_date.length > 8)
{
this.date_helper.set_value(new_date);
}
else if(typeof new_date === "string")
{
this.date_helper.set_year(new_date.substring(0,4));
this.date_helper.set_month(new_date.substring(4,6));
this.date_helper.set_date(new_date.substring(6,8));
}
var old_date = this.options.end_date;
this.options.end_date = this.date_helper.getValue();
if(old_date !== this.options.end_date && this.isAttached())
{
this.invalidate(true);
}
},
/**
* Set which user owns this. Owner is passed along to the individual
* days.
@ -1640,9 +1568,14 @@ var et2_calendar_timegrid = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResiz
}
// Try to resize width, though animations cause problems
var day_width = ( $j(this.getInstanceManager().DOMContainer).width() - (this.div.innerWidth() - this.days.innerWidth()))/this.day_list.length;
var total_width = ( $j(this.getInstanceManager().DOMContainer).width() - (
this.days.innerWidth() ? this.div.innerWidth() - this.days.innerWidth() : 0
));
// Set the max width to avoid animations screwing up the width
this.div.css('max-width',$j(this.getInstanceManager().DOMContainer).width());
var day_width = (total_width > 0 ? total_width : $j(this.getInstanceManager().DOMContainer).width())/this.day_widgets.length;
// update day widgets
for(var i = 0; i < this.day_list.length; i++)
for(var i = 0; i < this.day_widgets.length; i++)
{
var day = this.day_widgets[i];

View File

@ -0,0 +1,217 @@
/*
* Egroupware
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package
* @subpackage
* @link http://www.egroupware.org
* @author Nathan Gray
* @version $Id$
*/
"use strict";
/*egw:uses
/etemplate/js/et2_core_valueWidget;
*/
/**
* Parent class for the various calendar views to reduce copied code
*
* @augments et2_valueWidget
*/
var et2_calendar_view = et2_valueWidget.extend(
{
createNamespace: true,
attributes: {
owner: {
name: "Owner",
type: "any", // Integer, or array of integers, or string like r13 (resources, addressbook)
default: 0,
description: "Account ID number of the calendar owner, if not the current user"
},
start_date: {
name: "Start date",
type: "any"
},
end_date: {
name: "End date",
type: "any"
},
},
/**
* Constructor
*
* @memberOf et2_calendar_planner
* @constructor
*/
init: function init() {
this._super.apply(this, arguments);
// Used for its date calculations
this.date_helper = et2_createWidget('date-time',{},null);
this.date_helper.loadingFinished();
},
destroy: function destroy() {
this._super.apply(this, arguments);
// date_helper has no parent, so we must explicitly remove it
this.date_helper.destroy();
this.date_helper = null;
},
/**
* Something changed, and the view need to be re-drawn. We wait a bit to
* avoid re-drawing twice if start and end date both changed, then recreate
* as needed.
*
* @param {boolean} [trigger=false] Trigger an event once things are done.
* Waiting until invalidate completes prevents 2 updates when changing the date range.
* @returns {undefined}
*/
invalidate: function invalidate(trigger) {},
/**
* Change the start date
*
* @param {string|number|Date} new_date New starting date
* @returns {undefined}
*/
set_start_date: function set_start_date(new_date)
{
if(!new_date || new_date === null)
{
throw exception('Invalid start date. ' + new_date.toString());
}
// Use date widget's existing functions to deal
if(typeof new_date === "object" || typeof new_date === "string" && new_date.length > 8)
{
this.date_helper.set_value(new_date);
}
else if(typeof new_date === "string")
{
this.date_helper.set_year(new_date.substring(0,4));
this.date_helper.set_month(new_date.substring(4,6));
this.date_helper.set_date(new_date.substring(6,8));
}
var old_date = this.options.start_date;
this.options.start_date = this.date_helper.getValue();
if(old_date !== this.options.start_date && this.isAttached())
{
this.invalidate(true);
}
},
/**
* Change the end date
*
* @param {string|number|Date} new_date New end date
* @returns {undefined}
*/
set_end_date: function set_end_date(new_date)
{
if(!new_date || new_date === null)
{
throw exception('Invalid end date. ' + new_date.toString());
}
// Use date widget's existing functions to deal
if(typeof new_date === "object" || typeof new_date === "string" && new_date.length > 8)
{
this.date_helper.set_value(new_date);
}
else if(typeof new_date === "string")
{
this.date_helper.set_year(new_date.substring(0,4));
this.date_helper.set_month(new_date.substring(4,6));
this.date_helper.set_date(new_date.substring(6,8));
}
var old_date = this.options.end_date;
this.options.end_date = this.date_helper.getValue();
if(old_date !== this.options.end_date && this.isAttached())
{
this.invalidate(true);
}
},
/**
* Set which users to display
*
* @param {number|number[]|string|string[]} _owner Account ID
*/
set_owner: function set_owner(_owner)
{
var old = this.options.owner;
if(!jQuery.isArray(_owner))
{
if(typeof _owner === "string")
{
_owner = _owner.split(',');
}
else
{
_owner = [_owner];
}
}
else
{
_owner = jQuery.extend([],_owner);
}
this.options.owner = _owner;
if(old !== this.options.owner && this.isAttached())
{
this.invalidate(true);
}
},
/**
* Calendar supports many different owner types, including users & resources.
* This translates an ID to a user-friendly name.
*
* @param {string} user
* @returns {string}
*/
_get_owner_name: function _get_owner_name(user) {
if(parseInt(user) === 0)
{
// 0 means current user
user = egw.user('account_id');
}
if (isNaN(user)) // resources or contact
{
var application = 'home-accounts';
switch(user[0])
{
case 'c':
application = 'addressbook';
break;
case 'r':
application = 'resources';
this.owner.set_value(_owner.substr(1));
break;
}
// This might not have a value right away
user = egw.link_title(application,user.match(/\d+/)[0]);
}
else // users
{
user = parseInt(user)
var accounts = egw.accounts();
for(var j = 0; j < accounts.length; j++)
{
if(accounts[j].value === user)
{
user = accounts[j].label;
break;
}
}
}
return user;
}
});