[FIX] mail: show translations for emails
Due to shadowRoot, emails were not properly translated. closes odoo/odoo#140847 Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
@@ -100,6 +100,8 @@ export class Message extends Component {
|
||||
emailHeaderOpen: false,
|
||||
showTranslation: false,
|
||||
});
|
||||
/** @type {ShadowRoot} */
|
||||
this.shadowRoot;
|
||||
this.root = useRef("root");
|
||||
this.hasTouch = hasTouch;
|
||||
this.messageBody = useRef("body");
|
||||
@@ -136,11 +138,7 @@ export class Message extends Component {
|
||||
this.prepareMessageBody(this.messageBody.el);
|
||||
}
|
||||
if (this.shadowBody.el) {
|
||||
const shadowRoot = this.shadowBody.el.attachShadow({ mode: "open" });
|
||||
const body = document.createElement("span");
|
||||
body.innerHTML =
|
||||
this.props.messageSearch?.highlight(this.message.body) ?? this.message.body;
|
||||
this.prepareMessageBody(body);
|
||||
this.shadowRoot = this.shadowBody.el.attachShadow({ mode: "open" });
|
||||
const color = cookie.get("color_scheme") === "dark" ? "white" : "black";
|
||||
const shadowStyle = document.createElement("style");
|
||||
shadowStyle.innerHTML = `
|
||||
@@ -159,11 +157,32 @@ export class Message extends Component {
|
||||
}
|
||||
`;
|
||||
if (cookie.get("color_scheme") === "dark") {
|
||||
shadowRoot.appendChild(shadowStyle);
|
||||
this.shadowRoot.appendChild(shadowStyle);
|
||||
}
|
||||
shadowRoot.appendChild(body);
|
||||
}
|
||||
});
|
||||
useEffect(
|
||||
() => {
|
||||
if (this.shadowBody.el) {
|
||||
const body = document.createElement("span");
|
||||
body.innerHTML = this.state.showTranslation
|
||||
? this.message.translationValue
|
||||
: this.props.messageSearch?.highlight(this.message.body) ??
|
||||
this.message.body;
|
||||
this.prepareMessageBody(body);
|
||||
this.shadowRoot.appendChild(body);
|
||||
return () => {
|
||||
this.shadowRoot.removeChild(body);
|
||||
};
|
||||
}
|
||||
},
|
||||
() => [
|
||||
this.state.showTranslation,
|
||||
this.message.translationValue,
|
||||
this.props.messageSearch?.searchTerm,
|
||||
this.message.body,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
get attClass() {
|
||||
|
||||
@@ -46,3 +46,42 @@ QUnit.test("Toggle display of original/translated version of chatter message", a
|
||||
// The translation button should not trigger more than one external request for a single message.
|
||||
assert.verifySteps(["Request"]);
|
||||
});
|
||||
|
||||
QUnit.test("translation of email message", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const partnerId = pyEnv["res.partner"].create({});
|
||||
pyEnv["mail.message"].create({
|
||||
model: "res.partner",
|
||||
body: "Al mal tiempo, buena cara.",
|
||||
message_type: "email",
|
||||
author_id: partnerId,
|
||||
res_id: partnerId,
|
||||
});
|
||||
const { openFormView } = await start({
|
||||
mockRPC(route) {
|
||||
if (route === "/mail/message/translate") {
|
||||
return { body: "To bad weather, good face.", lang_name: "Spanish", error: null };
|
||||
}
|
||||
},
|
||||
});
|
||||
await openFormView("res.partner", partnerId);
|
||||
await contains("span", {
|
||||
text: "Al mal tiempo, buena cara.",
|
||||
parent: [".o-mail-Message-body > div", { shadowRoot: true }],
|
||||
});
|
||||
await click("button[title='Expand']");
|
||||
await click("span[title='Translate']");
|
||||
await contains("span", {
|
||||
text: "To bad weather, good face.",
|
||||
parent: [".o-mail-Message-body > div", { shadowRoot: true }],
|
||||
});
|
||||
await contains(".o-mail-Message-body", {
|
||||
text: "(Translated from: Spanish)",
|
||||
});
|
||||
await click("button[title='Expand']");
|
||||
await click("span[title='Revert']");
|
||||
await contains("span", {
|
||||
text: "Al mal tiempo, buena cara.",
|
||||
parent: [".o-mail-Message-body > div", { shadowRoot: true }],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -226,6 +226,7 @@ if (window.QUnit) {
|
||||
* Note: when using one of the scrollTop options, it is advised to ensure the height is not going
|
||||
* to change soon, by checking with a preceding contains that all the expected elements are in DOM.
|
||||
* @property {boolean} [setFocus] if provided, focuses the first found element.
|
||||
* @property {boolean} [shadowRoot] if provided, targets the shadowRoot of the found elements.
|
||||
* @property {number|"bottom"} [setScroll] if provided, sets the scrollTop on the first found
|
||||
* element.
|
||||
* @property {HTMLElement} [target=getFixture()]
|
||||
@@ -521,7 +522,9 @@ class Contains {
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
const baseRes = [...target.querySelectorAll(this.selector)];
|
||||
const baseRes = [...target.querySelectorAll(this.selector)]
|
||||
.map((el) => (this.options.shadowRoot ? el.shadowRoot : el))
|
||||
.filter((el) => el);
|
||||
/** @type {Contains[]} */
|
||||
this.childrenContains = [];
|
||||
const res = baseRes.filter((el, currentIndex) => {
|
||||
|
||||
Reference in New Issue
Block a user