From 0b6078dfea9cd60f7273e431fe52dd8ff4863607 Mon Sep 17 00:00:00 2001
From: Christophe Simonis <chs@odoo.com>
Date: Tue, 21 Oct 2014 12:48:19 +0200
Subject: [PATCH] [IMP] base: apps integration

---
 addons/web/static/src/css/base.css        |   4 +
 addons/web/static/src/css/base.sass       |   3 +
 openerp/addons/base/module/module.py      |   4 +-
 openerp/addons/base/static/src/js/apps.js | 176 +++++++++++++++-------
 4 files changed, 134 insertions(+), 53 deletions(-)

diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index d448bb38188e..236b038bab83 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -41,6 +41,10 @@
   margin-right: 0px !important;
 }
 
+.apps-client {
+  border: 0;
+}
+
 .oe_notification {
   z-index: 1600;
 }
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index b8132d68d9ca..7343d1e04066 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -161,6 +161,9 @@ $sheet-padding: 16px
 .oe_systray
     margin-right: 0px !important
 
+.apps-client
+    border: 0
+
 // Notifications {{{
 .oe_notification
     z-index: 1600
diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py
index b327871c953a..0da95a765978 100644
--- a/openerp/addons/base/module/module.py
+++ b/openerp/addons/base/module/module.py
@@ -2,7 +2,7 @@
 ##############################################################################
 #
 #    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2013 OpenERP S.A. (<http://openerp.com>).
+#    Copyright (C) 2004-2014 OpenERP S.A. (<http://openerp.com>).
 #
 #    This program is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU Affero General Public License as
@@ -664,7 +664,7 @@ class module(osv.osv):
 
         apps_server = urlparse.urlparse(self.get_apps_server(cr, uid, context=context))
 
-        OPENERP = 'openerp'
+        OPENERP = openerp.release.product_name.lower()
         tmp = tempfile.mkdtemp()
         _logger.debug('Install from url: %r', urls)
         try:
diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js
index b88585e26d57..1b4afc6e59ac 100644
--- a/openerp/addons/base/static/src/js/apps.js
+++ b/openerp/addons/base/static/src/js/apps.js
@@ -1,27 +1,18 @@
 openerp.base = function(instance) {
 
-    instance.base.apps_remote = null;
     instance.base.apps_client = null;
-    
+
     var _t = instance.web._t;
 
     instance.base.Apps = instance.web.Widget.extend({
         template: 'EmptyComponent',
-        remote_action_id: 'loempia.action_embed',
+        remote_action_tag: 'loempia.embed',
         failback_action_id: 'base.open_module_tree',
 
         init: function(parent, action) {
             this._super(parent, action);
             var options = action.params || {};
-
-            if (options.apps_user) {
-                sessionStorage.setItem('apps.login', options.apps_user);
-            }
-            if (options.apps_access_token) {
-                sessionStorage.setItem('apps.access_token', options.apps_access_token);
-            }
-
-            this.params = options; // NOTE read by embedded client action
+            this.params = options;  // NOTE forwarded to embedded client action
         },
 
         get_client: function() {
@@ -33,28 +24,7 @@ openerp.base = function(instance) {
                     d.reject(client);
                 };
                 i.onload = function() {
-                    client.session.session_bind(client.origin).then(function() {
-                        // check if client can authenticate
-                        client.authenticate().then(
-                           function() {     /* done */
-                            d.resolve(client);
-                        }, function() {     /* fail */
-                            if (client.login === 'anonymous') {
-                                d.reject(client);
-                            } else {
-                                sessionStorage.removeItem('apps.login');
-                                sessionStorage.removeItem('apps.access_token');
-                                client.bind_credentials(client.dbname, 'anonymous', 'anonymous');
-                                client.authenticate().then(
-                                   function() {     /* done */
-                                    d.resolve(client);
-                                }, function() {     /* fail */
-                                    d.reject(client);
-                                });
-                            }
-                        });
-                    });
-
+                    d.resolve(client);
                 };
                 var ts = new Date().getTime();
                 i.src = _.str.sprintf('%s/web/static/src/img/sep-a.gif?%s', client.origin, ts);
@@ -71,12 +41,10 @@ openerp.base = function(instance) {
                     if (dbname[0] === '/') {
                         dbname = dbname.substr(1);
                     }
-                    var login = (sessionStorage ? sessionStorage.getItem('apps.login') : null) || 'anonymous';
-                    var passwd = (sessionStorage ? sessionStorage.getItem('apps.access_token') : null) || 'anonymous';
-                    if (_.isNull(instance.base.apps_remote)) {
-                        instance.base.apps_remote = new openerp.init();
-                    }
-                    var client = new instance.base.apps_remote.web.EmbeddedClient(null, host, dbname, login, passwd);
+                    var client = {
+                        origin: host,
+                        dbname: dbname
+                    };
                     instance.base.apps_client = client;
                     return check_client_available(client);
                 });
@@ -84,35 +52,141 @@ openerp.base = function(instance) {
         },
 
         destroy: function() {
-            if (instance.base.apps_client) {
-                instance.base.apps_client.destroy();
+            $(window).off("message.apps");
+            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) {
+                    self.session.rpc.apply(self.session, m.args).then(function(r) {
+                        var w = self.$ifr[0].contentWindow;
+                        w.postMessage({id: m.id, result: r}, client.origin);
+                    });
+                },
+                'Model': function(m) {
+                    var M = new instance.web.Model(m.model);
+                    M[m.method].apply(M, m.args).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;
-            // desactivated for now because apps does not work anyway due to changes in the framework
-            /*return self.get_client().
+            return self.get_client().
                 done(function(client) {
-                    client.replace(self.$el).
-                        done(function() {
-                            client.$el.removeClass('openerp');
-                            client.do_action(self.remote_action_id, {hide_breadcrumb: true});
+                    self.client = client;
+
+                    var qs = (instance.session.debug ? 'debug&' : '') + 'db=' + client.dbname;
+                    var u = client.origin + '/apps/embed/client?' + qs;
+                    var css = {width: '100%', height: '400px'};
+                    self.$ifr = $('<iframe>').attr('src', u);
+
+                    $(window).on("message.apps", 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: this.session.db,
+                                origin: this.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:update_count', self, function(m) {
+                        var count = m.count
+                        var get_upd_menu_id = function() {
+                            if (_.isUndefined(self._upd_menu_id)) {
+                                var IMD = new instance.web.Model('ir.model.data');
+                                return IMD.call('get_object_reference', ['base', 'menu_module_updates']).then(function(r) {
+                                    var mid = r[1];
+                                    if(r[0] !== 'ir.ui.menu') {
+                                        // invalid reference, return null
+                                        mid = null;
+                                    }
+                                    self._upd_menu_id = mid;
+                                    return mid;
+                                });
+                            } else {
+                                return $.Deferred().resolve(self._upd_menu_id).promise();
+                            }
+                        };
+
+                        $.when(get_upd_menu_id()).done(function(menu_id) {
+                            if (_.isNull(menu_id)) {
+                                return;
+                            }
+                            var $menu = instance.webclient.menu.$secondary_menus.find(_.str.sprintf('a[data-menu=%s]', menu_id));
+                            if ($menu.length === 0) {
+                                return;
+                            }
+                            if (_.isUndefined(count)) {
+                                count = 0;
+                            }
+                            var needupdate = $menu.find('#menu_counter');
+                            if (needupdate && needupdate.length !== 0) {
+                                if (count > 0) {
+                                    needupdate.text(count);
+                                } else {
+                                    needupdate.remove();
+                                }
+                            } else if (count > 0) {
+                                $menu.append(instance.web.qweb.render("Menu.needaction_counter", {widget: {needaction_counter: count}}));
+                            }
                         });
+                    });
+
+                    self.on('message:blockUI', self, function() { instance.web.blockUI(); });
+                    self.on('message:unblockUI', self, function() { instance.web.unblockUI(); });
+                    self.on('message:warn', self, function(m) {instance.webclient.do_warn(m.title, m.message, m.sticky); });
+
+                    self.$ifr.appendTo(self.$el).css(css).addClass('apps-client');
                 }).
-                fail(function(client) {*/
+                fail(function(client) {
                     self.do_warn(_t('Odoo Apps will be available soon'), _t('Showing locally available modules'), true);
                     self.rpc('/web/action/load', {action_id: self.failback_action_id}).done(function(action) {
                         self.do_action(action);
                         instance.webclient.menu.open_action(action.id);
                     });
-                //});
+                });
         },
     });
 
     instance.base.AppsUpdates = instance.base.Apps.extend({
-        remote_action_id: 'loempia.action_embed_updates'
+        remote_action_tag: 'loempia.embed.updates',
     });
 
     instance.web.client_actions.add("apps", "instance.base.Apps");
-- 
GitLab