2012-08-10 13:05:42 +00:00
openerp _mail _followers = function ( session , mail ) {
var _t = session . web . _t ,
_lt = session . web . _lt ;
var mail _followers = session . mail _followers = { } ;
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2012-08-15 23:26:49 +00:00
* mail _followers Widget
2012-08-10 13:05:42 +00:00
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
*
2012-09-04 13:36:48 +00:00
* This widget handles the display of a list of records as a vertical
2012-08-15 23:26:49 +00:00
* list , with an image on the left . The widget itself is a floatting
* right - sided box .
* This widget is mainly used to display the followers of records
* in OpenChatter .
2012-08-10 13:05:42 +00:00
* /
2012-08-15 23:26:49 +00:00
/* Add the widget to registry */
2012-08-10 13:05:42 +00:00
session . web . form . widgets . add ( 'mail_followers' , 'openerp.mail_followers.Followers' ) ;
mail _followers . Followers = session . web . form . AbstractField . extend ( {
template : 'mail.followers' ,
2012-08-15 23:26:49 +00:00
init : function ( ) {
2012-08-10 13:05:42 +00:00
this . _super . apply ( this , arguments ) ;
2012-10-24 15:20:43 +00:00
this . image = this . node . attrs . image || 'image_small' ;
this . comment = this . node . attrs . help || false ;
2012-12-20 15:29:06 +00:00
this . displayed _limit = this . node . attrs . displayed _nb || 10 ;
this . displayed _nb = this . displayed _limit ;
2012-08-13 16:00:27 +00:00
this . ds _model = new session . web . DataSetSearch ( this , this . view . model ) ;
this . ds _follow = new session . web . DataSetSearch ( this , this . field . relation ) ;
2012-10-18 09:13:27 +00:00
this . ds _users = new session . web . DataSetSearch ( this , 'res.users' ) ;
2012-11-08 15:33:27 +00:00
this . value = [ ] ;
2012-12-20 15:29:06 +00:00
this . followers = [ ] ;
2012-12-21 10:26:49 +00:00
this . view _is _editable = this . _ _parentedParent . is _action _enabled ( 'edit' ) ;
2012-08-10 13:05:42 +00:00
} ,
2012-08-15 23:26:49 +00:00
2012-08-10 13:05:42 +00:00
start : function ( ) {
2012-09-12 13:36:27 +00:00
// use actual_mode property on view to know if the view is in create mode anymore
2012-11-20 16:24:34 +00:00
this . view . on ( "change:actual_mode" , this , this . on _check _visibility _mode ) ;
this . on _check _visibility _mode ( ) ;
2012-08-10 13:05:42 +00:00
this . reinit ( ) ;
2012-09-13 16:03:29 +00:00
this . bind _events ( ) ;
2012-10-19 12:06:48 +00:00
this . _super ( ) ;
2012-08-10 13:05:42 +00:00
} ,
2012-08-15 23:26:49 +00:00
2012-11-20 16:24:34 +00:00
on _check _visibility _mode : function ( ) {
this . set ( { "force_invisible" : this . view . get ( "actual_mode" ) == "create" } ) ;
} ,
2012-11-08 15:33:27 +00:00
set _value : function ( _value ) {
this . value = _value ;
this . _super ( _value ) ;
} ,
2012-08-10 13:05:42 +00:00
reinit : function ( ) {
2012-09-18 09:12:12 +00:00
this . message _is _follower == undefined ;
this . display _buttons ( ) ;
2012-08-10 13:05:42 +00:00
} ,
2012-08-15 23:26:49 +00:00
2012-09-12 13:36:27 +00:00
bind _events : function ( ) {
var self = this ;
2012-10-18 09:13:27 +00:00
// event: click on '(Un)Follow' button, that toggles the follow for uid
this . $ ( '.oe_follower' ) . on ( 'click' , function ( event ) {
2012-10-16 11:17:53 +00:00
if ( $ ( this ) . hasClass ( 'oe_notfollow' ) )
self . do _follow ( ) ;
else
self . do _unfollow ( ) ;
} ) ;
2012-10-18 09:13:27 +00:00
// event: click on a subtype, that (un)subscribe for this subtype
2012-10-24 15:20:43 +00:00
this . $el . on ( 'click' , '.oe_subtype_list input' , self . do _update _subscription ) ;
2012-10-18 09:13:27 +00:00
// event: click on 'invite' button, that opens the invite wizard
2012-12-20 14:09:46 +00:00
this . $ ( '.oe_invite' ) . on ( 'click' , self . on _invite _follower ) ;
2013-03-05 12:54:42 +00:00
this . $el . on ( 'click' , '.oe_edit_subtype' , self . on _edit _subtype ) ;
2012-12-20 14:09:46 +00:00
this . $el . on ( 'click' , '.oe_remove_follower' , self . on _remove _follower ) ;
2012-12-20 15:29:06 +00:00
this . $el . on ( 'click' , '.oe_show_more' , self . on _show _more _followers )
2012-12-20 14:09:46 +00:00
} ,
2013-03-14 10:29:49 +00:00
on _edit _subtype : function ( event ) {
2013-03-05 12:54:42 +00:00
var self = this ;
2013-03-14 10:29:49 +00:00
var records = [ ] ;
var partner _id = $ ( event . target ) . data ( 'id' ) ;
2013-03-14 13:41:22 +00:00
var partner _name = $ ( event . target ) . siblings ( 'a' ) . text ( ) ;
2013-03-14 10:29:49 +00:00
var id = this . view . datarecord . id ;
var res _model = this . view . dataset . model ;
2013-03-15 12:31:57 +00:00
var $dialog = new session . web . dialog ( $ ( '<div class = "oe_edit_actions">' ) , {
2013-03-14 10:29:49 +00:00
modal : true ,
2013-03-14 13:41:22 +00:00
title : _t ( 'Edit Subtypes of ' ) + '"' + partner _name + '"' ,
2013-03-14 10:29:49 +00:00
buttons : [
2013-03-15 08:52:45 +00:00
{ text : _t ( "Apply" ) , click : function ( ) {
self . on _apply _subtype ( id , partner _id ) ;
2013-03-19 07:33:19 +00:00
$ ( this ) . remove ( ) ;
2013-03-15 08:52:45 +00:00
} } ,
2013-03-19 07:33:19 +00:00
{ text : _t ( "Cancel" ) , click : function ( ) { $ ( this ) . remove ( ) ; } }
2013-03-14 10:29:49 +00:00
] ,
} ) ;
2013-03-15 08:52:45 +00:00
this . ds _model . call ( 'edit_followers_subtype' , [ [ id ] , partner _id , new session . web . CompoundContext ( this . build _context ( ) , { } ) ] )
2013-03-14 10:29:49 +00:00
. then ( function ( data ) {
if ( data [ id ] ) {
records = data [ id ] . message _subtype _data ;
}
_ ( records ) . each ( function ( record , record _name ) {
record . name = record _name ;
record . followed = record . followed || undefined ;
2013-03-14 13:41:22 +00:00
$ ( session . web . qweb . render ( "mail.followers.edit.subtype" , { 'record' : record } ) ) . appendTo ( $dialog ) ;
2013-03-14 10:29:49 +00:00
} ) ;
} ) ;
2013-03-15 08:52:45 +00:00
} ,
2013-03-14 10:29:49 +00:00
2013-03-15 08:52:45 +00:00
on _apply _subtype : function ( id , partner _id ) {
2013-03-15 12:31:57 +00:00
var check _list = new Array ( ) ;
2013-03-15 12:48:43 +00:00
_ ( $ ( '.oe_edit_actions input[type="checkbox"]' ) ) . each ( function ( record ) {
if ( $ ( record ) . is ( ':checked' ) ) {
check _list . push ( parseInt ( $ ( record ) . data ( 'id' ) ) ) ;
2013-03-15 12:31:57 +00:00
}
2013-03-15 08:52:45 +00:00
} ) ;
2013-03-15 12:31:57 +00:00
if ( ! check _list . length ) {
2013-03-15 08:52:45 +00:00
this . do _unfollow ( ) ;
} else {
2013-03-15 12:31:57 +00:00
return this . ds _model . call ( 'apply_edited_subtypes' , [ [ id ] , partner _id , check _list , new session . web . CompoundContext ( this . build _context ( ) , { } ) ] )
2013-03-15 08:52:45 +00:00
. then ( this . proxy ( 'read_value' ) ) ;
2013-03-05 12:54:42 +00:00
}
} ,
2012-12-20 14:09:46 +00:00
on _invite _follower : function ( event ) {
var self = this ;
var action = {
type : 'ir.actions.act_window' ,
res _model : 'mail.wizard.invite' ,
view _mode : 'form' ,
view _type : 'form' ,
views : [ [ false , 'form' ] ] ,
target : 'new' ,
context : {
'default_res_model' : this . view . dataset . model ,
'default_res_id' : this . view . datarecord . id ,
} ,
}
this . do _action ( action , {
on _close : function ( ) {
self . read _value ( ) ;
} ,
2012-09-12 13:36:27 +00:00
} ) ;
} ,
2012-12-20 15:29:06 +00:00
on _show _more _followers : function ( event ) {
this . displayed _nb += this . displayed _limit ;
this . display _followers ( false ) ;
} ,
2012-12-20 14:09:46 +00:00
on _remove _follower : function ( event ) {
var partner _id = $ ( event . target ) . data ( 'id' ) ;
2013-02-14 15:09:49 +00:00
var name = $ ( event . target ) . parent ( ) . find ( "a" ) . html ( ) ;
if ( confirm ( _ . str . sprintf ( _t ( "Warning! \n %s won't be notified of any email or discussion on this document. Do you really want to remove him from the followers ?" ) , name ) ) ) {
var context = new session . web . CompoundContext ( this . build _context ( ) , { } ) ;
return this . ds _model . call ( 'message_unsubscribe' , [ [ this . view . datarecord . id ] , [ partner _id ] , context ] )
. then ( this . proxy ( 'read_value' ) ) ;
}
2012-12-20 14:09:46 +00:00
} ,
2012-10-18 09:13:27 +00:00
read _value : function ( ) {
2012-09-12 13:36:27 +00:00
var self = this ;
2012-12-20 15:29:06 +00:00
this . displayed _nb = this . displayed _limit ;
2012-11-08 14:22:30 +00:00
return this . ds _model . read _ids ( [ this . view . datarecord . id ] , [ 'message_follower_ids' ] ) . then ( function ( results ) {
2012-11-08 15:33:27 +00:00
self . value = results [ 0 ] . message _follower _ids ;
self . render _value ( ) ;
2012-09-20 11:49:09 +00:00
} ) ;
2012-08-10 13:05:42 +00:00
} ,
2012-08-15 23:26:49 +00:00
2012-10-18 09:13:27 +00:00
render _value : function ( ) {
2012-09-24 09:56:16 +00:00
this . reinit ( ) ;
2012-11-08 15:33:27 +00:00
return this . fetch _followers ( this . value ) ;
2012-08-10 13:05:42 +00:00
} ,
2012-08-15 23:26:49 +00:00
2012-09-25 08:58:09 +00:00
fetch _followers : function ( value _ ) {
this . value = value _ || { } ;
2012-10-18 09:13:27 +00:00
return this . ds _follow . call ( 'read' , [ this . value , [ 'name' , 'user_ids' ] ] )
2012-11-08 14:22:30 +00:00
. then ( this . proxy ( 'display_followers' ) , this . proxy ( 'fetch_generic' ) )
. then ( this . proxy ( 'display_buttons' ) )
2013-03-15 12:31:57 +00:00
. then ( this . proxy ( 'fetch_subtypes' ) ) ;
2012-09-17 15:01:29 +00:00
} ,
2012-10-18 09:13:27 +00:00
/ * * R e a d o n r e s . p a r t n e r f a i l e d : f a l l b a c k o n a g e n e r i c c a s e
- fetch current user partner _id ( call because no other smart solution currently ) FIXME
- then display a generic message about followers * /
fetch _generic : function ( error , event ) {
var self = this ;
2012-09-17 15:01:29 +00:00
event . preventDefault ( ) ;
2012-11-08 14:22:30 +00:00
return this . ds _users . call ( 'read' , [ this . session . uid , [ 'partner_id' ] ] ) . then ( function ( results ) {
2012-10-18 09:13:27 +00:00
var pid = results [ 'partner_id' ] [ 0 ] ;
2012-11-08 15:33:27 +00:00
self . message _is _follower = ( _ . indexOf ( self . value , pid ) != - 1 ) ;
2012-11-08 14:22:30 +00:00
} ) . then ( self . proxy ( 'display_generic' ) ) ;
2012-10-18 09:13:27 +00:00
} ,
2012-10-26 09:58:21 +00:00
_format _followers : function ( count ) {
2012-10-29 11:21:17 +00:00
// TDE note: why redefining _t ?
function _t ( str ) { return str ; }
2012-10-26 09:58:21 +00:00
var str = '' ;
if ( count <= 0 ) {
str = _t ( 'No followers' ) ;
} else if ( count === 1 ) {
str = _t ( 'One follower' ) ;
} else {
str = '' + count + ' ' + _t ( 'followers' ) ;
}
return str ;
} ,
2012-10-18 09:13:27 +00:00
/* Display generic info about follower, for people not having access to res_partner */
display _generic : function ( ) {
var self = this ;
2012-10-24 15:20:43 +00:00
var node _user _list = this . $ ( '.oe_follower_list' ) . empty ( ) ;
2012-11-08 15:33:27 +00:00
this . $ ( '.oe_follower_title' ) . html ( this . _format _followers ( this . value . length ) ) ;
2012-08-10 13:05:42 +00:00
} ,
2012-08-15 23:26:49 +00:00
2012-10-16 11:17:53 +00:00
/** Display the followers */
2012-08-16 07:26:42 +00:00
display _followers : function ( records ) {
2012-08-10 13:05:42 +00:00
var self = this ;
2012-12-20 15:29:06 +00:00
this . followers = records || this . followers ;
this . message _is _follower = this . set _is _follower ( this . followers ) ;
2012-10-18 09:13:27 +00:00
// clean and display title
2012-10-24 15:20:43 +00:00
var node _user _list = this . $ ( '.oe_follower_list' ) . empty ( ) ;
2012-12-20 15:29:06 +00:00
this . $ ( '.oe_follower_title' ) . html ( this . _format _followers ( this . followers . length ) ) ;
2012-10-18 09:13:27 +00:00
// truncate number of displayed followers
2012-12-20 15:29:06 +00:00
var truncated = this . followers . slice ( 0 , this . displayed _nb ) ;
2012-10-18 09:13:27 +00:00
_ ( truncated ) . each ( function ( record ) {
2012-09-06 11:14:44 +00:00
record . avatar _url = mail . ChatterUtils . get _image ( self . session , 'res.partner' , 'image_small' , record . id ) ;
2012-12-20 15:01:12 +00:00
$ ( session . web . qweb . render ( 'mail.followers.partner' , { 'record' : record , 'widget' : self } ) ) . appendTo ( node _user _list ) ;
2012-10-18 09:13:27 +00:00
} ) ;
2012-10-29 11:21:17 +00:00
// FVA note: be sure it is correctly translated
2012-12-20 15:29:06 +00:00
if ( truncated . length < this . followers . length ) {
$ ( session . web . qweb . render ( 'mail.followers.show_more' , { 'number' : ( this . followers . length - truncated . length ) } ) ) . appendTo ( node _user _list ) ;
2012-09-26 07:17:09 +00:00
}
2012-09-18 09:12:12 +00:00
} ,
2012-10-15 12:03:31 +00:00
/** Computes whether the current user is in the followers */
2012-10-18 09:13:27 +00:00
set _is _follower : function ( records ) {
var user _ids = _ . pluck ( _ . pluck ( records , 'user_ids' ) , 0 ) ;
return _ . indexOf ( user _ids , this . session . uid ) != - 1 ;
2012-09-18 09:12:12 +00:00
} ,
display _buttons : function ( ) {
2012-09-24 09:56:16 +00:00
if ( this . message _is _follower ) {
2012-09-26 07:17:09 +00:00
this . $ ( 'button.oe_follower' ) . removeClass ( 'oe_notfollow' ) . addClass ( 'oe_following' ) ;
2012-09-20 11:49:09 +00:00
}
2012-08-10 13:05:42 +00:00
else {
2012-09-26 07:17:09 +00:00
this . $ ( 'button.oe_follower' ) . removeClass ( 'oe_following' ) . addClass ( 'oe_notfollow' ) ;
2012-09-20 11:49:09 +00:00
}
2012-10-15 12:03:31 +00:00
2012-09-21 09:50:37 +00:00
if ( this . view . is _action _enabled ( 'edit' ) )
2012-09-26 07:17:09 +00:00
this . $ ( 'span.oe_mail_invite_wrapper' ) . hide ( ) ;
2012-09-21 09:50:37 +00:00
else
2012-09-26 07:17:09 +00:00
this . $ ( 'span.oe_mail_invite_wrapper' ) . show ( ) ;
2012-08-28 07:19:06 +00:00
} ,
2012-09-20 11:49:09 +00:00
2012-10-18 09:13:27 +00:00
/** Fetch subtypes, only if current user is follower */
fetch _subtypes : function ( ) {
2013-02-15 11:19:26 +00:00
var self = this ;
2012-10-24 15:20:43 +00:00
var subtype _list _ul = this . $ ( '.oe_subtype_list' ) . empty ( ) ;
2012-10-18 09:13:27 +00:00
if ( ! this . message _is _follower ) return ;
2013-02-15 11:19:26 +00:00
var id = this . view . datarecord . id ;
this . ds _model . call ( 'message_get_subscription_data' , [ [ id ] , new session . web . CompoundContext ( this . build _context ( ) , { } ) ] )
. then ( function ( data ) { self . display _subtypes ( data , id ) ; } ) ;
2012-10-18 09:13:27 +00:00
} ,
/** Display subtypes: {'name': default, followed} */
2013-02-15 11:19:26 +00:00
display _subtypes : function ( data , id ) {
2012-09-24 09:56:16 +00:00
var self = this ;
2013-03-13 16:15:10 +00:00
var $list = this . $ ( '.oe_subtype_list' ) ;
$list . empty ( ) . hide ( ) ;
2012-10-19 13:23:07 +00:00
var records = data [ this . view . datarecord . id || this . view . dataset . ids [ 0 ] ] . message _subtype _data ;
2013-01-28 15:05:18 +00:00
_ ( records ) . each ( function ( record , record _name ) {
record . name = record _name ;
record . followed = record . followed || undefined ;
$ ( session . web . qweb . render ( 'mail.followers.subtype' , { 'record' : record } ) ) . appendTo ( self . $ ( '.oe_subtype_list' ) ) ;
} ) ;
2013-03-13 16:15:10 +00:00
if ( _ . size ( records ) > 1 ) {
$list . show ( ) ;
2012-12-20 13:24:34 +00:00
}
2012-08-23 06:02:16 +00:00
} ,
2012-09-24 09:56:16 +00:00
2012-08-10 13:05:42 +00:00
do _follow : function ( ) {
2012-12-20 13:24:34 +00:00
var context = new session . web . CompoundContext ( this . build _context ( ) , { } ) ;
this . ds _model . call ( 'message_subscribe_users' , [ [ this . view . datarecord . id ] , [ this . session . uid ] , undefined , context ] )
. then ( this . proxy ( 'read_value' ) ) ;
_ . each ( this . $ ( '.oe_subtype_list input' ) , function ( record ) {
2012-10-18 09:13:27 +00:00
$ ( record ) . attr ( 'checked' , 'checked' ) ;
2012-09-25 08:58:09 +00:00
} ) ;
2012-08-22 06:27:22 +00:00
} ,
2012-09-24 09:56:16 +00:00
2012-08-10 13:05:42 +00:00
do _unfollow : function ( ) {
2013-02-14 15:09:49 +00:00
if ( confirm ( _t ( "Warning! \nYou won't be notified of any email or discussion on this document. Do you really want to unfollow this document ?" ) ) ) {
_ ( this . $ ( '.oe_msg_subtype_check' ) ) . each ( function ( record ) {
$ ( record ) . attr ( 'checked' , false ) ;
} ) ;
var context = new session . web . CompoundContext ( this . build _context ( ) , { } ) ;
return this . ds _model . call ( 'message_unsubscribe_users' , [ [ this . view . datarecord . id ] , [ this . session . uid ] , context ] )
. then ( this . proxy ( 'read_value' ) ) ;
}
return false ;
2012-08-10 13:05:42 +00:00
} ,
2012-09-20 11:49:09 +00:00
2012-10-10 18:16:11 +00:00
do _update _subscription : function ( event ) {
2012-09-20 11:49:09 +00:00
var self = this ;
2012-09-24 09:56:16 +00:00
2012-09-20 11:49:09 +00:00
var checklist = new Array ( ) ;
2012-10-24 15:20:43 +00:00
_ ( this . $ ( '.oe_actions input[type="checkbox"]' ) ) . each ( function ( record ) {
2012-10-18 09:13:27 +00:00
if ( $ ( record ) . is ( ':checked' ) ) {
2012-10-18 09:34:53 +00:00
checklist . push ( parseInt ( $ ( record ) . data ( 'id' ) ) ) ;
2012-10-18 09:13:27 +00:00
}
2012-09-20 11:49:09 +00:00
} ) ;
2012-09-24 10:11:08 +00:00
2012-12-20 13:24:34 +00:00
if ( ! checklist . length ) {
2013-02-14 15:09:49 +00:00
if ( ! this . do _unfollow ( ) ) {
[MERGE] Chatter and CRM: usability fixes and improvements
Chatter:
- now displays the 'To' of messages, aka notified people,
- now allows to Send a message or to Log a note, that is a message not pushed to anyone; however users that see the document still see the log message,
- fixed suggested recipient behavior: canceling the partner creation popup now correctly avoids creating a partner,
- moved 'Advanced wizard' button on top-right,
- unfollowing or removing someone from followers now displays a warning,
CRM, Recruitment, Issues:
- better management of customers/applicants: Chatter suggests to notify and add as follower the customer, or to create a partner based on the email_from,
CRM, Recruitment, Tasks, Issues:
- changing the user_id (salesman, responsible) still adds the related partner as follower; but now an unread notification is pushed, with the first email or first message if no email,
- updated and added if missing message_summary in kanban views, now displayed only when having unread messages, and the related number, to be more visible,
CRM:
- crm_partner_assign: fixed forward-to-partner wizard,
- crm_partner_assign: geo localization now also sets salesteam along with salesman,
- crm: fixed opportunity email_template,
- crm: removed 'Send mail' button, as the functionality should be covered by Chatter (but the code of the action is left untouched to avoid errors),
Mail:
- merged message_post and message_post_user_api because there was an opportunity to avoid doing similar things in two different methods,
- fixed email_from of incoming email not always stored,
- followers: authors of discussion messages are now added as followers, this is not only limited to incoming emails,
- followers: recipients of emails coming through the mail gateway are not automatically added as followers of the target documents,
- followers: slightly updated _notify, to be able to notify a partner of a specific message; the notification process is therefore accessible outside of the mail_message.create() process
bzr revid: tde@openerp.com-20130301101122-l18mr6hb0j5k4atv
2013-03-01 10:11:22 +00:00
$ ( event . target ) . attr ( "checked" , "checked" ) ;
2013-02-14 15:09:49 +00:00
}
2012-12-20 13:24:34 +00:00
} else {
var context = new session . web . CompoundContext ( this . build _context ( ) , { } ) ;
return this . ds _model . call ( 'message_subscribe_users' , [ [ this . view . datarecord . id ] , [ this . session . uid ] , checklist , context ] )
. then ( this . proxy ( 'read_value' ) ) ;
}
2012-09-20 11:49:09 +00:00
} ,
2012-08-10 13:05:42 +00:00
} ) ;
2012-10-17 14:56:39 +00:00
} ;