mirror of https://github.com/OCA/web.git
[MIG] web_timeline: Migration to 12.0
parent
db826e8163
commit
10dbbc78d8
|
@ -1,16 +1,40 @@
|
||||||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
============
|
||||||
|
Web timeline
|
||||||
|
============
|
||||||
|
|
||||||
|
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
!! This file is generated by oca-gen-addon-readme !!
|
||||||
|
!! changes will be overwritten. !!
|
||||||
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
|
||||||
|
:target: https://odoo-community.org/page/development-status
|
||||||
|
:alt: Production/Stable
|
||||||
|
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
|
||||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||||
:alt: License: AGPL-3
|
:alt: License: AGPL-3
|
||||||
|
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github
|
||||||
|
:target: https://github.com/OCA/web/tree/12.0/web_timeline
|
||||||
|
:alt: OCA/web
|
||||||
|
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
|
||||||
|
:target: https://translation.odoo-community.org/projects/web-12-0/web-12-0-web_timeline
|
||||||
|
:alt: Translate me on Weblate
|
||||||
|
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
|
||||||
|
:target: https://runbot.odoo-community.org/runbot/162/12.0
|
||||||
|
:alt: Try me on Runbot
|
||||||
|
|
||||||
=============
|
|badge1| |badge2| |badge3| |badge4| |badge5|
|
||||||
Timeline view
|
|
||||||
=============
|
|
||||||
|
|
||||||
Define a new view displaying events in an interactive visualization chart.
|
Define a new view displaying events in an interactive visualization chart.
|
||||||
|
|
||||||
The widget is based on the external library
|
The widget is based on the external library
|
||||||
http://visjs.org/timeline_examples.html
|
http://visjs.org/timeline_examples.html
|
||||||
|
|
||||||
|
**Table of contents**
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
@ -119,11 +143,6 @@ new record with the group and start date linked to the area you clicked in.
|
||||||
By holding the Ctrl key and dragging left to right, you can create a new record
|
By holding the Ctrl key and dragging left to right, you can create a new record
|
||||||
with the dragged start and end date.
|
with the dragged start and end date.
|
||||||
|
|
||||||
|
|
||||||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
|
||||||
:alt: Try me on Runbot
|
|
||||||
:target: https://runbot.odoo-community.org/runbot/162/11.0
|
|
||||||
|
|
||||||
Known issues / Roadmap
|
Known issues / Roadmap
|
||||||
======================
|
======================
|
||||||
|
|
||||||
|
@ -132,21 +151,26 @@ Known issues / Roadmap
|
||||||
Bug Tracker
|
Bug Tracker
|
||||||
===========
|
===========
|
||||||
|
|
||||||
Bugs are tracked on `GitHub Issues
|
Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/issues>`_.
|
||||||
<https://github.com/OCA/web/issues>`_. In case of trouble, please
|
In case of trouble, please check there if your issue has already been reported.
|
||||||
check there if your issue has already been reported. If you spotted it first,
|
If you spotted it first, help us smashing it by providing a detailed and welcomed
|
||||||
help us smashing it by providing a detailed and welcomed feedback.
|
`feedback <https://github.com/OCA/web/issues/new?body=module:%20web_timeline%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||||
|
|
||||||
|
Do not contact contributors directly about support or help with technical issues.
|
||||||
|
|
||||||
Credits
|
Credits
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Images
|
Authors
|
||||||
------
|
~~~~~~~
|
||||||
|
|
||||||
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
|
* ACSONE SA/NV
|
||||||
|
* Tecnativa
|
||||||
|
* Monk Software
|
||||||
|
* Onestein
|
||||||
|
|
||||||
Contributors
|
Contributors
|
||||||
------------
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
* Laurent Mignon <laurent.mignon@acsone.eu>
|
* Laurent Mignon <laurent.mignon@acsone.eu>
|
||||||
* Adrien Peiffer <adrien.peiffer@acsone.eu>
|
* Adrien Peiffer <adrien.peiffer@acsone.eu>
|
||||||
|
@ -155,19 +179,35 @@ Contributors
|
||||||
* Adrien Didenot <adrien.didenot@horanet.com>
|
* Adrien Didenot <adrien.didenot@horanet.com>
|
||||||
* Dennis Sluijk <d.sluijk@onestein.nl>
|
* Dennis Sluijk <d.sluijk@onestein.nl>
|
||||||
|
|
||||||
Do not contact contributors directly about support or help with technical issues.
|
Other credits
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
Maintainer
|
Images
|
||||||
----------
|
------
|
||||||
|
|
||||||
|
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
|
||||||
|
|
||||||
|
Maintainers
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
This module is maintained by the OCA.
|
||||||
|
|
||||||
.. image:: https://odoo-community.org/logo.png
|
.. image:: https://odoo-community.org/logo.png
|
||||||
:alt: Odoo Community Association
|
:alt: Odoo Community Association
|
||||||
:target: https://odoo-community.org
|
:target: https://odoo-community.org
|
||||||
|
|
||||||
This module is maintained by the OCA.
|
|
||||||
|
|
||||||
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||||
mission is to support the collaborative development of Odoo features and
|
mission is to support the collaborative development of Odoo features and
|
||||||
promote its widespread use.
|
promote its widespread use.
|
||||||
|
|
||||||
To contribute to this module, please visit https://odoo-community.org.
|
.. |maintainer-tarteo| image:: https://github.com/tarteo.png?size=40px
|
||||||
|
:target: https://github.com/tarteo
|
||||||
|
:alt: tarteo
|
||||||
|
|
||||||
|
Current `maintainer <https://odoo-community.org/page/maintainer-role>`_:
|
||||||
|
|
||||||
|
|maintainer-tarteo|
|
||||||
|
|
||||||
|
This module is part of the `OCA/web <https://github.com/OCA/web/tree/12.0/web_timeline>`_ project on GitHub.
|
||||||
|
|
||||||
|
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
{
|
{
|
||||||
'name': "Web timeline",
|
'name': "Web timeline",
|
||||||
'summary': "Interactive visualization chart to show events in time",
|
'summary': "Interactive visualization chart to show events in time",
|
||||||
"version": "11.0.1.4.0",
|
"version": "12.0.1.0.0",
|
||||||
|
"development_status": "Production/Stable",
|
||||||
'author': 'ACSONE SA/NV, '
|
'author': 'ACSONE SA/NV, '
|
||||||
'Tecnativa, '
|
'Tecnativa, '
|
||||||
'Monk Software, '
|
'Monk Software, '
|
||||||
|
@ -14,7 +15,7 @@
|
||||||
"license": "AGPL-3",
|
"license": "AGPL-3",
|
||||||
"application": False,
|
"application": False,
|
||||||
"installable": True,
|
"installable": True,
|
||||||
"website": "http://acsone.eu",
|
"website": "https://github.com/OCA/web",
|
||||||
'depends': [
|
'depends': [
|
||||||
'web',
|
'web',
|
||||||
],
|
],
|
||||||
|
@ -24,4 +25,5 @@
|
||||||
'data': [
|
'data': [
|
||||||
'views/web_timeline.xml',
|
'views/web_timeline.xml',
|
||||||
],
|
],
|
||||||
|
"maintainers": ["tarteo"],
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
You need to define a view with the tag <timeline> as base element. These are
|
||||||
|
the possible attributes for the tag:
|
||||||
|
|
||||||
|
* date_start (required): it defines the name of the field of type date that
|
||||||
|
contains the start of the event.
|
||||||
|
* date_stop (optional): it defines the name of the field of type date that
|
||||||
|
contains the end of the event. The date_stop can be equal to the attribute
|
||||||
|
date_start to display events has 'point' on the Timeline (instantaneous event)
|
||||||
|
* date_delay (optional): it defines the name of the field of type float/integer
|
||||||
|
that contain the duration in hours of the event, default = 1
|
||||||
|
* default_group_by (required): it defines the name of the field that will be
|
||||||
|
taken as default group by when accessing the view or when no other group by
|
||||||
|
is selected.
|
||||||
|
* zoomKey (optional): Specifies whether the Timeline is only zoomed when an
|
||||||
|
additional key is down. Available values are '' (does not apply), 'altKey',
|
||||||
|
'ctrlKey', or 'metaKey'. Set this option if you want to be able to use the
|
||||||
|
scroll to navigate vertically on views with a lot of events.
|
||||||
|
* mode (optional): Specifies the initial visible window. Available values are:
|
||||||
|
'day' to display the current day, 'week', 'month' and 'fit'.
|
||||||
|
Default value is 'fit' to adjust the visible window such that it fits all items
|
||||||
|
* event_open_popup (optional): when set to true, it allows to edit the events
|
||||||
|
in a popup. If not (default value), the record is edited changing to form
|
||||||
|
view.
|
||||||
|
* colors (optional): it allows to set certain specific colors if the expressed
|
||||||
|
condition (JS syntax) is met.
|
||||||
|
* dependency_arrow (optional): set this attribute to a x2many field to draw
|
||||||
|
arrows between the records referenced in the x2many field.
|
||||||
|
|
||||||
|
Optionally you can declare a custom template, which will be used to render the
|
||||||
|
timeline items. You have to name the template 'timeline-item'.
|
||||||
|
These are the variables available in template rendering:
|
||||||
|
|
||||||
|
* ``record``: to access the fields values selected in the timeline definition.
|
||||||
|
* ``field_utils``: used to format and parse values (see available functions in ``web.field_utils``).
|
||||||
|
|
||||||
|
You also need to declare the view in an action window of the involved model.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="view_task_timeline" model="ir.ui.view">
|
||||||
|
<field name="model">project.task</field>
|
||||||
|
<field name="type">timeline</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<timeline date_start="date_start"
|
||||||
|
date_stop="date_end"
|
||||||
|
string="Tasks"
|
||||||
|
default_group_by="user_id"
|
||||||
|
event_open_popup="true"
|
||||||
|
zoomKey="ctrlKey"
|
||||||
|
colors="#ec7063:user_id == false;#2ecb71:kanban_state=='done';"
|
||||||
|
dependency_arrow="task_dependency_ids">
|
||||||
|
<field name="user_id"/>
|
||||||
|
<templates>
|
||||||
|
<div t-name="timeline-item">
|
||||||
|
<div t-esc="record.display_name"/>
|
||||||
|
Assigned to:
|
||||||
|
<span t-esc="record.user_id[1]"/>
|
||||||
|
</div>
|
||||||
|
</templates>
|
||||||
|
</timeline>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="project.action_view_task" model="ir.actions.act_window">
|
||||||
|
<field name="view_mode">kanban,tree,form,calendar,gantt,timeline,graph</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
|
@ -0,0 +1,6 @@
|
||||||
|
* Laurent Mignon <laurent.mignon@acsone.eu>
|
||||||
|
* Adrien Peiffer <adrien.peiffer@acsone.eu>
|
||||||
|
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
|
||||||
|
* Leonardo Donelli <donelli@webmonks.it>
|
||||||
|
* Adrien Didenot <adrien.didenot@horanet.com>
|
||||||
|
* Dennis Sluijk <d.sluijk@onestein.nl>
|
|
@ -0,0 +1,4 @@
|
||||||
|
Images
|
||||||
|
------
|
||||||
|
|
||||||
|
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
|
|
@ -0,0 +1,4 @@
|
||||||
|
Define a new view displaying events in an interactive visualization chart.
|
||||||
|
|
||||||
|
The widget is based on the external library
|
||||||
|
http://visjs.org/timeline_examples.html
|
|
@ -0,0 +1 @@
|
||||||
|
* Implement a more efficient way of refreshing timeline after a record update.
|
|
@ -0,0 +1,29 @@
|
||||||
|
For accessing the timeline view, you have to click on the button with the clock
|
||||||
|
icon in the view switcher. The first time you access to it, the timeline window
|
||||||
|
is zoomed to fit all the current elements, the same as when you perform a
|
||||||
|
search, filter or group by operation.
|
||||||
|
|
||||||
|
You can use the mouse scroll to zoom in or out in the timeline, and click on
|
||||||
|
any free area and drag for panning the view in that direction.
|
||||||
|
|
||||||
|
The records of your model will be shown as rectangles whose widths are the
|
||||||
|
duration of the event according our definition. You can select them clicking
|
||||||
|
on this rectangle. You can also use Ctrl or Shift keys for adding discrete
|
||||||
|
or range selections. Selected records are hightlighted with a different color
|
||||||
|
(but the difference will be more noticeable depending on the background color).
|
||||||
|
Once selected, you can drag and move the selected records across the timeline.
|
||||||
|
|
||||||
|
When a record is selected, a red cross button appears on the upper left corner
|
||||||
|
that allows to remove that record. This doesn't work for multiple records
|
||||||
|
although they were selected.
|
||||||
|
|
||||||
|
Records are grouped in different blocks depending on the group by criteria
|
||||||
|
selected (if none is specified, then the default group by is applied).
|
||||||
|
Dragging a record from one block to another change the corresponding field to
|
||||||
|
the value that represents the block. You can also click on the group name to
|
||||||
|
edit the involved record directly.
|
||||||
|
|
||||||
|
Double-click on the record to edit it. Double-click in open area to create a
|
||||||
|
new record with the group and start date linked to the area you clicked in.
|
||||||
|
By holding the Ctrl key and dragging left to right, you can create a new record
|
||||||
|
with the dragged start and end date.
|
|
@ -5,14 +5,37 @@ odoo.define('web_timeline.TimelineCanvas', function (require) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var Widget = require('web.Widget');
|
var Widget = require('web.Widget');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to draw stuff on upon the timeline view.
|
||||||
|
*/
|
||||||
var TimelineCanvas = Widget.extend({
|
var TimelineCanvas = Widget.extend({
|
||||||
template: 'TimelineView.Canvas',
|
template: 'TimelineView.Canvas',
|
||||||
|
|
||||||
clear: function() {
|
/**
|
||||||
|
* Clears all drawings (svg elements) from the canvas.
|
||||||
|
*/
|
||||||
|
clear: function () {
|
||||||
this.$el.find(' > :not(defs)').remove();
|
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 halfHeight1 = height1 / 2;
|
||||||
var halfHeight2 = height2 / 2;
|
var halfHeight2 = height2 / 2;
|
||||||
var x1 = coordx1 - widthMarker;
|
var x1 = coordx1 - widthMarker;
|
||||||
|
@ -47,11 +70,32 @@ odoo.define('web_timeline.TimelineCanvas', function (require) {
|
||||||
return points;
|
return points;
|
||||||
},
|
},
|
||||||
|
|
||||||
draw_arrow: function(from, to, color, width) {
|
/**
|
||||||
|
* 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);
|
return this.draw_line(from, to, color, width, '#arrowhead', 10, 12);
|
||||||
},
|
},
|
||||||
|
|
||||||
draw_line: function(from, to, color, width, markerStart, widthMarker, breakLineAt) {
|
/**
|
||||||
|
* 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,
|
var x1 = from.offsetLeft,
|
||||||
y1 = from.offsetTop + from.parentElement.offsetTop,
|
y1 = from.offsetTop + from.parentElement.offsetTop,
|
||||||
x2 = to.offsetLeft,
|
x2 = to.offsetLeft,
|
||||||
|
@ -81,8 +125,7 @@ odoo.define('web_timeline.TimelineCanvas', function (require) {
|
||||||
}
|
}
|
||||||
this.$el.append(line);
|
this.$el.append(line);
|
||||||
return line;
|
return line;
|
||||||
}
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return TimelineCanvas;
|
return TimelineCanvas;
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
odoo.define('web_timeline.TimelineController', function (require) {
|
odoo.define('web_timeline.TimelineController', function (require) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var AbstractController = require('web.AbstractController');
|
var AbstractController = require('web.AbstractController');
|
||||||
var dialogs = require('web.view_dialogs');
|
var dialogs = require('web.view_dialogs');
|
||||||
var core = require('web.core');
|
var core = require('web.core');
|
||||||
var time = require('web.time');
|
var time = require('web.time');
|
||||||
var Dialog = require('web.Dialog');
|
var Dialog = require('web.Dialog');
|
||||||
|
|
||||||
var _t = core._t;
|
var _t = core._t;
|
||||||
|
|
||||||
var CalendarController = AbstractController.extend({
|
var TimelineController = AbstractController.extend({
|
||||||
custom_events: _.extend({}, AbstractController.prototype.custom_events, {
|
custom_events: _.extend({}, AbstractController.prototype.custom_events, {
|
||||||
onGroupClick: '_onGroupClick',
|
onGroupClick: '_onGroupClick',
|
||||||
onUpdate: '_onUpdate',
|
onUpdate: '_onUpdate',
|
||||||
|
@ -18,6 +18,10 @@ var CalendarController = AbstractController.extend({
|
||||||
onAdd: '_onAdd',
|
onAdd: '_onAdd',
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
init: function (parent, model, renderer, params) {
|
init: function (parent, model, renderer, params) {
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
this.open_popup_action = params.open_popup_action;
|
this.open_popup_action = params.open_popup_action;
|
||||||
|
@ -29,7 +33,10 @@ var CalendarController = AbstractController.extend({
|
||||||
this.debouncedInternalMove = _.debounce(this.internalMove, 0);
|
this.debouncedInternalMove = _.debounce(this.internalMove, 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
update: function(params, options) {
|
/**
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
update: function (params, options) {
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
if (_.isEmpty(params)){
|
if (_.isEmpty(params)){
|
||||||
return;
|
return;
|
||||||
|
@ -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) {
|
_onGroupClick: function (event) {
|
||||||
var groupField = this.renderer.last_group_bys[0];
|
var groupField = this.renderer.last_group_bys[0];
|
||||||
return this.do_action({
|
return this.do_action({
|
||||||
|
@ -80,7 +93,12 @@ var CalendarController = AbstractController.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_onUpdate: function(event) {
|
/**
|
||||||
|
* Opens a form view of a clicked timeline item (triggered by the TimelineRenderer).
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_onUpdate: function (event) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.renderer = event.data.renderer;
|
this.renderer = event.data.renderer;
|
||||||
var rights = event.data.rights;
|
var rights = event.data.rights;
|
||||||
|
@ -112,7 +130,12 @@ var CalendarController = AbstractController.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_onMove: function(event) {
|
/**
|
||||||
|
* Gets triggered when a timeline item is moved (triggered by the TimelineRenderer).
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_onMove: function (event) {
|
||||||
var item = event.data.item;
|
var item = event.data.item;
|
||||||
var view = this.renderer.view;
|
var view = this.renderer.view;
|
||||||
var fields = view.fields;
|
var fields = view.fields;
|
||||||
|
@ -150,7 +173,13 @@ var CalendarController = AbstractController.extend({
|
||||||
this.debouncedInternalMove();
|
this.debouncedInternalMove();
|
||||||
},
|
},
|
||||||
|
|
||||||
internalMove: function() {
|
/**
|
||||||
|
* 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 self = this;
|
||||||
var queue = this.moveQueue.slice();
|
var queue = this.moveQueue.slice();
|
||||||
this.moveQueue = [];
|
this.moveQueue = [];
|
||||||
|
@ -175,7 +204,14 @@ var CalendarController = AbstractController.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_onRemove: function(e) {
|
/**
|
||||||
|
* 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;
|
var self = this;
|
||||||
|
|
||||||
function do_it(event) {
|
function do_it(event) {
|
||||||
|
@ -186,9 +222,9 @@ var CalendarController = AbstractController.extend({
|
||||||
[event.data.item.id],
|
[event.data.item.id],
|
||||||
],
|
],
|
||||||
context: self.getSession().user_context,
|
context: self.getSession().user_context,
|
||||||
}).then(function() {
|
}).then(function () {
|
||||||
var unlink_index = false;
|
var unlink_index = false;
|
||||||
for (var i=0; i<self.model.data.data.length; i++) {
|
for (var i = 0; i < self.model.data.data.length; i++) {
|
||||||
if (self.model.data.data[i].id === event.data.item.id) {
|
if (self.model.data.data[i].id === event.data.item.id) {
|
||||||
unlink_index = i;
|
unlink_index = i;
|
||||||
}
|
}
|
||||||
|
@ -214,7 +250,12 @@ var CalendarController = AbstractController.extend({
|
||||||
return def.promise();
|
return def.promise();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onAdd: function(event) {
|
/**
|
||||||
|
* Triggered when a timeline item gets added and opens a form view.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_onAdd: function (event) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var item = event.data.item;
|
var item = event.data.item;
|
||||||
// Initialize default values for creation
|
// Initialize default values for creation
|
||||||
|
@ -224,10 +265,14 @@ var CalendarController = AbstractController.extend({
|
||||||
default_context['default_'.concat(this.date_delay)] = 1;
|
default_context['default_'.concat(this.date_delay)] = 1;
|
||||||
}
|
}
|
||||||
if (this.date_start) {
|
if (this.date_start) {
|
||||||
default_context['default_'.concat(this.date_start)] = moment(item.start).add(1, 'hours').toDate();
|
default_context['default_'.concat(this.date_start)] = moment(item.start).add(1, 'hours').format(
|
||||||
|
'YYYY-MM-DD HH:mm:ss'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (this.date_stop && item.end) {
|
if (this.date_stop && item.end) {
|
||||||
default_context['default_'.concat(this.date_stop)] = moment(item.end).add(1, 'hours').toDate();
|
default_context['default_'.concat(this.date_stop)] = moment(item.end).add(1, 'hours').format(
|
||||||
|
'YYYY-MM-DD HH:mm:ss'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (item.group > 0) {
|
if (item.group > 0) {
|
||||||
default_context['default_'.concat(this.renderer.last_group_bys[0])] = item.group;
|
default_context['default_'.concat(this.renderer.last_group_bys[0])] = item.group;
|
||||||
|
@ -241,13 +286,19 @@ var CalendarController = AbstractController.extend({
|
||||||
on_saved: function (record) {
|
on_saved: function (record) {
|
||||||
self.create_completed([record.res_id]);
|
self.create_completed([record.res_id]);
|
||||||
},
|
},
|
||||||
}).open().on('closed', this, function() {
|
}).open().on('closed', this, function () {
|
||||||
event.data.callback();
|
event.data.callback();
|
||||||
});
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggered upon completion of a new record.
|
||||||
|
* Updates the timeline view with the new record.
|
||||||
|
*
|
||||||
|
* @returns {jQuery.Deferred}
|
||||||
|
*/
|
||||||
create_completed: function (id) {
|
create_completed: function (id) {
|
||||||
var self = this;
|
var self = this;
|
||||||
return this._rpc({
|
return this._rpc({
|
||||||
|
@ -268,6 +319,9 @@ var CalendarController = AbstractController.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggered upon completion of writing a record.
|
||||||
|
*/
|
||||||
write_completed: function (options) {
|
write_completed: function (options) {
|
||||||
var params = {
|
var params = {
|
||||||
domain: this.renderer.last_domains,
|
domain: this.renderer.last_domains,
|
||||||
|
@ -277,7 +331,7 @@ var CalendarController = AbstractController.extend({
|
||||||
|
|
||||||
this.update(params, options);
|
this.update(params, options);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return CalendarController;
|
return TimelineController;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,13 +1,20 @@
|
||||||
odoo.define('web_timeline.TimelineModel', function (require) {
|
odoo.define('web_timeline.TimelineModel', function (require) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var AbstractModel = require('web.AbstractModel');
|
var AbstractModel = require('web.AbstractModel');
|
||||||
|
|
||||||
var TimelineModel = AbstractModel.extend({
|
var TimelineModel = AbstractModel.extend({
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
init: function () {
|
init: function () {
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
load: function (params) {
|
load: function (params) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.modelName = params.modelName;
|
this.modelName = params.modelName;
|
||||||
|
@ -34,6 +41,12 @@ var TimelineModel = AbstractModel.extend({
|
||||||
return this.preload_def.then(this._loadTimeline.bind(this));
|
return this.preload_def.then(this._loadTimeline.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the records for the timeline.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @returns {jQuery.Deferred}
|
||||||
|
*/
|
||||||
_loadTimeline: function () {
|
_loadTimeline: function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
return self._rpc({
|
return self._rpc({
|
||||||
|
@ -52,7 +65,7 @@ var TimelineModel = AbstractModel.extend({
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return TimelineModel;
|
return TimelineModel;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,23 +1,32 @@
|
||||||
odoo.define('web_timeline.TimelineRenderer', function (require) {
|
odoo.define('web_timeline.TimelineRenderer', function (require) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var AbstractRenderer = require('web.AbstractRenderer');
|
var AbstractRenderer = require('web.AbstractRenderer');
|
||||||
var core = require('web.core');
|
var core = require('web.core');
|
||||||
var time = require('web.time');
|
var time = require('web.time');
|
||||||
var utils = require('web.utils');
|
var utils = require('web.utils');
|
||||||
var session = require('web.session');
|
var session = require('web.session');
|
||||||
var QWeb = require('web.QWeb');
|
var QWeb = require('web.QWeb');
|
||||||
var field_utils = require('web.field_utils');
|
var field_utils = require('web.field_utils');
|
||||||
var TimelineCanvas = require('web_timeline.TimelineCanvas');
|
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, {
|
||||||
|
'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) {
|
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 +45,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 +65,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,8 +77,10 @@ var CalendarRenderer = AbstractRenderer.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
_render: function () {
|
_render: function () {
|
||||||
this.add_events();
|
|
||||||
var self = this;
|
var self = this;
|
||||||
return $.when().then(function () {
|
return $.when().then(function () {
|
||||||
// Prevent Double Rendering on Updates
|
// Prevent Double Rendering on Updates
|
||||||
|
@ -74,25 +91,11 @@ var CalendarRenderer = AbstractRenderer.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
add_events: function() {
|
/**
|
||||||
var self = this;
|
* Set the timeline window to today (day).
|
||||||
this.$(".oe_timeline_button_today").click(function() {
|
*
|
||||||
self._onTodayClicked();
|
* @private
|
||||||
});
|
*/
|
||||||
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();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_onTodayClicked: function () {
|
_onTodayClicked: function () {
|
||||||
this.current_window = {
|
this.current_window = {
|
||||||
start: new moment(),
|
start: new moment(),
|
||||||
|
@ -104,22 +107,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 +157,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 +188,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 +244,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 +276,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 +299,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 +327,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 +352,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 +385,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 +448,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 +468,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 +481,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 +531,7 @@ var CalendarRenderer = AbstractRenderer.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return CalendarRenderer;
|
return TimelineRenderer;
|
||||||
});
|
});
|
||||||
|
|
|
@ -39,11 +39,15 @@ odoo.define('web_timeline.TimelineView', function (require) {
|
||||||
Renderer: TimelineRenderer,
|
Renderer: TimelineRenderer,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
init: function (viewInfo, params) {
|
init: function (viewInfo, params) {
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
var self = this;
|
var self = this;
|
||||||
this.timeline = false;
|
this.timeline = false;
|
||||||
this.arch = viewInfo.arch;
|
this.arch = this.rendererParams.arch;
|
||||||
var attrs = this.arch.attrs;
|
var attrs = this.arch.attrs;
|
||||||
this.fields = viewInfo.fields;
|
this.fields = viewInfo.fields;
|
||||||
this.modelName = this.controllerParams.modelName;
|
this.modelName = this.controllerParams.modelName;
|
||||||
|
@ -144,6 +148,9 @@ odoo.define('web_timeline.TimelineView', function (require) {
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Order function for groups.
|
||||||
|
*/
|
||||||
group_order: function (grp1, grp2) {
|
group_order: function (grp1, grp2) {
|
||||||
// display non grouped elements first
|
// display non grouped elements first
|
||||||
if (grp1.id === -1) {
|
if (grp1.id === -1) {
|
||||||
|
@ -156,6 +163,11 @@ odoo.define('web_timeline.TimelineView', function (require) {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the colors attribute.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
parse_colors: function () {
|
parse_colors: function () {
|
||||||
if (this.arch.attrs.colors) {
|
if (this.arch.attrs.colors) {
|
||||||
this.colors = _(this.arch.attrs.colors.split(';')).chain().compact().map(function (color_pair) {
|
this.colors = _(this.arch.attrs.colors.split(';')).chain().compact().map(function (color_pair) {
|
||||||
|
|
Loading…
Reference in New Issue