Files
odoo_source/addons/website/static/src/js/website.contentMenu.js
T
qsm-odoo f0620a9648 [FIX] web_editor,website: allow creating pages from edit menu
The code for page creation from menu edition dialog was there but
invisible to the user because of a wrong qweb template inheritance.
Indeed, the edit menu dialog relies on an extension of the link dialog
template. But this one is extended in-place in another location and
that extension is not considered when the second extension is made
because a t-extend always use the base template. The only solution to
achieve the same result is to copy the edit menu dialog qweb extension
in Javascript.

Note: the feature was still available from the link dialog in page
edition though because this was not concerned by the wrong qweb
extension.

However, adding a page by this way would create multiple pages because
one was created each time a page name was entered (and not only on
save !). So typing "test", then changing its mind and typing "hello",
then rechanging to "test", then hitting the save button created the
"test, "test-1", "test-2" and "hello" pages.
This fix takes advantage of an already present parameter which can
determine if a new page should be created or not. However, a code
refactoring should be done in master for these classes.
2016-07-20 15:59:53 +02:00

351 lines
12 KiB
JavaScript

odoo.define('website.contentMenu', function (require) {
"use strict";
var core = require('web.core');
var ajax = require('web.ajax');
var Widget = require('web.Widget');
var base = require('web_editor.base');
var editor = require('web_editor.editor');
var widget = require('web_editor.widget');
var website = require('website.website');
var _t = core._t;
var qweb = core.qweb;
ajax.loadXML('/website/static/src/xml/website.contentMenu.xml', qweb);
var TopBarContent = Widget.extend({
start: function() {
var self = this;
self.$el.on('click', 'a[data-action]', function(ev) {
ev.preventDefault();
var $content_item = $(this);
self[$content_item.data('action')]();
});
return this._super();
},
edit_menu: function() {
var self = this;
var context = base.get_context();
var def = $.Deferred();
if ($("[data-content_menu_id]").length) {
var select = new SelectEditMenuDialog();
select.appendTo(document.body);
select.on('save', this, function (root) {
def.resolve(root);
});
} else {
def.resolve(null);
}
def.then(function (root_id) {
ajax.jsonRpc('/web/dataset/call_kw', 'call', {
model: 'website.menu',
method: 'get_tree',
args: [context.website_id, root_id],
kwargs: {
context: context
},
}).then(function (menu) {
var result = new EditMenuDialog(menu).appendTo(document.body);
return result;
});
});
},
new_page: function() {
website.prompt({
id: "editor_new_page",
window_title: _t("New Page"),
input: _t("Page Title"),
init: function () {
var $group = this.$dialog.find("div.form-group");
$group.removeClass("mb0");
var $add = $(
'<div class="form-group mb0">'+
'<label class="col-sm-offset-3 col-sm-9 text-left">'+
' <input type="checkbox" checked="checked" required="required"/> '+
'</label>'+
'</div>');
$add.find('label').append(_t("Add page in menu"));
$group.after($add);
}
}).then(function (val, field, $dialog) {
if (val) {
var url = '/website/add/' + encodeURIComponent(val);
if ($dialog.find('input[type="checkbox"]').is(':checked')) url +="?add_menu=1";
document.location = url;
}
});
},
rename_page: function() {
var self = this;
var context = base.get_context();
self.mo_id = self.getMainObject().id;
ajax.jsonRpc('/web/dataset/call_kw', 'call', {
model: 'website',
method: 'page_search_dependencies',
args: [self.mo_id],
kwargs: {
context: context
},
}).then(function (deps) {
website.prompt({
id: "editor_rename_page",
window_title: _t("Rename Page"),
dependencies: deps,
}, 'website.rename_page').then(function (val, field, $dialog) {
ajax.jsonRpc('/web/dataset/call_kw', 'call', {
model: 'website',
method: 'rename_page',
args: [
self.mo_id,
val,
],
kwargs: {
context: context
},
}).then(function (new_name) {
window.location = "/page/" + encodeURIComponent(new_name);
});
});
});
},
delete_page: function() {
var self = this;
var context = base.get_context();
self.mo_id = self.getMainObject().id;
ajax.jsonRpc('/web/dataset/call_kw', 'call', {
model: 'website',
method: 'page_search_dependencies',
args: [self.mo_id],
kwargs: {
context: context
},
}).then(function (deps) {
website.prompt({
id: "editor_delete_page",
window_title: _t("Delete Page"),
dependencies: deps,
init: function() { $('.btn-continue').prop("disabled", true)},
}, 'website.delete_page').then(function (val, field, $dialog) {
if ($dialog.find('input[type="checkbox"]').is(':checked')){
ajax.jsonRpc('/web/dataset/call_kw', 'call', {
model: 'website',
method: 'delete_page',
args: [self.mo_id],
kwargs: {
context: context
},
}).then(function () {
window.location = "/";
});
}
});
});
},
getMainObject: function () {
var repr = $('html').data('main-object');
var m = repr.match(/(.+)\((\d+),(.*)\)/);
if (!m) {
return null;
} else {
return {
model: m[1],
id: m[2]|0
};
}
}
});
website.TopBar.include({
start: function () {
this.content_menu = new TopBarContent();
var def = this.content_menu.attachTo($('.oe_content_menu'));
return $.when(this._super(), def);
}
});
var SelectEditMenuDialog = widget.Dialog.extend({
template: 'website.contentMenu.dialog.select',
init: function () {
var self = this;
self.roots = [{id: null, name: _t("Top Menu")}];
$("[data-content_menu_id]").each(function () {
self.roots.push({id: $(this).data("content_menu_id"), name: $(this).attr("name")});
});
this._super();
},
save: function () {
this.trigger("save", parseInt(this.$el.find("select").val() || null));
this._super();
}
});
var EditMenuDialog = widget.Dialog.extend({
template: 'website.contentMenu.dialog.edit',
events: _.extend({}, widget.Dialog.prototype.events, {
'click a.js_add_menu': 'add_menu',
'click button.js_edit_menu': 'edit_menu',
'click button.js_delete_menu': 'delete_menu',
}),
init: function (menu) {
this.menu = menu;
this.root_menu_id = menu.id;
this.flat = this.flatenize(menu);
this.to_delete = [];
this._super();
},
start: function () {
var r = this._super.apply(this, arguments);
this.$('.oe_menu_editor').nestedSortable({
listType: 'ul',
handle: 'div',
items: 'li',
maxLevels: 2,
toleranceElement: '> div',
forcePlaceholderSize: true,
opacity: 0.6,
placeholder: 'oe_menu_placeholder',
tolerance: 'pointer',
attribute: 'data-menu-id',
expression: '()(.+)', // nestedSortable takes the second match of an expression (*sigh*)
});
return r;
},
flatenize: function (node, dict) {
dict = dict || {};
var self = this;
dict[node.id] = node;
node.children.forEach(function (child) {
self.flatenize(child, dict);
});
return dict;
},
add_menu: function () {
var self = this;
var dialog = new MenuEntryDialog(undefined, {});
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: [],
};
self.flat[new_menu.id] = new_menu;
self.$('.oe_menu_editor').append(
qweb.render('website.contentMenu.dialog.submenu', { submenu: new_menu }));
});
dialog.appendTo(document.body);
},
edit_menu: function (ev) {
var self = this;
var menu_id = $(ev.currentTarget).closest('[data-menu-id]').data('menu-id');
var menu = self.flat[menu_id];
if (menu) {
var dialog = new MenuEntryDialog(undefined, menu);
dialog.on('save', this, function (link) {
var id = link.id;
var menu_obj = self.flat[id];
_.extend(menu_obj, {
'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);
});
dialog.appendTo(document.body);
} else {
alert("Could not find menu entry");
}
},
delete_menu: function (ev) {
var self = this;
var $menu = $(ev.currentTarget).closest('[data-menu-id]');
var mid = $menu.data('menu-id')|0;
if (mid) {
this.to_delete.push(mid);
}
$menu.remove();
},
save: function () {
var self = this;
var new_menu = this.$('.oe_menu_editor').nestedSortable('toArray', {startDepthCount: 0});
var levels = [];
var data = [];
var context = base.get_context();
// Resequence, re-tree and remove useless data
new_menu.forEach(function (menu) {
if (menu.item_id) {
levels[menu.depth] = (levels[menu.depth] || 0) + 1;
var mobj = self.flat[menu.item_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);
}
});
ajax.jsonRpc('/web/dataset/call_kw', 'call', {
model: 'website.menu',
method: 'save',
args: [[context.website_id], { data: data, to_delete: self.to_delete }],
kwargs: {
context: context
},
}).then(function (menu) {
self.close();
editor.reload();
});
},
});
var MenuEntryDialog = widget.LinkDialog.extend({
init: function (editor, data) {
data.text = data.name || '';
data.isNewWindow = data.new_window;
this.data = data;
return this._super.apply(this, arguments);
},
start: function () {
var self = this;
this.$(".link-style").remove();
this.$("label[for=link-new]").text("Menu Label");
return $.when(this._super.apply(this, arguments)).then(function () {
var $link_text = self.$('#link-text').focus();
self.$('#link-page').change(function (e) {
if ($link_text.val()) { return; }
var data = $(this).select2('data');
$link_text.val(data.create ? data.id : data.text);
$link_text.focus();
});
});
},
save: function () {
var $e = this.$('#link-text');
if (!$e.val() || !$e[0].checkValidity()) {
$e.closest('.form-group').addClass('has-error');
$e.focus();
return;
}
return this._super.apply(this, arguments);
},
destroy: function () {
this._super.apply(this, arguments);
},
});
return {
'TopBar': TopBarContent,
};
});