summaryrefslogtreecommitdiff
path: root/addons/base
diff options
context:
space:
mode:
authorFabien Meghazi <fme@openerp.com>2011-07-27 13:44:30 +0200
committerFabien Meghazi <fme@openerp.com>2011-07-27 13:44:30 +0200
commit5ca8686fcc08a5b4a927e9ef57ed00a881a12d8a (patch)
treed02887726be15fcc93da8f5d3b4f0dfeecf727fe /addons/base
parent883380866e8917594525a7a0877f56729df8f238 (diff)
parent216ab84e5f27927ff1bf664ac8bdf38bbed57897 (diff)
[MERGE] Merge with trunk
bzr revid: fme@openerp.com-20110727114430-kzyiq9avv2kur1zm
Diffstat (limited to 'addons/base')
-rw-r--r--addons/base/controllers/main.py19
-rw-r--r--addons/base/static/src/css/base.css4
-rw-r--r--addons/base/static/src/js/chrome.js16
-rw-r--r--addons/base/static/src/js/data.js15
-rw-r--r--addons/base/static/src/js/form.js198
-rw-r--r--addons/base/static/src/js/list.js128
-rw-r--r--addons/base/static/src/js/search.js74
-rw-r--r--addons/base/static/src/js/views.js166
-rw-r--r--addons/base/static/src/xml/base.xml75
-rw-r--r--addons/base/static/test/list.js25
10 files changed, 451 insertions, 269 deletions
diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py
index 2c2a1f26a44..d1917aa764b 100644
--- a/addons/base/controllers/main.py
+++ b/addons/base/controllers/main.py
@@ -775,6 +775,25 @@ class SearchView(View):
filter["context"] = req.session.eval_context(self.parse_context(filter["context"], req.session))
filter["domain"] = req.session.eval_domain(self.parse_domain(filter["domain"], req.session))
return filters
+
+ @openerpweb.jsonrequest
+ def save_filter(self, req, model, name, context_to_save, domain):
+ Model = req.session.model("ir.filters")
+ ctx = openerpweb.nonliterals.CompoundContext(context_to_save)
+ ctx.session = req.session
+ ctx = ctx.evaluate()
+ domain = openerpweb.nonliterals.CompoundDomain(domain)
+ domain.session = req.session
+ domain = domain.evaluate()
+ uid = req.session._uid
+ context = req.session.eval_context(req.context)
+ to_return = Model.create_or_replace({"context": ctx,
+ "domain": domain,
+ "model_id": model,
+ "name": name,
+ "user_id": uid
+ }, context)
+ return to_return
class Binary(openerpweb.Controller):
_cp_path = "/base/binary"
diff --git a/addons/base/static/src/css/base.css b/addons/base/static/src/css/base.css
index dbb7d101f96..bbf8cba0fe7 100644
--- a/addons/base/static/src/css/base.css
+++ b/addons/base/static/src/css/base.css
@@ -1020,6 +1020,10 @@ background: linear-gradient(top, #ffffff 0%,#ebe9e9 100%); /* W3C */
.openerp .closed-sidebar .toggle-sidebar {
border-left: none;
}
+.openerp li.oe_sidebar_print {
+ padding-left: 20px;
+ background: 1px 3px url(../img/icons/gtk-print.png) no-repeat;
+}
.openerp.kitten-mode-activated .main_table {
background: url(http://placekitten.com/g/1500/800) repeat;
diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js
index bd535e60129..2cc16acc7ef 100644
--- a/addons/base/static/src/js/chrome.js
+++ b/addons/base/static/src/js/chrome.js
@@ -246,7 +246,7 @@ openerp.base.Session = openerp.base.Controller.extend( /** @lends openerp.base.S
* @param port
*/
init: function(parent, element_id, server, port) {
- this._super(element_id);
+ this._super(parent, element_id);
this.server = (server == undefined) ? location.hostname : server;
this.port = (port == undefined) ? location.port : port;
this.rpc_mode = (server == location.hostname) ? "ajax" : "jsonp";
@@ -425,7 +425,7 @@ openerp.base.Session = openerp.base.Controller.extend( /** @lends openerp.base.S
for(var i=0; i<cookies.length; ++i) {
var cookie = cookies[i].replace(/^\s*/, '');
if(cookie.indexOf(nameEQ) === 0) {
- return decodeURIComponent(cookie.substring(nameEQ.length));
+ return JSON.parse(decodeURIComponent(cookie.substring(nameEQ.length)));
}
}
return null;
@@ -441,7 +441,7 @@ openerp.base.Session = openerp.base.Controller.extend( /** @lends openerp.base.S
set_cookie: function (name, value, ttl) {
ttl = ttl || 24*60*60*365;
document.cookie = [
- this.element_id + '|' + name + '=' + encodeURIComponent(value),
+ this.element_id + '|' + name + '=' + encodeURIComponent(JSON.stringify(value)),
'max-age=' + ttl,
'expires=' + new Date(new Date().getTime() + ttl*1000).toGMTString()
].join(';');
@@ -532,6 +532,7 @@ openerp.base.Dialog = openerp.base.BaseWidget.extend({
dialog_title: "",
identifier_prefix: 'dialog',
init: function (parent, options) {
+ var self = this;
this._super(parent);
this.options = {
modal: true,
@@ -542,7 +543,10 @@ openerp.base.Dialog = openerp.base.BaseWidget.extend({
min_height: 0,
max_height: '100%',
autoOpen: false,
- buttons: {}
+ buttons: {},
+ close: function () {
+ self.stop();
+ }
};
for (var f in this) {
if (f.substr(0, 10) == 'on_button_') {
@@ -605,11 +609,7 @@ openerp.base.Dialog = openerp.base.BaseWidget.extend({
this.set_options(options);
this.$dialog.dialog(this.options).dialog('open');
},
- close: function(options) {
- this.$dialog.dialog('close');
- },
stop: function () {
- this.close();
this.$dialog.dialog('destroy');
}
});
diff --git a/addons/base/static/src/js/data.js b/addons/base/static/src/js/data.js
index 2e89dacceb8..385bd93d360 100644
--- a/addons/base/static/src/js/data.js
+++ b/addons/base/static/src/js/data.js
@@ -492,24 +492,33 @@ openerp.base.BufferedDataSet = openerp.base.DataSetStatic.extend({
this.to_create.push(cached);
this.cache.push(cached);
var to_return = $.Deferred().then(callback);
- setTimeout(function() {to_return.resolve({result: cached.id});}, 0);
+ to_return.resolve({result: cached.id});
return to_return.promise();
},
write: function (id, data, callback) {
var self = this;
var record = _.detect(this.to_create, function(x) {return x.id === id;});
record = record || _.detect(this.to_write, function(x) {return x.id === id;});
+ var dirty = false;
if (record) {
+ for (k in data) {
+ if (record.values[k] === undefined || record.values[k] !== data[k]) {
+ dirty = true;
+ break;
+ }
+ }
$.extend(record.values, data);
} else {
+ dirty = true;
record = {id: id, values: data};
self.to_write.push(record);
}
var cached = _.detect(this.cache, function(x) {return x.id === id;});
$.extend(cached.values, record.values);
- this.on_change();
+ if (dirty)
+ this.on_change();
var to_return = $.Deferred().then(callback);
- setTimeout(function () {to_return.resolve({result: true});}, 0);
+ to_return.resolve({result: true});
return to_return.promise();
},
unlink: function(ids, callback, error_callback) {
diff --git a/addons/base/static/src/js/form.js b/addons/base/static/src/js/form.js
index 25dcca611bd..d5a87a78309 100644
--- a/addons/base/static/src/js/form.js
+++ b/addons/base/static/src/js/form.js
@@ -1,7 +1,7 @@
openerp.base.form = function (openerp) {
openerp.base.views.add('form', 'openerp.base.FormView');
-openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormView# */{
+openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormView# */{
/**
* Indicates that this view is not searchable, and thus that no search
* view should be displayed (if there is one active).
@@ -19,6 +19,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
*/
init: function(parent, element_id, dataset, view_id, options) {
this._super(parent, element_id);
+ this.set_default_options();
this.view_manager = parent || new openerp.base.NullViewManager();
this.dataset = dataset;
this.model = dataset.model;
@@ -30,8 +31,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
this.datarecord = {};
this.ready = false;
this.show_invalid = true;
- this.touched = false;
- this.flags = this.view_manager.flags || {};
+ this.dirty = false;
this.default_focus_field = null;
this.default_focus_button = null;
this.registry = openerp.base.form.widgets;
@@ -53,10 +53,14 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
context.add(this.view_manager.action.context);
}
return this.rpc("/base/formview/load", {"model": this.model, "view_id": this.view_id,
- toolbar:!!this.flags.sidebar, context: context}, this.on_loaded);
+ toolbar: this.options.sidebar, context: context}, this.on_loaded);
}
},
stop: function() {
+ if (this.sidebar) {
+ this.sidebar.attachments.stop();
+ this.sidebar.stop();
+ }
_.each(this.widgets, function(w) {
w.stop();
});
@@ -85,12 +89,16 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
$('<xmp>' + openerp.base.json_node_to_xml(self.fields_view.arch, true) + '</xmp>').dialog({ width: '95%', height: 600});
});
- if(this.view_manager.sidebar)
- this.view_manager.sidebar.set_toolbar(data.fields_view.toolbar);
+ if (this.options.sidebar && this.options.sidebar_id) {
+ this.sidebar = new openerp.base.Sidebar(this, this.options.sidebar_id);
+ this.sidebar.start();
+ this.sidebar.attachments = new openerp.base.form.SidebarAttachments(this.sidebar, this.sidebar.add_section("Attachments"), this);
+ this.sidebar.add_toolbar(data.fields_view.toolbar);
+ this.sidebar.do_unfold();
+ }
this.has_been_loaded.resolve();
},
do_show: function () {
- var self = this;
var promise;
if (this.dataset.index === null) {
// null index means we should start a new record
@@ -98,13 +106,17 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
} else {
promise = this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded);
}
- self.$element.show();
- if(this.view_manager.sidebar)
- this.view_manager.sidebar.do_refresh(true);
+ this.$element.show();
+ if (this.sidebar) {
+ this.sidebar.$element.show();
+ }
return promise;
},
do_hide: function () {
this.$element.hide();
+ if (this.sidebar) {
+ this.sidebar.$element.hide();
+ }
},
on_record_loaded: function(record) {
if (!record) {
@@ -121,22 +133,22 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
this.$form_header.find('.oe_form_on_update').show();
this.$form_header.find('button.oe_form_button_new').show();
}
- this.touched = false;
+ this.dirty = false;
this.datarecord = record;
for (var f in this.fields) {
var field = this.fields[f];
- field.touched = false;
+ field.dirty = false;
field.set_value(this.datarecord[f] || false);
field.validate();
}
if (!record.id) {
// New record: Second pass in order to trigger the onchanges
- this.touched = true;
+ this.dirty = true;
this.show_invalid = false;
for (var f in record) {
var field = this.fields[f];
if (field) {
- field.touched = true;
+ field.dirty = true;
this.do_onchange(field);
}
}
@@ -144,7 +156,9 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
this.on_form_changed();
this.show_invalid = this.ready = true;
this.do_update_pager(record.id == null);
- this.do_update_sidebar();
+ if (this.sidebar) {
+ this.sidebar.attachments.do_update();
+ }
if (this.default_focus_field) {
this.default_focus_field.focus();
}
@@ -253,7 +267,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
processed.push(field.name);
if (field.get_value() != value) {
field.set_value(value);
- field.touched = true;
+ field.dirty = true;
if (_.indexOf(processed, field.name) < 0) {
this.do_onchange(field, processed);
}
@@ -301,37 +315,40 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
if (!this.ready) {
return false;
}
- var invalid = false,
+ var form_dirty = false,
+ form_invalid = false,
values = {},
first_invalid_field = null;
for (var f in this.fields) {
f = this.fields[f];
- if (f.invalid) {
- invalid = true;
+ if (!f.is_valid()) {
+ form_invalid = true;
f.update_dom();
if (!first_invalid_field) {
first_invalid_field = f;
}
- } else if (f.touched) {
+ } else if (f.is_dirty()) {
+ form_dirty = true;
values[f.name] = f.get_value();
}
}
- if (invalid) {
+ if (form_invalid) {
first_invalid_field.focus();
this.on_invalid();
return false;
- } else {
+ } else if (form_dirty) {
this.log("About to save", values);
if (!this.datarecord.id) {
- this.dataset.create(values, function(r) {
+ return this.dataset.create(values, function(r) {
self.on_created(r, success, prepend_on_create);
});
} else {
- this.dataset.write(this.datarecord.id, values, function(r) {
+ return this.dataset.write(this.datarecord.id, values, function(r) {
self.on_saved(r, success);
});
}
- return true;
+ } else {
+ return false;
}
},
do_save_edit: function() {
@@ -345,7 +362,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
on_invalid: function() {
var msg = "<ul>";
_.each(this.fields, function(f) {
- if (f.invalid) {
+ if (!f.is_valid()) {
msg += "<li>" + f.string + "</li>";
}
});
@@ -389,7 +406,9 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
this.dataset.index = 0;
}
this.do_update_pager();
- this.do_update_sidebar();
+ if (this.sidebar) {
+ this.sidebar.attachments.do_update();
+ }
this.notification.notify("Record created", "The record has been created with id #" + this.datarecord.id);
if (success) {
success(_.extend(r, {created: true}));
@@ -406,34 +425,55 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
do_cancel: function () {
this.notification.notify("Cancelling form");
},
- do_update_sidebar: function() {
- if (this.flags.sidebar === false || this.view_manager.sidebar === undefined) {
- return;
+ reload: function() {
+ if (this.datarecord.id) {
+ this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded);
+ } else {
+ this.on_button_new();
}
- if (!this.datarecord.id) {
+ },
+ get_fields_values: function() {
+ var values = {};
+ _.each(this.fields, function(value, key) {
+ var val = value.get_value();
+ values[key] = val;
+ });
+ return values;
+ }
+});
+
+/** @namespace */
+openerp.base.form = {};
+
+openerp.base.form.SidebarAttachments = openerp.base.Controller.extend({
+ init: function(parent, element_id, form_view) {
+ this._super(parent, element_id);
+ this.view = form_view;
+ },
+ do_update: function() {
+ if (!this.view.datarecord.id) {
this.on_attachments_loaded([]);
} else {
(new openerp.base.DataSetSearch(
- this, 'ir.attachment', this.dataset.get_context(),
- [['res_model', '=', this.dataset.model],
- ['res_id', '=', this.datarecord.id],
+ this, 'ir.attachment', this.view.dataset.get_context(),
+ [['res_model', '=', this.view.dataset.model],
+ ['res_id', '=', this.view.datarecord.id],
['type', 'in', ['binary', 'url']]])).read_slice(
['name', 'url', 'type'], false, false,
this.on_attachments_loaded);
}
},
on_attachments_loaded: function(attachments) {
- this.$sidebar = this.view_manager.sidebar.$element.find('.sidebar-attachments');
this.attachments = attachments;
- this.$sidebar.html(QWeb.render('FormView.sidebar.attachments', this));
- this.$sidebar.find('.oe-sidebar-attachment-delete').click(this.on_attachment_delete);
- this.$sidebar.find('.oe-binary-file').change(this.on_attachment_changed);
+ this.$element.html(QWeb.render('FormView.sidebar.attachments', this));
+ this.$element.find('.oe-binary-file').change(this.on_attachment_changed);
+ this.$element.find('.oe-sidebar-attachment-delete').click(this.on_attachment_delete);
},
on_attachment_changed: function(e) {
- window[this.element_id + '_iframe'] = this.do_update_sidebar;
+ window[this.element_id + '_iframe'] = this.do_update;
var $e = $(e.target);
if ($e.val() != '') {
- this.$sidebar.find('form.oe-binary-form').submit();
+ this.$element.find('form.oe-binary-form').submit();
$e.parent().find('input[type=file]').attr('disabled', 'true');
$e.parent().find('button').attr('disabled', 'true').find('img, span').toggle();
}
@@ -450,27 +490,9 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
self.notification.notify("Delete an attachment", "The attachment '" + name + "' has been deleted");
});
}
- },
- reload: function() {
- if (this.datarecord.id) {
- this.dataset.read_index(_.keys(this.fields_view.fields), this.on_record_loaded);
- } else {
- this.on_button_new();
- }
- },
- get_fields_values: function() {
- var values = {};
- _.each(this.fields, function(value, key) {
- var val = value.get_value();
- values[key] = val;
- });
- return values;
}
});
-/** @namespace */
-openerp.base.form = {};
-
openerp.base.form.compute_domain = function(expr, fields) {
var stack = [];
for (var i = expr.length - 1; i >= 0; i--) {
@@ -707,7 +729,7 @@ openerp.base.form.WidgetButton = openerp.base.form.Widget.extend({
},
on_click: function(saved) {
var self = this;
- if (!this.node.attrs.special && this.view.touched && saved !== true) {
+ if (!this.node.attrs.special && this.view.dirty && saved !== true) {
this.view.do_save(function() {
self.on_click(true);
});
@@ -787,7 +809,7 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
this.readonly = this.modifiers['readonly'] === true;
this.required = this.modifiers['required'] === true;
this.invalid = false;
- this.touched = false;
+ this.dirty = false;
},
set_value: function(value) {
this.value = value;
@@ -800,6 +822,12 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
get_value: function() {
return this.value;
},
+ is_valid: function() {
+ return !this.invalid;
+ },
+ is_dirty: function() {
+ return this.dirty;
+ },
get_on_change_value: function() {
return this.get_value();
},
@@ -808,13 +836,13 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({
this.$element.toggleClass('disabled', this.readonly);
this.$element.toggleClass('required', this.required);
if (this.view.show_invalid) {
- this.$element.toggleClass('invalid', this.invalid);
+ this.$element.toggleClass('invalid', !this.is_valid());
}
},
on_ui_change: function() {
- this.touched = this.view.touched = true;
+ this.dirty = this.view.dirty = true;
this.validate();
- if (!this.invalid) {
+ if (this.is_valid()) {
this.set_value_from_ui();
this.view.do_onchange(this);
this.view.on_form_changed();
@@ -912,7 +940,7 @@ openerp.base.form.FieldEmail = openerp.base.form.FieldChar.extend({
this.$element.find('button').click(this.on_button_clicked);
},
on_button_clicked: function() {
- if (!this.value || this.invalid) {
+ if (!this.value || !this.is_valid()) {
this.notification.warn("E-mail error", "Can't send email to invalid e-mail address");
} else {
location.href = 'mailto:' + this.value;
@@ -953,7 +981,7 @@ openerp.base.form.FieldFloat = openerp.base.form.FieldChar.extend({
if (value === false || value === undefined) {
// As in GTK client, floats default to 0
value = 0;
- this.touched = true;
+ this.dirty = true;
}
var show_value = value.toFixed(2);
this.$element.find('input').val(show_value);
@@ -973,7 +1001,7 @@ openerp.base.form.FieldInteger = openerp.base.form.FieldFloat.extend({
if (value === false || value === undefined) {
// TODO fme: check if GTK client default integers to 0 (like it does with floats)
value = 0;
- this.touched = true;
+ this.dirty = true;
}
var show_value = parseInt(value, 10);
this.$element.find('input').val(show_value);
@@ -1060,7 +1088,7 @@ openerp.base.form.FieldFloatTime = openerp.base.form.FieldChar.extend({
if (value === false || value === undefined) {
// As in GTK client, floats default to 0
value = 0;
- this.touched = true;
+ this.dirty = true;
}
var show_value = _.sprintf("%02d:%02d", Math.floor(value), Math.round((value % 1) * 60));
this.$element.find('input').val(show_value);
@@ -1267,7 +1295,6 @@ openerp.base.form.dialog = function(content, options) {
options.autoOpen = true;
var dialog = new openerp.base.Dialog(null, options);
dialog.$dialog = $(content).dialog(dialog.options);
- console.log(dialog.options)
return dialog.$dialog;
}
@@ -1612,6 +1639,9 @@ openerp.base.form.FieldOne2Many = openerp.base.form.Field.extend({
controller.on_record_loaded.add_last(function() {
once.resolve();
});
+ controller.on_form_changed.add_last(function() {
+ self.save_form_view();
+ });
}
self.is_started.resolve();
});
@@ -1692,6 +1722,7 @@ openerp.base.form.FieldOne2Many = openerp.base.form.Field.extend({
var self = this;
if (!this.dataset)
return [];
+ this.save_form_view();
var val = this.dataset.delete_all ? [commands.delete_all()] : [];
val = val.concat(_.map(this.dataset.ids, function(id) {
var alter_order = _.detect(self.dataset.to_create, function(x) {return x.id === id;});
@@ -1708,9 +1739,38 @@ openerp.base.form.FieldOne2Many = openerp.base.form.Field.extend({
this.dataset.to_delete, function(x) {
return commands['delete'](x.id);}));
},
+ save_form_view: function() {
+ if (this.viewmanager && this.viewmanager.views && this.viewmanager.active_view &&
+ this.viewmanager.views[this.viewmanager.active_view] &&
+ this.viewmanager.views[this.viewmanager.active_view].controller) {
+ var view = this.viewmanager.views[this.viewmanager.active_view].controller;
+ if (this.viewmanager.active_view === "form") {
+ var res = view.do_save();
+ if (res === false) {
+ // ignore
+ } else if (res.isRejected()) {
+ throw "Save or create on one2many dataset is not supposed to fail.";
+ } else if (!res.isResolved()) {
+ throw "Asynchronous get_value() is not supported in form view.";
+ }
+ }
+ }
+ },
validate: function() {
this.invalid = false;
- // TODO niv
+ var self = this;
+ var view = self.viewmanager.views[self.viewmanager.active_view].controller;
+ if(self.viewmanager.active_view === "list") {
+ return;
+ } else if (self.viewmanager.active_view === "form") {
+ for (var f in view.fields) {
+ f = view.fields[f];
+ if (!f.is_valid()) {
+ this.invalid = true;
+ return;
+ }
+ }
+ }
}
});
diff --git a/addons/base/static/src/js/list.js b/addons/base/static/src/js/list.js
index 1c3b1cfdc4c..0c595bed22d 100644
--- a/addons/base/static/src/js/list.js
+++ b/addons/base/static/src/js/list.js
@@ -24,24 +24,37 @@ openerp.base.list = {
].join('')
}
- var record = row_data[column.id];
- if (record.value === false) {
- return value_if_empty === undefined ? '' : value_if_empty;
+ var value = row_data[column.id].value;
+
+ // If NaN value, display as with a `false` (empty cell)
+ if (typeof value === 'number' && isNaN(value)) {
+ value = false;
+ }
+ switch (value) {
+ case false:
+ case Infinity:
+ case -Infinity:
+ return value_if_empty === undefined ? '' : value_if_empty;
}
switch (column.widget || column.type) {
- case 'many2one':
- // name_get value format
- return record.value[1];
+ case 'integer':
+ return _.sprintf('%d', value);
+ case 'float':
+ var precision = column.digits ? column.digits[1] : 2;
+ return _.sprintf('%.' + precision + 'f', value);
case 'float_time':
return _.sprintf("%02d:%02d",
- Math.floor(record.value),
- Math.round((record.value % 1) * 60));
+ Math.floor(value),
+ Math.round((value % 1) * 60));
case 'progressbar':
return _.sprintf(
'<progress value="%.2f" max="100.0">%.2f%%</progress>',
- record.value, record.value);
+ value, value);
+ case 'many2one':
+ // name_get value format
+ return value[1];
default:
- return record.value;
+ return value;
}
}
};
@@ -89,6 +102,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
*/
init: function(parent, element_id, dataset, view_id, options) {
this._super(parent, element_id);
+ this.set_default_options();
this.view_manager = parent || new openerp.base.NullViewManager();
this.dataset = dataset;
this.model = dataset.model;
@@ -97,7 +111,6 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
this.columns = [];
this.options = _.extend({}, this.defaults, options || {});
- this.flags = this.view_manager.flags || {};
this.set_groups(new openerp.base.ListView.Groups(this));
@@ -254,9 +267,11 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
})
.val(self._limit || 'NaN');
});
- if(this.view_manager.sidebar)
- this.view_manager.sidebar.set_toolbar(data.fields_view.toolbar);
-
+ if (this.options.sidebar && this.options.sidebar_id) {
+ this.sidebar = new openerp.base.Sidebar(this, this.options.sidebar_id);
+ this.sidebar.start();
+ this.sidebar.add_toolbar(data.fields_view.toolbar);
+ }
},
/**
* Configures the ListView pager based on the provided dataset's information
@@ -348,16 +363,10 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
}
var aggregation_func = column['group_operator'] || 'sum';
- if (!column[aggregation_func]) {
- return {};
- }
-
- return {
- field: column.id,
- type: column.type,
+ return _.extend({}, column, {
'function': aggregation_func,
label: column[aggregation_func]
- };
+ });
});
},
/**
@@ -386,16 +395,20 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
},
do_show: function () {
this.$element.show();
+ if (this.sidebar) {
+ this.sidebar.$element.show();
+ }
if (this.hidden) {
this.$element.find('.oe-listview-content').append(
this.groups.apoptosis().render());
this.hidden = false;
}
- if(this.view_manager.sidebar)
- this.view_manager.sidebar.do_refresh(true);
},
do_hide: function () {
this.$element.hide();
+ if (this.sidebar) {
+ this.sidebar.$element.hide();
+ }
this.hidden = true;
},
/**
@@ -415,7 +428,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
model: this.model,
view_id: this.view_id,
context: this.dataset.get_context(),
- toolbar: !!this.flags.sidebar
+ toolbar: this.options.sidebar
}, callback);
}
},
@@ -477,6 +490,7 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
var self = this;
return $.when(this.dataset.unlink(ids)).then(function () {
self.groups.drop_records(ids);
+ self.compute_aggregates();
});
},
/**
@@ -505,11 +519,17 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
* @param {Function} callback should be called after the action is executed, if non-null
*/
do_action: function (name, id, callback) {
- var action = _.detect(this.columns, function (field) {
+ var self = this,
+ action = _.detect(this.columns, function (field) {
return field.name === name;
});
if (!action) { return; }
- this.execute_action(action, this.dataset, this.session.action_manager, id, callback);
+ this.execute_action(
+ action, this.dataset, this.session.action_manager, id, function () {
+ $.when(callback.apply(this, arguments).then(function () {
+ self.compute_aggregates();
+ }));
+ });
},
/**
* Handles the activation of a record (clicking on it)
@@ -556,7 +576,6 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
compute_aggregates: function (records) {
var columns = _(this.aggregate_columns).filter(function (column) {
return column['function']; });
-
if (_.isEmpty(columns)) { return; }
if (_.isEmpty(records)) {
@@ -564,17 +583,39 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
}
var count = 0, sums = {};
- _(columns).each(function (column) { sums[column.field] = 0; });
+ _(columns).each(function (column) {
+ switch (column['function']) {
+ case 'max':
+ sums[column.id] = -Infinity;
+ break;
+ case 'min':
+ sums[column.id] = Infinity;
+ break;
+ default:
+ sums[column.id] = 0;
+ }
+ });
_(records).each(function (record) {
count += record.count || 1;
_(columns).each(function (column) {
- var field = column.field;
+ var field = column.id,
+ value = record.values[field];
switch (column['function']) {
case 'sum':
- sums[field] += record.values[field];
+ sums[field] += value;
break;
case 'avg':
- sums[field] += record.count * record.values[field];
+ sums[field] += record.count * value;
+ break;
+ case 'min':
+ if (sums[field] > value) {
+ sums[field] = value;
+ }
+ break;
+ case 'max':
+ if (sums[field] < value) {
+ sums[field] = value;
+ }
break;
}
});
@@ -582,14 +623,13 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
var aggregates = {};
_(columns).each(function (column) {
- var field = column.field;
+ var field = column.id;
switch (column['function']) {
- case 'sum':
- aggregates[field] = sums[field];
- break;
case 'avg':
- aggregates[field] = sums[field] / count;
+ aggregates[field] = {value: sums[field] / count};
break;
+ default:
+ aggregates[field] = {value: sums[field]};
}
});
@@ -601,9 +641,9 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
if (!column['function']) {
return;
}
- var pattern = (column.type == 'integer') ? '%d' : '%.2f';
- $footer_cells.filter(_.sprintf('[data-field=%s]', column.field))
- .text(_.sprintf(pattern, aggregation[column.field]));
+
+ $footer_cells.filter(_.sprintf('[data-field=%s]', column.id))
+ .html(openerp.base.list.render_cell(aggregation, column));
});
}
// TODO: implement reorder (drag and drop rows)
@@ -668,7 +708,7 @@ openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.
index = self.row_position($row);
$(self).trigger('action', [field, record_id, function () {
- self.reload_record(index, true);
+ return self.reload_record(index, true);
}]);
})
.delegate('tr', 'click', function (e) {
@@ -806,7 +846,7 @@ openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base.
return $.when(read_p).then(function () {
self.$current.children().eq(record_index)
- .replaceWith(self.render_record(record_index)); })
+ .replaceWith(self.render_record(record_index)); });
},
/**
* Renders a list record to HTML
@@ -981,8 +1021,8 @@ openerp.base.ListView.Groups = openerp.base.Class.extend( /** @lends openerp.bas
row_data[group.grouped_on] = group;
var group_column = _(self.columns).detect(function (column) {
return column.id === group.grouped_on; });
- $group_column.text(openerp.base.list.render_cell(
- row_data, group_column, "Undefined"
+ $group_column.html(openerp.base.list.render_cell(
+ row_data, group_column, "Undefined"
));
if (group.openable) {
// Make openable if not terminal group & group_by_no_leaf
diff --git a/addons/base/static/src/js/search.js b/addons/base/static/src/js/search.js
index 026f19db5b1..8a51abe1335 100644
--- a/addons/base/static/src/js/search.js
+++ b/addons/base/static/src/js/search.js
@@ -110,9 +110,10 @@ openerp.base.SearchView = openerp.base.Controller.extend({
}
},
on_loaded: function(data) {
- var lines = this.make_widgets(
- data.fields_view['arch'].children,
- data.fields_view.fields);
+ var self = this,
+ lines = this.make_widgets(
+ data.fields_view['arch'].children,
+ data.fields_view.fields);
// for extended search view
var ext = new openerp.base.search.ExtendedSearch(this, this.model);
@@ -144,7 +145,9 @@ openerp.base.SearchView = openerp.base.Controller.extend({
self.ready.resolve();
});
- // filters management
+ this.reload_managed_filters();
+ },
+ reload_managed_filters: function() {
var self = this;
return this.rpc('/base/searchview/get_filters', {
model: this.dataset.model
@@ -159,6 +162,7 @@ openerp.base.SearchView = openerp.base.Controller.extend({
* Handle event when the user make a selection in the filters management select box.
*/
on_filters_management: function(e) {
+ var self = this;
var select = this.$element.find(".oe_search-view-filters-management");
var val = select.val();
@@ -173,10 +177,50 @@ openerp.base.SearchView = openerp.base.Controller.extend({
this.on_search([filter.domain], [filter.context], []);
} else if (val == "save_filter") {
select.val("_filters");
- //TODO niv
+ var data = this.build_search_data();
+ var context = new openerp.base.CompoundContext();
+ _.each(data.contexts, function(x) {
+ context.add(x);
+ });
+ var domain = new openerp.base.CompoundDomain();
+ _.each(data.domains, function(x) {
+ domain.add(x);
+ });
+ var dial_html = QWeb.render("SearchView.managed-filters.add");
+ var $dial = $(dial_html);
+ $dial.dialog({
+ modal: true,
+ title: "Filter Entry",
+ buttons: {
+ Cancel: function() {
+ $(this).dialog("close");
+ },
+ OK: function() {
+ $(this).dialog("close");
+ var name = $(this).find("input").val();
+ self.rpc('/base/searchview/save_filter', {
+ model: self.dataset.model,
+ context_to_save: context,
+ domain: domain,
+ name: name
+ }).then(function(result) {
+ self.reload_managed_filters();
+ });
+ },
+ }
+ });
} else { // manage_filters
select.val("_filters");
- //TODO niv
+ this.do_action({
+ res_model: 'ir.filters',
+ views: [[false, 'list'], [false, 'form']],
+ type: 'ir.actions.act_window',
+ context: {"search_default_user_id": this.session.uid,
+ "search_default_model_id": this.dataset.model},
+ target: "current",
+ limit : 80,
+ auto_search : true
+ });
}
},
/**
@@ -197,6 +241,16 @@ openerp.base.SearchView = openerp.base.Controller.extend({
if (e && e.preventDefault) { e.preventDefault(); }
+ var data = this.build_search_data();
+
+ if (data.errors.length) {
+ this.on_invalid(data.errors);
+ return;
+ }
+
+ this.on_search(data.domains, data.contexts, data.groupbys);
+ },
+ build_search_data: function() {
var domains = [],
contexts = [],
errors = [];
@@ -221,19 +275,13 @@ openerp.base.SearchView = openerp.base.Controller.extend({
}
});
- if (errors.length) {
- this.on_invalid(errors);
- return;
- }
-
// TODO: do we need to handle *fields* with group_by in their context?
var groupbys = _(this.enabled_filters)
.chain()
.map(function (filter) { return filter.get_context();})
.compact()
.value();
-
- this.on_search(domains, contexts, groupbys);
+ return {domains: domains, contexts: contexts, errors: errors, groupbys: groupbys};
},
/**
* Triggered after the SearchView has collected all relevant domains and
diff --git a/addons/base/static/src/js/views.js b/addons/base/static/src/js/views.js
index 2bcd47dfd25..aa66f40e925 100644
--- a/addons/base/static/src/js/views.js
+++ b/addons/base/static/src/js/views.js
@@ -61,6 +61,9 @@ openerp.base.ActionManager = openerp.base.Controller.extend({
var url = window.location.protocol + "//" + window.location.host +
window.location.pathname + "?" + jQuery.param({ s_action : "" + key });
window.open(url);
+ if (on_closed) {
+ on_closed();
+ }
});
} else {
if (this.viewmanager) {
@@ -117,7 +120,6 @@ openerp.base.ViewManager = openerp.base.Controller.extend({
{return x instanceof Array? {view_id: x[0], view_type: x[1]} : x;});
this.views = {};
this.flags = this.flags || {};
- this.sidebar = new openerp.base.NullSidebar();
this.registry = openerp.base.views;
},
/**
@@ -131,7 +133,12 @@ openerp.base.ViewManager = openerp.base.Controller.extend({
self.on_mode_switch($(this).data('view-type'));
});
_.each(this.views_src, function(view) {
- self.views[view.view_type] = $.extend({}, view, {controller: null});
+ self.views[view.view_type] = $.extend({}, view, {
+ controller : null,
+ options : _.extend({
+ sidebar_id : self.element_id + '_sidebar_' + view.view_type
+ }, self.flags)
+ });
});
if (this.flags.views_switcher === false) {
this.$element.find('.oe_vm_switch').hide();
@@ -155,7 +162,7 @@ openerp.base.ViewManager = openerp.base.Controller.extend({
if (!view.controller) {
// Lazy loading of views
var controllerclass = this.registry.get_object(view_type);
- var controller = new controllerclass( this, this.element_id + "_view_" + view_type,
+ var controller = new controllerclass(this, this.element_id + '_view_' + view_type,
this.dataset, view.view_id, view.options);
if (view.embedded_view) {
controller.set_embedded_view(view.embedded_view);
@@ -285,7 +292,6 @@ openerp.base.NullViewManager = openerp.base.generate_null_object_class(openerp.b
if(parent)
this.session = parent.session;
this.action = {flags: {}};
- this.sidebar = new openerp.base.NullSidebar();
}
});
@@ -310,19 +316,10 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
// Not elegant but allows to avoid flickering of SearchView#do_hide
this.flags.search_view = this.flags.pager = this.flags.sidebar = this.flags.action_buttons = false;
}
- if (this.flags.sidebar) {
- this.sidebar = new openerp.base.Sidebar(null, this);
- }
},
start: function() {
var inital_view_loaded = this._super();
- // init sidebar
- if (this.flags.sidebar) {
- this.$element.find('.view-manager-main-sidebar').html(this.sidebar.render());
- this.sidebar.start();
- }
-
var search_defaults = {};
_.each(this.action.context, function (value, key) {
var match = /^search_default_(.*)$/.exec(key);
@@ -347,7 +344,6 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
},
stop: function() {
// should be replaced by automatic destruction implemented in BaseWidget
- this.sidebar.stop();
this._super();
},
/**
@@ -374,83 +370,97 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
}
});
-openerp.base.Sidebar = openerp.base.BaseWidget.extend({
- template: "ViewManager.sidebar",
- init: function(parent, view_manager) {
- this._super(parent, view_manager.session);
- this.view_manager = view_manager;
- this.sections = [];
+openerp.base.Sidebar = openerp.base.Controller.extend({
+ init: function(parent, element_id) {
+ this._super(parent, element_id);
+ this.items = {};
},
- set_toolbar: function(toolbar) {
- this.sections = [];
+ start: function() {
var self = this;
- _.each([["print", "Reports"], ["action", "Actions"], ["relate", "Links"]], function(type) {
- if (toolbar[type[0]].length == 0)
- return;
- var section = {elements:toolbar[type[0]], label:type[1]};
- self.sections.push(section);
+ this._super(this, arguments);
+ this.$element.html(QWeb.render('Sidebar'));
+ this.$element.find(".toggle-sidebar").click(function(e) {
+ self.do_toggle();
});
- this.do_refresh(true);
},
- do_refresh: function(new_view) {
- var view = this.view_manager.active_view;
- var the_condition = this.sections.length > 0 && _.detect(this.sections,
- function(x) {return x.elements.length > 0;}) != undefined
- && (!new_view || view != 'list');
-
- this.$element.toggleClass('open-sidebar', the_condition)
- .toggleClass('closed-sidebar', !the_condition);
-
- this.$element.html(QWeb.render("ViewManager.sidebar.internal", { sidebar: this, view: view }));
-
+ add_toolbar: function(toolbar) {
var self = this;
- this.$element.find(".toggle-sidebar").click(function(e) {
- self.$element.toggleClass('open-sidebar closed-sidebar');
- e.stopPropagation();
- e.preventDefault();
- });
-
- this.$element.find("a.oe_sidebar_action_a").click(function(e) {
- var $this = jQuery(this);
- var index = $this.attr("data-index").split('-');
- var action = self.sections[index[0]].elements[index[1]];
- action.flags = {
- new_window : true
- };
- self.session.action_manager.do_action(action);
- e.stopPropagation();
- e.preventDefault();
+ _.each([['print', "Reports"], ['action', "Actions"], ['relate', "Links"]], function(type) {
+ var items = toolbar[type[0]];
+ if (items.length) {
+ for (var i = 0; i < items.length; i++) {
+ items[i] = {
+ label: items[i]['name'],
+ action: items[i],
+ classname: 'oe_sidebar_' + type[0]
+ }
+ }
+ self.add_section(type[1], items);
+ }
});
},
- start: function() {
- this._super();
- this.do_refresh(false);
- }
-});
-
-openerp.base.NullSidebar = openerp.base.generate_null_object_class(openerp.base.Sidebar);
-
-/*
-openerp.base.Export = openerp.base.Dialog.extend({
- dialog_title: "Export",
- template: 'ExportDialog',
- identifier_prefix: 'export_dialog',
- init: function (session, model, domain) {
- this._super();
+ add_section: function(name, items) {
+ // For each section, we pass a name/label and optionally an array of items.
+ // If no items are passed, then the section will be created as a custom section
+ // returning back an element_id to be used by a custom controller.
+ // Else, the section is a standard section with items displayed as links.
+ // An item is a dictonary : {
+ // label: label to be displayed for the link,
+ // action: action to be launch when the link is clicked,
+ // callback: a function to be executed when the link is clicked,
+ // classname: optionnal dom class name for the line,
+ // }
+ // Note: The item should have one action or/and a callback
+ var self = this,
+ section_id = _.uniqueId(this.element_id + '_section_');
+ if (items) {
+ for (var i = 0; i < items.length; i++) {
+ items[i].element_id = _.uniqueId(section_id + '_item_');
+ this.items[items[i].element_id] = items[i];
+ }
+ }
+ var $section = $(QWeb.render("Sidebar.section", {
+ section_id: section_id,
+ name: name,
+ items: items
+ }));
+ if (items) {
+ $section.find('a.oe_sidebar_action_a').click(function() {
+ var item = self.items[$(this).attr('id')];
+ if (item.callback) {
+ item.callback();
+ }
+ if (item.action) {
+ item.action.flags = item.action.flags || {};
+ item.action.flags.new_window = true;
+ self.do_action(item.action);
+ }
+ return false;
+ });
+ }
+ $section.appendTo(this.$element.find('div.sidebar-actions'));
+ return section_id;
},
- start: function () {
- this._super();
- this.$element.html(this.render());
+ do_fold: function() {
+ this.$element.addClass('closed-sidebar').removeClass('open-sidebar');
},
- on_button_Export: function() {
- console.log("Export")
+ do_unfold: function() {
+ this.$element.addClass('open-sidebar').removeClass('closed-sidebar');
},
- on_button_Cancel: function() {
- this.$element.dialog("close");
+ do_toggle: function() {
+ this.$element.toggleClass('open-sidebar closed-sidebar');
}
});
-*/
+
openerp.base.View = openerp.base.Controller.extend({
+ set_default_options: function(options) {
+ this.options = options || {};
+ _.defaults(this.options, {
+ // All possible views options should be defaulted here
+ sidebar_id: null,
+ sidebar: true
+ });
+ },
/**
* Fetches and executes the action identified by ``action_data``.
*
diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml
index d8250d2c4d5..89e23fece6d 100644
--- a/addons/base/static/src/xml/base.xml
+++ b/addons/base/static/src/xml/base.xml
@@ -62,7 +62,7 @@
<td><label for="db">Database:</label></td>
<td>
<t t-if="!db_list">
- <input type="text" name="db" value="" autofocus="true"/>
+ <input type="text" name="db" t-att-value="selected_db || ''" autofocus="true"/>
</t>
<t t-if="db_list">
<select name="db">
@@ -232,18 +232,40 @@
</t>
</td>
<td class="view-manager-main-sidebar" height="100%">
+ <t t-foreach="views" t-as="view">
+ <div t-attf-id="#{prefix}_sidebar_#{view.view_type}" class="sidebar-main-div closed-sidebar" style="display: none"/>
+ </t>
</td>
</tr>
</table>
</t>
+<t t-name="Sidebar">
+ <a class="toggle-sidebar"></a>
+ <div class="sidebar-content">
+ <div class="sidebar-actions">
+ </div>
+ </div>
+</t>
+<t t-name="Sidebar.section">
+ <h2><t t-esc="name"/></h2>
+ <div t-att-id="section_id">
+ <ul t-if="items">
+ <li t-foreach="items" t-as="item" t-att-class="item.classname">
+ <a class="oe_sidebar_action_a" t-att-id="item.element_id" href="#">
+ <t t-esc="item.label"/>
+ </a>
+ </li>
+ </ul>
+ </div>
+</t>
<table t-name="ListView" class="oe-listview-content">
<t t-set="columns_count" t-value="visible_columns.length + (options.selectable ? 1 : 0) + (options.deletable ? 1 : 0)"/>
<thead class="ui-widget-header">
- <tr t-if="flags.action_buttons !== false or flags.pager !== false">
+ <tr t-if="options.action_buttons !== false or options.pager !== false">
<th t-att-colspan="columns_count">
<table>
<tr>
- <td t-if="flags.action_buttons !== false" class="oe-actions">
+ <td t-if="options.action_buttons !== false" class="oe-actions">
<button type="button" class="oe-list-add"
t-if="options.addable">
<t t-esc="options.addable"/>
@@ -253,7 +275,7 @@
Delete
</button>
</td>
- <th t-if="flags.pager !== false" class="oe-list-pager">
+ <th t-if="options.pager !== false" class="oe-list-pager">
<button type="button" disabled="disabled"
data-pager-action="first">First</button>
<button type="button" disabled="disabled"
@@ -293,7 +315,7 @@
<tr>
<td t-if="options.selectable"/>
<td t-foreach="aggregate_columns" t-as="column" class="oe-list-footer oe-number"
- t-att-data-field="column.field" t-att-title="column.label">
+ t-att-data-field="column.id" t-att-title="column.label">
</td>
<td t-if="options.deletable"/>
</tr>
@@ -335,7 +357,7 @@
<t t-name="FormView">
<div class="oe_form_header" t-att-id="view.element_id + '_header'">
<h2 class="oe_view_title"><t t-esc="view.fields_view.arch.attrs.string"/> <button class="oe_get_xml_view">xml</button></h2>
- <div class="oe_form_buttons" t-if="view.flags.action_buttons !== false">
+ <div class="oe_form_buttons" t-if="view.options.action_buttons !== false">
<!--<button type="button" class="oe_form_button_save">
<span class="oe_form_on_update">Save</span>
<span class="oe_form_on_create">Create</span>
@@ -347,7 +369,7 @@
<!--<button type="button" class="oe_form_button_cancel">Cancel</button>-->
<button type="button" class="oe_form_button_new">New</button>
</div>
- <div class="oe_form_pager" t-if="view.flags.pager !== false">
+ <div class="oe_form_pager" t-if="view.options.pager !== false">
<button type="button" data-pager-action="first">First</button>
<button type="button" data-pager-action="previous">&lt;&lt;</button>
@@ -360,21 +382,20 @@
<t t-raw="frame.render()"/>
</t>
<t t-name="FormView.sidebar.attachments">
- <h2>Attachments</h2>
<div class="oe-sidebar-attachments-toolbar">
<div class="oe-binary-file-set" style="float: right">
<form class="oe-binary-form" t-attf-target="#{element_id}_iframe"
method="post" enctype="multipart/form-data" action="/base/binary/upload_attachment">
<input type="hidden" name="session_id" t-att-value="session.session_id"/>
<input type="hidden" name="callback" t-attf-value="#{element_id}_iframe"/>
- <input type="hidden" name="model" t-att-value="dataset.model"/>
- <input type="hidden" name="id" t-att-value="datarecord.id"/>
+ <input type="hidden" name="model" t-att-value="view.dataset.model"/>
+ <input type="hidden" name="id" t-att-value="view.datarecord.id"/>
<button class="button" type="button">
<img src="/base/static/src/img/throbber.gif" width="16" height="16" style="display: none"/>
<span>Add</span>
</button>
<input type="file" class="oe-binary-file" name="ufile" title="Add attachment"
- t-att-onclick="datarecord.id ? null : 'alert(\'No record selected ! You can only attach to existing record.\'); return false;'"/>
+ t-att-onclick="view.datarecord.id ? null : 'alert(\'No record selected ! You can only attach to existing record.\'); return false;'"/>
</form>
<iframe t-attf-id="#{element_id}_iframe" t-attf-name="#{element_id}_iframe" style="display: none"> </iframe>
</div>
@@ -384,7 +405,7 @@
<li t-foreach="attachments" t-as="attachment">
<t t-if="attachment.type == 'binary'" t-set="attachment.url" t-value="'/base/binary/saveas?session_id='
+ session.session_id + '&amp;model=ir.attachment&amp;id=' + attachment.id
- + '&amp;field=datas' + '&amp;fieldname=name' + '&amp;t=' + (new Date().getTime())"/>
+ + '&amp;field=datas&amp;fieldname=name&amp;t=' + (new Date().getTime())"/>
<a class="oe-sidebar-attachments-link" t-att-href="attachment.url" target="_blank">
<t t-esc="attachment.name"/>
</a>
@@ -679,6 +700,13 @@
<option value="save_filter">Save Filter</option>
<option value="manage_filters">Manage Filters</option>
</t>
+<t t-name="SearchView.managed-filters.add">
+ <div>
+ <p>Filter Name:</p>
+ <input type="text"/>
+ <p>(Any existing filter with the same name will be replaced)</p>
+ </div>
+</t>
<t t-name="SearchView.render_lines">
<table class="oe-searchview-render-line" border="0" cellspacing="0" cellpadding="0"
t-foreach="lines" t-as="line">
@@ -842,29 +870,6 @@
</t>
</select>
</t>
-<t t-name="ViewManager.sidebar">
- <div t-att-id="element_id" class="sidebar-main-div closed-sidebar">
-
- </div>
-</t>
-<t t-name="ViewManager.sidebar.internal">
- <a class="toggle-sidebar"></a>
- <div class="sidebar-content">
- <div class="sidebar-attachments" t-if="view == 'form'"> </div>
- <div class="sidebar-actions">
- <t t-foreach="sidebar.sections" t-as="section" t-if="section.elements.length">
- <h2><t t-esc="section.label"/></h2>
- <ul>
- <li t-foreach="section.elements" t-as="element">
- <a class="oe_sidebar_action_a" t-attf-data-index="#{section_index}-#{element_index}" href="#">
- <t t-esc="element.name"/>
- </a>
- </li>
- </ul>
- </t>
- </div>
- </div>
-</t>
<t t-name="DialogWarning">
<table cellspacing="0" cellpadding="0" border="0" class="oe-dialog-warning">
<tr>
diff --git a/addons/base/static/test/list.js b/addons/base/static/test/list.js
index 3d441f190db..ebce7e8535a 100644
--- a/addons/base/static/test/list.js
+++ b/addons/base/static/test/list.js
@@ -18,15 +18,6 @@ $(document).ready(function () {
}
}};
- var fuck_that_shit = {
- action: {
- flags: {}
- },
- sidebar: {
- set_toolbar: function () {}
- }
- };
-
var openerp;
module("ListView", {
setup: function () {
@@ -42,8 +33,7 @@ $(document).ready(function () {
test('render selection checkboxes', 2, function () {
var listview = new openerp.base.ListView(
- fuck_that_shit, null,
- 'qunit-fixture', {model: null, ids: [null, null, null], index: 0});
+ null, 'qunit-fixture', {model: null, ids: [null, null, null], index: 0});
listview.on_loaded(fvg);
@@ -60,8 +50,7 @@ $(document).ready(function () {
});
test('render no checkbox if selectable=false', 1, function () {
var listview = new openerp.base.ListView(
- fuck_that_shit, null,
- 'qunit-fixture', {model: null, ids: [null, null, null], index: 0}, false,
+ null, 'qunit-fixture', {model: null, ids: [null, null, null], index: 0}, false,
{selectable: false});
listview.on_loaded(fvg);
@@ -75,8 +64,7 @@ $(document).ready(function () {
});
test('select a bunch of records', 2, function () {
var listview = new openerp.base.ListView(
- fuck_that_shit, null, 'qunit-fixture',
- {model: null, ids: [1, 2, 3], index: 0});
+ null, 'qunit-fixture', {model: null, ids: [1, 2, 3], index: 0});
listview.on_loaded(fvg);
listview.do_fill_table({records: [
@@ -94,8 +82,7 @@ $(document).ready(function () {
});
test('render deletion button if list is deletable', 1, function () {
var listview = new openerp.base.ListView(
- fuck_that_shit, null, 'qunit-fixture',
- {model: null, ids: [null, null, null], index: 0});
+ null, 'qunit-fixture', {model: null, ids: [null, null, null], index: 0});
listview.on_loaded(fvg);
@@ -112,7 +99,7 @@ $(document).ready(function () {
2, function () {
var deleted;
var listview = new openerp.base.ListView(
- fuck_that_shit, null, 'qunit-fixture',
+ null, 'qunit-fixture',
{model: null, unlink: function (ids) {
deleted = ids;
}, ids: [1, 2, 3], index: 0});
@@ -132,7 +119,7 @@ $(document).ready(function () {
test('multiple records deletion', 1, function () {
var deleted;
var listview = new openerp.base.ListView(
- fuck_that_shit, null, 'qunit-fixture',
+ null, 'qunit-fixture',
{model: null, unlink: function (ids) {
deleted = ids;
}, ids: [1, 2, 3], index: 0});