diff options
| author | Géry Debongnie <ged@odoo.com> | 2014-08-20 17:02:16 +0200 |
|---|---|---|
| committer | Géry Debongnie <ged@odoo.com> | 2014-10-21 09:33:49 +0200 |
| commit | 582ccb5ab9061bcc3cd4d1511ca6c5c1d20a6adc (patch) | |
| tree | b4cb915752c3d280fcb3798d24b3af52acb7ca7d /addons/web/static/src | |
| parent | e8290470154881cf7f77aedda353048fa4acd0af (diff) | |
[IMP] web client refactoring: action and view manager
large rewrite of action manager, view manager and
viewmanageraction. The goal is to lay the foundation
for the redesign of the advanced search view.
This commit includes:
* improvements to the display order (no/less flickering)
* large simplification of the breadcrumbs code
* much better html layout for the header (no table)
* bootstrapisation of the view manager
* lots of optimizations/simplification
* a base.css.map, courtesy of the last sass version
Diffstat (limited to 'addons/web/static/src')
| -rw-r--r-- | addons/web/static/src/css/base.css | 343 | ||||
| -rw-r--r-- | addons/web/static/src/css/base.sass | 131 | ||||
| -rw-r--r-- | addons/web/static/src/js/search.js | 6 | ||||
| -rw-r--r-- | addons/web/static/src/js/views.js | 1027 | ||||
| -rw-r--r-- | addons/web/static/src/xml/base.xml | 117 |
5 files changed, 643 insertions, 981 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 23fb4ed2f09..41d1f35bd0c 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -161,16 +161,16 @@ } .openerp .zebra tbody tr:hover td { background-color: #e6e6e6; - background-image: -webkit-gradient(linear, left top, left bottom, from(#eeeeee), to(#dedede)); - background-image: -webkit-linear-gradient(top, #eeeeee, #dedede); - background-image: -moz-linear-gradient(top, #eeeeee, #dedede); - background-image: -ms-linear-gradient(top, #eeeeee, #dedede); - background-image: -o-linear-gradient(top, #eeeeee, #dedede); - background-image: linear-gradient(to bottom, #eeeeee, #dedede); + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#dedede)); + background-image: -webkit-linear-gradient(top, #eee, #dedede); + background-image: -moz-linear-gradient(top, #eee, #dedede); + background-image: -ms-linear-gradient(top, #eee, #dedede); + background-image: -o-linear-gradient(top, #eee, #dedede); + background-image: linear-gradient(to bottom, #eee, #dedede); } .openerp input, .openerp textarea, .openerp select { padding: 2px 4px; - border: 1px solid #cccccc; + border: 1px solid #ccc; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; @@ -184,7 +184,7 @@ font-weight: bold; font-size: inherit; } -.openerp a.button:link, .openerp a.button:visited, .openerp button, .openerp .oe_button, .openerp input[type='submit'] { +.openerp a.button:link, .openerp a.button:visited, .openerp .oe_button, .openerp input[type='submit'] { display: inline-block; border: 1px solid rgba(0, 0, 0, 0.4); color: #4c4c4c; @@ -209,7 +209,7 @@ -webkit-font-smoothing: antialiased; outline: none; } -.openerp a.button:hover, .openerp button:hover, .openerp .oe_button:hover, .openerp input[type='submit']:hover { +.openerp a.button:hover, .openerp .oe_button:hover, .openerp input[type='submit']:hover { background-color: #ececec; background-image: -webkit-gradient(linear, left top, left bottom, from(#f6f6f6), to(#e3e3e3)); background-image: -webkit-linear-gradient(top, #f6f6f6, #e3e3e3); @@ -220,7 +220,7 @@ cursor: pointer; background-position: 0; } -.openerp a.button:focus, .openerp button:focus, .openerp .oe_button:focus, .openerp input[type='submit']:focus { +.openerp a.button:focus, .openerp .oe_button:focus, .openerp input[type='submit']:focus { border: 1px solid #80bfff; background-position: 0; background-color: #ececec; @@ -234,7 +234,7 @@ -webkit-box-shadow: 0 0 3px #80bfff, 0 1px 1px rgba(255, 255, 255, 0.8) inset; box-shadow: 0 0 3px #80bfff, 0 1px 1px rgba(255, 255, 255, 0.8) inset; } -.openerp a.button:active, .openerp a.button.active, .openerp button:active, .openerp .oe_button:active, .openerp .oe_button.active, .openerp input[type='submit']:active, .openerp input[type='submit'].active { +.openerp a.button:active, .openerp a.button.active, .openerp .oe_button:active, .openerp .oe_button.active, .openerp input[type='submit']:active, .openerp input[type='submit'].active { background-color: #ececec; background-image: -webkit-gradient(linear, left top, left bottom, from(#e3e3e3), to(#f6f6f6)); background-image: -webkit-linear-gradient(top, #e3e3e3, #f6f6f6); @@ -246,18 +246,18 @@ -webkit-box-shadow: none; box-shadow: none; } -.openerp a.button.disabled, .openerp button:disabled, .openerp .oe_button:disabled, .openerp input[type='submit']:disabled { +.openerp a.button.disabled, .openerp .oe_button:disabled, .openerp input[type='submit']:disabled { background: #efefef !important; border: 1px solid #d1d1d1 !important; -moz-box-shadow: none !important; -webkit-box-shadow: none !important; box-shadow: none !important; - color: #aaaaaa !important; + color: #aaa !important; cursor: default; - text-shadow: 0 1px 1px white !important; + text-shadow: 0 1px 1px #fff !important; } .openerp .ui-widget-content a { - color: #7c7bad; + color: #7C7BAD; } .openerp .oe_bounce_container { display: inline-block; @@ -305,7 +305,7 @@ cursor: wait; } .openerp .oe_fade { - color: #888888; + color: #888; font-weight: normal; } .openerp .oe_bold { @@ -316,7 +316,7 @@ } .openerp .oe_highlight { color: white; - background: #dc5f59; + background: #DC5F59; } .openerp button.oe_highlight { background-color: #c02c2c; @@ -349,7 +349,7 @@ background-image: linear-gradient(to bottom, #c52020, #d22323); } .openerp .oe_background_grey { - background: #eeeeee !important; + background: #eee !important; } .openerp .oe_form_dirty .oe_highlight_on_dirty { color: white; @@ -369,7 +369,7 @@ box-shadow: none; } .openerp .oe_form_dirty button.oe_highlight_on_dirty:hover { - background: #ed6f6a; + background: #ED6F6A; } .openerp .oe_warning_redirect { border: none !important; @@ -385,7 +385,7 @@ font-weight: normal; width: 132px !important; height: 40px; - color: #666666; + color: #666; margin: 0px -1px -1px 0px; padding: 0; border: 1px solid #dddddd; @@ -401,7 +401,7 @@ line-height: 120%; } .openerp .oe_stat_button .stat_button_icon { - color: #7c7bad; + color: #7C7BAD; font-size: 24px; padding: 0px 3px; width: 37px; @@ -482,7 +482,7 @@ -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; - color: #7c7bad; + color: #7C7BAD; font-weight: bold; } .openerp .oe_button.oe_link span:hover { @@ -505,7 +505,7 @@ max-width: 650px; } .openerp .oe_grey { - color: #aaaaaa; + color: #aaa; } .openerp .oe_error_detail hr { display: block; @@ -525,10 +525,10 @@ -webkit-border-radius: 6px; border-radius: 6px; background-position: center center; - background-image: -webkit-radial-gradient(circle, #eeeeee 0%, #cccccc 40%, #bbbbbb 100%); - background-image: -moz-radial-gradient(#eeeeee 0%, #cccccc 40%, #bbbbbb 100%); - background-image: -ms-radial-gradient(#eeeeee 0%, #cccccc 40%, #bbbbbb 100%); - background-image: radial-gradient(circle, #eeeeee 0%, #cccccc 40%, #bbbbbb 100%); + background-image: -webkit-radial-gradient(circle, #eee 0%, #ccc 40%, #bbb 100%); + background-image: -moz-radial-gradient(#eee 0%, #ccc 40%, #bbb 100%); + background-image: -ms-radial-gradient(#eee 0%, #ccc 40%, #bbb 100%); + background-image: radial-gradient(circle, #eee 0%, #ccc 40%, #bbb 100%); } .openerp .oe_kanban_status_green { background: green; @@ -562,11 +562,11 @@ -webkit-border-radius: 3px; border-radius: 3px; background: #f0f0fa; - color: #4c4c4c; + color: #4C4C4C; } .openerp .oe_tag_dark { - background: #7c7bad; - color: #eeeeee; + background: #7C7BAD; + color: #eee; } .openerp .oe_form_field_radio.oe_horizontal { white-space: nowrap; @@ -636,13 +636,13 @@ } .openerp .oe_notebook > li > a { display: block; - color: gray; + color: #808080; } .openerp .oe_notebook > li.ui-tabs-active > a { color: #4c4c4c; } .openerp .oe_notebook { - border-color: #dddddd; + border-color: #ddd; border-style: solid; border-width: 0 0 1px; } @@ -660,16 +660,16 @@ } .openerp .oe_notebook > li > a:hover { text-decoration: none; - background-color: #eeeeee; - border-color: #eeeeee #eeeeee #dddddd; + background-color: #eee; + border-color: #eee #eee #ddd; } .openerp .ui-tabs .oe_notebook.ui-tabs-nav li.ui-tabs-active { border-bottom: none; padding-bottom: 1px; } .openerp .oe_notebook > li.ui-state-active > a, .openerp .oe_notebook > li.ui-state-active > a:hover { - background-color: white; - border: 1px solid #dddddd; + background-color: #ffffff; + border: 1px solid #ddd; border-bottom-color: transparent; cursor: default; } @@ -690,7 +690,7 @@ cursor: pointer; } .openerp .oe_dropdown_toggle { - color: #2b2b2b; + color: #2B2B2B; font-weight: normal; } .openerp .oe_dropdown_hover:hover .oe_dropdown_menu, .openerp .oe_dropdown_menu.oe_opened { @@ -812,10 +812,10 @@ top: 0; right: 50%; padding: 4px 12px; - background: #a61300; + background: #A61300; color: white; text-align: center; - border: 1px solid #990000; + border: 1px solid #900; border-top: none; -moz-border-radius-bottomright: 8px; -moz-border-radius-bottomleft: 8px; @@ -833,12 +833,12 @@ width: 32px; } .openerp .oe_database_manager { - background: white; - color: black; + background: #fff; + color: #000; text-align: left; } .openerp .oe_database_manager .oe_database_manager_menu { - color: black; + color: #000; } .openerp .oe_webclient { width: 100%; @@ -881,7 +881,7 @@ width: 100%; display: none; text-align: center; - color: #eeeeee; + color: #eee; background: rgba(37, 37, 37, 0.9); -webkit-box-sizing: border-box; -moz-box-sizing: border-box; @@ -923,7 +923,7 @@ .openerp .oe_secondary_menu_section { font-weight: bold; margin-left: 8px; - color: #7c7bad; + color: #7C7BAD; } .openerp .oe_secondary_submenu { margin-bottom: 10px !important; @@ -1003,7 +1003,7 @@ } .openerp .oe_about .user-details .user-info-block .navigation li.active a { background: #a24689; - color: white; + color: #fff; } .openerp .oe_about .user-details .user-info-block .user-body { text-align: center; @@ -1027,10 +1027,10 @@ transform: scale(1.3); } .openerp .oe_about #social .social-fb:hover { - color: #3b5998; + color: #3B5998; } .openerp .oe_about #social .social-tw:hover { - color: #4099ff; + color: #4099FF; } .openerp .oe_about #social .social-gp:hover { color: #d34836; @@ -1045,8 +1045,11 @@ width: 100%; height: 100%; } -.openerp .oe_application a { - color: #7c7bad; +.openerp .oe_application .oe-view-manager-body a { + color: #7C7BAD; +} +.openerp .oe_application .oe-view-manager-body .oe-view-manager-view-kanban:not(:empty) { + height: 100%; } .openerp .oe_application > div { position: relative; @@ -1079,6 +1082,63 @@ overflow: hidden; font-weight: bold; } +.openerp .oe-view-manager-header { + height: 90px; + overflow: hidden; + border-bottom: 1px solid black; + display: none; +} +.openerp .oe-view-manager-header .row { + height: 45px; +} +.openerp .oe-view-manager-header .oe-view-title { + float: left; + font-size: 18px; + font-weight: bold; + margin: 0; +} +.openerp .oe-view-manager-header .oe-header-title { + padding-left: 0; +} +.openerp .oe-view-manager-header .oe-view-manager-search-view { + float: right; + padding-top: 5px; +} +.openerp .oe-view-manager-header .oe-view-manager-switch { + float: right; +} +.openerp .oe-view-manager-header .oe-view-manager-switch .oe-vm-switch-kanban:before { + content: ""; +} +.openerp .oe-view-manager-header .oe-view-manager-switch .oe-vm-switch-list:before { + content: ""; +} +.openerp .oe-view-manager-header .oe-view-manager-switch .oe-vm-switch-form:before { + content: ""; +} +.openerp .oe-view-manager-header .oe-view-manager-switch .oe-vm-switch-graph:before { + content: ""; +} +.openerp .oe-view-manager-header .oe-view-manager-switch .oe-vm-switch-calendar:before { + content: ""; +} +.openerp .oe-view-manager-header .oe-view-manager-switch .oe-vm-switch-gantt:before { + content: ""; +} +.openerp .oe-view-manager-header .oe-view-manager-buttons { + float: left; +} +.openerp .oe-view-manager-header .oe-view-manager-buttons > div { + display: none; +} +.openerp .oe_application > div > div > .oe-view-manager-body { + position: absolute; + top: 90px; + bottom: 0; + left: 0; + right: 0; + overflow: auto; +} .openerp .oe_view_manager { display: table; height: inherit; @@ -1122,7 +1182,7 @@ line-height: 30px; } .openerp .oe_view_manager table.oe_view_manager_header h2 a { - color: #7c7bad; + color: #7C7BAD; } .openerp .oe_view_manager table.oe_view_manager_header .oe_dropdown_menu { line-height: normal; @@ -1148,13 +1208,13 @@ text-decoration: none; } .openerp .oe_view_manager table.oe_view_manager_header .oe_button_group .active { - background: #999999; + background: #999; -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3) inset; -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3) inset; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3) inset; } .openerp .oe_view_manager table.oe_view_manager_header .oe_button_group .active a { - color: white; + color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); } .openerp .oe_view_manager table.oe_view_manager_header .oe_view_manager_buttons { @@ -1250,40 +1310,18 @@ text-decoration: none; } .openerp .oe_pager_group .active { - background: #999999; + background: #999; -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3) inset; -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3) inset; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3) inset; } .openerp .oe_pager_group .active a { - color: white; + color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); } .openerp .oe_list_pager.oe_list_pager_single_page .oe_pager_group { display: none; } -.openerp .oe_view_manager_current { - height: 100%; -} -.openerp .oe_view_manager_current > .oe_view_manager_header { - border-bottom: 1px solid #cacaca; - background-color: #ededed; - 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); - -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 9px rgba(0, 0, 0, 0.1); - -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_current > .oe_view_manager_header .oe_header_row td { - padding: 8px; -} -.openerp .oe_view_manager_current > .oe_view_manager_header .oe_header_row:first-child td { - padding-top: 8px; -} .openerp .oe_view_manager_inline, .openerp .oe_view_manager_inlineview { height: 100%; } @@ -1305,18 +1343,12 @@ .openerp .oe_searchview { cursor: text; position: relative; - float: right; padding: 1px 0; - line-height: 18px; min-width: 400px; - border: 1px solid #ababab; - background: white; + width: 400px; -moz-border-radius: 13px; -webkit-border-radius: 13px; border-radius: 13px; - -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) inset; - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) inset; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) inset; } .openerp .oe_searchview input, .openerp .oe_searchview textarea { padding: 3px; @@ -1343,73 +1375,44 @@ .openerp .oe_searchview .oe_searchview_clear { cursor: pointer; position: absolute; - top: 0; + top: 3px; right: 18px; width: 15px; height: 24px; - background: url(../img/search_reset.gif) center center no-repeat; } .openerp .oe_searchview .oe_searchview_unfold_drawer { position: absolute; top: 0; right: 0; - height: 24px; - padding: 0 7px 0 4px; - color: #cccccc; + color: #ccc; cursor: pointer; } .openerp .oe_searchview .oe_searchview_unfold_drawer:hover { - color: #999999; + color: #999; } .openerp .oe_searchview .oe_searchview_unfold_drawer:before { position: absolute; - top: 10px; - right: 7px; + top: 7px; + right: 18px; width: 0; - height: 0; - display: inline-block; - content: ""; - vertical-align: top; - border-top: 5px solid #4c4c4c; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - filter: alpha(opacity=50); - opacity: 0.5; } .openerp .oe_searchview .oe_searchview_search { - font-size: 1px; - letter-spacing: -1px; - color: transparent; - text-shadow: none; - font-weight: normal; - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; - -moz-border-radius: 0; - -webkit-border-radius: 0; - border-radius: 0; + cursor: pointer; position: absolute; - left: 3px; - top: 1px; - padding: 0; - border: none; - background: transparent; -} -.openerp .oe_searchview .oe_searchview_search:before { - font: 21px "mnmliconsRegular"; - content: "r"; - color: #a3a3a3; + left: 6px; + top: 8px; } .openerp .oe_searchview .oe_searchview_facets { min-height: 22px; - margin: 0 35px 0 15px; + margin: 2px 35px 0 20px; } .openerp .oe_searchview .oe_searchview_facets * { vertical-align: top; display: inline-block; - line-height: 17px; + font-size: 100%; } .openerp .oe_searchview .oe_searchview_facets .oe_searchview_facet { + height: 20px; margin: 1px 0; font-size: 11px; } @@ -1431,6 +1434,9 @@ padding: 0; -webkit-font-smoothing: auto; } +.openerp .oe_searchview .oe_searchview_facets .oe_searchview_facet span { + height: 18px; +} .openerp .oe_searchview .oe_searchview_facets .oe_searchview_facet:focus { border-color: #a6a6fe; -moz-box-shadow: 0 0 3px 1px #a6a6fe; @@ -1439,9 +1445,6 @@ } .openerp .oe_searchview .oe_searchview_facets .oe_searchview_facet .oe_facet_values { background: #f0f0fa; - -moz-border-radius: 0 3px 3px 0; - -webkit-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; } .openerp .oe_searchview .oe_searchview_facets .oe_searchview_facet .oe_facet_category, .openerp .oe_searchview .oe_searchview_facets .oe_searchview_facet .oe_facet_value { padding: 0 4px; @@ -1454,9 +1457,7 @@ font-size: 16px; } .openerp .oe_searchview .oe_searchview_facets .oe_searchview_facet .oe_facet_value { - border-left: 1px solid #afafb6; - text-shadow: 0 1px 1px white; - color: #4c4c4c; + color: #4C4C4C; } .openerp .oe_searchview .oe_searchview_facets .oe_searchview_facet .oe_facet_value:last-child { padding-right: 16px; @@ -1560,7 +1561,7 @@ margin-bottom: 0; } .openerp .oe_searchview_drawer dt { - color: #7c7bad; + color: #7C7BAD; font-size: 13px; line-height: 24px; } @@ -1783,8 +1784,8 @@ display: inline-block; } .openerp .oe_form_invalid input, .openerp .oe_form_invalid select, .openerp .oe_form_invalid textarea { - background-color: #ff6666 !important; - border: 1px solid #dd0000 !important; + background-color: #F66 !important; + border: 1px solid #D00 !important; } .openerp .oe_view_manager_current .oe_form_editable .oe_highlight { color: #404040; @@ -1878,7 +1879,7 @@ } .openerp .oe_application .oe_form_sheetbg { background: url(/web/static/src/img/form_sheetbg.png); - border-bottom: 1px solid #dddddd; + border-bottom: 1px solid #ddd; } .openerp .oe_application .oe_form_sheetbg .oe_subtotal_footer label { font-weight: bold; @@ -1938,7 +1939,7 @@ padding: 16px 16px 48px; } .openerp .oe_form div.oe_form_configuration p, .openerp .oe_form div.oe_form_configuration ul, .openerp .oe_form div.oe_form_configuration ol { - color: #aaaaaa; + color: #aaa; max-width: 650px; } .openerp .oe_form div.oe_form_configuration label { @@ -1979,8 +1980,8 @@ font-weight: normal !important; } .openerp .oe_form .oe_form_box_info { - background: #ffee99; - border-bottom: 1px solid #ccbb66; + background: #fe9; + border-bottom: 1px solid #cb6; padding: 4px; } .openerp .oe_form .oe_form_box_info > p { @@ -1988,7 +1989,7 @@ } .openerp .oe_form .oe_form_box_warning { background: #bd362f; - border-bottom: 1px solid #990000; + border-bottom: 1px solid #900; padding: 4px; } .openerp .oe_form .oe_form_box_warning * { @@ -2002,7 +2003,7 @@ margin: 2px; } .openerp .oe_form td.oe_form_group_cell_label { - border-right: 1px solid #dddddd; + border-right: 1px solid #ddd; padding: 2px 0px; } .openerp .oe_form td.oe_form_group_cell_label label { @@ -2027,7 +2028,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; @@ -2040,13 +2041,13 @@ font-weight: bold; font-size: 20px; margin: 15px 0px 10px 0px; - color: #7c7bad; + color: #7C7BAD; } .openerp .oe_horizontal_separator:empty { height: 5px; } .openerp .oe_vertical_separator { - border-left: 1px solid #666666; + border-left: 1px solid #666; padding: 0 4px 0 4px; } .openerp .oe_form_field_progressbar { @@ -2060,7 +2061,7 @@ -moz-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box; - border: 1px solid #999999; + border: 1px solid #999; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; @@ -2141,8 +2142,8 @@ font-family: "Lucida Grande", Helvetica, Verdana, Arial, sans-serif; } .openerp .oe_form input[readonly], .openerp .oe_form select[readonly], .openerp .oe_form textarea[readonly], .openerp .oe_form input[disabled], .openerp .oe_form select[disabled] { - background: #e5e5e5 !important; - color: #666666; + background: #E5E5E5 !important; + color: #666; } .openerp .oe_form textarea[disabled] { border: none; @@ -2156,7 +2157,7 @@ color: #4c4c4c; } .openerp .oe_form textarea.oe_inline[disabled] { - border-left: 8px solid #eeeeee; + border-left: 8px solid #eee; } .openerp .oe_form .oe_form_field_url button img { vertical-align: top; @@ -2173,11 +2174,11 @@ display: inline-block; } .openerp .oe_form .oe_form_required input:not([disabled]):not([readonly]), .openerp .oe_form .oe_form_required select:not([disabled]):not([readonly]), .openerp .oe_form .oe_form_required textarea:not([disabled]):not([readonly]) { - background-color: #d2d2ff !important; + background-color: #D2D2FF !important; } .openerp .oe_form .oe_form_invalid input, .openerp .oe_form .oe_form_invalid select, .openerp .oe_form .oe_form_invalid textarea { - background-color: #ff6666 !important; - border: 1px solid #dd0000 !important; + background-color: #F66 !important; + border: 1px solid #D00 !important; } .openerp .oe_form .oe_input_icon { cursor: pointer; @@ -2267,7 +2268,7 @@ width: 100%; display: none; text-align: center; - color: #eeeeee; + color: #eee; background: rgba(37, 37, 37, 0.9); -moz-border-radius: 3px 3px 0 0; -webkit-border-radius: 3px 3px 0 0; @@ -2304,7 +2305,7 @@ .openerp .oe_fileupload .oe_add button.oe_attach { width: 24px; background: transparent; - color: #7c7bad; + color: #7C7BAD; box-shadow: none; border: none; text-shadow: none; @@ -2323,7 +2324,7 @@ cursor: pointer; } .openerp .oe_fileupload .oe_add .oe_attach_label { - color: #7c7bad; + color: #7C7BAD; margin-left: -3px; } .openerp .oe_fileupload .oe_attachments { @@ -2349,7 +2350,7 @@ background: white; } .openerp .oe_fileupload .oe_attachments .oe_attachment:nth-child(even) { - background: #f4f5fa; + background: #F4F5FA; } .openerp .oe_form_field_many2one { display: inline-block; @@ -2510,7 +2511,7 @@ background-image: linear-gradient(to bottom, #e8e8e8, #cacaca); } .openerp ul.oe_form_status_clickable li > .label { - color: #7c7bad; + color: #7C7BAD; } .openerp ul.oe_form_status_clickable li.oe_active:hover { background-color: #3a699f; @@ -2580,7 +2581,7 @@ background-color: #d2d2ff; } .openerp .oe_form_editable .oe_list_editable .oe_list_content td.oe_readonly { - background-color: #eeeeee; + background-color: #eee; } .openerp .oe_list_editable .oe_list_content td.oe_list_field_cell { padding: 4px 6px 3px; @@ -2617,7 +2618,7 @@ -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; - border: 1px solid #aaaaff; + border: 1px solid #aaf; margin: 0; } .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field input, .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field textarea, .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field select { @@ -2709,7 +2710,7 @@ } .openerp .oe_list_content > thead { border-bottom: 2px solid #cacaca; - background: #eeeeee; + background: #eee; vertical-align: top; } .openerp .oe_list_content td, .openerp .oe_list_content th { @@ -2728,7 +2729,7 @@ margin-top: 7px; border-width: 0 4px 4px; border-style: solid; - border-color: black transparent; + border-color: #000 transparent; visibility: hidden; } .openerp .oe_list_content th.sortup div:after { @@ -2745,7 +2746,7 @@ border-bottom: none; border-left: 4px solid transparent; border-right: 4px solid transparent; - border-top: 4px solid black; + border-top: 4px solid #000; visibility: visible; -moz-box-shadow: none; -webkit-box-shadow: none; @@ -2758,7 +2759,7 @@ } .openerp .oe_list_content > tbody > tr { height: 27px; - border-top: 1px solid #dddddd; + border-top: 1px solid #ddd; } .openerp .oe_list_content > tbody > tr > td.oe_list_field_cell { padding: 3px 6px; @@ -2797,7 +2798,7 @@ .openerp .oe_list_content > tfoot { border-top: 2px solid #cacaca; border-bottom: 1px solid #cacaca; - background: #eeeeee; + background: #eee; font-weight: bold; } .openerp .oe_list_content .numeric { @@ -2828,7 +2829,7 @@ .openerp .oe_list_content td.oe_list_field_handle .oe_list_handle:before { font: 18px "entypoRegular"; content: "}"; - color: #e0e0e0; + color: #E0E0E0; } .openerp .oe_list_content .oe_list_field_progressbar progress { width: 100%; @@ -2990,7 +2991,7 @@ -webkit-margin-end: 0px; } .openerp pre { - background-color: white; + background-color: #FFFFFF; border: none; padding: 10px 0 3px 0; } @@ -3035,9 +3036,9 @@ -moz-border-radius: 15px; -webkit-border-radius: 15px; border-radius: 15px; - -moz-box-shadow: 0 0 5px 5px #999999; - -webkit-box-shadow: 0 0 5px 5px #999999; - box-shadow: 0 0 5px 5px #999999; + -moz-box-shadow: 0 0 5px 5px #999; + -webkit-box-shadow: 0 0 5px 5px #999; + box-shadow: 0 0 5px 5px #999; } div.ui-widget-overlay { @@ -3076,7 +3077,7 @@ div.ui-widget-overlay { background: #f0f0fa; } .ui-menu .ui-menu-item a.ui-state-hover, .ui-menu .ui-menu-item a.ui-state-active { - background: #7c7bad; + background: #7C7BAD; } .ui-corner-all { @@ -3090,7 +3091,7 @@ div.ui-widget-overlay { } body.oe_single_form { - background: #eeeeee url(/web/static/src/img/form_sheetbg.png); + background: #eee url(/web/static/src/img/form_sheetbg.png); height: 100%; } body.oe_single_form .oe_single_form_logo { @@ -3124,7 +3125,7 @@ body.oe_single_form .oe_single_form_container { width: 80px; } .openerp_ie .oe_form_field_boolean input { - background: white; + background: #fff; } .openerp_ie .db_option_table .oe_form_field_selection { width: auto; @@ -3315,7 +3316,7 @@ body.oe_single_form .oe_single_form_container { max-width: 350px; } .tooltip .tooltip-inner .oe_tooltip_string { - color: #ffdd55; + color: #FD5; font-weight: bold; font-size: 13px; } @@ -3339,7 +3340,7 @@ body.oe_single_form .oe_single_form_container { color: white; } .tooltip .tooltip-inner .oe_tooltip_close:hover { - color: #999999; + color: #999; cursor: pointer; } .tooltip .tooltip-inner .oe_tooltip_message { @@ -3414,7 +3415,7 @@ div.tour-backdrop { bottom: 0; left: 0; z-index: 1100; - background-color: black; + background-color: #000; opacity: 0.8; } diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index a8efd0f29cb..5aeaccf07aa 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -267,7 +267,7 @@ $sheet-padding: 16px font-size: inherit // }}} // Button style {{{ - a.button:link, a.button:visited, button, .oe_button, input[type='submit'] + a.button:link, a.button:visited, .oe_button, input[type='submit'] display: inline-block border: 1px solid rgba(0,0,0,0.4) color: #4c4c4c @@ -282,22 +282,22 @@ $sheet-padding: 16px -webkit-font-smoothing: antialiased outline: none - a.button:hover, button:hover,.oe_button:hover, input[type='submit']:hover + a.button:hover,.oe_button:hover, input[type='submit']:hover @include vertical-gradient(#f6f6f6, #e3e3e3) cursor: pointer background-position: 0 - a.button:focus, button:focus, .oe_button:focus, input[type='submit']:focus + a.button:focus, .oe_button:focus, input[type='submit']:focus border: 1px solid #80bfff background-position: 0 @include vertical-gradient(#f6f6f6, #e3e3e3) @include box-shadow((0 0 3px #80bfff, 0 1px 1px rgba(255, 255, 255, .8) inset)) - a.button:active, a.button.active, button:active, .oe_button:active, .oe_button.active, input[type='submit']:active, input[type='submit'].active + a.button:active, a.button.active, .oe_button:active, .oe_button.active, input[type='submit']:active, input[type='submit'].active @include vertical-gradient(#e3e3e3, #f6f6f6) @include box-shadow(none) - a.button.disabled, button:disabled, .oe_button:disabled, input[type='submit']:disabled + a.button.disabled, .oe_button:disabled, input[type='submit']:disabled background: #efefef !important border: 1px solid #d1d1d1 !important @include box-shadow(none !important) @@ -899,8 +899,11 @@ $sheet-padding: 16px .oe_application width: 100% height: 100% - a - color: $link-color + .oe-view-manager-body + a + color: $link-color + .oe-view-manager-view-kanban:not(:empty) + height: 100% > div position: relative height: 100% @@ -931,6 +934,52 @@ $sheet-padding: 16px font-weight: bold // }}} // ViewManager common {{{ + .oe-view-manager-header + height: 90px + overflow: hidden + border-bottom: 1px solid black + display: none + .row + height: 45px + .oe-view-title + float: left + font-size: 18px + font-weight: bold + margin: 0 + .oe-header-title + padding-left: 0 + .oe-view-manager-search-view + float: right + padding-top: 5px + .oe-view-manager-switch + float: right + .oe-vm-switch-kanban:before + content: "\f009" + .oe-vm-switch-list:before + content: "\f0c9" + .oe-vm-switch-form:before + content: "\f044" + .oe-vm-switch-graph:before + content: "\f080" + .oe-vm-switch-calendar:before + content: "\f073" + .oe-vm-switch-gantt:before + content: "\f0ae" + .oe-view-manager-buttons + float: left + > div + display: none + + .oe_application + > div + > div + > .oe-view-manager-body + position: absolute + top: 90px + bottom: 0 + left: 0 + right: 0 + overflow: auto .oe_view_manager display: table height: inherit @@ -1076,18 +1125,18 @@ $sheet-padding: 16px display: none // }}} // ViewManager application {{{ - .oe_view_manager_current - height: 100% - > .oe_view_manager_header - border-bottom: 1px solid #cacaca - @include vertical-gradient(#fcfcfc, #dedede) - @include box-shadow((0 1px 0 rgba(255,255,255,0.4), 0 0 9px rgba(0,0,0,0.1))) - .oe_header_row - td - padding: 8px - .oe_header_row:first-child - td - padding-top: 8px + // .oe_view_manager_current + // height: 100% + // > .oe_view_manager_header + // border-bottom: 1px solid #cacaca + // @include vertical-gradient(#fcfcfc, #dedede) + // @include box-shadow((0 1px 0 rgba(255,255,255,0.4), 0 0 9px rgba(0,0,0,0.1))) + // .oe_header_row + // td + // padding: 8px + // .oe_header_row:first-child + // td + // padding-top: 8px // }}} // ViewManager inline {{{ .oe_view_manager_inline, .oe_view_manager_inlineview @@ -1111,14 +1160,10 @@ $sheet-padding: 16px .oe_searchview cursor: text position: relative - float: right padding: 1px 0 - line-height: 18px min-width: 400px - border: 1px solid #ababab - background: white + width: 400px @include radius(13px) - @include box-shadow(0 1px 2px rgba(0,0,0,0.2) inset) input, textarea padding: 3px height: 14px @@ -1139,54 +1184,39 @@ $sheet-padding: 16px .oe_searchview_clear cursor: pointer position: absolute - top: 0 + top: 3px right: 18px width: 15px height: 24px - background: url(../img/search_reset.gif) center center no-repeat .oe_searchview_unfold_drawer position: absolute top: 0 right: 0 - height: 24px - padding: 0 7px 0 4px color: #ccc cursor: pointer &:hover color: #999 &:before position: absolute - top: 10px - right: 7px + top: 7px + right: 18px width: 0 - height: 0 - display: inline-block - content: "" - vertical-align: top - border-top: 5px solid #4C4C4C - border-left: 5px solid transparent - border-right: 5px solid transparent - @include opacity() .oe_searchview_search - @include text-to-icon("r", #a3a3a3) - @include box-shadow(none) - @include radius(0) + cursor: pointer position: absolute - left: 3px - top: 1px - padding: 0 - border: none - background: transparent + left: 6px + top: 8px .oe_searchview_facets min-height: 22px - margin: 0 35px 0 15px + margin: 2px 35px 0 20px * vertical-align: top display: inline-block - line-height: 17px + font-size: 100% .oe_searchview_facet + height: 20px margin: 1px 0 font-size: 11px &:focus @@ -1204,12 +1234,13 @@ $sheet-padding: 16px padding: 0 -webkit-font-smoothing: auto // spacing for opera, FF + span + height: 18px &:focus border-color: $tag-border-selected @include box-shadow(0 0 3px 1px $tag-border-selected) .oe_facet_values background: $tag-bg-light - @include radius(0 3px 3px 0) .oe_facet_category, .oe_facet_value padding: 0 4px .oe_facet_category @@ -1218,8 +1249,6 @@ $sheet-padding: 16px .oe_facet_category.oe_i font-size: 16px .oe_facet_value - border-left: 1px solid $tag-border - text-shadow: 0 1px 1px white color: #4C4C4C &:last-child padding-right: 16px diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index f14b8c010f1..e28b1185357 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -330,7 +330,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea } }, // search button - 'click button.oe_searchview_search': function (e) { + 'click i.oe_searchview_search': function (e) { e.stopImmediatePropagation(); this.do_search(); }, @@ -450,6 +450,10 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea this.drawer = drawer; }, + toggle_visibility: function (is_visible) { + this.$el.toggle(is_visible); + }, + show: function () { this.$el.show(); }, diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 248436357ad..ac8d146823b 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -3,6 +3,7 @@ *---------------------------------------------------------*/ (function() { +"use strict"; var instance = openerp; openerp.web.views = {}; @@ -14,17 +15,14 @@ instance.web.ActionManager = instance.web.Widget.extend({ this._super(parent); this.inner_action = null; this.inner_widget = null; + this.webclient = parent; this.dialog = null; this.dialog_widget = null; - this.breadcrumbs = []; + this.view_managers = []; this.on('history_back', this, function() { return this.history_back(); }); }, - start: function() { - this._super.apply(this, arguments); - this.$el.on('click', 'a.oe_breadcrumb_item', this.on_breadcrumb_clicked); - }, dialog_stop: function (reason) { if (this.dialog) { this.dialog.destroy(reason); @@ -47,185 +45,132 @@ instance.web.ActionManager = instance.web.Widget.extend({ * @param {String|Array} [item.title] title(s) of the view(s) to be displayed in the breadcrumb * @param {Function} [item.get_title] should return the title(s) of the view(s) to be displayed in the breadcrumb */ - push_breadcrumb: function(item) { - var last = this.breadcrumbs.slice(-1)[0]; - if (last) { - last.hide(); - } - item = _.extend({ - show: function(index) { - this.widget.$el.show(); - }, - hide: function() { - this.widget.$el.hide(); - }, - destroy: function() { - this.widget.destroy(); - }, - get_title: function() { - return this.title || this.widget.get('title'); - } - }, item); - item.id = _.uniqueId('breadcrumb_'); - this.breadcrumbs.push(item); - }, - history_back: function() { - var last = this.breadcrumbs.slice(-1)[0]; - if (!last) { - return false; - } - var title = last.get_title(); - if (_.isArray(title) && title.length > 1) { - return this.select_breadcrumb(this.breadcrumbs.length - 1, title.length - 2); - } else if (this.breadcrumbs.length === 1) { - // Only one single titled item in breadcrumb, most of the time you want to trigger back to home - return false; - } else { - var prev = this.breadcrumbs[this.breadcrumbs.length - 2]; - title = prev.get_title(); - return this.select_breadcrumb(this.breadcrumbs.length - 2, _.isArray(title) ? title.length - 1 : undefined); - } - }, - on_breadcrumb_clicked: function(ev) { - var $e = $(ev.target); - var id = $e.data('id'); - var index; - for (var i = this.breadcrumbs.length - 1; i >= 0; i--) { - if (this.breadcrumbs[i].id == id) { - index = i; - break; - } - } - var subindex = $e.parent().find('a.oe_breadcrumb_item[data-id=' + $e.data('id') + ']').index($e); - this.select_breadcrumb(index, subindex); - }, - select_breadcrumb: function(index, subindex) { - var next_item = this.breadcrumbs[index + 1]; - if (next_item && next_item.on_reverse_breadcrumb) { - next_item.on_reverse_breadcrumb(this.breadcrumbs[index].widget); + push_view_manager: function(widget, action, clear_breadcrumbs) { + var self = this, + old_widget = this.inner_widget; + + if (clear_breadcrumbs) { + var to_destroy = this.view_managers; + this.view_managers = []; } - for (var i = this.breadcrumbs.length - 1; i >= 0; i--) { - if (i > index) { - if (this.remove_breadcrumb(i) === false) { - return false; - } + this.view_managers.push(widget); + this.inner_action = action; + this.inner_widget = widget; + return $.when(this.inner_widget.appendTo(this.$el)).done(function () { + widget.$header && widget.$header.show(); + old_widget && old_widget.$el.hide(); + if (clear_breadcrumbs) { + self.clear_view_managers(to_destroy) } - } - var item = this.breadcrumbs[index]; - item.show(subindex); - this.inner_widget = item.widget; - this.inner_action = item.action; - return true; + }); }, - clear_breadcrumbs: function() { - for (var i = this.breadcrumbs.length - 1; i >= 0; i--) { - if (this.remove_breadcrumb(0) === false) { - break; - } - } + get_breadcrumbs: function () { + return _.flatten(_.map(this.view_managers, function (vm) { + return vm.view_stack.map(function (view, index) { + return { + title: view.controller.get('title') || vm.title, + index: index, + view_manager: vm, + }; + }); + }), true); }, - remove_breadcrumb: function(index) { - var item = this.breadcrumbs.splice(index, 1)[0]; - if (item) { - var dups = _.filter(this.breadcrumbs, function(it) { - return item.widget === it.widget; + history_back: function() { + // var last = this.breadcrumbs.slice(-1)[0]; + // if (!last) { + // return false; + // } + // var title = last.get_title(); + // if (_.isArray(title) && title.length > 1) { + // return this.select_breadcrumb(this.breadcrumbs.length - 1, title.length - 2); + // } else if (this.breadcrumbs.length === 1) { + // // Only one single titled item in breadcrumb, most of the time you want to trigger back to home + // return false; + // } else { + // var prev = this.breadcrumbs[this.breadcrumbs.length - 2]; + // title = prev.get_title(); + // return this.select_breadcrumb(this.breadcrumbs.length - 2, _.isArray(title) ? title.length - 1 : undefined); + // } + }, + select_view_manager: function(view_manager, index) { + var self = this; + var vm_index = this.view_managers.indexOf(view_manager); + view_manager.select_view(index).done(function () { + _.each(self.view_managers.splice(vm_index + 1), function (vm) { + vm.destroy(); }); - if (!dups.length) { - if (this.getParent().has_uncommitted_changes()) { - this.inner_widget = item.widget; - this.inner_action = item.action; - this.breadcrumbs.splice(index, 0, item); - return false; - } else { - item.destroy(); - } - } - } - var last_widget = this.breadcrumbs.slice(-1)[0]; - if (last_widget) { - this.inner_widget = last_widget.widget; - this.inner_action = last_widget.action; + self.inner_widget = _.last(self.view_managers); + self.inner_widget.display_breadcrumbs(); + self.inner_widget.$el.show(); + }); + }, + clear_view_managers: function(vms) { + _.each(vms || this.view_managers, function (vm) { + vm.destroy(); + }); + if (!vms) { + this.view_managers = []; + this.inner_widget = null; } }, add_breadcrumb_url: function (url, label) { // Add a pseudo breadcrumb that will redirect to an url - this.push_breadcrumb({ - show: function() { - instance.web.redirect(url); - }, - hide: function() {}, - destroy: function() {}, - get_title: function() { - return label; - } - }); + // this.push_breadcrumb({ + // show: function() { + // instance.web.redirect(url); + // }, + // hide: function() {}, + // destroy: function() {}, + // get_title: function() { + // return label; + // } + // }); }, - get_title: function() { - var titles = []; - for (var i = 0; i < this.breadcrumbs.length; i += 1) { - var item = this.breadcrumbs[i]; - var tit = item.get_title(); - if (item.hide_breadcrumb) { - continue; + do_push_state: function(state) { + if (!this.webclient || !this.webclient.do_push_state) { + return; + } + state = state || {}; + if (this.inner_action) { + if (this.inner_action._push_me === false) { + // this action has been explicitly marked as not pushable + return; } - if (!_.isArray(tit)) { - tit = [tit]; + state.title = this.inner_action.name; + if(this.inner_action.type == 'ir.actions.act_window') { + state.model = this.inner_action.res_model; } - for (var j = 0; j < tit.length; j += 1) { - var label = _.escape(tit[j]); - if (i === this.breadcrumbs.length - 1 && j === tit.length - 1) { - titles.push(_.str.sprintf('<span class="oe_breadcrumb_item">%s</span>', label)); - } else { - titles.push(_.str.sprintf('<a href="#" class="oe_breadcrumb_item" data-id="%s">%s</a>', item.id, label)); - } + if (this.inner_action.menu_id) { + state.menu_id = this.inner_action.menu_id; } - } - return titles.join(' <span class="oe_fade">/</span> '); - }, - do_push_state: function(state) { - state = state || {}; - if (this.getParent() && this.getParent().do_push_state) { - if (this.inner_action) { - if (this.inner_action._push_me === false) { - // this action has been explicitly marked as not pushable - return; - } - state['title'] = this.inner_action.name; - if(this.inner_action.type == 'ir.actions.act_window') { - state['model'] = this.inner_action.res_model; - } - if (this.inner_action.menu_id) { - state['menu_id'] = this.inner_action.menu_id; - } - if (this.inner_action.id) { - state['action'] = this.inner_action.id; - } else if (this.inner_action.type == 'ir.actions.client') { - state['action'] = this.inner_action.tag; - var params = {}; - _.each(this.inner_action.params, function(v, k) { - if(_.isString(v) || _.isNumber(v)) { - params[k] = v; - } - }); - state = _.extend(params || {}, state); - } - if (this.inner_action.context) { - var active_id = this.inner_action.context.active_id; - if (active_id) { - state["active_id"] = active_id; - } - var active_ids = this.inner_action.context.active_ids; - if (active_ids && !(active_ids.length === 1 && active_ids[0] === active_id)) { - // We don't push active_ids if it's a single element array containing the active_id - // This makes the url shorter in most cases. - state["active_ids"] = this.inner_action.context.active_ids.join(','); + if (this.inner_action.id) { + state.action = this.inner_action.id; + } else if (this.inner_action.type == 'ir.actions.client') { + state.action = this.inner_action.tag; + var params = {}; + _.each(this.inner_action.params, function(v, k) { + if(_.isString(v) || _.isNumber(v)) { + params[k] = v; } - } + }); + state = _.extend(params || {}, state); } - if(!this.dialog) { - this.getParent().do_push_state(state); + if (this.inner_action.context) { + var active_id = this.inner_action.context.active_id; + if (active_id) { + state.active_id = active_id; + } + var active_ids = this.inner_action.context.active_ids; + if (active_ids && !(active_ids.length === 1 && active_ids[0] === active_id)) { + // We don't push active_ids if it's a single element array containing the active_id + // This makes the url shorter in most cases. + state.active_ids = this.inner_action.context.active_ids.join(','); + } } } + if(!this.dialog) { + this.webclient.do_push_state(state); + } }, do_load_state: function(state, warm) { var self = this, @@ -390,7 +335,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ }, null_action: function() { this.dialog_stop(); - this.clear_breadcrumbs(); + this.clear_view_managers(); }, /** * @@ -403,14 +348,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ * @return {*} */ ir_actions_common: function(executor, options) { - if (this.inner_widget && executor.action.target !== 'new') { - if (this.getParent().has_uncommitted_changes()) { - return $.Deferred().reject(); - } else if (options.clear_breadcrumbs) { - this.clear_breadcrumbs(); - } - } - var widget = executor.widget(); + var widget; if (executor.action.target === 'new') { var pre_dialog = (this.dialog && !this.dialog.isDestroyed()) ? this.dialog : null; if (pre_dialog){ @@ -442,6 +380,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ } }; this.dialog.on("closing", null, this.dialog.on_close); + widget = executor.widget(); if (widget instanceof instance.web.ViewManager) { _.extend(widget.flags, { $buttons: this.dialog.$buttons, @@ -453,30 +392,33 @@ instance.web.ActionManager = instance.web.Widget.extend({ var initialized = this.dialog_widget.appendTo(this.dialog.$el); this.dialog.open(); return initialized; - } else { - // explicitly passing a closing action to dialog_stop() prevents - // it from reloading the original form view - we're opening a - // completely new action anyway - this.dialog_stop(executor.action); - this.inner_action = executor.action; - this.inner_widget = widget; - executor.post_process(widget); - return this.inner_widget.appendTo(this.$el); } + if (this.inner_widget && this.webclient.has_uncommitted_changes()) { + return $.Deferred().reject(); + } + widget = executor.widget(); + this.dialog_stop(executor.action); + if (options.clear_breadcrumbs) { + // this.clear_view_managers(); + } + return this.push_view_manager(widget, executor.action, options.clear_breadcrumbs); }, ir_actions_act_window: function (action, options) { var self = this; return this.ir_actions_common({ - widget: function () { return new instance.web.ViewManagerAction(self, action); }, + widget: function () { + return new instance.web.ViewManagerAction(self, action); + }, action: action, klass: 'oe_act_window', - post_process: function (widget) { - widget.add_breadcrumb({ - on_reverse_breadcrumb: options.on_reverse_breadcrumb, - hide_breadcrumb: options.hide_breadcrumb, - }); - }, + // post_process: function (widget) { + // self.push_breadcrumb({ + // widget: widget, + // on_reverse_breadcrumb: options.on_reverse_breadcrumb, + // hide_breadcrumb: options.hide_breadcrumb, + // }); + // }, }, options); }, ir_actions_client: function (action, options) { @@ -498,17 +440,17 @@ instance.web.ActionManager = instance.web.Widget.extend({ widget: function () { return new ClientWidget(self, action); }, action: action, klass: 'oe_act_client', - post_process: function(widget) { - self.push_breadcrumb({ - widget: widget, - title: action.name, - on_reverse_breadcrumb: options.on_reverse_breadcrumb, - hide_breadcrumb: options.hide_breadcrumb, - }); - if (action.tag !== 'reload') { - self.do_push_state({}); - } - } + // post_process: function(widget) { + // self.push_breadcrumb({ + // widget: widget, + // title: action.name, + // on_reverse_breadcrumb: options.on_reverse_breadcrumb, + // hide_breadcrumb: options.hide_breadcrumb, + // }); + // if (action.tag !== 'reload') { + // self.do_push_state({}); + // } + // } }, options); }, ir_actions_act_window_close: function (action, options) { @@ -578,247 +520,186 @@ instance.web.ActionManager = instance.web.Widget.extend({ instance.web.ViewManager = instance.web.Widget.extend({ template: "ViewManager", + /** + * @param {Object} [dataset] null object (... historical reasons) + * @param {Array} [views] List of [view_id, view_type] + * @param {Object} [flags] various boolean describing UI state + */ init: function(parent, dataset, views, flags) { + var self = this; this._super(parent); - this.url_states = {}; - this.model = dataset ? dataset.model : undefined; + + this.flags = flags; this.dataset = dataset; - this.searchview = null; - this.active_view = null; - this.views_src = _.map(views, function(x) { - if (x instanceof Array) { - var view_type = x[1]; - var View = instance.web.views.get_object(view_type, true); - var view_label = View ? View.prototype.display_name : (void 'nope'); - return { - view_id: x[0], - view_type: view_type, - label: view_label, - button_label: View ? _.str.sprintf(_t('%(view_type)s view'), {'view_type': (view_label || view_type)}) : (void 'nope'), - }; - } else { - return x; - } - }); - this.ActionManager = parent; + this.view_order = []; + this.url_states = {}; this.views = {}; - this.flags = flags || {}; + this.view_stack = []; // used for breadcrumbs + this.active_view = null; + this.searchview = null; + this.active_search = null; this.registry = instance.web.views; - this.views_history = []; - this.view_completely_inited = $.Deferred(); + this.title = this.action && this.action.name; + + _.each(views, function (view) { + var view_type = view[1] || view.view_type, + View = instance.web.views.get_object(view_type, true), + view_label = View ? View.prototype.display_name : (void 'nope'); + self.view_order.push(view_type); + self.views[view_type] = { + controller: null, + options: view.options || {}, + view_id: view[0] || view.view_id, + type: view_type, + label: view_label, + embedded_view: view.embedded_view, + title: self.action && self.action.name, + button_label: View ? _.str.sprintf(_t('%(view_type)s view'), {'view_type': (view_label || view_type)}) : (void 'nope'), + }; + }); }, /** * @returns {jQuery.Deferred} initial view loading promise */ start: function() { - this._super(); var self = this; - this.$el.find('.oe_view_manager_switch a').click(function() { - self.switch_mode($(this).data('view-type')); - }).tooltip(); - var views_ids = {}; - _.each(this.views_src, function(view) { - self.views[view.view_type] = $.extend({}, view, { - deferred : $.Deferred(), - controller : null, - options : _.extend({ - $buttons : self.$el.find('.oe_view_manager_buttons'), - $sidebar : self.flags.sidebar ? self.$el.find('.oe_view_manager_sidebar') : undefined, - $pager : self.$el.find('.oe_view_manager_pager'), - action : self.action, - action_views_ids : views_ids - }, self.flags, self.flags[view.view_type] || {}, view.options || {}) - }); + var default_view = this.flags.default_view || this.view_order[0], + default_options = this.flags[default_view] && this.flags[default_view].options; - views_ids[view.view_type] = view.view_id; - }); - if (this.flags.views_switcher === false) { - this.$el.find('.oe_view_manager_switch').hide(); - } - // If no default view defined, switch to the first one in sequence - var default_view = this.flags.default_view || this.views_src[0].view_type; + this._super(); + var $sidebar = this.flags.sidebar ? this.$('.oe_view_manager_sidebar') : undefined, + $pager = this.$('.oe_view_manager_pager'); - return this.switch_mode(default_view, null, this.flags[default_view] && this.flags[default_view].options); + this.$breadcrumbs = this.$('.oe-view-title'); + this.$switch_buttons = this.$('.oe-view-manager-switch a'); + this.$header = this.$('.oe-view-manager-header'); + self.$switch_buttons.click(function () { + self.switch_mode($(this).data('view-type')); + }); + var views_ids = {}; + _.each(this.views, function (view) { + views_ids[view.type] = view.view_id; + view.options = _.extend({ + $buttons: self.$('.oe-' + view.type + '-buttons'), + $sidebar : $sidebar, + $pager : $pager, + action : self.action, + action_views_ids : views_ids, + }, self.flags, self.flags[view.type], view.options); + }); + var search_view_loaded = this.flags.search_view ? this.setup_search_view() : $.when(), + main_view_loaded = this.switch_mode(default_view, null, default_options); + + return $.when(main_view_loaded, search_view_loaded); }, + switch_mode: function(view_type, no_store, view_options) { - var self = this; - var view = this.views[view_type]; - var view_promise; - var form = this.views['form']; - if (!view || (form && form.controller && !form.controller.can_be_discarded())) { - return $.Deferred().reject(); - } - if (!no_store) { - this.views_history.push(view_type); + var self = this, + view = this.views[view_type]; + + if (view_type !== 'form') { + this.view_stack = []; } - this.active_view = view_type; - if (!view.controller) { - view_promise = this.do_create_view(view_type); - } else if (this.searchview - && self.flags.auto_search - && view.controller.searchable !== false) { - this.searchview.ready.done(this.searchview.do_search); + this.view_stack.push(view); + this.active_view = view; + if (!view.created) { + view.created = this.create_view.bind(this)(view); } + this.active_search = $.Deferred(); - if (this.searchview) { - this.searchview[(view.controller.searchable === false || this.searchview.options.hidden) ? 'hide' : 'show'](); + if (this.searchview + && this.flags.auto_search + && view.controller.searchable !== false) { + $.when(this.searchview.ready, view.created).done(this.searchview.do_search); + } else { + this.active_search.resolve(); } - this.$el.find('.oe_view_manager_switch a').parent().removeClass('active'); - this.$el - .find('.oe_view_manager_switch a').filter('[data-view-type="' + view_type + '"]') - .parent().addClass('active'); - this.$el.attr("data-view-type", view_type); - return $.when(view_promise).done(function () { - _.each(_.keys(self.views), function(view_name) { - var controller = self.views[view_name].controller; - if (controller) { - var container = self.$el.find("> div > div > .oe_view_manager_body > .oe_view_manager_view_" + view_name); - if (view_name === view_type) { - container.show(); - controller.do_show(view_options || {}); - } else { - container.hide(); - controller.do_hide(); - } + self.update_header(); + return $.when(view.created, this.active_search).done(function () { + self.active_view = view; + self._display_view(view.type, view_options); + self.trigger('switch_mode', view_type, no_store, view_options); + }); + }, + update_header: function () { + this.$switch_buttons.removeClass('active'); + this.$('.oe-vm-switch-' + this.active_view.type).addClass('active'); + }, + _display_view: function (view_type, view_options) { + var self = this; + this.active_view.$container.show(); + $.when(this.active_view.controller.do_show(view_options)).done(function () { + _.each(self.views, function (view) { + if (view.type !== view_type) { + view.controller && view.controller.do_hide(); + view.$container && view.$container.hide(); + view.options.$buttons && view.options.$buttons.hide(); } }); - self.trigger('switch_mode', view_type, no_store, view_options); + self.active_view.options.$buttons && self.active_view.options.$buttons.show(); + if (self.searchview) { + var is_hidden = self.active_view.controller.searchable === false || self.searchview.options.hidden; + self.searchview.toggle_visibility(!is_hidden); + } + self.display_breadcrumbs(); }); }, - do_create_view: function(view_type) { - // Lazy loading of views + display_breadcrumbs: function () { var self = this; - var view = this.views[view_type]; - var viewclass = this.registry.get_object(view_type); - var options = _.clone(view.options); - if (view_type === "form" && this.action && (this.action.target == 'new' || this.action.target == 'inline')) { + if (!this.action_manager) return; + var breadcrumbs = this.action_manager.get_breadcrumbs(); + var $breadcrumbs = _.map(_.initial(breadcrumbs), function (bc) { + var $link = $('<a>').text(bc.title); + $link.click(function () { + self.action_manager.select_view_manager(bc.view_manager, bc.index); + }); + return $('<li>').append($link); + }); + $breadcrumbs.push($('<li>').addClass('active').text(_.last(breadcrumbs).title)); + this.$breadcrumbs + .empty() + .append($breadcrumbs); + }, + create_view: function(view) { + var self = this, + View = this.registry.get_object(view.type), + options = _.clone(view.options); + + if (view.type === "form" && this.action && (this.action.target === 'new' || this.action.target === 'inline')) { options.initial_mode = 'edit'; } - var controller = new viewclass(this, this.dataset, view.view_id, options); + var controller = new View(this, this.dataset, view.view_id, options), + $container = this.$(".oe-view-manager-view-" + view.type + ":first"); - controller.on('history_back', this, function() { - var am = self.getParent(); - if (am && am.trigger) { - return am.trigger('history_back'); - } - }); - - controller.on("change:title", this, function() { - if (self.active_view === view_type) { - self.set_title(controller.get('title')); - } - }); + $container.hide(); + view.controller = controller; if (view.embedded_view) { controller.set_embedded_view(view.embedded_view); } - controller.on('switch_mode', self, this.switch_mode); - controller.on('previous_view', self, this.prev_view); + controller.on('switch_mode', this, this.switch_mode.bind(this)); - var container = this.$el.find("> div > div > .oe_view_manager_body > .oe_view_manager_view_" + view_type); - var view_promise = controller.appendTo(container); - this.views[view_type].controller = controller; - return $.when(view_promise).done(function() { - self.views[view_type].deferred.resolve(view_type); - if (self.searchview - && self.flags.auto_search - && view.controller.searchable !== false) { - self.searchview.ready.done(self.searchview.do_search); - } else { - self.view_completely_inited.resolve(); - } - self.trigger("controller_inited",view_type,controller); - }); - }, + view.$container = $container; - /** - * @returns {Number|Boolean} the view id of the given type, false if not found - */ - get_view_id: function(view_type) { - return this.views[view_type] && this.views[view_type].view_id || false; - }, - set_title: function(title) { - this.$el.find('.oe_view_title_text:first').text(title); - }, - add_breadcrumb: function(options) { - options = options || {}; - var self = this; - var views = [this.active_view || this.views_src[0].view_type]; - this.on('switch_mode', self, function(mode) { - var last = views.slice(-1)[0]; - if (mode !== last) { - if (mode !== 'form') { - views.length = 0; - } - views.push(mode); - } - instance.web.bus.trigger('view_switch_mode', self, mode); + var view_loaded = $.Deferred(); + view.controller.on('view_loaded', this, function () { + view_loaded.resolve(); }); - var item = _.extend({ - widget: this, - action: this.action, - show: function(index) { - var view_to_select = views[index]; - var state = self.url_states[view_to_select]; - self.do_push_state(state || {}); - $.when(self.switch_mode(view_to_select)).done(function() { - self.$el.show(); - }); - }, - get_title: function() { - var id; - var currentIndex; - _.each(self.getParent().breadcrumbs, function(bc, i) { - if (bc.widget === self) { - currentIndex = i; - } - }); - var next = self.getParent().breadcrumbs.slice(currentIndex + 1)[0]; - var titles = _.map(views, function(v) { - var controller = self.views[v].controller; - if (v === 'form') { - id = controller.datarecord.id; - } - return controller.get('title'); + + return $.when(controller.appendTo($container), view_loaded) + .done(function () { + self.trigger("controller_inited", view.type, controller); }); - if (next && next.action && next.action.res_id && self.dataset && - self.active_view === 'form' && self.dataset.model === next.action.res_model && id === next.action.res_id) { - // If the current active view is a formview and the next item in the breadcrumbs - // is an action on same object (model / res_id), then we omit the current formview's title - titles.pop(); - } - return titles; - } - }, options); - this.getParent().push_breadcrumb(item); }, - /** - * Returns to the view preceding the caller view in this manager's - * navigation history (the navigation history is appended to via - * switch_mode) - * - * @param {Object} [options] - * @param {Boolean} [options.created=false] resource was created - * @param {String} [options.default=null] view to switch to if no previous view - * @returns {$.Deferred} switching end signal - */ - prev_view: function (options) { - options = options || {}; - var current_view = this.views_history.pop(); - var previous_view = this.views_history[this.views_history.length - 1] || options['default']; - if (options.created && current_view === 'form' && previous_view === 'list') { - // APR special case: "If creation mode from list (and only from a list), - // after saving, go to page view (don't come back in list)" - return this.switch_mode('form'); - } else if (options.created && !previous_view && this.action && this.action.flags.default_view === 'form') { - // APR special case: "If creation from dashboard, we have no previous view - return this.switch_mode('form'); - } - return this.switch_mode(previous_view, true); + + select_view: function (index) { + var view_type = this.view_stack[index].type; + this.view_stack.splice(index); + return this.switch_mode(view_type); }, /** * Sets up the current viewmanager's search view. @@ -826,25 +707,37 @@ instance.web.ViewManager = instance.web.Widget.extend({ * @param {Number|false} view_id the view to use or false for a default one * @returns {jQuery.Deferred} search view startup deferred */ - setup_search_view: function(view_id, search_defaults) { - var self = this; + setup_search_view: function() { if (this.searchview) { this.searchview.destroy(); } + var view_id = (this.action && this.action.search_view_id && this.action.search_view_id[0]) || false; + var search_defaults = {}; + + var context = this.action ? this.action.context : []; + _.each(context, function (value, key) { + var match = /^search_default_(.*)$/.exec(key); + if (match) { + search_defaults[match[1]] = value; + } + }); + + var options = { hidden: this.flags.search_view === false, disable_custom_filters: this.flags.search_disable_custom_filters, }; - this.searchview = new instance.web.SearchView(this, this.dataset, view_id, search_defaults, options); + var SearchView = instance.web.SearchView; + this.searchview = new SearchView(this, this.dataset, view_id, search_defaults, options); - this.searchview.on('search_data', self, this.do_searchview_search); - return this.searchview.appendTo(this.$(".oe_view_manager_view_search"), - this.$(".oe_searchview_drawer_container")); + this.searchview.on('search_data', this, this.search.bind(this)); + return this.searchview.appendTo(this.$(".oe-view-manager-search-view:first"), + this.$('.oe_searchview_drawer_container')); }, - do_searchview_search: function(domains, contexts, groupbys) { + search: function(domains, contexts, groupbys) { var self = this, - controller = this.views[this.active_view].controller, + controller = this.active_view.controller, action_context = this.action.context || {}; instance.web.pyeval.eval_domains_and_contexts({ domains: [this.action.domain || []].concat(domains || []), @@ -865,301 +758,48 @@ instance.web.ViewManager = instance.web.Widget.extend({ groupby = [groupby]; } $.when(controller.do_search(results.domain, results.context, groupby || [])).then(function() { - self.view_completely_inited.resolve(); + self.active_search.resolve(); }); }); }, - /** - * Called when one of the view want to execute an action - */ - on_action: function(action) { - }, - on_create: function() { - }, - on_remove: function() { - }, - on_edit: function() { - }, - /** - * Called by children view after executing an action - */ - on_action_executed: function () { - }, -}); - -instance.web.ViewManagerAction = instance.web.ViewManager.extend({ - template:"ViewManagerAction", - /** - * @constructs instance.web.ViewManagerAction - * @extends instance.web.ViewManager - * - * @param {instance.web.ActionManager} parent parent object/widget - * @param {Object} action descriptor for the action this viewmanager needs to manage its views. - */ - init: function(parent, action) { - // dataset initialization will take the session from ``this``, so if we - // do not have it yet (and we don't, because we've not called our own - // ``_super()``) rpc requests will blow up. - var flags = action.flags || {}; - if (!('auto_search' in flags)) { - flags.auto_search = action.auto_search !== false; - } - if (action.res_model == 'board.board' && action.view_mode === 'form') { - // Special case for Dashboards - _.extend(flags, { - views_switcher : false, - display_title : false, - search_view : false, - pager : false, - sidebar : false, - action_buttons : false - }); - } - this._super(parent, null, action.views, flags); - this.session = parent.session; - this.action = action; - var context = action.context; - if (action.target === 'current'){ - var active_context = { - active_model: action.res_model, - }; - context = new instance.web.CompoundContext(context, active_context).eval(); - delete context['active_id']; - delete context['active_ids']; - if (action.res_id){ - context['active_id'] = action.res_id; - context['active_ids'] = [action.res_id]; - } - } - var dataset = new instance.web.DataSetSearch(this, action.res_model, context, action.domain); - if (action.res_id) { - dataset.ids.push(action.res_id); - dataset.index = 0; - } - this.dataset = dataset; - }, - /** - * Initializes the ViewManagerAction: sets up the searchview (if the - * searchview is enabled in the manager's action flags), calls into the - * parent to initialize the primary view and (if the VMA has a searchview) - * launches an initial search after both views are done rendering. - */ - start: function() { - var self = this, - searchview_loaded, - search_defaults = {}; - _.each(this.action.context, function (value, key) { - var match = /^search_default_(.*)$/.exec(key); - if (match) { - search_defaults[match[1]] = value; - } - }); - // init search view - var searchview_id = this.action['search_view_id'] && this.action['search_view_id'][0]; - - searchview_loaded = this.setup_search_view(searchview_id || false, search_defaults); - - var main_view_loaded = this._super(); - - var manager_ready = $.when(searchview_loaded, main_view_loaded, this.view_completely_inited); - - this.$el.find('.oe_debug_view').change(this.on_debug_changed); - this.$el.addClass("oe_view_manager_" + (this.action.target || 'current')); - return manager_ready; - }, - on_debug_changed: function (evt) { - var self = this, - $sel = $(evt.currentTarget), - $option = $sel.find('option:selected'), - val = $sel.val(), - current_view = this.views[this.active_view].controller; - switch (val) { - case 'fvg': - var dialog = new instance.web.Dialog(this, { title: _t("Fields View Get") }).open(); - $('<pre>').text(instance.web.json_node_to_xml(current_view.fields_view.arch, true)).appendTo(dialog.$el); - break; - case 'tests': - this.do_action({ - name: _t("JS Tests"), - target: 'new', - type : 'ir.actions.act_url', - url: '/web/tests?mod=*' - }); - break; - case 'get_metadata': - var ids = current_view.get_selected_ids(); - if (ids.length === 1) { - this.dataset.call('get_metadata', [ids]).done(function(result) { - var dialog = new instance.web.Dialog(this, { - title: _.str.sprintf(_t("Metadata (%s)"), self.dataset.model), - size: 'medium', - }, QWeb.render('ViewManagerDebugViewLog', { - perm : result[0], - format : instance.web.format_value - })).open(); - }); - } - break; - case 'toggle_layout_outline': - current_view.rendering_engine.toggle_layout_debugging(); - break; - case 'set_defaults': - current_view.open_defaults_dialog(); - break; - case 'translate': - this.do_action({ - name: _t("Technical Translation"), - res_model : 'ir.translation', - domain : [['type', '!=', 'object'], '|', ['name', '=', this.dataset.model], ['name', 'ilike', this.dataset.model + ',']], - views: [[false, 'list'], [false, 'form']], - type : 'ir.actions.act_window', - view_type : "list", - view_mode : "list" - }); - break; - case 'fields': - this.dataset.call('fields_get', [false, {}]).done(function (fields) { - var $root = $('<dl>'); - _(fields).each(function (attributes, name) { - $root.append($('<dt>').append($('<h4>').text(name))); - var $attrs = $('<dl>').appendTo($('<dd>').appendTo($root)); - _(attributes).each(function (def, name) { - if (def instanceof Object) { - def = JSON.stringify(def); - } - $attrs - .append($('<dt>').text(name)) - .append($('<dd style="white-space: pre-wrap;">').text(def)); - }); - }); - new instance.web.Dialog(self, { - title: _.str.sprintf(_t("Model %s fields"), - self.dataset.model), - }, $root).open(); - }); - break; - case 'edit_workflow': - return this.do_action({ - res_model : 'workflow', - domain : [['osv', '=', this.dataset.model]], - views: [[false, 'list'], [false, 'form'], [false, 'diagram']], - type : 'ir.actions.act_window', - view_type : 'list', - view_mode : 'list' - }); - case 'edit': - this.do_edit_resource($option.data('model'), $option.data('id'), { name : $option.text() }); - break; - case 'manage_filters': - this.do_action({ - res_model: 'ir.filters', - views: [[false, 'list'], [false, 'form']], - type: 'ir.actions.act_window', - context: { - search_default_my_filters: true, - search_default_model_id: this.dataset.model - } - }); - break; - case 'print_workflow': - if (current_view.get_selected_ids && current_view.get_selected_ids().length == 1) { - instance.web.blockUI(); - var action = { - context: { active_ids: current_view.get_selected_ids() }, - report_name: "workflow.instance.graph", - datas: { - model: this.dataset.model, - id: current_view.get_selected_ids()[0], - nested: true, - } - }; - this.session.get_file({ - url: '/web/report', - data: {action: JSON.stringify(action)}, - complete: instance.web.unblockUI - }); - } - break; - default: - if (val) { - console.log("No debug handler for ", val); - } - } - evt.currentTarget.selectedIndex = 0; - }, - do_edit_resource: function(model, id, action) { - action = _.extend({ - res_model : model, - res_id : id, - type : 'ir.actions.act_window', - view_type : 'form', - view_mode : 'form', - views : [[false, 'form']], - target : 'new', - flags : { - action_buttons : true, - form : { - resize_textareas : true - } - } - }, action || {}); - this.do_action(action); - }, - switch_mode: function (view_type, no_store, options) { - var self = this; - - 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, - view_manager: self - })); - self.set_title(); - }); - }, - do_create_view: function(view_type) { - var self = this; - return this._super.apply(this, arguments).then(function() { - var view = self.views[view_type].controller; - view.set({ 'title': self.action.name }); - }); - }, - get_action_manager: function() { - var cur = this; - while ((cur = cur.getParent())) { - if (cur instanceof instance.web.ActionManager) { - return cur; - } - } - return undefined; - }, - set_title: function(title) { - this.$el.find('.oe_breadcrumb_title:first').html(this.get_action_manager().get_title()); - }, do_push_state: function(state) { - if (this.getParent() && this.getParent().do_push_state) { - state["view_type"] = this.active_view; - this.url_states[this.active_view] = state; - this.getParent().do_push_state(state); + if (this.action_manager) { + state.view_type = this.active_view.type; + this.action_manager.do_push_state(state); } - }, + }, do_load_state: function(state, warm) { var self = this, defs = []; - if (state.view_type && state.view_type !== this.active_view) { + if (state.view_type && state.view_type !== this.active_view.type) { defs.push( - this.views[this.active_view].deferred.then(function() { + this.active_view.created.then(function() { return self.switch_mode(state.view_type, true); }) ); } - $.when(this.views[this.active_view] ? this.views[this.active_view].deferred : $.when(), defs).done(function() { - self.views[self.active_view].controller.do_load_state(state, warm); + $.when(this.active_view ? this.active_view.created : null, defs).done(function() { + self.active_view.controller.do_load_state(state, warm); }); }, }); +instance.web.ViewManagerAction = instance.web.ViewManager.extend({ + template:"ViewManagerAction", + + init: function (parent, action) { + var flags = action.flags || {}; + if (!('auto_search' in flags)) { + flags.auto_search = action.auto_search !== false; + } + this.action = action; + this.action_manager = parent; + var dataset = new instance.web.DataSetSearch(this, action.res_model, action.context, action.domain); + this._super(parent, dataset, action.views, flags); + } +}); + instance.web.Sidebar = instance.web.Widget.extend({ init: function(parent) { var self = this; @@ -1331,7 +971,7 @@ instance.web.Sidebar = instance.web.Widget.extend({ a.url = prefix + '&id=' + a.id + '&t=' + (new Date().getTime()); } }); - self.items['files'] = attachments; + self.items.files = attachments; self.redraw(); this.$('.oe_sidebar_add_attachment .oe_form_binary_file').change(this.on_attachment_changed); this.$el.find('.oe_sidebar_delete_item').click(this.on_attachment_delete); @@ -1519,9 +1159,7 @@ instance.web.View = instance.web.Widget.extend({ this.$el.hide(); }, is_active: function () { - var manager = this.getParent(); - return !manager || !manager.active_view - || manager.views[manager.active_view].controller === this; + return this.ViewManager.active_view.controller === this; }, /** * Wraps fn to only call it if the current view is the active one. If the * current view is not active, doesn't call fn. @@ -1544,7 +1182,8 @@ instance.web.View = instance.web.Widget.extend({ this.getParent().do_push_state(state); } }, - do_load_state: function(state, warm) { + do_load_state: function (state, warm) { + }, /** * Switches to a specific view type diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index f99a96b649b..656b1c9c080 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -476,57 +476,45 @@ </div> </t> -<t t-name="ViewManager"> - <div class="oe_view_manager"> - <table class="oe_view_manager_header"> - <col width="20%"/> - <col width="35%"/> - <col width="15%"/> - <col width="30%"/> - <tr class="oe_header_row oe_header_row_top"> - <td colspan="2"> - <h2 class="oe_view_title" t-if="widget.flags.display_title !== false"> - <span class="oe_view_title_text oe_breadcrumb_title"/> - </h2> - </td> - <td colspan="2"> - <div class="oe_view_manager_view_search"/> - </td> - </tr> - <tr class="oe_header_row"> - <td> - <div class="oe_view_manager_buttons"/> - </td> - <td colspan="2"> - <div class="oe_view_manager_sidebar"/> - </td> - <td> - <ul class="oe_view_manager_switch oe_button_group oe_right"> - <t t-if="widget.views_src.length > 1" t-foreach="widget.views_src" t-as="view"> - <li class="oe_e"> - <a t-attf-class="oe_vm_switch_#{view.view_type}" t-att-data-view-type="view.view_type" - t-att-title="view.button_label"/> - </li> +<div t-name="ViewManager"> + <div class="oe-view-manager-header container-fluid"> + <div class="row"> + <div class="col-md-12 oe-header-title"> + <ol class="oe-view-title breadcrumb" t-if="widget.flags.display_title !== false"> + </ol> + <div class="oe-view-manager-search-view"> + </div> + </div> + </div> + <div class="row"> + <div class="col-md-12"> + <div class="oe-view-manager-buttons"> + <t t-foreach="widget.views" t-as="view"> + <div t-attf-class="oe-#{view}-buttons"/> + </t> + </div> + <div class="oe-view-manager-sidebar"></div> + <div class="oe-view-manager-pager"></div> + + <t t-if="widget.view_order.length > 1"> + <div class="oe-view-manager-switch btn-group btn-group-sm"> + <t t-foreach="widget.view_order" t-as="view_type"> + <a type="button" t-attf-class="btn btn-default fa oe-vm-switch-#{view_type}" t-att-data-view-type="view_type" t-att-title="view_type" t-if="view_type!=='form'"> + </a> </t> - </ul> - <div class="oe_view_manager_pager oe_right"/> - </td> - </tr> - </table> + </div> + </t> - <div class="oe_view_manager_wrapper"> - <div> - <div class="oe_view_manager_body"> - <div class="oe_searchview_drawer_container"/> - <t t-foreach="widget.views_src" t-as="view"> - <div t-attf-class="oe_view_manager_view_#{view.view_type}"/> - </t> - </div> </div> </div> </div> -</t> - + <div class="oe-view-manager-body"> + <div class="oe_searchview_drawer_container"/> + <t t-foreach="widget.views" t-as="view"> + <div t-attf-class="oe-view-manager-view-#{view}"/> + </t> + </div> +</div> <t t-name="ViewManagerAction" t-extend="ViewManager"> <t t-jquery="h2.oe_view_title" t-operation="before"> <select t-if="widget.session.debug" class="oe_debug_view"/> @@ -745,7 +733,7 @@ <t t-name="ListView.buttons"> <div class="oe_list_buttons"> <t t-if="!widget.no_leaf and widget.options.action_buttons !== false and widget.options.addable and widget.is_action_enabled('create')"> - <button type="button" class="oe_button oe_list_add oe_highlight"> + <button type="button" class="oe_list_add btn btn-primary"> <t t-esc="widget.options.addable"/> </button> </t> @@ -830,13 +818,13 @@ <span class="oe_form_buttons_view"> <!-- required for the bounce effect on button --> <div t-if="widget.is_action_enabled('edit')" style="display: inline-block;"> - <button type="button" class="oe_button oe_form_button_edit" accesskey="E">Edit</button> + <button type="button" class="oe_form_button_edit btn btn-default" accesskey="E">Edit</button> </div> <button t-if="widget.is_action_enabled('create')" - type="button" class="oe_button oe_form_button_create" accesskey="C">Create</button> + type="button" class="oe_form_button_create btn btn-default" accesskey="C">Create</button> </span> <span class="oe_form_buttons_edit"> - <button type="button" class="oe_button oe_form_button_save oe_highlight" accesskey="S">Save</button> + <button type="button" class="oe_form_button_save btn btn-primary" accesskey="S">Save</button> <span class="oe_fade">or</span> <a href="#" class="oe_bold oe_form_button_cancel" accesskey="D">Discard</a> </span> @@ -1537,7 +1525,7 @@ <t t-name="One2Many.viewmanager" t-extend="ViewManager"> <t t-jquery=".oe-view-manager-header"> - this.attr('t-if', 'views.length != 1'); + this.attr('t-if', 'widget.view_order.length != 1'); </t> </t> <t t-name="One2Many.formview" t-extend="FormView"> @@ -1558,12 +1546,12 @@ </t> </t> -<div t-name="SearchView" class="oe_searchview"> +<div t-name="SearchView" class="oe_searchview form-control input-sm"> <div class="oe_searchview_facets"/> - <div class="oe_searchview_clear"/> - <div class="oe_searchview_unfold_drawer" title="Advanced Search..."/> - <button type="button" class="oe_searchview_search" - title="Search Again">Search</button> + <div class="oe_searchview_clear"><i class="fa fa-times fa-lg"></i></div> + <div class="oe_searchview_unfold_drawer fa fa-lg fa-chevron-down" title="Advanced Search..."/> + <i type="button" class="oe_searchview_search fa fa-lg fa-search" + title="Search Again"></i> </div> <div t-name="SearchViewDrawer" class="oe_searchview_drawer" style="display:none;"> @@ -1577,16 +1565,17 @@ tabindex="0"/> <!-- tabindex: makes div focusable --> <div t-name="SearchView.FacetView" - class="oe_tag oe_tag_dark oe_searchview_facet" - tabindex="0" - ><span class="oe_facet_remove">x</span - ><span class="oe_facet_category oe_i" t-if="widget.model.has('icon')"> + class="oe_tag oe_searchview_facet" + tabindex="0"> + <span class="oe_facet_remove">x</span> + <span class="label label-default oe_i" t-if="widget.model.has('icon')"> <t t-esc="widget.model.get('icon')"/> - </span - ><span class="oe_facet_category" t-if="!widget.model.has('icon')"> + </span> + <span class="label label-default" t-if="!widget.model.has('icon')"> <t t-esc="widget.model.get('category')"/> - </span ><span class="oe_facet_values" -/></div> + </span > + <span class="oe_facet_values"/> +</div> <span t-name="SearchView.FacetView.Value" class="oe_facet_value"> <t t-esc="widget.model.get('label')"/> </span> |
