Skip to content

Commit b923fbc

Browse files
authored
Merge pull request #1288 from isaacphysics/feature/required-due-dates
Require due date when setting assignments and tests
2 parents c98685f + 8a593d2 commit b923fbc

File tree

4 files changed

+16
-15
lines changed

4 files changed

+16
-15
lines changed

src/app/components/elements/modals/QuizSettingModal.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,14 @@ export function QuizSettingModal({quiz, dueDate: initialDueDate, scheduledStartD
158158
</UncontrolledTooltip>
159159
{scheduledStartDateInvalid && <small className={"pt-2 text-danger"}>Start date must be today or in the future.</small>}
160160
</Label>
161-
<Label className="w-100 mb-4">Set an optional due date:<br/>
161+
<Label className="w-100 mb-4">Set a due date:<br/>
162162
<DateInput invalid={dueDateInvalid || undefined} value={dueDate ?? undefined} yearRange={yearRange}
163163
onChange={(e) => setDueDate(e.target.valueAsDate)}/>
164164
{dueDateInvalid && <small className={"pt-2 text-danger"}>{dueDate.valueOf() > TODAY().valueOf() ? "Due date must be on or after the start date." : `Due date must be after today.`}</small>}
165165
</Label>
166166

167167
<Alert color={siteSpecific("warning", "info")} className="py-1 px-2 mb-4">
168-
From {siteSpecific("Jan", "January")} 2025, due dates will be required for set tests.
168+
Since {siteSpecific("Jan", "January")} 2025, due dates are required for set tests.
169169
</Alert>
170170

171171
<div className="w-100">
@@ -179,7 +179,7 @@ export function QuizSettingModal({quiz, dueDate: initialDueDate, scheduledStartD
179179
</Button>
180180
<Button
181181
className={"float-end mb-4 w-100 w-sm-auto"}
182-
disabled={groupInvalid || !feedbackMode || isAssigning || dueDateInvalid || scheduledStartDateInvalid}
182+
disabled={groupInvalid || !feedbackMode || isAssigning || !dueDate || dueDateInvalid || scheduledStartDateInvalid }
183183
onMouseEnter={() => setValidated(new Set(['group', 'feedbackMode']))}
184184
onClick={assign}
185185
>

src/app/components/pages/AssignmentSchedule.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ const AssignmentModal = ({user, showSetAssignmentUI, toggleSetAssignmentUI, assi
444444

445445
const yearRange = range(currentYear, currentYear + 5);
446446

447-
const dueDateInvalid = dueDate && scheduledStartDate ? scheduledStartDate.valueOf() > dueDate.valueOf() : false;
447+
const dueDateInvalid = isDefined(dueDate) && ((scheduledStartDate ? (nthHourOf(0, scheduledStartDate).valueOf() > dueDate.valueOf()) : false) || TODAY().valueOf() > dueDate.valueOf());
448448

449449
useEffect(() => {
450450
if (showSetAssignmentUI) setShowGameboardPreview(false);
@@ -502,14 +502,14 @@ const AssignmentModal = ({user, showSetAssignmentUI, toggleSetAssignmentUI, assi
502502
onChange={(e: ChangeEvent<HTMLInputElement>) => setScheduledStartDate(e.target.valueAsDate as Date)}
503503
/>
504504
</Label>
505-
<Label className="w-100 pb-2">Due date reminder <span className="text-muted"> (optional)</span>
505+
<Label className="w-100 pb-2">Due date reminder
506506
<DateInput value={dueDate} placeholder="Select your due date..." yearRange={yearRange}
507507
onChange={(e: ChangeEvent<HTMLInputElement>) => setDueDate(e.target.valueAsDate as Date)}
508508
/>
509509
{dueDateInvalid && <small className={"pt-2 text-danger"}>Due date must be on or after start date.</small>}
510510
</Label>
511511
<Alert color={siteSpecific("warning", "info")} className="py-1">
512-
From January 2025, due dates will be required for assignments.
512+
Since January 2025, due dates are required for assignments.
513513
</Alert>
514514
{isStaff(user) && <Label className="w-100 pb-2">Notes (optional):
515515
<Input type="textarea"
@@ -529,7 +529,7 @@ const AssignmentModal = ({user, showSetAssignmentUI, toggleSetAssignmentUI, assi
529529
className="mb-2 mb-sm-0 w-100"
530530
block color={siteSpecific("secondary", "primary")}
531531
onClick={assign}
532-
disabled={selectedGroups.length === 0 || (isDefined(assignmentNotes) && assignmentNotes.length > 500) || !isDefined(selectedGameboard) || alreadyAssignedGroupNames.length === selectedGroups.length}
532+
disabled={selectedGroups.length === 0 || (isDefined(assignmentNotes) && assignmentNotes.length > 500) || !isDefined(selectedGameboard) || alreadyAssignedGroupNames.length === selectedGroups.length || !dueDate || dueDateInvalid}
533533
>
534534
Assign to group{selectedGroups.length > 1 ? "s" : ""}
535535
</Button>

src/app/components/pages/SetAssignments.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ const AssignGroup = ({groups, board}: AssignGroupProps) => {
9696
}
9797

9898
const yearRange = range(currentYear, currentYear + 5);
99-
const dueDateInvalid = dueDate && scheduledStartDate ? (nthHourOf(0, scheduledStartDate).valueOf() > dueDate.valueOf() || TODAY().valueOf() > dueDate.valueOf()) : false;
99+
const dueDateInvalid = isDefined(dueDate) && ((scheduledStartDate ? (nthHourOf(0, scheduledStartDate).valueOf() > dueDate.valueOf()) : false) || TODAY().valueOf() > dueDate.valueOf());
100100
const startDateInvalid = scheduledStartDate ? TODAY().valueOf() > scheduledStartDate.valueOf() : false;
101101

102102
function setScheduledStartDateAtSevenAM(e: ChangeEvent<HTMLInputElement>) {
@@ -124,14 +124,14 @@ const AssignGroup = ({groups, board}: AssignGroupProps) => {
124124
onChange={setScheduledStartDateAtSevenAM} />
125125
{startDateInvalid && <small className={"pt-2 text-danger"}>Start date must be in the future.</small>}
126126
</Label>
127-
<Label className="w-100 pb-2">Due date reminder <span className="text-muted"> (optional)</span>
127+
<Label className="w-100 pb-2">Due date reminder
128128
<DateInput value={dueDate} placeholder="Select your due date..." yearRange={yearRange}
129129
onChange={(e: ChangeEvent<HTMLInputElement>) => setDueDate(e.target.valueAsDate as Date)} /> {/* DANGER here with force-casting Date|null to Date */}
130130
{dueDateInvalid && <small className={"pt-2 text-danger"}>Due date must be on or after start date and in the future.</small>}
131131
{dueDateInvalid && startDateInvalid && <br/>}
132132
</Label>
133133
<Alert color={siteSpecific("warning", "info")} className="py-1 px-2">
134-
From {siteSpecific("Jan", "January")} 2025, due dates will be required for assignments.
134+
Since {siteSpecific("Jan", "January")} 2025, due dates are required for assignments.
135135
</Alert>
136136
{isEventLeaderOrStaff(user) && <Label className="w-100 pb-2">Notes (optional):
137137
<Input type="textarea"
@@ -150,7 +150,7 @@ const AssignGroup = ({groups, board}: AssignGroupProps) => {
150150
block color={siteSpecific("secondary", "primary")}
151151
onClick={assign}
152152
role={"button"}
153-
disabled={selectedGroups.length === 0 || (isDefined(assignmentNotes) && assignmentNotes.length > 500) || dueDateInvalid || startDateInvalid}
153+
disabled={selectedGroups.length === 0 || (isDefined(assignmentNotes) && assignmentNotes.length > 500) || !dueDate || dueDateInvalid || startDateInvalid}
154154
>Assign to group{selectedGroups.length > 1 ? "s" : ""}</Button>
155155
</Container>;
156156
};

src/test/pages/SetAssignments.test.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,10 @@ describe("SetAssignments", () => {
170170

171171
// Check scheduled start date and due date are there
172172
within(modal).getByLabelText("Schedule an assignment start date", {exact: false});
173-
within(modal).getByLabelText("Due date reminder", {exact: false});
174-
// TODO check setting scheduled start date and due date - might be best to transition to
175-
// react-select date picker UI for this functionality anyway
173+
const dueDateContainer = within(modal).getByLabelText("Due date reminder", {exact: false});
174+
// TODO check setting scheduled start date and due date leads to correctly saved values,
175+
// since this currently just checks any form of due date is set.
176+
await userEvent.selectOptions(dueDateContainer, "1");
176177

177178
// Add some notes
178179
const testNotes = "Test notes to test groups for test assignments";
@@ -195,7 +196,7 @@ describe("SetAssignments", () => {
195196
expect(requestGroupIds).toEqual([mockActiveGroups[1].id]);
196197
expect(requestAssignment.gameboardId).toEqual(mockGameboard.id);
197198
expect(requestAssignment.notes).toEqual(testNotes);
198-
expect(requestAssignment.dueDate).not.toBeDefined();
199+
expect(requestAssignment.dueDate).toBeDefined();
199200
expect(requestAssignment.scheduledStartDate).not.toBeDefined();
200201
});
201202

0 commit comments

Comments
 (0)