Index: lams_central/conf/language/lams/ApplicationResources_en_AU.properties
===================================================================
diff -u -r5491463bab18676cd7fa0b47ea36e66e0f809cad -ra0bea10c9022cc2146b3067858932029ca721683
--- lams_central/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision 5491463bab18676cd7fa0b47ea36e66e0f809cad)
+++ lams_central/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision a0bea10c9022cc2146b3067858932029ca721683)
@@ -752,4 +752,8 @@
label.search.for.courses =Search for courses
+label.save.as.course.grouping =Save as a Course Grouping
+label.enter.course.grouping.name =Please enter name for the new course grouping
+label.course.groups.name.not.unique =Course grouping with such name already exists. Please enter another one.
+
#======= End labels: Exported 744 labels for en AU =====
Index: lams_central/web/css/orgGroup.css
===================================================================
diff -u -rb07b3de82e183f1351bb22c32d269b5077e82457 -ra0bea10c9022cc2146b3067858932029ca721683
--- lams_central/web/css/orgGroup.css (.../orgGroup.css) (revision b07b3de82e183f1351bb22c32d269b5077e82457)
+++ lams_central/web/css/orgGroup.css (.../orgGroup.css) (revision a0bea10c9022cc2146b3067858932029ca721683)
@@ -121,3 +121,14 @@
background-color: #5c9ccc !important;
color: white !important;
}
+
+#save-course-grouping-container {
+ display: inline-block;
+ width: 100%;
+ margin-bottom: -7px;
+}
+.dialogContainer {
+ display: none;
+ -webkit-overflow-scrolling: touch !important;
+ overflow: auto;
+}
Index: lams_central/web/includes/javascript/orgGroup.js
===================================================================
diff -u -r2d50303390a6ea1ec157a3a1390ecf3833c0339c -ra0bea10c9022cc2146b3067858932029ca721683
--- lams_central/web/includes/javascript/orgGroup.js (.../orgGroup.js) (revision 2d50303390a6ea1ec157a3a1390ecf3833c0339c)
+++ lams_central/web/includes/javascript/orgGroup.js (.../orgGroup.js) (revision a0bea10c9022cc2146b3067858932029ca721683)
@@ -481,4 +481,114 @@
$('.removeGroupButton', container).remove();
// $('input', container).attr('readonly', 'readonly');
$('div.draggableUser', container).off('click').draggable('disable');
-}
\ No newline at end of file
+}
+
+/**
+ * *************** Save as a course grouping dialog ***************
+ */
+
+//open save as a course grouping dialog
+function saveAsCourseGrouping() {
+ $('#saveAsCourseGroupingDialog').modal('show');
+}
+
+$(document).ready(function(){
+
+ // sets up dialog for editing class
+ var saveAsCourseGroupingDialog = showDialog('saveAsCourseGroupingDialog',{
+ 'autoOpen' : false,
+ 'width' : 510,
+ 'title' : LABELS.SAVE_AS_COURSE_GROUPING_LABEL,
+ 'resizable' : true,
+ 'open' : function(){
+ //focus name text field
+ setTimeout(
+ function() {
+ $('#dialog-course-grouping-name').focus();
+ },
+ 700
+ );
+ },
+ 'close' : function(){
+ //reset dialog to its initial state
+ resetSaveGroupingDialog();
+ $('#dialog-course-grouping-name', this).val("");
+ }
+ }, false);
+
+ $('.modal-body', saveAsCourseGroupingDialog).empty().append($('#save-course-grouping-dialog-contents').show());
+
+ //save button handler
+ $('#dialog-save-button', saveAsCourseGroupingDialog).click(function() {
+ var dialog = $('#saveAsCourseGroupingDialog'),
+ name = $('#dialog-course-grouping-name', dialog).val();
+
+ //name can't be blank
+ if (!name || /^\s*$/.test(name)) {
+ $('#dialog-course-grouping-name', dialog).addClass("alert-danger");
+ $("#span-tooltip", dialog).addClass("alert-danger").text(LABELS.NAME_BLANK_LABEL);
+ return;
+ }
+
+ //name should be unique
+ $.ajax({
+ dataType : 'json',
+ url : LAMS_URL + 'monitoring/grouping.do',
+ cache : false,
+ async : false,
+ data : {
+ 'method' : 'checkGroupingNameUnique',
+ 'organisationID' : organisationId,
+ 'name' : name
+ },
+ success : function(response) {
+ if (response.isGroupingNameUnique) {
+ $.ajax({
+ dataType : 'json',
+ url : LAMS_URL + 'monitoring/grouping.do',
+ cache : false,
+ async : false,
+ data : {
+ 'method' : 'saveAsCourseGrouping',
+ 'organisationID' : organisationId,
+ 'activityID' : groupingActivityId,
+ 'name' : name
+ },
+ success : function(response) {
+ $('#saveAsCourseGroupingDialog').modal('hide');
+ alert(LABELS.SAVED_SUCCESSFULLY_LABEL);
+ }
+ });
+
+ } else {
+ $('#dialog-course-grouping-name', dialog).addClass("alert-danger");
+ $("#span-tooltip", dialog).addClass("alert-danger").text(LABELS.NAME_NOT_UNIQUE_LABEL);
+ }
+ }
+ });
+ });
+
+ //close button handler
+ $('#dialog-close-button', saveAsCourseGroupingDialog).click(function(){
+ $('#saveAsCourseGroupingDialog').modal('hide');
+ });
+
+ // ability to save a grouping on pressing the Enter key in the name input field
+ $('#dialog-course-grouping-name', saveAsCourseGroupingDialog).on('keyup', function (e) {
+ //remove alert class if it was applied
+ if ($("#span-tooltip", saveAsCourseGroupingDialog).hasClass("alert-danger")) {
+ resetSaveGroupingDialog();
+ }
+
+ if (e.keyCode == 13) {
+ $('#dialog-save-button', saveAsCourseGroupingDialog).trigger( "click" );
+ }
+ });
+
+ //reset dialog to its initial state
+ function resetSaveGroupingDialog() {
+ $("#span-tooltip", saveAsCourseGroupingDialog).removeClass("alert-danger").text(LABELS.ENTER_COURSE_GROUPING_NAME_LABEL);
+ $('#dialog-course-grouping-name', saveAsCourseGroupingDialog).removeClass("alert alert-danger");
+ }
+
+});
\ No newline at end of file
Index: lams_central/web/orgGroup.jsp
===================================================================
diff -u -r2d50303390a6ea1ec157a3a1390ecf3833c0339c -ra0bea10c9022cc2146b3067858932029ca721683
--- lams_central/web/orgGroup.jsp (.../orgGroup.jsp) (revision 2d50303390a6ea1ec157a3a1390ecf3833c0339c)
+++ lams_central/web/orgGroup.jsp (.../orgGroup.jsp) (revision a0bea10c9022cc2146b3067858932029ca721683)
@@ -44,12 +44,31 @@
GROUP_LOCK_LABEL : decoderDiv.html('').text(),
- TRANSFER_LOCKED_LABEL : decoderDiv.html('').text()
+ TRANSFER_LOCKED_LABEL : decoderDiv.html('').text(),
+
+ SAVE_AS_COURSE_GROUPING_LABEL : decoderDiv.html('').text(),
+
+ NAME_BLANK_LABEL : decoderDiv.html('').text(),
+
+ NAME_NOT_UNIQUE_LABEL : decoderDiv.html('').text(),
+
+ ENTER_COURSE_GROUPING_NAME_LABEL : decoderDiv.html('').text(),
+
+ SAVED_SUCCESSFULLY_LABEL : decoderDiv.html('').text()
};
+
+
+
+
+
+
@@ -125,5 +144,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/GroupingAJAXAction.java
===================================================================
diff -u -r51f0b0d75529c154910d175aad7d0f26acdf0597 -ra0bea10c9022cc2146b3067858932029ca721683
--- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/GroupingAJAXAction.java (.../GroupingAJAXAction.java) (revision 51f0b0d75529c154910d175aad7d0f26acdf0597)
+++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/GroupingAJAXAction.java (.../GroupingAJAXAction.java) (revision a0bea10c9022cc2146b3067858932029ca721683)
@@ -25,14 +25,19 @@
import java.io.IOException;
import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForm;
@@ -49,11 +54,20 @@
import org.lamsfoundation.lams.lesson.service.LessonServiceException;
import org.lamsfoundation.lams.monitoring.service.IMonitoringService;
import org.lamsfoundation.lams.monitoring.service.MonitoringServiceProxy;
+import org.lamsfoundation.lams.security.ISecurityService;
+import org.lamsfoundation.lams.usermanagement.OrganisationGroup;
+import org.lamsfoundation.lams.usermanagement.OrganisationGrouping;
+import org.lamsfoundation.lams.usermanagement.Role;
import org.lamsfoundation.lams.usermanagement.User;
+import org.lamsfoundation.lams.usermanagement.dto.UserDTO;
+import org.lamsfoundation.lams.usermanagement.service.IUserManagementService;
import org.lamsfoundation.lams.usermanagement.util.FirstNameAlphabeticComparator;
import org.lamsfoundation.lams.util.WebUtil;
import org.lamsfoundation.lams.web.action.LamsDispatchAction;
+import org.lamsfoundation.lams.web.session.SessionManager;
import org.lamsfoundation.lams.web.util.AttributeNames;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.WebApplicationContextUtils;
/**
* The action servlet that provides the support for the
@@ -78,6 +92,8 @@
public static final String PARAM_MAY_DELETE = "mayDelete";
public static final String PARAM_USED_FOR_BRANCHING = "usedForBranching";
public static final String PARAM_VIEW_MODE = "viewMode";
+
+ private static ISecurityService securityService;
/**
* Start the process of doing the chosen grouping
@@ -148,29 +164,6 @@
}
/**
- * Remove a list of users from a group. Designed to respond to an AJAX call.
- *
- * Input parameters: activityID, name: group name, members: comma separated list of users
- *
- * Output format: no data returned - just the header
- */
- public ActionForward removeMembers(ActionMapping mapping, ActionForm form, HttpServletRequest request,
- HttpServletResponse response) throws IOException, ServletException, LessonServiceException {
-
- Long activityID = WebUtil.readLongParam(request, AttributeNames.PARAM_ACTIVITY_ID);
- Long groupID = WebUtil.readLongParam(request, AttributeNames.PARAM_GROUP_ID);
- String members = WebUtil.readStrParam(request, GroupingAJAXAction.PARAM_MEMBERS, true);
- if (members != null) {
- String[] membersSplit = members.split(",");
- IMonitoringService monitoringService = MonitoringServiceProxy
- .getMonitoringService(getServlet().getServletContext());
- monitoringService.removeUsersFromGroup(activityID, groupID, membersSplit);
- }
- writeAJAXOKResponse(response);
- return null;
- }
-
- /**
* Moves users between groups, removing them from previous group and creating a new one, if needed.
*/
public ActionForward addMembers(ActionMapping mapping, ActionForm form, HttpServletRequest request,
@@ -259,7 +252,60 @@
response.getWriter().write(responseJSON.toString());
return null;
}
+
+ /**
+ * Stores lesson grouping as a course grouping.
+ */
+ public ActionForward saveAsCourseGrouping(ActionMapping mapping, ActionForm form, HttpServletRequest request,
+ HttpServletResponse response) throws JSONException, IOException {
+ IMonitoringService monitoringService = MonitoringServiceProxy
+ .getMonitoringService(getServlet().getServletContext());
+ IUserManagementService userManagementService = MonitoringServiceProxy
+ .getUserManagementService(getServlet().getServletContext());
+ HttpSession ss = SessionManager.getSession();
+ Integer userId = ((UserDTO) ss.getAttribute(AttributeNames.USER)).getUserID();
+ Integer organisationId = WebUtil.readIntParam(request, AttributeNames.PARAM_ORGANISATION_ID);
+ String newGroupingName = request.getParameter("name");
+
+ // check if user is allowed to view and edit groupings
+ if (!getSecurityService().hasOrgRole(organisationId, userId,
+ new String[] { Role.GROUP_ADMIN, Role.GROUP_MANAGER, Role.MONITOR, Role.AUTHOR },
+ "view organisation groupings", false)) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN, "User is not a participant in the organisation");
+ return null;
+ }
+ Long activityID = WebUtil.readLongParam(request, AttributeNames.PARAM_ACTIVITY_ID);
+ Activity activity = monitoringService.getActivityById(activityID);
+ Grouping grouping = activity.isChosenBranchingActivity() ? activity.getGrouping()
+ : ((GroupingActivity) activity).getCreateGrouping();
+
+ // iterate over groups
+ List orgGroups = new LinkedList();
+ for (Group group : grouping.getGroups()) {
+ OrganisationGroup orgGroup = new OrganisationGroup();
+ //groupId and GroupingId will be set during userManagementService.saveOrganisationGrouping() call
+ orgGroup.setName(group.getGroupName());
+ HashSet users = new HashSet();
+ users.addAll(group.getUsers());
+ orgGroup.setUsers(users);
+
+ orgGroups.add(orgGroup);
+ }
+
+ OrganisationGrouping orgGrouping = new OrganisationGrouping();
+ orgGrouping.setOrganisationId(organisationId);
+ orgGrouping.setName(newGroupingName);
+
+ userManagementService.saveOrganisationGrouping(orgGrouping, orgGroups);
+
+ response.setContentType("application/json;charset=utf-8");
+ JSONObject responseJSON = new JSONObject();
+ responseJSON.put("result", true);
+ response.getWriter().write(responseJSON.toString());
+ return null;
+ }
+
/**
* Renames the group.
*/
@@ -277,7 +323,32 @@
}
return null;
}
+
+ /**
+ * Checks if a course grouping name is unique inside of this organisation and thus whether the new group can be named using it
+ */
+ public ActionForward checkGroupingNameUnique(ActionMapping mapping, ActionForm form, HttpServletRequest request,
+ HttpServletResponse response) throws JSONException, IOException {
+ IUserManagementService userManagementService = MonitoringServiceProxy.getUserManagementService(getServlet().getServletContext());
+
+ Integer organisationId = WebUtil.readIntParam(request, AttributeNames.PARAM_ORGANISATION_ID);
+ String newGroupingName = request.getParameter("name");
+ // Checks if a course grouping name is unique inside of this group and thus new group can have it
+ HashMap properties = new HashMap();
+ properties.put("organisationId", organisationId);
+ properties.put("name", newGroupingName);
+ List orgGroupings = userManagementService.findByProperties(OrganisationGrouping.class,
+ properties);
+ boolean isGroupingNameUnique = orgGroupings.isEmpty();
+
+ JSONObject responseJSON = new JSONObject();
+ responseJSON.put("isGroupingNameUnique", isGroupingNameUnique);
+ response.setContentType("application/json;charset=utf-8");
+ response.getWriter().write(responseJSON.toString());
+ return null;
+ }
+
/**
* Checks if a group can be removed and performs it.
*/
@@ -311,4 +382,13 @@
response.getWriter().write(responseJSON.toString());
return null;
}
+
+ private ISecurityService getSecurityService() {
+ if (securityService == null) {
+ WebApplicationContext ctx = WebApplicationContextUtils
+ .getRequiredWebApplicationContext(getServlet().getServletContext());
+ securityService = (ISecurityService) ctx.getBean("securityService");
+ }
+ return securityService;
+ }
}