[MIG] web_timeline: Migration to 16.0

Syntax changes

Syntax changes
pull/2969/head
anjeel.haria 2023-03-01 15:52:42 +01:00 committed by Carlos Lopez
parent b97fb4aa2c
commit c6d9bf6987
10 changed files with 509 additions and 428 deletions

View File

@ -14,13 +14,13 @@ Web timeline
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3 :alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github
:target: https://github.com/OCA/web/tree/15.0/web_timeline :target: https://github.com/OCA/web/tree/16.0/web_timeline
:alt: OCA/web :alt: OCA/web
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/web-15-0/web-15-0-web_timeline :target: https://translation.odoo-community.org/projects/web-16-0/web-16-0-web_timeline
:alt: Translate me on Weblate :alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/162/15.0 :target: https://runbot.odoo-community.org/runbot/162/16.0
:alt: Try me on Runbot :alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5| |badge1| |badge2| |badge3| |badge4| |badge5|
@ -91,25 +91,50 @@ Example:
<timeline date_start="date_assign" <timeline date_start="date_assign"
date_stop="date_end" date_stop="date_end"
string="Tasks" string="Tasks"
default_group_by="user_id" default_group_by="project_id"
event_open_popup="true" event_open_popup="true"
zoomKey="ctrlKey" colors="white: user_ids == []; #2ecb71: kanban_state == 'done'; #ec7063: kanban_state == 'blocked'"
colors="#ec7063:user_id == false;#2ecb71:kanban_state=='done';" dependency_arrow="depend_on_ids"
dependency_arrow="task_dependency_ids"> >
<field name="user_id"/> <field name="user_ids" />
<field name="planned_hours" />
<templates> <templates>
<div t-name="timeline-item"> <t t-name="timeline-item">
<div t-esc="record.display_name"/> <div class="o_project_timeline_item">
Assigned to: <t t-foreach="record.user_ids" t-as="user">
<span t-esc="record.user_id[1]"/> <img
</div> t-if="record.user_ids"
t-attf-src="/web/image/res.users/#{user}/image_128/16x16"
t-att-title="record.user"
width="16"
height="16"
class="mr8"
alt="User"
/>
</t>
<span name="display_name">
<t t-esc="record.display_name" />
</span>
<small
name="planned_hours"
class="text-info ml4"
t-if="record.planned_hours"
>
<t
t-esc="field_utils.format.float_time(record.planned_hours)"
/>
</small>
</div>
</t>
</templates> </templates>
</timeline> </timeline>
</field> </field>
</record> </record>
<record id="project.action_view_task" model="ir.actions.act_window"> <record id="project.action_view_task" model="ir.actions.act_window">
<field name="view_mode">kanban,tree,form,calendar,gantt,timeline,graph</field> <field
name="view_mode"
>kanban,tree,form,calendar,timeline,pivot,graph,activity</field>
</record> </record>
</odoo> </odoo>
@ -165,7 +190,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues <https://github.com/OCA/web/issues>`_. 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. 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 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:%2015.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:%2016.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. Do not contact contributors directly about support or help with technical issues.
@ -188,7 +213,6 @@ Contributors
* Adrien Peiffer <adrien.peiffer@acsone.eu> * Adrien Peiffer <adrien.peiffer@acsone.eu>
* Leonardo Donelli <donelli@webmonks.it> * Leonardo Donelli <donelli@webmonks.it>
* Adrien Didenot <adrien.didenot@horanet.com> * Adrien Didenot <adrien.didenot@horanet.com>
* Dennis Sluijk <d.sluijk@onestein.nl>
* Thong Nguyen Van <thongnv@trobz.com> * Thong Nguyen Van <thongnv@trobz.com>
* Murtaza Mithaiwala <mmithaiwala@opensourceintegrators.com> * Murtaza Mithaiwala <mmithaiwala@opensourceintegrators.com>
* Ammar Officewala <aofficewala@opensourceintegrators.com> * Ammar Officewala <aofficewala@opensourceintegrators.com>
@ -197,6 +221,9 @@ Contributors
* Pedro M. Baeza * Pedro M. Baeza
* Alexandre Díaz * Alexandre Díaz
* César A. Sánchez * César A. Sánchez
* `Onestein <https://www.onestein.nl>`_:
* Dennis Sluijk <d.sluijk@onestein.nl>
* Anjeel Haria
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~
@ -219,6 +246,6 @@ 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/15.0/web_timeline>`_ project on GitHub. This module is part of the `OCA/web <https://github.com/OCA/web/tree/16.0/web_timeline>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@ -4,7 +4,7 @@
{ {
"name": "Web timeline", "name": "Web timeline",
"summary": "Interactive visualization chart to show events in time", "summary": "Interactive visualization chart to show events in time",
"version": "15.0.1.0.1", "version": "16.0.1.0.0",
"development_status": "Production/Stable", "development_status": "Production/Stable",
"author": "ACSONE SA/NV, " "author": "ACSONE SA/NV, "
"Tecnativa, " "Tecnativa, "
@ -25,11 +25,9 @@
"web_timeline/static/src/scss/web_timeline.scss", "web_timeline/static/src/scss/web_timeline.scss",
"web_timeline/static/src/js/timeline_view.js", "web_timeline/static/src/js/timeline_view.js",
"web_timeline/static/src/js/timeline_renderer.js", "web_timeline/static/src/js/timeline_renderer.js",
"web_timeline/static/src/js/timeline_controller.js", "web_timeline/static/src/js/timeline_controller.esm.js",
"web_timeline/static/src/js/timeline_model.js", "web_timeline/static/src/js/timeline_model.js",
"web_timeline/static/src/js/timeline_canvas.js", "web_timeline/static/src/js/timeline_canvas.js",
],
"web.assets_qweb": [
"web_timeline/static/src/xml/web_timeline.xml", "web_timeline/static/src/xml/web_timeline.xml",
], ],
}, },

View File

@ -4,7 +4,7 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 15.0\n" "Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
@ -14,42 +14,42 @@ msgstr ""
"Plural-Forms: \n" "Plural-Forms: \n"
#. module: web_timeline #. module: web_timeline
#. openerp-web #. odoo-javascript
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0 #: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format #, python-format
msgid "<b>UNASSIGNED</b>" msgid "<b>UNASSIGNED</b>"
msgstr "" msgstr ""
#. module: web_timeline #. module: web_timeline
#. openerp-web #. odoo-javascript
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0 #: code:addons/web_timeline/static/src/js/timeline_controller.esm.js:0
#, python-format #, python-format
msgid "Are you sure you want to delete this record?" msgid "Are you sure you want to delete this record?"
msgstr "" msgstr ""
#. module: web_timeline #. module: web_timeline
#. openerp-web #. odoo-javascript
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0 #: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format #, python-format
msgid "Day" msgid "Day"
msgstr "" msgstr ""
#. module: web_timeline #. module: web_timeline
#. openerp-web #. odoo-javascript
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0 #: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format #, python-format
msgid "Month" msgid "Month"
msgstr "" msgstr ""
#. module: web_timeline #. module: web_timeline
#. openerp-web #. odoo-javascript
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0 #: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format #, python-format
msgid "Template \"timeline-item\" not present in timeline view definition." msgid "Template \"timeline-item\" not present in timeline view definition."
msgstr "" msgstr ""
#. module: web_timeline #. module: web_timeline
#. openerp-web #. odoo-javascript
#: code:addons/web_timeline/static/src/js/timeline_view.js: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 #: model:ir.model.fields.selection,name:web_timeline.selection__ir_ui_view__type__timeline
#, python-format #, python-format
@ -57,14 +57,14 @@ msgid "Timeline"
msgstr "" msgstr ""
#. module: web_timeline #. module: web_timeline
#. openerp-web #. odoo-javascript
#: code:addons/web_timeline/static/src/js/timeline_renderer.js:0 #: code:addons/web_timeline/static/src/js/timeline_renderer.js:0
#, python-format #, python-format
msgid "Timeline view has not defined 'date_start' attribute." msgid "Timeline view has not defined 'date_start' attribute."
msgstr "" msgstr ""
#. module: web_timeline #. module: web_timeline
#. openerp-web #. odoo-javascript
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0 #: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format #, python-format
msgid "Today" msgid "Today"
@ -81,21 +81,21 @@ msgid "View Type"
msgstr "" msgstr ""
#. module: web_timeline #. module: web_timeline
#. openerp-web #. odoo-javascript
#: code:addons/web_timeline/static/src/js/timeline_controller.js:0 #: code:addons/web_timeline/static/src/js/timeline_controller.esm.js:0
#, python-format #, python-format
msgid "Warning" msgid "Warning"
msgstr "" msgstr ""
#. module: web_timeline #. module: web_timeline
#. openerp-web #. odoo-javascript
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0 #: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format #, python-format
msgid "Week" msgid "Week"
msgstr "" msgstr ""
#. module: web_timeline #. module: web_timeline
#. openerp-web #. odoo-javascript
#: code:addons/web_timeline/static/src/xml/web_timeline.xml:0 #: code:addons/web_timeline/static/src/xml/web_timeline.xml:0
#, python-format #, python-format
msgid "Year" msgid "Year"

View File

@ -51,24 +51,49 @@ Example:
<timeline date_start="date_assign" <timeline date_start="date_assign"
date_stop="date_end" date_stop="date_end"
string="Tasks" string="Tasks"
default_group_by="user_id" default_group_by="project_id"
event_open_popup="true" event_open_popup="true"
zoomKey="ctrlKey" colors="white: user_ids == []; #2ecb71: kanban_state == 'done'; #ec7063: kanban_state == 'blocked'"
colors="#ec7063:user_id == false;#2ecb71:kanban_state=='done';" dependency_arrow="depend_on_ids"
dependency_arrow="task_dependency_ids"> >
<field name="user_id"/> <field name="user_ids" />
<field name="planned_hours" />
<templates> <templates>
<div t-name="timeline-item"> <t t-name="timeline-item">
<div t-esc="record.display_name"/> <div class="o_project_timeline_item">
Assigned to: <t t-foreach="record.user_ids" t-as="user">
<span t-esc="record.user_id[1]"/> <img
</div> t-if="record.user_ids"
t-attf-src="/web/image/res.users/#{user}/image_128/16x16"
t-att-title="record.user"
width="16"
height="16"
class="mr8"
alt="User"
/>
</t>
<span name="display_name">
<t t-esc="record.display_name" />
</span>
<small
name="planned_hours"
class="text-info ml4"
t-if="record.planned_hours"
>
<t
t-esc="field_utils.format.float_time(record.planned_hours)"
/>
</small>
</div>
</t>
</templates> </templates>
</timeline> </timeline>
</field> </field>
</record> </record>
<record id="project.action_view_task" model="ir.actions.act_window"> <record id="project.action_view_task" model="ir.actions.act_window">
<field name="view_mode">kanban,tree,form,calendar,gantt,timeline,graph</field> <field
name="view_mode"
>kanban,tree,form,calendar,timeline,pivot,graph,activity</field>
</record> </record>
</odoo> </odoo>

View File

@ -2,7 +2,6 @@
* Adrien Peiffer <adrien.peiffer@acsone.eu> * Adrien Peiffer <adrien.peiffer@acsone.eu>
* Leonardo Donelli <donelli@webmonks.it> * Leonardo Donelli <donelli@webmonks.it>
* Adrien Didenot <adrien.didenot@horanet.com> * Adrien Didenot <adrien.didenot@horanet.com>
* Dennis Sluijk <d.sluijk@onestein.nl>
* Thong Nguyen Van <thongnv@trobz.com> * Thong Nguyen Van <thongnv@trobz.com>
* Murtaza Mithaiwala <mmithaiwala@opensourceintegrators.com> * Murtaza Mithaiwala <mmithaiwala@opensourceintegrators.com>
* Ammar Officewala <aofficewala@opensourceintegrators.com> * Ammar Officewala <aofficewala@opensourceintegrators.com>
@ -11,3 +10,6 @@
* Pedro M. Baeza * Pedro M. Baeza
* Alexandre Díaz * Alexandre Díaz
* César A. Sánchez * César A. Sánchez
* `Onestein <https://www.onestein.nl>`_:
* Dennis Sluijk <d.sluijk@onestein.nl>
* Anjeel Haria

View File

@ -367,7 +367,7 @@ ul.auto-toc {
!! This file is generated by oca-gen-addon-readme !! !! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !! !! 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/15.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-15-0/web-15-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/15.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/16.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-16-0/web-16-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/16.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>Define a new view displaying events in an interactive visualization chart.</p>
<p>The widget is based on the external library <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> <a class="reference external" href="https://visjs.github.io/vis-timeline/examples/timeline">https://visjs.github.io/vis-timeline/examples/timeline</a></p>
@ -470,25 +470,50 @@ These are the variables available in template rendering:</p>
<span class="nt">&lt;timeline</span> <span class="na">date_start=</span><span class="s">&quot;date_assign&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">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">string=</span><span class="s">&quot;Tasks&quot;</span>
<span class="na">default_group_by=</span><span class="s">&quot;user_id&quot;</span> <span class="na">default_group_by=</span><span class="s">&quot;project_id&quot;</span>
<span class="na">event_open_popup=</span><span class="s">&quot;true&quot;</span> <span class="na">event_open_popup=</span><span class="s">&quot;true&quot;</span>
<span class="na">zoomKey=</span><span class="s">&quot;ctrlKey&quot;</span> <span class="na">colors=</span><span class="s">&quot;white: user_ids == []; #2ecb71: kanban_state == 'done'; #ec7063: kanban_state == 'blocked'&quot;</span>
<span class="na">colors=</span><span class="s">&quot;#ec7063:user_id == false;#2ecb71:kanban_state=='done';&quot;</span> <span class="na">dependency_arrow=</span><span class="s">&quot;depend_on_ids&quot;</span>
<span class="na">dependency_arrow=</span><span class="s">&quot;task_dependency_ids&quot;</span><span class="nt">&gt;</span> <span class="nt">&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;user_id&quot;</span><span class="nt">/&gt;</span> <span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;user_ids&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;planned_hours&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;templates&gt;</span> <span class="nt">&lt;templates&gt;</span>
<span class="nt">&lt;div</span> <span class="na">t-name=</span><span class="s">&quot;timeline-item&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;t</span> <span class="na">t-name=</span><span class="s">&quot;timeline-item&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;div</span> <span class="na">t-esc=</span><span class="s">&quot;record.display_name&quot;</span><span class="nt">/&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;o_project_timeline_item&quot;</span><span class="nt">&gt;</span>
Assigned to: <span class="nt">&lt;t</span> <span class="na">t-foreach=</span><span class="s">&quot;record.user_ids&quot;</span> <span class="na">t-as=</span><span class="s">&quot;user&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;span</span> <span class="na">t-esc=</span><span class="s">&quot;record.user_id[1]&quot;</span><span class="nt">/&gt;</span> <span class="nt">&lt;img</span>
<span class="nt">&lt;/div&gt;</span> <span class="na">t-if=</span><span class="s">&quot;record.user_ids&quot;</span>
<span class="na">t-attf-src=</span><span class="s">&quot;/web/image/res.users/#{user}/image_128/16x16&quot;</span>
<span class="na">t-att-title=</span><span class="s">&quot;record.user&quot;</span>
<span class="na">width=</span><span class="s">&quot;16&quot;</span>
<span class="na">height=</span><span class="s">&quot;16&quot;</span>
<span class="na">class=</span><span class="s">&quot;mr8&quot;</span>
<span class="na">alt=</span><span class="s">&quot;User&quot;</span>
<span class="nt">/&gt;</span>
<span class="nt">&lt;/t&gt;</span>
<span class="nt">&lt;span</span> <span class="na">name=</span><span class="s">&quot;display_name&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;t</span> <span class="na">t-esc=</span><span class="s">&quot;record.display_name&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/span&gt;</span>
<span class="nt">&lt;small</span>
<span class="na">name=</span><span class="s">&quot;planned_hours&quot;</span>
<span class="na">class=</span><span class="s">&quot;text-info ml4&quot;</span>
<span class="na">t-if=</span><span class="s">&quot;record.planned_hours&quot;</span>
<span class="nt">&gt;</span>
<span class="nt">&lt;t</span>
<span class="na">t-esc=</span><span class="s">&quot;field_utils.format.float_time(record.planned_hours)&quot;</span>
<span class="nt">/&gt;</span>
<span class="nt">&lt;/small&gt;</span>
<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/t&gt;</span>
<span class="nt">&lt;/templates&gt;</span> <span class="nt">&lt;/templates&gt;</span>
<span class="nt">&lt;/timeline&gt;</span> <span class="nt">&lt;/timeline&gt;</span>
<span class="nt">&lt;/field&gt;</span> <span class="nt">&lt;/field&gt;</span>
<span class="nt">&lt;/record&gt;</span> <span class="nt">&lt;/record&gt;</span>
<span class="nt">&lt;record</span> <span class="na">id=</span><span class="s">&quot;project.action_view_task&quot;</span> <span class="na">model=</span><span class="s">&quot;ir.actions.act_window&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;record</span> <span class="na">id=</span><span class="s">&quot;project.action_view_task&quot;</span> <span class="na">model=</span><span class="s">&quot;ir.actions.act_window&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;view_mode&quot;</span><span class="nt">&gt;</span>kanban,tree,form,calendar,gantt,timeline,graph<span class="nt">&lt;/field&gt;</span> <span class="nt">&lt;field</span>
<span class="na">name=</span><span class="s">&quot;view_mode&quot;</span>
<span class="nt">&gt;</span>kanban,tree,form,calendar,timeline,pivot,graph,activity<span class="nt">&lt;/field&gt;</span>
<span class="nt">&lt;/record&gt;</span> <span class="nt">&lt;/record&gt;</span>
<span class="nt">&lt;/odoo&gt;</span> <span class="nt">&lt;/odoo&gt;</span>
</pre> </pre>
@ -539,7 +564,7 @@ the value according the group of the dragged item.</li>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/web/issues">GitHub Issues</a>. <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. 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 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:%2015.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:%2016.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> <p>Do not contact contributors directly about support or help with technical issues.</p>
</div> </div>
<div class="section" id="credits"> <div class="section" id="credits">
@ -561,7 +586,6 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<li>Adrien Peiffer &lt;<a class="reference external" href="mailto:adrien.peiffer&#64;acsone.eu">adrien.peiffer&#64;acsone.eu</a>&gt;</li> <li>Adrien Peiffer &lt;<a class="reference external" href="mailto:adrien.peiffer&#64;acsone.eu">adrien.peiffer&#64;acsone.eu</a>&gt;</li>
<li>Leonardo Donelli &lt;<a class="reference external" href="mailto:donelli&#64;webmonks.it">donelli&#64;webmonks.it</a>&gt;</li> <li>Leonardo Donelli &lt;<a class="reference external" href="mailto:donelli&#64;webmonks.it">donelli&#64;webmonks.it</a>&gt;</li>
<li>Adrien Didenot &lt;<a class="reference external" href="mailto:adrien.didenot&#64;horanet.com">adrien.didenot&#64;horanet.com</a>&gt;</li> <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>Thong Nguyen Van &lt;<a class="reference external" href="mailto:thongnv&#64;trobz.com">thongnv&#64;trobz.com</a>&gt;</li>
<li>Murtaza Mithaiwala &lt;<a class="reference external" href="mailto:mmithaiwala&#64;opensourceintegrators.com">mmithaiwala&#64;opensourceintegrators.com</a>&gt;</li> <li>Murtaza Mithaiwala &lt;<a class="reference external" href="mailto:mmithaiwala&#64;opensourceintegrators.com">mmithaiwala&#64;opensourceintegrators.com</a>&gt;</li>
<li>Ammar Officewala &lt;<a class="reference external" href="mailto:aofficewala&#64;opensourceintegrators.com">aofficewala&#64;opensourceintegrators.com</a>&gt;</li> <li>Ammar Officewala &lt;<a class="reference external" href="mailto:aofficewala&#64;opensourceintegrators.com">aofficewala&#64;opensourceintegrators.com</a>&gt;</li>
@ -571,6 +595,15 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<li>César A. Sánchez</li> <li>César A. Sánchez</li>
</ul> </ul>
</li> </li>
<li><dl class="first docutils">
<dt><a class="reference external" href="https://www.onestein.nl">Onestein</a>:</dt>
<dd><ul class="first last">
<li>Dennis Sluijk &lt;<a class="reference external" href="mailto:d.sluijk&#64;onestein.nl">d.sluijk&#64;onestein.nl</a>&gt;</li>
<li>Anjeel Haria</li>
</ul>
</dd>
</dl>
</li>
</ul> </ul>
</div> </div>
<div class="section" id="maintainers"> <div class="section" id="maintainers">
@ -582,7 +615,7 @@ mission is to support the collaborative development of Odoo features and
promote its widespread use.</p> promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</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><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/15.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/16.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> <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>
</div> </div>

View File

@ -50109,4 +50109,3 @@
Object.defineProperty(exports, '__esModule', { value: true }); Object.defineProperty(exports, '__esModule', { value: true });
})); }));
//# sourceMappingURL=vis-timeline-graph2d.js.map

View File

@ -0,0 +1,360 @@
/** @odoo-module alias=web_timeline.TimelineController **/
/* Copyright 2023 Onestein - Anjeel Haria
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */
import AbstractController from "web.AbstractController";
import {FormViewDialog} from "@web/views/view_dialogs/form_view_dialog";
import time from "web.time";
import core from "web.core";
import Dialog from "web.Dialog";
var _t = core._t;
import {Component} from "@odoo/owl";
export default AbstractController.extend({
custom_events: _.extend({}, AbstractController.prototype.custom_events, {
onGroupClick: "_onGroupClick",
onUpdate: "_onUpdate",
onRemove: "_onRemove",
onMove: "_onMove",
onAdd: "_onAdd",
}),
/**
* @override
*/
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;
this.date_stop = params.date_stop;
this.date_delay = params.date_delay;
this.context = params.actionContext;
this.moveQueue = [];
this.debouncedInternalMove = _.debounce(this.internalMove, 0);
},
on_detach_callback() {
if (this.Dialog) {
this.Dialog();
this.Dialog = undefined;
}
return this._super.apply(this, arguments);
},
/**
* @override
*/
update: function (params, options) {
const res = this._super.apply(this, arguments);
if (_.isEmpty(params)) {
return res;
}
const defaults = _.defaults({}, options, {
adjust_window: true,
});
const domains = params.domain || this.renderer.last_domains || [];
const contexts = params.context || [];
const group_bys = params.groupBy || this.renderer.last_group_bys || [];
this.last_domains = domains;
this.last_contexts = contexts;
// Select the group by
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(",");
}
this.renderer.last_group_bys = n_group_bys;
this.renderer.last_domains = domains;
let fields = this.renderer.fieldNames;
fields = _.uniq(fields.concat(n_group_bys));
$.when(
res,
this._rpc({
model: this.model.modelName,
method: "search_read",
kwargs: {
fields: fields,
domain: domains,
order: [{name: this.renderer.arch.attrs.default_group_by}],
},
context: this.getSession().user_context,
}).then((data) =>
this.renderer.on_data_loaded(data, n_group_bys, defaults.adjust_window)
)
);
return res;
},
/**
* Gets triggered when a group in the timeline is
* clicked (by the TimelineRenderer).
*
* @private
* @param {EventObject} event
* @returns {jQuery.Deferred}
*/
_onGroupClick: function (event) {
const groupField = this.renderer.last_group_bys[0];
return this.do_action({
type: "ir.actions.act_window",
res_model: this.renderer.fields[groupField].relation,
res_id: event.data.item.group,
target: "new",
views: [[false, "form"]],
});
},
/**
* Opens a form view of a clicked timeline
* item (triggered by the TimelineRenderer).
*
* @private
* @param {EventObject} event
*/
_onUpdate: function (event) {
this.renderer = event.data.renderer;
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) {
this.Dialog = Component.env.services.dialog.add(
FormViewDialog,
{
resId: id,
context: this.getSession().user_context,
title: title,
onRecordSaved: () => this.write_completed(),
resModel: this.model.modelName,
},
{}
);
} else {
let mode = "readonly";
if (rights.write) {
mode = "edit";
}
this.trigger_up("switch_view", {
view_type: "form",
res_id: id,
mode: mode,
model: this.model.modelName,
});
}
},
/**
* Gets triggered when a timeline item is
* moved (triggered by the TimelineRenderer).
*
* @private
* @param {EventObject} event
*/
_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;
}
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
);
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
);
} else {
data[this.date_stop] = data[this.date_start];
}
}
if (this.date_delay && event_end) {
const diff_seconds = Math.round(
(event_end.getTime() - event_start.getTime()) / 1000
);
data[this.date_delay] = diff_seconds / 3600;
}
const grouped_field = this.renderer.last_group_bys[0];
this._rpc({
model: this.modelName,
method: "fields_get",
args: [grouped_field],
context: this.getSession().user_context,
}).then(async (fields_processed) => {
if (
this.renderer.last_group_bys &&
this.renderer.last_group_bys instanceof Array &&
fields_processed[grouped_field].type !== "many2many"
) {
data[this.renderer.last_group_bys[0]] = group;
}
this.moveQueue.push({
id: event.data.item.id,
data: data,
event: event,
});
this.debouncedInternalMove();
});
},
/**
* Write enqueued moves to Odoo. After all writes are finished it updates
* the view once (prevents flickering of the view when multiple timeline items
* are moved at once).
*
* @returns {jQuery.Deferred}
*/
internalMove: function () {
const queues = this.moveQueue.slice();
this.moveQueue = [];
const defers = [];
for (const item of queues) {
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(() => {
this.write_completed({
adjust_window: false,
});
});
},
/**
* Triggered when a timeline item gets removed from the view.
* Requires user confirmation before it gets actually deleted.
*
* @private
* @param {EventObject} event
* @returns {jQuery.Deferred}
*/
_onRemove: function (event) {
var def = $.Deferred();
Dialog.confirm(this, _t("Are you sure you want to delete this record?"), {
title: _t("Warning"),
confirm_callback: () => {
this.remove_completed(event).then(def.resolve.bind(def));
},
cancel_callback: def.resolve.bind(def),
});
return def;
},
/**
* Triggered when a timeline item gets added and opens a form view.
*
* @private
* @param {EventObject} event
* @returns {dialogs.FormViewDialog}
*/
_onAdd: function (event) {
const item = event.data.item;
// Initialize default values for creation
const default_context = {};
default_context["default_".concat(this.date_start)] = item.start;
if (this.date_delay) {
default_context["default_".concat(this.date_delay)] = 1;
}
if (this.date_start) {
default_context["default_".concat(this.date_start)] = moment(item.start)
.utc()
.format("YYYY-MM-DD HH:mm:ss");
}
if (this.date_stop && item.end) {
default_context["default_".concat(this.date_stop)] = moment(item.end)
.utc()
.format("YYYY-MM-DD HH:mm:ss");
}
if (item.group > 0) {
default_context["default_".concat(this.renderer.last_group_bys[0])] =
item.group;
}
// Show popup
this.Dialog = Component.env.services.dialog.add(
FormViewDialog,
{
resId: null,
context: _.extend(default_context, this.context),
onRecordSaved: (record) => this.create_completed([record.res_id]),
resModel: this.model.modelName,
},
{onClose: () => event.data.callback()}
);
return false;
},
/**
* Triggered upon completion of a new record.
* Updates the timeline view with the new record.
*
* @param {RecordId} id
* @returns {jQuery.Deferred}
*/
create_completed: function (id) {
return this._rpc({
model: this.model.modelName,
method: "read",
args: [id, this.model.fieldNames],
context: this.context,
}).then((records) => {
var new_event = this.renderer.event_data_transform(records[0]);
var items = this.renderer.timeline.itemsData;
items.add(new_event);
});
},
/**
* Triggered upon completion of writing a record.
* @param {ControllerOptions} options
*/
write_completed: function (options) {
const params = {
domain: this.renderer.last_domains,
context: this.context,
groupBy: this.renderer.last_group_bys,
};
this.update(params, options);
},
/**
* Triggered upon confirm of removing a record.
* @param {EventObject} event
* @returns {jQuery.Deferred}
*/
remove_completed: function (event) {
return this._rpc({
model: this.modelName,
method: "unlink",
args: [[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)) {
this.model.data.data.splice(unlink_index, 1);
}
event.data.callback(event.data.item);
});
},
});

View File

@ -1,364 +0,0 @@
odoo.define("web_timeline.TimelineController", function (require) {
"use strict";
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");
const _t = core._t;
const TimelineController = AbstractController.extend({
custom_events: _.extend({}, AbstractController.prototype.custom_events, {
onGroupClick: "_onGroupClick",
onUpdate: "_onUpdate",
onRemove: "_onRemove",
onMove: "_onMove",
onAdd: "_onAdd",
}),
/**
* @override
*/
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;
this.date_stop = params.date_stop;
this.date_delay = params.date_delay;
this.context = params.actionContext;
this.moveQueue = [];
this.debouncedInternalMove = _.debounce(this.internalMove, 0);
},
/**
* @override
*/
update: function (params, options) {
const res = this._super.apply(this, arguments);
if (_.isEmpty(params)) {
return res;
}
const defaults = _.defaults({}, options, {
adjust_window: true,
});
const domains = params.domain || this.renderer.last_domains || [];
const contexts = params.context || [];
const group_bys = params.groupBy || this.renderer.last_group_bys || [];
this.last_domains = domains;
this.last_contexts = contexts;
// Select the group by
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(",");
}
this.renderer.last_group_bys = n_group_bys;
this.renderer.last_domains = domains;
let fields = this.renderer.fieldNames;
fields = _.uniq(fields.concat(n_group_bys));
$.when(
res,
this._rpc({
model: this.model.modelName,
method: "search_read",
kwargs: {
fields: fields,
domain: domains,
order: [{name: this.renderer.arch.attrs.default_group_by}],
},
context: this.getSession().user_context,
}).then((data) =>
this.renderer.on_data_loaded(
data,
n_group_bys,
defaults.adjust_window
)
)
);
return res;
},
/**
* Gets triggered when a group in the timeline is
* clicked (by the TimelineRenderer).
*
* @private
* @param {EventObject} event
* @returns {jQuery.Deferred}
*/
_onGroupClick: function (event) {
const groupField = this.renderer.last_group_bys[0];
return this.do_action({
type: "ir.actions.act_window",
res_model: this.renderer.fields[groupField].relation,
res_id: event.data.item.group,
target: "new",
views: [[false, "form"]],
});
},
/**
* Opens a form view of a clicked timeline
* item (triggered by the TimelineRenderer).
*
* @private
* @param {EventObject} event
*/
_onUpdate: function (event) {
this.renderer = event.data.renderer;
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,
res_id: id,
context: this.getSession().user_context,
title: title,
view_id: Number(this.open_popup_action),
on_saved: () => {
this.write_completed();
},
}).open();
} else {
let mode = "readonly";
if (rights.write) {
mode = "edit";
}
this.trigger_up("switch_view", {
view_type: "form",
res_id: id,
mode: mode,
model: this.model.modelName,
});
}
},
/**
* Gets triggered when a timeline item is
* moved (triggered by the TimelineRenderer).
*
* @private
* @param {EventObject} event
*/
_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;
}
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
);
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
);
} else {
data[this.date_stop] = data[this.date_start];
}
}
if (this.date_delay && event_end) {
const diff_seconds = Math.round(
(event_end.getTime() - event_start.getTime()) / 1000
);
data[this.date_delay] = diff_seconds / 3600;
}
const grouped_field = this.renderer.last_group_bys[0];
this._rpc({
model: this.modelName,
method: "fields_get",
args: [grouped_field],
context: this.getSession().user_context,
}).then(async (fields_processed) => {
if (
this.renderer.last_group_bys &&
this.renderer.last_group_bys instanceof Array &&
fields_processed[grouped_field].type !== "many2many"
) {
data[this.renderer.last_group_bys[0]] = group;
}
this.moveQueue.push({
id: event.data.item.id,
data: data,
event: event,
});
this.debouncedInternalMove();
});
},
/**
* Write enqueued moves to Odoo. After all writes are finished it updates
* the view once (prevents flickering of the view when multiple timeline items
* are moved at once).
*
* @returns {jQuery.Deferred}
*/
internalMove: function () {
const queues = this.moveQueue.slice();
this.moveQueue = [];
const defers = [];
for (const item of queues) {
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(() => {
this.write_completed({
adjust_window: false,
});
});
},
/**
* Triggered when a timeline item gets removed from the view.
* Requires user confirmation before it gets actually deleted.
*
* @private
* @param {EventObject} event
* @returns {jQuery.Deferred}
*/
_onRemove: function (event) {
var def = $.Deferred();
Dialog.confirm(this, _t("Are you sure you want to delete this record?"), {
title: _t("Warning"),
confirm_callback: () => {
this.remove_completed(event).then(def.resolve.bind(def));
},
cancel_callback: def.resolve.bind(def),
});
return def;
},
/**
* Triggered when a timeline item gets added and opens a form view.
*
* @private
* @param {EventObject} event
* @returns {dialogs.FormViewDialog}
*/
_onAdd: function (event) {
const item = event.data.item;
// Initialize default values for creation
const default_context = {};
default_context["default_".concat(this.date_start)] = item.start;
if (this.date_delay) {
default_context["default_".concat(this.date_delay)] = 1;
}
if (this.date_start) {
default_context["default_".concat(this.date_start)] = moment(item.start)
.utc()
.format("YYYY-MM-DD HH:mm:ss");
}
if (this.date_stop && item.end) {
default_context["default_".concat(this.date_stop)] = moment(item.end)
.utc()
.format("YYYY-MM-DD HH:mm:ss");
}
if (item.group > 0) {
default_context["default_".concat(this.renderer.last_group_bys[0])] =
item.group;
}
// Show popup
new dialogs.FormViewDialog(this, {
res_model: this.model.modelName,
res_id: null,
context: _.extend(default_context, this.context),
view_id: Number(this.open_popup_action),
on_saved: (record) => {
this.create_completed([record.res_id]);
},
})
.open()
.on("closed", this, () => {
event.data.callback();
});
return false;
},
/**
* Triggered upon completion of a new record.
* Updates the timeline view with the new record.
*
* @param {RecordId} id
* @returns {jQuery.Deferred}
*/
create_completed: function (id) {
return this._rpc({
model: this.model.modelName,
method: "read",
args: [id, this.model.fieldNames],
context: this.context,
}).then((records) => {
var new_event = this.renderer.event_data_transform(records[0]);
var items = this.renderer.timeline.itemsData;
items.add(new_event);
});
},
/**
* Triggered upon completion of writing a record.
* @param {ControllerOptions} options
*/
write_completed: function (options) {
const params = {
domain: this.renderer.last_domains,
context: this.context,
groupBy: this.renderer.last_group_bys,
};
this.update(params, options);
},
/**
* Triggered upon confirm of removing a record.
* @param {EventObject} event
* @returns {jQuery.Deferred}
*/
remove_completed: function (event) {
return this._rpc({
model: this.modelName,
method: "unlink",
args: [[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)) {
this.model.data.data.splice(unlink_index, 1);
}
event.data.callback(event.data.item);
});
},
});
return TimelineController;
});

View File

@ -2,6 +2,7 @@
/* Odoo web_timeline /* Odoo web_timeline
* Copyright 2015 ACSONE SA/NV * Copyright 2015 ACSONE SA/NV
* Copyright 2016 Pedro M. Baeza <pedro.baeza@tecnativa.com> * Copyright 2016 Pedro M. Baeza <pedro.baeza@tecnativa.com>
* Copyright 2023 Onestein - Anjeel Haria
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ * 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) {
@ -23,7 +24,7 @@ odoo.define("web_timeline.TimelineView", function (require) {
var TimelineView = AbstractView.extend({ var TimelineView = AbstractView.extend({
display_name: _lt("Timeline"), display_name: _lt("Timeline"),
icon: "fa-tasks", icon: "fa fa-tasks",
jsLibs: ["/web_timeline/static/lib/vis-timeline/vis-timeline-graph2d.js"], jsLibs: ["/web_timeline/static/lib/vis-timeline/vis-timeline-graph2d.js"],
cssLibs: ["/web_timeline/static/lib/vis-timeline/vis-timeline-graph2d.css"], cssLibs: ["/web_timeline/static/lib/vis-timeline/vis-timeline-graph2d.css"],
config: _.extend({}, AbstractView.prototype.config, { config: _.extend({}, AbstractView.prototype.config, {