From 139e0e257c0f9ce702c1d3df2fae87a7dd1187f7 Mon Sep 17 00:00:00 2001 From: Brieuc-brd Date: Thu, 11 Aug 2022 15:17:32 +0000 Subject: [PATCH 1/4] [IMP] web: add `d-[device]-contents` classes This commit extends the `display` class with a new value to fine-tune the layout in several circumstances. Classes added: - 'd-[device]-contents' task-2918464 X-original-commit: 1c871cc847f305649a4329b653540109596fa149 Part-of: odoo/odoo#101655 --- addons/web/static/src/scss/utilities_custom.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/addons/web/static/src/scss/utilities_custom.scss b/addons/web/static/src/scss/utilities_custom.scss index 90b87c42348..157795a4626 100644 --- a/addons/web/static/src/scss/utilities_custom.scss +++ b/addons/web/static/src/scss/utilities_custom.scss @@ -56,6 +56,12 @@ $utilities: () !default; $utilities: map-merge( $utilities, ( + "display": map-merge( + map-get($utilities, "display"), + ( + values: join(map-get(map-get($utilities, "display"), "values"), contents), + ), + ), "position": map-merge( map-get($utilities, "position"), ( From 929769ecdd77e09f5efc47dbccdfdb9668292651 Mon Sep 17 00:00:00 2001 From: Brieuc-brd Date: Thu, 11 Aug 2022 15:29:54 +0000 Subject: [PATCH 2/4] [REF] web: `FormView`, replace tables with grids This commit replaces the FormView group tables with css grids. Part of the overall v16 SCSS optimization/restyle, task-2704984 task-2918464 X-original-commit: a2b894989ea33364dd29a7d412e4bd4260c1f5ef Part-of: odoo/odoo#101655 --- .../static/src/views/form/form_compiler.js | 11 +- .../src/views/form/form_controller.scss | 171 +++++---------- .../src/views/form/form_group/form_group.js | 6 +- .../src/views/form/form_group/form_group.xml | 66 +++--- .../views/fields/one2many_field_tests.js | 2 +- .../views/fields/reference_field_tests.js | 2 +- .../tests/views/form/form_view_tests.js | 203 +++++++----------- 7 files changed, 187 insertions(+), 274 deletions(-) diff --git a/addons/web/static/src/views/form/form_compiler.js b/addons/web/static/src/views/form/form_compiler.js index 92b80fa3d94..79989bc5c19 100644 --- a/addons/web/static/src/views/form/form_compiler.js +++ b/addons/web/static/src/views/form/form_compiler.js @@ -316,7 +316,7 @@ export class FormCompiler extends ViewCompiler { } if (getTag(child, true) === "separator") { - forceNewline = true; + itemSpan = parseInt(formGroup.getAttribute("maxCols") || 2, 10); } let slotContent; @@ -343,9 +343,14 @@ export class FormCompiler extends ViewCompiler { mainSlot.setAttribute("subType", "'item_component'"); } } else { - if (child.classList.contains("o_td_label") || getTag(child, true) === "label") { + // TODO: When every apps will be revamp, we could remove the condition using 'o_td_label' in favor of 'o_wrap_label' + if ( + child.classList.contains("o_wrap_label") || + child.classList.contains("o_td_label") || + getTag(child, true) === "label" + ) { mainSlot.setAttribute("subType", "'label'"); - child.classList.remove("o_td_label"); + child.classList.remove("o_wrap_label"); } slotContent = this.compileNode(child, params, false); } diff --git a/addons/web/static/src/views/form/form_controller.scss b/addons/web/static/src/views/form/form_controller.scss index 21a10b58558..bf8c51ce4b3 100644 --- a/addons/web/static/src/views/form/form_controller.scss +++ b/addons/web/static/src/views/form/form_controller.scss @@ -28,53 +28,38 @@ margin-right: -$o-horizontal-padding; } -@mixin o-td-label-style { - width: 0%; - padding: 0 15px 0 0; - min-width: 150px; +@mixin o-label-style { color: $headings-color; } // XXS form view specific rules @mixin form-break-table { - display: block; + grid-template-columns: 1fr; margin-bottom: $o-form-spacing-unit * 4; - > tbody { - display: block; + .o_wrap_field { + .o_cell { + max-width: 100%; - > tr { - display: flex; - flex-flow: row wrap; - padding-bottom: map-get($spacers, 3); + &.o_wrap_label { + line-height: $o-label-font-size-factor; + } - > td { - flex: 1 0 auto; - display: block; + .o_field_widget { + margin-bottom: $o-form-spacing-unit * 2; + + > .o_field_widget { + margin-bottom: 0; + } + + &.o_field_boolean { + margin-right: 0; + } + } + + .o_input_dropdown { + width: auto; max-width: 100%; - padding: 0; - - &.o_td_label { - width: 94%!important; // The label must be on its own line except if the form field is small enough (checkbox) - line-height: $o-label-font-size-factor; - } - - .o_field_widget { - margin-bottom: $o-form-spacing-unit * 2; - - > .o_field_widget { - margin-bottom: 0; - } - - &.o_field_boolean { - margin-right: 0; - } - } - - .o_input_dropdown { - width: auto; - max-width: 100%; - } } } } @@ -104,11 +89,6 @@ } .oe_inline, .o_field_widget.oe_inline > * { width: auto!important; - @include media-breakpoint-up(vsm, $o-extra-grid-breakpoints) { - &.o_inner_group { - width: 1px!important; - } - } } .oe_left { @extend .oe_inline; @@ -419,48 +399,6 @@ // Groups .o_group { - display: inline-block; - width: 100%; - margin: 10px 0; - - .o_group { - margin: 0; - } - - // o_group contains nested groups - @for $i from 1 through $o-form-group-cols { - .o_group_col_#{$i} { - display: inline-block; - width: floor(100% / 12 * $i); - vertical-align: top; - - @include media-breakpoint-down(lg) { - width: 100%; - } - } - } - - &.o_inner_group { - display: inline-table; - - > tbody > tr > td { - padding: 0 $o-innergroup-rpadding 0 0; - vertical-align: top; - - &.o_td_label { - @include o-td-label-style; - } - } - - .o_field_widget { - &.o_field_many2one_avatar { - .o_field_many2one_selection { - width: calc(100% - 24px); - } - } - } - } - .o_form_label { font-weight: $font-weight-normal; } @@ -474,19 +412,6 @@ } } - @include media-breakpoint-up(sm) { - :not(.o_row):not(.o_data_cell) > .o_field_widget, - .o_row > .o_field_widget:last-child { // Note: this does not take care - // of an invisible last-child but - // it does not really matter - // Makes extra buttons (e.g. m2o external button) overflow on the - // right padding of the parent element - .o_input_dropdown { - flex: 1 0 auto; - } - } - } - @include media-breakpoint-up(vsm, $o-extra-grid-breakpoints) { .o_field_widget { &.o_text_overflow { @@ -509,13 +434,33 @@ white-space: normal; } } - - .o_td_label .o_form_label { + .o_wrap_label .o_form_label { font-weight: $font-weight-bold; margin-right: $o-form-label-margin-right; } } + .o_inner_group { + --columns: 1; + gap: map-get($spacers, 2) $o-horizontal-padding; + + .o_wrap_label { + @include o-label-style; + } + + span, .o_field_boolean, .oe_avatar, .o_form_uri { + &.o_field_widget { + width: auto; + } + } + } + + @include media-breakpoint-up(sm) { + .o_inner_group { + grid-template-columns: fit-content(150px) 1fr; + } + } + .o_checkbox_optional_field { display: flex; @@ -525,7 +470,7 @@ } > .o_form_label { - @include o-td-label-style; + @include o-label-style; margin-right: $o-form-label-margin-right; font-weight: $font-weight-bold; } @@ -715,10 +660,7 @@ margin-bottom: 0px; } } - .o_td_label .o_form_label:not(.o_status), .o_checkbox_optional_field > .o_form_label { - min-height: 23px; - } - td:not(.o_field_cell) .o_form_uri > span:first-child { + .o_cell:not(.o_field_cell) .o_form_uri > span:first-child { display: inline-block; padding: 1px 0; margin-bottom: 1px; @@ -783,14 +725,15 @@ } // Specific style classes - .o_group.o_inner_group.oe_subtotal_footer { + .o_inner_group.oe_subtotal_footer { + grid-template-columns: 1fr auto; @extend .oe_right; border-top: 1px solid $border-color; - > tbody > tr > td { + .o_cell { padding: 0; - &.o_td_label { + &.o_wrap_label { text-align: right; } @@ -811,7 +754,7 @@ } } - > tbody > tr:first-child > td { + .o_wrap_field:first-child > .o_cell { padding-top: 4px; } .oe_subtotal_footer_separator { @@ -964,7 +907,7 @@ } .oe_form_configuration { - .o_group .o_form_label { + .o_inner_group .o_form_label { white-space: nowrap; } h2 { @@ -1125,7 +1068,7 @@ } @include media-breakpoint-down(lg) { - .o_group.o_inner_group > tbody > tr > td.o_td_label { + .o_group.o_inner_group .o_wrap_label { min-width: 100px; } } @@ -1138,7 +1081,7 @@ } &.modal-sm .o_form_view { - .o_group { + .o_inner_group { @include form-break-table; } } @@ -1191,12 +1134,12 @@ word-break: break-all; } .o_group { - &.o_inner_group { - @include form-break-table; + .o_inner_group { + margin-bottom: $o-form-spacing-unit * 4; // Target XXS form view on mobile devices in portrait mode @include media-breakpoint-down(md) { - &:not(.oe_subtotal_footer) > tbody > tr > td { + &:not(.oe_subtotal_footer) > .o_cell { > .o_field_widget { margin-bottom: $o-form-spacing-unit * 4; } diff --git a/addons/web/static/src/views/form/form_group/form_group.js b/addons/web/static/src/views/form/form_group/form_group.js index 760348d2b66..3ba011a489b 100644 --- a/addons/web/static/src/views/form/form_group/form_group.js +++ b/addons/web/static/src/views/form/form_group/form_group.js @@ -26,7 +26,7 @@ export class OuterGroup extends Group { return items.map((item) => { const [slotName, slot] = item; const itemSpan = slot.itemSpan || 1; - return { name: slotName, size: itemSpan * colSize, newline: slot.newline }; + return { name: slotName, size: itemSpan * colSize, newline: slot.newline, colspan: itemSpan }; }); } } @@ -34,6 +34,7 @@ OuterGroup.template = "web.Form.OuterGroup"; OuterGroup.defaultProps = { ...Group.defaultProps, slots: [], + hasOuterTemplate: true, }; export class InnerGroup extends Group { @@ -66,6 +67,9 @@ export class InnerGroup extends Group { const isVisible = !("isVisible" in slot) || slot.isVisible; currentRow.push({ name: slotName, subType, itemSpan, props, isVisible, Component }); reservedSpace += itemSpan || 1; + + // Allows to remove the line if the content is not visible instead of leaving an empty line. + currentRow.isVisible = isVisible; } rows.push(currentRow); diff --git a/addons/web/static/src/views/form/form_group/form_group.xml b/addons/web/static/src/views/form/form_group/form_group.xml index df9883c4dd0..d3aa94431a7 100644 --- a/addons/web/static/src/views/form/form_group/form_group.xml +++ b/addons/web/static/src/views/form/form_group/form_group.xml @@ -2,44 +2,48 @@ -
- - -
- - -
+
+ + + + + +
- - - - - +
+
+ +
+
+ - -
- - + +
+ +
+
+ +
+
- - - + +
+ +
+
- - -
- -
- - - - - -
+ +
diff --git a/addons/web/static/tests/views/fields/one2many_field_tests.js b/addons/web/static/tests/views/fields/one2many_field_tests.js index 3b89e05dd1e..7f49dd07950 100644 --- a/addons/web/static/tests/views/fields/one2many_field_tests.js +++ b/addons/web/static/tests/views/fields/one2many_field_tests.js @@ -5429,7 +5429,7 @@ QUnit.module("Fields", (hooks) => { await click(target.querySelector(".modal-footer button.btn-primary")); assert.containsOnce(target, ".modal"); - assert.containsOnce(target, ".modal tbody label.o_field_invalid"); + assert.containsOnce(target, ".modal label.o_field_invalid"); }); QUnit.test("one2many list with action button", async function (assert) { diff --git a/addons/web/static/tests/views/fields/reference_field_tests.js b/addons/web/static/tests/views/fields/reference_field_tests.js index 6b42c2737d6..d843af8f244 100644 --- a/addons/web/static/tests/views/fields/reference_field_tests.js +++ b/addons/web/static/tests/views/fields/reference_field_tests.js @@ -919,7 +919,7 @@ QUnit.module("Fields", (hooks) => { `, }); - const groups = target.querySelectorAll(".o_group"); + const groups = target.querySelectorAll(".o_inner_group"); assert.containsNone( groups[0], diff --git a/addons/web/static/tests/views/form/form_view_tests.js b/addons/web/static/tests/views/form/form_view_tests.js index bc881f60df8..8017b9bad89 100644 --- a/addons/web/static/tests/views/form/form_view_tests.js +++ b/addons/web/static/tests/views/form/form_view_tests.js @@ -276,7 +276,7 @@ QUnit.module("Views", (hooks) => { assert.containsOnce(target, ".o_field_char input"); assert.strictEqual(target.querySelector(".o_field_char input").value, "blip"); assert.hasAttrValue( - target.querySelector(".o_group .o_group"), + target.querySelector(".o_group .o_inner_group"), "style", "background-color: red", "should apply style attribute on groups" @@ -292,7 +292,7 @@ QUnit.module("Views", (hooks) => { assert.containsOnce(target, "div.o_field_one2many table"); assert.containsOnce( target, - "tbody td:not(.o_list_record_selector) .o-checkbox input:checked" + "div.o_cell:not(.o_list_record_selector) .o-checkbox input:checked" ); assert.containsNone(target, "label.o_form_label_empty:contains(timmy)"); }); @@ -825,7 +825,7 @@ QUnit.module("Views", (hooks) => { resId: 1, }); - assert.containsOnce(target, "table.o_inner_group"); + assert.containsOnce(target, "div.o_inner_group"); }); QUnit.test("group containing both a field and a group", async function (assert) { @@ -854,7 +854,7 @@ QUnit.module("Views", (hooks) => { assert.containsOnce(target, ".o_group .o_inner_group .o_field_widget[name=int_field]"); assert.hasClass(target.querySelector(".o_field_widget[name=foo]"), "o_field_char"); - assert.hasClass(target.querySelector(".o_field_widget[name=foo]"), "o_group_col_6"); + assert.hasClass(target.querySelector(".o_field_widget[name=foo]"), "col-lg-6"); }); QUnit.test("Form and subview with _view_ref contexts", async function (assert) { @@ -1035,8 +1035,8 @@ QUnit.module("Views", (hooks) => { assert.containsNone(target, ".o_form_statusbar button:contains(coucou)"); assert.containsOnce(target, ".o_notebook li a:contains(visible)"); assert.containsNone(target, ".o_notebook li a:contains(invisible)"); - assert.containsOnce(target, "table.o_inner_group td:contains(visgroup)"); - assert.containsNone(target, "table.o_inner_group td:contains(invgroup)"); + assert.containsOnce(target, "div.o_inner_group:contains(visgroup)"); + assert.containsNone(target, "div.o_inner_group:contains(invgroup)"); }); QUnit.test( @@ -3962,18 +3962,18 @@ QUnit.module("Views", (hooks) => { ); assert.hasAttrValue( - target.querySelector(".firstgroup td"), - "colspan", + target.querySelector(".firstgroup div"), + "style", undefined, - "foo td should have a default colspan (1)" + "foo div should have a default colspan (1)" ); - assert.containsN(target, ".secondgroup tr", 2, "int_field and qux should have same tr"); + assert.containsN(target, ".secondgroup div.o_wrap_field", 2, "int_field and qux should have same o_wrap_field"); assert.containsN( target, - ".secondgroup tr:first td", + ".secondgroup div.o_wrap_field:first div.o_cell", 2, - "product_id field should be on its own tr" + "product_id field should be on its own o_wrap_field" ); }); @@ -4867,8 +4867,8 @@ QUnit.module("Views", (hooks) => { resId: 1, }); - assert.hasClass(target.querySelector(".inner_group"), "o_group_col_6"); - assert.hasClass(target.querySelector(".inner_div"), "o_group_col_6"); + assert.hasClass(target.querySelector(".inner_group"), "col-lg-6"); + assert.hasClass(target.querySelector(".inner_div"), "col-lg-6"); }); QUnit.test("deleting a record", async function (assert) { @@ -7804,10 +7804,10 @@ QUnit.module("Views", (hooks) => { // Verify outergroup/innergroup assert.strictEqual($parentGroup[0].tagName, "DIV", ".parent_group should be an outergroup"); - assert.strictEqual($group4[0].tagName, "TABLE", ".group_4 should be an innergroup"); + assert.strictEqual($group4[0].tagName, "DIV", ".group_4 should be an innergroup"); assert.strictEqual($group3[0].tagName, "DIV", ".group_3 should be an outergroup"); - assert.strictEqual($group1[0].tagName, "TABLE", ".group_1 should be an innergroup"); - assert.strictEqual($fieldGroup[0].tagName, "TABLE", ".field_group should be an innergroup"); + assert.strictEqual($group1[0].tagName, "DIV", ".group_1 should be an innergroup"); + assert.strictEqual($fieldGroup[0].tagName, "DIV", ".field_group should be an innergroup"); // Verify .parent_group content var $parentGroupChildren = $parentGroup.children(); @@ -7817,174 +7817,131 @@ QUnit.module("Views", (hooks) => { "there should be 2 groups in .parent_group" ); assert.ok( - $parentGroupChildren.eq(0).is(".o_group_col_6"), + $parentGroupChildren.eq(0).is(".col-lg-6"), "first .parent_group group should be 1/2 parent width" ); assert.ok( - $parentGroupChildren.eq(1).is(".o_group_col_8"), - "second .parent_group group should be 2/3 parent width" + $parentGroupChildren.eq(1).is(".col-lg-8"), + "second .parent_group group should be 3/4 parent width" ); // Verify .group_4 content - var $group4rows = $group4.find("> tbody > tr"); + var $group4rows = $group4.find("> div.o_wrap_field"); assert.strictEqual($group4rows.length, 3, "there should be 3 rows in .group_4"); - var $group4firstRowTd = $group4rows.eq(0).children("td"); - assert.strictEqual($group4firstRowTd.length, 1, "there should be 1 td in first row"); - assert.hasAttrValue($group4firstRowTd, "colspan", "3", "the first td colspan should be 3"); + var $group4firstRowTd = $group4rows.eq(0).children("div.o_cell"); + assert.strictEqual($group4firstRowTd.length, 1, "there should be 1 cell in first row"); + assert.strictEqual($group4firstRowTd.attr("style").substr(0, 19), "grid-column: span 3", "the first cell column span should be 3"); assert.strictEqual( - $group4firstRowTd.attr("style").substr(0, 9), - "width: 75", - "the first td should be 75% width" + $group4firstRowTd.attr("style").substr(0, 19), + "grid-column: span 3", + "the first cell should be 75% width" ); assert.strictEqual( $group4firstRowTd.children()[0].tagName, "DIV", - "the first td should contain a div" - ); - var $group4secondRowTds = $group4rows.eq(1).children("td"); - assert.strictEqual($group4secondRowTds.length, 2, "there should be 2 tds in second row"); - assert.hasAttrValue( - $group4secondRowTds.eq(0), - "colspan", - "2", - "the first td colspan should be 2" + "the first cell should contain a div" ); + var $group4secondRowTds = $group4rows.eq(1).children("div.o_cell"); + assert.strictEqual($group4secondRowTds.length, 2, "there should be 2 cells in second row"); assert.strictEqual( - $group4secondRowTds.eq(0).attr("style").substr(0, 9), - "width: 50", - "the first td be 50% width" - ); - assert.hasAttrValue( - $group4secondRowTds.eq(1), - "colspan", - undefined, - "the second td colspan should be default one (1)" + $group4secondRowTds.attr("style").substr(0, 29), + "grid-column: span 2;width: 50", + "the first cell colspan should be 2 and be 50% width" ); assert.strictEqual( $group4secondRowTds.eq(1).attr("style").substr(0, 9), "width: 25", - "the second td be 75% width" + "the second cell colspan should be default one (no style) and be 25% width" ); - var $group4thirdRowTd = $group4rows.eq(2).children("td"); - assert.strictEqual($group4thirdRowTd.length, 1, "there should be 1 td in third row"); - assert.hasAttrValue($group4thirdRowTd, "colspan", "4", "the first td colspan should be 4"); + var $group4thirdRowTd = $group4rows.eq(2).children(".o_cell"); + assert.strictEqual($group4thirdRowTd.length, 1, "there should be 1 cell in third row"); assert.strictEqual( - $group4thirdRowTd.attr("style").substr(0, 10), - "width: 100", - "the first td should be 100% width" + $group4thirdRowTd.attr("style").substr(0, 30), + "grid-column: span 4;width: 100", + "the first cell colspan should be 4 and be 100% width" ); // Verify .group_3 content assert.strictEqual($group3.children().length, 3, ".group_3 should have 3 children"); assert.strictEqual( - $group3.children(".o_group_col_4").length, + $group3.children(".col-lg-4").length, 3, ".group_3 should have 3 children of 1/3 width" ); // Verify .group_1 content assert.strictEqual( - $group1.find("> tbody > tr").length, + $group1.find("> .o_wrap_field").length, 3, "there should be 3 rows in .group_1" ); // Verify .field_group content - var $fieldGroupRows = $fieldGroup.find("> tbody > tr"); - assert.strictEqual($fieldGroupRows.length, 5, "there should be 5 rows in .field_group"); - var $fieldGroupFirstRowTds = $fieldGroupRows.eq(0).children("td"); - assert.strictEqual($fieldGroupFirstRowTds.length, 2, "there should be 2 tds in first row"); + var $fieldGroupRows = $fieldGroup.find("> .o_wrap_field"); + assert.strictEqual($fieldGroupRows.length, 5, "there should be 5 rows in .o_wrap_field"); + var $fieldGroupFirstRowTds = $fieldGroupRows.eq(0).children(".o_cell"); + assert.strictEqual($fieldGroupFirstRowTds.length, 2, "there should be 2 cells in first row"); assert.hasClass( $fieldGroupFirstRowTds.eq(0), - "o_td_label", - "first td should be a label td" - ); - assert.hasAttrValue( - $fieldGroupFirstRowTds.eq(1), - "colspan", - "2", - "second td colspan should be given colspan (3) - 1 (label)" + "o_wrap_label", + "first cell should be a label cell" ); assert.strictEqual( - $fieldGroupFirstRowTds.eq(1).attr("style").substr(0, 10), - "width: 100", - "second td width should be 100%" + $fieldGroupFirstRowTds.eq(1).attr("style").substr(0, 30), + "grid-column: span 2;width: 100", + "second cell colspan should be given colspan (3) - 1 (label) and be 100%" ); - var $fieldGroupSecondRowTds = $fieldGroupRows.eq(1).children("td"); + var $fieldGroupSecondRowTds = $fieldGroupRows.eq(1).children(".o_cell"); assert.strictEqual( $fieldGroupSecondRowTds.length, 2, - "there should be 2 tds in second row" - ); - assert.hasAttrValue( - $fieldGroupSecondRowTds.eq(0), - "colspan", - undefined, - "first td colspan should be default one (1)" + "there should be 2 cells in second row" ); assert.strictEqual( $fieldGroupSecondRowTds.eq(0).attr("style").substr(0, 9), "width: 33", - "first td width should be 33.3333%" - ); - assert.hasAttrValue( - $fieldGroupSecondRowTds.eq(1), - "colspan", - undefined, - "second td colspan should be default one (1)" + "first cell colspan should be default one (no style) and be 33.3333%" ); assert.strictEqual( $fieldGroupSecondRowTds.eq(1).attr("style").substr(0, 9), "width: 33", - "second td width should be 33.3333%" + "second cell colspan should be default one (no style) and be 33.3333%" ); - var $fieldGroupThirdRowTds = $fieldGroupRows.eq(2).children("td"); // new row as label/field pair colspan is greater than remaining space - assert.strictEqual($fieldGroupThirdRowTds.length, 2, "there should be 2 tds in third row"); + var $fieldGroupThirdRowTds = $fieldGroupRows.eq(2).children(".o_cell"); // new row as label/field pair colspan is greater than remaining space + assert.strictEqual($fieldGroupThirdRowTds.length, 2, "there should be 2 cells in third row"); assert.hasClass( $fieldGroupThirdRowTds.eq(0), - "o_td_label", - "first td should be a label td" - ); - assert.hasAttrValue( - $fieldGroupThirdRowTds.eq(1), - "colspan", - undefined, - "second td colspan should be default one (1)" + "o_wrap_label", + "first cell should be a label cell" ); assert.strictEqual( $fieldGroupThirdRowTds.eq(1).attr("style").substr(0, 9), "width: 50", - "second td should be 50% width" - ); - var $fieldGroupFourthRowTds = $fieldGroupRows.eq(3).children("td"); - assert.strictEqual($fieldGroupFourthRowTds.length, 1, "there should be 1 td in fourth row"); - assert.hasAttrValue( - $fieldGroupFourthRowTds, - "colspan", - "3", - "the td should have a colspan equal to 3" + "second cell colspan should be default one (no style) and be 50% width" ); + var $fieldGroupFourthRowTds = $fieldGroupRows.eq(3).children(".o_cell"); + assert.strictEqual($fieldGroupFourthRowTds.length, 1, "there should be 1 cell in fourth row"); assert.strictEqual( - $fieldGroupFourthRowTds.attr("style").substr(0, 10), - "width: 100", - "the td should have 100% width" + $fieldGroupFourthRowTds.attr("style").substr(0, 30), + "grid-column: span 3;width: 100", + "the cell should have a colspan equal to 3 and have 100% width" ); - var $fieldGroupFifthRowTds = $fieldGroupRows.eq(4).children("td"); // label/field pair can be put after the 1-colspan span - assert.strictEqual($fieldGroupFifthRowTds.length, 3, "there should be 3 tds in fourth row"); + var $fieldGroupFifthRowTds = $fieldGroupRows.eq(4).children(".o_cell"); // label/field pair can be put after the 1-colspan span + assert.strictEqual($fieldGroupFifthRowTds.length, 3, "there should be 3 cells in fourth row"); assert.strictEqual( $fieldGroupFifthRowTds.eq(0).attr("style").substr(0, 9), "width: 50", - "the first td should 50% width" + "the first cell should 50% width" ); assert.hasClass( $fieldGroupFifthRowTds.eq(1), - "o_td_label", - "the second td should be a label td" + "o_wrap_label", + "the second cell should be a label cell" ); assert.strictEqual( $fieldGroupFifthRowTds.eq(2).attr("style").substr(0, 9), "width: 50", - "the third td should 50% width" + "the third cell should 50% width" ); }); @@ -8012,10 +7969,10 @@ QUnit.module("Views", (hooks) => { resId: 1, }); - const rows = document.querySelectorAll(".o_inner_group tr"); - assert.containsOnce(rows[0], "> td", "Should only contain one cell"); + const rows = document.querySelectorAll(".o_inner_group > div"); + assert.containsOnce(rows[0], "> .o_cell", "Should only contain one cell"); assert.containsOnce(rows[0], ".o_horizontal_separator"); - assert.containsN(rows[1], "> td", 2, "Should contain 2 cells"); + assert.containsN(rows[1], "> .o_cell", 2, "Should contain 2 cells"); assert.containsOnce(rows[1], "label[for=display_name]"); assert.containsOnce(rows[1], "div[name=display_name]"); } @@ -8045,7 +8002,7 @@ QUnit.module("Views", (hooks) => { var $parentGroup = $(target.querySelector(".parent_group")); var $group1 = $(target.querySelector(".group_1")); var $group2 = $(target.querySelector(".group_2")); - assert.containsN(target, "table.o_inner_group", 2, "should contain two inner groups"); + assert.containsN(target, "div.o_inner_group", 2, "should contain two inner groups"); assert.strictEqual( $group1.find(".o_horizontal_separator").length, 1, @@ -8089,7 +8046,7 @@ QUnit.module("Views", (hooks) => {
@@ -8107,29 +8064,29 @@ QUnit.module("Views", (hooks) => { // Inner group assert.containsN( target, - ".main_inner_group > tbody > tr", + ".main_inner_group > .o_wrap_field", 2, "there should be 2 rows in the group" ); assert.containsOnce( target, - ".main_inner_group > tbody > tr:first > .o_td_label", + ".main_inner_group > .o_wrap_field:first > .o_wrap_label", "there should be only one label in the first row" ); assert.containsOnce( target, - ".main_inner_group > tbody > tr:first .o_field_widget", + ".main_inner_group > .o_wrap_field:first .o_field_widget", "there should be only one widget in the first row" ); assert.containsN( target, - ".main_inner_group > tbody > tr:last > .o_td_label", + ".main_inner_group > .o_wrap_field:last > .o_wrap_label", 2, "there should be two labels in the second row" ); assert.containsN( target, - ".main_inner_group > tbody > tr:last .o_field_widget", + ".main_inner_group > .o_wrap_field:last .o_field_widget", 2, "there should be two widgets in the second row" ); From 98d093b3c2b51cafcaee2508eaa9a4d18e253c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Dieudonn=C3=A9?= Date: Thu, 29 Sep 2022 12:22:28 +0000 Subject: [PATCH 3/4] [IMP] web: FormView, remove unnecessary mixin task-2918464 X-original-commit: a1f4f8ea930425c9556691d518905b2fe5ee6da2 Part-of: odoo/odoo#101655 --- addons/web/static/src/views/form/form_controller.scss | 10 +--------- .../static/src/views/form/form_group/form_group.xml | 4 ++-- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/addons/web/static/src/views/form/form_controller.scss b/addons/web/static/src/views/form/form_controller.scss index bf8c51ce4b3..db6c814733d 100644 --- a/addons/web/static/src/views/form/form_controller.scss +++ b/addons/web/static/src/views/form/form_controller.scss @@ -28,10 +28,6 @@ margin-right: -$o-horizontal-padding; } -@mixin o-label-style { - color: $headings-color; -} - // XXS form view specific rules @mixin form-break-table { grid-template-columns: 1fr; @@ -444,10 +440,6 @@ --columns: 1; gap: map-get($spacers, 2) $o-horizontal-padding; - .o_wrap_label { - @include o-label-style; - } - span, .o_field_boolean, .oe_avatar, .o_form_uri { &.o_field_widget { width: auto; @@ -470,7 +462,7 @@ } > .o_form_label { - @include o-label-style; + color: $headings-color; margin-right: $o-form-label-margin-right; font-weight: $font-weight-bold; } diff --git a/addons/web/static/src/views/form/form_group/form_group.xml b/addons/web/static/src/views/form/form_group/form_group.xml index d3aa94431a7..053607f105e 100644 --- a/addons/web/static/src/views/form/form_group/form_group.xml +++ b/addons/web/static/src/views/form/form_group/form_group.xml @@ -20,7 +20,7 @@ -
+
From a1c59a0aa82a7ee8b65a77514c91df44d600a9bc Mon Sep 17 00:00:00 2001 From: Brieuc-brd Date: Fri, 23 Sep 2022 10:13:30 +0000 Subject: [PATCH 4/4] [FIX] hr: adapt size of `o_work_employee_main` Since commit ae7bd570e13fe19367f86a1519b23747b3b0b73e, the size of `o_work_employee_main` has been reduced. This commit fixes this issue. task-2918464 X-original-commit: 99d13b4b3a5efabff9f71f0cfe1b9cf72bb47ccd Part-of: odoo/odoo#101655 --- addons/hr/views/hr_employee_public_views.xml | 2 +- addons/hr/views/hr_employee_views.xml | 2 +- addons/hr/views/res_users.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/hr/views/hr_employee_public_views.xml b/addons/hr/views/hr_employee_public_views.xml index cd627019ecf..d306aa6c26f 100644 --- a/addons/hr/views/hr_employee_public_views.xml +++ b/addons/hr/views/hr_employee_public_views.xml @@ -71,7 +71,7 @@
-
+
-
+
-
+