[IMP] Break list views completely, change DataGroup API to work better, improve columns management to handle groupby-reordering
bzr revid: xmo@openerp.com-20110517140358-vtank237dh5hso8i
This commit is contained in:
parent
196a7ab46e
commit
ccf8031e6b
|
@ -24,14 +24,39 @@ openerp.base.DataGroup = openerp.base.Controller.extend( /** @lends openerp.bas
|
|||
* @param {Array} group_by sequence of fields by which to group
|
||||
*/
|
||||
init: function(session, model, domain, context, group_by) {
|
||||
if (group_by) {
|
||||
if (group_by.length) {
|
||||
return new openerp.base.ContainerDataGroup(
|
||||
session, model, domain, context, group_by);
|
||||
} else {
|
||||
return new openerp.base.GrouplessDataGroup(
|
||||
session, model, domain, context);
|
||||
}
|
||||
}
|
||||
|
||||
this._super(session, null);
|
||||
this.model = model;
|
||||
this.context = context;
|
||||
this.domain = domain;
|
||||
}
|
||||
});
|
||||
openerp.base.ContainerDataGroup = openerp.base.DataGroup.extend(
|
||||
/** @lends openerp.base.ContainerDataGroup# */ {
|
||||
/**
|
||||
*
|
||||
* @constructs
|
||||
* @extends openerp.base.DataGroup
|
||||
*
|
||||
* @param session
|
||||
* @param model
|
||||
* @param domain
|
||||
* @param context
|
||||
* @param group_by
|
||||
*/
|
||||
init: function (session, model, domain, context, group_by) {
|
||||
this._super(session, model, domain, context);
|
||||
|
||||
this.group_by = group_by;
|
||||
|
||||
this.groups = null;
|
||||
},
|
||||
/**
|
||||
* The format returned by ``read_group`` is absolutely dreadful:
|
||||
|
@ -107,53 +132,6 @@ openerp.base.DataGroup = openerp.base.Controller.extend( /** @lends openerp.bas
|
|||
return d.promise();
|
||||
},
|
||||
/**
|
||||
* Retrieves the content of an item in the DataGroup, which results in
|
||||
* either a DataSet or new DataGroup instance.
|
||||
*
|
||||
* Calling :js:func:`~openerp.base.DataGroup.get` without having called
|
||||
* :js:func:`~openerp.base.DataGroup.list` beforehand will likely result
|
||||
* in an error.
|
||||
*
|
||||
* The resulting :js:class:`~openerp.base.DataGroup` or
|
||||
* :js:class:`~openerp.base.DataSet` will be provided through the relevant
|
||||
* callback function. In both functions, the current DataGroup will be
|
||||
* provided as context (``this``)
|
||||
*
|
||||
* @param {Number} index the index of the group to open in the datagroup's collection
|
||||
* @param {Function} ifDataSet executed if the item results in a DataSet, provided with the new dataset as parameter
|
||||
* @param {Function} ifDataGroup executed if the item results in a DataSet, provided with the new datagroup as parameter
|
||||
*/
|
||||
get: function (index, ifDataSet, ifDataGroup) {
|
||||
var group = this.groups[index];
|
||||
if (!group) {
|
||||
throw new Error("No group at index " + index);
|
||||
}
|
||||
|
||||
var child_context = _.extend({}, this.context, group.__context);
|
||||
if (group.__context.group_by.length) {
|
||||
var datagroup = new openerp.base.DataGroup(
|
||||
this.session, this.model, group.__domain, child_context,
|
||||
group.__context.group_by);
|
||||
ifDataGroup.call(this, datagroup);
|
||||
} else {
|
||||
var dataset = new openerp.base.DataSetSearch(this.session, this.model);
|
||||
dataset.domain = group.__domain;
|
||||
dataset.context = child_context;
|
||||
ifDataSet.call(this, dataset);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Gathers the content of the current data group (the current grouping
|
||||
* level), and provides it via a promise object to which callbacks should
|
||||
* be added::
|
||||
*
|
||||
* datagroup.list().then(function (list) {
|
||||
* // manipulate list here
|
||||
* });
|
||||
*
|
||||
* The argument to the callback is the list of elements fetched, the
|
||||
* context (``this``) is the datagroup itself.
|
||||
*
|
||||
* The items of a list have the following properties:
|
||||
*
|
||||
* ``length``
|
||||
|
@ -171,11 +149,40 @@ openerp.base.DataGroup = openerp.base.Controller.extend( /** @lends openerp.bas
|
|||
* records have for the current ``grouped_on`` field name).
|
||||
* ``aggregates``
|
||||
* a mapping of other aggregation fields provided by ``read_group``
|
||||
*
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
list: function () {
|
||||
return this.fetch();
|
||||
list: function (ifGroups, ifRecords) {
|
||||
var self = this;
|
||||
this.fetch().then(function (group_records) {
|
||||
ifGroups(_(group_records).map(function (group) {
|
||||
var child_context = _.extend({}, self.context, group.__context);
|
||||
return _.extend(
|
||||
new openerp.base.DataGroup(
|
||||
self.session, self.model, group.__domain,
|
||||
child_context, child_context.group_by),
|
||||
group);
|
||||
}));
|
||||
});
|
||||
}
|
||||
});
|
||||
openerp.base.GrouplessDataGroup = openerp.base.DataGroup.extend(
|
||||
/** @lends openerp.base.GrouplessDataGroup# */ {
|
||||
/**
|
||||
*
|
||||
* @constructs
|
||||
* @extends openerp.base.DataGroup
|
||||
*
|
||||
* @param session
|
||||
* @param model
|
||||
* @param domain
|
||||
* @param context
|
||||
*/
|
||||
init: function (session, model, domain, context) {
|
||||
this._super(session, model, domain, context);
|
||||
},
|
||||
list: function (ifGroups, ifRecords) {
|
||||
ifRecords(_.extend(
|
||||
new openerp.base.DataSetSearch(this.session, this.model),
|
||||
{domain: this.domain, context: this.context}));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -52,20 +52,14 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
|||
this.view_id = view_id;
|
||||
|
||||
this.columns = [];
|
||||
this.rows = [];
|
||||
|
||||
this.options = _.extend({}, this.defaults, options || {});
|
||||
|
||||
this.list = new openerp.base.ListView.List({
|
||||
options: this.options,
|
||||
columns: this.columns,
|
||||
rows: this.rows
|
||||
});
|
||||
this.groups = new openerp.base.ListView.Groups({
|
||||
options: this.options,
|
||||
columns: this.columns
|
||||
});
|
||||
$([this.list, this.groups]).bind({
|
||||
$(this.groups).bind({
|
||||
'selected': function (e, selection) {
|
||||
self.$element.find('#oe-list-delete')
|
||||
.toggle(!!selection.length);
|
||||
|
@ -124,41 +118,15 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
|||
* @param {Object} data.fields_view fields_view_get result (processed)
|
||||
* @param {Object} data.fields_view.fields mapping of fields for the current model
|
||||
* @param {Object} data.fields_view.arch current list view descriptor
|
||||
* @param {Array} columns columns to move to the front (and make visible)
|
||||
*/
|
||||
on_loaded: function(data) {
|
||||
on_loaded: function(data, columns) {
|
||||
var self = this;
|
||||
this.fields_view = data.fields_view;
|
||||
//this.log(this.fields_view);
|
||||
this.name = "" + this.fields_view.arch.attrs.string;
|
||||
|
||||
var fields = this.fields_view.fields;
|
||||
var domain_computer = openerp.base.form.compute_domain;
|
||||
|
||||
this.columns.splice(0, this.columns.length);
|
||||
this.columns.push.apply(this.columns, _(this.fields_view.arch.children).chain()
|
||||
.map(function (field) {
|
||||
var name = field.attrs.name;
|
||||
var column = _.extend({id: name, tag: field.tag},
|
||||
field.attrs, fields[name]);
|
||||
// attrs computer
|
||||
if (column.attrs) {
|
||||
var attrs = eval('(' + column.attrs + ')');
|
||||
column.attrs_for = function (fields) {
|
||||
var result = {};
|
||||
for (var attr in attrs) {
|
||||
result[attr] = domain_computer(attrs[attr], fields);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
} else {
|
||||
column.attrs_for = function () { return {}; };
|
||||
}
|
||||
return column;
|
||||
}).value());
|
||||
|
||||
this.visible_columns = _.filter(this.columns, function (column) {
|
||||
return column.invisible !== '1';
|
||||
});
|
||||
this.setup_columns(this.fields_view.fields, columns);
|
||||
|
||||
if (!this.fields_view.sorted) { this.fields_view.sorted = {}; }
|
||||
|
||||
|
@ -178,49 +146,51 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
|||
self.do_reload();
|
||||
});
|
||||
|
||||
var $table = this.$element.find('table');
|
||||
this.list.move_to($table);
|
||||
|
||||
// sidebar stuff
|
||||
if (this.view_manager && this.view_manager.sidebar) {
|
||||
this.view_manager.sidebar.set_toolbar(data.fields_view.toolbar);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Fills the table with the provided records after emptying it
|
||||
*
|
||||
* TODO: should also re-load the table itself, as e.g. columns may have changed
|
||||
*
|
||||
* @param {Object} result filling result
|
||||
* @param {Array} [result.view] the new view (wrapped fields_view_get result)
|
||||
* @param {Array} result.records records the records to fill the list view with
|
||||
*/
|
||||
do_fill_table: function(result) {
|
||||
if (result.view) {
|
||||
this.on_loaded({fields_view: result.view});
|
||||
}
|
||||
var records = result.records;
|
||||
setup_columns: function (fields, groupby_columns) {
|
||||
var self = this;
|
||||
var domain_computer = openerp.base.form.compute_domain;
|
||||
|
||||
this.rows.splice(0, this.rows.length);
|
||||
this.rows.push.apply(this.rows, records);
|
||||
|
||||
// Keep current selected record, if it's still in our new search
|
||||
var current_record_id = this.dataset.ids[this.dataset.index];
|
||||
this.dataset.ids = _(records).chain().map(function (record) {
|
||||
return record.data.id.value;
|
||||
}).value();
|
||||
this.dataset.index = _.indexOf(this.dataset.ids, current_record_id);
|
||||
if (this.dataset.index < 0) {
|
||||
this.dataset.index = 0;
|
||||
}
|
||||
var field_to_column = function (field) {
|
||||
var name = field.attrs.name;
|
||||
var column = _.extend({id: name, tag: field.tag},
|
||||
field.attrs, fields[name]);
|
||||
// attrs computer
|
||||
if (column.attrs) {
|
||||
var attrs = eval('(' + column.attrs + ')');
|
||||
column.attrs_for = function (fields) {
|
||||
var result = {};
|
||||
for (var attr in attrs) {
|
||||
result[attr] = domain_computer(attrs[attr], fields);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
} else {
|
||||
column.attrs_for = function () { return {}; };
|
||||
}
|
||||
return column;
|
||||
};
|
||||
|
||||
this.dataset.count = this.dataset.ids.length;
|
||||
var results = this.rows.length;
|
||||
this.$element.find('table')
|
||||
.find('.oe-pager-last').text(results).end()
|
||||
.find('.oe-pager-total').text(results);
|
||||
this.columns.splice(0, this.columns.length);
|
||||
this.columns.push.apply(
|
||||
this.columns,
|
||||
_(this.fields_view.arch.children).map(field_to_column));
|
||||
|
||||
this.list.refresh();
|
||||
_(groupby_columns).each(function (column_id, index) {
|
||||
var column_index = _(self.columns).chain()
|
||||
.pluck('id').indexOf(column_id).value();
|
||||
var column = self.columns.splice(column_index, 1)[0];
|
||||
delete column.invisible;
|
||||
self.columns.splice(index, 0, column);
|
||||
});
|
||||
|
||||
this.visible_columns = _.filter(this.columns, function (column) {
|
||||
return column.invisible !== '1';
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Used to handle a click on a table row, if no other handler caught the
|
||||
|
@ -259,12 +229,16 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
|||
},
|
||||
/**
|
||||
* Reloads the search view based on the current settings (dataset & al)
|
||||
*
|
||||
* @param {Array} [primary_columns] columns to bring to the front of the
|
||||
* sequence
|
||||
*/
|
||||
do_reload: function () {
|
||||
do_reload: function (primary_columns) {
|
||||
// TODO: need to do 5 billion tons of pre-processing, bypass
|
||||
// DataSet for now
|
||||
//self.dataset.read_slice(self.dataset.fields, 0, self.limit,
|
||||
// self.do_fill_table);
|
||||
var self = this;
|
||||
this.dataset.offset = 0;
|
||||
this.dataset.limit = false;
|
||||
return this.rpc('/base/listview/fill', {
|
||||
|
@ -273,7 +247,11 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
|||
'context': this.dataset.context,
|
||||
'domain': this.dataset.domain,
|
||||
'sort': this.dataset.sort && this.dataset.sort()
|
||||
}, this.do_fill_table);
|
||||
}, function (result) {
|
||||
if (result.view) {
|
||||
self.on_loaded({fields_view: result.view}, primary_columns);
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Event handler for a search, asks for the computation/folding of domains
|
||||
|
@ -291,24 +269,15 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
|||
contexts: contexts,
|
||||
group_by_seq: groupbys
|
||||
}, function (results) {
|
||||
// TODO: handle non-empty results.group_by with read_group
|
||||
self.dataset.context = results.context;
|
||||
self.dataset.domain = results.domain;
|
||||
if (results.group_by.length) {
|
||||
self.groups.datagroup = new openerp.base.DataGroup(
|
||||
self.session, self.dataset.model,
|
||||
results.domain, results.context,
|
||||
results.group_by);
|
||||
self.$element.html(self.groups.render());
|
||||
return;
|
||||
}
|
||||
return self.do_reload();
|
||||
self.groups.datagroup = new openerp.base.DataGroup(
|
||||
self.session, self.dataset.model,
|
||||
results.domain, results.context,
|
||||
results.group_by);
|
||||
self.do_reload(results.group_by);
|
||||
});
|
||||
},
|
||||
do_update: function () {
|
||||
var self = this;
|
||||
//self.dataset.read_ids(self.dataset.ids, self.dataset.fields, self.do_fill_table);
|
||||
},
|
||||
/**
|
||||
* Handles the signal to delete a line from the DOM
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue