Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": null,
"lines": null
},
"generated_at": "2025-10-09T10:00:02Z",
"generated_at": "2025-10-09T10:36:06Z",
"plugins_used": [
{
"name": "AWSKeyDetector"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import { Logger } from "winston";
import { PrismaService } from "../../../../prisma.service";
import { QuestionDto } from "../../dto/update.questions.request.dto";
import { assign } from "nodemailer/lib/shared";

Check warning on line 27 in apps/api/src/api/assignment/v2/services/version-management.service.ts

View workflow job for this annotation

GitHub Actions / Lint & Test - api

'assign' is defined but never used

export interface CreateVersionDto {
versionNumber?: string;
Expand Down Expand Up @@ -645,7 +645,8 @@
graded: versionToRestore.graded,
numAttempts: versionToRestore.numAttempts,
attemptsBeforeCoolDown: versionToRestore.attemptsBeforeCoolDown,
retakeAttemptCoolDownMinutes: versionToRestore.retakeAttemptCoolDownMinutes,
retakeAttemptCoolDownMinutes:
versionToRestore.retakeAttemptCoolDownMinutes,
allotedTimeMinutes: versionToRestore.allotedTimeMinutes,
attemptsPerTimeRange: versionToRestore.attemptsPerTimeRange,
attemptsTimeRangeHours: versionToRestore.attemptsTimeRangeHours,
Expand Down Expand Up @@ -954,7 +955,7 @@
};
}

async getVersionHistory(assignmentId: number, _userSession: UserSession) {

Check warning on line 958 in apps/api/src/api/assignment/v2/services/version-management.service.ts

View workflow job for this annotation

GitHub Actions / Lint & Test - api

'_userSession' is defined but never used
// Verify access
// await this.verifyAssignmentAccess(assignmentId, userSession);

Expand Down Expand Up @@ -1643,7 +1644,8 @@
graded: sourceVersion.graded,
numAttempts: sourceVersion.numAttempts,
attemptsBeforeCoolDown: sourceVersion.attemptsBeforeCoolDown,
retakeAttemptCoolDownMinutes: sourceVersion.retakeAttemptCoolDownMinutes,
retakeAttemptCoolDownMinutes:
sourceVersion.retakeAttemptCoolDownMinutes,
allotedTimeMinutes: sourceVersion.allotedTimeMinutes,
attemptsPerTimeRange: sourceVersion.attemptsPerTimeRange,
attemptsTimeRangeHours: sourceVersion.attemptsTimeRangeHours,
Expand Down Expand Up @@ -2105,9 +2107,11 @@
numAttempts:
draftData.assignmentData.numAttempts ?? assignment.numAttempts,
attemptsBeforeCoolDown:
draftData.assignmentData.attemptsBeforeCoolDown ?? assignment.attemptsBeforeCoolDown,
draftData.assignmentData.attemptsBeforeCoolDown ??
assignment.attemptsBeforeCoolDown,
retakeAttemptCoolDownMinutes:
draftData.assignmentData.retakeAttemptCoolDownMinutes ?? assignment.retakeAttemptCoolDownMinutes,
draftData.assignmentData.retakeAttemptCoolDownMinutes ??
assignment.retakeAttemptCoolDownMinutes,
allotedTimeMinutes:
draftData.assignmentData.allotedTimeMinutes ??
assignment.allotedTimeMinutes,
Expand Down
104 changes: 54 additions & 50 deletions apps/web/app/author/[assignmentId]/review/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,23 @@ import {
} from "@heroicons/react/24/solid";
import { QuestionAuthorStore } from "@/config/types";
import ExportModal, { ExportOptions } from "../../(components)/ExportModal";
import { omit } from "../../../../lib/utils";

const CONFIG_KEYS_TO_OMIT = [
"errors",
"updatedAt",
"id",
"name",
"introduction",
"instructions",
"gradingCriteriaOverview",
"type",
"questionOrder",
"published",
"languageCode",
"currentVersionId",
"questions",
];

// Helper function to determine if a validation error is question-related
const isQuestionRelatedValidationError = (message: string): boolean => {
Expand Down Expand Up @@ -744,31 +761,7 @@ function Component() {
const [isExportModalOpen, setIsExportModalOpen] = useState(false);
const [isIssuesModalOpen, setIsIssuesModalOpen] = useState(false);

const [
graded,
allotedTimeMinutes,
timeEstimateMinutes,
numAttempts,
attemptsBeforeCoolDown,
retakeAttemptCoolDownMinutes,
passingGrade,
displayOrder,
questionDisplay,
numberOfQuestionsPerAttempt,
strictTimeLimit,
] = useAssignmentConfig((state) => [
state.graded,
state.allotedTimeMinutes,
state.timeEstimateMinutes,
state.numAttempts,
state.attemptsBeforeCoolDown,
state.retakeAttemptCoolDownMinutes,
state.passingGrade,
state.displayOrder,
state.questionDisplay,
state.numberOfQuestionsPerAttempt,
state.strictTimeLimit,
]);
const assignmentConfig = useAssignmentConfig((state) => state);

const [
introduction,
Expand Down Expand Up @@ -1124,19 +1117,7 @@ function Component() {
}

if (exportOptions.includeConfig) {
exportData.config = {
graded,
allotedTimeMinutes,
timeEstimateMinutes,
numAttempts,
attemptsBeforeCoolDown,
retakeAttemptCoolDownMinutes,
passingGrade,
displayOrder,
questionDisplay,
numberOfQuestionsPerAttempt,
strictTimeLimit,
};
exportData.config = omit(assignmentConfig, CONFIG_KEYS_TO_OMIT);
}

if (exportOptions.includeFeedbackConfig) {
Expand Down Expand Up @@ -1698,7 +1679,7 @@ function Component() {
<ChangeComparison
label="Assignment Type"
before={originalAssignment.graded ? "Graded" : "Practice"}
after={graded ? "Graded" : "Practice"}
after={assignmentConfig.graded ? "Graded" : "Practice"}
onNavigate={() =>
router.push(`/author/${activeAssignmentId}/config`)
}
Expand All @@ -1714,8 +1695,8 @@ function Component() {
: "No time limit"
}
after={
allotedTimeMinutes
? `${allotedTimeMinutes} minutes`
assignmentConfig.allotedTimeMinutes
? `${assignmentConfig.allotedTimeMinutes} minutes`
: "No time limit"
}
/>
Expand All @@ -1730,8 +1711,8 @@ function Component() {
: "Not set"
}
after={
timeEstimateMinutes
? `${timeEstimateMinutes} minutes`
assignmentConfig.timeEstimateMinutes
? `${assignmentConfig.timeEstimateMinutes} minutes`
: "Not set"
}
/>
Expand All @@ -1745,39 +1726,59 @@ function Component() {
? "Unlimited"
: originalAssignment.numAttempts
}
after={numAttempts === -1 ? "Unlimited" : numAttempts}
after={
assignmentConfig.numAttempts === -1
? "Unlimited"
: assignmentConfig.numAttempts
}
/>
)}

{changes.attemptsBeforeCoolDown && (
<ChangeComparison
label="Number of Attempts Before Cooldown Period"
before={originalAssignment.attemptsBeforeCoolDown}
after={attemptsBeforeCoolDown}
after={assignmentConfig.attemptsBeforeCoolDown}
/>
)}

{changes.retakeAttemptCoolDownMinutes && (
<ChangeComparison
label="Number of Minutes Learners Must Wait Between Attempts"
before={originalAssignment.retakeAttemptCoolDownMinutes}
after={retakeAttemptCoolDownMinutes}
after={assignmentConfig.retakeAttemptCoolDownMinutes}
/>
)}

{changes.attemptsBeforeCoolDown && (
<ChangeComparison
label="Number of Attempts Before Cooldown Period"
before={originalAssignment.attemptsBeforeCoolDown}
after={changes.attemptsBeforeCoolDown}
/>
)}

{changes.retakeAttemptCoolDownMinutes && (
<ChangeComparison
label="Number of Minutes Learners Must Wait Between Attempts"
before={originalAssignment.retakeAttemptCoolDownMinutes}
after={changes.retakeAttemptCoolDownMinutes}
/>
)}

{changes.passingGrade && (
<ChangeComparison
label="Passing Grade"
before={`${originalAssignment.passingGrade}%`}
after={`${passingGrade}%`}
after={`${assignmentConfig.passingGrade}%`}
/>
)}

{changes.displayOrder && (
<ChangeComparison
label="Display Order"
before={originalAssignment.displayOrder}
after={displayOrder}
after={assignmentConfig.displayOrder}
/>
)}

Expand All @@ -1788,15 +1789,18 @@ function Component() {
/_/g,
" ",
)}
after={questionDisplay?.replace(/_/g, " ")}
after={assignmentConfig.questionDisplay?.replace(
/_/g,
" ",
)}
/>
)}

{changes.numberOfQuestionsPerAttempt && (
<ChangeComparison
label="Questions Per Attempt"
before={originalAssignment.numberOfQuestionsPerAttempt}
after={numberOfQuestionsPerAttempt}
after={assignmentConfig.numberOfQuestionsPerAttempt}
type="number"
/>
)}
Expand Down
7 changes: 7 additions & 0 deletions apps/web/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,13 @@ export const getSubmitButtonStatus = (

return { disabled: false, reason: null };
};

export const generateTempQuestionId = (): number => {
return Math.floor(Math.random() * 2e9);
};

export const omit = (obj: object, keys: string[]): object => {
return Object.fromEntries(
Object.entries(obj).filter(([k]) => !keys.includes(k)),
);
};
1 change: 1 addition & 0 deletions apps/web/stores/author.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { shallow } from "zustand/shallow";
import { createWithEqualityFn } from "zustand/traditional";
import { withUpdatedAt } from "./middlewares";
import { DraftSummary, VersionSummary } from "@/lib/author";
import { config } from "process";
const NON_PERSIST_KEYS = new Set<keyof AuthorState | keyof AuthorActions>([
// version control state
"versions",
Expand Down
Loading