[MERGE] merge with trunk upto revision no 632.
bzr revid: ysa@tinyerp.com-20110715045307-omm1jnigcnwy48gn
This commit is contained in:
@@ -508,7 +508,7 @@ class DataSet(openerpweb.Controller):
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def call(self, req, model, method, args, domain_id=None, context_id=None):
|
||||
return {'result': self.call_common(req, model, method, args, domain_id, context_id)}
|
||||
return self.call_common(req, model, method, args, domain_id, context_id)
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def call_button(self, req, model, method, args, domain_id=None, context_id=None):
|
||||
@@ -524,20 +524,19 @@ class DataSet(openerpweb.Controller):
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def default_get(self, req, model, fields):
|
||||
m = req.session.model(model)
|
||||
r = m.default_get(fields, req.session.eval_context(req.context))
|
||||
return {'result': r}
|
||||
Model = req.session.model(model)
|
||||
return Model.default_get(fields, req.session.eval_context(req.context))
|
||||
|
||||
class DataGroup(openerpweb.Controller):
|
||||
_cp_path = "/base/group"
|
||||
@openerpweb.jsonrequest
|
||||
def read(self, request, model, fields, group_by_fields, domain=None):
|
||||
def read(self, request, model, fields, group_by_fields, domain=None, sort=None):
|
||||
Model = request.session.model(model)
|
||||
context, domain = eval_context_and_domain(request.session, request.context, domain)
|
||||
|
||||
return Model.read_group(
|
||||
domain or [], fields, group_by_fields, 0, False,
|
||||
dict(context, group_by=group_by_fields))
|
||||
dict(context, group_by=group_by_fields), sort or False)
|
||||
|
||||
class View(openerpweb.Controller):
|
||||
_cp_path = "/base/view"
|
||||
@@ -570,10 +569,15 @@ class View(openerpweb.Controller):
|
||||
else:
|
||||
xml = ElementTree.fromstring(arch)
|
||||
fvg['arch'] = Xml2Json.convert_element(xml)
|
||||
for field in fvg['fields'].values():
|
||||
if field.has_key('views') and field['views']:
|
||||
for view in field["views"].values():
|
||||
|
||||
for field in fvg['fields'].itervalues():
|
||||
if field.get('views'):
|
||||
for view in field["views"].itervalues():
|
||||
self.process_view(session, view, None, transform)
|
||||
if field.get('domain'):
|
||||
field["domain"] = self.parse_domain(field["domain"], session)
|
||||
if field.get('context'):
|
||||
field["context"] = self.parse_context(field["context"], session)
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def add_custom(self, request, view_id, arch):
|
||||
@@ -611,27 +615,38 @@ class View(openerpweb.Controller):
|
||||
self.parse_domains_and_contexts(elem, session)
|
||||
return root
|
||||
|
||||
def parse_domain(self, elem, attr_name, session):
|
||||
""" Parses an attribute of the provided name as a domain, transforms it
|
||||
def parse_domain(self, domain, session):
|
||||
""" Parses an arbitrary string containing a domain, transforms it
|
||||
to either a literal domain or a :class:`openerpweb.nonliterals.Domain`
|
||||
|
||||
:param elem: the node being parsed
|
||||
:type param: xml.etree.ElementTree.Element
|
||||
:param str attr_name: the name of the attribute which should be parsed
|
||||
:param domain: the domain to parse, if the domain is not a string it is assumed to
|
||||
be a literal domain and is returned as-is
|
||||
:param session: Current OpenERP session
|
||||
:type session: openerpweb.openerpweb.OpenERPSession
|
||||
"""
|
||||
domain = elem.get(attr_name, '').strip()
|
||||
if domain:
|
||||
try:
|
||||
elem.set(
|
||||
attr_name,
|
||||
openerpweb.ast.literal_eval(
|
||||
domain))
|
||||
except ValueError:
|
||||
# not a literal
|
||||
elem.set(attr_name,
|
||||
openerpweb.nonliterals.Domain(session, domain))
|
||||
if not isinstance(domain, (str, unicode)):
|
||||
return domain
|
||||
try:
|
||||
return openerpweb.ast.literal_eval(domain)
|
||||
except ValueError:
|
||||
# not a literal
|
||||
return openerpweb.nonliterals.Domain(session, domain)
|
||||
|
||||
def parse_context(self, context, session):
|
||||
""" Parses an arbitrary string containing a context, transforms it
|
||||
to either a literal context or a :class:`openerpweb.nonliterals.Context`
|
||||
|
||||
:param context: the context to parse, if the context is not a string it is assumed to
|
||||
be a literal domain and is returned as-is
|
||||
:param session: Current OpenERP session
|
||||
:type session: openerpweb.openerpweb.OpenERPSession
|
||||
"""
|
||||
if not isinstance(context, (str, unicode)):
|
||||
return context
|
||||
try:
|
||||
return openerpweb.ast.literal_eval(context)
|
||||
except ValueError:
|
||||
return openerpweb.nonliterals.Context(session, context)
|
||||
|
||||
def parse_domains_and_contexts(self, elem, session):
|
||||
""" Converts domains and contexts from the view into Python objects,
|
||||
@@ -644,18 +659,14 @@ class View(openerpweb.Controller):
|
||||
non-literal objects
|
||||
:type session: openerpweb.openerpweb.OpenERPSession
|
||||
"""
|
||||
self.parse_domain(elem, 'domain', session)
|
||||
self.parse_domain(elem, 'filter_domain', session)
|
||||
for el in ['domain', 'filter_domain']:
|
||||
domain = elem.get(el, '').strip()
|
||||
if domain:
|
||||
elem.set(el, self.parse_domain(domain, session))
|
||||
for el in ['context', 'default_get']:
|
||||
context_string = elem.get(el, '').strip()
|
||||
if context_string:
|
||||
try:
|
||||
elem.set(el,
|
||||
openerpweb.ast.literal_eval(context_string))
|
||||
except ValueError:
|
||||
elem.set(el,
|
||||
openerpweb.nonliterals.Context(
|
||||
session, context_string))
|
||||
elem.set(el, self.parse_context(context_string, session))
|
||||
|
||||
class FormView(View):
|
||||
_cp_path = "/base/formview"
|
||||
|
||||
@@ -577,6 +577,10 @@ background: linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%,
|
||||
display: none;
|
||||
}
|
||||
|
||||
.openerp .searchview_extended_delete_prop {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.openerp .searchview_extended_delete_group span,
|
||||
.openerp .searchview_extended_delete_prop span {
|
||||
font-size: 0.9em;
|
||||
@@ -609,10 +613,14 @@ background: linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%,
|
||||
.openerp .oe-listview td.oe-record-delete {
|
||||
text-align: right;
|
||||
}
|
||||
.openerp .oe-listview th.oe-sortable,
|
||||
.openerp .oe-listview th.oe-sortable .ui-icon {
|
||||
.openerp .oe-listview th.oe-sortable {
|
||||
cursor: pointer;
|
||||
}
|
||||
.openerp .oe-listview th.oe-sortable .ui-icon {
|
||||
height: 1em;
|
||||
display: inline;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.openerp .oe-listview .oe-field-cell {
|
||||
cursor: pointer;
|
||||
|
||||
@@ -365,7 +365,7 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b
|
||||
params: params,
|
||||
id:null
|
||||
}).then(function () {deferred.resolve.apply(deferred, arguments);},
|
||||
function(error) {deferred.reject(error, $.Event());});
|
||||
function(error) {deferred.reject(error, $.Event());});
|
||||
return deferred.fail(function() {
|
||||
deferred.fail(function(error, event) {
|
||||
if (!event.isDefaultPrevented()) {
|
||||
@@ -398,31 +398,35 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b
|
||||
}, url);
|
||||
var deferred = $.Deferred();
|
||||
$.ajax(ajax).done(function(response, textStatus, jqXHR) {
|
||||
self.on_rpc_response();
|
||||
if (response.error) {
|
||||
if (response.error.data.type == "session_invalid") {
|
||||
self.uid = false;
|
||||
self.on_session_invalid(function() {
|
||||
self.rpc(url, payload.params,
|
||||
function() {deferred.resolve.apply(deferred, arguments);},
|
||||
function(error, event) {event.preventDefault();
|
||||
deferred.reject.apply(deferred, arguments);});
|
||||
});
|
||||
} else {
|
||||
deferred.reject(response.error);
|
||||
}
|
||||
} else {
|
||||
deferred.resolve(response["result"], textStatus, jqXHR);
|
||||
}
|
||||
}).fail(function(jqXHR, textStatus, errorThrown) {
|
||||
self.on_rpc_response();
|
||||
var error = {
|
||||
code: -32098,
|
||||
message: "XmlHttpRequestError " + errorThrown,
|
||||
data: {type: "xhr"+textStatus, debug: jqXHR.responseText, objects: [jqXHR, errorThrown] }
|
||||
};
|
||||
deferred.reject(error);
|
||||
self.on_rpc_response();
|
||||
if (!response.error) {
|
||||
deferred.resolve(response["result"], textStatus, jqXHR);
|
||||
return;
|
||||
}
|
||||
if (response.error.data.type !== "session_invalid") {
|
||||
deferred.reject(response.error);
|
||||
return;
|
||||
}
|
||||
self.uid = false;
|
||||
self.on_session_invalid(function() {
|
||||
self.rpc(url, payload.params,
|
||||
function() {
|
||||
deferred.resolve.apply(deferred, arguments);
|
||||
},
|
||||
function(error, event) {
|
||||
event.preventDefault();
|
||||
deferred.reject.apply(deferred, arguments);
|
||||
});
|
||||
});
|
||||
}).fail(function(jqXHR, textStatus, errorThrown) {
|
||||
self.on_rpc_response();
|
||||
var error = {
|
||||
code: -32098,
|
||||
message: "XmlHttpRequestError " + errorThrown,
|
||||
data: {type: "xhr"+textStatus, debug: jqXHR.responseText, objects: [jqXHR, errorThrown] }
|
||||
};
|
||||
deferred.reject(error);
|
||||
});
|
||||
return deferred.promise();
|
||||
},
|
||||
on_rpc_request: function() {
|
||||
|
||||
@@ -1,6 +1,23 @@
|
||||
|
||||
openerp.base.data = function(openerp) {
|
||||
|
||||
/**
|
||||
* Serializes the sort criterion array of a dataset into a form which can be
|
||||
* consumed by OpenERP's RPC APIs.
|
||||
*
|
||||
* @param {Array} criterion array of fields, from first to last criteria, prefixed with '-' for reverse sorting
|
||||
* @returns {String} SQL-like sorting string (``ORDER BY``) clause
|
||||
*/
|
||||
openerp.base.serialize_sort = function (criterion) {
|
||||
return _.map(criterion,
|
||||
function (criteria) {
|
||||
if (criteria[0] === '-') {
|
||||
return criteria.slice(1) + ' DESC';
|
||||
}
|
||||
return criteria + ' ASC';
|
||||
}).join(', ');
|
||||
};
|
||||
|
||||
openerp.base.DataGroup = openerp.base.Controller.extend( /** @lends openerp.base.DataGroup# */{
|
||||
/**
|
||||
* Management interface between views and grouped collections of OpenERP
|
||||
@@ -130,7 +147,8 @@ openerp.base.ContainerDataGroup = openerp.base.DataGroup.extend(
|
||||
context: this.context,
|
||||
domain: this.domain,
|
||||
fields: _.uniq(this.group_by.concat(fields)),
|
||||
group_by_fields: this.group_by
|
||||
group_by_fields: this.group_by,
|
||||
sort: openerp.base.serialize_sort(this.sort)
|
||||
}, function () { }).then(function (response) {
|
||||
var data_groups = _(response).map(
|
||||
_.bind(self.transform_group, self));
|
||||
@@ -174,7 +192,7 @@ openerp.base.ContainerDataGroup = openerp.base.DataGroup.extend(
|
||||
self.session, self.model, group.__domain,
|
||||
child_context, child_context.group_by,
|
||||
self.level + 1),
|
||||
group);
|
||||
group, {sort: self.sort});
|
||||
}));
|
||||
});
|
||||
}
|
||||
@@ -197,8 +215,8 @@ openerp.base.GrouplessDataGroup = openerp.base.DataGroup.extend(
|
||||
},
|
||||
list: function (fields, ifGroups, ifRecords) {
|
||||
ifRecords(_.extend(
|
||||
new openerp.base.DataSetSearch(this.session, this.model),
|
||||
{domain: this.domain, context: this.context}));
|
||||
new openerp.base.DataSetSearch(this.session, this.model),
|
||||
{domain: this.domain, context: this.context, _sort: this.sort}));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -378,7 +396,7 @@ openerp.base.DataSetStatic = openerp.base.DataSet.extend({
|
||||
var self = this;
|
||||
offset = offset || 0;
|
||||
var end_pos = limit && limit !== -1 ? offset + limit : undefined;
|
||||
this.read_ids(this.ids.slice(offset, end_pos), fields, callback);
|
||||
return this.read_ids(this.ids.slice(offset, end_pos), fields, callback);
|
||||
},
|
||||
set_ids: function (ids) {
|
||||
this.ids = ids;
|
||||
@@ -415,7 +433,7 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
|
||||
// return read_ids(ids.slice(start,start+limit),fields,callback)
|
||||
}
|
||||
}
|
||||
this.rpc('/base/dataset/search_read', {
|
||||
return this.rpc('/base/dataset/search_read', {
|
||||
model: this.model,
|
||||
fields: fields,
|
||||
domain: this.domain,
|
||||
@@ -426,7 +444,9 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
|
||||
}, function (result) {
|
||||
self.ids = result.ids;
|
||||
self.offset = offset;
|
||||
callback(result.records);
|
||||
if (callback) {
|
||||
callback(result.records);
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
@@ -444,16 +464,12 @@ openerp.base.DataSetSearch = openerp.base.DataSet.extend({
|
||||
*/
|
||||
sort: function (field, force_reverse) {
|
||||
if (!field) {
|
||||
return _.map(this._sort, function (criteria) {
|
||||
if (criteria[0] === '-') {
|
||||
return criteria.slice(1) + ' DESC';
|
||||
}
|
||||
return criteria + ' ASC';
|
||||
}).join(', ');
|
||||
return openerp.base.serialize_sort(this._sort);
|
||||
}
|
||||
|
||||
var reverse = force_reverse || (this._sort[0] === field);
|
||||
this._sort = _.without(this._sort, field, '-' + field);
|
||||
this._sort.splice.apply(
|
||||
this._sort, [0, this._sort.length].concat(
|
||||
_.without(this._sort, field, '-' + field)));
|
||||
|
||||
this._sort.unshift((reverse ? '-' : '') + field);
|
||||
return undefined;
|
||||
|
||||
@@ -79,6 +79,10 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
|
||||
this.$form_header.find('button.oe_form_button_cancel').click(this.do_cancel);
|
||||
this.$form_header.find('button.oe_form_button_new').click(this.on_button_new);
|
||||
|
||||
this.$form_header.find('button.oe_get_xml_view').click(function() {
|
||||
$('<xmp>' + openerp.base.json_node_to_xml(self.fields_view.arch, true) + '</xmp>').dialog({ width: '95%', height: 600});
|
||||
});
|
||||
|
||||
this.view_manager.sidebar.set_toolbar(data.fields_view.toolbar);
|
||||
this.has_been_loaded.resolve();
|
||||
},
|
||||
@@ -235,6 +239,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
|
||||
if (result.value) {
|
||||
for (var f in result.value) {
|
||||
var field = this.fields[f];
|
||||
// If field is not defined in the view, just ignore it
|
||||
if (field) {
|
||||
var value = result.value[f];
|
||||
processed.push(field.name);
|
||||
@@ -245,8 +250,6 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
|
||||
this.do_onchange(field, processed);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// this is a common case, the normal behavior should be to ignore it
|
||||
}
|
||||
}
|
||||
this.on_form_changed();
|
||||
@@ -262,16 +265,15 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
|
||||
});
|
||||
}
|
||||
if (result.domain) {
|
||||
// Will be removed ?
|
||||
// TODO:
|
||||
}
|
||||
this.ready = true;
|
||||
},
|
||||
on_button_new: function() {
|
||||
var self = this;
|
||||
$.when(this.has_been_loaded).then(function() {
|
||||
self.dataset.default_get(_.keys(self.fields_view.fields), function(result) {
|
||||
self.on_record_loaded(result.result);
|
||||
});
|
||||
self.dataset.default_get(
|
||||
_.keys(self.fields_view.fields), self.on_record_loaded);
|
||||
});
|
||||
},
|
||||
/**
|
||||
@@ -826,8 +828,10 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
|
||||
* the fields'context with the action's context.
|
||||
*/
|
||||
build_context: function() {
|
||||
var a_context = this.view.dataset.get_context() || {};
|
||||
var f_context = this.field.context || {};
|
||||
// I previously belevied contexts should be herrited, but now I doubt it
|
||||
//var a_context = this.view.dataset.get_context() || {};
|
||||
var f_context = this.field.context || null;
|
||||
// maybe the default_get should only be used when we do a default_get?
|
||||
var v_context1 = this.node.attrs.default_get || {};
|
||||
var v_context2 = this.node.attrs.context || {};
|
||||
var v_context = new openerp.base.CompoundContext(v_context1, v_context2);
|
||||
@@ -835,17 +839,19 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
|
||||
var fields_values = this._build_view_fields_values();
|
||||
v_context.set_eval_context(fields_values);
|
||||
}
|
||||
var ctx = new openerp.base.CompoundContext(a_context, f_context, v_context);
|
||||
// if there is a context on the node, overrides the model's context
|
||||
var ctx = f_context || v_context;
|
||||
return ctx;
|
||||
},
|
||||
build_domain: function() {
|
||||
var f_domain = this.field.domain || [];
|
||||
var f_domain = this.field.domain || null;
|
||||
var v_domain = this.node.attrs.domain || [];
|
||||
if (!(v_domain instanceof Array) || true) { //TODO niv: remove || true
|
||||
var fields_values = this._build_view_fields_values();
|
||||
v_domain = new openerp.base.CompoundDomain(v_domain).set_eval_context(fields_values);
|
||||
}
|
||||
return new openerp.base.CompoundDomain(f_domain, v_domain);
|
||||
// if there is a domain on the node, overrides the model's domain
|
||||
return f_domain || v_domain;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1239,6 +1245,21 @@ openerp.base.form.FieldSelection = openerp.base.form.Field.extend({
|
||||
});
|
||||
})();
|
||||
|
||||
openerp.base.form.dialog = function(content, options) {
|
||||
options = _.extend({
|
||||
autoOpen: true,
|
||||
width: '90%',
|
||||
height: '90%',
|
||||
min_width: '800px',
|
||||
min_height: '600px'
|
||||
}, options || {});
|
||||
options.autoOpen = true;
|
||||
var dialog = new openerp.base.Dialog(null, options);
|
||||
dialog.$dialog = $(content).dialog(dialog.options);
|
||||
console.log(dialog.options)
|
||||
return dialog.$dialog;
|
||||
}
|
||||
|
||||
openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
@@ -1827,10 +1848,7 @@ openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({
|
||||
this.context = context || {};
|
||||
this.options = _.defaults(options || {}, {"initial_view": "search", "auto_create": true});
|
||||
this.initial_ids = this.options.initial_ids;
|
||||
jQuery(this.render()).dialog({title: '',
|
||||
modal: true,
|
||||
width: 960,
|
||||
height: 600});
|
||||
openerp.base.form.dialog(this.render());
|
||||
this.start();
|
||||
},
|
||||
start: function() {
|
||||
@@ -2019,10 +2037,10 @@ openerp.base.form.FormOpenPopup = openerp.base.BaseWidget.extend({
|
||||
}
|
||||
});
|
||||
|
||||
openerp.base.form.FieldReference = openerp.base.form.Field.extend({
|
||||
openerp.base.form.FieldReference = openerp.base.form.FieldChar.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.template = "FieldReference";
|
||||
//this.template = "FieldReference";
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2040,6 +2058,10 @@ openerp.base.form.FieldBinary = openerp.base.form.Field.extend({
|
||||
},
|
||||
set_value_from_ui: function() {
|
||||
},
|
||||
update_dom: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$element.find('.oe-binary').toggle(!this.readonly);
|
||||
},
|
||||
human_filesize : function(size) {
|
||||
var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
var i = 0;
|
||||
@@ -2137,6 +2159,13 @@ openerp.base.form.FieldBinaryImage = openerp.base.form.FieldBinary.extend({
|
||||
this._super.apply(this, arguments);
|
||||
this.$image = this.$element.find('img.oe-binary-image');
|
||||
},
|
||||
set_value: function(value) {
|
||||
this._super.apply(this, arguments);
|
||||
this.set_image_maxwidth();
|
||||
var url = '/base/binary/image?session_id=' + this.session.session_id + '&model=' +
|
||||
this.view.dataset.model +'&id=' + (this.view.datarecord.id || '') + '&field=' + this.name + '&t=' + (new Date().getTime())
|
||||
this.$image.attr('src', url);
|
||||
},
|
||||
set_image_maxwidth: function() {
|
||||
this.$image.css('max-width', this.$element.width());
|
||||
},
|
||||
@@ -2152,13 +2181,6 @@ openerp.base.form.FieldBinaryImage = openerp.base.form.FieldBinary.extend({
|
||||
on_clear: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$image.attr('src', '/base/static/src/img/placeholder.png');
|
||||
},
|
||||
set_value: function(value) {
|
||||
this._super.apply(this, arguments);
|
||||
this.set_image_maxwidth();
|
||||
var url = '/base/binary/image?session_id=' + this.session.session_id + '&model=' +
|
||||
this.view.dataset.model +'&id=' + (this.view.datarecord.id || '') + '&field=' + this.name + '&t=' + (new Date().getTime())
|
||||
this.$image.attr('src', url);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -247,7 +247,12 @@ openerp.base.list.editable = function (openerp) {
|
||||
this.render_row_as_form();
|
||||
}
|
||||
});
|
||||
openerp.base.list = {form: {}};
|
||||
if (!openerp.base.list) {
|
||||
openerp.base.list = {};
|
||||
}
|
||||
if (!openerp.base.list.form) {
|
||||
openerp.base.list.form = {};
|
||||
}
|
||||
openerp.base.list.form.WidgetFrame = openerp.base.form.WidgetFrame.extend({
|
||||
template: 'ListView.row.frame'
|
||||
});
|
||||
|
||||
@@ -1,5 +1,50 @@
|
||||
openerp.base.list = function (openerp) {
|
||||
openerp.base.views.add('list', 'openerp.base.ListView');
|
||||
openerp.base.list = {
|
||||
/**
|
||||
* Formats the rendring of a given value based on its field type
|
||||
*
|
||||
* @param {Object} row_data record whose values should be displayed in the cell
|
||||
* @param {Object} column column descriptor
|
||||
* @param {"button"|"field"} column.tag base control type
|
||||
* @param {String} column.type widget type for a field control
|
||||
* @param {String} [column.string] button label
|
||||
* @param {String} [column.icon] button icon
|
||||
* @param {String} [value_if_empty=''] what to display if the field's value is ``false``
|
||||
*/
|
||||
render_cell: function (row_data, column, value_if_empty) {
|
||||
var attrs = column.modifiers_for(row_data);
|
||||
if (attrs.invisible) { return ''; }
|
||||
if (column.tag === 'button') {
|
||||
return [
|
||||
'<button type="button" title="', column.string || '', '">',
|
||||
'<img src="/base/static/src/img/icons/', column.icon, '.png"',
|
||||
' alt="', column.string || '', '"/>',
|
||||
'</button>'
|
||||
].join('')
|
||||
}
|
||||
|
||||
var record = row_data[column.id];
|
||||
if (record.value === false) {
|
||||
return value_if_empty === undefined ? '' : value_if_empty;
|
||||
}
|
||||
switch (column.widget || column.type) {
|
||||
case 'many2one':
|
||||
// name_get value format
|
||||
return record.value[1];
|
||||
case 'float_time':
|
||||
return _.sprintf("%02d:%02d",
|
||||
Math.floor(record.value),
|
||||
Math.round((record.value % 1) * 60));
|
||||
case 'progressbar':
|
||||
return _.sprintf(
|
||||
'<progress value="%.2f" max="100.0">%.2f%%</progress>',
|
||||
record.value, record.value);
|
||||
default:
|
||||
return record.value;
|
||||
}
|
||||
}
|
||||
};
|
||||
openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListView# */ {
|
||||
defaults: {
|
||||
// records can be selected one by one
|
||||
@@ -147,8 +192,6 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
||||
|
||||
this.setup_columns(this.fields_view.fields, grouped);
|
||||
|
||||
if (!this.fields_view.sorted) { this.fields_view.sorted = {}; }
|
||||
|
||||
this.$element.html(QWeb.render("ListView", this));
|
||||
|
||||
// Head hook
|
||||
@@ -158,13 +201,20 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
||||
this.$element.find('.oe-list-delete')
|
||||
.attr('disabled', true)
|
||||
.click(this.do_delete_selected);
|
||||
this.$element.find('thead').delegate('th[data-id]', 'click', function (e) {
|
||||
this.$element.find('thead').delegate('th.oe-sortable[data-id]', 'click', function (e) {
|
||||
e.stopPropagation();
|
||||
|
||||
self.dataset.sort($(this).data('id'));
|
||||
var $this = $(this);
|
||||
self.dataset.sort($this.data('id'));
|
||||
if ($this.find('span').length) {
|
||||
$this.find('span').toggleClass(
|
||||
'ui-icon-triangle-1-s ui-icon-triangle-1-n');
|
||||
} else {
|
||||
$this.append('<span class="ui-icon ui-icon-triangle-1-s">')
|
||||
.siblings('.oe-sortable').find('span').remove();
|
||||
}
|
||||
|
||||
// TODO: should only reload content (and set the right column to a sorted display state)
|
||||
self.reload_view();
|
||||
self.reload_content();
|
||||
});
|
||||
|
||||
this.$element.find('.oe-list-pager')
|
||||
@@ -263,6 +313,9 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
||||
'invisible': domain_computer(modifiers.invisible, fields)
|
||||
};
|
||||
};
|
||||
if (modifiers['tree_invisible']) {
|
||||
column.invisible = '1';
|
||||
}
|
||||
} else {
|
||||
column.modifiers_for = noop;
|
||||
}
|
||||
@@ -401,6 +454,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
||||
this.session, this.model,
|
||||
results.domain, results.context,
|
||||
results.group_by);
|
||||
this.groups.datagroup.sort = this.dataset._sort;
|
||||
|
||||
if (_.isEmpty(results.group_by) && !results.context['group_by_no_leaf']) {
|
||||
results.group_by = null;
|
||||
@@ -634,7 +688,7 @@ openerp.base.ListView.List = Class.extend( /** @lends openerp.base.ListView.List
|
||||
this.$current = this.$_element.clone(true);
|
||||
this.$current.empty().append(
|
||||
QWeb.render('ListView.rows', _.extend({
|
||||
render_cell: this.render_cell}, this)));
|
||||
render_cell: openerp.base.list.render_cell}, this)));
|
||||
},
|
||||
/**
|
||||
* Gets the ids of all currently selected records, if any
|
||||
@@ -765,49 +819,9 @@ openerp.base.ListView.List = Class.extend( /** @lends openerp.base.ListView.List
|
||||
row: this.rows[record_index],
|
||||
row_parity: (record_index % 2 === 0) ? 'even' : 'odd',
|
||||
row_index: record_index,
|
||||
render_cell: this.render_cell
|
||||
render_cell: openerp.base.list.render_cell
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Formats the rendring of a given value based on its field type
|
||||
*
|
||||
* @param {Object} row_data record whose values should be displayed in the cell
|
||||
* @param {Object} column column descriptor
|
||||
* @param {"button"|"field"} column.tag base control type
|
||||
* @param {String} column.type widget type for a field control
|
||||
* @param {String} [column.string] button label
|
||||
* @param {String} [column.icon] button icon
|
||||
*/
|
||||
render_cell: function (row_data, column) {
|
||||
var attrs = column.modifiers_for(row_data);
|
||||
if (attrs.invisible) { return ''; }
|
||||
if (column.tag === 'button') {
|
||||
return [
|
||||
'<button type="button" title="', column.string || '', '">',
|
||||
'<img src="/base/static/src/img/icons/', column.icon, '.png"',
|
||||
' alt="', column.string || '', '"/>',
|
||||
'</button>'
|
||||
].join('')
|
||||
}
|
||||
|
||||
var record = row_data[column.id];
|
||||
if (record.value === false) { return ''; }
|
||||
switch (column.widget || column.type) {
|
||||
case 'many2one':
|
||||
// name_get value format
|
||||
return record.value[1];
|
||||
case 'float_time':
|
||||
return _.sprintf("%02d:%02d",
|
||||
Math.floor(record.value),
|
||||
Math.round((record.value % 1) * 60));
|
||||
case 'progressbar':
|
||||
return _.sprintf(
|
||||
'<progress value="%.2f" max="100.0">%.2f%%</progress>',
|
||||
record.value, record.value);
|
||||
default:
|
||||
return record.value;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Stops displaying the records matching the provided ids.
|
||||
*
|
||||
@@ -959,10 +973,15 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
|
||||
placeholder.appendChild($row[0]);
|
||||
|
||||
var $group_column = $('<th class="oe-group-name">').appendTo($row);
|
||||
// Don't fill this if group_by_no_leaf but no group_by
|
||||
if (group.grouped_on) {
|
||||
// Don't fill this if group_by_no_leaf but no group_by
|
||||
$group_column
|
||||
.text((group.value instanceof Array ? group.value[1] : group.value));
|
||||
var row_data = {};
|
||||
row_data[group.grouped_on] = group;
|
||||
var group_column = _(self.columns).detect(function (column) {
|
||||
return column.id === group.grouped_on; });
|
||||
$group_column.text(openerp.base.list.render_cell(
|
||||
row_data, group_column, "Undefined"
|
||||
));
|
||||
if (group.openable) {
|
||||
// Make openable if not terminal group & group_by_no_leaf
|
||||
$group_column
|
||||
|
||||
@@ -283,10 +283,8 @@
|
||||
<t t-foreach="columns" t-as="column">
|
||||
<th t-if="!column.meta and column.invisible !== '1'" t-att-data-id="column.id"
|
||||
t-att-class="((options.sortable and column.tag !== 'button') ? 'oe-sortable' : null)">
|
||||
<t t-if="column.tag !== 'button'">
|
||||
<t t-esc="column.string"/>
|
||||
<span t-att-class="(fields_view.sorted.field === column.id) ? ('ui-icon' + (fields_view.sorted.reversed ? ' ui-icon-triangle-1-n' : ' ui-icon-triangle-1-s')) : ''"/>
|
||||
</t>
|
||||
<t t-if="column.tag !== 'button'"
|
||||
><t t-esc="column.string"/></t>
|
||||
</th>
|
||||
</t>
|
||||
<th t-if="options.deletable" width="1"/>
|
||||
@@ -336,8 +334,8 @@
|
||||
<t t-raw="frame.render()"/>
|
||||
</t>
|
||||
<t t-name="FormView">
|
||||
<h2 class="oe_view_title"><t t-esc="view.fields_view.arch.attrs.string"/></h2>
|
||||
<div class="oe_form_header" t-att-id="view.element_id + '_header'">
|
||||
<h2 class="oe_view_title"><t t-esc="view.fields_view.arch.attrs.string"/> <button class="oe_get_xml_view">xml</button></h2>
|
||||
<div class="oe_form_buttons" t-if="view.flags.action_buttons !== false">
|
||||
<!--<button type="button" class="oe_form_button_save">
|
||||
<span class="oe_form_on_update">Save</span>
|
||||
@@ -811,7 +809,7 @@
|
||||
<select class="searchview_extended_prop_op"/>
|
||||
<span class="searchview_extended_prop_value"/>
|
||||
<a class="searchview_extended_delete_prop"
|
||||
href="javascript:void(0)"><span></span></a>
|
||||
href="javascript:void(0)"><span> </span></a>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="SearchView.extended_search.proposition.char">
|
||||
|
||||
@@ -7,14 +7,18 @@
|
||||
}
|
||||
.openerp .oe-dashboard-action {
|
||||
margin: 0 0.5em 0.5em 0;
|
||||
padding: 2px;
|
||||
}
|
||||
.openerp .oe-dashboard-action:hover {
|
||||
border: 1px dashed #ccc;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.openerp .oe-dashboard-action .oe-dashboard-action-header {
|
||||
margin: 0.3em;
|
||||
padding-bottom: 4px;
|
||||
padding-left: 0.2em
|
||||
font-size: 125%;
|
||||
font-weight: bold;
|
||||
}
|
||||
.openerp a.oe-dashboard-action-rename {
|
||||
float: left;
|
||||
padding-right: 4px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
@@ -43,7 +47,7 @@
|
||||
}
|
||||
|
||||
.openerp .oe-dashboard-action .oe-dashboard-action-content {
|
||||
padding: 0.4em;
|
||||
/*padding: 0.4em;*/
|
||||
}
|
||||
|
||||
.openerp .oe-dashboard .ui-sortable-placeholder {
|
||||
@@ -126,3 +130,10 @@
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.openerp .oe-dashboard-action .view-manager-main-content {
|
||||
padding: 2px;
|
||||
}
|
||||
.openerp .oe-dashboard-action-header .ui-icon, .openerp .oe-dashboard-action-header .oe-dashboard-action-rename {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,10 @@ openerp.base.form.DashBoard = openerp.base.form.Widget.extend({
|
||||
});
|
||||
});
|
||||
|
||||
this.$element.find('a.oe-dashboard-action-rename').live('click', this.on_rename);
|
||||
//this.$element.find('a.oe-dashboard-action-rename').live('click', this.on_rename);
|
||||
this.$element.find('.oe-dashboard-action').live('mouseover mouseout', function(event) {
|
||||
$(this).find('.oe-dashboard-action-header .ui-icon, .oe-dashboard-action-header .oe-dashboard-action-rename').toggle(event.type == 'mouseover');
|
||||
});
|
||||
},
|
||||
on_undo: function() {
|
||||
this.rpc('/base/view/undo_custom', {
|
||||
|
||||
@@ -29,15 +29,15 @@
|
||||
</table>
|
||||
</t>
|
||||
<t t-name="DashBoard.action">
|
||||
<div t-att-data-id="action.attrs.name" class="oe-dashboard-action ui-widget ui-widget-content ui-helper-clearfix ui-corner-all">
|
||||
<div class="oe-dashboard-action-header ui-widget-header ui-corner-all">
|
||||
<a href="#" class="oe-dashboard-action-rename"><img src="/base/static/src/img/icons/gtk-edit.png" width="16" height="16"/></a>
|
||||
<span class="oe-dashboard-action-title"><t t-esc="action.attrs.string"/></span>
|
||||
<div t-att-data-id="action.attrs.name" class="oe-dashboard-action">
|
||||
<h2 class="oe-dashboard-action-header oe_view_title">
|
||||
<t t-esc="action.attrs.string"/>
|
||||
<!--<a href="#" class="oe-dashboard-action-rename"><img src="/base/static/src/img/icons/gtk-edit.png" width="16" height="16"/></a>-->
|
||||
<input class="oe-dashboard-action-input" type="text" name="title" value="" style="display: none"/>
|
||||
<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>
|
||||
</div>
|
||||
</h2>
|
||||
<div t-att-id="view.element_id + '_action_' + action.attrs.name" class="oe-dashboard-action-content" t-att-style="action.attrs.fold ? 'display: none' : null"></div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<t t-name="GraphView">
|
||||
<h2 class="oe_view_title"><t t-esc="fields_view.arch.attrs.string"/></h2>
|
||||
<div t-att-id="elem_id+'-'+chart+'chart'" style="height:300px;position:relative;border:1px solid #A4BED4;"></div>
|
||||
<div t-att-id="elem_id+'-'+chart+'chart'" style="height:300px;position:relative;"></div>
|
||||
</t>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user