syncing assignments works

This commit is contained in:
2024-11-14 13:31:14 -07:00
parent 27cd96acf5
commit b1e48e0ea9
8 changed files with 43 additions and 39 deletions

1
nextjs/.gitignore vendored
View File

@@ -1,6 +1,7 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
.pnpm-store/ .pnpm-store/
tmp.json
# dependencies # dependencies

View File

@@ -12,9 +12,9 @@ import { settingsBox } from "./sharedSettings";
import { Spinner } from "@/components/Spinner"; import { Spinner } from "@/components/Spinner";
export default function AssignmentGroupManagement() { export default function AssignmentGroupManagement() {
const [settings] = useLocalCourseSettingsQuery(); const [settings, { isPending }] = useLocalCourseSettingsQuery();
const updateSettings = useUpdateLocalCourseSettingsMutation(); const updateSettings = useUpdateLocalCourseSettingsMutation();
const applyInCanvas = useSetAssignmentGroupsMutation(settings.canvasId); // untested const applyInCanvas = useSetAssignmentGroupsMutation(settings.canvasId);
const [assignmentGroups, setAssignmentGroups] = useState< const [assignmentGroups, setAssignmentGroups] = useState<
LocalAssignmentGroup[] LocalAssignmentGroup[]
@@ -26,6 +26,12 @@ export default function AssignmentGroupManagement() {
if ( if (
!areAssignmentGroupsEqual(assignmentGroups, settings.assignmentGroups) !areAssignmentGroupsEqual(assignmentGroups, settings.assignmentGroups)
) { ) {
console.log(
"updating",
assignmentGroups,
updateSettings.isPending,
isPending
);
updateSettings.mutate({ updateSettings.mutate({
settings: { settings: {
...settings, ...settings,
@@ -38,7 +44,7 @@ export default function AssignmentGroupManagement() {
return () => { return () => {
clearTimeout(handler); clearTimeout(handler);
}; };
}, [assignmentGroups, settings, updateSettings]); }, [assignmentGroups, isPending, settings, updateSettings]);
return ( return (
<div className={settingsBox}> <div className={settingsBox}>
@@ -97,8 +103,11 @@ export default function AssignmentGroupManagement() {
<br /> <br />
<div className="flex justify-end"> <div className="flex justify-end">
<button <button
onClick={() => { onClick={async () => {
applyInCanvas.mutate(settings); const newSettings = await applyInCanvas.mutateAsync(settings);
// prevent debounce from resetting
if (newSettings) setAssignmentGroups(newSettings.assignmentGroups);
}} }}
disabled={applyInCanvas.isPending} disabled={applyInCanvas.isPending}
> >

View File

@@ -1,12 +1,16 @@
import { CanvasAssignmentGroup } from "@/models/canvas/assignments/canvasAssignmentGroup"; import { CanvasAssignmentGroup } from "@/models/canvas/assignments/canvasAssignmentGroup";
import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel"; import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel";
import { LocalAssignmentGroup } from "@/models/local/assignment/localAssignmentGroup"; import { LocalAssignmentGroup } from "@/models/local/assignment/localAssignmentGroup";
import { LocalCourseSettings } from "@/models/local/localCourseSettings"; import {
LocalCourseSettings,
zodLocalCourseSettings,
} from "@/models/local/localCourseSettings";
import { canvasAssignmentGroupService } from "@/services/canvas/canvasAssignmentGroupService"; import { canvasAssignmentGroupService } from "@/services/canvas/canvasAssignmentGroupService";
import { canvasService } from "@/services/canvas/canvasService"; import { canvasService } from "@/services/canvas/canvasService";
import { trpc } from "@/services/trpc/utils"; import { trpc } from "@/services/trpc/utils";
import { useMutation, useQuery } from "@tanstack/react-query"; import { useMutation, useQuery } from "@tanstack/react-query";
import { useUpdateLocalCourseSettingsMutation } from "../localCourse/localCoursesHooks"; import { useUpdateLocalCourseSettingsMutation } from "../localCourse/localCoursesHooks";
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
export const canvasCourseKeys = { export const canvasCourseKeys = {
courseDetails: (canavasId: number) => courseDetails: (canavasId: number) =>
@@ -40,7 +44,7 @@ export const useSetAssignmentGroupsMutation = (canvasId: number) => {
const groupsToDelete = canvasAssignmentGroups.filter( const groupsToDelete = canvasAssignmentGroups.filter(
(c: CanvasAssignmentGroup) => !localNames.includes(c.name) (c: CanvasAssignmentGroup) => !localNames.includes(c.name)
); );
console.log("updating canvas groups", groupsToDelete);
await Promise.all( await Promise.all(
groupsToDelete.map( groupsToDelete.map(
async (g: CanvasAssignmentGroup) => async (g: CanvasAssignmentGroup) =>
@@ -63,13 +67,17 @@ export const useSetAssignmentGroupsMutation = (canvasId: number) => {
canvasId: newGroup.canvasId, canvasId: newGroup.canvasId,
}; };
} else { } else {
if (canvasGroup.group_weight !== group.weight) { const groupWithCanvasId = {
await canvasAssignmentGroupService.update(canvasId, group);
}
return {
...group, ...group,
canvasId: canvasGroup.id, canvasId: canvasGroup.id,
}; };
if (canvasGroup.group_weight !== group.weight) {
await canvasAssignmentGroupService.update(
canvasId,
groupWithCanvasId
);
}
return groupWithCanvasId;
} }
} }
) )
@@ -79,11 +87,9 @@ export const useSetAssignmentGroupsMutation = (canvasId: number) => {
...settings, ...settings,
assignmentGroups: updatedGroups, assignmentGroups: updatedGroups,
}; };
console.log(
"finished updating canvas assignment groups, updating settings of file system",
updatedSettings
);
await updateSettingsMutation.mutateAsync({ settings: updatedSettings }); await updateSettingsMutation.mutateAsync({ settings: updatedSettings });
return updatedSettings;
}, },
}); });
}; };

View File

@@ -7,8 +7,8 @@ export interface LocalAssignmentGroup {
weight: number; weight: number;
} }
export const zodLocalAssignmentGroup = z.object({ export const zodLocalAssignmentGroup = z.object({
canvasId: z.number().optional(), // canvasId is optional canvasId: z.optional(z.number()),
id: z.string(), // id is a required string id: z.string(),
name: z.string(), // name is a required string name: z.string(),
weight: z.number(), // weight is a required number weight: z.number(),
}); });

View File

@@ -40,7 +40,7 @@ export const canvasAssignmentGroupService = {
canvasCourseId: number, canvasCourseId: number,
localAssignmentGroup: LocalAssignmentGroup localAssignmentGroup: LocalAssignmentGroup
): Promise<void> { ): Promise<void> {
console.log(`Updating assignment group: ${localAssignmentGroup.name}`); console.log(`Updating assignment group: ${localAssignmentGroup.name}, ${localAssignmentGroup.canvasId}`);
if (!localAssignmentGroup.canvasId) { if (!localAssignmentGroup.canvasId) {
throw new Error("Cannot update assignment group if canvas ID is null"); throw new Error("Cannot update assignment group if canvas ID is null");
} }

View File

@@ -73,6 +73,7 @@ export const settingsFileStorageService = {
const settingsPath = path.join(courseDirectory, "settings.yml"); const settingsPath = path.join(courseDirectory, "settings.yml");
const { name, ...settingsWithoutName } = settings; const { name, ...settingsWithoutName } = settings;
const settingsMarkdown = const settingsMarkdown =
localCourseYamlUtils.settingsToYaml(settingsWithoutName); localCourseYamlUtils.settingsToYaml(settingsWithoutName);

View File

@@ -54,19 +54,6 @@ export const settingsRouter = router({
const oldModules = await fileStorageService.modules.getModuleNames( const oldModules = await fileStorageService.modules.getModuleNames(
oldCourseName oldCourseName
); );
console.log(
"old course name",
oldCourseName,
"new course name",
newCourseName
);
console.log(
"old start date",
settingsFromCourseToImport.startDate,
"new start date",
settings.startDate
);
await Promise.all( await Promise.all(
oldModules.map(async (moduleName) => { oldModules.map(async (moduleName) => {
await fileStorageService.modules.createModule( await fileStorageService.modules.createModule(
@@ -96,7 +83,7 @@ export const settingsRouter = router({
const newAssignment = prepAssignmentForNewSemester( const newAssignment = prepAssignmentForNewSemester(
oldAssignment, oldAssignment,
settingsFromCourseToImport.startDate, settingsFromCourseToImport.startDate,
settings.startDate, settings.startDate
); );
await fileStorageService.assignments.updateOrCreateAssignment({ await fileStorageService.assignments.updateOrCreateAssignment({
courseName: newCourseName, courseName: newCourseName,
@@ -109,7 +96,7 @@ export const settingsRouter = router({
const newQuiz = prepQuizForNewSemester( const newQuiz = prepQuizForNewSemester(
oldQuiz, oldQuiz,
settingsFromCourseToImport.startDate, settingsFromCourseToImport.startDate,
settings.startDate, settings.startDate
); );
await fileStorageService.quizzes.updateQuiz({ await fileStorageService.quizzes.updateQuiz({
courseName: newCourseName, courseName: newCourseName,
@@ -122,7 +109,7 @@ export const settingsRouter = router({
const newPage = prepPageForNewSemester( const newPage = prepPageForNewSemester(
oldPage, oldPage,
settingsFromCourseToImport.startDate, settingsFromCourseToImport.startDate,
settings.startDate, settings.startDate
); );
await fileStorageService.pages.updatePage({ await fileStorageService.pages.updatePage({
courseName: newCourseName, courseName: newCourseName,
@@ -136,7 +123,7 @@ export const settingsRouter = router({
const newLecture = prepLectureForNewSemester( const newLecture = prepLectureForNewSemester(
oldLecture, oldLecture,
settingsFromCourseToImport.startDate, settingsFromCourseToImport.startDate,
settings.startDate, settings.startDate
); );
await updateLecture(newCourseName, settings, newLecture); await updateLecture(newCourseName, settings, newLecture);
}) })

View File

@@ -136,7 +136,7 @@ GET https://snow.instructure.com/api/v1/courses/872095/assignments/12676639?incl
Authorization: Bearer {{$dotenv CANVAS_TOKEN}} Authorization: Bearer {{$dotenv CANVAS_TOKEN}}
### ###
GET https://snow.instructure.com/api/v1/courses/871954/assignment_groups/ GET https://snow.instructure.com/api/v1/courses/1013058/assignment_groups/
Authorization: Bearer {{$dotenv CANVAS_TOKEN}} Authorization: Bearer {{$dotenv CANVAS_TOKEN}}
### ###