summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorOlivier Dony <odo@openerp.com>2012-09-11 13:42:01 +0200
committerOlivier Dony <odo@openerp.com>2012-09-11 13:42:01 +0200
commitaa98dd38e2f8ce9a3e5a26f391fd1fb59e89a0e6 (patch)
treea45f5337e4707a6552288ebd80c6e78d74382b27 /addons/web/static/src
parent02d32cd6cfa94304b790f680f2d7ebeee51b71f4 (diff)
parent5848e72d421d0c63a0a9bd3b254b6e4aa35d5cb6 (diff)
[MERGE] Sync with trunk
bzr revid: odo@openerp.com-20120911114201-1omaloa3b2dld9l9
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/css/Makefile2
-rw-r--r--addons/web/static/src/css/base.css765
-rw-r--r--addons/web/static/src/css/base.sass596
-rw-r--r--addons/web/static/src/css/data_import.css46
-rw-r--r--addons/web/static/src/js/chrome.js205
-rw-r--r--addons/web/static/src/js/corelib.js50
-rw-r--r--addons/web/static/src/js/coresetup.js159
-rw-r--r--addons/web/static/src/js/data.js2
-rw-r--r--addons/web/static/src/js/data_export.js114
-rw-r--r--addons/web/static/src/js/data_import.js393
-rw-r--r--addons/web/static/src/js/search.js166
-rw-r--r--addons/web/static/src/js/test_support.js1
-rw-r--r--addons/web/static/src/js/view_form.js634
-rw-r--r--addons/web/static/src/js/view_list.js88
-rw-r--r--addons/web/static/src/js/view_list_editable.js67
-rw-r--r--addons/web/static/src/js/view_tree.js26
-rw-r--r--addons/web/static/src/js/views.js285
-rw-r--r--addons/web/static/src/xml/base.xml115
18 files changed, 1686 insertions, 2028 deletions
diff --git a/addons/web/static/src/css/Makefile b/addons/web/static/src/css/Makefile
index eca044497ef..d6b4f4b2fc8 100644
--- a/addons/web/static/src/css/Makefile
+++ b/addons/web/static/src/css/Makefile
@@ -1,3 +1,3 @@
base.css: base.sass
- sass -t expanded base.sass base.css
+ sass --trace -t expanded base.sass base.css
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index a39838070cb..f952dd298fd 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -20,50 +20,11 @@
font-style: normal;
}
-@-moz-keyframes bounce {
- 0% {
- -moz-transform: scale(0);
- opacity: 0;
- }
-
- 50% {
- -moz-transform: scale(1.3);
- opacity: 0.4;
- }
-
- 75% {
- -moz-transform: scale(0.9);
- opacity: 0.7;
- }
-
- 100% {
- -moz-transform: scale(1);
- opacity: 1;
- }
-}
-
-@-webkit-keyframes bounce {
- 0% {
- -webkit-transform: scale(0);
- opacity: 0;
- }
-
- 50% {
- -webkit-transform: scale(1.3);
- opacity: 0.4;
- }
-
- 75% {
- -webkit-transform: scale(0.9);
- opacity: 0.7;
- }
-
- 100% {
- -webkit-transform: scale(1);
- opacity: 1;
+@media print {
+ .oe_topbar, .oe_leftbar, .oe_loading {
+ display: none !important;
}
}
-
.openerp.openerp_webclient_container {
height: 100%;
position: relative;
@@ -76,6 +37,7 @@
color: #4c4c4c;
font-size: 13px;
background: white;
+ text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
/* http://www.quirksmode.org/dom/inputfile.html
* http://stackoverflow.com/questions/2855589/replace-input-type-file-by-an-image
*/
@@ -135,13 +97,6 @@
background-image: -o-linear-gradient(top, #eeeeee, #dedede);
background-image: linear-gradient(to bottom, #eeeeee, #dedede);
}
-.openerp ul, .openerp li, .openerp ol {
- margin: 0;
- padding: 0;
-}
-.openerp li {
- list-style-type: none;
-}
.openerp input, .openerp textarea, .openerp select {
padding: 2px 4px;
border: 1px solid #cccccc;
@@ -156,10 +111,32 @@
.openerp h4 {
margin: 4px 0;
}
+.openerp .oe_semantic_html_override ul, .openerp .oe_semantic_html_override ol {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_semantic_html_override ul ul, .openerp .oe_semantic_html_override ul ol, .openerp .oe_semantic_html_override ul li, .openerp .oe_semantic_html_override ol ul, .openerp .oe_semantic_html_override ol ol, .openerp .oe_semantic_html_override ol li {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_semantic_html_override ul li, .openerp .oe_semantic_html_override ol li {
+ list-style-type: none;
+}
+.openerp ul.oe_semantic_html_override {
+ margin: 0;
+ padding: 0;
+}
+.openerp ul.oe_semantic_html_override ul, .openerp ul.oe_semantic_html_override ol, .openerp ul.oe_semantic_html_override li {
+ margin: 0;
+ padding: 0;
+}
+.openerp ul.oe_semantic_html_override li {
+ list-style-type: none;
+}
.openerp a.button:link, .openerp a.button:visited, .openerp button, .openerp input[type='submit'], .openerp .ui-dialog-buttonpane .ui-dialog-buttonset .ui-button {
display: inline-block;
border: 1px solid #ababab;
- color: #404040;
+ color: #4c4c4c;
margin: 0;
padding: 3px 12px;
font-size: 13px;
@@ -228,20 +205,11 @@
cursor: default;
text-shadow: 0 1px 1px white !important;
}
-.openerp .ui-widget {
- font-family: "Lucida Grande", Helvetica, Verdana, Arial, sans-serif;
- font-size: 13px;
-}
.openerp .ui-widget-content a {
- color: #8a89ba;
-}
-.openerp .ui-menu .ui-menu-item {
- margin: 0 8px 0 0;
- padding: 0 0 0 12px;
- width: auto;
+ color: #7c7bad;
}
-.openerp .ui-menu .ui-menu-item a.ui-state-active {
- background: #f0f0fa;
+.openerp .oe_bounce_container {
+ display: inline-block;
}
.openerp.ui-dialog {
display: none;
@@ -335,7 +303,7 @@
border-radius: 0 0 2px 2px;
}
.openerp.ui-dialog .oe_about a {
- color: #8a89ba;
+ color: #7c7bad;
}
.openerp.ui-dialog .oe_about a:hover {
text-decoration: underline;
@@ -425,40 +393,38 @@
background: #dc5f59;
}
.openerp button.oe_highlight {
- background-color: #dc5f59;
- background-image: -webkit-gradient(linear, left top, left bottom, from(#dc5f59), to(#b33630));
- background-image: -webkit-linear-gradient(top, #dc5f59, #b33630);
- background-image: -moz-linear-gradient(top, #dc5f59, #b33630);
- background-image: -ms-linear-gradient(top, #dc5f59, #b33630);
- background-image: -o-linear-gradient(top, #dc5f59, #b33630);
- background-image: linear-gradient(to bottom, #dc5f59, #b33630);
- -moz-box-shadow: none;
- -webkit-box-shadow: none;
- box-shadow: none;
+ border: 1px solid #795151;
+ background-color: #df3f3f;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#df3f3f), to(#a21a1a));
+ background-image: -webkit-linear-gradient(top, #df3f3f, #a21a1a);
+ background-image: -moz-linear-gradient(top, #df3f3f, #a21a1a);
+ background-image: -ms-linear-gradient(top, #df3f3f, #a21a1a);
+ background-image: -o-linear-gradient(top, #df3f3f, #a21a1a);
+ background-image: linear-gradient(to bottom, #df3f3f, #a21a1a);
+ -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset;
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset;
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset;
+}
+.openerp button.oe_highlight:hover {
+ background-color: #e25858;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#e25858), to(#ab1b1b));
+ background-image: -webkit-linear-gradient(top, #e25858, #ab1b1b);
+ background-image: -moz-linear-gradient(top, #e25858, #ab1b1b);
+ background-image: -ms-linear-gradient(top, #e25858, #ab1b1b);
+ background-image: -o-linear-gradient(top, #e25858, #ab1b1b);
+ background-image: linear-gradient(to bottom, #e25858, #ab1b1b);
}
.openerp button.oe_highlight:active {
- background-color: #b33630;
- background-image: -webkit-gradient(linear, left top, left bottom, from(#b33630), to(#dc5f59));
- background-image: -webkit-linear-gradient(top, #b33630, #dc5f59);
- background-image: -moz-linear-gradient(top, #b33630, #dc5f59);
- background-image: -ms-linear-gradient(top, #b33630, #dc5f59);
- background-image: -o-linear-gradient(top, #b33630, #dc5f59);
- background-image: linear-gradient(to bottom, #b33630, #dc5f59);
- -moz-box-shadow: none;
- -webkit-box-shadow: none;
- box-shadow: none;
+ background-color: #c52020;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#c52020), to(#d22323));
+ background-image: -webkit-linear-gradient(top, #c52020, #d22323);
+ background-image: -moz-linear-gradient(top, #c52020, #d22323);
+ background-image: -ms-linear-gradient(top, #c52020, #d22323);
+ background-image: -o-linear-gradient(top, #c52020, #d22323);
+ background-image: linear-gradient(to bottom, #c52020, #d22323);
}
-.openerp button.oe_highlight:hover {
- background-color: #df6b66;
- background-image: -webkit-gradient(linear, left top, left bottom, from(#df6b66), to(#bf3a33));
- background-image: -webkit-linear-gradient(top, #df6b66, #bf3a33);
- background-image: -moz-linear-gradient(top, #df6b66, #bf3a33);
- background-image: -ms-linear-gradient(top, #df6b66, #bf3a33);
- background-image: -o-linear-gradient(top, #df6b66, #bf3a33);
- background-image: linear-gradient(to bottom, #df6b66, #bf3a33);
- -moz-box-shadow: 0 0 1px rgba(0, 0, 0, 0.2);
- -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, 0.2);
- box-shadow: 0 0 1px rgba(0, 0, 0, 0.2);
+.openerp .oe_background_grey {
+ background: #eeeeee !important;
}
.openerp .oe_form_dirty .oe_highlight_on_dirty {
color: white;
@@ -499,15 +465,16 @@
margin: 4px;
}
.openerp .oe_avatar > img {
- height: 90px;
- max-width: 100px;
+ max-height: 90px;
+ max-width: 90px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
- -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
- -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
+ -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
+ -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
border: none;
+ margin-bottom: 10px;
}
.openerp .oe_avatar + div {
margin-left: 5px;
@@ -525,9 +492,9 @@
padding: 0;
margin: 0;
background: none;
- -moz-border-radius: none;
- -webkit-border-radius: none;
- border-radius: none;
+ -moz-border-radius: 0;
+ -webkit-border-radius: 0;
+ border-radius: 0;
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
@@ -540,13 +507,13 @@
padding: 0;
margin: 0;
background: none;
- -moz-border-radius: none;
- -webkit-border-radius: none;
- border-radius: none;
+ -moz-border-radius: 0;
+ -webkit-border-radius: 0;
+ border-radius: 0;
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
- color: #8a89ba;
+ color: #7c7bad;
font-weight: bold;
}
.openerp .oe_button.oe_link span:hover {
@@ -577,9 +544,12 @@
color: #4c4c4c;
}
.openerp .oe_tag_dark {
- background: #8786b7;
+ background: #7c7bad;
color: #eeeeee;
}
+.openerp .oe_tags {
+ margin-bottom: 1px;
+}
.openerp .oe_tags.oe_inline {
min-width: 250px;
}
@@ -632,6 +602,26 @@
padding: 0 16px;
list-style: none;
zoom: 1;
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_notebook ul, .openerp .oe_notebook ol, .openerp .oe_notebook li {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_notebook li {
+ list-style-type: none;
+}
+.openerp .oe_notebook ul, .openerp .oe_notebook ol {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_notebook ul ul, .openerp .oe_notebook ul ol, .openerp .oe_notebook ul li, .openerp .oe_notebook ol ul, .openerp .oe_notebook ol ol, .openerp .oe_notebook ol li {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_notebook ul li, .openerp .oe_notebook ol li {
+ list-style-type: none;
}
.openerp .oe_notebook.ui-corner-all {
-moz-border-radius: 0;
@@ -872,9 +862,9 @@
font-family: "Lucida Grande", Helvetica, Verdana, Arial;
border: 1px solid #999999;
background: whitesmoke;
- -moz-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
- -webkit-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
- box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
+ -moz-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.4);
+ -webkit-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.4);
+ box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.4);
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
@@ -936,6 +926,17 @@
-webkit-box-shadow: 0 0 18px rgba(0, 0, 0, 0.9);
box-shadow: 0 0 18px rgba(0, 0, 0, 0.9);
}
+.openerp .oe_login .oe_login_pane ul, .openerp .oe_login .oe_login_pane ol {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_login .oe_login_pane ul ul, .openerp .oe_login .oe_login_pane ul ol, .openerp .oe_login .oe_login_pane ul li, .openerp .oe_login .oe_login_pane ol ul, .openerp .oe_login .oe_login_pane ol ol, .openerp .oe_login .oe_login_pane ol li {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_login .oe_login_pane ul li, .openerp .oe_login .oe_login_pane ol li {
+ list-style-type: none;
+}
.openerp .oe_login .oe_login_pane h2 {
margin-top: 0;
font-size: 18px;
@@ -1006,7 +1007,6 @@
.openerp .oe_topbar {
width: 100%;
height: 31px;
- border-top: solid 1px #d3d3d3;
background-color: #646060;
background-image: -webkit-gradient(linear, left top, left bottom, from(#646060), to(#262626));
background-image: -webkit-linear-gradient(top, #646060, #262626);
@@ -1015,6 +1015,17 @@
background-image: -o-linear-gradient(top, #646060, #262626);
background-image: linear-gradient(to bottom, #646060, #262626);
}
+.openerp .oe_topbar ul, .openerp .oe_topbar ol {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_topbar ul ul, .openerp .oe_topbar ul ol, .openerp .oe_topbar ul li, .openerp .oe_topbar ol ul, .openerp .oe_topbar ol ol, .openerp .oe_topbar ol li {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_topbar ul li, .openerp .oe_topbar ol li {
+ list-style-type: none;
+}
.openerp .oe_topbar .oe_topbar_item {
display: block;
padding: 5px 10px 7px;
@@ -1031,14 +1042,6 @@
-webkit-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
}
-.openerp .oe_topbar .oe_topbar_item .oe_active {
- background: #303030;
- font-weight: bold;
- color: white;
- -moz-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
- -webkit-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
- box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
-}
.openerp .oe_topbar .oe_topbar_avatar {
width: 24px;
height: 24px;
@@ -1095,6 +1098,17 @@
text-shadow: 0 1px 1px white;
padding-bottom: 16px;
}
+.openerp .oe_leftbar ul, .openerp .oe_leftbar ol {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_leftbar ul ul, .openerp .oe_leftbar ul ol, .openerp .oe_leftbar ul li, .openerp .oe_leftbar ol ul, .openerp .oe_leftbar ol ol, .openerp .oe_leftbar ol li {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_leftbar ul li, .openerp .oe_leftbar ol li {
+ list-style-type: none;
+}
.openerp a.oe_logo {
width: 220px;
display: block;
@@ -1149,10 +1163,10 @@
padding: 0;
margin: 0;
}
-.openerp .oe_menu li {
+.openerp .oe_menu > li {
float: left;
}
-.openerp .oe_menu a {
+.openerp .oe_menu > li > a {
display: block;
padding: 5px 10px 7px;
line-height: 20px;
@@ -1161,14 +1175,14 @@
vertical-align: top;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
}
-.openerp .oe_menu a:hover {
+.openerp .oe_menu > li > a:hover {
background: #303030;
color: white;
-moz-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
-webkit-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
box-shadow: 0 1px 2px rgba(255, 255, 255, 0.3) inset;
}
-.openerp .oe_menu .oe_active {
+.openerp .oe_menu > li > .oe_active {
background: #303030;
font-weight: bold;
color: white;
@@ -1179,7 +1193,7 @@
.openerp .oe_secondary_menu_section {
font-weight: bold;
margin-left: 8px;
- color: #8a89ba;
+ color: #7c7bad;
}
.openerp .oe_secondary_submenu {
padding: 2px 0 8px 0;
@@ -1187,21 +1201,21 @@
width: 100%;
display: inline-block;
}
-.openerp .oe_secondary_submenu > li {
+.openerp .oe_secondary_submenu li {
position: relative;
- padding: 1px 0 1px 20px;
+ padding: 1px 0 1px 20px !important;
}
-.openerp .oe_secondary_submenu > li a {
+.openerp .oe_secondary_submenu li a {
display: block;
color: #4c4c4c;
padding: 2px 4px 2px 0;
}
-.openerp .oe_secondary_submenu > li .oe_menu_label {
+.openerp .oe_secondary_submenu li .oe_menu_label {
position: absolute;
top: 1px;
right: 1px;
font-size: 10px;
- background: #8a89ba;
+ background: #7c7bad;
color: white;
padding: 2px 4px;
margin: 1px 6px 0 0;
@@ -1217,24 +1231,33 @@
.openerp .oe_secondary_submenu .oe_menu_counter {
float: right;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
- margin: 0px;
+ margin: 1px;
padding: 1px 4px;
+ border: none;
+}
+.openerp .oe_secondary_submenu .oe_menu_counter:hover {
+ cursor: pointer;
+ -webkit-transform: scale(1.1);
+ -moz-transform: scale(1.1);
+ -ms-transform: scale(1.1);
+ -o-transform: scale(1.1);
+ transform: scale(1.1);
}
.openerp .oe_secondary_submenu .oe_active {
- background: #8a89ba;
border-top: 1px solid lightGray;
- border-bottom: 1px solid lightGray;
+ border-bottom: 1px solid #dedede;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
- -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2);
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2);
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2);
+ -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2), inset 0 -1px 3px rgba(40, 40, 40, 0.2);
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2), inset 0 -1px 3px rgba(40, 40, 40, 0.2);
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2), inset 0 -1px 3px rgba(40, 40, 40, 0.2);
+ background: #7c7bad;
}
.openerp .oe_secondary_submenu .oe_active a {
color: white;
}
.openerp .oe_secondary_submenu .oe_active .oe_menu_label {
background: #eeeeee;
- color: #8a89ba;
+ color: #7c7bad;
text-shadow: 0 1px 1px white;
-moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
@@ -1242,7 +1265,10 @@
}
.openerp .oe_secondary_submenu .oe_active .oe_menu_counter {
background: #eeeeee;
- color: #8a89ba;
+ color: #7c7bad;
+ -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2);
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2);
}
.openerp .oe_secondary_submenu .oe_menu_toggler:before {
width: 0;
@@ -1272,7 +1298,7 @@
width: 100%;
}
.openerp .oe_application a {
- color: #8a89ba;
+ color: #7c7bad;
}
.openerp .oe_application a:hover {
text-decoration: underline;
@@ -1290,6 +1316,16 @@
width: 100%;
table-layout: fixed;
}
+.openerp .oe_view_manager table.oe_view_manager_header ul {
+ padding: 0;
+ margin-right: 0;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+.openerp .oe_view_manager table.oe_view_manager_header ul li {
+ list-style-type: none;
+ margin: 0;
+}
.openerp .oe_view_manager table.oe_view_manager_header .oe_header_row {
clear: both;
text-shadow: 0 1px 1px white;
@@ -1297,6 +1333,9 @@
.openerp .oe_view_manager table.oe_view_manager_header .oe_header_row:last-child td {
padding-top: 0;
}
+.openerp .oe_view_manager table.oe_view_manager_header .oe_header_row:first-child td {
+ padding-top: 8px;
+}
.openerp .oe_view_manager table.oe_view_manager_header .oe_view_manager_sidebar {
margin: 0px auto;
text-align: center;
@@ -1310,7 +1349,10 @@
float: left;
}
.openerp .oe_view_manager table.oe_view_manager_header h2 a {
- color: #8a89ba;
+ color: #7c7bad;
+}
+.openerp .oe_view_manager table.oe_view_manager_header .oe_dropdown_menu {
+ line-height: normal;
}
.openerp .oe_view_manager table.oe_view_manager_header .oe_button_group {
display: inline-block;
@@ -1393,11 +1435,15 @@
color: white;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}
+.openerp .oe_view_manager .oe_view_manager_switch {
+ margin-left: 8px;
+}
.openerp .oe_view_manager .oe_view_manager_switch li {
text-align: center;
width: 24px;
height: 24px;
line-height: 16px;
+ padding: 0;
}
.openerp .oe_view_manager .oe_view_manager_switch li a {
position: relative;
@@ -1457,10 +1503,10 @@
.openerp .oe_view_manager_current > .oe_view_manager_header .oe_header_row:first-child td {
padding-top: 8px;
}
-.openerp .oe_view_manager_inline {
+.openerp .oe_view_manager_inline, .openerp .oe_view_manager_inlineview {
height: 100%;
}
-.openerp .oe_view_manager_inline > .oe_view_manager_header {
+.openerp .oe_view_manager_inline > .oe_view_manager_header, .openerp .oe_view_manager_inlineview > .oe_view_manager_header {
display: none;
}
.openerp .oe_popup_form > .oe_formview > .oe_form_pager {
@@ -1669,7 +1715,7 @@
}
.openerp .oe_searchview .oe_searchview_drawer h3 {
margin: 8px 4px 4px 12px;
- color: #8786b7;
+ color: #7c7bad;
font-size: 13px;
}
.openerp .oe_searchview .oe_searchview_drawer h4, .openerp .oe_searchview .oe_searchview_drawer h4 * {
@@ -1923,16 +1969,45 @@
width: auto;
}
.openerp .oe_form_nosheet {
- margin: 8px;
+ margin: 16px;
}
.openerp .oe_form_nosheet > header {
- margin-top: -8px;
- margin-left: -8px;
- margin-right: -8px;
+ margin: -16px -16px 0 -16px;
+ padding: 8px;
+}
+.openerp .oe_form_sheetbg {
+ padding: 8px 0;
+}
+.openerp .oe_form_sheet_width {
+ min-width: 650px;
+ max-width: 860px;
+ margin: 0 auto;
+}
+.openerp .oe_form_sheet {
+ background: white;
+ min-height: 330px;
+ padding: 16px;
+}
+.openerp .oe_application .oe_form_sheetbg {
+ background: url(/web/static/src/img/form_sheetbg.png);
+ border-bottom: 1px solid #dddddd;
+}
+.openerp .oe_application .oe_form_sheet {
+ border: 1px solid #afafb6;
+ -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
+ -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
+}
+.openerp .oe_application .oe_form_sheet .ui-tabs {
+ margin: 0 -16px;
+}
+.openerp .oe_application .oe_form_sheet .oe_notebook_page {
+ padding: 0 16px;
}
.openerp .oe_form header {
position: relative;
border-bottom: 1px solid #cacaca;
+ padding-left: 2px;
background-color: #fcfcfc;
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcfcfc), to(#dedede));
background-image: -webkit-linear-gradient(top, #fcfcfc, #dedede);
@@ -1940,163 +2015,166 @@
background-image: -ms-linear-gradient(top, #fcfcfc, #dedede);
background-image: -o-linear-gradient(top, #fcfcfc, #dedede);
background-image: linear-gradient(to bottom, #fcfcfc, #dedede);
- padding: 0 8px;
- line-height: 30px;
}
.openerp .oe_form header ul {
display: inline-block;
float: right;
}
+.openerp .oe_form header .oe_form_button {
+ margin: 3px 2px 1px;
+}
.openerp .oe_form div.oe_chatter {
min-width: 650px;
max-width: 860px;
margin: 0 auto;
+ padding: 16px 0 48px;
}
-.openerp .oe_form div.oe_form_configuration div.oe_horizontal_separator {
- margin: 25px 0 10px 0;
+.openerp .oe_form .oe_grey {
+ color: #aaaaaa;
+ max-width: 650px;
+ margin: 0 0 10px 0;
}
-.openerp .oe_form div.oe_form_configuration p {
+.openerp .oe_form div.oe_form_configuration p, .openerp .oe_form div.oe_form_configuration ul, .openerp .oe_form div.oe_form_configuration ol {
color: #aaaaaa;
max-width: 650px;
}
.openerp .oe_form div.oe_form_configuration label {
min-width: 150px;
}
-.openerp ul.oe_form_steps {
- height: 30px;
- padding: 0;
- margin: 0;
- text-shadow: 0 1px 1px white;
+.openerp .oe_form div.oe_form_configuration .oe_form_group_cell_label {
+ padding: 1px 0;
}
-.openerp ul.oe_form_steps img {
- vertical-align: top;
- margin-left: 8px;
+.openerp .oe_form div.oe_form_configuration .oe_form_group_cell div div {
+ padding: 1px 0;
}
-.openerp ul.oe_form_steps li {
- border-right: none;
- padding: 0;
- margin: 0;
- float: left;
- vertical-align: top;
- height: 30px;
- padding: 0 0 0 12px;
+.openerp .oe_form ul.oe_form_steps, .openerp .oe_form ul.oe_form_steps_clickable {
+ display: inline-block;
+ padding-right: 18px;
}
-.openerp ul.oe_form_steps li:first-child {
+.openerp .oe_form ul.oe_form_steps li, .openerp .oe_form ul.oe_form_steps_clickable li {
+ display: inline-block;
+ margin-right: -20px;
+ background-color: #fcfcfc;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fcfcfc), to(#dedede));
+ background-image: -webkit-linear-gradient(top, #fcfcfc, #dedede);
+ background-image: -moz-linear-gradient(top, #fcfcfc, #dedede);
+ background-image: -ms-linear-gradient(top, #fcfcfc, #dedede);
+ background-image: -o-linear-gradient(top, #fcfcfc, #dedede);
+ background-image: linear-gradient(to bottom, #fcfcfc, #dedede);
+}
+.openerp .oe_form ul.oe_form_steps li:first-child .label, .openerp .oe_form ul.oe_form_steps_clickable li:first-child .label {
border-left: 1px solid #cacaca;
+ padding-left: 14px;
}
-.openerp ul.oe_form_steps li:last-child {
- margin-right: 12px;
- padding-right: 12px;
+.openerp .oe_form ul.oe_form_steps li:last-child, .openerp .oe_form ul.oe_form_steps_clickable li:last-child {
border-right: 1px solid #cacaca;
}
-.openerp ul.oe_form_steps li a {
- color: #4c4c4c;
-}
-.openerp ul.oe_form_steps li a:hover {
- color: black;
+.openerp .oe_form ul.oe_form_steps li:last-child .label, .openerp .oe_form ul.oe_form_steps_clickable li:last-child .label {
+ padding-right: 14px;
}
-.openerp ul.oe_form_steps .oe_form_steps_active {
- font-weight: bold;
- color: #b33630;
+.openerp .oe_form ul.oe_form_steps li:last-child .arrow, .openerp .oe_form ul.oe_form_steps_clickable li:last-child .arrow {
+ display: none;
}
-.openerp ul.oe_form_steps_clickable {
- height: 30px;
+.openerp .oe_form ul.oe_form_steps li .label, .openerp .oe_form ul.oe_form_steps_clickable li .label {
+ color: #4c4c4c;
+ text-shadow: 0 1px 1px #fcfcfc, 0 -1px 1px #dedede;
+ padding: 7px;
+ display: inline-block;
+ padding-left: 24px;
margin: 0;
- padding: 0;
- text-shadow: 0 1px 1px #cacaca;
- box-shadow: 0 0 1px rgba(0, 0, 0, 0.5);
- overflow: hidden;
-}
-.openerp ul.oe_form_steps_clickable li {
- border-right: none;
- padding: 0 0 0 12px;
position: relative;
- float: left;
- vertical-align: top;
- height: 30px;
- color: white;
-}
-.openerp ul.oe_form_steps_clickable li:after {
- content: " ";
- width: 0;
- height: 0;
- border-top: 21px solid transparent;
- border-bottom: 21px solid transparent;
- border-left: 5px solid #807fb4;
- position: absolute;
- top: 50%;
- margin-top: -21px;
- left: 100%;
- z-index: 2;
}
-.openerp ul.oe_form_steps_clickable li:hover:after {
- border-left: 5px solid #807fb4;
-}
-.openerp ul.oe_form_steps_clickable li:before {
- content: " ";
- width: 0;
- height: 0;
- border-top: 21px solid transparent;
- border-bottom: 21px solid transparent;
- border-left: 5px solid white;
- position: absolute;
- top: 50%;
- margin-top: -21px;
- margin-left: 2px;
- left: 100%;
- z-index: 2;
+.openerp .oe_form ul.oe_form_steps li .arrow, .openerp .oe_form ul.oe_form_steps_clickable li .arrow {
+ width: 17px;
+ display: inline-block;
+ vertical-align: top;
+ overflow: hidden;
+ margin-left: -5px;
}
-.openerp ul.oe_form_steps_clickable li.oe_form_steps_active {
- font-weight: bold;
- text-shadow: 0 1px 1px #999999;
- box-shadow: inset 0 -1px 1px rgba(0, 0, 0, 0.25), inset 0 1px 1px rgba(255, 255, 255, 0.25);
- background-color: #dc5f59;
- background: -webkit-linear-gradient(top, #dc5f59, #b33630);
+.openerp .oe_form ul.oe_form_steps li .arrow span, .openerp .oe_form ul.oe_form_steps_clickable li .arrow span {
+ position: relative;
+ width: 24px;
+ height: 24px;
+ display: inline-block;
+ margin-left: -12px;
+ margin-top: 3px;
+ box-shadow: -1px 1px 2px rgba(255, 255, 255, 0.2), inset -1px 1px 1px rgba(0, 0, 0, 0.2);
+ background-color: #dedede;
+ background: -moz-linear-gradient(135deg, #dedede, #fcfcfc);
+ background: -o-linear-gradient(135deg, #fcfcfc, #dedede);
+ background: -webkit-gradient(linear, left top, right bottom, from(#fcfcfc), to(#dedede));
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+ -webkit-transform: rotate(45deg);
+ -moz-transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ -o-transform: rotate(45deg);
+ transform: rotate(45deg);
+}
+.openerp .oe_form ul.oe_form_steps li.oe_active, .openerp .oe_form ul.oe_form_steps_clickable li.oe_active {
+ background-color: #729fcf;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#729fcf), to(#3465a4));
+ background-image: -webkit-linear-gradient(top, #729fcf, #3465a4);
+ background-image: -moz-linear-gradient(top, #729fcf, #3465a4);
+ background-image: -ms-linear-gradient(top, #729fcf, #3465a4);
+ background-image: -o-linear-gradient(top, #729fcf, #3465a4);
+ background-image: linear-gradient(to bottom, #729fcf, #3465a4);
+}
+.openerp .oe_form ul.oe_form_steps li.oe_active .arrow span, .openerp .oe_form ul.oe_form_steps_clickable li.oe_active .arrow span {
+ background-color: #3465a4;
+ background: -moz-linear-gradient(135deg, #3465a4, #729fcf);
+ background: -o-linear-gradient(135deg, #729fcf, #3465a4);
+ background: -webkit-gradient(linear, left top, right bottom, from(#729fcf), to(#3465a4));
+}
+.openerp .oe_form ul.oe_form_steps li.oe_active .label, .openerp .oe_form ul.oe_form_steps_clickable li.oe_active .label {
color: white;
+ text-shadow: 0 1px 1px #729fcf, 0 -1px 1px #3465a4;
}
-.openerp ul.oe_form_steps_clickable li.oe_form_steps_inactive {
+.openerp .oe_form ul.oe_form_steps_clickable li {
cursor: pointer;
- box-shadow: inset 0 -1px 1px rgba(0, 0, 0, 0.25), inset 0 1px 1px rgba(255, 255, 255, 0.25);
- background-color: #adadcf;
- background: -webkit-linear-gradient(top, #adadcf, #7c7ba7);
-}
-.openerp ul.oe_form_steps_clickable li.oe_form_steps_inactive div {
- padding: 0 30px 0 0;
-}
-.openerp ul.oe_form_steps_clickable li.oe_form_steps_inactive:hover {
- background: -webkit-linear-gradient(top, #7c7ba7, #adadcf);
-}
-.openerp ul.oe_form_steps_clickable li div {
- padding: 0 30px 0 0;
-}
-.openerp ul.oe_form_steps_clickable li.oe_form_steps_active:after {
- content: " ";
- display: block;
- width: 0;
- height: 0;
- border-top: 21px solid transparent;
- border-bottom: 21px solid transparent;
- border-left: 5px solid #b33630;
- position: absolute;
- top: 50%;
- margin-top: -21px;
- left: 100%;
- z-index: 2;
}
-.openerp ul.oe_form_steps_clickable li.oe_form_steps_active:before {
- content: " ";
- display: block;
- width: 0;
- height: 0;
- border-top: 21px solid transparent;
- border-bottom: 21px solid transparent;
- border-left: 5px solid white;
- position: absolute;
- top: 50%;
- margin-top: -21px;
- margin-left: 2px;
- left: 100%;
- z-index: 2;
+.openerp .oe_form ul.oe_form_steps_clickable li:hover {
+ background-color: #e8e8e8;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#cacaca));
+ background-image: -webkit-linear-gradient(top, #e8e8e8, #cacaca);
+ background-image: -moz-linear-gradient(top, #e8e8e8, #cacaca);
+ background-image: -ms-linear-gradient(top, #e8e8e8, #cacaca);
+ background-image: -o-linear-gradient(top, #e8e8e8, #cacaca);
+ background-image: linear-gradient(to bottom, #e8e8e8, #cacaca);
+}
+.openerp .oe_form ul.oe_form_steps_clickable li:hover .label {
+ text-shadow: 0 -1px 1px #fcfcfc, 0 1px 1px #dedede;
+}
+.openerp .oe_form ul.oe_form_steps_clickable li:hover .arrow span {
+ background-color: #e8e8e8;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#cacaca));
+ background-image: -webkit-linear-gradient(top, #e8e8e8, #cacaca);
+ background-image: -moz-linear-gradient(top, #e8e8e8, #cacaca);
+ background-image: -ms-linear-gradient(top, #e8e8e8, #cacaca);
+ background-image: -o-linear-gradient(top, #e8e8e8, #cacaca);
+ background-image: linear-gradient(to bottom, #e8e8e8, #cacaca);
+}
+.openerp .oe_form ul.oe_form_steps_clickable li .label {
+ color: #7c7bad;
+}
+.openerp .oe_form ul.oe_form_steps_clickable li.oe_active:hover {
+ background-color: #4c85c2;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#4c85c2), to(#284d7d));
+ background-image: -webkit-linear-gradient(top, #4c85c2, #284d7d);
+ background-image: -moz-linear-gradient(top, #4c85c2, #284d7d);
+ background-image: -ms-linear-gradient(top, #4c85c2, #284d7d);
+ background-image: -o-linear-gradient(top, #4c85c2, #284d7d);
+ background-image: linear-gradient(to bottom, #4c85c2, #284d7d);
+}
+.openerp .oe_form ul.oe_form_steps_clickable li.oe_active:hover .label {
+ text-shadow: 0 -1px 1px #729fcf, 0 1px 1px #3465a4;
+}
+.openerp .oe_form ul.oe_form_steps_clickable li.oe_active:hover .arrow span {
+ background-color: #284d7d;
+ background: -moz-linear-gradient(135deg, #284d7d, #4c85c2);
+ background: -o-linear-gradient(135deg, #4c85c2, #284d7d);
+ background: -webkit-gradient(linear, left top, right bottom, from(#4c85c2), to(#284d7d));
}
.openerp .oe_form .oe_subtotal_footer {
width: 1% !important;
@@ -2124,45 +2202,20 @@
.openerp .oe_form .oe_subtotal_footer label.oe_form_label_help {
font-weight: normal;
}
-.openerp .oe_application .oe_form_sheetbg {
- background: url(/web/static/src/img/form_sheetbg.png);
- padding: 8px 0;
- border-bottom: 1px solid #dddddd;
-}
-.openerp .oe_application .oe_form_sheet_width {
- min-width: 650px;
- max-width: 860px;
- margin: 0 auto;
-}
-.openerp .oe_application .oe_form_sheet {
- background: white;
- min-height: 330px;
- padding: 16px;
- border: 1px solid #afafb6;
- -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
- -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
- box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
-}
-.openerp .oe_application .oe_form_sheet .ui-tabs {
- margin: 0 -16px;
-}
-.openerp .oe_application .oe_form_sheet .oe_notebook_page {
- padding: 0 16px;
-}
.openerp .oe_form .oe_form_button {
margin: 2px;
}
.openerp .oe_form td.oe_form_group_cell_label {
border-right: 1px solid #dddddd;
- padding: 4px 0px 4px 0px;
+ padding: 2px 0px;
}
.openerp .oe_form td.oe_form_group_cell_label label {
line-height: 18px;
display: block;
- min-width: 120px;
+ min-width: 140px;
}
.openerp .oe_form td.oe_form_group_cell + .oe_form_group_cell {
- padding-left: 6px;
+ padding: 2px 0 2px 8px;
}
.openerp .oe_form .oe_form_group {
width: 100%;
@@ -2174,7 +2227,7 @@
.openerp .oe_form .oe_form_label_help[for], .openerp .oe_form .oe_form_label[for] {
font-weight: bold;
white-space: nowrap;
- padding-right: 6px;
+ padding-right: 8px;
}
.openerp .oe_form .oe_form_label_help[for] span, .openerp .oe_form .oe_form_label[for] span {
font-size: 80%;
@@ -2190,8 +2243,8 @@
.openerp .oe_horizontal_separator {
font-weight: bold;
font-size: 20px;
- margin: 8px 0px 8px 0px;
- color: #53637e;
+ margin: 15px 0px 10px 0px;
+ color: #7c7bad;
}
.openerp .oe_horizontal_separator:empty {
height: 5px;
@@ -2250,7 +2303,6 @@
width: 100%;
display: inline-block;
padding: 2px 2px 2px 0px;
- line-height: 1em;
}
.openerp .oe_form .oe_form_field input {
margin: 0px;
@@ -2265,7 +2317,7 @@
-ms-box-sizing: border-box;
box-sizing: border-box;
background: white;
- min-width: 70px;
+ min-width: 60px;
color: #1f1f1f;
}
.openerp .oe_form input[readonly], .openerp .oe_form select[readonly], .openerp .oe_form textarea[readonly], .openerp .oe_form input[disabled], .openerp .oe_form select[disabled] {
@@ -2404,6 +2456,35 @@
float: right;
padding-left: 2px;
}
+.openerp.ui-autocomplete li.oe_m2o_dropdown_option a {
+ font-style: italic;
+ padding-left: 2em;
+}
+.openerp.ui-autocomplete li:not(.oe_m2o_dropdown_option) + li.oe_m2o_dropdown_option {
+ margin-top: 10px;
+}
+.openerp .oe_form_field_status {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_form_field_status ul, .openerp .oe_form_field_status ol {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_form_field_status ul ul, .openerp .oe_form_field_status ul ol, .openerp .oe_form_field_status ul li, .openerp .oe_form_field_status ol ul, .openerp .oe_form_field_status ol ol, .openerp .oe_form_field_status ol li {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_form_field_status ul li, .openerp .oe_form_field_status ol li {
+ list-style-type: none;
+}
+.openerp .oe_form_field_status ul, .openerp .oe_form_field_status ol, .openerp .oe_form_field_status li {
+ margin: 0;
+ padding: 0;
+}
+.openerp .oe_form_field_status li {
+ list-style-type: none;
+}
.openerp .oe_form .oe_form_field_one2many > .oe_view_manager .oe_list_pager_single_page {
display: none;
}
@@ -2468,10 +2549,11 @@
height: 27px;
}
.openerp .oe_list.oe_list_editable.oe_editing .oe_form_field input, .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field textarea {
+ -moz-border-radius: 0;
+ -webkit-border-radius: 0;
+ border-radius: 0;
border: 1px solid #aaaaff;
- border-radius: 0px;
- margin: 0px;
- -webkit-border-radius: 0px;
+ margin: 0;
}
.openerp .oe_list.oe_list_editable.oe_editing .oe_form_field textarea {
height: 60px;
@@ -2492,10 +2574,13 @@
.openerp .oe_form .oe_form_field_many2many > .oe_list .oe_list_pager_single_page {
display: none;
}
+.openerp .oe_list_buttons .oe_alternative {
+ visibility: hidden;
+}
.openerp .oe_list_buttons .oe_list_save, .openerp .oe_list_buttons .oe_list_discard {
display: none;
}
-.openerp .oe_list_buttons.oe_editing .oe_list_add, .openerp .oe_list_buttons.oe_editing .oe_list_button_import {
+.openerp .oe_list_buttons.oe_editing .oe_list_add {
display: none;
}
.openerp .oe_list_buttons.oe_editing .oe_list_save {
@@ -2504,6 +2589,9 @@
.openerp .oe_list_buttons.oe_editing .oe_list_discard {
display: inline;
}
+.openerp .oe_list_buttons.oe_editing .oe_alternative {
+ visibility: visible;
+}
.openerp .oe_list {
position: relative;
}
@@ -2518,6 +2606,15 @@
margin: 0 !important;
padding: 0;
}
+.openerp .oe_list .oe_list_content .oe_group_header {
+ background-color: #fcfcfc;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fcfcfc), to(#dedede));
+ background-image: -webkit-linear-gradient(top, #fcfcfc, #dedede);
+ background-image: -moz-linear-gradient(top, #fcfcfc, #dedede);
+ background-image: -ms-linear-gradient(top, #fcfcfc, #dedede);
+ background-image: -o-linear-gradient(top, #fcfcfc, #dedede);
+ background-image: linear-gradient(to bottom, #fcfcfc, #dedede);
+}
.openerp .oe_list_content {
width: 100%;
}
@@ -2571,6 +2668,7 @@
cursor: pointer;
}
.openerp .oe_list_content > tbody > tr {
+ height: 27px;
border-top: 1px solid #dddddd;
}
.openerp .oe_list_content > tbody > tr > td.oe_list_field_cell {
@@ -2633,6 +2731,12 @@
content: "ö";
color: #404040;
}
+.openerp .oe_list_cannot_edit .oe_list_header_handle, .openerp .oe_list_cannot_edit .oe_list_field_handle {
+ display: none !important;
+}
+.openerp .oe_list_cannot_delete .oe_list_record_delete {
+ display: none !important;
+}
.openerp .tree_header {
background-color: #f0f0f0;
border-bottom: 1px solid #cacaca;
@@ -2728,6 +2832,16 @@
float: right;
color: #333333;
}
+.openerp .oe_semantic_html li {
+ list-style-type: disc;
+ display: list-item;
+}
+.openerp .oe_semantic_html ul {
+ padding-left: 1em;
+}
+.openerp .oe_semantic_html p {
+ color: #4c4c4c !important;
+}
.kitten-mode-activated {
background-image: url(http://placekitten.com/g/1365/769);
@@ -2743,3 +2857,42 @@ div.ui-widget-overlay {
filter: alpha(opacity=30);
opacity: 0.3;
}
+
+.ui-widget {
+ font-family: "Lucida Grande", Helvetica, Verdana, Arial, sans-serif;
+ color: #4c4c4c;
+ font-size: 13px;
+}
+
+.ui-menu {
+ padding: 2px 0;
+ -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
+ -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
+ margin-top: 4px;
+ border: 1px solid #afafb6;
+}
+.ui-menu .ui-menu-item {
+ width: 100%;
+ padding: 0;
+}
+.ui-menu .ui-menu-item a {
+ padding: 1px 16px;
+}
+.ui-menu .ui-menu-item a.ui-corner-all {
+ -moz-border-radius: 0;
+ -webkit-border-radius: 0;
+ border-radius: 0;
+}
+.ui-menu .ui-menu-item a.ui-state-active {
+ background: #f0f0fa;
+}
+.ui-menu .ui-menu-item a.ui-state-hover, .ui-menu .ui-menu-item a.ui-state-active {
+ background: #7c7bad;
+}
+
+.ui-corner-all {
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+}
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index f1d1f2e9f1f..1f332756cf7 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -2,13 +2,13 @@
// Variables {{{
$facets-border: #afafb6
-$section-title-color: #8786b7
+$section-title-color: #7C7BAD
$tag-bg-light: #f0f0fa
-$tag-bg-dark: #8786b7
+$tag-bg-dark: #7C7BAD
$tag-border: #afafb6
$tag-border-selected: #a6a6fe
$hover-background: #f0f0fa
-$link-color: #8a89ba
+$link-color: #7C7BAD
$sheet-max-width: 860px
// }}}
// Mixins {{{
@@ -36,7 +36,7 @@ $sheet-max-width: 860px
padding: 0
margin: 0
background: none
- @include radius(none)
+ @include radius(0)
@include box-shadow(none)
@mixin vertical-gradient($startColor: #555, $endColor: #333)
@@ -88,6 +88,31 @@ $sheet-max-width: 860px
-ms-box-sizing: #{$type}-box
box-sizing: #{$type}-box
+@mixin skew-gradient($startColor: #555, $endColor: #333)
+ background-color: $endColor
+ background: -moz-linear-gradient(135deg, $endColor, $startColor)
+ background: -o-linear-gradient(135deg, $startColor, $endColor)
+ background: -webkit-gradient(linear, left top, right bottom, from($startColor), to($endColor))
+
+@mixin transform($transform)
+ -webkit-transform: $transform
+ -moz-transform: $transform
+ -ms-transform: $transform
+ -o-transform: $transform
+ transform: $transform
+
+@mixin keyframes($name)
+ @-webkit-keyframes #{$name}
+ @content
+ @-moz-keyframes #{$name}
+ @content
+ @-ms-keyframes #{$name}
+ @content
+ @-o-keyframes #{$name}
+ @content
+ @keyframes #{$name}
+ @content
+
// Transforms the (readable) text of an inline element into an mmlicons icon,
// allows for actual readable text in-code (and in readers?) with iconic looks
@mixin text-to-icon($icon-name, $color: #404040)
@@ -99,37 +124,25 @@ $sheet-max-width: 860px
content: $icon-name
color: $color
-// }}}
-// CSS animation bounces {{{
-@-moz-keyframes bounce
- 0%
- -moz-transform: scale(0)
- opacity: 0
- 50%
- -moz-transform: scale(1.3)
- opacity: 0.4
- 75%
- -moz-transform: scale(0.9)
- opacity: 0.7
- 100%
- -moz-transform: scale(1)
- opacity: 1
+@mixin ul-html-override()
+ margin: 0
+ padding: 0
+ ul, ol, li
+ margin: 0
+ padding: 0
+ li
+ list-style-type: none
+
+@mixin semantic-html-override()
+ ul, ol
+ @include ul-html-override()
-@-webkit-keyframes bounce
- 0%
- -webkit-transform: scale(0)
- opacity: 0
- 50%
- -webkit-transform: scale(1.3)
- opacity: 0.4
- 75%
- -webkit-transform: scale(0.9)
- opacity: 0.7
- 100%
- -webkit-transform: scale(1)
- opacity: 1
// }}}
+@media print
+ .oe_topbar, .oe_leftbar, .oe_loading
+ display: none !important
+
.openerp.openerp_webclient_container
height: 100%
position: relative
@@ -142,13 +155,14 @@ $sheet-max-width: 860px
color: #4c4c4c
font-size: 13px
background: white
+ text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5)
// }}}
//Placeholder style{{{
\:-moz-placeholder
- color: $facets-border !important
+ color: $tag-border !important
font-style: italic !important
\::-webkit-input-placeholder
- color: $facets-border !important
+ color: $tag-border !important
font-style: italic !important
//}}}
// Tag reset {{{
@@ -161,7 +175,7 @@ $sheet-max-width: 860px
font-weight: bold
background-color: #f0f0f0
th
- border-right: 1px dotted $facets-border
+ border-right: 1px dotted $tag-border
&:last-child
border-right: none
th, td
@@ -177,11 +191,6 @@ $sheet-max-width: 860px
@include vertical-gradient(#f0f0fa, #eeeef6)
.zebra tbody tr:hover td
@include vertical-gradient(#eee, #dedede)
- ul, li, ol
- margin: 0
- padding: 0
- li
- list-style-type: none
input, textarea, select
padding: 2px 4px
border: 1px solid #ccc
@@ -191,12 +200,16 @@ $sheet-max-width: 860px
vertical-align: middle
h4
margin: 4px 0
+ .oe_semantic_html_override
+ @include semantic-html-override
+ ul.oe_semantic_html_override
+ @include ul-html-override
// }}}
// Button style {{{
a.button:link, a.button:visited, button, input[type='submit'], .ui-dialog-buttonpane .ui-dialog-buttonset .ui-button
display: inline-block
border: 1px solid #ababab
- color: #404040
+ color: #4c4c4c
margin: 0
padding: 3px 12px
font-size: 13px
@@ -232,18 +245,10 @@ $sheet-max-width: 860px
text-shadow: 0 1px 1px #fff !important
// }}}
// Jquery ui Overrides {{{
- .ui-widget
- font-family: "Lucida Grande", Helvetica, Verdana, Arial, sans-serif
- font-size: 13px
.ui-widget-content a
color: $link-color
- .ui-menu
- .ui-menu-item
- margin: 0 8px 0 0
- padding: 0 0 0 12px
- width: auto
- a.ui-state-active
- background: #f0f0fa
+ .oe_bounce_container
+ display: inline-block
// Modal box
&.ui-dialog
@@ -374,15 +379,16 @@ $sheet-max-width: 860px
color: white
background: #DC5F59
button.oe_highlight
- @include vertical-gradient(#dc5f59, #b33630)
- @include box-shadow(none)
- button.oe_highlight:active
- @include vertical-gradient(#b33630, #dc5f59)
- @include box-shadow(none)
+ border: 1px solid #795151
+ @include vertical-gradient(#df3f3f, #a21a1a)
+ @include box-shadow((0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset))
button.oe_highlight:hover
- @include vertical-gradient(#DF6B66, #BF3A33)
- //@include vertical-gradient(lighten(#dc5f59, 3%), lighten(#b33630, 3%))
- @include box-shadow(0 0 1px rgba(0, 0, 0, 0.2))
+ @include vertical-gradient(lighten(#e04f4f, 2%), lighten(#a21a1a, 2%))
+ button.oe_highlight:active
+ @include vertical-gradient(lighten(#a21a1a, 8%), darken(#df3f3f, 8%))
+ .oe_background_grey
+ background: #eee !important
+
.oe_form_dirty
.oe_highlight_on_dirty
color: white
@@ -409,11 +415,12 @@ $sheet-max-width: 860px
margin: 4px
.oe_avatar
> img
- height: 90px
- max-width: 100px
+ max-height: 90px
+ max-width: 90px
@include radius(3px)
- @include box-shadow(0 1px 3px rgba(0, 0, 0, 0.3))
+ @include box-shadow(0 1px 4px rgba(0, 0, 0, 0.4))
border: none
+ margin-bottom: 10px
.oe_avatar + div
margin-left: 5px
.oe_image_small > img
@@ -467,6 +474,7 @@ $sheet-max-width: 860px
.text-core .text-wrap .text-dropdown .text-list .text-suggestion em
font-style: italic
text-decoration: none
+ margin-bottom: 1px
// }}}
// Tooltips {{{
&.oe_tooltip
@@ -501,6 +509,8 @@ $sheet-max-width: 860px
padding: 0 16px
list-style: none
zoom: 1
+ @include ul-html-override
+ @include semantic-html-override
.oe_notebook.ui-corner-all
@include radius(0)
.oe_notebook:before, .oe_notebook:after
@@ -557,7 +567,7 @@ $sheet-max-width: 860px
top: 26px
left: 0
z-index: 1
- border: 1px solid $facets-border
+ border: 1px solid $tag-border
background: white
padding: 4px 0
min-width: 140px
@@ -679,7 +689,7 @@ $sheet-max-width: 860px
font-family: "Lucida Grande", Helvetica, Verdana, Arial
border: 1px solid #999999
background: whitesmoke
- @include box-shadow(inset 0 1px 4px rgba(0, 0, 0, 0.3))
+ @include box-shadow(inset 0 1px 4px rgba(0, 0, 0, 0.4))
@include radius(3px)
input
margin-bottom: 9px
@@ -720,6 +730,7 @@ $sheet-max-width: 860px
text-align: left
@include radius(8px)
@include box-shadow(0 0 18px rgba(0, 0, 0, 0.9))
+ @include semantic-html-override
h2
margin-top: 0
font-size: 18px
@@ -783,8 +794,8 @@ $sheet-max-width: 860px
.oe_topbar
width: 100%
height: 31px
- border-top: solid 1px #d3d3d3
@include vertical-gradient(#646060, #262626)
+ @include semantic-html-override
.oe_topbar_item
display: block
padding: 5px 10px 7px
@@ -797,11 +808,6 @@ $sheet-max-width: 860px
background: #303030
color: white
@include box-shadow(0 1px 2px rgba(255,255,255,0.3) inset)
- .oe_active
- background: #303030
- font-weight: bold
- color: white
- @include box-shadow(0 1px 2px rgba(255,255,255,0.3) inset)
.oe_topbar_avatar
width: 24px
@@ -837,9 +843,10 @@ $sheet-max-width: 860px
display: none
width: 220px
background: #f0eeee
- border-right: 1px solid $facets-border
+ border-right: 1px solid $tag-border
text-shadow: 0 1px 1px white
padding-bottom: 16px
+ @include semantic-html-override
a.oe_logo
width: 220px
display: block
@@ -889,25 +896,25 @@ $sheet-max-width: 860px
float: left
padding: 0
margin: 0
- li
+ > li
float: left
- a
- display: block
- padding: 5px 10px 7px
- line-height: 20px
- height: 20px
- color: #eee
- vertical-align: top
- text-shadow: 0 1px 1px rgba(0,0,0,0.2)
- &:hover
+ > a
+ display: block
+ padding: 5px 10px 7px
+ line-height: 20px
+ height: 20px
+ color: #eee
+ vertical-align: top
+ text-shadow: 0 1px 1px rgba(0,0,0,0.2)
+ &:hover
+ background: #303030
+ color: white
+ @include box-shadow(0 1px 2px rgba(255,255,255,0.3) inset)
+ > .oe_active
background: #303030
+ font-weight: bold
color: white
@include box-shadow(0 1px 2px rgba(255,255,255,0.3) inset)
- .oe_active
- background: #303030
- font-weight: bold
- color: white
- @include box-shadow(0 1px 2px rgba(255,255,255,0.3) inset)
.oe_secondary_menu_section
font-weight: bold
margin-left: 8px
@@ -917,9 +924,9 @@ $sheet-max-width: 860px
margin: 0
width: 100%
display: inline-block
- > li
+ li
position: relative
- padding: 1px 0 1px 20px
+ padding: 1px 0 1px 20px !important
a
display: block
color: #4c4c4c
@@ -940,14 +947,18 @@ $sheet-max-width: 860px
.oe_menu_counter
float: right
text-shadow: 0 1px 1px rgba(0,0,0,0.2)
- margin: 0px
+ margin: 1px
padding: 1px 4px
+ border: none
+ &:hover
+ cursor: pointer
+ @include transform(scale(1.1))
.oe_active
- background: $link-color
border-top: 1px solid lightGray
- border-bottom: 1px solid lightGray
+ border-bottom: 1px solid #dedede
text-shadow: 0 1px 1px rgba(0,0,0,0.2)
- @include box-shadow(inset 0 1px 1px rgba(0, 0, 0, 0.2))
+ @include box-shadow((inset 0 1px 3px rgba(0, 0, 0, 0.2), inset 0 -1px 3px rgba(40, 40, 40, 0.2)))
+ background: $link-color
a
color: white
.oe_menu_label
@@ -958,6 +969,7 @@ $sheet-max-width: 860px
.oe_menu_counter
background: #eee
color: $link-color
+ @include box-shadow(inset 0 1px 2px rgba(0, 0, 0, 0.2))
.oe_menu_toggler:before
width: 0
height: 0
@@ -1000,6 +1012,14 @@ $sheet-max-width: 860px
table.oe_view_manager_header
width: 100%
table-layout: fixed
+ ul
+ padding: 0
+ margin-right: 0
+ margin-top: 0
+ margin-bottom: 0
+ li
+ list-style-type: none
+ margin: 0
.oe_header_row
//min-height: 26px
//line-height: 26px
@@ -1008,6 +1028,9 @@ $sheet-max-width: 860px
.oe_header_row:last-child
td
padding-top: 0
+ .oe_header_row:first-child
+ td
+ padding-top: 8px
.oe_view_manager_sidebar
margin: 0px auto
text-align: center
@@ -1019,6 +1042,8 @@ $sheet-max-width: 860px
float: left
a
color: $link-color
+ .oe_dropdown_menu
+ line-height: normal
.oe_button_group
display: inline-block
border: 1px solid #ababab
@@ -1079,11 +1104,13 @@ $sheet-max-width: 860px
// }}}
// ViewManager.switches {{{
.oe_view_manager_switch
+ margin-left: 8px
li
text-align: center
width: 24px
height: 24px
line-height: 16px
+ padding: 0
a
position: relative
.oe_vm_switch_list:after, .oe_vm_switch_tree:after
@@ -1128,7 +1155,7 @@ $sheet-max-width: 860px
padding-top: 8px
// }}}
// ViewManager inline {{{
- .oe_view_manager_inline
+ .oe_view_manager_inline, .oe_view_manager_inlineview
height: 100%
> .oe_view_manager_header
display: none
@@ -1278,7 +1305,7 @@ $sheet-max-width: 860px
background-color: white
min-width: 100%
display: none
- border: 1px solid $facets-border
+ border: 1px solid $tag-border
text-align: left
@include radius(4px)
@include box-shadow(0 1px 4px rgba(0,0,0,0.3))
@@ -1484,191 +1511,152 @@ $sheet-max-width: 860px
display: none !important
.oe_form .oe_form_field_date
width: auto
+ // Sheet and padding
.oe_form_nosheet
- margin: 8px
- .oe_form_nosheet > header
- margin-top: -8px
- margin-left: -8px
- margin-right: -8px
+ margin: 16px
+ > header
+ margin: -16px -16px 0 -16px
+ padding: 8px
+ .oe_form_sheetbg
+ padding: 8px 0
+ .oe_form_sheet_width
+ min-width: 650px
+ max-width: $sheet-max-width
+ margin: 0 auto
+ .oe_form_sheet
+ background: white
+ min-height: 330px
+ padding: 16px
+ // Sheet inline mode
+ .oe_application
+ .oe_form_sheetbg
+ background: url(/web/static/src/img/form_sheetbg.png)
+ border-bottom: 1px solid #ddd
+ .oe_form_sheet
+ border: 1px solid $tag-border
+ @include box-shadow(0 0 10px rgba(0,0,0,0.3))
+ .ui-tabs
+ margin: 0 -16px
+ .oe_notebook_page
+ padding: 0 16px
// }}}
// FormView.custom tags and classes {{{
.oe_form
header
position: relative
border-bottom: 1px solid #cacaca
+ padding-left: 2px
@include vertical-gradient(#fcfcfc, #dedede)
- padding: 0 8px
- line-height: 30px
ul
display: inline-block
float: right
+ .oe_form_button
+ margin: 3px 2px 1px
div.oe_chatter
min-width: 650px
max-width: $sheet-max-width
margin: 0 auto
+ padding: 16px 0 48px
+ .oe_grey
+ color: #aaa
+ max-width: 650px
+ margin: 0 0 10px 0
div.oe_form_configuration
- div.oe_horizontal_separator
- margin: 25px 0 10px 0
- p
+ p, ul, ol
color: #aaa
max-width: 650px
label
min-width: 150px
- ul.oe_form_steps
- height: 30px
- padding: 0
- margin: 0
- text-shadow: 0 1px 1px white
- img
- vertical-align: top
- margin-left: 8px
- li
- border-right: none
- padding: 0
- margin: 0
- float: left
- vertical-align: top
- height: 30px
- padding: 0 0 0 12px
- &:first-child
- border-left: 1px solid #cacaca
- &:last-child
- margin-right: 12px
- padding-right: 12px
- border-right: 1px solid #cacaca
- a
- color: #4c4c4c
- &:hover
- color: black
- .oe_form_steps_active
- font-weight: bold
- color: #b33630
- ul.oe_form_steps_clickable
- height: 30px
- margin: 0
- padding: 0
- text-shadow: 0 1px 1px #cacaca
- box-shadow: 0 0 1px rgba(0,0,0,0.5)
- overflow: hidden
- li
- border-right: none
- padding: 0 0 0 12px
- position: relative
- float: left
- vertical-align: top
- height: 30px
- color: white
- &:after
- content: " "
- width: 0
- height: 0
- border-top: 21px solid transparent
- border-bottom: 21px solid transparent
- border-left: 5px solid #807fb4
- position: absolute
- top: 50%
- margin-top: -21px
- left: 100%
- z-index: 2
- &:hover:after
- border-left: 5px solid #807fb4
- &:before
- content: " "
- width: 0
- height: 0
- border-top: 21px solid transparent
- border-bottom: 21px solid transparent
- border-left: 5px solid white
- position: absolute
- top: 50%
- margin-top: -21px
- margin-left: 2px
- left: 100%
- z-index: 2
- &.oe_form_steps_active
- font-weight: bold
- text-shadow: 0 1px 1px #999999
- box-shadow: inset 0 -1px 1px rgba(0,0,0,0.25), inset 0 1px 1px rgba(255,255,255,0.25)
- background-color: #dc5f59
- background: -webkit-linear-gradient(top, #dc5f59, #b33630)
- color: white
- &.oe_form_steps_inactive
+ .oe_form_group_cell_label
+ padding: 1px 0
+ .oe_form_group_cell div div
+ padding: 1px 0
+ ul.oe_form_steps, ul.oe_form_steps_clickable
+ display: inline-block
+ padding-right: 18px
+ li
+ display: inline-block
+ margin-right: -20px
+ @include vertical-gradient(#fcfcfc, #dedede)
+ &:first-child .label
+ border-left: 1px solid #cacaca
+ padding-left: 14px
+ &:last-child
+ border-right: 1px solid #cacaca
+ .label
+ padding-right: 14px
+ .arrow
+ display: none
+ .label
+ color: #4c4c4c
+ text-shadow: 0 1px 1px #fcfcfc, 0 -1px 1px #dedede
+ padding: 7px
+ display: inline-block
+ padding-left: 24px
+ margin: 0
+ position: relative
+ .arrow
+ width: 17px
+ display: inline-block
+ vertical-align: top
+ overflow: hidden
+ margin-left: -5px
+ span
+ position: relative
+ width: 24px
+ height: 24px
+ display: inline-block
+ margin-left: -12px
+ margin-top: 3px
+ box-shadow: -1px 1px 2px rgba(255,255,255,0.2), inset -1px 1px 1px rgba(0,0,0,0.2)
+ @include skew-gradient(#fcfcfc, #dedede)
+ @include radius(3px)
+ @include transform(rotate(45deg))
+ li.oe_active
+ @include vertical-gradient(#729fcf, #3465a4)
+ .arrow span
+ @include skew-gradient(#729fcf, #3465a4)
+ .label
+ color: white
+ text-shadow: 0 1px 1px #729fcf, 0 -1px 1px #3465a4
+ ul.oe_form_steps_clickable
+ li
cursor: pointer
- box-shadow: inset 0 -1px 1px rgba(0,0,0,0.25), inset 0 1px 1px rgba(255,255,255,0.25)
- background-color: #adadcf
- background: -webkit-linear-gradient(top, #adadcf, #7c7ba7)
- div
- padding: 0 30px 0 0
- &.oe_form_steps_inactive:hover
- background: -webkit-linear-gradient(top, #7c7ba7, #adadcf)
- div
- padding: 0 30px 0 0
- &.oe_form_steps_active:after
- content: " "
- display: block
- width: 0
- height: 0
- border-top: 21px solid transparent
- border-bottom: 21px solid transparent
- border-left: 5px solid #b33630
- position: absolute
- top: 50%
- margin-top: -21px
- left: 100%
- z-index: 2
- &.oe_form_steps_active:before
- content: " "
- display: block
- width: 0
- height: 0
- border-top: 21px solid transparent
- border-bottom: 21px solid transparent
- border-left: 5px solid white
- position: absolute
- top: 50%
- margin-top: -21px
- margin-left: 2px
- left: 100%
- z-index: 2
- .oe_form .oe_subtotal_footer
- width: 1% !important
- td.oe_form_group_cell
- text-align: right
- padding: 0 !important
- td.oe_form_group_cell_label
- border-right: none
- .oe_subtotal_footer_separator
- width: 108px
- border-top: 1px solid #cacaca
- font-weight: bold
- font-size: 18px
- label:after
- content: ":"
- label.oe_subtotal_footer_separator
- font-weight: bold !important
- padding: 2px 11px 2px 0px !important
- label.oe_form_label_help
- font-weight: normal
- // no sheet in popups
- .oe_application
- .oe_form_sheetbg
- background: url(/web/static/src/img/form_sheetbg.png)
- padding: 8px 0
- border-bottom: 1px solid #ddd
- .oe_form_sheet_width
- min-width: 650px
- max-width: $sheet-max-width
- margin: 0 auto
- .oe_form_sheet
- background: white
- min-height: 330px
- padding: 16px
- border: 1px solid $facets-border
- @include box-shadow(0 0 10px rgba(0,0,0,0.3))
- .ui-tabs
- margin: 0 -16px
- .oe_notebook_page
- padding: 0 16px
+ &:hover
+ @include vertical-gradient(darken(#fcfcfc, 8%), darken(#dedede, 8%))
+ .label
+ text-shadow: 0 -1px 1px #fcfcfc, 0 1px 1px #dedede
+ .arrow span
+ @include vertical-gradient(darken(#fcfcfc, 8%), darken(#dedede, 8%))
+ .label
+ color: $link-color
+ li.oe_active
+ &:hover
+ @include vertical-gradient(darken(#729fcf, 10%), darken(#3465a4, 10%))
+ .label
+ text-shadow: 0 -1px 1px #729fcf, 0 1px 1px #3465a4
+ .arrow span
+ @include skew-gradient(darken(#729fcf, 10%), darken(#3465a4, 10%))
+ .oe_subtotal_footer
+ width: 1% !important
+ td.oe_form_group_cell
+ text-align: right
+ padding: 0 !important
+ td.oe_form_group_cell_label
+ border-right: none
+ .oe_subtotal_footer_separator
+ width: 108px
+ border-top: 1px solid #cacaca
+ font-weight: bold
+ font-size: 18px
+ label:after
+ content: ":"
+ label.oe_subtotal_footer_separator
+ font-weight: bold !important
+ padding: 2px 11px 2px 0px !important
+ label.oe_form_label_help
+ font-weight: normal
+
// }}}
// FormView.group {{{
.oe_form
@@ -1676,13 +1664,13 @@ $sheet-max-width: 860px
margin: 2px
td.oe_form_group_cell_label
border-right: 1px solid #ddd
- padding: 4px 0px 4px 0px
+ padding: 2px 0px
label
line-height: 18px
display: block
- min-width: 120px
+ min-width: 140px
td.oe_form_group_cell + .oe_form_group_cell
- padding-left: 6px
+ padding: 2px 0 2px 8px
.oe_form_group
width: 100%
margin: 9px 0 9px 0
@@ -1694,7 +1682,7 @@ $sheet-max-width: 860px
.oe_form_label_help[for], .oe_form_label[for]
font-weight: bold
white-space: nowrap
- padding-right: 6px
+ padding-right: 8px
span
font-size: 80%
color: darkGreen
@@ -1709,8 +1697,8 @@ $sheet-max-width: 860px
.oe_horizontal_separator
font-weight: bold
font-size: 20px
- margin: 8px 0px 8px 0px
- color: #53637e
+ margin: 15px 0px 10px 0px
+ color: $section-title-color
.oe_horizontal_separator:empty
height: 5px
.oe_vertical_separator
@@ -1757,7 +1745,6 @@ $sheet-max-width: 860px
width: 100%
display: inline-block
padding: 2px 2px 2px 0px
- line-height: 1em
input
margin: 0px
input[type="text"], input[type="password"], input[type="file"], select
@@ -1766,7 +1753,7 @@ $sheet-max-width: 860px
input[type="text"], input[type="password"], input[type="file"], select, textarea
@include box-sizing(border)
background: white
- min-width: 70px
+ min-width: 60px
color: #1f1f1f
input[readonly], select[readonly], textarea[readonly], input[disabled], select[disabled]
background: #E5E5E5 !important
@@ -1883,6 +1870,17 @@ $sheet-max-width: 860px
line-height: 14px
float: right
padding-left: 2px
+ &.ui-autocomplete
+ li.oe_m2o_dropdown_option a
+ font-style: italic
+ padding-left: 2em
+ li:not(.oe_m2o_dropdown_option) + li.oe_m2o_dropdown_option
+ margin-top: 10px
+ // }}}
+ // FormView.fieldstatus {{{
+ .oe_form_field_status
+ @include semantic-html-override
+ @include ul-html-override
// }}}
// FormView.one2many {{{
.oe_form .oe_form_field_one2many > .oe_view_manager
@@ -1931,6 +1929,8 @@ $sheet-max-width: 860px
background-color: #d2d2ff
td.oe_readonly
background-color: #eee
+
+ $row-height: 27px
.oe_list_editable
.oe_list_content
td.oe_list_field_cell
@@ -1945,12 +1945,11 @@ $sheet-max-width: 860px
display: none
.oe_form_field
input
- height: 27px
+ height: $row-height
input, textarea
+ @include radius(0)
border: 1px solid #aaf
- border-radius: 0px
- margin: 0px
- -webkit-border-radius: 0px
+ margin: 0
textarea
height: 60px
&.oe_form_field_float,&.oe_form_view_integer
@@ -1972,15 +1971,19 @@ $sheet-max-width: 860px
// }}}
// ListView {{{
.oe_list_buttons
+ .oe_alternative
+ visibility: hidden
.oe_list_save, .oe_list_discard
display: none
&.oe_editing
- .oe_list_add, .oe_list_button_import
+ .oe_list_add
display: none
.oe_list_save
display: inline-block
.oe_list_discard
display: inline
+ .oe_alternative
+ visibility: visible
.oe_list
position: relative
@@ -1994,6 +1997,8 @@ $sheet-max-width: 860px
position: absolute
margin: 0 !important // dammit
padding: 0
+ .oe_list_content .oe_group_header
+ @include vertical-gradient(#fcfcfc, #dedede)
.oe_list_content
width: 100%
@@ -2035,6 +2040,7 @@ $sheet-max-width: 860px
> tbody
cursor: pointer
> tr
+ height: $row-height
border-top: 1px solid #ddd
> td.oe_list_field_cell
padding: 3px 6px
@@ -2052,6 +2058,7 @@ $sheet-max-width: 860px
> tr:nth-child(odd)
background-color: #f0f0fa
@include vertical-gradient(#f0f0fa, #eeeef6)
+
> tfoot
border-top: 2px solid #cacaca
border-bottom: 1px solid #cacaca
@@ -2074,6 +2081,13 @@ $sheet-max-width: 860px
.oe_list_handle
@include text-to-icon("ö")
+ .oe_list_cannot_edit
+ .oe_list_header_handle, .oe_list_field_handle
+ display: none !important
+ .oe_list_cannot_delete
+ .oe_list_record_delete
+ display: none !important
+
// }}}
// Tree view {{{
.tree_header
@@ -2098,7 +2112,7 @@ $sheet-max-width: 860px
border-bottom: 2px solid #cacaca
.treeview-tr, .treeview-td
cursor: pointer
- border-right: 1px dotted $facets-border
+ border-right: 1px dotted $tag-border
vertical-align: top
text-align: left
border-bottom: 1px solid #cfcccc
@@ -2156,6 +2170,15 @@ $sheet-max-width: 860px
float: right
color: #333
// }}}
+ .oe_semantic_html // a style to use normal html
+ li
+ list-style-type: disc
+ display: list-item
+ ul
+ padding-left: 1em
+ p
+ color: #4C4C4C !important
+
// Kitten Mode {{{
.kitten-mode-activated
background-image: url(http://placekitten.com/g/1365/769)
@@ -2166,10 +2189,37 @@ $sheet-max-width: 860px
// }}}
-// The jQuery-ui overlay is outside the .openerp div, please don't add indentation !!!
+// The jQuery-ui overlay and Autocomplete are outside the .openerp div, please don't add indentation !!!
div.ui-widget-overlay
background: black
@include opacity(0.3)
+.ui-widget
+ font-family: "Lucida Grande", Helvetica, Verdana, Arial, sans-serif
+ color: #4c4c4c
+ font-size: 13px
+
+.ui-menu
+ padding: 2px 0
+ @include box-shadow(0 1px 4px rgba(0,0,0,0.3))
+ margin-top: 4px
+ border: 1px solid $tag-border
+ .ui-menu-item
+ width: 100%
+ padding: 0
+ a
+ padding: 1px 16px
+ a.ui-corner-all
+ @include radius(0)
+ a.ui-state-active
+ background: #f0f0fa
+ .ui-menu-item a.ui-state-hover, .ui-menu-item a.ui-state-active
+ background: $tag-bg-dark
+ //color: #4c4c4c
+ //@include vertical-gradient(#f0f0fa, #eeeef6)
+
+.ui-corner-all
+ @include radius(3px)
+
// au BufWritePost,FileWritePost *.sass :!sass --style expanded --line-numbers <afile> > "%:p:r.css"
// vim:tabstop=4:shiftwidth=4:softtabstop=4:fdm=marker:
diff --git a/addons/web/static/src/css/data_import.css b/addons/web/static/src/css/data_import.css
deleted file mode 100644
index 47cd52aa081..00000000000
--- a/addons/web/static/src/css/data_import.css
+++ /dev/null
@@ -1,46 +0,0 @@
-.openerp .oe_import_grid {
- border: none;
- border-collapse: collapse;
-}
-.openerp .oe_import_grid-header .oe_import_grid-cell {
- background: url(../img/gradientlinebg.gif) repeat-x #CCCCCC;
- border-bottom: 1px solid #E3E3E3;
- font-weight: bold;
- text-align: left;
-}
-.openerp .oe_import_grid-row .oe_import_grid-cell {
- border-bottom: 1px solid #E3E3E3;
-}
-
-.openerp .oe_import_no_result .oe_import_result {
- display: none;
-}
-.openerp .oe_import fieldset {
- cursor: pointer;
-}
-.openerp .oe_import fieldset legend:before {
- content: '\25BC ';
-}
-.openerp .oe_import fieldset.oe_closed legend:before {
- content: '\25B6 ';
-}
-.openerp .oe_import fieldset.oe_closed table {
- display: none;
-}
-.openerp .oe_import .separator.horizontal {
- font-weight: bold;
- border-bottom-width: 1px;
- margin: 6px 4px 6px 1px;
- height: 20px;
-}
-.openerp .duplicate_fld{
- background-color:#FF6666;
-}
-.openerp .select_fld{
- background: none repeat scroll 0 0 white;
-}
-.openerp .ui-autocomplete {
- max-height: 300px;
- overflow-y: auto;
- padding-right: 20px;
-}
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index ff066c9f425..3114aaf315f 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -13,7 +13,7 @@ instance.web.Notification = instance.web.Widget.extend({
},
start: function() {
this._super.apply(this, arguments);
- this.$element.notify({
+ this.$el.notify({
speed: 500,
expires: 2500
});
@@ -24,7 +24,7 @@ instance.web.Notification = instance.web.Widget.extend({
if (sticky) {
opts.expires = false;
}
- this.$element.notify('create', {
+ this.$el.notify('create', {
title: title,
text: text
}, opts);
@@ -35,7 +35,7 @@ instance.web.Notification = instance.web.Widget.extend({
if (sticky) {
opts.expires = false;
}
- this.$element.notify('create', 'oe_notification_alert', {
+ this.$el.notify('create', 'oe_notification_alert', {
title: title,
text: text
}, opts);
@@ -123,22 +123,22 @@ instance.web.Dialog = instance.web.Widget.extend({
if (! this.dialog_inited)
this.init_dialog();
var o = this.get_options(options);
- instance.web.dialog(this.$element, o).dialog('open');
+ instance.web.dialog(this.$el, o).dialog('open');
if (o.height === 'auto' && o.max_height) {
- this.$element.css({ 'max-height': o.max_height, 'overflow-y': 'auto' });
+ this.$el.css({ 'max-height': o.max_height, 'overflow-y': 'auto' });
}
return this;
},
init_dialog: function(options) {
this.renderElement();
var o = this.get_options(options);
- instance.web.dialog(this.$element, o);
+ instance.web.dialog(this.$el, o);
var res = this.start();
this.dialog_inited = true;
return res;
},
close: function() {
- this.$element.dialog('close');
+ this.$el.dialog('close');
},
on_close: function() {
if (this.__tmp_dialog_destroying)
@@ -161,7 +161,7 @@ instance.web.Dialog = instance.web.Widget.extend({
this.__tmp_dialog_destroying = undefined;
}
if (! this.isDestroyed()) {
- this.$element.dialog('destroy');
+ this.$el.dialog('destroy');
}
this._super();
}
@@ -193,29 +193,9 @@ instance.web.CrashManager = instance.web.CallbackEnabled.extend({
on_traceback: function(error) {
var self = this;
var buttons = {};
- if (instance.session.openerp_entreprise) {
- buttons[_t("Send OpenERP Enterprise Report")] = function() {
- var $this = $(this);
- var issuename = $('#issuename').val();
- var explanation = $('#explanation').val();
- var remark = $('#remark').val();
- // Call the send method from server to send mail with details
- new instance.web.DataSet(self, 'publisher_warranty.contract').call_and_eval('send', [error.data,explanation,remark,issuename]).then(function(result){
- if (result === false) {
- alert('There was a communication error.');
- } else {
- $this.dialog('close');
- }
- });
- };
- buttons[_t("Dont send")] = function() {
- $(this).dialog("close");
- };
- } else {
- buttons[_t("Ok")] = function() {
- $(this).dialog("close");
- };
- }
+ buttons[_t("Ok")] = function() {
+ $(this).dialog("close");
+ };
var dialog = new instance.web.Dialog(this, {
title: "OpenERP " + _.str.capitalize(error.type),
width: '80%',
@@ -224,7 +204,7 @@ instance.web.CrashManager = instance.web.CallbackEnabled.extend({
min_height: '600px',
buttons: buttons
}).open();
- dialog.$element.html(QWeb.render('CrashManager.error', {session: instance.session, error: error}));
+ dialog.$el.html(QWeb.render('CrashManager.error', {session: instance.session, error: error}));
},
on_javascript_exception: function(exception) {
this.on_traceback({
@@ -270,12 +250,12 @@ instance.web.Loading = instance.web.Widget.extend({
this.count += increment;
if (this.count > 0) {
if (instance.session.debug) {
- this.$element.text(_.str.sprintf( _t("Loading (%d)"), this.count));
+ this.$el.text(_.str.sprintf( _t("Loading (%d)"), this.count));
} else {
- this.$element.text(_t("Loading"));
+ this.$el.text(_t("Loading"));
}
- this.$element.show();
- this.getParent().$element.addClass('oe_wait');
+ this.$el.show();
+ this.getParent().$el.addClass('oe_wait');
} else {
this.count = 0;
clearTimeout(this.long_running_timer);
@@ -284,8 +264,8 @@ instance.web.Loading = instance.web.Widget.extend({
this.blocked_ui = false;
instance.web.unblockUI();
}
- this.$element.fadeOut();
- this.getParent().$element.removeClass('oe_wait');
+ this.$el.fadeOut();
+ this.getParent().$el.removeClass('oe_wait');
}
}
});
@@ -317,7 +297,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
do_render: function() {
var self = this;
instance.webclient.toggle_bars(true);
- self.$element.html(QWeb.render("DatabaseManager", { widget : self }));
+ self.$el.html(QWeb.render("DatabaseManager", { widget : self }));
$('.oe_user_menu_placeholder').append(QWeb.render("DatabaseManager.user_menu",{ widget : self }));
$('.oe_secondary_menus_container').append(QWeb.render("DatabaseManager.menu",{ widget : self }));
$('ul.oe_secondary_submenu > li:first').addClass('oe_active')
@@ -329,14 +309,14 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
event.preventDefault();
});
$('#back-to-login').click(self.do_exit);
- self.$element.find("td").addClass("oe_form_group_cell");
- self.$element.find("tr td:first-child").addClass("oe_form_group_cell_label");
- self.$element.find("label").addClass("oe_form_label");
- self.$element.find("form[name=create_db_form]").validate({ submitHandler: self.do_create });
- self.$element.find("form[name=drop_db_form]").validate({ submitHandler: self.do_drop });
- self.$element.find("form[name=backup_db_form]").validate({ submitHandler: self.do_backup });
- self.$element.find("form[name=restore_db_form]").validate({ submitHandler: self.do_restore });
- self.$element.find("form[name=change_pwd_form]").validate({
+ self.$el.find("td").addClass("oe_form_group_cell");
+ self.$el.find("tr td:first-child").addClass("oe_form_group_cell_label");
+ self.$el.find("label").addClass("oe_form_label");
+ self.$el.find("form[name=create_db_form]").validate({ submitHandler: self.do_create });
+ self.$el.find("form[name=drop_db_form]").validate({ submitHandler: self.do_drop });
+ self.$el.find("form[name=backup_db_form]").validate({ submitHandler: self.do_backup });
+ self.$el.find("form[name=restore_db_form]").validate({ submitHandler: self.do_restore });
+ self.$el.find("form[name=change_pwd_form]").validate({
messages: {
old_pwd: "Please enter your previous password",
new_pwd: "Please enter your new password",
@@ -349,7 +329,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
});
},
destroy: function () {
- this.$element.find('#db-create, #db-drop, #db-backup, #db-restore, #db-change-password, #back-to-login').unbind('click').end().empty();
+ this.$el.find('#db-create, #db-drop, #db-backup, #db-restore, #db-change-password, #back-to-login').unbind('click').end().empty();
this._super();
},
/**
@@ -411,7 +391,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
'login': 'admin',
'password': form_obj['create_admin_pwd'],
'login_successful': function() {
- instance.webclient.show_application();
+ self.do_action("reload");
},
},
};
@@ -500,7 +480,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
});
},
do_exit: function () {
- this.$element.remove();
+ this.$el.remove();
instance.webclient.toggle_bars(false);
this.do_action('login');
}
@@ -533,8 +513,8 @@ instance.web.Login = instance.web.Widget.extend({
},
start: function() {
var self = this;
- self.$element.find("form").submit(self.on_submit);
- self.$element.find('.oe_login_manage_db').click(function() {
+ self.$el.find("form").submit(self.on_submit);
+ self.$el.find('.oe_login_manage_db').click(function() {
self.do_action("database_manager");
});
var d;
@@ -584,7 +564,7 @@ instance.web.Login = instance.web.Widget.extend({
*/
do_login: function (db, login, password) {
var self = this;
- this.$element.removeClass('oe_login_invalid');
+ this.$el.removeClass('oe_login_invalid');
self.$(".oe_login_pane").fadeOut("slow");
return this.session.session_authenticate(db, login, password).pipe(function() {
if (self.has_local_storage) {
@@ -603,7 +583,7 @@ instance.web.Login = instance.web.Widget.extend({
self.trigger('login_successful');
},function () {
self.$(".oe_login_pane").fadeIn("fast", function() {
- self.$element.addClass("oe_login_invalid");
+ self.$el.addClass("oe_login_invalid");
});
});
},
@@ -663,7 +643,7 @@ instance.web.ChangePassword = instance.web.Widget.extend({
template: "ChangePassword",
start: function() {
var self = this;
- self.$element.validate({
+ self.$el.validate({
submitHandler: function (form) {
self.rpc("/web/session/change_password",{
'fields': $(form).serializeArray()
@@ -700,7 +680,7 @@ instance.web.Menu = instance.web.Widget.extend({
},
start: function() {
this._super.apply(this, arguments);
- this.$secondary_menus = this.getParent().$element.find('.oe_secondary_menus_container');
+ this.$secondary_menus = this.getParent().$el.find('.oe_secondary_menus_container');
this.$secondary_menus.on('click', 'a[data-menu]', this.on_menu_click);
return this.do_reload();
},
@@ -712,8 +692,13 @@ instance.web.Menu = instance.web.Widget.extend({
this.data = data;
this.renderElement();
this.limit_entries();
+ // Hide toplevel item if there is only one
+ var $toplevel = this.$("li")
+ if($toplevel.length == 1) {
+ $toplevel.hide();
+ }
this.$secondary_menus.html(QWeb.render("Menu.secondary", { widget : this }));
- this.$element.on('click', 'a[data-menu]', this.on_menu_click);
+ this.$el.on('click', 'a[data-menu]', this.on_menu_click);
// Hide second level submenus
this.$secondary_menus.find('.oe_menu_toggler').siblings('.oe_secondary_submenu').hide();
if (self.current_menu) {
@@ -728,8 +713,9 @@ instance.web.Menu = instance.web.Widget.extend({
}
if (maximum_visible_links < this.data.data.children.length) {
var $more = $(QWeb.render('Menu.more')),
- $index = this.$element.find('li').eq(maximum_visible_links - 1);
+ $index = this.$el.find('li').eq(maximum_visible_links - 1);
$index.after($more);
+ //$('.oe_topbar').append($more);
$more.find('.oe_menu_more').append($index.next().nextAll());
}
},
@@ -745,20 +731,22 @@ instance.web.Menu = instance.web.Widget.extend({
* @param {Number} id database id of the terminal menu to select
*/
open_menu: function (id) {
+ this.current_menu = id;
+ this.session.active_id = id;
var $clicked_menu, $sub_menu, $main_menu;
- $clicked_menu = this.$element.add(this.$secondary_menus).find('a[data-menu=' + id + ']');
+ $clicked_menu = this.$el.add(this.$secondary_menus).find('a[data-menu=' + id + ']');
this.trigger('open_menu', id, $clicked_menu);
if (this.$secondary_menus.has($clicked_menu).length) {
$sub_menu = $clicked_menu.parents('.oe_secondary_menu');
- $main_menu = this.$element.find('a[data-menu=' + $sub_menu.data('menu-parent') + ']');
+ $main_menu = this.$el.find('a[data-menu=' + $sub_menu.data('menu-parent') + ']');
} else {
$sub_menu = this.$secondary_menus.find('.oe_secondary_menu[data-menu-parent=' + $clicked_menu.attr('data-menu') + ']');
$main_menu = $clicked_menu;
}
// Activate current main menu
- this.$element.find('.oe_active').removeClass('oe_active');
+ this.$el.find('.oe_active').removeClass('oe_active');
$main_menu.addClass('oe_active');
// Show current sub menu
@@ -785,7 +773,7 @@ instance.web.Menu = instance.web.Widget.extend({
* @param {Number} id the action_id to match
*/
open_action: function (id) {
- var $menu = this.$element.add(this.$secondary_menus).find('a[data-action-id="' + id + '"]');
+ var $menu = this.$el.add(this.$secondary_menus).find('a[data-action-id="' + id + '"]');
var menu_id = $menu.data('menu');
if (menu_id) {
this.open_menu(menu_id);
@@ -801,14 +789,14 @@ instance.web.Menu = instance.web.Widget.extend({
if (!id) { return; }
// find back the menuitem in dom to get the action
- var $item = this.$element.find('a[data-menu=' + id + ']');
+ var $item = this.$el.find('a[data-menu=' + id + ']');
if (!$item.length) {
$item = this.$secondary_menus.find('a[data-menu=' + id + ']');
}
var action_id = $item.data('action-id');
// If first level menu doesnt have action trigger first leaf
if (!action_id) {
- if(this.$element.has($item).length) {
+ if(this.$el.has($item).length) {
var $sub_menu = this.$secondary_menus.find('.oe_secondary_menu[data-menu-parent=' + id + ']');
var $items = $sub_menu.find('a[data-action-id]').filter('[data-action-id!=""]');
if($items.length) {
@@ -817,16 +805,15 @@ instance.web.Menu = instance.web.Widget.extend({
}
}
}
- this.open_menu(id);
- this.current_menu = id;
- this.session.active_id = id;
if (action_id) {
this.trigger('menu_click', {
action_id: action_id,
needaction: needaction,
- id: id
+ id: id,
+ previous_menu_id: this.current_menu // Here we don't know if action will fail (in which case we have to revert menu)
}, $item);
}
+ this.open_menu(id);
},
/**
* Jquery event handler for menu click
@@ -849,7 +836,7 @@ instance.web.UserMenu = instance.web.Widget.extend({
start: function() {
var self = this;
this._super.apply(this, arguments);
- this.$element.on('click', '.oe_dropdown_menu li a[data-menu]', function(ev) {
+ this.$el.on('click', '.oe_dropdown_menu li a[data-menu]', function(ev) {
ev.preventDefault();
var f = self['on_menu_' + $(this).data('menu')];
if (f) {
@@ -860,7 +847,7 @@ instance.web.UserMenu = instance.web.Widget.extend({
do_update: function () {
var self = this;
var fct = function() {
- var $avatar = self.$element.find('.oe_topbar_avatar');
+ var $avatar = self.$el.find('.oe_topbar_avatar');
$avatar.attr('src', $avatar.data('default-src'));
if (!self.session.uid)
return;
@@ -871,7 +858,7 @@ instance.web.UserMenu = instance.web.Widget.extend({
topbar_name = _.str.sprintf("%s (%s)", topbar_name, instance.session.db);
if(res.company_id[0] > 1)
topbar_name = _.str.sprintf("%s (%s)", topbar_name, res.company_id[1]);
- self.$element.find('.oe_topbar_name').text(topbar_name);
+ self.$el.find('.oe_topbar_name').text(topbar_name);
var avatar_src = _.str.sprintf('%s/web/binary/image?session_id=%s&model=res.users&field=image_small&id=%s', self.session.prefix, self.session.session_id, self.session.uid);
$avatar.attr('src', avatar_src);
});
@@ -884,10 +871,12 @@ instance.web.UserMenu = instance.web.Widget.extend({
},
on_menu_settings: function() {
var self = this;
- self.rpc("/web/action/load", { action_id: "base.action_res_users_my" }, function(result) {
- result.result.res_id = instance.session.uid;
- self.getParent().action_manager.do_action(result.result);
- });
+ if (!this.getParent().has_uncommitted_changes()) {
+ self.rpc("/web/action/load", { action_id: "base.action_res_users_my" }, function(result) {
+ result.result.res_id = instance.session.uid;
+ self.getParent().action_manager.do_action(result.result);
+ });
+ }
},
on_menu_about: function() {
var self = this;
@@ -921,10 +910,10 @@ instance.web.Client = instance.web.Widget.extend({
},
bind_events: function() {
var self = this;
- this.$element.on('mouseenter', '.oe_systray > div:not([data-tipsy=true])', function() {
+ this.$el.on('mouseenter', '.oe_systray > div:not([data-tipsy=true])', function() {
$(this).attr('data-tipsy', 'true').tipsy().trigger('mouseenter');
});
- this.$element.on('click', '.oe_dropdown_toggle', function(ev) {
+ this.$el.on('click', '.oe_dropdown_toggle', function(ev) {
ev.preventDefault();
var $toggle = $(this);
var $menu = $toggle.siblings('.oe_dropdown_menu');
@@ -948,7 +937,7 @@ instance.web.Client = instance.web.Widget.extend({
instance.web.bus.on('click', this, function(ev) {
$.fn.tipsy.clear();
if (!$(ev.target).is('input[type=file]')) {
- self.$element.find('.oe_dropdown_menu.oe_opened, .oe_dropdown_toggle.oe_opened').removeClass('oe_opened');
+ self.$el.find('.oe_dropdown_menu.oe_opened, .oe_dropdown_toggle.oe_opened').removeClass('oe_opened');
}
});
},
@@ -957,15 +946,18 @@ instance.web.Client = instance.web.Widget.extend({
this.crashmanager = new instance.web.CrashManager();
instance.session.on_rpc_error.add(this.crashmanager.on_rpc_error);
self.notification = new instance.web.Notification(this);
- self.notification.appendTo(self.$element);
+ self.notification.appendTo(self.$el);
self.loading = new instance.web.Loading(self);
- self.loading.appendTo(self.$element);
+ self.loading.appendTo(self.$el);
self.action_manager = new instance.web.ActionManager(self);
self.action_manager.appendTo(self.$('.oe_application'));
},
toggle_bars: function(value) {
this.$('tr:has(td.oe_topbar),.oe_leftbar').toggle(value);
- }
+ },
+ has_uncommitted_changes: function() {
+ return false;
+ },
});
instance.web.WebClient = instance.web.Client.extend({
@@ -977,6 +969,9 @@ instance.web.WebClient = instance.web.Client.extend({
start: function() {
var self = this;
return $.when(this._super()).pipe(function() {
+ self.$el.on('click', '.oe_logo', function() {
+ self.action_manager.do_action('home');
+ });
if (jQuery.param !== undefined && jQuery.deparam(jQuery.param.querystring()).kitten !== undefined) {
$("body").addClass("kitten-mode-activated");
if ($.blockUI) {
@@ -1029,25 +1024,21 @@ instance.web.WebClient = instance.web.Client.extend({
var self = this;
self.toggle_bars(true);
self.menu = new instance.web.Menu(self);
- self.menu.replace(this.$element.find('.oe_menu_placeholder'));
+ self.menu.replace(this.$el.find('.oe_menu_placeholder'));
self.menu.on('menu_click', this, this.on_menu_action);
self.user_menu = new instance.web.UserMenu(self);
- self.user_menu.replace(this.$element.find('.oe_user_menu_placeholder'));
+ self.user_menu.replace(this.$el.find('.oe_user_menu_placeholder'));
self.user_menu.on_menu_logout.add(this.proxy('on_logout'));
self.user_menu.on_action.add(this.proxy('on_menu_action'));
self.user_menu.do_update();
self.bind_hashchange();
- if (!self.session.openerp_entreprise) {
- var version_label = _t("OpenERP - Unsupported/Community Version");
- self.$element.find('.oe_footer_powered').append(_.str.sprintf('<span> - <a href="http://www.openerp.com/support-or-publisher-warranty-contract" target="_blank">%s</a></span>', version_label));
- }
self.set_title();
},
destroy_content: function() {
_.each(_.clone(this.getChildren()), function(el) {
el.destroy();
});
- this.$element.children().remove();
+ this.$el.children().remove();
},
do_reload: function() {
var self = this;
@@ -1066,11 +1057,13 @@ instance.web.WebClient = instance.web.Client.extend({
},
on_logout: function() {
var self = this;
- this.session.session_logout().then(function () {
- $(window).unbind('hashchange', self.on_hashchange);
- self.do_push_state({});
- window.location.reload();
- });
+ if (!this.has_uncommitted_changes()) {
+ this.session.session_logout().then(function () {
+ $(window).unbind('hashchange', self.on_hashchange);
+ self.do_push_state({});
+ window.location.reload();
+ });
+ }
},
bind_hashchange: function() {
var self = this;
@@ -1079,7 +1072,7 @@ instance.web.WebClient = instance.web.Client.extend({
var state = $.bbq.getState(true);
if (_.isEmpty(state) || state.action == "login") {
self.menu.has_been_loaded.then(function() {
- var first_menu_id = self.menu.$element.find("a:first").data("menu");
+ var first_menu_id = self.menu.$el.find("a:first").data("menu");
if(first_menu_id) {
self.menu.menu_click(first_menu_id);
}
@@ -1113,14 +1106,15 @@ instance.web.WebClient = instance.web.Client.extend({
},
on_menu_action: function(options) {
var self = this;
- this.rpc("/web/action/load", { action_id: options.action_id })
- .then(function (result) {
+ return this.rpc("/web/action/load", { action_id: options.action_id })
+ .pipe(function (result) {
var action = result.result;
if (options.needaction) {
action.context.search_default_needaction_pending = true;
}
- self.action_manager.clear_breadcrumbs();
- self.action_manager.do_action(action);
+ return $.when(self.action_manager.do_action(action, null, true)).fail(function() {
+ self.menu.open_menu(options.previous_menu_id);
+ });
});
},
do_action: function(action) {
@@ -1134,13 +1128,22 @@ instance.web.WebClient = instance.web.Client.extend({
},
set_content_full_screen: function(fullscreen) {
if (fullscreen) {
- $(".oe_webclient", this.$element).addClass("oe_content_full_screen");
+ $(".oe_webclient", this.$el).addClass("oe_content_full_screen");
$("body").css({'overflow-y':'hidden'});
} else {
- $(".oe_webclient", this.$element).removeClass("oe_content_full_screen");
+ $(".oe_webclient", this.$el).removeClass("oe_content_full_screen");
$("body").css({'overflow-y':'scroll'});
}
- }
+ },
+ has_uncommitted_changes: function() {
+ var $e = $.Event('clear_uncommitted_changes');
+ instance.web.bus.trigger('clear_uncommitted_changes', $e);
+ if ($e.isDefaultPrevented()) {
+ return true;
+ } else {
+ return this._super.apply(this, arguments);
+ }
+ },
});
instance.web.EmbeddedClient = instance.web.Client.extend({
diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js
index 5da12043994..c74c2d5dc03 100644
--- a/addons/web/static/src/js/corelib.js
+++ b/addons/web/static/src/js/corelib.js
@@ -525,8 +525,8 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, {
_.each(this.getChildren(), function(el) {
el.destroy();
});
- if(this.$element) {
- this.$element.remove();
+ if(this.$el) {
+ this.$el.remove();
}
instance.web.PropertiesMixin.destroy.call(this);
},
@@ -538,7 +538,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, {
appendTo: function(target) {
var self = this;
return this.__widgetRenderAndInsert(function(t) {
- self.$element.appendTo(t);
+ self.$el.appendTo(t);
}, target);
},
/**
@@ -549,7 +549,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, {
prependTo: function(target) {
var self = this;
return this.__widgetRenderAndInsert(function(t) {
- self.$element.prependTo(t);
+ self.$el.prependTo(t);
}, target);
},
/**
@@ -560,7 +560,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, {
insertAfter: function(target) {
var self = this;
return this.__widgetRenderAndInsert(function(t) {
- self.$element.insertAfter(t);
+ self.$el.insertAfter(t);
}, target);
},
/**
@@ -571,7 +571,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, {
insertBefore: function(target) {
var self = this;
return this.__widgetRenderAndInsert(function(t) {
- self.$element.insertBefore(t);
+ self.$el.insertBefore(t);
}, target);
},
/**
@@ -581,7 +581,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, {
*/
replace: function(target) {
return this.__widgetRenderAndInsert(_.bind(function(t) {
- this.$element.replaceAll(t);
+ this.$el.replaceAll(t);
}, this), target);
},
__widgetRenderAndInsert: function(insertion, target) {
@@ -640,8 +640,8 @@ instance.web.CallbackEnabled = instance.web.Class.extend(instance.web.CallbackEn
* // stuff that you want to init before the rendering
* },
* start: function() {
- * // stuff you want to make after the rendering, `this.$element` holds a correct value
- * this.$element.find(".my_button").click(/* an example of event binding * /);
+ * // 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 * /);
*
* // if you have some asynchronous operations, it's a good idea to return
* // a promise in start()
@@ -718,15 +718,15 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, {
* @returns {*} this
*/
replaceElement: function ($el) {
- var $oldel = this.$element;
+ var $oldel = this.$el;
this.setElement($el);
- if ($oldel && !$oldel.is(this.$element)) {
- $oldel.replaceWith(this.$element);
+ if ($oldel && !$oldel.is(this.$el)) {
+ $oldel.replaceWith(this.$el);
}
return this;
},
/**
- * Re-sets the widget's root element (el/$el/$element).
+ * Re-sets the widget's root element (el/$el/$el).
*
* Includes:
* * re-delegating events
@@ -738,14 +738,14 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, {
* @return {*} this
*/
setElement: function (element) {
- // NB: completely useless, as WidgetMixin#init creates a $element
+ // NB: completely useless, as WidgetMixin#init creates a $el
// always
- if (this.$element) {
+ if (this.$el) {
this.undelegateEvents();
}
- this.$element = (element instanceof $) ? element : $(element);
- this.el = this.$element[0];
+ this.$el = (element instanceof $) ? element : $(element);
+ this.el = this.$el[0];
this.delegateEvents();
@@ -797,23 +797,23 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, {
event += '.widget_events';
if (!selector) {
- this.$element.on(event, method);
+ this.$el.on(event, method);
} else {
- this.$element.on(event, selector, method);
+ this.$el.on(event, selector, method);
}
}
},
undelegateEvents: function () {
- this.$element.off('.widget_events');
+ this.$el.off('.widget_events');
},
/**
- * Shortcut for ``this.$element.find(selector)``
+ * Shortcut for ``this.$el.find(selector)``
*
* @param {String} selector CSS selector, rooted in $el
* @returns {jQuery} selector match
*/
$: function(selector) {
- return this.$element.find(selector);
+ return this.$el.find(selector);
},
/**
* Informs the action manager to do an action. This supposes that
@@ -1323,12 +1323,6 @@ instance.web.JsonRPC = instance.web.CallbackEnabled.extend({
deferred.resolve(response["result"], textStatus, jqXHR);
} else if (response.error.data.type === "session_invalid") {
self.uid = false;
- // TODO deprecate or use a deferred on login.do_ask_login()
- self.on_session_invalid(function() {
- self.rpc(url, payload.params,
- function() { deferred.resolve.apply(deferred, arguments); },
- function() { deferred.reject.apply(deferred, arguments); });
- });
} else {
deferred.reject(response.error, $.Event());
}
diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js
index 229a82a1784..5f0ecc80827 100644
--- a/addons/web/static/src/js/coresetup.js
+++ b/addons/web/static/src/js/coresetup.js
@@ -35,7 +35,6 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess
this.username = false;
this.user_context= {};
this.db = false;
- this.openerp_entreprise = false;
this.module_list = instance._modules.slice();
this.module_loaded = {};
_(this.module_list).each(function (mod) {
@@ -78,8 +77,7 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess
db: result.db,
username: result.login,
uid: result.uid,
- user_context: result.context,
- openerp_entreprise: result.openerp_entreprise
+ user_context: result.context
});
});
},
@@ -103,8 +101,7 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess
db: result.db,
username: result.login,
uid: result.uid,
- user_context: result.context,
- openerp_entreprise: result.openerp_entreprise
+ user_context: result.context
});
if (!_volatile) {
self.set_cookie('session_id', self.session_id);
@@ -116,20 +113,6 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess
this.set_cookie('session_id', '');
return this.rpc("/web/session/destroy", {});
},
- on_session_valid: function() {
- },
- /**
- * Called when a rpc call fail due to an invalid session.
- * By default, it's a noop
- */
- on_session_invalid: function(retry_callback) {
- },
- /**
- * Fetches a cookie stored by an openerp session
- *
- * @private
- * @param name the cookie's name
- */
get_cookie: function (name) {
if (!this.name) { return null; }
var nameEQ = this.name + '|' + name + '=';
@@ -163,9 +146,8 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess
/**
* Load additional web addons of that instance and init them
*
- * @param {Boolean} [no_session_valid_signal=false] prevents load_module from triggering ``on_session_valid``.
*/
- load_modules: function(no_session_valid_signal) {
+ load_modules: function() {
var self = this;
return this.rpc('/web/session/modules', {}).pipe(function(result) {
var lang = self.user_context.lang,
@@ -198,9 +180,6 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess
return loaded.then(function() {
self.on_modules_loaded();
self.trigger('module_loaded');
- if (!no_session_valid_signal) {
- self.on_session_valid();
- }
});
});
},
@@ -520,57 +499,6 @@ $.async_when = function() {
return old_async_when.apply(this, arguments);
};
-/** Setup blockui */
-if ($.blockUI) {
- $.blockUI.defaults.baseZ = 1100;
- $.blockUI.defaults.message = '<div class="oe_blockui_spin_container">';
- $.blockUI.defaults.css.border = '0';
- $.blockUI.defaults.css["background-color"] = '';
-}
-
-instance.web.Throbber = instance.web.Widget.extend({
- template: "Throbber",
- start: function() {
- var opts = {
- lines: 13, // The number of lines to draw
- length: 7, // The length of each line
- width: 4, // The line thickness
- radius: 10, // The radius of the inner circle
- rotate: 0, // The rotation offset
- color: '#FFF', // #rgb or #rrggbb
- speed: 1, // Rounds per second
- trail: 60, // Afterglow percentage
- shadow: false, // Whether to render a shadow
- hwaccel: false, // Whether to use hardware acceleration
- className: 'spinner', // The CSS class to assign to the spinner
- zIndex: 2e9, // The z-index (defaults to 2000000000)
- top: 'auto', // Top position relative to parent in px
- left: 'auto' // Left position relative to parent in px
- };
- this.spin = new Spinner(opts).spin(this.$element[0]);
- },
- destroy: function() {
- if (this.spin)
- this.spin.stop();
- this._super();
- },
-});
-instance.web.Throbber.throbbers = [];
-
-instance.web.blockUI = function() {
- var tmp = $.blockUI.apply($, arguments);
- var throbber = new instance.web.Throbber();
- instance.web.Throbber.throbbers.push(throbber);
- throbber.appendTo($(".oe_blockui_spin_container"));
- return tmp;
-}
-instance.web.unblockUI = function() {
- _.each(instance.web.Throbber.throbbers, function(el) {
- el.destroy();
- });
- return $.unblockUI.apply($, arguments);
-}
-
/** Setup default session */
instance.session = new instance.web.Session();
@@ -654,6 +582,87 @@ instance.session.on('module_loaded', this, function () {
$.timeago.settings.translator = instance.web._t;
});
+/** Setup blockui */
+if ($.blockUI) {
+ $.blockUI.defaults.baseZ = 1100;
+ $.blockUI.defaults.message = '<div class="openerp oe_blockui_spin_container" style="background-color: transparent;">';
+ $.blockUI.defaults.css.border = '0';
+ $.blockUI.defaults.css["background-color"] = '';
+}
+
+var messages_by_seconds = function() {
+ return [
+ [0, _t("Loading...")],
+ [20, _t("Still loading...")],
+ [60, _t("Still loading...<br />Please be patient.")],
+ [120, _t("Don't leave yet,<br />it's still loading...")],
+ [300, _t("You may not believe it,<br />but the application is actually loading...")],
+ [420, _t("Take a minute to get a coffee,<br />because it's loading...")],
+ [600, _t("It's loading...<br />By the way, did you tried the kitten mode?")],
+ [3600, _t("Maybe you should consider pressing F5...")],
+ ];
+};
+
+instance.web.Throbber = instance.web.Widget.extend({
+ template: "Throbber",
+ start: function() {
+ var opts = {
+ lines: 13, // The number of lines to draw
+ length: 7, // The length of each line
+ width: 4, // The line thickness
+ radius: 10, // The radius of the inner circle
+ rotate: 0, // The rotation offset
+ color: '#FFF', // #rgb or #rrggbb
+ speed: 1, // Rounds per second
+ trail: 60, // Afterglow percentage
+ shadow: false, // Whether to render a shadow
+ hwaccel: false, // Whether to use hardware acceleration
+ className: 'spinner', // The CSS class to assign to the spinner
+ zIndex: 2e9, // The z-index (defaults to 2000000000)
+ top: 'auto', // Top position relative to parent in px
+ left: 'auto' // Left position relative to parent in px
+ };
+ this.spin = new Spinner(opts).spin(this.$el[0]);
+ this.start_time = new Date().getTime();
+ this.act_message();
+ },
+ act_message: function() {
+ var self = this;
+ setTimeout(function() {
+ if (self.isDestroyed())
+ return;
+ var seconds = (new Date().getTime() - self.start_time) / 1000;
+ var mes;
+ _.each(messages_by_seconds(), function(el) {
+ if (seconds >= el[0])
+ mes = el[1];
+ });
+ self.$(".oe_throbber_message").html(mes);
+ self.act_message();
+ }, 1000);
+ },
+ destroy: function() {
+ if (this.spin)
+ this.spin.stop();
+ this._super();
+ },
+});
+instance.web.Throbber.throbbers = [];
+
+instance.web.blockUI = function() {
+ var tmp = $.blockUI.apply($, arguments);
+ var throbber = new instance.web.Throbber();
+ instance.web.Throbber.throbbers.push(throbber);
+ throbber.appendTo($(".oe_blockui_spin_container"));
+ return tmp;
+}
+instance.web.unblockUI = function() {
+ _.each(instance.web.Throbber.throbbers, function(el) {
+ el.destroy();
+ });
+ return $.unblockUI.apply($, arguments);
+}
+
/**
* Registry for all the client actions key: tag value: widget
*/
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index 10fd727e57a..29e799e54c3 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -417,6 +417,7 @@ instance.web.data = {
var group_size = fixed_group[grouping_field + '_count'] || fixed_group.__count || 0;
var leaf_group = fixed_group.__context.group_by.length === 0;
this.attributes = {
+ folded: !!(fixed_group.__fold),
grouped_on: grouping_field,
// if terminal group (or no group) and group_by_no_leaf => use group.__count
length: group_size,
@@ -494,6 +495,7 @@ instance.web.DataGroup = instance.web.CallbackEnabled.extend( /** @lends opener
{
__context: child_context,
__domain: group.model.domain(),
+ folded: group.get('folded'),
grouped_on: group.get('grouped_on'),
length: group.get('length'),
value: group.get('value'),
diff --git a/addons/web/static/src/js/data_export.js b/addons/web/static/src/js/data_export.js
index f8e669e1b4a..29aea6362f7 100644
--- a/addons/web/static/src/js/data_export.js
+++ b/addons/web/static/src/js/data_export.js
@@ -21,31 +21,31 @@ instance.web.DataExport = instance.web.Dialog.extend({
],
close: function(event, ui){ self.close();}
});
- self.$element.removeClass('ui-dialog-content ui-widget-content');
- self.$element.find('#add_field').click(function() {
+ self.$el.removeClass('ui-dialog-content ui-widget-content');
+ self.$el.find('#add_field').click(function() {
if ($('#field-tree-structure tr.ui-selected')) {
- var fld = self.$element.find('#field-tree-structure tr.ui-selected').find('a');
+ var fld = self.$el.find('#field-tree-structure tr.ui-selected').find('a');
for (var i = 0; i < fld.length; i++) {
var id = $(fld[i]).attr('id').split('-')[1];
var string = $(fld[i]).attr('string');
self.add_field(id, string);
}
- self.$element.find('#field-tree-structure tr').removeClass('ui-selected');
+ self.$el.find('#field-tree-structure tr').removeClass('ui-selected');
}
});
- self.$element.find('#remove_field').click(function() {
- self.$element.find('#fields_list option:selected').remove();
+ self.$el.find('#remove_field').click(function() {
+ self.$el.find('#fields_list option:selected').remove();
});
- self.$element.find('#remove_all_field').click(function() {
- self.$element.find('#fields_list').empty();
+ self.$el.find('#remove_all_field').click(function() {
+ self.$el.find('#fields_list').empty();
});
- this.$element.find('#export_new_list').click(this.on_show_save_list);
+ this.$el.find('#export_new_list').click(this.on_show_save_list);
var got_fields = new $.Deferred();
- this.$element.find('#import_compat').change(function() {
- self.$element.find('#fields_list').empty();
- self.$element.find('#field-tree-structure').remove();
- var import_comp = self.$element.find("#import_compat").val();
+ this.$el.find('#import_compat').change(function() {
+ self.$el.find('#fields_list').empty();
+ self.$el.find('#field-tree-structure').remove();
+ var import_comp = self.$el.find("#import_compat").val();
self.rpc("/web/export/get_fields", {
model: self.dataset.model,
import_compat: Boolean(import_comp)
@@ -61,7 +61,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
this.show_exports_list());
},
do_setup_export_formats: function (formats) {
- var $fmts = this.$element.find('#export_format');
+ var $fmts = this.$el.find('#export_format');
_(formats).each(function (format) {
var opt = new Option(format.label, format.tag);
if (format.error) {
@@ -76,8 +76,8 @@ instance.web.DataExport = instance.web.Dialog.extend({
},
show_exports_list: function() {
var self = this;
- if (self.$element.find('#saved_export_list').is(':hidden')) {
- self.$element.find('#ExistsExportList').show();
+ if (self.$el.find('#saved_export_list').is(':hidden')) {
+ self.$el.find('#ExistsExportList').show();
return;
}
return this.exports.read_slice(['name'], {
@@ -86,35 +86,35 @@ instance.web.DataExport = instance.web.Dialog.extend({
if (!export_list.length) {
return;
}
- self.$element.find('#ExistsExportList').append(QWeb.render('Exists.ExportList', {'existing_exports': export_list}));
- self.$element.find('#saved_export_list').change(function() {
- self.$element.find('#fields_list option').remove();
- var export_id = self.$element.find('#saved_export_list option:selected').val();
+ self.$el.find('#ExistsExportList').append(QWeb.render('Exists.ExportList', {'existing_exports': export_list}));
+ self.$el.find('#saved_export_list').change(function() {
+ self.$el.find('#fields_list option').remove();
+ var export_id = self.$el.find('#saved_export_list option:selected').val();
if (export_id) {
self.rpc('/web/export/namelist', {'model': self.dataset.model, export_id: parseInt(export_id)}, self.do_load_export_field);
}
});
- self.$element.find('#delete_export_list').click(function() {
- var select_exp = self.$element.find('#saved_export_list option:selected');
+ self.$el.find('#delete_export_list').click(function() {
+ var select_exp = self.$el.find('#saved_export_list option:selected');
if (select_exp.val()) {
self.exports.unlink([parseInt(select_exp.val(), 10)]);
select_exp.remove();
- if (self.$element.find('#saved_export_list option').length <= 1) {
- self.$element.find('#ExistsExportList').hide();
+ if (self.$el.find('#saved_export_list option').length <= 1) {
+ self.$el.find('#ExistsExportList').hide();
}
}
});
});
},
do_load_export_field: function(field_list) {
- var export_node = this.$element.find("#fields_list");
+ var export_node = this.$el.find("#fields_list");
_(field_list).each(function (field) {
export_node.append(new Option(field.label, field.name));
});
},
on_show_save_list: function() {
var self = this;
- var current_node = self.$element.find("#savenewlist");
+ var current_node = self.$el.find("#savenewlist");
if (!(current_node.find("label")).length) {
current_node.append(QWeb.render('ExportNewList'));
current_node.find("#add_export_list").click(function() {
@@ -150,14 +150,14 @@ instance.web.DataExport = instance.web.Dialog.extend({
if (!export_list_id.result) {
return;
}
- self.$element.find("#saved_export_list").append(
+ self.$el.find("#saved_export_list").append(
new Option(value, export_list_id.result));
- if (self.$element.find("#saved_export_list").is(":hidden")) {
+ if (self.$el.find("#saved_export_list").is(":hidden")) {
self.show_exports_list();
}
});
this.on_show_save_list();
- this.$element.find("#fields_list option").remove();
+ this.$el.find("#fields_list option").remove();
},
on_click: function(id, record) {
var self = this;
@@ -173,7 +173,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
}
if (!record.loaded) {
- var import_comp = self.$element.find("#import_compat").val();
+ var import_comp = self.$el.find("#import_compat").val();
self.rpc("/web/export/get_fields", {
model: model,
prefix: prefix,
@@ -191,44 +191,44 @@ instance.web.DataExport = instance.web.Dialog.extend({
},
on_show_data: function(result, after) {
var self = this;
- var imp_cmpt = Boolean(self.$element.find("#import_compat").val());
+ var imp_cmpt = Boolean(self.$el.find("#import_compat").val());
if (after) {
- var current_tr = self.$element.find("tr[id='treerow-" + after + "']");
+ var current_tr = self.$el.find("tr[id='treerow-" + after + "']");
current_tr.addClass('open');
current_tr.find('img').attr('src','/web/static/src/img/collapse.gif');
current_tr.after(QWeb.render('ExportTreeView-Secondary.children', {'fields': result}));
} else {
- self.$element.find('#left_field_panel').append(QWeb.render('ExportTreeView-Secondary', {'fields': result}));
+ self.$el.find('#left_field_panel').append(QWeb.render('ExportTreeView-Secondary', {'fields': result}));
}
_.each(result, function(record) {
self.records[record.id] = record.value;
if (record.required) {
- var required_fld = self.$element.find("tr[id='treerow-" + record.id + "']").find('#tree-column');
+ var required_fld = self.$el.find("tr[id='treerow-" + record.id + "']").find('#tree-column');
required_fld.addClass("oe_export_requiredfield");
}
- self.$element.find("img[id='parentimg-" + record.id +"']").click(function() {
+ self.$el.find("img[id='parentimg-" + record.id +"']").click(function() {
self.on_click(this.id, record);
});
- self.$element.find("tr[id='treerow-" + record.id + "']").click(function(e) {
+ self.$el.find("tr[id='treerow-" + record.id + "']").click(function(e) {
if (e.shiftKey) {
var frst_click, scnd_click = '';
if (self.row_index == 0) {
self.row_index = this.rowIndex;
- frst_click = self.$element.find("tr[id^='treerow-']")[self.row_index-1];
+ frst_click = self.$el.find("tr[id^='treerow-']")[self.row_index-1];
$(frst_click).addClass("ui-selected");
} else {
if (this.rowIndex >=self.row_index) {
for (var i = (self.row_index-1); i < this.rowIndex; i++) {
- scnd_click = self.$element.find("tr[id^='treerow-']")[i];
+ scnd_click = self.$el.find("tr[id^='treerow-']")[i];
if (!$(scnd_click).find('#tree-column').hasClass("oe_export_readonlyfield")) {
$(scnd_click).addClass("ui-selected");
}
}
} else {
for (var i = (self.row_index-1); i >= (this.rowIndex-1); i--) {
- scnd_click = self.$element.find("tr[id^='treerow-']")[i];
+ scnd_click = self.$el.find("tr[id^='treerow-']")[i];
if (!$(scnd_click).find('#tree-column').hasClass("oe_export_readonlyfield")) {
$(scnd_click).addClass("ui-selected");
}
@@ -238,10 +238,10 @@ instance.web.DataExport = instance.web.Dialog.extend({
}
self.row_index = this.rowIndex;
- self.$element.find("tr[id='treerow-" + record.id + "']").keyup(function() {
+ self.$el.find("tr[id='treerow-" + record.id + "']").keyup(function() {
self.row_index = 0;
});
- var o2m_selection = self.$element.find("tr[id='treerow-" + record.id + "']").find('#tree-column');
+ var o2m_selection = self.$el.find("tr[id='treerow-" + record.id + "']").find('#tree-column');
if ($(o2m_selection).hasClass("oe_export_readonlyfield")) {
return false;
}
@@ -252,14 +252,14 @@ instance.web.DataExport = instance.web.Dialog.extend({
$(this).addClass('ui-selected').find('a').focus();
}
} else if (!e.shiftKey) {
- self.$element.find("tr.ui-selected")
+ self.$el.find("tr.ui-selected")
.removeClass("ui-selected").find('a').blur();
$(this).addClass("ui-selected").find('a').focus();
}
return false;
});
- self.$element.find("tr[id='treerow-" + record.id + "']").keydown(function(e) {
+ self.$el.find("tr[id='treerow-" + record.id + "']").keydown(function(e) {
var keyCode = e.keyCode || e.which;
var arrow = {left: 37, up: 38, right: 39, down: 40 };
switch (keyCode) {
@@ -297,19 +297,19 @@ instance.web.DataExport = instance.web.Dialog.extend({
break;
}
});
- self.$element.find("tr[id='treerow-" + record.id + "']").dblclick(function() {
- var $o2m_selection = self.$element.find("tr[id^='treerow-" + record.id + "']").find('#tree-column');
+ self.$el.find("tr[id='treerow-" + record.id + "']").dblclick(function() {
+ var $o2m_selection = self.$el.find("tr[id^='treerow-" + record.id + "']").find('#tree-column');
if (!$o2m_selection.hasClass("oe_export_readonlyfield")) {
self.add_field(record.id, $(this).find("a").attr("string"));
}
});
});
- self.$element.find('#fields_list').mouseover(function(event) {
+ self.$el.find('#fields_list').mouseover(function(event) {
if (event.relatedTarget) {
if (event.relatedTarget.attributes['id'] && event.relatedTarget.attributes['string']) {
var field_id = event.relatedTarget.attributes["id"]["value"];
if (field_id && field_id.split("-")[0] === 'export') {
- if (!self.$element.find("tr[id='treerow-" + field_id.split("-")[1] + "']").find('#tree-column').hasClass("oe_export_readonlyfield")) {
+ if (!self.$el.find("tr[id='treerow-" + field_id.split("-")[1] + "']").find('#tree-column').hasClass("oe_export_readonlyfield")) {
self.add_field(field_id.split("-")[1], event.relatedTarget.attributes["string"]["value"]);
}
}
@@ -319,7 +319,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
},
showcontent: function(id) {
// show & hide the contents
- var $this = this.$element.find("tr[id='treerow-" + id + "']");
+ var $this = this.$el.find("tr[id='treerow-" + id + "']");
var is_open = $this.hasClass('open');
$this.toggleClass('open');
@@ -329,7 +329,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
} else {
first_child.attr('src', '/web/static/src/img/collapse.gif');
}
- var child_field = this.$element.find("tr[id^='treerow-" + id +"/']");
+ var child_field = this.$el.find("tr[id^='treerow-" + id +"/']");
var child_len = (id.split("/")).length + 1;
for (var i = 0; i < child_field.length; i++) {
var $child = $(child_field[i]);
@@ -345,15 +345,15 @@ instance.web.DataExport = instance.web.Dialog.extend({
}
},
add_field: function(field_id, string) {
- var field_list = this.$element.find('#fields_list');
- if (this.$element.find("#fields_list option[value='" + field_id + "']")
- && !this.$element.find("#fields_list option[value='" + field_id + "']").length) {
+ var field_list = this.$el.find('#fields_list');
+ if (this.$el.find("#fields_list option[value='" + field_id + "']")
+ && !this.$el.find("#fields_list option[value='" + field_id + "']").length) {
field_list.append(new Option(string, field_id));
}
},
get_fields: function() {
var export_field = [];
- this.$element.find("#fields_list option").each(function() {
+ this.$el.find("#fields_list option").each(function() {
export_field.push($(this).val());
});
if (!export_field.length) {
@@ -363,7 +363,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
},
on_click_export_data: function() {
var self = this;
- var exported_fields = this.$element.find('#fields_list option').map(function () {
+ var exported_fields = this.$el.find('#fields_list option').map(function () {
// DOM property is textContent, but IE8 only knows innerText
return {name: self.records[this.value] || this.value,
label: this.textContent || this.innerText};
@@ -375,7 +375,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
}
exported_fields.unshift({name: 'id', label: 'External ID'});
- var export_format = this.$element.find("#export_format").val();
+ var export_format = this.$el.find("#export_format").val();
instance.web.blockUI();
this.session.get_file({
url: '/web/export/' + export_format,
@@ -385,13 +385,13 @@ instance.web.DataExport = instance.web.Dialog.extend({
ids: this.dataset.ids,
domain: this.dataset.domain,
import_compat: Boolean(
- this.$element.find("#import_compat").val())
+ this.$el.find("#import_compat").val())
})},
complete: instance.web.unblockUI
});
},
close: function() {
- this.$element.remove();
+ this.$el.remove();
this._super();
}
});
diff --git a/addons/web/static/src/js/data_import.js b/addons/web/static/src/js/data_import.js
deleted file mode 100644
index 620878569ce..00000000000
--- a/addons/web/static/src/js/data_import.js
+++ /dev/null
@@ -1,393 +0,0 @@
-openerp.web.data_import = function(instance) {
-var QWeb = instance.web.qweb,
- _t = instance.web._t;
-/**
- * Safari does not deal well at all with raw JSON data being returned. As a
- * result, we're going to cheat by using a pseudo-jsonp: instead of getting
- * JSON data in the iframe, we're getting a ``script`` tag which consists of a
- * function call and the returned data (the json dump).
- *
- * The function is an auto-generated name bound to ``window``, which calls
- * back into the callback provided here.
- *
- * @param {Object} form the form element (DOM or jQuery) to use in the call
- * @param {Object} attributes jquery.form attributes object
- * @param {Function} callback function to call with the returned data
- */
-function jsonp(form, attributes, callback) {
- attributes = attributes || {};
- var options = {jsonp: _.uniqueId('import_callback_')};
- window[options.jsonp] = function () {
- delete window[options.jsonp];
- callback.apply(null, arguments);
- };
- if ('data' in attributes) {
- _.extend(attributes.data, options);
- } else {
- _.extend(attributes, {data: options});
- }
- $(form).ajaxSubmit(attributes);
-}
-
-instance.web.DataImport = instance.web.Dialog.extend({
- template: 'ImportDataView',
- dialog_title: {toString: function () { return _t("Import Data"); }},
- init: function(parent, dataset){
- var self = this;
- this._super(parent, {});
- this.model = parent.model;
- this.fields = [];
- this.all_fields = [];
- this.fields_with_defaults = [];
- this.required_fields = null;
-
- var convert_fields = function (root, prefix) {
- prefix = prefix || '';
- _(root.fields).each(function (f) {
- self.all_fields.push(prefix + f.name);
- if (f.fields) {
- convert_fields(f, prefix + f.id + '/');
- }
- });
- };
- this.ready = $.Deferred.queue().then(function () {
- self.required_fields = _(self.fields).chain()
- .filter(function (field) {
- return field.required &&
- !_.include(self.fields_with_defaults, field.id); })
- .pluck('id')
- .uniq()
- .value();
- convert_fields(self);
- self.all_fields.sort();
- });
- },
- start: function() {
- var self = this;
- this._super();
- this.open({
- buttons: [
- {text: _t("Close"), click: function() { self.destroy(); }},
- {text: _t("Import File"), click: function() { self.do_import(); }, 'class': 'oe_import_dialog_button'}
- ],
- close: function(event, ui) {
- self.destroy();
- }
- });
- this.toggle_import_button(false);
- this.$element.find('#csvfile').change(this.on_autodetect_data);
- this.$element.find('fieldset').change(this.on_autodetect_data);
- this.$element.delegate('fieldset legend', 'click', function() {
- $(this).parent().toggleClass('oe_closed');
- });
- this.ready.push(new instance.web.DataSet(this, this.model).call(
- 'fields_get', [], function (fields) {
- self.graft_fields(fields);
- self.ready.push(new instance.web.DataSet(self, self.model)
- .default_get(_.pluck(self.fields, 'id')).then(function (fields) {
- _.each(fields, function(val, key) {
- if (val) {
- self.fields_with_defaults.push(key);
- }
- });
- })
- )
- }));
- },
- graft_fields: function (fields, parent, level) {
- parent = parent || this;
- level = level || 0;
-
- var self = this;
- if (level === 0) {
- parent.fields.push({
- id: 'id',
- name: 'id',
- string: _t('External ID'),
- required: false
- });
- }
- _(fields).each(function (field, field_name) {
- // Ignore spec for id field
- // Don't import function fields (function and related)
- if (field_name === 'id') {
- return;
- }
- // Skip if there's no state which could disable @readonly,
- // if a field is ever always readonly we can't import it
- if (field.readonly) {
- // no states at all
- if (_.isEmpty(field.states)) { return; }
- // no state altering @readonly
- if (!_.any(field.states, function (modifiers) {
- return _(modifiers).chain().pluck(0).contains('readonly').value();
- })) { return; }
- }
-
- var f = {
- id: field_name,
- name: field_name,
- string: field.string,
- required: field.required
- };
-
- switch (field.type) {
- case 'many2many':
- case 'many2one':
- // push a copy for the bare many2one field, to allow importing
- // using name_search too - even if we default to exporting the XML ID
- var many2one_field = _.extend({}, f)
- parent.fields.push(many2one_field);
- f.name += '/id';
- break;
- case 'one2many':
- f.name += '/id';
- f.fields = [];
- // only fetch sub-fields to a depth of 2 levels
- if (level < 2) {
- self.ready.push(new instance.web.DataSet(self, field.relation).call(
- 'fields_get', [], function (fields) {
- self.graft_fields(fields, f, level+1);
- }));
- }
- break;
- }
- parent.fields.push(f);
- });
- },
- toggle_import_button: function (newstate) {
- instance.web.dialog(this.$element, 'widget')
- .find('.oe_import_dialog_button')
- .button('option', 'disabled', !newstate);
- },
- do_import: function() {
- if(!this.$element.find('#csvfile').val()) { return; }
- var lines_to_skip = parseInt(this.$element.find('#csv_skip').val(), 10);
- var with_headers = this.$element.find('#file_has_headers').prop('checked');
- if (!lines_to_skip && with_headers) {
- lines_to_skip = 1;
- }
- var indices = [], fields = [];
- this.$element.find(".sel_fields").each(function(index, element) {
- var val = element.value;
- if (!val) {
- return;
- }
- indices.push(index);
- fields.push(val);
- });
-
- jsonp(this.$element.find('#import_data'), {
- url: '/web/import/import_data',
- data: {
- model: this.model,
- meta: JSON.stringify({
- skip: lines_to_skip,
- indices: indices,
- fields: fields
- })
- }
- }, this.on_import_results);
- },
- on_autodetect_data: function() {
- if(!this.$element.find('#csvfile').val()) { return; }
- jsonp(this.$element.find('#import_data'), {
- url: '/web/import/detect_data'
- }, this.on_import_results);
- },
- on_import_results: function(results) {
- this.$element.find('#result').empty();
- var headers, result_node = this.$element.find("#result");
-
- if (results['error']) {
- result_node.append(QWeb.render('ImportView.error', {
- 'error': results['error']}));
- this.$element.find('fieldset').removeClass('oe_closed');
- return;
- }
- if (results['success']) {
- if (this.getParent().getParent().active_view == "list") {
- this.getParent().reload_content();
- }
- this.destroy();
- return;
- }
-
- if (results['records']) {
- var lines_to_skip = parseInt(this.$element.find('#csv_skip').val(), 10),
- with_headers = this.$element.find('#file_has_headers').prop('checked');
- headers = with_headers ? results.records[0] : null;
-
- result_node.append(QWeb.render('ImportView.result', {
- 'headers': headers,
- 'records': lines_to_skip ? results.records.slice(lines_to_skip)
- : with_headers ? results.records.slice(1)
- : results.records
- }));
- this.$element.find('fieldset').addClass('oe_closed');
- }
- this.$element.find('form').removeClass('oe_import_no_result');
-
- this.$element.delegate('.oe_m2o_drop_down_button', 'click', function () {
- $(this).prev('input').focus();
- });
-
- var self = this;
- this.ready.then(function () {
- var $fields = self.$element.find('.sel_fields').bind('blur', function () {
- if (this.value && !_(self.all_fields).contains(this.value)) {
- this.value = '';
- }
- }).autocomplete({
- minLength: 0,
- source: self.all_fields,
- change: self.on_check_field_values
- }).focus(function () {
- $(this).autocomplete('search');
- });
- // Column auto-detection
- _(headers).each(function (header, index) {
- var field_name = self.match_column_to_field(header);
- if (field_name) {
- $fields.eq(index).val(field_name);
- }
- });
- self.on_check_field_values();
- });
- },
- /**
- * Returns the name of the field (nested) matching the provided column name
- *
- * @param {String} name column name to look for
- * @param {Array} [fields] fields to look into for the provided name
- * @returns {String|undefined}
- */
- match_column_to_field: function (name, fields) {
- fields = fields || this.fields;
- var f;
- f = _(fields).detect(function (field) {
- return field.name === name
- });
- if (!f) {
- f = _(fields).detect(function (field) {
- // TODO: levenshtein between header and field.string
- return field.string.toLowerCase() === name.toLowerCase();
- });
- }
- if (f) { return f.name; }
-
- // if ``name`` is a path (o2m), we need to recurse through its .fields
- var index = name.indexOf('/');
- if (index === -1) { return undefined; }
- // Get the first path section, try to find the matching field
- var column_name = name.substring(0, index);
- f = _(fields).detect(function (field) {
- // field.name for o2m is $foo/id, so we want to match on id
- return field.id === column_name;
- });
- if (!f) {
- f = _(fields).detect(function (field) {
- return field.string.toLowerCase() === column_name.toLowerCase();
- });
- }
- if (!f) { return undefined; }
-
- // if we found a matching field for the first path section, recurse in
- // its own .fields to try and get the rest of the path matched
- var rest = this.match_column_to_field(
- name.substring(index+1), f.fields);
- if (!rest) { return undefined; }
- return f.id + '/' + rest;
- },
- /**
- * Looks through all the field selections, and tries to find if two
- * (or more) columns were matched to the same model field.
- *
- * Returns a map of the multiply-mapped fields to an array of offending
- * columns (not actually columns, but the inputs containing the same field
- * names).
- *
- * Also has the side-effect of marking the discovered inputs with the class
- * ``duplicate_fld``.
- *
- * @returns {Object<String, Array<String>>} map of duplicate field matches to same-valued inputs
- */
- find_duplicate_fields: function() {
- // Maps values to DOM nodes, in order to discover duplicates
- var values = {}, duplicates = {};
- this.$element.find(".sel_fields").each(function(index, element) {
- var value = element.value;
- var $element = $(element).removeClass('duplicate_fld');
- if (!value) { return; }
-
- if (!(value in values)) {
- values[value] = element;
- } else {
- var same_valued_field = values[value];
- if (value in duplicates) {
- duplicates[value].push(element);
- } else {
- duplicates[value] = [same_valued_field, element];
- }
- $element.add(same_valued_field).addClass('duplicate_fld');
- }
- });
- return duplicates;
- },
- on_check_field_values: function () {
- this.$element.find("#message, #msg").remove();
-
- var required_valid = this.check_required();
-
- var duplicates = this.find_duplicate_fields();
- if (_.isEmpty(duplicates)) {
- this.toggle_import_button(required_valid);
- } else {
- var $err = $('<div id="msg" style="color: red;">'+_t("Destination fields should only be selected once, some fields are selected more than once:")+'</div>').insertBefore(this.$element.find('#result'));
- var $dupes = $('<dl>').appendTo($err);
- _(duplicates).each(function(elements, value) {
- $('<dt>').text(value).appendTo($dupes);
- _(elements).each(function(element) {
- var cell = $(element).closest('td');
- $('<dd>').text(cell.parent().children().index(cell)).appendTo($dupes);
- });
- });
- this.toggle_import_button(false);
- }
-
- },
- check_required: function() {
- var self = this;
- if (!self.required_fields.length) { return true; }
-
- // Resolve field id based on column name, as there may be
- // several ways to provide the value for a given field and
- // thus satisfy the requirement.
- // (e.g. m2o_id or m2o_id/id columns may be provided)
- var resolve_field_id = function(column_name) {
- var f = _.detect(self.fields, function(field) {
- return field.name === column_name;
- });
- if (!f) { return column_name; };
- return f.id;
- };
-
- var selected_fields = _(this.$element.find('.sel_fields').get()).chain()
- .pluck('value')
- .compact()
- .map(resolve_field_id)
- .value();
-
- var missing_fields = _.difference(this.required_fields, selected_fields);
- if (missing_fields.length) {
- this.$element.find("#result").before('<div id="message" style="color:red">' + _t("*Required Fields are not selected :") + missing_fields + '.</div>');
- return false;
- }
- return true;
- },
- destroy: function() {
- this.$element.remove();
- this._super();
- }
-});
-};
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index a7625631aa5..8e9a31922b8 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -126,21 +126,21 @@ my.InputView = instance.web.Widget.extend({
template: 'SearchView.InputView',
start: function () {
var p = this._super.apply(this, arguments);
- this.$element.on('focus', this.proxy('onFocus'));
- this.$element.on('blur', this.proxy('onBlur'));
- this.$element.on('keydown', this.proxy('onKeydown'));
+ this.$el.on('focus', this.proxy('onFocus'));
+ this.$el.on('blur', this.proxy('onBlur'));
+ this.$el.on('keydown', this.proxy('onKeydown'));
return p;
},
onFocus: function () {
this.trigger('focused', this);
},
onBlur: function () {
- this.$element.text('');
+ this.$el.text('');
this.trigger('blurred', this);
},
getSelection: function () {
// get Text node
- var root = this.$element[0].childNodes[0];
+ var root = this.$el[0].childNodes[0];
if (!root || !root.textContent) {
// if input does not have a child node, or the child node is an
// empty string, then the selection can only be (0, 0)
@@ -202,7 +202,7 @@ my.InputView = instance.web.Widget.extend({
break;
case $.ui.keyCode.RIGHT:
sel = this.getSelection();
- var len = this.$element.text().length;
+ var len = this.$el.text().length;
if (sel.start !== len || sel.start !== sel.end) {
e.stopPropagation();
}
@@ -223,17 +223,17 @@ my.FacetView = instance.web.Widget.extend({
},
start: function () {
var self = this;
- this.$element.on('focus', function () { self.trigger('focused', self); });
- this.$element.on('blur', function () { self.trigger('blurred', self); });
- this.$element.on('click', function (e) {
+ this.$el.on('focus', function () { self.trigger('focused', self); });
+ this.$el.on('blur', function () { self.trigger('blurred', self); });
+ this.$el.on('click', function (e) {
if ($(e.target).is('.oe_facet_remove')) {
self.model.destroy();
return false;
}
- self.$element.focus();
+ self.$el.focus();
e.stopPropagation();
});
- this.$element.on('keydown', function (e) {
+ this.$el.on('keydown', function (e) {
var keys = $.ui.keyCode;
switch (e.which) {
case keys.BACKSPACE:
@@ -242,7 +242,7 @@ my.FacetView = instance.web.Widget.extend({
return false;
}
});
- var $e = self.$element.find('> span:last-child');
+ var $e = self.$el.find('> span:last-child');
var q = $.when(this._super());
return q.pipe(function () {
var values = self.model.values.map(function (value) {
@@ -253,7 +253,7 @@ my.FacetView = instance.web.Widget.extend({
});
},
model_changed: function () {
- this.$element.text(this.$element.text() + '*');
+ this.$el.text(this.$el.text() + '*');
}
});
my.FacetValueView = instance.web.Widget.extend({
@@ -268,7 +268,7 @@ my.FacetValueView = instance.web.Widget.extend({
this._super();
},
model_changed: function () {
- this.$element.text(this.$element.text() + '*');
+ this.$el.text(this.$el.text() + '*');
}
});
@@ -313,7 +313,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
.on('add change reset remove', this.proxy('renderFacets'));
if (this.hidden) {
- this.$element.hide();
+ this.$el.hide();
}
if (this.headless) {
this.ready.resolve();
@@ -331,12 +331,12 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
}
// Launch a search on clicking the oe_searchview_search button
- this.$element.on('click', 'button.oe_searchview_search', function (e) {
+ this.$el.on('click', 'button.oe_searchview_search', function (e) {
e.stopImmediatePropagation();
self.do_search();
});
- this.$element.on('keydown',
+ this.$el.on('keydown',
'.oe_searchview_input, .oe_searchview_facet', function (e) {
switch(e.which) {
case $.ui.keyCode.LEFT:
@@ -350,31 +350,31 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
}
});
- this.$element.on('click', '.oe_searchview_clear', function (e) {
+ this.$el.on('click', '.oe_searchview_clear', function (e) {
e.stopImmediatePropagation();
self.query.reset();
});
- this.$element.on('click', '.oe_searchview_unfold_drawer', function (e) {
+ this.$el.on('click', '.oe_searchview_unfold_drawer', function (e) {
e.stopImmediatePropagation();
- self.$element.toggleClass('oe_searchview_open_drawer');
+ self.$el.toggleClass('oe_searchview_open_drawer');
});
instance.web.bus.on('click', this, function(ev) {
if ($(ev.target).parents('.oe_searchview').length === 0) {
- self.$element.removeClass('oe_searchview_open_drawer');
+ self.$el.removeClass('oe_searchview_open_drawer');
}
});
// Focus last input if the view itself is clicked (empty section of
// facets element)
- this.$element.on('click', function (e) {
- if (e.target === self.$element.find('.oe_searchview_facets')[0]) {
- self.$element.find('.oe_searchview_input:last').focus();
+ this.$el.on('click', function (e) {
+ if (e.target === self.$el.find('.oe_searchview_facets')[0]) {
+ self.$el.find('.oe_searchview_input:last').focus();
}
});
// when the completion list opens/refreshes, automatically select the
// first completion item so if the user just hits [RETURN] or [TAB] it
// automatically selects it
- this.$element.on('autocompleteopen', function () {
- var menu = self.$element.data('autocomplete').menu;
+ this.$el.on('autocompleteopen', function () {
+ var menu = self.$el.data('autocomplete').menu;
menu.activate(
$.Event({ type: "mouseenter" }),
menu.element.children().first());
@@ -383,15 +383,15 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
return $.when(p, this.ready);
},
show: function () {
- this.$element.show();
+ this.$el.show();
},
hide: function () {
- this.$element.hide();
+ this.$el.hide();
},
subviewForRoot: function (subview_root) {
return _(this.input_subviews).detect(function (subview) {
- return subview.$element[0] === subview_root;
+ return subview.$el[0] === subview_root;
});
},
siblingSubview: function (subview, direction, wrap_around) {
@@ -406,12 +406,12 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
focusPreceding: function (subview_root) {
return this.siblingSubview(
this.subviewForRoot(subview_root), -1, true)
- .$element.focus();
+ .$el.focus();
},
focusFollowing: function (subview_root) {
return this.siblingSubview(
this.subviewForRoot(subview_root), +1, true)
- .$element.focus();
+ .$el.focus();
},
/**
@@ -430,19 +430,19 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
// autocomplete only correctly handles being initialized on the actual
// editable element (and only an element with a @value in 1.8 e.g.
- // input or textarea), cheat by setting val() on $element
- this.$element.on('keydown', function () {
+ // input or textarea), cheat by setting val() on $el
+ this.$el.on('keydown', function () {
// keydown is triggered *before* the element's value is set, so
// delay this. Pray that setTimeout are executed in FIFO (if they
// have the same delay) as autocomplete uses the exact same trick.
// FIXME: brittle as fuck
setTimeout(function () {
- self.$element.val(self.currentInputValue());
+ self.$el.val(self.currentInputValue());
}, 0);
});
- this.$element.autocomplete({
+ this.$el.autocomplete({
source: this.proxy('complete_global_search'),
select: this.proxy('select_completion'),
focus: function (e) { e.preventDefault(); },
@@ -479,7 +479,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
* div[contenteditable].oe_searchview_input)
*/
currentInputValue: function () {
- return this.$element.find('div.oe_searchview_input:focus').text();
+ return this.$el.find('div.oe_searchview_input:focus').text();
},
/**
* Provide auto-completion result for req.term (an array to `resp`)
@@ -509,22 +509,22 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
var input_index = _(this.input_subviews).indexOf(
this.subviewForRoot(
- this.$element.find('div.oe_searchview_input:focus')[0]));
+ this.$el.find('div.oe_searchview_input:focus')[0]));
this.query.add(ui.item.facet, {at: input_index / 2});
},
childFocused: function () {
- this.$element.addClass('oe_focused');
+ this.$el.addClass('oe_focused');
},
childBlurred: function () {
- var val = this.$element.val();
- this.$element.val('');
- var complete = this.$element.data('autocomplete');
+ var val = this.$el.val();
+ this.$el.val('');
+ var complete = this.$el.data('autocomplete');
if ((val && complete.term === undefined) || complete.previous !== undefined) {
throw new Error("new jquery.ui version altering implementation" +
" details relied on");
}
delete complete.term;
- this.$element.removeClass('oe_focused')
+ this.$el.removeClass('oe_focused')
.trigger('blur');
},
/**
@@ -538,7 +538,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
// _2: undefined if event=change, otherwise model
var self = this;
var started = [];
- var $e = this.$element.find('div.oe_searchview_facets');
+ var $e = this.$el.find('div.oe_searchview_facets');
_.invoke(this.input_subviews, 'destroy');
this.input_subviews = [];
@@ -569,7 +569,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
input_to_focus = self.input_subviews[(options.at + 1) * 2];
}
- input_to_focus.$element.focus();
+ input_to_focus.$el.focus();
});
},
@@ -664,7 +664,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
// build drawer
var drawer_started = $.when.apply(
null, _(this.select_for_drawer()).invoke(
- 'appendTo', this.$element.find('.oe_searchview_drawer')));
+ 'appendTo', this.$el.find('.oe_searchview_drawer')));
// load defaults
var defaults_fetched = $.when.apply(null, _(this.inputs).invoke(
@@ -680,7 +680,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
*/
on_filters_management: function(e) {
var self = this;
- var select = this.$element.find(".oe_search-view-filters-management");
+ var select = this.$el.find(".oe_search-view-filters-management");
var val = select.val();
switch(val) {
case 'advanced_filter':
@@ -989,7 +989,7 @@ instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends in
this.view.query.on('add remove change reset', this.proxy('search_change'));
},
start: function () {
- this.$element.on('click', 'li', this.proxy('toggle_filter'));
+ this.$el.on('click', 'li', this.proxy('toggle_filter'));
return $.when(null);
},
/**
@@ -998,7 +998,7 @@ instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends in
*/
search_change: function () {
var self = this;
- var $filters = this.$element.find('> li').removeClass('oe_selected');
+ var $filters = this.$el.find('> li').removeClass('oe_selected');
var facet = this.view.query.find(_.bind(this.match_facet, this));
if (!facet) { return; }
facet.values.each(function (v) {
@@ -1299,17 +1299,17 @@ instance.web.search.CharField = instance.web.search.Field.extend( /** @lends ins
});
instance.web.search.NumberField = instance.web.search.Field.extend(/** @lends instance.web.search.NumberField# */{
value_from: function () {
- if (!this.$element.val()) {
+ if (!this.$el.val()) {
return null;
}
- var val = this.parse(this.$element.val()),
- check = Number(this.$element.val());
+ var val = this.parse(this.$el.val()),
+ check = Number(this.$el.val());
if (isNaN(val) || val !== check) {
- this.$element.addClass('error');
+ this.$el.addClass('error');
throw new instance.web.search.Invalid(
- this.attrs.name, this.$element.val(), this.error_message);
+ this.attrs.name, this.$el.val(), this.error_message);
}
- this.$element.removeClass('error');
+ this.$el.removeClass('error');
return val;
}
});
@@ -1542,9 +1542,9 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
self.clear_selection();
})
.on('reset', this.proxy('clear_selection'));
- this.$element.on('submit', 'form', this.proxy('save_current'));
- this.$element.on('click', 'h4', function () {
- self.$element.toggleClass('oe_opened');
+ this.$el.on('submit', 'form', this.proxy('save_current'));
+ this.$el.on('click', 'h4', function () {
+ self.$el.toggleClass('oe_opened');
});
// FIXME: local eval of domain and context to get rid of special endpoint
return this.rpc('/web/searchview/get_filters', {
@@ -1552,7 +1552,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
}).pipe(this.proxy('set_filters'));
},
clear_selection: function () {
- this.$element.find('li.oe_selected').removeClass('oe_selected');
+ this.$el.find('li.oe_selected').removeClass('oe_selected');
},
append_filter: function (filter) {
var self = this;
@@ -1564,7 +1564,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
} else {
var id = filter.id;
$filter = this.filters[key] = $('<li></li>')
- .appendTo(this.$element.find('.oe_searchview_custom_list'))
+ .appendTo(this.$el.find('.oe_searchview_custom_list'))
.addClass(filter.user_id ? 'oe_searchview_custom_private'
: 'oe_searchview_custom_public')
.text(filter.name);
@@ -1599,8 +1599,8 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
},
save_current: function () {
var self = this;
- var $name = this.$element.find('input:first');
- var private_filter = !this.$element.find('input:last').prop('checked');
+ var $name = this.$el.find('input:first');
+ var private_filter = !this.$el.find('input:last').prop('checked');
var search = this.view.build_search_data();
this.rpc('/web/session/eval_domain_and_context', {
@@ -1622,7 +1622,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
return self.model.call('create_or_replace', [filter]).then(function (id) {
filter.id = id;
self.append_filter(filter);
- self.$element
+ self.$el
.removeClass('oe_opened')
.find('form')[0].reset();
});
@@ -1667,8 +1667,8 @@ instance.web.search.Filters = instance.web.search.Input.extend({
}
return $.when(
- this.render_column(col1, $('<div>').appendTo(this.$element)),
- this.render_column(col2, $('<div>').appendTo(this.$element)));
+ this.render_column(col1, $('<div>').appendTo(this.$el)),
+ this.render_column(col2, $('<div>').appendTo(this.$el)));
},
render_column: function (column, $el) {
return $.when.apply(null, _(column).map(function (group) {
@@ -1684,10 +1684,10 @@ instance.web.search.Advanced = instance.web.search.Input.extend({
_in_drawer: true,
start: function () {
var self = this;
- this.$element
+ this.$el
.on('keypress keydown keyup', function (e) { e.stopPropagation(); })
.on('click', 'h4', function () {
- self.$element.toggleClass('oe_opened');
+ self.$el.toggleClass('oe_opened');
}).on('click', 'button.oe_add_condition', function () {
self.append_proposition();
}).on('submit', 'form', function (e) {
@@ -1706,7 +1706,7 @@ instance.web.search.Advanced = instance.web.search.Input.extend({
},
append_proposition: function () {
return (new instance.web.search.ExtendedSearchProposition(this, this.fields))
- .appendTo(this.$element.find('ul'));
+ .appendTo(this.$el.find('ul'));
},
commit_search: function () {
var self = this;
@@ -1733,7 +1733,7 @@ instance.web.search.Advanced = instance.web.search.Input.extend({
// add new empty proposition
this.append_proposition();
// TODO: API on searchview
- this.view.$element.removeClass('oe_searchview_open_drawer');
+ this.view.$el.removeClass('oe_searchview_open_drawer');
}
});
@@ -1757,16 +1757,16 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
},
start: function () {
var _this = this;
- this.$element.find(".searchview_extended_prop_field").change(function() {
+ this.$el.find(".searchview_extended_prop_field").change(function() {
_this.changed();
});
- this.$element.find('.searchview_extended_delete_prop').click(function () {
+ this.$el.find('.searchview_extended_delete_prop').click(function () {
_this.destroy();
});
this.changed();
},
changed: function() {
- var nval = this.$element.find(".searchview_extended_prop_field").val();
+ var nval = this.$el.find(".searchview_extended_prop_field").val();
if(this.attrs.selected == null || nval != this.attrs.selected.name) {
this.select_field(_.detect(this.fields, function(x) {return x.name == nval;}));
}
@@ -1781,7 +1781,7 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
if(this.attrs.selected != null) {
this.value.destroy();
this.value = null;
- this.$element.find('.searchview_extended_prop_op').html('');
+ this.$el.find('.searchview_extended_prop_op').html('');
}
this.attrs.selected = field;
if(field == null) {
@@ -1797,9 +1797,9 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
_.each(this.value.operators, function(operator) {
$('<option>', {value: operator.value})
.text(String(operator.text))
- .appendTo(self.$element.find('.searchview_extended_prop_op'));
+ .appendTo(self.$el.find('.searchview_extended_prop_op'));
});
- var $value_loc = this.$element.find('.searchview_extended_prop_value').empty();
+ var $value_loc = this.$el.find('.searchview_extended_prop_value').empty();
this.value.appendTo($value_loc);
},
@@ -1807,7 +1807,7 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
if ( this.attrs.selected == null)
return null;
var field = this.attrs.selected;
- var op = this.$element.find('.searchview_extended_prop_op')[0];
+ var op = this.$el.find('.searchview_extended_prop_op')[0];
var operator = op.options[op.selectedIndex];
return {
label: _.str.sprintf(_t('%(field)s %(operator)s "%(value)s"'), {
@@ -1851,7 +1851,7 @@ instance.web.search.ExtendedSearchProposition.Char = instance.web.search.Extende
{value: "!=", text: _lt("is not equal to")}
],
get_value: function() {
- return this.$element.val();
+ return this.$el.val();
}
});
instance.web.search.ExtendedSearchProposition.DateTime = instance.web.search.ExtendedSearchProposition.Field.extend({
@@ -1875,7 +1875,7 @@ instance.web.search.ExtendedSearchProposition.DateTime = instance.web.search.Ext
start: function() {
var ready = this._super();
this.datewidget = new (this.widget())(this);
- this.datewidget.appendTo(this.$element);
+ this.datewidget.appendTo(this.$el);
return ready;
}
});
@@ -1893,11 +1893,11 @@ instance.web.search.ExtendedSearchProposition.Integer = instance.web.search.Exte
{value: "<=", text: _lt("less or equal than")}
],
toString: function () {
- return this.$element.val();
+ return this.$el.val();
},
get_value: function() {
try {
- return instance.web.parse_value(this.$element.val(), {'widget': 'integer'});
+ return instance.web.parse_value(this.$el.val(), {'widget': 'integer'});
} catch (e) {
return "";
}
@@ -1917,11 +1917,11 @@ instance.web.search.ExtendedSearchProposition.Float = instance.web.search.Extend
{value: "<=", text: _lt("less or equal than")}
],
toString: function () {
- return this.$element.val();
+ return this.$el.val();
},
get_value: function() {
try {
- return instance.web.parse_value(this.$element.val(), {'widget': 'float'});
+ return instance.web.parse_value(this.$el.val(), {'widget': 'float'});
} catch (e) {
return "";
}
@@ -1934,12 +1934,12 @@ instance.web.search.ExtendedSearchProposition.Selection = instance.web.search.Ex
{value: "!=", text: _lt("is not")}
],
toString: function () {
- var select = this.$element[0];
+ var select = this.$el[0];
var option = select.options[select.selectedIndex];
return option.label || option.text;
},
get_value: function() {
- return this.$element.val();
+ return this.$el.val();
}
});
instance.web.search.ExtendedSearchProposition.Boolean = instance.web.search.ExtendedSearchProposition.Field.extend({
diff --git a/addons/web/static/src/js/test_support.js b/addons/web/static/src/js/test_support.js
index 314a12c91c6..8e1317ba2b0 100644
--- a/addons/web/static/src/js/test_support.js
+++ b/addons/web/static/src/js/test_support.js
@@ -12,7 +12,6 @@ openerp.test_support = {
username: false,
user_context: {},
db: false,
- openerp_entreprise: false,
// this.module_list = openerp._modules.slice();
// this.module_loaded = {};
// _(this.module_list).each(function (mod) {
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 208ee3c0edb..08c9b96660e 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -23,10 +23,6 @@ instance.web.form.FieldManagerMixin = {
*/
get_field: function(field_name) {},
/**
- * Called by the field when the translate button is clicked.
- */
- open_translate_dialog: function(field) {},
- /**
* Returns true when the view is in create mode.
*/
is_create_mode: function() {},
@@ -96,14 +92,19 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
self.on("change:actual_mode", self, self.init_pager);
self.init_pager();
});
+ instance.web.bus.on('clear_uncommitted_changes', this, function(e) {
+ if (!this.can_be_discarded()) {
+ e.preventDefault();
+ }
+ });
},
destroy: function() {
_.each(this.get_widgets(), function(w) {
w.off('focused blurred');
w.destroy();
});
- if (this.$element) {
- this.$element.off('.formBlur');
+ if (this.$el) {
+ this.$el.off('.formBlur');
}
this._super();
},
@@ -122,11 +123,11 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
this.rendering_engine.set_tags_registry(this.tags_registry);
if (!this.extract_qweb_template(data)) {
this.rendering_engine.set_fields_view(data);
- var $dest = this.$element.hasClass("oe_form_container") ? this.$element : this.$element.find('.oe_form_container');
+ var $dest = this.$el.hasClass("oe_form_container") ? this.$el : this.$el.find('.oe_form_container');
this.rendering_engine.render_to($dest);
}
- this.$element.on('mousedown.formBlur', function () {
+ this.$el.on('mousedown.formBlur', function () {
self.__clicked_inside = true;
});
@@ -134,31 +135,31 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
if (this.options.$buttons) {
this.$buttons.appendTo(this.options.$buttons);
} else {
- this.$element.find('.oe_form_buttons').replaceWith(this.$buttons);
+ this.$el.find('.oe_form_buttons').replaceWith(this.$buttons);
}
this.$buttons.on('click','.oe_form_button_create',this.on_button_create);
this.$buttons.on('click','.oe_form_button_edit',this.on_button_edit);
this.$buttons.on('click','.oe_form_button_save',this.on_button_save);
this.$buttons.on('click','.oe_form_button_cancel',this.on_button_cancel);
- this.$sidebar = this.options.$sidebar || this.$element.find('.oe_form_sidebar');
+ this.$sidebar = this.options.$sidebar || this.$el.find('.oe_form_sidebar');
if (!this.sidebar && this.options.$sidebar) {
this.sidebar = new instance.web.Sidebar(this);
this.sidebar.appendTo(this.$sidebar);
- if(this.fields_view.toolbar) {
+ if (this.fields_view.toolbar) {
this.sidebar.add_toolbar(this.fields_view.toolbar);
}
- this.sidebar.add_items('other', [
- { label: _t('Delete'), callback: self.on_button_delete },
- { label: _t('Duplicate'), callback: self.on_button_duplicate },
+ this.sidebar.add_items('other', _.compact([
+ self.is_action_enabled('delete') && { label: _t('Delete'), callback: self.on_button_delete },
+ self.is_action_enabled('create') && { label: _t('Duplicate'), callback: self.on_button_duplicate },
{ label: _t('Set Default'), callback: function (item) { self.open_defaults_dialog(); } }
- ]);
+ ]));
}
this.has_been_loaded.resolve();
// Add bounce effect on button 'Edit' when click on readonly page view.
- this.$element.find(".oe_form_field,label").on('click', function (e) {
+ this.$el.find(".oe_form_field,label").on('click', function (e) {
if(self.get("actual_mode") == "view") {
var $button = self.options.$buttons.find(".oe_form_button_edit");
$button.effect('bounce', {distance: 18, times: 5}, 150)
@@ -215,7 +216,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
this.default_focus_field = null;
this.default_focus_button = null;
this.translatable_fields = [];
- this.$element.find('.oe_form_container').empty();
+ this.$el.find('.oe_form_container').empty();
},
widgetFocused: function() {
@@ -263,7 +264,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
var self = this;
options = options || {};
if (this.sidebar) {
- this.sidebar.$element.show();
+ this.sidebar.$el.show();
}
if (this.$buttons) {
this.$buttons.show();
@@ -271,11 +272,11 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
if (this.$pager) {
this.$pager.show();
}
- this.$element.show().css({
+ this.$el.show().css({
opacity: '0',
filter: 'alpha(opacity = 0)'
});
- this.$element.add(this.$buttons).removeClass('oe_form_dirty');
+ this.$el.add(this.$buttons).removeClass('oe_form_dirty');
var shown = this.has_been_loaded;
if (options.reload !== false) {
@@ -293,7 +294,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
}
return shown.pipe(function() {
self._actualize_mode(options.mode || self.options.initial_mode);
- self.$element.css({
+ self.$el.css({
opacity: '1',
filter: 'alpha(opacity = 100)'
});
@@ -301,7 +302,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
},
do_hide: function () {
if (this.sidebar) {
- this.sidebar.$element.hide();
+ this.sidebar.$el.hide();
}
if (this.$buttons) {
this.$buttons.hide();
@@ -325,7 +326,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
if (this.qweb) {
this.kill_current_form();
this.rendering_engine.set_fields_view(this.get_fvg_from_qweb(record));
- var $dest = this.$element.hasClass("oe_form_container") ? this.$element : this.$element.find('.oe_form_container');
+ var $dest = this.$el.hasClass("oe_form_container") ? this.$el : this.$el.find('.oe_form_container');
this.rendering_engine.render_to($dest);
}
@@ -357,7 +358,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
} else {
self.do_push_state({});
}
- self.$element.add(self.$buttons).removeClass('oe_form_dirty');
+ self.$el.add(self.$buttons).removeClass('oe_form_dirty');
self.autofocus();
});
},
@@ -379,7 +380,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
this.trigger("view_content_has_changed");
},
do_notify_change: function() {
- this.$element.add(this.$buttons).addClass('oe_form_dirty');
+ this.$el.add(this.$buttons).addClass('oe_form_dirty');
},
on_pager_action: function(action) {
if (this.can_be_discarded()) {
@@ -410,7 +411,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
if (this.options.$pager) {
this.$pager.appendTo(this.options.$pager);
} else {
- this.$element.find('.oe_form_pager').replaceWith(this.$pager);
+ this.$el.find('.oe_form_pager').replaceWith(this.$pager);
}
this.$pager.on('click','a[data-pager-action]',function() {
var action = $(this).data('pager-action');
@@ -653,7 +654,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
check_actual_mode: function(source, options) {
var self = this;
if(this.get("actual_mode") === "view") {
- self.$element.removeClass('oe_form_editable').addClass('oe_form_readonly');
+ self.$el.removeClass('oe_form_editable').addClass('oe_form_readonly');
self.$buttons.find('.oe_form_buttons_edit').hide();
self.$buttons.find('.oe_form_buttons_view').show();
self.$sidebar.show();
@@ -661,7 +662,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
field.set({"force_readonly": true});
});
} else {
- self.$element.removeClass('oe_form_readonly').addClass('oe_form_editable');
+ self.$el.removeClass('oe_form_readonly').addClass('oe_form_editable');
self.$buttons.find('.oe_form_buttons_edit').show();
self.$buttons.find('.oe_form_buttons_view').hide();
self.$sidebar.hide();
@@ -689,7 +690,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
},
on_button_save: function() {
var self = this;
- return this.do_save().then(function(result) {
+ return this.do_save().then(function(result) {
self.to_view_mode();
});
},
@@ -752,17 +753,24 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
return def.promise();
},
can_be_discarded: function() {
- return !this.$element.is('.oe_form_dirty') || confirm(_t("Warning, the record has been modified, your changes will be discarded."));
+ if (this.$el.is('.oe_form_dirty')) {
+ if (!confirm(_t("Warning, the record has been modified, your changes will be discarded.\n\nAre you sure you want to leave this page ?"))) {
+ return false;
+ }
+ this.$el.removeClass('oe_form_dirty');
+ }
+ return true;
},
/**
* Triggers saving the form's record. Chooses between creating a new
* record or saving an existing one depending on whether the record
* already has an id property.
*
- * @param {Function} [success] callback on save success
- * @param {Boolean} [prepend_on_create=false] if ``do_save`` creates a new record, should that record be inserted at the start of the dataset (by default, records are added at the end)
+ * @param {Boolean} [prepend_on_create=false] if ``do_save`` creates a new
+ * record, should that record be inserted at the start of the dataset (by
+ * default, records are added at the end)
*/
- do_save: function(success, prepend_on_create) {
+ do_save: function(prepend_on_create) {
var self = this;
return this.mutating_mutex.exec(function() { return self.is_initialized.pipe(function() {
try {
@@ -797,21 +805,21 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
self.set({'display_invalid_fields': false});
var save_deferral;
if (!self.datarecord.id) {
- // console.log("FormView(", self, ") : About to create", values);
+ // Creation save
save_deferral = self.dataset.create(values).pipe(function(r) {
- return self.on_created(r, undefined, prepend_on_create);
+ return self.on_created(r, prepend_on_create);
}, null);
} else if (_.isEmpty(values) && ! self.force_dirty) {
- // console.log("FormView(", self, ") : Nothing to save");
+ // Not dirty, noop save
save_deferral = $.Deferred().resolve({}).promise();
} else {
self.force_dirty = false;
- // console.log("FormView(", self, ") : About to save", values);
+ // Write save
save_deferral = self.dataset.write(self.datarecord.id, values, {}).pipe(function(r) {
return self.on_saved(r);
}, null);
}
- return save_deferral.then(success);
+ return save_deferral;
}
} catch (e) {
console.error(e);
@@ -830,14 +838,19 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
warnings.push('</ul>');
this.do_warn("The following fields are invalid :", warnings.join(''));
},
- on_saved: function(r, success) {
+ /**
+ * Reload the form after saving
+ *
+ * @param {Object} r result of the write function.
+ */
+ on_saved: function(r) {
if (!r.result) {
// should not happen in the server, but may happen for internal purpose
return $.Deferred().reject();
} else {
return $.when(this.reload()).pipe(function () {
- return r; })
- .then(success);
+ return r;
+ });
}
},
/**
@@ -850,10 +863,10 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
* * Updates the pager and sidebar displays
*
* @param {Object} r
- * @param {Function} success callback to execute after having updated the dataset
- * @param {Boolean} [prepend_on_create=false] adds the newly created record at the beginning of the dataset instead of the end
+ * @param {Boolean} [prepend_on_create=false] adds the newly created record
+ * at the beginning of the dataset instead of the end
*/
- on_created: function(r, success, prepend_on_create) {
+ on_created: function(r, prepend_on_create) {
if (!r.result) {
// should not happen in the server, but may happen for internal purpose
return $.Deferred().reject();
@@ -872,8 +885,8 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
}
//openerp.log("The record has been created with id #" + this.datarecord.id);
return $.when(this.reload()).pipe(function () {
- return _.extend(r, {created: true}); })
- .then(success);
+ return _.extend(r, {created: true});
+ });
}
},
on_action: function (action) {
@@ -960,15 +973,12 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
return false;
}
var displayed = value;
- switch (field.field.type) {
- case 'selection':
+ if (field instanceof instance.web.form.FieldSelection) {
displayed = _(field.values).find(function (option) {
return option[0] === value;
})[1];
- break;
- case 'many2one':
+ } else if (field instanceof instance.web.form.FieldMany2One) {
displayed = field.get_displayed();
- break;
}
return {
@@ -996,14 +1006,14 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
buttons: [
{text: _t("Close"), click: function () { d.close(); }},
{text: _t("Save default"), click: function () {
- var $defaults = d.$element.find('#formview_default_fields');
+ var $defaults = d.$el.find('#formview_default_fields');
var field_to_set = $defaults.val();
if (!field_to_set) {
$defaults.parent().addClass('oe_form_invalid');
return;
}
- var condition = d.$element.find('#formview_default_conditions').val(),
- all_users = d.$element.find('#formview_default_all').is(':checked');
+ var condition = d.$el.find('#formview_default_conditions').val(),
+ all_users = d.$el.find('#formview_default_all').is(':checked');
new instance.web.DataSet(self, 'ir.values').call(
'set_default', [
self.dataset.model,
@@ -1046,9 +1056,6 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
is_create_mode: function() {
return this.get("actual_mode") === "create";
},
- open_translate_dialog: function(field) {
- return this._super(field);
- },
});
/**
@@ -1057,7 +1064,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
instance.web.form.FormRenderingEngineInterface = instance.web.Class.extend({
set_fields_view: function(fields_view) {},
set_fields_registry: function(fields_registry) {},
- render_to: function($element) {},
+ render_to: function($el) {},
});
/**
@@ -1462,7 +1469,7 @@ instance.web.form.FormDialog = instance.web.Dialog.extend({
this.form = new instance.web.FormView(this, this.dataset, this.view_id, {
pager: false
});
- this.form.appendTo(this.$element);
+ this.form.appendTo(this.$el);
this.form.on_created.add_last(this.on_form_dialog_saved);
this.form.on_saved.add_last(this.on_form_dialog_saved);
return this;
@@ -1554,7 +1561,7 @@ instance.web.form.compute_domain = function(expr, fields) {
/**
* Must be applied over an class already possessing the PropertiesMixin.
*
- * Apply the result of the "invisible" domain to this.$element.
+ * Apply the result of the "invisible" domain to this.$el.
*/
instance.web.form.InvisibilityChangerMixin = {
init: function(field_manager, invisible_domain) {
@@ -1585,16 +1592,16 @@ instance.web.form.InvisibilityChangerMixin = {
this._check_visibility();
},
_check_visibility: function() {
- this.$element.toggleClass('oe_form_invisible', this.get("effective_invisible"));
+ this.$el.toggleClass('oe_form_invisible', this.get("effective_invisible"));
},
};
instance.web.form.InvisibilityChanger = instance.web.Class.extend(instance.web.PropertiesMixin, instance.web.form.InvisibilityChangerMixin, {
- init: function(parent, field_manager, invisible_domain, $element) {
+ init: function(parent, field_manager, invisible_domain, $el) {
this.setParent(parent);
instance.web.PropertiesMixin.init.call(this);
instance.web.form.InvisibilityChangerMixin.init.call(this, field_manager, invisible_domain);
- this.$element = $element;
+ this.$el = $el;
this.start();
},
});
@@ -1618,7 +1625,7 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi
},
renderElement: function() {
this._super();
- this.$element.addClass(this.node.attrs["class"] || "");
+ this.$el.addClass(this.node.attrs["class"] || "");
},
destroy: function() {
$.fn.tipsy.clear();
@@ -1652,7 +1659,7 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi
},
do_attach_tooltip: function(widget, trigger, options) {
widget = widget || this;
- trigger = trigger || this.$element;
+ trigger = trigger || this.$el;
options = _.extend({
delayIn: 500,
delayOut: 0,
@@ -1739,11 +1746,11 @@ instance.web.form.WidgetButton = instance.web.form.FormWidget.extend({
},
start: function() {
this._super.apply(this, arguments);
- this.$element.click(this.on_click);
+ this.$el.click(this.on_click);
if (this.node.attrs.help || instance.session.debug) {
this.do_attach_tooltip();
}
- this.setupFocus(this.$element);
+ this.setupFocus(this.$el);
},
on_click: function() {
var self = this;
@@ -1802,8 +1809,8 @@ instance.web.form.WidgetButton = instance.web.form.FormWidget.extend({
},
check_disable: function() {
var disabled = (this.force_disabled || !this.view.is_interactible_record());
- this.$element.prop('disabled', disabled);
- this.$element.css('color', disabled ? 'grey' : '');
+ this.$el.prop('disabled', disabled);
+ this.$el.css('color', disabled ? 'grey' : '');
}
});
@@ -1879,6 +1886,10 @@ instance.web.form.FieldInterface = {
* Must set the focus on the field. Return false if field is not focusable.
*/
focus: function() {},
+ /**
+ * Called when the translate button is clicked.
+ */
+ on_translate: function() {},
};
/**
@@ -1908,6 +1919,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w
this.field = this.field_manager.get_field(this.name);
this.widget = this.node.attrs.widget;
this.string = this.node.attrs.string || this.field.string || this.name;
+ this.options = JSON.parse(this.node.attrs.options || '{}');
this.set({'value': false});
this.set({required: this.modifiers['required'] === true});
@@ -1931,14 +1943,12 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w
var self = this;
this._super();
if (this.field.translate) {
- this.$element.addClass('oe_form_field_translatable');
- this.$element.find('.oe_field_translate').click(_.bind(function() {
- this.field_manager.open_translate_dialog(this);
- }, this));
+ this.$el.addClass('oe_form_field_translatable');
+ this.$el.find('.oe_field_translate').click(this.on_translate);
}
- this.$label = this.view.$element.find('label[for=' + this.id_for_label + ']');
+ this.$label = this.view.$el.find('label[for=' + this.id_for_label + ']');
if (instance.session.debug) {
- this.do_attach_tooltip(this, this.$label[0] || this.$element);
+ this.do_attach_tooltip(this, this.$label[0] || this.$el);
this.$label.off('dblclick').on('dblclick', function() {
console.log("Field '%s' of type '%s' in View: %o", self.name, (self.node.attrs.widget || self.field.type), self.view);
window.w = self;
@@ -1957,7 +1967,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w
* Private. Do not use.
*/
_set_required: function() {
- this.$element.toggleClass('oe_form_required', this.get("required"));
+ this.$el.toggleClass('oe_form_required', this.get("required"));
},
set_value: function(value_) {
this._inhibit_on_change = true;
@@ -1982,30 +1992,27 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w
},
_check_css_flags: function() {
if (this.field.translate) {
- this.$element.find('.oe_field_translate').toggle(!this.field_manager.is_create_mode());
+ this.$el.find('.oe_field_translate').toggle(!this.field_manager.is_create_mode());
}
if (!this.disable_utility_classes) {
if (this.field_manager.get('display_invalid_fields')) {
- this.$element.toggleClass('oe_form_invalid', !this.is_valid());
+ this.$el.toggleClass('oe_form_invalid', !this.is_valid());
}
}
},
focus: function() {
return false;
},
- /**
- * Utility method to get the widget options defined in the field xml description.
- */
- get_definition_options: function() {
- if (!this.definition_options) {
- var str = this.node.attrs.options || '{}';
- this.definition_options = JSON.parse(str);
- }
- return this.definition_options;
- },
set_input_id: function(id) {
this.id_for_label = id;
},
+ on_translate: function() {
+ var self = this;
+ var trans = new instance.web.DataSet(this, 'ir.translation');
+ return trans.call_button('translate_fields', [this.view.dataset.model, this.view.datarecord.id, this.name, this.view.dataset.get_context()]).then(function(r) {
+ self.do_action(r.result);
+ });
+ },
});
/**
@@ -2054,7 +2061,7 @@ instance.web.form.FieldChar = instance.web.form.AbstractField.extend(instance.we
},
initialize_content: function() {
var self = this;
- var $input = this.$element.find('input');
+ var $input = this.$el.find('input');
$input.change(function() {
self.set({'value': instance.web.parse_value($input.val(), self)});
});
@@ -2067,18 +2074,18 @@ instance.web.form.FieldChar = instance.web.form.AbstractField.extend(instance.we
render_value: function() {
var show_value = instance.web.format_value(this.get('value'), this, '');
if (!this.get("effective_readonly")) {
- this.$element.find('input').val(show_value);
+ this.$el.find('input').val(show_value);
} else {
if (this.password) {
show_value = new Array(show_value.length + 1).join('*');
}
- this.$element.text(show_value);
+ this.$el.text(show_value);
}
},
is_syntax_valid: function() {
if (!this.get("effective_readonly")) {
try {
- var value_ = instance.web.parse_value(this.$element.find('input').val(), this, '');
+ var value_ = instance.web.parse_value(this.$el.find('input').val(), this, '');
return true;
} catch(e) {
return false;
@@ -2102,7 +2109,7 @@ instance.web.form.FieldEmail = instance.web.form.FieldChar.extend({
template: 'FieldEmail',
initialize_content: function() {
this._super();
- var $button = this.$element.find('button');
+ var $button = this.$el.find('button');
$button.click(this.on_button_clicked);
this.setupFocus($button);
},
@@ -2110,7 +2117,7 @@ instance.web.form.FieldEmail = instance.web.form.FieldChar.extend({
if (!this.get("effective_readonly")) {
this._super();
} else {
- this.$element.find('a')
+ this.$el.find('a')
.attr('href', 'mailto:' + this.get('value'))
.text(this.get('value') || '');
}
@@ -2128,7 +2135,7 @@ instance.web.form.FieldUrl = instance.web.form.FieldChar.extend({
template: 'FieldUrl',
initialize_content: function() {
this._super();
- var $button = this.$element.find('button');
+ var $button = this.$el.find('button');
$button.click(this.on_button_clicked);
this.setupFocus($button);
},
@@ -2141,7 +2148,7 @@ instance.web.form.FieldUrl = instance.web.form.FieldChar.extend({
if (!s) {
tmp = "http://" + this.get('value');
}
- this.$element.find('a').attr('href', tmp).text(this.get('value') ? tmp : '');
+ this.$el.find('a').attr('href', tmp).text(this.get('value') ? tmp : '');
}
},
on_button_clicked: function() {
@@ -2190,8 +2197,8 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({
},
start: function() {
var self = this;
- this.$input = this.$element.find('input.oe_datepicker_master');
- this.$input_picker = this.$element.find('input.oe_datepicker_container');
+ this.$input = this.$el.find('input.oe_datepicker_master');
+ this.$input_picker = this.$el.find('input.oe_datepicker_container');
this.$input.change(this.on_change);
this.picker({
onClose: this.on_picker_select,
@@ -2199,9 +2206,10 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({
changeMonth: true,
changeYear: true,
showWeek: true,
- showButtonPanel: true
+ showButtonPanel: true,
+ firstDay: Date.CultureInfo.firstDayOfWeek
});
- this.$element.find('img.oe_datepicker_trigger').click(function() {
+ this.$el.find('img.oe_datepicker_trigger').click(function() {
if (self.get("effective_readonly") || self.picker('widget').is(':visible')) {
self.$input.focus();
return;
@@ -2238,7 +2246,7 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({
set_readonly: function(readonly) {
this.readonly = readonly;
this.$input.prop('readonly', this.readonly);
- this.$element.find('img.oe_datepicker_trigger').toggleClass('oe_input_icon_disabled', readonly);
+ this.$el.find('img.oe_datepicker_trigger').toggleClass('oe_input_icon_disabled', readonly);
},
is_valid_: function() {
var value_ = this.$input.val();
@@ -2288,7 +2296,7 @@ instance.web.form.FieldDatetime = instance.web.form.AbstractField.extend(instanc
this.datewidget.on_change.add_last(_.bind(function() {
this.set({'value': this.datewidget.get_value()});
}, this));
- this.datewidget.appendTo(this.$element);
+ this.datewidget.appendTo(this.$el);
this.setupFocus(this.datewidget.$input);
}
},
@@ -2300,7 +2308,7 @@ instance.web.form.FieldDatetime = instance.web.form.AbstractField.extend(instanc
if (!this.get("effective_readonly")) {
this.datewidget.set_value(this.get('value'));
} else {
- this.$element.text(instance.web.format_value(this.get('value'), this, ''));
+ this.$el.text(instance.web.format_value(this.get('value'), this, ''));
}
},
is_syntax_valid: function() {
@@ -2328,16 +2336,21 @@ instance.web.form.FieldDate = instance.web.form.FieldDatetime.extend({
instance.web.form.FieldText = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, {
template: 'FieldText',
+ init: function (field_manager, node) {
+ this._super(field_manager, node);
+ },
initialize_content: function() {
- this.$textarea = this.$element.find('textarea');
+ var self = this;
+ this.$textarea = this.$el.find('textarea');
+ this.default_height = this.$textarea.css('height');
if (!this.get("effective_readonly")) {
this.$textarea.change(_.bind(function() {
- this.set({'value': instance.web.parse_value(this.$textarea.val(), this)});
+ self.set({'value': instance.web.parse_value(self.$textarea.val(), self)});
}, this));
} else {
this.$textarea.attr('disabled', 'disabled');
}
- this.$element.keyup(function (e) {
+ this.$el.keyup(function (e) {
if (e.which === $.ui.keyCode.ENTER) {
e.stopPropagation();
}
@@ -2345,15 +2358,17 @@ instance.web.form.FieldText = instance.web.form.AbstractField.extend(instance.we
this.setupFocus(this.$textarea);
},
set_value: function(value_) {
- this._super.apply(this, arguments);
+ this._super(value_);
this.render_value();
+ $(window).resize();
},
render_value: function() {
var show_value = instance.web.format_value(this.get('value'), this, '');
- this.$textarea.val(show_value);
- if (show_value && this.view.options.resize_textareas) {
- this.do_resize(this.view.options.resize_textareas);
+ if (show_value === '') {
+ this.$textarea.css('height', parseInt(this.default_height)+"px");
}
+ this.$textarea.val(show_value);
+ this.$textarea.autosize();
},
is_syntax_valid: function() {
if (!this.get("effective_readonly")) {
@@ -2369,29 +2384,9 @@ instance.web.form.FieldText = instance.web.form.AbstractField.extend(instance.we
is_false: function() {
return this.get('value') === '' || this._super();
},
- focus: function($element) {
+ focus: function($el) {
this.$textarea.focus();
},
- do_resize: function(max_height) {
- max_height = parseInt(max_height, 10);
- var $input = this.$textarea,
- $div = $('<div style="position: absolute; z-index: 1000; top: 0"/>').width($input.width()),
- new_height;
- $div.text($input.val());
- _.each('font-family,font-size,white-space'.split(','), function(style) {
- $div.css(style, $input.css(style));
- });
- $div.appendTo($('body'));
- new_height = $div.height();
- if (new_height < 90) {
- new_height = 90;
- }
- if (!isNaN(max_height) && new_height > max_height) {
- new_height = max_height;
- }
- $div.remove();
- $input.height(new_height);
- },
});
/**
@@ -2405,7 +2400,7 @@ instance.web.form.FieldTextHtml = instance.web.form.AbstractField.extend(instanc
template: 'FieldTextHtml',
init: function() {
this._super.apply(this, arguments);
- if (this.field.type !== 'html') {
+ if (this.field.type !== 'html' && ! this.options.safe) {
throw new Error(_.str.sprintf(
_t("Error with field %s, it is not allowed to use the widget 'html' with any other field type than 'html'"), this.string));
}
@@ -2414,9 +2409,9 @@ instance.web.form.FieldTextHtml = instance.web.form.AbstractField.extend(instanc
var self = this;
if (! this.get("effective_readonly")) {
self._updating_editor = false;
- this.$textarea = this.$element.find('textarea');
+ this.$textarea = this.$el.find('textarea');
var width = ((this.node.attrs || {}).editor_width || 468);
- var height = ((this.node.attrs || {}).editor_height || 100);
+ var height = ((this.node.attrs || {}).editor_height || 250);
this.$textarea.cleditor({
width: width, // width not including margins, borders or padding
height: height, // height not including margins, borders or padding
@@ -2447,7 +2442,7 @@ instance.web.form.FieldTextHtml = instance.web.form.AbstractField.extend(instanc
this.$cleditor.updateFrame();
this._updating_editor = false;
} else {
- this.$element.html(this.get('value'));
+ this.$el.html(this.get('value'));
}
},
});
@@ -2457,9 +2452,9 @@ instance.web.form.FieldBoolean = instance.web.form.AbstractField.extend({
start: function() {
var self = this;
this._super.apply(this, arguments);
- this.$checkbox = $("input", this.$element);
+ this.$checkbox = $("input", this.$el);
this.setupFocus(this.$checkbox);
- this.$element.click(_.bind(function() {
+ this.$el.click(_.bind(function() {
this.set({'value': this.$checkbox.is(':checked')});
}, this));
var check_readonly = function() {
@@ -2481,7 +2476,7 @@ instance.web.form.FieldProgressBar = instance.web.form.AbstractField.extend({
template: 'FieldProgressBar',
start: function() {
this._super.apply(this, arguments);
- this.$element.progressbar({
+ this.$el.progressbar({
value: this.get('value'),
disabled: this.get("effective_readonly")
});
@@ -2493,7 +2488,7 @@ instance.web.form.FieldProgressBar = instance.web.form.AbstractField.extend({
show_value = 0;
}
var formatted_value = instance.web.format_value(show_value, { type : 'float' }, '0');
- this.$element.progressbar('option', 'value', show_value).find('span').html(formatted_value + '%');
+ this.$el.progressbar('option', 'value', show_value).find('span').html(formatted_value + '%');
}
});
@@ -2524,9 +2519,9 @@ instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instan
// changing the selected value), takes the action as validating the
// row
var ischanging = false;
- var $select = this.$element.find('select')
+ var $select = this.$el.find('select')
.change(_.bind(function() {
- this.set({'value': this.values[this.$element.find('select')[0].selectedIndex][0]});
+ this.set({'value': this.values[this.$el.find('select')[0].selectedIndex][0]});
}, this))
.change(function () { ischanging = true; })
.click(function () { ischanging = false; })
@@ -2549,27 +2544,27 @@ instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instan
for (var i = 0, ii = this.values.length; i < ii; i++) {
if (this.values[i][0] === this.get('value')) index = i;
}
- this.$element.find('select')[0].selectedIndex = index;
+ this.$el.find('select')[0].selectedIndex = index;
} else {
var self = this;
var option = _(this.values)
.detect(function (record) { return record[0] === self.get('value'); });
- this.$element.text(option ? option[1] : this.values[0][1]);
+ this.$el.text(option ? option[1] : this.values[0][1]);
}
},
is_syntax_valid: function() {
if (this.get("effective_readonly")) {
return true;
}
- var value_ = this.values[this.$element.find('select')[0].selectedIndex];
+ var value_ = this.values[this.$el.find('select')[0].selectedIndex];
return !! value_;
},
focus: function() {
- this.$element.find('select:first').focus();
+ this.$el.find('select:first').focus();
}
});
-// jquery autocomplete tweak to allow html
+// jquery autocomplete tweak to allow html and classnames
(function() {
var proto = $.ui.autocomplete.prototype,
initSource = proto._initSource;
@@ -2596,7 +2591,8 @@ instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instan
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( $( "<a></a>" )[ this.options.html ? "html" : "text" ]( item.label ) )
- .appendTo( ul );
+ .appendTo( ul )
+ .addClass(item.classname);
}
});
})();
@@ -2636,25 +2632,36 @@ instance.web.form.CompletionFieldMixin = {
// search more... if more results that max
if (values.length > self.limit) {
values = values.slice(0, self.limit);
- values.push({label: _t("<em>   Search More...</em>"), action: function() {
- dataset.name_search(search_val, self.build_domain(), 'ilike'
- , false, function(data) {
- self._search_create_popup("search", data);
- });
- }});
+ values.push({
+ label: _t("Search More..."),
+ action: function() {
+ dataset.name_search(search_val, self.build_domain(), 'ilike', false, function(data) {
+ self._search_create_popup("search", data);
+ });
+ },
+ classname: 'oe_m2o_dropdown_option'
+ });
}
// quick create
var raw_result = _(data.result).map(function(x) {return x[1];});
if (search_val.length > 0 && !_.include(raw_result, search_val)) {
- values.push({label: _.str.sprintf(_t('<em>   Create "<strong>%s</strong>"</em>'),
- $('<span />').text(search_val).html()), action: function() {
- self._quick_create(search_val);
- }});
+ values.push({
+ label: _.str.sprintf(_t('Create "<strong>%s</strong>"'),
+ $('<span />').text(search_val).html()),
+ action: function() {
+ self._quick_create(search_val);
+ },
+ classname: 'oe_m2o_dropdown_option'
+ });
}
// create...
- values.push({label: _t("<em>   Create and Edit...</em>"), action: function() {
- self._search_create_popup("form", undefined, {});
- }});
+ values.push({
+ label: _t("Create and Edit..."),
+ action: function() {
+ self._search_create_popup("form", undefined, self._create_context(search_val));
+ },
+ classname: 'oe_m2o_dropdown_option'
+ });
return values;
});
@@ -2665,9 +2672,9 @@ instance.web.form.CompletionFieldMixin = {
_quick_create: function(name) {
var self = this;
var slow_create = function () {
- self._search_create_popup("form", undefined, {"default_name": name});
+ self._search_create_popup("form", undefined, self._create_context(name));
};
- if (self.get_definition_options().quick_create === undefined || self.get_definition_options().quick_create) {
+ if (self.options.quick_create === undefined || self.options.quick_create) {
new instance.web.DataSet(this, this.field.relation, self.build_context())
.name_create(name, function(data) {
self.add_id(data[0]);
@@ -2702,6 +2709,13 @@ instance.web.form.CompletionFieldMixin = {
* To implement.
*/
add_id: function(id) {},
+ _create_context: function(name) {
+ var tmp = {};
+ var field = (this.options || {}).create_name_field;
+ if (field !== false && (this.options || {}).quick_create !== false)
+ tmp["default_" + field] = name || "name";
+ return tmp;
+ },
};
instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instance.web.form.CompletionFieldMixin, instance.web.form.ReinitializeFieldMixin, {
@@ -2736,7 +2750,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
},
render_editable: function() {
var self = this;
- this.$input = this.$element.find("input");
+ this.$input = this.$el.find("input");
self.$input.tipsy({
title: function() {
@@ -2756,8 +2770,8 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
self.$input.tipsy("hide");
});
- this.$drop_down = this.$element.find(".oe_m2o_drop_down_button");
- this.$follow_button = $(".oe_m2o_cm_button", this.$element);
+ this.$drop_down = this.$el.find(".oe_m2o_drop_down_button");
+ this.$follow_button = $(".oe_m2o_cm_button", this.$el);
this.$follow_button.click(function() {
if (!self.get('value')) {
@@ -2850,7 +2864,21 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
self.tip_def.reject();
}
};
- this.$input.focusout(anyoneLoosesFocus);
+ var ignore_blur = false;
+ this.$input.on({
+ focusout: anyoneLoosesFocus,
+ focus: function () { self.trigger('focused'); },
+ autocompleteopen: function () { ignore_blur = true; },
+ autocompleteclose: function () { ignore_blur = false; },
+ blur: function () {
+ // autocomplete open
+ if (ignore_blur) { return; }
+ if (_(self.getChildren()).any(function (child) {
+ return child instanceof instance.web.form.AbstractFormPopup;
+ })) { return; }
+ self.trigger('blurred');
+ }
+ });
var isSelecting = false;
// autocomplete
@@ -2868,7 +2896,6 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
self.display_value["" + item.id] = item.name;
self.set({value: item.id});
} else if (item.action) {
- self.floating = true;
item.action();
// Cancel widget blurring, to avoid form blur event
self.trigger('focused');
@@ -2893,7 +2920,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
}
isSelecting = false;
});
- this.setupFocus(this.$input.add(this.$follow_button));
+ this.setupFocus(this.$follow_button);
},
render_value: function(no_recurse) {
var self = this;
@@ -2924,7 +2951,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
var lines = _.escape(str).split("\n");
var link = "";
var follow = "";
- if (! this.get_definition_options().highlight_first_line) {
+ if (! this.options.highlight_first_line) {
link = lines.join("<br />");
} else {
link = lines[0];
@@ -2932,10 +2959,10 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
if (follow)
link += "<br />";
}
- var $link = this.$element.find('.oe_form_uri')
+ var $link = this.$el.find('.oe_form_uri')
.unbind('click')
.html(link);
- if (! this.get_definition_options().no_open)
+ if (! this.options.no_open)
$link.click(function () {
self.do_action({
type: 'ir.actions.act_window',
@@ -2947,14 +2974,14 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
});
return false;
});
- $(".oe_form_m2o_follow", this.$element).html(follow);
+ $(".oe_form_m2o_follow", this.$el).html(follow);
}
},
set_value: function(value_) {
var self = this;
if (value_ instanceof Array) {
this.display_value = {};
- if (! this.get_definition_options().always_reload) {
+ if (! this.options.always_reload) {
this.display_value["" + value_[0]] = value_[1];
}
value_ = value_[0];
@@ -3048,7 +3075,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
},
start: function() {
this._super.apply(this, arguments);
- this.$element.addClass('oe_form_field oe_form_field_one2many');
+ this.$el.addClass('oe_form_field oe_form_field_one2many');
var self = this;
@@ -3158,7 +3185,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
}
} else if (view_type === "form") {
if (self.get("effective_readonly")) {
- $(".oe_form_buttons", controller.$element).children().remove();
+ $(".oe_form_buttons", controller.$el).children().remove();
}
controller.on_record_loaded.add_last(function() {
once.resolve();
@@ -3179,7 +3206,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
});
this.is_setted.then(function() {
$.async_when().then(function () {
- self.viewmanager.appendTo(self.$element);
+ self.viewmanager.appendTo(self.$el);
});
});
return def;
@@ -3400,7 +3427,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({
},
start: function () {
var ret = this._super();
- this.$element
+ this.$el
.off('mousedown.handleButtons')
.on('mousedown.handleButtons', 'table button', this.proxy('_button_down'));
return ret;
@@ -3414,7 +3441,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({
// If the form has not been modified, the view can only be valid
// NB: is_dirty will also be set on defaults/onchanges/whatever?
// oe_form_dirty seems to only be set on actual user actions
- if (!form.$element.is('.oe_form_dirty')) {
+ if (!form.$el.is('.oe_form_dirty')) {
return true;
}
this.o2m._dirty_flag = true;
@@ -3478,7 +3505,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({
return self.o2m.dataset.read_ids.apply(self.o2m.dataset, arguments);
},
form_view_options: {'not_interactible_on_create':true},
- readonly: self.o2m.get("effective_readonly")
+ readonly: !this.is_action_enabled('edit') || self.o2m.get("effective_readonly")
});
},
do_button_action: function (name, id, callback) {
@@ -3528,7 +3555,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({
return;
}
// FIXME: why isn't there an API for this?
- if (this.editor.form.$element.hasClass('oe_form_dirty')) {
+ if (this.editor.form.$el.hasClass('oe_form_dirty')) {
this.save_edition();
return;
}
@@ -3566,7 +3593,11 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({
});
instance.web.form.One2ManyList = instance.web.ListView.List.extend({
pad_table_to: function (count) {
- this._super(count > 0 ? count - 1 : 0);
+ if (!this.view.is_action_enabled('create')) {
+ this._super(count);
+ } else {
+ this._super(count > 0 ? count - 1 : 0);
+ }
// magical invocation of wtf does that do
if (this.view.o2m.get('effective_readonly')) {
@@ -3579,6 +3610,11 @@ instance.web.form.One2ManyList = instance.web.ListView.List.extend({
}).length;
if (this.options.selectable) { columns++; }
if (this.options.deletable) { columns++; }
+
+ if (!this.view.is_action_enabled('create')) {
+ return;
+ }
+
var $cell = $('<td>', {
colspan: columns,
'class': 'oe_form_field_one2many_list_row_add'
@@ -3656,7 +3692,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
if (this.get("effective_readonly"))
return;
var self = this;
- self.$text = $("textarea", this.$element);
+ self.$text = $("textarea", this.$el);
self.$text.textext({
plugins : 'tags arrow autocomplete',
autocomplete: {
@@ -3714,7 +3750,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
self._drop_shown = true;
});
self.tags = self.$text.textext()[0].tags();
- $("textarea", this.$element).focusout(function() {
+ $("textarea", this.$el).focusout(function() {
self.$text.trigger("setInputData", "");
}).keydown(function(e) {
if (e.which === $.ui.keyCode.TAB && self._drop_shown) {
@@ -3748,10 +3784,10 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
data = _.map(values, function(el) { return indexed[el]; });
if (! self.get("effective_readonly")) {
self.tags.containerElement().children().remove();
- $("textarea", self.$element).css("padding-left", "3px");
+ $("textarea", self.$el).css("padding-left", "3px");
self.tags.addTags(_.map(data, function(el) {return {name: el[1], id:el[0]};}));
} else {
- self.$element.html(QWeb.render("FieldMany2ManyTag", {elements: data}));
+ self.$el.html(QWeb.render("FieldMany2ManyTag", {elements: data}));
}
};
if (! values || values.length > 0) {
@@ -3779,7 +3815,7 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({
},
start: function() {
this._super.apply(this, arguments);
- this.$element.addClass('oe_form_field oe_form_field_many2many');
+ this.$el.addClass('oe_form_field oe_form_field_many2many');
var self = this;
@@ -3842,7 +3878,7 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({
loaded.resolve();
});
$.async_when().then(function () {
- self.list_view.appendTo(self.$element);
+ self.list_view.appendTo(self.$el);
});
return loaded;
},
@@ -3970,7 +4006,7 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend(
});
this.kanban_view.do_switch_view.add_last(_.bind(this.open_popup, this));
$.async_when().then(function () {
- self.kanban_view.appendTo(self.$element);
+ self.kanban_view.appendTo(self.$el);
});
return loaded;
},
@@ -4054,7 +4090,7 @@ instance.web.form.Many2ManyQuickCreate = instance.web.Widget.extend({
},
start: function () {
var self = this;
- self.$text = this.$element.find('input').css("width", "200px");
+ self.$text = this.$el.find('input').css("width", "200px");
self.$text.textext({
plugins : 'arrow autocomplete',
autocomplete: {
@@ -4162,8 +4198,8 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({
},
title: this.options.title || "",
buttons: [{text:"tmp"}],
- }, this.$element).open();
- this.$buttonpane = dialog.$element.dialog("widget").find(".ui-dialog-buttonpane").html("");
+ }, this.$el).open();
+ this.$buttonpane = dialog.$el.dialog("widget").find(".ui-dialog-buttonpane").html("");
this.start();
},
on_write_completed: function() {},
@@ -4186,7 +4222,7 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({
if (this.options.alternative_form_view) {
this.view_form.set_embedded_view(this.options.alternative_form_view);
}
- this.view_form.appendTo(this.$element.find(".oe_popup_form"));
+ this.view_form.appendTo(this.$el.find(".oe_popup_form"));
this.view_form.on_loaded.add_last(function() {
var multi_select = self.row_id === null && ! self.options.disable_multiple_selection;
self.$buttonpane.html(QWeb.render("AbstractFormPopup.buttons", {
@@ -4226,7 +4262,7 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({
this.destroy();
},
destroy: function () {
- this.$element.dialog('close');
+ this.$el.dialog('close');
this._super();
},
});
@@ -4318,7 +4354,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
e.cancel = true;
});
self.view_list.popup = self;
- self.view_list.appendTo($(".oe_popup_list", self.$element)).pipe(function() {
+ self.view_list.appendTo($(".oe_popup_list", self.$el)).pipe(function() {
self.view_list.do_show();
}).pipe(function() {
self.searchview.do_search();
@@ -4336,7 +4372,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
});
});
});
- this.searchview.appendTo($(".oe_popup_list", self.$element));
+ this.searchview.appendTo($(".oe_popup_list", self.$el));
},
do_search: function(domains, contexts, groupbys) {
var self = this;
@@ -4362,7 +4398,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
this.searchview.hide();
}
if (this.view_list) {
- this.view_list.$element.hide();
+ this.view_list.$el.hide();
}
this.setup_form_view();
},
@@ -4395,7 +4431,7 @@ instance.web.form.FieldReference = instance.web.form.AbstractField.extend(instan
var sel = this.selection.get_value();
this.m2o.field.relation = sel;
this.m2o.set_value(false);
- this.m2o.$element.toggle(sel !== false);
+ this.m2o.$el.toggle(sel !== false);
}
},
destroy_content: function() {
@@ -4499,9 +4535,9 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance.
this._super.apply(this, arguments);
},
initialize_content: function() {
- this.$element.find('input.oe_form_binary_file').change(this.on_file_change);
- this.$element.find('button.oe_form_binary_file_save').click(this.on_save_as);
- this.$element.find('.oe_form_binary_file_clear').click(this.on_clear);
+ this.$el.find('input.oe_form_binary_file').change(this.on_file_change);
+ this.$el.find('button.oe_form_binary_file_save').click(this.on_save_as);
+ this.$el.find('.oe_form_binary_file_clear').click(this.on_clear);
},
human_filesize : function(size) {
var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
@@ -4518,10 +4554,10 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance.
// http://deepliquid.com/projects/Jcrop/demos.php?demo=handler
if ($(e.target).val() !== '') {
- this.$element.find('form.oe_form_binary_form input[name=session_id]').val(this.session.session_id);
- this.$element.find('form.oe_form_binary_form').submit();
- this.$element.find('.oe_form_binary_progress').show();
- this.$element.find('.oe_form_binary').hide();
+ this.$el.find('form.oe_form_binary_form input[name=session_id]').val(this.session.session_id);
+ this.$el.find('form.oe_form_binary_form').submit();
+ this.$el.find('.oe_form_binary_progress').show();
+ this.$el.find('.oe_form_binary').hide();
}
},
on_file_uploaded: function(size, name, content_type, file_base64) {
@@ -4533,8 +4569,8 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance.
this.filename = name;
this.on_file_uploaded_and_valid.apply(this, arguments);
}
- this.$element.find('.oe_form_binary_progress').hide();
- this.$element.find('.oe_form_binary').show();
+ this.$el.find('.oe_form_binary_progress').hide();
+ this.$el.find('.oe_form_binary').show();
},
on_file_uploaded_and_valid: function(size, name, content_type, file_base64) {
},
@@ -4588,7 +4624,7 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({
this._super();
if (this.get("effective_readonly")) {
var self = this;
- this.$element.find('a').click(function() {
+ this.$el.find('a').click(function() {
if (self.get('value')) {
self.on_save_as();
}
@@ -4608,12 +4644,12 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({
} else {
show_value = (this.get('value') != null && this.get('value') !== false) ? this.get('value') : '';
}
- this.$element.find('input').eq(0).val(show_value);
+ this.$el.find('input').eq(0).val(show_value);
} else {
- this.$element.find('a').show(!!this.get('value'));
+ this.$el.find('a').show(!!this.get('value'));
if (this.get('value')) {
var show_value = _t("Download") + " " + (this.view.datarecord[this.node.attrs.filename] || '');
- this.$element.find('a').text(show_value);
+ this.$el.find('a').text(show_value);
}
}
},
@@ -4621,7 +4657,7 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({
this.binary_value = true;
this.set({'value': file_base64});
var show_value = name + " (" + this.human_filesize(size) + ")";
- this.$element.find('input').eq(0).val(show_value);
+ this.$el.find('input').eq(0).val(show_value);
this.set_filename(name);
},
set_filename: function(value_) {
@@ -4632,7 +4668,7 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({
},
on_clear: function() {
this._super.apply(this, arguments);
- this.$element.find('input').eq(0).val('');
+ this.$el.find('input').eq(0).val('');
this.set_filename('');
}
});
@@ -4644,19 +4680,31 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({
this.render_value();
},
render_value: function() {
+ var self = this;
var url;
if (this.get('value') && ! /^\d+(\.\d*)? \w+$/.test(this.get('value'))) {
url = 'data:image/png;base64,' + this.get('value');
} else if (this.get('value')) {
var id = escape(JSON.stringify(this.view.datarecord.id || null));
+ var field = this.name;
+ if (this.options.preview_image)
+ field = this.options.preview_image;
url = '/web/binary/image?session_id=' + this.session.session_id + '&model=' +
- this.view.dataset.model +'&id=' + id + '&field=' + this.name + '&t=' + (new Date().getTime());
+ this.view.dataset.model +'&id=' + id + '&field=' + field + '&t=' + (new Date().getTime());
} else {
url = "/web/static/src/img/placeholder.png";
}
- var img = QWeb.render("FieldBinaryImage-img", { widget: this, url: url });
- this.$element.find('> img').remove();
- this.$element.prepend(img);
+ var $img = $(QWeb.render("FieldBinaryImage-img", { widget: this, url: url }));
+ this.$el.find('> img').remove();
+ this.$el.prepend($img);
+ $img.load(function() {
+ if (! self.options.size)
+ return;
+ $img.css("max-width", "" + self.options.size[0] + "px");
+ $img.css("max-height", "" + self.options.size[1] + "px");
+ $img.css("margin-left", "" + (self.options.size[0] - $img.width()) / 2 + "px");
+ $img.css("margin-top", "" + (self.options.size[1] - $img.height()) / 2 + "px");
+ });
},
on_file_change: function() {
this.render_value();
@@ -4675,17 +4723,22 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({
instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
template: "FieldStatus",
- clickable: false,
+ init: function(field_manager, node) {
+ this._super(field_manager, node);
+ this.options.clickable = this.options.clickable || (this.node.attrs || {}).clickable || false;
+ this.options.visible = this.options.visible || (this.node.attrs || {}).statusbar_visible || false;
+ this.selected_value = null;
+ },
start: function() {
this._super();
- this.selected_value = null;
- this.clickable = !!this.node.attrs.clickable;
- if (this.$element.parent().is('header')) {
- this.$element.after('<div class="oe_clear"/>');
+ // backward compatibility
+ this.loaded = new $.Deferred();
+ if (this.options.clickable) {
+ this.$el.on('click','li',this.on_click_stage);
}
- // preview in start only for selection fields, because of the dynamic behavior of many2one fields.
- if (this.field.type in ['selection']) {
- this.render_list();
+ // TODO move the following into css :after
+ if (this.$el.parent().is('header')) {
+ this.$el.after('<div class="oe_clear"/>');
}
},
set_value: function(value_) {
@@ -4701,115 +4754,70 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
}
// trick to be sure all values are loaded in the form, therefore
// enabling the evaluation of dynamic domains
+ self.selection = [];
$.async_when().then(function() {
- return self.render_list();
+ self.get_selection();
});
+ return this.loaded;
},
-
- /** Get the status list and render them
- * to_show: [[identifier, value_to_display]] where
- * - identifier = key for a selection, id for a many2one
- * - display_val = label that will be displayed
- * - ex: [[0, "New"]] (many2one) or [["new", "In Progress"]] (selection)
- */
- render_list: function() {
- var self = this;
- // get selection values, filter them and render them
- var selection_done = this.get_selection().pipe(self.proxy('filter_selection')).pipe(self.proxy('render_elements'));
- },
-
- /** Get the selection list to be displayed in the statusbar widget.
+ /** Get the selection and render it
+ * selection: [[identifier, value_to_display], ...]
* For selection fields: this is directly given by this.field.selection
- * For many2one fields :
- * - perform a search on the relation of the many2one field (given by
- * field.relation )
- * - get the field domain for the search
- * - self.build_domain() gives the domain given by the view or by
- * the field
- * - if the optional statusbar_fold attribute is set to true, make
- * an AND with build_domain to hide all 'fold=true' columns
- * - make an OR with current value, to be sure it is displayed,
- * with the correct order, even if it is folded
+ * For many2one fields: perform a search on the relation of the many2one field
*/
get_selection: function() {
var self = this;
if (this.field.type == "many2one") {
- this.selection = [];
- // get fold information from widget
- var fold = ((this.node.attrs || {}).statusbar_fold || true);
- // build final domain: if fold option required, add the
- if (fold == true) {
- var domain = new instance.web.CompoundDomain(['|'], ['&'], self.build_domain(), [['fold', '=', false]], [['id', '=', self.selected_value]]);
- } else {
- var domain = new instance.web.CompoundDomain(['|'], self.build_domain(), [['id', '=', self.selected_value]]);
- }
- // get a DataSetSearch on the current field relation (ex: crm.lead.stage_id -> crm.case.stage)
- var model_ext = new instance.web.DataSetSearch(this, this.field.relation, self.build_context(), domain);
- // fetch selection
- var read_defer = model_ext.read_slice(['name'], {}).pipe( function (records) {
- _(records).each(function (record) {
- self.selection.push([record.id, record.name]);
- });
+ var domain = new instance.web.CompoundDomain(['|'], self.build_domain(), [['id', '=', self.selected_value]]);
+ var ds = new instance.web.DataSetSearch(this, this.field.relation, self.build_context(), domain);
+ ds.read_slice(['name'], {}).done( function (records) {
+ for(var i = 0; i < records.length; i++) {
+ self.selection.push([records[i].id, records[i].name]);
+ }
+ self.render_elements();
+ self.loaded.resolve();
});
} else {
- this.selection = this.field.selection;
- var read_defer = new $.Deferred().resolve();
- }
- return read_defer;
- },
-
- /** Filters this.selection, according to values coming from the statusbar_visible
- * attribute of the field. For example: statusbar_visible="draft,open"
- * Currently, the key of (key, label) pairs has to be used in the
- * selection of visible items. This feature is not meant to be used
- * with many2one fields.
- */
- filter_selection: function() {
- var self = this;
- var shown = _.map(((this.node.attrs || {}).statusbar_visible || "").split(","),
- function(x) { return _.str.trim(x); });
- shown = _.select(shown, function(x) { return x.length > 0; });
-
- if (shown.length == 0) {
- this.to_show = this.selection;
- } else {
- this.to_show = _.select(this.selection, function(x) {
- return _.indexOf(shown, x[0]) !== -1 || x[0] === self.selected_value;
- });
+ this.loaded.resolve();
+ // For field type selection filter values according to
+ // statusbar_visible attribute of the field. For example:
+ // statusbar_visible="draft,open".
+ var selection = this.field.selection;
+ for(var i=0; i< selection.length; i++) {
+ var key = selection[i][0];
+ if(key == this.selected_value || !this.options.visible || this.options.visible.indexOf(key) != -1) {
+ this.selection.push(selection[i]);
+ }
+ }
+ this.render_elements();
}
},
-
/** Renders the widget. This function also checks for statusbar_colors='{"pending": "blue"}'
* attribute in the widget. This allows to set a given color to a given
* state (given by the key of (key, label)).
*/
render_elements: function () {
var self = this;
- var content = instance.web.qweb.render("FieldStatus.content", {widget: this, _:_});
- this.$element.html(content);
- if (this.clickable) {
- this.$element.addClass("oe_form_steps_clickable");
- $('.oe_form_steps_arrow').remove();
- var elemts = this.$element.find('.oe_form_steps_button');
- _.each(elemts, function(element){
- $item = $(element);
- if ($item.attr("data-id") != self.selected_value) {
- $item.click(function(event){
- var data_id = parseInt($(this).attr("data-id"))
- self.view.dataset.call('stage_set', [[self.view.datarecord.id],data_id]).then(function() {
- return self.view.reload();
- });
- });
- }
- });
- } else {
- this.$element.addClass("oe_form_steps");
- }
+ var content = instance.web.qweb.render("FieldStatus.content", {widget: this});
+ this.$el.html(content);
var colors = JSON.parse((this.node.attrs || {}).statusbar_colors || "{}");
var color = colors[this.selected_value];
- if (color) {
- var elem = this.$element.find("li.oe_form_steps_active span");
- elem.css("color", color);
+ if (color) {
+ this.$("oe_active").css("color", color);
+ }
+ },
+ on_click_stage: function (ev) {
+ var self = this;
+ var $li = $(ev.currentTarget);
+ var val = parseInt($li.data("id"));
+ if (val != self.selected_value) {
+ this.view.recursive_save().then(function() {
+ var change = {};
+ change[self.name] = val;
+ self.view.dataset.write(self.view.datarecord.id, change).then(function() {
+ self.view.reload();
+ });
+ });
}
},
});
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index 95dfa78fd63..015cd1636f1 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -21,8 +21,6 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
// whether the view rows can be reordered (via vertical drag & drop)
'reorderable': true,
'action_buttons': true,
- // if true, the 'Import', 'Export', etc... buttons will be shown
- 'import_enabled': true,
},
/**
* Core class for list-type displays.
@@ -145,7 +143,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
* @returns {$.Deferred} loading promise
*/
start: function() {
- this.$element.addClass('oe_list');
+ this.$el.addClass('oe_list');
return this.reload_view(null, null, true);
},
/**
@@ -248,20 +246,26 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
this.setup_columns(this.fields_view.fields, grouped);
- this.$element.html(QWeb.render(this._template, this));
- this.$element.addClass(this.fields_view.arch.attrs['class']);
+ this.$el.html(QWeb.render(this._template, this));
+ this.$el.addClass(this.fields_view.arch.attrs['class']);
+
+ // add css classes that reflect the (absence of) access rights
+ this.$el.toggleClass('oe_list_cannot_create', !this.is_action_enabled('create'))
+ .toggleClass('oe_list_cannot_edit', !this.is_action_enabled('edit'))
+ .toggleClass('oe_list_cannot_delete', !this.is_action_enabled('delete'));
+
// Head hook
// Selecting records
- this.$element.find('.oe_list_record_selector').click(function(){
- self.$element.find('.oe_list_record_selector input').prop('checked',
- self.$element.find('.oe_list_record_selector').prop('checked') || false);
+ this.$el.find('.oe_list_record_selector').click(function(){
+ self.$el.find('.oe_list_record_selector input').prop('checked',
+ self.$el.find('.oe_list_record_selector').prop('checked') || false);
var selection = self.groups.get_selection();
$(self.groups).trigger(
'selected', [selection.ids, selection.records]);
});
// Sorting columns
- this.$element.find('thead').delegate('th.oe_sortable[data-id]', 'click', function (e) {
+ this.$el.find('thead').delegate('th.oe_sortable[data-id]', 'click', function (e) {
e.stopPropagation();
var $this = $(this);
self.dataset.sort($this.data('id'));
@@ -275,21 +279,17 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
self.reload_content();
});
- // Add button and Import link
+ // Add button
if (!this.$buttons) {
this.$buttons = $(QWeb.render("ListView.buttons", {'widget':self}));
if (this.options.$buttons) {
this.$buttons.appendTo(this.options.$buttons);
} else {
- this.$element.find('.oe_list_buttons').replaceWith(this.$buttons);
+ this.$el.find('.oe_list_buttons').replaceWith(this.$buttons);
}
this.$buttons.find('.oe_list_add')
.click(this.proxy('do_add_record'))
.prop('disabled', grouped);
- this.$buttons.on('click', '.oe_list_button_import', function() {
- self.on_sidebar_import();
- return false;
- });
}
// Pager
@@ -298,7 +298,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
if (this.options.$buttons) {
this.$pager.appendTo(this.options.$pager);
} else {
- this.$element.find('.oe_list_pager').replaceWith(this.$pager);
+ this.$el.find('.oe_list_pager').replaceWith(this.$pager);
}
this.$pager
@@ -351,13 +351,12 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
if (!this.sidebar && this.options.$sidebar) {
this.sidebar = new instance.web.Sidebar(this);
this.sidebar.appendTo(this.options.$sidebar);
- this.sidebar.add_items('other', [
- { label: _t("Import"), callback: this.on_sidebar_import },
+ this.sidebar.add_items('other', _.compact([
{ label: _t("Export"), callback: this.on_sidebar_export },
- { label: _t('Delete'), callback: this.do_delete_selected }
- ]);
+ self.is_action_enabled('delete') && { label: _t('Delete'), callback: this.do_delete_selected }
+ ]));
this.sidebar.add_toolbar(this.fields_view.toolbar);
- this.sidebar.$element.hide();
+ this.sidebar.$el.hide();
}
},
/**
@@ -450,7 +449,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
},
do_hide: function () {
if (this.sidebar) {
- this.sidebar.$element.hide();
+ this.sidebar.$el.hide();
}
if (this.$buttons) {
this.$buttons.hide();
@@ -474,7 +473,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
if (this.embedded_view) {
return $.Deferred().then(callback).resolve(this.embedded_view);
} else {
- return this.rpc('/web/listview/load', {
+ return this.rpc('/web/view/load', {
model: this.model,
view_id: this.view_id,
view_type: "tree",
@@ -490,10 +489,10 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
*/
reload_content: function () {
var self = this;
- self.$element.find('.oe_list_record_selector').prop('checked', false);
+ self.$el.find('.oe_list_record_selector').prop('checked', false);
this.records.reset();
var reloaded = $.Deferred();
- this.$element.find('.oe_list_content').append(
+ this.$el.find('.oe_list_content').append(
this.groups.render(function () {
if (self.dataset.index == null) {
var has_one = false;
@@ -595,7 +594,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
if (!ids.length) {
this.dataset.index = 0;
if (this.sidebar) {
- this.sidebar.$element.hide();
+ this.sidebar.$el.hide();
}
this.compute_aggregates();
return;
@@ -603,7 +602,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
this.dataset.index = _(this.dataset.ids).indexOf(ids[0]);
if (this.sidebar) {
- this.sidebar.$element.show();
+ this.sidebar.$el.show();
}
this.compute_aggregates(_(records).map(function (record) {
@@ -763,7 +762,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
},
display_aggregates: function (aggregation) {
var self = this;
- var $footer_cells = this.$element.find('.oe_list_footer');
+ var $footer_cells = this.$el.find('.oe_list_footer');
_(this.aggregate_columns).each(function (column) {
if (!column['function']) {
return;
@@ -789,7 +788,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
pad_columns: function (count, options) {
options = options || {};
// padding for action/pager header
- var $first_header = this.$element.find('thead tr:first th');
+ var $first_header = this.$el.find('thead tr:first th');
var colspan = $first_header.attr('colspan');
if (colspan) {
if (!this.previous_colspan) {
@@ -798,7 +797,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
$first_header.attr('colspan', parseInt(colspan, 10) + count);
}
// Padding for column titles, footer and data rows
- var $rows = this.$element
+ var $rows = this.$el
.find('.oe_list_header_columns, tr:not(thead tr)')
.not(options['except']);
var newcols = new Array(count+1).join('<td class="oe_list_padding"></td>');
@@ -812,23 +811,23 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
* Removes all padding columns of the table
*/
unpad_columns: function () {
- this.$element.find('.oe_list_padding').remove();
+ this.$el.find('.oe_list_padding').remove();
if (this.previous_colspan) {
- this.$element
+ this.$el
.find('thead tr:first th')
.attr('colspan', this.previous_colspan);
this.previous_colspan = null;
}
},
no_result: function () {
- this.$element.find('.oe_view_nocontent').remove();
+ this.$el.find('.oe_view_nocontent').remove();
if (this.groups.group_by
|| !this.options.action
|| !this.options.action.help) {
return;
}
- this.$element.find('table:first').hide();
- this.$element.prepend(
+ this.$el.find('table:first').hide();
+ this.$el.prepend(
$('<div class="oe_view_nocontent">').html(this.options.action.help)
);
}
@@ -1259,7 +1258,7 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
self.bind_child_events(child);
child.datagroup = group;
- var $row = child.$row = $('<tr>');
+ var $row = child.$row = $('<tr class="oe_group_header">');
if (group.openable && group.length) {
$row.click(function (e) {
if (!$row.data('open')) {
@@ -1478,27 +1477,27 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
},
render: function (post_render) {
var self = this;
- var $element = $('<tbody>');
- this.elements = [$element[0]];
+ var $el = $('<tbody>');
+ this.elements = [$el[0]];
this.datagroup.list(
_(this.view.visible_columns).chain()
.filter(function (column) { return column.tag === 'field' })
.pluck('name').value(),
function (groups) {
- $element[0].appendChild(
+ $el[0].appendChild(
self.render_groups(groups));
if (post_render) { post_render(); }
}, function (dataset) {
self.render_dataset(dataset).then(function (list) {
self.children[null] = list;
self.elements =
- [list.$current.replaceAll($element)[0]];
+ [list.$current.replaceAll($el)[0]];
self.setup_resequence_rows(list, dataset);
if (post_render) { post_render(); }
});
});
- return $element;
+ return $el;
},
/**
* Returns the ids of all selected records for this group, and the records
@@ -1995,7 +1994,7 @@ instance.web.list.Column = instance.web.Class.extend({
if (!(aggregation_func in this)) {
return {};
}
- var C = function (label, fn) {
+ var C = function (fn, label) {
this['function'] = fn;
this.label = label;
};
@@ -2115,6 +2114,11 @@ instance.web.list.ProgressBar = instance.web.list.Column.extend({
}
});
instance.web.list.Handle = instance.web.list.Column.extend({
+ init: function () {
+ this._super.apply(this, arguments);
+ // Handle overrides the field to not be form-editable.
+ this.modifiers.readonly = true;
+ },
/**
* Return styling hooks for a drag handle
*
diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js
index 9a101a5ac1a..892221a347b 100644
--- a/addons/web/static/src/js/view_list_editable.js
+++ b/addons/web/static/src/js/view_list_editable.js
@@ -45,16 +45,22 @@ openerp.web.list_editable = function (instance) {
}
});
this.on('edit:after', this, function () {
- self.$element.add(self.$buttons).addClass('oe_editing');
+ self.$el.add(self.$buttons).addClass('oe_editing');
});
this.on('save:after cancel:after', this, function () {
- self.$element.add(self.$buttons).removeClass('oe_editing');
+ self.$el.add(self.$buttons).removeClass('oe_editing');
});
},
destroy: function () {
instance.web.bus.off('resize', this, this.resize_fields);
this._super();
},
+ do_hide: function () {
+ if (this.editor.is_editing()) {
+ this.cancel_edition(true);
+ }
+ this._super();
+ },
/**
* Handles the activation of a record in editable mode (making a record
* editable), called *after* the record has become editable.
@@ -87,8 +93,8 @@ openerp.web.list_editable = function (instance) {
*/
do_add_record: function () {
if (this.editable()) {
- this.$element.find('table:first').show();
- this.$element.find('.oe_view_nocontent').remove();
+ this.$el.find('table:first').show();
+ this.$el.find('.oe_view_nocontent').remove();
this.start_edition();
} else {
this._super();
@@ -99,7 +105,7 @@ openerp.web.list_editable = function (instance) {
// tree/@editable takes priority on everything else if present.
var result = this._super(data, grouped);
if (this.editable()) {
- this.$element.addClass('oe_list_editable');
+ this.$el.addClass('oe_list_editable');
// FIXME: any hook available to ensure this is only done once?
this.$buttons
.off('click', '.oe_list_save')
@@ -109,7 +115,7 @@ openerp.web.list_editable = function (instance) {
e.preventDefault();
self.cancel_edition();
});
- this.$element
+ this.$el
.off('click', 'tbody td:not(.oe_list_field_cell)')
.on('click', 'tbody td:not(.oe_list_field_cell)', function () {
if (!self.editor.is_editing()) {
@@ -120,12 +126,12 @@ openerp.web.list_editable = function (instance) {
// Editor is not restartable due to formview not being
// restartable
this.editor = this.make_editor();
- var editor_ready = this.editor.prependTo(this.$element)
+ var editor_ready = this.editor.prependTo(this.$el)
.then(this.proxy('setup_events'));
return $.when(result, editor_ready);
} else {
- this.$element.removeClass('oe_list_editable');
+ this.$el.removeClass('oe_list_editable');
}
return result;
@@ -203,7 +209,7 @@ openerp.web.list_editable = function (instance) {
}
// FIXME: need better way to get the field back from bubbling (delegated) DOM events somehow
- field.$element.attr('data-fieldname', field_name);
+ field.$el.attr('data-fieldname', field_name);
self.fields_for_resize.push({field: field, cell: cell});
}, options).pipe(function () {
$recordRow.addClass('oe_edition');
@@ -249,8 +255,8 @@ openerp.web.list_editable = function (instance) {
var position = $cell.position();
// jquery does not understand !important
- field.$element.attr('style', 'width: '+$cell.outerWidth()+'px !important')
- field.$element.css({
+ field.$el.attr('style', 'width: '+$cell.outerWidth()+'px !important');
+ field.$el.css({
top: position.top,
left: position.left,
minHeight: $cell.outerHeight()
@@ -354,14 +360,17 @@ openerp.web.list_editable = function (instance) {
'class': 'oe_form_container',
version: '7.0'
});
- _(view.arch.children).each(function (widget) {
- var modifiers = JSON.parse(widget.attrs.modifiers || '{}');
- widget.attrs.nolabel = true;
- if (modifiers['tree_invisible'] || widget.tag === 'button') {
- modifiers.invisible = true;
- }
- widget.attrs.modifiers = JSON.stringify(modifiers);
- });
+ _(view.arch.children).chain()
+ .zip(this.columns)
+ .each(function (ar) {
+ var widget = ar[0], column = ar[1];
+ var modifiers = _.extend({}, column.modifiers);
+ widget.attrs.nolabel = true;
+ if (modifiers['tree_invisible'] || widget.tag === 'button') {
+ modifiers.invisible = true;
+ }
+ widget.attrs.modifiers = JSON.stringify(modifiers);
+ });
return view;
},
handle_onwrite: function (source_record) {
@@ -391,7 +400,7 @@ openerp.web.list_editable = function (instance) {
},
setup_events: function () {
var self = this;
- this.editor.$element.on('keyup keydown', function (e) {
+ this.editor.$el.on('keyup keydown', function (e) {
if (!self.editor.is_editing()) { return; }
var key = _($.ui.keyCode).chain()
.map(function (v, k) { return {name: k, code: v}; })
@@ -540,7 +549,7 @@ openerp.web.list_editable = function (instance) {
if (--field_index < 0) { return $.when(); }
field = fields[fields_order[field_index]];
- } while (!field.$element.is(':visible'));
+ } while (!field.$el.is(':visible'));
// and focus it
field.focus();
@@ -563,7 +572,7 @@ openerp.web.list_editable = function (instance) {
if (++field_index >= fields_order.length) { return $.when(); }
field = fields[fields_order[field_index]];
- } while (!field.$element.is(':visible'));
+ } while (!field.$el.is(':visible'));
field.focus();
return $.when();
@@ -572,11 +581,11 @@ openerp.web.list_editable = function (instance) {
var form = this.editor.form;
var last_field = _(form.fields_order).chain()
.map(function (name) { return form.fields[name]; })
- .filter(function (field) { return field.$element.is(':visible'); })
+ .filter(function (field) { return field.$el.is(':visible'); })
.last()
.value();
// tabbed from last field in form
- if (last_field && last_field.$element.has(e.target).length) {
+ if (last_field && last_field.$el.has(e.target).length) {
e.preventDefault();
return this._next();
}
@@ -620,7 +629,7 @@ openerp.web.list_editable = function (instance) {
var _super = this._super();
this.form.embedded_view = this._validate_view(
this.delegate.edition_view(this));
- var form_ready = this.form.appendTo(this.$element).then(
+ var form_ready = this.form.appendTo(this.$el).then(
self.form.proxy('do_hide'));
return $.when(_super, form_ready);
},
@@ -678,7 +687,7 @@ openerp.web.list_editable = function (instance) {
// Is actually in the form
&& (field = form.fields[focus_field])
// And is visible
- && field.$element.is(':visible')) {
+ && field.$el.is(':visible')) {
// focus it
field.focus();
return;
@@ -687,7 +696,7 @@ openerp.web.list_editable = function (instance) {
_(form.fields_order).detect(function (name) {
// look for first visible field in fields_order, focus it
var field = form.fields[name];
- if (!field.$element.is(':visible')) {
+ if (!field.$el.is(':visible')) {
return false;
}
// Stop as soon as a field got focused
@@ -716,7 +725,7 @@ openerp.web.list_editable = function (instance) {
save: function () {
var self = this;
return this.form
- .do_save(null, this.delegate.prepends_on_create())
+ .do_save(this.delegate.prepends_on_create())
.pipe(function (result) {
var created = result.created && !self.record.id;
if (created) {
@@ -750,7 +759,7 @@ openerp.web.list_editable = function (instance) {
instance.web.ListView.List.include(/** @lends instance.web.ListView.List# */{
row_clicked: function (event) {
- if (!this.view.editable()) {
+ if (!this.view.editable() || ! this.view.is_action_enabled('edit')) {
return this._super.apply(this, arguments);
}
var record_id = $(event.currentTarget).data('id');
diff --git a/addons/web/static/src/js/view_tree.js b/addons/web/static/src/js/view_tree.js
index 2181b2aa157..e0493a446e2 100644
--- a/addons/web/static/src/js/view_tree.js
+++ b/addons/web/static/src/js/view_tree.js
@@ -84,13 +84,13 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie
});
this.fields = fields_view.fields;
this.hook_row_click();
- this.$element.html(QWeb.render('TreeView', {
+ this.$el.html(QWeb.render('TreeView', {
'title': this.fields_view.arch.attrs.string,
'fields_view': this.fields_view.arch.children,
'fields': this.fields,
'toolbar': has_toolbar
}));
- this.$element.addClass(this.fields_view.arch.attrs['class']);
+ this.$el.addClass(this.fields_view.arch.attrs['class']);
this.dataset.read_slice(this.fields_list()).then(function(records) {
self.store_record(records);
@@ -102,7 +102,7 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie
return;
}
- var $select = self.$element.find('select')
+ var $select = self.$el.find('select')
.change(function () {
var $option = $(this).find(':selected');
self.getdata($option.val());
@@ -120,10 +120,10 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie
$select.change();
}
});
- this.$element.find("#tree_view_expand").click(function(){
+ this.$el.find("#tree_view_expand").click(function(){
self.expand_all();
});
- this.$element.find("#tree_view_collapse").click(function(){
+ this.$el.find("#tree_view_collapse").click(function(){
self.collpase_all();
});
// TODO store open nodes in url ?...
@@ -143,14 +143,14 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie
},
expand_all: function(){
var self = this;
- var tr = this.$element.find(".oe-treeview-table tbody tr[id^='treerow_']");
+ var tr = this.$el.find(".oe-treeview-table tbody tr[id^='treerow_']");
_.each(tr,function(rec){
self.showcontent($(rec).attr('data-id'),true);
});
},
collpase_all: function(){
var self = this;
- var root_tr = this.$element.find(".oe-treeview-table tbody tr[data-level='"+1+"']");
+ var root_tr = this.$el.find(".oe-treeview-table tbody tr[data-level='"+1+"']");
_.each(root_tr,function(rec){
if($(rec).hasClass('oe_open')){
self.showcontent($(rec).attr('data-id'),false);
@@ -187,12 +187,12 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie
*/
hook_row_click: function () {
var self = this;
- this.$element.delegate('.treeview-td span, .treeview-tr span', 'click', function (e) {
+ this.$el.delegate('.treeview-td span, .treeview-tr span', 'click', function (e) {
e.stopImmediatePropagation();
self.activate($(this).closest('tr').data('id'));
});
- this.$element.delegate('.treeview-tr', 'click', function () {
+ this.$el.delegate('.treeview-tr', 'click', function () {
var $this = $(this),
record_id = $this.data('id'),
bool = $this.parent().hasClass('oe_open');
@@ -220,7 +220,7 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie
render_data: function(groupby){
var self = this;
_.each(_.keys(groupby),function(key){
- var $curr_node = self.$element.find('#treerow_' + key);
+ var $curr_node = self.$el.find('#treerow_' + key);
var record = groupby[key];
var children_rows = QWeb.render('TreeView.rows', {
'records': record,
@@ -235,7 +235,7 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie
$curr_node.addClass('oe_open');
$curr_node.after(children_rows);
} else {
- self.$element.find('tbody').html(children_rows);
+ self.$el.find('tbody').html(children_rows);
}
});
self.collpase_all();
@@ -272,11 +272,11 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie
// show & hide the contents
showcontent: function (record_id, show) {
- this.$element.find('#treerow_' + record_id)
+ this.$el.find('#treerow_' + record_id)
.toggleClass('oe_open', show);
_(this.records[record_id][this.children_field]).each(function (child_id) {
- var $child_row = this.$element.find('#treerow_' + child_id);
+ var $child_row = this.$el.find('#treerow_' + child_id);
if ($child_row.hasClass('oe_open')) {
this.showcontent(child_id, false);
}
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index 0831d0c5f8e..2dffe9520a1 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -20,7 +20,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
},
start: function() {
this._super.apply(this, arguments);
- this.$element.on('click', '.oe_breadcrumb_item', this.on_breadcrumb_clicked);
+ this.$el.on('click', '.oe_breadcrumb_item', this.on_breadcrumb_clicked);
},
dialog_stop: function () {
if (this.dialog) {
@@ -53,10 +53,10 @@ instance.web.ActionManager = instance.web.Widget.extend({
}
var item = _.extend({
show: function(index) {
- this.widget.$element.show();
+ this.widget.$el.show();
},
hide: function() {
- this.widget.$element.hide();
+ this.widget.$el.hide();
},
destroy: function() {
this.widget.destroy();
@@ -101,7 +101,9 @@ instance.web.ActionManager = instance.web.Widget.extend({
select_breadcrumb: function(index, subindex) {
for (var i = this.breadcrumbs.length - 1; i >= 0; i--) {
if (i > index) {
- this.remove_breadcrumb(i);
+ if (this.remove_breadcrumb(i) === false) {
+ return false;
+ }
}
}
var item = this.breadcrumbs[index];
@@ -110,8 +112,10 @@ instance.web.ActionManager = instance.web.Widget.extend({
return true;
},
clear_breadcrumbs: function() {
- while (this.breadcrumbs.length) {
- this.remove_breadcrumb(0);
+ for (var i = this.breadcrumbs.length - 1; i >= 0; i--) {
+ if (this.remove_breadcrumb(0) === false) {
+ break;
+ }
}
},
remove_breadcrumb: function(index) {
@@ -121,9 +125,17 @@ instance.web.ActionManager = instance.web.Widget.extend({
return item.widget === it.widget;
});
if (!dups.length) {
- item.destroy();
+ if (this.getParent().has_uncommitted_changes()) {
+ this.inner_widget = item.widget;
+ this.breadcrumbs.splice(index, 0, item);
+ return false;
+ } else {
+ item.destroy();
+ }
}
}
+ var last_widget = this.breadcrumbs.slice(-1)[0];
+ this.inner_widget = last_widget && last_widget.widget;
},
get_title: function() {
var titles = [];
@@ -208,19 +220,19 @@ instance.web.ActionManager = instance.web.Widget.extend({
}
});
},
- do_action: function(action, on_close) {
+ do_action: function(action, on_close, clear_breadcrumbs) {
if (_.isString(action) && instance.web.client_actions.contains(action)) {
var action_client = { type: "ir.actions.client", tag: action };
- return this.do_action(action_client);
+ return this.do_action(action_client, on_close, clear_breadcrumbs);
} else if (_.isNumber(action) || _.isString(action)) {
var self = this;
- return self.rpc("/web/action/load", { action_id: action }, function(result) {
- self.do_action(result.result, on_close);
+ return self.rpc("/web/action/load", { action_id: action }).pipe(function(result) {
+ return self.do_action(result.result, on_close, clear_breadcrumbs);
});
}
if (!action.type) {
console.error("No type for action", action);
- return null;
+ return $.Deferred().reject();
}
var type = action.type.replace(/\./g,'_');
var popup = action.target === 'new';
@@ -235,16 +247,23 @@ instance.web.ActionManager = instance.web.Widget.extend({
}, action.flags || {});
if (!(type in this)) {
console.error("Action manager can't handle action of type " + action.type, action);
- return null;
+ return $.Deferred().reject();
}
- return this[type](action, on_close);
+ return this[type](action, on_close, clear_breadcrumbs);
},
null_action: function() {
this.dialog_stop();
this.clear_breadcrumbs();
},
- ir_actions_common: function(action, on_close) {
+ ir_actions_common: function(action, on_close, clear_breadcrumbs) {
var self = this, klass, widget, post_process;
+ if (this.inner_widget && (action.type === 'ir.actions.client' || action.target !== 'new')) {
+ if (this.getParent().has_uncommitted_changes()) {
+ return $.Deferred().reject();
+ } else if (clear_breadcrumbs) {
+ this.clear_breadcrumbs();
+ }
+ }
if (action.type === 'ir.actions.client') {
var ClientWidget = instance.web.client_actions.get_object(action.tag);
widget = new ClientWidget(this, action.params);
@@ -277,27 +296,27 @@ instance.web.ActionManager = instance.web.Widget.extend({
}
this.dialog.dialog_title = action.name;
this.dialog_widget = widget;
- this.dialog_widget.appendTo(this.dialog.$element);
+ this.dialog_widget.appendTo(this.dialog.$el);
this.dialog.open();
} else {
this.dialog_stop();
this.inner_action = action;
this.inner_widget = widget;
post_process();
- this.inner_widget.appendTo(this.$element);
+ this.inner_widget.appendTo(this.$el);
}
},
- ir_actions_act_window: function (action, on_close) {
+ ir_actions_act_window: function (action, on_close, clear_breadcrumbs) {
var self = this;
if (action.target !== 'new') {
if(action.menu_id) {
this.dialog_stop();
return this.getParent().do_action(action, function () {
instance.webclient.menu.open_menu(action.menu_id);
- });
+ }, clear_breadcrumbs);
}
}
- return this.ir_actions_common(action, on_close);
+ return this.ir_actions_common(action, on_close, clear_breadcrumbs);
},
ir_actions_client: function (action, on_close) {
return this.ir_actions_common(action, on_close);
@@ -314,7 +333,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
action_id: action.id,
context: action.context || {}
}).then(function (action) {
- self.do_action(action, on_closed)
+ self.do_action(action, on_closed, clear_breadcrumbs)
});
},
ir_actions_report_xml: function(action, on_closed) {
@@ -376,7 +395,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
start: function() {
this._super();
var self = this;
- this.$element.find('.oe_view_manager_switch a').click(function() {
+ this.$el.find('.oe_view_manager_switch a').click(function() {
self.on_mode_switch($(this).data('view-type'));
}).tipsy();
var views_ids = {};
@@ -385,9 +404,9 @@ instance.web.ViewManager = instance.web.Widget.extend({
deferred : $.Deferred(),
controller : null,
options : _.extend({
- $buttons : self.$element.find('.oe_view_manager_buttons'),
- $sidebar : self.flags.sidebar ? self.$element.find('.oe_view_manager_sidebar') : undefined,
- $pager : self.$element.find('.oe_view_manager_pager'),
+ $buttons : self.$el.find('.oe_view_manager_buttons'),
+ $sidebar : self.flags.sidebar ? self.$el.find('.oe_view_manager_sidebar') : undefined,
+ $pager : self.$el.find('.oe_view_manager_pager'),
action : self.action,
action_views_ids : views_ids
}, self.flags, self.flags[view.view_type] || {}, view.options || {})
@@ -395,7 +414,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
views_ids[view.view_type] = view.view_id;
});
if (this.flags.views_switcher === false) {
- this.$element.find('.oe_view_manager_switch').hide();
+ this.$el.find('.oe_view_manager_switch').hide();
}
// If no default view defined, switch to the first one in sequence
var default_view = this.flags.default_view || this.views_src[0].view_type;
@@ -412,8 +431,10 @@ instance.web.ViewManager = instance.web.Widget.extend({
var self = this;
var view = this.views[view_type];
var view_promise;
- if(!view)
+ var form = this.views['form'];
+ if (!view || (form && form.controller && !form.controller.can_be_discarded())) {
return $.Deferred().reject();
+ }
if (!no_store) {
this.views_history.push(view_type);
@@ -432,9 +453,9 @@ instance.web.ViewManager = instance.web.Widget.extend({
this.searchview[(view.controller.searchable === false || this.searchview.hidden) ? 'hide' : 'show']();
}
- this.$element
+ this.$el
.find('.oe_view_manager_switch a').parent().removeClass('active');
- this.$element
+ this.$el
.find('.oe_view_manager_switch a').filter('[data-view-type="' + view_type + '"]')
.parent().addClass('active');
@@ -442,7 +463,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
_.each(_.keys(self.views), function(view_name) {
var controller = self.views[view_name].controller;
if (controller) {
- var container = self.$element.find(".oe_view_manager_view_" + view_name + ":first");
+ var container = self.$el.find(".oe_view_manager_view_" + view_name + ":first");
if (view_name === view_type) {
container.show();
controller.do_show(view_options || {});
@@ -451,10 +472,10 @@ instance.web.ViewManager = instance.web.Widget.extend({
controller.do_hide();
}
// put the <footer> in the dialog's buttonpane
- if (self.$element.parent('.ui-dialog-content') && self.$element.find('footer')) {
- self.$element.parent('.ui-dialog-content').parent().find('div.ui-dialog-buttonset').hide()
- self.$element.find('footer').appendTo(
- self.$element.parent('.ui-dialog-content').parent().find('div.ui-dialog-buttonpane')
+ if (self.$el.parent('.ui-dialog-content') && self.$el.find('footer')) {
+ self.$el.parent('.ui-dialog-content').parent().find('div.ui-dialog-buttonset').hide()
+ self.$el.find('footer').appendTo(
+ self.$el.parent('.ui-dialog-content').parent().find('div.ui-dialog-buttonpane')
);
}
}
@@ -491,7 +512,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
controller.do_switch_view.add_last(_.bind(this.switch_view, this));
controller.do_prev_view.add_last(this.on_prev_view);
- var container = this.$element.find(".oe_view_manager_view_" + view_type);
+ var container = this.$el.find(".oe_view_manager_view_" + view_type);
var view_promise = controller.appendTo(container);
this.views[view_type].controller = controller;
this.views[view_type].deferred.resolve(view_type);
@@ -505,7 +526,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
});
},
set_title: function(title) {
- this.$element.find('.oe_view_title_text:first').text(title);
+ this.$el.find('.oe_view_title_text:first').text(title);
},
add_breadcrumb: function() {
var self = this;
@@ -524,7 +545,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
action: this.action,
show: function(index) {
var view_to_select = views[index];
- self.$element.show();
+ self.$el.show();
if (self.active_view !== view_to_select) {
self.on_mode_switch(view_to_select);
}
@@ -600,7 +621,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
this.searchview = new instance.web.SearchView(this, this.dataset, view_id, search_defaults, this.flags.search_view === false);
this.searchview.on_search.add(this.do_searchview_search);
- return this.searchview.appendTo(this.$element.find(".oe_view_manager_view_search"));
+ return this.searchview.appendTo(this.$el.find(".oe_view_manager_view_search"));
},
do_searchview_search: function(domains, contexts, groupbys) {
var self = this,
@@ -717,8 +738,8 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
var manager_ready = $.when(searchview_loaded, main_view_loaded);
- this.$element.find('.oe_debug_view').change(this.on_debug_changed);
- this.$element.addClass("oe_view_manager_" + (this.action.target || 'current'));
+ this.$el.find('.oe_debug_view').change(this.on_debug_changed);
+ this.$el.addClass("oe_view_manager_" + (this.action.target || 'current'));
return manager_ready;
},
on_debug_changed: function (evt) {
@@ -730,7 +751,15 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
switch (val) {
case 'fvg':
var dialog = new instance.web.Dialog(this, { title: _t("Fields View Get"), width: '95%' }).open();
- $('<pre>').text(instance.web.json_node_to_xml(current_view.fields_view.arch, true)).appendTo(dialog.$element);
+ $('<pre>').text(instance.web.json_node_to_xml(current_view.fields_view.arch, true)).appendTo(dialog.$el);
+ break;
+ case 'tests':
+ this.do_action({
+ name: "JS Tests",
+ target: 'new',
+ type : 'ir.actions.act_url',
+ url: '/web/static/test/test.html'
+ })
break;
case 'perm_read':
var ids = current_view.get_selected_ids();
@@ -749,6 +778,17 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
case 'toggle_layout_outline':
current_view.rendering_engine.toggle_layout_debugging();
break;
+ case 'translate':
+ this.do_action({
+ name: "Technical Translation",
+ res_model : 'ir.translation',
+ domain : [['type', '!=', 'object'], '|', ['name', '=', this.dataset.model], ['name', 'ilike', this.dataset.model + ',']],
+ views: [[false, 'list'], [false, 'form']],
+ type : 'ir.actions.act_window',
+ view_type : "list",
+ view_mode : "list"
+ });
+ break;
case 'fields':
this.dataset.call_and_eval(
'fields_get', [false, {}], null, 1).then(function (fields) {
@@ -828,7 +868,7 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
var controller = self.views[self.active_view].controller,
fvg = controller.fields_view,
view_id = (fvg && fvg.view_id) || '--';
- self.$element.find('.oe_debug_view').html(QWeb.render('ViewManagerDebug', {
+ self.$el.find('.oe_debug_view').html(QWeb.render('ViewManagerDebug', {
view: controller,
view_manager: self
}));
@@ -842,7 +882,7 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
return r;
},
set_title: function(title) {
- this.$element.find('.oe_breadcrumb_title:first').html(this.getParent().get_title());
+ this.$el.find('.oe_breadcrumb_title:first').html(this.getParent().get_title());
},
do_push_state: function(state) {
if (this.getParent() && this.getParent().do_push_state) {
@@ -874,7 +914,7 @@ instance.web.Sidebar = instance.web.Widget.extend({
var view = this.getParent();
this.sections = [
{ 'name' : 'print', 'label' : _t('Print'), },
- { 'name' : 'files', 'label' : _t('Attachment'), },
+ { 'name' : 'files', 'label' : _t('Attachment(s)'), },
{ 'name' : 'other', 'label' : _t('More'), }
];
this.items = {
@@ -882,10 +922,6 @@ instance.web.Sidebar = instance.web.Widget.extend({
'files' : [],
'other' : []
};
- if (this.session.uid === 1) {
- var item = { label: _t("Translate"), callback: view.on_sidebar_translate, title: _t("Technical translation") };
- this.items.other.push(item);
- }
this.fileupload_id = _.uniqueId('oe_fileupload');
$(window).on(this.fileupload_id, function() {
var args = [].slice.call(arguments).slice(1);
@@ -901,7 +937,7 @@ instance.web.Sidebar = instance.web.Widget.extend({
var self = this;
this._super(this);
this.redraw();
- this.$element.on('click','.oe_dropdown_menu li a', function(event) {
+ this.$el.on('click','.oe_dropdown_menu li a', function(event) {
var section = $(this).data('section');
var index = $(this).data('index');
var item = self.items[section][index];
@@ -917,7 +953,7 @@ instance.web.Sidebar = instance.web.Widget.extend({
},
redraw: function() {
var self = this;
- self.$element.html(QWeb.render('Sidebar', {widget: self}));
+ self.$el.html(QWeb.render('Sidebar', {widget: self}));
// Hides Sidebar sections when item list is empty
this.$('.oe_form_dropdown_section').each(function() {
@@ -1024,12 +1060,12 @@ instance.web.Sidebar = instance.web.Widget.extend({
self.items['files'] = attachments;
self.redraw();
this.$('.oe_sidebar_add_attachment .oe_form_binary_file').change(this.on_attachment_changed);
- this.$element.find('.oe_sidebar_delete_item').click(this.on_attachment_delete);
+ this.$el.find('.oe_sidebar_delete_item').click(this.on_attachment_delete);
},
on_attachment_changed: function(e) {
var $e = $(e.target);
if ($e.val() !== '') {
- this.$element.find('form.oe_form_binary_form').submit();
+ this.$el.find('form.oe_form_binary_form').submit();
$e.parent().find('input[type=file]').prop('disabled', true);
$e.parent().find('button').prop('disabled', true).find('img, span').toggle();
this.$('.oe_sidebar_add_attachment span').text(_t('Uploading...'));
@@ -1050,119 +1086,6 @@ instance.web.Sidebar = instance.web.Widget.extend({
}
});
-instance.web.TranslateDialog = instance.web.Dialog.extend({
- dialog_title: {toString: function () { return _t("Translations"); }},
- init: function(view) {
- // TODO fme: should add the language to fields_view_get because between the fields view get
- // and the moment the user opens the translation dialog, the user language could have been changed
- this.view_language = view.session.user_context.lang;
- this['on_button_' + _t("Save")] = this.on_btn_save;
- this['on_button_' + _t("Close")] = this.on_btn_close;
- this._super(view, {
- width: '80%',
- height: '80%',
- destroy_on_close: false,
- });
- this.view = view;
- this.view_type = view.fields_view.type || '';
- this.$fields_form = null;
- this.$view_form = null;
- this.$sidebar_form = null;
- this.translatable_fields_keys = _.map(this.view.translatable_fields || [], function(i) { return i.name; });
- this.languages = null;
- this.languages_loaded = $.Deferred();
- (new instance.web.DataSetSearch(this, 'res.lang', this.view.dataset.get_context(),
- [['translatable', '=', '1']])).read_slice(['code', 'name'], { sort: 'id' }).then(this.on_languages_loaded);
- },
- start: function() {
- var self = this;
- this._super();
- $.when(this.languages_loaded).then(function() {
- self.$element.html(instance.web.qweb.render('TranslateDialog', { widget: self }));
- self.$fields_form = self.$element.find('.oe_translation_form');
- self.$fields_form.find('.oe_trad_field').change(function() {
- $(this).toggleClass('touched', ($(this).val() != $(this).attr('data-value')));
- });
- });
- return this;
- },
- on_languages_loaded: function(langs) {
- this.languages = langs;
- this.languages_loaded.resolve();
- },
- do_load_fields_values: function(callback) {
- var self = this,
- deffered = [];
- this.$fields_form.find('.oe_trad_field').val('').removeClass('touched');
- _.each(self.languages, function(lg) {
- var deff = $.Deferred();
- deffered.push(deff);
- var callback = function(values) {
- _.each(self.translatable_fields_keys, function(f) {
- var value = values[0][f] || '';
- self.$fields_form.find('.oe_trad_field[name="' + lg.code + '-' + f + '"]').val(value).attr('data-value', value);
- });
- deff.resolve();
- };
- if (lg.code === self.view_language) {
- var values = {};
- _.each(self.translatable_fields_keys, function(field) {
- values[field] = self.view.fields[field].get_value();
- });
- callback([values]);
- } else {
- self.view.dataset.read_ids([self.view.datarecord.id], self.translatable_fields_keys, {
- context: { 'lang': lg.code }
- }).then(callback);
- }
- });
- $.when.apply(null, deffered).then(callback);
- },
- open: function(field) {
- var self = this;
- this._super();
- $.when(this.languages_loaded).then(function() {
- if (self.view.translatable_fields && self.view.translatable_fields.length) {
- self.do_load_fields_values(function() {
- if (field) {
- var $field_input = self.$element.find('tr[data-field="' + field.name + '"] td:nth-child(2) *:first-child');
- self.$element.scrollTo($field_input);
- $field_input.focus();
- }
- });
- } else {
- sup.call(self);
- }
- });
- },
- on_btn_save: function() {
- var trads = {},
- self = this,
- trads_mutex = new $.Mutex();
- self.$fields_form.find('.oe_trad_field.touched').each(function() {
- var field = $(this).attr('name').split('-');
- if (!trads[field[0]]) {
- trads[field[0]] = {};
- }
- trads[field[0]][field[1]] = $(this).val();
- });
- _.each(trads, function(data, code) {
- if (code === self.view_language) {
- _.each(data, function(value, field) {
- self.view.fields[field].set_value(value);
- });
- }
- trads_mutex.exec(function() {
- return self.view.dataset.write(self.view.datarecord.id, data, { context : { 'lang': code } });
- });
- });
- this.close();
- },
- on_btn_close: function() {
- this.close();
- }
-});
-
instance.web.View = instance.web.Widget.extend({
// name displayed in view switchers
display_name: '',
@@ -1214,12 +1137,6 @@ instance.web.View = instance.web.Widget.extend({
action_views_ids: {}
});
},
- open_translate_dialog: function(field) {
- if (!this.translate_dialog) {
- this.translate_dialog = new instance.web.TranslateDialog(this);
- }
- this.translate_dialog.open(field);
- },
/**
* Fetches and executes the action identified by ``action_data``.
*
@@ -1302,10 +1219,10 @@ instance.web.View = instance.web.Widget.extend({
this.embedded_view = embedded_view;
},
do_show: function () {
- this.$element.show();
+ this.$el.show();
},
do_hide: function () {
- this.$element.hide();
+ this.$el.hide();
},
do_push_state: function(state) {
if (this.getParent() && this.getParent().do_push_state) {
@@ -1332,22 +1249,9 @@ instance.web.View = instance.web.Widget.extend({
},
do_search: function(view) {
},
- on_sidebar_import: function() {
- new instance.web.DataImport(this, this.dataset).open();
- },
on_sidebar_export: function() {
new instance.web.DataExport(this, this.dataset).open();
},
- on_sidebar_translate: function() {
- return this.do_action({
- res_model : 'ir.translation',
- domain : [['type', '!=', 'object'], '|', ['name', '=', this.dataset.model], ['name', 'ilike', this.dataset.model + ',']],
- views: [[false, 'list'], [false, 'form']],
- type : 'ir.actions.act_window',
- view_type : "list",
- view_mode : "list"
- });
- },
sidebar_context: function () {
return $.when();
},
@@ -1357,6 +1261,15 @@ instance.web.View = instance.web.Widget.extend({
*/
reload: function () {
return $.when();
+ },
+ /**
+ * Return whether the user can perform the action ('create', 'edit', 'delete') in this view.
+ * An action is disabled by setting the corresponding attribute in the view's main element,
+ * like: <form string="" create="false" edit="false" delete="false">
+ */
+ is_action_enabled: function(action) {
+ var attrs = this.fields_view.arch.attrs;
+ return (action in attrs) ? JSON.parse(attrs[action]) : true;
}
});
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index ee5183d8e5c..a595bb9e495 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -51,29 +51,6 @@
</table>
</t>
<t t-name="CrashManager.error">
- <t t-if="!session.openerp_entreprise">
- <span>Your version of OpenERP is unsupported. Support &amp; maintenance services are available here: <a href="http://www.openerp.com/support-or-publisher-warranty-contract" target="_blank">OpenERP Entreprise</a>.</span>
- </t>
- <t t-if="session.openerp_entreprise">
- <div class="oe_error_send">
- <div>
- <div class="oe_centeralign"><b>OpenERP Enterprise Contract.</b></div>
- <div><br/>Your report will be sent to the OpenERP Enterprise team.<br/></div><br/>
- <div>
- <label>Summary:</label><br/>
- <input id="issuename" type="text" class="oe_fielddiv"/>
- </div><br/><br/>
- <div>
- <label>Description:</label><br/>
- <textarea id="explanation" rows="6"></textarea>
- </div><br/><br/>
- <div>
- <label>What you did:</label><br/>
- <textarea id="remark" rows="6" ></textarea>
- </div>
- </div>
- </div><br/>
- </t>
<div class="oe_error_detail">
<pre><t t-esc="error.message"/></pre>
<hr/>
@@ -102,7 +79,7 @@
</form>
<div class="oe_login_footer">
<a href="#" class="oe_login_manage_db">Manage Databases</a> |
- <a href="http://www.openerp.com">Powered by <span>OpenERP</span></a>
+ <a href="http://www.openerp.com" target="_blank">Powered by <span>OpenERP</span></a>
</div>
</div>
</div>
@@ -143,7 +120,7 @@
</tr>
<tr>
<td><label for="db_name">New database name:</label></td>
- <td><input type="text" name="db_name" class="required" matches="^[a-zA-Z][a-zA-Z0-9_]+$" autofocus="true"/></td>
+ <td><input type="text" name="db_name" class="required" matches="^[a-zA-Z][a-zA-Z0-9_-]+$" autofocus="true"/></td>
</tr>
<tr>
<td><label for="demo_data">Load Demonstration data:</label></td>
@@ -427,13 +404,10 @@
</tr>
<tr>
<td class="oe_leftbar" valign="top">
- <t t-js="d">
- d.url = '/' + (window.location.search || '');
- </t>
- <a t-att-href="url" class="oe_logo"><img t-att-src='_s + "/web/static/src/img/logo.png"'/></a>
+ <a class="oe_logo" href="#"><img t-att-src='_s + "/web/static/src/img/logo.png"'/></a>
<div class="oe_secondary_menus_container"/>
<div class="oe_footer">
- Powered by <a href="http://www.openerp.com"><span>Open</span>ERP</a>
+ Powered by <a href="http://www.openerp.com" target="_blank"><span>Open</span>ERP</a>
</div>
</td>
<td class="oe_application">
@@ -502,10 +476,12 @@
<option value="">Debug View#<t t-esc="view.fields_view.view_id"/></option>
<option t-if="view_manager.active_view === 'form'" value="perm_read" data-views="form,page">View Log (perm_read)</option>
<option t-if="view_manager.active_view === 'form'" value="toggle_layout_outline">Toggle Form Layout Outline</option>
+ <option value="tests">JS Tests</option>
<option value="fields">View Fields</option>
<option value="fvg">Fields View Get</option>
<option value="manage_filters">Manage Filters</option>
<t t-if="view_manager.session.uid === 1">
+ <option value="translate">Technical translation</option>
<option value="manage_views">Manage Views</option>
<option value="edit" data-model="ir.ui.view" t-att-data-id="view.fields_view.view_id">Edit <t t-esc="_.str.capitalize(view.fields_view.type)"/>View</option>
<option t-if="view_manager.searchview" value="edit" data-model="ir.ui.view" t-att-data-id="view_manager.searchview.view_id">Edit SearchView</option>
@@ -563,6 +539,7 @@
<t t-foreach="widget.sections" t-as="section">
<div class="oe_form_dropdown_section">
<button class="oe_dropdown_toggle oe_dropdown_arrow">
+ <t t-if="section.name == 'files'" t-raw="widget.items[section.name].length || ''"/>
<t t-esc="section.label"/>
</button>
<ul class="oe_dropdown_menu">
@@ -657,7 +634,7 @@
<t t-if="column.tag !== 'button'"><t t-esc="column.string"/></t>
</th>
</t>
- <th t-if="options.deletable" width="13px"/>
+ <th t-if="options.deletable" class="oe_list_record_delete" width="13px"/>
</tr>
</thead>
<tfoot>
@@ -671,13 +648,10 @@
</tfoot>
</table>
<div t-name="ListView.buttons" class="oe_list_buttons">
- <t t-if="!widget.no_leaf and widget.options.action_buttons !== false and widget.options.addable">
+ <t t-if="!widget.no_leaf and widget.options.action_buttons !== false and widget.options.addable and widget.is_action_enabled('create')">
<button type="button" class="oe_button oe_list_add oe_highlight">
<t t-esc="widget.options.addable"/>
</button>
- <span class="oe_alternative" t-if="widget.options.import_enabled">
- <span class="oe_fade">or</span> <a href="#" class="oe_bold oe_list_button_import">Import</a>
- </span>
</t>
</div>
<t t-name="ListView.pager">
@@ -721,9 +695,10 @@
<t t-jquery="button.oe_list_add" t-operation="after">
<button class="oe_button oe_list_save oe_highlight"
type="button">Save</button>
- </t>
- <t t-jquery="a.oe_list_button_import" t-operation="after">
- <a href="#" class="oe_bold oe_list_discard">discard</a>
+ <span class="oe_alternative">
+ <span class="oe_fade">or</span>
+ <a href="#" class="oe_bold oe_list_discard">Discard</a>
+ </span>
</t>
</t>
<t t-extend="ListView.row">
@@ -747,13 +722,17 @@
<div t-name="FormView.buttons" class="oe_form_buttons">
<t t-if="widget.options.action_buttons !== false">
<span class="oe_form_buttons_view">
- <div style="display: inline-block;"> <!-- required for the bounce effect on button -->
- <button type="button" class="oe_button oe_form_button_edit">Edit</button>
+ <!-- required for the bounce effect on button -->
+ <div t-if="widget.is_action_enabled('edit')" style="display: inline-block;">
+ <button type="button" class="oe_button oe_form_button_edit" accesskey="E">Edit</button>
</div>
- <button type="button" class="oe_button oe_form_button_create">Create</button>
+ <button t-if="widget.is_action_enabled('create')"
+ type="button" class="oe_button oe_form_button_create" accesskey="C">Create</button>
</span>
<span class="oe_form_buttons_edit">
- <button type="button" class="oe_button oe_form_button_save oe_highlight">Save</button> <span class="oe_fade">or</span> <a href="#" class="oe_bold oe_form_button_cancel">Discard</a>
+ <button type="button" class="oe_button oe_form_button_save oe_highlight" accesskey="S">Save</button>
+ <span class="oe_fade">or</span>
+ <a href="#" class="oe_bold oe_form_button_cancel" accesskey="D">Discard</a>
</span>
</t>
</div>
@@ -839,7 +818,7 @@
<div class="oe_clear">
<ul t-attf-class="oe_notebook #{classnames}">
<li t-foreach="pages" t-as="page" t-att-modifiers="page.modifiers">
- <a t-attf-href="##{page.id}">
+ <a t-attf-href="##{page.id}" t-att-accesskey="page.accesskey">
<t t-esc="page.string"/>
</a>
</li>
@@ -1017,12 +996,12 @@
<t t-name="FieldMany2One">
<span class="oe_form_field oe_form_field_many2one oe_form_field_with_button" t-att-style="widget.node.attrs.style">
<t t-if="widget.get('effective_readonly')">
- <a t-if="! widget.get_definition_options().no_open" href="#" class="oe_form_uri"/>
- <span t-if="widget.get_definition_options().no_open" href="#" class="oe_form_uri"/>
+ <a t-if="! widget.options.no_open" href="#" class="oe_form_uri"/>
+ <span t-if="widget.options.no_open" href="#" class="oe_form_uri"/>
<span class="oe_form_m2o_follow"/>
</t>
<t t-if="!widget.get('effective_readonly')">
- <a t-if="! widget.get_definition_options().no_open" href="#" tabindex="-1"
+ <a t-if="! widget.options.no_open" href="#" tabindex="-1"
class="oe_m2o_cm_button oe_e">/</a>
<div>
<input type="text"
@@ -1083,19 +1062,14 @@
</span>
</t>
<t t-name="FieldStatus">
- <ul class="" t-att-style="widget.node.attrs.style"/>
+ <ul t-att-class="'oe_form_field_status ' + (widget.options.clickable ? 'oe_form_steps_clickable' : 'oe_form_steps')" t-att-style="widget.node.attrs.style"/>
</t>
<t t-name="FieldStatus.content">
- <t t-set="size" t-value="widget.to_show.length"/>
- <t t-foreach="_.range(size)" t-as="i">
- <li t-att-class="widget.to_show[i][0] === widget.selected_value ? 'oe_form_steps_active' : 'oe_form_steps_inactive'">
- <div class="oe_form_steps_button" t-att-data-id="widget.to_show[i][0]">
- <t t-esc="widget.to_show[i][1]"/>
- <span class="oe_form_steps_arrow">
- <span></span>
- </span>
- <img t-att-src='_s + "/web/static/src/img/form_steps.png"' class="oe_form_steps_arrow" t-if="i &lt; size - 1"/>
- </div>
+ <t t-foreach="widget.selection" t-as="i">
+ <li t-att-class="i[0] === widget.selected_value ? 'oe_active' : ''" t-att-data-id="i[0]">
+ <span class="label"><t t-esc="i[1]"/></span>
+ <!-- are you mit ? -->
+ <span class="arrow"><span></span></span>
</li>
</t>
</t>
@@ -1192,7 +1166,8 @@
<button type="button" class="oe_button oe_form_button"
t-att-style="widget.node.attrs.style"
t-att-tabindex="widget.node.attrs.tabindex"
- t-att-autofocus="widget.node.attrs.autofocus">
+ t-att-autofocus="widget.node.attrs.autofocus"
+ t-att-accesskey="widget.node.attrs.accesskey">
<img t-if="widget.node.attrs.icon" t-att-src="_s + widget.node.attrs.icon" width="16" height="16"/>
<span t-if="widget.string"><t t-esc="widget.string"/></span>
</button>
@@ -1229,28 +1204,6 @@
</t>
</t>
-<t t-name="TranslateDialog">
- <table t-if="widget.view.translatable_fields" class="oe_form oe_translation_form" border="0" cellpadding="0" cellspacing="0" width="100%">
- <tr>
- <td class="oe_form_separator" width="1%" nowrap="nowrap">
- <div class="oe_horizontal_separator">Field</div>
- </td>
- <th t-foreach="widget.languages" align="left">
- <div class="oe_horizontal_separator"><t t-esc="name"/></div>
- </th>
- </tr>
- <tr t-foreach="widget.view.translatable_fields" t-as="field" t-att-data-field="field.name">
- <td class="oe_form_group_cell" width="1%" nowrap="nowrap">
- <label class="oe_label"><t t-esc="field.string"/>:</label>
- </td>
- <td t-foreach="widget.languages" t-as="lg" class="oe_form_group_cell">
- <input t-if="field.field.type == 'char'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" data-value="" class="oe_trad_field" style="width: 100%"/>
- <textarea t-if="field.field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" data-value="" class="oe_trad_field" style="width: 100%"></textarea>
- </td>
- </tr>
- </table>
-</t>
-
<t t-name="AbstractFormPopup.render">
<div>
<table style="width:100%">
@@ -1741,7 +1694,7 @@
<div class="oe_blockui_spin" style="height: 50px">
</div>
<br />
- <div style="color:white">Loading...</div>
+ <div class="oe_throbber_message" style="color:white"></div>
</div>
</t>
</templates>