mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-26 08:38:54 +01:00
Refactor & more intelligence in grid views for speed improvements
This commit is contained in:
parent
34d896f8ee
commit
7d1de17438
@ -796,6 +796,9 @@ class calendar_ui
|
||||
{
|
||||
$event['app_id'] .= ':'.egw_time::to($event['recur_date'] ? $event['recur_date'] : $event['start'],'ts');
|
||||
}
|
||||
// set id for grid
|
||||
$event['row_id'] = $event['id'].($event['recur_type'] ? ':'.egw_time::to($event['recur_date'] ? $event['recur_date'] : $event['start'],'ts') : '');
|
||||
|
||||
$event['parts'] = implode(",\n",$this->bo->participants($event,false));
|
||||
$event['date'] = $this->bo->date2string($event['start']);
|
||||
|
||||
|
@ -462,9 +462,6 @@ class calendar_uilist extends calendar_ui
|
||||
$event['edit_link'] = $this->popup($view_link).'; return false;';
|
||||
}
|
||||
|
||||
// set id for grid
|
||||
$event['row_id'] = $event['id'].($event['recur_type'] ? ':'.egw_time::to($event['recur_date'] ? $event['recur_date'] : $event['start'],'ts') : '');
|
||||
|
||||
// Format start and end with timezone
|
||||
foreach(array('start','end') as $time)
|
||||
{
|
||||
|
@ -661,20 +661,36 @@ class calendar_uiviews extends calendar_ui
|
||||
|
||||
$content = array('view' => array());
|
||||
|
||||
// Always do 7 days for a week so scrolling works properly
|
||||
$this->last = ($days == 4 ? $this->last : $search_params['end'] = strtotime("+$days days",$this->first) - 1);
|
||||
if (count($users) == 1 || count($users) >= $this->cal_prefs['week_consolidate']) // for more then X users, show all in one row
|
||||
if(!$home)
|
||||
{
|
||||
$content['view'][] = (array)$this->tagWholeDayOnTop($this->bo->search($search_params)) +
|
||||
array('owner' => $users);
|
||||
// Fill with the minimum needed 'weeks'
|
||||
$min = max(
|
||||
6, // Some months need 6 weeks for full display
|
||||
$this->cal_prefs['multiple_weeks'], // WeekN view
|
||||
$this->cal_prefs['week_consolidate'] // We collapse after this many users
|
||||
);
|
||||
for($i = 0; $i < $min; $i++)
|
||||
{
|
||||
$content['view'][] = array();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($this->_get_planner_users(false) as $uid => $label)
|
||||
// Always do 7 days for a week so scrolling works properly
|
||||
$this->last = ($days == 4 ? $this->last : $search_params['end'] = strtotime("+$days days",$this->first) - 1);
|
||||
if (count($users) == 1 || count($users) >= $this->cal_prefs['week_consolidate']) // for more then X users, show all in one row
|
||||
{
|
||||
$search_params['users'] = $uid;
|
||||
$content['view'][] = $this->tagWholeDayOnTop($this->bo->search($search_params))
|
||||
+ array('owner' => $uid);
|
||||
$content['view'][] = (array)$this->tagWholeDayOnTop($this->bo->search($search_params)) +
|
||||
array('owner' => $users);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($this->_get_planner_users(false) as $uid => $label)
|
||||
{
|
||||
$search_params['users'] = $uid;
|
||||
$content['view'][] = $this->tagWholeDayOnTop($this->bo->search($search_params))
|
||||
+ array('owner' => $uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
$tmpl = $home ? $home :new etemplate_new('calendar.view');
|
||||
|
@ -1594,7 +1594,7 @@ app.classes.calendar = AppJS.extend(
|
||||
*
|
||||
* @param {Object} _set New settings
|
||||
*/
|
||||
update_state: function(_set)
|
||||
update_state: function update_state(_set)
|
||||
{
|
||||
// Make sure we're running in top window
|
||||
if(window !== window.top)
|
||||
@ -1632,7 +1632,7 @@ app.classes.calendar = AppJS.extend(
|
||||
*
|
||||
* @return {object} description
|
||||
*/
|
||||
getState: function()
|
||||
getState: function getState()
|
||||
{
|
||||
var state = jQuery.extend({},this.state);
|
||||
|
||||
@ -1683,7 +1683,7 @@ app.classes.calendar = AppJS.extend(
|
||||
*
|
||||
* @param {object} state containing "name" attribute to be used as "favorite" GET parameter to a nextmatch
|
||||
*/
|
||||
setState: function(state)
|
||||
setState: function setState(state)
|
||||
{
|
||||
// State should be an object, not a string, but we'll parse
|
||||
if(typeof state == "string")
|
||||
@ -1730,7 +1730,7 @@ app.classes.calendar = AppJS.extend(
|
||||
}
|
||||
|
||||
// Check for valid cache
|
||||
var cachable_changes = ['date','view','days','planner_days','sortby'];
|
||||
var cachable_changes = ['date','weekend','view','days','planner_days','sortby'];
|
||||
var keys = jQuery.unique(Object.keys(this.state).concat(Object.keys(state.state)));
|
||||
for(var i = 0; i < keys.length; i++)
|
||||
{
|
||||
@ -1838,19 +1838,18 @@ app.classes.calendar = AppJS.extend(
|
||||
var grid = view.etemplates[0].widgetContainer.getWidgetById('view');
|
||||
|
||||
/*
|
||||
If the count is different, we need to have the correct number (just remove all & re-create)
|
||||
If the count is different, we need to have the correct number
|
||||
If the count is > 1, it's either because there are multiple date spans (weekN, month) and we need the correct span
|
||||
per row, or there are multiple owners and we need the correct owner per row.
|
||||
*/
|
||||
if(grid && (grid_count !== grid._children.length || grid_count > 1))
|
||||
if(grid)
|
||||
{
|
||||
// Need to redo the number of grids
|
||||
var value = [];
|
||||
state.state.first = view.start_date(state.state).toJSON();
|
||||
// We'll modify this one, so it needs to be a new object
|
||||
var date = new Date(state.state.first);
|
||||
|
||||
// Determine the different end date
|
||||
// Determine the different end date & varying values
|
||||
switch(state.state.view)
|
||||
{
|
||||
case 'month':
|
||||
@ -1861,59 +1860,147 @@ app.classes.calendar = AppJS.extend(
|
||||
for(var week = 0; week < grid_count; week++)
|
||||
{
|
||||
var val = {
|
||||
id: ""+date.getUTCFullYear() + sprintf("%02d",date.getUTCMonth()) + sprintf("%02d",date.getUTCDate()),
|
||||
id: app.classes.calendar._daywise_cache_id(date,state.state.owner),
|
||||
start_date: date.toJSON(),
|
||||
end_date: new Date(date.toJSON()),
|
||||
owner: state.state.owner
|
||||
};
|
||||
val.end_date.setUTCHours(24*7-1);
|
||||
val.end_date.setUTCMinutes(59);
|
||||
val.end_date.setUTCSeconds(59);
|
||||
val.end_date = val.end_date.toJSON();
|
||||
value.push(val);
|
||||
date.setUTCHours(24*7);
|
||||
}
|
||||
state.state.last=val.end_date;
|
||||
break;
|
||||
case 'day':
|
||||
var end = state.state.last = view.end_date(state.state).toJSON();
|
||||
value.push({
|
||||
id: app.classes.calendar._daywise_cache_id(date,state.state.owner),
|
||||
start_date: state.state.first,
|
||||
end_date: state.state.last,
|
||||
owner: view.owner(state.state)
|
||||
});
|
||||
break;
|
||||
default:
|
||||
var end = state.state.last = view.end_date(state.state).toJSON();
|
||||
for(var owner = 0; owner < grid_count && owner < state.state.owner.length; owner++)
|
||||
{
|
||||
var _owner = grid_count > 1 ? state.state.owner[owner] || 0 : state.state.owner
|
||||
value.push({
|
||||
id: ""+date.getUTCFullYear() + sprintf("%02d",date.getUTCMonth()) + sprintf("%02d",date.getUTCDate()),
|
||||
id: app.classes.calendar._daywise_cache_id(date,_owner),
|
||||
start_date: date,
|
||||
end_date: end,
|
||||
owner: grid_count > 1 ? state.state.owner[owner] || 0 : state.state.owner
|
||||
owner: _owner
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
// If we have cached data for the timespan, pass it along
|
||||
this._need_data(value,state.state);
|
||||
if(grid)
|
||||
|
||||
var row_index = 0;
|
||||
|
||||
// Find any matching, existing rows - they can be kept
|
||||
grid.iterateOver(function(widget) {
|
||||
for(var i = 0; i < value.length; i++)
|
||||
{
|
||||
if(widget.id == value[i].id)
|
||||
{
|
||||
// Keep it, but move it
|
||||
if(i > row_index)
|
||||
{
|
||||
for(var j = i-row_index; j > 0; j--)
|
||||
{
|
||||
// Move from the end to the start
|
||||
grid._children.unshift(grid._children.pop());
|
||||
|
||||
// Swap DOM nodes
|
||||
var a = grid._children[0].getDOMNode().parentNode.parentNode;
|
||||
var b = grid._children[1].getDOMNode().parentNode.parentNode;
|
||||
a.parentNode.insertBefore(a,b);
|
||||
}
|
||||
}
|
||||
else if (row_index > i)
|
||||
{
|
||||
for(var j = row_index - i; j > 0; j--)
|
||||
{
|
||||
// Move from the start to the end
|
||||
grid._children.push(grid._children.shift());
|
||||
|
||||
// Swap DOM nodes
|
||||
var a = grid._children[grid._children.length - 1].getDOMNode().parentNode.parentNode;
|
||||
a.parentNode.insertBefore(a,null);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
row_index++;
|
||||
},this,et2_calendar_view);
|
||||
row_index = 0;
|
||||
|
||||
// Set rows that need it
|
||||
grid.iterateOver(function(widget) {
|
||||
if(row_index < value.length)
|
||||
{
|
||||
widget.set_disabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
widget.set_disabled(true);
|
||||
return;
|
||||
}
|
||||
if(widget.set_show_weekend)
|
||||
{
|
||||
widget.set_show_weekend(view.show_weekend(state.state));
|
||||
}
|
||||
if(widget.id == value[row_index].id &&
|
||||
widget.get_end_date().toJSON() == value[row_index].end_date
|
||||
)
|
||||
{
|
||||
// Do not need to re-set this row, but we do need to re-do
|
||||
// the times, as they may have changed
|
||||
widget.invalidate();
|
||||
row_index++;
|
||||
return;
|
||||
}
|
||||
if(widget.set_value)
|
||||
{
|
||||
widget.set_value(value[row_index++]);
|
||||
}
|
||||
},this, et2_calendar_view);
|
||||
grid.iterateOver(function(widget) {
|
||||
if(widget.set_granularity)
|
||||
{
|
||||
widget.set_granularity(view.granularity(state.state));
|
||||
}
|
||||
if(widget.resize)
|
||||
{
|
||||
widget.resize();
|
||||
}
|
||||
},this,et2_calendar_view);
|
||||
|
||||
// Single day with multiple owners still needs owners split to satisfy
|
||||
// caching keys, otherwise they'll cache consolidated
|
||||
if(state.state.view == 'day' && state.state.owner.length < parseInt(this.egw.preference('day_consolidate','calendar')))
|
||||
{
|
||||
grid.set_value(
|
||||
{content: value}
|
||||
);
|
||||
|
||||
// Weekend needs to be done seperately
|
||||
grid.iterateOver(function(widget) {
|
||||
if(widget.set_show_weekend)
|
||||
{
|
||||
widget.set_show_weekend(view.show_weekend(state.state));
|
||||
}
|
||||
},this, et2_calendar_view);
|
||||
|
||||
// Granularity needs to be done seperately
|
||||
grid.iterateOver(function(widget) {
|
||||
if(widget.set_granularity)
|
||||
{
|
||||
widget.set_granularity(view.granularity(state.state));
|
||||
}
|
||||
},this, et2_calendar_view);
|
||||
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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Simple, easy case - just one widget for the selected time span.
|
||||
// Simple, easy case - just one widget for the selected time span. (planner)
|
||||
// Update existing view's special attribute filters, defined in the view list
|
||||
for(var updater in view)
|
||||
{
|
||||
@ -1929,26 +2016,13 @@ app.classes.calendar = AppJS.extend(
|
||||
view.etemplates[i].widgetContainer.iterateOver(function(widget) {
|
||||
if(typeof widget['set_'+updater] === 'function')
|
||||
{
|
||||
widget['set_'+updater](value);
|
||||
widget['set_'+updater](value);
|
||||
}
|
||||
}, 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
|
||||
@ -2488,7 +2562,7 @@ app.classes.calendar = AppJS.extend(
|
||||
{start: start, num_rows:200},
|
||||
query,
|
||||
this.id,
|
||||
function(data) {
|
||||
function calendar_handleResponse(data) {
|
||||
console.log(data);
|
||||
// Look for any updated select options
|
||||
if(data.rows && data.rows.sel_options && this.sidebox_et2)
|
||||
@ -3282,10 +3356,6 @@ jQuery.extend(app.classes.calendar,{
|
||||
// Always 7 days, we just turn weekends on or off
|
||||
d.setUTCHours(24*7-1);
|
||||
return d;
|
||||
},
|
||||
granularity: function(state) {
|
||||
// Does not care how many users you select
|
||||
return parseInt(egw.preference('interval','calendar')) || 30;
|
||||
}
|
||||
}),
|
||||
month: app.classes.calendar.prototype.View.extend({
|
||||
|
@ -93,6 +93,8 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
// Percentage; not yet available
|
||||
titleHeight: 2.0
|
||||
}
|
||||
|
||||
this.registeredUID = null;
|
||||
},
|
||||
|
||||
doLoadingFinished: function() {
|
||||
@ -122,7 +124,7 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
this.date_helper.destroy();
|
||||
this.date_helper = null;
|
||||
|
||||
egw.dataUnregisterUID(app.classes.calendar._daywise_cache_id(this.options.date,this.options.owner),false,this);
|
||||
egw.dataUnregisterUID(this.registeredUID,false,this);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -248,9 +250,11 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.options.date)
|
||||
var cache_id = app.classes.calendar._daywise_cache_id(new_date,this.options.owner);
|
||||
if(this.options.date && this.registeredUID &&
|
||||
cache_id !== this.registeredUID)
|
||||
{
|
||||
egw.dataUnregisterUID(app.classes.calendar._daywise_cache_id(this.options.date,this.options.owner),false,this);
|
||||
egw.dataUnregisterUID(this.registeredUID,false,this);
|
||||
|
||||
// Remove existing events
|
||||
while(this._children.length > 0)
|
||||
@ -271,11 +275,10 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
|
||||
|
||||
// Register for updates on events for this day
|
||||
var cache_id = app.classes.calendar._daywise_cache_id(new_date,this.options.owner);
|
||||
egw.dataRegisterUID(cache_id, this._data_callback,this,this.getInstanceManager().execId,this.id);
|
||||
|
||||
if(events) {
|
||||
this._update_events(events);
|
||||
if(this.registeredUID !== cache_id)
|
||||
{
|
||||
this.registeredUID = cache_id;
|
||||
egw.dataRegisterUID(this.registeredUID, this._data_callback,this,this.getInstanceManager().execId,this.id);
|
||||
}
|
||||
},
|
||||
|
||||
@ -295,17 +298,22 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
return;
|
||||
}
|
||||
|
||||
egw.dataUnregisterUID(app.classes.calendar._daywise_cache_id(this.options.date,this.options.owner),false,this);
|
||||
var cache_id = app.classes.calendar._daywise_cache_id(this.options.date,_owner)
|
||||
if(this.options.date && this.registeredUID &&
|
||||
cache_id !== this.registeredUID)
|
||||
{
|
||||
egw.dataUnregisterUID(this.registeredUID,false,this);
|
||||
}
|
||||
|
||||
this.options.owner = _owner;
|
||||
this.title
|
||||
.attr("data-owner", this.options.owner);
|
||||
|
||||
// Register for updates on events for this day
|
||||
egw.dataRegisterUID(
|
||||
app.classes.calendar._daywise_cache_id(this.options.date,this.options.owner),
|
||||
this._data_callback,this,this.getInstanceManager().execId,this.id
|
||||
);
|
||||
if(this.registeredUID !== cache_id)
|
||||
{
|
||||
this.registeredUID = cache_id;
|
||||
egw.dataRegisterUID(this.registeredUID, this._data_callback,this,this.getInstanceManager().execId,this.id);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -445,22 +453,20 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
{
|
||||
// Create event
|
||||
var event = et2_createWidget('calendar-event',{
|
||||
id:events[c].id,
|
||||
id:'event_'+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.length; c++)
|
||||
{
|
||||
this.getWidgetById(events[c].id).set_value(events[c]);
|
||||
var event = this.getWidgetById('event_'+events[c].id);
|
||||
if(!event) continue;
|
||||
if(this.isInTree())
|
||||
{
|
||||
event.doLoadingFinished();
|
||||
}
|
||||
}
|
||||
|
||||
// Apply styles to hidden events
|
||||
|
@ -97,6 +97,16 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
this.options.date = '';
|
||||
this.set_date(date);
|
||||
}
|
||||
if(this.options.value && this.options.value.row_id)
|
||||
{
|
||||
egw.dataRegisterUID(
|
||||
'calendar::'+this.options.value.row_id,
|
||||
this._UID_callback ,
|
||||
this,
|
||||
this.getInstanceManager().execId,
|
||||
this.id
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
@ -131,47 +141,60 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
// Un-register for updates
|
||||
if(this.options.value)
|
||||
{
|
||||
var old_app_id = this.options.value.app_id;
|
||||
egw.dataUnregisterUID('calendar::'+old_app_id,false,this);
|
||||
var old_id = this.options.value.row_id;
|
||||
if(!_value || !_value.row_id || old_id !== _value.row_id)
|
||||
{
|
||||
egw.dataUnregisterUID('calendar::'+old_id,false,this);
|
||||
}
|
||||
}
|
||||
this.options.value = _value;
|
||||
|
||||
// Register for updates
|
||||
var app_id = this.options.value.app_id;
|
||||
egw.dataRegisterUID('calendar::'+app_id, function _UID_callback(event) {
|
||||
// Make sure id is a string
|
||||
this._values_check(event);
|
||||
|
||||
// Check for changing days in the grid view
|
||||
if(!this._sameday_check(event))
|
||||
{
|
||||
// This should now cease to exist, as new events have been created
|
||||
this.free();
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy to avoid changes, which may cause nm problems
|
||||
this.options.value = jQuery.extend({},event);
|
||||
|
||||
if(this._parent.options.date)
|
||||
{
|
||||
this.options.value.date = this._parent.options.date;
|
||||
}
|
||||
|
||||
// Let parent position
|
||||
this._parent.position_event(this);
|
||||
|
||||
// Parent may remove this if the date isn't the same
|
||||
if(this._parent)
|
||||
{
|
||||
this._update(this.options.value);
|
||||
}
|
||||
|
||||
},this,this.getInstanceManager().execId,this.id);
|
||||
|
||||
if(_value && !egw.dataHasUID('calendar::'+app_id))
|
||||
var id = this.options.value.row_id;
|
||||
if(!old_id || old_id !== id)
|
||||
{
|
||||
egw.dataStoreUID('calendar::'+app_id, _value);
|
||||
egw.dataRegisterUID('calendar::'+id, this._UID_callback ,this,this.getInstanceManager().execId,this.id);
|
||||
}
|
||||
if(_value && !egw.dataHasUID('calendar::'+id))
|
||||
{
|
||||
egw.dataStoreUID('calendar::'+id, _value);
|
||||
}
|
||||
},
|
||||
|
||||
_UID_callback: function _UID_callback(event) {
|
||||
// Make sure id is a string
|
||||
this._values_check(event);
|
||||
|
||||
// Check for changing days in the grid view
|
||||
if(!this._sameday_check(event))
|
||||
{
|
||||
// This should now cease to exist, as new events have been created
|
||||
this.free();
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy to avoid changes, which may cause nm problems
|
||||
this.options.value = jQuery.extend({},event);
|
||||
|
||||
if(this._parent.options.date)
|
||||
{
|
||||
this.options.value.date = this._parent.options.date;
|
||||
}
|
||||
|
||||
// Let parent position
|
||||
this._parent.position_event(this);
|
||||
|
||||
// Parent may remove this if the date isn't the same
|
||||
if(this._parent)
|
||||
{
|
||||
// This gives some slight speed enhancements over doing it immediately,
|
||||
// but it looks weird
|
||||
/*
|
||||
window.setTimeout(jQuery.proxy(function() {
|
||||
if(this.options) this._update(this.options.value);
|
||||
},this),100);
|
||||
*/
|
||||
this._update(this.options.value);
|
||||
}
|
||||
},
|
||||
|
||||
@ -180,15 +203,19 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
// Copy new information
|
||||
this.options.value = event;
|
||||
|
||||
var app_id = event.app_id ? event.app_id : event.id + (event.recur_type ? ':'+event.recur_date : '');
|
||||
var id = event.row_id ? event.row_id : event.id + (event.recur_type ? ':'+event.recur_date : '');
|
||||
this._parent.date_helper.set_value(event.start.valueOf ? new Date(event.start) : event.start);
|
||||
var formatted_start = this._parent.date_helper.getValue();
|
||||
|
||||
this.set_id('event_' + event.app_id);
|
||||
this.set_id('event_' + id);
|
||||
if(this._actionObject)
|
||||
{
|
||||
this._actionObject.id = 'calendar::' + event.app_id;
|
||||
this._actionObject.id = 'calendar::' + id;
|
||||
}
|
||||
|
||||
// Copy actions set in parent
|
||||
this._link_actions(this._parent._parent._parent.options.actions||{});
|
||||
|
||||
// Make sure category stuff is there
|
||||
// Fake it to use the cache / call - if already there, these will return
|
||||
// immediately.
|
||||
@ -217,7 +244,7 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
// Put everything we need for basic interaction here, so it's available immediately
|
||||
.attr('data-id', event.id)
|
||||
.attr('data-app', event.app || 'calendar')
|
||||
.attr('data-app_id', app_id)
|
||||
.attr('data-app_id', event.app_id)
|
||||
.attr('data-start', formatted_start)
|
||||
.attr('data-owner', event.owner)
|
||||
.attr('data-recur_type', event.recur_type)
|
||||
|
@ -692,30 +692,29 @@ var et2_calendar_planner = et2_calendar_view.extend([et2_IDetachedDOM, et2_IResi
|
||||
window.clearTimeout(this.update_timer);
|
||||
}
|
||||
this.update_timer = window.setTimeout(jQuery.proxy(function() {
|
||||
this.doInvalidate = false;
|
||||
|
||||
this.widget.value = this.widget._fetch_data();
|
||||
this.widget.doInvalidate = false;
|
||||
|
||||
// Show AJAX loader
|
||||
framework.applications.calendar.sidemenuEntry.showAjaxLoader();
|
||||
this.widget.loader.show();
|
||||
|
||||
this.widget.value = this.widget._fetch_data();
|
||||
|
||||
this.widget._drawGrid();
|
||||
|
||||
// Update actions
|
||||
if(this._actionManager)
|
||||
if(this.widget._actionManager)
|
||||
{
|
||||
this._link_actions(this._actionManager.children);
|
||||
this.widget._link_actions(this.widget._actionManager.children);
|
||||
}
|
||||
|
||||
// Hide AJAX loader
|
||||
framework.applications.calendar.sidemenuEntry.hideAjaxLoader();
|
||||
|
||||
if(this.trigger)
|
||||
{
|
||||
this.widget.change();
|
||||
}
|
||||
this.widget.update_timer = null;
|
||||
this.doInvalidate = true;
|
||||
this.widget.doInvalidate = true;
|
||||
|
||||
window.setTimeout(jQuery.proxy(function() {this.loader.hide();},this.widget),100);
|
||||
},{widget:this,"trigger":trigger}),ET2_GRID_INVALIDATE_TIMEOUT);
|
||||
},
|
||||
|
||||
|
@ -227,22 +227,20 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
{
|
||||
// Create event
|
||||
var event = et2_createWidget('calendar-event',{
|
||||
id:events[c].id,
|
||||
id:'event_'+events[c].row_id,
|
||||
value: events[c]
|
||||
},this);
|
||||
}
|
||||
|
||||
// Seperate loop so column sorting finds all children in the right place
|
||||
for(var c = 0; c < events.length && c < this._children.length; c++)
|
||||
{
|
||||
var event = this.getWidgetById('event_'+events[c].row_id);
|
||||
if(!event) continue;
|
||||
if(this.isInTree())
|
||||
{
|
||||
event.doLoadingFinished();
|
||||
}
|
||||
|
||||
// Copy actions set in parent
|
||||
event._link_actions(this._parent._parent.options.actions||this._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.length; c++)
|
||||
{
|
||||
this.getWidgetById(events[c].id).set_value(events[c]);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -96,7 +96,8 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
// Contains times / rows
|
||||
this.scrolling = $j(document.createElement('div'))
|
||||
.addClass("calendar_calTimeGridScroll")
|
||||
.appendTo(this.div);
|
||||
.appendTo(this.div)
|
||||
.append('<div class="calendar_calTimeLabels"></div>');
|
||||
|
||||
// Contains days / columns
|
||||
this.days = $j(document.createElement("div"))
|
||||
@ -500,25 +501,31 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
this.day_list = [];
|
||||
|
||||
// Wait a bit to see if anything else changes, then re-draw the days
|
||||
if(this.update_timer === null)
|
||||
if(this.update_timer)
|
||||
{
|
||||
this.update_timer = window.setTimeout(jQuery.proxy(function() {
|
||||
this.widget.update_timer = null;
|
||||
|
||||
// Update actions
|
||||
if(this.widget._actionManager)
|
||||
{
|
||||
this.widget._link_actions(this.widget._actionManager.children);
|
||||
}
|
||||
|
||||
this.widget._drawDays();
|
||||
this.widget._resizeTimes();
|
||||
if(this.trigger)
|
||||
{
|
||||
this.widget.change();
|
||||
}
|
||||
},{widget:this,"trigger":trigger}),ET2_GRID_INVALIDATE_TIMEOUT);
|
||||
window.clearTimeout(this.update_timer);
|
||||
}
|
||||
this.update_timer = window.setTimeout(jQuery.proxy(function() {
|
||||
this.widget.update_timer = null;
|
||||
this.widget.loader.hide().show();
|
||||
|
||||
// Update actions
|
||||
if(this.widget._actionManager)
|
||||
{
|
||||
this.widget._link_actions(this.widget._actionManager.children);
|
||||
}
|
||||
|
||||
this.widget._drawDays();
|
||||
// We have to completely re-do times, as they may have changed in
|
||||
// scale to the point where more labels are needed / need to be removed
|
||||
this.widget._drawTimes();
|
||||
if(this.trigger)
|
||||
{
|
||||
this.widget.change();
|
||||
}
|
||||
// Hide loader
|
||||
window.setTimeout(jQuery.proxy(function() {this.loader.hide();},this.widget),100);
|
||||
},{widget:this,"trigger":trigger}),ET2_GRID_INVALIDATE_TIMEOUT);
|
||||
},
|
||||
|
||||
detachFromDOM: function() {
|
||||
@ -562,6 +569,14 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
}
|
||||
},
|
||||
|
||||
set_disabled: function(disabled) {
|
||||
this._super.apply(this, arguments);
|
||||
if(disabled)
|
||||
{
|
||||
this.loader.show();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear everything, and redraw the whole grid
|
||||
*/
|
||||
@ -569,6 +584,7 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
|
||||
this.div.css('height', this.options.height)
|
||||
.empty();
|
||||
this.loader.prependTo(this.div).show();
|
||||
|
||||
// Draw in the horizontal - the times
|
||||
this._drawTimes();
|
||||
@ -605,7 +621,6 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
this.scrolling
|
||||
.css('height', (this.div.innerHeight() - header_height)+'px')
|
||||
.appendTo(this.div)
|
||||
.empty()
|
||||
.off().on('scroll', jQuery.proxy(this._scroll, this));
|
||||
|
||||
// Percent
|
||||
@ -616,8 +631,16 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
// We need a reasonable bottom limit here...
|
||||
if(this.rowHeight < 5 && this.div.is(':visible'))
|
||||
{
|
||||
this.options.granularity *= 2;
|
||||
return this._drawTimes();
|
||||
if(this.rowHeight === 0)
|
||||
{
|
||||
// Something is not right...
|
||||
this.rowHeight = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.options.granularity *= 2;
|
||||
return this._drawTimes();
|
||||
}
|
||||
}
|
||||
|
||||
// the hour rows
|
||||
@ -659,8 +682,9 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
}
|
||||
|
||||
// Set heights in pixels for scrolling
|
||||
this.scrolling
|
||||
.append('<div class="calendar_calTimeLabels">' + html + '</div>');
|
||||
$j('.calendar_calTimeLabels',this.scrolling)
|
||||
.empty()
|
||||
.append(html);
|
||||
this.days.css('height', (this.rowHeight*i)+'px');
|
||||
|
||||
// Scroll to start of day
|
||||
@ -797,25 +821,30 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
day.set_left((day_width * i) + 'px');
|
||||
if(daily_owner)
|
||||
{
|
||||
day.set_id(this.day_list[0]+'-'+this.options.owner[i]);
|
||||
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_id(this.day_list[i]);
|
||||
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');
|
||||
}
|
||||
|
||||
// Don't hold on to value any longer, use the data cache for best info
|
||||
this.value = {};
|
||||
|
||||
|
||||
if(daily_owner)
|
||||
{
|
||||
this.set_label('');
|
||||
}
|
||||
|
||||
// Adjust and scroll to start of day
|
||||
this._resizeTimes();
|
||||
|
||||
@ -1190,7 +1219,8 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
set_value: function(events)
|
||||
{
|
||||
if(typeof events !== 'object') return false;
|
||||
|
||||
|
||||
this.loader.show();
|
||||
var use_days_sent = true;
|
||||
|
||||
if(events.id)
|
||||
@ -1198,11 +1228,6 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
this.set_id(events.id);
|
||||
delete events.id;
|
||||
}
|
||||
if(events.owner)
|
||||
{
|
||||
this.set_owner(events.owner);
|
||||
delete events.owner;
|
||||
}
|
||||
if(events.start_date)
|
||||
{
|
||||
this.set_start_date(events.start_date);
|
||||
@ -1215,6 +1240,13 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
delete events.end_date;
|
||||
use_days_sent = false;
|
||||
}
|
||||
// set_owner() wants start_date set to get the correct week number
|
||||
// for the corner label
|
||||
if(events.owner)
|
||||
{
|
||||
this.set_owner(events.owner);
|
||||
delete events.owner;
|
||||
}
|
||||
|
||||
this.value = events || {};
|
||||
|
||||
@ -1230,6 +1262,12 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
|
||||
// Reset and calculate instead of just use the keys so we can get the weekend preference
|
||||
this.day_list = [];
|
||||
|
||||
// None of the above changed anything, hide the loader
|
||||
if(!this.update_timer)
|
||||
{
|
||||
window.setTimeout(jQuery.proxy(function() {this.loader.hide();},this),100);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1244,6 +1282,7 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
var old = this.options.owner || 0;
|
||||
this.owner.set_label('');
|
||||
this.div.removeClass('calendar_TimeGridNoLabel');
|
||||
this.options.owner = _owner;
|
||||
|
||||
if(typeof _owner == 'string' && isNaN(_owner))
|
||||
{
|
||||
@ -1262,7 +1301,7 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
// Label is empty, but give extra space for the owner name
|
||||
this.div.removeClass('calendar_TimeGridNoLabel');
|
||||
}
|
||||
else if (typeof _owner == 'object' && _owner.length)
|
||||
else if (!_owner || typeof _owner == 'object' && _owner.length)
|
||||
{
|
||||
// Don't show owners if more than one, show week number
|
||||
this.owner.set_value('');
|
||||
@ -1275,10 +1314,10 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
{
|
||||
this.owner.options.application = 'home-accounts'
|
||||
this.owner.set_value(typeof _owner == "string" || typeof _owner == "number" ? _owner : jQuery.extend([],_owner));
|
||||
this.set_label('');
|
||||
$j(this.getDOMNode(this.owner)).prepend(this.owner.getDOMNode());
|
||||
}
|
||||
|
||||
this.options.owner = _owner;//this.owner.getValue();
|
||||
if(this.isAttached() && (
|
||||
typeof old == "number" && typeof _owner == "number" && old !== this.options.owner ||
|
||||
// Array of ids will not compare as equal
|
||||
@ -1304,7 +1343,6 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
|
||||
// If it's a short label (eg week number), don't give it an extra line
|
||||
// but is empty, but give extra space for a single owner name
|
||||
this.div.removeClass('calendar_TimeGridNoLabel');
|
||||
this.div.toggleClass('calendar_TimeGridNoLabel', label.trim().length < 6 && typeof this.options.owner === 'object');
|
||||
},
|
||||
|
||||
@ -1318,11 +1356,15 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
// Avoid 0 or less
|
||||
minutes = Math.max(1,minutes);
|
||||
|
||||
if(this.options.granularity != minutes)
|
||||
if(this.options.granularity !== minutes)
|
||||
{
|
||||
this.options.granularity = minutes;
|
||||
this._drawTimes();
|
||||
}
|
||||
else
|
||||
{
|
||||
this._resizeTimes();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1332,9 +1374,10 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
*/
|
||||
set_show_weekend: function(weekends)
|
||||
{
|
||||
weekends = weekends ? true : false;
|
||||
if(this.options.show_weekend !== weekends)
|
||||
{
|
||||
this.options.show_weekend = weekends ? true : false;
|
||||
this.options.show_weekend = weekends;
|
||||
if(this.isAttached())
|
||||
{
|
||||
this.invalidate();
|
||||
@ -1430,7 +1473,7 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
result = this.onclick.apply(this, args);
|
||||
}
|
||||
|
||||
if(event.id && result && !this.options.disabled && !this.options.readonly)
|
||||
if(event.id && result && !this.disabled && !this.options.readonly)
|
||||
{
|
||||
et2_calendar_event.recur_prompt(event);
|
||||
|
||||
@ -1539,33 +1582,35 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
// Resizable interface
|
||||
resize: function ()
|
||||
{
|
||||
if(!this.div.is(':visible'))
|
||||
if(this.disabled || !this.div.is(':visible'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the max width to avoid animations screwing up the width
|
||||
this.div.css('max-width',$j(this.getInstanceManager().DOMContainer).width());
|
||||
|
||||
// We expect the timegrid to be in a table with 0 or more other timegrids,
|
||||
// 1 per row. We want each timegrid to be as large as possible, but space
|
||||
// shared equally. Height can't be set to a percentage on the rows, because
|
||||
// that doesn't work.
|
||||
|
||||
// Find the table
|
||||
var table = this.div.parentsUntil('table').parent();
|
||||
|
||||
// How many rows?
|
||||
var rowCount = table.children('tr').length;
|
||||
var rowCount = 0;
|
||||
this._parent.iterateOver(function(widget) {
|
||||
if(!widget.disabled) rowCount++;
|
||||
},this, et2_calendar_timegrid);
|
||||
|
||||
// Take the whole tab height
|
||||
this.options.height = Math.floor(Math.min($j(this.getInstanceManager().DOMContainer).height(),$j(this.getInstanceManager().DOMContainer).parent().innerHeight()) / rowCount);
|
||||
this.options.height = Math.floor((egw.getHiddenDimensions(this.getInstanceManager().DOMContainer).h ) / rowCount);
|
||||
this.options.height -= 2*((this.div.outerWidth(true) - this.div.innerWidth()) + parseInt(this.div.parent().css('padding-top')));
|
||||
|
||||
if(this.options.height+"px" != this.div.css('height'))
|
||||
if(this.options.height+"px" !== this.div.css('height'))
|
||||
{
|
||||
this.div.css('height', this.options.height);
|
||||
|
||||
// Re-do time grid
|
||||
this._drawGrid();
|
||||
this._drawTimes();
|
||||
|
||||
// Just re-did everything, no need to do more
|
||||
return;
|
||||
@ -1575,8 +1620,6 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes
|
||||
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_widgets.length; i++)
|
||||
|
@ -43,7 +43,7 @@ var et2_calendar_view = et2_valueWidget.extend(
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @memberOf et2_calendar_planner
|
||||
* @memberOf et2_calendar_view
|
||||
* @constructor
|
||||
*/
|
||||
init: function init() {
|
||||
@ -52,6 +52,8 @@ var et2_calendar_view = et2_valueWidget.extend(
|
||||
// Used for its date calculations
|
||||
this.date_helper = et2_createWidget('date-time',{},null);
|
||||
this.date_helper.loadingFinished();
|
||||
|
||||
this.loader = $j('<div class="egw-loading-prompt-container ui-front loading"></div>');
|
||||
},
|
||||
|
||||
destroy: function destroy() {
|
||||
@ -62,22 +64,53 @@ var et2_calendar_view = et2_valueWidget.extend(
|
||||
this.date_helper = null;
|
||||
},
|
||||
|
||||
doLoadingFinished: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.loader.hide(0).prependTo(this.div);
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param {boolean} [trigger_event=false] Trigger an event once things are done.
|
||||
* Waiting until invalidate completes prevents 2 updates when changing the date range.
|
||||
* @returns {undefined}
|
||||
*
|
||||
* @memberOf et2_calendar_view
|
||||
*/
|
||||
invalidate: function invalidate(trigger) {},
|
||||
invalidate: function invalidate(trigger_event) {},
|
||||
|
||||
/**
|
||||
* Returns the current start date
|
||||
*
|
||||
* @returns {Date}
|
||||
*
|
||||
* @memberOf et2_calendar_view
|
||||
*/
|
||||
get_start_date: function get_start_date() {
|
||||
return new Date(this.options.start_date);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the current start date
|
||||
*
|
||||
* @returns {Date}
|
||||
*
|
||||
* @memberOf et2_calendar_view
|
||||
*/
|
||||
get_end_date: function get_end_date() {
|
||||
return new Date(this.options.end_date);
|
||||
},
|
||||
|
||||
/**
|
||||
* Change the start date
|
||||
*
|
||||
* @param {string|number|Date} new_date New starting date
|
||||
* @returns {undefined}
|
||||
*
|
||||
* @memberOf et2_calendar_view
|
||||
*/
|
||||
set_start_date: function set_start_date(new_date)
|
||||
{
|
||||
@ -112,6 +145,8 @@ var et2_calendar_view = et2_valueWidget.extend(
|
||||
*
|
||||
* @param {string|number|Date} new_date New end date
|
||||
* @returns {undefined}
|
||||
*
|
||||
* @memberOf et2_calendar_view
|
||||
*/
|
||||
set_end_date: function set_end_date(new_date)
|
||||
{
|
||||
@ -144,6 +179,8 @@ var et2_calendar_view = et2_valueWidget.extend(
|
||||
* Set which users to display
|
||||
*
|
||||
* @param {number|number[]|string|string[]} _owner Account ID
|
||||
*
|
||||
* @memberOf et2_calendar_view
|
||||
*/
|
||||
set_owner: function set_owner(_owner)
|
||||
{
|
||||
@ -176,6 +213,8 @@ var et2_calendar_view = et2_valueWidget.extend(
|
||||
*
|
||||
* @param {string} user
|
||||
* @returns {string}
|
||||
*
|
||||
* @memberOf et2_calendar_view
|
||||
*/
|
||||
_get_owner_name: function _get_owner_name(user) {
|
||||
if(parseInt(user) === 0)
|
||||
|
@ -61,6 +61,9 @@
|
||||
width: 100%;
|
||||
transition: width 1s ease-in-out;
|
||||
}
|
||||
#calendar-view_view td {
|
||||
padding: 0px;
|
||||
}
|
||||
/* Header classes */
|
||||
tr.dialogHeader td, tr.dialogHeader2 td, tr.dialogHeader3 td, tr.dialogHeader4 td,
|
||||
tr.dialogOperators td,.dialogFooterToolbar {
|
||||
@ -171,6 +174,13 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.calendar_calTimeGrid .loading,.calendar_plannerWidget .loading {
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
position: absolute;
|
||||
}
|
||||
/* single row in the time-line you dont need to set a bgcolor, but you can
|
||||
*/
|
||||
.calendar_calTimeRow {
|
||||
@ -624,7 +634,6 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 99.5%;
|
||||
border: 1px solid gray;
|
||||
padding-right: 3px;
|
||||
}
|
||||
.calendar_plannerWidget > div:not(.calendar_plannerHeader) {
|
||||
@ -723,14 +732,14 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget
|
||||
text-overflow: ellipsis;
|
||||
white-space:nowrap;
|
||||
overflow:hidden;
|
||||
margin-left: 20px;
|
||||
padding-left: 20px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
.calendar_plannerRowHeader:hover {
|
||||
width: initial !important;
|
||||
overflow:visible;
|
||||
z-index: 30;
|
||||
background-color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* calendar_eventRows contain multiple eventRowWidgets
|
||||
|
@ -22,6 +22,7 @@ Egroupware
|
||||
<calendar-timegrid id="${row}"
|
||||
onchange="var state = {}; if(widget.options.start_date == widget.options.end_date) state.view = 'day'; app.calendar.update_state(state);"
|
||||
onevent_change="app.calendar.event_change"
|
||||
disabled="true"
|
||||
>
|
||||
</calendar-timegrid>
|
||||
</row>
|
||||
|
Loading…
Reference in New Issue
Block a user