diff --git a/CHANGELOG b/CHANGELOG index adf01abb40..4b8310003f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,2 +1,4 @@ +* Add Note + Version 3.8.0 - 2015-11-02 * Initial release diff --git a/src/model.js b/src/model.js index cda2f09334..f7eed4cde0 100644 --- a/src/model.js +++ b/src/model.js @@ -451,6 +451,7 @@ this.fields = {}; this._timestamp = null; this.attachment_count = -1; + this.unread_note = -1; this.state_attrs = {}; this.autocompletion = {}; this.exception = false; @@ -1188,6 +1189,28 @@ prm.resolve(this.attachment_count); } return prm; + }, + get_unread_note: function(reload) { + var prm = jQuery.Deferred(); + if (this.id < 0) { + prm.resolve(0); + return prm; + } + if ((this.unread_note < 0) || reload) { + prm = Sao.rpc({ + method: 'model.ir.note.search_count', + params: [ + [['resource', '=', this.model.name + ',' + this.id], + ['unread', '=', true]], + this.get_context()] + }, this.model.session).then(function(count) { + this.unread_note = count; + return count; + }.bind(this)); + } else { + prm.resolve(this.unread_note); + } + return prm; } }); diff --git a/src/sao.less b/src/sao.less index 52d4d4c206..9d8fef5b5f 100644 --- a/src/sao.less +++ b/src/sao.less @@ -91,6 +91,9 @@ button { white-space: nowrap; text-overflow: ellipsis; } + & td > .column-text { + white-space: pre; + } & .expander { cursor: pointer; } diff --git a/src/screen.js b/src/screen.js index 378fde489a..0114dec298 100644 --- a/src/screen.js +++ b/src/screen.js @@ -796,8 +796,11 @@ if (record) { record.get_attachment_count().always( this.tab.attachment_count.bind(this.tab)); + record.get_unread_note().always( + this.tab.update_unread_note.bind(this.tab)); } else { this.tab.attachment_count(0); + this.tab.update_unread_note(0); } this.tab.record_message(); } diff --git a/src/tab.js b/src/tab.js index 068d4ab499..73ba60d8c4 100644 --- a/src/tab.js +++ b/src/tab.js @@ -330,7 +330,10 @@ Sao.i18n.gettext('Next Record'), 'next'], ['attach', 'glyphicon-paperclip', Sao.i18n.gettext('Attachment'), - Sao.i18n.gettext('Add an attachment to the record'), 'attach'] + Sao.i18n.gettext('Add an attachment to the record'), 'attach'], + ['note', 'glyphicon-comment', + Sao.i18n.gettext('Note'), + Sao.i18n.gettext('Add a note to the record'), 'note'] ]; }, menu_def: function() { @@ -353,6 +356,7 @@ ['glyphicon-remove', Sao.i18n.gettext('Close Tab'), 'close'], ['glyphicon-paperclip', Sao.i18n.gettext('Attachment'), 'attach'], + ['glyphicon-comment', Sao.i18n.gettext('Note'), 'note'], ['glyphicon-cog', Sao.i18n.gettext('Action'), 'action'], ['glyphicon-share-alt', Sao.i18n.gettext('Relate'), 'relate'], ['glyphicon-print', Sao.i18n.gettext('Print'), 'print'] @@ -745,6 +749,31 @@ this.buttons.attach.prop('disabled', record_id < 0 || record_id === null); }, + note: function() { + var record = this.screen.current_record; + if (!record || (record.id < 0)) { + return; + } + new Sao.Window.Note(record, function() { + this.update_unread_note(true); + }.bind(this)); + }, + update_unread_note: function(reload) { + var record = this.screen.current_record; + if (record) { + record.get_unread_note(reload).always( + this._unread_note.bind(this)); + } else { + this._unread_note(0); + } + }, + _unread_note: function(unread) { + var label = Sao.i18n.gettext('Note(%1)', unread); + this.buttons.note.text(label); + var record_id = this.screen.get_id(); + this.buttons.note.prop('disabled', + record_id < 0 || record_id === null); + }, record_message: function() { this.info_bar.message(); }, @@ -826,6 +855,8 @@ } }, attachment_count: function() { + }, + note: function() { } }); diff --git a/src/view/tree.js b/src/view/tree.js index 697940870a..7555d3ac1e 100644 --- a/src/view/tree.js +++ b/src/view/tree.js @@ -6,8 +6,9 @@ Sao.View.tree_column_get = function(type) { switch (type) { case 'char': - case 'text': return Sao.View.Tree.CharColumn; + case 'text': + return Sao.View.Tree.TextColum; case 'many2one': return Sao.View.Tree.Many2OneColumn; case 'one2one': @@ -1258,6 +1259,10 @@ } }); + Sao.View.Tree.TextColum = Sao.class_(Sao.View.Tree.CharColumn, { + class_: 'column-text' + }); + Sao.View.Tree.IntegerColumn = Sao.class_(Sao.View.Tree.CharColumn, { class_: 'column-integer', init: function(model, attributes) { diff --git a/src/window.js b/src/window.js index bab5f154bf..daee922a94 100644 --- a/src/window.js +++ b/src/window.js @@ -409,6 +409,46 @@ } }); + Sao.Window.Note = Sao.class_(Sao.Window.Form, { + init: function(record, callback) { + this.resource = record.model.name + ',' + record.id; + this.note_callback = callback; + var context = record.get_context(); + context.resource = this.resource; + var screen = new Sao.Screen('ir.note', { + domain: [['resource', '=', this.resource]], + mode: ['tree', 'form'], + context: context, + exclude_field: 'resource' + }); + screen.switch_view().done(function() { + screen.search_filter(); + screen.group.parent = record; + }); + Sao.Window.Note._super.init.call(this, screen, this.callback, + {view_type: 'tree'}); + }, + callback: function(result) { + var prm = jQuery.when(); + if (result) { + var resource = this.screen.group.model.fields.resource; + var unread = this.screen.group.model.fields.unread; + this.screen.group.forEach(function(record) { + if (record.get_loaded()) { + resource.set_client(record, this.resource); + if (!record._changed.unread) { + unread.set_client(record, false); + } + } + }.bind(this)); + prm = this.screen.group.save(); + } + if (this.note_callback) { + prm.always(this.note_callback.bind(this)); + } + } + }); + Sao.Window.Search = Sao.class_(Object, { init: function(model, callback, kwargs) { kwargs = kwargs || {};