[Merge] Merge from openerp-web.
bzr revid: jra@tinyerp.com-20111014051952-a5emayrxco8oztyy
This commit is contained in:
commit
4c15f26980
|
@ -227,7 +227,7 @@ class HttpRequest(WebRequest):
|
|||
_logger.debug("%s --> %s.%s %r", self.httprequest.method, controller.__class__.__name__, method.__name__, akw)
|
||||
r = method(controller, self, **self.params)
|
||||
if self.debug or 1:
|
||||
if isinstance(r, werkzeug.wrappers.BaseResponse):
|
||||
if isinstance(r, (werkzeug.wrappers.BaseResponse, werkzeug.exceptions.HTTPException)):
|
||||
_logger.debug('<-- %s', r)
|
||||
else:
|
||||
_logger.debug("<-- size: %s", len(r))
|
||||
|
@ -395,7 +395,8 @@ class Root(object):
|
|||
else:
|
||||
response = result
|
||||
|
||||
response.set_cookie(self.session_cookie, session.sid)
|
||||
if hasattr(response, 'set_cookie'):
|
||||
response.set_cookie(self.session_cookie, session.sid)
|
||||
|
||||
return response(environ, start_response)
|
||||
|
||||
|
|
|
@ -5,15 +5,16 @@ openerp.web.chrome = function(openerp) {
|
|||
var QWeb = openerp.web.qweb;
|
||||
|
||||
openerp.web.Notification = openerp.web.Widget.extend(/** @lends openerp.web.Notification# */{
|
||||
/**
|
||||
* @constructs openerp.web.Notification
|
||||
* @extends openerp.web.Widget
|
||||
*
|
||||
* @param parent
|
||||
* @param element_id
|
||||
*/
|
||||
init: function(parent, element_id) {
|
||||
this._super(parent, element_id);
|
||||
template: 'Notification',
|
||||
identifier_prefix: 'notification-',
|
||||
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
openerp.notification = this;
|
||||
},
|
||||
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$element.notify({
|
||||
speed: 500,
|
||||
expires: 1500
|
||||
|
@ -28,9 +29,12 @@ openerp.web.Notification = openerp.web.Widget.extend(/** @lends openerp.web.Not
|
|||
warn: function(title, text) {
|
||||
this.$element.notify('create', 'oe_notification_alert', {
|
||||
title: title,
|
||||
text: text
|
||||
text: text,
|
||||
}, {
|
||||
expires: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog# */{
|
||||
|
@ -369,7 +373,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
|||
}
|
||||
$db_list.find(':selected').remove();
|
||||
self.db_list.splice(_.indexOf(self.db_list, db, true), 1);
|
||||
self.notification.notify("Dropping database", "The database '" + db + "' has been dropped");
|
||||
self.do_notify("Dropping database", "The database '" + db + "' has been dropped");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -454,7 +458,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
|
|||
self.display_error(result);
|
||||
return;
|
||||
}
|
||||
self.notification.notify("Changed Password", "Password has been changed successfully");
|
||||
self.do_notify("Changed Password", "Password has been changed successfully");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -487,6 +491,15 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
|
|||
this.selected_password = localStorage.getItem('last_password_login_success');
|
||||
}
|
||||
}
|
||||
|
||||
var qs = jQuery.deparam(jQuery.param.querystring());
|
||||
if (qs.db) {
|
||||
this.selected_db = qs.db;
|
||||
}
|
||||
if (qs.login) {
|
||||
this.selected_login = qs.login;
|
||||
}
|
||||
|
||||
},
|
||||
start: function() {
|
||||
var self = this;
|
||||
|
@ -779,9 +792,8 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{
|
|||
},
|
||||
start: function() {
|
||||
this.$secondary_menu.addClass(this.folded ? 'oe_folded' : 'oe_unfolded');
|
||||
this.reload();
|
||||
},
|
||||
reload: function() {
|
||||
do_reload: function() {
|
||||
this.rpc("/web/menu/load", {}, this.on_loaded);
|
||||
},
|
||||
on_loaded: function(data) {
|
||||
|
@ -823,7 +835,9 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{
|
|||
this.session.active_id = id;
|
||||
this.rpc('/web/menu/action', {'menu_id': id}, this.on_menu_action_loaded);
|
||||
}
|
||||
ev.stopPropagation();
|
||||
if (ev) {
|
||||
ev.stopPropagation();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
do_menu_click: function($clicked_menu, manual) {
|
||||
|
@ -866,6 +880,7 @@ openerp.web.Menu = openerp.web.Widget.extend(/** @lends openerp.web.Menu# */{
|
|||
$sub_menu.hide();
|
||||
return true;
|
||||
}
|
||||
return manual;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
@ -927,14 +942,12 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
|
|||
}
|
||||
this.$element.html(QWeb.render("Interface", params));
|
||||
|
||||
this.notification = new openerp.web.Notification();
|
||||
this.session = new openerp.web.Session();
|
||||
this.loading = new openerp.web.Loading(this,"oe_loading");
|
||||
this.crashmanager = new openerp.web.CrashManager(this);
|
||||
this.crashmanager.start();
|
||||
|
||||
// Do you autorize this ? will be replaced by notify() in controller
|
||||
openerp.web.Widget.prototype.notification = new openerp.web.Notification(this, "oe_notification");
|
||||
|
||||
this.header = new openerp.web.Header(this);
|
||||
this.login = new openerp.web.Login(this);
|
||||
this.header.on_logout.add(this.login.on_logout);
|
||||
|
@ -954,12 +967,27 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
|
|||
|
||||
},
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.notification.prependTo(this.$element);
|
||||
this.header.appendTo($("#oe_header"));
|
||||
this.session.start();
|
||||
this.login.appendTo($('#oe_login'));
|
||||
this.menu.start();
|
||||
},
|
||||
do_reload: function() {
|
||||
this.session.session_restore();
|
||||
this.menu.do_reload();
|
||||
},
|
||||
do_notify: function() {
|
||||
var n = this.notification;
|
||||
n.notify.apply(n, arguments);
|
||||
},
|
||||
do_warn: function() {
|
||||
var n = this.notification;
|
||||
n.warn.apply(n, arguments);
|
||||
},
|
||||
on_logged: function() {
|
||||
this.menu.do_reload();
|
||||
if(this.action_manager)
|
||||
this.action_manager.stop();
|
||||
this.action_manager = new openerp.web.ActionManager(this);
|
||||
|
@ -1046,7 +1074,8 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
|
|||
this.action_manager.do_action(action);
|
||||
},
|
||||
do_about: function() {
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
|
|
@ -74,7 +74,6 @@ openerp.web.qweb.debug = (window.location.search.indexOf('?debug') !== -1);
|
|||
}
|
||||
return this;
|
||||
}
|
||||
// This should NOT be used, like callbackenable it's too hackish not enough javasish
|
||||
Class.include = function (properties) {
|
||||
for (var name in properties) {
|
||||
if (typeof properties[name] !== 'function'
|
||||
|
@ -288,14 +287,12 @@ openerp.web.Registry = openerp.web.Class.extend( /** @lends openerp.web.Registry
|
|||
*/
|
||||
get_any: function (keys) {
|
||||
for (var i=0; i<keys.length; ++i) {
|
||||
try {
|
||||
return this.get_object(keys[i]);
|
||||
} catch (e) {
|
||||
if (e instanceof openerp.web.KeyNotFound) {
|
||||
continue;
|
||||
}
|
||||
throw e;
|
||||
var key = keys[i];
|
||||
if (key === undefined || !(key in this.map)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return this.get_object(key);
|
||||
}
|
||||
throw new openerp.web.KeyNotFound(keys.join(','));
|
||||
},
|
||||
|
|
|
@ -610,44 +610,120 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
|
|||
on_default_get: function(res) {
|
||||
this.last_default_get = res;
|
||||
},
|
||||
/**
|
||||
* Makes sure this dataset has the fields_get for its model stored locally,
|
||||
* so create/write methods are able to determine if written fields are m2os
|
||||
* and can name_get those fields if that's the case (in order to cache a
|
||||
* correct m2o value for them)
|
||||
*
|
||||
* @returns {$.Deferred} whether the fields_get is done executing, provides the fields_get value to its callbacks
|
||||
*/
|
||||
ensure_has_fields: function () {
|
||||
var self = this;
|
||||
|
||||
if (this.fields_get) {
|
||||
var d = $.Deferred();
|
||||
setTimeout(function () { d.resolve(self.fields_get, true); }, 0);
|
||||
return d.promise();
|
||||
} else {
|
||||
return self.call('fields_get', [], function (fields_get) {
|
||||
self.fields_get = fields_get;
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Relational fields may not be written in the same format they are read.
|
||||
*
|
||||
* Since the BufferedDataSet is a bit dumb, it returns what it's got stored
|
||||
* in its cache, which for modified value is what it was given. This breaks
|
||||
* some basic contracts of openerp such as m2o read being in the
|
||||
* ``name_get`` format.
|
||||
*
|
||||
* Because create & write are supposed to be asynchronous, though, it
|
||||
* should be easy to just name_get all incorrect values.
|
||||
*
|
||||
* @param {Object} data form-data to write to the cache
|
||||
* @returns {$.Deferred} resolved with a fixed data dictionary
|
||||
*/
|
||||
fix_relational: function (data) {
|
||||
var self = this;
|
||||
var results = $.Deferred();
|
||||
this.ensure_has_fields().then(function (fields) {
|
||||
var fields_to_fix = _(fields).chain()
|
||||
.map(function (d, k) { return {key: k, descriptor: d}; })
|
||||
.filter(function (field) {
|
||||
// keep m2o fields which are in the data dict
|
||||
return field.descriptor.type === 'many2one' &&
|
||||
data[field.key];
|
||||
}).pluck('key')
|
||||
.value();
|
||||
var name_gets = _(fields_to_fix).map(function (field) {
|
||||
return new openerp.web.DataSet(self, self.fields_get[field].relation)
|
||||
.name_get([data[field]], null);
|
||||
});
|
||||
// null-concat forces stupid bastard `when` to always return an
|
||||
// array containing the Array-ified results of all the name_gets.
|
||||
// otherwise, if there's a single field to fix it returns the
|
||||
// results of the unique name_get directly.
|
||||
$.when.apply(null, name_gets.concat([null])).then(function () {
|
||||
var record = _.extend({}, data);
|
||||
for(var i=0; i<fields_to_fix.length; ++i) {
|
||||
// Each argument is [[name_get], success, jqXhr] and we
|
||||
// want just the name_get pair
|
||||
record[fields_to_fix[i]] = arguments[i][0][0];
|
||||
}
|
||||
results.resolve(record);
|
||||
});
|
||||
});
|
||||
return results;
|
||||
},
|
||||
create: function(data, callback, error_callback) {
|
||||
var cached = {id:_.uniqueId(this.virtual_id_prefix), values: data,
|
||||
defaults: this.last_default_get};
|
||||
this.to_create.push(_.extend(_.clone(cached), {values: _.clone(cached.values)}));
|
||||
this.cache.push(cached);
|
||||
this.on_change();
|
||||
var self = this;
|
||||
var prom = $.Deferred().then(callback);
|
||||
prom.resolve({result: cached.id});
|
||||
this.fix_relational(data).then(function (fixed_m2o_data) {
|
||||
var cached = {
|
||||
id:_.uniqueId(self.virtual_id_prefix),
|
||||
values: fixed_m2o_data,
|
||||
defaults: self.last_default_get
|
||||
};
|
||||
self.to_create.push(_.extend(_.clone(cached), {
|
||||
values: _.clone(data)}));
|
||||
self.cache.push(cached);
|
||||
self.on_change();
|
||||
prom.resolve({result: cached.id});
|
||||
});
|
||||
return prom.promise();
|
||||
},
|
||||
write: function (id, data, options, callback) {
|
||||
var self = this;
|
||||
var record = _.detect(this.to_create, function(x) {return x.id === id;});
|
||||
record = record || _.detect(this.to_write, function(x) {return x.id === id;});
|
||||
var dirty = false;
|
||||
if (record) {
|
||||
for (var k in data) {
|
||||
if (record.values[k] === undefined || record.values[k] !== data[k]) {
|
||||
dirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$.extend(record.values, data);
|
||||
} else {
|
||||
dirty = true;
|
||||
record = {id: id, values: data};
|
||||
self.to_write.push(record);
|
||||
}
|
||||
var cached = _.detect(this.cache, function(x) {return x.id === id;});
|
||||
if (!cached) {
|
||||
cached = {id: id, values: {}};
|
||||
this.cache.push(cached);
|
||||
}
|
||||
$.extend(cached.values, record.values);
|
||||
if (dirty)
|
||||
this.on_change();
|
||||
var to_return = $.Deferred().then(callback);
|
||||
to_return.resolve({result: true});
|
||||
this.fix_relational(data).then(function (fixed_m2o_data) {
|
||||
var record = _.detect(self.to_create, function(x) {return x.id === id;});
|
||||
record = record || _.detect(self.to_write, function(x) {return x.id === id;});
|
||||
var dirty = false;
|
||||
if (record) {
|
||||
for (var k in data) {
|
||||
if (record.values[k] === undefined || record.values[k] !== data[k]) {
|
||||
dirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_.extend(record.values, data);
|
||||
} else {
|
||||
dirty = true;
|
||||
record = {id: id, values: data};
|
||||
self.to_write.push(record);
|
||||
}
|
||||
var cached = _.detect(self.cache, function(x) {return x.id === id;});
|
||||
if (!cached) {
|
||||
cached = {id: id, values: {}};
|
||||
this.cache.push(cached);
|
||||
}
|
||||
_.extend(cached.values, fixed_m2o_data);
|
||||
if (dirty)
|
||||
self.on_change();
|
||||
to_return.resolve({result: true});
|
||||
});
|
||||
return to_return.promise();
|
||||
},
|
||||
unlink: function(ids, callback, error_callback) {
|
||||
|
|
|
@ -69,6 +69,13 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
|
|||
} catch (e) {
|
||||
return value.format("%H:%M:%S");
|
||||
}
|
||||
case 'selection':
|
||||
// Each choice is [value, label]
|
||||
var result = _(descriptor.selection).detect(function (choice) {
|
||||
return choice[0] === value;
|
||||
});
|
||||
if (result) { return result[1]; }
|
||||
return;
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
|
|
|
@ -336,7 +336,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
|
|||
* @param {Array} errors a never-empty array of error objects
|
||||
*/
|
||||
on_invalid: function (errors) {
|
||||
this.notification.notify("Invalid Search", "triggered from search view");
|
||||
this.do_notify("Invalid Search", "triggered from search view");
|
||||
},
|
||||
do_clear: function () {
|
||||
this.$element.find('.filter_label, .filter_icon').removeClass('enabled');
|
||||
|
|
|
@ -33,7 +33,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
this.widgets_counter = 0;
|
||||
this.fields = {};
|
||||
this.datarecord = {};
|
||||
this.ready = false;
|
||||
this.show_invalid = true;
|
||||
this.dirty_for_user = false;
|
||||
this.default_focus_field = null;
|
||||
|
@ -44,7 +43,10 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
this.translatable_fields = [];
|
||||
_.defaults(this.options, {"always_show_new_button": true,
|
||||
"not_interactible_on_create": false});
|
||||
this.save_lock = $.Deferred().resolve();
|
||||
this.mutating_lock = $.Deferred();
|
||||
this.initial_mutating_lock = this.mutating_lock;
|
||||
this.on_change_lock = $.Deferred().resolve();
|
||||
this.reload_lock = $.Deferred().resolve();
|
||||
},
|
||||
start: function() {
|
||||
this._super();
|
||||
|
@ -120,7 +122,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id);
|
||||
this.sidebar.start();
|
||||
this.sidebar.do_unfold();
|
||||
this.sidebar.attachments = new openerp.web.form.SidebarAttachments(this.sidebar, this.sidebar.add_section('attachments', "Attachments"), this);
|
||||
this.sidebar.attachments = new openerp.web.form.SidebarAttachments(this.sidebar, this);
|
||||
this.sidebar.add_toolbar(this.fields_view.toolbar);
|
||||
this.set_common_sidebar_sections(this.sidebar);
|
||||
}
|
||||
|
@ -181,7 +183,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
}
|
||||
}
|
||||
this.on_form_changed();
|
||||
this.show_invalid = this.ready = true;
|
||||
this.initial_mutating_lock.resolve();
|
||||
this.show_invalid = true;
|
||||
this.do_update_pager(record.id == null);
|
||||
if (this.sidebar) {
|
||||
this.sidebar.attachments.do_update();
|
||||
|
@ -224,69 +227,78 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
$pager.find('span.oe_pager_count').html(this.dataset.ids.length);
|
||||
},
|
||||
do_onchange: function(widget, processed) {
|
||||
processed = processed || [];
|
||||
if (widget.node.attrs.on_change) {
|
||||
var self = this;
|
||||
this.ready = false;
|
||||
var onchange = _.trim(widget.node.attrs.on_change);
|
||||
var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/);
|
||||
if (call) {
|
||||
var method = call[1], args = [];
|
||||
var context_index = null;
|
||||
var argument_replacement = {
|
||||
'False' : function() {return false;},
|
||||
'True' : function() {return true;},
|
||||
'None' : function() {return null;},
|
||||
'context': function(i) {
|
||||
context_index = i;
|
||||
var ctx = widget.build_context ? widget.build_context() : {};
|
||||
return ctx;
|
||||
}
|
||||
};
|
||||
var parent_fields = null;
|
||||
_.each(call[2].split(','), function(a, i) {
|
||||
var field = _.trim(a);
|
||||
if (field in argument_replacement) {
|
||||
args.push(argument_replacement[field](i));
|
||||
return;
|
||||
} else if (self.fields[field]) {
|
||||
var value = self.fields[field].get_on_change_value();
|
||||
args.push(value == null ? false : value);
|
||||
return;
|
||||
} else {
|
||||
var splitted = field.split('.');
|
||||
if (splitted.length > 1 && _.trim(splitted[0]) === "parent" && self.dataset.parent_view) {
|
||||
if (parent_fields === null) {
|
||||
parent_fields = self.dataset.parent_view.get_fields_values();
|
||||
}
|
||||
var p_val = parent_fields[_.trim(splitted[1])];
|
||||
if (p_val !== undefined) {
|
||||
args.push(p_val == null ? false : p_val);
|
||||
return;
|
||||
var self = this;
|
||||
var act = function() {
|
||||
try {
|
||||
processed = processed || [];
|
||||
if (widget.node.attrs.on_change) {
|
||||
var onchange = _.trim(widget.node.attrs.on_change);
|
||||
var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/);
|
||||
if (call) {
|
||||
var method = call[1], args = [];
|
||||
var context_index = null;
|
||||
var argument_replacement = {
|
||||
'False' : function() {return false;},
|
||||
'True' : function() {return true;},
|
||||
'None' : function() {return null;},
|
||||
'context': function(i) {
|
||||
context_index = i;
|
||||
var ctx = widget.build_context ? widget.build_context() : {};
|
||||
return ctx;
|
||||
}
|
||||
};
|
||||
var parent_fields = null;
|
||||
_.each(call[2].split(','), function(a, i) {
|
||||
var field = _.trim(a);
|
||||
if (field in argument_replacement) {
|
||||
args.push(argument_replacement[field](i));
|
||||
return;
|
||||
} else if (self.fields[field]) {
|
||||
var value = self.fields[field].get_on_change_value();
|
||||
args.push(value == null ? false : value);
|
||||
return;
|
||||
} else {
|
||||
var splitted = field.split('.');
|
||||
if (splitted.length > 1 && _.trim(splitted[0]) === "parent" && self.dataset.parent_view) {
|
||||
if (parent_fields === null) {
|
||||
parent_fields = self.dataset.parent_view.get_fields_values();
|
||||
}
|
||||
var p_val = parent_fields[_.trim(splitted[1])];
|
||||
if (p_val !== undefined) {
|
||||
args.push(p_val == null ? false : p_val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw "Could not get field with name '" + field +
|
||||
"' for onchange '" + onchange + "'";
|
||||
});
|
||||
var ajax = {
|
||||
url: '/web/dataset/call',
|
||||
async: false
|
||||
};
|
||||
return this.rpc(ajax, {
|
||||
model: this.dataset.model,
|
||||
method: method,
|
||||
args: [(this.datarecord.id == null ? [] : [this.datarecord.id])].concat(args),
|
||||
context_id: context_index === null ? null : context_index + 1
|
||||
}, function(response) {
|
||||
self.on_processed_onchange(response, processed);
|
||||
});
|
||||
} else {
|
||||
console.log("Wrong on_change format", on_change);
|
||||
throw "Could not get field with name '" + field +
|
||||
"' for onchange '" + onchange + "'";
|
||||
});
|
||||
var ajax = {
|
||||
url: '/web/dataset/call',
|
||||
async: false
|
||||
};
|
||||
return self.rpc(ajax, {
|
||||
model: self.dataset.model,
|
||||
method: method,
|
||||
args: [(self.datarecord.id == null ? [] : [self.datarecord.id])].concat(args),
|
||||
context_id: context_index === null ? null : context_index + 1
|
||||
}).pipe(function(response) {
|
||||
return self.on_processed_onchange(response, processed);
|
||||
});
|
||||
} else {
|
||||
console.log("Wrong on_change format", on_change);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
return $.Deferred().reject();
|
||||
}
|
||||
};
|
||||
this.on_change_lock = this.on_change_lock.pipe(act, act);
|
||||
return this.on_change_lock;
|
||||
},
|
||||
on_processed_onchange: function(response, processed) {
|
||||
try {
|
||||
var result = response;
|
||||
if (result.value) {
|
||||
for (var f in result.value) {
|
||||
|
@ -319,7 +331,11 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
if (result.domain) {
|
||||
// TODO:
|
||||
}
|
||||
this.ready = true;
|
||||
return $.Deferred().resolve();
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
return $.Deferred().reject();
|
||||
}
|
||||
},
|
||||
on_button_new: function() {
|
||||
var self = this;
|
||||
|
@ -367,9 +383,9 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
do_save: function(success, prepend_on_create) {
|
||||
var self = this;
|
||||
var action = function() {
|
||||
if (!self.ready) {
|
||||
return $.Deferred().reject();
|
||||
}
|
||||
try {
|
||||
if (!self.initial_mutating_lock.isResolved() && !self.initial_mutating_lock.isRejected())
|
||||
return;
|
||||
var form_dirty = false,
|
||||
form_invalid = false,
|
||||
values = {},
|
||||
|
@ -403,8 +419,13 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
}).then(success);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return $.Deferred().reject();
|
||||
}
|
||||
};
|
||||
this.save_lock = this.save_lock.pipe(action, action);
|
||||
this.mutating_lock = this.mutating_lock.pipe(action, action);
|
||||
return this.mutating_lock;
|
||||
},
|
||||
do_save_edit: function() {
|
||||
this.do_save();
|
||||
|
@ -422,14 +443,15 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
}
|
||||
});
|
||||
msg += "</ul>";
|
||||
this.notification.warn("The following fields are invalid :", msg);
|
||||
this.do_warn("The following fields are invalid :", msg);
|
||||
},
|
||||
on_saved: function(r, success) {
|
||||
if (!r.result) {
|
||||
// should not happen in the server, but may happen for internal purpose
|
||||
return $.Deferred().reject();
|
||||
} else {
|
||||
return this.reload().then(success);
|
||||
this.reload();
|
||||
return $.when(r).then(success);
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
@ -463,9 +485,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
this.sidebar.attachments.do_update();
|
||||
}
|
||||
console.debug("The record has been created with id #" + this.datarecord.id);
|
||||
return this.reload().pipe(function() {
|
||||
return _.extend(r, {created: true});
|
||||
}).then(success);
|
||||
this.reload();
|
||||
return $.when(_.extend(r, {created: true})).then(success);
|
||||
}
|
||||
},
|
||||
on_action: function (action) {
|
||||
|
@ -475,11 +496,16 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
|
|||
console.debug("Cancelling form");
|
||||
},
|
||||
reload: function() {
|
||||
if (this.dataset.index == null || this.dataset.index < 0) {
|
||||
return $.when(this.on_button_new());
|
||||
} else {
|
||||
return this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded);
|
||||
}
|
||||
var self = this;
|
||||
var act = function() {
|
||||
if (self.dataset.index == null || self.dataset.index < 0) {
|
||||
return $.when(self.on_button_new());
|
||||
} else {
|
||||
return self.dataset.read_index(_.keys(self.fields_view.fields), self.on_record_loaded);
|
||||
}
|
||||
};
|
||||
this.reload_lock = this.reload_lock.pipe(act, act);
|
||||
return this.reload_lock;
|
||||
},
|
||||
get_fields_values: function() {
|
||||
var values = {};
|
||||
|
@ -545,8 +571,12 @@ openerp.web.FormDialog = openerp.web.Dialog.extend({
|
|||
openerp.web.form = {};
|
||||
|
||||
openerp.web.form.SidebarAttachments = openerp.web.Widget.extend({
|
||||
init: function(parent, element_id, form_view) {
|
||||
this._super(parent, element_id);
|
||||
init: function(parent, form_view) {
|
||||
var $section = parent.add_section(_t('Attachments'), 'attachments');
|
||||
this.$div = $('<div class="oe-sidebar-attachments"></div>');
|
||||
$section.append(this.$div);
|
||||
|
||||
this._super(parent, $section.attr('id'));
|
||||
this.view = form_view;
|
||||
},
|
||||
do_update: function() {
|
||||
|
@ -564,7 +594,7 @@ openerp.web.form.SidebarAttachments = openerp.web.Widget.extend({
|
|||
},
|
||||
on_attachments_loaded: function(attachments) {
|
||||
this.attachments = attachments;
|
||||
this.$element.html(QWeb.render('FormView.sidebar.attachments', this));
|
||||
this.$div.html(QWeb.render('FormView.sidebar.attachments', this));
|
||||
this.$element.find('.oe-binary-file').change(this.on_attachment_changed);
|
||||
this.$element.find('.oe-sidebar-attachment-delete').click(this.on_attachment_delete);
|
||||
},
|
||||
|
@ -586,7 +616,7 @@ openerp.web.form.SidebarAttachments = openerp.web.Widget.extend({
|
|||
ids: [parseInt($e.attr('data-id'))]
|
||||
}, function(r) {
|
||||
$e.parent().remove();
|
||||
self.notification.notify("Delete an attachment", "The attachment '" + name + "' has been deleted");
|
||||
self.do_notify("Delete an attachment", "The attachment '" + name + "' has been deleted");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -705,6 +735,51 @@ openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.
|
|||
render: function() {
|
||||
var template = this.template;
|
||||
return QWeb.render(template, { "widget": this });
|
||||
},
|
||||
_build_view_fields_values: function() {
|
||||
var a_dataset = this.view.dataset;
|
||||
var fields_values = this.view.get_fields_values();
|
||||
var parent_values = a_dataset.parent_view ? a_dataset.parent_view.get_fields_values() : {};
|
||||
fields_values.parent = parent_values;
|
||||
return fields_values;
|
||||
},
|
||||
_build_eval_context: function() {
|
||||
var a_dataset = this.view.dataset;
|
||||
return new openerp.web.CompoundContext(a_dataset.get_context(), this._build_view_fields_values());
|
||||
},
|
||||
/**
|
||||
* Builds a new context usable for operations related to fields by merging
|
||||
* the fields'context with the action's context.
|
||||
*/
|
||||
build_context: function() {
|
||||
var f_context = (this.field || {}).context || {};
|
||||
if (!!f_context.__ref) {
|
||||
var fields_values = this._build_eval_context();
|
||||
f_context = new openerp.web.CompoundDomain(f_context).set_eval_context(fields_values);
|
||||
}
|
||||
// maybe the default_get should only be used when we do a default_get?
|
||||
var v_contexts = _.compact([this.node.attrs.default_get || null,
|
||||
this.node.attrs.context || null]);
|
||||
var v_context = new openerp.web.CompoundContext();
|
||||
_.each(v_contexts, function(x) {v_context.add(x);});
|
||||
if (_.detect(v_contexts, function(x) {return !!x.__ref;})) {
|
||||
var fields_values = this._build_eval_context();
|
||||
v_context.set_eval_context(fields_values);
|
||||
}
|
||||
// if there is a context on the node, overrides the model's context
|
||||
var ctx = v_contexts.length > 0 ? v_context : f_context;
|
||||
return ctx;
|
||||
},
|
||||
build_domain: function() {
|
||||
var f_domain = this.field.domain || [];
|
||||
var n_domain = this.node.attrs.domain || null;
|
||||
// if there is a domain on the node, overrides the model's domain
|
||||
var final_domain = n_domain !== null ? n_domain : f_domain;
|
||||
if (!(final_domain instanceof Array)) {
|
||||
var fields_values = this._build_eval_context();
|
||||
final_domain = new openerp.web.CompoundDomain(final_domain).set_eval_context(fields_values);
|
||||
}
|
||||
return final_domain;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -918,7 +993,7 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
|
|||
return self.on_confirmed();
|
||||
}
|
||||
};
|
||||
if (!this.node.attrs.special && (this.view.dirty_for_user || !this.view.datarecord.id)) {
|
||||
if (!this.node.attrs.special) {
|
||||
return this.view.recursive_save().pipe(exec_action);
|
||||
} else {
|
||||
return exec_action();
|
||||
|
@ -926,9 +1001,16 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
|
|||
},
|
||||
on_confirmed: function() {
|
||||
var self = this;
|
||||
|
||||
var context = this.node.attrs.context;
|
||||
if (context && context.__ref) {
|
||||
context = new openerp.web.CompoundContext(context);
|
||||
context.set_eval_context(this._build_eval_context());
|
||||
}
|
||||
|
||||
return this.view.do_execute_action(
|
||||
this.node.attrs, this.view.dataset, this.view.datarecord.id, function () {
|
||||
_.extend({}, this.node.attrs, {context: context}),
|
||||
this.view.dataset, this.view.datarecord.id, function () {
|
||||
self.view.reload();
|
||||
});
|
||||
},
|
||||
|
@ -1075,51 +1157,6 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
|
|||
this.invalid = false;
|
||||
},
|
||||
focus: function() {
|
||||
},
|
||||
_build_view_fields_values: function() {
|
||||
var a_dataset = this.view.dataset;
|
||||
var fields_values = this.view.get_fields_values();
|
||||
var parent_values = a_dataset.parent_view ? a_dataset.parent_view.get_fields_values() : {};
|
||||
fields_values.parent = parent_values;
|
||||
return fields_values;
|
||||
},
|
||||
_build_eval_context: function() {
|
||||
var a_dataset = this.view.dataset;
|
||||
return new openerp.web.CompoundContext(a_dataset.get_context(), this._build_view_fields_values());
|
||||
},
|
||||
/**
|
||||
* Builds a new context usable for operations related to fields by merging
|
||||
* the fields'context with the action's context.
|
||||
*/
|
||||
build_context: function() {
|
||||
var f_context = this.field.context || {};
|
||||
if (!!f_context.__ref) {
|
||||
var fields_values = this._build_eval_context();
|
||||
f_context = new openerp.web.CompoundDomain(f_context).set_eval_context(fields_values);
|
||||
}
|
||||
// maybe the default_get should only be used when we do a default_get?
|
||||
var v_contexts = _.compact([this.node.attrs.default_get || null,
|
||||
this.node.attrs.context || null]);
|
||||
var v_context = new openerp.web.CompoundContext();
|
||||
_.each(v_contexts, function(x) {v_context.add(x);});
|
||||
if (_.detect(v_contexts, function(x) {return !!x.__ref;})) {
|
||||
var fields_values = this._build_eval_context();
|
||||
v_context.set_eval_context(fields_values);
|
||||
}
|
||||
// if there is a context on the node, overrides the model's context
|
||||
var ctx = v_contexts.length > 0 ? v_context : f_context;
|
||||
return ctx;
|
||||
},
|
||||
build_domain: function() {
|
||||
var f_domain = this.field.domain || [];
|
||||
var n_domain = this.node.attrs.domain || null;
|
||||
// if there is a domain on the node, overrides the model's domain
|
||||
var final_domain = n_domain !== null ? n_domain : f_domain;
|
||||
if (!(final_domain instanceof Array)) {
|
||||
var fields_values = this._build_eval_context();
|
||||
final_domain = new openerp.web.CompoundDomain(final_domain).set_eval_context(fields_values);
|
||||
}
|
||||
return final_domain;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1165,7 +1202,7 @@ openerp.web.form.FieldEmail = openerp.web.form.FieldChar.extend({
|
|||
},
|
||||
on_button_clicked: function() {
|
||||
if (!this.value || !this.is_valid()) {
|
||||
this.notification.warn("E-mail error", "Can't send email to invalid e-mail address");
|
||||
this.do_warn("E-mail error", "Can't send email to invalid e-mail address");
|
||||
} else {
|
||||
location.href = 'mailto:' + this.value;
|
||||
}
|
||||
|
@ -1180,7 +1217,7 @@ openerp.web.form.FieldUrl = openerp.web.form.FieldChar.extend({
|
|||
},
|
||||
on_button_clicked: function() {
|
||||
if (!this.value) {
|
||||
this.notification.warn("Resource error", "This resource is empty");
|
||||
this.do_warn("Resource error", "This resource is empty");
|
||||
} else {
|
||||
window.open(this.value);
|
||||
}
|
||||
|
@ -1857,6 +1894,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
|
|||
this._super(view, node);
|
||||
this.is_started = $.Deferred();
|
||||
this.form_last_update = $.Deferred();
|
||||
this.init_form_last_update = this.form_last_update;
|
||||
this.disable_utility_classes = true;
|
||||
},
|
||||
start: function() {
|
||||
|
@ -1898,7 +1936,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
|
|||
form: 'openerp.web.form.One2ManyFormView'
|
||||
});
|
||||
var once = $.Deferred().then(function() {
|
||||
self.form_last_update.resolve();
|
||||
self.init_form_last_update.resolve();
|
||||
});
|
||||
this.viewmanager.on_controller_inited.add_last(function(view_type, controller) {
|
||||
if (view_type == "list") {
|
||||
|
@ -1932,9 +1970,10 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
|
|||
if (this.dataset.index === null && this.dataset.ids.length >= 1) {
|
||||
this.dataset.index = 0;
|
||||
}
|
||||
this.form_last_update.then(function() {
|
||||
this.form_last_update = view.do_show();
|
||||
});
|
||||
var act = function() {
|
||||
return view.do_show();
|
||||
}
|
||||
this.form_last_update = this.form_last_update.pipe(act, act);;
|
||||
} else if (self.viewmanager.active_view === "graph") {
|
||||
view.do_search(this.build_domain(), this.dataset.get_context(), []);
|
||||
}
|
||||
|
@ -2025,9 +2064,10 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
|
|||
var view = this.viewmanager.views[this.viewmanager.active_view].controller;
|
||||
if (this.viewmanager.active_view === "form") {
|
||||
var res = $.when(view.do_save());
|
||||
if (!res.isResolved() && !res.isRejected()) {
|
||||
throw "Asynchronous get_value() is not supported in form view.";
|
||||
}
|
||||
// it seems line there are some cases when this happens
|
||||
/*if (!res.isResolved() && !res.isRejected()) {
|
||||
console.warn("Asynchronous get_value() is not supported in form view.");
|
||||
}*/
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
@ -2039,6 +2079,8 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
|
|||
},
|
||||
validate: function() {
|
||||
this.invalid = false;
|
||||
if (!this.viewmanager.views[this.viewmanager.active_view])
|
||||
return;
|
||||
var view = this.viewmanager.views[this.viewmanager.active_view].controller;
|
||||
if (this.viewmanager.active_view === "form") {
|
||||
for (var f in view.fields) {
|
||||
|
@ -2362,13 +2404,17 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
|
|||
var $nbutton = $buttons.find(".oe_selectcreatepopup-form-save-new");
|
||||
$nbutton.click(function() {
|
||||
$.when(self.view_form.do_save()).then(function() {
|
||||
self.view_form.on_button_new();
|
||||
self.view_form.reload_lock.then(function() {
|
||||
self.view_form.on_button_new();
|
||||
});
|
||||
});
|
||||
});
|
||||
var $nbutton = $buttons.find(".oe_selectcreatepopup-form-save");
|
||||
$nbutton.click(function() {
|
||||
$.when(self.view_form.do_save()).then(function() {
|
||||
self.check_exit();
|
||||
self.view_form.reload_lock.then(function() {
|
||||
self.check_exit();
|
||||
});
|
||||
});
|
||||
});
|
||||
var $cbutton = $buttons.find(".oe_selectcreatepopup-form-close");
|
||||
|
@ -2437,7 +2483,6 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
|
|||
this.setup_form_view();
|
||||
},
|
||||
on_write: function(id, data) {
|
||||
this.stop();
|
||||
if (!this.options.auto_write)
|
||||
return;
|
||||
var self = this;
|
||||
|
@ -2460,7 +2505,9 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
|
|||
$buttons.html(QWeb.render("FormOpenPopup.form.buttons"));
|
||||
var $nbutton = $buttons.find(".oe_formopenpopup-form-save");
|
||||
$nbutton.click(function() {
|
||||
self.view_form.do_save();
|
||||
self.view_form.do_save().then(function() {
|
||||
self.stop();
|
||||
});
|
||||
});
|
||||
var $cbutton = $buttons.find(".oe_formopenpopup-form-close");
|
||||
$cbutton.click(function() {
|
||||
|
@ -2587,7 +2634,7 @@ openerp.web.form.FieldBinary = openerp.web.form.Field.extend({
|
|||
on_file_uploaded: function(size, name, content_type, file_base64) {
|
||||
delete(window[this.iframe]);
|
||||
if (size === false) {
|
||||
this.notification.warn("File Upload", "There was a problem while uploading your file");
|
||||
this.do_warn("File Upload", "There was a problem while uploading your file");
|
||||
// TODO: use openerp web crashmanager
|
||||
console.warn("Error while uploading file : ", name);
|
||||
} else {
|
||||
|
@ -2601,7 +2648,7 @@ openerp.web.form.FieldBinary = openerp.web.form.Field.extend({
|
|||
},
|
||||
on_save_as: function() {
|
||||
if (!this.view.datarecord.id) {
|
||||
this.notification.warn("Can't save file", "The record has not yet been saved");
|
||||
this.do_warn("Can't save file", "The record has not yet been saved");
|
||||
} else {
|
||||
var url = '/web/binary/saveas?session_id=' + this.session.session_id + '&model=' +
|
||||
this.view.dataset.model +'&id=' + (this.view.datarecord.id || '') + '&field=' + this.name +
|
||||
|
|
|
@ -194,7 +194,7 @@ openerp.web.list_editable = function (openerp) {
|
|||
}
|
||||
self.edition = true;
|
||||
self.edition_id = record_id;
|
||||
self.edition_form = _.extend(new openerp.web.ListEditableFormView(self, self.dataset, false), {
|
||||
self.edition_form = _.extend(new openerp.web.ListEditableFormView(self.view, self.dataset, false), {
|
||||
form_template: 'ListView.row.form',
|
||||
registry: openerp.web.list.form.widgets,
|
||||
$element: $new_row
|
||||
|
|
|
@ -110,7 +110,7 @@ openerp.web.TreeView = openerp.web.View.extend(/** @lends openerp.web.TreeView#
|
|||
}
|
||||
});
|
||||
|
||||
if (this.fields_view.arch.attrs.colors) {
|
||||
if (!this.fields_view.arch.attrs.colors) {
|
||||
return;
|
||||
}
|
||||
this.colors = _(this.fields_view.arch.attrs.colors.split(';')).chain()
|
||||
|
|
|
@ -121,6 +121,12 @@ db.web.ActionManager = db.web.Widget.extend({
|
|||
if (!this.dialog && on_closed) {
|
||||
on_closed();
|
||||
}
|
||||
if (this.dialog && action.context) {
|
||||
var model = action.context.active_model;
|
||||
if (model === 'base.module.upgrade' || model === 'base.setup.installer' || model === 'base.module.upgrade') {
|
||||
db.webclient.do_reload();
|
||||
}
|
||||
}
|
||||
this.dialog_stop();
|
||||
},
|
||||
ir_actions_server: function (action, on_closed) {
|
||||
|
@ -514,9 +520,57 @@ db.web.Sidebar = db.web.Widget.extend({
|
|||
self.do_toggle();
|
||||
});
|
||||
},
|
||||
|
||||
call_default_on_sidebar: function(item) {
|
||||
var func_name = 'on_sidebar_' + _.underscored(item.label);
|
||||
var fn = this.widget_parent[func_name];
|
||||
if(typeof fn === 'function') {
|
||||
fn(item);
|
||||
}
|
||||
},
|
||||
|
||||
add_default_sections: function() {
|
||||
this.add_section(_t('Customize'), 'customize');
|
||||
this.add_items('customize', [
|
||||
{
|
||||
label: _t("Manage Views"),
|
||||
callback: this.call_default_on_sidebar,
|
||||
title: _t("Manage views of the current object"),
|
||||
}, {
|
||||
label: _t("Edit Workflow"),
|
||||
callback: this.call_default_on_sidebar,
|
||||
title: _t("Manage views of the current object"),
|
||||
classname: 'oe_hide oe_sidebar_edit_workflow'
|
||||
}, {
|
||||
label: _t("Customize Object"),
|
||||
callback: this.call_default_on_sidebar,
|
||||
title: _t("Manage views of the current object"),
|
||||
}
|
||||
]);
|
||||
|
||||
this.add_section(_t('Other Options'), 'other');
|
||||
this.add_items('other', [
|
||||
{
|
||||
label: _t("Import"),
|
||||
callback: this.call_default_on_sidebar,
|
||||
}, {
|
||||
label: _t("Export"),
|
||||
callback: this.call_default_on_sidebar,
|
||||
}, {
|
||||
label: _t("Translate"),
|
||||
callback: this.call_default_on_sidebar,
|
||||
classname: 'oe_sidebar_translate oe_hide'
|
||||
}, {
|
||||
label: _t("View Log"),
|
||||
callback: this.call_default_on_sidebar,
|
||||
classname: 'oe_hide oe_sidebar_view_log'
|
||||
}
|
||||
]);
|
||||
},
|
||||
|
||||
add_toolbar: function(toolbar) {
|
||||
var self = this;
|
||||
_.each([['print', "Reports"], ['action', "Actions"], ['relate', "Links"]], function(type) {
|
||||
_.each([['print', _t("Reports")], ['action', _t("Actions")], ['relate', _t("Links")]], function(type) {
|
||||
var items = toolbar[type[0]];
|
||||
if (items.length) {
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
|
@ -526,15 +580,30 @@ db.web.Sidebar = db.web.Widget.extend({
|
|||
classname: 'oe_sidebar_' + type[0]
|
||||
}
|
||||
}
|
||||
self.add_section(type[0], type[1], items);
|
||||
self.add_section(type[1], type[0]);
|
||||
self.add_items(type[0], items);
|
||||
}
|
||||
});
|
||||
},
|
||||
add_section: function(code, name, items) {
|
||||
// For each section, we pass a name/label and optionally an array of items.
|
||||
// If no items are passed, then the section will be created as a custom section
|
||||
// returning back an element_id to be used by a custom controller.
|
||||
// Else, the section is a standard section with items displayed as links.
|
||||
|
||||
add_section: function(name, code) {
|
||||
if(!code) code = _.underscored(name);
|
||||
var $section = this.sections[code];
|
||||
|
||||
if(!$section) {
|
||||
section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
|
||||
var $section = $(db.web.qweb.render("Sidebar.section", {
|
||||
section_id: section_id,
|
||||
name: name,
|
||||
classname: 'oe_sidebar_' + code,
|
||||
}));
|
||||
$section.appendTo(this.$element.find('div.sidebar-actions'));
|
||||
this.sections[code] = $section;
|
||||
}
|
||||
return $section;
|
||||
},
|
||||
|
||||
add_items: function(section_code, items) {
|
||||
// An item is a dictonary : {
|
||||
// label: label to be displayed for the link,
|
||||
// action: action to be launch when the link is clicked,
|
||||
|
@ -543,25 +612,24 @@ db.web.Sidebar = db.web.Widget.extend({
|
|||
// title: optional title for the link
|
||||
// }
|
||||
// Note: The item should have one action or/and a callback
|
||||
//
|
||||
|
||||
var self = this,
|
||||
section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
|
||||
$section = this.add_section(_.titleize(section_code.replace('_', ' ')), section_code),
|
||||
section_id = $section.attr('id');
|
||||
|
||||
if (items) {
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
items[i].element_id = _.uniqueId(section_id + '_item_');
|
||||
this.items[items[i].element_id] = items[i];
|
||||
}
|
||||
}
|
||||
var $section = $(db.web.qweb.render("Sidebar.section", {
|
||||
section_id: section_id,
|
||||
name: name,
|
||||
classname: 'oe_sidebar_' + code,
|
||||
items: items
|
||||
}));
|
||||
if (items) {
|
||||
$section.find('a.oe_sidebar_action_a').click(function() {
|
||||
|
||||
var $items = $(db.web.qweb.render("Sidebar.section.items", {items: items}));
|
||||
|
||||
$items.find('a.oe_sidebar_action_a').click(function() {
|
||||
var item = self.items[$(this).attr('id')];
|
||||
if (item.callback) {
|
||||
item.callback();
|
||||
item.callback.apply(self, [item]);
|
||||
}
|
||||
if (item.action) {
|
||||
var ids = self.widget_parent.get_selected_ids();
|
||||
|
@ -591,10 +659,13 @@ db.web.Sidebar = db.web.Widget.extend({
|
|||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
var $ul = $section.find('ul');
|
||||
if(!$ul.length) {
|
||||
$ul = $('<ul/>').appendTo($section);
|
||||
}
|
||||
$items.appendTo($ul);
|
||||
}
|
||||
$section.appendTo(this.$element.find('div.sidebar-actions'));
|
||||
this.sections[code] = $section;
|
||||
return section_id;
|
||||
},
|
||||
do_fold: function() {
|
||||
this.$element.addClass('closed-sidebar').removeClass('open-sidebar');
|
||||
|
@ -823,46 +894,15 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
|
|||
},
|
||||
do_search: function(view) {
|
||||
},
|
||||
|
||||
set_common_sidebar_sections: function(sidebar) {
|
||||
sidebar.add_section('customize', "Customize", [
|
||||
{
|
||||
label: "Manage Views",
|
||||
callback: this.on_sidebar_manage_view,
|
||||
title: "Manage views of the current object"
|
||||
}, {
|
||||
label: "Edit Workflow",
|
||||
callback: this.on_sidebar_edit_workflow,
|
||||
title: "Manage views of the current object",
|
||||
classname: 'oe_hide oe_sidebar_edit_workflow'
|
||||
}, {
|
||||
label: "Customize Object",
|
||||
callback: this.on_sidebar_customize_object,
|
||||
title: "Manage views of the current object"
|
||||
}
|
||||
]);
|
||||
sidebar.add_section('other', "Other Options", [
|
||||
{
|
||||
label: "Import",
|
||||
callback: this.on_sidebar_import
|
||||
}, {
|
||||
label: "Export",
|
||||
callback: this.on_sidebar_export
|
||||
}, {
|
||||
label: "Translate",
|
||||
callback: this.on_sidebar_translate,
|
||||
classname: 'oe_sidebar_translate oe_hide'
|
||||
}, {
|
||||
label: "View Log",
|
||||
callback: this.on_sidebar_view_log,
|
||||
classname: 'oe_hide oe_sidebar_view_log'
|
||||
}
|
||||
]);
|
||||
sidebar.add_default_sections();
|
||||
},
|
||||
on_sidebar_manage_view: function() {
|
||||
on_sidebar_manage_views: function() {
|
||||
if (this.fields_view && this.fields_view.arch) {
|
||||
$('<xmp>' + db.web.json_node_to_xml(this.fields_view.arch, true) + '</xmp>').dialog({ width: '95%', height: 600});
|
||||
} else {
|
||||
this.notification.warn("Manage Views", "Could not find current view declaration");
|
||||
this.do_warn("Manage Views", "Could not find current view declaration");
|
||||
}
|
||||
},
|
||||
on_sidebar_edit_workflow: function() {
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
<!-- vim:fdl=1:
|
||||
-->
|
||||
<templates id="template" xml:space="preserve">
|
||||
<t t-name="Interface">
|
||||
<div id="oe_loading" class="loading"></div>
|
||||
<div id="oe_notification" class="oe_notification">
|
||||
<t t-name="Notification">
|
||||
<div class="oe_notification">
|
||||
<div id="oe_notification_default">
|
||||
<a class="ui-notify-cross ui-notify-close" href="#">x</a>
|
||||
<h1>#{title}</h1>
|
||||
|
@ -17,6 +16,9 @@
|
|||
<p>#{text}</p>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="Interface">
|
||||
<div id="oe_loading" class="loading"></div>
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%" class="main_table">
|
||||
<tr>
|
||||
<td colspan="2" valign="top">
|
||||
|
@ -467,17 +469,20 @@
|
|||
</div>
|
||||
</t>
|
||||
<t t-name="Sidebar.section">
|
||||
<h2><t t-esc="name"/></h2>
|
||||
<div t-att-id="section_id" t-att-class="classname">
|
||||
<ul t-if="items">
|
||||
<h2><t t-esc="name"/></h2>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
|
||||
<t t-name="Sidebar.section.items">
|
||||
<li t-foreach="items" t-as="item" t-att-class="item.classname">
|
||||
<a class="oe_sidebar_action_a" t-att-id="item.element_id" t-att-title="item.title" href="#">
|
||||
<t t-esc="item.label"/>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="TranslateDialog">
|
||||
<ul class="oe_translate_tabs">
|
||||
<li><a t-attf-href="##{widget.element_id}_fields">Fields</a></li>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# French translation for openerp-web
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openerp-web package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openerp-web\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
|
||||
"PO-Revision-Date: 2011-10-12 05:03+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: French <fr@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-10-13 04:46+0000\n"
|
||||
"X-Generator: Launchpad (build 14124)\n"
|
||||
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
|
||||
msgid " "
|
||||
msgstr ""
|
|
@ -3,6 +3,7 @@
|
|||
*---------------------------------------------------------*/
|
||||
|
||||
openerp.web_calendar = function(openerp) {
|
||||
var _t = openerp.web._t;
|
||||
var QWeb = openerp.web.qweb;
|
||||
QWeb.add_template('/web_calendar/static/src/xml/web_calendar.xml');
|
||||
openerp.web.views.add('calendar', 'openerp.web_calendar.CalendarView');
|
||||
|
@ -84,8 +85,8 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
|
|||
if (this.options.sidebar && this.options.sidebar_id) {
|
||||
this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id);
|
||||
this.sidebar.start();
|
||||
this.sidebar.navigator = new openerp.web_calendar.SidebarNavigator(this.sidebar, this.sidebar.add_section('navigator', "Navigator"), this);
|
||||
this.sidebar.responsible = new openerp.web_calendar.SidebarResponsible(this.sidebar, this.sidebar.add_section('responsible', "Responsible"), this);
|
||||
this.sidebar.navigator = new openerp.web_calendar.SidebarNavigator(this.sidebar, this);
|
||||
this.sidebar.responsible = new openerp.web_calendar.SidebarResponsible(this.sidebar, this);
|
||||
this.sidebar.add_toolbar(this.fields_view.toolbar);
|
||||
this.set_common_sidebar_sections(this.sidebar);
|
||||
this.sidebar.do_unfold();
|
||||
|
@ -362,13 +363,16 @@ openerp.web_calendar.CalendarFormDialog = openerp.web.Dialog.extend({
|
|||
});
|
||||
|
||||
openerp.web_calendar.SidebarResponsible = openerp.web.Widget.extend({
|
||||
init: function(parent, element_id, view) {
|
||||
this._super(parent, element_id);
|
||||
init: function(parent, view) {
|
||||
var $section = parent.add_section(_t('Responsible'), 'responsible');
|
||||
this.$div = $('<div></div>');
|
||||
$section.append(this.$div);
|
||||
this._super(parent, $section.attr('id'));
|
||||
this.view = view;
|
||||
this.$element.delegate('input:checkbox', 'change', this.on_filter_click);
|
||||
},
|
||||
on_events_loaded: function(filters) {
|
||||
this.$element.html(QWeb.render('CalendarView.sidebar.responsible', { filters: filters }));
|
||||
this.$div.html(QWeb.render('CalendarView.sidebar.responsible', { filters: filters }));
|
||||
},
|
||||
on_filter_click: function(e) {
|
||||
var responsibles = [],
|
||||
|
@ -388,8 +392,9 @@ openerp.web_calendar.SidebarResponsible = openerp.web.Widget.extend({
|
|||
});
|
||||
|
||||
openerp.web_calendar.SidebarNavigator = openerp.web.Widget.extend({
|
||||
init: function(parent, element_id, view) {
|
||||
this._super(parent, element_id);
|
||||
init: function(parent, view) {
|
||||
var $section = parent.add_section(_t('Navigator'), 'navigator');
|
||||
this._super(parent, $section.attr('id'));
|
||||
this.view = view;
|
||||
},
|
||||
on_events_loaded: function(events) {
|
||||
|
|
|
@ -22,11 +22,7 @@ class Widgets(openerpweb.Controller):
|
|||
_cp_path = '/web_dashboard/widgets'
|
||||
|
||||
@openerpweb.httprequest
|
||||
def content(self, req, widget_id):
|
||||
Widget = req.session.model('res.widget')
|
||||
w = Widget.read([widget_id], ['content'], req.session.eval_context(req.context))
|
||||
if w:
|
||||
r = WIDGET_CONTENT_PATTERN % w[0]
|
||||
else:
|
||||
r = "Widget unavailable"
|
||||
return r
|
||||
def content(self, request, widget_id):
|
||||
return WIDGET_CONTENT_PATTERN % request.session.model('res.widget').read(
|
||||
[int(widget_id)], ['content'], request.session.eval_context(request.context)
|
||||
)[0]
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
# French translation for openerp-web
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openerp-web package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openerp-web\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||
"PO-Revision-Date: 2011-10-12 05:10+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: French <fr@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-10-13 04:46+0000\n"
|
||||
"X-Generator: Launchpad (build 14124)\n"
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Reset"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Undo"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Add Widget"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Change layout"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "Choose dashboard layout"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "progress:"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
|
||||
msgid "%"
|
||||
msgstr ""
|
|
@ -34,6 +34,10 @@
|
|||
-webkit-border-top-right-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
.openerp h2.oe-dashboard-action-header-empty {
|
||||
padding-top: 0;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.openerp a.oe-dashboard-action-rename {
|
||||
float: left;
|
||||
|
|
|
@ -420,18 +420,15 @@ openerp.web_dashboard.ApplicationTiles = openerp.web.View.extend({
|
|||
// Check for installed application
|
||||
var Installer = new openerp.web.DataSet(this, 'base.setup.installer');
|
||||
Installer.call('default_get', [], function (installed_modules) {
|
||||
var installed = false;
|
||||
_.each(installed_modules, function(v,k) {
|
||||
if(_.startsWith(k,"cat")) {
|
||||
installed =installed || v;
|
||||
}
|
||||
});
|
||||
var installed = _(installed_modules).any(function (active, name) {
|
||||
return _.startsWith(name, 'cat') && active; });
|
||||
|
||||
if(installed) {
|
||||
self.do_display_root_menu();
|
||||
} else {
|
||||
self.do_display_installer();
|
||||
}
|
||||
} );
|
||||
});
|
||||
},
|
||||
do_display_root_menu: function() {
|
||||
var self = this;
|
||||
|
@ -446,10 +443,8 @@ openerp.web_dashboard.ApplicationTiles = openerp.web.View.extend({
|
|||
self.$element.append(tiles)
|
||||
.find('.oe-dashboard-home-tile')
|
||||
.click(function () {
|
||||
var $this = $(this);
|
||||
$this.closest('.openerp')
|
||||
.find('.menu a[data-menu=' + $this.data('menuid') + ']')
|
||||
.click();});
|
||||
openerp.webclient.menu.on_menu_click(null, $(this).data('menuid'))
|
||||
});
|
||||
});
|
||||
return r;
|
||||
},
|
||||
|
@ -490,9 +485,8 @@ openerp.web_dashboard.ApplicationTiles = openerp.web.View.extend({
|
|||
var self = this;
|
||||
new openerp.web.DataSet(this, 'res.config').call('start', [[]], function (action) {
|
||||
$.unblockUI();
|
||||
self.do_action(action, function () {
|
||||
// TODO: less brutal reloading
|
||||
window.location.reload(true);
|
||||
self.widget_parent.widget_parent.do_action(action, function () {
|
||||
openerp.webclient.do_reload();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -30,9 +30,10 @@
|
|||
</t>
|
||||
<t t-name="DashBoard.action">
|
||||
<div t-att-data-id="action.attrs.name" class="oe-dashboard-action">
|
||||
<h2 class="oe-dashboard-action-header oe_view_title">
|
||||
<h2 t-attf-class="oe-dashboard-action-header oe_view_title #{action.attrs.string ? '' : 'oe-dashboard-action-header-empty'}">
|
||||
<input class="oe-dashboard-action-input" type="text" name="title" value="" style="display: none"/>
|
||||
<t t-esc="action.attrs.string"/>
|
||||
<t t-if="!action.attrs.string">&nbsp;</t>
|
||||
<span class='ui-icon ui-icon-closethick'></span>
|
||||
<span class='ui-icon ui-icon-minusthick oe-dashboard-fold' t-if="!action.attrs.fold"></span>
|
||||
<span class='ui-icon ui-icon-plusthick oe-dashboard-fold' t-if="action.attrs.fold"></span>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Danish translation for openerp-web
|
||||
# French translation for openerp-web
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openerp-web package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
|
@ -8,31 +8,31 @@ msgstr ""
|
|||
"Project-Id-Version: openerp-web\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
|
||||
"PO-Revision-Date: 2011-10-11 14:02+0000\n"
|
||||
"Last-Translator: Jonas Mortensen <Unknown>\n"
|
||||
"Language-Team: Danish <da@li.org>\n"
|
||||
"PO-Revision-Date: 2011-10-12 05:07+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: French <fr@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-10-12 04:44+0000\n"
|
||||
"X-Launchpad-Export-Date: 2011-10-13 04:46+0000\n"
|
||||
"X-Generator: Launchpad (build 14124)\n"
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Welcome to your new OpenERP instance."
|
||||
msgstr "Velkommen til din nye OpenERP instans."
|
||||
msgstr ""
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Remember to bookmark this page."
|
||||
msgstr "Husk at tilføje denne side til dine favoritter."
|
||||
msgstr ""
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Remember your login:"
|
||||
msgstr "Husk dit log ind:"
|
||||
msgstr ""
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Choose the first OpenERP Application you want to install.."
|
||||
msgstr "Vælg den første OpenERP Applikation som du ønsker at installere."
|
||||
msgstr ""
|
||||
|
||||
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
|
||||
msgid "Install"
|
||||
msgstr "Installér"
|
||||
msgstr ""
|
Loading…
Reference in New Issue