diff --git a/addons/project/project.py b/addons/project/project.py
index e61251e465a..c55a718a3a3 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -453,6 +453,9 @@ class task(osv.osv):
'attachment_ids': fields.one2many('ir.attachment', 'res_id', domain=lambda self: [('res_model', '=', self._name)], auto_join=True, string='Attachments'),
# In the domain of displayed_image_id, we couln't use attachment_ids because a one2many is represented as a list of commands so we used res_model & res_id
'displayed_image_id': fields.many2one('ir.attachment', domain="[('res_model', '=', 'project.task'), ('res_id', '=', id), ('mimetype', 'ilike', 'image')]", string='Displayed Image'),
+ 'legend_blocked': fields.related("stage_id", "legend_blocked", type="char", string='Kanban Blocked Explanation'),
+ 'legend_done': fields.related("stage_id", "legend_done", type="char", string='Kanban Valid Explanation'),
+ 'legend_normal': fields.related("stage_id", "legend_normal", type="char", string='Kanban Ongoing Explanation'),
}
_defaults = {
'stage_id': _get_default_stage_id,
@@ -637,7 +640,6 @@ class task(osv.osv):
# user_id change: update date_assign
if vals.get('user_id'):
vals['date_assign'] = fields.datetime.now()
-
# context: no_log, because subtype already handle this
create_context = dict(context, mail_create_nolog=True)
task_id = super(task, self).create(cr, uid, vals, context=create_context)
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index a99da613812..46aa452adfd 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -254,11 +254,7 @@
options='{"terminology": "archive"}'/>
-
+
@@ -274,6 +270,9 @@
+
+
+
@@ -329,6 +328,9 @@
+
+
+
@@ -365,8 +367,7 @@
-
+
diff --git a/addons/web/static/src/js/views/form_widgets.js b/addons/web/static/src/js/views/form_widgets.js
index 30a4700e766..074a36e76f7 100644
--- a/addons/web/static/src/js/views/form_widgets.js
+++ b/addons/web/static/src/js/views/form_widgets.js
@@ -165,6 +165,7 @@ var FieldChar = common.AbstractField.extend(common.ReinitializeFieldMixin, {
});
var KanbanSelection = FieldChar.extend({
+ template: "FormSelection",
init: function (field_manager, node) {
this._super(field_manager, node);
},
@@ -180,54 +181,58 @@ var KanbanSelection = FieldChar.extend({
prepare_dropdown_selection: function() {
var self = this;
var _data = [];
- var fetch_stage;
- var selection = this.field.selection || [];
- var stage_id = _.isArray(this.view.datarecord.stage_id) ? this.view.datarecord.stage_id[0] : this.view.datarecord.stage_id;
- var legend_field = this.options && this.options.states_legend_field || false;
- var fields_to_read = _.map(
- this.options && this.options.states_legend || {},
- function (value, key, list) { return value; });
- if (legend_field && fields_to_read && stage_id) {
- fetch_stage = new data.DataSet(
- this,
- self.view.fields[legend_field].field.relation).read_ids([stage_id],
- fields_to_read);
- }
- else { fetch_stage = $.Deferred().resolve(false); }
- return $.when(fetch_stage).then(function (stage_data) {
- _.map(selection, function(res) {
- var value = {
- 'name': res[0],
- 'tooltip': res[1],
- 'state_name': res[1],
- };
- if (stage_data && stage_data[0][self.options.states_legend[res[0]]]) {
- value['state_name'] = stage_data[0][self.options.states_legend[res[0]]];
- value['tooltip'] = stage_data[0][self.options.states_legend[res[0]]];
- }
- if (res[0] == 'normal') { value['state_class'] = 'oe_kanban_status'; }
- else if (res[0] == 'done') { value['state_class'] = 'oe_kanban_status oe_kanban_status_green'; }
- else { value['state_class'] = 'oe_kanban_status oe_kanban_status_red'; }
- _data.push(value);
- });
- return _data;
+ var current_stage_id = self.view.datarecord.stage_id[0];
+ var stage_data = {
+ id: current_stage_id,
+ legend_normal: self.view.datarecord.legend_normal,
+ legend_blocked : self.view.datarecord.legend_blocked,
+ legend_done: self.view.datarecord.legend_done,
+ };
+ _.map(self.field.selection || [], function(selection_item) {
+ var value = {
+ 'name': selection_item[0],
+ 'tooltip': selection_item[1],
+ };
+ if (selection_item[0] === 'normal') {
+ value.state_name = stage_data.legend_normal ? stage_data.legend_normal : selection_item[1];
+ } else if (selection_item[0] === 'done') {
+ value.state_class = 'oe_kanban_status_green';
+ value.state_name = stage_data.legend_done ? stage_data.legend_done : selection_item[1];
+ } else {
+ value.state_class = 'oe_kanban_status_red';
+ value.state_name = stage_data.legend_blocked ? stage_data.legend_blocked : selection_item[1];
+ }
+ _data.push(value);
});
+ return _data;
},
render_value: function() {
+ this._super();
+ this.states = this.prepare_dropdown_selection();
var self = this;
- var dd_fetched = this.prepare_dropdown_selection();
- return $.when(dd_fetched).then(function (states) {
- self.states = states;
- self.$el.addClass('oe_right oe_inline');
- self.$el.html(QWeb.render("KanbanSelection", {'widget': self}));
- self.$el.find('li').on('click', self.set_kanban_selection.bind(self));
+ // Adapt "FormSelection"
+ var current_state = _.find(this.states, function(state) {
+ return state.name === self.get('value');
});
+ this.$('.oe_kanban_status')
+ .removeClass('oe_kanban_status_red oe_kanban_status_green')
+ .addClass(current_state.state_class);
+
+ // Render "FormSelection.Items" and move it into "FormSelection"
+ var $items = $(QWeb.render('FormSelection.items', {
+ states: _.without(this.states, current_state)
+ }));
+ var $dropdown = this.$el.find('.dropdown-menu');
+ $dropdown.children().remove(); // remove old items
+ $items.appendTo($dropdown);
+ this.$el.find('a').on('click', this.set_kanban_selection.bind(this));
},
/* setting the value: in view mode, perform an asynchronous call and reload
the form view; in edit mode, use set_value to save the new value that will
be written when saving the record. */
set_kanban_selection: function (ev) {
var self = this;
+ ev.preventDefault();
var li = $(ev.target).closest('li');
if (li.length) {
var value = String(li.data('value'));
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index be17df5ba48..435352efc16 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -679,28 +679,21 @@
-
-
-
-
-
-
- Toggle Dropdown
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/web_kanban/static/src/js/kanban_widgets.js b/addons/web_kanban/static/src/js/kanban_widgets.js
index 4db931e9a64..9fe64c3c3ea 100644
--- a/addons/web_kanban/static/src/js/kanban_widgets.js
+++ b/addons/web_kanban/static/src/js/kanban_widgets.js
@@ -9,7 +9,6 @@ var pyeval = require('web.pyeval');
var Registry = require('web.Registry');
var session = require('web.session');
var Widget = require('web.Widget');
-
var QWeb = core.qweb;
/**
* Interface to be implemented by kanban fields.
@@ -103,53 +102,52 @@ var KanbanSelection = AbstractField.extend({
this.name = $node.attr('name');
this.parent = parent;
},
+ // Instead of making several rpc calls for each kanban card, take the values from the related fields on the tasks
prepare_dropdown_selection: function() {
var self = this;
- var data = [];
- _.map(this.field.selection || [], function(res) {
+ var _data = [];
+ var stage_id = self.parent.values.stage_id.value[0];
+ var stage_data = {
+ id: stage_id,
+ legend_normal: self.parent.values.legend_normal.value,
+ legend_blocked : self.parent.values.legend_blocked.value,
+ legend_done: self.parent.values.legend_done.value,
+ };
+ _.map(self.field.selection || [], function(res) {
var value = {
'name': res[0],
'tooltip': res[1],
- 'state_name': res[1],
};
- var leg_opt = self.options && self.options.states_legend || null;
- if (leg_opt) {
- var key = leg_opt[value.name];
- var legend = self.parent.group_info && self.parent.group_info[key];
- if (legend) {
- value.state_name = legend;
- value.tooltip = legend;
- }
+ if (res[0] === 'normal') {
+ value.state_name = stage_data.legend_normal ? stage_data.legend_normal : res[1];
+ } else if (res[0] === 'done') {
+ value.state_class = 'oe_kanban_status_green';
+ value.state_name = stage_data.legend_done ? stage_data.legend_done : res[1];
+ } else {
+ value.state_class = 'oe_kanban_status_red';
+ value.state_name = stage_data.legend_blocked ? stage_data.legend_blocked : res[1];
}
- if (res[0] == 'normal') { value.state_class = 'oe_kanban_status'; }
- else if (res[0] == 'done') { value.state_class = 'oe_kanban_status oe_kanban_status_green'; }
- else { value.state_class = 'oe_kanban_status oe_kanban_status_red'; }
- data.push(value);
+ _data.push(value);
});
- return data;
+ return _data;
},
renderElement: function() {
var self = this;
- this.states = this.prepare_dropdown_selection();
-
var state;
- for(var i = 0 ; i < this.states.length ; i++) {
- if(this.states[i].name === this.get('value')) {
- state = this.states[i];
- }
- }
+ self.states = this.prepare_dropdown_selection();
- this.$el = $(QWeb.render("KanbanSelection", {'widget': this}));
- this.$('a').first().find('span').removeClass().addClass(state.state_class);
- this.$('ul li').show().filter(function() {
- return ($(this).data('value') === state.name);
- }).hide();
-
- this.$('a').click(function (ev) {
- ev.preventDefault();
+ var current_state = _.find(this.states, function(state) {
+ return state.name === self.get('value');
});
- this.$('li').click(this.set_kanban_selection.bind(this));
+ self.$el = $(QWeb.render("KanbanSelection", {
+ current_state_class: current_state.state_class,
+ states: _.without(this.states, current_state)
+ }));
+ self.$('a').click(function (ev) {
+ ev.preventDefault();
+ });
+ self.$('a').click(self.set_kanban_selection.bind(self));
},
set_kanban_selection: function(e) {
e.preventDefault();
diff --git a/addons/web_kanban/static/src/xml/web_kanban.xml b/addons/web_kanban/static/src/xml/web_kanban.xml
index e07298e95b5..07663caa85b 100644
--- a/addons/web_kanban/static/src/xml/web_kanban.xml
+++ b/addons/web_kanban/static/src/xml/web_kanban.xml
@@ -84,4 +84,21 @@
+
+
+
+
+