Skip to content

Commit

Permalink
SAK-42046 Gradebook add course grade breakdown to the dropdown for co…
Browse files Browse the repository at this point in the history
…urse grade column (sakaiproject#10822)

Co-authored-by: jkozar2 <moronzac@moronzac-hpzbook15g2>
  • Loading branch information
jkozar2 and jkozar2 authored Nov 13, 2022
1 parent 90629bc commit fbd9722
Show file tree
Hide file tree
Showing 9 changed files with 526 additions and 0 deletions.
6 changes: 6 additions & 0 deletions gradebookng/bundle/src/main/bundle/gradebookng.properties
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,11 @@ assignment.option.preview = Rubric Preview/Statistics
assignment.option.setungraded = Set Score for Empty Cells
assignment.menulabel = Open menu for {0} column

breakdown.title=Course Grade Breakdown
breakdown.item=Gradebook Item
breakdown.points=Points
breakdown.students=Number Of Graded Students
breakdown.total=Total Points

message.edititem.success=Gradebook item ''{0}'' has been updated.
message.edititem.error=An error occurred updating the Gradebook item.
Expand Down Expand Up @@ -626,6 +631,7 @@ coursegrade.option.override = Course Grade Override
coursegrade.option.overridelog = Course Grade Override Log
coursegrade.option.setungraded = Set Zero Score For Empty Cells
coursegrade.option.viewcoursegradestatistics = View Course Grade Statistics
coursegrade.option.coursegradebreakdown = Course Grade Breakdown
coursegrade.header.menulabel = Open menu for Course Grade column
coursegrade.cell.menulabel = Open menu for Course Grade cell

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -510,6 +511,24 @@ public List<Assignment> getGradebookAssignments(final String siteId, final SortT
return assignments;
}

public List<Assignment> getGradebookAssignmentsForCategory(final Long categoryId, final SortType sortBy) {
return getGradebookAssignmentsForCategory(this.getCurrentSiteId(), categoryId, sortBy);
}

public List<Assignment> getGradebookAssignmentsForCategory(final String siteId, final Long categoryId, final SortType sortBy) {
final List<Assignment> returnList = new ArrayList<>();
final Gradebook gradebook = getGradebook(siteId);
if (gradebook != null) { // applies permissions (both student and TA) and default sort is SORT_BY_SORTING
final List<Assignment> assignments = this.gradingService.getViewableAssignmentsForCurrentUser(gradebook.getUid(), sortBy);
for (Assignment assignment : assignments) {
if (Objects.equals(assignment.getCategoryId(), categoryId)) {
returnList.add(assignment);
}
}
}
return returnList;
}

/**
* Get a list of categories in the gradebook in the current site
*
Expand Down Expand Up @@ -3111,6 +3130,51 @@ private String getAttendanceIconClass() {
return ICON_SAKAI + "sakai-attendance";
}

/**
* Gets a list of assignment averages for a category.
* @param category category
* @param group group of students
* @return allAssignmentGrades list of assignment averages for a specific group
*/
public List<Double> getCategoryAssignmentTotals(CategoryDefinition category, GbGroup group){
final List<Double> allAssignmentGrades = new ArrayList<>();
final List<String> groupUsers = getGradeableUsers(group);
final List<String> studentUUIDs = new ArrayList<>();
studentUUIDs.addAll(groupUsers);
final List<Assignment> assignments = category.getAssignmentList();
final List<GbStudentGradeInfo> grades = buildGradeMatrix(assignments, studentUUIDs);
for (final Assignment assignment : assignments) {
if (assignment != null) {
final List<Double> allGrades = new ArrayList<>();
for (int j = 0; j < grades.size(); j++) {
final GbStudentGradeInfo studentGradeInfo = grades.get(j);
final Map<Long, GbGradeInfo> studentGrades = studentGradeInfo.getGrades();
final GbGradeInfo grade = studentGrades.get(assignment.getId());
if (grade != null && grade.getGrade() != null) {
allGrades.add(Double.valueOf(grade.getGrade()));
}
}
if (grades.size() > 0) {
if (!assignment.getExtraCredit()) {
if (allGrades.size() > 0) {
allAssignmentGrades.add((calculateAverage(allGrades) / assignment.getPoints()) * 100);
}
}
}
}
}
return allAssignmentGrades;
}

/**
* Calculates the average grade for an assignment
* @param allGrades list of grades
* @return the average of the grades
*/
public double calculateAverage(final List<Double> allGrades) {
return allGrades.stream().reduce(0D, (sub, el) -> sub + el.doubleValue()) / allGrades.size();
}

// Return a CandidateDetailProvider or null if it's not enabled
private CandidateDetailProvider getCandidateDetailProvider() {
return (CandidateDetailProvider)ComponentManager.get("org.sakaiproject.user.api.CandidateDetailProvider");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.sakaiproject.gradebookng.tool.actions;

import java.io.Serializable;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.model.Model;
import org.sakaiproject.gradebookng.tool.actions.InjectableAction;
import org.sakaiproject.gradebookng.tool.model.GbModalWindow;
import org.sakaiproject.gradebookng.tool.pages.GradebookPage;
import org.sakaiproject.gradebookng.tool.panels.CourseGradeBreakdownPanel;
import org.sakaiproject.gradebookng.tool.panels.CourseGradeStatisticsPanel;
import com.fasterxml.jackson.databind.JsonNode;

public class CourseGradeBreakdownAction extends InjectableAction implements Serializable {

private static final long serialVersionUID = 1L;

public CourseGradeBreakdownAction() {
}

@Override
public ActionResponse handleEvent(final JsonNode params, final AjaxRequestTarget target) {

final String siteId = params.get("siteId").asText();

final GradebookPage gradebookPage = (GradebookPage) target.getPage();
final GbModalWindow window = gradebookPage.getGradeLogWindow();
window.setTitle("Course Grade Breakdown");
window.setContent(new CourseGradeBreakdownPanel(window.getContentId(), window));
window.show(target);

return new EmptyOkResponse();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
</li>
{/if}
<li><a href="javascript:void(0);" class="gb-view-course-grade-statistics dropdown-item"><wicket:message key="coursegrade.option.viewcoursegradestatistics" /></a></li>
<li><a href="javascript:void(0);" class="gb-course-grade-breakdown dropdown-item" ><wicket:message key="coursegrade.option.coursegradebreakdown" /></a></li>
</ul>
</div>
{/if}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.sakaiproject.gradebookng.tool.model;

import java.io.Serializable;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.sakaiproject.grading.api.Assignment;
import org.sakaiproject.grading.api.CategoryDefinition;

@Data
@AllArgsConstructor
public class GbBreakdownItem implements Serializable {

private static final long serialVersionUID = 1L;

@Getter
@Setter
private Long itemId;

@Getter
@Setter
private CategoryDefinition categoryDefinition;

@Getter
@Setter
private Assignment gradebookItem;

@Getter
@Setter
private Double categoryPointsOrWeight;

@Getter
@Setter
private Integer numGraded;
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import org.sakaiproject.gradebookng.tool.actions.ViewAssignmentStatisticsAction;
import org.sakaiproject.gradebookng.tool.actions.ViewCourseGradeLogAction;
import org.sakaiproject.gradebookng.tool.actions.ViewCourseGradeStatisticsAction;
import org.sakaiproject.gradebookng.tool.actions.CourseGradeBreakdownAction;
import org.sakaiproject.gradebookng.tool.actions.ViewGradeLogAction;
import org.sakaiproject.gradebookng.tool.actions.ViewGradeSummaryAction;
import org.sakaiproject.gradebookng.tool.actions.ViewRubricGradeAction;
Expand Down Expand Up @@ -315,6 +316,7 @@ public GbGradeTableData load() {
this.gradeTable.addEventListener("moveAssignmentLeft", new MoveAssignmentLeftAction());
this.gradeTable.addEventListener("moveAssignmentRight", new MoveAssignmentRightAction());
this.gradeTable.addEventListener("viewCourseGradeStatistics", new ViewCourseGradeStatisticsAction());
this.gradeTable.addEventListener("viewCourseGradeBreakdown", new CourseGradeBreakdownAction());
this.gradeTable.addEventListener("excuseGrade", new ExcuseGradeAction());

this.tableArea.add(this.gradeTable);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">

<body>
<wicket:panel>

<div id="itemsPage">
<div class="row">
<div class="skip">
<span wicket:id="items-feedback" />
</div>
</div>
<div wicket:id="item-list-container">
<table class="itemsTable table table-responsive table-bordered table-hover table-condensed">
<thead>
<tr>
<th><span><wicket:message key="breakdown.item" /></span></th>
<th class="text-center"><span><wicket:message key="breakdown.points" /></span></th>
<th class="text-center"><span><wicket:message key="breakdown.students" /></span></th>
</tr>
</thead>
<tbody>
<tr wicket:id="items">
<td class="nameColumn">
<div class="gb-title">
<span wicket:id="externalAppFlag"></span>
<span wicket:id="name-label" />
<span wicket:id="extraCreditFlag" class="gb-flag-extra-credit pull-right"></span>
<span wicket:id="notReleasedFlag" class="gb-flag-not-released pull-right"></span>
<span wicket:id="notCountedFlag" class="gb-flag-not-counted pull-right"></span>
<span wicket:id="extraCreditCategoryFlag" class="gb-category-extra-credit pull-right"></span>
<span wicket:id="dropLowestCategoryFlag" class="gb-category-drop-lowest pull-right"></span>
<span wicket:id="dropHighestCategoryFlag" class="gb-category-drop-highest pull-right"></span>
<span wicket:id="keepHighestCategoryFlag" class="gb-category-keep-highest pull-right"></span>
</div>
</td>
<td class="text-center totalColumn">
<span wicket:id="out-of-label" />
</td>
<td wicket:id="number-graded" class="text-center">
<span wicket:id="number-graded-label" />
</td>
</tr>

<!-- Total Points Row -->
<tr wicket:id="total-points-container">
<td class="text-right totalPoints">
<strong><wicket:message key="breakdown.total" /></strong>
</td>
<td class="text-center totalPoints">
<strong><span wicket:id="total-points" /></strong>
</td>
</tr>
</tbody>
</table>
</div>
<div class="row">
<span class="col-sm-6">
<input type="button" class="button_color" wicket:id="done" wicket:message="value:button.done" />
</span>
</div>
</div>
</wicket:panel>
</body>
</html>
Loading

0 comments on commit fbd9722

Please sign in to comment.