[MIG] web_timeline: Finish migration to 13.0

pull/2378/head
Alexandre Díaz 2020-03-23 02:39:25 +01:00 committed by anjeel.haria
parent 18267a7cc2
commit 54706cb673
23 changed files with 2166 additions and 1046 deletions

View File

@ -14,16 +14,16 @@ Web timeline
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
: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
:target: https://github.com/OCA/web/tree/13.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
:target: https://translation.odoo-community.org/projects/web-13-0/web-13-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
:target: https://runbot.odoo-community.org/runbot/162/13.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
|badge1| |badge2| |badge3| |badge4| |badge5|
Define a new view displaying events in an interactive visualization chart.
@ -88,7 +88,7 @@ Example:
<field name="model">project.task</field>
<field name="type">timeline</field>
<field name="arch" type="xml">
<timeline date_start="date_start"
<timeline date_start="date_assign"
date_stop="date_end"
string="Tasks"
default_group_by="user_id"
@ -159,7 +159,7 @@ 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 <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**>`_.
`feedback <https://github.com/OCA/web/issues/new?body=module:%20web_timeline%0Aversion:%2013.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.
@ -185,14 +185,7 @@ Contributors
* Adrien Didenot <adrien.didenot@horanet.com>
* Dennis Sluijk <d.sluijk@onestein.nl>
* Thong Nguyen Van <thongnv@trobz.com>
Other credits
~~~~~~~~~~~~~
Images
------
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
* Alexandre Díaz <alexandre.diaz@tecnativa.com>
Maintainers
~~~~~~~~~~~
@ -213,8 +206,8 @@ promote its widespread use.
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-tarteo|
|maintainer-tarteo|
This module is part of the `OCA/web <https://github.com/OCA/web/tree/12.0/web_timeline>`_ project on GitHub.
This module is part of the `OCA/web <https://github.com/OCA/web/tree/13.0/web_timeline>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@ -19,94 +19,51 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Activity"
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "<b>UNASSIGNED</b>"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_controller.js:243
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0
#, fuzzy, python-format
msgid "Are you sure you want to delete this record?"
msgstr "¿Está seguro que desea eliminar este registro?"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Calendar"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:8
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Day"
msgstr "Día"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Diagram"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Form"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Gantt"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Graph"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Kanban"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:10
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Month"
msgstr "Mes"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Pivot"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "QWeb"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Search"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:467
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "Template \"timeline-item\" not present in timeline view definition."
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_view.js:32
#: selection:ir.ui.view,type:0
#: code:addons/web_timeline/static/src/js/timeline_view.js:0
#: model:ir.model.fields.selection,name:web_timeline.selection__ir_ui_view__type__timeline
#, python-format
msgid "Timeline"
msgstr "Línea de tiempo"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:63
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "Timeline view has not defined 'date_start' attribute."
msgstr ""
@ -114,16 +71,11 @@ msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:5
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Today"
msgstr "Hoy"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Tree"
msgstr ""
#. module: web_timeline
#: model:ir.model,name:web_timeline.model_ir_ui_view
msgid "View"
@ -136,21 +88,21 @@ msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_controller.js:246
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0
#, python-format
msgid "Warning"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:9
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Week"
msgstr "Semana"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:11
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Year"
msgstr "Año"

View File

@ -21,79 +21,36 @@ msgstr ""
"X-Generator: Weblate 3.7.1\n"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Activity"
msgstr "Activité"
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "<b>UNASSIGNED</b>"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_controller.js:243
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0
#, python-format
msgid "Are you sure you want to delete this record?"
msgstr "Êtes vous sûr de vouloir supprimer cet enregistrement ?"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Calendar"
msgstr "Calendrier"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:8
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Day"
msgstr "Jour"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Diagram"
msgstr "Diagramme"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Form"
msgstr "Formulaire"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Gantt"
msgstr "Gantt"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Graph"
msgstr "Graphique"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Kanban"
msgstr "Kanban"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:10
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Month"
msgstr "Mois"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Pivot"
msgstr "Pivot"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "QWeb"
msgstr "QWeb"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Search"
msgstr "Recherche"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:467
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "Template \"timeline-item\" not present in timeline view definition."
msgstr ""
@ -102,31 +59,26 @@ msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_view.js:32
#: selection:ir.ui.view,type:0
#: code:addons/web_timeline/static/src/js/timeline_view.js:0
#: model:ir.model.fields.selection,name:web_timeline.selection__ir_ui_view__type__timeline
#, python-format
msgid "Timeline"
msgstr "Chronologie"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:63
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "Timeline view has not defined 'date_start' attribute."
msgstr "La vue chronologique n'a pas défini l'attribut 'date_start'."
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:5
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Today"
msgstr "Aujourd'hui"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Tree"
msgstr "Arborescence"
#. module: web_timeline
#: model:ir.model,name:web_timeline.model_ir_ui_view
msgid "View"
@ -139,24 +91,57 @@ msgstr "Type de vue"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_controller.js:246
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0
#, python-format
msgid "Warning"
msgstr "Alerte"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:9
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Week"
msgstr "Semaine"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:11
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Year"
msgstr "Année"
#~ msgid "Activity"
#~ msgstr "Activité"
#~ msgid "Calendar"
#~ msgstr "Calendrier"
#~ msgid "Diagram"
#~ msgstr "Diagramme"
#~ msgid "Form"
#~ msgstr "Formulaire"
#~ msgid "Gantt"
#~ msgstr "Gantt"
#~ msgid "Graph"
#~ msgstr "Graphique"
#~ msgid "Kanban"
#~ msgstr "Kanban"
#~ msgid "Pivot"
#~ msgstr "Pivot"
#~ msgid "QWeb"
#~ msgstr "QWeb"
#~ msgid "Search"
#~ msgstr "Recherche"
#~ msgid "Tree"
#~ msgstr "Arborescence"
#~ msgid "ir.ui.view"
#~ msgstr "ir.ui.view"

View File

@ -16,84 +16,41 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<="
"4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 3.8\n"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Activity"
msgstr "Aktivnost"
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "<b>UNASSIGNED</b>"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_controller.js:243
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0
#, python-format
msgid "Are you sure you want to delete this record?"
msgstr "Jeste li sigurni da želite brisati ovaj zapis?"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Calendar"
msgstr "Kalendar"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:8
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Day"
msgstr "Dan"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Diagram"
msgstr "Diagram"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Form"
msgstr "Forma"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Gantt"
msgstr "Gant"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Graph"
msgstr "Graf"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Kanban"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:10
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Month"
msgstr "Mjesec"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Pivot"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "QWeb"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Search"
msgstr "Pretraga"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:467
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "Template \"timeline-item\" not present in timeline view definition."
msgstr ""
@ -101,31 +58,26 @@ msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_view.js:32
#: selection:ir.ui.view,type:0
#: code:addons/web_timeline/static/src/js/timeline_view.js:0
#: model:ir.model.fields.selection,name:web_timeline.selection__ir_ui_view__type__timeline
#, python-format
msgid "Timeline"
msgstr "Vremenska crta"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:63
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "Timeline view has not defined 'date_start' attribute."
msgstr "Pogled vremenske crte nema definiran atribut 'date_start'."
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:5
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Today"
msgstr "Danas"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Tree"
msgstr "Lista"
#. module: web_timeline
#: model:ir.model,name:web_timeline.model_ir_ui_view
msgid "View"
@ -138,24 +90,48 @@ msgstr "Vrsta pogleda"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_controller.js:246
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0
#, python-format
msgid "Warning"
msgstr "Upozorenje"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:9
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Week"
msgstr "Tjedan"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:11
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Year"
msgstr "Godina"
#~ msgid "Activity"
#~ msgstr "Aktivnost"
#~ msgid "Calendar"
#~ msgstr "Kalendar"
#~ msgid "Diagram"
#~ msgstr "Diagram"
#~ msgid "Form"
#~ msgstr "Forma"
#~ msgid "Gantt"
#~ msgstr "Gant"
#~ msgid "Graph"
#~ msgstr "Graf"
#~ msgid "Search"
#~ msgstr "Pretraga"
#~ msgid "Tree"
#~ msgstr "Lista"
#~ msgid "ir.ui.view"
#~ msgstr "ir.ui.view"

View File

@ -20,110 +20,62 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Activity"
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "<b>UNASSIGNED</b>"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_controller.js:243
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0
#, fuzzy, python-format
msgid "Are you sure you want to delete this record?"
msgstr "Weet je zeker dat je dit record wil verwijderen?"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Calendar"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:8
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Day"
msgstr "Dag"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Diagram"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Form"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Gantt"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Graph"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Kanban"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:10
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Month"
msgstr "Maand"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Pivot"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "QWeb"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Search"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:467
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "Template \"timeline-item\" not present in timeline view definition."
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_view.js:32
#: selection:ir.ui.view,type:0
#: code:addons/web_timeline/static/src/js/timeline_view.js:0
#: model:ir.model.fields.selection,name:web_timeline.selection__ir_ui_view__type__timeline
#, python-format
msgid "Timeline"
msgstr "Tijdlijn"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:63
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "Timeline view has not defined 'date_start' attribute."
msgstr "Tijdlijn heeft geen 'date_start' eigenschap."
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:5
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Today"
msgstr "Vandaag"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Tree"
msgstr ""
#. module: web_timeline
#: model:ir.model,name:web_timeline.model_ir_ui_view
msgid "View"
@ -136,21 +88,21 @@ msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_controller.js:246
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0
#, python-format
msgid "Warning"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:9
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Week"
msgstr "Week"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:11
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Year"
msgstr "Jaar"

View File

@ -1,6 +1,6 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * web_timeline
# * web_timeline
#
msgid ""
msgstr ""
@ -17,79 +17,36 @@ msgstr ""
"X-Generator: Weblate 3.7.1\n"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Activity"
msgstr "Atividade"
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "<b>UNASSIGNED</b>"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_controller.js:243
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0
#, python-format
msgid "Are you sure you want to delete this record?"
msgstr "Está seguro de que quer eliminar este registo?"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Calendar"
msgstr "Calendário"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:8
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Day"
msgstr "Dia"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Diagram"
msgstr "Diagrama"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Form"
msgstr "Formulário"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Gantt"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Graph"
msgstr "Gráfico"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Kanban"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:10
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Month"
msgstr "Mês"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Pivot"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "QWeb"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Search"
msgstr "Pesquisar"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:467
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "Template \"timeline-item\" not present in timeline view definition."
msgstr ""
@ -98,31 +55,26 @@ msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_view.js:32
#: selection:ir.ui.view,type:0
#: code:addons/web_timeline/static/src/js/timeline_view.js:0
#: model:ir.model.fields.selection,name:web_timeline.selection__ir_ui_view__type__timeline
#, python-format
msgid "Timeline"
msgstr "Linha Temporal"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:63
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "Timeline view has not defined 'date_start' attribute."
msgstr "A vista da linha temporal não tem o atributo 'date_start' definido."
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:5
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Today"
msgstr "Hoje"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Tree"
msgstr "Árvore"
#. module: web_timeline
#: model:ir.model,name:web_timeline.model_ir_ui_view
msgid "View"
@ -135,21 +87,42 @@ msgstr "Tipo de Vista"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_controller.js:246
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0
#, python-format
msgid "Warning"
msgstr "Aviso"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:9
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Week"
msgstr "Semana"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:11
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Year"
msgstr "Ano"
#~ msgid "Activity"
#~ msgstr "Atividade"
#~ msgid "Calendar"
#~ msgstr "Calendário"
#~ msgid "Diagram"
#~ msgstr "Diagrama"
#~ msgid "Form"
#~ msgstr "Formulário"
#~ msgid "Graph"
#~ msgstr "Gráfico"
#~ msgid "Search"
#~ msgstr "Pesquisar"
#~ msgid "Tree"
#~ msgstr "Árvore"

View File

@ -1,12 +1,12 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * web_timeline
# * web_timeline
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: <>\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -14,110 +14,62 @@ msgstr ""
"Plural-Forms: \n"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Activity"
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "<b>UNASSIGNED</b>"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_controller.js:243
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0
#, python-format
msgid "Are you sure you want to delete this record?"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Calendar"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:8
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Day"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Diagram"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Form"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Gantt"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Graph"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Kanban"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:10
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Month"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Pivot"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "QWeb"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Search"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:467
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "Template \"timeline-item\" not present in timeline view definition."
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_view.js:32
#: selection:ir.ui.view,type:0
#: code:addons/web_timeline/static/src/js/timeline_view.js:0
#: model:ir.model.fields.selection,name:web_timeline.selection__ir_ui_view__type__timeline
#, python-format
msgid "Timeline"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:63
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "Timeline view has not defined 'date_start' attribute."
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:5
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Today"
msgstr ""
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Tree"
msgstr ""
#. module: web_timeline
#: model:ir.model,name:web_timeline.model_ir_ui_view
msgid "View"
@ -130,22 +82,21 @@ msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_controller.js:246
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0
#, python-format
msgid "Warning"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:9
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Week"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:11
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Year"
msgstr ""

View File

@ -1,6 +1,6 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * web_timeline
# * web_timeline
#
msgid ""
msgstr ""
@ -17,110 +17,62 @@ msgstr ""
"X-Generator: Weblate 3.8\n"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Activity"
msgstr "活动"
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "<b>UNASSIGNED</b>"
msgstr ""
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_controller.js:243
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0
#, python-format
msgid "Are you sure you want to delete this record?"
msgstr "您确定要删除此记录吗?"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Calendar"
msgstr "日历"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:8
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Day"
msgstr "天"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Diagram"
msgstr "图表"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Form"
msgstr "表单"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Gantt"
msgstr "甘特图"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Graph"
msgstr "图形"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Kanban"
msgstr "看板"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:10
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Month"
msgstr "月"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Pivot"
msgstr "透视表"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "QWeb"
msgstr "QWeb"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Search"
msgstr "搜索"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:467
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "Template \"timeline-item\" not present in timeline view definition."
msgstr "时间线视图定义中不存在模板“timeline-item”。"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_view.js:32
#: selection:ir.ui.view,type:0
#: code:addons/web_timeline/static/src/js/timeline_view.js:0
#: model:ir.model.fields.selection,name:web_timeline.selection__ir_ui_view__type__timeline
#, python-format
msgid "Timeline"
msgstr "时间线"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:63
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format
msgid "Timeline view has not defined 'date_start' attribute."
msgstr "时间线视图尚未定义\"date_start\"属性。"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:5
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Today"
msgstr "今天"
#. module: web_timeline
#: selection:ir.ui.view,type:0
msgid "Tree"
msgstr "树形"
#. module: web_timeline
#: model:ir.model,name:web_timeline.model_ir_ui_view
msgid "View"
@ -133,21 +85,54 @@ msgstr "查看类型"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/js/timeline_controller.js:246
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0
#, python-format
msgid "Warning"
msgstr "警告"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:9
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Week"
msgstr "周"
#. module: web_timeline
#. openerp-web
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:11
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format
msgid "Year"
msgstr "年"
#~ msgid "Activity"
#~ msgstr "活动"
#~ msgid "Calendar"
#~ msgstr "日历"
#~ msgid "Diagram"
#~ msgstr "图表"
#~ msgid "Form"
#~ msgstr "表单"
#~ msgid "Gantt"
#~ msgstr "甘特图"
#~ msgid "Graph"
#~ msgstr "图形"
#~ msgid "Kanban"
#~ msgstr "看板"
#~ msgid "Pivot"
#~ msgstr "透视表"
#~ msgid "QWeb"
#~ msgstr "QWeb"
#~ msgid "Search"
#~ msgstr "搜索"
#~ msgid "Tree"
#~ msgstr "树形"

View File

@ -48,7 +48,7 @@ Example:
<field name="model">project.task</field>
<field name="type">timeline</field>
<field name="arch" type="xml">
<timeline date_start="date_start"
<timeline date_start="date_assign"
date_stop="date_end"
string="Tasks"
default_group_by="user_id"

View File

@ -5,3 +5,4 @@
* Adrien Didenot <adrien.didenot@horanet.com>
* Dennis Sluijk <d.sluijk@onestein.nl>
* Thong Nguyen Van <thongnv@trobz.com>
* Alexandre Díaz <alexandre.diaz@tecnativa.com>

View File

@ -1,4 +0,0 @@
Images
------
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.

View File

@ -367,7 +367,7 @@ ul.auto-toc {
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/web/tree/12.0/web_timeline"><img alt="OCA/web" src="https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/web-12-0/web-12-0-web_timeline"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/162/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/web/tree/13.0/web_timeline"><img alt="OCA/web" src="https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/web-13-0/web-13-0-web_timeline"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/162/13.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>Define a new view displaying events in an interactive visualization chart.</p>
<p>The widget is based on the external library
<a class="reference external" href="https://visjs.github.io/vis-timeline/examples/timeline">https://visjs.github.io/vis-timeline/examples/timeline</a></p>
@ -381,11 +381,7 @@ ul.auto-toc {
<li><a class="reference internal" href="#credits" id="id5">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id6">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id7">Contributors</a></li>
<li><a class="reference internal" href="#other-credits" id="id8">Other credits</a><ul>
<li><a class="reference internal" href="#images" id="id9">Images</a></li>
</ul>
</li>
<li><a class="reference internal" href="#maintainers" id="id10">Maintainers</a></li>
<li><a class="reference internal" href="#maintainers" id="id8">Maintainers</a></li>
</ul>
</li>
</ul>
@ -471,7 +467,7 @@ These are the variables available in template rendering:</p>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;model&quot;</span><span class="nt">&gt;</span>project.task<span class="nt">&lt;/field&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;type&quot;</span><span class="nt">&gt;</span>timeline<span class="nt">&lt;/field&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;arch&quot;</span> <span class="na">type=</span><span class="s">&quot;xml&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;timeline</span> <span class="na">date_start=</span><span class="s">&quot;date_start&quot;</span>
<span class="nt">&lt;timeline</span> <span class="na">date_start=</span><span class="s">&quot;date_assign&quot;</span>
<span class="na">date_stop=</span><span class="s">&quot;date_end&quot;</span>
<span class="na">string=</span><span class="s">&quot;Tasks&quot;</span>
<span class="na">default_group_by=</span><span class="s">&quot;user_id&quot;</span>
@ -537,7 +533,7 @@ with the dragged start and end date.</p>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/web/issues">GitHub Issues</a>.
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
<a class="reference external" href="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**">feedback</a>.</p>
<a class="reference external" href="https://github.com/OCA/web/issues/new?body=module:%20web_timeline%0Aversion:%2013.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
@ -562,19 +558,11 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<li>Adrien Didenot &lt;<a class="reference external" href="mailto:adrien.didenot&#64;horanet.com">adrien.didenot&#64;horanet.com</a>&gt;</li>
<li>Dennis Sluijk &lt;<a class="reference external" href="mailto:d.sluijk&#64;onestein.nl">d.sluijk&#64;onestein.nl</a>&gt;</li>
<li>Thong Nguyen Van &lt;<a class="reference external" href="mailto:thongnv&#64;trobz.com">thongnv&#64;trobz.com</a>&gt;</li>
<li>Alexandre Díaz &lt;<a class="reference external" href="mailto:alexandre.diaz&#64;tecnativa.com">alexandre.diaz&#64;tecnativa.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="other-credits">
<h2><a class="toc-backref" href="#id8">Other credits</a></h2>
<div class="section" id="images">
<h3><a class="toc-backref" href="#id9">Images</a></h3>
<ul class="simple">
<li>Odoo Community Association: <a class="reference external" href="https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg">Icon</a>.</li>
</ul>
</div>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id10">Maintainers</a></h2>
<h2><a class="toc-backref" href="#id8">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
@ -582,7 +570,7 @@ mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external" href="https://github.com/tarteo"><img alt="tarteo" src="https://github.com/tarteo.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/web/tree/12.0/web_timeline">OCA/web</a> project on GitHub.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/web/tree/13.0/web_timeline">OCA/web</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,69 +1,83 @@
/* Copyright 2018 Onestein
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
odoo.define('web_timeline.TimelineCanvas', function (require) {
odoo.define("web_timeline.TimelineCanvas", function(require) {
"use strict";
var Widget = require('web.Widget');
const Widget = require("web.Widget");
/**
* Used to draw stuff on upon the timeline view.
*/
var TimelineCanvas = Widget.extend({
template: 'TimelineView.Canvas',
const TimelineCanvas = Widget.extend({
template: "TimelineView.Canvas",
/**
* Clears all drawings (svg elements) from the canvas.
*/
clear: function () {
this.$(' > :not(defs)').remove();
clear: function() {
this.$(" > :not(defs)").remove();
},
/**
* 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 {Object} rectFrom
* @param {Object} rectTo
* @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;
var y1 = coordy1 + halfHeight1;
var x2 = coordx2 + width2;
var y2 = coordy2 + halfHeight2;
var xDiff = x1 - x2;
var yDiff = y1 - y2;
var threshold = breakAt + widthMarker;
var spaceY = halfHeight2 + 6;
var points = [[x1, y1]];
if (y1 !== y2) {
if (xDiff > threshold) {
points.push([x1 - breakAt, y1]);
points.push([x1 - breakAt, y1 - yDiff]);
} else {
var yDiffSpace = yDiff > 0 ? spaceY : -spaceY;
points.push([x1 - breakAt, y1]);
points.push([x1 - breakAt, y2 + yDiffSpace]);
points.push([x2 + breakAt, y2 + yDiffSpace]);
points.push([x2 + breakAt, y2]);
}
} else if (x1 < x2) {
points.push([x1 - breakAt, y1]);
points.push([x1 - breakAt, y1 + spaceY]);
points.push([x2 + breakAt, y2 + spaceY]);
points.push([x2 + breakAt, y2]);
get_polyline_points: function(rectFrom, rectTo, widthMarker, breakAt) {
let fromX = 0,
toX = 0;
if (rectFrom.x < rectTo.x + rectTo.w) {
fromX = rectFrom.x + rectFrom.w + widthMarker;
toX = rectTo.x;
} else {
fromX = rectFrom.x - widthMarker;
toX = rectTo.x + rectTo.w;
}
points.push([x2, y2]);
let deltaBreak = 0;
if (fromX < toX) {
deltaBreak = fromX + breakAt - (toX - breakAt);
} else {
deltaBreak = fromX - breakAt - (toX + breakAt);
}
const fromHalfHeight = rectFrom.h / 2;
const fromY = rectFrom.y + fromHalfHeight;
const toHalfHeight = rectTo.h / 2;
const toY = rectTo.y + toHalfHeight;
const xDiff = fromX - toX;
const yDiff = fromY - toY;
const threshold = breakAt + widthMarker;
const spaceY = toHalfHeight + 2;
const points = [[fromX, fromY]];
const _addPoints = (space, ePoint, mode) => {
if (mode) {
points.push([fromX + breakAt, fromY]);
points.push([fromX + breakAt, ePoint + space]);
points.push([toX - breakAt, toY + space]);
points.push([toX - breakAt, toY]);
} else {
points.push([fromX - breakAt, fromY]);
points.push([fromX - breakAt, ePoint + space]);
points.push([toX + breakAt, toY + space]);
points.push([toX + breakAt, toY]);
}
};
if (fromY !== toY) {
if (Math.abs(xDiff) < threshold) {
points.push([fromX + breakAt, toY + yDiff]);
points.push([fromX + breakAt, toY]);
} else {
const yDiffSpace = yDiff > 0 ? spaceY : -spaceY;
_addPoints(yDiffSpace, toY, rectFrom.x < rectTo.x + rectTo.w);
}
} else if (Math.abs(deltaBreak) >= threshold) {
_addPoints(spaceY, fromY, fromX < toX);
}
points.push([toX, toY]);
return points;
},
@ -77,8 +91,8 @@ odoo.define('web_timeline.TimelineCanvas', function (require) {
* @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);
draw_arrow: function(from, to, color, width) {
return this.draw_line(from, to, color, width, "#arrowhead", 10, 12);
},
/**
@ -93,31 +107,49 @@ odoo.define('web_timeline.TimelineCanvas', function (require) {
* @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,
x2 = to.offsetLeft,
y2 = to.offsetTop + to.parentElement.offsetTop,
width1 = from.clientWidth,
height1 = from.clientHeight,
width2 = to.clientWidth,
height2 = to.clientHeight;
var points = this.get_polyline_points(x1, y1, x2, y2, width1, height1, width2, height2, widthMarker, breakLineAt);
var polyline_points = _.map(points, function (point) {
return point.join(',');
}).join();
var line = document.createElementNS(
'http://www.w3.org/2000/svg', 'polyline'
draw_line: function(
from,
to,
color,
width,
markerStart,
widthMarker,
breakLineAt
) {
const $from = $(from);
const childPosFrom = $from.offset();
const parentPosFrom = $from.closest(".vis-center").offset();
const rectFrom = {
x: childPosFrom.left - parentPosFrom.left,
y: childPosFrom.top - parentPosFrom.top,
w: $from.width(),
h: $from.height(),
};
const $to = $(to);
const childPosTo = $to.offset();
const parentPosTo = $to.closest(".vis-center").offset();
const rectTo = {
x: childPosTo.left - parentPosTo.left,
y: childPosTo.top - parentPosTo.top,
w: $to.width(),
h: $to.height(),
};
const points = this.get_polyline_points(
rectFrom,
rectTo,
widthMarker,
breakLineAt
);
line.setAttribute('points', polyline_points);
line.setAttribute('stroke', color || '#000');
line.setAttribute('stroke-width', width || 1);
line.setAttribute('fill', 'none');
const line = document.createElementNS(
"http://www.w3.org/2000/svg",
"polyline"
);
line.setAttribute("points", _.flatten(points).join(","));
line.setAttribute("stroke", color || "#000");
line.setAttribute("stroke-width", width || 1);
line.setAttribute("fill", "none");
if (markerStart) {
line.setAttribute('marker-start', 'url(' + markerStart + ')');
line.setAttribute("marker-start", "url(" + markerStart + ")");
}
this.$el.append(line);
return line;

View File

@ -1,27 +1,27 @@
odoo.define('web_timeline.TimelineController', function (require) {
odoo.define("web_timeline.TimelineController", function(require) {
"use strict";
var AbstractController = require('web.AbstractController');
var dialogs = require('web.view_dialogs');
var core = require('web.core');
var time = require('web.time');
var Dialog = require('web.Dialog');
const AbstractController = require("web.AbstractController");
const dialogs = require("web.view_dialogs");
const core = require("web.core");
const time = require("web.time");
const Dialog = require("web.Dialog");
var _t = core._t;
const _t = core._t;
var TimelineController = AbstractController.extend({
const TimelineController = AbstractController.extend({
custom_events: _.extend({}, AbstractController.prototype.custom_events, {
onGroupClick: '_onGroupClick',
onUpdate: '_onUpdate',
onRemove: '_onRemove',
onMove: '_onMove',
onAdd: '_onAdd',
onGroupClick: "_onGroupClick",
onUpdate: "_onUpdate",
onRemove: "_onRemove",
onMove: "_onMove",
onAdd: "_onAdd",
}),
/**
* @override
*/
init: function (parent, model, renderer, params) {
init: function(parent, model, renderer, params) {
this._super.apply(this, arguments);
this.open_popup_action = params.open_popup_action;
this.date_start = params.date_start;
@ -35,77 +35,81 @@ odoo.define('web_timeline.TimelineController', function (require) {
/**
* @override
*/
update: function (params, options) {
var res = this._super.apply(this, arguments);
update: function(params, options) {
const res = this._super.apply(this, arguments);
if (_.isEmpty(params)) {
return res;
}
var defaults = _.defaults({}, options, {
const defaults = _.defaults({}, options, {
adjust_window: true,
});
var self = this;
var domains = params.domain;
var contexts = params.context;
var group_bys = params.groupBy;
const domains = params.domain;
const contexts = params.context;
const group_bys = params.groupBy;
this.last_domains = domains;
this.last_contexts = contexts;
// Select the group by
var n_group_bys = group_bys;
let n_group_bys = group_bys;
if (!n_group_bys.length && this.renderer.arch.attrs.default_group_by) {
n_group_bys = this.renderer.arch.attrs.default_group_by.split(',');
n_group_bys = this.renderer.arch.attrs.default_group_by.split(",");
}
this.renderer.last_group_bys = n_group_bys;
this.renderer.last_domains = domains;
var fields = this.renderer.fieldNames;
let fields = this.renderer.fieldNames;
fields = _.uniq(fields.concat(n_group_bys));
return $.when(
res,
self._rpc({
model: self.model.modelName,
method: 'search_read',
this._rpc({
model: this.model.modelName,
method: "search_read",
kwargs: {
fields: fields,
domain: domains,
},
context: self.getSession().user_context,
}).then(function (data) {
return self.renderer.on_data_loaded(data, n_group_bys, defaults.adjust_window);
})
context: this.getSession().user_context,
}).then(data =>
this.renderer.on_data_loaded(
data,
n_group_bys,
defaults.adjust_window
)
)
);
},
/**
* Gets triggered when a group in the timeline is clicked (by the TimelineRenderer).
* Gets triggered when a group in the timeline is
* clicked (by the TimelineRenderer).
*
* @private
* @param {EventObject} event
* @returns {jQuery.Deferred}
*/
_onGroupClick: function (event) {
var groupField = this.renderer.last_group_bys[0];
_onGroupClick: function(event) {
const groupField = this.renderer.last_group_bys[0];
return this.do_action({
type: 'ir.actions.act_window',
res_model: this.renderer.view.fields[groupField].relation,
type: "ir.actions.act_window",
res_model: this.renderer.fields[groupField].relation,
res_id: event.data.item.group,
target: 'new',
views: [[false, 'form']],
target: "new",
views: [[false, "form"]],
});
},
/**
* Opens a form view of a clicked timeline item (triggered by the TimelineRenderer).
* Opens a form view of a clicked timeline
* item (triggered by the TimelineRenderer).
*
* @private
* @param {EventObject} event
*/
_onUpdate: function (event) {
var self = this;
_onUpdate: function(event) {
this.renderer = event.data.renderer;
var rights = event.data.rights;
var item = event.data.item;
var id = Number(item.evt.id) || item.evt.id;
var title = item.evt.__name;
const rights = event.data.rights;
const item = event.data.item;
const id = Number(item.evt.id) || item.evt.id;
const title = item.evt.__name;
if (this.open_popup_action) {
new dialogs.FormViewDialog(this, {
res_model: this.model.modelName,
@ -113,17 +117,17 @@ odoo.define('web_timeline.TimelineController', function (require) {
context: this.getSession().user_context,
title: title,
view_id: Number(this.open_popup_action),
on_saved: function () {
self.write_completed();
on_saved: () => {
this.write_completed();
},
}).open();
} else {
var mode = 'readonly';
let mode = "readonly";
if (rights.write) {
mode = 'edit';
mode = "edit";
}
this.trigger_up('switch_view', {
view_type: 'form',
this.trigger_up("switch_view", {
view_type: "form",
res_id: id,
mode: mode,
model: this.model.modelName,
@ -132,38 +136,49 @@ odoo.define('web_timeline.TimelineController', function (require) {
},
/**
* Gets triggered when a timeline item is moved (triggered by the TimelineRenderer).
* Gets triggered when a timeline item is
* moved (triggered by the TimelineRenderer).
*
* @private
* @param {EventObject} event
*/
_onMove: function (event) {
var item = event.data.item;
var view = this.renderer.view;
var fields = view.fields;
var event_start = item.start;
var event_end = item.end;
var group = false;
_onMove: function(event) {
const item = event.data.item;
const fields = this.renderer.fields;
const event_start = item.start;
const event_end = item.end;
let group = false;
if (item.group !== -1) {
group = item.group;
}
var data = {};
const data = {};
// In case of a move event, the date_delay stay the same,
// only date_start and stop must be updated
data[this.date_start] = time.auto_date_to_str(event_start, fields[this.date_start].type);
data[this.date_start] = time.auto_date_to_str(
event_start,
fields[this.date_start].type
);
if (this.date_stop) {
// In case of instantaneous event, item.end is not defined
if (event_end) {
data[this.date_stop] = time.auto_date_to_str(event_end, fields[this.date_stop].type);
data[this.date_stop] = time.auto_date_to_str(
event_end,
fields[this.date_stop].type
);
} else {
data[this.date_stop] = data[this.date_start];
}
}
if (this.date_delay && event_end) {
var diff_seconds = Math.round((event_end.getTime() - event_start.getTime()) / 1000);
const diff_seconds = Math.round(
(event_end.getTime() - event_start.getTime()) / 1000
);
data[this.date_delay] = diff_seconds / 3600;
}
if (this.renderer.last_group_bys && this.renderer.last_group_bys instanceof Array) {
if (
this.renderer.last_group_bys &&
this.renderer.last_group_bys instanceof Array
) {
data[this.renderer.last_group_bys[0]] = group;
}
@ -177,31 +192,30 @@ odoo.define('web_timeline.TimelineController', function (require) {
},
/**
* 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).
* 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 queues = this.moveQueue.slice();
internalMove: function() {
const queues = this.moveQueue.slice();
this.moveQueue = [];
var defers = [];
const defers = [];
for (const item of queues) {
defers.push(self._rpc({
model: self.model.modelName,
method: 'write',
args: [
[item.event.data.item.id],
item.data,
],
context: self.getSession().user_context,
}).then(function () {
item.event.data.callback(item.event.data.item);
}));
defers.push(
this._rpc({
model: this.model.modelName,
method: "write",
args: [[item.event.data.item.id], item.data],
context: this.getSession().user_context,
}).then(() => {
item.event.data.callback(item.event.data.item);
})
);
}
return $.when.apply($, defers).done(function () {
self.write_completed({
return $.when.apply($, defers).done(() => {
this.write_completed({
adjust_window: false,
});
});
@ -215,14 +229,13 @@ odoo.define('web_timeline.TimelineController', function (require) {
* @param {EventObject} event
* @returns {jQuery.Deferred}
*/
_onRemove: function (event) {
var self = this;
_onRemove: function(event) {
var def = $.Deferred();
Dialog.confirm(this, _t("Are you sure you want to delete this record?"), {
title: _t("Warning"),
confirm_callback: function () {
self.remove_completed(event).then(def.resolve.bind(def));
confirm_callback: () => {
this.remove_completed(event).then(def.resolve.bind(def));
},
cancel_callback: def.resolve.bind(def),
});
@ -237,27 +250,27 @@ odoo.define('web_timeline.TimelineController', function (require) {
* @param {EventObject} event
* @returns {dialogs.FormViewDialog}
*/
_onAdd: function (event) {
var self = this;
var item = event.data.item;
_onAdd: function(event) {
const item = event.data.item;
// Initialize default values for creation
var default_context = {};
default_context['default_'.concat(this.date_start)] = item.start;
const default_context = {};
default_context["default_".concat(this.date_start)] = item.start;
if (this.date_delay) {
default_context['default_'.concat(this.date_delay)] = 1;
default_context["default_".concat(this.date_delay)] = 1;
}
if (this.date_start) {
default_context['default_'.concat(this.date_start)] = moment(item.start).add(1, 'hours').format(
'YYYY-MM-DD HH:mm:ss'
);
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) {
default_context['default_'.concat(this.date_stop)] = moment(item.end).add(1, 'hours').format(
'YYYY-MM-DD HH:mm:ss'
);
default_context["default_".concat(this.date_stop)] = moment(item.end)
.add(1, "hours")
.format("YYYY-MM-DD HH:mm:ss");
}
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;
}
// Show popup
new dialogs.FormViewDialog(this, {
@ -265,12 +278,14 @@ odoo.define('web_timeline.TimelineController', function (require) {
res_id: null,
context: _.extend(default_context, this.context),
view_id: Number(this.open_popup_action),
on_saved: function (record) {
self.create_completed([record.res_id]);
on_saved: record => {
this.create_completed([record.res_id]);
},
}).open().on('closed', this, function () {
event.data.callback();
});
})
.open()
.on("closed", this, () => {
event.data.callback();
});
return false;
},
@ -282,22 +297,18 @@ odoo.define('web_timeline.TimelineController', function (require) {
* @param {RecordId} id
* @returns {jQuery.Deferred}
*/
create_completed: function (id) {
var self = this;
create_completed: function(id) {
return this._rpc({
model: this.model.modelName,
method: 'read',
args: [
id,
this.model.fieldNames,
],
method: "read",
args: [id, this.model.fieldNames],
context: this.context,
}).then(function (records) {
var new_event = self.renderer.event_data_transform(records[0]);
var items = self.renderer.timeline.itemsData;
}).then(records => {
var new_event = this.renderer.event_data_transform(records[0]);
var items = this.renderer.timeline.itemsData;
items.add(new_event);
self.renderer.timeline.setItems(items);
self.reload();
this.renderer.timeline.setItems(items);
this.reload();
});
},
@ -305,8 +316,8 @@ odoo.define('web_timeline.TimelineController', function (require) {
* Triggered upon completion of writing a record.
* @param {ControllerOptions} options
*/
write_completed: function (options) {
var params = {
write_completed: function(options) {
const params = {
domain: this.renderer.last_domains,
context: this.context,
groupBy: this.renderer.last_group_bys,
@ -319,22 +330,21 @@ odoo.define('web_timeline.TimelineController', function (require) {
* @param {EventObject} event
* @returns {jQuery.Deferred}
*/
remove_completed: function (event) {
var self = this;
return self._rpc({
model: self.modelName,
method: 'unlink',
remove_completed: function(event) {
return this._rpc({
model: this.modelName,
method: "unlink",
args: [[event.data.item.id]],
context: self.getSession().user_context,
}).then(function () {
var unlink_index = false;
for (var i = 0; i < self.model.data.data.length; i++) {
if (self.model.data.data[i].id === event.data.item.id) {
context: this.getSession().user_context,
}).then(() => {
let unlink_index = false;
for (var i = 0; i < this.model.data.data.length; i++) {
if (this.model.data.data[i].id === event.data.item.id) {
unlink_index = i;
}
}
if (!isNaN(unlink_index)) {
self.model.data.data.splice(unlink_index, 1);
this.model.data.data.splice(unlink_index, 1);
}
event.data.callback(event.data.item);
});

View File

@ -1,16 +1,14 @@
odoo.define('web_timeline.TimelineModel', function (require) {
odoo.define("web_timeline.TimelineModel", function(require) {
"use strict";
var AbstractModel = require('web.AbstractModel');
const AbstractModel = require("web.AbstractModel");
var TimelineModel = AbstractModel.extend({
init: function () {
const TimelineModel = AbstractModel.extend({
init: function() {
this._super.apply(this, arguments);
},
load: function (params) {
var self = this;
load: function(params) {
this.modelName = params.modelName;
this.fieldNames = params.fieldNames;
if (!this.preload_def) {
@ -18,24 +16,24 @@ odoo.define('web_timeline.TimelineModel', function (require) {
$.when(
this._rpc({
model: this.modelName,
method: 'check_access_rights',
method: "check_access_rights",
args: ["write", false],
}),
this._rpc({
model: this.modelName,
method: 'check_access_rights',
method: "check_access_rights",
args: ["unlink", false],
}),
this._rpc({
model: this.modelName,
method: 'check_access_rights',
method: "check_access_rights",
args: ["create", false],
})
).then(function (write, unlink, create) {
self.write_right = write;
self.unlink_right = unlink;
self.create_right = create;
self.preload_def.resolve();
).then((write, unlink, create) => {
this.write_right = write;
this.unlink_right = unlink;
this.create_right = create;
this.preload_def.resolve();
});
}
@ -53,20 +51,19 @@ odoo.define('web_timeline.TimelineModel', function (require) {
* @private
* @returns {jQuery.Deferred}
*/
_loadTimeline: function () {
var self = this;
return self._rpc({
model: self.modelName,
method: 'search_read',
context: self.data.context,
fields: self.fieldNames,
domain: self.data.domain,
}).then(function (events) {
self.data.data = events;
self.data.rights = {
'unlink': self.unlink_right,
'create': self.create_right,
'write': self.write_right,
_loadTimeline: function() {
return this._rpc({
model: this.modelName,
method: "search_read",
context: this.data.context,
fields: this.fieldNames,
domain: this.data.domain,
}).then(events => {
this.data.data = events;
this.data.rights = {
unlink: this.unlink_right,
create: this.create_right,
write: this.write_right,
};
});
},

View File

@ -1,36 +1,34 @@
odoo.define('web_timeline.TimelineRenderer', function (require) {
/* global vis, py */
odoo.define("web_timeline.TimelineRenderer", function(require) {
"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');
const AbstractRenderer = require("web.AbstractRenderer");
const core = require("web.core");
const time = require("web.time");
const utils = require("web.utils");
const session = require("web.session");
const QWeb = require("web.QWeb");
const field_utils = require("web.field_utils");
const TimelineCanvas = require("web_timeline.TimelineCanvas");
const _t = core._t;
var _t = core._t;
var TimelineRenderer = AbstractRenderer.extend({
const 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',
"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",
}),
init: function (parent, state, params) {
init: function(parent, state, params) {
this._super.apply(this, arguments);
this.modelName = params.model;
this.mode = params.mode;
this.options = params.options;
this.permissions = params.permissions;
this.timeline = params.timeline;
this.min_height = params.min_height;
this.date_start = params.date_start;
this.date_stop = params.date_stop;
@ -38,35 +36,39 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
this.colors = params.colors;
this.fieldNames = params.fieldNames;
this.dependency_arrow = params.dependency_arrow;
this.view = params.view;
this.modelClass = this.view.model;
this.modelClass = params.view.model;
this.fields = params.fields;
this.timeline = false;
},
/**
* @override
*/
start: function () {
var self = this;
var attrs = this.arch.attrs;
start: function() {
const attrs = this.arch.attrs;
this.current_window = {
start: new moment(),
end: new moment().add(24, 'hours'),
end: new moment().add(24, "hours"),
};
this.$el.addClass(attrs.class);
this.$timeline = this.$('.oe_timeline_widget');
this.$timeline = this.$(".oe_timeline_widget");
if (!this.date_start) {
throw new Error(_t("Timeline view has not defined 'date_start' attribute."));
throw new Error(
_t("Timeline view has not defined 'date_start' attribute.")
);
}
this._super.apply(this, self);
this._super.apply(this, arguments);
},
/**
* Triggered when the timeline is attached to the DOM.
*/
on_attach_callback: function () {
var height = this.$el.parent().height() - this.$('.oe_timeline_buttons').height();
on_attach_callback: function() {
const height =
this.$el.parent().height() - this.$(".oe_timeline_buttons").height();
if (height > this.min_height && this.timeline) {
this.timeline.setOptions({
height: height,
@ -77,13 +79,12 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
/**
* @override
*/
_render: function () {
var self = this;
return $.when().then(function () {
_render: function() {
return Promise.resolve().then(() => {
// Prevent Double Rendering on Updates
if (!self.timeline) {
self.init_timeline();
$(window).trigger('resize');
if (!this.timeline) {
this.init_timeline();
$(window).trigger("resize");
}
});
},
@ -93,10 +94,10 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
*
* @private
*/
_onTodayClicked: function () {
_onTodayClicked: function() {
this.current_window = {
start: new moment(),
end: new moment().add(24, 'hours'),
end: new moment().add(24, "hours"),
};
if (this.timeline) {
@ -109,7 +110,7 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
*
* @private
*/
_onScaleDayClicked: function () {
_onScaleDayClicked: function() {
this._scaleCurrentWindow(24);
},
@ -118,7 +119,7 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
*
* @private
*/
_onScaleWeekClicked: function () {
_onScaleWeekClicked: function() {
this._scaleCurrentWindow(24 * 7);
},
@ -127,8 +128,10 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
*
* @private
*/
_onScaleMonthClicked: function () {
this._scaleCurrentWindow(24 * moment(this.current_window.start).daysInMonth());
_onScaleMonthClicked: function() {
this._scaleCurrentWindow(
24 * moment(this.current_window.start).daysInMonth()
);
},
/**
@ -136,8 +139,10 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
*
* @private
*/
_onScaleYearClicked: function () {
this._scaleCurrentWindow(24 * (moment(this.current_window.start).isLeapYear() ? 366 : 365));
_onScaleYearClicked: function() {
this._scaleCurrentWindow(
24 * (moment(this.current_window.start).isLeapYear() ? 366 : 365)
);
},
/**
@ -146,10 +151,13 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
* @param {Integer} factor The timespan (in hours) the window must be scaled to.
* @private
*/
_scaleCurrentWindow: function (factor) {
_scaleCurrentWindow: function(factor) {
if (this.timeline) {
this.current_window = this.timeline.getWindow();
this.current_window.end = moment(this.current_window.start).add(factor, 'hours');
this.current_window.end = moment(this.current_window.start).add(
factor,
"hours"
);
this.timeline.setWindow(this.current_window);
}
},
@ -159,39 +167,40 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
*
* @private
*/
_computeMode: function () {
_computeMode: function() {
if (this.mode) {
var start = false, end = false;
let start = false,
end = false;
switch (this.mode) {
case 'day':
start = new moment().startOf('day');
end = new moment().endOf('day');
break;
case 'week':
start = new moment().startOf('week');
end = new moment().endOf('week');
break;
case 'month':
start = new moment().startOf('month');
end = new moment().endOf('month');
break;
case "day":
start = new moment().startOf("day");
end = new moment().endOf("day");
break;
case "week":
start = new moment().startOf("week");
end = new moment().endOf("week");
break;
case "month":
start = new moment().startOf("month");
end = new moment().endOf("month");
break;
}
if (end && start) {
this.options.start = start;
this.options.end = end;
} else {
this.mode = 'fit';
this.mode = "fit";
}
}
},
/**
* Initializes the timeline (https://visjs.github.io/vis-timeline/docs/timeline).
* Initializes the timeline
* (https://visjs.github.io/vis-timeline/docs/timeline).
*
* @private
*/
init_timeline: function () {
var self = this;
init_timeline: function() {
this._computeMode();
this.options.editable = {
// Add new items by double tapping
@ -204,41 +213,34 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
remove: this.modelClass.data.rights.unlink,
};
$.extend(this.options, {
onAdd: self.on_add,
onMove: self.on_move,
onUpdate: self.on_update,
onRemove: self.on_remove,
onAdd: this.on_add,
onMove: this.on_move,
onUpdate: this.on_update,
onRemove: this.on_remove,
});
this.qweb = new QWeb(session.debug, {_s: session.origin}, false);
if (this.arch.children.length) {
var tmpl = utils.json_node_to_xml(
_.filter(this.arch.children, function (item) {
return item.tag === 'templates';
})[0]
const tmpl = utils.json_node_to_xml(
_.filter(this.arch.children, item => item.tag === "templates")[0]
);
this.qweb.add_template(tmpl);
}
this.timeline = new vis.Timeline(self.$timeline.get(0));
this.timeline = new vis.Timeline(this.$timeline.get(0));
this.timeline.setOptions(this.options);
if (self.mode && self['on_scale_' + self.mode + '_clicked']) {
self['on_scale_' + self.mode + '_clicked']();
if (this.mode && this["on_scale_" + this.mode + "_clicked"]) {
this["on_scale_" + this.mode + "_clicked"]();
}
this.timeline.on('click', self.on_group_click);
var group_bys = this.arch.attrs.default_group_by.split(',');
this.timeline.on("click", this.on_group_click);
const group_bys = this.arch.attrs.default_group_by.split(",");
this.last_group_bys = group_bys;
this.last_domains = this.modelClass.data.domain;
this.on_data_loaded(this.modelClass.data.data, group_bys);
this.$centerContainer = $(this.timeline.dom.centerContainer);
this.canvas = new TimelineCanvas(this);
this.canvas.appendTo(this.$centerContainer);
this.timeline.on('changed', function () {
self.draw_canvas();
self.canvas.$el.attr(
'style',
self.$('.vis-content').attr('style') +
self.$('.vis-itemset').attr('style')
);
this.timeline.on("changed", () => {
this.draw_canvas();
});
},
@ -247,7 +249,7 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
*
* @private
*/
draw_canvas: function () {
draw_canvas: function() {
this.canvas.clear();
if (this.dependency_arrow) {
this.draw_dependencies();
@ -259,16 +261,22 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
*
* @private
*/
draw_dependencies: function () {
var self = this;
var items = this.timeline.itemSet.items;
for (const item of items) {
if (!item.data.evt) {
draw_dependencies: function() {
const items = this.timeline.itemSet.items;
const datas = this.timeline.itemsData;
if (!items || !datas) {
return;
}
const keys = Object.keys(items);
for (const key of keys) {
const item = items[key];
const data = datas._data[key];
if (!data || !data.evt) {
return;
}
for (const id of item.data.evt[self.dependency_arrow]) {
if (id in items) {
self.draw_dependency(item, items[id]);
for (const id of data.evt[this.dependency_arrow]) {
if (keys.indexOf(id.toString()) !== -1) {
this.draw_dependency(item, items[id]);
}
}
}
@ -284,67 +292,72 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
* @param {Object} options.line_width The width of the line
* @private
*/
draw_dependency: function (from, to, options) {
draw_dependency: function(from, to, options) {
if (!from.displayed || !to.displayed) {
return;
}
var defaults = _.defaults({}, options, {
line_color: 'black',
const defaults = _.defaults({}, options, {
line_color: "black",
line_width: 1,
});
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.
*
* @param {Object[]} events
* @param {String[]} group_bys
* @param {Boolean} adjust_window
* @private
* @returns {jQuery.Deferred}
*/
on_data_loaded: function (events, group_bys, adjust_window) {
var self = this;
var ids = _.pluck(events, "id");
on_data_loaded: function(events, group_bys, adjust_window) {
const ids = _.pluck(events, "id");
return this._rpc({
model: this.modelName,
method: 'name_get',
args: [
ids,
],
method: "name_get",
args: [ids],
context: this.getSession().user_context,
}).then(function (names) {
var nevents = _.map(events, function (event) {
return _.extend({
__name: _.detect(names, function (name) {
return name[0] === event.id;
})[1],
}, event);
});
return self.on_data_loaded_2(nevents, group_bys, adjust_window);
}).then(names => {
const nevents = _.map(events, event =>
_.extend(
{
__name: _.detect(names, name => name[0] === event.id)[1],
},
event
)
);
return this.on_data_loaded_2(nevents, group_bys, adjust_window);
});
},
/**
* Set groups and events.
*
* @param {Object[]} events
* @param {String[]} group_bys
* @param {Boolean} adjust_window
* @private
*/
on_data_loaded_2: function (events, group_bys, adjust_window) {
var self = this;
var data = [];
var groups = [];
on_data_loaded_2: function(events, group_bys, adjust_window) {
const data = [];
this.grouped_by = group_bys;
for (const evt of events) {
if (evt[self.date_start]) {
data.push(self.event_data_transform(evt));
if (evt[this.date_start]) {
data.push(this.event_data_transform(evt));
}
}
groups = this.split_groups(events, group_bys);
const groups = this.split_groups(events, group_bys);
this.timeline.setGroups(groups);
this.timeline.setItems(data);
var mode = !this.mode || this.mode === 'fit';
var adjust = _.isUndefined(adjust_window) || adjust_window;
const mode = !this.mode || this.mode === "fit";
const adjust = _.isUndefined(adjust_window) || adjust_window;
if (mode && adjust) {
this.timeline.fit();
}
@ -353,22 +366,25 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
/**
* Get the groups.
*
* @param {Object[]} events
* @param {String[]} group_bys
* @private
* @returns {Array}
*/
split_groups: function (events, group_bys) {
split_groups: function(events, group_bys) {
if (group_bys.length === 0) {
return events;
}
var groups = [];
groups.push({id: -1, content: _t('-')});
const groups = [];
groups.push({id: -1, content: _t("<b>UNASSIGNED</b>")});
for (const evt of events) {
var group_name = evt[_.first(group_bys)];
const group_name = evt[_.first(group_bys)];
if (group_name) {
if (group_name instanceof Array) {
var group = _.find(groups, function (existing_group) {
return existing_group.id === group_name[0];
});
const group = _.find(
groups,
existing_group => existing_group.id === group_name[0]
);
if (_.isUndefined(group)) {
groups.push({
id: group_name[0],
@ -382,60 +398,84 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
},
/**
* Transform Odoo event object to timeline event object.
* Get dates from given event
*
* @private
* @param {TransformEvent} evt
* @returns {Object}
*/
event_data_transform: function (evt) {
var self = this;
var date_start = new moment();
var date_stop = null;
_get_event_dates: function(evt) {
let date_start = new moment();
let date_stop = null;
var date_delay = evt[this.date_delay] || false,
const date_delay = evt[this.date_delay] || false,
all_day = this.all_day ? evt[this.all_day] : false;
if (all_day) {
date_start = time.auto_str_to_date(evt[this.date_start].split(' ')[0], 'start');
date_start = time.auto_str_to_date(
evt[this.date_start].split(" ")[0],
"start"
);
if (this.no_period) {
date_stop = date_start;
} else {
date_stop = this.date_stop ? time.auto_str_to_date(evt[this.date_stop].split(' ')[0], 'stop') : null;
date_stop = this.date_stop
? time.auto_str_to_date(
evt[this.date_stop].split(" ")[0],
"stop"
)
: null;
}
} else {
date_start = time.auto_str_to_date(evt[this.date_start]);
date_stop = this.date_stop ? time.auto_str_to_date(evt[this.date_stop]) : null;
date_stop = this.date_stop
? time.auto_str_to_date(evt[this.date_stop])
: null;
}
if (!date_stop && date_delay) {
date_stop = date_start.clone().add(date_delay, 'hours').toDate();
date_stop = date_start
.clone()
.add(date_delay, "hours")
.toDate();
}
var group = evt[self.last_group_bys[0]];
return [date_start, date_stop];
},
/**
* Transform Odoo event object to timeline event object.
*
* @param {TransformEvent} evt
* @private
* @returns {Object}
*/
event_data_transform: function(evt) {
const [date_start, date_stop] = this._get_event_dates(evt);
let group = evt[this.last_group_bys[0]];
if (group && group instanceof Array) {
group = _.first(group);
} else {
group = -1;
}
for (const color of self.colors) {
if (py.eval("'" + evt[color.field] + "' " + color.opt + " '" + color.value + "'")) {
self.color = color.color;
for (const color of this.colors) {
if (py.eval(`'${evt[color.field]}' ${color.opt} '${color.value}'`)) {
this.color = color.color;
}
}
var content = evt.__name || evt.display_name;
let content = evt.__name || evt.display_name;
if (this.arch.children.length) {
content = this.render_timeline_item(evt);
}
var r = {
'start': date_start,
'content': content,
'id': evt.id,
'group': group,
'evt': evt,
'style': `background-color: ${this.color};`,
const r = {
start: date_start,
content: content,
id: evt.id,
group: group,
evt: evt,
style: `background-color: ${this.color};`,
};
// Check if the event is instantaneous,
// if so, display it with a point on the timeline (no 'end')
@ -453,11 +493,11 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
* @private
* @returns {String} Rendered template
*/
render_timeline_item: function (evt) {
if (this.qweb.has_template('timeline-item')) {
return this.qweb.render('timeline-item', {
'record': evt,
'field_utils': field_utils,
render_timeline_item: function(evt) {
if (this.qweb.has_template("timeline-item")) {
return this.qweb.render("timeline-item", {
record: evt,
field_utils: field_utils,
});
}
@ -469,66 +509,81 @@ odoo.define('web_timeline.TimelineRenderer', function (require) {
/**
* Handle a click on a group header.
*
* @param {ClickEvent} e
* @private
*/
on_group_click: function (e) {
if (e.what === 'group-label' && e.group !== -1) {
this._trigger(e, function () {
// Do nothing
}, 'onGroupClick');
on_group_click: function(e) {
if (e.what === "group-label" && e.group !== -1) {
this._trigger(
e,
() => {
// Do nothing
},
"onGroupClick"
);
}
},
/**
* Trigger onUpdate.
*
* @param {Object} item
* @param {Function} callback
* @private
*/
on_update: function (item, callback) {
this._trigger(item, callback, 'onUpdate');
on_update: function(item, callback) {
this._trigger(item, callback, "onUpdate");
},
/**
* Trigger onMove.
*
* @param {Object} item
* @param {Function} callback
* @private
*/
on_move: function (item, callback) {
this._trigger(item, callback, 'onMove');
on_move: function(item, callback) {
this._trigger(item, callback, "onMove");
},
/**
* Trigger onRemove.
*
* @param {Object} item
* @param {Function} callback
* @private
*/
on_remove: function (item, callback) {
this._trigger(item, callback, 'onRemove');
on_remove: function(item, callback) {
this._trigger(item, callback, "onRemove");
},
/**
* Trigger onAdd.
*
* @param {Object} item
* @param {Function} callback
* @private
*/
on_add: function (item, callback) {
this._trigger(item, callback, 'onAdd');
on_add: function(item, callback) {
this._trigger(item, callback, "onAdd");
},
/**
* Trigger_up encapsulation adds by default the rights, and the renderer.
*
* @param {HTMLElement} item
* @param {Function} callback
* @param {String} trigger
* @private
*/
_trigger: function (item, callback, trigger) {
_trigger: function(item, callback, trigger) {
this.trigger_up(trigger, {
'item': item,
'callback': callback,
'rights': this.modelClass.data.rights,
'renderer': this,
item: item,
callback: callback,
rights: this.modelClass.data.rights,
renderer: this,
});
},
});
return TimelineRenderer;

View File

@ -1,31 +1,31 @@
/* global py */
/* Odoo web_timeline
* Copyright 2015 ACSONE SA/NV
* Copyright 2016 Pedro M. Baeza <pedro.baeza@tecnativa.com>
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
odoo.define('web_timeline.TimelineView', function (require) {
odoo.define("web_timeline.TimelineView", function(require) {
"use strict";
var core = require('web.core');
var utils = require('web.utils');
var view_registry = require('web.view_registry');
var AbstractView = require('web.AbstractView');
var TimelineRenderer = require('web_timeline.TimelineRenderer');
var TimelineController = require('web_timeline.TimelineController');
var TimelineModel = require('web_timeline.TimelineModel');
const core = require("web.core");
const utils = require("web.utils");
const view_registry = require("web.view_registry");
const AbstractView = require("web.AbstractView");
const TimelineRenderer = require("web_timeline.TimelineRenderer");
const TimelineController = require("web_timeline.TimelineController");
const TimelineModel = require("web_timeline.TimelineModel");
var _lt = core._lt;
const _lt = core._lt;
function isNullOrUndef(value) {
return _.isUndefined(value) || _.isNull(value);
}
var TimelineView = AbstractView.extend({
display_name: _lt('Timeline'),
icon: 'fa-clock-o',
jsLibs: ['/web_timeline/static/lib/vis-timeline/vis-timeline-graph2d.min.js'],
cssLibs: ['/web_timeline/static/lib/vis-timeline/vis-timeline-graph2d.min.css'],
display_name: _lt("Timeline"),
icon: "fa-tasks",
jsLibs: ["/web_timeline/static/lib/vis-timeline/vis-timeline-graph2d.min.js"],
cssLibs: ["/web_timeline/static/lib/vis-timeline/vis-timeline-graph2d.min.css"],
config: {
Model: TimelineModel,
Controller: TimelineController,
@ -35,123 +35,112 @@ odoo.define('web_timeline.TimelineView', function (require) {
/**
* @override
*/
init: function (viewInfo, params) {
init: function(viewInfo, params) {
this._super.apply(this, arguments);
var self = this;
this.timeline = false;
this.arch = this.rendererParams.arch;
var attrs = this.arch.attrs;
this.fields = viewInfo.fields;
this.modelName = this.controllerParams.modelName;
this.action = params.action;
var fieldNames = this.fields.display_name ? ['display_name'] : [];
var mapping = {};
var fieldsToGather = [
const action = params.action;
this.arch = this.rendererParams.arch;
const attrs = this.arch.attrs;
const date_start = attrs.date_start;
const date_stop = attrs.date_stop;
const date_delay = attrs.date_delay;
const dependency_arrow = attrs.dependency_arrow;
const fields = viewInfo.fields;
let fieldNames = fields.display_name ? ["display_name"] : [];
const fieldsToGather = [
"date_start",
"date_stop",
"default_group_by",
"progress",
"date_delay",
attrs.default_group_by,
];
fieldsToGather.push(attrs.default_group_by);
for (const field of fieldsToGather) {
if (attrs[field]) {
var fieldName = attrs[field];
mapping[field] = fieldName;
fieldNames.push(fieldName);
fieldNames.push(attrs[field]);
}
}
var archFieldNames = _.map(_.filter(this.arch.children, function (item) {
return item.tag === 'field';
}), function (item) {
return item.attrs.name;
});
fieldNames = _.union(
fieldNames,
archFieldNames
const archFieldNames = _.map(
_.filter(this.arch.children, item => item.tag === "field"),
item => item.attrs.name
);
fieldNames = _.union(fieldNames, archFieldNames);
this.parse_colors();
for (const color of this.colors) {
const colors = this.parse_colors();
for (const color of colors) {
fieldNames.push(color.field);
}
if (attrs.dependency_arrow) {
fieldNames.push(attrs.dependency_arrow);
if (dependency_arrow) {
fieldNames.push(dependency_arrow);
}
this.permissions = {};
this.grouped_by = false;
this.date_start = attrs.date_start;
this.date_stop = attrs.date_stop;
this.date_delay = attrs.date_delay;
this.dependency_arrow = attrs.dependency_arrow;
const mode = attrs.mode || attrs.default_window || "fit";
const min_height = attrs.min_height || 300;
this.no_period = this.date_start === this.date_stop;
this.zoomKey = attrs.zoomKey || '';
this.margin = attrs.margin || '{}';
this.mode = attrs.mode || attrs.default_window || 'fit';
this.min_height = attrs.min_height || 300;
this.current_window = {
const current_window = {
start: new moment(),
end: new moment().add(24, 'hours'),
end: new moment().add(24, "hours"),
};
if (!isNullOrUndef(attrs.quick_create_instance)) {
self.quick_create_instance = 'instance.' + attrs.quick_create_instance;
this.quick_create_instance = "instance." + attrs.quick_create_instance;
}
this.stack = true;
if (!isNullOrUndef(attrs.stack) && !utils.toBoolElse(attrs.stack, true)) {
this.stack = false;
let open_popup_action = false;
if (
!isNullOrUndef(attrs.event_open_popup) &&
utils.toBoolElse(attrs.event_open_popup, true)
) {
open_popup_action = attrs.event_open_popup;
}
this.options = {
this.rendererParams.mode = mode;
this.rendererParams.model = this.modelName;
this.rendererParams.view = this;
this.rendererParams.options = this._preapre_vis_timeline_options(attrs);
this.rendererParams.current_window = current_window;
this.rendererParams.date_start = date_start;
this.rendererParams.date_stop = date_stop;
this.rendererParams.date_delay = date_delay;
this.rendererParams.colors = colors;
this.rendererParams.fieldNames = fieldNames;
this.rendererParams.min_height = min_height;
this.rendererParams.dependency_arrow = dependency_arrow;
this.rendererParams.fields = fields;
this.loadParams.modelName = this.modelName;
this.loadParams.fieldNames = fieldNames;
this.controllerParams.open_popup_action = open_popup_action;
this.controllerParams.date_start = date_start;
this.controllerParams.date_stop = date_stop;
this.controllerParams.date_delay = date_delay;
this.controllerParams.actionContext = action.context;
this.withSearchPanel = false;
},
_preapre_vis_timeline_options: function(attrs) {
return {
groupOrder: this.group_order,
orientation: 'both',
orientation: "both",
selectable: true,
multiselect: true,
showCurrentTime: true,
stack: this.stack,
margin: JSON.parse(this.margin),
zoomKey: this.zoomKey,
stack: isNullOrUndef(attrs.stack)
? true
: utils.toBoolElse(attrs.stack, true),
margin: attrs.margin ? JSON.parse(attrs.margin) : {item: 2},
zoomKey: attrs.zoomKey || "ctrlKey",
};
if (isNullOrUndef(attrs.event_open_popup) || !utils.toBoolElse(attrs.event_open_popup, true)) {
this.open_popup_action = false;
} else {
this.open_popup_action = attrs.event_open_popup;
}
this.rendererParams.mode = this.mode;
this.rendererParams.model = this.modelName;
this.rendererParams.options = this.options;
this.rendererParams.permissions = this.permissions;
this.rendererParams.current_window = this.current_window;
this.rendererParams.timeline = this.timeline;
this.rendererParams.date_start = this.date_start;
this.rendererParams.date_stop = this.date_stop;
this.rendererParams.date_delay = this.date_delay;
this.rendererParams.colors = this.colors;
this.rendererParams.fieldNames = fieldNames;
this.rendererParams.view = this;
this.rendererParams.min_height = this.min_height;
this.rendererParams.dependency_arrow = this.dependency_arrow;
this.loadParams.modelName = this.modelName;
this.loadParams.fieldNames = fieldNames;
this.controllerParams.open_popup_action = this.open_popup_action;
this.controllerParams.date_start = this.date_start;
this.controllerParams.date_stop = this.date_stop;
this.controllerParams.date_delay = this.date_delay;
this.controllerParams.actionContext = this.action.context;
this.withSearchPanel = false;
},
/**
* Order function for groups.
* @param {Object} grp1
* @param {Object} grp2
* @returns {Integer}
*/
group_order: function (grp1, grp2) {
group_order: function(grp1, grp2) {
// Display non grouped elements first
if (grp1.id === -1) {
return -1;
@ -167,26 +156,31 @@ odoo.define('web_timeline.TimelineView', function (require) {
* Parse the colors attribute.
*
* @private
* @returns {Array}
*/
parse_colors: function () {
parse_colors: function() {
if (this.arch.attrs.colors) {
this.colors = _(this.arch.attrs.colors.split(';')).chain().compact().map(function (color_pair) {
var pair = color_pair.split(':'), color = pair[0], expr = pair[1];
var temp = py.parse(py.tokenize(expr));
return {
'color': color,
'field': temp.expressions[0].value,
'opt': temp.operators[0],
'value': temp.expressions[1].value,
};
}).value();
} else {
this.colors = [];
return _(this.arch.attrs.colors.split(";"))
.chain()
.compact()
.map(color_pair => {
const pair = color_pair.split(":");
const color = pair[0];
const expr = pair[1];
const temp = py.parse(py.tokenize(expr));
return {
color: color,
field: temp.expressions[0].value,
opt: temp.operators[0],
value: temp.expressions[1].value,
};
})
.value();
}
return [];
},
});
view_registry.add('timeline', TimelineView);
view_registry.add("timeline", TimelineView);
return TimelineView;
});

View File

@ -1,8 +1,11 @@
$vis-weekend-background-color: #dcdcdc;
$vis-item-content-padding: 0 3px !important;
.oe_timeline_view .vis-timeline {
.vis-grid {
.vis-saturday, .vis-sunday {
// very light gray background in weekends
background: #DCDCDC;
&.vis-saturday,
&.vis-sunday {
background: $vis-weekend-background-color;
}
}
@ -13,5 +16,17 @@
&.vis-item-overflow {
overflow: visible;
}
.vis-item-content {
padding: $vis-item-content-padding;
}
}
}
.oe_timeline_view_canvas {
pointer-events: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

View File

@ -1,25 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<template>
<t t-name="TimelineView">
<div class="oe_timeline_view">
<div class="oe_timeline_buttons">
<button class="btn btn-default btn-sm oe_timeline_button_today">Today</button>
<button
class="btn btn-default btn-sm oe_timeline_button_today"
>Today</button>
<div class="btn-group btn-sm">
<button class="btn btn-default oe_timeline_button_scale_day">Day</button>
<button class="btn btn-default oe_timeline_button_scale_week">Week</button>
<button class="btn btn-default oe_timeline_button_scale_month">Month</button>
<button class="btn btn-default oe_timeline_button_scale_year">Year</button>
<button
class="btn btn-default oe_timeline_button_scale_day"
>Day</button>
<button
class="btn btn-default oe_timeline_button_scale_week"
>Week</button>
<button
class="btn btn-default oe_timeline_button_scale_month"
>Month</button>
<button
class="btn btn-default oe_timeline_button_scale_year"
>Year</button>
</div>
</div>
<div class="oe_timeline_widget"/>
<div class="oe_timeline_widget" />
</div>
</t>
<svg t-name="TimelineView.Canvas" class="oe_timeline_view_canvas">
<defs>
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
<polygon points="10 0, 10 7, 0 3.5"/>
<marker
id="arrowhead"
markerWidth="10"
markerHeight="7"
refX="10"
refY="3.5"
orient="auto"
>
<polygon points="10 0, 10 7, 0 3.5" />
</marker>
</defs>
</svg>

View File

@ -1,16 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="assets_backend" name="web_timeline assets" inherit_id="web.assets_backend">
<template
id="assets_backend"
name="web_timeline assets"
inherit_id="web.assets_backend"
>
<xpath expr="." position="inside">
<link rel="stylesheet" type="text/css" href="/web_timeline/static/lib/vis-timeline/vis-timeline-graph2d.min.css"/>
<link rel="stylesheet" type="text/scss" href="/web_timeline/static/src/scss/web_timeline.scss"/>
<script type="text/javascript" src="/web_timeline/static/lib/vis-timeline/vis-timeline-graph2d.min.js"/>
<script type="text/javascript" src="/web_timeline/static/src/js/timeline_view.js"/>
<script type="text/javascript" src="/web_timeline/static/src/js/timeline_renderer.js"/>
<script type="text/javascript" src="/web_timeline/static/src/js/timeline_controller.js"/>
<script type="text/javascript" src="/web_timeline/static/src/js/timeline_model.js"/>
<script type="text/javascript" src="/web_timeline/static/src/js/timeline_canvas.js"/>
<link
rel="stylesheet"
type="text/css"
href="/web_timeline/static/lib/vis-timeline/vis-timeline-graph2d.css"
/>
<link
rel="stylesheet"
type="text/scss"
href="/web_timeline/static/src/scss/web_timeline.scss"
/>
<script
type="text/javascript"
src="/web_timeline/static/lib/vis-timeline/vis-timeline-graph2d.min.js"
/>
<script
type="text/javascript"
src="/web_timeline/static/src/js/timeline_view.js"
/>
<script
type="text/javascript"
src="/web_timeline/static/src/js/timeline_renderer.js"
/>
<script
type="text/javascript"
src="/web_timeline/static/src/js/timeline_controller.js"
/>
<script
type="text/javascript"
src="/web_timeline/static/src/js/timeline_model.js"
/>
<script
type="text/javascript"
src="/web_timeline/static/src/js/timeline_canvas.js"
/>
</xpath>
</template>
</odoo>