From d4ee05255c35e99a10526d84652723223e8a4984 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 24 Mar 2011 13:42:21 +0100 Subject: [PATCH 01/39] [IMP] make qweb raise an error on template not found bzr revid: xmo@openerp.com-20110324124221-jnnrznrg3a4w02rx --- addons/base/static/qweb/qweb.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/base/static/qweb/qweb.js b/addons/base/static/qweb/qweb.js index 46c2824a278..c12af4e0f45 100644 --- a/addons/base/static/qweb/qweb.js +++ b/addons/base/static/qweb/qweb.js @@ -400,7 +400,7 @@ var QWeb = { if (e = this.templates[name]) { return this.render_node(e, v); } - return "template " + name + " not found"; + throw new Error("template " + name + " not found"); } }; From a8f877e6f0bf51b5845cf2e07970f48eed2eed18 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 24 Mar 2011 13:46:53 +0100 Subject: [PATCH 02/39] [ADD] start of widgets-based search view, break search itself (for now) and get the same result as before I broke everything layout-wise (woohoo) bzr revid: xmo@openerp.com-20110324124653-kn5c69ytuieu68gn --- addons/base/static/openerp/base.css | 1 + addons/base/static/openerp/base.xml | 115 ++++------- addons/base/static/openerp/js/base_views.js | 201 +++++++++++++++----- 3 files changed, 193 insertions(+), 124 deletions(-) diff --git a/addons/base/static/openerp/base.css b/addons/base/static/openerp/base.css index 316b0aa3902..f27a4a23ccc 100644 --- a/addons/base/static/openerp/base.css +++ b/addons/base/static/openerp/base.css @@ -348,6 +348,7 @@ body.openerp { } .openerp .filter_label_group { padding-right: 0.4em; + white-space: nowrap; } .openerp .filter_label_group button:first-child { border-left: 1px solid #666; diff --git a/addons/base/static/openerp/base.xml b/addons/base/static/openerp/base.xml index 11f562f02f1..1f7bc7aa088 100644 --- a/addons/base/static/openerp/base.xml +++ b/addons/base/static/openerp/base.xml @@ -276,86 +276,51 @@ -

- - - - - - - -
+

+ + +
- - - - <td nowrap="true" valign="bottom" class="filter_label_group"> - - - - </td> - - - - - - - - </tr> - </table> - <table border="0" cellspacing="0" cellpadding="0"> - <tr> - - - - - -
- -
- -
- - - -
- -
- - - - -
-
-
- - </tr> - </table> - <table border="0" cellspacing="0" cellpadding="0"> - <tr> -
- - - + + + + + +
+ +
- - - - - - - + +
+ + +
+ +
+
+ +
+ +
+ +
+
diff --git a/addons/base/static/openerp/js/base_views.js b/addons/base/static/openerp/js/base_views.js index cbb4e173cf4..11c7eefd8df 100644 --- a/addons/base/static/openerp/js/base_views.js +++ b/addons/base/static/openerp/js/base_views.js @@ -371,63 +371,166 @@ openerp.base.SearchView = openerp.base.Controller.extend({ //this.log('Starting SearchView '+this.model+this.view_id) this.rpc("/base/searchview/load", {"model": this.model, "view_id":this.view_id}, this.on_loaded); }, + /** + * Builds a list of widget rows (each row is an array of widgets) + * + * @param {Array} items a list of nodes to convert to widgets + * @param {Object} fields a mapping of field names to (ORM) field attributes + */ + make_widgets: function (items, fields) { + var rows = [], + row = []; + rows.push(row); + var filters = []; + _.each(items, function (item) { + if (filters.length && item.tag !== 'filter') { + row.push( + new openerp.base.search.FilterGroup( + filters, this)); + filters = []; + } + + if (item.tag === 'newline') { + row = []; + rows.push(row); + } else if (item.tag === 'filter') { + filters.push( + new openerp.base.search.Filter( + item, this)); + } else if (item.tag === 'separator') { + // a separator is a no-op + } else { + if (item.tag === 'group') { + // TODO: group and field should be fetched from registries, maybe even filters + row.push( + new openerp.base.search.Group( + item, this, fields)); + } else if (item.tag === 'field') { + row.push( + this.make_field( + item, fields[item['attrs'].name])); + } + } + }, this); + + return rows; + }, + /** + * + */ + make_field: function (item, field) { + // TODO: should fetch from an actual registry + // TODO: register fields in self? + switch (field.type) { + case 'char': + return new openerp.base.search.CharField( + item, field, this); + case 'float': + return new openerp.base.search.FloatField( + item, field, this); + case 'datetime': + return new openerp.base.search.DateTimeField( + item, field, this); + case 'one2many': + return new openerp.base.search.OneToManyField( + item, field, this); + case 'many2one': + return new openerp.base.search.ManyToOneField( + item, field, this); + default: + console.group('Unknown field type ' + field.type); + console.error('View node', item); + console.info('View field', field); + console.info('In view', this); + console.groupEnd(); + } + }, on_loaded: function(data) { - this.fields_view = data.fields_view; - this.log(this.fields_view); - this.input_ids = {}; - this.$element.html(QWeb.render("SearchView", {"fields_view": this.fields_view})); - this.$element.find("#search").bind('click',this.on_search); - // TODO bind click event on all button - // TODO we don't do many2one yet, but in the future bind a many2one controller on them - this.log(this.$element.find("#search")); - }, - register_input: function(node) { - // self should be passed in the qweb dict to do: - // + var lines = this.make_widgets( + data.fields_view['arch'].children, + data.fields_view.fields); - // generate id - var id = this.element_id + "_" + this.input_index++; - // TODO construct a nice object - // save it in our registry - this.input_ids[id] = { - node: node, - type: "filter", - domain: "", - context: "", - disabled: false - }; + // TODO: get default values + var default_values = {}; - return id; + var render = QWeb.render("SearchView", { + 'view': data.fields_view['arch'], + 'lines': lines, + 'defaults': default_values + }); + this.$element.html(render); + // TODO: setup events }, - on_click: function() { - // event catched on a button - // flip the disabled flag - // adjust the css class - }, - on_search: function() { - this.log("on_search"); - // collect all non disabled domains definitions, AND them - // evaluate as python expression - // save the result in this.domain - this.dataset.fetch(); - }, - on_clear: function() { - } + on_search: function () {} }); -openerp.base.SearchViewInput = openerp.base.Controller.extend({ -// TODO not sure should we create a controller for every input ? - -// of we just keep a simple dict for each input in -// openerp.base.SearchView#input_ids -// and use if when we get an event depending on the type -// i think it's less bloated to avoid useless controllers - -// but i think for many2one a controller would be nice -// so simple dict for simple inputs -// an controller for many2one ? +openerp.base.search = {}; +openerp.base.search.Widget = openerp.base.Controller.extend({ + template: null, + init: function (view) { + this.view = view; + }, + render: function (defaults) { + return QWeb.render( + this.template, _.extend(this, { + defaults: defaults + })); + } + // TODO: rendering + // TODO: validation +}); +openerp.base.search.Filter = openerp.base.search.Widget.extend({ + template: 'SearchView.filter', + // TODO: force rendering + init: function (node, view) { + this._super(view); + this.attrs = node.attrs; + } +}); +openerp.base.search.FilterGroup = openerp.base.search.Widget.extend({ + template: 'SearchView.filters', + init: function (filters, view) { + this._super(view); + this.filters = filters; + } +}); +openerp.base.search.Group = openerp.base.search.Widget.extend({ + template: 'SearchView.group', + // TODO: contain stuff + // TODO: @expand + init: function (view_section, view, fields) { + this._super(view); + this.attrs = view_section.attrs; + this.lines = view.make_widgets( + view_section.children, fields); + } +}); +openerp.base.search.Field = openerp.base.search.Widget.extend({ + template: 'SearchView.field', + // TODO: set default values + // TODO: get context, domain + // TODO: holds Filters + init: function (view_section, field, view) { + this._super(view); + this.attrs = _.extend({}, field, view_section.attrs); + } +}); +openerp.base.search.CharField = openerp.base.search.Field.extend({ + // TODO: .size +}); +openerp.base.search.FloatField = openerp.base.search.Field.extend({ + // TODO: .digits (a, b) +}); +openerp.base.search.DateTimeField = openerp.base.search.Field.extend({ }); +openerp.base.search.OneToManyField = openerp.base.search.Field.extend({ + // TODO: .relation, .context, .domain +}); +openerp.base.search.ManyToOneField = openerp.base.search.Field.extend({ + // TODO: @widget + // TODO: .relation, .selection, .context, .domain +}); openerp.base.FormView = openerp.base.Controller.extend({ init: function(session, element_id, dataset, view_id) { From 8a0faeb73f5b8a8af5d3124d443b9fc16f1ec4d0 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 24 Mar 2011 15:23:30 +0100 Subject: [PATCH 03/39] [add] kinda forgot about the filters-within-fields things bzr revid: xmo@openerp.com-20110324142330-711hpfm4younpcim --- addons/base/static/openerp/base.xml | 7 ++++--- addons/base/static/openerp/js/base_views.js | 5 +++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/addons/base/static/openerp/base.xml b/addons/base/static/openerp/base.xml index 1f7bc7aa088..3cb1820e0c6 100644 --- a/addons/base/static/openerp/base.xml +++ b/addons/base/static/openerp/base.xml @@ -302,17 +302,18 @@
-
+> -
+
+
diff --git a/addons/base/static/openerp/js/base_views.js b/addons/base/static/openerp/js/base_views.js index 11c7eefd8df..975cd2ddec5 100644 --- a/addons/base/static/openerp/js/base_views.js +++ b/addons/base/static/openerp/js/base_views.js @@ -513,6 +513,11 @@ openerp.base.search.Field = openerp.base.search.Widget.extend({ init: function (view_section, field, view) { this._super(view); this.attrs = _.extend({}, field, view_section.attrs); + this.filters = new openerp.base.search.FilterGroup(_.map( + view_section.children, function (filter_node) { + return new openerp.base.search.Filter( + filter_node, view); + }), view); } }); openerp.base.search.CharField = openerp.base.search.Field.extend({ From 491e6017af247e98ad6cd43189d810fe11a0bdca Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 24 Mar 2011 17:18:42 +0100 Subject: [PATCH 04/39] [ADD] a bunch of stuff to make it possible to enable and disable filters when clicking on them (yay) bzr revid: xmo@openerp.com-20110324161842-6lri6u9pu0msa5cx --- addons/base/static/openerp/base.xml | 21 +-- addons/base/static/openerp/js/base_views.js | 141 +++++++++++++++++--- 2 files changed, 138 insertions(+), 24 deletions(-) diff --git a/addons/base/static/openerp/base.xml b/addons/base/static/openerp/base.xml index 3cb1820e0c6..3d3a3fe856b 100644 --- a/addons/base/static/openerp/base.xml +++ b/addons/base/static/openerp/base.xml @@ -278,12 +278,14 @@

- +
+ -
- - -
+
+ + +
+