Index: content/content-tool/tool/src/java/org/sakaiproject/content/tool/ResourceConditionsHelper.java =================================================================== --- content/content-tool/tool/src/java/org/sakaiproject/content/tool/ResourceConditionsHelper.java (revision 0) +++ content/content-tool/tool/src/java/org/sakaiproject/content/tool/ResourceConditionsHelper.java (revision 0) @@ -0,0 +1,221 @@ +package org.sakaiproject.content.tool; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.sakaiproject.cheftool.Context; +import org.sakaiproject.cheftool.VelocityPortletPaneledAction; +import org.sakaiproject.component.cover.ComponentManager; +import org.sakaiproject.conditions.api.Condition; +import org.sakaiproject.conditions.api.Rule; +import org.sakaiproject.conditions.api.ConditionService; +import org.sakaiproject.content.cover.ContentHostingService; +import org.sakaiproject.entity.api.Entity; +import org.sakaiproject.event.api.Notification; +import org.sakaiproject.event.api.NotificationEdit; +import org.sakaiproject.event.api.NotificationLockedException; +import org.sakaiproject.event.api.NotificationNotDefinedException; +import org.sakaiproject.event.api.SessionState; +import org.sakaiproject.event.cover.EventTrackingService; +import org.sakaiproject.event.cover.NotificationService; +import org.sakaiproject.component.cover.ServerConfigurationService; +import org.sakaiproject.tool.cover.ToolManager; +import org.sakaiproject.util.ParameterParser; +import org.sakaiproject.util.ResourceLoader; + + +public class ResourceConditionsHelper extends VelocityPortletPaneledAction { + + /** + * + */ + private static final long serialVersionUID = -3875833398687224551L; + + static final Log logger = LogFactory.getLog(ResourceConditionsHelper.class); + + static final ConditionService conditionService = (ConditionService)ComponentManager.get("org.sakaiproject.conditions.api.ConditionService"); + + /** Resource bundle using current language locale */ + private static ResourceLoader rb = new ResourceLoader("content"); + + static void saveCondition(ListItem item, ParameterParser params, SessionState state, int index) { + if (! conditionsEnabled()) { + return; + } + boolean cbSelected = Boolean.valueOf(params.get("cbCondition" + ListItem.DOT + index)); + String selectedConditionValue = params.get("selectCondition" + ListItem.DOT + index); + if (selectedConditionValue == null) return; + logger.debug("Selected condition value: " + selectedConditionValue); + //The selectCondition value must be broken up so we can get at the values + //that make up the index, submittedFunctionName, missingTermQuery, and operatorValue in that order + String[] conditionTokens = selectedConditionValue.split("\\|"); + int selectedIndex = Integer.valueOf(conditionTokens[0]); + String submittedFunctionName = conditionTokens[1]; + String missingTermQuery = conditionTokens[2]; + String operatorValue = conditionTokens[3]; + logger.debug("submittedFunctionName: " + submittedFunctionName); + logger.debug("missingTermQuery: " + missingTermQuery); + logger.debug("operatorValue: " + operatorValue); + String submittedResourceFilter = params.get("selectResource" + ListItem.DOT + index); + // the number of grade points are tagging along for the ride. chop this off. + String assignmentPoints = submittedResourceFilter.substring(submittedResourceFilter.lastIndexOf("/") + 1); + submittedResourceFilter = submittedResourceFilter.substring(0, submittedResourceFilter.lastIndexOf("/")); + logger.debug("submittedResourceFilter: " + submittedResourceFilter); + String eventDataClass = conditionService.getClassNameForEvent(submittedFunctionName); + Object argument = null; + if ((selectedIndex == 9) || (selectedIndex == 10)) { + try { + argument = new Double(params.get("assignment_grade" + ListItem.DOT + index)); + } catch (NumberFormatException e) { + return; + } + logger.debug("argument: " + argument); + } + + if (cbSelected) { + if (item.useConditionalRelease) { + logger.debug("Previous condition exists. Removing related notification"); + removeExistingNotification(item, state); + } + + String containingCollectionId = item.containingCollectionId; + String resourceId = item.getId(); + if (! resourceId.startsWith(containingCollectionId)) { + resourceId = containingCollectionId + resourceId; + if (item.isCollection() && !resourceId.endsWith("/")) resourceId = resourceId + "/"; + } + List predicates = new ArrayList(); + Condition resourcePredicate = conditionService.makeBooleanExpression(eventDataClass, missingTermQuery, operatorValue, argument); + + predicates.add(resourcePredicate); + + Rule resourceConditionRule = conditionService.makeRule(resourceId, predicates, Rule.Conjunction.OR); + NotificationEdit notification = NotificationService.addNotification(); + notification.addFunction(submittedFunctionName); + notification.addFunction("cond+" + submittedFunctionName); + if (missingTermQuery.contains("Date")) { + notification.addFunction("datetime.update"); + } + notification.setAction(resourceConditionRule); + notification.setResourceFilter(submittedResourceFilter); + notification.getProperties().addProperty(ConditionService.PROP_SUBMITTED_FUNCTION_NAME, submittedFunctionName); + notification.getProperties().addProperty(ConditionService.PROP_SUBMITTED_RESOURCE_FILTER, submittedResourceFilter); + notification.getProperties().addProperty(ConditionService.PROP_SELECTED_CONDITION_KEY, selectedConditionValue); + notification.getProperties().addProperty(ConditionService.PROP_CONDITIONAL_RELEASE_ARGUMENT, params.get("assignment_grade" + ListItem.DOT + index)); + NotificationService.commitEdit(notification); + + item.setUseConditionalRelease(true); + item.setNotificationId(notification.getId()); + } else { + //only remove the condition if it previously existed + if (item.useConditionalRelease) { + item.setUseConditionalRelease(false); + removeExistingNotification(item, state); + } + } + + } + + + private static boolean conditionsEnabled() { + return ServerConfigurationService.getBoolean("conditions.service.enabled", Boolean.FALSE); + } + + + void loadConditionData(SessionState state) { + if (! conditionsEnabled()) { + return; + } + logger.debug("Loading condition data"); + ListItem item = (ListItem) state.getAttribute(ResourcesAction.STATE_REVISE_PROPERTIES_ITEM); + if ((item != null) && (item.useConditionalRelease)) { + try { + Notification notification = NotificationService.getNotification(item.getNotificationId()); + if (notification != null) { + item.setSubmittedFunctionName(notification.getProperties().getProperty(ConditionService.PROP_SUBMITTED_FUNCTION_NAME)); + item.setSubmittedResourceFilter(notification.getProperties().getProperty(ConditionService.PROP_SUBMITTED_RESOURCE_FILTER)); + item.setSelectedConditionKey(notification.getProperties().getProperty(ConditionService.PROP_SELECTED_CONDITION_KEY)); + item.setConditionArgument(notification.getProperties().getProperty(ConditionService.PROP_CONDITIONAL_RELEASE_ARGUMENT)); + } + } catch (NotificationNotDefinedException e) { + addAlert(state, rb.getString("notification.load.error")); + } + } + + + Map resourceSelections = conditionService.getEntitiesForServiceAndContext("gradebook", ToolManager.getCurrentPlacement().getContext()); + + //TODO look this data up + //Using LinkedHashMap to maintain order + Map conditionSelections = new LinkedHashMap(); + conditionSelections.put("1|gradebook.updateAssignment|dueDateHasPassed|no_operator","due date has passed."); + conditionSelections.put("2|gradebook.updateAssignment|dueDateHasNotPassed|no_operator","due date has not passed."); + conditionSelections.put("3|gradebook.updateAssignment|isReleasedToStudents|no_operator","is released to students."); + conditionSelections.put("4|gradebook.updateAssignment|isNotReleasedToStudents|no_operator","is not released to students."); + conditionSelections.put("5|gradebook.updateAssignment|isIncludedInCourseGrade|no_operator","is included in course grade."); + conditionSelections.put("6|gradebook.updateAssignment|isNotIncludedInCourseGrade|no_operator","is not included in course grade."); + conditionSelections.put("7|gradebook.updateItemScore|isScoreBlank|no_operator", "grade is blank."); + conditionSelections.put("8|gradebook.updateItemScore|isScoreNonBlank|no_operator", "grade is non-blank."); + conditionSelections.put("9|gradebook.updateItemScore|getScore|less_than","grade is less than:"); + conditionSelections.put("10|gradebook.updateItemScore|getScore|greater_than_equal_to","grade is greater than or equal to:"); + + //This isn't the final resting place for this data..see the buildReviseMetadataContext method in this class + state.setAttribute("resourceSelections", resourceSelections); + state.setAttribute("conditionSelections", conditionSelections); + if (item != null) { + state.setAttribute("conditionArgument", item.getConditionArgument()); + } + } + + static void removeExistingNotification(ListItem item, SessionState state) { + if (! conditionsEnabled()) { + return; + } + logger.debug("Removing condition"); + try { + NotificationEdit notificationToRemove = NotificationService.editNotification(item.getNotificationId()); + NotificationService.removeNotification(notificationToRemove); + } catch (NotificationLockedException e) { + addAlert(state, rb.getString("disable.condition.error")); + } catch (NotificationNotDefinedException e) { + addAlert(state, rb.getString("disable.condition.error")); + } + } + + + + static void buildConditionContext(Context context, SessionState state) { + if (! conditionsEnabled()) { + context.put("conditions_enabled", Boolean.FALSE); + return; + } + context.put("conditions_enabled", Boolean.TRUE); + context.put("resourceSelections", state.getAttribute("resourceSelections")); + context.put("conditionSelections", state.getAttribute("conditionSelections")); + } + + static void notifyCondition(Entity entity) { + if (! conditionsEnabled()) { + return; + } + Notification resourceNotification = null; + String notificationId = entity.getProperties().getProperty(ConditionService.PROP_CONDITIONAL_NOTIFICATION_ID); + if (notificationId != null && !"".equals(notificationId)) { + try { + resourceNotification = NotificationService.getNotification(notificationId); + } catch (NotificationNotDefinedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + if (resourceNotification != null) { + EventTrackingService.post(EventTrackingService.newEvent("cond+" + resourceNotification.getFunction(), resourceNotification.getResourceFilter(), true)); + } + + } + +} Index: content/content-tool/tool/src/java/org/sakaiproject/content/tool/ResourcesAction.java =================================================================== --- content/content-tool/tool/src/java/org/sakaiproject/content/tool/ResourcesAction.java (revision 69866) +++ content/content-tool/tool/src/java/org/sakaiproject/content/tool/ResourcesAction.java (working copy) @@ -87,8 +87,13 @@ import org.sakaiproject.entity.api.ResourceProperties; import org.sakaiproject.entity.api.ResourcePropertiesEdit; import org.sakaiproject.entity.cover.EntityManager; +import org.sakaiproject.event.api.Notification; +import org.sakaiproject.event.api.NotificationEdit; +import org.sakaiproject.event.api.NotificationLockedException; +import org.sakaiproject.event.api.NotificationNotDefinedException; import org.sakaiproject.event.api.SessionState; import org.sakaiproject.event.api.UsageSession; +import org.sakaiproject.event.cover.EventTrackingService; import org.sakaiproject.event.cover.NotificationService; import org.sakaiproject.event.cover.UsageSessionService; import org.sakaiproject.exception.IdInvalidException; @@ -454,6 +459,8 @@ private static ResourceLoader rrb = new ResourceLoader("right"); static final Log logger = LogFactory.getLog(ResourcesAction.class); + + static final ResourceConditionsHelper conditionsHelper = new ResourceConditionsHelper(); public static final String PREFIX = "resources."; public static final String SYS = "sys."; @@ -1233,6 +1240,7 @@ resourceProperties.addProperty(pname, pvalue); } ContentHostingService.commitCollection(edit); + conditionsHelper.notifyCondition(edit); new_collections.add(edit); } catch (PermissionException e) @@ -4170,6 +4178,8 @@ context.put("GROUP_ACCESS", AccessMode.GROUPED.toString()); context.put("INHERITED_ACCESS", AccessMode.INHERITED.toString()); context.put("PUBLIC_ACCESS", PUBLIC_ACCESS); + + conditionsHelper.buildConditionContext(context, state); } return template; } @@ -5138,6 +5148,7 @@ { context.put("showMountPointProperty", Boolean.TRUE.toString()); } + conditionsHelper.buildConditionContext(context, state); return TEMPLATE_REVISE_METADATA; } @@ -5640,6 +5651,14 @@ if(user_action.equals("save")) { item.captureProperties(params, ListItem.DOT + "0"); + if (item.numberFieldIsInvalid) { + addAlert(state, rb.getString("invalid.condition.argument")); + return; + } + if (item.numberFieldIsOutOfRange) { + addAlert(state, rb.getString("invalid.condition.argument.outside.range") + " " + item.getConditionAssignmentPoints() + "."); + return; + } String name = params.getString("name" + ListItem.DOT + "0"); if(name == null) { @@ -5704,7 +5723,8 @@ } resource.setResourceType(resourceType); - + item.setId(resource.getId()); + conditionsHelper.saveCondition(item, params, state, 0); item.updateContentResourceEdit(resource); extractContent(pipe, resource); @@ -6093,6 +6113,7 @@ } startHelper(data.getRequest(), iAction.getHelperId()); + conditionsHelper.loadConditionData(state); } else if(action instanceof ServiceLevelAction) { @@ -6154,6 +6175,7 @@ state.setAttribute (STATE_MODE, MODE_REVISE_METADATA); ListItem item = getListItem(state); state.setAttribute(STATE_REVISE_PROPERTIES_ITEM, item); + conditionsHelper.loadConditionData(state); // sAction.finalizeAction(reference); break; case CUSTOM_TOOL_ACTION: @@ -6867,6 +6889,14 @@ } item.captureProperties(params, ListItem.DOT + "0"); + if (item.numberFieldIsInvalid) { + addAlert(state, rb.getString("invalid.condition.argument")); + return; + } + if (item.numberFieldIsOutOfRange) { + addAlert(state, rb.getString("invalid.condition.argument.outside.range") + " " + item.getConditionAssignmentPoints() + "."); + return; + } // notification int noti = NotificationService.NOTI_NONE; @@ -6921,20 +6951,24 @@ { try { + conditionsHelper.saveCondition(item, params, state, 0); + + Entity entity = null; if(item.isCollection()) { - ContentCollectionEdit entity = ContentHostingService.editCollection(entityId); - item.updateContentCollectionEdit(entity); + entity = ContentHostingService.editCollection(entityId); + item.updateContentCollectionEdit((ContentCollectionEdit)entity); - ContentHostingService.commitCollection(entity); + ContentHostingService.commitCollection((ContentCollectionEdit)entity); } else { - ContentResourceEdit entity = ContentHostingService.editResource(entityId); - item.updateContentResourceEdit(entity); - ContentHostingService.commitResource(entity, noti); + entity = ContentHostingService.editResource(entityId); + item.updateContentResourceEdit((ContentResourceEdit)entity); + ContentHostingService.commitResource((ContentResourceEdit)entity, noti); } + conditionsHelper.notifyCondition(entity); state.setAttribute(STATE_MODE, MODE_LIST); } catch (IdUnusedException e) @@ -8460,6 +8494,10 @@ if(obj != null && obj instanceof ListItem) { displayName = ((ListItem) obj).getName(); + List alerts = ((ListItem)obj).checkRequiredProperties(); + for (String alert : alerts) { + addAlert(state, alert); + } } if(displayName == null || displayName.trim().equals("")) { Index: content/content-tool/tool/src/java/org/sakaiproject/content/tool/ResourcesHelperAction.java =================================================================== --- content/content-tool/tool/src/java/org/sakaiproject/content/tool/ResourcesHelperAction.java (revision 69866) +++ content/content-tool/tool/src/java/org/sakaiproject/content/tool/ResourcesHelperAction.java (working copy) @@ -86,6 +86,8 @@ /** the logger for this class */ private static final Log logger = LogFactory.getLog(ResourcesHelperAction.class); + private static final ResourceConditionsHelper conditionsHelper = new ResourceConditionsHelper(); + /** Resource bundle using current language locale */ private static ResourceLoader rb = new ResourceLoader("types"); @@ -384,6 +386,7 @@ ResourcesAction.copyrightChoicesIntoContext(state, context); ResourcesAction.publicDisplayChoicesIntoContext(state, context); + ResourceConditionsHelper.buildConditionContext(context, state); int requestStateId = ResourcesAction.preserveRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST}); context.put("requestStateId", requestStateId); @@ -442,6 +445,7 @@ } ResourcesAction.publicDisplayChoicesIntoContext(state, context); + ResourceConditionsHelper.buildConditionContext(context, state); int requestStateId = ResourcesAction.preserveRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST}); context.put("requestStateId", requestStateId); @@ -649,6 +653,8 @@ } context.put("defaultCopyrightStatus", defaultCopyrightStatus); + + ResourceConditionsHelper.buildConditionContext(context, state); int requestStateId = ResourcesAction.preserveRequestState(state, new String[]{ResourcesAction.PREFIX + ResourcesAction.REQUEST}); context.put("requestStateId", requestStateId); @@ -911,9 +917,19 @@ // capture properties newFolder.captureProperties(params, ListItem.DOT + i); + if (newFolder.numberFieldIsInvalid) { + addAlert(state, rb.getString("invalid.condition.argument")); + return; + } + if (newFolder.numberFieldIsOutOfRange) { + addAlert(state, rb.getString("invalid.condition.argument.outside.range") + " " + newFolder.getConditionAssignmentPoints() + "."); + return; + } fp.setRevisedListItem(newFolder); + ResourceConditionsHelper.saveCondition(newFolder, params, state, i); + actualCount++; } @@ -1159,6 +1175,14 @@ // capture properties newFile.captureProperties(params, ListItem.DOT + i); + if (newFile.numberFieldIsInvalid) { + addAlert(state, rb.getString("invalid.condition.argument")); + return; + } + if (newFile.numberFieldIsOutOfRange) { + addAlert(state, rb.getString("invalid.condition.argument.outside.range") + " " + newFile.getConditionAssignmentPoints() + "."); + return; + } // notification int noti = determineNotificationPriority(params, newFile.isDropbox, newFile.userIsMaintainer()); newFile.setNotification(noti); Index: content/content-tool/tool/src/java/org/sakaiproject/content/tool/ListItem.java =================================================================== --- content/content-tool/tool/src/java/org/sakaiproject/content/tool/ListItem.java (revision 69866) +++ content/content-tool/tool/src/java/org/sakaiproject/content/tool/ListItem.java (working copy) @@ -42,6 +42,7 @@ import org.sakaiproject.authz.cover.SecurityService; import org.sakaiproject.cheftool.Context; import org.sakaiproject.component.cover.ComponentManager; +import org.sakaiproject.conditions.api.ConditionService; import org.sakaiproject.component.cover.ServerConfigurationService; import org.sakaiproject.content.api.ContentCollection; import org.sakaiproject.content.api.ContentCollectionEdit; @@ -394,6 +395,18 @@ protected boolean useRetractDate; protected Time retractDate; + public boolean useConditionalRelease = false; + private String submittedFunctionName; + private String submittedResourceFilter; + private String selectedConditionKey; + private String conditionArgument; + private String conditionAssignmentPoints; + + private String notificationId; + private Collection accessControlList; + + protected boolean numberFieldIsInvalid; + protected boolean numberFieldIsOutOfRange; protected String description; protected String copyrightInfo = ""; @@ -402,7 +415,7 @@ protected ListItem parent; - protected String containingCollectionId; + public String containingCollectionId; protected boolean isUserSite = false; protected boolean isDropbox = false; @@ -427,6 +440,14 @@ protected Time lastChange = null; private org.sakaiproject.content.api.ContentHostingService contentService; + + public String getConditionAssignmentPoints() { + return conditionAssignmentPoints; + } + + public void setConditionAssignmentPoints(String conditionAssignmentPoints) { + this.conditionAssignmentPoints = conditionAssignmentPoints; + } /** * @param entity @@ -503,6 +524,10 @@ } } this.description = props.getProperty(ResourceProperties.PROP_DESCRIPTION); + this.useConditionalRelease = Boolean.parseBoolean(props.getProperty(ConditionService.PROP_CONDITIONAL_RELEASE)); + this.notificationId = props.getProperty(ConditionService.PROP_CONDITIONAL_NOTIFICATION_ID); + this.accessControlList = props.getPropertyList(ContentHostingService.CONDITIONAL_ACCESS_LIST); + if(this.isDropbox) { @@ -534,6 +559,15 @@ } } + this.useConditionalRelease = Boolean.parseBoolean(props.getProperty(ConditionService.PROP_CONDITIONAL_RELEASE)); + this.notificationId = props.getProperty(ConditionService.PROP_CONDITIONAL_NOTIFICATION_ID); + this.accessControlList = props.getPropertyList(ContentHostingService.CONDITIONAL_ACCESS_LIST); + //this.submittedFunctionName = props.getProperty(ContentHostingService.PROP_SUBMITTED_FUNCTION_NAME); + //this.submittedResourceFilter = props.getProperty(ContentHostingService.PROP_SUBMITTED_RESOURCE_FILTER); + //this.selectedConditionKey = props.getProperty(ContentHostingService.PROP_SELECTED_CONDITION_KEY); + //this.conditionArgument = props.getProperty(ContentHostingService.PROP_CONDITIONAL_RELEASE_ARGUMENT); + + this.permissions = new TreeSet(); this.selected = false; @@ -1424,8 +1458,79 @@ this.retractDate = null; } + String selectedConditionValue = params.get("selectCondition" + index); + if (selectedConditionValue == null) return; + String[] conditionTokens = selectedConditionValue.split("\\|"); + int selectedIndex = Integer.valueOf(conditionTokens[0]); + if ((selectedIndex == 9) || (selectedIndex == 10)) { + this.conditionArgument = params.get("assignment_grade" + index); + Double argument = null; + try { + argument = new Double(this.conditionArgument); + } catch (NumberFormatException nfe) { + this.numberFieldIsInvalid = true; + } + + String submittedResourceFilter = params.get("selectResource" + index); + // the number of grade points are tagging along for the ride. chop this off. + this.conditionAssignmentPoints = submittedResourceFilter.substring(submittedResourceFilter.lastIndexOf("/") + 1); + Double assignmentPoints = new Double(conditionAssignmentPoints); + if ((argument > assignmentPoints) || (argument < 0)) { + this.numberFieldIsOutOfRange = true; + } + } + + } + public String getConditionArgument() { + return conditionArgument; + } + + public void setConditionArgument(String conditionArgument) { + this.conditionArgument = conditionArgument; + } + + public boolean isUseConditionalRelease() { + return useConditionalRelease; + } + + public void setUseConditionalRelease(boolean useConditionalRelease) { + this.useConditionalRelease = useConditionalRelease; + } + + public String getSubmittedFunctionName() { + return submittedFunctionName; + } + + public void setSubmittedFunctionName(String submittedFunctionName) { + this.submittedFunctionName = submittedFunctionName; + } + + public String getSubmittedResourceFilter() { + return submittedResourceFilter; + } + + public void setSubmittedResourceFilter(String submittedResourceFilter) { + this.submittedResourceFilter = submittedResourceFilter; + } + + public String getSelectedConditionKey() { + return selectedConditionKey; + } + + public void setSelectedConditionKey(String selectedConditionKey) { + this.selectedConditionKey = selectedConditionKey; + } + + public String getNotificationId() { + return notificationId; + } + + public void setNotificationId(String notificationId) { + this.notificationId = notificationId; + } + protected void captureCopyright(ParameterParser params, String index) { // rights @@ -2863,6 +2968,7 @@ setDisplayNameOnEntity(props); setDescriptionOnEntity(props); //setCopyrightOnEntity(props); + setConditionalReleaseOnEntity(props); setAccessOnEntity(edit); setAvailabilityOnEntity(edit); setQuotaOnEntity(props); @@ -2897,7 +3003,20 @@ { edit.setAvailability(hidden, releaseDate, retractDate); } + + protected void setConditionalReleaseOnEntity(ResourcePropertiesEdit props) + { + props.addProperty(ConditionService.PROP_CONDITIONAL_RELEASE, Boolean.toString(this.useConditionalRelease)); + props.addProperty(ConditionService.PROP_CONDITIONAL_NOTIFICATION_ID, this.notificationId); + props.removeProperty(ContentHostingService.CONDITIONAL_ACCESS_LIST); + if (this.accessControlList != null) { + for (String id : this.accessControlList) { + props.addPropertyToList(ContentHostingService.CONDITIONAL_ACCESS_LIST, id); + } + } + } + protected void setCopyrightOnEntity(ResourcePropertiesEdit props) { if(copyrightInfo == null || copyrightInfo.trim().length() == 0) @@ -2980,6 +3099,7 @@ setCHHMountpoint(props); setDisplayNameOnEntity(props); setDescriptionOnEntity(props); + setConditionalReleaseOnEntity(props); setCopyrightOnEntity(props); setAccessOnEntity(edit); setAvailabilityOnEntity(edit); Index: content/content-tool/tool/src/webapp/vm/resources/sakai_properties.vm =================================================================== --- content/content-tool/tool/src/webapp/vm/resources/sakai_properties.vm (revision 69866) +++ content/content-tool/tool/src/webapp/vm/resources/sakai_properties.vm (working copy) @@ -359,8 +359,80 @@ #resources_timeSelectionWidget("retract" "$i" $model.retractDate) + #if($conditions_enabled) + + + #if($resourceSelections.size() == 0) + + #else + #if($item.useConditionalRelease()) + + #else + + #end + #end + + + + + + #end + + #if($conditions_enabled) + + + + + + +
+       + +        + + #if($resourceSelections.size() == 0) + $tlang.getString("no.gradebook.assignments") + #else + Gradebook + + + #if($item.getSelectedConditionKey().startsWith("9") || $item.getSelectedConditionKey().startsWith("10")) + + + #else + + #end +
+ #end + + +
Index: content/content-tool/tool/src/webapp/vm/resources/sakai_properties_scripts.vm =================================================================== --- content/content-tool/tool/src/webapp/vm/resources/sakai_properties_scripts.vm (revision 69866) +++ content/content-tool/tool/src/webapp/vm/resources/sakai_properties_scripts.vm (working copy) @@ -711,6 +711,15 @@ { newElement.style.display = "none"; } + if( root.id.match( /^grade_argument_span${DOT}\d+$/ ) ) + { + newElement.style.display = "none"; + } + if( root.id.match( /^selectCondition${DOT}\d+$/ ) ) + { + newElement.onchange = handleSelectConditionChange; + } + } return newElement; } @@ -1378,6 +1387,11 @@ if(use_end_date) { use_end_date.checked = false; + } + var use_condition = document.getElementById("cbCondition"); + if(use_condition) + { + use_condition.checked = false; } } function handleSelectAllChange(evt) @@ -1414,6 +1428,37 @@ } } + function changeCondition(selectValue,dotSuffix) + { + selectIndex = Number(selectValue.substring(0, selectValue.indexOf("|"))); + if (selectIndex < 9) { + document.getElementById("grade_argument_span" + dotSuffix).style.display = "none"; + } else if (selectIndex < 11){ + document.getElementById("grade_argument_span" + dotSuffix).style.display = "inline"; + } + } + + function handleSelectConditionChange(evt) + { + evt = (evt) ? evt : ((event) ? event : null); + if(evt) + { + var element = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null) + if(element) + { + var selectedValue = element.options[element.selectedIndex].value; + var dot = element.id.lastIndexOf("$DOT"); + if(dot >= 0) + { + var index = element.id.substr(dot + 1); + changeCondition(selectedValue, "${DOT}" + index); + } + } + } + + } + + attachEventHandlers(); #if($calendarcounter > 0) Index: content/content-tool/tool/pom.xml =================================================================== --- content/content-tool/tool/pom.xml (revision 69866) +++ content/content-tool/tool/pom.xml (working copy) @@ -41,6 +41,11 @@ commons-logging 1.0.4 + + commons-collections + commons-collections + 3.2.1 +