Files
odoo_source/addons/web/static/src/js/apps.js
T
Géry Debongnie b17ba359db [REF] web,*: introduce the concept of AbstractAction
Before this commit, a client action was simply a subclass of Widget.
This is quite simple, but not really enough for the ActionManager. The
ActionManager needs to handle client actions in a different way that
view actions. Sometimes, it needs to check if a method exists before
calling it.

With this commit, we introduce a new abstraction: the AbstractAction
class, which defines a common API for all actions managed by the web
client.

Note that the API proposed in this commit is just the beginning. We will
introduce other methods in the future, to manage the focus, or the
scroll position, for example.
2018-03-08 16:48:54 +01:00

172 lines
5.8 KiB
JavaScript

odoo.define('web.Apps', function (require) {
"use strict";
var AbstractAction = require('web.AbstractAction');
var core = require('web.core');
var framework = require('web.framework');
var session = require('web.session');
var _t = core._t;
var apps_client = null;
var Apps = AbstractAction.extend({
template: 'EmptyComponent',
remote_action_tag: 'loempia.embed',
failback_action_id: 'base.open_module_tree',
init: function(parent, action) {
this._super(parent, action);
var options = action.params || {};
this.params = options; // NOTE forwarded to embedded client action
},
get_client: function() {
// return the client via a deferred, resolved or rejected depending if
// the remote host is available or not.
var check_client_available = function(client) {
var d = $.Deferred();
var i = new Image();
i.onerror = function() {
d.reject(client);
};
i.onload = function() {
d.resolve(client);
};
var ts = new Date().getTime();
i.src = _.str.sprintf('%s/web/static/src/img/sep-a.gif?%s', client.origin, ts);
return d.promise();
};
if (apps_client) {
return check_client_available(apps_client);
} else {
return this._rpc({model: 'ir.module.module', method: 'get_apps_server'})
.then(function(u) {
var link = $(_.str.sprintf('<a href="%s"></a>', u))[0];
var host = _.str.sprintf('%s//%s', link.protocol, link.host);
var dbname = link.pathname;
if (dbname[0] === '/') {
dbname = dbname.substr(1);
}
var client = {
origin: host,
dbname: dbname
};
apps_client = client;
return check_client_available(client);
});
}
},
destroy: function() {
$(window).off("message." + this.uniq);
if (this.$ifr) {
this.$ifr.remove();
this.$ifr = null;
}
return this._super();
},
_on_message: function($e) {
var self = this, client = this.client, e = $e.originalEvent;
if (e.origin !== client.origin) {
return;
}
var dispatcher = {
'event': function(m) { self.trigger('message:' + m.event, m); },
'action': function(m) {
self.do_action(m.action).then(function(r) {
var w = self.$ifr[0].contentWindow;
w.postMessage({id: m.id, result: r}, client.origin);
});
},
'rpc': function(m) {
return self._rpc({route: m.args[0], params: m.args[1]}).then(function(r) {
var w = self.$ifr[0].contentWindow;
w.postMessage({id: m.id, result: r}, client.origin);
});
},
'Model': function(m) {
return self._rpc({model: m.model, method: m.args[0], args: m.args[1]})
.then(function(r) {
var w = self.$ifr[0].contentWindow;
w.postMessage({id: m.id, result: r}, client.origin);
});
},
};
// console.log(e.data);
if (!_.isObject(e.data)) { return; }
if (dispatcher[e.data.type]) {
dispatcher[e.data.type](e.data);
}
},
start: function() {
var self = this;
var def = $.Deferred();
self.get_client().then(function(client) {
self.client = client;
var qs = {db: client.dbname};
if (session.debug) {
qs.debug = session.debug;
}
var u = $.param.querystring(client.origin + "/apps/embed/client", qs);
var css = {width: '100%', height: '750px'};
self.$ifr = $('<iframe>').attr('src', u);
self.uniq = _.uniqueId('apps');
$(window).on("message." + self.uniq, self.proxy('_on_message'));
self.on('message:ready', self, function(m) {
var w = this.$ifr[0].contentWindow;
var act = {
type: 'ir.actions.client',
tag: this.remote_action_tag,
params: _.extend({}, this.params, {
db: session.db,
origin: session.origin,
})
};
w.postMessage({type:'action', action: act}, client.origin);
});
self.on('message:set_height', self, function(m) {
this.$ifr.height(m.height);
});
self.on('message:blockUI', self, function() { framework.blockUI(); });
self.on('message:unblockUI', self, function() { framework.unblockUI(); });
self.on('message:warn', self, function(m) {self.do_warn(m.title, m.message, m.sticky); });
self.$ifr.appendTo(self.$el).css(css).addClass('apps-client');
def.resolve();
}, function() {
self.do_warn(_t('Odoo Apps will be available soon'), _t('Showing locally available modules'), true);
return self._rpc({
route: '/web/action/load',
params: {action_id: self.failback_action_id},
}).then(function(action) {
return self.do_action(action);
}).always(function () {
def.reject();
});
});
return def;
},
});
var AppsUpdates = Apps.extend({
remote_action_tag: 'loempia.embed.updates',
});
core.action_registry.add("apps", Apps);
core.action_registry.add("apps.updates", AppsUpdates);
return Apps;
});