diff --git a/addons/test_mail/static/tests/tracking_value_tests.js b/addons/test_mail/static/tests/tracking_value_tests.js index 3d3fc04ba55..c3d04eac6a4 100644 --- a/addons/test_mail/static/tests/tracking_value_tests.js +++ b/addons/test_mail/static/tests/tracking_value_tests.js @@ -211,7 +211,7 @@ QUnit.test('rendering of tracked field of type boolean: from true to false', asy const mailTestTrackAllId1 = pyEnv['mail.test.track.all'].create({ boolean_field: true }); const { click } = await this.start({ res_id: mailTestTrackAllId1 }); - document.querySelector('.form-check input').click(); + document.querySelector('.o_field_boolean input').click(); await click('.o_form_button_save'); assert.strictEqual( document.querySelector('.o_TrackingValue').textContent, @@ -227,7 +227,7 @@ QUnit.test('rendering of tracked field of type boolean: from false to true', asy const mailTestTrackAllId1 = pyEnv['mail.test.track.all'].create({}); const { click } = await this.start({ res_id: mailTestTrackAllId1 }); - document.querySelector('.form-check input').click(); + document.querySelector('.o_field_boolean input').click(); await click('.o_form_button_save'); assert.strictEqual( document.querySelector('.o_TrackingValue').textContent, diff --git a/addons/web/static/src/core/checkbox/checkbox.scss b/addons/web/static/src/core/checkbox/checkbox.scss deleted file mode 100644 index 57880fdf50f..00000000000 --- a/addons/web/static/src/core/checkbox/checkbox.scss +++ /dev/null @@ -1,20 +0,0 @@ -// = Checkbox -// ============================================================================ - -.custom-control.form-check .form-check-input { - &:disabled { - ~ .form-check-label { - cursor: not-allowed; - } - - &:checked ~ .form-check-label:after { - // Use odoo custom muted icon - background-image: $o-custom-checkbox-indicator-icon-checked-disabled; - } - } - - @media print { - -webkit-print-color-adjust: exact !important; - color-adjust: exact !important; - } -} diff --git a/addons/web/static/src/core/checkbox/checkbox.xml b/addons/web/static/src/core/checkbox/checkbox.xml index b60d55f6c3e..5f25a60020e 100644 --- a/addons/web/static/src/core/checkbox/checkbox.xml +++ b/addons/web/static/src/core/checkbox/checkbox.xml @@ -2,7 +2,7 @@ -
+
") !default; - // Layout // // Extension of BS4. This is not redefining the BS4 variable directly as we only diff --git a/addons/web/static/src/legacy/xml/base.xml b/addons/web/static/src/legacy/xml/base.xml index 8249c27d853..fc81d55fd42 100644 --- a/addons/web/static/src/legacy/xml/base.xml +++ b/addons/web/static/src/legacy/xml/base.xml @@ -92,7 +92,7 @@ -
+
​ - diff --git a/addons/web/static/src/views/list/list_controller.scss b/addons/web/static/src/views/list/list_controller.scss index 0dbd59fbb29..bbc6b914d51 100644 --- a/addons/web/static/src/views/list/list_controller.scss +++ b/addons/web/static/src/views/list/list_controller.scss @@ -117,6 +117,9 @@ .o_list_record_selector { width: 40px; padding-left: $o-horizontal-padding; + .o-checkbox { + margin-bottom: $form-check-margin-bottom; + } .form-check-label { cursor: pointer; } diff --git a/addons/web/static/src/views/list/list_renderer.js b/addons/web/static/src/views/list/list_renderer.js index be0921bf9d4..0d90273beb4 100644 --- a/addons/web/static/src/views/list/list_renderer.js +++ b/addons/web/static/src/views/list/list_renderer.js @@ -261,7 +261,7 @@ export class ListRenderer extends Component { table.classList.add("o_list_computing_widths"); const headers = [...table.querySelectorAll("thead th")]; - const columnWidths = headers.map((th) => th.offsetWidth); + const columnWidths = headers.map((th) => Math.floor(th.getBoundingClientRect().width)); const getWidth = (th) => columnWidths[headers.indexOf(th)] || 0; const getTotalWidth = () => columnWidths.reduce((tot, width) => tot + width, 0); const shrinkColumns = (thsToShrink, shrinkAmount) => { diff --git a/addons/web/static/src/views/widgets/week_days/week_days.scss b/addons/web/static/src/views/widgets/week_days/week_days.scss new file mode 100644 index 00000000000..1ef21c8fb4f --- /dev/null +++ b/addons/web/static/src/views/widgets/week_days/week_days.scss @@ -0,0 +1,5 @@ +.o_recurrent_weekdays .form-check .form-check-input { + float: none; + margin-left: 0; + margin-right: map-get($spacers, 1); +} diff --git a/addons/web/static/tests/core/checkbox_tests.js b/addons/web/static/tests/core/checkbox_tests.js index 2011af057a0..5b96d3619e7 100644 --- a/addons/web/static/tests/core/checkbox_tests.js +++ b/addons/web/static/tests/core/checkbox_tests.js @@ -32,7 +32,7 @@ QUnit.module("Components", (hooks) => { QUnit.test("can be rendered", async (assert) => { const env = await makeTestEnv(); await mount(CheckBox, target, { env, props: {} }); - assert.containsOnce(target, "div.form-check"); + assert.containsOnce(target, '.o-checkbox input[type="checkbox"]'); }); QUnit.test("has a slot for translatable text", async (assert) => { @@ -62,7 +62,7 @@ QUnit.module("Components", (hooks) => { Parent.components = { CheckBox }; await mount(Parent, target, { env }); - assert.containsOnce(target, "div.form-check"); + assert.containsOnce(target, ".o-checkbox input"); await click(target.querySelector("input")); assert.strictEqual(value, true); await click(target.querySelector("input")); @@ -83,12 +83,12 @@ QUnit.module("Components", (hooks) => { Parent.components = { CheckBox }; await mount(Parent, target, { env }); - assert.containsOnce(target, "div.form-check"); - assert.notOk(target.querySelector("div.form-check input").checked); - await triggerEvent(target, "div.form-check input", "keydown", { key: "Enter" }); - assert.ok(target.querySelector("div.form-check input").checked); - await triggerEvent(target, "div.form-check input", "keydown", { key: "Enter" }); - assert.notOk(target.querySelector("div.form-check input").checked); + assert.containsOnce(target, ".o-checkbox input"); + assert.notOk(target.querySelector(".o-checkbox input").checked); + await triggerEvent(target, ".o-checkbox input", "keydown", { key: "Enter" }); + assert.ok(target.querySelector(".o-checkbox input").checked); + await triggerEvent(target, ".o-checkbox input", "keydown", { key: "Enter" }); + assert.notOk(target.querySelector(".o-checkbox input").checked); }); QUnit.test("toggling through multiple ways", async (assert) => { @@ -105,43 +105,43 @@ QUnit.module("Components", (hooks) => { Parent.template = xml``; Parent.components = { CheckBox }; await mount(Parent, target, { env }); - assert.containsOnce(target, "div.form-check"); - assert.notOk(target.querySelector("div.form-check input").checked); + assert.containsOnce(target, ".o-checkbox input"); + assert.notOk(target.querySelector(".o-checkbox input").checked); // Click on div assert.verifySteps([]); - await click(target, "div.form-check"); - assert.ok(target.querySelector("div.form-check input").checked); + await click(target, ".o-checkbox"); + assert.ok(target.querySelector(".o-checkbox input").checked); assert.verifySteps(["true"]); // Click on label assert.verifySteps([]); - await click(target, "div.form-check label", true); - assert.notOk(target.querySelector("div.form-check input").checked); + await click(target, ".o-checkbox > .form-check-label", true); + assert.notOk(target.querySelector(".o-checkbox input").checked); assert.verifySteps(["false"]); // Click on input (only possible programmatically) assert.verifySteps([]); - await click(target, "div.form-check input"); - assert.ok(target.querySelector("div.form-check input").checked); + await click(target, ".o-checkbox input"); + assert.ok(target.querySelector(".o-checkbox input").checked); assert.verifySteps(["true"]); // When somehow applying focus on label, the focus receives it // (this is the default behavior from the label) - target.querySelector("div.form-check label").focus(); + target.querySelector(".o-checkbox > .form-check-label").focus(); await nextTick(); - assert.strictEqual(document.activeElement, target.querySelector("div.form-check input")); + assert.strictEqual(document.activeElement, target.querySelector(".o-checkbox input")); // Press Enter when focus is on input assert.verifySteps([]); triggerHotkey("Enter"); await nextTick(); - assert.notOk(target.querySelector("div.form-check input").checked); + assert.notOk(target.querySelector(".o-checkbox input").checked); assert.verifySteps(["false"]); // Pressing Space when focus is on the input is a standard behavior // So we simulate it and verify that it will have its standard behavior. - assert.strictEqual(document.activeElement, target.querySelector("div.form-check input")); + assert.strictEqual(document.activeElement, target.querySelector(".o-checkbox input")); const event = triggerEvent( document.activeElement, null, @@ -150,11 +150,11 @@ QUnit.module("Components", (hooks) => { { fast: true } ); assert.ok(!event.defaultPrevented); - target.querySelector("div.form-check input").checked = true; + target.querySelector(".o-checkbox input").checked = true; assert.verifySteps([]); - triggerEvent(target, "div.form-check input", "change", {}, { fast: true }); + triggerEvent(target, ".o-checkbox input", "change", {}, { fast: true }); await nextTick(); - assert.ok(target.querySelector("div.form-check input").checked); + assert.ok(target.querySelector(".o-checkbox input").checked); assert.verifySteps(["true"]); }); }); diff --git a/addons/web/static/tests/views/fields/boolean_field_tests.js b/addons/web/static/tests/views/fields/boolean_field_tests.js index 1c5d795e2d4..be39b061992 100644 --- a/addons/web/static/tests/views/fields/boolean_field_tests.js +++ b/addons/web/static/tests/views/fields/boolean_field_tests.js @@ -176,13 +176,13 @@ QUnit.module("Fields", (hooks) => { assert.containsN( target, - "tbody td:not(.o_list_record_selector) .form-check", + "tbody td:not(.o_list_record_selector) .o-checkbox input", 5, "should have 5 checkboxes" ); assert.containsN( target, - "tbody td:not(.o_list_record_selector) .form-check input:checked", + "tbody td:not(.o_list_record_selector) .o-checkbox input:checked", 4, "should have 4 checked input" ); @@ -190,52 +190,52 @@ QUnit.module("Fields", (hooks) => { // Edit a line let cell = target.querySelector("tr.o_data_row td:not(.o_list_record_selector)"); assert.ok( - cell.querySelector(".form-check input:checked").disabled, + cell.querySelector(".o-checkbox input:checked").disabled, "input should be disabled in readonly mode" ); await click(cell); assert.notOk( - cell.querySelector(".form-check input:checked").disabled, + cell.querySelector(".o-checkbox input:checked").disabled, "input should not have the disabled property in edit mode" ); - await click(cell, ".form-check"); + await click(cell, ".o-checkbox"); // save await click(target.querySelector(".o_list_button_save")); cell = target.querySelector("tr.o_data_row td:not(.o_list_record_selector)"); assert.ok( - cell.querySelector(".form-check input:not(:checked)").disabled, + cell.querySelector(".o-checkbox input:not(:checked)").disabled, "input should be disabled again" ); assert.containsN( target, - "tbody td:not(.o_list_record_selector) .form-check", + "tbody td:not(.o_list_record_selector) .o-checkbox", 5, "should still have 5 checkboxes" ); assert.containsN( target, - "tbody td:not(.o_list_record_selector) .form-check input:checked", + "tbody td:not(.o_list_record_selector) .o-checkbox input:checked", 3, "should now have only 3 checked input" ); // Re-Edit the line and fake-check the checkbox await click(cell); - await click(cell, ".form-check"); - await click(cell, ".form-check"); + await click(cell, ".o-checkbox"); + await click(cell, ".o-checkbox"); // Save await click(target.querySelector(".o_list_button_save")); assert.containsN( target, - "tbody td:not(.o_list_record_selector) .form-check", + "tbody td:not(.o_list_record_selector) .o-checkbox", 5, "should still have 5 checkboxes" ); assert.containsN( target, - "tbody td:not(.o_list_record_selector) .form-check input:checked", + "tbody td:not(.o_list_record_selector) .o-checkbox input:checked", 3, "should still have only 3 checked input" ); @@ -247,18 +247,18 @@ QUnit.module("Fields", (hooks) => { await click(cell, ".o_field_boolean"); assert.notOk( - cell.querySelector(".form-check input").disabled, + cell.querySelector(".o-checkbox input").disabled, "input should not have the disabled property in edit mode" ); assert.containsN( target, - "tbody td:not(.o_list_record_selector) .form-check", + "tbody td:not(.o_list_record_selector) .o-checkbox", 5, "should still have 5 checkboxes" ); assert.containsN( target, - "tbody td:not(.o_list_record_selector) .form-check input:checked", + "tbody td:not(.o_list_record_selector) .o-checkbox input:checked", 3, "should still have only 3 checked input" ); @@ -291,7 +291,7 @@ QUnit.module("Fields", (hooks) => { "checkbox should still be disabled" ); - await click(target, ".o_field_boolean .form-check"); + await click(target, ".o_field_boolean .o-checkbox"); assert.containsOnce( target, ".o_field_boolean input:checked", diff --git a/addons/web/static/tests/views/fields/boolean_toggle_field_tests.js b/addons/web/static/tests/views/fields/boolean_toggle_field_tests.js index da54bcc5b30..b7acbdac836 100644 --- a/addons/web/static/tests/views/fields/boolean_toggle_field_tests.js +++ b/addons/web/static/tests/views/fields/boolean_toggle_field_tests.js @@ -43,15 +43,15 @@ QUnit.module("Fields", (hooks) => { ); assert.containsOnce( target, - ".form-check.o_boolean_toggle .fa-check-circle", - "Boolean toggle should have fa-check-circle icon" + ".form-check.o_boolean_toggle input:checked", + "Boolean toggle should be checked" ); await click(target, ".o_field_widget[name='bar'] input"); assert.containsOnce( target, - ".form-check.o_boolean_toggle .fa-times-circle", - "Boolean toggle should have fa-times-circle icon" + ".form-check.o_boolean_toggle input:not(:checked)", + "Boolean toggle shouldn't be checked" ); }); 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 15971e11eee..568c8bb71c2 100644 --- a/addons/web/static/tests/views/form/form_view_tests.js +++ b/addons/web/static/tests/views/form/form_view_tests.js @@ -293,7 +293,7 @@ QUnit.module("Views", (hooks) => { assert.containsOnce(target, "div.o_field_one2many table"); assert.containsOnce( target, - "tbody td:not(.o_list_record_selector) .form-check input:checked" + "tbody td:not(.o_list_record_selector) .o-checkbox input:checked" ); assert.containsNone(target, "label.o_form_label_empty:contains(timmy)"); }); diff --git a/addons/web/static/tests/views/kanban_view_tests.js b/addons/web/static/tests/views/kanban_view_tests.js index 0b86ef7a70d..8e75160c0ab 100644 --- a/addons/web/static/tests/views/kanban_view_tests.js +++ b/addons/web/static/tests/views/kanban_view_tests.js @@ -9187,7 +9187,7 @@ QUnit.module("Views", (hooks) => { `, }); - assert.containsOnce(getCard(0), "div.o_field_boolean .form-check"); + assert.containsOnce(getCard(0), "div.o_field_boolean .o-checkbox"); }); QUnit.test("kanban view with boolean toggle widget", async (assert) => { diff --git a/addons/web/static/tests/views/list_view_tests.js b/addons/web/static/tests/views/list_view_tests.js index 5b95a4a3014..9658494ad44 100644 --- a/addons/web/static/tests/views/list_view_tests.js +++ b/addons/web/static/tests/views/list_view_tests.js @@ -5113,7 +5113,7 @@ QUnit.module("Views", (hooks) => { "", "Char field should yield an empty element" ); - assert.containsOnce(cells[1], ".form-check", "Boolean field has been instantiated"); + assert.containsOnce(cells[1], ".o-checkbox", "Boolean field has been instantiated"); assert.notOk(isNaN(cells[2].innerText.trim()), "Intger value is a number"); assert.ok(cells[3].innerText.trim(), "Many2one field is a string"); diff --git a/addons/web/static/tests/views/widgets/week_days_tests.js b/addons/web/static/tests/views/widgets/week_days_tests.js index 94d6534f2b8..f26df358063 100644 --- a/addons/web/static/tests/views/widgets/week_days_tests.js +++ b/addons/web/static/tests/views/widgets/week_days_tests.js @@ -82,7 +82,7 @@ QUnit.module("Widgets", ({ beforeEach }) => { assert.containsN( fixture, - ".custom-control input:disabled", + "input:disabled", 7, "all inputs should be disabled in readonly mode" ); diff --git a/addons/web/static/tests/webclient/settings_form_view_tests.js b/addons/web/static/tests/webclient/settings_form_view_tests.js index 171b2b67cb2..a8847e7e300 100644 --- a/addons/web/static/tests/webclient/settings_form_view_tests.js +++ b/addons/web/static/tests/webclient/settings_form_view_tests.js @@ -363,14 +363,14 @@ QUnit.module("SettingsFormView", (hooks) => { const webClient = await createWebClient({ serverData, mockRPC }); await doAction(webClient, 1); - assert.notOk(target.querySelector(".custom-control input").disabled); + assert.notOk(target.querySelector(".o_field_boolean input").disabled); await click(target.querySelector("button[name='4']")); assert.strictEqual( target.querySelector(".breadcrumb").textContent, "SettingsOther action" ); await click(target.querySelector(".o_control_panel .breadcrumb-item a")); - assert.notOk(target.querySelector(".custom-control input").disabled); + assert.notOk(target.querySelector(".o_field_boolean input").disabled); assert.verifySteps([ "get_views", // initial setting action "onchange", // this is a setting view => create new record @@ -413,7 +413,7 @@ QUnit.module("SettingsFormView", (hooks) => { "checkbox should not be checked" ); assert.containsNone(target, ".o_dirty_warning", "warning message should not be shown"); - await click(target.querySelector(".custom-control input[id=bar]")); + await click(target.querySelector(".o_field_boolean input[id=bar]")); assert.containsOnce(target, ".o_field_boolean input:checked", "checkbox should be checked"); window.dispatchEvent(new Event("beforeunload")); @@ -469,8 +469,8 @@ QUnit.module("SettingsFormView", (hooks) => { const webClient = await createWebClient({ serverData, mockRPC }); await doAction(webClient, 1); - assert.notOk(target.querySelector(".custom-control input").disabled); - await click(target.querySelector(".custom-control input")); + assert.notOk(target.querySelector(".o_field_boolean input").disabled); + await click(target.querySelector(".o_field_boolean input")); assert.containsOnce(target, ".o_field_boolean input:checked", "checkbox should be checked"); await click(target.querySelector(".o_form_button_save")); @@ -610,7 +610,7 @@ QUnit.module("SettingsFormView", (hooks) => { "checkbox should not be checked" ); - await click(target.querySelector(".custom-control input")); + await click(target.querySelector(".o_field_boolean input")); assert.containsOnce( target, ".o_field_boolean input:checked", @@ -630,7 +630,7 @@ QUnit.module("SettingsFormView", (hooks) => { "checkbox should not be checked" ); - await click(target.querySelector(".custom-control input")); + await click(target.querySelector(".o_field_boolean input")); await click(target.querySelector("button[name='4']")); assert.containsOnce(document.body, ".modal", "should open a warning dialog"); @@ -639,9 +639,9 @@ QUnit.module("SettingsFormView", (hooks) => { await click(target.querySelector(".o_form_button_save")); // Form Save button assert.containsNone(document.body, ".modal", "should not open a warning dialog"); - assert.notOk(target.querySelector(".custom-control input").disabled); // Everything must stay in edit + assert.notOk(target.querySelector(".o_field_boolean input").disabled); // Everything must stay in edit - await click(target.querySelector(".custom-control input")); + await click(target.querySelector(".o_field_boolean input")); await click(target.querySelector(".o_form_button_cancel")); // Form Discard button assert.containsNone(document.body, ".modal", "should not open a warning dialog"); } @@ -703,7 +703,7 @@ QUnit.module("SettingsFormView", (hooks) => { "checkbox should not be checked" ); - await click(target.querySelector(".custom-control input")); + await click(target.querySelector(".o_field_boolean input")); assert.containsOnce( target, ".o_field_boolean input:checked", @@ -795,7 +795,7 @@ QUnit.module("SettingsFormView", (hooks) => { "checkbox should not be checked" ); assert.containsNone(target, ".o_dirty_warning", "warning message should not be shown"); - await click(target.querySelector(".custom-control input[id=bar]")); + await click(target.querySelector(".o_field_boolean input[id=bar]")); assert.containsOnce(target, ".o_field_boolean input:checked", "checkbox should be checked"); assert.containsOnce(target, ".o_dirty_warning", "warning message should be shown"); }); @@ -1008,7 +1008,7 @@ QUnit.module("SettingsFormView", (hooks) => { "checkbox should not be checked" ); - await click(target.querySelector(".custom-control input")); + await click(target.querySelector(".o_field_boolean input")); assert.containsOnce( target, ".o_field_boolean input:checked", @@ -1085,7 +1085,7 @@ QUnit.module("SettingsFormView", (hooks) => { "checkbox should not be checked" ); - await click(target.querySelector(".custom-control input")); + await click(target.querySelector(".o_field_boolean input")); assert.containsOnce(target, ".o_field_boolean input:checked", "checkbox should be checked"); await click(target.querySelector(".o_form_button_cancel"));