[FIX] web: render label with empty string to preserve layout

Previously, when a label in a form arch had an empty string attribute,
we would not render it at all as it seemed useless. In practice, some
existing form arch rely on empty labels being rendered for layout
reasons, and the corresponding views are now broken.

This commit fixes that by instead rendering an empty label, just as
legacy views used to.

Part-of: odoo/odoo#98711
This commit is contained in:
Aaron Bohy
2022-08-25 03:11:45 +02:00
parent a6dd7075b3
commit 545e2378ab
4 changed files with 33 additions and 23 deletions
@@ -79,13 +79,14 @@ export class FormCompiler extends ViewCompiler {
fieldInfo: `props.archInfo.fieldNodes['${fieldId}']`,
className: `"${label.className}"`,
};
if (label.hasAttribute("data-no-label")) {
return;
}
let labelText = label.textContent || fieldString;
labelText = labelText
? toStringExpression(labelText)
: `props.record.fields['${fieldName}'].string`;
if (label.hasAttribute("data-no-label")) {
labelText = toStringExpression("");
} else {
labelText = labelText
? toStringExpression(labelText)
: `props.record.fields['${fieldName}'].string`;
}
const formLabel = createElement("FormLabel", {
"t-props": objectToString(props),
string: labelText,
@@ -41,16 +41,20 @@ QUnit.module("Form Compiler", () => {
assert.areEquivalent(compileTemplate(arch), expected);
});
QUnit.test("label with empty string is not rendered", async (assert) => {
const arch = /*xml*/ `<form><field name="test"/><label for="test" string=""/></form>`;
const expected = /*xml*/ `
QUnit.test(
"label with empty string compiles to FormLabel with empty string",
async (assert) => {
const arch = /*xml*/ `<form><field name="test"/><label for="test" string=""/></form>`;
const expected = /*xml*/ `
<t>
<div t-att-class="props.class" t-attf-class="{{props.record.isInEdition ? 'o_form_editable' : 'o_form_readonly'}} d-block" class="o_form_nosheet" t-ref="compiled_view_root">
<Field id="'test'" name="'test'" record="props.record" fieldInfo="props.archInfo.fieldNodes['test']"/>
<Field id="'test'" name="'test'" record="props.record" fieldInfo="props.archInfo.fieldNodes['test']" />
<FormLabel t-props="{id:'test',fieldName:'test',record:props.record,fieldInfo:props.archInfo.fieldNodes['test'],className:&quot;&quot;}" string="\`\`" />
</div>
</t>`;
assert.areEquivalent(compileTemplate(arch), expected);
});
assert.areEquivalent(compileTemplate(arch), expected);
}
);
QUnit.test("properly compile simple div with field", async (assert) => {
const arch = /*xml*/ `<form><div class="someClass">lol<field name="display_name"/></div></form>`;
@@ -1690,12 +1690,14 @@ QUnit.module("Views", (hooks) => {
assert.strictEqual(target.querySelector("label.o_form_label").textContent, "Bar");
});
QUnit.test("label with empty string attribute doesn't get rendered", async function (assert) {
await makeView({
type: "form",
resModel: "partner",
serverData,
arch: `
QUnit.test(
"label with empty string attribute renders to an empty label",
async function (assert) {
await makeView({
type: "form",
resModel: "partner",
serverData,
arch: `
<form>
<sheet>
<group>
@@ -1706,11 +1708,13 @@ QUnit.module("Views", (hooks) => {
</group>
</sheet>
</form>`,
resId: 2,
});
resId: 2,
});
assert.containsNone(target, "label.o_form_label");
});
assert.containsOnce(target, "label.o_form_label");
assert.equal(target.querySelector("label.o_form_label").textContent, "");
}
);
QUnit.test(
"label is not rendered when invisible and not at top-level in a group",
@@ -599,7 +599,8 @@ QUnit.module("SettingsFormView", (hooks) => {
const webClient = await createWebClient({ serverData });
await doAction(webClient, 1);
assert.containsNone(target, ".o_form_label");
assert.containsOnce(target, ".o_form_label");
assert.equal(target.querySelector(".o_form_label").textContent, "");
assert.containsNone(target, ".settingSearchHeader");
await editSearch(target, "Fo");
await execTimeouts();