diff --git a/addons/web_kanban/static/src/css/kanban.css b/addons/web_kanban/static/src/css/kanban.css index d7c27510f4d..03640ffff40 100644 --- a/addons/web_kanban/static/src/css/kanban.css +++ b/addons/web_kanban/static/src/css/kanban.css @@ -1,37 +1,71 @@ -.openerp .oe_kanban_view .oe_column { - width: 100%; -} - -.openerp .oe_vertical_text { - writing-mode:tb-rl; - -webkit-transform:rotate(90deg); - -moz-transform:rotate(90deg); - -o-transform: rotate(90deg); - -ms-transform: rotate(90deg); - transform: rotate(90deg); - display:block; - width:30px; - height:20px; - align:center; - font-size:24px; - white-space: nowrap; -} - .openerp .oe_kanban_view .ui-sortable-placeholder { border: 1px dotted black; visibility: visible !important; height: 60px !important; } +.openerp .oe_kanban_group_header { + position: relative; +} +.openerp .oe_kanban_group_folded { + padding: 0 5px 0 5px; +} +.openerp .oe_kanban_group_folded .oe_kanban_group_title, +.openerp .oe_kanban_group_folded .oe_kanban_aggregates { + display: none; +} +.openerp .oe_kanban_group_folded .oe_kanban_group_title_vertical { + display: block; +} -.openerp .oe_kanban_view .oe_column_heading { +.openerp .oe_kanban_group_title { color: #000000; font-size: 130%; font-weight: bold; } -.openerp .oe_kanban_view .fold-columns-icon { +.openerp .oe_kanban_group_title_undefined { + color: #666666; +} +.openerp .oe_kanban_group_title_vertical { + writing-mode: tb-rl; + -webkit-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -o-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); + width: 30px; + height: 20px; + align: center; + font-size: 24px; + white-space: nowrap; + display: none; + position: absolute; + top: 10px; +} + +.openerp .oe_kanban_fold_icon { + cursor: pointer; float: left; padding: 2px 2px 0 0; + width: 16px; + height: 16px; + background: url(/web_kanban/static/src/img/minus-icon.png) no-repeat; } +.openerp .oe_kanban_group_folded .oe_kanban_fold_icon { + background: url(/web_kanban/static/src/img/plus-icon.png) no-repeat; +} + +.openerp ul.oe_kanban_aggregates { + padding: 0; + margin: 0 0 0 22px; +} +.openerp ul.oe_kanban_aggregates li { + list-style: circle; + font-style: italic; +} +.openerp ul.oe_kanban_aggregates span { + text-decoration: underline; +} + .openerp .oe_kanban_action_button { height: 22px; margin: 0; diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index 13d3c9203fc..9ba02c48e9a 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -1,38 +1,59 @@ openerp.web_kanban = function (openerp) { +var _t = openerp.web._t; var QWeb = openerp.web.qweb; QWeb.add_template('/web_kanban/static/src/xml/web_kanban.xml'); openerp.web.views.add('kanban', 'openerp.web_kanban.KanbanView'); + openerp.web_kanban.KanbanView = openerp.web.View.extend({ + template: "KanbanView", + default_nr_columns: 3, init: function (parent, dataset, view_id, options) { this._super(parent); this.set_default_options(options); this.dataset = dataset; - this.model = dataset.model; this.view_id = view_id; this.fields_view = {}; - this.group_by = []; - this.source_index = {}; - this.all_display_data = false; + this.fields_keys = []; + this.group_by = null; + this.state = { + groups : {}, + records : {} + }; this.groups = []; + this.form_dialog = new openerp.web.FormDialog(this, {}, this.options.action_views_ids.form, dataset).start(); + this.form_dialog.on_form_dialog_saved.add_last(this.do_reload); + this.aggregates = {}; this.qweb = new QWeb2.Engine(); this.qweb.debug = (window.location.search.indexOf('?debug') !== -1); - this.aggregates = {}; - this.NO_OF_COLUMNS = 3; - this.form_dialog = new openerp.web.FormDialog(this, {}, this.options.action_views_ids.form, dataset).start(); - this.form_dialog.on_form_dialog_saved.add_last(this.on_record_saved); + this.qweb.default_dict = { + '_' : _, + '_t' : _t + } + this.has_been_loaded = $.Deferred(); + this.search_domain = this.search_context = this.search_group_by = null; + this.currently_dragging = {}; }, start: function() { this._super(); - return this.rpc("/web/view/load", {"model": this.model, "view_id": this.view_id, "view_type": "kanban"}, this.on_loaded); + this.$element.find('button.oe_kanban_button_new').click(this.do_add_record); + this.$groups = this.$element.find('.oe_kanban_groups tr'); + var context = new openerp.web.CompoundContext(this.dataset.get_context()); + return this.rpc('/web/view/load', { + 'model': this.dataset.model, + 'view_id': this.view_id, + 'view_type': 'kanban', + context: context + }, this.on_loaded); }, on_loaded: function(data) { - var self = this; this.fields_view = data; + this.fields_keys = _.keys(this.fields_view.fields); this.add_qweb_template(); + this.has_been_loaded.resolve(); }, add_qweb_template: function() { - var group_operator = ["avg", "max", "min", "sum", "count"] + var group_operator = ['avg', 'max', 'min', 'sum', 'count'] for (var i=0, ii=this.fields_view.arch.children.length; i < ii; i++) { var child = this.fields_view.arch.children[i]; if (child.tag === "field") { @@ -50,50 +71,6 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({ } } }, - get_qweb_context: function(record) { - return { - record: this.do_transform_record(record), - kanban_color: _.bind(this.kanban_color, this), - kanban_gravatar: _.bind(this.kanban_gravatar, this), - kanban_image: _.bind(this.kanban_image, this), - kanban_text_ellipsis: _.bind(this.kanban_text_ellipsis, this), - '_' : _ - } - }, - kanban_color: function(variable) { - var number_of_color_schemes = 10, - index = 0; - switch (typeof(variable)) { - case 'string': - for (var i=0, ii=variable.length; i 0) { - drag_handel = ".oe_kanban_draghandle"; - } - if (!this.group_by.length) { - drag_handel = true; - } - this.$element.find(".oe_column").sortable({ - connectWith: ".oe_column", - handle : drag_handel, - start: function(event, ui) { - self.source_index['index'] = ui.item.index(); - self.source_index['column'] = ui.item.parent().attr('id'); - }, - stop: self.on_receive_record, - scroll: false - }); - this.$element.find('button.oe_kanban_button_new').click(this.do_add_record); - this.$element.find(".fold-columns-icon").click(function(event) { - self.do_fold_unfold_columns(event, this.id); - }); - }, - do_fold_unfold_columns: function(event, element_id) { - var column_id = "column_" + element_id; - var column_element = this.$element.find("#" + column_id + " .oe_fold_column"); - if (column_element.is(":hidden")) { - this.$element.find("#" + column_id).find("img.fold-columns-icon").attr('src', '/web_kanban/static/src/img/minus-icon.png'); - column_element.show(); - this.$element.find("#" + column_id + ".oe_table_column").css("width",Math.round(99 / this.all_display_data.length) + "%"); - this.$element.find("#" + column_id + ".oe_vertical_text").hide(); - } - else{ - this.$element.find("#" + column_id).find("img.fold-columns-icon").attr('src', '/web_kanban/static/src/img/plus-icon.png'); - column_element.hide(); - this.$element.find("#" + column_id + ".oe_table_column").css("width","0.5%"); - this.$element.find("#" + column_id + ".oe_vertical_text").show(); - } - - }, - do_record_group: function() { - if (this.NO_OF_COLUMNS && this.all_display_data.length > 0) { - var records = this.all_display_data[0].records; - var record_per_group = Math.round((records).length / this.NO_OF_COLUMNS); - this.all_display_data = []; - for (var i=0, ii=this.NO_OF_COLUMNS; i < ii; i++) { - this.all_display_data.push({'records': records.slice(0,record_per_group), 'value':i, 'header' : false, 'ids':[]}); - records.splice(0,record_per_group); - } - } - }, - on_button_click: function (button_attrs, record_id) { - this.on_execute_button_click(this.dataset, button_attrs, record_id); - }, do_add_record: function() { this.dataset.index = null; this.do_switch_view('form'); }, - do_edit_record: function(record_id) { + do_search: function(domain, context, group_by) { var self = this; - this.form_dialog.select_id(record_id).then(function() { - self.form_dialog.open(); + this.search_domain = domain; + this.search_context = context; + this.search_group_by = group_by; + $.when(this.has_been_loaded).then(function() { + self.group_by = group_by.length ? group_by[0] : self.fields_view.arch.attrs.default_group_by; + self.datagroup = new openerp.web.DataGroup(self, self.dataset.model, domain, context, self.group_by ? [self.group_by] : []); + self.datagroup.list(self.fields_keys, self.do_process_groups, self.do_process_dataset); }); }, - on_record_saved: function(r) { - var id = this.form_dialog.form.datarecord.id; - this.on_reload_record(id); - }, - do_change_color: function(record_id, $e) { + do_process_groups: function(groups) { + this.do_clear_groups(); + this.dataset.ids = []; var self = this, - id = record_id, - colors = '#FFFFFF,#CCCCCC,#FFC7C7,#FFF1C7,#E3FFC7,#C7FFD5,#C7FFFF,#C7D5FF,#E3C7FF,#FFC7F1'.split(','), - $cpicker = $(QWeb.render('KanbanColorPicker', { colors : colors, columns: 2 })); - $e.after($cpicker); - $cpicker.mouseenter(function() { - clearTimeout($cpicker.data('timeoutId')); - }).mouseleave(function(evt) { - var timeoutId = setTimeout(function() { $cpicker.remove() }, 500); - $cpicker.data('timeoutId', timeoutId); - }); - $cpicker.find('a').click(function(evt) { - var data = {}; - data[$e.data('name')] = $(this).data('color'); - self.dataset.write(id, data, {}, function() { - self.on_reload_record(id); - }); - $cpicker.remove(); - return false; - }); - }, - /** - Reload one record in view. - record_id : reload record id. - */ - on_reload_record: function (record_id){ - var self = this; - this.dataset.read_ids([record_id], _.keys(self.fields_view.fields), function (records) { - if (records.length > 0) { - for (var i=0, ii=self.all_display_data.length; i < ii; i++) { - for(j=0, jj=self.all_display_data[i].records.length; j < jj; j++) { - if (self.all_display_data[i].records[j].id == record_id) { - _.extend(self.all_display_data[i].records[j], records[0]); - self.$element.find("#main_" + record_id).children().remove(); - self.$element.find("#main_" + record_id).append( - self.qweb.render('kanban-box', self.get_qweb_context(self.all_display_data[i].records[j])) - ); - break; - } - } - } - self.$element.find("#main_" + record_id + " .oe_kanban_action").click(self.on_action_clicked); - self.$element.find("#main_" + record_id + " .oe_kanban_box_show_onclick_trigger").click(function() { - $(this).parent("#main_" + record_id + " .oe_kanban_box").find(".oe_kanban_box_show_onclick").toggle(); - }); - } - }); - - }, - do_delete: function (id) { - var self = this; - return $.when(this.dataset.unlink([id])).then(function () { - self.drop_records(id); - }); - }, - drop_records: function (id) { - var self = this; - _.each(self.all_display_data, function(data, index) { - _.each(data.records, function(record, index_row) { - if (parseInt(record.id) == id) { - self.all_display_data[index]['records'].splice(index_row, 1); - self.all_display_data[index]['ids'].splice(index_row, 1); - return false; - } - }); - }); - self.$element.find("#main_" + id).remove(); - }, - on_execute_button_click: function (dataset, button_attrs, record_id) { - var self = this; - this.do_execute_action( - button_attrs, dataset, - record_id, function () { - self.on_reload_record(record_id); - } - ); - }, - on_receive_record: function (event, ui) { - var self = this; - var from = ui.item.index(); - var search_action = false; - var to = ui.item.prev().index() || 0; - if (!ui.item.attr("id")) { - return false; - } - if (self.fields_view.fields.sequence != undefined && ((self.source_index.index >= 0 && self.source_index.index != from) || - (self.source_index.column && self.source_index.column != ui.item.parent().attr('id')))) { - var child_record = ui.item.parent().children(); - var data, sequence = 1, index = to; - child_record.splice(0, to); - var flag = false; - if (to >= 0 && child_record) { - var record_id = parseInt($(child_record).attr("id").split("_")[1]); - if (record_id) { - _.each(self.all_display_data, function(data, index) { - _.each(data.records, function(record, index_row) { - if(record_id == record.id && record.sequence) { - sequence = record.sequence; - flag = true; - return false; - } - }); - if(flag) {return false;} - }); - } - } - _.each(child_record, function (child) { - var child_id = parseInt($(child).attr("id").split("_")[1]); - if (child_id) { - flag = false; - _.each(self.all_display_data, function(data, index) { - _.each(data.records, function(record, index_row) { - if(parseInt(record.id) == child_id) { - self.all_display_data[index]['records'][index_row]['sequence'] = sequence; - flag = true; - return false; - } - }); - if (flag) {return false;} - }); - self.dataset.write(child_id, {sequence: sequence}); - sequence++; - search_action = true; - } - }); - } - if (self.group_by.length > 0 && self.source_index.column && self.source_index.column != ui.item.parent().attr('id')) { - var value = ui.item.closest("td").attr("id"); - if (value) { - var data_val = {}; - var wirte_id = parseInt(ui.item.attr("id").split("_")[1]); - value = value.split("_")[1]; - if (value == 'false') { - value = false; - } - var update_record = false; - _.each(self.all_display_data, function(data, index) { - _.each(data.records, function(record, index_row) { - if(parseInt(record.id) == wirte_id) { - self.all_display_data[index]['records'][index_row][self.group_by[0]] = value; - update_record = self.all_display_data[index]['records'].splice(index_row,1) - return false; - } - }); - if (update_record) {return false;} - }); - _.each(self.all_display_data, function(data, index) { - if (data.value == value || (data.value == 'false' && value == false)) { - self.all_display_data[index]['records'].push(update_record[0]); - } - }); - data_val[self.group_by[0]] = value; - self.dataset.write(wirte_id, data_val); - search_action = true; - } - } - if (search_action) { - self.on_reload_kanban(); - } - this.source_index = {}; - }, - on_reload_kanban: function() { - var self = this; - _.each(self.all_display_data, function(data, index) { - if (data.records.length > 0){ - _.each(data.records, function(record) { - self.$element.find("#main_" + record.id).children().remove(); - self.$element.find("#main_" + record.id).append( - self.qweb.render('kanban-box', self.get_qweb_context(record)) - ); - }); - } - }); - this.$element.find('.oe_kanban_action').click(this.on_action_clicked); - this.$element.find('.oe_kanban_box_show_onclick_trigger').click(function() { - $(this).parent('.oe_kanban_box').find('.oe_kanban_box_show_onclick').toggle(); - }); - }, - on_action_clicked: function(evt) { - evt.preventDefault(); - var $action = $(evt.currentTarget), - record_id = parseInt($action.closest(".oe_kanban_record").attr("id").split('_')[1]), - type = $action.data('type'); - if (type == 'delete') { - this.do_delete(record_id); - } else if (type == 'edit') { - this.do_edit_record(record_id); - } else if (type == 'color') { - this.do_change_color(record_id, $action); - } else { - var button_attrs = $action.data(); - this.on_button_click(button_attrs, record_id); - } - }, - do_transform_record: function(record) { - var self = this, - new_record = {}; - _.each(record, function(value, name) { - var r = _.clone(self.fields_view.fields[name]); - r.raw_value = value; - r.value = openerp.web.format_value(value, r); - new_record[name] = r; - }); - return new_record; - }, - do_search: function (domain, context, group_by) { - var self = this; - self.group_by = group_by; - var self = this, - group_by = self.group_by; - if (!group_by.length && this.fields_view.arch.attrs.default_group_by) { - group_by = [this.fields_view.arch.attrs.default_group_by]; - self.group_by = group_by; - } - self.datagroup = new openerp.web.DataGroup(self, self.model, domain, context, group_by); - self.datagroup.list( - _.keys(self.fields_view.fields), - function (groups) { - self.dataset.ids = []; - self.groups = groups; - if (groups.length) { - self.do_render_group(groups); - } else { - self.all_display_data = []; - self.on_show_data(); - } - }, - function (dataset) { - self.groups = []; - self.dataset.read_slice(_.keys(self.fields_view.fields), {}, function(records) { - if (records.length) { - self.all_display_data = [{'records': records, 'value':false, 'header' : false, 'ids': self.dataset.ids}]; - } else { - self.all_display_data = []; - } - self.$element.find(".oe_kanban_view").remove(); - self.on_show_data(); - }); - } - ); - }, - do_render_group : function (datagroups) { - this.all_display_data = []; - var self = this, - remaining = datagroups.length - 1; - _.each(datagroups, function (group, index) { - var group_name = group.value; - var group_value = group.value; - if (!group.value) { - group_name = "Undefined"; - group_value = 'false'; - } else if (group.value instanceof Array) { + remaining = groups.length - 1, + groups_array = []; + _.each(groups, function (group, index) { + var group_name = group.value, + group_value = group.value, + group_aggregates = {}; + if (group.value instanceof Array) { group_name = group.value[1]; group_value = group.value[0]; } - var group_aggregates = {}; _.each(self.aggregates, function(value, key) { group_aggregates[value] = group.aggregates[key]; }); var dataset = new openerp.web.DataSetSearch(self, self.dataset.model, group.context, group.domain); - self.$element.find(".oe_kanban_view").remove(); - dataset.read_slice(_.keys(self.fields_view.fields), {'domain': group.domain, 'context': group.context}, function(records) { + dataset.read_slice(self.fields_keys, {'domain': group.domain, 'context': group.context}, function(records) { self.dataset.ids.push.apply(self.dataset.ids, dataset.ids); - self.all_display_data[index] = {"value" : group_value, "records" : records, 'header' : group_name, 'ids' : dataset.ids, 'aggregates' : group_aggregates}; + groups_array[index] = new openerp.web_kanban.KanbanGroup(self, records, group_value, group_name, group_aggregates); if (!remaining--) { self.dataset.index = self.dataset.ids.length ? 0 : null; - self.on_show_data(); + self.do_add_groups(groups_array); } }); }); }, + do_process_dataset: function(dataset) { + var self = this; + this.do_clear_groups(); + this.dataset.read_slice(this.fields_keys, {}, function(records) { + var groups = []; + while (records.length) { + for (var i = 0; i < self.default_nr_columns; i++) { + if (!groups[i]) { + groups[i] = []; + } + groups[i].push(records.shift()); + } + } + for (var i = 0; i < groups.length; i++) { + groups[i] = new openerp.web_kanban.KanbanGroup(self, _.compact(groups[i])); + } + self.do_add_groups(groups); + }); + }, + do_reload: function() { + this.do_search(this.search_domain, this.search_context, this.search_group_by); + }, + do_clear_groups: function() { + _.each(this.groups, function(group) { + group.stop(); + }); + this.groups = []; + this.$element.find('.oe_kanban_groups_headers, .oe_kanban_groups_records').empty(); + }, + do_add_groups: function(groups) { + var self = this; + _.each(groups, function(group) { + self.groups[group.undefined_title ? 'unshift' : 'push'](group); + }); + _.each(this.groups, function(group) { + group.appendTo(self.$element.find('.oe_kanban_groups_headers')); + }); + this.on_groups_started(); + }, + on_groups_started: function() { + var self = this; + this.compute_groups_width(); + if (this.group_by) { + this.$element.find('.oe_kanban_column').sortable({ + connectWith: '.oe_kanban_column', + handle : '.oe_kanban_draghandle', + start: function(event, ui) { + self.currently_dragging.index = ui.item.index(); + self.currently_dragging.group = ui.item.parents('.oe_kanban_column:first').data('widget'); + }, + stop: function(event, ui) { + var record = ui.item.data('widget'), + old_index = self.currently_dragging.index, + new_index = ui.item.index(), + old_group = self.currently_dragging.group, + new_group = ui.item.parents('.oe_kanban_column:first').data('widget'); + if (!(old_group.title === new_group.title && old_group.value === new_group.value && old_index == new_index)) { + self.on_record_moved(record, old_group, old_index, new_group, new_index); + } + }, + scroll: false + }); + } else { + this.$element.find('.oe_kanban_draghandle').removeClass('oe_kanban_draghandle'); + } + }, + on_record_moved : function(record, old_group, old_index, new_group, new_index) { + if (old_group === new_group) { + new_group.records.splice(old_index, 1); + new_group.records.splice(new_index, 0, record); + new_group.do_save_sequences(); + } else { + old_group.records.splice(old_index, 1); + new_group.records.splice(new_index, 0, record); + record.group = new_group; + var data = {}; + data[this.group_by] = new_group.value; + this.dataset.write(record.id, data, {}, function() { + record.do_reload(); + new_group.do_save_sequences(); + }); + } + }, do_show: function () { this.$element.show(); }, do_hide: function () { this.$element.hide(); + }, + compute_groups_width: function() { + var unfolded = 0; + _.each(this.groups, function(group) { + unfolded += group.state.folded ? 0 : 1; + group.$element.css('width', ''); + }); + _.each(this.groups, function(group) { + if (!group.state.folded) { + group.$element.css('width', Math.round(100/unfolded) + '%'); + } + }); + } +}); + +openerp.web_kanban.KanbanGroup = openerp.web.Widget.extend({ + template: 'KanbanView.group_header', + init: function (parent, records, value, title, aggregates) { + var self = this; + this._super(parent); + this.view = parent; + this.value = value; + this.title = title; + if (title === false) { + this.title = _t('Undefined'); + this.undefined_title = true; + } + this.aggregates = aggregates || {}; + var key = this.view.group_by + '-' + value; + if (!this.view.state.groups[key]) { + this.view.state.groups[key] = { + folded: false + } + } + this.state = this.view.state.groups[key]; + this.$records = null; + this.records = _.map(records, function(record) { + return new openerp.web_kanban.KanbanRecord(self, record); + }); + }, + start: function() { + var self = this, + def = this._super(); + this.$records = $(QWeb.render('KanbanView.group_records_container', { widget : this})); + this.$records.appendTo(this.view.$element.find('.oe_kanban_groups_records')); + _.each(this.records, function(record) { + record.appendTo(self.$records); + }); + this.$element.find(".oe_kanban_fold_icon").click(function() { + self.do_toggle_fold(); + self.view.compute_groups_width(); + return false; + }); + if (this.state.folded) { + this.do_toggle_fold(); + } + this.$element.data('widget', this); + this.$records.data('widget', this); + return def; + }, + stop: function() { + this._super(); + if (this.$records) { + this.$records.remove(); + } + }, + remove_record: function(id, remove_from_dataset) { + for (var i = 0, ii = this.records.length; i < ii; i++) { + if (this.records[i]['id'] === id) { + this.records.splice(i, 1); + } + } + }, + do_toggle_fold: function(compute_width) { + this.$element.toggleClass('oe_kanban_group_folded'); + this.$records.find('.oe_kanban_record').toggle(); + this.state.folded = this.$element.is('.oe_kanban_group_folded'); + }, + do_save_sequences: function() { + var self = this; + if (_.indexOf(this.view.fields_keys, 'sequence') > -1) { + _.each(this.records, function(record, index) { + self.view.dataset.write(record.id, { sequence : index }); + }); + } + } +}); + +openerp.web_kanban.KanbanRecord = openerp.web.Widget.extend({ + template: 'KanbanView.record', + init: function (parent, record) { + this._super(parent); + this.group = parent; + this.view = parent.view; + this.id = null; + this.set_record(record); + if (!this.view.state.records[this.id]) { + this.view.state.records[this.id] = { + folded: false + }; + } + this.state = this.view.state.records[this.id]; + }, + set_record: function(record) { + this.id = record.id; + this.record = this.transform_record(record); + }, + start: function() { + this._super(); + this.$element.data('widget', this); + this.bind_events(); + }, + transform_record: function(record) { + var self = this, + new_record = {}; + _.each(record, function(value, name) { + var r = _.clone(self.view.fields_view.fields[name]); + r.raw_value = value; + r.value = openerp.web.format_value(value, r); + new_record[name] = r; + }); + return new_record; + }, + render: function() { + var ctx = { + record: this.record, + widget: this + } + for (var p in this) { + if (_.startsWith(p, 'kanban_')) { + ctx[p] = _.bind(this[p], this); + } + } + return this._super({ + 'content': this.view.qweb.render('kanban-box', ctx) + }); + }, + bind_events: function() { + var self = this, + $show_on_click = self.$element.find('.oe_kanban_box_show_onclick'); + $show_on_click.toggle(this.state.folded); + this.$element.find('.oe_kanban_box_show_onclick_trigger').click(function() { + $show_on_click.toggle(); + self.state.folded = !self.state.folded; + }); + this.$element.find('.oe_kanban_action').click(function() { + var $action = $(this), + type = $action.data('type') || 'button', + method = 'do_action_' + type; + if (typeof self[method] === 'function') { + self[method]($action); + } else { + self.do_warn("Kanban: no action for type : " + type); + } + return false; + }); + }, + do_action_delete: function($action) { + var self = this; + if (confirm(_t("Are you sure you want to delete this record ?"))) { + return $.when(this.view.dataset.unlink([this.id])).then(function() { + self.group.remove_record(self.id) + self.stop(); + }); + } + }, + do_action_edit: function($action) { + var self = this; + if ($action.attr('target') === 'dialog') { + this.view.form_dialog.select_id(this.id).then(function() { + self.view.form_dialog.open(); + }); + } else { + if (self.view.dataset.select_id(this.id)) { + this.view.do_switch_view('form'); + } else { + this.do_warn("Kanban: could not find id#" + id); + } + } + }, + do_action_color: function($action) { + var self = this, + colors = '#FFFFFF,#CCCCCC,#FFC7C7,#FFF1C7,#E3FFC7,#C7FFD5,#C7FFFF,#C7D5FF,#E3C7FF,#FFC7F1'.split(','), + $cpicker = $(QWeb.render('KanbanColorPicker', { colors : colors, columns: 2 })); + $action.after($cpicker); + $cpicker.mouseenter(function() { + clearTimeout($cpicker.data('timeoutId')); + }).mouseleave(function(evt) { + var timeoutId = setTimeout(function() { $cpicker.remove() }, 500); + $cpicker.data('timeoutId', timeoutId); + }); + $cpicker.find('a').click(function() { + var data = {}; + data[$action.data('name')] = $(this).data('color'); + self.view.dataset.write(self.id, data, {}, function() { + self.record[$action.data('name')] = $(this).data('color'); + self.do_reload(); + }); + $cpicker.remove(); + return false; + }); + }, + do_action_object: function ($action) { + var button_attrs = $action.data(); + this.view.do_execute_action(button_attrs, this.view.dataset, this.id, this.do_reload); + }, + do_reload: function() { + var self = this; + this.view.dataset.read_ids([this.id], this.view.fields_keys, function(records) { + if (records.length) { + self.set_record(records[0]); + self.do_render(); + } else { + self.stop(); + } + }); + }, + do_render: function() { + this.$element.html(this.render()); + this.bind_events(); + }, + kanban_color: function(variable) { + var number_of_color_schemes = 10, + index = 0; + switch (typeof(variable)) { + case 'string': + for (var i=0, ii=variable.length; i - - - - - - - - - - -
-
- -
-
- -
-
- -
-
- : +
+ +
+
+ + + + + +
+
+ + +
+ +
+
+
+
+
    +
  • + : +
  • +
-
-

-
-
+

+
+ + + + + + + +
+ +