summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorAntony Lesuisse <al@openerp.com>2012-05-31 15:43:27 +0200
committerAntony Lesuisse <al@openerp.com>2012-05-31 15:43:27 +0200
commit47d882ca34a0c2e0745ff0d6b10efad0a97aa660 (patch)
tree62b40a9e08074ea0986bca0bc2d718c60252e914 /addons/web/static/src
parent7d0196053867ef2bef9d9929d8c4cf3e4a70cde6 (diff)
parent1242ff10da2434a08d6261fe4d8f44a13c596ece (diff)
[MERGE] trunk
bzr revid: al@openerp.com-20120531134327-z4zcvhfdmdsor0m7
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/css/base.css16
-rw-r--r--addons/web/static/src/css/base.sass17
-rw-r--r--addons/web/static/src/js/view_form.js230
-rw-r--r--addons/web/static/src/xml/base.xml3
4 files changed, 246 insertions, 20 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index ab5f261dbf2..e2879011a72 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -518,6 +518,7 @@
opacity: 0.5;
}
.openerp .oe_leftbar {
+ display: none;
width: 220px;
background: #f0eeee;
border-right: 1px solid #afafb6;
@@ -1721,7 +1722,7 @@
-webkit-border-radius: 3px;
border-radius: 3px;
background: white;
- min-width: 90px;
+ min-width: 70px;
color: #1f1f1f;
}
.openerp .oe_form input[readonly],
@@ -1760,8 +1761,6 @@
.openerp .oe_form .oe_form_field_url button img {
vertical-align: top;
}
-.openerp .oe_form .oe_form_field_translatable,
-.openerp .oe_form .oe_form_field_many2one,
.openerp .oe_form .oe_form_field_date,
.openerp .oe_form .oe_form_field_datetime {
white-space: nowrap;
@@ -1878,8 +1877,9 @@
}
.openerp .oe_horizontal_separator {
font-weight: bold;
- font-size: 16px;
- margin: 4px 0;
+ font-size: 20px;
+ margin: 20px 0px 10px 0px;
+ color: #aaaabb;
}
.openerp .oe_horizontal_separator:empty {
height: 5px;
@@ -1956,7 +1956,7 @@
-webkit-border-radius: 3px;
border-radius: 3px;
background: white;
- min-width: 90px;
+ min-width: 50px;
}
.openerp .oe_form .oe_form_field_progressbar.ui-progressbar span {
position: absolute;
@@ -2070,8 +2070,10 @@
.openerp .oe-listview-content > tbody > tr {
border-top: 1px solid #dddddd;
}
-.openerp .oe-listview-content > tbody > tr > td, .openerp .oe-listview-content > tbody > tr > th {
+.openerp .oe-listview-content > tbody > tr > td.oe-field-cell {
padding: 3px 6px;
+}
+.openerp .oe-listview-content > tbody > tr > td, .openerp .oe-listview-content > tbody > tr > th {
line-height: 18px;
}
.openerp .oe-listview-content > tbody > tr > td > button, .openerp .oe-listview-content > tbody > tr > th > button {
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index 75c351a8558..eda410aa6ca 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -434,6 +434,7 @@ $colour4: #8a89ba
// }}}
// Webclient.leftbar {{{
.oe_leftbar
+ display: none
width: 220px
background: #f0eeee
border-right: 1px solid #afafb6
@@ -1376,13 +1377,13 @@ $colour4: #8a89ba
-webkit-border-radius: 3px
border-radius: 3px
background: white
- min-width: 90px
+ min-width: 70px
color: #1f1f1f
input[readonly],
select[readonly],
textarea[readonly],
input[disabled],
- select[disabled],
+ select[disabled]
background: #E5E5E5 !important
color: #666
textarea[disabled]
@@ -1406,8 +1407,6 @@ $colour4: #8a89ba
.oe_form_field_email button img,
.oe_form_field_url button img
vertical-align: top
- .oe_form_field_translatable,
- .oe_form_field_many2one,
.oe_form_field_date,
.oe_form_field_datetime
white-space: nowrap
@@ -1518,8 +1517,9 @@ $colour4: #8a89ba
border-bottom: 1px solid black
.oe_horizontal_separator
font-weight: bold
- font-size: 16px
- margin: 4px 0
+ font-size: 20px
+ margin: 20px 0px 10px 0px
+ color: #aab
.oe_horizontal_separator:empty
height: 5px
.oe_vertical_separator
@@ -1585,7 +1585,7 @@ $colour4: #8a89ba
-webkit-border-radius: 3px
border-radius: 3px
background: white
- min-width: 90px
+ min-width: 50px
span
position: absolute
@@ -1689,8 +1689,9 @@ $colour4: #8a89ba
background: white
> tr
border-top: 1px solid #ddd
- > td, > th
+ > td.oe-field-cell
padding: 3px 6px
+ > td, > th
line-height: 18px
> button
border: none
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 3430f1dd703..ca1d576a8e5 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -673,7 +673,7 @@ instance.web.FormView = instance.web.View.extend(_.extend({}, instance.web.form.
var msg = "<ul>";
_.each(this.fields, function(f) {
if (!f.is_valid()) {
- msg += "<li>" + f.node.attrs.string + "</li>";
+ msg += "<li>" + (f.node.attrs.string || f.field.string) + "</li>";
}
});
msg += "</ul>";
@@ -937,7 +937,7 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
}
var obj = self.fields_registry.get_any([$elem.attr('widget'), self.fvg.fields[name].type]);
if (!obj) {
- throw new Error("Widget type '"+ key + "' is not implemented");
+ throw new Error("Widget type '"+ $elem.attr('widget') + "' is not implemented");
}
var w = new (obj)(self.view, instance.web.xml_to_json($elem[0]));
var $label = self.labels[$elem.attr("name")];
@@ -2317,9 +2317,11 @@ instance.web.form.CompletionFieldMixin = {
var self = this;
var dataset = new instance.web.DataSet(this, this.field.relation, self.build_context());
+ var blacklist = this.get_search_blacklist();
return this.orderer.add(dataset.name_search(
- search_val, self.build_domain(), 'ilike', this.limit + 1)).pipe(function(data) {
+ search_val, new instance.web.CompoundDomain(self.build_domain(), [["id", "not in", blacklist]]),
+ 'ilike', this.limit + 1)).pipe(function(data) {
self.last_search = data;
// possible selections for the m2o
var values = _.map(data, function(x) {
@@ -2357,6 +2359,9 @@ instance.web.form.CompletionFieldMixin = {
return values;
});
},
+ get_search_blacklist: function() {
+ return [];
+ },
_quick_create: function(name) {
var self = this;
var slow_create = function () {
@@ -2952,6 +2957,12 @@ instance.web.form.One2ManyViewManager = instance.web.ViewManager.extend({
var pop = new instance.web.form.FormOpenPopup(self.o2m.view);
pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(), {
title: _t("Open: ") + self.name,
+ create_function: function(data) {
+ return self.o2m.dataset.create(data).then(function(r) {
+ self.o2m.dataset.set_ids(self.o2m.dataset.ids.concat([r.result]));
+ self.o2m.dataset.on_change();
+ });
+ },
write_function: function(id, data, options) {
return self.o2m.dataset.write(id, data, {}).then(function() {
self.o2m.reload_current_view();
@@ -2966,6 +2977,9 @@ instance.web.form.One2ManyViewManager = instance.web.ViewManager.extend({
form_view_options: {'not_interactible_on_create':true},
readonly: self.o2m.get("effective_readonly")
});
+ pop.on_select_elements.add_last(function() {
+ self.o2m.reload_current_view();
+ });
},
});
@@ -3149,7 +3163,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(_.
});
}).bind('hideDropdown', function() {
self._drop_shown = false;
- }).bind('hideDropdown', function() {
+ }).bind('showDropdown', function() {
self._drop_shown = true;
});
self.tags = self.$text.textext()[0].tags();
@@ -3172,6 +3186,9 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(_.
var tmp = [commands.replace_with(this.get("value"))];
return tmp;
},
+ get_search_blacklist: function() {
+ return this.get("value");
+ },
render_value: function() {
var self = this;
var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.view.dataset.get_context());
@@ -3338,6 +3355,208 @@ instance.web.form.Many2ManyListView = instance.web.ListView.extend(/** @lends in
}
});
+instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend(_.extend({}, instance.web.form.CompletionFieldMixin, {
+ disable_utility_classes: true,
+ init: function(field_manager, node) {
+ this._super(field_manager, node);
+ instance.web.form.CompletionFieldMixin.init.call(this);
+ m2m_kanban_lazy_init();
+ this.is_loaded = $.Deferred();
+ this.initial_is_loaded = this.is_loaded;
+ this.is_setted = $.Deferred();
+ },
+ start: function() {
+ this._super.apply(this, arguments);
+
+ var self = this;
+
+ this.dataset = new instance.web.form.Many2ManyDataSet(this, this.field.relation);
+ this.dataset.m2m = this;
+ this.dataset.on_unlink.add_last(function(ids) {
+ self.dataset_changed();
+ });
+
+ this.is_setted.then(function() {
+ self.load_view();
+ });
+ this.is_loaded.then(function() {
+ self.on("change:effective_readonly", self, function() {
+ self.is_loaded = self.is_loaded.pipe(function() {
+ self.kanban_view.destroy();
+ return $.when(self.load_view()).then(function() {
+ self.reload_content();
+ });
+ });
+ });
+ })
+ },
+ set_value: function(value_) {
+ value_ = value_ || [];
+ if (value_.length >= 1 && value_[0] instanceof Array) {
+ value_ = value_[0][2];
+ }
+ this._super(value_);
+ this.dataset.set_ids(value_);
+ var self = this;
+ self.reload_content();
+ this.is_setted.resolve();
+ },
+ load_view: function() {
+ var self = this;
+ this.kanban_view = new instance.web.form.Many2ManyKanbanView(this, this.dataset, false, {
+ 'create_text': _t("Add"),
+ 'creatable': self.get("effective_readonly") ? false : true,
+ 'quick_creatable': self.get("effective_readonly") ? false : true,
+ });
+ var embedded = (this.field.views || {}).kanban;
+ if (embedded) {
+ this.kanban_view.set_embedded_view(embedded);
+ }
+ this.kanban_view.m2m = this;
+ var loaded = $.Deferred();
+ this.kanban_view.on_loaded.add_last(function() {
+ self.initial_is_loaded.resolve();
+ loaded.resolve();
+ });
+ this.kanban_view.do_switch_view.add_last(_.bind(this.open_popup, this));
+ $.async_when().then(function () {
+ self.kanban_view.appendTo(self.$element);
+ });
+ return loaded;
+ },
+ reload_content: function() {
+ var self = this;
+ this.is_loaded = this.is_loaded.pipe(function() {
+ return self.kanban_view.do_search(self.build_domain(), self.dataset.get_context(), []);
+ });
+ },
+ dataset_changed: function() {
+ this.set({'value': [commands.replace_with(this.dataset.ids)]});
+ },
+ open_popup: function(type, unused) {
+ if (type !== "form")
+ return;
+ var self = this;
+ if (this.dataset.index === null) {
+ var pop = new instance.web.form.SelectCreatePopup(this);
+ pop.select_element(
+ this.field.relation,
+ {
+ title: _t("Add: ") + this.name
+ },
+ new instance.web.CompoundDomain(this.build_domain(), ["!", ["id", "in", this.dataset.ids]]),
+ this.build_context()
+ );
+ pop.on_select_elements.add(function(element_ids) {
+ _.each(element_ids, function(one_id) {
+ if(! _.detect(self.dataset.ids, function(x) {return x == one_id;})) {
+ self.dataset.set_ids([].concat(self.dataset.ids, [one_id]));
+ self.dataset_changed();
+ self.reload_content();
+ }
+ });
+ });
+ } else {
+ var id = self.dataset.ids[self.dataset.index];
+ var pop = new instance.web.form.FormOpenPopup(self.view);
+ pop.show_element(self.field.relation, id, self.build_context(), {
+ title: _t("Open: ") + self.name,
+ write_function: function(id, data, options) {
+ return self.dataset.write(id, data, {}).then(function() {
+ self.reload_content();
+ });
+ },
+ alternative_form_view: self.field.views ? self.field.views["form"] : undefined,
+ parent_view: self.view,
+ child_name: self.name,
+ readonly: self.get("effective_readonly")
+ });
+ }
+ },
+ add_id: function(id) {
+ this.quick_create.add_id(id);
+ },
+}));
+
+function m2m_kanban_lazy_init() {
+if (instance.web.form.Many2ManyKanbanView)
+ return;
+instance.web.form.Many2ManyKanbanView = instance.web_kanban.KanbanView.extend({
+ quick_create_class: 'instance.web.form.Many2ManyQuickCreate',
+ _is_quick_create_enabled: function() {
+ return this._super() && ! this.group_by;
+ },
+});
+instance.web.form.Many2ManyQuickCreate = instance.web.Widget.extend({
+ template: 'Many2ManyKanban.quick_create',
+
+ /**
+ * close_btn: If true, the widget will display a "Close" button able to trigger
+ * a "close" event.
+ */
+ init: function(parent, dataset, context, buttons) {
+ this._super(parent);
+ this.m2m = this.getParent().view.m2m;
+ this.m2m.quick_create = this;
+ this._dataset = dataset;
+ this._buttons = buttons || false;
+ this._context = context || {};
+ },
+ start: function () {
+ var self = this;
+ self.$text = this.$element.find('input').css("width", "200px");
+ self.$text.textext({
+ plugins : 'arrow autocomplete',
+ autocomplete: {
+ render: function(suggestion) {
+ return $('<span class="text-label"/>').
+ data('index', suggestion['index']).html(suggestion['label']);
+ }
+ },
+ ext: {
+ autocomplete: {
+ selectFromDropdown: function() {
+ $(this).trigger('hideDropdown');
+ var index = Number(this.selectedSuggestionElement().children().children().data('index'));
+ var data = self.search_result[index];
+ if (data.id) {
+ self.add_id(data.id);
+ } else {
+ data.action();
+ }
+ },
+ },
+ itemManager: {
+ itemToString: function(item) {
+ return item.name;
+ },
+ },
+ },
+ }).bind('getSuggestions', function(e, data) {
+ var _this = this;
+ var str = !!data ? data.query || '' : '';
+ self.m2m.get_search_result(str).then(function(result) {
+ self.search_result = result;
+ $(_this).trigger('setSuggestions', {result : _.map(result, function(el, i) {
+ return _.extend(el, {index:i});
+ })});
+ });
+ });
+ self.$text.focusout(function() {
+ self.$text.val("");
+ });
+ },
+ focus: function() {
+ this.$text.focus();
+ },
+ add_id: function(id) {
+ var self = this;
+ self.$text.val("");
+ self.trigger('added', id);
+ },
+});
+}
+
/**
* Class with everything which is common between FormOpenPopup and SelectCreatePopup.
*/
@@ -3950,7 +4169,8 @@ instance.web.form.widgets = new instance.web.Registry({
'selection' : 'instance.web.form.FieldSelection',
'many2one' : 'instance.web.form.FieldMany2One',
'many2many' : 'instance.web.form.FieldMany2Many',
- 'many2manytags' : 'instance.web.form.FieldMany2ManyTags',
+ 'many2many_tags' : 'instance.web.form.FieldMany2ManyTags',
+ 'many2many_kanban' : 'instance.web.form.FieldMany2ManyKanban',
'one2many' : 'instance.web.form.FieldOne2Many',
'one2many_list' : 'instance.web.form.FieldOne2Many',
'reference' : 'instance.web.form.FieldReference',
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 20bf690c60b..594b3e3c8d1 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -1822,5 +1822,8 @@
<pre><t t-esc="error.preview"/></pre>
</t>
</t>
+<div t-name="Many2ManyKanban.quick_create" class="oe_kanban_quick_create">
+ <input t-att-placeholder="_t('Type name to search')"/>
+</div>
</templates>