accessList = getAuthoringService().updateLearningDesignAccessByUser(userId);
Index: lams_central/src/java/org/lamsfoundation/lams/workspace/service/WorkspaceManagementService.java
===================================================================
diff -u -reeb8faaea5372ccf5445d7172f726931e9f26098 -r7b0401fe54636737b72030c60fd9292956e79487
--- lams_central/src/java/org/lamsfoundation/lams/workspace/service/WorkspaceManagementService.java (.../WorkspaceManagementService.java) (revision eeb8faaea5372ccf5445d7172f726931e9f26098)
+++ lams_central/src/java/org/lamsfoundation/lams/workspace/service/WorkspaceManagementService.java (.../WorkspaceManagementService.java) (revision 7b0401fe54636737b72030c60fd9292956e79487)
@@ -435,6 +435,7 @@
learningDesignJSON.put("canModify",
WorkspaceFolder.OWNER_ACCESS.equals(folderContent.getPermissionCode())
|| ((user != null) && isSysAuthorAdmin(user)));
+ learningDesignJSON.put("readOnly", folderContent.getReadOnly());
result.append("learningDesigns", learningDesignJSON);
}
} else {
@@ -453,7 +454,8 @@
JSONArray result = new JSONArray();
Pattern searchPattern = searchString != null
- ? Pattern.compile(Pattern.quote(searchString), Pattern.CASE_INSENSITIVE) : null;
+ ? Pattern.compile(Pattern.quote(searchString), Pattern.CASE_INSENSITIVE)
+ : null;
FolderContentDTO userFolder = getUserWorkspaceFolder(userID);
long numDesigns = 0;
Index: lams_central/web/authoring/authoring.jsp
===================================================================
diff -u -rf75e35d4e90a3c49f51ba59eebcc1f63d8ee0bcc -r7b0401fe54636737b72030c60fd9292956e79487
--- lams_central/web/authoring/authoring.jsp (.../authoring.jsp) (revision f75e35d4e90a3c49f51ba59eebcc1f63d8ee0bcc)
+++ lams_central/web/authoring/authoring.jsp (.../authoring.jsp) (revision 7b0401fe54636737b72030c60fd9292956e79487)
@@ -124,6 +124,8 @@
SEQUENCE_EXISTS_ERROR : decoderDiv.html('').text(),
SEQUENCE_SAVE_ERROR : decoderDiv.html('').text(),
+
+ READONLY_FORBIDDEN_ERROR : decoderDiv.html('').text(),
SVG_SAVE_ERROR : decoderDiv.html('').text(),
@@ -278,7 +280,8 @@
CONDITIONS_MAPPING_BROKEN_ERROR : decoderDiv.html('').text()
},
-
+
+ canSetReadOnly = ${canSetReadOnly},
isReadOnlyMode = false,
activitiesOnlySelectable = false,
initContentFolderID = '${contentFolderID}',
@@ -555,6 +558,11 @@
+
+
Index: lams_central/web/authoring/svgGenerator.jsp
===================================================================
diff -u -rcb63a28069a1267691684394eb67c7eee0f77fde -r7b0401fe54636737b72030c60fd9292956e79487
--- lams_central/web/authoring/svgGenerator.jsp (.../svgGenerator.jsp) (revision cb63a28069a1267691684394eb67c7eee0f77fde)
+++ lams_central/web/authoring/svgGenerator.jsp (.../svgGenerator.jsp) (revision 7b0401fe54636737b72030c60fd9292956e79487)
@@ -47,6 +47,7 @@
},
paperMinWidth = 1000,
+ canSetReadOnly = false,
isReadOnlyMode = true,
activitiesOnlySelectable = ${param.selectable eq 'true'},
initLearningDesignID = '${param.learningDesignID}';
Index: lams_central/web/css/_authoring_base.scss
===================================================================
diff -u -r18448ae0a8003d82f840fc3f20af8a0b5d197ba1 -r7b0401fe54636737b72030c60fd9292956e79487
--- lams_central/web/css/_authoring_base.scss (.../_authoring_base.scss) (revision 18448ae0a8003d82f840fc3f20af8a0b5d197ba1)
+++ lams_central/web/css/_authoring_base.scss (.../_authoring_base.scss) (revision 7b0401fe54636737b72030c60fd9292956e79487)
@@ -230,6 +230,10 @@
overflow: auto;
}
+div#ldStoreDialogContents div#ldStoreDialogTree .readOnly {
+ font-style: italic;
+}
+
div#ldStoreDialogContents #ldStoreDialogAccessCell {
border-top: $border-thin-dotted;
border-right: $border-thin-dotted;
@@ -281,6 +285,14 @@
width: 99%;
}
+div#ldStoreDialogContents #ldStoreDialogReadOnlyCheckbox {
+ vertical-align: top;
+}
+
+div#ldStoreDialogContents #ldStoreDialogReadOnlySpan {
+ padding-left: 5px;
+}
+
div#ldStoreDialogContents div#ldStoreDialogNameContainer {
margin-left: 20px;
}
Index: lams_central/web/includes/javascript/authoring/authoringGeneral.js
===================================================================
diff -u -r8f28a31b3105724e7edfa8dd2df58cf5a0473d77 -r7b0401fe54636737b72030c60fd9292956e79487
--- lams_central/web/includes/javascript/authoring/authoringGeneral.js (.../authoringGeneral.js) (revision 8f28a31b3105724e7edfa8dd2df58cf5a0473d77)
+++ lams_central/web/includes/javascript/authoring/authoringGeneral.js (.../authoringGeneral.js) (revision 7b0401fe54636737b72030c60fd9292956e79487)
@@ -134,7 +134,8 @@
'selectEffect' : 'black',
'transition' : 'rgb(119,126,157)',
// highlight TBL activities which should be grouped
- 'activityRequireGrouping' : 'red'
+ 'activityRequireGrouping' : 'red',
+ 'activityReadOnly' : 'red'
},
'defaultTextAttributes' : {
@@ -544,6 +545,7 @@
});
$('#ldStoreDialogSaveButton', ldStoreDialogContents).click(function(){
+ debugger;
var dialog = layout.ldStoreDialog,
title = $('#ldStoreDialogNameContainer input', dialog).val().trim();
if (!title) {
@@ -556,8 +558,7 @@
return;
}
- var learningDesignID = null,
- folderNode = null,
+ var folderNode = null,
folderID = null,
tree = dialog.data('ldTree'),
node = tree.getHighlightedNode();
@@ -588,21 +589,27 @@
// if a node is highlighted but user modified the title,
// it is considered a new sequence
// otherwise check if there is no other sequence with the same name
+ var nodeData = null;
if (folderNode && folderNode.children) {
$.each(folderNode.children, function(){
if (this.label == title) {
this.highlight();
- learningDesignID = this.data.learningDesignId;
+ nodeData = this.data;
return false;
}
});
}
- if (learningDesignID
- && !confirm(LABELS.SEQUENCE_OVERWRITE_CONFIRM)) {
+ if (nodeData && (!nodeData.canModify || (!canSetReadOnly && nodeData.readOnly))){
+ alert(LABELS.READONLY_FORBIDDEN_ERROR);
return;
}
-
- var result = GeneralLib.saveLearningDesign(folderID, learningDesignID, title);
+ if (nodeData && !confirm(LABELS.SEQUENCE_OVERWRITE_CONFIRM)) {
+ return;
+ }
+ var readOnly = (nodeData && !nodeData.canModify) ||
+ (canSetReadOnly && $('#ldStoreDialogReadOnlyCheckbox', dialog).prop('checked')),
+ learningDesignID = nodeData ? nodeData.learningDesignId : null,
+ result = GeneralLib.saveLearningDesign(folderID, learningDesignID, title, readOnly);
if (result) {
GeneralLib.openLearningDesign();
dialog.modal('hide');
@@ -754,8 +761,23 @@
$('.modal-title', layout.ldStoreDialog).text(dialogTitle);
var rightButtons = $('#ldStoreDialogRightButtonContainer', layout.ldStoreDialog);
$('button', rightButtons).hide();
+ $('#ldStoreDialogReadOnlyLabel *', layout.ldStoreDialog).hide();
$('#ldStoreDialogNameContainer, #ldStoreDialogImportPartFrame', layout.ldStoreDialog).hide();
$(shownElementIDs, layout.ldStoreDialog).show();
+
+ var isOpenDialog = shownElementIDs.indexOf('ldStoreDialogOpenButton') >= 0;
+ if (isOpenDialog) {
+ // in open dialog display only information
+ $('#ldStoreDialogReadOnlySpan', layout.ldStoreDialog).css('color', layout.colors.activityReadOnly);
+ } else if (canSetReadOnly) {
+ // the first highlighted folder is user's private folder
+ $('#ldStoreDialogReadOnlyCheckbox', layout.ldStoreDialog).show()
+ .prop('disabled', false).prop('checked', false);
+ $('#ldStoreDialogReadOnlySpan', layout.ldStoreDialog).show().css('color', 'initial');
+ } else {
+ $('#ldStoreDialogReadOnlySpan', layout.ldStoreDialog).css('color', layout.colors.activityReadOnly);
+ }
+
},
/**
* Extracts a selected activity from another LD.
@@ -927,7 +949,7 @@
// make folder contents load dynamically on open
tree.setDynamicLoad(function(node, callback){
// load subfolder contents
- var childNodeData = MenuLib.getFolderContents(node.data.folderID);
+ var childNodeData = MenuLib.getFolderContents(node.data.folderID, node.data.canSave, node.data.canHaveReadOnly);
if (childNodeData) {
$.each(childNodeData, function(){
// create and add a leaf
@@ -943,7 +965,8 @@
});
tree.singleNodeHighlight = true;
tree.subscribe('clickEvent', function(event) {
- var isOpenDialog = $('#ldStoreDialogSaveButton', layout.ldStoreDialog).is(':hidden');
+ var isOpenDialog = $('#ldStoreDialogSaveButton', layout.ldStoreDialog).is(':hidden')
+ nodeData = event.node.data;
//prevent item from being deselected on any subsequent clicks
if (isOpenDialog && event.node.highlightState == 1) {
@@ -953,14 +976,35 @@
//disable edit buttons if no elements is selected
$('#ldStoreDialogLeftButtonContainer button', layout.ldStoreDialog)
.prop('disabled', event.node.highlightState > 0);
-
+
+ if (canSetReadOnly && !isOpenDialog) {
+ // detect which folders/sequences are marked as read-only
+ // and which ones are immutable
+ if (event.node.isLeaf) {
+ $('#ldStoreDialogReadOnlyCheckbox', layout.ldStoreDialog)
+ .prop('disabled', !nodeData.canModify || !nodeData.canHaveReadOnly)
+ .prop('checked', nodeData.readOnly || !nodeData.canModify);
+ } else {
+ $('#ldStoreDialogReadOnlyCheckbox', layout.ldStoreDialog)
+ .prop('disabled', !nodeData.canSave || !nodeData.canHaveReadOnly)
+ .prop('checked', !nodeData.canSave);
+ }
+ } else {
+ // is this is normal user or open dialog, only show/hide read-only label
+ if (event.node.isLeaf ? nodeData.readOnly || !nodeData.canModify : !nodeData.canSave){
+ $('#ldStoreDialogReadOnlySpan', layout.ldStoreDialog).show();
+ } else {
+ $('#ldStoreDialogReadOnlySpan', layout.ldStoreDialog).hide();
+ }
+ }
+
// if it's a folder in load sequence dialog - highlight but stop processing
- if (isOpenDialog && !event.node.data.learningDesignId){
+ if (isOpenDialog && !nodeData.learningDesignId){
return true;
}
//show LearningDesign thumbnail and title
- var learningDesignID = event.node.highlightState == 0 ? +event.node.data.learningDesignId : null,
+ var learningDesignID = event.node.highlightState == 0 ? +nodeData.learningDesignId : null,
title = !isOpenDialog && learningDesignID ? event.node.label : null;
GeneralLib.showLearningDesignThumbnail(learningDesignID, title);
});
@@ -1642,8 +1686,7 @@
if (force) {
layout.ld = {
- 'maxUIID' : 0,
- 'designType' : null
+ 'maxUIID' : 0
};
layout.activities = [];
layout.regions = [];
@@ -1708,7 +1751,8 @@
'contentFolderID' : ld.contentFolderID,
'title' : ld.title,
'maxUIID' : 0,
- 'designType' : ld.designType
+ 'readOnly' : ld.readOnly,
+ 'canModify' : ld.copyTypeID == 1
};
if (!isReadOnlyMode) {
@@ -1721,6 +1765,8 @@
var arrangeNeeded = false,
// if system gate is found, it is Live Edit
systemGate = null,
+ // should we allow the author to enter activity authoring
+ activitiesReadOnly = !layout.ld.canModify || (!canSetReadOnly && layout.ld.readOnly),
branchToBranching = {},
// helper for finding last activity in a branch
branchToActivityDefs = {};
@@ -1749,7 +1795,7 @@
activityData.xCoord ? activityData.xCoord : 1,
activityData.yCoord ? activityData.yCoord : 1,
activityData.activityTitle,
- activityData.readOnly,
+ activityData.readOnly || activitiesReadOnly,
activityData.evaluation);
// for later reference
activityData.activity = activity;
@@ -1797,7 +1843,7 @@
activityData.xCoord,
activityData.yCoord,
activityData.activityTitle,
- activityData.readOnly,
+ activityData.readOnly || activitiesReadOnly,
groupingData.groupingID,
groupingData.groupingUIID,
groupingType,
@@ -1827,7 +1873,7 @@
activityData.yCoord,
activityData.activityTitle,
activityData.description,
- activityData.readOnly,
+ activityData.readOnly || activitiesReadOnly,
gateType,
activityData.gateStartTimeOffset,
activityData.gateActivityCompletionBased);
@@ -1846,7 +1892,7 @@
activityData.xCoord,
activityData.yCoord,
activityData.activityTitle,
- activityData.readOnly);
+ activityData.readOnly || activitiesReadOnly);
// for later reference
activityData.activity = activity;
// for later reference
@@ -1861,7 +1907,7 @@
activityData.xCoord,
activityData.yCoord,
activityData.activityTitle,
- activityData.readOnly,
+ activityData.readOnly || activitiesReadOnly,
activityData.minOptions,
activityData.maxOptions);
break;
@@ -1880,7 +1926,7 @@
arrangeNeeded ? 0 : activityData.startXCoord,
arrangeNeeded ? 0 : activityData.startYCoord,
activityData.activityTitle,
- activityData.readOnly,
+ activityData.readOnly || activitiesReadOnly,
branchingType);
layout.activities.push(branchingEdge);
// for later reference
@@ -2652,7 +2698,6 @@
'licenseText' : $('#ldDescriptionLicenseSelect').val() == "0"
|| $('#ldDescriptionLicenseSelect option:selected').attr('url')
? null : $('#ldDescriptionLicenseText').val(),
- 'designType' : layout.ld.designType,
'systemGate' : systemGate,
'activities' : activities,
'transitions' : transitions,
@@ -2724,7 +2769,7 @@
/**
* Stores the sequece in database.
*/
- saveLearningDesign : function(folderID, learningDesignID, title) {
+ saveLearningDesign : function(folderID, learningDesignID, title, readOnly) {
var ld = GeneralLib.prepareLearningDesignData(true);
if (!ld) {
return false;
@@ -2740,6 +2785,7 @@
ld.description = CKEDITOR.instances['ldDescriptionFieldDescription'].getData();
ld.saveMode = layout.ld.learningDesignID && layout.ld.learningDesignID != learningDesignID
? 1 : 0;
+ ld.readOnly = readOnly;
ld.systemGate = null;
$.ajax({
Index: lams_central/web/includes/javascript/authoring/authoringMenu.js
===================================================================
diff -u -rc1a5012654a6a505a5f8cec825c080f4d7f56a78 -r7b0401fe54636737b72030c60fd9292956e79487
--- lams_central/web/includes/javascript/authoring/authoringMenu.js (.../authoringMenu.js) (revision c1a5012654a6a505a5f8cec825c080f4d7f56a78)
+++ lams_central/web/includes/javascript/authoring/authoringMenu.js (.../authoringMenu.js) (revision 7b0401fe54636737b72030c60fd9292956e79487)
@@ -338,7 +338,7 @@
/**
* Loads subfolders and LDs from the server.
*/
- getFolderContents : function(folderID) {
+ getFolderContents : function(folderID, canSave, canHaveReadOnly) {
var result = null;
$.ajax({
@@ -353,26 +353,35 @@
dataType : 'json',
success : function(response) {
result = [];
-
// parse the response; extract folders and LDs
if (response.folders) {
- $.each(response.folders, function(){
- result.push({'type' : 'text',
- 'label' : this.isRunSequencesFolder ?
- LABELS.RUN_SEQUENCES_FOLDER : this.name,
- 'folderID' : this.folderID,
- 'canSave' : this.folderID > 0 && !this.isRunSequencesFolder,
- 'canModify' : this.canModify
+ $.each(response.folders, function(index){
+ // folderID == -2 is courses folder
+ var canSave = this.folderID > 0 && !this.isRunSequencesFolder;
+ result.push({'type' : 'text',
+ 'label' : this.isRunSequencesFolder ?
+ LABELS.RUN_SEQUENCES_FOLDER : this.name,
+ 'folderID' : this.folderID,
+ 'isRunSequenceFolder' : this.isRunSequencesFolder,
+ // either take parent's setting or take 2nd (courses) and 3rd (public) folder
+ 'canHaveReadOnly' : folderID ? canHaveReadOnly : index > 0,
+ 'canSave' : canSave,
+ 'canModify' : this.canModify && !this.isRunSequenceFolder,
+ 'labelStyle' : 'ygtvlabel' + (!canSave ? ' readOnly' : '')
});
});
}
if (response.learningDesigns) {
$.each(response.learningDesigns, function(){
+ var canModify = canSave && this.canModify;
result.push({'type' : 'text',
'label' : this.name,
'isLeaf' : true,
'learningDesignId' : this.learningDesignId,
- 'canModify' : this.canModify
+ 'canHaveReadOnly' : canHaveReadOnly,
+ 'canModify' : canModify,
+ 'readOnly' : this.readOnly,
+ 'labelStyle' : 'ygtvlabel' + (this.readOnly || !canModify ? ' readOnly' : '')
});
});
}
@@ -649,7 +658,11 @@
$('#saveButton').blur();
if (!showDialog && layout.ld.learningDesignID) {
- GeneralLib.saveLearningDesign(layout.ld.folderID, layout.ld.learningDesignID, layout.ld.title);
+ if (!layout.ld.canModify || (!canSetReadOnly && layout.ld.readOnly)) {
+ alert(LABELS.READONLY_FORBIDDEN_ERROR);
+ } else {
+ GeneralLib.saveLearningDesign(layout.ld.folderID, layout.ld.learningDesignID, layout.ld.title, layout.ld.readOnly);
+ }
return;
}