[MERGE] Latest bugfixes from 7.0, up to rev 3731
rev 3731 = revision-id: fme@openerp.com-20130129142638-81uffjq3aiopr8ta bzr revid: odo@openerp.com-20130129163725-feesf1n2xf0wbpro
This commit is contained in:
commit
02a6c638a9
|
@ -86,5 +86,4 @@ This module provides the core of the OpenERP Web Client.
|
|||
"static/test/mutex.js"
|
||||
],
|
||||
'bootstrap': True,
|
||||
'twitter': False,
|
||||
}
|
||||
|
|
|
@ -522,7 +522,7 @@ html_template = """<!DOCTYPE html>
|
|||
</head>
|
||||
<body>
|
||||
<!--[if lte IE 8]>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script>
|
||||
<script>CFInstall.check({mode: "overlay"});</script>
|
||||
<![endif]-->
|
||||
</body>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
.. _module:
|
||||
|
||||
Building an OpenERP Web module
|
||||
==============================
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ class OpenERPSession(object):
|
|||
self.jsonp_requests = {} # FIXME use a LRU
|
||||
|
||||
def send(self, service_name, method, *args):
|
||||
code_string = "warning -- %s\n\n%s"
|
||||
code_string = u"warning -- %s\n\n%s"
|
||||
try:
|
||||
return openerp.netsvc.dispatch_rpc(service_name, method, args)
|
||||
except openerp.osv.osv.except_osv, e:
|
||||
|
@ -95,13 +95,13 @@ class OpenERPSession(object):
|
|||
except openerp.exceptions.AccessError, e:
|
||||
raise xmlrpclib.Fault(code_string % ("AccessError", e), '')
|
||||
except openerp.exceptions.AccessDenied, e:
|
||||
raise xmlrpclib.Fault('AccessDenied', str(e))
|
||||
raise xmlrpclib.Fault('AccessDenied', openerp.tools.ustr(e))
|
||||
except openerp.exceptions.DeferredException, e:
|
||||
formatted_info = "".join(traceback.format_exception(*e.traceback))
|
||||
raise xmlrpclib.Fault(openerp.tools.ustr(e.message), formatted_info)
|
||||
raise xmlrpclib.Fault(openerp.tools.ustr(e), formatted_info)
|
||||
except Exception, e:
|
||||
formatted_info = "".join(traceback.format_exception(*(sys.exc_info())))
|
||||
raise xmlrpclib.Fault(openerp.tools.exception_to_unicode(e), formatted_info)
|
||||
raise xmlrpclib.Fault(openerp.tools.ustr(e), formatted_info)
|
||||
|
||||
def proxy(self, service):
|
||||
return Service(self, service)
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
Date.CultureInfo = {
|
||||
/* Culture Name */
|
||||
name: "am-ET",
|
||||
englishName: "Amharic (Ethiopia)",
|
||||
nativeName: "አምሃርኛ (ኢትዮጵያ)",
|
||||
|
||||
/* Day Name Strings */
|
||||
dayNames: ["እሁድ", "ሰኞ", "ማክሰኞ", "ረብዑ", "ሃሙስ", "ዓርብ", "ቅዳሜ"],
|
||||
abbreviatedDayNames: ["እሁድ", "ሰኞ", "ማክሰ", "ረብዑ", "ሃሙስ", "ዓርብ", "ቅዳሜ"],
|
||||
shortestDayNames: ["እሁ", "ሰኞ", "ማክ", "ረብ", "ሃሙ", "ዓር", "ቅዳ"],
|
||||
firstLetterDayNames: ["እ", "ሰ", "ማ", "ረ", "ሃ", "ዓ", "ቅ"],
|
||||
|
||||
/* Month Name Strings */
|
||||
monthNames: ["ጃንዋሪ", "ፌብሩዋሪ", "ማርች", "አፕሪል", "ሜይ", "ጁን", "ጁላይ", "ኦገስት", "ሴፕቴምበር", "ኦክቶበር", "ኖቬምበር", "ዲሴምበር"],
|
||||
abbreviatedMonthNames: ["ጃንዋ", "ፌብሩ", "ማርች", "አፕሪ", "ሜይ", "ጁን", "ጁላይ", "ኦገስ", "ሴፕቴ", "ኦክቶ", "ኖቬም", "ዲሴም"],
|
||||
|
||||
/* AM/PM Designators */
|
||||
amDesignator: "ከቀኑ",
|
||||
pmDesignator: "ከለሊቱ",
|
||||
|
||||
firstDayOfWeek: 1,
|
||||
twoDigitYearMax: 2029,
|
||||
|
||||
/**
|
||||
* The dateElementOrder is based on the order of the
|
||||
* format specifiers in the formatPatterns.DatePattern.
|
||||
*
|
||||
* Example:
|
||||
<pre>
|
||||
shortDatePattern dateElementOrder
|
||||
------------------ ----------------
|
||||
"M/d/yyyy" "mdy"
|
||||
"dd/MM/yyyy" "dmy"
|
||||
"yyyy-MM-dd" "ymd"
|
||||
</pre>
|
||||
*
|
||||
* The correct dateElementOrder is required by the parser to
|
||||
* determine the expected order of the date elements in the
|
||||
* string being parsed.
|
||||
*/
|
||||
dateElementOrder: "dmy",
|
||||
|
||||
/* Standard date and time format patterns */
|
||||
formatPatterns: {
|
||||
shortDate: "dd/MM/yyyy",
|
||||
longDate: "dd MMMM yyyy",
|
||||
shortTime: "HH:mm",
|
||||
longTime: "HH:mm:ss",
|
||||
fullDateTime: "dd MMMM yyyy HH:mm:ss",
|
||||
sortableDateTime: "yyyy-MM-ddTHH:mm:ss",
|
||||
universalSortableDateTime: "yyyy-MM-dd HH:mm:ssZ",
|
||||
rfc1123: "ddd, dd MMM yyyy HH:mm:ss GMT",
|
||||
monthDay: "dd MMMM",
|
||||
yearMonth: "MMMM yyyy"
|
||||
},
|
||||
|
||||
/**
|
||||
* NOTE: If a string format is not parsing correctly, but
|
||||
* you would expect it parse, the problem likely lies below.
|
||||
*
|
||||
* The following regex patterns control most of the string matching
|
||||
* within the parser.
|
||||
*
|
||||
* The Month name and Day name patterns were automatically generated
|
||||
* and in general should be (mostly) correct.
|
||||
*
|
||||
* Beyond the month and day name patterns are natural language strings.
|
||||
* Example: "next", "today", "months"
|
||||
*
|
||||
* These natural language string may NOT be correct for this culture.
|
||||
* If they are not correct, please translate and edit this file
|
||||
* providing the correct regular expression pattern.
|
||||
*
|
||||
* If you modify this file, please post your revised CultureInfo file
|
||||
* to the Datejs Forum located at http://www.datejs.com/forums/.
|
||||
*
|
||||
* Please mark the subject of the post with [CultureInfo]. Example:
|
||||
* Subject: [CultureInfo] Translated "da-DK" Danish(Denmark)
|
||||
*
|
||||
* We will add the modified patterns to the master source files.
|
||||
*
|
||||
* As well, please review the list of "Future Strings" section below.
|
||||
*/
|
||||
regexPatterns: {
|
||||
jan: /^jan(uary)?/i,
|
||||
feb: /^feb(ruary)?/i,
|
||||
mar: /^mar(ch)?/i,
|
||||
apr: /^apr(il)?/i,
|
||||
may: /^may/i,
|
||||
jun: /^jun(e)?/i,
|
||||
jul: /^jul(y)?/i,
|
||||
aug: /^aug(ust)?/i,
|
||||
sep: /^sep(t(ember)?)?/i,
|
||||
oct: /^oct(ober)?/i,
|
||||
nov: /^nov(ember)?/i,
|
||||
dec: /^dec(ember)?/i,
|
||||
|
||||
sun: /^su(n(day)?)?/i,
|
||||
mon: /^mo(n(day)?)?/i,
|
||||
tue: /^tu(e(s(day)?)?)?/i,
|
||||
wed: /^we(d(nesday)?)?/i,
|
||||
thu: /^th(u(r(s(day)?)?)?)?/i,
|
||||
fri: /^fr(i(day)?)?/i,
|
||||
sat: /^sa(t(urday)?)?/i,
|
||||
|
||||
future: /^next/i,
|
||||
past: /^last|past|prev(ious)?/i,
|
||||
add: /^(\+|aft(er)?|from|hence)/i,
|
||||
subtract: /^(\-|bef(ore)?|ago)/i,
|
||||
|
||||
yesterday: /^yes(terday)?/i,
|
||||
today: /^t(od(ay)?)?/i,
|
||||
tomorrow: /^tom(orrow)?/i,
|
||||
now: /^n(ow)?/i,
|
||||
|
||||
millisecond: /^ms|milli(second)?s?/i,
|
||||
second: /^sec(ond)?s?/i,
|
||||
minute: /^mn|min(ute)?s?/i,
|
||||
hour: /^h(our)?s?/i,
|
||||
week: /^w(eek)?s?/i,
|
||||
month: /^m(onth)?s?/i,
|
||||
day: /^d(ay)?s?/i,
|
||||
year: /^y(ear)?s?/i,
|
||||
|
||||
shortMeridian: /^(a|p)/i,
|
||||
longMeridian: /^(a\.?m?\.?|p\.?m?\.?)/i,
|
||||
timezone: /^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt|utc)/i,
|
||||
ordinalSuffix: /^\s*(st|nd|rd|th)/i,
|
||||
timeContext: /^\s*(\:|a(?!u|p)|p)/i
|
||||
},
|
||||
|
||||
timezones: [{name:"UTC", offset:"-000"}, {name:"GMT", offset:"-000"}, {name:"EST", offset:"-0500"}, {name:"EDT", offset:"-0400"}, {name:"CST", offset:"-0600"}, {name:"CDT", offset:"-0500"}, {name:"MST", offset:"-0700"}, {name:"MDT", offset:"-0600"}, {name:"PST", offset:"-0800"}, {name:"PDT", offset:"-0700"}]
|
||||
};
|
||||
|
||||
/********************
|
||||
** Future Strings **
|
||||
********************
|
||||
*
|
||||
* The following list of strings may not be currently being used, but
|
||||
* may be incorporated into the Datejs library later.
|
||||
*
|
||||
* We would appreciate any help translating the strings below.
|
||||
*
|
||||
* If you modify this file, please post your revised CultureInfo file
|
||||
* to the Datejs Forum located at http://www.datejs.com/forums/.
|
||||
*
|
||||
* Please mark the subject of the post with [CultureInfo]. Example:
|
||||
* Subject: [CultureInfo] Translated "da-DK" Danish(Denmark)b
|
||||
*
|
||||
* English Name Translated
|
||||
* ------------------ -----------------
|
||||
* about about
|
||||
* ago ago
|
||||
* date date
|
||||
* time time
|
||||
* calendar calendar
|
||||
* show show
|
||||
* hourly hourly
|
||||
* daily daily
|
||||
* weekly weekly
|
||||
* bi-weekly bi-weekly
|
||||
* fortnight fortnight
|
||||
* monthly monthly
|
||||
* bi-monthly bi-monthly
|
||||
* quarter quarter
|
||||
* quarterly quarterly
|
||||
* yearly yearly
|
||||
* annual annual
|
||||
* annually annually
|
||||
* annum annum
|
||||
* again again
|
||||
* between between
|
||||
* after after
|
||||
* from now from now
|
||||
* repeat repeat
|
||||
* times times
|
||||
* per per
|
||||
* min (abbrev minute) min
|
||||
* morning morning
|
||||
* noon noon
|
||||
* night night
|
||||
* midnight midnight
|
||||
* mid-night mid-night
|
||||
* evening evening
|
||||
* final final
|
||||
* future future
|
||||
* spring spring
|
||||
* summer summer
|
||||
* fall fall
|
||||
* winter winter
|
||||
* end of end of
|
||||
* end end
|
||||
* long long
|
||||
* short short
|
||||
*/
|
|
@ -1242,8 +1242,6 @@
|
|||
.openerp .oe_secondary_submenu {
|
||||
padding: 2px 0 8px 0;
|
||||
margin: 0;
|
||||
width: 220px;
|
||||
display: inline-block;
|
||||
}
|
||||
.openerp .oe_secondary_submenu li {
|
||||
position: relative;
|
||||
|
|
|
@ -1009,8 +1009,6 @@ $sheet-padding: 16px
|
|||
.oe_secondary_submenu
|
||||
padding: 2px 0 8px 0
|
||||
margin: 0
|
||||
width: 220px
|
||||
display: inline-block
|
||||
li
|
||||
position: relative
|
||||
margin: 0
|
||||
|
|
|
@ -481,6 +481,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
|
|||
self.do_action("reload");
|
||||
},
|
||||
},
|
||||
_push_me: false,
|
||||
};
|
||||
self.do_action(client_action);
|
||||
});
|
||||
|
@ -868,7 +869,7 @@ instance.web.Menu = instance.web.Widget.extend({
|
|||
this.needaction_data = data;
|
||||
_.each(this.needaction_data, function (item, menu_id) {
|
||||
var $item = self.$secondary_menus.find('a[data-menu="' + menu_id + '"]');
|
||||
$item.remove('oe_menu_counter');
|
||||
$item.find('.oe_menu_counter').remove();
|
||||
if (item.needaction_counter && item.needaction_counter > 0) {
|
||||
$item.append(QWeb.render("Menu.needaction_counter", { widget : item }));
|
||||
}
|
||||
|
@ -1395,13 +1396,9 @@ instance.web.WebClient = instance.web.Client.extend({
|
|||
});
|
||||
},
|
||||
set_content_full_screen: function(fullscreen) {
|
||||
if (fullscreen) {
|
||||
$(".oe_webclient", this.$el).addClass("oe_content_full_screen");
|
||||
$("body").css({'overflow-y':'hidden'});
|
||||
} else {
|
||||
$(".oe_webclient", this.$el).removeClass("oe_content_full_screen");
|
||||
$("body").css({'overflow-y':'scroll'});
|
||||
}
|
||||
$(document.body).css('overflow-y', fullscreen ? 'hidden' : 'scroll');
|
||||
this.$('.oe_webclient').toggleClass(
|
||||
'oe_content_full_screen', fullscreen);
|
||||
},
|
||||
has_uncommitted_changes: function() {
|
||||
var $e = $.Event('clear_uncommitted_changes');
|
||||
|
|
|
@ -166,9 +166,13 @@ instance.web.format_value = function (value, descriptor, value_if_empty) {
|
|||
value = Math.abs(value);
|
||||
pattern = '-' + pattern;
|
||||
}
|
||||
return _.str.sprintf(pattern,
|
||||
Math.floor(value),
|
||||
Math.round((value % 1) * 60));
|
||||
var hour = Math.floor(value);
|
||||
var min = Math.round((value % 1) * 60);
|
||||
if (min == 60){
|
||||
min = 0;
|
||||
hour = hour + 1;
|
||||
}
|
||||
return _.str.sprintf(pattern, hour, min);
|
||||
case 'many2one':
|
||||
// name_get value format
|
||||
return value[1] ? value[1].split("\n")[0] : value[1];
|
||||
|
|
|
@ -689,15 +689,14 @@ openerp.web.pyeval = function (instance) {
|
|||
};
|
||||
|
||||
instance.web.pyeval.context = function () {
|
||||
return {
|
||||
uid: py.float.fromJSON(instance.session.uid),
|
||||
return _.extend({
|
||||
datetime: datetime,
|
||||
context_today: context_today,
|
||||
time: time,
|
||||
relativedelta: relativedelta,
|
||||
current_date: py.PY_call(
|
||||
time.strftime, [py.str.fromJSON('%Y-%m-%d')]),
|
||||
};
|
||||
}, instance.session.user_context);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -127,41 +127,26 @@ my.InputView = instance.web.Widget.extend({
|
|||
events: {
|
||||
focus: function () { this.trigger('focused', this); },
|
||||
blur: function () { this.$el.text(''); this.trigger('blurred', this); },
|
||||
keydown: 'onKeydown'
|
||||
keydown: 'onKeydown',
|
||||
paste: 'onPaste',
|
||||
},
|
||||
getSelection: function () {
|
||||
// get Text node
|
||||
var root = this.$el[0].childNodes[0];
|
||||
var root = this.el.childNodes[0];
|
||||
if (!root || !root.textContent) {
|
||||
// if input does not have a child node, or the child node is an
|
||||
// empty string, then the selection can only be (0, 0)
|
||||
return {start: 0, end: 0};
|
||||
}
|
||||
if (window.getSelection) {
|
||||
var domRange = window.getSelection().getRangeAt(0);
|
||||
assert(domRange.startContainer === root,
|
||||
"selection should be in the input view");
|
||||
assert(domRange.endContainer === root,
|
||||
"selection should be in the input view");
|
||||
return {
|
||||
start: domRange.startOffset,
|
||||
end: domRange.endOffset
|
||||
}
|
||||
} else if (document.selection) {
|
||||
var ieRange = document.selection.createRange();
|
||||
var rangeParent = ieRange.parentElement();
|
||||
assert(rangeParent === root,
|
||||
"selection should be in the input view");
|
||||
var offsetRange = document.body.createTextRange();
|
||||
offsetRange = offsetRange.moveToElementText(rangeParent);
|
||||
offsetRange.setEndPoint("EndToStart", ieRange);
|
||||
var start = offsetRange.text.length;
|
||||
return {
|
||||
start: start,
|
||||
end: start + ieRange.text.length
|
||||
}
|
||||
var range = window.getSelection().getRangeAt(0);
|
||||
assert(range.startContainer === root,
|
||||
"selection should be in the input view");
|
||||
assert(range.endContainer === root,
|
||||
"selection should be in the input view");
|
||||
return {
|
||||
start: range.startOffset,
|
||||
end: range.endOffset
|
||||
}
|
||||
throw new Error("Could not get caret position");
|
||||
},
|
||||
onKeydown: function (e) {
|
||||
var sel;
|
||||
|
@ -199,6 +184,50 @@ my.InputView = instance.web.Widget.extend({
|
|||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
setCursorAtEnd: function () {
|
||||
var sel = window.getSelection();
|
||||
sel.removeAllRanges();
|
||||
var range = document.createRange();
|
||||
// in theory, range.selectNodeContents should work here. In practice,
|
||||
// MSIE9 has issues from time to time, instead of selecting the inner
|
||||
// text node it would select the reference node instead (e.g. in demo
|
||||
// data, company news, copy across the "Company News" link + the title,
|
||||
// from about half the link to half the text, paste in search box then
|
||||
// hit the left arrow key, getSelection would blow up).
|
||||
//
|
||||
// Explicitly selecting only the inner text node (only child node at
|
||||
// this point, though maybe we should assert that) avoiids the issue
|
||||
range.selectNode(this.el.childNodes[0]);
|
||||
range.collapse(false);
|
||||
sel.addRange(range);
|
||||
},
|
||||
onPaste: function () {
|
||||
// In MSIE and Webkit, it is possible to get various representations of
|
||||
// the clipboard data at this point e.g.
|
||||
// window.clipboardData.getData('Text') and
|
||||
// event.clipboardData.getData('text/plain') to ensure we have a plain
|
||||
// text representation of the object (and probably ensure the object is
|
||||
// pastable as well, so nobody puts an image in the search view)
|
||||
// (nb: since it's not possible to alter the content of the clipboard
|
||||
// — at least in Webkit — to ensure only textual content is available,
|
||||
// using this would require 1. getting the text data; 2. manually
|
||||
// inserting the text data into the content; and 3. cancelling the
|
||||
// paste event)
|
||||
//
|
||||
// But Firefox doesn't support the clipboard API (as of FF18)
|
||||
// although it correctly triggers the paste event (Opera does not even
|
||||
// do that) => implement lowest-denominator system where onPaste
|
||||
// triggers a followup "cleanup" pass after the data has been pasted
|
||||
setTimeout(function () {
|
||||
// Read text content (ignore pasted HTML)
|
||||
var data = this.$el.text();
|
||||
// paste raw text back in
|
||||
this.$el.empty().text(data);
|
||||
// Set the cursor at the end of the text, so the cursor is not lost
|
||||
// in some kind of error-spawning limbo.
|
||||
this.setCursorAtEnd();
|
||||
}.bind(this), 0);
|
||||
}
|
||||
});
|
||||
my.FacetView = instance.web.Widget.extend({
|
||||
|
@ -1572,6 +1601,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
|
|||
append_filter: function (filter) {
|
||||
var self = this;
|
||||
var key = this.key_for(filter);
|
||||
var warning = _t("This filter is global and will be removed for everybody if you continue.");
|
||||
|
||||
var $filter;
|
||||
if (key in this.$filters) {
|
||||
|
@ -1589,6 +1619,9 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
|
|||
$('<a class="oe_searchview_custom_delete">x</a>')
|
||||
.click(function (e) {
|
||||
e.stopPropagation();
|
||||
if (!(filter.user_id || confirm(warning))) {
|
||||
return;
|
||||
}
|
||||
self.model.call('unlink', [id]).done(function () {
|
||||
$filter.remove();
|
||||
delete self.$filters[key];
|
||||
|
@ -1711,10 +1744,12 @@ instance.web.search.Advanced = instance.web.search.Input.extend({
|
|||
});
|
||||
return $.when(
|
||||
this._super(),
|
||||
new instance.web.Model(this.view.model).call('fields_get').done(function(data) {
|
||||
self.fields = _.extend({
|
||||
id: { string: 'ID', type: 'id' }
|
||||
}, data);
|
||||
new instance.web.Model(this.view.model).call('fields_get', {
|
||||
context: this.view.dataset.context
|
||||
}).done(function(data) {
|
||||
self.fields = _.extend({
|
||||
id: { string: 'ID', type: 'id' }
|
||||
}, data);
|
||||
})).done(function () {
|
||||
self.append_proposition();
|
||||
});
|
||||
|
@ -1781,6 +1816,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; })
|
||||
.sortBy(function(field) {return field.string;})
|
||||
.value();
|
||||
this.attrs = {_: _, fields: this.fields, selected: null};
|
||||
|
|
|
@ -573,19 +573,14 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
|
|||
]
|
||||
});
|
||||
}
|
||||
if (result.domain) {
|
||||
function edit_domain(node) {
|
||||
if (typeof node !== "object") {
|
||||
return;
|
||||
}
|
||||
var new_domain = result.domain[node.attrs.name];
|
||||
if (new_domain) {
|
||||
node.attrs.domain = new_domain;
|
||||
}
|
||||
_(node.children).each(edit_domain);
|
||||
}
|
||||
edit_domain(this.fields_view.arch);
|
||||
}
|
||||
|
||||
var fields = this.fields;
|
||||
_(result.domain).each(function (domain, fieldname) {
|
||||
var field = fields[fieldname];
|
||||
if (!field) { return; }
|
||||
field.node.attrs.domain = domain;
|
||||
});
|
||||
|
||||
return $.Deferred().resolve();
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
|
|
|
@ -1414,8 +1414,6 @@
|
|||
this.removeAttr('t-if');
|
||||
</t>
|
||||
|
||||
<t t-jquery="tfoot > tr:last-child" t-operation="replace"/>
|
||||
|
||||
<t t-jquery="td.oe-actions">
|
||||
this.removeAttr('t-if');
|
||||
</t>
|
||||
|
|
|
@ -68,6 +68,12 @@ openerp.testing.section('web-formats', {
|
|||
strictEqual(
|
||||
instance.web.format_value(-0.0085, {type:'float', widget:'float_time'}),
|
||||
'-00:01');
|
||||
strictEqual(
|
||||
instance.web.format_value(4.9999, {type:'float', widget:'float_time'}),
|
||||
'05:00');
|
||||
strictEqual(
|
||||
instance.web.format_value(-6.9999, {type:'float', widget:'float_time'}),
|
||||
'-07:00');
|
||||
});
|
||||
test("format_float", function (instance) {
|
||||
var fl = 12.1234;
|
||||
|
|
|
@ -632,7 +632,7 @@ instance.web_kanban.KanbanGroup = instance.web.Widget.extend({
|
|||
'limit': self.view.limit,
|
||||
'offset': self.dataset_offset += self.view.limit
|
||||
}).then(function(records) {
|
||||
self.view.dataset.ids = ids.concat(self.view.dataset.ids);
|
||||
self.view.dataset.ids = ids.concat(self.dataset.ids);
|
||||
self.do_add_records(records);
|
||||
self.compute_cards_auto_height();
|
||||
return records;
|
||||
|
|
Loading…
Reference in New Issue