Skip to content

Commit b50fb70

Browse files
committed
[FIX] document_page_reference: migrate widget to OWL for Odoo 16
The legacy JS widget registered in web.field_registry was not picked up by the OWL form view parser, causing "Missing widget: document_page_reference" warnings and the content_parsed field not rendering at all. Changes: - Migrate JS widget from legacy field_registry to OWL registry - Fix retargetLinks adding target="_blank" to internal reference links - Override _get_page_index to use oe_direct_line links in category pages - Replace oe_read_only/oe_edit_only CSS classes with proper attrs/invisible - Add tour test for reference link navigation - Fix _compute_content_parsed using self instead of record in loop
1 parent 1237fc6 commit b50fb70

10 files changed

Lines changed: 244 additions & 79 deletions

File tree

document_page_reference/README.rst

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
.. image:: https://odoo-community.org/readme-banner-image
2-
:target: https://odoo-community.org/get-involved?utm_source=readme
3-
:alt: Odoo Community Association
4-
51
=======================
62
Document Page Reference
73
=======================
@@ -17,7 +13,7 @@ Document Page Reference
1713
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
1814
:target: https://odoo-community.org/page/development-status
1915
:alt: Beta
20-
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
2117
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
2218
:alt: License: AGPL-3
2319
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fknowledge-lightgray.png?logo=github

document_page_reference/__manifest__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
"web.assets_backend": [
1919
"document_page_reference/static/src/js/**/*",
2020
],
21+
"web.assets_tests": [
22+
"document_page_reference/static/tests/**/*",
23+
],
2124
},
2225
"maintainers": ["etobella"],
2326
}

document_page_reference/models/document_page.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,23 +54,44 @@ class DocumentPage(models.Model):
5454
)
5555
content_parsed = fields.Html(compute="_compute_content_parsed")
5656

57+
def _get_page_index(self, link=True):
58+
"""Override to use oe_direct_line links compatible with the widget."""
59+
self.ensure_one()
60+
index = [
61+
"<li>" + subpage._get_page_index() + "</li>" for subpage in self.child_ids
62+
]
63+
r = ""
64+
if link:
65+
r = (
66+
'<a href="#" class="oe_direct_line"'
67+
f' data-oe-model="{self._name}" data-oe-id="{self.id}">'
68+
+ html_escape(self.name)
69+
+ "</a>"
70+
)
71+
if index:
72+
r += "<ul>" + "".join(index) + "</ul>"
73+
return r
74+
5775
def get_formview_action(self, access_uid=None):
5876
res = super().get_formview_action(access_uid)
5977
view_id = self.env.ref("document_page.view_wiki_form").id
6078
res["views"] = [(view_id, "form")]
6179
return res
6280

63-
@api.depends("history_head")
81+
@api.depends("history_head", "type")
6482
def _compute_content_parsed(self):
6583
for record in self:
66-
content = record.get_content()
67-
if content == "<p>" and self.content != "<p>":
68-
_logger.error(
69-
"Template from page with id = %s cannot be processed correctly"
70-
% self.id
71-
)
72-
content = self.content
73-
record.content_parsed = content
84+
if record.type == "category":
85+
record.content_parsed = record.content
86+
else:
87+
content = record.get_content()
88+
if content == "<p>" and record.content != "<p>":
89+
_logger.error(
90+
"Template from page with id = %s cannot be "
91+
"processed correctly" % record.id
92+
)
93+
content = record.content
94+
record.content_parsed = content
7495

7596
@api.constrains("reference")
7697
def _check_reference(self):

document_page_reference/static/description/index.html

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@
33
<head>
44
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
55
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
6-
<title>README.rst</title>
6+
<title>Document Page Reference</title>
77
<style type="text/css">
88

99
/*
1010
:Author: David Goodger (goodger@python.org)
11-
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
11+
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
1212
:Copyright: This stylesheet has been placed in the public domain.
1313
1414
Default cascading style sheet for the HTML output of Docutils.
15-
Despite the name, some widely supported CSS2 features are used.
1615
1716
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
1817
customize this style sheet.
@@ -275,7 +274,7 @@
275274
margin-left: 2em ;
276275
margin-right: 2em }
277276

278-
pre.code .ln { color: gray; } /* line numbers */
277+
pre.code .ln { color: grey; } /* line numbers */
279278
pre.code, code { background-color: #eeeeee }
280279
pre.code .comment, code .comment { color: #5C6576 }
281280
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
@@ -301,7 +300,7 @@
301300
span.pre {
302301
white-space: pre }
303302

304-
span.problematic, pre.problematic {
303+
span.problematic {
305304
color: red }
306305

307306
span.section-subtitle {
@@ -360,21 +359,16 @@
360359
</style>
361360
</head>
362361
<body>
363-
<div class="document">
362+
<div class="document" id="document-page-reference">
363+
<h1 class="title">Document Page Reference</h1>
364364

365-
366-
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
367-
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
368-
</a>
369-
<div class="section" id="document-page-reference">
370-
<h1>Document Page Reference</h1>
371365
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
372366
!! This file is generated by oca-gen-addon-readme !!
373367
!! changes will be overwritten. !!
374368
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
375369
!! source digest: sha256:3604a4c11db5706c09226e3e0d5a5363cc7272e856131e06c4a5a47b43616e20
376370
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
377-
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.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/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/knowledge/tree/16.0/document_page_reference"><img alt="OCA/knowledge" src="https://img.shields.io/badge/github-OCA%2Fknowledge-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/knowledge-16-0/knowledge-16-0-document_page_reference"><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/knowledge&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
371+
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.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/knowledge/tree/16.0/document_page_reference"><img alt="OCA/knowledge" src="https://img.shields.io/badge/github-OCA%2Fknowledge-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/knowledge-16-0/knowledge-16-0-document_page_reference"><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/knowledge&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
378372
<p>This module allows to add a reference name on documents and simplifies the link
379373
between document pages.</p>
380374
<p><strong>Table of contents</strong></p>
@@ -391,39 +385,37 @@ <h1>Document Page Reference</h1>
391385
</ul>
392386
</div>
393387
<div class="section" id="usage">
394-
<h2><a class="toc-backref" href="#toc-entry-1">Usage</a></h2>
388+
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
395389
<p>When editing a document page add elements like ${XXX} where XXX is the reference
396390
of another page. Now, when viewing the document, it will link directly to the page.
397391
Also, the name will be parsed as the display name.</p>
398392
</div>
399393
<div class="section" id="bug-tracker">
400-
<h2><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h2>
394+
<h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1>
401395
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/knowledge/issues">GitHub Issues</a>.
402396
In case of trouble, please check there if your issue has already been reported.
403397
If you spotted it first, help us to smash it by providing a detailed and welcomed
404398
<a class="reference external" href="https://github.com/OCA/knowledge/issues/new?body=module:%20document_page_reference%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
405399
<p>Do not contact contributors directly about support or help with technical issues.</p>
406400
</div>
407401
<div class="section" id="credits">
408-
<h2><a class="toc-backref" href="#toc-entry-3">Credits</a></h2>
402+
<h1><a class="toc-backref" href="#toc-entry-3">Credits</a></h1>
409403
<div class="section" id="authors">
410-
<h3><a class="toc-backref" href="#toc-entry-4">Authors</a></h3>
404+
<h2><a class="toc-backref" href="#toc-entry-4">Authors</a></h2>
411405
<ul class="simple">
412406
<li>Creu Blanca</li>
413407
</ul>
414408
</div>
415409
<div class="section" id="contributors">
416-
<h3><a class="toc-backref" href="#toc-entry-5">Contributors</a></h3>
410+
<h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
417411
<ul class="simple">
418412
<li>Enric Tobella &lt;<a class="reference external" href="mailto:etobella&#64;creublanca.es">etobella&#64;creublanca.es</a>&gt;</li>
419413
</ul>
420414
</div>
421415
<div class="section" id="maintainers">
422-
<h3><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h3>
416+
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
423417
<p>This module is maintained by the OCA.</p>
424-
<a class="reference external image-reference" href="https://odoo-community.org">
425-
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
426-
</a>
418+
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
427419
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
428420
mission is to support the collaborative development of Odoo features and
429421
promote its widespread use.</p>
@@ -434,6 +426,5 @@ <h3><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h3>
434426
</div>
435427
</div>
436428
</div>
437-
</div>
438429
</body>
439430
</html>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* @odoo-module */
2+
3+
import {HtmlField} from "@web_editor/js/backend/html_field";
4+
import {registry} from "@web/core/registry";
5+
import {useService} from "@web/core/utils/hooks";
6+
import {onMounted, onPatched} from "@odoo/owl";
7+
8+
export class DocumentPageReferenceField extends HtmlField {
9+
setup() {
10+
super.setup();
11+
this.actionService = useService("action");
12+
this.orm = useService("orm");
13+
this._onClickDirectLink = this._onClickDirectLink.bind(this);
14+
onMounted(() => this._bindLinks());
15+
onPatched(() => this._bindLinks());
16+
}
17+
_bindLinks() {
18+
const el = this.readonlyElementRef && this.readonlyElementRef.el;
19+
if (!el) return;
20+
// Remove target="_blank" from internal reference links
21+
// (added by retargetLinks in HtmlField)
22+
for (const link of el.querySelectorAll("a.oe_direct_line")) {
23+
link.removeAttribute("target");
24+
link.removeAttribute("rel");
25+
link.removeEventListener("click", this._onClickDirectLink);
26+
link.addEventListener("click", this._onClickDirectLink);
27+
}
28+
}
29+
_onClickDirectLink(ev) {
30+
ev.preventDefault();
31+
ev.stopPropagation();
32+
const target = ev.currentTarget;
33+
const model = target.dataset.oeModel;
34+
const id = parseInt(target.dataset.oeId, 10);
35+
if (!model || !id) return;
36+
this.orm.call(model, "get_formview_action", [[id]]).then((action) => {
37+
this.actionService.doAction(action);
38+
});
39+
}
40+
}
41+
42+
registry.category("fields").add("document_page_reference", DocumentPageReferenceField);

document_page_reference/static/src/js/editor.js

Lines changed: 0 additions & 34 deletions
This file was deleted.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/** @odoo-module */
2+
3+
import tour from "web_tour.tour";
4+
5+
/*
6+
* Test 1: Reference widget renders ${ref} as clickable links.
7+
*/
8+
tour.register(
9+
"document_page_reference_widget_tour",
10+
{
11+
test: true,
12+
url: "/web#action=document_page.action_page",
13+
},
14+
[
15+
{
16+
content: "Open Test Ref Page 1",
17+
trigger: '.o_data_cell[name="name"]:contains("Test Ref Page 1")',
18+
run: "click",
19+
},
20+
{
21+
content: "Verify content_parsed renders reference as link",
22+
trigger:
23+
'.o_form_view .o_field_widget[name="content_parsed"] a.oe_direct_line',
24+
timeout: 20000,
25+
run: function () {
26+
var link = this.$anchor[0];
27+
if (!link.dataset.oeModel || !link.dataset.oeId) {
28+
throw new Error("Reference link missing data-oe-model/data-oe-id");
29+
}
30+
if (link.getAttribute("target") === "_blank") {
31+
throw new Error(
32+
"Internal reference link should not have target=_blank"
33+
);
34+
}
35+
},
36+
},
37+
]
38+
);
39+
40+
/*
41+
* Test 2: Category page index uses oe_direct_line links.
42+
*/
43+
tour.register(
44+
"document_page_reference_category_tour",
45+
{
46+
test: true,
47+
url: "/web#action=document_page.action_page",
48+
},
49+
[
50+
{
51+
content: "Open Test Ref Page 1 to navigate to its category",
52+
trigger: '.o_data_cell[name="name"]:contains("Test Ref Page 1")',
53+
run: "click",
54+
},
55+
{
56+
content: "Navigate to category via parent_id link",
57+
trigger: '.o_form_view .o_field_widget[name="parent_id"] a',
58+
timeout: 20000,
59+
run: "click",
60+
},
61+
{
62+
content: "Verify category shows child links as oe_direct_line",
63+
trigger:
64+
'.o_form_view .o_field_widget[name="content_parsed"] a.oe_direct_line',
65+
timeout: 20000,
66+
run: function () {
67+
var links = document.querySelectorAll(
68+
'.o_field_widget[name="content_parsed"] a.oe_direct_line'
69+
);
70+
if (links.length < 1) {
71+
throw new Error("Category should have child page links");
72+
}
73+
// Verify links have correct attributes
74+
var link = links[0];
75+
if (!link.dataset.oeModel || !link.dataset.oeId) {
76+
throw new Error("Category index link missing data-oe-model/id");
77+
}
78+
if (link.getAttribute("target") === "_blank") {
79+
throw new Error("Category index link should not open in new tab");
80+
}
81+
},
82+
},
83+
]
84+
);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
from . import test_document_reference
2+
from . import test_document_reference_tour

0 commit comments

Comments
 (0)