diff --git a/bemade_hierarchical_tree_view/rng/hlist.rng b/bemade_hierarchical_tree_view/rng/hlist.rng new file mode 100644 index 0000000..05fa01e --- /dev/null +++ b/bemade_hierarchical_tree_view/rng/hlist.rng @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + top + bottom + + + + + + + + + + + + + diff --git a/bemade_hierarchical_tree_view/static/src/js/hlist_controller.js b/bemade_hierarchical_tree_view/static/src/js/hlist_controller.js new file mode 100644 index 0000000..47f75bb --- /dev/null +++ b/bemade_hierarchical_tree_view/static/src/js/hlist_controller.js @@ -0,0 +1,15 @@ +/** @odoo-module alias=htree.HListController **/ + +import ListController from 'web.ListController'; + +var HListController = ListController.extend({ + custom_events: _.extend({}, ListController.prototype.custom_events, { + toggle_hierarchy: '_onToggleHierarchy' + }), + init: function(parent, model, renderer, params) { + this._super.apply(this, arguments); + }, + _onToggleHierarchy: function(ev) { + + }, +}) \ No newline at end of file diff --git a/bemade_hierarchical_tree_view/static/src/js/hlist_model.js b/bemade_hierarchical_tree_view/static/src/js/hlist_model.js new file mode 100644 index 0000000..90bd9a9 --- /dev/null +++ b/bemade_hierarchical_tree_view/static/src/js/hlist_model.js @@ -0,0 +1,80 @@ +/** @odoo-module alias=htree.HListModel **/ + +import ListModel from 'web.ListModel' + +var HListModel = ListModel.extend({ + /** + * @override + * @param {string} params.parentField + */ + init: function (parent, params) { + this._super.apply(this, arguments); + this.parentField = params.parentField; + }, + /** + * + * @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', + }); + }); + }); + }, +}) + +export default HListModel; \ No newline at end of file diff --git a/bemade_hierarchical_tree_view/static/src/js/hlist_renderer.js b/bemade_hierarchical_tree_view/static/src/js/hlist_renderer.js new file mode 100644 index 0000000..9f76705 --- /dev/null +++ b/bemade_hierarchical_tree_view/static/src/js/hlist_renderer.js @@ -0,0 +1,38 @@ +/** @odoo-module alias=htree.HListRenderer **/ + +import {ListRenderer} from 'web.ListRenderer' + +var HierarchicalListRenderer = ListRenderer.extend({ + className: 'o_hlist_view', + events: _.extend({}, ListRenderer.prototype.events, { + 'click .o_hierarchy_parent': '_onToggleHierarchyGroup', + }), + init: function (parent, state, params) { + this._super.apply(this, arguments); + }, + _renderBody: function () { + this._super.apply(this); + + }, + _renderHierarchy(data, hierarchyLevel) { + var self = this; + hierarchyLevel = hierarchyLevel || 0; + var result = []; + var $tbody = $(''); + _.each(data, function (hierarchyGroup) { + if (!$tbody) { + $tbody = $(''); + } + $tbody.append(self._renderHierarchyRow(hierarchyGroup, hierarchyLevel)); + if (hierarchyGroup.data.length) { + result.push($tbody); + result = result.concat(self._renderHierarchyParent(hierarchyGroup, + hierarchyLevel)); + $tbody = null; + } + }) + }, + _renderHierarchyParent(hierarchyGroup, hierarchyLevel) { + + } +}) \ No newline at end of file diff --git a/bemade_hierarchical_tree_view/static/src/js/hlist_view.js b/bemade_hierarchical_tree_view/static/src/js/hlist_view.js new file mode 100644 index 0000000..0ec0497 --- /dev/null +++ b/bemade_hierarchical_tree_view/static/src/js/hlist_view.js @@ -0,0 +1,49 @@ +/** @odoo-module alias=htree.HListView **/ + +/** + * The Hierarchical List view extends the base List View from Odoo by adding + * a toggle to expand/collapse a hierarchy of records with children. + */ + +import ListView from 'web.ListView'; +import viewRegistry from 'web.view_registry'; +import HListRenderer from 'htree.HListRenderer'; +import HListController from 'htree.HListController'; +import HListModel from 'htree.HListModel'; + + +var HListView = ListView.extend({ + accesskey: 't', + icon: 'fa-sitemap', + display_name: _lt("Hierarchical Tree"), + config: _.extend({}, ListView.prototype.config, { + Model: HListModel, + Controller: HListController, + Renderer: HListRenderer, + }), + viewType: 'hlist', + /** + * Add a parentField parameter to allow for hierarchy display. + * + * @override + * + * @param {Object} viewInfo + * @param {Object} params + * @param {boolean} params.hasActionMenus + * @param {string} [params.parentField] + * @param {boolean} [params.hasSelectors=true] + */ + init: function(viewInfo, params) { + var self = this; + this._super.apply(this, arguments); + this.parentField = params.parentField + }, + _updateMVCParams: function() { + this._super.apply(this, arguments); + var attrs = this.arch.attrs; + this.loadParams.parentField = attrs.parentField; + this.modelParams.parentField = attrs.parentField; + } +}); + +viewRegistry.add('hlist', HListView);