[FIX] web: remove translation alert banner

The translation alert banner is an old remaining edit/save feature that
is not relevant anymore with the new "always edit" and the "save when
leave" features.

closes odoo/odoo#115866

Task-id: 3232795
X-original-commit: dfd65d08ef3d76f9cd702927ee09dafe429d895a
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Jorge Pinna Puissant
2023-03-20 18:13:06 +01:00
parent b17acfc8ab
commit c7aff4cb7d
4 changed files with 2 additions and 202 deletions
@@ -18,7 +18,6 @@ import {
makeSeparator,
} from "@web/views/view_compiler";
import { ViewCompiler } from "../view_compiler";
import { localization } from "@web/core/l10n/localization";
const compilersRegistry = registry.category("form_compilers");
@@ -247,21 +246,6 @@ export class FormCompiler extends ViewCompiler {
}
append(form, compiledList);
}
if (localization.multiLang) {
const statusBar = form.querySelector(".o_form_statusbar");
const translateAlert = createElement("t", {
"t-if": "__comp__.props.translateAlert",
"t-call": "web.TranslateAlert",
"t-call-context": "__comp__",
});
if (statusBar) {
statusBar.parentElement.insertBefore(translateAlert, statusBar.nextSibling);
} else if (form.querySelector(".o_form_sheet_bg")) {
form.querySelector(".o_form_sheet_bg").prepend(translateAlert);
} else {
form.prepend(translateAlert);
}
}
return form;
}
@@ -4,7 +4,6 @@ import { hasTouch } from "@web/core/browser/feature_detection";
import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
import { makeContext } from "@web/core/context";
import { useDebugCategory } from "@web/core/debug/debug_context";
import { localization } from "@web/core/l10n/localization";
import { registry } from "@web/core/registry";
import { SIZES } from "@web/core/ui/ui_service";
import { useBus, useService } from "@web/core/utils/hooks";
@@ -20,7 +19,7 @@ import { useViewButtons } from "@web/views/view_button/view_button_hook";
import { useSetupView } from "@web/views/view_hook";
import { FormStatusIndicator } from "./form_status_indicator/form_status_indicator";
import { Component, onRendered, onWillStart, toRaw, useEffect, useRef, useState } from "@odoo/owl";
import { Component, onRendered, onWillStart, useEffect, useRef, useState } from "@odoo/owl";
const viewRegistry = registry.category("views");
@@ -184,8 +183,6 @@ export class FormController extends Component {
});
const state = this.props.state || {};
const { fieldsToTranslate } = state;
this.fieldsToTranslate = useState(fieldsToTranslate || {});
const activeNotebookPages = { ...state.activeNotebookPages };
this.onNotebookPageChange = (notebookId, page) => {
if (page) {
@@ -202,7 +199,6 @@ export class FormController extends Component {
return {
activeNotebookPages: !this.model.root.isNew ? activeNotebookPages : {},
resId: this.model.root.resId,
fieldsToTranslate: toRaw(this.fieldsToTranslate),
};
},
});
@@ -441,18 +437,6 @@ export class FormController extends Component {
const record = this.model.root;
let saved = false;
// Before we save, we gather dirty translate fields data. It needs to be done before the
// save as nothing will be dirty after. It is why there is a compute part and a show part.
const dirtyTranslatableFields = localization.multiLang
? Object.values(record.fields).filter((f) => f.translate && record.isFieldDirty(f.name))
: [];
if (dirtyTranslatableFields.length) {
const { resId } = record;
this.fieldsToTranslate[resId] = new Set([
...toRaw(this.fieldsToTranslate[resId] || []),
...dirtyTranslatableFields,
]);
}
if (this.props.saveRecord) {
saved = await this.props.saveRecord(record, params);
} else {
@@ -463,13 +447,6 @@ export class FormController extends Component {
this.props.onSave(record, params);
}
// After we saved, we show the previously computed data in the alert (if there is any).
// It needs to be done after the save because if we were in record creation, the resId
// changed from false to a number. So it first needs to update the computed data to the new id.
if (this.fieldsToTranslate.false) {
this.fieldsToTranslate[record.resId] = this.fieldsToTranslate.false;
delete this.fieldsToTranslate.false;
}
return saved;
}
@@ -487,20 +464,6 @@ export class FormController extends Component {
}
}
get translateAlert() {
const { resId } = this.model.root;
if (!this.fieldsToTranslate[resId]) {
return null;
}
return {
fields: this.fieldsToTranslate[resId],
close: () => {
delete this.fieldsToTranslate[resId];
},
};
}
get className() {
const result = {};
const { size } = this.ui;
@@ -37,7 +37,7 @@
<button type="button" class="btn btn-outline-primary o_form_button_create" data-hotkey="c" t-on-click.stop="create" t-att-disabled="state.isDisabled">New</button>
</t>
</t>
<t t-component="props.Renderer" record="model.root" Compiler="props.Compiler" archInfo="archInfo" translateAlert="translateAlert" enableViewButtons.bind="enableButtons" disableViewButtons.bind="disableButtons" onNotebookPageChange.bind="onNotebookPageChange" activeNotebookPages="props.state and props.state.activeNotebookPages"/>
<t t-component="props.Renderer" record="model.root" Compiler="props.Compiler" archInfo="archInfo" enableViewButtons.bind="enableButtons" disableViewButtons.bind="disableButtons" onNotebookPageChange.bind="onNotebookPageChange" activeNotebookPages="props.state and props.state.activeNotebookPages"/>
</Layout>
</div>
</div>
@@ -63,18 +63,4 @@
</div>
</div>
</t>
<!--
Used in FormRenderer
Note: `props` is only accessible through `this` as we call the compiled template a restricted context (t-call-context)
-->
<t t-name="web.TranslateAlert" owl="1">
<div class="alert alert-info alert-dismissible" role="alertdialog">
Please update translations of :
<t t-foreach="Array.from(props.translateAlert.fields)" t-as="field" t-key="field.name">
<strong><a class="o_field_translate" t-att-name="field.name" href="#"><t t-esc="field.string"/><t t-if="!field_last">, </t></a></strong>
</t>
<button t-on-click="props.translateAlert.close" type="button" class="btn-close" aria-label="Close"></button>
</div>
</t>
</templates>
@@ -8953,59 +8953,6 @@ QUnit.module("Views", (hooks) => {
);
});
QUnit.test("display translation alert", async function (assert) {
serverData.models.partner.fields.foo.translate = true;
serverData.models.partner.fields.display_name.translate = true;
patchWithCleanup(localization, {
multiLang: true,
});
await makeView({
type: "form",
resModel: "partner",
serverData,
arch: `
<form>
<header>
<button string="Additionnal button" class="btn btn-primary"/>
</header>
<sheet>
<group>
<field name="foo"/>
<field name="display_name"/>
</group>
</sheet>
</form>`,
resId: 1,
});
await editInput(target, '[name="foo"] input', "test");
await clickSave(target);
assert.containsOnce(
target,
".alert .o_field_translate",
"should have single translation alert"
);
await editInput(target, '[name="foo"] input', "test2");
await editInput(target, '[name="display_name"] input', "test3");
await clickSave(target);
assert.containsN(
target,
".alert .o_field_translate",
2,
"should have two translate fields in translation alert"
);
const statusBarY = target.querySelector(".o_form_statusbar").getBoundingClientRect().top;
const translateAlertY = target
.querySelector(".alert .o_field_translate")
.getBoundingClientRect().top;
assert.ok(translateAlertY > statusBarY, "translation alert should be below status bar");
await click(target, ".alert .btn-close");
assert.containsNone(target, ".alert", "should have closed the translate alert");
});
QUnit.test("can save without any dirty translatable fields", async function (assert) {
serverData.models.partner.fields.foo.translate = true;
@@ -9142,86 +9089,6 @@ QUnit.module("Views", (hooks) => {
assert.strictEqual(target.querySelector(".modal-title").textContent, "Translate: foo");
});
QUnit.test("translation alerts are preserved on pager change", async function (assert) {
serverData.models.partner.fields.foo.translate = true;
patchWithCleanup(localization, {
multiLang: true,
});
await makeView({
type: "form",
serverData,
resModel: "partner",
arch: `<form><sheet><field name="foo"/></sheet></form>`,
resIds: [1, 2],
resId: 1,
});
await editInput(target, '[name="foo"] input', "test");
await clickSave(target);
assert.containsOnce(target, ".alert .o_field_translate", "should have a translation alert");
// click on the pager to switch to the next record
await click(target.querySelector(".o_pager_next"));
assert.containsNone(
target,
".alert .o_field_translate",
"should not have a translation alert"
);
// click on the pager to switch back to the previous record
await click(target.querySelector(".o_pager_previous"));
assert.containsOnce(target, ".alert .o_field_translate", "should have a translation alert");
// remove translation alert by click X and check alert even after form reload
await click(target.querySelector(".alert .btn-close"));
assert.containsNone(
target,
".alert .o_field_translate",
"should not have a translation alert"
);
await click(target.querySelector(".o_pager_next"));
await click(target.querySelector(".o_pager_previous"));
assert.containsNone(
target,
".alert .o_field_translate",
"should not have a translation alert after reload"
);
});
QUnit.test("translation alerts preserved on reverse breadcrumb", async function (assert) {
serverData.models.partner.fields.foo.translate = true;
serverData.views = {
"partner,false,form": `<form><sheet><field name="foo"/></sheet></form>`,
"partner,false,search": "<search></search>",
};
serverData.actions = {
1: {
id: 1,
name: "Partner",
res_model: "partner",
type: "ir.actions.act_window",
views: [[false, "form"]],
},
};
const webClient = await createWebClient({ serverData });
patchWithCleanup(localization, {
multiLang: true,
});
await doAction(webClient, 1);
await editInput(target, `[name="foo"] input`, "test");
await clickSave(target);
assert.containsOnce(target, ".alert .o_field_translate", "should have a translation alert");
});
QUnit.test(
"translate event correctly handled with multiple controllers",
async function (assert) {