|
@ -1,23 +1,26 @@ |
|
|
odoo.define('web_timeline.TimelineRenderer', function (require) { |
|
|
odoo.define('web_timeline.TimelineRenderer', function (require) { |
|
|
"use strict"; |
|
|
|
|
|
|
|
|
"use strict"; |
|
|
|
|
|
|
|
|
var AbstractRenderer = require('web.AbstractRenderer'); |
|
|
|
|
|
var core = require('web.core'); |
|
|
|
|
|
var time = require('web.time'); |
|
|
|
|
|
var utils = require('web.utils'); |
|
|
|
|
|
var session = require('web.session'); |
|
|
|
|
|
var QWeb = require('web.QWeb'); |
|
|
|
|
|
var field_utils = require('web.field_utils'); |
|
|
|
|
|
var TimelineCanvas = require('web_timeline.TimelineCanvas'); |
|
|
|
|
|
|
|
|
var AbstractRenderer = require('web.AbstractRenderer'); |
|
|
|
|
|
var core = require('web.core'); |
|
|
|
|
|
var time = require('web.time'); |
|
|
|
|
|
var utils = require('web.utils'); |
|
|
|
|
|
var session = require('web.session'); |
|
|
|
|
|
var QWeb = require('web.QWeb'); |
|
|
|
|
|
var field_utils = require('web.field_utils'); |
|
|
|
|
|
var TimelineCanvas = require('web_timeline.TimelineCanvas'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var _t = core._t; |
|
|
|
|
|
|
|
|
var _t = core._t; |
|
|
|
|
|
|
|
|
var CalendarRenderer = AbstractRenderer.extend({ |
|
|
|
|
|
|
|
|
var TimelineRenderer = AbstractRenderer.extend({ |
|
|
template: "TimelineView", |
|
|
template: "TimelineView", |
|
|
events: _.extend({}, AbstractRenderer.prototype.events, { |
|
|
events: _.extend({}, AbstractRenderer.prototype.events, { |
|
|
}), |
|
|
}), |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @constructor |
|
|
|
|
|
*/ |
|
|
init: function (parent, state, params) { |
|
|
init: function (parent, state, params) { |
|
|
this._super.apply(this, arguments); |
|
|
this._super.apply(this, arguments); |
|
|
this.modelName = params.model; |
|
|
this.modelName = params.model; |
|
@ -36,6 +39,9 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
this.modelClass = this.view.model; |
|
|
this.modelClass = this.view.model; |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @override |
|
|
|
|
|
*/ |
|
|
start: function () { |
|
|
start: function () { |
|
|
var self = this; |
|
|
var self = this; |
|
|
var attrs = this.arch.attrs; |
|
|
var attrs = this.arch.attrs; |
|
@ -53,6 +59,9 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
this._super.apply(this, self); |
|
|
this._super.apply(this, self); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Triggered when the timeline is attached to the DOM. |
|
|
|
|
|
*/ |
|
|
on_attach_callback: function() { |
|
|
on_attach_callback: function() { |
|
|
var height = this.$el.parent().height() - this.$el.find('.oe_timeline_buttons').height(); |
|
|
var height = this.$el.parent().height() - this.$el.find('.oe_timeline_buttons').height(); |
|
|
if (height > this.min_height) { |
|
|
if (height > this.min_height) { |
|
@ -62,6 +71,9 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @override |
|
|
|
|
|
*/ |
|
|
_render: function () { |
|
|
_render: function () { |
|
|
this.add_events(); |
|
|
this.add_events(); |
|
|
var self = this; |
|
|
var self = this; |
|
@ -74,7 +86,12 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
}); |
|
|
}); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
add_events: function() { |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Binds events to buttons. |
|
|
|
|
|
|
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
|
|
|
add_events: function () { |
|
|
var self = this; |
|
|
var self = this; |
|
|
this.$(".oe_timeline_button_today").click(function() { |
|
|
this.$(".oe_timeline_button_today").click(function() { |
|
|
self._onTodayClicked(); |
|
|
self._onTodayClicked(); |
|
@ -93,6 +110,11 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
}); |
|
|
}); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Set the timeline window to today (day). |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
_onTodayClicked: function () { |
|
|
_onTodayClicked: function () { |
|
|
this.current_window = { |
|
|
this.current_window = { |
|
|
start: new moment(), |
|
|
start: new moment(), |
|
@ -104,22 +126,48 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Scale the timeline window to a day. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
_onScaleDayClicked: function () { |
|
|
_onScaleDayClicked: function () { |
|
|
this._scaleCurrentWindow(24); |
|
|
this._scaleCurrentWindow(24); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Scale the timeline window to a week. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
_onScaleWeekClicked: function () { |
|
|
_onScaleWeekClicked: function () { |
|
|
this._scaleCurrentWindow(24 * 7); |
|
|
this._scaleCurrentWindow(24 * 7); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Scale the timeline window to a month. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
_onScaleMonthClicked: function () { |
|
|
_onScaleMonthClicked: function () { |
|
|
this._scaleCurrentWindow(24 * 30); |
|
|
this._scaleCurrentWindow(24 * 30); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Scale the timeline window to a year. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
_onScaleYearClicked: function () { |
|
|
_onScaleYearClicked: function () { |
|
|
this._scaleCurrentWindow(24 * 365); |
|
|
this._scaleCurrentWindow(24 * 365); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Scales the timeline window based on the current window. |
|
|
|
|
|
* |
|
|
|
|
|
* @param {Integer} factor The timespan (in hours) the window must be scaled to. |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
_scaleCurrentWindow: function (factor) { |
|
|
_scaleCurrentWindow: function (factor) { |
|
|
if (this.timeline) { |
|
|
if (this.timeline) { |
|
|
this.current_window = this.timeline.getWindow(); |
|
|
this.current_window = this.timeline.getWindow(); |
|
@ -128,7 +176,12 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
_computeMode: function() { |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Computes the initial visible window. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
|
|
|
_computeMode: function () { |
|
|
if (this.mode) { |
|
|
if (this.mode) { |
|
|
var start = false, end = false; |
|
|
var start = false, end = false; |
|
|
switch (this.mode) { |
|
|
switch (this.mode) { |
|
@ -154,6 +207,11 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Initializes the timeline (http://visjs.org/docs/timeline/).
|
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
init_timeline: function () { |
|
|
init_timeline: function () { |
|
|
var self = this; |
|
|
var self = this; |
|
|
this._computeMode(); |
|
|
this._computeMode(); |
|
@ -205,14 +263,24 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
}); |
|
|
}); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
draw_canvas: function() { |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Clears and draws the canvas items. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
|
|
|
draw_canvas: function () { |
|
|
this.canvas.clear(); |
|
|
this.canvas.clear(); |
|
|
if (this.dependency_arrow) { |
|
|
if (this.dependency_arrow) { |
|
|
this.draw_dependencies(); |
|
|
this.draw_dependencies(); |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
draw_dependencies: function() { |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Draw item dependencies on canvas. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
|
|
|
draw_dependencies: function () { |
|
|
var self = this; |
|
|
var self = this; |
|
|
var items = this.timeline.itemSet.items; |
|
|
var items = this.timeline.itemSet.items; |
|
|
_.each(items, function(item) { |
|
|
_.each(items, function(item) { |
|
@ -227,7 +295,17 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
}); |
|
|
}); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
draw_dependency: function(from, to, options) { |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Draws a dependency arrow between 2 timeline items. |
|
|
|
|
|
* |
|
|
|
|
|
* @param {Object} from Start timeline item |
|
|
|
|
|
* @param {Object} to Destination timeline item |
|
|
|
|
|
* @param {Object} options |
|
|
|
|
|
* @param {Object} options.line_color Color of the line |
|
|
|
|
|
* @param {Object} options.line_width The width of the line |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
|
|
|
draw_dependency: function (from, to, options) { |
|
|
if (!from.displayed || !to.displayed) { |
|
|
if (!from.displayed || !to.displayed) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
@ -240,6 +318,12 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
this.canvas.draw_arrow(from.dom.box, to.dom.box, defaults.line_color, defaults.line_width); |
|
|
this.canvas.draw_arrow(from.dom.box, to.dom.box, defaults.line_color, defaults.line_width); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Load display_name of records. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
* @returns {jQuery.Deferred} |
|
|
|
|
|
*/ |
|
|
on_data_loaded: function (events, group_bys, adjust_window) { |
|
|
on_data_loaded: function (events, group_bys, adjust_window) { |
|
|
var self = this; |
|
|
var self = this; |
|
|
var ids = _.pluck(events, "id"); |
|
|
var ids = _.pluck(events, "id"); |
|
@ -262,6 +346,11 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
}); |
|
|
}); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Set groups and events. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
on_data_loaded_2: function (events, group_bys, adjust_window) { |
|
|
on_data_loaded_2: function (events, group_bys, adjust_window) { |
|
|
var self = this; |
|
|
var self = this; |
|
|
var data = []; |
|
|
var data = []; |
|
@ -282,7 +371,12 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
// get the groups
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Get the groups. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
* @returns {Array} |
|
|
|
|
|
*/ |
|
|
split_groups: function (events, group_bys) { |
|
|
split_groups: function (events, group_bys) { |
|
|
if (group_bys.length === 0) { |
|
|
if (group_bys.length === 0) { |
|
|
return events; |
|
|
return events; |
|
@ -310,7 +404,12 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
return groups; |
|
|
return groups; |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/* Transform Odoo event object to timeline event object */ |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Transform Odoo event object to timeline event object. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
* @returns {Object} |
|
|
|
|
|
*/ |
|
|
event_data_transform: function (evt) { |
|
|
event_data_transform: function (evt) { |
|
|
var self = this; |
|
|
var self = this; |
|
|
var date_start = new moment(); |
|
|
var date_start = new moment(); |
|
@ -368,7 +467,14 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
return r; |
|
|
return r; |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
render_timeline_item: function(evt) { |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Render timeline item template. |
|
|
|
|
|
* |
|
|
|
|
|
* @param {Object} evt Record |
|
|
|
|
|
* @private |
|
|
|
|
|
* @returns {String} Rendered template |
|
|
|
|
|
*/ |
|
|
|
|
|
render_timeline_item: function (evt) { |
|
|
if(this.qweb.has_template('timeline-item')) { |
|
|
if(this.qweb.has_template('timeline-item')) { |
|
|
return this.qweb.render('timeline-item', { |
|
|
return this.qweb.render('timeline-item', { |
|
|
'record': evt, |
|
|
'record': evt, |
|
@ -381,8 +487,12 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
); |
|
|
); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Handle a click on a group header. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
on_group_click: function (e) { |
|
|
on_group_click: function (e) { |
|
|
// handle a click on a group header
|
|
|
|
|
|
if (e.what === 'group-label' && e.group !== -1) { |
|
|
if (e.what === 'group-label' && e.group !== -1) { |
|
|
this._trigger(e, function() { |
|
|
this._trigger(e, function() { |
|
|
// Do nothing
|
|
|
// Do nothing
|
|
@ -390,22 +500,47 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Trigger onUpdate. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
on_update: function (item, callback) { |
|
|
on_update: function (item, callback) { |
|
|
this._trigger(item, callback, 'onUpdate'); |
|
|
this._trigger(item, callback, 'onUpdate'); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Trigger onMove. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
on_move: function (item, callback) { |
|
|
on_move: function (item, callback) { |
|
|
this._trigger(item, callback, 'onMove'); |
|
|
this._trigger(item, callback, 'onMove'); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Trigger onRemove. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
on_remove: function (item, callback) { |
|
|
on_remove: function (item, callback) { |
|
|
this._trigger(item, callback, 'onRemove'); |
|
|
this._trigger(item, callback, 'onRemove'); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Trigger onAdd. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
on_add: function (item, callback) { |
|
|
on_add: function (item, callback) { |
|
|
this._trigger(item, callback, 'onAdd'); |
|
|
this._trigger(item, callback, 'onAdd'); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* trigger_up encapsulation adds by default the rights, and the renderer. |
|
|
|
|
|
* |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
_trigger: function (item, callback, trigger) { |
|
|
_trigger: function (item, callback, trigger) { |
|
|
this.trigger_up(trigger, { |
|
|
this.trigger_up(trigger, { |
|
|
'item': item, |
|
|
'item': item, |
|
@ -415,7 +550,7 @@ var CalendarRenderer = AbstractRenderer.extend({ |
|
|
}); |
|
|
}); |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
return CalendarRenderer; |
|
|
|
|
|
|
|
|
return TimelineRenderer; |
|
|
}); |
|
|
}); |