summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorVidhin Mehta <vme@tinyerp.com>2013-05-23 10:44:07 +0530
committerVidhin Mehta <vme@tinyerp.com>2013-05-23 10:44:07 +0530
commite9fadb6ff8c899ad3820f16abd96c8e40fa4cd91 (patch)
tree556870c837e984f68d3ec7f497d3d7558a29a752 /addons/web/static/src
parentb585ca8f093bbb479d0767eafc3bbb7602a87123 (diff)
parent978c76c5ea6bf16f7db2f94630ceb4b27caec037 (diff)
[MERGE]Trunk.
bzr revid: vme@tinyerp.com-20130514120256-0xob1bgm77zrsp27 bzr revid: vme@tinyerp.com-20130523051407-vyl5oy2ubm1on2r3
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/css/base.css138
-rw-r--r--addons/web/static/src/css/base.sass82
-rw-r--r--addons/web/static/src/fixbind.js28
-rw-r--r--addons/web/static/src/js/chrome.js19
-rw-r--r--addons/web/static/src/js/data.js48
-rw-r--r--addons/web/static/src/js/formats.js30
-rw-r--r--addons/web/static/src/js/search.js38
-rw-r--r--addons/web/static/src/js/testing.js4
-rw-r--r--addons/web/static/src/js/view_form.js147
-rw-r--r--addons/web/static/src/js/view_list.js7
-rw-r--r--addons/web/static/src/js/views.js3
-rw-r--r--addons/web/static/src/xml/base.xml21
12 files changed, 394 insertions, 171 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index 2dab643e931..b61c599ba62 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -544,6 +544,29 @@
background: #7c7bad;
color: #eeeeee;
}
+.openerp .oe_form_field_radio.oe_horizontal {
+ white-space: nowrap;
+}
+.openerp .oe_form_field_radio.oe_horizontal label {
+ display: inline-block;
+ text-align: center;
+ height: 16px;
+}
+.openerp .oe_form_field_radio.oe_vertical label {
+ margin-left: 4px;
+}
+.openerp .oe_form_field_radio.oe_form_required .oe_radio_input {
+ border: 2px solid transparent;
+ display: inline-block;
+ height: 12px;
+ width: 12px;
+ vertical-align: bottom;
+ border-radius: 10px;
+ margin: 1px 0;
+}
+.openerp .oe_form_field_radio.oe_form_required.oe_form_invalid .oe_radio_input {
+ border-color: red;
+}
.openerp .oe_tags {
margin-bottom: 1px;
}
@@ -1269,7 +1292,7 @@
color: white;
padding: 2px 4px;
margin: 1px 6px 0 0;
- border: 1px solid lightGray;
+ border: 1px solid lightgrey;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
@@ -1301,7 +1324,7 @@
transform: scale(1.1);
}
.openerp .oe_secondary_submenu .oe_active {
- border-top: 1px solid lightGray;
+ border-top: 1px solid lightgrey;
border-bottom: 1px solid #dedede;
text-shadow: 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);
@@ -1706,6 +1729,7 @@
font-size: 1px;
letter-spacing: -1px;
color: transparent;
+ text-shadow: none;
font-weight: normal;
-moz-box-shadow: none;
-webkit-box-shadow: none;
@@ -1841,12 +1865,12 @@
margin: 0;
}
.openerp .oe_searchview .oe_searchview_drawer h3 {
- margin: 8px 4px 4px 12px;
+ margin: 8px 4px 4px 0px;
color: #7c7bad;
font-size: 13px;
}
.openerp .oe_searchview .oe_searchview_drawer h4, .openerp .oe_searchview .oe_searchview_drawer h4 * {
- margin: 0;
+ margin: 0 0 0 2px;
cursor: pointer;
font-weight: normal;
display: inline-block;
@@ -1923,6 +1947,12 @@
.openerp .oe_searchview .oe_searchview_drawer .oe_searchview_custom {
padding: 0 8px 8px 8px;
}
+.openerp .oe_searchview .oe_searchview_drawer .oe_searchview_custom div {
+ padding: 0;
+}
+.openerp .oe_searchview .oe_searchview_drawer .oe_searchview_custom div h4 {
+ margin: 0;
+}
.openerp .oe_searchview .oe_searchview_drawer .oe_searchview_custom form {
display: none;
}
@@ -2164,6 +2194,7 @@
}
.openerp .oe_form header {
position: relative;
+ z-index: 1;
border-bottom: 1px solid #cacaca;
padding-left: 2px;
background-color: #ededed;
@@ -2289,7 +2320,7 @@
}
.openerp .oe_form .oe_form_label_help[for] span, .openerp .oe_form .oe_form_label[for] span {
font-size: 80%;
- color: darkGreen;
+ color: darkgreen;
vertical-align: top;
position: relative;
top: -4px;
@@ -2315,30 +2346,6 @@
display: inline-block;
min-width: 70px;
}
-.openerp .oe_form_field_radio.oe_horizontal {
- white-space: nowrap;
-}
-.openerp .oe_form_field_radio.oe_form_required .oe_radio_input {
- border: 1px solid transparent;
- display: inline-block;
- height: 12px;
- width: 12px;
- vertical-align: bottom;
- border-radius: 10px;
- margin: 1px 0;
-}
-.openerp .oe_form_field_radio.oe_form_required.oe_form_invalid .oe_radio_input {
- border-color: red;
-}
-.openerp .oe_form_field_radio.oe_horizontal label,
-.openerp .oe_form_field_radio.oe_horizontal div {
- display: inline-block;
- text-align: center;
- height: 16px;
-}
-.openerp .oe_form_field_radio.oe_vertical label {
- margin-left: 4px;
-}
.openerp .oe_form_field_progressbar.ui-progressbar {
height: 22px;
font-size: 10px;
@@ -2499,10 +2506,10 @@
width: 7em;
}
.openerp .oe_form_editable .oe_form .oe_form_field_date input {
- width: 7.5em;
+ width: 100px;
}
.openerp .oe_form_editable .oe_form .oe_form_field_datetime input {
- width: 11.5em;
+ width: 150px;
}
.openerp .oe_hidden_input_file {
position: relative;
@@ -2662,20 +2669,20 @@
background-image: -o-linear-gradient(top, #fcfcfc, #dedede);
background-image: linear-gradient(to bottom, #fcfcfc, #dedede);
}
-.openerp ul.oe_form_status li:first-child .label, .openerp ul.oe_form_status_clickable li:first-child .label {
+.openerp ul.oe_form_status li:first-child > .label, .openerp ul.oe_form_status_clickable li:first-child > .label {
border-left: 1px solid #cacaca;
padding-left: 14px;
}
.openerp ul.oe_form_status li:last-child, .openerp ul.oe_form_status_clickable li:last-child {
border-right: 1px solid #cacaca;
}
-.openerp ul.oe_form_status li:last-child .label, .openerp ul.oe_form_status_clickable li:last-child .label {
+.openerp ul.oe_form_status li:last-child > .label, .openerp ul.oe_form_status_clickable li:last-child > .label {
padding-right: 14px;
}
-.openerp ul.oe_form_status li:last-child .arrow, .openerp ul.oe_form_status_clickable li:last-child .arrow {
+.openerp ul.oe_form_status li:last-child > .arrow, .openerp ul.oe_form_status_clickable li:last-child > .arrow {
display: none;
}
-.openerp ul.oe_form_status li .label, .openerp ul.oe_form_status_clickable li .label {
+.openerp ul.oe_form_status li > .label, .openerp ul.oe_form_status_clickable li > .label {
color: #4c4c4c;
text-shadow: 0 1px 1px #fcfcfc, 0 -1px 1px #dedede;
padding: 7px;
@@ -2684,14 +2691,14 @@
margin: 0;
position: relative;
}
-.openerp ul.oe_form_status li .arrow, .openerp ul.oe_form_status_clickable li .arrow {
+.openerp ul.oe_form_status li > .arrow, .openerp ul.oe_form_status_clickable li > .arrow {
width: 17px;
display: inline-block;
vertical-align: top;
overflow: hidden;
margin-left: -5px;
}
-.openerp ul.oe_form_status li .arrow span, .openerp ul.oe_form_status_clickable li .arrow span {
+.openerp ul.oe_form_status li > .arrow span, .openerp ul.oe_form_status_clickable li > .arrow span {
position: relative;
width: 24px;
height: 24px;
@@ -2713,6 +2720,32 @@
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
+.openerp ul.oe_form_status .oe_folded .label, .openerp ul.oe_form_status_clickable .oe_folded .label {
+ padding-bottom: 8px;
+}
+.openerp ul.oe_form_status .oe_folded ul, .openerp ul.oe_form_status_clickable .oe_folded ul {
+ position: absolute;
+ border-top: 1px solid #cacaca;
+ float: none;
+ top: 30px;
+ right: 0;
+ display: none;
+}
+.openerp ul.oe_form_status .oe_folded ul li, .openerp ul.oe_form_status_clickable .oe_folded ul li {
+ margin: 0;
+ border-left: 1px solid #cacaca;
+ display: block;
+}
+.openerp ul.oe_form_status .oe_folded ul li.label, .openerp ul.oe_form_status_clickable .oe_folded ul li.label {
+ border: 0;
+ padding-left: 24px;
+}
+.openerp ul.oe_form_status .oe_folded ul li:last-child, .openerp ul.oe_form_status_clickable .oe_folded ul li:last-child {
+ border-bottom: 1px solid #cacaca;
+}
+.openerp ul.oe_form_status .oe_folded:hover ul, .openerp ul.oe_form_status_clickable .oe_folded:hover ul {
+ display: block;
+}
.openerp ul.oe_form_status li.oe_active, .openerp ul.oe_form_status_clickable li.oe_active {
background-color: #5382b9;
background-image: -webkit-gradient(linear, left top, left bottom, from(#729fcf), to(#3465a4));
@@ -2722,14 +2755,14 @@
background-image: -o-linear-gradient(top, #729fcf, #3465a4);
background-image: linear-gradient(to bottom, #729fcf, #3465a4);
}
-.openerp ul.oe_form_status li.oe_active .arrow span, .openerp ul.oe_form_status_clickable li.oe_active .arrow span {
+.openerp ul.oe_form_status li.oe_active > .arrow span, .openerp ul.oe_form_status_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));
background: -ms-linear-gradient(top, #729fcf, #3465a4);
}
-.openerp ul.oe_form_status li.oe_active .label, .openerp ul.oe_form_status_clickable li.oe_active .label {
+.openerp ul.oe_form_status li.oe_active > .label, .openerp ul.oe_form_status_clickable li.oe_active > .label {
color: white;
text-shadow: 0 1px 1px #729fcf, 0 -1px 1px #3465a4;
}
@@ -2745,10 +2778,10 @@
background-image: -o-linear-gradient(top, #e8e8e8, #cacaca);
background-image: linear-gradient(to bottom, #e8e8e8, #cacaca);
}
-.openerp ul.oe_form_status_clickable li:hover .label {
+.openerp ul.oe_form_status_clickable li:hover > .label {
text-shadow: 0 -1px 1px #fcfcfc, 0 1px 1px #dedede;
}
-.openerp ul.oe_form_status_clickable li:hover .arrow span {
+.openerp ul.oe_form_status_clickable li:hover > .arrow span {
background-color: #d9d9d9;
background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#cacaca));
background-image: -webkit-linear-gradient(top, #e8e8e8, #cacaca);
@@ -2757,7 +2790,7 @@
background-image: -o-linear-gradient(top, #e8e8e8, #cacaca);
background-image: linear-gradient(to bottom, #e8e8e8, #cacaca);
}
-.openerp ul.oe_form_status_clickable li .label {
+.openerp ul.oe_form_status_clickable li > .label {
color: #7c7bad;
}
.openerp ul.oe_form_status_clickable li.oe_active:hover {
@@ -2769,10 +2802,10 @@
background-image: -o-linear-gradient(top, #4c85c2, #284d7d);
background-image: linear-gradient(to bottom, #4c85c2, #284d7d);
}
-.openerp ul.oe_form_status_clickable li.oe_active:hover .label {
+.openerp ul.oe_form_status_clickable li.oe_active:hover > .label {
text-shadow: 0 -1px 1px #729fcf, 0 1px 1px #3465a4;
}
-.openerp ul.oe_form_status_clickable li.oe_active:hover .arrow span {
+.openerp ul.oe_form_status_clickable li.oe_active:hover > .arrow span {
background-color: #284d7d;
background: -moz-linear-gradient(135deg, #284d7d, #4c85c2);
background: -o-linear-gradient(135deg, #4c85c2, #284d7d);
@@ -3049,6 +3082,7 @@
font-size: 1px;
letter-spacing: -1px;
color: transparent;
+ text-shadow: none;
font-weight: normal;
margin-right: 7px;
}
@@ -3184,6 +3218,7 @@
.kitten-mode-activated > * {
opacity: 0.7;
}
+
.loading-kitten {
-moz-border-radius: 15px;
-webkit-border-radius: 15px;
@@ -3246,6 +3281,9 @@ div.ui-widget-overlay {
color: #afafb6 !important;
font-style: italic !important;
}
+.openerp_ie .oe_form_binary_file {
+ width: 80px;
+}
.openerp_ie .oe_form_field_boolean input {
background: white;
}
@@ -3346,11 +3384,11 @@ div.ui-widget-overlay {
overflow: hidden;
border-right: 1px solid #cacaca;
}
-.openerp_ie ul.oe_form_status li:last-child .label, .openerp_ie ul.oe_form_status_clickable li:last-child .label {
+.openerp_ie ul.oe_form_status li:last-child > .label, .openerp_ie ul.oe_form_status_clickable li:last-child > .label {
padding-right: 14px;
border-right: none;
}
-.openerp_ie ul.oe_form_status li:last-child .arrow, .openerp_ie ul.oe_form_status_clickable li:last-child .arrow {
+.openerp_ie ul.oe_form_status li:last-child > .arrow, .openerp_ie ul.oe_form_status_clickable li:last-child > .arrow {
display: inline-block;
opacity: 0;
filter: alpha(opacity=0);
@@ -3358,17 +3396,17 @@ div.ui-widget-overlay {
width: 0;
border-right: none;
}
-.openerp_ie ul.oe_form_status .label, .openerp_ie ul.oe_form_status_clickable .label {
+.openerp_ie ul.oe_form_status li > .label, .openerp_ie ul.oe_form_status_clickable li > .label {
border-bottom: 1px solid #cacaca;
background: transparent;
}
-.openerp_ie ul.oe_form_status .arrow span, .openerp_ie ul.oe_form_status_clickable .arrow span {
+.openerp_ie ul.oe_form_status li > .arrow span, .openerp_ie ul.oe_form_status_clickable li > .arrow span {
background-color: #fefefe !important;
}
-.openerp_ie ul.oe_form_status li.oe_active .label, .openerp_ie ul.oe_form_status_clickable li.oe_active .label {
+.openerp_ie ul.oe_form_status li.oe_active > .label, .openerp_ie ul.oe_form_status_clickable li.oe_active > .label {
border-bottom: 1px solid #729fcf;
}
-.openerp_ie ul.oe_form_status li.oe_active .arrow span, .openerp_ie ul.oe_form_status_clickable li.oe_active .arrow span {
+.openerp_ie ul.oe_form_status li.oe_active > .arrow span, .openerp_ie ul.oe_form_status_clickable li.oe_active > .arrow span {
background-color: #729fcf !important;
}
.openerp_ie .ui-dialog-buttonpane .ui-dialog-buttonset .ui-button {
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index 056293a4559..099b1c871f9 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -123,6 +123,7 @@ $sheet-padding: 16px
font-size: 1px
letter-spacing: -1px
color: transparent
+ text-shadow: none
font-weight: normal
&:before
font: 21px "mnmliconsRegular"
@@ -133,6 +134,7 @@ $sheet-padding: 16px
font-size: 1px
letter-spacing: -1px
color: transparent
+ text-shadow: none
font-weight: normal
&:before
font: $size "entypoRegular"
@@ -1483,11 +1485,11 @@ $sheet-padding: 16px
border-top: none
margin: 0
h3
- margin: 8px 4px 4px 12px
+ margin: 8px 4px 4px 0px
color: $section-title-color
font-size: 13px
h4, h4 *
- margin: 0
+ margin: 0 0 0 2px
cursor: pointer
font-weight: normal
display: inline-block
@@ -1543,6 +1545,10 @@ $sheet-padding: 16px
margin: 0 0 8px 0
.oe_searchview_custom
padding: 0 8px 8px 8px
+ div
+ padding: 0
+ h4
+ margin: 0
form
display: none
li
@@ -1733,6 +1739,7 @@ $sheet-padding: 16px
// FormView.header {{{
.oe_form header
position: relative
+ z-index: 1
border-bottom: 1px solid #cacaca
padding-left: 2px
@include vertical-gradient(#fcfcfc, #dedede)
@@ -1981,9 +1988,9 @@ $sheet-padding: 16px
.oe_form_field_float input
width: 7em
.oe_form_field_date input
- width: 7.5em
+ width: 100px
.oe_form_field_datetime input
- width: 11.5em
+ width: 150px
// }}}
// FormView.fields_binary {{{
/* http://www.quirksmode.org/dom/inputfile.html
@@ -2120,16 +2127,16 @@ $sheet-padding: 16px
margin: 0 -18px 0 0
padding: 0
@include vertical-gradient(#fcfcfc, #dedede)
- &:first-child .label
+ &:first-child > .label
border-left: 1px solid #cacaca
padding-left: 14px
&:last-child
border-right: 1px solid #cacaca
- .label
+ > .label
padding-right: 14px
- .arrow
+ > .arrow
display: none
- .label
+ > .label
color: #4c4c4c
text-shadow: 0 1px 1px #fcfcfc, 0 -1px 1px #dedede
padding: 7px
@@ -2137,7 +2144,7 @@ $sheet-padding: 16px
padding-left: 24px
margin: 0
position: relative
- .arrow
+ > .arrow
width: 17px
display: inline-block
vertical-align: top
@@ -2154,11 +2161,32 @@ $sheet-padding: 16px
@include skew-gradient(#fcfcfc, #dedede)
@include radius(3px)
@include transform(rotate(45deg))
+ .oe_folded
+ .label
+ padding-bottom: 8px
+ ul
+ position: absolute
+ border-top: 1px solid #cacaca
+ float: none
+ top: 30px
+ right: 0
+ display: none
+ li
+ margin: 0
+ border-left: 1px solid #cacaca
+ display: block
+ li.label
+ border: 0
+ padding-left: 24px
+ li:last-child
+ border-bottom: 1px solid #cacaca
+ &:hover ul
+ display: block
li.oe_active
@include vertical-gradient(#729fcf, #3465a4)
- .arrow span
+ > .arrow span
@include skew-gradient(#729fcf, #3465a4)
- .label
+ > .label
color: white
text-shadow: 0 1px 1px #729fcf, 0 -1px 1px #3465a4
ul.oe_form_status_clickable
@@ -2166,18 +2194,18 @@ $sheet-padding: 16px
cursor: pointer
&:hover
@include vertical-gradient(darken(#fcfcfc, 8%), darken(#dedede, 8%))
- .label
+ > .label
text-shadow: 0 -1px 1px #fcfcfc, 0 1px 1px #dedede
- .arrow span
+ > .arrow span
@include vertical-gradient(darken(#fcfcfc, 8%), darken(#dedede, 8%))
- .label
+ > .label
color: $link-color
li.oe_active
&:hover
@include vertical-gradient(darken(#729fcf, 10%), darken(#3465a4, 10%))
- .label
+ > .label
text-shadow: 0 -1px 1px #729fcf, 0 1px 1px #3465a4
- .arrow span
+ > .arrow span
@include skew-gradient(darken(#729fcf, 10%), darken(#3465a4, 10%))
// }}}
// FormView.one2many {{{
@@ -2560,6 +2588,8 @@ div.ui-widget-overlay
.placeholder
color: $tag-border !important
font-style: italic !important
+ .oe_form_binary_file
+ width: 80px
.oe_form_field_boolean input
background: #fff
.db_option_table .oe_form_field_selection
@@ -2640,26 +2670,26 @@ div.ui-widget-overlay
&:last-child
overflow: hidden
border-right: 1px solid #cacaca
- .label
+ > .label
padding-right: 14px
border-right: none
- .arrow
+ > .arrow
display: inline-block
opacity: 0
filter: alpha(opacity = 0)
border: none
width: 0
border-right: none
- .label
- border-bottom: 1px solid #cacaca
- background: transparent
- .arrow
- span
- background-color: #fefefe !important
+ > .label
+ border-bottom: 1px solid #cacaca
+ background: transparent
+ > .arrow
+ span
+ background-color: #fefefe !important
li.oe_active
- .label
+ > .label
border-bottom: 1px solid #729fcf
- .arrow span
+ > .arrow span
background-color: #729fcf !important
// jquery ui for ie
diff --git a/addons/web/static/src/fixbind.js b/addons/web/static/src/fixbind.js
new file mode 100644
index 00000000000..4a441ce0b9e
--- /dev/null
+++ b/addons/web/static/src/fixbind.js
@@ -0,0 +1,28 @@
+// Fix old versions of Webkit (such as ones used on iOS < 6 or PhantomJS <= 1.7)
+// which does not have Function.prototype.bind function
+
+// Use moz polyfill:
+// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind#Compatibility
+if (!Function.prototype.bind) {
+ Function.prototype.bind = function (oThis) {
+ if (typeof this !== "function") {
+ // closest thing possible to the ECMAScript 5 internal IsCallable function
+ throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
+ }
+
+ var aArgs = Array.prototype.slice.call(arguments, 1),
+ fToBind = this,
+ fNOP = function () {},
+ fBound = function () {
+ return fToBind.apply(this instanceof fNOP && oThis
+ ? this
+ : oThis,
+ aArgs.concat(Array.prototype.slice.call(arguments)));
+ };
+
+ fNOP.prototype = this.prototype;
+ fBound.prototype = new fNOP();
+
+ return fBound;
+ };
+}
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index 3870a7999b4..4a89eee8984 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -251,9 +251,9 @@ instance.web.CrashManager = instance.web.Class.extend({
if (handler) {
new (handler)(this, error).display();
return;
- };
+ }
if (error.data.name === "openerp.addons.web.session SessionExpiredException") {
- this.show_warning({type: "Session Expired", data: { message: "Your OpenERP session expired. Please refresh the current web page." }});
+ this.show_warning({type: "Session Expired", data: { message: _t("Your OpenERP session expired. Please refresh the current web page.") }});
return;
}
if (error.data.exception_type === "except_osv" || error.data.exception_type === "warning"
@@ -530,16 +530,11 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
'login': 'admin',
'password': form_obj['create_admin_pwd'],
'login_successful': function() {
- var action = {
- type: "ir.actions.client",
- tag: 'reload',
- params: {
- url_search : {
- db: form_obj['db_name'],
- },
- }
- };
- self.do_action(action);
+ var url = '/?db=' + form_obj['db_name'];
+ if (self.session.debug) {
+ url += '&debug';
+ }
+ instance.web.redirect(url);
},
},
_push_me: false,
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index f1b043bacf9..d60f72c6577 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -112,24 +112,27 @@ instance.web.Query = instance.web.Class.extend({
* @returns {jQuery.Deferred<Array<openerp.web.QueryGroup>> | null}
*/
group_by: function (grouping) {
- if (grouping === undefined) {
- return null;
+ var ctx = instance.web.pyeval.eval(
+ 'context', this._model.context(this._context));
+
+ // undefined passed in explicitly (!)
+ if (_.isUndefined(grouping)) {
+ grouping = [];
}
if (!(grouping instanceof Array)) {
grouping = _.toArray(arguments);
}
- if (_.isEmpty(grouping)) { return null; }
+ if (_.isEmpty(grouping) && !ctx['group_by_no_leaf']) {
+ return null;
+ }
var self = this;
-
- var ctx = instance.web.pyeval.eval(
- 'context', this._model.context(this._context));
return this._model.call('read_group', {
groupby: grouping,
fields: _.uniq(grouping.concat(this._fields || [])),
domain: this._model.domain(this._filter),
- context: this._model.context(this._context),
+ context: ctx,
offset: this._offset,
limit: this._limit,
orderby: instance.web.serialize_sort(this._order_by) || false
@@ -325,7 +328,7 @@ instance.web.Model = instance.web.Class.extend({
* Fetches the model's domain, combined with the provided domain if any
*
* @param {Array} [domain] to combine with the model's internal domain
- * @returns The model's internal domain, or the AND-ed union of the model's internal domain and the provided domain
+ * @returns {instance.web.CompoundDomain} The model's internal domain, or the AND-ed union of the model's internal domain and the provided domain
*/
domain: function (domain) {
if (!domain) { return this._domain; }
@@ -337,7 +340,7 @@ instance.web.Model = instance.web.Class.extend({
* combined with the provided context if any
*
* @param {Object} [context] to combine with the model's internal context
- * @returns The union of the user's context and the model's internal context, as well as the provided context if any. In that order.
+ * @returns {instance.web.CompoundContext} The union of the user's context and the model's internal context, as well as the provided context if any. In that order.
*/
context: function (context) {
return new instance.web.CompoundContext(
@@ -604,6 +607,9 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin,
alter_ids: function(n_ids) {
this.ids = n_ids;
},
+ remove_ids: function (ids) {
+ this.alter_ids(_(this.ids).difference(ids));
+ },
/**
* Resequence records.
*
@@ -701,22 +707,28 @@ instance.web.DataSetSearch = instance.web.DataSet.extend({
get_domain: function (other_domain) {
this._model.domain(other_domain);
},
+ alter_ids: function (ids) {
+ this._super(ids);
+ if (this.index !== null && this.index >= this.ids.length) {
+ this.index = this.ids.length > 0 ? this.ids.length - 1 : 0;
+ }
+ },
+ remove_ids: function (ids) {
+ var before = this.ids.length;
+ this._super(ids);
+ if (this._length) {
+ this._length -= (before - this.ids.length);
+ }
+ },
unlink: function(ids, callback, error_callback) {
var self = this;
return this._super(ids).done(function(result) {
- self.ids = _(self.ids).difference(ids);
- if (self._length) {
- self._length -= 1;
- }
- if (self.index !== null) {
- self.index = self.index <= self.ids.length - 1 ?
- self.index : (self.ids.length > 0 ? self.ids.length -1 : 0);
- }
+ self.remove_ids( ids);
self.trigger("dataset_changed", ids, callback, error_callback);
});
},
size: function () {
- if (this._length !== undefined) {
+ if (this._length != null) {
return this._length;
}
return this._super();
diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js
index 851b60af229..854c5f76218 100644
--- a/addons/web/static/src/js/formats.js
+++ b/addons/web/static/src/js/formats.js
@@ -314,4 +314,34 @@ instance.web.auto_date_to_str = function(value, type) {
}
};
+/**
+ * performs a half up rounding with arbitrary precision, correcting for float loss of precision
+ * See the corresponding float_round() in server/tools/float_utils.py for more info
+ * @param {Number} the value to be rounded
+ * @param {Number} a non zero precision parameter. eg: 0.01 rounds to two digits.
+ */
+instance.web.round_precision = function(value, precision){
+ if(!value){
+ return 0;
+ }else if(!precision){
+ throw new Error('round_precision(...): Cannot round value: '+value+' with a precision of zero (or undefined)');
+ }
+ var normalized_value = value / precision;
+ var epsilon_magnitude = Math.log(Math.abs(normalized_value))/Math.log(2);
+ var epsilon = Math.pow(2, epsilon_magnitude - 53);
+ normalized_value += normalized_value >= 0 ? epsilon : -epsilon;
+ var rounded_value = Math.round(normalized_value);
+ return rounded_value * precision;
+};
+
+/**
+ * performs a half up rounding with a fixed amount of decimals, correcting for float loss of precision
+ * See the corresponding float_round() in server/tools/float_utils.py for more info
+ * @param {Number} the value to be rounded
+ * @param {Number} the number of decimals. eg: round_decimals(3.141592,2) -> 3.14
+ */
+instance.web.round_decimals = function(value, decimals){
+ return instance.web.round_precision(value, Math.pow(10,-decimals));
+};
+
};
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index f5449ed8bba..0051598e48a 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -326,7 +326,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
}
},
'autocompleteopen': function () {
- this.$el.autocomplete('widget').css('z-index', 3);
+ this.$el.autocomplete('widget').css('z-index', 1004);
},
},
/**
@@ -1039,7 +1039,9 @@ instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends in
facet.values.each(function (v) {
var i = _(self.filters).indexOf(v.get('value'));
if (i === -1) { return; }
- $filters.eq(i).addClass('oe_selected');
+ $filters.filter(function () {
+ return Number($(this).data('index')) === i;
+ }).addClass('oe_selected');
});
},
/**
@@ -1129,7 +1131,7 @@ instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends in
});
},
toggle_filter: function (e) {
- this.toggle(this.filters[$(e.target).index()]);
+ this.toggle(this.filters[Number($(e.target).data('index'))]);
},
toggle: function (filter) {
this.view.query.toggle(this.make_facet([this.make_value(filter)]));
@@ -1337,20 +1339,22 @@ 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.$el.val()) {
- return null;
- }
- var val = this.parse(this.$el.val()),
- check = Number(this.$el.val());
- if (isNaN(val) || val !== check) {
- this.$el.addClass('error');
- throw new instance.web.search.Invalid(
- this.attrs.name, this.$el.val(), this.error_message);
- }
- this.$el.removeClass('error');
- return val;
- }
+ complete: function (value) {
+ var val = this.parse(value);
+ if (isNaN(val)) { return $.when(); }
+ var label = _.str.sprintf(
+ _t("Search %(field)s for: %(value)s"), {
+ field: '<em>' + this.attrs.string + '</em>',
+ value: '<strong>' + _.str.escapeHTML(value) + '</strong>'});
+ return $.when([{
+ label: label,
+ facet: {
+ category: this.attrs.string,
+ field: this,
+ values: [{label: value, value: val}]
+ }
+ }]);
+ },
});
/**
* @class
diff --git a/addons/web/static/src/js/testing.js b/addons/web/static/src/js/testing.js
index e7aad43ffc7..e665a43db01 100644
--- a/addons/web/static/src/js/testing.js
+++ b/addons/web/static/src/js/testing.js
@@ -176,9 +176,9 @@ openerp.testing = {};
});
QUnit.module(testing.current_module + '.' + name, {_oe: options});
- body(testing.case);
+ body(testing['case']);
};
- testing.case = function (name, options, callback) {
+ testing['case'] = function (name, options, callback) {
if (_.isFunction(options)) {
callback = options;
options = {};
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 53a7425c036..454f20ddcd5 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -765,7 +765,11 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
this.has_been_loaded.done(function() {
if (self.datarecord.id && confirm(_t("Do you really want to delete this record?"))) {
self.dataset.unlink([self.datarecord.id]).done(function() {
- self.execute_pager_action('next');
+ if (self.dataset.size()) {
+ self.execute_pager_action('next');
+ } else {
+ self.do_action('history_back');
+ }
def.resolve();
});
} else {
@@ -802,6 +806,8 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
if (save_obj.error)
return $.Deferred().reject();
return $.when.apply($, save_obj.ret);
+ }).done(function() {
+ self.$el.removeClass('oe_form_dirty');
});
},
_process_save: function(save_obj) {
@@ -1021,7 +1027,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
return value;
}
var fields = _.chain(this.fields)
- .map(function (field, name) {
+ .map(function (field) {
var value = field.get_value();
// ignore fields which are empty, invisible, readonly, o2m
// or m2m
@@ -1036,7 +1042,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
}
return {
- name: name,
+ name: field.name,
string: field.string,
value: value,
displayed: display(field, value),
@@ -1047,10 +1053,10 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
.value();
var conditions = _.chain(self.fields)
.filter(function (field) { return field.field.change_default; })
- .map(function (field, name) {
+ .map(function (field) {
var value = field.get_value();
return {
- name: name,
+ name: field.name,
string: field.string,
value: value,
displayed: display(field, value),
@@ -1444,6 +1450,9 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
$(this).children().each(function() {
var $td = $(this),
$child = $td.children(':first');
+ if ($child.attr('cell-class')) {
+ $td.addClass($child.attr('cell-class'));
+ }
switch ($child[0].tagName.toLowerCase()) {
case 'separator':
break;
@@ -1520,7 +1529,7 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
if (! page.__ic)
return;
page.__ic.on("change:effective_invisible", null, function() {
- if (!page.__ic.get('effective_invisible')) {
+ if (!page.__ic.get('effective_invisible') && page.autofocus) {
$new_notebook.tabs('select', i);
return;
}
@@ -2126,7 +2135,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w
value without triggering a re-rendering.
*/
internal_set_value: function(value_) {
- var tmp = this.no_render;
+ var tmp = this.no_rerender;
this.no_rerender = true;
this.set({'value': value_});
this.no_rerender = tmp;
@@ -2296,7 +2305,8 @@ instance.web.form.FieldChar = instance.web.form.AbstractField.extend(instance.we
return this.get('value') === '' || this._super();
},
focus: function() {
- this.$('input:first')[0].focus();
+ var input = this.$('input:first')[0];
+ return input ? input.focus() : false;
},
set_dimensions: function (height, width) {
this._super(height, width);
@@ -2393,7 +2403,8 @@ instance.web.form.FieldFloat = instance.web.form.FieldChar.extend({
this._super.apply(this, [value_]);
},
focus: function () {
- this.$('input:first').select();
+ var $input = this.$('input:first');
+ return $input.length ? $input.select() : false;
}
});
@@ -2413,6 +2424,42 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({
this.$input = this.$el.find('input.oe_datepicker_master');
this.$input_picker = this.$el.find('input.oe_datepicker_container');
+ $.datepicker.setDefaults({
+ clearText: _t('Clear'),
+ clearStatus: _t('Erase the current date'),
+ closeText: _t('Done'),
+ closeStatus: _t('Close without change'),
+ prevText: _t('<Prev'),
+ prevStatus: _t('Show the previous month'),
+ nextText: _t('Next>'),
+ nextStatus: _t('Show the next month'),
+ currentText: _t('Today'),
+ currentStatus: _t('Show the current month'),
+ monthNames: Date.CultureInfo.monthNames,
+ monthNamesShort: Date.CultureInfo.abbreviatedMonthNames,
+ monthStatus: _t('Show a different month'),
+ yearStatus: _t('Show a different year'),
+ weekHeader: _t('Wk'),
+ weekStatus: _t('Week of the year'),
+ dayNames: Date.CultureInfo.dayNames,
+ dayNamesShort: Date.CultureInfo.abbreviatedDayNames,
+ dayNamesMin: Date.CultureInfo.shortestDayNames,
+ dayStatus: _t('Set DD as first week day'),
+ dateStatus: _t('Select D, M d'),
+ firstDay: Date.CultureInfo.firstDayOfWeek,
+ initStatus: _t('Select a date'),
+ isRTL: false
+ });
+ $.timepicker.setDefaults({
+ timeOnlyTitle: _t('Choose Time'),
+ timeText: _t('Time'),
+ hourText: _t('Hour'),
+ minuteText: _t('Minute'),
+ secondText: _t('Second'),
+ currentText: _t('Now'),
+ closeText: _t('Done')
+ });
+
this.picker({
onClose: this.on_picker_select,
onSelect: this.on_picker_select,
@@ -2539,9 +2586,8 @@ instance.web.form.FieldDatetime = instance.web.form.AbstractField.extend(instanc
return this.get('value') === '' || this._super();
},
focus: function() {
- if (this.datewidget && this.datewidget.$input) {
- this.datewidget.$input[0].focus();
- }
+ var input = this.datewidget && this.datewidget.$input[0];
+ return input ? input.focus() : false;
},
set_dimensions: function (height, width) {
this._super(height, width);
@@ -2622,9 +2668,8 @@ instance.web.form.FieldText = instance.web.form.AbstractField.extend(instance.we
return this.get('value') === '' || this._super();
},
focus: function($el) {
- if (!this.get("effective_readonly") && this.$textarea) {
- this.$textarea[0].focus();
- }
+ var input = !this.get("effective_readonly") && this.$textarea && this.$textarea[0];
+ return input ? input.focus() : false;
},
set_dimensions: function (height, width) {
this._super(height, width);
@@ -2707,7 +2752,8 @@ instance.web.form.FieldBoolean = instance.web.form.AbstractField.extend({
this.$checkbox[0].checked = this.get('value');
},
focus: function() {
- this.$checkbox[0].focus();
+ var input = this.$checkbox && this.$checkbox[0];
+ return input ? input.focus() : false;
}
});
@@ -2793,7 +2839,8 @@ instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instan
}
},
focus: function() {
- this.$('select:first')[0].focus();
+ var input = this.$('select:first')[0];
+ return input ? input.focus() : false;
},
set_dimensions: function (height, width) {
this._super(height, width);
@@ -3336,7 +3383,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
}
if (! no_recurse) {
var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context());
- dataset.name_get([self.get("value")]).done(function(data) {
+ this.alive(dataset.name_get([self.get("value")])).done(function(data) {
self.display_value["" + self.get("value")] = data[0][1];
self.render_value(true);
});
@@ -3401,9 +3448,8 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
return ! this.get("value");
},
focus: function () {
- if (!this.get('effective_readonly')) {
- this.$input && this.$input[0].focus();
- }
+ var input = !this.get('effective_readonly') && this.$input && this.$input[0];
+ return input ? input.focus() : false;
},
_quick_create: function() {
this.no_ed = true;
@@ -4263,7 +4309,8 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
this.set({'value': _.uniq(this.get('value').concat([id]))});
},
focus: function () {
- this.$text[0].focus();
+ var input = this.$text && this.$text[0];
+ return input ? input.focus() : false;
},
set_dimensions: function (height, width) {
this._super(height, width);
@@ -5356,14 +5403,14 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
this.options.clickable = this.options.clickable || (this.node.attrs || {}).clickable || false;
this.options.visible = this.options.visible || (this.node.attrs || {}).statusbar_visible || false;
this.set({value: false});
- this.selection = [];
- this.set("selection", []);
+ this.selection = {'unfolded': [], 'folded': []};
+ this.set("selection", {'unfolded': [], 'folded': []});
this.selection_dm = new instance.web.DropMisordered();
+ this.dataset = new instance.web.DataSetStatic(this, this.field.relation, this.build_context());
},
start: function() {
this.field_manager.on("view_content_has_changed", this, this.calc_domain);
this.calc_domain();
- this.on("change:value", this, this.get_selection);
this.on("change:evaluated_selection_domain", this, this.get_selection);
this.on("change:selection", this, function() {
this.selection = this.get("selection");
@@ -5371,7 +5418,7 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
});
this.get_selection();
if (this.options.clickable) {
- this.$el.on('click','li',this.on_click_stage);
+ this.$el.on('click','li:not(.oe_folded)',this.on_click_stage);
}
if (this.$el.parent().is('header')) {
this.$el.after('<div class="oe_clear"/>');
@@ -5386,17 +5433,20 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
},
render_value: function() {
var self = this;
- var content = QWeb.render("FieldStatus.content", {widget: self});
+ var content = QWeb.render("FieldStatus.content", {
+ 'widget': self,
+ 'value_folded': _.find(self.selection.folded, function(i){return i[0] === self.get('value')})
+ });
self.$el.html(content);
},
calc_domain: function() {
var d = instance.web.pyeval.eval('domain', this.build_domain());
var domain = []; //if there is no domain defined, fetch all the records
-
+
if (d.length) {
domain = ['|',['id', '=', this.get('value')]].concat(d);
}
-
+
if (! _.isEqual(domain, this.get("evaluated_selection_domain"))) {
this.set("evaluated_selection_domain", domain);
}
@@ -5408,17 +5458,27 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
*/
get_selection: function() {
var self = this;
- var selection = [];
+ var selection_unfolded = [];
+ var selection_folded = [];
var calculation = _.bind(function() {
if (this.field.type == "many2one") {
- var domain = [];
- var ds = new instance.web.DataSetSearch(this, this.field.relation,
- self.build_context(), this.get("evaluated_selection_domain"));
- return ds.read_slice(['name'], {}).then(function (records) {
- for(var i = 0; i < records.length; i++) {
- selection.push([records[i].id, records[i].name]);
- }
+ return self.get_distant_fields().then(function(fields) {
+ return new instance.web.DataSetSearch(self, self.field.relation, self.build_context(), self.get("evaluated_selection_domain"))
+ .read_slice(fields.fold ? ['fold'] : ['id'], {}).then(function (records) {
+
+ var ids = _.map(records, function (val) {return val.id});
+ return self.dataset.name_get(ids).then(function (records_name) {
+ _.each(records, function (record) {
+ var name = _.find(records_name, function (val) {return val[0] == record.id;})[1];
+ if (record.fold && record.id != self.get('value')) {
+ selection_folded.push([record.id, name]);
+ } else {
+ selection_unfolded.push([record.id, name]);
+ }
+ });
+ })
+ });
});
} else {
// For field type selection filter values according to
@@ -5428,18 +5488,29 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
for(var i=0; i < select.length; i++) {
var key = select[i][0];
if(key == this.get('value') || !this.options.visible || this.options.visible.indexOf(key) != -1) {
- selection.push(select[i]);
+ selection_unfolded.push(select[i]);
}
}
return $.when();
}
}, this);
this.selection_dm.add(calculation()).then(function () {
+ var selection = {'unfolded': selection_unfolded, 'folded': selection_folded};
if (! _.isEqual(selection, self.get("selection"))) {
self.set("selection", selection);
}
});
},
+ get_distant_fields: function() {
+ var self = this;
+ if (this.distant_fields) {
+ return $.when(this.distant_fields);
+ }
+ return new instance.web.Model(self.field.relation).call("fields_get", [["fold"]]).then(function(fields) {
+ self.distant_fields = fields;
+ return fields;
+ })
+ },
on_click_stage: function (ev) {
var self = this;
var $li = $(ev.currentTarget);
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index b69ec6dbdca..b96079d2051 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -578,7 +578,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
this.no_leaf = !!context['group_by_no_leaf'];
this.grouped = !!group_by;
- return this.load_view(context).then(
+ return this.alive(this.load_view(context)).then(
this.proxy('reload_content'));
},
/**
@@ -895,8 +895,9 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web.
this.record_callbacks = {
'remove': function (event, record) {
- var $row = self.$current.children(
- '[data-id=' + record.get('id') + ']');
+ var id = record.get('id');
+ self.dataset.remove_ids([id])
+ var $row = self.$current.children('[data-id=' + id + ']');
var index = $row.data('index');
$row.remove();
},
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index 1143bdfc2af..0737281e199 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -241,6 +241,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
} else if (state.active_id) {
add_context.active_ids = [state.active_id];
}
+ add_context.params = state;
this.null_action();
action_loaded = this.do_action(state.action, { additional_context: add_context });
$.when(action_loaded || null).done(function() {
@@ -1004,7 +1005,7 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
switch_mode: function (view_type, no_store, options) {
var self = this;
- return $.when(this._super.apply(this, arguments)).done(function () {
+ return this.alive($.when(this._super.apply(this, arguments))).done(function () {
var controller = self.views[self.active_view].controller;
self.$el.find('.oe_debug_view').html(QWeb.render('ViewManagerDebug', {
view: controller,
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 943326f5011..14c7f722ec2 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -650,7 +650,7 @@
<li t-if="section.name == 'files'" class="oe_sidebar_add_attachment">
<t t-call="HiddenInputFile">
<t t-set="fileupload_id" t-value="widget.fileupload_id"/>
- <t t-set="fileupload_action">/web/binary/upload_attachment</t>
+ <t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t>
<input type="hidden" name="model" t-att-value="widget.dataset and widget.dataset.model"/>
<input type="hidden" name="id" t-att-value="widget.model_id"/>
<input type="hidden" name="session_id" t-att-value="widget.session.session_id"/>
@@ -1218,13 +1218,25 @@
<ul t-att-class="'oe_form_field_status ' + (widget.options.clickable ? 'oe_form_status_clickable' : 'oe_form_status')" t-att-style="widget.node.attrs.style"/>
</t>
<t t-name="FieldStatus.content">
- <t t-foreach="widget.selection" t-as="i">
+ <t t-foreach="widget.selection.unfolded" t-as="i">
<li t-att-class="i[0] === widget.get('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 t-if="widget.selection.folded.length">
+ <li t-att-class="value_folded ? 'oe_active oe_folded' : 'oe_folded'">
+ <span class="label"> ... </span>
+ <ul>
+ <t t-foreach="widget.selection.folded" t-as="i">
+ <li t-att-class="i[0] === widget.get('value') ? 'oe_active' : ''" t-att-data-id="i[0]">
+ <span class="label"><t t-esc="i[1]"/></span>
+ </li>
+ </t>
+ </ul>
+ </li>
+ </t>
</t>
<t t-name="FieldBinaryImage">
<span class="oe_form_field oe_form_field_image" t-att-style="widget.node.attrs.style">
@@ -1552,8 +1564,9 @@
<t t-esc="attrs.string"/>
</button>
<ul t-name="SearchView.filters">
- <li t-foreach="widget.filters" t-as="filter" t-if="filter.visible()"
- t-att-title="filter.attrs.string ? filter.attrs.help : undefined">
+ <li t-foreach="widget.filters" t-as="filter" t-if="!filter.visible || filter.visible()"
+ t-att-title="filter.attrs.string ? filter.attrs.help : undefined"
+ t-att-data-index="filter_index">
<t t-esc="filter.attrs.string or filter.attrs.help or filter.attrs.name or 'Ω'"/>
</li>
</ul>