Skip to content

Commit f1f2179

Browse files
plukasewbjones86
authored andcommitted
SAK-39978: Develop an empty state for Gradebook to better orientate and guide user (sakaiproject#5632)
1 parent 486115c commit f1f2179

File tree

5 files changed

+275
-115
lines changed

5 files changed

+275
-115
lines changed

gradebookng/tool/src/java/org/sakaiproject/gradebookng/GradebookNgApplication.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ permissionspage.update.dupes=Note: One or more duplicate permissions were detect
497497

498498

499499
no-assignments.label = There are no Gradebook items
500-
no-students.label = There are no students with Gradebook items
500+
no-students.label = There are no students to display
501501

502502
gradebookpage.uncategorised = Uncategorized
503503

gradebookng/tool/src/java/org/sakaiproject/gradebookng/tool/pages/GradebookPage.html

+77-66
Original file line numberDiff line numberDiff line change
@@ -5,89 +5,100 @@
55

66
<wicket:extend>
77
<form wicket:id="form" id="gradebookSpreadsheet">
8-
<div wicket:id="noAssignments" class="messageInformation"><wicket:message key="no-assignments.label" /></div>
9-
<div wicket:id="noStudents" class="messageInformation"><wicket:message key="no-students.label" /></div>
108
<div id="gbConnectionTimeoutFeedback" class="messageWarning" style="display:none;">
119
<wicket:message key="feedback.connectiontimeout" />
1210
</div>
1311
<div id="gbReorderColumnsFailed" class="messageWarning" style="display:none;">
1412
<wicket:message key="feedback.reordercolumnsfailed" />
1513
</div>
1614

17-
<div class="row">
18-
<div class="col-sm-12">
19-
<div class="col-sm-6">
20-
<button wicket:id="addGradeItem" class="button_color gb-add-gradebook-item-button">
15+
<div wicket:id="addOrEditGradeItemWindow" />
16+
<div wicket:id="studentGradeSummaryWindow" />
17+
<div wicket:id="updateUngradedItemsWindow" />
18+
<div wicket:id="gradeLogWindow" />
19+
<div wicket:id="gradeCommentWindow" />
20+
<div wicket:id="deleteItemWindow" />
21+
<div wicket:id="gradeStatisticsWindow" />
22+
<div wicket:id="updateCourseGradeDisplayWindow" />
23+
<div wicket:id="sortGradeItemsWindow" />
24+
<div wicket:id="courseGradeStatisticsWindow" />
25+
26+
<div wicket:id="gradeTableArea">
27+
<div wicket:id="noAssignments" class="gb-noGbItems">
28+
<i class="fa fa-fw fa-table" aria-hidden="true"></i>
29+
<wicket:message key="no-assignments.label" />
30+
<div class="act">
31+
<button wicket:id="addGradeItem2" class="active gb-add-gradebook-item-button">
2132
<wicket:message key="button.addgradeitem" />
2233
</button>
34+
</div>
35+
</div>
2336

24-
<div wicket:id="liveGradingFeedback" class="gb-live-feedback"></div>
37+
<div class="row gradesToolbar1">
38+
<div class="col-sm-12">
39+
<div class="col-sm-6">
40+
<button wicket:id="addGradeItem" class="button_color gb-add-gradebook-item-button">
41+
<wicket:message key="button.addgradeitem" />
42+
</button>
43+
<div wicket:id="liveGradingFeedback" class="gb-live-feedback"></div>
44+
</div>
45+
<div class="col-sm-6 text-right">
46+
<wicket:enclosure>
47+
<label for="filterByGroup" class="sr-only"><wicket:message key="filter.groups" /></label>
48+
<select id="filterByGroup" wicket:id="groupFilter">
49+
<option value="1">Section 1</option>
50+
<option value="2">Section 2</option>
51+
</select>
52+
</wicket:enclosure>
53+
<a wicket:id="captionToggle" href="javascript:void(0);" id="captionToggle" aria-popup="true" aria-controls="gradeTableCaption">
54+
<span class="sr-only">
55+
<wicket:message key="label.toolbar.togglehelp"/>
56+
</span>
57+
</a>
58+
</div>
2559
</div>
26-
<div class="col-sm-6 text-right">
60+
</div>
61+
62+
<div wicket:id="toolbar" id="gradebookGradesToolbar" class="btn-toolbar gradesToolbar2">
63+
<ul class="gb-toolbar-left">
2764
<wicket:enclosure>
28-
<label for="filterByGroup" class="sr-only"><wicket:message key="filter.groups" /></label>
29-
<select id="filterByGroup" wicket:id="groupFilter">
30-
<option value="1">Section 1</option>
31-
<option value="2">Section 2</option>
32-
</select>
65+
<li>
66+
<div class="gb-student-filter">
67+
<label for="studentFilterInput" class="sr-only"><wicket:message key="filter.students"/></label>
68+
<input type="text" id="studentFilterInput" class="form-control" aria-controls="gradeTable" wicket:id="studentFilter" wicket:message="placeholder:filter.students" accesskey="f">
69+
<a class="gb-student-filter-clear-button" wicket:message="title:filter.studentsclear" href="javascript:void(0)">
70+
<i class="fa fa-times-circle" aria-hidden="true"></i>
71+
</a>
72+
</div>
73+
</li>
3374
</wicket:enclosure>
34-
<a wicket:id="captionToggle" href="javascript:void(0);" id="captionToggle" aria-popup="true" aria-controls="gradeTableCaption">
35-
<span class="sr-only">
36-
<wicket:message key="label.toolbar.togglehelp"/>
37-
</span>
38-
</a>
39-
</div>
75+
<wicket:enclosure>
76+
<li><span wicket:id="groupFilterOnlyOne" class="gb-group-title" role="status">Section 001</span></li>
77+
</wicket:enclosure>
78+
<li class="gb-student-summary"><!-- Populated by JavaScript --></li>
79+
</ul>
80+
<ul wicket:id="gbToolbarColumnTools" class="gb-toolbar-right">
81+
<li class="gb-grade-item-summary"><!-- Populated by JavaScript --></li>
82+
<li>
83+
<button wicket:id="toggleGradeItemsToolbarItem" id="toggleGradeItemsToolbarItem" class="button" aria-popup="true" aria-controls="gradeItemsTogglePanel"><wicket:message key="label.toolbar.toggleitems"/></button>
84+
</li>
85+
<li>
86+
<button wicket:id="sortGradeItemsToolbarItem" id="sortGradeItemsToolbarItem" class="button" aria-popup="true"><wicket:message key="label.toolbar.sortgradeitems"/></button>
87+
</li>
88+
<wicket:enclosure>
89+
<li>
90+
<button wicket:id="toggleCategoriesToolbarItem" id="toggleCategoriesToolbarItem" class="button" aria-controls="gradeTable"><wicket:message key="label.toolbar.togglecategories"/></button>
91+
</li>
92+
</wicket:enclosure>
93+
</ul>
4094
</div>
41-
</div>
42-
43-
<div wicket:id="addOrEditGradeItemWindow" />
44-
<div wicket:id="studentGradeSummaryWindow" />
45-
<div wicket:id="updateUngradedItemsWindow" />
46-
<div wicket:id="gradeLogWindow" />
47-
<div wicket:id="gradeCommentWindow" />
48-
<div wicket:id="deleteItemWindow" />
49-
<div wicket:id="gradeStatisticsWindow" />
50-
<div wicket:id="updateCourseGradeDisplayWindow" />
51-
<div wicket:id="sortGradeItemsWindow" />
52-
<div wicket:id="courseGradeStatisticsWindow" />
5395

54-
<div wicket:id="toolbar" id="gradebookGradesToolbar" class="btn-toolbar">
55-
<ul class="gb-toolbar-left">
56-
<wicket:enclosure>
57-
<li>
58-
<div class="gb-student-filter">
59-
<label for="studentFilterInput" class="sr-only"><wicket:message key="filter.students"/></label>
60-
<input type="text" id="studentFilterInput" class="form-control" aria-controls="gradeTable" wicket:id="studentFilter" wicket:message="placeholder:filter.students" accesskey="f">
61-
<a class="gb-student-filter-clear-button" wicket:message="title:filter.studentsclear" href="javascript:void(0)">
62-
<i class="fa fa-times-circle" aria-hidden="true"></i>
63-
</a>
64-
</div>
65-
</li>
66-
</wicket:enclosure>
67-
<wicket:enclosure>
68-
<li><span wicket:id="groupFilterOnlyOne" class="gb-group-title" role="status">Section 001</span></li>
69-
</wicket:enclosure>
70-
<li class="gb-student-summary"><!-- Populated by JavaScript --></li>
71-
</ul>
72-
<ul class="gb-toolbar-right">
73-
<li class="gb-grade-item-summary"><!-- Populated by JavaScript --></li>
74-
<li>
75-
<button wicket:id="toggleGradeItemsToolbarItem" id="toggleGradeItemsToolbarItem" class="button" aria-popup="true" aria-controls="gradeItemsTogglePanel"><wicket:message key="label.toolbar.toggleitems"/></button>
76-
</li>
77-
<li>
78-
<button wicket:id="sortGradeItemsToolbarItem" id="sortGradeItemsToolbarItem" class="button" aria-popup="true"><wicket:message key="label.toolbar.sortgradeitems"/></button>
79-
</li>
80-
<wicket:enclosure>
81-
<li>
82-
<button wicket:id="toggleCategoriesToolbarItem" id="toggleCategoriesToolbarItem" class="button" aria-controls="gradeTable"><wicket:message key="label.toolbar.togglecategories"/></button>
83-
</li>
84-
</wicket:enclosure>
85-
</ul>
96+
<div class="gradeTableOuterWrapper">
97+
<div wicket:id="gradeTable" />
98+
<div wicket:id="noStudents" class="gb-noStudents"><wicket:message key="no-students.label" /></div>
99+
</div>
86100
</div>
87101

88-
<!-- Here we go... -->
89-
<div wicket:id="gradeTable" />
90-
91102
</form>
92103

93104
<div wicket:id="gradeItemsTogglePanel" id="gradeItemsTogglePanel" style="display: none;"/>

gradebookng/tool/src/java/org/sakaiproject/gradebookng/tool/pages/GradebookPage.java

+68-46
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public class GradebookPage extends BasePage {
106106
GbModalWindow courseGradeStatisticsWindow;
107107

108108
Label liveGradingFeedback;
109-
boolean hasAssignmentsAndGrades;
109+
boolean hasGradebookItems, hasStudents;
110110
private static final AttributeModifier DISPLAY_NONE = new AttributeModifier("style", "display: none");
111111

112112
Form<Void> form;
@@ -115,6 +115,8 @@ public class GradebookPage extends BasePage {
115115
boolean showGroupFilter = true;
116116
private GbGradeTable gradeTable;
117117

118+
private final WebMarkupContainer tableArea;
119+
118120
@SuppressWarnings({ "rawtypes", "unchecked", "serial" })
119121
public GradebookPage() {
120122
disableLink(this.gradebookPageLink);
@@ -195,25 +197,6 @@ public GradebookPage() {
195197
this.courseGradeStatisticsWindow.setPositionAtTop(true);
196198
this.form.add(this.courseGradeStatisticsWindow);
197199

198-
final GbAjaxButton addGradeItem = new GbAjaxButton("addGradeItem") {
199-
@Override
200-
public void onSubmit(final AjaxRequestTarget target, final Form form) {
201-
final GbModalWindow window = getAddOrEditGradeItemWindow();
202-
window.setTitle(getString("heading.addgradeitem"));
203-
window.setComponentToReturnFocusTo(this);
204-
window.setContent(new AddOrEditGradeItemPanel(window.getContentId(), window, null));
205-
window.show(target);
206-
}
207-
208-
@Override
209-
public boolean isVisible() {
210-
return (businessService.isUserAbleToEditAssessments());
211-
}
212-
};
213-
addGradeItem.setDefaultFormProcessing(false);
214-
addGradeItem.setOutputMarkupId(true);
215-
this.form.add(addGradeItem);
216-
217200
// first get any settings data from the session
218201
final GradebookUiSettings settings = getUiSettings();
219202

@@ -227,28 +210,52 @@ public boolean isVisible() {
227210
final List<Assignment> assignments = this.businessService.getGradebookAssignments(sortBy);
228211
final List<String> students = this.businessService.getGradeableUsers();
229212

230-
this.hasAssignmentsAndGrades = !assignments.isEmpty() && !students.isEmpty();
231-
213+
hasGradebookItems = !assignments.isEmpty();
214+
hasStudents = !students.isEmpty();
232215
// categories enabled?
233216
final boolean categoriesEnabled = this.businessService.categoriesAreEnabled();
234217

235218
// grading type?
236219
final GradingType gradingType = GradingType.valueOf(gradebook.getGrade_type());
237220

221+
tableArea = new WebMarkupContainer("gradeTableArea");
222+
if (!hasGradebookItems) {
223+
tableArea.add(AttributeAppender.append("class", "gradeTableArea"));
224+
}
225+
form.add(tableArea);
226+
227+
final GbAddButton addGradeItem = new GbAddButton("addGradeItem");
228+
addGradeItem.setDefaultFormProcessing(false);
229+
addGradeItem.setOutputMarkupId(true);
230+
tableArea.add(addGradeItem);
231+
238232
final WebMarkupContainer noAssignments = new WebMarkupContainer("noAssignments");
239233
noAssignments.setVisible(assignments.isEmpty());
240-
this.form.add(noAssignments);
234+
tableArea.add(noAssignments);
235+
final GbAddButton addGradeItem2 = new GbAddButton("addGradeItem2") {
236+
@Override
237+
public boolean isVisible() {
238+
return GradebookPage.this.role == GbRole.INSTRUCTOR;
239+
}
240+
};
241+
addGradeItem2.setDefaultFormProcessing(false);
242+
addGradeItem2.setOutputMarkupId(true);
243+
noAssignments.add(addGradeItem2);
241244

242245
final WebMarkupContainer noStudents = new WebMarkupContainer("noStudents");
243246
noStudents.setVisible(students.isEmpty());
244-
this.form.add(noStudents);
247+
tableArea.add(noStudents);
245248

246249
// Populate the toolbar
247250
final WebMarkupContainer toolbar = new WebMarkupContainer("toolbar");
248-
this.form.add(toolbar);
251+
tableArea.add(toolbar);
252+
253+
final WebMarkupContainer toolbarColumnTools = new WebMarkupContainer("gbToolbarColumnTools");
254+
toolbarColumnTools.setVisible(hasGradebookItems);
255+
toolbar.add(toolbarColumnTools);
249256

250257
final WebMarkupContainer toggleGradeItemsToolbarItem = new WebMarkupContainer("toggleGradeItemsToolbarItem");
251-
toolbar.add(toggleGradeItemsToolbarItem);
258+
toolbarColumnTools.add(toggleGradeItemsToolbarItem);
252259

253260
this.gradeTable = new GbGradeTable("gradeTable",
254261
new LoadableDetachableModel() {
@@ -276,7 +283,7 @@ public GbGradeTableData load() {
276283
this.gradeTable.addEventListener("viewCourseGradeStatistics", new ViewCourseGradeStatisticsAction());
277284

278285

279-
this.form.add(this.gradeTable);
286+
tableArea.add(this.gradeTable);
280287

281288
final Button toggleCategoriesToolbarItem = new Button("toggleCategoriesToolbarItem") {
282289
@Override
@@ -302,7 +309,7 @@ public boolean isVisible() {
302309
return categoriesEnabled;
303310
}
304311
};
305-
toolbar.add(toggleCategoriesToolbarItem);
312+
toolbarColumnTools.add(toggleCategoriesToolbarItem);
306313

307314
final GbAjaxLink sortGradeItemsToolbarItem = new GbAjaxLink("sortGradeItemsToolbarItem") {
308315
@Override
@@ -324,7 +331,7 @@ public boolean isVisible() {
324331
return (businessService.isUserAbleToEditAssessments());
325332
}
326333
};
327-
toolbar.add(sortGradeItemsToolbarItem);
334+
toolbarColumnTools.add(sortGradeItemsToolbarItem);
328335

329336
// section and group dropdown
330337
final List<GbGroup> groups = this.businessService.getSiteSectionsAndGroups();
@@ -405,15 +412,13 @@ protected void onUpdate(final AjaxRequestTarget target) {
405412
groupFilter.setNullValid(false);
406413

407414
// if only one item, hide the dropdown
408-
if (groups.size() == 1 || !this.hasAssignmentsAndGrades) {
409-
groupFilter.setVisible(false);
410-
}
415+
groupFilter.setVisible(groups.size() > 1 && hasStudents);
411416

412417
final WebMarkupContainer studentFilter = new WebMarkupContainer("studentFilter");
413-
studentFilter.setVisible(this.hasAssignmentsAndGrades);
418+
studentFilter.setVisible(hasStudents);
414419
toolbar.add(studentFilter);
415420

416-
this.form.add(groupFilter);
421+
tableArea.add(groupFilter);
417422

418423
final Map<String, Object> togglePanelModel = new HashMap<>();
419424
togglePanelModel.put("assignments", this.businessService.getGradebookAssignments(sortBy));
@@ -424,17 +429,9 @@ protected void onUpdate(final AjaxRequestTarget target) {
424429
new ToggleGradeItemsToolbarPanel("gradeItemsTogglePanel", Model.ofMap(togglePanelModel));
425430
add(gradeItemsTogglePanel);
426431

427-
this.form.add(new WebMarkupContainer("captionToggle").setVisible(this.hasAssignmentsAndGrades));
428-
429-
//
430-
// hide/show components
431-
//
432+
tableArea.add(new WebMarkupContainer("captionToggle").setVisible(hasStudents));
432433

433-
// Only show the toolbar if there are students and grade items
434-
toolbar.setVisible(!assignments.isEmpty());
435-
436-
// Show the table if there are grade items
437-
this.gradeTable.setVisible(!assignments.isEmpty());
434+
toolbar.setVisible(hasStudents || hasGradebookItems);
438435

439436
stopwatch.time("Gradebook page done", stopwatch.getTime());
440437
}
@@ -560,15 +557,15 @@ public void onBeforeRender() {
560557
// add simple feedback nofication to sit above the table
561558
// which is reset every time the page renders
562559
this.liveGradingFeedback = new Label("liveGradingFeedback", getString("feedback.saved"));
563-
this.liveGradingFeedback.setVisible(this.hasAssignmentsAndGrades);
560+
this.liveGradingFeedback.setVisible(hasGradebookItems && hasStudents);
564561
this.liveGradingFeedback.setOutputMarkupId(true);
565562
this.liveGradingFeedback.add(DISPLAY_NONE);
566563

567564
// add the 'saving...' message to the DOM as the JavaScript will
568565
// need to be the one that displays this message (Wicket will handle
569566
// the 'saved' and 'error' messages when a grade is changed
570567
this.liveGradingFeedback.add(new AttributeModifier("data-saving-message", getString("feedback.saving")));
571-
this.form.addOrReplace(this.liveGradingFeedback);
568+
tableArea.addOrReplace(this.liveGradingFeedback);
572569
}
573570

574571
public Component updateLiveGradingMessage(final String message) {
@@ -578,4 +575,29 @@ public Component updateLiveGradingMessage(final String message) {
578575
}
579576
return this.liveGradingFeedback;
580577
}
578+
579+
private class GbAddButton extends GbAjaxButton {
580+
581+
public GbAddButton(String id) {
582+
super(id);
583+
}
584+
585+
public GbAddButton(String id, Form<?> form) {
586+
super(id, form);
587+
}
588+
589+
@Override
590+
public void onSubmit(final AjaxRequestTarget target, final Form form) {
591+
final GbModalWindow window = getAddOrEditGradeItemWindow();
592+
window.setTitle(getString("heading.addgradeitem"));
593+
window.setComponentToReturnFocusTo(this);
594+
window.setContent(new AddOrEditGradeItemPanel(window.getContentId(), window, null));
595+
window.show(target);
596+
}
597+
598+
@Override
599+
public boolean isVisible() {
600+
return GradebookPage.this.role == GbRole.INSTRUCTOR && hasGradebookItems;
601+
}
602+
}
581603
}

0 commit comments

Comments
 (0)