Skip to content
Snippets Groups Projects
Commit 3daed421 authored by qsm-odoo's avatar qsm-odoo
Browse files

[FIX] website: restore edit menu dialog


Since saas-12.5, with recent ORM changes, writing on non-existing fields
does not trigger a warning anymore but instead crashes. This revealed
that the 12.0 "Edit Menu" dialog was doing some of that. Indeed,
depending on what was edited, we ended up writing on the 'is_homepage'
field, the 'text' field, the 'isNewWindow' field, ... which do not
exist.

This commit takes advantage of the fix to also lint the dialog code and
convert some of it to ES6.

Discovered while working on task-1925319

closes odoo/odoo#36204

Signed-off-by: default avatarQuentin Smetz (qsm) <qsm@odoo.com>
parent 4e9416b4
Branches
Tags
No related merge requests found
......@@ -108,25 +108,24 @@ class Menu(models.Model):
@api.model
def get_tree(self, website_id, menu_id=None):
def make_tree(node):
page_id = node.page_id.id if node.page_id else None
is_homepage = page_id and self.env['website'].browse(website_id).homepage_id.id == page_id
menu_node = dict(
id=node.id,
name=node.name,
url=node.page_id.url if page_id else node.url,
new_window=node.new_window,
sequence=node.sequence,
parent_id=node.parent_id.id,
children=[],
is_homepage=is_homepage,
)
is_homepage = bool(node.page_id and self.env['website'].browse(website_id).homepage_id.id == node.page_id.id)
menu_node = {
'fields': {
'id': node.id,
'name': node.name,
'url': node.page_id.url if node.page_id else node.url,
'new_window': node.new_window,
'sequence': node.sequence,
'parent_id': node.parent_id.id,
},
'children': [],
'is_homepage': is_homepage,
}
for child in node.child_id:
menu_node['children'].append(make_tree(child))
return menu_node
if menu_id:
menu = self.browse(menu_id)
else:
menu = self.env['website'].browse(website_id).menu_id
menu = menu_id and self.browse(menu_id) or self.env['website'].browse(website_id).menu_id
return make_tree(menu)
@api.model
......
......@@ -369,13 +369,12 @@ var MenuEntryDialog = weWidgets.LinkDialog.extend({
* @constructor
*/
init: function (parent, options, data) {
data.text = data.name || '';
data.isNewWindow = data.new_window;
this._super(parent, _.extend({
title: _t("Add a menu item"),
}, options || {}), _.extend({
needLabel: true,
text: data.name || '',
isNewWindow: data.new_window,
}, data || {}));
},
/**
......@@ -469,7 +468,6 @@ var EditMenuDialog = weWidgets.Dialog.extend({
*/
willStart: function () {
var defs = [this._super.apply(this, arguments)];
var self = this;
var context;
this.trigger_up('context_get', {
callback: function (ctx) {
......@@ -480,11 +478,11 @@ var EditMenuDialog = weWidgets.Dialog.extend({
model: 'website.menu',
method: 'get_tree',
args: [context.website_id, this.rootID],
}).then(function (menu) {
self.menu = menu;
self.root_menu_id = menu.id;
self.flat = self._flatenize(menu);
self.to_delete = [];
}).then(menu => {
this.menu = menu;
this.rootMenuID = menu.fields['id'];
this.flat = this._flatenize(menu);
this.toDelete = [];
}));
return Promise.all(defs);
},
......@@ -518,8 +516,7 @@ var EditMenuDialog = weWidgets.Dialog.extend({
*/
save: function () {
var _super = this._super.bind(this);
var self = this;
var new_menu = this.$('.oe_menu_editor').nestedSortable('toArray', {startDepthCount: 0});
var newMenus = this.$('.oe_menu_editor').nestedSortable('toArray', {startDepthCount: 0});
var levels = [];
var data = [];
var context;
......@@ -529,20 +526,25 @@ var EditMenuDialog = weWidgets.Dialog.extend({
},
});
// Resequence, re-tree and remove useless data
new_menu.forEach(function (menu) {
newMenus.forEach(menu => {
if (menu.id) {
levels[menu.depth] = (levels[menu.depth] || 0) + 1;
var mobj = self.flat[menu.id];
mobj.sequence = levels[menu.depth];
mobj.parent_id = (menu.parent_id|0) || menu.parent_id || self.root_menu_id;
delete(mobj.children);
data.push(mobj);
var menuFields = this.flat[menu.id].fields;
menuFields['sequence'] = levels[menu.depth];
menuFields['parent_id'] = parseInt(menu['parent_id']) || this.rootMenuID;
data.push(menuFields);
}
});
this._rpc({
return this._rpc({
model: 'website.menu',
method: 'save',
args: [context.website_id, { data: data, to_delete: self.to_delete }],
args: [
context.website_id,
{
'data': data,
'to_delete': this.toDelete,
}
],
}).then(function () {
return _super();
});
......@@ -563,10 +565,9 @@ var EditMenuDialog = weWidgets.Dialog.extend({
*/
_flatenize: function (node, _dict) {
_dict = _dict || {};
var self = this;
_dict[node.id] = node;
node.children.forEach(function (child) {
self._flatenize(child, _dict);
_dict[node.fields['id']] = node;
node.children.forEach(child => {
this._flatenize(child, _dict);
});
return _dict;
},
......@@ -582,21 +583,24 @@ var EditMenuDialog = weWidgets.Dialog.extend({
* @private
*/
_onAddMenuButtonClick: function () {
var self = this;
var dialog = new MenuEntryDialog(this, {}, {});
dialog.on('save', this, function (link) {
var new_menu = {
id: _.uniqueId('new-'),
name: link.text,
url: link.url,
new_window: link.isNewWindow,
parent_id: false,
sequence: 0,
children: [],
dialog.on('save', this, link => {
var newMenu = {
'fields': {
'id': _.uniqueId('new-'),
'name': link.text,
'url': link.url,
'new_window': link.isNewWindow,
'sequence': 0,
'parent_id': false,
},
'children': [],
'is_homepage': false,
};
self.flat[new_menu.id] = new_menu;
self.$('.oe_menu_editor').append(
qweb.render('website.contentMenu.dialog.submenu', { submenu: new_menu }));
this.flat[newMenu.fields['id']] = newMenu;
this.$('.oe_menu_editor').append(
qweb.render('website.contentMenu.dialog.submenu', {submenu: newMenu})
);
});
dialog.open();
},
......@@ -607,9 +611,9 @@ var EditMenuDialog = weWidgets.Dialog.extend({
*/
_onDeleteMenuButtonClick: function (ev) {
var $menu = $(ev.currentTarget).closest('[data-menu-id]');
var menuID = $menu.data('menu-id')|0;
var menuID = parseInt($menu.data('menu-id'));
if (menuID) {
this.to_delete.push(menuID);
this.toDelete.push(menuID);
}
$menu.remove();
},
......@@ -620,21 +624,18 @@ var EditMenuDialog = weWidgets.Dialog.extend({
* @private
*/
_onEditMenuButtonClick: function (ev) {
var self = this;
var menu_id = $(ev.currentTarget).closest('[data-menu-id]').data('menu-id');
var menu = self.flat[menu_id];
var $menu = $(ev.currentTarget).closest('[data-menu-id]');
var menuID = $menu.data('menu-id');
var menu = this.flat[menuID];
if (menu) {
var dialog = new MenuEntryDialog(this, {}, menu);
dialog.on('save', this, function (link) {
var id = link.id;
var menu_obj = self.flat[id];
_.extend(menu_obj, {
var dialog = new MenuEntryDialog(this, {}, menu.fields);
dialog.on('save', this, link => {
_.extend(menu.fields, {
'name': link.text,
'url': link.url,
'new_window': link.isNewWindow,
});
var $menu = self.$('[data-menu-id="' + id + '"]');
$menu.find('.js_menu_label').first().text(menu_obj.name);
$menu.find('.js_menu_label').first().text(menu.fields['name']);
});
dialog.open();
} else {
......
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="website.contentMenu.dialog.submenu">
<li t-att-data-menu-id="submenu.id">
<li t-att-data-menu-id="submenu.fields['id']">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text fa fa-bars" role="img" aria-label="Dropdown menu" title="Dropdown menu"/>
</div>
<span class="form-control d-flex align-items-center">
<span class="js_menu_label o_text_overflow flex-grow-1">
<t t-esc="submenu.name"/>
<t t-esc="submenu.fields['name']"/>
</span>
<i t-if="submenu.is_homepage" class="fa fa-home ml-3" role="img" aria-label="Home" title="Home"/>
</span>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment