[ADD] treeview
bzr revid: xmo@openerp.com-20110809155516-f35pjfviu0zunkis
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
"static/lib/underscore/underscore.string.js",
|
||||
"static/src/js/boot.js",
|
||||
"static/src/js/core.js",
|
||||
"static/src/js/dates.js",
|
||||
"static/src/js/formats.js",
|
||||
"static/src/js/chrome.js",
|
||||
"static/src/js/views.js",
|
||||
"static/src/js/data.js",
|
||||
|
||||
@@ -390,10 +390,10 @@ def load_actions_from_ir_values(req, key, key2, models, meta, context):
|
||||
Values = req.session.model('ir.values')
|
||||
actions = Values.get(key, key2, models, meta, context)
|
||||
|
||||
return [(id, name, clean_action(action, req.session))
|
||||
return [(id, name, clean_action(action, req.session, context=context))
|
||||
for id, name, action in actions]
|
||||
|
||||
def clean_action(action, session):
|
||||
def clean_action(action, session, context=None):
|
||||
action.setdefault('flags', {})
|
||||
if action['type'] != 'ir.actions.act_window':
|
||||
return action
|
||||
@@ -401,7 +401,7 @@ def clean_action(action, session):
|
||||
if isinstance(action.get('context'), basestring):
|
||||
action['context'] = eval(
|
||||
action['context'],
|
||||
session.evaluation_context()) or {}
|
||||
session.evaluation_context(context=context)) or {}
|
||||
|
||||
if isinstance(action.get('domain'), basestring):
|
||||
action['domain'] = eval(
|
||||
@@ -559,6 +559,7 @@ class DataSet(openerpweb.Controller):
|
||||
:rtype: list
|
||||
"""
|
||||
Model = request.session.model(model)
|
||||
|
||||
context, domain = eval_context_and_domain(
|
||||
request.session, request.context, domain)
|
||||
|
||||
@@ -581,9 +582,14 @@ class DataSet(openerpweb.Controller):
|
||||
}
|
||||
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def read(self, request, model, ids, fields=False):
|
||||
return self.do_search_read(request, model, ids, fields)
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def get(self, request, model, ids, fields=False):
|
||||
return self.do_get(request, model, ids, fields)
|
||||
|
||||
def do_get(self, request, model, ids, fields=False):
|
||||
""" Fetches and returns the records of the model ``model`` whose ids
|
||||
are in ``ids``.
|
||||
@@ -668,6 +674,12 @@ class DataSet(openerpweb.Controller):
|
||||
Model = req.session.model(model)
|
||||
return Model.default_get(fields, req.session.eval_context(req.context))
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def name_search(self, req, model, search_str, domain=[], context={}):
|
||||
m = req.session.model(model)
|
||||
r = m.name_search(search_str+'%', domain, '=ilike', context)
|
||||
return {'result': r}
|
||||
|
||||
class DataGroup(openerpweb.Controller):
|
||||
_cp_path = "/base/group"
|
||||
@openerpweb.jsonrequest
|
||||
@@ -1001,6 +1013,19 @@ class Action(openerpweb.Controller):
|
||||
return clean_action(req.session.model('ir.actions.server').run(
|
||||
[action_id], req.session.eval_context(req.context)), req.session)
|
||||
|
||||
class TreeView(View):
|
||||
_cp_path = "/base/treeview"
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def load(self, req, model, view_id, toolbar=False):
|
||||
return self.fields_view_get(req, model, view_id, 'tree', toolbar=toolbar)
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def action(self, req, model, id):
|
||||
return load_actions_from_ir_values(
|
||||
req,'action', 'tree_but_open',[(model, id)],
|
||||
False, req.session.eval_context(req.context))
|
||||
|
||||
def export_csv(fields, result):
|
||||
fp = StringIO()
|
||||
writer = csv.writer(fp, quoting=csv.QUOTE_ALL)
|
||||
@@ -1213,4 +1238,3 @@ class Export(View):
|
||||
return export_xls(field, result)
|
||||
else:
|
||||
return export_csv(field, result)
|
||||
|
||||
|
||||
@@ -269,7 +269,7 @@ label.error {
|
||||
border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
|
||||
|
||||
color: #eee;
|
||||
text-shadow: #222 0 1px 0;
|
||||
text-decoration: none;
|
||||
@@ -1053,7 +1053,7 @@ label.error {
|
||||
padding-left: 10px;
|
||||
padding-right: 21px;
|
||||
height: 21px;
|
||||
|
||||
|
||||
background: #ffffff; /* Old browsers */
|
||||
background: -moz-linear-gradient(top, #ffffff 0%, #ebe9e9 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#ebe9e9)); /* Chrome,Safari4+ */
|
||||
@@ -1062,7 +1062,7 @@ background: -o-linear-gradient(top, #ffffff 0%,#ebe9e9 100%); /* Opera11.10+ */
|
||||
background: -ms-linear-gradient(top, #ffffff 0%,#ebe9e9 100%); /* IE10+ */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFFFFF', endColorstr='#EBE9E9',GradientType=0 ); /* IE6-9 */
|
||||
background: linear-gradient(top, #ffffff 0%,#ebe9e9 100%); /* W3C */
|
||||
|
||||
|
||||
border: 1px solid #D2CFCF;
|
||||
border-right-width: 0;
|
||||
border-left-width: 0;
|
||||
@@ -1167,7 +1167,9 @@ background: linear-gradient(top, #ffffff 0%,#ebe9e9 100%); /* W3C */
|
||||
.openerp .oe-m2o-disabled-cm {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.parent_top {
|
||||
vertical-align: text-top;
|
||||
}
|
||||
.openerp .oe-dialog-warning p {
|
||||
padding-left: 1em;
|
||||
font-size: 1.2em;
|
||||
@@ -1180,3 +1182,30 @@ background: linear-gradient(top, #ffffff 0%,#ebe9e9 100%); /* W3C */
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.openerp .oe-treeview-table {
|
||||
width: 100%;
|
||||
}
|
||||
.treeview-tr, .treeview-td {
|
||||
cursor: pointer;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
.treeview-tr span, .treeview-td span {
|
||||
display: block;
|
||||
}
|
||||
.treeview-tr:first-of-type {
|
||||
background: transparent url(/base/static/src/img/expand.gif) 0 50% no-repeat;
|
||||
}
|
||||
.oe-open .treeview-tr:first-of-type {
|
||||
background-image: url(/base/static/src/img/collapse.gif);
|
||||
}
|
||||
.treeview-tr:first-of-type span,
|
||||
.treeview-td:first-of-type span {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.treeview-header {
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
openerp.base = function(instance) {
|
||||
openerp.base.core(instance);
|
||||
openerp.base.dates(instance);
|
||||
openerp.base.formats(instance);
|
||||
openerp.base.chrome(instance);
|
||||
openerp.base.data(instance);
|
||||
if (openerp.base.views) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
openerp.base.dates = function(openerp) {
|
||||
openerp.base.formats = function(openerp) {
|
||||
|
||||
/**
|
||||
* Converts a string to a Date javascript object using OpenERP's
|
||||
@@ -133,5 +133,75 @@ openerp.base.format_time = function(obj) {
|
||||
return fts(obj.getHours(),2) + ":" + fts(obj.getMinutes(),2) + ":"
|
||||
+ fts(obj.getSeconds(),2);
|
||||
};
|
||||
|
||||
/**
|
||||
* Formats a single atomic value based on a field descriptor
|
||||
*
|
||||
* @param {Object} value read from OpenERP
|
||||
* @param {Object} descriptor union of orm field and view field
|
||||
* @param {Object} [descriptor.widget] widget to use to display the value
|
||||
* @param {Object} descriptor.type fallback if no widget is provided, or if the provided widget is unknown
|
||||
* @param {Object} [descriptor.digits] used for the formatting of floats
|
||||
* @param {String} [value_if_empty=''] returned if the ``value`` argument is considered empty
|
||||
*/
|
||||
openerp.base.format_value = function (value, descriptor, value_if_empty) {
|
||||
// If NaN value, display as with a `false` (empty cell)
|
||||
if (typeof value === 'number' && isNaN(value)) {
|
||||
value = false;
|
||||
}
|
||||
switch (value) {
|
||||
case false:
|
||||
case Infinity:
|
||||
case -Infinity:
|
||||
return value_if_empty === undefined ? '' : value_if_empty;
|
||||
}
|
||||
switch (descriptor.widget || descriptor.type) {
|
||||
case 'integer':
|
||||
return _.sprintf('%d', value);
|
||||
case 'float':
|
||||
var precision = descriptor.digits ? descriptor.digits[1] : 2;
|
||||
return _.sprintf('%.' + precision + 'f', value);
|
||||
case 'float_time':
|
||||
return _.sprintf("%02d:%02d",
|
||||
Math.floor(value),
|
||||
Math.round((value % 1) * 60));
|
||||
case 'progressbar':
|
||||
return _.sprintf(
|
||||
'<progress value="%.2f" max="100.0">%.2f%%</progress>',
|
||||
value, value);
|
||||
case 'many2one':
|
||||
// name_get value format
|
||||
return value[1];
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Formats a provided cell 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``
|
||||
*/
|
||||
openerp.base.format_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('')
|
||||
}
|
||||
|
||||
return openerp.base.format_value(
|
||||
row_data[column.id].value, column, value_if_empty);
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,63 +1,5 @@
|
||||
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 value = row_data[column.id].value;
|
||||
|
||||
// If NaN value, display as with a `false` (empty cell)
|
||||
if (typeof value === 'number' && isNaN(value)) {
|
||||
value = false;
|
||||
}
|
||||
switch (value) {
|
||||
case false:
|
||||
case Infinity:
|
||||
case -Infinity:
|
||||
return value_if_empty === undefined ? '' : value_if_empty;
|
||||
}
|
||||
switch (column.widget || column.type) {
|
||||
case 'integer':
|
||||
return _.sprintf('%d', value);
|
||||
case 'float':
|
||||
var precision = column.digits ? column.digits[1] : 2;
|
||||
return _.sprintf('%.' + precision + 'f', value);
|
||||
case 'float_time':
|
||||
return _.sprintf("%02d:%02d",
|
||||
Math.floor(value),
|
||||
Math.round((value % 1) * 60));
|
||||
case 'progressbar':
|
||||
return _.sprintf(
|
||||
'<progress value="%.2f" max="100.0">%.2f%%</progress>',
|
||||
value, value);
|
||||
case 'many2one':
|
||||
// name_get value format
|
||||
return value[1];
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
};
|
||||
openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListView# */ {
|
||||
defaults: {
|
||||
// records can be selected one by one
|
||||
@@ -637,7 +579,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
||||
}
|
||||
|
||||
$footer_cells.filter(_.sprintf('[data-field=%s]', column.id))
|
||||
.html(openerp.base.list.render_cell(aggregation, column));
|
||||
.html(openerp.base.format_cell(aggregation, column));
|
||||
});
|
||||
}
|
||||
// TODO: implement reorder (drag and drop rows)
|
||||
@@ -725,7 +667,7 @@ openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.
|
||||
this.$current = this.$_element.clone(true);
|
||||
this.$current.empty().append(
|
||||
QWeb.render('ListView.rows', _.extend({
|
||||
render_cell: openerp.base.list.render_cell}, this)));
|
||||
render_cell: openerp.base.format_cell}, this)));
|
||||
},
|
||||
/**
|
||||
* Gets the ids of all currently selected records, if any
|
||||
@@ -856,7 +798,7 @@ openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.
|
||||
row: this.rows[record_index],
|
||||
row_parity: (record_index % 2 === 0) ? 'even' : 'odd',
|
||||
row_index: record_index,
|
||||
render_cell: openerp.base.list.render_cell
|
||||
render_cell: openerp.base.format_cell
|
||||
});
|
||||
},
|
||||
/**
|
||||
@@ -1016,7 +958,7 @@ openerp.base.ListView.Groups = openerp.base.Class.extend( /** @lends openerp.bas
|
||||
row_data[group.grouped_on] = group;
|
||||
var group_column = _(self.columns).detect(function (column) {
|
||||
return column.id === group.grouped_on; });
|
||||
$group_column.html(openerp.base.list.render_cell(
|
||||
$group_column.html(openerp.base.format_cell(
|
||||
row_data, group_column, "Undefined"
|
||||
));
|
||||
if (group.openable) {
|
||||
|
||||
@@ -5,22 +5,203 @@
|
||||
openerp.base.view_tree = function(openerp) {
|
||||
|
||||
openerp.base.views.add('tree', 'openerp.base.TreeView');
|
||||
openerp.base.TreeView = openerp.base.Widget.extend({
|
||||
/**
|
||||
* Genuine tree view (the one displayed as a tree, not the list)
|
||||
*/
|
||||
openerp.base.TreeView = openerp.base.View.extend({
|
||||
/**
|
||||
* Indicates that this view is not searchable, and thus that no search
|
||||
* view should be displayed (if there is one active).
|
||||
*/
|
||||
searchable : false,
|
||||
|
||||
init: function(parent, element_id, dataset, view_id, options) {
|
||||
this._super(parent, element_id);
|
||||
this.dataset = dataset;
|
||||
this.model = dataset.model;
|
||||
this.view_id = view_id;
|
||||
|
||||
this.records = {};
|
||||
|
||||
this.options = _.extend({}, this.defaults, options || {});
|
||||
},
|
||||
|
||||
start: function () {
|
||||
this._super();
|
||||
this.$element.append('Tree view');
|
||||
return this.rpc("/base/treeview/load", {
|
||||
model: this.model,
|
||||
view_id: this.view_id,
|
||||
toolbar: this.view_manager ? !!this.view_manager.sidebar : false
|
||||
}, this.on_loaded);
|
||||
},
|
||||
/**
|
||||
* Returns the list of fields needed to correctly read objects.
|
||||
*
|
||||
* Gathers the names of all fields in fields_view_get, and adds the
|
||||
* field_parent (children_field in the tree view) if it's not already one
|
||||
* of the fields to fetch
|
||||
*
|
||||
* @returns {Array} an array of fields which can be provided to DataSet.read_slice and others
|
||||
*/
|
||||
fields_list: function () {
|
||||
var fields = _.keys(this.fields);
|
||||
if (!_(fields).contains(this.children_field)) {
|
||||
fields.push(this.children_field);
|
||||
}
|
||||
return fields;
|
||||
},
|
||||
on_loaded: function (fields_view) {
|
||||
var self = this;
|
||||
var has_toolbar = !!fields_view.arch.attrs.toolbar;
|
||||
// field name in OpenERP is kinda stupid: this is the name of the field
|
||||
// holding the ids to the children of the current node, why call it
|
||||
// field_parent?
|
||||
this.children_field = fields_view['field_parent'];
|
||||
this.fields_view = fields_view;
|
||||
_(this.fields_view.arch.children).each(function (field) {
|
||||
if (field.attrs.modifiers) {
|
||||
field.attrs.modifiers = JSON.parse(field.attrs.modifiers);
|
||||
}
|
||||
});
|
||||
this.fields = fields_view.fields;
|
||||
this.hook_row_click();
|
||||
this.$element.html(QWeb.render('TreeView', {
|
||||
'title': this.fields_view.arch.attrs.string,
|
||||
'fields_view': this.fields_view.arch.children,
|
||||
'fields': this.fields,
|
||||
'toolbar': has_toolbar
|
||||
}));
|
||||
|
||||
this.dataset.read_slice(this.fields_list(), 0, false, function (records) {
|
||||
if (!has_toolbar) {
|
||||
// WARNING: will do a second read on the same ids, but only on
|
||||
// first load so not very important
|
||||
self.getdata(null, _(records).pluck('id'));
|
||||
return;
|
||||
}
|
||||
|
||||
var $select = self.$element.find('select')
|
||||
.change(function () {
|
||||
var $option = $(this).find(':selected');
|
||||
self.getdata($option.val(), $option.data('children'));
|
||||
});
|
||||
_(records).each(function (record) {
|
||||
self.records[record.id] = record;
|
||||
$('<option>')
|
||||
.val(record.id)
|
||||
.text(record.name)
|
||||
.data('children', record[self.children_field])
|
||||
.appendTo($select);
|
||||
});
|
||||
|
||||
if (!_.isEmpty(records)) {
|
||||
$select.change();
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Sets up opening a row
|
||||
*/
|
||||
hook_row_click: function () {
|
||||
var self = this;
|
||||
this.$element.delegate('.treeview-td span, .treeview-tr span', 'click', function (e) {
|
||||
e.stopImmediatePropagation();
|
||||
self.activate($(this).closest('tr').data('id'));
|
||||
});
|
||||
|
||||
this.$element.delegate('.treeview-tr', 'click', function () {
|
||||
var is_loaded = 0,
|
||||
$this = $(this),
|
||||
record_id = $this.data('id'),
|
||||
record = self.records[record_id],
|
||||
children_ids = record[self.children_field];
|
||||
|
||||
_(children_ids).each(function(childid) {
|
||||
if (self.$element.find('#treerow_' + childid).length) {
|
||||
if (self.$element.find('#treerow_' + childid).is(':hidden')) {
|
||||
is_loaded = -1;
|
||||
} else {
|
||||
is_loaded++;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (is_loaded === 0) {
|
||||
if (!$this.parent().hasClass('oe-open')) {
|
||||
self.getdata(record_id, children_ids);
|
||||
}
|
||||
} else {
|
||||
self.showcontent(record_id, is_loaded < 0);
|
||||
}
|
||||
});
|
||||
},
|
||||
// get child data of selected value
|
||||
getdata: function (id, children_ids) {
|
||||
var self = this;
|
||||
|
||||
self.dataset.read_ids(children_ids, this.fields_list(), function (records) {
|
||||
_(records).each(function (record) {
|
||||
self.records[record.id] = record;
|
||||
});
|
||||
|
||||
var $curr_node = self.$element.find('#treerow_' + id);
|
||||
var children_rows = QWeb.render('TreeView.rows', {
|
||||
'records': records,
|
||||
'children_field': self.children_field,
|
||||
'fields_view': self.fields_view.arch.children,
|
||||
'fields': self.fields,
|
||||
'level': $curr_node.data('level') || 0,
|
||||
'render': openerp.base.format_value
|
||||
});
|
||||
|
||||
if ($curr_node.length) {
|
||||
$curr_node.addClass('oe-open');
|
||||
$curr_node.after(children_rows);
|
||||
} else {
|
||||
self.$element.find('tbody').html(children_rows);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Get details in listview
|
||||
activate: function(id) {
|
||||
var self = this;
|
||||
this.rpc('/base/treeview/action', {
|
||||
id: id,
|
||||
model: this.dataset.model,
|
||||
context: new openerp.base.CompoundContext(
|
||||
this.dataset.get_context(), {
|
||||
active_model: this.dataset.model,
|
||||
active_id: id,
|
||||
active_ids: [id]})
|
||||
}, function (actions) {
|
||||
if (!actions.length) { return; }
|
||||
var action = actions[0][2];
|
||||
action.flags.new_window = true;
|
||||
self.session.action_manager.do_action(action);
|
||||
});
|
||||
},
|
||||
|
||||
// show & hide the contents
|
||||
showcontent: function (record_id, show) {
|
||||
this.$element.find('#treerow_' + record_id)
|
||||
.toggleClass('oe-open', show);
|
||||
|
||||
_(this.records[record_id][this.children_field]).each(function (child_id) {
|
||||
var $child_row = this.$element.find('#treerow_' + child_id);
|
||||
if ($child_row.hasClass('oe-open')) {
|
||||
this.showcontent(child_id, false);
|
||||
}
|
||||
$child_row.toggle(show);
|
||||
}, this);
|
||||
},
|
||||
|
||||
do_show: function () {
|
||||
this.$element.show();
|
||||
},
|
||||
|
||||
do_hide: function () {
|
||||
this.$element.hide();
|
||||
this.hidden = true;
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
|
||||
|
||||
@@ -219,7 +219,7 @@ openerp.base.ViewManager = openerp.base.Widget.extend({
|
||||
},
|
||||
/**
|
||||
* Event launched when a controller has been inited.
|
||||
*
|
||||
*
|
||||
* @param {String} view_type type of view
|
||||
* @param {String} view the inited controller
|
||||
*/
|
||||
@@ -291,11 +291,11 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
|
||||
this.session = parent.session;
|
||||
var dataset;
|
||||
if (!action.res_id) {
|
||||
dataset = new openerp.base.DataSetSearch(this, action.res_model, action.context || null);
|
||||
dataset = new openerp.base.DataSetSearch(this, action.res_model, action.context || null, action.domain || null);
|
||||
} else {
|
||||
dataset = new openerp.base.DataSetStatic(this, action.res_model, {}, [action.res_id]);
|
||||
if (action.context) {
|
||||
// TODO fme: should normalize all DataSets constructors to (session, model, context, ...)
|
||||
// TODO fme: should normalize all DataSets constructors to (session, model, context, domain, ...)
|
||||
dataset.context = action.context;
|
||||
}
|
||||
}
|
||||
@@ -512,7 +512,7 @@ openerp.base.View = openerp.base.Widget.extend({
|
||||
* Directly set a view to use instead of calling fields_view_get. This method must
|
||||
* be called before start(). When an embedded view is set, underlying implementations
|
||||
* of openerp.base.View must use the provided view instead of any other one.
|
||||
*
|
||||
*
|
||||
* @param embedded_view A view.
|
||||
*/
|
||||
set_embedded_view: function(embedded_view) {
|
||||
|
||||
@@ -449,6 +449,41 @@
|
||||
</ul>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="TreeView">
|
||||
<h2 class="oe_view_title"><t t-esc="title"/></h2>
|
||||
<select t-if="toolbar" style="width: 30%">
|
||||
</select>
|
||||
<table class="oe-treeview-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th t-foreach="fields_view" t-as="field"
|
||||
t-if="!field.attrs.modifiers.tree_invisible"
|
||||
class="treeview-header">
|
||||
<t t-esc="fields[field.attrs.name].string" />
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
<tr t-name="TreeView.rows"
|
||||
t-foreach="records" t-as="record"
|
||||
t-att-id="'treerow_' + record.id"
|
||||
t-att-data-id="record.id" t-att-data-level="level + 1">
|
||||
<t t-set="children" t-value="record[children_field]"/>
|
||||
<t t-set="has_children" t-value="children and children.length"/>
|
||||
|
||||
<td t-foreach="fields_view" t-as="field"
|
||||
t-if="!field.attrs.modifiers.tree_invisible"
|
||||
t-att-data-id="record.id"
|
||||
t-att-style="!field_index ? 'background-position: ' + 19*level + 'px; padding-left: ' + 19*level + 'px' : undefined"
|
||||
t-att-class="!field_index and has_children ? 'treeview-tr' : 'treeview-td'">
|
||||
<span t-if="!field.attrs.modifiers.invisible">
|
||||
<t t-esc="render(record[field.attrs.name], fields[field.attrs.name])" />
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<table t-name="ListView" class="oe-listview-content">
|
||||
<t t-set="columns_count" t-value="visible_columns.length + (options.selectable ? 1 : 0) + (options.deletable ? 1 : 0)"/>
|
||||
<thead class="ui-widget-header">
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
<script src="/base/static/src/js/boot.js"></script>
|
||||
<script src="/base/static/src/js/core.js"></script>
|
||||
<script src="/base/static/src/js/dates.js"></script>
|
||||
<script src="/base/static/src/js/formats.js"></script>
|
||||
<script src="/base/static/src/js/chrome.js"></script>
|
||||
<script src="/base/static/src/js/data.js"></script>
|
||||
<script src="/base/static/src/js/views.js"></script>
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
<script type="text/javascript" src="/base/static/src/js/base.js"></script>
|
||||
<script type="text/javascript" src="/base/static/src/js/chrome.js"></script>
|
||||
<script type="text/javascript" src="/base/static/src/js/data.js"></script>
|
||||
<script type="text/javascript" src="/base/static/src/js/dates.js"></script>
|
||||
<script type="text/javascript" src="/base/static/src/js/formats.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/web_mobile/static/src/js/web_mobile.js"></script>
|
||||
<script type="text/javascript" src="/web_mobile/static/src/js/chrome_mobile.js"></script>
|
||||
<script type="text/javascript" src="/web_mobile/static/src/js/web_mobile.js"></script>
|
||||
<script type="text/javascript" src="/web_mobile/static/src/js/chrome_mobile.js"></script>
|
||||
<script type="text/javascript" src="/web_mobile/static/src/js/list_mobile.js"></script>
|
||||
<script type="text/javascript" src="/web_mobile/static/src/js/form_mobile.js"></script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user