Index: lams_build/lib/lams/lams.jar =================================================================== diff -u -ree35ce3afcea957fc919c15fb254ae593cdb44c2 -r668a627903b72826f7dffa148a7e775139af8b5e Binary files differ Index: lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java =================================================================== diff -u -ree35ce3afcea957fc919c15fb254ae593cdb44c2 -r668a627903b72826f7dffa148a7e775139af8b5e --- lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java (.../ObjectExtractor.java) (revision ee35ce3afcea957fc919c15fb254ae593cdb44c2) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java (.../ObjectExtractor.java) (revision 668a627903b72826f7dffa148a7e775139af8b5e) @@ -1753,7 +1753,7 @@ if (grouping != null) { setGrouping(activity, grouping, groupingUIID); } else { - log.warn("Unable to find matching grouping for groupingUIID" + groupingUIID + ". Activity UUID " + log.warn("Unable to find matching grouping for groupingUIID " + groupingUIID + ". Activity UUID " + activityUIID + " will not be grouped."); clearGrouping(activity); } Index: lams_central/web/includes/javascript/authoring/authoringActivity.js =================================================================== diff -u -ree35ce3afcea957fc919c15fb254ae593cdb44c2 -r668a627903b72826f7dffa148a7e775139af8b5e --- lams_central/web/includes/javascript/authoring/authoringActivity.js (.../authoringActivity.js) (revision ee35ce3afcea957fc919c15fb254ae593cdb44c2) +++ lams_central/web/includes/javascript/authoring/authoringActivity.js (.../authoringActivity.js) (revision 668a627903b72826f7dffa148a7e775139af8b5e) @@ -9,7 +9,7 @@ */ ToolActivity : function(id, uiid, toolContentID, toolID, x, y, title, supportsOutputs) { this.id = +id; - this.uiid = +uiid || ++layout.maxUIID; + this.uiid = +uiid || ++layout.ld.maxUIID; this.toolContentID = toolContentID; this.type = 'tool'; this.toolID = +toolID; @@ -29,11 +29,12 @@ /** * Constructor for a Grouping Activity. */ - GroupingActivity : function(id, uiid, x, y, title, groupingID, groupingType, groupDivide, groupCount, learnerCount, - equalSizes, viewLearners, groups) { + GroupingActivity : function(id, uiid, x, y, title, groupingID, groupingUIID, groupingType, groupDivide, + groupCount, learnerCount, equalSizes, viewLearners, groups) { this.id = +id; - this.uiid = +uiid || ++layout.maxUIID; this.groupingID = +groupingID; + this.groupingUIID = +groupingUIID || ++layout.ld.maxUIID; + this.uiid = +uiid || ++layout.ld.maxUIID; this.type = 'grouping'; this.title = title; this.groupingType = groupingType || 'random'; @@ -59,7 +60,7 @@ */ GateActivity : function(id, uiid, x, y, gateType) { this.id = +id; - this.uiid = +uiid || ++layout.maxUIID; + this.uiid = +uiid || ++layout.ld.maxUIID; this.type = 'gate'; this.gateType = gateType || 'permission'; this.transitions = { @@ -109,7 +110,7 @@ */ BranchingActivity : function(id, uiid, branchingEdgeStart) { this.id = +id; - this.uiid = +uiid || ++layout.maxUIID; + this.uiid = +uiid || ++layout.ld.maxUIID; this.start = branchingEdgeStart; this.branches = []; // mapping between groups and branches, if applicable @@ -122,7 +123,7 @@ */ BranchActivity : function(id, uiid, title, branchingActivity, transitionFrom) { this.id = +id; - this.uiid = +uiid || ++layout.maxUIID; + this.uiid = +uiid || ++layout.ld.maxUIID; this.title = title; this.transitionFrom = transitionFrom; this.branchingActivity = branchingActivity; @@ -182,7 +183,7 @@ paper.setStart(); var shape = paper.path(Raphael.format('M {0} {1}' + layout.defs.activity, x, y)) .attr({ - 'fill' : layout.colors.activity + 'fill' : layout.colors.grouping }); paper.image('../images/grouping.gif', x + 47, y + 2, 30, 30); @@ -385,7 +386,7 @@ 'fill' : layout.colors.transition }); var transition = paper.setFinish(); - transition.uiid = uiid || ++layout.maxUIID; + transition.uiid = uiid || ++layout.ld.maxUIID; transition.id = id; transition.data('transition', transition); @@ -597,15 +598,15 @@ data : { 'method' : 'createToolContent', 'toolID' : activity.toolID, - 'contentFolderID' : layout.contentFolderID + 'contentFolderID' : layout.ld.contentFolderID }, success : function(response) { activity.authorURL = response.authorURL; activity.toolContentID = response.toolContentID; - if (!layout.contentFolderID) { + if (!layout.ld.contentFolderID) { // if LD did not have contentFolderID, it was just generated // so remember it - layout.contentFolderID = response.contentFolderID; + layout.ld.contentFolderID = response.contentFolderID; } } }); Index: lams_central/web/includes/javascript/authoring/authoringGeneral.js =================================================================== diff -u -ree35ce3afcea957fc919c15fb254ae593cdb44c2 -r668a627903b72826f7dffa148a7e775139af8b5e --- lams_central/web/includes/javascript/authoring/authoringGeneral.js (.../authoringGeneral.js) (revision ee35ce3afcea957fc919c15fb254ae593cdb44c2) +++ lams_central/web/includes/javascript/authoring/authoringGeneral.js (.../authoringGeneral.js) (revision 668a627903b72826f7dffa148a7e775139af8b5e) @@ -8,7 +8,6 @@ // configuration and storage of various elements layout = { - 'maxUIID' : 0, // 'isZoomed' : false, 'activities' : null, 'items' : { @@ -22,7 +21,7 @@ 'groupNamingDialog' : null, 'groupsToBranchesMappingDialog' : null }, - + 'dialogs' : [], 'toolMetadata': { 'grouping' : { 'iconPath' : '../images/grouping.gif' @@ -54,6 +53,7 @@ 'offlineActivity' : 'black', 'activityText' : 'black', 'offlineActivityText' : 'white', + 'grouping' : '#A9C8FD', 'gate' : 'red', 'gateText' : 'white', 'branchingEdgeStart' : 'green', @@ -148,7 +148,14 @@ * Initialises various Authoring widgets. */ function initLayout() { - $('#tabs').tabs(); + $('#tabs').tabs({ + 'activate' : function(){ + // close all opened dialogs + $.each(layout.dialogs, function() { + this.dialog('close'); + }); + } + }); $('#tabs .ui-tabs-nav, #tabs .ui-tabs-nav > *') .removeClass( "ui-corner-all ui-corner-top" ) .addClass( "ui-corner-bottom" ); @@ -244,6 +251,8 @@ } }); + layout.dialogs.push(ldStoreDialog); + $('#ldScreenshotAuthor', ldStoreDialog).load(function(){ // hide "loading" animation $('#ldStoreDialog .ldChoiceDependentCanvasElement').css('display', 'none'); @@ -286,9 +295,9 @@ if (event.node.highlightState == 0) { if (event.node.data.learningDesignId) { $('#ldStoreDialog #ldScreenshotLoading', dialog).css('display', 'inline'); - // get the image of the chosen LD + // get the image of the chosen LD and prevent caching $('#ldStoreDialog #ldScreenshotAuthor', dialog) - .attr('src', LD_THUMBNAIL_URL_BASE + event.node.data.learningDesignId); + .attr('src', LD_THUMBNAIL_URL_BASE + event.node.data.learningDesignId + '&_=' + new Date().getTime()); $('#ldStoreDialog #ldScreenshotAuthor', dialog).css({ 'width' : 'auto', 'height' : 'auto' @@ -319,6 +328,8 @@ of: '#canvas' } }); + + layout.dialogs.push(layout.items.infoDialog); } @@ -343,6 +354,12 @@ // remove existing activities MenuLib.newLearningDesign(true); + layout.ld = { + 'learningDesignID' : learningDesignID, + 'folderID' : ld.workspaceFolderID, + 'contentFolderID' : ld.contentFolderID, + 'title' : ld.title + }; $('#ldDescriptionFieldTitle').text(ld.title); $('#ldDescriptionFieldDescription').text(ld.description); @@ -361,8 +378,8 @@ activity = null; // find max uiid so newly created elements have, unique ones - if (activityData.activityUIID && layout.maxUIID < activityData.activityUIID) { - layout.maxUIID = activityData.activityUIID; + if (activityData.activityUIID && layout.ld.maxUIID < activityData.activityUIID) { + layout.ld,maxUIID = activityData.activityUIID; } switch(activityData.activityTypeID) { @@ -416,6 +433,7 @@ activityData.yCoord, activityData.activityTitle, groupingData.groupingID, + groupingData.groupingUIID, groupingType, groupingData.learnersPerGroup ? 'learners' : 'groups', groupingData.numberOfGroups, @@ -646,26 +664,44 @@ /** - * Stores the sequece into database. + * Stores the sequece in database. */ function saveLearningDesign(folderID, learningDesignID, title) { var activities = [], transitions = [], + groupings = [], + // trim the + title = title.trim(), + description = $('#ldDescriptionFieldDescription').val().trim(), + // final success/failure of the save result = false; $.each(layout.activities, function(){ var activity = this, activityBox = activity.items.shape.getBBox(), + activityTypeID = null, toolID = activity.toolID, - iconPath = null; + iconPath = null, + isGrouped = activity.grouping ? true : false; + if (toolID) { + // find out what is the icon for tool acitivty var templateIcon = $('.template[toolId=' + toolID +'] img'); if (templateIcon.width() > 0) { - // iconPath = layout.toolMetadata[toolID].iconPath; + iconPath = layout.toolMetadata[toolID].iconPath; } } - + // translate grouping type to back-end understandable + switch(activity.type) { + case 'tool' : + activityTypeID = 1; + break; + case 'grouping' : + activityTypeID = 2; + break; + } + // add activity activities.push({ 'activityID' : activity.id, 'activityUIID' : activity.uiid, @@ -674,21 +710,25 @@ 'toolContentID' : activity.toolContentID, 'stopAfterActivity' : false, 'groupingSupportType' : 2, - 'applyGrouping' : false, + 'applyGrouping' : isGrouped, + 'groupingUIID' : isGrouped ? activity.grouping.groupingUIID : null, + 'createGroupingUIID' : activity.type == 'grouping' ? activity.groupingUIID : null, 'parentActivityID' : null, 'parentUIID' : null, 'libraryActivityUIImage' : iconPath, 'xCoord' : activityBox.x, 'yCoord' : activityBox.y, 'activityTitle' : activity.title, - 'activityCategoryID' : layout.toolMetadata[toolID].activityCategoryID, - 'activityTypeID' : 1, + 'activityCategoryID' : activity.type == 'tool' ? + layout.toolMetadata[toolID].activityCategoryID : 1, + 'activityTypeID' : activityTypeID, 'gradebookToolOutputDefinitionName' : null, 'helpText' : null, 'description' : null }); - + + // iterate over transitions and create a list $.each(activity.transitions.from, function(){ var transition = this; @@ -700,6 +740,43 @@ 'transitionType' : 0 }); }); + + if (activity.type == 'grouping') { + // create a list of groupings + var groups = [], + groupingType = null; + $.each(activity.groups, function(groupIndex, group){ + groups.push({ + 'groupName' : group.name, + 'groupID' : group.id, + 'groupUIID' : group.uiid, + 'orderID' : groupIndex + }); + }); + + switch(activity.groupingType) { + case 'random' : + groupingType = 1; + break; + case 'monitor' : + groupingType = 2; + break; + case 'learner' : + groupingType = 4; + break; + } + + groupings.push({ + 'groupingUIID' : activity.groupingUIID, + 'groupingTypeID' : groupingType, + 'learnersPerGroup' : activity.learnerCount, + 'equalNumberOfLearnersPerGroup' : activity.equalSizes, + 'viewStudentsBeforeSelection' : activity.viewLearners, + 'maxNumberOfGroups' : activity.groupCount, + 'numberOfGroups' : groups.length, + 'groups' : groups + }); + } }); // serialise the sequence @@ -709,28 +786,26 @@ 'workspaceFolderID' : folderID, 'copyTypeID' : 1, 'originalUserID' : null, - 'title' : title.trim(), - 'description' : $('#ldDescriptionFieldDescription').val().trim(), - 'maxID' : layout.maxUIID, + 'title' : title, + 'description' : description, + 'maxID' : layout.ld.maxUIID, 'readOnly' : false, 'editOverrideLock' : false, 'dateReadOnly' : null, 'version' : null, - 'contentFolderID' : layout.contentFolderID, + 'contentFolderID' : layout.ld.contentFolderID, 'saveMode' : 0, 'originalLearningDesignID' : null, 'activities' : activities, 'transitions' : transitions, - 'groupings' : null, + 'groupings' : groupings, 'branchMappings' : null, - 'learningDesignUIID' : null, 'helpText' : null, 'duration' : null, 'licenseID' : null, 'licenseText' : null - }; // get LD details @@ -744,18 +819,25 @@ 'ld' : JSON.stringify(ld) }, success : function(response) { + // if save was successful if (response.learningDesignID) { - layout.learningDesignID = response.learningDesignID; - layout.folderID = folderID; - layout.title = title; - if (!layout.contentFolderID) { - layout.contentFolderID = response.contentFolderID; + // assing the database-generated values + layout.ld.learningDesignID = response.learningDesignID; + layout.ld.folderID = folderID; + layout.ld.title = title; + if (!layout.ld.contentFolderID) { + layout.ld.contentFolderID = response.contentFolderID; } + $('#ldDescriptionFieldTitle').text(title); + $('#ldDescriptionFieldDescription').text(description); + + // check if there were any validation errors if (response.validation.length > 0) { var message = 'While saving the sequence there were following validation issues:\n'; $.each(response.validation, function() { var uiid = this.UIID, title = ''; + // find which activity is the error about $.each(layout.activities, function(){ if (uiid == this.uiid) { title = this.title + ': '; @@ -768,6 +850,7 @@ return; } + // assign database-generated properties to activities $.each(response.activities, function() { var updatedActivity = this; $.each(layout.activities, function(){ @@ -779,6 +862,7 @@ }); }); + alert('Congratulations! Your design is valid and has been saved.'); result = true; } else { alert('Error while saving the sequence'); Index: lams_central/web/includes/javascript/authoring/authoringMenu.js =================================================================== diff -u -ree35ce3afcea957fc919c15fb254ae593cdb44c2 -r668a627903b72826f7dffa148a7e775139af8b5e --- lams_central/web/includes/javascript/authoring/authoringMenu.js (.../authoringMenu.js) (revision ee35ce3afcea957fc919c15fb254ae593cdb44c2) +++ lams_central/web/includes/javascript/authoring/authoringMenu.js (.../authoringMenu.js) (revision 668a627903b72826f7dffa148a7e775139af8b5e) @@ -89,7 +89,7 @@ x = translatedEvent[0] - 47, y = translatedEvent[1] - 2; - layout.activities.push(new ActivityLib.GroupingActivity(null, x, y, 'Grouping')); + layout.activities.push(new ActivityLib.GroupingActivity(null, null, x, y, 'Grouping')); }); }, @@ -159,9 +159,9 @@ * Opens "Save sequence" dialog where an user can choose where to save the Learning Design. */ saveLearningDesign : function(showDialog){ - if (!showDialog && layout.learningDesignID) { + if (!showDialog && layout.ld.learningDesignID) { if (confirm('Are you sure you want to overwrite the existing sequence?')) { - saveLearningDesign(layout.folderID, layout.learningDesignID, layout.title); + saveLearningDesign(layout.ld.folderID, layout.ld.learningDesignID, layout.ld.title); } return; } @@ -458,7 +458,9 @@ $('.ldDescriptionField').text(''); - layout.maxUIID = 0; + layout.ld = { + 'maxUIID' : 0 + }; layout.activities = []; if (paper) { paper.clear(); Index: lams_central/web/includes/javascript/authoring/authoringProperty.js =================================================================== diff -u -ree35ce3afcea957fc919c15fb254ae593cdb44c2 -r668a627903b72826f7dffa148a7e775139af8b5e --- lams_central/web/includes/javascript/authoring/authoringProperty.js (.../authoringProperty.js) (revision ee35ce3afcea957fc919c15fb254ae593cdb44c2) +++ lams_central/web/includes/javascript/authoring/authoringProperty.js (.../authoringProperty.js) (revision 668a627903b72826f7dffa148a7e775139af8b5e) @@ -27,8 +27,8 @@ .css('opacity', layout.conf.propertiesDialogDimOpacity) .mousemove(HandlerLib.approachPropertiesDialogHandler) .find('.ui-dialog-titlebar-close').remove(); + layout.dialogs.push(propertiesDialog); - // initialise dialog from group naming layout.items.groupNamingDialog = $('
').dialog({ 'autoOpen' : false, @@ -62,6 +62,7 @@ } ] }); + layout.dialogs.push(layout.items.groupNamingDialog); // initialise dialog from matching groups to branches in branching activities @@ -86,8 +87,8 @@ // find references to groups and branches branchingActivity.groupsToBranches = []; $('#gtbMappingGroupCell div', dialog).each(function(){ - var groupUIID = $(this).attr('uiid'), - branchUIID = $(this).data('boundItem').attr('uiid'), + var groupUIID = +$(this).attr('uiid'), + branchUIID = +$(this).data('boundItem').attr('uiid'), group = null, branch = null; @@ -135,6 +136,8 @@ }, 'text' : false }); + + layout.dialogs.push(gtbDialog); }, @@ -216,8 +219,8 @@ $('.propertiesContentFieldNameGroups', content).css('display', activity.groupDivide == 'groups' ? '' : 'none'); - activity.groupCount = $('.propertiesContentFieldGroupCount', content).val(); - activity.learnerCount = $('.propertiesContentFieldLearnerCount', content).val(); + activity.groupCount = +$('.propertiesContentFieldGroupCount', content).val(); + activity.learnerCount = +$('.propertiesContentFieldLearnerCount', content).val(); activity.equalSizes = $('.propertiesContentFieldEqualSizes', content).is(':checked'); activity.viewLearners = $('.propertiesContentFieldViewLearners', content).is(':checked'); Index: lams_common/src/java/org/lamsfoundation/lams/util/svg/SVGGenerator.java =================================================================== diff -u -rd931a6affbb047b66932cde407f4c80348501567 -r668a627903b72826f7dffa148a7e775139af8b5e --- lams_common/src/java/org/lamsfoundation/lams/util/svg/SVGGenerator.java (.../SVGGenerator.java) (revision d931a6affbb047b66932cde407f4c80348501567) +++ lams_common/src/java/org/lamsfoundation/lams/util/svg/SVGGenerator.java (.../SVGGenerator.java) (revision 668a627903b72826f7dffa148a7e775139af8b5e) @@ -195,7 +195,7 @@ // **************** Draw transitions******************************************************** - ArrayList