dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #34905
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 17905: Implemented web api endpoints for setting messageconversation followup. Cleaned up message.js cod...
Merge authors:
Halvdan Hoem Grelland (halvdanhg)
------------------------------------------------------------
revno: 17905 [merge]
committer: Halvdan Hoem Grelland <halvdanhg@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2015-01-07 14:34:50 +0100
message:
Implemented web api endpoints for setting messageconversation followup. Cleaned up message.js code. Added batch followup to dashboard messaging. Minor fixes.
modified:
dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageService.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/DefaultMessageService.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/hibernate/HibernateMessageConversationStore.java
dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/message/MessageServiceTest.java
dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/MessageConversationController.java
dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.dhisCheckboxMenu.js
dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/resources/org/hisp/dhis/dashboard/i18n_module.properties
dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/javascript/message.js
dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/message.vm
--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk
Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageService.java 2014-11-18 12:55:20 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/message/MessageService.java 2015-01-06 16:21:58 +0000
@@ -102,7 +102,7 @@
List<MessageConversation> getMessageConversations( boolean followUpOnly, boolean unreadOnly, int first, int max );
- Collection<MessageConversation> getMessageConversations( String[] messageConversationUids );
+ Collection<MessageConversation> getMessageConversations( User user, String[] messageConversationUids );
int getMessageConversationCount();
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/DefaultMessageService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/DefaultMessageService.java 2014-12-21 17:57:33 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/DefaultMessageService.java 2015-01-06 16:21:58 +0000
@@ -327,9 +327,20 @@
}
@Override
- public Collection<MessageConversation> getMessageConversations( String[] messageConversationUids )
+ public Collection<MessageConversation> getMessageConversations( User user, String[] messageConversationUids )
{
- return messageConversationStore.getMessageConversations( messageConversationUids );
+ Collection<MessageConversation> conversations = messageConversationStore.getMessageConversations( messageConversationUids );
+
+ // Set transient properties
+ // TODO See getMessageConversation(String)
+
+ for ( MessageConversation mc : conversations )
+ {
+ mc.setFollowUp( mc.isFollowUp( user ) );
+ mc.setRead( mc.isRead( user ) );
+ }
+
+ return conversations;
}
@Override
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/hibernate/HibernateMessageConversationStore.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/hibernate/HibernateMessageConversationStore.java 2014-10-16 06:17:19 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/message/hibernate/HibernateMessageConversationStore.java 2015-01-07 12:59:57 +0000
@@ -29,6 +29,7 @@
*/
import org.hibernate.Query;
+import org.hibernate.criterion.Restrictions;
import org.hisp.dhis.common.hibernate.HibernateIdentifiableObjectStore;
import org.hisp.dhis.jdbc.StatementBuilder;
import org.hisp.dhis.message.MessageConversation;
@@ -40,6 +41,7 @@
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -128,15 +130,12 @@
}
@Override
- @SuppressWarnings("unchecked")
- public Collection<MessageConversation> getMessageConversations( String[] messageConversationUids )
+ @SuppressWarnings( "unchecked" )
+ public Collection<MessageConversation> getMessageConversations( String[] uids )
{
- String hql = ( "FROM MessageConversation where uid in :messageConversationUids" );
-
- Query query = getQuery( hql );
- query.setParameterList( "messageConversationUids", messageConversationUids );
-
- return query.list();
+ return getSharingCriteria()
+ .add( Restrictions.in( "uid", uids ) )
+ .list();
}
@Override
@@ -259,4 +258,4 @@
return recipients;
}
-}
\ No newline at end of file
+}
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/message/MessageServiceTest.java'
--- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/message/MessageServiceTest.java 2014-10-16 06:17:19 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/message/MessageServiceTest.java 2015-01-06 16:21:58 +0000
@@ -229,7 +229,7 @@
String[] uids = { uidA, uidB };
- Collection<MessageConversation> conversations = messageService.getMessageConversations( uids );
+ Collection<MessageConversation> conversations = messageService.getMessageConversations( sender, uids );
assertTrue( conversations.contains( conversationA ) );
assertTrue( conversations.contains( conversationB ) );
=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/MessageConversationController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/MessageConversationController.java 2014-12-30 17:28:02 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/MessageConversationController.java 2015-01-07 12:59:57 +0000
@@ -293,7 +293,7 @@
throw new UpdateAccessDeniedException( "Not authorized to modify this object." );
}
- Collection<org.hisp.dhis.message.MessageConversation> messageConversations = messageService.getMessageConversations( uids );
+ Collection<org.hisp.dhis.message.MessageConversation> messageConversations = messageService.getMessageConversations( user, uids );
if ( messageConversations.isEmpty() )
{
@@ -344,7 +344,7 @@
throw new UpdateAccessDeniedException( "Not authorized to modify this object." );
}
- Collection<org.hisp.dhis.message.MessageConversation> messageConversations = messageService.getMessageConversations( uids );
+ Collection<org.hisp.dhis.message.MessageConversation> messageConversations = messageService.getMessageConversations( user, uids );
if ( messageConversations.isEmpty() )
{
@@ -371,6 +371,110 @@
}
//--------------------------------------------------------------------------
+ // Mark conversations for follow up
+ //--------------------------------------------------------------------------
+
+ @RequestMapping( value = "followup", method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE } )
+ public @ResponseBody RootNode markMessageConversationFollowup(
+ @RequestParam( value = "user", required = false ) String userUid, @RequestBody String[] uids, HttpServletResponse response )
+ {
+ RootNode responseNode = new RootNode( "response" );
+
+ User currentUser = currentUserService.getCurrentUser();
+ User user = userUid != null ? userService.getUser( userUid ) : currentUser;
+
+ if ( user == null )
+ {
+ response.setStatus( HttpServletResponse.SC_NOT_FOUND );
+ responseNode.addChild( new SimpleNode( "message", "No user with uid: " + userUid ) );
+ return responseNode;
+ }
+
+ if ( !canModifyUserConversation( currentUser, user ) )
+ {
+ throw new UpdateAccessDeniedException( "Not authorized to modify this object." );
+ }
+
+ Collection<org.hisp.dhis.message.MessageConversation> messageConversations = messageService.getMessageConversations( user, uids );
+
+ if ( messageConversations.isEmpty() )
+ {
+ response.setStatus( HttpServletResponse.SC_NOT_FOUND );
+ responseNode.addChild( new SimpleNode( "message", "No MessageConversations found for the given UIDs" ) );
+ return responseNode;
+ }
+
+ CollectionNode marked = responseNode.addChild( new CollectionNode( "markedFollowup" ) );
+ marked.setWrapping( false );
+
+ for ( org.hisp.dhis.message.MessageConversation conversation : messageConversations )
+ {
+ if ( !conversation.isFollowUp() )
+ {
+ conversation.toggleFollowUp( user );
+ messageService.updateMessageConversation( conversation );
+ }
+ marked.addChild( new SimpleNode( "uid", conversation.getUid() ) );
+ }
+
+ response.setStatus( HttpServletResponse.SC_OK );
+
+ return responseNode;
+ }
+
+ //--------------------------------------------------------------------------
+ // Clear follow up
+ //--------------------------------------------------------------------------
+
+ @RequestMapping( value = "unfollowup", method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE } )
+ public @ResponseBody RootNode unmarkMessageConversationFollowup(
+ @RequestParam( value = "user", required = false ) String userUid, @RequestBody String[] uids, HttpServletResponse response )
+ {
+ RootNode responseNode = new RootNode( "response" );
+
+ User currentUser = currentUserService.getCurrentUser();
+ User user = userUid != null ? userService.getUser( userUid ) : currentUser;
+
+ if ( user == null )
+ {
+ response.setStatus( HttpServletResponse.SC_NOT_FOUND );
+ responseNode.addChild( new SimpleNode( "message", "No user with uid: " + userUid ) );
+ return responseNode;
+ }
+
+ if ( !canModifyUserConversation( currentUser, user ) )
+ {
+ throw new UpdateAccessDeniedException( "Not authorized to modify this object." );
+ }
+
+ Collection<org.hisp.dhis.message.MessageConversation> messageConversations = messageService.getMessageConversations( user, uids );
+
+ if ( messageConversations.isEmpty() )
+ {
+ response.setStatus( HttpServletResponse.SC_NOT_FOUND );
+ responseNode.addChild( new SimpleNode( "message", "No MessageConversations found for the given UIDs" ) );
+ return responseNode;
+ }
+
+ CollectionNode marked = responseNode.addChild( new CollectionNode( "unmarkedFollowup" ) );
+ marked.setWrapping( false );
+
+ for ( org.hisp.dhis.message.MessageConversation conversation : messageConversations )
+ {
+ if ( conversation.isFollowUp() )
+ {
+ conversation.toggleFollowUp( user );
+ messageService.updateMessageConversation( conversation );
+ }
+ marked.addChild( new SimpleNode( "uid", conversation.getUid() ) );
+ }
+
+ response.setStatus( HttpServletResponse.SC_OK );
+
+ return responseNode;
+ }
+
+ //--------------------------------------------------------------------------
// Delete a MessageConversation (requires override auth)
//--------------------------------------------------------------------------
@@ -465,7 +569,7 @@
throw new DeleteAccessDeniedException( "Not authorized to modify user: " + user.getUid() );
}
- Collection<org.hisp.dhis.message.MessageConversation> messageConversations = messageService.getMessageConversations( mcUids );
+ Collection<org.hisp.dhis.message.MessageConversation> messageConversations = messageService.getMessageConversations( user, mcUids );
if ( messageConversations.isEmpty() )
{
=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.dhisCheckboxMenu.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.dhisCheckboxMenu.js 2014-10-03 12:12:40 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.dhisCheckboxMenu.js 2015-01-06 18:19:11 +0000
@@ -68,6 +68,16 @@
return checked;
}
+ function executeNamedFn(fnName, ctx ) {
+ var args = [].slice.call(arguments).splice(2);
+ var namespaces = fnName.split(".");
+ var func = namespaces.pop();
+ for( var i = 0; i < namespaces.length; i++ ) {
+ ctx = ctx[ namespaces[ i ] ];
+ }
+ return ctx[func].apply( this, args );
+ }
+
var multiCheckboxMenu = $.fn.multiCheckboxMenu;
$.fn.multiCheckboxMenu = function( $checkboxContainer, options ) {
@@ -130,7 +140,7 @@
}
el.click( function() {
- return window[ el.action ]( getCheckedValues( $checkboxContainer ) );
+ return executeNamedFn( el.action, window, getCheckedValues( $checkboxContainer ) );
});
});
=== modified file 'dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/resources/org/hisp/dhis/dashboard/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/resources/org/hisp/dhis/dashboard/i18n_module.properties 2014-12-18 11:41:20 +0000
+++ dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/resources/org/hisp/dhis/dashboard/i18n_module.properties 2015-01-07 13:32:22 +0000
@@ -26,6 +26,8 @@
recipients=Recipients
mark_unread=Mark as unread
mark_read=Mark as read
+mark_followup=Mark for followup
+clear_followup=Clear followup
read=Read
delete=Delete
confirm_delete_message=Are you sure you want to delete the message?
=== modified file 'dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/javascript/message.js'
--- dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/javascript/message.js 2014-10-03 11:32:55 +0000
+++ dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/javascript/message.js 2015-01-07 13:02:00 +0000
@@ -8,101 +8,6 @@
removeItem( id, "", i18n_confirm_delete_message, "removeMessage.action" );
}
-function removeMessages( messages )
-{
- if( typeof messages === "undefined" || messages.length < 1 )
- {
- return;
- }
-
- var confirmed = window.confirm( i18n_confirm_delete_all_selected_messages );
-
- if( confirmed )
- {
- setHeaderWaitMessage( i18n_deleting );
-
- $.ajax(
- {
- url: "../api/messageConversations?" + $.param( { mc: messages }, true ),
- contentType: "application/json",
- dataType: "json",
- type: "DELETE",
- success: function( response )
- {
- for( var i = 0; i < response.removed.length; i++ )
- {
- $( "#messages" ).find( "[name='" + response.removed[i] + "']" ).remove();
- }
- setHeaderDelayMessage( i18n_messages_were_deleted );
- },
- error: function( response )
- {
- showErrorMessage( response.message, 3 );
- }
- } );
- }
-}
-
-function markMessagesRead( messages )
-{
- if( messages.length < 1 )
- {
- return;
- }
-
- $.ajax(
- {
- url: "../api/messageConversations/read",
- type: "POST",
- data: JSON.stringify( messages ),
- contentType: "application/json",
- dataType: "json",
- success: function( response )
- {
- toggleMessagesRead( response.markedRead );
- },
- error: function( response )
- {
- showErrorMessage( response.message, 3 );
- }
- } );
-}
-
-function markMessagesUnread( messages )
-{
- if( messages.length < 1 )
- {
- return;
- }
-
- $.ajax(
- {
- url: "../api/messageConversations/unread",
- type: "POST",
- data: JSON.stringify( messages ),
- contentType: "application/json",
- dataType: "json",
- success: function( response )
- {
- toggleMessagesRead( response.markedUnread );
- },
- error: function( response )
- {
- showErrorMessage( response.message, 3 );
- }
- } );
-}
-
-function toggleMessagesRead( messageUids )
-{
- var messages = $( "#messages" );
-
- for( var i = 0; i < messageUids.length; i++ )
- {
- messages.find( "[name='" + messageUids[i] + "']" ).toggleClass( "unread bold" );
- }
-}
-
function toggleRowSelected( element )
{
$( element ).closest( "tr" ).toggleClass( "list-row-selected", element.checked );
@@ -197,3 +102,119 @@
return item.text;
}
}
+
+var messageOperations = ( function() {
+
+ //
+ // Private
+ //
+
+ var removeMessages = function( messages ) {
+ if( typeof messages === "undefined" || messages.length < 1 ) {
+ return;
+ }
+
+ var confirmed = window.confirm( i18n_confirm_delete_all_selected_messages );
+
+ if( confirmed ) {
+ setHeaderWaitMessage( i18n_deleting );
+
+ $.ajax( {
+ url: "../api/messageConversations?" + $.param( { mc: messages }, true ),
+ contentType: "application/json",
+ dataType: "json",
+ type: "DELETE",
+ success: function( response ) {
+ for( var i = 0; i < response.removed.length; i++ ) {
+ $( "#messages" ).find( "[name='" + response.removed[i] + "']" ).remove();
+ }
+ setHeaderDelayMessage( i18n_messages_were_deleted );
+ },
+ error: function( response ) {
+ showErrorMessage( response.message, 3 );
+ }
+ } );
+ }
+ };
+
+ var propertyRegExp = new RegExp( "[read|unread|followup|unfollowup]" );
+
+ /**
+ * Workhorse function to mark/unmark messages read, unread, followup or unfollowup.
+ *
+ * @param messages {array} UID of messages to mark
+ * @param property {string} property to mark. String values are read|unread|followup|unfollowup
+ */
+ var markMessages = function( messages, property ) {
+ if( typeof messages === "undefined" || messages.length < 1 ) {
+ return;
+ }
+
+ if( !_.isString( property ) || !propertyRegExp.test( property ) ) {
+ throw "Property string must be set.";
+ }
+
+ $.ajax( {
+ url: "../api/messageConversations/" + property,
+ type: "POST",
+ data: JSON.stringify( messages ),
+ contentType: "application/json",
+ dataType: "json",
+ success: function( response ) {
+ switch( property ) {
+ case "read":
+ toggleMessagesRead( response.markedRead );
+ break;
+ case "unread":
+ toggleMessagesRead( response.markedUnread );
+ break;
+ case "followup":
+ setFollowupIndicator( response.markedFollowup, true);
+ break;
+ case "unfollowup":
+ setFollowupIndicator( response.unmarkedFollowup, false );
+ break;
+ }
+ },
+ error: function( response ) {
+ showErrorMessage( response.message, 3);
+ }
+ } );
+ };
+
+ var setFollowupIndicator = function( messageUids, marked ) {
+ var messages = $( "#messages" );
+ var imgSrc = marked ? "../images/marked.png" : "../images/unmarked.png";
+
+ for( var i = 0; i < messageUids.length; i++ ) {
+ messages.find( "[name='" + messageUids[i] + "'] .followup-icon img" ).attr( "src", imgSrc );
+ }
+ };
+
+ var toggleMessagesRead = function( messageUids ) {
+ var messages = $( "#messages" );
+
+ for( var i = 0; i < messageUids.length; i++ ) {
+ messages.find( "[name='" + messageUids[i] + "']" ).toggleClass( "unread bold" );
+ }
+ };
+
+ //
+ // Public
+ //
+ return {
+ unmarkMessagesFollowup: function( messages ) {
+ return markMessages( messages, "unfollowup" );
+ },
+ markMessagesFollowup: function( messages) {
+ return markMessages( messages, "followup" );
+ },
+ markMessagesRead: function( messages ) {
+ return markMessages( messages, "read" );
+ },
+ markMessagesUnread: function( messages ) {
+ return markMessages( messages, "unread" );
+ },
+ removeMessages: removeMessages
+ };
+})( window );
\ No newline at end of file
=== modified file 'dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/message.vm'
--- dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/message.vm 2014-10-03 11:32:55 +0000
+++ dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/message.vm 2015-01-07 13:32:22 +0000
@@ -12,9 +12,11 @@
<div id="checkboxDropdown">
<div></div>
<ul>
- <li data-action="removeMessages">Delete</li>
- <li data-action="markMessagesRead">Mark read</li>
- <li data-action="markMessagesUnread">Mark unread</li>
+ <li data-action="messageOperations.removeMessages">$i18n.getString( "delete" )</li>
+ <li data-action="messageOperations.markMessagesRead">$i18n.getString( "mark_read")</li>
+ <li data-action="messageOperations.markMessagesUnread">$i18n.getString( "mark_unread" )</li>
+ <li data-action="messageOperations.markMessagesFollowup">$i18n.getString( "mark_followup")</li>
+ <li data-action="messageOperations.unmarkMessagesFollowup">$i18n.getString( "clear_followup" )</li>
</ul>
</div>
</li>
@@ -43,7 +45,7 @@
<td style="width:20px;padding-left:5px;">
<input type="checkbox" value="${conversation.uid}" onchange="toggleRowSelected( this )"/>
</td>
- <td style="width:40px;padding-left:5px;" onclick="toggleFollowUp( '${conversation.id}' )">
+ <td style="width:40px;padding-left:5px;" onclick="toggleFollowUp( '${conversation.id}' )" class="followup-icon">
<img id="followUp${conversation.id}" #if( $conversation.followUp ) src="../images/marked.png"#else src="../images/unmarked.png"#end></td>
<td style="width:200px" onclick="read( '${conversation.uid}' )">
#if( $conversation.lastSenderName )$!encoder.htmlEncode( $conversation.lastSenderName )#else $i18n.getString( "system_notification" )#end