[MERGE]merge with main branch.
[odoo/odoo.git] / addons / web / static / src / js / views.js
index fcc8a4c..060d12e 100644 (file)
@@ -20,13 +20,14 @@ session.web.ActionManager = session.web.Widget.extend({
     identifier_prefix: "actionmanager",
     init: function(parent) {
         this._super(parent);
+        this.inner_action = null;
         this.inner_viewmanager = null;
         this.dialog = null;
         this.dialog_viewmanager = null;
         this.client_widget = null;
     },
     render: function() {
-        return "<div id='"+this.element_id+"'></div>";
+        return '<div id="' + this.element_id + '" style="height: 100%;"></div>';
     },
     dialog_stop: function () {
         if (this.dialog) {
@@ -46,37 +47,56 @@ session.web.ActionManager = session.web.Widget.extend({
             this.client_widget = null;
         }
     },
-
-    do_push_state: function(state, overwrite) {
+    do_push_state: function(state) {
+        if (this.widget_parent && this.widget_parent.do_push_state) {
+            if (this.inner_action) {
+                if (this.inner_action.id) {
+                    state['action_id'] = this.inner_action.id;
+                } else {
+                    state['model'] = this.inner_action.res_model;
+                }
+            }
+            this.widget_parent.do_push_state(state);
+        }
     },
-
     do_load_state: function(state) {
+        var self = this,
+            action_loaded;
         if (state.action_id) {
-            this.null_action();
-            this.do_action(state.action_id);
+            var run_action = (!this.inner_viewmanager) || this.inner_viewmanager.action.id !== state.action_id;
+            if (run_action) {
+                this.null_action();
+                action_loaded = this.do_action(state.action_id);
+            }
         }
         else if (state.model && state.id) {
-            // TODO implement it
-            //this.null_action();
-            // action = {}
+            // TODO handle context & domain ?
+            this.null_action();
+            var action = {
+                res_model: state.model,
+                res_id: state.id,
+                type: 'ir.actions.act_window',
+                views: [[false, 'page'], [false, 'form']]
+            };
+            action_loaded = this.do_action(action);
         }
         else if (state.client_action) {
             this.null_action();
             this.ir_actions_client(state.client_action);
         }
 
-        if (this.inner_viewmanager) {
-            this.inner_viewmanager.do_load_state(state);
-        }
+        $.when(action_loaded || null).then(function() {
+            if (self.inner_viewmanager) {
+                self.inner_viewmanager.do_load_state(state);
+            }
+        });
     },
-
     do_action: function(action, on_close) {
         if (_.isNumber(action)) {
             var self = this;
-            self.rpc("/web/action/load", { action_id: action }, function(result) {
+            return self.rpc("/web/action/load", { action_id: action }, function(result) {
                 self.do_action(result.result, on_close);
             });
-            return;
         }
         if (!action.type) {
             console.error("No type for action", action);
@@ -89,7 +109,8 @@ session.web.ActionManager = session.web.Widget.extend({
             search_view : !popup,
             action_buttons : !popup,
             sidebar : !popup,
-            pager : !popup
+            pager : !popup,
+            display_title : !popup
         }, action.flags || {});
         if (!(type in this)) {
             console.error("Action manager can't handle action of type " + action.type, action);
@@ -124,14 +145,15 @@ session.web.ActionManager = session.web.Widget.extend({
             this.dialog_viewmanager.appendTo(this.dialog.$element);
             this.dialog.open();
         } else  {
+            if(action.menu_id) {
+                return this.widget_parent.do_action(action, function () {
+                    session.webclient.menu.open_menu(action.menu_id);
+                });
+            }
             this.dialog_stop();
             this.content_stop();
             this.inner_action = action;
             this.inner_viewmanager = new session.web.ViewManagerAction(this, action);
-            this.inner_viewmanager.do_push_state.add(function(state,overwrite) {
-                state['action_id'] = action.id;
-                self.do_push_state(state,true);
-            });
             this.inner_viewmanager.appendTo(this.$element);
         }
     },
@@ -152,12 +174,9 @@ session.web.ActionManager = session.web.Widget.extend({
     },
     ir_actions_client: function (action) {
         this.content_stop();
+        this.dialog_stop();
         var ClientWidget = session.web.client_actions.get_object(action.tag);
         (this.client_widget = new ClientWidget(this, action.params)).appendTo(this);
-
-        var client_action = {tag: action.tag};
-        if (action.params) _.extend(client_action, {params: action.params});
-        this.do_push_state({client_action: client_action}, true);
     },
     ir_actions_report_xml: function(action, on_closed) {
         var self = this;
@@ -206,7 +225,18 @@ session.web.ViewManager =  session.web.Widget.extend(/** @lends session.web.View
         this.dataset = dataset;
         this.searchview = null;
         this.active_view = null;
-        this.views_src = _.map(views, function(x) {return x instanceof Array? {view_id: x[0], view_type: x[1]} : x;});
+        this.views_src = _.map(views, function(x) {
+            if (x instanceof Array) {
+                var View = session.web.views.get_object(x[1], true);
+                return {
+                    view_id: x[0],
+                    view_type: x[1],
+                    label: View ? View.prototype.display_name : (void 'nope')
+                };
+            } else {
+                return x;
+            }
+        });
         this.views = {};
         this.flags = flags || {};
         this.registry = session.web.views;
@@ -298,24 +328,23 @@ session.web.ViewManager =  session.web.Widget.extend(/** @lends session.web.View
             .filter('[data-view-type="' + view_type + '"]')
             .attr('disabled', true);
 
-        for (var view_name in this.views) {
-            if (!this.views.hasOwnProperty(view_name)) { continue; }
-            if (this.views[view_name].controller) {
-                if (view_name === view_type) {
-                    $.when(view_promise).then(this.views[view_name].controller.do_show);
-                } else {
-                    this.views[view_name].controller.do_hide();
-                }
-            }
-        }
         $.when(view_promise).then(function () {
+            _.each(_.keys(self.views), function(view_name) {
+                var controller = self.views[view_name].controller;
+                if (controller) {
+                    if (view_name === view_type) {
+                        controller.do_show();
+                    } else {
+                        controller.do_hide();
+                    }
+                }
+            });
+
             self.$element.find('.oe_view_title_text:first').text(
                     self.display_title());
         });
         return view_promise;
     },
-
-
     /**
      * Returns to the view preceding the caller view in this manager's
      * navigation history (the navigation history is appended to via
@@ -391,7 +420,8 @@ session.web.ViewManager =  session.web.Widget.extend(/** @lends session.web.View
     /**
      * Called by children view after executing an action
      */
-    on_action_executed: function () {},
+    on_action_executed: function () {
+    },
     display_title: function () {
         var view = this.views[this.active_view];
         if (view) {
@@ -466,12 +496,6 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
 
         var main_view_loaded = this._super();
 
-        _.each(_.keys(this.views), function(view_type) {
-            $.when(self.views[view_type].deferred).done(function(view_type) {
-                self.views[view_type].controller.do_push_state.add(self.do_push_state);
-            });
-        });
-
         var manager_ready = $.when(searchview_loaded, main_view_loaded);
 
         this.$element.find('.oe_debug_view').change(this.on_debug_changed);
@@ -506,10 +530,11 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
             $res_logs.removeClass('oe-folded');
             return false;
         }).delegate('a.oe-remove-everything', 'click', function () {
-            $res_logs.removeClass('oe-has-more')
-                     .find('ul').empty();
+            $res_logs.removeClass('oe-has-more').find('ul').empty();
+            $res_logs.css('display','none');
             return false;
         });
+        $res_logs.css('display','none');
 
         return manager_ready;
     },
@@ -534,7 +559,10 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
                         view_mode : 'form',
                         target : 'new',
                         flags : {
-                            action_buttons : true
+                            action_buttons : true,
+                            form : {
+                                resize_textareas : true
+                            }
                         }
                     };
                 if (id) {
@@ -560,9 +588,7 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
         return $.when(this._super(view_type, no_store)).then(function () {
             self.shortcut_check(self.views[view_type]);
 
-            self.$element.find('.oe-view-manager-logs:first')
-                .addClass('oe-folded').removeClass('oe-has-more')
-                .find('ul').empty();
+            self.$element.find('.oe-view-manager-logs:first').addClass('oe-folded').removeClass('oe-has-more').css('display','none').find('ul').empty();
 
             var controller = self.views[self.active_view].controller,
                 fvg = controller.fields_view,
@@ -577,34 +603,42 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
 
             var $title = self.$element.find('.oe_view_title_text'),
                 $search_prefix = $title.find('span.oe_searchable_view');
-            if (controller.searchable !== false) {
+            if (controller.searchable !== false && self.flags.search_view !== false) {
                 if (!$search_prefix.length) {
                     $title.prepend('<span class="oe_searchable_view">' + _t("Search: ") + '</span>');
                 }
             } else {
                 $search_prefix.remove();
             }
-
-            self.do_push_state({view_type: self.active_view});
         });
     },
-
-    do_push_state: function(state, overwrite) {
+    do_push_state: function(state) {
+        if (this.widget_parent && this.widget_parent.do_push_state) {
+            state["view_type"] = this.active_view;
+            this.widget_parent.do_push_state(state);
+        }
     },
-
     do_load_state: function(state) {
-        var self = this;
-        $.when(this.on_mode_switch(state.view_type, true)).done(function() {
+        var self = this,
+            defs = [];
+        if (state.view_type && state.view_type !== this.active_view) {
+            defs.push(
+                this.views[this.active_view].deferred.pipe(function() {
+                    return self.on_mode_switch(state.view_type, true);
+                })
+            );
+        } 
+
+        $.when(defs).then(function() {
             self.views[self.active_view].controller.do_load_state(state);
         });
     },
-
     shortcut_check : function(view) {
         var self = this;
         var grandparent = this.widget_parent && this.widget_parent.widget_parent;
         // display shortcuts if on the first view for the action
         var $shortcut_toggle = this.$element.find('.oe-shortcut-toggle');
-        if (!(grandparent instanceof session.web.WebClient) ||
+        if (!this.action.name ||
             !(view.view_type === this.views_src[0].view_type
                 && view.view_id === this.views_src[0].view_id)) {
             $shortcut_toggle.hide();
@@ -648,11 +682,10 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
      * @param {Array<Object>} log_records
      */
     do_display_log: function (log_records) {
-        var self = this,
-            cutoff = 3,
-            $logs = this.$element.find('.oe-view-manager-logs:first')
-                    .addClass('oe-folded'),
-            $logs_list = $logs.find('ul').empty();
+        var self = this;
+        var cutoff = 3;
+        var $logs = this.$element.find('.oe-view-manager-logs:first').addClass('oe-folded').css('display', 'block');
+        var $logs_list = $logs.find('ul').empty();
         $logs.toggleClass('oe-has-more', log_records.length > cutoff);
         _(log_records.reverse()).each(function (record) {
             $(_.str.sprintf('<li><a href="#">%s</a></li>', record.name))
@@ -705,7 +738,7 @@ session.web.Sidebar = session.web.Widget.extend({
                     label: _t("Edit Workflow"),
                     callback: view.on_sidebar_edit_workflow,
                     title: _t("Manage views of the current object"),
-                    classname: 'oe_hide oe_sidebar_edit_workflow'
+                    classname: 'oe_sidebar_edit_workflow'
                 }, {
                     label: _t("Customize Object"),
                     callback: view.on_sidebar_customize_object,
@@ -835,7 +868,10 @@ session.web.Sidebar = session.web.Widget.extend({
                     additional_context);
                 result.result.flags = result.result.flags || {};
                 result.result.flags.new_window = true;
-                self.do_action(result.result);
+                self.do_action(result.result, function () {
+                    // reload view
+                    self.widget_parent.reload();
+                });
             });
         });
     },
@@ -851,7 +887,7 @@ session.web.Sidebar = session.web.Widget.extend({
 });
 
 session.web.TranslateDialog = session.web.Dialog.extend({
-    dialog_title: _t("Translations"),
+    dialog_title: {toString: function () { return _t("Translations"); }},
     init: function(view) {
         // TODO fme: should add the language to fields_view_get because between the fields view get
         // and the moment the user opens the translation dialog, the user language could have been changed
@@ -966,6 +1002,8 @@ session.web.TranslateDialog = session.web.Dialog.extend({
 
 session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{
     template: "EmptyComponent",
+    // name displayed in view switchers
+    display_name: '',
     set_default_options: function(options) {
         this.options = options || {};
         _.defaults(this.options, {
@@ -1064,19 +1102,33 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{
         this.embedded_view = embedded_view;
         this.options.sidebar = false;
     },
+    do_show: function () {
+        this.$element.show();
+    },
+    do_hide: function () {
+        this.$element.hide();
+    },
+    do_push_state: function(state) {
+        if (this.widget_parent && this.widget_parent.do_push_state) {
+            this.widget_parent.do_push_state(state);
+        }
+    },
+    do_load_state: function(state) {
+    },
     /**
      * Switches to a specific view type
      *
      * @param {String} view view type to switch to
      */
-    do_switch_view: function(view) { },
+    do_switch_view: function(view) { 
+    },
     /**
      * Cancels the switch to the current view, switches to the previous one
      */
-    do_prev_view: function () { },
+    do_prev_view: function () { 
+    },
     do_search: function(view) {
     },
-
     set_common_sidebar_sections: function(sidebar) {
         sidebar.add_default_sections();
     },
@@ -1089,7 +1141,14 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{
         }
     },
     on_sidebar_edit_workflow: function() {
-        console.log('Todo');
+        return this.do_action({
+            res_model : 'workflow',
+            domain : [['osv', '=', this.dataset.model]],
+            views: [[false, 'list'], [false, 'form']],
+            type : 'ir.actions.act_window',
+            view_type : "list",
+            view_mode : "list"
+        });
     },
     on_sidebar_customize_object: function() {
         var self = this;
@@ -1143,13 +1202,14 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{
     on_sidebar_view_log: function() {
     },
     sidebar_context: function () {
-        return $.Deferred().resolve({}).promise();
-    },
-
-    do_push_state: function(state, overwrite) {
+        return $.when();
     },
-
-    do_load_state: function(state) {
+    /**
+     * Asks the view to reload itself, if the reloading is asynchronous should
+     * return a {$.Deferred} indicating when the reloading is done.
+     */
+    reload: function () {
+        return $.when();
     }
 });