summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorFabien Pinckaers <fp@tinyerp.com>2012-08-17 09:08:49 +0200
committerFabien Pinckaers <fp@tinyerp.com>2012-08-17 09:08:49 +0200
commitd22b14809be06393144f492aaef19fa27ef5fbe4 (patch)
treefeb3412c97ff05028406a7d90f17bdef0118b131 /addons/web/static/src
parent332b118e3e16ae764dface838af6451ad567c433 (diff)
parent01b1e2209dbfc1d168fa56a53fb7225ac43925ad (diff)
[MERGE] trunk
bzr revid: fp@tinyerp.com-20120817070849-hii1q6yu8xpxz07o
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/css/base.css7
-rw-r--r--addons/web/static/src/css/base.sass3
-rw-r--r--addons/web/static/src/js/boot.js5
-rw-r--r--addons/web/static/src/js/chrome.js159
-rw-r--r--addons/web/static/src/js/corelib.js6
-rw-r--r--addons/web/static/src/js/coresetup.js95
-rw-r--r--addons/web/static/src/js/data.js38
-rw-r--r--addons/web/static/src/js/search.js96
-rw-r--r--addons/web/static/src/js/test_support.js12
-rw-r--r--addons/web/static/src/js/view_form.js165
-rw-r--r--addons/web/static/src/js/view_list.js4
-rw-r--r--addons/web/static/src/js/views.js44
-rw-r--r--addons/web/static/src/xml/base.xml214
13 files changed, 435 insertions, 413 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index 38d9311c3e2..b9eb6fed93b 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -1,4 +1,4 @@
-@charset "UTF-8";
+@charset "utf-8";
@font-face {
font-family: "mnmliconsRegular";
src: url("/web/static/src/font/mnmliconsv21-webfont.eot") format("eot");
@@ -79,7 +79,7 @@
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
/* http://www.quirksmode.org/dom/inputfile.html
* http://stackoverflow.com/questions/2855589/replace-input-type-file-by-an-image
- */
+ */ */
}
.openerp :-moz-placeholder {
color: #afafb6 !important;
@@ -581,6 +581,9 @@
background: #8786b7;
color: #eeeeee;
}
+.openerp .oe_tags.oe_inline {
+ min-width: 250px;
+}
.openerp .oe_tags .text-wrap {
width: 100% !important;
}
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index ad2b3b87773..befb68b42db 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -1,6 +1,7 @@
@charset "utf-8"
// Variables {{{
+$facets-border: #afafb6
$section-title-color: #8786b7
$tag-bg-light: #f0f0fa
$tag-bg-dark: #8786b7
@@ -470,6 +471,8 @@ $sheet-max-width: 860px
color: #eee
.oe_tags
+ &.oe_inline
+ min-width: 250px
.text-wrap
width: 100% !important
textarea
diff --git a/addons/web/static/src/js/boot.js b/addons/web/static/src/js/boot.js
index 844dd88a0ac..05ce709e80a 100644
--- a/addons/web/static/src/js/boot.js
+++ b/addons/web/static/src/js/boot.js
@@ -37,7 +37,10 @@
};
openerp.instances[new_instance._session_id] = new_instance;
for(var i=0; i < modules.length; i++) {
- openerp[modules[i]](new_instance,new_instance[modules[i]]);
+ new_instance[modules[i]] = {};
+ if (openerp[modules[i]]) {
+ openerp[modules[i]](new_instance,new_instance[modules[i]]);
+ }
}
return new_instance;
}
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index 05f9fb5b1b6..ff066c9f425 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -66,9 +66,9 @@ instance.web.Dialog = instance.web.Widget.extend({
max_width: '95%',
height: 'auto',
min_height: 0,
- max_height: this.get_height('100%') - 140,
+ max_height: this.get_height('100%') - 200,
autoOpen: false,
- position: [false, 50],
+ position: [false, 40],
buttons: {},
beforeClose: function () { self.on_close(); },
resizeStop: this.on_resized
@@ -109,7 +109,7 @@ instance.web.Dialog = instance.web.Widget.extend({
} else if (val.slice(-1) == "%") {
return Math.round(available_size / 100 * parseInt(val.slice(0, -1), 10));
} else {
- return parseInt(val, 10);
+ return parseInt(val, 10);
}
},
renderElement: function() {
@@ -123,7 +123,7 @@ instance.web.Dialog = instance.web.Widget.extend({
if (! this.dialog_inited)
this.init_dialog();
var o = this.get_options(options);
- instance.web.dialog(this.$element, o).dialog('open');
+ instance.web.dialog(this.$element, o).dialog('open');
if (o.height === 'auto' && o.max_height) {
this.$element.css({ 'max-height': o.max_height, 'overflow-y': 'auto' });
}
@@ -193,7 +193,7 @@ instance.web.CrashManager = instance.web.CallbackEnabled.extend({
on_traceback: function(error) {
var self = this;
var buttons = {};
- if (instance.connection.openerp_entreprise) {
+ if (instance.session.openerp_entreprise) {
buttons[_t("Send OpenERP Enterprise Report")] = function() {
var $this = $(this);
var issuename = $('#issuename').val();
@@ -224,7 +224,7 @@ instance.web.CrashManager = instance.web.CallbackEnabled.extend({
min_height: '600px',
buttons: buttons
}).open();
- dialog.$element.html(QWeb.render('CrashManager.error', {session: instance.connection, error: error}));
+ dialog.$element.html(QWeb.render('CrashManager.error', {session: instance.session, error: error}));
},
on_javascript_exception: function(exception) {
this.on_traceback({
@@ -269,7 +269,7 @@ instance.web.Loading = instance.web.Widget.extend({
this.count += increment;
if (this.count > 0) {
- if (instance.connection.debug) {
+ if (instance.session.debug) {
this.$element.text(_.str.sprintf( _t("Loading (%d)"), this.count));
} else {
this.$element.text(_t("Loading"));
@@ -300,6 +300,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
},
start: function() {
var self = this;
+ $('.oe_secondary_menus_container,.oe_user_menu_placeholder').empty();
var fetch_db = this.rpc("/web/database/get_list", {}).pipe(
function(result) {
self.db_list = result.db_list;
@@ -315,12 +316,22 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
},
do_render: function() {
var self = this;
+ instance.webclient.toggle_bars(true);
self.$element.html(QWeb.render("DatabaseManager", { widget : self }));
- self.$element.find(".oe_database_manager_menu").tabs({
- show: function(event, ui) {
- $('*[autofocus]:first', ui.panel).focus();
- }
+ $('.oe_user_menu_placeholder').append(QWeb.render("DatabaseManager.user_menu",{ widget : self }));
+ $('.oe_secondary_menus_container').append(QWeb.render("DatabaseManager.menu",{ widget : self }));
+ $('ul.oe_secondary_submenu > li:first').addClass('oe_active')
+ $('ul.oe_secondary_submenu > li').bind('click', function (event) {
+ var menuitem = $(this);
+ menuitem.addClass('oe_active').siblings().removeClass('oe_active');
+ var form_id =menuitem.find('a').attr('href');
+ $(form_id).show().siblings().hide();
+ event.preventDefault();
});
+ $('#back-to-login').click(self.do_exit);
+ self.$element.find("td").addClass("oe_form_group_cell");
+ self.$element.find("tr td:first-child").addClass("oe_form_group_cell_label");
+ self.$element.find("label").addClass("oe_form_label");
self.$element.find("form[name=create_db_form]").validate({ submitHandler: self.do_create });
self.$element.find("form[name=drop_db_form]").validate({ submitHandler: self.do_drop });
self.$element.find("form[name=backup_db_form]").validate({ submitHandler: self.do_backup });
@@ -336,7 +347,6 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
},
submitHandler: self.do_change_password
});
- self.$element.find("#back_to_login").click(self.do_exit);
},
destroy: function () {
this.$element.find('#db-create, #db-drop, #db-backup, #db-restore, #db-change-password, #back-to-login').unbind('click').end().empty();
@@ -407,7 +417,6 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
};
self.do_action(client_action);
});
-
},
do_drop: function(form) {
var self = this;
@@ -486,11 +495,14 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
self.display_error(result);
return;
}
+ self.unblockUI();
self.do_notify("Changed Password", "Password has been changed successfully");
});
},
do_exit: function () {
- this.do_action("login");
+ this.$element.remove();
+ instance.webclient.toggle_bars(false);
+ this.do_action('login');
}
});
instance.web.client_actions.add("database_manager", "instance.web.DatabaseManager");
@@ -498,11 +510,11 @@ instance.web.client_actions.add("database_manager", "instance.web.DatabaseManage
instance.web.Login = instance.web.Widget.extend({
template: "Login",
remember_credentials: true,
- _db_list: null,
init: function(parent, params) {
this._super(parent);
this.has_local_storage = typeof(localStorage) != 'undefined';
+ this.db_list = null;
this.selected_db = null;
this.selected_login = null;
this.params = params || {};
@@ -525,50 +537,41 @@ instance.web.Login = instance.web.Widget.extend({
self.$element.find('.oe_login_manage_db').click(function() {
self.do_action("database_manager");
});
- return self.load_db_list().then(self.on_db_list_loaded).then(function() {
- if (self.params.db) {
- self.do_login(self.params.db, self.params.login, self.params.password);
- }
- });
- },
- load_db_list: function (force) {
- var d = $.when(), self = this;
- if (_.isNull(this._db_list) || force) {
- d = self.rpc("/web/database/get_list", {}, function(result) {
- self._db_list = _.clone(result.db_list);
- }, function(error, event) {
- if (error.data.fault_code === 'AccessDenied') {
- event.preventDefault();
- }
- });
+ var d;
+ if (self.params.db) {
+ d = self.do_login(self.params.db, self.params.login, self.params.password);
+ } else {
+ d = self.rpc("/web/database/get_list", {}).done(self.on_db_loaded).fail(self.on_db_failed);
}
return d;
},
- on_db_list_loaded: function () {
- var self = this;
- var list = this._db_list;
- var dbdiv = this.$element.find('div.oe_login_dbpane');
- this.$element.find("[name=db]").replaceWith(instance.web.qweb.render('Login.dblist', { db_list: list, selected_db: this.selected_db}));
- if(list.length === 0) {
+ on_db_loaded: function (result) {
+ this.db_list = result.db_list;
+ this.$("[name=db]").replaceWith(QWeb.render('Login.dblist', { db_list: this.db_list, selected_db: this.selected_db}));
+ if(this.db_list.length === 0) {
this.do_action("database_manager");
- } else if(list && list.length === 1) {
- dbdiv.hide();
+ } else if(this.db_list.length === 1) {
+ this.$('div.oe_login_dbpane').hide();
} else {
- dbdiv.show();
+ this.$('div.oe_login_dbpane').show();
+ }
+ },
+ on_db_failed: function (error, event) {
+ if (error.data.fault_code === 'AccessDenied') {
+ event.preventDefault();
}
},
on_submit: function(ev) {
if(ev) {
ev.preventDefault();
}
- var $e = this.$element;
- var db = $e.find("form [name=db]").val();
+ var db = this.$("form [name=db]").val();
if (!db) {
this.do_warn("Login", "No database selected !");
return false;
}
- var login = $e.find("form input[name=login]").val();
- var password = $e.find("form input[name=password]").val();
+ var login = this.$("form input[name=login]").val();
+ var password = this.$("form input[name=password]").val();
this.do_login(db, login, password);
},
@@ -599,16 +602,11 @@ instance.web.Login = instance.web.Widget.extend({
}
self.trigger('login_successful');
},function () {
- self.$(".oe_login_pane").fadeIn("fast");
- self.$element.addClass("oe_login_invalid");
+ self.$(".oe_login_pane").fadeIn("fast", function() {
+ self.$element.addClass("oe_login_invalid");
+ });
});
},
- show: function () {
- this.$element.show();
- },
- hide: function () {
- this.$element.hide();
- }
});
instance.web.client_actions.add("login", "instance.web.Login");
@@ -623,11 +621,11 @@ instance.web.Reload = instance.web.Widget.extend({
},
start: function() {
var l = window.location;
- var timestamp = new Date().getTime();
- var search = "?ts=" + timestamp;
- if (l.search) {
- search = l.search + "&ts=" + timestamp;
- }
+
+ var sobj = $.deparam(l.search.substr(1));
+ sobj.ts = new Date().getTime();
+ var search = '?' + $.param(sobj);
+
var hash = l.hash;
if (this.menu_id) {
hash = "#menu_id=" + this.menu_id;
@@ -665,7 +663,7 @@ instance.web.ChangePassword = instance.web.Widget.extend({
template: "ChangePassword",
start: function() {
var self = this;
- self.$element.find("form[name=change_password_form]").validate({
+ self.$element.validate({
submitHandler: function (form) {
self.rpc("/web/session/change_password",{
'fields': $(form).serializeArray()
@@ -685,7 +683,7 @@ instance.web.ChangePassword = instance.web.Widget.extend({
modal: true,
title: error.title,
buttons: [
- {text: _("Ok"), click: function() { $(this).dialog("close"); }}
+ {text: _t("Ok"), click: function() { $(this).dialog("close"); }}
]
}).html(error.error);
},
@@ -869,8 +867,8 @@ instance.web.UserMenu = instance.web.Widget.extend({
var func = new instance.web.Model("res.users").get_func("read");
return func(self.session.uid, ["name", "company_id"]).pipe(function(res) {
var topbar_name = res.name;
- if(instance.connection.debug)
- topbar_name = _.str.sprintf("%s (%s)", topbar_name, instance.connection.db);
+ if(instance.session.debug)
+ topbar_name = _.str.sprintf("%s (%s)", topbar_name, instance.session.db);
if(res.company_id[0] > 1)
topbar_name = _.str.sprintf("%s (%s)", topbar_name, res.company_id[1]);
self.$element.find('.oe_topbar_name').text(topbar_name);
@@ -887,7 +885,7 @@ instance.web.UserMenu = instance.web.Widget.extend({
on_menu_settings: function() {
var self = this;
self.rpc("/web/action/load", { action_id: "base.action_res_users_my" }, function(result) {
- result.result.res_id = instance.connection.uid;
+ result.result.res_id = instance.session.uid;
self.getParent().action_manager.do_action(result.result);
});
},
@@ -914,7 +912,7 @@ instance.web.Client = instance.web.Widget.extend({
},
start: function() {
var self = this;
- return instance.connection.session_bind(this.origin).pipe(function() {
+ return instance.session.session_bind(this.origin).pipe(function() {
var $e = $(QWeb.render(self._template, {}));
self.replaceElement($e);
self.bind_events();
@@ -950,14 +948,14 @@ instance.web.Client = instance.web.Widget.extend({
instance.web.bus.on('click', this, function(ev) {
$.fn.tipsy.clear();
if (!$(ev.target).is('input[type=file]')) {
- self.$element.find('.oe_dropdown_menu.oe_opened').removeClass('oe_opened');
+ self.$element.find('.oe_dropdown_menu.oe_opened, .oe_dropdown_toggle.oe_opened').removeClass('oe_opened');
}
});
},
show_common: function() {
var self = this;
this.crashmanager = new instance.web.CrashManager();
- instance.connection.on_rpc_error.add(this.crashmanager.on_rpc_error);
+ instance.session.on_rpc_error.add(this.crashmanager.on_rpc_error);
self.notification = new instance.web.Notification(this);
self.notification.appendTo(self.$element);
self.loading = new instance.web.Loading(self);
@@ -965,6 +963,9 @@ instance.web.Client = instance.web.Widget.extend({
self.action_manager = new instance.web.ActionManager(self);
self.action_manager.appendTo(self.$('.oe_application'));
},
+ toggle_bars: function(value) {
+ this.$('tr:has(td.oe_topbar),.oe_leftbar').toggle(value);
+ }
});
instance.web.WebClient = instance.web.Client.extend({
@@ -1006,13 +1007,27 @@ instance.web.WebClient = instance.web.Client.extend({
};
},
show_login: function() {
- this.$('.oe_topbar').hide();
- this.action_manager.do_action("login");
- this.action_manager.inner_widget.on('login_successful', this, this.show_application);
+ this.toggle_bars(false);
+
+ var action = {
+ 'type': 'ir.actions.client',
+ 'tag': 'login'
+ };
+ var state = $.bbq.getState(true);
+ if (state.action === "login") {
+ action.params = state;
+ }
+
+ this.action_manager.do_action(action);
+ this.action_manager.inner_widget.on('login_successful', this, function() {
+ this.do_push_state(state);
+ this._current_state = null; // ensure the state will be loaded
+ this.show_application(); // will load the state we just pushed
+ });
},
show_application: function() {
var self = this;
- self.$('.oe_topbar').show();
+ self.toggle_bars(true);
self.menu = new instance.web.Menu(self);
self.menu.replace(this.$element.find('.oe_menu_placeholder'));
self.menu.on('menu_click', this, this.on_menu_action);
@@ -1037,7 +1052,7 @@ instance.web.WebClient = instance.web.Client.extend({
do_reload: function() {
var self = this;
return this.session.session_reload().pipe(function () {
- instance.connection.load_modules(true).pipe(
+ instance.session.load_modules(true).pipe(
self.menu.proxy('do_reload')); });
},
@@ -1054,8 +1069,6 @@ instance.web.WebClient = instance.web.Client.extend({
this.session.session_logout().then(function () {
$(window).unbind('hashchange', self.on_hashchange);
self.do_push_state({});
- //would be cool to be able to do this, but I think it will make addons do strange things
- //this.show_login();
window.location.reload();
});
},
@@ -1144,7 +1157,7 @@ instance.web.EmbeddedClient = instance.web.Client.extend({
start: function() {
var self = this;
return $.when(this._super()).pipe(function() {
- return instance.connection.session_authenticate(self.dbname, self.login, self.key, true).pipe(function() {
+ return instance.session.session_authenticate(self.dbname, self.login, self.key, true).pipe(function() {
return self.rpc("/web/action/load", { action_id: self.action_id }, function(result) {
var action = result.result;
action.flags = _.extend({
diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js
index a46d6314ebe..5da12043994 100644
--- a/addons/web/static/src/js/corelib.js
+++ b/addons/web/static/src/js/corelib.js
@@ -692,7 +692,7 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, {
instance.web.WidgetMixin.init.call(this,parent);
// FIXME: this should not be
this.setElement(this._make_descriptive());
- this.session = instance.connection;
+ this.session = instance.session;
},
/**
* Renders the element. The default implementation renders the widget using QWeb,
@@ -841,7 +841,7 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, {
rpc: function(url, data, success, error) {
var def = $.Deferred().then(success, error);
var self = this;
- instance.connection.rpc(url, data). then(function() {
+ instance.session.rpc(url, data). then(function() {
if (!self.isDestroyed())
def.resolve.apply(def, arguments);
}, function() {
@@ -863,7 +863,7 @@ instance.web.Registry = instance.web.Class.extend({
*
* An object path is simply a dotted name from the instance root to the
* object pointed to (e.g. ``"instance.web.Session"`` for an OpenERP
- * connection object).
+ * session object).
*
* @constructs instance.web.Registry
* @param {Object} mapping a mapping of keys to object-paths
diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js
index 6ba62162e93..229a82a1784 100644
--- a/addons/web/static/src/js/coresetup.js
+++ b/addons/web/static/src/js/coresetup.js
@@ -11,32 +11,6 @@ if (!console.debug) {
openerp.web.coresetup = function(instance) {
-/**
- * @deprecated use :class:`instance.web.Widget`
- */
-instance.web.OldWidget = instance.web.Widget.extend({
- init: function(parent, element_id) {
- this._super(parent);
- this.element_id = element_id;
- this.element_id = this.element_id || _.uniqueId('widget-');
-
- var tmp = document.getElementById(this.element_id);
- this.setElement(tmp || this._make_descriptive());
- },
- renderElement: function() {
- var rendered = this.render();
- if (rendered) {
- this.replaceElement($(rendered));
- }
- return this;
- },
- render: function (additional) {
- if (this.template)
- return instance.web.qweb.render(this.template, _.extend({widget: this}, additional || {}));
- return null;
- }
-});
-
/** Session openerp specific RPC class */
instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Session# */{
init: function() {
@@ -540,7 +514,7 @@ $.async_when = function() {
// special tweak for the web client
var old_async_when = $.async_when;
$.async_when = function() {
- if (instance.connection.synch)
+ if (instance.session.synch)
return $.when.apply(this, arguments);
else
return old_async_when.apply(this, arguments);
@@ -549,43 +523,56 @@ $.async_when = function() {
/** Setup blockui */
if ($.blockUI) {
$.blockUI.defaults.baseZ = 1100;
- $.blockUI.defaults.message = '<div class="oe_blockui_spin" style="height: 50px">';
+ $.blockUI.defaults.message = '<div class="oe_blockui_spin_container">';
$.blockUI.defaults.css.border = '0';
$.blockUI.defaults.css["background-color"] = '';
- $.blockUI.spinners = [];
}
+
+instance.web.Throbber = instance.web.Widget.extend({
+ template: "Throbber",
+ start: function() {
+ var opts = {
+ lines: 13, // The number of lines to draw
+ length: 7, // The length of each line
+ width: 4, // The line thickness
+ radius: 10, // The radius of the inner circle
+ rotate: 0, // The rotation offset
+ color: '#FFF', // #rgb or #rrggbb
+ speed: 1, // Rounds per second
+ trail: 60, // Afterglow percentage
+ shadow: false, // Whether to render a shadow
+ hwaccel: false, // Whether to use hardware acceleration
+ className: 'spinner', // The CSS class to assign to the spinner
+ zIndex: 2e9, // The z-index (defaults to 2000000000)
+ top: 'auto', // Top position relative to parent in px
+ left: 'auto' // Left position relative to parent in px
+ };
+ this.spin = new Spinner(opts).spin(this.$element[0]);
+ },
+ destroy: function() {
+ if (this.spin)
+ this.spin.stop();
+ this._super();
+ },
+});
+instance.web.Throbber.throbbers = [];
+
instance.web.blockUI = function() {
var tmp = $.blockUI.apply($, arguments);
- var target = $(".oe_blockui_spin")[0];
- var opts = {
- lines: 13, // The number of lines to draw
- length: 7, // The length of each line
- width: 4, // The line thickness
- radius: 10, // The radius of the inner circle
- rotate: 0, // The rotation offset
- color: '#FFF', // #rgb or #rrggbb
- speed: 1, // Rounds per second
- trail: 60, // Afterglow percentage
- shadow: false, // Whether to render a shadow
- hwaccel: false, // Whether to use hardware acceleration
- className: 'spinner', // The CSS class to assign to the spinner
- zIndex: 2e9, // The z-index (defaults to 2000000000)
- top: 'auto', // Top position relative to parent in px
- left: 'auto' // Left position relative to parent in px
- };
- var spinner = new Spinner(opts).spin(target);
- $.blockUI.spinners.push(spinner);
+ var throbber = new instance.web.Throbber();
+ instance.web.Throbber.throbbers.push(throbber);
+ throbber.appendTo($(".oe_blockui_spin_container"));
return tmp;
}
instance.web.unblockUI = function() {
- _.each($.blockUI.spinners, function(el) {
- el.stop();
+ _.each(instance.web.Throbber.throbbers, function(el) {
+ el.destroy();
});
return $.unblockUI.apply($, arguments);
}
/** Setup default session */
-instance.connection = new instance.web.Session();
+instance.session = new instance.web.Session();
/** Configure default qweb */
instance.web._t = new instance.web.TranslationDataBase().build_translation_function();
@@ -604,8 +591,8 @@ instance.web._lt = function (s) {
return {toString: function () { return instance.web._t(s); }}
};
instance.web.qweb = new QWeb2.Engine();
-instance.web.qweb.default_dict['__debug__'] = instance.connection.debug; // Which one ?
-instance.web.qweb.debug = instance.connection.debug;
+instance.web.qweb.default_dict['__debug__'] = instance.session.debug; // Which one ?
+instance.web.qweb.debug = instance.session.debug;
instance.web.qweb.default_dict = {
'_' : _,
'_t' : instance.web._t
@@ -662,7 +649,7 @@ var _t = instance.web._t;
_t('%d years ago');
}
-instance.connection.on('module_loaded', this, function () {
+instance.session.on('module_loaded', this, function () {
// provide timeago.js with our own translator method
$.timeago.settings.translator = instance.web._t;
});
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index 2589afe5503..10fd727e57a 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -58,7 +58,7 @@ instance.web.Query = instance.web.Class.extend({
},
_execute: function () {
var self = this;
- return instance.connection.rpc('/web/dataset/search_read', {
+ return instance.session.rpc('/web/dataset/search_read', {
model: this._model.name,
fields: this._fields || false,
domain: this._model.domain(this._filter),
@@ -233,7 +233,7 @@ instance.web.Model = instance.web.Class.extend(/** @lends openerp.web.Model# */{
kwargs = args;
args = [];
}
- return instance.connection.rpc('/web/dataset/call_kw', {
+ return instance.session.rpc('/web/dataset/call_kw', {
model: this.name,
method: method,
args: args,
@@ -256,7 +256,7 @@ instance.web.Model = instance.web.Class.extend(/** @lends openerp.web.Model# */{
* @param {String} signal signal to trigger on the workflow
*/
exec_workflow: function (id, signal) {
- return instance.connection.rpc('/web/dataset/exec_workflow', {
+ return instance.session.rpc('/web/dataset/exec_workflow', {
model: this.name,
id: id,
signal: signal
@@ -282,7 +282,7 @@ instance.web.Model = instance.web.Class.extend(/** @lends openerp.web.Model# */{
*/
context: function (context) {
return new instance.web.CompoundContext(
- instance.connection.user_context, this._context, context || {});
+ instance.session.user_context, this._context, context || {});
},
/**
* Button action caller, needs to perform cleanup if an action is returned
@@ -292,7 +292,7 @@ instance.web.Model = instance.web.Class.extend(/** @lends openerp.web.Model# */{
* FIXME: remove when evaluator integrated
*/
call_button: function (method, args) {
- return instance.connection.rpc('/web/dataset/call_button', {
+ return instance.session.rpc('/web/dataset/call_button', {
model: this.name,
method: method,
domain_id: null,
@@ -439,7 +439,7 @@ instance.web.data = {
})
};
-instance.web.DataGroup = instance.web.OldWidget.extend( /** @lends openerp.web.DataGroup# */{
+instance.web.DataGroup = instance.web.CallbackEnabled.extend( /** @lends openerp.web.DataGroup# */{
/**
* Management interface between views and grouped collections of OpenERP
* records.
@@ -451,9 +451,9 @@ instance.web.DataGroup = instance.web.OldWidget.extend( /** @lends openerp.web.
* content of the current grouping level.
*
* @constructs instance.web.DataGroup
- * @extends instance.web.OldWidget
+ * @extends instance.web.CallbackEnabled
*
- * @param {instance.web.OldWidget} parent widget
+ * @param {instance.web.CallbackEnabled} parent widget
* @param {String} model name of the model managed by this DataGroup
* @param {Array} domain search domain for this DataGroup
* @param {Object} context context of the DataGroup's searches
@@ -524,13 +524,13 @@ instance.web.StaticDataGroup = instance.web.GrouplessDataGroup.extend( /** @lend
}
});
-instance.web.DataSet = instance.web.OldWidget.extend( /** @lends openerp.web.DataSet# */{
+instance.web.DataSet = instance.web.CallbackEnabled.extend( /** @lends openerp.web.DataSet# */{
/**
* DateaManagement interface between views and the collection of selected
* OpenERP records (represents the view's state?)
*
* @constructs instance.web.DataSet
- * @extends instance.web.OldWidget
+ * @extends instance.web.CallbackEnabled
*
* @param {String} model the OpenERP model this dataset will manage
*/
@@ -706,7 +706,7 @@ instance.web.DataSet = instance.web.OldWidget.extend( /** @lends openerp.web.Da
* @returns {$.Deferred}
*/
call_and_eval: function (method, args, domain_index, context_index, callback, error_callback) {
- return this.rpc('/web/dataset/call', {
+ return instance.session.rpc('/web/dataset/call', {
model: this.model,
method: method,
domain_id: domain_index == undefined ? null : domain_index,
@@ -805,6 +805,22 @@ instance.web.DataSet = instance.web.OldWidget.extend( /** @lends openerp.web.Da
alter_ids: function(n_ids) {
this.ids = n_ids;
},
+ /**
+ * Resequence records.
+ *
+ * @param {Array} ids identifiers of the records to resequence
+ * @returns {$.Deferred}
+ */
+ resequence: function (ids, options) {
+ options = options || {};
+ return instance.session.rpc('/web/dataset/resequence', {
+ model: this.model,
+ ids: ids,
+ context: this._model.context(options.context),
+ }).pipe(function (results) {
+ return results;
+ });
+ },
});
instance.web.DataSetStatic = instance.web.DataSet.extend({
init: function(parent, model, context, ids) {
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index 53daa40ae31..a7625631aa5 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -635,6 +635,16 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
return null;
}
},
+
+ add_common_inputs: function() {
+ // add Filters to this.inputs, need view.controls filled
+ (new instance.web.search.Filters(this));
+ // add custom filters to this.inputs
+ (new instance.web.search.CustomFilters(this));
+ // add Advanced to this.inputs
+ (new instance.web.search.Advanced(this));
+ },
+
on_loaded: function(data) {
var self = this;
this.fields_view = data.fields_view;
@@ -649,20 +659,13 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
data.fields_view['arch'].children,
data.fields_view.fields);
- // add Filters to this.inputs, need view.controls filled
- (new instance.web.search.Filters(this));
- // add custom filters to this.inputs
- (new instance.web.search.CustomFilters(this));
- // add Advanced to this.inputs
- (new instance.web.search.Advanced(this));
+ this.add_common_inputs();
// build drawer
var drawer_started = $.when.apply(
null, _(this.select_for_drawer()).invoke(
'appendTo', this.$element.find('.oe_searchview_drawer')));
- new instance.web.search.AddToReporting(this).appendTo($('.oe_searchview_drawer', this.$element));
-
// load defaults
var defaults_fetched = $.when.apply(null, _(this.inputs).invoke(
'facet_for_defaults', this.defaults)).then(function () {
@@ -683,9 +686,6 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
case 'advanced_filter':
this.extended_search.on_activate();
break;
- case 'add_to_dashboard':
- this.on_add_to_dashboard();
- break;
case '':
this.do_clear();
}
@@ -1613,7 +1613,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
}
var filter = {
name: $name.val(),
- user_id: private_filter ? instance.connection.uid : false,
+ user_id: private_filter ? instance.session.uid : false,
model_id: self.view.model,
context: results.context,
domain: results.domain
@@ -1678,74 +1678,6 @@ instance.web.search.Filters = instance.web.search.Input.extend({
}));
}
});
-instance.web.search.AddToReporting = instance.web.Widget.extend({
- template: 'SearchView.addtoreporting',
- _in_drawer: true,
- start: function () {
- var self = this;
- this.$element
- .on('click', 'h4', this.proxy('show_option'))
- .on('submit', 'form', function (e) {
- e.preventDefault();
- self.add_dashboard();
- });
- return this.load_data().then(this.proxy("render_data"));
- },
- load_data:function(){
- if (!instance.webclient) { return $.Deferred().reject(); }
- var dashboard_menu = instance.webclient.menu.data.data.children;
- return new instance.web.Model('ir.model.data')
- .query(['res_id'])
- .filter([['name','=','menu_reporting_dashboard']])
- .first().pipe(function (result) {
- var menu = _(dashboard_menu).chain()
- .pluck('children')
- .flatten(true)
- .find(function (child) { return child.id === result.res_id; })
- .value();
- return menu ? menu.children : [];
- });
- },
- render_data: function(dashboard_choices){
- var selection = instance.web.qweb.render(
- "SearchView.addtoreporting.selection", {
- selections: dashboard_choices});
- this.$("input").before(selection)
- },
- add_dashboard:function(){
- var self = this;
- var getParent = this.getParent();
- var view_parent = this.getParent().getParent();
- if (! view_parent.action || ! this.$element.find("select").val())
- return this.do_warn("Can't find dashboard action");
- var data = getParent.build_search_data();
- var context = new instance.web.CompoundContext(getParent.dataset.get_context() || []);
- var domain = new instance.web.CompoundDomain(getParent.dataset.get_domain() || []);
- _.each(data.contexts, context.add, context);
- _.each(data.domains, domain.add, domain);
- this.rpc('/web/searchview/add_to_dashboard', {
- menu_id: this.$element.find("select").val(),
- action_id: view_parent.action.id,
- context_to_save: context,
- domain: domain,
- view_mode: view_parent.active_view,
- name: this.$element.find("input").val()
- }, function(r) {
- if (r === false) {
- self.do_warn("Could not add filter to dashboard");
- } else {
- self.$element.toggleClass('oe_opened');
- self.do_notify("Filter added to dashboard", '');
- }
- });
- },
- show_option:function(){
- this.$element.toggleClass('oe_opened');
- if (! this.$element.hasClass('oe_opened'))
- return;
- this.$("input").val(this.getParent().fields_view.name || "" );
- }
-});
instance.web.search.Advanced = instance.web.search.Input.extend({
template: 'SearchView.advanced',
@@ -1805,11 +1737,11 @@ instance.web.search.Advanced = instance.web.search.Input.extend({
}
});
-instance.web.search.ExtendedSearchProposition = instance.web.OldWidget.extend(/** @lends instance.web.search.ExtendedSearchProposition# */{
+instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @lends instance.web.search.ExtendedSearchProposition# */{
template: 'SearchView.extended_search.proposition',
/**
* @constructs instance.web.search.ExtendedSearchProposition
- * @extends instance.web.OldWidget
+ * @extends instance.web.Widget
*
* @param parent
* @param fields
diff --git a/addons/web/static/src/js/test_support.js b/addons/web/static/src/js/test_support.js
index d46366326b7..314a12c91c6 100644
--- a/addons/web/static/src/js/test_support.js
+++ b/addons/web/static/src/js/test_support.js
@@ -1,12 +1,12 @@
openerp.test_support = {
- setup_connection: function (connection) {
+ setup_session: function (session) {
var origin = location.protocol+"//"+location.host;
- _.extend(connection, {
+ _.extend(session, {
origin: origin,
prefix: origin,
server: origin, // keep chs happy
//openerp.web.qweb.default_dict['_s'] = this.origin;
- rpc_function: connection.rpc_json,
+ rpc_function: session.rpc_json,
session_id: false,
uid: false,
username: false,
@@ -22,7 +22,7 @@ openerp.test_support = {
shortcuts: [],
active_id: null
});
- return connection.session_reload();
+ return session.session_reload();
},
module: function (title, tested_core, nonliterals) {
var conf = QUnit.config.openerp = {};
@@ -31,10 +31,10 @@ openerp.test_support = {
QUnit.stop();
var oe = conf.openerp = window.openerp.init();
window.openerp.web[tested_core](oe);
- var done = openerp.test_support.setup_connection(oe.connection);
+ var done = openerp.test_support.setup_session(oe.session);
if (nonliterals) {
done = done.pipe(function () {
- return oe.connection.rpc('/tests/add_nonliterals', {
+ return oe.session.rpc('/tests/add_nonliterals', {
domains: nonliterals.domains || [],
contexts: nonliterals.contexts || []
}).then(function (r) {
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 823bb4b57ad..e2a254773ae 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -255,7 +255,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
/**
*
* @param {Object} [options]
- * @param {Boolean} [editable=false] whether the form should be switched to edition mode. A value of ``false`` will keep the current mode.
+ * @param {Boolean} [mode=undefined] If specified, switch the form to specified mode. Can be "edit" or "view".
* @param {Boolean} [reload=true] whether the form should reload its content on show, or use the currently loaded record
* @return {$.Deferred}
*/
@@ -292,9 +292,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
});
}
return shown.pipe(function() {
- if (options.editable) {
- self.to_edit_mode();
- }
+ self._actualize_mode(options.mode || self.options.initial_mode);
self.$element.css({
opacity: '1',
filter: 'alpha(opacity = 100)'
@@ -634,12 +632,21 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
this._actualize_mode("edit");
},
/**
- * Reactualize actual_mode.
+ * Ask the view to switch to a precise mode if possible. The view is free to
+ * not respect this command if the state of the dataset is not compatible with
+ * the new mode. For example, it is not possible to switch to edit mode if
+ * the current record is not yet saved in database.
+ *
+ * @param {string} [new_mode] Can be "edit", "view", "create" or undefined. If
+ * undefined the view will test the actual mode to check if it is still consistent
+ * with the dataset state.
*/
_actualize_mode: function(switch_to) {
var mode = switch_to || this.get("actual_mode");
if (! this.datarecord.id) {
mode = "create";
+ } else if (mode === "create") {
+ mode = "edit";
}
this.set({actual_mode: mode});
},
@@ -1656,7 +1663,7 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi
template = 'WidgetLabel.tooltip';
}
return QWeb.render(template, {
- debug: instance.connection.debug,
+ debug: instance.session.debug,
widget: widget
})},
gravity: $.fn.tipsy.autoBounds(50, 'nw'),
@@ -1733,7 +1740,7 @@ instance.web.form.WidgetButton = instance.web.form.FormWidget.extend({
start: function() {
this._super.apply(this, arguments);
this.$element.click(this.on_click);
- if (this.node.attrs.help || instance.connection.debug) {
+ if (this.node.attrs.help || instance.session.debug) {
this.do_attach_tooltip();
}
this.setupFocus(this.$element);
@@ -1930,7 +1937,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w
}, this));
}
this.$label = this.view.$element.find('label[for=' + this.id_for_label + ']');
- if (instance.connection.debug) {
+ if (instance.session.debug) {
this.do_attach_tooltip(this, this.$label[0] || this.$element);
this.$label.off('dblclick').on('dblclick', function() {
console.log("Field '%s' of type '%s' in View: %o", self.name, (self.node.attrs.widget || self.field.type), self.view);
@@ -2173,7 +2180,7 @@ instance.web.form.FieldFloat = instance.web.form.FieldChar.extend({
}
});
-instance.web.DateTimeWidget = instance.web.OldWidget.extend({
+instance.web.DateTimeWidget = instance.web.Widget.extend({
template: "web.datepicker",
jqueryui_object: 'datetimepicker',
type_of_date: "datetime",
@@ -2394,44 +2401,54 @@ instance.web.form.FieldText = instance.web.form.AbstractField.extend(instance.we
* To find more information about CLEditor configutation: go to
* http://premiumsoftware.net/cleditor/docs/GettingStarted.html
*/
-instance.web.form.FieldTextHtml = instance.web.form.FieldText.extend({
-
- initialize_content: function() {
- this.$textarea = this.$element.find('textarea');
- var width = ((this.node.attrs || {}).editor_width || 468);
- var height = ((this.node.attrs || {}).editor_height || 100);
- this.$textarea.cleditor({
- width: width, // width not including margins, borders or padding
- height: height, // height not including margins, borders or padding
- controls: // controls to add to the toolbar
- "bold italic underline strikethrough | size " +
- "| removeformat | bullets numbering | outdent " +
- "indent | link unlink",
- sizes: // sizes in the font size popup
- "1,2,3,4,5,6,7",
- bodyStyle: // style to assign to document body contained within the editor
- "margin:4px; font:12px monospace; cursor:text; color:#1F1F1F"
- });
- this.$cleditor = this.$textarea.cleditor()[0];
- // call super now, because cleditor resets the disable attr
+instance.web.form.FieldTextHtml = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, {
+ template: 'FieldTextHtml',
+ init: function() {
this._super.apply(this, arguments);
- // propagate disabled property to cleditor
- this.$cleditor.disable(this.$textarea.prop('disabled'));
+ if (this.field.type !== 'html') {
+ throw new Error(_.str.sprintf(
+ _t("Error with field %s, it is not allowed to use the widget 'html' with any other field type than 'html'"), this.string));
+ }
+ },
+ initialize_content: function() {
+ var self = this;
+ if (! this.get("effective_readonly")) {
+ self._updating_editor = false;
+ this.$textarea = this.$element.find('textarea');
+ var width = ((this.node.attrs || {}).editor_width || 468);
+ var height = ((this.node.attrs || {}).editor_height || 100);
+ this.$textarea.cleditor({
+ width: width, // width not including margins, borders or padding
+ height: height, // height not including margins, borders or padding
+ controls: // controls to add to the toolbar
+ "bold italic underline strikethrough " +
+ "| removeformat | bullets numbering | outdent " +
+ "indent | link unlink | source",
+ bodyStyle: // style to assign to document body contained within the editor
+ "margin:4px; font:12px monospace; cursor:text; color:#1F1F1F"
+ });
+ this.$cleditor = this.$textarea.cleditor()[0];
+ this.$cleditor.change(function() {
+ if (! self._updating_editor) {
+ self.$cleditor.updateTextArea();
+ self.set({'value': self.$textarea.val()});
+ }
+ });
+ }
},
-
set_value: function(value_) {
this._super.apply(this, arguments);
- this._dirty_flag = true;
+ this.render_value();
},
-
render_value: function() {
- this._super.apply(this, arguments);
- this.$cleditor.updateFrame();
- },
-
- get_value: function() {
- this.$cleditor.updateTextArea();
- return this.$textarea.val();
+ if (! this.get("effective_readonly")) {
+ this.$textarea.val(this.get('value'));
+ this._updating_editor = true;
+ this.$cleditor.updateFrame();
+ this._updating_editor = false;
+ } else {
+ this.$element.html(this.get('value'));
+ }
},
});
@@ -2706,6 +2723,11 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
this.floating = false;
this.render_value();
});
+ instance.web.bus.on('click', this, function() {
+ if (!this.get("effective_readonly") && this.$input && this.$input.autocomplete('widget').is(':visible')) {
+ this.$input.autocomplete("close");
+ }
+ });
},
initialize_content: function() {
if (!this.get("effective_readonly"))
@@ -2784,8 +2806,8 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
}
}
});
- var tip_def = $.Deferred();
- var untip_def = $.Deferred();
+ self.tip_def = $.Deferred();
+ self.untip_def = $.Deferred();
var tip_delay = 200;
var tip_duration = 15000;
var anyoneLoosesFocus = function() {
@@ -2807,24 +2829,25 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
}
self.floating = false;
}
- if (used && self.get("value") === false) {
- tip_def.reject();
- untip_def.reject();
- tip_def = $.Deferred();
- tip_def.then(function() {
+ if (used && self.get("value") === false && ! self.no_tipsy) {
+ self.tip_def.reject();
+ self.untip_def.reject();
+ self.tip_def = $.Deferred();
+ self.tip_def.then(function() {
self.$input.tipsy("show");
});
setTimeout(function() {
- tip_def.resolve();
- untip_def.reject();
- untip_def = $.Deferred();
- untip_def.then(function() {
+ self.tip_def.resolve();
+ self.untip_def.reject();
+ self.untip_def = $.Deferred();
+ self.untip_def.then(function() {
self.$input.tipsy("hide");
});
- setTimeout(function() {untip_def.resolve();}, tip_duration);
+ setTimeout(function() {self.untip_def.resolve();}, tip_duration);
}, tip_delay);
} else {
- tip_def.reject();
+ self.no_tipsy = false;
+ self.tip_def.reject();
}
};
this.$input.focusout(anyoneLoosesFocus);
@@ -2953,7 +2976,17 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
},
focus: function () {
this.$input.focus();
- }
+ },
+ _quick_create: function() {
+ this.no_tipsy = true;
+ this.tip_def.reject();
+ return instance.web.form.CompletionFieldMixin._quick_create.apply(this, arguments);
+ },
+ _search_create_popup: function() {
+ this.no_tipsy = true;
+ this.tip_def.reject();
+ return instance.web.form.CompletionFieldMixin._search_create_popup.apply(this, arguments);
+ },
});
/*
@@ -4078,7 +4111,7 @@ instance.web.form.Many2ManyQuickCreate = instance.web.Widget.extend({
/**
* Class with everything which is common between FormOpenPopup and SelectCreatePopup.
*/
-instance.web.form.AbstractFormPopup = instance.web.OldWidget.extend({
+instance.web.form.AbstractFormPopup = instance.web.Widget.extend({
template: "AbstractFormPopup.render",
/**
* options:
@@ -4156,7 +4189,10 @@ instance.web.form.AbstractFormPopup = instance.web.OldWidget.extend({
this.view_form.appendTo(this.$element.find(".oe_popup_form"));
this.view_form.on_loaded.add_last(function() {
var multi_select = self.row_id === null && ! self.options.disable_multiple_selection;
- self.$buttonpane.html(QWeb.render("AbstractFormPopup.buttons", {multi_select: multi_select}));
+ self.$buttonpane.html(QWeb.render("AbstractFormPopup.buttons", {
+ multi_select: multi_select,
+ readonly: self.row_id !== null && self.options.readonly,
+ }));
var $snbutton = self.$buttonpane.find(".oe_abstractformpopup-form-save-new");
$snbutton.click(function() {
$.when(self.view_form.do_save()).then(function() {
@@ -4177,11 +4213,6 @@ instance.web.form.AbstractFormPopup = instance.web.OldWidget.extend({
$cbutton.click(function() {
self.check_exit();
});
- if (self.row_id !== null && self.options.readonly) {
- $snbutton.hide();
- $sbutton.hide();
- $cbutton.text(_t("Close"));
- }
self.view_form.do_show();
});
},
@@ -4318,11 +4349,12 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
});
},
on_click_element: function(ids) {
+ var self = this;
this.selected_ids = ids || [];
if(this.selected_ids.length > 0) {
- this.$element.find(".oe_selectcreatepopup-search-select").removeAttr('disabled');
+ self.$buttonpane.find(".oe_selectcreatepopup-search-select").removeAttr('disabled');
} else {
- this.$element.find(".oe_selectcreatepopup-search-select").attr('disabled', "disabled");
+ self.$buttonpane.find(".oe_selectcreatepopup-search-select").attr('disabled', "disabled");
}
},
new_object: function() {
@@ -4616,8 +4648,9 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({
if (this.get('value') && ! /^\d+(\.\d*)? \w+$/.test(this.get('value'))) {
url = 'data:image/png;base64,' + this.get('value');
} else if (this.get('value')) {
+ var id = escape(JSON.stringify(this.view.datarecord.id || null));
url = '/web/binary/image?session_id=' + this.session.session_id + '&model=' +
- this.view.dataset.model +'&id=' + (this.view.datarecord.id || '') + '&field=' + this.name + '&t=' + (new Date().getTime());
+ this.view.dataset.model +'&id=' + id + '&field=' + this.name + '&t=' + (new Date().getTime());
} else {
url = "/web/static/src/img/placeholder.png";
}
@@ -4793,7 +4826,7 @@ instance.web.form.widgets = new instance.web.Registry({
'email' : 'instance.web.form.FieldEmail',
'url' : 'instance.web.form.FieldUrl',
'text' : 'instance.web.form.FieldText',
- 'text_html' : 'instance.web.form.FieldTextHtml',
+ 'html' : 'instance.web.form.FieldTextHtml',
'date' : 'instance.web.form.FieldDate',
'datetime' : 'instance.web.form.FieldDatetime',
'selection' : 'instance.web.form.FieldSelection',
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index 986b0e49faf..95dfa78fd63 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -2059,7 +2059,7 @@ instance.web.list.Button = instance.web.list.Column.extend({
title: this.string || '',
additional_attributes: isNaN(row_data["id"].value) && instance.web.BufferedDataSet.virtual_id_regex.test(row_data["id"].value) ?
'disabled="disabled" class="oe_list_button_disabled"' : '',
- prefix: instance.connection.prefix,
+ prefix: instance.session.prefix,
icon: this.icon,
alt: this.string || ''
});
@@ -2086,7 +2086,7 @@ instance.web.list.Binary = instance.web.list.Column.extend({
var text = _t("Download");
var download_url = _.str.sprintf(
'/web/binary/saveas?session_id=%s&model=%s&field=%s&id=%d',
- instance.connection.session_id, options.model, this.id, options.id);
+ instance.session.session_id, options.model, this.id, options.id);
if (this.filename) {
download_url += '&filename_field=' + this.filename;
if (row_data[this.filename]) {
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index 2845d9afb73..0831d0c5f8e 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -159,7 +159,9 @@ instance.web.ActionManager = instance.web.Widget.extend({
//state = _.extend(this.inner_action.params || {}, state);
}
}
- this.getParent().do_push_state(state);
+ if(!this.dialog) {
+ this.getParent().do_push_state(state);
+ }
}
},
do_load_state: function(state, warm) {
@@ -222,7 +224,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
}
var type = action.type.replace(/\./g,'_');
var popup = action.target === 'new';
- var inline = action.target === 'inline';
+ var inline = action.target === 'inline' || action.target === 'inlineview';
action.flags = _.extend({
views_switcher : !popup && !inline,
search_view : !popup && !inline,
@@ -241,8 +243,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
this.dialog_stop();
this.clear_breadcrumbs();
},
-
- do_ir_actions_common: function(action, on_close) {
+ ir_actions_common: function(action, on_close) {
var self = this, klass, widget, post_process;
if (action.type === 'ir.actions.client') {
var ClientWidget = instance.web.client_actions.get_object(action.tag);
@@ -286,16 +287,8 @@ instance.web.ActionManager = instance.web.Widget.extend({
this.inner_widget.appendTo(this.$element);
}
},
-
ir_actions_act_window: function (action, on_close) {
var self = this;
- if (_(['base.module.upgrade', 'base.setup.installer'])
- .contains(action.res_model)) {
- var old_close = on_close;
- on_close = function () {
- instance.webclient.do_reload().then(old_close);
- };
- }
if (action.target !== 'new') {
if(action.menu_id) {
this.dialog_stop();
@@ -304,10 +297,10 @@ instance.web.ActionManager = instance.web.Widget.extend({
});
}
}
- return this.do_ir_actions_common(action, on_close);
+ return this.ir_actions_common(action, on_close);
},
ir_actions_client: function (action, on_close) {
- return this.do_ir_actions_common(action, on_close);
+ return this.ir_actions_common(action, on_close);
},
ir_actions_act_window_close: function (action, on_closed) {
if (!this.dialog && on_closed) {
@@ -350,9 +343,6 @@ instance.web.ActionManager = instance.web.Widget.extend({
ir_actions_act_url: function (action) {
window.open(action.url, action.target === 'self' ? '_self' : '_blank');
},
- ir_ui_menu: function (action) {
- this.getParent().do_action(action);
- }
});
instance.web.ViewManager = instance.web.Widget.extend({
@@ -475,17 +465,12 @@ instance.web.ViewManager = instance.web.Widget.extend({
// Lazy loading of views
var self = this;
var view = this.views[view_type];
- var controllerclass = this.registry.get_object(view_type);
+ var viewclass = this.registry.get_object(view_type);
var options = _.clone(view.options);
- if (view_type === "form" && this.action) {
- switch (this.action.target) {
- case 'new':
- case 'inline':
- options.initial_mode = 'edit';
- break;
- }
+ if (view_type === "form" && this.action && (this.action.target == 'new' || this.action.target == 'inline')) {
+ options.initial_mode = 'edit';
}
- var controller = new controllerclass(this, this.dataset, view.view_id, options);
+ var controller = new viewclass(this, this.dataset, view.view_id, options);
controller.on('history_back', this, function() {
var am = self.getParent();
@@ -1179,7 +1164,6 @@ instance.web.TranslateDialog = instance.web.Dialog.extend({
});
instance.web.View = instance.web.Widget.extend({
- template: "EmptyComponent",
// name displayed in view switchers
display_name: '',
/**
@@ -1349,12 +1333,10 @@ instance.web.View = instance.web.Widget.extend({
do_search: function(view) {
},
on_sidebar_import: function() {
- var import_view = new instance.web.DataImport(this, this.dataset);
- import_view.start();
+ new instance.web.DataImport(this, this.dataset).open();
},
on_sidebar_export: function() {
- var export_view = new instance.web.DataExport(this, this.dataset);
- export_view.start();
+ new instance.web.DataExport(this, this.dataset).open();
},
on_sidebar_translate: function() {
return this.do_action({
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 75c9904dbf7..8e6f7ffc3cb 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -121,25 +121,25 @@
</select>
</t>
+
<t t-name="DatabaseManager">
- <div class="oe_database_manager">
- <div class="oe_database_manager_menu">
- <ul class="oe_notebook">
- <li><a href="#db_create">Create</a></li>
- <li><a href="#db_drop">Drop</a></li>
- <li><a href="#db_backup">Backup</a></li>
- <li><a href="#db_restore">Restore</a></li>
- <li><a href="#db_change_password">Password</a></li>
- <li><a id="back_to_login" href="#">Back to Login</a></li>
- </ul>
- <form id="db_create" name="create_db_form" method="POST">
+ <div class="oe_view_manager_view_form">
+ <div class="oe_form">
+ <form id="db_create" name="create_db_form" style="display: block;">
+ <div class="oe_view_manager oe_view_manager_current">
+ <div class="oe_view_manager_header" style="padding: 8px;">
+ <div class="oe_header_row">
+ <h2 class="oe_view_title">
+ <span class="oe_view_title_text oe_breadcrumb_title">Create Database</span>
+ </h2>
+ <button type="submit" class="oe_button oe_highlight db_create">Create</button>
+ </div>
+ </div>
+ </div>
<table align="center" class="db_option_table">
<tr>
- <th colspan="2" class="option_string"> CREATE DATABASE </th>
- </tr>
- <tr>
<td><label for="super_admin_pwd">Master password:</label></td>
- <td><input type="password" name="super_admin_pwd" class="required" value="admin"/></td>
+ <td><input type="password" name="super_admin_pwd" class="required" value="admin" /></td>
</tr>
<tr>
<td><label for="db_name">New database name:</label></td>
@@ -147,42 +147,54 @@
</tr>
<tr>
<td><label for="demo_data">Load Demonstration data:</label></td>
- <td><input type="checkbox" name="demo_data"/></td>
+ <td class="oe_form_group_cell">
+ <span class="oe_form_field oe_form_field_boolean">
+ <input type="checkbox" name="demo_data" />
+ </span>
+ </td>
</tr>
<tr>
<td><label for="db_lang">Default language:</label></td>
- <td>
+ <td class="oe_form_field oe_form_field_selection ">
<select name="db_lang" t-if="widget.lang_list">
<t t-foreach="widget.lang_list" t-as="lang">
- <option t-att-value="lang[0]" t-att-selected="lang[0] === 'en_US' ? 'selected' : undefined"><t t-esc="lang[1]"/></option>
+ <option t-att-value="lang[0]" t-att-selected="lang[0] === 'en_US' ? 'selected' : undefined">
+ <t t-esc="lang[1]" />
+ </option>
</t>
</select>
</td>
</tr>
<tr>
<td><label for="create_admin_pwd">Admin password:</label></td>
- <td><input type="password" name="create_admin_pwd" class="required"/></td>
+ <td><input type="password" name="create_admin_pwd" class="required" /></td>
</tr>
<tr>
<td><label for="create_confirm_pwd">Confirm password:</label></td>
<td><input type="password" name="create_confirm_pwd" class="required" equalTo="input[name=create_admin_pwd]"/></td>
</tr>
- <tr>
- <td colspan="2" align="right"><button class="oe_button">Create</button></td>
- </tr>
</table>
</form>
- <form id="db_drop" name="drop_db_form" method="POST">
+ <form id="db_drop" name="drop_db_form" style="display: none; ">
+ <div class="oe_view_manager oe_view_manager_current">
+ <div class="oe_view_manager_header" style="padding: 8px;">
+ <div class="oe_header_row">
+ <h2 class="oe_view_title">
+ <span class="oe_view_title_text oe_breadcrumb_title">Drop Database</span>
+ </h2>
+ <button type="submit" class="oe_button oe_highlight db_drop">Drop</button>
+ </div>
+ </div>
+ </div>
<table align="center" class="db_option_table">
<tr>
- <th colspan="2" class="option_string"> DROP DATABASE </th>
- </tr>
- <tr>
<td><label for="drop_db">Database:</label></td>
- <td>
+ <td class="oe_form_field oe_form_field_selection">
<select t-if="widget.db_list" name="drop_db" autofocus="autofocus">
<t t-foreach="widget.db_list" t-as="db">
- <option t-att-value="db"><t t-esc="db"/></option>
+ <option t-att-value="db">
+ <t t-esc="db" />
+ </option>
</t>
</select>
<input t-if="!widget.db_list" name="drop_db" class="required" type="text" autofocus="autofocus"/>
@@ -190,25 +202,31 @@
</tr>
<tr>
<td><label for="drop_password">Master Password:</label></td>
- <td><input type="password" name="drop_pwd" class="required"/></td>
- </tr>
- <tr>
- <td colspan="2" align="right"><button class="oe_button">Drop</button></td>
+ <td><input type="password" name="drop_pwd" class="required" /></td>
</tr>
</table>
</form>
- <form id="db_backup" name="backup_db_form" method="POST" target="backup-target" action="/web/database/backup">
- <input type="hidden" name="token"/>
+ <form id="db_backup" name="backup_db_form" target="backup-target" action="/web/database/backup" style="display: none;">
+ <div class="oe_view_manager oe_view_manager_current">
+ <div class="oe_view_manager_header" style="padding: 8px;">
+ <div class="oe_header_row">
+ <h2 class="oe_view_title">
+ <span class="oe_view_title_text oe_breadcrumb_title">Backup Database</span>
+ </h2>
+ <button type="submit" class="oe_button oe_highlight db_backup">Backup</button>
+ </div>
+ </div>
+ </div>
+ <input type="hidden" name="token" />
<table align="center" class="db_option_table">
<tr>
- <th colspan="2" class="option_string"> BACKUP DATABASE </th>
- </tr>
- <tr>
<td><label for="backup_db">Database:</label></td>
- <td>
+ <td class="oe_form_field oe_form_field_selection ">
<select t-if="widget.db_list" name="backup_db" autofocus="autofocus">
<t t-foreach="widget.db_list" t-as="db">
- <option t-att-value="db"><t t-esc="db"/></option>
+ <option t-att-value="db">
+ <t t-esc="db" />
+ </option>
</t>
</select>
<input t-if="!widget.db_list" name="backup_db" class="required" type="text" autofocus="autofocus"/>
@@ -216,19 +234,23 @@
</tr>
<tr>
<td><label for="backup_pwd">Master Password:</label></td>
- <td><input type="password" name="backup_pwd" class="required"/></td>
- </tr>
- <tr>
- <td colspan="2" align="right"><button class="oe_button">Backup</button></td>
+ <td><input type="password" name="backup_pwd" class="required" /></td>
</tr>
</table>
</form>
- <form id="db_restore" name="restore_db_form" method="POST">
+ <form id="db_restore" name="restore_db_form" style="display: none; ">
+ <div class="oe_view_manager oe_view_manager_current">
+ <div class="oe_view_manager_header" style="padding: 8px;">
+ <div class="oe_header_row">
+ <h2 class="oe_view_title">
+ <span class="oe_view_title_text oe_breadcrumb_title">Restore Database</span>
+ </h2>
+ <button type="submit" class="oe_button oe_highlight db_restore">Restore</button>
+ </div>
+ </div>
+ </div>
<table align="center" class="db_option_table">
<tr>
- <th colspan="2" class="option_string"> RESTORE DATABASE </th>
- </tr>
- <tr>
<td><label for="restore_db">File:</label></td>
<td><input type="file" name="db_file" class="required" autofocus="autofocus"/></td>
</tr>
@@ -240,17 +262,21 @@
<td><label for="new_db">New database name:</label></td>
<td><input type="text" name="new_db" class="required"/></td>
</tr>
- <tr>
- <td colspan="2" align="right"><button class="oe_button">Restore</button></td>
- </tr>
</table>
</form>
- <form id="db_change_password" name="change_pwd_form" method="POST">
+ <form id="db_change_password" name="change_pwd_form" style="display: none;">
+ <div class="oe_view_manager oe_view_manager_current">
+ <div class="oe_view_manager_header" style="padding: 8px;">
+ <div class="oe_header_row">
+ <h2 class="oe_view_title">
+ <span class="oe_view_title_text oe_breadcrumb_title">Change Master Password</span>
+ </h2>
+ <button type="submit" class="oe_button oe_highlight db-change-password">Change Password</button>
+ </div>
+ </div>
+ </div>
<table align="center" class="db_option_table">
<tr>
- <th colspan="2" class="option_string"> CHANGE MASTER PASSWORD </th>
- </tr>
- <tr>
<td><label for="old_pwd">Master password:</label></td>
<td><input type="password" name="old_pwd" class="required" minlength="1" autofocus="autofocus"/></td>
</tr>
@@ -260,16 +286,28 @@
</tr>
<tr>
<td><label for="confirm_pwd">Confirm new master password:</label></td>
- <td><input type="password" name="confirm_pwd" class="required" equalTo="input[name=new_pwd]" minlength="1"/></td>
- </tr>
- <tr>
- <td colspan="2" align="right"><button class="oe_button">Change Password</button></td>
+ <td><input type="password" name="confirm_pwd" class="required" equalTo="input[name=new_pwd]" minlength="1"/> </td>
</tr>
</table>
</form>
</div>
</div>
</t>
+<t t-name="DatabaseManager.user_menu">
+ <span class="oe_right">
+ <a id="back-to-login" href="#"><span class="oe_topbar_item oe_topbar_name">Back to Login</span></a>
+ </span>
+</t>
+<t t-name="DatabaseManager.menu">
+ <div class="oe_secondary_menu_section">Database Management</div>
+ <ul class="oe_secondary_submenu">
+ <li><a href="#db_create">Create</a></li>
+ <li><a href="#db_drop">Drop</a></li>
+ <li><a href="#db_backup">Backup</a></li>
+ <li><a href="#db_restore">Restore</a></li>
+ <li><a href="#db_change_password">Password</a></li>
+ </ul>
+</t>
<t t-name="ChangePassword">
<form name="change_password_form" method="POST">
@@ -282,7 +320,7 @@
<tr>
<td><label for="new_password">New Password:</label></td>
<td><input type="password" name="new_password"
- minlength="1" autofocus="autofocus"/></td>
+ minlength="1"/></td>
</tr>
<tr>
<td><label for="confirm_pwd">Confirm Password:</label></td>
@@ -937,6 +975,14 @@
/>
</div>
</t>
+<t t-name="FieldTextHtml">
+ <div t-att-class="'oe_form_field oe_form_field_html' + (widget.get('effective_readonly') ? ' oe_form_embedded_html' : '')"
+ t-att-style="widget.node.attrs.style">
+ <t t-if="! widget.get('effective_readonly')">
+ <textarea/>
+ </t>
+ </div>
+</t>
<t t-name="web.datepicker">
<span>
<t t-set="placeholder" t-value="widget.getParent().node and widget.getParent().node.attrs.placeholder"/>
@@ -1051,7 +1097,7 @@
<span></span>
</span>
<img t-att-src='_s + "/web/static/src/img/form_steps.png"' class="oe_form_steps_arrow" t-if="i &lt; size - 1"/>
- </div>
+ </div>
</li>
</t>
</t>
@@ -1245,14 +1291,24 @@
<a class="oe_button oe_selectcreatepopup-search-close oe_bold oe_form_button_cancel" href="javascript:void(0)">Cancel</a>
</t>
<t t-name="AbstractFormPopup.buttons">
- <t t-if="! multi_select">
- <button type="button" class="oe_button oe_abstractformpopup-form-save oe_highlight">Save</button>
- </t>
- <t t-if="multi_select">
- <button type="button" class="oe_button oe_abstractformpopup-form-save-new oe_highlight">Save &amp; New</button>
- <button type="button" class="oe_button oe_abstractformpopup-form-save oe_highlight">Save &amp; Close</button>
+ <t t-if="! readonly">
+ <t t-if="! multi_select">
+ <button type="button" class="oe_button oe_abstractformpopup-form-save oe_highlight">Save</button>
+ </t>
+ <t t-if="multi_select">
+ <button type="button" class="oe_button oe_abstractformpopup-form-save-new oe_highlight">Save &amp; New</button>
+ <button type="button" class="oe_button oe_abstractformpopup-form-save oe_highlight">Save &amp; Close</button>
+ </t>
+ or
</t>
- or <a class="oe_button oe_abstractformpopup-form-close oe_bold oe_form_button_cancel" href="javascript:void(0)">Discard</a>
+ <a class="oe_button oe_abstractformpopup-form-close oe_bold oe_form_button_cancel" href="javascript:void(0)">
+ <t t-if="! readonly">
+ Discard
+ </t>
+ <t t-if="readonly">
+ Close
+ </t>
+ </a>
</t>
<t t-name="One2Many.viewmanager" t-extend="ViewManager">
@@ -1469,20 +1525,7 @@
<div>
</div>
</div>
-<div t-name="SearchView.addtoreporting" class="oe_searchview_dashboard">
- <h4>Add to Dashboard</h4>
- <form>
- <p><input placeholder="Title of new dashboard item"/></p>
- <button class="oe_apply" type="submit">Add</button>
- </form>
-</div>
-<t t-name="SearchView.addtoreporting.selection">
- <select>
- <option t-foreach="selections" t-as="element"
- t-att-value="element.id || element.res_id ">
- <t t-esc="element.name"/></option>
- </select>
-</t>
+
<div t-name="SearchView.advanced" class="oe_searchview_advanced">
<h4>Advanced Search</h4>
<form>
@@ -1708,5 +1751,12 @@
<div t-name="Many2ManyKanban.quick_create" class="oe_kanban_quick_create">
<input t-att-placeholder="_t('Type name to search')"/>
</div>
-
+<t t-name="Throbber">
+ <div>
+ <div class="oe_blockui_spin" style="height: 50px">
+ </div>
+ <br />
+ <div style="color:white">Loading...</div>
+ </div>
+</t>
</templates>