[MERGE] *: stop duplicating web
Avoid duplicating web addon in enterprise by extracting a common basis. Enterprise features stay in enterprise, but use that common basis. In web, mainly: - JS refactoring and linting - Conversion of .sass into .less split into multiple files - Templates cleaning and DOM simplification - Re-generation of web.pot, and update of .po files Minor tweaks in some other addons to make them work with this new structure.
This commit is contained in:
@@ -127,9 +127,8 @@
|
||||
<script type="text/javascript" src="/mail/static/src/js/chat_window.js"></script>
|
||||
<script type="text/javascript" src="/mail/static/src/js/thread.js"></script>
|
||||
<script type="text/javascript" src="/im_livechat/static/src/js/im_livechat.js"></script>
|
||||
<t t-call="web.less_helpers"/>
|
||||
<link rel="stylesheet" href="/im_livechat/static/src/less/im_livechat_bootstrap.less"/>
|
||||
<link rel="stylesheet" href="/web/static/src/less/variables.less"/>
|
||||
<link rel="stylesheet" href="/web/static/src/less/utils.less"/>
|
||||
<link rel="stylesheet" href="/mail/static/src/less/chat_window.less"></link>
|
||||
<link rel="stylesheet" href="/mail/static/src/less/thread.less"></link>
|
||||
<link rel="stylesheet" href="/im_livechat/static/src/less/im_livechat.less"/>
|
||||
|
||||
@@ -84,6 +84,9 @@ var FieldPad = form_common.AbstractField.extend(form_common.ReinitializeWidgetMi
|
||||
}
|
||||
});
|
||||
},
|
||||
is_false: function() {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
core.form_widget_registry.add('pad', FieldPad);
|
||||
|
||||
@@ -54,13 +54,7 @@
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class='openerp openerp_webclient_container'>
|
||||
<table class='oe_webclient'>
|
||||
<tr>
|
||||
<td class='oe_application' />
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="o_main_content"/>
|
||||
</body>
|
||||
</html>
|
||||
</template>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@dashboard-bg-color: white;
|
||||
|
||||
.o_kanban_view.o_kanban_dashboard.o_salesteam_kanban {
|
||||
@sale-table-spacing: 10px;
|
||||
|
||||
@@ -13,7 +15,7 @@
|
||||
.o-flex(1, 0, 100%);
|
||||
padding: 10px (@odoo-horizontal-padding - @sale-table-spacing);
|
||||
|
||||
background-color: @odoo-view-background-color;
|
||||
background-color: @dashboard-bg-color;
|
||||
position: relative;
|
||||
|
||||
.o_welcome_message {
|
||||
@@ -51,7 +53,7 @@
|
||||
> tbody > tr > td {
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
border-top: 1px solid @odoo-view-background-color;
|
||||
border-top: 1px solid @dashboard-bg-color;
|
||||
width: 25%;
|
||||
|
||||
height: 33px;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"directory": "static/lib/"
|
||||
}
|
||||
@@ -9,30 +9,10 @@ module.exports = function(grunt) {
|
||||
laxbreak: true, //unsafe line breaks
|
||||
},
|
||||
},
|
||||
sass: {
|
||||
dev: {
|
||||
options: {
|
||||
style: "expanded",
|
||||
},
|
||||
files: {
|
||||
"static/src/css/base.css": "static/src/css/base.sass",
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
sass: {
|
||||
files: ["static/src/css/base.sass"],
|
||||
tasks: ['sass']
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-sass');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
|
||||
grunt.registerTask('gen', ["sass"]);
|
||||
grunt.registerTask('watcher', ["gen", "watch"]);
|
||||
grunt.registerTask('test', []);
|
||||
|
||||
grunt.registerTask('default', ['jshint']);
|
||||
|
||||
@@ -14,8 +14,8 @@ This module provides the core of the Odoo Web Client.
|
||||
'data': [
|
||||
'views/webclient_templates.xml',
|
||||
],
|
||||
'qweb' : [
|
||||
'qweb': [
|
||||
"static/src/xml/*.xml",
|
||||
],
|
||||
'bootstrap': True, # load translations for login screen
|
||||
'bootstrap': True, # load translations for login screen
|
||||
}
|
||||
|
||||
@@ -427,13 +427,6 @@ def binary_content(xmlid=None, model='ir.attachment', id=None, field='datas', un
|
||||
xmlid=xmlid, model=model, id=id, field=field, unique=unique, filename=filename, filename_field=filename_field,
|
||||
download=download, mimetype=mimetype, default_mimetype=default_mimetype, env=env)
|
||||
|
||||
def db_info():
|
||||
version_info = openerp.service.common.exp_version()
|
||||
return {
|
||||
'server_version': version_info.get('server_version'),
|
||||
'server_version_info': version_info.get('server_version_info'),
|
||||
}
|
||||
|
||||
#----------------------------------------------------------
|
||||
# OpenERP Web web Controllers
|
||||
#----------------------------------------------------------
|
||||
@@ -454,7 +447,14 @@ class Home(http.Controller):
|
||||
|
||||
request.uid = request.session.uid
|
||||
menu_data = request.registry['ir.ui.menu'].load_menus(request.cr, request.uid, request.debug, context=request.context)
|
||||
return request.render('web.webclient_bootstrap', qcontext={'menu_data': menu_data, 'db_info': json.dumps(db_info())})
|
||||
|
||||
version_info = openerp.service.common.exp_version()
|
||||
db_info = {
|
||||
'server_version': version_info.get('server_version'),
|
||||
'server_version_info': version_info.get('server_version_info'),
|
||||
}
|
||||
|
||||
return request.render('web.webclient_bootstrap', qcontext={'menu_data': menu_data, 'db_info': json.dumps(db_info)})
|
||||
|
||||
@http.route('/web/dbredirect', type='http', auth="none")
|
||||
def web_db_redirect(self, redirect='/', **kw):
|
||||
|
||||
@@ -46,7 +46,7 @@ various situations:
|
||||
|
||||
Action button (``button`` tag in the view) inside the cell
|
||||
|
||||
``.oe_readonly``
|
||||
``.o_readonly``
|
||||
|
||||
Readonly field cell
|
||||
|
||||
@@ -66,7 +66,7 @@ Editable list view
|
||||
The editable list view module adds a few supplementary style hook
|
||||
classes, for edition situations:
|
||||
|
||||
``.oe_list_editable``
|
||||
``.o_list_editable``
|
||||
|
||||
Added to the ``.oe_list`` when the list is editable (however that
|
||||
was done). The class may be removed on-the-fly if the list becomes
|
||||
|
||||
+712
-538
File diff suppressed because it is too large
Load Diff
+750
-570
File diff suppressed because it is too large
Load Diff
+721
-547
File diff suppressed because it is too large
Load Diff
+720
-546
File diff suppressed because it is too large
Load Diff
+747
-569
File diff suppressed because it is too large
Load Diff
+712
-538
File diff suppressed because it is too large
Load Diff
+748
-570
File diff suppressed because it is too large
Load Diff
+745
-567
File diff suppressed because it is too large
Load Diff
+746
-568
File diff suppressed because it is too large
Load Diff
+750
-572
File diff suppressed because it is too large
Load Diff
+732
-554
File diff suppressed because it is too large
Load Diff
+746
-568
File diff suppressed because it is too large
Load Diff
+737
-559
File diff suppressed because it is too large
Load Diff
+749
-571
File diff suppressed because it is too large
Load Diff
+710
-536
File diff suppressed because it is too large
Load Diff
+741
-559
File diff suppressed because it is too large
Load Diff
+720
-546
File diff suppressed because it is too large
Load Diff
+740
-559
File diff suppressed because it is too large
Load Diff
+735
-557
File diff suppressed because it is too large
Load Diff
+734
-556
File diff suppressed because it is too large
Load Diff
+709
-535
File diff suppressed because it is too large
Load Diff
+719
-545
File diff suppressed because it is too large
Load Diff
+710
-536
File diff suppressed because it is too large
Load Diff
+728
-551
File diff suppressed because it is too large
Load Diff
+749
-571
File diff suppressed because it is too large
Load Diff
+743
-561
File diff suppressed because it is too large
Load Diff
+720
-546
File diff suppressed because it is too large
Load Diff
+711
-537
File diff suppressed because it is too large
Load Diff
+727
-553
File diff suppressed because it is too large
Load Diff
+709
-535
File diff suppressed because it is too large
Load Diff
+750
-572
File diff suppressed because it is too large
Load Diff
+742
-558
File diff suppressed because it is too large
Load Diff
+750
-576
File diff suppressed because it is too large
Load Diff
+740
-560
File diff suppressed because it is too large
Load Diff
+736
-558
File diff suppressed because it is too large
Load Diff
+726
-552
File diff suppressed because it is too large
Load Diff
+723
-549
File diff suppressed because it is too large
Load Diff
+749
-571
File diff suppressed because it is too large
Load Diff
+872
-504
File diff suppressed because it is too large
Load Diff
+735
-561
File diff suppressed because it is too large
Load Diff
+710
-536
File diff suppressed because it is too large
Load Diff
+749
-571
File diff suppressed because it is too large
Load Diff
+749
-571
File diff suppressed because it is too large
Load Diff
+747
-569
File diff suppressed because it is too large
Load Diff
+739
-557
File diff suppressed because it is too large
Load Diff
+725
-551
File diff suppressed because it is too large
Load Diff
+751
-573
File diff suppressed because it is too large
Load Diff
+744
-566
File diff suppressed because it is too large
Load Diff
+747
-565
File diff suppressed because it is too large
Load Diff
+749
-571
File diff suppressed because it is too large
Load Diff
+737
-559
File diff suppressed because it is too large
Load Diff
+740
-558
File diff suppressed because it is too large
Load Diff
+749
-571
File diff suppressed because it is too large
Load Diff
+709
-535
File diff suppressed because it is too large
Load Diff
+720
-546
File diff suppressed because it is too large
Load Diff
+735
-561
File diff suppressed because it is too large
Load Diff
+747
-567
File diff suppressed because it is too large
Load Diff
+737
-559
File diff suppressed because it is too large
Load Diff
+739
-557
File diff suppressed because it is too large
Load Diff
+724
-550
File diff suppressed because it is too large
Load Diff
+700
-510
File diff suppressed because it is too large
Load Diff
+751
-567
File diff suppressed because it is too large
Load Diff
+728
-550
File diff suppressed because it is too large
Load Diff
@@ -1,587 +0,0 @@
|
||||
/*!
|
||||
* Bootstrap v3.3.5 (http://getbootstrap.com)
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
.btn-default,
|
||||
.btn-primary,
|
||||
.btn-success,
|
||||
.btn-info,
|
||||
.btn-warning,
|
||||
.btn-danger {
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.btn-default:active,
|
||||
.btn-primary:active,
|
||||
.btn-success:active,
|
||||
.btn-info:active,
|
||||
.btn-warning:active,
|
||||
.btn-danger:active,
|
||||
.btn-default.active,
|
||||
.btn-primary.active,
|
||||
.btn-success.active,
|
||||
.btn-info.active,
|
||||
.btn-warning.active,
|
||||
.btn-danger.active {
|
||||
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
|
||||
}
|
||||
.btn-default.disabled,
|
||||
.btn-primary.disabled,
|
||||
.btn-success.disabled,
|
||||
.btn-info.disabled,
|
||||
.btn-warning.disabled,
|
||||
.btn-danger.disabled,
|
||||
.btn-default[disabled],
|
||||
.btn-primary[disabled],
|
||||
.btn-success[disabled],
|
||||
.btn-info[disabled],
|
||||
.btn-warning[disabled],
|
||||
.btn-danger[disabled],
|
||||
fieldset[disabled] .btn-default,
|
||||
fieldset[disabled] .btn-primary,
|
||||
fieldset[disabled] .btn-success,
|
||||
fieldset[disabled] .btn-info,
|
||||
fieldset[disabled] .btn-warning,
|
||||
fieldset[disabled] .btn-danger {
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.btn-default .badge,
|
||||
.btn-primary .badge,
|
||||
.btn-success .badge,
|
||||
.btn-info .badge,
|
||||
.btn-warning .badge,
|
||||
.btn-danger .badge {
|
||||
text-shadow: none;
|
||||
}
|
||||
.btn:active,
|
||||
.btn.active {
|
||||
background-image: none;
|
||||
}
|
||||
.btn-default {
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
||||
background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
|
||||
background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dbdbdb;
|
||||
border-color: #ccc;
|
||||
}
|
||||
.btn-default:hover,
|
||||
.btn-default:focus {
|
||||
background-color: #e0e0e0;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-default:active,
|
||||
.btn-default.active {
|
||||
background-color: #e0e0e0;
|
||||
border-color: #dbdbdb;
|
||||
}
|
||||
.btn-default.disabled,
|
||||
.btn-default[disabled],
|
||||
fieldset[disabled] .btn-default,
|
||||
.btn-default.disabled:hover,
|
||||
.btn-default[disabled]:hover,
|
||||
fieldset[disabled] .btn-default:hover,
|
||||
.btn-default.disabled:focus,
|
||||
.btn-default[disabled]:focus,
|
||||
fieldset[disabled] .btn-default:focus,
|
||||
.btn-default.disabled.focus,
|
||||
.btn-default[disabled].focus,
|
||||
fieldset[disabled] .btn-default.focus,
|
||||
.btn-default.disabled:active,
|
||||
.btn-default[disabled]:active,
|
||||
fieldset[disabled] .btn-default:active,
|
||||
.btn-default.disabled.active,
|
||||
.btn-default[disabled].active,
|
||||
fieldset[disabled] .btn-default.active {
|
||||
background-color: #e0e0e0;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-primary {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #245580;
|
||||
}
|
||||
.btn-primary:hover,
|
||||
.btn-primary:focus {
|
||||
background-color: #265a88;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-primary:active,
|
||||
.btn-primary.active {
|
||||
background-color: #265a88;
|
||||
border-color: #245580;
|
||||
}
|
||||
.btn-primary.disabled,
|
||||
.btn-primary[disabled],
|
||||
fieldset[disabled] .btn-primary,
|
||||
.btn-primary.disabled:hover,
|
||||
.btn-primary[disabled]:hover,
|
||||
fieldset[disabled] .btn-primary:hover,
|
||||
.btn-primary.disabled:focus,
|
||||
.btn-primary[disabled]:focus,
|
||||
fieldset[disabled] .btn-primary:focus,
|
||||
.btn-primary.disabled.focus,
|
||||
.btn-primary[disabled].focus,
|
||||
fieldset[disabled] .btn-primary.focus,
|
||||
.btn-primary.disabled:active,
|
||||
.btn-primary[disabled]:active,
|
||||
fieldset[disabled] .btn-primary:active,
|
||||
.btn-primary.disabled.active,
|
||||
.btn-primary[disabled].active,
|
||||
fieldset[disabled] .btn-primary.active {
|
||||
background-color: #265a88;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-success {
|
||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
|
||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #3e8f3e;
|
||||
}
|
||||
.btn-success:hover,
|
||||
.btn-success:focus {
|
||||
background-color: #419641;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-success:active,
|
||||
.btn-success.active {
|
||||
background-color: #419641;
|
||||
border-color: #3e8f3e;
|
||||
}
|
||||
.btn-success.disabled,
|
||||
.btn-success[disabled],
|
||||
fieldset[disabled] .btn-success,
|
||||
.btn-success.disabled:hover,
|
||||
.btn-success[disabled]:hover,
|
||||
fieldset[disabled] .btn-success:hover,
|
||||
.btn-success.disabled:focus,
|
||||
.btn-success[disabled]:focus,
|
||||
fieldset[disabled] .btn-success:focus,
|
||||
.btn-success.disabled.focus,
|
||||
.btn-success[disabled].focus,
|
||||
fieldset[disabled] .btn-success.focus,
|
||||
.btn-success.disabled:active,
|
||||
.btn-success[disabled]:active,
|
||||
fieldset[disabled] .btn-success:active,
|
||||
.btn-success.disabled.active,
|
||||
.btn-success[disabled].active,
|
||||
fieldset[disabled] .btn-success.active {
|
||||
background-color: #419641;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-info {
|
||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
|
||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #28a4c9;
|
||||
}
|
||||
.btn-info:hover,
|
||||
.btn-info:focus {
|
||||
background-color: #2aabd2;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-info:active,
|
||||
.btn-info.active {
|
||||
background-color: #2aabd2;
|
||||
border-color: #28a4c9;
|
||||
}
|
||||
.btn-info.disabled,
|
||||
.btn-info[disabled],
|
||||
fieldset[disabled] .btn-info,
|
||||
.btn-info.disabled:hover,
|
||||
.btn-info[disabled]:hover,
|
||||
fieldset[disabled] .btn-info:hover,
|
||||
.btn-info.disabled:focus,
|
||||
.btn-info[disabled]:focus,
|
||||
fieldset[disabled] .btn-info:focus,
|
||||
.btn-info.disabled.focus,
|
||||
.btn-info[disabled].focus,
|
||||
fieldset[disabled] .btn-info.focus,
|
||||
.btn-info.disabled:active,
|
||||
.btn-info[disabled]:active,
|
||||
fieldset[disabled] .btn-info:active,
|
||||
.btn-info.disabled.active,
|
||||
.btn-info[disabled].active,
|
||||
fieldset[disabled] .btn-info.active {
|
||||
background-color: #2aabd2;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-warning {
|
||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
|
||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #e38d13;
|
||||
}
|
||||
.btn-warning:hover,
|
||||
.btn-warning:focus {
|
||||
background-color: #eb9316;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-warning:active,
|
||||
.btn-warning.active {
|
||||
background-color: #eb9316;
|
||||
border-color: #e38d13;
|
||||
}
|
||||
.btn-warning.disabled,
|
||||
.btn-warning[disabled],
|
||||
fieldset[disabled] .btn-warning,
|
||||
.btn-warning.disabled:hover,
|
||||
.btn-warning[disabled]:hover,
|
||||
fieldset[disabled] .btn-warning:hover,
|
||||
.btn-warning.disabled:focus,
|
||||
.btn-warning[disabled]:focus,
|
||||
fieldset[disabled] .btn-warning:focus,
|
||||
.btn-warning.disabled.focus,
|
||||
.btn-warning[disabled].focus,
|
||||
fieldset[disabled] .btn-warning.focus,
|
||||
.btn-warning.disabled:active,
|
||||
.btn-warning[disabled]:active,
|
||||
fieldset[disabled] .btn-warning:active,
|
||||
.btn-warning.disabled.active,
|
||||
.btn-warning[disabled].active,
|
||||
fieldset[disabled] .btn-warning.active {
|
||||
background-color: #eb9316;
|
||||
background-image: none;
|
||||
}
|
||||
.btn-danger {
|
||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
|
||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #b92c28;
|
||||
}
|
||||
.btn-danger:hover,
|
||||
.btn-danger:focus {
|
||||
background-color: #c12e2a;
|
||||
background-position: 0 -15px;
|
||||
}
|
||||
.btn-danger:active,
|
||||
.btn-danger.active {
|
||||
background-color: #c12e2a;
|
||||
border-color: #b92c28;
|
||||
}
|
||||
.btn-danger.disabled,
|
||||
.btn-danger[disabled],
|
||||
fieldset[disabled] .btn-danger,
|
||||
.btn-danger.disabled:hover,
|
||||
.btn-danger[disabled]:hover,
|
||||
fieldset[disabled] .btn-danger:hover,
|
||||
.btn-danger.disabled:focus,
|
||||
.btn-danger[disabled]:focus,
|
||||
fieldset[disabled] .btn-danger:focus,
|
||||
.btn-danger.disabled.focus,
|
||||
.btn-danger[disabled].focus,
|
||||
fieldset[disabled] .btn-danger.focus,
|
||||
.btn-danger.disabled:active,
|
||||
.btn-danger[disabled]:active,
|
||||
fieldset[disabled] .btn-danger:active,
|
||||
.btn-danger.disabled.active,
|
||||
.btn-danger[disabled].active,
|
||||
fieldset[disabled] .btn-danger.active {
|
||||
background-color: #c12e2a;
|
||||
background-image: none;
|
||||
}
|
||||
.thumbnail,
|
||||
.img-thumbnail {
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.dropdown-menu > li > a:hover,
|
||||
.dropdown-menu > li > a:focus {
|
||||
background-color: #e8e8e8;
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.dropdown-menu > .active > a,
|
||||
.dropdown-menu > .active > a:hover,
|
||||
.dropdown-menu > .active > a:focus {
|
||||
background-color: #2e6da4;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.navbar-default {
|
||||
background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
||||
background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));
|
||||
background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.navbar-default .navbar-nav > .open > a,
|
||||
.navbar-default .navbar-nav > .active > a {
|
||||
background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
|
||||
background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
|
||||
background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.navbar-brand,
|
||||
.navbar-nav > li > a {
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
|
||||
}
|
||||
.navbar-inverse {
|
||||
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
||||
background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
|
||||
background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
background-repeat: repeat-x;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.navbar-inverse .navbar-nav > .open > a,
|
||||
.navbar-inverse .navbar-nav > .active > a {
|
||||
background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
|
||||
background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
|
||||
background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
|
||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
|
||||
}
|
||||
.navbar-inverse .navbar-brand,
|
||||
.navbar-inverse .navbar-nav > li > a {
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
|
||||
}
|
||||
.navbar-static-top,
|
||||
.navbar-fixed-top,
|
||||
.navbar-fixed-bottom {
|
||||
border-radius: 0;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a,
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
|
||||
color: #fff;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
}
|
||||
.alert {
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
|
||||
}
|
||||
.alert-success {
|
||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
|
||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #b2dba1;
|
||||
}
|
||||
.alert-info {
|
||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
|
||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #9acfea;
|
||||
}
|
||||
.alert-warning {
|
||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
|
||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #f5e79e;
|
||||
}
|
||||
.alert-danger {
|
||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
||||
background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
|
||||
background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dca7a7;
|
||||
}
|
||||
.progress {
|
||||
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
||||
background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
|
||||
background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-success {
|
||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
|
||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-info {
|
||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
|
||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-warning {
|
||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
|
||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-danger {
|
||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
|
||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.progress-bar-striped {
|
||||
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
|
||||
}
|
||||
.list-group {
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
|
||||
}
|
||||
.list-group-item.active,
|
||||
.list-group-item.active:hover,
|
||||
.list-group-item.active:focus {
|
||||
text-shadow: 0 -1px 0 #286090;
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #2b669a;
|
||||
}
|
||||
.list-group-item.active .badge,
|
||||
.list-group-item.active:hover .badge,
|
||||
.list-group-item.active:focus .badge {
|
||||
text-shadow: none;
|
||||
}
|
||||
.panel {
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
||||
}
|
||||
.panel-default > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
|
||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-primary > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-success > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
|
||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-info > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
|
||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-warning > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
|
||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.panel-danger > .panel-heading {
|
||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
||||
background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
|
||||
background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
.well {
|
||||
background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
||||
background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
|
||||
background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
|
||||
background-repeat: repeat-x;
|
||||
border-color: #dcdcdc;
|
||||
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-theme.css.map */
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,5 +0,0 @@
|
||||
repo: 076b192d0d8ab2b92d1dbcfa3da055382f30eaea
|
||||
node: 7ee0bc7b4e9138f485cdc9ec791961d8ef452f17
|
||||
branch: default
|
||||
latesttag: 0.7
|
||||
latesttagdistance: 11
|
||||
@@ -1,89 +0,0 @@
|
||||
.openerp .oe_export {
|
||||
width: 100%;
|
||||
}
|
||||
/* Customize according bootstrap3 */
|
||||
.openerp .oe_export label {
|
||||
font-weight: normal;
|
||||
}
|
||||
/* End of customize */
|
||||
.openerp .oe_export_row tr{
|
||||
background-color: #FFFFFF;
|
||||
font-size: 0.8em;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.openerp tr.ui-selected td {
|
||||
background-color: #CCCCCC;
|
||||
}
|
||||
|
||||
.openerp .oe_export_requiredfield {
|
||||
background-color: #D2D2FF;
|
||||
}
|
||||
|
||||
.openerp .oe_export_readonlyfield{
|
||||
background-color: #999999;
|
||||
}
|
||||
|
||||
.openerp .oe_export_row:hover{
|
||||
background-color: #F3F3F3;
|
||||
}
|
||||
|
||||
.openerp .oe_export_fields_selector_left {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.openerp div#left_field_panel {
|
||||
overflow: scroll;
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
border: solid #999999 1px;
|
||||
}
|
||||
.openerp div#left_field_panel table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.openerp .oe_export_fields_selector_center {
|
||||
text-align: center;
|
||||
}
|
||||
.openerp .oe_export_fields_selector_center button {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.openerp .oe_export_fields_selector_right {
|
||||
width: 45%;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.openerp .oe_export_fields_selector_right select{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.openerp .oe_export_tree_header{
|
||||
border: 0.5px solid #E3E3E3;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
padding: 4px 5px;
|
||||
background: url(/web/static/src/img/header.gif);
|
||||
}
|
||||
|
||||
|
||||
.openerp table.tree_grid{
|
||||
border: 1px solid #E3E3E3;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
background-color:#E3E3E3;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.openerp table.tree_grid a:hover {
|
||||
color: blue;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.openerp table.tree_grid a {
|
||||
color: #5F5C5C;
|
||||
border: none;
|
||||
display: block;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
/* This css contains the styling specific to the 'normal mode'. (as opposite to the embedded mode) */
|
||||
/* In embedded mode [1], this stylesheet won't be loaded. */
|
||||
|
||||
/* [1] The web client features an embedded mode in which the webclient */
|
||||
/* or a part of it can be started in any element of any webpage host. */
|
||||
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow-y: scroll;
|
||||
height: 100%;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/** base */
|
||||
.openerp .oe_form label + .oe_form_field.oe_form_field_one2many {
|
||||
display: block;
|
||||
}
|
||||
.openerp .oe_leftbar > div > div > div > div.oe_secondary_menus_container {
|
||||
position: static;
|
||||
}
|
||||
.openerp .oe_application > div > .oe_view_manager > .oe_view_manager_wrapper > div > .oe_view_manager_body {
|
||||
position: static;
|
||||
}
|
||||
|
||||
/** web_calendar */
|
||||
.fc .ui-draggable-dragging .fc-event-bg, /* TODO: something nicer like .fc-opacity */
|
||||
.fc-select-helper .fc-event-bg {
|
||||
display: none; /* for IE6/7/8. nested opacity filters while dragging don't work */
|
||||
}
|
||||
|
||||
/** web_graph */
|
||||
.openerp svg:not(:root) { /* width and height are not take in consideration */
|
||||
overflow: visible;
|
||||
}
|
||||
.graph_main_content.graph_chart_mode > div > svg {
|
||||
min-height: 521px;
|
||||
}
|
||||
|
||||
/** web_kanban */
|
||||
.openerp .oe_kanban_column_cards {
|
||||
min-height: 80px;
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 125 B |
@@ -0,0 +1,245 @@
|
||||
odoo.define('web.AbstractWebClient', function (require) {
|
||||
"use strict";
|
||||
|
||||
var ActionManager = require('web.ActionManager');
|
||||
var core = require('web.core');
|
||||
var crash_manager = require('web.crash_manager');
|
||||
var Loading = require('web.Loading');
|
||||
var NotificationManager = require('web.notification').NotificationManager;
|
||||
var session = require('web.session');
|
||||
var utils = require('web.utils');
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
var _t = core._t;
|
||||
|
||||
var WebClient = Widget.extend({
|
||||
custom_events: {
|
||||
notification: function (e) {
|
||||
if(this.notification_manager) {
|
||||
this.notification_manager.notify(e.data.title, e.data.message, e.data.sticky);
|
||||
}
|
||||
},
|
||||
warning: function (e) {
|
||||
if(this.notification_manager) {
|
||||
this.notification_manager.warn(e.data.title, e.data.message, e.data.sticky);
|
||||
}
|
||||
},
|
||||
clear_uncommitted_changes: function (e) {
|
||||
this.clear_uncommitted_changes().then(e.data.callback);
|
||||
},
|
||||
},
|
||||
init: function(parent, client_options) {
|
||||
this.client_options = {};
|
||||
this._super(parent);
|
||||
this.origin = undefined;
|
||||
if (client_options) {
|
||||
_.extend(this.client_options, client_options);
|
||||
}
|
||||
this._current_state = null;
|
||||
this.menu_dm = new utils.DropMisordered();
|
||||
this.action_mutex = new utils.Mutex();
|
||||
this.set('title_part', {"zopenerp": "Odoo"});
|
||||
},
|
||||
start: function() {
|
||||
var self = this;
|
||||
|
||||
this.on("change:title_part", this, this._title_changed);
|
||||
this._title_changed();
|
||||
|
||||
return session.session_bind(this.origin)
|
||||
.then(function () {
|
||||
self.bind_events();
|
||||
return $.when(
|
||||
self.set_action_manager(),
|
||||
self.set_notification_manager(),
|
||||
self.set_loading()
|
||||
);
|
||||
}).then(function () {
|
||||
if (session.session_is_valid()) {
|
||||
return self.show_application();
|
||||
} else {
|
||||
// database manager needs the webclient to keep going even
|
||||
// though it has no valid session
|
||||
return $.when();
|
||||
}
|
||||
}).then(function () {
|
||||
if (self.client_options.action) {
|
||||
self.do_action(self.client_options.action);
|
||||
delete(self.client_options.action);
|
||||
}
|
||||
core.bus.trigger('web_client_ready');
|
||||
});
|
||||
},
|
||||
bind_events: function() {
|
||||
var self = this;
|
||||
$('.oe_systray').show();
|
||||
this.$el.on('mouseenter', '.oe_systray > div:not([data-toggle=tooltip])', function() {
|
||||
$(this).attr('data-toggle', 'tooltip').tooltip().trigger('mouseenter');
|
||||
});
|
||||
this.$el.on('click', '.oe_dropdown_toggle', function(ev) {
|
||||
ev.preventDefault();
|
||||
var $toggle = $(this);
|
||||
var doc_width = $(document).width();
|
||||
var $menu = $toggle.siblings('.oe_dropdown_menu');
|
||||
$menu = $menu.size() >= 1 ? $menu : $toggle.find('.oe_dropdown_menu');
|
||||
var state = $menu.is('.oe_opened');
|
||||
setTimeout(function() {
|
||||
// Do not alter propagation
|
||||
$toggle.add($menu).toggleClass('oe_opened', !state);
|
||||
if (!state) {
|
||||
// Move $menu if outside window's edge
|
||||
var offset = $menu.offset();
|
||||
var menu_width = $menu.width();
|
||||
var x = doc_width - offset.left - menu_width - 2;
|
||||
if (x < 0) {
|
||||
$menu.offset({ left: offset.left + x }).width(menu_width);
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
core.bus.on('click', this, function(ev) {
|
||||
$('.tooltip').remove();
|
||||
if (!$(ev.target).is('input[type=file]')) {
|
||||
self.$('.oe_dropdown_menu.oe_opened, .oe_dropdown_toggle.oe_opened').removeClass('oe_opened');
|
||||
}
|
||||
});
|
||||
core.bus.on('set_full_screen', this, function (full_screen) {
|
||||
this.set_content_full_screen(full_screen);
|
||||
});
|
||||
core.bus.on('connection_lost', this, this.on_connection_lost);
|
||||
core.bus.on('connection_restored', this, this.on_connection_restored);
|
||||
|
||||
// crash manager integration
|
||||
session.on('error', crash_manager, crash_manager.rpc_error);
|
||||
window.onerror = function (message, file, line, col, error) {
|
||||
var traceback = error ? error.stack : '';
|
||||
crash_manager.show_error({
|
||||
type: _t("Client Error"),
|
||||
message: message,
|
||||
data: {debug: file + ':' + line + "\n" + _t('Traceback:') + "\n" + traceback}
|
||||
});
|
||||
};
|
||||
},
|
||||
set_action_manager: function() {
|
||||
this.action_manager = new ActionManager(this, {webclient: this});
|
||||
return this.action_manager.appendTo(this.$('.o_main_content'));
|
||||
},
|
||||
set_notification_manager: function() {
|
||||
this.notification_manager = new NotificationManager(this);
|
||||
return this.notification_manager.appendTo(this.$el);
|
||||
},
|
||||
set_loading: function() {
|
||||
this.loading = new Loading(this);
|
||||
return this.loading.appendTo(this.$el);
|
||||
},
|
||||
show_application: function() {
|
||||
},
|
||||
clear_uncommitted_changes: function() {
|
||||
var def = $.Deferred().resolve();
|
||||
core.bus.trigger('clear_uncommitted_changes', function chain_callbacks(callback) {
|
||||
def = def.then(callback);
|
||||
});
|
||||
return def;
|
||||
},
|
||||
destroy_content: function() {
|
||||
_.each(_.clone(this.getChildren()), function(el) {
|
||||
el.destroy();
|
||||
});
|
||||
this.$el.children().remove();
|
||||
},
|
||||
// --------------------------------------------------------------
|
||||
// Window title handling
|
||||
// --------------------------------------------------------------
|
||||
/**
|
||||
Sets the first part of the title of the window, dedicated to the current action.
|
||||
*/
|
||||
set_title: function(title) {
|
||||
this.set_title_part("action", title);
|
||||
},
|
||||
/**
|
||||
Sets an arbitrary part of the title of the window. Title parts are identified by strings. Each time
|
||||
a title part is changed, all parts are gathered, ordered by alphabetical order and displayed in the
|
||||
title of the window separated by '-'.
|
||||
*/
|
||||
set_title_part: function(part, title) {
|
||||
var tmp = _.clone(this.get("title_part"));
|
||||
tmp[part] = title;
|
||||
this.set("title_part", tmp);
|
||||
},
|
||||
_title_changed: function() {
|
||||
var parts = _.sortBy(_.keys(this.get("title_part")), function(x) { return x; });
|
||||
var tmp = "";
|
||||
_.each(parts, function(part) {
|
||||
var str = this.get("title_part")[part];
|
||||
if (str) {
|
||||
tmp = tmp ? tmp + " - " + str : str;
|
||||
}
|
||||
}, this);
|
||||
document.title = tmp;
|
||||
},
|
||||
// --------------------------------------------------------------
|
||||
// do_*
|
||||
// --------------------------------------------------------------
|
||||
/**
|
||||
* When do_action is performed on the WebClient, forward it to the main ActionManager
|
||||
* This allows to widgets that are not inside the ActionManager to perform do_action
|
||||
*/
|
||||
do_action: function() {
|
||||
return this.action_manager.do_action.apply(this, arguments);
|
||||
},
|
||||
do_reload: function() {
|
||||
var self = this;
|
||||
return this.session.session_reload().then(function () {
|
||||
session.load_modules(true).then(
|
||||
self.menu.proxy('do_reload'));
|
||||
});
|
||||
},
|
||||
do_push_state: function(state) {
|
||||
if ('title' in state) {
|
||||
this.set_title(state.title);
|
||||
delete state.title;
|
||||
}
|
||||
var url = '#' + $.param(state);
|
||||
this._current_state = $.deparam($.param(state), false); // stringify all values
|
||||
$.bbq.pushState(url);
|
||||
this.trigger('state_pushed', state);
|
||||
},
|
||||
// --------------------------------------------------------------
|
||||
// Connection notifications
|
||||
// --------------------------------------------------------------
|
||||
on_connection_lost: function () {
|
||||
this.connection_notification = this.notification_manager.notify(
|
||||
_t('Connection lost'),
|
||||
_t('Trying to reconnect...'),
|
||||
true
|
||||
);
|
||||
},
|
||||
on_connection_restored: function () {
|
||||
if (this.connection_notification) {
|
||||
this.connection_notification.destroy();
|
||||
this.notification_manager.notify(
|
||||
_t('Connection restored'),
|
||||
_t('You are back online'),
|
||||
false
|
||||
);
|
||||
this.connection_notification = false;
|
||||
}
|
||||
},
|
||||
// --------------------------------------------------------------
|
||||
// Scrolltop handling
|
||||
// --------------------------------------------------------------
|
||||
get_scrollTop: function () {
|
||||
},
|
||||
//--------------------------------------------------------------
|
||||
// Misc.
|
||||
//--------------------------------------------------------------
|
||||
set_content_full_screen: function(fullscreen) {
|
||||
$(document.body).css('overflow-y', fullscreen ? 'hidden' : 'scroll');
|
||||
this.$('.oe_webclient').toggleClass(
|
||||
'oe_content_full_screen', fullscreen);
|
||||
},
|
||||
});
|
||||
|
||||
return WebClient;
|
||||
|
||||
});
|
||||
@@ -22,25 +22,18 @@ var Action = core.Class.extend({
|
||||
this.action_descr = action;
|
||||
this.title = action.display_name || action.name;
|
||||
},
|
||||
/**
|
||||
* Not implemented for client actions
|
||||
* @return {Deferred} a rejected Deferred
|
||||
*/
|
||||
appendTo: function() {
|
||||
return $.Deferred().reject();
|
||||
},
|
||||
/**
|
||||
* This method should restore this previously loaded action
|
||||
* Calls on_reverse_breadcrumb callback if defined
|
||||
* Calls on_reverse_breadcrumb_callback if defined
|
||||
* @return {Deferred} resolved when widget is enabled
|
||||
*/
|
||||
restore: function() {
|
||||
if (this.on_reverse_breadcrumb) {
|
||||
return this.on_reverse_breadcrumb();
|
||||
if (this.on_reverse_breadcrumb_callback) {
|
||||
return this.on_reverse_breadcrumb_callback();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Not implemented for functions
|
||||
* There is nothing to detach in the case of a client function
|
||||
*/
|
||||
detach: function() {
|
||||
},
|
||||
@@ -50,11 +43,16 @@ var Action = core.Class.extend({
|
||||
destroy: function() {
|
||||
},
|
||||
/**
|
||||
* Sets the on_reverse_breadcrumb callback to be called when coming back to that action
|
||||
* @param {Function} [on_reverse_breadcrumb] the callback
|
||||
* Sets the on_reverse_breadcrumb_callback to be called when coming back to that action
|
||||
* @param {Function} [callback] the callback
|
||||
*/
|
||||
set_on_reverse_breadcrumb: function(on_reverse_breadcrumb) {
|
||||
this.on_reverse_breadcrumb = on_reverse_breadcrumb;
|
||||
set_on_reverse_breadcrumb: function(callback) {
|
||||
this.on_reverse_breadcrumb_callback = callback;
|
||||
},
|
||||
/**
|
||||
* Not implemented for client actions
|
||||
*/
|
||||
set_scrollTop: function() {
|
||||
},
|
||||
/**
|
||||
* Stores the DOM fragment of the action
|
||||
@@ -65,8 +63,10 @@ var Action = core.Class.extend({
|
||||
},
|
||||
/**
|
||||
* Not implemented for client actions
|
||||
* @return {int} the number of pixels the webclient is scrolled when leaving the action
|
||||
*/
|
||||
set_is_in_DOM: function() {
|
||||
get_scrollTop: function() {
|
||||
return 0;
|
||||
},
|
||||
/**
|
||||
* @return {Object} the description of the action
|
||||
@@ -112,16 +112,6 @@ var WidgetAction = Action.extend({
|
||||
this.title = widget.get('title');
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Wraps the action's widget in a container and appends it to el
|
||||
* @param {DocumentFragment} [el] where to append the widget
|
||||
* @return {Deferred} resolved when the widget is appended
|
||||
*/
|
||||
appendTo: function(el) {
|
||||
this.$client_action_container = $('<div>').addClass('oe_client_action');
|
||||
this.$client_action_container.appendTo(el);
|
||||
return this.widget.appendTo(this.$client_action_container);
|
||||
},
|
||||
/**
|
||||
* Restores WidgetAction by calling do_show on its widget
|
||||
*/
|
||||
@@ -132,32 +122,26 @@ var WidgetAction = Action.extend({
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Detaches the client action's container from the DOM
|
||||
* @return {jQuery} the action's container
|
||||
* Detaches the action's widget from the DOM
|
||||
* @return the widget's $el
|
||||
*/
|
||||
detach: function() {
|
||||
return this.$client_action_container.detach();
|
||||
// Hack to remove badly inserted nvd3 tooltips ; should be removed when upgrading nvd3 lib
|
||||
$('body > .nvtooltip').remove();
|
||||
|
||||
return framework.detach([{widget: this.widget}]);
|
||||
},
|
||||
/**
|
||||
* Destroys the widget
|
||||
*/
|
||||
destroy: function() {
|
||||
this.widget.destroy();
|
||||
this.detach();
|
||||
},
|
||||
});
|
||||
/**
|
||||
* Specialization of WidgetAction for window actions (i.e. ViewManagers)
|
||||
*/
|
||||
var ViewManagerAction = WidgetAction.extend({
|
||||
/**
|
||||
* Appends the action's widget to el
|
||||
* @param {DocumentFragment} [el] where to append the widget
|
||||
* @return {Deferred} resolved when the widget is appended
|
||||
*/
|
||||
appendTo: function(el) {
|
||||
return this.widget.appendTo(el);
|
||||
},
|
||||
/**
|
||||
* Restores a ViewManagerAction
|
||||
* Switches to the requested view by calling select_view on the ViewManager
|
||||
@@ -170,27 +154,27 @@ var ViewManagerAction = WidgetAction.extend({
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Sets is_in_DOM on this.widget
|
||||
* @param {Boolean} [is_in_DOM] true iff the widget is attached in the DOM
|
||||
* Sets the on_reverse_breadcrumb_callback and the scrollTop to apply when
|
||||
* coming back to that action
|
||||
* @param {Function} [callback] the callback
|
||||
* @param {int} [scrollTop] the number of pixels to scroll
|
||||
*/
|
||||
set_is_in_DOM: function(is_in_DOM) {
|
||||
this.widget.is_in_DOM = is_in_DOM;
|
||||
set_on_reverse_breadcrumb: function(callback, scrollTop) {
|
||||
this._super(callback);
|
||||
this.set_scrollTop(scrollTop);
|
||||
},
|
||||
/**
|
||||
* Detaches the view_manager from the DOM
|
||||
* @return {jQuery} the view_manager's $el
|
||||
* Sets the scroll position of the widgets's active_view
|
||||
* @param {int} [scrollTop] the number of pixels to scroll
|
||||
*/
|
||||
detach: function() {
|
||||
// Hack to remove badly inserted nvd3 tooltips ; should be removed when upgrading nvd3 lib
|
||||
$('body > .nvtooltip').remove();
|
||||
|
||||
return this.widget.$el.detach();
|
||||
set_scrollTop: function(scrollTop) {
|
||||
this.widget.active_view.controller.set_scrollTop(scrollTop);
|
||||
},
|
||||
/**
|
||||
* Destroys the widget
|
||||
* @return {int} the number of pixels the webclient is scrolled when leaving the action
|
||||
*/
|
||||
destroy: function() {
|
||||
this.widget.destroy();
|
||||
get_scrollTop: function() {
|
||||
return this.widget.active_view.controller.get_scrollTop();
|
||||
},
|
||||
/**
|
||||
* @return {Array} array of Objects that will be interpreted to display the breadcrumbs
|
||||
@@ -214,13 +198,31 @@ var ViewManagerAction = WidgetAction.extend({
|
||||
});
|
||||
|
||||
var ActionManager = Widget.extend({
|
||||
template: "ActionManager",
|
||||
init: function(parent) {
|
||||
template: 'ActionManager',
|
||||
/**
|
||||
* Called each time the action manager is attached into the DOM
|
||||
*/
|
||||
on_attach_callback: function() {
|
||||
this.is_in_DOM = true;
|
||||
if (this.inner_widget && this.inner_widget.on_attach_callback) {
|
||||
this.inner_widget.on_attach_callback();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Called each time the action manager is detached from the DOM
|
||||
*/
|
||||
on_detach_callback: function() {
|
||||
this.is_in_DOM = false;
|
||||
if (this.inner_widget && this.inner_widget.on_detach_callback) {
|
||||
this.inner_widget.on_detach_callback();
|
||||
}
|
||||
},
|
||||
init: function(parent, options) {
|
||||
this._super(parent);
|
||||
this.action_stack = [];
|
||||
this.inner_action = null;
|
||||
this.inner_widget = null;
|
||||
this.webclient = parent;
|
||||
this.webclient = options && options.webclient;
|
||||
this.dialog = null;
|
||||
this.dialog_widget = null;
|
||||
this.on('history_back', this, this.proxy('history_back'));
|
||||
@@ -236,8 +238,15 @@ var ActionManager = Widget.extend({
|
||||
this.select_action(action, index);
|
||||
}, 200, true));
|
||||
|
||||
// Append the main control panel to the DOM (inside the ActionManager jQuery element)
|
||||
this.main_control_panel.appendTo(this.$el);
|
||||
// Listen to event "DOM_updated" to restore the scroll position
|
||||
core.bus.on('DOM_updated', this, function() {
|
||||
if (this.inner_action) {
|
||||
this.trigger_up('scrollTo', {offset: this.inner_action.get_scrollTop() || 0});
|
||||
}
|
||||
});
|
||||
|
||||
// Insert the main control panel into the DOM
|
||||
return this.main_control_panel.insertBefore(this.$el);
|
||||
},
|
||||
dialog_stop: function (reason) {
|
||||
if (this.dialog) {
|
||||
@@ -256,9 +265,9 @@ var ActionManager = Widget.extend({
|
||||
*/
|
||||
push_action: function(widget, action_descr, options) {
|
||||
var self = this;
|
||||
var old_widget = this.inner_widget;
|
||||
var old_action = this.inner_action;
|
||||
var old_action_stack = this.action_stack;
|
||||
var old_action = this.inner_action;
|
||||
var old_widget = this.inner_widget;
|
||||
options = options || {};
|
||||
|
||||
// Empty action_stack if requested
|
||||
@@ -277,8 +286,8 @@ var ActionManager = Widget.extend({
|
||||
}
|
||||
|
||||
// Set on_reverse_breadcrumb callback on previous inner_action
|
||||
if (old_action) {
|
||||
old_action.set_on_reverse_breadcrumb(options.on_reverse_breadcrumb);
|
||||
if (this.webclient && old_action) {
|
||||
old_action.set_on_reverse_breadcrumb(options.on_reverse_breadcrumb, this.webclient.get_scrollTop());
|
||||
}
|
||||
|
||||
// Update action_stack (must be done before appendTo to properly
|
||||
@@ -295,25 +304,19 @@ var ActionManager = Widget.extend({
|
||||
// render the inner_widget in a fragment, and append it to the
|
||||
// document only when it's ready
|
||||
var new_widget_fragment = document.createDocumentFragment();
|
||||
return $.when(this.inner_action.appendTo(new_widget_fragment)).done(function() {
|
||||
return $.when(this.inner_widget.appendTo(new_widget_fragment)).done(function() {
|
||||
// Detach the fragment of the previous action and store it within the action
|
||||
if (old_action) {
|
||||
old_action.set_fragment(old_action.detach());
|
||||
old_action.set_is_in_DOM(false);
|
||||
}
|
||||
if (!widget.need_control_panel) {
|
||||
// Hide the main ControlPanel for widgets that do not use it
|
||||
self.main_control_panel.do_hide();
|
||||
}
|
||||
|
||||
framework.append(self.$el, new_widget_fragment, true);
|
||||
self.inner_action.set_is_in_DOM(true);
|
||||
|
||||
// Hide the old_widget as it will be removed from the DOM when it
|
||||
// is destroyed
|
||||
if (old_widget) {
|
||||
old_widget.do_hide();
|
||||
}
|
||||
framework.append(self.$el, new_widget_fragment, {
|
||||
in_DOM: self.is_in_DOM,
|
||||
callbacks: [{widget: self.inner_widget}],
|
||||
});
|
||||
if (options.clear_breadcrumbs) {
|
||||
self.clear_action_stack(old_action_stack);
|
||||
}
|
||||
@@ -325,6 +328,11 @@ var ActionManager = Widget.extend({
|
||||
self.inner_widget = old_widget;
|
||||
});
|
||||
},
|
||||
set_scrollTop: function(scrollTop) {
|
||||
if (this.inner_action) {
|
||||
this.inner_action.set_scrollTop(scrollTop);
|
||||
}
|
||||
},
|
||||
get_breadcrumbs: function () {
|
||||
return _.flatten(_.map(this.action_stack, function (action) {
|
||||
return action.get_breadcrumbs();
|
||||
@@ -368,7 +376,9 @@ var ActionManager = Widget.extend({
|
||||
},
|
||||
select_action: function(action, index) {
|
||||
var self = this;
|
||||
return this.webclient.clear_uncommitted_changes().then(function() {
|
||||
var def = this.webclient && this.webclient.clear_uncommitted_changes() || $.when();
|
||||
|
||||
return def.then(function() {
|
||||
// Set the new inner_action/widget and update the action stack
|
||||
var old_action = self.inner_action;
|
||||
var action_index = self.action_stack.indexOf(action);
|
||||
@@ -376,19 +386,21 @@ var ActionManager = Widget.extend({
|
||||
self.inner_action = action;
|
||||
self.inner_widget = action.widget;
|
||||
|
||||
// Hide the ControlPanel if the widget doesn't use it
|
||||
if (!self.inner_widget.need_control_panel) {
|
||||
self.main_control_panel.do_hide();
|
||||
}
|
||||
|
||||
return $.when(action.restore(index)).done(function() {
|
||||
// Hide the ControlPanel if the widget doesn't use it
|
||||
if (!self.inner_widget.need_control_panel) {
|
||||
self.main_control_panel.do_hide();
|
||||
}
|
||||
// Attach the DOM of the action and restore the scroll position only if necessary
|
||||
if (action !== old_action) {
|
||||
// Clear the action stack (this also removes the current action from the DOM)
|
||||
self.clear_action_stack(to_destroy);
|
||||
|
||||
// Append the fragment of the action to restore to self.$el
|
||||
framework.append(self.$el, action.get_fragment(), true);
|
||||
self.inner_action.set_is_in_DOM(true);
|
||||
framework.append(self.$el, action.get_fragment(), {
|
||||
in_DOM: self.is_in_DOM,
|
||||
callbacks: [{widget: action.widget}],
|
||||
});
|
||||
}
|
||||
});
|
||||
}).fail(function() {
|
||||
@@ -406,7 +418,7 @@ var ActionManager = Widget.extend({
|
||||
}
|
||||
},
|
||||
do_push_state: function(state) {
|
||||
if (!this.webclient || !this.webclient.do_push_state || this.dialog) {
|
||||
if (!this.webclient || this.dialog) {
|
||||
return;
|
||||
}
|
||||
state = state || {};
|
||||
@@ -491,13 +503,6 @@ var ActionManager = Widget.extend({
|
||||
res_id: state.id,
|
||||
view_type: state.view_type,
|
||||
});
|
||||
$.when(action_loaded || null).done(function() {
|
||||
self.webclient.menu.is_bound.done(function() {
|
||||
if (self.inner_action && self.inner_action.get_action_descr().id) {
|
||||
self.webclient.menu.open_action(self.inner_action.get_action_descr().id);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (state.model && state.id) {
|
||||
@@ -524,9 +529,9 @@ var ActionManager = Widget.extend({
|
||||
});
|
||||
}
|
||||
|
||||
$.when(action_loaded || null).done(function() {
|
||||
return $.when(action_loaded || null).done(function() {
|
||||
if (self.inner_widget && self.inner_widget.do_load_state) {
|
||||
self.inner_widget.do_load_state(state, warm);
|
||||
return self.inner_widget.do_load_state(state, warm);
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -628,7 +633,9 @@ var ActionManager = Widget.extend({
|
||||
});
|
||||
}
|
||||
|
||||
return this[type](action, options);
|
||||
return $.when(this[type](action, options)).then(function() {
|
||||
return action;
|
||||
});
|
||||
},
|
||||
null_action: function() {
|
||||
this.dialog_stop();
|
||||
@@ -645,6 +652,7 @@ var ActionManager = Widget.extend({
|
||||
* @return {*}
|
||||
*/
|
||||
ir_actions_common: function(executor, options) {
|
||||
var self = this;
|
||||
if (executor.action.target === 'new') {
|
||||
var pre_dialog = (this.dialog && !this.dialog.isDestroyed()) ? this.dialog : null;
|
||||
if (pre_dialog){
|
||||
@@ -693,13 +701,16 @@ var ActionManager = Widget.extend({
|
||||
this.dialog_widget.set_cp_bus(new core.Bus());
|
||||
}
|
||||
this.dialog_widget.setParent(this.dialog);
|
||||
this.dialog.open();
|
||||
|
||||
return this.dialog_widget.appendTo(this.dialog.$el);
|
||||
|
||||
var fragment = document.createDocumentFragment();
|
||||
return this.dialog_widget.appendTo(fragment).then(function() {
|
||||
self.dialog.open().$el.append(fragment);
|
||||
if(options.state && self.dialog_widget.do_load_state) {
|
||||
return self.dialog_widget.do_load_state(options.state);
|
||||
}
|
||||
}).then(function () { return executor.action; });
|
||||
}
|
||||
// Clear uncommitted changes on the current inner widget if there is one
|
||||
var self = this;
|
||||
var def = (this.inner_widget && this.webclient.clear_uncommitted_changes()) || $.when();
|
||||
var def = this.inner_action && this.webclient && this.webclient.clear_uncommitted_changes() || $.when();
|
||||
return def.then(function() {
|
||||
self.dialog_stop(executor.action);
|
||||
return self.push_action(executor.widget(), executor.action, options);
|
||||
@@ -764,11 +775,11 @@ var ActionManager = Widget.extend({
|
||||
},
|
||||
ir_actions_server: function (action, options) {
|
||||
var self = this;
|
||||
this.rpc('/web/action/run', {
|
||||
return this.rpc('/web/action/run', {
|
||||
action_id: action.id,
|
||||
context: action.context || {}
|
||||
}).done(function (action) {
|
||||
self.do_action(action, options);
|
||||
}).then(function (action) {
|
||||
return self.do_action(action, options);
|
||||
});
|
||||
},
|
||||
ir_actions_report_xml: function(action, options) {
|
||||
@@ -818,6 +829,7 @@ var ActionManager = Widget.extend({
|
||||
|
||||
if (action.target === 'self') {
|
||||
framework.redirect(url);
|
||||
return $.Deferred(); // The action is finished only when the redirection is done
|
||||
} else {
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
odoo.define('base.apps', function (require) {
|
||||
odoo.define('web.Apps', function (require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
@@ -9,10 +9,9 @@ var web_client = require('web.web_client');
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
var _t = core._t;
|
||||
var qweb = core.qweb;
|
||||
|
||||
var apps_client = null;
|
||||
|
||||
var qweb = core.qweb;
|
||||
|
||||
var Apps = Widget.extend({
|
||||
template: 'EmptyComponent',
|
||||
@@ -106,92 +105,98 @@ var Apps = Widget.extend({
|
||||
}
|
||||
},
|
||||
|
||||
_on_update_count: function(m) {
|
||||
var self = this;
|
||||
var count = m.count;
|
||||
var get_upd_menu_id = function() {
|
||||
if (_.isUndefined(self._upd_menu_id)) {
|
||||
var IMD = new Model('ir.model.data');
|
||||
return IMD.call('get_object_reference', ['base', 'menu_module_updates']).then(function(r) {
|
||||
var mid = r[1];
|
||||
if(r[0] !== 'ir.ui.menu') {
|
||||
// invalid reference, return null
|
||||
mid = null;
|
||||
}
|
||||
self._upd_menu_id = mid;
|
||||
return mid;
|
||||
});
|
||||
} else {
|
||||
return $.Deferred().resolve(self._upd_menu_id).promise();
|
||||
}
|
||||
};
|
||||
|
||||
$.when(get_upd_menu_id()).done(function(menu_id) {
|
||||
if (_.isNull(menu_id)) {
|
||||
return;
|
||||
}
|
||||
var $menu = web_client.menu.$secondary_menus.find(_.str.sprintf('a[data-menu=%s]', menu_id));
|
||||
if ($menu.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (_.isUndefined(count)) {
|
||||
count = 0;
|
||||
}
|
||||
var needupdate = $menu.find('#menu_counter');
|
||||
if (needupdate && needupdate.length !== 0) {
|
||||
if (count > 0) {
|
||||
needupdate.text(count);
|
||||
} else {
|
||||
needupdate.remove();
|
||||
}
|
||||
} else if (count > 0) {
|
||||
$menu.append(qweb.render("Menu.needaction_counter", {widget: {needaction_counter: count}}));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
start: function() {
|
||||
var self = this;
|
||||
return self.get_client().
|
||||
done(function(client) {
|
||||
self.client = client;
|
||||
var def = $.Deferred();
|
||||
self.get_client().then(function(client) {
|
||||
self.client = client;
|
||||
|
||||
var qs = (session.debug ? 'debug&' : '') + 'db=' + client.dbname;
|
||||
var u = client.origin + '/apps/embed/client?' + qs;
|
||||
var css = {width: '100%', height: '400px'};
|
||||
self.$ifr = $('<iframe>').attr('src', u);
|
||||
var qs = (session.debug ? 'debug&' : '') + 'db=' + client.dbname;
|
||||
var u = client.origin + '/apps/embed/client?' + qs;
|
||||
var css = {width: '100%', height: '400px'};
|
||||
self.$ifr = $('<iframe>').attr('src', u);
|
||||
|
||||
$(window).on("message.apps", self.proxy('_on_message'));
|
||||
$(window).on("message.apps", self.proxy('_on_message'));
|
||||
|
||||
self.on('message:ready', self, function(m) {
|
||||
var w = this.$ifr[0].contentWindow;
|
||||
var act = {
|
||||
type: 'ir.actions.client',
|
||||
tag: this.remote_action_tag,
|
||||
params: _.extend({}, this.params, {
|
||||
db: this.session.db,
|
||||
origin: this.session.origin,
|
||||
})
|
||||
};
|
||||
w.postMessage({type:'action', action: act}, client.origin);
|
||||
});
|
||||
|
||||
self.on('message:set_height', self, function(m) {
|
||||
this.$ifr.height(m.height);
|
||||
});
|
||||
|
||||
self.on('message:update_count', self, function(m) {
|
||||
var count = m.count;
|
||||
var get_upd_menu_id = function() {
|
||||
if (_.isUndefined(self._upd_menu_id)) {
|
||||
var IMD = new Model('ir.model.data');
|
||||
return IMD.call('get_object_reference', ['base', 'menu_module_updates']).then(function(r) {
|
||||
var mid = r[1];
|
||||
if(r[0] !== 'ir.ui.menu') {
|
||||
// invalid reference, return null
|
||||
mid = null;
|
||||
}
|
||||
self._upd_menu_id = mid;
|
||||
return mid;
|
||||
});
|
||||
} else {
|
||||
return $.Deferred().resolve(self._upd_menu_id).promise();
|
||||
}
|
||||
};
|
||||
|
||||
$.when(get_upd_menu_id()).done(function(menu_id) {
|
||||
if (_.isNull(menu_id)) {
|
||||
return;
|
||||
}
|
||||
var $menu = web_client.menu.$secondary_menus.find(_.str.sprintf('a[data-menu=%s]', menu_id));
|
||||
if ($menu.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (_.isUndefined(count)) {
|
||||
count = 0;
|
||||
}
|
||||
var needupdate = $menu.find('#menu_counter');
|
||||
if (needupdate && needupdate.length !== 0) {
|
||||
if (count > 0) {
|
||||
needupdate.text(count);
|
||||
} else {
|
||||
needupdate.remove();
|
||||
}
|
||||
} else if (count > 0) {
|
||||
$menu.append(qweb.render("Menu.needaction_counter", {widget: {needaction_counter: count}}));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
self.on('message:blockUI', self, function() { framework.blockUI(); });
|
||||
self.on('message:unblockUI', self, function() { framework.unblockUI(); });
|
||||
self.on('message:warn', self, function(m) {self.do_warn(m.title, m.message, m.sticky); });
|
||||
|
||||
self.$ifr.appendTo(self.$el).css(css).addClass('apps-client');
|
||||
}).
|
||||
fail(function(client) {
|
||||
self.do_warn(_t('Odoo Apps will be available soon'), _t('Showing locally available modules'), true);
|
||||
self.rpc('/web/action/load', {action_id: self.failback_action_id}).done(function(action) {
|
||||
self.do_action(action);
|
||||
web_client.menu.open_action(action.id);
|
||||
});
|
||||
self.on('message:ready', self, function(m) {
|
||||
var w = this.$ifr[0].contentWindow;
|
||||
var act = {
|
||||
type: 'ir.actions.client',
|
||||
tag: this.remote_action_tag,
|
||||
params: _.extend({}, this.params, {
|
||||
db: this.session.db,
|
||||
origin: this.session.origin,
|
||||
})
|
||||
};
|
||||
w.postMessage({type:'action', action: act}, client.origin);
|
||||
});
|
||||
|
||||
self.on('message:set_height', self, function(m) {
|
||||
this.$ifr.height(m.height);
|
||||
});
|
||||
|
||||
self.on('message:update_count', self, self._on_update_count);
|
||||
|
||||
self.on('message:blockUI', self, function() { framework.blockUI(); });
|
||||
self.on('message:unblockUI', self, function() { framework.unblockUI(); });
|
||||
self.on('message:warn', self, function(m) {self.do_warn(m.title, m.message, m.sticky); });
|
||||
|
||||
self.$ifr.appendTo(self.$el).css(css).addClass('apps-client');
|
||||
|
||||
def.resolve();
|
||||
}, function() {
|
||||
self.do_warn(_t('Odoo Apps will be available soon'), _t('Showing locally available modules'), true);
|
||||
return session.rpc('/web/action/load', {action_id: self.failback_action_id}).then(function(action) {
|
||||
return self.do_action(action);
|
||||
}).always(function () {
|
||||
def.reject();
|
||||
});
|
||||
});
|
||||
return def;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -202,4 +207,6 @@ var AppsUpdates = Apps.extend({
|
||||
core.action_registry.add("apps", Apps);
|
||||
core.action_registry.add("apps.updates", AppsUpdates);
|
||||
|
||||
return Apps;
|
||||
|
||||
});
|
||||
|
||||
@@ -199,7 +199,6 @@
|
||||
process_jobs: function (jobs, services) {
|
||||
var job;
|
||||
var require;
|
||||
var time;
|
||||
|
||||
function process_job (job) {
|
||||
var require = make_require(job);
|
||||
|
||||
@@ -22,7 +22,6 @@ var form_relational = require('web.form_relational'); // necessary
|
||||
var form_widgets = require('web.form_widgets'); // necessary
|
||||
var framework = require('web.framework');
|
||||
var ListView = require('web.ListView');
|
||||
var Menu = require('web.Menu');
|
||||
var Model = require('web.DataModel');
|
||||
var pyeval = require('web.pyeval');
|
||||
var Registry = require('web.Registry');
|
||||
@@ -96,7 +95,6 @@ openerp.web.FormView = FormView;
|
||||
openerp.web.json_node_to_xml = utils.json_node_to_xml;
|
||||
|
||||
openerp.web.ListView = ListView;
|
||||
openerp.web.Menu = Menu;
|
||||
openerp.web.Model = Model;
|
||||
openerp.web.normalize_format = time.strftime_to_moment_format;
|
||||
openerp.web.py_eval = pyeval.py_eval;
|
||||
@@ -208,7 +206,7 @@ ListView.include({
|
||||
}).value();
|
||||
}
|
||||
|
||||
return this._super(data);
|
||||
return this._super();
|
||||
},
|
||||
/**
|
||||
* Returns the style for the provided record in the current view (from the
|
||||
|
||||
@@ -54,17 +54,15 @@ var ControlPanel = Widget.extend({
|
||||
* @return {jQuery.Deferred}
|
||||
*/
|
||||
start: function() {
|
||||
this.$title_col = this.$('.oe-cp-title');
|
||||
|
||||
// Exposed jQuery nodesets
|
||||
this.nodes = {
|
||||
$breadcrumbs: this.$('.oe-view-title'),
|
||||
$buttons: this.$('.oe-cp-buttons'),
|
||||
$pager: this.$('.oe-cp-pager'),
|
||||
$searchview: this.$('.oe-cp-search-view'),
|
||||
$searchview_buttons: this.$('.oe-search-options'),
|
||||
$sidebar: this.$('.oe-cp-sidebar'),
|
||||
$switch_buttons: this.$('.oe-cp-switch-buttons'),
|
||||
$breadcrumbs: this.$('.breadcrumb'),
|
||||
$buttons: this.$('.o_cp_buttons'),
|
||||
$pager: this.$('.o_cp_pager'),
|
||||
$searchview: this.$('.o_cp_searchview'),
|
||||
$searchview_buttons: this.$('.o_search_options'),
|
||||
$sidebar: this.$('.o_cp_sidebar'),
|
||||
$switch_buttons: this.$('.o_cp_switch_buttons'),
|
||||
};
|
||||
|
||||
// By default, hide the ControlPanel and remove its contents from the DOM
|
||||
@@ -120,7 +118,7 @@ var ControlPanel = Widget.extend({
|
||||
|
||||
// Update the searchview and switch buttons
|
||||
this._update_search_view(status.searchview, status.search_view_hidden);
|
||||
if (status.active_view_selector) {
|
||||
if (status.active_view_selector) {
|
||||
this._update_switch_buttons(status.active_view_selector);
|
||||
}
|
||||
}
|
||||
@@ -182,22 +180,25 @@ var ControlPanel = Widget.extend({
|
||||
*/
|
||||
_render_breadcrumbs: function (breadcrumbs) {
|
||||
var self = this;
|
||||
|
||||
return breadcrumbs.map(function (bc, index) {
|
||||
return make_breadcrumb(bc, index === breadcrumbs.length - 1);
|
||||
return self._render_breadcrumbs_li(bc, index, breadcrumbs.length);
|
||||
});
|
||||
|
||||
function make_breadcrumb (bc, is_last) {
|
||||
var $bc = $('<li>')
|
||||
.append(is_last ? _.escape(bc.title) : $('<a>').text(bc.title))
|
||||
.toggleClass('active', is_last);
|
||||
if (!is_last) {
|
||||
$bc.click(function () {
|
||||
self.trigger("on_breadcrumb_click", bc.action, bc.index);
|
||||
});
|
||||
}
|
||||
return $bc;
|
||||
},
|
||||
/**
|
||||
* Private function that renders a breadcrumbs' li Jquery element
|
||||
*/
|
||||
_render_breadcrumbs_li: function (bc, index, length) {
|
||||
var self = this;
|
||||
var is_last = (index === length-1);
|
||||
var $bc = $('<li>')
|
||||
.append(is_last ? _.escape(bc.title) : $('<a>').text(bc.title))
|
||||
.toggleClass('active', is_last);
|
||||
if (!is_last) {
|
||||
$bc.click(function () {
|
||||
self.trigger("on_breadcrumb_click", bc.action, bc.index);
|
||||
});
|
||||
}
|
||||
return $bc;
|
||||
},
|
||||
/**
|
||||
* Private function that updates the SearchView's visibility and extend the
|
||||
@@ -211,8 +212,10 @@ var ControlPanel = Widget.extend({
|
||||
// have been appended to a jQuery node not in the DOM at SearchView initialization
|
||||
searchview.$buttons = this.nodes.$searchview_buttons;
|
||||
searchview.toggle_visibility(!is_hidden);
|
||||
this.$title_col.toggleClass('col-md-6', !is_hidden).toggleClass('col-md-12', is_hidden);
|
||||
}
|
||||
|
||||
this.nodes.$searchview.toggle(!is_hidden);
|
||||
this.$el.toggleClass('o_breadcrumb_full', !!is_hidden);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ odoo.define('web.ajax', function (require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var time = require('web.time');
|
||||
var utils = require('web.utils');
|
||||
var time = require('web.time');
|
||||
|
||||
function genericJsonRpc (fct_name, params, fct) {
|
||||
var data = {
|
||||
@@ -14,6 +14,7 @@ function genericJsonRpc (fct_name, params, fct) {
|
||||
};
|
||||
var xhr = fct(data);
|
||||
var result = xhr.pipe(function(result) {
|
||||
core.bus.trigger('rpc:result', data, result);
|
||||
if (result.error !== undefined) {
|
||||
if (result.error.data.arguments[0] !== "bus.Bus not available in test mode") {
|
||||
console.error("Server application error", JSON.stringify(result.error));
|
||||
@@ -42,7 +43,7 @@ function jsonRpc(url, fct_name, params, settings) {
|
||||
contentType: 'application/json'
|
||||
}));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function jsonpRpc(url, fct_name, params, settings) {
|
||||
settings = settings || {};
|
||||
@@ -116,7 +117,7 @@ function jsonpRpc(url, fct_name, params, settings) {
|
||||
return deferred;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// helper
|
||||
function realSetTimeout (fct, millis) {
|
||||
@@ -140,7 +141,7 @@ function loadCSS(url) {
|
||||
'type': 'text/css'
|
||||
}));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function loadJS(url) {
|
||||
var def = $.Deferred();
|
||||
@@ -165,7 +166,7 @@ function loadJS(url) {
|
||||
head.appendChild(script);
|
||||
}
|
||||
return def;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Cooperative file download implementation, for ajaxy APIs.
|
||||
@@ -301,7 +302,7 @@ function post (controller_url, data) {
|
||||
|
||||
var Def = $.Deferred();
|
||||
var postData = new FormData();
|
||||
|
||||
|
||||
$.each(data, function(i,val) {
|
||||
postData.append(i, val);
|
||||
});
|
||||
@@ -311,7 +312,7 @@ function post (controller_url, data) {
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
if(xhr.upload) xhr.upload.addEventListener('progress', progressHandler(Def), false);
|
||||
|
||||
|
||||
var ajaxDef = $.ajax(controller_url, {
|
||||
xhr: function() {return xhr;},
|
||||
data: postData,
|
||||
@@ -324,8 +325,6 @@ function post (controller_url, data) {
|
||||
return Def;
|
||||
}
|
||||
|
||||
|
||||
|
||||
var loadXML = (function () {
|
||||
var loading = false;
|
||||
var urls = [];
|
||||
|
||||
@@ -177,20 +177,16 @@ return {
|
||||
_lt: _lt,
|
||||
|
||||
// registries
|
||||
view_registry: new Registry(),
|
||||
crash_registry: new Registry(),
|
||||
action_registry : new Registry(),
|
||||
form_widget_registry: new Registry(),
|
||||
form_tag_registry: new Registry(),
|
||||
crash_registry: new Registry(),
|
||||
form_custom_registry: new Registry(),
|
||||
form_tag_registry: new Registry(),
|
||||
form_widget_registry: new Registry(),
|
||||
list_widget_registry: new Registry(),
|
||||
search_widgets_registry: new Registry(),
|
||||
search_filters_registry: new Registry(),
|
||||
|
||||
// necessary to make the kanban view compatible between
|
||||
// community and enterprise edition
|
||||
one2many_view_registry: new Registry(),
|
||||
|
||||
search_filters_registry: new Registry(),
|
||||
search_widgets_registry: new Registry(),
|
||||
view_registry: new Registry(),
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -40,22 +40,17 @@ var CrashManager = core.Class.extend({
|
||||
if (!this.active) {
|
||||
return;
|
||||
}
|
||||
if (this.$indicator){
|
||||
if (this.connection_lost) {
|
||||
return;
|
||||
}
|
||||
if (error.code == -32098) {
|
||||
$.blockUI({ message: '' , overlayCSS: {'z-index': 9999, backgroundColor: '#FFFFFF', opacity: 0.0, cursor: 'wait'}});
|
||||
this.$indicator = $('<div class="oe_indicator">' + _t("Trying to reconnect... ") + '<i class="fa fa-refresh"></i></div>');
|
||||
this.$indicator.prependTo("body");
|
||||
var timeinterval = setInterval(function(){
|
||||
core.bus.trigger('connection_lost');
|
||||
this.connection_lost = true;
|
||||
var timeinterval = setInterval(function() {
|
||||
ajax.jsonRpc('/web/webclient/version_info').then(function() {
|
||||
clearInterval(timeinterval);
|
||||
self.$indicator.html(_t("You are back online"));
|
||||
self.$indicator.delay(2000).fadeOut('slow',function(){
|
||||
$(this).remove();
|
||||
self.$indicator.remove();
|
||||
});
|
||||
$.unblockUI();
|
||||
core.bus.trigger('connection_restored');
|
||||
self.connection_lost = false;
|
||||
});
|
||||
}, 2000);
|
||||
return;
|
||||
|
||||
@@ -320,6 +320,7 @@ var DataSet = Class.extend(mixins.PropertiesMixin, {
|
||||
this.index = null;
|
||||
this._sort = [];
|
||||
this._model = new Model(model, context);
|
||||
this.orderer = new utils.DropMisordered();
|
||||
},
|
||||
previous: function () {
|
||||
this.index -= 1;
|
||||
@@ -408,10 +409,11 @@ var DataSet = Class.extend(mixins.PropertiesMixin, {
|
||||
read_slice: function (fields, options) {
|
||||
var self = this;
|
||||
options = options || {};
|
||||
return this._model.query(fields)
|
||||
var query = this._model.query(fields)
|
||||
.limit(options.limit || false)
|
||||
.offset(options.offset || 0)
|
||||
.all().done(function (records) {
|
||||
.all();
|
||||
return this.orderer.add(query).done(function (records) {
|
||||
self.ids = _(records).pluck('id');
|
||||
});
|
||||
},
|
||||
@@ -761,12 +763,6 @@ var BufferedDataSet = DataSetStatic.extend({
|
||||
_.extend(cached.from_read, options.from_read);
|
||||
_.extend(cached.changes, options.changes);
|
||||
_.extend(cached.readonly_fields, options.readonly_fields);
|
||||
// discard values from cached.changes that are in cached.from_read
|
||||
_.each(cached.changes, function (v, k) {
|
||||
if (cached.from_read[k] === v) {
|
||||
delete cached.changes[k];
|
||||
}
|
||||
});
|
||||
if (options.to_create !== undefined) cached.to_create = options.to_create;
|
||||
if (options.to_delete !== undefined) cached.to_delete = options.to_delete;
|
||||
}
|
||||
|
||||
@@ -211,6 +211,16 @@ if ('nv' in window) {
|
||||
nv.tooltip.cleanup = function () {
|
||||
$('.nvtooltip').remove();
|
||||
};
|
||||
|
||||
// monkey patch nvd3 to prevent it to display a tooltip (position: absolute) with
|
||||
// a negative `top`; with this patch the highest tooltip's position is still in the
|
||||
// graph
|
||||
var originalCalcTooltipPosition = nv.tooltip.calcTooltipPosition;
|
||||
nv.tooltip.calcTooltipPosition = function () {
|
||||
var container = originalCalcTooltipPosition.apply(this, arguments);
|
||||
container.style.top = container.style.top.split('px')[0] < 0 ? 0 + 'px' : container.style.top;
|
||||
return container;
|
||||
};
|
||||
}
|
||||
|
||||
// Bootstrap customization
|
||||
@@ -303,11 +313,18 @@ $.extend( proto, {
|
||||
});
|
||||
|
||||
/**
|
||||
* Private function that triggers an event on core.bus
|
||||
* Private function to notify that something has been attached in the DOM
|
||||
* @param {htmlString or Element or Array or jQuery} [content] the content that
|
||||
* has been attached in the DOM
|
||||
* @params {Array} [callbacks] array of {widget: w, callback_args: args} such
|
||||
* that on_attach_callback() will be called on each w with arguments args
|
||||
*/
|
||||
function _notify (content) {
|
||||
function _notify (content, callbacks) {
|
||||
_.each(callbacks, function(c) {
|
||||
if (c.widget && c.widget.on_attach_callback) {
|
||||
c.widget.on_attach_callback(c.callback_args);
|
||||
}
|
||||
});
|
||||
core.bus.trigger('DOM_updated', content);
|
||||
}
|
||||
/**
|
||||
@@ -315,12 +332,14 @@ function _notify (content) {
|
||||
* @param {jQuery} [$target] the node where content will be appended
|
||||
* @param {htmlString or Element or Array or jQuery} [content] DOM element,
|
||||
* array of elements, HTML string or jQuery object to append to $target
|
||||
* @param {jQuery} [trigger] true to trigger an event, false otherwise
|
||||
* @param {Boolean} [options.in_DOM] true if $target is in the DOM
|
||||
* @param {Array} [options.callbacks] array of objects describing the callbacks
|
||||
* to perform (see _notify for a complete description)
|
||||
*/
|
||||
function append ($target, content, trigger) {
|
||||
function append ($target, content, options) {
|
||||
$target.append(content);
|
||||
if (trigger) {
|
||||
_notify(content);
|
||||
if (options && options.in_DOM) {
|
||||
_notify(content, options.callbacks);
|
||||
}
|
||||
}
|
||||
/**
|
||||
@@ -328,15 +347,39 @@ function append ($target, content, trigger) {
|
||||
* @param {jQuery} [$target] the node where content will be prepended
|
||||
* @param {htmlString or Element or Array or jQuery} [content] DOM element,
|
||||
* array of elements, HTML string or jQuery object to prepend to $target
|
||||
* @param {jQuery} [trigger] true to trigger an event, false otherwise
|
||||
* @param {Boolean} [options.in_DOM] true if $target is in the DOM
|
||||
* @param {Array} [options.callbacks] array of objects describing the callbacks
|
||||
* to perform (see _notify for a complete description)
|
||||
*/
|
||||
function prepend ($target, content, trigger) {
|
||||
function prepend ($target, content, options) {
|
||||
$target.prepend(content);
|
||||
if (trigger) {
|
||||
_notify(content);
|
||||
if (options && options.in_DOM) {
|
||||
_notify(content, options.callbacks);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches widgets from the DOM and performs their on_detach_callback()
|
||||
* @param {Array} [to_detach] array of {widget: w, callback_args: args} such
|
||||
* that w.$el will be detached and w.on_detach_callback(args) will be called
|
||||
* @param {jQuery} [options.$to_detach] if given, detached instead of widgets' $el
|
||||
* @return {jQuery} the detached elements
|
||||
*/
|
||||
function detach (to_detach, options) {
|
||||
_.each(to_detach, function(d) {
|
||||
if (d.widget.on_detach_callback) {
|
||||
d.widget.on_detach_callback(d.callback_args);
|
||||
}
|
||||
});
|
||||
var $to_detach = options && options.$to_detach;
|
||||
if (!$to_detach) {
|
||||
$to_detach = $(_.map(to_detach, function(d) {
|
||||
return d.widget.el;
|
||||
}));
|
||||
}
|
||||
return $to_detach.detach();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the distance between a DOM element and the top-left corner of the window
|
||||
* @param {element} [e] the DOM element
|
||||
@@ -358,6 +401,7 @@ return {
|
||||
redirect: redirect,
|
||||
append: append,
|
||||
prepend: prepend,
|
||||
detach: detach,
|
||||
getPosition: getPosition,
|
||||
};
|
||||
|
||||
|
||||
@@ -6,14 +6,12 @@ var session = require('web.session');
|
||||
|
||||
var Model = Class.extend({
|
||||
/**
|
||||
new openerp.web.Model([session,] model_name[, context[, domain]])
|
||||
new openerp.web.Model(name[, context[, domain]])
|
||||
|
||||
@constructs instance.web.Model
|
||||
@extends instance.web.Class
|
||||
|
||||
@param {openerp.web.Session} [session] The session object used to communicate with
|
||||
the server.
|
||||
@param {String} model_name name of the OpenERP model this object is bound to
|
||||
@param {String} name name of the OpenERP model this object is bound to
|
||||
@param {Object} [context]
|
||||
@param {Array} [domain]
|
||||
*/
|
||||
|
||||
@@ -236,7 +236,7 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, {
|
||||
return d;
|
||||
},
|
||||
load_qweb: function(mods) {
|
||||
this.qweb_mutex.exec(function() {
|
||||
this.qweb_mutex.exec(function () {
|
||||
return $.get('/web/webclient/qweb?mods=' + mods).then(function (doc) {
|
||||
if (!doc) { return; }
|
||||
qweb.add_template(doc);
|
||||
|
||||
@@ -423,7 +423,6 @@ function swap(array, elem1, elem2) {
|
||||
array[i1] = elem2;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
divmod: divmod,
|
||||
modf: modf,
|
||||
|
||||
@@ -27,6 +27,8 @@ var View = Widget.extend({
|
||||
// multi_record is used to distinguish views displaying a single record
|
||||
// (e.g. FormView) from those that display several records (e.g. ListView)
|
||||
multi_record: true,
|
||||
// indicates whether or not the view is mobile-friendly
|
||||
mobile_friendly: false,
|
||||
// icon is the font-awesome icon to display in the view switcher
|
||||
icon: 'fa-question',
|
||||
// whether or not the view requires the model's fields to render itself
|
||||
@@ -45,11 +47,8 @@ var View = Widget.extend({
|
||||
* @return {Deferred}
|
||||
*/
|
||||
start: function() {
|
||||
// add css classes that reflect the (absence of) access rights
|
||||
this.$el.addClass('oe_view')
|
||||
.toggleClass('oe_cannot_create', !this.is_action_enabled('create'))
|
||||
.toggleClass('oe_cannot_edit', !this.is_action_enabled('edit'))
|
||||
.toggleClass('oe_cannot_delete', !this.is_action_enabled('delete'));
|
||||
// add classname that reflect the (absence of) access rights
|
||||
this.$el.toggleClass('o_cannot_create', !this.is_action_enabled('create'));
|
||||
return this._super().then(this.trigger.bind(this, 'view_loaded'));
|
||||
},
|
||||
/**
|
||||
@@ -76,7 +75,7 @@ var View = Widget.extend({
|
||||
|
||||
// response handler
|
||||
var handler = function (action) {
|
||||
if (action && action.constructor == Object) {
|
||||
if (action && action.constructor === Object) {
|
||||
// filter out context keys that are specific to the current action.
|
||||
// Wrong default_* and search_default_* values will no give the expected result
|
||||
// Wrong group_by values will simply fail and forbid rendering of the destination view
|
||||
@@ -106,7 +105,7 @@ var View = Widget.extend({
|
||||
|
||||
if (action_data.special === 'cancel') {
|
||||
return handler({"type":"ir.actions.act_window_close"});
|
||||
} else if (action_data.type=="object") {
|
||||
} else if (action_data.type === "object") {
|
||||
var args = [[record_id]];
|
||||
if (action_data.args) {
|
||||
try {
|
||||
@@ -122,7 +121,7 @@ var View = Widget.extend({
|
||||
return dataset.call_button(action_data.name, args).then(handler).then(function () {
|
||||
core.bus.trigger('do_reload_needaction');
|
||||
});
|
||||
} else if (action_data.type=="action") {
|
||||
} else if (action_data.type === "action") {
|
||||
return data_manager.load_action(action_data.name, _.extend(pyeval.eval('context', context), {
|
||||
active_model: dataset.model,
|
||||
active_ids: dataset.ids,
|
||||
@@ -144,27 +143,24 @@ var View = Widget.extend({
|
||||
do_load_state: function (state, warm) {
|
||||
},
|
||||
/**
|
||||
* This function should render the buttons of the view, set this.$buttons to
|
||||
* the produced jQuery element and define some listeners on it.
|
||||
* This function should be called after start().
|
||||
* This function should render the action buttons of the view.
|
||||
* It should be called after start().
|
||||
* @param {jQuery} [$node] a jQuery node where the rendered buttons should be inserted
|
||||
* $node may be undefined, in which case the View can insert the buttons somewhere else
|
||||
*/
|
||||
render_buttons: function($node) {
|
||||
},
|
||||
/**
|
||||
* This function should instantiate and render the sidebar of the view, set this.sidebar to
|
||||
* the instantiated Sidebar Widget and possibly add custom items in it.
|
||||
* This function should be called after start().
|
||||
* This function should render the sidebar of the view.
|
||||
* It should be called after start().
|
||||
* @param {jQuery} [$node] a jQuery node where the sidebar should be inserted
|
||||
* $node may be undefined, in which case the View can insert the sidebar somewhere else
|
||||
*/
|
||||
render_sidebar: function($node) {
|
||||
},
|
||||
/**
|
||||
* This function should render the pager of the view, set this.$pager to
|
||||
* the produced jQuery element and define some listeners on it.
|
||||
* This function should be called after start().
|
||||
* This function should render the pager of the view.
|
||||
* It should be called after start().
|
||||
* @param {jQuery} [$node] a jQuery node where the pager should be inserted
|
||||
* $node may be undefined, in which case the View can insert the pager somewhere else
|
||||
*/
|
||||
@@ -200,6 +196,12 @@ var View = Widget.extend({
|
||||
get_context: function () {
|
||||
return {};
|
||||
},
|
||||
set_scrollTop: function(scrollTop) {
|
||||
this.scrollTop = scrollTop;
|
||||
},
|
||||
get_scrollTop: function() {
|
||||
return this.scrollTop;
|
||||
}
|
||||
});
|
||||
|
||||
return View;
|
||||
|
||||
@@ -32,7 +32,7 @@ var mixins = core.mixins;
|
||||
* },
|
||||
* start: function() {
|
||||
* // stuff you want to make after the rendering, `this.$el` holds a correct value
|
||||
* this.$el.find(".my_button").click(/* an example of event binding * /);
|
||||
* this.$(".my_button").click(/* an example of event binding * /);
|
||||
*
|
||||
* // if you have some asynchronous operations, it's a good idea to return
|
||||
* // a promise in start()
|
||||
|
||||
@@ -15,7 +15,7 @@ var Menu = Widget.extend({
|
||||
this.data = {data:{children:[]}};
|
||||
this.on("menu_bound", this, function() {
|
||||
// launch the fetch of needaction counters, asynchronous
|
||||
var $all_menus = self.$el.parents('body').find('.oe_webclient').find('[data-menu]');
|
||||
var $all_menus = self.$el.parents('.o_web_client').find('.o_sub_menu').find('[data-menu]');
|
||||
var all_menu_ids = _.map($all_menus, function (menu) {return parseInt($(menu).attr('data-menu'), 10);});
|
||||
if (!_.isEmpty(all_menu_ids)) {
|
||||
this.do_load_needaction(all_menu_ids);
|
||||
@@ -34,7 +34,7 @@ var Menu = Widget.extend({
|
||||
},
|
||||
bind_menu: function() {
|
||||
var self = this;
|
||||
this.$secondary_menus = this.$el.parents().find('.oe_secondary_menus_container');
|
||||
this.$secondary_menus = this.$el.parents().find('.o_sub_menu');
|
||||
this.$secondary_menus.on('click', 'a[data-menu]', this.on_menu_click);
|
||||
this.$el.on('click', 'a[data-menu]', function (event) {
|
||||
event.preventDefault();
|
||||
@@ -160,7 +160,7 @@ var Menu = Widget.extend({
|
||||
$sub_menu.show();
|
||||
|
||||
// Hide/Show the leftbar menu depending of the presence of sub-items
|
||||
this.$secondary_menus.parent('.oe_leftbar').toggle(!!$sub_menu.children().length);
|
||||
this.$secondary_menus.toggle(!!$sub_menu.children().length);
|
||||
|
||||
// Activate current menu item and show parents
|
||||
this.$secondary_menus.find('.active').removeClass('active');
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user