[IMP] spreadsheet: improve wrong linked menu handling

If a chart was linked to an odoo menu, but the odoo menu didn't have
an action, the user would get a traceback when clicking on the chart.

This commit:
- Improves dashboard validation. Now we test that the menu is linked
to an action, in addition to testing that the menu exists
- Send a "danger" notification when the user clicks on a chart with
a menu without an action linked to it, rather than a traceback

closes odoo/odoo#139324

Task: 3563450
Signed-off-by: Rémi Rahir (rar) <rar@odoo.com>
This commit is contained in:
Adrien Minne (adrm)
2023-10-25 11:37:33 +00:00
parent b3ffdf02bb
commit 61d54527fc
3 changed files with 62 additions and 2 deletions
@@ -3,18 +3,29 @@
import { patch } from "@web/core/utils/patch";
import * as spreadsheet from "@odoo/o-spreadsheet";
import { useService } from "@web/core/utils/hooks";
import { _t } from "@web/core/l10n/translation";
patch(spreadsheet.components.FigureComponent.prototype, {
setup() {
super.setup();
this.menuService = useService("menu");
this.actionService = useService("action");
this.notificationService = useService("notification");
},
async navigateToOdooMenu() {
const menu = this.env.model.getters.getChartOdooMenu(this.props.figure.id);
if (!menu) {
throw new Error(`Cannot find any menu associated with the chart`);
}
if (!menu.actionID) {
this.notificationService.add(
_t(
"The menu linked to this chart doesn't have an corresponding action. Please link the chart to another menu."
),
{ type: "danger" }
);
return;
}
await this.actionService.doAction(menu.actionID);
},
get hasOdooMenu() {
@@ -9,6 +9,7 @@ import { menuService } from "@web/webclient/menus/menu_service";
import { actionService } from "@web/webclient/actions/action_service";
import { mountSpreadsheet } from "@spreadsheet/../tests/utils/ui";
import { createModelWithDataSource } from "@spreadsheet/../tests/utils/model";
import { makeFakeNotificationService } from "@web/../tests/helpers/mock_services";
const chartId = "uuid1";
@@ -80,6 +81,13 @@ QUnit.module(
appID: 1,
actionID: "menuAction2",
},
3: {
id: 3,
children: [],
name: "test menu 2",
xmlid: "documents_spreadsheet.test.menu_without_action",
appID: 1,
},
};
this.serverData.actions = {
menuAction: {
@@ -328,5 +336,41 @@ QUnit.module(
assert.verifySteps(["doAction"]);
});
QUnit.test(
"Trying to open a menu without an action sends a notification to the user",
async function (assert) {
mockActionService(assert, "doAction");
const notificationMock = (message) => {
assert.step(message);
return () => {};
};
const notificationService = makeFakeNotificationService(notificationMock);
registry.category("services").add("notification", notificationService, {
force: true,
});
const model = await createModelWithDataSource({
serverData: this.serverData,
});
const fixture = await mountSpreadsheet(model);
createBasicChart(model, chartId);
model.dispatch("LINK_ODOO_MENU_TO_CHART", {
chartId,
odooMenuId: "documents_spreadsheet.test.menu_without_action",
});
await nextTick();
await clickChartExternalLink(fixture);
const expectedNotificationMessage =
"The menu linked to this chart doesn't have an corresponding action. Please link the chart to another menu.";
assert.verifySteps(
[expectedNotificationMessage],
"Notification was send and doAction wasn't called"
);
}
);
}
);
@@ -182,7 +182,7 @@ def fields_in_spreadsheet(data):
return dict(fields_by_model)
def xml_ids_in_spreadsheet(data):
def menus_xml_ids_in_spreadsheet(data):
return set(data.get("chartOdooMenusReferences", {}).values()) | {
url[len(xml_id_url_prefix):]
@@ -212,9 +212,14 @@ class ValidateSpreadsheetData(TransactionCase):
if field.relational:
field_model = field.comodel_name
for xml_id in xml_ids_in_spreadsheet(data):
for xml_id in menus_xml_ids_in_spreadsheet(data):
record = self.env.ref(xml_id, raise_if_not_found=False)
if not record:
raise AssertionError(
f"xml id '{xml_id}' used in spreadsheet '{spreadsheet_name}' does not exist"
)
# check that the menu has an action. Root menus always have an action.
if not record.action and record.parent_id.id:
raise AssertionError(
f"menu with xml id '{xml_id}' used in spreadsheet '{spreadsheet_name}' does not have an action"
)