Browse Source

Merge pull request #1087 from tarteo/11-fix-add-events

[11.0][FIX] web_timeline: add_events call and add jsdocs
pull/1094/head
Pedro M. Baeza 6 years ago
committed by GitHub
parent
commit
5ea07649c0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      web_timeline/__manifest__.py
  2. 49
      web_timeline/static/src/js/timeline_canvas.js
  3. 54
      web_timeline/static/src/js/timeline_controller.js
  4. 13
      web_timeline/static/src/js/timeline_model.js
  5. 166
      web_timeline/static/src/js/timeline_renderer.js
  6. 12
      web_timeline/static/src/js/timeline_view.js

2
web_timeline/__manifest__.py

@ -4,7 +4,7 @@
{
'name': "Web timeline",
'summary': "Interactive visualization chart to show events in time",
"version": "11.0.1.4.0",
"version": "11.0.1.4.1",
'author': 'ACSONE SA/NV, '
'Tecnativa, '
'Monk Software, '

49
web_timeline/static/src/js/timeline_canvas.js

@ -5,14 +5,37 @@ odoo.define('web_timeline.TimelineCanvas', function (require) {
"use strict";
var Widget = require('web.Widget');
/**
* Used to draw stuff on upon the timeline view.
*/
var TimelineCanvas = Widget.extend({
template: 'TimelineView.Canvas',
/**
* Clears all drawings (svg elements) from the canvas.
*/
clear: function () {
this.$el.find(' > :not(defs)').remove();
},
get_polyline_points: function(coordx1, coordy1, coordx2, coordy2, width1, height1, width2, height2, widthMarker, breakAt) {
/**
* Gets the path from one point to another.
*
* @param {Number} coordx1
* @param {Number} coordy1
* @param {Number} coordx2
* @param {Number} coordy2
* @param {Number} width1
* @param {Number} height1
* @param {Number} width2
* @param {Number} height2
* @param {Number} widthMarker The marker's width of the polyline
* @param {Number} breakAt The space between the line turns
* @returns {Array} Each item represents a coordinate
*/
get_polyline_points: function (coordx1, coordy1, coordx2, coordy2,
width1, height1, width2, height2,
widthMarker, breakAt) {
var halfHeight1 = height1 / 2;
var halfHeight2 = height2 / 2;
var x1 = coordx1 - widthMarker;
@ -47,10 +70,31 @@ odoo.define('web_timeline.TimelineCanvas', function (require) {
return points;
},
/**
* Draws an arrow.
*
* @param {HTMLElement} from Element to draw the arrow from
* @param {HTMLElement} to Element to draw the arrow to
* @param {String} color Color of the line
* @param {Number} width Width of the line
* @returns {HTMLElement} The created SVG polyline
*/
draw_arrow: function (from, to, color, width) {
return this.draw_line(from, to, color, width, '#arrowhead', 10, 12);
},
/**
* Draws a line.
*
* @param {HTMLElement} from Element to draw the line from
* @param {HTMLElement} to Element to draw the line to
* @param {String} color Color of the line
* @param {Number} width Width of the line
* @param {String} markerStart Start marker of the line
* @param {Number} widthMarker The marker's width of the polyline
* @param {Number} breakLineAt The space between the line turns
* @returns {HTMLElement} The created SVG polyline
*/
draw_line: function (from, to, color, width, markerStart, widthMarker, breakLineAt) {
var x1 = from.offsetLeft,
y1 = from.offsetTop + from.parentElement.offsetTop,
@ -81,8 +125,7 @@ odoo.define('web_timeline.TimelineCanvas', function (require) {
}
this.$el.append(line);
return line;
}
},
});
return TimelineCanvas;

54
web_timeline/static/src/js/timeline_controller.js

@ -9,7 +9,7 @@ var Dialog = require('web.Dialog');
var _t = core._t;
var CalendarController = AbstractController.extend({
var TimelineController = AbstractController.extend({
custom_events: _.extend({}, AbstractController.prototype.custom_events, {
onGroupClick: '_onGroupClick',
onUpdate: '_onUpdate',
@ -18,6 +18,10 @@ var CalendarController = AbstractController.extend({
onAdd: '_onAdd',
}),
/**
* @constructor
* @override
*/
init: function (parent, model, renderer, params) {
this._super.apply(this, arguments);
this.open_popup_action = params.open_popup_action;
@ -29,6 +33,9 @@ var CalendarController = AbstractController.extend({
this.debouncedInternalMove = _.debounce(this.internalMove, 0);
},
/**
* @override
*/
update: function (params, options) {
this._super.apply(this, arguments);
if (_.isEmpty(params)){
@ -69,6 +76,12 @@ var CalendarController = AbstractController.extend({
});
},
/**
* Gets triggered when a group in the timeline is clicked (by the TimelineRenderer).
*
* @private
* @returns {jQuery.Deferred}
*/
_onGroupClick: function (event) {
var groupField = this.renderer.last_group_bys[0];
return this.do_action({
@ -80,6 +93,11 @@ var CalendarController = AbstractController.extend({
});
},
/**
* Opens a form view of a clicked timeline item (triggered by the TimelineRenderer).
*
* @private
*/
_onUpdate: function (event) {
var self = this;
this.renderer = event.data.renderer;
@ -112,6 +130,11 @@ var CalendarController = AbstractController.extend({
}
},
/**
* Gets triggered when a timeline item is moved (triggered by the TimelineRenderer).
*
* @private
*/
_onMove: function (event) {
var item = event.data.item;
var view = this.renderer.view;
@ -150,6 +173,12 @@ var CalendarController = AbstractController.extend({
this.debouncedInternalMove();
},
/**
* Write enqueued moves to Odoo. After all writes are finished it updates the view once
* (prevents flickering of the view when multiple timeline items are moved at once).
*
* @returns {jQuery.Deferred}
*/
internalMove: function () {
var self = this;
var queue = this.moveQueue.slice();
@ -175,6 +204,13 @@ var CalendarController = AbstractController.extend({
});
},
/**
* Triggered when a timeline item gets removed from the view.
* Requires user confirmation before it gets actually deleted.
*
* @private
* @returns {jQuery.Deferred}
*/
_onRemove: function (e) {
var self = this;
@ -214,6 +250,11 @@ var CalendarController = AbstractController.extend({
return def.promise();
},
/**
* Triggered when a timeline item gets added and opens a form view.
*
* @private
*/
_onAdd: function (event) {
var self = this;
var item = event.data.item;
@ -248,6 +289,12 @@ var CalendarController = AbstractController.extend({
return false;
},
/**
* Triggered upon completion of a new record.
* Updates the timeline view with the new record.
*
* @returns {jQuery.Deferred}
*/
create_completed: function (id) {
var self = this;
return this._rpc({
@ -268,6 +315,9 @@ var CalendarController = AbstractController.extend({
});
},
/**
* Triggered upon completion of writing a record.
*/
write_completed: function (options) {
var params = {
domain: this.renderer.last_domains,
@ -279,5 +329,5 @@ var CalendarController = AbstractController.extend({
},
});
return CalendarController;
return TimelineController;
});

13
web_timeline/static/src/js/timeline_model.js

@ -4,10 +4,17 @@ odoo.define('web_timeline.TimelineModel', function (require) {
var AbstractModel = require('web.AbstractModel');
var TimelineModel = AbstractModel.extend({
/**
* @constructor
*/
init: function () {
this._super.apply(this, arguments);
},
/**
* @override
*/
load: function (params) {
var self = this;
this.modelName = params.modelName;
@ -34,6 +41,12 @@ var TimelineModel = AbstractModel.extend({
return this.preload_def.then(this._loadTimeline.bind(this));
},
/**
* Read the records for the timeline.
*
* @private
* @returns {jQuery.Deferred}
*/
_loadTimeline: function () {
var self = this;
return self._rpc({

166
web_timeline/static/src/js/timeline_renderer.js

@ -13,11 +13,20 @@ var TimelineCanvas = require('web_timeline.TimelineCanvas');
var _t = core._t;
var CalendarRenderer = AbstractRenderer.extend({
var TimelineRenderer = AbstractRenderer.extend({
template: "TimelineView",
events: _.extend({}, AbstractRenderer.prototype.events, {
'click .oe_timeline_button_today': '_onTodayClicked',
'click .oe_timeline_button_scale_day': '_onScaleDayClicked',
'click .oe_timeline_button_scale_week': '_onScaleWeekClicked',
'click .oe_timeline_button_scale_month': '_onScaleMonthClicked',
'click .oe_timeline_button_scale_year': '_onScaleYearClicked',
}),
/**
* @constructor
*/
init: function (parent, state, params) {
this._super.apply(this, arguments);
this.modelName = params.model;
@ -36,6 +45,9 @@ var CalendarRenderer = AbstractRenderer.extend({
this.modelClass = this.view.model;
},
/**
* @override
*/
start: function () {
var self = this;
var attrs = this.arch.attrs;
@ -53,6 +65,9 @@ var CalendarRenderer = AbstractRenderer.extend({
this._super.apply(this, self);
},
/**
* Triggered when the timeline is attached to the DOM.
*/
on_attach_callback: function() {
var height = this.$el.parent().height() - this.$el.find('.oe_timeline_buttons').height();
if (height > this.min_height) {
@ -62,8 +77,10 @@ var CalendarRenderer = AbstractRenderer.extend({
}
},
/**
* @override
*/
_render: function () {
this.add_events();
var self = this;
return $.when().then(function () {
// Prevent Double Rendering on Updates
@ -74,25 +91,11 @@ var CalendarRenderer = AbstractRenderer.extend({
});
},
add_events: function() {
var self = this;
this.$(".oe_timeline_button_today").click(function() {
self._onTodayClicked();
});
this.$(".oe_timeline_button_scale_day").click(function() {
self._onScaleDayClicked();
});
this.$(".oe_timeline_button_scale_week").click(function() {
self._onScaleWeekClicked();
});
this.$(".oe_timeline_button_scale_month").click(function() {
self._onScaleMonthClicked();
});
this.$(".oe_timeline_button_scale_year").click(function() {
self._onScaleYearClicked();
});
},
/**
* Set the timeline window to today (day).
*
* @private
*/
_onTodayClicked: function () {
this.current_window = {
start: new moment(),
@ -104,22 +107,48 @@ var CalendarRenderer = AbstractRenderer.extend({
}
},
/**
* Scale the timeline window to a day.
*
* @private
*/
_onScaleDayClicked: function () {
this._scaleCurrentWindow(24);
},
/**
* Scale the timeline window to a week.
*
* @private
*/
_onScaleWeekClicked: function () {
this._scaleCurrentWindow(24 * 7);
},
/**
* Scale the timeline window to a month.
*
* @private
*/
_onScaleMonthClicked: function () {
this._scaleCurrentWindow(24 * 30);
},
/**
* Scale the timeline window to a year.
*
* @private
*/
_onScaleYearClicked: function () {
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) {
if (this.timeline) {
this.current_window = this.timeline.getWindow();
@ -128,6 +157,11 @@ var CalendarRenderer = AbstractRenderer.extend({
}
},
/**
* Computes the initial visible window.
*
* @private
*/
_computeMode: function () {
if (this.mode) {
var start = false, end = false;
@ -154,6 +188,11 @@ var CalendarRenderer = AbstractRenderer.extend({
}
},
/**
* Initializes the timeline (http://visjs.org/docs/timeline/).
*
* @private
*/
init_timeline: function () {
var self = this;
this._computeMode();
@ -205,6 +244,11 @@ var CalendarRenderer = AbstractRenderer.extend({
});
},
/**
* Clears and draws the canvas items.
*
* @private
*/
draw_canvas: function () {
this.canvas.clear();
if (this.dependency_arrow) {
@ -212,6 +256,11 @@ var CalendarRenderer = AbstractRenderer.extend({
}
},
/**
* Draw item dependencies on canvas.
*
* @private
*/
draw_dependencies: function () {
var self = this;
var items = this.timeline.itemSet.items;
@ -227,6 +276,16 @@ var CalendarRenderer = AbstractRenderer.extend({
});
},
/**
* 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) {
return;
@ -240,6 +299,12 @@ var CalendarRenderer = AbstractRenderer.extend({
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) {
var self = this;
var ids = _.pluck(events, "id");
@ -262,6 +327,11 @@ var CalendarRenderer = AbstractRenderer.extend({
});
},
/**
* Set groups and events.
*
* @private
*/
on_data_loaded_2: function (events, group_bys, adjust_window) {
var self = this;
var data = [];
@ -282,7 +352,12 @@ var CalendarRenderer = AbstractRenderer.extend({
}
},
// get the groups
/**
* Get the groups.
*
* @private
* @returns {Array}
*/
split_groups: function (events, group_bys) {
if (group_bys.length === 0) {
return events;
@ -310,7 +385,12 @@ var CalendarRenderer = AbstractRenderer.extend({
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) {
var self = this;
var date_start = new moment();
@ -368,6 +448,13 @@ var CalendarRenderer = AbstractRenderer.extend({
return r;
},
/**
* 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')) {
return this.qweb.render('timeline-item', {
@ -381,8 +468,12 @@ var CalendarRenderer = AbstractRenderer.extend({
);
},
/**
* Handle a click on a group header.
*
* @private
*/
on_group_click: function (e) {
// handle a click on a group header
if (e.what === 'group-label' && e.group !== -1) {
this._trigger(e, function() {
// Do nothing
@ -390,22 +481,47 @@ var CalendarRenderer = AbstractRenderer.extend({
}
},
/**
* Trigger onUpdate.
*
* @private
*/
on_update: function (item, callback) {
this._trigger(item, callback, 'onUpdate');
},
/**
* Trigger onMove.
*
* @private
*/
on_move: function (item, callback) {
this._trigger(item, callback, 'onMove');
},
/**
* Trigger onRemove.
*
* @private
*/
on_remove: function (item, callback) {
this._trigger(item, callback, 'onRemove');
},
/**
* Trigger onAdd.
*
* @private
*/
on_add: function (item, callback) {
this._trigger(item, callback, 'onAdd');
},
/**
* trigger_up encapsulation adds by default the rights, and the renderer.
*
* @private
*/
_trigger: function (item, callback, trigger) {
this.trigger_up(trigger, {
'item': item,
@ -417,5 +533,5 @@ var CalendarRenderer = AbstractRenderer.extend({
});
return CalendarRenderer;
return TimelineRenderer;
});

12
web_timeline/static/src/js/timeline_view.js

@ -39,6 +39,10 @@ odoo.define('web_timeline.TimelineView', function (require) {
Renderer: TimelineRenderer,
},
/**
* @constructor
* @override
*/
init: function (viewInfo, params) {
this._super.apply(this, arguments);
var self = this;
@ -144,6 +148,9 @@ odoo.define('web_timeline.TimelineView', function (require) {
return this;
},
/**
* Order function for groups.
*/
group_order: function (grp1, grp2) {
// display non grouped elements first
if (grp1.id === -1) {
@ -156,6 +163,11 @@ odoo.define('web_timeline.TimelineView', function (require) {
},
/**
* Parse the colors attribute.
*
* @private
*/
parse_colors: function () {
if (this.arch.attrs.colors) {
this.colors = _(this.arch.attrs.colors.split(';')).chain().compact().map(function (color_pair) {

Loading…
Cancel
Save