Skip to content

Commit

Permalink
LDEV-4417 Popover portraits in Monitoring
Browse files Browse the repository at this point in the history
    Implmented in Share Resources, Survey, Leader, Mindmap, 
    Noticeboard, Notebook, Pixlr, Peer Review
  • Loading branch information
FionaMalikoff committed Sep 14, 2017
1 parent f851d4f commit 109770e
Show file tree
Hide file tree
Showing 43 changed files with 318 additions and 125 deletions.
5 changes: 3 additions & 2 deletions lams_central/web/includes/javascript/portrait.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var NUM_COLORS = 7,
STYLE_LARGE = 'large',
STYLE_XLARGE = 'xlarge';

// Add a portrait to an existing div as specified by selector
// Add a portrait to an existing div as specified by selector.
function addPortrait( selector, portraitId, userId, size, round, LAMS_URL ) {
var isRound = round == null ? true : round;
if ( portraitId && portraitId > 0) {
Expand Down Expand Up @@ -55,6 +55,7 @@ function initializePortraitPopover(LAMS_URL, size) {
html: true,
trigger: 'hover focus',
title: element.dataset.fullname,
delay: { "show": 700, "hide": 100 },
container: 'body' // ensures popovers are not clipped within jqgrid tables
});
element.classList.remove('new-popover');
Expand All @@ -64,7 +65,7 @@ function initializePortraitPopover(LAMS_URL, size) {

// Define the element to have a popover/tooltip to display the learner's portrait. Call in the ajaxProcessing (tablesorter) or
// in a formatter function (jqgrid). Use with initializePortraitPopover. Displays the fullName and portrait in the popover when the
// user hovers on linkText. Usually linkText === fullName
// user hovers on linkText. Usually linkText === fullName.
function definePortraitPopover(portraitId, userId, fullName, linkText) {
if ( ! linkText )
linkText = fullName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
public class StyledRatingDTO {

private Long itemId;
private String itemDescription; // user readable version of the item, usually the name of the learner that has been rated\
private String itemDescription; // user readable version of the item, usually the name of the learner that has been rated
private String itemDescription2; // system detail for addition description content, usually the portrait id of the learner that has been rated.

private String userRating; // rating left by the current user
private String averageRating; // average of ratings by all users
Expand Down Expand Up @@ -92,6 +93,14 @@ public String getComment() {
public void setComment(String comment) {
this.comment = comment;
}

public String getItemDescription2() {
return itemDescription2;
}

public void setItemDescription2(String itemDescription2) {
this.itemDescription2 = itemDescription2;
}



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,8 @@ public StyledCriteriaRatingDTO convertToStyledDTO(RatingCriteria ratingCriteria,

StyledRatingDTO dto = new StyledRatingDTO(((BigInteger) row[0]).longValue());
dto.setComment((String) row[2]);
dto.setItemDescription((String) row[numColumns - 1]);
dto.setItemDescription( row[numColumns - 2] != null ? row[numColumns - 2].toString() : null);
dto.setItemDescription2( row[numColumns - 1] != null ? row[numColumns - 1].toString() : null);
if ( ! isComment ) {
dto.setUserRating(row[3] == null ? "" : numberFormat.format((Double) row[3]));
dto.setAverageRating(row[4] == null ? "" : numberFormat.format((Double) row[4]));
Expand All @@ -662,9 +663,9 @@ public StyledCriteriaRatingDTO convertToStyledDTO(RatingCriteria ratingCriteria,

/**
* Convert the raw data from the database to JSON, similar on StyledCriteriaRatingDTO and StyleRatingDTO.
* The rating service expects the potential itemId followed by rating.* (its own fields) and the last item
* in the array to be an item description (eg formatted user's name) Will go back to the database for the
* justification comment that would apply to hedging.
* The rating service expects the potential itemId followed by rating.* (its own fields) and the last two items
* in the array will be two item descriptions fields (eg formatted user's name, portrait id). Will go back to
* the database for the justification comment that would apply to hedging.
*
* If includeCurrentUser == true will include the current users' records (used for SelfReview and Monitoring)
* otherwise skips the current user, so they do not rate themselves!
Expand Down Expand Up @@ -721,7 +722,8 @@ public JSONArray convertToStyledJSON(RatingCriteria ratingCriteria, Long toolSes
JSONObject userRow = new JSONObject();
userRow.put("itemId", itemId);
userRow.put("comment", row[2] == null ? "" : (String) row[2]);
userRow.put("itemDescription", row[numColumns - 1] == null ? "" : (String) row[numColumns - 1]);
userRow.put("itemDescription", row[numColumns - 2] == null ? "" : row[numColumns - 2].toString());
userRow.put("itemDescription2", row[numColumns - 1] == null ? "" : row[numColumns - 1].toString());
if ( ! isComment ) {
userRow.put("userRating", row[3] == null ? "" : numberFormat.format((Double) row[3]));
userRow.put("averageRating", row[4] == null ? "" : numberFormat.format((Double) row[4]));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ label.rating =Rating
label.average.rating =Average rating {0}/{1} votes
label.your.rating =Your rating {0}, average rating {1}/{2} votes
del.confirmation =Are you sure you want to delete this resource?
label.error =Error
error.loaderror =There was an error loading the grid. If this problem persists, please contact your system administrator.
label.ok =OK


#======= End labels: Exported 170 labels for en AU =====
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import org.lamsfoundation.lams.tool.rsrc.dto.VisitLogDTO;
import org.lamsfoundation.lams.tool.rsrc.model.ResourceItemVisitLog;
import org.lamsfoundation.lams.usermanagement.service.IUserManagementService;

public interface ResourceItemVisitDAO extends DAO {

Expand All @@ -47,7 +48,7 @@ public interface ResourceItemVisitDAO extends DAO {
List<ResourceItemVisitLog> getResourceItemLogBySession(Long sessionId, Long itemUid);

List<VisitLogDTO> getPagedVisitLogsBySessionAndItem(Long sessionId, Long itemUid, int page, int size, String sortBy,
String sortOrder, String searchString);
String sortOrder, String searchString, IUserManagementService userManagementService);

int getCountVisitLogsBySessionAndItem(Long sessionId, Long itemUid, String searchString);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.lamsfoundation.lams.tool.rsrc.model.Resource;
import org.lamsfoundation.lams.tool.rsrc.model.ResourceItemVisitLog;
import org.lamsfoundation.lams.tool.rsrc.model.ResourceSession;
import org.lamsfoundation.lams.usermanagement.service.IUserManagementService;
import org.springframework.stereotype.Repository;

@Repository
Expand Down Expand Up @@ -105,27 +106,39 @@ public List<ResourceItemVisitLog> getResourceItemLogBySession(Long sessionId, Lo
return (List<ResourceItemVisitLog>) doFind(FIND_BY_ITEM_BYSESSION, new Object[] { sessionId, itemUid });
}

private static String LOAD_USERS_ORDERED_BY_NAME_SELECT = " SELECT user.user_id, CONCAT(user.last_name, ' ', user.first_name), visit.complete_date, visit.access_date ";
private static String LOAD_USERS_ORDERED_BY_NAME_FROM = " FROM tl_larsrc11_item_log visit "
+ " JOIN tl_larsrc11_user user ON visit.user_uid = user.uid "
+ " AND (CONCAT(user.last_name, ' ', user.first_name) LIKE CONCAT('%', :searchString, '%'))";
private static String LOAD_USERS_ORDERED_BY_NAME_WHERE = " WHERE visit.session_id = :sessionId AND visit.resource_item_uid = :itemUid "
+ " ORDER BY CASE WHEN :sortBy='userName' THEN CONCAT(user.last_name, ' ', user.first_name) "
+ " WHEN :sortBy='startTime' THEN visit.access_date "
+ " WHEN :sortBy='completeTime' THEN visit.complete_date "
+ " WHEN :sortBy='timeTaken' THEN TIMEDIFF(visit.complete_date,visit.access_date) END ";

@Override
public List<VisitLogDTO> getPagedVisitLogsBySessionAndItem(Long sessionId, Long itemUid, int page, int size,
String sortBy, String sortOrder, String searchString) {
String LOAD_USERS_ORDERED_BY_NAME = "SELECT visit.user.userId, CONCAT(visit.user.lastName, ' ', visit.user.firstName), visit.completeDate, visit.accessDate"
+ " FROM " + ResourceItemVisitLog.class.getName() + " visit" + " WHERE visit.sessionId = :sessionId "
+ " AND visit.resourceItem.uid = :itemUid "
+ " AND (CONCAT(visit.user.lastName, ' ', visit.user.firstName) LIKE CONCAT('%', :searchString, '%')) "
+ " ORDER BY " + " CASE " + " WHEN :sortBy='userName' THEN CONCAT(user.lastName, ' ', user.firstName) "
+ " WHEN :sortBy='startTime' THEN visit.accessDate "
+ " WHEN :sortBy='completeTime' THEN visit.completeDate "
+ " WHEN :sortBy='timeTaken' THEN TIMEDIFF(visit.completeDate,visit.accessDate) " + " END " + sortOrder;

Query query = getSession().createQuery(LOAD_USERS_ORDERED_BY_NAME);
query.setLong("sessionId", sessionId);
query.setLong("itemUid", itemUid);
String sortBy, String sortOrder, String searchString, IUserManagementService userManagementService) {

String[] portraitStrings = userManagementService.getPortraitSQL("user.user_id");

StringBuilder bldr = new StringBuilder(LOAD_USERS_ORDERED_BY_NAME_SELECT)
.append(portraitStrings[0])
.append(LOAD_USERS_ORDERED_BY_NAME_FROM)
.append(portraitStrings[1])
.append(LOAD_USERS_ORDERED_BY_NAME_WHERE)
.append(sortOrder);

Query query = getSession().createSQLQuery(bldr.toString())
.setLong("sessionId", sessionId)
.setLong("itemUid", itemUid);

// support for custom search from a toolbar
searchString = searchString == null ? "" : searchString;
query.setString("searchString", searchString);
query.setString("sortBy", sortBy);
query.setFirstResult(page * size);
query.setMaxResults(size);
query.setString("searchString", searchString)
.setString("sortBy", sortBy)
.setFirstResult(page * size)
.setMaxResults(size);
List<Object[]> list = query.list();

ArrayList<VisitLogDTO> visitLogDto = new ArrayList<VisitLogDTO>();
Expand All @@ -138,14 +151,15 @@ public List<VisitLogDTO> getPagedVisitLogsBySessionAndItem(Long sessionId, Long
Date accessDate = element[3] == null ? null : new Date(((Timestamp) element[3]).getTime());
Date timeTaken = (element[2] == null || element[3] == null) ? null
: new Date(completeDate.getTime() - accessDate.getTime());
Long portraitId = element[4] == null ? null : ((Number) element[4]).longValue();

VisitLogDTO userDto = new VisitLogDTO();
userDto.setUserId(userId);
userDto.setUserFullName(userFullName);
userDto.setCompleteDate(completeDate);
userDto.setAccessDate(accessDate);
userDto.setTimeTaken(timeTaken);
;
userDto.setPortraitId(portraitId);;
visitLogDto.add(userDto);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/
public class ReflectDTO {
private Long userUid;
private Long userId;
private String fullName;
private String loginName;
private String reflectInstrctions;
Expand All @@ -20,6 +21,7 @@ public ReflectDTO(ResourceUser user) {
this.setLoginName(user.getLoginName());
this.setFullName(user.getFirstName() + " " + user.getLastName());
this.setUserUid(user.getUid());
this.setUserId(user.getUserId());
}

public boolean isFinishReflection() {
Expand Down Expand Up @@ -77,4 +79,12 @@ public Date getDate() {
public void setDate(Date date) {
this.date = date;
}

public Long getUserId() {
return userId;
}

public void setUserId(Long userId) {
this.userId = userId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,16 @@ public class VisitLogDTO {

private String userFullName;

private Long portraitId;

// the user access some reousrce item date time. Use in monitoring summary page
private Date accessDate;
// resource item complete date. Use in monitoring summary page
private Date completeDate;
// difference between completeDate and accessDate
private Date timeTaken;


public Long getUserId() {
return userId;
}
Expand Down Expand Up @@ -78,4 +81,12 @@ public void setTimeTaken(Date timeTaken) {
this.timeTaken = timeTaken;
}

public Long getPortraitId() {
return portraitId;
}

public void setPortraitId(Long portraitId) {
this.portraitId = portraitId;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ public List<ResourceUser> getUserListBySessionItem(Long sessionId, Long itemUid)
public List<VisitLogDTO> getPagedVisitLogsBySessionAndItem(Long sessionId, Long itemUid, int page, int size,
String sortBy, String sortOrder, String searchString) {
return resourceItemVisitDao.getPagedVisitLogsBySessionAndItem(sessionId, itemUid, page, size, sortBy, sortOrder,
searchString);
searchString, userManagementService);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ private ActionForward getSubgridData(ActionMapping mapping, ActionForm form, Htt
String timeTaken = (visitLogDto.getTimeTaken() == null) ? ""
: timeTakenFormatter.format(visitLogDto.getTimeTaken());
visitLogData.put(timeTaken);
visitLogData.put(visitLogDto.getPortraitId());

JSONObject userRow = new JSONObject();
userRow.put("id", i++);
Expand Down
3 changes: 2 additions & 1 deletion lams_tool_larsrc/web/pages/monitoring/reflections.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
<c:forEach var="reflectDTO" items="${sessionMap.reflectList}">
<tr>
<td>
<strong><c:out value="${reflectDTO.fullName}" escapeXml="true"/></strong> - <lams:Date value="${reflectDTO.date}"/>
<lams:Portrait userId="${reflectDTO.userId}" hover="true"><strong><c:out value="${reflectDTO.fullName}" escapeXml="true"/></strong></lams:Portrait>
- <lams:Date value="${reflectDTO.date}"/>
<br>
<lams:out value="${reflectDTO.reflect}" escapeHtml="true" />
</td>
Expand Down
26 changes: 18 additions & 8 deletions lams_tool_larsrc/web/pages/monitoring/summary.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@
<script type="text/javascript" src="${lams}includes/javascript/jquery.jqGrid.locale-en.js"></script>
<script type="text/javascript" src="${lams}includes/javascript/jquery.jqGrid.js"></script>
<script type="text/javascript" src="${lams}includes/javascript/monitorToolSummaryAdvanced.js" ></script>
<script type="text/javascript" src="${lams}includes/javascript/portrait.js" ></script>
<script type="text/javascript">
$(document).ready(function(){
initializePortraitPopover("<lams:LAMSURL />");
<c:forEach var="groupSummary" items="${summaryList}" varStatus="status">
Expand Down Expand Up @@ -93,27 +96,31 @@
"<fmt:message key="monitoring.label.user.name"/>",
"<fmt:message key="monitoring.label.access.time"/>",
"<fmt:message key="monitoring.label.complete.time"/>",
"<fmt:message key="monitoring.label.time.taken"/>"
"<fmt:message key="monitoring.label.time.taken"/>",
'portraitId'
],
colModel:[
{name:'id', index:'id', hidden:true},
{name:'userName',index:'userName', searchoptions: { clearSearch: false }},
{name:'userName',index:'userName', searchoptions: { clearSearch: false }, formatter:userNameFormatter},
{name:'startTime', index:'startTime', width:140, align:"center", search:false},
{name:'completeTime', index:'completeTime', width:140, align:"center", search:false},
{name:'timeTaken',index:'timeTaken', width:70, align:"center", search:false}
{name:'timeTaken',index:'timeTaken', width:70, align:"center", search:false},
{name:'portraidId',index:'portraidId', hidden:true}
],
loadError: function(xhr,st,err) {
jQuery("#"+subgridTableId).clearGridData();
info_dialog("<fmt:message key="label.error"/>", "<fmt:message key="gradebook.error.loaderror"/>", "<fmt:message key="label.ok"/>");
}
jQuery("#"+subgridTableId).clearGridData();
jQuery.jgrid.info_dialog("<fmt:message key="label.error"/>", "<fmt:message key="error.loaderror"/>", "<fmt:message key="label.ok"/>");
},
loadComplete: function () {
initializePortraitPopover('<lams:LAMSURL/>');
}
})
.jqGrid('filterToolbar', {
searchOnEnter: false
})
.navGrid("#pager-" + subgridTableId, {edit:false,add:false,del:false,search:false});
}
});
})
<c:forEach var="item" items="${groupSummary.items}" varStatus="i">
<c:choose>
<c:when test="${item.itemHide}">
Expand Down Expand Up @@ -183,6 +190,9 @@
setTimeout(function(){ window.dispatchEvent(new Event('resize')); }, 300);
});
function userNameFormatter (cellvalue, options, rowObject) {
return definePortraitPopover(rowObject[5], rowObject[0], rowObject[1]);
}
function changeItemVisibility(linkObject, itemUid, isHideItem) {
<c:set var="hideShowLink"><a href='<c:url value='/monitoring/changeItemVisibility.do'/>?sessionMapID=${sessionMapID}&itemUid=${item.itemUid}' class='button'> <fmt:message key='monitoring.label.show' /> </a></c:set>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class LeaderselectionUserDTO implements Comparable {
private String firstName;

private String lastName;

private Long userId;

private boolean finishedActivity;

Expand All @@ -46,6 +48,7 @@ public LeaderselectionUserDTO(LeaderselectionUser user, NotebookEntry entry) {
this.firstName = user.getFirstName();
this.lastName = user.getLastName();
this.finishedActivity = user.isFinishedActivity();
this.userId = user.getUserId();
}

public LeaderselectionUserDTO(LeaderselectionUser user) {
Expand All @@ -54,6 +57,7 @@ public LeaderselectionUserDTO(LeaderselectionUser user) {
this.firstName = user.getFirstName();
this.lastName = user.getLastName();
this.finishedActivity = user.isFinishedActivity();
this.userId = user.getUserId();
}

@Override
Expand Down Expand Up @@ -106,4 +110,12 @@ public boolean isFinishedActivity() {
public void setFinishedActivity(boolean finishedActivity) {
this.finishedActivity = finishedActivity;
}

public Long getUserId() {
return userId;
}

public void setUserId(Long userId) {
this.userId = userId;
}
}
2 changes: 1 addition & 1 deletion lams_tool_leader/web/pages/monitoring/headItems.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@

<script type="text/javascript" src="${lams}includes/javascript/jquery-ui.js"></script>
<script type="text/javascript" src="${lams}includes/javascript/thickbox.js"></script>
<script type="text/javascript" src="${lams}includes/javascript/portrait.js"></script>
<script type="text/javascript" src="${tool}includes/javascript/monitoring.js"></script>

Loading

0 comments on commit 109770e

Please sign in to comment.