[MERGE] Dirty form notification

bzr revid: fme@openerp.com-20120906151443-52a4ifdfe0dfwu5n
This commit is contained in:
Fabien Meghazi 2012-09-06 17:14:43 +02:00
commit 90e82478a4
4 changed files with 93 additions and 43 deletions

View File

@ -731,6 +731,8 @@ instance.web.Menu = instance.web.Widget.extend({
* @param {Number} id database id of the terminal menu to select * @param {Number} id database id of the terminal menu to select
*/ */
open_menu: function (id) { open_menu: function (id) {
this.current_menu = id;
this.session.active_id = id;
var $clicked_menu, $sub_menu, $main_menu; var $clicked_menu, $sub_menu, $main_menu;
$clicked_menu = this.$el.add(this.$secondary_menus).find('a[data-menu=' + id + ']'); $clicked_menu = this.$el.add(this.$secondary_menus).find('a[data-menu=' + id + ']');
this.trigger('open_menu', id, $clicked_menu); this.trigger('open_menu', id, $clicked_menu);
@ -803,16 +805,15 @@ instance.web.Menu = instance.web.Widget.extend({
} }
} }
} }
this.open_menu(id);
this.current_menu = id;
this.session.active_id = id;
if (action_id) { if (action_id) {
this.trigger('menu_click', { this.trigger('menu_click', {
action_id: action_id, action_id: action_id,
needaction: needaction, needaction: needaction,
id: id id: id,
previous_menu_id: this.current_menu // Here we don't know if action will fail (in which case we have to revert menu)
}, $item); }, $item);
} }
this.open_menu(id);
}, },
/** /**
* Jquery event handler for menu click * Jquery event handler for menu click
@ -870,10 +871,12 @@ instance.web.UserMenu = instance.web.Widget.extend({
}, },
on_menu_settings: function() { on_menu_settings: function() {
var self = this; var self = this;
self.rpc("/web/action/load", { action_id: "base.action_res_users_my" }, function(result) { if (!this.getParent().has_uncommitted_changes()) {
result.result.res_id = instance.session.uid; self.rpc("/web/action/load", { action_id: "base.action_res_users_my" }, function(result) {
self.getParent().action_manager.do_action(result.result); result.result.res_id = instance.session.uid;
}); self.getParent().action_manager.do_action(result.result);
});
}
}, },
on_menu_about: function() { on_menu_about: function() {
var self = this; var self = this;
@ -951,7 +954,10 @@ instance.web.Client = instance.web.Widget.extend({
}, },
toggle_bars: function(value) { toggle_bars: function(value) {
this.$('tr:has(td.oe_topbar),.oe_leftbar').toggle(value); this.$('tr:has(td.oe_topbar),.oe_leftbar').toggle(value);
} },
has_uncommitted_changes: function() {
return false;
},
}); });
instance.web.WebClient = instance.web.Client.extend({ instance.web.WebClient = instance.web.Client.extend({
@ -963,6 +969,9 @@ instance.web.WebClient = instance.web.Client.extend({
start: function() { start: function() {
var self = this; var self = this;
return $.when(this._super()).pipe(function() { return $.when(this._super()).pipe(function() {
self.$el.on('click', '.oe_logo', function() {
self.action_manager.do_action('home');
});
if (jQuery.param !== undefined && jQuery.deparam(jQuery.param.querystring()).kitten !== undefined) { if (jQuery.param !== undefined && jQuery.deparam(jQuery.param.querystring()).kitten !== undefined) {
$("body").addClass("kitten-mode-activated"); $("body").addClass("kitten-mode-activated");
if ($.blockUI) { if ($.blockUI) {
@ -1048,11 +1057,13 @@ instance.web.WebClient = instance.web.Client.extend({
}, },
on_logout: function() { on_logout: function() {
var self = this; var self = this;
this.session.session_logout().then(function () { if (!this.has_uncommitted_changes()) {
$(window).unbind('hashchange', self.on_hashchange); this.session.session_logout().then(function () {
self.do_push_state({}); $(window).unbind('hashchange', self.on_hashchange);
window.location.reload(); self.do_push_state({});
}); window.location.reload();
});
}
}, },
bind_hashchange: function() { bind_hashchange: function() {
var self = this; var self = this;
@ -1095,14 +1106,15 @@ instance.web.WebClient = instance.web.Client.extend({
}, },
on_menu_action: function(options) { on_menu_action: function(options) {
var self = this; var self = this;
this.rpc("/web/action/load", { action_id: options.action_id }) return this.rpc("/web/action/load", { action_id: options.action_id })
.then(function (result) { .pipe(function (result) {
var action = result.result; var action = result.result;
if (options.needaction) { if (options.needaction) {
action.context.search_default_needaction_pending = true; action.context.search_default_needaction_pending = true;
} }
self.action_manager.clear_breadcrumbs(); return $.when(self.action_manager.do_action(action, null, true)).fail(function() {
self.action_manager.do_action(action); self.menu.open_menu(options.previous_menu_id);
});
}); });
}, },
do_action: function(action) { do_action: function(action) {
@ -1122,7 +1134,16 @@ instance.web.WebClient = instance.web.Client.extend({
$(".oe_webclient", this.$el).removeClass("oe_content_full_screen"); $(".oe_webclient", this.$el).removeClass("oe_content_full_screen");
$("body").css({'overflow-y':'scroll'}); $("body").css({'overflow-y':'scroll'});
} }
} },
has_uncommitted_changes: function() {
var $e = $.Event('clear_uncommitted_changes');
instance.web.bus.trigger('clear_uncommitted_changes', $e);
if ($e.isDefaultPrevented()) {
return true;
} else {
return this._super.apply(this, arguments);
}
},
}); });
instance.web.EmbeddedClient = instance.web.Client.extend({ instance.web.EmbeddedClient = instance.web.Client.extend({

View File

@ -92,6 +92,11 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
self.on("change:actual_mode", self, self.init_pager); self.on("change:actual_mode", self, self.init_pager);
self.init_pager(); self.init_pager();
}); });
instance.web.bus.on('clear_uncommitted_changes', this, function(e) {
if (!this.can_be_discarded()) {
e.preventDefault();
}
});
}, },
destroy: function() { destroy: function() {
_.each(this.get_widgets(), function(w) { _.each(this.get_widgets(), function(w) {
@ -748,7 +753,13 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
return def.promise(); return def.promise();
}, },
can_be_discarded: function() { can_be_discarded: function() {
return !this.$el.is('.oe_form_dirty') || confirm(_t("Warning, the record has been modified, your changes will be discarded.")); if (this.$el.is('.oe_form_dirty')) {
if (!confirm(_t("Warning, the record has been modified, your changes will be discarded.\n\nAre you sure you want to leave this page ?"))) {
return false;
}
this.$el.removeClass('oe_form_dirty');
}
return true;
}, },
/** /**
* Triggers saving the form's record. Chooses between creating a new * Triggers saving the form's record. Chooses between creating a new

View File

@ -101,7 +101,9 @@ instance.web.ActionManager = instance.web.Widget.extend({
select_breadcrumb: function(index, subindex) { select_breadcrumb: function(index, subindex) {
for (var i = this.breadcrumbs.length - 1; i >= 0; i--) { for (var i = this.breadcrumbs.length - 1; i >= 0; i--) {
if (i > index) { if (i > index) {
this.remove_breadcrumb(i); if (this.remove_breadcrumb(i) === false) {
return false;
}
} }
} }
var item = this.breadcrumbs[index]; var item = this.breadcrumbs[index];
@ -110,8 +112,10 @@ instance.web.ActionManager = instance.web.Widget.extend({
return true; return true;
}, },
clear_breadcrumbs: function() { clear_breadcrumbs: function() {
while (this.breadcrumbs.length) { for (var i = this.breadcrumbs.length - 1; i >= 0; i--) {
this.remove_breadcrumb(0); if (this.remove_breadcrumb(0) === false) {
break;
}
} }
}, },
remove_breadcrumb: function(index) { remove_breadcrumb: function(index) {
@ -121,9 +125,17 @@ instance.web.ActionManager = instance.web.Widget.extend({
return item.widget === it.widget; return item.widget === it.widget;
}); });
if (!dups.length) { if (!dups.length) {
item.destroy(); if (this.getParent().has_uncommitted_changes()) {
this.inner_widget = item.widget;
this.breadcrumbs.splice(index, 0, item);
return false;
} else {
item.destroy();
}
} }
} }
var last_widget = this.breadcrumbs.slice(-1)[0];
this.inner_widget = last_widget && last_widget.widget;
}, },
get_title: function() { get_title: function() {
var titles = []; var titles = [];
@ -208,19 +220,19 @@ instance.web.ActionManager = instance.web.Widget.extend({
} }
}); });
}, },
do_action: function(action, on_close) { do_action: function(action, on_close, clear_breadcrumbs) {
if (_.isString(action) && instance.web.client_actions.contains(action)) { if (_.isString(action) && instance.web.client_actions.contains(action)) {
var action_client = { type: "ir.actions.client", tag: action }; var action_client = { type: "ir.actions.client", tag: action };
return this.do_action(action_client); return this.do_action(action_client, on_close, clear_breadcrumbs);
} else if (_.isNumber(action) || _.isString(action)) { } else if (_.isNumber(action) || _.isString(action)) {
var self = this; var self = this;
return self.rpc("/web/action/load", { action_id: action }, function(result) { return self.rpc("/web/action/load", { action_id: action }).pipe(function(result) {
self.do_action(result.result, on_close); return self.do_action(result.result, on_close, clear_breadcrumbs);
}); });
} }
if (!action.type) { if (!action.type) {
console.error("No type for action", action); console.error("No type for action", action);
return null; return $.Deferred().reject();
} }
var type = action.type.replace(/\./g,'_'); var type = action.type.replace(/\./g,'_');
var popup = action.target === 'new'; var popup = action.target === 'new';
@ -235,16 +247,23 @@ instance.web.ActionManager = instance.web.Widget.extend({
}, action.flags || {}); }, action.flags || {});
if (!(type in this)) { if (!(type in this)) {
console.error("Action manager can't handle action of type " + action.type, action); console.error("Action manager can't handle action of type " + action.type, action);
return null; return $.Deferred().reject();
} }
return this[type](action, on_close); return this[type](action, on_close, clear_breadcrumbs);
}, },
null_action: function() { null_action: function() {
this.dialog_stop(); this.dialog_stop();
this.clear_breadcrumbs(); this.clear_breadcrumbs();
}, },
ir_actions_common: function(action, on_close) { ir_actions_common: function(action, on_close, clear_breadcrumbs) {
var self = this, klass, widget, post_process; var self = this, klass, widget, post_process;
if (this.inner_widget && (action.type === 'ir.actions.client' || action.target !== 'new')) {
if (this.getParent().has_uncommitted_changes()) {
return $.Deferred().reject();
} else if (clear_breadcrumbs) {
this.clear_breadcrumbs();
}
}
if (action.type === 'ir.actions.client') { if (action.type === 'ir.actions.client') {
var ClientWidget = instance.web.client_actions.get_object(action.tag); var ClientWidget = instance.web.client_actions.get_object(action.tag);
widget = new ClientWidget(this, action.params); widget = new ClientWidget(this, action.params);
@ -287,17 +306,17 @@ instance.web.ActionManager = instance.web.Widget.extend({
this.inner_widget.appendTo(this.$el); this.inner_widget.appendTo(this.$el);
} }
}, },
ir_actions_act_window: function (action, on_close) { ir_actions_act_window: function (action, on_close, clear_breadcrumbs) {
var self = this; var self = this;
if (action.target !== 'new') { if (action.target !== 'new') {
if(action.menu_id) { if(action.menu_id) {
this.dialog_stop(); this.dialog_stop();
return this.getParent().do_action(action, function () { return this.getParent().do_action(action, function () {
instance.webclient.menu.open_menu(action.menu_id); instance.webclient.menu.open_menu(action.menu_id);
}); }, clear_breadcrumbs);
} }
} }
return this.ir_actions_common(action, on_close); return this.ir_actions_common(action, on_close, clear_breadcrumbs);
}, },
ir_actions_client: function (action, on_close) { ir_actions_client: function (action, on_close) {
return this.ir_actions_common(action, on_close); return this.ir_actions_common(action, on_close);
@ -314,7 +333,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
action_id: action.id, action_id: action.id,
context: action.context || {} context: action.context || {}
}).then(function (action) { }).then(function (action) {
self.do_action(action, on_closed) self.do_action(action, on_closed, clear_breadcrumbs)
}); });
}, },
ir_actions_report_xml: function(action, on_closed) { ir_actions_report_xml: function(action, on_closed) {
@ -412,8 +431,10 @@ instance.web.ViewManager = instance.web.Widget.extend({
var self = this; var self = this;
var view = this.views[view_type]; var view = this.views[view_type];
var view_promise; var view_promise;
if(!view) var form = this.views['form'];
if (!view || (form && form.controller && !form.controller.can_be_discarded())) {
return $.Deferred().reject(); return $.Deferred().reject();
}
if (!no_store) { if (!no_store) {
this.views_history.push(view_type); this.views_history.push(view_type);

View File

@ -79,7 +79,7 @@
</form> </form>
<div class="oe_login_footer"> <div class="oe_login_footer">
<a href="#" class="oe_login_manage_db">Manage Databases</a> | <a href="#" class="oe_login_manage_db">Manage Databases</a> |
<a href="http://www.openerp.com">Powered by <span>OpenERP</span></a> <a href="http://www.openerp.com" target="_blank">Powered by <span>OpenERP</span></a>
</div> </div>
</div> </div>
</div> </div>
@ -404,13 +404,10 @@
</tr> </tr>
<tr> <tr>
<td class="oe_leftbar" valign="top"> <td class="oe_leftbar" valign="top">
<t t-js="d"> <a class="oe_logo" href="#"><img t-att-src='_s + "/web/static/src/img/logo.png"'/></a>
d.url = '/' + (window.location.search || '');
</t>
<a t-att-href="url" class="oe_logo"><img t-att-src='_s + "/web/static/src/img/logo.png"'/></a>
<div class="oe_secondary_menus_container"/> <div class="oe_secondary_menus_container"/>
<div class="oe_footer"> <div class="oe_footer">
Powered by <a href="http://www.openerp.com"><span>Open</span>ERP</a> Powered by <a href="http://www.openerp.com" target="_blank"><span>Open</span>ERP</a>
</div> </div>
</td> </td>
<td class="oe_application"> <td class="oe_application">