continued work on hierarchical tree view
This commit is contained in:
parent
aa6b0f917f
commit
00bd00e1d3
4 changed files with 55 additions and 89 deletions
|
|
@ -9,6 +9,7 @@
|
||||||
<rng:define name="hlist">
|
<rng:define name="hlist">
|
||||||
<rng:element name="hlist">
|
<rng:element name="hlist">
|
||||||
<rng:attribute name="parent_field"/>
|
<rng:attribute name="parent_field"/>
|
||||||
|
<rng:attribute name="children_field"/>
|
||||||
<rng:optional><rng:attribute name="name"/></rng:optional>
|
<rng:optional><rng:attribute name="name"/></rng:optional>
|
||||||
<rng:optional><rng:attribute name="create"/></rng:optional>
|
<rng:optional><rng:attribute name="create"/></rng:optional>
|
||||||
<rng:optional><rng:attribute name="delete"/></rng:optional>
|
<rng:optional><rng:attribute name="delete"/></rng:optional>
|
||||||
|
|
|
||||||
|
|
@ -8,72 +8,11 @@ var HListModel = ListModel.extend({
|
||||||
* @param {string} params.parentField
|
* @param {string} params.parentField
|
||||||
*/
|
*/
|
||||||
init: function (parent, params) {
|
init: function (parent, params) {
|
||||||
|
var self = this;
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
this.parentField = params.parentField;
|
self.parentField = params.parentField;
|
||||||
},
|
self.loadParams.domain = _.union(self.loadParams.domain,
|
||||||
/**
|
[[self.parentField, '=', false]])
|
||||||
*
|
|
||||||
* @override
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_readGroup: function (list, options) {
|
|
||||||
var self = this;
|
|
||||||
return this._super(list, options).then(function (result) {
|
|
||||||
return self._readHierarchy(list).then(_.constant(result));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Fetches hierarchy specific fields on the parent field relation and stores them
|
|
||||||
* in the column datapoint in a special key 'hierarchyData'.
|
|
||||||
* Data for the hierarchy are fetched in batch for all hierarchies, to avoid
|
|
||||||
* multiple calls.
|
|
||||||
*
|
|
||||||
* @param {Object} list
|
|
||||||
* @private
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
_readHierarchy (list) {
|
|
||||||
const self = this;
|
|
||||||
const parentFieldName = self.parentField;
|
|
||||||
const parentField = list.fields[parentFieldName];
|
|
||||||
/* Each record should have only one parent */
|
|
||||||
if (parentField.type !== 'many2one') {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
const hierarchyIds = _.reduce(list.data, function (hierarchyIds, id) {
|
|
||||||
const resId = self.get(id, { raw: true }).res_id;
|
|
||||||
if (resId) {
|
|
||||||
hierarchyIds.push(resId);
|
|
||||||
}
|
|
||||||
return hierarchyIds;
|
|
||||||
}, []);
|
|
||||||
let prom;
|
|
||||||
if (hierarchyIds.length) {
|
|
||||||
prom = this._rpc({
|
|
||||||
model: list.model,
|
|
||||||
method: 'read',
|
|
||||||
args: [hierarchyIds, self.viewFields],
|
|
||||||
context: list.context,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Promise.resolve(prom).then(function (result) {
|
|
||||||
_.each(list.data, function(id) {
|
|
||||||
let dp = self.localData[id];
|
|
||||||
let hierarchyData = result && _.findWhere(result, {
|
|
||||||
id: dp.res_id,
|
|
||||||
});
|
|
||||||
let hierarchyDp = self._makeDataPoint({
|
|
||||||
context: dp.context,
|
|
||||||
data: hierarchyData,
|
|
||||||
fields: list.fields,
|
|
||||||
fieldsInfo: list.fieldsInfo,
|
|
||||||
modelName: list.model,
|
|
||||||
parentID: dp.id,
|
|
||||||
res_id: dp.res_id,
|
|
||||||
viewType: 'list',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,37 +2,57 @@
|
||||||
|
|
||||||
import {ListRenderer} from 'web.ListRenderer'
|
import {ListRenderer} from 'web.ListRenderer'
|
||||||
|
|
||||||
|
const toggleClass = 'o_hlist_toggle';
|
||||||
|
const toggleIconClass = 'fa-sitemap';
|
||||||
|
|
||||||
var HierarchicalListRenderer = ListRenderer.extend({
|
var HierarchicalListRenderer = ListRenderer.extend({
|
||||||
className: 'o_hlist_view',
|
className: 'o_hlist_view',
|
||||||
events: _.extend({}, ListRenderer.prototype.events, {
|
events: _.extend({}, ListRenderer.prototype.events, {
|
||||||
'click .o_hierarchy_parent': '_onToggleHierarchyGroup',
|
'click o_hlist_toggle': '_onToggleHierarchyGroup',
|
||||||
}),
|
}),
|
||||||
|
/**
|
||||||
|
* @param {string} params.parentField
|
||||||
|
* @param {string} params.childrenField
|
||||||
|
*/
|
||||||
init: function (parent, state, params) {
|
init: function (parent, state, params) {
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
},
|
|
||||||
_renderBody: function () {
|
|
||||||
this._super.apply(this);
|
|
||||||
|
|
||||||
},
|
this.parentField = params.parentField;
|
||||||
_renderHierarchy(data, hierarchyLevel) {
|
this.childrenField = params.childrenField;
|
||||||
|
}, // TODO: add header column on left side for toggle
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
* @private
|
||||||
|
* @param {Object} record
|
||||||
|
* @returns {jQueryElement} a <tr> element
|
||||||
|
*/
|
||||||
|
_renderRow: function (record) {
|
||||||
var self = this;
|
var self = this;
|
||||||
hierarchyLevel = hierarchyLevel || 0;
|
var $tr = this._super.apply(this, arguments)
|
||||||
var result = [];
|
if (this.childrenField in record.data) {
|
||||||
var $tbody = $('<tbody>');
|
let numChildren = record.data[this.childrenField].length
|
||||||
_.each(data, function (hierarchyGroup) {
|
if (numChildren > 0) {
|
||||||
if (!$tbody) {
|
$td = $('<td>', {class: toggleClass}).append(
|
||||||
$tbody = $('<tbody>');
|
$('<span>', {class: toggleIconClass, text: numChildren})
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
$tr.prepend($('<td>'))
|
||||||
}
|
}
|
||||||
$tbody.append(self._renderHierarchyRow(hierarchyGroup, hierarchyLevel));
|
}
|
||||||
if (hierarchyGroup.data.length) {
|
if (record.data.child_ids && record.data.child_ids.length) {
|
||||||
result.push($tbody);
|
$tr.prepend(this._renderHierarchyToggle(record));
|
||||||
result = result.concat(self._renderHierarchyParent(hierarchyGroup,
|
} else {
|
||||||
hierarchyLevel));
|
$tr.prepend($('<td>'))
|
||||||
$tbody = null;
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
_renderHierarchyParent(hierarchyGroup, hierarchyLevel) {
|
/**
|
||||||
|
*
|
||||||
|
* @param record
|
||||||
|
* @private
|
||||||
|
* @returns {jQueryElement} a <td> element
|
||||||
|
*/
|
||||||
|
_renderHierarchyToggle: function (record) {
|
||||||
|
let numChildren = record.data[this.childrenField].length
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -30,7 +30,8 @@ var HListView = ListView.extend({
|
||||||
* @param {Object} viewInfo
|
* @param {Object} viewInfo
|
||||||
* @param {Object} params
|
* @param {Object} params
|
||||||
* @param {boolean} params.hasActionMenus
|
* @param {boolean} params.hasActionMenus
|
||||||
* @param {string} [params.parentField]
|
* @param {string} params.parentField
|
||||||
|
* @param {string} params.childrenField
|
||||||
* @param {boolean} [params.hasSelectors=true]
|
* @param {boolean} [params.hasSelectors=true]
|
||||||
*/
|
*/
|
||||||
init: function(viewInfo, params) {
|
init: function(viewInfo, params) {
|
||||||
|
|
@ -41,8 +42,13 @@ var HListView = ListView.extend({
|
||||||
_updateMVCParams: function() {
|
_updateMVCParams: function() {
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
var attrs = this.arch.attrs;
|
var attrs = this.arch.attrs;
|
||||||
this.loadParams.parentField = attrs.parentField;
|
|
||||||
this.modelParams.parentField = attrs.parentField;
|
this.loadParams.parentField = attrs.parent_field;
|
||||||
|
|
||||||
|
this.modelParams.parentField = attrs.parent_field;
|
||||||
|
|
||||||
|
this.rendererParams.parentField = this.modelParams.parentField
|
||||||
|
this.rendererParams.childrenField = attrs.childrenField
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue