[FIX] web,purchase: no content helper position in modal on small screen

This commit fixes an issue where the "No records found" helper text is
wrongly positioned below the sample data's records (i.e. not visible)
instead of over them.

This is basically a revert of 9407383a56
due to the changes in the DOM and styling made in the meantime.

But actually we can go further and ensure we always have the ListView's
table present in the DOM. This change allows to simplify the positioning
of the helper and the implementation of the Purchase's dashboard.

Steps to reproduce:
- create a new database **without demo data**
- install "Planning" and "Sales" apps
- with a mobile-like screen size, open Planning
- switch to Gantt view
- in a cell, click/tap on the magnifier button (which is on hover...)
- the many2x view doesn't contain data
=> action helper "No records found" isn"t visible (scroll to bottom to
find it)

closes odoo/odoo#112878

X-original-commit: 766498a36b322ffe9c647616f56f3ba04cc51d96
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Signed-off-by: Pierre Paridans (app) <app@odoo.com>
This commit is contained in:
Pierre Paridans
2023-02-16 17:57:00 +01:00
parent 8780f0db25
commit 6f700b2973
8 changed files with 21 additions and 61 deletions
-1
View File
@@ -40,7 +40,6 @@
'web.assets_backend': [
'purchase/static/src/toaster_button/*',
'purchase/static/src/views/*.js',
'purchase/static/src/views/*.scss',
'purchase/static/src/js/tours/purchase.js',
'purchase/static/src/**/*.xml',
],
@@ -1,3 +0,0 @@
.o_rfq_no_content {
position: relative;
}
@@ -1,21 +1,7 @@
<templates>
<t t-name="purchase.RfqNoContent" t-inherit="web.ActionHelper" t-inherit-mode="primary" owl="1">
<xpath expr="//div[hasclass('o_view_nocontent')]" position="attributes">
<attribute name="class" add="o_rfq_no_content" separator=" "/>
</xpath>
</t>
<t t-name="purchase.PurchaseListView" t-inherit="web.ListRenderer" t-inherit-mode="primary" owl="1">
<xpath expr="//t[@t-call='web.ActionHelper']" position="replace">
<xpath expr="//div[hasclass('o_list_renderer')]" position="before">
<PurchaseDashBoard />
<t t-if="showNoContentHelper">
<t t-if="!showTable" t-call="purchase.RfqNoContent">
<t t-set="noContentHelp" t-value="props.noContentHelp"/>
</t>
<t t-else="" t-call="web.ActionHelper">
<t t-set="noContentHelp" t-value="props.noContentHelp"/>
</t>
</t>
</xpath>
</t>
</templates>
@@ -36,10 +36,6 @@
}
}
> :not(.o_legacy_view_sample_data) .o_view_nocontent {
position: unset;
}
.o_modal_changes td {
&:first-child {
padding-right: 10px;
@@ -140,7 +140,7 @@ export class ListRenderer extends Component {
if (this.env.searchModel) {
useBus(this.env.searchModel, "focus-view", () => {
if (this.props.list.model.useSampleModel || !this.showTable) {
if (this.props.list.model.useSampleModel) {
return;
}
@@ -180,7 +180,7 @@ export class ListRenderer extends Component {
() => {
this.freezeColumnWidths();
},
() => [this.state.columns, this.isEmpty, this.showTable]
() => [this.state.columns, this.isEmpty]
);
useExternalListener(window, "resize", () => {
this.columnWidths = null;
@@ -224,9 +224,6 @@ export class ListRenderer extends Component {
// The following code manipulates the DOM directly to avoid having to wait for a
// render + patch which would occur on the next frame and cause flickering.
freezeColumnWidths() {
if (!this.showTable) {
return;
}
if (!this.keepColumnWidths) {
this.columnWidths = null;
}
@@ -1586,11 +1583,6 @@ export class ListRenderer extends Component {
return !group.isFolded && group.list.limit < group.list.count;
}
get showTable() {
const { model } = this.props.list;
return model.hasData() || !this.props.noContentHelp;
}
toggleGroup(group) {
group.toggle();
}
@@ -3,8 +3,7 @@
<t t-name="web.ListRenderer" owl="1">
<div
class="o_list_renderer o_renderer"
t-att-class="{'table-responsive': showTable}"
class="o_list_renderer o_renderer table-responsive"
t-attf-class="{{ props.archInfo.className or '' }}"
tabindex="-1"
t-ref="root"
@@ -12,7 +11,7 @@
<t t-if="showNoContentHelper" t-call="web.ActionHelper">
<t t-set="noContentHelp" t-value="props.noContentHelp"/>
</t>
<table t-if="showTable" t-attf-class="o_list_table table table-sm table-hover position-relative mb-0 {{props.list.isGrouped ? 'o_list_table_grouped' : 'o_list_table_ungrouped table-striped'}}" t-ref="table">
<table t-attf-class="o_list_table table table-sm table-hover position-relative mb-0 {{props.list.isGrouped ? 'o_list_table_grouped' : 'o_list_table_ungrouped table-striped'}}" t-ref="table">
<thead>
<tr>
<th t-if="hasSelectors" class="o_list_record_selector o_list_controller align-middle pe-1 cursor-pointer" tabindex="-1" t-on-keydown.synthetic="(ev) => this.onCellKeydown(ev)" t-on-click.stop="toggleSelection">
@@ -4257,32 +4257,26 @@ QUnit.module("Views", (hooks) => {
noContentHelp: '<p class="hello">click to add a foo</p>',
});
// as help is being provided in the action, table won't be rendered until a record exists
assert.containsNone(
target,
".o_list_table",
" there should not be any records in the view."
);
assert.containsOnce(target, ".o_view_nocontent", "should have no content help");
// click on create button
await click(target.querySelector(".o_list_button_add"));
const handleWidgetMinWidth = "33px";
const handleWidgetWidth = "33px";
const handleWidgetHeader = target.querySelector("thead > tr > th.o_handle_cell");
assert.strictEqual(
window.getComputedStyle(handleWidgetHeader).minWidth,
handleWidgetMinWidth,
"While creating first record, min-width should be applied to handle widget."
window.getComputedStyle(handleWidgetHeader).width,
handleWidgetWidth,
"While creating first record, width should be applied to handle widget."
);
// creating one record
await editInput(target, ".o_selected_row [name='foo'] input", "test_foo");
await clickSave(target);
assert.strictEqual(
window.getComputedStyle(handleWidgetHeader).minWidth,
handleWidgetMinWidth,
"After creation of the first record, min-width of the handle widget should remain as it is"
window.getComputedStyle(handleWidgetHeader).width,
handleWidgetWidth,
"After creation of the first record, width of the handle widget should remain as it is"
);
}
);
@@ -6581,7 +6575,7 @@ QUnit.module("Views", (hooks) => {
noContentHelp: "click to add a partner",
});
assert.containsOnce(target, ".o_view_nocontent", "should display the no content helper");
assert.containsNone(target, ".o_list_view table", "should not have a table in the dom");
assert.containsOnce(target, ".o_list_view table", "should have a table in the dom");
assert.deepEqual(
[...target.querySelectorAll(".o_view_nocontent")].map((el) => el.textContent),
["click to add a partner"]
@@ -6595,7 +6589,6 @@ QUnit.module("Views", (hooks) => {
".o_view_nocontent",
"should not display the no content helper"
);
assert.containsOnce(target, ".o_list_view table", "should have a table in the dom");
});
QUnit.test("no nocontent helper when no data and no help", async function (assert) {
@@ -6678,7 +6671,7 @@ QUnit.module("Views", (hooks) => {
target.querySelector(".o_list_view .o_content"),
"o_view_sample_data"
);
assert.containsNone(target, ".o_list_table");
assert.containsOnce(target, ".o_list_table");
assert.containsOnce(target, ".o_nocontent_help");
await toggleMenuItem(target, "False Domain");
@@ -6923,7 +6916,7 @@ QUnit.module("Views", (hooks) => {
target.querySelector(".o_list_view .o_content"),
"o_view_sample_data"
);
assert.containsNone(target, ".o_list_table");
assert.containsOnce(target, ".o_list_table");
assert.containsOnce(target, ".o_nocontent_help");
}
);
@@ -6967,7 +6960,7 @@ QUnit.module("Views", (hooks) => {
target.querySelector(".o_list_view .o_content"),
"o_view_sample_data"
);
assert.containsNone(target, ".o_list_table");
assert.containsOnce(target, ".o_list_table");
assert.containsOnce(target, ".o_nocontent_help");
}
);
@@ -7025,7 +7018,7 @@ QUnit.module("Views", (hooks) => {
target.querySelector(".o_list_view .o_content"),
"o_view_sample_data"
);
assert.containsNone(target, ".o_list_table");
assert.containsOnce(target, ".o_list_table");
assert.containsOnce(target, ".o_nocontent_help");
}
);
@@ -7340,12 +7333,12 @@ QUnit.module("Views", (hooks) => {
".o_view_nocontent",
"should have a no content helper displayed"
);
assert.containsNone(
assert.containsOnce(
target,
"div.table-responsive",
"should not have a div.table-responsive"
"should have a div.table-responsive"
);
assert.containsNone(target, "table", "should not have rendered a table");
assert.containsOnce(target, "table", "should have rendered a table");
await click(target.querySelector(".o_list_button_add"));
assert.containsNone(
@@ -7353,7 +7346,6 @@ QUnit.module("Views", (hooks) => {
".o_view_nocontent",
"should not have a no content helper displayed"
);
assert.containsOnce(target, "table", "should have rendered a table");
assert.hasClass(
target.querySelector("tbody tr"),
"o_selected_row",
@@ -2501,12 +2501,11 @@ QUnit.module("ActionManager", (hooks) => {
assert.containsOnce(target, ".o_list_view");
assert.containsOnce(target, ".o_view_nocontent");
assert.strictEqual(target.querySelector(".o_view_nocontent").innerText, "Hello");
assert.containsNone(target, "table");
assert.containsOnce(target, "table");
await doAction(webClient, 4);
assert.containsOnce(target, ".o_list_view");
assert.containsNone(target, ".o_view_nocontent");
assert.containsOnce(target, "table");
});
QUnit.test("process context.form_view_initial_mode", async function (assert) {