mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-28 09:38:53 +01:00
Calendar planner:
- Hover shows current time - Clicking a row adds event at that time for that user / category
This commit is contained in:
parent
00b7d2242f
commit
eb999f98a6
@ -100,6 +100,10 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
|
|||||||
this.rows = $j(document.createElement("div"))
|
this.rows = $j(document.createElement("div"))
|
||||||
.appendTo(this.div);
|
.appendTo(this.div);
|
||||||
|
|
||||||
|
this.vertical_bar = $j(document.createElement("div"))
|
||||||
|
.addClass('verticalBar')
|
||||||
|
.appendTo(this.div);
|
||||||
|
|
||||||
// Used for its date calculations
|
// Used for its date calculations
|
||||||
this.date_helper = et2_createWidget('date-time',{},null);
|
this.date_helper = et2_createWidget('date-time',{},null);
|
||||||
this.date_helper.loadingFinished();
|
this.date_helper.loadingFinished();
|
||||||
@ -158,7 +162,6 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
|
|||||||
* than binding it for every calendar event.
|
* than binding it for every calendar event.
|
||||||
*/
|
*/
|
||||||
this.div.on('mouseover', '.calendar_calEvent:not(.ui-resizable):not(.rowNoEdit)', function() {
|
this.div.on('mouseover', '.calendar_calEvent:not(.ui-resizable):not(.rowNoEdit)', function() {
|
||||||
|
|
||||||
// Load the event
|
// Load the event
|
||||||
planner._get_event_info(this);
|
planner._get_event_info(this);
|
||||||
var that = this;
|
var that = this;
|
||||||
@ -247,6 +250,35 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
|
|||||||
},ui.helper.outerHeight());
|
},ui.helper.outerHeight());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
})
|
||||||
|
.on('mousemove', function(event) {
|
||||||
|
// Position bar by mouse
|
||||||
|
planner.vertical_bar.position({
|
||||||
|
my: 'right-1',
|
||||||
|
of: event,
|
||||||
|
collision: 'fit'
|
||||||
|
});
|
||||||
|
planner.vertical_bar.css('top','0px');
|
||||||
|
|
||||||
|
// Get time at mouse
|
||||||
|
if(planner.options.group_by == 'month')
|
||||||
|
{
|
||||||
|
var time = planner._get_time_from_position(event.clientX, event.clientY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var time = planner._get_time_from_position(event.offsetX, event.offsetY);
|
||||||
|
}
|
||||||
|
// Passing to formatter, cancel out timezone
|
||||||
|
if(time)
|
||||||
|
{
|
||||||
|
var formatDate = new Date(time.valueOf() + time.getTimezoneOffset() * 60 * 1000);
|
||||||
|
planner.vertical_bar.html('<span>'+date(egw.preference('timeformat','calendar') == 12 ? 'h:ia' : 'H:i',formatDate)+'</span>');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
planner.vertical_bar.text('');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Customize and override some draggable settings
|
// Customize and override some draggable settings
|
||||||
@ -327,14 +359,14 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
|
|||||||
row.set_label(name);
|
row.set_label(name);
|
||||||
}
|
}
|
||||||
},user);
|
},user);
|
||||||
labels.push({id: user, label: label});
|
labels.push({id: user, label: label, data: {participants:user,owner:''}});
|
||||||
}
|
}
|
||||||
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.push({id: id, label: result[id]});
|
this.push({id: id, label: result[id], data: {participants:id,owner:''}});
|
||||||
}
|
}
|
||||||
},labels);
|
},labels);
|
||||||
}
|
}
|
||||||
@ -345,7 +377,7 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
|
|||||||
{
|
{
|
||||||
if(accounts[j].value === user)
|
if(accounts[j].value === user)
|
||||||
{
|
{
|
||||||
labels.push({id: user, label: accounts[j].label});
|
labels.push({id: user, label: accounts[j].label, data: {participants:user,owner:''}});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -475,7 +507,11 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
|
|||||||
draw_row: function(sort_key, label, events)
|
draw_row: function(sort_key, label, events)
|
||||||
{
|
{
|
||||||
var key = sort_key.split('-');
|
var key = sort_key.split('-');
|
||||||
this._drawRow(sort_key, label, events, new Date(key[0],key[1],1),new Date(key[0],parseInt(key[1])+1,0));
|
this._drawRow(
|
||||||
|
sort_key, label, events,
|
||||||
|
new Date(key[0]+"-"+sprintf("%02d",parseInt(key[1])+1)+"-01T00:00:00Z"),
|
||||||
|
new Date(key[0],parseInt(key[1])+1,0)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Group by category has one row for each [sub]category
|
// Group by category has one row for each [sub]category
|
||||||
@ -508,7 +544,7 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
row_labels: function() {
|
row_labels: function() {
|
||||||
return [{id:'',label: egw.lang('none')}];
|
return [{id:'',label: egw.lang('none'), data: {}}];
|
||||||
},
|
},
|
||||||
group: function(labels, rows, event) {
|
group: function(labels, rows, event) {
|
||||||
var label_index = false;
|
var label_index = false;
|
||||||
@ -523,7 +559,7 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
|
|||||||
if(label_index === false)
|
if(label_index === false)
|
||||||
{
|
{
|
||||||
label_index = labels.length;
|
label_index = labels.length;
|
||||||
labels.push({id: event.category, label: ''});
|
labels.push({id: event.category, label: '', data: {cat_id:event.category}});
|
||||||
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({
|
||||||
@ -685,7 +721,13 @@ 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,labels[key].id, labels[key].label, events[key] || []);
|
var row = grouper.draw_row.call(this,labels[key].id, labels[key].label, events[key] || []);
|
||||||
|
|
||||||
|
// Add extra data for clicking on row
|
||||||
|
for(var extra in labels[key].data)
|
||||||
|
{
|
||||||
|
row.getDOMNode().dataset[extra] = labels[key].data[extra];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust header if there's a scrollbar
|
// Adjust header if there's a scrollbar
|
||||||
@ -720,6 +762,8 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
|
|||||||
|
|
||||||
// Add actual events
|
// Add actual events
|
||||||
row._update_events(events);
|
row._update_events(events);
|
||||||
|
|
||||||
|
return row;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -1531,7 +1575,7 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
|
|||||||
}
|
}
|
||||||
|
|
||||||
var old_date = this.options.start_date;
|
var old_date = this.options.start_date;
|
||||||
this.options.start_date = this.date_helper.getValue();
|
this.options.start_date = new Date(this.date_helper.getValue());
|
||||||
|
|
||||||
if(old_date !== this.options.start_date && this.isAttached())
|
if(old_date !== this.options.start_date && this.isAttached())
|
||||||
{
|
{
|
||||||
@ -1567,7 +1611,7 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
|
|||||||
this.date_helper.set_minutes(59);
|
this.date_helper.set_minutes(59);
|
||||||
this.date_helper.date.setSeconds(59);
|
this.date_helper.date.setSeconds(59);
|
||||||
var old_date = this.options.end_date;
|
var old_date = this.options.end_date;
|
||||||
this.options.end_date = this.date_helper.getValue();
|
this.options.end_date = new Date(this.date_helper.getValue());
|
||||||
|
|
||||||
if(old_date !== this.options.end_date && this.isAttached())
|
if(old_date !== this.options.end_date && this.isAttached())
|
||||||
{
|
{
|
||||||
@ -1711,6 +1755,26 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (!event.id)
|
||||||
|
{
|
||||||
|
// Clicked in row, but not on an event
|
||||||
|
// Default handler to open a new event at the selected time
|
||||||
|
if(this.options.group_by == 'month')
|
||||||
|
{
|
||||||
|
var date = this._get_time_from_position(_ev.clientX, _ev.clientY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var date = this._get_time_from_position(_ev.offsetX, _ev.offsetY);
|
||||||
|
}
|
||||||
|
var data = $j(_ev.target).closest('.calendar_plannerRowWidget')[0].dataset || {};
|
||||||
|
this.egw().open(null, 'calendar', 'add', jQuery.extend({
|
||||||
|
start: date.toJSON(),
|
||||||
|
hour: date.getUTCHours(),
|
||||||
|
minute: date.getUTCMinutes()
|
||||||
|
},data) , '_blank');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else if (!jQuery.isEmptyObject(_ev.target.dataset))
|
else if (!jQuery.isEmptyObject(_ev.target.dataset))
|
||||||
@ -1787,9 +1851,38 @@ var et2_calendar_planner = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResize
|
|||||||
y = Math.round(y);
|
y = Math.round(y);
|
||||||
|
|
||||||
var rel_x = Math.min(x / $j('.calendar_eventRows',this.div).width(),1);
|
var rel_x = Math.min(x / $j('.calendar_eventRows',this.div).width(),1);
|
||||||
|
var rel_time = 0;
|
||||||
|
|
||||||
var rel_time = (new Date(this.options.end_date) - new Date(this.options.start_date))*rel_x/1000;
|
// Simple math, the x is offset from start date
|
||||||
this.date_helper.set_value(this.options.start_date);
|
if(this.options.group_by !== 'month')
|
||||||
|
{
|
||||||
|
rel_time = (new Date(this.options.end_date) - new Date(this.options.start_date))*rel_x/1000;
|
||||||
|
this.date_helper.set_value(this.options.start_date.toJSON());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Find the correct row so we know which month, then get the offset
|
||||||
|
var row = $j(document.elementFromPoint(x, y)).closest('.calendar_plannerRowWidget');
|
||||||
|
var row_widget = null;
|
||||||
|
for(var i = 0; i < this._children.length && row.length > 0; i++)
|
||||||
|
{
|
||||||
|
if(this._children[i].div[0] == row[0])
|
||||||
|
{
|
||||||
|
row_widget = this._children[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(row_widget)
|
||||||
|
{
|
||||||
|
rel_x = Math.min((x-row_widget.rows.offset().left)/row_widget.rows.width(),1);
|
||||||
|
rel_time = (new Date(row_widget.options.end_date) - new Date(row_widget.options.start_date))*rel_x/1000;
|
||||||
|
this.date_helper.set_value(row_widget.options.start_date.toJSON());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
var interval = egw.preference('interval','calendar') || 30;
|
var interval = egw.preference('interval','calendar') || 30;
|
||||||
this.date_helper.set_minutes(Math.round(rel_time / (60 * interval))*interval);
|
this.date_helper.set_minutes(Math.round(rel_time / (60 * interval))*interval);
|
||||||
|
|
||||||
|
@ -58,6 +58,10 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM],
|
|||||||
// Used for its date calculations
|
// Used for its date calculations
|
||||||
this.date_helper = et2_createWidget('date-time',{},null);
|
this.date_helper = et2_createWidget('date-time',{},null);
|
||||||
this.date_helper.loadingFinished();
|
this.date_helper.loadingFinished();
|
||||||
|
|
||||||
|
this.set_start_date(this.options.start_date);
|
||||||
|
this.set_end_date(this.options.end_date);
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
doLoadingFinished: function() {
|
doLoadingFinished: function() {
|
||||||
@ -137,6 +141,43 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM],
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the start date
|
||||||
|
*
|
||||||
|
* @param {Date} new_date New end date
|
||||||
|
* @returns {undefined}
|
||||||
|
*/
|
||||||
|
set_start_date: function(new_date)
|
||||||
|
{
|
||||||
|
if(!new_date || new_date === null)
|
||||||
|
{
|
||||||
|
throw exception('Invalid end date. ' + new_date.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.options.start_date = new Date(typeof new_date == 'string' ? new_date : new_date.toJSON());
|
||||||
|
this.options.start_date.setUTCHours(0);
|
||||||
|
this.options.start_date.setUTCMinutes(0);
|
||||||
|
this.options.start_date.setUTCSeconds(0);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.options.end_date = new Date(typeof new_date == 'string' ? new_date : new_date.toJSON());
|
||||||
|
this.options.end_date.setUTCHours(23);
|
||||||
|
this.options.end_date.setUTCMinutes(59);
|
||||||
|
this.options.end_date.setUTCSeconds(59);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark special days (birthdays, holidays) on the planner
|
* Mark special days (birthdays, holidays) on the planner
|
||||||
*
|
*
|
||||||
@ -357,7 +398,6 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM],
|
|||||||
// Basic scaling, doesn't consider working times
|
// Basic scaling, doesn't consider working times
|
||||||
pos = (t - start) / (end - start);
|
pos = (t - start) / (end - start);
|
||||||
|
|
||||||
|
|
||||||
// Month view
|
// Month view
|
||||||
if(this._parent.options.group_by !== 'month')
|
if(this._parent.options.group_by !== 'month')
|
||||||
{
|
{
|
||||||
@ -389,6 +429,11 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM],
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 2678400 is the number of seconds in 31 days
|
||||||
|
//pos = (t - start) / 2678400000;
|
||||||
|
}
|
||||||
pos = 100 * pos;
|
pos = 100 * pos;
|
||||||
|
|
||||||
return pos;
|
return pos;
|
||||||
|
@ -687,8 +687,11 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
|||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
.calendar_eventRows {
|
||||||
|
margin-left: 2px;
|
||||||
|
}
|
||||||
.calendar_plannerWidget .verticalBar {
|
.calendar_plannerWidget .verticalBar {
|
||||||
width: 1px;
|
width: 8ex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
@ -696,6 +699,13 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 40;
|
z-index: 40;
|
||||||
}
|
}
|
||||||
|
.calendar_plannerWidget .verticalBar > span {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
right: 0px;
|
||||||
|
background-color: rgba(255,255,255,.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filler for month with less then 31 days in yearly planner
|
* Filler for month with less then 31 days in yearly planner
|
||||||
|
Loading…
Reference in New Issue
Block a user