odoo.define('website.customizeMenu', function (require) {
'use strict';
var core = require('web.core');
var Widget = require('web.Widget');
var websiteNavbarData = require('website.navbar');
var WebsiteAceEditor = require('website.ace');
var qweb = core.qweb;
var CustomizeMenu = Widget.extend({
xmlDependencies: ['/website/static/src/xml/website.editor.xml'],
events: {
'show.bs.dropdown': '_onDropdownShow',
'click .dropdown-item[data-view-key]': '_onCustomizeOptionClick',
},
/**
* @override
*/
willStart: function () {
this.viewName = $(document.documentElement).data('view-xmlid');
return this._super.apply(this, arguments);
},
/**
* @override
*/
start: function () {
if (!this.viewName) {
_.defer(this.destroy.bind(this));
}
if (this.$el.is('.show')) {
this._loadCustomizeOptions();
}
return this._super.apply(this, arguments);
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* Enables/Disables a view customization whose id is given.
*
* @private
* @param {string} viewKey
* @returns {Promise}
* Unresolved if the customization succeeded as the page will be
* reloaded.
* Rejected otherwise.
*/
_doCustomize: function (viewKey) {
return this._rpc({
route: '/website/toggle_switchable_view',
params: {
'view_key': viewKey,
},
}).then(function () {
window.location.reload();
return new Promise(function () {});
});
},
/**
* Loads the information about the views which can be enabled/disabled on
* the current page and shows them as switchable elements in the menu.
*
* @private
* @return {Promise}
*/
_loadCustomizeOptions: function () {
if (this.__customizeOptionsLoaded) {
return Promise.resolve();
}
this.__customizeOptionsLoaded = true;
var $menu = this.$el.children('.dropdown-menu');
return this._rpc({
route: '/website/get_switchable_related_views',
params: {
key: this.viewName,
},
}).then(function (result) {
var currentGroup = '';
if (result.length) {
$menu.append($('
', {
class: 'dropdown-divider',
role: 'separator',
}));
}
_.each(result, function (item) {
if (currentGroup !== item.inherit_id[1]) {
currentGroup = item.inherit_id[1];
$menu.append('');
}
var $a = $('', {href: '#', class: 'dropdown-item', 'data-view-key': item.key, role: 'menuitem'})
.append(qweb.render('website.components.switch', {id: 'switch-' + item.id, label: item.name}));
$a.find('input').prop('checked', !!item.active);
$menu.append($a);
});
});
},
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* Called when a view's related switchable element is clicked -> enable /
* disable the related view.
*
* @private
* @param {Event} ev
*/
_onCustomizeOptionClick: function (ev) {
ev.preventDefault();
var viewKey = $(ev.currentTarget).data('viewKey');
this._doCustomize(viewKey);
},
/**
* @private
*/
_onDropdownShow: function () {
this._loadCustomizeOptions();
},
});
var AceEditorMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({
actions: _.extend({}, websiteNavbarData.WebsiteNavbarActionWidget.prototype.actions || {}, {
close_all_widgets: '_hideEditor',
edit: '_enterEditMode',
ace: '_launchAce',
}),
/**
* Launches the ace editor automatically when the corresponding hash is in
* the page URL.
*
* @override
*/
start: function () {
if (window.location.hash.substr(0, WebsiteAceEditor.prototype.hash.length) === WebsiteAceEditor.prototype.hash) {
this._launchAce();
}
return this._super.apply(this, arguments);
},
//--------------------------------------------------------------------------
// Actions
//--------------------------------------------------------------------------
/**
* When handling the "edit" website action, the ace editor has to be closed.
*
* @private
*/
_enterEditMode: function () {
this._hideEditor();
},
/**
* @private
*/
_hideEditor: function () {
if (this.globalEditor) {
this.globalEditor.do_hide();
}
},
/**
* Launches the ace editor to be able to edit the templates and scss files
* which are used by the current page.
*
* @private
* @returns {Promise}
*/
_launchAce: function () {
var self = this;
var prom = new Promise(function (resolve, reject) {
self.trigger_up('action_demand', {
actionName: 'close_all_widgets',
onSuccess: resolve,
});
});
prom.then(function () {
if (self.globalEditor) {
self.globalEditor.do_show();
return Promise.resolve();
} else {
var currentHash = window.location.hash;
var indexOfView = currentHash.indexOf("?res=");
var initialResID = undefined;
if (indexOfView >= 0) {
initialResID = currentHash.substr(indexOfView + ("?res=".length));
var parsedResID = parseInt(initialResID, 10);
if (parsedResID) {
initialResID = parsedResID;
}
}
self.globalEditor = new WebsiteAceEditor(self, $(document.documentElement).data('view-xmlid'), {
initialResID: initialResID,
defaultBundlesRestriction: [
'web.assets_frontend',
'web.assets_frontend_minimal',
'web.assets_frontend_lazy',
],
});
return self.globalEditor.appendTo(document.body);
}
});
return prom;
},
});
websiteNavbarData.websiteNavbarRegistry.add(CustomizeMenu, '#customize-menu');
websiteNavbarData.websiteNavbarRegistry.add(AceEditorMenu, '#html_editor');
return CustomizeMenu;
});