summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorParamjit Singh Sahota <psa@tinyerp.com>2013-05-17 11:01:30 +0530
committerParamjit Singh Sahota <psa@tinyerp.com>2013-05-17 11:01:30 +0530
commita031c86d68ad3ebaad2ea8381c8667ae92b14e19 (patch)
treef0bfa73ebe69ebc42fcf04ebe58976bc0239b571 /addons/web/static/src
parent876c7900775baa7a653983ba1049355497dcd439 (diff)
parentee262e156a19bceb961f62ea3912e362a11ddad3 (diff)
[MERGE] Merged lp:openerp-web/7.0
bzr revid: bth@tinyerp.com-20130417073823-qh3hzbj2j70kt6c6 bzr revid: psa@tinyerp.com-20130517053130-09k6t1os2x6g8i0j
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/css/base.css10
-rw-r--r--addons/web/static/src/css/base.sass4
-rw-r--r--[-rwxr-xr-x]addons/web/static/src/font/entypo-webfont.svg0
-rw-r--r--[-rwxr-xr-x]addons/web/static/src/font/mnmliconsv21-webfont.svg0
-rw-r--r--addons/web/static/src/js/chrome.js47
-rw-r--r--addons/web/static/src/js/coresetup.js8
-rw-r--r--addons/web/static/src/js/data.js48
-rw-r--r--addons/web/static/src/js/formats.js30
-rw-r--r--addons/web/static/src/js/search.js34
-rw-r--r--addons/web/static/src/js/view_form.js20
-rw-r--r--addons/web/static/src/js/view_list.js5
-rw-r--r--addons/web/static/src/js/views.js9
-rw-r--r--addons/web/static/src/xml/base.xml4
13 files changed, 159 insertions, 60 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index b4d6e7968b9..66997040bde 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -1269,7 +1269,7 @@
color: white;
padding: 2px 4px;
margin: 1px 6px 0 0;
- border: 1px solid lightGray;
+ border: 1px solid lightgrey;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
@@ -1301,7 +1301,7 @@
transform: scale(1.1);
}
.openerp .oe_secondary_submenu .oe_active {
- border-top: 1px solid lightGray;
+ border-top: 1px solid lightgrey;
border-bottom: 1px solid #dedede;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
-moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2), inset 0 -1px 3px rgba(40, 40, 40, 0.2);
@@ -2288,7 +2288,7 @@
}
.openerp .oe_form .oe_form_label_help[for] span, .openerp .oe_form .oe_form_label[for] span {
font-size: 80%;
- color: darkGreen;
+ color: darkgreen;
vertical-align: top;
position: relative;
top: -4px;
@@ -2472,10 +2472,10 @@
width: 7em;
}
.openerp .oe_form_editable .oe_form .oe_form_field_date input {
- width: 7.5em;
+ width: 100px;
}
.openerp .oe_form_editable .oe_form .oe_form_field_datetime input {
- width: 11.5em;
+ width: 150px;
}
.openerp .oe_hidden_input_file {
position: relative;
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index 52893fc77ca..3f4f3e58bbe 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -1959,9 +1959,9 @@ $sheet-padding: 16px
.oe_form_field_float input
width: 7em
.oe_form_field_date input
- width: 7.5em
+ width: 100px
.oe_form_field_datetime input
- width: 11.5em
+ width: 150px
// }}}
// FormView.fields_binary {{{
/* http://www.quirksmode.org/dom/inputfile.html
diff --git a/addons/web/static/src/font/entypo-webfont.svg b/addons/web/static/src/font/entypo-webfont.svg
index c24d92adb5f..c24d92adb5f 100755..100644
--- a/addons/web/static/src/font/entypo-webfont.svg
+++ b/addons/web/static/src/font/entypo-webfont.svg
diff --git a/addons/web/static/src/font/mnmliconsv21-webfont.svg b/addons/web/static/src/font/mnmliconsv21-webfont.svg
index 34b20ff992f..34b20ff992f 100755..100644
--- a/addons/web/static/src/font/mnmliconsv21-webfont.svg
+++ b/addons/web/static/src/font/mnmliconsv21-webfont.svg
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index ef045f07931..3944078a5a7 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -249,7 +249,9 @@ instance.web.CrashManager = instance.web.Class.extend({
}
// yes, exception handling is shitty
if (error.code === 300 && error.data && error.data.type == "client_exception" && error.data.debug.match("SessionExpiredException")) {
- this.show_warning({type: "Session Expired", data: { fault_code: "Your OpenERP session expired. Please refresh the current web page." }});
+ this.show_warning({type: "Session Expired", data: {
+ fault_code: _t("Your OpenERP session expired. Please refresh the current web page.")
+ }});
return;
}
if (error.data.fault_code) {
@@ -861,9 +863,7 @@ instance.web.Menu = instance.web.Widget.extend({
self.reflow();
// launch the fetch of needaction counters, asynchronous
if (!_.isEmpty(menu_data.all_menu_ids)) {
- this.rpc("/web/menu/load_needaction", {menu_ids: menu_data.all_menu_ids}).done(function(r) {
- self.on_needaction_loaded(r);
- });
+ this.do_load_needaction(menu_data.all_menu_ids);
}
});
var lazyreflow = _.debounce(this.reflow.bind(this), 200);
@@ -889,7 +889,7 @@ instance.web.Menu = instance.web.Widget.extend({
this.data = {data: data};
this.renderElement();
this.$secondary_menus.html(QWeb.render("Menu.secondary", { widget : this }));
- this.$el.on('click', 'a[data-menu]', this.on_menu_click);
+ this.$el.on('click', 'a[data-menu]', this.on_top_menu_click);
// Hide second level submenus
this.$secondary_menus.find('.oe_menu_toggler').siblings('.oe_secondary_submenu').hide();
if (self.current_menu) {
@@ -898,6 +898,16 @@ instance.web.Menu = instance.web.Widget.extend({
this.trigger('menu_loaded', data);
this.has_been_loaded.resolve();
},
+ do_load_needaction: function (menu_ids) {
+ var self = this;
+ menu_ids = _.compact(menu_ids);
+ if (_.isEmpty(menu_ids)) {
+ return $.when();
+ }
+ return this.rpc("/web/menu/load_needaction", {'menu_ids': menu_ids}).done(function(r) {
+ self.on_needaction_loaded(r);
+ });
+ },
on_needaction_loaded: function(data) {
var self = this;
this.needaction_data = data;
@@ -1029,11 +1039,38 @@ instance.web.Menu = instance.web.Widget.extend({
}
this.open_menu(id);
},
+ do_reload_needaction: function () {
+ var self = this;
+ if (self.current_menu) {
+ self.do_load_needaction([self.current_menu]).then(function () {
+ self.trigger("need_action_reloaded");
+ });
+ }
+ },
/**
* Jquery event handler for menu click
*
* @param {Event} ev the jquery event
*/
+ on_top_menu_click: function(ev) {
+ var self = this;
+ var id = $(ev.currentTarget).data('menu');
+ var menu_ids = [id];
+ var menu = _.filter(this.data.data.children, function (menu) {return menu.id == id;})[0];
+ function add_menu_ids (menu) {
+ if (menu.children) {
+ _.each(menu.children, function (menu) {
+ menu_ids.push(menu.id);
+ add_menu_ids(menu);
+ });
+ }
+ };
+ add_menu_ids(menu);
+ self.do_load_needaction(menu_ids).then(function () {
+ self.trigger("need_action_reloaded");
+ });
+ this.on_menu_click(ev);
+ },
on_menu_click: function(ev) {
ev.preventDefault();
var needaction = $(ev.target).is('div.oe_menu_counter');
diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js
index dedb4a49710..6fc837333b6 100644
--- a/addons/web/static/src/js/coresetup.js
+++ b/addons/web/static/src/js/coresetup.js
@@ -555,19 +555,19 @@ instance.web.qweb.default_dict = {
instance.web.qweb.preprocess_node = function() {
// Note that 'this' is the Qweb Node
switch (this.node.nodeType) {
- case 3:
- case 4:
+ case Node.TEXT_NODE:
+ case Node.CDATA_SECTION_NODE:
// Text and CDATAs
var translation = this.node.parentNode.attributes['t-translation'];
if (translation && translation.value === 'off') {
return;
}
- var match = /^(\s*)(.+?)(\s*)$/.exec(this.node.data);
+ var match = /^(\s*)([\s\S]+?)(\s*)$/.exec(this.node.data);
if (match) {
this.node.data = match[1] + instance.web._t(match[2]) + match[3];
}
break;
- case 1:
+ case Node.ELEMENT_NODE:
// Element
var attr, attrs = ['label', 'title', 'alt', 'placeholder'];
while (attr = attrs.pop()) {
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index f1b043bacf9..d60f72c6577 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -112,24 +112,27 @@ instance.web.Query = instance.web.Class.extend({
* @returns {jQuery.Deferred<Array<openerp.web.QueryGroup>> | null}
*/
group_by: function (grouping) {
- if (grouping === undefined) {
- return null;
+ var ctx = instance.web.pyeval.eval(
+ 'context', this._model.context(this._context));
+
+ // undefined passed in explicitly (!)
+ if (_.isUndefined(grouping)) {
+ grouping = [];
}
if (!(grouping instanceof Array)) {
grouping = _.toArray(arguments);
}
- if (_.isEmpty(grouping)) { return null; }
+ if (_.isEmpty(grouping) && !ctx['group_by_no_leaf']) {
+ return null;
+ }
var self = this;
-
- var ctx = instance.web.pyeval.eval(
- 'context', this._model.context(this._context));
return this._model.call('read_group', {
groupby: grouping,
fields: _.uniq(grouping.concat(this._fields || [])),
domain: this._model.domain(this._filter),
- context: this._model.context(this._context),
+ context: ctx,
offset: this._offset,
limit: this._limit,
orderby: instance.web.serialize_sort(this._order_by) || false
@@ -325,7 +328,7 @@ instance.web.Model = instance.web.Class.extend({
* Fetches the model's domain, combined with the provided domain if any
*
* @param {Array} [domain] to combine with the model's internal domain
- * @returns The model's internal domain, or the AND-ed union of the model's internal domain and the provided domain
+ * @returns {instance.web.CompoundDomain} The model's internal domain, or the AND-ed union of the model's internal domain and the provided domain
*/
domain: function (domain) {
if (!domain) { return this._domain; }
@@ -337,7 +340,7 @@ instance.web.Model = instance.web.Class.extend({
* combined with the provided context if any
*
* @param {Object} [context] to combine with the model's internal context
- * @returns The union of the user's context and the model's internal context, as well as the provided context if any. In that order.
+ * @returns {instance.web.CompoundContext} The union of the user's context and the model's internal context, as well as the provided context if any. In that order.
*/
context: function (context) {
return new instance.web.CompoundContext(
@@ -604,6 +607,9 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin,
alter_ids: function(n_ids) {
this.ids = n_ids;
},
+ remove_ids: function (ids) {
+ this.alter_ids(_(this.ids).difference(ids));
+ },
/**
* Resequence records.
*
@@ -701,22 +707,28 @@ instance.web.DataSetSearch = instance.web.DataSet.extend({
get_domain: function (other_domain) {
this._model.domain(other_domain);
},
+ alter_ids: function (ids) {
+ this._super(ids);
+ if (this.index !== null && this.index >= this.ids.length) {
+ this.index = this.ids.length > 0 ? this.ids.length - 1 : 0;
+ }
+ },
+ remove_ids: function (ids) {
+ var before = this.ids.length;
+ this._super(ids);
+ if (this._length) {
+ this._length -= (before - this.ids.length);
+ }
+ },
unlink: function(ids, callback, error_callback) {
var self = this;
return this._super(ids).done(function(result) {
- self.ids = _(self.ids).difference(ids);
- if (self._length) {
- self._length -= 1;
- }
- if (self.index !== null) {
- self.index = self.index <= self.ids.length - 1 ?
- self.index : (self.ids.length > 0 ? self.ids.length -1 : 0);
- }
+ self.remove_ids( ids);
self.trigger("dataset_changed", ids, callback, error_callback);
});
},
size: function () {
- if (this._length !== undefined) {
+ if (this._length != null) {
return this._length;
}
return this._super();
diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js
index 851b60af229..854c5f76218 100644
--- a/addons/web/static/src/js/formats.js
+++ b/addons/web/static/src/js/formats.js
@@ -314,4 +314,34 @@ instance.web.auto_date_to_str = function(value, type) {
}
};
+/**
+ * performs a half up rounding with arbitrary precision, correcting for float loss of precision
+ * See the corresponding float_round() in server/tools/float_utils.py for more info
+ * @param {Number} the value to be rounded
+ * @param {Number} a non zero precision parameter. eg: 0.01 rounds to two digits.
+ */
+instance.web.round_precision = function(value, precision){
+ if(!value){
+ return 0;
+ }else if(!precision){
+ throw new Error('round_precision(...): Cannot round value: '+value+' with a precision of zero (or undefined)');
+ }
+ var normalized_value = value / precision;
+ var epsilon_magnitude = Math.log(Math.abs(normalized_value))/Math.log(2);
+ var epsilon = Math.pow(2, epsilon_magnitude - 53);
+ normalized_value += normalized_value >= 0 ? epsilon : -epsilon;
+ var rounded_value = Math.round(normalized_value);
+ return rounded_value * precision;
+};
+
+/**
+ * performs a half up rounding with a fixed amount of decimals, correcting for float loss of precision
+ * See the corresponding float_round() in server/tools/float_utils.py for more info
+ * @param {Number} the value to be rounded
+ * @param {Number} the number of decimals. eg: round_decimals(3.141592,2) -> 3.14
+ */
+instance.web.round_decimals = function(value, decimals){
+ return instance.web.round_precision(value, Math.pow(10,-decimals));
+};
+
};
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index c284dcb513b..e84a9472ff3 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -326,7 +326,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
}
},
'autocompleteopen': function () {
- this.$el.autocomplete('widget').css('z-index', 3);
+ this.$el.autocomplete('widget').css('z-index', 1004);
},
},
/**
@@ -1346,20 +1346,22 @@ instance.web.search.CharField = instance.web.search.Field.extend( /** @lends ins
}
});
instance.web.search.NumberField = instance.web.search.Field.extend(/** @lends instance.web.search.NumberField# */{
- value_from: function () {
- if (!this.$el.val()) {
- return null;
- }
- var val = this.parse(this.$el.val()),
- check = Number(this.$el.val());
- if (isNaN(val) || val !== check) {
- this.$el.addClass('error');
- throw new instance.web.search.Invalid(
- this.attrs.name, this.$el.val(), this.error_message);
- }
- this.$el.removeClass('error');
- return val;
- }
+ complete: function (value) {
+ var val = this.parse(value);
+ if (isNaN(val)) { return $.when(); }
+ var label = _.str.sprintf(
+ _t("Search %(field)s for: %(value)s"), {
+ field: '<em>' + this.attrs.string + '</em>',
+ value: '<strong>' + _.str.escapeHTML(value) + '</strong>'});
+ return $.when([{
+ label: label,
+ facet: {
+ category: this.attrs.string,
+ field: this,
+ values: [{label: value, value: val}]
+ }
+ }]);
+ },
});
/**
* @class
@@ -1897,7 +1899,7 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
this._super(parent);
this.fields = _(fields).chain()
.map(function(val, key) { return _.extend({}, val, {'name': key}); })
- .filter(function (field) { return !field.deprecated; })
+ .filter(function (field) { return !field.deprecated && (field.store === void 0 || field.store || field.fnct_search); })
.sortBy(function(field) {return field.string;})
.value();
this.attrs = {_: _, fields: this.fields, selected: null};
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index a2091bb5c40..b9dfa8e284a 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -91,6 +91,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
init: function(parent, dataset, view_id, options) {
var self = this;
this._super(parent);
+ this.ViewManager = parent;
this.set_default_options(options);
this.dataset = dataset;
this.model = dataset.model;
@@ -720,6 +721,8 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
return this.save().done(function(result) {
self.trigger("save", result);
self.to_view_mode();
+ }).then(function(result) {
+ self.ViewManager.ActionManager.__parentedParent.menu.do_reload_needaction();
});
},
on_button_cancel: function(event) {
@@ -765,7 +768,11 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
this.has_been_loaded.done(function() {
if (self.datarecord.id && confirm(_t("Do you really want to delete this record?"))) {
self.dataset.unlink([self.datarecord.id]).done(function() {
- self.execute_pager_action('next');
+ if (self.dataset.size()) {
+ self.execute_pager_action('next');
+ } else {
+ self.do_action('history_back');
+ }
def.resolve();
});
} else {
@@ -802,6 +809,8 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
if (save_obj.error)
return $.Deferred().reject();
return $.when.apply($, save_obj.ret);
+ }).done(function() {
+ self.$el.removeClass('oe_form_dirty');
});
},
_process_save: function(save_obj) {
@@ -1444,6 +1453,9 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
$(this).children().each(function() {
var $td = $(this),
$child = $td.children(':first');
+ if ($child.attr('cell-class')) {
+ $td.addClass($child.attr('cell-class'));
+ }
switch ($child[0].tagName.toLowerCase()) {
case 'separator':
break;
@@ -1520,7 +1532,7 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
if (! page.__ic)
return;
page.__ic.on("change:effective_invisible", null, function() {
- if (!page.__ic.get('effective_invisible')) {
+ if (!page.__ic.get('effective_invisible') && page.autofocus) {
$new_notebook.tabs('select', i);
return;
}
@@ -2126,7 +2138,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w
value without triggering a re-rendering.
*/
internal_set_value: function(value_) {
- var tmp = this.no_render;
+ var tmp = this.no_rerender;
this.no_rerender = true;
this.set({'value': value_});
this.no_rerender = tmp;
@@ -3281,7 +3293,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
}
if (! no_recurse) {
var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context());
- dataset.name_get([self.get("value")]).done(function(data) {
+ this.alive(dataset.name_get([self.get("value")])).done(function(data) {
self.display_value["" + self.get("value")] = data[0][1];
self.render_value(true);
});
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index 3c89ef7126e..b96079d2051 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -895,8 +895,9 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web.
this.record_callbacks = {
'remove': function (event, record) {
- var $row = self.$current.children(
- '[data-id=' + record.get('id') + ']');
+ var id = record.get('id');
+ self.dataset.remove_ids([id])
+ var $row = self.$current.children('[data-id=' + id + ']');
var index = $row.data('index');
$row.remove();
},
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index 0a7250397f7..f9050369a83 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -521,6 +521,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
return x;
}
});
+ this.ActionManager = parent;
this.views = {};
this.flags = flags || {};
this.registry = instance.web.views;
@@ -1259,6 +1260,7 @@ instance.web.View = instance.web.Widget.extend({
view_type: undefined,
init: function(parent, dataset, view_id, options) {
this._super(parent);
+ this.ViewManager = parent;
this.dataset = dataset;
this.view_id = view_id;
this.set_default_options(options);
@@ -1330,7 +1332,6 @@ instance.web.View = instance.web.Widget.extend({
}
};
var context = new instance.web.CompoundContext(dataset.get_context(), action_data.context || {});
-
var handler = function (action) {
if (action && action.constructor == Object) {
var ncontext = new instance.web.CompoundContext(context);
@@ -1367,7 +1368,11 @@ instance.web.View = instance.web.Widget.extend({
}
}
args.push(context);
- return dataset.call_button(action_data.name, args).then(handler);
+ return dataset.call_button(action_data.name, args).then(handler).then(function () {
+ if (instance.webclient) {
+ instance.webclient.menu.do_reload_needaction();
+ }
+ });
} else if (action_data.type=="action") {
return this.rpc('/web/action/load', {
action_id: action_data.name,
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index c9adc91a6ad..9c0e3fa249f 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -650,7 +650,7 @@
<li t-if="section.name == 'files'" class="oe_sidebar_add_attachment">
<t t-call="HiddenInputFile">
<t t-set="fileupload_id" t-value="widget.fileupload_id"/>
- <t t-set="fileupload_action">/web/binary/upload_attachment</t>
+ <t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t>
<input type="hidden" name="model" t-att-value="widget.dataset and widget.dataset.model"/>
<input type="hidden" name="id" t-att-value="widget.model_id"/>
<input type="hidden" name="session_id" t-att-value="widget.session.session_id"/>
@@ -739,7 +739,7 @@
<td t-foreach="aggregate_columns" t-as="column" class="oe_list_footer oe_number"
t-att-data-field="column.id" t-att-title="column.label">
</td>
- <td t-if="options.deletable"/>
+ <td t-if="options.deletable" class="oe_list_record_delete"/>
</tr>
</tfoot>
</table>