[IMP] convert listviews (non-editable anyway) to collections
bzr revid: xmo@openerp.com-20110817131635-cv3qcbiarmlk5o3o
This commit is contained in:
parent
2f8e6e62e5
commit
bd49735371
|
@ -50,6 +50,8 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
|||
|
||||
this.columns = [];
|
||||
|
||||
this.records = new Collection();
|
||||
|
||||
this.set_groups(new openerp.base.ListView.Groups(this));
|
||||
|
||||
if (this.dataset instanceof openerp.base.DataSetStatic) {
|
||||
|
@ -535,7 +537,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
|
|||
count += record.count || 1;
|
||||
_(columns).each(function (column) {
|
||||
var field = column.id,
|
||||
value = record.values[field];
|
||||
value = record.values.get(field);
|
||||
switch (column['function']) {
|
||||
case 'sum':
|
||||
sums[field] += value;
|
||||
|
@ -621,7 +623,7 @@ openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.
|
|||
this.options = opts.options;
|
||||
this.columns = opts.columns;
|
||||
this.dataset = opts.dataset;
|
||||
this.rows = opts.rows;
|
||||
this.records = opts.records;
|
||||
|
||||
this.$_element = $('<tbody class="ui-widget-content">')
|
||||
.appendTo(document.body)
|
||||
|
@ -657,7 +659,7 @@ openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.
|
|||
row_clicked: function () {
|
||||
$(this).trigger(
|
||||
'row_link',
|
||||
[this.rows[this.dataset.index].data.id.value,
|
||||
[this.records.at(this.dataset.index).get('id'),
|
||||
this.dataset]);
|
||||
},
|
||||
render: function () {
|
||||
|
@ -677,15 +679,12 @@ openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.
|
|||
if (!this.options.selectable) {
|
||||
return [];
|
||||
}
|
||||
var rows = this.rows;
|
||||
var records = this.records;
|
||||
var result = {ids: [], records: []};
|
||||
this.$current.find('th.oe-record-selector input:checked')
|
||||
.closest('tr').each(function () {
|
||||
var record = {};
|
||||
_(rows[$(this).data('index')].data).each(function (obj, key) {
|
||||
record[key] = obj.value;
|
||||
});
|
||||
result.ids.push(record.id);
|
||||
var record = records.at($(this).data('index'));
|
||||
result.ids.push(record.get('id'));
|
||||
result.records.push(record);
|
||||
});
|
||||
return result;
|
||||
|
@ -707,7 +706,7 @@ openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.
|
|||
* @returns {Number|String} the identifier of the row's object
|
||||
*/
|
||||
row_id: function (row) {
|
||||
return this.rows[this.row_position(row)].data.id.value;
|
||||
return this.records.at(this.row_position(row)).get('id');
|
||||
},
|
||||
/**
|
||||
* Death signal, cleans up list
|
||||
|
@ -719,41 +718,14 @@ openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.
|
|||
this.$_element.remove();
|
||||
},
|
||||
get_records: function () {
|
||||
return _(this.rows).map(function (row) {
|
||||
var record = {};
|
||||
_(row.data).each(function (obj, key) {
|
||||
record[key] = obj.value;
|
||||
});
|
||||
return {count: 1, values: record};
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Transforms a record from what is returned by a dataset read (a simple
|
||||
* mapping of ``$fieldname: $value``) to the format expected by list rows
|
||||
* and form views:
|
||||
*
|
||||
* data: {
|
||||
* $fieldname: {
|
||||
* value: $value
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* This format allows for the insertion of a bunch of metadata (names,
|
||||
* colors, etc...)
|
||||
*
|
||||
* @param {Object} record original record, in dataset format
|
||||
* @returns {Object} record displayable in a form or list view
|
||||
*/
|
||||
transform_record: function (record) {
|
||||
// TODO: colors handling
|
||||
var form_data = {},
|
||||
form_record = {data: form_data};
|
||||
|
||||
_(record).each(function (value, key) {
|
||||
form_data[key] = {value: value};
|
||||
});
|
||||
|
||||
return form_record;
|
||||
var records = [];
|
||||
for(var i=0, length=this.records.length; i<length; ++i) {
|
||||
records.push({
|
||||
count: 1,
|
||||
values: this.records.at(i)
|
||||
})
|
||||
}
|
||||
return records;
|
||||
},
|
||||
/**
|
||||
* Reloads the record at index ``row_index`` in the list's rows.
|
||||
|
@ -774,8 +746,10 @@ openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.
|
|||
read_p = this.dataset.read_index(
|
||||
_.pluck(_(this.columns).filter(function (r) {return r.tag === 'field';}), 'name'),
|
||||
function (record) {
|
||||
var form_record = self.transform_record(record);
|
||||
self.rows.splice(record_index, 1, form_record);
|
||||
var r = self.records.get(record.id);
|
||||
_(record).each(function (value, key) {
|
||||
r.set(key, value);
|
||||
});
|
||||
self.dataset.index = old_index;
|
||||
}
|
||||
)
|
||||
|
@ -795,7 +769,7 @@ openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.
|
|||
return QWeb.render('ListView.row', {
|
||||
columns: this.columns,
|
||||
options: this.options,
|
||||
row: this.rows[record_index],
|
||||
record: this.records.at(record_index),
|
||||
row_parity: (record_index % 2 === 0) ? 'even' : 'odd',
|
||||
row_index: record_index,
|
||||
render_cell: openerp.base.format_cell
|
||||
|
@ -807,17 +781,9 @@ openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.
|
|||
* @param {Array} ids identifiers of the records to remove
|
||||
*/
|
||||
drop_records: function (ids) {
|
||||
var self = this;
|
||||
_(this.rows).chain()
|
||||
.map(function (record, index) {
|
||||
return {index: index, id: record.data.id.value};
|
||||
}).filter(function (record) {
|
||||
return _(ids).contains(record.id);
|
||||
}).reverse()
|
||||
.each(function (record) {
|
||||
self.$current.find('tr:eq(' + record.index + ')').remove();
|
||||
self.rows.splice(record.index, 1);
|
||||
})
|
||||
for(var i=ids.length-1; i>=0; --i) {
|
||||
this.records.remove(this.records.get(ids[i]));
|
||||
}
|
||||
}
|
||||
// drag and drop
|
||||
});
|
||||
|
@ -829,11 +795,20 @@ openerp.base.ListView.Groups = openerp.base.Class.extend( /** @lends openerp.bas
|
|||
*
|
||||
* Provides events similar to those of
|
||||
* :js:class:`~openerp.base.ListView.List`
|
||||
*
|
||||
* @constructs
|
||||
* @param {openerp.base.ListView} view
|
||||
* @param {Object} [options]
|
||||
* @param {Collection} [options.records]
|
||||
* @param {Object} [options.options]
|
||||
* @param {Array} [options.columns]
|
||||
*/
|
||||
init: function (view) {
|
||||
init: function (view, options) {
|
||||
options = options || {};
|
||||
this.view = view;
|
||||
this.options = view.options;
|
||||
this.columns = view.columns;
|
||||
this.records = options.records || view.records;
|
||||
this.options = options.options || view.options;
|
||||
this.columns = options.columns || view.columns;
|
||||
this.datagroup = null;
|
||||
|
||||
this.$row = null;
|
||||
|
@ -925,6 +900,7 @@ openerp.base.ListView.Groups = openerp.base.Class.extend( /** @lends openerp.bas
|
|||
delete self.children[group.value];
|
||||
}
|
||||
var child = self.children[group.value] = new openerp.base.ListView.Groups(self.view, {
|
||||
records: self.records.proxy(group.value),
|
||||
options: self.options,
|
||||
columns: self.columns
|
||||
});
|
||||
|
@ -1019,13 +995,12 @@ openerp.base.ListView.Groups = openerp.base.Class.extend( /** @lends openerp.bas
|
|||
});
|
||||
},
|
||||
render_dataset: function (dataset) {
|
||||
var rows = [],
|
||||
self = this,
|
||||
var self = this,
|
||||
list = new openerp.base.ListView.List(this, {
|
||||
options: this.options,
|
||||
columns: this.columns,
|
||||
dataset: dataset,
|
||||
rows: rows
|
||||
records: this.records
|
||||
});
|
||||
this.bind_child_events(list);
|
||||
|
||||
|
@ -1054,11 +1029,7 @@ openerp.base.ListView.Groups = openerp.base.Class.extend( /** @lends openerp.bas
|
|||
.attr('disabled', page === pages - 1);
|
||||
}
|
||||
|
||||
var form_records = _(records).map(
|
||||
$.proxy(list, 'transform_record'));
|
||||
|
||||
rows.splice(0, rows.length);
|
||||
rows.push.apply(rows, form_records);
|
||||
self.records.reset(records);
|
||||
list.render();
|
||||
d.resolve(list);
|
||||
});
|
||||
|
@ -1078,7 +1049,9 @@ openerp.base.ListView.Groups = openerp.base.Class.extend( /** @lends openerp.bas
|
|||
var from = ui.item.data('index'),
|
||||
to = ui.item.prev().data('index') || 0;
|
||||
if (from === to) { return; }
|
||||
list.rows.splice(to, 0, list.rows.splice(from, 1)[0]);
|
||||
var to_move = list.records.at(from);
|
||||
list.records.remove(to_move);
|
||||
list.records.add(to_move, {at: to});
|
||||
|
||||
ui.item.parent().children().each(function (i, e) {
|
||||
// reset record-index accelerators on rows and even/odd
|
||||
|
@ -1089,17 +1062,16 @@ openerp.base.ListView.Groups = openerp.base.Class.extend( /** @lends openerp.bas
|
|||
});
|
||||
|
||||
// resequencing time!
|
||||
var data, index = to,
|
||||
var record, index = to,
|
||||
// if drag to 1st row (to = 0), start sequencing from 0
|
||||
// (exclusive lower bound)
|
||||
seq = to ? list.rows[to - 1].data.sequence.value : 0;
|
||||
while (++seq, list.rows[index]) {
|
||||
data = list.rows[index].data;
|
||||
data.sequence.value = seq;
|
||||
seq = to ? list.records.at(to - 1).get('sequence') : 0;
|
||||
while (++seq, record = list.records.at(index)) {
|
||||
record.set('sequence', seq);
|
||||
// write are independent from one another, so we can just
|
||||
// launch them all at the same time and we don't really
|
||||
// give a fig about when they're done
|
||||
dataset.write(data.id.value, {sequence: seq});
|
||||
dataset.write(record.get('id'), {sequence: seq});
|
||||
list.reload_record(index++);
|
||||
}
|
||||
}
|
||||
|
@ -1223,14 +1195,14 @@ var Record = openerp.base.Class.extend(/** @lends Record# */{
|
|||
* @param {Object} [data]
|
||||
*/
|
||||
init: function (data) {
|
||||
this.data = data || {};
|
||||
this.attributes = data || {};
|
||||
},
|
||||
/**
|
||||
* @param {String} key
|
||||
* @returns {Object}
|
||||
*/
|
||||
get: function (key) {
|
||||
return this.data[key];
|
||||
return this.attributes[key];
|
||||
},
|
||||
/**
|
||||
* @param key
|
||||
|
@ -1238,10 +1210,32 @@ var Record = openerp.base.Class.extend(/** @lends Record# */{
|
|||
* @returns {Record}
|
||||
*/
|
||||
set: function (key, value) {
|
||||
this.data[key] = value;
|
||||
this.attributes[key] = value;
|
||||
this.trigger('change:' + key, this, value);
|
||||
this.trigger('change', this);
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
* Converts the current record to the format expected by form views:
|
||||
*
|
||||
* .. code-block:: javascript
|
||||
*
|
||||
* data: {
|
||||
* $fieldname: {
|
||||
* value: $value
|
||||
* }
|
||||
* }
|
||||
*
|
||||
*
|
||||
* @returns {Object} record displayable in a form view
|
||||
*/
|
||||
toForm: function () {
|
||||
var form_data = {};
|
||||
_(this.attributes).each(function (value, key) {
|
||||
form_data[key] = {value: value};
|
||||
});
|
||||
|
||||
return {data: form_data};
|
||||
}
|
||||
});
|
||||
Record.include(Events);
|
||||
|
@ -1257,6 +1251,7 @@ var Collection = openerp.base.Class.extend(/** @lends Collection# */{
|
|||
init: function (records, options) {
|
||||
options = options || {};
|
||||
_.bindAll(this, '_onRecordEvent');
|
||||
this.length = 0;
|
||||
this.records = [];
|
||||
this._byId = {};
|
||||
this._proxies = {};
|
||||
|
@ -1269,16 +1264,24 @@ var Collection = openerp.base.Class.extend(/** @lends Collection# */{
|
|||
},
|
||||
/**
|
||||
* @param {Object|Array} record
|
||||
* @param {Object} [options]
|
||||
* @param {Number} [options.at]
|
||||
* @returns this
|
||||
*/
|
||||
add: function (record) {
|
||||
add: function (record, options) {
|
||||
options = options || {};
|
||||
var records = record instanceof Array ? record : [record];
|
||||
|
||||
for(var i=0, length=records.length; i<length; ++i) {
|
||||
var instance = (records[i] instanceof Record) ? records[i] : new Record(records[i]);
|
||||
instance.bind(null, this._onRecordEvent);
|
||||
this._byId[instance.get('id')] = instance;
|
||||
this.records.push(instance);
|
||||
if (options.at === undefined) {
|
||||
this.records.push(instance);
|
||||
} else {
|
||||
this.records.splice(options.at + i, 0, instance);
|
||||
}
|
||||
this.length++;
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
@ -1327,6 +1330,36 @@ var Collection = openerp.base.Class.extend(/** @lends Collection# */{
|
|||
key: section
|
||||
}).bind(null, this._onRecordEvent);
|
||||
},
|
||||
/**
|
||||
* @param {Array} [records]
|
||||
* @returns this
|
||||
*/
|
||||
reset: function (records) {
|
||||
this.length = 0;
|
||||
this.records = [];
|
||||
this._byId = {};
|
||||
if (records) {
|
||||
this.add(records);
|
||||
}
|
||||
this.trigger('reset', this);
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
* Removes the provided record from the collection
|
||||
*
|
||||
* @param {Record} record
|
||||
* @returns this
|
||||
*/
|
||||
remove: function (record) {
|
||||
var index = _(this.records).indexOf(record);
|
||||
if (index === -1) { return this; }
|
||||
|
||||
this.records.splice(index, 1);
|
||||
delete this._byId[record.get('id')];
|
||||
this.length--;
|
||||
this.trigger('remove', record, this);
|
||||
return this;
|
||||
},
|
||||
|
||||
_onRecordEvent: function (event, record, options) {
|
||||
this.trigger.apply(this, arguments);
|
||||
|
|
|
@ -555,8 +555,12 @@
|
|||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<t t-name="ListView.rows" t-foreach="rows" t-as="row">
|
||||
<t t-call="ListView.row"/>
|
||||
<t t-name="ListView.rows" t-foreach="records.length" t-as="index">
|
||||
<t t-call="ListView.row">
|
||||
<t t-set="record" t-value="records.at(index)"/>
|
||||
<t t-set="row_index" t-value="index"/>
|
||||
<t t-set="row_parity" t-value="index_parity"/>
|
||||
</t>
|
||||
</t>
|
||||
<tr t-name="ListView.row" t-att-class="row_parity"
|
||||
t-att-data-index="row_index">
|
||||
|
@ -573,7 +577,7 @@
|
|||
<td t-if="!column.meta and column.invisible !== '1'" t-att-title="column.help"
|
||||
t-att-class="'oe-field-cell' + (align ? ' oe-number' : '')"
|
||||
t-att-data-field="column.id">
|
||||
<t t-raw="render_cell(row.data, column)"/>
|
||||
<t t-raw="render_cell(record.toForm().data, column)"/>
|
||||
</td>
|
||||
</t>
|
||||
<td t-if="options.deletable" class='oe-record-delete' width="1">
|
||||
|
|
|
@ -107,10 +107,12 @@ $(document).ready(function () {
|
|||
});
|
||||
test('Fetch from collection', function () {
|
||||
var c = new openerp.base.list.Collection();
|
||||
strictEqual(c.length, 0);
|
||||
c.add({id: 1, value: 2});
|
||||
c.add({id: 2, value: 3});
|
||||
c.add({id: 3, value: 5});
|
||||
c.add({id: 4, value: 7});
|
||||
strictEqual(c.length, 4);
|
||||
var r = c.at(2), r2 = c.get(1);
|
||||
|
||||
ok(r instanceof openerp.base.list.Record);
|
||||
|
@ -121,6 +123,52 @@ $(document).ready(function () {
|
|||
strictEqual(r2.get('id'), 1);
|
||||
strictEqual(r2.get('value'), 2);
|
||||
});
|
||||
test('Add at index', function () {
|
||||
var c = new openerp.base.list.Collection([
|
||||
{id: 1, value: 5},
|
||||
{id: 2, value: 10},
|
||||
{id: 3, value: 20}
|
||||
]);
|
||||
strictEqual(c.at(1).get('value'), 10);
|
||||
equal(c.at(3), undefined);
|
||||
c.add({id:4, value: 55}, {at: 1});
|
||||
strictEqual(c.at(1).get('value'), 55);
|
||||
strictEqual(c.at(3).get('value'), 20);
|
||||
});
|
||||
test('Remove record', function () {
|
||||
var c = new openerp.base.list.Collection([
|
||||
{id: 1, value: 5},
|
||||
{id: 2, value: 10},
|
||||
{id: 3, value: 20}
|
||||
]);
|
||||
var record = c.get(2);
|
||||
strictEqual(c.length, 3);
|
||||
c.remove(record);
|
||||
strictEqual(c.length, 2);
|
||||
equal(c.get(2), undefined);
|
||||
strictEqual(c.at(1).get('value'), 20);
|
||||
});
|
||||
test('Reset', function () {
|
||||
var event, obj, c = new openerp.base.list.Collection([
|
||||
{id: 1, value: 5},
|
||||
{id: 2, value: 10},
|
||||
{id: 3, value: 20}
|
||||
]);
|
||||
c.bind(null, function (e, instance) { event = e; obj = instance; });
|
||||
c.reset();
|
||||
strictEqual(c.length, 0);
|
||||
strictEqual(event, 'reset');
|
||||
strictEqual(obj, c);
|
||||
c.add([
|
||||
{id: 1, value: 5},
|
||||
{id: 2, value: 10},
|
||||
{id: 3, value: 20}
|
||||
]);
|
||||
c.reset([{id: 42, value: 55}]);
|
||||
strictEqual(c.length, 1);
|
||||
strictEqual(c.get(42).get('value'), 55);
|
||||
});
|
||||
|
||||
test('Events propagation', function () {
|
||||
var values = [];
|
||||
var c = new openerp.base.list.Collection([
|
||||
|
|
Loading…
Reference in New Issue