[IMP] web: documentation link widget
This commit introduces the documentation link widget, the aim is to standardize the help documentation links that can be found in the views. This widget will add an icon (o_doc_link), this icon is a link to the documentation. Note that you can use relative or absolute path. The relative path is relative to `https://www.odoo.com/documentation/server_version`, so it's not necessary to hard-code the server version on the arch any more. ```xml <widget name="documentation_link" documentation="/applications/technical/web/settings/this_is_a_test.html"/> ``` Task-id: 2980478 Part-of: odoo/odoo#110432
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { session } from "@web/session";
|
||||
import { standardWidgetProps } from "@web/views/widgets/standard_widget_props";
|
||||
import { Component } from "@odoo/owl";
|
||||
import { registry } from "@web/core/registry";
|
||||
|
||||
const LINK_REGEX = new RegExp("^https?://");
|
||||
|
||||
export class DocumentationLink extends Component {
|
||||
get url() {
|
||||
if (LINK_REGEX.test(this.props.path)) {
|
||||
return this.props.path;
|
||||
} else {
|
||||
const serverVersion = session.server_version.includes("alpha")
|
||||
? "master"
|
||||
: session.server_version;
|
||||
return "https://www.odoo.com/documentation/" + serverVersion + this.props.path;
|
||||
}
|
||||
}
|
||||
}
|
||||
DocumentationLink.template = "web.DocumentationLink";
|
||||
DocumentationLink.props = {
|
||||
...standardWidgetProps,
|
||||
record: { type: Object, optional: 1 }, // The record is not needed in this widget
|
||||
path: { type: String },
|
||||
};
|
||||
DocumentationLink.extractProps = ({ attrs }) => {
|
||||
const { path } = attrs;
|
||||
return {
|
||||
path,
|
||||
};
|
||||
};
|
||||
DocumentationLink.additionalClasses = ["d-inline"];
|
||||
|
||||
registry.category("view_widgets").add("documentation_link", DocumentationLink);
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-name="web.DocumentationLink" owl="1">
|
||||
<a t-att-href="url" title="Documentation" class="o_doc_link me-2" target="_blank"></a>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -25,11 +25,17 @@ export class Widget extends Component {
|
||||
}
|
||||
|
||||
get classNames() {
|
||||
return {
|
||||
const classNames = {
|
||||
o_widget: true,
|
||||
[`o_widget_${this.props.name}`]: true,
|
||||
[this.props.className]: Boolean(this.props.className),
|
||||
};
|
||||
if (this.Widget.additionalClasses) {
|
||||
for (const cls of this.Widget.additionalClasses) {
|
||||
classNames[cls] = true;
|
||||
}
|
||||
}
|
||||
return classNames;
|
||||
}
|
||||
get widgetProps() {
|
||||
const { node: rawNode } = this.props;
|
||||
|
||||
@@ -5,9 +5,8 @@ import { HighlightText } from "../highlight_text/highlight_text";
|
||||
import { session } from "@web/session";
|
||||
import { FormLabelHighlightText } from "../highlight_text/form_label_highlight_text";
|
||||
import { Component, useState } from "@odoo/owl";
|
||||
import { DocumentationLink } from "@web/views/widgets/documentation_link/documentation_link";
|
||||
|
||||
|
||||
const LINK_REGEX = new RegExp("^https?://");
|
||||
export class Setting extends Component {
|
||||
setup() {
|
||||
this.state = useState({
|
||||
@@ -57,16 +56,6 @@ export class Setting extends Component {
|
||||
return label || "";
|
||||
}
|
||||
|
||||
get url() {
|
||||
if (LINK_REGEX.test(this.props.documentation)) {
|
||||
return this.props.documentation;
|
||||
} else {
|
||||
const serverVersion = session.server_version.includes("alpha")
|
||||
? "master"
|
||||
: session.server_version;
|
||||
return "https://www.odoo.com/documentation/" + serverVersion + this.props.documentation;
|
||||
}
|
||||
}
|
||||
visible() {
|
||||
if (!this.state.search.value) {
|
||||
return true;
|
||||
@@ -84,6 +73,7 @@ export class Setting extends Component {
|
||||
Setting.components = {
|
||||
FormLabelHighlightText,
|
||||
HighlightText,
|
||||
DocumentationLink,
|
||||
};
|
||||
Setting.template = "web.Setting";
|
||||
Setting.props = {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<span class="o_form_label"><HighlightText originalText="labelString"/></span>
|
||||
</t>
|
||||
<t t-if="labelString and props.documentation">
|
||||
<a t-att-href="url" title="Documentation" class="o_doc_link me-2" target="_blank"></a>
|
||||
<DocumentationLink path="props.documentation"/>
|
||||
</t>
|
||||
<t t-if="displayCompanyDependentIcon">
|
||||
<span class="fa fa-lg fa-building-o" title="Values set here are company-specific."/>
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/** @odoo-module **/
|
||||
import { getFixture } from "@web/../tests/helpers/utils";
|
||||
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
|
||||
|
||||
let target;
|
||||
let serverData;
|
||||
|
||||
QUnit.module("Widgets", (hooks) => {
|
||||
hooks.beforeEach(() => {
|
||||
target = getFixture();
|
||||
serverData = {
|
||||
models: {
|
||||
partner: {
|
||||
fields: {
|
||||
bar: { string: "Bar", type: "boolean" },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
setupViewRegistries();
|
||||
});
|
||||
|
||||
QUnit.module("DocumentationLink");
|
||||
|
||||
QUnit.test("documentation_link: relative path", async function (assert) {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="bar"/>
|
||||
<widget name="documentation_link" path="/applications/technical/web/settings/this_is_a_test.html"/>
|
||||
</form>`,
|
||||
});
|
||||
|
||||
assert.hasAttrValue(
|
||||
target.querySelector(".o_doc_link"),
|
||||
"href",
|
||||
"https://www.odoo.com/documentation/1.0/applications/technical/web/settings/this_is_a_test.html"
|
||||
);
|
||||
});
|
||||
QUnit.test("documentation_link: absoluth path (http)", async function (assert) {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="bar"/>
|
||||
<widget name="documentation_link" path="http://www.odoo.com/"/>
|
||||
</form>`,
|
||||
});
|
||||
|
||||
assert.hasAttrValue(target.querySelector(".o_doc_link"), "href", "http://www.odoo.com/");
|
||||
});
|
||||
QUnit.test("documentation_link: absoluth path (https)", async function (assert) {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
serverData,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="bar"/>
|
||||
<widget name="documentation_link" path="https://www.odoo.com/"/>
|
||||
</form>`,
|
||||
});
|
||||
|
||||
assert.hasAttrValue(target.querySelector(".o_doc_link"), "href", "https://www.odoo.com/");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user