diff --git a/setup/web_timeline/odoo_addons/__init__.py b/setup/web_timeline/odoo_addons/__init__.py new file mode 100644 index 00000000..de40ea7c --- /dev/null +++ b/setup/web_timeline/odoo_addons/__init__.py @@ -0,0 +1 @@ +__import__('pkg_resources').declare_namespace(__name__) diff --git a/setup/web_timeline/odoo_addons/web_timeline b/setup/web_timeline/odoo_addons/web_timeline new file mode 120000 index 00000000..8105b4f1 --- /dev/null +++ b/setup/web_timeline/odoo_addons/web_timeline @@ -0,0 +1 @@ +../../../web_timeline \ No newline at end of file diff --git a/setup/web_timeline/setup.py b/setup/web_timeline/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/web_timeline/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/web_timeline/README.rst b/web_timeline/README.rst index a97118b2..e634fd9c 100755 --- a/web_timeline/README.rst +++ b/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 =============== -!Prototype! Define a new widget displaying events in an interactive visualization chart. + The widget is based on the external library http://visjs.org/timeline_examples.html + +Usage +===== + +Example: + + + + + + project.task.timeline + project.task + timeline + + + + + + + + + kanban,tree,form,calendar,gantt,timeline,graph + + + + +.. 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 +`_. 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 `_. + +Contributors +------------ + +* Laurent Mignon +* Adrien Peiffer + +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. \ No newline at end of file diff --git a/web_timeline/__init__.py b/web_timeline/__init__.py index 68f25f6b..444b39cc 100644 --- a/web_timeline/__init__.py +++ b/web_timeline/__init__.py @@ -1 +1,5 @@ -from . import ir_view +# -*- coding: utf-8 -*- +# Copyright 2016 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import models diff --git a/web_timeline/__openerp__.py b/web_timeline/__openerp__.py index bf205575..57ee01b0 100644 --- a/web_timeline/__openerp__.py +++ b/web_timeline/__openerp__.py @@ -1,16 +1,24 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + { 'name': "Web timeline", '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", - 'depends': ['web', 'project'], - 'qweb': ['static/src/xml/web_timeline.xml'], + 'depends': [ + 'web' + ], + 'qweb': [ + 'static/src/xml/web_timeline.xml', + ], 'data': [ 'views/web_timeline.xml', - 'project_view.xml', ], } diff --git a/web_timeline/ir_view.py b/web_timeline/ir_view.py deleted file mode 100644 index efbd8d67..00000000 --- a/web_timeline/ir_view.py +++ /dev/null @@ -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 . -# -############################################################################## -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() diff --git a/web_timeline/models/__init__.py b/web_timeline/models/__init__.py new file mode 100644 index 00000000..81a27ea1 --- /dev/null +++ b/web_timeline/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# © 2016 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import ir_view diff --git a/web_timeline/models/ir_view.py b/web_timeline/models/ir_view.py new file mode 100644 index 00000000..899d4873 --- /dev/null +++ b/web_timeline/models/ir_view.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 ACSONE SA/NV () +# 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() diff --git a/web_timeline/project_view.xml b/web_timeline/project_view.xml deleted file mode 100644 index 0e8e2b21..00000000 --- a/web_timeline/project_view.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - project.task.timeline - project.task - timeline - - - - - - - - - kanban,tree,form,calendar,gantt,timeline,graph - - - diff --git a/web_timeline/static/src/js/web_timeline.js b/web_timeline/static/src/js/web_timeline.js index 6193bde0..7835a213 100644 --- a/web_timeline/static/src/js/web_timeline.js +++ b/web_timeline/static/src/js/web_timeline.js @@ -247,7 +247,6 @@ openerp.web_timeline = function(instance) { var self = this; self.last_domains = domains; self.last_contexts = contexts; - // self.reload_gantt(); // select the group by var n_group_bys = []; 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))); - 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, { domain: domains, context: contexts @@ -304,18 +296,33 @@ openerp.web_timeline = function(instance) { var self = this; var data = []; var groups = []; - groups.push({id:-1, content: _t('Undefined')}) _.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.setItems(data); this.timeline.setWindow(this.current_window); - //this.timeline.moveTo(new Date(), true); - //this.timeline.zoom(0.5, new Date()); }, do_show: function() { @@ -394,7 +401,6 @@ openerp.web_timeline = function(instance) { null, {readonly: true, title: title} ); - //pop.on('closed', self, self.reload); var form_controller = pop.view_form; form_controller.on("load_record", self, function() { var footer = pop.$el.closest(".modal").find(".modal-footer");