diff options
| author | Paramjit Singh Sahota <psa@tinyerp.com> | 2012-07-09 14:26:35 +0530 |
|---|---|---|
| committer | Paramjit Singh Sahota <psa@tinyerp.com> | 2012-07-09 14:26:35 +0530 |
| commit | 2774263ddda67b6983d1c00a04da00e18ff53b85 (patch) | |
| tree | 3b2a8ec5fdccacc2983905f191167d5efdfeddc3 /addons/web/static/src | |
| parent | 202238473c6eb90e539028d553265eb1ec43c87a (diff) | |
| parent | 4d2255a2b3390653f58a17502f7be37b5ec15089 (diff) | |
[MERGE] Merged from openerp-web.
bzr revid: psa@tinyerp.com-20120709085635-g0tcm7nlqe7wd3n3
Diffstat (limited to 'addons/web/static/src')
| -rw-r--r-- | addons/web/static/src/css/base.css | 177 | ||||
| -rw-r--r-- | addons/web/static/src/css/base.sass | 133 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome.js | 90 | ||||
| -rw-r--r-- | addons/web/static/src/js/corelib.js | 6 | ||||
| -rw-r--r-- | addons/web/static/src/js/coresetup.js | 45 | ||||
| -rw-r--r-- | addons/web/static/src/js/search.js | 72 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_form.js | 112 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_list.js | 16 | ||||
| -rw-r--r-- | addons/web/static/src/js/views.js | 7 | ||||
| -rw-r--r-- | addons/web/static/src/xml/base.xml | 32 |
10 files changed, 503 insertions, 187 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 00ecab65951..9f443f68504 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -34,7 +34,7 @@ background: white; /* http://www.quirksmode.org/dom/inputfile.html * http://stackoverflow.com/questions/2855589/replace-input-type-file-by-an-image - */ + */ */ } .openerp a { text-decoration: none; @@ -91,7 +91,7 @@ list-style-type: none; } .openerp input, .openerp textarea, .openerp select { - padding: 1px 4px; + padding: 2px 4px; border: 1px solid #cccccc; -moz-border-radius: 3px; -webkit-border-radius: 3px; @@ -186,6 +186,99 @@ .openerp .ui-menu .ui-menu-item a.ui-state-active { background: #f0f0fa; } +.openerp.ui-dialog { + display: none; + position: fixed; + padding: 6px; + top: 50%; + left: 50%; + z-index: 1050; + width: 560px; + margin: -150px 0 0 -280px; + background-color: rgba(60, 60, 60, 0.7); + border: 1px solid; + border-color: #888888 #555555 #444444; + -moz-border-radius: 8px; + -webkit-border-radius: 8px; + border-radius: 8px; + -moz-box-shadow: 0 1px 12px rgba(0, 0, 0, 0.6); + -webkit-box-shadow: 0 1px 12px rgba(0, 0, 0, 0.6); + box-shadow: 0 1px 12px rgba(0, 0, 0, 0.6); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.openerp.ui-dialog .ui-dialog-titlebar, .openerp.ui-dialog .ui-dialog-content, .openerp.ui-dialog .ui-dialog-buttonpane { + padding: 16px; +} +.openerp.ui-dialog .ui-dialog-titlebar { + border-bottom: 1px solid #cacaca; + -moz-border-radius: 2px 2px 0 0; + -webkit-border-radius: 2px 2px 0 0; + border-radius: 2px 2px 0 0; + 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.ui-dialog .ui-dialog-titlebar .ui-dialog-title { + margin: 0; + padding: 0; +} +.openerp.ui-dialog .ui-widget-header { + border: none; +} +.openerp.ui-dialog .ui-dialog-content { + background: white; +} +.openerp.ui-dialog .ui-dialog-buttonpane { + border-top: 1px solid #e0e0e0; + background: #f5f7f9; + padding: 8px; + margin: 0; + -moz-border-radius: 0 0 2px 2px; + -webkit-border-radius: 0 0 2px 2px; + border-radius: 0 0 2px 2px; +} +.openerp.ui-dialog .ui-dialog-buttonpane button { + margin-left: 8px; +} +.openerp.ui-dialog .ui-dialog-titlebar-close { + padding: 0; +} +.openerp.ui-dialog .ui-dialog-titlebar-close .ui-icon-closethick { + display: none; +} +.openerp.ui-dialog .ui-dialog-titlebar-close:before { + content: "×"; + font-size: 18px; + font-weight: bold; + line-height: 16px; + color: black; + text-shadow: 0 1px 0 white; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; +} +.openerp.ui-dialog .ui-dialog-titlebar-close:before:hover { + color: black; + text-decoration: none; +} +.openerp .modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: black; + filter: alpha(opacity=30); + opacity: 0.3; +} .openerp .oe_i { font-family: "mnmliconsRegular" !important; font-size: 21px; @@ -283,7 +376,7 @@ background: #ed6f6a; } .openerp .oe_title { - width: 55%; + width: 60%; } .openerp .oe_title:after { content: "."; @@ -341,6 +434,19 @@ .openerp .oe_button.oe_link span:hover { text-decoration: underline; } +.openerp .oe_webclient .oe_star_on, .openerp .oe_webclient .oe_star_off { + color: #cccccc; + text-shadow: 0 0 2px black; + vertical-align: top; + position: relative; + top: -5px; +} +.openerp .oe_webclient .oe_star_on:hover, .openerp .oe_webclient .oe_star_off:hover { + text-decoration: none; +} +.openerp .oe_webclient .oe_star_on { + color: gold; +} .openerp.oe_tooltip { font-size: 12px; } @@ -368,6 +474,11 @@ list-style: none; zoom: 1; } +.openerp .oe_notebook.ui-corner-all { + -moz-border-radius: 0; + -webkit-border-radius: 0; + border-radius: 0; +} .openerp .oe_notebook:before, .openerp .oe_notebook:after { display: table; content: ""; @@ -424,18 +535,22 @@ position: relative; cursor: pointer; } +.openerp .oe_dropdown_toggle { + color: #888888; + font-weight: normal; +} .openerp .oe_dropdown_hover:hover .oe_dropdown_menu, .openerp .oe_dropdown_menu.oe_opened { display: block; } .openerp .oe_dropdown_menu { display: none; position: absolute; - top: 28px; + top: 32px; z-index: 1; border: 1px solid #afafb6; background: white; - padding: 8px; - min-width: 120px; + padding: 6px 0; + min-width: 140px; text-align: left; -moz-border-radius: 3px; -webkit-border-radius: 3px; @@ -465,7 +580,7 @@ .openerp .oe_dropdown_menu > li > a { white-space: nowrap; display: block; - padding: 3px 6px; + padding: 4px 15px; color: #4c4c4c; text-decoration: none; } @@ -779,6 +894,7 @@ border-top: 4px solid white; } .openerp .oe_topbar .oe_dropdown_menu { + top: 32px; background: #333333; background: rgba(37, 37, 37, 0.9); border-color: #999999; @@ -1161,10 +1277,10 @@ .openerp .oe_view_manager .oe_view_manager_switch .oe_vm_switch_diagram:after { content: "f"; } -.openerp .oe_view_manager_global { +.openerp .oe_view_manager_current { height: 100%; } -.openerp .oe_view_manager_global > .oe_view_manager_header { +.openerp .oe_view_manager_current > .oe_view_manager_header { border-top: 1px solid #cacaca; border-bottom: 1px solid #cacaca; background-color: #fcfcfc; @@ -1178,12 +1294,18 @@ -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 9px rgba(0, 0, 0, 0.1); box-shadow: 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 9px rgba(0, 0, 0, 0.1); } -.openerp .oe_view_manager_global > .oe_view_manager_header .oe_header_row td { +.openerp .oe_view_manager_current > .oe_view_manager_header .oe_header_row td { padding: 8px; } -.openerp .oe_view_manager_global > .oe_view_manager_header .oe_header_row:first-child td { +.openerp .oe_view_manager_current > .oe_view_manager_header .oe_header_row:first-child td { padding-top: 8px; } +.openerp .oe_view_manager_inline { + height: 100%; +} +.openerp .oe_view_manager_inline > .oe_view_manager_header { + display: none; +} .openerp .oe_popup_form > .oe_formview > .oe_form_pager { display: none !important; } @@ -1206,7 +1328,7 @@ .openerp .oe_searchview input, .openerp .oe_searchview textarea { padding: 3px; height: 14px; - font-size: 11px; + font-size: 12px; line-height: 18px; } .openerp .oe_searchview.oe_focused { @@ -1565,11 +1687,11 @@ background-color: #ff6666 !important; border: 1px solid #dd0000 !important; } -.openerp .oe_form_editable .oe_highlight { +.openerp .oe_view_manager_current .oe_form_editable .oe_highlight { color: #404040; background: none; } -.openerp .oe_form_editable button.oe_highlight { +.openerp .oe_view_manager_current .oe_form_editable button.oe_highlight { background-color: #efefef; background-image: -webkit-gradient(linear, left top, left bottom, from(#efefef), to(#d8d8d8)); background-image: -webkit-linear-gradient(top, #efefef, #d8d8d8); @@ -1581,7 +1703,7 @@ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(255, 255, 255, 0.8) inset; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(255, 255, 255, 0.8) inset; } -.openerp .oe_form_editable button.oe_highlight:active { +.openerp .oe_view_manager_current .oe_form_editable button.oe_highlight:active { background-color: #e3e3e3; background-image: -webkit-gradient(linear, left top, left bottom, from(#e3e3e3), to(#f6f6f6)); background-image: -webkit-linear-gradient(top, #e3e3e3, #f6f6f6); @@ -1593,7 +1715,7 @@ -webkit-box-shadow: none; box-shadow: none; } -.openerp .oe_form_editable button.oe_highlight:hover { +.openerp .oe_view_manager_current .oe_form_editable button.oe_highlight:hover { background-color: #f6f6f6; background-image: -webkit-gradient(linear, left top, left bottom, from(#f6f6f6), to(#e3e3e3)); background-image: -webkit-linear-gradient(top, #f6f6f6, #e3e3e3); @@ -1611,9 +1733,13 @@ .openerp .oe_form_readonly .oe_edit_only, .openerp .oe_form_readonly .oe_form_field:empty { display: none !important; } -.openerp .oe_form_nosheet > *:not(header) { - margin-left: 10px !important; - margin-right: 10px !important; +.openerp .oe_form_nosheet { + margin-left: 10px; + margin-right: 10px; +} +.openerp .oe_form_nosheet > header { + margin-left: -10px; + margin-right: -10px; } .openerp .oe_form header { position: relative; @@ -1634,7 +1760,7 @@ } .openerp .oe_form footer { min-width: 650px; - max-width: 960px; + max-width: 860px; margin: 0 auto; } .openerp ul.oe_form_steps { @@ -1703,7 +1829,7 @@ } .openerp .oe_application .oe_form_sheet_width { min-width: 650px; - max-width: 960px; + max-width: 860px; margin: 0 auto; } .openerp .oe_application .oe_form_sheet { @@ -2013,7 +2139,10 @@ display: none; } .openerp .oe_form_field_one2many .oe_list .oe_list_edit_row_save { - background-image: url(/web/static/src/img/iconset-b-remove.png); + background: url(/web/static/src/img/iconset-b-remove.png) 50% 50% no-repeat; +} +.openerp .oe_form_field_one2many .oe_list .oe_list_edit_row_save:before { + visibility: hidden; } .openerp .oe_form_field_one2many > .oe_view_manager .oe_header_row_top { display: none; @@ -2083,7 +2212,6 @@ } .openerp .oe_list_content > tbody { cursor: pointer; - background: white; } .openerp .oe_list_content > tbody > tr { border-top: 1px solid #dddddd; @@ -2143,6 +2271,9 @@ .openerp .oe_list_content .numeric input { text-align: right; } +.openerp .oe_list_content .oe_list_edit_row_save:before { + content: "S"; +} .openerp .oe_trad_field.touched { border: 1px solid green !important; } diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index a0b29b1fc81..82ed305a275 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -6,6 +6,7 @@ $facets-border: #afafb6 $facets-border-selected: #a6a6fe $hover-background: #f0f0fa $colour4: #8a89ba +$sheet-max-width: 860px // }}} // Mixins {{{ @font-face @@ -143,7 +144,7 @@ $colour4: #8a89ba li list-style-type: none input, textarea, select - padding: 1px 4px + padding: 2px 4px border: 1px solid #ccc @include radius(3px) background: white @@ -200,6 +201,75 @@ $colour4: #8a89ba width: auto a.ui-state-active background: #f0f0fa + + // Modal box + &.ui-dialog + display: none + position: fixed + padding: 6px + top: 50% + left: 50% + z-index: 1050 + width: 560px + margin: -150px 0 0 -280px + //overflow: hidden + background-color: rgba(60,60,60,0.7) + border: 1px solid + border-color: #888 #555 #444 + //overflow: hidden + @include radius(8px) + @include box-shadow(0 1px 12px rgba(0, 0, 0, 0.6)) + @include background-clip() + .ui-dialog-titlebar, .ui-dialog-content, .ui-dialog-buttonpane + padding: 16px + .ui-dialog-titlebar + border-bottom: 1px solid #cacaca + @include radius(2px 2px 0 0) + @include vertical-gradient(#FCFCFC, #DEDEDE) + .ui-dialog-title + margin: 0 + padding: 0 + .ui-widget-header + border: none + .ui-dialog-content + background: white + .ui-dialog-buttonpane + border-top: 1px solid #e0e0e0 + background: #f5f7f9 + padding: 8px + margin: 0 + @include radius(0 0 2px 2px) + button + margin-left: 8px + .ui-dialog-titlebar-close + padding: 0 + .ui-icon-closethick + display: none + &:before + content: "×" + font-size: 18px + font-weight: bold + line-height: 16px + color: black + text-shadow: 0 1px 0 white + padding: 0 + cursor: pointer + background: transparent + border: 0 + &:hover + color: black + text-decoration: none + + .modal-backdrop + position: fixed + top: 0 + right: 0 + bottom: 0 + left: 0 + z-index: 1040 + background-color: black + @include opacity(.3) + // }}} // Generic classes {{{ .oe_i @@ -252,7 +322,7 @@ $colour4: #8a89ba &:hover background: #ED6F6A .oe_title - width: 55% + width: 60% .oe_title:after content: "." display: block @@ -279,6 +349,17 @@ $colour4: #8a89ba font-weight: bold &:hover text-decoration: underline + .oe_webclient + .oe_star_on, .oe_star_off + color: #cccccc + text-shadow: 0 0 2px black + vertical-align: top + position: relative + top: -5px + .oe_star_on:hover, .oe_star_off:hover + text-decoration: none + .oe_star_on + color: gold //.oe_edit_only // }}} @@ -305,6 +386,8 @@ $colour4: #8a89ba padding: 0 16px list-style: none zoom: 1 + .oe_notebook.ui-corner-all + @include radius(0) .oe_notebook:before, .oe_notebook:after display: table content: "" @@ -348,17 +431,20 @@ $colour4: #8a89ba .oe_dropdown, .oe_dropdown_hover, .oe_dropdown_toggle position: relative cursor: pointer + .oe_dropdown_toggle + color: #888 + font-weight: normal .oe_dropdown_hover:hover .oe_dropdown_menu, .oe_dropdown_menu.oe_opened display: block .oe_dropdown_menu display: none position: absolute - top: 28px + top: 32px z-index: 1 border: 1px solid #afafb6 background: white - padding: 8px - min-width: 120px + padding: 6px 0 + min-width: 140px text-align: left @include radius(3px) @include box-shadow(0 1px 4px rgba(0,0,0,0.3)) @@ -373,7 +459,7 @@ $colour4: #8a89ba > a white-space: nowrap display: block - padding: 3px 6px + padding: 4px 15px color: #4c4c4c text-decoration: none &:hover @@ -391,7 +477,6 @@ $colour4: #8a89ba border-right: 4px solid transparent border-top: 4px solid#404040 @include opacity(0.5) - .oe_sidebar white-space: nowrap .oe_dropdown_menu @@ -612,6 +697,7 @@ $colour4: #8a89ba .oe_dropdown_arrow:after border-top: 4px solid white .oe_dropdown_menu + top: 32px background: #333 background: rgba(37,37,37,0.9) border-color: #999 @@ -627,6 +713,7 @@ $colour4: #8a89ba &:hover @include vertical-gradient(#292929, #191919) @include box-shadow(none) + // }}} // Webclient.leftbar {{{ .oe_leftbar @@ -912,7 +999,7 @@ $colour4: #8a89ba content: "f" // }}} // ViewManager application {{{ - .oe_view_manager_global + .oe_view_manager_current height: 100% > .oe_view_manager_header border-top: 1px solid #cacaca @@ -926,6 +1013,12 @@ $colour4: #8a89ba td padding-top: 8px // }}} + // ViewManager inline {{{ + .oe_view_manager_inline + height: 100% + > .oe_view_manager_header + display: none + // }}} // Viewmanager popup {{{ .oe_popup_form > .oe_formview > .oe_form_pager display: none !important @@ -945,7 +1038,7 @@ $colour4: #8a89ba input, textarea padding: 3px height: 14px - font-size: 11px + font-size: 12px line-height: 18px &.oe_focused border-color: $facets-border-selected @@ -1240,7 +1333,7 @@ $colour4: #8a89ba input, select, textarea background-color: #F66 !important border: 1px solid #D00 !important - .oe_form_editable + .oe_view_manager_current .oe_form_editable .oe_highlight color: #404040 background: none @@ -1258,9 +1351,12 @@ $colour4: #8a89ba .oe_form_readonly .oe_edit_only, .oe_form_field:empty display: none !important - .oe_form_nosheet > *:not(header) - margin-left: 10px !important - margin-right: 10px !important + .oe_form_nosheet + margin-left: 10px + margin-right: 10px + .oe_form_nosheet > header + margin-left: -10px + margin-right: -10px // }}} // FormView.custom tags and classes {{{ .oe_form @@ -1275,7 +1371,7 @@ $colour4: #8a89ba float: right footer min-width: 650px - max-width: 960px + max-width: $sheet-max-width margin: 0 auto ul.oe_form_steps height: 30px @@ -1330,7 +1426,7 @@ $colour4: #8a89ba border-bottom: 1px solid #ddd .oe_form_sheet_width min-width: 650px - max-width: 960px + max-width: $sheet-max-width margin: 0 auto .oe_form_sheet background: white @@ -1589,7 +1685,9 @@ $colour4: #8a89ba .oe_form_field_one2many // TODO: oe_form_field_one2many_list? .oe_list .oe_list_edit_row_save - background-image: url(/web/static/src/img/iconset-b-remove.png) + background: url(/web/static/src/img/iconset-b-remove.png) 50% 50% no-repeat + &:before + visibility: hidden &> .oe_view_manager .oe_header_row_top @@ -1649,7 +1747,6 @@ $colour4: #8a89ba @include opacity(0.6) > tbody cursor: pointer - background: white > tr border-top: 1px solid #ddd > td.oe_list_field_cell @@ -1684,6 +1781,8 @@ $colour4: #8a89ba width: 82px input text-align: right + .oe_list_edit_row_save:before + content: "S" // }}} // Translation {{{ .oe_trad_field.touched diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 76a6b561f64..b87ebe56856 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -136,14 +136,18 @@ instance.web.Dialog = instance.web.Widget.extend({ }, on_close: function() { if (this.dialog_options.destroy_on_close) { - this.$element.dialog('destroy'); + this.destroy(); } }, on_resized: function() { }, destroy: function () { - this.close(); - this.$element.dialog('destroy'); + _.each(this.getChildren(), function(el) { + el.destroy(); + }); + if (! this.isDestroyed()) { + this.$element.dialog('destroy'); + } this._super(); } }); @@ -401,7 +405,14 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ success: function () { self.do_notify(_t("Backed"), _t("Database backed up successfully")); }, - error: instance.webclient.crashmanager.on_rpc_error, + error: function(error){ + if(error){ + self.display_error({ + title: 'Backup Database', + error: 'AccessDenied' + }); + } + }, complete: function() { self.unblockUI(); } @@ -538,6 +549,7 @@ instance.web.Login = instance.web.Widget.extend({ do_login: function (db, login, password) { var self = this; this.$element.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) { if(self.remember_credentials) { @@ -552,9 +564,9 @@ instance.web.Login = instance.web.Widget.extend({ localStorage.setItem('last_password_login_success', ''); } } - self.$(".oe_login_pane").fadeOut("slow"); self.trigger("login"); },function () { + self.$(".oe_login_pane").fadeIn("fast"); self.$element.addClass("oe_login_invalid"); }); } @@ -571,6 +583,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.on('click', 'a[data-menu]', this.on_menu_click); return this.do_reload(); }, do_reload: function() { @@ -583,7 +596,6 @@ instance.web.Menu = instance.web.Widget.extend({ this.limit_entries(); this.$secondary_menus.html(QWeb.render("Menu.secondary", { widget : this })); this.$element.on('click', 'a[data-menu]', this.on_menu_click); - this.$secondary_menus.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) { @@ -665,32 +677,37 @@ instance.web.Menu = instance.web.Widget.extend({ * Process a click on a menu item * * @param {Number} id the menu_id + * @param {Boolean} [needaction=false] whether the triggered action should execute in a `needs action` context */ - menu_click: function(id) { - if (id) { - // find back the menuitem in dom to get the action - var $item = this.$element.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) { - $sub_menu = this.$secondary_menus.find('.oe_secondary_menu[data-menu-parent=' + id + ']'); - $items = $sub_menu.find('a[data-action-id]').filter('[data-action-id!=""]'); - if($items.length) { - action_id = $items.data('action-id'); - id = $items.data('menu'); - } + menu_click: function(id, needaction) { + if (!id) { return; } + + // find back the menuitem in dom to get the action + var $item = this.$element.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) { + 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) { + action_id = $items.data('action-id'); + id = $items.data('menu'); } } - this.open_menu(id); - this.current_menu = id; - this.session.active_id = id; - if (action_id) { - this.trigger('menu_click', action_id, id, $item); - } + } + 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 + }, $item); } }, /** @@ -700,7 +717,8 @@ instance.web.Menu = instance.web.Widget.extend({ */ on_menu_click: function(ev) { ev.preventDefault(); - this.menu_click($(ev.currentTarget).data('menu')); + var needaction = $(ev.target).is('div.oe_menu_counter'); + this.menu_click($(ev.currentTarget).data('menu'), needaction); }, }); @@ -1010,8 +1028,16 @@ instance.web.WebClient = instance.web.Widget.extend({ this._current_state = _.clone(state); $.bbq.pushState(url); }, - on_menu_action: function(action) { - this.action_manager.do_action(action); + on_menu_action: function(options) { + var self = this; + this.rpc("/web/action/load", { action_id: options.action_id }) + .then(function (result) { + var action = result.result; + if (options.needaction) { + action.context.search_default_needaction_pending = true; + } + self.action_manager.do_action(action); + }); }, do_action: function(action) { var self = this; diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js index 988c419182b..a200f272a91 100644 --- a/addons/web/static/src/js/corelib.js +++ b/addons/web/static/src/js/corelib.js @@ -1314,19 +1314,19 @@ instance.web.JsonRPC = instance.web.CallbackEnabled.extend({ } else { // Indirect jsonp request var ifid = _.uniqueId('oe_rpc_iframe'); - var display = options.openerp.debug ? 'block' : 'none'; + var display = self.debug ? 'block' : 'none'; var $iframe = $(_.str.sprintf("<iframe src='javascript:false;' name='%s' id='%s' style='display:%s'></iframe>", ifid, ifid, display)); var $form = $('<form>') .attr('method', 'POST') .attr('target', ifid) .attr('enctype', "multipart/form-data") - .attr('action', ajax.url + '?' + $.param(data)) + .attr('action', ajax.url + '?jsonp=1&' + $.param(data)) .append($('<input type="hidden" name="r" />').attr('value', payload_str)) .hide() .appendTo($('body')); var cleanUp = function() { if ($iframe) { - $iframe.unbind("load").attr("src", "javascript:false;").remove(); + $iframe.unbind("load").remove(); } $form.remove(); }; diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js index 955a46e6923..a00ca4002e5 100644 --- a/addons/web/static/src/js/coresetup.js +++ b/addons/web/static/src/js/coresetup.js @@ -334,11 +334,14 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess .appendTo(document.body) .load(function () { try { - if (options.error) { - options.error(JSON.parse( - this.contentDocument.body.childNodes[1].textContent - )); - } + if (options.error) { + if (!this.contentDocument.body.childNodes[1]) { + options.error(this.contentDocument.body.childNodes); + } + else { + options.error(JSON.parse(this.contentDocument.body.childNodes[1].textContent)); + } + } } finally { complete(); } @@ -605,15 +608,31 @@ instance.web.qweb.preprocess_node = function() { }; /** Setup jQuery timeago */ -var timeago_setup = function () { - var s = $.timeago.settings.strings; - _.each(s, function(v,k) { - if(_.isString(v)) { - s[k] = instance.web._t(v); - } - }); +var _t = instance.web._t; +/* + * Strings in timeago are "composed" with prefixes, words and suffixes. This + * makes their detection by our translating system impossible. Use all literal + * strings we're using with a translation mark here so the extractor can do its + * job. + */ +{ + _t('less than a minute ago'); + _t('about a minute ago'); + _t('%d minutes ago'); + _t('about an hour ago'); + _t('%d hours ago'); + _t('a day ago'); + _t('%d days ago'); + _t('about a month ago'); + _t('%d months ago'); + _t('about a year ago'); + _t('%d years ago'); } -instance.connection.on('module_loaded', this, timeago_setup); + +instance.connection.on('module_loaded', this, function () { + // provide timeago.js with our own translator method + $.timeago.settings.translator = instance.web._t; +}); /** * Registry for all the client actions key: tag value: widget diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 169c7053575..c8b6f797dba 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -352,6 +352,11 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea e.stopImmediatePropagation(); self.$element.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'); + } + }); // Focus last input if the view itself is clicked (empty section of // facets element) this.$element.on('click', function (e) { @@ -635,12 +640,13 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea (new instance.web.search.CustomFilters(this)); // add Advanced to this.inputs (new instance.web.search.Advanced(this)); - (new instance.web.search.AddToDashboard(this)); // build drawer var drawer_started = $.when.apply( null, _(this.select_for_drawer()).invoke( 'appendTo', this.$element.find('.oe_searchview_drawer'))); + + new instance.web.search.AddToDashboard(this).appendTo($('.oe_searchview_drawer', this.$element)); // load defaults var defaults_fetched = $.when.apply(null, _(this.inputs).invoke( @@ -1188,7 +1194,7 @@ instance.web.search.Field = instance.web.search.Input.extend( /** @lends instanc var self = this; // A field needs a context to send when active var context = this.attrs.context; - if (!context || !facet.values.length) { + if (_.isEmpty(context) || !facet.values.length) { return; } var contexts = facet.values.map(function (facetValue) { @@ -1484,6 +1490,15 @@ instance.web.search.ManyToOneField = instance.web.search.CharField.extend({ return [[name, '=', facetValue.get('value')]]; } return this._super(name, operator, facetValue); + }, + get_context: function (facet) { + var values = facet.values; + if (_.isEmpty(this.attrs.context) && values.length === 1) { + var c = {}; + c['default_' + this.attrs.name] = values.at(0).get('value'); + return c; + } + return this._super(facet); } }); @@ -1638,7 +1653,7 @@ instance.web.search.Filters = instance.web.search.Input.extend({ })); } }); -instance.web.search.AddToDashboard = instance.web.search.Input.extend({ +instance.web.search.AddToDashboard = instance.web.Widget.extend({ template: 'SearchView.addtodashboard', _in_drawer: true, start: function () { @@ -1646,44 +1661,18 @@ instance.web.search.AddToDashboard = instance.web.search.Input.extend({ this.data_loaded = $.Deferred(); this.dashboard_data =[]; this.$element - .on('click', 'h4', this.proxy('show_option')) - .on('submit', 'form', function (e) {e.preventDefault(); self.add_dashboard();}); + .on('click', 'h4', this.proxy('show_option')) + .on('submit', 'form', function (e) { + e.preventDefault(); + self.add_dashboard(); + }); return $.when(this.load_data(),this.data_loaded).pipe(this.proxy("render_data")); }, load_data:function(){ - // get from database if dashboard position change than also works(from Reporting to else). - /*var self = this, - ir_actions_act_window = new instance.web.Model('ir.actions.act_window',{},[['res_model','=',"board.board"],['view_id','!=',false]]) - .query(['name','id']), - map_data = function(){ - var ir_actions_values = arguments[0],ir_values = arguments[1]; - _(ir_values).each(function(res){ - var get_name = _.detect(ir_actions_values,function(name){ return name.id == parseInt((res.value).split(",")[1]);}); - self.dashboard_data.push({"res_id":res.res_id,"name":get_name.name}) - }); - self.data_loaded.resolve(); - }, - make_domain = function(result){ - var domain = []; - _(result).map(function(value,key){ - domain.push(["value","=","ir.actions.act_window,"+value.id]); - ((result.length)- 1 !== key)?domain.unshift("|"):false; - }) - return domain; - }; - return ir_actions_act_window._execute().then(function(ir_actions_values){ - if(!ir_actions_values.length) {self.data_loaded.resolve();return;} - var ir_value = new instance.web.Model('ir.values',{},make_domain(ir_actions_values)).query(['res_id','value']); - ir_value._execute().done(function(ir_values){ - map_data(ir_actions_values,ir_values); - }) - });*/ - - //===============================get from instance.webclient.menu (with less rpc call) - var self = this,dashbaord_menu = instance.webclient.menu.data.data.children, - ir_model_data = new instance.web.Model('ir.model.data',{},[['name','=','menu_reporting_dashboard']]).query(['res_id']), - map_data = function(result){ - _.detect(dashbaord_menu,function(dash){ + var self = this,dashboard_menu = instance.webclient.menu.data.data.children; + var ir_model_data = new instance.web.Model('ir.model.data',{},[['name','=','menu_reporting_dashboard']]).query(['res_id']); + var map_data = function(result){ + _.detect(dashboard_menu, function(dash){ var id = _.pluck(dash.children, "id"),indexof = _.indexOf(id, result.res_id); if(indexof !== -1){ self.dashboard_data = dash.children[indexof].children @@ -1701,8 +1690,10 @@ instance.web.search.AddToDashboard = instance.web.search.Input.extend({ this.$element.find("input").before(selection) }, add_dashboard:function(){ - var self = this,getParent = this.getParent(),view_parent = this.view.getParent(); - if(!view_parent.action || !this.$element.find("select").val()) + var self = this; + var getParent = this.getParent(); + var view_parent = this.getParent().getParent(); + if (! view_parent.action || ! this.$element.find("select").val()) return this.do_warn("Can't find dashboard action"); data = getParent.build_search_data(), context = new instance.web.CompoundContext(getParent.dataset.get_context() || []), @@ -1732,6 +1723,7 @@ instance.web.search.AddToDashboard = instance.web.search.Input.extend({ this.$element.find("input").val(this.getParent().fields_view.name || "" ); } }); + instance.web.search.Advanced = instance.web.search.Input.extend({ template: 'SearchView.advanced', _in_drawer: true, diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index a2d849d5172..a65e471c6bf 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -333,9 +333,6 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM if (self.sidebar) { self.sidebar.do_attachement_update(self.dataset, self.datarecord.id); } - if (self.default_focus_field) { - self.default_focus_field.focus(); - } if (record.id) { self.do_push_state({id:record.id}); } @@ -584,6 +581,16 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM _.each(this.fields,function(field){ field.set({"force_readonly": false}); }); + var fields_order = self.fields_order.slice(0); + if (self.default_focus_field) { + fields_order.unshift(self.default_focus_field); + } + for (var i = 0; i < fields_order.length; i += 1) { + var field = self.fields[fields_order[i]]; + if (!field.get('effective_invisible') && !field.get('effective_readonly') && field.focus() !== false) { + break; + } + } } }, on_button_save: function() { @@ -728,7 +735,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM var msg = "<ul>"; _.each(this.fields, function(f) { if (!f.is_valid()) { - msg += "<li>" + (f.node.attrs.string || f.field.string) + "</li>"; + msg += "<li>" + f.string + "</li>"; } }); msg += "</ul>"; @@ -872,7 +879,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM return { name: name, - string: field.node.attrs.string || field.field.string, + string: field.string, value: value, displayed: displayed, // convert undefined to false @@ -921,6 +928,9 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM register_field: function(field, name) { this.fields[name] = field; this.fields_order.push(name); + if (field.node.attrs.default_focus == '1') { + this.default_focus_field = field; + } field.on('focused', null, this.proxy('widgetFocused')) .on('blurred', null, this.proxy('widgetBlurred')); @@ -1525,7 +1535,9 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi this._super.apply(this, arguments); }, /** - * Sets up blur/focus forwarding from DOM elements to a widget (`this`) + * Sets up blur/focus forwarding from DOM elements to a widget (`this`). + * + * This method is an utility method that is meant to be called by child classes. * * @param {jQuery} $e jQuery object of elements to bind focus/blur on */ @@ -1774,7 +1786,7 @@ instance.web.form.FieldInterface = { */ is_syntax_valid: function() {}, /** - * Must set the focus on the field. + * Must set the focus on the field. Return false if field is not focusable. */ focus: function() {}, }; @@ -1804,6 +1816,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w this.name = this.node.attrs.name; 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.set({'value': false}); this.set({required: this.modifiers['required'] === true}); @@ -1876,7 +1889,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w is_false: function() { return this.get('value') === false; }, - _check_css_flags: function(show_invalid) { + _check_css_flags: function() { if (this.field.translate) { this.$element.find('.oe_field_translate').toggle(!this.field_manager.is_create_mode()); } @@ -2458,15 +2471,16 @@ instance.web.form.CompletionFieldMixin = { return this.orderer.add(dataset.name_search( search_val, new instance.web.CompoundDomain(self.build_domain(), [["id", "not in", blacklist]]), - 'ilike', this.limit + 1)).pipe(function(data) { + 'ilike', this.limit + 1, self.build_context())).pipe(function(data) { self.last_search = data; // possible selections for the m2o var values = _.map(data, function(x) { + x[1] = x[1].split("\n")[0]; return { label: _.str.escapeHTML(x[1]), - value:x[1], - name:x[1], - id:x[0] + value: x[1], + name: x[1], + id: x[0], }; }); @@ -2522,7 +2536,7 @@ instance.web.form.CompletionFieldMixin = { pop.select_element( self.field.relation, { - title: (view === 'search' ? _t("Search: ") : _t("Create: ")) + (this.string || this.name), + title: (view === 'search' ? _t("Search: ") : _t("Create: ")) + this.string, initial_ids: ids ? _.map(ids, function(x) {return x[0]}) : undefined, initial_view: view, disable_multiple_selection: true @@ -2591,7 +2605,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc self.get("value"), self.build_context(), { - title: _t("Open: ") + (self.string || self.name) + title: _t("Open: ") + self.string } ); pop.on_write_completed.add_last(function() { @@ -2720,7 +2734,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc return; } if (! no_recurse) { - var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.view.dataset.get_context()); + var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context()); dataset.name_get([self.get("value")], function(data) { self.display_value["" + self.get("value")] = data[0][1]; self.render_value(true); @@ -2730,11 +2744,12 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc display_string: function(str) { var self = this; if (!this.get("effective_readonly")) { - this.$input.val(str); + this.$input.val(str.split("\n")[0]); } else { + str = _.escape(str).split("\n").join("<br />"); this.$element.find('a') .unbind('click') - .text(str) + .html(str) .click(function () { self.do_action({ type: 'ir.actions.act_window', @@ -2752,7 +2767,9 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc var self = this; if (value_ instanceof Array) { this.display_value = {}; - this.display_value["" + value_[0]] = value_[1]; + if (! this.get_definition_options().always_reload) { + this.display_value["" + value_[0]] = value_[1]; + } value_ = value_[0]; } value_ = value_ || false; @@ -2886,25 +2903,36 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({ view.embedded_view = self.field.views[mode]; } if(view.view_type === "list") { - view.options.selectable = self.multi_selection; - view.options.sortable = false; + _.extend(view.options, { + selectable: self.multi_selection, + sortable: false, + import_enabled: false, + }); if (self.get("effective_readonly")) { - view.options.addable = null; - view.options.deletable = null; - view.options.reorderable = false; + _.extend(view.options, { + addable: null, + deletable: null, + reorderable: false, + }); } } else if (view.view_type === "form") { if (self.get("effective_readonly")) { view.view_type = 'form'; } - view.options.not_interactible_on_create = true; + _.extend(view.options, { + not_interactible_on_create: true, + }); } else if (view.view_type === "kanban") { - view.options.confirm_on_delete = false; + _.extend(view.options, { + confirm_on_delete: false, + }); if (self.get("effective_readonly")) { - view.options.action_buttons = false; - view.options.quick_creatable = false; - view.options.creatable = false; - view.options.read_only_mode = true; + _.extend(view.options, { + action_buttons: false, + quick_creatable: false, + creatable: false, + read_only_mode: true, + }); } } views.push(view); @@ -3117,7 +3145,7 @@ instance.web.form.One2ManyViewManager = instance.web.ViewManager.extend({ var id = self.o2m.dataset.index !== null ? self.o2m.dataset.ids[self.o2m.dataset.index] : null; var pop = new instance.web.form.FormOpenPopup(self.o2m.view); pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(), { - title: _t("Open: ") + self.name, + title: _t("Open: ") + self.o2m.string, create_function: function(data) { return self.o2m.dataset.create(data).then(function(r) { self.o2m.dataset.set_ids(self.o2m.dataset.ids.concat([r.result])); @@ -3174,7 +3202,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ // Otherwise validate internal form return _(form.fields).chain() .invoke(function () { - this._check_css_flag(); + this._check_css_flags(); return this.is_valid(); }) .all(_.identity) @@ -3202,7 +3230,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ pop.select_element( self.o2m.field.relation, { - title: _t("Create: ") + self.name, + title: _t("Create: ") + self.o2m.string, initial_view: "form", alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined, create_function: function(data, callback, error_callback) { @@ -3230,7 +3258,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ var self = this; var pop = new instance.web.form.FormOpenPopup(self.o2m.view); pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(), { - title: _t("Open: ") + self.name, + title: _t("Open: ") + self.o2m.string, write_function: function(id, data) { return self.o2m.dataset.write(id, data, {}, function(r) { self.o2m.reload_current_view(); @@ -3514,6 +3542,7 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({ 'selectable': self.multi_selection, 'sortable': false, 'reorderable': false, + 'import_enabled': false, }); var embedded = (this.field.views || {}).tree; if (embedded) { @@ -3558,7 +3587,7 @@ instance.web.form.Many2ManyListView = instance.web.ListView.extend(/** @lends in pop.select_element( this.model, { - title: _t("Add: ") + this.name + title: _t("Add: ") + this.m2m_field.string }, new instance.web.CompoundDomain(this.m2m_field.build_domain(), ["!", ["id", "in", this.m2m_field.dataset.ids]]), this.m2m_field.build_context() @@ -3578,7 +3607,7 @@ instance.web.form.Many2ManyListView = instance.web.ListView.extend(/** @lends in var self = this; var pop = new instance.web.form.FormOpenPopup(this); pop.show_element(this.dataset.model, id, this.m2m_field.build_context(), { - title: _t("Open: ") + this.name, + title: _t("Open: ") + this.m2m_field.string, readonly: this.getParent().get("effective_readonly") }); pop.on_write_completed.add_last(function() { @@ -3676,7 +3705,7 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend( pop.select_element( this.field.relation, { - title: _t("Add: ") + this.name + title: _t("Add: ") + this.string }, new instance.web.CompoundDomain(this.build_domain(), ["!", ["id", "in", this.dataset.ids]]), this.build_context() @@ -3694,7 +3723,7 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend( var id = self.dataset.ids[self.dataset.index]; var pop = new instance.web.form.FormOpenPopup(self.view); pop.show_element(self.field.relation, id, self.build_context(), { - title: _t("Open: ") + self.name, + title: _t("Open: ") + self.string, write_function: function(id, data, options) { return self.dataset.write(id, data, {}).then(function() { self.reload_content(); @@ -3994,6 +4023,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend _.extend({'deletable': false, 'selectable': !self.options.disable_multiple_selection, 'read_only': true, + 'import_enabled': false, }, self.options.list_view_options || {})); self.view_list.popup = self; self.view_list.appendTo($(".oe_popup_list", self.$element)).pipe(function() { @@ -4354,10 +4384,13 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({ }); instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ - tagName: "span", + template: "FieldStatus", start: function() { this._super(); this.selected_value = null; + if (this.$element.parent().is('header')) { + this.$element.after('<div class="oe_clear"/>'); + } // preview in start only for selection fields, because of the dynamic behavior of many2one fields. if (this.field.type in ['selection']) { this.render_list(); @@ -4469,6 +4502,9 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ elem.css("color", color); } }, + focus: function() { + return false; + }, }); /** diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 015829a0579..7bf9d4ad6bf 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -24,6 +24,8 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi // if true, the view can't be editable, ignoring the view's and the context's // instructions 'read_only': false, + // if true, the 'Import', 'Export', etc... buttons will be shown + 'import_enabled': true, }, /** * Core class for list-type displays. @@ -343,6 +345,8 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi self._limit = (isNaN(val) ? null : val); self.page = 0; self.reload_content(); + }).blur(function() { + $(this).trigger('change'); }) .val(self._limit || 'NaN'); }); @@ -375,11 +379,12 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi } var total = dataset.size(); - this.$pager.toggleClass('oe_list_pager_single_page', (total <= this.limit())); + var limit = this.limit() || total; + this.$pager.toggleClass('oe_list_pager_single_page', (total <= limit)); var spager = '-'; if (total) { - var range_start = this.page * this.limit() + 1; - var range_stop = range_start - 1 + this.limit(); + var range_start = this.page * limit + 1; + var range_stop = range_start - 1 + limit; if (range_stop > total) { range_stop = total; } @@ -1331,6 +1336,11 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we row_data[group.grouped_on] = group; var group_column = _(self.columns).detect(function (column) { return column.id === group.grouped_on; }); + if (! group_column) { + throw new Error(_.str.sprintf( + _t("Grouping on field '%s' is not possible because that field does not appear in the list view."), + group.grouped_on)); + } try { $group_column.html(instance.web.format_cell( row_data, group_column, { diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 8d0493a9753..98df8a0af0d 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -136,7 +136,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ }; } if (action.target === 'new') { - if (this.dialog == null) { + if (this.dialog === null) { this.dialog = new instance.web.Dialog(this, { width: '80%' }); if(on_close) this.dialog.on_close.add(on_close); @@ -144,8 +144,9 @@ instance.web.ActionManager = instance.web.Widget.extend({ this.dialog_viewmanager.destroy(); } this.dialog.dialog_title = action.name; - this.dialog_viewmanager = new instance.web.ViewManagerAction(this, action); + this.dialog_viewmanager = new instance.web.ViewManagerAction(this.dialog, action); this.dialog_viewmanager.appendTo(this.dialog.$element); + this.dialog_viewmanager.$element.addClass("oe_view_manager_" + action.target); this.dialog.open(); } else { this.dialog_stop(); @@ -158,7 +159,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ this.inner_action = action; this.inner_viewmanager = new instance.web.ViewManagerAction(this, action); this.inner_viewmanager.appendTo(this.$element); - this.inner_viewmanager.$element.addClass("oe_view_manager_global"); + this.inner_viewmanager.$element.addClass("oe_view_manager_" + action.target); } }, ir_actions_act_window_close: function (action, on_closed) { diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 02ff528b993..1e954fc9a3a 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -619,7 +619,9 @@ <button type="button" class="oe_button oe_list_add oe_highlight"> <t t-esc="widget.options.addable"/> </button> - <span class="oe_fade">or</span> <a href="#" class="oe_bold oe_list_button_import">Import</a> + <t t-if="widget.options.import_enabled"> + <span class="oe_fade">or</span> <a href="#" class="oe_bold oe_list_button_import">Import</a> + </t> </t> </div> <t t-name="ListView.pager"> @@ -665,7 +667,7 @@ <t t-name="ListView.row.save"> <td> - <button class='oe_i oe_list_edit_row_save' type='button' name='save'>S</button> + <button class='oe_i oe_list_edit_row_save' type='button' name='save'/> </td> </t> @@ -684,7 +686,7 @@ <button type="button" class="oe_button oe_form_button_create">Create</button> </span> <span class="oe_form_buttons_edit"> - <button type="button" class="oe_button oe_form_button_save oe_highlight_on_dirty">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">Save</button> <span class="oe_fade">or</span> <a href="#" class="oe_bold oe_form_button_cancel">Discard</a> </span> </t> </div> @@ -874,7 +876,7 @@ </t> <t t-name="FieldEmail"> <span class="oe_form_field oe_form_field_email oe_form_field_with_button"> - <a t-if="widget.get('effective_readonly')" href="#" class="oe_form_uri"/> + <a t-if="widget.get('effective_readonly')" href="#" class="oe_form_uri" target="_blank"/> <t t-if="!widget.get('effective_readonly')"> <div> <input type="text" @@ -1006,17 +1008,17 @@ <span></span> </span> </t> +<t t-name="FieldStatus"> + <ul class="oe_form_steps"/> +</t> <t t-name="FieldStatus.content"> - <ul class="oe_form_steps"> - <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' : ''"> - <span><t t-esc="widget.to_show[i][1]"/></span> - <img t-att-src='_s + "/web/static/src/img/form_steps.png"' class="oe_form_steps_arrow" t-if="i < size - 1"/> - </li> - </t> - </ul> - <div class="oe_clear"/> + <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' : ''"> + <span><t t-esc="widget.to_show[i][1]"/></span> + <img t-att-src='_s + "/web/static/src/img/form_steps.png"' class="oe_form_steps_arrow" t-if="i < size - 1"/> + </li> + </t> </t> <t t-name="FieldBinaryImage"> <span class="oe_form_field oe_form_field_image"> @@ -1202,7 +1204,7 @@ <div t-name="SearchView" class="oe_searchview"> <div class="oe_searchview_facets"/> <div class="oe_searchview_clear"/> - <div class="oe_searchview_unfold_drawer"/> + <div class="oe_searchview_unfold_drawer" title="Advanced Search..."/> <div class="oe_searchview_drawer"/> </div> |
