[MIG] web_timeline: Migration to 18.0

pull/3136/head
JasminSForgeFlow 2025-03-28 13:13:32 +05:30
parent d2bca998b0
commit cf61ce8216
16 changed files with 107 additions and 85 deletions

View File

@ -17,13 +17,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/17.0/web_timeline :target: https://github.com/OCA/web/tree/18.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-17-0/web-17-0-web_timeline :target: https://translation.odoo-community.org/projects/web-18-0/web-18-0-web_timeline
:alt: Translate me on Weblate :alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/web&target_branch=17.0 :target: https://runboat.odoo-community.org/builds?repo=OCA/web&target_branch=18.0
:alt: Try me on Runboat :alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5| |badge1| |badge2| |badge3| |badge4| |badge5|
@ -202,7 +202,7 @@ More evolved example, from ``project_timeline``:
<record id="project.action_view_task" model="ir.actions.act_window"> <record id="project.action_view_task" model="ir.actions.act_window">
<field <field
name="view_mode" name="view_mode"
>kanban,tree,form,calendar,timeline,pivot,graph,activity</field> >kanban,list,form,calendar,timeline,pivot,graph,activity</field>
</record> </record>
</odoo> </odoo>
@ -264,7 +264,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 to smash it by providing a detailed and welcomed If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/web/issues/new?body=module:%20web_timeline%0Aversion:%2017.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:%2018.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.
@ -327,6 +327,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/17.0/web_timeline>`_ project on GitHub. This module is part of the `OCA/web <https://github.com/OCA/web/tree/18.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

@ -5,7 +5,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": "17.0.1.0.1", "version": "18.0.1.0.0",
"development_status": "Production/Stable", "development_status": "Production/Stable",
"author": "ACSONE SA/NV, " "author": "ACSONE SA/NV, "
"Tecnativa, " "Tecnativa, "
@ -34,7 +34,6 @@
"web_timeline/static/src/views/timeline/timeline_controller.xml", "web_timeline/static/src/views/timeline/timeline_controller.xml",
"web_timeline/static/src/views/timeline/timeline_model.esm.js", "web_timeline/static/src/views/timeline/timeline_model.esm.js",
"web_timeline/static/src/views/timeline/timeline_canvas.esm.js", "web_timeline/static/src/views/timeline/timeline_canvas.esm.js",
"web_timeline/static/src/views/timeline/timeline_view.xml",
], ],
"web_timeline.vis-timeline_lib": [ "web_timeline.vis-timeline_lib": [
"/web_timeline/static/lib/vis-timeline/vis-timeline-graph2d.js", "/web_timeline/static/lib/vis-timeline/vis-timeline-graph2d.js",

View File

@ -9,6 +9,6 @@
</field> </field>
</record> </record>
<record id="base.ir_cron_act" model="ir.actions.act_window"> <record id="base.ir_cron_act" model="ir.actions.act_window">
<field name="view_mode">tree,form,calendar,timeline</field> <field name="view_mode">list,form,calendar,timeline</field>
</record> </record>
</odoo> </odoo>

View File

@ -14,3 +14,6 @@ class IrUIView(models.Model):
def _is_qweb_based_view(self, view_type): def _is_qweb_based_view(self, view_type):
return view_type == TIMELINE_VIEW[0] or super()._is_qweb_based_view(view_type) return view_type == TIMELINE_VIEW[0] or super()._is_qweb_based_view(view_type)
def _get_view_info(self):
return {"timeline": {"icon": "fa fa-tasks"}} | super()._get_view_info()

View File

@ -85,7 +85,7 @@ More evolved example, from `project_timeline`:
<record id="project.action_view_task" model="ir.actions.act_window"> <record id="project.action_view_task" model="ir.actions.act_window">
<field <field
name="view_mode" name="view_mode"
>kanban,tree,form,calendar,timeline,pivot,graph,activity</field> >kanban,list,form,calendar,timeline,pivot,graph,activity</field>
</record> </record>
</odoo> </odoo>
``` ```

View File

@ -369,7 +369,7 @@ ul.auto-toc {
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:2fb5b8c01ee5f36a21f88358b673738a05282e9cf75f10aa33d38565ecfac956 !! source digest: sha256:2fb5b8c01ee5f36a21f88358b673738a05282e9cf75f10aa33d38565ecfac956
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" 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 image-reference" 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 image-reference" href="https://github.com/OCA/web/tree/17.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 image-reference" href="https://translation.odoo-community.org/projects/web-17-0/web-17-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 image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/web&amp;target_branch=17.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p> <p><a class="reference external image-reference" 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 image-reference" 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 image-reference" href="https://github.com/OCA/web/tree/18.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 image-reference" href="https://translation.odoo-community.org/projects/web-18-0/web-18-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 image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/web&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Define a new view displaying events in an interactive visualization <p>Define a new view displaying events in an interactive visualization
chart.</p> chart.</p>
<p>The widget is based on the external library <p>The widget is based on the external library
@ -579,7 +579,7 @@ view example added onto cron tasks.</p>
</span><span class="nt">&lt;record</span><span class="w"> </span><span class="na">id=</span><span class="s">&quot;project.action_view_task&quot;</span><span class="w"> </span><span class="na">model=</span><span class="s">&quot;ir.actions.act_window&quot;</span><span class="nt">&gt;</span><span class="w"> </span><span class="nt">&lt;record</span><span class="w"> </span><span class="na">id=</span><span class="s">&quot;project.action_view_task&quot;</span><span class="w"> </span><span class="na">model=</span><span class="s">&quot;ir.actions.act_window&quot;</span><span class="nt">&gt;</span><span class="w">
</span><span class="nt">&lt;field</span><span class="w"> </span><span class="nt">&lt;field</span><span class="w">
</span><span class="na">name=</span><span class="s">&quot;view_mode&quot;</span><span class="w"> </span><span class="na">name=</span><span class="s">&quot;view_mode&quot;</span><span class="w">
</span><span class="nt">&gt;</span>kanban,tree,form,calendar,timeline,pivot,graph,activity<span class="nt">&lt;/field&gt;</span><span class="w"> </span><span class="nt">&gt;</span>kanban,list,form,calendar,timeline,pivot,graph,activity<span class="nt">&lt;/field&gt;</span><span class="w">
</span><span class="nt">&lt;/record&gt;</span><span class="w"> </span><span class="nt">&lt;/record&gt;</span><span class="w">
</span><span class="nt">&lt;/odoo&gt;</span> </span><span class="nt">&lt;/odoo&gt;</span>
</pre> </pre>
@ -636,7 +636,7 @@ not open that 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 to smash it by providing a detailed and welcomed If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/web/issues/new?body=module:%20web_timeline%0Aversion:%2017.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:%2018.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">
@ -690,7 +690,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 image-reference" href="https://github.com/tarteo"><img alt="tarteo" src="https://github.com/tarteo.png?size=40px" /></a></p> <p><a class="reference external image-reference" 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/17.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/18.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

@ -1,10 +1,9 @@
/** @odoo-module **/
/** /**
* Copyright 2024 Tecnativa - Carlos López * Copyright 2024 Tecnativa - Carlos López
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
*/ */
import {_t} from "@web/core/l10n/translation"; import {_t} from "@web/core/l10n/translation";
import {archParseBoolean} from "@web/views/utils"; import {exprToBoolean} from "@web/core/utils/strings";
import {parseExpr} from "@web/core/py_js/py"; import {parseExpr} from "@web/core/py_js/py";
import {visitXML} from "@web/core/utils/xml"; import {visitXML} from "@web/core/utils/xml";
@ -71,7 +70,7 @@ export class TimelineArchParser {
node.getAttribute("dependency_arrow"); node.getAttribute("dependency_arrow");
} }
if (node.hasAttribute("stack")) { if (node.hasAttribute("stack")) {
archInfo.options.stack = archParseBoolean( archInfo.options.stack = exprToBoolean(
node.getAttribute("stack"), node.getAttribute("stack"),
true true
); );
@ -97,24 +96,24 @@ export class TimelineArchParser {
} }
} }
if (node.hasAttribute("event_open_popup")) { if (node.hasAttribute("event_open_popup")) {
archInfo.open_popup_action = archParseBoolean( archInfo.open_popup_action = exprToBoolean(
node.getAttribute("event_open_popup") node.getAttribute("event_open_popup")
); );
} }
if (node.hasAttribute("create")) { if (node.hasAttribute("create")) {
archInfo.canCreate = archParseBoolean( archInfo.canCreate = exprToBoolean(
node.getAttribute("create"), node.getAttribute("create"),
true true
); );
} }
if (node.hasAttribute("edit")) { if (node.hasAttribute("edit")) {
archInfo.canUpdate = archParseBoolean( archInfo.canUpdate = exprToBoolean(
node.getAttribute("edit"), node.getAttribute("edit"),
true true
); );
} }
if (node.hasAttribute("delete")) { if (node.hasAttribute("delete")) {
archInfo.canDelete = archParseBoolean( archInfo.canDelete = exprToBoolean(
node.getAttribute("delete"), node.getAttribute("delete"),
true true
); );

View File

@ -1,4 +1,3 @@
/** @odoo-module **/
/* Copyright 2018 Onestein /* Copyright 2018 Onestein
Copyright 2024 Tecnativa - Carlos López Copyright 2024 Tecnativa - Carlos López
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */ * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
@ -15,7 +14,16 @@ export class TimelineCanvas {
* Clears all drawings (svg elements) from the canvas. * Clears all drawings (svg elements) from the canvas.
*/ */
clear() { clear() {
$(this.canvas_ref).find(" > :not(defs)").remove(); if (this.canvas_ref) {
const tempElement = document.createElement("div");
tempElement.innerHTML = this.canvas_ref;
Array.from(tempElement.children).forEach((child) => {
if (child.tagName.toLowerCase() !== "defs") {
child.remove();
}
});
this.canvas_ref = tempElement.innerHTML;
}
} }
/** /**
@ -107,24 +115,34 @@ export class TimelineCanvas {
* @param {Number} breakLineAt The space between the line turns * @param {Number} breakLineAt The space between the line turns
* @returns {HTMLElement} The created SVG polyline * @returns {HTMLElement} The created SVG polyline
*/ */
draw_line(from, to, color, width, markerStart, widthMarker, breakLineAt) { draw_line(
const $from = $(from); from,
const childPosFrom = $from.offset(); to,
const parentPosFrom = $from.closest(".vis-center").offset(); color = "#000",
width = 1,
markerStart,
widthMarker,
breakLineAt
) {
const fromElement =
typeof from === "string" ? document.querySelector(from) : from;
const toElement = typeof to === "string" ? document.querySelector(to) : to;
if (!fromElement || !toElement) return;
const childPosFrom = fromElement.getBoundingClientRect();
const parentFrom = fromElement.closest(".vis-center")?.getBoundingClientRect();
const rectFrom = { const rectFrom = {
x: childPosFrom.left - parentPosFrom.left, x: childPosFrom.left - (parentFrom?.left || 0),
y: childPosFrom.top - parentPosFrom.top, y: childPosFrom.top - (parentFrom?.top || 0),
w: $from.width(), w: fromElement.offsetWidth,
h: $from.height(), h: fromElement.offsetHeight,
}; };
const $to = $(to); const childPosTo = toElement.getBoundingClientRect();
const childPosTo = $to.offset(); const parentTo = toElement.closest(".vis-center")?.getBoundingClientRect();
const parentPosTo = $to.closest(".vis-center").offset();
const rectTo = { const rectTo = {
x: childPosTo.left - parentPosTo.left, x: childPosTo.left - (parentTo?.left || 0),
y: childPosTo.top - parentPosTo.top, y: childPosTo.top - (parentTo?.top || 0),
w: $to.width(), w: toElement.offsetWidth,
h: $to.height(), h: toElement.offsetHeight,
}; };
const points = this.get_polyline_points( const points = this.get_polyline_points(
rectFrom, rectFrom,
@ -134,13 +152,15 @@ export class TimelineCanvas {
); );
const line = document.createElementNS("http://www.w3.org/2000/svg", "polyline"); const line = document.createElementNS("http://www.w3.org/2000/svg", "polyline");
line.setAttribute("points", points.flat().join(",")); line.setAttribute("points", points.flat().join(","));
line.setAttribute("stroke", color || "#000"); line.setAttribute("stroke", color);
line.setAttribute("stroke-width", width || 1); line.setAttribute("stroke-width", width);
line.setAttribute("fill", "none"); line.setAttribute("fill", "none");
if (markerStart) { if (markerStart) {
line.setAttribute("marker-start", "url(" + markerStart + ")"); line.setAttribute("marker-start", `url(${markerStart})`);
}
if (this.canvas_ref instanceof HTMLElement) {
this.canvas_ref.appendChild(line);
} }
this.canvas_ref.append(line);
return line; return line;
} }
} }

View File

@ -16,12 +16,10 @@ import {useDebounced} from "@web/core/utils/timing";
import {useModel} from "@web/model/model"; import {useModel} from "@web/model/model";
import {useSearchBarToggler} from "@web/search/search_bar/search_bar_toggler"; import {useSearchBarToggler} from "@web/search/search_bar/search_bar_toggler";
import {useService} from "@web/core/utils/hooks"; import {useService} from "@web/core/utils/hooks";
import {useSetupView} from "@web/views/view_hook"; import {useSetupAction} from "@web/search/action_hook";
const {DateTime} = luxon; const {DateTime} = luxon;
// Import time from "web.time";
export class TimelineController extends Component { export class TimelineController extends Component {
/** /**
* @override * @override
@ -29,7 +27,7 @@ export class TimelineController extends Component {
setup() { setup() {
this.rootRef = useRef("root"); this.rootRef = useRef("root");
this.model = useModel(this.props.Model, this.props.modelParams); this.model = useModel(this.props.Model, this.props.modelParams);
useSetupView({rootRef: useRef("root")}); useSetupAction({rootRef: useRef("root")});
this.searchBarToggler = useSearchBarToggler(); this.searchBarToggler = useSearchBarToggler();
this.date_start = this.props.modelParams.date_start; this.date_start = this.props.modelParams.date_start;
this.date_stop = this.props.modelParams.date_stop; this.date_stop = this.props.modelParams.date_stop;

View File

@ -1,4 +1,3 @@
/** @odoo-module **/
/** /**
* Copyright 2024 Tecnativa - Carlos López * Copyright 2024 Tecnativa - Carlos López
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

View File

@ -1,4 +1,3 @@
/** @odoo-module **/
/* global vis */ /* global vis */
/** /**
* Copyright 2024 Tecnativa - Carlos López * Copyright 2024 Tecnativa - Carlos López
@ -35,7 +34,7 @@ export class TimelineRenderer extends Component {
this.fields = this.params.fields; this.fields = this.params.fields;
this.timeline = false; this.timeline = false;
this.initial_data_loaded = false; this.initial_data_loaded = false;
this.canvas_ref = $(renderToString("TimelineView.Canvas", {})); this.canvas_ref = renderToString("TimelineView.Canvas", {});
onWillUpdateProps(async (props) => { onWillUpdateProps(async (props) => {
this.on_data_loaded(props.model.data); this.on_data_loaded(props.model.data);
}); });
@ -55,16 +54,23 @@ export class TimelineRenderer extends Component {
* Triggered when the timeline is attached to the DOM. * Triggered when the timeline is attached to the DOM.
*/ */
on_attach_callback() { on_attach_callback() {
const $root = $(this.rootRef.el); const $root = this.rootRef.el;
$root.addClass(this.params.class); if (this.params.class) {
const height = $root.classList.add(this.params.class);
$root.parent().height() - $root.find(".oe_timeline_buttons").height(); }
if (this.rootRef.el) {
const parentHeight = this.rootRef.el.parentElement?.clientHeight || 0;
const buttonHeight =
this.rootRef.el.querySelector(".oe_timeline_buttons")?.clientHeight ||
0;
const height = parentHeight - buttonHeight;
if (height > this.min_height && this.timeline) { if (height > this.min_height && this.timeline) {
this.timeline.setOptions({ this.timeline.setOptions({
height: height, height: height,
}); });
} }
} }
}
/** /**
* Set the timeline window to today (day). * Set the timeline window to today (day).
* *
@ -202,9 +208,11 @@ export class TimelineRenderer extends Component {
// In read-only mode, catch double-clicks this way. // In read-only mode, catch double-clicks this way.
this.timeline.on("doubleClick", this.on_timeline_double_click.bind(this)); this.timeline.on("doubleClick", this.on_timeline_double_click.bind(this));
} }
this.$centerContainer = $(this.timeline.dom.centerContainer); this.$centerContainer = this.timeline.dom.centerContainer;
this.canvas = new TimelineCanvas(this.canvas_ref); this.canvas = new TimelineCanvas(this.canvas_ref);
this.canvas_ref.appendTo(this.$centerContainer); if (this.$centerContainer.el) {
this.$centerContainer.el.appendChild(this.canvas_ref);
}
this.timeline.on("changed", () => { this.timeline.on("changed", () => {
this.draw_canvas(); this.draw_canvas();
this.load_initial_data(); this.load_initial_data();

View File

@ -1,4 +1,3 @@
/** @odoo-module **/
/* 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>
@ -10,13 +9,13 @@ import {TimelineArchParser} from "./timeline_arch_parser.esm";
import {TimelineController} from "./timeline_controller.esm"; import {TimelineController} from "./timeline_controller.esm";
import {TimelineModel} from "./timeline_model.esm"; import {TimelineModel} from "./timeline_model.esm";
import {TimelineRenderer} from "./timeline_renderer.esm"; import {TimelineRenderer} from "./timeline_renderer.esm";
import {_lt} from "@web/core/l10n/translation"; import {_t} from "@web/core/l10n/translation";
import {registry} from "@web/core/registry"; import {registry} from "@web/core/registry";
const viewRegistry = registry.category("views"); const viewRegistry = registry.category("views");
export const TimelineView = { export const TimelineView = {
display_name: _lt("Timeline"), display_name: _t("Timeline"),
icon: "fa fa-tasks", icon: "fa fa-tasks",
multiRecord: true, multiRecord: true,
ArchParser: TimelineArchParser, ArchParser: TimelineArchParser,

View File

@ -1,5 +1,3 @@
/** @odoo-module **/
export const FAKE_ORDER_FIELDS = { export const FAKE_ORDER_FIELDS = {
display_name: {string: "Display Name", type: "char"}, display_name: {string: "Display Name", type: "char"},
date_start: {string: "Date start", type: "date"}, date_start: {string: "Date start", type: "date"},

View File

@ -1,4 +1,3 @@
/** @odoo-module **/
import { import {
TimelineArchParser, TimelineArchParser,
TimelineParseArchError, TimelineParseArchError,
@ -17,23 +16,23 @@ function check(assert, paramName, paramValue, expectedName, expectedValue) {
const data = parseArch(arch); const data = parseArch(arch);
assert.strictEqual(data[expectedName], expectedValue); assert.strictEqual(data[expectedName], expectedValue);
} }
// eslint-disable-next-line no-undef
QUnit.module("TimelineView - ArchParser"); QUnit.module("TimelineView - ArchParser");
// eslint-disable-next-line no-undef
QUnit.test("throw if date_start is not set", (assert) => { QUnit.test("throw if date_start is not set", (assert) => {
assert.throws( assert.throws(
() => parseArch(`<timeline default_group_by="partner_id"/>`), () => parseArch(`<timeline default_group_by="partner_id"/>`),
TimelineParseArchError TimelineParseArchError
); );
}); });
// eslint-disable-next-line no-undef
QUnit.test("throw if default_group_by is not set", (assert) => { QUnit.test("throw if default_group_by is not set", (assert) => {
assert.throws( assert.throws(
() => parseArch(`<timeline date_start="date_start"/>`), () => parseArch(`<timeline date_start="date_start"/>`),
TimelineParseArchError TimelineParseArchError
); );
}); });
// eslint-disable-next-line no-undef
QUnit.test("hasEditDialog", (assert) => { QUnit.test("hasEditDialog", (assert) => {
check(assert, "event_open_popup", "", "open_popup_action", false); check(assert, "event_open_popup", "", "open_popup_action", false);
check(assert, "event_open_popup", "true", "open_popup_action", true); check(assert, "event_open_popup", "true", "open_popup_action", true);
@ -43,7 +42,7 @@ QUnit.test("hasEditDialog", (assert) => {
check(assert, "event_open_popup", "False", "open_popup_action", false); check(assert, "event_open_popup", "False", "open_popup_action", false);
check(assert, "event_open_popup", "0", "open_popup_action", false); check(assert, "event_open_popup", "0", "open_popup_action", false);
}); });
// eslint-disable-next-line no-undef
QUnit.test("create", (assert) => { QUnit.test("create", (assert) => {
check(assert, "create", "", "canCreate", true); check(assert, "create", "", "canCreate", true);
check(assert, "create", "true", "canCreate", true); check(assert, "create", "true", "canCreate", true);
@ -54,7 +53,7 @@ QUnit.test("create", (assert) => {
check(assert, "create", "0", "canCreate", false); check(assert, "create", "0", "canCreate", false);
check(assert, "create", "12", "canCreate", true); check(assert, "create", "12", "canCreate", true);
}); });
// eslint-disable-next-line no-undef
QUnit.test("edit", (assert) => { QUnit.test("edit", (assert) => {
check(assert, "edit", "", "canUpdate", true); check(assert, "edit", "", "canUpdate", true);
check(assert, "edit", "true", "canUpdate", true); check(assert, "edit", "true", "canUpdate", true);
@ -66,7 +65,6 @@ QUnit.test("edit", (assert) => {
check(assert, "edit", "12", "canUpdate", true); check(assert, "edit", "12", "canUpdate", true);
}); });
// eslint-disable-next-line no-undef
QUnit.test("delete", (assert) => { QUnit.test("delete", (assert) => {
check(assert, "delete", "", "canDelete", true); check(assert, "delete", "", "canDelete", true);
check(assert, "delete", "true", "canDelete", true); check(assert, "delete", "true", "canDelete", true);
@ -77,7 +75,7 @@ QUnit.test("delete", (assert) => {
check(assert, "delete", "0", "canDelete", false); check(assert, "delete", "0", "canDelete", false);
check(assert, "delete", "12", "canDelete", true); check(assert, "delete", "12", "canDelete", true);
}); });
// eslint-disable-next-line no-undef
QUnit.test("mode", (assert) => { QUnit.test("mode", (assert) => {
check(assert, "mode", "day", "mode", "day"); check(assert, "mode", "day", "mode", "day");
check(assert, "mode", "week", "mode", "week"); check(assert, "mode", "week", "mode", "week");
@ -94,7 +92,7 @@ QUnit.test("mode", (assert) => {
); );
}, TimelineParseArchError); }, TimelineParseArchError);
}); });
// eslint-disable-next-line no-undef
QUnit.test("colors", (assert) => { QUnit.test("colors", (assert) => {
const archInfo = parseArch(` const archInfo = parseArch(`
<timeline date_start="start_date" default_group_by="partner_id" colors="gray: state == 'cancel'; #ec7063: state == 'done'"/> <timeline date_start="start_date" default_group_by="partner_id" colors="gray: state == 'cancel'; #ec7063: state == 'done'"/>
@ -118,7 +116,7 @@ QUnit.test("colors", (assert) => {
"fieldNames should include field state" "fieldNames should include field state"
); );
}); });
// eslint-disable-next-line no-undef
QUnit.test("templates", (assert) => { QUnit.test("templates", (assert) => {
const archInfo = parseArch(` const archInfo = parseArch(`
<timeline date_start="start_date" default_group_by="partner_id"> <timeline date_start="start_date" default_group_by="partner_id">

View File

@ -1,4 +1,3 @@
/** @odoo-module **/
import {click, getFixture} from "@web/../tests/helpers/utils"; import {click, getFixture} from "@web/../tests/helpers/utils";
import {makeView, setupViewRegistries} from "@web/../tests/views/helpers"; import {makeView, setupViewRegistries} from "@web/../tests/views/helpers";
import {FAKE_ORDER_FIELDS} from "./helpers.esm"; import {FAKE_ORDER_FIELDS} from "./helpers.esm";
@ -6,7 +5,7 @@ import {loadBundle} from "@web/core/assets";
let serverData = {}; let serverData = {};
let target = null; let target = null;
// eslint-disable-next-line no-undef
QUnit.module("Views", (hooks) => { QUnit.module("Views", (hooks) => {
loadBundle("web_timeline.vis-timeline_lib"); loadBundle("web_timeline.vis-timeline_lib");
hooks.beforeEach(async () => { hooks.beforeEach(async () => {
@ -65,9 +64,9 @@ QUnit.module("Views", (hooks) => {
setupViewRegistries(); setupViewRegistries();
target = getFixture(); target = getFixture();
}); });
// eslint-disable-next-line no-undef
QUnit.module("TimelineView - View"); QUnit.module("TimelineView - View");
// eslint-disable-next-line no-undef
QUnit.test("Test basic timeline view", async (assert) => { QUnit.test("Test basic timeline view", async (assert) => {
await makeView({ await makeView({
type: "timeline", type: "timeline",
@ -77,7 +76,7 @@ QUnit.module("Views", (hooks) => {
}); });
assert.containsOnce(target, ".oe_timeline_view"); assert.containsOnce(target, ".oe_timeline_view");
}); });
// eslint-disable-next-line no-undef
QUnit.test("click today slot", async (assert) => { QUnit.test("click today slot", async (assert) => {
await makeView({ await makeView({
type: "timeline", type: "timeline",
@ -117,7 +116,7 @@ QUnit.module("Views", (hooks) => {
"year should no have classnames btn-primary" "year should no have classnames btn-primary"
); );
}); });
// eslint-disable-next-line no-undef
QUnit.test("click month slot", async (assert) => { QUnit.test("click month slot", async (assert) => {
await makeView({ await makeView({
type: "timeline", type: "timeline",
@ -157,7 +156,7 @@ QUnit.module("Views", (hooks) => {
"year should no have classnames btn-primary" "year should no have classnames btn-primary"
); );
}); });
// eslint-disable-next-line no-undef
QUnit.test("Check button delete", async (assert) => { QUnit.test("Check button delete", async (assert) => {
await makeView({ await makeView({
type: "timeline", type: "timeline",
@ -174,7 +173,7 @@ QUnit.module("Views", (hooks) => {
await click($item_content); await click($item_content);
assert.containsOnce($item_content.parentElement, ".vis-delete"); assert.containsOnce($item_content.parentElement, ".vis-delete");
}); });
// eslint-disable-next-line no-undef
QUnit.test("Check button delete disabled", async (assert) => { QUnit.test("Check button delete disabled", async (assert) => {
await makeView({ await makeView({
type: "timeline", type: "timeline",

View File

@ -8,16 +8,18 @@ from odoo.tests.common import HttpCase
class TestWebTimeline(HttpCase): class TestWebTimeline(HttpCase):
def test_timeline_arch(self): def test_timeline_arch(self):
self.browser_js( self.browser_js(
"/web/tests?filter=TimelineView - ArchParser", "/web/tests/legacy?mod=web&filter=TimelineView - ArchParser",
"", "",
login="admin", login="admin",
timeout=1800, timeout=1800,
success_signal="QUnit test suite done.",
) )
def test_timeline_view(self): def test_timeline_view(self):
self.browser_js( self.browser_js(
"/web/tests?filter=TimelineView - View", "/web/tests/legacy?mod=web&filter=TimelineView - View",
"", "",
login="admin", login="admin",
timeout=1800, timeout=1800,
success_signal="QUnit test suite done.",
) )