mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-26 07:38:33 -06:00
some papercuts
This commit is contained in:
@@ -7,7 +7,6 @@ import { QuizButtons } from "./QuizButton";
|
||||
import ClientOnly from "@/components/ClientOnly";
|
||||
import { SuspenseAndErrorHandling } from "@/components/SuspenseAndErrorHandling";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { getModuleItemUrl } from "@/services/urlUtils";
|
||||
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
|
||||
import {
|
||||
useQuizQuery,
|
||||
@@ -16,8 +15,15 @@ import {
|
||||
import { useAuthoritativeUpdates } from "../../../../utils/useAuthoritativeUpdates";
|
||||
import { extractLabelValue } from "@/models/local/assignment/utils/markdownUtils";
|
||||
import EditQuizHeader from "./EditQuizHeader";
|
||||
import { LocalCourseSettings } from "@/models/local/localCourseSettings";
|
||||
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
|
||||
|
||||
const helpString = `QUESTION REFERENCE
|
||||
const helpString = (settings: LocalCourseSettings) => {
|
||||
const groupNames = settings.assignmentGroups.map((g) => g.name).join("\n- ");
|
||||
return `Assignment Group Names:
|
||||
- ${groupNames}
|
||||
|
||||
QUESTION REFERENCE
|
||||
---
|
||||
Points: 2
|
||||
this is a question?
|
||||
@@ -57,6 +63,7 @@ short answer
|
||||
this is a matching question
|
||||
^ left answer - right dropdown
|
||||
^ other thing - another option`;
|
||||
};
|
||||
|
||||
export default function EditQuiz({
|
||||
moduleName,
|
||||
@@ -66,6 +73,7 @@ export default function EditQuiz({
|
||||
moduleName: string;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [settings] = useLocalCourseSettingsQuery();
|
||||
const { courseName } = useCourseContext();
|
||||
const [quiz, { dataUpdatedAt: serverDataUpdatedAt, isFetching }] =
|
||||
useQuizQuery(moduleName, quizName);
|
||||
@@ -95,19 +103,15 @@ export default function EditQuiz({
|
||||
)
|
||||
) {
|
||||
if (clientIsAuthoritative) {
|
||||
const updatedQuiz = quizMarkdownUtils.parseMarkdown(
|
||||
text,
|
||||
quizName
|
||||
);
|
||||
await updateQuizMutation
|
||||
.mutateAsync({
|
||||
quiz: updatedQuiz,
|
||||
moduleName,
|
||||
quizName: quizName,
|
||||
previousModuleName: moduleName,
|
||||
previousQuizName: quizName,
|
||||
courseName,
|
||||
})
|
||||
const updatedQuiz = quizMarkdownUtils.parseMarkdown(text, quizName);
|
||||
await updateQuizMutation.mutateAsync({
|
||||
quiz: updatedQuiz,
|
||||
moduleName,
|
||||
quizName: quizName,
|
||||
previousModuleName: moduleName,
|
||||
previousQuizName: quizName,
|
||||
courseName,
|
||||
});
|
||||
} else {
|
||||
console.log(
|
||||
"client not authoritative, updating client with server quiz"
|
||||
@@ -143,7 +147,7 @@ export default function EditQuiz({
|
||||
<div className={"min-h-96 h-full flex flex-row w-full"}>
|
||||
{showHelp && (
|
||||
<pre className=" max-w-96">
|
||||
<code>{helpString}</code>
|
||||
<code>{helpString(settings)}</code>
|
||||
</pre>
|
||||
)}
|
||||
<div className="flex-1 h-full">
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
"use client"
|
||||
"use client";
|
||||
|
||||
import AssignmentGroupManagement from "./AssignmentGroupManagement";
|
||||
import DaysOfWeekSettings from "./DaysOfWeekSettings";
|
||||
import DefaultDueTime from "./DefaultDueTime";
|
||||
import DefaultFileUploadTypes from "./DefaultFileUploadTypes";
|
||||
import GithubClassroomList from "./GithubClassroomList";
|
||||
import HolidayConfig from "./HolidayConfig";
|
||||
import SettingsHeader from "./SettingsHeader";
|
||||
import StartAndEndDate from "./StartAndEndDate";
|
||||
@@ -15,6 +16,7 @@ export default function AllSettings() {
|
||||
<SettingsHeader />
|
||||
<DaysOfWeekSettings />
|
||||
<StartAndEndDate />
|
||||
<GithubClassroomList />
|
||||
<SubmissionDefaults />
|
||||
<DefaultFileUploadTypes />
|
||||
<DefaultDueTime />
|
||||
|
||||
31
src/app/course/[courseName]/settings/GithubClassroomList.tsx
Normal file
31
src/app/course/[courseName]/settings/GithubClassroomList.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
"use client";
|
||||
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
|
||||
import { settingsBox } from "./sharedSettings";
|
||||
import { useCourseStudentsQuery } from "@/hooks/canvas/canvasCourseHooks";
|
||||
import { Spinner } from "@/components/Spinner";
|
||||
|
||||
export default function GithubClassroomList() {
|
||||
const [settings] = useLocalCourseSettingsQuery();
|
||||
const enrollmentsQuery = useCourseStudentsQuery(settings.canvasId);
|
||||
|
||||
if (enrollmentsQuery.isLoading)
|
||||
return (
|
||||
<div className={settingsBox}>
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className={settingsBox}>
|
||||
<h5 className="text-center">Github Classroom Friendly Roster</h5>
|
||||
<p className="text-center text-slate-500">
|
||||
Copy and paste this into github classroom to import students
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
{enrollmentsQuery.data?.map((student) => student.email + "\n")}
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,16 +1,11 @@
|
||||
import { CanvasAssignmentGroup } from "@/models/canvas/assignments/canvasAssignmentGroup";
|
||||
import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel";
|
||||
import { LocalAssignmentGroup } from "@/models/local/assignment/localAssignmentGroup";
|
||||
import {
|
||||
LocalCourseSettings,
|
||||
zodLocalCourseSettings,
|
||||
} from "@/models/local/localCourseSettings";
|
||||
import { LocalCourseSettings } from "@/models/local/localCourseSettings";
|
||||
import { canvasAssignmentGroupService } from "@/services/canvas/canvasAssignmentGroupService";
|
||||
import { canvasService } from "@/services/canvas/canvasService";
|
||||
import { trpc } from "@/services/serverFunctions/trpcClient";
|
||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||
import { useUpdateLocalCourseSettingsMutation } from "../localCourse/localCoursesHooks";
|
||||
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
|
||||
|
||||
export const canvasCourseKeys = {
|
||||
courseDetails: (canavasId: number) =>
|
||||
@@ -19,6 +14,8 @@ export const canvasCourseKeys = {
|
||||
["canvas", canavasId, "assignment groups"] as const,
|
||||
courseListInTerm: (canvasTermId: number | undefined) =>
|
||||
["canvas courses in term", canvasTermId] as const,
|
||||
students: (canvasId: number) =>
|
||||
["students in canvas course", canvasId] as const,
|
||||
};
|
||||
|
||||
export const useCourseListInTermQuery = (canvasTermId: number | undefined) =>
|
||||
@@ -101,3 +98,9 @@ export const useAssignmentGroupsQuery = (canvasId: number) => {
|
||||
await canvasAssignmentGroupService.getAll(canvasId),
|
||||
});
|
||||
};
|
||||
|
||||
export const useCourseStudentsQuery = (canvasId: number) =>
|
||||
useQuery({
|
||||
queryKey: canvasCourseKeys.students(canvasId),
|
||||
queryFn: async () => await canvasService.getEnrolledStudents(canvasId),
|
||||
});
|
||||
|
||||
12
src/models/canvas/courses/canvasCourseStudentModel.ts
Normal file
12
src/models/canvas/courses/canvasCourseStudentModel.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export interface CanvasCourseStudentModel {
|
||||
id: number;
|
||||
name: string;
|
||||
created_at: string; // ISO 8601 date string
|
||||
sortable_name: string;
|
||||
short_name: string;
|
||||
sis_user_id: string;
|
||||
integration_id?: string;
|
||||
root_account: string;
|
||||
login_id: string;
|
||||
email: string;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { CanvasEnrollmentTermModel } from "@/models/canvas/enrollmentTerms/canvasEnrollmentTermModel";
|
||||
import { canvasApi, paginatedRequest } from "./canvasServiceUtils";
|
||||
import { CanvasCourseModel } from "@/models/canvas/courses/canvasCourseModel";
|
||||
import { CanvasEnrollmentModel } from "@/models/canvas/enrollments/canvasEnrollmentModel";
|
||||
import { axiosClient } from "../axiosUtils";
|
||||
import { CanvasCourseStudentModel } from "@/models/canvas/courses/canvasCourseStudentModel";
|
||||
|
||||
const getAllTerms = async () => {
|
||||
const url = `${canvasApi}/accounts/10/terms?per_page=100`;
|
||||
@@ -54,8 +54,8 @@ export const canvasService = {
|
||||
|
||||
async getEnrolledStudents(canvasCourseId: number) {
|
||||
console.log(`Getting students for course ${canvasCourseId}`);
|
||||
const url = `${canvasApi}/courses/${canvasCourseId}/enrollments?enrollment_type=student`;
|
||||
const { data } = await axiosClient.get<CanvasEnrollmentModel[]>(url);
|
||||
const url = `${canvasApi}/courses/${canvasCourseId}/users?enrollment_type=student`;
|
||||
const data = await paginatedRequest<CanvasCourseStudentModel[]>({url});
|
||||
|
||||
if (!data)
|
||||
throw new Error(
|
||||
|
||||
Reference in New Issue
Block a user