Browse Source

[IMP] web_timeline: Several improvements:

* Avoid to display all items of group_by model
* Remove unnecessary readgroup
* Remove dependency on project. Modify module structure. Imporve readme file.
* Add setup.py
pull/1090/head
Adrien Peiffer (ACSONE) 9 years ago
committed by tarteo
parent
commit
b00bfd8643
  1. 75
      web_timeline/README.rst
  2. 6
      web_timeline/__init__.py
  3. 22
      web_timeline/__openerp__.py
  4. 40
      web_timeline/ir_view.py
  5. 5
      web_timeline/models/__init__.py
  6. 25
      web_timeline/models/ir_view.py
  7. 24
      web_timeline/project_view.xml
  8. 40
      web_timeline/static/src/js/web_timeline.js

75
web_timeline/README.rst

@ -1,7 +1,80 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
===============
Timeline Widget Timeline Widget
=============== ===============
!Prototype!
Define a new widget displaying events in an interactive visualization chart. Define a new widget 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
Usage
=====
Example:
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_task_timeline" model="ir.ui.view">
<field name="name">project.task.timeline</field>
<field name="model">project.task</field>
<field name="type">timeline</field>
<field eval="2" name="priority"/>
<field name="arch" type="xml">
<timeline date_start="date_start"
date_stop="date_end"
date_delay='1'
string="Tasks"
default_group_by="user_id" event_open_popup="true" colors="#ec7063:user_id == false;#2ecb71:kanban_state=='done';">
</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>
</data>
</openerp>
.. 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/8.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/web/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed feedback.
Credits
=======
Images
------
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
Contributors
------------
* Laurent Mignon <laurent.mignon@acsone.eu>
* Adrien Peiffer <adrien.peiffer@acsone.eu>
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.
To contribute to this module, please visit https://odoo-community.org.

6
web_timeline/__init__.py

@ -1 +1,5 @@
from . import ir_view
# -*- coding: utf-8 -*-
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import models

22
web_timeline/__openerp__.py

@ -1,16 +1,24 @@
# -*- coding: utf-8 -*-
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{ {
'name': "Web timeline", 'name': "Web timeline",
'summary': """ 'summary': """
Interactive visualization chart to visualize events in time
Interactive visualization chart to visualize events in time
""", """,
"version": "0.1",
"author": "ACSONE SA/NV",
"category": "Acsone",
"version": "8.0.1.0.0",
'author': 'ACSONE SA/NV,'
'Odoo Community Association (OCA)',
"category": "Tools",
"website": "http://acsone.eu", "website": "http://acsone.eu",
'depends': ['web', 'project'],
'qweb': ['static/src/xml/web_timeline.xml'],
'depends': [
'web'
],
'qweb': [
'static/src/xml/web_timeline.xml',
],
'data': [ 'data': [
'views/web_timeline.xml', 'views/web_timeline.xml',
'project_view.xml',
], ],
} }

40
web_timeline/ir_view.py

@ -1,40 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright 2015 ACSONE SA/NV
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models
from openerp import api
TIMELINE_VIEW = ('timeline', 'Timeline')
class IrUIView(models.Model):
_inherit = 'ir.ui.view'
@api.model
def _setup_fields(self):
"""Hack due since the field 'type' is not defined with the new api.
"""
cls = type(self)
type_selection = cls._fields['type'].selection
if TIMELINE_VIEW not in type_selection:
tmp = list(type_selection)
tmp.append(TIMELINE_VIEW)
cls._fields['type'].selection = tuple(set(tmp))
super(IrUIView, self)._setup_fields()

5
web_timeline/models/__init__.py

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import ir_view

25
web_timeline/models/ir_view.py

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models
from openerp import api
TIMELINE_VIEW = ('timeline', 'Timeline')
class IrUIView(models.Model):
_inherit = 'ir.ui.view'
@api.model
def _setup_fields(self):
"""Hack due since the field 'type' is not defined with the new api.
"""
cls = type(self)
type_selection = cls._fields['type'].selection
if TIMELINE_VIEW not in type_selection:
tmp = list(type_selection)
tmp.append(TIMELINE_VIEW)
cls._fields['type'].selection = tuple(set(tmp))
super(IrUIView, self)._setup_fields()

24
web_timeline/project_view.xml

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_task_timeline" model="ir.ui.view">
<field name="name">project.task.timeline</field>
<field name="model">project.task</field>
<field name="type">timeline</field>
<field eval="2" name="priority"/>
<field name="arch" type="xml">
<timeline date_start="date_start"
date_stop="date_end"
date_delay='1'
string="Tasks"
default_group_by="user_id" event_open_popup="true" colors="#ec7063:user_id == false;#2ecb71:kanban_state=='done';">
</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>
</data>
</openerp>

40
web_timeline/static/src/js/web_timeline.js

@ -247,7 +247,6 @@ openerp.web_timeline = function(instance) {
var self = this; var self = this;
self.last_domains = domains; self.last_domains = domains;
self.last_contexts = contexts; self.last_contexts = contexts;
// self.reload_gantt();
// select the group by // select the group by
var n_group_bys = []; var n_group_bys = [];
if (this.fields_view.arch.attrs.default_group_by) { if (this.fields_view.arch.attrs.default_group_by) {
@ -263,14 +262,7 @@ openerp.web_timeline = function(instance) {
})); }));
fields = _.uniq(fields.concat(_.pluck(this.colors, "field").concat(n_group_bys))); fields = _.uniq(fields.concat(_.pluck(this.colors, "field").concat(n_group_bys)));
var group_by = self.fields[_.first(n_group_bys)]
var read_groups = new instance.web.DataSet(this, group_by.relation, group_by.context)
.name_search('', group_by.domain)
.then(function(groups){
self.groups = groups;
});
return $.when(this.has_been_loaded, read_groups).then(function() {
return $.when(this.has_been_loaded).then(function() {
return self.dataset.read_slice(fields, { return self.dataset.read_slice(fields, {
domain: domains, domain: domains,
context: contexts context: contexts
@ -304,18 +296,33 @@ openerp.web_timeline = function(instance) {
var self = this; var self = this;
var data = []; var data = [];
var groups = []; var groups = [];
groups.push({id:-1, content: _t('Undefined')})
_.each(tasks, function(event) { _.each(tasks, function(event) {
data.push(self.event_data_transform(event));
});
_.each(self.groups, function(group){
groups.push({id: group[0], content: group[1]});
if (event[self.date_start]){
data.push(self.event_data_transform(event));
}
}); });
// get the groups
var split_groups = function(tasks, group_bys) {
if (group_bys.length === 0)
return tasks;
var groups = [];
groups.push({id:-1, content: _t('-')})
_.each(tasks, function(task) {
var group_name = task[_.first(group_bys)];
if (group_name) {
var group = _.find(groups, function(group) { return _.isEqual(group.id, group_name[0]); });
if (group === undefined) {
group = {id: group_name[0], content: group_name[1]};
groups.push(group);
}
}
});
return groups;
}
var groups = split_groups(tasks, group_bys);
this.timeline.setGroups(groups); this.timeline.setGroups(groups);
this.timeline.setItems(data); this.timeline.setItems(data);
this.timeline.setWindow(this.current_window); this.timeline.setWindow(this.current_window);
//this.timeline.moveTo(new Date(), true);
//this.timeline.zoom(0.5, new Date());
}, },
do_show: function() { do_show: function() {
@ -394,7 +401,6 @@ openerp.web_timeline = function(instance) {
null, null,
{readonly: true, title: title} {readonly: true, title: title}
); );
//pop.on('closed', self, self.reload);
var form_controller = pop.view_form; var form_controller = pop.view_form;
form_controller.on("load_record", self, function() { form_controller.on("load_record", self, function() {
var footer = pop.$el.closest(".modal").find(".modal-footer"); var footer = pop.$el.closest(".modal").find(".modal-footer");

Loading…
Cancel
Save