summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/css/base.css39
-rw-r--r--addons/web/static/src/css/base.sass27
-rw-r--r--addons/web/static/src/js/chrome.js78
-rw-r--r--addons/web/static/src/js/coresetup.js32
-rw-r--r--addons/web/static/src/js/search.js5
-rw-r--r--addons/web/static/src/js/view_form.js40
-rw-r--r--addons/web/static/src/js/view_list.js2
-rw-r--r--addons/web/static/src/js/views.js2
-rw-r--r--addons/web/static/src/xml/base.xml24
9 files changed, 173 insertions, 76 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index e338cc309d9..71214acf4fe 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;
@@ -186,6 +186,17 @@
.openerp .ui-menu .ui-menu-item a.ui-state-active {
background: #f0f0fa;
}
+.openerp.ui-dialog {
+ border: 13px solid rgba(0, 0, 0, 0.3);
+ -moz-border-radius: 16px;
+ -webkit-border-radius: 16px;
+ border-radius: 16px;
+ -moz-background-clip: padding-box;
+ -webkit-background-clip: padding;
+ background-clip: padding-box;
+ box-shadow: 0px 0px 1px 1px rgba(0, 0, 0, 0.6);
+ -webkit-box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.2);
+}
.openerp .oe_i {
font-family: "mnmliconsRegular" !important;
font-size: 21px;
@@ -283,7 +294,7 @@
background: #ed6f6a;
}
.openerp .oe_title {
- width: 55%;
+ width: 60%;
}
.openerp .oe_title:after {
content: ".";
@@ -1162,10 +1173,10 @@
.openerp .oe_view_manager .oe_view_manager_switch .oe_vm_switch_diagram:after {
content: "f";
}
-.openerp .oe_view_manager_current, .openerp .oe_view_manager_inline {
+.openerp .oe_view_manager_current {
height: 100%;
}
-.openerp .oe_view_manager_current > .oe_view_manager_header, .openerp .oe_view_manager_inline > .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;
@@ -1179,12 +1190,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_current > .oe_view_manager_header .oe_header_row td, .openerp .oe_view_manager_inline > .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_current > .oe_view_manager_header .oe_header_row:first-child td, .openerp .oe_view_manager_inline > .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;
}
@@ -1612,9 +1629,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;
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index 6514ea8d70b..97a2f708615 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -200,6 +200,14 @@ $colour4: #8a89ba
width: auto
a.ui-state-active
background: #f0f0fa
+ &.ui-dialog
+ border: 13px solid rgba(0, 0, 0, 0.3)
+ @include radius(16px)
+ -moz-background-clip: padding-box
+ -webkit-background-clip: padding
+ background-clip: padding-box
+ box-shadow: 0px 0px 1px 1px rgba(0, 0, 0, 0.6)
+ -webkit-box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.2)
// }}}
// Generic classes {{{
.oe_i
@@ -252,7 +260,7 @@ $colour4: #8a89ba
&:hover
background: #ED6F6A
.oe_title
- width: 55%
+ width: 60%
.oe_title:after
content: "."
display: block
@@ -913,7 +921,7 @@ $colour4: #8a89ba
content: "f"
// }}}
// ViewManager application {{{
- .oe_view_manager_current, .oe_view_manager_inline
+ .oe_view_manager_current
height: 100%
> .oe_view_manager_header
border-top: 1px solid #cacaca
@@ -927,6 +935,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
@@ -1259,9 +1273,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
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index cab59c50ae7..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();
}
});
@@ -579,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() {
@@ -591,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) {
@@ -673,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);
}
},
/**
@@ -708,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);
},
});
@@ -1018,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/coresetup.js b/addons/web/static/src/js/coresetup.js
index ee421bee092..a00ca4002e5 100644
--- a/addons/web/static/src/js/coresetup.js
+++ b/addons/web/static/src/js/coresetup.js
@@ -608,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 2e332ed8b28..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) {
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 8bc2a3894c8..d40a1760e81 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -2891,25 +2891,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);
@@ -3519,6 +3530,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) {
@@ -3999,6 +4011,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() {
@@ -4359,10 +4372,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();
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index 97fccd343f1..b19e483bed9 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.
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index a364b9e0669..98df8a0af0d 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -144,7 +144,7 @@ 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();
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 6e0bd2417f1..ce130dc0e1e 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -621,7 +621,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">
@@ -1008,17 +1010,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 &lt; 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 &lt; size - 1"/>
+ </li>
+ </t>
</t>
<t t-name="FieldBinaryImage">
<span class="oe_form_field oe_form_field_image">